Synchronize with sys/i386/isa/wd.c revision 1.126.

This commit is contained in:
KATO Takenori 1997-03-13 17:00:27 +00:00
parent 77fd6eeaf8
commit b5ff11dbb6

View File

@ -34,7 +34,7 @@
* SUCH DAMAGE.
*
* from: @(#)wd.c 7.2 (Berkeley) 5/9/91
* $Id$
* $Id: wd.c,v 1.19 1997/02/22 09:43:52 peter Exp $
*/
/* TODO:
@ -102,10 +102,15 @@
#include <vm/vm_prot.h>
#include <vm/pmap.h>
#ifdef ATAPI
#include <i386/isa/atapi.h>
#endif
#ifdef CMD640
#include <i386/isa/wdc_p.h>
#endif /*CMD640*/
extern void wdstart(int ctrlr);
#define TIMEOUT 10000
@ -147,6 +152,8 @@ epson_errorf(int wdc)
#define RECAL 2 /* doing restore */
#define OPEN 3 /* done with open */
#define PRIMARY 0
/*
* Disk geometry. A small part of struct disklabel.
* XXX disklabel.5 contains an old clone of disklabel.h.
@ -168,6 +175,9 @@ struct disk {
long dk_bc; /* byte count left */
short dk_skip; /* blocks already transferred */
int dk_ctrlr; /* physical controller number */
#ifdef CMD640
int dk_ctrlr_cmd640;/* controller number for CMD640 quirk */
#endif
int dk_unit; /* physical unit number */
int dk_lunit; /* logical unit number */
char dk_state; /* control state */
@ -264,6 +274,26 @@ static struct bdevsw wd_bdevsw =
{ wdopen, wdclose, wdstrategy, wdioctl, /*0*/
wddump, wdsize, D_DISK, "wd", &wd_cdevsw, -1 };
#ifdef CMD640
static int atapictrlr;
static int eide_quirks;
#endif
/*
* Here we use the pci-subsystem to find out, whether there is
* a cmd640b-chip attached on this pci-bus. This public routine
* will be called by wdc_p.c .
*/
#ifdef CMD640
void
wdc_pci(int quirks)
{
eide_quirks = quirks;
}
#endif
/*
* Probe for controller.
*/
@ -423,7 +453,18 @@ wdattach(struct isa_device *dvp)
if (dvp->id_unit >= NWDC)
return (0);
#ifdef CMD640
if (eide_quirks & Q_CMD640B) {
if (dvp->id_unit == PRIMARY) {
printf("wdc0: CMD640B workaround enabled\n");
TAILQ_INIT( &wdtab[PRIMARY].controller_queue);
}
} else
TAILQ_INIT( &wdtab[dvp->id_unit].controller_queue);
#else
TAILQ_INIT( &wdtab[dvp->id_unit].controller_queue);
#endif
for (wdup = isa_biotab_wdc; wdup->id_driver != 0; wdup++) {
if (!old_epson_note) {
@ -452,6 +493,13 @@ wdattach(struct isa_device *dvp)
TAILQ_INIT( &drive_queue[lunit]);
bzero(du, sizeof *du);
du->dk_ctrlr = dvp->id_unit;
#ifdef CMD640
if (eide_quirks & Q_CMD640B) {
du->dk_ctrlr_cmd640 = PRIMARY;
} else {
du->dk_ctrlr_cmd640 = du->dk_ctrlr;
}
#endif
du->dk_unit = unit;
du->dk_lunit = lunit;
du->dk_port = dvp->id_iobase;
@ -548,14 +596,23 @@ wdattach(struct isa_device *dvp)
if (wddrives[lunit]->dk_ctrlr == dvp->id_unit &&
wddrives[lunit]->dk_unit == unit)
goto next;
#ifdef CMD640
if (atapi_attach (dvp->id_unit, unit, dvp->id_iobase))
atapictrlr = dvp->id_unit;
#else
atapi_attach (dvp->id_unit, unit, dvp->id_iobase);
#endif
next: }
#endif
/*
* Discard any interrupts generated by wdgetctlr(). wdflushirq()
* doesn't work now because the ambient ipl is too high.
*/
#ifdef CMD640
wdtab[du->dk_ctrlr_cmd640].b_active = 2;
#else
wdtab[dvp->id_unit].b_active = 2;
#endif
return (1);
}
@ -634,7 +691,11 @@ wdstrategy(register struct buf *bp)
du->dk_state = WANTOPEN;
}
#ifdef CMD640
if (wdtab[du->dk_ctrlr_cmd640].b_active == 0)
#else
if (wdtab[du->dk_ctrlr].b_active == 0)
#endif
wdstart(du->dk_ctrlr); /* start controller */
if (du->dk_dkunit >= 0) {
@ -682,7 +743,11 @@ static void
wdustart(register struct disk *du)
{
register struct buf *bp;
#ifdef CMD640
int ctrlr = du->dk_ctrlr_cmd640;
#else
int ctrlr = du->dk_ctrlr;
#endif
#ifdef PC98
outb(0x432,(du->dk_unit)%2);
@ -723,6 +788,16 @@ wdstart(int ctrlr)
long secpertrk, secpercyl;
int lunit;
int count;
#ifdef CMD640
int ctrlr_atapi;
if (eide_quirks & Q_CMD640B) {
ctrlr = PRIMARY;
ctrlr_atapi = atapictrlr;
} else {
ctrlr_atapi = ctrlr;
}
#endif
#ifdef ATAPI
if (wdtab[ctrlr].b_active == 2)
@ -734,9 +809,14 @@ wdstart(int ctrlr)
bp = wdtab[ctrlr].controller_queue.tqh_first;
if (bp == NULL) {
#ifdef ATAPI
#ifdef CMD640
if (atapi_start && atapi_start (ctrlr_atapi))
wdtab[ctrlr].b_active = 3;
#else
if (atapi_start && atapi_start (ctrlr))
/* mark controller active in ATAPI mode */
wdtab[ctrlr].b_active = 3;
#endif
#endif
return;
}
@ -976,6 +1056,17 @@ wdintr(int unit)
register struct disk *du;
register struct buf *bp;
#ifdef CMD640
int ctrlr_atapi;
if (eide_quirks & Q_CMD640B) {
unit = PRIMARY;
ctrlr_atapi = atapictrlr;
} else {
ctrlr_atapi = unit;
}
#endif
if (wdtab[unit].b_active == 2)
return; /* intr in wdflushirq() */
if (!wdtab[unit].b_active) {
@ -992,7 +1083,11 @@ wdintr(int unit)
#ifdef ATAPI
if (wdtab[unit].b_active == 3) {
/* process an ATAPI interrupt */
#ifdef CMD640
if (atapi_intr && atapi_intr (ctrlr_atapi))
#else
if (atapi_intr && atapi_intr (unit))
#endif
/* ATAPI op continues */
return;
/* controller is free, start new op */
@ -1211,8 +1306,13 @@ wdopen(dev_t dev, int flags, int fmt, struct proc *p)
#endif
/* Finish flushing IRQs left over from wdattach(). */
#ifdef CMD640
if (wdtab[du->dk_ctrlr_cmd640].b_active == 2)
wdtab[du->dk_ctrlr_cmd640].b_active = 0;
#else
if (wdtab[du->dk_ctrlr].b_active == 2)
wdtab[du->dk_ctrlr].b_active = 0;
#endif
du->dk_flags &= ~DKFL_BADSCAN;
@ -1377,7 +1477,11 @@ wdcontrol(register struct buf *bp)
int ctrlr;
du = wddrives[dkunit(bp->b_dev)];
#ifdef CMD640
ctrlr = du->dk_ctrlr_cmd640;
#else
ctrlr = du->dk_ctrlr;
#endif
#ifdef PC98
outb(0x432,(du->dk_unit)%2);
@ -1550,7 +1654,11 @@ wdsetctlr(struct disk *du)
error = 1;
}
if (error) {
#ifdef CMD640
wdtab[du->dk_ctrlr_cmd640].b_errcnt += RETRIES;
#else
wdtab[du->dk_ctrlr].b_errcnt += RETRIES;
#endif
return (1);
}
if (wdcommand(du, du->dk_dd.d_ncylinders, du->dk_dd.d_ntracks - 1, 0,
@ -2136,10 +2244,17 @@ wderror(struct buf *bp, struct disk *du, char *mesg)
static void
wdflushirq(struct disk *du, int old_ipl)
{
#ifdef CMD640
wdtab[du->dk_ctrlr_cmd640].b_active = 2;
splx(old_ipl);
(void)splbio();
wdtab[du->dk_ctrlr_cmd640].b_active = 0;
#else
wdtab[du->dk_ctrlr].b_active = 2;
splx(old_ipl);
(void)splbio();
wdtab[du->dk_ctrlr].b_active = 0;
#endif
}
/*
@ -2198,6 +2313,10 @@ static void
wdsleep(int ctrlr, char *wmesg)
{
int s = splbio();
#ifdef CMD640
if (eide_quirks & Q_CMD640B)
ctrlr = PRIMARY;
#endif
while (wdtab[ctrlr].b_active)
tsleep((caddr_t)&wdtab[ctrlr].b_active, PZERO - 1, wmesg, 1);
splx(s);