Commit 81e403ce authored by Yang, Bo's avatar Yang, Bo Committed by James Bottomley

[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: default avatarJames Bottomley <James.Bottomley@suse.de>
parent 87911122
...@@ -2036,6 +2036,98 @@ static int megasas_alloc_cmds(struct megasas_instance *instance) ...@@ -2036,6 +2036,98 @@ static int megasas_alloc_cmds(struct megasas_instance *instance)
return 0; return 0;
} }
/*
* megasas_get_pd_list_info - Returns FW's pd_list structure
* @instance: Adapter soft state
* @pd_list: pd_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_pd_list(struct megasas_instance *instance)
{
int ret = 0, pd_index = 0;
struct megasas_cmd *cmd;
struct megasas_dcmd_frame *dcmd;
struct MR_PD_LIST *ci;
struct MR_PD_ADDRESS *pd_addr;
dma_addr_t ci_h = 0;
cmd = megasas_get_cmd(instance);
if (!cmd) {
printk(KERN_DEBUG "megasas (get_pd_list): Failed to get cmd\n");
return -ENOMEM;
}
dcmd = &cmd->frame->dcmd;
ci = pci_alloc_consistent(instance->pdev,
MEGASAS_MAX_PD * sizeof(struct MR_PD_LIST), &ci_h);
if (!ci) {
printk(KERN_DEBUG "Failed to alloc mem for pd_list\n");
megasas_return_cmd(instance, cmd);
return -ENOMEM;
}
memset(ci, 0, sizeof(*ci));
memset(dcmd->mbox.b, 0, MFI_MBOX_SIZE);
dcmd->mbox.b[0] = MR_PD_QUERY_TYPE_EXPOSED_TO_HOST;
dcmd->mbox.b[1] = 0;
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 = MEGASAS_MAX_PD * sizeof(struct MR_PD_LIST);
dcmd->opcode = MR_DCMD_PD_LIST_QUERY;
dcmd->sgl.sge32[0].phys_addr = ci_h;
dcmd->sgl.sge32[0].length = MEGASAS_MAX_PD * sizeof(struct MR_PD_LIST);
if (!megasas_issue_polled(instance, cmd)) {
ret = 0;
} else {
ret = -1;
}
/*
* the following function will get the instance PD LIST.
*/
pd_addr = ci->addr;
if ( ret == 0 &&
(ci->count <
(MEGASAS_MAX_PD_CHANNELS * MEGASAS_MAX_DEV_PER_CHANNEL))) {
memset(instance->pd_list, 0,
MEGASAS_MAX_PD * sizeof(struct megasas_pd_list));
for (pd_index = 0; pd_index < ci->count; pd_index++) {
instance->pd_list[pd_addr->deviceId].tid =
pd_addr->deviceId;
instance->pd_list[pd_addr->deviceId].driveType =
pd_addr->scsiDevType;
instance->pd_list[pd_addr->deviceId].driveState =
MR_PD_STATE_SYSTEM;
pd_addr++;
}
}
pci_free_consistent(instance->pdev,
MEGASAS_MAX_PD * sizeof(struct MR_PD_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
...@@ -2326,6 +2418,10 @@ static int megasas_init_mfi(struct megasas_instance *instance) ...@@ -2326,6 +2418,10 @@ static int megasas_init_mfi(struct megasas_instance *instance)
if (megasas_issue_init_mfi(instance)) if (megasas_issue_init_mfi(instance))
goto fail_fw_init; goto fail_fw_init;
memset(instance->pd_list, 0 ,
(MEGASAS_MAX_PD * sizeof(struct megasas_pd_list)));
megasas_get_pd_list(instance);
ctrl_info = kmalloc(sizeof(struct megasas_ctrl_info), GFP_KERNEL); ctrl_info = kmalloc(sizeof(struct megasas_ctrl_info), GFP_KERNEL);
/* /*
......
...@@ -133,6 +133,7 @@ ...@@ -133,6 +133,7 @@
#define MR_DCMD_CLUSTER 0x08000000 #define MR_DCMD_CLUSTER 0x08000000
#define MR_DCMD_CLUSTER_RESET_ALL 0x08010100 #define MR_DCMD_CLUSTER_RESET_ALL 0x08010100
#define MR_DCMD_CLUSTER_RESET_LD 0x08010200 #define MR_DCMD_CLUSTER_RESET_LD 0x08010200
#define MR_DCMD_PD_LIST_QUERY 0x02010100
/* /*
* MFI command completion codes * MFI command completion codes
...@@ -253,9 +254,89 @@ enum MR_EVT_ARGS { ...@@ -253,9 +254,89 @@ enum MR_EVT_ARGS {
MR_EVT_ARGS_STR, MR_EVT_ARGS_STR,
MR_EVT_ARGS_TIME, MR_EVT_ARGS_TIME,
MR_EVT_ARGS_ECC, MR_EVT_ARGS_ECC,
MR_EVT_ARGS_LD_PROP,
MR_EVT_ARGS_PD_SPARE,
MR_EVT_ARGS_PD_INDEX,
MR_EVT_ARGS_DIAG_PASS,
MR_EVT_ARGS_DIAG_FAIL,
MR_EVT_ARGS_PD_LBA_LBA,
MR_EVT_ARGS_PORT_PHY,
MR_EVT_ARGS_PD_MISSING,
MR_EVT_ARGS_PD_ADDRESS,
MR_EVT_ARGS_BITMAP,
MR_EVT_ARGS_CONNECTOR,
MR_EVT_ARGS_PD_PD,
MR_EVT_ARGS_PD_FRU,
MR_EVT_ARGS_PD_PATHINFO,
MR_EVT_ARGS_PD_POWER_STATE,
MR_EVT_ARGS_GENERIC,
};
/*
* define constants for device list query options
*/
enum MR_PD_QUERY_TYPE {
MR_PD_QUERY_TYPE_ALL = 0,
MR_PD_QUERY_TYPE_STATE = 1,
MR_PD_QUERY_TYPE_POWER_STATE = 2,
MR_PD_QUERY_TYPE_MEDIA_TYPE = 3,
MR_PD_QUERY_TYPE_SPEED = 4,
MR_PD_QUERY_TYPE_EXPOSED_TO_HOST = 5,
}; };
enum MR_PD_STATE {
MR_PD_STATE_UNCONFIGURED_GOOD = 0x00,
MR_PD_STATE_UNCONFIGURED_BAD = 0x01,
MR_PD_STATE_HOT_SPARE = 0x02,
MR_PD_STATE_OFFLINE = 0x10,
MR_PD_STATE_FAILED = 0x11,
MR_PD_STATE_REBUILD = 0x14,
MR_PD_STATE_ONLINE = 0x18,
MR_PD_STATE_COPYBACK = 0x20,
MR_PD_STATE_SYSTEM = 0x40,
};
/*
* defines the physical drive address structure
*/
struct MR_PD_ADDRESS {
u16 deviceId;
u16 enclDeviceId;
union {
struct {
u8 enclIndex;
u8 slotNumber;
} mrPdAddress;
struct {
u8 enclPosition;
u8 enclConnectorIndex;
} mrEnclAddress;
};
u8 scsiDevType;
union {
u8 connectedPortBitmap;
u8 connectedPortNumbers;
};
u64 sasAddr[2];
} __packed;
/*
* defines the physical drive list structure
*/
struct MR_PD_LIST {
u32 size;
u32 count;
struct MR_PD_ADDRESS addr[1];
} __packed;
struct megasas_pd_list {
u16 tid;
u8 driveType;
u8 driveState;
} __packed;
/* /*
* SAS controller properties * SAS controller properties
*/ */
...@@ -284,7 +365,7 @@ struct megasas_ctrl_prop { ...@@ -284,7 +365,7 @@ struct megasas_ctrl_prop {
u8 expose_encl_devices; u8 expose_encl_devices;
u8 reserved[38]; u8 reserved[38];
} __attribute__ ((packed)); } __packed;
/* /*
* SAS controller information * SAS controller information
...@@ -527,7 +608,7 @@ struct megasas_ctrl_info { ...@@ -527,7 +608,7 @@ struct megasas_ctrl_info {
u8 pad[0x800 - 0x6a0]; u8 pad[0x800 - 0x6a0];
} __attribute__ ((packed)); } __packed;
/* /*
* =============================== * ===============================
...@@ -542,6 +623,8 @@ struct megasas_ctrl_info { ...@@ -542,6 +623,8 @@ struct megasas_ctrl_info {
#define MEGASAS_DEFAULT_INIT_ID -1 #define MEGASAS_DEFAULT_INIT_ID -1
#define MEGASAS_MAX_LUN 8 #define MEGASAS_MAX_LUN 8
#define MEGASAS_MAX_LD 64 #define MEGASAS_MAX_LD 64
#define MEGASAS_MAX_PD (MEGASAS_MAX_PD_CHANNELS * \
MEGASAS_MAX_DEV_PER_CHANNEL)
#define MEGASAS_DBG_LVL 1 #define MEGASAS_DBG_LVL 1
...@@ -1089,6 +1172,7 @@ struct megasas_instance { ...@@ -1089,6 +1172,7 @@ struct megasas_instance {
unsigned long base_addr; unsigned long base_addr;
struct megasas_register_set __iomem *reg_set; struct megasas_register_set __iomem *reg_set;
struct megasas_pd_list pd_list[MEGASAS_MAX_PD];
s8 init_id; s8 init_id;
u16 max_num_sge; u16 max_num_sge;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment