[PATCH 6/9] scsi: megaraid_sas - Report the unconfigured PD (system PD) to OS

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Add the support for reporting the unconfigured PD (system PD) to OS in MegaRAID SAS driver

Signed-off-by Bo Yang<bo.yang@xxxxxxx>

---
drivers/scsi/megaraid/megaraid_sas.c |  148 ++++++++++++++++++++++++++++++++++-
 drivers/scsi/megaraid/megaraid_sas.h |   92 +++++++++++++++++++++
 2 files changed, 237 insertions(+), 3 deletions(-)

diff -rupN linux-2.6.28_orig/drivers/scsi/megaraid/megaraid_sas.c linux-2.6.28_new/drivers/scsi/megaraid/megaraid_sas.c
--- linux-2.6.28_orig/drivers/scsi/megaraid/megaraid_sas.c      2009-02-12 16:16:42.000000000 -0500
+++ linux-2.6.28_new/drivers/scsi/megaraid/megaraid_sas.c       2009-02-12 16:24:41.000000000 -0500
@@ -1119,6 +1119,11 @@ megasas_queue_command(struct scsi_cmnd *

 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.
         *
@@ -1126,7 +1131,17 @@ static int megasas_slave_configure(struc
         *        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)
+       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) {
+                       sdev->timeout = 90 * HZ;
+                       return 0;
+               }
+
                return -ENXIO;

        /*
@@ -1423,6 +1438,29 @@ megasas_service_aen(struct megasas_insta
        megasas_return_cmd(instance, cmd);
 }

+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) {
+               /*
+                * 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;
+}
 /*
  * Scsi host template for megaraid_sas driver
  */
@@ -1432,6 +1470,7 @@ static struct scsi_host_template megasas
        .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,
