Module Name:    src
Committed By:   jdolecek
Date:           Sat Apr 15 17:14:11 UTC 2017

Modified Files:
        src/sys/dev/ata [jdolecek-ncq]: ata.c atavar.h satapmp_subr.c wd.c
        src/sys/dev/ic [jdolecek-ncq]: ahcisata_core.c mvsata.c siisata.c wdc.c
            wdcvar.h
        src/sys/dev/scsipi [jdolecek-ncq]: atapi_wdc.c

Log Message:
pass also ata_command via ata_xfer, callers of ata_exec_command() is now
responsible for allocation/disposal of the structure

change code to allocate ata_xfer for commands on stack same way as previously
the ata_command were, using c_slot 0; adjust asserts so that it would allow
several xfers with same c_slot, as long as only one such transfer is active
at a time


To generate a diff of this commit:
cvs rdiff -u -r1.132.8.3 -r1.132.8.4 src/sys/dev/ata/ata.c
cvs rdiff -u -r1.92.8.3 -r1.92.8.4 src/sys/dev/ata/atavar.h
cvs rdiff -u -r1.12 -r1.12.24.1 src/sys/dev/ata/satapmp_subr.c
cvs rdiff -u -r1.428.2.3 -r1.428.2.4 src/sys/dev/ata/wd.c
cvs rdiff -u -r1.57.6.3 -r1.57.6.4 src/sys/dev/ic/ahcisata_core.c
cvs rdiff -u -r1.35.6.4 -r1.35.6.5 src/sys/dev/ic/mvsata.c
cvs rdiff -u -r1.30.4.3 -r1.30.4.4 src/sys/dev/ic/siisata.c
cvs rdiff -u -r1.283.2.2 -r1.283.2.3 src/sys/dev/ic/wdc.c
cvs rdiff -u -r1.97 -r1.97.26.1 src/sys/dev/ic/wdcvar.h
cvs rdiff -u -r1.123.4.2 -r1.123.4.3 src/sys/dev/scsipi/atapi_wdc.c

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/sys/dev/ata/ata.c
diff -u src/sys/dev/ata/ata.c:1.132.8.3 src/sys/dev/ata/ata.c:1.132.8.4
--- src/sys/dev/ata/ata.c:1.132.8.3	Sat Apr 15 12:01:23 2017
+++ src/sys/dev/ata/ata.c	Sat Apr 15 17:14:11 2017
@@ -1,4 +1,4 @@
-/*	$NetBSD: ata.c,v 1.132.8.3 2017/04/15 12:01:23 jdolecek Exp $	*/
+/*	$NetBSD: ata.c,v 1.132.8.4 2017/04/15 17:14:11 jdolecek 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.132.8.3 2017/04/15 12:01:23 jdolecek Exp $");
+__KERNEL_RCSID(0, "$NetBSD: ata.c,v 1.132.8.4 2017/04/15 17:14:11 jdolecek Exp $");
 
 #include "opt_ata.h"
 
@@ -192,10 +192,18 @@ ata_queue_reset(struct ata_queue *chq)
 struct ata_xfer *
 ata_queue_hwslot_to_xfer(struct ata_queue *chq, int hwslot)
 {
+	struct ata_xfer *xfer;
+
 	KASSERT(hwslot < chq->queue_openings);
-	KASSERT((chq->queue_xfers_avail & __BIT(hwslot)) == 0);
+	KASSERT(hwslot == 0 || (chq->queue_xfers_avail & __BIT(hwslot)) == 0);
+
+	/* Usually the first entry will be the one */
+	TAILQ_FOREACH(xfer, &chq->active_xfers, c_activechain) {
+		if (xfer->c_slot == hwslot)
+			return xfer;
+	}
 
-	return &chq->queue_xfers[hwslot];
+	panic("%s: xfer with slot %d not found", __func__, hwslot);
 }
 
 struct ata_queue *
