4 * SCSI sysfs interface routines.
6 * Created to pull SCSI mid layer sysfs routines into one file.
9 #include <linux/config.h>
10 #include <linux/module.h>
11 #include <linux/init.h>
12 #include <linux/blkdev.h>
13 #include <linux/device.h>
15 #include <scsi/scsi_host.h>
16 #include <scsi/scsi_transport.h>
19 #include "scsi_priv.h"
20 #include "scsi_logging.h"
23 enum scsi_device_state value;
26 { SDEV_CREATED, "created" },
27 { SDEV_RUNNING, "running" },
28 { SDEV_CANCEL, "cancel" },
29 { SDEV_DEL, "deleted" },
30 { SDEV_QUIESCE, "quiesce" },
31 { SDEV_OFFLINE, "offline" },
34 const char *scsi_device_state_name(enum scsi_device_state state)
39 for (i = 0; i < sizeof(sdev_states)/sizeof(sdev_states[0]); i++) {
40 if (sdev_states[i].value == state) {
41 name = sdev_states[i].name;
48 static int check_set(unsigned int *val, char *src)
52 if (strncmp(src, "-", 20) == 0) {
53 *val = SCAN_WILD_CARD;
56 * Doesn't check for int overflow
58 *val = simple_strtoul(src, &last, 0);
65 static int scsi_scan(struct Scsi_Host *shost, const char *str)
67 char s1[15], s2[15], s3[15], junk;
68 unsigned int channel, id, lun;
71 res = sscanf(str, "%10s %10s %10s %c", s1, s2, s3, &junk);
74 if (check_set(&channel, s1))
76 if (check_set(&id, s2))
78 if (check_set(&lun, s3))
80 res = scsi_scan_host_selected(shost, channel, id, lun, 1);
85 * shost_show_function: macro to create an attr function that can be used to
86 * show a non-bit field.
88 #define shost_show_function(name, field, format_string) \
90 show_##name (struct class_device *class_dev, char *buf) \
92 struct Scsi_Host *shost = class_to_shost(class_dev); \
93 return snprintf (buf, 20, format_string, shost->field); \
97 * shost_rd_attr: macro to create a function and attribute variable for a
100 #define shost_rd_attr2(name, field, format_string) \
101 shost_show_function(name, field, format_string) \
102 static CLASS_DEVICE_ATTR(name, S_IRUGO, show_##name, NULL)
104 #define shost_rd_attr(field, format_string) \
105 shost_rd_attr2(field, field, format_string)
108 * Create the actual show/store functions and data structures.
111 static ssize_t store_scan(struct class_device *class_dev, const char *buf,
114 struct Scsi_Host *shost = class_to_shost(class_dev);
117 res = scsi_scan(shost, buf);
122 static CLASS_DEVICE_ATTR(scan, S_IWUSR, NULL, store_scan);
124 shost_rd_attr(unique_id, "%u\n");
125 shost_rd_attr(host_busy, "%hu\n");
126 shost_rd_attr(cmd_per_lun, "%hd\n");
127 shost_rd_attr(sg_tablesize, "%hu\n");
128 shost_rd_attr(unchecked_isa_dma, "%d\n");
129 shost_rd_attr2(proc_name, hostt->proc_name, "%s\n");
131 static struct class_device_attribute *scsi_sysfs_shost_attrs[] = {
132 &class_device_attr_unique_id,
133 &class_device_attr_host_busy,
134 &class_device_attr_cmd_per_lun,
135 &class_device_attr_sg_tablesize,
136 &class_device_attr_unchecked_isa_dma,
137 &class_device_attr_proc_name,
138 &class_device_attr_scan,
142 static void scsi_device_cls_release(struct class_device *class_dev)
144 struct scsi_device *sdev;
146 sdev = class_to_sdev(class_dev);
147 put_device(&sdev->sdev_gendev);
150 void scsi_device_dev_release(struct device *dev)
152 struct scsi_device *sdev;
153 struct device *parent;
156 parent = dev->parent;
157 sdev = to_scsi_device(dev);
159 spin_lock_irqsave(sdev->host->host_lock, flags);
160 list_del(&sdev->siblings);
161 list_del(&sdev->same_target_siblings);
162 list_del(&sdev->starved_entry);
163 if (sdev->single_lun && --sdev->sdev_target->starget_refcnt == 0)
164 kfree(sdev->sdev_target);
165 spin_unlock_irqrestore(sdev->host->host_lock, flags);
167 if (sdev->request_queue)
168 scsi_free_queue(sdev->request_queue);
170 kfree(sdev->inquiry);
176 struct class sdev_class = {
177 .name = "scsi_device",
178 .release = scsi_device_cls_release,
181 /* all probing is done in the individual ->probe routines */
182 static int scsi_bus_match(struct device *dev, struct device_driver *gendrv)
184 struct scsi_device *sdp = to_scsi_device(dev);
185 return (sdp->inq_periph_qual == SCSI_INQ_PQ_CON)? 1: 0;
188 struct bus_type scsi_bus_type = {
190 .match = scsi_bus_match,
193 int scsi_sysfs_register(void)
197 error = bus_register(&scsi_bus_type);
199 error = class_register(&sdev_class);
201 bus_unregister(&scsi_bus_type);
207 void scsi_sysfs_unregister(void)
209 class_unregister(&sdev_class);
210 bus_unregister(&scsi_bus_type);
214 * sdev_show_function: macro to create an attr function that can be used to
215 * show a non-bit field.
217 #define sdev_show_function(field, format_string) \
219 sdev_show_##field (struct device *dev, char *buf) \
221 struct scsi_device *sdev; \
222 sdev = to_scsi_device(dev); \
223 return snprintf (buf, 20, format_string, sdev->field); \
227 * sdev_rd_attr: macro to create a function and attribute variable for a
230 #define sdev_rd_attr(field, format_string) \
231 sdev_show_function(field, format_string) \
232 static DEVICE_ATTR(field, S_IRUGO, sdev_show_##field, NULL)
236 * sdev_rd_attr: create a function and attribute variable for a
239 #define sdev_rw_attr(field, format_string) \
240 sdev_show_function(field, format_string) \
243 sdev_store_##field (struct device *dev, const char *buf, size_t count) \
245 struct scsi_device *sdev; \
246 sdev = to_scsi_device(dev); \
247 snscanf (buf, 20, format_string, &sdev->field); \
250 static DEVICE_ATTR(field, S_IRUGO | S_IWUSR, sdev_show_##field, sdev_store_##field)
252 /* Currently we don't export bit fields, but we might in future,
253 * so leave this code in */
256 * sdev_rd_attr: create a function and attribute variable for a
257 * read/write bit field.
259 #define sdev_rw_attr_bit(field) \
260 sdev_show_function(field, "%d\n") \
263 sdev_store_##field (struct device *dev, const char *buf, size_t count) \
266 struct scsi_device *sdev; \
267 ret = scsi_sdev_check_buf_bit(buf); \
269 sdev = to_scsi_device(dev); \
275 static DEVICE_ATTR(field, S_IRUGO | S_IWUSR, sdev_show_##field, sdev_store_##field)
278 * scsi_sdev_check_buf_bit: return 0 if buf is "0", return 1 if buf is "1",
279 * else return -EINVAL.
281 static int scsi_sdev_check_buf_bit(const char *buf)
283 if ((buf[1] == '\0') || ((buf[1] == '\n') && (buf[2] == '\0'))) {
286 else if (buf[0] == '0')
295 * Create the actual show/store functions and data structures.
297 sdev_rd_attr (device_blocked, "%d\n");
298 sdev_rd_attr (queue_depth, "%d\n");
299 sdev_rd_attr (type, "%d\n");
300 sdev_rd_attr (scsi_level, "%d\n");
301 sdev_rd_attr (vendor, "%.8s\n");
302 sdev_rd_attr (model, "%.16s\n");
303 sdev_rd_attr (rev, "%.4s\n");
306 sdev_show_timeout (struct device *dev, char *buf)
308 struct scsi_device *sdev;
309 sdev = to_scsi_device(dev);
310 return snprintf (buf, 20, "%d\n", sdev->timeout / HZ);
314 sdev_store_timeout (struct device *dev, const char *buf, size_t count)
316 struct scsi_device *sdev;
318 sdev = to_scsi_device(dev);
319 sscanf (buf, "%d\n", &timeout);
320 sdev->timeout = timeout * HZ;
323 static DEVICE_ATTR(timeout, S_IRUGO | S_IWUSR, sdev_show_timeout, sdev_store_timeout)
326 store_rescan_field (struct device *dev, const char *buf, size_t count)
328 scsi_rescan_device(dev);
331 static DEVICE_ATTR(rescan, S_IWUSR, NULL, store_rescan_field)
333 static ssize_t sdev_store_delete(struct device *dev, const char *buf,
336 scsi_remove_device(to_scsi_device(dev));
339 static DEVICE_ATTR(delete, S_IWUSR, NULL, sdev_store_delete);
342 store_state_field(struct device *dev, const char *buf, size_t count)
345 struct scsi_device *sdev = to_scsi_device(dev);
346 enum scsi_device_state state = 0;
348 for (i = 0; i < sizeof(sdev_states)/sizeof(sdev_states[0]); i++) {
349 const int len = strlen(sdev_states[i].name);
350 if (strncmp(sdev_states[i].name, buf, len) == 0 &&
352 state = sdev_states[i].value;
359 if (scsi_device_set_state(sdev, state))
365 show_state_field(struct device *dev, char *buf)
367 struct scsi_device *sdev = to_scsi_device(dev);
368 const char *name = scsi_device_state_name(sdev->sdev_state);
373 return snprintf(buf, 20, "%s\n", name);
376 DEVICE_ATTR(state, S_IRUGO | S_IWUSR, show_state_field, store_state_field);
379 /* Default template for device attributes. May NOT be modified */
380 static struct device_attribute *scsi_sysfs_sdev_attrs[] = {
381 &dev_attr_device_blocked,
382 &dev_attr_queue_depth,
384 &dev_attr_scsi_level,
396 static struct device_attribute *attr_overridden(
397 struct device_attribute **attrs,
398 struct device_attribute *attr)
404 for (i = 0; attrs[i]; i++)
405 if (!strcmp(attrs[i]->attr.name, attr->attr.name))
410 static int attr_add(struct device *dev, struct device_attribute *attr)
412 struct device_attribute *base_attr;
415 * Spare the caller from having to copy things it's not interested in.
417 base_attr = attr_overridden(scsi_sysfs_sdev_attrs, attr);
419 /* extend permissions */
420 attr->attr.mode |= base_attr->attr.mode;
422 /* override null show/store with default */
424 attr->show = base_attr->show;
426 attr->store = base_attr->store;
429 return device_create_file(dev, attr);
433 * scsi_sysfs_add_sdev - add scsi device to sysfs
434 * @sdev: scsi_device to add
437 * 0 on Success / non-zero on Failure
439 int scsi_sysfs_add_sdev(struct scsi_device *sdev)
441 struct class_device_attribute **attrs;
444 if ((error = scsi_device_set_state(sdev, SDEV_RUNNING)) != 0)
447 error = device_add(&sdev->sdev_gendev);
449 printk(KERN_INFO "error 1\n");
453 error = class_device_add(&sdev->sdev_classdev);
455 printk(KERN_INFO "error 2\n");
458 /* take a reference for the sdev_classdev; this is
459 * released by the sdev_class .release */
460 get_device(&sdev->sdev_gendev);
462 if (sdev->transport_classdev.class) {
463 error = class_device_add(&sdev->transport_classdev);
466 /* take a reference for the transport_classdev; this
467 * is released by the transport_class .release */
468 get_device(&sdev->sdev_gendev);
472 if (sdev->host->hostt->sdev_attrs) {
473 for (i = 0; sdev->host->hostt->sdev_attrs[i]; i++) {
474 error = attr_add(&sdev->sdev_gendev,
475 sdev->host->hostt->sdev_attrs[i]);
477 scsi_remove_device(sdev);
483 for (i = 0; scsi_sysfs_sdev_attrs[i]; i++) {
484 if (!attr_overridden(sdev->host->hostt->sdev_attrs,
485 scsi_sysfs_sdev_attrs[i])) {
486 error = device_create_file(&sdev->sdev_gendev,
487 scsi_sysfs_sdev_attrs[i]);
489 scsi_remove_device(sdev);
495 if (sdev->transport_classdev.class) {
496 attrs = sdev->host->transportt->attrs;
497 for (i = 0; attrs[i]; i++) {
498 error = class_device_create_file(&sdev->transport_classdev,
501 scsi_remove_device(sdev);
511 class_device_del(&sdev->sdev_classdev);
513 scsi_device_set_state(sdev, SDEV_CANCEL);
515 device_del(&sdev->sdev_gendev);
516 put_device(&sdev->sdev_gendev);
522 * scsi_remove_device - unregister a device from the scsi bus
523 * @sdev: scsi_device to unregister
525 void scsi_remove_device(struct scsi_device *sdev)
527 if (scsi_device_set_state(sdev, SDEV_CANCEL) != 0)
530 class_device_unregister(&sdev->sdev_classdev);
531 if (sdev->transport_classdev.class)
532 class_device_unregister(&sdev->transport_classdev);
533 device_del(&sdev->sdev_gendev);
534 scsi_device_set_state(sdev, SDEV_DEL);
535 if (sdev->host->hostt->slave_destroy)
536 sdev->host->hostt->slave_destroy(sdev);
537 if (sdev->host->transportt->cleanup)
538 sdev->host->transportt->cleanup(sdev);
539 put_device(&sdev->sdev_gendev);
542 int scsi_register_driver(struct device_driver *drv)
544 drv->bus = &scsi_bus_type;
546 return driver_register(drv);
549 int scsi_register_interface(struct class_interface *intf)
551 intf->class = &sdev_class;
553 return class_interface_register(intf);
557 static struct class_device_attribute *class_attr_overridden(
558 struct class_device_attribute **attrs,
559 struct class_device_attribute *attr)
565 for (i = 0; attrs[i]; i++)
566 if (!strcmp(attrs[i]->attr.name, attr->attr.name))
571 static int class_attr_add(struct class_device *classdev,
572 struct class_device_attribute *attr)
574 struct class_device_attribute *base_attr;
577 * Spare the caller from having to copy things it's not interested in.
579 base_attr = class_attr_overridden(scsi_sysfs_shost_attrs, attr);
581 /* extend permissions */
582 attr->attr.mode |= base_attr->attr.mode;
584 /* override null show/store with default */
586 attr->show = base_attr->show;
588 attr->store = base_attr->store;
591 return class_device_create_file(classdev, attr);
595 * scsi_sysfs_add_host - add scsi host to subsystem
596 * @shost: scsi host struct to add to subsystem
597 * @dev: parent struct device pointer
599 int scsi_sysfs_add_host(struct Scsi_Host *shost)
603 if (shost->hostt->shost_attrs) {
604 for (i = 0; shost->hostt->shost_attrs[i]; i++) {
605 error = class_attr_add(&shost->shost_classdev,
606 shost->hostt->shost_attrs[i]);
612 for (i = 0; scsi_sysfs_shost_attrs[i]; i++) {
613 if (!class_attr_overridden(shost->hostt->shost_attrs,
614 scsi_sysfs_shost_attrs[i])) {
615 error = class_device_create_file(&shost->shost_classdev,
616 scsi_sysfs_shost_attrs[i]);
625 /* A blank transport template that is used in drivers that don't
626 * yet implement Transport Attributes */
627 struct scsi_transport_template blank_transport_template = { 0, };