summaryrefslogtreecommitdiffstats
path: root/sys/dev/amr
diff options
context:
space:
mode:
authorscottl <scottl@FreeBSD.org>2004-12-05 23:48:17 +0000
committerscottl <scottl@FreeBSD.org>2004-12-05 23:48:17 +0000
commit29448bd3e8894f9cdc7c69f422529c405275bd1d (patch)
tree9eea5a1c633325715743c7bf5c0ce5678ab4b4c6 /sys/dev/amr
parent8f9a2ff959fd4e1cf63e13cfd9bb293314873371 (diff)
downloadFreeBSD-src-29448bd3e8894f9cdc7c69f422529c405275bd1d.zip
FreeBSD-src-29448bd3e8894f9cdc7c69f422529c405275bd1d.tar.gz
Fix a number of bugs and significantly alter the command execution path to
properly support bounce buffers and resource shortages. This allows the driver to work properly and reliably with more than 4GB of RAM. Of the three data paths that exist in the driver, (block, CAM, ioctl), the ioctl path has not been well tested with these changes due to difficulty with finding an application that uses it that actually works. Sponsored by: The FreeBSD Foundation and FreeBSD Systems, Inc.
Diffstat (limited to 'sys/dev/amr')
-rw-r--r--sys/dev/amr/amr.c207
-rw-r--r--sys/dev/amr/amr_cam.c6
-rw-r--r--sys/dev/amr/amr_pci.c12
-rw-r--r--sys/dev/amr/amrvar.h2
4 files changed, 168 insertions, 59 deletions
diff --git a/sys/dev/amr/amr.c b/sys/dev/amr/amr.c
index e575143..8762a01 100644
--- a/sys/dev/amr/amr.c
+++ b/sys/dev/amr/amr.c
@@ -123,12 +123,15 @@ static void amr_freecmd_cluster(struct amr_command_cluster *acc);
* Command processing.
*/
static int amr_bio_command(struct amr_softc *sc, struct amr_command **acp);
-static int amr_wait_command(struct amr_command *ac);
+static int amr_wait_command(struct amr_command *ac) __unused;
static int amr_getslot(struct amr_command *ac);
-static void amr_mapcmd(struct amr_command *ac);
+static int amr_mapcmd(struct amr_command *ac);
static void amr_unmapcmd(struct amr_command *ac);
static int amr_start(struct amr_command *ac);
+static int amr_start1(struct amr_softc *sc, 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_data_dmamap(void *arg, bus_dma_segment_t *segs, int nsegments, int error);
/*
* Status monitoring
@@ -141,6 +144,7 @@ static void amr_periodic(void *data);
static int amr_quartz_submit_command(struct amr_softc *sc);
static int amr_quartz_get_work(struct amr_softc *sc, struct amr_mailbox *mbsave);
static int amr_quartz_poll_command(struct amr_command *ac);
+static int amr_quartz_poll_command1(struct amr_softc *sc, struct amr_command *ac);
static int amr_std_submit_command(struct amr_softc *sc);
static int amr_std_get_work(struct amr_softc *sc, struct amr_mailbox *mbsave);
@@ -208,6 +212,7 @@ amr_attach(struct amr_softc *sc)
sc->amr_submit_command = amr_quartz_submit_command;
sc->amr_get_work = amr_quartz_get_work;
sc->amr_poll_command = amr_quartz_poll_command;
+ sc->amr_poll_command1 = amr_quartz_poll_command1;
} else {
sc->amr_submit_command = amr_std_submit_command;
sc->amr_get_work = amr_std_get_work;
@@ -705,9 +710,10 @@ amr_enquiry(struct amr_softc *sc, size_t bufsize, u_int8_t cmd, u_int8_t cmdsub,
if ((ac = amr_alloccmd(sc)) == NULL)
goto out;
/* allocate the response structure */
- if ((result = malloc(bufsize, M_DEVBUF, M_NOWAIT)) == NULL)
+ if ((result = malloc(bufsize, M_DEVBUF, M_ZERO|M_NOWAIT)) == NULL)
goto out;
/* set command flags */
+
ac->ac_flags |= AMR_CMD_PRIORITY | AMR_CMD_DATAIN;
/* point the command at our data */
@@ -818,6 +824,10 @@ amr_startio(struct amr_softc *sc)
/* spin until something prevents us from doing any work */
for (;;) {
+ /* Don't bother to queue commands no bounce buffers are available. */
+ if (sc->amr_state & AMR_STATE_QUEUE_FRZN)
+ break;
+
/* try to get a ready command */
ac = amr_dequeue_ready(sc);
@@ -991,6 +1001,17 @@ amr_std_poll_command(struct amr_command *ac)
return(error);
}
+static void
+amr_setup_polled_dmamap(void *arg, bus_dma_segment_t *segs, int nsegs, int err)
+{
+ struct amr_command *ac = arg;
+ struct amr_softc *sc = ac->ac_sc;
+
+ amr_setup_dmamap(arg, segs, nsegs, err);
+ bus_dmamap_sync(sc->amr_buffer_dmat,ac->ac_dmamap,BUS_DMASYNC_PREREAD);
+ sc->amr_poll_command1(sc, ac);
+}
+
/********************************************************************************
* Take a command, submit it to the controller and busy-wait for it to return.
* Returns nonzero on error. Can be safely called with interrupts enabled.
@@ -999,15 +1020,31 @@ static int
amr_quartz_poll_command(struct amr_command *ac)
{
struct amr_softc *sc = ac->ac_sc;
- int s;
- int error,count;
+ int s, error;
debug_called(2);
+ s = splbio();
+ error = 0;
+
/* now we have a slot, we can map the command (unmapped in amr_complete) */
- amr_mapcmd(ac);
+ if (ac->ac_data != 0) {
+ if (bus_dmamap_load(sc->amr_buffer_dmat, ac->ac_dmamap, ac->ac_data,
+ ac->ac_length, amr_setup_polled_dmamap, ac, BUS_DMA_NOWAIT) != 0) {
+ error = 1;
+ }
+ } else {
+ error = amr_quartz_poll_command1(sc, ac);
+ }
- s = splbio();
+ splx(s);
+ return (error);
+}
+
+static int
+amr_quartz_poll_command1(struct amr_softc *sc, struct amr_command *ac)
+{
+ int count, error;
if ((sc->amr_state & AMR_STATE_CRASHDUMP) == 0) {
count=0;
@@ -1020,8 +1057,8 @@ amr_quartz_poll_command(struct amr_command *ac)
if(sc->amr_busyslots) {
device_printf(sc->amr_dev, "adapter is busy\n");
- splx(s);
- amr_unmapcmd(ac);
+ if (ac->ac_data != NULL)
+ bus_dmamap_unload(sc->amr_buffer_dmat, ac->ac_dmamap);
ac->ac_status=0;
return(1);
}
@@ -1051,10 +1088,9 @@ amr_quartz_poll_command(struct amr_command *ac)
AMR_QPUT_IDB(sc, sc->amr_mailboxphys | AMR_QIDB_ACK);
while(AMR_QGET_IDB(sc) & AMR_QIDB_ACK);
- splx(s);
-
/* unmap the command's data buffer */
- amr_unmapcmd(ac);
+ bus_dmamap_sync(sc->amr_buffer_dmat, ac->ac_dmamap, BUS_DMASYNC_POSTREAD);
+ bus_dmamap_unload(sc->amr_buffer_dmat, ac->ac_dmamap);
return(error);
}
@@ -1137,12 +1173,14 @@ amr_setup_dmamap(void *arg, bus_dma_segment_t *segs, int nsegments, int error)
} else {
ac->ac_mailbox.mb_nsgelem = nsegments;
*sgc = nsegments;
- ac->ac_mailbox.mb_physaddr = sc->amr_sgbusaddr + (ac->ac_slot * AMR_NSEG * sizeof(struct amr_sgentry));
+ ac->ac_mailbox.mb_physaddr = sc->amr_sgbusaddr +
+ (ac->ac_slot * AMR_NSEG * sizeof(struct amr_sgentry));
for (i = 0; i < nsegments; i++, sg++) {
sg->sg_addr = segs[i].ds_addr;
sg->sg_count = segs[i].ds_len;
}
}
+
}
static void
@@ -1166,16 +1204,21 @@ amr_setup_ccbmap(void *arg, bus_dma_segment_t *segs, int nsegments, int error)
} else {
/* save s/g table information in passthrough */
aep->ap_no_sg_elements = nsegments;
- aep->ap_data_transfer_address = sc->amr_sgbusaddr + (ac->ac_slot * AMR_NSEG * sizeof(struct amr_sgentry));
- /* populate s/g table (overwrites previous call which mapped the passthrough) */
+ aep->ap_data_transfer_address = sc->amr_sgbusaddr +
+ (ac->ac_slot * AMR_NSEG * sizeof(struct amr_sgentry));
+ /*
+ * 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);
}
}
- debug(3, "slot %d %d segments at 0x%x, passthrough at 0x%x", ac->ac_slot,
- aep->ap_no_sg_elements, aep->ap_data_transfer_address, ac->ac_dataphys);
+ debug(3, "slot %d %d segments at 0x%x, passthrough at 0x%x\n",
+ ac->ac_slot, aep->ap_no_sg_elements, aep->ap_data_transfer_address,
+ ac->ac_dataphys);
} else {
if (nsegments < 2) {
ap->ap_no_sg_elements = 0;
@@ -1183,20 +1226,42 @@ amr_setup_ccbmap(void *arg, bus_dma_segment_t *segs, int nsegments, int error)
} else {
/* save s/g table information in passthrough */
ap->ap_no_sg_elements = nsegments;
- ap->ap_data_transfer_address = sc->amr_sgbusaddr + (ac->ac_slot * AMR_NSEG * sizeof(struct amr_sgentry));
- /* populate s/g table (overwrites previous call which mapped the passthrough) */
+ ap->ap_data_transfer_address = sc->amr_sgbusaddr +
+ (ac->ac_slot * AMR_NSEG * sizeof(struct amr_sgentry));
+ /*
+ * 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);
}
}
- debug(3, "slot %d %d segments at 0x%x, passthrough at 0x%x", ac->ac_slot,
- ap->ap_no_sg_elements, ap->ap_data_transfer_address, ac->ac_dataphys);
+ debug(3, "slot %d %d segments at 0x%x, passthrough at 0x%x",
+ ac->ac_slot, ap->ap_no_sg_elements, ap->ap_data_transfer_address,
+ ac->ac_dataphys);
}
+ 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");
+
+ if (ac->ac_flags & AMR_CMD_DATAIN)
+ bus_dmamap_sync(sc->amr_buffer_dmat,ac->ac_dmamap,BUS_DMASYNC_PREREAD);
+ if (ac->ac_flags & AMR_CMD_DATAOUT)
+ bus_dmamap_sync(sc->amr_buffer_dmat,ac->ac_dmamap,BUS_DMASYNC_PREWRITE);
+
+ ac->ac_flags |= AMR_CMD_MAPPED;
+
+ amr_start1(sc, ac);
}
-static void
+static int
amr_mapcmd(struct amr_command *ac)
{
struct amr_softc *sc = ac->ac_sc;
@@ -1204,28 +1269,27 @@ amr_mapcmd(struct amr_command *ac)
debug_called(3);
/* if the command involves data at all, and hasn't been mapped */
- if (!(ac->ac_flags & AMR_CMD_MAPPED)) {
-
- if (ac->ac_data != NULL) {
+ if ((ac->ac_flags & AMR_CMD_MAPPED) == 0 && (ac->ac_data != NULL)) {
+ if (ac->ac_ccb_data == NULL) {
/* map the data buffers into bus space and build the s/g list */
- bus_dmamap_load(sc->amr_buffer_dmat, ac->ac_dmamap, ac->ac_data, ac->ac_length,
- amr_setup_dmamap, ac, 0);
- if (ac->ac_flags & AMR_CMD_DATAIN)
- bus_dmamap_sync(sc->amr_buffer_dmat, ac->ac_dmamap, BUS_DMASYNC_PREREAD);
- if (ac->ac_flags & AMR_CMD_DATAOUT)
- bus_dmamap_sync(sc->amr_buffer_dmat, ac->ac_dmamap, BUS_DMASYNC_PREWRITE);
- }
+ if (bus_dmamap_load(sc->amr_buffer_dmat, ac->ac_dmamap, ac->ac_data,
+ ac->ac_length, amr_setup_data_dmamap, ac, 0) == EINPROGRESS) {
+ sc->amr_state |= AMR_STATE_QUEUE_FRZN;
+ }
+ } else {
- if (ac->ac_ccb_data != NULL) {
- bus_dmamap_load(sc->amr_buffer_dmat, ac->ac_ccb_dmamap, ac->ac_ccb_data, ac->ac_ccb_length,
- amr_setup_ccbmap, ac, 0);
- 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 (bus_dmamap_load(sc->amr_buffer_dmat, ac->ac_dmamap, ac->ac_data,
+ ac->ac_length, amr_setup_dmamap, ac, BUS_DMA_NOWAIT) != 0){
+ return (ENOMEM);
+ }
+ 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;
+ }
}
- ac->ac_flags |= AMR_CMD_MAPPED;
}
+ return (0);
}
static void
@@ -1240,23 +1304,47 @@ amr_unmapcmd(struct amr_command *ac)
if (ac->ac_data != NULL) {
if (ac->ac_flags & AMR_CMD_DATAIN)
- bus_dmamap_sync(sc->amr_buffer_dmat, ac->ac_dmamap, BUS_DMASYNC_POSTREAD);
+ bus_dmamap_sync(sc->amr_buffer_dmat, ac->ac_dmamap,
+ 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(sc->amr_buffer_dmat, ac->ac_dmamap,
+ BUS_DMASYNC_POSTWRITE);
bus_dmamap_unload(sc->amr_buffer_dmat, ac->ac_dmamap);
}
if (ac->ac_ccb_data != NULL) {
if (ac->ac_flags & AMR_CMD_CCB_DATAIN)
- bus_dmamap_sync(sc->amr_buffer_dmat, ac->ac_ccb_dmamap, BUS_DMASYNC_POSTREAD);
+ bus_dmamap_sync(sc->amr_buffer_dmat, ac->ac_ccb_dmamap,
+ BUS_DMASYNC_POSTREAD);
if (ac->ac_flags & AMR_CMD_CCB_DATAOUT)
- bus_dmamap_sync(sc->amr_buffer_dmat, ac->ac_ccb_dmamap, BUS_DMASYNC_POSTWRITE);
+ bus_dmamap_sync(sc->amr_buffer_dmat, ac->ac_ccb_dmamap,
+ BUS_DMASYNC_POSTWRITE);
bus_dmamap_unload(sc->amr_buffer_dmat, ac->ac_ccb_dmamap);
+ debug(3, "slot %d %d segments at 0x%x, passthrough at 0x%x\n",
+ ac->ac_slot, aep->ap_no_sg_elements, aep->ap_data_transfer_address,
+ ac->ac_dataphys);
}
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;
+
+ amr_setup_dmamap(arg, segs, nsegs, err);
+
+ if (ac->ac_flags & AMR_CMD_DATAIN)
+ bus_dmamap_sync(sc->amr_buffer_dmat,ac->ac_dmamap,BUS_DMASYNC_PREREAD);
+ if (ac->ac_flags & AMR_CMD_DATAOUT)
+ bus_dmamap_sync(sc->amr_buffer_dmat,ac->ac_dmamap,BUS_DMASYNC_PREWRITE);
+ ac->ac_flags |= AMR_CMD_MAPPED;
+
+ amr_start1(sc, ac);
+}
+
/********************************************************************************
* Take a command and give it to the controller, returns 0 if successful, or
* EBUSY if the command should be retried later.
@@ -1264,20 +1352,37 @@ amr_unmapcmd(struct amr_command *ac)
static int
amr_start(struct amr_command *ac)
{
- struct amr_softc *sc = ac->ac_sc;
- int done, s, i;
+ struct amr_softc *sc;
+ int error = 0;
debug_called(3);
/* mark command as busy so that polling consumer can tell */
+ sc = ac->ac_sc;
ac->ac_flags |= AMR_CMD_BUSY;
/* get a command slot (freed in amr_done) */
if (amr_getslot(ac))
return(EBUSY);
- /* now we have a slot, we can map the command (unmapped in amr_complete) */
- amr_mapcmd(ac);
+ /* Now we have a slot, we can map the command (unmapped in amr_complete). */
+ if ((error = amr_mapcmd(ac)) == ENOMEM) {
+ /*
+ * Memroy resources are short, so free the slot and let this be tried
+ * later.
+ */
+ sc->amr_busycmd[ac->ac_slot] = NULL;
+ sc->amr_busyslots--;
+ }
+
+ return (error);
+}
+
+
+static int
+amr_start1(struct amr_softc *sc, struct amr_command *ac)
+{
+ int done, s, i;
/* mark the new mailbox we are going to copy in as busy */
ac->ac_mailbox.mb_busy = 1;
@@ -1387,8 +1492,9 @@ amr_done(struct amr_softc *sc)
break; /* no work */
}
}
-
+
/* if we've completed any commands, try posting some more */
+ sc->amr_state &= ~AMR_STATE_QUEUE_FRZN;
if (result)
amr_startio(sc);
@@ -1399,7 +1505,7 @@ amr_done(struct amr_softc *sc)
else
#endif
amr_complete(sc, 0);
-
+
return(result);
}
@@ -1443,6 +1549,7 @@ amr_complete(void *context, int pending)
wakeup(sc);
}
}
+ amr_startio(sc);
}
/********************************************************************************
diff --git a/sys/dev/amr/amr_cam.c b/sys/dev/amr/amr_cam.c
index a8c0252..bd4cdb9 100644
--- a/sys/dev/amr/amr_cam.c
+++ b/sys/dev/amr/amr_cam.c
@@ -443,7 +443,7 @@ amr_cam_command(struct amr_softc *sc, struct amr_command **acp)
goto out;
}
- ac->ac_flags |= AMR_CMD_DATAOUT;
+ ac->ac_flags |= AMR_CMD_DATAOUT | AMR_CMD_DATAIN;
ac->ac_ccb_data = csio->data_ptr;
ac->ac_ccb_length = csio->dxfer_len;
@@ -501,7 +501,7 @@ amr_cam_complete(struct amr_command *ac)
/* XXX note that we're ignoring ac->ac_status - good idea? */
- debug(1, "status 0x%x scsi_status 0x%x", ac->ac_status, ap->ap_scsi_status);
+ debug(1, "status 0x%x AP scsi_status 0x%x", ac->ac_status, ap->ap_scsi_status);
/*
* Hide disks from CAM so that they're not picked up and treated as 'normal' disks.
@@ -564,7 +564,7 @@ amr_cam_complete_extcdb(struct amr_command *ac)
/* XXX note that we're ignoring ac->ac_status - good idea? */
- debug(1, "status 0x%x scsi_status 0x%x", ac->ac_status, aep->ap_scsi_status);
+ debug(1, "status 0x%x AEP scsi_status 0x%x", ac->ac_status, aep->ap_scsi_status);
/*
* Hide disks from CAM so that they're not picked up and treated as 'normal' disks.
diff --git a/sys/dev/amr/amr_pci.c b/sys/dev/amr/amr_pci.c
index aa4094b..f4cf4ac 100644
--- a/sys/dev/amr/amr_pci.c
+++ b/sys/dev/amr/amr_pci.c
@@ -253,7 +253,7 @@ amr_pci_attach(device_t dev)
NULL, NULL, /* filter, filterarg */
MAXBSIZE, AMR_NSEG, /* maxsize, nsegments */
BUS_SPACE_MAXSIZE_32BIT, /* maxsegsize */
- BUS_DMA_ALLOCNOW, /* flags */
+ 0, /* flags */
NULL, NULL, /* lockfunc, lockarg */
&sc->amr_parent_dmat)) {
device_printf(dev, "can't allocate parent DMA tag\n");
@@ -265,12 +265,12 @@ amr_pci_attach(device_t dev)
*/
if (bus_dma_tag_create(sc->amr_parent_dmat, /* parent */
1, 0, /* alignment, boundary */
- BUS_SPACE_MAXADDR, /* lowaddr */
+ BUS_SPACE_MAXADDR_32BIT, /* lowaddr */
BUS_SPACE_MAXADDR, /* highaddr */
NULL, NULL, /* filter, filterarg */
MAXBSIZE, AMR_NSEG, /* maxsize, nsegments */
- BUS_SPACE_MAXSIZE_32BIT, /* maxsegsize */
- 0, /* flags */
+ MAXBSIZE, /* maxsegsize */
+ BUS_DMA_ALLOCNOW, /* flags */
busdma_lock_mutex, &Giant, /* lockfunc, lockarg */
&sc->amr_buffer_dmat)) {
device_printf(sc->amr_dev, "can't allocate buffer DMA tag\n");
@@ -506,7 +506,7 @@ amr_sglist_map(struct amr_softc *sc)
segsize = sizeof(struct amr_sgentry) * AMR_NSEG * AMR_MAXCMD;
error = bus_dma_tag_create(sc->amr_parent_dmat, /* parent */
1, 0, /* alignment, boundary */
- BUS_SPACE_MAXADDR, /* lowaddr */
+ BUS_SPACE_MAXADDR_32BIT, /* lowaddr */
BUS_SPACE_MAXADDR, /* highaddr */
NULL, NULL, /* filter, filterarg */
segsize, 1, /* maxsize, nsegments */
@@ -578,7 +578,7 @@ amr_setup_mbox(struct amr_softc *sc)
*/
error = bus_dma_tag_create(sc->amr_parent_dmat, /* parent */
16, 0, /* alignment, boundary */
- BUS_SPACE_MAXADDR, /* lowaddr */
+ BUS_SPACE_MAXADDR_32BIT, /* lowaddr */
BUS_SPACE_MAXADDR, /* highaddr */
NULL, NULL, /* filter, filterarg */
sizeof(struct amr_mailbox) + 16, 1, /* maxsize, nsegments */
diff --git a/sys/dev/amr/amrvar.h b/sys/dev/amr/amrvar.h
index 224ae44..ee0a27c 100644
--- a/sys/dev/amr/amrvar.h
+++ b/sys/dev/amr/amrvar.h
@@ -188,6 +188,7 @@ struct amr_softc
#define AMR_STATE_INTEN (1<<2)
#define AMR_STATE_SHUTDOWN (1<<3)
#define AMR_STATE_CRASHDUMP (1<<4)
+#define AMR_STATE_QUEUE_FRZN (1<<5)
/* per-controller queues */
struct bio_queue_head amr_bioq; /* pending I/O with no commands */
@@ -214,6 +215,7 @@ struct amr_softc
int (* amr_submit_command)(struct amr_softc *sc);
int (* amr_get_work)(struct amr_softc *sc, struct amr_mailbox *mbsave);
int (*amr_poll_command)(struct amr_command *ac);
+ int (*amr_poll_command1)(struct amr_softc *sc, struct amr_command *ac);
int support_ext_cdb; /* greater than 10 byte cdb support */
/* misc glue */
OpenPOWER on IntegriCloud