diff -u -r -N old/aacraid/aacraid.c new/aacraid/aacraid.c --- old/aacraid/aacraid.c 2016-08-31 15:26:58.775957000 -0700 +++ new/aacraid/aacraid.c 2016-08-31 15:26:06.154119000 -0700 @@ -261,7 +261,7 @@ /* * 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); @@ -281,8 +281,8 @@ */ 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); } @@ -725,7 +725,7 @@ else break; } - if (sc->msi_enabled) + if (sc->msi_enabled || sc->msi_tupelo) pci_release_msi(sc->aac_dev); /* destroy data-transfer DMA tag */ @@ -1313,6 +1313,9 @@ 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) { @@ -1430,11 +1433,14 @@ 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) { @@ -1614,6 +1620,7 @@ 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) @@ -1628,13 +1635,13 @@ 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; @@ -1848,8 +1855,30 @@ 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; @@ -1955,7 +1984,7 @@ 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, @@ -2852,13 +2881,13 @@ fib = cm->cm_fib; srbcmd = (struct aac_srb *)fib->data; if ((error = copyin((void *)&user_srb->data_len, &fibsize, - sizeof (u_int32_t)) != 0)) + 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 */ @@ -2882,13 +2911,10 @@ (struct aac_sg_entry64 *)srbcmd->sg_map.SgEntry; srb_sg_bytecount = sgp->SgByteCount; srb_sg_address = sgp->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; @@ -3676,7 +3702,7 @@ 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; @@ -3720,7 +3746,7 @@ 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); @@ -3786,43 +3812,49 @@ 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) { - - 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; - - (void) aac_sync_fib(sc, ContainerCommand, 0, fib, - sizeof (struct aac_pause_command)); - aac_release_sync_fib(sc); - - goto finish; - } - } 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--; + } 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"); + + /* 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); + + goto finish; + } + } else if (sc->doorbell_mask) { + ret = 0; + reset_mask = sc->doorbell_mask; + } + 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--; + } } } diff -u -r -N old/aacraid/aacraid_cam.c new/aacraid/aacraid_cam.c --- old/aacraid/aacraid_cam.c 2016-08-31 15:26:58.770711000 -0700 +++ new/aacraid/aacraid_cam.c 2016-08-31 15:26:06.148893000 -0700 @@ -1015,8 +1015,8 @@ 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 @@ * 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) diff -u -r -N old/aacraid/aacraid_pci.c new/aacraid/aacraid_pci.c --- old/aacraid/aacraid_pci.c 2016-08-31 15:26:58.782224000 -0700 +++ new/aacraid/aacraid_pci.c 2016-08-31 15:26:06.160373000 -0700 @@ -111,12 +111,10 @@ aac_find_ident(device_t dev) { struct aac_ident *m; - u_int16_t vendid, devid, sub_vendid, sub_devid; + u_int16_t vendid, devid; vendid = pci_get_vendor(dev); devid = pci_get_device(dev); - sub_vendid = pci_get_subvendor(dev); - sub_devid = pci_get_subdevice(dev); for (m = aacraid_family_identifiers; m->vendor != 0; m++) { if ((m->vendor == vendid) && (m->device == devid)) diff -u -r -N old/aacraid/aacraid_reg.h new/aacraid/aacraid_reg.h --- old/aacraid/aacraid_reg.h 2016-08-31 15:26:58.785425000 -0700 +++ new/aacraid/aacraid_reg.h 2016-08-31 15:26:06.163590000 -0700 @@ -40,7 +40,7 @@ /* * Misc. magic numbers. */ -#define AAC_MAX_CONTAINERS 64 +#define AAC_MAX_CONTAINERS 240 #define AAC_BLOCK_SIZE 512 /* diff -u -r -N old/aacraid/aacraid_var.h new/aacraid/aacraid_var.h --- old/aacraid/aacraid_var.h 2016-08-31 15:26:58.787487000 -0700 +++ new/aacraid/aacraid_var.h 2016-08-31 15:26:06.165656000 -0700 @@ -47,7 +47,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 @@ -479,9 +479,11 @@ 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; #define AAC_CAM_TARGET_WILDCARD ~0 void (*cam_rescan_cb)(struct aac_softc *, uint32_t, uint32_t);