atastart() (called only at splbio(), and from interrupts) can change

drive_flags, to make sure all drive_flags manipulations are done at
splbio().
This commit is contained in:
thorpej 2004-08-21 00:28:34 +00:00
parent b0d8762c07
commit 335b799580
19 changed files with 185 additions and 59 deletions

View File

@ -1,4 +1,4 @@
/* $NetBSD: ata.c,v 1.57 2004/08/20 23:50:13 thorpej Exp $ */
/* $NetBSD: ata.c,v 1.58 2004/08/21 00:28:34 thorpej Exp $ */
/*
* Copyright (c) 1998, 2001 Manuel Bouyer. All rights reserved.
@ -30,7 +30,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: ata.c,v 1.57 2004/08/20 23:50:13 thorpej Exp $");
__KERNEL_RCSID(0, "$NetBSD: ata.c,v 1.58 2004/08/21 00:28:34 thorpej Exp $");
#ifndef ATADEBUG
#define ATADEBUG
@ -167,7 +167,7 @@ atabusconfig(struct atabus_softc *atabus_sc)
{
struct ata_channel *chp = atabus_sc->sc_chan;
struct atac_softc *atac = chp->ch_atac;
int i;
int i, s;
struct atabus_initq *atabus_initq = NULL;
/* Probe for the drives. */
@ -213,8 +213,10 @@ atabusconfig(struct atabus_softc *atabus_sc)
aprint_normal("atapibus at %s not configured\n",
atac->atac_dev.dv_xname);
chp->atapibus = NULL;
s = splbio();
for (i = 0; i < chp->ch_ndrive; i++)
chp->ch_drive[i].drive_flags &= ~DRIVE_ATAPI;
splx(s);
#endif
break;
}
@ -235,9 +237,12 @@ atabusconfig(struct atabus_softc *atabus_sc)
&adev, ataprint);
if (chp->ata_drives[i] != NULL)
ata_probe_caps(&chp->ch_drive[i]);
else
else {
s = splbio();
chp->ch_drive[i].drive_flags &=
~(DRIVE_ATA | DRIVE_OLD);
splx(s);
}
}
/* now that we know the drives, the controller can set its modes */
@ -256,12 +261,14 @@ atabusconfig(struct atabus_softc *atabus_sc)
* reset drive_flags for unattached devices, reset state for attached
* ones
*/
s = splbio();
for (i = 0; i < chp->ch_ndrive; i++) {
if (chp->ch_drive[i].drv_softc == NULL)
chp->ch_drive[i].drive_flags = 0;
else
chp->ch_drive[i].state = 0;
}
splx(s);
out:
if (atabus_initq == NULL) {
@ -1010,7 +1017,7 @@ ata_probe_caps(struct ata_drive_datas *drvp)
struct ata_channel *chp = drvp->chnl_softc;
struct atac_softc *atac = chp->ch_atac;
struct device *drv_dev = drvp->drv_softc;
int i, printed;
int i, printed, s;
char *sep = "";
int cf_flags;
@ -1025,11 +1032,15 @@ ata_probe_caps(struct ata_drive_datas *drvp)
* Re-do an IDENTIFY with 32-bit transfers,
* and compare results.
*/
s = splbio();
drvp->drive_flags |= DRIVE_CAP32;
splx(s);
ata_get_params(drvp, AT_WAIT, &params2);
if (memcmp(&params, &params2, sizeof(struct ataparams)) != 0) {
/* Not good. fall back to 16bits */
s = splbio();
drvp->drive_flags &= ~DRIVE_CAP32;
splx(s);
} else {
aprint_normal("%s: 32-bit data port\n",
drv_dev->dv_xname);
@ -1109,7 +1120,9 @@ ata_probe_caps(struct ata_drive_datas *drvp)
*/
return;
}
s = splbio();
drvp->drive_flags |= DRIVE_MODE;
splx(s);
printed = 0;
for (i = 7; i >= 0; i--) {
if ((params.atap_dmamode_supp & (1 << i)) == 0)
@ -1130,7 +1143,9 @@ ata_probe_caps(struct ata_drive_datas *drvp)
continue;
drvp->DMA_mode = i;
drvp->DMA_cap = i;
s = splbio();
drvp->drive_flags |= DRIVE_DMA;
splx(s);
}
break;
}
@ -1165,7 +1180,9 @@ ata_probe_caps(struct ata_drive_datas *drvp)
continue;
drvp->UDMA_mode = i;
drvp->UDMA_cap = i;
s = splbio();
drvp->drive_flags |= DRIVE_UDMA;
splx(s);
}
break;
}
@ -1173,6 +1190,7 @@ ata_probe_caps(struct ata_drive_datas *drvp)
aprint_normal("\n");
}
s = splbio();
drvp->drive_flags &= ~DRIVE_NOSTREAM;
if (drvp->drive_flags & DRIVE_ATAPI) {
if (atac->atac_cap & ATAC_CAP_ATAPI_NOSTREAM)
@ -1181,6 +1199,7 @@ ata_probe_caps(struct ata_drive_datas *drvp)
if (atac->atac_cap & ATAC_CAP_ATA_NOSTREAM)
drvp->drive_flags |= DRIVE_NOSTREAM;
}
splx(s);
/* Try to guess ATA version here, if it didn't get reported */
if (drvp->ata_vers == 0) {
@ -1191,15 +1210,18 @@ ata_probe_caps(struct ata_drive_datas *drvp)
}
cf_flags = drv_dev->dv_cfdata->cf_flags;
if (cf_flags & ATA_CONFIG_PIO_SET) {
s = splbio();
drvp->PIO_mode =
(cf_flags & ATA_CONFIG_PIO_MODES) >> ATA_CONFIG_PIO_OFF;
drvp->drive_flags |= DRIVE_MODE;
splx(s);
}
if ((atac->atac_cap & ATAC_CAP_DMA) == 0) {
/* don't care about DMA modes */
return;
}
if (cf_flags & ATA_CONFIG_DMA_SET) {
s = splbio();
if ((cf_flags & ATA_CONFIG_DMA_MODES) ==
ATA_CONFIG_DMA_DISABLE) {
drvp->drive_flags &= ~DRIVE_DMA;
@ -1208,12 +1230,14 @@ ata_probe_caps(struct ata_drive_datas *drvp)
ATA_CONFIG_DMA_OFF;
drvp->drive_flags |= DRIVE_DMA | DRIVE_MODE;
}
splx(s);
}
if ((atac->atac_cap & ATAC_CAP_UDMA) == 0) {
/* don't care about UDMA modes */
return;
}
if (cf_flags & ATA_CONFIG_UDMA_SET) {
s = splbio();
if ((cf_flags & ATA_CONFIG_UDMA_MODES) ==
ATA_CONFIG_UDMA_DISABLE) {
drvp->drive_flags &= ~DRIVE_UDMA;
@ -1222,6 +1246,7 @@ ata_probe_caps(struct ata_drive_datas *drvp)
ATA_CONFIG_UDMA_OFF;
drvp->drive_flags |= DRIVE_UDMA | DRIVE_MODE;
}
splx(s);
}
}

