mirror of
https://github.com/torvalds/linux.git
synced 2024-11-27 22:51:35 +00:00
[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: James Bottomley <James.Bottomley@suse.de>
This commit is contained in:
parent
879111224d
commit
81e403ce3c
@ -2036,6 +2036,98 @@ static int megasas_alloc_cmds(struct megasas_instance *instance)
|
||||
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
|
||||
* @instance: Adapter soft state
|
||||
@ -2326,6 +2418,10 @@ static int megasas_init_mfi(struct megasas_instance *instance)
|
||||
if (megasas_issue_init_mfi(instance))
|
||||
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);
|
||||
|
||||
/*
|
||||
|
@ -133,6 +133,7 @@
|
||||
#define MR_DCMD_CLUSTER 0x08000000
|
||||
#define MR_DCMD_CLUSTER_RESET_ALL 0x08010100
|
||||
#define MR_DCMD_CLUSTER_RESET_LD 0x08010200
|
||||
#define MR_DCMD_PD_LIST_QUERY 0x02010100
|
||||
|
||||
/*
|
||||
* MFI command completion codes
|
||||
@ -253,9 +254,89 @@ enum MR_EVT_ARGS {
|
||||
MR_EVT_ARGS_STR,
|
||||
MR_EVT_ARGS_TIME,
|
||||
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
|
||||
*/
|
||||
@ -284,7 +365,7 @@ struct megasas_ctrl_prop {
|
||||
u8 expose_encl_devices;
|
||||
u8 reserved[38];
|
||||
|
||||
} __attribute__ ((packed));
|
||||
} __packed;
|
||||
|
||||
/*
|
||||
* SAS controller information
|
||||
@ -527,7 +608,7 @@ struct megasas_ctrl_info {
|
||||
|
||||
u8 pad[0x800 - 0x6a0];
|
||||
|
||||
} __attribute__ ((packed));
|
||||
} __packed;
|
||||
|
||||
/*
|
||||
* ===============================
|
||||
@ -542,6 +623,8 @@ struct megasas_ctrl_info {
|
||||
#define MEGASAS_DEFAULT_INIT_ID -1
|
||||
#define MEGASAS_MAX_LUN 8
|
||||
#define MEGASAS_MAX_LD 64
|
||||
#define MEGASAS_MAX_PD (MEGASAS_MAX_PD_CHANNELS * \
|
||||
MEGASAS_MAX_DEV_PER_CHANNEL)
|
||||
|
||||
#define MEGASAS_DBG_LVL 1
|
||||
|
||||
@ -1089,6 +1172,7 @@ struct megasas_instance {
|
||||
unsigned long base_addr;
|
||||
struct megasas_register_set __iomem *reg_set;
|
||||
|
||||
struct megasas_pd_list pd_list[MEGASAS_MAX_PD];
|
||||
s8 init_id;
|
||||
|
||||
u16 max_num_sge;
|
||||
|
Loading…
Reference in New Issue
Block a user