[SCSI] megaraid_sas: driver fixed the device update issue
authorYang, Bo <Bo.Yang@lsi.com>
Sun, 6 Dec 2009 15:39:25 +0000 (08:39 -0700)
committerJames Bottomley <James.Bottomley@suse.de>
Wed, 17 Feb 2010 19:12:40 +0000 (13:12 -0600)
driver fixed the device update issue after get the AEN PD delete/ADD
and LD add/delete from FW.

Signed-off-by Bo Yang<bo.yang@lsi.com>
Signed-off-by: James Bottomley <James.Bottomley@suse.de>
drivers/scsi/megaraid/megaraid_sas.c

index a92998fe246849b9f4b9304c7ecee172d33b877c..9ad274cf73a2f3324499f7f6c8f54e1fdb5c5b26 100644 (file)
@@ -4072,6 +4072,7 @@ megasas_aen_polling(struct work_struct *work)
        struct  Scsi_Host *host;
        struct  scsi_device *sdev1;
        u16     pd_index = 0;
+       u16     ld_index = 0;
        int     i, j, doscan = 0;
        u32 seq_num;
        int error;
@@ -4087,8 +4088,124 @@ megasas_aen_polling(struct work_struct *work)
 
                switch (instance->evt_detail->code) {
                case MR_EVT_PD_INSERTED:
+                       if (megasas_get_pd_list(instance) == 0) {
+                       for (i = 0; i < MEGASAS_MAX_PD_CHANNELS; i++) {
+                               for (j = 0;
+                               j < MEGASAS_MAX_DEV_PER_CHANNEL;
+                               j++) {
+
+                               pd_index =
+                               (i * MEGASAS_MAX_DEV_PER_CHANNEL) + j;
+
+                               sdev1 =
+                               scsi_device_lookup(host, i, j, 0);
+
+                               if (instance->pd_list[pd_index].driveState
+                                               == MR_PD_STATE_SYSTEM) {
+                                               if (!sdev1) {
+                                               scsi_add_device(host, i, j, 0);
+                                               }
+
+                                       if (sdev1)
+                                               scsi_device_put(sdev1);
+                                       }
+                               }
+                       }
+                       }
+                       doscan = 0;
+                       break;
+
                case MR_EVT_PD_REMOVED:
+                       if (megasas_get_pd_list(instance) == 0) {
+                       megasas_get_pd_list(instance);
+                       for (i = 0; i < MEGASAS_MAX_PD_CHANNELS; i++) {
+                               for (j = 0;
+                               j < MEGASAS_MAX_DEV_PER_CHANNEL;
+                               j++) {
+
+                               pd_index =
+                               (i * MEGASAS_MAX_DEV_PER_CHANNEL) + j;
+
+                               sdev1 =
+                               scsi_device_lookup(host, i, j, 0);
+
+                               if (instance->pd_list[pd_index].driveState
+                                       == MR_PD_STATE_SYSTEM) {
+                                       if (sdev1) {
+                                               scsi_device_put(sdev1);
+                                       }
+                               } else {
+                                       if (sdev1) {
+                                               scsi_remove_device(sdev1);
+                                               scsi_device_put(sdev1);
+                                       }
+                               }
+                               }
+                       }
+                       }
+                       doscan = 0;
+                       break;
+
+               case MR_EVT_LD_OFFLINE:
+               case MR_EVT_LD_DELETED:
+                       megasas_get_ld_list(instance);
+                       for (i = 0; i < MEGASAS_MAX_LD_CHANNELS; i++) {
+                               for (j = 0;
+                               j < MEGASAS_MAX_DEV_PER_CHANNEL;
+                               j++) {
+
+                               ld_index =
+                               (i * MEGASAS_MAX_DEV_PER_CHANNEL) + j;
+
+                               sdev1 = scsi_device_lookup(host,
+                                       i + MEGASAS_MAX_LD_CHANNELS,
+                                       j,
+                                       0);
+
+                               if (instance->ld_ids[ld_index] != 0xff) {
+                                       if (sdev1) {
+                                               scsi_device_put(sdev1);
+                                       }
+                               } else {
+                                       if (sdev1) {
+                                               scsi_remove_device(sdev1);
+                                               scsi_device_put(sdev1);
+                                       }
+                               }
+                               }
+                       }
+                       doscan = 0;
+                       break;
+               case MR_EVT_LD_CREATED:
+                       megasas_get_ld_list(instance);
+                       for (i = 0; i < MEGASAS_MAX_LD_CHANNELS; i++) {
+                               for (j = 0;
+                                       j < MEGASAS_MAX_DEV_PER_CHANNEL;
+                                       j++) {
+                                       ld_index =
+                                       (i * MEGASAS_MAX_DEV_PER_CHANNEL) + j;
+
+                                       sdev1 = scsi_device_lookup(host,
+                                               i+MEGASAS_MAX_LD_CHANNELS,
+                                               j, 0);
+
+                                       if (instance->ld_ids[ld_index] !=
+                                                               0xff) {
+                                               if (!sdev1) {
+                                                       scsi_add_device(host,
+                                                               i + 2,
+                                                               j, 0);
+                                               }
+                                       }
+                                       if (sdev1) {
+                                               scsi_device_put(sdev1);
+                                       }
+                               }
+                       }
+                       doscan = 0;
+                       break;
                case MR_EVT_CTRL_HOST_BUS_SCAN_REQUESTED:
+               case MR_EVT_FOREIGN_CFG_IMPORTED:
                        doscan = 1;
                        break;
                default:
@@ -4123,6 +4240,31 @@ megasas_aen_polling(struct work_struct *work)
                                }
                        }
                }
+
+               megasas_get_ld_list(instance);
+               for (i = 0; i < MEGASAS_MAX_LD_CHANNELS; i++) {
+                       for (j = 0; j < MEGASAS_MAX_DEV_PER_CHANNEL; j++) {
+                               ld_index =
+                               (i * MEGASAS_MAX_DEV_PER_CHANNEL) + j;
+
+                               sdev1 = scsi_device_lookup(host,
+                                       i+MEGASAS_MAX_LD_CHANNELS, j, 0);
+                               if (instance->ld_ids[ld_index] != 0xff) {
+                                       if (!sdev1) {
+                                               scsi_add_device(host,
+                                                               i+2,
+                                                               j, 0);
+                                       } else {
+                                               scsi_device_put(sdev1);
+                                       }
+                               } else {
+                                       if (sdev1) {
+                                               scsi_remove_device(sdev1);
+                                               scsi_device_put(sdev1);
+                                       }
+                               }
+                       }
+               }
        }
 
        if ( instance->aen_cmd != NULL ) {