aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/scsi_sysfs.c
diff options
context:
space:
mode:
authorJeff Garzik <jeff@garzik.org>2007-10-29 17:15:22 -0400
committerJeff Garzik <jeff@garzik.org>2007-11-03 22:23:02 -0400
commita341cd0f6a0fde1f85fec9aa8f81f824ea4a3f92 (patch)
treee96b2ab04c94cb1a29d972b135dd6b2bdfac0f78 /drivers/scsi/scsi_sysfs.c
parentb4f555081fdd27d13e6ff39d455d5aefae9d2c0c (diff)
SCSI: add asynchronous event notification API
Originally based on a patch by Kristen Carlson Accardi @ Intel. Copious input from James Bottomley. Signed-off-by: Jeff Garzik <jgarzik@redhat.com>
Diffstat (limited to 'drivers/scsi/scsi_sysfs.c')
-rw-r--r--drivers/scsi/scsi_sysfs.c47
1 files changed, 47 insertions, 0 deletions
diff --git a/drivers/scsi/scsi_sysfs.c b/drivers/scsi/scsi_sysfs.c
index d531ceeb0d8c..f374fdcb6815 100644
--- a/drivers/scsi/scsi_sysfs.c
+++ b/drivers/scsi/scsi_sysfs.c
@@ -268,6 +268,7 @@ static void scsi_device_dev_release_usercontext(struct work_struct *work)
268 struct scsi_device *sdev; 268 struct scsi_device *sdev;
269 struct device *parent; 269 struct device *parent;
270 struct scsi_target *starget; 270 struct scsi_target *starget;
271 struct list_head *this, *tmp;
271 unsigned long flags; 272 unsigned long flags;
272 273
273 sdev = container_of(work, struct scsi_device, ew.work); 274 sdev = container_of(work, struct scsi_device, ew.work);
@@ -282,6 +283,16 @@ static void scsi_device_dev_release_usercontext(struct work_struct *work)
282 list_del(&sdev->starved_entry); 283 list_del(&sdev->starved_entry);
283 spin_unlock_irqrestore(sdev->host->host_lock, flags); 284 spin_unlock_irqrestore(sdev->host->host_lock, flags);
284 285
286 cancel_work_sync(&sdev->event_work);
287
288 list_for_each_safe(this, tmp, &sdev->event_list) {
289 struct scsi_event *evt;
290
291 evt = list_entry(this, struct scsi_event, node);
292 list_del(&evt->node);
293 kfree(evt);
294 }
295
285 if (sdev->request_queue) { 296 if (sdev->request_queue) {
286 sdev->request_queue->queuedata = NULL; 297 sdev->request_queue->queuedata = NULL;
287 /* user context needed to free queue */ 298 /* user context needed to free queue */
@@ -614,6 +625,41 @@ sdev_show_modalias(struct device *dev, struct device_attribute *attr, char *buf)
614} 625}
615static DEVICE_ATTR(modalias, S_IRUGO, sdev_show_modalias, NULL); 626static DEVICE_ATTR(modalias, S_IRUGO, sdev_show_modalias, NULL);
616 627
628#define DECLARE_EVT_SHOW(name, Cap_name) \
629static ssize_t \
630sdev_show_evt_##name(struct device *dev, struct device_attribute *attr, \
631 char *buf) \
632{ \
633 struct scsi_device *sdev = to_scsi_device(dev); \
634 int val = test_bit(SDEV_EVT_##Cap_name, sdev->supported_events);\
635 return snprintf(buf, 20, "%d\n", val); \
636}
637
638#define DECLARE_EVT_STORE(name, Cap_name) \
639static ssize_t \
640sdev_store_evt_##name(struct device *dev, struct device_attribute *attr, \
641 const char *buf, size_t count) \
642{ \
643 struct scsi_device *sdev = to_scsi_device(dev); \
644 int val = simple_strtoul(buf, NULL, 0); \
645 if (val == 0) \
646 clear_bit(SDEV_EVT_##Cap_name, sdev->supported_events); \
647 else if (val == 1) \
648 set_bit(SDEV_EVT_##Cap_name, sdev->supported_events); \
649 else \
650 return -EINVAL; \
651 return count; \
652}
653
654#define DECLARE_EVT(name, Cap_name) \
655 DECLARE_EVT_SHOW(name, Cap_name) \
656 DECLARE_EVT_STORE(name, Cap_name) \
657 static DEVICE_ATTR(evt_##name, S_IRUGO, sdev_show_evt_##name, \
658 sdev_store_evt_##name);
659#define REF_EVT(name) &dev_attr_evt_##name.attr
660
661DECLARE_EVT(media_change, MEDIA_CHANGE)
662
617/* Default template for device attributes. May NOT be modified */ 663/* Default template for device attributes. May NOT be modified */
618static struct attribute *scsi_sdev_attrs[] = { 664static struct attribute *scsi_sdev_attrs[] = {
619 &dev_attr_device_blocked.attr, 665 &dev_attr_device_blocked.attr,
@@ -631,6 +677,7 @@ static struct attribute *scsi_sdev_attrs[] = {
631 &dev_attr_iodone_cnt.attr, 677 &dev_attr_iodone_cnt.attr,
632 &dev_attr_ioerr_cnt.attr, 678 &dev_attr_ioerr_cnt.attr,
633 &dev_attr_modalias.attr, 679 &dev_attr_modalias.attr,
680 REF_EVT(media_change),
634 NULL 681 NULL
635}; 682};
636 683