Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 12 Dec 2007 06:33:35 GMT
From:      Kip Macy <kmacy@FreeBSD.org>
To:        Perforce Change Reviews <perforce@freebsd.org>
Subject:   PERFORCE change 130676 for review
Message-ID:  <200712120633.lBC6XZrB029726@repoman.freebsd.org>

next in thread | raw e-mail | index | archive | help
http://perforce.freebsd.org/chv.cgi?CH=130676

Change 130676 by kmacy@kmacy:storage:toehead on 2007/12/12 06:32:45

	IFC 130674

Affected files ...

.. //depot/projects/toehead/sys/dev/amr/amr.c#2 integrate
.. //depot/projects/toehead/sys/dev/amr/amr_cam.c#2 integrate
.. //depot/projects/toehead/sys/dev/amr/amr_pci.c#2 integrate
.. //depot/projects/toehead/sys/dev/amr/amrvar.h#2 integrate
.. //depot/projects/toehead/sys/netinet/tcp_syncache.c#2 integrate

Differences ...

==== //depot/projects/toehead/sys/dev/amr/amr.c#2 (text+ko) ====

@@ -56,7 +56,7 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: src/sys/dev/amr/amr.c,v 1.83 2007/12/02 19:54:45 scottl Exp $");
+__FBSDID("$FreeBSD: src/sys/dev/amr/amr.c,v 1.84 2007/12/12 05:55:03 scottl Exp $");
 
 /*
  * Driver for the AMI MegaRaid family of controllers.
@@ -140,9 +140,9 @@
 static void	amr_unmapcmd(struct amr_command *ac);
 static int	amr_start(struct amr_command *ac);
 static void	amr_complete(void *context, int pending);
-static void	amr_setup_dmamap(void *arg, bus_dma_segment_t *segs, int nsegments, int error);
-static void	amr_setup_dma64map(void *arg, bus_dma_segment_t *segs, int nsegments, int error);
-static void	amr_setup_data_dmamap(void *arg, bus_dma_segment_t *segs, int nsegments, int error);
+static void	amr_setup_sg(void *arg, bus_dma_segment_t *segs, int nsegments, int error);
+static void	amr_setup_data(void *arg, bus_dma_segment_t *segs, int nsegments, int error);
+static void	amr_setup_ccb(void *arg, bus_dma_segment_t *segs, int nsegments, int error);
 
 /*
  * Status monitoring
@@ -572,9 +572,6 @@
 
 	adapter = (ali.ui.fcs.adapno) ^ 'm' << 8;
 
-	ap = malloc(sizeof(struct amr_passthrough),
-	    M_AMR, M_WAITOK | M_ZERO);
-
 	mb = (void *)&ali.mbox[0];
 
 	if ((ali.mbox[0] == FC_DEL_LOGDRV  && ali.mbox[2] == OP_DEL_LOGDRV) ||	/* delete */
@@ -587,6 +584,12 @@
 	}
 
 	if (ali.mbox[0] == AMR_CMD_PASS) {
+	    mtx_lock(&sc->amr_list_lock); 
+	    while ((ac = amr_alloccmd(sc)) == NULL)
+		msleep(sc, &sc->amr_list_lock, PPAUSE, "amrioc", hz);
+	    mtx_unlock(&sc->amr_list_lock);
+	    ap = &ac->ac_ccb->ccb_pthru;
+
 	    error = copyin((void *)(uintptr_t)mb->mb_physaddr, ap,
 		sizeof(struct amr_passthrough));
 	    if (error)
@@ -603,21 +606,16 @@
 		    break;
 	    }
 
-	    mtx_lock(&sc->amr_list_lock); 
-	    while ((ac = amr_alloccmd(sc)) == NULL)
-		msleep(sc, &sc->amr_list_lock, PPAUSE, "amrioc", hz);
-
-	    ac_flags = AMR_CMD_DATAIN|AMR_CMD_DATAOUT|AMR_CMD_CCB_DATAIN|AMR_CMD_CCB_DATAOUT;
+	    ac_flags = AMR_CMD_DATAIN|AMR_CMD_DATAOUT|AMR_CMD_CCB;
 	    bzero(&ac->ac_mailbox, sizeof(ac->ac_mailbox));
 	    ac->ac_mailbox.mb_command = AMR_CMD_PASS;
 	    ac->ac_flags = ac_flags;
 
-	    ac->ac_data = ap;
-	    ac->ac_length = sizeof(struct amr_passthrough);
-	    ac->ac_ccb_data = dp;
-	    ac->ac_ccb_length = ap->ap_data_transfer_length;
+	    ac->ac_data = dp;
+	    ac->ac_length = ap->ap_data_transfer_length;
 	    temp = (void *)(uintptr_t)ap->ap_data_transfer_address;
 
+	    mtx_lock(&sc->amr_list_lock);
 	    error = amr_wait_command(ac);
 	    mtx_unlock(&sc->amr_list_lock);
 	    if (error)
@@ -706,8 +704,6 @@
     mtx_unlock(&sc->amr_list_lock);
     if (dp != NULL)
 	free(dp, M_AMR);
-    if (ap != NULL)
-	free(ap, M_AMR);
     return(error);
 }
 
@@ -729,7 +725,7 @@
     unsigned long		au_length;
     unsigned char		*au_cmd;
     int				*au_statusp, au_direction;
-    int				error, ac_flags = 0;
+    int				error;
     struct amr_passthrough	*ap;	/* 60 bytes */
     int				logical_drives_changed = 0;
 
@@ -832,8 +828,6 @@
     }
 
     /* Allocate this now before the mutex gets held */
-    if (au_cmd[0] == AMR_CMD_PASS)
-	ap = malloc(sizeof(struct amr_passthrough), M_AMR, M_WAITOK|M_ZERO);
 
     mtx_lock(&sc->amr_list_lock); 
     while ((ac = amr_alloccmd(sc)) == NULL)
