Gitweb:     
http://git.kernel.org/git/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commit;h=0995ad382df77b438d0c1e4f93ff349aa2eb9caf
Commit:     0995ad382df77b438d0c1e4f93ff349aa2eb9caf
Parent:     d9aa3af09cdc5d3ae0e67bed4107bcf7e25b9f31
Author:     Salyzyn, Mark <[EMAIL PROTECTED]>
AuthorDate: Fri Jan 11 11:56:07 2008 -0800
Committer:  James Bottomley <[EMAIL PROTECTED]>
CommitDate: Wed Jan 23 11:29:26 2008 -0600

    [SCSI] aacraid: respond to enclosure service events
    
    Added support to respond to enclosure service events
    (controller AIFs) to add, online or offline physical targets
    reported to sg. Also added online and offlining of arrays.
    Removed an automatic variable definition in a sub block that
    hid an earlier definition, determined to be inert as the
    sub-block use did not interfere. Bumped the driver versioning
    to stamp the addition of this feature.
    
    Signed-off-by: Mark Salyzyn <[EMAIL PROTECTED]>
    Signed-off-by: James Bottomley <[EMAIL PROTECTED]>
---
 drivers/scsi/aacraid/aacraid.h |    5 ++-
 drivers/scsi/aacraid/commsup.c |   96 +++++++++++++++++++++++++++++++---------
 2 files changed, 79 insertions(+), 22 deletions(-)

diff --git a/drivers/scsi/aacraid/aacraid.h b/drivers/scsi/aacraid/aacraid.h
index 85b85ae..858b974 100644
--- a/drivers/scsi/aacraid/aacraid.h
+++ b/drivers/scsi/aacraid/aacraid.h
@@ -12,7 +12,7 @@
  
*----------------------------------------------------------------------------*/
 
 #ifndef AAC_DRIVER_BUILD
-# define AAC_DRIVER_BUILD 2449
+# define AAC_DRIVER_BUILD 2454
 # define AAC_DRIVER_BRANCH "-ms"
 #endif
 #define MAXIMUM_NUM_CONTAINERS 32
@@ -1772,6 +1772,9 @@ extern struct aac_common aac_config;
 #define                        AifEnConfigChange       3       /* Adapter 
configuration change */
 #define                        AifEnContainerChange    4       /* Container 
configuration change */
 #define                        AifEnDeviceFailure      5       /* SCSI device 
failed */
+#define                        AifEnEnclosureManagement 13     /* EM_DRIVE_* */
+#define                                EM_DRIVE_INSERTION      31
+#define                                EM_DRIVE_REMOVAL        32
 #define                        AifEnBatteryEvent       14      /* Change in 
Battery State */
 #define                        AifEnAddContainer       15      /* A new array 
was created */
 #define                        AifEnDeleteContainer    16      /* A container 
was deleted */
diff --git a/drivers/scsi/aacraid/commsup.c b/drivers/scsi/aacraid/commsup.c
index 3a3017d..6d88f30 100644
--- a/drivers/scsi/aacraid/commsup.c
+++ b/drivers/scsi/aacraid/commsup.c
@@ -775,20 +775,20 @@ static void aac_handle_aif(struct aac_dev * dev, struct 
fib * fibptr)
 {
        struct hw_fib * hw_fib = fibptr->hw_fib_va;
        struct aac_aifcmd * aifcmd = (struct aac_aifcmd *)hw_fib->data;
-       u32 container;
+       u32 channel, id, lun, container;
        struct scsi_device *device;
        enum {
                NOTHING,
                DELETE,
                ADD,
                CHANGE
-       } device_config_needed;
+       } device_config_needed = NOTHING;
 
        /* Sniff for container changes */
 
        if (!dev || !dev->fsa_dev)
                return;
