diff options
Diffstat (limited to 'sys')
-rw-r--r-- | sys/dev/aac/aac.c | 89 | ||||
-rw-r--r-- | sys/dev/aac/aac_debug.c | 5 | ||||
-rw-r--r-- | sys/dev/aac/aac_disk.c | 9 | ||||
-rw-r--r-- | sys/dev/aac/aacreg.h | 54 |
4 files changed, 90 insertions, 67 deletions
diff --git a/sys/dev/aac/aac.c b/sys/dev/aac/aac.c index 42587dd..046fa19 100644 --- a/sys/dev/aac/aac.c +++ b/sys/dev/aac/aac.c @@ -624,45 +624,43 @@ aac_intr(void *arg) { struct aac_softc *sc; u_int16_t reason; + u_int32_t *resp_queue; debug_called(2); sc = (struct aac_softc *)arg; - reason = AAC_GET_ISTATUS(sc); + /* + * Optimize the common case of adapter response interrupts. + * We must read from the card prior to processing the responses + * to ensure the clear is flushed prior to accessing the queues. + * Reading the queues from local memory might save us a PCI read. + */ + resp_queue = sc->aac_queues->qt_qindex[AAC_HOST_NORM_RESP_QUEUE]; + if (resp_queue[AAC_PRODUCER_INDEX] != resp_queue[AAC_CONSUMER_INDEX]) + reason = AAC_DB_RESPONSE_READY; + else + reason = AAC_GET_ISTATUS(sc); + AAC_CLEAR_ISTATUS(sc, reason); + (void)AAC_GET_ISTATUS(sc); + + /* It's not ok to return here because of races with the previous step */ + if (reason & AAC_DB_RESPONSE_READY) + aac_host_response(sc); /* controller wants to talk to the log */ - if (reason & AAC_DB_PRINTF) { - AAC_CLEAR_ISTATUS(sc, AAC_DB_PRINTF); + if (reason & AAC_DB_PRINTF) aac_print_printf(sc); - } /* controller has a message for us? */ if (reason & AAC_DB_COMMAND_READY) { - AAC_CLEAR_ISTATUS(sc, AAC_DB_COMMAND_READY); /* XXX What happens if the thread is already awake? */ if (sc->aifflags & AAC_AIFFLAGS_RUNNING) { sc->aifflags |= AAC_AIFFLAGS_PENDING; wakeup(sc->aifthread); } } - - /* controller has a response for us? */ - if (reason & AAC_DB_RESPONSE_READY) { - AAC_CLEAR_ISTATUS(sc, AAC_DB_RESPONSE_READY); - aac_host_response(sc); - } - - /* - * spurious interrupts that we don't use - reset the mask and clear the - * interrupts - */ - if (reason & (AAC_DB_COMMAND_NOT_FULL | AAC_DB_RESPONSE_NOT_FULL)) { - AAC_UNMASK_INTERRUPTS(sc); - AAC_CLEAR_ISTATUS(sc, AAC_DB_COMMAND_NOT_FULL | - AAC_DB_RESPONSE_NOT_FULL); - } -}; +} /* * Command Processing @@ -729,7 +727,6 @@ aac_start(struct aac_command *cm) /* save a pointer to the command for speedy reverse-lookup */ cm->cm_fib->Header.SenderData = (u_int32_t)cm; /* XXX 64-bit physical * address issue */ - /* put the FIB on the outbound queue */ error = aac_enqueue_fib(sc, cm->cm_queue, cm); return(error); @@ -928,11 +925,14 @@ aac_bio_command(struct aac_softc *sc, struct aac_command **cmp) /* build the FIB */ fib = cm->cm_fib; fib->Header.XferState = - AAC_FIBSTATE_HOSTOWNED | - AAC_FIBSTATE_INITIALISED | - AAC_FIBSTATE_FROMHOST | - AAC_FIBSTATE_REXPECTED | - AAC_FIBSTATE_NORM; + 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 = ContainerCommand; fib->Header.Size = sizeof(struct aac_fib_header); @@ -1081,7 +1081,8 @@ aac_release_command(struct aac_command *cm) * initialised here for debugging purposes only. */ cm->cm_fib->Header.SenderFibAddress = (u_int32_t)cm->cm_fib; - cm->cm_fib->Header.ReceiverFibAddress = cm->cm_fibphys; + cm->cm_fib->Header.ReceiverFibAddress = (u_int32_t)cm->cm_fibphys; + cm->cm_fib->Header.SenderData = 0; aac_enqueue_free(cm); } @@ -1121,7 +1122,7 @@ aac_alloc_commands(struct aac_softc *sc) bus_dmamap_load(sc->aac_fib_dmat, sc->aac_fibmap, sc->aac_fibs, AAC_FIB_COUNT * sizeof(struct aac_fib), aac_map_command_helper, sc, 0); - + bzero(sc->aac_fibs, AAC_FIB_COUNT * sizeof(struct aac_fib)); /* initialise constant fields in the command structure */ for (i = 0; i < AAC_FIB_COUNT; i++) { cm = &sc->aac_command[i]; @@ -1206,12 +1207,12 @@ aac_map_command(struct aac_command *cm) cm->cm_data, cm->cm_datalen, aac_map_command_sg, cm, 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); + 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; } @@ -1362,10 +1363,11 @@ aac_init(struct aac_softc *sc) */ ip = &sc->aac_common->ac_init; ip->InitStructRevision = AAC_INIT_STRUCT_REVISION; + ip->MiniPortRevision = AAC_INIT_STRUCT_MINIPORT_REVISION; ip->AdapterFibsPhysicalAddress = sc->aac_common_busaddr + offsetof(struct aac_common, ac_fibs); - ip->AdapterFibsVirtualAddress = &sc->aac_common->ac_fibs[0]; + ip->AdapterFibsVirtualAddress = (u_int32_t)&sc->aac_common->ac_fibs[0]; ip->AdapterFibsSize = AAC_ADAPTER_FIBS * sizeof(struct aac_fib); ip->AdapterFibAlign = sizeof(struct aac_fib); @@ -1373,7 +1375,8 @@ aac_init(struct aac_softc *sc) offsetof(struct aac_common, ac_printf); ip->PrintfBufferSize = AAC_PRINTF_BUFSIZE; - ip->HostPhysMemPages = 0; /* not used? */ + /* The adapter assumes that pages are 4K in size */ + ip->HostPhysMemPages = ctob(physmem) / AAC_PAGE_SIZE; ip->HostElapsedSeconds = time_second; /* reset later if invalid */ /* @@ -1398,7 +1401,6 @@ aac_init(struct aac_softc *sc) ip->CommHeaderAddress = sc->aac_common_busaddr + ((u_int32_t)sc->aac_queues - (u_int32_t)sc->aac_common); - bzero(sc->aac_queues, sizeof(struct aac_queue_table)); sc->aac_queues->qt_qindex[AAC_HOST_NORM_CMD_QUEUE][AAC_PRODUCER_INDEX] = AAC_HOST_NORM_CMD_ENTRIES; @@ -1704,6 +1706,15 @@ aac_dequeue_fib(struct aac_softc *sc, int queue, u_int32_t *fib_size, *fib_addr = (struct aac_fib *)(sc->aac_qentries[queue] + ci)->aq_fib_addr; + /* + * Is this a fast response? If it is, update the fib fields in + * local memory so the whole fib doesn't have to be DMA'd back up. + */ + if (*(uintptr_t *)fib_addr & 0x01) { + *(uintptr_t *)fib_addr &= ~0x01; + (*fib_addr)->Header.XferState |= AAC_FIBSTATE_DONEADAP; + *((u_int32_t*)((*fib_addr)->data)) = AAC_ERROR_NORMAL; + } /* update consumer index */ sc->aac_queues->qt_qindex[queue][AAC_CONSUMER_INDEX] = ci + 1; diff --git a/sys/dev/aac/aac_debug.c b/sys/dev/aac/aac_debug.c index 3a71318..36cfa4f 100644 --- a/sys/dev/aac/aac_debug.c +++ b/sys/dev/aac/aac_debug.c @@ -185,6 +185,11 @@ aac_panic(struct aac_softc *sc, char *reason) void aac_print_fib(struct aac_softc *sc, struct aac_fib *fib, const char *caller) { + if (fib == NULL) { + device_printf(sc->aac_dev, + "aac_print_fib called with NULL fib\n"); + return; + } device_printf(sc->aac_dev, "%s: FIB @ %p\n", caller, fib); device_printf(sc->aac_dev, " XferState %b\n", fib->Header.XferState, "\20" diff --git a/sys/dev/aac/aac_disk.c b/sys/dev/aac/aac_disk.c index 68692aa..668778d 100644 --- a/sys/dev/aac/aac_disk.c +++ b/sys/dev/aac/aac_disk.c @@ -135,12 +135,17 @@ aac_disk_open(dev_t dev, int flags, int fmt, d_thread_t *td) sc = (struct aac_disk *)dev->si_drv1; - if (sc == NULL) + if (sc == NULL) { + printf("aac_disk_open: No Softc\n"); return (ENXIO); + } /* check that the controller is up and running */ - if (sc->ad_controller->aac_state & AAC_STATE_SUSPEND) + if (sc->ad_controller->aac_state & AAC_STATE_SUSPEND) { + printf("Controller Suspended controller state = 0x%x\n", + sc->ad_controller->aac_state); return(ENXIO); + } sc->ad_disk.d_sectorsize = AAC_BLOCK_SIZE; sc->ad_disk.d_mediasize = (off_t)sc->ad_size * AAC_BLOCK_SIZE; diff --git a/sys/dev/aac/aacreg.h b/sys/dev/aac/aacreg.h index cf2c13f..75bb21c 100644 --- a/sys/dev/aac/aacreg.h +++ b/sys/dev/aac/aacreg.h @@ -128,8 +128,8 @@ struct aac_queue_table { * our private command structure and don't touch these) */ struct aac_fib_list_entry { - struct fib_list_entry *Flink; - struct fib_list_entry *Blink; + u_int32_t Flink; + u_int32_t Blink; } __packed; /* @@ -269,17 +269,19 @@ typedef enum { */ struct aac_adapter_init { u_int32_t InitStructRevision; -#define AAC_INIT_STRUCT_REVISION 3 +#define AAC_INIT_STRUCT_REVISION 3 u_int32_t MiniPortRevision; +#define AAC_INIT_STRUCT_MINIPORT_REVISION 1 u_int32_t FilesystemRevision; u_int32_t CommHeaderAddress; u_int32_t FastIoCommAreaAddress; u_int32_t AdapterFibsPhysicalAddress; - void *AdapterFibsVirtualAddress; + u_int32_t AdapterFibsVirtualAddress; u_int32_t AdapterFibsSize; u_int32_t AdapterFibAlign; u_int32_t PrintfBufferAddress; u_int32_t PrintfBufferSize; +#define AAC_PAGE_SIZE 4096 u_int32_t HostPhysMemPages; u_int32_t HostElapsedSeconds; } __packed; @@ -969,8 +971,8 @@ struct aac_mntobj { char FileSystemName[16]; struct aac_container_creation CreateInfo; u_int32_t Capacity; - AAC_FSAVolType VolType; - AAC_FType ObjType; + u_int32_t VolType; + u_int32_t ObjType; u_int32_t ContentState; #define FSCS_READONLY 0x0002 /* XXX need more information * than this */ @@ -981,14 +983,14 @@ struct aac_mntobj { } __packed; struct aac_mntinfo { - AAC_VMCommand Command; - AAC_FType MntType; + u_int32_t Command; + u_int32_t MntType; u_int32_t MntCount; } __packed; struct aac_mntinforesp { - AAC_FSAStatus Status; - AAC_FType MntType; + u_int32_t Status; + u_int32_t MntType; u_int32_t MntRespCount; struct aac_mntobj MntTable[1]; } __packed; @@ -1006,13 +1008,13 @@ struct aac_closecommand { */ #define CT_GET_SCSI_METHOD 64 struct aac_ctcfg { - AAC_VMCommand Command; + u_int32_t Command; u_int32_t cmd; u_int32_t param; } __packed; struct aac_ctcfg_resp { - AAC_FSAStatus Status; + u_int32_t Status; u_int32_t resp; u_int32_t param; } __packed; @@ -1036,8 +1038,8 @@ struct aac_getbusinf { } __packed; struct aac_vmioctl { - AAC_VMCommand Command; - AAC_FType ObjType; + u_int32_t Command; + u_int32_t ObjType; u_int32_t MethId; u_int32_t ObjId; u_int32_t IoctlCmd; @@ -1045,8 +1047,8 @@ struct aac_vmioctl { } __packed; struct aac_vmi_businf_resp { - AAC_FSAStatus Status; - AAC_FType ObjType; + u_int32_t Status; + u_int32_t ObjType; u_int32_t MethId; u_int32_t ObjId; u_int32_t IoctlCmd; @@ -1058,8 +1060,8 @@ struct aac_vmi_businf_resp { #define GetDeviceProbeInfo 0x5 struct aac_vmi_devinfo_resp { - AAC_FSAStatus Status; - AAC_FType ObjType; + u_int32_t Status; + u_int32_t ObjType; u_int32_t MethId; u_int32_t ObjId; u_int32_t IoctlCmd; @@ -1125,7 +1127,7 @@ typedef enum { */ struct aac_blockread { - AAC_VMCommand Command; /* not FSACommand! */ + u_int32_t Command; /* not FSACommand! */ u_int32_t ContainerId; u_int32_t BlockNumber; u_int32_t ByteCount; @@ -1133,31 +1135,31 @@ struct aac_blockread { } __packed; struct aac_blockread_response { - AAC_FSAStatus Status; + u_int32_t Status; u_int32_t ByteCount; } __packed; struct aac_blockwrite { - AAC_VMCommand Command; /* not FSACommand! */ + u_int32_t Command; /* not FSACommand! */ u_int32_t ContainerId; u_int32_t BlockNumber; u_int32_t ByteCount; - AAC_CacheLevel Stable; + u_int32_t Stable; struct aac_sg_table SgMap; /* variable size */ } __packed; struct aac_blockwrite_response { - AAC_FSAStatus Status; + u_int32_t Status; u_int32_t ByteCount; - AAC_CommitLevel Committed; + u_int32_t Committed; } __packed; /* * Container shutdown command. */ struct aac_close_command { - AAC_VMCommand Command; - u_int32_t ContainerId; + u_int32_t Command; + u_int32_t ContainerId; }; /* |