@@ -204,7 +212,7 @@ ata_queue_alloc(int openings)
 	if (openings == 0)
 		openings = 1;
 	struct ata_queue *chq = malloc(offsetof(struct ata_queue, queue_xfers[openings]),
-	    M_DEVBUF, M_WAITOK);
+	    M_DEVBUF, M_WAITOK | M_ZERO);
 	if (chq != NULL) {
 		chq->queue_openings = openings;
 		chq->queue_xfers_avail = (1 << openings) - 1;
@@ -768,7 +776,7 @@ int
 ata_get_params(struct ata_drive_datas *drvp, uint8_t flags,
     struct ataparams *prms)
 {
-	struct ata_command ata_c;
+	struct ata_xfer xfer;
 	struct ata_channel *chp = drvp->chnl_softc;
 	struct atac_softc *atac = chp->ch_atac;
 	char *tb;
@@ -779,42 +787,42 @@ ata_get_params(struct ata_drive_datas *d
 
 	tb = kmem_zalloc(DEV_BSIZE, KM_SLEEP);
 	memset(prms, 0, sizeof(struct ataparams));
-	memset(&ata_c, 0, sizeof(struct ata_command));
+	memset(&xfer, 0, sizeof(xfer));
 
 	if (drvp->drive_type == ATA_DRIVET_ATA) {
-		ata_c.r_command = WDCC_IDENTIFY;
-		ata_c.r_st_bmask = WDCS_DRDY;
-		ata_c.r_st_pmask = WDCS_DRQ;
-		ata_c.timeout = 3000; /* 3s */
+		xfer.c_ata_c.r_command = WDCC_IDENTIFY;
+		xfer.c_ata_c.r_st_bmask = WDCS_DRDY;
+		xfer.c_ata_c.r_st_pmask = WDCS_DRQ;
+		xfer.c_ata_c.timeout = 3000; /* 3s */
 	} else if (drvp->drive_type == ATA_DRIVET_ATAPI) {
-		ata_c.r_command = ATAPI_IDENTIFY_DEVICE;
-		ata_c.r_st_bmask = 0;
-		ata_c.r_st_pmask = WDCS_DRQ;
-		ata_c.timeout = 10000; /* 10s */
+		xfer.c_ata_c.r_command = ATAPI_IDENTIFY_DEVICE;
+		xfer.c_ata_c.r_st_bmask = 0;
+		xfer.c_ata_c.r_st_pmask = WDCS_DRQ;
+		xfer.c_ata_c.timeout = 10000; /* 10s */
 	} else {
 		ATADEBUG_PRINT(("ata_get_parms: no disks\n"),
 		    DEBUG_FUNCS|DEBUG_PROBE);
 		rv = CMD_ERR;
 		goto out;
 	}
-	ata_c.flags = AT_READ | flags;
-	ata_c.data = tb;
-	ata_c.bcount = DEV_BSIZE;
+	xfer.c_ata_c.flags = AT_READ | flags;
+	xfer.c_ata_c.data = tb;
+	xfer.c_ata_c.bcount = DEV_BSIZE;
 	if ((*atac->atac_bustype_ata->ata_exec_command)(drvp,
-						&ata_c) != ATACMD_COMPLETE) {
+						&xfer) != ATACMD_COMPLETE) {
 		ATADEBUG_PRINT(("ata_get_parms: wdc_exec_command failed\n"),
 		    DEBUG_FUNCS|DEBUG_PROBE);
 		rv = CMD_AGAIN;
 		goto out;
 	}
-	if (ata_c.flags & (AT_ERROR | AT_TIMEOU | AT_DF)) {
+	if (xfer.c_ata_c.flags & (AT_ERROR | AT_TIMEOU | AT_DF)) {
 		ATADEBUG_PRINT(("ata_get_parms: ata_c.flags=0x%x\n",
-		    ata_c.flags), DEBUG_FUNCS|DEBUG_PROBE);
+		    xfer.c_ata_c.flags), DEBUG_FUNCS|DEBUG_PROBE);
 		rv = CMD_ERR;
 		goto out;
 	}
 	/* if we didn't read any data something is wrong */
-	if ((ata_c.flags & AT_XFDONE) == 0) {
+	if ((xfer.c_ata_c.flags & AT_XFDONE) == 0) {
 		rv = CMD_ERR;
 		goto out;
 	}
@@ -868,24 +876,24 @@ ata_get_params(struct ata_drive_datas *d
 int
 ata_set_mode(struct ata_drive_datas *drvp, uint8_t mode, uint8_t flags)
 {
-	struct ata_command ata_c;
+	struct ata_xfer xfer;
 	struct ata_channel *chp = drvp->chnl_softc;
 	struct atac_softc *atac = chp->ch_atac;
 
 	ATADEBUG_PRINT(("ata_set_mode=0x%x\n", mode), DEBUG_FUNCS);
-	memset(&ata_c, 0, sizeof(struct ata_command));
+	memset(&xfer, 0, sizeof(xfer));
 
-	ata_c.r_command = SET_FEATURES;
-	ata_c.r_st_bmask = 0;
-	ata_c.r_st_pmask = 0;
-	ata_c.r_features = WDSF_SET_MODE;
-	ata_c.r_count = mode;
-	ata_c.flags = flags;
-	ata_c.timeout = 1000; /* 1s */
+	xfer.c_ata_c.r_command = SET_FEATURES;
+	xfer.c_ata_c.r_st_bmask = 0;
+	xfer.c_ata_c.r_st_pmask = 0;
+	xfer.c_ata_c.r_features = WDSF_SET_MODE;
+	xfer.c_ata_c.r_count = mode;
+	xfer.c_ata_c.flags = flags;
+	xfer.c_ata_c.timeout = 1000; /* 1s */
 	if ((*atac->atac_bustype_ata->ata_exec_command)(drvp,
-						&ata_c) != ATACMD_COMPLETE)
+						&xfer) != ATACMD_COMPLETE)
 		return CMD_AGAIN;
-	if (ata_c.flags & (AT_ERROR | AT_TIMEOU | AT_DF)) {
+	if (xfer.c_ata_c.flags & (AT_ERROR | AT_TIMEOU | AT_DF)) {
 		return CMD_ERR;
 	}
 	return CMD_OK;
@@ -1113,11 +1121,11 @@ ata_activate_xfer(struct ata_channel *ch
 	struct ata_queue * const chq = chp->ch_queue;
 
 	KASSERT(chq->queue_active < chq->queue_openings);
-	KASSERT((chq->queue_xfers_avail & __BIT(xfer->c_slot)) == 0);
+	KASSERT((chq->active_xfers_used & __BIT(xfer->c_slot)) == 0);
 
 	TAILQ_REMOVE(&chq->queue_xfer, xfer, c_xferchain);
 	TAILQ_INSERT_TAIL(&chq->active_xfers, xfer, c_activechain);
-
+	chq->active_xfers_used |= __BIT(xfer->c_slot);
 	chq->queue_active++;
 }
 
@@ -1127,12 +1135,13 @@ ata_deactivate_xfer(struct ata_channel *
 	struct ata_queue * const chq = chp->ch_queue;
 
 	KASSERT(chq->queue_active > 0);
-	KASSERT((chq->queue_xfers_avail & __BIT(xfer->c_slot)) == 0);
+	KASSERT((chq->active_xfers_used & __BIT(xfer->c_slot)) != 0);
 
 	//if ((xfer->c_flags & C_TIMEOU) == 0)
 	callout_stop(&chp->ch_callout);
 
 	TAILQ_REMOVE(&chq->active_xfers, xfer, c_activechain);
+	chq->active_xfers_used &= ~__BIT(xfer->c_slot);
 	chq->queue_active--;
 }
 

Index: src/sys/dev/ata/atavar.h
diff -u src/sys/dev/ata/atavar.h:1.92.8.3 src/sys/dev/ata/atavar.h:1.92.8.4
--- src/sys/dev/ata/atavar.h:1.92.8.3	Sat Apr 15 12:01:23 2017
+++ src/sys/dev/ata/atavar.h	Sat Apr 15 17:14:11 2017
@@ -1,4 +1,4 @@
-/*	$NetBSD: atavar.h,v 1.92.8.3 2017/04/15 12:01:23 jdolecek Exp $	*/
+/*	$NetBSD: atavar.h,v 1.92.8.4 2017/04/15 17:14:11 jdolecek Exp $	*/
 
 /*
  * Copyright (c) 1998, 2001 Manuel Bouyer.
@@ -69,6 +69,64 @@ struct ata_bio {
 };
 
 /*
+ * ATA/ATAPI commands description
+ *
+ * This structure defines the interface between the ATA/ATAPI device driver
+ * and the controller for short commands. It contains the command's parameter,
+ * the length of data to read/write (if any), and a function to call upon
+ * completion.
+ * If no sleep is allowed, the driver can poll for command completion.
+ * Once the command completed, if the error registered is valid, the flag
+ * AT_ERROR is set and the error register value is copied to r_error .
+ * A separate interface is needed for read/write or ATAPI packet commands
+ * (which need multiple interrupts per commands).
+ */
+struct ata_command {
+	/* ATA parameters */
+	uint64_t r_lba;		/* before & after */
+	uint16_t r_count;	/* before & after */
+	union {
+		uint16_t r_features; /* before */
+		uint8_t r_error; /* after */
+	};
+	union {
+		uint8_t r_command; /* before */
+		uint8_t r_status; /* after */
+	};
+	uint8_t r_device;	/* before & after */
+
+	uint8_t r_st_bmask;	/* status register mask to wait for before
+				   command */
+	uint8_t r_st_pmask;	/* status register mask to wait for after
+				   command */
+	volatile uint16_t flags;
+
+#define AT_READ     0x0001 /* There is data to read */
+#define AT_WRITE    0x0002 /* There is data to write (excl. with AT_READ) */
+#define AT_WAIT     0x0008 /* wait in controller code for command completion */
+#define AT_POLL     0x0010 /* poll for command completion (no interrupts) */
+#define AT_DONE     0x0020 /* command is done */
+#define AT_XFDONE   0x0040 /* data xfer is done */
+#define AT_ERROR    0x0080 /* command is done with error */
+#define AT_TIMEOU   0x0100 /* command timed out */
+#define AT_DF       0x0200 /* Drive fault */
+#define AT_RESET    0x0400 /* command terminated by channel reset */
+#define AT_GONE     0x0800 /* command terminated because device is gone */
+#define AT_READREG  0x1000 /* Read registers on completion */
+#define AT_LBA      0x2000 /* LBA28 */
+#define AT_LBA48    0x4000 /* LBA48 */
+
+	int timeout;		/* timeout (in ms) */
+	void *data;		/* Data buffer address */
+	int bcount;		/* number of bytes to transfer */
+	void (*callback)(void *); /* command to call once command completed */
+	void *callback_arg;	/* argument passed to *callback() */
+};
+
+/* Forward declaration for ata_xfer */
+struct scsipi_xfer;
+
+/*
  * Description of a command to be handled by an ATA controller.  These
  * commands are queued in a list.
  */
@@ -80,7 +138,6 @@ struct ata_xfer {
 	uint16_t c_drive;
 	int8_t c_slot;			/* queue slot # */
 
-	void	*c_cmd;			/* private request structure pointer */
 	void	*c_databuf;		/* pointer to data buffer */
 	int	c_bcount;		/* byte count left */
 	int	c_skip;			/* bytes already transferred */
@@ -88,9 +145,13 @@ struct ata_xfer {
 	int	c_lenoff;		/* offset to c_bcount (ATAPI) */
 
 	union {
-		struct ata_bio	c_bio;	/* block I/O context */
+		struct ata_bio	c_bio;		/* ATA transfer */
+		struct ata_command c_ata_c;	/* ATA command */ 
+		struct scsipi_xfer *c_scsipi;	/* SCSI transfer */
 	} u;
 #define c_bio	u.c_bio
+#define c_ata_c	u.c_ata_c
+#define c_scsipi u.c_scsipi
 
 	/* Link on the command queue. */
 	TAILQ_ENTRY(ata_xfer) c_xferchain;
@@ -127,6 +188,7 @@ struct ata_queue {
 	int queue_openings; /* max number of active transfers */
 #ifdef ATABUS_PRIVATE
 	TAILQ_HEAD(, ata_xfer) active_xfers; 	/* active commands */
+	uint32_t active_xfers_used;		/* mask of active commands */
 	uint32_t queue_xfers_avail;		/* available xfers mask */
 	struct ata_xfer queue_xfers[0];		/* xfers */
 #endif
@@ -240,61 +302,6 @@ struct ata_drive_datas {
 #define ATA_CONFIG_UDMA_OFF	8
 
 /*
- * ATA/ATAPI commands description
- *
- * This structure defines the interface between the ATA/ATAPI device driver
- * and the controller for short commands. It contains the command's parameter,
- * the length of data to read/write (if any), and a function to call upon
- * completion.
- * If no sleep is allowed, the driver can poll for command completion.
- * Once the command completed, if the error registered is valid, the flag
- * AT_ERROR is set and the error register value is copied to r_error .
- * A separate interface is needed for read/write or ATAPI packet commands
- * (which need multiple interrupts per commands).
- */
-struct ata_command {
-	/* ATA parameters */
-	uint64_t r_lba;		/* before & after */
-	uint16_t r_count;	/* before & after */
-	union {
-		uint16_t r_features; /* before */
-		uint8_t r_error; /* after */
-	};
-	union {
-		uint8_t r_command; /* before */
-		uint8_t r_status; /* after */
-	};
-	uint8_t r_device;	/* before & after */
-
-	uint8_t r_st_bmask;	/* status register mask to wait for before
-				   command */
-	uint8_t r_st_pmask;	/* status register mask to wait for after
-				   command */
-	volatile uint16_t flags;
-
-#define AT_READ     0x0001 /* There is data to read */
-#define AT_WRITE    0x0002 /* There is data to write (excl. with AT_READ) */
-#define AT_WAIT     0x0008 /* wait in controller code for command completion */
-#define AT_POLL     0x0010 /* poll for command completion (no interrupts) */
-#define AT_DONE     0x0020 /* command is done */
-#define AT_XFDONE   0x0040 /* data xfer is done */
-#define AT_ERROR    0x0080 /* command is done with error */
-#define AT_TIMEOU   0x0100 /* command timed out */
-#define AT_DF       0x0200 /* Drive fault */
-#define AT_RESET    0x0400 /* command terminated by channel reset */
-#define AT_GONE     0x0800 /* command terminated because device is gone */
-#define AT_READREG  0x1000 /* Read registers on completion */
-#define AT_LBA      0x2000 /* LBA28 */
-#define AT_LBA48    0x4000 /* LBA48 */
-
-	int timeout;		/* timeout (in ms) */
-	void *data;		/* Data buffer address */
-	int bcount;		/* number of bytes to transfer */
-	void (*callback)(void *); /* command to call once command completed */
-	void *callback_arg;	/* argument passed to *callback() */
-};
-
-/*
  * ata_bustype.  The first field must be compatible with scsipi_bustype,
  * as it's used for autoconfig by both ata and atapi drivers.
  */
@@ -308,7 +315,7 @@ struct ata_bustype {
 #define	AT_RST_NOCMD 0x20000 /* XXX has to go - temporary until we have tagged queuing */
 
 	int	(*ata_exec_command)(struct ata_drive_datas *,
-				    struct ata_command *);
+				    struct ata_xfer *);
 
 #define	ATACMD_COMPLETE		0x01
 #define	ATACMD_QUEUED		0x02

Index: src/sys/dev/ata/satapmp_subr.c
diff -u src/sys/dev/ata/satapmp_subr.c:1.12 src/sys/dev/ata/satapmp_subr.c:1.12.24.1
--- src/sys/dev/ata/satapmp_subr.c:1.12	Fri May  3 20:02:08 2013
+++ src/sys/dev/ata/satapmp_subr.c	Sat Apr 15 17:14:11 2017
@@ -1,4 +1,4 @@
-/*	$NetBSD: satapmp_subr.c,v 1.12 2013/05/03 20:02:08 jakllsch Exp $	*/
+/*	$NetBSD: satapmp_subr.c,v 1.12.24.1 2017/04/15 17:14:11 jdolecek Exp $	*/
 
 /*
  * Copyright (c) 2012 Manuel Bouyer.  All rights reserved.
@@ -25,7 +25,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: satapmp_subr.c,v 1.12 2013/05/03 20:02:08 jakllsch Exp $");
+__KERNEL_RCSID(0, "$NetBSD: satapmp_subr.c,v 1.12.24.1 2017/04/15 17:14:11 jdolecek Exp $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -50,7 +50,7 @@ __KERNEL_RCSID(0, "$NetBSD: satapmp_subr
 static int
 satapmp_read_8(struct ata_channel *chp, int port, int reg, uint64_t *value)
 {
-	struct ata_command ata_c;
+	struct ata_xfer xfer;
 	struct atac_softc *atac = chp->ch_atac;
 	struct ata_drive_datas *drvp;
 
@@ -60,39 +60,39 @@ satapmp_read_8(struct ata_channel *chp, 
 	drvp = &chp->ch_drive[PMP_PORT_CTL];
 	KASSERT(drvp->drive == PMP_PORT_CTL);
 
-	memset(&ata_c, 0, sizeof(struct ata_command));
+	memset(&xfer, 0, sizeof(xfer));
 
-	ata_c.r_command = PMPC_READ_PORT;
-	ata_c.r_features = reg;
-	ata_c.r_device = port;
-	ata_c.timeout = 3000; /* 3s */
-	ata_c.r_st_bmask = 0;
-	ata_c.r_st_pmask = WDCS_DRDY;
-	ata_c.flags = AT_LBA48 | AT_READREG | AT_WAIT;
+	xfer.c_ata_c.r_command = PMPC_READ_PORT;
+	xfer.c_ata_c.r_features = reg;
+	xfer.c_ata_c.r_device = port;
+	xfer.c_ata_c.timeout = 3000; /* 3s */
+	xfer.c_ata_c.r_st_bmask = 0;
+	xfer.c_ata_c.r_st_pmask = WDCS_DRDY;
+	xfer.c_ata_c.flags = AT_LBA48 | AT_READREG | AT_WAIT;
 
 	if ((*atac->atac_bustype_ata->ata_exec_command)(drvp,
-	    &ata_c) != ATACMD_COMPLETE) {
+	    &xfer) != ATACMD_COMPLETE) {
 		aprint_error_dev(chp->atabus,
 		    "PMP port %d register %d read failed\n", port, reg);
 		return EIO;
 	}
-	if (ata_c.flags & (AT_TIMEOU | AT_DF)) {
+	if (xfer.c_ata_c.flags & (AT_TIMEOU | AT_DF)) {
 		aprint_error_dev(chp->atabus,
 		    "PMP port %d register %d read failed, flags 0x%x\n",
-		    port, reg, ata_c.flags);
+		    port, reg, xfer.c_ata_c.flags);
 		return EIO;
 	}
-	if (ata_c.flags & AT_ERROR) {
+	if (xfer.c_ata_c.flags & AT_ERROR) {
 		aprint_verbose_dev(chp->atabus,
 		    "PMP port %d register %d read failed, error 0x%x\n",
-		    port, reg, ata_c.r_error);
+		    port, reg, xfer.c_ata_c.r_error);
 		return EIO;
 	}
 
-	*value = ((uint64_t)((ata_c.r_lba >> 24) & 0xffffff) << 40) |
-		((uint64_t)((ata_c.r_count >> 8) & 0xff) << 32) |
-		((uint64_t)((ata_c.r_lba >> 0) & 0xffffff) << 8) |
-		((uint64_t)((ata_c.r_count >> 0) & 0xff) << 0);
+	*value = ((uint64_t)((xfer.c_ata_c.r_lba >> 24) & 0xffffff) << 40) |
+		((uint64_t)((xfer.c_ata_c.r_count >> 8) & 0xff) << 32) |
+		((uint64_t)((xfer.c_ata_c.r_lba >> 0) & 0xffffff) << 8) |
+		((uint64_t)((xfer.c_ata_c.r_count >> 0) & 0xff) << 0);
 
 	return 0;
 }
@@ -114,7 +114,7 @@ satapmp_read(struct ata_channel *chp, in
 static int
 satapmp_write_8(struct ata_channel *chp, int port, int reg, uint64_t value)
 {
-	struct ata_command ata_c;
+	struct ata_xfer xfer;
 	struct atac_softc *atac = chp->ch_atac;
 	struct ata_drive_datas *drvp;
 
@@ -124,36 +124,36 @@ satapmp_write_8(struct ata_channel *chp,
 	drvp = &chp->ch_drive[PMP_PORT_CTL];
 	KASSERT(drvp->drive == PMP_PORT_CTL);
 
-	memset(&ata_c, 0, sizeof(struct ata_command));
+	memset(&xfer, 0, sizeof(xfer));
 
-	ata_c.r_command = PMPC_WRITE_PORT;
-	ata_c.r_features = reg;
-	ata_c.r_device = port;
-	ata_c.r_lba = (((value >> 40) & 0xffffff) << 24) |
+	xfer.c_ata_c.r_command = PMPC_WRITE_PORT;
+	xfer.c_ata_c.r_features = reg;
+	xfer.c_ata_c.r_device = port;
+	xfer.c_ata_c.r_lba = (((value >> 40) & 0xffffff) << 24) |
 		      (((value >>  8) & 0xffffff) <<  0);
-	ata_c.r_count = (((value >> 32) & 0xff) << 8) |
+	xfer.c_ata_c.r_count = (((value >> 32) & 0xff) << 8) |
 			(((value >>  0) & 0xff) << 0);
-	ata_c.timeout = 3000; /* 3s */
-	ata_c.r_st_bmask = 0;
-	ata_c.r_st_pmask = WDCS_DRDY;
-	ata_c.flags = AT_LBA48 | AT_WAIT;
+	xfer.c_ata_c.timeout = 3000; /* 3s */
+	xfer.c_ata_c.r_st_bmask = 0;
+	xfer.c_ata_c.r_st_pmask = WDCS_DRDY;
+	xfer.c_ata_c.flags = AT_LBA48 | AT_WAIT;
 
 	if ((*atac->atac_bustype_ata->ata_exec_command)(drvp,
-	    &ata_c) != ATACMD_COMPLETE) {
+	    &xfer) != ATACMD_COMPLETE) {
 		aprint_error_dev(chp->atabus,
 		    "PMP port %d register %d write failed\n", port, reg);
 		return EIO;
 	}
-	if (ata_c.flags & (AT_TIMEOU | AT_DF)) {
+	if (xfer.c_ata_c.flags & (AT_TIMEOU | AT_DF)) {
 		aprint_error_dev(chp->atabus,
 		    "PMP port %d register %d write failed, flags 0x%x\n",
-		    port, reg, ata_c.flags);
+		    port, reg, xfer.c_ata_c.flags);
 		return EIO;
 	}
-	if (ata_c.flags & AT_ERROR) {
+	if (xfer.c_ata_c.flags & AT_ERROR) {
 		aprint_verbose_dev(chp->atabus,
 		    "PMP port %d register %d write failed, error 0x%x\n",
-		    port, reg, ata_c.r_error);
+		    port, reg, xfer.c_ata_c.r_error);
 		return EIO;
 	}
 	return 0;

Index: src/sys/dev/ata/wd.c
diff -u src/sys/dev/ata/wd.c:1.428.2.3 src/sys/dev/ata/wd.c:1.428.2.4
--- src/sys/dev/ata/wd.c:1.428.2.3	Sat Apr 15 12:01:23 2017
+++ src/sys/dev/ata/wd.c	Sat Apr 15 17:14:11 2017
@@ -1,4 +1,4 @@
-/*	$NetBSD: wd.c,v 1.428.2.3 2017/04/15 12:01:23 jdolecek Exp $ */
+/*	$NetBSD: wd.c,v 1.428.2.4 2017/04/15 17:14:11 jdolecek 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.428.2.3 2017/04/15 12:01:23 jdolecek Exp $");
+__KERNEL_RCSID(0, "$NetBSD: wd.c,v 1.428.2.4 2017/04/15 17:14:11 jdolecek Exp $");
 
 #include "opt_ata.h"
 
@@ -1889,7 +1889,7 @@ int
 wd_setcache(struct wd_softc *wd, int bits)
 {
 	struct ataparams params;
-	struct ata_command ata_c;
+	struct ata_xfer xfer;
 
 	if (wd_get_params(wd, AT_WAIT, &params) != 0)
 		return EIO;
@@ -1903,24 +1903,24 @@ wd_setcache(struct wd_softc *wd, int bit
 	    (bits & DKCACHE_SAVE) != 0)
 		return EOPNOTSUPP;
 
-	memset(&ata_c, 0, sizeof(struct ata_command));
-	ata_c.r_command = SET_FEATURES;
-	ata_c.r_st_bmask = 0;
-	ata_c.r_st_pmask = 0;
-	ata_c.timeout = 30000; /* 30s timeout */
-	ata_c.flags = AT_WAIT;
+	memset(&xfer, 0, sizeof(xfer));
+	xfer.c_ata_c.r_command = SET_FEATURES;
+	xfer.c_ata_c.r_st_bmask = 0;
+	xfer.c_ata_c.r_st_pmask = 0;
+	xfer.c_ata_c.timeout = 30000; /* 30s timeout */
+	xfer.c_ata_c.flags = AT_WAIT;
 	if (bits & DKCACHE_WRITE)
-		ata_c.r_features = WDSF_WRITE_CACHE_EN;
+		xfer.c_ata_c.r_features = WDSF_WRITE_CACHE_EN;
 	else
-		ata_c.r_features = WDSF_WRITE_CACHE_DS;
-	if (wd->atabus->ata_exec_command(wd->drvp, &ata_c) != ATACMD_COMPLETE) {
+		xfer.c_ata_c.r_features = WDSF_WRITE_CACHE_DS;
+	if (wd->atabus->ata_exec_command(wd->drvp, &xfer) != ATACMD_COMPLETE) {
 		aprint_error_dev(wd->sc_dev,
 		    "wd_setcache command not complete\n");
 		return EIO;
 	}
-	if (ata_c.flags & (AT_ERROR | AT_TIMEOU | AT_DF)) {
+	if (xfer.c_ata_c.flags & (AT_ERROR | AT_TIMEOU | AT_DF)) {
 		char sbuf[sizeof(at_errbits) + 64];
-		snprintb(sbuf, sizeof(sbuf), at_errbits, ata_c.flags);
+		snprintb(sbuf, sizeof(sbuf), at_errbits, xfer.c_ata_c.flags);
 		aprint_error_dev(wd->sc_dev, "wd_setcache: status=%s\n", sbuf);
 		return EIO;
 	}
@@ -1930,26 +1930,28 @@ wd_setcache(struct wd_softc *wd, int bit
 static int
 wd_standby(struct wd_softc *wd, int flags)
 {
-	struct ata_command ata_c;
+	struct ata_xfer xfer;
 
-	memset(&ata_c, 0, sizeof(struct ata_command));
-	ata_c.r_command = WDCC_STANDBY_IMMED;
-	ata_c.r_st_bmask = WDCS_DRDY;
-	ata_c.r_st_pmask = WDCS_DRDY;
-	ata_c.flags = flags;
-	ata_c.timeout = 30000; /* 30s timeout */
-	if (wd->atabus->ata_exec_command(wd->drvp, &ata_c) != ATACMD_COMPLETE) {
+	memset(&xfer, 0, sizeof(xfer));
+	xfer.c_ata_c.r_command = WDCC_STANDBY_IMMED;
+	xfer.c_ata_c.r_st_bmask = WDCS_DRDY;
+	xfer.c_ata_c.r_st_pmask = WDCS_DRDY;
+	xfer.c_ata_c.flags = flags;
+	xfer.c_ata_c.timeout = 30000; /* 30s timeout */
+	if (wd->atabus->ata_exec_command(wd->drvp, &xfer) != ATACMD_COMPLETE) {
 		aprint_error_dev(wd->sc_dev,
 		    "standby immediate command didn't complete\n");
 		return EIO;
 	}
-	if (ata_c.flags & AT_ERROR) {
-		if (ata_c.r_error == WDCE_ABRT) /* command not supported */
+	if (xfer.c_ata_c.flags & AT_ERROR) {
+		if (xfer.c_ata_c.r_error == WDCE_ABRT) {
+			/* command not supported */
 			return ENODEV;
+		}
 	}
-	if (ata_c.flags & (AT_ERROR | AT_TIMEOU | AT_DF)) {
+	if (xfer.c_ata_c.flags & (AT_ERROR | AT_TIMEOU | AT_DF)) {
 		char sbuf[sizeof(at_errbits) + 64];
-		snprintb(sbuf, sizeof(sbuf), at_errbits, ata_c.flags);
+		snprintb(sbuf, sizeof(sbuf), at_errbits, xfer.c_ata_c.flags);
 		aprint_error_dev(wd->sc_dev, "wd_standby: status=%s\n", sbuf);
 		return EIO;
 	}
@@ -1959,7 +1961,7 @@ wd_standby(struct wd_softc *wd, int flag
 int
 wd_flushcache(struct wd_softc *wd, int flags)
 {
-	struct ata_command ata_c;
+	struct ata_xfer xfer;
 
 	/*
 	 * WDCC_FLUSHCACHE is here since ATA-4, but some drives report
@@ -1969,29 +1971,31 @@ wd_flushcache(struct wd_softc *wd, int f
 	    ((wd->sc_params.atap_cmd_set2 & WDC_CMD2_FC) == 0 ||
 	    wd->sc_params.atap_cmd_set2 == 0xffff))
 		return ENODEV;
-	memset(&ata_c, 0, sizeof(struct ata_command));
+	memset(&xfer, 0, sizeof(xfer));
 	if ((wd->sc_params.atap_cmd2_en & ATA_CMD2_LBA48) != 0 &&
 	    (wd->sc_params.atap_cmd2_en & ATA_CMD2_FCE) != 0) {
-		ata_c.r_command = WDCC_FLUSHCACHE_EXT;
+		xfer.c_ata_c.r_command = WDCC_FLUSHCACHE_EXT;
 		flags |= AT_LBA48;
 	} 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 */
-	if (wd->atabus->ata_exec_command(wd->drvp, &ata_c) != ATACMD_COMPLETE) {
+		xfer.c_ata_c.r_command = WDCC_FLUSHCACHE;
+	xfer.c_ata_c.r_st_bmask = WDCS_DRDY;
+	xfer.c_ata_c.r_st_pmask = WDCS_DRDY;
+	xfer.c_ata_c.flags = flags | AT_READREG;
+	xfer.c_ata_c.timeout = 300000; /* 5m timeout */
+	if (wd->atabus->ata_exec_command(wd->drvp, &xfer) != ATACMD_COMPLETE) {
 		aprint_error_dev(wd->sc_dev,
 		    "flush cache command didn't complete\n");
 		return EIO;
 	}
-	if (ata_c.flags & AT_ERROR) {
-		if (ata_c.r_error == WDCE_ABRT) /* command not supported */
+	if (xfer.c_ata_c.flags & AT_ERROR) {
+		if (xfer.c_ata_c.r_error == WDCE_ABRT) {
+			/* command not supported */
 			return ENODEV;
+		}
 	}
-	if (ata_c.flags & (AT_ERROR | AT_TIMEOU | AT_DF)) {
+	if (xfer.c_ata_c.flags & (AT_ERROR | AT_TIMEOU | AT_DF)) {
 		char sbuf[sizeof(at_errbits) + 64];
-		snprintb(sbuf, sizeof(sbuf), at_errbits, ata_c.flags);
+		snprintb(sbuf, sizeof(sbuf), at_errbits, xfer.c_ata_c.flags);
 		aprint_error_dev(wd->sc_dev, "wd_flushcache: status=%s\n",
 		    sbuf);
 		return EIO;
@@ -2002,7 +2006,7 @@ wd_flushcache(struct wd_softc *wd, int f
 int
 wd_trim(struct wd_softc *wd, int part, daddr_t bno, long size)
 {
-	struct ata_command ata_c;
+	struct ata_xfer xfer;
 	unsigned char *req;
 
 	if (part != RAW_PART)
@@ -2018,30 +2022,32 @@ wd_trim(struct wd_softc *wd, int part, d
 	req[6] = size & 0xff;
 	req[7] = (size >> 8) & 0xff;
 
-	memset(&ata_c, 0, sizeof(struct ata_command));
-	ata_c.r_command = ATA_DATA_SET_MANAGEMENT;
-	ata_c.r_count = 1;
-	ata_c.r_features = ATA_SUPPORT_DSM_TRIM;
-	ata_c.r_st_bmask = WDCS_DRDY;
-	ata_c.r_st_pmask = WDCS_DRDY;
-	ata_c.timeout = 30000; /* 30s timeout */
-	ata_c.data = req;
-	ata_c.bcount = 512;
-	ata_c.flags |= AT_WRITE | AT_WAIT;
-	if (wd->atabus->ata_exec_command(wd->drvp, &ata_c) != ATACMD_COMPLETE) {
+	memset(&xfer, 0, sizeof(xfer));
+	xfer.c_ata_c.r_command = ATA_DATA_SET_MANAGEMENT;
+	xfer.c_ata_c.r_count = 1;
+	xfer.c_ata_c.r_features = ATA_SUPPORT_DSM_TRIM;
+	xfer.c_ata_c.r_st_bmask = WDCS_DRDY;
+	xfer.c_ata_c.r_st_pmask = WDCS_DRDY;
+	xfer.c_ata_c.timeout = 30000; /* 30s timeout */
+	xfer.c_ata_c.data = req;
+	xfer.c_ata_c.bcount = 512;
+	xfer.c_ata_c.flags |= AT_WRITE | AT_WAIT;
+	if (wd->atabus->ata_exec_command(wd->drvp, &xfer) != ATACMD_COMPLETE) {
 		aprint_error_dev(wd->sc_dev,
 		    "trim command didn't complete\n");
 		kmem_free(req, 512);
 		return EIO;
 	}
 	kmem_free(req, 512);
-	if (ata_c.flags & AT_ERROR) {
-		if (ata_c.r_error == WDCE_ABRT) /* command not supported */
+	if (xfer.c_ata_c.flags & AT_ERROR) {
+		if (xfer.c_ata_c.r_error == WDCE_ABRT) {
+			/* command not supported */
 			return ENODEV;
+		}
 	}
-	if (ata_c.flags & (AT_ERROR | AT_TIMEOU | AT_DF)) {
+	if (xfer.c_ata_c.flags & (AT_ERROR | AT_TIMEOU | AT_DF)) {
 		char sbuf[sizeof(at_errbits) + 64];
-		snprintb(sbuf, sizeof(sbuf), at_errbits, ata_c.flags);
+		snprintb(sbuf, sizeof(sbuf), at_errbits, xfer.c_ata_c.flags);
 		aprint_error_dev(wd->sc_dev, "wd_trim: status=%s\n",
 		    sbuf);
 		return EIO;
@@ -2170,7 +2176,7 @@ void
 wdioctlstrategy(struct buf *bp)
 {
 	struct wd_ioctl *wi;
-	struct ata_command ata_c;
+	struct ata_xfer xfer;
 	int error = 0;
 
 	wi = wi_find(bp);
@@ -2181,7 +2187,7 @@ wdioctlstrategy(struct buf *bp)
 		goto bad;
 	}
 
-	memset(&ata_c, 0, sizeof(ata_c));
+	memset(&xfer, 0, sizeof(xfer));
 
 	/*
 	 * Abort if physio broke up the transfer
@@ -2215,55 +2221,56 @@ wdioctlstrategy(struct buf *bp)
 	}
 
 	if (wi->wi_atareq.flags & ATACMD_READ)
-		ata_c.flags |= AT_READ;
+		xfer.c_ata_c.flags |= AT_READ;
 	else if (wi->wi_atareq.flags & ATACMD_WRITE)
-		ata_c.flags |= AT_WRITE;
+		xfer.c_ata_c.flags |= AT_WRITE;
 
 	if (wi->wi_atareq.flags & ATACMD_READREG)
-		ata_c.flags |= AT_READREG;
+		xfer.c_ata_c.flags |= AT_READREG;
 
 	if ((wi->wi_atareq.flags & ATACMD_LBA) != 0)
-		ata_c.flags |= AT_LBA;
+		xfer.c_ata_c.flags |= AT_LBA;
 
-	ata_c.flags |= AT_WAIT;
+	xfer.c_ata_c.flags |= AT_WAIT;
 
-	ata_c.timeout = wi->wi_atareq.timeout;
-	ata_c.r_command = wi->wi_atareq.command;
-	ata_c.r_lba = ((wi->wi_atareq.head & 0x0f) << 24) |
+	xfer.c_ata_c.timeout = wi->wi_atareq.timeout;
+	xfer.c_ata_c.r_command = wi->wi_atareq.command;
+	xfer.c_ata_c.r_lba = ((wi->wi_atareq.head & 0x0f) << 24) |
 	    (wi->wi_atareq.cylinder << 8) |
 	    wi->wi_atareq.sec_num;
-	ata_c.r_count = wi->wi_atareq.sec_count;
-	ata_c.r_features = wi->wi_atareq.features;
-	ata_c.r_st_bmask = WDCS_DRDY;
-	ata_c.r_st_pmask = WDCS_DRDY;
-	ata_c.data = wi->wi_bp.b_data;
-	ata_c.bcount = wi->wi_bp.b_bcount;
+	xfer.c_ata_c.r_count = wi->wi_atareq.sec_count;
+	xfer.c_ata_c.r_features = wi->wi_atareq.features;
+	xfer.c_ata_c.r_st_bmask = WDCS_DRDY;
+	xfer.c_ata_c.r_st_pmask = WDCS_DRDY;
+	xfer.c_ata_c.data = wi->wi_bp.b_data;
+	xfer.c_ata_c.bcount = wi->wi_bp.b_bcount;
 
-	if (wi->wi_softc->atabus->ata_exec_command(wi->wi_softc->drvp, &ata_c)
+	if (wi->wi_softc->atabus->ata_exec_command(wi->wi_softc->drvp, &xfer)
 	    != ATACMD_COMPLETE) {
 		wi->wi_atareq.retsts = ATACMD_ERROR;
 		goto bad;
 	}
 
-	if (ata_c.flags & (AT_ERROR | AT_TIMEOU | AT_DF)) {
-		if (ata_c.flags & AT_ERROR) {
+	if (xfer.c_ata_c.flags & (AT_ERROR | AT_TIMEOU | AT_DF)) {
+		if (xfer.c_ata_c.flags & AT_ERROR) {
 			wi->wi_atareq.retsts = ATACMD_ERROR;
-			wi->wi_atareq.error = ata_c.r_error;
-		} else if (ata_c.flags & AT_DF)
+			wi->wi_atareq.error = xfer.c_ata_c.r_error;
+		} else if (xfer.c_ata_c.flags & AT_DF)
 			wi->wi_atareq.retsts = ATACMD_DF;
 		else
 			wi->wi_atareq.retsts = ATACMD_TIMEOUT;
 	} else {
 		wi->wi_atareq.retsts = ATACMD_OK;
 		if (wi->wi_atareq.flags & ATACMD_READREG) {
-			wi->wi_atareq.command = ata_c.r_status;
-			wi->wi_atareq.features = ata_c.r_error;
-			wi->wi_atareq.sec_count = ata_c.r_count;
-			wi->wi_atareq.sec_num = ata_c.r_lba & 0xff;
-			wi->wi_atareq.head = (ata_c.r_device & 0xf0) |
-			    ((ata_c.r_lba >> 24) & 0x0f);
-			wi->wi_atareq.cylinder = (ata_c.r_lba >> 8) & 0xffff;
-			wi->wi_atareq.error = ata_c.r_error;
+			wi->wi_atareq.command = xfer.c_ata_c.r_status;
+			wi->wi_atareq.features = xfer.c_ata_c.r_error;
+			wi->wi_atareq.sec_count = xfer.c_ata_c.r_count;
+			wi->wi_atareq.sec_num = xfer.c_ata_c.r_lba & 0xff;
+			wi->wi_atareq.head = (xfer.c_ata_c.r_device & 0xf0) |
+			    ((xfer.c_ata_c.r_lba >> 24) & 0x0f);
+			wi->wi_atareq.cylinder =
+			    (xfer.c_ata_c.r_lba >> 8) & 0xffff;
+			wi->wi_atareq.error = xfer.c_ata_c.r_error;
 		}
 	}
 

Index: src/sys/dev/ic/ahcisata_core.c
diff -u src/sys/dev/ic/ahcisata_core.c:1.57.6.3 src/sys/dev/ic/ahcisata_core.c:1.57.6.4
--- src/sys/dev/ic/ahcisata_core.c:1.57.6.3	Sat Apr 15 12:01:23 2017
+++ src/sys/dev/ic/ahcisata_core.c	Sat Apr 15 17:14:11 2017
@@ -1,4 +1,4 @@
-/*	$NetBSD: ahcisata_core.c,v 1.57.6.3 2017/04/15 12:01:23 jdolecek Exp $	*/
+/*	$NetBSD: ahcisata_core.c,v 1.57.6.4 2017/04/15 17:14:11 jdolecek Exp $	*/
 
 /*
  * Copyright (c) 2006 Manuel Bouyer.
@@ -26,7 +26,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: ahcisata_core.c,v 1.57.6.3 2017/04/15 12:01:23 jdolecek Exp $");
+__KERNEL_RCSID(0, "$NetBSD: ahcisata_core.c,v 1.57.6.4 2017/04/15 17:14:11 jdolecek Exp $");
 
 #include <sys/types.h>
 #include <sys/malloc.h>
@@ -61,7 +61,7 @@ static int  ahci_ata_bio(struct ata_driv
 static int  ahci_do_reset_drive(struct ata_channel *, int, int, uint32_t *);
 static void ahci_reset_drive(struct ata_drive_datas *, int, uint32_t *);
 static void ahci_reset_channel(struct ata_channel *, int);
-static int  ahci_exec_command(struct ata_drive_datas *, struct ata_command *);
+static int  ahci_exec_command(struct ata_drive_datas *, struct ata_xfer *);
 static int  ahci_ata_addref(struct ata_drive_datas *);
 static void ahci_ata_delref(struct ata_drive_datas *);
 static void ahci_killpending(struct ata_drive_datas *);
@@ -919,10 +919,10 @@ ahci_setup_channel(struct ata_channel *c
 }
 
 static int
-ahci_exec_command(struct ata_drive_datas *drvp, struct ata_command *ata_c)
+ahci_exec_command(struct ata_drive_datas *drvp, struct ata_xfer *xfer)
 {
 	struct ata_channel *chp = drvp->chnl_softc;
-	struct ata_xfer *xfer;
+	struct ata_command *ata_c = &xfer->c_ata_c;
 	int ret;
 	int s;
 
@@ -930,10 +930,6 @@ ahci_exec_command(struct ata_drive_datas
 	AHCIDEBUG_PRINT(("ahci_exec_command port %d CI 0x%x\n",
 	    chp->ch_channel, AHCI_READ(sc, AHCI_P_CI(chp->ch_channel))),
 	    DEBUG_XFERS);
-	xfer = ata_get_xfer(chp);
-	if (xfer == NULL) {
-		return ATACMD_TRY_AGAIN;
-	}
 	if (ata_c->flags & AT_POLL)
 		xfer->c_flags |= C_POLL;
 	if (ata_c->flags & AT_WAIT)
@@ -941,7 +937,6 @@ ahci_exec_command(struct ata_drive_datas
 	xfer->c_drive = drvp->drive;
 	xfer->c_databuf = ata_c->data;
 	xfer->c_bcount = ata_c->bcount;
-	xfer->c_cmd = ata_c;
 	xfer->c_start = ahci_cmd_start;
 	xfer->c_intr = ahci_cmd_complete;
 	xfer->c_kill_xfer = ahci_cmd_kill_xfer;
@@ -973,7 +968,7 @@ ahci_cmd_start(struct ata_channel *chp, 
 {
 	struct ahci_softc *sc = (struct ahci_softc *)chp->ch_atac;
 	struct ahci_channel *achp = (struct ahci_channel *)chp;
-	struct ata_command *ata_c = xfer->c_cmd;
+	struct ata_command *ata_c = &xfer->c_ata_c;
 	int slot = xfer->c_slot;
 	struct ahci_cmd_tbl *cmd_tbl;
 	struct ahci_cmd_header *cmd_h;
@@ -1059,7 +1054,7 @@ ahci_cmd_start(struct ata_channel *chp, 
 static void
 ahci_cmd_kill_xfer(struct ata_channel *chp, struct ata_xfer *xfer, int reason)
 {
-	struct ata_command *ata_c = xfer->c_cmd;
+	struct ata_command *ata_c = &xfer->c_ata_c;
 	AHCIDEBUG_PRINT(("ahci_cmd_kill_xfer channel %d\n", chp->ch_channel),
 	    DEBUG_FUNCS);
 
@@ -1081,7 +1076,7 @@ static int
 ahci_cmd_complete(struct ata_channel *chp, struct ata_xfer *xfer, int is)
 {
 	int slot = 0; /* XXX slot */
-	struct ata_command *ata_c = xfer->c_cmd;
+	struct ata_command *ata_c = &xfer->c_ata_c;
 	struct ahci_softc *sc = (struct ahci_softc *)chp->ch_atac;
 	struct ahci_channel *achp = (struct ahci_channel *)chp;
 
@@ -1119,7 +1114,7 @@ ahci_cmd_done(struct ata_channel *chp, s
 {
 	struct ahci_softc *sc = (struct ahci_softc *)chp->ch_atac;
 	struct ahci_channel *achp = (struct ahci_channel *)chp;
-	struct ata_command *ata_c = xfer->c_cmd;
+	struct ata_command *ata_c = &xfer->c_ata_c;
 	uint16_t *idwordbuf;
 	int i;
 
@@ -1153,7 +1148,6 @@ ahci_cmd_done(struct ata_channel *chp, s
 	if (achp->ahcic_cmdh[slot].cmdh_prdbc)
 		ata_c->flags |= AT_XFDONE;
 
-	ata_free_xfer(chp, xfer);
 	if (ata_c->flags & AT_WAIT)
 		wakeup(ata_c);
 	else if (ata_c->callback)
@@ -1572,7 +1566,7 @@ ahci_atapi_scsipi_request(struct scsipi_
 			xfer->c_flags |= C_POLL;
 		xfer->c_drive = drive;
 		xfer->c_flags |= C_ATAPI;
-		xfer->c_cmd = sc_xfer;
+		xfer->c_scsipi = sc_xfer;
 		xfer->c_databuf = sc_xfer->data;
 		xfer->c_bcount = sc_xfer->datalen;
 		xfer->c_start = ahci_atapi_start;
@@ -1600,7 +1594,7 @@ ahci_atapi_start(struct ata_channel *chp
 {
 	struct ahci_softc *sc = (struct ahci_softc *)chp->ch_atac;
 	struct ahci_channel *achp = (struct ahci_channel *)chp;
-	struct scsipi_xfer *sc_xfer = xfer->c_cmd;
+	struct scsipi_xfer *sc_xfer = xfer->c_scsipi;
 	int slot = 0 /* XXX slot */;
 	struct ahci_cmd_tbl *cmd_tbl;
 	struct ahci_cmd_header *cmd_h;
@@ -1683,7 +1677,7 @@ static int
 ahci_atapi_complete(struct ata_channel *chp, struct ata_xfer *xfer, int irq)
 {
 	int slot = xfer->c_slot; /* XXX slot */
-	struct scsipi_xfer *sc_xfer = xfer->c_cmd;
+	struct scsipi_xfer *sc_xfer = xfer->c_scsipi;
 	struct ahci_channel *achp = (struct ahci_channel *)chp;
 	struct ahci_softc *sc = (struct ahci_softc *)chp->ch_atac;
 
@@ -1740,7 +1734,7 @@ ahci_atapi_complete(struct ata_channel *
 static void
 ahci_atapi_kill_xfer(struct ata_channel *chp, struct ata_xfer *xfer, int reason)
 {
-	struct scsipi_xfer *sc_xfer = xfer->c_cmd;
+	struct scsipi_xfer *sc_xfer = xfer->c_scsipi;
 	struct ahci_channel *achp = (struct ahci_channel *)chp;
 	int slot = 0; /* XXX slot */
 

Index: src/sys/dev/ic/mvsata.c
diff -u src/sys/dev/ic/mvsata.c:1.35.6.4 src/sys/dev/ic/mvsata.c:1.35.6.5
--- src/sys/dev/ic/mvsata.c:1.35.6.4	Sat Apr 15 12:01:23 2017
+++ src/sys/dev/ic/mvsata.c	Sat Apr 15 17:14:11 2017
@@ -1,4 +1,4 @@
-/*	$NetBSD: mvsata.c,v 1.35.6.4 2017/04/15 12:01:23 jdolecek Exp $	*/
+/*	$NetBSD: mvsata.c,v 1.35.6.5 2017/04/15 17:14:11 jdolecek Exp $	*/
 /*
  * Copyright (c) 2008 KIYOHARA Takashi
  * All rights reserved.
@@ -26,7 +26,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: mvsata.c,v 1.35.6.4 2017/04/15 12:01:23 jdolecek Exp $");
+__KERNEL_RCSID(0, "$NetBSD: mvsata.c,v 1.35.6.5 2017/04/15 17:14:11 jdolecek Exp $");
 
 #include "opt_mvsata.h"
 
@@ -111,7 +111,7 @@ static void mvsata_probe_drive(struct at
 static int mvsata_bio(struct ata_drive_datas *, struct ata_xfer *);
 static void mvsata_reset_drive(struct ata_drive_datas *, int, uint32_t *);
 static void mvsata_reset_channel(struct ata_channel *, int);
-static int mvsata_exec_command(struct ata_drive_datas *, struct ata_command *);
+static int mvsata_exec_command(struct ata_drive_datas *, struct ata_xfer *);
 static int mvsata_addref(struct ata_drive_datas *);
 static void mvsata_delref(struct ata_drive_datas *);
 static void mvsata_killpending(struct ata_drive_datas *);
@@ -550,7 +550,6 @@ mvsata_bio(struct ata_drive_datas *drvp,
 	    (ata_bio->flags & ATA_SINGLE) == 0)
 		xfer->c_flags |= C_DMA;
 	xfer->c_drive = drvp->drive;
-	xfer->c_cmd = ata_bio;
 	xfer->c_databuf = ata_bio->databuf;
 	xfer->c_bcount = ata_bio->bcount;
 	xfer->c_start = mvsata_bio_start;
@@ -644,13 +643,13 @@ mvsata_reset_channel(struct ata_channel 
 
 
 static int
-mvsata_exec_command(struct ata_drive_datas *drvp, struct ata_command *ata_c)
+mvsata_exec_command(struct ata_drive_datas *drvp, struct ata_xfer *xfer)
 {
 	struct ata_channel *chp = drvp->chnl_softc;
 #ifdef MVSATA_DEBUG
 	struct mvsata_port *mvport = (struct mvsata_port *)chp;
 #endif
-	struct ata_xfer *xfer;
+	struct ata_command *ata_c = &xfer->c_ata_c;
 	int rv, s;
 
 	DPRINTFN(1, ("%s:%d: mvsata_exec_command: drive=%d, bcount=%d,"
@@ -660,9 +659,6 @@ mvsata_exec_command(struct ata_drive_dat
 	    drvp->drive, ata_c->bcount, ata_c->r_lba, ata_c->r_count,
 	    ata_c->r_features, ata_c->r_device, ata_c->r_command));
 
-	xfer = ata_get_xfer(chp);
-	if (xfer == NULL)
-		return ATACMD_TRY_AGAIN;
 	if (ata_c->flags & AT_POLL)
 		xfer->c_flags |= C_POLL;
 	if (ata_c->flags & AT_WAIT)
@@ -670,7 +666,6 @@ mvsata_exec_command(struct ata_drive_dat
 	xfer->c_drive = drvp->drive;
 	xfer->c_databuf = ata_c->data;
 	xfer->c_bcount = ata_c->bcount;
-	xfer->c_cmd = ata_c;
 	xfer->c_start = mvsata_wdc_cmd_start;
 	xfer->c_intr = mvsata_wdc_cmd_intr;
 	xfer->c_kill_xfer = mvsata_wdc_cmd_kill_xfer;
@@ -786,7 +781,7 @@ mvsata_atapi_scsipi_request(struct scsip
 			xfer->c_flags |= C_POLL;
 		xfer->c_drive = drive;
 		xfer->c_flags |= C_ATAPI;
-		xfer->c_cmd = sc_xfer;
+		xfer->c_scsipi = sc_xfer;
 		xfer->c_databuf = sc_xfer->data;
 		xfer->c_bcount = sc_xfer->datalen;
 		xfer->c_start = mvsata_atapi_start;
@@ -1058,7 +1053,7 @@ mvsata_bio_start(struct ata_channel *chp
 	struct mvsata_softc *sc = device_private(MVSATA_DEV2(mvport));
 	struct atac_softc *atac = chp->ch_atac;
 	struct wdc_softc *wdc = CHAN_TO_WDC(chp);
-	struct ata_bio *ata_bio = xfer->c_cmd;
+	struct ata_bio *ata_bio = &xfer->c_bio;
 	struct ata_drive_datas *drvp = &chp->ch_drive[xfer->c_drive];
 	int wait_flags = (xfer->c_flags & C_POLL) ? AT_POLL : 0;
 	u_int16_t cyl;
@@ -1300,7 +1295,7 @@ mvsata_bio_intr(struct ata_channel *chp,
 {
 	struct atac_softc *atac = chp->ch_atac;
 	struct wdc_softc *wdc = CHAN_TO_WDC(chp);
-	struct ata_bio *ata_bio = xfer->c_cmd;
+	struct ata_bio *ata_bio = &xfer->c_bio;
 	struct ata_drive_datas *drvp = &chp->ch_drive[xfer->c_drive];
 
 	DPRINTFN(2, ("%s:%d: mvsata_bio_intr: drive=%d\n",
@@ -1394,7 +1389,7 @@ mvsata_bio_kill_xfer(struct ata_channel 
 {
 	struct mvsata_port *mvport = (struct mvsata_port *)chp;
 	struct atac_softc *atac = chp->ch_atac;
-	struct ata_bio *ata_bio = xfer->c_cmd;
+	struct ata_bio *ata_bio = &xfer->c_bio;
 	int drive = xfer->c_drive;
 
 	DPRINTFN(2, ("%s:%d: mvsata_bio_kill_xfer: drive=%d\n",
@@ -1427,7 +1422,7 @@ static void
 mvsata_bio_done(struct ata_channel *chp, struct ata_xfer *xfer)
 {
 	struct mvsata_port *mvport = (struct mvsata_port *)chp;
-	struct ata_bio *ata_bio = xfer->c_cmd;
+	struct ata_bio *ata_bio = &xfer->c_bio;
 	int drive = xfer->c_drive;
 
 	DPRINTFN(2, ("%s:%d: mvsata_bio_done: drive=%d, flags=0x%x\n",
@@ -1568,7 +1563,7 @@ mvsata_wdc_cmd_start(struct ata_channel 
 	struct mvsata_port *mvport = (struct mvsata_port *)chp;
 	int drive = xfer->c_drive;
 	int wait_flags = (xfer->c_flags & C_POLL) ? AT_POLL : 0;
-	struct ata_command *ata_c = xfer->c_cmd;
+	struct ata_command *ata_c = &xfer->c_ata_c;
 
 	DPRINTFN(1, ("%s:%d: mvsata_cmd_start: drive=%d\n",
 	    device_xname(MVSATA_DEV2(mvport)), chp->ch_channel, drive));
@@ -1627,7 +1622,7 @@ mvsata_wdc_cmd_intr(struct ata_channel *
 {
 	struct mvsata_port *mvport = (struct mvsata_port *)chp;
 	struct wdc_softc *wdc = CHAN_TO_WDC(chp);
-	struct ata_command *ata_c = xfer->c_cmd;
+	struct ata_command *ata_c = &xfer->c_ata_c;
 	int bcount = ata_c->bcount;
 	char *data = ata_c->data;
 	int wflags;
@@ -1728,7 +1723,7 @@ mvsata_wdc_cmd_kill_xfer(struct ata_chan
 			 int reason)
 {
 	struct mvsata_port *mvport = (struct mvsata_port *)chp;
-	struct ata_command *ata_c = xfer->c_cmd;
+	struct ata_command *ata_c = &xfer->c_ata_c;
 
 	DPRINTFN(1, ("%s:%d: mvsata_cmd_kill_xfer: drive=%d\n",
 	    device_xname(MVSATA_DEV2(mvport)), chp->ch_channel, xfer->c_drive));
@@ -1753,7 +1748,7 @@ mvsata_wdc_cmd_done(struct ata_channel *
 {
 	struct mvsata_port *mvport = (struct mvsata_port *)chp;
 	struct atac_softc *atac = chp->ch_atac;
-	struct ata_command *ata_c = xfer->c_cmd;
+	struct ata_command *ata_c = &xfer->c_ata_c;
 
 	DPRINTFN(1, ("%s:%d: mvsata_cmd_done: drive=%d, flags=0x%x\n",
 	    device_xname(atac->atac_dev), chp->ch_channel, xfer->c_drive,
@@ -1823,7 +1818,7 @@ static void
 mvsata_wdc_cmd_done_end(struct ata_channel *chp, struct ata_xfer *xfer)
 {
 	struct mvsata_port *mvport = (struct mvsata_port *)chp;
-	struct ata_command *ata_c = xfer->c_cmd;
+	struct ata_command *ata_c = &xfer->c_ata_c;
 
 	/* EDMA restart, if enabled */
 	if (mvport->port_edmamode != nodma) {
@@ -1832,7 +1827,6 @@ mvsata_wdc_cmd_done_end(struct ata_chann
 	}
 
 	ata_c->flags |= AT_DONE;
-	ata_free_xfer(chp, xfer);
 	if (ata_c->flags & AT_WAIT)
 		wakeup(ata_c);
 	else if (ata_c->callback)
@@ -1849,7 +1843,7 @@ mvsata_atapi_start(struct ata_channel *c
 	struct mvsata_softc *sc = (struct mvsata_softc *)chp->ch_atac;
 	struct mvsata_port *mvport = (struct mvsata_port *)chp;
 	struct atac_softc *atac = &sc->sc_wdcdev.sc_atac;
-	struct scsipi_xfer *sc_xfer = xfer->c_cmd;
+	struct scsipi_xfer *sc_xfer = xfer->c_scsipi;
 	struct ata_drive_datas *drvp = &chp->ch_drive[xfer->c_drive];
 	const int wait_flags = (xfer->c_flags & C_POLL) ? AT_POLL : 0;
 	const char *errstring;
@@ -2034,7 +2028,7 @@ mvsata_atapi_intr(struct ata_channel *ch
 	struct mvsata_port *mvport = (struct mvsata_port *)chp;
 	struct atac_softc *atac = chp->ch_atac;
 	struct wdc_softc *wdc = CHAN_TO_WDC(chp);
-	struct scsipi_xfer *sc_xfer = xfer->c_cmd;
+	struct scsipi_xfer *sc_xfer = xfer->c_scsipi;
 	struct ata_drive_datas *drvp = &chp->ch_drive[xfer->c_drive];
 	int len, phase, ire, error, retries=0, i;
 	void *cmd;
@@ -2251,7 +2245,7 @@ mvsata_atapi_kill_xfer(struct ata_channe
 		       int reason)
 {
 	struct mvsata_port *mvport = (struct mvsata_port *)chp;
-	struct scsipi_xfer *sc_xfer = xfer->c_cmd;
+	struct scsipi_xfer *sc_xfer = xfer->c_scsipi;
 
 	/* remove this command from xfer queue */
 	switch (reason) {
@@ -2277,7 +2271,7 @@ mvsata_atapi_reset(struct ata_channel *c
 {
 	struct atac_softc *atac = chp->ch_atac;
 	struct ata_drive_datas *drvp = &chp->ch_drive[xfer->c_drive];
-	struct scsipi_xfer *sc_xfer = xfer->c_cmd;
+	struct scsipi_xfer *sc_xfer = xfer->c_scsipi;
 
 	mvsata_pmp_select(mvport, xfer->c_drive);
 
@@ -2298,7 +2292,7 @@ mvsata_atapi_phase_complete(struct ata_x
 	struct ata_channel *chp = xfer->c_chp;
 	struct atac_softc *atac = chp->ch_atac;
 	struct wdc_softc *wdc = CHAN_TO_WDC(chp);
-	struct scsipi_xfer *sc_xfer = xfer->c_cmd;
+	struct scsipi_xfer *sc_xfer = xfer->c_scsipi;
 	struct ata_drive_datas *drvp = &chp->ch_drive[xfer->c_drive];
 
 	/* wait for DSC if needed */
@@ -2376,7 +2370,7 @@ static void
 mvsata_atapi_done(struct ata_channel *chp, struct ata_xfer *xfer)
 {
 	struct atac_softc *atac = chp->ch_atac;
-	struct scsipi_xfer *sc_xfer = xfer->c_cmd;
+	struct scsipi_xfer *sc_xfer = xfer->c_scsipi;
 	int drive = xfer->c_drive;
 
 	DPRINTFN(1, ("%s:%d:%d: mvsata_atapi_done: flags 0x%x\n",
@@ -2584,7 +2578,7 @@ mvsata_edma_handle(struct mvsata_port *m
 
 		chp->ch_status = CRPB_CDEVSTS(le16toh(crpb->rspflg));
 		chp->ch_error = CRPB_CEDMASTS(le16toh(crpb->rspflg));
-		ata_bio = xfer->c_cmd;
+		ata_bio = &xfer->c_bio;
 		ata_bio->error = NOERROR;
 		ata_bio->r_error = 0;
 		if (chp->ch_status & WDCS_ERR)
@@ -2644,7 +2638,7 @@ mvsata_edma_handle(struct mvsata_port *m
 static int
 mvsata_edma_wait(struct mvsata_port *mvport, struct ata_xfer *xfer, int timeout)
 {
-	struct ata_bio *ata_bio = xfer->c_cmd;
+	struct ata_bio *ata_bio = &xfer->c_bio;
 	int xtime;
 
 	for (xtime = 0;  xtime < timeout / 10; xtime++) {
@@ -2700,7 +2694,7 @@ mvsata_edma_rqq_remove(struct mvsata_por
 		if (mvport->port_reqtbl[i].xfer == NULL)
 			continue;
 
-		ata_bio = mvport->port_reqtbl[i].xfer->c_cmd;
+		ata_bio = &mvport->port_reqtbl[i].xfer->c_bio;
 		if (mvport->port_reqtbl[i].xfer == xfer) {
 			/* remove xfer from EDMA request queue */
 			bus_dmamap_sync(mvport->port_dmat,

Index: src/sys/dev/ic/siisata.c
diff -u src/sys/dev/ic/siisata.c:1.30.4.3 src/sys/dev/ic/siisata.c:1.30.4.4
--- src/sys/dev/ic/siisata.c:1.30.4.3	Sat Apr 15 12:01:23 2017
+++ src/sys/dev/ic/siisata.c	Sat Apr 15 17:14:11 2017
@@ -1,4 +1,4 @@
-/* $NetBSD: siisata.c,v 1.30.4.3 2017/04/15 12:01:23 jdolecek Exp $ */
+/* $NetBSD: siisata.c,v 1.30.4.4 2017/04/15 17:14:11 jdolecek Exp $ */
 
 /* from ahcisata_core.c */
 
@@ -79,7 +79,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: siisata.c,v 1.30.4.3 2017/04/15 12:01:23 jdolecek Exp $");
+__KERNEL_RCSID(0, "$NetBSD: siisata.c,v 1.30.4.4 2017/04/15 17:14:11 jdolecek Exp $");
 
 #include <sys/types.h>
 #include <sys/param.h>
@@ -153,7 +153,7 @@ void siisata_cmd_kill_xfer(struct ata_ch
 void siisata_bio_start(struct ata_channel *, struct ata_xfer *);
 int siisata_bio_complete(struct ata_channel *, struct ata_xfer *, int);
 void siisata_bio_kill_xfer(struct ata_channel *, struct ata_xfer *, int);
-int siisata_exec_command(struct ata_drive_datas *, struct ata_command *);
+int siisata_exec_command(struct ata_drive_datas *, struct ata_xfer *);
 
 void siisata_timeout(void *);
 
@@ -762,10 +762,10 @@ siisata_setup_channel(struct ata_channel
 }
 
 int
-siisata_exec_command(struct ata_drive_datas *drvp, struct ata_command *ata_c)
+siisata_exec_command(struct ata_drive_datas *drvp, struct ata_xfer *xfer)
 {
 	struct ata_channel *chp = drvp->chnl_softc;
-	struct ata_xfer *xfer;
+	struct ata_command *ata_c = &xfer->c_ata_c;
 	int ret;
 	int s;
 
@@ -773,9 +773,6 @@ siisata_exec_command(struct ata_drive_da
 	    SIISATANAME((struct siisata_softc *)chp->ch_atac), __func__),
 	    DEBUG_FUNCS);
 
-	xfer = ata_get_xfer(chp);
-	if (xfer == NULL)
-		return ATACMD_TRY_AGAIN;
 	if (ata_c->flags & AT_POLL)
 		xfer->c_flags |= C_POLL;
 	if (ata_c->flags & AT_WAIT)
@@ -783,7 +780,6 @@ siisata_exec_command(struct ata_drive_da
 	xfer->c_drive = drvp->drive;
 	xfer->c_databuf = ata_c->data;
 	xfer->c_bcount = ata_c->bcount;
-	xfer->c_cmd = ata_c;
 	xfer->c_start = siisata_cmd_start;
 	xfer->c_intr = siisata_cmd_complete;
 	xfer->c_kill_xfer = siisata_cmd_kill_xfer;
@@ -821,7 +817,7 @@ void
 siisata_cmd_start(struct ata_channel *chp, struct ata_xfer *xfer)
 {
 	struct siisata_channel *schp = (struct siisata_channel *)chp;
-	struct ata_command *ata_c = xfer->c_cmd;
+	struct ata_command *ata_c = &xfer->c_ata_c;
 	int slot = SIISATA_NON_NCQ_SLOT;
 	struct siisata_prb *prb;
 	int i;
@@ -902,7 +898,7 @@ siisata_cmd_kill_xfer(struct ata_channel
 {
 	int slot = SIISATA_NON_NCQ_SLOT;
 
-	struct ata_command *ata_c = xfer->c_cmd;
+	struct ata_command *ata_c = &xfer->c_ata_c;
 	switch (reason) {
 	case KILL_GONE:
 		ata_c->flags |= AT_GONE;
@@ -920,7 +916,7 @@ siisata_cmd_kill_xfer(struct ata_channel
 int
 siisata_cmd_complete(struct ata_channel *chp, struct ata_xfer *xfer, int slot)
 {
-	struct ata_command *ata_c = xfer->c_cmd;
+	struct ata_command *ata_c = &xfer->c_ata_c;
 #ifdef SIISATA_DEBUG
 	struct siisata_softc *sc = (struct siisata_softc *)chp->ch_atac;
 #endif
@@ -956,7 +952,7 @@ siisata_cmd_done(struct ata_channel *chp
 	uint32_t fis[howmany(RDH_FISLEN,sizeof(uint32_t))];
 	struct siisata_softc *sc = (struct siisata_softc *)chp->ch_atac;
 	struct siisata_channel *schp = (struct siisata_channel *)chp;
-	struct ata_command *ata_c = xfer->c_cmd;
+	struct ata_command *ata_c = &xfer->c_ata_c;
 	uint16_t *idwordbuf;
 	int i;
 
@@ -994,8 +990,6 @@ siisata_cmd_done(struct ata_channel *chp
 	if (PRREAD(sc, PRSX(chp->ch_channel, slot, PRSO_RTC)))
 		ata_c->flags |= AT_XFDONE;
 
-	ata_free_xfer(chp, xfer);
-
 	if (ata_c->flags & AT_WAIT)
 		wakeup(ata_c);
 	else if (ata_c->callback)
@@ -1019,7 +1013,6 @@ siisata_ata_bio(struct ata_drive_datas *
 	if (ata_bio->flags & ATA_POLL)
 		xfer->c_flags |= C_POLL;
 	xfer->c_drive = drvp->drive;
-	xfer->c_cmd = ata_bio;
 	xfer->c_databuf = ata_bio->databuf;
 	xfer->c_bcount = ata_bio->bcount;
 	xfer->c_start = siisata_bio_start;
@@ -1035,7 +1028,7 @@ siisata_bio_start(struct ata_channel *ch
 {
 	struct siisata_channel *schp = (struct siisata_channel *)chp;
 	struct siisata_prb *prb;
-	struct ata_bio *ata_bio = xfer->c_cmd;
+	struct ata_bio *ata_bio = &xfer->c_bio;
 	int slot = SIISATA_NON_NCQ_SLOT;
 	int i;
 
@@ -1101,7 +1094,7 @@ siisata_bio_kill_xfer(struct ata_channel
     int reason)
 {
 	struct siisata_channel *schp = (struct siisata_channel *)chp;
-	struct ata_bio *ata_bio = xfer->c_cmd;
+	struct ata_bio *ata_bio = &xfer->c_bio;
 	int drive = xfer->c_drive;
 	int slot = SIISATA_NON_NCQ_SLOT;
 
@@ -1132,7 +1125,7 @@ siisata_bio_complete(struct ata_channel 
 {
 	struct siisata_softc *sc = (struct siisata_softc *)chp->ch_atac;
 	struct siisata_channel *schp = (struct siisata_channel *)chp;
-	struct ata_bio *ata_bio = xfer->c_cmd;
+	struct ata_bio *ata_bio = &xfer->c_bio;
 	int drive = xfer->c_drive;
 
 	schp->sch_active_slots &= ~__BIT(slot);
@@ -1373,7 +1366,7 @@ void
 siisata_atapi_kill_xfer(struct ata_channel *chp, struct ata_xfer *xfer,
     int reason)
 {
-	struct scsipi_xfer *sc_xfer = xfer->c_cmd;
+	struct scsipi_xfer *sc_xfer = xfer->c_scsipi;
 
 	/* remove this command from xfer queue */
 	switch (reason) {
@@ -1541,7 +1534,7 @@ siisata_atapi_scsipi_request(struct scsi
 			xfer->c_flags |= C_POLL;
 		xfer->c_drive = drive;
 		xfer->c_flags |= C_ATAPI;
-		xfer->c_cmd = sc_xfer;
+		xfer->c_scsipi = sc_xfer;
 		xfer->c_databuf = sc_xfer->data;
 		xfer->c_bcount = sc_xfer->datalen;
 		xfer->c_start = siisata_atapi_start;
@@ -1570,7 +1563,7 @@ siisata_atapi_start(struct ata_channel *
 	struct siisata_channel *schp = (struct siisata_channel *)chp;
 	struct siisata_prb *prbp;
 
-	struct scsipi_xfer *sc_xfer = xfer->c_cmd;
+	struct scsipi_xfer *sc_xfer = xfer->c_scsipi;
 
 	int slot = SIISATA_NON_NCQ_SLOT;
 	int i;
@@ -1650,7 +1643,7 @@ siisata_atapi_complete(struct ata_channe
 {
 	struct siisata_softc *sc = (struct siisata_softc *)chp->ch_atac;
 	struct siisata_channel *schp = (struct siisata_channel *)chp;
-	struct scsipi_xfer *sc_xfer = xfer->c_cmd;
+	struct scsipi_xfer *sc_xfer = xfer->c_scsipi;
 
 	SIISATA_DEBUG_PRINT(
 	    ("%s: %s()\n", SIISATANAME(sc), __func__), DEBUG_INTR);

Index: src/sys/dev/ic/wdc.c
diff -u src/sys/dev/ic/wdc.c:1.283.2.2 src/sys/dev/ic/wdc.c:1.283.2.3
--- src/sys/dev/ic/wdc.c:1.283.2.2	Sat Apr 15 12:01:23 2017
+++ src/sys/dev/ic/wdc.c	Sat Apr 15 17:14:11 2017
@@ -1,4 +1,4 @@
-/*	$NetBSD: wdc.c,v 1.283.2.2 2017/04/15 12:01:23 jdolecek Exp $ */
+/*	$NetBSD: wdc.c,v 1.283.2.3 2017/04/15 17:14:11 jdolecek 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.283.2.2 2017/04/15 12:01:23 jdolecek Exp $");
+__KERNEL_RCSID(0, "$NetBSD: wdc.c,v 1.283.2.3 2017/04/15 17:14:11 jdolecek Exp $");
 
 #include "opt_ata.h"
 #include "opt_wdc.h"
@@ -1366,10 +1366,10 @@ wdctimeout(void *arg)
 }
 
 int
-wdc_exec_command(struct ata_drive_datas *drvp, struct ata_command *ata_c)
+wdc_exec_command(struct ata_drive_datas *drvp, struct ata_xfer *xfer)
 {
 	struct ata_channel *chp = drvp->chnl_softc;
-	struct ata_xfer *xfer;
+	struct ata_command *ata_c = &xfer->c_ata_c;
 	int s, ret;
 
 	ATADEBUG_PRINT(("wdc_exec_command %s:%d:%d\n",
@@ -1377,11 +1377,6 @@ wdc_exec_command(struct ata_drive_datas 
 	    drvp->drive), DEBUG_FUNCS);
 
 	/* set up an xfer and queue. Wait for completion */
-	xfer = ata_get_xfer(chp);
-	if (xfer == NULL) {
-		return ATACMD_TRY_AGAIN;
-	 }
-
 	if (chp->ch_atac->atac_cap & ATAC_CAP_NOIRQ)
 		ata_c->flags |= AT_POLL;
 	if (ata_c->flags & AT_POLL)
@@ -1391,7 +1386,6 @@ wdc_exec_command(struct ata_drive_datas 
 	xfer->c_drive = drvp->drive;
 	xfer->c_databuf = ata_c->data;
 	xfer->c_bcount = ata_c->bcount;
-	xfer->c_cmd = ata_c;
 	xfer->c_start = __wdccommand_start;
 	xfer->c_intr = __wdccommand_intr;
 	xfer->c_kill_xfer = __wdccommand_kill_xfer;
@@ -1426,7 +1420,7 @@ __wdccommand_start(struct ata_channel *c
 	struct wdc_regs *wdr = &wdc->regs[chp->ch_channel];
 	int drive = xfer->c_drive;
 	int wait_flags = (xfer->c_flags & C_POLL) ? AT_POLL : 0;
-	struct ata_command *ata_c = xfer->c_cmd;
+	struct ata_command *ata_c = &xfer->c_ata_c;
 
 	ATADEBUG_PRINT(("__wdccommand_start %s:%d:%d\n",
 	    device_xname(chp->ch_atac->atac_dev), chp->ch_channel,
@@ -1487,7 +1481,7 @@ __wdccommand_intr(struct ata_channel *ch
 {
 	struct wdc_softc *wdc = CHAN_TO_WDC(chp);
 	struct wdc_regs *wdr = &wdc->regs[chp->ch_channel];
-	struct ata_command *ata_c = xfer->c_cmd;
+	struct ata_command *ata_c = &xfer->c_ata_c;
 	int bcount = ata_c->bcount;
 	char *data = ata_c->data;
 	int wflags;
@@ -1598,7 +1592,7 @@ __wdccommand_done(struct ata_channel *ch
 	struct atac_softc *atac = chp->ch_atac;
 	struct wdc_softc *wdc = CHAN_TO_WDC(chp);
 	struct wdc_regs *wdr = &wdc->regs[chp->ch_channel];
-	struct ata_command *ata_c = xfer->c_cmd;
+	struct ata_command *ata_c = &xfer->c_ata_c;
 
 	ATADEBUG_PRINT(("__wdccommand_done %s:%d:%d flags 0x%x\n",
 	    device_xname(atac->atac_dev), chp->ch_channel, xfer->c_drive,
@@ -1683,10 +1677,9 @@ __wdccommand_done(struct ata_channel *ch
 static void
 __wdccommand_done_end(struct ata_channel *chp, struct ata_xfer *xfer)
 {
-	struct ata_command *ata_c = xfer->c_cmd;
+	struct ata_command *ata_c = &xfer->c_ata_c;
 
 	ata_c->flags |= AT_DONE;
-	ata_free_xfer(chp, xfer);
 	if (ata_c->flags & AT_WAIT)
 		wakeup(ata_c);
 	else if (ata_c->callback)
@@ -1699,7 +1692,7 @@ static void
 __wdccommand_kill_xfer(struct ata_channel *chp, struct ata_xfer *xfer,
     int reason)
 {
-	struct ata_command *ata_c = xfer->c_cmd;
+	struct ata_command *ata_c = &xfer->c_ata_c;
 
 	switch (reason) {
 	case KILL_GONE:

Index: src/sys/dev/ic/wdcvar.h
diff -u src/sys/dev/ic/wdcvar.h:1.97 src/sys/dev/ic/wdcvar.h:1.97.26.1
--- src/sys/dev/ic/wdcvar.h:1.97	Sun Feb  3 20:13:28 2013
+++ src/sys/dev/ic/wdcvar.h	Sat Apr 15 17:14:11 2017
@@ -1,4 +1,4 @@
-/*	$NetBSD: wdcvar.h,v 1.97 2013/02/03 20:13:28 jakllsch Exp $	*/
+/*	$NetBSD: wdcvar.h,v 1.97.26.1 2017/04/15 17:14:11 jdolecek Exp $	*/
 
 /*-
  * Copyright (c) 1998, 2003, 2004 The NetBSD Foundation, Inc.
@@ -173,7 +173,7 @@ void	wdc_reset_drive(struct ata_drive_da
 void	wdc_reset_channel(struct ata_channel *, int);
 void	wdc_do_reset(struct ata_channel *, int);
 
-int	wdc_exec_command(struct ata_drive_datas *, struct ata_command*);
+int	wdc_exec_command(struct ata_drive_datas *, struct ata_xfer *);
 
 /*
  * ST506 spec says that if READY or SEEKCMPLT go off, then the read or write

Index: src/sys/dev/scsipi/atapi_wdc.c
diff -u src/sys/dev/scsipi/atapi_wdc.c:1.123.4.2 src/sys/dev/scsipi/atapi_wdc.c:1.123.4.3
--- src/sys/dev/scsipi/atapi_wdc.c:1.123.4.2	Sat Apr 15 12:01:24 2017
+++ src/sys/dev/scsipi/atapi_wdc.c	Sat Apr 15 17:14:11 2017
@@ -1,4 +1,4 @@
-/*	$NetBSD: atapi_wdc.c,v 1.123.4.2 2017/04/15 12:01:24 jdolecek Exp $	*/
+/*	$NetBSD: atapi_wdc.c,v 1.123.4.3 2017/04/15 17:14:11 jdolecek Exp $	*/
 
 /*
  * Copyright (c) 1998, 2001 Manuel Bouyer.
@@ -25,7 +25,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: atapi_wdc.c,v 1.123.4.2 2017/04/15 12:01:24 jdolecek Exp $");
+__KERNEL_RCSID(0, "$NetBSD: atapi_wdc.c,v 1.123.4.3 2017/04/15 17:14:11 jdolecek Exp $");
 
 #ifndef ATADEBUG
 #define ATADEBUG
@@ -169,7 +169,7 @@ wdc_atapi_kill_pending(struct scsipi_per
 static void
 wdc_atapi_kill_xfer(struct ata_channel *chp, struct ata_xfer *xfer, int reason)
 {
-	struct scsipi_xfer *sc_xfer = xfer->c_cmd;
+	struct scsipi_xfer *sc_xfer = xfer->c_scsipi;
 
 	/* remove this command from xfer queue */
 	switch (reason) {
@@ -196,25 +196,25 @@ wdc_atapi_get_params(struct scsipi_chann
 	struct atac_softc *atac = &wdc->sc_atac;
 	struct wdc_regs *wdr = &wdc->regs[chan->chan_channel];
 	struct ata_channel *chp = atac->atac_channels[chan->chan_channel];
-	struct ata_command ata_c;
+	struct ata_xfer xfer;
 
-	memset(&ata_c, 0, sizeof(struct ata_command));
-	ata_c.r_command = ATAPI_SOFT_RESET;
-	ata_c.r_st_bmask = 0;
-	ata_c.r_st_pmask = 0;
-	ata_c.flags = AT_WAIT | AT_POLL;
-	ata_c.timeout = WDC_RESET_WAIT;
-	if (wdc_exec_command(&chp->ch_drive[drive], &ata_c) != ATACMD_COMPLETE) {
+	memset(&xfer, 0, sizeof(xfer));
+	xfer.c_ata_c.r_command = ATAPI_SOFT_RESET;
+	xfer.c_ata_c.r_st_bmask = 0;
+	xfer.c_ata_c.r_st_pmask = 0;
+	xfer.c_ata_c.flags = AT_WAIT | AT_POLL;
+	xfer.c_ata_c.timeout = WDC_RESET_WAIT;
+	if (wdc_exec_command(&chp->ch_drive[drive], &xfer) != ATACMD_COMPLETE) {
 		printf("wdc_atapi_get_params: ATAPI_SOFT_RESET failed for"
 		    " drive %s:%d:%d: driver failed\n",
 		    device_xname(atac->atac_dev), chp->ch_channel, drive);
 		panic("wdc_atapi_get_params");
 	}
-	if (ata_c.flags & (AT_ERROR | AT_TIMEOU | AT_DF)) {
+	if (xfer.c_ata_c.flags & (AT_ERROR | AT_TIMEOU | AT_DF)) {
 		ATADEBUG_PRINT(("wdc_atapi_get_params: ATAPI_SOFT_RESET "
 		    "failed for drive %s:%d:%d: error 0x%x\n",
 		    device_xname(atac->atac_dev), chp->ch_channel, drive,
-		    ata_c.r_error), DEBUG_PROBE);
+		    xfer.c_ata_c.r_error), DEBUG_PROBE);
 		return -1;
 	}
 	chp->ch_drive[drive].state = 0;
@@ -227,7 +227,7 @@ wdc_atapi_get_params(struct scsipi_chann
 		ATADEBUG_PRINT(("wdc_atapi_get_params: ATAPI_IDENTIFY_DEVICE "
 		    "failed for drive %s:%d:%d: error 0x%x\n",
 		    device_xname(atac->atac_dev), chp->ch_channel, drive,
-		    ata_c.r_error), DEBUG_PROBE);
+		    xfer.c_ata_c.r_error), DEBUG_PROBE);
 		return -1;
 	}
 	return 0;
@@ -424,7 +424,7 @@ wdc_atapi_scsipi_request(struct scsipi_c
 			xfer->c_flags &= ~C_DMA;
 #endif	/* NATA_DMA */
 
-		xfer->c_cmd = sc_xfer;
+		xfer->c_scsipi = sc_xfer;
 		xfer->c_databuf = sc_xfer->data;
 		xfer->c_bcount = sc_xfer->datalen;
 		xfer->c_start = wdc_atapi_start;
@@ -454,7 +454,7 @@ wdc_atapi_start(struct ata_channel *chp,
 	struct atac_softc *atac = chp->ch_atac;
 	struct wdc_softc *wdc = CHAN_TO_WDC(chp);
 	struct wdc_regs *wdr = &wdc->regs[chp->ch_channel];
-	struct scsipi_xfer *sc_xfer = xfer->c_cmd;
+	struct scsipi_xfer *sc_xfer = xfer->c_scsipi;
 	struct ata_drive_datas *drvp = &chp->ch_drive[xfer->c_drive];
 	int wait_flags = (sc_xfer->xs_control & XS_CTL_POLL) ? AT_POLL : 0;
 	const char *errstring;
@@ -690,7 +690,7 @@ wdc_atapi_intr(struct ata_channel *chp, 
 	struct atac_softc *atac = chp->ch_atac;
 	struct wdc_softc *wdc = CHAN_TO_WDC(chp);
 	struct wdc_regs *wdr = &wdc->regs[chp->ch_channel];
-	struct scsipi_xfer *sc_xfer = xfer->c_cmd;
+	struct scsipi_xfer *sc_xfer = xfer->c_scsipi;
 	struct ata_drive_datas *drvp = &chp->ch_drive[xfer->c_drive];
 	int len, phase, i, retries=0;
 	int ire;
@@ -994,7 +994,7 @@ wdc_atapi_phase_complete(struct ata_xfer
 #if NATA_DMA || NATA_PIOBM
 	struct wdc_softc *wdc = CHAN_TO_WDC(chp);
 #endif
-	struct scsipi_xfer *sc_xfer = xfer->c_cmd;
+	struct scsipi_xfer *sc_xfer = xfer->c_scsipi;
 	struct ata_drive_datas *drvp = &chp->ch_drive[xfer->c_drive];
 
 	/* wait for DSC if needed */
@@ -1077,7 +1077,7 @@ static void
 wdc_atapi_done(struct ata_channel *chp, struct ata_xfer *xfer)
 {
 	struct atac_softc *atac = chp->ch_atac;
-	struct scsipi_xfer *sc_xfer = xfer->c_cmd;
+	struct scsipi_xfer *sc_xfer = xfer->c_scsipi;
 	int drive = xfer->c_drive;
 
 	ATADEBUG_PRINT(("wdc_atapi_done %s:%d:%d: flags 0x%x\n",
@@ -1102,7 +1102,7 @@ wdc_atapi_reset(struct ata_channel *chp,
 {
 	struct atac_softc *atac = chp->ch_atac;
 	struct ata_drive_datas *drvp = &chp->ch_drive[xfer->c_drive];
-	struct scsipi_xfer *sc_xfer = xfer->c_cmd;
+	struct scsipi_xfer *sc_xfer = xfer->c_scsipi;
 
 	wdccommandshort(chp, xfer->c_drive, ATAPI_SOFT_RESET);
 	drvp->state = 0;

Reply via email to