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.sax...@broadcom.com>
  Reviewed by:  Kashyap Desai <kashyap.de...@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;
_______________________________________________
svn-src-head@freebsd.org mailing list
https://lists.freebsd.org/mailman/listinfo/svn-src-head
To unsubscribe, send any mail to "svn-src-head-unsubscr...@freebsd.org"

Reply via email to