Use <machine/bus.h> ... on the right track to making this an MI driver.
This commit is contained in:
parent
7f0f603f3a
commit
ea8aad3319
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: fd.c,v 1.88 1996/05/03 19:14:53 christos Exp $ */
|
||||
/* $NetBSD: fd.c,v 1.89 1996/05/12 01:37:02 thorpej Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1993, 1994, 1995 Charles Hannum.
|
||||
|
@ -54,7 +54,7 @@
|
|||
#include <sys/queue.h>
|
||||
|
||||
#include <machine/cpu.h>
|
||||
#include <machine/pio.h>
|
||||
#include <machine/bus.h>
|
||||
#include <machine/conf.h>
|
||||
|
||||
#include <dev/isa/isavar.h>
|
||||
|
@ -94,7 +94,9 @@ struct fdc_softc {
|
|||
struct isadev sc_id;
|
||||
void *sc_ih;
|
||||
|
||||
int sc_iobase;
|
||||
bus_chipset_tag_t sc_bc; /* ISA chipset identifier */
|
||||
bus_io_handle_t sc_ioh; /* ISA io handle */
|
||||
|
||||
int sc_drq;
|
||||
|
||||
struct fd_softc *sc_fd[4]; /* pointers to children */
|
||||
|
@ -203,7 +205,7 @@ void fd_set_motor __P((struct fdc_softc *fdc, int reset));
|
|||
void fd_motor_off __P((void *arg));
|
||||
void fd_motor_on __P((void *arg));
|
||||
int fdcresult __P((struct fdc_softc *fdc));
|
||||
int out_fdc __P((int iobase, u_char x));
|
||||
int out_fdc __P((bus_chipset_tag_t bc, bus_io_handle_t ioh, u_char x));
|
||||
void fdcstart __P((struct fdc_softc *fdc));
|
||||
void fdcstatus __P((struct device *dv, int n, char *s));
|
||||
void fdctimeout __P((void *arg));
|
||||
|
@ -219,41 +221,58 @@ fdcprobe(parent, match, aux)
|
|||
void *match, *aux;
|
||||
{
|
||||
register struct isa_attach_args *ia = aux;
|
||||
int iobase = ia->ia_iobase;
|
||||
bus_chipset_tag_t bc;
|
||||
bus_io_handle_t ioh;
|
||||
int rv;
|
||||
|
||||
bc = ia->ia_bc;
|
||||
rv = 0;
|
||||
|
||||
/* Map the i/o space. */
|
||||
if (bus_io_map(bc, ia->ia_iobase, FDC_NPORT, &ioh))
|
||||
return 0;
|
||||
|
||||
/* reset */
|
||||
outb(iobase + fdout, 0);
|
||||
bus_io_write_1(bc, ioh, fdout, 0);
|
||||
delay(100);
|
||||
outb(iobase + fdout, FDO_FRST);
|
||||
bus_io_write_1(bc, ioh, fdout, FDO_FRST);
|
||||
|
||||
/* see if it can handle a command */
|
||||
if (out_fdc(iobase, NE7CMD_SPECIFY) < 0)
|
||||
return 0;
|
||||
out_fdc(iobase, 0xdf);
|
||||
out_fdc(iobase, 2);
|
||||
if (out_fdc(bc, ioh, NE7CMD_SPECIFY) < 0)
|
||||
goto out;
|
||||
out_fdc(bc, ioh, 0xdf);
|
||||
out_fdc(bc, ioh, 2);
|
||||
|
||||
#ifdef NEWCONFIG
|
||||
if (iobase == IOBASEUNK || ia->ia_drq == DRQUNK)
|
||||
if (ia->ia_iobase == IOBASEUNK || ia->ia_drq == DRQUNK)
|
||||
return 0;
|
||||
|
||||
if (ia->ia_irq == IRQUNK) {
|
||||
ia->ia_irq = isa_discoverintr(fdcforceintr, aux);
|
||||
if (ia->ia_irq == IRQNONE)
|
||||
return 0;
|
||||
goto out;
|
||||
|
||||
/* reset it again */
|
||||
outb(iobase + fdout, 0);
|
||||
bus_io_write_1(bc, ioh, fdout, 0);
|
||||
delay(100);
|
||||
outb(iobase + fdout, FDO_FRST);
|
||||
bus_io_write_1(bc, ioh, fdout, FDO_FRST);
|
||||
}
|
||||
#endif
|
||||
|
||||
rv = 1;
|
||||
ia->ia_iosize = FDC_NPORT;
|
||||
ia->ia_msize = 0;
|
||||
return 1;
|
||||
|
||||
out:
|
||||
bus_io_unmap(bc, ioh, FDC_NPORT);
|
||||
return rv;
|
||||
}
|
||||
|
||||
#ifdef NEWCONFIG
|
||||
/*
|
||||
* XXX This is broken, and needs fixing. In general, the interface needs
|
||||
* XXX to change.
|
||||
*/
|
||||
void
|
||||
fdcforceintr(aux)
|
||||
void *aux;
|
||||
|
@ -263,9 +282,9 @@ fdcforceintr(aux)
|
|||
|
||||
/* the motor is off; this should generate an error with or
|
||||
without a disk drive present */
|
||||
out_fdc(iobase, NE7CMD_SEEK);
|
||||
out_fdc(iobase, 0);
|
||||
out_fdc(iobase, 0);
|
||||
out_fdc(bc, ioh, NE7CMD_SEEK);
|
||||
out_fdc(bc, ioh, 0);
|
||||
out_fdc(bc, ioh, 0);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -302,11 +321,21 @@ fdcattach(parent, self, aux)
|
|||
void *aux;
|
||||
{
|
||||
struct fdc_softc *fdc = (void *)self;
|
||||
bus_chipset_tag_t bc;
|
||||
bus_io_handle_t ioh;
|
||||
struct isa_attach_args *ia = aux;
|
||||
struct fdc_attach_args fa;
|
||||
int type;
|
||||
|
||||
fdc->sc_iobase = ia->ia_iobase;
|
||||
bc = ia->ia_bc;
|
||||
|
||||
/* Re-map the I/O space. */
|
||||
if (bus_io_map(bc, ia->ia_iobase, FDC_NPORT, &ioh))
|
||||
panic("fdcattach: couldn't map I/O ports");
|
||||
|
||||
fdc->sc_bc = bc;
|
||||
fdc->sc_ioh = ioh;
|
||||
|
||||
fdc->sc_drq = ia->ia_drq;
|
||||
fdc->sc_state = DEVIDLE;
|
||||
TAILQ_INIT(&fdc->sc_drives);
|
||||
|
@ -349,7 +378,8 @@ fdprobe(parent, match, aux)
|
|||
struct cfdata *cf = match;
|
||||
struct fdc_attach_args *fa = aux;
|
||||
int drive = fa->fa_drive;
|
||||
int iobase = fdc->sc_iobase;
|
||||
bus_chipset_tag_t bc = fdc->sc_bc;
|
||||
bus_io_handle_t ioh = fdc->sc_ioh;
|
||||
int n;
|
||||
|
||||
if (cf->cf_loc[0] != -1 && cf->cf_loc[0] != drive)
|
||||
|
@ -363,14 +393,14 @@ fdprobe(parent, match, aux)
|
|||
return 0;
|
||||
|
||||
/* select drive and turn on motor */
|
||||
outb(iobase + fdout, drive | FDO_FRST | FDO_MOEN(drive));
|
||||
bus_io_write_1(bc, ioh, fdout, drive | FDO_FRST | FDO_MOEN(drive));
|
||||
/* wait for motor to spin up */
|
||||
delay(250000);
|
||||
out_fdc(iobase, NE7CMD_RECAL);
|
||||
out_fdc(iobase, drive);
|
||||
out_fdc(bc, ioh, NE7CMD_RECAL);
|
||||
out_fdc(bc, ioh, drive);
|
||||
/* wait for recalibrate */
|
||||
delay(2000000);
|
||||
out_fdc(iobase, NE7CMD_SENSEI);
|
||||
out_fdc(bc, ioh, NE7CMD_SENSEI);
|
||||
n = fdcresult(fdc);
|
||||
#ifdef FD_DEBUG
|
||||
{
|
||||
|
@ -384,7 +414,7 @@ fdprobe(parent, match, aux)
|
|||
if (n != 2 || (fdc->sc_status[0] & 0xf8) != 0x20)
|
||||
return 0;
|
||||
/* turn off motor */
|
||||
outb(iobase + fdout, FDO_FRST);
|
||||
bus_io_write_1(bc, ioh, fdout, FDO_FRST);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
@ -633,7 +663,7 @@ fd_set_motor(fdc, reset)
|
|||
for (n = 0; n < 4; n++)
|
||||
if ((fd = fdc->sc_fd[n]) && (fd->sc_flags & FD_MOTOR))
|
||||
status |= FDO_MOEN(n);
|
||||
outb(fdc->sc_iobase + fdout, status);
|
||||
bus_io_write_1(fdc->sc_bc, fdc->sc_ioh, fdout, status);
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -668,13 +698,15 @@ int
|
|||
fdcresult(fdc)
|
||||
struct fdc_softc *fdc;
|
||||
{
|
||||
int iobase = fdc->sc_iobase;
|
||||
bus_chipset_tag_t bc = fdc->sc_bc;
|
||||
bus_io_handle_t ioh = fdc->sc_ioh;
|
||||
u_char i;
|
||||
int j = 100000,
|
||||
n = 0;
|
||||
|
||||
for (; j; j--) {
|
||||
i = inb(iobase + fdsts) & (NE7_DIO | NE7_RQM | NE7_CB);
|
||||
i = bus_io_read_1(bc, ioh, fdsts) &
|
||||
(NE7_DIO | NE7_RQM | NE7_CB);
|
||||
if (i == NE7_RQM)
|
||||
return n;
|
||||
if (i == (NE7_DIO | NE7_RQM | NE7_CB)) {
|
||||
|
@ -682,7 +714,7 @@ fdcresult(fdc)
|
|||
log(LOG_ERR, "fdcresult: overrun\n");
|
||||
return -1;
|
||||
}
|
||||
fdc->sc_status[n++] = inb(iobase + fddata);
|
||||
fdc->sc_status[n++] = bus_io_read_1(bc, ioh, fddata);
|
||||
}
|
||||
}
|
||||
log(LOG_ERR, "fdcresult: timeout\n");
|
||||
|
@ -690,19 +722,20 @@ fdcresult(fdc)
|
|||
}
|
||||
|
||||
int
|
||||
out_fdc(iobase, x)
|
||||
int iobase;
|
||||
out_fdc(bc, ioh, x)
|
||||
bus_chipset_tag_t bc;
|
||||
bus_io_handle_t ioh;
|
||||
u_char x;
|
||||
{
|
||||
int i = 100000;
|
||||
|
||||
while ((inb(iobase + fdsts) & NE7_DIO) && i-- > 0);
|
||||
while ((bus_io_read_1(bc, ioh, fdsts) & NE7_DIO) && i-- > 0);
|
||||
if (i <= 0)
|
||||
return -1;
|
||||
while ((inb(iobase + fdsts) & NE7_RQM) == 0 && i-- > 0);
|
||||
while ((bus_io_read_1(bc, ioh, fdsts) & NE7_RQM) == 0 && i-- > 0);
|
||||
if (i <= 0)
|
||||
return -1;
|
||||
outb(iobase + fddata, x);
|
||||
bus_io_write_1(bc, ioh, fddata, x);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -776,7 +809,7 @@ fdcstatus(dv, n, s)
|
|||
struct fdc_softc *fdc = (void *)dv->dv_parent;
|
||||
|
||||
if (n == 0) {
|
||||
out_fdc(fdc->sc_iobase, NE7CMD_SENSEI);
|
||||
out_fdc(fdc->sc_bc, fdc->sc_ioh, NE7CMD_SENSEI);
|
||||
(void) fdcresult(fdc);
|
||||
n = 2;
|
||||
}
|
||||
|
@ -848,7 +881,8 @@ fdcintr(arg)
|
|||
#define cyl fdc->sc_status[1]
|
||||
struct fd_softc *fd;
|
||||
struct buf *bp;
|
||||
int iobase = fdc->sc_iobase;
|
||||
bus_chipset_tag_t bc = fdc->sc_bc;
|
||||
bus_io_handle_t ioh = fdc->sc_ioh;
|
||||
int read, head, sec, i, nblks;
|
||||
struct fd_type *type;
|
||||
|
||||
|
@ -903,13 +937,13 @@ loop:
|
|||
if (fd->sc_cylin == bp->b_cylin)
|
||||
goto doio;
|
||||
|
||||
out_fdc(iobase, NE7CMD_SPECIFY);/* specify command */
|
||||
out_fdc(iobase, fd->sc_type->steprate);
|
||||
out_fdc(iobase, 6); /* XXX head load time == 6ms */
|
||||
out_fdc(bc, ioh, NE7CMD_SPECIFY);/* specify command */
|
||||
out_fdc(bc, ioh, fd->sc_type->steprate);
|
||||
out_fdc(bc, ioh, 6); /* XXX head load time == 6ms */
|
||||
|
||||
out_fdc(iobase, NE7CMD_SEEK); /* seek function */
|
||||
out_fdc(iobase, fd->sc_drive); /* drive number */
|
||||
out_fdc(iobase, bp->b_cylin * fd->sc_type->step);
|
||||
out_fdc(bc, ioh, NE7CMD_SEEK); /* seek function */
|
||||
out_fdc(bc, ioh, fd->sc_drive); /* drive number */
|
||||
out_fdc(bc, ioh, bp->b_cylin * fd->sc_type->step);
|
||||
|
||||
fd->sc_cylin = -1;
|
||||
fdc->sc_state = SEEKWAIT;
|
||||
|
@ -949,24 +983,24 @@ loop:
|
|||
isa_dmastart(read, bp->b_data + fd->sc_skip, fd->sc_nbytes,
|
||||
fdc->sc_drq);
|
||||
#endif
|
||||
outb(iobase + fdctl, type->rate);
|
||||
bus_io_write_1(bc, ioh, fdctl, type->rate);
|
||||
#ifdef FD_DEBUG
|
||||
printf("fdcintr: %s drive %d track %d head %d sec %d nblks %d\n",
|
||||
read ? "read" : "write", fd->sc_drive, fd->sc_cylin, head,
|
||||
sec, nblks);
|
||||
#endif
|
||||
if (read)
|
||||
out_fdc(iobase, NE7CMD_READ); /* READ */
|
||||
out_fdc(bc, ioh, NE7CMD_READ); /* READ */
|
||||
else
|
||||
out_fdc(iobase, NE7CMD_WRITE); /* WRITE */
|
||||
out_fdc(iobase, (head << 2) | fd->sc_drive);
|
||||
out_fdc(iobase, fd->sc_cylin); /* track */
|
||||
out_fdc(iobase, head);
|
||||
out_fdc(iobase, sec + 1); /* sector +1 */
|
||||
out_fdc(iobase, type->secsize); /* sector size */
|
||||
out_fdc(iobase, type->sectrac); /* sectors/track */
|
||||
out_fdc(iobase, type->gap1); /* gap1 size */
|
||||
out_fdc(iobase, type->datalen); /* data length */
|
||||
out_fdc(bc, ioh, NE7CMD_WRITE); /* WRITE */
|
||||
out_fdc(bc, ioh, (head << 2) | fd->sc_drive);
|
||||
out_fdc(bc, ioh, fd->sc_cylin); /* track */
|
||||
out_fdc(bc, ioh, head);
|
||||
out_fdc(bc, ioh, sec + 1); /* sector +1 */
|
||||
out_fdc(bc, ioh, type->secsize); /* sector size */
|
||||
out_fdc(bc, ioh, type->sectrac); /* sectors/track */
|
||||
out_fdc(bc, ioh, type->gap1); /* gap1 size */
|
||||
out_fdc(bc, ioh, type->datalen); /* data length */
|
||||
fdc->sc_state = IOCOMPLETE;
|
||||
|
||||
disk_busy(&fd->sc_dk);
|
||||
|
@ -986,7 +1020,7 @@ loop:
|
|||
disk_unbusy(&fd->sc_dk, 0); /* no data on seek */
|
||||
|
||||
/* Make sure seek really happened. */
|
||||
out_fdc(iobase, NE7CMD_SENSEI);
|
||||
out_fdc(bc, ioh, NE7CMD_SENSEI);
|
||||
if (fdcresult(fdc) != 2 || (st0 & 0xf8) != 0x20 ||
|
||||
cyl != bp->b_cylin * fd->sc_type->step) {
|
||||
#ifdef FD_DEBUG
|
||||
|
@ -1066,14 +1100,14 @@ loop:
|
|||
untimeout(fdctimeout, fdc);
|
||||
/* clear the controller output buffer */
|
||||
for (i = 0; i < 4; i++) {
|
||||
out_fdc(iobase, NE7CMD_SENSEI);
|
||||
out_fdc(bc, ioh, NE7CMD_SENSEI);
|
||||
(void) fdcresult(fdc);
|
||||
}
|
||||
|
||||
/* fall through */
|
||||
case DORECAL:
|
||||
out_fdc(iobase, NE7CMD_RECAL); /* recalibrate function */
|
||||
out_fdc(iobase, fd->sc_drive);
|
||||
out_fdc(bc, ioh, NE7CMD_RECAL); /* recalibrate function */
|
||||
out_fdc(bc, ioh, fd->sc_drive);
|
||||
fdc->sc_state = RECALWAIT;
|
||||
timeout(fdctimeout, fdc, 5 * hz);
|
||||
return 1; /* will return later */
|
||||
|
@ -1086,7 +1120,7 @@ loop:
|
|||
return 1; /* will return later */
|
||||
|
||||
case RECALCOMPLETE:
|
||||
out_fdc(iobase, NE7CMD_SENSEI);
|
||||
out_fdc(bc, ioh, NE7CMD_SENSEI);
|
||||
if (fdcresult(fdc) != 2 || (st0 & 0xf8) != 0x20 || cyl != 0) {
|
||||
#ifdef FD_DEBUG
|
||||
fdcstatus(&fd->sc_dev, 2, "recalibrate failed");
|
||||
|
|
Loading…
Reference in New Issue