forked from Minki/linux
[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:
parent
780a3762fb
commit
bdc6fb8d69
@ -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);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -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;
|
||||||
|
Loading…
Reference in New Issue
Block a user