diff -ru dev.bad/ata/ata.c dev/ata/ata.c --- dev.bad/ata/ata.c 2012-07-25 09:21:19.000000000 -0400 +++ dev/ata/ata.c 2012-07-25 09:14:20.000000000 -0400 @@ -1,4 +1,4 @@ -/* $NetBSD: ata.c,v 1.121 2012/07/24 14:04:29 jakllsch Exp $ */ +/* $NetBSD: ata.c,v 1.116 2012/04/06 02:52:00 isaki Exp $ */ /* * Copyright (c) 1998, 2001 Manuel Bouyer. All rights reserved. @@ -25,7 +25,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: ata.c,v 1.121 2012/07/24 14:04:29 jakllsch Exp $"); +__KERNEL_RCSID(0, "$NetBSD: ata.c,v 1.116 2012/04/06 02:52:00 isaki Exp $"); #include "opt_ata.h" @@ -55,22 +55,17 @@ #include "atapibus.h" #include "ataraid.h" -#include "sata_pmp.h" #if NATARAID > 0 #include #endif -#if NSATA_PMP > 0 -#include -#endif -#include #define DEBUG_FUNCS 0x08 #define DEBUG_PROBE 0x10 #define DEBUG_DETACH 0x20 #define DEBUG_XFERS 0x40 #ifdef ATADEBUG -int atadebug_mask = DEBUG_PROBE; +int atadebug_mask = 0; #define ATADEBUG_PRINT(args, level) \ if (atadebug_mask & (level)) \ printf args @@ -204,19 +199,13 @@ chp->ch_flags |= ATACH_TH_RUN; splx(s); - /* - * Probe for the drives attached to controller, unless a PMP - * is already known - */ + /* Probe for the drives. */ /* XXX for SATA devices we will power up all drives at once */ - if (chp->ch_satapmp_nports == 0) - (*atac->atac_probe)(chp); + (*atac->atac_probe)(chp); - if (chp->ch_drive != NULL && chp->ch_ndrives >= 2) { - ATADEBUG_PRINT(("atabusattach: ch_drive_type 0x%x 0x%x\n", - chp->ch_drive[0].drive_type, chp->ch_drive[1].drive_type), - DEBUG_PROBE); - } + ATADEBUG_PRINT(("atabusattach: ch_drive_flags 0x%x 0x%x\n", + chp->ch_drive[0].drive_flags, chp->ch_drive[1].drive_flags), + DEBUG_PROBE); /* next operations will occurs in a separate thread */ s = splbio(); @@ -234,19 +223,17 @@ mutex_exit(&atabus_qlock); /* If no drives, abort here */ - 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) + for (i = 0; i < chp->ch_ndrive; i++) + if ((chp->ch_drive[i].drive_flags & DRIVE) != 0) break; - if (i == chp->ch_ndrives) + if (i == chp->ch_ndrive) 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) @@ -287,25 +274,10 @@ 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. */ - 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) { + for (i = 0; i < chp->ch_ndrive; i++) { + if (chp->ch_drive[i].drive_flags & DRIVE_ATAPI) { #if NATAPIBUS > 0 (*atac->atac_atapibus_attach)(atabus_sc); #else @@ -316,36 +288,33 @@ device_xname(atac->atac_dev)); chp->atapibus = NULL; s = splbio(); - 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; - } + for (i = 0; i < chp->ch_ndrive; i++) + chp->ch_drive[i].drive_flags &= ~DRIVE_ATAPI; splx(s); #endif break; } } - for (i = 0; i < chp->ch_ndrives; i++) { + for (i = 0; i < chp->ch_ndrive; i++) { struct ata_device adev; - if (chp->ch_drive[i].drive_type != DRIVET_ATA && - chp->ch_drive[i].drive_type != DRIVET_OLD) { + if ((chp->ch_drive[i].drive_flags & + (DRIVE_ATA | DRIVE_OLD)) == 0) { 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->ch_drive[i].drv_softc = config_found_ia(atabus_sc->sc_dev, + chp->ata_drives[i] = config_found_ia(atabus_sc->sc_dev, "ata_hl", &adev, ataprint); - if (chp->ch_drive[i].drv_softc != NULL) { + if (chp->ata_drives[i] != NULL) ata_probe_caps(&chp->ch_drive[i]); - } else { + else { s = splbio(); - chp->ch_drive[i].drive_type = DRIVET_NONE; + chp->ch_drive[i].drive_flags &= + ~(DRIVE_ATA | DRIVE_OLD); splx(s); } } @@ -356,14 +325,10 @@ ata_print_modes(chp); } #if NATARAID > 0 - 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); - } - } - } + 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]); #endif /* NATARAID > 0 */ /* @@ -371,13 +336,10 @@ * ones */ s = splbio(); - 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) { + for (i = 0; i < chp->ch_ndrive; i++) { + if (chp->ch_drive[i].drv_softc == NULL) chp->ch_drive[i].drive_flags = 0; - chp->ch_drive[i].drive_type = DRIVET_NONE; - } else + else chp->ch_drive[i].state = 0; } splx(s); @@ -412,16 +374,13 @@ chp->ch_flags |= ATACH_TH_RUN; /* - * Probe the drives. Reset type to indicate to controllers + * Probe the drives. Reset all flags to 0 to indicate to controllers * that can re-probe that all drives must be probed.. * - * Note: ch_ndrives may be changed during the probe. + * Note: ch_ndrive may be changed during the probe. */ - KASSERT(chp->ch_ndrives == 0 || chp->ch_drive != NULL); - for (i = 0; i < chp->ch_ndrives; i++) { + for (i = 0; i < ATA_MAXDRIVES; i++) chp->ch_drive[i].drive_flags = 0; - chp->ch_drive[i].drive_type = DRIVET_NONE; - } splx(s); atabusconfig(sc); @@ -563,28 +522,24 @@ KASSERT(chp->atapibus == NULL); } - KASSERT(chp->ch_ndrives == 0 || chp->ch_drive != NULL); - /* * Detach our other children. */ - for (i = 0; i < chp->ch_ndrives; i++) { - if (chp->ch_drive[i].drive_type == DRIVET_ATAPI) + for (i = 0; i < chp->ch_ndrive; i++) { + if (chp->ch_drive[i].drive_flags & DRIVE_ATAPI) continue; - 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) { + if ((dev = chp->ata_drives[i]) != 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->ch_drive[i].drv_softc == NULL); - KASSERT(chp->ch_drive[i].drive_type == 0); + KASSERT(chp->ata_drives[i] == NULL); } } - atabus_free_drives(chp); out: #ifdef ATADEBUG @@ -605,35 +560,26 @@ 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_ndrives; i++) { - if (chp->ch_drive[i].drive_type == DRIVET_ATAPI) + for (i = 0; i < chp->ch_ndrive; i++) { + if (chp->ch_drive[i].drive_flags & DRIVE_ATAPI) continue; - if (child == chp->ch_drive[i].drv_softc) { + if (child == chp->ata_drives[i]) { + KASSERT(chp->ata_drives[i] == + chp->ch_drive[i].drv_softc); + chp->ata_drives[i] = NULL; 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; } } @@ -651,64 +597,6 @@ * 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, @@ -727,12 +615,12 @@ memset(prms, 0, sizeof(struct ataparams)); memset(&ata_c, 0, sizeof(struct ata_command)); - if (drvp->drive_type == DRIVET_ATA) { + if (drvp->drive_flags & DRIVE_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_type == DRIVET_ATAPI) { + } else if (drvp->drive_flags & DRIVE_ATAPI) { ata_c.r_command = ATAPI_IDENTIFY_DEVICE; ata_c.r_st_bmask = 0; ata_c.r_st_pmask = WDCS_DRQ; @@ -783,7 +671,7 @@ #if BYTE_ORDER == BIG_ENDIAN ! #endif - ((drvp->drive_type == DRIVET_ATAPI) ? + ((drvp->drive_flags & DRIVE_ATAPI) ? ((M(0) == 'N' && M(1) == 'E') || (M(0) == 'F' && M(1) == 'X') || (M(0) == 'P' && M(1) == 'i')) : @@ -1121,8 +1009,7 @@ (*atac->atac_bustype_ata->ata_reset_channel)(chp, flags); - KASSERT(chp->ch_ndrives == 0 || chp->ch_drive != NULL); - for (drive = 0; drive < chp->ch_ndrives; drive++) + for (drive = 0; drive < chp->ch_ndrive; drive++) chp->ch_drive[drive].state = 0; chp->ch_flags &= ~ATACH_TH_RESET; @@ -1176,11 +1063,9 @@ int drive; struct ata_drive_datas *drvp; - KASSERT(chp->ch_ndrives == 0 || chp->ch_drive != NULL); - for (drive = 0; drive < chp->ch_ndrives; drive++) { + for (drive = 0; drive < chp->ch_ndrive; drive++) { drvp = &chp->ch_drive[drive]; - if (drvp->drive_type == DRIVET_NONE || - drvp->drv_softc == NULL) + if ((drvp->drive_flags & DRIVE) == 0 || drvp->drv_softc == NULL) continue; aprint_verbose("%s(%s:%d:%d): using PIO mode %d", device_xname(drvp->drv_softc), @@ -1330,7 +1215,7 @@ #endif /* An ATAPI device is at last PIO mode 3 */ - if (drvp->drive_type == DRIVET_ATAPI) + if (drvp->drive_flags & DRIVE_ATAPI) drvp->PIO_mode = 3; /* @@ -1469,7 +1354,7 @@ s = splbio(); drvp->drive_flags &= ~DRIVE_NOSTREAM; - if (drvp->drive_type == DRIVET_ATAPI) { + if (drvp->drive_flags & DRIVE_ATAPI) { if (atac->atac_cap & ATAC_CAP_ATAPI_NOSTREAM) drvp->drive_flags |= DRIVE_NOSTREAM; } else { @@ -1605,8 +1490,8 @@ struct atabusioscan_args *a= (struct atabusioscan_args *)addr; #endif - if ((chp->ch_drive[0].drive_type == DRIVET_OLD) || - (chp->ch_drive[1].drive_type == DRIVET_OLD)) + if ((chp->ch_drive[0].drive_flags & DRIVE_OLD) || + (chp->ch_drive[1].drive_flags & DRIVE_OLD)) return (EOPNOTSUPP); return (EOPNOTSUPP); } @@ -1614,8 +1499,8 @@ { struct atabusiodetach_args *a= (struct atabusiodetach_args *)addr; - if ((chp->ch_drive[0].drive_type == DRIVET_OLD) || - (chp->ch_drive[1].drive_type == DRIVET_OLD)) + if ((chp->ch_drive[0].drive_flags & DRIVE_OLD) || + (chp->ch_drive[1].drive_flags & DRIVE_OLD)) return (EOPNOTSUPP); switch (a->at_dev) { case -1: @@ -1688,23 +1573,23 @@ struct ata_channel *chp = sc->sc_chan; struct atabus_initq *initq; int i; + int s; - /* - * we can rescan a port multiplier atabus, even if some devices are - * still attached - */ - if (chp->ch_satapmp_nports == 0) { - if (chp->atapibus != NULL) { + if (chp->atapibus != NULL) { + return EBUSY; + } + + for (i = 0; i < ATA_MAXDRIVES; i++) { + if (chp->ata_drives[i] != NULL) { return EBUSY; } + } - 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; - } - } + s = splbio(); + for (i = 0; i < ATA_MAXDRIVES; i++) { + chp->ch_drive[i].drive_flags = 0; } + splx(s); initq = malloc(sizeof(*initq), M_DEVBUF, M_WAITOK); initq->atabus_sc = sc; diff -ru dev.bad/ata/ata_wdc.c dev/ata/ata_wdc.c --- dev.bad/ata/ata_wdc.c 2012-07-25 09:16:14.000000000 -0400 +++ dev/ata/ata_wdc.c 2012-07-25 09:14:20.000000000 -0400 @@ -1,4 +1,4 @@ -/* $NetBSD: ata_wdc.c,v 1.99 2012/07/24 14:04:29 jakllsch Exp $ */ +/* $NetBSD: ata_wdc.c,v 1.96 2012/01/09 01:01:48 jakllsch Exp $ */ /* * Copyright (c) 1998, 2001, 2003 Manuel Bouyer. @@ -54,7 +54,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: ata_wdc.c,v 1.99 2012/07/24 14:04:29 jakllsch Exp $"); +__KERNEL_RCSID(0, "$NetBSD: ata_wdc.c,v 1.96 2012/01/09 01:01:48 jakllsch Exp $"); #include "opt_ata.h" #include "opt_wdc.h" @@ -187,10 +187,8 @@ wait_flags = (xfer->c_flags & C_POLL) ? AT_POLL : 0; #endif - 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), + ATADEBUG_PRINT(("wdc_ata_bio_start %s:%d:%d\n", + device_xname(atac->atac_dev), chp->ch_channel, xfer->c_drive), DEBUG_XFERS); /* Do control operations specially. */ @@ -782,7 +780,7 @@ panic("wdc_ata_bio_kill_xfer"); } ata_bio->r_error = WDCE_ABRT; - ATADEBUG_PRINT(("wdc_ata_bio_kill_xfer: drv_done\n"), DEBUG_XFERS); + ATADEBUG_PRINT(("wdc_ata_done: drv_done\n"), DEBUG_XFERS); (*chp->ch_drive[drive].drv_done)(chp->ch_drive[drive].drv_softc); } diff -ru dev.bad/ata/atavar.h dev/ata/atavar.h --- dev.bad/ata/atavar.h 2012-07-25 09:16:14.000000000 -0400 +++ dev/ata/atavar.h 2012-07-25 09:14:20.000000000 -0400 @@ -1,4 +1,4 @@ -/* $NetBSD: atavar.h,v 1.87 2012/07/24 14:04:29 jakllsch Exp $ */ +/* $NetBSD: atavar.h,v 1.84 2012/01/24 20:04:07 jakllsch Exp $ */ /* * Copyright (c) 1998, 2001 Manuel Bouyer. @@ -37,6 +37,11 @@ #include /* + * Max number of drives per channel. + */ +#define ATA_MAXDRIVES 2 + +/* * Description of a command to be handled by an ATA controller. These * commands are queued in a list. */ @@ -108,24 +113,22 @@ /* 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_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 */ + +#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 */ /* * Current setting of drive's PIO, DMA and UDMA modes. @@ -283,7 +286,7 @@ 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, uint32_t *); + void (*ata_reset_drive)(struct ata_drive_datas *, int); 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 */ @@ -344,8 +347,8 @@ int ch_reset_flags; /* per-drive info */ - int ch_ndrives; /* number of entries in ch_drive[] */ - struct ata_drive_datas *ch_drive; /* array of ata_drive_datas */ + int ch_ndrive; + struct ata_drive_datas ch_drive[ATA_MAXDRIVES]; device_t atabus; /* self */ @@ -353,6 +356,9 @@ 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. @@ -361,9 +367,6 @@ /* The channel kernel thread */ struct lwp *ch_thread; - - /* Number of sata PMP ports, if any */ - int ch_satapmp_nports; }; /* @@ -431,9 +434,6 @@ 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 -ru dev.bad/ata/files.ata dev/ata/files.ata --- dev.bad/ata/files.ata 2012-07-25 09:16:14.000000000 -0400 +++ dev/ata/files.ata 2012-07-25 09:14:20.000000000 -0400 @@ -1,4 +1,4 @@ -# $NetBSD: files.ata,v 1.22 2012/07/02 18:15:46 bouyer Exp $ +# $NetBSD: files.ata,v 1.21 2009/06/17 03:07:51 jakllsch Exp $ # # Config file and device description for machine-independent devices # which attach to ATA busses. Included by ports that need it. Ports @@ -34,6 +34,3 @@ # 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 -ru dev.bad/ata/sata_subr.c dev/ata/sata_subr.c --- dev.bad/ata/sata_subr.c 2012-07-25 09:16:15.000000000 -0400 +++ dev/ata/sata_subr.c 2012-07-25 09:14:20.000000000 -0400 @@ -1,4 +1,4 @@ -/* $NetBSD: sata_subr.c,v 1.18 2012/07/24 14:04:29 jakllsch Exp $ */ +/* $NetBSD: sata_subr.c,v 1.15 2012/05/15 19:01:10 bouyer Exp $ */ /*- * Copyright (c) 2004 The NetBSD Foundation, Inc. @@ -33,7 +33,7 @@ * Common functions for Serial ATA. */ #include -__KERNEL_RCSID(0, "$NetBSD: sata_subr.c,v 1.18 2012/07/24 14:04:29 jakllsch Exp $"); +__KERNEL_RCSID(0, "$NetBSD: sata_subr.c,v 1.15 2012/05/15 19:01:10 bouyer Exp $"); #include #include @@ -41,7 +41,6 @@ #include #include -#include /* * sata_speed: @@ -147,53 +146,3 @@ } 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 -ru dev.bad/ata/satafis_subr.c dev/ata/satafis_subr.c --- dev.bad/ata/satafis_subr.c 2012-07-25 09:16:15.000000000 -0400 +++ dev/ata/satafis_subr.c 2012-07-25 09:14:20.000000000 -0400 @@ -1,4 +1,4 @@ -/* $NetBSD: satafis_subr.c,v 1.7 2012/07/22 17:57:57 jakllsch Exp $ */ +/* $NetBSD: satafis_subr.c,v 1.6 2012/01/24 20:04:07 jakllsch Exp $ */ /*- * Copyright (c) 2009 Jonathan A. Kollasch. @@ -51,7 +51,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: satafis_subr.c,v 1.7 2012/07/22 17:57:57 jakllsch Exp $"); +__KERNEL_RCSID(0, "$NetBSD: satafis_subr.c,v 1.6 2012/01/24 20:04:07 jakllsch Exp $"); #include #include @@ -81,14 +81,14 @@ fis[rhd_lba1] = (ata_c->r_lba >> 8) & 0xff; fis[rhd_lba2] = (ata_c->r_lba >> 16) & 0xff; if ((ata_c->flags & AT_LBA48) != 0) { - fis[rhd_dh] = ata_c->r_device; + fis[rhd_dh] = WDSD_LBA; fis[rhd_lba3] = (ata_c->r_lba >> 24) & 0xff; fis[rhd_lba4] = (ata_c->r_lba >> 32) & 0xff; fis[rhd_lba5] = (ata_c->r_lba >> 40) & 0xff; fis[rhd_features1] = (ata_c->r_features >> 8) & 0xff; } else { - fis[rhd_dh] = (ata_c->r_device & 0xf0) | - ((ata_c->r_lba >> 24) & 0x0f); + fis[rhd_dh] = ((ata_c->r_lba >> 24) & 0x0f) | + (((ata_c->flags & AT_LBA) != 0) ? WDSD_LBA : 0); } fis[rhd_count0] = (ata_c->r_count >> 0) & 0xff; @@ -170,10 +170,8 @@ ata_c->r_lba |= (uint64_t)fis[rdh_lba3] << 24; ata_c->r_lba |= (uint64_t)fis[rdh_lba4] << 32; ata_c->r_lba |= (uint64_t)fis[rdh_lba5] << 40; - ata_c->r_device = fis[rdh_dh]; } else { ata_c->r_lba |= (uint64_t)(fis[rdh_dh] & 0x0f) << 24; - ata_c->r_device = fis[rdh_dh] & 0xf0; } ata_c->r_count = fis[rdh_count0] << 0; @@ -183,4 +181,6 @@ ata_c->r_error = fis[rdh_error]; ata_c->r_status = fis[rdh_status]; + + ata_c->r_device = fis[rdh_dh] & 0xf0; } Only in dev.bad/ata: satapmp_subr.c diff -ru dev.bad/ata/satapmpreg.h dev/ata/satapmpreg.h --- dev.bad/ata/satapmpreg.h 2012-07-25 09:16:15.000000000 -0400 +++ dev/ata/satapmpreg.h 2012-07-25 09:14:20.000000000 -0400 @@ -1,4 +1,4 @@ -/* $NetBSD: satapmpreg.h,v 1.4 2012/07/02 18:15:46 bouyer Exp $ */ +/* $NetBSD: satapmpreg.h,v 1.3 2008/04/28 20:23:47 martin 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,7 +79,4 @@ #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_ */ Only in dev.bad/ata: satapmpvar.h diff -ru dev.bad/ata/satavar.h dev/ata/satavar.h --- dev.bad/ata/satavar.h 2012-07-25 09:16:15.000000000 -0400 +++ dev/ata/satavar.h 2012-07-25 09:14:20.000000000 -0400 @@ -1,4 +1,4 @@ -/* $NetBSD: satavar.h,v 1.6 2012/07/02 18:15:46 bouyer Exp $ */ +/* $NetBSD: satavar.h,v 1.5 2008/04/28 20:23:47 martin Exp $ */ /*- * Copyright (c) 2004 The NetBSD Foundation, Inc. @@ -42,6 +42,5 @@ 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 -ru dev.bad/ata/wd.c dev/ata/wd.c --- dev.bad/ata/wd.c 2012-07-25 09:21:10.000000000 -0400 +++ dev/ata/wd.c 2012-07-25 09:14:20.000000000 -0400 @@ -1,4 +1,4 @@ -/* $NetBSD: wd.c,v 1.398 2012/07/24 14:04:29 jakllsch Exp $ */ +/* $NetBSD: wd.c,v 1.393 2012/06/26 09:49:24 bouyer Exp $ */ /* * Copyright (c) 1998, 2001 Manuel Bouyer. All rights reserved. @@ -54,7 +54,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: wd.c,v 1.398 2012/07/24 14:04:29 jakllsch Exp $"); +__KERNEL_RCSID(0, "$NetBSD: wd.c,v 1.393 2012/06/26 09:49:24 bouyer Exp $"); #include "opt_ata.h" @@ -107,7 +107,7 @@ #define DEBUG_FUNCS 0x08 #define DEBUG_PROBE 0x10 #ifdef ATADEBUG -int wdcdebug_wd_mask = DEBUG_PROBE; +int wdcdebug_wd_mask = 0x0; #define ATADEBUG_PRINT(args, level) \ if (wdcdebug_wd_mask & (level)) \ printf args @@ -283,8 +283,7 @@ wd->drvp = adev->adev_drv_data; wd->drvp->drv_done = wddone; - wd->drvp->drv_softc = wd->sc_dev; /* done in atabusconfig_thread() - but too late */ + wd->drvp->drv_softc = wd->sc_dev; aprint_naive("\n"); aprint_normal("\n"); @@ -292,7 +291,7 @@ /* read our drive info */ if (wd_get_params(wd, AT_WAIT, &wd->sc_params) != 0) { aprint_error_dev(self, "IDENTIFY failed\n"); - goto out; + return; } for (blank = 0, p = wd->sc_params.atap_model, q = tbuf, i = 0; @@ -381,7 +380,6 @@ 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. */ @@ -463,8 +461,7 @@ callout_destroy(&sc->sc_restart_ch); - sc->drvp->drive_type = DRIVET_NONE; /* no drive any more here */ - sc->drvp->drive_flags = 0; + sc->drvp->drive_flags = 0; /* no drive any more here */ return (0); } @@ -775,7 +772,7 @@ errmsg = "error"; do_perror = 1; retry: /* Just reset and retry. Can we do more ? */ - (*wd->atabus->ata_reset_drive)(wd->drvp, AT_RST_NOCMD, NULL); + (*wd->atabus->ata_reset_drive)(wd->drvp, AT_RST_NOCMD); retry2: diskerr(bp, "wd", errmsg, LOG_PRINTF, wd->sc_wdc_bio.blkdone, wd->sc_dk.dk_label); @@ -899,9 +896,6 @@ 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); @@ -934,15 +928,11 @@ } } else { if ((wd->sc_flags & WDF_LOADED) == 0) { + wd->sc_flags |= WDF_LOADED; /* Load the physical device parameters. */ - 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; + wd_get_params(wd, AT_WAIT, &wd->sc_params); + /* Load the partition info if not already loaded. */ wdgetdisklabel(wd); } @@ -1617,7 +1607,7 @@ if (wddumprecalibrated == 0) { wddumprecalibrated = 1; (*wd->atabus->ata_reset_drive)(wd->drvp, - AT_POLL | AT_RST_EMERG, NULL); + AT_POLL | AT_RST_EMERG); wd->drvp->state = RESET; } @@ -1772,8 +1762,6 @@ 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 @@ -1906,15 +1894,14 @@ return ENODEV; memset(&ata_c, 0, sizeof(struct ata_command)); if ((wd->sc_params.atap_cmd2_en & ATA_CMD2_LBA48) != 0 && - (wd->sc_params.atap_cmd2_en & ATA_CMD2_FCE) != 0) { + (wd->sc_params.atap_cmd2_en & ATA_CMD2_FCE) != 0) ata_c.r_command = WDCC_FLUSHCACHE_EXT; - flags |= AT_LBA48; - } else + else ata_c.r_command = WDCC_FLUSHCACHE; ata_c.r_st_bmask = WDCS_DRDY; ata_c.r_st_pmask = WDCS_DRDY; - ata_c.flags = flags | AT_READREG; - ata_c.timeout = 300000; /* 5m timeout */ + ata_c.flags = flags; + ata_c.timeout = 30000; /* 30s timeout */ if (wd->atabus->ata_exec_command(wd->drvp, &ata_c) != ATACMD_COMPLETE) { aprint_error_dev(wd->sc_dev, "flush cache command didn't complete\n"); diff -ru dev.bad/i2c/ds1307.c dev/i2c/ds1307.c --- dev.bad/i2c/ds1307.c 2012-07-25 09:16:15.000000000 -0400 +++ dev/i2c/ds1307.c 2012-07-25 09:14:22.000000000 -0400 @@ -1,4 +1,4 @@ -/* $NetBSD: ds1307.c,v 1.16 2012/07/25 03:07:37 matt Exp $ */ +/* $NetBSD: ds1307.c,v 1.15 2012/02/23 20:59:19 matt Exp $ */ /* * Copyright (c) 2003 Wasabi Systems, Inc. @@ -36,7 +36,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: ds1307.c,v 1.16 2012/07/25 03:07:37 matt Exp $"); +__KERNEL_RCSID(0, "$NetBSD: ds1307.c,v 1.15 2012/02/23 20:59:19 matt Exp $"); #include #include @@ -251,8 +251,7 @@ sc->sc_address, &cmd, 1, &ch, 1, 0)) != 0) { iic_release_bus(sc->sc_tag, 0); aprint_error_dev(sc->sc_dev, - "%s: read failed at 0x%x: %d\n", - __func__, a, error); + "dsrtc_read: read failed at 0x%x\n", a); return error; } if ((error = uiomove(&ch, 1, uio)) != 0) { @@ -294,8 +293,7 @@ uio->uio_resid ? I2C_OP_WRITE : I2C_OP_WRITE_WITH_STOP, sc->sc_address, cmdbuf, 1, &cmdbuf[1], 1, 0)) != 0) { aprint_error_dev(sc->sc_dev, - "%s: write failed at 0x%x: %d\n", - __func__, a, error); + "dsrtc_write: write failed at 0x%x\n", a); break; } } @@ -344,35 +342,33 @@ { struct dsrtc_model * const dm = &sc->sc_model; uint8_t bcd[DSXXXX_RTC_SIZE], cmdbuf[1]; - int error; KASSERT(DSXXXX_RTC_SIZE >= dm->dm_rtc_size); - if ((error = iic_acquire_bus(sc->sc_tag, I2C_F_POLL)) != 0) { + if (iic_acquire_bus(sc->sc_tag, I2C_F_POLL)) { aprint_error_dev(sc->sc_dev, - "%s: failed to acquire I2C bus: %d\n", - __func__, error); + "dsrtc_clock_read: failed to acquire I2C bus\n"); return 0; } /* Read each RTC register in order. */ - for (u_int i = 0; !error && i < dm->dm_rtc_size; i++) { + for (u_int i = 0; i < dm->dm_rtc_size; i++) { cmdbuf[0] = dm->dm_rtc_start + i; - error = iic_exec(sc->sc_tag, I2C_OP_READ_WITH_STOP, - sc->sc_address, cmdbuf, 1, &bcd[i], 1, I2C_F_POLL); + if (iic_exec(sc->sc_tag, I2C_OP_READ_WITH_STOP, + sc->sc_address, cmdbuf, 1, + &bcd[i], 1, I2C_F_POLL)) { + iic_release_bus(sc->sc_tag, I2C_F_POLL); + aprint_error_dev(sc->sc_dev, + "dsrtc_clock_read: failed to read rtc " + "at 0x%x\n", i); + return 0; + } } /* Done with I2C */ iic_release_bus(sc->sc_tag, I2C_F_POLL); - if (error != 0) { - aprint_error_dev(sc->sc_dev, - "%s: failed to read rtc at 0x%x: %d\n", - __func__, cmdbuf[0], error); - return 0; - } - /* * Convert the RTC's register values into something useable */ @@ -404,7 +400,6 @@ { struct dsrtc_model * const dm = &sc->sc_model; uint8_t bcd[DSXXXX_RTC_SIZE], cmdbuf[2]; - int error; KASSERT(DSXXXX_RTC_SIZE >= dm->dm_rtc_size); @@ -422,33 +417,30 @@ if (dt->dt_year - POSIX_BASE_YEAR >= 100) bcd[DSXXXX_MONTH] |= DSXXXX_MONTH_CENTURY; - if ((error = iic_acquire_bus(sc->sc_tag, I2C_F_POLL)) != 0) { + if (iic_acquire_bus(sc->sc_tag, I2C_F_POLL)) { aprint_error_dev(sc->sc_dev, - "%s: failed to acquire I2C bus: %d\n", - __func__, error); + "dsrtc_clock_write: failed to acquire I2C bus\n"); return 0; } /* Stop the clock */ cmdbuf[0] = dm->dm_ch_reg; - if ((error = iic_exec(sc->sc_tag, I2C_OP_READ, sc->sc_address, - cmdbuf, 1, &cmdbuf[1], 1, I2C_F_POLL)) != 0) { + if (iic_exec(sc->sc_tag, I2C_OP_READ, sc->sc_address, + cmdbuf, 1, &cmdbuf[1], 1, I2C_F_POLL)) { iic_release_bus(sc->sc_tag, I2C_F_POLL); aprint_error_dev(sc->sc_dev, - "%s: failed to read Hold Clock: %d\n", - __func__, error); + "dsrtc_clock_write: failed to read Hold Clock\n"); return 0; } cmdbuf[1] |= dm->dm_ch_value; - if ((error = iic_exec(sc->sc_tag, I2C_OP_WRITE, sc->sc_address, - cmdbuf, 1, &cmdbuf[1], 1, I2C_F_POLL)) != 0) { + if (iic_exec(sc->sc_tag, I2C_OP_WRITE, sc->sc_address, + cmdbuf, 1, &cmdbuf[1], 1, I2C_F_POLL)) { iic_release_bus(sc->sc_tag, I2C_F_POLL); aprint_error_dev(sc->sc_dev, - "%s: failed to write Hold Clock: %d\n", - __func__, error); + "dsrtc_clock_write: failed to write Hold Clock\n"); return 0; } @@ -462,12 +454,12 @@ if (dm->dm_rtc_start + i == dm->dm_ch_reg) { op = I2C_OP_WRITE_WITH_STOP; } - if ((error = iic_exec(sc->sc_tag, op, sc->sc_address, - cmdbuf, 1, &bcd[i], 1, I2C_F_POLL)) != 0) { + if (iic_exec(sc->sc_tag, op, sc->sc_address, + cmdbuf, 1, &bcd[i], 1, I2C_F_POLL)) { iic_release_bus(sc->sc_tag, I2C_F_POLL); aprint_error_dev(sc->sc_dev, - "%s: failed to write rtc at 0x%x: %d\n", - __func__, i, error); + "dsrtc_clock_write: failed to write rtc " + " at 0x%x\n", i); /* XXX: Clock Hold is likely still asserted! */ return 0; } @@ -480,13 +472,11 @@ cmdbuf[0] = dm->dm_ch_reg; cmdbuf[1] &= ~dm->dm_ch_value; - if ((error = iic_exec(sc->sc_tag, I2C_OP_WRITE_WITH_STOP, - sc->sc_address, cmdbuf, 1, &cmdbuf[1], 1, - I2C_F_POLL)) != 0) { + if (iic_exec(sc->sc_tag, I2C_OP_WRITE_WITH_STOP, sc->sc_address, + cmdbuf, 1, &cmdbuf[1], 1, I2C_F_POLL)) { iic_release_bus(sc->sc_tag, I2C_F_POLL); aprint_error_dev(sc->sc_dev, - "%s: failed to Hold Clock: %d\n", - __func__, error); + "dsrtc_clock_write: failed to Hold Clock\n"); return 0; } } @@ -540,37 +530,33 @@ { const struct dsrtc_model * const dm = &sc->sc_model; uint8_t buf[4]; - int error; - if ((error = iic_acquire_bus(sc->sc_tag, I2C_F_POLL)) != 0) { - aprint_error_dev(sc->sc_dev, - "%s: failed to acquire I2C bus: %d\n", - __func__, error); - return 0; + if (iic_acquire_bus(sc->sc_tag, I2C_F_POLL)) { + aprint_error_dev(sc->sc_dev, "%s: failed to acquire I2C bus\n", + __func__); + return (0); } /* read all registers: */ uint8_t reg = dm->dm_rtc_start; - error = iic_exec(sc->sc_tag, I2C_OP_READ_WITH_STOP, sc->sc_address, - ®, 1, buf, 4, I2C_F_POLL); + if (iic_exec(sc->sc_tag, I2C_OP_READ_WITH_STOP, sc->sc_address, ®, 1, + buf, 4, I2C_F_POLL)) { + iic_release_bus(sc->sc_tag, I2C_F_POLL); + aprint_error_dev(sc->sc_dev, "%s: failed to read rtc\n", + __func__); + return (0); + } /* Done with I2C */ iic_release_bus(sc->sc_tag, I2C_F_POLL); - if (error != 0) { - aprint_error_dev(sc->sc_dev, - "%s: failed to read rtc at 0x%x: %d\n", - __func__, reg, error); - return 0; - } - uint32_t v = (buf[3] << 24) | (buf[2] << 16) | (buf[1] << 8) | buf[0]; *tp = v; aprint_debug_dev(sc->sc_dev, "%s: cntr=0x%08"PRIx32"\n", __func__, v); - return 1; + return (1); } static int @@ -579,7 +565,6 @@ const struct dsrtc_model * const dm = &sc->sc_model; size_t buflen = dm->dm_rtc_size + 2; uint8_t buf[buflen]; - int error; KASSERT((dm->dm_flags & DSRTC_FLAG_CLOCK_HOLD) == 0); KASSERT(dm->dm_ch_reg == dm->dm_rtc_start + 4); @@ -591,26 +576,22 @@ buf[4] = (t >> 24) & 0xff; buf[5] = 0; - if ((error = iic_acquire_bus(sc->sc_tag, I2C_F_POLL)) != 0) { - aprint_error_dev(sc->sc_dev, - "%s: failed to acquire I2C bus: %d\n", - __func__, error); - return 0; + if (iic_acquire_bus(sc->sc_tag, I2C_F_POLL)) { + aprint_error_dev(sc->sc_dev, "%s: failed to acquire I2C bus\n", + __func__); + return (0); } - error = iic_exec(sc->sc_tag, I2C_OP_WRITE_WITH_STOP, sc->sc_address, - &buf, buflen, NULL, 0, I2C_F_POLL); - - /* Done with I2C */ - iic_release_bus(sc->sc_tag, I2C_F_POLL); - /* send data */ - if (error != 0) { - aprint_error_dev(sc->sc_dev, - "%s: failed to set time: %d\n", - __func__, error); - return 0; + if (iic_exec(sc->sc_tag, I2C_OP_WRITE_WITH_STOP, sc->sc_address, + &buf, buflen, NULL, 0, I2C_F_POLL)) { + iic_release_bus(sc->sc_tag, I2C_F_POLL); + aprint_error_dev(sc->sc_dev, "%s: failed to set time\n", + __func__); + return (0); } - return 1; + iic_release_bus(sc->sc_tag, I2C_F_POLL); + + return (1); } diff -ru dev.bad/ic/ahcisata_core.c dev/ic/ahcisata_core.c --- dev.bad/ic/ahcisata_core.c 2012-07-25 09:16:15.000000000 -0400 +++ dev/ic/ahcisata_core.c 2012-07-25 09:14:22.000000000 -0400 @@ -1,4 +1,4 @@ -/* $NetBSD: ahcisata_core.c,v 1.38 2012/07/24 14:04:29 jakllsch Exp $ */ +/* $NetBSD: ahcisata_core.c,v 1.34 2012/04/20 20:23:20 bouyer Exp $ */ /* * Copyright (c) 2006 Manuel Bouyer. @@ -26,7 +26,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: ahcisata_core.c,v 1.38 2012/07/24 14:04:29 jakllsch Exp $"); +__KERNEL_RCSID(0, "$NetBSD: ahcisata_core.c,v 1.34 2012/04/20 20:23:20 bouyer Exp $"); #include #include @@ -42,25 +42,21 @@ #include #include #include -#include #include -#include #include /* for SCSI status */ #include "atapibus.h" -#define AHCI_DEBUG #ifdef AHCI_DEBUG -int ahcidebug_mask = 0; +int ahcidebug_mask = 0x0; #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 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_drive(struct ata_drive_datas *, int); 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 *); @@ -75,8 +71,7 @@ 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 *, - int, int); +static void ahci_channel_start(struct ahci_softc *, struct ata_channel *); static void ahci_timeout(void *); static int ahci_dma_setup(struct ata_channel *, int, void *, size_t, int); @@ -211,7 +206,7 @@ void ahci_attach(struct ahci_softc *sc) { - uint32_t ahci_rev, ahci_ports; + uint32_t ahci_cap, ahci_rev, ahci_ports; int i, j, port; struct ahci_channel *achp; struct ata_channel *chp; @@ -224,9 +219,9 @@ if (ahci_reset(sc) != 0) return; - 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_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; ahci_rev = AHCI_READ(sc, AHCI_VS); snprintb(buf, sizeof(buf), "\177\020" /* "f\000\005NP\0" */ @@ -253,7 +248,7 @@ "b\035SSNTF\0" "b\036SNCQ\0" "b\037S64A\0" - "\0", sc->sc_ahci_cap); + "\0", 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), @@ -399,6 +394,7 @@ } } 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 " @@ -546,16 +542,11 @@ 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, 0, 0); + ahci_channel_start(sc, chp); } else { slot = 0; /* XXX */ is = AHCI_READ(sc, AHCI_P_IS(chp->ch_channel)); @@ -572,166 +563,13 @@ } static void -ahci_reset_drive(struct ata_drive_datas *drvp, int flags, uint32_t *sigp) +ahci_reset_drive(struct ata_drive_datas *drvp, int flags) { struct ata_channel *chp = drvp->chnl_softc; - 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); + ata_reset_channel(chp, flags); return; } -/* return error code from ata_bio */ -static int -ahci_exec_fis(struct ata_channel *chp, int timeout, int flags) -{ - struct ahci_channel *achp = (struct ahci_channel *)chp; - struct ahci_softc *sc = (struct ahci_softc *)chp->ch_atac; - int i; - uint32_t is; - - timeout = timeout * 10; /* wait is 10ms */ - AHCI_CMDH_SYNC(sc, achp, 0, BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE); - /* start command */ - AHCI_WRITE(sc, AHCI_P_CI(chp->ch_channel), 1 << 0); - for (i = 0; i < timeout; i++) { - if ((AHCI_READ(sc, AHCI_P_CI(chp->ch_channel)) & 1 << 0) == 0) - return 0; - is = AHCI_READ(sc, AHCI_P_IS(chp->ch_channel)); - if (is & (AHCI_P_IX_TFES | AHCI_P_IX_HBFS | AHCI_P_IX_IFS | - AHCI_P_IX_OFS | AHCI_P_IX_UFS)) { - if ((is & (AHCI_P_IX_DHRS|AHCI_P_IX_TFES)) == - (AHCI_P_IX_DHRS|AHCI_P_IX_TFES)) { - /* - * we got the D2H FIS anyway, - * assume sig is valid. - * channel is restarted later - */ - return ERROR; - } - aprint_debug("%s channel %d: error 0x%x sending FIS\n", - AHCINAME(sc), chp->ch_channel, is); - return ERR_DF; - } - if (flags & AT_WAIT) - tsleep(&sc, PRIBIO, "ahcifis", mstohz(10)); - else - delay(10000); - } - aprint_debug("%s channel %d: timeout sending FIS\n", - AHCINAME(sc), chp->ch_channel); - return TIMEOUT; -} - -static int -ahci_do_reset_drive(struct ata_channel *chp, int drive, int flags, - uint32_t *sigp) -{ - struct ahci_channel *achp = (struct ahci_channel *)chp; - struct ahci_softc *sc = (struct ahci_softc *)chp->ch_atac; - struct ahci_cmd_tbl *cmd_tbl; - struct ahci_cmd_header *cmd_h; - int i; - uint32_t sig; - - KASSERT((AHCI_READ(sc, AHCI_P_CMD(chp->ch_channel)) & AHCI_P_CMD_CR) == 0); - /* clear port interrupt register */ - AHCI_WRITE(sc, AHCI_P_IS(chp->ch_channel), 0xffffffff); - /* clear SErrors and start operations */ - if ((sc->sc_ahci_cap & AHCI_CAP_CLO) == AHCI_CAP_CLO) { - /* - * issue a command list override to clear BSY. - * This is needed if there's a PMP with no drive - * on port 0 - */ - ahci_channel_start(sc, chp, flags, 1); - } else { - ahci_channel_start(sc, chp, flags, 0); - } - if (drive > 0) { - KASSERT(sc->sc_ahci_cap & AHCI_CAP_SPM); - } - /* polled command, assume interrupts are disabled */ - /* use slot 0 to send reset, the channel is idle */ - cmd_h = &achp->ahcic_cmdh[0]; - cmd_tbl = achp->ahcic_cmd_tbl[0]; - cmd_h->cmdh_flags = htole16(AHCI_CMDH_F_RST | AHCI_CMDH_F_CBSY | - RHD_FISLEN / 4 | (drive << AHCI_CMDH_F_PMP_SHIFT)); - cmd_h->cmdh_prdbc = 0; - memset(cmd_tbl->cmdt_cfis, 0, 64); - cmd_tbl->cmdt_cfis[fis_type] = RHD_FISTYPE; - cmd_tbl->cmdt_cfis[rhd_c] = drive; - cmd_tbl->cmdt_cfis[rhd_control] = WDCTL_RST; - switch(ahci_exec_fis(chp, 1, flags)) { - case ERR_DF: - case TIMEOUT: - aprint_error("%s channel %d: setting WDCTL_RST failed " - "for drive %d\n", AHCINAME(sc), chp->ch_channel, drive); - if (sigp) - *sigp = 0xffffffff; - goto end; - default: - break; - } - cmd_h->cmdh_flags = htole16(RHD_FISLEN / 4 | - (drive << AHCI_CMDH_F_PMP_SHIFT)); - cmd_h->cmdh_prdbc = 0; - memset(cmd_tbl->cmdt_cfis, 0, 64); - cmd_tbl->cmdt_cfis[fis_type] = RHD_FISTYPE; - cmd_tbl->cmdt_cfis[rhd_c] = drive; - cmd_tbl->cmdt_cfis[rhd_control] = 0; - switch(ahci_exec_fis(chp, 31, flags)) { - case ERR_DF: - case TIMEOUT: - aprint_error("%s channel %d: clearing WDCTL_RST failed " - "for drive %d\n", AHCINAME(sc), chp->ch_channel, drive); - if (sigp) - *sigp = 0xffffffff; - goto end; - default: - break; - } - /* - * wait 31s for BSY to clear - * This should not be needed, but some controllers clear the - * command slot before receiving the D2H FIS ... - */ - for (i = 0; i ch_channel)); - if ((((sig & AHCI_P_TFD_ST) >> AHCI_P_TFD_ST_SHIFT) - & WDCS_BSY) == 0) - break; - tsleep(&sc, PRIBIO, "ahcid2h", mstohz(10)); - } - if (i == AHCI_RST_WAIT) { - aprint_error("%s: BSY never cleared, TD 0x%x\n", - AHCINAME(sc), sig); - if (sigp) - *sigp = 0xffffffff; - goto end; - } - AHCIDEBUG_PRINT(("%s: BSY took %d ms\n", AHCINAME(sc), i * 10), - DEBUG_PROBE); - sig = AHCI_READ(sc, AHCI_P_SIG(chp->ch_channel)); - if (sigp) - *sigp = sig; - AHCIDEBUG_PRINT(("%s: port %d: sig=0x%x CMD=0x%x\n", - AHCINAME(sc), chp->ch_channel, sig, - AHCI_READ(sc, AHCI_P_CMD(chp->ch_channel))), DEBUG_PROBE); -end: - ahci_channel_stop(sc, chp, flags); - tsleep(&sc, PRIBIO, "ahcirst", mstohz(500)); - /* clear port interrupt register */ - AHCI_WRITE(sc, AHCI_P_IS(chp->ch_channel), 0xffffffff); - ahci_channel_start(sc, chp, AT_WAIT, - (sc->sc_ahci_cap & AHCI_CAP_CLO) ? 1 : 0); - return 0; -} - static void ahci_reset_channel(struct ata_channel *chp, int flags) { @@ -753,7 +591,7 @@ /* clear port interrupt register */ AHCI_WRITE(sc, AHCI_P_IS(chp->ch_channel), 0xffffffff); /* clear SErrors and start operations */ - ahci_channel_start(sc, chp, flags, 1); + ahci_channel_start(sc, chp); /* wait 31s for BSY to clear */ for (i = 0; i ch_channel)); @@ -796,8 +634,15 @@ { 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 | @@ -807,19 +652,39 @@ achp->ahcic_sstatus)) { case SStatus_DET_DEV: tsleep(&sc, PRIBIO, "ahcidv", mstohz(500)); - 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); + /* clear port interrupt register */ + AHCI_WRITE(sc, AHCI_P_IS(chp->ch_channel), 0xffffffff); + /* clear SErrors and start operations */ + ahci_channel_start(sc, chp); + /* wait 31s for BSY to clear */ + for (i = 0; i ch_channel)); + if ((((sig & AHCI_P_TFD_ST) >> AHCI_P_TFD_ST_SHIFT) + & WDCS_BSY) == 0) + break; + tsleep(&sc, PRIBIO, "ahcid2h", mstohz(10)); } - 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); + if (i == AHCI_RST_WAIT) { + aprint_error("%s: BSY never cleared, TD 0x%x\n", + AHCINAME(sc), sig); + return; } + 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 */ @@ -913,7 +778,6 @@ 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), @@ -929,7 +793,7 @@ } cmd_h->cmdh_flags = htole16( ((ata_c->flags & AT_WRITE) ? AHCI_CMDH_F_WR : 0) | - RHD_FISLEN / 4 | (xfer->c_drive << AHCI_CMDH_F_PMP_SHIFT)); + RHD_FISLEN / 4); cmd_h->cmdh_prdbc = 0; AHCI_CMDH_SYNC(sc, achp, slot, BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE); @@ -1135,7 +999,6 @@ 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), @@ -1149,7 +1012,7 @@ } cmd_h->cmdh_flags = htole16( ((ata_bio->flags & ATA_READ) ? 0 : AHCI_CMDH_F_WR) | - RHD_FISLEN / 4 | (xfer->c_drive << AHCI_CMDH_F_PMP_SHIFT)); + RHD_FISLEN / 4); cmd_h->cmdh_prdbc = 0; AHCI_CMDH_SYNC(sc, achp, slot, BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE); @@ -1301,7 +1164,7 @@ == 0) break; if (flags & AT_WAIT) - tsleep(&sc, PRIBIO, "ahcistop", mstohz(10)); + tsleep(&sc, PRIBIO, "ahcirst", mstohz(10)); else delay(10000); } @@ -1313,44 +1176,16 @@ } static void -ahci_channel_start(struct ahci_softc *sc, struct ata_channel *chp, - int flags, int clo) +ahci_channel_start(struct ahci_softc *sc, struct ata_channel *chp) { - 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 */ - 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); + 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); } static void @@ -1543,7 +1378,6 @@ 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); @@ -1560,8 +1394,7 @@ } 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 | - (xfer->c_drive << AHCI_CMDH_F_PMP_SHIFT)); + RHD_FISLEN / 4 | AHCI_CMDH_F_A); cmd_h->cmdh_prdbc = 0; AHCI_CMDH_SYNC(sc, achp, slot, BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE); @@ -1712,7 +1545,7 @@ return; /* if no ATAPI device detected at attach time, skip */ - if (drvp->drive_type != DRIVET_ATAPI) { + if ((drvp->drive_flags & DRIVE_ATAPI) == 0) { AHCIDEBUG_PRINT(("ahci_atapi_probe_device: drive %d " "not present\n", target), DEBUG_PROBE); return; @@ -1751,7 +1584,7 @@ periph->periph_flags |= PERIPH_REMOVABLE; if (periph->periph_type == T_SEQUENTIAL) { s = splbio(); - drvp->drive_flags |= DRIVE_ATAPIDSCW; + drvp->drive_flags |= DRIVE_ATAPIST; splx(s); } @@ -1782,7 +1615,7 @@ ata_probe_caps(drvp); else { s = splbio(); - drvp->drive_type = DRIVET_NONE; + drvp->drive_flags &= ~DRIVE_ATAPI; splx(s); } } else { @@ -1791,7 +1624,7 @@ AHCINAME(ahcic), chp->ch_channel, target, chp->ch_error), DEBUG_PROBE); s = splbio(); - drvp->drive_type = DRIVET_NONE; + drvp->drive_flags &= ~DRIVE_ATAPI; splx(s); } } diff -ru dev.bad/ic/mvsata.c dev/ic/mvsata.c --- dev.bad/ic/mvsata.c 2012-07-25 09:16:15.000000000 -0400 +++ dev/ic/mvsata.c 2012-07-25 09:14:29.000000000 -0400 @@ -1,4 +1,4 @@ -/* $NetBSD: mvsata.c,v 1.22 2012/07/24 14:04:30 jakllsch Exp $ */ +/* $NetBSD: mvsata.c,v 1.16 2012/04/20 20:23:20 bouyer Exp $ */ /* * Copyright (c) 2008 KIYOHARA Takashi * All rights reserved. @@ -26,11 +26,11 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: mvsata.c,v 1.22 2012/07/24 14:04:30 jakllsch Exp $"); +__KERNEL_RCSID(0, "$NetBSD: mvsata.c,v 1.16 2012/04/20 20:23:20 bouyer Exp $"); #include "opt_mvsata.h" -/* ATAPI implementation not finished. */ +/* ATAPI implementation not finished. Also don't work shadow registers? */ //#include "atapibus.h" #include @@ -76,17 +76,13 @@ #define MVSATA_EDMA_WRITE_4(mvport, reg, val) \ bus_space_write_4((mvport)->port_iot, (mvport)->port_ioh, (reg), (val)) #define MVSATA_WDC_READ_2(mvport, reg) \ - bus_space_read_2((mvport)->port_iot, (mvport)->port_ioh, \ - SHADOW_REG_BLOCK_OFFSET + (reg)) + bus_space_read_2((mvport)->port_iot, (mvport)->port_ioh, (reg)) #define MVSATA_WDC_READ_1(mvport, reg) \ - bus_space_read_1((mvport)->port_iot, (mvport)->port_ioh, \ - SHADOW_REG_BLOCK_OFFSET + (reg)) + bus_space_read_1((mvport)->port_iot, (mvport)->port_ioh, (reg)) #define MVSATA_WDC_WRITE_2(mvport, reg, val) \ - bus_space_write_2((mvport)->port_iot, (mvport)->port_ioh, \ - SHADOW_REG_BLOCK_OFFSET + (reg), (val)) + bus_space_write_2((mvport)->port_iot, (mvport)->port_ioh, (reg), (val)) #define MVSATA_WDC_WRITE_1(mvport, reg, val) \ - bus_space_write_1((mvport)->port_iot, (mvport)->port_ioh, \ - SHADOW_REG_BLOCK_OFFSET + (reg), (val)) + bus_space_write_1((mvport)->port_iot, (mvport)->port_ioh, (reg), (val)) #ifdef MVSATA_DEBUG #define DPRINTF(x) if (mvsata_debug) printf x @@ -107,7 +103,7 @@ #ifndef MVSATA_WITHOUTDMA static int mvsata_bio(struct ata_drive_datas *, struct ata_bio *); -static void mvsata_reset_drive(struct ata_drive_datas *, int, uint32_t *); +static void mvsata_reset_drive(struct ata_drive_datas *, int); 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 *); @@ -308,7 +304,6 @@ 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; @@ -524,14 +519,12 @@ } static void -mvsata_reset_drive(struct ata_drive_datas *drvp, int flags, uint32_t *sigp) +mvsata_reset_drive(struct ata_drive_datas *drvp, int flags) { 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", @@ -796,7 +789,7 @@ return; /* if no ATAPI device detected at attach time, skip */ - if (drvp->drive_type != DRIVET_ATAPI) { + if ((drvp->drive_flags & DRIVE_ATAPI) == 0) { DPRINTF(("%s:%d: mvsata_atapi_probe_device:" " drive %d not present\n", device_xname(atac->atac_dev), chp->ch_channel, target)); @@ -837,7 +830,7 @@ periph->periph_flags |= PERIPH_REMOVABLE; if (periph->periph_type == T_SEQUENTIAL) { s = splbio(); - drvp->drive_flags |= DRIVE_ATAPIDSCW; + drvp->drive_flags |= DRIVE_ATAPIST; splx(s); } @@ -867,7 +860,7 @@ ata_probe_caps(drvp); else { s = splbio(); - drvp->drive_type = DRIVET_NONE; + drvp->drive_flags &= ~DRIVE_ATAPI; splx(s); } } else { @@ -876,7 +869,7 @@ device_xname(atac->atac_dev), chp->ch_channel, target, chp->ch_error)); s = splbio(); - drvp->drive_type = DRIVET_NONE; + drvp->drive_flags &= ~DRIVE_ATAPI; splx(s); } } @@ -925,11 +918,11 @@ device_xname(MVSATA_DEV2(mvport)), chp->ch_channel)); edma_mode = nodma; - for (drive = 0; drive < chp->ch_ndrives; drive++) { + for (drive = 0; drive < chp->ch_ndrive; drive++) { drvp = &chp->ch_drive[drive]; /* If no drive, skip */ - if (drvp->drive_type == DRIVET_NONE) + if (!(drvp->drive_flags & DRIVE)) continue; if (drvp->drive_flags & DRIVE_UDMA) { @@ -940,7 +933,7 @@ } if (drvp->drive_flags & (DRIVE_UDMA | DRIVE_DMA)) - if (drvp->drive_type == DRIVET_ATA) + if (drvp->drive_flags & DRIVE_ATA) edma_mode = dma; } @@ -985,11 +978,11 @@ aprint_error_dev(MVSATA_DEV2(mvport), "channel %d: can't use EDMA\n", chp->ch_channel); s = splbio(); - for (drive = 0; drive < chp->ch_ndrives; drive++) { + for (drive = 0; drive < chp->ch_ndrive; drive++) { drvp = &chp->ch_drive[drive]; /* If no drive, skip */ - if (drvp->drive_type == DRIVET_NONE) + if (!(drvp->drive_flags & DRIVE)) continue; drvp->drive_flags &= ~(DRIVE_UDMA | DRIVE_DMA); @@ -1743,7 +1736,7 @@ } ata_c->r_count |= MVSATA_WDC_READ_1(mvport, SRB_SC) << 8; - ata_c->r_lba |= + ata_c->r_lba = (uint64_t)MVSATA_WDC_READ_1(mvport, SRB_LBAL) << 24; ata_c->r_lba |= (uint64_t)MVSATA_WDC_READ_1(mvport, SRB_LBAM) << 32; @@ -2255,7 +2248,7 @@ struct ata_drive_datas *drvp = &chp->ch_drive[xfer->c_drive]; /* wait for DSC if needed */ - if (drvp->drive_flags & DRIVE_ATAPIDSCW) { + if (drvp->drive_flags & DRIVE_ATAPIST) { DPRINTFN(1, ("%s:%d:%d: mvsata_atapi_phase_complete: polldsc %d\n", device_xname(atac->atac_dev), chp->ch_channel, @@ -2830,6 +2823,7 @@ 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 -ru dev.bad/ic/siisata.c dev/ic/siisata.c --- dev.bad/ic/siisata.c 2012-07-25 09:16:15.000000000 -0400 +++ dev/ic/siisata.c 2012-07-25 09:14:29.000000000 -0400 @@ -1,4 +1,4 @@ -/* $NetBSD: siisata.c,v 1.20 2012/07/24 14:04:30 jakllsch Exp $ */ +/* $NetBSD: siisata.c,v 1.17 2012/05/15 19:06:26 bouyer Exp $ */ /* from ahcisata_core.c */ @@ -79,7 +79,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: siisata.c,v 1.20 2012/07/24 14:04:30 jakllsch Exp $"); +__KERNEL_RCSID(0, "$NetBSD: siisata.c,v 1.17 2012/05/15 19:06:26 bouyer Exp $"); #include #include @@ -96,7 +96,6 @@ #include #include #include -#include #include #include @@ -117,7 +116,7 @@ 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, uint32_t *); +void siisata_reset_drive(struct ata_drive_datas *, int); void siisata_reset_channel(struct ata_channel *, int); int siisata_ata_addref(struct ata_drive_datas *); void siisata_ata_delref(struct ata_drive_datas *); @@ -346,6 +345,7 @@ } } + 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,29 +462,23 @@ xfer = chp->ch_queue->active_xfer; slot = SIISATA_NON_NCQ_SLOT; - pis = PRREAD(sc, PRX(chp->ch_channel, PRO_PIS)); + SIISATA_DEBUG_PRINT(("%s: %s port %d\n", + SIISATANAME(sc), __func__, chp->ch_channel), DEBUG_INTR); - SIISATA_DEBUG_PRINT(("%s: %s port %d, pis 0x%x ", - SIISATANAME(sc), __func__, chp->ch_channel, pis), DEBUG_INTR); + pis = PRREAD(sc, PRX(chp->ch_channel, PRO_PIS)); 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) { - aprint_error( "%s: unexpected command " + PRWRITE(sc, PRX(chp->ch_channel, PRO_PIS), 0xffffffff); + log(LOG_WARNING, "%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; @@ -493,9 +487,8 @@ 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 && xfer != NULL) { + if (ec == PR_PCE_DEVICEERROR) { /* read in specific information about error */ prbfis = bus_space_read_stream_4( sc->sc_prt, sc->sc_prh, @@ -505,10 +498,9 @@ } siisata_reinit_port(chp); } else { - 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))); + aprint_error_dev(sc->sc_atac.atac_dev, + "fatal error %d on channel %d, resetting\n", + ec, chp->ch_channel); /* okay, we have a "Fatal Error" */ siisata_device_reset(chp); } @@ -523,7 +515,7 @@ } void -siisata_reset_drive(struct ata_drive_datas *drvp, int flags, uint32_t *sigp) +siisata_reset_drive(struct ata_drive_datas *drvp, int flags) { struct ata_channel *chp = drvp->chnl_softc; struct siisata_softc *sc = (struct siisata_softc *)chp->ch_atac; @@ -540,37 +532,21 @@ 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 < 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)); + for(i = 0; i < 31000; i++) { + if (PRREAD(sc, PRX(chp->ch_channel, PRO_PSS)) & + PR_PXSS(slot)) + DELAY(1000); else - DELAY(10000); + break; } siisata_deactivate_prb(schp, slot); - 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; - } - } + + log(LOG_DEBUG, "%s: port %d: ch_status %x ch_error %x\n", + __func__, chp->ch_channel, chp->ch_status, chp->ch_error); #if 1 /* attempt to downgrade signaling in event of CRC error */ @@ -595,6 +571,7 @@ chp->ch_status = 0; chp->ch_error = 0; #endif + return; } @@ -650,6 +627,7 @@ 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; @@ -658,6 +636,12 @@ 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 @@ -677,7 +661,6 @@ 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); @@ -720,10 +703,28 @@ SIISATA_DEBUG_PRINT(("%s: %s: sig=0x%08x\n", SIISATANAME(sc), __func__, sig), DEBUG_PROBE); - if (sig == 0x96690101) - PRWRITE(sc, PRX(chp->ch_channel, PRO_PCS), - PR_PC_PMP_ENABLE); - sata_interpret_sig(chp, 0, sig); + /* 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); break; default: break; @@ -807,11 +808,8 @@ struct siisata_prb *prb; int i; - 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); + SIISATA_DEBUG_PRINT(("%s: %s port %d, slot %d\n", + SIISATANAME(sc), __func__, chp->ch_channel, slot), DEBUG_FUNCS); chp->ch_status = 0; chp->ch_error = 0; @@ -820,8 +818,6 @@ 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)); @@ -861,14 +857,15 @@ } if ((ata_c->flags & AT_DONE) == 0) { - siisata_timeout(chp); + ata_c->flags |= AT_TIMEOU; + siisata_cmd_complete(chp, xfer, slot); } /* reenable interrupts */ siisata_enable_port_interrupt(chp); out: SIISATA_DEBUG_PRINT( - ("%s: %s: done\n", SIISATANAME((struct siisata_softc *)chp->ch_atac), __func__), DEBUG_FUNCS); + ("%s: %s: done\n", SIISATANAME(sc), __func__), DEBUG_FUNCS); return; } @@ -902,7 +899,7 @@ #endif SIISATA_DEBUG_PRINT( - ("%s: %s\n", SIISATANAME(sc), __func__), DEBUG_FUNCS|DEBUG_XFERS); + ("%s: %s\n", SIISATANAME(sc), __func__), DEBUG_FUNCS); chp->ch_flags &= ~ATACH_IRQ_WAIT; if (xfer->c_flags & C_TIMEOU) @@ -939,8 +936,7 @@ int i; SIISATA_DEBUG_PRINT( - ("%s: %s flags 0x%x error 0x%x\n", SIISATANAME(sc), __func__, - ata_c->flags, ata_c->r_error), DEBUG_FUNCS|DEBUG_XFERS); + ("%s: %s.\n", SIISATANAME(sc), __func__), DEBUG_FUNCS); siisata_deactivate_prb(schp, slot); @@ -1020,7 +1016,7 @@ SIISATA_DEBUG_PRINT( ("%s: %s port %d, slot %d\n", - SIISATANAME((struct siisata_softc *)chp->ch_atac), __func__, chp->ch_channel, slot), + SIISATANAME(sc), __func__, chp->ch_channel, slot), DEBUG_FUNCS); chp->ch_status = 0; @@ -1030,8 +1026,6 @@ 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)); @@ -1071,7 +1065,7 @@ siisata_enable_port_interrupt(chp); out: SIISATA_DEBUG_PRINT( - ("%s: %s: done\n", SIISATANAME((struct siisata_softc *)chp->ch_atac), __func__), DEBUG_FUNCS); + ("%s: %s: done\n", SIISATANAME(sc), __func__), DEBUG_FUNCS); return; } @@ -1173,7 +1167,6 @@ 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); @@ -1277,8 +1270,6 @@ 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 @@ -1395,7 +1386,7 @@ return; /* if no ATAPI device detected at attach time, skip */ - if (drvp->drive_type == DRIVET_ATAPI) { + if ((drvp->drive_flags & DRIVE_ATAPI) == 0) { SIISATA_DEBUG_PRINT(("%s: drive %d " "not present\n", __func__, target), DEBUG_PROBE); return; @@ -1433,6 +1424,12 @@ 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 ? @@ -1470,7 +1467,7 @@ ata_probe_caps(drvp); else { s = splbio(); - drvp->drive_type &= DRIVET_NONE; + drvp->drive_flags &= ~DRIVE_ATAPI; splx(s); } } else { @@ -1479,7 +1476,7 @@ __func__, SIISATANAME(siic), chp->ch_channel, target, chp->ch_error), DEBUG_PROBE); s = splbio(); - drvp->drive_type &= DRIVET_NONE; + drvp->drive_flags &= ~DRIVE_ATAPI; splx(s); } } @@ -1558,7 +1555,7 @@ int i; SIISATA_DEBUG_PRINT( ("%s: %s:%d:%d, scsi flags 0x%x\n", __func__, - SIISATANAME((struct siisata_softc *)chp->ch_atac), chp->ch_channel, + SIISATANAME(sc), chp->ch_channel, chp->ch_drive[xfer->c_drive].drive, sc_xfer->xs_control), DEBUG_XFERS); @@ -1576,8 +1573,6 @@ 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); @@ -1616,13 +1611,14 @@ DELAY(1000); } if ((sc_xfer->xs_status & XS_STS_DONE) == 0) { - siisata_timeout(chp); + sc_xfer->error = XS_TIMEOUT; + siisata_atapi_complete(chp, xfer, slot); } /* reenable interrupts */ siisata_enable_port_interrupt(chp); out: SIISATA_DEBUG_PRINT( - ("%s: %s: done\n", SIISATANAME((struct siisata_softc *)chp->ch_atac), __func__), DEBUG_FUNCS); + ("%s: %s: done\n", SIISATANAME(sc), __func__), DEBUG_FUNCS); return; } diff -ru dev.bad/ic/wdc.c dev/ic/wdc.c --- dev.bad/ic/wdc.c 2012-07-25 09:16:15.000000000 -0400 +++ dev/ic/wdc.c 2012-07-25 09:14:29.000000000 -0400 @@ -1,4 +1,4 @@ -/* $NetBSD: wdc.c,v 1.271 2012/07/24 14:04:30 jakllsch Exp $ */ +/* $NetBSD: wdc.c,v 1.268 2012/01/24 20:04:08 jakllsch Exp $ */ /* * Copyright (c) 1998, 2001, 2003 Manuel Bouyer. All rights reserved. @@ -58,7 +58,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: wdc.c,v 1.271 2012/07/24 14:04:30 jakllsch Exp $"); +__KERNEL_RCSID(0, "$NetBSD: wdc.c,v 1.268 2012/01/24 20:04:08 jakllsch Exp $"); #include "opt_ata.h" #include "opt_wdc.h" @@ -208,7 +208,11 @@ uint8_t st = 0, sc, sn, cl, ch; int i, s; - KASSERT(chp->ch_ndrives == 0 || chp->ch_drive != NULL); + /* 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; + } /* reset the PHY and bring online */ switch (sata_reset_interface(chp, wdr->sata_iot, wdr->sata_control, @@ -240,17 +244,15 @@ "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_type = DRIVET_ATAPI; + chp->ch_drive[0].drive_flags |= DRIVE_ATAPI; else - chp->ch_drive[0].drive_type = DRIVET_ATA; + chp->ch_drive[0].drive_flags |= DRIVE_ATA; splx(s); /* @@ -258,7 +260,7 @@ * is up */ if (wdcreset(chp, RESET_SLEEP) != 0) - chp->ch_drive[0].drive_type = DRIVET_NONE; + chp->ch_drive[0].drive_flags = 0; break; default: @@ -292,11 +294,8 @@ 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; } @@ -307,8 +306,7 @@ * select drive 1 first, so that master is selected on * exit from the loop */ - if (chp->ch_ndrives > 1 && - chp->ch_drive[1].drive_type == DRIVET_ATA) { + if (chp->ch_drive[1].drive_flags & (DRIVE_ATA|DRIVE_OLD)) { if (wdc->select) wdc->select(chp,1); bus_space_write_1(wdr->cmd_iot, wdr->cmd_iohs[wd_sdh], @@ -317,7 +315,7 @@ st1 = bus_space_read_1(wdr->cmd_iot, wdr->cmd_iohs[wd_status], 0); } - if (chp->ch_drive[0].drive_type == DRIVET_ATA) { + if (chp->ch_drive[0].drive_flags & (DRIVE_ATA|DRIVE_OLD)) { if (wdc->select) wdc->select(chp,0); bus_space_write_1(wdr->cmd_iot, wdr->cmd_iohs[wd_sdh], @@ -328,11 +326,12 @@ } - 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))) + 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))) break; #ifdef WDC_NO_IDS /* cannot tsleep here (can't enable IPL_BIO interrups), @@ -343,12 +342,10 @@ tsleep(¶ms, PRIBIO, "atadrdy", 1); #endif } - 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; + if ((st0 & WDCS_DRDY) == 0) + chp->ch_drive[0].drive_flags &= ~(DRIVE_ATA|DRIVE_OLD); + if ((st1 & WDCS_DRDY) == 0) + chp->ch_drive[1].drive_flags &= ~(DRIVE_ATA|DRIVE_OLD); splx(s); ATADEBUG_PRINT(("%s:%d: wait DRDY st0 0x%x st1 0x%x\n", @@ -358,7 +355,11 @@ /* Wait a bit, some devices are weird just after a reset. */ delay(5000); - for (i = 0; i < chp->ch_ndrives; i++) { + 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; + #if NATA_DMA /* * Init error counter so that an error withing the first xfers @@ -374,7 +375,7 @@ chp->ch_drive[i].drive_flags |= DRIVE_CAP32; splx(s); } - if (chp->ch_drive[i].drive_type == DRIVET_NONE) + if ((chp->ch_drive[i].drive_flags & DRIVE) == 0) continue; /* Shortcut in case we've been shutdown */ @@ -399,17 +400,22 @@ error = ata_get_params(&chp->ch_drive[i], AT_WAIT | AT_POLL, ¶ms); } - if (error != CMD_OK) { + 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); ATADEBUG_PRINT(("%s:%d:%d: IDENTIFY failed (%d)\n", device_xname(atac->atac_dev), chp->ch_channel, i, error), DEBUG_PROBE); - 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; + if ((chp->ch_drive[i].drive_flags & DRIVE_OLD) == 0) continue; - } - splx(s); /* * Pre-ATA drive ? * Test registers writability (Error register not @@ -433,7 +439,7 @@ device_xname(atac->atac_dev), chp->ch_channel, i), DEBUG_PROBE); s = splbio(); - chp->ch_drive[i].drive_type = DRIVET_NONE; + chp->ch_drive[i].drive_flags &= ~DRIVE_OLD; splx(s); continue; } @@ -442,7 +448,7 @@ device_xname(atac->atac_dev), chp->ch_channel, i), DEBUG_PROBE); s = splbio(); - chp->ch_drive[i].drive_type = DRIVET_NONE; + chp->ch_drive[i].drive_flags &= ~DRIVE_OLD; splx(s); continue; } @@ -454,17 +460,13 @@ device_xname(atac->atac_dev), chp->ch_channel, i), DEBUG_PROBE); s = splbio(); - chp->ch_drive[i].drive_type = DRIVET_NONE; + chp->ch_drive[i].drive_flags &= ~DRIVE_OLD; splx(s); } else { s = splbio(); - 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; - } - } + for (j = 0; j < chp->ch_ndrive; j++) + chp->ch_drive[j].drive_flags &= + ~(DRIVE_ATA | DRIVE_ATAPI); splx(s); } } @@ -722,7 +724,7 @@ * be something here assume it's ATA or OLD. Ghost will be killed * later in attach routine. */ - for (drive = 0; drive < wdc->wdc_maxdrives; drive++) { + for (drive = 0; drive < chp->ch_ndrive; drive++) { if ((ret_value & (0x01 << drive)) == 0) continue; if (wdc->select) @@ -748,12 +750,12 @@ * sc & sn are supposed to be 0x1 for ATAPI but in some cases * we get wrong values here, so ignore it. */ - 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; - } + 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; } } /* @@ -776,7 +778,7 @@ struct atac_softc *atac = chp->ch_atac; struct wdc_softc *wdc = CHAN_TO_WDC(chp); - KASSERT(wdc->wdc_maxdrives > 0 && wdc->wdc_maxdrives <= WDC_MAXDRIVES); + KASSERT(chp->ch_ndrive > 0 && chp->ch_ndrive < 3); /* default data transfer methods */ if (wdc->datain_pio == NULL) @@ -914,12 +916,10 @@ /* Put all disk in RESET state */ void -wdc_reset_drive(struct ata_drive_datas *drvp, int flags, uint32_t *sigp) +wdc_reset_drive(struct ata_drive_datas *drvp, int flags) { 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,10 +1037,8 @@ #endif wdc->reset(chp, poll); - 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_mask1 = (chp->ch_drive[0].drive_flags & DRIVE) ? 0x01:0x00; + drv_mask1 |= (chp->ch_drive[1].drive_flags & DRIVE) ? 0x02:0x00; drv_mask2 = __wdcwait_reset(chp, drv_mask1, (poll == RESET_SLEEP) ? 0 : 1); if (drv_mask2 != drv_mask1) { diff -ru dev.bad/ic/wdc_upc.c dev/ic/wdc_upc.c --- dev.bad/ic/wdc_upc.c 2012-07-25 09:16:15.000000000 -0400 +++ dev/ic/wdc_upc.c 2012-07-25 09:14:29.000000000 -0400 @@ -1,4 +1,4 @@ -/* $NetBSD: wdc_upc.c,v 1.27 2012/07/02 18:15:47 bouyer Exp $ */ +/* $NetBSD: wdc_upc.c,v 1.26 2009/01/25 14:34:14 bjh21 Exp $ */ /*- * Copyright (c) 2000 Ben Harris * All rights reserved. @@ -28,7 +28,7 @@ /* This file is part of NetBSD/arm26 -- a port of NetBSD to ARM2/3 machines. */ #include -__KERNEL_RCSID(0, "$NetBSD: wdc_upc.c,v 1.27 2012/07/02 18:15:47 bouyer Exp $"); +__KERNEL_RCSID(0, "$NetBSD: wdc_upc.c,v 1.26 2009/01/25 14:34:14 bjh21 Exp $"); #include #include @@ -89,7 +89,7 @@ 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_wdc.wdc_maxdrives = 2; + sc->sc_channel.ch_ndrive = 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 -ru dev.bad/ic/wdcvar.h dev/ic/wdcvar.h --- dev.bad/ic/wdcvar.h 2012-07-25 09:16:15.000000000 -0400 +++ dev/ic/wdcvar.h 2012-07-25 09:14:29.000000000 -0400 @@ -1,4 +1,4 @@ -/* $NetBSD: wdcvar.h,v 1.93 2012/07/02 18:15:47 bouyer Exp $ */ +/* $NetBSD: wdcvar.h,v 1.92 2012/01/09 01:01:49 jakllsch Exp $ */ /*- * Copyright (c) 1998, 2003, 2004 The NetBSD Foundation, Inc. @@ -43,8 +43,6 @@ #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; @@ -76,9 +74,7 @@ struct wdc_regs *regs; /* register array (per-channel) */ - int wdc_maxdrives; /* max number of drives per channel */ - - int cap; /* controller capabilities */ + 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 */ @@ -168,7 +164,7 @@ 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, uint32_t *); +void wdc_reset_drive(struct ata_drive_datas *, int); void wdc_reset_channel(struct ata_channel *, int); void wdc_do_reset(struct ata_channel *, int); diff -ru dev.bad/pci/pciide_common.c dev/pci/pciide_common.c --- dev.bad/pci/pciide_common.c 2012-07-25 09:16:17.000000000 -0400 +++ dev/pci/pciide_common.c 2012-07-25 09:14:40.000000000 -0400 @@ -1,4 +1,4 @@ -/* $NetBSD: pciide_common.c,v 1.55 2012/07/24 14:04:31 jakllsch Exp $ */ +/* $NetBSD: pciide_common.c,v 1.52 2012/01/30 19:41:22 drochner Exp $ */ /* @@ -70,7 +70,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: pciide_common.c,v 1.55 2012/07/24 14:04:31 jakllsch Exp $"); +__KERNEL_RCSID(0, "$NetBSD: pciide_common.c,v 1.52 2012/01/30 19:41:22 drochner Exp $"); #include #include @@ -203,7 +203,7 @@ cp->ctl_baseioh, cp->ctl_ios); } - for (drive = 0; drive < sc->sc_wdcdev.wdc_maxdrives; drive++) { + for (drive = 0; drive < cp->ata_channel.ch_ndrive; drive++) { #if NATA_DMA pciide_dma_table_teardown(sc, channel, drive); #endif @@ -568,12 +568,12 @@ struct pciide_softc *sc = CHAN_TO_PCIIDE(&cp->ata_channel); struct ata_drive_datas *drvp; - KASSERT(cp->ata_channel.ch_ndrives != 0); + KASSERT(cp->ata_channel.ch_ndrive != 0); - for (drive = 0; drive < cp->ata_channel.ch_ndrives; drive++) { + for (drive = 0; drive < cp->ata_channel.ch_ndrive; drive++) { drvp = &cp->ata_channel.ch_drive[drive]; /* If no drive, skip */ - if (drvp->drive_type == DRIVET_NONE) + if ((drvp->drive_flags & DRIVE) == 0) continue; /* setup DMA if needed */ if (((drvp->drive_flags & DRIVE_DMA) == 0 && @@ -875,6 +875,7 @@ 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)) ? @@ -995,7 +996,6 @@ 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 @@ channel++) { idedma_ctl = 0; cp = &sc->pciide_channels[channel]; - for (drive = 0; drive < sc->sc_wdcdev.wdc_maxdrives; drive++) { + for (drive = 0; drive < cp->ata_channel.ch_ndrive; drive++) { /* * we have not probed the drives yet, allocate * ressources for all of them. @@ -1116,11 +1116,10 @@ idedma_ctl = 0; - KASSERT(cp->ata_channel.ch_ndrives != 0); - for (drive = 0; drive < cp->ata_channel.ch_ndrives; drive++) { + for (drive = 0; drive < cp->ata_channel.ch_ndrive; drive++) { drvp = &chp->ch_drive[drive]; /* If no drive, skip */ - if (drvp->drive_type == DRIVET_NONE) + if ((drvp->drive_flags & DRIVE) == 0) continue; #if NATA_UDMA if (drvp->drive_flags & DRIVE_UDMA) { diff -ru dev.bad/pci/pciidevar.h dev/pci/pciidevar.h --- dev.bad/pci/pciidevar.h 2012-07-25 09:16:17.000000000 -0400 +++ dev/pci/pciidevar.h 2012-07-25 09:14:40.000000000 -0400 @@ -1,4 +1,4 @@ -/* $NetBSD: pciidevar.h,v 1.44 2012/07/02 18:15:47 bouyer Exp $ */ +/* $NetBSD: pciidevar.h,v 1.43 2011/04/04 20:37:56 dyoung Exp $ */ /* * Copyright (c) 1998 Christopher G. Demetriou. All rights reserved. @@ -142,7 +142,7 @@ struct idedma_table *dma_table; bus_dmamap_t dmamap_xfer; int dma_flags; - } dma_maps[WDC_MAXDRIVES]; + } dma_maps[ATA_MAXDRIVES]; bus_space_handle_t dma_iohs[IDEDMA_NREGS]; /* * Some controllers require certain bits to diff -ru dev.bad/pci/piixide.c dev/pci/piixide.c --- dev.bad/pci/piixide.c 2012-07-25 09:16:17.000000000 -0400 +++ dev/pci/piixide.c 2012-07-25 09:14:41.000000000 -0400 @@ -1,4 +1,4 @@ -/* $NetBSD: piixide.c,v 1.61 2012/07/24 14:04:31 jakllsch Exp $ */ +/* $NetBSD: piixide.c,v 1.58 2012/03/05 16:21:44 sborrill Exp $ */ /* * Copyright (c) 1999, 2000, 2001 Manuel Bouyer. @@ -25,7 +25,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: piixide.c,v 1.61 2012/07/24 14:04:31 jakllsch Exp $"); +__KERNEL_RCSID(0, "$NetBSD: piixide.c,v 1.58 2012/03/05 16:21:44 sborrill Exp $"); #include #include @@ -486,7 +486,6 @@ 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)), @@ -677,7 +676,7 @@ */ for (drive = 0; drive < 2; drive++) { /* If no drive, skip */ - if (drvp[drive].drive_type == DRIVET_NONE) + if ((drvp[drive].drive_flags & DRIVE) == 0) continue; idetim |= piix_setup_idetim_drvs(&drvp[drive]); if (drvp[drive].drive_flags & DRIVE_DMA) @@ -722,7 +721,7 @@ PIIX_UDMATIM_SET(0x3, channel, drive)); drvp = &chp->ch_drive[drive]; /* If no drive, skip */ - if (drvp->drive_type == DRIVET_NONE) + if ((drvp->drive_flags & DRIVE) == 0) continue; if (((drvp->drive_flags & DRIVE_DMA) == 0 && (drvp->drive_flags & DRIVE_UDMA) == 0)) @@ -944,7 +943,6 @@ 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 -ru dev.bad/scsipi/atapi_wdc.c dev/scsipi/atapi_wdc.c --- dev.bad/scsipi/atapi_wdc.c 2012-07-25 09:16:17.000000000 -0400 +++ dev/scsipi/atapi_wdc.c 2012-07-25 09:14:45.000000000 -0400 @@ -1,4 +1,4 @@ -/* $NetBSD: atapi_wdc.c,v 1.116 2012/07/24 14:04:32 jakllsch Exp $ */ +/* $NetBSD: atapi_wdc.c,v 1.113 2012/04/20 20:23:21 bouyer Exp $ */ /* * Copyright (c) 1998, 2001 Manuel Bouyer. @@ -25,7 +25,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: atapi_wdc.c,v 1.116 2012/07/24 14:04:32 jakllsch Exp $"); +__KERNEL_RCSID(0, "$NetBSD: atapi_wdc.c,v 1.113 2012/04/20 20:23:21 bouyer Exp $"); #ifndef ATADEBUG #define ATADEBUG @@ -199,7 +199,7 @@ struct ata_command ata_c; /* if no ATAPI device detected at wdc attach time, skip */ - if (chp->ch_drive[drive].drive_type != DRIVET_ATAPI) { + if ((chp->ch_drive[drive].drive_flags & DRIVE_ATAPI) == 0) { ATADEBUG_PRINT(("wdc_atapi_get_params: drive %d not present\n", drive), DEBUG_PROBE); return -1; @@ -290,7 +290,7 @@ periph->periph_flags |= PERIPH_REMOVABLE; if (periph->periph_type == T_SEQUENTIAL) { s = splbio(); - drvp->drive_flags |= DRIVE_ATAPIDSCW; + drvp->drive_flags |= DRIVE_ATAPIST; splx(s); } @@ -321,12 +321,12 @@ ata_probe_caps(drvp); else { s = splbio(); - drvp->drive_type = DRIVET_NONE; + drvp->drive_flags &= ~DRIVE_ATAPI; splx(s); } } else { s = splbio(); - drvp->drive_type = DRIVET_NONE; + drvp->drive_flags &= ~DRIVE_ATAPI; splx(s); } } @@ -995,7 +995,7 @@ struct ata_drive_datas *drvp = &chp->ch_drive[xfer->c_drive]; /* wait for DSC if needed */ - if (drvp->drive_flags & DRIVE_ATAPIDSCW) { + if (drvp->drive_flags & DRIVE_ATAPIST) { ATADEBUG_PRINT(("wdc_atapi_phase_complete(%s:%d:%d) " "polldsc %d\n", device_xname(atac->atac_dev), chp->ch_channel, diff -ru dev.bad/usb/umass_isdata.c dev/usb/umass_isdata.c --- dev.bad/usb/umass_isdata.c 2012-07-25 09:16:17.000000000 -0400 +++ dev/usb/umass_isdata.c 2012-07-25 09:14:47.000000000 -0400 @@ -1,4 +1,4 @@ -/* $NetBSD: umass_isdata.c,v 1.25 2012/07/24 14:04:32 jakllsch Exp $ */ +/* $NetBSD: umass_isdata.c,v 1.22 2012/03/04 00:21:20 mrg Exp $ */ /* * TODO: @@ -37,7 +37,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: umass_isdata.c,v 1.25 2012/07/24 14:04:32 jakllsch Exp $"); +__KERNEL_RCSID(0, "$NetBSD: umass_isdata.c,v 1.22 2012/03/04 00:21:20 mrg Exp $"); #ifdef _KERNEL_OPT #include "opt_umass.h" @@ -110,7 +110,7 @@ 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, uint32_t *); +void uisdata_reset_drive(struct ata_drive_datas *, int); 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 @@ adev.adev_channel = 1; /* XXX */ adev.adev_openings = 1; adev.adev_drv_data = &scbus->sc_drv_data; - scbus->sc_drv_data.drive_type = DRIVET_ATA; + scbus->sc_drv_data.drive_flags = DRIVE_ATA; scbus->sc_drv_data.chnl_softc = sc; scbus->base.sc_child = config_found(sc->sc_dev, &adev, uwdprint); @@ -376,10 +376,9 @@ } void -uisdata_reset_drive(struct ata_drive_datas *drv, int flags, uint32_t *sigp) +uisdata_reset_drive(struct ata_drive_datas *drv, int flags) { DPRINTFN(-1,("%s\n", __func__)); - KASSERT(sigp == NULL); /* XXX what? */ }