Author: sobomax
Date: Wed May 22 04:51:08 2019
New Revision: 348091
URL: https://svnweb.freebsd.org/changeset/base/348091

Log:
  Make aacraid(4) working on ASR8805 & ASR8402 in particular. This patch
  has been in the PR system for 5 months and then on reviews for another 5.
  Nobody came with any cases where it fails, while many people cried for
  it to be commited & merged.
  
  PR:           209468
  Submitted by: Prasad B M <prasad.munirath...@microsemi.com>
  Reported by:  Steven Peterson <s...@mainstream.net>
  Approved by:  scottl
  MFC after:    1 month
  Differential Revision:        https://reviews.freebsd.org/D18408

Modified:
  head/sys/dev/aacraid/aacraid.c
  head/sys/dev/aacraid/aacraid_cam.c
  head/sys/dev/aacraid/aacraid_reg.h
  head/sys/dev/aacraid/aacraid_var.h

Modified: head/sys/dev/aacraid/aacraid.c
==============================================================================
--- head/sys/dev/aacraid/aacraid.c      Wed May 22 04:13:57 2019        
(r348090)
+++ head/sys/dev/aacraid/aacraid.c      Wed May 22 04:51:08 2019        
(r348091)
@@ -264,7 +264,7 @@ aacraid_attach(struct aac_softc *sc)
        /*
         * Check that the firmware on the card is supported.
         */
-       sc->msi_enabled = FALSE;
+       sc->msi_enabled = sc->msi_tupelo = FALSE;
        if ((error = aac_check_firmware(sc)) != 0)
                return(error);
 
@@ -284,8 +284,8 @@ aacraid_attach(struct aac_softc *sc)
         */
        if ((error = aac_alloc(sc)) != 0)
                return(error);
+       aac_define_int_mode(sc);
        if (!(sc->flags & AAC_FLAGS_SYNC_MODE)) {
-               aac_define_int_mode(sc);
                if ((error = aac_init(sc)) != 0)
                        return(error);
        }
@@ -728,7 +728,7 @@ aacraid_free(struct aac_softc *sc)
                else
                        break;
        }
-       if (sc->msi_enabled)
+       if (sc->msi_enabled || sc->msi_tupelo)
                pci_release_msi(sc->aac_dev);
 
        /* destroy data-transfer DMA tag */
@@ -1316,6 +1316,9 @@ aacraid_map_command_sg(void *arg, bus_dma_segment_t *s
        fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "nseg %d", nseg);
        mtx_assert(&sc->aac_io_lock, MA_OWNED);
 
