aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/megaraid/megaraid_sas.c
diff options
context:
space:
mode:
authorYang, Bo <Bo.Yang@lsi.com>2009-12-06 10:30:19 -0500
committerJames Bottomley <James.Bottomley@suse.de>2010-02-17 14:12:10 -0500
commitbdc6fb8d69fab7b4b7f70823e3932bd8e4cfd7db (patch)
tree97425c74c6cf22c853ac2e8561888ea550d3384a /drivers/scsi/megaraid/megaraid_sas.c
parent780a3762fb9208748baac5aa9c63a4d4c9287753 (diff)
[SCSI] megaraid_sas: add the logical drive list to driver
Driver issue the get ld list to fw to get the logic drive list. Driver will keep the logic drive list for the internal use after driver load. 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.c95
1 files changed, 95 insertions, 0 deletions
diff --git a/drivers/scsi/megaraid/megaraid_sas.c b/drivers/scsi/megaraid/megaraid_sas.c
index 18d3a312c29f..a92998fe2468 100644
--- a/drivers/scsi/megaraid/megaraid_sas.c
+++ b/drivers/scsi/megaraid/megaraid_sas.c
@@ -875,6 +875,12 @@ megasas_build_dcdb(struct megasas_instance *instance, struct scsi_cmnd *scp,
875 pthru->sge_count = megasas_make_sgl32(instance, scp, 875 pthru->sge_count = megasas_make_sgl32(instance, scp,
876 &pthru->sgl); 876 &pthru->sgl);
877 877
878 if (pthru->sge_count > instance->max_num_sge) {
879 printk(KERN_ERR "megasas: DCDB two many SGE NUM=%x\n",
880 pthru->sge_count);
881 return 0;
882 }
883
878 /* 884 /*
879 * Sense info specific 885 * Sense info specific
880 */ 886 */
@@ -1001,6 +1007,12 @@ megasas_build_ldio(struct megasas_instance *instance, struct scsi_cmnd *scp,
1001 } else 1007 } else
1002 ldio->sge_count = megasas_make_sgl32(instance, scp, &ldio->sgl); 1008 ldio->sge_count = megasas_make_sgl32(instance, scp, &ldio->sgl);
1003 1009
1010 if (ldio->sge_count > instance->max_num_sge) {
1011 printk(KERN_ERR "megasas: build_ld_io: sge_count = %x\n",
1012 ldio->sge_count);
1013 return 0;
1014 }
1015
1004 /* 1016 /*
1005 * Sense info specific 1017 * Sense info specific
1006 */ 1018 */
@@ -2296,6 +2308,86 @@ megasas_get_pd_list(struct megasas_instance *instance)
2296 return ret; 2308 return ret;
2297} 2309}
2298 2310
2311/*
2312 * megasas_get_ld_list_info - Returns FW's ld_list structure
2313 * @instance: Adapter soft state
2314 * @ld_list: ld_list structure
2315 *
2316 * Issues an internal command (DCMD) to get the FW's controller PD
2317 * list structure. This information is mainly used to find out SYSTEM
2318 * supported by the FW.
2319 */
2320static int
2321megasas_get_ld_list(struct megasas_instance *instance)
2322{
2323 int ret = 0, ld_index = 0, ids = 0;
2324 struct megasas_cmd *cmd;
2325 struct megasas_dcmd_frame *dcmd;
2326 struct MR_LD_LIST *ci;
2327 dma_addr_t ci_h = 0;
2328
2329 cmd = megasas_get_cmd(instance);
2330
2331 if (!cmd) {
2332 printk(KERN_DEBUG "megasas_get_ld_list: Failed to get cmd\n");
2333 return -ENOMEM;
2334 }
2335
2336 dcmd = &cmd->frame->dcmd;
2337
2338 ci = pci_alloc_consistent(instance->pdev,
2339 sizeof(struct MR_LD_LIST),
2340 &ci_h);
2341
2342 if (!ci) {
2343 printk(KERN_DEBUG "Failed to alloc mem in get_ld_list\n");
2344 megasas_return_cmd(instance, cmd);
2345 return -ENOMEM;
2346 }
2347
2348 memset(ci, 0, sizeof(*ci));
2349 memset(dcmd->mbox.b, 0, MFI_MBOX_SIZE);
2350
2351 dcmd->cmd = MFI_CMD_DCMD;
2352 dcmd->cmd_status = 0xFF;
2353 dcmd->sge_count = 1;
2354 dcmd->flags = MFI_FRAME_DIR_READ;
2355 dcmd->timeout = 0;
2356 dcmd->data_xfer_len = sizeof(struct MR_LD_LIST);
2357 dcmd->opcode = MR_DCMD_LD_GET_LIST;
2358 dcmd->sgl.sge32[0].phys_addr = ci_h;
2359 dcmd->sgl.sge32[0].length = sizeof(struct MR_LD_LIST);
2360 dcmd->pad_0 = 0;
2361
2362 if (!megasas_issue_polled(instance, cmd)) {
2363 ret = 0;
2364 } else {
2365 ret = -1;
2366 }
2367
2368 /* the following function will get the instance PD LIST */
2369
2370 if ((ret == 0) && (ci->ldCount < MAX_LOGICAL_DRIVES)) {
2371 memset(instance->ld_ids, 0xff, MEGASAS_MAX_LD_IDS);
2372
2373 for (ld_index = 0; ld_index < ci->ldCount; ld_index++) {
2374 if (ci->ldList[ld_index].state != 0) {
2375 ids = ci->ldList[ld_index].ref.targetId;
2376 instance->ld_ids[ids] =
2377 ci->ldList[ld_index].ref.targetId;
2378 }
2379 }
2380 }
2381
2382 pci_free_consistent(instance->pdev,
2383 sizeof(struct MR_LD_LIST),
2384 ci,
2385 ci_h);
2386
2387 megasas_return_cmd(instance, cmd);
2388 return ret;
2389}
2390
2299/** 2391/**
2300 * megasas_get_controller_info - Returns FW's controller structure 2392 * megasas_get_controller_info - Returns FW's controller structure
2301 * @instance: Adapter soft state 2393 * @instance: Adapter soft state
@@ -2593,6 +2685,9 @@ static int megasas_init_mfi(struct megasas_instance *instance)
2593 (MEGASAS_MAX_PD * sizeof(struct megasas_pd_list))); 2685 (MEGASAS_MAX_PD * sizeof(struct megasas_pd_list)));
2594 megasas_get_pd_list(instance); 2686 megasas_get_pd_list(instance);
2595 2687
2688 memset(instance->ld_ids, 0xff, MEGASAS_MAX_LD_IDS);
2689 megasas_get_ld_list(instance);
2690
2596 ctrl_info = kmalloc(sizeof(struct megasas_ctrl_info), GFP_KERNEL); 2691 ctrl_info = kmalloc(sizeof(struct megasas_ctrl_info), GFP_KERNEL);
2597 2692
2598 /* 2693 /*