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 <sys/cdefs.h>
-__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 <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
 #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 <sys/cdefs.h>
-__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 <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.
  */
@@ -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 <sys/cdefs.h>
-__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 <sys/param.h>
 #include <sys/kernel.h>
@@ -41,7 +41,6 @@
 
 #include <dev/ata/satareg.h>
 #include <dev/ata/satavar.h>
-#include <dev/ata/satapmpreg.h>
 
 /*
  * 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 <sys/cdefs.h>
-__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 <sys/param.h>
 #include <sys/systm.h>
@@ -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 <sys/cdefs.h>
-__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 <sys/cdefs.h>
-__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 <sys/param.h>
 #include <sys/systm.h>
@@ -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,
-	     &reg, 1, buf, 4, I2C_F_POLL);
+	if (iic_exec(sc->sc_tag, I2C_OP_READ_WITH_STOP, sc->sc_address, &reg, 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 <sys/cdefs.h>
-__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 <sys/types.h>
 #include <sys/malloc.h>
@@ -42,25 +42,21 @@
 #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 = 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 <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)
 {
@@ -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 <AHCI_RST_WAIT; i++) {
 		tfd = AHCI_READ(sc, AHCI_P_TFD(chp->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 <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));
 		}
-		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 <sys/cdefs.h>
-__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 <sys/param.h>
@@ -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 <sys/cdefs.h>
-__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 <sys/types.h>
 #include <sys/malloc.h>
@@ -96,7 +96,6 @@
 #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>
 
@@ -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 <sys/cdefs.h>
-__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(&params, 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, &params);
 		}
-		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 <sys/cdefs.h>
-__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 <sys/param.h>
 #include <sys/device.h>
@@ -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 <sys/cdefs.h>
-__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 <sys/param.h>
 #include <sys/malloc.h>
@@ -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 <sys/cdefs.h>
-__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 <sys/param.h>
 #include <sys/systm.h>
@@ -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 <sys/cdefs.h>
-__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 <sys/cdefs.h>
-__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? */
 }