ndtest: Add dimm attributes

This patch adds sysfs attributes for nvdimm and the dimm device.

Signed-off-by: Santosh Sivaraj <santosh@fossix.org>
Link: https://lore.kernel.org/r/20201222042240.2983755-5-santosh@fossix.org
Signed-off-by: Dan Williams <dan.j.williams@intel.com>

authored by Santosh Sivaraj and committed by Dan Williams 5e41396f 9399ab61

Changed files
+200 -2
tools
testing
nvdimm
test
+200 -2
tools/testing/nvdimm/test/ndtest.c
··· 219 219 } 220 220 } 221 221 222 + static ssize_t handle_show(struct device *dev, struct device_attribute *attr, 223 + char *buf) 224 + { 225 + struct ndtest_dimm *dimm = dev_get_drvdata(dev); 226 + 227 + return sprintf(buf, "%#x\n", dimm->handle); 228 + } 229 + static DEVICE_ATTR_RO(handle); 230 + 231 + static ssize_t fail_cmd_show(struct device *dev, struct device_attribute *attr, 232 + char *buf) 233 + { 234 + struct ndtest_dimm *dimm = dev_get_drvdata(dev); 235 + 236 + return sprintf(buf, "%#x\n", dimm->fail_cmd); 237 + } 238 + 239 + static ssize_t fail_cmd_store(struct device *dev, struct device_attribute *attr, 240 + const char *buf, size_t size) 241 + { 242 + struct ndtest_dimm *dimm = dev_get_drvdata(dev); 243 + unsigned long val; 244 + ssize_t rc; 245 + 246 + rc = kstrtol(buf, 0, &val); 247 + if (rc) 248 + return rc; 249 + 250 + dimm->fail_cmd = val; 251 + 252 + return size; 253 + } 254 + static DEVICE_ATTR_RW(fail_cmd); 255 + 256 + static ssize_t fail_cmd_code_show(struct device *dev, struct device_attribute *attr, 257 + char *buf) 258 + { 259 + struct ndtest_dimm *dimm = dev_get_drvdata(dev); 260 + 261 + return sprintf(buf, "%d\n", dimm->fail_cmd_code); 262 + } 263 + 264 + static ssize_t fail_cmd_code_store(struct device *dev, struct device_attribute *attr, 265 + const char *buf, size_t size) 266 + { 267 + struct ndtest_dimm *dimm = dev_get_drvdata(dev); 268 + unsigned long val; 269 + ssize_t rc; 270 + 271 + rc = kstrtol(buf, 0, &val); 272 + if (rc) 273 + return rc; 274 + 275 + dimm->fail_cmd_code = val; 276 + return size; 277 + } 278 + static DEVICE_ATTR_RW(fail_cmd_code); 279 + 280 + static struct attribute *dimm_attributes[] = { 281 + &dev_attr_handle.attr, 282 + &dev_attr_fail_cmd.attr, 283 + &dev_attr_fail_cmd_code.attr, 284 + NULL, 285 + }; 286 + 287 + static struct attribute_group dimm_attribute_group = { 288 + .attrs = dimm_attributes, 289 + }; 290 + 291 + static const struct attribute_group *dimm_attribute_groups[] = { 292 + &dimm_attribute_group, 293 + NULL, 294 + }; 295 + 296 + static ssize_t phys_id_show(struct device *dev, 297 + struct device_attribute *attr, char *buf) 298 + { 299 + struct nvdimm *nvdimm = to_nvdimm(dev); 300 + struct ndtest_dimm *dimm = nvdimm_provider_data(nvdimm); 301 + 302 + return sprintf(buf, "%#x\n", dimm->physical_id); 303 + } 304 + static DEVICE_ATTR_RO(phys_id); 305 + 306 + static ssize_t vendor_show(struct device *dev, 307 + struct device_attribute *attr, char *buf) 308 + { 309 + return sprintf(buf, "0x1234567\n"); 310 + } 311 + static DEVICE_ATTR_RO(vendor); 312 + 313 + static ssize_t id_show(struct device *dev, 314 + struct device_attribute *attr, char *buf) 315 + { 316 + struct nvdimm *nvdimm = to_nvdimm(dev); 317 + struct ndtest_dimm *dimm = nvdimm_provider_data(nvdimm); 318 + 319 + return sprintf(buf, "%04x-%02x-%04x-%08x", 0xabcd, 320 + 0xa, 2016, ~(dimm->handle)); 321 + } 322 + static DEVICE_ATTR_RO(id); 323 + 324 + static ssize_t nvdimm_handle_show(struct device *dev, 325 + struct device_attribute *attr, char *buf) 326 + { 327 + struct nvdimm *nvdimm = to_nvdimm(dev); 328 + struct ndtest_dimm *dimm = nvdimm_provider_data(nvdimm); 329 + 330 + return sprintf(buf, "%#x\n", dimm->handle); 331 + } 332 + 333 + static struct device_attribute dev_attr_nvdimm_show_handle = { 334 + .attr = { .name = "handle", .mode = 0444 }, 335 + .show = nvdimm_handle_show, 336 + }; 337 + 338 + static ssize_t subsystem_vendor_show(struct device *dev, 339 + struct device_attribute *attr, char *buf) 340 + { 341 + return sprintf(buf, "0x%04x\n", 0); 342 + } 343 + static DEVICE_ATTR_RO(subsystem_vendor); 344 + 345 + static ssize_t dirty_shutdown_show(struct device *dev, 346 + struct device_attribute *attr, char *buf) 347 + { 348 + return sprintf(buf, "%d\n", 42); 349 + } 350 + static DEVICE_ATTR_RO(dirty_shutdown); 351 + 352 + static ssize_t formats_show(struct device *dev, 353 + struct device_attribute *attr, char *buf) 354 + { 355 + struct nvdimm *nvdimm = to_nvdimm(dev); 356 + struct ndtest_dimm *dimm = nvdimm_provider_data(nvdimm); 357 + 358 + return sprintf(buf, "%d\n", dimm->num_formats); 359 + } 360 + static DEVICE_ATTR_RO(formats); 361 + 362 + static ssize_t format_show(struct device *dev, 363 + struct device_attribute *attr, char *buf) 364 + { 365 + struct nvdimm *nvdimm = to_nvdimm(dev); 366 + struct ndtest_dimm *dimm = nvdimm_provider_data(nvdimm); 367 + 368 + if (dimm->num_formats > 1) 369 + return sprintf(buf, "0x201\n"); 370 + 371 + return sprintf(buf, "0x101\n"); 372 + } 373 + static DEVICE_ATTR_RO(format); 374 + 375 + static ssize_t format1_show(struct device *dev, struct device_attribute *attr, 376 + char *buf) 377 + { 378 + return sprintf(buf, "0x301\n"); 379 + } 380 + static DEVICE_ATTR_RO(format1); 381 + 382 + static umode_t ndtest_nvdimm_attr_visible(struct kobject *kobj, 383 + struct attribute *a, int n) 384 + { 385 + struct device *dev = container_of(kobj, struct device, kobj); 386 + struct nvdimm *nvdimm = to_nvdimm(dev); 387 + struct ndtest_dimm *dimm = nvdimm_provider_data(nvdimm); 388 + 389 + if (a == &dev_attr_format1.attr && dimm->num_formats <= 1) 390 + return 0; 391 + 392 + return a->mode; 393 + } 394 + 395 + static struct attribute *ndtest_nvdimm_attributes[] = { 396 + &dev_attr_nvdimm_show_handle.attr, 397 + &dev_attr_vendor.attr, 398 + &dev_attr_id.attr, 399 + &dev_attr_phys_id.attr, 400 + &dev_attr_subsystem_vendor.attr, 401 + &dev_attr_dirty_shutdown.attr, 402 + &dev_attr_formats.attr, 403 + &dev_attr_format.attr, 404 + &dev_attr_format1.attr, 405 + NULL, 406 + }; 407 + 408 + static const struct attribute_group ndtest_nvdimm_attribute_group = { 409 + .name = "papr", 410 + .attrs = ndtest_nvdimm_attributes, 411 + .is_visible = ndtest_nvdimm_attr_visible, 412 + }; 413 + 414 + static const struct attribute_group *ndtest_nvdimm_attribute_groups[] = { 415 + &ndtest_nvdimm_attribute_group, 416 + NULL, 417 + }; 418 + 222 419 static int ndtest_dimm_register(struct ndtest_priv *priv, 223 420 struct ndtest_dimm *dimm, int id) 224 421 { ··· 427 230 set_bit(NDD_LABELING, &dimm_flags); 428 231 } 429 232 430 - dimm->nvdimm = nvdimm_create(priv->bus, dimm, NULL, dimm_flags, 233 + dimm->nvdimm = nvdimm_create(priv->bus, dimm, 234 + ndtest_nvdimm_attribute_groups, dimm_flags, 431 235 NDTEST_SCM_DIMM_CMD_MASK, 0, NULL); 432 236 if (!dimm->nvdimm) { 433 237 dev_err(dev, "Error creating DIMM object for %pOF\n", priv->dn); ··· 437 239 438 240 dimm->dev = device_create_with_groups(ndtest_dimm_class, 439 241 &priv->pdev.dev, 440 - 0, dimm, NULL, 242 + 0, dimm, dimm_attribute_groups, 441 243 "test_dimm%d", id); 442 244 if (!dimm->dev) { 443 245 pr_err("Could not create dimm device attributes\n");