@@ -2143,7 +2182,7 @@ megasas_mem_to_fw(struct megasas_instanc
        cmd = megasas_get_cmd(instance);

        if (!cmd) {
-               printk(KERN_DEBUG "megasas (get_pd_list): Failed to get cmd\n");
+               printk(KERN_DEBUG "megasas (mem_to_fw): Failed to get cmd\n");
                return -ENOMEM;
        }

@@ -2152,7 +2191,7 @@ megasas_mem_to_fw(struct megasas_instanc
        memset(dcmd->mbox.b, 0, MFI_MBOX_SIZE);

        dcmd->mbox.s[0] = instance->skinny_mm_alloc_ind;
-       dcmd->mbox.s[2] = MEGASAS_SKINNY_SZ_MEM_BK / 1024;
+       dcmd->mbox.s[2] = MEGASAS_SKINNY_SZ_MEM_BK/1024;

        dcmd->cmd = MFI_CMD_DCMD;
        dcmd->cmd_status = 0xFF;
@@ -2177,6 +2216,100 @@ megasas_mem_to_fw(struct megasas_instanc
 }

 /**
+ * megasas_get_pd_list_info -  Returns FW's pd_list structure
+ * @instance:                          Adapter soft state
+ * @pd_list:                           pd_list structure
+ *
+ * Issues an internal command (DCMD) to get the FW's controller PD
+ * list structure.  This information is mainly used to find out SYSTEM
+ * supported by the FW.
+ */
+static int
+megasas_get_pd_list(struct megasas_instance *instance)
+{
+       int ret = 0, pd_index = 0;
+       struct megasas_cmd *cmd;
+       struct megasas_dcmd_frame *dcmd;
+       struct MR_PD_LIST *ci;
+       struct MR_PD_ADDRESS *pd_addr;
+       dma_addr_t ci_h = 0;
+
+       cmd = megasas_get_cmd(instance);
+
+       if (!cmd) {
+               printk(KERN_DEBUG "megasas (get_pd_list): Failed to get cmd\n");
+               return -ENOMEM;
+       }
+
+       dcmd = &cmd->frame->dcmd;
+
+       ci = pci_alloc_consistent(instance->pdev,
+                 MEGASAS_MAX_PD * sizeof(struct MR_PD_LIST), &ci_h);
+
+       if (!ci) {
+               printk(KERN_DEBUG "Failed to alloc mem for pd_list\n");
+               megasas_return_cmd(instance, cmd);
+               return -ENOMEM;
+       }
+
+       memset(ci, 0, sizeof(*ci));
+       memset(dcmd->mbox.b, 0, MFI_MBOX_SIZE);
+
+       dcmd->mbox.b[0] = MR_PD_QUERY_TYPE_EXPOSED_TO_HOST;
+       dcmd->mbox.b[1] = 0;
+       dcmd->cmd = MFI_CMD_DCMD;
+       dcmd->cmd_status = 0xFF;
+       dcmd->sge_count = 1;
+       dcmd->flags = MFI_FRAME_DIR_READ;
+       dcmd->timeout = 0;
+       dcmd->data_xfer_len = MEGASAS_MAX_PD * sizeof(struct MR_PD_LIST);
+       dcmd->opcode = MR_DCMD_PD_LIST_QUERY;
+       dcmd->sgl.sge32[0].phys_addr = ci_h;
+       dcmd->sgl.sge32[0].length = MEGASAS_MAX_PD * sizeof(struct MR_PD_LIST);
+
+       if (!megasas_issue_polled(instance, cmd)) {
+               ret = 0;
+
+       } else {
+               ret = -1;
+       }
+
+       /*
+       * the following function will get the instance PD LIST.
+       */
+
+       pd_addr = ci->addr;
+
+       if ( ret == 0 &&
+               (ci->count <
+                 (MEGASAS_MAX_PD_CHANNELS * MEGASAS_MAX_DEV_PER_CHANNEL))) {
+
+               memset(instance->pd_list, 0,
+                       MEGASAS_MAX_PD * sizeof(struct megasas_pd_list));
+
+               for (pd_index = 0; pd_index < ci->count; pd_index++) {
+
+                       instance->pd_list[pd_addr->deviceId].tid        =
+                                                       pd_addr->deviceId;
+                       instance->pd_list[pd_addr->deviceId].driveType  =
+                                                       pd_addr->scsiDevType;
+                       instance->pd_list[pd_addr->deviceId].driveState =
+                                                       MR_PD_STATE_SYSTEM;
+
+                       pd_addr++;
+               }
+
+       }
+
+       pci_free_consistent(instance->pdev, sizeof(struct megasas_ctrl_info),
+                           ci, ci_h);
+
+       megasas_return_cmd(instance, cmd);
+
+       return ret;
+}
+
+/**
  * megasas_get_controller_info -       Returns FW's controller structure
  * @instance:                          Adapter soft state
  * @ctrl_info:                         Controller information structure
@@ -2488,6 +2621,15 @@ static int megasas_init_mfi(struct megas
        if (megasas_issue_init_mfi(instance))
                goto fail_fw_init;

+       /**
+       * for passthrough
+       * the following function will get the PD LIST.
+       **/
+
+       memset(instance->pd_list, 0,
+               MEGASAS_MAX_PD * sizeof(struct megasas_pd_list));
+       megasas_get_pd_list(instance);
+
        ctrl_info = kmalloc(sizeof(struct megasas_ctrl_info), GFP_KERNEL);

        /*
diff -rupN linux-2.6.28_orig/drivers/scsi/megaraid/megaraid_sas.h linux-2.6.28_new/drivers/scsi/megaraid/megaraid_sas.h
--- linux-2.6.28_orig/drivers/scsi/megaraid/megaraid_sas.h      2009-02-12 16:16:43.000000000 -0500
+++ linux-2.6.28_new/drivers/scsi/megaraid/megaraid_sas.h       2009-02-12 15:24:58.000000000 -0500
@@ -133,6 +133,7 @@
 #define MR_DCMD_CLUSTER                                0x08000000
 #define MR_DCMD_CLUSTER_RESET_ALL              0x08010100
 #define MR_DCMD_CLUSTER_RESET_LD               0x08010200
+#define MR_DCMD_PD_LIST_QUERY                  0x02010100

 #define MR_EVT_CFG_CLEARED                     0x0004

@@ -263,9 +264,98 @@ enum MR_EVT_ARGS {
        MR_EVT_ARGS_STR,
        MR_EVT_ARGS_TIME,
        MR_EVT_ARGS_ECC,
+       MR_EVT_ARGS_LD_PROP,
+       MR_EVT_ARGS_PD_SPARE,
+       MR_EVT_ARGS_PD_INDEX,
+       MR_EVT_ARGS_DIAG_PASS,
+       MR_EVT_ARGS_DIAG_FAIL,
+       MR_EVT_ARGS_PD_LBA_LBA,
+       MR_EVT_ARGS_PORT_PHY,
+       MR_EVT_ARGS_PD_MISSING,
+       MR_EVT_ARGS_PD_ADDRESS,
+       MR_EVT_ARGS_BITMAP,
+       MR_EVT_ARGS_CONNECTOR,
+       MR_EVT_ARGS_PD_PD,
+       MR_EVT_ARGS_PD_FRU,
+       MR_EVT_ARGS_PD_PATHINFO,
+       MR_EVT_ARGS_PD_POWER_STATE,
+       MR_EVT_ARGS_GENERIC,
+};

+/*
+ * define constants for device list query options
+ */
+enum MR_PD_QUERY_TYPE {
+    MR_PD_QUERY_TYPE_ALL                = 0,
+    MR_PD_QUERY_TYPE_STATE              = 1,
+    MR_PD_QUERY_TYPE_POWER_STATE        = 2,
+    MR_PD_QUERY_TYPE_MEDIA_TYPE         = 3,
+    MR_PD_QUERY_TYPE_SPEED              = 4,
+    MR_PD_QUERY_TYPE_EXPOSED_TO_HOST    = 5,
+} __attribute__ ((packed));
+
+#define MR_EVT_CFG_CLEARED                             0x0004
+#define MR_EVT_LD_STATE_CHANGE                         0x0051
+#define MR_EVT_PD_INSERTED                             0x005b
+#define MR_EVT_PD_REMOVED                              0x0070
+#define MR_EVT_LD_CREATED                              0x008a
+#define MR_EVT_LD_DELETED                              0x008b
+#define MR_EVT_FOREIGN_CFG_IMPORTED                    0x00db
+#define MR_EVT_LD_OFFLINE                              0x00fc
+#define MR_EVT_CTRL_HOST_BUS_SCAN_REQUESTED            0x0152
+
+
+enum MR_PD_STATE {
+    MR_PD_STATE_UNCONFIGURED_GOOD   = 0x00,
+    MR_PD_STATE_UNCONFIGURED_BAD    = 0x01,
+    MR_PD_STATE_HOT_SPARE           = 0x02,
+    MR_PD_STATE_OFFLINE             = 0x10,
+    MR_PD_STATE_FAILED              = 0x11,
+    MR_PD_STATE_REBUILD             = 0x14,
+    MR_PD_STATE_ONLINE              = 0x18,
+    MR_PD_STATE_COPYBACK            = 0x20,
+    MR_PD_STATE_SYSTEM              = 0x40,
 };

+ /*
+ * defines the physical drive address structure
+ */
+struct MR_PD_ADDRESS {
+       u16     deviceId;
+       u16     enclDeviceId;
+       union {
+               struct {
+                       u8  enclIndex;
+                       u8  slotNumber;
+               } mrPdAddress;
+               struct {
+                       u8  enclPosition;
+                       u8  enclConnectorIndex;
+               } mrEnclAddress;
+       };
+       u8      scsiDevType;
+       union {
+               u8      connectedPortBitmap;
+               u8      connectedPortNumbers;
+       };
+       u64     sasAddr[2];
+} __attribute__ ((packed));
+
+/*
+ * defines the physical drive list structure
+ */
+struct MR_PD_LIST {
+    u32             size;
+    u32             count;
+    struct MR_PD_ADDRESS   addr[1];
+} __attribute__ ((packed));
+
+struct megasas_pd_list {
+    u16             tid;
+    u8             driveType;
+    u8             driveState;
+} __attribute__ ((packed));
+
 /*
  * SAS controller properties
  */
@@ -552,6 +642,8 @@ struct megasas_ctrl_info {
 #define MEGASAS_DEFAULT_INIT_ID                        -1
 #define MEGASAS_MAX_LUN                                8
 #define MEGASAS_MAX_LD                         64
+#define MEGASAS_MAX_PD                         (MEGASAS_MAX_PD_CHANNELS * \
+                                               MEGASAS_MAX_DEV_PER_CHANNEL)

 #define MEGASAS_DBG_LVL                                1
--
To unsubscribe from this list: send the line "unsubscribe linux-scsi" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Index of Archives]     [SCSI Target Devel]     [Linux SCSI Target Infrastructure]     [Kernel Newbies]     [IDE]     [Security]     [Git]     [Netfilter]     [Bugtraq]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux ATA RAID]     [Linux IIO]     [Samba]     [Device Mapper]
  Powered by Linux