diff options
author | Yang, Bo <Bo.Yang@lsi.com> | 2009-10-06 16:27:54 -0400 |
---|---|---|
committer | James Bottomley <James.Bottomley@suse.de> | 2009-10-29 13:03:19 -0400 |
commit | 81e403ce3c6a34cd705bf54d4cdeefdeb7068a8d (patch) | |
tree | 7437520601436026c7d90e5520fddc8230eaac56 /drivers/scsi/megaraid/megaraid_sas.c | |
parent | 879111224d0784eab623fe8130a1f4481e0e1966 (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.c | 96 |
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 | */ | ||
2048 | static int | ||
2049 | megasas_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 | /* |