aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/megaraid/megaraid_sas.c
diff options
context:
space:
mode:
authorYang, Bo <Bo.Yang@lsi.com>2009-10-06 16:27:54 -0400
committerJames Bottomley <James.Bottomley@suse.de>2009-10-29 13:03:19 -0400
commit81e403ce3c6a34cd705bf54d4cdeefdeb7068a8d (patch)
tree7437520601436026c7d90e5520fddc8230eaac56 /drivers/scsi/megaraid/megaraid_sas.c
parent879111224d0784eab623fe8130a1f4481e0e1966 (diff)
[SCSI] megaraid_sas: infrastructure to get PDs from FW
Add system PDs to OS. Driver implemented the get_pd_list function to get the system PD from FW. Signed-off-by Bo Yang<bo.yang@lsi.com> Signed-off-by: James Bottomley <James.Bottomley@suse.de>
Diffstat (limited to 'drivers/scsi/megaraid/megaraid_sas.c')
-rw-r--r--drivers/scsi/megaraid/megaraid_sas.c96
1 files changed, 96 insertions, 0 deletions
diff --git a/drivers/scsi/megaraid/megaraid_sas.c b/drivers/scsi/megaraid/megaraid_sas.c
index b6e43271883c..48c3658d73a7 100644
--- a/drivers/scsi/megaraid/megaraid_sas.c
+++ b/drivers/scsi/megaraid/megaraid_sas.c
@@ -2036,6 +2036,98 @@ static int megasas_alloc_cmds(struct megasas_instance *instance)
2036 return 0; 2036 return 0;
2037} 2037}
2038 2038
2039/*
2040 * megasas_get_pd_list_info - Returns FW's pd_list structure
2041 * @instance: Adapter soft state
2042 * @pd_list: pd_list structure
2043 *
2044 * Issues an internal command (DCMD) to get the FW's controller PD
2045 * list structure. This information is mainly used to find out SYSTEM
2046 * supported by the FW.
2047 */
2048static int
2049megasas_get_pd_list(struct megasas_instance *instance)
2050{
2051 int ret = 0, pd_index = 0;
2052 struct megasas_cmd *cmd;
2053 struct megasas_dcmd_frame *dcmd;
2054 struct MR_PD_LIST *ci;
2055 struct MR_PD_ADDRESS *pd_addr;
2056 dma_addr_t ci_h = 0;
2057
2058 cmd = megasas_get_cmd(instance);
2059
2060 if (!cmd) {
2061 printk(KERN_DEBUG "megasas (get_pd_list): Failed to get cmd\n");
2062 return -ENOMEM;
2063 }
2064
2065 dcmd = &cmd->frame->dcmd;
2066
2067 ci = pci_alloc_consistent(instance->pdev,
2068 MEGASAS_MAX_PD * sizeof(struct MR_PD_LIST), &ci_h);
2069
2070 if (!ci) {
2071 printk(KERN_DEBUG "Failed to alloc mem for pd_list\n");
2072 megasas_return_cmd(instance, cmd);
2073 return -ENOMEM;
2074 }
2075
2076 memset(ci, 0, sizeof(*ci));
2077 memset(dcmd->mbox.b, 0, MFI_MBOX_SIZE);
2078
2079 dcmd->mbox.b[0] = MR_PD_QUERY_TYPE_EXPOSED_TO_HOST;
2080 dcmd->mbox.b[1] = 0;
2081 dcmd->cmd = MFI_CMD_DCMD;
2082 dcmd->cmd_status = 0xFF;
2083 dcmd->sge_count = 1;
2084 dcmd->flags = MFI_FRAME_DIR_READ;
2085 dcmd->timeout = 0;
2086 dcmd->data_xfer_len = MEGASAS_MAX_PD * sizeof(struct MR_PD_LIST);
2087 dcmd->opcode = MR_DCMD_PD_LIST_QUERY;
2088 dcmd->sgl.sge32[0].phys_addr = ci_h;
2089 dcmd->sgl.sge32[0].length = MEGASAS_MAX_PD * sizeof(struct MR_PD_LIST);
2090
2091 if (!megasas_issue_polled(instance, cmd)) {
2092 ret = 0;
2093 } else {
2094 ret = -1;
2095 }
2096
2097 /*
2098 * the following function will get the instance PD LIST.
2099 */
2100
2101 pd_addr = ci->addr;
2102
2103 if ( ret == 0 &&
2104 (ci->count <
2105 (MEGASAS_MAX_PD_CHANNELS * MEGASAS_MAX_DEV_PER_CHANNEL))) {
2106
2107 memset(instance->pd_list, 0,
2108 MEGASAS_MAX_PD * sizeof(struct megasas_pd_list));
2109
2110 for (pd_index = 0; pd_index < ci->count; pd_index++) {
2111
2112 instance->pd_list[pd_addr->deviceId].tid =
2113 pd_addr->deviceId;
2114 instance->pd_list[pd_addr->deviceId].driveType =
2115 pd_addr->scsiDevType;
2116 instance->pd_list[pd_addr->deviceId].driveState =
2117 MR_PD_STATE_SYSTEM;
2118 pd_addr++;
2119 }
2120 }
2121
2122 pci_free_consistent(instance->pdev,
2123 MEGASAS_MAX_PD * sizeof(struct MR_PD_LIST),
2124 ci, ci_h);
2125 megasas_return_cmd(instance, cmd);
2126
2127 return ret;
2128}
2129
2130
2039/** 2131/**
2040 * megasas_get_controller_info - Returns FW's controller structure 2132 * megasas_get_controller_info - Returns FW's controller structure
2041 * @instance: Adapter soft state 2133 * @instance: Adapter soft state
@@ -2326,6 +2418,10 @@ static int megasas_init_mfi(struct megasas_instance *instance)
2326 if (megasas_issue_init_mfi(instance)) 2418 if (megasas_issue_init_mfi(instance))
2327 goto fail_fw_init; 2419 goto fail_fw_init;
2328 2420
2421 memset(instance->pd_list, 0 ,
2422 (MEGASAS_MAX_PD * sizeof(struct megasas_pd_list)));
2423 megasas_get_pd_list(instance);
2424
2329 ctrl_info = kmalloc(sizeof(struct megasas_ctrl_info), GFP_KERNEL); 2425 ctrl_info = kmalloc(sizeof(struct megasas_ctrl_info), GFP_KERNEL);
2330 2426
2331 /* 2427 /*