Only in sys/dev/aac/: .svn diff -purw sys/dev/aac/aac.c /home/emaste/src/adaptec/aac.c --- sys/dev/aac/aac.c 2009-02-24 05:23:46.000000000 -0500 +++ /home/emaste/src/adaptec/aac.c 2009-02-20 12:19:32.000000000 -0500 @@ -28,13 +28,12 @@ */ #include -__FBSDID("$FreeBSD: head/sys/dev/aac/aac.c 188896 2009-02-21 15:40:03Z attilio $"); +__FBSDID("$FreeBSD: /repoman/r/ncvs/src/sys/dev/aac/aac.c,v 1.120.2.11 2008/04/07 14:19:57 emaste Exp $"); /* * Driver for the Adaptec 'FSA' family of PCI/SCSI RAID adapters. */ -#define AAC_DRIVER_VERSION 0x02000000 -#define AAC_DRIVERNAME "aac" +#define AAC_DRIVERNAME "aacu" #include "opt_aac.h" @@ -64,6 +63,7 @@ __FBSDID("$FreeBSD: head/sys/dev/aac/aac #include #include +#include #include #include @@ -96,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); @@ -230,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, @@ -240,7 +240,7 @@ static struct cdevsw aac_cdevsw = { .d_close = aac_close, .d_ioctl = aac_ioctl, .d_poll = aac_poll, - .d_name = "aac", + .d_name = "aacu", }; MALLOC_DEFINE(M_AACBUF, "aacbuf", "Buffers for the AAC driver"); @@ -259,6 +259,7 @@ int aac_attach(struct aac_softc *sc) { int error, unit; + struct timeval tv; fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, ""); @@ -293,14 +294,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); @@ -311,11 +318,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; @@ -337,7 +339,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"); @@ -353,34 +355,13 @@ aac_attach(struct aac_softc *sc) aac_get_bus_info(sc); } - mtx_lock(&sc->aac_io_lock); - callout_reset(&sc->aac_daemontime, 30 * 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) { @@ -398,6 +379,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 */ @@ -489,7 +492,7 @@ aac_add_container(struct aac_softc *sc, mir->MntTable[0].FileSystemName, mir->MntTable[0].Capacity, mir->MntTable[0].VolType); - if ((child = device_add_child(sc->aac_dev, "aacd", -1)) == NULL) + if ((child = device_add_child(sc->aac_dev, "aacdu", -1)) == NULL) device_printf(sc->aac_dev, "device_add_child failed\n"); else device_set_ivars(child, co); @@ -686,7 +689,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) { @@ -969,6 +972,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. @@ -1117,7 +1122,7 @@ aac_command_thread(struct aac_softc *sc) mtx_unlock(&sc->aac_io_lock); wakeup(sc->aac_dev); - kproc_exit(0); + kthread_exit(0); } /* @@ -1215,7 +1220,6 @@ aac_bio_command(struct aac_softc *sc, st cm->cm_complete = aac_bio_complete; cm->cm_private = bp; cm->cm_timestamp = time_uptime; - cm->cm_queue = AAC_ADAP_NORM_CMD_QUEUE; /* build the FIB */ fib = cm->cm_fib; @@ -1328,7 +1332,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 { @@ -1341,7 +1347,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, @@ -1370,7 +1376,6 @@ aac_wait_command(struct aac_command *cm) fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, ""); /* Put the command on the ready queue and get things going */ - cm->cm_queue = AAC_ADAP_NORM_CMD_QUEUE; aac_enqueue_ready(cm); aac_startio(sc); error = msleep(cm, &sc->aac_io_lock, PRIBIO, "aacwait", 0); @@ -1420,6 +1425,8 @@ aac_release_command(struct aac_command * cm->cm_flags = 0; 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; @@ -1620,12 +1627,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) { @@ -1664,7 +1674,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); @@ -1852,6 +1862,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); } @@ -1901,10 +1912,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; @@ -2053,7 +2073,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) @@ -2391,6 +2411,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; @@ -2809,6 +2830,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"); @@ -2863,22 +2902,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_VERSION >> 24, - (AAC_DRIVER_VERSION >> 16) & 0xFF, - AAC_DRIVER_VERSION & 0xFF, - AAC_DRIVER_BUILD); - aac_release_sync_fib(sc); mtx_unlock(&sc->aac_io_lock); } @@ -3039,7 +3062,6 @@ static int 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; @@ -3047,12 +3069,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); @@ -3173,7 +3191,205 @@ out: static int aac_ioctl_send_raw_srb(struct aac_softc *sc, caddr_t arg) { - return (EINVAL); + struct aac_command *cm; + struct aac_fib *fib; + 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; + + 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) { + error = EBUSY; + mtx_unlock(&sc->aac_io_lock); + goto out; + } + event->ev_type = AAC_EVENT_CMFREE; + event->ev_callback = aac_ioctl_event; + event->ev_arg = &cm; + aac_add_event(sc, event); + 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; + 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)) + goto out; + + 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; + } + /* check fibsize */ + if (fibsize == (sizeof(struct aac_srb) + + srbcmd->sg_map.SgCount * sizeof(struct aac_sg_entry))) { + 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))) { +#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; + } + } else { + error = EINVAL; + goto out; + } + user_reply = (char *)arg + fibsize; + if (srbcmd->sg_map.SgCount == 1) + transfer_data = 1; + + if (transfer_data) { + /* + * 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) + cm->cm_flags |= AAC_CMD_DATAOUT; + + 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 = + AAC_FIBSTATE_HOSTOWNED | + AAC_FIBSTATE_INITIALISED | + AAC_FIBSTATE_EMPTY | + AAC_FIBSTATE_FROMHOST | + AAC_FIBSTATE_REXPECTED | + AAC_FIBSTATE_NORM | + AAC_FIBSTATE_ASYNC | + AAC_FIBSTATE_FAST_RESPONSE; + + 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); + while (!(cm->cm_flags & AAC_CMD_COMPLETED)) + msleep(cm, &sc->aac_io_lock, 0, "sndrw2", 0); + mtx_unlock(&sc->aac_io_lock); + + /* 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); + } + + /* status */ + error = copyout(fib->data, user_reply, sizeof(struct aac_srb_response)); + +out: + 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); + } + return(error); } /* @@ -3297,6 +3513,12 @@ aac_handle_aif(struct aac_softc *sc, str break; + case AifEnAddJBOD: + case AifEnDeleteJBOD: + /* re-enumerate JBOD devices */ + aac_cam_rescan_jbod(sc); + break; + default: break; } @@ -3362,10 +3584,16 @@ aac_rev_check(struct aac_softc *sc, cadd * Doctor up the response struct. */ rev_check_resp.possiblyCompatible = 1; - rev_check_resp.adapterSWRevision.external.ul = - sc->aac_revision.external.ul; + rev_check_resp.adapterSWRevision.external.comp.major = + AAC_DRIVER_MAJOR_VERSION; + rev_check_resp.adapterSWRevision.external.comp.minor = + AAC_DRIVER_MINOR_VERSION; + rev_check_resp.adapterSWRevision.external.comp.type = + AAC_DRIVER_TYPE; + rev_check_resp.adapterSWRevision.external.comp.dash = + AAC_DRIVER_BUGFIX_LEVEL; rev_check_resp.adapterSWRevision.buildNumber = - sc->aac_revision.buildNumber; + (u_int32_t)AAC_DRIVER_BUILD; return(copyout((caddr_t)&rev_check_resp, udata, sizeof(struct aac_rev_check_resp))); @@ -3557,6 +3785,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) @@ -3714,7 +3943,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", @@ -3728,6 +3957,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"); @@ -3741,3 +3971,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 sys/dev/aac/aac_cam.c /home/emaste/src/adaptec/aac_cam.c --- sys/dev/aac/aac_cam.c 2008-06-23 10:01:21.000000000 -0400 +++ /home/emaste/src/adaptec/aac_cam.c 2009-02-20 12:19:32.000000000 -0500 @@ -25,7 +25,7 @@ */ #include -__FBSDID("$FreeBSD: head/sys/dev/aac/aac_cam.c 177567 2008-03-24 19:23:33Z emaste $"); +__FBSDID("$FreeBSD: /repoman/r/ncvs/src/sys/dev/aac/aac_cam.c,v 1.28.2.3 2008/03/31 14:32:06 emaste Exp $"); /* * CAM front-end for communicating with non-DASD devices @@ -45,6 +45,7 @@ __FBSDID("$FreeBSD: head/sys/dev/aac/aac #include #include #include +#include #include #include @@ -61,6 +62,7 @@ __FBSDID("$FreeBSD: head/sys/dev/aac/aac #include #include +#include #include struct aac_cam { @@ -90,16 +92,40 @@ 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) +{ + union ccb *ccb; + struct aac_sim *sim; + + /* re-enumerate JBOD devices */ + while ((sim = TAILQ_FIRST(&sc->aac_sim_tqh)) != NULL) { + ccb = xpt_alloc_ccb_nowait(); + if (ccb == NULL) { + device_printf(sc->aac_dev, + "Cannot allocate ccb for bus rescan\n"); + break; + } + if (sim->aac_cam == NULL || sim->aac_cam->path == NULL) { + device_printf(sc->aac_dev, + "Cannot rescan bus (not attached?)\n"); + break; + } + ccb->ccb_h.path = sim->aac_cam->path; + xpt_rescan(ccb); + } +} + static void aac_cam_event(struct aac_softc *sc, struct aac_event *event, void *arg) { @@ -141,6 +167,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 +198,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); @@ -211,7 +239,7 @@ aac_cam_action(struct cam_sim *sim, unio { struct aac_cam *camsc; struct aac_softc *sc; - struct aac_srb32 *srb; + struct aac_srb *srb; struct aac_fib *fib; struct aac_command *cm; @@ -351,7 +379,7 @@ aac_cam_action(struct cam_sim *sim, unio } fib = cm->cm_fib; - srb = (struct aac_srb32 *)&fib->data[0]; + srb = (struct aac_srb *)&fib->data[0]; cm->cm_datalen = 0; switch (ccb->ccb_h.flags & CAM_DIR_MASK) { @@ -402,10 +430,10 @@ aac_cam_action(struct cam_sim *sim, unio if (ccb->ccb_h.flags & CAM_DATA_PHYS) { /* Send a 32bit command */ fib->Header.Command = ScsiPortCommand; - srb->sg_map32.SgCount = 1; - srb->sg_map32.SgEntry[0].SgAddress = + srb->sg_map.SgCount = 1; + srb->sg_map.SgEntry[0].SgAddress = (uint32_t)(uintptr_t)csio->data_ptr; - srb->sg_map32.SgEntry[0].SgByteCount = + srb->sg_map.SgEntry[0].SgByteCount = csio->dxfer_len; } else { /* @@ -414,15 +442,15 @@ aac_cam_action(struct cam_sim *sim, unio */ cm->cm_data = (void *)csio->data_ptr; cm->cm_datalen = csio->dxfer_len; - cm->cm_sgtable = &srb->sg_map32; + cm->cm_sgtable = &srb->sg_map; } } else { /* XXX Need to handle multiple s/g elements */ panic("aac_cam: multiple s/g elements"); } } else { - srb->sg_map32.SgCount = 0; - srb->sg_map32.SgEntry[0].SgByteCount = 0; + srb->sg_map.SgCount = 0; + srb->sg_map.SgEntry[0].SgByteCount = 0; srb->data_len = 0; } @@ -450,7 +478,6 @@ aac_cam_action(struct cam_sim *sim, unio cm->cm_complete = aac_cam_complete; cm->cm_private = ccb; cm->cm_timestamp = time_uptime; - cm->cm_queue = AAC_ADAP_NORM_CMD_QUEUE; fib->Header.XferState = AAC_FIBSTATE_HOSTOWNED | @@ -459,7 +486,7 @@ aac_cam_action(struct cam_sim *sim, unio AAC_FIBSTATE_REXPECTED | AAC_FIBSTATE_NORM; fib->Header.Size = sizeof(struct aac_fib_header) + - sizeof(struct aac_srb32); + sizeof(struct aac_srb); aac_enqueue_ready(cm); aac_startio(cm->cm_sc); @@ -488,7 +515,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 { @@ -533,7 +562,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] = Only in /home/emaste/src/adaptec/: aac_compat.h diff -purw sys/dev/aac/aac_debug.c /home/emaste/src/adaptec/aac_debug.c --- sys/dev/aac/aac_debug.c 2009-02-24 05:23:46.000000000 -0500 +++ /home/emaste/src/adaptec/aac_debug.c 2009-02-20 12:19:33.000000000 -0500 @@ -28,7 +28,7 @@ */ #include -__FBSDID("$FreeBSD: head/sys/dev/aac/aac_debug.c 188896 2009-02-21 15:40:03Z attilio $"); +__FBSDID("$FreeBSD: /repoman/r/ncvs/src/sys/dev/aac/aac_debug.c,v 1.22.2.2 2008/03/31 14:32:06 emaste Exp $"); /* * Debugging support. @@ -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); /* @@ -129,12 +129,11 @@ aac_printstate0(void) { struct aac_softc *sc; - sc = devclass_get_softc(devclass_find("aac"), 0); + sc = devclass_get_softc(devclass_find("aacu"), 0); 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 sys/dev/aac/aac_disk.c /home/emaste/src/adaptec/aac_disk.c --- sys/dev/aac/aac_disk.c 2009-02-14 09:07:13.000000000 -0500 +++ /home/emaste/src/adaptec/aac_disk.c 2009-02-20 12:19:33.000000000 -0500 @@ -28,7 +28,7 @@ */ #include -__FBSDID("$FreeBSD: head/sys/dev/aac/aac_disk.c 177899 2008-04-03 23:29:31Z emaste $"); +__FBSDID("$FreeBSD: /repoman/r/ncvs/src/sys/dev/aac/aac_disk.c,v 1.43.10.2 2008/03/31 19:21:49 emaste Exp $"); #include "opt_aac.h" @@ -51,6 +51,7 @@ __FBSDID("$FreeBSD: head/sys/dev/aac/aac #include #include +#include #include /* @@ -78,14 +79,14 @@ static device_method_t aac_disk_methods[ }; static driver_t aac_disk_driver = { - "aacd", + "aacdu", aac_disk_methods, sizeof(struct aac_disk) }; #define AAC_MAXIO 65536 -DRIVER_MODULE(aacd, aac, aac_disk_driver, aac_disk_devclass, 0, 0); +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 */ @@ -104,25 +105,59 @@ SYSCTL_UINT(_hw_aac, OID_AUTO, iosize_ma 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); } @@ -132,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; + + /* 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); + } - sc->ad_flags &= ~AAC_DISK_OPEN; + scd->ad_flags &= ~AAC_DISK_OPEN; return (0); } @@ -183,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) @@ -209,31 +281,6 @@ 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 AAC_MAXIO of data. @@ -244,13 +291,12 @@ aac_disk_dump(void *arg, void *virtual, struct aac_disk *ad; struct aac_softc *sc; struct aac_fib *fib; + 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; @@ -270,33 +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) { len = (length > AAC_MAXIO) ? AAC_MAXIO : length; - if ((sc->flags & AAC_FLAGS_SG_64BIT) == 0) { - struct aac_blockwrite *bw; - bw = (struct aac_blockwrite *)&fib->data[0]; 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 @@ -305,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); @@ -407,7 +435,7 @@ 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_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; Only in /home/emaste/src/adaptec/: aac_fwdb.c Only in /home/emaste/src/adaptec/: aac_fwdb.h Only in sys/dev/aac/: aac_fwstatus.diff Only in sys/dev/aac/: aac_fwstatus_new_comm.diff Only in /home/emaste/src/adaptec/: aac_ioctl.h diff -purw sys/dev/aac/aac_linux.c /home/emaste/src/adaptec/aac_linux.c --- sys/dev/aac/aac_linux.c 2008-06-23 10:01:21.000000000 -0400 +++ /home/emaste/src/adaptec/aac_linux.c 2009-02-20 12:19:33.000000000 -0500 @@ -25,7 +25,7 @@ */ #include -__FBSDID("$FreeBSD: head/sys/dev/aac/aac_linux.c 165393 2006-12-20 17:10:53Z delphij $"); +__FBSDID("$FreeBSD: /repoman/r/ncvs/src/sys/dev/aac/aac_linux.c,v 1.4 2006/12/20 17:10:53 delphij Exp $"); /* * Linux ioctl handler for the aac device driver diff -purw sys/dev/aac/aac_pci.c /home/emaste/src/adaptec/aac_pci.c --- sys/dev/aac/aac_pci.c 2009-02-24 05:23:46.000000000 -0500 +++ /home/emaste/src/adaptec/aac_pci.c 2009-02-20 12:19:34.000000000 -0500 @@ -28,7 +28,7 @@ */ #include -__FBSDID("$FreeBSD: head/sys/dev/aac/aac_pci.c 188896 2009-02-21 15:40:03Z attilio $"); +__FBSDID("$FreeBSD: /repoman/r/ncvs/src/sys/dev/aac/aac_pci.c,v 1.62.2.4 2008/03/31 14:32:06 emaste Exp $"); /* * PCI bus interface and resource allocation. @@ -55,6 +55,7 @@ __FBSDID("$FreeBSD: head/sys/dev/aac/aac #include #include +#include #include static int aac_pci_probe(device_t dev); @@ -74,14 +75,14 @@ static device_method_t aac_methods[] = { }; static driver_t aac_pci_driver = { - "aac", + "aacu", aac_methods, sizeof(struct aac_softc) }; static devclass_t aac_devclass; -DRIVER_MODULE(aac, pci, aac_pci_driver, aac_devclass, 0, 0); +DRIVER_MODULE(aacu, pci, aac_pci_driver, aac_devclass, 0, 0); MODULE_DEPEND(aac, pci, 1, 1, 1); @@ -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, @@ -244,14 +245,6 @@ struct aac_ident "Adaptec RAID 52445"}, {0x9005, 0x0285, 0x9005, 0x02d1, AAC_HWIF_I960RX, 0, "Adaptec RAID 5405"}, - {0x9005, 0x0285, 0x9005, 0x02d4, AAC_HWIF_I960RX, 0, - "Adaptec RAID 2045"}, - {0x9005, 0x0285, 0x9005, 0x02d5, AAC_HWIF_I960RX, 0, - "Adaptec RAID 2405"}, - {0x9005, 0x0285, 0x9005, 0x02d6, AAC_HWIF_I960RX, 0, - "Adaptec RAID 2445"}, - {0x9005, 0x0285, 0x9005, 0x02d7, AAC_HWIF_I960RX, 0, - "Adaptec RAID 2805"}, {0x9005, 0x0286, 0x1014, 0x9580, AAC_HWIF_RKT, 0, "IBM ServeRAID-8k"}, {0x9005, 0x0285, 0x1014, 0x034d, AAC_HWIF_I960RX, 0, @@ -325,7 +318,7 @@ aac_pci_probe(device_t dev) if ((id = aac_find_ident(dev)) != NULL) { device_set_desc(dev, id->desc); - return(BUS_PROBE_DEFAULT); + return(BUS_PROBE_SPECIFIC); } return(ENXIO); } @@ -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_FALCON: + fwprintf(sc, HBA_FLAGS_DBG_INIT_B, "set hardware up for Falcon/PPC"); + sc->aac_if = aac_fa_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,37 +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_FALCON: - fwprintf(sc, HBA_FLAGS_DBG_INIT_B, "set hardware up for Falcon/PPC"); - sc->aac_if = aac_fa_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; @@ -486,13 +488,13 @@ struct aacch_softc { }; static driver_t aacch_driver = { - "aacch", + "aacchu", aacch_methods, sizeof(struct aacch_softc) }; 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 sys/dev/aac/aac_tables.h /home/emaste/src/adaptec/aac_tables.h --- sys/dev/aac/aac_tables.h 2008-06-23 10:01:21.000000000 -0400 +++ /home/emaste/src/adaptec/aac_tables.h 2009-02-20 12:19:34.000000000 -0500 @@ -24,7 +24,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $FreeBSD: head/sys/dev/aac/aac_tables.h 151086 2005-10-08 15:55:09Z scottl $ + * $FreeBSD: /repoman/r/ncvs/src/sys/dev/aac/aac_tables.h,v 1.6 2005/10/08 15:55:09 scottl Exp $ */ /* @@ -57,6 +57,7 @@ static struct aac_code_lookup aac_comman {"quota exceeded", 69}, {"stale file handle", 70}, {"too many levels of remote in path", 71}, + {"device busy (spinning up)", 72}, {"bad file handle", 10001}, {"not sync", 10002}, {"bad cookie", 10003}, @@ -68,6 +69,7 @@ static struct aac_code_lookup aac_comman {"not mounted", 10009}, {"in maintenance mode", 10010}, {"stale ACL", 10011}, + {"bus reset - command aborted", 20001}, {NULL, 0}, {"unknown command status", 0} }; diff -purw sys/dev/aac/aacreg.h /home/emaste/src/adaptec/aacreg.h --- sys/dev/aac/aacreg.h 2009-02-24 05:23:46.000000000 -0500 +++ /home/emaste/src/adaptec/aacreg.h 2009-02-20 12:19:35.000000000 -0500 @@ -26,7 +26,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $FreeBSD: head/sys/dev/aac/aacreg.h 188896 2009-02-21 15:40:03Z attilio $ + * $FreeBSD: /repoman/r/ncvs/src/sys/dev/aac/aacreg.h,v 1.23.2.2 2008/03/31 19:21:49 emaste Exp $ */ /* @@ -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 */ @@ -1081,6 +1112,7 @@ typedef enum { ST_DQUOT = 69, ST_STALE = 70, ST_REMOTE = 71, + ST_NOT_READY = 72, ST_BADHANDLE = 10001, ST_NOT_SYNC = 10002, ST_BAD_COOKIE = 10003, @@ -1091,7 +1123,8 @@ typedef enum { ST_JUKEBOX = 10008, ST_NOTMOUNTED = 10009, ST_MAINTMODE = 10010, - ST_STALEACL = 10011 + ST_STALEACL = 10011, + ST_BUS_RESET = 20001 } AAC_FSAStatus; /* @@ -1123,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" */ @@ -1167,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; @@ -1289,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. @@ -1358,12 +1444,12 @@ struct aac_raw_io { struct aac_close_command { u_int32_t Command; u_int32_t ContainerId; -}; +} __packed; /* * SCSI Passthrough structures */ -struct aac_srb32 { +struct aac_srb { u_int32_t function; u_int32_t bus; u_int32_t target; @@ -1374,8 +1460,8 @@ struct aac_srb32 { u_int32_t retry_limit; u_int32_t cdb_len; u_int8_t cdb[16]; - struct aac_sg_table sg_map32; -}; + struct aac_sg_table sg_map; +} __packed; enum { AAC_SRB_FUNC_EXECUTE_SCSI = 0x00, @@ -1416,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, @@ -1528,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 sys/dev/aac/aacvar.h /home/emaste/src/adaptec/aacvar.h --- sys/dev/aac/aacvar.h 2009-02-24 05:23:46.000000000 -0500 +++ /home/emaste/src/adaptec/aacvar.h 2009-02-20 12:19:35.000000000 -0500 @@ -26,19 +26,28 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $FreeBSD: head/sys/dev/aac/aacvar.h 188896 2009-02-21 15:40:03Z attilio $ + * $FreeBSD: /repoman/r/ncvs/src/sys/dev/aac/aacvar.h,v 1.48.2.3 2008/03/31 19:21:49 emaste Exp $ */ #include -#include #include #include #include #include #include +#define AAC_TYPE_DEVO 1 +#define AAC_TYPE_ALPHA 2 +#define AAC_TYPE_BETA 3 +#define AAC_TYPE_RELEASE 4 + +#define AAC_DRIVER_MAJOR_VERSION 2 +#define AAC_DRIVER_MINOR_VERSION 2 +#define AAC_DRIVER_BUGFIX_LEVEL 4 +#define AAC_DRIVER_TYPE AAC_TYPE_RELEASE + #ifndef AAC_DRIVER_BUILD -# define AAC_DRIVER_BUILD 1 +# define AAC_DRIVER_BUILD 16343 #endif /* @@ -46,12 +55,6 @@ */ /* - * The firmware interface allows for a 16-bit s/g list length. We limit - * ourselves to a reasonable maximum and ensure alignment. - */ -#define AAC_MAXSGENTRIES 64 /* max S/G entries, limit 65535 */ - -/* * We allocate a small set of FIBs for the adapter to use to send us messages. */ #define AAC_ADAPTER_FIBS 8 @@ -60,7 +63,7 @@ * FIBs are allocated in page-size chunks and can grow up to the 512 * limit imposed by the hardware. */ -#define AAC_PREALLOCATE_FIBS 128 +#define AAC_PREALLOCATE_FIBS 512 #define AAC_NUM_MGT_FIB 8 /* @@ -110,6 +113,7 @@ struct aac_container /* * Per-SIM data structure */ +struct aac_cam; struct aac_sim { device_t sim_dev; @@ -117,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; }; @@ -171,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 { @@ -312,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; @@ -319,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; @@ -407,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. */ + 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 */ }; /* @@ -460,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); #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); Only in sys/dev/aac/: d Only in sys/dev/aac/: tags