[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>
This commit is contained in:
Yang, Bo 2009-12-06 08:30:19 -07:00 committed by James Bottomley
parent 780a3762fb
commit bdc6fb8d69
2 changed files with 125 additions and 0 deletions

View File

@ -875,6 +875,12 @@ megasas_build_dcdb(struct megasas_instance *instance, struct scsi_cmnd *scp,
pthru->sge_count = megasas_make_sgl32(instance, scp, pthru->sge_count = megasas_make_sgl32(instance, scp,
&pthru->sgl); &pthru->sgl);
if (pthru->sge_count > instance->max_num_sge) {
printk(KERN_ERR "megasas: DCDB two many SGE NUM=%x\n",
pthru->sge_count);
return 0;
}
/* /*
* Sense info specific * Sense info specific
*/ */
@ -1001,6 +1007,12 @@ megasas_build_ldio(struct megasas_instance *instance, struct scsi_cmnd *scp,
} else } else
ldio->sge_count = megasas_make_sgl32(instance, scp, &ldio->sgl); ldio->sge_count = megasas_make_sgl32(instance, scp, &ldio->sgl);
if (ldio->sge_count > instance->max_num_sge) {
printk(KERN_ERR "megasas: build_ld_io: sge_count = %x\n",
ldio->sge_count);
return 0;
}
/* /*
* Sense info specific * Sense info specific
*/ */
@ -2296,6 +2308,86 @@ megasas_get_pd_list(struct megasas_instance *instance)
return ret; return ret;
} }
/*
* megasas_get_ld_list_info - Returns FW's ld_list structure
* @instance: Adapter soft state
* @ld_list: ld_list structure
*
* Issues an internal command (DCMD) to get the FW's controller PD
* list structure. This information is mainly used to find out SYSTEM
* supported by the FW.
*/
static int
megasas_get_ld_list(struct megasas_instance *instance)
{
int ret = 0, ld_index = 0, ids = 0;
struct megasas_cmd *cmd;
struct megasas_dcmd_frame *dcmd;
struct MR_LD_LIST *ci;
dma_addr_t ci_h = 0;
cmd = megasas_get_cmd(instance);
if (!cmd) {
printk(KERN_DEBUG "megasas_get_ld_list: Failed to get cmd\n");
return -ENOMEM;
}
dcmd = &cmd->frame->dcmd;
ci = pci_alloc_consistent(instance->pdev,
sizeof(struct MR_LD_LIST),
&ci_h);
if (!ci) {
printk(KERN_DEBUG "Failed to alloc mem in get_ld_list\n");
megasas_return_cmd(instance, cmd);
return -ENOMEM;
}
memset(ci, 0, sizeof(*ci));
memset(dcmd->mbox.b, 0, MFI_MBOX_SIZE);
dcmd->cmd = MFI_CMD_DCMD;
dcmd->cmd_status = 0xFF;
dcmd->sge_count = 1;
dcmd->flags = MFI_FRAME_DIR_READ;
dcmd->timeout = 0;
dcmd->data_xfer_len = sizeof(struct MR_LD_LIST);
dcmd->opcode = MR_DCMD_LD_GET_LIST;
dcmd->sgl.sge32[0].phys_addr = ci_h;
dcmd->sgl.sge32[0].length = sizeof(struct MR_LD_LIST);
dcmd->pad_0 = 0;
if (!megasas_issue_polled(instance, cmd)) {
ret = 0;
} else {
ret = -1;
}
/* the following function will get the instance PD LIST */
if ((ret == 0) && (ci->ldCount < MAX_LOGICAL_DRIVES)) {
memset(instance->ld_ids, 0xff, MEGASAS_MAX_LD_IDS);
for (ld_index = 0; ld_index < ci->ldCount; ld_index++) {
if (ci->ldList[ld_index].state != 0) {
ids = ci->ldList[ld_index].ref.targetId;
instance->ld_ids[ids] =
ci->ldList[ld_index].ref.targetId;
}
}
}
pci_free_consistent(instance->pdev,
sizeof(struct MR_LD_LIST),
ci,
ci_h);
megasas_return_cmd(instance, cmd);
return ret;
}
/** /**
* megasas_get_controller_info - Returns FW's controller structure * megasas_get_controller_info - Returns FW's controller structure
* @instance: Adapter soft state * @instance: Adapter soft state
@ -2593,6 +2685,9 @@ static int megasas_init_mfi(struct megasas_instance *instance)
(MEGASAS_MAX_PD * sizeof(struct megasas_pd_list))); (MEGASAS_MAX_PD * sizeof(struct megasas_pd_list)));
megasas_get_pd_list(instance); megasas_get_pd_list(instance);
memset(instance->ld_ids, 0xff, MEGASAS_MAX_LD_IDS);
megasas_get_ld_list(instance);
ctrl_info = kmalloc(sizeof(struct megasas_ctrl_info), GFP_KERNEL); ctrl_info = kmalloc(sizeof(struct megasas_ctrl_info), GFP_KERNEL);
/* /*

View File

@ -117,6 +117,7 @@
#define MFI_CMD_STP 0x08 #define MFI_CMD_STP 0x08
#define MR_DCMD_CTRL_GET_INFO 0x01010000 #define MR_DCMD_CTRL_GET_INFO 0x01010000
#define MR_DCMD_LD_GET_LIST 0x03010000
#define MR_DCMD_CTRL_CACHE_FLUSH 0x01101000 #define MR_DCMD_CTRL_CACHE_FLUSH 0x01101000
#define MR_FLUSH_CTRL_CACHE 0x01 #define MR_FLUSH_CTRL_CACHE 0x01
@ -349,6 +350,32 @@ struct megasas_pd_list {
u8 driveState; u8 driveState;
} __packed; } __packed;
/*
* defines the logical drive reference structure
*/
union MR_LD_REF {
struct {
u8 targetId;
u8 reserved;
u16 seqNum;
};
u32 ref;
} __packed;
/*
* defines the logical drive list structure
*/
struct MR_LD_LIST {
u32 ldCount;
u32 reserved;
struct {
union MR_LD_REF ref;
u8 state;
u8 reserved[3];
u64 size;
} ldList[MAX_LOGICAL_DRIVES];
} __packed;
/* /*
* SAS controller properties * SAS controller properties
*/ */
@ -637,6 +664,8 @@ struct megasas_ctrl_info {
#define MEGASAS_MAX_LD 64 #define MEGASAS_MAX_LD 64
#define MEGASAS_MAX_PD (MEGASAS_MAX_PD_CHANNELS * \ #define MEGASAS_MAX_PD (MEGASAS_MAX_PD_CHANNELS * \
MEGASAS_MAX_DEV_PER_CHANNEL) MEGASAS_MAX_DEV_PER_CHANNEL)
#define MEGASAS_MAX_LD_IDS (MEGASAS_MAX_LD_CHANNELS * \
MEGASAS_MAX_DEV_PER_CHANNEL)
#define MEGASAS_DBG_LVL 1 #define MEGASAS_DBG_LVL 1
@ -1187,6 +1216,7 @@ struct megasas_instance {
struct megasas_register_set __iomem *reg_set; struct megasas_register_set __iomem *reg_set;
struct megasas_pd_list pd_list[MEGASAS_MAX_PD]; struct megasas_pd_list pd_list[MEGASAS_MAX_PD];
u8 ld_ids[MEGASAS_MAX_LD_IDS];
s8 init_id; s8 init_id;
u16 max_num_sge; u16 max_num_sge;