This adds support for SAS3.5 controllers in mpii(4). To get these working, I had to rearrange the initialisation code a bit. The new controllers don't like being hard reset, which means we have to call mpii_iocfacts() to determine whether soft reset is supported before calling mpii_init().
The changes look pretty innocuous but could break older controllers (though this is how the linux driver works), so it'd help if people could test those. I found a SAS3008 (Dell HBA330) on my desk and that still works. These controllers also support nvme devices, but that will have to remain unimplemented for now. Index: mpiireg.h =================================================================== RCS file: /cvs/src/sys/dev/pci/mpiireg.h,v retrieving revision 1.12 diff -u -p -u -p -r1.12 mpiireg.h --- mpiireg.h 16 Jan 2017 18:09:35 -0000 1.12 +++ mpiireg.h 16 Jun 2018 21:55:19 -0000 @@ -524,6 +524,7 @@ struct mpii_msg_portfacts_reply { #define MPII_PORTFACTS_PORTTYPE_ISCSI (0x20) #define MPII_PORTFACTS_PORTTYPE_SAS_PHYSICAL (0x30) #define MPII_PORTFACTS_PORTTYPE_SAS_VIRTUAL (0x31) +#define MPII_PORTFACTS_PORTTYPE_TRI_MODE (0x40) u_int16_t reserved6; u_int16_t max_posted_cmd_buffers; Index: mpii.c =================================================================== RCS file: /cvs/src/sys/dev/pci/mpii.c,v retrieving revision 1.113 diff -u -p -u -p -r1.113 mpii.c --- mpii.c 12 Dec 2017 11:18:32 -0000 1.113 +++ mpii.c 16 Jun 2018 21:55:20 -0000 @@ -431,7 +431,13 @@ static const struct pci_matchid mpii_dev { PCI_VENDOR_SYMBIOS, PCI_PRODUCT_SYMBIOS_SAS3108_1 }, { PCI_VENDOR_SYMBIOS, PCI_PRODUCT_SYMBIOS_SAS3108_2 }, { PCI_VENDOR_SYMBIOS, PCI_PRODUCT_SYMBIOS_SAS3108_3 }, - { PCI_VENDOR_SYMBIOS, PCI_PRODUCT_SYMBIOS_SAS3108_4 } + { PCI_VENDOR_SYMBIOS, PCI_PRODUCT_SYMBIOS_SAS3108_4 }, + { PCI_VENDOR_SYMBIOS, PCI_PRODUCT_SYMBIOS_SAS3408 }, + { PCI_VENDOR_SYMBIOS, PCI_PRODUCT_SYMBIOS_SAS3416 }, + { PCI_VENDOR_SYMBIOS, PCI_PRODUCT_SYMBIOS_SAS3508 }, + { PCI_VENDOR_SYMBIOS, PCI_PRODUCT_SYMBIOS_SAS3508_1 }, + { PCI_VENDOR_SYMBIOS, PCI_PRODUCT_SYMBIOS_SAS3516 }, + { PCI_VENDOR_SYMBIOS, PCI_PRODUCT_SYMBIOS_SAS3516_1 } }; int @@ -492,13 +498,13 @@ mpii_attach(struct device *parent, struc } printf(": %s\n", pci_intr_string(sc->sc_pc, ih)); - if (mpii_init(sc) != 0) { - printf("%s: unable to initialize ioc\n", DEVNAME(sc)); + if (mpii_iocfacts(sc) != 0) { + printf("%s: unable to get iocfacts\n", DEVNAME(sc)); goto unmap; } - if (mpii_iocfacts(sc) != 0) { - printf("%s: unable to get iocfacts\n", DEVNAME(sc)); + if (mpii_init(sc) != 0) { + printf("%s: unable to initialize ioc\n", DEVNAME(sc)); goto unmap; } @@ -556,7 +562,8 @@ mpii_attach(struct device *parent, struc /* XXX bail on unsupported porttype? */ if ((sc->sc_porttype == MPII_PORTFACTS_PORTTYPE_SAS_PHYSICAL) || - (sc->sc_porttype == MPII_PORTFACTS_PORTTYPE_SAS_VIRTUAL)) { + (sc->sc_porttype == MPII_PORTFACTS_PORTTYPE_SAS_VIRTUAL) || + (sc->sc_porttype == MPII_PORTFACTS_PORTTYPE_TRI_MODE)) { if (mpii_eventnotify(sc) != 0) { printf("%s: unable to enable events\n", DEVNAME(sc)); goto free_queues; @@ -876,7 +883,8 @@ mpii_scsi_probe(struct scsi_link *link) int flags; if ((sc->sc_porttype != MPII_PORTFACTS_PORTTYPE_SAS_PHYSICAL) && - (sc->sc_porttype != MPII_PORTFACTS_PORTTYPE_SAS_VIRTUAL)) + (sc->sc_porttype != MPII_PORTFACTS_PORTTYPE_SAS_VIRTUAL) && + (sc->sc_porttype != MPII_PORTFACTS_PORTTYPE_TRI_MODE)) return (ENXIO); dev = sc->sc_devs[link->target]; @@ -1261,12 +1269,16 @@ mpii_iocfacts(struct mpii_softc *sc) if (ISSET(lemtoh32(&ifp.ioc_capabilities), MPII_IOCFACTS_CAPABILITY_INTEGRATED_RAID)) SET(sc->sc_flags, MPII_F_RAID); + if (ISSET(lemtoh32(&ifp.ioc_capabilities), + MPII_IOCFACTS_CAPABILITY_EVENT_REPLAY)) + sc->sc_ioc_event_replay = 1; sc->sc_max_cmds = MIN(lemtoh16(&ifp.request_credit), MPII_REQUEST_CREDIT); - /* SAS3 controllers have different sgl layouts */ - if (ifp.msg_version_maj == 2 && ifp.msg_version_min == 5) + /* SAS3 and 3.5 controllers have different sgl layouts */ + if (ifp.msg_version_maj == 2 && ((ifp.msg_version_min == 5) + || (ifp.msg_version_min == 6))) SET(sc->sc_flags, MPII_F_SAS3); /*