PERFORCE change 130676 for review
Kip Macy
kmacy at FreeBSD.org
Tue Dec 11 22:33:36 PST 2007
http://perforce.freebsd.org/chv.cgi?CH=130676
Change 130676 by kmacy at 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) <<<
More information about the p4-projects
mailing list