Merge master.kernel.org:/pub/scm/linux/kernel/git/gregkh/pci-2.6
[powerpc.git] / drivers / scsi / scsi_sysfs.c
index a77b32d..5ec7a4f 100644 (file)
@@ -39,7 +39,7 @@ const char *scsi_device_state_name(enum scsi_device_state state)
        int i;
        char *name = NULL;
 
-       for (i = 0; i < sizeof(sdev_states)/sizeof(sdev_states[0]); i++) {
+       for (i = 0; i < ARRAY_SIZE(sdev_states); i++) {
                if (sdev_states[i].value == state) {
                        name = sdev_states[i].name;
                        break;
@@ -65,7 +65,7 @@ const char *scsi_host_state_name(enum scsi_host_state state)
        int i;
        char *name = NULL;
 
-       for (i = 0; i < sizeof(shost_states)/sizeof(shost_states[0]); i++) {
+       for (i = 0; i < ARRAY_SIZE(shost_states); i++) {
                if (shost_states[i].value == state) {
                        name = shost_states[i].name;
                        break;
@@ -160,7 +160,7 @@ store_shost_state(struct class_device *class_dev, const char *buf, size_t count)
        struct Scsi_Host *shost = class_to_shost(class_dev);
        enum scsi_host_state state = 0;
 
-       for (i = 0; i < sizeof(shost_states)/sizeof(shost_states[0]); i++) {
+       for (i = 0; i < ARRAY_SIZE(shost_states); i++) {
                const int len = strlen(shost_states[i].name);
                if (strncmp(shost_states[i].name, buf, len) == 0 &&
                   buf[len] == '\n') {
@@ -217,8 +217,9 @@ static void scsi_device_cls_release(struct class_device *class_dev)
        put_device(&sdev->sdev_gendev);
 }
 
-static void scsi_device_dev_release(struct device *dev)
+static void scsi_device_dev_release_usercontext(void *data)
 {
+       struct device *dev = data;
        struct scsi_device *sdev;
        struct device *parent;
        struct scsi_target *starget;
@@ -237,6 +238,7 @@ static void scsi_device_dev_release(struct device *dev)
 
        if (sdev->request_queue) {
                sdev->request_queue->queuedata = NULL;
+               /* user context needed to free queue */
                scsi_free_queue(sdev->request_queue);
                /* temporary expedient, try to catch use of queue lock
                 * after free of sdev */
@@ -252,6 +254,13 @@ static void scsi_device_dev_release(struct device *dev)
                put_device(parent);
 }
 
+static void scsi_device_dev_release(struct device *dev)
+{
+       struct scsi_device *sdp = to_scsi_device(dev);
+       execute_in_process_context(scsi_device_dev_release_usercontext, dev,
+                                  &sdp->ew);
+}
+
 static struct class sdev_class = {
        .name           = "scsi_device",
        .release        = scsi_device_cls_release,
@@ -277,7 +286,7 @@ static int scsi_bus_suspend(struct device * dev, pm_message_t state)
                return err;
 
        if (sht->suspend)
-               err = sht->suspend(sdev);
+               err = sht->suspend(sdev, state);
 
        return err;
 }
@@ -457,7 +466,7 @@ store_state_field(struct device *dev, struct device_attribute *attr, const char
        struct scsi_device *sdev = to_scsi_device(dev);
        enum scsi_device_state state = 0;
 
-       for (i = 0; i < sizeof(sdev_states)/sizeof(sdev_states[0]); i++) {
+       for (i = 0; i < ARRAY_SIZE(sdev_states); i++) {
                const int len = strlen(sdev_states[i].name);
                if (strncmp(sdev_states[i].name, buf, len) == 0 &&
                   buf[len] == '\n') {