diff -purw --exclude .svn -I '\$FreeBSD.*\$' -I '"aac"' -I '"aacu"' -I '"aacd"' -I '"aacdu"' -I '"aacch"' -I '"aacchu"' ./aac.c /home/emaste/adaptec/aac.c --- ./aac.c 2010-04-12 16:32:26.000000000 -0400 +++ /home/emaste/adaptec/aac.c 2009-08-28 13:13:22.000000000 -0400 @@ -63,6 +63,7 @@ __FBSDID("$FreeBSD: head/sys/dev/aac/aac #include #include +#include #include #include @@ -95,9 +96,6 @@ static void aac_common_map(void *arg, bu int error); static int aac_check_firmware(struct aac_softc *sc); static int aac_init(struct aac_softc *sc); -static int aac_sync_command(struct aac_softc *sc, u_int32_t command, - u_int32_t arg0, u_int32_t arg1, u_int32_t arg2, - u_int32_t arg3, u_int32_t *sp); static int aac_setup_intr(struct aac_softc *sc); static int aac_enqueue_fib(struct aac_softc *sc, int queue, struct aac_command *cm); @@ -207,8 +227,11 @@ static int aac_get_pci_info(struct aac_ static int aac_supported_features(struct aac_softc *sc, caddr_t uptr); static void aac_ioctl_event(struct aac_softc *sc, struct aac_event *event, void *arg); +static int aac_reset_adapter(struct aac_softc *sc); static struct aac_mntinforesp * aac_get_container_info(struct aac_softc *sc, struct aac_fib *fib, int cid); +static u_int32_t + aac_check_adapter_health(struct aac_softc *sc, u_int8_t *bled); static struct cdevsw aac_cdevsw = { .d_version = D_VERSION, @@ -236,8 +259,10 @@ int aac_attach(struct aac_softc *sc) { int error, unit; + struct timeval tv; fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, ""); + sc->hint_flags = device_get_flags(sc->aac_dev); /* * Initialize per-controller queues. @@ -270,14 +295,20 @@ aac_attach(struct aac_softc *sc) TAILQ_INIT(&sc->aac_container_tqh); TAILQ_INIT(&sc->aac_ev_cmfree); - /* Initialize the clock daemon callout. */ - callout_init_mtx(&sc->aac_daemontime, &sc->aac_io_lock, 0); - /* - * Initialize the adapter. + * Allocate adapter comm. space. */ if ((error = aac_alloc(sc)) != 0) return(error); + + /* + * Print a little information about the controller. + */ + aac_describe_controller(sc); + + /* + * Initialize the adapter. + */ if ((error = aac_init(sc)) != 0) return(error); @@ -288,11 +319,6 @@ aac_attach(struct aac_softc *sc) return(error); /* - * Print a little information about the controller. - */ - aac_describe_controller(sc); - - /* * Register to probe our containers later. */ sc->aac_ich.ich_func = aac_startup; @@ -314,7 +340,7 @@ aac_attach(struct aac_softc *sc) sc->aac_dev_t->si_drv1 = sc; /* Create the AIF thread */ - if (kproc_create((void(*)(void *))aac_command_thread, sc, + if (kthread_create((void(*)(void *))aac_command_thread, sc, &sc->aifthread, 0, 0, "aac%daif", unit)) panic("Could not create AIF thread"); @@ -330,34 +356,13 @@ aac_attach(struct aac_softc *sc) aac_get_bus_info(sc); } - mtx_lock(&sc->aac_io_lock); - callout_reset(&sc->aac_daemontime, 60 * hz, aac_daemon, sc); - mtx_unlock(&sc->aac_io_lock); + tv.tv_sec = 60; + tv.tv_usec = 0; + sc->timeout_id = timeout(aac_daemon, (void *)sc, tvtohz(&tv)); return(0); } -static void -aac_daemon(void *arg) -{ - struct timeval tv; - struct aac_softc *sc; - struct aac_fib *fib; - - sc = arg; - mtx_assert(&sc->aac_io_lock, MA_OWNED); - - if (callout_pending(&sc->aac_daemontime) || - callout_active(&sc->aac_daemontime) == 0) - return; - getmicrotime(&tv); - aac_alloc_sync_fib(sc, &fib); - *(uint32_t *)fib->data = tv.tv_sec; - aac_sync_fib(sc, SendHostTime, 0, fib, sizeof(uint32_t)); - aac_release_sync_fib(sc); - callout_schedule(&sc->aac_daemontime, 30 * 60 * hz); -} - void aac_add_event(struct aac_softc *sc, struct aac_event *event) { @@ -375,6 +380,28 @@ aac_add_event(struct aac_softc *sc, stru return; } +/* daemon */ +static void +aac_daemon(void *arg) +{ + struct aac_softc *sc = (struct aac_softc *)arg; + struct timeval tv; + struct aac_fib *fib; + + /* time sync. with firmware */ + getmicrotime(&tv); + mtx_lock(&sc->aac_io_lock); + aac_alloc_sync_fib(sc, &fib); + *(uint32_t *)fib->data = tv.tv_sec; + aac_sync_fib(sc, SendHostTime, 0, fib, sizeof(uint32_t)); + aac_release_sync_fib(sc); + mtx_unlock(&sc->aac_io_lock); + + tv.tv_sec = 30*60; /* 30 minutes */ + tv.tv_usec = 0; + sc->timeout_id = timeout(aac_daemon, (void *)sc, tvtohz(&tv)); +} + /* * Request information of container #cid */ @@ -530,7 +557,7 @@ aac_alloc(struct aac_softc *sc) 0, /* flags */ NULL, NULL, /* No locking needed */ &sc->aac_fib_dmat)) { - device_printf(sc->aac_dev, "can't allocate FIB DMA tag\n"); + device_printf(sc->aac_dev, "can't allocate FIB DMA tag\n");; return (ENOMEM); } @@ -581,7 +608,7 @@ aac_alloc(struct aac_softc *sc) TAILQ_INIT(&sc->aac_fibmap_tqh); sc->aac_commands = malloc(sc->aac_max_fibs * sizeof(struct aac_command), M_AACBUF, M_WAITOK|M_ZERO); - while (sc->total_fibs < sc->aac_max_fibs) { + while (sc->total_fibs < AAC_PREALLOCATE_FIBS) { if (aac_alloc_commands(sc) != 0) break; } @@ -663,7 +690,7 @@ aac_detach(device_t dev) if (sc->aac_state & AAC_STATE_OPEN) return(EBUSY); - callout_drain(&sc->aac_daemontime); + untimeout(aac_daemon, (void *)sc, sc->timeout_id); /* Remove the child containers */ while ((co = TAILQ_FIRST(&sc->aac_container_tqh)) != NULL) { @@ -886,11 +913,8 @@ aac_new_intr(void *arg) mtx_unlock(&sc->aac_io_lock); } -/* - * Interrupt filter for !NEW_COMM interface. - */ int -aac_filter(void *arg) +aac_fast_intr(void *arg) { struct aac_softc *sc; u_int16_t reason; @@ -949,6 +973,8 @@ aac_startio(struct aac_softc *sc) fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, ""); for (;;) { + if (sc->aac_state & AAC_STATE_RESET) + break; /* * This flag might be set if the card is out of resources. * Checking it here prevents an infinite loop of deferrals. @@ -1097,7 +1123,7 @@ aac_command_thread(struct aac_softc *sc) mtx_unlock(&sc->aac_io_lock); wakeup(sc->aac_dev); - kproc_exit(0); + kthread_exit(0); } /* @@ -1189,6 +1215,16 @@ aac_bio_command(struct aac_softc *sc, st if ((bp = aac_dequeue_bio(sc)) == NULL) goto fail; + ad = (struct aac_disk *)bp->bio_disk->d_drv1; + /* container still valid? */ + if (ad->ad_container == NULL) { + bp->bio_flags |= BIO_ERROR; + bp->bio_error = EINVAL; + biodone(bp); + bp = NULL; + goto fail; + } + /* fill out the command */ cm->cm_data = (void *)bp->bio_data; cm->cm_datalen = bp->bio_bcount; @@ -1210,8 +1246,6 @@ aac_bio_command(struct aac_softc *sc, st AAC_FIBSTATE_FAST_RESPONSE; /* build the read/write request */ - ad = (struct aac_disk *)bp->bio_disk->d_drv1; - if (sc->flags & AAC_FLAGS_RAW_IO) { struct aac_raw_io *raw; raw = (struct aac_raw_io *)&fib->data[0]; @@ -1307,7 +1341,9 @@ aac_bio_complete(struct aac_command *cm) /* fetch relevant status and then release the command */ bp = (struct bio *)cm->cm_private; - if (bp->bio_cmd == BIO_READ) { + if (cm->cm_flags & AAC_CMD_RESET) { + status = ST_BUS_RESET; + } else if (bp->bio_cmd == BIO_READ) { brr = (struct aac_blockread_response *)&cm->cm_fib->data[0]; status = brr->Status; } else { @@ -1320,7 +1356,7 @@ aac_bio_complete(struct aac_command *cm) if (status == ST_OK) { bp->bio_resid = 0; } else { - bp->bio_error = EIO; + bp->bio_error = (status == ST_NOT_READY ? EBUSY : EIO); bp->bio_flags |= BIO_ERROR; /* pass an error string out to the disk layer */ bp->bio_driver1 = aac_describe_code(aac_command_status_table, @@ -1399,6 +1435,7 @@ aac_release_command(struct aac_command * cm->cm_complete = NULL; cm->cm_private = NULL; cm->cm_queue = AAC_ADAP_NORM_CMD_QUEUE; + cm->cm_passthr_dmat = 0; cm->cm_fib->Header.XferState = AAC_FIBSTATE_EMPTY; cm->cm_fib->Header.StructType = AAC_FIBTYPE_TFIB; cm->cm_fib->Header.Flags = 0; @@ -1599,12 +1636,15 @@ aac_map_command_sg(void *arg, bus_dma_se /* save a pointer to the command for speedy reverse-lookup */ cm->cm_fib->Header.SenderData = cm->cm_index; + if (cm->cm_passthr_dmat == 0) { if (cm->cm_flags & AAC_CMD_DATAIN) bus_dmamap_sync(sc->aac_buffer_dmat, cm->cm_datamap, BUS_DMASYNC_PREREAD); if (cm->cm_flags & AAC_CMD_DATAOUT) bus_dmamap_sync(sc->aac_buffer_dmat, cm->cm_datamap, BUS_DMASYNC_PREWRITE); + } + cm->cm_flags |= AAC_CMD_MAPPED; if (sc->flags & AAC_FLAGS_NEW_COMM) { @@ -1643,7 +1683,7 @@ aac_unmap_command(struct aac_command *cm if (!(cm->cm_flags & AAC_CMD_MAPPED)) return; - if (cm->cm_datalen != 0) { + if (cm->cm_datalen != 0 && cm->cm_passthr_dmat == 0) { if (cm->cm_flags & AAC_CMD_DATAIN) bus_dmamap_sync(sc->aac_buffer_dmat, cm->cm_datamap, BUS_DMASYNC_POSTREAD); @@ -1750,7 +1790,8 @@ aac_check_firmware(struct aac_softc *sc) if (options & AAC_SUPPORTED_NONDASD) sc->flags |= AAC_FLAGS_ENABLE_CAM; if ((options & AAC_SUPPORTED_SGMAP_HOST64) != 0 - && (sizeof(bus_addr_t) > 4)) { + && (sizeof(bus_addr_t) > 4) + && (sc->hint_flags & 0x1)) { device_printf(sc->aac_dev, "Enabling 64-bit address support\n"); sc->flags |= AAC_FLAGS_SG_64BIT; @@ -1831,6 +1872,7 @@ aac_check_firmware(struct aac_softc *sc) device_printf(sc->aac_dev, "Enable 64-bit array\n"); } + aac_get_fw_debug_buffer(sc); return (0); } @@ -1880,10 +1922,19 @@ aac_init(struct aac_softc *sc) ip->InitFlags = 0; if (sc->flags & AAC_FLAGS_NEW_COMM) { - ip->InitFlags = INITFLAGS_NEW_COMM_SUPPORTED; + ip->InitFlags |= AAC_INITFLAGS_NEW_COMM_SUPPORTED; device_printf(sc->aac_dev, "New comm. interface enabled\n"); } + /* ADPml10863: Disable Power Management support */ + sc->aac_support_opt2 &= ~AAC_SUPPORTED_POWER_MANAGEMENT; + + if (sc->aac_support_opt2 & AAC_SUPPORTED_POWER_MANAGEMENT) { + ip->InitFlags |= AAC_INITFLAGS_DRIVER_SUPPORTS_PM; + ip->InitFlags |= AAC_INITFLAGS_DRIVER_USES_UTC_TIME; + device_printf(sc->aac_dev, "Power Management enabled\n"); + } + ip->MaxIoCommands = sc->aac_max_fibs; ip->MaxIoSize = sc->aac_max_sectors << 9; ip->MaxFibSize = sc->aac_max_fib_size; @@ -2011,13 +2062,20 @@ aac_setup_intr(struct aac_softc *sc) } } else { if (bus_setup_intr(sc->aac_dev, sc->aac_irq, - INTR_TYPE_BIO, aac_filter, NULL, + INTR_TYPE_BIO, aac_fast_intr, NULL, + sc, &sc->aac_intr)) { + device_printf(sc->aac_dev, + "can't set up FAST interrupt\n"); + if (bus_setup_intr(sc->aac_dev, sc->aac_irq, + INTR_MPSAFE|INTR_TYPE_BIO, + NULL, (driver_intr_t *)aac_fast_intr, sc, &sc->aac_intr)) { device_printf(sc->aac_dev, - "can't set up interrupt filter\n"); + "can't set up MPSAFE interrupt\n"); return (EINVAL); } } + } return (0); } @@ -2025,7 +2083,7 @@ aac_setup_intr(struct aac_softc *sc) * Send a synchronous command to the controller and wait for a result. * Indicate if the controller completed the command with an error status. */ -static int +int aac_sync_command(struct aac_softc *sc, u_int32_t command, u_int32_t arg0, u_int32_t arg1, u_int32_t arg2, u_int32_t arg3, u_int32_t *sp) @@ -2351,9 +2409,8 @@ aac_timeout(struct aac_softc *sc) /* && !(cm->cm_flags & AAC_CMD_TIMEDOUT) */) { cm->cm_flags |= AAC_CMD_TIMEDOUT; device_printf(sc->aac_dev, - "COMMAND %p (TYPE %d) TIMEOUT AFTER %d SECONDS\n", - cm, cm->cm_fib->Header.Command, - (int)(time_uptime-cm->cm_timestamp)); + "COMMAND %p TIMEOUT AFTER %d SECONDS\n", + cm, (int)(time_uptime-cm->cm_timestamp)); AAC_PRINT_FIB(sc, cm->cm_fib); timedout++; } @@ -2364,6 +2421,7 @@ aac_timeout(struct aac_softc *sc) if (code != AAC_UP_AND_RUNNING) { device_printf(sc->aac_dev, "WARNING! Controller is no " "longer running! code= 0x%x\n", code); + aac_reset_adapter(sc); } } return; @@ -2389,8 +2447,18 @@ aac_rx_get_fwstatus(struct aac_softc *sc { fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, ""); - return(AAC_MEM0_GETREG4(sc, sc->flags & AAC_FLAGS_NEW_COMM ? - AAC_RX_OMR0 : AAC_RX_FWSTATUS)); + return(AAC_MEM0_GETREG4(sc, AAC_RX_OMR0)); @@ -2398,8 +2466,7 @@ aac_rkt_get_fwstatus(struct aac_softc *s { fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, ""); - return(AAC_MEM0_GETREG4(sc, sc->flags & AAC_FLAGS_NEW_COMM ? - AAC_RKT_OMR0 : AAC_RKT_FWSTATUS)); + return(AAC_MEM0_GETREG4(sc, AAC_RKT_OMR0)); } /* @@ -2701,6 +2840,24 @@ aac_describe_controller(struct aac_softc mtx_lock(&sc->aac_io_lock); aac_alloc_sync_fib(sc, &fib); + if (sc->supported_options & AAC_SUPPORTED_SUPPLEMENT_ADAPTER_INFO) { + fib->data[0] = 0; + if (aac_sync_fib(sc, RequestSupplementAdapterInfo, 0, fib, 1)) + device_printf(sc->aac_dev, "RequestSupplementAdapterInfo failed\n"); + else { + struct aac_supplement_adapter_info *supp_info; + + supp_info = ((struct aac_supplement_adapter_info *)&fib->data[0]); + adapter_type = supp_info->AdapterTypeText; + sc->aac_feature_bits = supp_info->FeatureBits; + sc->aac_support_opt2 = supp_info->SupportedOptions2; + } + } + device_printf(sc->aac_dev, "%s, aac driver %d.%d.%d-%d\n", + adapter_type, + AAC_DRIVER_MAJOR_VERSION, AAC_DRIVER_MINOR_VERSION, + AAC_DRIVER_BUGFIX_LEVEL, AAC_DRIVER_BUILD); + fib->data[0] = 0; if (aac_sync_fib(sc, RequestAdapterInfo, 0, fib, 1)) { device_printf(sc->aac_dev, "RequestAdapterInfo failed\n"); @@ -2755,20 +2912,6 @@ aac_describe_controller(struct aac_softc "\24HEATSENSOR"); } - if (sc->supported_options & AAC_SUPPORTED_SUPPLEMENT_ADAPTER_INFO) { - fib->data[0] = 0; - if (aac_sync_fib(sc, RequestSupplementAdapterInfo, 0, fib, 1)) - device_printf(sc->aac_dev, - "RequestSupplementAdapterInfo failed\n"); - else - adapter_type = ((struct aac_supplement_adapter_info *) - &fib->data[0])->AdapterTypeText; - } - device_printf(sc->aac_dev, "%s, aac driver %d.%d.%d-%d\n", - adapter_type, - AAC_DRIVER_MAJOR_VERSION, AAC_DRIVER_MINOR_VERSION, - AAC_DRIVER_BUGFIX_LEVEL, AAC_DRIVER_BUILD); - aac_release_sync_fib(sc); mtx_unlock(&sc->aac_io_lock); } @@ -2793,7 +2936,7 @@ aac_describe_code(struct aac_code_lookup */ static int -aac_open(struct cdev *dev, int flags, int fmt, struct thread *td) +aac_open(struct cdev *dev, int flags, int fmt, d_thread_t *td) { struct aac_softc *sc; @@ -2806,7 +2949,7 @@ aac_open(struct cdev *dev, int flags, in } static int -aac_close(struct cdev *dev, int flags, int fmt, struct thread *td) +aac_close(struct cdev *dev, int flags, int fmt, d_thread_t *td) { struct aac_softc *sc; @@ -2821,7 +2964,7 @@ aac_close(struct cdev *dev, int flags, i } static int -aac_ioctl(struct cdev *dev, u_long cmd, caddr_t arg, int flag, struct thread *td) +aac_ioctl(struct cdev *dev, u_long cmd, caddr_t arg, int flag, d_thread_t *td) { union aac_statrequest *as; struct aac_softc *sc; @@ -2926,10 +3069,9 @@ aac_ioctl(struct cdev *dev, u_long cmd, } static int -aac_poll(struct cdev *dev, int poll_events, struct thread *td) +aac_poll(struct cdev *dev, int poll_events, d_thread_t *td) { struct aac_softc *sc; - struct aac_fib_context *ctx; int revents; sc = dev->si_drv1; @@ -2937,12 +3079,8 @@ aac_poll(struct cdev *dev, int poll_even mtx_lock(&sc->aac_aifq_lock); if ((poll_events & (POLLRDNORM | POLLIN)) != 0) { - for (ctx = sc->fibctx; ctx; ctx = ctx->next) { - if (ctx->ctx_idx != sc->aifq_idx || ctx->ctx_wrap) { + if (sc->aifq_idx != 0 || sc->aifq_filled) revents |= poll_events & (POLLIN | POLLRDNORM); - break; - } - } } mtx_unlock(&sc->aac_aifq_lock); @@ -3064,24 +3202,24 @@ static int aac_ioctl_send_raw_srb(struct aac_softc *sc, caddr_t arg) { struct aac_command *cm; - struct aac_event *event; struct aac_fib *fib; - struct aac_srb *srbcmd, *user_srb; - struct aac_sg_entry *sge; - struct aac_sg_entry64 *sge64; - void *srb_sg_address, *ureply; - uint32_t fibsize, srb_sg_bytecount; - int error, transfer_data; + struct aac_srb *srbcmd; + struct aac_srb *user_srb = (struct aac_srb *)arg; + void *user_reply; + int error, transfer_data = 0; + bus_dmamap_t orig_map = 0; + u_int32_t fibsize = 0; + u_int64_t srb_sg_address; + u_int32_t srb_sg_bytecount; fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, ""); cm = NULL; - transfer_data = 0; - fibsize = 0; - user_srb = (struct aac_srb *)arg; mtx_lock(&sc->aac_io_lock); if (aac_alloc_command(sc, &cm)) { + struct aac_event *event; + event = malloc(sizeof(struct aac_event), M_AACBUF, M_NOWAIT | M_ZERO); if (event == NULL) { @@ -3093,80 +3231,111 @@ aac_ioctl_send_raw_srb(struct aac_softc event->ev_callback = aac_ioctl_event; event->ev_arg = &cm; aac_add_event(sc, event); - msleep(cm, &sc->aac_io_lock, 0, "aacraw", 0); + msleep(cm, &sc->aac_io_lock, 0, "sndraw", 0); } mtx_unlock(&sc->aac_io_lock); cm->cm_data = NULL; + /* save original dma map */ + orig_map = cm->cm_datamap; + fib = cm->cm_fib; srbcmd = (struct aac_srb *)fib->data; - error = copyin(&user_srb->data_len, &fibsize, sizeof(uint32_t)); - if (error != 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; } - error = copyin(user_srb, srbcmd, fibsize); - if (error != 0) + if ((error = copyin((void *)user_srb, srbcmd, fibsize) != 0)) goto out; - srbcmd->function = 0; - srbcmd->retry_limit = 0; + + srbcmd->function = 0; /* SRBF_ExecuteScsi */ + srbcmd->retry_limit = 0; /* obsolete */ + + /* only one sg element from userspace supported */ if (srbcmd->sg_map.SgCount > 1) { error = EINVAL; goto out; } - - /* Retrieve correct SG entries. */ + /* check fibsize */ if (fibsize == (sizeof(struct aac_srb) + srbcmd->sg_map.SgCount * sizeof(struct aac_sg_entry))) { - sge = srbcmd->sg_map.SgEntry; - sge64 = NULL; - srb_sg_bytecount = sge->SgByteCount; - srb_sg_address = (void *)(uintptr_t)sge->SgAddress; - } -#ifdef __amd64__ - else if (fibsize == (sizeof(struct aac_srb) + + struct aac_sg_entry *sgp = srbcmd->sg_map.SgEntry; + srb_sg_bytecount = sgp->SgByteCount; + srb_sg_address = (u_int64_t)sgp->SgAddress; + } else if (fibsize == (sizeof(struct aac_srb) + srbcmd->sg_map.SgCount * sizeof(struct aac_sg_entry64))) { - sge = NULL; - sge64 = (struct aac_sg_entry64 *)srbcmd->sg_map.SgEntry; - srb_sg_bytecount = sge64->SgByteCount; - srb_sg_address = (void *)sge64->SgAddress; - if (sge64->SgAddress > 0xffffffffull && - (sc->flags & AAC_FLAGS_SG_64BIT) == 0) { +#ifdef __amd64__ + struct aac_sg_entry64 *sgp = + (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; } - } -#endif - else { + } else { error = EINVAL; goto out; } - ureply = (char *)arg + fibsize; + user_reply = (char *)arg + fibsize; srbcmd->data_len = srb_sg_bytecount; if (srbcmd->sg_map.SgCount == 1) transfer_data = 1; - cm->cm_sgtable = (struct aac_sg_table *)&srbcmd->sg_map; if (transfer_data) { - cm->cm_datalen = srb_sg_bytecount; - cm->cm_data = malloc(cm->cm_datalen, M_AACBUF, M_NOWAIT); - if (cm->cm_data == NULL) { + /* + * Create DMA tag for the passthr. data buffer and allocate it. + */ + if (bus_dma_tag_create(sc->aac_parent_dmat, /* parent */ + 1, 0, /* algnmnt, boundary */ + (sc->flags & AAC_FLAGS_SG_64BIT) ? + BUS_SPACE_MAXADDR_32BIT : + 0x7fffffff, /* lowaddr */ + BUS_SPACE_MAXADDR, /* highaddr */ + NULL, NULL, /* filter, filterarg */ + srb_sg_bytecount, /* size */ + sc->aac_sg_tablesize, /* nsegments */ + srb_sg_bytecount, /* maxsegsize */ + 0, /* flags */ + NULL, NULL, /* No locking needed */ + &cm->cm_passthr_dmat)) { + error = ENOMEM; + goto out; + } + if (bus_dmamem_alloc(cm->cm_passthr_dmat, (void **)&cm->cm_data, + BUS_DMA_NOWAIT, &cm->cm_datamap)) { error = ENOMEM; goto out; } + /* fill some cm variables */ + cm->cm_datalen = srb_sg_bytecount; if (srbcmd->flags & AAC_SRB_FLAGS_DATA_IN) cm->cm_flags |= AAC_CMD_DATAIN; - if (srbcmd->flags & AAC_SRB_FLAGS_DATA_OUT) { + if (srbcmd->flags & AAC_SRB_FLAGS_DATA_OUT) cm->cm_flags |= AAC_CMD_DATAOUT; - error = copyin(srb_sg_address, cm->cm_data, - cm->cm_datalen); - if (error != 0) + + if (srbcmd->flags & AAC_SRB_FLAGS_DATA_OUT) { + if ((error = copyin( +#ifdef __amd64__ + (void *)srb_sg_address, +#else + (void *)(u_int32_t)srb_sg_address, +#endif + cm->cm_data, cm->cm_datalen)) != 0) goto out; + /* sync required for bus_dmamem_alloc() alloc. mem.? */ + bus_dmamap_sync(cm->cm_passthr_dmat, cm->cm_datamap, + BUS_DMASYNC_PREWRITE); } } + /* build the FIB */ fib->Header.Size = sizeof(struct aac_fib_header) + sizeof(struct aac_srb); fib->Header.XferState = @@ -3178,23 +3347,55 @@ aac_ioctl_send_raw_srb(struct aac_softc AAC_FIBSTATE_NORM | AAC_FIBSTATE_ASYNC | AAC_FIBSTATE_FAST_RESPONSE; - fib->Header.Command = (sc->flags & AAC_FLAGS_SG_64BIT) != 0 ? + + fib->Header.Command = (sc->flags & AAC_FLAGS_SG_64BIT) ? ScsiPortCommandU64 : ScsiPortCommand; + cm->cm_sgtable = (struct aac_sg_table *)&srbcmd->sg_map; + /* send command */ + if (transfer_data) { + bus_dmamap_load(cm->cm_passthr_dmat, + cm->cm_datamap, cm->cm_data, + cm->cm_datalen, + aac_map_command_sg, cm, 0); + } else { + aac_map_command_sg(cm, NULL, 0, 0); + } + + /* wait for completion */ mtx_lock(&sc->aac_io_lock); - aac_wait_command(cm); + while (!(cm->cm_flags & AAC_CMD_COMPLETED)) + msleep(cm, &sc->aac_io_lock, 0, "sndrw2", 0); mtx_unlock(&sc->aac_io_lock); - if (transfer_data && (srbcmd->flags & AAC_SRB_FLAGS_DATA_IN) != 0) { - error = copyout(cm->cm_data, srb_sg_address, cm->cm_datalen); - if (error != 0) + /* copy data */ + if (transfer_data && (srbcmd->flags & AAC_SRB_FLAGS_DATA_IN)) { + if ((error = copyout(cm->cm_data, +#ifdef __amd64__ + (void *)srb_sg_address, +#else + (void *)(u_int32_t)srb_sg_address, +#endif + cm->cm_datalen)) != 0) goto out; + /* sync required for bus_dmamem_alloc() allocated mem.? */ + bus_dmamap_sync(cm->cm_passthr_dmat, cm->cm_datamap, + BUS_DMASYNC_POSTREAD); } - error = copyout(fib->data, ureply, sizeof(struct aac_srb_response)); + + /* status */ + error = copyout(fib->data, user_reply, sizeof(struct aac_srb_response)); + out: - if (cm != NULL) { - if (cm->cm_data != NULL) - free(cm->cm_data, M_AACBUF); + if (cm && cm->cm_data) { + if (transfer_data) + bus_dmamap_unload(cm->cm_passthr_dmat, cm->cm_datamap); + bus_dmamem_free(cm->cm_passthr_dmat, cm->cm_data, cm->cm_datamap); + cm->cm_datamap = orig_map; + } + if (cm && cm->cm_passthr_dmat) + bus_dma_tag_destroy(cm->cm_passthr_dmat); + if (cm) { mtx_lock(&sc->aac_io_lock); aac_release_command(cm); mtx_unlock(&sc->aac_io_lock); @@ -3293,6 +3494,9 @@ aac_handle_aif(struct aac_softc *sc, str co = TAILQ_FIRST(&sc->aac_container_tqh); while (co != NULL) { if (co->co_found == 0) { + struct aac_disk *ad; + ad = device_get_softc(co->co_disk); + ad->ad_container = NULL; mtx_unlock(&sc->aac_io_lock); mtx_lock(&Giant); device_delete_child(sc->aac_dev, @@ -3323,6 +3527,17 @@ aac_handle_aif(struct aac_softc *sc, str break; + case AifEnAddJBOD: + case AifEnDeleteJBOD: + { + u_int32_t container = + aif->data.EN.data.ECE.container; + + /* re-enumerate JBOD devices */ + aac_cam_rescan_jbod(sc,((container>>24) & 0xf)); + } + break; + default: break; } @@ -3397,7 +3612,7 @@ aac_rev_check(struct aac_softc *sc, cadd rev_check_resp.adapterSWRevision.external.comp.dash = AAC_DRIVER_BUGFIX_LEVEL; rev_check_resp.adapterSWRevision.buildNumber = - AAC_DRIVER_BUILD; + (u_int32_t)AAC_DRIVER_BUILD; return(copyout((caddr_t)&rev_check_resp, udata, sizeof(struct aac_rev_check_resp))); @@ -3589,6 +3804,7 @@ aac_supported_features(struct aac_softc if (f.feat.fValue == 0) { f.feat.fBits.largeLBA = (sc->flags & AAC_FLAGS_LBA_64BIT) ? 1 : 0; + f.feat.fBits.JBODSupport = 1; /* TODO: In the future, add other features state here as well */ } else { if (f.feat.fBits.largeLBA) @@ -3746,7 +3962,7 @@ aac_get_bus_info(struct aac_softc *sc) break; }; - child = device_add_child(sc->aac_dev, "aacp", -1); + child = device_add_child(sc->aac_dev, "aacpu", -1); if (child == NULL) { device_printf(sc->aac_dev, "device_add_child failed for passthrough bus %d\n", @@ -3760,6 +3976,7 @@ aac_get_bus_info(struct aac_softc *sc) caminf->InitiatorBusId = businfo.InitiatorBusId[i]; caminf->aac_sc = sc; caminf->sim_dev = child; + caminf->aac_cam = NULL; device_set_ivars(child, caminf); device_set_desc(child, "SCSI Passthrough Bus"); @@ -3773,3 +3990,159 @@ aac_get_bus_info(struct aac_softc *sc) return; } + +/* + * Check to see if the kernel is up and running. If we are in a + * BlinkLED state, return the BlinkLED code. + */ +static u_int32_t +aac_check_adapter_health(struct aac_softc *sc, u_int8_t *bled) +{ + u_int32_t ret; + + ret = AAC_GET_FWSTATUS(sc); + + if (ret & AAC_UP_AND_RUNNING) + ret = 0; + else if (ret & AAC_KERNEL_PANIC && bled) + *bled = (ret >> 16) & 0xff; + + return (ret); +} + +/* + * Once do an IOP reset, basically have to re-initialize the card as + * if coming up from a cold boot, and the driver is responsible for + * any IO that was outstanding to the adapter at the time of the IOP + * RESET. And prepare the driver for IOP RESET by making the init code + * modular with the ability to call it from multiple places. + */ +static int +aac_reset_adapter(struct aac_softc *sc) +{ + struct aac_command *cm; + u_int32_t status, old_flags; + + fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, ""); + + if (sc->aac_state & AAC_STATE_RESET) { + device_printf(sc->aac_dev, "aac_reset_adapter() already in progress\n"); + return (EINVAL); + } + sc->aac_state |= AAC_STATE_RESET; + + /* disable interrupt */ + AAC_MASK_INTERRUPTS(sc); + + /* + * Abort all pending commands: + * a) on the controller + */ + while ((cm = aac_dequeue_busy(sc)) != NULL) { + cm->cm_flags |= AAC_CMD_RESET; + + /* is there a completion handler? */ + if (cm->cm_complete != NULL) { + cm->cm_complete(cm); + } else { + /* assume that someone is sleeping on this + * command + */ + wakeup(cm); + } + } + + /* b) in the waiting queues */ + while ((cm = aac_dequeue_ready(sc)) != NULL) { + cm->cm_flags |= AAC_CMD_RESET; + + /* is there a completion handler? */ + if (cm->cm_complete != NULL) { + cm->cm_complete(cm); + } else { + /* assume that someone is sleeping on this + * command + */ + wakeup(cm); + } + } + + /* flush drives */ + if (aac_check_adapter_health(sc, NULL) == 0) + (void) aac_shutdown(sc->aac_dev); + + /* execute IOP reset */ + if ((aac_sync_command(sc, AAC_IOP_RESET, 0, 0, 0, 0, &status)) != 0) { + struct aac_fib *fib; + struct aac_pause_command *pc; + u_int32_t waitCount; + + if ((status & 0xf) == 0xf) { + /* Sunrise Lake has dual cores and we must drag the other core + * with us to reset simultaneously. There are 2 bits in the + * Inbound Reset Control and Status Register (offset 0x38) of the + * Sunrise Lake to reset the chip without clearing out the + * PCI configuration info (COMMAND & BARS). + */ + + 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 + */ + waitCount = 5 * 10000; + while (waitCount) { + DELAY(100); /* delay 100 microseconds */ + waitCount--; + } + } else { + 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; + } + } + + /* + * Re-read and renegotiate the FIB parameters, as one of the actions + * that can result from an IOP reset is the running of a new firmware + * image. + */ + old_flags = sc->flags; + /* + * Initialize the adapter. + */ + if (aac_check_firmware(sc) != 0) + goto finish; + if (aac_init(sc) != 0) + goto finish; + + if ((old_flags & AAC_FLAGS_NEW_COMM) && + !(sc->flags & AAC_FLAGS_NEW_COMM)) { + /* remap interrupt handler */ + aac_setup_intr(sc); + } + +finish: + sc->aac_state &= ~AAC_STATE_RESET; + AAC_UNMASK_INTERRUPTS(sc); + aac_startio(sc); + return (0); +} + diff -purw --exclude .svn -I '\$FreeBSD.*\$' -I '"aac"' -I '"aacu"' -I '"aacd"' -I '"aacdu"' -I '"aacch"' -I '"aacchu"' ./aac_cam.c /home/emaste/adaptec/aac_cam.c --- ./aac_cam.c 2010-04-12 16:32:27.000000000 -0400 +++ /home/emaste/adaptec/aac_cam.c 2009-08-28 13:13:22.000000000 -0400 @@ -45,6 +45,7 @@ __FBSDID("$FreeBSD: head/sys/dev/aac/aac #include #include #include +#include #include #include @@ -61,8 +62,11 @@ __FBSDID("$FreeBSD: head/sys/dev/aac/aac #include #include +#include #include +#include + struct aac_cam { device_t dev; struct aac_sim *inf; @@ -90,16 +94,49 @@ static device_method_t aac_pass_methods[ }; static driver_t aac_pass_driver = { - "aacp", + "aacpu", aac_pass_methods, sizeof(struct aac_cam) }; -DRIVER_MODULE(aacp, aac, aac_pass_driver, aac_pass_devclass, 0, 0); -MODULE_DEPEND(aacp, cam, 1, 1, 1); +DRIVER_MODULE(aacpu, aacu, aac_pass_driver, aac_pass_devclass, 0, 0); +MODULE_DEPEND(aacpu, cam, 1, 1, 1); MALLOC_DEFINE(M_AACCAM, "aaccam", "AAC CAM info"); +void +aac_cam_rescan_jbod(struct aac_softc *sc, u_int32_t chn) +{ + union ccb *ccb; + struct aac_sim *sim; + struct aac_cam *camsc; + + /* re-enumerate JBOD devices */ + for (sim = TAILQ_FIRST(&sc->aac_sim_tqh); sim != NULL; + sim = TAILQ_NEXT(sim, sim_link)) { + camsc = sim->aac_cam; + if (!camsc || !camsc->inf || camsc->inf->BusNumber != chn) + continue; + + ccb = xpt_alloc_ccb_nowait(); + if (ccb == NULL) { + device_printf(sc->aac_dev, + "Cannot allocate ccb for bus rescan\n"); + break; + } + if (xpt_create_path(&ccb->ccb_h.path, xpt_periph, + cam_sim_path(camsc->sim), + CAM_TARGET_WILDCARD, CAM_LUN_WILDCARD) != CAM_REQ_CMP) { + xpt_free_ccb(ccb); + device_printf(sc->aac_dev, + "Cannot create path for bus rescan\n"); + break; + } + xpt_rescan(ccb); + break; + } +} + static void aac_cam_event(struct aac_softc *sc, struct aac_event *event, void *arg) { @@ -141,6 +178,7 @@ aac_cam_detach(device_t dev) camsc = (struct aac_cam *)device_get_softc(dev); sc = camsc->inf->aac_sc; + camsc->inf->aac_cam = NULL; mtx_lock(&sc->aac_io_lock); @@ -171,12 +209,13 @@ aac_cam_attach(device_t dev) camsc = (struct aac_cam *)device_get_softc(dev); inf = (struct aac_sim *)device_get_ivars(dev); camsc->inf = inf; + camsc->inf->aac_cam = camsc; devq = cam_simq_alloc(inf->TargetsPerBus); if (devq == NULL) return (EIO); - sim = cam_sim_alloc(aac_cam_action, aac_cam_poll, "aacp", camsc, + sim = cam_sim_alloc(aac_cam_action, aac_cam_poll, "aacpu", camsc, device_get_unit(dev), &inf->aac_sc->aac_io_lock, 1, 1, devq); if (sim == NULL) { cam_simq_free(devq); @@ -260,11 +299,8 @@ aac_cam_action(struct cam_sim *sim, unio cpi->hba_inquiry = PI_WIDE_16; cpi->target_sprt = 0; - /* - * Resetting via the passthrough or parallel bus scan - * causes problems. - */ - cpi->hba_misc = PIM_NOBUSRESET | PIM_SEQSCAN; + /* Resetting via the passthrough causes problems. */ + cpi->hba_misc = PIM_NOBUSRESET; cpi->hba_eng_cnt = 0; cpi->max_target = camsc->inf->TargetsPerBus; cpi->max_lun = 8; /* Per the controller spec */ @@ -490,7 +526,9 @@ aac_cam_complete(struct aac_command *cm) ccb = cm->cm_private; srbr = (struct aac_srb_response *)&cm->cm_fib->data[0]; - if (srbr->fib_status != 0) { + if (cm->cm_flags & AAC_CMD_RESET) { + ccb->ccb_h.status = CAM_SCSI_BUS_RESET; + } else if (srbr->fib_status != 0) { device_printf(sc->aac_dev, "Passthru FIB failed!\n"); ccb->ccb_h.status = CAM_REQ_ABORTED; } else { @@ -535,7 +573,8 @@ aac_cam_complete(struct aac_command *cm) * We want DASD and PROC devices to only be * visible through the pass device. */ - if ((device == T_DIRECT) || + if ((device == T_DIRECT && + !(sc->aac_feature_bits & AAC_SUPPL_SUPPORTED_JBOD)) || (device == T_PROCESSOR) || (sc->flags & AAC_FLAGS_CAM_PASSONLY)) ccb->csio.data_ptr[0] = diff -purw --exclude .svn -I '\$FreeBSD.*\$' -I '"aac"' -I '"aacu"' -I '"aacd"' -I '"aacdu"' -I '"aacch"' -I '"aacchu"' ./aac_debug.c /home/emaste/adaptec/aac_debug.c --- ./aac_debug.c 2010-04-12 16:32:27.000000000 -0400 +++ /home/emaste/adaptec/aac_debug.c 2009-08-28 13:13:22.000000000 -0400 @@ -47,10 +47,10 @@ __FBSDID("$FreeBSD: head/sys/dev/aac/aac #include #include +#include #include #ifdef AAC_DEBUG -int aac_debug_enable = 0; void aac_printstate0(void); /* @@ -134,7 +134,6 @@ aac_printstate0(void) aac_print_queues(sc); switch (sc->aac_hwif) { case AAC_HWIF_I960RX: - case AAC_HWIF_NARK: device_printf(sc->aac_dev, "IDBR 0x%08x IIMR 0x%08x " "IISR 0x%08x\n", AAC_MEM0_GETREG4(sc, AAC_RX_IDBR), AAC_MEM0_GETREG4(sc, AAC_RX_IIMR), AAC_MEM0_GETREG4(sc, AAC_RX_IISR)); diff -purw --exclude .svn -I '\$FreeBSD.*\$' -I '"aac"' -I '"aacu"' -I '"aacd"' -I '"aacdu"' -I '"aacch"' -I '"aacchu"' ./aac_disk.c /home/emaste/adaptec/aac_disk.c --- ./aac_disk.c 2010-04-12 16:32:27.000000000 -0400 +++ /home/emaste/adaptec/aac_disk.c 2009-08-28 13:13:22.000000000 -0400 @@ -36,6 +36,7 @@ __FBSDID("$FreeBSD: head/sys/dev/aac/aac #include #include #include +#include #include #include @@ -50,6 +51,7 @@ __FBSDID("$FreeBSD: head/sys/dev/aac/aac #include #include +#include #include /* @@ -82,7 +84,17 @@ static driver_t aac_disk_driver = { sizeof(struct aac_disk) }; -DRIVER_MODULE(aacd, aac, aac_disk_driver, aac_disk_devclass, 0, 0); +#define AAC_MAXIO 65536 + +DRIVER_MODULE(aacdu, aacu, aac_disk_driver, aac_disk_devclass, 0, 0); + +/* sysctl tunables */ +static unsigned int aac_iosize_max = AAC_MAXIO; /* due to limits of the card */ +TUNABLE_INT("hw.aac.iosize_max", &aac_iosize_max); + +SYSCTL_DECL(_hw_aac); +SYSCTL_UINT(_hw_aac, OID_AUTO, iosize_max, CTLFLAG_RDTUN, &aac_iosize_max, 0, + "Max I/O size per transfer to an array"); /* * Handle open from generic layer. @@ -93,25 +105,59 @@ DRIVER_MODULE(aacd, aac, aac_disk_driver static int aac_disk_open(struct disk *dp) { - struct aac_disk *sc; + struct aac_disk *scd; + struct aac_softc *sc; fwprintf(NULL, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, ""); - sc = (struct aac_disk *)dp->d_drv1; + scd = (struct aac_disk *)dp->d_drv1; - if (sc == NULL) { + if (scd == NULL) { printf("aac_disk_open: No Softc\n"); return (ENXIO); } + sc = scd->ad_controller; /* check that the controller is up and running */ - if (sc->ad_controller->aac_state & AAC_STATE_SUSPEND) { + if (sc->aac_state & AAC_STATE_SUSPEND) { printf("Controller Suspended controller state = 0x%x\n", - sc->ad_controller->aac_state); + sc->aac_state); return(ENXIO); } - sc->ad_flags |= AAC_DISK_OPEN; + /* already opened? */ + if (scd->ad_flags & AAC_DISK_OPEN) + return (0); + + /* power management */ + if (sc->aac_support_opt2 & AAC_SUPPORTED_POWER_MANAGEMENT) { + struct aac_fib *fib; + struct aac_cnt_config *cmd; + + mtx_lock(&sc->aac_io_lock); + aac_alloc_sync_fib(sc, &fib); + + /* Start unit */ + cmd = (struct aac_cnt_config *)&fib->data[0]; + bzero(cmd, sizeof (*cmd) - CT_PACKET_SIZE); + cmd->Command = VM_ContainerConfig; + cmd->CTCommand.command = CT_PM_DRIVER_SUPPORT; + cmd->CTCommand.param[0] = AAC_PM_DRIVERSUP_START_UNIT; + cmd->CTCommand.param[1] = scd->ad_container->co_mntobj.ObjectId; + cmd->CTCommand.param[2] = 0; /* 1 - immediate */ + + if (aac_sync_fib(sc, ContainerCommand, 0, fib, + sizeof(struct aac_cnt_config)) || + *(u_int32_t *)&fib->data[0] != 0) { + printf("Power Management: Error starting container %d\n", + scd->ad_container->co_mntobj.ObjectId); + } + + aac_release_sync_fib(sc); + mtx_unlock(&sc->aac_io_lock); + } + + scd->ad_flags |= AAC_DISK_OPEN; return (0); } @@ -121,16 +167,50 @@ aac_disk_open(struct disk *dp) static int aac_disk_close(struct disk *dp) { - struct aac_disk *sc; + struct aac_disk *scd; + struct aac_softc *sc; fwprintf(NULL, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, ""); - sc = (struct aac_disk *)dp->d_drv1; + scd = (struct aac_disk *)dp->d_drv1; - if (sc == NULL) + if (scd == NULL) return (ENXIO); + sc = scd->ad_controller; - sc->ad_flags &= ~AAC_DISK_OPEN; + /* already closed? */ + if (!(scd->ad_flags & AAC_DISK_OPEN)) + return (0); + + /* power management */ + if (sc->aac_support_opt2 & AAC_SUPPORTED_POWER_MANAGEMENT) { + struct aac_fib *fib; + struct aac_cnt_config *cmd; + + mtx_lock(&sc->aac_io_lock); + aac_alloc_sync_fib(sc, &fib); + + /* Stop unit */ + cmd = (struct aac_cnt_config *)&fib->data[0]; + bzero(cmd, sizeof (*cmd) - CT_PACKET_SIZE); + cmd->Command = VM_ContainerConfig; + cmd->CTCommand.command = CT_PM_DRIVER_SUPPORT; + cmd->CTCommand.param[0] = AAC_PM_DRIVERSUP_STOP_UNIT; + cmd->CTCommand.param[1] = scd->ad_container->co_mntobj.ObjectId; + cmd->CTCommand.param[2] = 0; /* 1 - immediate */ + + if (aac_sync_fib(sc, ContainerCommand, 0, fib, + sizeof(struct aac_cnt_config)) || + *(u_int32_t *)&fib->data[0] != 0) { + printf("Power Management: Error stopping container %d\n", + scd->ad_container->co_mntobj.ObjectId); + } + + aac_release_sync_fib(sc); + mtx_unlock(&sc->aac_io_lock); + } + + scd->ad_flags &= ~AAC_DISK_OPEN; return (0); } @@ -172,6 +252,9 @@ aac_disk_strategy(struct bio *bp) /* * Map the S/G elements for doing a dump. + * + * XXX This does not handle >4GB of RAM. Fixing it is possible except on + * adapters that cannot do 64bit s/g lists. */ static void aac_dump_map_sg(void *arg, bus_dma_segment_t *segs, int nsegs, int error) @@ -198,34 +281,9 @@ aac_dump_map_sg(void *arg, bus_dma_segme } /* - * Map the S/G elements for doing a dump on 64-bit capable devices. - */ -static void -aac_dump_map_sg64(void *arg, bus_dma_segment_t *segs, int nsegs, int error) -{ - struct aac_fib *fib; - struct aac_blockwrite64 *bw; - struct aac_sg_table64 *sg; - int i; - - fib = (struct aac_fib *)arg; - bw = (struct aac_blockwrite64 *)&fib->data[0]; - sg = &bw->SgMap64; - - if (sg != NULL) { - sg->SgCount = nsegs; - for (i = 0; i < nsegs; i++) { - sg->SgEntry64[i].SgAddress = segs[i].ds_addr; - sg->SgEntry64[i].SgByteCount = segs[i].ds_len; - } - fib->Header.Size = nsegs * sizeof(struct aac_sg_entry64); - } -} - -/* * Dump memory out to an array * - * Send out one command at a time with up to maxio of data. + * Send out one command at a time with up to AAC_MAXIO of data. */ static int aac_disk_dump(void *arg, void *virtual, vm_offset_t physical, off_t offset, size_t length) @@ -233,13 +291,12 @@ aac_disk_dump(void *arg, void *virtual, struct aac_disk *ad; struct aac_softc *sc; struct aac_fib *fib; - size_t len, maxio; + struct aac_blockwrite *bw; + size_t len; int size; static bus_dmamap_t dump_datamap; static int first = 0; struct disk *dp; - bus_dmamap_callback_t *callback; - u_int32_t command; dp = arg; ad = dp->d_drv1; @@ -259,34 +316,15 @@ aac_disk_dump(void *arg, void *virtual, /* Skip aac_alloc_sync_fib(). We don't want to mess with sleep locks */ fib = &sc->aac_common->ac_sync_fib; + bw = (struct aac_blockwrite *)&fib->data[0]; while (length > 0) { - maxio = sc->aac_max_sectors << 9; - len = (length > maxio) ? maxio : length; - if ((sc->flags & AAC_FLAGS_SG_64BIT) == 0) { - struct aac_blockwrite *bw; - bw = (struct aac_blockwrite *)&fib->data[0]; + len = (length > AAC_MAXIO) ? AAC_MAXIO : length; bw->Command = VM_CtBlockWrite; bw->ContainerId = ad->ad_container->co_mntobj.ObjectId; bw->BlockNumber = offset / AAC_BLOCK_SIZE; bw->ByteCount = len; bw->Stable = CUNSTABLE; - command = ContainerCommand; - callback = aac_dump_map_sg; - size = sizeof(struct aac_blockwrite); - } else { - struct aac_blockwrite64 *bw; - bw = (struct aac_blockwrite64 *)&fib->data[0]; - bw->Command = VM_CtHostWrite64; - bw->ContainerId = ad->ad_container->co_mntobj.ObjectId; - bw->BlockNumber = offset / AAC_BLOCK_SIZE; - bw->SectorCount = len / AAC_BLOCK_SIZE; - bw->Pad = 0; - bw->Flags = 0; - command = ContainerCommand64; - callback = aac_dump_map_sg64; - size = sizeof(struct aac_blockwrite64); - } /* * There really isn't any way to recover from errors or @@ -295,16 +333,16 @@ aac_disk_dump(void *arg, void *virtual, * is too much required context. */ if (bus_dmamap_load(sc->aac_buffer_dmat, dump_datamap, virtual, - len, callback, fib, BUS_DMA_NOWAIT) != 0) + len, aac_dump_map_sg, fib, BUS_DMA_NOWAIT) != 0) return (ENOMEM); bus_dmamap_sync(sc->aac_buffer_dmat, dump_datamap, BUS_DMASYNC_PREWRITE); /* fib->Header.Size is set in aac_dump_map_sg */ - size += fib->Header.Size; + size = fib->Header.Size + sizeof(struct aac_blockwrite); - if (aac_sync_fib(sc, command, 0, fib, size)) { + if (aac_sync_fib(sc, ContainerCommand, 0, fib, size)) { printf("Error dumping block 0x%jx\n", (uintmax_t)physical); return (EIO); @@ -397,8 +435,8 @@ aac_disk_attach(device_t dev) sc->unit = device_get_unit(dev); sc->ad_disk = disk_alloc(); sc->ad_disk->d_drv1 = sc; - sc->ad_disk->d_name = "aacd"; - sc->ad_disk->d_maxsize = sc->ad_controller->aac_max_sectors << 9; + sc->ad_disk->d_name = "aacdu"; + sc->ad_disk->d_maxsize = aac_iosize_max; sc->ad_disk->d_open = aac_disk_open; sc->ad_disk->d_close = aac_disk_close; sc->ad_disk->d_strategy = aac_disk_strategy; diff -purw --exclude .svn -I '\$FreeBSD.*\$' -I '"aac"' -I '"aacu"' -I '"aacd"' -I '"aacdu"' -I '"aacch"' -I '"aacchu"' ./aac_pci.c /home/emaste/adaptec/aac_pci.c --- ./aac_pci.c 2010-04-12 16:32:27.000000000 -0400 +++ /home/emaste/adaptec/aac_pci.c 2009-08-28 13:13:22.000000000 -0400 @@ -55,6 +55,7 @@ __FBSDID("$FreeBSD: head/sys/dev/aac/aac #include #include +#include #include static int aac_pci_probe(device_t dev); @@ -177,7 +178,7 @@ struct aac_ident {0x9005, 0x0285, 0x1014, 0x0312, AAC_HWIF_I960RX, 0, "IBM ServeRAID 8i"}, {0x9005, 0x0285, 0x9005, 0x0298, AAC_HWIF_I960RX, 0, - "Adaptec SAS RAID 4000SAS"}, + "Adaptec RAID 4000"}, {0x9005, 0x0285, 0x9005, 0x0299, AAC_HWIF_I960RX, 0, "Adaptec SAS RAID 4800SAS"}, {0x9005, 0x0285, 0x9005, 0x029a, AAC_HWIF_I960RX, 0, @@ -370,11 +363,48 @@ aac_pci_attach(device_t dev) } /* + * Detect the hardware interface version, set up the bus interface + * indirection. + */ + id = aac_find_ident(dev); + sc->aac_hwif = id->hwif; + switch(sc->aac_hwif) { + case AAC_HWIF_I960RX: + case AAC_HWIF_NARK: + fwprintf(sc, HBA_FLAGS_DBG_INIT_B, "set hardware up for i960Rx/NARK"); + sc->aac_if = aac_rx_interface; + break; + case AAC_HWIF_STRONGARM: + fwprintf(sc, HBA_FLAGS_DBG_INIT_B, "set hardware up for StrongARM"); + sc->aac_if = aac_sa_interface; + break; + case AAC_HWIF_RKT: + fwprintf(sc, HBA_FLAGS_DBG_INIT_B, "set hardware up for Rocket/MIPS"); + sc->aac_if = aac_rkt_interface; + break; + default: + sc->aac_hwif = AAC_HWIF_UNKNOWN; + device_printf(sc->aac_dev, "unknown hardware type\n"); + error = ENXIO; + goto out; + } + + /* assume failure is 'out of memory' */ + error = ENOMEM; + + /* * Allocate the PCI register window. */ sc->aac_regs_rid0 = PCIR_BAR(0); if ((sc->aac_regs_res0 = bus_alloc_resource_any(sc->aac_dev, - SYS_RES_MEMORY, &sc->aac_regs_rid0, RF_ACTIVE)) == NULL) { + SYS_RES_MEMORY, + &sc->aac_regs_rid0, + RF_ACTIVE)) == + NULL) { device_printf(sc->aac_dev, "couldn't allocate register window 0\n"); goto out; @@ -385,9 +415,12 @@ aac_pci_attach(device_t dev) if (sc->aac_hwif == AAC_HWIF_NARK) { sc->aac_regs_rid1 = PCIR_BAR(1); if ((sc->aac_regs_res1 = bus_alloc_resource_any(sc->aac_dev, - SYS_RES_MEMORY, &sc->aac_regs_rid1, RF_ACTIVE)) == NULL) { + SYS_RES_MEMORY, + &sc->aac_regs_rid1, + RF_ACTIVE)) == + NULL) { device_printf(sc->aac_dev, - "couldn't allocate register window 1\n"); + "couldn't allocate register window 0\n"); goto out; } sc->aac_btag1 = rman_get_bustag(sc->aac_regs_res1); @@ -419,33 +452,6 @@ aac_pci_attach(device_t dev) goto out; } - /* - * Detect the hardware interface version, set up the bus interface - * indirection. - */ - id = aac_find_ident(dev); - sc->aac_hwif = id->hwif; - switch(sc->aac_hwif) { - case AAC_HWIF_I960RX: - case AAC_HWIF_NARK: - fwprintf(sc, HBA_FLAGS_DBG_INIT_B, "set hardware up for i960Rx/NARK"); - sc->aac_if = aac_rx_interface; - break; - case AAC_HWIF_STRONGARM: - fwprintf(sc, HBA_FLAGS_DBG_INIT_B, "set hardware up for StrongARM"); - sc->aac_if = aac_sa_interface; - break; - case AAC_HWIF_RKT: - fwprintf(sc, HBA_FLAGS_DBG_INIT_B, "set hardware up for Rocket/MIPS"); - sc->aac_if = aac_rkt_interface; - break; - default: - sc->aac_hwif = AAC_HWIF_UNKNOWN; - device_printf(sc->aac_dev, "unknown hardware type\n"); - error = ENXIO; - goto out; - } - /* Set up quirks */ sc->flags = id->quirks; @@ -488,7 +494,7 @@ static driver_t aacch_driver = { }; static devclass_t aacch_devclass; -DRIVER_MODULE(aacch, pci, aacch_driver, aacch_devclass, 0, 0); +DRIVER_MODULE(aacchu, pci, aacch_driver, aacch_devclass, 0, 0); static int aacch_probe(device_t dev) diff -purw --exclude .svn -I '\$FreeBSD.*\$' -I '"aac"' -I '"aacu"' -I '"aacd"' -I '"aacdu"' -I '"aacch"' -I '"aacchu"' ./aacreg.h /home/emaste/adaptec/aacreg.h --- ./aacreg.h 2010-04-12 16:42:14.000000000 -0400 +++ /home/emaste/adaptec/aacreg.h 2009-08-28 13:13:22.000000000 -0400 @@ -306,7 +306,9 @@ struct aac_adapter_init { u_int32_t HostElapsedSeconds; /* ADAPTER_INIT_STRUCT_REVISION_4 begins here */ u_int32_t InitFlags; /* flags for supported features */ -#define INITFLAGS_NEW_COMM_SUPPORTED 1 +#define AAC_INITFLAGS_NEW_COMM_SUPPORTED 1 +#define AAC_INITFLAGS_DRIVER_USES_UTC_TIME 0x10 +#define AAC_INITFLAGS_DRIVER_SUPPORTS_PM 0x20 u_int32_t MaxIoCommands; /* max outstanding commands */ u_int32_t MaxIoSize; /* largest I/O command */ u_int32_t MaxFibSize; /* largest FIB to adapter */ @@ -605,6 +607,19 @@ struct aac_adapter_info { } __packed; /* + * More options from supplement info - SupportedOptions2 + */ +#define AAC_SUPPORTED_MU_RESET 0x01 +#define AAC_SUPPORTED_IGNORE_RESET 0x02 +#define AAC_SUPPORTED_POWER_MANAGEMENT 0x04 +#define AAC_SUPPORTED_ARCIO_PHYDEV 0x08 + +/* + * FeatureBits of RequestSupplementAdapterInfo used in the driver + */ +#define AAC_SUPPL_SUPPORTED_JBOD 0x08000000 + +/* * Structure used to respond to a RequestSupplementAdapterInfo fib. */ struct vpd_info { @@ -652,8 +667,12 @@ struct aac_supplement_adapter_info { u_int8_t MfgPcbaSerialNo[MFG_PCBA_SERIAL_NUMBER_WIDTH]; /* WWN from the MFG sector */ u_int8_t MfgWWNName[MFG_WWN_WIDTH]; - /* Growth Area for future expansion ((7*4) - 12 - 8)/4 = 2 words */ - u_int32_t ReservedGrowth[2]; + u_int32_t SupportedOptions2; /* more supported features */ + u_int32_t ExpansionFlag; /* 1 - following fields are valid */ + u_int32_t FeatureBits3; + u_int32_t SupportedPerformanceMode; + /* Growth Area for future expansion */ + u_int32_t ReservedGrowth[80]; } __packed; /* @@ -673,6 +692,7 @@ struct aac_supplement_adapter_info { #define AAC_MONKER_RCVTEMP 0x25 #define AAC_MONKER_GETCOMMPREF 0x26 #define AAC_MONKER_REINIT 0xee +#define AAC_IOP_RESET 0x1000 /* * Adapter Status Register @@ -885,6 +905,17 @@ typedef enum { AifEnBatteryNeedsRecond, /* The battery needs reconditioning */ AifEnClusterEvent, /* Some cluster event */ AifEnDiskSetEvent, /* A disk set event occured. */ + AifEnContainerScsiEvent, /* a container event with no. and scsi id */ + AifEnPicBatteryEvent, /* An event gen. by pic_battery.c for an ABM */ + AifEnExpEvent, /* Exp. Event Type to replace CTPopUp messages */ + AifEnRAID6RebuildDone, /* RAID6 rebuild finished */ + AifEnSensorOverHeat, /* Heat Sensor indicate overheat */ + AifEnSensorCoolDown, /* Heat Sensor ind. cooled down after overheat */ + AifFeatureKeysModified, /* notif. of updated feature keys */ + AifApplicationExpirationEvent, /* notif. on app. expiration status */ + AifEnBackgroundConsistencyCheck, /* BCC notif. for NEC - DDTS 94700 */ + AifEnAddJBOD, /* A new JBOD type drive was created (30) */ + AifEnDeleteJBOD, /* A JBOD type drive was deleted (31) */ AifDriverNotifyStart=199, /* Notifies for host driver go here */ /* Host driver notifications start here */ AifDenMorphComplete, /* A morph operation completed */ @@ -1125,6 +1156,42 @@ typedef enum _VM_COMMANDS { VM_NameServe64 } AAC_VMCommand; +/* Container Configuration Sub-Commands */ +#define CT_GET_SCSI_METHOD 64 +#define CT_PAUSE_IO 65 +#define CT_RELEASE_IO 66 +#define CT_GET_CONFIG_STATUS 147 +#define CT_COMMIT_CONFIG 152 +#define CT_PM_DRIVER_SUPPORT 245 + +/* CT_PM_DRIVER_SUPPORT parameter */ +typedef enum { + AAC_PM_DRIVERSUP_GET_STATUS = 1, + AAC_PM_DRIVERSUP_START_UNIT, + AAC_PM_DRIVERSUP_STOP_UNIT +} AAC_CT_PM_DRIVER_SUPPORT_SUB_COM; + +/* + * CT_PAUSE_IO is immediate minimal runtime command that is used + * to restart the applications and cache. + */ +struct aac_pause_command { + u_int32_t Command; + u_int32_t Type; + u_int32_t Timeout; + u_int32_t Min; + u_int32_t NoRescan; + u_int32_t Parm3; + u_int32_t Parm4; + u_int32_t Count; +} __packed; + +/* Flag values for ContentState */ +#define AAC_FSCS_NOTCLEAN 0x1 /* fscheck is necessary before mounting */ +#define AAC_FSCS_READONLY 0x2 /* possible result of broken mirror */ +#define AAC_FSCS_HIDDEN 0x4 /* container should be ignored by driver */ +#define AAC_FSCS_NOT_READY 0x8 /* cnt is in spinn. state, not rdy for IO's */ + /* * "mountable object" */ @@ -1169,7 +1236,6 @@ struct aac_closecommand { /* * Container Config Command */ -#define CT_GET_SCSI_METHOD 64 struct aac_ctcfg { u_int32_t Command; u_int32_t cmd; @@ -1291,6 +1357,24 @@ typedef enum { CMUNSTABLE } AAC_CommitLevel; + +#define CT_FIB_PARAMS 6 +#define MAX_FIB_PARAMS 10 +#define CT_PACKET_SIZE \ + (AAC_FIB_DATASIZE - sizeof (u_int32_t) - \ + ((sizeof (u_int32_t)) * (MAX_FIB_PARAMS + 1))) + +struct aac_fsa_ctm { + u_int32_t command; + u_int32_t param[CT_FIB_PARAMS]; + int8_t data[CT_PACKET_SIZE]; +}; + +struct aac_cnt_config { + u_int32_t Command; + struct aac_fsa_ctm CTCommand; +}; + /* * Block read/write operations. * These structures are packed into the 'data' area in the FIB. @@ -1360,7 +1444,7 @@ struct aac_raw_io { struct aac_close_command { u_int32_t Command; u_int32_t ContainerId; -}; +} __packed; /* * SCSI Passthrough structures @@ -1377,7 +1461,7 @@ struct aac_srb { u_int32_t cdb_len; u_int8_t cdb[16]; struct aac_sg_table sg_map; -}; +} __packed; enum { AAC_SRB_FUNC_EXECUTE_SCSI = 0x00, @@ -1418,7 +1502,7 @@ struct aac_srb_response { u_int32_t data_len; u_int32_t sense_len; u_int8_t sense[AAC_HOST_SENSE_DATA_MAX]; -}; +} __packed; /* * Status codes for SCSI passthrough commands. Since they are based on ASPI, @@ -1455,6 +1539,24 @@ enum { }; /* + * Register set for adapters based on the Falcon bridge and PPC core + */ + +#define AAC_FA_DOORBELL0_CLEAR 0x00 +#define AAC_FA_DOORBELL1_CLEAR 0x02 +#define AAC_FA_DOORBELL0 0x04 +#define AAC_FA_DOORBELL1 0x06 +#define AAC_FA_MASK0_CLEAR 0x08 +#define AAC_FA_MASK1_CLEAR 0x0a +#define AAC_FA_MASK0 0x0c +#define AAC_FA_MASK1 0x0e +#define AAC_FA_MAILBOX 0x10 +#define AAC_FA_FWSTATUS 0x2c /* Mailbox 7 */ +#define AAC_FA_INTSRC 0x900 + +#define AAC_FA_HACK(sc) (void)AAC_MEM0_GETREG4(sc, AAC_FA_INTSRC) + +/* * Register definitions for the Adaptec AAC-364 'Jalapeno I/II' adapters, based * on the SA110 'StrongArm'. */ @@ -1512,6 +1614,11 @@ enum { #define AAC_RKT_MAILBOX 0x1000 /* mailbox */ #define AAC_RKT_FWSTATUS 0x101c /* Firmware Status (mailbox 7) */ +/* Sunrise Lake dual core reset */ +#define AAC_IRCSR 0x38 /* inbound dual cores reset */ +#define AAC_IRCSR_CORES_RST 3 + + /* * Common bit definitions for the doorbell registers. */ diff -purw --exclude .svn -I '\$FreeBSD.*\$' -I '"aac"' -I '"aacu"' -I '"aacd"' -I '"aacdu"' -I '"aacch"' -I '"aacchu"' ./aacvar.h /home/emaste/adaptec/aacvar.h --- ./aacvar.h 2010-04-12 16:32:27.000000000 -0400 +++ /home/emaste/adaptec/aacvar.h 2009-08-28 13:13:22.000000000 -0400 @@ -30,7 +30,6 @@ */ #include -#include #include #include #include @@ -43,12 +42,12 @@ #define AAC_TYPE_RELEASE 4 #define AAC_DRIVER_MAJOR_VERSION 2 -#define AAC_DRIVER_MINOR_VERSION 1 -#define AAC_DRIVER_BUGFIX_LEVEL 9 +#define AAC_DRIVER_MINOR_VERSION 2 +#define AAC_DRIVER_BUGFIX_LEVEL 8 #define AAC_DRIVER_TYPE AAC_TYPE_RELEASE #ifndef AAC_DRIVER_BUILD -# define AAC_DRIVER_BUILD 1 +# define AAC_DRIVER_BUILD 17517 #endif /* @@ -56,15 +55,16 @@ */ /* - * The firmware interface allows for a 16-bit s/g list length. We limit - * ourselves to a reasonable maximum and ensure alignment. + * We allocate a small set of FIBs for the adapter to use to send us messages. */ -#define AAC_MAXSGENTRIES 64 /* max S/G entries, limit 65535 */ +#define AAC_ADAPTER_FIBS 8 /* - * We allocate a small set of FIBs for the adapter to use to send us messages. + * FIBs are allocated in page-size chunks and can grow up to the 512 + * limit imposed by the hardware. */ -#define AAC_ADAPTER_FIBS 8 +#define AAC_PREALLOCATE_FIBS 512 +#define AAC_NUM_MGT_FIB 8 /* * The controller reports status events in AIFs. We hang on to a number of @@ -91,7 +91,7 @@ /* * Timeout for normal commands */ -#define AAC_CMD_TIMEOUT 120 /* seconds */ +#define AAC_CMD_TIMEOUT 30 /* seconds */ /* * Rate at which we periodically check for timed out commands and kick the @@ -113,6 +113,7 @@ struct aac_container /* * Per-SIM data structure */ +struct aac_cam; struct aac_sim { device_t sim_dev; @@ -120,6 +121,7 @@ struct aac_sim int BusNumber; int InitiatorBusId; struct aac_softc *aac_sc; + struct aac_cam *aac_cam; TAILQ_ENTRY(aac_sim) sim_link; }; @@ -174,14 +176,15 @@ struct aac_command #define AAC_ON_AACQ_AIF (1<<8) #define AAC_ON_AACQ_NORM (1<<10) #define AAC_ON_AACQ_MASK ((1<<5)|(1<<6)|(1<<7)|(1<<8)|(1<<10)) -#define AAC_QUEUE_FRZN (1<<9) /* Freeze the processing of - * commands on the queue. */ +#define AAC_CMD_RESET (1<<9) void (* cm_complete)(struct aac_command *cm); void *cm_private; time_t cm_timestamp; /* command creation time */ int cm_queue; int cm_index; + bus_dma_tag_t cm_passthr_dmat; /* passthrough buffer/command + * DMA tag */ }; struct aac_fibmap { @@ -315,6 +318,7 @@ struct aac_softc int aac_irq_rid; void *aac_intr; /* interrupt handle */ eventhandler_tag eh; + struct callout_handle timeout_id; /* timeout handle */ /* controller features, limits and status */ int aac_state; @@ -322,6 +326,7 @@ struct aac_softc #define AAC_STATE_OPEN (1<<1) #define AAC_STATE_INTERRUPTS_ON (1<<2) #define AAC_STATE_AIF_SLEEPER (1<<3) +#define AAC_STATE_RESET (1<<4) int aac_open_cnt; struct FsaRevision aac_revision; @@ -329,6 +334,7 @@ struct aac_softc int aac_hwif; #define AAC_HWIF_I960RX 0 #define AAC_HWIF_STRONGARM 1 +#define AAC_HWIF_FALCON 2 #define AAC_HWIF_RKT 3 #define AAC_HWIF_NARK 4 #define AAC_HWIF_UNKNOWN -1 @@ -409,18 +415,27 @@ struct aac_softc #define AAC_FLAGS_RAW_IO (1 << 12) /* Raw I/O interface */ #define AAC_FLAGS_ARRAY_64BIT (1 << 13) /* 64-bit array size */ #define AAC_FLAGS_LBA_64BIT (1 << 14) /* 64-bit LBA support */ - +#define AAC_QUEUE_FRZN (1<<15) /* Freeze the processing of + * commands on the queue. */ + u_int32_t hint_flags; /* driver parameters */ + int sim_freezed; /* flag for sim_freeze/release */ u_int32_t supported_options; u_int32_t scsi_method_id; TAILQ_HEAD(,aac_sim) aac_sim_tqh; - struct callout aac_daemontime; /* clock daemon callout */ - u_int32_t aac_max_fibs; /* max. FIB count */ u_int32_t aac_max_fibs_alloc; /* max. alloc. per alloc_commands() */ u_int32_t aac_max_fib_size; /* max. FIB size */ u_int32_t aac_sg_tablesize; /* max. sg count from host */ u_int32_t aac_max_sectors; /* max. I/O size from host (blocks) */ + 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 DebugFlags; /* Debug print flags bitmap */ + u_int32_t DebugOffset; /* Offset from DPMEM start */ + u_int32_t DebugHeaderSize; /* Size of debug header */ + u_int32_t FwDebugFlags; /* FW Debug Flags */ + u_int32_t FwDebugBufferSize; /* FW Debug Buffer Size in Bytes */ }; /* @@ -450,7 +465,7 @@ extern int aac_shutdown(device_t dev); extern int aac_suspend(device_t dev); extern int aac_resume(device_t dev); extern void aac_new_intr(void *arg); -extern int aac_filter(void *arg); +extern int aac_fast_intr(void *arg); extern void aac_submit_bio(struct bio *bp); extern void aac_biodone(struct bio *bp); extern void aac_startio(struct aac_softc *sc); @@ -462,19 +477,11 @@ extern int aac_sync_fib(struct aac_soft u_int16_t datasize); extern void aac_add_event(struct aac_softc *sc, struct aac_event *event); +extern void aac_cam_rescan_jbod(struct aac_softc *sc, u_int32_t chn); #ifdef AAC_DEBUG -extern int aac_debug_enable; # define fwprintf(sc, flags, fmt, args...) \ -do { \ - if (!aac_debug_enable) \ - break; \ - if (sc != NULL) \ - device_printf(((struct aac_softc *)sc)->aac_dev, \ - "%s: " fmt "\n", __func__, ##args); \ - else \ - printf("%s: " fmt "\n", __func__, ##args); \ -} while(0) + aac_fw_printf(sc, flags, "%s: " fmt, __func__, ##args); extern void aac_print_queues(struct aac_softc *sc); extern void aac_panic(struct aac_softc *sc, char *reason);