@@ -843,6 +837,9 @@
     if (au_cmd[0] == AMR_CMD_PASS) {
         int len;
 
+	ap = &ac->ac_ccb->ccb_pthru;
+	bzero(ap, sizeof(struct amr_passthrough));
+
 	/* copy cdb */
         len = au_cmd[2];
 	ap->ap_cdb_length = len;
@@ -860,13 +857,8 @@
 	/* XXX what about the request-sense area? does the caller want it? */
 
 	/* build command */
-	ac->ac_data = ap;
-	ac->ac_length = sizeof(struct amr_passthrough);
-	ac->ac_ccb_data = dp;
-	ac->ac_ccb_length = au_length;
-
 	ac->ac_mailbox.mb_command = AMR_CMD_PASS;
-	ac_flags = AMR_CMD_DATAIN|AMR_CMD_DATAOUT|AMR_CMD_CCB_DATAIN|AMR_CMD_CCB_DATAOUT;
+	ac->ac_flags = AMR_CMD_CCB;
 
     } else {
 	/* direct command to controller */
@@ -878,14 +870,13 @@
 	mbi->mb_param = au_cmd[2];
 	mbi->mb_pad[0] = au_cmd[3];
 	mbi->mb_drive = au_cmd[4];
-
-	/* build the command */
-	ac->ac_data = dp;
-	ac->ac_length = au_length;
-	ac_flags = AMR_CMD_DATAIN|AMR_CMD_DATAOUT;
+	ac->ac_flags = 0;
     }
 
-    ac->ac_flags = ac_flags;
+    /* build the command */
+    ac->ac_data = dp;
+    ac->ac_length = au_length;
+    ac->ac_flags |= AMR_CMD_DATAIN|AMR_CMD_DATAOUT;
 
     /* run the command */
     error = amr_wait_command(ac);
@@ -899,7 +890,7 @@
     }
     debug(2, "copyout %ld bytes from %p -> %p", au_length, dp, au_buffer);
     if (dp != NULL)
-	debug(2, "%jd", (uintptr_t)dp);
+	debug(2, "%p status 0x%x", dp, ac->ac_status);
     *au_statusp = ac->ac_status;
 
 out:
@@ -913,8 +904,6 @@
     mtx_unlock(&sc->amr_list_lock);
     if (dp != NULL)
 	free(dp, M_AMR);
-    if (ap != NULL)
-	free(ap, M_AMR);
 
 #ifndef LSI
     if (logical_drives_changed)
@@ -1420,21 +1409,24 @@
 {
     struct amr_command *ac = arg;
     struct amr_softc *sc = ac->ac_sc;
-    int flags;
+    int mb_channel;
+
+    amr_setup_sg(arg, segs, nsegs, err);
 
-    flags = 0;
-    if (ac->ac_flags & AMR_CMD_DATAIN)
-	flags |= BUS_DMASYNC_PREREAD;
-    if (ac->ac_flags & AMR_CMD_DATAOUT)
-	flags |= BUS_DMASYNC_PREWRITE;
+    /* for AMR_CMD_CONFIG Read/Write the s/g count goes elsewhere */
+    mb_channel = ((struct amr_mailbox_ioctl *)&ac->ac_mailbox)->mb_channel;
+    if (ac->ac_mailbox.mb_command == AMR_CMD_CONFIG &&
+        ((mb_channel == AMR_CONFIG_READ_NVRAM_CONFIG) ||
+        (mb_channel == AMR_CONFIG_WRITE_NVRAM_CONFIG)))
+	((struct amr_mailbox_ioctl *)&ac->ac_mailbox)->mb_param = ac->ac_nsegments;
 
+    ac->ac_mailbox.mb_nsgelem = ac->ac_nsegments;
+    ac->ac_mailbox.mb_physaddr = ac->ac_mb_physaddr;
     if (AC_IS_SG64(ac)) {
-	amr_setup_dma64map(arg, segs, nsegs, err);
-	bus_dmamap_sync(sc->amr_buffer64_dmat,ac->ac_dma64map, flags);
-    } else {
-	amr_setup_dmamap(arg, segs, nsegs, err);
-	bus_dmamap_sync(sc->amr_buffer_dmat,ac->ac_dmamap, flags);
+	ac->ac_sg64_hi = 0;
+	ac->ac_sg64_lo = ac->ac_sgbusaddr;
     }
+
     sc->amr_poll_command1(sc, ac);
 }
 
