Module Name: src Committed By: bouyer Date: Sun Aug 5 14:54:02 UTC 2012
Modified Files: src/sys/dev/ic: mfi.c mfivar.h Log Message: Add some support for 64bit DMA but stick to 32bit DMA for now. >From OpenBSD mfi.c rev 1.119. To generate a diff of this commit: cvs rdiff -u -r1.38 -r1.39 src/sys/dev/ic/mfi.c cvs rdiff -u -r1.15 -r1.16 src/sys/dev/ic/mfivar.h Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/sys/dev/ic/mfi.c diff -u src/sys/dev/ic/mfi.c:1.38 src/sys/dev/ic/mfi.c:1.39 --- src/sys/dev/ic/mfi.c:1.38 Wed Mar 21 14:22:36 2012 +++ src/sys/dev/ic/mfi.c Sun Aug 5 14:54:01 2012 @@ -1,4 +1,4 @@ -/* $NetBSD: mfi.c,v 1.38 2012/03/21 14:22:36 sborrill Exp $ */ +/* $NetBSD: mfi.c,v 1.39 2012/08/05 14:54:01 bouyer Exp $ */ /* $OpenBSD: mfi.c,v 1.66 2006/11/28 23:59:45 dlg Exp $ */ /* * Copyright (c) 2006 Marco Peereboom <ma...@peereboom.us> @@ -17,7 +17,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: mfi.c,v 1.38 2012/03/21 14:22:36 sborrill Exp $"); +__KERNEL_RCSID(0, "$NetBSD: mfi.c,v 1.39 2012/08/05 14:54:01 bouyer Exp $"); #include "bio.h" @@ -735,7 +735,7 @@ mfi_attach(struct mfi_softc *sc, enum mf { struct scsipi_adapter *adapt = &sc->sc_adapt; struct scsipi_channel *chan = &sc->sc_chan; - uint32_t status, frames; + uint32_t status, frames, max_sgl; int i; DNPRINTF(MFI_D_MISC, "%s: mfi_attach\n", DEVNAME(sc)); @@ -764,7 +764,16 @@ mfi_attach(struct mfi_softc *sc, enum mf status = mfi_fw_state(sc); sc->sc_max_cmds = status & MFI_STATE_MAXCMD_MASK; - sc->sc_max_sgl = (status & MFI_STATE_MAXSGL_MASK) >> 16; + max_sgl = (status & MFI_STATE_MAXSGL_MASK) >> 16; + if (sc->sc_64bit_dma) { + sc->sc_max_sgl = min(max_sgl, (128 * 1024) / PAGE_SIZE + 1); + sc->sc_sgl_size = sizeof(struct mfi_sg64); + sc->sc_sgl_flags = MFI_FRAME_SGL64; + } else { + sc->sc_max_sgl = max_sgl; + sc->sc_sgl_size = sizeof(struct mfi_sg32); + sc->sc_sgl_flags = MFI_FRAME_SGL32; + } DNPRINTF(MFI_D_MISC, "%s: max commands: %u, max sgl: %u\n", DEVNAME(sc), sc->sc_max_cmds, sc->sc_max_sgl); @@ -781,9 +790,8 @@ mfi_attach(struct mfi_softc *sc, enum mf BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE); /* frame memory */ - /* we are not doing 64 bit IO so only calculate # of 32 bit frames */ - frames = (sizeof(struct mfi_sg32) * sc->sc_max_sgl + - MFI_FRAME_SIZE - 1) / MFI_FRAME_SIZE + 1; + frames = (sc->sc_sgl_size * sc->sc_max_sgl + MFI_FRAME_SIZE - 1) / + MFI_FRAME_SIZE + 1; sc->sc_frames_size = frames * MFI_FRAME_SIZE; sc->sc_frames = mfi_allocmem(sc, sc->sc_frames_size * sc->sc_max_cmds); if (sc->sc_frames == NULL) { @@ -1307,10 +1315,18 @@ mfi_create_sgl(struct mfi_ccb *ccb, int sgl = ccb->ccb_sgl; sgd = ccb->ccb_dmamap->dm_segs; for (i = 0; i < ccb->ccb_dmamap->dm_nsegs; i++) { - sgl->sg32[i].addr = htole32(sgd[i].ds_addr); - sgl->sg32[i].len = htole32(sgd[i].ds_len); - DNPRINTF(MFI_D_DMA, "%s: addr: %#x len: %#x\n", - DEVNAME(sc), sgl->sg32[i].addr, sgl->sg32[i].len); + if (sc->sc_64bit_dma) { + sgl->sg64[i].addr = htole64(sgd[i].ds_addr); + sgl->sg64[i].len = htole64(sgd[i].ds_len); + DNPRINTF(MFI_D_DMA, "%s: addr: %#" PRIx64 " len: %#" + PRIx64 "\n", + DEVNAME(sc), sgl->sg64[i].addr, sgl->sg64[i].len); + } else { + sgl->sg32[i].addr = htole32(sgd[i].ds_addr); + sgl->sg32[i].len = htole32(sgd[i].ds_len); + DNPRINTF(MFI_D_DMA, "%s: addr: %#x len: %#x\n", + DEVNAME(sc), sgl->sg32[i].addr, sgl->sg32[i].len); + } } if (ccb->ccb_direction == MFI_DATA_IN) { @@ -1323,10 +1339,9 @@ mfi_create_sgl(struct mfi_ccb *ccb, int ccb->ccb_dmamap->dm_mapsize, BUS_DMASYNC_PREWRITE); } + hdr->mfh_flags |= sc->sc_sgl_flags; hdr->mfh_sg_count = ccb->ccb_dmamap->dm_nsegs; - /* for 64 bit io make the sizeof a variable to hold whatever sg size */ - ccb->ccb_frame_size += sizeof(struct mfi_sg32) * - ccb->ccb_dmamap->dm_nsegs; + ccb->ccb_frame_size += sc->sc_sgl_size * ccb->ccb_dmamap->dm_nsegs; ccb->ccb_extra_frames = (ccb->ccb_frame_size - 1) / MFI_FRAME_SIZE; DNPRINTF(MFI_D_DMA, "%s: sg_count: %d frame_size: %d frames_size: %d" Index: src/sys/dev/ic/mfivar.h diff -u src/sys/dev/ic/mfivar.h:1.15 src/sys/dev/ic/mfivar.h:1.16 --- src/sys/dev/ic/mfivar.h:1.15 Wed Mar 21 14:22:36 2012 +++ src/sys/dev/ic/mfivar.h Sun Aug 5 14:54:02 2012 @@ -1,4 +1,4 @@ -/* $NetBSD: mfivar.h,v 1.15 2012/03/21 14:22:36 sborrill Exp $ */ +/* $NetBSD: mfivar.h,v 1.16 2012/08/05 14:54:02 bouyer Exp $ */ /* $OpenBSD: mfivar.h,v 1.28 2006/08/31 18:18:46 marco Exp $ */ /* * Copyright (c) 2006 Marco Peereboom <ma...@peereboom.us> @@ -121,6 +121,7 @@ struct mfi_softc { void *sc_ih; uint32_t sc_flags; + bool sc_64bit_dma; bus_space_tag_t sc_iot; bus_space_handle_t sc_ioh; @@ -138,8 +139,11 @@ struct mfi_softc { /* firmware determined max, totals and other information*/ uint32_t sc_max_cmds; uint32_t sc_max_sgl; + uint32_t sc_sgl_size; uint32_t sc_max_ld; uint32_t sc_ld_cnt; + uint16_t sc_sgl_flags; + uint16_t sc_reserved; /* XXX these struct should be local to mgmt function */ struct mfi_ctrl_info sc_info; struct mfi_ld_list sc_ld_list;