xref: /freebsd/sys/dev/ata/ata-all.h (revision 9f06a427)
18b89ef0aSSøren Schmidt /*-
2bb5bdd38SSøren Schmidt  * Copyright (c) 1998 - 2003 S�ren Schmidt <sos@FreeBSD.org>
38b89ef0aSSøren Schmidt  * All rights reserved.
48b89ef0aSSøren Schmidt  *
58b89ef0aSSøren Schmidt  * Redistribution and use in source and binary forms, with or without
68b89ef0aSSøren Schmidt  * modification, are permitted provided that the following conditions
78b89ef0aSSøren Schmidt  * are met:
88b89ef0aSSøren Schmidt  * 1. Redistributions of source code must retain the above copyright
98b89ef0aSSøren Schmidt  *    notice, this list of conditions and the following disclaimer,
108b89ef0aSSøren Schmidt  *    without modification, immediately at the beginning of the file.
118b89ef0aSSøren Schmidt  * 2. Redistributions in binary form must reproduce the above copyright
128b89ef0aSSøren Schmidt  *    notice, this list of conditions and the following disclaimer in the
138b89ef0aSSøren Schmidt  *    documentation and/or other materials provided with the distribution.
148b89ef0aSSøren Schmidt  * 3. The name of the author may not be used to endorse or promote products
158b89ef0aSSøren Schmidt  *    derived from this software without specific prior written permission.
168b89ef0aSSøren Schmidt  *
178b89ef0aSSøren Schmidt  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
188b89ef0aSSøren Schmidt  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
198b89ef0aSSøren Schmidt  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
208b89ef0aSSøren Schmidt  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
218b89ef0aSSøren Schmidt  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
228b89ef0aSSøren Schmidt  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
238b89ef0aSSøren Schmidt  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
248b89ef0aSSøren Schmidt  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
258b89ef0aSSøren Schmidt  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
268b89ef0aSSøren Schmidt  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
278b89ef0aSSøren Schmidt  *
28c3aac50fSPeter Wemm  * $FreeBSD$
298b89ef0aSSøren Schmidt  */
308b89ef0aSSøren Schmidt 
318b89ef0aSSøren Schmidt /* ATA register defines */
328b89ef0aSSøren Schmidt #define ATA_DATA			0x00	/* data register */
335fdbb0d2SSøren Schmidt 
348b89ef0aSSøren Schmidt #define ATA_ERROR			0x01	/* (R) error register */
355fdbb0d2SSøren Schmidt #define		ATA_E_ILI		0x01	/* illegal length */
363082a6dcSSøren Schmidt #define		ATA_E_NM		0x02	/* no media */
372b0a1c08SSøren Schmidt #define		ATA_E_ABORT		0x04	/* command aborted */
383082a6dcSSøren Schmidt #define		ATA_E_MCR		0x08	/* media change request */
393082a6dcSSøren Schmidt #define		ATA_E_IDNF		0x10	/* ID not found */
403082a6dcSSøren Schmidt #define		ATA_E_MC		0x20	/* media changed */
413082a6dcSSøren Schmidt #define		ATA_E_UNC		0x40	/* uncorrectable data */
423082a6dcSSøren Schmidt #define		ATA_E_ICRC		0x80	/* UDMA crc error */
435fdbb0d2SSøren Schmidt #define		ATA_E_MASK		0x0f	/* error mask */
445fdbb0d2SSøren Schmidt #define		ATA_SK_MASK		0xf0	/* sense key mask */
455fdbb0d2SSøren Schmidt #define		ATA_SK_NO_SENSE		0x00	/* no specific sense key info */
465fdbb0d2SSøren Schmidt #define		ATA_SK_RECOVERED_ERROR	0x10	/* command OK, data recovered */
475fdbb0d2SSøren Schmidt #define		ATA_SK_NOT_READY	0x20	/* no access to drive */
485fdbb0d2SSøren Schmidt #define		ATA_SK_MEDIUM_ERROR	0x30	/* non-recovered data error */
495fdbb0d2SSøren Schmidt #define		ATA_SK_HARDWARE_ERROR	0x40	/* non-recoverable HW failure */
505fdbb0d2SSøren Schmidt #define		ATA_SK_ILLEGAL_REQUEST	0x50	/* invalid command param(s) */
515fdbb0d2SSøren Schmidt #define		ATA_SK_UNIT_ATTENTION	0x60	/* media changed */
525fdbb0d2SSøren Schmidt #define		ATA_SK_DATA_PROTECT	0x70	/* write protect */
535fdbb0d2SSøren Schmidt #define		ATA_SK_BLANK_CHECK	0x80	/* blank check */
545fdbb0d2SSøren Schmidt #define		ATA_SK_VENDOR_SPECIFIC	0x90	/* vendor specific skey */
555fdbb0d2SSøren Schmidt #define		ATA_SK_COPY_ABORTED	0xa0	/* copy aborted */
565fdbb0d2SSøren Schmidt #define		ATA_SK_ABORTED_COMMAND	0xb0	/* command aborted, try again */
575fdbb0d2SSøren Schmidt #define		ATA_SK_EQUAL		0xc0	/* equal */
585fdbb0d2SSøren Schmidt #define		ATA_SK_VOLUME_OVERFLOW	0xd0	/* volume overflow */
595fdbb0d2SSøren Schmidt #define		ATA_SK_MISCOMPARE	0xe0	/* data dont match the medium */
605fdbb0d2SSøren Schmidt #define		ATA_SK_RESERVED		0xf0
612b0a1c08SSøren Schmidt 
6255bfaed1SSøren Schmidt #define ATA_FEATURE			0x01	/* (W) feature register */
6355bfaed1SSøren Schmidt #define		ATA_F_DMA		0x01	/* enable DMA */
6455bfaed1SSøren Schmidt #define		ATA_F_OVL		0x02	/* enable overlap */
6555bfaed1SSøren Schmidt 
6655bfaed1SSøren Schmidt #define ATA_COUNT			0x02	/* (W) sector count */
6755bfaed1SSøren Schmidt #define ATA_IREASON			0x02	/* (R) interrupt reason */
688b89ef0aSSøren Schmidt #define		ATA_I_CMD		0x01	/* cmd (1) | data (0) */
698b89ef0aSSøren Schmidt #define		ATA_I_IN		0x02	/* read (1) | write (0) */
708b89ef0aSSøren Schmidt #define		ATA_I_RELEASE		0x04	/* released bus (1) */
7155bfaed1SSøren Schmidt #define		ATA_I_TAGMASK		0xf8	/* tag mask */
728b89ef0aSSøren Schmidt 
738b89ef0aSSøren Schmidt #define ATA_SECTOR			0x03	/* sector # */
748b89ef0aSSøren Schmidt #define ATA_CYL_LSB			0x04	/* cylinder# LSB */
758b89ef0aSSøren Schmidt #define ATA_CYL_MSB			0x05	/* cylinder# MSB */
768b89ef0aSSøren Schmidt #define ATA_DRIVE			0x06	/* Sector/Drive/Head register */
7756bded8aSKris Kennaway #define		ATA_D_LBA		0x40	/* use LBA addressing */
788b89ef0aSSøren Schmidt #define		ATA_D_IBM		0xa0	/* 512 byte sectors, ECC */
798b89ef0aSSøren Schmidt 
808b89ef0aSSøren Schmidt #define ATA_CMD				0x07	/* command register */
818b89ef0aSSøren Schmidt 
828b89ef0aSSøren Schmidt #define ATA_STATUS			0x07	/* status register */
838b89ef0aSSøren Schmidt #define		ATA_S_ERROR		0x01	/* error */
848b89ef0aSSøren Schmidt #define		ATA_S_INDEX		0x02	/* index */
858b89ef0aSSøren Schmidt #define		ATA_S_CORR		0x04	/* data corrected */
868b89ef0aSSøren Schmidt #define		ATA_S_DRQ		0x08	/* data request */
8755bfaed1SSøren Schmidt #define		ATA_S_DSC		0x10	/* drive seek completed */
882b0a1c08SSøren Schmidt #define		ATA_S_SERVICE		0x10	/* drive needs service */
898b89ef0aSSøren Schmidt #define		ATA_S_DWF		0x20	/* drive write fault */
902b0a1c08SSøren Schmidt #define		ATA_S_DMA		0x20	/* DMA ready */
912b0a1c08SSøren Schmidt #define		ATA_S_READY		0x40	/* drive ready */
922b0a1c08SSøren Schmidt #define		ATA_S_BUSY		0x80	/* busy */
938b89ef0aSSøren Schmidt 
94566cf07aSSøren Schmidt #define ATA_ALTSTAT			0x08	/* alternate status register */
95511e9e72SSøren Schmidt #define ATA_ALTOFFSET			0x206	/* alternate registers offset */
960dbc12d8SSøren Schmidt #define ATA_PCCARD_ALTOFFSET		0x0e	/* do for PCCARD devices */
978ba4488cSSøren Schmidt #define ATA_PC98_ALTOFFSET		0x10c	/* do for PC98 devices */
988b89ef0aSSøren Schmidt #define		ATA_A_IDS		0x02	/* disable interrupts */
998b89ef0aSSøren Schmidt #define		ATA_A_RESET		0x04	/* RESET controller */
1008b89ef0aSSøren Schmidt #define		ATA_A_4BIT		0x08	/* 4 head bits */
1018b89ef0aSSøren Schmidt 
1025fdbb0d2SSøren Schmidt /* ATAPI misc defines */
1035fdbb0d2SSøren Schmidt #define ATAPI_MAGIC_LSB			0x14
1045fdbb0d2SSøren Schmidt #define ATAPI_MAGIC_MSB			0xeb
1055fdbb0d2SSøren Schmidt #define ATAPI_P_READ			(ATA_S_DRQ | ATA_I_IN)
1065fdbb0d2SSøren Schmidt #define ATAPI_P_WRITE			(ATA_S_DRQ)
1075fdbb0d2SSøren Schmidt #define ATAPI_P_CMDOUT			(ATA_S_DRQ | ATA_I_CMD)
1085fdbb0d2SSøren Schmidt #define ATAPI_P_DONEDRQ			(ATA_S_DRQ | ATA_I_CMD | ATA_I_IN)
1095fdbb0d2SSøren Schmidt #define ATAPI_P_DONE			(ATA_I_CMD | ATA_I_IN)
1105fdbb0d2SSøren Schmidt #define ATAPI_P_ABORT			0
1115fdbb0d2SSøren Schmidt 
11255bfaed1SSøren Schmidt /* misc defines */
1137dd6c388SSøren Schmidt #define ATA_PRIMARY			0x1f0
1147dd6c388SSøren Schmidt #define ATA_SECONDARY			0x170
1158ba4488cSSøren Schmidt #define ATA_PC98_BANK			0x432
1168b89ef0aSSøren Schmidt #define ATA_IOSIZE			0x08
117566cf07aSSøren Schmidt #define ATA_PC98_IOSIZE			0x10
118b17f7a1aSSøren Schmidt #define ATA_ALTIOSIZE			0x01
119b17f7a1aSSøren Schmidt #define ATA_BMIOSIZE			0x08
1208ba4488cSSøren Schmidt #define ATA_PC98_BANKIOSIZE		0x01
121331c488dSSøren Schmidt #define ATA_IOADDR_RID			0
122331c488dSSøren Schmidt #define ATA_ALTADDR_RID			1
123566cf07aSSøren Schmidt #define ATA_BMADDR_RID			0x20
1248ba4488cSSøren Schmidt #define ATA_PC98_ALTADDR_RID		8
1258ba4488cSSøren Schmidt #define ATA_PC98_BANKADDR_RID		9
1268ba4488cSSøren Schmidt 
127331c488dSSøren Schmidt #define ATA_IRQ_RID			0
1286ddce903SSøren Schmidt #define ATA_DEV(device)			((device == ATA_MASTER) ? 0 : 1)
129331c488dSSøren Schmidt 
13055bfaed1SSøren Schmidt /* busmaster DMA related defines */
13155bfaed1SSøren Schmidt #define ATA_DMA_ENTRIES			256
13255bfaed1SSøren Schmidt #define ATA_DMA_EOT			0x80000000
1338b89ef0aSSøren Schmidt 
134566cf07aSSøren Schmidt #define ATA_BMCMD_PORT			0x09
13555bfaed1SSøren Schmidt #define		ATA_BMCMD_START_STOP	0x01
13655bfaed1SSøren Schmidt #define		ATA_BMCMD_WRITE_READ	0x08
13755bfaed1SSøren Schmidt 
1381b39bd24SSøren Schmidt #define ATA_BMCTL_PORT			0x09
139566cf07aSSøren Schmidt #define ATA_BMDEVSPEC_0			0x0a
140566cf07aSSøren Schmidt #define ATA_BMSTAT_PORT			0x0b
14155bfaed1SSøren Schmidt #define		ATA_BMSTAT_ACTIVE	0x01
14255bfaed1SSøren Schmidt #define		ATA_BMSTAT_ERROR	0x02
14355bfaed1SSøren Schmidt #define		ATA_BMSTAT_INTERRUPT	0x04
14434276510SSøren Schmidt #define		ATA_BMSTAT_MASK		0x07
14555bfaed1SSøren Schmidt #define		ATA_BMSTAT_DMA_MASTER	0x20
14655bfaed1SSøren Schmidt #define		ATA_BMSTAT_DMA_SLAVE	0x40
1472b0a1c08SSøren Schmidt #define		ATA_BMSTAT_DMA_SIMPLEX	0x80
14855bfaed1SSøren Schmidt 
149566cf07aSSøren Schmidt #define ATA_BMDEVSPEC_1			0x0c
150566cf07aSSøren Schmidt #define ATA_BMDTP_PORT			0x0d
151566cf07aSSøren Schmidt 
1521b39bd24SSøren Schmidt #define ATA_IDX_ADDR			0x0e
1531b39bd24SSøren Schmidt #define ATA_IDX_DATA			0x0f
154566cf07aSSøren Schmidt #define ATA_MAX_RES			0x10
15555bfaed1SSøren Schmidt 
1565fdbb0d2SSøren Schmidt #define ATA_INTR_FLAGS			(INTR_MPSAFE|INTR_TYPE_BIO|INTR_ENTROPY)
1575fdbb0d2SSøren Schmidt #define ATA_OP_CONTINUES		0
1585fdbb0d2SSøren Schmidt #define ATA_OP_FINISHED			1
1595fdbb0d2SSøren Schmidt 
1605fdbb0d2SSøren Schmidt struct ata_request {
1615fdbb0d2SSøren Schmidt     struct ata_device		*device;	/* ptr to device softc */
1625fdbb0d2SSøren Schmidt     void			*driver;	/* driver specific */
1635fdbb0d2SSøren Schmidt 
1645fdbb0d2SSøren Schmidt     union {
1655fdbb0d2SSøren Schmidt 	struct {
1665fdbb0d2SSøren Schmidt 	    u_int8_t		command;	/* command reg */
1675fdbb0d2SSøren Schmidt 	    u_int8_t		feature;	/* feature reg */
1685fdbb0d2SSøren Schmidt 	    u_int64_t		lba;		/* lba reg */
1695fdbb0d2SSøren Schmidt 	    u_int16_t		count;		/* count reg */
1705fdbb0d2SSøren Schmidt 	} ata;
1715fdbb0d2SSøren Schmidt 	struct {
1725fdbb0d2SSøren Schmidt 	    u_int8_t		ccb[16];	/* ATAPI command block */
1735fdbb0d2SSøren Schmidt 	} atapi;
1745fdbb0d2SSøren Schmidt     } u;
1755fdbb0d2SSøren Schmidt 
1765fdbb0d2SSøren Schmidt     u_int8_t			status;		/* ATA status */
1775fdbb0d2SSøren Schmidt     u_int8_t			error;		/* ATA error */
1785fdbb0d2SSøren Schmidt     u_int8_t			dmastat;	/* DMA status */
1795fdbb0d2SSøren Schmidt 
1805fdbb0d2SSøren Schmidt     u_int32_t			bytecount;	/* bytes to transfer */
1815fdbb0d2SSøren Schmidt     u_int32_t			transfersize;	/* bytes pr transfer */
1825fdbb0d2SSøren Schmidt     u_int32_t			donecount;	/* bytes transferred */
1835fdbb0d2SSøren Schmidt     caddr_t			data;		/* pointer to data buf */
1845fdbb0d2SSøren Schmidt     int				flags;
1855fdbb0d2SSøren Schmidt #define		ATA_R_DONE		0x0001
1865fdbb0d2SSøren Schmidt #define		ATA_R_CONTROL		0x0002
1875fdbb0d2SSøren Schmidt #define		ATA_R_READ		0x0004
1885fdbb0d2SSøren Schmidt #define		ATA_R_WRITE		0x0008
1895fdbb0d2SSøren Schmidt 
1905fdbb0d2SSøren Schmidt #define		ATA_R_ATAPI		0x0010
1915fdbb0d2SSøren Schmidt #define		ATA_R_QUIET		0x0020
1925fdbb0d2SSøren Schmidt #define		ATA_R_DMA		0x0040
1935fdbb0d2SSøren Schmidt 
1945fdbb0d2SSøren Schmidt #define		ATA_R_ORDERED		0x0100
1955fdbb0d2SSøren Schmidt #define		ATA_R_AT_HEAD		0x0200
1965fdbb0d2SSøren Schmidt #define		ATA_R_REQUEUE		0x0400
1975fdbb0d2SSøren Schmidt #define		ATA_R_SKIPSTART		0x0800
1985fdbb0d2SSøren Schmidt 
1999f06a427SSøren Schmidt     void			(*callback)(struct ata_request *request);
2005fdbb0d2SSøren Schmidt     int				retries;	/* retry count */
2015fdbb0d2SSøren Schmidt     int				timeout;	/* timeout for this cmd */
2025fdbb0d2SSøren Schmidt     struct callout_handle	timeout_handle; /* handle for untimeout */
2035fdbb0d2SSøren Schmidt     int				result;		/* result error code */
2045fdbb0d2SSøren Schmidt     struct task			task;		/* task management */
2055fdbb0d2SSøren Schmidt     TAILQ_ENTRY(ata_request)	sequence;	/* sequence management */
2065fdbb0d2SSøren Schmidt     TAILQ_ENTRY(ata_request)	chain;		/* list management */
20755bfaed1SSøren Schmidt };
20855bfaed1SSøren Schmidt 
2096ddce903SSøren Schmidt /* structure describing an ATA/ATAPI device */
2106ddce903SSøren Schmidt struct ata_device {
2116ddce903SSøren Schmidt     struct ata_channel		*channel;
2126ddce903SSøren Schmidt     int				unit;		/* unit number */
2136ddce903SSøren Schmidt #define		ATA_MASTER		0x00
2146ddce903SSøren Schmidt #define		ATA_SLAVE		0x10
2156ddce903SSøren Schmidt 
2166ddce903SSøren Schmidt     char			*name;		/* device name */
2176ddce903SSøren Schmidt     struct ata_params		*param;		/* ata param structure */
2185fdbb0d2SSøren Schmidt     void			*softc;		/* ptr to softc for device */
2199f06a427SSøren Schmidt     void			(*attach)(struct ata_device *atadev);
2209f06a427SSøren Schmidt     void			(*detach)(struct ata_device *atadev);
2219f06a427SSøren Schmidt     void			(*start)(struct ata_device *atadev);
2226ddce903SSøren Schmidt     int				flags;
2236ddce903SSøren Schmidt #define		ATA_D_USE_CHS		0x0001
2246ddce903SSøren Schmidt #define		ATA_D_DETACHING		0x0002
2256ddce903SSøren Schmidt #define		ATA_D_MEDIA_CHANGED	0x0004
22633ede9b3SSøren Schmidt #define		ATA_D_ENC_PRESENT	0x0008
2276ddce903SSøren Schmidt 
2286ddce903SSøren Schmidt     int				cmd;		/* last cmd executed */
229bb5bdd38SSøren Schmidt     int				mode;		/* transfermode */
2309f06a427SSøren Schmidt     void			(*setmode)(struct ata_device *atadev, int mode);
2316ddce903SSøren Schmidt };
2326ddce903SSøren Schmidt 
2335fdbb0d2SSøren Schmidt /* structure for holding DMA address data */
2345fdbb0d2SSøren Schmidt struct ata_dmaentry {
2355fdbb0d2SSøren Schmidt     u_int32_t base;
2365fdbb0d2SSøren Schmidt     u_int32_t count;
2375fdbb0d2SSøren Schmidt };
2385fdbb0d2SSøren Schmidt 
239566cf07aSSøren Schmidt /* structure holding DMA related information */
2405fdbb0d2SSøren Schmidt struct ata_dma {
241566cf07aSSøren Schmidt     bus_dma_tag_t		dmatag;		/* parent DMA tag */
242566cf07aSSøren Schmidt     bus_dma_tag_t		cdmatag;	/* control DMA tag */
243566cf07aSSøren Schmidt     bus_dmamap_t		cdmamap;	/* control DMA map */
244566cf07aSSøren Schmidt     bus_dma_tag_t		ddmatag;	/* data DMA tag */
245566cf07aSSøren Schmidt     bus_dmamap_t		ddmamap;	/* data DMA map */
246566cf07aSSøren Schmidt     struct ata_dmaentry		*dmatab;	/* DMA transfer table */
247566cf07aSSøren Schmidt     bus_addr_t			mdmatab;	/* bus address of dmatab */
248566cf07aSSøren Schmidt     u_int32_t			alignment;	/* DMA engine alignment */
2495fdbb0d2SSøren Schmidt     u_int32_t			max_iosize;	/* DMA engine max IO size */
250566cf07aSSøren Schmidt     int				flags;
251566cf07aSSøren Schmidt #define ATA_DMA_ACTIVE			0x01	/* DMA transfer in progress */
252566cf07aSSøren Schmidt #define ATA_DMA_READ			0x02	/* transaction is a read */
253566cf07aSSøren Schmidt 
2549f06a427SSøren Schmidt     int (*alloc)(struct ata_channel *ch);
2559f06a427SSøren Schmidt     void (*free)(struct ata_channel *ch);
2569f06a427SSøren Schmidt     int (*setup)(struct ata_device *atadev, caddr_t data, int32_t count);
2579f06a427SSøren Schmidt     int (*start)(struct ata_channel *ch, caddr_t data, int32_t count, int dir);
2589f06a427SSøren Schmidt     int (*stop)(struct ata_channel *ch);
259566cf07aSSøren Schmidt };
260566cf07aSSøren Schmidt 
2615fdbb0d2SSøren Schmidt /* structure holding lowlevel functions */
2625fdbb0d2SSøren Schmidt struct ata_lowlevel {
2639f06a427SSøren Schmidt     void (*reset)(struct ata_channel *ch);
2649f06a427SSøren Schmidt     int (*transaction)(struct ata_request *request);
2659f06a427SSøren Schmidt     void (*interrupt)(void *channel);
2665fdbb0d2SSøren Schmidt };
2675fdbb0d2SSøren Schmidt 
268566cf07aSSøren Schmidt /* structure holding resources for an ATA channel */
269566cf07aSSøren Schmidt struct ata_resource {
270566cf07aSSøren Schmidt     struct resource		*res;
271566cf07aSSøren Schmidt     int				offset;
272bb5bdd38SSøren Schmidt };
273bb5bdd38SSøren Schmidt 
2746ddce903SSøren Schmidt /* structure describing an ATA channel */
2756ddce903SSøren Schmidt struct ata_channel {
276f1cb6ca3SSøren Schmidt     struct device		*dev;		/* device handle */
2776ddce903SSøren Schmidt     int				unit;		/* channel number */
278566cf07aSSøren Schmidt     struct ata_resource		r_io[ATA_MAX_RES];/* I/O resources */
27947351d27SSøren Schmidt     struct resource		*r_irq;		/* interrupt of this channel */
2801a488af6SSøren Schmidt     void			*ih;		/* interrupt handle */
2815fdbb0d2SSøren Schmidt     struct ata_lowlevel		hw;		/* lowlevel HW functions */
2825fdbb0d2SSøren Schmidt     struct ata_dma		*dma;		/* DMA data / functions */
283bb5bdd38SSøren Schmidt     int				flags;		/* channel flags */
2848975ededSSøren Schmidt #define		ATA_NO_SLAVE		0x01
2858975ededSSøren Schmidt #define		ATA_USE_16BIT		0x02
2865dd00980SSøren Schmidt #define		ATA_USE_PC98GEOM	0x04
2875dd00980SSøren Schmidt #define		ATA_ATAPI_DMA_RO	0x08
2885fdbb0d2SSøren Schmidt #define		ATA_48BIT_ACTIVE	0x10
28934276510SSøren Schmidt 
2906ddce903SSøren Schmidt     struct ata_device		device[2];	/* devices on this channel */
2916ddce903SSøren Schmidt #define		MASTER			0x00
2926ddce903SSøren Schmidt #define		SLAVE			0x01
2936ddce903SSøren Schmidt 
2948563f77dSSøren Schmidt     int				devices;	/* what is present */
295f63c7e58SSøren Schmidt #define		ATA_ATA_MASTER		0x01
296f63c7e58SSøren Schmidt #define		ATA_ATA_SLAVE		0x02
297f63c7e58SSøren Schmidt #define		ATA_ATAPI_MASTER	0x04
298f63c7e58SSøren Schmidt #define		ATA_ATAPI_SLAVE		0x08
299f63c7e58SSøren Schmidt 
3005fdbb0d2SSøren Schmidt     int				state;		/* ATA channel state control */
3018ea3ce2aSSøren Schmidt #define		ATA_IDLE		0x0000
3025fdbb0d2SSøren Schmidt #define		ATA_ACTIVE		0x0001
3035fdbb0d2SSøren Schmidt #define		ATA_CONTROL		0x0002
3048b89ef0aSSøren Schmidt 
305bb5bdd38SSøren Schmidt     void (*locking)(struct ata_channel *, int);
3068ba4488cSSøren Schmidt #define		ATA_LF_LOCK		0x0001
3078ba4488cSSøren Schmidt #define		ATA_LF_UNLOCK		0x0002
3088ba4488cSSøren Schmidt 
3095fdbb0d2SSøren Schmidt     struct mtx			queue_mtx;
3105fdbb0d2SSøren Schmidt     TAILQ_HEAD(, ata_request)	ata_queue;	/* head of ATA queue */
31134276510SSøren Schmidt     void			*running;	/* currently running request */
3128b89ef0aSSøren Schmidt };
3138b89ef0aSSøren Schmidt 
3145fdbb0d2SSøren Schmidt /* ATAPI request sense structure */
3155fdbb0d2SSøren Schmidt struct atapi_sense {
3165fdbb0d2SSøren Schmidt     u_int8_t	error_code	:7;		/* current or deferred errors */
3175fdbb0d2SSøren Schmidt     u_int8_t	valid		:1;		/* follows ATAPI spec */
3185fdbb0d2SSøren Schmidt     u_int8_t	segment;			/* Segment number */
3195fdbb0d2SSøren Schmidt     u_int8_t	sense_key	:4;		/* sense key */
3205fdbb0d2SSøren Schmidt     u_int8_t	reserved2_4	:1;		/* reserved */
3215fdbb0d2SSøren Schmidt     u_int8_t	ili		:1;		/* incorrect length indicator */
3225fdbb0d2SSøren Schmidt     u_int8_t	eom		:1;		/* end of medium */
3235fdbb0d2SSøren Schmidt     u_int8_t	filemark	:1;		/* filemark */
3245fdbb0d2SSøren Schmidt     u_int32_t	cmd_info __packed;		/* cmd information */
3255fdbb0d2SSøren Schmidt     u_int8_t	sense_length;			/* additional sense len (n-7) */
3265fdbb0d2SSøren Schmidt     u_int32_t	cmd_specific_info __packed;	/* additional cmd spec info */
3275fdbb0d2SSøren Schmidt     u_int8_t	asc;				/* additional sense code */
3285fdbb0d2SSøren Schmidt     u_int8_t	ascq;				/* additional sense code qual */
3295fdbb0d2SSøren Schmidt     u_int8_t	replaceable_unit_code;		/* replaceable unit code */
3305fdbb0d2SSøren Schmidt     u_int8_t	sk_specific	:7;		/* sense key specific */
3315fdbb0d2SSøren Schmidt     u_int8_t	sksv		:1;		/* sense key specific info OK */
3325fdbb0d2SSøren Schmidt     u_int8_t	sk_specific1;			/* sense key specific */
3335fdbb0d2SSøren Schmidt     u_int8_t	sk_specific2;			/* sense key specific */
3345fdbb0d2SSøren Schmidt };
3355fdbb0d2SSøren Schmidt 
33633ede9b3SSøren Schmidt /* disk bay/enclosure related */
3376ddce903SSøren Schmidt #define		ATA_LED_OFF		0x00
3386ddce903SSøren Schmidt #define		ATA_LED_RED		0x01
3396ddce903SSøren Schmidt #define		ATA_LED_GREEN		0x02
3406ddce903SSøren Schmidt #define		ATA_LED_ORANGE		0x03
34133ede9b3SSøren Schmidt #define		ATA_LED_MASK		0x03
3426ddce903SSøren Schmidt 
3432c483f9eSSøren Schmidt /* externs */
34447351d27SSøren Schmidt extern devclass_t ata_devclass;
3458ba4488cSSøren Schmidt extern struct intr_config_hook *ata_delayed_attach;
3465fdbb0d2SSøren Schmidt extern int ata_dma, ata_wc, atapi_dma;
3478b89ef0aSSøren Schmidt 
3488b89ef0aSSøren Schmidt /* public prototypes */
3495fdbb0d2SSøren Schmidt /* ata-all.c: */
3509f06a427SSøren Schmidt int ata_probe(device_t dev);
3519f06a427SSøren Schmidt int ata_attach(device_t dev);
3529f06a427SSøren Schmidt int ata_detach(device_t dev);
3539f06a427SSøren Schmidt int ata_suspend(device_t dev);
3549f06a427SSøren Schmidt int ata_resume(device_t dev);
3559f06a427SSøren Schmidt int ata_printf(struct ata_channel *ch, int device, const char *fmt, ...) __printflike(3, 4);
3569f06a427SSøren Schmidt int ata_prtdev(struct ata_device *atadev, const char *fmt, ...) __printflike(2, 3);
3579f06a427SSøren Schmidt void ata_set_name(struct ata_device *atadev, char *name, int lun);
3589f06a427SSøren Schmidt void ata_free_name(struct ata_device *atadev);
3599f06a427SSøren Schmidt int ata_get_lun(u_int32_t *map);
3609f06a427SSøren Schmidt int ata_test_lun(u_int32_t *map, int lun);
3619f06a427SSøren Schmidt void ata_free_lun(u_int32_t *map, int lun);
3629f06a427SSøren Schmidt char *ata_mode2str(int mode);
3635fdbb0d2SSøren Schmidt int ata_pmode(struct ata_params *ap);
3645fdbb0d2SSøren Schmidt int ata_wmode(struct ata_params *ap);
3655fdbb0d2SSøren Schmidt int ata_umode(struct ata_params *ap);
3665fdbb0d2SSøren Schmidt int ata_limit_mode(struct ata_device *atadev, int mode, int maxmode);
3675fdbb0d2SSøren Schmidt 
3685fdbb0d2SSøren Schmidt /* ata-queue.c: */
3695fdbb0d2SSøren Schmidt int ata_reinit(struct ata_channel *ch);
3705fdbb0d2SSøren Schmidt void ata_start(struct ata_channel *ch);
3715fdbb0d2SSøren Schmidt struct ata_request *ata_alloc_request(void);
3725fdbb0d2SSøren Schmidt void ata_free_request(struct ata_request *request);
3735fdbb0d2SSøren Schmidt int ata_controlcmd(struct ata_device *atadev, u_int8_t command, u_int16_t feature, u_int64_t lba, u_int16_t count);
3745fdbb0d2SSøren Schmidt int ata_atapicmd(struct ata_device *atadev, u_int8_t *ccb, caddr_t data, int count, int flags, int timeout);
3755fdbb0d2SSøren Schmidt void ata_queue_request(struct ata_request *request);
3765fdbb0d2SSøren Schmidt void ata_finish(struct ata_request *request);
3775fdbb0d2SSøren Schmidt char *ata_cmd2str(struct ata_request *request);
3785fdbb0d2SSøren Schmidt 
3795fdbb0d2SSøren Schmidt /* ata-lowlevel.c: */
3805fdbb0d2SSøren Schmidt void ata_generic_hw(struct ata_channel *ch);
3815fdbb0d2SSøren Schmidt 
3825fdbb0d2SSøren Schmidt /* subdrivers */
3839f06a427SSøren Schmidt void ad_attach(struct ata_device *atadev);
3849f06a427SSøren Schmidt void acd_attach(struct ata_device *atadev);
3859f06a427SSøren Schmidt void afd_attach(struct ata_device *atadev);
3869f06a427SSøren Schmidt void ast_attach(struct ata_device *atadev);
3879f06a427SSøren Schmidt void atapi_cam_attach_bus(struct ata_channel *ch);
3889f06a427SSøren Schmidt void atapi_cam_detach_bus(struct ata_channel *ch);
3899f06a427SSøren Schmidt void atapi_cam_reinit_bus(struct ata_channel *ch);
390b17f7a1aSSøren Schmidt 
391fe86c448SSøren Schmidt /* macros for locking a channel */
392fe86c448SSøren Schmidt #define ATA_LOCK_CH(ch, value) \
3935fdbb0d2SSøren Schmidt 	atomic_cmpset_acq_int(&(ch)->state, ATA_IDLE, (value))
394fe86c448SSøren Schmidt 
395fe86c448SSøren Schmidt #define ATA_SLEEPLOCK_CH(ch, value) \
3965fdbb0d2SSøren Schmidt 	while (!atomic_cmpset_acq_int(&(ch)->state, ATA_IDLE, (value))) \
397fe86c448SSøren Schmidt 	    tsleep((caddr_t)&(ch), PRIBIO, "atalck", 1);
398fe86c448SSøren Schmidt 
3995fdbb0d2SSøren Schmidt #define ATA_FORCELOCK_CH(ch, value) atomic_store_rel_int(&(ch)->state, (value))
400fe86c448SSøren Schmidt 
4015fdbb0d2SSøren Schmidt #define ATA_UNLOCK_CH(ch) atomic_store_rel_int(&(ch)->state, ATA_IDLE)
402fe86c448SSøren Schmidt 
4038ea3ce2aSSøren Schmidt /* macros to hide busspace uglyness */
404b17f7a1aSSøren Schmidt #define ATA_INB(res, offset) \
405b17f7a1aSSøren Schmidt 	bus_space_read_1(rman_get_bustag((res)), \
406b17f7a1aSSøren Schmidt 			 rman_get_bushandle((res)), (offset))
407566cf07aSSøren Schmidt 
408b17f7a1aSSøren Schmidt #define ATA_INW(res, offset) \
409b17f7a1aSSøren Schmidt 	bus_space_read_2(rman_get_bustag((res)), \
410b17f7a1aSSøren Schmidt 			 rman_get_bushandle((res)), (offset))
411b17f7a1aSSøren Schmidt #define ATA_INL(res, offset) \
412b17f7a1aSSøren Schmidt 	bus_space_read_4(rman_get_bustag((res)), \
413b17f7a1aSSøren Schmidt 			 rman_get_bushandle((res)), (offset))
414b17f7a1aSSøren Schmidt #define ATA_INSW(res, offset, addr, count) \
415b17f7a1aSSøren Schmidt 	bus_space_read_multi_2(rman_get_bustag((res)), \
416b17f7a1aSSøren Schmidt 			       rman_get_bushandle((res)), \
417b17f7a1aSSøren Schmidt 			       (offset), (addr), (count))
4187800211bSSøren Schmidt #define ATA_INSW_STRM(res, offset, addr, count) \
4197800211bSSøren Schmidt 	bus_space_read_multi_stream_2(rman_get_bustag((res)), \
4207800211bSSøren Schmidt 				      rman_get_bushandle((res)), \
4217800211bSSøren Schmidt 				      (offset), (addr), (count))
422b17f7a1aSSøren Schmidt #define ATA_INSL(res, offset, addr, count) \
423b17f7a1aSSøren Schmidt 	bus_space_read_multi_4(rman_get_bustag((res)), \
424b17f7a1aSSøren Schmidt 			       rman_get_bushandle((res)), \
425b17f7a1aSSøren Schmidt 			       (offset), (addr), (count))
4267800211bSSøren Schmidt #define ATA_INSL_STRM(res, offset, addr, count) \
4277800211bSSøren Schmidt 	bus_space_read_multi_stream_4(rman_get_bustag((res)), \
4287800211bSSøren Schmidt 				      rman_get_bushandle((res)), \
4297800211bSSøren Schmidt 				      (offset), (addr), (count))
430b17f7a1aSSøren Schmidt #define ATA_OUTB(res, offset, value) \
431b17f7a1aSSøren Schmidt 	bus_space_write_1(rman_get_bustag((res)), \
432b17f7a1aSSøren Schmidt 			  rman_get_bushandle((res)), (offset), (value))
433b17f7a1aSSøren Schmidt #define ATA_OUTW(res, offset, value) \
434b17f7a1aSSøren Schmidt 	bus_space_write_2(rman_get_bustag((res)), \
435b17f7a1aSSøren Schmidt 			  rman_get_bushandle((res)), (offset), (value))
436b17f7a1aSSøren Schmidt #define ATA_OUTL(res, offset, value) \
437b17f7a1aSSøren Schmidt 	bus_space_write_4(rman_get_bustag((res)), \
438b17f7a1aSSøren Schmidt 			  rman_get_bushandle((res)), (offset), (value))
439b17f7a1aSSøren Schmidt #define ATA_OUTSW(res, offset, addr, count) \
440b17f7a1aSSøren Schmidt 	bus_space_write_multi_2(rman_get_bustag((res)), \
441b17f7a1aSSøren Schmidt 				rman_get_bushandle((res)), \
442b17f7a1aSSøren Schmidt 				(offset), (addr), (count))
4437800211bSSøren Schmidt #define ATA_OUTSW_STRM(res, offset, addr, count) \
4447800211bSSøren Schmidt 	bus_space_write_multi_stream_2(rman_get_bustag((res)), \
4457800211bSSøren Schmidt 				       rman_get_bushandle((res)), \
4467800211bSSøren Schmidt 				       (offset), (addr), (count))
447b17f7a1aSSøren Schmidt #define ATA_OUTSL(res, offset, addr, count) \
448b17f7a1aSSøren Schmidt 	bus_space_write_multi_4(rman_get_bustag((res)), \
449b17f7a1aSSøren Schmidt 				rman_get_bushandle((res)), \
450b17f7a1aSSøren Schmidt 				(offset), (addr), (count))
4517800211bSSøren Schmidt #define ATA_OUTSL_STRM(res, offset, addr, count) \
4527800211bSSøren Schmidt 	bus_space_write_multi_stream_4(rman_get_bustag((res)), \
4537800211bSSøren Schmidt 				       rman_get_bushandle((res)), \
4547800211bSSøren Schmidt 				       (offset), (addr), (count))
4551b39bd24SSøren Schmidt 
4561b39bd24SSøren Schmidt #define ATA_IDX_SET(ch, idx) \
4571b39bd24SSøren Schmidt 	ATA_OUTB(ch->r_io[ATA_IDX_ADDR].res, ch->r_io[ATA_IDX_ADDR].offset, \
4581b39bd24SSøren Schmidt 		 ch->r_io[idx].offset)
4591b39bd24SSøren Schmidt 
460566cf07aSSøren Schmidt #define ATA_IDX_INB(ch, idx) \
4611b39bd24SSøren Schmidt 	((ch->r_io[idx].res) \
4621b39bd24SSøren Schmidt 	? ATA_INB(ch->r_io[idx].res, ch->r_io[idx].offset) \
4631b39bd24SSøren Schmidt 	: (ATA_IDX_SET(ch, idx), \
4641b39bd24SSøren Schmidt 	   ATA_INB(ch->r_io[ATA_IDX_DATA].res, ch->r_io[ATA_IDX_DATA].offset)))
4651b39bd24SSøren Schmidt 
466566cf07aSSøren Schmidt #define ATA_IDX_INW(ch, idx) \
4671b39bd24SSøren Schmidt 	((ch->r_io[idx].res) \
4681b39bd24SSøren Schmidt 	? ATA_INW(ch->r_io[idx].res, ch->r_io[idx].offset) \
4691b39bd24SSøren Schmidt 	: (ATA_IDX_SET(ch, idx), \
4701b39bd24SSøren Schmidt 	   ATA_INW(ch->r_io[ATA_IDX_DATA].res, ch->r_io[ATA_IDX_DATA].offset)))
4711b39bd24SSøren Schmidt 
472566cf07aSSøren Schmidt #define ATA_IDX_INL(ch, idx) \
4731b39bd24SSøren Schmidt 	((ch->r_io[idx].res) \
4741b39bd24SSøren Schmidt 	? ATA_INL(ch->r_io[idx].res, ch->r_io[idx].offset) \
4751b39bd24SSøren Schmidt 	: (ATA_IDX_SET(ch, idx), \
4761b39bd24SSøren Schmidt 	   ATA_INL(ch->r_io[ATA_IDX_DATA].res, ch->r_io[ATA_IDX_DATA].offset)))
4771b39bd24SSøren Schmidt 
478566cf07aSSøren Schmidt #define ATA_IDX_INSW(ch, idx, addr, count) \
4791b39bd24SSøren Schmidt 	((ch->r_io[idx].res) \
4801b39bd24SSøren Schmidt 	? ATA_INSW(ch->r_io[idx].res, ch->r_io[idx].offset, addr, count) \
4811b39bd24SSøren Schmidt 	: (ATA_IDX_SET(ch, idx), \
4821b39bd24SSøren Schmidt 	   ATA_INSW(ch->r_io[ATA_IDX_DATA].res, \
4831b39bd24SSøren Schmidt 		    ch->r_io[ATA_IDX_DATA].offset, addr, count)))
4841b39bd24SSøren Schmidt 
485566cf07aSSøren Schmidt #define ATA_IDX_INSW_STRM(ch, idx, addr, count) \
4861b39bd24SSøren Schmidt 	((ch->r_io[idx].res) \
4871b39bd24SSøren Schmidt 	? ATA_INSW_STRM(ch->r_io[idx].res, ch->r_io[idx].offset, addr, count) \
4881b39bd24SSøren Schmidt 	: (ATA_IDX_SET(ch, idx), \
4891b39bd24SSøren Schmidt 	   ATA_INSW_STRM(ch->r_io[ATA_IDX_DATA].res, \
4901b39bd24SSøren Schmidt 			 ch->r_io[ATA_IDX_DATA].offset, addr, count)))
4911b39bd24SSøren Schmidt 
492566cf07aSSøren Schmidt #define ATA_IDX_INSL(ch, idx, addr, count) \
4931b39bd24SSøren Schmidt 	((ch->r_io[idx].res) \
4941b39bd24SSøren Schmidt 	? ATA_INSL(ch->r_io[idx].res, ch->r_io[idx].offset, addr, count) \
4951b39bd24SSøren Schmidt 	: (ATA_IDX_SET(ch, idx), \
4961b39bd24SSøren Schmidt 	   ATA_INSL(ch->r_io[ATA_IDX_DATA].res, \
4971b39bd24SSøren Schmidt 		    ch->r_io[ATA_IDX_DATA].offset, addr, count)))
4981b39bd24SSøren Schmidt 
499566cf07aSSøren Schmidt #define ATA_IDX_INSL_STRM(ch, idx, addr, count) \
5001b39bd24SSøren Schmidt 	((ch->r_io[idx].res) \
5011b39bd24SSøren Schmidt 	? ATA_INSL_STRM(ch->r_io[idx].res, ch->r_io[idx].offset, addr, count) \
5021b39bd24SSøren Schmidt 	: (ATA_IDX_SET(ch, idx), \
5031b39bd24SSøren Schmidt 	   ATA_INSL_STRM(ch->r_io[ATA_IDX_DATA].res, \
5041b39bd24SSøren Schmidt 			 ch->r_io[ATA_IDX_DATA].offset, addr, count)))
5051b39bd24SSøren Schmidt 
506566cf07aSSøren Schmidt #define ATA_IDX_OUTB(ch, idx, value) \
5071b39bd24SSøren Schmidt 	((ch->r_io[idx].res) \
5081b39bd24SSøren Schmidt 	? ATA_OUTB(ch->r_io[idx].res, ch->r_io[idx].offset, value) \
5091b39bd24SSøren Schmidt 	: (ATA_IDX_SET(ch, idx), \
5101b39bd24SSøren Schmidt 	   ATA_OUTB(ch->r_io[ATA_IDX_DATA].res, \
5111b39bd24SSøren Schmidt 		    ch->r_io[ATA_IDX_DATA].offset, value)))
5121b39bd24SSøren Schmidt 
513566cf07aSSøren Schmidt #define ATA_IDX_OUTW(ch, idx, value) \
5141b39bd24SSøren Schmidt 	((ch->r_io[idx].res) \
5151b39bd24SSøren Schmidt 	? ATA_OUTW(ch->r_io[idx].res, ch->r_io[idx].offset, value) \
5161b39bd24SSøren Schmidt 	: (ATA_IDX_SET(ch, idx), \
5171b39bd24SSøren Schmidt 	   ATA_OUTW(ch->r_io[ATA_IDX_DATA].res, \
5181b39bd24SSøren Schmidt 		    ch->r_io[ATA_IDX_DATA].offset, value)))
5191b39bd24SSøren Schmidt 
520566cf07aSSøren Schmidt #define ATA_IDX_OUTL(ch, idx, value) \
5211b39bd24SSøren Schmidt 	((ch->r_io[idx].res) \
5221b39bd24SSøren Schmidt 	? ATA_OUTL(ch->r_io[idx].res, ch->r_io[idx].offset, value) \
5231b39bd24SSøren Schmidt 	: (ATA_IDX_SET(ch, idx), \
5241b39bd24SSøren Schmidt 	   ATA_OUTL(ch->r_io[ATA_IDX_DATA].res, \
5251b39bd24SSøren Schmidt 		    ch->r_io[ATA_IDX_DATA].offset, value)))
5261b39bd24SSøren Schmidt 
527566cf07aSSøren Schmidt #define ATA_IDX_OUTSW(ch, idx, addr, count) \
5281b39bd24SSøren Schmidt 	((ch->r_io[idx].res) \
5291b39bd24SSøren Schmidt 	? ATA_OUTSW(ch->r_io[idx].res, ch->r_io[idx].offset, addr, count) \
5301b39bd24SSøren Schmidt 	: (ATA_IDX_SET(ch, idx), \
5311b39bd24SSøren Schmidt 	   ATA_OUTSW(ch->r_io[ATA_IDX_DATA].res, \
5321b39bd24SSøren Schmidt 		     ch->r_io[ATA_IDX_DATA].offset, addr, count)))
5331b39bd24SSøren Schmidt 
534566cf07aSSøren Schmidt #define ATA_IDX_OUTSW_STRM(ch, idx, addr, count) \
5351b39bd24SSøren Schmidt 	((ch->r_io[idx].res) \
5361b39bd24SSøren Schmidt 	? ATA_OUTSW_STRM(ch->r_io[idx].res, ch->r_io[idx].offset, addr, count) \
5371b39bd24SSøren Schmidt 	: (ATA_IDX_SET(ch, idx), \
5381b39bd24SSøren Schmidt 	   ATA_OUTSW_STRM(ch->r_io[ATA_IDX_DATA].res, \
5391b39bd24SSøren Schmidt 			  ch->r_io[ATA_IDX_DATA].offset, addr, count)))
5401b39bd24SSøren Schmidt 
541566cf07aSSøren Schmidt #define ATA_IDX_OUTSL(ch, idx, addr, count) \
5421b39bd24SSøren Schmidt 	((ch->r_io[idx].res) \
5431b39bd24SSøren Schmidt 	? ATA_OUTSL(ch->r_io[idx].res, ch->r_io[idx].offset, addr, count) \
5441b39bd24SSøren Schmidt 	: (ATA_IDX_SET(ch, idx), \
5451b39bd24SSøren Schmidt 	   ATA_OUTSL(ch->r_io[ATA_IDX_DATA].res, \
5461b39bd24SSøren Schmidt 		     ch->r_io[ATA_IDX_DATA].offset, addr, count)))
5471b39bd24SSøren Schmidt 
548566cf07aSSøren Schmidt #define ATA_IDX_OUTSL_STRM(ch, idx, addr, count) \
5491b39bd24SSøren Schmidt 	((ch->r_io[idx].res) \
5501b39bd24SSøren Schmidt 	? ATA_OUTSL_STRM(ch->r_io[idx].res, ch->r_io[idx].offset, addr, count) \
5511b39bd24SSøren Schmidt 	: (ATA_IDX_SET(ch, idx), \
5521b39bd24SSøren Schmidt 	   ATA_OUTSL_STRM(ch->r_io[ATA_IDX_DATA].res, \
5531b39bd24SSøren Schmidt 			  ch->r_io[ATA_IDX_DATA].offset, addr, count)))
554