aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/scsi/megaraid/megaraid_sas.c95
-rw-r--r--drivers/scsi/megaraid/megaraid_sas.h30
2 files changed, 125 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 /*
diff --git a/drivers/scsi/megaraid/megaraid_sas.h b/drivers/scsi/megaraid/megaraid_sas.h
index 72b28e436e32..1135c94bedbd 100644
--- a/drivers/scsi/megaraid/megaraid_sas.h
+++ b/drivers/scsi/megaraid/megaraid_sas.h
@@ -117,6 +117,7 @@
117#define MFI_CMD_STP 0x08 117#define MFI_CMD_STP 0x08
118 118
119#define MR_DCMD_CTRL_GET_INFO 0x01010000 119#define MR_DCMD_CTRL_GET_INFO 0x01010000
120#define MR_DCMD_LD_GET_LIST 0x03010000
120 121
121#define MR_DCMD_CTRL_CACHE_FLUSH 0x01101000 122#define MR_DCMD_CTRL_CACHE_FLUSH 0x01101000
122#define MR_FLUSH_CTRL_CACHE 0x01 123#define MR_FLUSH_CTRL_CACHE 0x01
@@ -349,6 +350,32 @@ struct megasas_pd_list {
349 u8 driveState; 350 u8 driveState;
350} __packed; 351} __packed;
351 352
353 /*
354 * defines the logical drive reference structure
355 */
356union MR_LD_REF {
357 struct {
358 u8 targetId;
359 u8 reserved;
360 u16 seqNum;
361 };
362 u32 ref;
363} __packed;
364
365/*
366 * defines the logical drive list structure
367 */
368struct MR_LD_LIST {
369 u32 ldCount;
370 u32 reserved;
371 struct {
372 union MR_LD_REF ref;
373 u8 state;
374 u8 reserved[3];
375 u64 size;
376 } ldList[MAX_LOGICAL_DRIVES];
377} __packed;
378
352/* 379/*
353 * SAS controller properties 380 * SAS controller properties
354 */ 381 */
@@ -637,6 +664,8 @@ struct megasas_ctrl_info {
637#define MEGASAS_MAX_LD 64 664#define MEGASAS_MAX_LD 64
638#define MEGASAS_MAX_PD (MEGASAS_MAX_PD_CHANNELS * \ 665#define MEGASAS_MAX_PD (MEGASAS_MAX_PD_CHANNELS * \
639 MEGASAS_MAX_DEV_PER_CHANNEL) 666 MEGASAS_MAX_DEV_PER_CHANNEL)
667#define MEGASAS_MAX_LD_IDS (MEGASAS_MAX_LD_CHANNELS * \
668 MEGASAS_MAX_DEV_PER_CHANNEL)
640 669
641#define MEGASAS_DBG_LVL 1 670#define MEGASAS_DBG_LVL 1
642 671
@@ -1187,6 +1216,7 @@ struct megasas_instance {
1187 struct megasas_register_set __iomem *reg_set; 1216 struct megasas_register_set __iomem *reg_set;
1188 1217
1189 struct megasas_pd_list pd_list[MEGASAS_MAX_PD]; 1218 struct megasas_pd_list pd_list[MEGASAS_MAX_PD];
1219 u8 ld_ids[MEGASAS_MAX_LD_IDS];
1190 s8 init_id; 1220 s8 init_id;
1191 1221
1192 u16 max_num_sge; 1222 u16 max_num_sge;