-       container = (u32)-1;
+       container = channel = id = lun = (u32)-1;
 
        /*
         *      We have set this up to try and minimize the number of
@@ -901,6 +901,36 @@ static void aac_handle_aif(struct aac_dev * dev, struct 
fib * fibptr)
                case AifEnConfigChange:
                        break;
 
+               case AifEnEnclosureManagement:
+                       switch (le32_to_cpu(((__le32 *)aifcmd->data)[3])) {
+                       case EM_DRIVE_INSERTION:
+                       case EM_DRIVE_REMOVAL:
+                               container = le32_to_cpu(
+                                       ((__le32 *)aifcmd->data)[2]);
+                               if ((container >> 28))
+                                       break;
+                               channel = (container >> 24) & 0xF;
+                               if (channel >= dev->maximum_num_channels)
+                                       break;
+                               id = container & 0xFFFF;
+                               lun = (container >> 16) & 0xFF;
+                               if (id >= dev->maximum_num_physicals) {
+                                       /* legacy dev_t ? */
+                                       if ((0x2000 <= id) || lun || channel ||
+                                         ((channel = (id >> 7) & 0x3F) >=
+                                         dev->maximum_num_channels))
+                                               break;
+                                       lun = (id >> 4) & 7;
+                                       id &= 0xF;
+                               }
+                               channel = aac_phys_to_logical(channel);
+                               device_config_needed =
+                                 (((__le32 *)aifcmd->data)[3]
+                                   == cpu_to_le32(EM_DRIVE_INSERTION)) ?
+                                 ADD : DELETE;
+                               break;
+                       }
+                       break;
                }
 
                /*
@@ -969,7 +999,7 @@ static void aac_handle_aif(struct aac_dev * dev, struct fib 
* fibptr)
                break;
        }
 
-       device_config_needed = NOTHING;
+       if (device_config_needed == NOTHING)
        for (container = 0; container < dev->maximum_num_containers;
            ++container) {
                if ((dev->fsa_dev[container].config_waiting_on == 0) &&
@@ -978,6 +1008,9 @@ static void aac_handle_aif(struct aac_dev * dev, struct 
fib * fibptr)
                        device_config_needed =
                                dev->fsa_dev[container].config_needed;
                        dev->fsa_dev[container].config_needed = NOTHING;
+                       channel = CONTAINER_TO_CHANNEL(container);
+                       id = CONTAINER_TO_ID(container);
+                       lun = CONTAINER_TO_LUN(container);
                        break;
                }
        }
@@ -1001,34 +1034,56 @@ static void aac_handle_aif(struct aac_dev * dev, struct 
fib * fibptr)
        /*
         * force reload of disk info via aac_probe_container
         */
-       if ((device_config_needed == CHANGE)
-        && (dev->fsa_dev[container].valid == 1))
-               dev->fsa_dev[container].valid = 2;
-       if ((device_config_needed == CHANGE) ||
-                       (device_config_needed == ADD))
+       if ((channel == CONTAINER_CHANNEL) &&
+         (device_config_needed != NOTHING)) {
+               if (dev->fsa_dev[container].valid == 1)
+                       dev->fsa_dev[container].valid = 2;
                aac_probe_container(dev, container);
-       device = scsi_device_lookup(dev->scsi_host_ptr, 
-               CONTAINER_TO_CHANNEL(container), 
-               CONTAINER_TO_ID(container), 
-               CONTAINER_TO_LUN(container));
+       }
+       device = scsi_device_lookup(dev->scsi_host_ptr, channel, id, lun);
        if (device) {
                switch (device_config_needed) {
                case DELETE:
+                       if (scsi_device_online(device)) {
+                               scsi_device_set_state(device, SDEV_OFFLINE);
+                               sdev_printk(KERN_INFO, device,
+                                       "Device offlined - %s\n",
+                                       (channel == CONTAINER_CHANNEL) ?
+                                               "array deleted" :
+                                               "enclosure services event");
+                       }
+                       break;
+               case ADD:
+                       if (!scsi_device_online(device)) {
+                               sdev_printk(KERN_INFO, device,
+                                       "Device online - %s\n",
+                                       (channel == CONTAINER_CHANNEL) ?
+                                               "array created" :
+                                               "enclosure services event");
+                               scsi_device_set_state(device, SDEV_RUNNING);
+                       }
+                       /* FALLTHRU */
                case CHANGE:
+                       if ((channel == CONTAINER_CHANNEL)
+                        && (!dev->fsa_dev[container].valid)) {
+                               if (!scsi_device_online(device))
+                                       break;
+                               scsi_device_set_state(device, SDEV_OFFLINE);
+                               sdev_printk(KERN_INFO, device,
+                                       "Device offlined - %s\n",
+                                       "array failed");
+                               break;
+                       }
                        scsi_rescan_device(&device->sdev_gendev);
 
                default:
                        break;
                }
                scsi_device_put(device);
+               device_config_needed = NOTHING;
        }
-       if (device_config_needed == ADD) {
-               scsi_add_device(dev->scsi_host_ptr,
-                 CONTAINER_TO_CHANNEL(container),
-                 CONTAINER_TO_ID(container),
-                 CONTAINER_TO_LUN(container));
-       }
-
+       if (device_config_needed == ADD)
+               scsi_add_device(dev->scsi_host_ptr, channel, id, lun);
 }
 
 static int _aac_reset_adapter(struct aac_dev *aac, int forced)
@@ -1469,7 +1524,6 @@ int aac_command_thread(void *data)
                                *(__le32 *)hw_fib->data = cpu_to_le32(ST_OK);
                                aac_fib_adapter_complete(fib, (u16)sizeof(u32));
                        } else {
-                               struct list_head *entry;
                                /* The u32 here is important and intended. We 
are using
                                   32bit wrapping time to fit the adapter field 
*/
                                   
-
To unsubscribe from this list: send the line "unsubscribe git-commits-head" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to