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;

Reply via email to