Author: slm
Date: Mon May  9 16:19:13 2016
New Revision: 299266
URL: https://svnweb.freebsd.org/changeset/base/299266

Log:
  Add support for the Broadcom (Avago/LSI) 9305 16 and 24 port HBA's.
  
  Reviewed by:    ken, scottl, ambrisko, asomers
  Approved by:  ken, scottl, ambrisko
  MFC after:      1 week
  Relnotes:       yes
  Differential Revision: https://reviews.freebsd.org/D6098

Modified:
  head/sys/dev/mpr/mpr.c
  head/sys/dev/mpr/mpr_pci.c
  head/sys/dev/mpr/mpr_sas.c
  head/sys/dev/mpr/mpr_sas_lsi.c
  head/sys/dev/mpr/mprvar.h

Modified: head/sys/dev/mpr/mpr.c
==============================================================================
--- head/sys/dev/mpr/mpr.c      Mon May  9 16:16:00 2016        (r299265)
+++ head/sys/dev/mpr/mpr.c      Mon May  9 16:19:13 2016        (r299266)
@@ -441,6 +441,8 @@ mpr_iocfacts_allocate(struct mpr_softc *
            (saved_facts.IOCCapabilities != sc->facts->IOCCapabilities) ||
            (saved_facts.IOCRequestFrameSize !=
            sc->facts->IOCRequestFrameSize) ||
+           (saved_facts.IOCMaxChainSegmentSize !=
+           sc->facts->IOCMaxChainSegmentSize) ||
            (saved_facts.MaxTargets != sc->facts->MaxTargets) ||
            (saved_facts.MaxSasExpanders != sc->facts->MaxSasExpanders) ||
            (saved_facts.MaxEnclosures != sc->facts->MaxEnclosures) ||
@@ -1188,7 +1190,28 @@ mpr_alloc_requests(struct mpr_softc *sc)
         bus_dmamap_load(sc->req_dmat, sc->req_map, sc->req_frames, rsize,
            mpr_memaddr_cb, &sc->req_busaddr, 0);
 
-       rsize = sc->facts->IOCRequestFrameSize * sc->max_chains * 4;
+       /*
+        * Gen3 and beyond uses the IOCMaxChainSegmentSize from IOC Facts to
+        * get the size of a Chain Frame.  Previous versions use the size as a
+        * Request Frame for the Chain Frame size.  If IOCMaxChainSegmentSize
+        * is 0, use the default value.  The IOCMaxChainSegmentSize is the
+        * number of 16-byte elelements that can fit in a Chain Frame, which is
+        * the size of an IEEE Simple SGE.
+        */
+       if (sc->facts->MsgVersion >= MPI2_VERSION_02_05) {
+               sc->chain_seg_size =
+                   htole16(sc->facts->IOCMaxChainSegmentSize);
+               if (sc->chain_seg_size == 0) {
+                       sc->chain_frame_size = MPR_DEFAULT_CHAIN_SEG_SIZE *
+                           MPR_MAX_CHAIN_ELEMENT_SIZE;
+               } else {
+                       sc->chain_frame_size = sc->chain_seg_size *
+                           MPR_MAX_CHAIN_ELEMENT_SIZE;
+               }
+       } else {
+               sc->chain_frame_size = sc->facts->IOCRequestFrameSize * 4;
+       }
+       rsize = sc->chain_frame_size * sc->max_chains;
         if (bus_dma_tag_create( sc->mpr_parent_dmat,    /* parent */
                                16, 0,                  /* algnmnt, boundary */
                                BUS_SPACE_MAXADDR,      /* lowaddr */
@@ -1246,9 +1269,9 @@ mpr_alloc_requests(struct mpr_softc *sc)
        for (i = 0; i < sc->max_chains; i++) {
                chain = &sc->chains[i];
                chain->chain = (MPI2_SGE_IO_UNION *)(sc->chain_frames +
-                   i * sc->facts->IOCRequestFrameSize * 4);
+                   i * sc->chain_frame_size);
                chain->chain_busaddr = sc->chain_busaddr +
-                   i * sc->facts->IOCRequestFrameSize * 4;
+                   i * sc->chain_frame_size;
                mpr_free_chain(sc, chain);
                sc->chain_free_lowwater++;
        }
@@ -2169,7 +2192,7 @@ mpr_add_chain(struct mpr_command *cm, in
        MPI2_REQUEST_HEADER *req;
        MPI25_IEEE_SGE_CHAIN64 *ieee_sgc;
        struct mpr_chain *chain;
-       int space, sgc_size, current_segs, rem_segs, segs_per_frame;
+       int sgc_size, current_segs, rem_segs, segs_per_frame;
        uint8_t next_chain_offset = 0;
 
        /*
@@ -2191,8 +2214,6 @@ mpr_add_chain(struct mpr_command *cm, in
        if (chain == NULL)
                return (ENOBUFS);
 
-       space = (int)cm->cm_sc->facts->IOCRequestFrameSize * 4;
-
        /*
         * Note: a double-linked list is used to make it easier to walk for
         * debugging.
@@ -2218,13 +2239,14 @@ mpr_add_chain(struct mpr_command *cm, in
                 */
                current_segs = (cm->cm_sglsize / sgc_size) - 1;
                rem_segs = segsleft - current_segs;
-               segs_per_frame = space / sgc_size;
+               segs_per_frame = sc->chain_frame_size / sgc_size;
                if (rem_segs > segs_per_frame) {
                        next_chain_offset = segs_per_frame - 1;
                }
        }
        ieee_sgc = &((MPI25_SGE_IO_UNION *)cm->cm_sge)->IeeeChain;
-       ieee_sgc->Length = next_chain_offset ? htole32((uint32_t)space) :
+       ieee_sgc->Length = next_chain_offset ?
+           htole32((uint32_t)sc->chain_frame_size) :
            htole32((uint32_t)rem_segs * (uint32_t)sgc_size);
        ieee_sgc->NextChainOffset = next_chain_offset;
        ieee_sgc->Flags = (MPI2_IEEE_SGE_FLAGS_CHAIN_ELEMENT |
@@ -2233,10 +2255,9 @@ mpr_add_chain(struct mpr_command *cm, in
        ieee_sgc->Address.High = htole32(chain->chain_busaddr >> 32);
        cm->cm_sge = &((MPI25_SGE_IO_UNION *)chain->chain)->IeeeSimple;
        req = (MPI2_REQUEST_HEADER *)cm->cm_req;
-       req->ChainOffset = ((sc->facts->IOCRequestFrameSize * 4) -
-           sgc_size) >> 4;
+       req->ChainOffset = (sc->chain_frame_size - sgc_size) >> 4;
 
-       cm->cm_sglsize = space;
+       cm->cm_sglsize = sc->chain_frame_size;
        return (0);
 }
 

Modified: head/sys/dev/mpr/mpr_pci.c
==============================================================================
--- head/sys/dev/mpr/mpr_pci.c  Mon May  9 16:16:00 2016        (r299265)
+++ head/sys/dev/mpr/mpr_pci.c  Mon May  9 16:19:13 2016        (r299266)
@@ -110,6 +110,18 @@ struct mpr_ident {
            0xffff, 0xffff, 0, "Avago Technologies (LSI) SAS3108_5" },
        { MPI2_MFGPAGE_VENDORID_LSI, MPI25_MFGPAGE_DEVID_SAS3108_6,
            0xffff, 0xffff, 0, "Avago Technologies (LSI) SAS3108_6" },
+       { MPI2_MFGPAGE_VENDORID_LSI, MPI26_MFGPAGE_DEVID_SAS3316_1,
+           0xffff, 0xffff, 0, "Avago Technologies (LSI) SAS3316_1" },
+       { MPI2_MFGPAGE_VENDORID_LSI, MPI26_MFGPAGE_DEVID_SAS3316_2,
+           0xffff, 0xffff, 0, "Avago Technologies (LSI) SAS3316_2" },
+       { MPI2_MFGPAGE_VENDORID_LSI, MPI26_MFGPAGE_DEVID_SAS3324_1,
+           0xffff, 0xffff, 0, "Avago Technologies (LSI) SAS3324_1" },
+       { MPI2_MFGPAGE_VENDORID_LSI, MPI26_MFGPAGE_DEVID_SAS3324_2,
+           0xffff, 0xffff, 0, "Avago Technologies (LSI) SAS3324_2" },
+       { MPI2_MFGPAGE_VENDORID_LSI, MPI26_MFGPAGE_DEVID_SAS3216,
+           0xffff, 0xffff, 0, "Avago Technologies (LSI) SAS3216" },
+       { MPI2_MFGPAGE_VENDORID_LSI, MPI26_MFGPAGE_DEVID_SAS3224,
+           0xffff, 0xffff, 0, "Avago Technologies (LSI) SAS3224" },
        { 0, 0, 0, 0, 0, NULL }
 };
 

Modified: head/sys/dev/mpr/mpr_sas.c
==============================================================================
--- head/sys/dev/mpr/mpr_sas.c  Mon May  9 16:16:00 2016        (r299265)
+++ head/sys/dev/mpr/mpr_sas.c  Mon May  9 16:19:13 2016        (r299266)
@@ -704,6 +704,7 @@ mprsas_register_events(struct mpr_softc 
        setbit(events, MPI2_EVENT_IR_PHYSICAL_DISK);
        setbit(events, MPI2_EVENT_IR_OPERATION_STATUS);
        setbit(events, MPI2_EVENT_TEMP_THRESHOLD);
+       setbit(events, MPI2_EVENT_ACTIVE_CABLE_EXCEPTION);
 
        mpr_register_events(sc, events, mprsas_evt_handler, NULL,
            &sc->sassc->mprsas_eh);
@@ -2048,6 +2049,9 @@ mpr_sc_failed_io_info(struct mpr_softc *
        case MPI2_IOCSTATUS_EEDP_APP_TAG_ERROR:
                desc_ioc_state = "eedp app tag error";
                break;
+       case MPI2_IOCSTATUS_INSUFFICIENT_POWER:
+               desc_ioc_state = "insufficient power";
+               break;
        default:
                desc_ioc_state = "unknown";
                break;

Modified: head/sys/dev/mpr/mpr_sas_lsi.c
==============================================================================
--- head/sys/dev/mpr/mpr_sas_lsi.c      Mon May  9 16:16:00 2016        
(r299265)
+++ head/sys/dev/mpr/mpr_sas_lsi.c      Mon May  9 16:19:13 2016        
(r299266)
@@ -645,6 +645,23 @@ skip_fp_send:
                }
                break;
        }
+       case MPI2_EVENT_ACTIVE_CABLE_EXCEPTION:
+       {
+               pMpi26EventDataActiveCableExcept_t      ace_event_data;
+               ace_event_data =
+                   (pMpi26EventDataActiveCableExcept_t)fw_event->event_data;
+
+               if (ace_event_data->ReasonCode ==
+                   MPI26_EVENT_ACTIVE_CABLE_INSUFFICIENT_POWER) {
+                       mpr_printf(sc, "Currently an active cable with "
+                           "ReceptacleID %d cannot be powered and device "
+                           "connected to this active cable will not be seen. "
+                           "This active cable requires %d mW of power.\n",
+                           ace_event_data->ReceptacleID,
+                           ace_event_data->ActiveCablePowerRequirement);
+               }
+               break;
+       }
        case MPI2_EVENT_SAS_DEVICE_STATUS_CHANGE:
        case MPI2_EVENT_SAS_BROADCAST_PRIMITIVE:
        default:

Modified: head/sys/dev/mpr/mprvar.h
==============================================================================
--- head/sys/dev/mpr/mprvar.h   Mon May  9 16:16:00 2016        (r299265)
+++ head/sys/dev/mpr/mprvar.h   Mon May  9 16:19:13 2016        (r299266)
@@ -46,6 +46,8 @@
 #define MPR_SGE64_SIZE         12
 #define MPR_SGE32_SIZE         8
 #define MPR_SGC_SIZE           8
+#define MPR_DEFAULT_CHAIN_SEG_SIZE     8
+#define MPR_MAX_CHAIN_ELEMENT_SIZE     16
 
 #define MPR_FUNCTRACE(sc)                      \
        mpr_dprint((sc), MPR_TRACE, "%s\n", __func__)
@@ -263,6 +265,8 @@ struct mpr_softc {
        int                             chain_free;
        int                             max_chains;
        int                             chain_free_lowwater;
+       uint32_t                        chain_frame_size;
+       uint16_t                        chain_seg_size;
        u_int                           enable_ssu;
        int                             spinup_wait_time;
        uint64_t                        chain_alloc_fail;
_______________________________________________
svn-src-all@freebsd.org mailing list
https://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"

Reply via email to