summaryrefslogtreecommitdiffstats
path: root/sys/dev/aac
diff options
context:
space:
mode:
authorscottl <scottl@FreeBSD.org>2003-10-17 21:44:06 +0000
committerscottl <scottl@FreeBSD.org>2003-10-17 21:44:06 +0000
commit49356e4d0e1a781d28164a8f6e3e0fc4c249c86b (patch)
tree9b02a5f12a9ca3bbffec2b21ba7a9ba7bfdbfd72 /sys/dev/aac
parent365e4629edf786bcc796bf7f5ca4bd137bd5056f (diff)
downloadFreeBSD-src-49356e4d0e1a781d28164a8f6e3e0fc4c249c86b.zip
FreeBSD-src-49356e4d0e1a781d28164a8f6e3e0fc4c249c86b.tar.gz
Fix a couple of bugs with AIF handling:
- Correct the logic for the AIF array index pointers so that correct slot is always looked at. - Copy the full FIB payload size when copying AIF's, not just the first 64 bytes. Thanks to Mirapoint, Inc, for pointing these problems out and offering a solution.
Diffstat (limited to 'sys/dev/aac')
-rw-r--r--sys/dev/aac/aac.c26
-rw-r--r--sys/dev/aac/aacreg.h7
2 files changed, 19 insertions, 14 deletions
diff --git a/sys/dev/aac/aac.c b/sys/dev/aac/aac.c
index 2abee31..8466bd8 100644
--- a/sys/dev/aac/aac.c
+++ b/sys/dev/aac/aac.c
@@ -241,6 +241,8 @@ aac_attach(struct aac_softc *sc)
AAC_LOCK_INIT(&sc->aac_container_lock, "AAC container lock");
TAILQ_INIT(&sc->aac_container_tqh);
+ /* Initialize the local AIF queue pointers */
+ sc->aac_aifq_head = sc->aac_aifq_tail = AAC_AIFQ_LENGTH;
/*
* Initialise the adapter.
@@ -2803,23 +2805,25 @@ aac_getnext_aif(struct aac_softc *sc, caddr_t arg)
static int
aac_return_aif(struct aac_softc *sc, caddr_t uptr)
{
- int error;
+ int next, error;
debug_called(2);
AAC_LOCK_ACQUIRE(&sc->aac_aifq_lock);
if (sc->aac_aifq_tail == sc->aac_aifq_head) {
- error = EAGAIN;
- } else {
- error = copyout(&sc->aac_aifq[sc->aac_aifq_tail], uptr,
- sizeof(struct aac_aif_command));
- if (error)
- device_printf(sc->aac_dev,
- "aac_return_aif: copyout returned %d\n", error);
- if (!error)
- sc->aac_aifq_tail = (sc->aac_aifq_tail + 1) %
- AAC_AIFQ_LENGTH;
+ AAC_LOCK_RELEASE(&sc->aac_aifq_lock);
+ return (EAGAIN);
}
+
+ next = (sc->aac_aifq_tail + 1) % AAC_AIFQ_LENGTH;
+ error = copyout(&sc->aac_aifq[next], uptr,
+ sizeof(struct aac_aif_command));
+ if (error)
+ device_printf(sc->aac_dev,
+ "aac_return_aif: copyout returned %d\n", error);
+ else
+ sc->aac_aifq_tail = next;
+
AAC_LOCK_RELEASE(&sc->aac_aifq_lock);
return(error);
}
diff --git a/sys/dev/aac/aacreg.h b/sys/dev/aac/aacreg.h
index dd08437..fe54487 100644
--- a/sys/dev/aac/aacreg.h
+++ b/sys/dev/aac/aacreg.h
@@ -851,9 +851,10 @@ struct aac_aif_command {
u_int32_t seqNumber; /* To allow ordering of
* reports (if necessary) */
union {
- struct aac_AifEventNotify EN; /* Event notify structure */
- struct aac_AifJobProgressReport PR[1]; /* Progress report */
- u_int8_t AR[AAC_AIF_REPORT_MAX_SIZE];
+ struct aac_AifEventNotify EN; /* Event notify */
+ struct aac_AifJobProgressReport PR[1]; /* Progress report */
+ u_int8_t AR[AAC_AIF_REPORT_MAX_SIZE];
+ u_int8_t data[AAC_FIB_DATASIZE - 8];
} data;
} __packed;
OpenPOWER on IntegriCloud