Subject: port-i386/1477: Add bounce buffers to ISA DMA
To: None <gnats-bugs@gnats.netbsd.org>
From: Juergen Hannken-Illjes <hannken@eis.cs.tu-bs.de>
List: netbsd-bugs
Date: 09/19/1995 11:51:02
>Number: 1477
>Category: port-i386
>Synopsis: Add bounce buffers to ISA DMA
>Confidential: no
>Severity: serious
>Priority: medium
>Responsible: gnats-admin (GNATS administrator)
>State: open
>Class: change-request
>Submitter-Id: net
>Arrival-Date: Tue Sep 19 06:05:02 1995
>Last-Modified:
>Originator: Juergen Hannken-Illjes
>Organization:
TU Braunschweig - EIS - Germany
>Release: NetBSD-current as of Sep, 16. tarballs
>Environment:
System: NetBSD home 1.0A NetBSD 1.0A (CUSTOM) #73: Mon Sep 18 09:41:18 MET DST 1995 hannken@home:/usr/users/hannken/sys/arch/i386/compile/CUSTOM i386
>Description:
NetBSD/I386 is missing bounce buffers for busmaster DMA.
The hostmaster DMA code is not as good as it should be
because DMA is only possible up to PAGESIZE bytes.
>How-To-Repeat:
>Fix:
Patch relative to Sep, 16. NetBSD-current sources.
fd.c and aha1542.c have been updated to use the new DMA mapper. I cannot
test other drivers because I don't own the corresponding devices. The tail
of isadmavar.h contains some #defines to let drivers use the old interface.
If a driver doesn't call isadma_done() a warning is sent to syslog.
--- sys/dev/isa/isadma.c.orig Tue Apr 18 12:16:35 1995
+++ sys/dev/isa/isadma.c Sun Sep 17 17:10:22 1995
@@ -15,30 +15,33 @@
#include <dev/isa/isareg.h>
#include <dev/isa/isadmavar.h>
#include <dev/isa/isadmareg.h>
-/* region of physical memory known to be contiguous */
-vm_offset_t isaphysmem;
-static caddr_t dma_bounce[8]; /* XXX */
-static char bounced[8]; /* XXX */
-#define MAXDMASZ 512 /* XXX */
+struct dma_info {
+ int flags;
+ caddr_t addr;
+ vm_size_t nbytes;
+ struct isadma_seg phys[1];
+};
+
+static struct dma_info dma_info[8];
/* high byte of address is stored in this port for i-th dma channel */
static int dmapageport[8] =
{ 0x87, 0x83, 0x81, 0x82, 0x8f, 0x8b, 0x89, 0x8a };
/*
- * isa_dmacascade(): program 8237 DMA controller channel to accept
+ * isadma_cascade(): program 8237 DMA controller channel to accept
* external dma control by a board.
*/
void
-isa_dmacascade(chan)
+isadma_cascade(chan)
int chan;
{
#ifdef DIAGNOSTIC
if (chan < 0 || chan > 7)
- panic("isa_dmacascade: impossible request");
+ panic("isadma_cascade: impossible request");
#endif
/* set dma channel mode, and set dma channel mode */
if ((chan & 4) == 0) {
@@ -50,63 +53,67 @@
}
}
/*
- * isa_dmastart(): program 8237 DMA controller channel, avoid page alignment
+ * isadma_start(): program 8237 DMA controller channel, avoid page alignment
* problems by using a bounce buffer.
*/
void
-isa_dmastart(flags, addr, nbytes, chan)
- int flags;
+isadma_start(addr, nbytes, chan, flags)
caddr_t addr;
vm_size_t nbytes;
int chan;
+ int flags;
{
- vm_offset_t phys;
+ struct dma_info *di;
int waport;
- caddr_t newaddr;
+ int mflags;
+ vm_size_t size;
#ifdef DIAGNOSTIC
if (chan < 0 || chan > 7 ||
+ ((flags & ISADMA_START_READ) == 0) == ((flags & ISADMA_START_WRITE) == 0) ||
((chan & 4) ? (nbytes >= (1<<17) || nbytes & 1 || (u_int)addr & 1) :
(nbytes >= (1<<16))))
- panic("isa_dmastart: impossible request");
+ panic("isadma_start: impossible request");
#endif
- if (isa_dmarangecheck(addr, nbytes, chan)) {
- if (dma_bounce[chan] == 0)
- dma_bounce[chan] =
- /*(caddr_t)malloc(MAXDMASZ, M_TEMP, M_WAITOK);*/
- (caddr_t) isaphysmem + NBPG*chan;
- bounced[chan] = 1;
- newaddr = dma_bounce[chan];
- *(int *) newaddr = 0; /* XXX */
- /* copy bounce buffer on write */
- if ((flags & B_READ) == 0)
- bcopy(addr, newaddr, nbytes);
- addr = newaddr;
+ di = dma_info+chan;
+ if (di->flags != 0) {
+ log(LOG_ERR,"isadma_start: old request active on %d\n",chan);
+ isadma_abort(chan);
}
- /* translate to physical */
- phys = pmap_extract(pmap_kernel(), (vm_offset_t)addr);
+ di->flags = flags;
+ di->addr = addr;
+ di->nbytes = nbytes;
+
+ mflags = ISADMA_MAP_WAITOK | ISADMA_MAP_BOUNCE | ISADMA_MAP_CONTIG;
+ mflags |= (chan & 4) ? ISADMA_MAP_16BIT : ISADMA_MAP_8BIT;
+
+ if (isadma_map(addr, nbytes, di->phys, mflags) != 1)
+ panic("isadma_start: cannot map");
+
+ if ((flags & ISADMA_START_READ) == 0)
+ isadma_copytobuf(addr, nbytes, 1, di->phys);
if ((chan & 4) == 0) {
/*
* Program one of DMA channels 0..3. These are
* byte mode channels.
*/
/* set dma channel mode, and reset address ff */
- if (flags & B_READ)
+ if (flags & ISADMA_START_READ)
outb(DMA1_MODE, chan | DMA37MD_SINGLE | DMA37MD_WRITE);
else
outb(DMA1_MODE, chan | DMA37MD_SINGLE | DMA37MD_READ);
outb(DMA1_FFC, 0);
/* send start address */
waport = DMA1_CHN(chan);
- outb(waport, phys);
- outb(waport, phys>>8);
- outb(dmapageport[chan], phys>>16);
+ outb(waport, di->phys[0].addr);
+ outb(waport, di->phys[0].addr>>8);
+ outb(dmapageport[chan], di->phys[0].addr>>16);
/* send count */
outb(waport + 1, --nbytes);
outb(waport + 1, nbytes>>8);
@@ -118,19 +125,19 @@
* Program one of DMA channels 4..7. These are
* word mode channels.
*/
/* set dma channel mode, and reset address ff */
- if (flags & B_READ)
+ if (flags & ISADMA_START_READ)
outb(DMA2_MODE, (chan & 3) | DMA37MD_SINGLE | DMA37MD_WRITE);
else
outb(DMA2_MODE, (chan & 3) | DMA37MD_SINGLE | DMA37MD_READ);
outb(DMA2_FFC, 0);
/* send start address */
waport = DMA2_CHN(chan & 3);
- outb(waport, phys>>1);
- outb(waport, phys>>9);
- outb(dmapageport[chan], phys>>16);
+ outb(waport, di->phys[0].addr>>1);
+ outb(waport, di->phys[0].addr>>9);
+ outb(dmapageport[chan], di->phys[0].addr>>16);
/* send count */
nbytes >>= 1;
outb(waport + 2, --nbytes);
@@ -141,40 +148,52 @@
}
}
void
-isa_dmaabort(chan)
+isadma_abort(chan)
int chan;
{
+ struct dma_info *di;
#ifdef DIAGNOSTIC
if (chan < 0 || chan > 7)
- panic("isa_dmaabort: impossible request");
+ panic("isadma_abort: impossible request");
#endif
- bounced[chan] = 0;
+ di = dma_info+chan;
+ if (di->flags == 0) {
+ log(LOG_ERR,"isadma_abort: no request active on %d\n",chan);
+ return;
+ }
/* mask channel */
if ((chan & 4) == 0)
outb(DMA1_SMSK, DMA37SM_SET | chan);
else
outb(DMA2_SMSK, DMA37SM_SET | (chan & 3));
+
+ isadma_unmap(di->addr, di->nbytes, 1, di->phys);
+ di->flags = 0;
}
void
-isa_dmadone(flags, addr, nbytes, chan)
- int flags;
- caddr_t addr;
- vm_size_t nbytes;
+isadma_done(chan)
int chan;
{
+ struct dma_info *di;
u_char tc;
#ifdef DIAGNOSTIC
if (chan < 0 || chan > 7)
- panic("isa_dmadone: impossible request");
+ panic("isadma_done: impossible request");
#endif
+ di = dma_info+chan;
+ if (di->flags == 0) {
+ log(LOG_ERR,"isadma_done: no request active on %d\n",chan);
+ return;
+ }
+
/* check that the terminal count was reached */
if ((chan & 4) == 0)
tc = inb(DMA1_SR) & (1 << chan);
else
@@ -188,86 +207,10 @@
outb(DMA1_SMSK, DMA37SM_SET | chan);
else
outb(DMA2_SMSK, DMA37SM_SET | (chan & 3));
- /* copy bounce buffer on read */
- if (bounced[chan]) {
- bcopy(dma_bounce[chan], addr, nbytes);
- bounced[chan] = 0;
- }
-}
+ if (di->flags & ISADMA_START_READ)
+ isadma_copyfrombuf(di->addr, di->nbytes, 1, di->phys);
-/*
- * Check for problems with the address range of a DMA transfer
- * (non-contiguous physical pages, outside of bus address space,
- * crossing DMA page boundaries).
- * Return true if special handling needed.
- */
-int
-isa_dmarangecheck(va, length, chan)
- vm_offset_t va;
- u_long length;
- int chan;
-{
- vm_offset_t phys, priorpage = 0, endva;
- u_int dma_pgmsk = (chan & 4) ? ~(128*1024-1) : ~(64*1024-1);
-
- endva = round_page(va + length);
- for (; va < endva ; va += NBPG) {
- phys = trunc_page(pmap_extract(pmap_kernel(), va));
- if (phys == 0)
- panic("isa_dmacheck: no physical page present");
- if (phys >= (1<<24))
- return 1;
- if (priorpage) {
- if (priorpage + NBPG != phys)
- return 1;
- /* check if crossing a DMA page boundary */
- if ((priorpage ^ phys) & dma_pgmsk)
- return 1;
- }
- priorpage = phys;
- }
- return 0;
-}
-
-/* head of queue waiting for physmem to become available */
-struct buf isa_physmemq;
-
-/* blocked waiting for resource to become free for exclusive use */
-static isaphysmemflag;
-/* if waited for and call requested when free (B_CALL) */
-static void (*isaphysmemunblock)(); /* needs to be a list */
-
-/*
- * Allocate contiguous physical memory for transfer, returning
- * a *virtual* address to region. May block waiting for resource.
- * (assumed to be called at splbio())
- */
-caddr_t
-isa_allocphysmem(caddr_t va, unsigned length, void (*func)()) {
-
- isaphysmemunblock = func;
- while (isaphysmemflag & B_BUSY) {
- isaphysmemflag |= B_WANTED;
- sleep((caddr_t)&isaphysmemflag, PRIBIO);
- }
- isaphysmemflag |= B_BUSY;
-
- return((caddr_t)isaphysmem);
-}
-
-/*
- * Free contiguous physical memory used for transfer.
- * (assumed to be called at splbio())
- */
-void
-isa_freephysmem(caddr_t va, unsigned length) {
-
- isaphysmemflag &= ~B_BUSY;
- if (isaphysmemflag & B_WANTED) {
- isaphysmemflag &= B_WANTED;
- wakeup((caddr_t)&isaphysmemflag);
- if (isaphysmemunblock)
- (*isaphysmemunblock)();
- }
+ isadma_unmap(di->addr, di->nbytes, 1, di->phys);
+ di->flags = 0;
}
--- sys/dev/isa/wd.c.orig Tue Aug 15 18:16:43 1995
+++ sys/dev/isa/wd.c Sun Sep 17 13:37:00 1995
@@ -54,8 +54,9 @@
#include <machine/cpu.h>
#include <machine/pio.h>
#include <dev/isa/isavar.h>
+#include <dev/isa/isadmavar.h>
#include <dev/isa/wdreg.h>
#define WAITTIME (4 * hz) /* time to wait for a completion */
#define RECOVERYTIME (hz / 2) /* time to recover from an error */
--- sys/dev/isa/isadmavar.h.orig Fri Apr 14 12:54:45 1995
+++ sys/dev/isa/isadmavar.h Mon Sep 18 09:36:19 1995
@@ -1,6 +1,32 @@
/* $NetBSD: isadmavar.h,v 1.2 1994/10/27 04:17:09 cgd Exp $ */
-void isa_dmacascade __P((int));
-void isa_dmastart __P((int, caddr_t, vm_size_t, int));
-void isa_dmaabort __P((int));
-void isa_dmadone __P((int, caddr_t, vm_size_t, int));
+#define ISADMA_START_READ 0x0001 /* read from device */
+#define ISADMA_START_WRITE 0x0002 /* write to device */
+
+#define ISADMA_MAP_WAITOK 0x0001 /* OK for isadma_map to sleep */
+#define ISADMA_MAP_BOUNCE 0x0002 /* use bounce buffer if necessary */
+#define ISADMA_MAP_CONTIG 0x0004 /* must be physically contiguous */
+#define ISADMA_MAP_8BIT 0x0008 /* must not cross 64k boundary */
+#define ISADMA_MAP_16BIT 0x0010 /* must not cross 128k boundary */
+
+struct isadma_seg { /* a physical contiguous segment */
+ vm_offset_t addr; /* address of this segment */
+ vm_size_t length; /* length of this segment (bytes) */
+};
+
+int isadma_map __P((caddr_t, vm_size_t, struct isadma_seg *, int));
+void isadma_unmap __P((caddr_t, vm_size_t, int, struct isadma_seg *));
+void isadma_copytobuf __P((caddr_t, vm_size_t, int, struct isadma_seg *));
+void isadma_copyfrombuf __P((caddr_t, vm_size_t, int, struct isadma_seg *));
+
+void isadma_cascade __P((int));
+void isadma_start __P((caddr_t, vm_size_t, int, int));
+void isadma_abort __P((int));
+void isadma_done __P((int));
+
+/************ these are needed until all drivers have been cleaned up */
+#define isa_dmacascade(c) isadma_cascade((c))
+#define isa_dmastart(f,a,s,c) \
+ isadma_start((a),(s),(c),(f)&B_READ?ISADMA_START_READ:ISADMA_START_WRITE)
+#define isa_dmaabort(c) isadma_abort((c))
+#define isa_dmadone(a,s,c,f) isadma_abort((c))
--- sys/dev/isa/aha1542.c.orig Sun Sep 17 13:35:33 1995
+++ sys/dev/isa/aha1542.c Mon Sep 18 10:16:59 1995
@@ -1,6 +1,5 @@
/* $NetBSD: aha1542.c,v 1.50 1995/09/14 20:43:09 pk Exp $ */
-
/*
* Copyright (c) 1994 Charles Hannum. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -49,8 +48,9 @@
*/
#include <sys/types.h>
#include <sys/param.h>
+#include <sys/syslog.h>
#include <sys/systm.h>
#include <sys/kernel.h>
#include <sys/errno.h>
#include <sys/ioctl.h>
@@ -62,8 +62,9 @@
#include <machine/pio.h>
#include <dev/isa/isavar.h>
+#include <dev/isa/isadmavar.h>
#include <scsi/scsi_all.h>
#include <scsi/scsiconf.h>
#ifdef DDB
@@ -71,8 +72,10 @@
#else /* !DDB */
#define Debugger() panic("should call debugger here (aha1542.c)")
#endif /* !DDB */
+#define TUNE_1542 /* if bus speed check breaks the machine, undefine it */
+
/************************** board definitions *******************************/
/*
* I/O Port Interface
@@ -185,9 +188,9 @@
#define AHA_MBI_ERROR 0x4 /* Completed with error */
/* FOR OLD VERSIONS OF THE !%$@ this may have to be 16 (yuk) */
#define AHA_NSEG 17 /* Number of scatter gather segments <= 16 */
- /* allow 64 K i/o (min) */
+ /* allow 60 K i/o (min) */
struct aha_ccb {
u_char opcode;
u_char lun:3;
@@ -208,18 +211,21 @@
struct aha_scat_gath {
u_char seg_len[3];
u_char seg_addr[3];
} scat_gath[AHA_NSEG];
+#define CCB_PHYS_SIZE ((int)&((struct aha_ccb *)0)->chain)
/*----------------------------------------------------------------*/
TAILQ_ENTRY(aha_ccb) chain;
struct aha_ccb *nexthash;
- long hashkey;
struct scsi_xfer *xs; /* the scsi_xfer for this cmd */
int flags;
#define CCB_FREE 0
#define CCB_ACTIVE 1
#define CCB_ABORTED 2
struct aha_mbx_out *mbx; /* pointer to mail box */
+ struct isadma_seg ccb_phys[1]; /* phys segment of this ccb */
+ struct isadma_seg data_phys[AHA_NSEG]; /* phys segments of data */
+ int data_nseg;
};
/*
* opcode fields
@@ -303,10 +309,8 @@
#define CHAN7 0x80
/*********************************** end of board definitions***************/
-#define KVTOPHYS(x) vtophys(x)
-
#ifdef AHADEBUG
int aha_debug = 1;
#endif /*AHADEBUG */
@@ -567,9 +571,9 @@
struct isa_attach_args *ia = aux;
struct aha_softc *aha = (void *)self;
if (ia->ia_drq != DRQUNK)
- isa_dmacascade(ia->ia_drq);
+ isadma_cascade(ia->ia_drq);
aha_init(aha);
TAILQ_INIT(&aha->free_ccb);
@@ -728,8 +732,11 @@
int s;
s = splbio();
+ if (ccb->ccb_phys[0].addr)
+ isadma_unmap((caddr_t)ccb, CCB_PHYS_SIZE, 1, ccb->ccb_phys);
+
ccb->flags = CCB_FREE;
TAILQ_INSERT_HEAD(&aha->free_ccb, ccb, chain);
/*
@@ -749,14 +756,18 @@
aha_get_ccb(aha, flags)
struct aha_softc *aha;
int flags;
{
- int s;
+ int hashnum,mflags,s;
struct aha_ccb *ccb;
- int hashnum;
s = splbio();
+ if (flags & SCSI_NOSLEEP)
+ mflags = ISADMA_MAP_BOUNCE;
+ else
+ mflags = ISADMA_MAP_BOUNCE | ISADMA_MAP_WAITOK;
+
/*
* If we can and have to, sleep waiting for one
* to come free
*/
@@ -770,16 +781,8 @@
if (ccb = (struct aha_ccb *) malloc(sizeof(struct aha_ccb),
M_TEMP, M_NOWAIT)) {
bzero(ccb, sizeof(struct aha_ccb));
aha->numccbs++;
- /*
- * put in the phystokv hash table
- * Never gets taken out.
- */
- ccb->hashkey = KVTOPHYS(ccb);
- hashnum = CCB_HASH(ccb->hashkey);
- ccb->nexthash = aha->ccbhash[hashnum];
- aha->ccbhash[hashnum] = ccb;
} else {
printf("%s: can't malloc ccb\n",
aha->sc_dev.dv_xname);
}
@@ -789,29 +792,46 @@
break;
tsleep(&aha->free_ccb, PRIBIO, "ahaccb", 0);
}
+ 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 = aha->ccbhash[hashnum];
+ aha->ccbhash[hashnum] = ccb;
+ } else {
+ ccb->ccb_phys[0].addr = 0;
+ aha_free_ccb(aha,ccb,flags);
+ ccb = 0;
+ }
+
splx(s);
+
return ccb;
}
/*
- * given a physical address, find the ccb that it corresponds to.
+ * given a physical address, find the ccb that it corresponds to and remove
+ * it from the hash list.
*/
struct aha_ccb *
aha_ccb_phys_kv(aha, ccb_phys)
struct aha_softc *aha;
u_long ccb_phys;
{
int hashnum = CCB_HASH(ccb_phys);
- struct aha_ccb *ccb = aha->ccbhash[hashnum];
+ struct aha_ccb *res, **ccb = &aha->ccbhash[hashnum];
- while (ccb) {
- if (ccb->hashkey == ccb_phys)
+ while (*ccb) {
+ if ((*ccb)->ccb_phys[0].addr == ccb_phys)
break;
- ccb = ccb->nexthash;
+ (*ccb) = (*ccb)->nexthash;
}
- return ccb;
+
+ if (res = *ccb)
+ *ccb = (*ccb)->nexthash;
+
+ return res;
}
/*
* Get a mbo and send the ccb.
@@ -853,9 +873,9 @@
tsleep(wmbx, PRIBIO, "ahasnd", 0);/*XXX can't do this */
}
/* Link ccb to mbo. */
- lto3b(KVTOPHYS(ccb), wmbo->ccb_addr);
+ lto3b(ccb->ccb_phys[0].addr, wmbo->ccb_addr);
ccb->mbx = wmbo;
wmbo->cmd = cmd;
/* Sent it! */
@@ -920,8 +940,22 @@
} else
xs->resid = 0;
}
xs->flags |= ITSDONE;
+/* XXX fixme: */
+#ifndef KSTACK_IS_VALID_ON_INTERRUPT
+ if (xs->bp == NULL && (xs->flags & SCSI_POLL) == 0) {
+ wakeup(ccb);
+ return;
+ }
+#endif
+ 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);
+ }
aha_free_ccb(aha, ccb, xs->flags);
scsi_done(xs);
}
@@ -931,9 +965,8 @@
int
aha_find(aha)
struct aha_softc *aha;
{
- u_char ad[3];
volatile int i, sts;
struct aha_config conf;
struct aha_inquire inquire;
struct aha_extbios extbios;
@@ -1069,18 +1102,8 @@
*/
aha_cmd(aha, 1, 0, 0, 0, AHA_BUS_ON_TIME_SET, 7);
aha_cmd(aha, 1, 0, 0, 0, AHA_BUS_OFF_TIME_SET, 4);
-#ifdef TUNE_1542
-#error XXX Must deal with configuring the DRQ channel if we do this.
- /*
- * Initialize memory transfer speed
- * Not compiled in by default because it breaks some machines
- */
- if (!aha_set_bus_speed(aha))
- return EIO;
-#endif /* TUNE_1542 */
-
return 0;
}
/*
@@ -1090,14 +1113,27 @@
aha_init(aha)
struct aha_softc *aha;
{
u_char ad[3];
+ struct isadma_seg mbx_phys[1];
int i;
+#ifdef TUNE_1542
/*
- * Initialize mail box
+ * Initialize memory transfer speed
+ * Not compiled in by default because it breaks some machines
*/
- lto3b(KVTOPHYS(&aha->aha_mbx), ad);
+ if (!aha_set_bus_speed(aha))
+ panic("aha_init: cannot set bus speed");
+#endif /* TUNE_1542 */
+
+ /*
+ * Initialize mail box. This mapping will never be undone.
+ */
+ if (isadma_map((caddr_t)(&aha->aha_mbx), sizeof(struct aha_mbx),
+ mbx_phys,ISADMA_MAP_CONTIG) != 1)
+ panic("aha_init: cannot map mail box");
+ lto3b(mbx_phys[0].addr, ad);
aha_cmd(aha, 4, 0, 0, 0, AHA_MBX_INIT, AHA_MBX_SIZE,
ad[0], ad[1], ad[2]);
@@ -1117,10 +1153,10 @@
ahaminphys(bp)
struct buf *bp;
{
- if (bp->b_bcount > ((AHA_NSEG - 1) << PGSHIFT))
- bp->b_bcount = ((AHA_NSEG - 1) << PGSHIFT);
+ if (bp->b_bcount > ((AHA_NSEG - 2) << PGSHIFT))
+ bp->b_bcount = ((AHA_NSEG - 2) << PGSHIFT);
minphys(bp);
}
/*
@@ -1134,12 +1170,9 @@
struct scsi_link *sc_link = xs->sc_link;
struct aha_softc *aha = sc_link->adapter_softc;
struct aha_ccb *ccb;
struct aha_scat_gath *sg;
- int seg; /* scatter gather seg being worked on */
- int thiskv;
- u_long thisphys, nextphys;
- int bytes_this_seg, bytes_this_page, datalen, flags;
+ int seg, datalen, flags, mflags;
struct iovec *iovp;
struct aha_mbx_out *mbo;
int s;
@@ -1149,8 +1182,12 @@
* is from a buf (possibly from interrupt time)
* then we can't allow it to sleep
*/
flags = xs->flags;
+ if (flags & SCSI_NOSLEEP)
+ mflags = ISADMA_MAP_BOUNCE;
+ else
+ mflags = ISADMA_MAP_BOUNCE | ISADMA_MAP_WAITOK;
if ((flags & (ITSDONE|INUSE)) != INUSE) {
printf("%s: done or not in use?\n", aha->sc_dev.dv_xname);
xs->flags &= ~ITSDONE;
xs->flags |= INUSE;
@@ -1158,8 +1195,9 @@
if ((ccb = aha_get_ccb(aha, flags)) == NULL) {
xs->error = XS_DRIVER_STUFFUP;
return TRY_AGAIN_LATER;
}
+
ccb->flags = CCB_ACTIVE;
ccb->xs = xs;
/*
@@ -1179,11 +1217,13 @@
ccb->scsi_cmd_length = xs->cmdlen;
ccb->req_sense_length = sizeof(ccb->scsi_sense);
ccb->host_stat = 0x00;
ccb->target_stat = 0x00;
+ ccb->data_nseg = 0;
if (xs->datalen && (flags & SCSI_RESET) == 0) {
- lto3b(KVTOPHYS(ccb->scat_gath), ccb->data_addr);
+ sg = ((struct aha_ccb *)(ccb->ccb_phys[0].addr))->scat_gath;
+ lto3b((vm_offset_t)sg, ccb->data_addr);
sg = ccb->scat_gath;
seg = 0;
#ifdef TFS
if (flags & SCSI_DATA_UIO) {
@@ -1207,75 +1247,25 @@
/*
* 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 < AHA_NSEG) {
- bytes_this_seg = 0;
-
- /* put in the base address */
- lto3b(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
- */
- /* check it fits on the ISA bus */
- if (thisphys > 0xFFFFFF) {
- printf("%s: DMA beyond"
- " end of ISA\n",
- aha->sc_dev.dv_xname);
- xs->error = XS_DRIVER_STUFFUP;
- aha_free_ccb(aha, ccb, flags);
- return COMPLETE;
- }
- /** 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));
- lto3b(bytes_this_seg, sg->seg_len);
- sg++;
- seg++;
+ ccb->data_nseg = isadma_map(xs->data,xs->datalen,
+ ccb->data_phys, mflags);
+ for (seg = 0; seg < ccb->data_nseg; seg++) {
+ lto3b(ccb->data_phys[seg].addr,sg[seg].seg_addr);
+ lto3b(ccb->data_phys[seg].length,sg[seg].seg_len);
}
}
- lto3b(seg * sizeof(struct aha_scat_gath), ccb->data_length);
- SC_DEBUGN(sc_link, SDEV_DB4, ("\n"));
- if (datalen) {
- /*
- * there's still data, must have run out of segs!
- */
- printf("%s: aha_scsi_cmd, more than %d dma segs\n",
- aha->sc_dev.dv_xname, AHA_NSEG);
+ lto3b(ccb->data_nseg * sizeof(struct aha_scat_gath), ccb->data_length);
+ if (ccb->data_nseg == 0) {
+ printf("%s: aha_scsi_cmd, cannot map\n",
+ aha->sc_dev.dv_xname);
xs->error = XS_DRIVER_STUFFUP;
aha_free_ccb(aha, ccb, flags);
return COMPLETE;
- }
+ } else if (flags & SCSI_DATA_OUT)
+ isadma_copytobuf(xs->data,xs->datalen,ccb->data_nseg,
+ ccb->data_phys);
} else { /* No data xfer, use non S/G values */
lto3b(0, ccb->data_addr);
lto3b(0, ccb->data_length);
}
@@ -1289,19 +1279,45 @@
bcopy(xs->cmd, &ccb->scsi_cmd, ccb->scsi_cmd_length);
s = splbio();
+ isadma_copytobuf((caddr_t)ccb, CCB_PHYS_SIZE, 1, ccb->ccb_phys);
+
if (aha_send_mbo(aha, AHA_MBO_START, ccb) == NULL) {
splx(s);
xs->error = XS_DRIVER_STUFFUP;
+ if (ccb->data_nseg)
+ isadma_unmap(xs->data,xs->datalen,ccb->data_nseg,
+ ccb->data_phys);
aha_free_ccb(aha, ccb, flags);
return TRY_AGAIN_LATER;
}
/*
* Usually return SUCCESSFULLY QUEUED
*/
SC_DEBUG(sc_link, SDEV_DB3, ("cmd_sent\n"));
+/* XXX fixme: */
+#ifndef KSTACK_IS_VALID_ON_INTERRUPT
+ if (xs->bp == NULL && (flags & SCSI_POLL) == 0) {
+ if (tsleep(ccb,PRIBIO,"ahawait",(xs->timeout * hz) / 1000)) {
+ aha_timeout(ccb);
+ tsleep(ccb,PRIBIO,"ahawait1",2000);
+ }
+ splx(s);
+ 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);
+ }
+ aha_free_ccb(aha, ccb, xs->flags);
+ scsi_done(xs);
+ return COMPLETE;
+ }
+#endif
if ((flags & SCSI_POLL) == 0) {
timeout(aha_timeout, ccb, (xs->timeout * hz) / 1000);
splx(s);
return SUCCESSFULLY_QUEUED;
@@ -1382,21 +1398,20 @@
break;
lastworking = speed;
}
if (lastworking == -1) {
- printf("no working bus speed\n");
+ printf(" no working bus speed");
return 0;
}
- printf("%d nsec ", aha_bus_speeds[lastworking].nsecs);
+ printf(", %d nsec ", aha_bus_speeds[lastworking].nsecs);
if (lastworking == 7) /* is slowest already */
- printf("marginal\n");
+ printf("marginal");
else {
lastworking++;
- printf("ok, using %d nsec\n",
- aha_bus_speeds[lastworking].nsecs);
+ printf("ok, using %d nsec", aha_bus_speeds[lastworking].nsecs);
}
if (!aha_bus_speed_check(aha, lastworking)) {
- printf("test retry failed.. aborting.\n");
+ printf("test retry failed.. aborting.");
return 0;
}
return 1;
}
@@ -1415,11 +1430,25 @@
struct aha_softc *aha;
int speed;
{
int numspeeds = sizeof(aha_bus_speeds) / sizeof(struct bus_speed);
- int loopcount;
+ int result, loopcount;
+ struct isadma_seg test_phys[1], scratch_phys[1];
u_char ad[3];
+ result = 1;
+
+ if (isadma_map(aha_scratch_buf,sizeof(aha_scratch_buf),scratch_phys,
+ ISADMA_MAP_CONTIG) != 1)
+ return 0;
+ if (isadma_map(aha_test_string,sizeof(aha_test_string),test_phys,
+ ISADMA_MAP_CONTIG) != 1) {
+ isadma_unmap(aha_scratch_buf,sizeof(aha_scratch_buf),1,
+ scratch_phys);
+ return 0;
+ }
+ isadma_copytobuf(aha_test_string,sizeof(aha_test_string),1,test_phys);
+
/*
* Set the dma-speed
*/
aha_cmd(aha, 1, 0, 0, 0, AHA_SPEED_SET, aha_bus_speeds[speed].arg);
@@ -1428,32 +1457,41 @@
* put the test data into the buffer and calculate
* it's address. Read it onto the board
*/
for (loopcount = 100; loopcount; loopcount--) {
- lto3b(KVTOPHYS(aha_test_string), ad);
+ lto3b(test_phys[0].addr, ad);
aha_cmd(aha, 3, 0, 0, 0, AHA_WRITE_FIFO, ad[0], ad[1], ad[2]);
/*
* Clear the buffer then copy the contents back from the
* board.
*/
bzero(aha_scratch_buf, 54);
+ isadma_copytobuf(aha_scratch_buf, sizeof(aha_scratch_buf),
+ 1, scratch_phys);
- lto3b(KVTOPHYS(aha_scratch_buf), ad);
+ lto3b(scratch_phys[0].addr, ad);
aha_cmd(aha, 3, 0, 0, 0, AHA_READ_FIFO, ad[0], ad[1], ad[2]);
+ isadma_copyfrombuf(aha_scratch_buf, sizeof(aha_scratch_buf),
+ 1, scratch_phys);
/*
* Compare the original data and the final data and return the
* correct value depending upon the result. We only check the
* first 54 bytes, because that's all the board copies during
* WRITE_FIFO and READ_FIFO.
*/
- if (memcmp(aha_test_string, aha_scratch_buf, 54))
- return 0; /* failed test */
+ if (memcmp(aha_test_string, aha_scratch_buf, 54)) {
+ result = 0; /* failed test */
+ break;
+ }
}
+ isadma_unmap(aha_scratch_buf,sizeof(aha_scratch_buf),1,scratch_phys);
+ isadma_unmap(aha_test_string,sizeof(aha_test_string),1,test_phys);
+
/* copy succeeded; assume speed ok */
- return 1;
+ return result;
}
#endif /* TUNE_1542 */
void
--- sys/dev/isa/ultra14f.c.orig Sun Sep 17 13:35:40 1995
+++ sys/dev/isa/ultra14f.c Mon Sep 18 10:45:14 1995
@@ -65,8 +65,9 @@
#include <machine/pio.h>
#include <dev/isa/isavar.h>
+#include <dev/isa/isadmavar.h>
#include <scsi/scsi_all.h>
#include <scsi/scsiconf.h>
--- sys/dev/isa/wd7000.c.orig Sat Aug 19 18:41:04 1995
+++ sys/dev/isa/wd7000.c Mon Sep 18 10:46:03 1995
@@ -39,8 +39,9 @@
#include <machine/cpu.h>
#include <machine/pio.h>
+#include <dev/isa/isadmavar.h>
#include <i386/isa/isa_device.h> /* XXX BROKEN */
extern int delaycount; /* from clock setup code */
--- sys/arch/i386/i386/pmap.c.orig Tue Aug 15 18:14:12 1995
+++ sys/arch/i386/i386/pmap.c Sun Sep 17 13:37:03 1995
@@ -275,11 +275,20 @@
/*
* reserve special hunk of memory for use by bus dma as a bounce
* buffer (contiguous virtual *and* physical memory). XXX
*/
-#if NISA > 0
- isaphysmem = pmap_steal_memory(DMA_BOUNCE * NBPG);
-#endif
+ if (NISA > 0) {
+ if (ctob(physmem) >= 0x1000000) {
+ isaphysmem = pmap_steal_memory(DMA_BOUNCE * NBPG);
+ isaphysmempgs = DMA_BOUNCE;
+ } else {
+ isaphysmem = pmap_steal_memory(DMA_BOUNCE_LOW * NBPG);
+ isaphysmempgs = DMA_BOUNCE_LOW;
+ }
+ } else {
+ isaphysmem = NULL;
+ isaphysmempgs = 0;
+ }
pmap_update();
}
--- sys/arch/i386/isa/isa_machdep.h.orig Fri May 5 12:03:18 1995
+++ sys/arch/i386/isa/isa_machdep.h Mon Sep 18 09:17:06 1995
@@ -96,19 +96,25 @@
* ISA DMA bounce buffers.
* XXX should be made partially machine- and bus-mapping-independent.
*
* DMA_BOUNCE is the number of pages of low-addressed physical memory
- * to acquire for ISA bounce buffers.
+ * to acquire for ISA bounce buffers. If physical memory below 16 MB
+ * then DMA_BOUNCE_LOW will be used.
*
- * isaphysmem is the location of those bounce buffers. (They are currently
- * assumed to be contiguous.
+ * isaphysmem is the address of this physical contiguous low memory.
+ * isaphysmempgs is the number of pages allocated.
*/
#ifndef DMA_BOUNCE
-#define DMA_BOUNCE 8 /* one buffer per channel */
+#define DMA_BOUNCE 48 /* number of pages if memory > 16M */
+#endif
+
+#ifndef DMA_BOUNCE_LOW
+#define DMA_BOUNCE_LOW 16 /* number of pages if memory <= 16M */
#endif
extern vm_offset_t isaphysmem;
+extern int isaphysmempgs;
/*
* Variables and macros to deal with the ISA I/O hole.
--- sys/arch/i386/isa/isa_machdep.c.orig Tue Aug 15 18:14:17 1995
+++ sys/arch/i386/isa/isa_machdep.c Mon Sep 18 09:34:16 1995
@@ -43,13 +43,16 @@
#include <sys/syslog.h>
#include <sys/device.h>
#include <sys/malloc.h>
+#include <vm/vm.h>
+
#include <machine/pio.h>
#include <machine/cpufunc.h>
#include <dev/isa/isareg.h>
#include <dev/isa/isavar.h>
+#include <dev/isa/isadmavar.h>
#include <i386/isa/isa_machdep.h>
#include <i386/isa/icu.h>
#define IDTVEC(name) __CONCAT(X,name)
@@ -369,5 +372,308 @@
intr_calculatemasks();
if (intrhand[irq] == NULL)
intrtype[irq] = ISA_IST_NONE;
+}
+
+/*
+ * ISA DMA and bounce buffer management
+ */
+
+#define MAX_CHUNK 256 /* number of low memory segments */
+
+static unsigned long bitmap[MAX_CHUNK / 32 + 1];
+
+#define set(i) (bitmap[(i) >> 5] |= (1 << (i)))
+#define clr(i) (bitmap[(i) >> 5] &= ~(1 << (i)))
+#define bit(i) ((bitmap[(i) >> 5] & (1 << (i))) != 0)
+
+static int bit_ptr = -1; /* last segment visited */
+static int chunk_size = 0; /* size (bytes) of one low mem segment */
+static int chunk_num = 0; /* actual number of low mem segments */
+
+vm_offset_t isaphysmem; /* base address of low mem arena */
+int isaphysmempgs; /* number of pages of low mem arena */
+
+/*
+ * check if addr is from our low mem arena
+ */
+
+static int
+bounce_isbounced(addr)
+ vm_offset_t addr;
+{
+ return(addr >= vtophys(isaphysmem) &&
+ addr < vtophys(isaphysmem)+isaphysmempgs*NBPG);
+}
+
+/*
+ * return the virtual address of addr. addr must be from low mem arena
+ */
+
+static caddr_t
+bounce_to_virt(addr)
+ vm_offset_t addr;
+{
+ return((caddr_t)(isaphysmem+(addr-vtophys(isaphysmem))));
+}
+
+/*
+ * alloc a low mem segment of size nbytes. Alignment constraint is:
+ * (addr & pmask) == ((addr+size-1) & pmask)
+ * if waitok, call may wait for memory to become available.
+ * returns 0 on failure
+ */
+
+static vm_offset_t
+bounce_alloc(nbytes, pmask, waitok)
+ vm_size_t nbytes;
+ vm_offset_t pmask;
+ int waitok;
+{
+ int i,l;
+ vm_offset_t a,b,c,r;
+ vm_size_t n;
+ int nunits, opri;
+
+ opri = splbio();
+
+ if (bit_ptr < 0) { /* initialize low mem arena */
+ if ((chunk_size = isaphysmempgs*NBPG/MAX_CHUNK) & 1)
+ chunk_size--;
+ chunk_num = (isaphysmempgs*NBPG) / chunk_size;
+ for(i = 0; i < chunk_num; i++)
+ set(i);
+ bit_ptr = 0;
+ }
+
+ nunits = (nbytes+chunk_size-1)/chunk_size;
+
+ /*
+ * set a=start, b=start with address constraints, c=end
+ * check if this request may ever succeed.
+ */
+
+ a = isaphysmem;
+ b = (isaphysmem + ~pmask) & pmask;
+ c = isaphysmem + chunk_num*chunk_size;
+ n = nunits*chunk_size;
+ if (a + n >= c || pmask != 0 && a + n >= b && b + n >= c) {
+ splx(opri);
+ return(0);
+ }
+
+ for (;;) {
+ i = bit_ptr;
+ l = -1;
+ do{
+ if (bit(i) && l >= 0 && (i - l + 1) >= nunits){
+ r = vtophys(isaphysmem+(i-nunits+1)*chunk_size);
+ if (((r ^ (r+nbytes-1)) & pmask) == 0) {
+ for (l = i - nunits + 1; l <= i; l++)
+ clr(l);
+ bit_ptr = i;
+ splx(opri);
+ return(r);
+ }
+ } else if (bit(i) && l < 0)
+ l = i;
+ else if (!bit(i))
+ l = -1;
+ if (++i == chunk_num) {
+ i = 0;
+ l = -1;
+ }
+ } while(i != bit_ptr);
+
+ if (waitok)
+ tsleep((caddr_t) &bit_ptr, PRIBIO, "physmem", 0);
+ else {
+ splx(opri);
+ return(0);
+ }
+ }
+}
+
+/*
+ * return a segent of the low mem arena to the free pool
+ */
+
+static void
+bounce_free(addr, nbytes)
+ vm_offset_t addr;
+ vm_size_t nbytes;
+{
+ int i,j, opri;
+ vm_offset_t vaddr;
+
+ opri = splbio();
+
+ vaddr = (vm_offset_t)bounce_to_virt(addr);
+ if (vaddr < isaphysmem || vaddr >= isaphysmem+chunk_num*chunk_size ||
+ ((i = (int)(vaddr-isaphysmem)) % chunk_size) != 0)
+ panic("bounce_free: bad address");
+
+ i /= chunk_size;
+ j = i + (nbytes+chunk_size-1)/chunk_size;
+
+ while (i < j) {
+ if (bit(i))
+ panic("bounce_free: already free");
+ set(i);
+ i++;
+ }
+
+ wakeup((caddr_t)&bit_ptr);
+ splx(opri);
+}
+
+/*
+ * setup (addr,nbytes) for an ISA dma transfer.
+ * flags&ISADMA_MAP_WAITOK may wait
+ * flags&ISADMA_MAP_BOUNCE may use a bounce buffer if necessary
+ * flags&ISADMA_MAP_CONTIG result must be physically contiguous
+ * flags&ISADMA_MAP_8BIT must not cross 64k boundary
+ * flags&ISADMA_MAP_16BIT must not cross 128k boundary
+ *
+ * returns the number of used phys entries, 0 on failure.
+ * if flags&ISADMA_MAP_CONTIG result is 1 on sucess!
+ */
+
+int
+isadma_map(addr, nbytes, phys, flags)
+ caddr_t addr;
+ vm_size_t nbytes;
+ struct isadma_seg *phys;
+ int flags;
+{
+ vm_offset_t pmask, thiskv, thisphys, nextphys;
+ vm_size_t datalen;
+ int seg, waitok, i;
+
+ if (flags & ISADMA_MAP_8BIT)
+ pmask = ~((64*1024)-1);
+ else if (flags & ISADMA_MAP_16BIT)
+ pmask = ~((128*1024)-1);
+ else
+ pmask = 0;
+
+ waitok = (flags & ISADMA_MAP_WAITOK) != 0;
+
+ thiskv = (vm_offset_t)addr;
+ datalen = nbytes;
+ thisphys = vtophys(thiskv);
+ seg = 0;
+
+ while (datalen > 0 && (seg == 0 || (flags & ISADMA_MAP_CONTIG) == 0)) {
+ if (thisphys == 0)
+ panic("isadma_map: no physical page present");
+
+ phys[seg].length = 0;
+ phys[seg].addr = thisphys;
+
+ nextphys = thisphys;
+ while (datalen > 0 && thisphys == nextphys) {
+ nextphys = trunc_page(thisphys) + NBPG;
+ phys[seg].length += min(nextphys-thisphys, datalen);
+ datalen -= min(nextphys-thisphys, datalen);
+ thiskv = trunc_page(thiskv) + NBPG;
+ if (datalen)
+ thisphys = vtophys(thiskv);
+ }
+
+ if (phys[seg].addr+phys[seg].length > 0xffffff) {
+ if (flags & ISADMA_MAP_CONTIG) {
+ phys[seg].length = nbytes;
+ datalen = 0;
+ }
+ if ((flags & ISADMA_MAP_BOUNCE) == 0)
+ phys[seg].addr = 0;
+ else
+ phys[seg].addr =
+ bounce_alloc(phys[seg].length, pmask,
+ waitok);
+ if (phys[seg].addr == 0) {
+ for (i = 0; i < seg; i++)
+ if (bounce_isbounced(phys[i].addr))
+ bounce_free(phys[i].addr,
+ phys[i].length);
+ return 0;
+ }
+ }
+
+ seg++;
+ }
+
+ /* check all constraints */
+ if (datalen ||
+ ((phys[0].addr ^ (phys[0].addr+phys[0].length-1)) & pmask) != 0 ||
+ ((phys[0].addr & 1) && (flags & ISADMA_MAP_16BIT))) {
+ if ((flags & ISADMA_MAP_BOUNCE) == 0)
+ return 0;
+ if ((phys[0].addr = bounce_alloc(nbytes,pmask,waitok)) == 0)
+ return 0;
+ phys[0].length = nbytes;
+ }
+
+ return seg;
+}
+
+/*
+ * undo a ISA dma mapping. Simply return the bounced segments to the pool.
+ */
+
+void
+isadma_unmap(addr, nbytes, nphys, phys)
+ caddr_t addr;
+ vm_size_t nbytes;
+ int nphys;
+ struct isadma_seg *phys;
+{
+ int i;
+
+ for (i = 0; i < nphys; i++)
+ if (bounce_isbounced(phys[i].addr))
+ bounce_free(phys[i].addr,phys[i].length);
+}
+
+/*
+ * copy bounce buffer to buffer where needed
+ */
+
+void
+isadma_copyfrombuf(addr, nbytes, nphys, phys)
+ caddr_t addr;
+ vm_size_t nbytes;
+ int nphys;
+ struct isadma_seg *phys;
+{
+ int i;
+
+ for (i = 0; i < nphys; i++) {
+ if (bounce_isbounced(phys[i].addr)) {
+ bcopy(bounce_to_virt(phys[i].addr),addr,phys[i].length);
+ }
+ addr += phys[i].length;
+ }
+}
+
+/*
+ * copy buffer to bounce buffer where needed
+ */
+
+void
+isadma_copytobuf(addr, nbytes, nphys, phys)
+ caddr_t addr;
+ vm_size_t nbytes;
+ int nphys;
+ struct isadma_seg *phys;
+{
+ int i;
+
+ for (i = 0; i < nphys; i++) {
+ if (bounce_isbounced(phys[i].addr)) {
+ bcopy(addr,bounce_to_virt(phys[i].addr),phys[i].length);
+ }
+ addr += phys[i].length;
+ }
}
--- sys/arch/i386/isa/fd.c.orig Sat Aug 26 18:34:34 1995
+++ sys/arch/i386/isa/fd.c Sun Sep 17 16:55:39 1995
@@ -914,10 +914,10 @@
#ifdef NEWCONFIG
at_dma(read, bp->b_data + fd->sc_skip, fd->sc_nbytes,
fdc->sc_drq);
#else
- isa_dmastart(read, bp->b_data + fd->sc_skip, fd->sc_nbytes,
- fdc->sc_drq);
+ isadma_start(bp->b_data + fd->sc_skip, fd->sc_nbytes,
+ fdc->sc_drq, read ? ISADMA_START_READ : ISADMA_START_WRITE);
#endif
outb(iobase + fdctl, type->rate);
#ifdef FD_DEBUG
printf("fdcintr: %s drive %d track %d head %d sec %d nblks %d\n",
@@ -965,9 +965,9 @@
case IOTIMEDOUT:
#ifdef NEWCONFIG
at_dma_abort(fdc->sc_drq);
#else
- isa_dmaabort(fdc->sc_drq);
+ isadma_abort(fdc->sc_drq);
#endif
case SEEKTIMEDOUT:
case RECALTIMEDOUT:
case RESETTIMEDOUT:
@@ -979,9 +979,9 @@
if (fdcresult(fdc) != 7 || (st0 & 0xf8) != 0) {
#ifdef NEWCONFIG
at_dma_abort(fdc->sc_drq);
#else
- isa_dmaabort(fdc->sc_drq);
+ isadma_abort(fdc->sc_drq);
#endif
#ifdef FD_DEBUG
fdcstatus(&fd->sc_dev, 7, bp->b_flags & B_READ ?
"read failed" : "write failed");
@@ -993,11 +993,9 @@
}
#ifdef NEWCONFIG
at_dma_terminate(fdc->sc_drq);
#else
- read = bp->b_flags & B_READ;
- isa_dmadone(read, bp->b_data + fd->sc_skip, fd->sc_nbytes,
- fdc->sc_drq);
+ isadma_done(fdc->sc_drq);
#endif
if (fdc->sc_errors) {
diskerr(bp, "fd", "soft error", LOG_PRINTF,
fd->sc_skip / FDC_BSIZE, (struct disklabel *)NULL);
--- sys/arch/i386/isa/fdreg.h.orig Tue Aug 15 18:14:16 1995
+++ sys/arch/i386/isa/fdreg.h Sun Sep 17 16:56:29 1995
@@ -62,5 +62,5 @@
#define FDI_DCHG 0x80 /* diskette has been changed */
#define FDC_BSIZE 512
#define FDC_NPORT 8
-#define FDC_MAXIOSIZE NBPG /* XXX should be MAXBSIZE */
+#define FDC_MAXIOSIZE MAXBSIZE
--
Juergen Hannken-Illjes - hannken@eis.cs.tu-bs.de - TU Braunschweig (W Germany)
>Audit-Trail:
>Unformatted: