aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
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
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')
-rw-r--r--drivers/scsi/megaraid/megaraid_sas.c96
-rw-r--r--drivers/scsi/megaraid/megaraid_sas.h88
2 files changed, 182 insertions, 2 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 /*
diff --git a/drivers/scsi/megaraid/megaraid_sas.h b/drivers/scsi/megaraid/megaraid_sas.h
index 365a96172070..8ac6b2659c12 100644
--- a/drivers/scsi/megaraid/megaraid_sas.h
+++ b/drivers/scsi/megaraid/megaraid_sas.h
@@ -133,6 +133,7 @@
133#define MR_DCMD_CLUSTER 0x08000000 133#define MR_DCMD_CLUSTER 0x08000000
134#define MR_DCMD_CLUSTER_RESET_ALL 0x08010100 134#define MR_DCMD_CLUSTER_RESET_ALL 0x08010100
135#define MR_DCMD_CLUSTER_RESET_LD 0x08010200 135#define MR_DCMD_CLUSTER_RESET_LD 0x08010200
136#define MR_DCMD_PD_LIST_QUERY 0x02010100
136 137
137/* 138/*
138 * MFI command completion codes 139 * MFI command completion codes
@@ -253,9 +254,89 @@ enum MR_EVT_ARGS {
253 MR_EVT_ARGS_STR, 254 MR_EVT_ARGS_STR,
254 MR_EVT_ARGS_TIME, 255 MR_EVT_ARGS_TIME,
255 MR_EVT_ARGS_ECC, 256 MR_EVT_ARGS_ECC,
257 MR_EVT_ARGS_LD_PROP,
258 MR_EVT_ARGS_PD_SPARE,
259 MR_EVT_ARGS_PD_INDEX,
260 MR_EVT_ARGS_DIAG_PASS,
261 MR_EVT_ARGS_DIAG_FAIL,
262 MR_EVT_ARGS_PD_LBA_LBA,
263 MR_EVT_ARGS_PORT_PHY,
264 MR_EVT_ARGS_PD_MISSING,
265 MR_EVT_ARGS_PD_ADDRESS,
266 MR_EVT_ARGS_BITMAP,
267 MR_EVT_ARGS_CONNECTOR,
268 MR_EVT_ARGS_PD_PD,
269 MR_EVT_ARGS_PD_FRU,
270 MR_EVT_ARGS_PD_PATHINFO,
271 MR_EVT_ARGS_PD_POWER_STATE,
272 MR_EVT_ARGS_GENERIC,
273};
256 274
275/*
276 * define constants for device list query options
277 */
278enum MR_PD_QUERY_TYPE {
279 MR_PD_QUERY_TYPE_ALL = 0,
280 MR_PD_QUERY_TYPE_STATE = 1,
281 MR_PD_QUERY_TYPE_POWER_STATE = 2,
282 MR_PD_QUERY_TYPE_MEDIA_TYPE = 3,
283 MR_PD_QUERY_TYPE_SPEED = 4,
284 MR_PD_QUERY_TYPE_EXPOSED_TO_HOST = 5,
257}; 285};
258 286
287enum MR_PD_STATE {
288 MR_PD_STATE_UNCONFIGURED_GOOD = 0x00,
289 MR_PD_STATE_UNCONFIGURED_BAD = 0x01,
290 MR_PD_STATE_HOT_SPARE = 0x02,
291 MR_PD_STATE_OFFLINE = 0x10,
292 MR_PD_STATE_FAILED = 0x11,
293 MR_PD_STATE_REBUILD = 0x14,
294 MR_PD_STATE_ONLINE = 0x18,
295 MR_PD_STATE_COPYBACK = 0x20,
296 MR_PD_STATE_SYSTEM = 0x40,
297 };
298
299
300 /*
301 * defines the physical drive address structure
302 */
303struct MR_PD_ADDRESS {
304 u16 deviceId;
305 u16 enclDeviceId;
306
307 union {
308 struct {
309 u8 enclIndex;
310 u8 slotNumber;
311 } mrPdAddress;
312 struct {
313 u8 enclPosition;
314 u8 enclConnectorIndex;
315 } mrEnclAddress;
316 };
317 u8 scsiDevType;
318 union {
319 u8 connectedPortBitmap;
320 u8 connectedPortNumbers;
321 };
322 u64 sasAddr[2];
323} __packed;
324
325/*
326 * defines the physical drive list structure
327 */
328struct MR_PD_LIST {
329 u32 size;
330 u32 count;
331 struct MR_PD_ADDRESS addr[1];
332} __packed;
333
334struct megasas_pd_list {
335 u16 tid;
336 u8 driveType;
337 u8 driveState;
338} __packed;
339
259/* 340/*
260 * SAS controller properties 341 * SAS controller properties
261 */ 342 */
@@ -284,7 +365,7 @@ struct megasas_ctrl_prop {
284 u8 expose_encl_devices; 365 u8 expose_encl_devices;
285 u8 reserved[38]; 366 u8 reserved[38];
286 367
287} __attribute__ ((packed)); 368} __packed;
288 369
289/* 370/*
290 * SAS controller information 371 * SAS controller information
@@ -527,7 +608,7 @@ struct megasas_ctrl_info {
527 608
528 u8 pad[0x800 - 0x6a0]; 609 u8 pad[0x800 - 0x6a0];
529 610
530} __attribute__ ((packed)); 611} __packed;
531 612
532/* 613/*
533 * =============================== 614 * ===============================
@@ -542,6 +623,8 @@ struct megasas_ctrl_info {
542#define MEGASAS_DEFAULT_INIT_ID -1 623#define MEGASAS_DEFAULT_INIT_ID -1
543#define MEGASAS_MAX_LUN 8 624#define MEGASAS_MAX_LUN 8
544#define MEGASAS_MAX_LD 64 625#define MEGASAS_MAX_LD 64
626#define MEGASAS_MAX_PD (MEGASAS_MAX_PD_CHANNELS * \
627 MEGASAS_MAX_DEV_PER_CHANNEL)
545 628
546#define MEGASAS_DBG_LVL 1 629#define MEGASAS_DBG_LVL 1
547 630
@@ -1089,6 +1172,7 @@ struct megasas_instance {
1089 unsigned long base_addr; 1172 unsigned long base_addr;
1090 struct megasas_register_set __iomem *reg_set; 1173 struct megasas_register_set __iomem *reg_set;
1091 1174
1175 struct megasas_pd_list pd_list[MEGASAS_MAX_PD];
1092 s8 init_id; 1176 s8 init_id;
1093 1177
1094 u16 max_num_sge; 1178 u16 max_num_sge;