diff options
author | scottl <scottl@FreeBSD.org> | 2003-10-17 21:44:06 +0000 |
---|---|---|
committer | scottl <scottl@FreeBSD.org> | 2003-10-17 21:44:06 +0000 |
commit | 49356e4d0e1a781d28164a8f6e3e0fc4c249c86b (patch) | |
tree | 9b02a5f12a9ca3bbffec2b21ba7a9ba7bfdbfd72 /sys/dev/aac | |
parent | 365e4629edf786bcc796bf7f5ca4bd137bd5056f (diff) | |
download | FreeBSD-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.c | 26 | ||||
-rw-r--r-- | sys/dev/aac/aacreg.h | 7 |
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; |