From aee187e7a26ea9ba93b45c0bbcd0fdd490c6c497 Mon Sep 17 00:00:00 2001 From: bouyer Date: Tue, 31 Jul 2012 15:50:31 +0000 Subject: Apply back changes that were reverted on Jul 24 and Jul 26 (general ata/wdc cleanup and SATA PMP support), now that I'm back to fix the fallouts. --- sys/dev/ata/ata.c | 283 ++++++++++++++++++++++++++++------------ sys/dev/ata/ata_wdc.c | 24 ++-- sys/dev/ata/atavar.h | 47 +++---- sys/dev/ata/files.ata | 5 +- sys/dev/ata/sata_subr.c | 55 +++++++- sys/dev/ata/satapmpreg.h | 7 +- sys/dev/ata/satavar.h | 3 +- sys/dev/ata/wd.c | 40 ++++-- sys/dev/ic/ahcisata_core.c | 309 ++++++++++++++++++++++++++++++++++---------- sys/dev/ic/ahcisatavar.h | 3 +- sys/dev/ic/mvsata.c | 86 ++++++------ sys/dev/ic/ninjaata32.c | 14 +- sys/dev/ic/siisata.c | 164 +++++++++++------------ sys/dev/ic/wdc.c | 152 +++++++++++----------- sys/dev/ic/wdc_upc.c | 6 +- sys/dev/ic/wdcvar.h | 10 +- sys/dev/isa/wdc_isa.c | 6 +- sys/dev/isapnp/wdc_isapnp.c | 6 +- sys/dev/mca/ed_mca.c | 8 +- sys/dev/ofisa/wdc_ofisa.c | 6 +- sys/dev/pci/acardide.c | 19 +-- sys/dev/pci/aceride.c | 17 +-- sys/dev/pci/artsata.c | 6 +- sys/dev/pci/cmdide.c | 24 ++-- sys/dev/pci/cypide.c | 10 +- sys/dev/pci/geodeide.c | 13 +- sys/dev/pci/hptide.c | 15 ++- sys/dev/pci/iteide.c | 15 ++- sys/dev/pci/ixpide.c | 13 +- sys/dev/pci/jmide.c | 13 +- sys/dev/pci/nside.c | 9 +- sys/dev/pci/optiide.c | 11 +- sys/dev/pci/pciide_common.c | 35 ++--- sys/dev/pci/pciidevar.h | 4 +- sys/dev/pci/pdcide.c | 63 ++++----- sys/dev/pci/pdcsata.c | 14 +- sys/dev/pci/piixide.c | 36 +++--- sys/dev/pci/rccide.c | 15 ++- sys/dev/pci/rdcide.c | 13 +- sys/dev/pci/satalink.c | 29 ++--- sys/dev/pci/schide.c | 15 ++- sys/dev/pci/siside.c | 24 ++-- sys/dev/pci/slide.c | 15 ++- sys/dev/pci/stpcide.c | 13 +- sys/dev/pci/svwsata.c | 5 +- sys/dev/pci/toshide.c | 13 +- sys/dev/pci/viaide.c | 26 ++-- sys/dev/pcmcia/wdc_pcmcia.c | 10 +- sys/dev/podulebus/dtide.c | 6 +- sys/dev/podulebus/hcide.c | 6 +- sys/dev/scsipi/atapi_wdc.c | 28 ++-- sys/dev/usb/umass_isdata.c | 11 +- 52 files changed, 1088 insertions(+), 692 deletions(-) (limited to 'sys/dev') diff --git a/sys/dev/ata/ata.c b/sys/dev/ata/ata.c index a83e2a0e041..d26d9cc6d93 100644 --- a/sys/dev/ata/ata.c +++ b/sys/dev/ata/ata.c @@ -1,4 +1,4 @@ -/* $NetBSD: ata.c,v 1.123 2012/07/29 21:10:50 jakllsch Exp $ */ +/* $NetBSD: ata.c,v 1.124 2012/07/31 15:50:34 bouyer Exp $ */ /* * Copyright (c) 1998, 2001 Manuel Bouyer. All rights reserved. @@ -25,7 +25,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: ata.c,v 1.123 2012/07/29 21:10:50 jakllsch Exp $"); +__KERNEL_RCSID(0, "$NetBSD: ata.c,v 1.124 2012/07/31 15:50:34 bouyer Exp $"); #include "opt_ata.h" @@ -55,10 +55,15 @@ __KERNEL_RCSID(0, "$NetBSD: ata.c,v 1.123 2012/07/29 21:10:50 jakllsch Exp $"); #include "atapibus.h" #include "ataraid.h" +#include "sata_pmp.h" #if NATARAID > 0 #include #endif +#if NSATA_PMP > 0 +#include +#endif +#include #define DEBUG_FUNCS 0x08 #define DEBUG_PROBE 0x10 @@ -199,13 +204,19 @@ atabusconfig(struct atabus_softc *atabus_sc) chp->ch_flags |= ATACH_TH_RUN; splx(s); - /* Probe for the drives. */ + /* + * Probe for the drives attached to controller, unless a PMP + * is already known + */ /* XXX for SATA devices we will power up all drives at once */ - (*atac->atac_probe)(chp); + if (chp->ch_satapmp_nports == 0) + (*atac->atac_probe)(chp); - ATADEBUG_PRINT(("atabusattach: ch_drive_flags 0x%x 0x%x\n", - chp->ch_drive[0].drive_flags, chp->ch_drive[1].drive_flags), - DEBUG_PROBE); + if (chp->ch_drive != NULL && chp->ch_ndrives >= 2) { + ATADEBUG_PRINT(("atabusattach: ch_drive_type 0x%x 0x%x\n", + chp->ch_drive[0].drive_type, chp->ch_drive[1].drive_type), + DEBUG_PROBE); + } /* next operations will occurs in a separate thread */ s = splbio(); @@ -223,17 +234,19 @@ atabusconfig(struct atabus_softc *atabus_sc) mutex_exit(&atabus_qlock); /* If no drives, abort here */ - for (i = 0; i < chp->ch_ndrive; i++) - if ((chp->ch_drive[i].drive_flags & DRIVE) != 0) + if (chp->ch_drive == NULL) + goto out; + KASSERT(chp->ch_ndrives == 0 || chp->ch_drive != NULL); + for (i = 0; i < chp->ch_ndrives; i++) + if (chp->ch_drive[i].drive_type != ATA_DRIVET_NONE) break; - if (i == chp->ch_ndrive) + if (i == chp->ch_ndrives) goto out; /* Shortcut in case we've been shutdown */ if (chp->ch_flags & ATACH_SHUTDOWN) goto out; - if ((error = kthread_create(PRI_NONE, 0, NULL, atabusconfig_thread, atabus_sc, &atabus_cfg_lwp, "%scnf", device_xname(atac->atac_dev))) != 0) @@ -273,11 +286,26 @@ atabusconfig_thread(void *arg) KASSERT(atabus_initq->atabus_sc == atabus_sc); mutex_exit(&atabus_qlock); + /* + * First look for a port multiplier + */ + if (chp->ch_ndrives == PMP_MAX_DRIVES && + chp->ch_drive[PMP_PORT_CTL].drive_type == ATA_DRIVET_PM) { +#if NSATA_PMP > 0 + satapmp_attach(chp); +#else + aprint_error_dev(atabus_sc->sc_dev, + "SATA port multiplier not supported\n"); + /* no problems going on, all drives are ATA_DRIVET_NONE */ +#endif + } + /* * Attach an ATAPI bus, if needed. */ - for (i = 0; i < chp->ch_ndrive; i++) { - if (chp->ch_drive[i].drive_flags & DRIVE_ATAPI) { + KASSERT(chp->ch_ndrives == 0 || chp->ch_drive != NULL); + for (i = 0; i < chp->ch_ndrives && chp->atapibus == NULL; i++) { + if (chp->ch_drive[i].drive_type == ATA_DRIVET_ATAPI) { #if NATAPIBUS > 0 (*atac->atac_atapibus_attach)(atabus_sc); #else @@ -288,34 +316,36 @@ atabusconfig_thread(void *arg) device_xname(atac->atac_dev)); chp->atapibus = NULL; s = splbio(); - for (i = 0; i < chp->ch_ndrive; i++) - chp->ch_drive[i].drive_flags &= ~DRIVE_ATAPI; + for (i = 0; i < chp->ch_ndrives; i++) { + if (chp->ch_drive[i].drive_type == ATA_DRIVET_ATAPI) + chp->ch_drive[i].drive_type = ATA_DRIVET_NONE; + } splx(s); #endif break; } } - for (i = 0; i < chp->ch_ndrive; i++) { + for (i = 0; i < chp->ch_ndrives; i++) { struct ata_device adev; - if ((chp->ch_drive[i].drive_flags & - (DRIVE_ATA | DRIVE_OLD)) == 0) { + if (chp->ch_drive[i].drive_type != ATA_DRIVET_ATA && + chp->ch_drive[i].drive_type != ATA_DRIVET_OLD) { continue; } + if (chp->ch_drive[i].drv_softc != NULL) + continue; memset(&adev, 0, sizeof(struct ata_device)); adev.adev_bustype = atac->atac_bustype_ata; adev.adev_channel = chp->ch_channel; adev.adev_openings = 1; adev.adev_drv_data = &chp->ch_drive[i]; - KASSERT(chp->ch_drive[i].drv_softc == NULL); chp->ch_drive[i].drv_softc = config_found_ia(atabus_sc->sc_dev, "ata_hl", &adev, ataprint); - if (chp->ch_drive[i].drv_softc != NULL) + if (chp->ch_drive[i].drv_softc != NULL) { ata_probe_caps(&chp->ch_drive[i]); - else { + } else { s = splbio(); - chp->ch_drive[i].drive_flags &= - ~(DRIVE_ATA | DRIVE_OLD); + chp->ch_drive[i].drive_type = ATA_DRIVET_NONE; splx(s); } } @@ -327,9 +357,8 @@ atabusconfig_thread(void *arg) } #if NATARAID > 0 if (atac->atac_cap & ATAC_CAP_RAID) { - for (i = 0; i < chp->ch_ndrive; i++) { - if ((chp->ch_drive[i].drv_softc != NULL) && - (chp->ch_drive[i].drive_flags & DRIVE_ATA)) { + for (i = 0; i < chp->ch_ndrives; i++) { + if (chp->ch_drive[i].drive_type == ATA_DRIVET_ATA) { ata_raid_check_component( chp->ch_drive[i].drv_softc); } @@ -342,10 +371,13 @@ atabusconfig_thread(void *arg) * ones */ s = splbio(); - for (i = 0; i < chp->ch_ndrive; i++) { - if (chp->ch_drive[i].drv_softc == NULL) + for (i = 0; i < chp->ch_ndrives; i++) { + if (chp->ch_drive[i].drive_type == ATA_DRIVET_PM) + continue; + if (chp->ch_drive[i].drv_softc == NULL) { chp->ch_drive[i].drive_flags = 0; - else + chp->ch_drive[i].drive_type = ATA_DRIVET_NONE; + } else chp->ch_drive[i].state = 0; } splx(s); @@ -380,13 +412,16 @@ atabus_thread(void *arg) chp->ch_flags |= ATACH_TH_RUN; /* - * Probe the drives. Reset all flags to 0 to indicate to controllers + * Probe the drives. Reset type to indicate to controllers * that can re-probe that all drives must be probed.. * - * Note: ch_ndrive may be changed during the probe. + * Note: ch_ndrives may be changed during the probe. */ - for (i = 0; i < ATA_MAXDRIVES; i++) + KASSERT(chp->ch_ndrives == 0 || chp->ch_drive != NULL); + for (i = 0; i < chp->ch_ndrives; i++) { chp->ch_drive[i].drive_flags = 0; + chp->ch_drive[i].drive_type = ATA_DRIVET_NONE; + } splx(s); atabusconfig(sc); @@ -528,12 +563,16 @@ atabus_detach(device_t self, int flags) KASSERT(chp->atapibus == NULL); } + KASSERT(chp->ch_ndrives == 0 || chp->ch_drive != NULL); + /* * Detach our other children. */ - for (i = 0; i < chp->ch_ndrive; i++) { - if (chp->ch_drive[i].drive_flags & DRIVE_ATAPI) + for (i = 0; i < chp->ch_ndrives; i++) { + if (chp->ch_drive[i].drive_type == ATA_DRIVET_ATAPI) continue; + if (chp->ch_drive[i].drive_type == ATA_DRIVET_PM) + chp->ch_drive[i].drive_type = ATA_DRIVET_NONE; if ((dev = chp->ch_drive[i].drv_softc) != NULL) { ATADEBUG_PRINT(("%s.%d: %s: detaching %s\n", __func__, __LINE__, device_xname(self), device_xname(dev)), @@ -542,9 +581,10 @@ atabus_detach(device_t self, int flags) if (error) goto out; KASSERT(chp->ch_drive[i].drv_softc == NULL); - KASSERT((chp->ch_drive[i].drive_flags & DRIVE) == 0); + KASSERT(chp->ch_drive[i].drive_type == 0); } } + atabus_free_drives(chp); out: #ifdef ATADEBUG @@ -565,23 +605,35 @@ atabus_childdetached(device_t self, device_t child) struct ata_channel *chp = sc->sc_chan; int i; + KASSERT(chp->ch_ndrives == 0 || chp->ch_drive != NULL); /* * atapibus detached. */ if (child == chp->atapibus) { chp->atapibus = NULL; found = true; + for (i = 0; i < chp->ch_ndrives; i++) { + if (chp->ch_drive[i].drive_type != ATA_DRIVET_ATAPI) + continue; + KASSERT(chp->ch_drive[i].drv_softc != NULL); + chp->ch_drive[i].drv_softc = NULL; + chp->ch_drive[i].drive_flags = 0; + chp->ch_drive[i].drive_type = ATA_DRIVET_NONE; + } } /* * Detach our other children. */ - for (i = 0; i < chp->ch_ndrive; i++) { - if (chp->ch_drive[i].drive_flags & DRIVE_ATAPI) + for (i = 0; i < chp->ch_ndrives; i++) { + if (chp->ch_drive[i].drive_type == ATA_DRIVET_ATAPI) continue; if (child == chp->ch_drive[i].drv_softc) { chp->ch_drive[i].drv_softc = NULL; chp->ch_drive[i].drive_flags = 0; + if (chp->ch_drive[i].drive_type == ATA_DRIVET_PM) + chp->ch_satapmp_nports = 0; + chp->ch_drive[i].drive_type = ATA_DRIVET_NONE; found = true; } } @@ -599,6 +651,64 @@ CFATTACH_DECL3_NEW(atabus, sizeof(struct atabus_softc), * Common ATA bus operations. *****************************************************************************/ +/* allocate/free the channel's ch_drive[] array */ +int +atabus_alloc_drives(struct ata_channel *chp, int ndrives) +{ + int i; + if (chp->ch_ndrives != ndrives) + atabus_free_drives(chp); + if (chp->ch_drive == NULL) { + chp->ch_drive = malloc( + sizeof(struct ata_drive_datas) * ndrives, + M_DEVBUF, M_NOWAIT | M_ZERO); + } + if (chp->ch_drive == NULL) { + aprint_error_dev(chp->ch_atac->atac_dev, + "can't alloc drive array\n"); + chp->ch_ndrives = 0; + return ENOMEM; + }; + for (i = 0; i < ndrives; i++) { + chp->ch_drive[i].chnl_softc = chp; + chp->ch_drive[i].drive = i; + } + chp->ch_ndrives = ndrives; + return 0; +} + +void +atabus_free_drives(struct ata_channel *chp) +{ +#ifdef DIAGNOSTIC + int i; + int dopanic = 0; + KASSERT(chp->ch_ndrives == 0 || chp->ch_drive != NULL); + for (i = 0; i < chp->ch_ndrives; i++) { + if (chp->ch_drive[i].drive_type != ATA_DRIVET_NONE) { + printf("%s: ch_drive[%d] type %d != ATA_DRIVET_NONE\n", + device_xname(chp->atabus), i, + chp->ch_drive[i].drive_type); + dopanic = 1; + } + if (chp->ch_drive[i].drv_softc != NULL) { + printf("%s: ch_drive[%d] attached to %s\n", + device_xname(chp->atabus), i, + device_xname(chp->ch_drive[i].drv_softc)); + dopanic = 1; + } + } + if (dopanic) + panic("atabus_free_drives"); +#endif + + if (chp->ch_drive == NULL) + return; + chp->ch_ndrives = 0; + free(chp->ch_drive, M_DEVBUF); + chp->ch_drive = NULL; +} + /* Get the disk's parameters */ int ata_get_params(struct ata_drive_datas *drvp, u_int8_t flags, @@ -617,12 +727,12 @@ ata_get_params(struct ata_drive_datas *drvp, u_int8_t flags, memset(prms, 0, sizeof(struct ataparams)); memset(&ata_c, 0, sizeof(struct ata_command)); - if (drvp->drive_flags & DRIVE_ATA) { + if (drvp->drive_type == ATA_DRIVET_ATA) { ata_c.r_command = WDCC_IDENTIFY; ata_c.r_st_bmask = WDCS_DRDY; ata_c.r_st_pmask = WDCS_DRQ; ata_c.timeout = 3000; /* 3s */ - } else if (drvp->drive_flags & DRIVE_ATAPI) { + } else if (drvp->drive_type == ATA_DRIVET_ATAPI) { ata_c.r_command = ATAPI_IDENTIFY_DEVICE; ata_c.r_st_bmask = 0; ata_c.r_st_pmask = WDCS_DRQ; @@ -673,7 +783,7 @@ ata_get_params(struct ata_drive_datas *drvp, u_int8_t flags, #if BYTE_ORDER == BIG_ENDIAN ! #endif - ((drvp->drive_flags & DRIVE_ATAPI) ? + ((drvp->drive_type == ATA_DRIVET_ATAPI) ? ((M(0) == 'N' && M(1) == 'E') || (M(0) == 'F' && M(1) == 'X') || (M(0) == 'P' && M(1) == 'i')) : @@ -869,8 +979,8 @@ atastart(struct ata_channel *chp) ATADEBUG_PRINT(("atastart: xfer %p channel %d drive %d\n", xfer, chp->ch_channel, xfer->c_drive), DEBUG_XFERS); - if (chp->ch_drive[xfer->c_drive].drive_flags & DRIVE_RESET) { - chp->ch_drive[xfer->c_drive].drive_flags &= ~DRIVE_RESET; + if (chp->ch_drive[xfer->c_drive].drive_flags & ATA_DRIVE_RESET) { + chp->ch_drive[xfer->c_drive].drive_flags &= ~ATA_DRIVE_RESET; chp->ch_drive[xfer->c_drive].state = 0; } chp->ch_queue->active_xfer = xfer; @@ -952,7 +1062,7 @@ ata_kill_pending(struct ata_drive_datas *drvp) while ((xfer = chp->ch_queue->active_xfer) != NULL) { if (xfer->c_chp == chp && xfer->c_drive == drvp->drive) { - drvp->drive_flags |= DRIVE_WAITDRAIN; + drvp->drive_flags |= ATA_DRIVE_WAITDRAIN; (void) tsleep(&chp->ch_queue->active_xfer, PRIBIO, "atdrn", 0); } else { @@ -1011,7 +1121,8 @@ ata_reset_channel(struct ata_channel *chp, int flags) (*atac->atac_bustype_ata->ata_reset_channel)(chp, flags); - for (drive = 0; drive < chp->ch_ndrive; drive++) + KASSERT(chp->ch_ndrives == 0 || chp->ch_drive != NULL); + for (drive = 0; drive < chp->ch_ndrives; drive++) chp->ch_drive[drive].state = 0; chp->ch_flags &= ~ATACH_TH_RESET; @@ -1065,19 +1176,21 @@ ata_print_modes(struct ata_channel *chp) int drive; struct ata_drive_datas *drvp; - for (drive = 0; drive < chp->ch_ndrive; drive++) { + KASSERT(chp->ch_ndrives == 0 || chp->ch_drive != NULL); + for (drive = 0; drive < chp->ch_ndrives; drive++) { drvp = &chp->ch_drive[drive]; - if ((drvp->drive_flags & DRIVE) == 0 || drvp->drv_softc == NULL) + if (drvp->drive_type == ATA_DRIVET_NONE || + drvp->drv_softc == NULL) continue; aprint_verbose("%s(%s:%d:%d): using PIO mode %d", device_xname(drvp->drv_softc), device_xname(atac->atac_dev), chp->ch_channel, drvp->drive, drvp->PIO_mode); #if NATA_DMA - if (drvp->drive_flags & DRIVE_DMA) + if (drvp->drive_flags & ATA_DRIVE_DMA) aprint_verbose(", DMA mode %d", drvp->DMA_mode); #if NATA_UDMA - if (drvp->drive_flags & DRIVE_UDMA) { + if (drvp->drive_flags & ATA_DRIVE_UDMA) { aprint_verbose(", Ultra-DMA mode %d", drvp->UDMA_mode); if (drvp->UDMA_mode == 2) aprint_verbose(" (Ultra/33)"); @@ -1093,7 +1206,7 @@ ata_print_modes(struct ata_channel *chp) #if NATA_DMA || NATA_PIOBM if (0 #if NATA_DMA - || (drvp->drive_flags & (DRIVE_DMA | DRIVE_UDMA)) + || (drvp->drive_flags & (ATA_DRIVE_DMA | ATA_DRIVE_UDMA)) #endif #if NATA_PIOBM /* PIOBM capable controllers use DMA for PIO commands */ @@ -1122,7 +1235,7 @@ ata_downgrade_mode(struct ata_drive_datas *drvp, int flags) int cf_flags = device_cfdata(drv_dev)->cf_flags; /* if drive or controller don't know its mode, we can't do much */ - if ((drvp->drive_flags & DRIVE_MODE) == 0 || + if ((drvp->drive_flags & ATA_DRIVE_MODE) == 0 || (atac->atac_set_modes == NULL)) return 0; /* current drive mode was set by a config flag, let it this way */ @@ -1135,7 +1248,7 @@ ata_downgrade_mode(struct ata_drive_datas *drvp, int flags) /* * If we were using Ultra-DMA mode, downgrade to the next lower mode. */ - if ((drvp->drive_flags & DRIVE_UDMA) && drvp->UDMA_mode >= 2) { + if ((drvp->drive_flags & ATA_DRIVE_UDMA) && drvp->UDMA_mode >= 2) { drvp->UDMA_mode--; aprint_error_dev(drv_dev, "transfer error, downgrading to Ultra-DMA mode %d\n", @@ -1146,8 +1259,8 @@ ata_downgrade_mode(struct ata_drive_datas *drvp, int flags) /* * If we were using ultra-DMA, don't downgrade to multiword DMA. */ - else if (drvp->drive_flags & (DRIVE_DMA | DRIVE_UDMA)) { - drvp->drive_flags &= ~(DRIVE_DMA | DRIVE_UDMA); + else if (drvp->drive_flags & (ATA_DRIVE_DMA | ATA_DRIVE_UDMA)) { + drvp->drive_flags &= ~(ATA_DRIVE_DMA | ATA_DRIVE_UDMA); drvp->PIO_mode = drvp->PIO_cap; aprint_error_dev(drv_dev, "transfer error, downgrading to PIO mode %d\n", @@ -1190,13 +1303,13 @@ ata_probe_caps(struct ata_drive_datas *drvp) * and compare results. */ s = splbio(); - drvp->drive_flags |= DRIVE_CAP32; + drvp->drive_flags |= ATA_DRIVE_CAP32; splx(s); ata_get_params(drvp, AT_WAIT, ¶ms2); if (memcmp(¶ms, ¶ms2, sizeof(struct ataparams)) != 0) { /* Not good. fall back to 16bits */ s = splbio(); - drvp->drive_flags &= ~DRIVE_CAP32; + drvp->drive_flags &= ~ATA_DRIVE_CAP32; splx(s); } else { aprint_verbose_dev(drv_dev, "32-bit data port\n"); @@ -1217,7 +1330,7 @@ ata_probe_caps(struct ata_drive_datas *drvp) #endif /* An ATAPI device is at last PIO mode 3 */ - if (drvp->drive_flags & DRIVE_ATAPI) + if (drvp->drive_type == ATA_DRIVET_ATAPI) drvp->PIO_mode = 3; /* @@ -1277,7 +1390,7 @@ ata_probe_caps(struct ata_drive_datas *drvp) return; } s = splbio(); - drvp->drive_flags |= DRIVE_MODE; + drvp->drive_flags |= ATA_DRIVE_MODE; splx(s); printed = 0; for (i = 7; i >= 0; i--) { @@ -1303,7 +1416,7 @@ ata_probe_caps(struct ata_drive_datas *drvp) drvp->DMA_mode = i; drvp->DMA_cap = i; s = splbio(); - drvp->drive_flags |= DRIVE_DMA; + drvp->drive_flags |= ATA_DRIVE_DMA; splx(s); } #endif @@ -1344,7 +1457,7 @@ ata_probe_caps(struct ata_drive_datas *drvp) drvp->UDMA_mode = i; drvp->UDMA_cap = i; s = splbio(); - drvp->drive_flags |= DRIVE_UDMA; + drvp->drive_flags |= ATA_DRIVE_UDMA; splx(s); } #endif @@ -1355,20 +1468,20 @@ ata_probe_caps(struct ata_drive_datas *drvp) } s = splbio(); - drvp->drive_flags &= ~DRIVE_NOSTREAM; - if (drvp->drive_flags & DRIVE_ATAPI) { + drvp->drive_flags &= ~ATA_DRIVE_NOSTREAM; + if (drvp->drive_type == ATA_DRIVET_ATAPI) { if (atac->atac_cap & ATAC_CAP_ATAPI_NOSTREAM) - drvp->drive_flags |= DRIVE_NOSTREAM; + drvp->drive_flags |= ATA_DRIVE_NOSTREAM; } else { if (atac->atac_cap & ATAC_CAP_ATA_NOSTREAM) - drvp->drive_flags |= DRIVE_NOSTREAM; + drvp->drive_flags |= ATA_DRIVE_NOSTREAM; } splx(s); /* Try to guess ATA version here, if it didn't get reported */ if (drvp->ata_vers == 0) { #if NATA_UDMA - if (drvp->drive_flags & DRIVE_UDMA) + if (drvp->drive_flags & ATA_DRIVE_UDMA) drvp->ata_vers = 4; /* should be at last ATA-4 */ else #endif @@ -1380,7 +1493,7 @@ ata_probe_caps(struct ata_drive_datas *drvp) s = splbio(); drvp->PIO_mode = (cf_flags & ATA_CONFIG_PIO_MODES) >> ATA_CONFIG_PIO_OFF; - drvp->drive_flags |= DRIVE_MODE; + drvp->drive_flags |= ATA_DRIVE_MODE; splx(s); } #if NATA_DMA @@ -1392,11 +1505,11 @@ ata_probe_caps(struct ata_drive_datas *drvp) s = splbio(); if ((cf_flags & ATA_CONFIG_DMA_MODES) == ATA_CONFIG_DMA_DISABLE) { - drvp->drive_flags &= ~DRIVE_DMA; + drvp->drive_flags &= ~ATA_DRIVE_DMA; } else { drvp->DMA_mode = (cf_flags & ATA_CONFIG_DMA_MODES) >> ATA_CONFIG_DMA_OFF; - drvp->drive_flags |= DRIVE_DMA | DRIVE_MODE; + drvp->drive_flags |= ATA_DRIVE_DMA | ATA_DRIVE_MODE; } splx(s); } @@ -1409,11 +1522,11 @@ ata_probe_caps(struct ata_drive_datas *drvp) s = splbio(); if ((cf_flags & ATA_CONFIG_UDMA_MODES) == ATA_CONFIG_UDMA_DISABLE) { - drvp->drive_flags &= ~DRIVE_UDMA; + drvp->drive_flags &= ~ATA_DRIVE_UDMA; } else { drvp->UDMA_mode = (cf_flags & ATA_CONFIG_UDMA_MODES) >> ATA_CONFIG_UDMA_OFF; - drvp->drive_flags |= DRIVE_UDMA | DRIVE_MODE; + drvp->drive_flags |= ATA_DRIVE_UDMA | ATA_DRIVE_MODE; } splx(s); } @@ -1492,8 +1605,8 @@ atabusioctl(dev_t dev, u_long cmd, void *addr, int flag, struct lwp *l) struct atabusioscan_args *a= (struct atabusioscan_args *)addr; #endif - if ((chp->ch_drive[0].drive_flags & DRIVE_OLD) || - (chp->ch_drive[1].drive_flags & DRIVE_OLD)) + if ((chp->ch_drive[0].drive_type == ATA_DRIVET_OLD) || + (chp->ch_drive[1].drive_type == ATA_DRIVET_OLD)) return (EOPNOTSUPP); return (EOPNOTSUPP); } @@ -1501,8 +1614,8 @@ atabusioctl(dev_t dev, u_long cmd, void *addr, int flag, struct lwp *l) { struct atabusiodetach_args *a= (struct atabusiodetach_args *)addr; - if ((chp->ch_drive[0].drive_flags & DRIVE_OLD) || - (chp->ch_drive[1].drive_flags & DRIVE_OLD)) + if ((chp->ch_drive[0].drive_type == ATA_DRIVET_OLD) || + (chp->ch_drive[1].drive_type == ATA_DRIVET_OLD)) return (EOPNOTSUPP); switch (a->at_dev) { case -1: @@ -1575,23 +1688,23 @@ atabus_rescan(device_t self, const char *ifattr, const int *locators) struct ata_channel *chp = sc->sc_chan; struct atabus_initq *initq; int i; - int s; - if (chp->atapibus != NULL) { - return EBUSY; - } - - for (i = 0; i < ATA_MAXDRIVES; i++) { - if (chp->ch_drive[i].drv_softc != NULL) { + /* + * we can rescan a port multiplier atabus, even if some devices are + * still attached + */ + if (chp->ch_satapmp_nports == 0) { + if (chp->atapibus != NULL) { return EBUSY; } - } - s = splbio(); - for (i = 0; i < ATA_MAXDRIVES; i++) { - chp->ch_drive[i].drive_flags = 0; + KASSERT(chp->ch_ndrives == 0 || chp->ch_drive != NULL); + for (i = 0; i < chp->ch_ndrives; i++) { + if (chp->ch_drive[i].drv_softc != NULL) { + return EBUSY; + } + } } - splx(s); initq = malloc(sizeof(*initq), M_DEVBUF, M_WAITOK); initq->atabus_sc = sc; diff --git a/sys/dev/ata/ata_wdc.c b/sys/dev/ata/ata_wdc.c index af4f9635d68..8ae353cfe6d 100644 --- a/sys/dev/ata/ata_wdc.c +++ b/sys/dev/ata/ata_wdc.c @@ -1,4 +1,4 @@ -/* $NetBSD: ata_wdc.c,v 1.100 2012/07/26 20:49:47 jakllsch Exp $ */ +/* $NetBSD: ata_wdc.c,v 1.101 2012/07/31 15:50:34 bouyer Exp $ */ /* * Copyright (c) 1998, 2001, 2003 Manuel Bouyer. @@ -54,7 +54,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: ata_wdc.c,v 1.100 2012/07/26 20:49:47 jakllsch Exp $"); +__KERNEL_RCSID(0, "$NetBSD: ata_wdc.c,v 1.101 2012/07/31 15:50:34 bouyer Exp $"); #include "opt_ata.h" #include "opt_wdc.h" @@ -149,7 +149,7 @@ wdc_ata_bio(struct ata_drive_datas *drvp, struct ata_bio *ata_bio) if (ata_bio->flags & ATA_POLL) xfer->c_flags |= C_POLL; #if NATA_DMA - if ((drvp->drive_flags & (DRIVE_DMA | DRIVE_UDMA)) && + if ((drvp->drive_flags & (ATA_DRIVE_DMA | ATA_DRIVE_UDMA)) && (ata_bio->flags & ATA_SINGLE) == 0) xfer->c_flags |= C_DMA; #endif @@ -187,8 +187,10 @@ wdc_ata_bio_start(struct ata_channel *chp, struct ata_xfer *xfer) wait_flags = (xfer->c_flags & C_POLL) ? AT_POLL : 0; #endif - ATADEBUG_PRINT(("wdc_ata_bio_start %s:%d:%d\n", - device_xname(atac->atac_dev), chp->ch_channel, xfer->c_drive), + ATADEBUG_PRINT(("wdc_ata_bio_start %s:%d:%d state %d drive_flags 0x%x " + "c_flags 0x%x ch_flags 0x%x\n", + device_xname(atac->atac_dev), chp->ch_channel, xfer->c_drive, + drvp->state, drvp->drive_flags, xfer->c_flags, chp->ch_flags), DEBUG_XFERS); /* Do control operations specially. */ @@ -231,7 +233,7 @@ wdc_ata_bio_start(struct ata_channel *chp, struct ata_xfer *xfer) if (atac->atac_set_modes == NULL) goto geometry; /* Also don't try if the drive didn't report its mode */ - if ((drvp->drive_flags & DRIVE_MODE) == 0) + if ((drvp->drive_flags & ATA_DRIVE_MODE) == 0) goto geometry; wdccommand(chp, drvp->drive, SET_FEATURES, 0, 0, 0, 0x08 | drvp->PIO_mode, WDSF_SET_MODE); @@ -242,12 +244,12 @@ wdc_ata_bio_start(struct ata_channel *chp, struct ata_xfer *xfer) goto ctrlerror; #if NATA_DMA #if NATA_UDMA - if (drvp->drive_flags & DRIVE_UDMA) { + if (drvp->drive_flags & ATA_DRIVE_UDMA) { wdccommand(chp, drvp->drive, SET_FEATURES, 0, 0, 0, 0x40 | drvp->UDMA_mode, WDSF_SET_MODE); } else #endif - if (drvp->drive_flags & DRIVE_DMA) { + if (drvp->drive_flags & ATA_DRIVE_DMA) { wdccommand(chp, drvp->drive, SET_FEATURES, 0, 0, 0, 0x20 | drvp->DMA_mode, WDSF_SET_MODE); } else { @@ -780,7 +782,7 @@ wdc_ata_bio_kill_xfer(struct ata_channel *chp, struct ata_xfer *xfer, panic("wdc_ata_bio_kill_xfer"); } ata_bio->r_error = WDCE_ABRT; - ATADEBUG_PRINT(("wdc_ata_done: drv_done\n"), DEBUG_XFERS); + ATADEBUG_PRINT(("wdc_ata_bio_kill_xfer: drv_done\n"), DEBUG_XFERS); (*chp->ch_drive[drive].drv_done)(chp->ch_drive[drive].drv_softc); } @@ -804,9 +806,9 @@ wdc_ata_bio_done(struct ata_channel *chp, struct ata_xfer *xfer) chp->ch_queue->active_xfer = NULL; ata_free_xfer(chp, xfer); - if (chp->ch_drive[drive].drive_flags & DRIVE_WAITDRAIN) { + if (chp->ch_drive[drive].drive_flags & ATA_DRIVE_WAITDRAIN) { ata_bio->error = ERR_NODEV; - chp->ch_drive[drive].drive_flags &= ~DRIVE_WAITDRAIN; + chp->ch_drive[drive].drive_flags &= ~ATA_DRIVE_WAITDRAIN; wakeup(&chp->ch_queue->active_xfer); } ata_bio->flags |= ATA_ITSDONE; diff --git a/sys/dev/ata/atavar.h b/sys/dev/ata/atavar.h index 24878f34af9..5b45d0da107 100644 --- a/sys/dev/ata/atavar.h +++ b/sys/dev/ata/atavar.h @@ -1,4 +1,4 @@ -/* $NetBSD: atavar.h,v 1.89 2012/07/29 21:10:50 jakllsch Exp $ */ +/* $NetBSD: atavar.h,v 1.90 2012/07/31 15:50:34 bouyer Exp $ */ /* * Copyright (c) 1998, 2001 Manuel Bouyer. @@ -36,11 +36,6 @@ #include #include -/* - * Max number of drives per channel. - */ -#define ATA_MAXDRIVES 2 - /* * Description of a command to be handled by an ATA controller. These * commands are queued in a list. @@ -116,19 +111,21 @@ struct ata_drive_datas { u_int8_t drive; /* drive number */ int8_t ata_vers; /* ATA version supported */ u_int16_t drive_flags; /* bitmask for drives present/absent and cap */ - -#define DRIVE_ATA 0x0001 -#define DRIVE_ATAPI 0x0002 -#define DRIVE_OLD 0x0004 -#define DRIVE (DRIVE_ATA|DRIVE_ATAPI|DRIVE_OLD) -#define DRIVE_CAP32 0x0008 -#define DRIVE_DMA 0x0010 -#define DRIVE_UDMA 0x0020 -#define DRIVE_MODE 0x0040 /* the drive reported its mode */ -#define DRIVE_RESET 0x0080 /* reset the drive state at next xfer */ -#define DRIVE_WAITDRAIN 0x0100 /* device is waiting for the queue to drain */ -#define DRIVE_ATAPIST 0x0200 /* device is an ATAPI tape drive */ -#define DRIVE_NOSTREAM 0x0400 /* no stream methods on this drive */ +#define ATA_DRIVE_CAP32 0x0001 +#define ATA_DRIVE_DMA 0x0002 +#define ATA_DRIVE_UDMA 0x0004 +#define ATA_DRIVE_MODE 0x0008 /* the drive reported its mode */ +#define ATA_DRIVE_RESET 0x0010 /* reset the drive state at next xfer */ +#define ATA_DRIVE_WAITDRAIN 0x0020 /* device is waiting for the queue to drain */ +#define ATA_DRIVE_NOSTREAM 0x0040 /* no stream methods on this drive */ +#define ATA_DRIVE_ATAPIDSCW 0x0080 /* needs to wait for DSC in phase_complete */ + + uint8_t drive_type; +#define ATA_DRIVET_NONE 0 +#define ATA_DRIVET_ATA 1 +#define ATA_DRIVET_ATAPI 2 +#define ATA_DRIVET_OLD 3 +#define ATA_DRIVET_PM 4 /* * Current setting of drive's PIO, DMA and UDMA modes. @@ -286,7 +283,7 @@ struct ata_command { struct ata_bustype { int bustype_type; /* symbolic name of type */ int (*ata_bio)(struct ata_drive_datas *, struct ata_bio *); - void (*ata_reset_drive)(struct ata_drive_datas *, int); + void (*ata_reset_drive)(struct ata_drive_datas *, int, uint32_t *); void (*ata_reset_channel)(struct ata_channel *, int); /* extra flags for ata_reset_*(), in addition to AT_* */ #define AT_RST_EMERG 0x10000 /* emergency - e.g. for a dump */ @@ -347,8 +344,8 @@ struct ata_channel { int ch_reset_flags; /* per-drive info */ - int ch_ndrive; - struct ata_drive_datas ch_drive[ATA_MAXDRIVES]; + int ch_ndrives; /* number of entries in ch_drive[] */ + struct ata_drive_datas *ch_drive; /* array of ata_drive_datas */ device_t atabus; /* self */ @@ -364,6 +361,9 @@ struct ata_channel { /* The channel kernel thread */ struct lwp *ch_thread; + + /* Number of sata PMP ports, if any */ + int ch_satapmp_nports; }; /* @@ -431,6 +431,9 @@ void ata_channel_attach(struct ata_channel *); int atabusprint(void *aux, const char *); int ataprint(void *aux, const char *); +int atabus_alloc_drives(struct ata_channel *, int); +void atabus_free_drives(struct ata_channel *); + struct ataparams; int ata_get_params(struct ata_drive_datas *, u_int8_t, struct ataparams *); int ata_set_mode(struct ata_drive_datas *, u_int8_t, u_int8_t); diff --git a/sys/dev/ata/files.ata b/sys/dev/ata/files.ata index 195b65c8be1..7183c5bfdc4 100644 --- a/sys/dev/ata/files.ata +++ b/sys/dev/ata/files.ata @@ -1,4 +1,4 @@ -# $NetBSD: files.ata,v 1.23 2012/07/26 20:49:47 jakllsch Exp $ +# $NetBSD: files.ata,v 1.24 2012/07/31 15:50:34 bouyer Exp $ # # Config file and device description for machine-independent devices # which attach to ATA busses. Included by ports that need it. Ports @@ -34,3 +34,6 @@ file dev/ata/sata_subr.c sata needs-flag # Common SATA FIS subroutines file dev/ata/satafis_subr.c sata_fis + +# SATA port multiplier support +file dev/ata/satapmp_subr.c sata_pmp needs-flag diff --git a/sys/dev/ata/sata_subr.c b/sys/dev/ata/sata_subr.c index c1053ef2fb2..6945f3d864f 100644 --- a/sys/dev/ata/sata_subr.c +++ b/sys/dev/ata/sata_subr.c @@ -1,4 +1,4 @@ -/* $NetBSD: sata_subr.c,v 1.19 2012/07/26 20:49:47 jakllsch Exp $ */ +/* $NetBSD: sata_subr.c,v 1.20 2012/07/31 15:50:34 bouyer Exp $ */ /*- * Copyright (c) 2004 The NetBSD Foundation, Inc. @@ -33,7 +33,7 @@ * Common functions for Serial ATA. */ #include -__KERNEL_RCSID(0, "$NetBSD: sata_subr.c,v 1.19 2012/07/26 20:49:47 jakllsch Exp $"); +__KERNEL_RCSID(0, "$NetBSD: sata_subr.c,v 1.20 2012/07/31 15:50:34 bouyer Exp $"); #include #include @@ -41,6 +41,7 @@ __KERNEL_RCSID(0, "$NetBSD: sata_subr.c,v 1.19 2012/07/26 20:49:47 jakllsch Exp #include #include +#include /* * sata_speed: @@ -146,3 +147,53 @@ sata_reset_interface(struct ata_channel *chp, bus_space_tag_t sata_t, } return(sstatus & SStatus_DET_mask); } + +void +sata_interpret_sig(struct ata_channel *chp, int port, uint32_t sig) +{ + int err; + int s; + + /* some ATAPI devices have bogus lower two bytes, sigh */ + if ((sig & 0xffff0000) == 0xeb140000) { + sig &= 0xffff0000; + sig |= 0x00000101; + } + if (chp->ch_drive == NULL) { + if (sig == 0x96690101) + err = atabus_alloc_drives(chp, PMP_MAX_DRIVES); + else + err = atabus_alloc_drives(chp, 1); + if (err) + return; + } + KASSERT(port < chp->ch_ndrives); + + s = splbio(); + switch(sig) { + case 0x96690101: + KASSERT(port == 0 || port == PMP_PORT_CTL); + chp->ch_drive[PMP_PORT_CTL].drive_type = ATA_DRIVET_PM; + break; + case 0xc33c0101: + aprint_verbose_dev(chp->atabus, "port %d is SEMB, ignored\n", + port); + break; + case 0xeb140101: + chp->ch_drive[port].drive_type = ATA_DRIVET_ATAPI; + break; + case 0x00000101: + chp->ch_drive[port].drive_type = ATA_DRIVET_ATA; + break; + case 0xffffffff: + /* COMRESET time out */ + break; + default: + chp->ch_drive[port].drive_type = ATA_DRIVET_ATA; + aprint_verbose_dev(chp->atabus, + "Unrecognized signature 0x%08x on port %d. " + "Assuming it's a disk.\n", sig, port); + break; + } + splx(s); +} diff --git a/sys/dev/ata/satapmpreg.h b/sys/dev/ata/satapmpreg.h index 8bb9b85bd98..a5fdc4beec0 100644 --- a/sys/dev/ata/satapmpreg.h +++ b/sys/dev/ata/satapmpreg.h @@ -1,4 +1,4 @@ -/* $NetBSD: satapmpreg.h,v 1.5 2012/07/26 20:49:48 jakllsch Exp $ */ +/* $NetBSD: satapmpreg.h,v 1.6 2012/07/31 15:50:34 bouyer Exp $ */ /*- * Copyright (c) 2004 The NetBSD Foundation, Inc. @@ -37,7 +37,7 @@ */ #define PMP_GSCR_ID 0x00 /* product and vendor id */ -#define PMP_ID_DEV(x) ((x) << 16) +#define PMP_ID_DEV(x) ((x) >> 16) #define PMP_ID_VEND(x) ((x) & 0xffff) #define PMP_GSCR_REV 0x01 /* revision */ #define PMP_REV_SPEC_10 0x02 @@ -79,4 +79,7 @@ #define PMPC_READ_PORT 0xe4 #define PMPC_WRITE_PORT 0xe8 +/* max number of drives (last one being the PM itself */ +#define PMP_MAX_DRIVES 16 + #endif /* _DEV_ATA_SATAPMPREG_H_ */ diff --git a/sys/dev/ata/satavar.h b/sys/dev/ata/satavar.h index 4764801f9bd..5e0d20e5699 100644 --- a/sys/dev/ata/satavar.h +++ b/sys/dev/ata/satavar.h @@ -1,4 +1,4 @@ -/* $NetBSD: satavar.h,v 1.7 2012/07/26 20:49:48 jakllsch Exp $ */ +/* $NetBSD: satavar.h,v 1.8 2012/07/31 15:50:34 bouyer Exp $ */ /*- * Copyright (c) 2004 The NetBSD Foundation, Inc. @@ -42,5 +42,6 @@ const char *sata_speed(uint32_t); uint32_t sata_reset_interface(struct ata_channel *, bus_space_tag_t, bus_space_handle_t, bus_space_handle_t); +void sata_interpret_sig(struct ata_channel *, int, uint32_t); #endif /* _DEV_ATA_SATAVAR_H_ */ diff --git a/sys/dev/ata/wd.c b/sys/dev/ata/wd.c index df7ee54988e..1e381bebe7b 100644 --- a/sys/dev/ata/wd.c +++ b/sys/dev/ata/wd.c @@ -1,4 +1,4 @@ -/* $NetBSD: wd.c,v 1.399 2012/07/26 20:49:48 jakllsch Exp $ */ +/* $NetBSD: wd.c,v 1.400 2012/07/31 15:50:34 bouyer Exp $ */ /* * Copyright (c) 1998, 2001 Manuel Bouyer. All rights reserved. @@ -54,7 +54,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: wd.c,v 1.399 2012/07/26 20:49:48 jakllsch Exp $"); +__KERNEL_RCSID(0, "$NetBSD: wd.c,v 1.400 2012/07/31 15:50:34 bouyer Exp $"); #include "opt_ata.h" @@ -283,7 +283,8 @@ wdattach(device_t parent, device_t self, void *aux) wd->drvp = adev->adev_drv_data; wd->drvp->drv_done = wddone; - wd->drvp->drv_softc = wd->sc_dev; + wd->drvp->drv_softc = wd->sc_dev; /* done in atabusconfig_thread() + but too late */ aprint_naive("\n"); aprint_normal("\n"); @@ -291,7 +292,7 @@ wdattach(device_t parent, device_t self, void *aux) /* read our drive info */ if (wd_get_params(wd, AT_WAIT, &wd->sc_params) != 0) { aprint_error_dev(self, "IDENTIFY failed\n"); - return; + goto out; } for (blank = 0, p = wd->sc_params.atap_model, q = tbuf, i = 0; @@ -380,6 +381,7 @@ wdattach(device_t parent, device_t self, void *aux) ATADEBUG_PRINT(("%s: atap_dmatiming_mimi=%d, atap_dmatiming_recom=%d\n", device_xname(self), wd->sc_params.atap_dmatiming_mimi, wd->sc_params.atap_dmatiming_recom), DEBUG_PROBE); +out: /* * Initialize and attach the disk structure. */ @@ -461,7 +463,8 @@ wddetach(device_t self, int flags) callout_destroy(&sc->sc_restart_ch); - sc->drvp->drive_flags = 0; /* no drive any more here */ + sc->drvp->drive_type = ATA_DRIVET_NONE; /* no drive any more here */ + sc->drvp->drive_flags = 0; return (0); } @@ -772,7 +775,7 @@ wddone(void *v) errmsg = "error"; do_perror = 1; retry: /* Just reset and retry. Can we do more ? */ - (*wd->atabus->ata_reset_drive)(wd->drvp, AT_RST_NOCMD); + (*wd->atabus->ata_reset_drive)(wd->drvp, AT_RST_NOCMD, NULL); retry2: diskerr(bp, "wd", errmsg, LOG_PRINTF, wd->sc_wdc_bio.blkdone, wd->sc_dk.dk_label); @@ -896,6 +899,9 @@ wdopen(dev_t dev, int flag, int fmt, struct lwp *l) if (! device_is_active(wd->sc_dev)) return (ENODEV); + if (wd->sc_capacity == 0) + return (ENODEV); + part = WDPART(dev); mutex_enter(&wd->sc_dk.dk_openlock); @@ -928,11 +934,15 @@ wdopen(dev_t dev, int flag, int fmt, struct lwp *l) } } else { if ((wd->sc_flags & WDF_LOADED) == 0) { - wd->sc_flags |= WDF_LOADED; /* Load the physical device parameters. */ - wd_get_params(wd, AT_WAIT, &wd->sc_params); - + if (wd_get_params(wd, AT_WAIT, &wd->sc_params) != 0) { + aprint_error_dev(wd->sc_dev, + "IDENTIFY failed\n"); + error = EIO; + goto bad2; + } + wd->sc_flags |= WDF_LOADED; /* Load the partition info if not already loaded. */ wdgetdisklabel(wd); } @@ -1077,7 +1087,7 @@ wdgetdisklabel(struct wd_softc *wd) if (wd->drvp->state > RESET) { s = splbio(); - wd->drvp->drive_flags |= DRIVE_RESET; + wd->drvp->drive_flags |= ATA_DRIVE_RESET; splx(s); } errstring = readdisklabel(MAKEWDDEV(0, device_unit(wd->sc_dev), @@ -1092,7 +1102,7 @@ wdgetdisklabel(struct wd_softc *wd) */ if (wd->drvp->state > RESET) { s = splbio(); - wd->drvp->drive_flags |= DRIVE_RESET; + wd->drvp->drive_flags |= ATA_DRIVE_RESET; splx(s); } errstring = readdisklabel(MAKEWDDEV(0, device_unit(wd->sc_dev), @@ -1105,7 +1115,7 @@ wdgetdisklabel(struct wd_softc *wd) if (wd->drvp->state > RESET) { s = splbio(); - wd->drvp->drive_flags |= DRIVE_RESET; + wd->drvp->drive_flags |= ATA_DRIVE_RESET; splx(s); } #ifdef HAS_BAD144_HANDLING @@ -1293,7 +1303,7 @@ wdioctl(dev_t dev, u_long xfer, void *addr, int flag, struct lwp *l) if (error == 0) { if (wd->drvp->state > RESET) { s = splbio(); - wd->drvp->drive_flags |= DRIVE_RESET; + wd->drvp->drive_flags |= ATA_DRIVE_RESET; splx(s); } if (xfer == DIOCWDINFO @@ -1607,7 +1617,7 @@ wddump(dev_t dev, daddr_t blkno, void *va, size_t size) if (wddumprecalibrated == 0) { wddumprecalibrated = 1; (*wd->atabus->ata_reset_drive)(wd->drvp, - AT_POLL | AT_RST_EMERG); + AT_POLL | AT_RST_EMERG, NULL); wd->drvp->state = RESET; } @@ -1762,6 +1772,8 @@ wd_get_params(struct wd_softc *wd, u_int8_t flags, struct ataparams *params) case CMD_AGAIN: return 1; case CMD_ERR: + if (wd->drvp->drive_type != ATA_DRIVET_OLD) + return 1; /* * We `know' there's a drive here; just assume it's old. * This geometry is only used to read the MBR and print a diff --git a/sys/dev/ic/ahcisata_core.c b/sys/dev/ic/ahcisata_core.c index 8387f6b8d0a..9f0713d2cbc 100644 --- a/sys/dev/ic/ahcisata_core.c +++ b/sys/dev/ic/ahcisata_core.c @@ -1,4 +1,4 @@ -/* $NetBSD: ahcisata_core.c,v 1.39 2012/07/26 20:49:48 jakllsch Exp $ */ +/* $NetBSD: ahcisata_core.c,v 1.40 2012/07/31 15:50:34 bouyer Exp $ */ /* * Copyright (c) 2006 Manuel Bouyer. @@ -26,7 +26,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: ahcisata_core.c,v 1.39 2012/07/26 20:49:48 jakllsch Exp $"); +__KERNEL_RCSID(0, "$NetBSD: ahcisata_core.c,v 1.40 2012/07/31 15:50:34 bouyer Exp $"); #include #include @@ -42,21 +42,25 @@ __KERNEL_RCSID(0, "$NetBSD: ahcisata_core.c,v 1.39 2012/07/26 20:49:48 jakllsch #include #include #include +#include #include +#include #include /* for SCSI status */ #include "atapibus.h" +#define AHCI_DEBUG #ifdef AHCI_DEBUG -int ahcidebug_mask = 0x0; +int ahcidebug_mask = 0; #endif static void ahci_probe_drive(struct ata_channel *); static void ahci_setup_channel(struct ata_channel *); static int ahci_ata_bio(struct ata_drive_datas *, struct ata_bio *); -static void ahci_reset_drive(struct ata_drive_datas *, int); +static int ahci_do_reset_drive(struct ata_channel *, int, int, uint32_t *); +static void ahci_reset_drive(struct ata_drive_datas *, int, uint32_t *); static void ahci_reset_channel(struct ata_channel *, int); static int ahci_exec_command(struct ata_drive_datas *, struct ata_command *); static int ahci_ata_addref(struct ata_drive_datas *); @@ -71,7 +75,8 @@ static void ahci_bio_start(struct ata_channel *, struct ata_xfer *); static int ahci_bio_complete(struct ata_channel *, struct ata_xfer *, int); static void ahci_bio_kill_xfer(struct ata_channel *, struct ata_xfer *, int) ; static void ahci_channel_stop(struct ahci_softc *, struct ata_channel *, int); -static void ahci_channel_start(struct ahci_softc *, struct ata_channel *); +static void ahci_channel_start(struct ahci_softc *, struct ata_channel *, + int, int); static void ahci_timeout(void *); static int ahci_dma_setup(struct ata_channel *, int, void *, size_t, int); @@ -206,7 +211,7 @@ ahci_enable_intrs(struct ahci_softc *sc) void ahci_attach(struct ahci_softc *sc) { - uint32_t ahci_cap, ahci_rev, ahci_ports; + uint32_t ahci_rev, ahci_ports; int i, j, port; struct ahci_channel *achp; struct ata_channel *chp; @@ -219,9 +224,9 @@ ahci_attach(struct ahci_softc *sc) if (ahci_reset(sc) != 0) return; - ahci_cap = AHCI_READ(sc, AHCI_CAP); - sc->sc_atac.atac_nchannels = (ahci_cap & AHCI_CAP_NPMASK) + 1; - sc->sc_ncmds = ((ahci_cap & AHCI_CAP_NCS) >> 8) + 1; + sc->sc_ahci_cap = AHCI_READ(sc, AHCI_CAP); + sc->sc_atac.atac_nchannels = (sc->sc_ahci_cap & AHCI_CAP_NPMASK) + 1; + sc->sc_ncmds = ((sc->sc_ahci_cap & AHCI_CAP_NCS) >> 8) + 1; ahci_rev = AHCI_READ(sc, AHCI_VS); snprintb(buf, sizeof(buf), "\177\020" /* "f\000\005NP\0" */ @@ -248,7 +253,7 @@ ahci_attach(struct ahci_softc *sc) "b\035SSNTF\0" "b\036SNCQ\0" "b\037S64A\0" - "\0", ahci_cap); + "\0", sc->sc_ahci_cap); aprint_normal_dev(sc->sc_atac.atac_dev, "AHCI revision %u.%u" ", %d ports, %d slots, CAP %s\n", AHCI_VS_MJR(ahci_rev), AHCI_VS_MNR(ahci_rev), @@ -394,7 +399,6 @@ ahci_attach(struct ahci_softc *sc) } } ahci_setup_port(sc, i); - chp->ch_ndrive = 1; if (bus_space_subregion(sc->sc_ahcit, sc->sc_ahcih, AHCI_P_SSTS(i), 4, &achp->ahcic_sstatus) != 0) { aprint_error("%s: couldn't map channel %d " @@ -542,11 +546,16 @@ ahci_intr_port(struct ahci_softc *sc, struct ahci_channel *achp) chp->ch_error = WDCE_CRC; chp->ch_status = WDCS_ERR; } + if (is & AHCI_P_IX_IFS) { + aprint_error("%s port %d: SERR 0x%x\n", + AHCINAME(sc), chp->ch_channel, + AHCI_READ(sc, AHCI_P_SERR(chp->ch_channel))); + } xfer->c_intr(chp, xfer, is); /* if channel has not been restarted, do it now */ if ((AHCI_READ(sc, AHCI_P_CMD(chp->ch_channel)) & AHCI_P_CMD_CR) == 0) - ahci_channel_start(sc, chp); + ahci_channel_start(sc, chp, 0, 0); } else { slot = 0; /* XXX */ is = AHCI_READ(sc, AHCI_P_IS(chp->ch_channel)); @@ -563,13 +572,166 @@ ahci_intr_port(struct ahci_softc *sc, struct ahci_channel *achp) } static void -ahci_reset_drive(struct ata_drive_datas *drvp, int flags) +ahci_reset_drive(struct ata_drive_datas *drvp, int flags, uint32_t *sigp) { struct ata_channel *chp = drvp->chnl_softc; - ata_reset_channel(chp, flags); + struct ahci_softc *sc = (struct ahci_softc *)chp->ch_atac; + AHCI_WRITE(sc, AHCI_GHC, + AHCI_READ(sc, AHCI_GHC) & ~AHCI_GHC_IE); + ahci_channel_stop(sc, chp, flags); + if (ahci_do_reset_drive(chp, drvp->drive, flags, sigp) != 0) + ata_reset_channel(chp, flags); + AHCI_WRITE(sc, AHCI_GHC, AHCI_READ(sc, AHCI_GHC) | AHCI_GHC_IE); return; } +/* return error code from ata_bio */ +static int +ahci_exec_fis(struct ata_channel *chp, int timeout, int flags) +{ + struct ahci_channel *achp = (struct ahci_channel *)chp; + struct ahci_softc *sc = (struct ahci_softc *)chp->ch_atac; + int i; + uint32_t is; + + timeout = timeout * 10; /* wait is 10ms */ + AHCI_CMDH_SYNC(sc, achp, 0, BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE); + /* start command */ + AHCI_WRITE(sc, AHCI_P_CI(chp->ch_channel), 1 << 0); + for (i = 0; i < timeout; i++) { + if ((AHCI_READ(sc, AHCI_P_CI(chp->ch_channel)) & 1 << 0) == 0) + return 0; + is = AHCI_READ(sc, AHCI_P_IS(chp->ch_channel)); + if (is & (AHCI_P_IX_TFES | AHCI_P_IX_HBFS | AHCI_P_IX_IFS | + AHCI_P_IX_OFS | AHCI_P_IX_UFS)) { + if ((is & (AHCI_P_IX_DHRS|AHCI_P_IX_TFES)) == + (AHCI_P_IX_DHRS|AHCI_P_IX_TFES)) { + /* + * we got the D2H FIS anyway, + * assume sig is valid. + * channel is restarted later + */ + return ERROR; + } + aprint_debug("%s channel %d: error 0x%x sending FIS\n", + AHCINAME(sc), chp->ch_channel, is); + return ERR_DF; + } + if (flags & AT_WAIT) + tsleep(&sc, PRIBIO, "ahcifis", mstohz(10)); + else + delay(10000); + } + aprint_debug("%s channel %d: timeout sending FIS\n", + AHCINAME(sc), chp->ch_channel); + return TIMEOUT; +} + +static int +ahci_do_reset_drive(struct ata_channel *chp, int drive, int flags, + uint32_t *sigp) +{ + struct ahci_channel *achp = (struct ahci_channel *)chp; + struct ahci_softc *sc = (struct ahci_softc *)chp->ch_atac; + struct ahci_cmd_tbl *cmd_tbl; + struct ahci_cmd_header *cmd_h; + int i; + uint32_t sig; + + KASSERT((AHCI_READ(sc, AHCI_P_CMD(chp->ch_channel)) & AHCI_P_CMD_CR) == 0); + /* clear port interrupt register */ + AHCI_WRITE(sc, AHCI_P_IS(chp->ch_channel), 0xffffffff); + /* clear SErrors and start operations */ + if ((sc->sc_ahci_cap & AHCI_CAP_CLO) == AHCI_CAP_CLO) { + /* + * issue a command list override to clear BSY. + * This is needed if there's a PMP with no drive + * on port 0 + */ + ahci_channel_start(sc, chp, flags, 1); + } else { + ahci_channel_start(sc, chp, flags, 0); + } + if (drive > 0) { + KASSERT(sc->sc_ahci_cap & AHCI_CAP_SPM); + } + /* polled command, assume interrupts are disabled */ + /* use slot 0 to send reset, the channel is idle */ + cmd_h = &achp->ahcic_cmdh[0]; + cmd_tbl = achp->ahcic_cmd_tbl[0]; + cmd_h->cmdh_flags = htole16(AHCI_CMDH_F_RST | AHCI_CMDH_F_CBSY | + RHD_FISLEN / 4 | (drive << AHCI_CMDH_F_PMP_SHIFT)); + cmd_h->cmdh_prdbc = 0; + memset(cmd_tbl->cmdt_cfis, 0, 64); + cmd_tbl->cmdt_cfis[fis_type] = RHD_FISTYPE; + cmd_tbl->cmdt_cfis[rhd_c] = drive; + cmd_tbl->cmdt_cfis[rhd_control] = WDCTL_RST; + switch(ahci_exec_fis(chp, 1, flags)) { + case ERR_DF: + case TIMEOUT: + aprint_error("%s channel %d: setting WDCTL_RST failed " + "for drive %d\n", AHCINAME(sc), chp->ch_channel, drive); + if (sigp) + *sigp = 0xffffffff; + goto end; + default: + break; + } + cmd_h->cmdh_flags = htole16(RHD_FISLEN / 4 | + (drive << AHCI_CMDH_F_PMP_SHIFT)); + cmd_h->cmdh_prdbc = 0; + memset(cmd_tbl->cmdt_cfis, 0, 64); + cmd_tbl->cmdt_cfis[fis_type] = RHD_FISTYPE; + cmd_tbl->cmdt_cfis[rhd_c] = drive; + cmd_tbl->cmdt_cfis[rhd_control] = 0; + switch(ahci_exec_fis(chp, 31, flags)) { + case ERR_DF: + case TIMEOUT: + aprint_error("%s channel %d: clearing WDCTL_RST failed " + "for drive %d\n", AHCINAME(sc), chp->ch_channel, drive); + if (sigp) + *sigp = 0xffffffff; + goto end; + default: + break; + } + /* + * wait 31s for BSY to clear + * This should not be needed, but some controllers clear the + * command slot before receiving the D2H FIS ... + */ + for (i = 0; i ch_channel)); + if ((((sig & AHCI_P_TFD_ST) >> AHCI_P_TFD_ST_SHIFT) + & WDCS_BSY) == 0) + break; + tsleep(&sc, PRIBIO, "ahcid2h", mstohz(10)); + } + if (i == AHCI_RST_WAIT) { + aprint_error("%s: BSY never cleared, TD 0x%x\n", + AHCINAME(sc), sig); + if (sigp) + *sigp = 0xffffffff; + goto end; + } + AHCIDEBUG_PRINT(("%s: BSY took %d ms\n", AHCINAME(sc), i * 10), + DEBUG_PROBE); + sig = AHCI_READ(sc, AHCI_P_SIG(chp->ch_channel)); + if (sigp) + *sigp = sig; + AHCIDEBUG_PRINT(("%s: port %d: sig=0x%x CMD=0x%x\n", + AHCINAME(sc), chp->ch_channel, sig, + AHCI_READ(sc, AHCI_P_CMD(chp->ch_channel))), DEBUG_PROBE); +end: + ahci_channel_stop(sc, chp, flags); + tsleep(&sc, PRIBIO, "ahcirst", mstohz(500)); + /* clear port interrupt register */ + AHCI_WRITE(sc, AHCI_P_IS(chp->ch_channel), 0xffffffff); + ahci_channel_start(sc, chp, AT_WAIT, + (sc->sc_ahci_cap & AHCI_CAP_CLO) ? 1 : 0); + return 0; +} + static void ahci_reset_channel(struct ata_channel *chp, int flags) { @@ -591,7 +753,7 @@ ahci_reset_channel(struct ata_channel *chp, int flags) /* clear port interrupt register */ AHCI_WRITE(sc, AHCI_P_IS(chp->ch_channel), 0xffffffff); /* clear SErrors and start operations */ - ahci_channel_start(sc, chp); + ahci_channel_start(sc, chp, flags, 1); /* wait 31s for BSY to clear */ for (i = 0; i ch_channel)); @@ -634,15 +796,8 @@ ahci_probe_drive(struct ata_channel *chp) { struct ahci_softc *sc = (struct ahci_softc *)chp->ch_atac; struct ahci_channel *achp = (struct ahci_channel *)chp; - int i, s; uint32_t sig; - /* XXX This should be done by other code. */ - for (i = 0; i < chp->ch_ndrive; i++) { - chp->ch_drive[i].chnl_softc = chp; - chp->ch_drive[i].drive = i; - } - /* bring interface up, accept FISs, power up and spin up device */ AHCI_WRITE(sc, AHCI_P_CMD(chp->ch_channel), AHCI_P_CMD_ICC_AC | AHCI_P_CMD_FRE | @@ -652,39 +807,19 @@ ahci_probe_drive(struct ata_channel *chp) achp->ahcic_sstatus)) { case SStatus_DET_DEV: tsleep(&sc, PRIBIO, "ahcidv", mstohz(500)); - /* clear port interrupt register */ - AHCI_WRITE(sc, AHCI_P_IS(chp->ch_channel), 0xffffffff); - /* clear SErrors and start operations */ - ahci_channel_start(sc, chp); - /* wait 31s for BSY to clear */ - for (i = 0; i ch_channel)); - if ((((sig & AHCI_P_TFD_ST) >> AHCI_P_TFD_ST_SHIFT) - & WDCS_BSY) == 0) - break; - tsleep(&sc, PRIBIO, "ahcid2h", mstohz(10)); + if (sc->sc_ahci_cap & AHCI_CAP_SPM) { + ahci_do_reset_drive(chp, PMP_PORT_CTL, AT_WAIT, &sig); + } else { + ahci_do_reset_drive(chp, 0, AT_WAIT, &sig); } - if (i == AHCI_RST_WAIT) { - aprint_error("%s: BSY never cleared, TD 0x%x\n", - AHCINAME(sc), sig); - return; + sata_interpret_sig(chp, 0, sig); + /* if we have a PMP attached, inform the controller */ + if (chp->ch_ndrives > PMP_PORT_CTL && + chp->ch_drive[PMP_PORT_CTL].drive_type == ATA_DRIVET_PM) { + AHCI_WRITE(sc, AHCI_P_CMD(chp->ch_channel), + AHCI_READ(sc, AHCI_P_CMD(chp->ch_channel)) | + AHCI_P_CMD_PMA); } - AHCIDEBUG_PRINT(("%s: BSY took %d ms\n", AHCINAME(sc), i * 10), - DEBUG_PROBE); - sig = AHCI_READ(sc, AHCI_P_SIG(chp->ch_channel)); - AHCIDEBUG_PRINT(("%s: port %d: sig=0x%x CMD=0x%x\n", - AHCINAME(sc), chp->ch_channel, sig, - AHCI_READ(sc, AHCI_P_CMD(chp->ch_channel))), DEBUG_PROBE); - /* - * 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 ((sig & 0xffff0000) == 0xeb140000) { - chp->ch_drive[0].drive_flags |= DRIVE_ATAPI; - } else - chp->ch_drive[0].drive_flags |= DRIVE_ATA; - splx(s); /* clear port interrupt register */ AHCI_WRITE(sc, AHCI_P_IS(chp->ch_channel), 0xffffffff); /* and enable interrupts */ @@ -778,6 +913,7 @@ ahci_cmd_start(struct ata_channel *chp, struct ata_xfer *xfer) cmd_tbl), DEBUG_XFERS); satafis_rhd_construct_cmd(ata_c, cmd_tbl->cmdt_cfis); + cmd_tbl->cmdt_cfis[rhd_c] |= xfer->c_drive; cmd_h = &achp->ahcic_cmdh[slot]; AHCIDEBUG_PRINT(("%s port %d header %p\n", AHCINAME(sc), @@ -793,7 +929,7 @@ ahci_cmd_start(struct ata_channel *chp, struct ata_xfer *xfer) } cmd_h->cmdh_flags = htole16( ((ata_c->flags & AT_WRITE) ? AHCI_CMDH_F_WR : 0) | - RHD_FISLEN / 4); + RHD_FISLEN / 4 | (xfer->c_drive << AHCI_CMDH_F_PMP_SHIFT)); cmd_h->cmdh_prdbc = 0; AHCI_CMDH_SYNC(sc, achp, slot, BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE); @@ -883,9 +1019,9 @@ ahci_cmd_complete(struct ata_channel *chp, struct ata_xfer *xfer, int is) chp->ch_queue->active_xfer = NULL; - if (chp->ch_drive[xfer->c_drive].drive_flags & DRIVE_WAITDRAIN) { + if (chp->ch_drive[xfer->c_drive].drive_flags & ATA_DRIVE_WAITDRAIN) { ahci_cmd_kill_xfer(chp, xfer, KILL_GONE); - chp->ch_drive[xfer->c_drive].drive_flags &= ~DRIVE_WAITDRAIN; + chp->ch_drive[xfer->c_drive].drive_flags &= ~ATA_DRIVE_WAITDRAIN; wakeup(&chp->ch_queue->active_xfer); return 0; } @@ -999,6 +1135,7 @@ ahci_bio_start(struct ata_channel *chp, struct ata_xfer *xfer) cmd_tbl), DEBUG_XFERS); satafis_rhd_construct_bio(xfer, cmd_tbl->cmdt_cfis); + cmd_tbl->cmdt_cfis[rhd_c] |= xfer->c_drive; cmd_h = &achp->ahcic_cmdh[slot]; AHCIDEBUG_PRINT(("%s port %d header %p\n", AHCINAME(sc), @@ -1012,7 +1149,7 @@ ahci_bio_start(struct ata_channel *chp, struct ata_xfer *xfer) } cmd_h->cmdh_flags = htole16( ((ata_bio->flags & ATA_READ) ? 0 : AHCI_CMDH_F_WR) | - RHD_FISLEN / 4); + RHD_FISLEN / 4 | (xfer->c_drive << AHCI_CMDH_F_PMP_SHIFT)); cmd_h->cmdh_prdbc = 0; AHCI_CMDH_SYNC(sc, achp, slot, BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE); @@ -1117,9 +1254,9 @@ ahci_bio_complete(struct ata_channel *chp, struct ata_xfer *xfer, int is) BUS_DMASYNC_POSTWRITE); bus_dmamap_unload(sc->sc_dmat, achp->ahcic_datad[slot]); - if (chp->ch_drive[xfer->c_drive].drive_flags & DRIVE_WAITDRAIN) { + if (chp->ch_drive[xfer->c_drive].drive_flags & ATA_DRIVE_WAITDRAIN) { ahci_bio_kill_xfer(chp, xfer, KILL_GONE); - chp->ch_drive[xfer->c_drive].drive_flags &= ~DRIVE_WAITDRAIN; + chp->ch_drive[xfer->c_drive].drive_flags &= ~ATA_DRIVE_WAITDRAIN; wakeup(&chp->ch_queue->active_xfer); return 0; } @@ -1164,7 +1301,7 @@ ahci_channel_stop(struct ahci_softc *sc, struct ata_channel *chp, int flags) == 0) break; if (flags & AT_WAIT) - tsleep(&sc, PRIBIO, "ahcirst", mstohz(10)); + tsleep(&sc, PRIBIO, "ahcistop", mstohz(10)); else delay(10000); } @@ -1176,16 +1313,44 @@ ahci_channel_stop(struct ahci_softc *sc, struct ata_channel *chp, int flags) } static void -ahci_channel_start(struct ahci_softc *sc, struct ata_channel *chp) +ahci_channel_start(struct ahci_softc *sc, struct ata_channel *chp, + int flags, int clo) { + int i; + uint32_t p_cmd; /* clear error */ AHCI_WRITE(sc, AHCI_P_SERR(chp->ch_channel), AHCI_READ(sc, AHCI_P_SERR(chp->ch_channel))); + if (clo) { + /* issue command list override */ + KASSERT(sc->sc_ahci_cap & AHCI_CAP_CLO); + AHCI_WRITE(sc, AHCI_P_CMD(chp->ch_channel), + AHCI_READ(sc, AHCI_P_CMD(chp->ch_channel)) | AHCI_P_CMD_CLO); + /* wait 1s for AHCI_CAP_CLO to clear */ + for (i = 0; i <100; i++) { + if ((AHCI_READ(sc, AHCI_P_CMD(chp->ch_channel)) & + AHCI_P_CMD_CLO) == 0) + break; + if (flags & AT_WAIT) + tsleep(&sc, PRIBIO, "ahciclo", mstohz(10)); + else + delay(10000); + } + if (AHCI_READ(sc, AHCI_P_CMD(chp->ch_channel)) & AHCI_P_CMD_CLO) { + printf("%s: channel wouldn't CLO\n", AHCINAME(sc)); + /* XXX controller reset ? */ + return; + } + } /* and start controller */ - AHCI_WRITE(sc, AHCI_P_CMD(chp->ch_channel), - AHCI_P_CMD_ICC_AC | AHCI_P_CMD_POD | AHCI_P_CMD_SUD | - AHCI_P_CMD_FRE | AHCI_P_CMD_ST); + p_cmd = AHCI_P_CMD_ICC_AC | AHCI_P_CMD_POD | AHCI_P_CMD_SUD | + AHCI_P_CMD_FRE | AHCI_P_CMD_ST; + if (chp->ch_ndrives > PMP_PORT_CTL && + chp->ch_drive[PMP_PORT_CTL].drive_type == ATA_DRIVET_PM) { + p_cmd |= AHCI_P_CMD_PMA; + } + AHCI_WRITE(sc, AHCI_P_CMD(chp->ch_channel), p_cmd); } static void @@ -1378,6 +1543,7 @@ ahci_atapi_start(struct ata_channel *chp, struct ata_xfer *xfer) cmd_tbl), DEBUG_XFERS); satafis_rhd_construct_atapi(xfer, cmd_tbl->cmdt_cfis); + cmd_tbl->cmdt_cfis[rhd_c] |= xfer->c_drive; memset(&cmd_tbl->cmdt_acmd, 0, sizeof(cmd_tbl->cmdt_acmd)); memcpy(cmd_tbl->cmdt_acmd, sc_xfer->cmd, sc_xfer->cmdlen); @@ -1394,7 +1560,8 @@ ahci_atapi_start(struct ata_channel *chp, struct ata_xfer *xfer) } cmd_h->cmdh_flags = htole16( ((sc_xfer->xs_control & XS_CTL_DATA_OUT) ? AHCI_CMDH_F_WR : 0) | - RHD_FISLEN / 4 | AHCI_CMDH_F_A); + RHD_FISLEN / 4 | AHCI_CMDH_F_A | + (xfer->c_drive << AHCI_CMDH_F_PMP_SHIFT)); cmd_h->cmdh_prdbc = 0; AHCI_CMDH_SYNC(sc, achp, slot, BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE); @@ -1468,9 +1635,9 @@ ahci_atapi_complete(struct ata_channel *chp, struct ata_xfer *xfer, int irq) BUS_DMASYNC_POSTWRITE); bus_dmamap_unload(sc->sc_dmat, achp->ahcic_datad[slot]); - if (chp->ch_drive[drive].drive_flags & DRIVE_WAITDRAIN) { + if (chp->ch_drive[drive].drive_flags & ATA_DRIVE_WAITDRAIN) { ahci_atapi_kill_xfer(chp, xfer, KILL_GONE); - chp->ch_drive[drive].drive_flags &= ~DRIVE_WAITDRAIN; + chp->ch_drive[drive].drive_flags &= ~ATA_DRIVE_WAITDRAIN; wakeup(&chp->ch_queue->active_xfer); return 0; } @@ -1545,7 +1712,7 @@ ahci_atapi_probe_device(struct atapibus_softc *sc, int target) return; /* if no ATAPI device detected at attach time, skip */ - if ((drvp->drive_flags & DRIVE_ATAPI) == 0) { + if (drvp->drive_type != ATA_DRIVET_ATAPI) { AHCIDEBUG_PRINT(("ahci_atapi_probe_device: drive %d " "not present\n", target), DEBUG_PROBE); return; @@ -1584,7 +1751,7 @@ ahci_atapi_probe_device(struct atapibus_softc *sc, int target) periph->periph_flags |= PERIPH_REMOVABLE; if (periph->periph_type == T_SEQUENTIAL) { s = splbio(); - drvp->drive_flags |= DRIVE_ATAPIST; + drvp->drive_flags |= ATA_DRIVE_ATAPIDSCW; splx(s); } @@ -1615,7 +1782,7 @@ ahci_atapi_probe_device(struct atapibus_softc *sc, int target) ata_probe_caps(drvp); else { s = splbio(); - drvp->drive_flags &= ~DRIVE_ATAPI; + drvp->drive_type = ATA_DRIVET_NONE; splx(s); } } else { @@ -1624,7 +1791,7 @@ ahci_atapi_probe_device(struct atapibus_softc *sc, int target) AHCINAME(ahcic), chp->ch_channel, target, chp->ch_error), DEBUG_PROBE); s = splbio(); - drvp->drive_flags &= ~DRIVE_ATAPI; + drvp->drive_type = ATA_DRIVET_NONE; splx(s); } } diff --git a/sys/dev/ic/ahcisatavar.h b/sys/dev/ic/ahcisatavar.h index c70ada8f1ec..d07b428533d 100644 --- a/sys/dev/ic/ahcisatavar.h +++ b/sys/dev/ic/ahcisatavar.h @@ -1,4 +1,4 @@ -/* $NetBSD: ahcisatavar.h,v 1.9 2012/07/26 20:49:48 jakllsch Exp $ */ +/* $NetBSD: ahcisatavar.h,v 1.10 2012/07/31 15:50:34 bouyer Exp $ */ /* * Copyright (c) 2006 Manuel Bouyer. @@ -55,6 +55,7 @@ struct ahci_softc { int sc_cmd_hdr_nseg; int sc_atac_capflags; + int32_t sc_ahci_cap; /* copy of AHCI_CAP */ int sc_ncmds; /* number of command slots */ struct ata_channel *sc_chanarray[AHCI_MAX_PORTS]; struct ahci_channel { diff --git a/sys/dev/ic/mvsata.c b/sys/dev/ic/mvsata.c index a3f0fce1e1b..86dc85c1446 100644 --- a/sys/dev/ic/mvsata.c +++ b/sys/dev/ic/mvsata.c @@ -1,4 +1,4 @@ -/* $NetBSD: mvsata.c,v 1.23 2012/07/26 20:49:48 jakllsch Exp $ */ +/* $NetBSD: mvsata.c,v 1.24 2012/07/31 15:50:34 bouyer Exp $ */ /* * Copyright (c) 2008 KIYOHARA Takashi * All rights reserved. @@ -26,11 +26,11 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: mvsata.c,v 1.23 2012/07/26 20:49:48 jakllsch Exp $"); +__KERNEL_RCSID(0, "$NetBSD: mvsata.c,v 1.24 2012/07/31 15:50:34 bouyer Exp $"); #include "opt_mvsata.h" -/* ATAPI implementation not finished. Also don't work shadow registers? */ +/* ATAPI implementation not finished. */ //#include "atapibus.h" #include @@ -76,13 +76,17 @@ __KERNEL_RCSID(0, "$NetBSD: mvsata.c,v 1.23 2012/07/26 20:49:48 jakllsch Exp $") #define MVSATA_EDMA_WRITE_4(mvport, reg, val) \ bus_space_write_4((mvport)->port_iot, (mvport)->port_ioh, (reg), (val)) #define MVSATA_WDC_READ_2(mvport, reg) \ - bus_space_read_2((mvport)->port_iot, (mvport)->port_ioh, (reg)) + bus_space_read_2((mvport)->port_iot, (mvport)->port_ioh, \ + SHADOW_REG_BLOCK_OFFSET + (reg)) #define MVSATA_WDC_READ_1(mvport, reg) \ - bus_space_read_1((mvport)->port_iot, (mvport)->port_ioh, (reg)) + bus_space_read_1((mvport)->port_iot, (mvport)->port_ioh, \ + SHADOW_REG_BLOCK_OFFSET + (reg)) #define MVSATA_WDC_WRITE_2(mvport, reg, val) \ - bus_space_write_2((mvport)->port_iot, (mvport)->port_ioh, (reg), (val)) + bus_space_write_2((mvport)->port_iot, (mvport)->port_ioh, \ + SHADOW_REG_BLOCK_OFFSET + (reg), (val)) #define MVSATA_WDC_WRITE_1(mvport, reg, val) \ - bus_space_write_1((mvport)->port_iot, (mvport)->port_ioh, (reg), (val)) + bus_space_write_1((mvport)->port_iot, (mvport)->port_ioh, \ + SHADOW_REG_BLOCK_OFFSET + (reg), (val)) #ifdef MVSATA_DEBUG #define DPRINTF(x) if (mvsata_debug) printf x @@ -103,7 +107,7 @@ int mvsata_debug = 2; #ifndef MVSATA_WITHOUTDMA static int mvsata_bio(struct ata_drive_datas *, struct ata_bio *); -static void mvsata_reset_drive(struct ata_drive_datas *, int); +static void mvsata_reset_drive(struct ata_drive_datas *, int, uint32_t *); static void mvsata_reset_channel(struct ata_channel *, int); static int mvsata_exec_command(struct ata_drive_datas *, struct ata_command *); static int mvsata_addref(struct ata_drive_datas *); @@ -304,6 +308,7 @@ mvsata_attach(struct mvsata_softc *sc, struct mvsata_product *product, sc->sc_wdcdev.sc_atac.atac_atapibus_attach = mvsata_atapibus_attach; #endif #endif + sc->sc_wdcdev.wdc_maxdrives = 1; /* SATA is always 1 drive */ sc->sc_wdcdev.sc_atac.atac_probe = wdc_sataprobe; sc->sc_wdcdev.sc_atac.atac_set_modes = mvsata_setup_channel; @@ -504,7 +509,7 @@ mvsata_bio(struct ata_drive_datas *drvp, struct ata_bio *ata_bio) ata_bio->flags |= ATA_POLL; if (ata_bio->flags & ATA_POLL) xfer->c_flags |= C_POLL; - if ((drvp->drive_flags & (DRIVE_DMA | DRIVE_UDMA)) && + if ((drvp->drive_flags & (ATA_DRIVE_DMA | ATA_DRIVE_UDMA)) && (ata_bio->flags & ATA_SINGLE) == 0) xfer->c_flags |= C_DMA; xfer->c_drive = drvp->drive; @@ -519,12 +524,14 @@ mvsata_bio(struct ata_drive_datas *drvp, struct ata_bio *ata_bio) } static void -mvsata_reset_drive(struct ata_drive_datas *drvp, int flags) +mvsata_reset_drive(struct ata_drive_datas *drvp, int flags, uint32_t *sigp) { struct ata_channel *chp = drvp->chnl_softc; struct mvsata_port *mvport = (struct mvsata_port *)chp; uint32_t edma_c; + KASSERT(sigp == NULL); + edma_c = MVSATA_EDMA_READ_4(mvport, EDMA_CMD); DPRINTF(("%s:%d: mvsata_reset_drive: drive=%d (EDMA %sactive)\n", @@ -789,7 +796,7 @@ mvsata_atapi_probe_device(struct atapibus_softc *sc, int target) return; /* if no ATAPI device detected at attach time, skip */ - if ((drvp->drive_flags & DRIVE_ATAPI) == 0) { + if (drvp->drive_type != ATA_DRIVET_ATAPI) { DPRINTF(("%s:%d: mvsata_atapi_probe_device:" " drive %d not present\n", device_xname(atac->atac_dev), chp->ch_channel, target)); @@ -830,7 +837,7 @@ mvsata_atapi_probe_device(struct atapibus_softc *sc, int target) periph->periph_flags |= PERIPH_REMOVABLE; if (periph->periph_type == T_SEQUENTIAL) { s = splbio(); - drvp->drive_flags |= DRIVE_ATAPIST; + drvp->drive_flags |= ATA_DRIVE_ATAPIDSCW; splx(s); } @@ -860,7 +867,7 @@ mvsata_atapi_probe_device(struct atapibus_softc *sc, int target) ata_probe_caps(drvp); else { s = splbio(); - drvp->drive_flags &= ~DRIVE_ATAPI; + drvp->drive_type = ATA_DRIVET_NONE; splx(s); } } else { @@ -869,7 +876,7 @@ mvsata_atapi_probe_device(struct atapibus_softc *sc, int target) device_xname(atac->atac_dev), chp->ch_channel, target, chp->ch_error)); s = splbio(); - drvp->drive_flags &= ~DRIVE_ATAPI; + drvp->drive_type = ATA_DRIVET_NONE; splx(s); } } @@ -918,22 +925,22 @@ mvsata_setup_channel(struct ata_channel *chp) device_xname(MVSATA_DEV2(mvport)), chp->ch_channel)); edma_mode = nodma; - for (drive = 0; drive < chp->ch_ndrive; drive++) { + for (drive = 0; drive < chp->ch_ndrives; drive++) { drvp = &chp->ch_drive[drive]; /* If no drive, skip */ - if (!(drvp->drive_flags & DRIVE)) + if (drvp->drive_type == ATA_DRIVET_NONE) continue; - if (drvp->drive_flags & DRIVE_UDMA) { + if (drvp->drive_flags & ATA_DRIVE_UDMA) { /* use Ultra/DMA */ s = splbio(); - drvp->drive_flags &= ~DRIVE_DMA; + drvp->drive_flags &= ~ATA_DRIVE_DMA; splx(s); } - if (drvp->drive_flags & (DRIVE_UDMA | DRIVE_DMA)) - if (drvp->drive_flags & DRIVE_ATA) + if (drvp->drive_flags & (ATA_DRIVE_UDMA | ATA_DRIVE_DMA)) + if (drvp->drive_type == ATA_DRIVET_ATA) edma_mode = dma; } @@ -978,14 +985,14 @@ no_edma: aprint_error_dev(MVSATA_DEV2(mvport), "channel %d: can't use EDMA\n", chp->ch_channel); s = splbio(); - for (drive = 0; drive < chp->ch_ndrive; drive++) { + for (drive = 0; drive < chp->ch_ndrives; drive++) { drvp = &chp->ch_drive[drive]; /* If no drive, skip */ - if (!(drvp->drive_flags & DRIVE)) + if (drvp->drive_type == ATA_DRIVET_NONE) continue; - drvp->drive_flags &= ~(DRIVE_UDMA | DRIVE_DMA); + drvp->drive_flags &= ~(ATA_DRIVE_UDMA | ATA_DRIVE_DMA); } splx(s); goto no_edma; @@ -1397,9 +1404,9 @@ mvsata_bio_done(struct ata_channel *chp, struct ata_xfer *xfer) chp->ch_queue->active_xfer = NULL; ata_free_xfer(chp, xfer); - if (chp->ch_drive[drive].drive_flags & DRIVE_WAITDRAIN) { + if (chp->ch_drive[drive].drive_flags & ATA_DRIVE_WAITDRAIN) { ata_bio->error = ERR_NODEV; - chp->ch_drive[drive].drive_flags &= ~DRIVE_WAITDRAIN; + chp->ch_drive[drive].drive_flags &= ~ATA_DRIVE_WAITDRAIN; wakeup(&chp->ch_queue->active_xfer); } ata_bio->flags |= ATA_ITSDONE; @@ -1440,7 +1447,7 @@ mvsata_bio_ready(struct mvsata_port *mvport, struct ata_bio *ata_bio, int drive, if (atac->atac_set_modes == NULL) goto geometry; /* Also don't try if the drive didn't report its mode */ - if ((drvp->drive_flags & DRIVE_MODE) == 0) + if ((drvp->drive_flags & ATA_DRIVE_MODE) == 0) goto geometry; wdccommand(chp, drvp->drive, SET_FEATURES, 0, 0, 0, 0x08 | drvp->PIO_mode, WDSF_SET_MODE); @@ -1449,10 +1456,10 @@ mvsata_bio_ready(struct mvsata_port *mvport, struct ata_bio *ata_bio, int drive, goto ctrltimeout; if (chp->ch_status & (WDCS_ERR | WDCS_DWF)) goto ctrlerror; - if (drvp->drive_flags & DRIVE_UDMA) + if (drvp->drive_flags & ATA_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) + else if (drvp->drive_flags & ATA_DRIVE_DMA) wdccommand(chp, drvp->drive, SET_FEATURES, 0, 0, 0, 0x20 | drvp->DMA_mode, WDSF_SET_MODE); else @@ -1590,7 +1597,7 @@ mvsata_wdc_cmd_intr(struct ata_channel *chp, struct ata_xfer *xfer, int irq) * Historically it's what we have always done so keeping it * here ensure binary backward compatibility. */ - drive_flags = DRIVE_NOSTREAM | + drive_flags = ATA_DRIVE_NOSTREAM | chp->ch_drive[xfer->c_drive].drive_flags; else /* @@ -1736,7 +1743,7 @@ mvsata_wdc_cmd_done(struct ata_channel *chp, struct ata_xfer *xfer) } ata_c->r_count |= MVSATA_WDC_READ_1(mvport, SRB_SC) << 8; - ata_c->r_lba = + ata_c->r_lba |= (uint64_t)MVSATA_WDC_READ_1(mvport, SRB_LBAL) << 24; ata_c->r_lba |= (uint64_t)MVSATA_WDC_READ_1(mvport, SRB_LBAM) << 32; @@ -1761,9 +1768,9 @@ mvsata_wdc_cmd_done(struct ata_channel *chp, struct ata_xfer *xfer) MVSATA_WDC_WRITE_1(mvport, SRB_CAS, WDCTL_4BIT); delay(10); /* some drives need a little delay here */ } - if (chp->ch_drive[xfer->c_drive].drive_flags & DRIVE_WAITDRAIN) { + if (chp->ch_drive[xfer->c_drive].drive_flags & ATA_DRIVE_WAITDRAIN) { mvsata_wdc_cmd_kill_xfer(chp, xfer, KILL_GONE); - chp->ch_drive[xfer->c_drive].drive_flags &= ~DRIVE_WAITDRAIN; + chp->ch_drive[xfer->c_drive].drive_flags &= ~ATA_DRIVE_WAITDRAIN; wakeup(&chp->ch_queue->active_xfer); } else mvsata_wdc_cmd_done_end(chp, xfer); @@ -1833,7 +1840,7 @@ mvsata_atapi_start(struct ata_channel *chp, struct ata_xfer *xfer) if (atac->atac_set_modes == NULL) goto ready; /* Also don't try if the drive didn't report its mode */ - if ((drvp->drive_flags & DRIVE_MODE) == 0) + if ((drvp->drive_flags & ATA_DRIVE_MODE) == 0) goto ready; errstring = "unbusy"; if (wdc_wait_for_unbusy(chp, ATAPI_DELAY, wait_flags)) @@ -1860,11 +1867,11 @@ mvsata_atapi_start(struct ata_channel *chp, struct ata_xfer *xfer) } else goto error; } - if (drvp->drive_flags & DRIVE_UDMA) + if (drvp->drive_flags & ATA_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) + if (drvp->drive_flags & ATA_DRIVE_DMA) wdccommand(chp, drvp->drive, SET_FEATURES, 0, 0, 0, 0x20 | drvp->DMA_mode, WDSF_SET_MODE); else @@ -1874,7 +1881,7 @@ mvsata_atapi_start(struct ata_channel *chp, struct ata_xfer *xfer) goto timeout; if (chp->ch_status & WDCS_ERR) { if (chp->ch_error == WDCE_ABRT) { - if (drvp->drive_flags & DRIVE_UDMA) + if (drvp->drive_flags & ATA_DRIVE_UDMA) goto error; else { /* @@ -2248,7 +2255,7 @@ mvsata_atapi_phase_complete(struct ata_xfer *xfer) struct ata_drive_datas *drvp = &chp->ch_drive[xfer->c_drive]; /* wait for DSC if needed */ - if (drvp->drive_flags & DRIVE_ATAPIST) { + if (drvp->drive_flags & ATA_DRIVE_ATAPIDSCW) { DPRINTFN(1, ("%s:%d:%d: mvsata_atapi_phase_complete: polldsc %d\n", device_xname(atac->atac_dev), chp->ch_channel, @@ -2333,9 +2340,9 @@ mvsata_atapi_done(struct ata_channel *chp, struct ata_xfer *xfer) chp->ch_queue->active_xfer = NULL; ata_free_xfer(chp, xfer); - if (chp->ch_drive[drive].drive_flags & DRIVE_WAITDRAIN) { + if (chp->ch_drive[drive].drive_flags & ATA_DRIVE_WAITDRAIN) { sc_xfer->error = XS_DRIVER_STUFFUP; - chp->ch_drive[drive].drive_flags &= ~DRIVE_WAITDRAIN; + chp->ch_drive[drive].drive_flags &= ~ATA_DRIVE_WAITDRAIN; wakeup(&chp->ch_queue->active_xfer); } @@ -2823,7 +2830,6 @@ mvsata_port_init(struct mvsata_hc *mvhc, int port) chp = &mvport->port_ata_channel; chp->ch_channel = channel; chp->ch_atac = &sc->sc_wdcdev.sc_atac; - chp->ch_ndrive = 1; /* SATA is always 1 drive */ chp->ch_queue = &mvport->port_ata_queue; sc->sc_ata_channels[channel] = chp; diff --git a/sys/dev/ic/ninjaata32.c b/sys/dev/ic/ninjaata32.c index edbcec9bbc4..e044c8ad246 100644 --- a/sys/dev/ic/ninjaata32.c +++ b/sys/dev/ic/ninjaata32.c @@ -1,4 +1,4 @@ -/* $NetBSD: ninjaata32.c,v 1.17 2012/07/26 20:49:48 jakllsch Exp $ */ +/* $NetBSD: ninjaata32.c,v 1.18 2012/07/31 15:50:34 bouyer Exp $ */ /* * Copyright (c) 2006 ITOH Yasufumi. @@ -27,7 +27,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: ninjaata32.c,v 1.17 2012/07/26 20:49:48 jakllsch Exp $"); +__KERNEL_RCSID(0, "$NetBSD: ninjaata32.c,v 1.18 2012/07/31 15:50:34 bouyer Exp $"); #include #include @@ -192,7 +192,7 @@ njata32_attach(struct njata32_softc *sc) sc->sc_ch[0].ch_ata_channel.ch_channel = 0; sc->sc_ch[0].ch_ata_channel.ch_atac = &sc->sc_wdcdev.sc_atac; sc->sc_ch[0].ch_ata_channel.ch_queue = &sc->sc_wdc_chqueue; - sc->sc_ch[0].ch_ata_channel.ch_ndrive = 2; /* max number of drives */ + sc->sc_wdcdev.wdc_maxdrives = 2; /* max number of drives per channel */ /* map ATA registers */ for (i = 0; i < WDC_NREG; i++) { @@ -317,20 +317,20 @@ njata32_setup_channel(struct ata_channel *chp) int drive; uint8_t mode; - KASSERT(chp->ch_ndrive != 0); + KASSERT(chp->ch_ndrives != 0); sc->sc_timing_pio = 0; #if 0 /* ATA DMA is currently unused */ sc->sc_timing_dma = 0; #endif - for (drive = 0; drive < chp->ch_ndrive; drive++) { + for (drive = 0; drive < chp->ch_ndrives; drive++) { drvp = &chp->ch_drive[drive]; - if ((drvp->drive_flags & DRIVE) == 0) + if (drvp->drive_type == ATA_DRIVET_NONE) continue; /* no drive */ #if 0 /* ATA DMA is currently unused */ - if ((drvp->drive_flags & DRIVE_DMA) != 0) { + if ((drvp->drive_flags & ATA_DRIVE_DMA) != 0) { /* * Multiword DMA */ diff --git a/sys/dev/ic/siisata.c b/sys/dev/ic/siisata.c index 7d7f467def9..c7737200fe9 100644 --- a/sys/dev/ic/siisata.c +++ b/sys/dev/ic/siisata.c @@ -1,4 +1,4 @@ -/* $NetBSD: siisata.c,v 1.21 2012/07/26 20:49:48 jakllsch Exp $ */ +/* $NetBSD: siisata.c,v 1.22 2012/07/31 15:50:34 bouyer Exp $ */ /* from ahcisata_core.c */ @@ -79,7 +79,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: siisata.c,v 1.21 2012/07/26 20:49:48 jakllsch Exp $"); +__KERNEL_RCSID(0, "$NetBSD: siisata.c,v 1.22 2012/07/31 15:50:34 bouyer Exp $"); #include #include @@ -96,6 +96,7 @@ __KERNEL_RCSID(0, "$NetBSD: siisata.c,v 1.21 2012/07/26 20:49:48 jakllsch Exp $" #include #include #include +#include #include #include @@ -116,7 +117,7 @@ void siisata_probe_drive(struct ata_channel *); void siisata_setup_channel(struct ata_channel *); int siisata_ata_bio(struct ata_drive_datas *, struct ata_bio *); -void siisata_reset_drive(struct ata_drive_datas *, int); +void siisata_reset_drive(struct ata_drive_datas *, int, uint32_t *); void siisata_reset_channel(struct ata_channel *, int); int siisata_ata_addref(struct ata_drive_datas *); void siisata_ata_delref(struct ata_drive_datas *); @@ -345,7 +346,6 @@ siisata_attach_port(struct siisata_softc *sc, int port) } } - chp->ch_ndrive = 1; if (bus_space_subregion(sc->sc_prt, sc->sc_prh, PRX(chp->ch_channel, PRO_SSTATUS), 4, &schp->sch_sstatus) != 0) { aprint_error_dev(sc->sc_atac.atac_dev, @@ -462,23 +462,29 @@ siisata_intr_port(struct siisata_channel *schp) xfer = chp->ch_queue->active_xfer; slot = SIISATA_NON_NCQ_SLOT; - SIISATA_DEBUG_PRINT(("%s: %s port %d\n", - SIISATANAME(sc), __func__, chp->ch_channel), DEBUG_INTR); - pis = PRREAD(sc, PRX(chp->ch_channel, PRO_PIS)); + SIISATA_DEBUG_PRINT(("%s: %s port %d, pis 0x%x ", + SIISATANAME(sc), __func__, chp->ch_channel, pis), DEBUG_INTR); + if (pis & PR_PIS_CMDCMPL) { /* get slot status, clearing completion interrupt */ pss = PRREAD(sc, PRX(chp->ch_channel, PRO_PSS)); + SIISATA_DEBUG_PRINT(("pss 0x%x\n", pss), DEBUG_INTR); /* is this expected? */ /* XXX improve */ if ((schp->sch_active_slots & __BIT(slot)) == 0) { - PRWRITE(sc, PRX(chp->ch_channel, PRO_PIS), 0xffffffff); - log(LOG_WARNING, "%s: unexpected command " + aprint_error( "%s: unexpected command " "completion on port %d\n", SIISATANAME(sc), chp->ch_channel); return; } + if ((~pss & __BIT(slot)) == 0) { + aprint_error( "%s: unknown slot " + "completion on port %d, pss 0x%x\n", + SIISATANAME(sc), chp->ch_channel, pss); + return; + } } else if (pis & PR_PIS_CMDERRR) { uint32_t ec; @@ -487,8 +493,9 @@ siisata_intr_port(struct siisata_channel *schp) chp->ch_error = WDCE_CRC; ec = PRREAD(sc, PRX(chp->ch_channel, PRO_PCE)); + SIISATA_DEBUG_PRINT(("ec %d\n", ec), DEBUG_INTR); if (ec <= PR_PCE_DATAFISERROR) { - if (ec == PR_PCE_DEVICEERROR) { + if (ec == PR_PCE_DEVICEERROR && xfer != NULL) { /* read in specific information about error */ prbfis = bus_space_read_stream_4( sc->sc_prt, sc->sc_prh, @@ -498,9 +505,10 @@ siisata_intr_port(struct siisata_channel *schp) } siisata_reinit_port(chp); } else { - aprint_error_dev(sc->sc_atac.atac_dev, - "fatal error %d on channel %d, resetting\n", - ec, chp->ch_channel); + aprint_error_dev(sc->sc_atac.atac_dev, "fatal error %d" + " on channel %d (ctx 0x%x), resetting\n", + ec, chp->ch_channel, + PRREAD(sc, PRX(chp->ch_channel, PRO_PCR))); /* okay, we have a "Fatal Error" */ siisata_device_reset(chp); } @@ -515,7 +523,7 @@ siisata_intr_port(struct siisata_channel *schp) } void -siisata_reset_drive(struct ata_drive_datas *drvp, int flags) +siisata_reset_drive(struct ata_drive_datas *drvp, int flags, uint32_t *sigp) { struct ata_channel *chp = drvp->chnl_softc; struct siisata_softc *sc = (struct siisata_softc *)chp->ch_atac; @@ -532,21 +540,37 @@ siisata_reset_drive(struct ata_drive_datas *drvp, int flags) memset(prb, 0, sizeof(struct siisata_prb)); prb->prb_control = htole16(PRB_CF_SOFT_RESET | PRB_CF_INTERRUPT_MASK); + KASSERT(drvp->drive <= PMP_PORT_CTL); + prb->prb_fis[rhd_c] = drvp->drive; siisata_activate_prb(schp, slot); - for(i = 0; i < 31000; i++) { - if (PRREAD(sc, PRX(chp->ch_channel, PRO_PSS)) & - PR_PXSS(slot)) - DELAY(1000); - else + for(i = 0; i < 3100; i++) { + if ((PRREAD(sc, PRX(chp->ch_channel, PRO_PSS)) & + PR_PXSS(slot)) == 0) break; + if (flags & AT_WAIT) + tsleep(schp, PRIBIO, "siiprb", mstohz(10)); + else + DELAY(10000); } siisata_deactivate_prb(schp, slot); - - log(LOG_DEBUG, "%s: port %d: ch_status %x ch_error %x\n", - __func__, chp->ch_channel, chp->ch_status, chp->ch_error); + if (i == 3100) { + /* timeout */ + siisata_device_reset(chp); + if (sigp) + *sigp = 0xffffffff; + } else { + /* read the signature out of the FIS */ + if (sigp) { + *sigp = 0; + *sigp |= (PRREAD(sc, PRSX(chp->ch_channel, slot, + PRSO_FIS+0x4)) & 0x00ffffff) << 8; + *sigp |= PRREAD(sc, PRSX(chp->ch_channel, slot, + PRSO_FIS+0xc)) & 0xff; + } + } #if 1 /* attempt to downgrade signaling in event of CRC error */ @@ -571,7 +595,6 @@ siisata_reset_drive(struct ata_drive_datas *drvp, int flags) chp->ch_status = 0; chp->ch_error = 0; #endif - return; } @@ -627,7 +650,6 @@ siisata_probe_drive(struct ata_channel *chp) struct siisata_softc *sc = (struct siisata_softc *)chp->ch_atac; struct siisata_channel *schp = (struct siisata_channel *)chp; int i; - int s; uint32_t sig; int slot = SIISATA_NON_NCQ_SLOT; struct siisata_prb *prb; @@ -636,12 +658,6 @@ siisata_probe_drive(struct ata_channel *chp) SIISATA_DEBUG_PRINT(("%s: %s: port %d start\n", SIISATANAME(sc), __func__, chp->ch_channel), DEBUG_FUNCS); - /* XXX This should be done by other code. */ - for (i = 0; i < chp->ch_ndrive; i++) { - chp->ch_drive[i].chnl_softc = chp; - chp->ch_drive[i].drive = i; - } - /* * disable port interrupt as we're polling for PHY up and * prb completion @@ -661,6 +677,7 @@ siisata_probe_drive(struct ata_channel *chp) prb = schp->sch_prb[slot]; memset(prb, 0, sizeof(struct siisata_prb)); prb->prb_control = htole16(PRB_CF_SOFT_RESET); + prb->prb_fis[rhd_c] = PMP_PORT_CTL; siisata_activate_prb(schp, slot); @@ -703,28 +720,10 @@ siisata_probe_drive(struct ata_channel *chp) SIISATA_DEBUG_PRINT(("%s: %s: sig=0x%08x\n", SIISATANAME(sc), __func__, sig), DEBUG_PROBE); - /* some ATAPI devices have bogus lower two bytes, sigh */ - if ((sig & 0xffff0000) == 0xeb140000) { - sig &= 0xffff0000; - sig |= 0x00000101; - } - - s = splbio(); - switch (sig) { - case 0xeb140101: - chp->ch_drive[0].drive_flags |= DRIVE_ATAPI; - break; - case 0x00000101: - chp->ch_drive[0].drive_flags |= DRIVE_ATA; - break; - default: - chp->ch_drive[0].drive_flags |= DRIVE_ATA; - aprint_verbose_dev(sc->sc_atac.atac_dev, - "Unrecognized signature 0x%08x on port %d. " - "Assuming it's a disk.\n", sig, chp->ch_channel); - break; - } - splx(s); + if (sig == 0x96690101) + PRWRITE(sc, PRX(chp->ch_channel, PRO_PCS), + PR_PC_PMP_ENABLE); + sata_interpret_sig(chp, 0, sig); break; default: break; @@ -808,8 +807,11 @@ siisata_cmd_start(struct ata_channel *chp, struct ata_xfer *xfer) struct siisata_prb *prb; int i; - SIISATA_DEBUG_PRINT(("%s: %s port %d, slot %d\n", - SIISATANAME(sc), __func__, chp->ch_channel, slot), DEBUG_FUNCS); + SIISATA_DEBUG_PRINT(("%s: %s port %d drive %d command 0x%x, slot %d\n", + SIISATANAME((struct siisata_softc *)chp->ch_atac), + __func__, chp->ch_channel, xfer->c_drive, + ata_c->r_command, slot), + DEBUG_FUNCS|DEBUG_XFERS); chp->ch_status = 0; chp->ch_error = 0; @@ -818,6 +820,8 @@ siisata_cmd_start(struct ata_channel *chp, struct ata_xfer *xfer) memset(prb, 0, sizeof(struct siisata_prb)); satafis_rhd_construct_cmd(ata_c, prb->prb_fis); + KASSERT(xfer->c_drive <= PMP_PORT_CTL); + prb->prb_fis[rhd_c] |= xfer->c_drive; memset(prb->prb_atapi, 0, sizeof(prb->prb_atapi)); @@ -857,15 +861,14 @@ siisata_cmd_start(struct ata_channel *chp, struct ata_xfer *xfer) } if ((ata_c->flags & AT_DONE) == 0) { - ata_c->flags |= AT_TIMEOU; - siisata_cmd_complete(chp, xfer, slot); + siisata_timeout(chp); } /* reenable interrupts */ siisata_enable_port_interrupt(chp); out: SIISATA_DEBUG_PRINT( - ("%s: %s: done\n", SIISATANAME(sc), __func__), DEBUG_FUNCS); + ("%s: %s: done\n", SIISATANAME((struct siisata_softc *)chp->ch_atac), __func__), DEBUG_FUNCS); return; } @@ -899,7 +902,7 @@ siisata_cmd_complete(struct ata_channel *chp, struct ata_xfer *xfer, int slot) #endif SIISATA_DEBUG_PRINT( - ("%s: %s\n", SIISATANAME(sc), __func__), DEBUG_FUNCS); + ("%s: %s\n", SIISATANAME(sc), __func__), DEBUG_FUNCS|DEBUG_XFERS); chp->ch_flags &= ~ATACH_IRQ_WAIT; if (xfer->c_flags & C_TIMEOU) @@ -914,9 +917,9 @@ siisata_cmd_complete(struct ata_channel *chp, struct ata_xfer *xfer, int slot) ata_c->flags |= AT_ERROR; } - if (chp->ch_drive[xfer->c_drive].drive_flags & DRIVE_WAITDRAIN) { + if (chp->ch_drive[xfer->c_drive].drive_flags & ATA_DRIVE_WAITDRAIN) { siisata_cmd_kill_xfer(chp, xfer, KILL_GONE); - chp->ch_drive[xfer->c_drive].drive_flags &= ~DRIVE_WAITDRAIN; + chp->ch_drive[xfer->c_drive].drive_flags &= ~ATA_DRIVE_WAITDRAIN; wakeup(&chp->ch_queue->active_xfer); return 0; } else @@ -936,7 +939,8 @@ siisata_cmd_done(struct ata_channel *chp, struct ata_xfer *xfer, int slot) int i; SIISATA_DEBUG_PRINT( - ("%s: %s.\n", SIISATANAME(sc), __func__), DEBUG_FUNCS); + ("%s: %s flags 0x%x error 0x%x\n", SIISATANAME(sc), __func__, + ata_c->flags, ata_c->r_error), DEBUG_FUNCS|DEBUG_XFERS); siisata_deactivate_prb(schp, slot); @@ -1016,7 +1020,7 @@ siisata_bio_start(struct ata_channel *chp, struct ata_xfer *xfer) SIISATA_DEBUG_PRINT( ("%s: %s port %d, slot %d\n", - SIISATANAME(sc), __func__, chp->ch_channel, slot), + SIISATANAME((struct siisata_softc *)chp->ch_atac), __func__, chp->ch_channel, slot), DEBUG_FUNCS); chp->ch_status = 0; @@ -1026,6 +1030,8 @@ siisata_bio_start(struct ata_channel *chp, struct ata_xfer *xfer) memset(prb, 0, sizeof(struct siisata_prb)); satafis_rhd_construct_bio(xfer, prb->prb_fis); + KASSERT(xfer->c_drive <= PMP_PORT_CTL); + prb->prb_fis[rhd_c] |= xfer->c_drive; memset(prb->prb_atapi, 0, sizeof(prb->prb_atapi)); @@ -1065,7 +1071,7 @@ siisata_bio_start(struct ata_channel *chp, struct ata_xfer *xfer) siisata_enable_port_interrupt(chp); out: SIISATA_DEBUG_PRINT( - ("%s: %s: done\n", SIISATANAME(sc), __func__), DEBUG_FUNCS); + ("%s: %s: done\n", SIISATANAME((struct siisata_softc *)chp->ch_atac), __func__), DEBUG_FUNCS); return; } @@ -1124,9 +1130,9 @@ siisata_bio_complete(struct ata_channel *chp, struct ata_xfer *xfer, int slot) BUS_DMASYNC_POSTWRITE); bus_dmamap_unload(sc->sc_dmat, schp->sch_datad[slot]); - if (chp->ch_drive[xfer->c_drive].drive_flags & DRIVE_WAITDRAIN) { + if (chp->ch_drive[xfer->c_drive].drive_flags & ATA_DRIVE_WAITDRAIN) { siisata_bio_kill_xfer(chp, xfer, KILL_GONE); - chp->ch_drive[xfer->c_drive].drive_flags &= ~DRIVE_WAITDRAIN; + chp->ch_drive[xfer->c_drive].drive_flags &= ~ATA_DRIVE_WAITDRAIN; wakeup(&chp->ch_queue->active_xfer); return 0; } @@ -1167,6 +1173,7 @@ siisata_timeout(void *v) int slot = SIISATA_NON_NCQ_SLOT; int s = splbio(); SIISATA_DEBUG_PRINT(("%s: %p\n", __func__, xfer), DEBUG_INTR); + siisata_device_reset(chp); if ((chp->ch_flags & ATACH_IRQ_WAIT) != 0) { xfer->c_flags |= C_TIMEOU; xfer->c_intr(chp, xfer, slot); @@ -1270,6 +1277,8 @@ siisata_reinit_port(struct ata_channel *chp) PRWRITE(sc, PRX(chp->ch_channel, PRO_PCS), PR_PC_PORT_INITIALIZE); while (!(PRREAD(sc, PRX(chp->ch_channel, PRO_PS)) & PR_PS_PORT_READY)) DELAY(10); + if (chp->ch_ndrives > 1) + PRWRITE(sc, PRX(chp->ch_channel, PRO_PCS), PR_PC_PMP_ENABLE); } static void @@ -1386,7 +1395,7 @@ siisata_atapi_probe_device(struct atapibus_softc *sc, int target) return; /* if no ATAPI device detected at attach time, skip */ - if ((drvp->drive_flags & DRIVE_ATAPI) == 0) { + if (drvp->drive_type == ATA_DRIVET_ATAPI) { SIISATA_DEBUG_PRINT(("%s: drive %d " "not present\n", __func__, target), DEBUG_PROBE); return; @@ -1424,12 +1433,6 @@ siisata_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) { - s = splbio(); - drvp->drive_flags |= DRIVE_ATAPIST; - splx(s); - } - sa.sa_periph = periph; sa.sa_inqbuf.type = ATAPI_CFG_TYPE(id->atap_config); sa.sa_inqbuf.removable = id->atap_config & ATAPI_CFG_REMOV ? @@ -1467,7 +1470,7 @@ siisata_atapi_probe_device(struct atapibus_softc *sc, int target) ata_probe_caps(drvp); else { s = splbio(); - drvp->drive_flags &= ~DRIVE_ATAPI; + drvp->drive_type &= ATA_DRIVET_NONE; splx(s); } } else { @@ -1476,7 +1479,7 @@ siisata_atapi_probe_device(struct atapibus_softc *sc, int target) __func__, SIISATANAME(siic), chp->ch_channel, target, chp->ch_error), DEBUG_PROBE); s = splbio(); - drvp->drive_flags &= ~DRIVE_ATAPI; + drvp->drive_type &= ATA_DRIVET_NONE; splx(s); } } @@ -1555,7 +1558,7 @@ siisata_atapi_start(struct ata_channel *chp, struct ata_xfer *xfer) int i; SIISATA_DEBUG_PRINT( ("%s: %s:%d:%d, scsi flags 0x%x\n", __func__, - SIISATANAME(sc), chp->ch_channel, + SIISATANAME((struct siisata_softc *)chp->ch_atac), chp->ch_channel, chp->ch_drive[xfer->c_drive].drive, sc_xfer->xs_control), DEBUG_XFERS); @@ -1573,6 +1576,8 @@ siisata_atapi_start(struct ata_channel *chp, struct ata_xfer *xfer) prbp->prb_control |= htole16(PRB_CF_PACKET_WRITE); satafis_rhd_construct_atapi(xfer, prbp->prb_fis); + KASSERT(xfer->c_drive <= PMP_PORT_CTL); + prbp->prb_fis[rhd_c] |= xfer->c_drive; /* copy over ATAPI command */ memcpy(prbp->prb_atapi, sc_xfer->cmd, sc_xfer->cmdlen); @@ -1611,14 +1616,13 @@ siisata_atapi_start(struct ata_channel *chp, struct ata_xfer *xfer) DELAY(1000); } if ((sc_xfer->xs_status & XS_STS_DONE) == 0) { - sc_xfer->error = XS_TIMEOUT; - siisata_atapi_complete(chp, xfer, slot); + siisata_timeout(chp); } /* reenable interrupts */ siisata_enable_port_interrupt(chp); out: SIISATA_DEBUG_PRINT( - ("%s: %s: done\n", SIISATANAME(sc), __func__), DEBUG_FUNCS); + ("%s: %s: done\n", SIISATANAME((struct siisata_softc *)chp->ch_atac), __func__), DEBUG_FUNCS); return; } @@ -1649,9 +1653,9 @@ siisata_atapi_complete(struct ata_channel *chp, struct ata_xfer *xfer, BUS_DMASYNC_POSTREAD : BUS_DMASYNC_POSTWRITE); bus_dmamap_unload(sc->sc_dmat, schp->sch_datad[slot]); - if (chp->ch_drive[xfer->c_drive].drive_flags & DRIVE_WAITDRAIN) { + if (chp->ch_drive[xfer->c_drive].drive_flags & ATA_DRIVE_WAITDRAIN) { siisata_atapi_kill_xfer(chp, xfer, KILL_GONE); - chp->ch_drive[xfer->c_drive].drive_flags &= ~DRIVE_WAITDRAIN; + chp->ch_drive[xfer->c_drive].drive_flags &= ~ATA_DRIVE_WAITDRAIN; wakeup(&chp->ch_queue->active_xfer); return 0; /* XXX verify */ } diff --git a/sys/dev/ic/wdc.c b/sys/dev/ic/wdc.c index 07b0d0f5fd7..7e4913c2f39 100644 --- a/sys/dev/ic/wdc.c +++ b/sys/dev/ic/wdc.c @@ -1,4 +1,4 @@ -/* $NetBSD: wdc.c,v 1.273 2012/07/29 18:20:13 christos Exp $ */ +/* $NetBSD: wdc.c,v 1.274 2012/07/31 15:50:34 bouyer Exp $ */ /* * Copyright (c) 1998, 2001, 2003 Manuel Bouyer. All rights reserved. @@ -58,7 +58,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: wdc.c,v 1.273 2012/07/29 18:20:13 christos Exp $"); +__KERNEL_RCSID(0, "$NetBSD: wdc.c,v 1.274 2012/07/31 15:50:34 bouyer Exp $"); #include "opt_ata.h" #include "opt_wdc.h" @@ -208,11 +208,7 @@ wdc_sataprobe(struct ata_channel *chp) uint8_t st = 0, sc, sn, cl, ch; int i, s; - /* XXX This should be done by other code. */ - for (i = 0; i < chp->ch_ndrive; i++) { - chp->ch_drive[i].chnl_softc = chp; - chp->ch_drive[i].drive = i; - } + KASSERT(chp->ch_ndrives == 0 || chp->ch_drive != NULL); /* reset the PHY and bring online */ switch (sata_reset_interface(chp, wdr->sata_iot, wdr->sata_control, @@ -244,15 +240,17 @@ wdc_sataprobe(struct ata_channel *chp) "cl=0x%x ch=0x%x\n", device_xname(chp->ch_atac->atac_dev), chp->ch_channel, sc, sn, cl, ch), DEBUG_PROBE); + if (atabus_alloc_drives(chp, 1) != 0) + return; /* * sc 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; + chp->ch_drive[0].drive_type = ATA_DRIVET_ATAPI; else - chp->ch_drive[0].drive_flags |= DRIVE_ATA; + chp->ch_drive[0].drive_type = ATA_DRIVET_ATA; splx(s); /* @@ -260,7 +258,7 @@ wdc_sataprobe(struct ata_channel *chp) * is up */ if (wdcreset(chp, RESET_SLEEP) != 0) - chp->ch_drive[0].drive_flags = 0; + chp->ch_drive[0].drive_type = ATA_DRIVET_NONE; break; default: @@ -294,8 +292,11 @@ wdc_drvprobe(struct ata_channel *chp) u_int8_t st0 = 0, st1 = 0; int i, j, error, s; + if (atabus_alloc_drives(chp, wdc->wdc_maxdrives) != 0) + return; if (wdcprobe1(chp, 0) == 0) { /* No drives, abort the attach here. */ + atabus_free_drives(chp); return; } @@ -306,7 +307,8 @@ wdc_drvprobe(struct ata_channel *chp) * select drive 1 first, so that master is selected on * exit from the loop */ - if (chp->ch_drive[1].drive_flags & (DRIVE_ATA|DRIVE_OLD)) { + if (chp->ch_ndrives > 1 && + chp->ch_drive[1].drive_type == ATA_DRIVET_ATA) { if (wdc->select) wdc->select(chp,1); bus_space_write_1(wdr->cmd_iot, wdr->cmd_iohs[wd_sdh], @@ -315,7 +317,7 @@ wdc_drvprobe(struct ata_channel *chp) st1 = bus_space_read_1(wdr->cmd_iot, wdr->cmd_iohs[wd_status], 0); } - if (chp->ch_drive[0].drive_flags & (DRIVE_ATA|DRIVE_OLD)) { + if (chp->ch_drive[0].drive_type == ATA_DRIVET_ATA) { if (wdc->select) wdc->select(chp,0); bus_space_write_1(wdr->cmd_iot, wdr->cmd_iohs[wd_sdh], @@ -326,12 +328,11 @@ wdc_drvprobe(struct ata_channel *chp) } - if (((chp->ch_drive[0].drive_flags & (DRIVE_ATA|DRIVE_OLD)) - == 0 || - (st0 & WDCS_DRDY)) && - ((chp->ch_drive[1].drive_flags & (DRIVE_ATA|DRIVE_OLD)) - == 0 || - (st1 & WDCS_DRDY))) + if ((chp->ch_drive[0].drive_type != ATA_DRIVET_ATA || + (st0 & WDCS_DRDY)) && + (chp->ch_ndrives < 2 || + chp->ch_drive[1].drive_type != ATA_DRIVET_ATA || + (st1 & WDCS_DRDY))) break; #ifdef WDC_NO_IDS /* cannot tsleep here (can't enable IPL_BIO interrups), @@ -342,10 +343,12 @@ wdc_drvprobe(struct ata_channel *chp) tsleep(¶ms, PRIBIO, "atadrdy", 1); #endif } - 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); + if ((st0 & WDCS_DRDY) == 0 && + chp->ch_drive[0].drive_type != ATA_DRIVET_ATAPI) + chp->ch_drive[0].drive_type = ATA_DRIVET_NONE; + if (chp->ch_ndrives > 1 && (st1 & WDCS_DRDY) == 0 && + chp->ch_drive[1].drive_type != ATA_DRIVET_ATAPI) + chp->ch_drive[1].drive_type = ATA_DRIVET_NONE; splx(s); ATADEBUG_PRINT(("%s:%d: wait DRDY st0 0x%x st1 0x%x\n", @@ -355,11 +358,7 @@ wdc_drvprobe(struct ata_channel *chp) /* Wait a bit, some devices are weird just after a reset. */ delay(5000); - for (i = 0; i < chp->ch_ndrive; i++) { - /* XXX This should be done by other code. */ - chp->ch_drive[i].chnl_softc = chp; - chp->ch_drive[i].drive = i; - + for (i = 0; i < chp->ch_ndrives; i++) { #if NATA_DMA /* * Init error counter so that an error withing the first xfers @@ -372,10 +371,10 @@ wdc_drvprobe(struct ata_channel *chp) if ((atac->atac_cap & (ATAC_CAP_DATA16 | ATAC_CAP_DATA32)) == ATAC_CAP_DATA32) { s = splbio(); - chp->ch_drive[i].drive_flags |= DRIVE_CAP32; + chp->ch_drive[i].drive_flags |= ATA_DRIVE_CAP32; splx(s); } - if ((chp->ch_drive[i].drive_flags & DRIVE) == 0) + if (chp->ch_drive[i].drive_type == ATA_DRIVET_NONE) continue; /* Shortcut in case we've been shutdown */ @@ -400,22 +399,17 @@ wdc_drvprobe(struct ata_channel *chp) error = ata_get_params(&chp->ch_drive[i], AT_WAIT | AT_POLL, ¶ms); } - if (error == CMD_OK) { - /* If IDENTIFY succeeded, this is not an OLD ctrl */ - s = splbio(); - for (j = 0; j < chp->ch_ndrive; j++) - chp->ch_drive[j].drive_flags &= ~DRIVE_OLD; - splx(s); - } else { - s = splbio(); - chp->ch_drive[i].drive_flags &= - ~(DRIVE_ATA | DRIVE_ATAPI); - splx(s); + if (error != CMD_OK) { ATADEBUG_PRINT(("%s:%d:%d: IDENTIFY failed (%d)\n", device_xname(atac->atac_dev), chp->ch_channel, i, error), DEBUG_PROBE); - if ((chp->ch_drive[i].drive_flags & DRIVE_OLD) == 0) + s = splbio(); + if (chp->ch_drive[i].drive_type != ATA_DRIVET_ATA || + (wdc->cap & WDC_CAPABILITY_PREATA) == 0) { + chp->ch_drive[i].drive_type = ATA_DRIVET_NONE; continue; + } + splx(s); /* * Pre-ATA drive ? * Test registers writability (Error register not @@ -439,7 +433,7 @@ wdc_drvprobe(struct ata_channel *chp) device_xname(atac->atac_dev), chp->ch_channel, i), DEBUG_PROBE); s = splbio(); - chp->ch_drive[i].drive_flags &= ~DRIVE_OLD; + chp->ch_drive[i].drive_type = ATA_DRIVET_NONE; splx(s); continue; } @@ -448,7 +442,7 @@ wdc_drvprobe(struct ata_channel *chp) device_xname(atac->atac_dev), chp->ch_channel, i), DEBUG_PROBE); s = splbio(); - chp->ch_drive[i].drive_flags &= ~DRIVE_OLD; + chp->ch_drive[i].drive_type = ATA_DRIVET_NONE; splx(s); continue; } @@ -460,13 +454,17 @@ wdc_drvprobe(struct ata_channel *chp) device_xname(atac->atac_dev), chp->ch_channel, i), DEBUG_PROBE); s = splbio(); - chp->ch_drive[i].drive_flags &= ~DRIVE_OLD; + chp->ch_drive[i].drive_type = ATA_DRIVET_NONE; splx(s); } else { s = splbio(); - for (j = 0; j < chp->ch_ndrive; j++) - chp->ch_drive[j].drive_flags &= - ~(DRIVE_ATA | DRIVE_ATAPI); + for (j = 0; j < chp->ch_ndrives; j++) { + if (chp->ch_drive[i].drive_type != + ATA_DRIVET_NONE) { + chp->ch_drive[j].drive_type = + ATA_DRIVET_OLD; + } + } splx(s); } } @@ -724,7 +722,7 @@ wdcprobe1(struct ata_channel *chp, int poll) * be something here assume it's ATA or OLD. Ghost will be killed * later in attach routine. */ - for (drive = 0; drive < chp->ch_ndrive; drive++) { + for (drive = 0; drive < wdc->wdc_maxdrives; drive++) { if ((ret_value & (0x01 << drive)) == 0) continue; if (wdc->select) @@ -750,12 +748,12 @@ wdcprobe1(struct ata_channel *chp, int poll) * sc & sn are supposed to be 0x1 for ATAPI but in some cases * we get wrong values here, so ignore it. */ - if (cl == 0x14 && ch == 0xeb) { - chp->ch_drive[drive].drive_flags |= DRIVE_ATAPI; - } else { - chp->ch_drive[drive].drive_flags |= DRIVE_ATA; - if ((wdc->cap & WDC_CAPABILITY_PREATA) != 0) - chp->ch_drive[drive].drive_flags |= DRIVE_OLD; + if (chp->ch_drive != NULL) { + if (cl == 0x14 && ch == 0xeb) { + chp->ch_drive[drive].drive_type = ATA_DRIVET_ATAPI; + } else { + chp->ch_drive[drive].drive_type = ATA_DRIVET_ATA; + } } } /* @@ -778,7 +776,7 @@ wdcattach(struct ata_channel *chp) struct atac_softc *atac = chp->ch_atac; struct wdc_softc *wdc = CHAN_TO_WDC(chp); - KASSERT(chp->ch_ndrive > 0 && chp->ch_ndrive < 3); + KASSERT(wdc->wdc_maxdrives > 0 && wdc->wdc_maxdrives <= WDC_MAXDRIVES); /* default data transfer methods */ if (wdc->datain_pio == NULL) @@ -916,10 +914,12 @@ wdcintr(void *arg) /* Put all disk in RESET state */ void -wdc_reset_drive(struct ata_drive_datas *drvp, int flags) +wdc_reset_drive(struct ata_drive_datas *drvp, int flags, uint32_t *sigp) { struct ata_channel *chp = drvp->chnl_softc; + KASSERT(sigp == NULL); + ATADEBUG_PRINT(("wdc_reset_drive %s:%d for drive %d\n", device_xname(chp->ch_atac->atac_dev), chp->ch_channel, drvp->drive), DEBUG_FUNCS); @@ -1037,8 +1037,10 @@ wdcreset(struct ata_channel *chp, int poll) #endif wdc->reset(chp, poll); - drv_mask1 = (chp->ch_drive[0].drive_flags & DRIVE) ? 0x01:0x00; - drv_mask1 |= (chp->ch_drive[1].drive_flags & DRIVE) ? 0x02:0x00; + drv_mask1 = (chp->ch_drive[0].drive_type != ATA_DRIVET_NONE) ? 0x01:0x00; + if (chp->ch_ndrives > 1) + drv_mask1 |= + (chp->ch_drive[1].drive_type != ATA_DRIVET_NONE) ? 0x02:0x00; drv_mask2 = __wdcwait_reset(chp, drv_mask1, (poll == RESET_SLEEP) ? 0 : 1); if (drv_mask2 != drv_mask1) { @@ -1504,7 +1506,7 @@ __wdccommand_intr(struct ata_channel *chp, struct ata_xfer *xfer, int irq) * Historically it's what we have always done so keeping it * here ensure binary backward compatibility. */ - drive_flags = DRIVE_NOSTREAM | + drive_flags = ATA_DRIVE_NOSTREAM | chp->ch_drive[xfer->c_drive].drive_flags; } else { /* @@ -1668,9 +1670,9 @@ __wdccommand_done(struct ata_channel *chp, struct ata_xfer *xfer) WDCTL_4BIT); delay(10); /* some drives need a little delay here */ } - if (chp->ch_drive[xfer->c_drive].drive_flags & DRIVE_WAITDRAIN) { + if (chp->ch_drive[xfer->c_drive].drive_flags & ATA_DRIVE_WAITDRAIN) { __wdccommand_kill_xfer(chp, xfer, KILL_GONE); - chp->ch_drive[xfer->c_drive].drive_flags &= ~DRIVE_WAITDRAIN; + chp->ch_drive[xfer->c_drive].drive_flags &= ~ATA_DRIVE_WAITDRAIN; wakeup(&chp->ch_queue->active_xfer); } else __wdccommand_done_end(chp, xfer); @@ -1874,12 +1876,12 @@ wdc_datain_pio(struct ata_channel *chp, int flags, void *bf, size_t len) #ifndef __NO_STRICT_ALIGNMENT if ((uintptr_t)bf & 1) goto unaligned; - if ((flags & DRIVE_CAP32) && ((uintptr_t)bf & 3)) + if ((flags & ATA_DRIVE_CAP32) && ((uintptr_t)bf & 3)) goto unaligned; #endif - if (flags & DRIVE_NOSTREAM) { - if ((flags & DRIVE_CAP32) && len > 3) { + if (flags & ATA_DRIVE_NOSTREAM) { + if ((flags & ATA_DRIVE_CAP32) && len > 3) { bus_space_read_multi_4(wdr->data32iot, wdr->data32ioh, 0, bf, len >> 2); bf = (char *)bf + (len & ~3); @@ -1892,7 +1894,7 @@ wdc_datain_pio(struct ata_channel *chp, int flags, void *bf, size_t len) len &= 1; } } else { - if ((flags & DRIVE_CAP32) && len > 3) { + if ((flags & ATA_DRIVE_CAP32) && len > 3) { bus_space_read_multi_stream_4(wdr->data32iot, wdr->data32ioh, 0, bf, len >> 2); bf = (char *)bf + (len & ~3); @@ -1912,8 +1914,8 @@ wdc_datain_pio(struct ata_channel *chp, int flags, void *bf, size_t len) #ifndef __NO_STRICT_ALIGNMENT unaligned: - if (flags & DRIVE_NOSTREAM) { - if (flags & DRIVE_CAP32) { + if (flags & ATA_DRIVE_NOSTREAM) { + if (flags & ATA_DRIVE_CAP32) { while (len > 3) { uint32_t val; @@ -1934,7 +1936,7 @@ unaligned: len -= 2; } } else { - if (flags & DRIVE_CAP32) { + if (flags & ATA_DRIVE_CAP32) { while (len > 3) { uint32_t val; @@ -1966,12 +1968,12 @@ wdc_dataout_pio(struct ata_channel *chp, int flags, void *bf, size_t len) #ifndef __NO_STRICT_ALIGNMENT if ((uintptr_t)bf & 1) goto unaligned; - if ((flags & DRIVE_CAP32) && ((uintptr_t)bf & 3)) + if ((flags & ATA_DRIVE_CAP32) && ((uintptr_t)bf & 3)) goto unaligned; #endif - if (flags & DRIVE_NOSTREAM) { - if (flags & DRIVE_CAP32) { + if (flags & ATA_DRIVE_NOSTREAM) { + if (flags & ATA_DRIVE_CAP32) { bus_space_write_multi_4(wdr->data32iot, wdr->data32ioh, 0, bf, len >> 2); bf = (char *)bf + (len & ~3); @@ -1982,7 +1984,7 @@ wdc_dataout_pio(struct ata_channel *chp, int flags, void *bf, size_t len) wdr->cmd_iohs[wd_data], 0, bf, len >> 1); } } else { - if (flags & DRIVE_CAP32) { + if (flags & ATA_DRIVE_CAP32) { bus_space_write_multi_stream_4(wdr->data32iot, wdr->data32ioh, 0, bf, len >> 2); bf = (char *)bf + (len & ~3); @@ -1997,8 +1999,8 @@ wdc_dataout_pio(struct ata_channel *chp, int flags, void *bf, size_t len) #ifndef __NO_STRICT_ALIGNMENT unaligned: - if (flags & DRIVE_NOSTREAM) { - if (flags & DRIVE_CAP32) { + if (flags & ATA_DRIVE_NOSTREAM) { + if (flags & ATA_DRIVE_CAP32) { while (len > 3) { uint32_t val; @@ -2019,7 +2021,7 @@ unaligned: len -= 2; } } else { - if (flags & DRIVE_CAP32) { + if (flags & ATA_DRIVE_CAP32) { while (len > 3) { uint32_t val; diff --git a/sys/dev/ic/wdc_upc.c b/sys/dev/ic/wdc_upc.c index 92daca8231c..5dd00ca97fa 100644 --- a/sys/dev/ic/wdc_upc.c +++ b/sys/dev/ic/wdc_upc.c @@ -1,4 +1,4 @@ -/* $NetBSD: wdc_upc.c,v 1.28 2012/07/26 20:49:49 jakllsch Exp $ */ +/* $NetBSD: wdc_upc.c,v 1.29 2012/07/31 15:50:35 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 -__KERNEL_RCSID(0, "$NetBSD: wdc_upc.c,v 1.28 2012/07/26 20:49:49 jakllsch Exp $"); +__KERNEL_RCSID(0, "$NetBSD: wdc_upc.c,v 1.29 2012/07/31 15:50:35 bouyer Exp $"); #include #include @@ -89,7 +89,7 @@ wdc_upc_attach(device_t parent, device_t self, void *aux) sc->sc_channel.ch_channel = 0; sc->sc_channel.ch_atac = &sc->sc_wdc.sc_atac; sc->sc_channel.ch_queue = &sc->sc_chqueue; - sc->sc_channel.ch_ndrive = 2; + sc->sc_wdc.wdc_maxdrives = 2; for (i = 0; i < WDC_NREG; i++) { if (bus_space_subregion(ua->ua_iot, ua->ua_ioh, i, i == 0 ? 4 : 1, &wdr->cmd_iohs[i]) != 0) { diff --git a/sys/dev/ic/wdcvar.h b/sys/dev/ic/wdcvar.h index 14e78c6cb46..f65409ac8f4 100644 --- a/sys/dev/ic/wdcvar.h +++ b/sys/dev/ic/wdcvar.h @@ -1,4 +1,4 @@ -/* $NetBSD: wdcvar.h,v 1.94 2012/07/26 20:49:49 jakllsch Exp $ */ +/* $NetBSD: wdcvar.h,v 1.95 2012/07/31 15:50:35 bouyer Exp $ */ /*- * Copyright (c) 1998, 2003, 2004 The NetBSD Foundation, Inc. @@ -43,6 +43,8 @@ #define WDC_NREG 8 /* number of command registers */ #define WDC_NSHADOWREG 2 /* number of command "shadow" registers */ +#define WDC_MAXDRIVES 2 /* absolute max number of drives per channel */ + struct wdc_regs { /* Our registers */ bus_space_tag_t cmd_iot; @@ -74,7 +76,9 @@ struct wdc_softc { struct wdc_regs *regs; /* register array (per-channel) */ - int cap; /* controller capabilities */ + int wdc_maxdrives; /* max number of drives per channel */ + + int cap; /* controller capabilities */ #define WDC_CAPABILITY_NO_EXTRA_RESETS 0x0100 /* only reset once */ #define WDC_CAPABILITY_PREATA 0x0200 /* ctrl can be a pre-ata one */ #define WDC_CAPABILITY_WIDEREGS 0x0400 /* Ctrl has wide (16bit) registers */ @@ -164,7 +168,7 @@ void wdccommandext(struct ata_channel *, u_int8_t, u_int8_t, u_int64_t, u_int16_t, u_int16_t); void wdccommandshort(struct ata_channel *, int, int); void wdctimeout(void *arg); -void wdc_reset_drive(struct ata_drive_datas *, int); +void wdc_reset_drive(struct ata_drive_datas *, int, uint32_t *); void wdc_reset_channel(struct ata_channel *, int); void wdc_do_reset(struct ata_channel *, int); diff --git a/sys/dev/isa/wdc_isa.c b/sys/dev/isa/wdc_isa.c index ce5df302f06..14b2698c39f 100644 --- a/sys/dev/isa/wdc_isa.c +++ b/sys/dev/isa/wdc_isa.c @@ -1,4 +1,4 @@ -/* $NetBSD: wdc_isa.c,v 1.58 2012/07/26 20:49:49 jakllsch Exp $ */ +/* $NetBSD: wdc_isa.c,v 1.59 2012/07/31 15:50:35 bouyer Exp $ */ /*- * Copyright (c) 1998, 2003 The NetBSD Foundation, Inc. @@ -30,7 +30,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: wdc_isa.c,v 1.58 2012/07/26 20:49:49 jakllsch Exp $"); +__KERNEL_RCSID(0, "$NetBSD: wdc_isa.c,v 1.59 2012/07/31 15:50:35 bouyer Exp $"); #include #include @@ -224,10 +224,10 @@ wdc_isa_attach(device_t parent, device_t self, void *aux) sc->wdc_chanlist[0] = &sc->ata_channel; sc->sc_wdcdev.sc_atac.atac_channels = sc->wdc_chanlist; sc->sc_wdcdev.sc_atac.atac_nchannels = 1; + sc->sc_wdcdev.wdc_maxdrives = 2; sc->ata_channel.ch_channel = 0; sc->ata_channel.ch_atac = &sc->sc_wdcdev.sc_atac; sc->ata_channel.ch_queue = &sc->wdc_chqueue; - sc->ata_channel.ch_ndrive = 2; wdc_init_shadow_regs(&sc->ata_channel); aprint_normal("\n"); diff --git a/sys/dev/isapnp/wdc_isapnp.c b/sys/dev/isapnp/wdc_isapnp.c index b8998ca8060..cfcc394220b 100644 --- a/sys/dev/isapnp/wdc_isapnp.c +++ b/sys/dev/isapnp/wdc_isapnp.c @@ -1,4 +1,4 @@ -/* $NetBSD: wdc_isapnp.c,v 1.41 2012/07/26 20:49:49 jakllsch Exp $ */ +/* $NetBSD: wdc_isapnp.c,v 1.42 2012/07/31 15:50:35 bouyer Exp $ */ /*- * Copyright (c) 1998, 2003 The NetBSD Foundation, Inc. @@ -30,7 +30,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: wdc_isapnp.c,v 1.41 2012/07/26 20:49:49 jakllsch Exp $"); +__KERNEL_RCSID(0, "$NetBSD: wdc_isapnp.c,v 1.42 2012/07/31 15:50:35 bouyer Exp $"); #include #include @@ -156,10 +156,10 @@ wdc_isapnp_attach(device_t parent, device_t self, void *aux) sc->wdc_chanlist[0] = &sc->ata_channel; sc->sc_wdcdev.sc_atac.atac_channels = sc->wdc_chanlist; sc->sc_wdcdev.sc_atac.atac_nchannels = 1; + sc->sc_wdcdev.wdc_maxdrives = 2; sc->ata_channel.ch_channel = 0; sc->ata_channel.ch_atac = &sc->sc_wdcdev.sc_atac; sc->ata_channel.ch_queue = &sc->wdc_chqueue; - sc->ata_channel.ch_ndrive = 2; wdc_init_shadow_regs(&sc->ata_channel); diff --git a/sys/dev/mca/ed_mca.c b/sys/dev/mca/ed_mca.c index ecbfdb4dd96..25f017c5f69 100644 --- a/sys/dev/mca/ed_mca.c +++ b/sys/dev/mca/ed_mca.c @@ -1,4 +1,4 @@ -/* $NetBSD: ed_mca.c,v 1.51 2012/07/24 14:04:30 jakllsch Exp $ */ +/* $NetBSD: ed_mca.c,v 1.52 2012/07/31 15:50:35 bouyer Exp $ */ /* * Copyright (c) 2001 The NetBSD Foundation, Inc. @@ -34,7 +34,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: ed_mca.c,v 1.51 2012/07/24 14:04:30 jakllsch Exp $"); +__KERNEL_RCSID(0, "$NetBSD: ed_mca.c,v 1.52 2012/07/31 15:50:35 bouyer Exp $"); #include #include @@ -440,7 +440,7 @@ edgetdisklabel(dev_t dev, struct ed_softc *ed) */ #if 0 if (wd->drvp->state > RECAL) - wd->drvp->drive_flags |= DRIVE_RESET; + wd->drvp->drive_flags |= ATA_DRIVE_RESET; #endif errstring = readdisklabel(EDLABELDEV(dev), edmcastrategy, lp, ed->sc_dk.dk_cpulabel); @@ -492,7 +492,7 @@ edmcaioctl(dev_t dev, u_long xfer, void *addr, int flag, struct lwp *l) if (error == 0) { #if 0 if (wd->drvp->state > RECAL) - wd->drvp->drive_flags |= DRIVE_RESET; + wd->drvp->drive_flags |= ATA_DRIVE_RESET; #endif if (xfer == DIOCWDINFO) error = writedisklabel(EDLABELDEV(dev), diff --git a/sys/dev/ofisa/wdc_ofisa.c b/sys/dev/ofisa/wdc_ofisa.c index 11908495fc9..09b89c1ba27 100644 --- a/sys/dev/ofisa/wdc_ofisa.c +++ b/sys/dev/ofisa/wdc_ofisa.c @@ -1,4 +1,4 @@ -/* $NetBSD: wdc_ofisa.c,v 1.32 2012/07/26 20:49:49 jakllsch Exp $ */ +/* $NetBSD: wdc_ofisa.c,v 1.33 2012/07/31 15:50:35 bouyer Exp $ */ /* * Copyright 1997, 1998 @@ -38,7 +38,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: wdc_ofisa.c,v 1.32 2012/07/26 20:49:49 jakllsch Exp $"); +__KERNEL_RCSID(0, "$NetBSD: wdc_ofisa.c,v 1.33 2012/07/31 15:50:35 bouyer Exp $"); #include #include @@ -158,10 +158,10 @@ wdc_ofisa_attach(device_t parent, device_t self, void *aux) sc->sc_chanlist[0] = &sc->sc_channel; sc->sc_wdcdev.sc_atac.atac_channels = sc->sc_chanlist; sc->sc_wdcdev.sc_atac.atac_nchannels = 1; + sc->sc_wdcdev.wdc_maxdrives = 2; sc->sc_channel.ch_channel = 0; sc->sc_channel.ch_atac = &sc->sc_wdcdev.sc_atac; sc->sc_channel.ch_queue = &sc->sc_chqueue; - sc->sc_channel.ch_ndrive = 2; wdc_init_shadow_regs(&sc->sc_channel); diff --git a/sys/dev/pci/acardide.c b/sys/dev/pci/acardide.c index 94abe88284c..65f75db2e92 100644 --- a/sys/dev/pci/acardide.c +++ b/sys/dev/pci/acardide.c @@ -1,4 +1,4 @@ -/* $NetBSD: acardide.c,v 1.29 2012/07/26 20:49:49 jakllsch Exp $ */ +/* $NetBSD: acardide.c,v 1.30 2012/07/31 15:50:35 bouyer Exp $ */ /*- * Copyright (c) 2001 Izumi Tsutsui. All rights reserved. @@ -25,7 +25,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: acardide.c,v 1.29 2012/07/26 20:49:49 jakllsch Exp $"); +__KERNEL_RCSID(0, "$NetBSD: acardide.c,v 1.30 2012/07/31 15:50:35 bouyer Exp $"); #include #include @@ -159,6 +159,7 @@ acard_chip_map(struct pciide_softc *sc, const struct pci_attach_args *pa) sc->sc_wdcdev.sc_atac.atac_set_modes = acard_setup_channel; sc->sc_wdcdev.sc_atac.atac_channels = sc->wdc_chanarray; sc->sc_wdcdev.sc_atac.atac_nchannels = 2; + sc->sc_wdcdev.wdc_maxdrives = 2; wdc_allocate_regs(&sc->sc_wdcdev); @@ -202,8 +203,8 @@ acard_setup_channel(struct ata_channel *chp) udma_mode &= ~ATP860_UDMA_MASK(channel); /* check 80 pins cable */ - if ((chp->ch_drive[0].drive_flags & DRIVE_UDMA) || - (chp->ch_drive[1].drive_flags & DRIVE_UDMA)) { + if ((chp->ch_drive[0].drive_flags & ATA_DRIVE_UDMA) || + (chp->ch_drive[1].drive_flags & ATA_DRIVE_UDMA)) { if (pci_conf_read(sc->sc_pc, sc->sc_tag, ATP8x0_CTRL) & ATP860_CTRL_80P(chp->ch_channel)) { if (chp->ch_drive[0].UDMA_mode > 2) @@ -220,11 +221,11 @@ acard_setup_channel(struct ata_channel *chp) for (drive = 0; drive < 2; drive++) { drvp = &chp->ch_drive[drive]; /* If no drive, skip */ - if ((drvp->drive_flags & DRIVE) == 0) + if (drvp->drive_type == ATA_DRIVET_NONE) continue; /* add timing values, setup DMA if needed */ if ((atac->atac_cap & ATAC_CAP_UDMA) && - (drvp->drive_flags & DRIVE_UDMA)) { + (drvp->drive_flags & ATA_DRIVE_UDMA)) { /* use Ultra/DMA */ if (ACARD_IS_850(sc)) { idetime |= ATP850_SETTIME(drive, @@ -241,10 +242,10 @@ acard_setup_channel(struct ata_channel *chp) } idedma_ctl |= IDEDMA_CTL_DRV_DMA(drive); } else if ((atac->atac_cap & ATAC_CAP_DMA) && - (drvp->drive_flags & DRIVE_DMA)) { + (drvp->drive_flags & ATA_DRIVE_DMA)) { /* use Multiword DMA */ s = splbio(); - drvp->drive_flags &= ~DRIVE_UDMA; + drvp->drive_flags &= ~ATA_DRIVE_UDMA; splx(s); if (ACARD_IS_850(sc)) { idetime |= ATP850_SETTIME(drive, @@ -259,7 +260,7 @@ acard_setup_channel(struct ata_channel *chp) } else { /* PIO only */ s = splbio(); - drvp->drive_flags &= ~(DRIVE_UDMA | DRIVE_DMA); + drvp->drive_flags &= ~(ATA_DRIVE_UDMA | ATA_DRIVE_DMA); splx(s); if (ACARD_IS_850(sc)) { idetime |= ATP850_SETTIME(drive, diff --git a/sys/dev/pci/aceride.c b/sys/dev/pci/aceride.c index bc0f1f66a99..425a7392239 100644 --- a/sys/dev/pci/aceride.c +++ b/sys/dev/pci/aceride.c @@ -1,4 +1,4 @@ -/* $NetBSD: aceride.c,v 1.34 2012/07/26 20:49:49 jakllsch Exp $ */ +/* $NetBSD: aceride.c,v 1.35 2012/07/31 15:50:35 bouyer Exp $ */ /* * Copyright (c) 1999, 2000, 2001 Manuel Bouyer. @@ -25,7 +25,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: aceride.c,v 1.34 2012/07/26 20:49:49 jakllsch Exp $"); +__KERNEL_RCSID(0, "$NetBSD: aceride.c,v 1.35 2012/07/31 15:50:35 bouyer Exp $"); #include #include @@ -152,6 +152,7 @@ acer_chip_map(struct pciide_softc *sc, const struct pci_attach_args *pa) sc->sc_wdcdev.sc_atac.atac_set_modes = acer_setup_channel; sc->sc_wdcdev.sc_atac.atac_channels = sc->wdc_chanarray; sc->sc_wdcdev.sc_atac.atac_nchannels = PCIIDE_NUM_CHANNELS; + sc->sc_wdcdev.wdc_maxdrives = 2; pciide_pci_write(sc->sc_pc, sc->sc_tag, ACER_CDRC, (pciide_pci_read(sc->sc_pc, sc->sc_tag, ACER_CDRC) | @@ -268,7 +269,7 @@ acer_setup_channel(struct ata_channel *chp) pciide_channel_dma_setup(cp); if ((chp->ch_drive[0].drive_flags | chp->ch_drive[1].drive_flags) & - DRIVE_UDMA) { /* check 80 pins cable */ + ATA_DRIVE_UDMA) { /* check 80 pins cable */ if (pciide_pci_read(sc->sc_pc, sc->sc_tag, ACER_0x4A) & ACER_0x4A_80PIN(chp->ch_channel)) { if (chp->ch_drive[0].UDMA_mode > 2) @@ -281,7 +282,7 @@ acer_setup_channel(struct ata_channel *chp) for (drive = 0; drive < 2; drive++) { drvp = &chp->ch_drive[drive]; /* If no drive, skip */ - if ((drvp->drive_flags & DRIVE) == 0) + if (drvp->drive_type == ATA_DRIVET_NONE) continue; ATADEBUG_PRINT(("acer_setup_channel: old timings reg for " "channel %d drive %d 0x%x\n", chp->ch_channel, drive, @@ -293,18 +294,18 @@ acer_setup_channel(struct ata_channel *chp) ACER_UDMA_TIM(chp->ch_channel, drive, 0x7)); /* add timing values, setup DMA if needed */ - if ((drvp->drive_flags & DRIVE_DMA) == 0 && - (drvp->drive_flags & DRIVE_UDMA) == 0) { + if ((drvp->drive_flags & ATA_DRIVE_DMA) == 0 && + (drvp->drive_flags & ATA_DRIVE_UDMA) == 0) { acer_fifo_udma |= ACER_FTH_OPL(chp->ch_channel, drive, 0x1); goto pio; } acer_fifo_udma |= ACER_FTH_OPL(chp->ch_channel, drive, 0x2); - if (drvp->drive_flags & DRIVE_UDMA) { + if (drvp->drive_flags & ATA_DRIVE_UDMA) { /* use Ultra/DMA */ s = splbio(); - drvp->drive_flags &= ~DRIVE_DMA; + drvp->drive_flags &= ~ATA_DRIVE_DMA; splx(s); acer_fifo_udma |= ACER_UDMA_EN(chp->ch_channel, drive); acer_fifo_udma |= diff --git a/sys/dev/pci/artsata.c b/sys/dev/pci/artsata.c index d2399beac96..2fcbd6ab1a5 100644 --- a/sys/dev/pci/artsata.c +++ b/sys/dev/pci/artsata.c @@ -1,4 +1,4 @@ -/* $NetBSD: artsata.c,v 1.23 2012/07/26 20:49:49 jakllsch Exp $ */ +/* $NetBSD: artsata.c,v 1.24 2012/07/31 15:50:36 bouyer Exp $ */ /*- * Copyright (c) 2003 The NetBSD Foundation, Inc. @@ -30,7 +30,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: artsata.c,v 1.23 2012/07/26 20:49:49 jakllsch Exp $"); +__KERNEL_RCSID(0, "$NetBSD: artsata.c,v 1.24 2012/07/31 15:50:36 bouyer Exp $"); #include "opt_pciide.h" @@ -233,7 +233,6 @@ artisea_chansetup(struct pciide_softc *sc, int channel, cp->ata_channel.ch_atac = &sc->sc_wdcdev.sc_atac; cp->ata_channel.ch_queue = malloc(sizeof(struct ata_queue), M_DEVBUF, M_NOWAIT); - cp->ata_channel.ch_ndrive = 2; if (cp->ata_channel.ch_queue == NULL) { aprint_error("%s %s channel: " "can't allocate memory for command queue", @@ -349,6 +348,7 @@ artisea_chip_map_dpa(struct pciide_softc *sc, const struct pci_attach_args *pa) sc->sc_wdcdev.sc_atac.atac_channels = sc->wdc_chanarray; sc->sc_wdcdev.sc_atac.atac_nchannels = ARTISEA_NUM_CHAN; sc->sc_wdcdev.sc_atac.atac_probe = wdc_sataprobe; + sc->sc_wdcdev.wdc_maxdrives = 1; wdc_allocate_regs(&sc->sc_wdcdev); diff --git a/sys/dev/pci/cmdide.c b/sys/dev/pci/cmdide.c index 54ba573b1bd..d63feaa18e2 100644 --- a/sys/dev/pci/cmdide.c +++ b/sys/dev/pci/cmdide.c @@ -1,4 +1,4 @@ -/* $NetBSD: cmdide.c,v 1.36 2012/07/26 20:49:49 jakllsch Exp $ */ +/* $NetBSD: cmdide.c,v 1.37 2012/07/31 15:50:36 bouyer Exp $ */ /* * Copyright (c) 1999, 2000, 2001 Manuel Bouyer. @@ -25,7 +25,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: cmdide.c,v 1.36 2012/07/26 20:49:49 jakllsch Exp $"); +__KERNEL_RCSID(0, "$NetBSD: cmdide.c,v 1.37 2012/07/31 15:50:36 bouyer Exp $"); #include #include @@ -148,6 +148,7 @@ cmd_channel_map(const struct pci_attach_args *pa, struct pciide_softc *sc, cp->name = PCIIDE_CHANNEL_NAME(channel); cp->ata_channel.ch_channel = channel; cp->ata_channel.ch_atac = &sc->sc_wdcdev.sc_atac; + sc->sc_wdcdev.wdc_maxdrives = 2; /* * Older CMD64X doesn't have independent channels @@ -174,7 +175,6 @@ cmd_channel_map(const struct pci_attach_args *pa, struct pciide_softc *sc, device_xname(sc->sc_wdcdev.sc_atac.atac_dev), cp->name); return; } - cp->ata_channel.ch_ndrive = 2; aprint_normal_dev(sc->sc_wdcdev.sc_atac.atac_dev, "%s channel %s to %s mode\n", cp->name, @@ -258,6 +258,7 @@ cmd_chip_map(struct pciide_softc *sc, const struct pci_attach_args *pa) sc->sc_wdcdev.sc_atac.atac_channels = sc->wdc_chanarray; sc->sc_wdcdev.sc_atac.atac_nchannels = PCIIDE_NUM_CHANNELS; sc->sc_wdcdev.sc_atac.atac_cap = ATAC_CAP_DATA16; + sc->sc_wdcdev.wdc_maxdrives = 2; wdc_allocate_regs(&sc->sc_wdcdev); @@ -378,15 +379,15 @@ cmd0643_9_setup_channel(struct ata_channel *chp) for (drive = 0; drive < 2; drive++) { drvp = &chp->ch_drive[drive]; /* If no drive, skip */ - if ((drvp->drive_flags & DRIVE) == 0) + if (drvp->drive_type == ATA_DRIVET_NONE) continue; /* add timing values, setup DMA if needed */ tim = cmd0643_9_data_tim_pio[drvp->PIO_mode]; - if (drvp->drive_flags & (DRIVE_DMA | DRIVE_UDMA)) { - if (drvp->drive_flags & DRIVE_UDMA) { + if (drvp->drive_flags & (ATA_DRIVE_DMA | ATA_DRIVE_UDMA)) { + if (drvp->drive_flags & ATA_DRIVE_UDMA) { /* UltraDMA on a 646U2, 0648 or 0649 */ s = splbio(); - drvp->drive_flags &= ~DRIVE_DMA; + drvp->drive_flags &= ~ATA_DRIVE_DMA; splx(s); udma_reg = pciide_pci_read(sc->sc_pc, sc->sc_tag, CMD_UDMATIM(chp->ch_channel)); @@ -527,7 +528,6 @@ cmd680_channel_map(const struct pci_attach_args *pa, struct pciide_softc *sc, device_xname(sc->sc_wdcdev.sc_atac.atac_dev), cp->name); return; } - cp->ata_channel.ch_ndrive = 2; /* XXX */ reg = 0xa2 + channel * 16; @@ -572,12 +572,12 @@ cmd680_setup_channel(struct ata_channel *chp) for (drive = 0; drive < 2; drive++) { drvp = &chp->ch_drive[drive]; /* If no drive, skip */ - if ((drvp->drive_flags & DRIVE) == 0) + if (drvp->drive_type == ATA_DRIVET_NONE) continue; mode &= ~(0x03 << (drive * 4)); - if (drvp->drive_flags & DRIVE_UDMA) { + if (drvp->drive_flags & ATA_DRIVE_UDMA) { s = splbio(); - drvp->drive_flags &= ~DRIVE_DMA; + drvp->drive_flags &= ~ATA_DRIVE_DMA; splx(s); off = 0xa0 + chp->ch_channel * 16; if (drvp->UDMA_mode > 2 && @@ -599,7 +599,7 @@ cmd680_setup_channel(struct ata_channel *chp) val |= udma_tbl[drvp->UDMA_mode]; pciide_pci_write(pc, pa, off, val); idedma_ctl |= IDEDMA_CTL_DRV_DMA(drive); - } else if (drvp->drive_flags & DRIVE_DMA) { + } else if (drvp->drive_flags & ATA_DRIVE_DMA) { mode |= 0x02 << (drive * 4); off = 0xa8 + chp->ch_channel * 16 + drive * 2; val = dma_tbl[drvp->DMA_mode]; diff --git a/sys/dev/pci/cypide.c b/sys/dev/pci/cypide.c index 33c9dd83756..4c551ff33af 100644 --- a/sys/dev/pci/cypide.c +++ b/sys/dev/pci/cypide.c @@ -1,4 +1,4 @@ -/* $NetBSD: cypide.c,v 1.28 2012/07/26 20:49:49 jakllsch Exp $ */ +/* $NetBSD: cypide.c,v 1.29 2012/07/31 15:50:36 bouyer Exp $ */ /* * Copyright (c) 1999, 2000, 2001 Manuel Bouyer. @@ -26,7 +26,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: cypide.c,v 1.28 2012/07/26 20:49:49 jakllsch Exp $"); +__KERNEL_RCSID(0, "$NetBSD: cypide.c,v 1.29 2012/07/31 15:50:36 bouyer Exp $"); #include #include @@ -139,6 +139,7 @@ cy693_chip_map(struct pciide_softc *sc, const struct pci_attach_args *pa) sc->sc_wdcdev.sc_atac.atac_channels = sc->wdc_chanarray; sc->sc_wdcdev.sc_atac.atac_nchannels = 1; + sc->sc_wdcdev.wdc_maxdrives = 2; wdc_allocate_regs(&sc->sc_wdcdev); @@ -150,7 +151,6 @@ cy693_chip_map(struct pciide_softc *sc, const struct pci_attach_args *pa) cp->ata_channel.ch_atac = &sc->sc_wdcdev.sc_atac; cp->ata_channel.ch_queue = malloc(sizeof(struct ata_queue), M_DEVBUF, M_NOWAIT); - cp->ata_channel.ch_ndrive = 2; if (cp->ata_channel.ch_queue == NULL) { aprint_error("%s primary channel: " "can't allocate memory for command queue", @@ -195,10 +195,10 @@ cy693_setup_channel(struct ata_channel *chp) for (drive = 0; drive < 2; drive++) { drvp = &chp->ch_drive[drive]; /* If no drive, skip */ - if ((drvp->drive_flags & DRIVE) == 0) + if (drvp->drive_type == ATA_DRIVET_NONE) continue; /* add timing values, setup DMA if needed */ - if (drvp->drive_flags & DRIVE_DMA) { + if (drvp->drive_flags & ATA_DRIVE_DMA) { idedma_ctl |= IDEDMA_CTL_DRV_DMA(drive); /* use Multiword DMA */ if (dma_mode == -1 || dma_mode > drvp->DMA_mode) diff --git a/sys/dev/pci/geodeide.c b/sys/dev/pci/geodeide.c index bee3aed61f1..9714d2b8b1f 100644 --- a/sys/dev/pci/geodeide.c +++ b/sys/dev/pci/geodeide.c @@ -1,4 +1,4 @@ -/* $NetBSD: geodeide.c,v 1.23 2012/07/26 20:49:49 jakllsch Exp $ */ +/* $NetBSD: geodeide.c,v 1.24 2012/07/31 15:50:36 bouyer Exp $ */ /* * Copyright (c) 2004 Manuel Bouyer. @@ -32,7 +32,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: geodeide.c,v 1.23 2012/07/26 20:49:49 jakllsch Exp $"); +__KERNEL_RCSID(0, "$NetBSD: geodeide.c,v 1.24 2012/07/31 15:50:36 bouyer Exp $"); #include #include @@ -136,6 +136,7 @@ geodeide_chip_map(struct pciide_softc *sc, const struct pci_attach_args *pa) sc->sc_wdcdev.sc_atac.atac_channels = sc->wdc_chanarray; sc->sc_wdcdev.sc_atac.atac_nchannels = PCIIDE_NUM_CHANNELS; sc->sc_wdcdev.sc_atac.atac_cap |= ATAC_CAP_DATA16 | ATAC_CAP_DATA32; + sc->sc_wdcdev.wdc_maxdrives = 2; /* * Soekris Engineering Issue #0003: @@ -203,7 +204,7 @@ geodeide_setup_channel(struct ata_channel *chp) for (drive = 0; drive < 2; drive++) { drvp = &chp->ch_drive[drive]; /* If no drive, skip */ - if ((drvp->drive_flags & DRIVE) == 0) + if (drvp->drive_type == ATA_DRIVET_NONE) continue; switch (sc->sc_pp->ide_product) { @@ -222,18 +223,18 @@ geodeide_setup_channel(struct ata_channel *chp) } /* add timing values, setup DMA if needed */ - if (drvp->drive_flags & DRIVE_UDMA) { + if (drvp->drive_flags & ATA_DRIVE_UDMA) { /* Use Ultra-DMA */ dma_timing |= geode_udma[drvp->UDMA_mode]; idedma_ctl |= IDEDMA_CTL_DRV_DMA(drive); - } else if (drvp->drive_flags & DRIVE_DMA) { + } else if (drvp->drive_flags & ATA_DRIVE_DMA) { /* use Multiword DMA */ dma_timing |= geode_dma[drvp->DMA_mode]; idedma_ctl |= IDEDMA_CTL_DRV_DMA(drive); } else { /* PIO only */ s = splbio(); - drvp->drive_flags &= ~(DRIVE_UDMA | DRIVE_DMA); + drvp->drive_flags &= ~(ATA_DRIVE_UDMA | ATA_DRIVE_DMA); splx(s); } diff --git a/sys/dev/pci/hptide.c b/sys/dev/pci/hptide.c index 7ec77a2bebf..11d374f9348 100644 --- a/sys/dev/pci/hptide.c +++ b/sys/dev/pci/hptide.c @@ -1,4 +1,4 @@ -/* $NetBSD: hptide.c,v 1.32 2012/07/26 20:49:49 jakllsch Exp $ */ +/* $NetBSD: hptide.c,v 1.33 2012/07/31 15:50:36 bouyer Exp $ */ /* * Copyright (c) 1999, 2000, 2001 Manuel Bouyer. @@ -25,7 +25,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: hptide.c,v 1.32 2012/07/26 20:49:49 jakllsch Exp $"); +__KERNEL_RCSID(0, "$NetBSD: hptide.c,v 1.33 2012/07/31 15:50:36 bouyer Exp $"); #include #include @@ -199,6 +199,7 @@ hpt_chip_map(struct pciide_softc *sc, const struct pci_attach_args *pa) else sc->sc_wdcdev.sc_atac.atac_udma_cap = 5; } + sc->sc_wdcdev.wdc_maxdrives = 2; wdc_allocate_regs(&sc->sc_wdcdev); @@ -334,26 +335,26 @@ hpt_setup_channel(struct ata_channel *chp) } /* Per drive settings */ - for (drive = 0; drive < chp->ch_ndrive; drive++) { + for (drive = 0; drive < chp->ch_ndrives; drive++) { drvp = &chp->ch_drive[drive]; /* If no drive, skip */ - if ((drvp->drive_flags & DRIVE) == 0) + if (drvp->drive_type == ATA_DRIVET_NONE) continue; before = pci_conf_read(sc->sc_pc, sc->sc_tag, HPT_IDETIM(chp->ch_channel, drive)); /* add timing values, setup DMA if needed */ - if (drvp->drive_flags & DRIVE_UDMA) { + if (drvp->drive_flags & ATA_DRIVE_UDMA) { /* use Ultra/DMA */ s = splbio(); - drvp->drive_flags &= ~DRIVE_DMA; + drvp->drive_flags &= ~ATA_DRIVE_DMA; splx(s); if ((cable & HPT_CSEL_CBLID(chp->ch_channel)) != 0 && drvp->UDMA_mode > 2) drvp->UDMA_mode = 2; after = tim_udma[drvp->UDMA_mode]; idedma_ctl |= IDEDMA_CTL_DRV_DMA(drive); - } else if (drvp->drive_flags & DRIVE_DMA) { + } else if (drvp->drive_flags & ATA_DRIVE_DMA) { /* * use Multiword DMA. * Timings will be used for both PIO and DMA, so adjust diff --git a/sys/dev/pci/iteide.c b/sys/dev/pci/iteide.c index ee9590b1f41..e79c62b76c8 100644 --- a/sys/dev/pci/iteide.c +++ b/sys/dev/pci/iteide.c @@ -1,4 +1,4 @@ -/* $NetBSD: iteide.c,v 1.16 2012/07/26 20:49:49 jakllsch Exp $ */ +/* $NetBSD: iteide.c,v 1.17 2012/07/31 15:50:36 bouyer Exp $ */ /* * Copyright (c) 2004 The NetBSD Foundation, Inc. @@ -31,7 +31,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: iteide.c,v 1.16 2012/07/26 20:49:49 jakllsch Exp $"); +__KERNEL_RCSID(0, "$NetBSD: iteide.c,v 1.17 2012/07/31 15:50:36 bouyer Exp $"); #include #include @@ -132,6 +132,7 @@ ite_chip_map(struct pciide_softc *sc, const struct pci_attach_args *pa) sc->sc_wdcdev.sc_atac.atac_set_modes = ite_setup_channel; sc->sc_wdcdev.sc_atac.atac_channels = sc->wdc_chanarray; sc->sc_wdcdev.sc_atac.atac_nchannels = PCIIDE_NUM_CHANNELS; + sc->sc_wdcdev.wdc_maxdrives = 2; wdc_allocate_regs(&sc->sc_wdcdev); @@ -188,13 +189,13 @@ ite_setup_channel(struct ata_channel *chp) drvp = &chp->ch_drive[drive]; /* If no drive, skip */ - if ((drvp->drive_flags & DRIVE) == 0) + if (drvp->drive_type == ATA_DRIVET_NONE) continue; if ((chp->ch_atac->atac_cap & ATAC_CAP_UDMA) != 0 && - (drvp->drive_flags & DRIVE_UDMA) != 0) { + (drvp->drive_flags & ATA_DRIVE_UDMA) != 0) { /* Setup UltraDMA mode */ - drvp->drive_flags &= ~DRIVE_DMA; + drvp->drive_flags &= ~ATA_DRIVE_DMA; modectl &= ~IT_MODE_DMA(channel, drive); #if 0 @@ -216,9 +217,9 @@ ite_setup_channel(struct ata_channel *chp) mode = drvp->PIO_mode; } else if ((chp->ch_atac->atac_cap & ATAC_CAP_DMA) != 0 && - (drvp->drive_flags & DRIVE_DMA) != 0) { + (drvp->drive_flags & ATA_DRIVE_DMA) != 0) { /* Setup multiword DMA mode */ - drvp->drive_flags &= ~DRIVE_UDMA; + drvp->drive_flags &= ~ATA_DRIVE_UDMA; modectl |= IT_MODE_DMA(channel, drive); /* mode = min(pio, dma + 2) */ diff --git a/sys/dev/pci/ixpide.c b/sys/dev/pci/ixpide.c index d420ac5be38..b7a80601dab 100644 --- a/sys/dev/pci/ixpide.c +++ b/sys/dev/pci/ixpide.c @@ -1,4 +1,4 @@ -/* $NetBSD: ixpide.c,v 1.23 2012/07/26 20:49:49 jakllsch Exp $ */ +/* $NetBSD: ixpide.c,v 1.24 2012/07/31 15:50:36 bouyer Exp $ */ /* * Copyright (c) 2004 The NetBSD Foundation. @@ -27,7 +27,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: ixpide.c,v 1.23 2012/07/26 20:49:49 jakllsch Exp $"); +__KERNEL_RCSID(0, "$NetBSD: ixpide.c,v 1.24 2012/07/31 15:50:36 bouyer Exp $"); #include #include @@ -120,6 +120,7 @@ ixp_chip_map(struct pciide_softc *sc, const struct pci_attach_args *pa) sc->sc_wdcdev.sc_atac.atac_set_modes = ixp_setup_channel; sc->sc_wdcdev.sc_atac.atac_channels = sc->wdc_chanarray; sc->sc_wdcdev.sc_atac.atac_nchannels = PCIIDE_NUM_CHANNELS; + sc->sc_wdcdev.wdc_maxdrives = 2; interface = PCI_INTERFACE(pa->pa_class); @@ -187,15 +188,15 @@ ixp_setup_channel(struct ata_channel *chp) for (drive = 0; drive < 2; drive++) { drvp = &chp->ch_drive[drive]; - if ((drvp->drive_flags & DRIVE) == 0) + if (drvp->drive_type == ATA_DRIVET_NONE) continue; - if (drvp->drive_flags & DRIVE_UDMA) { + if (drvp->drive_flags & ATA_DRIVE_UDMA) { s = splbio(); - drvp->drive_flags &= ~DRIVE_DMA; + drvp->drive_flags &= ~ATA_DRIVE_DMA; splx(s); IXP_UDMA_ENABLE(udma, chp->ch_channel, drive); IXP_SET_MODE(udma, chp->ch_channel, drive, drvp->UDMA_mode); - } else if (drvp->drive_flags & DRIVE_DMA) { + } else if (drvp->drive_flags & ATA_DRIVE_DMA) { IXP_UDMA_DISABLE(udma, chp->ch_channel, drive); IXP_SET_TIMING(mdma_timing, chp->ch_channel, drive, ixp_mdma_timings[drvp->DMA_mode]); diff --git a/sys/dev/pci/jmide.c b/sys/dev/pci/jmide.c index 2d54f0d09e3..cb8928f0916 100644 --- a/sys/dev/pci/jmide.c +++ b/sys/dev/pci/jmide.c @@ -1,4 +1,4 @@ -/* $NetBSD: jmide.c,v 1.17 2012/07/26 20:49:49 jakllsch Exp $ */ +/* $NetBSD: jmide.c,v 1.18 2012/07/31 15:50:36 bouyer Exp $ */ /* * Copyright (c) 2007 Manuel Bouyer. @@ -25,7 +25,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: jmide.c,v 1.17 2012/07/26 20:49:49 jakllsch Exp $"); +__KERNEL_RCSID(0, "$NetBSD: jmide.c,v 1.18 2012/07/31 15:50:36 bouyer Exp $"); #include #include @@ -326,6 +326,7 @@ jmpata_chip_map(struct pciide_softc *sc, const struct pci_attach_args *pa) sc->sc_wdcdev.sc_atac.atac_set_modes = jmpata_setup_channel; sc->sc_wdcdev.sc_atac.atac_channels = sc->wdc_chanarray; sc->sc_wdcdev.sc_atac.atac_nchannels = PCIIDE_NUM_CHANNELS; + sc->sc_wdcdev.wdc_maxdrives = 2; wdc_allocate_regs(&sc->sc_wdcdev); /* * can't rely on the PCI_CLASS_REG content if the chip was in raid @@ -395,17 +396,17 @@ jmpata_setup_channel(struct ata_channel *chp) for (drive = 0; drive < 2; drive++) { drvp = &chp->ch_drive[drive]; /* If no drive, skip */ - if ((drvp->drive_flags & DRIVE) == 0) + if (drvp->drive_type == ATA_DRIVET_NONE) continue; - if (drvp->drive_flags & DRIVE_UDMA) { + if (drvp->drive_flags & ATA_DRIVE_UDMA) { /* use Ultra/DMA */ s = splbio(); - drvp->drive_flags &= ~DRIVE_DMA; + drvp->drive_flags &= ~ATA_DRIVE_DMA; if (drvp->UDMA_mode > 2 && ide80p == 0) drvp->UDMA_mode = 2; splx(s); idedma_ctl |= IDEDMA_CTL_DRV_DMA(drive); - } else if (drvp->drive_flags & DRIVE_DMA) { + } else if (drvp->drive_flags & ATA_DRIVE_DMA) { idedma_ctl |= IDEDMA_CTL_DRV_DMA(drive); } } diff --git a/sys/dev/pci/nside.c b/sys/dev/pci/nside.c index 3ce6cae7255..94aec9ba2c3 100644 --- a/sys/dev/pci/nside.c +++ b/sys/dev/pci/nside.c @@ -1,4 +1,4 @@ -/* $NetBSD: nside.c,v 1.6 2012/07/26 20:49:49 jakllsch Exp $ */ +/* $NetBSD: nside.c,v 1.7 2012/07/31 15:50:36 bouyer Exp $ */ /* * Copyright (c) 1999, 2000, 2001 Manuel Bouyer. @@ -25,7 +25,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: nside.c,v 1.6 2012/07/26 20:49:49 jakllsch Exp $"); +__KERNEL_RCSID(0, "$NetBSD: nside.c,v 1.7 2012/07/31 15:50:36 bouyer Exp $"); #include #include @@ -129,6 +129,7 @@ natsemi_chip_map(struct pciide_softc *sc, const struct pci_attach_args *pa) sc->sc_wdcdev.sc_atac.atac_set_modes = natsemi_setup_channel; sc->sc_wdcdev.sc_atac.atac_channels = sc->wdc_chanarray; sc->sc_wdcdev.sc_atac.atac_nchannels = PCIIDE_NUM_CHANNELS; + sc->sc_wdcdev.wdc_maxdrives = 2; interface = PCI_INTERFACE(pa->pa_class); interface &= ~PCIIDE_CHANSTATUS_EN; /* Reserved on PC87415 */ @@ -172,12 +173,12 @@ natsemi_setup_channel(struct ata_channel *chp) for (drive = 0; drive < 2; drive++) { drvp = &chp->ch_drive[drive]; /* If no drive, skip */ - if ((drvp->drive_flags & DRIVE) == 0) + if (drvp->drive_type == ATA_DRIVET_NONE) continue; ndrives++; /* add timing values, setup DMA if needed */ - if ((drvp->drive_flags & DRIVE_DMA) == 0) { + if ((drvp->drive_flags & ATA_DRIVE_DMA) == 0) { tim = natsemi_pio_pulse[drvp->PIO_mode] | (natsemi_pio_recover[drvp->PIO_mode] << 4); } else { diff --git a/sys/dev/pci/optiide.c b/sys/dev/pci/optiide.c index 788c45ccd0e..d1a3249c05d 100644 --- a/sys/dev/pci/optiide.c +++ b/sys/dev/pci/optiide.c @@ -1,4 +1,4 @@ -/* $NetBSD: optiide.c,v 1.23 2012/07/26 20:49:49 jakllsch Exp $ */ +/* $NetBSD: optiide.c,v 1.24 2012/07/31 15:50:36 bouyer Exp $ */ /*- * Copyright (c) 2000 The NetBSD Foundation, Inc. @@ -30,7 +30,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: optiide.c,v 1.23 2012/07/26 20:49:49 jakllsch Exp $"); +__KERNEL_RCSID(0, "$NetBSD: optiide.c,v 1.24 2012/07/31 15:50:36 bouyer Exp $"); #include #include @@ -141,6 +141,7 @@ opti_chip_map(struct pciide_softc *sc, const struct pci_attach_args *pa) sc->sc_wdcdev.sc_atac.atac_channels = sc->wdc_chanarray; sc->sc_wdcdev.sc_atac.atac_nchannels = PCIIDE_NUM_CHANNELS; + sc->sc_wdcdev.wdc_maxdrives = 2; init_ctrl = pciide_pci_read(sc->sc_pc, sc->sc_tag, OPTI_REG_INIT_CONTROL); @@ -197,12 +198,12 @@ opti_setup_channel(struct ata_channel *chp) for (drive = 0; drive < 2; drive++) { drvp = &chp->ch_drive[drive]; /* If no drive, skip */ - if ((drvp->drive_flags & DRIVE) == 0) { + if (drvp->drive_type == ATA_DRIVET_NONE) { mode[drive] = -1; continue; } - if ((drvp->drive_flags & DRIVE_DMA)) { + if ((drvp->drive_flags & ATA_DRIVE_DMA)) { /* * Timings will be used for both PIO and DMA, * so adjust DMA mode if needed @@ -233,7 +234,7 @@ opti_setup_channel(struct ata_channel *chp) 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; + chp->ch_drive[d].drive_flags &= ~ATA_DRIVE_DMA; splx(s); } } diff --git a/sys/dev/pci/pciide_common.c b/sys/dev/pci/pciide_common.c index ad54fd3612e..84d9eda94c7 100644 --- a/sys/dev/pci/pciide_common.c +++ b/sys/dev/pci/pciide_common.c @@ -1,4 +1,4 @@ -/* $NetBSD: pciide_common.c,v 1.56 2012/07/26 20:49:50 jakllsch Exp $ */ +/* $NetBSD: pciide_common.c,v 1.57 2012/07/31 15:50:36 bouyer Exp $ */ /* @@ -70,7 +70,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: pciide_common.c,v 1.56 2012/07/26 20:49:50 jakllsch Exp $"); +__KERNEL_RCSID(0, "$NetBSD: pciide_common.c,v 1.57 2012/07/31 15:50:36 bouyer Exp $"); #include #include @@ -203,7 +203,7 @@ pciide_common_detach(struct pciide_softc *sc, int flags) cp->ctl_baseioh, cp->ctl_ios); } - for (drive = 0; drive < cp->ata_channel.ch_ndrive; drive++) { + for (drive = 0; drive < sc->sc_wdcdev.wdc_maxdrives; drive++) { #if NATA_DMA pciide_dma_table_teardown(sc, channel, drive); #endif @@ -568,19 +568,19 @@ pciide_channel_dma_setup(struct pciide_channel *cp) struct pciide_softc *sc = CHAN_TO_PCIIDE(&cp->ata_channel); struct ata_drive_datas *drvp; - KASSERT(cp->ata_channel.ch_ndrive != 0); + KASSERT(cp->ata_channel.ch_ndrives != 0); - for (drive = 0; drive < cp->ata_channel.ch_ndrive; drive++) { + for (drive = 0; drive < cp->ata_channel.ch_ndrives; drive++) { drvp = &cp->ata_channel.ch_drive[drive]; /* If no drive, skip */ - if ((drvp->drive_flags & DRIVE) == 0) + if (drvp->drive_type == ATA_DRIVET_NONE) continue; /* setup DMA if needed */ - if (((drvp->drive_flags & DRIVE_DMA) == 0 && - (drvp->drive_flags & DRIVE_UDMA) == 0) || + if (((drvp->drive_flags & ATA_DRIVE_DMA) == 0 && + (drvp->drive_flags & ATA_DRIVE_UDMA) == 0) || sc->sc_dma_ok == 0) { s = splbio(); - drvp->drive_flags &= ~(DRIVE_DMA | DRIVE_UDMA); + drvp->drive_flags &= ~(ATA_DRIVE_DMA | ATA_DRIVE_UDMA); splx(s); continue; } @@ -588,7 +588,7 @@ pciide_channel_dma_setup(struct pciide_channel *cp) drive) != 0) { /* Abort DMA setup */ s = splbio(); - drvp->drive_flags &= ~(DRIVE_DMA | DRIVE_UDMA); + drvp->drive_flags &= ~(ATA_DRIVE_DMA | ATA_DRIVE_UDMA); splx(s); continue; } @@ -875,7 +875,6 @@ pciide_chansetup(struct pciide_softc *sc, int channel, pcireg_t interface) device_xname(sc->sc_wdcdev.sc_atac.atac_dev), cp->name); return 0; } - cp->ata_channel.ch_ndrive = 2; aprint_verbose_dev(sc->sc_wdcdev.sc_atac.atac_dev, "%s channel %s to %s mode\n", cp->name, (interface & PCIIDE_INTERFACE_SETTABLE(channel)) ? @@ -996,6 +995,7 @@ default_chip_map(struct pciide_softc *sc, const struct pci_attach_args *pa) sc->sc_wdcdev.sc_atac.atac_channels = sc->wdc_chanarray; sc->sc_wdcdev.sc_atac.atac_nchannels = PCIIDE_NUM_CHANNELS; sc->sc_wdcdev.sc_atac.atac_cap |= ATAC_CAP_DATA16; + sc->sc_wdcdev.wdc_maxdrives = 2; wdc_allocate_regs(&sc->sc_wdcdev); @@ -1069,7 +1069,7 @@ next: channel++) { idedma_ctl = 0; cp = &sc->pciide_channels[channel]; - for (drive = 0; drive < cp->ata_channel.ch_ndrive; drive++) { + for (drive = 0; drive < sc->sc_wdcdev.wdc_maxdrives; drive++) { /* * we have not probed the drives yet, allocate * ressources for all of them. @@ -1116,21 +1116,22 @@ sata_setup_channel(struct ata_channel *chp) idedma_ctl = 0; - for (drive = 0; drive < cp->ata_channel.ch_ndrive; drive++) { + KASSERT(cp->ata_channel.ch_ndrives != 0); + for (drive = 0; drive < cp->ata_channel.ch_ndrives; drive++) { drvp = &chp->ch_drive[drive]; /* If no drive, skip */ - if ((drvp->drive_flags & DRIVE) == 0) + if (drvp->drive_type == ATA_DRIVET_NONE) continue; #if NATA_UDMA - if (drvp->drive_flags & DRIVE_UDMA) { + if (drvp->drive_flags & ATA_DRIVE_UDMA) { /* use Ultra/DMA */ s = splbio(); - drvp->drive_flags &= ~DRIVE_DMA; + drvp->drive_flags &= ~ATA_DRIVE_DMA; splx(s); idedma_ctl |= IDEDMA_CTL_DRV_DMA(drive); } else #endif /* NATA_UDMA */ - if (drvp->drive_flags & DRIVE_DMA) { + if (drvp->drive_flags & ATA_DRIVE_DMA) { idedma_ctl |= IDEDMA_CTL_DRV_DMA(drive); } } diff --git a/sys/dev/pci/pciidevar.h b/sys/dev/pci/pciidevar.h index 073bd341327..311c6ab7017 100644 --- a/sys/dev/pci/pciidevar.h +++ b/sys/dev/pci/pciidevar.h @@ -1,4 +1,4 @@ -/* $NetBSD: pciidevar.h,v 1.45 2012/07/26 20:49:50 jakllsch Exp $ */ +/* $NetBSD: pciidevar.h,v 1.46 2012/07/31 15:50:36 bouyer Exp $ */ /* * Copyright (c) 1998 Christopher G. Demetriou. All rights reserved. @@ -142,7 +142,7 @@ struct pciide_softc { struct idedma_table *dma_table; bus_dmamap_t dmamap_xfer; int dma_flags; - } dma_maps[ATA_MAXDRIVES]; + } dma_maps[WDC_MAXDRIVES]; bus_space_handle_t dma_iohs[IDEDMA_NREGS]; /* * Some controllers require certain bits to diff --git a/sys/dev/pci/pdcide.c b/sys/dev/pci/pdcide.c index 314c2752159..43ee0a0192d 100644 --- a/sys/dev/pci/pdcide.c +++ b/sys/dev/pci/pdcide.c @@ -1,4 +1,4 @@ -/* $NetBSD: pdcide.c,v 1.33 2012/07/26 20:49:50 jakllsch Exp $ */ +/* $NetBSD: pdcide.c,v 1.34 2012/07/31 15:50:36 bouyer Exp $ */ /* * Copyright (c) 1999, 2000, 2001 Manuel Bouyer. @@ -25,7 +25,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: pdcide.c,v 1.33 2012/07/26 20:49:50 jakllsch Exp $"); +__KERNEL_RCSID(0, "$NetBSD: pdcide.c,v 1.34 2012/07/31 15:50:36 bouyer Exp $"); #include #include @@ -233,6 +233,7 @@ pdc202xx_chip_map(struct pciide_softc *sc, const struct pci_attach_args *pa) pdc20268_setup_channel : pdc202xx_setup_channel; sc->sc_wdcdev.sc_atac.atac_channels = sc->wdc_chanarray; sc->sc_wdcdev.sc_atac.atac_nchannels = PCIIDE_NUM_CHANNELS; + sc->sc_wdcdev.wdc_maxdrives = 2; wdc_allocate_regs(&sc->sc_wdcdev); @@ -349,9 +350,9 @@ pdc202xx_setup_channel(struct ata_channel *chp) st = pci_conf_read(sc->sc_pc, sc->sc_tag, PDC2xx_STATE); /* Trim UDMA mode */ if ((st & PDC262_STATE_80P(channel)) != 0 || - (chp->ch_drive[0].drive_flags & DRIVE_UDMA && + (chp->ch_drive[0].drive_flags & ATA_DRIVE_UDMA && chp->ch_drive[0].UDMA_mode <= 2) || - (chp->ch_drive[1].drive_flags & DRIVE_UDMA && + (chp->ch_drive[1].drive_flags & ATA_DRIVE_UDMA && chp->ch_drive[1].UDMA_mode <= 2)) { if (chp->ch_drive[0].UDMA_mode > 2) chp->ch_drive[0].UDMA_mode = 2; @@ -359,9 +360,9 @@ pdc202xx_setup_channel(struct ata_channel *chp) chp->ch_drive[1].UDMA_mode = 2; } /* Set U66 if needed */ - if ((chp->ch_drive[0].drive_flags & DRIVE_UDMA && + if ((chp->ch_drive[0].drive_flags & ATA_DRIVE_UDMA && chp->ch_drive[0].UDMA_mode > 2) || - (chp->ch_drive[1].drive_flags & DRIVE_UDMA && + (chp->ch_drive[1].drive_flags & ATA_DRIVE_UDMA && chp->ch_drive[1].UDMA_mode > 2)) scr |= PDC262_U66_EN(channel); else @@ -372,14 +373,14 @@ pdc202xx_setup_channel(struct ata_channel *chp) device_xname(sc->sc_wdcdev.sc_atac.atac_dev), channel, bus_space_read_4(sc->sc_dma_iot, sc->sc_dma_ioh, PDC262_ATAPI(channel))), DEBUG_PROBE); - if (chp->ch_drive[0].drive_flags & DRIVE_ATAPI || - chp->ch_drive[1].drive_flags & DRIVE_ATAPI) { - if (((chp->ch_drive[0].drive_flags & DRIVE_UDMA) && - !(chp->ch_drive[1].drive_flags & DRIVE_UDMA) && - (chp->ch_drive[1].drive_flags & DRIVE_DMA)) || - ((chp->ch_drive[1].drive_flags & DRIVE_UDMA) && - !(chp->ch_drive[0].drive_flags & DRIVE_UDMA) && - (chp->ch_drive[0].drive_flags & DRIVE_DMA))) + if (chp->ch_drive[0].drive_type == ATA_DRIVET_ATAPI || + chp->ch_drive[1].drive_type == ATA_DRIVET_ATAPI) { + if (((chp->ch_drive[0].drive_flags & ATA_DRIVE_UDMA) && + !(chp->ch_drive[1].drive_flags & ATA_DRIVE_UDMA) && + (chp->ch_drive[1].drive_flags & ATA_DRIVE_DMA)) || + ((chp->ch_drive[1].drive_flags & ATA_DRIVE_UDMA) && + !(chp->ch_drive[0].drive_flags & ATA_DRIVE_UDMA) && + (chp->ch_drive[0].drive_flags & ATA_DRIVE_DMA))) atapi = 0; else atapi = PDC262_ATAPI_UDMA; @@ -390,20 +391,20 @@ pdc202xx_setup_channel(struct ata_channel *chp) for (drive = 0; drive < 2; drive++) { drvp = &chp->ch_drive[drive]; /* If no drive, skip */ - if ((drvp->drive_flags & DRIVE) == 0) + if (drvp->drive_type == ATA_DRIVET_NONE) continue; mode = 0; - if (drvp->drive_flags & DRIVE_UDMA) { + if (drvp->drive_flags & ATA_DRIVE_UDMA) { /* use Ultra/DMA */ s = splbio(); - drvp->drive_flags &= ~DRIVE_DMA; + drvp->drive_flags &= ~ATA_DRIVE_DMA; splx(s); mode = PDC2xx_TIM_SET_MB(mode, pdc2xx_udma_mb[drvp->UDMA_mode]); mode = PDC2xx_TIM_SET_MC(mode, pdc2xx_udma_mc[drvp->UDMA_mode]); idedma_ctl |= IDEDMA_CTL_DRV_DMA(drive); - } else if (drvp->drive_flags & DRIVE_DMA) { + } else if (drvp->drive_flags & ATA_DRIVE_DMA) { mode = PDC2xx_TIM_SET_MB(mode, pdc2xx_dma_mb[drvp->DMA_mode]); mode = PDC2xx_TIM_SET_MC(mode, @@ -417,7 +418,7 @@ pdc202xx_setup_channel(struct ata_channel *chp) } mode = PDC2xx_TIM_SET_PA(mode, pdc2xx_pa[drvp->PIO_mode]); mode = PDC2xx_TIM_SET_PB(mode, pdc2xx_pb[drvp->PIO_mode]); - if (drvp->drive_flags & DRIVE_ATA) + if (drvp->drive_type == ATA_DRIVET_ATA) mode |= PDC2xx_TIM_PRE; mode |= PDC2xx_TIM_SYNC | PDC2xx_TIM_ERRDY; if (drvp->PIO_mode >= 3) { @@ -468,17 +469,17 @@ pdc20268_setup_channel(struct ata_channel *chp) for (drive = 0; drive < 2; drive++) { drvp = &chp->ch_drive[drive]; /* If no drive, skip */ - if ((drvp->drive_flags & DRIVE) == 0) + if (drvp->drive_type == ATA_DRIVET_NONE) continue; - if (drvp->drive_flags & DRIVE_UDMA) { + if (drvp->drive_flags & ATA_DRIVE_UDMA) { /* use Ultra/DMA */ s = splbio(); - drvp->drive_flags &= ~DRIVE_DMA; + drvp->drive_flags &= ~ATA_DRIVE_DMA; splx(s); idedma_ctl |= IDEDMA_CTL_DRV_DMA(drive); if (drvp->UDMA_mode > 2 && u100 == 0) drvp->UDMA_mode = 2; - } else if (drvp->drive_flags & DRIVE_DMA) { + } else if (drvp->drive_flags & ATA_DRIVE_DMA) { idedma_ctl |= IDEDMA_CTL_DRV_DMA(drive); } } @@ -594,14 +595,14 @@ pdc20262_dma_finish(void *v, int channel, int drive, int force) if (dma_maps->dma_flags & WDC_DMA_LBA48) { chp = sc->wdc_chanarray[channel]; atapi = 0; - if (chp->ch_drive[0].drive_flags & DRIVE_ATAPI || - chp->ch_drive[1].drive_flags & DRIVE_ATAPI) { - if ((!(chp->ch_drive[0].drive_flags & DRIVE_UDMA) || - (chp->ch_drive[1].drive_flags & DRIVE_UDMA) || - !(chp->ch_drive[1].drive_flags & DRIVE_DMA)) && - (!(chp->ch_drive[1].drive_flags & DRIVE_UDMA) || - (chp->ch_drive[0].drive_flags & DRIVE_UDMA) || - !(chp->ch_drive[0].drive_flags & DRIVE_DMA))) + if (chp->ch_drive[0].drive_type == ATA_DRIVET_ATAPI || + chp->ch_drive[1].drive_type == ATA_DRIVET_ATAPI) { + if ((!(chp->ch_drive[0].drive_flags & ATA_DRIVE_UDMA) || + (chp->ch_drive[1].drive_flags & ATA_DRIVE_UDMA) || + !(chp->ch_drive[1].drive_flags & ATA_DRIVE_DMA)) && + (!(chp->ch_drive[1].drive_flags & ATA_DRIVE_UDMA) || + (chp->ch_drive[0].drive_flags & ATA_DRIVE_UDMA) || + !(chp->ch_drive[0].drive_flags & ATA_DRIVE_DMA))) atapi = PDC262_ATAPI_UDMA; } bus_space_write_4(sc->sc_dma_iot, sc->sc_dma_ioh, diff --git a/sys/dev/pci/pdcsata.c b/sys/dev/pci/pdcsata.c index 307fad3529d..6a014e73457 100644 --- a/sys/dev/pci/pdcsata.c +++ b/sys/dev/pci/pdcsata.c @@ -1,4 +1,4 @@ -/* $NetBSD: pdcsata.c,v 1.24 2012/07/26 20:49:50 jakllsch Exp $ */ +/* $NetBSD: pdcsata.c,v 1.25 2012/07/31 15:50:36 bouyer Exp $ */ /* * Copyright (c) 2004, Manuel Bouyer. @@ -25,7 +25,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: pdcsata.c,v 1.24 2012/07/26 20:49:50 jakllsch Exp $"); +__KERNEL_RCSID(0, "$NetBSD: pdcsata.c,v 1.25 2012/07/31 15:50:36 bouyer Exp $"); #include #include @@ -292,6 +292,7 @@ pdcsata_chip_map(struct pciide_softc *sc, const struct pci_attach_args *pa) sc->sc_wdcdev.sc_atac.atac_udma_cap = 6; sc->sc_wdcdev.sc_atac.atac_set_modes = pdc203xx_setup_channel; sc->sc_wdcdev.sc_atac.atac_channels = sc->wdc_chanarray; + sc->sc_wdcdev.wdc_maxdrives = 2; sc->sc_wdcdev.reset = pdcsata_do_reset; @@ -302,6 +303,7 @@ pdcsata_chip_map(struct pciide_softc *sc, const struct pci_attach_args *pa) 0x00ff0033); sc->sc_wdcdev.sc_atac.atac_probe = wdc_sataprobe; sc->sc_wdcdev.sc_atac.atac_nchannels = PDC203xx_SATA_NCHANNELS; + sc->sc_wdcdev.wdc_maxdrives = 1; break; case PCI_PRODUCT_PROMISE_PDC20371: case PCI_PRODUCT_PROMISE_PDC20375: @@ -324,6 +326,7 @@ pdcsata_chip_map(struct pciide_softc *sc, const struct pci_attach_args *pa) 0x00ff00ff); sc->sc_wdcdev.sc_atac.atac_nchannels = PDC40718_SATA_NCHANNELS; sc->sc_wdcdev.sc_atac.atac_probe = wdc_sataprobe; + sc->sc_wdcdev.wdc_maxdrives = 1; break; case PCI_PRODUCT_PROMISE_PDC20571: @@ -373,7 +376,6 @@ pdcsata_chip_map(struct pciide_softc *sc, const struct pci_attach_args *pa) cp->ata_channel.ch_atac = &sc->sc_wdcdev.sc_atac; cp->ata_channel.ch_queue = malloc(sizeof(struct ata_queue), M_DEVBUF, M_NOWAIT); - cp->ata_channel.ch_ndrive = 2; if (cp->ata_channel.ch_queue == NULL) { aprint_error("%s channel %d: " "can't allocate memory for command queue\n", @@ -496,11 +498,11 @@ pdc203xx_setup_channel(struct ata_channel *chp) for (drive = 0; drive < 2; drive++) { drvp = &chp->ch_drive[drive]; - if ((drvp->drive_flags & DRIVE) == 0) + if (drvp->drive_type == ATA_DRIVET_NONE) continue; - if (drvp->drive_flags & DRIVE_UDMA) { + if (drvp->drive_flags & ATA_DRIVE_UDMA) { s = splbio(); - drvp->drive_flags &= ~DRIVE_DMA; + drvp->drive_flags &= ~ATA_DRIVE_DMA; splx(s); } } diff --git a/sys/dev/pci/piixide.c b/sys/dev/pci/piixide.c index 441de21fea3..065f4573479 100644 --- a/sys/dev/pci/piixide.c +++ b/sys/dev/pci/piixide.c @@ -1,4 +1,4 @@ -/* $NetBSD: piixide.c,v 1.62 2012/07/26 20:49:50 jakllsch Exp $ */ +/* $NetBSD: piixide.c,v 1.63 2012/07/31 15:50:36 bouyer Exp $ */ /* * Copyright (c) 1999, 2000, 2001 Manuel Bouyer. @@ -25,7 +25,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: piixide.c,v 1.62 2012/07/26 20:49:50 jakllsch Exp $"); +__KERNEL_RCSID(0, "$NetBSD: piixide.c,v 1.63 2012/07/31 15:50:36 bouyer Exp $"); #include #include @@ -486,6 +486,7 @@ piix_chip_map(struct pciide_softc *sc, const struct pci_attach_args *pa) sc->sc_wdcdev.sc_atac.atac_set_modes = piix3_4_setup_channel; sc->sc_wdcdev.sc_atac.atac_channels = sc->wdc_chanarray; sc->sc_wdcdev.sc_atac.atac_nchannels = PCIIDE_NUM_CHANNELS; + sc->sc_wdcdev.wdc_maxdrives = 2; ATADEBUG_PRINT(("piix_setup_chip: old idetim=0x%x", pci_conf_read(sc->sc_pc, sc->sc_tag, PIIX_IDETIM)), @@ -611,8 +612,8 @@ piix_setup_channel(struct ata_channel *chp) */ /* If both drives supports DMA, take the lower mode */ - if ((drvp[0].drive_flags & DRIVE_DMA) && - (drvp[1].drive_flags & DRIVE_DMA)) { + if ((drvp[0].drive_flags & ATA_DRIVE_DMA) && + (drvp[1].drive_flags & ATA_DRIVE_DMA)) { mode[0] = mode[1] = min(drvp[0].DMA_mode, drvp[1].DMA_mode); drvp[0].DMA_mode = mode[0]; @@ -623,7 +624,7 @@ piix_setup_channel(struct ata_channel *chp) * If only one drive supports DMA, use its mode, and * put the other one in PIO mode 0 if mode not compatible */ - if (drvp[0].drive_flags & DRIVE_DMA) { + if (drvp[0].drive_flags & ATA_DRIVE_DMA) { mode[0] = drvp[0].DMA_mode; mode[1] = drvp[1].PIO_mode; if (piix_isp_pio[mode[1]] != piix_isp_dma[mode[0]] || @@ -631,7 +632,7 @@ piix_setup_channel(struct ata_channel *chp) mode[1] = drvp[1].PIO_mode = 0; goto ok; } - if (drvp[1].drive_flags & DRIVE_DMA) { + if (drvp[1].drive_flags & ATA_DRIVE_DMA) { mode[1] = drvp[1].DMA_mode; mode[0] = drvp[0].PIO_mode; if (piix_isp_pio[mode[0]] != piix_isp_dma[mode[1]] || @@ -657,7 +658,7 @@ piix_setup_channel(struct ata_channel *chp) } ok: /* The modes are setup */ for (drive = 0; drive < 2; drive++) { - if (drvp[drive].drive_flags & DRIVE_DMA) { + if (drvp[drive].drive_flags & ATA_DRIVE_DMA) { idetim |= piix_setup_idetim_timings( mode[drive], 1, chp->ch_channel); goto end; @@ -676,10 +677,10 @@ end: /* */ for (drive = 0; drive < 2; drive++) { /* If no drive, skip */ - if ((drvp[drive].drive_flags & DRIVE) == 0) + if (drvp[drive].drive_type == ATA_DRIVET_NONE) continue; idetim |= piix_setup_idetim_drvs(&drvp[drive]); - if (drvp[drive].drive_flags & DRIVE_DMA) + if (drvp[drive].drive_flags & ATA_DRIVE_DMA) idedma_ctl |= IDEDMA_CTL_DRV_DMA(drive); } if (idedma_ctl != 0) { @@ -721,10 +722,10 @@ piix3_4_setup_channel(struct ata_channel *chp) PIIX_UDMATIM_SET(0x3, channel, drive)); drvp = &chp->ch_drive[drive]; /* If no drive, skip */ - if ((drvp->drive_flags & DRIVE) == 0) + if (drvp->drive_type == ATA_DRIVET_NONE) continue; - if (((drvp->drive_flags & DRIVE_DMA) == 0 && - (drvp->drive_flags & DRIVE_UDMA) == 0)) + if (((drvp->drive_flags & ATA_DRIVE_DMA) == 0 && + (drvp->drive_flags & ATA_DRIVE_UDMA) == 0)) goto pio; if (sc->sc_pp->ide_product == PCI_PRODUCT_INTEL_82801AA_IDE || @@ -781,10 +782,10 @@ piix3_4_setup_channel(struct ata_channel *chp) ideconf &= ~PIIX_CONFIG_UDMA66(channel, drive); } if ((wdc->sc_atac.atac_cap & ATAC_CAP_UDMA) && - (drvp->drive_flags & DRIVE_UDMA)) { + (drvp->drive_flags & ATA_DRIVE_UDMA)) { /* use Ultra/DMA */ s = splbio(); - drvp->drive_flags &= ~DRIVE_DMA; + drvp->drive_flags &= ~ATA_DRIVE_DMA; splx(s); udmareg |= PIIX_UDMACTL_DRV_EN( channel, drive); udmareg |= PIIX_UDMATIM_SET( @@ -792,7 +793,7 @@ piix3_4_setup_channel(struct ata_channel *chp) } else { /* use Multiword DMA */ s = splbio(); - drvp->drive_flags &= ~DRIVE_UDMA; + drvp->drive_flags &= ~ATA_DRIVE_UDMA; splx(s); if (drive == 0) { idetim |= piix_setup_idetim_timings( @@ -860,9 +861,9 @@ piix_setup_idetim_drvs(struct ata_drive_datas *drvp) * If drive is using UDMA, timings setups are independent * So just check DMA and PIO here. */ - if (drvp->drive_flags & DRIVE_DMA) { + if (drvp->drive_flags & ATA_DRIVE_DMA) { /* if mode = DMA mode 0, use compatible timings */ - if ((drvp->drive_flags & DRIVE_DMA) && + if ((drvp->drive_flags & ATA_DRIVE_DMA) && drvp->DMA_mode == 0) { drvp->PIO_mode = 0; return ret; @@ -943,6 +944,7 @@ piixsata_chip_map(struct pciide_softc *sc, const struct pci_attach_args *pa) sc->sc_wdcdev.sc_atac.atac_channels = sc->wdc_chanarray; sc->sc_wdcdev.sc_atac.atac_nchannels = PCIIDE_NUM_CHANNELS; + sc->sc_wdcdev.wdc_maxdrives = 2; cmdsts = pci_conf_read(sc->sc_pc, sc->sc_tag, PCI_COMMAND_STATUS_REG); cmdsts &= ~PCI_COMMAND_INTERRUPT_DISABLE; diff --git a/sys/dev/pci/rccide.c b/sys/dev/pci/rccide.c index d53acfaf773..a269c887d5a 100644 --- a/sys/dev/pci/rccide.c +++ b/sys/dev/pci/rccide.c @@ -1,4 +1,4 @@ -/* $NetBSD: rccide.c,v 1.25 2012/07/26 20:49:50 jakllsch Exp $ */ +/* $NetBSD: rccide.c,v 1.26 2012/07/31 15:50:36 bouyer Exp $ */ /* * Copyright (c) 2003 By Noon Software, Inc. All rights reserved. @@ -27,7 +27,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: rccide.c,v 1.25 2012/07/26 20:49:50 jakllsch Exp $"); +__KERNEL_RCSID(0, "$NetBSD: rccide.c,v 1.26 2012/07/31 15:50:36 bouyer Exp $"); #include #include @@ -152,6 +152,7 @@ serverworks_chip_map(struct pciide_softc *sc, const struct pci_attach_args *pa) sc->sc_wdcdev.sc_atac.atac_set_modes = serverworks_setup_channel; sc->sc_wdcdev.sc_atac.atac_channels = sc->wdc_chanarray; sc->sc_wdcdev.sc_atac.atac_nchannels = 2; + sc->sc_wdcdev.wdc_maxdrives = 2; wdc_allocate_regs(&sc->sc_wdcdev); @@ -211,14 +212,14 @@ serverworks_setup_channel(struct ata_channel *chp) for (drive = 0; drive < 2; drive++) { drvp = &chp->ch_drive[drive]; /* If no drive, skip */ - if ((drvp->drive_flags & DRIVE) == 0) + if (drvp->drive_type == ATA_DRIVET_NONE) continue; unit = drive + 2 * channel; /* add timing values, setup DMA if needed */ pio_time |= pio_modes[drvp->PIO_mode] << (8 * (unit^1)); pio_mode |= drvp->PIO_mode << (4 * unit + 16); if ((atac->atac_cap & ATAC_CAP_UDMA) && - (drvp->drive_flags & DRIVE_UDMA)) { + (drvp->drive_flags & ATA_DRIVE_UDMA)) { /* use Ultra/DMA, check for 80-pin cable */ if (drvp->UDMA_mode > 2 && (PCI_PRODUCT(pci_conf_read(sc->sc_pc, sc->sc_tag, @@ -230,17 +231,17 @@ serverworks_setup_channel(struct ata_channel *chp) udma_mode |= 1 << unit; idedma_ctl |= IDEDMA_CTL_DRV_DMA(drive); } else if ((atac->atac_cap & ATAC_CAP_DMA) && - (drvp->drive_flags & DRIVE_DMA)) { + (drvp->drive_flags & ATA_DRIVE_DMA)) { /* use Multiword DMA */ s = splbio(); - drvp->drive_flags &= ~DRIVE_UDMA; + drvp->drive_flags &= ~ATA_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); + drvp->drive_flags &= ~(ATA_DRIVE_UDMA | ATA_DRIVE_DMA); splx(s); } } diff --git a/sys/dev/pci/rdcide.c b/sys/dev/pci/rdcide.c index f3528a2dde3..fb87ed56abf 100644 --- a/sys/dev/pci/rdcide.c +++ b/sys/dev/pci/rdcide.c @@ -1,4 +1,4 @@ -/* $NetBSD: rdcide.c,v 1.6 2012/07/26 20:49:50 jakllsch Exp $ */ +/* $NetBSD: rdcide.c,v 1.7 2012/07/31 15:50:36 bouyer Exp $ */ /* * Copyright (c) 2011 Manuel Bouyer. @@ -25,7 +25,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: rdcide.c,v 1.6 2012/07/26 20:49:50 jakllsch Exp $"); +__KERNEL_RCSID(0, "$NetBSD: rdcide.c,v 1.7 2012/07/31 15:50:36 bouyer Exp $"); #include #include @@ -144,6 +144,7 @@ rdcide_chip_map(struct pciide_softc *sc, const struct pci_attach_args *pa) sc->sc_wdcdev.sc_atac.atac_set_modes = rdcide_setup_channel; sc->sc_wdcdev.sc_atac.atac_channels = sc->wdc_chanarray; sc->sc_wdcdev.sc_atac.atac_nchannels = PCIIDE_NUM_CHANNELS; + sc->sc_wdcdev.wdc_maxdrives = 2; ATADEBUG_PRINT(("rdcide_setup_chip: old PATR=0x%x", pci_conf_read(sc->sc_pc, sc->sc_tag, RDCIDE_PATR)), @@ -219,9 +220,9 @@ rdcide_setup_channel(struct ata_channel *chp) } /* now setup modes */ for (drive = 0; drive < 2; drive++) { - if ((drvp[drive].drive_flags & DRIVE) == 0) + if (drvp[drive].drive_type == ATA_DRIVET_NONE) continue; - if ((drvp[drive].drive_flags & DRIVE_ATAPI) == 0) + if (drvp[drive].drive_type == ATA_DRIVET_ATAPI) patr |= RDCIDE_PATR_ATA(chp->ch_channel, drive); if (drive == 0) { patr |= RDCIDE_PATR_SETUP( @@ -243,10 +244,10 @@ rdcide_setup_channel(struct ata_channel *chp) patr |= RDCIDE_PATR_FTIM(chp->ch_channel, drive); patr |= RDCIDE_PATR_IORDY(chp->ch_channel, drive); } - if (drvp[drive].drive_flags & DRIVE_DMA) { + if (drvp[drive].drive_flags & ATA_DRIVE_DMA) { patr |= RDCIDE_PATR_DMAEN(chp->ch_channel, drive); } - if ((drvp[drive].drive_flags & DRIVE_UDMA) == 0) + if ((drvp[drive].drive_flags & ATA_DRIVE_UDMA) == 0) continue; if ((iiocr & RDCIDE_IIOCR_CABLE(chp->ch_channel, drive)) == 0 diff --git a/sys/dev/pci/satalink.c b/sys/dev/pci/satalink.c index e1eaffd0559..aefda296cee 100644 --- a/sys/dev/pci/satalink.c +++ b/sys/dev/pci/satalink.c @@ -1,4 +1,4 @@ -/* $NetBSD: satalink.c,v 1.47 2012/07/26 20:49:50 jakllsch Exp $ */ +/* $NetBSD: satalink.c,v 1.48 2012/07/31 15:50:36 bouyer Exp $ */ /*- * Copyright (c) 2003 The NetBSD Foundation, Inc. @@ -30,7 +30,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: satalink.c,v 1.47 2012/07/26 20:49:50 jakllsch Exp $"); +__KERNEL_RCSID(0, "$NetBSD: satalink.c,v 1.48 2012/07/31 15:50:36 bouyer Exp $"); #include #include @@ -505,6 +505,7 @@ sii3112_chip_map(struct pciide_softc *sc, const struct pci_attach_args *pa) sc->sc_wdcdev.sc_atac.atac_channels = sc->wdc_chanarray; sc->sc_wdcdev.sc_atac.atac_nchannels = PCIIDE_NUM_CHANNELS; + sc->sc_wdcdev.wdc_maxdrives = 1; wdc_allocate_regs(&sc->sc_wdcdev); @@ -606,7 +607,6 @@ sii3114_chansetup(struct pciide_softc *sc, int channel) cp->ata_channel.ch_atac = &sc->sc_wdcdev.sc_atac; cp->ata_channel.ch_queue = malloc(sizeof(struct ata_queue), M_DEVBUF, M_NOWAIT); - cp->ata_channel.ch_ndrive = 2; if (cp->ata_channel.ch_queue == NULL) { aprint_error("%s %s channel: " "can't allocate memory for command queue", @@ -750,6 +750,7 @@ sii3114_chip_map(struct pciide_softc *sc, const struct pci_attach_args *pa) sc->sc_wdcdev.sc_atac.atac_channels = sc->wdc_chanarray; sc->sc_wdcdev.sc_atac.atac_nchannels = 4; + sc->sc_wdcdev.wdc_maxdrives = 1; wdc_allocate_regs(&sc->sc_wdcdev); @@ -795,13 +796,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, s; - - /* XXX This should be done by other code. */ - for (i = 0; i < 2; i++) { - chp->ch_drive[i].chnl_softc = chp; - chp->ch_drive[i].drive = i; - } + int s; /* * The 3112 is a 2-port part, and only has one drive per channel @@ -875,15 +870,17 @@ sii3112_drv_probe(struct ata_channel *chp) device_xname(&sc->sc_wdcdev.sc_atac.atac_dev), chp->ch_channel, scnt, sn, cl, ch); #endif + if (atabus_alloc_drives(chp, 1) != 0) + return; /* * 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; + chp->ch_drive[0].drive_type = ATA_DRIVET_ATAPI; else - chp->ch_drive[0].drive_flags |= DRIVE_ATA; + chp->ch_drive[0].drive_type = ATA_DRIVET_ATA; splx(s); aprint_normal_dev(sc->sc_wdcdev.sc_atac.atac_dev, @@ -917,16 +914,16 @@ sii3112_setup_channel(struct ata_channel *chp) for (drive = 0; drive < 2; drive++) { drvp = &chp->ch_drive[drive]; /* If no drive, skip */ - if ((drvp->drive_flags & DRIVE) == 0) + if (drvp->drive_type == ATA_DRIVET_NONE) continue; - if (drvp->drive_flags & DRIVE_UDMA) { + if (drvp->drive_flags & ATA_DRIVE_UDMA) { /* use Ultra/DMA */ s = splbio(); - drvp->drive_flags &= ~DRIVE_DMA; + drvp->drive_flags &= ~ATA_DRIVE_DMA; splx(s); idedma_ctl |= IDEDMA_CTL_DRV_DMA(drive); dtm |= DTM_IDEx_DMA; - } else if (drvp->drive_flags & DRIVE_DMA) { + } else if (drvp->drive_flags & ATA_DRIVE_DMA) { idedma_ctl |= IDEDMA_CTL_DRV_DMA(drive); dtm |= DTM_IDEx_DMA; } else { diff --git a/sys/dev/pci/schide.c b/sys/dev/pci/schide.c index 84206f8fad3..688beb40a47 100644 --- a/sys/dev/pci/schide.c +++ b/sys/dev/pci/schide.c @@ -1,4 +1,4 @@ -/* $NetBSD: schide.c,v 1.6 2012/07/26 20:49:50 jakllsch Exp $ */ +/* $NetBSD: schide.c,v 1.7 2012/07/31 15:50:36 bouyer Exp $ */ /* $OpenBSD: pciide.c,v 1.305 2009/11/01 01:50:15 dlg Exp $ */ /* @@ -57,7 +57,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: schide.c,v 1.6 2012/07/26 20:49:50 jakllsch Exp $"); +__KERNEL_RCSID(0, "$NetBSD: schide.c,v 1.7 2012/07/31 15:50:36 bouyer Exp $"); #include #include @@ -140,6 +140,7 @@ sch_chip_map(struct pciide_softc *sc, const struct pci_attach_args *pa) sc->sc_wdcdev.sc_atac.atac_set_modes = sch_setup_channel; sc->sc_wdcdev.sc_atac.atac_channels = sc->wdc_chanarray; sc->sc_wdcdev.sc_atac.atac_nchannels = 1; + sc->sc_wdcdev.wdc_maxdrives = 2; ATADEBUG_PRINT(("sch_setup_chip: old d0tim=0x%x, d1tim=0x%x\n", @@ -184,26 +185,26 @@ sch_setup_channel(struct ata_channel *chp) for (drive = 0; drive < 2; drive++) { drvp = &chp->ch_drive[drive]; /* If no drive, skip */ - if ((drvp->drive_flags & DRIVE) == 0) + if (drvp->drive_type == ATA_DRIVET_NONE) continue; timaddr = (drive == 0) ? SCH_D0TIM : SCH_D1TIM; tim = pci_conf_read(sc->sc_pc, sc->sc_tag, timaddr); tim &= ~SCH_TIM_MASK; - if (((drvp->drive_flags & DRIVE_DMA) == 0 && - (drvp->drive_flags & DRIVE_UDMA) == 0)) + if (((drvp->drive_flags & ATA_DRIVE_DMA) == 0 && + (drvp->drive_flags & ATA_DRIVE_UDMA) == 0)) goto pio; /* add timing values, setup DMA if needed */ if ((atac->atac_cap & ATAC_CAP_UDMA) && - (drvp->drive_flags & DRIVE_UDMA)) { + (drvp->drive_flags & ATA_DRIVE_UDMA)) { /* use Ultra/DMA */ tim |= (drvp->UDMA_mode << 16) | SCH_TIM_SYNCDMA; } else { /* use Multiword DMA */ s = splbio(); - drvp->drive_flags &= ~DRIVE_UDMA; + drvp->drive_flags &= ~ATA_DRIVE_UDMA; splx(s); tim &= ~SCH_TIM_SYNCDMA; } diff --git a/sys/dev/pci/siside.c b/sys/dev/pci/siside.c index 09ebb4986e1..695209c5e04 100644 --- a/sys/dev/pci/siside.c +++ b/sys/dev/pci/siside.c @@ -1,4 +1,4 @@ -/* $NetBSD: siside.c,v 1.32 2012/07/26 20:49:50 jakllsch Exp $ */ +/* $NetBSD: siside.c,v 1.33 2012/07/31 15:50:36 bouyer Exp $ */ /* * Copyright (c) 1999, 2000, 2001 Manuel Bouyer. @@ -25,7 +25,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: siside.c,v 1.32 2012/07/26 20:49:50 jakllsch Exp $"); +__KERNEL_RCSID(0, "$NetBSD: siside.c,v 1.33 2012/07/31 15:50:36 bouyer Exp $"); #include #include @@ -293,6 +293,7 @@ sis_chip_map(struct pciide_softc *sc, const struct pci_attach_args *pa) sc->sc_wdcdev.sc_atac.atac_channels = sc->wdc_chanarray; sc->sc_wdcdev.sc_atac.atac_nchannels = PCIIDE_NUM_CHANNELS; + sc->sc_wdcdev.wdc_maxdrives = 2; switch(sc->sis_type) { case SIS_TYPE_NOUDMA: case SIS_TYPE_66: @@ -357,13 +358,13 @@ sis96x_setup_channel(struct ata_channel *chp) chp->ch_channel, drive); drvp = &chp->ch_drive[drive]; /* If no drive, skip */ - if ((drvp->drive_flags & DRIVE) == 0) + if (drvp->drive_type == ATA_DRIVET_NONE) continue; /* add timing values, setup DMA if needed */ - if (drvp->drive_flags & DRIVE_UDMA) { + if (drvp->drive_flags & ATA_DRIVE_UDMA) { /* use Ultra/DMA */ s = splbio(); - drvp->drive_flags &= ~DRIVE_DMA; + drvp->drive_flags &= ~ATA_DRIVE_DMA; splx(s); if (pciide_pci_read(sc->sc_pc, sc->sc_tag, SIS96x_REG_CBL(chp->ch_channel)) & SIS96x_REG_CBL_33) { @@ -373,7 +374,7 @@ sis96x_setup_channel(struct ata_channel *chp) sis_tim |= sis_udma133new_tim[drvp->UDMA_mode]; sis_tim |= sis_pio133new_tim[drvp->PIO_mode]; idedma_ctl |= IDEDMA_CTL_DRV_DMA(drive); - } else if (drvp->drive_flags & DRIVE_DMA) { + } else if (drvp->drive_flags & ATA_DRIVE_DMA) { /* * use Multiword DMA * Timings will be used for both PIO and DMA, @@ -423,17 +424,17 @@ sis_setup_channel(struct ata_channel *chp) for (drive = 0; drive < 2; drive++) { drvp = &chp->ch_drive[drive]; /* If no drive, skip */ - if ((drvp->drive_flags & DRIVE) == 0) + if (drvp->drive_type == ATA_DRIVET_NONE) continue; /* add timing values, setup DMA if needed */ - if ((drvp->drive_flags & DRIVE_DMA) == 0 && - (drvp->drive_flags & DRIVE_UDMA) == 0) + if ((drvp->drive_flags & ATA_DRIVE_DMA) == 0 && + (drvp->drive_flags & ATA_DRIVE_UDMA) == 0) goto pio; - if (drvp->drive_flags & DRIVE_UDMA) { + if (drvp->drive_flags & ATA_DRIVE_UDMA) { /* use Ultra/DMA */ s = splbio(); - drvp->drive_flags &= ~DRIVE_DMA; + drvp->drive_flags &= ~ATA_DRIVE_DMA; splx(s); if (pciide_pci_read(sc->sc_pc, sc->sc_tag, SIS_REG_CBL) & SIS_REG_CBL_33(chp->ch_channel)) { @@ -544,6 +545,7 @@ sis_sata_chip_map(struct pciide_softc *sc, const struct pci_attach_args *pa) sc->sc_wdcdev.sc_atac.atac_nchannels = PCIIDE_NUM_CHANNELS; sc->sc_wdcdev.sc_atac.atac_cap |= ATAC_CAP_DATA16 | ATAC_CAP_DATA32; sc->sc_wdcdev.sc_atac.atac_set_modes = sata_setup_channel; + sc->sc_wdcdev.wdc_maxdrives = 2; wdc_allocate_regs(&sc->sc_wdcdev); diff --git a/sys/dev/pci/slide.c b/sys/dev/pci/slide.c index 6a688a02859..29ea3882c19 100644 --- a/sys/dev/pci/slide.c +++ b/sys/dev/pci/slide.c @@ -1,4 +1,4 @@ -/* $NetBSD: slide.c,v 1.27 2012/07/26 20:49:50 jakllsch Exp $ */ +/* $NetBSD: slide.c,v 1.28 2012/07/31 15:50:36 bouyer Exp $ */ /*- * Copyright (c) 2002 The NetBSD Foundation, Inc. @@ -30,7 +30,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: slide.c,v 1.27 2012/07/26 20:49:50 jakllsch Exp $"); +__KERNEL_RCSID(0, "$NetBSD: slide.c,v 1.28 2012/07/31 15:50:36 bouyer Exp $"); #include #include @@ -160,6 +160,7 @@ sl82c105_chip_map(struct pciide_softc *sc, const struct pci_attach_args *pa) sc->sc_wdcdev.sc_atac.atac_channels = sc->wdc_chanarray; sc->sc_wdcdev.sc_atac.atac_nchannels = PCIIDE_NUM_CHANNELS; + sc->sc_wdcdev.wdc_maxdrives = 2; idecr = pci_conf_read(sc->sc_pc, sc->sc_tag, SYMPH_IDECSR); @@ -207,12 +208,12 @@ sl82c105_setup_channel(struct ata_channel *chp) drvp = &chp->ch_drive[drive]; /* If no drive, skip. */ - if ((drvp->drive_flags & DRIVE) == 0) { + if (drvp->drive_type == ATA_DRIVET_NONE) { pci_conf_write(sc->sc_pc, sc->sc_tag, pxdx_reg, pxdx); continue; } - if (drvp->drive_flags & DRIVE_DMA) { + if (drvp->drive_flags & ATA_DRIVE_DMA) { /* * Timings will be used for both PIO and DMA, * so adjust DMA mode if needed. @@ -226,7 +227,7 @@ sl82c105_setup_channel(struct ata_channel *chp) * Disable DMA. */ s = splbio(); - drvp->drive_flags &= ~DRIVE_DMA; + drvp->drive_flags &= ~ATA_DRIVE_DMA; splx(s); } } else { @@ -235,12 +236,12 @@ sl82c105_setup_channel(struct ata_channel *chp) * DMA. */ s = splbio(); - drvp->drive_flags &= ~DRIVE_DMA; + drvp->drive_flags &= ~ATA_DRIVE_DMA; splx(s); } } - if (drvp->drive_flags & DRIVE_DMA) { + if (drvp->drive_flags & ATA_DRIVE_DMA) { /* Use multi-word DMA. */ pxdx |= symph_mw_dma_times[drvp->DMA_mode].cmd_on << PxDx_CMD_ON_SHIFT; diff --git a/sys/dev/pci/stpcide.c b/sys/dev/pci/stpcide.c index 14ae1623077..56d72130f81 100644 --- a/sys/dev/pci/stpcide.c +++ b/sys/dev/pci/stpcide.c @@ -1,4 +1,4 @@ -/* $NetBSD: stpcide.c,v 1.25 2012/07/26 20:49:50 jakllsch Exp $ */ +/* $NetBSD: stpcide.c,v 1.26 2012/07/31 15:50:36 bouyer Exp $ */ /*- * Copyright (c) 2003 The NetBSD Foundation, Inc. @@ -30,7 +30,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: stpcide.c,v 1.25 2012/07/26 20:49:50 jakllsch Exp $"); +__KERNEL_RCSID(0, "$NetBSD: stpcide.c,v 1.26 2012/07/31 15:50:36 bouyer Exp $"); #include #include @@ -109,6 +109,7 @@ stpc_chip_map(struct pciide_softc *sc, const struct pci_attach_args *pa) sc->sc_wdcdev.sc_atac.atac_set_modes = stpc_setup_channel; sc->sc_wdcdev.sc_atac.atac_channels = sc->wdc_chanarray; sc->sc_wdcdev.sc_atac.atac_nchannels = PCIIDE_NUM_CHANNELS; + sc->sc_wdcdev.wdc_maxdrives = 2; wdc_allocate_regs(&sc->sc_wdcdev); @@ -158,14 +159,14 @@ stpc_setup_channel(struct ata_channel *chp) for (drive = 0; drive < 2; drive++) { drvp = &chp->ch_drive[drive]; /* If no drive, skip */ - if ((drvp->drive_flags & DRIVE) == 0) + if (drvp->drive_type == ATA_DRIVET_NONE) continue; /* add timing values, setup DMA if needed */ if ((atac->atac_cap & ATAC_CAP_DMA) && - (drvp->drive_flags & DRIVE_DMA)) { + (drvp->drive_flags & ATA_DRIVE_DMA)) { /* use Multiword DMA */ s = splbio(); - drvp->drive_flags &= ~DRIVE_UDMA; + drvp->drive_flags &= ~ATA_DRIVE_UDMA; splx(s); idedma_ctl |= IDEDMA_CTL_DRV_DMA(drive); bits[drive] = 0xe; /* IOCHRDY,wr/post,rd/prefetch */ @@ -173,7 +174,7 @@ stpc_setup_channel(struct ata_channel *chp) else { /* PIO only */ s = splbio(); - drvp->drive_flags &= ~(DRIVE_UDMA | DRIVE_DMA); + drvp->drive_flags &= ~(ATA_DRIVE_UDMA | ATA_DRIVE_DMA); splx(s); bits[drive] = 0x8; /* IOCHRDY */ } diff --git a/sys/dev/pci/svwsata.c b/sys/dev/pci/svwsata.c index c7c44b8c3dc..ad89a6410fe 100644 --- a/sys/dev/pci/svwsata.c +++ b/sys/dev/pci/svwsata.c @@ -1,4 +1,4 @@ -/* $NetBSD: svwsata.c,v 1.15 2012/07/26 20:49:50 jakllsch Exp $ */ +/* $NetBSD: svwsata.c,v 1.16 2012/07/31 15:50:36 bouyer Exp $ */ /* * Copyright (c) 2005 Mark Kettenis @@ -17,7 +17,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: svwsata.c,v 1.15 2012/07/26 20:49:50 jakllsch Exp $"); +__KERNEL_RCSID(0, "$NetBSD: svwsata.c,v 1.16 2012/07/31 15:50:36 bouyer Exp $"); #include #include @@ -151,6 +151,7 @@ svwsata_chip_map(struct pciide_softc *sc, const struct pci_attach_args *pa) /* We can use SControl and SStatus to probe for drives. */ sc->sc_wdcdev.sc_atac.atac_probe = wdc_sataprobe; + sc->sc_wdcdev.wdc_maxdrives = 1; wdc_allocate_regs(&sc->sc_wdcdev); diff --git a/sys/dev/pci/toshide.c b/sys/dev/pci/toshide.c index 85937355d2f..100f4574810 100644 --- a/sys/dev/pci/toshide.c +++ b/sys/dev/pci/toshide.c @@ -1,4 +1,4 @@ -/* $NetBSD: toshide.c,v 1.8 2012/07/26 20:49:50 jakllsch Exp $ */ +/* $NetBSD: toshide.c,v 1.9 2012/07/31 15:50:37 bouyer Exp $ */ /*- * Copyright (c) 2009 The NetBSD Foundation, Inc. @@ -27,7 +27,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: toshide.c,v 1.8 2012/07/26 20:49:50 jakllsch Exp $"); +__KERNEL_RCSID(0, "$NetBSD: toshide.c,v 1.9 2012/07/31 15:50:37 bouyer Exp $"); #include #include @@ -141,6 +141,7 @@ piccolo_chip_map(struct pciide_softc *sc, const struct pci_attach_args *pa) sc->sc_wdcdev.sc_atac.atac_channels = sc->wdc_chanarray; sc->sc_wdcdev.sc_atac.atac_nchannels = 1; + sc->sc_wdcdev.wdc_maxdrives = 2; /* * XXX one for now. We'll figure out how to talk to the second channel * later, hopefully! Second interface config is via the @@ -183,13 +184,13 @@ piccolo_setup_channel(struct ata_channel *chp) drvp = &chp->ch_drive[drive]; /* If no drive, skip */ - if ((drvp->drive_flags & DRIVE) == 0) + if (drvp->drive_type == ATA_DRIVET_NONE) continue; - if (drvp->drive_flags & DRIVE_UDMA) { + if (drvp->drive_flags & ATA_DRIVE_UDMA) { /* use Ultra/DMA */ s = splbio(); - drvp->drive_flags &= ~DRIVE_DMA; + drvp->drive_flags &= ~ATA_DRIVE_DMA; splx(s); /* @@ -214,7 +215,7 @@ piccolo_setup_channel(struct ata_channel *chp) idedma_ctl |= IDEDMA_CTL_DRV_DMA(drive); } - else if (drvp->drive_flags & DRIVE_DMA) { + else if (drvp->drive_flags & ATA_DRIVE_DMA) { /* * Use Multiword DMA */ diff --git a/sys/dev/pci/viaide.c b/sys/dev/pci/viaide.c index c3cadec2abc..a215fab2da1 100644 --- a/sys/dev/pci/viaide.c +++ b/sys/dev/pci/viaide.c @@ -1,4 +1,4 @@ -/* $NetBSD: viaide.c,v 1.82 2012/07/26 20:49:50 jakllsch Exp $ */ +/* $NetBSD: viaide.c,v 1.83 2012/07/31 15:50:37 bouyer Exp $ */ /* * Copyright (c) 1999, 2000, 2001 Manuel Bouyer. @@ -26,7 +26,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: viaide.c,v 1.82 2012/07/26 20:49:50 jakllsch Exp $"); +__KERNEL_RCSID(0, "$NetBSD: viaide.c,v 1.83 2012/07/31 15:50:37 bouyer Exp $"); #include #include @@ -614,6 +614,7 @@ via_chip_map(struct pciide_softc *sc, const struct pci_attach_args *pa) sc->sc_wdcdev.sc_atac.atac_set_modes = via_setup_channel; sc->sc_wdcdev.sc_atac.atac_channels = sc->wdc_chanarray; sc->sc_wdcdev.sc_atac.atac_nchannels = PCIIDE_NUM_CHANNELS; + sc->sc_wdcdev.wdc_maxdrives = 2; if (PCI_CLASS(pa->pa_class) == PCI_CLASS_MASS_STORAGE && PCI_SUBCLASS(pa->pa_class) == PCI_SUBCLASS_MASS_STORAGE_RAID) @@ -743,19 +744,19 @@ via_setup_channel(struct ata_channel *chp) for (drive = 0; drive < 2; drive++) { drvp = &chp->ch_drive[drive]; /* If no drive, skip */ - if ((drvp->drive_flags & DRIVE) == 0) + if (drvp->drive_type == ATA_DRIVET_NONE) continue; /* add timing values, setup DMA if needed */ - if (((drvp->drive_flags & DRIVE_DMA) == 0 && - (drvp->drive_flags & DRIVE_UDMA) == 0)) { + if (((drvp->drive_flags & ATA_DRIVE_DMA) == 0 && + (drvp->drive_flags & ATA_DRIVE_UDMA) == 0)) { mode = drvp->PIO_mode; goto pio; } if ((atac->atac_cap & ATAC_CAP_UDMA) && - (drvp->drive_flags & DRIVE_UDMA)) { + (drvp->drive_flags & ATA_DRIVE_UDMA)) { /* use Ultra/DMA */ s = splbio(); - drvp->drive_flags &= ~DRIVE_DMA; + drvp->drive_flags &= ~ATA_DRIVE_DMA; splx(s); udmatim_reg |= APO_UDMA_EN(chp->ch_channel, drive) | APO_UDMA_EN_MTH(chp->ch_channel, drive); @@ -800,7 +801,7 @@ via_setup_channel(struct ata_channel *chp) } else { /* use Multiword DMA, but only if revision is OK */ s = splbio(); - drvp->drive_flags &= ~DRIVE_UDMA; + drvp->drive_flags &= ~ATA_DRIVE_UDMA; splx(s); #ifndef PCIIDE_AMD756_ENABLEDMA /* @@ -821,7 +822,7 @@ via_setup_channel(struct ata_channel *chp) chp->ch_channel, drive); mode = drvp->PIO_mode; s = splbio(); - drvp->drive_flags &= ~DRIVE_DMA; + drvp->drive_flags &= ~ATA_DRIVE_DMA; splx(s); goto pio; } @@ -891,6 +892,7 @@ via_sata_chip_map_common(struct pciide_softc *sc, sc->sc_wdcdev.sc_atac.atac_nchannels = PCIIDE_NUM_CHANNELS; sc->sc_wdcdev.sc_atac.atac_cap |= ATAC_CAP_DATA16 | ATAC_CAP_DATA32; sc->sc_wdcdev.sc_atac.atac_set_modes = sata_setup_channel; + sc->sc_wdcdev.wdc_maxdrives = 2; if (PCI_CLASS(pa->pa_class) == PCI_CLASS_MASS_STORAGE && PCI_SUBCLASS(pa->pa_class) == PCI_SUBCLASS_MASS_STORAGE_RAID) @@ -960,6 +962,8 @@ via_sata_chip_map(struct pciide_softc *sc, const struct pci_attach_args *pa, PCIIDE_INTERFACE_PCI(0) | PCIIDE_INTERFACE_PCI(1); } + sc->sc_wdcdev.sc_atac.atac_probe = wdc_sataprobe; + sc->sc_wdcdev.wdc_maxdrives = 1; for (channel = 0; channel < sc->sc_wdcdev.sc_atac.atac_nchannels; channel++) { cp = &sc->pciide_channels[channel]; @@ -993,7 +997,6 @@ via_sata_chip_map(struct pciide_softc *sc, const struct pci_attach_args *pa, wdc_cp->ch_channel); continue; } - sc->sc_wdcdev.sc_atac.atac_probe = wdc_sataprobe; pciide_mapchan(pa, cp, interface, pciide_pci_intr); } } @@ -1070,7 +1073,6 @@ via_vt6421_chansetup(struct pciide_softc *sc, int channel) cp->ata_channel.ch_atac = &sc->sc_wdcdev.sc_atac; cp->ata_channel.ch_queue = malloc(sizeof(struct ata_queue), M_DEVBUF, M_NOWAIT); - cp->ata_channel.ch_ndrive = 2; if (cp->ata_channel.ch_queue == NULL) { aprint_error("%s channel %d: " "can't allocate memory for command queue", @@ -1120,6 +1122,7 @@ via_sata_chip_map_new(struct pciide_softc *sc, sc->sc_wdcdev.sc_atac.atac_channels = sc->wdc_chanarray; sc->sc_wdcdev.sc_atac.atac_nchannels = 3; + sc->sc_wdcdev.wdc_maxdrives = 2; wdc_allocate_regs(&sc->sc_wdcdev); @@ -1148,7 +1151,6 @@ via_sata_chip_map_new(struct pciide_softc *sc, cp = &sc->pciide_channels[channel]; if (via_vt6421_chansetup(sc, channel) == 0) continue; - cp->ata_channel.ch_ndrive = 2; wdc_cp = &cp->ata_channel; wdr = CHAN_TO_WDC_REGS(wdc_cp); diff --git a/sys/dev/pcmcia/wdc_pcmcia.c b/sys/dev/pcmcia/wdc_pcmcia.c index 1ca2e2aef06..010979c9a04 100644 --- a/sys/dev/pcmcia/wdc_pcmcia.c +++ b/sys/dev/pcmcia/wdc_pcmcia.c @@ -1,4 +1,4 @@ -/* $NetBSD: wdc_pcmcia.c,v 1.122 2012/07/26 20:49:50 jakllsch Exp $ */ +/* $NetBSD: wdc_pcmcia.c,v 1.123 2012/07/31 15:50:37 bouyer Exp $ */ /*- * Copyright (c) 1998, 2003, 2004 The NetBSD Foundation, Inc. @@ -30,7 +30,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: wdc_pcmcia.c,v 1.122 2012/07/26 20:49:50 jakllsch Exp $"); +__KERNEL_RCSID(0, "$NetBSD: wdc_pcmcia.c,v 1.123 2012/07/31 15:50:37 bouyer Exp $"); #include #include @@ -299,7 +299,7 @@ wdc_pcmcia_attach(device_t parent, device_t self, void *aux) sc->ata_channel.ch_queue = &sc->wdc_chqueue; wdcp = pcmcia_product_lookup(pa, wdc_pcmcia_products, wdc_pcmcia_nproducts, sizeof(wdc_pcmcia_products[0]), NULL); - sc->ata_channel.ch_ndrive = wdcp ? wdcp->wdc_ndrive : 2; + sc->sc_wdcdev.wdc_maxdrives = wdcp ? wdcp->wdc_ndrive : 2; wdc_init_shadow_regs(&sc->ata_channel); error = wdc_pcmcia_enable(self, 1); @@ -404,7 +404,7 @@ wdc_pcmcia_datain_memory(struct ata_channel *chp, int flags, void *buf, size_t n; n = min(len, 1024); - if ((flags & DRIVE_CAP32) && (n & 3) == 0) + if ((flags & ATA_DRIVE_CAP32) && (n & 3) == 0) bus_space_read_region_stream_4(wdr->data32iot, wdr->data32ioh, 0, buf, n >> 2); else @@ -425,7 +425,7 @@ wdc_pcmcia_dataout_memory(struct ata_channel *chp, int flags, void *buf, size_t n; n = min(len, 1024); - if ((flags & DRIVE_CAP32) && (n & 3) == 0) + if ((flags & ATA_DRIVE_CAP32) && (n & 3) == 0) bus_space_write_region_stream_4(wdr->data32iot, wdr->data32ioh, 0, buf, n >> 2); else diff --git a/sys/dev/podulebus/dtide.c b/sys/dev/podulebus/dtide.c index 9bd9ca4940d..1d5347fb324 100644 --- a/sys/dev/podulebus/dtide.c +++ b/sys/dev/podulebus/dtide.c @@ -1,4 +1,4 @@ -/* $NetBSD: dtide.c,v 1.27 2012/07/26 20:49:51 jakllsch Exp $ */ +/* $NetBSD: dtide.c,v 1.28 2012/07/31 15:50:37 bouyer Exp $ */ /*- * Copyright (c) 2000, 2001 Ben Harris @@ -31,7 +31,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: dtide.c,v 1.27 2012/07/26 20:49:51 jakllsch Exp $"); +__KERNEL_RCSID(0, "$NetBSD: dtide.c,v 1.28 2012/07/31 15:50:37 bouyer Exp $"); #include @@ -93,6 +93,7 @@ dtide_attach(device_t parent, device_t self, void *aux) sc->sc_wdc.sc_atac.atac_pio_cap = 0; /* XXX correct? */ sc->sc_wdc.sc_atac.atac_nchannels = DTIDE_NCHANNELS; sc->sc_wdc.sc_atac.atac_channels = sc->sc_chp; + sc->sc_wdc.wdc_maxdrives = 2; sc->sc_magict = pa->pa_fast_t; bus_space_map(pa->pa_fast_t, pa->pa_fast_base + DTIDE_MAGICBASE, 0, 1, &sc->sc_magich); @@ -106,7 +107,6 @@ dtide_attach(device_t parent, device_t self, void *aux) wdr->cmd_iot = bst; wdr->ctl_iot = bst; ch->ch_queue = &sc->sc_chq[i]; - ch->ch_ndrive = 2; bus_space_map(pa->pa_fast_t, pa->pa_fast_base + dtide_cmdoffsets[i], 0, 8, &wdr->cmd_baseioh); diff --git a/sys/dev/podulebus/hcide.c b/sys/dev/podulebus/hcide.c index e0c07c20e04..0fe81feced1 100644 --- a/sys/dev/podulebus/hcide.c +++ b/sys/dev/podulebus/hcide.c @@ -1,4 +1,4 @@ -/* $NetBSD: hcide.c,v 1.24 2012/07/26 20:49:51 jakllsch Exp $ */ +/* $NetBSD: hcide.c,v 1.25 2012/07/31 15:50:37 bouyer Exp $ */ /*- * Copyright (c) 2000, 2001 Ben Harris @@ -31,7 +31,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: hcide.c,v 1.24 2012/07/26 20:49:51 jakllsch Exp $"); +__KERNEL_RCSID(0, "$NetBSD: hcide.c,v 1.25 2012/07/31 15:50:37 bouyer Exp $"); #include @@ -92,6 +92,7 @@ hcide_attach(device_t parent, device_t self, void *aux) sc->sc_wdc.sc_atac.atac_pio_cap = 0; /* XXX correct? */ sc->sc_wdc.sc_atac.atac_nchannels = HCIDE_NCHANNELS; sc->sc_wdc.sc_atac.atac_channels = sc->sc_chp; + sc->sc_wdc.wdc_maxdrives = 2; aprint_normal("\n"); for (i = 0; i < HCIDE_NCHANNELS; i++) { ch = sc->sc_chp[i] = &sc->sc_chan[i]; @@ -101,7 +102,6 @@ hcide_attach(device_t parent, device_t self, void *aux) wdr->cmd_iot = pa->pa_mod_t; wdr->ctl_iot = pa->pa_mod_t; ch->ch_queue = &sc->sc_chq[i]; - ch->ch_ndrive = 2; bus_space_map(pa->pa_fast_t, pa->pa_fast_base + hcide_cmdoffsets[i], 0, 8, &wdr->cmd_baseioh); diff --git a/sys/dev/scsipi/atapi_wdc.c b/sys/dev/scsipi/atapi_wdc.c index a037c1b8bab..f8179c479be 100644 --- a/sys/dev/scsipi/atapi_wdc.c +++ b/sys/dev/scsipi/atapi_wdc.c @@ -1,4 +1,4 @@ -/* $NetBSD: atapi_wdc.c,v 1.117 2012/07/26 20:49:51 jakllsch Exp $ */ +/* $NetBSD: atapi_wdc.c,v 1.118 2012/07/31 15:50:37 bouyer Exp $ */ /* * Copyright (c) 1998, 2001 Manuel Bouyer. @@ -25,7 +25,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: atapi_wdc.c,v 1.117 2012/07/26 20:49:51 jakllsch Exp $"); +__KERNEL_RCSID(0, "$NetBSD: atapi_wdc.c,v 1.118 2012/07/31 15:50:37 bouyer Exp $"); #ifndef ATADEBUG #define ATADEBUG @@ -199,7 +199,7 @@ wdc_atapi_get_params(struct scsipi_channel *chan, int drive, struct ata_command ata_c; /* if no ATAPI device detected at wdc attach time, skip */ - if ((chp->ch_drive[drive].drive_flags & DRIVE_ATAPI) == 0) { + if (chp->ch_drive[drive].drive_type != ATA_DRIVET_ATAPI) { ATADEBUG_PRINT(("wdc_atapi_get_params: drive %d not present\n", drive), DEBUG_PROBE); return -1; @@ -290,7 +290,7 @@ wdc_atapi_probe_device(struct atapibus_softc *sc, int target) periph->periph_flags |= PERIPH_REMOVABLE; if (periph->periph_type == T_SEQUENTIAL) { s = splbio(); - drvp->drive_flags |= DRIVE_ATAPIST; + drvp->drive_flags |= ATA_DRIVE_ATAPIDSCW; splx(s); } @@ -321,12 +321,12 @@ wdc_atapi_probe_device(struct atapibus_softc *sc, int target) ata_probe_caps(drvp); else { s = splbio(); - drvp->drive_flags &= ~DRIVE_ATAPI; + drvp->drive_type = ATA_DRIVET_NONE; splx(s); } } else { s = splbio(); - drvp->drive_flags &= ~DRIVE_ATAPI; + drvp->drive_type = ATA_DRIVET_NONE; splx(s); } } @@ -370,7 +370,7 @@ wdc_atapi_scsipi_request(struct scsipi_channel *chan, scsipi_adapter_req_t req, xfer->c_flags |= C_POLL; #if NATA_DMA if ((atac->atac_channels[channel]->ch_drive[drive].drive_flags & - (DRIVE_DMA | DRIVE_UDMA)) && sc_xfer->datalen > 0) + (ATA_DRIVE_DMA | ATA_DRIVE_UDMA)) && sc_xfer->datalen > 0) xfer->c_flags |= C_DMA; #endif #if NATA_DMA && NATA_PIOBM @@ -486,7 +486,7 @@ wdc_atapi_start(struct ata_channel *chp, struct ata_xfer *xfer) if (atac->atac_set_modes == NULL) goto ready; /* Also don't try if the drive didn't report its mode */ - if ((drvp->drive_flags & DRIVE_MODE) == 0) + if ((drvp->drive_flags & ATA_DRIVE_MODE) == 0) goto ready; errstring = "unbusy"; if (wdc_wait_for_unbusy(chp, ATAPI_DELAY, wait_flags)) @@ -515,12 +515,12 @@ wdc_atapi_start(struct ata_channel *chp, struct ata_xfer *xfer) } #if NATA_DMA #if NATA_UDMA - if (drvp->drive_flags & DRIVE_UDMA) { + if (drvp->drive_flags & ATA_DRIVE_UDMA) { wdccommand(chp, drvp->drive, SET_FEATURES, 0, 0, 0, 0x40 | drvp->UDMA_mode, WDSF_SET_MODE); } else #endif - if (drvp->drive_flags & DRIVE_DMA) { + if (drvp->drive_flags & ATA_DRIVE_DMA) { wdccommand(chp, drvp->drive, SET_FEATURES, 0, 0, 0, 0x20 | drvp->DMA_mode, WDSF_SET_MODE); } else { @@ -532,7 +532,7 @@ wdc_atapi_start(struct ata_channel *chp, struct ata_xfer *xfer) if (chp->ch_status & WDCS_ERR) { if (chp->ch_error == WDCE_ABRT) { #if NATA_UDMA - if (drvp->drive_flags & DRIVE_UDMA) + if (drvp->drive_flags & ATA_DRIVE_UDMA) goto error; else #endif @@ -995,7 +995,7 @@ wdc_atapi_phase_complete(struct ata_xfer *xfer) struct ata_drive_datas *drvp = &chp->ch_drive[xfer->c_drive]; /* wait for DSC if needed */ - if (drvp->drive_flags & DRIVE_ATAPIST) { + if (drvp->drive_flags & ATA_DRIVE_ATAPIDSCW) { ATADEBUG_PRINT(("wdc_atapi_phase_complete(%s:%d:%d) " "polldsc %d\n", device_xname(atac->atac_dev), chp->ch_channel, @@ -1085,9 +1085,9 @@ wdc_atapi_done(struct ata_channel *chp, struct ata_xfer *xfer) chp->ch_queue->active_xfer = NULL; ata_free_xfer(chp, xfer); - if (chp->ch_drive[drive].drive_flags & DRIVE_WAITDRAIN) { + if (chp->ch_drive[drive].drive_flags & ATA_DRIVE_WAITDRAIN) { sc_xfer->error = XS_DRIVER_STUFFUP; - chp->ch_drive[drive].drive_flags &= ~DRIVE_WAITDRAIN; + chp->ch_drive[drive].drive_flags &= ~ATA_DRIVE_WAITDRAIN; wakeup(&chp->ch_queue->active_xfer); } diff --git a/sys/dev/usb/umass_isdata.c b/sys/dev/usb/umass_isdata.c index ab735f56e6c..e582e16d03a 100644 --- a/sys/dev/usb/umass_isdata.c +++ b/sys/dev/usb/umass_isdata.c @@ -1,4 +1,4 @@ -/* $NetBSD: umass_isdata.c,v 1.26 2012/07/26 20:49:51 jakllsch Exp $ */ +/* $NetBSD: umass_isdata.c,v 1.27 2012/07/31 15:50:37 bouyer Exp $ */ /* * TODO: @@ -37,7 +37,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: umass_isdata.c,v 1.26 2012/07/26 20:49:51 jakllsch Exp $"); +__KERNEL_RCSID(0, "$NetBSD: umass_isdata.c,v 1.27 2012/07/31 15:50:37 bouyer Exp $"); #ifdef _KERNEL_OPT #include "opt_umass.h" @@ -110,7 +110,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_drive(struct ata_drive_datas *, int); +void uisdata_reset_drive(struct ata_drive_datas *, int, uint32_t *); void uisdata_reset_channel(struct ata_channel *, int); int uisdata_exec_command(struct ata_drive_datas *, struct ata_command *); int uisdata_get_params(struct ata_drive_datas *, u_int8_t, struct ataparams *); @@ -215,7 +215,7 @@ umass_isdata_attach(struct umass_softc *sc) adev.adev_channel = 1; /* XXX */ adev.adev_openings = 1; adev.adev_drv_data = &scbus->sc_drv_data; - scbus->sc_drv_data.drive_flags = DRIVE_ATA; + scbus->sc_drv_data.drive_type = ATA_DRIVET_ATA; scbus->sc_drv_data.chnl_softc = sc; scbus->base.sc_child = config_found(sc->sc_dev, &adev, uwdprint); @@ -376,9 +376,10 @@ uisdata_bio1(struct ata_drive_datas *drv, struct ata_bio *ata_bio) } void -uisdata_reset_drive(struct ata_drive_datas *drv, int flags) +uisdata_reset_drive(struct ata_drive_datas *drv, int flags, uint32_t *sigp) { DPRINTFN(-1,("%s\n", __func__)); + KASSERT(sigp == NULL); /* XXX what? */ } -- cgit