diff options
author | scottl <scottl@FreeBSD.org> | 2006-03-01 07:24:39 +0000 |
---|---|---|
committer | scottl <scottl@FreeBSD.org> | 2006-03-01 07:24:39 +0000 |
commit | ff94cb013a7f2f8bdadb7fc31f312e71e7323204 (patch) | |
tree | 922e99713620b5f24a90cd23b398a93e1dfddcc2 /sys/dev/iir/iir.h | |
parent | ad462fd146fb56a5c568bc3d2dd116bba4320595 (diff) | |
download | FreeBSD-src-ff94cb013a7f2f8bdadb7fc31f312e71e7323204.zip FreeBSD-src-ff94cb013a7f2f8bdadb7fc31f312e71e7323204.tar.gz |
Big update to the iir driver:
- Don't use a common buffer in the softc to store per-command data. Reserve
a buffer in the command itself.
- Don't allocate DMA memory for the kernel command structures when all you
really need is DMA memory for the scratch buffer embedded in them. Instead
allocate a slab for the scratch buffers and divide it up as needed.
- Call bus_dmamap_unload() at the completion of commands.
- Preserve and clear the CAM CCB status flags at completion.
- Reorder some low-level command operations to try to close races.
- Limit the simq to 32 commands for now. There are some serious problems
with the driver under load that are not well understood, so keeping the
simq lower helps avoid this. It has been tested at a higher value, but
this is a safe value that doesn't show much performance degredation.
These changes allow the driver to work reliably with >4GB of memory on i386
and amd64, and also work around deadlocks seen under very high load in
certain situations. The work-around is far from ideal, but without and
documentation it is hard to know what the right fix is.
MFC candidate
Diffstat (limited to 'sys/dev/iir/iir.h')
-rw-r--r-- | sys/dev/iir/iir.h | 15 |
1 files changed, 8 insertions, 7 deletions
diff --git a/sys/dev/iir/iir.h b/sys/dev/iir/iir.h index e38a9e0..62f429a 100644 --- a/sys/dev/iir/iir.h +++ b/sys/dev/iir/iir.h @@ -612,20 +612,19 @@ struct gdt_softc { bus_addr_t sc_dpmembase; bus_dma_tag_t sc_parent_dmat; bus_dma_tag_t sc_buffer_dmat; - bus_dma_tag_t sc_gccb_dmat; - bus_dmamap_t sc_gccb_dmamap; - bus_addr_t sc_gccb_busbase; + bus_dma_tag_t sc_gcscratch_dmat; + bus_dmamap_t sc_gcscratch_dmamap; + bus_addr_t sc_gcscratch_busbase; struct gdt_ccb *sc_gccbs; + u_int8_t *sc_gcscratch; SLIST_HEAD(, gdt_ccb) sc_free_gccb, sc_pending_gccb; TAILQ_HEAD(, ccb_hdr) sc_ccb_queue; TAILQ_HEAD(, gdt_ucmd) sc_ucmd_queue; u_int16_t sc_ic_all_size; - u_int16_t sc_cmd_len; u_int16_t sc_cmd_off; u_int16_t sc_cmd_cnt; - u_int8_t sc_cmd[GDT_CMD_SZ]; u_int32_t sc_info; u_int32_t sc_info2; @@ -679,13 +678,13 @@ struct gdt_softc { * controller. */ struct gdt_ccb { - u_int8_t gc_scratch[GDT_SCRATCH_SZ]; + u_int8_t *gc_scratch; + bus_addr_t gc_scratch_busbase; union ccb *gc_ccb; gdt_ucmd_t *gc_ucmd; bus_dmamap_t gc_dmamap; int gc_map_flag; int gc_timeout; - int gc_state; u_int8_t gc_service; u_int8_t gc_cmd_index; u_int8_t gc_flags; @@ -694,6 +693,8 @@ struct gdt_ccb { #define GDT_GCF_SCREEN 2 #define GDT_GCF_SCSI 3 #define GDT_GCF_IOCTL 4 + u_int16_t gc_cmd_len; + u_int8_t gc_cmd[GDT_CMD_SZ]; SLIST_ENTRY(gdt_ccb) sle; }; |