Make the ATA mid-layer appears as atabus, as proposed in

http://mail-index.netbsd.org/tech-kern/2003/09/25/0006.html
This adds a device (atabus) between IDE controllers and wd or atapibus, to
have each ATA channel show up in the device tree. Later there will be atabus
devices in /dev, so that we can do IOCTL on them.
Each atabus has its own kernel thread, to handle operations that needs polling,
e.g. reset and others.

Device probing on each bus it defered to the atabus thread creation.
This allows to do the reset and basic device probes in parallel, which reduce
boot time on systems with several pciide controllers.
This commit is contained in:
bouyer 2003-10-08 10:58:12 +00:00
parent 32856df936
commit 99d6009c2a
23 changed files with 1094 additions and 787 deletions

View File

@ -1,4 +1,4 @@
# $NetBSD: files,v 1.636 2003/10/05 08:04:24 jdolecek Exp $
# $NetBSD: files,v 1.637 2003/10/08 10:58:12 bouyer Exp $
# @(#)files.newconf 7.5 (Berkeley) 5/10/93
@ -195,11 +195,11 @@ include "dev/majors"
define audiobus { }
define midibus { }
define midisyn
define wdc_base
define wdc_base {[channel = -1]}
define scsi_core
define scsi {[channel = -1]}: scsi_core
define ata {[channel = -1], [drive = -1]}
define atapi {[channel = -1]}
define ata {[drive = -1]}
define atapi { }
define radiodev { }
define gpibdev {[address = -1]}
@ -718,8 +718,11 @@ file dev/ic/rtl81x9.c rtk
# Common code for ESDI/IDE/etc. controllers
#
device wdc: ata, atapi, wdc_base
file dev/ic/wdc.c wdc_base
device wdc: wdc_base
device atabus: atapi,ata
attach atabus at wdc_base
file dev/ic/wdc.c atabus
# CHIPS and Technologies 82C7[12][01] Universal Peripheral Controller
# lpt attachment commented out because "device lpt" isn't in this file.

View File