View File

@ -1,4 +1,4 @@
/* $NetBSD: wd.c,v 1.290 2004/08/20 17:19:44 thorpej Exp $ */
/* $NetBSD: wd.c,v 1.291 2004/08/21 00:28:34 thorpej 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.290 2004/08/20 17:19:44 thorpej Exp $");
__KERNEL_RCSID(0, "$NetBSD: wd.c,v 1.291 2004/08/21 00:28:34 thorpej Exp $");
#ifndef ATADEBUG
#define ATADEBUG
@ -1017,6 +1017,7 @@ wdgetdisklabel(struct wd_softc *wd)
{
struct disklabel *lp = wd->sc_dk.dk_label;
const char *errstring;
int s;
ATADEBUG_PRINT(("wdgetdisklabel\n"), DEBUG_FUNCS);
@ -1026,8 +1027,11 @@ wdgetdisklabel(struct wd_softc *wd)
wd->sc_badsect[0] = -1;
if (wd->drvp->state > RESET)
if (wd->drvp->state > RESET) {
s = splbio();
wd->drvp->drive_flags |= DRIVE_RESET;
splx(s);
}
errstring = readdisklabel(MAKEWDDEV(0, wd->sc_dev.dv_unit, RAW_PART),
wdstrategy, lp, wd->sc_dk.dk_cpulabel);
if (errstring) {
@ -1037,8 +1041,11 @@ 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 > RESET)
if (wd->drvp->state > RESET) {
s = splbio();
wd->drvp->drive_flags |= DRIVE_RESET;
splx(s);
}
errstring = readdisklabel(MAKEWDDEV(0, wd->sc_dev.dv_unit,
RAW_PART), wdstrategy, lp, wd->sc_dk.dk_cpulabel);
}
@ -1047,8 +1054,11 @@ wdgetdisklabel(struct wd_softc *wd)
return;
}
if (wd->drvp->state > RESET)
if (wd->drvp->state > RESET) {
s = splbio();
wd->drvp->drive_flags |= DRIVE_RESET;
splx(s);
}
#ifdef HAS_BAD144_HANDLING
if ((lp->d_flags & D_BADSECT) != 0)
bad144intern(wd);
@ -1098,7 +1108,7 @@ int
wdioctl(dev_t dev, u_long xfer, caddr_t addr, int flag, struct proc *p)
{
struct wd_softc *wd = device_lookup(&wd_cd, WDUNIT(dev));
int error = 0;
int error = 0, s;
#ifdef __HAVE_OLD_DISKLABEL
struct disklabel *newlabel = NULL;
#endif
@ -1228,8 +1238,11 @@ 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 > RESET)
if (wd->drvp->state > RESET) {
s = splbio();
wd->drvp->drive_flags |= DRIVE_RESET;
splx(s);
}
if (xfer == DIOCWDINFO
#ifdef __HAVE_OLD_DISKLABEL
|| xfer == ODIOCWDINFO

View File

@ -1,4 +1,4 @@
/* $NetBSD: wdc.c,v 1.211 2004/08/20 23:26:54 thorpej Exp $ */
/* $NetBSD: wdc.c,v 1.212 2004/08/21 00:28:34 thorpej Exp $ */
/*
* Copyright (c) 1998, 2001, 2003 Manuel Bouyer. All rights reserved.
@ -70,7 +70,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: wdc.c,v 1.211 2004/08/20 23:26:54 thorpej Exp $");
__KERNEL_RCSID(0, "$NetBSD: wdc.c,v 1.212 2004/08/21 00:28:34 thorpej Exp $");
#ifndef ATADEBUG
#define ATADEBUG
@ -207,7 +207,7 @@ wdc_drvprobe(struct ata_channel *chp)
struct wdc_softc *wdc = CHAN_TO_WDC(chp);
struct wdc_regs *wdr = &wdc->regs[chp->ch_channel];
u_int8_t st0 = 0, st1 = 0;
int i, error;
int i, error, s;
if (wdcprobe1(chp, 0) == 0) {
/* No drives, abort the attach here. */
@ -245,10 +245,12 @@ wdc_drvprobe(struct ata_channel *chp)
break;
tsleep(&params, PRIBIO, "atadrdy", 1);
}
s = splbio();
if ((st0 & WDCS_DRDY) == 0)
chp->ch_drive[0].drive_flags &= ~(DRIVE_ATA|DRIVE_OLD);
if ((st1 & WDCS_DRDY) == 0)
chp->ch_drive[1].drive_flags &= ~(DRIVE_ATA|DRIVE_OLD);
splx(s);
ATADEBUG_PRINT(("%s:%d: wait DRDY st0 0x%x st1 0x%x\n",
atac->atac_dev.dv_xname,
@ -270,8 +272,11 @@ wdc_drvprobe(struct ata_channel *chp)
/* If controller can't do 16bit flag the drives as 32bit */
if ((atac->atac_cap &
(ATAC_CAP_DATA16 | ATAC_CAP_DATA32)) == ATAC_CAP_DATA32)
(ATAC_CAP_DATA16 | ATAC_CAP_DATA32)) == ATAC_CAP_DATA32) {
s = splbio();
chp->ch_drive[i].drive_flags |= DRIVE_CAP32;
splx(s);
}
if ((chp->ch_drive[i].drive_flags & DRIVE) == 0)
continue;
@ -294,11 +299,16 @@ wdc_drvprobe(struct ata_channel *chp)
}
if (error == CMD_OK) {
/* If IDENTIFY succeeded, this is not an OLD ctrl */
s = splbio();
/* XXXJRT ch_ndrive */
chp->ch_drive[0].drive_flags &= ~DRIVE_OLD;
chp->ch_drive[1].drive_flags &= ~DRIVE_OLD;
splx(s);
} else {
s = splbio();
chp->ch_drive[i].drive_flags &=
~(DRIVE_ATA | DRIVE_ATAPI);
splx(s);
ATADEBUG_PRINT(("%s:%d:%d: IDENTIFY failed (%d)\n",
atac->atac_dev.dv_xname,
chp->ch_channel, i, error), DEBUG_PROBE);
@ -326,14 +336,18 @@ wdc_drvprobe(struct ata_channel *chp)
"writability failed\n",
atac->atac_dev.dv_xname,
chp->ch_channel, i), DEBUG_PROBE);
s = splbio();
chp->ch_drive[i].drive_flags &= ~DRIVE_OLD;
splx(s);
continue;
}
if (wdc_wait_for_ready(chp, 10000, 0) == WDCWAIT_TOUT) {
ATADEBUG_PRINT(("%s:%d:%d: not ready\n",
atac->atac_dev.dv_xname,
chp->ch_channel, i), DEBUG_PROBE);
s = splbio();
chp->ch_drive[i].drive_flags &= ~DRIVE_OLD;
splx(s);
continue;
}
bus_space_write_1(wdr->cmd_iot,
@ -343,12 +357,17 @@ wdc_drvprobe(struct ata_channel *chp)
ATADEBUG_PRINT(("%s:%d:%d: WDCC_RECAL failed\n",
atac->atac_dev.dv_xname,
chp->ch_channel, i), DEBUG_PROBE);
s = splbio();
chp->ch_drive[i].drive_flags &= ~DRIVE_OLD;
splx(s);
} else {
s = splbio();
/* XXXJRT ch_ndrive */
chp->ch_drive[0].drive_flags &=
~(DRIVE_ATA | DRIVE_ATAPI);
chp->ch_drive[1].drive_flags &=
~(DRIVE_ATA | DRIVE_ATAPI);
splx(s);
}
}
}
@ -628,6 +647,7 @@ wdcprobe1(struct ata_channel *chp, int poll)
* sc & sn are supposted to be 0x1 for ATAPI but in some cases
* we get wrong values here, so ignore it.
*/
s = splbio();
if (cl == 0x14 && ch == 0xeb) {
chp->ch_drive[drive].drive_flags |= DRIVE_ATAPI;
} else {
@ -636,6 +656,7 @@ wdcprobe1(struct ata_channel *chp, int poll)
(wdc->cap & WDC_CAPABILITY_PREATA) != 0)
chp->ch_drive[drive].drive_flags |= DRIVE_OLD;
}
splx(s);
}
return (ret_value);
}

