ata-all.h revision 125199
1/*-
2 * Copyright (c) 1998 - 2004 S�ren Schmidt <sos@FreeBSD.org>
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 *    notice, this list of conditions and the following disclaimer,
10 *    without modification, immediately at the beginning of the file.
11 * 2. Redistributions in binary form must reproduce the above copyright
12 *    notice, this list of conditions and the following disclaimer in the
13 *    documentation and/or other materials provided with the distribution.
14 * 3. The name of the author may not be used to endorse or promote products
15 *    derived from this software without specific prior written permission.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 *
28 * $FreeBSD: head/sys/dev/ata/ata-all.h 125199 2004-01-29 15:03:01Z sos $
29 */
30
31/* ATA register defines */
32#define ATA_DATA			0x00	/* data register */
33
34#define ATA_ERROR			0x01	/* (R) error register */
35#define		ATA_E_ILI		0x01	/* illegal length */
36#define		ATA_E_NM		0x02	/* no media */
37#define		ATA_E_ABORT		0x04	/* command aborted */
38#define		ATA_E_MCR		0x08	/* media change request */
39#define		ATA_E_IDNF		0x10	/* ID not found */
40#define		ATA_E_MC		0x20	/* media changed */
41#define		ATA_E_UNC		0x40	/* uncorrectable data */
42#define		ATA_E_ICRC		0x80	/* UDMA crc error */
43#define		ATA_E_MASK		0x0f	/* error mask */
44#define		ATA_SK_MASK		0xf0	/* sense key mask */
45#define		ATA_SK_NO_SENSE		0x00	/* no specific sense key info */
46#define		ATA_SK_RECOVERED_ERROR	0x10	/* command OK, data recovered */
47#define		ATA_SK_NOT_READY	0x20	/* no access to drive */
48#define		ATA_SK_MEDIUM_ERROR	0x30	/* non-recovered data error */
49#define		ATA_SK_HARDWARE_ERROR	0x40	/* non-recoverable HW failure */
50#define		ATA_SK_ILLEGAL_REQUEST	0x50	/* invalid command param(s) */
51#define		ATA_SK_UNIT_ATTENTION	0x60	/* media changed */
52#define		ATA_SK_DATA_PROTECT	0x70	/* write protect */
53#define		ATA_SK_BLANK_CHECK	0x80	/* blank check */
54#define		ATA_SK_VENDOR_SPECIFIC	0x90	/* vendor specific skey */
55#define		ATA_SK_COPY_ABORTED	0xa0	/* copy aborted */
56#define		ATA_SK_ABORTED_COMMAND	0xb0	/* command aborted, try again */
57#define		ATA_SK_EQUAL		0xc0	/* equal */
58#define		ATA_SK_VOLUME_OVERFLOW	0xd0	/* volume overflow */
59#define		ATA_SK_MISCOMPARE	0xe0	/* data dont match the medium */
60#define		ATA_SK_RESERVED		0xf0
61
62#define ATA_FEATURE			0x01	/* (W) feature register */
63#define		ATA_F_DMA		0x01	/* enable DMA */
64#define		ATA_F_OVL		0x02	/* enable overlap */
65
66#define ATA_COUNT			0x02	/* (W) sector count */
67#define ATA_IREASON			0x02	/* (R) interrupt reason */
68#define		ATA_I_CMD		0x01	/* cmd (1) | data (0) */
69#define		ATA_I_IN		0x02	/* read (1) | write (0) */
70#define		ATA_I_RELEASE		0x04	/* released bus (1) */
71#define		ATA_I_TAGMASK		0xf8	/* tag mask */
72
73#define ATA_SECTOR			0x03	/* sector # */
74#define ATA_CYL_LSB			0x04	/* cylinder# LSB */
75#define ATA_CYL_MSB			0x05	/* cylinder# MSB */
76#define ATA_DRIVE			0x06	/* Sector/Drive/Head register */
77#define		ATA_D_LBA		0x40	/* use LBA addressing */
78#define		ATA_D_IBM		0xa0	/* 512 byte sectors, ECC */
79
80#define ATA_CMD				0x07	/* command register */
81
82#define ATA_STATUS			0x07	/* status register */
83#define		ATA_S_ERROR		0x01	/* error */
84#define		ATA_S_INDEX		0x02	/* index */
85#define		ATA_S_CORR		0x04	/* data corrected */
86#define		ATA_S_DRQ		0x08	/* data request */
87#define		ATA_S_DSC		0x10	/* drive seek completed */
88#define		ATA_S_SERVICE		0x10	/* drive needs service */
89#define		ATA_S_DWF		0x20	/* drive write fault */
90#define		ATA_S_DMA		0x20	/* DMA ready */
91#define		ATA_S_READY		0x40	/* drive ready */
92#define		ATA_S_BUSY		0x80	/* busy */
93
94#define ATA_ALTSTAT			0x08	/* alternate status register */
95#define ATA_ALTOFFSET			0x206	/* alternate registers offset */
96#define ATA_PCCARD_ALTOFFSET		0x0e	/* do for PCCARD devices */
97#define ATA_PC98_ALTOFFSET		0x10c	/* do for PC98 devices */
98#define		ATA_A_IDS		0x02	/* disable interrupts */
99#define		ATA_A_RESET		0x04	/* RESET controller */
100#define		ATA_A_4BIT		0x08	/* 4 head bits */
101
102/* ATAPI misc defines */
103#define ATAPI_MAGIC_LSB			0x14
104#define ATAPI_MAGIC_MSB			0xeb
105#define ATAPI_P_READ			(ATA_S_DRQ | ATA_I_IN)
106#define ATAPI_P_WRITE			(ATA_S_DRQ)
107#define ATAPI_P_CMDOUT			(ATA_S_DRQ | ATA_I_CMD)
108#define ATAPI_P_DONEDRQ			(ATA_S_DRQ | ATA_I_CMD | ATA_I_IN)
109#define ATAPI_P_DONE			(ATA_I_CMD | ATA_I_IN)
110#define ATAPI_P_ABORT			0
111
112/* misc defines */
113#define ATA_PRIMARY			0x1f0
114#define ATA_SECONDARY			0x170
115#define ATA_PC98_BANK			0x432
116#define ATA_IOSIZE			0x08
117#define ATA_PC98_IOSIZE			0x10
118#define ATA_ALTIOSIZE			0x01
119#define ATA_BMIOSIZE			0x08
120#define ATA_PC98_BANKIOSIZE		0x01
121#define ATA_IOADDR_RID			0
122#define ATA_ALTADDR_RID			1
123#define ATA_BMADDR_RID			0x20
124#define ATA_PC98_ALTADDR_RID		8
125#define ATA_PC98_BANKADDR_RID		9
126
127#define ATA_IRQ_RID			0
128#define ATA_DEV(device)			((device == ATA_MASTER) ? 0 : 1)
129
130/* busmaster DMA related defines */
131#define ATA_DMA_ENTRIES			256
132#define ATA_DMA_EOT			0x80000000
133
134#define ATA_BMCMD_PORT			0x09
135#define		ATA_BMCMD_START_STOP	0x01
136#define		ATA_BMCMD_WRITE_READ	0x08
137
138#define ATA_BMDEVSPEC_0			0x0a
139#define ATA_BMSTAT_PORT			0x0b
140#define		ATA_BMSTAT_ACTIVE	0x01
141#define		ATA_BMSTAT_ERROR	0x02
142#define		ATA_BMSTAT_INTERRUPT	0x04
143#define		ATA_BMSTAT_MASK		0x07
144#define		ATA_BMSTAT_DMA_MASTER	0x20
145#define		ATA_BMSTAT_DMA_SLAVE	0x40
146#define		ATA_BMSTAT_DMA_SIMPLEX	0x80
147
148#define ATA_BMDEVSPEC_1			0x0c
149#define ATA_BMDTP_PORT			0x0d
150
151#define ATA_IDX_ADDR			0x0e
152#define ATA_IDX_DATA			0x0f
153#define ATA_MAX_RES			0x10
154
155#define ATA_INTR_FLAGS			(INTR_MPSAFE|INTR_TYPE_BIO|INTR_ENTROPY)
156#define ATA_OP_CONTINUES		0
157#define ATA_OP_FINISHED			1
158
159struct ata_request {
160    struct ata_device		*device;	/* ptr to device softc */
161    void			*driver;	/* driver specific */
162
163    union {
164	struct {
165	    u_int8_t		command;	/* command reg */
166	    u_int8_t		feature;	/* feature reg */
167	    u_int64_t		lba;		/* lba reg */
168	    u_int16_t		count;		/* count reg */
169	} ata;
170	struct {
171	    u_int8_t		ccb[16];	/* ATAPI command block */
172	} atapi;
173    } u;
174
175    u_int8_t			status;		/* ATA status */
176    u_int8_t			error;		/* ATA error */
177    u_int8_t			dmastat;	/* DMA status */
178
179    u_int32_t			bytecount;	/* bytes to transfer */
180    u_int32_t			transfersize;	/* bytes pr transfer */
181    u_int32_t			donecount;	/* bytes transferred */
182    caddr_t			data;		/* pointer to data buf */
183    int				flags;
184#define		ATA_R_CONTROL		0x0001
185#define		ATA_R_READ		0x0002
186#define		ATA_R_WRITE		0x0004
187#define		ATA_R_DMA		0x0008
188
189#define		ATA_R_ATAPI		0x0010
190#define		ATA_R_QUIET		0x0020
191#define		ATA_R_INTR_SEEN		0x0040
192#define		ATA_R_TIMEOUT		0x0080
193
194#define		ATA_R_ORDERED		0x0100
195#define		ATA_R_IMMEDIATE		0x0200
196#define		ATA_R_REQUEUE		0x0400
197
198#define		ATA_R_DEBUG		0x1000
199
200    void			(*callback)(struct ata_request *request);
201    struct sema			done;		/* request done sema */
202    int				retries;	/* retry count */
203    int				timeout;	/* timeout for this cmd */
204    struct callout_handle	timeout_handle; /* handle for untimeout */
205    int				result;		/* result error code */
206    struct task			task;		/* task management */
207    struct bio			*bio;		/* bio for this request */
208    TAILQ_ENTRY(ata_request)	sequence;	/* sequence management */
209    TAILQ_ENTRY(ata_request)	chain;		/* list management */
210};
211
212/* define this for debugging request processing */
213#if 0
214#define ATA_DEBUG_RQ(request, string) \
215    { \
216    if (request->flags & ATA_R_DEBUG) \
217        ata_prtdev(request->device, "req=%08x %s " string "\n", \
218                   (u_int)request, ata_cmd2str(request)); \
219    }
220#else
221#define ATA_DEBUG_RQ(request, string)
222#endif
223
224
225/* structure describing an ATA/ATAPI device */
226struct ata_device {
227    struct ata_channel		*channel;
228    int				unit;		/* unit number */
229#define		ATA_MASTER		0x00
230#define		ATA_SLAVE		0x10
231
232    char			*name;		/* device name */
233    struct ata_params		*param;		/* ata param structure */
234    void			*softc;		/* ptr to softc for device */
235    void			(*attach)(struct ata_device *atadev);
236    void			(*detach)(struct ata_device *atadev);
237    void			(*config)(struct ata_device *atadev);
238    void			(*start)(struct ata_device *atadev);
239    int				flags;
240#define		ATA_D_USE_CHS		0x0001
241#define		ATA_D_DETACHING		0x0002
242#define		ATA_D_MEDIA_CHANGED	0x0004
243#define		ATA_D_ENC_PRESENT	0x0008
244
245    int				cmd;		/* last cmd executed */
246    int				mode;		/* transfermode */
247    void			(*setmode)(struct ata_device *atadev, int mode);
248};
249
250/* structure for holding DMA address data */
251struct ata_dmaentry {
252    u_int32_t base;
253    u_int32_t count;
254};
255
256/* structure holding DMA related information */
257struct ata_dma {
258    bus_dma_tag_t		dmatag;		/* parent DMA tag */
259    bus_dma_tag_t		cdmatag;	/* control DMA tag */
260    bus_dmamap_t		cdmamap;	/* control DMA map */
261    bus_dma_tag_t		ddmatag;	/* data DMA tag */
262    bus_dmamap_t		ddmamap;	/* data DMA map */
263    struct ata_dmaentry		*dmatab;	/* DMA transfer table */
264    bus_addr_t			mdmatab;	/* bus address of dmatab */
265    u_int32_t			alignment;	/* DMA engine alignment */
266    u_int32_t			boundary;	/* DMA engine boundary */
267    u_int32_t			max_iosize;	/* DMA engine max IO size */
268    u_int32_t			cur_iosize;	/* DMA engine current IO size */
269    int				flags;
270#define ATA_DMA_ACTIVE			0x01	/* DMA transfer in progress */
271#define ATA_DMA_READ			0x02	/* transaction is a read */
272
273    void (*alloc)(struct ata_channel *ch);
274    void (*free)(struct ata_channel *ch);
275    int (*load)(struct ata_device *atadev, caddr_t data, int32_t count,int dir);
276    int (*unload)(struct ata_channel *ch);
277    int (*start)(struct ata_channel *ch);
278    int (*stop)(struct ata_channel *ch);
279};
280
281/* structure holding lowlevel functions */
282struct ata_lowlevel {
283    void (*reset)(struct ata_channel *ch);
284    int (*transaction)(struct ata_request *request);
285    void (*interrupt)(void *channel);
286};
287
288/* structure holding resources for an ATA channel */
289struct ata_resource {
290    struct resource		*res;
291    int				offset;
292};
293
294/* structure describing an ATA channel */
295struct ata_channel {
296    struct device		*dev;		/* device handle */
297    int				unit;		/* channel number */
298    struct ata_resource		r_io[ATA_MAX_RES];/* I/O resources */
299    struct resource		*r_irq;		/* interrupt of this channel */
300    void			*ih;		/* interrupt handle */
301    struct ata_lowlevel		hw;		/* lowlevel HW functions */
302    struct ata_dma		*dma;		/* DMA data / functions */
303    int				flags;		/* channel flags */
304#define		ATA_NO_SLAVE		0x01
305#define		ATA_USE_16BIT		0x02
306#define		ATA_USE_PC98GEOM	0x04
307#define		ATA_ATAPI_DMA_RO	0x08
308#define		ATA_48BIT_ACTIVE	0x10
309#define		ATA_IMMEDIATE_MODE	0x20
310
311    struct ata_device		device[2];	/* devices on this channel */
312#define		MASTER			0x00
313#define		SLAVE			0x01
314
315    int				devices;	/* what is present */
316#define		ATA_ATA_MASTER		0x01
317#define		ATA_ATA_SLAVE		0x02
318#define		ATA_ATAPI_MASTER	0x04
319#define		ATA_ATAPI_SLAVE		0x08
320
321    int				state;		/* ATA channel state control */
322#define		ATA_IDLE		0x0000
323#define		ATA_ACTIVE		0x0001
324#define		ATA_CONTROL		0x0002
325
326    void (*reset)(struct ata_channel *);
327    void (*locking)(struct ata_channel *, int);
328#define		ATA_LF_LOCK		0x0001
329#define		ATA_LF_UNLOCK		0x0002
330
331    struct mtx			queue_mtx;	/* queue lock */
332    TAILQ_HEAD(, ata_request)	ata_queue;	/* head of ATA queue */
333    void			*running;	/* currently running request */
334};
335
336/* ATAPI request sense structure */
337struct atapi_sense {
338    u_int8_t	error_code	:7;		/* current or deferred errors */
339    u_int8_t	valid		:1;		/* follows ATAPI spec */
340    u_int8_t	segment;			/* Segment number */
341    u_int8_t	sense_key	:4;		/* sense key */
342    u_int8_t	reserved2_4	:1;		/* reserved */
343    u_int8_t	ili		:1;		/* incorrect length indicator */
344    u_int8_t	eom		:1;		/* end of medium */
345    u_int8_t	filemark	:1;		/* filemark */
346    u_int32_t	cmd_info __packed;		/* cmd information */
347    u_int8_t	sense_length;			/* additional sense len (n-7) */
348    u_int32_t	cmd_specific_info __packed;	/* additional cmd spec info */
349    u_int8_t	asc;				/* additional sense code */
350    u_int8_t	ascq;				/* additional sense code qual */
351    u_int8_t	replaceable_unit_code;		/* replaceable unit code */
352    u_int8_t	sk_specific	:7;		/* sense key specific */
353    u_int8_t	sksv		:1;		/* sense key specific info OK */
354    u_int8_t	sk_specific1;			/* sense key specific */
355    u_int8_t	sk_specific2;			/* sense key specific */
356};
357
358/* disk bay/enclosure related */
359#define		ATA_LED_OFF		0x00
360#define		ATA_LED_RED		0x01
361#define		ATA_LED_GREEN		0x02
362#define		ATA_LED_ORANGE		0x03
363#define		ATA_LED_MASK		0x03
364
365/* externs */
366extern devclass_t ata_devclass;
367extern int ata_wc;
368
369/* public prototypes */
370/* ata-all.c: */
371int ata_probe(device_t dev);
372int ata_attach(device_t dev);
373int ata_detach(device_t dev);
374int ata_suspend(device_t dev);
375int ata_resume(device_t dev);
376int ata_printf(struct ata_channel *ch, int device, const char *fmt, ...) __printflike(3, 4);
377int ata_prtdev(struct ata_device *atadev, const char *fmt, ...) __printflike(2, 3);
378void ata_set_name(struct ata_device *atadev, char *name, int lun);
379void ata_free_name(struct ata_device *atadev);
380int ata_get_lun(u_int32_t *map);
381int ata_test_lun(u_int32_t *map, int lun);
382void ata_free_lun(u_int32_t *map, int lun);
383char *ata_mode2str(int mode);
384int ata_pmode(struct ata_params *ap);
385int ata_wmode(struct ata_params *ap);
386int ata_umode(struct ata_params *ap);
387int ata_limit_mode(struct ata_device *atadev, int mode, int maxmode);
388
389/* ata-queue.c: */
390int ata_reinit(struct ata_channel *ch);
391void ata_start(struct ata_channel *ch);
392int ata_controlcmd(struct ata_device *atadev, u_int8_t command, u_int16_t feature, u_int64_t lba, u_int16_t count);
393int ata_atapicmd(struct ata_device *atadev, u_int8_t *ccb, caddr_t data, int count, int flags, int timeout);
394void ata_queue_request(struct ata_request *request);
395void ata_finish(struct ata_request *request);
396char *ata_cmd2str(struct ata_request *request);
397
398/* ata-lowlevel.c: */
399void ata_generic_hw(struct ata_channel *ch);
400
401/* subdrivers */
402void ad_attach(struct ata_device *atadev);
403void acd_attach(struct ata_device *atadev);
404void afd_attach(struct ata_device *atadev);
405void ast_attach(struct ata_device *atadev);
406void atapi_cam_attach_bus(struct ata_channel *ch);
407void atapi_cam_detach_bus(struct ata_channel *ch);
408void atapi_cam_reinit_bus(struct ata_channel *ch);
409
410/* macros for alloc/free of ata_requests */
411extern uma_zone_t ata_zone;
412#define ata_alloc_request() uma_zalloc(ata_zone, M_NOWAIT | M_ZERO)
413#define ata_free_request(request) uma_zfree(ata_zone, request)
414
415/* macros for locking a channel */
416#define ATA_LOCK_CH(ch, value) \
417	atomic_cmpset_acq_int(&(ch)->state, ATA_IDLE, (value))
418
419#define ATA_SLEEPLOCK_CH(ch, value) \
420	while (!atomic_cmpset_acq_int(&(ch)->state, ATA_IDLE, (value))) \
421	    tsleep((caddr_t)&(ch), PRIBIO, "atalck", 1);
422
423#define ATA_FORCELOCK_CH(ch, value) atomic_store_rel_int(&(ch)->state, (value))
424
425#define ATA_UNLOCK_CH(ch) atomic_store_rel_int(&(ch)->state, ATA_IDLE)
426
427/* macros to hide busspace uglyness */
428#define ATA_INB(res, offset) \
429	bus_space_read_1(rman_get_bustag((res)), \
430			 rman_get_bushandle((res)), (offset))
431
432#define ATA_INW(res, offset) \
433	bus_space_read_2(rman_get_bustag((res)), \
434			 rman_get_bushandle((res)), (offset))
435#define ATA_INL(res, offset) \
436	bus_space_read_4(rman_get_bustag((res)), \
437			 rman_get_bushandle((res)), (offset))
438#define ATA_INSW(res, offset, addr, count) \
439	bus_space_read_multi_2(rman_get_bustag((res)), \
440			       rman_get_bushandle((res)), \
441			       (offset), (addr), (count))
442#define ATA_INSW_STRM(res, offset, addr, count) \
443	bus_space_read_multi_stream_2(rman_get_bustag((res)), \
444				      rman_get_bushandle((res)), \
445				      (offset), (addr), (count))
446#define ATA_INSL(res, offset, addr, count) \
447	bus_space_read_multi_4(rman_get_bustag((res)), \
448			       rman_get_bushandle((res)), \
449			       (offset), (addr), (count))
450#define ATA_INSL_STRM(res, offset, addr, count) \
451	bus_space_read_multi_stream_4(rman_get_bustag((res)), \
452				      rman_get_bushandle((res)), \
453				      (offset), (addr), (count))
454#define ATA_OUTB(res, offset, value) \
455	bus_space_write_1(rman_get_bustag((res)), \
456			  rman_get_bushandle((res)), (offset), (value))
457#define ATA_OUTW(res, offset, value) \
458	bus_space_write_2(rman_get_bustag((res)), \
459			  rman_get_bushandle((res)), (offset), (value))
460#define ATA_OUTL(res, offset, value) \
461	bus_space_write_4(rman_get_bustag((res)), \
462			  rman_get_bushandle((res)), (offset), (value))
463#define ATA_OUTSW(res, offset, addr, count) \
464	bus_space_write_multi_2(rman_get_bustag((res)), \
465				rman_get_bushandle((res)), \
466				(offset), (addr), (count))
467#define ATA_OUTSW_STRM(res, offset, addr, count) \
468	bus_space_write_multi_stream_2(rman_get_bustag((res)), \
469				       rman_get_bushandle((res)), \
470				       (offset), (addr), (count))
471#define ATA_OUTSL(res, offset, addr, count) \
472	bus_space_write_multi_4(rman_get_bustag((res)), \
473				rman_get_bushandle((res)), \
474				(offset), (addr), (count))
475#define ATA_OUTSL_STRM(res, offset, addr, count) \
476	bus_space_write_multi_stream_4(rman_get_bustag((res)), \
477				       rman_get_bushandle((res)), \
478				       (offset), (addr), (count))
479
480#define ATA_IDX_SET(ch, idx) \
481	ATA_OUTB(ch->r_io[ATA_IDX_ADDR].res, ch->r_io[ATA_IDX_ADDR].offset, \
482		 ch->r_io[idx].offset)
483
484#define ATA_IDX_INB(ch, idx) \
485	((ch->r_io[idx].res) \
486	? ATA_INB(ch->r_io[idx].res, ch->r_io[idx].offset) \
487	: (ATA_IDX_SET(ch, idx), \
488	   ATA_INB(ch->r_io[ATA_IDX_DATA].res, ch->r_io[ATA_IDX_DATA].offset)))
489
490#define ATA_IDX_INW(ch, idx) \
491	((ch->r_io[idx].res) \
492	? ATA_INW(ch->r_io[idx].res, ch->r_io[idx].offset) \
493	: (ATA_IDX_SET(ch, idx), \
494	   ATA_INW(ch->r_io[ATA_IDX_DATA].res, ch->r_io[ATA_IDX_DATA].offset)))
495
496#define ATA_IDX_INL(ch, idx) \
497	((ch->r_io[idx].res) \
498	? ATA_INL(ch->r_io[idx].res, ch->r_io[idx].offset) \
499	: (ATA_IDX_SET(ch, idx), \
500	   ATA_INL(ch->r_io[ATA_IDX_DATA].res, ch->r_io[ATA_IDX_DATA].offset)))
501
502#define ATA_IDX_INSW(ch, idx, addr, count) \
503	((ch->r_io[idx].res) \
504	? ATA_INSW(ch->r_io[idx].res, ch->r_io[idx].offset, addr, count) \
505	: (ATA_IDX_SET(ch, idx), \
506	   ATA_INSW(ch->r_io[ATA_IDX_DATA].res, \
507		    ch->r_io[ATA_IDX_DATA].offset, addr, count)))
508
509#define ATA_IDX_INSW_STRM(ch, idx, addr, count) \
510	((ch->r_io[idx].res) \
511	? ATA_INSW_STRM(ch->r_io[idx].res, ch->r_io[idx].offset, addr, count) \
512	: (ATA_IDX_SET(ch, idx), \
513	   ATA_INSW_STRM(ch->r_io[ATA_IDX_DATA].res, \
514			 ch->r_io[ATA_IDX_DATA].offset, addr, count)))
515
516#define ATA_IDX_INSL(ch, idx, addr, count) \
517	((ch->r_io[idx].res) \
518	? ATA_INSL(ch->r_io[idx].res, ch->r_io[idx].offset, addr, count) \
519	: (ATA_IDX_SET(ch, idx), \
520	   ATA_INSL(ch->r_io[ATA_IDX_DATA].res, \
521		    ch->r_io[ATA_IDX_DATA].offset, addr, count)))
522
523#define ATA_IDX_INSL_STRM(ch, idx, addr, count) \
524	((ch->r_io[idx].res) \
525	? ATA_INSL_STRM(ch->r_io[idx].res, ch->r_io[idx].offset, addr, count) \
526	: (ATA_IDX_SET(ch, idx), \
527	   ATA_INSL_STRM(ch->r_io[ATA_IDX_DATA].res, \
528			 ch->r_io[ATA_IDX_DATA].offset, addr, count)))
529
530#define ATA_IDX_OUTB(ch, idx, value) \
531	((ch->r_io[idx].res) \
532	? ATA_OUTB(ch->r_io[idx].res, ch->r_io[idx].offset, value) \
533	: (ATA_IDX_SET(ch, idx), \
534	   ATA_OUTB(ch->r_io[ATA_IDX_DATA].res, \
535		    ch->r_io[ATA_IDX_DATA].offset, value)))
536
537#define ATA_IDX_OUTW(ch, idx, value) \
538	((ch->r_io[idx].res) \
539	? ATA_OUTW(ch->r_io[idx].res, ch->r_io[idx].offset, value) \
540	: (ATA_IDX_SET(ch, idx), \
541	   ATA_OUTW(ch->r_io[ATA_IDX_DATA].res, \
542		    ch->r_io[ATA_IDX_DATA].offset, value)))
543
544#define ATA_IDX_OUTL(ch, idx, value) \
545	((ch->r_io[idx].res) \
546	? ATA_OUTL(ch->r_io[idx].res, ch->r_io[idx].offset, value) \
547	: (ATA_IDX_SET(ch, idx), \
548	   ATA_OUTL(ch->r_io[ATA_IDX_DATA].res, \
549		    ch->r_io[ATA_IDX_DATA].offset, value)))
550
551#define ATA_IDX_OUTSW(ch, idx, addr, count) \
552	((ch->r_io[idx].res) \
553	? ATA_OUTSW(ch->r_io[idx].res, ch->r_io[idx].offset, addr, count) \
554	: (ATA_IDX_SET(ch, idx), \
555	   ATA_OUTSW(ch->r_io[ATA_IDX_DATA].res, \
556		     ch->r_io[ATA_IDX_DATA].offset, addr, count)))
557
558#define ATA_IDX_OUTSW_STRM(ch, idx, addr, count) \
559	((ch->r_io[idx].res) \
560	? ATA_OUTSW_STRM(ch->r_io[idx].res, ch->r_io[idx].offset, addr, count) \
561	: (ATA_IDX_SET(ch, idx), \
562	   ATA_OUTSW_STRM(ch->r_io[ATA_IDX_DATA].res, \
563			  ch->r_io[ATA_IDX_DATA].offset, addr, count)))
564
565#define ATA_IDX_OUTSL(ch, idx, addr, count) \
566	((ch->r_io[idx].res) \
567	? ATA_OUTSL(ch->r_io[idx].res, ch->r_io[idx].offset, addr, count) \
568	: (ATA_IDX_SET(ch, idx), \
569	   ATA_OUTSL(ch->r_io[ATA_IDX_DATA].res, \
570		     ch->r_io[ATA_IDX_DATA].offset, addr, count)))
571
572#define ATA_IDX_OUTSL_STRM(ch, idx, addr, count) \
573	((ch->r_io[idx].res) \
574	? ATA_OUTSL_STRM(ch->r_io[idx].res, ch->r_io[idx].offset, addr, count) \
575	: (ATA_IDX_SET(ch, idx), \
576	   ATA_OUTSL_STRM(ch->r_io[ATA_IDX_DATA].res, \
577			  ch->r_io[ATA_IDX_DATA].offset, addr, count)))
578