svn commit: r342065 - head/sys/dev/mrsas
Kashyap D Desai
kadesai at FreeBSD.org
Fri Dec 14 08:03:29 UTC 2018
Author: kadesai
Date: Fri Dec 14 08:03:28 2018
New Revision: 342065
URL: https://svnweb.freebsd.org/changeset/base/342065
Log:
This patch will add support for new DCMD to get PD information and a single data structure
to specify LD and JBOD.
Submitted by: Sumit Saxena <sumit.saxena at broadcom.com>
Reviewed by: Kashyap Desai <Kashyap.Desai at broadcom.com>
Approved by: ken
MFC after: 3 days
Sponsored by: Broadcom Inc
Modified:
head/sys/dev/mrsas/mrsas.c
head/sys/dev/mrsas/mrsas.h
Modified: head/sys/dev/mrsas/mrsas.c
==============================================================================
--- head/sys/dev/mrsas/mrsas.c Fri Dec 14 08:02:44 2018 (r342064)
+++ head/sys/dev/mrsas/mrsas.c Fri Dec 14 08:03:28 2018 (r342065)
@@ -90,6 +90,8 @@ static void mrsas_update_ext_vd_details(struct mrsas_s
static int
mrsas_issue_blocked_abort_cmd(struct mrsas_softc *sc,
struct mrsas_mfi_cmd *cmd_to_abort);
+static void
+mrsas_get_pd_info(struct mrsas_softc *sc, u_int16_t device_id);
static struct mrsas_softc *
mrsas_get_softc_instance(struct cdev *dev,
u_long cmd, caddr_t arg);
@@ -971,6 +973,7 @@ attach_fail:
static void
mrsas_ich_startup(void *arg)
{
+ int i = 0;
struct mrsas_softc *sc = (struct mrsas_softc *)arg;
/*
@@ -1006,6 +1009,13 @@ mrsas_ich_startup(void *arg)
/* Enable Interrupts */
mrsas_enable_intr(sc);
+ /* Call DCMD get_pd_info for all system PDs */
+ for (i = 0; i < MRSAS_MAX_PD; i++) {
+ if ((sc->target_list[i].target_id != 0xffff) &&
+ sc->pd_info_mem)
+ mrsas_get_pd_info(sc, sc->target_list[i].target_id);
+ }
+
/* Initiate AEN (Asynchronous Event Notification) */
if (mrsas_start_aen(sc)) {
device_printf(sc->mrsas_dev, "Error: AEN registration FAILED !!! "
@@ -1216,6 +1226,16 @@ mrsas_free_mem(struct mrsas_softc *sc)
bus_dma_tag_destroy(sc->evt_detail_tag);
/*
+ * Free PD info memory
+ */
+ if (sc->pd_info_phys_addr)
+ bus_dmamap_unload(sc->pd_info_tag, sc->pd_info_dmamap);
+ if (sc->pd_info_mem != NULL)
+ bus_dmamem_free(sc->pd_info_tag, sc->pd_info_mem, sc->pd_info_dmamap);
+ if (sc->pd_info_tag != NULL)
+ bus_dma_tag_destroy(sc->pd_info_tag);
+
+ /*
* Free MFI frames
*/
if (sc->mfi_cmd_list) {
@@ -1808,7 +1828,7 @@ static int
mrsas_alloc_mem(struct mrsas_softc *sc)
{
u_int32_t verbuf_size, io_req_size, reply_desc_size, sense_size, chain_frame_size,
- evt_detail_size, count;
+ evt_detail_size, count, pd_info_size;
/*
* Allocate parent DMA tag
@@ -2009,7 +2029,39 @@ mrsas_alloc_mem(struct mrsas_softc *sc)
device_printf(sc->mrsas_dev, "Cannot load Event detail buffer memory\n");
return (ENOMEM);
}
+
/*
+ * Allocate for PD INFO structure
+ */
+ pd_info_size = sizeof(struct mrsas_pd_info);
+ if (bus_dma_tag_create(sc->mrsas_parent_tag,
+ 1, 0,
+ BUS_SPACE_MAXADDR_32BIT,
+ BUS_SPACE_MAXADDR,
+ NULL, NULL,
+ pd_info_size,
+ 1,
+ pd_info_size,
+ BUS_DMA_ALLOCNOW,
+ NULL, NULL,
+ &sc->pd_info_tag)) {
+ device_printf(sc->mrsas_dev, "Cannot create PD INFO tag\n");
+ return (ENOMEM);
+ }
+ if (bus_dmamem_alloc(sc->pd_info_tag, (void **)&sc->pd_info_mem,
+ BUS_DMA_NOWAIT, &sc->pd_info_dmamap)) {
+ device_printf(sc->mrsas_dev, "Cannot alloc PD INFO buffer memory\n");
+ return (ENOMEM);
+ }
+ bzero(sc->pd_info_mem, pd_info_size);
+ if (bus_dmamap_load(sc->pd_info_tag, sc->pd_info_dmamap,
+ sc->pd_info_mem, pd_info_size, mrsas_addr_cb,
+ &sc->pd_info_phys_addr, BUS_DMA_NOWAIT)) {
+ device_printf(sc->mrsas_dev, "Cannot load PD INFO buffer memory\n");
+ return (ENOMEM);
+ }
+
+ /*
* Create a dma tag for data buffers; size will be the maximum
* possible I/O size (280kB).
*/
@@ -2297,6 +2349,7 @@ mrsas_init_fw(struct mrsas_softc *sc)
device_printf(sc->mrsas_dev, "Adapter initialize Fail.\n");
return (1);
}
+
/* Allocate internal commands for pass-thru */
if (mrsas_alloc_mfi_cmds(sc) != SUCCESS) {
device_printf(sc->mrsas_dev, "Allocate MFI cmd failed.\n");
@@ -2334,6 +2387,12 @@ mrsas_init_fw(struct mrsas_softc *sc)
}
megasas_setup_jbod_map(sc);
+
+ memset(sc->target_list, 0,
+ MRSAS_MAX_TM_TARGETS * sizeof(struct mrsas_target));
+ for (i = 0; i < MRSAS_MAX_TM_TARGETS; i++)
+ sc->target_list[i].target_id = 0xffff;
+
/* For pass-thru, get PD/LD list and controller info */
memset(sc->pd_list, 0,
MRSAS_MAX_PD * sizeof(struct mrsas_pd_list));
@@ -4271,7 +4330,114 @@ mrsas_sync_map_info(struct mrsas_softc *sc)
return (retcode);
}
+/* Input: dcmd.opcode - MR_DCMD_PD_GET_INFO
+ * dcmd.mbox.s[0] - deviceId for this physical drive
+ * dcmd.sge IN - ptr to returned MR_PD_INFO structure
+ * Desc: Firmware return the physical drive info structure
+ *
+ */
+static void
+mrsas_get_pd_info(struct mrsas_softc *sc, u_int16_t device_id)
+{
+ int retcode;
+ u_int8_t do_ocr = 1;
+ struct mrsas_mfi_cmd *cmd;
+ struct mrsas_dcmd_frame *dcmd;
+
+ cmd = mrsas_get_mfi_cmd(sc);
+
+ if (!cmd) {
+ device_printf(sc->mrsas_dev,
+ "Cannot alloc for get PD info cmd\n");
+ return;
+ }
+ dcmd = &cmd->frame->dcmd;
+
+ memset(sc->pd_info_mem, 0, sizeof(struct mrsas_pd_info));
+ memset(dcmd->mbox.b, 0, MFI_MBOX_SIZE);
+
+ dcmd->mbox.s[0] = device_id;
+ dcmd->cmd = MFI_CMD_DCMD;
+ dcmd->cmd_status = 0xFF;
+ dcmd->sge_count = 1;
+ dcmd->flags = MFI_FRAME_DIR_READ;
+ dcmd->timeout = 0;
+ dcmd->pad_0 = 0;
+ dcmd->data_xfer_len = sizeof(struct mrsas_pd_info);
+ dcmd->opcode = MR_DCMD_PD_GET_INFO;
+ dcmd->sgl.sge32[0].phys_addr = (u_int32_t)sc->pd_info_phys_addr;
+ dcmd->sgl.sge32[0].length = sizeof(struct mrsas_pd_info);
+
+ if (!sc->mask_interrupts)
+ retcode = mrsas_issue_blocked_cmd(sc, cmd);
+ else
+ retcode = mrsas_issue_polled(sc, cmd);
+
+ if (retcode == ETIMEDOUT)
+ goto dcmd_timeout;
+
+ sc->target_list[device_id].interface_type =
+ sc->pd_info_mem->state.ddf.pdType.intf;
+
+ do_ocr = 0;
+
+dcmd_timeout:
+
+ if (do_ocr)
+ sc->do_timedout_reset = MFI_DCMD_TIMEOUT_OCR;
+
+ if (!sc->mask_interrupts)
+ mrsas_release_mfi_cmd(cmd);
+}
+
/*
+ * mrsas_add_target: Add target ID of system PD/VD to driver's data structure.
+ * sc: Adapter's soft state
+ * target_id: Unique target id per controller(managed by driver)
+ * for system PDs- target ID ranges from 0 to (MRSAS_MAX_PD - 1)
+ * for VDs- target ID ranges from MRSAS_MAX_PD to MRSAS_MAX_TM_TARGETS
+ * return: void
+ * Descripton: This function will be called whenever system PD or VD is created.
+ */
+static void mrsas_add_target(struct mrsas_softc *sc,
+ u_int16_t target_id)
+{
+ sc->target_list[target_id].target_id = target_id;
+
+ device_printf(sc->mrsas_dev,
+ "%s created target ID: 0x%x\n",
+ (target_id < MRSAS_MAX_PD ? "System PD" : "VD"),
+ (target_id < MRSAS_MAX_PD ? target_id : (target_id - MRSAS_MAX_PD)));
+ /*
+ * If interrupts are enabled, then only fire DCMD to get pd_info
+ * for system PDs
+ */
+ if (!sc->mask_interrupts && sc->pd_info_mem &&
+ (target_id < MRSAS_MAX_PD))
+ mrsas_get_pd_info(sc, target_id);
+
+}
+
+/*
+ * mrsas_remove_target: Remove target ID of system PD/VD from driver's data structure.
+ * sc: Adapter's soft state
+ * target_id: Unique target id per controller(managed by driver)
+ * for system PDs- target ID ranges from 0 to (MRSAS_MAX_PD - 1)
+ * for VDs- target ID ranges from MRSAS_MAX_PD to MRSAS_MAX_TM_TARGETS
+ * return: void
+ * Descripton: This function will be called whenever system PD or VD is deleted
+ */
+static void mrsas_remove_target(struct mrsas_softc *sc,
+ u_int16_t target_id)
+{
+ sc->target_list[target_id].target_id = 0xffff;
+ device_printf(sc->mrsas_dev,
+ "%s deleted target ID: 0x%x\n",
+ (target_id < MRSAS_MAX_PD ? "System PD" : "VD"),
+ (target_id < MRSAS_MAX_PD ? target_id : (target_id - MRSAS_MAX_PD)));
+}
+
+/*
* mrsas_get_pd_list: Returns FW's PD list structure input:
* Adapter soft state
*
@@ -4347,8 +4513,18 @@ mrsas_get_pd_list(struct mrsas_softc *sc)
pd_addr->scsiDevType;
sc->local_pd_list[pd_addr->deviceId].driveState =
MR_PD_STATE_SYSTEM;
+ if (sc->target_list[pd_addr->deviceId].target_id == 0xffff)
+ mrsas_add_target(sc, pd_addr->deviceId);
pd_addr++;
}
+ for (pd_index = 0; pd_index < MRSAS_MAX_PD; pd_index++) {
+ if ((sc->local_pd_list[pd_index].driveState !=
+ MR_PD_STATE_SYSTEM) &&
+ (sc->target_list[pd_index].target_id !=
+ 0xffff)) {
+ mrsas_remove_target(sc, pd_index);
+ }
+ }
/*
* Use mutext/spinlock if pd_list component size increase more than
* 32 bit.
@@ -4380,7 +4556,7 @@ dcmd_timeout:
static int
mrsas_get_ld_list(struct mrsas_softc *sc)
{
- int ld_list_size, retcode = 0, ld_index = 0, ids = 0;
+ int ld_list_size, retcode = 0, ld_index = 0, ids = 0, drv_tgt_id;
u_int8_t do_ocr = 1;
struct mrsas_mfi_cmd *cmd;
struct mrsas_dcmd_frame *dcmd;
@@ -4442,11 +4618,21 @@ mrsas_get_ld_list(struct mrsas_softc *sc)
sc->CurLdCount = ld_list_mem->ldCount;
memset(sc->ld_ids, 0xff, MAX_LOGICAL_DRIVES_EXT);
for (ld_index = 0; ld_index < ld_list_mem->ldCount; ld_index++) {
+ ids = ld_list_mem->ldList[ld_index].ref.ld_context.targetId;
+ drv_tgt_id = ids + MRSAS_MAX_PD;
if (ld_list_mem->ldList[ld_index].state != 0) {
- ids = ld_list_mem->ldList[ld_index].ref.ld_context.targetId;
sc->ld_ids[ids] = ld_list_mem->ldList[ld_index].ref.ld_context.targetId;
+ if (sc->target_list[drv_tgt_id].target_id ==
+ 0xffff)
+ mrsas_add_target(sc, drv_tgt_id);
+ } else {
+ if (sc->target_list[drv_tgt_id].target_id !=
+ 0xffff)
+ mrsas_remove_target(sc,
+ drv_tgt_id);
}
}
+
do_ocr = 0;
}
dcmd_timeout:
Modified: head/sys/dev/mrsas/mrsas.h
==============================================================================
--- head/sys/dev/mrsas/mrsas.h Fri Dec 14 08:02:44 2018 (r342064)
+++ head/sys/dev/mrsas/mrsas.h Fri Dec 14 08:03:28 2018 (r342065)
@@ -740,6 +740,7 @@ Mpi2IOCInitRequest_t, MPI2_POINTER pMpi2IOCInitRequest
#define MR_DCMD_SYSTEM_PD_MAP_GET_INFO 0x0200e102
#define MR_DCMD_PD_MFI_TASK_MGMT 0x0200e100
+#define MR_DCMD_PD_GET_INFO 0x02020000
#define MRSAS_MAX_PD_CHANNELS 1
#define MRSAS_MAX_LD_CHANNELS 1
#define MRSAS_MAX_DEV_PER_CHANNEL 256
@@ -2944,6 +2945,210 @@ typedef struct _MRSAS_DRV_PCI_INFORMATION {
u_int8_t reserved2[28];
} MRSAS_DRV_PCI_INFORMATION, *PMRSAS_DRV_PCI_INFORMATION;
+typedef enum _MR_PD_TYPE {
+ UNKNOWN_DRIVE = 0,
+ PARALLEL_SCSI = 1,
+ SAS_PD = 2,
+ SATA_PD = 3,
+ FC_PD = 4,
+ NVME_PD = 5,
+} MR_PD_TYPE;
+
+typedef union _MR_PD_REF {
+ struct {
+ u_int16_t deviceId;
+ u_int16_t seqNum;
+ } mrPdRef;
+ u_int32_t ref;
+} MR_PD_REF;
+
+/*
+ * define the DDF Type bit structure
+ */
+union MR_PD_DDF_TYPE {
+ struct {
+ union {
+ struct {
+ u_int16_t forcedPDGUID:1;
+ u_int16_t inVD:1;
+ u_int16_t isGlobalSpare:1;
+ u_int16_t isSpare:1;
+ u_int16_t isForeign:1;
+ u_int16_t reserved:7;
+ u_int16_t intf:4;
+ } pdType;
+ u_int16_t type;
+ };
+ u_int16_t reserved;
+ } ddf;
+ struct {
+ u_int32_t reserved;
+ } nonDisk;
+ u_int32_t type;
+} __packed;
+
+/*
+ * defines the progress structure
+ */
+union MR_PROGRESS {
+ struct {
+ u_int16_t progress;
+ union {
+ u_int16_t elapsedSecs;
+ u_int16_t elapsedSecsForLastPercent;
+ };
+ } mrProgress;
+ u_int32_t w;
+} __packed;
+
+/*
+ * defines the physical drive progress structure
+ */
+struct MR_PD_PROGRESS {
+ struct {
+ u_int32_t rbld:1;
+ u_int32_t patrol:1;
+ u_int32_t clear:1;
+ u_int32_t copyBack:1;
+ u_int32_t erase:1;
+ u_int32_t locate:1;
+ u_int32_t reserved:26;
+ } active;
+ union MR_PROGRESS rbld;
+ union MR_PROGRESS patrol;
+ union {
+ union MR_PROGRESS clear;
+ union MR_PROGRESS erase;
+ };
+
+ struct {
+ u_int32_t rbld:1;
+ u_int32_t patrol:1;
+ u_int32_t clear:1;
+ u_int32_t copyBack:1;
+ u_int32_t erase:1;
+ u_int32_t reserved:27;
+ } pause;
+
+ union MR_PROGRESS reserved[3];
+} __packed;
+
+
+struct mrsas_pd_info {
+ MR_PD_REF ref;
+ u_int8_t inquiryData[96];
+ u_int8_t vpdPage83[64];
+
+ u_int8_t notSupported;
+ u_int8_t scsiDevType;
+
+ union {
+ u_int8_t connectedPortBitmap;
+ u_int8_t connectedPortNumbers;
+ };
+
+ u_int8_t deviceSpeed;
+ u_int32_t mediaErrCount;
+ u_int32_t otherErrCount;
+ u_int32_t predFailCount;
+ u_int32_t lastPredFailEventSeqNum;
+
+ u_int16_t fwState;
+ u_int8_t disabledForRemoval;
+ u_int8_t linkSpeed;
+ union MR_PD_DDF_TYPE state;
+
+ struct {
+ u_int8_t count;
+ u_int8_t isPathBroken:4;
+ u_int8_t reserved3:3;
+ u_int8_t widePortCapable:1;
+
+ u_int8_t connectorIndex[2];
+ u_int8_t reserved[4];
+ u_int64_t sasAddr[2];
+ u_int8_t reserved2[16];
+ } pathInfo;
+
+ u_int64_t rawSize;
+ u_int64_t nonCoercedSize;
+ u_int64_t coercedSize;
+ u_int16_t enclDeviceId;
+ u_int8_t enclIndex;
+
+ union {
+ u_int8_t slotNumber;
+ u_int8_t enclConnectorIndex;
+ };
+
+ struct MR_PD_PROGRESS progInfo;
+ u_int8_t badBlockTableFull;
+ u_int8_t unusableInCurrentConfig;
+ u_int8_t vpdPage83Ext[64];
+ u_int8_t powerState;
+ u_int8_t enclPosition;
+ u_int32_t allowedOps;
+ u_int16_t copyBackPartnerId;
+ u_int16_t enclPartnerDeviceId;
+ struct {
+ u_int16_t fdeCapable:1;
+ u_int16_t fdeEnabled:1;
+ u_int16_t secured:1;
+ u_int16_t locked:1;
+ u_int16_t foreign:1;
+ u_int16_t needsEKM:1;
+ u_int16_t reserved:10;
+ } security;
+ u_int8_t mediaType;
+ u_int8_t notCertified;
+ u_int8_t bridgeVendor[8];
+ u_int8_t bridgeProductIdentification[16];
+ u_int8_t bridgeProductRevisionLevel[4];
+ u_int8_t satBridgeExists;
+
+ u_int8_t interfaceType;
+ u_int8_t temperature;
+ u_int8_t emulatedBlockSize;
+ u_int16_t userDataBlockSize;
+ u_int16_t reserved2;
+
+ struct {
+ u_int32_t piType:3;
+ u_int32_t piFormatted:1;
+ u_int32_t piEligible:1;
+ u_int32_t NCQ:1;
+ u_int32_t WCE:1;
+ u_int32_t commissionedSpare:1;
+ u_int32_t emergencySpare:1;
+ u_int32_t ineligibleForSSCD:1;
+ u_int32_t ineligibleForLd:1;
+ u_int32_t useSSEraseType:1;
+ u_int32_t wceUnchanged:1;
+ u_int32_t supportScsiUnmap:1;
+ u_int32_t reserved:18;
+ } properties;
+
+ u_int64_t shieldDiagCompletionTime;
+ u_int8_t shieldCounter;
+
+ u_int8_t linkSpeedOther;
+ u_int8_t reserved4[2];
+
+ struct {
+ u_int32_t bbmErrCountSupported:1;
+ u_int32_t bbmErrCount:31;
+ } bbmErr;
+
+ u_int8_t reserved1[512-428];
+} __packed;
+
+struct mrsas_target {
+ u_int16_t target_id;
+ u_int32_t queue_depth;
+ u_int8_t interface_type;
+ u_int32_t max_io_size_kb;
+} __packed;
+
/*******************************************************************
* per-instance data
********************************************************************/
@@ -3066,10 +3271,14 @@ struct mrsas_softc {
bus_addr_t raidmap_phys_addr[2];
bus_dma_tag_t mficmd_frame_tag;
bus_dma_tag_t mficmd_sense_tag;
+ bus_addr_t evt_detail_phys_addr;
bus_dma_tag_t evt_detail_tag;
bus_dmamap_t evt_detail_dmamap;
struct mrsas_evt_detail *evt_detail_mem;
- bus_addr_t evt_detail_phys_addr;
+ bus_addr_t pd_info_phys_addr;
+ bus_dma_tag_t pd_info_tag;
+ bus_dmamap_t pd_info_dmamap;
+ struct mrsas_pd_info *pd_info_mem;
struct mrsas_ctrl_info *ctrl_info;
bus_dma_tag_t ctlr_info_tag;
bus_dmamap_t ctlr_info_dmamap;
@@ -3094,6 +3303,7 @@ struct mrsas_softc {
bus_addr_t el_info_phys_addr;
struct mrsas_pd_list pd_list[MRSAS_MAX_PD];
struct mrsas_pd_list local_pd_list[MRSAS_MAX_PD];
+ struct mrsas_target target_list[MRSAS_MAX_TM_TARGETS];
u_int8_t ld_ids[MRSAS_MAX_LD_IDS];
struct taskqueue *ev_tq;
struct task ev_task;
More information about the svn-src-all
mailing list