summaryrefslogtreecommitdiffstats
path: root/sys/dev
diff options
context:
space:
mode:
Diffstat (limited to 'sys/dev')
-rw-r--r--sys/dev/aac/aac.c89
-rw-r--r--sys/dev/aac/aac_debug.c5
-rw-r--r--sys/dev/aac/aac_disk.c9
-rw-r--r--sys/dev/aac/aacreg.h54
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;
};
/*
OpenPOWER on IntegriCloud