diff options
| author | bouyer <bouyer@NetBSD.org> | 2012-07-02 18:15:44 +0000 |
|---|---|---|
| committer | bouyer <bouyer@NetBSD.org> | 2012-07-02 18:15:44 +0000 |
| commit | e71c312b36758c88cddf238ea7a428e0d0b5b282 (patch) | |
| tree | 30524ef2398f3971778b2857026dbec86ff3e6f5 /sys/dev | |
| parent | 70ef220e99b4b94d8d10af02c721ba7818e4d663 (diff) | |
Add sata Port MultiPlier (PMP) support to the ata bus layer,
as described in
http://mail-index.netbsd.org/tech-kern/2012/06/23/msg013442.html
PMP support in integrated to the atabus layer.
struct ata_channel's ch_drive[] is not dynamically allocated, and ch_ndrive
(renamed to ch_ndrives) closely reflects the size of the ch_drive[] array.
Add helper functions atabus_alloc_drives() and atabus_free_drives()
to manage ch_drive[]/ch_ndrives.
Add wdc_maxdrives to struct wdc_softc so that bus front-end can specify
how much drive they really support (master/slave or single).
ata_reset_drive() callback gains a uint32_t *sigp argument which,
when not NULL, will contain the signature of the device being reset.
While there, some cosmetic changes:
- added a drive_type enum to ata_drive_datas, and stop encoding the
probed drive type in drive_flags (we were out of drive flags anyway).
- rename DRIVE_ATAPIST to DRIVE_ATAPIDSCW to better reflect what this
really is
- remove ata_channel->ata_drives, it's redundant with the pointer in
ata_drive_datas
- factor out the interpretation of SATA signatures in sata_interpet_sig()
propagate these changes to the ATA HBA drivers, and add support for PMP
to ahcisata(4) and siisata(4).
Thanks to:
- Protocase (http://www.protocase.com/) which provided a system
with lots of controllers, SATA PMP and drive slots
- Conservation Genomics Laboratory, Department of Biology, New Mexico State
University for hosting the above system
- Brook Milligan, who set up remote access and has been very responsive
when SATA cable move was needed
Diffstat (limited to 'sys/dev')
53 files changed, 1158 insertions, 482 deletions
diff --git a/sys/dev/ata/ata.c b/sys/dev/ata/ata.c index 8fbb91b170c..90205cc4fa7 100644 --- a/sys/dev/ata/ata.c +++ b/sys/dev/ata/ata.c @@ -1,4 +1,4 @@ -/* $NetBSD: ata.c,v 1.116 2012/04/06 02:52:00 isaki Exp $ */ +/* $NetBSD: ata.c,v 1.117 2012/07/02 18:15:46 bouyer Exp $ */ /* * Copyright (c) 1998, 2001 Manuel Bouyer. All rights reserved. @@ -25,7 +25,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: ata.c,v 1.116 2012/04/06 02:52:00 isaki Exp $"); +__KERNEL_RCSID(0, "$NetBSD: ata.c,v 1.117 2012/07/02 18:15:46 bouyer Exp $"); #include "opt_ata.h" @@ -55,10 +55,15 @@ __KERNEL_RCSID(0, "$NetBSD: ata.c,v 1.116 2012/04/06 02:52:00 isaki Exp $"); #include "atapibus.h" #include "ataraid.h" +#include "sata_pmp.h" #if NATARAID > 0 #include <dev/ata/ata_raidvar.h> #endif +#if NSATA_PMP > 0 +#include <dev/ata/satapmpvar.h> +#endif +#include <dev/ata/satapmpreg.h> #define DEBUG_FUNCS 0x08 #define DEBUG_PROBE 0x10 @@ -199,12 +204,16 @@ 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), + 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 */ @@ -223,17 +232,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 != 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) @@ -274,10 +285,25 @@ atabusconfig_thread(void *arg) 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 == 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 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 == DRIVET_ATAPI) { #if NATAPIBUS > 0 (*atac->atac_atapibus_attach)(atabus_sc); #else @@ -288,33 +314,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 == DRIVET_ATAPI) + chp->ch_drive[i].drive_type = 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 != DRIVET_ATA && + chp->ch_drive[i].drive_type != 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]; - chp->ata_drives[i] = config_found_ia(atabus_sc->sc_dev, + chp->ch_drive[i].drv_softc = config_found_ia(atabus_sc->sc_dev, "ata_hl", &adev, ataprint); - if (chp->ata_drives[i] != 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 = DRIVET_NONE; splx(s); } } @@ -325,10 +354,14 @@ atabusconfig_thread(void *arg) ata_print_modes(chp); } #if NATARAID > 0 - if (atac->atac_cap & ATAC_CAP_RAID) - for (i = 0; i < chp->ch_ndrive; i++) - if (chp->ata_drives[i] != NULL) - ata_raid_check_component(chp->ata_drives[i]); + if (atac->atac_cap & ATAC_CAP_RAID) { + for (i = 0; i < chp->ch_ndrives; i++) { + if (chp->ch_drive[i].drive_type == DRIVET_ATA) { + ata_raid_check_component( + chp->ch_drive[i].drv_softc); + } + } + } #endif /* NATARAID > 0 */ /* @@ -336,10 +369,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 == 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 = DRIVET_NONE; + } else chp->ch_drive[i].state = 0; } splx(s); @@ -374,13 +410,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 = DRIVET_NONE; + } splx(s); atabusconfig(sc); @@ -522,24 +561,28 @@ 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 == DRIVET_ATAPI) continue; - if ((dev = chp->ata_drives[i]) != NULL) { + if (chp->ch_drive[i].drive_type == DRIVET_PM) + chp->ch_drive[i].drive_type = 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)), DEBUG_DETACH); - KASSERT(chp->ch_drive[i].drv_softc == - chp->ata_drives[i]); error = config_detach(dev, flags); if (error) goto out; - KASSERT(chp->ata_drives[i] == NULL); + KASSERT(chp->ch_drive[i].drv_softc == NULL); + KASSERT(chp->ch_drive[i].drive_type == 0); } } + atabus_free_drives(chp); out: #ifdef ATADEBUG @@ -560,26 +603,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 != 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 = 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 == DRIVET_ATAPI) continue; - if (child == chp->ata_drives[i]) { - KASSERT(chp->ata_drives[i] == - chp->ch_drive[i].drv_softc); - chp->ata_drives[i] = NULL; + 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 == DRIVET_PM) + chp->ch_satapmp_nports = 0; + chp->ch_drive[i].drive_type = DRIVET_NONE; found = true; } } @@ -597,6 +649,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 != DRIVET_NONE) { + printf("%s: ch_drive[%d] type %d != 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, @@ -615,12 +725,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 == 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 == DRIVET_ATAPI) { ata_c.r_command = ATAPI_IDENTIFY_DEVICE; ata_c.r_st_bmask = 0; ata_c.r_st_pmask = WDCS_DRQ; @@ -671,7 +781,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 == DRIVET_ATAPI) ? ((M(0) == 'N' && M(1) == 'E') || (M(0) == 'F' && M(1) == 'X') || (M(0) == 'P' && M(1) == 'i')) : @@ -1009,7 +1119,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; @@ -1063,9 +1174,11 @@ 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 == DRIVET_NONE || + drvp->drv_softc == NULL) continue; aprint_verbose("%s(%s:%d:%d): using PIO mode %d", device_xname(drvp->drv_softc), @@ -1215,7 +1328,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 == DRIVET_ATAPI) drvp->PIO_mode = 3; /* @@ -1354,7 +1467,7 @@ ata_probe_caps(struct ata_drive_datas *drvp) s = splbio(); drvp->drive_flags &= ~DRIVE_NOSTREAM; - if (drvp->drive_flags & DRIVE_ATAPI) { + if (drvp->drive_type == DRIVET_ATAPI) { if (atac->atac_cap & ATAC_CAP_ATAPI_NOSTREAM) drvp->drive_flags |= DRIVE_NOSTREAM; } else { @@ -1490,8 +1603,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 == DRIVET_OLD) || + (chp->ch_drive[1].drive_type == DRIVET_OLD)) return (EOPNOTSUPP); return (EOPNOTSUPP); } @@ -1499,8 +1612,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 == DRIVET_OLD) || + (chp->ch_drive[1].drive_type == DRIVET_OLD)) return (EOPNOTSUPP); switch (a->at_dev) { case -1: @@ -1573,23 +1686,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->ata_drives[i] != 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 5cc3d474dfe..3418679f6ef 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.96 2012/01/09 01:01:48 jakllsch Exp $ */ +/* $NetBSD: ata_wdc.c,v 1.97 2012/07/02 18:15:46 bouyer Exp $ */ /* * Copyright (c) 1998, 2001, 2003 Manuel Bouyer. @@ -54,7 +54,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: ata_wdc.c,v 1.96 2012/01/09 01:01:48 jakllsch Exp $"); +__KERNEL_RCSID(0, "$NetBSD: ata_wdc.c,v 1.97 2012/07/02 18:15:46 bouyer Exp $"); #include "opt_ata.h" #include "opt_wdc.h" @@ -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. */ @@ -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); } diff --git a/sys/dev/ata/atavar.h b/sys/dev/ata/atavar.h index 21df35baba0..7d94a24b7c1 100644 --- a/sys/dev/ata/atavar.h +++ b/sys/dev/ata/atavar.h @@ -1,4 +1,4 @@ -/* $NetBSD: atavar.h,v 1.84 2012/01/24 20:04:07 jakllsch Exp $ */ +/* $NetBSD: atavar.h,v 1.85 2012/07/02 18:15:46 bouyer Exp $ */ /* * Copyright (c) 1998, 2001 Manuel Bouyer. @@ -37,11 +37,6 @@ #include <dev/scsipi/atapiconf.h> /* - * 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. */ @@ -113,22 +108,24 @@ struct ataparams; /* Datas common to drives and controller drivers */ struct ata_drive_datas { + enum { + DRIVET_NONE = 0, + DRIVET_ATA, + DRIVET_ATAPI, + DRIVET_OLD, + DRIVET_PM, + } drive_type; 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 DRIVE_CAP32 0x0001 +#define DRIVE_DMA 0x0002 +#define DRIVE_UDMA 0x0004 +#define DRIVE_MODE 0x0008 /* the drive reported its mode */ +#define DRIVE_RESET 0x0010 /* reset the drive state at next xfer */ +#define DRIVE_WAITDRAIN 0x0020 /* device is waiting for the queue to drain */ +#define DRIVE_NOSTREAM 0x0040 /* no stream methods on this drive */ +#define DRIVE_ATAPIDSCW 0x0080 /* needs to wait for DSC in phase_complete */ /* * 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 */ @@ -356,9 +353,6 @@ struct ata_channel { device_t atapibus; struct scsipi_channel ch_atapi_channel; - /* ATA children */ - device_t ata_drives[ATA_MAXDRIVES]; - /* * Channel queues. May be the same for all channels, if hw * channels are not independent. @@ -367,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; }; /* @@ -434,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 343a10fdf8f..0aa6a52d79a 100644 --- a/sys/dev/ata/files.ata +++ b/sys/dev/ata/files.ata @@ -1,4 +1,4 @@ -# $NetBSD: files.ata,v 1.21 2009/06/17 03:07:51 jakllsch Exp $ +# $NetBSD: files.ata,v 1.22 2012/07/02 18:15:46 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 fb43d1c4c1c..148d2d2f5d4 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.15 2012/05/15 19:01:10 bouyer Exp $ */ +/* $NetBSD: sata_subr.c,v 1.16 2012/07/02 18:15:46 bouyer Exp $ */ /*- * Copyright (c) 2004 The NetBSD Foundation, Inc. @@ -33,7 +33,7 @@ * Common functions for Serial ATA. */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: sata_subr.c,v 1.15 2012/05/15 19:01:10 bouyer Exp $"); +__KERNEL_RCSID(0, "$NetBSD: sata_subr.c,v 1.16 2012/07/02 18:15:46 bouyer Exp $"); #include <sys/param.h> #include <sys/kernel.h> @@ -41,6 +41,7 @@ __KERNEL_RCSID(0, "$NetBSD: sata_subr.c,v 1.15 2012/05/15 19:01:10 bouyer Exp $" #include <dev/ata/satareg.h> #include <dev/ata/satavar.h> +#include <dev/ata/satapmpreg.h> /* * 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 = 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 = DRIVET_ATAPI; + break; + case 0x00000101: + chp->ch_drive[port].drive_type = DRIVET_ATA; + break; + case 0xffffffff: + /* COMRESET time out */ + break; + default: + chp->ch_drive[port].drive_type = 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/satapmp_subr.c b/sys/dev/ata/satapmp_subr.c new file mode 100644 index 00000000000..d94c4be42a8 --- /dev/null +++ b/sys/dev/ata/satapmp_subr.c @@ -0,0 +1,251 @@ +/* $NetBSD: satapmp_subr.c,v 1.1 2012/07/02 18:15:46 bouyer Exp $ */ + +/* + * Copyright (c) 2012 Manuel Bouyer. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include <sys/cdefs.h> +__KERNEL_RCSID(0, "$NetBSD: satapmp_subr.c,v 1.1 2012/07/02 18:15:46 bouyer Exp $"); + +#include <sys/param.h> +#include <sys/systm.h> +#include <sys/kernel.h> +#include <sys/device.h> +#include <sys/conf.h> +#include <sys/fcntl.h> +#include <sys/proc.h> +#include <sys/errno.h> +#include <sys/kmem.h> +#include <sys/intr.h> + +#include <dev/ata/ataconf.h> +#include <dev/ata/atareg.h> +#include <dev/ata/atavar.h> + +#include <dev/ata/satapmpvar.h> +#include <dev/ata/satapmpreg.h> +#include <dev/ata/satavar.h> +#include <dev/ata/satareg.h> + +static int +satapmp_read(struct ata_channel *chp, int port, int reg, uint32_t *value) +{ + struct ata_command ata_c; + struct atac_softc *atac = chp->ch_atac; + struct ata_drive_datas *drvp; + + KASSERT(reg < PMP_GSCR_NREGS); + KASSERT(chp->ch_ndrives >= PMP_MAX_DRIVES); + drvp = &chp->ch_drive[PMP_PORT_CTL]; + KASSERT(drvp->drive == PMP_PORT_CTL); + + memset(&ata_c, 0, sizeof(struct ata_command)); + + ata_c.r_command = PMPC_READ_PORT; + ata_c.r_features = reg; + ata_c.r_lba = (port & 0xf) << 24; + ata_c.timeout = 3000; /* 3s */ + ata_c.r_st_bmask = WDCS_DRDY; + ata_c.r_st_pmask = 0; + ata_c.flags = AT_READREG | AT_WAIT; + + if ((*atac->atac_bustype_ata->ata_exec_command)(drvp, + &ata_c) != ATACMD_COMPLETE) { + aprint_error_dev(chp->atabus, + "PMP register %d read failed\n", reg); + return EIO; + } + if (ata_c.flags & (AT_TIMEOU | AT_DF)) { + aprint_error_dev(chp->atabus, + "PMP register %d read failed, flags 0x%x\n", + reg, ata_c.flags); + return EIO; + } + if (ata_c.flags & AT_ERROR) { + aprint_verbose_dev(chp->atabus, + "PMP register %d read failed, error 0x%x\n", + reg, ata_c.r_error); + return EIO; + } + *value = ata_c.r_lba << 8 | ata_c.r_count; + return 0; +} + +static int satapmp_write(struct ata_channel *chp, int, int, uint32_t) __unused; +static int +satapmp_write(struct ata_channel *chp, int port, int reg, uint32_t value) +{ + struct ata_command ata_c; + struct atac_softc *atac = chp->ch_atac; + struct ata_drive_datas *drvp; + + KASSERT(reg < PMP_GSCR_NREGS); + KASSERT(chp->ch_ndrives >= PMP_MAX_DRIVES); + drvp = &chp->ch_drive[PMP_PORT_CTL]; + KASSERT(drvp->drive == PMP_PORT_CTL); + + + memset(&ata_c, 0, sizeof(struct ata_command)); + + ata_c.r_command = PMPC_WRITE_PORT; + ata_c.r_features = reg; + ata_c.r_lba = (port & 0xf) << 24; + ata_c.r_lba |= (value & 0xffffff00) >> 8; + ata_c.r_count = value & 0xff; + ata_c.timeout = 3000; /* 3s */ + ata_c.r_st_bmask = WDCS_DRDY; + ata_c.r_st_pmask = 0; + ata_c.flags = AT_WAIT; + + if ((*atac->atac_bustype_ata->ata_exec_command)(drvp, + &ata_c) != ATACMD_COMPLETE) { + aprint_error_dev(chp->atabus, + "PMP register %d write failed\n", reg); + return EIO; + } + if (ata_c.flags & (AT_TIMEOU | AT_DF)) { + aprint_error_dev(chp->atabus, + "PMP register %d write failed, flags 0x%x\n", + reg, ata_c.flags); + return EIO; + } + if (ata_c.flags & AT_ERROR) { + aprint_verbose_dev(chp->atabus, + "PMP register %d write failed, error 0x%x\n", + reg, ata_c.r_error); + return EIO; + } + return 0; +} + +/* + * Reset one port's PHY and bring it online + * XXX duplicate of sata_reset_interface() + */ +static uint32_t +satapmp_reset_device_port(struct ata_channel *chp, int port) +{ + uint32_t scontrol, sstatus; + int i; + + /* bring the PHY online */ + scontrol = SControl_IPM_NONE | SControl_SPD_ANY | SControl_DET_INIT; + if (satapmp_write(chp, port, PMP_PSCR_SControl, scontrol) != 0) + return 0; + + tsleep(chp, PRIBIO, "sataup", mstohz(50)); + scontrol &= ~SControl_DET_INIT; + if (satapmp_write(chp, port, PMP_PSCR_SControl, scontrol) != 0) + return 0; + tsleep(chp, PRIBIO, "sataup", mstohz(50)); + + /* wait up to 1s for device to come up */ + for (i = 0; i < 100; i++) { + + if (satapmp_read(chp, port, PMP_PSCR_SStatus, &sstatus) != 0) + return 0; + if ((sstatus & SStatus_DET_mask) == SStatus_DET_DEV) + break; + tsleep(chp, PRIBIO, "sataup", mstohz(10)); + } + + switch (sstatus & SStatus_DET_mask) { + case SStatus_DET_NODEV: + /* No Device; be silent. */ + break; + case SStatus_DET_DEV_NE: + aprint_error("%s PMP port %d: device connected, but " + "communication not established\n", + device_xname(chp->atabus), port); + break; + case SStatus_DET_OFFLINE: + aprint_error("%s PMP port %d: PHY offline\n", + device_xname(chp->atabus), port); + break; + case SStatus_DET_DEV: + aprint_normal("%s PMP port %d: device present, speed: %s\n", + device_xname(chp->atabus), port, sata_speed(sstatus)); + break; + default: + aprint_error("%s PMP port %d: unknown SStatus: 0x%08x\n", + device_xname(chp->atabus), port, sstatus); + } + return(sstatus & SStatus_DET_mask); +} + +void +satapmp_rescan(struct ata_channel *chp) { + int i; + uint32_t sig; + + KASSERT(chp->ch_satapmp_nports <= PMP_PORT_CTL); + KASSERT(chp->ch_satapmp_nports <= chp->ch_ndrives); + + for (i = 0; i < chp->ch_satapmp_nports; i++) { + if (chp->ch_drive[i].drive_type != DRIVET_NONE || + satapmp_reset_device_port(chp, i) != SStatus_DET_DEV) { + continue; + } + if (satapmp_write(chp, i, PMP_PSCR_SError, 0xffffffff) != 0) { + aprint_error("%s PMP port %d: can't write SError\n", + device_xname(chp->atabus), i); + continue; + } + chp->ch_atac->atac_bustype_ata->ata_reset_drive( + &chp->ch_drive[i], AT_WAIT, &sig); + + sata_interpret_sig(chp, i, sig); + } +} + +void +satapmp_attach(struct ata_channel *chp) +{ + uint32_t id, rev, inf; + + if (satapmp_read(chp, PMP_PORT_CTL, PMP_GSCR_ID, &id) != 0 || + satapmp_read(chp, PMP_PORT_CTL, PMP_GSCR_REV, &rev) != 0 || + satapmp_read(chp, PMP_PORT_CTL, PMP_GSCR_INF, &inf) != 0) { + aprint_normal_dev(chp->atabus, "can't read PMP registers\n"); + return; + } + + aprint_normal_dev(chp->atabus, + "SATA port multiplier, %d ports\n", PMP_INF_NPORTS(inf)); + aprint_verbose_dev(chp->atabus, + "vendor 0x%x, product 0x%x", + PMP_ID_VEND(id), PMP_ID_DEV(id)); + if (rev & PMP_REV_SPEC_11) { + aprint_verbose(", revision 1.1"); + } else if (rev & PMP_REV_SPEC_10) { + aprint_verbose(", revision 1.0"); + } else { + aprint_verbose(", unknown revision 0x%x", rev & 0x0f); + } + aprint_verbose(", level %d\n", PMP_REV_LEVEL(rev)); + + chp->ch_satapmp_nports = PMP_INF_NPORTS(inf); + + /* reset and bring up PHYs */ + satapmp_rescan(chp); +} diff --git a/sys/dev/ata/satapmpreg.h b/sys/dev/ata/satapmpreg.h index 9404861125f..8d732c57bfb 100644 --- a/sys/dev/ata/satapmpreg.h +++ b/sys/dev/ata/satapmpreg.h @@ -1,4 +1,4 @@ -/* $NetBSD: satapmpreg.h,v 1.3 2008/04/28 20:23:47 martin Exp $ */ +/* $NetBSD: satapmpreg.h,v 1.4 2012/07/02 18:15:46 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/satapmpvar.h b/sys/dev/ata/satapmpvar.h new file mode 100644 index 00000000000..f2031d59744 --- /dev/null +++ b/sys/dev/ata/satapmpvar.h @@ -0,0 +1,35 @@ +/* $NetBSD: satapmpvar.h,v 1.1 2012/07/02 18:15:46 bouyer Exp $ */ + + +/* + * Copyright (c) 2012 Manuel Bouyer. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef _DEV_ATA_SATAPMPVAR_H_ +#define _DEV_ATA_SATAPMPVAR_H_ + +void satapmp_attach(struct ata_channel *); +void satapmp_rescan(struct ata_channel *); + +#endif /* _DEV_ATA_SATAPMPVAR_H_ */ + diff --git a/sys/dev/ata/satavar.h b/sys/dev/ata/satavar.h index 0e86f6668cf..526b9542190 100644 --- a/sys/dev/ata/satavar.h +++ b/sys/dev/ata/satavar.h @@ -1,4 +1,4 @@ -/* $NetBSD: satavar.h,v 1.5 2008/04/28 20:23:47 martin Exp $ */ +/* $NetBSD: satavar.h,v 1.6 2012/07/02 18:15:46 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 29a695cbaef..46f26e90af2 100644 --- a/sys/dev/ata/wd.c +++ b/sys/dev/ata/wd.c @@ -1,4 +1,4 @@ -/* $NetBSD: wd.c,v 1.393 2012/06/26 09:49:24 bouyer Exp $ */ +/* $NetBSD: wd.c,v 1.394 2012/07/02 18:15:46 bouyer Exp $ */ /* * Copyright (c) 1998, 2001 Manuel Bouyer. All rights reserved. @@ -54,7 +54,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: wd.c,v 1.393 2012/06/26 09:49:24 bouyer Exp $"); +__KERNEL_RCSID(0, "$NetBSD: wd.c,v 1.394 2012/07/02 18:15:46 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 = 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); } @@ -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 != 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 67c03b1d42e..bb0a55f3c74 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.34 2012/04/20 20:23:20 bouyer Exp $ */ +/* $NetBSD: ahcisata_core.c,v 1.35 2012/07/02 18:15:46 bouyer Exp $ */ /* * Copyright (c) 2006 Manuel Bouyer. @@ -26,7 +26,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: ahcisata_core.c,v 1.34 2012/04/20 20:23:20 bouyer Exp $"); +__KERNEL_RCSID(0, "$NetBSD: ahcisata_core.c,v 1.35 2012/07/02 18:15:46 bouyer Exp $"); #include <sys/types.h> #include <sys/malloc.h> @@ -42,21 +42,25 @@ __KERNEL_RCSID(0, "$NetBSD: ahcisata_core.c,v 1.34 2012/04/20 20:23:20 bouyer Ex #include <dev/ata/satareg.h> #include <dev/ata/satafisvar.h> #include <dev/ata/satafisreg.h> +#include <dev/ata/satapmpreg.h> #include <dev/ic/ahcisatavar.h> +#include <dev/ic/wdcreg.h> #include <dev/scsipi/scsi_all.h> /* 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,167 @@ 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_SPM | AHCI_CAP_CLO)) == + (AHCI_CAP_SPM | 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 <AHCI_RST_WAIT; i++) { + sig = AHCI_READ(sc, AHCI_P_TFD(chp->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 +754,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 <AHCI_RST_WAIT; i++) { tfd = AHCI_READ(sc, AHCI_P_TFD(chp->ch_channel)); @@ -634,15 +797,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 +808,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 <AHCI_RST_WAIT; i++) { - sig = AHCI_READ(sc, AHCI_P_TFD(chp->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 == 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 +914,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 +930,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); @@ -999,6 +1136,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 +1150,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); @@ -1164,7 +1302,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 +1314,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 == DRIVET_PM) { + p_cmd |= AHCI_P_CMD_PMA; + } + AHCI_WRITE(sc, AHCI_P_CMD(chp->ch_channel), p_cmd); } static void @@ -1378,6 +1544,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 +1561,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); @@ -1545,7 +1713,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 != DRIVET_ATAPI) { AHCIDEBUG_PRINT(("ahci_atapi_probe_device: drive %d " "not present\n", target), DEBUG_PROBE); return; @@ -1584,7 +1752,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 |= DRIVE_ATAPIDSCW; splx(s); } @@ -1615,7 +1783,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 = DRIVET_NONE; splx(s); } } else { @@ -1624,7 +1792,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 = DRIVET_NONE; splx(s); } } diff --git a/sys/dev/ic/ahcisatavar.h b/sys/dev/ic/ahcisatavar.h index 94473ad5554..c9a766e175b 100644 --- a/sys/dev/ic/ahcisatavar.h +++ b/sys/dev/ic/ahcisatavar.h @@ -1,4 +1,4 @@ -/* $NetBSD: ahcisatavar.h,v 1.7 2010/07/27 22:07:50 jakllsch Exp $ */ +/* $NetBSD: ahcisatavar.h,v 1.8 2012/07/02 18:15:46 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 32434b2780e..4a47b0de8d1 100644 --- a/sys/dev/ic/mvsata.c +++ b/sys/dev/ic/mvsata.c @@ -1,4 +1,4 @@ -/* $NetBSD: mvsata.c,v 1.16 2012/04/20 20:23:20 bouyer Exp $ */ +/* $NetBSD: mvsata.c,v 1.17 2012/07/02 18:15:46 bouyer Exp $ */ /* * Copyright (c) 2008 KIYOHARA Takashi * All rights reserved. @@ -26,7 +26,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: mvsata.c,v 1.16 2012/04/20 20:23:20 bouyer Exp $"); +__KERNEL_RCSID(0, "$NetBSD: mvsata.c,v 1.17 2012/07/02 18:15:46 bouyer Exp $"); #include "opt_mvsata.h" @@ -103,7 +103,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 +304,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; @@ -519,12 +520,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 +792,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 != 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 +833,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 |= DRIVE_ATAPIDSCW; splx(s); } @@ -860,7 +863,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 = DRIVET_NONE; splx(s); } } else { @@ -869,7 +872,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 = DRIVET_NONE; splx(s); } } @@ -918,11 +921,11 @@ 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 == DRIVET_NONE) continue; if (drvp->drive_flags & DRIVE_UDMA) { @@ -933,7 +936,7 @@ mvsata_setup_channel(struct ata_channel *chp) } if (drvp->drive_flags & (DRIVE_UDMA | DRIVE_DMA)) - if (drvp->drive_flags & DRIVE_ATA) + if (drvp->drive_type == DRIVET_ATA) edma_mode = dma; } @@ -978,11 +981,11 @@ 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 == DRIVET_NONE) continue; drvp->drive_flags &= ~(DRIVE_UDMA | DRIVE_DMA); @@ -2248,7 +2251,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 & DRIVE_ATAPIDSCW) { DPRINTFN(1, ("%s:%d:%d: mvsata_atapi_phase_complete: polldsc %d\n", device_xname(atac->atac_dev), chp->ch_channel, @@ -2823,7 +2826,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 16406f88e12..39458cb6fd8 100644 --- a/sys/dev/ic/ninjaata32.c +++ b/sys/dev/ic/ninjaata32.c @@ -1,4 +1,4 @@ -/* $NetBSD: ninjaata32.c,v 1.13 2011/02/21 02:32:00 itohy Exp $ */ +/* $NetBSD: ninjaata32.c,v 1.14 2012/07/02 18:15:46 bouyer Exp $ */ /* * Copyright (c) 2006 ITOH Yasufumi. @@ -27,7 +27,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: ninjaata32.c,v 1.13 2011/02/21 02:32:00 itohy Exp $"); +__KERNEL_RCSID(0, "$NetBSD: ninjaata32.c,v 1.14 2012/07/02 18:15:46 bouyer Exp $"); #include <sys/param.h> #include <sys/kernel.h> @@ -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,16 +317,16 @@ 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 == DRIVET_NONE) continue; /* no drive */ #if 0 /* ATA DMA is currently unused */ diff --git a/sys/dev/ic/siisata.c b/sys/dev/ic/siisata.c index 6a1eacbb660..37ea92b9069 100644 --- a/sys/dev/ic/siisata.c +++ b/sys/dev/ic/siisata.c @@ -1,4 +1,4 @@ -/* $NetBSD: siisata.c,v 1.17 2012/05/15 19:06:26 bouyer Exp $ */ +/* $NetBSD: siisata.c,v 1.18 2012/07/02 18:15:47 bouyer Exp $ */ /* from ahcisata_core.c */ @@ -79,7 +79,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: siisata.c,v 1.17 2012/05/15 19:06:26 bouyer Exp $"); +__KERNEL_RCSID(0, "$NetBSD: siisata.c,v 1.18 2012/07/02 18:15:47 bouyer Exp $"); #include <sys/types.h> #include <sys/malloc.h> @@ -96,6 +96,7 @@ __KERNEL_RCSID(0, "$NetBSD: siisata.c,v 1.17 2012/05/15 19:06:26 bouyer Exp $"); #include <dev/ata/satareg.h> #include <dev/ata/satafisvar.h> #include <dev/ata/satafisreg.h> +#include <dev/ata/satapmpreg.h> #include <dev/ic/siisatavar.h> #include <dev/ic/siisatareg.h> @@ -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) @@ -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; } @@ -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 == 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 &= 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 &= 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; } diff --git a/sys/dev/ic/wdc.c b/sys/dev/ic/wdc.c index 3742aa9fd8c..430fe3328c7 100644 --- a/sys/dev/ic/wdc.c +++ b/sys/dev/ic/wdc.c @@ -1,4 +1,4 @@ -/* $NetBSD: wdc.c,v 1.268 2012/01/24 20:04:08 jakllsch Exp $ */ +/* $NetBSD: wdc.c,v 1.269 2012/07/02 18:15:47 bouyer Exp $ */ /* * Copyright (c) 1998, 2001, 2003 Manuel Bouyer. All rights reserved. @@ -58,7 +58,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: wdc.c,v 1.268 2012/01/24 20:04:08 jakllsch Exp $"); +__KERNEL_RCSID(0, "$NetBSD: wdc.c,v 1.269 2012/07/02 18:15:47 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 = DRIVET_ATAPI; else - chp->ch_drive[0].drive_flags |= DRIVE_ATA; + chp->ch_drive[0].drive_type = 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 = 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 == 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 == 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 != DRIVET_ATA || + (st0 & WDCS_DRDY)) && + (chp->ch_ndrives < 2 || + chp->ch_drive[1].drive_type != 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 != DRIVET_ATAPI) + chp->ch_drive[0].drive_type = DRIVET_NONE; + if (chp->ch_ndrives > 1 && (st1 & WDCS_DRDY) == 0 && + chp->ch_drive[1].drive_type != DRIVET_ATAPI) + chp->ch_drive[1].drive_type = 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 @@ -375,7 +374,7 @@ wdc_drvprobe(struct ata_channel *chp) chp->ch_drive[i].drive_flags |= DRIVE_CAP32; splx(s); } - if ((chp->ch_drive[i].drive_flags & DRIVE) == 0) + if (chp->ch_drive[i].drive_type == 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 != DRIVET_ATA || + (wdc->cap & WDC_CAPABILITY_PREATA) == 0) { + chp->ch_drive[i].drive_type = 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 = 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 = 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 = 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 != + DRIVET_NONE) { + chp->ch_drive[j].drive_type = + 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 = DRIVET_ATAPI; + } else { + chp->ch_drive[drive].drive_type = 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 != DRIVET_NONE) ? 0x01:0x00; + if (chp->ch_ndrives > 1) + drv_mask1 |= + (chp->ch_drive[1].drive_type != DRIVET_NONE) ? 0x02:0x00; drv_mask2 = __wdcwait_reset(chp, drv_mask1, (poll == RESET_SLEEP) ? 0 : 1); if (drv_mask2 != drv_mask1) { diff --git a/sys/dev/ic/wdc_upc.c b/sys/dev/ic/wdc_upc.c index c1bd5628c2b..751298b9b63 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.26 2009/01/25 14:34:14 bjh21 Exp $ */ +/* $NetBSD: wdc_upc.c,v 1.27 2012/07/02 18:15:47 bouyer Exp $ */ /*- * Copyright (c) 2000 Ben Harris * All rights reserved. @@ -28,7 +28,7 @@ /* This file is part of NetBSD/arm26 -- a port of NetBSD to ARM2/3 machines. */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: wdc_upc.c,v 1.26 2009/01/25 14:34:14 bjh21 Exp $"); +__KERNEL_RCSID(0, "$NetBSD: wdc_upc.c,v 1.27 2012/07/02 18:15:47 bouyer Exp $"); #include <sys/param.h> #include <sys/device.h> @@ -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 6c317ea6e90..4cd1052cfd9 100644 --- a/sys/dev/ic/wdcvar.h +++ b/sys/dev/ic/wdcvar.h @@ -1,4 +1,4 @@ -/* $NetBSD: wdcvar.h,v 1.92 2012/01/09 01:01:49 jakllsch Exp $ */ +/* $NetBSD: wdcvar.h,v 1.93 2012/07/02 18:15:47 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 fa5f2e157a7..1731b5ed868 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.56 2009/04/02 00:09:33 dyoung Exp $ */ +/* $NetBSD: wdc_isa.c,v 1.57 2012/07/02 18:15:47 bouyer Exp $ */ /*- * Copyright (c) 1998, 2003 The NetBSD Foundation, Inc. @@ -30,7 +30,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: wdc_isa.c,v 1.56 2009/04/02 00:09:33 dyoung Exp $"); +__KERNEL_RCSID(0, "$NetBSD: wdc_isa.c,v 1.57 2012/07/02 18:15:47 bouyer Exp $"); #include <sys/param.h> #include <sys/systm.h> @@ -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 279576e99f5..f7c20bdeb3d 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.39 2008/04/28 20:23:53 martin Exp $ */ +/* $NetBSD: wdc_isapnp.c,v 1.40 2012/07/02 18:15:47 bouyer Exp $ */ /*- * Copyright (c) 1998, 2003 The NetBSD Foundation, Inc. @@ -30,7 +30,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: wdc_isapnp.c,v 1.39 2008/04/28 20:23:53 martin Exp $"); +__KERNEL_RCSID(0, "$NetBSD: wdc_isapnp.c,v 1.40 2012/07/02 18:15:47 bouyer Exp $"); #include <sys/param.h> #include <sys/systm.h> @@ -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/ofisa/wdc_ofisa.c b/sys/dev/ofisa/wdc_ofisa.c index b41f3bd1f86..a21d146ad11 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.30 2008/03/18 20:46:36 cube Exp $ */ +/* $NetBSD: wdc_ofisa.c,v 1.31 2012/07/02 18:15:47 bouyer Exp $ */ /* * Copyright 1997, 1998 @@ -38,7 +38,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: wdc_ofisa.c,v 1.30 2008/03/18 20:46:36 cube Exp $"); +__KERNEL_RCSID(0, "$NetBSD: wdc_ofisa.c,v 1.31 2012/07/02 18:15:47 bouyer Exp $"); #include <sys/param.h> #include <sys/device.h> @@ -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 9471715c8a7..4e15234badc 100644 --- a/sys/dev/pci/acardide.c +++ b/sys/dev/pci/acardide.c @@ -1,4 +1,4 @@ -/* $NetBSD: acardide.c,v 1.25 2011/04/04 20:37:56 dyoung Exp $ */ +/* $NetBSD: acardide.c,v 1.26 2012/07/02 18:15:47 bouyer Exp $ */ /*- * Copyright (c) 2001 Izumi Tsutsui. All rights reserved. @@ -25,7 +25,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: acardide.c,v 1.25 2011/04/04 20:37:56 dyoung Exp $"); +__KERNEL_RCSID(0, "$NetBSD: acardide.c,v 1.26 2012/07/02 18:15:47 bouyer Exp $"); #include <sys/param.h> #include <sys/systm.h> @@ -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); @@ -220,7 +221,7 @@ 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 == DRIVET_NONE) continue; /* add timing values, setup DMA if needed */ if ((atac->atac_cap & ATAC_CAP_UDMA) && diff --git a/sys/dev/pci/aceride.c b/sys/dev/pci/aceride.c index 7998a317a35..259c3f90432 100644 --- a/sys/dev/pci/aceride.c +++ b/sys/dev/pci/aceride.c @@ -1,4 +1,4 @@ -/* $NetBSD: aceride.c,v 1.30 2011/04/04 20:37:56 dyoung Exp $ */ +/* $NetBSD: aceride.c,v 1.31 2012/07/02 18:15:47 bouyer Exp $ */ /* * Copyright (c) 1999, 2000, 2001 Manuel Bouyer. @@ -25,7 +25,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: aceride.c,v 1.30 2011/04/04 20:37:56 dyoung Exp $"); +__KERNEL_RCSID(0, "$NetBSD: aceride.c,v 1.31 2012/07/02 18:15:47 bouyer Exp $"); #include <sys/param.h> #include <sys/systm.h> @@ -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) | @@ -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 == DRIVET_NONE) continue; ATADEBUG_PRINT(("acer_setup_channel: old timings reg for " "channel %d drive %d 0x%x\n", chp->ch_channel, drive, diff --git a/sys/dev/pci/artsata.c b/sys/dev/pci/artsata.c index cd7d176b44d..cb047ab0ced 100644 --- a/sys/dev/pci/artsata.c +++ b/sys/dev/pci/artsata.c @@ -1,4 +1,4 @@ -/* $NetBSD: artsata.c,v 1.21 2011/04/04 20:37:56 dyoung Exp $ */ +/* $NetBSD: artsata.c,v 1.22 2012/07/02 18:15:47 bouyer Exp $ */ /*- * Copyright (c) 2003 The NetBSD Foundation, Inc. @@ -30,7 +30,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: artsata.c,v 1.21 2011/04/04 20:37:56 dyoung Exp $"); +__KERNEL_RCSID(0, "$NetBSD: artsata.c,v 1.22 2012/07/02 18:15:47 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 1b2392f011f..755031e9358 100644 --- a/sys/dev/pci/cmdide.c +++ b/sys/dev/pci/cmdide.c @@ -1,4 +1,4 @@ -/* $NetBSD: cmdide.c,v 1.32 2011/04/04 20:37:56 dyoung Exp $ */ +/* $NetBSD: cmdide.c,v 1.33 2012/07/02 18:15:47 bouyer Exp $ */ /* * Copyright (c) 1999, 2000, 2001 Manuel Bouyer. @@ -25,7 +25,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: cmdide.c,v 1.32 2011/04/04 20:37:56 dyoung Exp $"); +__KERNEL_RCSID(0, "$NetBSD: cmdide.c,v 1.33 2012/07/02 18:15:47 bouyer Exp $"); #include <sys/param.h> #include <sys/systm.h> @@ -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,7 +379,7 @@ 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 == DRIVET_NONE) continue; /* add timing values, setup DMA if needed */ tim = cmd0643_9_data_tim_pio[drvp->PIO_mode]; @@ -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,7 +572,7 @@ 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 == DRIVET_NONE) continue; mode &= ~(0x03 << (drive * 4)); if (drvp->drive_flags & DRIVE_UDMA) { diff --git a/sys/dev/pci/cypide.c b/sys/dev/pci/cypide.c index 39a55ee8b61..754fc7dc4db 100644 --- a/sys/dev/pci/cypide.c +++ b/sys/dev/pci/cypide.c @@ -1,4 +1,4 @@ -/* $NetBSD: cypide.c,v 1.24 2011/04/04 20:37:56 dyoung Exp $ */ +/* $NetBSD: cypide.c,v 1.25 2012/07/02 18:15:47 bouyer Exp $ */ /* * Copyright (c) 1999, 2000, 2001 Manuel Bouyer. @@ -26,7 +26,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: cypide.c,v 1.24 2011/04/04 20:37:56 dyoung Exp $"); +__KERNEL_RCSID(0, "$NetBSD: cypide.c,v 1.25 2012/07/02 18:15:47 bouyer Exp $"); #include <sys/param.h> #include <sys/systm.h> @@ -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,7 +195,7 @@ 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 == DRIVET_NONE) continue; /* add timing values, setup DMA if needed */ if (drvp->drive_flags & DRIVE_DMA) { diff --git a/sys/dev/pci/geodeide.c b/sys/dev/pci/geodeide.c index 428a23223c3..d105b4defae 100644 --- a/sys/dev/pci/geodeide.c +++ b/sys/dev/pci/geodeide.c @@ -1,4 +1,4 @@ -/* $NetBSD: geodeide.c,v 1.19 2011/04/04 20:37:56 dyoung Exp $ */ +/* $NetBSD: geodeide.c,v 1.20 2012/07/02 18:15:47 bouyer Exp $ */ /* * Copyright (c) 2004 Manuel Bouyer. @@ -32,7 +32,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: geodeide.c,v 1.19 2011/04/04 20:37:56 dyoung Exp $"); +__KERNEL_RCSID(0, "$NetBSD: geodeide.c,v 1.20 2012/07/02 18:15:47 bouyer Exp $"); #include <sys/param.h> #include <sys/systm.h> @@ -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 == DRIVET_NONE) continue; switch (sc->sc_pp->ide_product) { diff --git a/sys/dev/pci/hptide.c b/sys/dev/pci/hptide.c index 52a085c984d..14ed634ac80 100644 --- a/sys/dev/pci/hptide.c +++ b/sys/dev/pci/hptide.c @@ -1,4 +1,4 @@ -/* $NetBSD: hptide.c,v 1.28 2011/04/04 20:37:56 dyoung Exp $ */ +/* $NetBSD: hptide.c,v 1.29 2012/07/02 18:15:47 bouyer Exp $ */ /* * Copyright (c) 1999, 2000, 2001 Manuel Bouyer. @@ -25,7 +25,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: hptide.c,v 1.28 2011/04/04 20:37:56 dyoung Exp $"); +__KERNEL_RCSID(0, "$NetBSD: hptide.c,v 1.29 2012/07/02 18:15:47 bouyer Exp $"); #include <sys/param.h> #include <sys/systm.h> @@ -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,10 +335,10 @@ 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 == DRIVET_NONE) continue; before = pci_conf_read(sc->sc_pc, sc->sc_tag, HPT_IDETIM(chp->ch_channel, drive)); diff --git a/sys/dev/pci/iteide.c b/sys/dev/pci/iteide.c index 4044da69587..fbd6b1b6128 100644 --- a/sys/dev/pci/iteide.c +++ b/sys/dev/pci/iteide.c @@ -1,4 +1,4 @@ -/* $NetBSD: iteide.c,v 1.12 2011/04/04 20:37:56 dyoung Exp $ */ +/* $NetBSD: iteide.c,v 1.13 2012/07/02 18:15:47 bouyer Exp $ */ /* * Copyright (c) 2004 The NetBSD Foundation, Inc. @@ -31,7 +31,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: iteide.c,v 1.12 2011/04/04 20:37:56 dyoung Exp $"); +__KERNEL_RCSID(0, "$NetBSD: iteide.c,v 1.13 2012/07/02 18:15:47 bouyer Exp $"); #include <sys/param.h> #include <sys/systm.h> @@ -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,7 +189,7 @@ 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 == DRIVET_NONE) continue; if ((chp->ch_atac->atac_cap & ATAC_CAP_UDMA) != 0 && diff --git a/sys/dev/pci/ixpide.c b/sys/dev/pci/ixpide.c index 5320a904ae0..9c9982116b1 100644 --- a/sys/dev/pci/ixpide.c +++ b/sys/dev/pci/ixpide.c @@ -1,4 +1,4 @@ -/* $NetBSD: ixpide.c,v 1.19 2011/04/04 20:37:56 dyoung Exp $ */ +/* $NetBSD: ixpide.c,v 1.20 2012/07/02 18:15:47 bouyer Exp $ */ /* * Copyright (c) 2004 The NetBSD Foundation. @@ -27,7 +27,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: ixpide.c,v 1.19 2011/04/04 20:37:56 dyoung Exp $"); +__KERNEL_RCSID(0, "$NetBSD: ixpide.c,v 1.20 2012/07/02 18:15:47 bouyer Exp $"); #include <sys/param.h> #include <sys/systm.h> @@ -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,7 +188,7 @@ 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 == DRIVET_NONE) continue; if (drvp->drive_flags & DRIVE_UDMA) { s = splbio(); diff --git a/sys/dev/pci/jmide.c b/sys/dev/pci/jmide.c index 5c7a073272a..547269f46b0 100644 --- a/sys/dev/pci/jmide.c +++ b/sys/dev/pci/jmide.c @@ -1,4 +1,4 @@ -/* $NetBSD: jmide.c,v 1.13 2012/03/29 00:02:41 pgoyette Exp $ */ +/* $NetBSD: jmide.c,v 1.14 2012/07/02 18:15:47 bouyer Exp $ */ /* * Copyright (c) 2007 Manuel Bouyer. @@ -25,7 +25,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: jmide.c,v 1.13 2012/03/29 00:02:41 pgoyette Exp $"); +__KERNEL_RCSID(0, "$NetBSD: jmide.c,v 1.14 2012/07/02 18:15:47 bouyer Exp $"); #include <sys/param.h> #include <sys/systm.h> @@ -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,7 +396,7 @@ 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 == DRIVET_NONE) continue; if (drvp->drive_flags & DRIVE_UDMA) { /* use Ultra/DMA */ diff --git a/sys/dev/pci/nside.c b/sys/dev/pci/nside.c index afa89c7a45e..f01ebc61390 100644 --- a/sys/dev/pci/nside.c +++ b/sys/dev/pci/nside.c @@ -1,4 +1,4 @@ -/* $NetBSD: nside.c,v 1.2 2011/04/04 20:37:56 dyoung Exp $ */ +/* $NetBSD: nside.c,v 1.3 2012/07/02 18:15:47 bouyer Exp $ */ /* * Copyright (c) 1999, 2000, 2001 Manuel Bouyer. @@ -25,7 +25,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: nside.c,v 1.2 2011/04/04 20:37:56 dyoung Exp $"); +__KERNEL_RCSID(0, "$NetBSD: nside.c,v 1.3 2012/07/02 18:15:47 bouyer Exp $"); #include <sys/param.h> #include <sys/systm.h> @@ -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,7 +173,7 @@ 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 == DRIVET_NONE) continue; ndrives++; diff --git a/sys/dev/pci/optiide.c b/sys/dev/pci/optiide.c index e51f0820579..602d38e99b9 100644 --- a/sys/dev/pci/optiide.c +++ b/sys/dev/pci/optiide.c @@ -1,4 +1,4 @@ -/* $NetBSD: optiide.c,v 1.19 2011/04/04 20:37:56 dyoung Exp $ */ +/* $NetBSD: optiide.c,v 1.20 2012/07/02 18:15:47 bouyer Exp $ */ /*- * Copyright (c) 2000 The NetBSD Foundation, Inc. @@ -30,7 +30,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: optiide.c,v 1.19 2011/04/04 20:37:56 dyoung Exp $"); +__KERNEL_RCSID(0, "$NetBSD: optiide.c,v 1.20 2012/07/02 18:15:47 bouyer Exp $"); #include <sys/param.h> #include <sys/systm.h> @@ -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,7 +198,7 @@ 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 == DRIVET_NONE) { mode[drive] = -1; continue; } diff --git a/sys/dev/pci/pciide_common.c b/sys/dev/pci/pciide_common.c index d073269a00e..874d739cb6f 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.52 2012/01/30 19:41:22 drochner Exp $ */ +/* $NetBSD: pciide_common.c,v 1.53 2012/07/02 18:15:47 bouyer Exp $ */ /* @@ -70,7 +70,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: pciide_common.c,v 1.52 2012/01/30 19:41:22 drochner Exp $"); +__KERNEL_RCSID(0, "$NetBSD: pciide_common.c,v 1.53 2012/07/02 18:15:47 bouyer Exp $"); #include <sys/param.h> #include <sys/malloc.h> @@ -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,12 +568,12 @@ 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 == DRIVET_NONE) continue; /* setup DMA if needed */ if (((drvp->drive_flags & DRIVE_DMA) == 0 && @@ -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,10 +1116,11 @@ 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 == DRIVET_NONE) continue; #if NATA_UDMA if (drvp->drive_flags & DRIVE_UDMA) { diff --git a/sys/dev/pci/pciidevar.h b/sys/dev/pci/pciidevar.h index 1f73d87f092..5900db53451 100644 --- a/sys/dev/pci/pciidevar.h +++ b/sys/dev/pci/pciidevar.h @@ -1,4 +1,4 @@ -/* $NetBSD: pciidevar.h,v 1.43 2011/04/04 20:37:56 dyoung Exp $ */ +/* $NetBSD: pciidevar.h,v 1.44 2012/07/02 18:15:47 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 d56509bd9da..6a16cf0c6ab 100644 --- a/sys/dev/pci/pdcide.c +++ b/sys/dev/pci/pdcide.c @@ -1,4 +1,4 @@ -/* $NetBSD: pdcide.c,v 1.29 2011/04/04 20:37:56 dyoung Exp $ */ +/* $NetBSD: pdcide.c,v 1.30 2012/07/02 18:15:47 bouyer Exp $ */ /* * Copyright (c) 1999, 2000, 2001 Manuel Bouyer. @@ -25,7 +25,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: pdcide.c,v 1.29 2011/04/04 20:37:56 dyoung Exp $"); +__KERNEL_RCSID(0, "$NetBSD: pdcide.c,v 1.30 2012/07/02 18:15:47 bouyer Exp $"); #include <sys/param.h> #include <sys/systm.h> @@ -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); @@ -372,8 +373,8 @@ 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_type == DRIVET_ATAPI || + chp->ch_drive[1].drive_type == DRIVET_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)) || @@ -390,7 +391,7 @@ 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 == DRIVET_NONE) continue; mode = 0; if (drvp->drive_flags & DRIVE_UDMA) { @@ -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 == DRIVET_ATA) mode |= PDC2xx_TIM_PRE; mode |= PDC2xx_TIM_SYNC | PDC2xx_TIM_ERRDY; if (drvp->PIO_mode >= 3) { @@ -468,7 +469,7 @@ 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 == DRIVET_NONE) continue; if (drvp->drive_flags & DRIVE_UDMA) { /* use Ultra/DMA */ @@ -594,8 +595,8 @@ 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_type == DRIVET_ATAPI || + chp->ch_drive[1].drive_type == DRIVET_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)) && diff --git a/sys/dev/pci/pdcsata.c b/sys/dev/pci/pdcsata.c index ec560eb3934..57a9fc2e800 100644 --- a/sys/dev/pci/pdcsata.c +++ b/sys/dev/pci/pdcsata.c @@ -1,4 +1,4 @@ -/* $NetBSD: pdcsata.c,v 1.20 2011/04/04 20:37:56 dyoung Exp $ */ +/* $NetBSD: pdcsata.c,v 1.21 2012/07/02 18:15:47 bouyer Exp $ */ /* * Copyright (c) 2004, Manuel Bouyer. @@ -25,7 +25,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: pdcsata.c,v 1.20 2011/04/04 20:37:56 dyoung Exp $"); +__KERNEL_RCSID(0, "$NetBSD: pdcsata.c,v 1.21 2012/07/02 18:15:47 bouyer Exp $"); #include <sys/types.h> #include <sys/malloc.h> @@ -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,7 +498,7 @@ 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 == DRIVET_NONE) continue; if (drvp->drive_flags & DRIVE_UDMA) { s = splbio(); diff --git a/sys/dev/pci/piixide.c b/sys/dev/pci/piixide.c index 650c5f4590e..03c94e16ed1 100644 --- a/sys/dev/pci/piixide.c +++ b/sys/dev/pci/piixide.c @@ -1,4 +1,4 @@ -/* $NetBSD: piixide.c,v 1.58 2012/03/05 16:21:44 sborrill Exp $ */ +/* $NetBSD: piixide.c,v 1.59 2012/07/02 18:15:47 bouyer Exp $ */ /* * Copyright (c) 1999, 2000, 2001 Manuel Bouyer. @@ -25,7 +25,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: piixide.c,v 1.58 2012/03/05 16:21:44 sborrill Exp $"); +__KERNEL_RCSID(0, "$NetBSD: piixide.c,v 1.59 2012/07/02 18:15:47 bouyer Exp $"); #include <sys/param.h> #include <sys/systm.h> @@ -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)), @@ -676,7 +677,7 @@ end: /* */ for (drive = 0; drive < 2; drive++) { /* If no drive, skip */ - if ((drvp[drive].drive_flags & DRIVE) == 0) + if (drvp[drive].drive_type == DRIVET_NONE) continue; idetim |= piix_setup_idetim_drvs(&drvp[drive]); if (drvp[drive].drive_flags & DRIVE_DMA) @@ -721,7 +722,7 @@ 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 == DRIVET_NONE) continue; if (((drvp->drive_flags & DRIVE_DMA) == 0 && (drvp->drive_flags & DRIVE_UDMA) == 0)) @@ -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 c6e77e752ed..15b775bec4d 100644 --- a/sys/dev/pci/rccide.c +++ b/sys/dev/pci/rccide.c @@ -1,4 +1,4 @@ -/* $NetBSD: rccide.c,v 1.21 2011/04/04 20:37:56 dyoung Exp $ */ +/* $NetBSD: rccide.c,v 1.22 2012/07/02 18:15:48 bouyer Exp $ */ /* * Copyright (c) 2003 By Noon Software, Inc. All rights reserved. @@ -27,7 +27,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: rccide.c,v 1.21 2011/04/04 20:37:56 dyoung Exp $"); +__KERNEL_RCSID(0, "$NetBSD: rccide.c,v 1.22 2012/07/02 18:15:48 bouyer Exp $"); #include <sys/param.h> #include <sys/systm.h> @@ -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,7 +212,7 @@ 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 == DRIVET_NONE) continue; unit = drive + 2 * channel; /* add timing values, setup DMA if needed */ diff --git a/sys/dev/pci/rdcide.c b/sys/dev/pci/rdcide.c index f8a8d01564f..ec9dcab7d9a 100644 --- a/sys/dev/pci/rdcide.c +++ b/sys/dev/pci/rdcide.c @@ -1,4 +1,4 @@ -/* $NetBSD: rdcide.c,v 1.2 2011/04/04 22:13:58 dyoung Exp $ */ +/* $NetBSD: rdcide.c,v 1.3 2012/07/02 18:15:48 bouyer Exp $ */ /* * Copyright (c) 2011 Manuel Bouyer. @@ -25,7 +25,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: rdcide.c,v 1.2 2011/04/04 22:13:58 dyoung Exp $"); +__KERNEL_RCSID(0, "$NetBSD: rdcide.c,v 1.3 2012/07/02 18:15:48 bouyer Exp $"); #include <sys/param.h> #include <sys/systm.h> @@ -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 == DRIVET_NONE) continue; - if ((drvp[drive].drive_flags & DRIVE_ATAPI) == 0) + if (drvp[drive].drive_type == DRIVET_ATAPI) patr |= RDCIDE_PATR_ATA(chp->ch_channel, drive); if (drive == 0) { patr |= RDCIDE_PATR_SETUP( diff --git a/sys/dev/pci/satalink.c b/sys/dev/pci/satalink.c index 55eca5bf4cb..8c394154f39 100644 --- a/sys/dev/pci/satalink.c +++ b/sys/dev/pci/satalink.c @@ -1,4 +1,4 @@ -/* $NetBSD: satalink.c,v 1.43 2011/04/04 20:37:56 dyoung Exp $ */ +/* $NetBSD: satalink.c,v 1.44 2012/07/02 18:15:48 bouyer Exp $ */ /*- * Copyright (c) 2003 The NetBSD Foundation, Inc. @@ -30,7 +30,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: satalink.c,v 1.43 2011/04/04 20:37:56 dyoung Exp $"); +__KERNEL_RCSID(0, "$NetBSD: satalink.c,v 1.44 2012/07/02 18:15:48 bouyer Exp $"); #include <sys/param.h> #include <sys/systm.h> @@ -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 = DRIVET_ATAPI; else - chp->ch_drive[0].drive_flags |= DRIVE_ATA; + chp->ch_drive[0].drive_type = DRIVET_ATA; splx(s); aprint_normal_dev(sc->sc_wdcdev.sc_atac.atac_dev, @@ -917,7 +914,7 @@ 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 == DRIVET_NONE) continue; if (drvp->drive_flags & DRIVE_UDMA) { /* use Ultra/DMA */ diff --git a/sys/dev/pci/schide.c b/sys/dev/pci/schide.c index 938575ba47d..7abcd47171b 100644 --- a/sys/dev/pci/schide.c +++ b/sys/dev/pci/schide.c @@ -1,4 +1,4 @@ -/* $NetBSD: schide.c,v 1.2 2011/04/04 20:37:56 dyoung Exp $ */ +/* $NetBSD: schide.c,v 1.3 2012/07/02 18:15:48 bouyer Exp $ */ /* $OpenBSD: pciide.c,v 1.305 2009/11/01 01:50:15 dlg Exp $ */ /* @@ -57,7 +57,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: schide.c,v 1.2 2011/04/04 20:37:56 dyoung Exp $"); +__KERNEL_RCSID(0, "$NetBSD: schide.c,v 1.3 2012/07/02 18:15:48 bouyer Exp $"); #include <sys/param.h> #include <sys/systm.h> @@ -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,7 +185,7 @@ 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 == DRIVET_NONE) continue; timaddr = (drive == 0) ? SCH_D0TIM : SCH_D1TIM; diff --git a/sys/dev/pci/siside.c b/sys/dev/pci/siside.c index 6357c7bd2da..f8f7272522a 100644 --- a/sys/dev/pci/siside.c +++ b/sys/dev/pci/siside.c @@ -1,4 +1,4 @@ -/* $NetBSD: siside.c,v 1.28 2011/05/24 16:42:10 joerg Exp $ */ +/* $NetBSD: siside.c,v 1.29 2012/07/02 18:15:48 bouyer Exp $ */ /* * Copyright (c) 1999, 2000, 2001 Manuel Bouyer. @@ -25,7 +25,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: siside.c,v 1.28 2011/05/24 16:42:10 joerg Exp $"); +__KERNEL_RCSID(0, "$NetBSD: siside.c,v 1.29 2012/07/02 18:15:48 bouyer Exp $"); #include <sys/param.h> #include <sys/systm.h> @@ -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,7 +358,7 @@ 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 == DRIVET_NONE) continue; /* add timing values, setup DMA if needed */ if (drvp->drive_flags & DRIVE_UDMA) { @@ -423,7 +424,7 @@ 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 == DRIVET_NONE) continue; /* add timing values, setup DMA if needed */ if ((drvp->drive_flags & DRIVE_DMA) == 0 && @@ -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 93504729052..441fed34dd0 100644 --- a/sys/dev/pci/slide.c +++ b/sys/dev/pci/slide.c @@ -1,4 +1,4 @@ -/* $NetBSD: slide.c,v 1.23 2012/04/08 13:08:02 jakllsch Exp $ */ +/* $NetBSD: slide.c,v 1.24 2012/07/02 18:15:48 bouyer Exp $ */ /*- * Copyright (c) 2002 The NetBSD Foundation, Inc. @@ -30,7 +30,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: slide.c,v 1.23 2012/04/08 13:08:02 jakllsch Exp $"); +__KERNEL_RCSID(0, "$NetBSD: slide.c,v 1.24 2012/07/02 18:15:48 bouyer Exp $"); #include <sys/param.h> #include <sys/systm.h> @@ -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,7 +208,7 @@ 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 == DRIVET_NONE) { pci_conf_write(sc->sc_pc, sc->sc_tag, pxdx_reg, pxdx); continue; } diff --git a/sys/dev/pci/stpcide.c b/sys/dev/pci/stpcide.c index 41361b303ed..df3c51e5887 100644 --- a/sys/dev/pci/stpcide.c +++ b/sys/dev/pci/stpcide.c @@ -1,4 +1,4 @@ -/* $NetBSD: stpcide.c,v 1.21 2011/04/04 20:37:56 dyoung Exp $ */ +/* $NetBSD: stpcide.c,v 1.22 2012/07/02 18:15:48 bouyer Exp $ */ /*- * Copyright (c) 2003 The NetBSD Foundation, Inc. @@ -30,7 +30,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: stpcide.c,v 1.21 2011/04/04 20:37:56 dyoung Exp $"); +__KERNEL_RCSID(0, "$NetBSD: stpcide.c,v 1.22 2012/07/02 18:15:48 bouyer Exp $"); #include <sys/param.h> #include <sys/systm.h> @@ -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,7 +159,7 @@ 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 == DRIVET_NONE) continue; /* add timing values, setup DMA if needed */ if ((atac->atac_cap & ATAC_CAP_DMA) && diff --git a/sys/dev/pci/svwsata.c b/sys/dev/pci/svwsata.c index 93151d1f238..8917e579cb5 100644 --- a/sys/dev/pci/svwsata.c +++ b/sys/dev/pci/svwsata.c @@ -1,4 +1,4 @@ -/* $NetBSD: svwsata.c,v 1.13 2011/04/04 20:37:56 dyoung Exp $ */ +/* $NetBSD: svwsata.c,v 1.14 2012/07/02 18:15:48 bouyer Exp $ */ /* * Copyright (c) 2005 Mark Kettenis @@ -17,7 +17,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: svwsata.c,v 1.13 2011/04/04 20:37:56 dyoung Exp $"); +__KERNEL_RCSID(0, "$NetBSD: svwsata.c,v 1.14 2012/07/02 18:15:48 bouyer Exp $"); #include <sys/param.h> #include <sys/systm.h> @@ -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 07ec4748c2f..38c9ce9592c 100644 --- a/sys/dev/pci/toshide.c +++ b/sys/dev/pci/toshide.c @@ -1,4 +1,4 @@ -/* $NetBSD: toshide.c,v 1.4 2011/04/04 20:37:56 dyoung Exp $ */ +/* $NetBSD: toshide.c,v 1.5 2012/07/02 18:15:48 bouyer Exp $ */ /*- * Copyright (c) 2009 The NetBSD Foundation, Inc. @@ -27,7 +27,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: toshide.c,v 1.4 2011/04/04 20:37:56 dyoung Exp $"); +__KERNEL_RCSID(0, "$NetBSD: toshide.c,v 1.5 2012/07/02 18:15:48 bouyer Exp $"); #include <sys/param.h> #include <sys/systm.h> @@ -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,7 +184,7 @@ 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 == DRIVET_NONE) continue; if (drvp->drive_flags & DRIVE_UDMA) { diff --git a/sys/dev/pci/viaide.c b/sys/dev/pci/viaide.c index 05be79d8fb1..a6e536a1764 100644 --- a/sys/dev/pci/viaide.c +++ b/sys/dev/pci/viaide.c @@ -1,4 +1,4 @@ -/* $NetBSD: viaide.c,v 1.78 2012/03/18 17:50:43 tsutsui Exp $ */ +/* $NetBSD: viaide.c,v 1.79 2012/07/02 18:15:48 bouyer Exp $ */ /* * Copyright (c) 1999, 2000, 2001 Manuel Bouyer. @@ -26,7 +26,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: viaide.c,v 1.78 2012/03/18 17:50:43 tsutsui Exp $"); +__KERNEL_RCSID(0, "$NetBSD: viaide.c,v 1.79 2012/07/02 18:15:48 bouyer Exp $"); #include <sys/param.h> #include <sys/systm.h> @@ -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,7 +744,7 @@ 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 == DRIVET_NONE) continue; /* add timing values, setup DMA if needed */ if (((drvp->drive_flags & DRIVE_DMA) == 0 && @@ -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 3bcd5f72834..fd625aa7b1a 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.117 2009/11/12 19:37:17 dyoung Exp $ */ +/* $NetBSD: wdc_pcmcia.c,v 1.118 2012/07/02 18:15:48 bouyer Exp $ */ /*- * Copyright (c) 1998, 2003, 2004 The NetBSD Foundation, Inc. @@ -30,7 +30,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: wdc_pcmcia.c,v 1.117 2009/11/12 19:37:17 dyoung Exp $"); +__KERNEL_RCSID(0, "$NetBSD: wdc_pcmcia.c,v 1.118 2012/07/02 18:15:48 bouyer Exp $"); #include <sys/param.h> #include <sys/device.h> @@ -294,12 +294,12 @@ wdc_pcmcia_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 = wdcp ? wdcp->wdc_ndrive : 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; 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; wdc_init_shadow_regs(&sc->ata_channel); error = wdc_pcmcia_enable(self, 1); diff --git a/sys/dev/podulebus/dtide.c b/sys/dev/podulebus/dtide.c index de882adf133..3ec9af21b89 100644 --- a/sys/dev/podulebus/dtide.c +++ b/sys/dev/podulebus/dtide.c @@ -1,4 +1,4 @@ -/* $NetBSD: dtide.c,v 1.25 2008/03/18 20:46:37 cube Exp $ */ +/* $NetBSD: dtide.c,v 1.26 2012/07/02 18:15:48 bouyer Exp $ */ /*- * Copyright (c) 2000, 2001 Ben Harris @@ -31,7 +31,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: dtide.c,v 1.25 2008/03/18 20:46:37 cube Exp $"); +__KERNEL_RCSID(0, "$NetBSD: dtide.c,v 1.26 2012/07/02 18:15:48 bouyer Exp $"); #include <sys/param.h> @@ -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 a7fd548a69b..ee05a468199 100644 --- a/sys/dev/podulebus/hcide.c +++ b/sys/dev/podulebus/hcide.c @@ -1,4 +1,4 @@ -/* $NetBSD: hcide.c,v 1.22 2008/03/18 20:46:37 cube Exp $ */ +/* $NetBSD: hcide.c,v 1.23 2012/07/02 18:15:48 bouyer Exp $ */ /*- * Copyright (c) 2000, 2001 Ben Harris @@ -31,7 +31,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: hcide.c,v 1.22 2008/03/18 20:46:37 cube Exp $"); +__KERNEL_RCSID(0, "$NetBSD: hcide.c,v 1.23 2012/07/02 18:15:48 bouyer Exp $"); #include <sys/param.h> @@ -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 b21943840aa..646f5e108d1 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.113 2012/04/20 20:23:21 bouyer Exp $ */ +/* $NetBSD: atapi_wdc.c,v 1.114 2012/07/02 18:15:48 bouyer Exp $ */ /* * Copyright (c) 1998, 2001 Manuel Bouyer. @@ -25,7 +25,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: atapi_wdc.c,v 1.113 2012/04/20 20:23:21 bouyer Exp $"); +__KERNEL_RCSID(0, "$NetBSD: atapi_wdc.c,v 1.114 2012/07/02 18:15:48 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 != 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 |= 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 = DRIVET_NONE; splx(s); } } else { s = splbio(); - drvp->drive_flags &= ~DRIVE_ATAPI; + drvp->drive_type = DRIVET_NONE; splx(s); } } @@ -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 & DRIVE_ATAPIDSCW) { ATADEBUG_PRINT(("wdc_atapi_phase_complete(%s:%d:%d) " "polldsc %d\n", device_xname(atac->atac_dev), chp->ch_channel, diff --git a/sys/dev/usb/umass_isdata.c b/sys/dev/usb/umass_isdata.c index 9e76b84a44f..148db9f421c 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.22 2012/03/04 00:21:20 mrg Exp $ */ +/* $NetBSD: umass_isdata.c,v 1.23 2012/07/02 18:15:48 bouyer Exp $ */ /* * TODO: @@ -37,7 +37,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: umass_isdata.c,v 1.22 2012/03/04 00:21:20 mrg Exp $"); +__KERNEL_RCSID(0, "$NetBSD: umass_isdata.c,v 1.23 2012/07/02 18:15:48 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 = 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? */ } |