+       if ((sc->flags & AAC_FLAGS_SYNC_MODE) && sc->aac_sync_cm)
+               return;
+
        /* copy into the FIB */
        if (cm->cm_sgtable != NULL) {
                if (fib->Header.Command == RawIo2) {
@@ -1433,11 +1436,14 @@ aacraid_map_command_sg(void *arg, bus_dma_segment_t *s
 
        cm->cm_flags |= AAC_CMD_MAPPED;
 
-       if (sc->flags & AAC_FLAGS_SYNC_MODE) {
+       if (cm->cm_flags & AAC_CMD_WAIT) {
+               aacraid_sync_command(sc, AAC_MONKER_SYNCFIB,
+                       cm->cm_fibphys, 0, 0, 0, NULL, NULL);
+       } else if (sc->flags & AAC_FLAGS_SYNC_MODE) {
                u_int32_t wait = 0;
-               aacraid_sync_command(sc, AAC_MONKER_SYNCFIB, cm->cm_fibphys, 0, 
0, 0, &wait, NULL);
-       } else if (cm->cm_flags & AAC_CMD_WAIT) {
-               aacraid_sync_command(sc, AAC_MONKER_SYNCFIB, cm->cm_fibphys, 0, 
0, 0, NULL, NULL);
+               sc->aac_sync_cm = cm;
+               aacraid_sync_command(sc, AAC_MONKER_SYNCFIB,
+                       cm->cm_fibphys, 0, 0, 0, &wait, NULL);
        } else {
                int count = 10000000L;
                while (AAC_SEND_COMMAND(sc, cm) != 0) {
@@ -1617,6 +1623,7 @@ aac_check_firmware(struct aac_softc *sc)
                options = AAC_GET_MAILBOX(sc, 1);
                atu_size = AAC_GET_MAILBOX(sc, 2);
                sc->supported_options = options;
+               sc->doorbell_mask = AAC_GET_MAILBOX(sc, 3);
 
                if ((options & AAC_SUPPORTED_4GB_WINDOW) != 0 &&
                    (sc->flags & AAC_FLAGS_NO4GB) == 0)
@@ -1631,13 +1638,13 @@ aac_check_firmware(struct aac_softc *sc)
                        sc->flags |= AAC_FLAGS_SG_64BIT;
                }
                if (sc->aac_if.aif_send_command) {
-                       if ((options & AAC_SUPPORTED_NEW_COMM_TYPE3) ||
-                               (options & AAC_SUPPORTED_NEW_COMM_TYPE4))
-                               sc->flags |= AAC_FLAGS_NEW_COMM | 
AAC_FLAGS_NEW_COMM_TYPE34;
+                       if (options & AAC_SUPPORTED_NEW_COMM_TYPE2)
+                               sc->flags |= AAC_FLAGS_NEW_COMM | 
AAC_FLAGS_NEW_COMM_TYPE2;
                        else if (options & AAC_SUPPORTED_NEW_COMM_TYPE1)
                                sc->flags |= AAC_FLAGS_NEW_COMM | 
AAC_FLAGS_NEW_COMM_TYPE1;
-                       else if (options & AAC_SUPPORTED_NEW_COMM_TYPE2)
-                               sc->flags |= AAC_FLAGS_NEW_COMM | 
AAC_FLAGS_NEW_COMM_TYPE2;
+                       else if ((options & AAC_SUPPORTED_NEW_COMM_TYPE3) ||
+                               (options & AAC_SUPPORTED_NEW_COMM_TYPE4))
+                               sc->flags |= AAC_FLAGS_NEW_COMM | 
AAC_FLAGS_NEW_COMM_TYPE34;
                }
                if (options & AAC_SUPPORTED_64BIT_ARRAYSIZE)
                        sc->flags |= AAC_FLAGS_ARRAY_64BIT;
@@ -1851,8 +1858,30 @@ aac_define_int_mode(struct aac_softc *sc)
        
        dev = sc->aac_dev;
 
+       if (sc->flags & AAC_FLAGS_SYNC_MODE) {
+               device_printf(dev, "using line interrupts\n");
+               sc->aac_max_msix = 1;
+               sc->aac_vector_cap = sc->aac_max_fibs;
+               return;
+       }
+
        /* max. vectors from AAC_MONKER_GETCOMMPREF */
        if (sc->aac_max_msix == 0) {
+               if (sc->aac_hwif == AAC_HWIF_SRC) {
+                       msi_count = 1;
+                       if ((error = pci_alloc_msi(dev, &msi_count)) != 0) {
+                               device_printf(dev, "alloc msi failed - err=%d; "
+                                   "will use INTx\n", error);
+                               pci_release_msi(dev);
+                       } else {
+                               sc->msi_tupelo = TRUE;
+                       }
+               }
+               if (sc->msi_tupelo)
+                       device_printf(dev, "using MSI interrupts\n");
+               else
+                       device_printf(dev, "using line interrupts\n");
+
                sc->aac_max_msix = 1;
                sc->aac_vector_cap = sc->aac_max_fibs;
                return;
@@ -1958,7 +1987,7 @@ aac_setup_intr(struct aac_softc *sc)
        void *tag;
 
        msi_count = sc->aac_max_msix;
-       rid = (sc->msi_enabled ? 1:0);
+       rid = ((sc->msi_enabled || sc->msi_tupelo)? 1:0);
 
        for (i = 0; i < msi_count; i++, rid++) {
                if ((res = bus_alloc_resource_any(sc->aac_dev,SYS_RES_IRQ, &rid,
@@ -2854,14 +2883,14 @@ aac_ioctl_send_raw_srb(struct aac_softc *sc, caddr_t a
 
        fib = cm->cm_fib;
        srbcmd = (struct aac_srb *)fib->data;
-       if ((error = copyin((void *)&user_srb->data_len, &fibsize, 
-               sizeof (u_int32_t)) != 0)) 
+       if ((error = copyin((void *)&user_srb->data_len, &fibsize,
+           sizeof (u_int32_t))) != 0)
                goto out;
        if (fibsize > (sc->aac_max_fib_size-sizeof(struct aac_fib_header))) {
                error = EINVAL;
                goto out;
        }
-       if ((error = copyin((void *)user_srb, srbcmd, fibsize) != 0)) 
+       if ((error = copyin((void *)user_srb, srbcmd, fibsize)) != 0)
                goto out;
 
        srbcmd->function = 0;           /* SRBF_ExecuteScsi */
@@ -2895,13 +2924,10 @@ aac_ioctl_send_raw_srb(struct aac_softc *sc, caddr_t a
 
                srb_sg_bytecount = sg.SgByteCount;
                srb_sg_address = sg.SgAddress;
-               if (srb_sg_address > 0xffffffffull && 
-                       !(sc->flags & AAC_FLAGS_SG_64BIT))
-#endif 
-               {
-                       error = EINVAL;
-                       goto out;
-               }
+#else
+               error = EINVAL;
+               goto out;
+#endif
        } else {
                error = EINVAL;
                goto out;
@@ -3701,7 +3727,7 @@ aac_get_bus_info(struct aac_softc *sc)
                caminf->TargetsPerBus = businfo.TargetsPerBus;
                caminf->BusNumber = i+1;
                caminf->BusType = PASSTHROUGH_BUS;
-               caminf->InitiatorBusId = businfo.InitiatorBusId[i];
+               caminf->InitiatorBusId = -1;
                caminf->aac_sc = sc;
                caminf->sim_dev = child;
                caminf->aac_cam = NULL;
@@ -3745,7 +3771,7 @@ aac_reset_adapter(struct aac_softc *sc)
        struct aac_fib *fib;
        struct aac_pause_command *pc;
        u_int32_t status, reset_mask, waitCount, max_msix_orig;
-       int msi_enabled_orig;
+       int ret, msi_enabled_orig;
 
        fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
        mtx_assert(&sc->aac_io_lock, MA_OWNED);
@@ -3804,50 +3830,61 @@ aac_reset_adapter(struct aac_softc *sc)
                AAC_MEM0_SETREG4(sc, AAC_IRCSR, AAC_IRCSR_CORES_RST);
 
                /* We need to wait for 5 seconds before accessing the MU again
-                * 10000 * 100us = 1000,000us = 1000ms = 1s  
+                * 10000 * 100us = 1000,000us = 1000ms = 1s
                 */
                waitCount = 5 * 10000;
                while (waitCount) {
                        DELAY(100);                     /* delay 100 
microseconds */
                        waitCount--;
                }
-       } else if ((aacraid_sync_command(sc, 
-               AAC_IOP_RESET_ALWAYS, 0, 0, 0, 0, &status, &reset_mask)) != 0) {
-               /* call IOP_RESET for older firmware */
-               if ((aacraid_sync_command(sc,
-                       AAC_IOP_RESET, 0, 0, 0, 0, &status, NULL)) != 0) {
+       } else {
+               ret = aacraid_sync_command(sc, AAC_IOP_RESET_ALWAYS,
+                       0, 0, 0, 0, &status, &reset_mask);
+               if (ret && !sc->doorbell_mask) {
+                       /* call IOP_RESET for older firmware */
+                       if ((aacraid_sync_command(sc, AAC_IOP_RESET, 0,0,0,0,
+                           &status, NULL)) != 0) {
+                               if (status == AAC_SRB_STS_INVALID_REQUEST) {
+                                       device_printf(sc->aac_dev,
+                                           "IOP_RESET not supported\n");
+                               } else {
+                                       /* probably timeout */
+                                       device_printf(sc->aac_dev,
+                                           "IOP_RESET failed\n");
+                               }
 
-                       if (status == AAC_SRB_STS_INVALID_REQUEST)
-                               device_printf(sc->aac_dev, "IOP_RESET not 
supported\n");
-                       else
-                               /* probably timeout */
-                               device_printf(sc->aac_dev, "IOP_RESET 
failed\n");
+                               /* unwind aac_shutdown() */
+                               aac_alloc_sync_fib(sc, &fib);
+                               pc = (struct aac_pause_command *)&fib->data[0];
+                               pc->Command = VM_ContainerConfig;
+                               pc->Type = CT_PAUSE_IO;
+                               pc->Timeout = 1;
+                               pc->Min = 1;
+                               pc->NoRescan = 1;
 
-                       /* unwind aac_shutdown() */
-                       aac_alloc_sync_fib(sc, &fib);
-                       pc = (struct aac_pause_command *)&fib->data[0];
-                       pc->Command = VM_ContainerConfig;
-                       pc->Type = CT_PAUSE_IO;
-                       pc->Timeout = 1;
-                       pc->Min = 1;
-                       pc->NoRescan = 1;
+                               (void) aac_sync_fib(sc, ContainerCommand, 0,
+                                   fib, sizeof (struct aac_pause_command));
+                               aac_release_sync_fib(sc);
 
-                       (void) aac_sync_fib(sc, ContainerCommand, 0, fib,
-                               sizeof (struct aac_pause_command));
-                       aac_release_sync_fib(sc);
-
-                       goto finish;
+                               goto finish;
+                       }
+               } else if (sc->doorbell_mask) {
+                       ret = 0;
+                       reset_mask = sc->doorbell_mask;
                }
-       } else if (sc->aac_support_opt2 & AAC_SUPPORTED_DOORBELL_RESET) {
-               AAC_MEM0_SETREG4(sc, AAC_SRC_IDBR, reset_mask);
-               /* 
-                * We need to wait for 5 seconds before accessing the doorbell
-                * again, 10000 * 100us = 1000,000us = 1000ms = 1s  
-                */
-               waitCount = 5 * 10000;
-               while (waitCount) {
-                       DELAY(100);             /* delay 100 microseconds */
-                       waitCount--;
+               if (!ret &&
+                   (sc->aac_support_opt2 & AAC_SUPPORTED_DOORBELL_RESET)) {
+                       AAC_MEM0_SETREG4(sc, AAC_SRC_IDBR, reset_mask);
+                       /*
+                        * We need to wait for 5 seconds before accessing the
+                        * doorbell again;
+                        * 10000 * 100us = 1000,000us = 1000ms = 1s
+                        */
+                       waitCount = 5 * 10000;
+                       while (waitCount) {
+                               DELAY(100);     /* delay 100 microseconds */
+                               waitCount--;
+                       }
                }
        }
 

Modified: head/sys/dev/aacraid/aacraid_cam.c
==============================================================================
--- head/sys/dev/aacraid/aacraid_cam.c  Wed May 22 04:13:57 2019        
(r348090)
+++ head/sys/dev/aacraid/aacraid_cam.c  Wed May 22 04:51:08 2019        
(r348091)
@@ -1017,8 +1017,8 @@ aac_cam_action(struct cam_sim *sim, union ccb *ccb)
                cpi->version_num = 1;
                cpi->target_sprt = 0;
                cpi->hba_eng_cnt = 0;
-               cpi->max_target = camsc->inf->TargetsPerBus;
-               cpi->max_lun = 8;       /* Per the controller spec */
+               cpi->max_target = camsc->inf->TargetsPerBus - 1;
+               cpi->max_lun = 7;       /* Per the controller spec */
                cpi->initiator_id = camsc->inf->InitiatorBusId;
                cpi->bus_id = camsc->inf->BusNumber;
 #if __FreeBSD_version >= 800000
@@ -1389,15 +1389,9 @@ aacraid_startio(struct aac_softc *sc)
                 * Try to get a command that's been put off for lack of
                 * resources
                 */
-               if (sc->flags & AAC_FLAGS_SYNC_MODE) {
-                       /* sync. transfer mode */
-                       if (sc->aac_sync_cm) 
-                               break;
-                       cm = aac_dequeue_ready(sc);
-                       sc->aac_sync_cm = cm;
-               } else {
-                       cm = aac_dequeue_ready(sc);
-               }
+               if ((sc->flags & AAC_FLAGS_SYNC_MODE) && sc->aac_sync_cm)
+                       break;
+               cm = aac_dequeue_ready(sc);
 
                /* nothing to do? */
                if (cm == NULL)

Modified: head/sys/dev/aacraid/aacraid_reg.h
==============================================================================
--- head/sys/dev/aacraid/aacraid_reg.h  Wed May 22 04:13:57 2019        
(r348090)
+++ head/sys/dev/aacraid/aacraid_reg.h  Wed May 22 04:51:08 2019        
(r348091)
@@ -42,7 +42,7 @@
 /*
  * Misc. magic numbers.
  */
-#define AAC_MAX_CONTAINERS     64
+#define AAC_MAX_CONTAINERS     240
 #define AAC_BLOCK_SIZE         512
 
 /*

Modified: head/sys/dev/aacraid/aacraid_var.h
==============================================================================
--- head/sys/dev/aacraid/aacraid_var.h  Wed May 22 04:13:57 2019        
(r348090)
+++ head/sys/dev/aacraid/aacraid_var.h  Wed May 22 04:51:08 2019        
(r348091)
@@ -49,7 +49,7 @@
 
 #define        AAC_DRIVER_MAJOR_VERSION        3
 #define        AAC_DRIVER_MINOR_VERSION        2
-#define        AAC_DRIVER_BUGFIX_LEVEL         5
+#define        AAC_DRIVER_BUGFIX_LEVEL         10
 #define        AAC_DRIVER_TYPE                 AAC_TYPE_RELEASE
 
 #ifndef AAC_DRIVER_BUILD
@@ -481,9 +481,12 @@ struct aac_softc 
        u_int32_t       aac_feature_bits;               /* feature bits from 
suppl. info */
        u_int32_t       aac_support_opt2;               /* supp. options from 
suppl. info */
        u_int32_t       aac_max_aif;                    /* max. AIF count */
+       u_int32_t       doorbell_mask;                  /* for IOP reset */
        u_int32_t       aac_max_msix;                   /* max. MSI-X vectors */
        u_int32_t       aac_vector_cap;                 /* MSI-X vector capab.*/
        int             msi_enabled;                    /* MSI/MSI-X enabled */
+       int             msi_tupelo;             /* Series 6 support for */
+                                               /* single MSI interrupt */
 #define AAC_CAM_TARGET_WILDCARD ~0
        void                    (*cam_rescan_cb)(struct aac_softc *, uint32_t,
                                    uint32_t);
_______________________________________________
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