@@ -1445,8 +1437,6 @@
 static int
 amr_quartz_poll_command(struct amr_command *ac)
 {
-    bus_dma_tag_t	tag;
-    bus_dmamap_t	datamap;
     struct amr_softc	*sc = ac->ac_sc;
     int			error;
 
@@ -1455,17 +1445,17 @@
     error = 0;
 
     if (AC_IS_SG64(ac)) {
-	tag = sc->amr_buffer64_dmat;
-	datamap = ac->ac_dma64map;
+	ac->ac_tag = sc->amr_buffer64_dmat;
+	ac->ac_datamap = ac->ac_dma64map;
     } else {
-	tag = sc->amr_buffer_dmat;
-	datamap = ac->ac_dmamap;
+	ac->ac_tag = sc->amr_buffer_dmat;
+	ac->ac_datamap = ac->ac_dmamap;
     }
 
     /* now we have a slot, we can map the command (unmapped in amr_complete) */
     if (ac->ac_data != 0) {
-	if (bus_dmamap_load(tag, datamap, ac->ac_data, ac->ac_length,
-	    amr_setup_polled_dmamap, ac, BUS_DMA_NOWAIT) != 0) {
+	if (bus_dmamap_load(ac->ac_tag, ac->ac_datamap, ac->ac_data,
+	    ac->ac_length, amr_setup_polled_dmamap, ac, BUS_DMA_NOWAIT) != 0) {
 	    error = 1;
 	}
     } else {
@@ -1494,10 +1484,7 @@
 	    device_printf(sc->amr_dev, "adapter is busy\n");
 	    mtx_unlock(&sc->amr_hw_lock);
 	    if (ac->ac_data != NULL) {
-		if (AC_IS_SG64(ac))
-		    bus_dmamap_unload(sc->amr_buffer64_dmat, ac->ac_dma64map);
-		else
-		    bus_dmamap_unload(sc->amr_buffer_dmat, ac->ac_dmamap);
+		bus_dmamap_unload(ac->ac_tag, ac->ac_datamap);
 	    }
     	    ac->ac_status=0;
 	    return(1);
@@ -1535,17 +1522,12 @@
 
     /* unmap the command's data buffer */
     if (ac->ac_flags & AMR_CMD_DATAIN) {
-	bus_dmamap_sync(sc->amr_buffer_dmat,ac->ac_dmamap,
-	    BUS_DMASYNC_POSTREAD);
+	bus_dmamap_sync(ac->ac_tag, ac->ac_datamap, BUS_DMASYNC_POSTREAD);
     }
     if (ac->ac_flags & AMR_CMD_DATAOUT) {
-	bus_dmamap_sync(sc->amr_buffer_dmat,ac->ac_dmamap,
-	    BUS_DMASYNC_POSTWRITE);
+	bus_dmamap_sync(ac->ac_tag, ac->ac_datamap, BUS_DMASYNC_POSTWRITE);
     }
-    if (AC_IS_SG64(ac))
-	bus_dmamap_unload(sc->amr_buffer64_dmat, ac->ac_dma64map);
-    else
-	bus_dmamap_unload(sc->amr_buffer_dmat, ac->ac_dmamap);
+    bus_dmamap_unload(ac->ac_tag, ac->ac_datamap);
 
     return(error);
 }
@@ -1574,289 +1556,141 @@
  * These functions may be safely called multiple times on a given command.
  */
 static void
-amr_setup_dmamap(void *arg, bus_dma_segment_t *segs, int nsegments, int error)
+amr_setup_sg(void *arg, bus_dma_segment_t *segs, int nsegments, int error)
 {
     struct amr_command	*ac = (struct amr_command *)arg;
     struct amr_sgentry	*sg;
-    int			i;
-    u_int8_t		*sgc;
+    struct amr_sg64entry *sg64;
+    int flags, i;
 
     debug_called(3);
 
-    /* get base address of s/g table */
-    sg = ac->ac_sg.sg32;
-
-    /* save data physical address */
-
-    /* for AMR_CMD_CONFIG Read/Write the s/g count goes elsewhere */
-    if (ac->ac_mailbox.mb_command == AMR_CMD_CONFIG && ( 
-	 ((struct amr_mailbox_ioctl *)&ac->ac_mailbox)->mb_channel == AMR_CONFIG_READ_NVRAM_CONFIG ||
-	 ((struct amr_mailbox_ioctl *)&ac->ac_mailbox)->mb_channel == AMR_CONFIG_WRITE_NVRAM_CONFIG)) {
-	sgc = &(((struct amr_mailbox_ioctl *)&ac->ac_mailbox)->mb_param);
-    } else {
-	sgc = &ac->ac_mailbox.mb_nsgelem;
-    }
+    if (error)
+	printf("amr_setup_sg: error %d\n", error);
 
-    /* decide whether we need to populate the s/g table */
-    if (nsegments < 2) {
-	*sgc = 0;
-	ac->ac_mailbox.mb_nsgelem = 0;
-	ac->ac_mailbox.mb_physaddr = segs[0].ds_addr;
-    } else {
-        ac->ac_mailbox.mb_nsgelem = nsegments;
-	*sgc = nsegments;
-	/* XXX Setting these to 0 might not be needed. */
-	ac->ac_sg64_lo = 0;
-	ac->ac_sg64_hi = 0;
-	ac->ac_mailbox.mb_physaddr = ac->ac_sgbusaddr;
-	for (i = 0; i < nsegments; i++, sg++) {
-	    sg->sg_addr = segs[i].ds_addr;
-	    sg->sg_count = segs[i].ds_len;
-	}
-    }
-
-}
-
-static void
-amr_setup_dma64map(void *arg, bus_dma_segment_t *segs, int nsegments, int error)
-{
-    struct amr_command	*ac = (struct amr_command *)arg;
-    struct amr_sg64entry *sg;
-    int			i;
-    u_int8_t		*sgc;
-
-    debug_called(3);
-
     /* get base address of s/g table */
-    sg = ac->ac_sg.sg64;
-
-    /* save data physical address */
-
-    /* for AMR_CMD_CONFIG Read/Write the s/g count goes elsewhere */
-    if (ac->ac_mailbox.mb_command == AMR_CMD_CONFIG && ( 
-	 ((struct amr_mailbox_ioctl *)&ac->ac_mailbox)->mb_channel == AMR_CONFIG_READ_NVRAM_CONFIG ||
-	 ((struct amr_mailbox_ioctl *)&ac->ac_mailbox)->mb_channel == AMR_CONFIG_WRITE_NVRAM_CONFIG)) {
-	sgc = &(((struct amr_mailbox_ioctl *)&ac->ac_mailbox)->mb_param);
-    } else {
-	sgc = &ac->ac_mailbox.mb_nsgelem;
-    }
-
-    ac->ac_mailbox.mb_nsgelem = nsegments;
-    *sgc = nsegments;
-    ac->ac_sg64_hi = 0;
-    ac->ac_sg64_lo = ac->ac_sgbusaddr;
-    ac->ac_mailbox.mb_physaddr = 0xffffffff;
-    for (i = 0; i < nsegments; i++, sg++) {
-	sg->sg_addr = segs[i].ds_addr;
-	sg->sg_count = segs[i].ds_len;
-    }
-}
-
-static void
-amr_setup_ccbmap(void *arg, bus_dma_segment_t *segs, int nsegments, int error)
-{
-    struct amr_command          *ac = (struct amr_command *)arg;
-    struct amr_softc            *sc = ac->ac_sc;
-    struct amr_sgentry          *sg;
-    struct amr_passthrough      *ap = (struct amr_passthrough *)ac->ac_data;
-    struct amr_ext_passthrough	*aep = (struct amr_ext_passthrough *)ac->ac_data;
-    int                         i;
-
-    /* get base address of s/g table */
     sg = ac->ac_sg.sg32;
+    sg64 = ac->ac_sg.sg64;
 
-    /* decide whether we need to populate the s/g table */
-    if( ac->ac_mailbox.mb_command == AMR_CMD_EXTPASS ) {
-	if (nsegments < 2) {
-	    aep->ap_no_sg_elements = 0;
-	    aep->ap_data_transfer_address =  segs[0].ds_addr;
-	} else {
-	    /* save s/g table information in passthrough */
-	    aep->ap_no_sg_elements = nsegments;
-	    aep->ap_data_transfer_address = ac->ac_sgbusaddr;
-	    /*
-	     * populate s/g table (overwrites previous call which mapped the
-	     * passthrough)
-	     */
-	    for (i = 0; i < nsegments; i++, sg++) {
-		sg->sg_addr = segs[i].ds_addr;
-		sg->sg_count = segs[i].ds_len;
-		debug(3, " %d: 0x%x/%d", i, sg->sg_addr, sg->sg_count);
-	    }
+    if (AC_IS_SG64(ac)) {
+	ac->ac_nsegments = nsegments;
+	ac->ac_mb_physaddr = 0xffffffff;
+	for (i = 0; i < nsegments; i++, sg64++) {
+	    sg64->sg_addr = segs[i].ds_addr;
+	    sg64->sg_count = segs[i].ds_len;
 	}
-	debug(3, "slot %d  %d segments at 0x%x\n", ac->ac_slot,
-	    aep->ap_no_sg_elements, aep->ap_data_transfer_address);
     } else {
+	/* decide whether we need to populate the s/g table */
 	if (nsegments < 2) {
-	    ap->ap_no_sg_elements = 0;
-	    ap->ap_data_transfer_address =  segs[0].ds_addr;
+	    ac->ac_nsegments = 0;
+	    ac->ac_mb_physaddr = segs[0].ds_addr;
 	} else {
-	    /* save s/g table information in passthrough */
-	    ap->ap_no_sg_elements = nsegments;
-	    ap->ap_data_transfer_address = ac->ac_sgbusaddr;
-	    /*
-	     * populate s/g table (overwrites previous call which mapped the
-	     * passthrough)
-	     */
+            ac->ac_nsegments = nsegments;
+	    ac->ac_mb_physaddr = ac->ac_sgbusaddr;
 	    for (i = 0; i < nsegments; i++, sg++) {
 		sg->sg_addr = segs[i].ds_addr;
 		sg->sg_count = segs[i].ds_len;
-		debug(3, " %d: 0x%x/%d", i, sg->sg_addr, sg->sg_count);
 	    }
 	}
-	debug(3, "slot %d  %d segments at 0x%x\n", ac->ac_slot,
-	    ap->ap_no_sg_elements, ap->ap_data_transfer_address);
     }
-    if (ac->ac_flags & AMR_CMD_CCB_DATAIN)
-	bus_dmamap_sync(sc->amr_buffer_dmat, ac->ac_ccb_dmamap,
-	    BUS_DMASYNC_PREREAD);
-    if (ac->ac_flags & AMR_CMD_CCB_DATAOUT)
-	bus_dmamap_sync(sc->amr_buffer_dmat, ac->ac_ccb_dmamap,
-	    BUS_DMASYNC_PREWRITE);
-    if ((ac->ac_flags & (AMR_CMD_CCB_DATAIN | AMR_CMD_CCB_DATAOUT)) == 0)
-	panic("no direction for ccb?\n");
 
+    flags = 0;
     if (ac->ac_flags & AMR_CMD_DATAIN)
-	bus_dmamap_sync(sc->amr_buffer_dmat,ac->ac_dmamap,BUS_DMASYNC_PREREAD);
+	flags |= BUS_DMASYNC_PREREAD;
     if (ac->ac_flags & AMR_CMD_DATAOUT)
-	bus_dmamap_sync(sc->amr_buffer_dmat,ac->ac_dmamap,BUS_DMASYNC_PREWRITE);
-
+	flags |= BUS_DMASYNC_PREWRITE;
+    bus_dmamap_sync(ac->ac_tag, ac->ac_datamap, flags);
     ac->ac_flags |= AMR_CMD_MAPPED;
-
-    if (sc->amr_submit_command(ac) == EBUSY) {
-	amr_freeslot(ac);
-	amr_requeue_ready(ac);
-    }
 }
 
 static void
-amr_setup_ccb64map(void *arg, bus_dma_segment_t *segs, int nsegments, int error)
+amr_setup_data(void *arg, bus_dma_segment_t *segs, int nsegs, int err)
 {
-    struct amr_command          *ac = (struct amr_command *)arg;
-    struct amr_softc            *sc = ac->ac_sc;
-    struct amr_sg64entry        *sg;
-    struct amr_passthrough      *ap = (struct amr_passthrough *)ac->ac_data;
-    struct amr_ext_passthrough	*aep = (struct amr_ext_passthrough *)ac->ac_data;
-    int                         i;
+    struct amr_command *ac = arg;
+    struct amr_softc *sc = ac->ac_sc;
+    int mb_channel;
+
+    amr_setup_sg(arg, segs, nsegs, err);
 
-    /* get base address of s/g table */
-    sg = ac->ac_sg.sg64;
+    /* for AMR_CMD_CONFIG Read/Write the s/g count goes elsewhere */
+    mb_channel = ((struct amr_mailbox_ioctl *)&ac->ac_mailbox)->mb_channel;
+    if (ac->ac_mailbox.mb_command == AMR_CMD_CONFIG &&
+        ((mb_channel == AMR_CONFIG_READ_NVRAM_CONFIG) ||
+        (mb_channel == AMR_CONFIG_WRITE_NVRAM_CONFIG)))
+	((struct amr_mailbox_ioctl *)&ac->ac_mailbox)->mb_param = ac->ac_nsegments;
 
-    /* decide whether we need to populate the s/g table */
-    if( ac->ac_mailbox.mb_command == AMR_CMD_EXTPASS ) {
-	/* save s/g table information in passthrough */
-	aep->ap_no_sg_elements = nsegments;
-	aep->ap_data_transfer_address = ac->ac_sgbusaddr;
-	/*
-	 * populate s/g table (overwrites previous call which mapped the
-	 * passthrough)
-	 */
-	for (i = 0; i < nsegments; i++, sg++) {
-	    sg->sg_addr = segs[i].ds_addr;
-	    sg->sg_count = segs[i].ds_len;
-	    debug(3, " %d: 0x%lx/%d", i, (u_long)sg->sg_addr, sg->sg_count);
-	}
-	debug(3, "slot %d  %d segments at 0x%x\n", ac->ac_slot,
-	    aep->ap_no_sg_elements, aep->ap_data_transfer_address);
-    } else {
-	/* save s/g table information in passthrough */
-	ap->ap_no_sg_elements = nsegments;
-	ap->ap_data_transfer_address = ac->ac_sgbusaddr;
-	/*
-	 * populate s/g table (overwrites previous call which mapped the
-	 * passthrough)
-	 */
-	for (i = 0; i < nsegments; i++, sg++) {
-	    sg->sg_addr = segs[i].ds_addr;
-	    sg->sg_count = segs[i].ds_len;
-	    debug(3, " %d: 0x%lx/%d", i, (u_long)sg->sg_addr, sg->sg_count);
-	}
-	debug(3, "slot %d  %d segments at 0x%x\n", ac->ac_slot,
-	    ap->ap_no_sg_elements, ap->ap_data_transfer_address);
+    ac->ac_mailbox.mb_nsgelem = ac->ac_nsegments;
+    ac->ac_mailbox.mb_physaddr = ac->ac_mb_physaddr;
+    if (AC_IS_SG64(ac)) {
+	ac->ac_sg64_hi = 0;
+	ac->ac_sg64_lo = ac->ac_sgbusaddr;
     }
-    if (ac->ac_flags & AMR_CMD_CCB_DATAIN)
-	bus_dmamap_sync(sc->amr_buffer64_dmat, ac->ac_ccb_dma64map,
-	    BUS_DMASYNC_PREREAD);
-    if (ac->ac_flags & AMR_CMD_CCB_DATAOUT)
-	bus_dmamap_sync(sc->amr_buffer64_dmat, ac->ac_ccb_dma64map,
-	    BUS_DMASYNC_PREWRITE);
-    if ((ac->ac_flags & (AMR_CMD_CCB_DATAIN | AMR_CMD_CCB_DATAOUT)) == 0)
-	panic("no direction for ccb?\n");
 
-    if (ac->ac_flags & AMR_CMD_DATAIN)
-	bus_dmamap_sync(sc->amr_buffer64_dmat, ac->ac_dma64map,
-	    BUS_DMASYNC_PREREAD);
-    if (ac->ac_flags & AMR_CMD_DATAOUT)
-	bus_dmamap_sync(sc->amr_buffer64_dmat, ac->ac_dma64map,
-	    BUS_DMASYNC_PREWRITE);
-
-    ac->ac_flags |= AMR_CMD_MAPPED;
-
     if (sc->amr_submit_command(ac) == EBUSY) {
 	amr_freeslot(ac);
 	amr_requeue_ready(ac);
     }
 }
-
+ 
 static void
-amr_setup_dmamap_cb(void *arg, bus_dma_segment_t *segs, int nsegments,
-    int error)
+amr_setup_ccb(void *arg, bus_dma_segment_t *segs, int nsegs, int err)
 {
-    struct amr_command          *ac = (struct amr_command *)arg;
-    struct amr_softc            *sc = ac->ac_sc;
+    struct amr_command *ac = arg;
+    struct amr_softc *sc = ac->ac_sc;
+    struct amr_passthrough *ap = &ac->ac_ccb->ccb_pthru;
+    struct amr_ext_passthrough *aep = &ac->ac_ccb->ccb_epthru;
+
+    /* Set up the mailbox portion of the command to point at the ccb */
+    ac->ac_mailbox.mb_nsgelem = 0;
+    ac->ac_mailbox.mb_physaddr = ac->ac_ccb_busaddr;
 
-    amr_setup_dmamap(arg, segs, nsegments, error);
+    amr_setup_sg(arg, segs, nsegs, err);
 
-    if (bus_dmamap_load(sc->amr_buffer_dmat, ac->ac_ccb_dmamap,
-	ac->ac_ccb_data, ac->ac_ccb_length, amr_setup_ccbmap, ac,
-	0) == EINPROGRESS) {
-	sc->amr_state |= AMR_STATE_QUEUE_FRZN;
+    switch (ac->ac_mailbox.mb_command) {
+    case AMR_CMD_EXTPASS:
+	aep->ap_no_sg_elements = ac->ac_nsegments;
+	aep->ap_data_transfer_address = ac->ac_mb_physaddr;
+        break;
+    case AMR_CMD_PASS:
+	ap->ap_no_sg_elements = ac->ac_nsegments;
+	ap->ap_data_transfer_address = ac->ac_mb_physaddr;
+	break;
+    default:
+	panic("Unknown ccb command");
     }
-}
 
-static void
-amr_setup_dma64map_cb(void *arg, bus_dma_segment_t *segs, int nsegments,
-    int error)
-{
-    struct amr_command          *ac = (struct amr_command *)arg;
-    struct amr_softc            *sc = ac->ac_sc;
-
-    amr_setup_dma64map(arg, segs, nsegments, error);
-
-    if (bus_dmamap_load(sc->amr_buffer64_dmat, ac->ac_ccb_dma64map,
-	ac->ac_ccb_data, ac->ac_ccb_length, amr_setup_ccb64map, ac,
-	0) == EINPROGRESS) {
-	sc->amr_state |= AMR_STATE_QUEUE_FRZN;
+    if (sc->amr_submit_command(ac) == EBUSY) {
+	amr_freeslot(ac);
+	amr_requeue_ready(ac);
     }
 }
 
 static int
 amr_mapcmd(struct amr_command *ac)
 {
-    bus_dma_tag_t	tag;
-    bus_dmamap_t	datamap;
     bus_dmamap_callback_t *cb;
     struct amr_softc	*sc = ac->ac_sc;
 
     debug_called(3);
 
     if (AC_IS_SG64(ac)) {
-	tag = sc->amr_buffer64_dmat;
-	datamap = ac->ac_dma64map;
-	cb = amr_setup_dma64map_cb;
+	ac->ac_tag = sc->amr_buffer64_dmat;
+	ac->ac_datamap = ac->ac_dma64map;
     } else {
-	tag = sc->amr_buffer_dmat;
-	datamap = ac->ac_dmamap;
-	cb = amr_setup_dmamap_cb;
+	ac->ac_tag = sc->amr_buffer_dmat;
+	ac->ac_datamap = ac->ac_dmamap;
     }
 
+    if (ac->ac_flags & AMR_CMD_CCB)
+	cb = amr_setup_ccb;
+    else
+	cb = amr_setup_data;
+
     /* if the command involves data at all, and hasn't been mapped */
     if ((ac->ac_flags & AMR_CMD_MAPPED) == 0 && (ac->ac_data != NULL)) {
-	if (ac->ac_ccb_data == NULL)
-	    cb = amr_setup_data_dmamap;
 	/* map the data buffers into bus space and build the s/g list */
-	if (bus_dmamap_load(tag, datamap, ac->ac_data, ac->ac_length,
-	    cb, ac, 0) == EINPROGRESS) {
+	if (bus_dmamap_load(ac->ac_tag, ac->ac_datamap, ac->ac_data,
+	     ac->ac_length, cb, ac, 0) == EINPROGRESS) {
 	    sc->amr_state |= AMR_STATE_QUEUE_FRZN;
 	}
    } else {
@@ -1872,7 +1706,6 @@
 static void
 amr_unmapcmd(struct amr_command *ac)
 {
-    struct amr_softc	*sc = ac->ac_sc;
     int			flag;
 
     debug_called(3);
@@ -1888,63 +1721,14 @@
 	    if (ac->ac_flags & AMR_CMD_DATAOUT)
 		flag |= BUS_DMASYNC_POSTWRITE;
 
-	    if (AC_IS_SG64(ac)) {
-		bus_dmamap_sync(sc->amr_buffer64_dmat, ac->ac_dma64map, flag);
-		bus_dmamap_unload(sc->amr_buffer64_dmat, ac->ac_dma64map);
-	    } else {
-		bus_dmamap_sync(sc->amr_buffer_dmat, ac->ac_dmamap, flag);
-		bus_dmamap_unload(sc->amr_buffer_dmat, ac->ac_dmamap);
-	    }
+	    bus_dmamap_sync(ac->ac_tag, ac->ac_datamap, flag);
+	    bus_dmamap_unload(ac->ac_tag, ac->ac_datamap);
 	}
 
-	if (ac->ac_ccb_data != NULL) {
-
-	    flag = 0;
-	    if (ac->ac_flags & AMR_CMD_CCB_DATAIN)
-		flag |= BUS_DMASYNC_POSTREAD;
-	    if (ac->ac_flags & AMR_CMD_CCB_DATAOUT)
-		flag |= BUS_DMASYNC_POSTWRITE;
-
-	    if (AC_IS_SG64(ac)) {
-		bus_dmamap_sync(sc->amr_buffer64_dmat,ac->ac_ccb_dma64map,flag);
-		bus_dmamap_unload(sc->amr_buffer64_dmat, ac->ac_ccb_dma64map);
-	    } else {
-		bus_dmamap_sync(sc->amr_buffer_dmat, ac->ac_ccb_dmamap, flag);
-		bus_dmamap_unload(sc->amr_buffer_dmat, ac->ac_ccb_dmamap);
-	    }
-	}
 	ac->ac_flags &= ~AMR_CMD_MAPPED;
     }
 }
 
-static void
-amr_setup_data_dmamap(void *arg, bus_dma_segment_t *segs, int nsegs, int err)
-{
-    struct amr_command *ac = arg;
-    struct amr_softc *sc = ac->ac_sc;
-    int flags;
-
-    flags = 0;
-    if (ac->ac_flags & AMR_CMD_DATAIN)
-	flags |= BUS_DMASYNC_PREREAD;
-    if (ac->ac_flags & AMR_CMD_DATAOUT)
-	flags |= BUS_DMASYNC_PREWRITE;
-
-    if (AC_IS_SG64(ac)) {
-	amr_setup_dma64map(arg, segs, nsegs, err);
-	bus_dmamap_sync(sc->amr_buffer64_dmat,ac->ac_dma64map, flags);
-    } else {
-	amr_setup_dmamap(arg, segs, nsegs, err);
-	bus_dmamap_sync(sc->amr_buffer_dmat,ac->ac_dmamap, flags);
-    }
-    ac->ac_flags |= AMR_CMD_MAPPED;
-
-    if (sc->amr_submit_command(ac) == EBUSY) {
-	amr_freeslot(ac);
-	amr_requeue_ready(ac);
-    }
-}
-   
 /********************************************************************************
  * Take a command and give it to the controller, returns 0 if successful, or
  * EBUSY if the command should be retried later.
@@ -2124,8 +1908,9 @@
     ac->ac_flags = 0;
     ac->ac_bio = NULL;
     ac->ac_data = NULL;
-    ac->ac_ccb_data = NULL;
     ac->ac_complete = NULL;
+    ac->ac_tag = NULL;
+    ac->ac_datamap = NULL;
     return(ac);
 }
 
@@ -2177,12 +1962,15 @@
 	        ac->ac_sg.sg32 = sc->amr_sgtable + (ac->ac_slot * AMR_NSEG);
 	    }
 
-	    if (bus_dmamap_create(sc->amr_buffer_dmat, 0, &ac->ac_dmamap) ||
-		bus_dmamap_create(sc->amr_buffer_dmat, 0, &ac->ac_ccb_dmamap) ||
-		(AMR_IS_SG64(sc) &&
-		(bus_dmamap_create(sc->amr_buffer64_dmat, 0,&ac->ac_dma64map) ||
-		bus_dmamap_create(sc->amr_buffer64_dmat, 0, &ac->ac_ccb_dma64map))))
-		    break;
+	    ac->ac_ccb = sc->amr_ccb + ac->ac_slot;
+	    ac->ac_ccb_busaddr = sc->amr_ccb_busaddr +
+		(ac->ac_slot * sizeof(union amr_ccb));
+
+	    if (bus_dmamap_create(sc->amr_buffer_dmat, 0, &ac->ac_dmamap))
+		break;
+	    if (AMR_IS_SG64(sc) &&
+		(bus_dmamap_create(sc->amr_buffer64_dmat, 0,&ac->ac_dma64map)))
+		break;
 	    amr_releasecmd(ac);
 	    if (++nextslot > sc->amr_maxio)
 		break;
@@ -2202,10 +1990,8 @@
 
     for (i = 0; i < AMR_CMD_CLUSTERCOUNT; i++) {
 	bus_dmamap_destroy(sc->amr_buffer_dmat, acc->acc_command[i].ac_dmamap);
-	bus_dmamap_destroy(sc->amr_buffer_dmat, acc->acc_command[i].ac_ccb_dmamap);
 	if (AMR_IS_SG64(sc))
 		bus_dmamap_destroy(sc->amr_buffer64_dmat, acc->acc_command[i].ac_dma64map);
-		bus_dmamap_destroy(sc->amr_buffer64_dmat, acc->acc_command[i].ac_ccb_dma64map);
     }
     free(acc, M_AMR);
 }

==== //depot/projects/toehead/sys/dev/amr/amr_cam.c#2 (text+ko) ====

@@ -55,7 +55,7 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: src/sys/dev/amr/amr_cam.c,v 1.26 2007/12/02 19:54:45 scottl Exp $");
+__FBSDID("$FreeBSD: src/sys/dev/amr/amr_cam.c,v 1.27 2007/12/12 05:55:03 scottl Exp $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -222,16 +222,16 @@
 
 		/* check the CDB length */
 		if (csio->cdb_len > AMR_MAX_EXTCDB_LEN)
-			ccbh->status = CAM_REQ_CMP_ERR;
+			ccbh->status = CAM_REQ_INVALID;
 
 		if ((csio->cdb_len > AMR_MAX_CDB_LEN) &&
 		    (sc->support_ext_cdb == 0))
-			ccbh->status = CAM_REQ_CMP_ERR;
+			ccbh->status = CAM_REQ_INVALID;
 	
 		/* check that the CDB pointer is not to a physical address */
 		if ((ccbh->flags & CAM_CDB_POINTER) &&
 		    (ccbh->flags & CAM_CDB_PHYS))
-			ccbh->status = CAM_REQ_CMP_ERR;
+			ccbh->status = CAM_REQ_INVALID;
 		/*
 		 * if there is data transfer, it must be to/from a virtual
 		 * address
@@ -239,10 +239,10 @@
 		if ((ccbh->flags & CAM_DIR_MASK) != CAM_DIR_NONE) {
 			if (ccbh->flags & CAM_DATA_PHYS)
 				/* we can't map it */
-				ccbh->status = CAM_REQ_CMP_ERR;
+				ccbh->status = CAM_REQ_INVALID;
 			if (ccbh->flags & CAM_SCATTER_VALID)
 				/* we want to do the s/g setup */
-				ccbh->status = CAM_REQ_CMP_ERR;
+				ccbh->status = CAM_REQ_INVALID;
 		}
 	
 		/*
@@ -252,7 +252,7 @@
 		 * devices appear echoed.
 		 */
 		if (csio->ccb_h.target_lun != 0)
-			ccbh->status = CAM_REQ_CMP_ERR;
+			ccbh->status = CAM_DEV_NOT_THERE;
 
 		/* if we're happy with the request, queue it for attention */
 		if (ccbh->status == CAM_REQ_INPROG) {
@@ -405,13 +405,15 @@
 	 * Build a passthrough command.
 	 */
 
+	/* construct command */
+	if ((ac = amr_alloccmd(sc)) == NULL) {
+		error = ENOMEM;
+		goto out;
+	}
+
 	/* construct passthrough */
 	if (sc->support_ext_cdb ) {
-		if ((aep = malloc(sizeof(*aep), M_AMRCAM, M_NOWAIT | M_ZERO))
-		    == NULL) {
-			error = ENOMEM;
-			goto out;
-		}
+		aep = &ac->ac_ccb->ccb_epthru;
 		aep->ap_timeout = 2;
 		aep->ap_ars = 1;
 		aep->ap_request_sense_length = 14;
@@ -437,11 +439,7 @@
 		    aep->ap_scsi_id, aep->ap_logical_drive_no);
 
 	} else {
-		if ((ap = malloc(sizeof(*ap), M_AMRCAM, M_NOWAIT | M_ZERO))
-		    == NULL) {
-			error = ENOMEM;
-			goto out;
-		}
+		ap = &ac->ac_ccb->ccb_pthru;
 		ap->ap_timeout = 0;
 		ap->ap_ars = 1;
 		ap->ap_request_sense_length = 14;
@@ -467,30 +465,20 @@
 		    ap->ap_scsi_id, ap->ap_logical_drive_no);
 	}
 
-	/* construct command */
-	if ((ac = amr_alloccmd(sc)) == NULL) {
-		error = ENOMEM;
-		goto out;
-	}
+	ac->ac_flags |= AMR_CMD_CCB;
 
-	ac->ac_flags |= AMR_CMD_DATAOUT | AMR_CMD_DATAIN;
-
-	ac->ac_ccb_data = csio->data_ptr;
-	ac->ac_ccb_length = csio->dxfer_len;
+	ac->ac_data = csio->data_ptr;
+	ac->ac_length = csio->dxfer_len;
 	if ((csio->ccb_h.flags & CAM_DIR_MASK) == CAM_DIR_IN)
-		ac->ac_flags |= AMR_CMD_CCB_DATAIN;
+		ac->ac_flags |= AMR_CMD_DATAIN;
 	if ((csio->ccb_h.flags & CAM_DIR_MASK) == CAM_DIR_OUT)
-		ac->ac_flags |= AMR_CMD_CCB_DATAOUT;
+		ac->ac_flags |= AMR_CMD_DATAOUT;
 
 	ac->ac_private = csio;
 	ac->ac_complete = amr_cam_complete;
 	if ( sc->support_ext_cdb ) {
-		ac->ac_data = aep;
-		ac->ac_length = sizeof(*aep);
 		ac->ac_mailbox.mb_command = AMR_CMD_EXTPASS;
 	} else {
-		ac->ac_data = ap;
-		ac->ac_length = sizeof(*ap);
 		ac->ac_mailbox.mb_command = AMR_CMD_PASS;
 	}
 
@@ -498,10 +486,6 @@
 	if (error != 0) {
 		if (ac != NULL)
 			amr_releasecmd(ac);
-		if (ap != NULL)
-			free(ap, M_AMRCAM);
-		if (aep != NULL)
-			free(aep, M_AMRCAM);
 		if (csio != NULL)
 			/* put it back and try again later */
 			amr_requeue_ccb(sc, (union ccb *)csio);
@@ -532,19 +516,20 @@
 	struct scsi_inquiry_data	*inq;
 	int				scsi_status, cdb0;
 
-	ap = (struct amr_passthrough *)ac->ac_data;
-	aep = (struct amr_ext_passthrough *)ac->ac_data;
+	ap = &ac->ac_ccb->ccb_pthru;
+	aep = &ac->ac_ccb->ccb_epthru;
 	csio = (struct ccb_scsiio *)ac->ac_private;
 	inq = (struct scsi_inquiry_data *)csio->data_ptr;
 
-	if (ac->ac_length == sizeof(*ap))
+	if (ac->ac_mailbox.mb_command == AMR_CMD_EXTPASS)
+		scsi_status = aep->ap_scsi_status;
+	else
 		scsi_status = ap->ap_scsi_status;
-	else
-		scsi_status = aep->ap_scsi_status;
 	debug(1, "status 0x%x  AP scsi_status 0x%x", ac->ac_status,
 	    scsi_status);
 
-	if (ac->ac_status != AMR_STATUS_SUCCESS) {
+	/* Make sure the status is sane */
+	if ((ac->ac_status != AMR_STATUS_SUCCESS) && (scsi_status == 0)) {
 		csio->ccb_h.status = CAM_REQ_CMP_ERR;
 		goto out;
 	}
@@ -561,10 +546,10 @@
 	/* handle passthrough SCSI status */
 	switch(scsi_status) {
 	case 0:	/* completed OK */
-		if (ac->ac_length == sizeof(*ap))
+		if (ac->ac_mailbox.mb_command == AMR_CMD_EXTPASS)
+			cdb0 = aep->ap_cdb[0];
+		else
 			cdb0 = ap->ap_cdb[0];
-		else
-			cdb0 = aep->ap_cdb[0];
 		if ((cdb0 == INQUIRY) && (SID_TYPE(inq) == T_DIRECT))
 			inq->device = (inq->device & 0xe0) | T_NODEVICE;
 		csio->ccb_h.status = CAM_REQ_CMP;
@@ -573,11 +558,11 @@
 	case 0x02:
 		csio->ccb_h.status = CAM_SCSI_STATUS_ERROR;
 		csio->scsi_status = SCSI_STATUS_CHECK_COND;
-		if (ac->ac_length == sizeof(*ap))
-			bcopy(ap->ap_request_sense_area, &csio->sense_data,
+		if (ac->ac_mailbox.mb_command == AMR_CMD_EXTPASS)
+			bcopy(aep->ap_request_sense_area, &csio->sense_data,
 			    AMR_MAX_REQ_SENSE_LEN);
 		else
-			bcopy(aep->ap_request_sense_area, &csio->sense_data,
+			bcopy(ap->ap_request_sense_area, &csio->sense_data,
 			    AMR_MAX_REQ_SENSE_LEN);
 		csio->sense_len = AMR_MAX_REQ_SENSE_LEN;
 		csio->ccb_h.status |= CAM_AUTOSNS_VALID;
@@ -590,20 +575,20 @@
 	case 0xf0:
 	case 0xf4:
 	default:
-		csio->ccb_h.status = CAM_REQ_CMP_ERR;
+		/*
+		 * Non-zero LUNs are already filtered, so there's no need
+		 * to return CAM_DEV_NOT_THERE.
+		 */
+		csio->ccb_h.status = CAM_SEL_TIMEOUT;
 		break;
 	}
 
 out:
-	if (ac->ac_length == sizeof(*ap))
-		free(ap, M_AMRCAM);
-	else
-		free(aep, M_AMRCAM);
 	if ((csio->ccb_h.flags & CAM_DIR_MASK) != CAM_DIR_NONE)
 		debug(2, "%*D\n", imin(csio->dxfer_len, 16), csio->data_ptr,
 		    " ");
 
-	mtx_unlock(&ac->ac_sc->amr_list_lock);
+	mtx_lock(&ac->ac_sc->amr_list_lock);
 	xpt_done((union ccb *)csio);
 	amr_releasecmd(ac);
 	mtx_unlock(&ac->ac_sc->amr_list_lock);

==== //depot/projects/toehead/sys/dev/amr/amr_pci.c#2 (text+ko) ====

@@ -55,7 +55,7 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: src/sys/dev/amr/amr_pci.c,v 1.39 2007/12/02 18:47:31 scottl Exp $");
+__FBSDID("$FreeBSD: src/sys/dev/amr/amr_pci.c,v 1.40 2007/12/12 05:55:03 scottl Exp $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -86,10 +86,10 @@
 static int              amr_pci_resume(device_t dev);
 static void		amr_pci_intr(void *arg);
 static void		amr_pci_free(struct amr_softc *sc);
-static void		amr_sglist_map_helper(void *arg, bus_dma_segment_t *segs, int nseg, int error);
+static void		amr_sglist_helper(void *arg, bus_dma_segment_t *segs, int nseg, int error);
 static int		amr_sglist_map(struct amr_softc *sc);
-static void		amr_setup_mbox_helper(void *arg, bus_dma_segment_t *segs, int nseg, int error);
 static int		amr_setup_mbox(struct amr_softc *sc);

>>> TRUNCATED FOR MAIL (1000 lines) <<<



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200712120633.lBC6XZrB029726>