summaryrefslogtreecommitdiff
path: root/sys/dev/isa/bt.c
diff options
context:
space:
mode:
authorTheo de Raadt <deraadt@cvs.openbsd.org>1997-01-22 22:47:51 +0000
committerTheo de Raadt <deraadt@cvs.openbsd.org>1997-01-22 22:47:51 +0000
commit970003eed59753e695f06e708c619c27c62e9ec8 (patch)
tree0657820b8d5c5d1698d458bb6fed985fd81e5a76 /sys/dev/isa/bt.c
parent56b59151d5feab8b9ed50371ca2cc13480be265b (diff)
back out bounce buffer fixes until i get them working 100%
Diffstat (limited to 'sys/dev/isa/bt.c')
-rw-r--r--sys/dev/isa/bt.c205
1 files changed, 73 insertions, 132 deletions
diff --git a/sys/dev/isa/bt.c b/sys/dev/isa/bt.c
index 25031d5daf5..2c114315713 100644
--- a/sys/dev/isa/bt.c
+++ b/sys/dev/isa/bt.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: bt.c,v 1.20 1997/01/17 17:15:15 kstailey Exp $ */
+/* $OpenBSD: bt.c,v 1.21 1997/01/22 22:47:50 deraadt Exp $ */
/* $NetBSD: bt.c,v 1.10 1996/05/12 23:51:54 mycroft Exp $ */
#undef BTDIAG
@@ -74,18 +74,6 @@
#define Debugger() panic("should call debugger here (bt742a.c)")
#endif /* ! DDB */
-/* XXX fixme:
- * on i386 at least, xfers to/from user memory
- * cannot be serviced at interrupt time.
- */
-#ifdef i386
-#define VOLATILE_XS(xs) \
- ((xs)->datalen > 0 && (xs)->bp == NULL && \
- ((xs)->flags & SCSI_POLL) == 0)
-#else
-#define VOLATILE_XS(xs) 0
-#endif
-
/*
* Mail box defs etc.
* these could be bigger but we need the bt_softc to fit on a single page..
@@ -128,9 +116,8 @@ struct bt_softc {
int sc_iobase;
int sc_irq, sc_drq;
- char sc_model[7];
- char sc_firmware[6];
- char sc_version[2];
+ char sc_model[7],
+ sc_firmware[6];
struct bt_mbx sc_mbx; /* all our mailboxes */
#define wmbx (&sc->sc_mbx)
@@ -139,7 +126,6 @@ struct bt_softc {
int sc_numccbs, sc_mbofull;
int sc_scsi_dev; /* adapters scsi id */
struct scsi_link sc_link; /* prototype for devs */
- int sc_needbounce;
};
#ifdef BTDEBUG
@@ -477,8 +463,6 @@ AGAIN:
}
untimeout(bt_timeout, ccb);
- isadma_copyfrombuf((caddr_t)ccb, CCB_PHYS_SIZE,
- 1, ccb->ccb_phys);
bt_done(sc, ccb);
next:
@@ -557,9 +541,6 @@ bt_free_ccb(sc, ccb)
s = splbio();
- if (ccb->ccb_phys[0].addr)
- isadma_unmap((caddr_t)ccb, CCB_PHYS_SIZE, 1, ccb->ccb_phys);
-
bt_reset_ccb(sc, ccb);
TAILQ_INSERT_HEAD(&sc->sc_free_ccb, ccb, chain);
@@ -604,17 +585,10 @@ bt_get_ccb(sc, flags)
int flags;
{
struct bt_ccb *ccb;
- int hashnum, mflags, s;
+ int s;
s = splbio();
- if (sc->sc_needbounce) {
- if (flags & SCSI_NOSLEEP)
- mflags = ISADMA_MAP_BOUNCE;
- else
- mflags = ISADMA_MAP_BOUNCE | ISADMA_MAP_WAITOK;
- } else
- mflags = 0;
/*
* If we can and have to, sleep waiting for one to come free
* but only if we can't allocate a new one.
@@ -644,17 +618,6 @@ bt_get_ccb(sc, flags)
ccb->flags |= CCB_ALLOC;
- if (isadma_map((caddr_t)ccb, CCB_PHYS_SIZE, ccb->ccb_phys,
- mflags | ISADMA_MAP_CONTIG) == 1) {
- hashnum = CCB_HASH(ccb->ccb_phys[0].addr);
- ccb->nexthash = sc->sc_ccbhash[hashnum];
- sc->sc_ccbhash[hashnum] = ccb;
- } else {
- ccb->ccb_phys[0].addr = 0;
- bt_free_ccb(sc, ccb);
- ccb = 0;
- }
-
out:
splx(s);
return ccb;
@@ -754,9 +717,7 @@ bt_start_ccbs(sc)
#endif
/* Link ccb to mbo. */
- isadma_copytobuf((caddr_t)ccb, CCB_PHYS_SIZE,
- 1, ccb->ccb_phys);
- ltophys(ccb->ccb_phys[0].addr, wmbo->ccb_addr);
+ ltophys(KVTOPHYS(ccb), wmbo->ccb_addr);
if (ccb->flags & CCB_ABORT)
wmbo->cmd = BT_MBO_ABORT;
else
@@ -837,21 +798,8 @@ bt_done(sc, ccb)
} else
xs->resid = 0;
}
- xs->flags |= ITSDONE;
-
- if (VOLATILE_XS(xs)) {
- wakeup(ccb);
- return;
- }
-
- if (ccb->data_nseg) {
- if (xs->flags & SCSI_DATA_IN)
- isadma_copyfrombuf(xs->data, xs->datalen,
- ccb->data_nseg, ccb->data_phys);
- isadma_unmap(xs->data, xs->datalen,
- ccb->data_nseg, ccb->data_phys);
- }
bt_free_ccb(sc, ccb);
+ xs->flags |= ITSDONE;
scsi_done(xs);
}
@@ -906,8 +854,6 @@ bt_find(ia, sc)
sizeof(inquire.reply), (u_char *)&inquire.reply);
switch (inquire.reply.bus_type) {
case BT_BUS_TYPE_24BIT:
- sc->sc_needbounce = 1;
- break;
case BT_BUS_TYPE_32BIT:
break;
case BT_BUS_TYPE_MCA:
@@ -1020,7 +966,6 @@ bt_init(sc)
struct bt_setup setup;
struct bt_mailbox mailbox;
struct bt_period period;
- struct isadma_seg mbx_phys[1];
int i;
/* Enable round-robin scheme - appeared at firmware rev. 3.31. */
@@ -1082,18 +1027,9 @@ bt_init(sc)
/* Initialize mail box. */
mailbox.cmd.opcode = BT_MBX_INIT_EXTENDED;
mailbox.cmd.nmbx = BT_MBX_SIZE;
- if (isadma_map((caddr_t)(wmbx), sizeof(struct bt_mbx),
- mbx_phys, ISADMA_MAP_CONTIG) != 1)
- panic("bt_init: cannot map mail box");
- ltophys(mbx_phys[0].addr, mailbox.cmd.addr);
+ ltophys(KVTOPHYS(wmbx), mailbox.cmd.addr);
bt_cmd(iobase, sc, sizeof(mailbox.cmd), (u_char *)&mailbox.cmd,
0, (u_char *)0);
-
- /* deal with buggy boards */
- if ((sc->sc_model[0] == '4' && sc->sc_model[1] == '4' &&
- sc->sc_model[2] == '5' && sc->sc_model[3] == 'S') ||
- sc->sc_version[0] == '5')
- sc->sc_needbounce = 1;
}
void
@@ -1151,8 +1087,6 @@ bt_inquire_setup_information(sc)
while (p > sc->sc_model && (p[-1] == ' ' || p[-1] == '\0'))
p--;
*p = '\0';
- bcopy(model.reply.version, sc->sc_version,
- sizeof sc->sc_version);
} else
strcpy(sc->sc_model, "542B");
@@ -1182,7 +1116,8 @@ bt_scsi_cmd(xs)
struct bt_ccb *ccb;
struct bt_scat_gath *sg;
int seg; /* scatter gather seg being worked on */
- int flags, mflags;
+ u_long thiskv, thisphys, nextphys;
+ int bytes_this_seg, bytes_this_page, datalen, flags;
#ifdef TFS
struct iovec *iovp;
#endif
@@ -1195,13 +1130,6 @@ bt_scsi_cmd(xs)
* then we can't allow it to sleep
*/
flags = xs->flags;
- if (sc->sc_needbounce) {
- if (flags & SCSI_NOSLEEP)
- mflags = ISADMA_MAP_BOUNCE;
- else
- mflags = ISADMA_MAP_BOUNCE | ISADMA_MAP_WAITOK;
- } else
- mflags = 0;
if ((ccb = bt_get_ccb(sc, flags)) == NULL) {
xs->error = XS_DRIVER_STUFFUP;
return TRY_AGAIN_LATER;
@@ -1244,32 +1172,69 @@ bt_scsi_cmd(xs)
}
} else
#endif /* TFS */
- /*
- * Set up the scatter-gather block.
- */
- SC_DEBUG(sc_link, SDEV_DB4,
- ("%d @0x%x:- ", xs->datalen, xs->data));
-
- ccb->data_nseg = isadma_map(xs->data, xs->datalen,
- ccb->data_phys, mflags);
- for (seg = 0; seg < ccb->data_nseg; seg++) {
- ltophys(ccb->data_phys[seg].addr,
- sg[seg].seg_addr);
- ltophys(ccb->data_phys[seg].length,
- sg[seg].seg_len);
+ {
+ /*
+ * Set up the scatter-gather block.
+ */
+ SC_DEBUG(sc_link, SDEV_DB4,
+ ("%d @0x%x:- ", xs->datalen, xs->data));
+
+ datalen = xs->datalen;
+ thiskv = (int)xs->data;
+ thisphys = KVTOPHYS(thiskv);
+
+ while (datalen && seg < BT_NSEG) {
+ bytes_this_seg = 0;
+
+ /* put in the base address */
+ ltophys(thisphys, sg->seg_addr);
+
+ SC_DEBUGN(sc_link, SDEV_DB4, ("0x%x", thisphys));
+
+ /* do it at least once */
+ nextphys = thisphys;
+ while (datalen && thisphys == nextphys) {
+ /*
+ * This page is contiguous (physically)
+ * with the the last, just extend the
+ * length
+ */
+ /* how far to the end of the page */
+ nextphys = (thisphys & ~PGOFSET) + NBPG;
+ bytes_this_page = nextphys - thisphys;
+ /**** or the data ****/
+ bytes_this_page = min(bytes_this_page,
+ datalen);
+ bytes_this_seg += bytes_this_page;
+ datalen -= bytes_this_page;
+
+ /* get more ready for the next page */
+ thiskv = (thiskv & ~PGOFSET) + NBPG;
+ if (datalen)
+ thisphys = KVTOPHYS(thiskv);
+ }
+ /*
+ * next page isn't contiguous, finish the seg
+ */
+ SC_DEBUGN(sc_link, SDEV_DB4,
+ ("(0x%x)", bytes_this_seg));
+ ltophys(bytes_this_seg, sg->seg_len);
+ sg++;
+ seg++;
+ }
}
/* end of iov/kv decision */
- if (ccb->data_nseg == 0) {
- printf("%s: bt_scsi_cmd, cannot map\n",
- sc->sc_dev.dv_xname);
+ SC_DEBUGN(sc_link, SDEV_DB4, ("\n"));
+ if (datalen) {
+ /*
+ * there's still data, must have run out of segs!
+ */
+ printf("%s: bt_scsi_cmd, more than %d dma segs\n",
+ sc->sc_dev.dv_xname, BT_NSEG);
goto bad;
- } else if (flags & SCSI_DATA_OUT)
- isadma_copytobuf(xs->data, xs->datalen,
- ccb->data_nseg, ccb->data_phys);
- ltophys((unsigned)((struct bt_ccb *)(ccb->ccb_phys[0].addr))->scat_gath,
- ccb->data_addr);
- ltophys(ccb->data_nseg * sizeof(struct bt_scat_gath),
- ccb->data_length);
+ }
+ ltophys(KVTOPHYS(ccb->scat_gath), ccb->data_addr);
+ ltophys(seg * sizeof(struct bt_scat_gath), ccb->data_length);
} else { /* No data xfer, use non S/G values */
ltophys(0, ccb->data_addr);
ltophys(0, ccb->data_length);
@@ -1288,30 +1253,12 @@ bt_scsi_cmd(xs)
s = splbio();
bt_queue_ccb(sc, ccb);
+ splx(s);
/*
* Usually return SUCCESSFULLY QUEUED
*/
SC_DEBUG(sc_link, SDEV_DB3, ("cmd_sent\n"));
-
- if (VOLATILE_XS(xs)) {
- while ((ccb->xs->flags & ITSDONE) == 0) {
- tsleep(ccb, PRIBIO, "btwait", 0);
- }
- if (ccb->data_nseg) {
- if (flags & SCSI_DATA_IN)
- isadma_copyfrombuf(xs->data, xs->datalen,
- ccb->data_nseg, ccb->data_phys);
- isadma_unmap(xs->data, xs->datalen,
- ccb->data_nseg, ccb->data_phys);
- }
- bt_free_ccb(sc, ccb);
- scsi_done(xs);
- splx(s);
- return COMPLETE;
- }
- splx(s);
-
if ((flags & SCSI_POLL) == 0)
return SUCCESSFULLY_QUEUED;
@@ -1363,17 +1310,11 @@ bt_timeout(arg)
void *arg;
{
struct bt_ccb *ccb = arg;
- struct scsi_xfer *xs;
- struct scsi_link *sc_link;
- struct bt_softc *sc;
+ struct scsi_xfer *xs = ccb->xs;
+ struct scsi_link *sc_link = xs->sc_link;
+ struct bt_softc *sc = sc_link->adapter_softc;
int s;
- s = splbio();
- isadma_copyfrombuf((caddr_t)ccb, CCB_PHYS_SIZE, 1, ccb->ccb_phys);
- xs = ccb->xs;
- sc_link = xs->sc_link;
- sc = sc_link->adapter_softc;
-
sc_print_addr(sc_link);
printf("timed out");