@ -1,4 +1,4 @@
/* $NetBSD: ata.c,v 1.19 2003/09/23 09:19:22 mycroft Exp $ */
/* $NetBSD: ata.c,v 1.20 2003/10/08 10:58:12 bouyer Exp $ */
/*
* Copyright (c) 1998, 2001 Manuel Bouyer. All rights reserved.
*
@ -29,7 +29,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: ata.c,v 1.19 2003/09/23 09:19:22 mycroft Exp $");
__KERNEL_RCSID(0, "$NetBSD: ata.c,v 1.20 2003/10/08 10:58:12 bouyer Exp $");
#ifndef WDCDEBUG
#define WDCDEBUG
@ -173,7 +173,7 @@ ata_set_mode(drvp, mode, flags)
}
void
ata_dmaerr(drvp)
ata_dmaerr(drvp, flags)
struct ata_drive_datas *drvp;
{
/*
@ -185,7 +185,7 @@ ata_dmaerr(drvp)
*/
drvp->n_dmaerrs++;
if (drvp->n_dmaerrs >= NERRS_MAX && drvp->n_xfers <= NXFER) {
wdc_downgrade_mode(drvp);
wdc_downgrade_mode(drvp, flags);
drvp->n_dmaerrs = NERRS_MAX-1;
drvp->n_xfers = 0;
return;

View File

@ -1,7 +1,7 @@
/* $NetBSD: ata_wdc.c,v 1.40 2003/10/05 17:48:49 bouyer Exp $ */
/* $NetBSD: ata_wdc.c,v 1.41 2003/10/08 10:58:12 bouyer Exp $ */
/*
* Copyright (c) 1998, 2001 Manuel Bouyer.
* Copyright (c) 1998, 2001, 2003 Manuel Bouyer.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@ -67,7 +67,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: ata_wdc.c,v 1.40 2003/10/05 17:48:49 bouyer Exp $");
__KERNEL_RCSID(0, "$NetBSD: ata_wdc.c,v 1.41 2003/10/08 10:58:12 bouyer Exp $");
#ifndef WDCDEBUG
#define WDCDEBUG
@ -106,7 +106,7 @@ __KERNEL_RCSID(0, "$NetBSD: ata_wdc.c,v 1.40 2003/10/05 17:48:49 bouyer Exp $");
#define DEBUG_FUNCS 0x08
#define DEBUG_PROBE 0x10
#ifdef WDCDEBUG
int wdcdebug_wd_mask = 0;
extern int wdcdebug_wd_mask; /* inited in wd.c */
#define WDCDEBUG_PRINT(args, level) \
if (wdcdebug_wd_mask & (level)) \
printf args
@ -122,7 +122,6 @@ void _wdc_ata_bio_start __P((struct channel_softc *,struct wdc_xfer *));
int wdc_ata_bio_intr __P((struct channel_softc *, struct wdc_xfer *, int));
void wdc_ata_bio_kill_xfer __P((struct channel_softc *,struct wdc_xfer *));
void wdc_ata_bio_done __P((struct channel_softc *, struct wdc_xfer *));
int wdc_ata_ctrl_intr __P((struct channel_softc *, struct wdc_xfer *, int));
int wdc_ata_err __P((struct ata_drive_datas *, struct ata_bio *));
#define WDC_ATA_NOERR 0x00 /* Drive doesn't report an error */
#define WDC_ATA_RECOV 0x01 /* There was a recovered error */
@ -207,15 +206,132 @@ wdc_ata_bio_start(chp, xfer)
struct wdc_xfer *xfer;
{
struct ata_bio *ata_bio = xfer->cmd;
struct ata_drive_datas *drvp = &chp->ch_drive[xfer->drive];
int wait_flags = (xfer->c_flags & C_POLL) ? AT_POLL : 0;
char *errstring;
WDCDEBUG_PRINT(("wdc_ata_bio_start %s:%d:%d\n",
chp->wdc->sc_dev.dv_xname, chp->channel, xfer->drive),
DEBUG_XFERS);
/* start timeout machinery */
if ((ata_bio->flags & ATA_POLL) == 0)
callout_reset(&chp->ch_callout, ATA_DELAY / 1000 * hz,
wdctimeout, chp);
/* Do control operations specially. */
if (__predict_false(drvp->state < READY)) {
/*
* Actually, we want to be careful not to mess with the control
* state if the device is currently busy, but we can assume
* that we never get to this point if that's the case.
*/
/* If it's not a polled command, we need the kenrel thread */
if ((xfer->c_flags & C_POLL) == 0 &&
(chp->ch_flags & WDCF_TH_RUN) == 0) {
chp->ch_queue->queue_freese++;
wakeup(&chp->thread);
return;
}
/*
* disable interrupts, all commands here should be quick
* enouth to be able to poll, and we don't go here that often
*/
bus_space_write_1(chp->ctl_iot, chp->ctl_ioh, wd_aux_ctlr,
WDCTL_4BIT | WDCTL_IDS);
if (chp->wdc->cap & WDC_CAPABILITY_SELECT)
chp->wdc->select(chp,xfer->drive);
bus_space_write_1(chp->cmd_iot, chp->cmd_ioh, wd_sdh,
WDSD_IBM | (xfer->drive << 4));
errstring = "wait";
if (wdcwait(chp, WDCS_DRDY, WDCS_DRDY, ATA_DELAY, wait_flags))
goto ctrltimeout;
wdccommandshort(chp, xfer->drive, WDCC_RECAL);
/* Wait for at last 400ns for status bit to be valid */
DELAY(1);
errstring = "recal";
if (wdcwait(chp, WDCS_DRDY, WDCS_DRDY, ATA_DELAY, wait_flags))
goto ctrltimeout;
if (chp->ch_status & (WDCS_ERR | WDCS_DWF))
goto ctrlerror;
/* Don't try to set modes if controller can't be adjusted */
if ((chp->wdc->cap & WDC_CAPABILITY_MODE) == 0)
goto geometry;
/* Also don't try if the drive didn't report its mode */
if ((drvp->drive_flags & DRIVE_MODE) == 0)
goto geometry;
wdccommand(chp, drvp->drive, SET_FEATURES, 0, 0, 0,
0x08 | drvp->PIO_mode, WDSF_SET_MODE);
errstring = "piomode";
if (wdcwait(chp, WDCS_DRDY, WDCS_DRDY, ATA_DELAY, wait_flags))
goto ctrltimeout;
if (chp->ch_status & (WDCS_ERR | WDCS_DWF))
goto ctrlerror;
if (drvp->drive_flags & DRIVE_UDMA) {
wdccommand(chp, drvp->drive, SET_FEATURES, 0, 0, 0,
0x40 | drvp->UDMA_mode, WDSF_SET_MODE);
} else if (drvp->drive_flags & DRIVE_DMA) {
wdccommand(chp, drvp->drive, SET_FEATURES, 0, 0, 0,
0x20 | drvp->DMA_mode, WDSF_SET_MODE);
} else {
goto geometry;
}
errstring = "dmamode";
if (wdcwait(chp, WDCS_DRDY, WDCS_DRDY, ATA_DELAY, wait_flags))
goto ctrltimeout;
if (chp->ch_status & (WDCS_ERR | WDCS_DWF))
goto ctrlerror;
geometry:
if (ata_bio->flags & ATA_LBA)
goto multimode;
wdccommand(chp, xfer->drive, WDCC_IDP,
ata_bio->lp->d_ncylinders,
ata_bio->lp->d_ntracks - 1, 0, ata_bio->lp->d_nsectors,
(ata_bio->lp->d_type == DTYPE_ST506) ?
ata_bio->lp->d_precompcyl / 4 : 0);
errstring = "geometry";
if (wdcwait(chp, WDCS_DRDY, WDCS_DRDY, ATA_DELAY, wait_flags))
goto ctrltimeout;
if (chp->ch_status & (WDCS_ERR | WDCS_DWF))
goto ctrlerror;
multimode:
if (ata_bio->multi == 1)
goto ready;
wdccommand(chp, xfer->drive, WDCC_SETMULTI, 0, 0, 0,
ata_bio->multi, 0);
errstring = "setmulti";
if (wdcwait(chp, WDCS_DRDY, WDCS_DRDY, ATA_DELAY, wait_flags))
goto ctrltimeout;
if (chp->ch_status & (WDCS_ERR | WDCS_DWF))
goto ctrlerror;
ready:
drvp->state = READY;
/*
* The drive is usable now
*/
bus_space_write_1(chp->ctl_iot, chp->ctl_ioh, wd_aux_ctlr,
WDCTL_4BIT);
}
_wdc_ata_bio_start(chp, xfer);
return;
ctrltimeout:
printf("%s:%d:%d: %s timed out\n",
chp->wdc->sc_dev.dv_xname, chp->channel, xfer->drive, errstring);
ata_bio->error = TIMEOUT;
goto ctrldone;
ctrlerror:
printf("%s:%d:%d: %s ",
chp->wdc->sc_dev.dv_xname, chp->channel, xfer->drive,
errstring);
if (chp->ch_status & WDCS_DWF) {
printf("drive fault\n");
ata_bio->error = ERR_DF;
} else {
printf("error (%x)\n", chp->ch_error);
ata_bio->r_error = chp->ch_error;
ata_bio->error = ERROR;
}
ctrldone:
drvp->state = 0;
wdc_ata_bio_done(chp, xfer);
bus_space_write_1(chp->ctl_iot, chp->ctl_ioh, wd_aux_ctlr, WDCTL_4BIT);
return;
}
void
@ -223,48 +339,17 @@ _wdc_ata_bio_start(chp, xfer)
struct channel_softc *chp;
struct wdc_xfer *xfer;
{
int wait_flags = (xfer->c_flags & C_POLL) ? AT_POLL : 0;
struct ata_bio *ata_bio = xfer->cmd;
struct ata_drive_datas *drvp = &chp->ch_drive[xfer->drive];
u_int16_t cyl;
u_int8_t head, sect, cmd = 0;
int nblks;
int ata_delay;
int dma_flags = 0;
WDCDEBUG_PRINT(("_wdc_ata_bio_start %s:%d:%d\n",
chp->wdc->sc_dev.dv_xname, chp->channel, xfer->drive),
DEBUG_INTR | DEBUG_XFERS);
/* Do control operations specially. */
if (drvp->state < READY) {
/*
* Actually, we want to be careful not to mess with the control
* state if the device is currently busy, but we can assume
* that we never get to this point if that's the case.
*/
/* at this point, we should only be in RECAL state */
if (drvp->state != RESET) {
printf("%s:%d:%d: bad state %d in _wdc_ata_bio_start\n",
chp->wdc->sc_dev.dv_xname, chp->channel,
xfer->drive, drvp->state);
panic("_wdc_ata_bio_start: bad state");
}
drvp->state = RECAL;
xfer->c_intr = wdc_ata_ctrl_intr;
bus_space_write_1(chp->cmd_iot, chp->cmd_ioh, wd_sdh,
WDSD_IBM | (xfer->drive << 4));
if (wdcwait(chp, WDCS_DRDY, WDCS_DRDY, ATA_DELAY) != 0)
goto timeout;
wdccommandshort(chp, xfer->drive, WDCC_RECAL);
drvp->state = RECAL_WAIT;
if ((ata_bio->flags & ATA_POLL) == 0) {
chp->ch_flags |= WDCF_IRQ_WAIT;
} else {
/* Wait for at last 400ns for status bit to be valid */
DELAY(1);
wdc_ata_ctrl_intr(chp, xfer, 0);
}
return;
}
if (xfer->c_flags & C_DMA) {
if (drvp->n_xfers <= NXFER)
@ -273,10 +358,6 @@ _wdc_ata_bio_start(chp, xfer)
if (ata_bio->flags & ATA_LBA48)
dma_flags |= WDC_DMA_LBA48;
}
if (ata_bio->flags & ATA_SINGLE)
ata_delay = ATA_DELAY;
else
ata_delay = ATA_DELAY;
again:
/*
*
@ -347,10 +428,18 @@ again:
return;
}
/* Initiate command */
if (chp->wdc->cap & WDC_CAPABILITY_SELECT)
chp->wdc->select(chp,xfer->drive);
bus_space_write_1(chp->cmd_iot, chp->cmd_ioh, wd_sdh,
WDSD_IBM | (xfer->drive << 4));
if (wait_for_ready(chp, ata_delay) < 0)
switch(wait_for_ready(chp, ATA_DELAY, wait_flags)) {
case WDCWAIT_OK:
break;
case WDCWAIT_TOUT:
goto timeout;
case WDCWAIT_THR:
return;
}
if (ata_bio->flags & ATA_LBA48) {
wdccommandext(chp, xfer->drive, to48(cmd),
(u_int64_t)ata_bio->blkno, nblks);
@ -362,6 +451,10 @@ again:
(*chp->wdc->dma_start)(chp->wdc->dma_arg,
chp->channel, xfer->drive);
chp->ch_flags |= WDCF_DMA_WAIT;
/* start timeout machinery */
if ((xfer->c_flags & C_POLL) == 0)
callout_reset(&chp->ch_callout,
ATA_DELAY / 1000 * hz, wdctimeout, chp);
/* wait for irq */
goto intr;
} /* else not DMA */
@ -375,10 +468,18 @@ again:
WDCC_READ : WDCC_WRITE;
}
/* Initiate command! */
if (chp->wdc->cap & WDC_CAPABILITY_SELECT)
chp->wdc->select(chp,xfer->drive);
bus_space_write_1(chp->cmd_iot, chp->cmd_ioh, wd_sdh,
WDSD_IBM | (xfer->drive << 4));
if (wait_for_ready(chp, ata_delay) < 0)
switch(wait_for_ready(chp, ATA_DELAY, wait_flags)) {
case WDCWAIT_OK:
break;
case WDCWAIT_TOUT:
goto timeout;
case WDCWAIT_THR:
return;
}
if (ata_bio->flags & ATA_LBA48) {
wdccommandext(chp, xfer->drive, to48(cmd),
(u_int64_t) ata_bio->blkno, nblks);
@ -388,6 +489,10 @@ again:
(ata_bio->lp->d_type == DTYPE_ST506) ?
ata_bio->lp->d_precompcyl / 4 : 0);
}
/* start timeout machinery */
if ((xfer->c_flags & C_POLL) == 0)
callout_reset(&chp->ch_callout,
ATA_DELAY / 1000 * hz, wdctimeout, chp);
} else if (ata_bio->nblks > 1) {
/* The number of blocks in the last stretch may be smaller. */
nblks = xfer->c_bcount / ata_bio->lp->d_secsize;
@ -398,7 +503,11 @@ again:
}
/* If this was a write and not using DMA, push the data. */
if ((ata_bio->flags & ATA_READ) == 0) {
if (wait_for_drq(chp, ata_delay) != 0) {
/*
* we have to busy-wait here, we can't rely on running in
* thread context.
*/
if (wait_for_drq(chp, ATA_DELAY, AT_POLL) != 0) {
printf("%s:%d:%d: timeout waiting for DRQ, "
"st=0x%02x, err=0x%02x\n",
chp->wdc->sc_dev.dv_xname, chp->channel,
@ -502,8 +611,7 @@ wdc_ata_bio_intr(chp, xfer, irq)
}
/* Ack interrupt done by wait_for_unbusy */
if (wait_for_unbusy(chp,
(irq == 0) ? ATA_DELAY : 0) < 0) {
if (wait_for_unbusy(chp, (irq == 0) ? ATA_DELAY : 0, AT_POLL) < 0) {
if (irq && (xfer->c_flags & C_TIMEOU) == 0)
return 0; /* IRQ was not for us */
printf("%s:%d:%d: device timeout, c_bcount=%d, c_skip%d\n",
@ -511,7 +619,8 @@ wdc_ata_bio_intr(chp, xfer, irq)
xfer->c_bcount, xfer->c_skip);
/* if we were using DMA, flag a DMA error */
if (xfer->c_flags & C_DMA) {
ata_dmaerr(drvp);
ata_dmaerr(drvp,
(xfer->c_flags & C_POLL) ? AT_POLL : 0);
}
ata_bio->error = TIMEOUT;
wdc_ata_bio_done(chp, xfer);
@ -532,7 +641,7 @@ wdc_ata_bio_intr(chp, xfer, irq)
* asserted for DMA transfers, so poll for DRDY.
*/
if (wdcwait(chp, WDCS_DRDY | WDCS_DRQ, WDCS_DRDY,
ATA_DELAY) < 0) {
ATA_DELAY, ATA_POLL) == WDCWAIT_TOUT) {
printf("%s:%d:%d: polled transfer timed out "
"(st=0x%x)\n", chp->wdc->sc_dev.dv_xname,
chp->channel, xfer->drive, chp->ch_status);
@ -557,7 +666,7 @@ wdc_ata_bio_intr(chp, xfer, irq)
}
if (drv_err != WDC_ATA_ERR)
goto end;
ata_dmaerr(drvp);
ata_dmaerr(drvp, (xfer->c_flags & C_POLL) ? AT_POLL : 0);
}
/* if we had an error, end */
@ -685,169 +794,6 @@ wdc_ata_bio_done(chp, xfer)
wdcstart(chp);
}
/*
* Implement operations needed before read/write.
*/
int
wdc_ata_ctrl_intr(chp, xfer, irq)
struct channel_softc *chp;
struct wdc_xfer *xfer;
int irq;
{
struct ata_bio *ata_bio = xfer->cmd;
struct ata_drive_datas *drvp = &chp->ch_drive[xfer->drive];
char *errstring = NULL;
int delay = (irq == 0) ? ATA_DELAY : 0;
WDCDEBUG_PRINT(("wdc_ata_ctrl_intr: state %d\n", drvp->state),
DEBUG_FUNCS);
again:
switch (drvp->state) {
case RECAL: /* Should not be in this state here */
panic("wdc_ata_ctrl_intr: state==RECAL");
break;
case RECAL_WAIT:
errstring = "recal";
if (wdcwait(chp, WDCS_DRDY, WDCS_DRDY, delay))
goto timeout;
if (chp->wdc->cap & WDC_CAPABILITY_IRQACK)
chp->wdc->irqack(chp);
if (chp->ch_status & (WDCS_ERR | WDCS_DWF))
goto error;
/* fall through */
case PIOMODE:
/* Don't try to set modes if controller can't be adjusted */
if ((chp->wdc->cap & WDC_CAPABILITY_MODE) == 0)
goto geometry;
/* Also don't try if the drive didn't report its mode */
if ((drvp->drive_flags & DRIVE_MODE) == 0)
goto geometry;
wdccommand(chp, drvp->drive, SET_FEATURES, 0, 0, 0,
0x08 | drvp->PIO_mode, WDSF_SET_MODE);
drvp->state = PIOMODE_WAIT;
break;
case PIOMODE_WAIT:
errstring = "piomode";
if (wdcwait(chp, WDCS_DRDY, WDCS_DRDY, delay))
goto timeout;
if (chp->wdc->cap & WDC_CAPABILITY_IRQACK)
chp->wdc->irqack(chp);
if (chp->ch_status & (WDCS_ERR | WDCS_DWF))
goto error;
/* fall through */
case DMAMODE:
if (drvp->drive_flags & DRIVE_UDMA) {
wdccommand(chp, drvp->drive, SET_FEATURES, 0, 0, 0,
0x40 | drvp->UDMA_mode, WDSF_SET_MODE);
} else if (drvp->drive_flags & DRIVE_DMA) {
wdccommand(chp, drvp->drive, SET_FEATURES, 0, 0, 0,
0x20 | drvp->DMA_mode, WDSF_SET_MODE);
} else {
goto geometry;
}
drvp->state = DMAMODE_WAIT;
break;
case DMAMODE_WAIT:
errstring = "dmamode";
if (wdcwait(chp, WDCS_DRDY, WDCS_DRDY, delay))
goto timeout;
if (chp->wdc->cap & WDC_CAPABILITY_IRQACK)
chp->wdc->irqack(chp);
if (chp->ch_status & (WDCS_ERR | WDCS_DWF))
goto error;
/* fall through */
case GEOMETRY:
geometry:
if (ata_bio->flags & ATA_LBA)
goto multimode;
wdccommand(chp, xfer->drive, WDCC_IDP,
ata_bio->lp->d_ncylinders,
ata_bio->lp->d_ntracks - 1, 0, ata_bio->lp->d_nsectors,
(ata_bio->lp->d_type == DTYPE_ST506) ?
ata_bio->lp->d_precompcyl / 4 : 0);
drvp->state = GEOMETRY_WAIT;
break;
case GEOMETRY_WAIT:
errstring = "geometry";
if (wdcwait(chp, WDCS_DRDY, WDCS_DRDY, delay))
goto timeout;
if (chp->wdc->cap & WDC_CAPABILITY_IRQACK)
chp->wdc->irqack(chp);
if (chp->ch_status & (WDCS_ERR | WDCS_DWF))
goto error;
/* fall through */
case MULTIMODE:
multimode:
if (ata_bio->multi == 1)
goto ready;
wdccommand(chp, xfer->drive, WDCC_SETMULTI, 0, 0, 0,
ata_bio->multi, 0);
drvp->state = MULTIMODE_WAIT;
break;
case MULTIMODE_WAIT:
errstring = "setmulti";
if (wdcwait(chp, WDCS_DRDY, WDCS_DRDY, delay))
goto timeout;
if (chp->wdc->cap & WDC_CAPABILITY_IRQACK)
chp->wdc->irqack(chp);
if (chp->ch_status & (WDCS_ERR | WDCS_DWF))
goto error;
/* fall through */
case READY:
ready:
drvp->state = READY;
/*
* The drive is usable now
*/
xfer->c_intr = wdc_ata_bio_intr;
_wdc_ata_bio_start(chp, xfer);
return 1;
}
if ((ata_bio->flags & ATA_POLL) == 0) {
chp->ch_flags |= WDCF_IRQ_WAIT;
} else {
goto again;
}
return 1;
timeout:
if (irq && (xfer->c_flags & C_TIMEOU) == 0) {
return 0; /* IRQ was not for us */
}
printf("%s:%d:%d: %s timed out\n",
chp->wdc->sc_dev.dv_xname, chp->channel, xfer->drive, errstring);
ata_bio->error = TIMEOUT;
drvp->state = 0;
wdc_ata_bio_done(chp, xfer);
return 0;
error:
printf("%s:%d:%d: %s ",
chp->wdc->sc_dev.dv_xname, chp->channel, xfer->drive,
errstring);
if (chp->ch_status & WDCS_DWF) {
printf("drive fault\n");
ata_bio->error = ERR_DF;
} else {
printf("error (%x)\n", chp->ch_error);
ata_bio->r_error = chp->ch_error;
ata_bio->error = ERROR;
}
drvp->state = 0;
wdc_ata_bio_done(chp, xfer);
return 1;
}
int
wdc_ata_err(drvp, ata_bio)
struct ata_drive_datas *drvp;

View File

@ -1,4 +1,4 @@
/* $NetBSD: atavar.h,v 1.28 2003/10/05 17:48:49 bouyer Exp $ */
/* $NetBSD: atavar.h,v 1.29 2003/10/08 10:58:12 bouyer Exp $ */
/*
* Copyright (c) 1998, 2001 Manuel Bouyer.
@ -66,17 +66,7 @@ struct ata_drive_datas {
*/
u_int8_t state;
#define RESET 0
#define RECAL 1
#define RECAL_WAIT 2
#define PIOMODE 3
#define PIOMODE_WAIT 4
#define DMAMODE 5
#define DMAMODE_WAIT 6
#define GEOMETRY 7
#define GEOMETRY_WAIT 8
#define MULTIMODE 9
#define MULTIMODE_WAIT 10
#define READY 11
#define READY 1
/* numbers of xfers and DMA errs. Used by ata_dmaerr() */
u_int8_t n_dmaerrs;
@ -193,7 +183,7 @@ struct ata_smart_thresholds {
int8_t checksum;
} __attribute__((packed));
int wdc_downgrade_mode __P((struct ata_drive_datas *));
int wdc_downgrade_mode __P((struct ata_drive_datas *, int));
struct ataparams;
int ata_get_params __P((struct ata_drive_datas *, u_int8_t,
@ -204,4 +194,4 @@ int ata_set_mode __P((struct ata_drive_datas *, u_int8_t, u_int8_t));
#define CMD_ERR 1
#define CMD_AGAIN 2
void ata_dmaerr __P((struct ata_drive_datas *));
void ata_dmaerr __P((struct ata_drive_datas *, int));

View File

@ -1,4 +1,4 @@
# $NetBSD: files.ata,v 1.6 2003/01/27 18:21:29 thorpej Exp $
# $NetBSD: files.ata,v 1.7 2003/10/08 10:58:12 bouyer Exp $
#
# Config file and device description for machine-independent devices
# which attach to ATA busses. Included by ports that need it. Ports
@ -9,9 +9,9 @@
device wd: disk
attach wd at ata
file dev/ata/wd.c wd needs-flag
file dev/ata/ata_wdc.c wd & wdc_base
file dev/ata/ata_wdc.c wd & atabus
file dev/ata/ata.c (ata | atapi) & wdc_base
file dev/ata/ata.c (ata | atapi) & atabus
# ATA RAID configuration support
defpseudo ataraid {[vendtype = -1], [unit = -1]}

View File

@ -1,4 +1,4 @@
/* $NetBSD: wd.c,v 1.261 2003/09/19 21:36:01 mycroft Exp $ */
/* $NetBSD: wd.c,v 1.262 2003/10/08 10:58:12 bouyer Exp $ */
/*
* Copyright (c) 1998, 2001 Manuel Bouyer. All rights reserved.
@ -66,7 +66,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: wd.c,v 1.261 2003/09/19 21:36:01 mycroft Exp $");
__KERNEL_RCSID(0, "$NetBSD: wd.c,v 1.262 2003/10/08 10:58:12 bouyer Exp $");
#ifndef WDCDEBUG
#define WDCDEBUG
@ -126,7 +126,7 @@ __KERNEL_RCSID(0, "$NetBSD: wd.c,v 1.261 2003/09/19 21:36:01 mycroft Exp $");
#define DEBUG_FUNCS 0x08
#define DEBUG_PROBE 0x10
#ifdef WDCDEBUG
extern int wdcdebug_wd_mask; /* init'ed in ata_wdc.c */
int wdcdebug_wd_mask = 0x0;
#define WDCDEBUG_PRINT(args, level) \
if (wdcdebug_wd_mask & (level)) \
printf args
@ -262,10 +262,6 @@ wdprobe(struct device *parent, struct cfdata *match, void *aux)
if (adev->adev_bustype->bustype_type != SCSIPI_BUSTYPE_ATA)
return 0;
if (match->cf_loc[ATACF_CHANNEL] != ATACF_CHANNEL_DEFAULT &&
match->cf_loc[ATACF_CHANNEL] != adev->adev_channel)
return 0;
if (match->cf_loc[ATACF_DRIVE] != ATACF_DRIVE_DEFAULT &&
match->cf_loc[ATACF_DRIVE] != adev->adev_drv_data->drive)
return 0;
@ -293,7 +289,6 @@ wdattach(struct device *parent, struct device *self, void *aux)
wd->atabus = adev->adev_bustype;
wd->openings = adev->adev_openings;
wd->drvp = adev->adev_drv_data;
wd->wdc_softc = parent;
/* give back our softc to our caller */
wd->drvp->drv_softc = &wd->sc_dev;
@ -755,7 +750,7 @@ wddone(void *v)
errmsg = "error";
do_perror = 1;
retry: /* Just reset and retry. Can we do more ? */
wd->atabus->ata_reset_channel(wd->drvp);
wd->atabus->ata_reset_channel(wd->drvp, 0);
diskerr(bp, "wd", errmsg, LOG_PRINTF,
wd->sc_wdc_bio.blkdone, wd->sc_dk.dk_label);
if (wd->retries < WDIORETRIES)
@ -1067,7 +1062,7 @@ wdgetdisklabel(struct wd_softc *wd)
wd->sc_badsect[0] = -1;
if (wd->drvp->state > RECAL)
if (wd->drvp->state > RESET)
wd->drvp->drive_flags |= DRIVE_RESET;
errstring = readdisklabel(MAKEWDDEV(0, wd->sc_dev.dv_unit, RAW_PART),
wdstrategy, lp, wd->sc_dk.dk_cpulabel);
@ -1078,7 +1073,7 @@ wdgetdisklabel(struct wd_softc *wd)
* assume the DOS geometry is now in the label and try
* again. XXX This is a kluge.
*/
if (wd->drvp->state > RECAL)
if (wd->drvp->state > RESET)
wd->drvp->drive_flags |= DRIVE_RESET;
errstring = readdisklabel(MAKEWDDEV(0, wd->sc_dev.dv_unit,
RAW_PART), wdstrategy, lp, wd->sc_dk.dk_cpulabel);
@ -1088,7 +1083,7 @@ wdgetdisklabel(struct wd_softc *wd)
return;
}
if (wd->drvp->state > RECAL)
if (wd->drvp->state > RESET)
wd->drvp->drive_flags |= DRIVE_RESET;
#ifdef HAS_BAD144_HANDLING
if ((lp->d_flags & D_BADSECT) != 0)
@ -1269,7 +1264,7 @@ wdioctl(dev_t dev, u_long xfer, caddr_t addr, int flag, struct proc *p)
lp, /*wd->sc_dk.dk_openmask : */0,
wd->sc_dk.dk_cpulabel);
if (error == 0) {
if (wd->drvp->state > RECAL)
if (wd->drvp->state > RESET)
wd->drvp->drive_flags |= DRIVE_RESET;
if (xfer == DIOCWDINFO
#ifdef __HAVE_OLD_DISKLABEL

View File

@ -1,4 +1,4 @@
/* $NetBSD: wdvar.h,v 1.18 2003/10/05 17:48:49 bouyer Exp $ */
/* $NetBSD: wdvar.h,v 1.19 2003/10/08 10:58:12 bouyer Exp $ */
/*
* Copyright (c) 1998, 2001 Manuel Bouyer.
@ -68,7 +68,7 @@ struct ata_bio {
struct ata_bustype {
int bustype_type; /* symbolic name of type */
int (*ata_bio) __P((struct ata_drive_datas*, struct ata_bio *));
void (*ata_reset_channel) __P((struct ata_drive_datas *));
void (*ata_reset_channel) __P((struct ata_drive_datas *, int));
int (*ata_exec_command) __P((struct ata_drive_datas *,
struct wdc_command *));
#define WDC_COMPLETE 0x01
@ -108,7 +108,6 @@ struct wd_softc {
/* IDE disk soft states */
struct ata_bio sc_wdc_bio; /* current transfer */
struct buf *sc_bp; /* buf being transfered */
void *wdc_softc; /* pointer to our parent */
struct ata_drive_datas *drvp; /* Our controller's infos */
const struct ata_bustype *atabus;
int openings;

File diff suppressed because it is too large Load Diff

View File

@ -1,4 +1,4 @@
/* $NetBSD: wdc_upc.c,v 1.8 2003/09/25 19:29:49 mycroft Exp $ */
/* $NetBSD: wdc_upc.c,v 1.9 2003/10/08 10:58:12 bouyer Exp $ */
/*-
* Copyright (c) 2000 Ben Harris
* All rights reserved.
@ -28,7 +28,7 @@
/* This file is part of NetBSD/arm26 -- a port of NetBSD to ARM2/3 machines. */
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: wdc_upc.c,v 1.8 2003/09/25 19:29:49 mycroft Exp $");
__KERNEL_RCSID(0, "$NetBSD: wdc_upc.c,v 1.9 2003/10/08 10:58:12 bouyer Exp $");
#include <sys/param.h>
#include <sys/device.h>
@ -95,5 +95,5 @@ wdc_upc_attach(struct device *parent, struct device *self, void *aux)
printf("\n");
wdcattach(&sc->sc_wdc);
wdcattach(&sc->sc_channel);
}

View File

@ -1,4 +1,4 @@
/* $NetBSD: wdcvar.h,v 1.40 2003/09/25 19:29:49 mycroft Exp $ */
/* $NetBSD: wdcvar.h,v 1.41 2003/10/08 10:58:12 bouyer Exp $ */
/*-
* Copyright (c) 1998, 2003 The NetBSD Foundation, Inc.
@ -47,6 +47,7 @@
struct channel_queue { /* per channel queue (may be shared) */
TAILQ_HEAD(xferhead, wdc_xfer) sc_xfer;
int queue_freese;
};
struct channel_softc { /* Per channel data */
@ -67,24 +68,35 @@ struct channel_softc { /* Per channel data */
/* Our state */
int ch_flags;
#define WDCF_ACTIVE 0x01 /* channel is active */
#define WDCF_SHUTDOWN 0x02 /* channel is shutting down */
#define WDCF_IRQ_WAIT 0x10 /* controller is waiting for irq */
#define WDCF_DMA_WAIT 0x20 /* controller is waiting for DMA */
#define WDCF_DISABLED 0x80 /* channel is disabled */
#define WDCF_TH_RUN 0x100 /* the kenrel thread is working */
#define WDCF_TH_RESET 0x200 /* someone ask the thread to reset */
u_int8_t ch_status; /* copy of status register */
u_int8_t ch_error; /* copy of error register */
/* per-drive infos */
struct ata_drive_datas ch_drive[2];
struct device *atapibus;
struct device *atabus; /* self */
struct device *atapibus; /* children */
struct scsipi_channel ch_atapi_channel;
struct device *ata_drives[2];
struct device *ata_drives[2]; /* children */
/*
* channel queues. May be the same for all channels, if hw channels
* are not independants
*/
struct channel_queue *ch_queue;
/* the channel kenrel thread */
struct proc *thread;
};
struct atabus_softc { /* the atabus softc */
struct device sc_dev;
struct channel_softc *sc_chan;
};
struct wdc_softc { /* Per controller state */
@ -156,8 +168,6 @@ struct wdc_xfer {
#define C_TIMEOU 0x0002 /* xfer processing timed out */
#define C_POLL 0x0004 /* cmd is polled */
#define C_DMA 0x0008 /* cmd uses DMA */
#define C_SENSE 0x0010 /* cmd is a internal command */
#define C_FORCEPIO 0x0020 /* cmd must use PIO */
/* Informations about our location */
struct channel_softc *chp;
@ -181,7 +191,7 @@ struct wdc_xfer {
*/
int wdcprobe __P((struct channel_softc *));
void wdcattach __P((struct wdc_softc *));
void wdcattach __P((struct channel_softc *));
int wdcdetach __P((struct device *, int));
int wdcactivate __P((struct device *, enum devact));
int wdcintr __P((void *));
@ -193,9 +203,12 @@ void wdc_free_xfer __P((struct channel_softc *, struct wdc_xfer *));
void wdcstart __P((struct channel_softc *));
void wdcrestart __P((void*));
int wdcreset __P((struct channel_softc *, int));
#define VERBOSE 1
#define SILENT 0 /* wdcreset will not print errors */
int wdcwait __P((struct channel_softc *, int, int, int));
#define RESET_POLL 1
#define RESET_SLEEP 0 /* wdcreset will use tsleep() */
int wdcwait __P((struct channel_softc *, int, int, int, int));
#define WDCWAIT_OK 0 /* we have what we asked */
#define WDCWAIT_TOUT -1 /* timed out */
#define WDCWAIT_THR 1 /* return, the kernel thread has been awakened */
int wdc_dmawait __P((struct channel_softc *, struct wdc_xfer *, int));
void wdcbit_bucket __P(( struct channel_softc *, int));
void wdccommand __P((struct channel_softc *, u_int8_t, u_int8_t, u_int16_t,
@ -204,7 +217,7 @@ void wdccommandext __P((struct channel_softc *, u_int8_t, u_int8_t, u_int64_t,
u_int16_t));
void wdccommandshort __P((struct channel_softc *, int, int));
void wdctimeout __P((void *arg));
void wdc_reset_channel __P((struct ata_drive_datas *));
void wdc_reset_channel __P((struct ata_drive_datas *, int));
int wdc_exec_command __P((struct ata_drive_datas *, struct wdc_command*));
#define WDC_COMPLETE 0x01
#define WDC_QUEUED 0x02
@ -221,11 +234,13 @@ void wdc_probe_caps __P((struct ata_drive_datas*));
* ST506 spec says that if READY or SEEKCMPLT go off, then the read or write
* command is aborted.
*/
#define wait_for_drq(chp, timeout) wdcwait((chp), WDCS_DRQ, WDCS_DRQ, (timeout))
#define wait_for_unbusy(chp, timeout) wdcwait((chp), 0, 0, (timeout))
#define wait_for_ready(chp, timeout) wdcwait((chp), WDCS_DRDY, \
WDCS_DRDY, (timeout))
#define wait_for_drq(chp, timeout, flags) \
wdcwait((chp), WDCS_DRQ, WDCS_DRQ, (timeout), (flags))
#define wait_for_unbusy(chp, timeout, flags) \
wdcwait((chp), 0, 0, (timeout), (flags))
#define wait_for_ready(chp, timeout, flags) \
wdcwait((chp), WDCS_DRDY, WDCS_DRDY, (timeout), (flags))
/* ATA/ATAPI specs says a device can take 31s to reset */
#define WDC_RESET_WAIT 31000
void wdc_atapibus_attach __P((struct channel_softc *));
void wdc_atapibus_attach __P((struct atabus_softc *));

View File

@ -1,4 +1,4 @@
/* $NetBSD: wdc_isa.c,v 1.35 2003/09/25 19:29:49 mycroft Exp $ */
/* $NetBSD: wdc_isa.c,v 1.36 2003/10/08 10:58:12 bouyer Exp $ */
/*-
* Copyright (c) 1998, 2003 The NetBSD Foundation, Inc.
@ -37,7 +37,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: wdc_isa.c,v 1.35 2003/09/25 19:29:49 mycroft Exp $");
__KERNEL_RCSID(0, "$NetBSD: wdc_isa.c,v 1.36 2003/10/08 10:58:12 bouyer Exp $");
#include <sys/param.h>
#include <sys/systm.h>
@ -196,7 +196,7 @@ wdc_isa_attach(parent, self, aux)
printf("\n");
wdcattach(&sc->sc_wdcdev);
wdcattach(&sc->wdc_channel);
}
#if 0

View File

@ -1,4 +1,4 @@
/* $NetBSD: wdc_isapnp.c,v 1.21 2003/09/25 19:29:49 mycroft Exp $ */
/* $NetBSD: wdc_isapnp.c,v 1.22 2003/10/08 10:58:12 bouyer Exp $ */
/*-
* Copyright (c) 1998, 2003 The NetBSD Foundation, Inc.
@ -37,7 +37,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: wdc_isapnp.c,v 1.21 2003/09/25 19:29:49 mycroft Exp $");
__KERNEL_RCSID(0, "$NetBSD: wdc_isapnp.c,v 1.22 2003/10/08 10:58:12 bouyer Exp $");
#include <sys/param.h>
#include <sys/systm.h>
@ -158,7 +158,7 @@ wdc_isapnp_attach(parent, self, aux)
sc->wdc_channel.wdc = &sc->sc_wdcdev;
sc->wdc_channel.ch_queue = &sc->wdc_chqueue;
wdcattach(&sc->sc_wdcdev);
wdcattach(&sc->wdc_channel);
}
#ifdef notyet

View File

@ -1,4 +1,4 @@
/* $NetBSD: wdc_ofisa.c,v 1.14 2003/09/25 19:29:49 mycroft Exp $ */
/* $NetBSD: wdc_ofisa.c,v 1.15 2003/10/08 10:58:12 bouyer Exp $ */
/*
* Copyright 1997, 1998
@ -38,7 +38,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: wdc_ofisa.c,v 1.14 2003/09/25 19:29:49 mycroft Exp $");
__KERNEL_RCSID(0, "$NetBSD: wdc_ofisa.c,v 1.15 2003/10/08 10:58:12 bouyer Exp $");
#include <sys/param.h>
#include <sys/device.h>
@ -155,7 +155,7 @@ wdc_ofisa_attach(parent, self, aux)
sc->wdc_channel.wdc = &sc->sc_wdcdev;
sc->wdc_channel.ch_queue = &sc->wdc_chqueue;
wdcattach(&sc->sc_wdcdev);
wdcattach(&sc->wdc_channel);
#if 0
printf("%s: registers: ", sc->sc_dev.dv_xname);

View File

@ -1,4 +1,4 @@
# $NetBSD: files.pci,v 1.195 2003/09/30 00:35:30 thorpej Exp $
# $NetBSD: files.pci,v 1.196 2003/10/08 10:58:12 bouyer Exp $
#
# Config file and device description for machine-independent PCI code.
# Included by ports that need it. Requires that the SCSI files be
@ -191,7 +191,7 @@ file dev/pci/gtp.c gtp
#file dev/pci/sf64pcr.c sf4r
# PCI IDE controllers
device pciide {[channel = -1]}: cy82c693, wdc_base, ata, atapi
device pciide {[channel = -1]}: cy82c693, wdc_base
attach pciide at pci
file dev/pci/pciide.c pciide

View File

@ -1,4 +1,4 @@
/* $NetBSD: pciide.c,v 1.207 2003/10/05 17:48:49 bouyer Exp $ */
/* $NetBSD: pciide.c,v 1.208 2003/10/08 10:58:12 bouyer Exp $ */
/*
@ -75,7 +75,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: pciide.c,v 1.207 2003/10/05 17:48:49 bouyer Exp $");
__KERNEL_RCSID(0, "$NetBSD: pciide.c,v 1.208 2003/10/08 10:58:12 bouyer Exp $");
#ifndef WDCDEBUG
#define WDCDEBUG
@ -839,8 +839,6 @@ pciide_attach(parent, self, aux)
}
WDCDEBUG_PRINT(("pciide: command/status register=%x\n",
pci_conf_read(pc, tag, PCI_COMMAND_STATUS_REG)), DEBUG_PROBE);
wdcattach(&sc->sc_wdcdev);
}
/* tell whether the chip is enabled or not */
@ -1411,6 +1409,7 @@ pciide_mapchan(pa, cp, interface, cmdsizep, ctlsizep, pci_intr)
else
pciide_mapregs_compat(pa, cp, wdc_cp->channel, cmdsizep,
ctlsizep);
wdcattach(wdc_cp);
}
/*
@ -1497,6 +1496,13 @@ default_chip_map(sc, pa)
* Check to see if something appears to be there.
*/
failreason = NULL;
/*
* In native mode, always enable the controller. It's
* not possible to have an ISA board using the same address
* anyway.
*/
if (interface & PCIIDE_INTERFACE_PCI(channel))
goto next;
if (!wdcprobe(&cp->wdc_channel)) {
failreason = "not responding; disabled or no drives?";
goto next;
@ -1523,6 +1529,7 @@ next:
failreason);
cp->wdc_channel.ch_flags |= WDCF_DISABLED;
}
wdcattach(&cp->wdc_channel);
}
if (sc->sc_dma_ok == 0)
@ -3239,6 +3246,7 @@ cy693_chip_map(sc, pa)
pciide_mapregs_compat(pa, cp, sc->sc_cy_compatchan, &cmdsize,
&ctlsize);
}
wdcattach(&cp->wdc_channel);
}
void
@ -3253,6 +3261,9 @@ cy693_setup_channel(chp)
struct pciide_softc *sc = (struct pciide_softc *)cp->wdc_channel.wdc;
int dma_mode = -1;
WDCDEBUG_PRINT(("cy693_chip_map: old timings reg 0x%x\n",
pci_conf_read(sc->sc_pc, sc->sc_tag, CY_CMD_CTRL)),DEBUG_PROBE);
cy_cmd_ctrl = idedma_ctl = 0;
/* setup DMA if needed */
@ -3298,6 +3309,8 @@ cy693_setup_channel(chp)
bus_space_write_1(sc->sc_dma_iot, sc->sc_dma_ioh,
IDEDMA_CTL, idedma_ctl);
}
WDCDEBUG_PRINT(("cy693_chip_map: new timings reg 0x%x\n",
pci_conf_read(sc->sc_pc, sc->sc_tag, CY_CMD_CTRL)), DEBUG_PROBE);
}
static struct sis_hostbr_type {
@ -4004,6 +4017,7 @@ hpt_chip_map(sc, pa)
pciide_mapregs_compat(pa, cp, compatchan,
&cmdsize, &ctlsize);
}
wdcattach(&cp->wdc_channel);
}
if ((sc->sc_pp->ide_product == PCI_PRODUCT_TRIONES_HPT366 &&
(revision == HPT370_REV || revision == HPT370A_REV ||
@ -4594,6 +4608,11 @@ pdc20265_pci_intr(arg)
/* If a compat channel skip. */
if (cp->compat)
continue;
#if 0
bus_space_write_1(sc->sc_dma_iot, sc->sc_dma_ioh, IDEDMA_CMD + 0x1 + IDEDMA_SCH_OFFSET * i, 0x0b);
if ((bus_space_read_1(sc->sc_dma_iot, sc->sc_dma_ioh, IDEDMA_CMD + 0x3 + IDEDMA_SCH_OFFSET * i) & 0x20) == 0)
continue;
#endif
/*
* The Ultra/100 seems to assert PDC2xx_SCR_INT * spuriously,
* however it asserts INT in IDEDMA_CTL even for non-DMA ops.

View File

@ -1,4 +1,4 @@
/* $NetBSD: wdc_pcmcia.c,v 1.59 2003/09/25 19:29:49 mycroft Exp $ */
/* $NetBSD: wdc_pcmcia.c,v 1.60 2003/10/08 10:58:13 bouyer Exp $ */
/*-
* Copyright (c) 1998, 2003 The NetBSD Foundation, Inc.
@ -37,7 +37,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: wdc_pcmcia.c,v 1.59 2003/09/25 19:29:49 mycroft Exp $");
__KERNEL_RCSID(0, "$NetBSD: wdc_pcmcia.c,v 1.60 2003/10/08 10:58:13 bouyer Exp $");
#include <sys/param.h>
#include <sys/device.h>
@ -377,7 +377,7 @@ wdc_pcmcia_attach(parent, self, aux)
wdc_pcmcia_enable;
sc->sc_flags |= WDC_PCMCIA_ATTACH;
wdcattach(&sc->sc_wdcdev);
wdcattach(&sc->wdc_channel);
sc->sc_flags &= ~WDC_PCMCIA_ATTACH;
return;

View File

@ -1,4 +1,4 @@
/* $NetBSD: dtide.c,v 1.10 2003/09/25 19:29:49 mycroft Exp $ */
/* $NetBSD: dtide.c,v 1.11 2003/10/08 10:58:13 bouyer Exp $ */
/*-
* Copyright (c) 2000, 2001 Ben Harris
@ -31,7 +31,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: dtide.c,v 1.10 2003/09/25 19:29:49 mycroft Exp $");
__KERNEL_RCSID(0, "$NetBSD: dtide.c,v 1.11 2003/10/08 10:58:13 bouyer Exp $");
#include <sys/param.h>
@ -106,7 +106,7 @@ dtide_attach(struct device *parent, struct device *self, void *aux)
bus_space_map(pa->pa_fast_t,
pa->pa_fast_base + dtide_ctloffsets[i], 0, 8,
&sc->sc_chan[i].ctl_ioh);
wdcattach(&sc->sc_chan[i]);
}
wdcattach(&sc->sc_wdc);
}

View File

@ -1,4 +1,4 @@
# $NetBSD: files.podulebus,v 1.13 2001/07/04 15:01:08 bjh21 Exp $
# $NetBSD: files.podulebus,v 1.14 2003/10/08 10:58:13 bouyer Exp $
device podulebus { [slot = -1] }
define podloader
@ -14,12 +14,12 @@ attach hcsc at podulebus
file dev/podulebus/hcsc.c hcsc
# D.T. software IDE
device dtide: wdc_base, ata, atapi
device dtide: wdc_base
attach dtide at podulebus
file dev/podulebus/dtide.c dtide
# HCCS IDE
device hcide: wdc_base, ata, atapi
device hcide: wdc_base
attach hcide at podulebus
file dev/podulebus/hcide.c hcide

View File

@ -1,4 +1,4 @@
/* $NetBSD: hcide.c,v 1.7 2003/09/25 19:29:49 mycroft Exp $ */
/* $NetBSD: hcide.c,v 1.8 2003/10/08 10:58:13 bouyer Exp $ */
/*-
* Copyright (c) 2000, 2001 Ben Harris
@ -31,7 +31,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: hcide.c,v 1.7 2003/09/25 19:29:49 mycroft Exp $");
__KERNEL_RCSID(0, "$NetBSD: hcide.c,v 1.8 2003/10/08 10:58:13 bouyer Exp $");
#include <sys/param.h>
@ -101,7 +101,7 @@ hcide_attach(struct device *parent, struct device *self, void *aux)
bus_space_map(pa->pa_fast_t,
pa->pa_fast_base + hcide_ctloffsets[i], 0, 8,
&sc->sc_chan[i].ctl_ioh);
wdcattach(&sc->sc_chan[i]);
}
wdcattach(&sc->sc_wdc);
}

View File

@ -1,4 +1,4 @@
/* $NetBSD: atapi_wdc.c,v 1.58 2003/10/05 17:48:49 bouyer Exp $ */
/* $NetBSD: atapi_wdc.c,v 1.59 2003/10/08 10:58:13 bouyer Exp $ */
/*
* Copyright (c) 1998, 2001 Manuel Bouyer.
@ -31,7 +31,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: atapi_wdc.c,v 1.58 2003/10/05 17:48:49 bouyer Exp $");
__KERNEL_RCSID(0, "$NetBSD: atapi_wdc.c,v 1.59 2003/10/08 10:58:13 bouyer Exp $");
#ifndef WDCDEBUG
#define WDCDEBUG
@ -81,6 +81,7 @@ int wdcdebug_atapi_mask = 0;
#endif
#define ATAPI_DELAY 10 /* 10 ms, this is used only before sending a cmd */
#define ATAPI_MODE_DELAY 1000 /* 1s, timeout for SET_FEATYRE cmds */
int wdc_atapi_get_params __P((struct scsipi_channel *, int,
struct ataparams *));
void wdc_atapi_probe_device __P((struct atapibus_softc *, int));
@ -88,14 +89,13 @@ void wdc_atapi_minphys __P((struct buf *bp));
void wdc_atapi_start __P((struct channel_softc *,struct wdc_xfer *));
int wdc_atapi_intr __P((struct channel_softc *, struct wdc_xfer *, int));
void wdc_atapi_kill_xfer __P((struct channel_softc *, struct wdc_xfer *));
int wdc_atapi_ctrl __P((struct channel_softc *, struct wdc_xfer *, int));
void wdc_atapi_phase_complete __P((struct wdc_xfer *));
void wdc_atapi_done __P((struct channel_softc *, struct wdc_xfer *));
void wdc_atapi_reset __P((struct channel_softc *, struct wdc_xfer *));
void wdc_atapi_scsipi_request __P((struct scsipi_channel *,
scsipi_adapter_req_t, void *));
void wdc_atapi_kill_pending __P((struct scsipi_periph *));
void wdc_atapi_polldsc __P((void *arg));
static void wdc_atapi_polldsc __P((void *arg));
#define MAX_SIZE MAXPHYS
@ -108,9 +108,10 @@ const struct scsipi_bustype wdc_atapi_bustype = {
};
void
wdc_atapibus_attach(chp)
struct channel_softc *chp;
wdc_atapibus_attach(ata_sc)
struct atabus_softc *ata_sc;
{
struct channel_softc *chp = ata_sc->sc_chan;
struct wdc_softc *wdc = chp->wdc;
struct scsipi_adapter *adapt = &wdc->sc_atapi_adapter._generic;
struct scsipi_channel *chan = &chp->ch_atapi_channel;
@ -139,7 +140,7 @@ wdc_atapibus_attach(chp)
chan->chan_ntargets = 2;
chan->chan_nluns = 1;
chp->atapibus = config_found(&wdc->sc_dev, chan, atapiprint);
chp->atapibus = config_found(&ata_sc->sc_dev, chan, atapiprint);
}
void
@ -194,25 +195,35 @@ wdc_atapi_get_params(chan, drive, id)
struct wdc_command wdc_c;
/* if no ATAPI device detected at wdc attach time, skip */
/*
* XXX this will break scsireprobe if this is of any interest for
* ATAPI devices one day.
*/
if ((chp->ch_drive[drive].drive_flags & DRIVE_ATAPI) == 0) {
WDCDEBUG_PRINT(("wdc_atapi_get_params: drive %d not present\n",
drive), DEBUG_PROBE);
return -1;
}
wdccommandshort(chp, drive, ATAPI_SOFT_RESET);
chp->ch_drive[drive].state = 0;
if (wait_for_unbusy(chp, WDC_RESET_WAIT) != 0) {
memset(&wdc_c, 0, sizeof(struct wdc_command));
wdc_c.r_command = ATAPI_SOFT_RESET;
wdc_c.r_st_bmask = 0;
wdc_c.r_st_pmask = 0;
wdc_c.flags = AT_POLL;
wdc_c.timeout = WDC_RESET_WAIT;
if (wdc_exec_command(&chp->ch_drive[drive], &wdc_c) != WDC_COMPLETE) {
printf("wdc_atapi_get_params: ATAPI_SOFT_RESET failed for"
" drive %s:%d:%d: driver failed\n",
chp->wdc->sc_dev.dv_xname, chp->channel, drive);
panic("wdc_atapi_get_params");
}
if (wdc_c.flags & (AT_ERROR | AT_TIMEOU | AT_DF)) {
WDCDEBUG_PRINT(("wdc_atapi_get_params: ATAPI_SOFT_RESET "
"failed for drive %s:%d:%d\n",
chp->wdc->sc_dev.dv_xname, chp->channel, drive),
DEBUG_PROBE);
"failed for drive %s:%d:%d: error 0x%x\n",
chp->wdc->sc_dev.dv_xname, chp->channel, drive,
wdc_c.r_error), DEBUG_PROBE);
return -1;
}
chp->ch_drive[drive].state = 0;
bus_space_read_1(chp->cmd_iot, chp->cmd_ioh, wd_status);
/* Some ATAPI devices need a bit more time after software reset. */
delay(5000);
if (ata_get_params(&chp->ch_drive[drive], AT_WAIT, id) != 0) {
@ -338,6 +349,9 @@ wdc_atapi_scsipi_request(chan, req, arg)
if (sc_xfer->xs_control & XS_CTL_POLL)
xfer->c_flags |= C_POLL;
if ((wdc->channels[channel]->ch_drive[drive].drive_flags &
(DRIVE_DMA | DRIVE_UDMA)) && sc_xfer->datalen > 0)
xfer->c_flags |= C_DMA;
xfer->drive = drive;
xfer->c_flags |= C_ATAPI;
if (sc_xfer->cmd->opcode == GPCMD_REPORT_KEY ||
@ -347,7 +361,7 @@ wdc_atapi_scsipi_request(chan, req, arg)
* DVD authentication commands must always be done in
* PIO mode.
*/
xfer->c_flags |= C_FORCEPIO;
xfer->c_flags &= ~C_DMA;
}
/*
* DMA can't deal with transfers which are not a multiple of
@ -358,7 +372,7 @@ wdc_atapi_scsipi_request(chan, req, arg)
* 4 bytes.
*/
if (sc_xfer->datalen < 4 || (sc_xfer->datalen & 0x01))
xfer->c_flags |= C_FORCEPIO;
xfer->c_flags &= ~C_DMA;
xfer->cmd = sc_xfer;
xfer->databuf = sc_xfer->data;
@ -391,43 +405,105 @@ wdc_atapi_start(chp, xfer)
{
struct scsipi_xfer *sc_xfer = xfer->cmd;
struct ata_drive_datas *drvp = &chp->ch_drive[xfer->drive];
int wait_flags = (sc_xfer->xs_control & XS_CTL_POLL) ? AT_POLL : 0;
char *errstring;
WDCDEBUG_PRINT(("wdc_atapi_start %s:%d:%d, scsi flags 0x%x \n",
chp->wdc->sc_dev.dv_xname, chp->channel, drvp->drive,
sc_xfer->xs_control), DEBUG_XFERS);
/* Adjust C_DMA, it may have changed if we are requesting sense */
if ((drvp->drive_flags & (DRIVE_DMA | DRIVE_UDMA)) &&
sc_xfer->datalen > 0 && !(xfer->c_flags & C_FORCEPIO)) {
if (drvp->n_xfers <= NXFER)
drvp->n_xfers++;
xfer->c_flags |= C_DMA;
} else {
xfer->c_flags &= ~C_DMA;
if ((xfer->c_flags & C_DMA) && (drvp->n_xfers <= NXFER))
drvp->n_xfers++;
/* Do control operations specially. */
if (__predict_false(drvp->state < READY)) {
/* If it's not a polled command, we need the kenrel thread */
if ((sc_xfer->xs_control & XS_CTL_POLL) == 0 &&
(chp->ch_flags & WDCF_TH_RUN) == 0) {
chp->ch_queue->queue_freese++;
wakeup(&chp->thread);
return;
}
/*
* disable interrupts, all commands here should be quick
* enouth to be able to poll, and we don't go here that often
*/
bus_space_write_1(chp->ctl_iot, chp->ctl_ioh, wd_aux_ctlr,
WDCTL_4BIT | WDCTL_IDS);
if (chp->wdc->cap & WDC_CAPABILITY_SELECT)
chp->wdc->select(chp,xfer->drive);
bus_space_write_1(chp->cmd_iot, chp->cmd_ioh, wd_sdh,
WDSD_IBM | (xfer->drive << 4));
/* Don't try to set mode if controller can't be adjusted */
if ((chp->wdc->cap & WDC_CAPABILITY_MODE) == 0)
goto ready;
/* Also don't try if the drive didn't report its mode */
if ((drvp->drive_flags & DRIVE_MODE) == 0)
goto ready;
errstring = "unbusy";
if (wait_for_unbusy(chp, ATAPI_DELAY, wait_flags))
goto timeout;
wdccommand(chp, drvp->drive, SET_FEATURES, 0, 0, 0,
0x08 | drvp->PIO_mode, WDSF_SET_MODE);
errstring = "piomode";
if (wait_for_unbusy(chp, ATAPI_MODE_DELAY, wait_flags))
goto timeout;
if (chp->ch_status & WDCS_ERR) {
if (chp->ch_error == WDCE_ABRT) {
/*
* some ATAPI drives rejects pio settings.
* all we can do here is fall back to PIO 0
*/
drvp->drive_flags &= ~DRIVE_MODE;
drvp->drive_flags &= ~(DRIVE_DMA|DRIVE_UDMA);
drvp->PIO_mode = 0;
drvp->DMA_mode = 0;
printf("%s:%d:%d: pio setting rejected, "
"falling back to PIO mode 0\n",
chp->wdc->sc_dev.dv_xname,
chp->channel, xfer->drive);
chp->wdc->set_modes(chp);
goto ready;
}
goto error;
}
if (drvp->drive_flags & DRIVE_UDMA) {
wdccommand(chp, drvp->drive, SET_FEATURES, 0, 0, 0,
0x40 | drvp->UDMA_mode, WDSF_SET_MODE);
} else if (drvp->drive_flags & DRIVE_DMA) {
wdccommand(chp, drvp->drive, SET_FEATURES, 0, 0, 0,
0x20 | drvp->DMA_mode, WDSF_SET_MODE);
} else {
goto ready;
}
errstring = "dmamode";
if (wait_for_unbusy(chp, ATAPI_MODE_DELAY, wait_flags))
goto timeout;
if (chp->ch_status & WDCS_ERR)
goto error;
ready:
drvp->state = READY;
bus_space_write_1(chp->ctl_iot, chp->ctl_ioh, wd_aux_ctlr,
WDCTL_4BIT);
}
/* start timeout machinery */
if ((sc_xfer->xs_control & XS_CTL_POLL) == 0)
callout_reset(&chp->ch_callout, mstohz(sc_xfer->timeout),
wdctimeout, chp);
/* Do control operations specially. */
if (drvp->state < READY) {
if (drvp->state != RESET) {
printf("%s:%d:%d: bad state %d in wdc_atapi_start\n",
chp->wdc->sc_dev.dv_xname, chp->channel,
xfer->drive, drvp->state);
panic("wdc_atapi_start: bad state");
}
drvp->state = PIOMODE;
wdc_atapi_ctrl(chp, xfer, 0);
return;
}
if (chp->wdc->cap & WDC_CAPABILITY_SELECT)
chp->wdc->select(chp,xfer->drive);
bus_space_write_1(chp->cmd_iot, chp->cmd_ioh, wd_sdh,
WDSD_IBM | (xfer->drive << 4));
if (wait_for_unbusy(chp, ATAPI_DELAY) < 0) {
switch (wait_for_unbusy(chp, ATAPI_DELAY, wait_flags) < 0) {
case WDCWAIT_OK:
break;
case WDCWAIT_TOUT:
printf("wdc_atapi_start: not ready, st = %02x\n",
chp->ch_status);
sc_xfer->error = XS_TIMEOUT;
wdc_atapi_reset(chp, xfer);
return;
case WDCWAIT_THR:
return;
}
/*
@ -468,6 +544,24 @@ wdc_atapi_start(chp, xfer)
wdc_atapi_intr(chp, xfer, 0);
}
}
return;
timeout:
printf("%s:%d:%d: %s timed out\n",
chp->wdc->sc_dev.dv_xname, chp->channel, xfer->drive, errstring);
sc_xfer->error = XS_TIMEOUT;
bus_space_write_1(chp->ctl_iot, chp->ctl_ioh, wd_aux_ctlr, WDCTL_4BIT);
wdc_atapi_reset(chp, xfer);
return;
error:
printf("%s:%d:%d: %s ",
chp->wdc->sc_dev.dv_xname, chp->channel, xfer->drive,
errstring);
printf("error (0x%x)\n", chp->ch_error);
sc_xfer->error = XS_SHORTSENSE;
sc_xfer->sense.atapi_sense = chp->ch_error;
bus_space_write_1(chp->ctl_iot, chp->ctl_ioh, wd_aux_ctlr, WDCTL_4BIT);
wdc_atapi_reset(chp, xfer);
return;
}
int
@ -504,17 +598,20 @@ wdc_atapi_intr(chp, xfer, irq)
}
/* Ack interrupt done in wait_for_unbusy */
if (chp->wdc->cap & WDC_CAPABILITY_SELECT)
chp->wdc->select(chp,xfer->drive);
bus_space_write_1(chp->cmd_iot, chp->cmd_ioh, wd_sdh,
WDSD_IBM | (xfer->drive << 4));
if (wait_for_unbusy(chp,
(irq == 0) ? sc_xfer->timeout : 0) != 0) {
(irq == 0) ? sc_xfer->timeout : 0, AT_POLL) == WDCWAIT_TOUT) {
if (irq && (xfer->c_flags & C_TIMEOU) == 0)
return 0; /* IRQ was not for us */
printf("%s:%d:%d: device timeout, c_bcount=%d, c_skip=%d\n",
chp->wdc->sc_dev.dv_xname, chp->channel, xfer->drive,
xfer->c_bcount, xfer->c_skip);
if (xfer->c_flags & C_DMA) {
ata_dmaerr(drvp);
ata_dmaerr(drvp,
(xfer->c_flags & C_POLL) ? AT_POLL : 0);
}
sc_xfer->error = XS_TIMEOUT;
wdc_atapi_reset(chp, xfer);
@ -528,7 +625,7 @@ wdc_atapi_intr(chp, xfer, irq)
* and reset device.
*/
if ((xfer->c_flags & C_TIMEOU) && (xfer->c_flags & C_DMA)) {
ata_dmaerr(drvp);
ata_dmaerr(drvp, (xfer->c_flags & C_POLL) ? AT_POLL : 0);
sc_xfer->error = XS_RESET;
wdc_atapi_reset(chp, xfer);
return (1);
@ -603,7 +700,8 @@ again:
(xfer->c_flags & C_DMA) != 0) {
printf("wdc_atapi_intr: bad data phase DATAOUT\n");
if (xfer->c_flags & C_DMA) {
ata_dmaerr(drvp);
ata_dmaerr(drvp,
(xfer->c_flags & C_POLL) ? AT_POLL : 0);
}
sc_xfer->error = XS_TIMEOUT;
wdc_atapi_reset(chp, xfer);
@ -678,7 +776,8 @@ again:
(xfer->c_flags & C_DMA) != 0) {
printf("wdc_atapi_intr: bad data phase DATAIN\n");
if (xfer->c_flags & C_DMA) {
ata_dmaerr(drvp);
ata_dmaerr(drvp,
(xfer->c_flags & C_POLL) ? AT_POLL : 0);
}
sc_xfer->error = XS_TIMEOUT;
wdc_atapi_reset(chp, xfer);
@ -769,7 +868,8 @@ again:
sc_xfer->sense.atapi_sense = chp->ch_error;
} else {
if (xfer->c_flags & C_DMA) {
ata_dmaerr(drvp);
ata_dmaerr(drvp,
(xfer->c_flags & C_POLL) ? AT_POLL : 0);
}
sc_xfer->error = XS_RESET;
wdc_atapi_reset(chp, xfer);
@ -783,121 +883,6 @@ again:
return (1);
}
int
wdc_atapi_ctrl(chp, xfer, irq)
struct channel_softc *chp;
struct wdc_xfer *xfer;
int irq;
{
struct scsipi_xfer *sc_xfer = xfer->cmd;
struct ata_drive_datas *drvp = &chp->ch_drive[xfer->drive];
char *errstring = NULL;
int delay = (irq == 0) ? ATAPI_DELAY : 0;
/* Ack interrupt done in wait_for_unbusy */
again:
WDCDEBUG_PRINT(("wdc_atapi_ctrl %s:%d:%d state %d\n",
chp->wdc->sc_dev.dv_xname, chp->channel, drvp->drive, drvp->state),
DEBUG_INTR | DEBUG_FUNCS);
bus_space_write_1(chp->cmd_iot, chp->cmd_ioh, wd_sdh,
WDSD_IBM | (xfer->drive << 4));
switch (drvp->state) {
case PIOMODE:
/* Don't try to set mode if controller can't be adjusted */
if ((chp->wdc->cap & WDC_CAPABILITY_MODE) == 0)
goto ready;
/* Also don't try if the drive didn't report its mode */
if ((drvp->drive_flags & DRIVE_MODE) == 0)
goto ready;
wdccommand(chp, drvp->drive, SET_FEATURES, 0, 0, 0,
0x08 | drvp->PIO_mode, WDSF_SET_MODE);
drvp->state = PIOMODE_WAIT;
break;
case PIOMODE_WAIT:
errstring = "piomode";
if (wait_for_unbusy(chp, delay))
goto timeout;
if (chp->wdc->cap & WDC_CAPABILITY_IRQACK)
chp->wdc->irqack(chp);
if (chp->ch_status & WDCS_ERR) {
if (chp->ch_error == WDCE_ABRT) {
/*
* some ATAPI drives rejects pio settings.
* all we can do here is fall back to PIO 0
*/
drvp->drive_flags &= ~DRIVE_MODE;
drvp->drive_flags &= ~(DRIVE_DMA|DRIVE_UDMA);
drvp->PIO_mode = 0;
drvp->DMA_mode = 0;
printf("%s:%d:%d: pio setting rejected, "
"falling back to PIO mode 0\n",
chp->wdc->sc_dev.dv_xname,
chp->channel, xfer->drive);
chp->wdc->set_modes(chp);
goto ready;
}
goto error;
}
/* fall through */
case DMAMODE:
if (drvp->drive_flags & DRIVE_UDMA) {
wdccommand(chp, drvp->drive, SET_FEATURES, 0, 0, 0,
0x40 | drvp->UDMA_mode, WDSF_SET_MODE);
} else if (drvp->drive_flags & DRIVE_DMA) {
wdccommand(chp, drvp->drive, SET_FEATURES, 0, 0, 0,
0x20 | drvp->DMA_mode, WDSF_SET_MODE);
} else {
goto ready;
}
drvp->state = DMAMODE_WAIT;
break;
case DMAMODE_WAIT:
errstring = "dmamode";
if (wait_for_unbusy(chp, delay))
goto timeout;
if (chp->wdc->cap & WDC_CAPABILITY_IRQACK)
chp->wdc->irqack(chp);
if (chp->ch_status & WDCS_ERR)
goto error;
/* fall through */
case READY:
ready:
drvp->state = READY;
xfer->c_intr = wdc_atapi_intr;
callout_stop(&chp->ch_callout);
wdc_atapi_start(chp, xfer);
return 1;
}
if ((sc_xfer->xs_control & XS_CTL_POLL) == 0) {
chp->ch_flags |= WDCF_IRQ_WAIT;
xfer->c_intr = wdc_atapi_ctrl;
} else {
goto again;
}
return 1;
timeout:
if (irq && (xfer->c_flags & C_TIMEOU) == 0) {
return 0; /* IRQ was not for us */
}
printf("%s:%d:%d: %s timed out\n",
chp->wdc->sc_dev.dv_xname, chp->channel, xfer->drive, errstring);
sc_xfer->error = XS_TIMEOUT;
wdc_atapi_reset(chp, xfer);
return 1;
error:
printf("%s:%d:%d: %s ",
chp->wdc->sc_dev.dv_xname, chp->channel, xfer->drive,
errstring);
printf("error (0x%x)\n", chp->ch_error);
sc_xfer->error = XS_SHORTSENSE;
sc_xfer->sense.atapi_sense = chp->ch_error;
wdc_atapi_reset(chp, xfer);
return 1;
}
void
wdc_atapi_phase_complete(xfer)
struct wdc_xfer *xfer;
@ -915,15 +900,18 @@ wdc_atapi_phase_complete(xfer)
if (cold)
panic("wdc_atapi_phase_complete: cold");
#endif
if (wdcwait(chp, WDCS_DSC, WDCS_DSC, 10)) {
if (wdcwait(chp, WDCS_DSC, WDCS_DSC, 10,
AT_POLL) == WDCWAIT_TOUT) {
/* 10ms not enough, try again in 1 tick */
if (xfer->c_dscpoll++ >
mstohz(sc_xfer->timeout)) {
printf("%s:%d:%d: wait_for_dsc failed\n",
chp->wdc->sc_dev.dv_xname, chp->channel,
xfer->drive);
printf("%s:%d:%d: wait_for_dsc "
"failed\n",
chp->wdc->sc_dev.dv_xname,
chp->channel, xfer->drive);
sc_xfer->error = XS_TIMEOUT;
wdc_atapi_reset(chp, xfer);
return;
} else
callout_reset(&chp->ch_callout, 1,
wdc_atapi_polldsc, xfer);
@ -950,7 +938,8 @@ wdc_atapi_phase_complete(xfer)
sc_xfer->status = SCSI_CHECK;
} else if (chp->wdc->dma_status &
(WDC_DMAST_NOIRQ | WDC_DMAST_ERR)) {
ata_dmaerr(drvp);
ata_dmaerr(drvp,
(xfer->c_flags & C_POLL) ? AT_POLL : 0);
sc_xfer->error = XS_RESET;
wdc_atapi_reset(chp, xfer);
return;
@ -1003,7 +992,7 @@ wdc_atapi_reset(chp, xfer)
wdccommandshort(chp, xfer->drive, ATAPI_SOFT_RESET);
drvp->state = 0;
if (wait_for_unbusy(chp, WDC_RESET_WAIT) != 0) {
if (wait_for_unbusy(chp, WDC_RESET_WAIT, AT_POLL) != 0) {
printf("%s:%d:%d: reset failed\n",
chp->wdc->sc_dev.dv_xname, chp->channel,
xfer->drive);
@ -1013,7 +1002,7 @@ wdc_atapi_reset(chp, xfer)
return;
}
void
static void
wdc_atapi_polldsc(arg)
void *arg;
{

View File

@ -1,4 +1,4 @@
/* $NetBSD: atapiconf.c,v 1.61 2003/09/18 00:06:31 mycroft Exp $ */
/* $NetBSD: atapiconf.c,v 1.62 2003/10/08 10:58:13 bouyer Exp $ */
/*
* Copyright (c) 1996, 2001 Manuel Bouyer. All rights reserved.
@ -30,7 +30,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: atapiconf.c,v 1.61 2003/09/18 00:06:31 mycroft Exp $");
__KERNEL_RCSID(0, "$NetBSD: atapiconf.c,v 1.62 2003/10/08 10:58:13 bouyer Exp $");
#include <sys/param.h>
#include <sys/systm.h>
@ -112,10 +112,8 @@ atapiprint(aux, pnp)
void *aux;
const char *pnp;
{
struct scsipi_channel *chan = aux;
if (pnp)
aprint_normal("atapibus at %s", pnp);
aprint_normal(" channel %d", chan->chan_channel);
return (UNCONF);
}
@ -133,10 +131,6 @@ atapibusmatch(parent, cf, aux)
if (chan->chan_bustype->bustype_type != SCSIPI_BUSTYPE_ATAPI)
return (0);
if (cf->cf_loc[ATAPICF_CHANNEL] != chan->chan_channel &&
cf->cf_loc[ATAPICF_CHANNEL] != ATAPICF_CHANNEL_DEFAULT)
return (0);
return (1);
}

View File

@ -1,4 +1,4 @@
# $NetBSD: files.scsipi,v 1.36 2003/09/18 00:06:34 mycroft Exp $
# $NetBSD: files.scsipi,v 1.37 2003/10/08 10:58:13 bouyer Exp $
#
# Config file and device description for machine-independent SCSI code.
# Included by ports that need it. Ports that use it must provide
@ -20,7 +20,7 @@ file dev/scsipi/scsipi_ioctl.c scsi_core | atapibus
file dev/scsipi/scsipi_verbose.c (scsi_core | atapibus) & scsiverbose
file dev/scsipi/scsi_base.c scsi_core
file dev/scsipi/atapi_base.c atapibus
file dev/scsipi/atapi_wdc.c atapibus & wdc_base
file dev/scsipi/atapi_wdc.c atapibus & atabus
device scsibus {target = -1, lun = -1}: scsi_core
attach scsibus at scsi

View File

@ -1,4 +1,4 @@
/* $NetBSD: umass_isdata.c,v 1.5 2003/01/27 13:06:38 toshii Exp $ */
/* $NetBSD: umass_isdata.c,v 1.6 2003/10/08 10:58:13 bouyer Exp $ */
/*
* TODO:
@ -44,7 +44,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: umass_isdata.c,v 1.5 2003/01/27 13:06:38 toshii Exp $");
__KERNEL_RCSID(0, "$NetBSD: umass_isdata.c,v 1.6 2003/10/08 10:58:13 bouyer Exp $");
#include <sys/param.h>
#include <sys/systm.h>
@ -115,7 +115,7 @@ int uisdatadebug = 0;
int uisdata_bio(struct ata_drive_datas *, struct ata_bio *);
int uisdata_bio1(struct ata_drive_datas *, struct ata_bio *);
void uisdata_reset_channel(struct ata_drive_datas *);
void uisdata_reset_channel(struct ata_drive_datas *, int);
int uisdata_exec_command(struct ata_drive_datas *, struct wdc_command *);
int uisdata_get_params(struct ata_drive_datas *, u_int8_t, struct ataparams *);
int uisdata_addref(struct ata_drive_datas *);
@ -379,7 +379,7 @@ uisdata_bio1(struct ata_drive_datas *drv, struct ata_bio *ata_bio)
}
void
uisdata_reset_channel(struct ata_drive_datas *drv)
uisdata_reset_channel(struct ata_drive_datas *drv, int flags)
{
DPRINTFN(-1,("%s\n", __func__));
/* XXX what? */