[SCSI] megaraid_sas: report system PDs to OS
authorYang, Bo <Bo.Yang@lsi.com>
Tue, 6 Oct 2009 20:33:06 +0000 (14:33 -0600)
committerJames Bottomley <James.Bottomley@suse.de>
Thu, 29 Oct 2009 17:03:19 +0000 (13:03 -0400)
When OS issue inquiry, it will check driver's internal pd_list.

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 48c3658..9967ee7 100644 (file)
@@ -1115,24 +1115,76 @@ megasas_queue_command(struct scsi_cmnd *scmd, void (*done) (struct scsi_cmnd *))
        return 0;
 }
 
+static struct megasas_instance *megasas_lookup_instance(u16 host_no)
+{
+       int i;
+
+       for (i = 0; i < megasas_mgmt_info.max_index; i++) {
+
+               if ((megasas_mgmt_info.instance[i]) &&
+                   (megasas_mgmt_info.instance[i]->host->host_no == host_no))
+                       return megasas_mgmt_info.instance[i];
+       }
+
+       return NULL;
+}
+
 static int megasas_slave_configure(struct scsi_device *sdev)
 {
+       u16             pd_index = 0;
+       struct  megasas_instance *instance ;
+
+       instance = megasas_lookup_instance(sdev->host->host_no);
+
        /*
-        * Don't export physical disk devices to the disk driver.
-        *
-        * FIXME: Currently we don't export them to the midlayer at all.
-        *        That will be fixed once LSI engineers have audited the
-        *        firmware for possible issues.
-        */
-       if (sdev->channel < MEGASAS_MAX_PD_CHANNELS && sdev->type == TYPE_DISK)
+       * Don't export physical disk devices to the disk driver.
+       *
+       * FIXME: Currently we don't export them to the midlayer at all.
+       *        That will be fixed once LSI engineers have audited the
+       *        firmware for possible issues.
+       */
+       if (sdev->channel < MEGASAS_MAX_PD_CHANNELS &&
+                               sdev->type == TYPE_DISK) {
+               pd_index = (sdev->channel * MEGASAS_MAX_DEV_PER_CHANNEL) +
+                                                               sdev->id;
+               if (instance->pd_list[pd_index].driveState ==
+                                               MR_PD_STATE_SYSTEM) {
+                       blk_queue_rq_timeout(sdev->request_queue,
+                               MEGASAS_DEFAULT_CMD_TIMEOUT * HZ);
+                       return 0;
+               }
                return -ENXIO;
+       }
 
        /*
-        * The RAID firmware may require extended timeouts.
-        */
-       if (sdev->channel >= MEGASAS_MAX_PD_CHANNELS)
-               blk_queue_rq_timeout(sdev->request_queue,
-                                    MEGASAS_DEFAULT_CMD_TIMEOUT * HZ);
+       * The RAID firmware may require extended timeouts.
+       */
+       blk_queue_rq_timeout(sdev->request_queue,
+               MEGASAS_DEFAULT_CMD_TIMEOUT * HZ);
+       return 0;
+}
+
+static int megasas_slave_alloc(struct scsi_device *sdev)
+{
+       u16             pd_index = 0;
+       struct megasas_instance *instance ;
+       instance = megasas_lookup_instance(sdev->host->host_no);
+       if ((sdev->channel < MEGASAS_MAX_PD_CHANNELS) &&
+                               (sdev->type == TYPE_DISK)) {
+               /*
+                * Open the OS scan to the SYSTEM PD
+                */
+               pd_index =
+                       (sdev->channel * MEGASAS_MAX_DEV_PER_CHANNEL) +
+                       sdev->id;
+               if ((instance->pd_list[pd_index].driveState ==
+                                       MR_PD_STATE_SYSTEM) &&
+                       (instance->pd_list[pd_index].driveType ==
+                                               TYPE_DISK)) {
+                       return 0;
+               }
+               return -ENXIO;
+       }
        return 0;
 }
 
@@ -1423,6 +1475,7 @@ static struct scsi_host_template megasas_template = {
        .name = "LSI SAS based MegaRAID driver",
        .proc_name = "megaraid_sas",
        .slave_configure = megasas_slave_configure,
+       .slave_alloc = megasas_slave_alloc,
        .queuecommand = megasas_queue_command,
        .eh_device_reset_handler = megasas_reset_device,
        .eh_bus_reset_handler = megasas_reset_bus_host,
@@ -3455,20 +3508,6 @@ megasas_mgmt_fw_ioctl(struct megasas_instance *instance,
        return error;
 }
 
-static struct megasas_instance *megasas_lookup_instance(u16 host_no)
-{
-       int i;
-
-       for (i = 0; i < megasas_mgmt_info.max_index; i++) {
-
-               if ((megasas_mgmt_info.instance[i]) &&
-                   (megasas_mgmt_info.instance[i]->host->host_no == host_no))
-                       return megasas_mgmt_info.instance[i];
-       }
-
-       return NULL;
-}
-
 static int megasas_mgmt_ioctl_fw(struct file *file, unsigned long arg)
 {
        struct megasas_iocpacket __user *user_ioc =