View File

@ -1,4 +1,4 @@
/* $NetBSD: acardide.c,v 1.13 2004/08/20 06:39:38 thorpej Exp $ */
/* $NetBSD: acardide.c,v 1.14 2004/08/21 00:28:34 thorpej Exp $ */
/*
* Copyright (c) 2001 Izumi Tsutsui.
@ -183,7 +183,7 @@ acard_setup_channel(struct ata_channel *chp)
struct pciide_channel *cp = CHAN_TO_PCHAN(chp);
struct pciide_softc *sc = CHAN_TO_PCIIDE(chp);
int channel = chp->ch_channel;
int drive;
int drive, s;
u_int32_t idetime, udma_mode;
u_int32_t idedma_ctl;
@ -242,7 +242,9 @@ acard_setup_channel(struct ata_channel *chp)
} else if ((atac->atac_cap & ATAC_CAP_DMA) &&
(drvp->drive_flags & DRIVE_DMA)) {
/* use Multiword DMA */
s = splbio();
drvp->drive_flags &= ~DRIVE_UDMA;
splx(s);
if (ACARD_IS_850(sc)) {
idetime |= ATP850_SETTIME(drive,
acard_act_dma[drvp->DMA_mode],
@ -255,7 +257,9 @@ acard_setup_channel(struct ata_channel *chp)
idedma_ctl |= IDEDMA_CTL_DRV_DMA(drive);
} else {
/* PIO only */
s = splbio();
drvp->drive_flags &= ~(DRIVE_UDMA | DRIVE_DMA);
splx(s);
if (ACARD_IS_850(sc)) {
idetime |= ATP850_SETTIME(drive,
acard_act_pio[drvp->PIO_mode],

View File

@ -1,4 +1,4 @@
/* $NetBSD: aceride.c,v 1.12 2004/08/20 06:39:38 thorpej Exp $ */
/* $NetBSD: aceride.c,v 1.13 2004/08/21 00:28:34 thorpej Exp $ */
/*
* Copyright (c) 1999, 2000, 2001 Manuel Bouyer.
@ -173,7 +173,7 @@ static void
acer_setup_channel(struct ata_channel *chp)
{
struct ata_drive_datas *drvp;
int drive;
int drive, s;
u_int32_t acer_fifo_udma;
u_int32_t idedma_ctl;
struct pciide_channel *cp = (struct pciide_channel*)chp;
@ -222,7 +222,9 @@ acer_setup_channel(struct ata_channel *chp)
acer_fifo_udma |= ACER_FTH_OPL(chp->ch_channel, drive, 0x2);
if (drvp->drive_flags & DRIVE_UDMA) {
/* use Ultra/DMA */
s = splbio();
drvp->drive_flags &= ~DRIVE_DMA;
splx(s);
acer_fifo_udma |= ACER_UDMA_EN(chp->ch_channel, drive);
acer_fifo_udma |=
ACER_UDMA_TIM(chp->ch_channel, drive,

View File

@ -1,4 +1,4 @@
/* $NetBSD: cmdide.c,v 1.16 2004/08/20 06:39:38 thorpej Exp $ */
/* $NetBSD: cmdide.c,v 1.17 2004/08/21 00:28:34 thorpej Exp $ */
/*
* Copyright (c) 1999, 2000, 2001 Manuel Bouyer.
@ -364,7 +364,7 @@ cmd0643_9_setup_channel(struct ata_channel *chp)
struct ata_drive_datas *drvp;
u_int8_t tim;
u_int32_t idedma_ctl, udma_reg;
int drive;
int drive, s;
struct pciide_channel *cp = CHAN_TO_PCHAN(chp);
struct pciide_softc *sc = CHAN_TO_PCIIDE(chp);
@ -382,7 +382,9 @@ cmd0643_9_setup_channel(struct ata_channel *chp)
if (drvp->drive_flags & (DRIVE_DMA | DRIVE_UDMA)) {
if (drvp->drive_flags & DRIVE_UDMA) {
/* UltraDMA on a 646U2, 0648 or 0649 */
s = splbio();
drvp->drive_flags &= ~DRIVE_DMA;
splx(s);
udma_reg = pciide_pci_read(sc->sc_pc,
sc->sc_tag, CMD_UDMATIM(chp->ch_channel));
if (drvp->UDMA_mode > 2 &&
@ -546,7 +548,7 @@ cmd680_setup_channel(struct ata_channel *chp)
u_int8_t mode, off, scsc;
u_int16_t val;
u_int32_t idedma_ctl;
int drive;
int drive, s;
struct pciide_channel *cp = CHAN_TO_PCHAN(chp);
struct pciide_softc *sc = CHAN_TO_PCIIDE(chp);
pci_chipset_tag_t pc = sc->sc_pc;
@ -571,7 +573,9 @@ cmd680_setup_channel(struct ata_channel *chp)
continue;
mode &= ~(0x03 << (drive * 4));
if (drvp->drive_flags & DRIVE_UDMA) {
s = splbio();
drvp->drive_flags &= ~DRIVE_DMA;
splx(s);
off = 0xa0 + chp->ch_channel * 16;
if (drvp->UDMA_mode > 2 &&
(pciide_pci_read(pc, pa, off) & 0x01) == 0)

View File

@ -1,4 +1,4 @@
/* $NetBSD: geodeide.c,v 1.6 2004/08/20 06:39:39 thorpej Exp $ */
/* $NetBSD: geodeide.c,v 1.7 2004/08/21 00:28:34 thorpej Exp $ */
/*
* Copyright (c) 2004 Manuel Bouyer.
@ -37,7 +37,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: geodeide.c,v 1.6 2004/08/20 06:39:39 thorpej Exp $");
__KERNEL_RCSID(0, "$NetBSD: geodeide.c,v 1.7 2004/08/21 00:28:34 thorpej Exp $");
#include <sys/param.h>
#include <sys/systm.h>
@ -163,7 +163,7 @@ geodeide_setup_channel(struct ata_channel *chp)
struct pciide_channel *cp = CHAN_TO_PCHAN(chp);
struct pciide_softc *sc = CHAN_TO_PCIIDE(chp);
int channel = chp->ch_channel;
int drive;
int drive, s;
u_int32_t dma_timing;
u_int8_t idedma_ctl;
const int32_t *geode_pio;
@ -224,7 +224,9 @@ geodeide_setup_channel(struct ata_channel *chp)
idedma_ctl |= IDEDMA_CTL_DRV_DMA(drive);
} else {
/* PIO only */
s = splbio();
drvp->drive_flags &= ~(DRIVE_UDMA | DRIVE_DMA);
splx(s);
}
switch (sc->sc_pp->ide_product) {

View File

@ -1,4 +1,4 @@
/* $NetBSD: hptide.c,v 1.15 2004/08/20 06:39:39 thorpej Exp $ */
/* $NetBSD: hptide.c,v 1.16 2004/08/21 00:28:34 thorpej Exp $ */
/*
* Copyright (c) 1999, 2000, 2001 Manuel Bouyer.
@ -275,7 +275,7 @@ static void
hpt_setup_channel(struct ata_channel *chp)
{
struct ata_drive_datas *drvp;
int drive;
int drive, s;
int cable;
u_int32_t before, after;
u_int32_t idedma_ctl;
@ -341,7 +341,9 @@ hpt_setup_channel(struct ata_channel *chp)
/* add timing values, setup DMA if needed */
if (drvp->drive_flags & DRIVE_UDMA) {
/* use Ultra/DMA */
s = splbio();
drvp->drive_flags &= ~DRIVE_DMA;
splx(s);
if ((cable & HPT_CSEL_CBLID(chp->ch_channel)) != 0 &&
drvp->UDMA_mode > 2)
drvp->UDMA_mode = 2;

View File

@ -1,4 +1,4 @@
/* $NetBSD: optiide.c,v 1.9 2004/08/20 06:39:39 thorpej Exp $ */
/* $NetBSD: optiide.c,v 1.10 2004/08/21 00:28:34 thorpej Exp $ */
/*-
* Copyright (c) 2000 The NetBSD Foundation, Inc.
@ -175,7 +175,7 @@ opti_setup_channel(struct ata_channel *chp)
struct ata_drive_datas *drvp;
struct pciide_channel *cp = CHAN_TO_PCHAN(chp);
struct pciide_softc *sc = CHAN_TO_PCIIDE(chp);
int drive, spd;
int drive, spd, s;
int mode[2];
u_int8_t rv, mr;
@ -236,7 +236,9 @@ opti_setup_channel(struct ata_channel *chp)
mode[d] = mode[1-d];
chp->ch_drive[d].PIO_mode = chp->ch_drive[1-d].PIO_mode;
chp->ch_drive[d].DMA_mode = 0;
s = splbio();
chp->ch_drive[d].drive_flags &= ~DRIVE_DMA;
splx(s);
}
}

View File

@ -1,4 +1,4 @@
/* $NetBSD: pciide_common.c,v 1.20 2004/08/20 06:39:39 thorpej Exp $ */
/* $NetBSD: pciide_common.c,v 1.21 2004/08/21 00:28:34 thorpej Exp $ */
/*
@ -76,7 +76,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: pciide_common.c,v 1.20 2004/08/20 06:39:39 thorpej Exp $");
__KERNEL_RCSID(0, "$NetBSD: pciide_common.c,v 1.21 2004/08/21 00:28:34 thorpej Exp $");
#include <sys/param.h>
#include <sys/malloc.h>
@ -491,7 +491,7 @@ void
pciide_channel_dma_setup(cp)
struct pciide_channel *cp;
{
int drive;
int drive, s;
struct pciide_softc *sc = CHAN_TO_PCIIDE(&cp->ata_channel);
struct ata_drive_datas *drvp;
@ -506,13 +506,17 @@ pciide_channel_dma_setup(cp)
if (((drvp->drive_flags & DRIVE_DMA) == 0 &&
(drvp->drive_flags & DRIVE_UDMA) == 0) ||
sc->sc_dma_ok == 0) {
s = splbio();
drvp->drive_flags &= ~(DRIVE_DMA | DRIVE_UDMA);
splx(s);
continue;
}
if (pciide_dma_table_setup(sc, cp->ata_channel.ch_channel,
drive) != 0) {
/* Abort DMA setup */
s = splbio();
drvp->drive_flags &= ~(DRIVE_DMA | DRIVE_UDMA);
splx(s);
continue;
}
}
@ -830,7 +834,7 @@ default_chip_map(sc, pa)
struct pciide_channel *cp;
pcireg_t interface = PCI_INTERFACE(pa->pa_class);
pcireg_t csr;
int channel, drive;
int channel, drive, s;
struct ata_drive_datas *drvp;
u_int8_t idedma_ctl;
bus_size_t cmdsize, ctlsize;
@ -957,7 +961,9 @@ next:
"using PIO transfers\n",
sc->sc_wdcdev.sc_atac.atac_dev.dv_xname,
channel, drive);
s = splbio();
drvp->drive_flags &= ~DRIVE_DMA;
splx(s);
}
aprint_normal("%s:%d:%d: using DMA data transfers\n",
sc->sc_wdcdev.sc_atac.atac_dev.dv_xname,
@ -977,7 +983,7 @@ sata_setup_channel(chp)
struct ata_channel *chp;
{
struct ata_drive_datas *drvp;
int drive;
int drive, s;
u_int32_t idedma_ctl;
struct pciide_channel *cp = CHAN_TO_PCHAN(chp);
struct pciide_softc *sc = CHAN_TO_PCIIDE(chp);
@ -994,7 +1000,9 @@ sata_setup_channel(chp)
continue;
if (drvp->drive_flags & DRIVE_UDMA) {
/* use Ultra/DMA */
s = splbio();
drvp->drive_flags &= ~DRIVE_DMA;
splx(s);
idedma_ctl |= IDEDMA_CTL_DRV_DMA(drive);
} else if (drvp->drive_flags & DRIVE_DMA) {
idedma_ctl |= IDEDMA_CTL_DRV_DMA(drive);

View File

@ -1,4 +1,4 @@
/* $NetBSD: pdcide.c,v 1.17 2004/08/20 06:39:39 thorpej Exp $ */
/* $NetBSD: pdcide.c,v 1.18 2004/08/21 00:28:34 thorpej Exp $ */
/*
* Copyright (c) 1999, 2000, 2001 Manuel Bouyer.
@ -326,7 +326,7 @@ static void
pdc202xx_setup_channel(struct ata_channel *chp)
{
struct ata_drive_datas *drvp;
int drive;
int drive, s;
pcireg_t mode, st;
u_int32_t idedma_ctl, scr, atapi;
struct pciide_channel *cp = CHAN_TO_PCHAN(chp);
@ -395,7 +395,9 @@ pdc202xx_setup_channel(struct ata_channel *chp)
mode = 0;
if (drvp->drive_flags & DRIVE_UDMA) {
/* use Ultra/DMA */
s = splbio();
drvp->drive_flags &= ~DRIVE_DMA;
splx(s);
mode = PDC2xx_TIM_SET_MB(mode,
pdc2xx_udma_mb[drvp->UDMA_mode]);
mode = PDC2xx_TIM_SET_MC(mode,
@ -441,7 +443,7 @@ static void
pdc20268_setup_channel(struct ata_channel *chp)
{
struct ata_drive_datas *drvp;
int drive;
int drive, s;
u_int32_t idedma_ctl;
struct pciide_channel *cp = CHAN_TO_PCHAN(chp);
struct pciide_softc *sc = CHAN_TO_PCIIDE(chp);
@ -470,7 +472,9 @@ pdc20268_setup_channel(struct ata_channel *chp)
continue;
if (drvp->drive_flags & DRIVE_UDMA) {
/* use Ultra/DMA */
s = splbio();
drvp->drive_flags &= ~DRIVE_DMA;
splx(s);
idedma_ctl |= IDEDMA_CTL_DRV_DMA(drive);
if (drvp->UDMA_mode > 2 && u100 == 0)
drvp->UDMA_mode = 2;

View File

@ -1,4 +1,4 @@
/* $NetBSD: piixide.c,v 1.14 2004/08/20 06:39:39 thorpej Exp $ */
/* $NetBSD: piixide.c,v 1.15 2004/08/21 00:28:34 thorpej Exp $ */
/*
* Copyright (c) 1999, 2000, 2001 Manuel Bouyer.
@ -441,7 +441,7 @@ piix3_4_setup_channel(struct ata_channel *chp)
struct pciide_channel *cp = CHAN_TO_PCHAN(chp);
struct pciide_softc *sc = CHAN_TO_PCIIDE(chp);
struct wdc_softc *wdc = &sc->sc_wdcdev;
int drive;
int drive, s;
int channel = chp->ch_channel;
oidetim = pci_conf_read(sc->sc_pc, sc->sc_tag, PIIX_IDETIM);
@ -520,13 +520,17 @@ piix3_4_setup_channel(struct ata_channel *chp)
if ((wdc->sc_atac.atac_cap & ATAC_CAP_UDMA) &&
(drvp->drive_flags & DRIVE_UDMA)) {
/* use Ultra/DMA */
s = splbio();
drvp->drive_flags &= ~DRIVE_DMA;
splx(s);
udmareg |= PIIX_UDMACTL_DRV_EN( channel, drive);
udmareg |= PIIX_UDMATIM_SET(
piix4_sct_udma[drvp->UDMA_mode], channel, drive);
} else {
/* use Multiword DMA */
s = splbio();
drvp->drive_flags &= ~DRIVE_UDMA;
splx(s);
if (drive == 0) {
idetim |= piix_setup_idetim_timings(
drvp->DMA_mode, 1, channel);

View File

@ -1,4 +1,4 @@
/* $NetBSD: rccide.c,v 1.11 2004/08/20 06:39:39 thorpej Exp $ */
/* $NetBSD: rccide.c,v 1.12 2004/08/21 00:28:34 thorpej Exp $ */
/*
* Copyright (c) 2003 By Noon Software, Inc. All rights reserved.
@ -27,7 +27,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: rccide.c,v 1.11 2004/08/20 06:39:39 thorpej Exp $");
__KERNEL_RCSID(0, "$NetBSD: rccide.c,v 1.12 2004/08/21 00:28:34 thorpej Exp $");
#include <sys/param.h>
#include <sys/systm.h>
@ -178,7 +178,7 @@ serverworks_setup_channel(struct ata_channel *chp)
struct pciide_channel *cp = CHAN_TO_PCHAN(chp);
struct pciide_softc *sc = CHAN_TO_PCIIDE(chp);
int channel = chp->ch_channel;
int drive, unit;
int drive, unit, s;
u_int32_t pio_time, dma_time, pio_mode, udma_mode;
u_int32_t idedma_ctl;
static const u_int8_t pio_modes[5] = {0x5d, 0x47, 0x34, 0x22, 0x20};
@ -225,12 +225,16 @@ serverworks_setup_channel(struct ata_channel *chp)
} else if ((atac->atac_cap & ATAC_CAP_DMA) &&
(drvp->drive_flags & DRIVE_DMA)) {
/* use Multiword DMA */
s = splbio();
drvp->drive_flags &= ~DRIVE_UDMA;
splx(s);
dma_time |= dma_modes[drvp->DMA_mode] << (8 * (unit^1));
idedma_ctl |= IDEDMA_CTL_DRV_DMA(drive);
} else {
/* PIO only */
s = splbio();
drvp->drive_flags &= ~(DRIVE_UDMA | DRIVE_DMA);
splx(s);
}
}

View File

@ -1,4 +1,4 @@
/* $NetBSD: satalink.c,v 1.21 2004/08/20 06:39:39 thorpej Exp $ */
/* $NetBSD: satalink.c,v 1.22 2004/08/21 00:28:34 thorpej Exp $ */
/*-
* Copyright (c) 2003 The NetBSD Foundation, Inc.
@ -769,7 +769,7 @@ sii3112_drv_probe(struct ata_channel *chp)
struct wdc_regs *wdr = CHAN_TO_WDC_REGS(chp);
uint32_t scontrol, sstatus;
uint8_t scnt, sn, cl, ch;
int i;
int i, s;
/* XXX This should be done by other code. */
for (i = 0; i < 2; i++) {
@ -852,10 +852,12 @@ sii3112_drv_probe(struct ata_channel *chp)
* scnt and sn are supposed to be 0x1 for ATAPI, but in some
* cases we get wrong values here, so ignore it.
*/
s = splbio();
if (cl == 0x14 && ch == 0xeb)
chp->ch_drive[0].drive_flags |= DRIVE_ATAPI;
else
chp->ch_drive[0].drive_flags |= DRIVE_ATA;
splx(s);
aprint_normal("%s: port %d: device present, speed: %s\n",
sc->sc_wdcdev.sc_atac.atac_dev.dv_xname, chp->ch_channel,
@ -872,7 +874,7 @@ static void
sii3112_setup_channel(struct ata_channel *chp)
{
struct ata_drive_datas *drvp;
int drive;
int drive, s;
u_int32_t idedma_ctl, dtm;
struct pciide_channel *cp = CHAN_TO_PCHAN(chp);
struct pciide_softc *sc = CHAN_TO_PCIIDE(chp);
@ -890,7 +892,9 @@ sii3112_setup_channel(struct ata_channel *chp)
continue;
if (drvp->drive_flags & DRIVE_UDMA) {
/* use Ultra/DMA */
s = splbio();
drvp->drive_flags &= ~DRIVE_DMA;
splx(s);
idedma_ctl |= IDEDMA_CTL_DRV_DMA(drive);
dtm |= DTM_IDEx_DMA;
} else if (drvp->drive_flags & DRIVE_DMA) {

View File

@ -1,4 +1,4 @@
/* $NetBSD: siside.c,v 1.12 2004/08/20 06:39:39 thorpej Exp $ */
/* $NetBSD: siside.c,v 1.13 2004/08/21 00:28:34 thorpej Exp $ */
/*
* Copyright (c) 1999, 2000, 2001 Manuel Bouyer.
@ -304,7 +304,7 @@ static void
sis96x_setup_channel(struct ata_channel *chp)
{
struct ata_drive_datas *drvp;
int drive;
int drive, s;
u_int32_t sis_tim;
u_int32_t idedma_ctl;
int regtim;
@ -327,7 +327,9 @@ sis96x_setup_channel(struct ata_channel *chp)
/* add timing values, setup DMA if needed */
if (drvp->drive_flags & DRIVE_UDMA) {
/* use Ultra/DMA */
s = splbio();
drvp->drive_flags &= ~DRIVE_DMA;
splx(s);
if (pciide_pci_read(sc->sc_pc, sc->sc_tag,
SIS96x_REG_CBL(chp->ch_channel)) & SIS96x_REG_CBL_33) {
if (drvp->UDMA_mode > 2)
@ -368,7 +370,7 @@ static void
sis_setup_channel(struct ata_channel *chp)
{
struct ata_drive_datas *drvp;
int drive;
int drive, s;
u_int32_t sis_tim;
u_int32_t idedma_ctl;
struct pciide_channel *cp = CHAN_TO_PCHAN(chp);
@ -395,7 +397,9 @@ sis_setup_channel(struct ata_channel *chp)
if (drvp->drive_flags & DRIVE_UDMA) {
/* use Ultra/DMA */
s = splbio();
drvp->drive_flags &= ~DRIVE_DMA;
splx(s);
if (pciide_pci_read(sc->sc_pc, sc->sc_tag,
SIS_REG_CBL) & SIS_REG_CBL_33(chp->ch_channel)) {
if (drvp->UDMA_mode > 2)

View File

@ -1,4 +1,4 @@
/* $NetBSD: slide.c,v 1.8 2004/08/20 06:39:39 thorpej Exp $ */
/* $NetBSD: slide.c,v 1.9 2004/08/21 00:28:34 thorpej Exp $ */
/*-
* Copyright (c) 2002 The NetBSD Foundation, Inc.
@ -190,7 +190,7 @@ sl82c105_setup_channel(struct ata_channel *chp)
struct ata_drive_datas *drvp;
struct pciide_channel *cp = CHAN_TO_PCHAN(chp);
struct pciide_softc *sc = CHAN_TO_PCIIDE(chp);
int pxdx_reg, drive;
int pxdx_reg, drive, s;
pcireg_t pxdx;
/* Set up DMA if needed. */
@ -226,14 +226,18 @@ sl82c105_setup_channel(struct ata_channel *chp)
* Can't mix both PIO and DMA.
* Disable DMA.
*/
s = splbio();
drvp->drive_flags &= ~DRIVE_DMA;
splx(s);
}
} else {
/*
* Can't mix both PIO and DMA. Disable
* DMA.
*/
s = splbio();
drvp->drive_flags &= ~DRIVE_DMA;
splx(s);
}
}

View File

@ -1,4 +1,4 @@
/* $NetBSD: stpcide.c,v 1.8 2004/08/20 06:39:39 thorpej Exp $ */
/* $NetBSD: stpcide.c,v 1.9 2004/08/21 00:28:34 thorpej Exp $ */
/*
* Copyright (c) 2003 Toru Nishimura
@ -142,7 +142,7 @@ stpc_setup_channel(struct ata_channel *chp)
int channel = chp->ch_channel;
struct ata_drive_datas *drvp;
u_int32_t idedma_ctl, idetim;
int drive, bits[2];
int drive, bits[2], s;
/* setup DMA if needed */
pciide_channel_dma_setup(cp);
@ -160,13 +160,17 @@ stpc_setup_channel(struct ata_channel *chp)
if ((atac->atac_cap & ATAC_CAP_DMA) &&
(drvp->drive_flags & DRIVE_DMA)) {
/* use Multiword DMA */
s = splbio();
drvp->drive_flags &= ~DRIVE_UDMA;
splx(s);
idedma_ctl |= IDEDMA_CTL_DRV_DMA(drive);
bits[drive] = 0xe; /* IOCHRDY,wr/post,rd/prefetch */
}
else {
/* PIO only */
s = splbio();
drvp->drive_flags &= ~(DRIVE_UDMA | DRIVE_DMA);
splx(s);
bits[drive] = 0x8; /* IOCHRDY */
}
bits[drive] |= dmatbl[drvp->DMA_mode] | piotbl[drvp->PIO_mode];

View File

@ -1,4 +1,4 @@
/* $NetBSD: viaide.c,v 1.17 2004/08/20 06:39:39 thorpej Exp $ */
/* $NetBSD: viaide.c,v 1.18 2004/08/21 00:28:34 thorpej Exp $ */
/*
* Copyright (c) 1999, 2000, 2001 Manuel Bouyer.
@ -341,7 +341,7 @@ via_setup_channel(struct ata_channel *chp)
{
u_int32_t udmatim_reg, datatim_reg;
u_int8_t idedma_ctl;
int mode, drive;
int mode, drive, s;
struct ata_drive_datas *drvp;
struct atac_softc *atac = chp->ch_atac;
struct pciide_channel *cp = CHAN_TO_PCHAN(chp);
@ -374,7 +374,9 @@ via_setup_channel(struct ata_channel *chp)
if ((atac->atac_cap & ATAC_CAP_UDMA) &&
(drvp->drive_flags & DRIVE_UDMA)) {
/* use Ultra/DMA */
s = splbio();
drvp->drive_flags &= ~DRIVE_DMA;
splx(s);
udmatim_reg |= APO_UDMA_EN(chp->ch_channel, drive) |
APO_UDMA_EN_MTH(chp->ch_channel, drive);
switch (PCI_VENDOR(sc->sc_pci_id)) {
@ -417,7 +419,9 @@ via_setup_channel(struct ata_channel *chp)
mode = drvp->PIO_mode;
} else {
/* use Multiword DMA, but only if revision is OK */
s = splbio();
drvp->drive_flags &= ~DRIVE_UDMA;
splx(s);
#ifndef PCIIDE_AMD756_ENABLEDMA
/*
* The workaround doesn't seem to be necessary
@ -435,7 +439,9 @@ via_setup_channel(struct ata_channel *chp)
sc->sc_wdcdev.sc_atac.atac_dev.dv_xname,
chp->ch_channel, drive);
mode = drvp->PIO_mode;
s = splbio();
drvp->drive_flags &= ~DRIVE_DMA;
splx(s);
goto pio;
}
#endif

View File

@ -1,4 +1,4 @@
/* $NetBSD: atapi_wdc.c,v 1.88 2004/08/20 06:39:39 thorpej Exp $ */
/* $NetBSD: atapi_wdc.c,v 1.89 2004/08/21 00:28:34 thorpej Exp $ */
/*
* Copyright (c) 1998, 2001 Manuel Bouyer.
@ -30,7 +30,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: atapi_wdc.c,v 1.88 2004/08/20 06:39:39 thorpej Exp $");
__KERNEL_RCSID(0, "$NetBSD: atapi_wdc.c,v 1.89 2004/08/21 00:28:34 thorpej Exp $");
#ifndef ATADEBUG
#define ATADEBUG
@ -255,6 +255,7 @@ wdc_atapi_probe_device(struct atapibus_softc *sc, int target)
struct ata_drive_datas *drvp = &chp->ch_drive[target];
struct scsipibus_attach_args sa;
char serial_number[21], model[41], firmware_revision[9];
int s;
/* skip if already attached */
if (scsipi_lookup_periph(chan, target, 0) != NULL)
@ -288,8 +289,11 @@ wdc_atapi_probe_device(struct atapibus_softc *sc, int target)
periph->periph_type = ATAPI_CFG_TYPE(id->atap_config);
if (id->atap_config & ATAPI_CFG_REMOV)
periph->periph_flags |= PERIPH_REMOVABLE;
if (periph->periph_type == T_SEQUENTIAL)
if (periph->periph_type == T_SEQUENTIAL) {
s = splbio();
drvp->drive_flags |= DRIVE_ATAPIST;
splx(s);
}
sa.sa_periph = periph;
sa.sa_inqbuf.type = ATAPI_CFG_TYPE(id->atap_config);
@ -314,10 +318,15 @@ wdc_atapi_probe_device(struct atapibus_softc *sc, int target)
if (drvp->drv_softc)
ata_probe_caps(drvp);
else
else {
s = splbio();
drvp->drive_flags &= ~DRIVE_ATAPI;
splx(s);
}
} else {
s = splbio();
drvp->drive_flags &= ~DRIVE_ATAPI;
splx(s);
}
}