summaryrefslogtreecommitdiff
path: root/usr/src/uts/intel/io/dktp/controller/ata/ata_common.h
blob: 001c1248487aa481a7f8f636b18927093966a2ac (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
/*
 * CDDL HEADER START
 *
 * The contents of this file are subject to the terms of the
 * Common Development and Distribution License (the "License").
 * You may not use this file except in compliance with the License.
 *
 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
 * or http://www.opensolaris.org/os/licensing.
 * See the License for the specific language governing permissions
 * and limitations under the License.
 *
 * When distributing Covered Code, include this CDDL HEADER in each
 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
 * If applicable, add the following below this CDDL HEADER, with the
 * fields enclosed by brackets "[]" replaced with your own identifying
 * information: Portions Copyright [yyyy] [name of copyright owner]
 *
 * CDDL HEADER END
 */

/*
 * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
 * Use is subject to license terms.
 */

#ifndef _ATA_COMMON_H
#define	_ATA_COMMON_H

#ifdef	__cplusplus
extern "C" {
#endif

#include <sys/varargs.h>

#include <sys/scsi/scsi.h>
#include <sys/dktp/dadkio.h>
#include <sys/dktp/dadev.h>
#include <sys/dkio.h>
#include <sys/dktp/tgdk.h>

#include <sys/ddi.h>
#include <sys/sunddi.h>

#include "ghd.h"

#include "pciide.h"
#include "ata_cmd.h"
#include "ata_fsm.h"
#include "ata_debug.h"


/*
 * device types
 */
#define	ATA_DEV_NONE	0
#define	ATA_DEV_DISK	1
#define	ATA_DEV_ATAPI	2

/*
 * Largest sector allowed in 28 bit mode
 */
#define	MAX_28BIT_CAPACITY	0xfffffff

/*
 * Largest sector count allowed for device firmware file in one command.
 */
#define	MAX_FWFILE_SIZE_ONECMD	0xffff

/*
 * ata-options property configuration bits
 */

#define	ATA_OPTIONS_DMA		0x01

#define	ATAPRT(fmt)	ghd_err fmt

/* ad_flags (per-drive) */

#define	AD_ATAPI		0x01	/* is an ATAPI drive */
#define	AD_DISK			0x02
#define	AD_MUTEX_INIT		0x04
#define	AD_NO_CDB_INTR		0x20
#define	AD_1SECTOR		0x40
#define	AD_INT13LBA		0x80	/* supports LBA at Int13 interface */
#define	AD_NORVRT		0x100	/* block revert-to-defaults */
#define	AD_EXT48		0x200	/* 48 bit (extended) LBA */
#define	AD_BLLBA48		0x400
#define	ATAPIDRV(X)  ((X)->ad_flags & AD_ATAPI)


/* max targets and luns */

#define	ATA_MAXTARG	2
#define	ATA_MAXLUN	16

/*
 * PCI-IDE Bus Mastering Scatter/Gather list size
 */
#define	ATA_DMA_NSEGS	17	/* enough for at least 64K */

/*
 * Controller port address defaults
 */
#define	ATA_BASE0	0x1f0
#define	ATA_BASE1	0x170

/*
 * port offsets from base address ioaddr1
 */
#define	AT_DATA		0x00	/* data register 			*/
#define	AT_ERROR	0x01	/* error register (read)		*/
#define	AT_FEATURE	0x01	/* features (write)			*/
#define	AT_COUNT	0x02    /* sector count 			*/
#define	AT_SECT		0x03	/* sector number 			*/
#define	AT_LCYL		0x04	/* cylinder low byte 			*/
#define	AT_HCYL		0x05	/* cylinder high byte 			*/
#define	AT_DRVHD	0x06    /* drive/head register 			*/
#define	AT_STATUS	0x07	/* status/command register 		*/
#define	AT_CMD		0x07	/* status/command register 		*/

/*
 * port offsets from base address ioaddr2
 */
#define	AT_ALTSTATUS	0x00	/* alternate status (read)		*/
#define	AT_DEVCTL	0x00	/* device control (write)		*/

/*	Device control register						*/
#define	ATDC_NIEN    	0x02    /* disable interrupts 			*/
#define	ATDC_SRST	0x04	/* controller reset			*/
#define	ATDC_D3		0x08	/* Mysterious bit, must be set  	*/
/*
 * ATA-6 spec
 * In 48-bit addressing, reading the LBA location and count
 * registers when the high-order bit is set reads the "previous
 * content" (LBA bits 47:24, count bits 15:8) instead of the
 * "most recent" values (LBA bits 23:0, count bits 7:0).
 */
#define	ATDC_HOB	0x80	/* High order bit			*/

/*
 * Status bits from AT_STATUS register
 */
#define	ATS_BSY		0x80    /* controller busy 			*/
#define	ATS_DRDY	0x40    /* drive ready 				*/
#define	ATS_DF		0x20    /* device fault				*/
#define	ATS_DSC    	0x10    /* seek operation complete 		*/
#define	ATS_DRQ		0x08	/* data request 			*/
#define	ATS_CORR	0x04    /* ECC correction applied 		*/
#define	ATS_IDX		0x02    /* disk revolution index 		*/
#define	ATS_ERR		0x01    /* error flag 				*/

/*
 * Status bits from AT_ERROR register
 */
#define	ATE_BBK_ICRC	0x80	/* bad block detected in ATA-1		*/
				/* ICRC error in ATA-4 and newer	*/
#define	ATE_UNC		0x40	/* uncorrectable data error		*/
#define	ATE_MC		0x20    /* Media change				*/
#define	ATE_IDNF	0x10    /* ID not found				*/
#define	ATE_MCR		0x08	/* media change request			*/
#define	ATE_ABORT	0x04    /* aborted command			*/
#define	ATE_TKONF	0x02    /* track 0 not found			*/
#define	ATE_AMNF	0x01    /* address mark not found		*/

#define	ATE_NM		0x02	/* no media				*/

/*
 * Drive selectors for AT_DRVHD register
 */
#define	ATDH_LBA	0x40	/* addressing in LBA mode not chs 	*/
#define	ATDH_DRIVE0	0xa0    /* or into AT_DRVHD to select drive 0 	*/
#define	ATDH_DRIVE1	0xb0    /* or into AT_DRVHD to select drive 1 	*/

/*
 * Feature register bits
 */
#define	ATF_ATAPI_DMA	0x01	/* ATAPI DMA enable bit */
#define	ATF_XFRMOD_MDMA	0x20	/* Multi-Word DMA mode */
#define	ATF_XFRMOD_UDMA	0x40	/* Ultra DMA mode	*/
#define	ATACM_UDMA_SEL(id)	(((id)->ai_ultradma >> 8) & 0x7f)

/*
 * Set feature register definitions.
 */
#define	ATSF_SET_XFRMOD	0X03	/* Set transfer mode			  */
#define	ATSF_DIS_REVPOD	0x66	/* Disable reverting to power on defaults */
#define	ATSF_ENA_REVPOD	0xcc	/* Enable reverting to power on defaults  */

/*
 * common bits and options for set features (ATC_SET_FEAT)
 */
#define	FC_WRITE_CACHE_ON	0x02
#define	FC_WRITE_CACHE_OFF	0x82

/* Test which version of ATA is supported */
#define	IS_ATA_VERSION_SUPPORTED(idp, n) \
	((idp->ai_majorversion != 0xffff) && \
	(idp->ai_majorversion & (1<<n)))

/* Test if supported version >= ATA-n */
#define	IS_ATA_VERSION_GE(idp, n) \
	((idp->ai_majorversion != 0xffff) && \
	(idp->ai_majorversion != 0) && \
	(idp->ai_majorversion >= (1<<n)))

/* Test whether a device is a CD drive */
#define	IS_CDROM(dp) \
		((dp->ad_flags & AD_ATAPI) && \
		    ((dp->ad_id.ai_config >> 8) & DTYPE_MASK) == \
		    DTYPE_RODIRECT)

/* Test whether the device support write cache */
#define	IS_WRITE_CACHE_SUPPORTED(x) \
	((((x).ai_cmdset82) & 0x20) >> 5)

/*  macros from old common hba code */

#define	ATA_INTPROP(devi, pname, pval, plen) \
	(ddi_prop_op(DDI_DEV_T_ANY, (devi), PROP_LEN_AND_VAL_BUF, \
		DDI_PROP_DONTPASS, (pname), (caddr_t)(pval), (plen)))

#define	ATA_LONGPROP(devi, pname, pval, plen) \
	(ddi_getlongprop(DDI_DEV_T_ANY, (devi), DDI_PROP_DONTPASS, \
		(pname), (caddr_t)(pval), (plen)))

/*
 *
 * per-controller soft-state data structure
 *
 */

#define	CTL2DRV(cp, t, l)	(cp->ac_drvp[t][l])

typedef struct ata_ctl {

	dev_info_t	*ac_dip;
	uint_t		 ac_flags;
	uint_t		 ac_timing_flags;
	struct ata_drv	*ac_drvp[ATA_MAXTARG][ATA_MAXLUN];
	int		 ac_max_transfer; /* max transfer in sectors */
	uint_t		 ac_standby_time; /* timer value seconds */

	ccc_t		 ac_ccc;	  /* for GHD module */
	struct ata_drv	*ac_active_drvp;  /* active drive, if any */
	struct ata_pkt	*ac_active_pktp;  /* active packet, if any */
	uchar_t		 ac_state;

	scsi_hba_tran_t *ac_atapi_tran;	  /* for atapi module */

	/*
	 * port addresses associated with ioaddr1
	 */
	ddi_acc_handle_t ac_iohandle1;	  /* DDI I/O handle */
	caddr_t		 ac_ioaddr1;
	ushort_t	*ac_data;	  /* data register 		*/
	uchar_t		*ac_error;	  /* error register (read)	*/
	uchar_t		*ac_feature;	  /* features (write)		*/
	uchar_t		*ac_count;	  /* sector count 		*/
	uchar_t		*ac_sect;	  /* sector number 		*/
	uchar_t		*ac_lcyl;	  /* cylinder low byte 		*/
	uchar_t		*ac_hcyl;	  /* cylinder high byte 	*/
	uchar_t		*ac_drvhd;	  /* drive/head register 	*/
	uchar_t		*ac_status;	  /* status/command register 	*/
	uchar_t		*ac_cmd;	  /* status/command register 	*/

	/*
	 * port addresses associated with ioaddr2
	 */
	ddi_acc_handle_t ac_iohandle2;	  /* DDI I/O handle		*/
	caddr_t		 ac_ioaddr2;
	uchar_t		*ac_altstatus;	  /* alternate status (read)	*/
	uchar_t		*ac_devctl;	  /* device control (write)	*/

	/*
	 * handle and port addresss for PCI-IDE Bus Master controller
	 */
	ddi_acc_handle_t ac_bmhandle;	  /* DDI I/O handle		*/
	caddr_t		 ac_bmaddr;	  /* base addr of Bus Master Regs */
	uchar_t		 ac_pciide;	  /* PCI-IDE device */
	uchar_t		 ac_pciide_bm;	  /* Bus Mastering PCI-IDE device */

	/*
	 * Scatter/Gather list for PCI-IDE Bus Mastering controllers
	 */
	caddr_t		 ac_sg_list;	  /* virtual addr of S/G list */
	paddr_t		 ac_sg_paddr;	  /* phys addr of S/G list */
	ddi_acc_handle_t ac_sg_acc_handle;
	ddi_dma_handle_t ac_sg_handle;

	/*
	 * data for managing ARQ on ATAPI devices
	 */
	struct ata_pkt	*ac_arq_pktp;	  /* pkt for performing ATAPI ARQ */
	struct ata_pkt	*ac_fault_pktp;	  /* pkt that caused ARQ */
	uchar_t		 ac_arq_cdb[6];

	/*
	 * Power Management
	 */
	int		ac_pm_support;
	int		ac_pm_level;
} ata_ctl_t;

/* ac_flags (per-controller) */

#define	AC_GHD_INIT			0x02
#define	AC_ATAPI_INIT			0x04
#define	AC_DISK_INIT			0x08
#define	AC_ATTACHED			0x10
#define	AC_SCSI_HBA_TRAN_ALLOC		0x1000
#define	AC_SCSI_HBA_ATTACH		0x2000

#define	AC_BMSTATREG_PIO_BROKEN		0x80000000

/*
 * Bug 1256489:
 *
 * If AC_BSY_WAIT needs to be set  for laptops that do
 * suspend/resume but do not correctly wait for the busy bit to
 * drop after a resume.
 */

/* ac_timing_flags (per-controller) */
#define	AC_BSY_WAIT	0x1	/* tweak timing in ata_start & atapi_start */



/* Identify drive data */
struct ata_id {
/*  					WORD				*/
/* 					OFFSET COMMENT			*/
	ushort_t  ai_config;	  /*   0  general configuration bits 	*/
	ushort_t  ai_fixcyls;	  /*   1  # of fixed cylinders		*/
	ushort_t  ai_resv0;	  /*   2  # reserved			*/
	ushort_t  ai_heads;	  /*   3  # of heads			*/
	ushort_t  ai_trksiz;	  /*   4  # of unformatted bytes/track 	*/
	ushort_t  ai_secsiz;	  /*   5  # of unformatted bytes/sector	*/
	ushort_t  ai_sectors;	  /*   6  # of sectors/track		*/
	ushort_t  ai_resv1[3];	  /*   7  "Vendor Unique"		*/
	char	ai_drvser[20];	  /*  10  Serial number			*/
	ushort_t ai_buftype;	  /*  20  Buffer type			*/
	ushort_t ai_bufsz;	  /*  21  Buffer size in 512 byte incr  */
	ushort_t ai_ecc;	  /*  22  # of ecc bytes avail on rd/wr */
	char	ai_fw[8];	  /*  23  Firmware revision		*/
	char	ai_model[40];	  /*  27  Model #			*/
	ushort_t ai_mult1;	  /*  47  Multiple command flags	*/
	ushort_t ai_dwcap;	  /*  48  Doubleword capabilities	*/
	ushort_t ai_cap;	  /*  49  Capabilities			*/
	ushort_t ai_resv2;	  /*  50  Reserved			*/
	ushort_t ai_piomode;	  /*  51  PIO timing mode		*/
	ushort_t ai_dmamode;	  /*  52  DMA timing mode		*/
	ushort_t ai_validinfo;	  /*  53  bit0: wds 54-58, bit1: 64-70	*/
	ushort_t ai_curcyls;	  /*  54  # of current cylinders	*/
	ushort_t ai_curheads;	  /*  55  # of current heads		*/
	ushort_t ai_cursectrk;	  /*  56  # of current sectors/track	*/
	ushort_t ai_cursccp[2];	  /*  57  current sectors capacity	*/
	ushort_t ai_mult2;	  /*  59  multiple sectors info		*/
	ushort_t ai_addrsec[2];	  /*  60  LBA only: no of addr secs	*/
	ushort_t ai_sworddma;	  /*  62  single word dma modes		*/
	ushort_t ai_dworddma;	  /*  63  double word dma modes		*/
	ushort_t ai_advpiomode;	  /*  64  advanced PIO modes supported	*/
	ushort_t ai_minmwdma;	  /*  65  min multi-word dma cycle info	*/
	ushort_t ai_recmwdma;	  /*  66  rec multi-word dma cycle info	*/
	ushort_t ai_minpio;	  /*  67  min PIO cycle info		*/
	ushort_t ai_minpioflow;	  /*  68  min PIO cycle info w/flow ctl */
	ushort_t ai_resv3[2];	  /* 69,70 reserved			*/
	ushort_t ai_resv4[4];	  /* 71-74 reserved			*/
	ushort_t ai_qdepth;	  /*  75  queue depth			*/
	ushort_t ai_resv5[4];	  /* 76-79 reserved			*/
	ushort_t ai_majorversion; /*  80  major versions supported	*/
	ushort_t ai_minorversion; /*  81  minor version number supported */
	ushort_t ai_cmdset82;	  /*  82  command set supported		*/
	ushort_t ai_cmdset83;	  /*  83  more command sets supported	*/
	ushort_t ai_cmdset84;	  /*  84  more command sets supported	*/
	ushort_t ai_features85;	  /*  85 enabled features		*/
	ushort_t ai_features86;	  /*  86 enabled features		*/
	ushort_t ai_features87;	  /*  87 enabled features		*/
	ushort_t ai_ultradma;	  /*  88 Ultra DMA mode			*/
	ushort_t ai_erasetime;	  /*  89 security erase time		*/
	ushort_t ai_erasetimex;	  /*  90 enhanced security erase time	*/
	ushort_t ai_padding1[9];  /* pad through 99			*/
	ushort_t ai_addrsecxt[4]; /* 100 extended max LBA sector	*/
	ushort_t ai_padding2[22]; /* pad to 126				*/
	ushort_t ai_lastlun;	  /* 126 last LUN, as per SFF-8070i	*/
	ushort_t ai_resv6;	  /* 127 reserved			*/
	ushort_t ai_securestatus; /* 128 security status		*/
	ushort_t ai_vendor[31];	  /* 129-159 vendor specific		*/
	ushort_t ai_padding3[16]; /* 160 pad to 176			*/
	ushort_t ai_curmedser[30]; /* 176-205 current media serial number */
	ushort_t ai_padding4[49]; /* 206 pad to 255			*/
	ushort_t ai_integrity;	  /* 255 integrity word			*/
};

/* Identify Drive: general config bits  - word 0 */

#define	ATA_ID_REM_DRV  	0x80
#define	ATA_ID_COMPACT_FLASH 	0x848a
#define	ATA_ID_CF_TO_ATA 	0x040a
#define	ATA_ID_INCMPT		0x0004

/* Identify Drive: common capability bits - word 49 */

#define	ATAC_DMA_SUPPORT	0x0100
#define	ATAC_LBA_SUPPORT	0x0200
#define	ATAC_IORDY_DISABLE	0x0400
#define	ATAC_IORDY_SUPPORT	0x0800
#define	ATAC_RESERVED_IDPKT	0x1000	/* rsrvd for identify pkt dev */
#define	ATAC_STANDBYTIMER	0x2000
#define	ATAC_ATA_TYPE_MASK	0x8001
#define	ATAC_ATA_TYPE		0x0000
#define	ATAC_ATAPI_TYPE_MASK	0xc000
#define	ATAC_ATAPI_TYPE		0x8000

/* Identify Driver ai_validinfo (word 53) */

#define	ATAC_VALIDINFO_83	0x0004	/* word 83 supported fields valid */
#define	ATAC_VALIDINFO_70_64	0x0002	/* word 70:64 sup. fields valid */

/* Identify Drive: ai_dworddma (word 63) */

#define	ATAC_MDMA_SUP_MASK	0x0007	/* Multiword DMA supported */
#define	ATAC_MDMA_SEL_MASK	0x0700	/* Multiword DMA selected */
#define	ATAC_MDMA_2_SEL		0x0400	/* Multiword DMA mode 2 selected */
#define	ATAC_MDMA_1_SEL		0x0200	/* Multiword DMA mode 1 selected */
#define	ATAC_MDMA_0_SEL		0x0100	/* Multiword DMA mode 0 selected */
#define	ATAC_MDMA_2_SUP		0x0004	/* Multiword DMA mode 2 supported */
#define	ATAC_MDMA_1_SUP		0x0002	/* Multiword DMA mode 1 supported */
#define	ATAC_MDMA_0_SUP		0x0001	/* Multiword DMA mode 0 supported */

/* Identify Drive: ai_advpiomode (word 64) */

#define	ATAC_ADVPIO_4_SUP	0x0002	/* PIO mode 4 supported */
#define	ATAC_ADVPIO_3_SUP	0x0001	/* PIO mode 3 supported */
#define	ATAC_ADVPIO_SERIAL	0x0003	/* Serial interface */

/* Identify Drive: ai_majorversion (word 80) */

#define	ATAC_MAJVER_8		0x0100	/* ATA/ATAPI-8 version supported */
#define	ATAC_MAJVER_6		0x0040	/* ATA/ATAPI-6 version supported */
#define	ATAC_MAJVER_4		0x0010	/* ATA/ATAPI-4 version supported */

/* Identify Drive: command set supported/enabled bits - words 83 and 86 */

#define	ATACS_EXT48		0x0400	/* 48 bit address feature */

/* Identify Drive: ai_features85 (word 85) */
#define	ATAC_FEATURES85_WCE	0x0020	/* write cache enabled */

/* Identify Drive: ai_ultradma (word 88) */
#define	ATAC_UDMA_SUP_MASK	0x007f	/* UDMA modes supported */
#define	ATAC_UDMA_SEL_MASK	0x7f00	/* UDMA modes selected */


/* per-drive data struct */

typedef struct ata_drv {
	ata_ctl_t		*ad_ctlp; 	/* pointer back to ctlr */
	struct ata_id		ad_id;  	/* IDENTIFY DRIVE data */

	uint_t			ad_flags;
	uchar_t			ad_pciide_dma;	/* PCIIDE DMA supported */
	uchar_t			ad_targ;	/* target */
	uchar_t			ad_lun;		/* lun */
	uchar_t			ad_drive_bits;

	/* Used by atapi side only */

	uchar_t			ad_state;	/* state of ATAPI FSM */
	uchar_t			ad_cdb_len;	/* Size of ATAPI CDBs */

	uchar_t			ad_bogus_drq;
	uchar_t			ad_nec_bad_status;

	/* Used by disk side only */

	struct scsi_device	*ad_device;
	struct scsi_inquiry	ad_inquiry;
	struct ctl_obj		ad_ctl_obj;
	uchar_t			ad_rd_cmd;
	uchar_t			ad_wr_cmd;
	ushort_t		ad_acyl;

	/*
	 * Geometry note: The following three values are the geometry
	 * that the driver will use.  They may differ from the
	 * geometry reported by the controller and/or BIOS.  See note
	 * on ata_fix_large_disk_geometry in ata_disk.c for more
	 * details.
	 */
	uint32_t		ad_drvrcyl;	/* number of cyls */
	uint32_t		ad_drvrhd;	/* number of heads */
	uint32_t		ad_drvrsec;	/* number of sectors */
	ushort_t		ad_phhd;	/* number of phys heads */
	ushort_t		ad_phsec;	/* number of phys sectors */
	short			ad_block_factor;
	short			ad_bytes_per_block;

	/*
	 * Support for 48-bit LBA (ATA-6)
	 */
	uint64_t		ad_capacity;	/* Total sectors on disk */

	/*
	 * save/restore the DMA mode for suspend/resume
	 */
	ushort_t		ad_dma_cap;
	ushort_t		ad_dma_mode;
} ata_drv_t;

/* values for ad_dma_cap */
#define	ATA_DMA_ULTRAMODE	0x1
#define	ATA_DMA_MWORDMODE	0x2

typedef	struct	ata_tgt {
	ata_drv_t	*at_drvp;
	int		 at_arq;
	ulong_t		 at_total_sectors;
	ddi_dma_attr_t	 at_dma_attr;
} ata_tgt_t;

/* values for ad_pciide_dma */
#define	ATA_DMA_OFF		0x0
#define	ATA_DMA_ON		0x1
#define	ATA_DMA_UNINITIALIZED	0x2

/*
 * (ata_pkt_t *) to (gcmd_t *)
 */
#define	APKT2GCMD(apktp)	(apktp->ap_gcmdp)

/*
 * (gcmd_t *) to (ata_pkt_t *)
 */
#define	GCMD2APKT(gcmdp)	((ata_pkt_t *)gcmdp->cmd_private)

/*
 * (gtgt_t *) to (ata_ctl_t *)
 */
#define	GTGTP2ATAP(gtgtp)	((ata_ctl_t *)GTGTP2HBA(gtgtp))

/*
 * (gtgt_t *) to (ata_tgt_t *)
 */
#define	GTGTP2ATATGTP(gtgtp)	((ata_tgt_t *)GTGTP2TARGET(gtgtp))

/*
 * (gtgt_t *) to (ata_drv_t *)
 */
#define	GTGTP2ATADRVP(gtgtp)	(GTGTP2ATATGTP(gtgtp)->at_drvp)

/*
 * (gcmd_t *) to (ata_tgt_t *)
 */
#define	GCMD2TGT(gcmdp)		GTGTP2ATATGTP(GCMDP2GTGTP(gcmdp))

/*
 * (gcmd_t *) to (ata_drv_t *)
 */
#define	GCMD2DRV(gcmdp)		GTGTP2ATADRVP(GCMDP2GTGTP(gcmdp))

/*
 * (ata_pkt_t *) to (ata_drv_t *)
 */
#define	APKT2DRV(apktp)		GCMD2DRV(APKT2GCMD(apktp))


/*
 * (struct hba_tran *) to (ata_ctl_t *)
 */
#define	TRAN2ATAP(tranp) 	((ata_ctl_t *)TRAN2HBA(tranp))


/*
 * ata common packet structure
 */
typedef struct ata_pkt {

	gcmd_t		*ap_gcmdp;	/* GHD command struct */

	uint_t		ap_flags;	/* packet flags */

	caddr_t		ap_baddr;	/* I/O buffer base address */
	size_t		ap_boffset;	/* current offset into I/O buffer */
	size_t		ap_bcount;	/* # bytes in this request */

	caddr_t		ap_v_addr;	/* I/O buffer address */
	size_t		ap_resid;	/* # bytes left to read/write */

	uchar_t		ap_pciide_dma;	/* This pkt uses DMA transfer mode */
	prde_t		ap_sg_list[ATA_DMA_NSEGS]; /* Scatter/Gather list */
	int		ap_sg_cnt;	/* number of entries in S/G list */

	/* command, starting sector number, sector count */

	daddr_t		ap_startsec;	/* starting sector number */
	ushort_t	ap_count;	/* sector count */
	uchar_t		ap_sec;
	uchar_t		ap_lwcyl;
	uchar_t		ap_hicyl;
	uchar_t		ap_hd;
	uchar_t		ap_cmd;

	/* saved status and error registers for error case */

	uchar_t		ap_status;
	uchar_t		ap_error;

	/* disk/atapi callback routines */

	int		(*ap_start)(ata_ctl_t *ata_ctlp, ata_drv_t *ata_drvp,
				struct ata_pkt *ata_pktp);
	int		(*ap_intr)(ata_ctl_t *ata_ctlp, ata_drv_t *ata_drvp,
				struct ata_pkt *ata_pktp);
	void		(*ap_complete)(ata_drv_t *ata_drvp,
				struct ata_pkt *ata_pktp, int do_callback);

	/* Used by disk side */

	char		ap_cdb;		/* disk command */
	char		ap_scb;		/* status after disk cmd */
	uint_t		ap_bytes_per_block; /* blk mode factor */
	uint_t		ap_wrt_count;	/* size of last write */
	caddr_t		ap_v_addr_sav;	/* Original I/O buffer address. */
	size_t		ap_resid_sav;	/* Original # of bytes */
					/* left to read/write. */

	/* Used by atapi side */

	uchar_t		*ap_cdbp;	/* ptr to SCSI CDB */
	uchar_t		ap_cdb_len;	/* length of SCSI CDB (in bytes) */
	uchar_t		ap_cdb_pad;	/* padding after SCSI CDB (in shorts) */

	struct scsi_arq_status *ap_scbp; /* ptr to SCSI status block */
	uchar_t		ap_statuslen;	/* length of SCSI status block */
} ata_pkt_t;


/*
 * defines for ap_flags
 */
#define	AP_ATAPI		0x0001	/* device is atapi */
#define	AP_ERROR		0x0002	/* normal error */
#define	AP_TRAN_ERROR		0x0004	/* transport error */
#define	AP_READ			0x0008	/* read data */
#define	AP_WRITE		0x0010	/* write data */
#define	AP_ABORT		0x0020	/* packet aborted */
#define	AP_TIMEOUT		0x0040	/* packet timed out */
#define	AP_BUS_RESET		0x0080	/* bus reset */
#define	AP_DEV_RESET		0x0100	/* device reset */

#define	AP_SENT_CMD		0x0200	/* atapi: cdb sent */
#define	AP_XFERRED_DATA		0x0400	/* atapi: data transferred */
#define	AP_GOT_STATUS		0x0800	/* atapi: status received */
#define	AP_ARQ_ON_ERROR		0x1000	/* atapi: do ARQ on error */
#define	AP_ARQ_OKAY		0x2000
#define	AP_ARQ_ERROR		0x4000

#define	AP_FREE		   0x80000000u	/* packet is free! */


/*
 * public function prototypes
 */

int	ata_check_drive_blacklist(struct ata_id *aidp, uint_t flags);
int	ata_command(ata_ctl_t *ata_ctlp, ata_drv_t *ata_drvp, int expect_drdy,
		int silent, uint_t busy_wait, uchar_t cmd, uchar_t feature,
		uchar_t count, uchar_t sector, uchar_t head, uchar_t cyl_low,
		uchar_t cyl_hi);
int	ata_get_status_clear_intr(ata_ctl_t *ata_ctlp, ata_pkt_t *ata_pktp);
int	ata_id_common(uchar_t id_cmd, int drdy_expected,
		ddi_acc_handle_t io_hdl1, caddr_t ioaddr1,
		ddi_acc_handle_t io_hdl2, caddr_t ioaddr2,
		struct ata_id *ata_idp);
int	ata_prop_create(dev_info_t *tgt_dip, ata_drv_t *ata_drvp, char *name);
int	ata_queue_cmd(int (*func)(ata_ctl_t *, ata_drv_t *, ata_pkt_t *),
		void *arg, ata_ctl_t *ata_ctlp, ata_drv_t *ata_drvp,
		gtgt_t *gtgtp);
int	ata_set_feature(ata_ctl_t *ata_ctlp, ata_drv_t *ata_drvp,
		uchar_t feature, uchar_t value);
int	ata_wait(ddi_acc_handle_t io_hdl, caddr_t ioaddr, uchar_t onbits,
		uchar_t offbits, uint_t timeout_usec);
int	ata_wait3(ddi_acc_handle_t io_hdl, caddr_t ioaddr, uchar_t onbits1,
		uchar_t offbits1, uchar_t failure_onbits2,
		uchar_t failure_offbits2, uchar_t failure_onbits3,
		uchar_t failure_offbits3, uint_t timeout_usec);
int	ata_test_lba_support(struct ata_id *aidp);
void	ata_nsecwait(clock_t count);
int	ata_set_dma_mode(ata_ctl_t *ata_ctlp, ata_drv_t *ata_drvp);
void	ata_reset_dma_mode(ata_drv_t *ata_drvp);
void	atapi_reset_dma_mode(ata_drv_t *ata_drvp, int need_wait);


/*
 * PCIIDE DMA (Bus Mastering) functions and data in ata_dma.c
 */
extern	ddi_dma_attr_t ata_pciide_dma_attr;
extern	int	ata_dma_disabled;

int	ata_pciide_alloc(dev_info_t *dip, ata_ctl_t *ata_ctlp);
void	ata_pciide_free(ata_ctl_t *ata_ctlp);

void	ata_pciide_dma_sg_func(gcmd_t *gcmdp, ddi_dma_cookie_t *dmackp,
		int single_segment, int seg_index);
void	ata_pciide_dma_setup(ata_ctl_t *ata_ctlp, prde_t *srcp, int sg_cnt);
void	ata_pciide_dma_start(ata_ctl_t *ata_ctlp, uchar_t direction);
void	ata_pciide_dma_stop(ata_ctl_t *ata_ctlp);
int	ata_pciide_status_clear(ata_ctl_t *ata_ctlp);
int	ata_pciide_status_dmacheck_clear(ata_ctl_t *ata_ctlp);
int	ata_pciide_status_pending(ata_ctl_t *ata_ctlp);

#ifdef	__cplusplus
}
#endif

#endif /* _ATA_COMMON_H */