diff options
author | Marco Peereboom <marco@cvs.openbsd.org> | 2006-04-07 20:05:32 +0000 |
---|---|---|
committer | Marco Peereboom <marco@cvs.openbsd.org> | 2006-04-07 20:05:32 +0000 |
commit | a9227b0df02e20908f2f6ced9a343c55485dd2f2 (patch) | |
tree | 98fd4a8a07e74bb99ca4bce148671df7a9bb9809 /sys/dev/ic | |
parent | 1bb8732b2d498319e868487d40275578266968df (diff) |
Add memory allocator functions.
Diffstat (limited to 'sys/dev/ic')
-rw-r--r-- | sys/dev/ic/mfi.c | 81 | ||||
-rw-r--r-- | sys/dev/ic/mfivar.h | 20 |
2 files changed, 98 insertions, 3 deletions
diff --git a/sys/dev/ic/mfi.c b/sys/dev/ic/mfi.c index e2aaf69b296..b65143f0db2 100644 --- a/sys/dev/ic/mfi.c +++ b/sys/dev/ic/mfi.c @@ -1,4 +1,4 @@ -/* $OpenBSD: mfi.c,v 1.5 2006/04/07 17:02:15 marco Exp $ */ +/* $OpenBSD: mfi.c,v 1.6 2006/04/07 20:05:31 marco Exp $ */ /* * Copyright (c) 2006 Marco Peereboom <marco@peereboom.us> * @@ -66,7 +66,63 @@ struct scsi_device mfi_dev = { NULL, NULL, NULL, NULL }; -int mfi_transition_firmware(struct mfi_softc *); +struct mfi_mem *mfi_allocmem(struct mfi_softc *, size_t); +void mfi_freemem(struct mfi_softc *, struct mfi_mem *); +int mfi_transition_firmware(struct mfi_softc *); + +struct mfi_mem * +mfi_allocmem(struct mfi_softc *sc, size_t size) +{ + struct mfi_mem *mm; + int nsegs; + + mm = malloc(sizeof(struct mfi_mem), M_DEVBUF, M_NOWAIT); + if (mm == NULL) + return (NULL); + + memset(mm, 0, sizeof(struct mfi_mem)); + mm->am_size = size; + + if (bus_dmamap_create(sc->sc_dmat, size, 1, size, 0, + BUS_DMA_NOWAIT | BUS_DMA_ALLOCNOW, &mm->am_map) != 0) + goto amfree; + + if (bus_dmamem_alloc(sc->sc_dmat, size, PAGE_SIZE, 0, &mm->am_seg, 1, + &nsegs, BUS_DMA_NOWAIT) != 0) + goto destroy; + + if (bus_dmamem_map(sc->sc_dmat, &mm->am_seg, nsegs, size, &mm->am_kva, + BUS_DMA_NOWAIT) != 0) + goto free; + + if (bus_dmamap_load(sc->sc_dmat, mm->am_map, mm->am_kva, size, NULL, + BUS_DMA_NOWAIT) != 0) + goto unmap; + + memset(mm->am_kva, 0, size); + return (mm); + +unmap: + bus_dmamem_unmap(sc->sc_dmat, mm->am_kva, size); +free: + bus_dmamem_free(sc->sc_dmat, &mm->am_seg, 1); +destroy: + bus_dmamap_destroy(sc->sc_dmat, mm->am_map); +amfree: + free(mm, M_DEVBUF); + + return (NULL); +} + +void +mfi_freemem(struct mfi_softc *sc, struct mfi_mem *mm) +{ + bus_dmamap_unload(sc->sc_dmat, mm->am_map); + bus_dmamem_unmap(sc->sc_dmat, mm->am_kva, mm->am_size); + bus_dmamem_free(sc->sc_dmat, &mm->am_seg, 1); + bus_dmamap_destroy(sc->sc_dmat, mm->am_map); + free(mm, M_DEVBUF); +} int mfi_transition_firmware(struct mfi_softc *sc) @@ -143,9 +199,30 @@ mfiminphys(struct buf *bp) int mfi_attach(struct mfi_softc *sc) { + uint32_t status; + if (mfi_transition_firmware(sc)) return (1); + status = bus_space_read_4(sc->sc_iot, sc->sc_ioh, MFI_OMSG0); + /* XXX add barrier */ + sc->sc_max_cmds = status & MFI_STATE_MAXCMD_MASK; + sc->sc_max_sgl = (status & MFI_STATE_MAXSGL_MASK) >> 16; + DNPRINTF(MFI_D_MISC, "%s: max commands: %u, max sgl: %u\n", + DEVNAME(sc), sc->sc_max_cmds, sc->sc_max_sgl); + + /* reply queue memory */ + sc->sc_reply_q = mfi_allocmem(sc, + sizeof(uint32_t) * (sc->sc_max_cmds + 1)); + if (sc->sc_reply_q == NULL) { + printf("%s: unable to allocate reply queue memory\n", + DEVNAME(sc)); + return (1); + } + + /* enable interrupts */ + bus_space_write_4(sc->sc_iot, sc->sc_ioh, MFI_OMSK, 0x01); + return (0); } diff --git a/sys/dev/ic/mfivar.h b/sys/dev/ic/mfivar.h index 15072878660..ed01725ae7c 100644 --- a/sys/dev/ic/mfivar.h +++ b/sys/dev/ic/mfivar.h @@ -1,4 +1,4 @@ -/* $OpenBSD: mfivar.h,v 1.3 2006/04/07 16:28:07 marco Exp $ */ +/* $OpenBSD: mfivar.h,v 1.4 2006/04/07 20:05:31 marco Exp $ */ /* * Copyright (c) 2006 Marco Peereboom <marco@peereboom.us> * @@ -32,6 +32,17 @@ extern uint32_t mfi_debug; #define DNPRINTF(n,x...) #endif +struct mfi_mem { + bus_dmamap_t am_map; + bus_dma_segment_t am_seg; + size_t am_size; + caddr_t am_kva; +}; + +#define MFIMEM_MAP(_am) ((_am)->am_map) +#define MFIMEM_DVA(_am) ((_am)->am_map->dm_segs[0].ds_addr) +#define MFIMEM_KVA(_am) ((void *)(_am)->am_kva) + struct mfi_softc { struct device sc_dev; void *sc_ih; @@ -42,6 +53,13 @@ struct mfi_softc { bus_space_tag_t sc_iot; bus_space_handle_t sc_ioh; bus_dma_tag_t sc_dmat; + + /* firmware determined max and totals */ + uint32_t sc_max_cmds; + uint32_t sc_max_sgl; + + /* reply queue */ + struct mfi_mem *sc_reply_q; }; int mfi_attach(struct mfi_softc *sc); |