[USB]
[reactos.git] / reactos / drivers / storage / ide / uniata / bsmaster.h
1 /*++
2
3 Copyright (c) 2002-2011 Alexandr A. Telyatnikov (Alter)
4
5 Module Name:
6 bsmaster.h
7
8 Abstract:
9 This file contains DMA/UltraDMA and IDE BusMastering related definitions,
10 internal structures and useful macros
11
12 Author:
13 Alexander A. Telyatnikov (Alter)
14
15 Environment:
16 kernel mode only
17
18 Notes:
19
20 THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
21 IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
22 OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
23 IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
24 INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
25 NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
26 DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
27 THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
29 THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30
31 Revision History:
32
33 Code was created by
34 Alter, Copyright (c) 2002-2008
35
36 Some definitions were taken from FreeBSD 4.3-4.6 ATA driver by
37 Søren Schmidt, Copyright (c) 1998,1999,2000,2001
38
39 --*/
40
41 #ifndef __IDE_BUSMASTER_H__
42 #define __IDE_BUSMASTER_H__
43
44 #include "config.h"
45
46 #include "tools.h"
47
48 //
49 //
50 //
51 #define ATA_IDLE 0x0
52 #define ATA_IMMEDIATE 0x1
53 #define ATA_WAIT_INTR 0x2
54 #define ATA_WAIT_READY 0x3
55 #define ATA_ACTIVE 0x4
56 #define ATA_ACTIVE_ATA 0x5
57 #define ATA_ACTIVE_ATAPI 0x6
58 #define ATA_REINITING 0x7
59 #define ATA_WAIT_BASE_READY 0x8
60 #define ATA_WAIT_IDLE 0x9
61
62
63 #include "bm_devs.h"
64
65 #include "uata_ctl.h"
66
67 #define MAX_RETRIES 6
68 #define RETRY_UDMA2 1
69 #define RETRY_WDMA 2
70 #define RETRY_PIO 3
71
72
73 #define IO_WD1 0x1F0 /* Primary Fixed Disk Controller */
74 #define IO_WD2 0x170 /* Secondary Fixed Disk Controller */
75 #define IP_PC98_BANK 0x432
76
77 #define PCI_ADDRESS_IOMASK 0xfffffff0
78
79 #define ATA_BM_OFFSET1 0x08
80 #define ATA_IOSIZE 0x08
81 #define ATA_ALTOFFSET 0x206 /* alternate registers offset */
82 #define ATA_PCCARD_ALTOFFSET 0x0e /* do for PCCARD devices */
83 #define ATA_ALTIOSIZE 0x01 /* alternate registers size */
84 #define ATA_BMIOSIZE 0x20
85 #define ATA_PC98_BANKIOSIZE 0x01
86 //#define ATA_MAX_LBA28 DEF_U64(0x0fffffff)
87 // Hitachi 1 Tb HDD didn't allow LBA28 with BCount > 1 beyond this LBA
88 #define ATA_MAX_IOLBA28 DEF_U64(0x0fffff80)
89 #define ATA_MAX_LBA28 DEF_U64(0x0fffffff)
90
91 #define ATA_DMA_ENTRIES 256 /* PAGESIZE/2/sizeof(BM_DMA_ENTRY)*/
92 #define ATA_DMA_EOT 0x80000000
93
94 #define DEV_BSIZE 512
95
96 #define ATAPI_MAGIC_LSB 0x14
97 #define ATAPI_MAGIC_MSB 0xeb
98
99 #define AHCI_MAX_PORT 32
100
101 #define SATA_MAX_PM_UNITS 16
102
103 typedef struct _BUSMASTER_CTX {
104 PBUSMASTER_CONTROLLER_INFORMATION* BMListPtr;
105 ULONG* BMListLen;
106 } BUSMASTER_CTX, *PBUSMASTER_CTX;
107
108 #define PCI_DEV_CLASS_STORAGE 0x01
109
110 #define PCI_DEV_SUBCLASS_IDE 0x01
111 #define PCI_DEV_SUBCLASS_RAID 0x04
112 #define PCI_DEV_SUBCLASS_ATA 0x05
113 #define PCI_DEV_SUBCLASS_SATA 0x06
114
115 #define PCI_DEV_PROGIF_AHCI_1_0 0x01
116
117 /* structure for holding DMA address data */
118 typedef struct BM_DMA_ENTRY {
119 ULONG base;
120 ULONG count;
121 } BM_DMA_ENTRY, *PBM_DMA_ENTRY;
122
123 typedef struct _IDE_BUSMASTER_REGISTERS {
124 UCHAR Command;
125 UCHAR DeviceSpecific0;
126 UCHAR Status;
127 UCHAR DeviceSpecific1;
128 ULONG PRD_Table;
129 } IDE_BUSMASTER_REGISTERS, *PIDE_BUSMASTER_REGISTERS;
130
131 #define BM_STATUS_ACTIVE 0x01
132 #define BM_STATUS_ERR 0x02
133 #define BM_STATUS_INTR 0x04
134 #define BM_STATUS_MASK 0x07
135 #define BM_STATUS_DRIVE_0_DMA 0x20
136 #define BM_STATUS_DRIVE_1_DMA 0x40
137 #define BM_STATUS_SIMPLEX_ONLY 0x80
138
139 #define BM_COMMAND_START_STOP 0x01
140 /*#define BM_COMMAND_WRITE 0x08
141 #define BM_COMMAND_READ 0x00*/
142 #define BM_COMMAND_WRITE 0x00
143 #define BM_COMMAND_READ 0x08
144
145 #define BM_DS0_SII_DMA_ENABLE (1 << 0) /* DMA run switch */
146 #define BM_DS0_SII_IRQ (1 << 3) /* ??? */
147 #define BM_DS0_SII_DMA_SATA_IRQ (1 << 4) /* OR of all SATA IRQs */
148 #define BM_DS0_SII_DMA_ERROR (1 << 17) /* PCI bus error */
149 #define BM_DS0_SII_DMA_COMPLETE (1 << 18) /* cmd complete / IRQ pending */
150
151
152 #define IDX_BM_IO (IDX_IO2_o+IDX_IO2_o_SZ)
153 //#define IDX_BM_IO_SZ sizeof(IDE_BUSMASTER_REGISTERS)
154 #define IDX_BM_IO_SZ 5
155
156 #define IDX_BM_Command (FIELD_OFFSET(IDE_BUSMASTER_REGISTERS, Command )+IDX_BM_IO)
157 #define IDX_BM_DeviceSpecific0 (FIELD_OFFSET(IDE_BUSMASTER_REGISTERS, DeviceSpecific0)+IDX_BM_IO)
158 #define IDX_BM_Status (FIELD_OFFSET(IDE_BUSMASTER_REGISTERS, Status )+IDX_BM_IO)
159 #define IDX_BM_DeviceSpecific1 (FIELD_OFFSET(IDE_BUSMASTER_REGISTERS, DeviceSpecific1)+IDX_BM_IO)
160 #define IDX_BM_PRD_Table (FIELD_OFFSET(IDE_BUSMASTER_REGISTERS, PRD_Table )+IDX_BM_IO)
161
162 typedef struct _IDE_AHCI_REGISTERS {
163 // HBA Capabilities
164 struct {
165 ULONG NOP:5; // number of ports
166 ULONG Reserved5_7:1;
167 ULONG NCS:5; // number of command slots
168 ULONG PSC:1; // partial state capable
169 ULONG SSC:1; // slumber state capable
170 ULONG PMD:1; // PIO multiple DRQ block
171 ULONG Reserved16:1;
172
173 ULONG SPM:1; // port multiplier
174 ULONG SAM:1; // AHCI mode only
175 ULONG SNZO:1; // non-zero DMA offset
176 ULONG ISS:4; // interface speed
177 ULONG SCLO:1; // command list override
178 ULONG SAL:1; // activity LED
179 ULONG SALP:1; // aggressive link power management
180 ULONG SSS:1; // staggered spin-up
181 ULONG SIS:1; // interlock switch
182 ULONG Reserved29:1;
183 ULONG SNCQ:1; // native command queue
184 ULONG S64A:1; // 64bit addr
185 } CAP;
186
187 #define AHCI_CAP_NOP_MASK 0x0000001f
188 #define AHCI_CAP_NCS_MASK 0x00001f00
189 #define AHCI_CAP_PMD 0x00008000
190 #define AHCI_CAP_SPM 0x00020000
191 #define AHCI_CAP_SAM 0x00040000
192 #define AHCI_CAP_SCLO 0x01000000
193 #define AHCI_CAP_S64A 0x80000000
194
195 // Global HBA Control
196 struct {
197 ULONG HR:1; // HBA Reset
198 ULONG IE:1; // interrupt enable
199 ULONG Reserved2_30:1;
200 ULONG AE:1; // AHCI enable
201 } GHC;
202
203 #define AHCI_GHC 0x04
204 #define AHCI_GHC_HR 0x00000001
205 #define AHCI_GHC_IE 0x00000002
206 #define AHCI_GHC_AE 0x80000000
207
208 // Interrupt status (bit mask)
209 ULONG IS;
210 // Ports implemented (bit mask)
211 ULONG PI;
212 // AHCI Version
213 ULONG VS;
214 ULONG Reserved[3];
215
216 UCHAR Reserved2[0x80];
217
218 UCHAR VendorSpec[0x60];
219 } IDE_AHCI_REGISTERS, *PIDE_AHCI_REGISTERS;
220
221 #define IDX_AHCI_CAP (FIELD_OFFSET(IDE_AHCI_REGISTERS, CAP))
222 #define IDX_AHCI_GHC (FIELD_OFFSET(IDE_AHCI_REGISTERS, GHC))
223 #define IDX_AHCI_IS (FIELD_OFFSET(IDE_AHCI_REGISTERS, IS))
224 #define IDX_AHCI_VS (FIELD_OFFSET(IDE_AHCI_REGISTERS, VS))
225 #define IDX_AHCI_PI (FIELD_OFFSET(IDE_AHCI_REGISTERS, PI))
226
227
228 typedef union _SATA_SSTATUS_REG {
229
230 struct {
231 ULONG DET:4; // Device Detection
232
233 #define SStatus_DET_NoDev 0x00
234 #define SStatus_DET_Dev_NoPhy 0x01
235 #define SStatus_DET_Dev_Ok 0x03
236 #define SStatus_DET_Offline 0x04
237
238 ULONG SPD:4; // Current Interface Speed
239
240 #define SStatus_SPD_NoDev 0x00
241 #define SStatus_SPD_Gen1 0x01
242 #define SStatus_SPD_Gen2 0x02
243 #define SStatus_SPD_Gen3 0x03
244
245 ULONG IPM:4; // Interface Power Management
246
247 #define SStatus_IPM_NoDev 0x00
248 #define SStatus_IPM_Active 0x01
249 #define SStatus_IPM_Partial 0x02
250 #define SStatus_IPM_Slumber 0x06
251
252 ULONG Reserved:20;
253 };
254 ULONG Reg;
255
256 } SATA_SSTATUS_REG, *PSATA_SSTATUS_REG;
257
258
259 typedef union _SATA_SCONTROL_REG {
260
261 struct {
262 ULONG DET:4; // Device Detection Init
263
264 #define SControl_DET_DoNothing 0x00
265 #define SControl_DET_Idle 0x00
266 #define SControl_DET_Init 0x01
267 #define SControl_DET_Disable 0x04
268
269 ULONG SPD:4; // Speed Allowed
270
271 #define SControl_SPD_NoRestrict 0x00
272 #define SControl_SPD_LimGen1 0x01
273 #define SControl_SPD_LimGen2 0x02
274 #define SControl_SPD_LimGen3 0x03
275
276 ULONG IPM:4; // Interface Power Management Transitions Allowed
277
278 #define SControl_IPM_NoRestrict 0x00
279 #define SControl_IPM_NoPartial 0x01
280 #define SControl_IPM_NoSlumber 0x02
281 #define SControl_IPM_NoPartialSlumber 0x03
282
283 ULONG SPM:4; // Select Power Management, unused by AHCI
284 ULONG PMP:4; // Port Multiplier Port, unused by AHCI
285 ULONG Reserved:12;
286 };
287 ULONG Reg;
288
289 } SATA_SCONTROL_REG, *PSATA_SCONTROL_REG;
290
291
292 typedef union _SATA_SERROR_REG {
293
294 struct {
295 struct {
296 UCHAR I:1; // Recovered Data Integrity Error
297 UCHAR M:1; // Recovered Communications Error
298 UCHAR Reserved_2_7:6;
299
300 UCHAR T:1; // Transient Data Integrity Error
301 UCHAR C:1; // Persistent Communication or Data Integrity Error
302 UCHAR P:1; // Protocol Error
303 UCHAR E:1; // Internal Error
304 UCHAR Reserved_12_15:4;
305 } ERR;
306
307 struct {
308 UCHAR N:1; // PhyRdy Change, PIS.PRCS
309 UCHAR I:1; // Phy Internal Error
310 UCHAR W:1; // Comm Wake
311 UCHAR B:1; // 10B to 8B Decode Error
312 UCHAR D:1; // Disparity Error, not used by AHCI
313 UCHAR C:1; // CRC Error
314 UCHAR H:1; // Handshake Error
315 UCHAR S:1; // Link Sequence Error
316
317 UCHAR T:1; // Transport state transition error
318 UCHAR F:1; // Unknown FIS Type
319 UCHAR X:1; // Exchanged
320 UCHAR Reserved_27_31:5;
321 } DIAG;
322 };
323 ULONG Reg;
324
325 } SATA_SERROR_REG, *PSATA_SERROR_REG;
326
327
328 typedef struct _IDE_SATA_REGISTERS {
329 union {
330 SATA_SSTATUS_REG SStatus;
331 ULONG SStatus_Reg;
332 };
333 union {
334 SATA_SERROR_REG SError;
335 ULONG SError_Reg;
336 };
337 union {
338 SATA_SCONTROL_REG SControl;
339 ULONG SControl_Reg;
340 };
341
342 // SATA 1.2
343
344 ULONG SActive;
345 union {
346 ULONG Reg;
347 struct {
348 USHORT PMN; // PM Notify, bitmask
349 USHORT Reserved;
350 };
351 } SNTF;
352 ULONG SReserved[11];
353 } IDE_SATA_REGISTERS, *PIDE_SATA_REGISTERS;
354
355 #define IDX_SATA_IO (IDX_BM_IO+IDX_BM_IO_SZ)
356 //#define IDX_SATA_IO_SZ sizeof(IDE_SATA_REGISTERS)
357 #define IDX_SATA_IO_SZ 5
358
359 #define IDX_SATA_SStatus (0+IDX_SATA_IO)
360 #define IDX_SATA_SError (1+IDX_SATA_IO)
361 #define IDX_SATA_SControl (2+IDX_SATA_IO)
362 #define IDX_SATA_SActive (3+IDX_SATA_IO)
363 #define IDX_SATA_SNTF_PMN (4+IDX_SATA_IO)
364
365 #define IDX_INDEXED_IO (IDX_SATA_IO+IDX_SATA_IO_SZ)
366 #define IDX_INDEXED_IO_SZ 2
367
368 #define IDX_INDEXED_ADDR (0+IDX_INDEXED_IO)
369 #define IDX_INDEXED_DATA (1+IDX_INDEXED_IO)
370
371 #define IDX_MAX_REG (IDX_INDEXED_IO+IDX_INDEXED_IO_SZ)
372
373
374 typedef union _AHCI_IS_REG {
375 struct {
376 ULONG DHRS:1;// Device to Host Register FIS Interrupt
377 ULONG PSS:1; // PIO Setup FIS Interrupt
378 ULONG DSS:1; // DMA Setup FIS Interrupt
379 ULONG SDBS:1;// Set Device Bits Interrupt
380 ULONG UFS:1; // Unknown FIS Interrupt
381 ULONG DPS:1; // Descriptor Processed
382 ULONG PCS:1; // Port Connect Change Status
383 ULONG DMPS:1;// Device Mechanical Presence Status
384
385 ULONG Reserved_8_21:14;
386 ULONG PRCS:1;// PhyRdy Change Status
387 ULONG IPMS:1;// Incorrect Port Multiplier Status
388
389 ULONG OFS:1; // Overflow Status
390 ULONG Reserved_25:1;
391 ULONG INFS:1;// Interface Non-fatal Error Status
392 ULONG IFS:1; // Interface Fatal Error Status
393 ULONG HBDS:1;// Host Bus Data Error Status
394 ULONG HBFS:1;// Host Bus Fatal Error Status
395 ULONG TFES:1;// Task File Error Status
396 ULONG CPDS:1;// Cold Port Detect Status
397 };
398 ULONG Reg;
399 } AHCI_IS_REG, *PAHCI_IS_REG;
400
401 #define ATA_AHCI_P_IX_DHR 0x00000001
402 #define ATA_AHCI_P_IX_PS 0x00000002
403 #define ATA_AHCI_P_IX_DS 0x00000004
404 #define ATA_AHCI_P_IX_SDB 0x00000008
405 #define ATA_AHCI_P_IX_UF 0x00000010
406 #define ATA_AHCI_P_IX_DP 0x00000020
407 #define ATA_AHCI_P_IX_PC 0x00000040
408 #define ATA_AHCI_P_IX_DI 0x00000080
409
410 #define ATA_AHCI_P_IX_PRC 0x00400000
411 #define ATA_AHCI_P_IX_IPM 0x00800000
412 #define ATA_AHCI_P_IX_OF 0x01000000
413 #define ATA_AHCI_P_IX_INF 0x04000000
414 #define ATA_AHCI_P_IX_IF 0x08000000
415 #define ATA_AHCI_P_IX_HBD 0x10000000
416 #define ATA_AHCI_P_IX_HBF 0x20000000
417 #define ATA_AHCI_P_IX_TFE 0x40000000
418 #define ATA_AHCI_P_IX_CPD 0x80000000
419
420 #define AHCI_CLB_ALIGNEMENT_MASK ((ULONGLONG)(1024-1))
421 #define AHCI_FIS_ALIGNEMENT_MASK ((ULONGLONG)(256-1))
422 #define AHCI_CMD_ALIGNEMENT_MASK ((ULONGLONG)(128-1))
423
424 typedef struct _IDE_AHCI_PORT_REGISTERS {
425 union {
426 struct {
427 ULONG CLB; // command list base address, 1K-aligned
428 ULONG CLBU; // command list base address (upper 32bits)
429 };
430 ULONGLONG CLB64;
431 }; // 0x100 + 0x80*c + 0x0000
432
433 union {
434 struct {
435 ULONG FB; // FIS base address
436 ULONG FBU; // FIS base address (upper 32bits)
437 };
438 ULONGLONG FB64;
439 }; // 0x100 + 0x80*c + 0x0008
440
441 union {
442 ULONG IS_Reg; // interrupt status
443 AHCI_IS_REG IS;
444 }; // 0x100 + 0x80*c + 0x0010
445
446 union {
447 ULONG Reg; // interrupt enable
448 struct {
449 ULONG DHRE:1;// Device to Host Register FIS Interrupt Enable
450 ULONG PSE:1; // PIO Setup FIS Interrupt Enable
451 ULONG DSE:1; // DMA Setup FIS Interrupt Enable
452 ULONG SDBE:1;// Set Device Bits FIS Interrupt Enable
453 ULONG UFE:1; // Unknown FIS Interrupt Enable
454 ULONG DPE:1; // Descriptor Processed Interrupt Enable
455 ULONG PCE:1; // Port Change Interrupt Enable
456 ULONG DPME:1;// Device Mechanical Presence Enable
457
458 ULONG Reserved_8_21:14;
459 ULONG PRCE:1;// PhyRdy Change Interrupt Enable
460 ULONG IPME:1;// Incorrect Port Multiplier Enable
461 ULONG OFE:1; // Overflow Enable
462 ULONG Reserved_25:1;
463 ULONG INFE:1;// Interface Non-fatal Error Enable
464 ULONG IFE:1; // Interface Fatal Error Enable
465 ULONG HBDE:1;// Host Bus Data Error Enable
466 ULONG HBFE:1;// Host Bus Fatal Error Enable
467 ULONG TFEE:1;// Task File Error Enable
468 ULONG CPDE:1;// Cold Port Detect Enable
469 };
470 } IE; // 0x100 + 0x80*c + 0x0014
471
472 union {
473 ULONG Reg; // command register
474 struct {
475
476 ULONG ST:1; // Start
477 ULONG SUD:1; // Spin-Up Device
478 ULONG POD:1; // Power On Device
479 ULONG CLO:1; // Command List Override
480 ULONG FRE:1; // FIS Receive Enable
481 ULONG Reserved_5_7:3;
482
483 ULONG CCS:5; // Current Command Slot
484 ULONG MPSS:1;// Mechanical Presence Switch State
485 ULONG FR:1; // FIS Receive Running
486 ULONG CR:1; // Command List Running
487
488 ULONG CPS:1; // Cold Presence State
489 ULONG PMA:1; // Port Multiplier Attached
490 ULONG HPCP:1;// Hot Plug Capable Port
491 ULONG MPSP:1;// Mechanical Presence Switch Attached to Port
492 ULONG CPD:1; // Cold Presence Detection
493 ULONG ESP:1; // External SATA Port
494 ULONG Reserved_22_23:2;
495
496 ULONG ATAPI:1; // Device is ATAPI
497 ULONG DLAE:1;// Drive LED on ATAPI Enable
498 ULONG ALPE:1;// Aggressive Link Power Management Enable
499 ULONG ASP:1; // Aggressive Slumber / Partial
500 ULONG ICC:4; // Interface Communication Control
501
502 #define SATA_CMD_ICC_Idle 0x00
503 #define SATA_CMD_ICC_NoOp 0x00
504 #define SATA_CMD_ICC_Active 0x01
505 #define SATA_CMD_ICC_Partial 0x02
506 #define SATA_CMD_ICC_Slumber 0x06
507 };
508 } CMD; // 0x100 + 0x80*c + 0x0018
509
510 ULONG Reserved;
511
512 union {
513 ULONG Reg; // Task File Data
514 struct {
515 struct {
516 UCHAR ERR:1;
517 UCHAR cs1:2;// command-specific
518 UCHAR DRQ:1;
519 UCHAR cs2:3;// command-specific
520 UCHAR BSY:1;
521 } STS;
522 UCHAR ERR; // Contains the latest copy of the task file error register.
523 UCHAR Reserved[2];
524 };
525 } TFD; // 0x100 + 0x80*c + 0x0020
526
527 union {
528 ULONG Reg; // signature
529 struct {
530 UCHAR SectorCount;
531 UCHAR LbaLow;
532 UCHAR LbaMid;
533 UCHAR LbaHigh;
534 };
535 } SIG; // 0x100 + 0x80*c + 0x0024
536 union {
537 ULONG SStatus; // SCR0
538 SATA_SSTATUS_REG SSTS;
539 }; // 0x100 + 0x80*c + 0x0028
540 union {
541 ULONG SControl; // SCR2
542 SATA_SCONTROL_REG SCTL;
543 }; // 0x100 + 0x80*c + 0x002c
544 union {
545 ULONG SError; // SCR1
546 SATA_SERROR_REG SERR;
547 }; // 0x100 + 0x80*c + 0x0030
548 union {
549 ULONG SACT; // SCR3
550 ULONG SActive; // bitmask
551 }; // 0x100 + 0x80*c + 0x0034
552
553 ULONG CI; // Command issue, bitmask, 0x100 + 0x80*c + 0x0038
554
555 // AHCI 1.1
556 union {
557 ULONG Reg;
558 struct {
559 USHORT PMN; // PM Notify, bitmask
560 USHORT Reserved;
561 };
562 } SNTF; // 0x100 + 0x80*c + 0x003c
563
564 ULONG FIS_Switching_Reserved[12];
565 UCHAR VendorSpec[16];
566
567 } IDE_AHCI_PORT_REGISTERS, *PIDE_AHCI_PORT_REGISTERS;
568
569 #define IDX_AHCI_P_CLB (FIELD_OFFSET(IDE_AHCI_PORT_REGISTERS, CLB))
570 #define IDX_AHCI_P_FB (FIELD_OFFSET(IDE_AHCI_PORT_REGISTERS, FB))
571 #define IDX_AHCI_P_IS (FIELD_OFFSET(IDE_AHCI_PORT_REGISTERS, IS))
572 #define IDX_AHCI_P_IE (FIELD_OFFSET(IDE_AHCI_PORT_REGISTERS, IE))
573 #define IDX_AHCI_P_CI (FIELD_OFFSET(IDE_AHCI_PORT_REGISTERS, CI))
574 #define IDX_AHCI_P_TFD (FIELD_OFFSET(IDE_AHCI_PORT_REGISTERS, TFD))
575 #define IDX_AHCI_P_SIG (FIELD_OFFSET(IDE_AHCI_PORT_REGISTERS, SIG))
576 #define IDX_AHCI_P_CMD (FIELD_OFFSET(IDE_AHCI_PORT_REGISTERS, CMD))
577
578 #define IDX_AHCI_P_SNTF (FIELD_OFFSET(IDE_AHCI_PORT_REGISTERS, SNTF))
579
580 // AHCI commands ( -> IDX_AHCI_P_CMD)
581 #define ATA_AHCI_P_CMD_ST 0x00000001
582 #define ATA_AHCI_P_CMD_SUD 0x00000002
583 #define ATA_AHCI_P_CMD_POD 0x00000004
584 #define ATA_AHCI_P_CMD_CLO 0x00000008
585 #define ATA_AHCI_P_CMD_FRE 0x00000010
586 #define ATA_AHCI_P_CMD_CCS_MASK 0x00001f00
587 #define ATA_AHCI_P_CMD_ISS 0x00002000
588 #define ATA_AHCI_P_CMD_FR 0x00004000
589 #define ATA_AHCI_P_CMD_CR 0x00008000
590 #define ATA_AHCI_P_CMD_CPS 0x00010000
591 #define ATA_AHCI_P_CMD_PMA 0x00020000
592 #define ATA_AHCI_P_CMD_HPCP 0x00040000
593 #define ATA_AHCI_P_CMD_ISP 0x00080000
594 #define ATA_AHCI_P_CMD_CPD 0x00100000
595 #define ATA_AHCI_P_CMD_ATAPI 0x01000000
596 #define ATA_AHCI_P_CMD_DLAE 0x02000000
597 #define ATA_AHCI_P_CMD_ALPE 0x04000000
598 #define ATA_AHCI_P_CMD_ASP 0x08000000
599 #define ATA_AHCI_P_CMD_ICC_MASK 0xf0000000
600 #define ATA_AHCI_P_CMD_NOOP 0x00000000
601 #define ATA_AHCI_P_CMD_ACTIVE 0x10000000
602 #define ATA_AHCI_P_CMD_PARTIAL 0x20000000
603 #define ATA_AHCI_P_CMD_SLUMBER 0x60000000
604
605
606 typedef struct _IDE_AHCI_PRD_ENTRY {
607 union {
608 ULONG base;
609 ULONGLONG base64;
610 struct {
611 ULONG DBA;
612 union {
613 ULONG DBAU;
614 ULONG baseu;
615 };
616 };
617 };
618 ULONG Reserved1;
619
620 ULONG DBC:22;
621 ULONG Reserved2:9;
622 ULONG I:1;
623
624 } IDE_AHCI_PRD_ENTRY, *PIDE_AHCI_PRD_ENTRY;
625
626 #define ATA_AHCI_DMA_ENTRIES (PAGE_SIZE/2/sizeof(IDE_AHCI_PRD_ENTRY)) /* 128 */
627 #define ATA_AHCI_MAX_TAGS 32
628
629 #define AHCI_FIS_TYPE_ATA_H2D 0x27
630 #define AHCI_FIS_TYPE_ATA_D2H 0x34
631
632 #define AHCI_FIS_COMM_PM (0x80 | AHCI_DEV_SEL_PM)
633
634 #define AHCI_DEV_SEL_1 0x00
635 #define AHCI_DEV_SEL_2 0x01
636 #define AHCI_DEV_SEL_PM 0x0f
637
638 /* 128-byte aligned */
639 typedef struct _IDE_AHCI_CMD {
640 UCHAR cfis[64];
641 UCHAR acmd[32];
642 UCHAR Reserved[32];
643 IDE_AHCI_PRD_ENTRY prd_tab[ATA_AHCI_DMA_ENTRIES]; // also 128-byte aligned
644 } IDE_AHCI_CMD, *PIDE_AHCI_CMD;
645
646
647 /* cmd_flags */
648 #define ATA_AHCI_CMD_ATAPI 0x0020
649 #define ATA_AHCI_CMD_WRITE 0x0040
650 #define ATA_AHCI_CMD_PREFETCH 0x0080
651 #define ATA_AHCI_CMD_RESET 0x0100
652 #define ATA_AHCI_CMD_BIST 0x0200
653 #define ATA_AHCI_CMD_CLR_BUSY 0x0400
654
655 /* 128-byte aligned */
656 typedef struct _IDE_AHCI_CMD_LIST {
657 USHORT cmd_flags;
658 USHORT prd_length; /* PRD entries */
659 ULONG bytecount;
660 ULONGLONG cmd_table_phys; /* points to IDE_AHCI_CMD */
661 ULONG Reserved[4];
662 } IDE_AHCI_CMD_LIST, *PIDE_AHCI_CMD_LIST;
663
664 /* 256-byte aligned */
665 typedef struct _IDE_AHCI_RCV_FIS {
666 UCHAR dsfis[28];
667 UCHAR Reserved1[4];
668 UCHAR psfis[24];
669 UCHAR Reserved2[8];
670 UCHAR rfis[24];
671 UCHAR Reserved3[4];
672 ULONG SDBFIS;
673 UCHAR ufis[64];
674 UCHAR Reserved4[96];
675 } IDE_AHCI_RCV_FIS, *PIDE_AHCI_RCV_FIS;
676
677 /* 1K-byte aligned */
678 typedef struct _IDE_AHCI_CHANNEL_CTL_BLOCK {
679 IDE_AHCI_CMD_LIST cmd_list[ATA_AHCI_MAX_TAGS]; // 1K-size (32*32)
680 IDE_AHCI_RCV_FIS rcv_fis;
681 IDE_AHCI_CMD cmd; // for single internal comamnds w/o associated AtaReq
682 } IDE_AHCI_CHANNEL_CTL_BLOCK, *PIDE_AHCI_CHANNEL_CTL_BLOCK;
683
684
685 #define IsBusMaster(pciData) \
686 ( ((pciData)->Command & (PCI_ENABLE_BUS_MASTER/* | PCI_ENABLE_IO_SPACE*/)) == \
687 (PCI_ENABLE_BUS_MASTER/* | PCI_ENABLE_IO_SPACE*/))
688
689 #define PCI_IDE_PROGIF_NATIVE_1 0x01
690 #define PCI_IDE_PROGIF_NATIVE_2 0x04
691 #define PCI_IDE_PROGIF_NATIVE_ALL 0x05
692
693 #define IsMasterDev(pciData) \
694 ( ((pciData)->ProgIf & 0x80) && \
695 ((pciData)->ProgIf & PCI_IDE_PROGIF_NATIVE_ALL) != PCI_IDE_PROGIF_NATIVE_ALL )
696
697 //#define INT_Q_SIZE 32
698 #define MIN_REQ_TTL 4
699
700 union _ATA_REQ;
701
702 typedef union _ATA_REQ {
703 // ULONG reqId; // serial
704 struct {
705
706 //union {
707
708 struct {
709 union _ATA_REQ* next_req;
710 union _ATA_REQ* prev_req;
711
712 PSCSI_REQUEST_BLOCK Srb; // Current request on controller.
713
714 PUSHORT DataBuffer; // Data buffer pointer.
715 ULONG WordsLeft; // Data words left.
716 ULONG TransferLength; // Originally requested transfer length
717 LONGLONG lba;
718 ULONG WordsTransfered;// Data words already transfered.
719 ULONG bcount;
720
721 UCHAR retry;
722 UCHAR ttl;
723 // UCHAR tag;
724 UCHAR Flags;
725 UCHAR ReqState;
726
727 PSCSI_REQUEST_BLOCK OriginalSrb; // Mechanism Status Srb Data
728
729 ULONG dma_entries;
730 union {
731 // for ATA
732 struct {
733 ULONG dma_base;
734 ULONG dma_baseu;
735 } ata;
736 // for AHCI
737 struct {
738 ULONGLONG ahci_base64;
739 ULONGLONG in_lba;
740 PIDE_AHCI_CMD ahci_cmd_ptr;
741 ULONG in_bcount;
742 ULONG in_status;
743 USHORT io_cmd_flags; // out
744
745 } ahci;
746 };
747 };
748 //UCHAR padding_128b[128]; // Note: we assume, NT allocates block > 4k as PAGE-aligned
749 //};
750 struct {
751 union {
752 BM_DMA_ENTRY dma_tab[ATA_DMA_ENTRIES];
753 IDE_AHCI_CMD ahci_cmd0; // for AHCI, 128-byte aligned
754 };
755 };
756 };
757
758 UCHAR padding_4kb[PAGE_SIZE];
759
760 } ATA_REQ, *PATA_REQ;
761
762 #define REQ_FLAG_FORCE_DOWNRATE 0x01
763 #define REQ_FLAG_DMA_OPERATION 0x02
764 #define REQ_FLAG_REORDERABLE_CMD 0x04
765 #define REQ_FLAG_RW_MASK 0x08
766 #define REQ_FLAG_READ 0x08
767 #define REQ_FLAG_WRITE 0x00
768 #define REQ_FLAG_FORCE_DOWNRATE_LBA48 0x10
769 #define REQ_FLAG_DMA_DBUF 0x20
770 #define REQ_FLAG_DMA_DBUF_PRD 0x40
771 #define REQ_FLAG_LBA48 0x80
772
773 // Request states
774 #define REQ_STATE_NONE 0x00
775 #define REQ_STATE_QUEUED 0x10
776
777 #define REQ_STATE_PREPARE_TO_TRANSFER 0x20
778 #define REQ_STATE_PREPARE_TO_NEXT 0x21
779 #define REQ_STATE_READY_TO_TRANSFER 0x30
780
781 #define REQ_STATE_EXPECTING_INTR 0x40
782 #define REQ_STATE_ATAPI_EXPECTING_CMD_INTR 0x41
783 #define REQ_STATE_ATAPI_EXPECTING_DATA_INTR 0x42
784 #define REQ_STATE_ATAPI_DO_NOTHING_INTR 0x43
785
786 #define REQ_STATE_EARLY_INTR 0x48
787
788 #define REQ_STATE_PROCESSING_INTR 0x50
789
790 #define REQ_STATE_DPC_INTR_REQ 0x51
791 #define REQ_STATE_DPC_RESET_REQ 0x52
792 #define REQ_STATE_DPC_COMPLETE_REQ 0x53
793
794 #define REQ_STATE_DPC_WAIT_BUSY0 0x57
795 #define REQ_STATE_DPC_WAIT_BUSY1 0x58
796 #define REQ_STATE_DPC_WAIT_BUSY 0x59
797 #define REQ_STATE_DPC_WAIT_DRQ 0x5a
798 #define REQ_STATE_DPC_WAIT_DRQ0 0x5b
799 #define REQ_STATE_DPC_WAIT_DRQ_ERR 0x5c
800
801 #define REQ_STATE_TRANSFER_COMPLETE 0x7f
802
803 // Command actions:
804 #define CMD_ACTION_PREPARE 0x01
805 #define CMD_ACTION_EXEC 0x02
806 #define CMD_ACTION_ALL (CMD_ACTION_PREPARE | CMD_ACTION_EXEC)
807
808 // predefined Reorder costs
809 #define REORDER_COST_MAX ((DEF_I64(0x1) << 60) - 1)
810 #define REORDER_COST_TTL (REORDER_COST_MAX - 1)
811 #define REORDER_COST_INTERSECT (REORDER_COST_MAX - 2)
812 #define REORDER_COST_DENIED (REORDER_COST_MAX - 3)
813 #define REORDER_COST_RESELECT (REORDER_COST_MAX/4)
814
815 #define REORDER_COST_SWITCH_RW_CD (REORDER_COST_MAX/8)
816 #define REORDER_MCOST_SWITCH_RW_CD (0)
817 #define REORDER_MCOST_SEEK_BACK_CD (16)
818
819 #define REORDER_COST_SWITCH_RW_HDD (0)
820 #define REORDER_MCOST_SWITCH_RW_HDD (4)
821 #define REORDER_MCOST_SEEK_BACK_HDD (2)
822
823 /*typedef struct _ATA_QUEUE {
824 struct _ATA_REQ* head_req; // index
825 struct _ATA_REQ* tail_req; // index
826 ULONG req_count;
827 ULONG dma_base;
828 BM_DMA_ENTRY dma_tab[ATA_DMA_ENTRIES];
829 } ATA_QUEUE, *PATA_QUEUE;*/
830
831 struct _HW_DEVICE_EXTENSION;
832 struct _HW_LU_EXTENSION;
833
834 typedef struct _IORES {
835 ULONG Addr; /* Base address*/
836 ULONG MemIo:1; /* Memory mapping (1) vs IO ports (0) */
837 ULONG Proc:1; /* Need special process via IO_Proc */
838 ULONG Reserved:30;
839 } IORES, *PIORES;
840
841 // Channel extension
842 typedef struct _HW_CHANNEL {
843
844 PATA_REQ cur_req;
845 ULONG cur_cdev;
846 /* PATA_REQ first_req;
847 PATA_REQ last_req;*/
848 ULONG queue_depth;
849 ULONG ChannelSelectWaitCount;
850
851 UCHAR DpcState;
852
853 BOOLEAN ExpectingInterrupt; // Indicates expecting an interrupt
854 BOOLEAN RDP; // Indicate last tape command was DSC Restrictive.
855 // Indicates whether '0x1f0' is the base address. Used
856 // in SMART Ioctl calls.
857 BOOLEAN PrimaryAddress;
858 // Placeholder for the sub-command value of the last
859 // SMART command.
860 UCHAR SmartCommand;
861 // Reorder anabled
862 BOOLEAN UseReorder;
863 // Placeholder for status register after a GET_MEDIA_STATUS command
864 UCHAR ReturningMediaStatus;
865
866 BOOLEAN CopyDmaBuffer;
867 //BOOLEAN MemIo;
868 BOOLEAN AltRegMap;
869
870 //UCHAR Reserved[3];
871
872 MECHANICAL_STATUS_INFORMATION_HEADER MechStatusData;
873 SENSE_DATA MechStatusSense;
874 ULONG MechStatusRetryCount;
875 SCSI_REQUEST_BLOCK InternalSrb;
876
877 ULONG MaxTransferMode; // may differ from Controller's value due to 40-pin cable
878
879 ULONG ChannelCtrlFlags;
880 ULONG ResetInProgress; // flag
881 LONG DisableIntr;
882 LONG CheckIntr;
883
884 ULONG lChannel;
885
886 #define CHECK_INTR_ACTIVE 0x03
887 #define CHECK_INTR_DETECTED 0x02
888 #define CHECK_INTR_CHECK 0x01
889 #define CHECK_INTR_IDLE 0x00
890
891 ULONG NextDpcChan;
892 PHW_TIMER HwScsiTimer;
893 LONGLONG DpcTime;
894 #if 0
895 PHW_TIMER HwScsiTimer1;
896 PHW_TIMER HwScsiTimer2;
897 LONGLONG DpcTime1;
898 // PHW_TIMER CurDpc;
899 // LARGE_INTEGER ActivationTime;
900
901 // KDPC Dpc;
902 // KTIMER Timer;
903 // PHW_TIMER HwScsiTimer;
904 // KSPIN_LOCK QueueSpinLock;
905 // KIRQL QueueOldIrql;
906 #endif
907 struct _HW_DEVICE_EXTENSION* DeviceExtension;
908 struct _HW_LU_EXTENSION* lun[IDE_MAX_LUN_PER_CHAN];
909
910 ULONG NumberLuns;
911 ULONG PmLunMap;
912
913 // Double-buffering support
914 PVOID DB_PRD;
915 ULONG DB_PRD_PhAddr;
916 PVOID DB_IO;
917 ULONG DB_IO_PhAddr;
918
919 PUCHAR DmaBuffer;
920
921 //
922 PIDE_AHCI_CHANNEL_CTL_BLOCK AhciCtlBlock0; // unaligned
923 PIDE_AHCI_CHANNEL_CTL_BLOCK AhciCtlBlock; // 128-byte aligned
924 ULONGLONG AHCI_CTL_PhAddr;
925 IORES BaseIoAHCI_Port;
926 //PVOID AHCI_FIS; // is not actually used by UniATA now, but is required by AHCI controller
927 //ULONGLONG AHCI_FIS_PhAddr;
928 // Note: in contrast to FBSD, we keep PRD and CMD item in AtaReq structure
929
930 #ifdef QUEUE_STATISTICS
931 LONGLONG QueueStat[MAX_QUEUE_STAT];
932 LONGLONG ReorderCount;
933 LONGLONG IntersectCount;
934 LONGLONG TryReorderCount;
935 LONGLONG TryReorderHeadCount;
936 LONGLONG TryReorderTailCount; /* in-order requests */
937 #endif //QUEUE_STATISTICS
938
939 //ULONG BaseMemAddress;
940 //ULONG BaseMemAddressOffset;
941 IORES RegTranslation[IDX_MAX_REG];
942
943 } HW_CHANNEL, *PHW_CHANNEL;
944
945 #define CTRFLAGS_DMA_ACTIVE 0x0001
946 #define CTRFLAGS_DMA_RO 0x0002
947 #define CTRFLAGS_DMA_OPERATION 0x0004
948 #define CTRFLAGS_INTR_DISABLED 0x0008
949 #define CTRFLAGS_DPC_REQ 0x0010
950 #define CTRFLAGS_ENABLE_INTR_REQ 0x0020
951 #define CTRFLAGS_LBA48 0x0040
952 #define CTRFLAGS_DSC_BSY 0x0080
953 #define CTRFLAGS_NO_SLAVE 0x0100
954 //#define CTRFLAGS_PATA 0x0200
955 #define CTRFLAGS_AHCI_PM 0x0400
956 #define CTRFLAGS_AHCI_PM2 0x0800
957
958 #define CTRFLAGS_PERMANENT (CTRFLAGS_DMA_RO | CTRFLAGS_NO_SLAVE)
959
960 #define GEOM_AUTO 0xffffffff
961 #define GEOM_STD 0x0000
962 #define GEOM_UNIATA 0x0001
963 #define GEOM_ORIG 0x0002
964 #define GEOM_MANUAL 0x0003
965
966 #define DPC_STATE_NONE 0x00
967 #define DPC_STATE_ISR 0x10
968 #define DPC_STATE_DPC 0x20
969 #define DPC_STATE_TIMER 0x30
970 #define DPC_STATE_COMPLETE 0x40
971
972 // Logical unit extension
973 typedef struct _HW_LU_EXTENSION {
974 IDENTIFY_DATA2 IdentifyData;
975 ULONGLONG NumOfSectors;
976 ULONG DeviceFlags; // Flags word for each possible device. DFLAGS_XXX
977 ULONG DiscsPresent; // Indicates number of platters on changer-ish devices.
978 BOOLEAN DWordIO; // Indicates use of 32-bit PIO
979 UCHAR ReturningMediaStatus;
980
981 UCHAR TransferMode; // current transfer mode
982 UCHAR LimitedTransferMode; // user-defined or IDE cable limitation
983 UCHAR OrigTransferMode; // transfer mode, returned by device IDENTIFY (can be changed via IOCTL)
984
985 UCHAR MaximumBlockXfer;
986 UCHAR Padding0[2]; // padding
987 ULONG ErrorCount; // Count of errors. Used to turn off features.
988 // ATA_QUEUE cmd_queue;
989 LONGLONG ReadCmdCost;
990 LONGLONG WriteCmdCost;
991 LONGLONG OtherCmdCost;
992 LONGLONG RwSwitchCost;
993 LONGLONG RwSwitchMCost;
994 LONGLONG SeekBackMCost;
995 //
996 PATA_REQ first_req;
997 PATA_REQ last_req;
998 ULONG queue_depth;
999 ULONG last_write;
1000
1001 ULONG LunSelectWaitCount;
1002
1003 // tuning options
1004 ULONG opt_GeomType;
1005 ULONG opt_MaxTransferMode;
1006 ULONG opt_PreferedTransferMode;
1007 BOOLEAN opt_ReadCacheEnable;
1008 BOOLEAN opt_WriteCacheEnable;
1009 UCHAR opt_ReadOnly;
1010 // padding
1011 BOOLEAN opt_reserved[1];
1012
1013 struct _SBadBlockListItem* bbListDescr;
1014 struct _SBadBlockRange* arrBadBlocks;
1015 ULONG nBadBlocks;
1016
1017 // Controller-specific LUN options
1018 union {
1019 /* for tricky controllers, those can change Logical-to-Physical LUN mapping.
1020 mainly for mapping SATA ports to compatible PATA registers
1021 Treated as PHYSICAL port number, regardless of logical mapping.
1022 */
1023 ULONG SATA_lun_map;
1024 };
1025
1026 struct _HW_DEVICE_EXTENSION* DeviceExtension;
1027 struct _HW_CHANNEL* chan;
1028 ULONG Lun;
1029
1030 #ifdef IO_STATISTICS
1031
1032 LONGLONG ModeErrorCount[MAX_RETRIES];
1033 LONGLONG RecoverCount[MAX_RETRIES];
1034 LONGLONG IoCount;
1035 LONGLONG BlockIoCount;
1036
1037 #endif//IO_STATISTICS
1038 } HW_LU_EXTENSION, *PHW_LU_EXTENSION;
1039
1040 // Device extension
1041 typedef struct _HW_DEVICE_EXTENSION {
1042 CHAR Signature[32];
1043 //PIDE_REGISTERS_1 BaseIoAddress1[IDE_MAX_CHAN]; // Base register locations
1044 //PIDE_REGISTERS_2 BaseIoAddress2[IDE_MAX_CHAN];
1045 ULONG BusInterruptLevel; // Interrupt level
1046 ULONG InterruptMode; // Interrupt Mode (Level or Edge)
1047 ULONG BusInterruptVector;
1048 // Number of channels being supported by one instantiation
1049 // of the device extension. Normally (and correctly) one, but
1050 // with so many broken PCI IDE controllers being sold, we have
1051 // to support them.
1052 ULONG NumberChannels;
1053 ULONG NumberLuns;
1054 ULONG FirstChannelToCheck;
1055 #if 0
1056 HW_LU_EXTENSION lun[IDE_MAX_LUN];
1057 HW_CHANNEL chan[AHCI_MAX_PORT/*IDE_MAX_CHAN*/];
1058 #else
1059 PHW_LU_EXTENSION lun;
1060 PHW_CHANNEL chan;
1061 #endif
1062 UCHAR LastInterruptedChannel;
1063 // Indicates the number of blocks transferred per int. according to the
1064 // identify data.
1065 BOOLEAN DriverMustPoll; // Driver is being used by the crash dump utility or ntldr.
1066 BOOLEAN BusMaster;
1067 BOOLEAN UseDpc; // Indicates use of DPC on long waits
1068 IDENTIFY_DATA FullIdentifyData; // Identify data for device
1069 // BusMaster specific data
1070 // PBM_DMA_ENTRY dma_tab_0;
1071 //KSPIN_LOCK DpcSpinLock;
1072
1073 ULONG ActiveDpcChan;
1074 ULONG FirstDpcChan;
1075 /*
1076 PHW_TIMER HwScsiTimer1;
1077 PHW_TIMER HwScsiTimer2;
1078 LONGLONG DpcTime1;
1079 LONGLONG DpcTime2;
1080 */
1081 ULONG queue_depth;
1082
1083 PDEVICE_OBJECT Isr2DevObj;
1084
1085 //PIDE_BUSMASTER_REGISTERS BaseIoAddressBM_0;
1086 IORES BaseIoAddressBM_0;
1087 //PIDE_BUSMASTER_REGISTERS BaseIoAddressBM[IDE_MAX_CHAN];
1088
1089 // Device identification
1090 ULONG DevID;
1091 ULONG RevID;
1092 ULONG slotNumber;
1093 ULONG SystemIoBusNumber;
1094 ULONG DevIndex;
1095
1096 ULONG InitMethod; // vendor specific
1097
1098 ULONG Channel;
1099
1100 ULONG HbaCtrlFlags;
1101 BOOLEAN simplexOnly;
1102 //BOOLEAN MemIo;
1103 BOOLEAN AltRegMap;
1104 BOOLEAN UnknownDev;
1105 BOOLEAN MasterDev;
1106 BOOLEAN Host64;
1107 BOOLEAN DWordIO; // Indicates use of 32-bit PIO
1108 UCHAR Reserved1[2];
1109
1110 LONG ReCheckIntr;
1111
1112 ULONG MaxTransferMode; // max transfer mode supported by controller
1113 ULONG HwFlags;
1114 INTERFACE_TYPE OrigAdapterInterfaceType;
1115 INTERFACE_TYPE AdapterInterfaceType;
1116 ULONG MaximumDmaTransferLength;
1117 ULONG AlignmentMask;
1118
1119 //ULONG BaseMemAddress;
1120
1121 //PIDE_SATA_REGISTERS BaseIoAddressSATA_0;
1122 IORES BaseIoAddressSATA_0;
1123 //PIDE_SATA_REGISTERS BaseIoAddressSATA[IDE_MAX_CHAN];
1124
1125 IORES BaseIoAHCI_0;
1126 //PIDE_AHCI_PORT_REGISTERS BaseIoAHCIPort[AHCI_MAX_PORT];
1127 ULONG AHCI_CAP;
1128
1129 BOOLEAN opt_AtapiDmaZeroTransfer; // default FALSE
1130 BOOLEAN opt_AtapiDmaControlCmd; // default FALSE
1131 BOOLEAN opt_AtapiDmaRawRead; // default TRUE
1132 BOOLEAN opt_AtapiDmaReadWrite; // default TRUE
1133
1134 PCCH FullDevName;
1135
1136 // Controller specific state/options
1137 union {
1138 ULONG HwCfg;
1139 };
1140
1141 } HW_DEVICE_EXTENSION, *PHW_DEVICE_EXTENSION;
1142
1143 typedef struct _ISR2_DEVICE_EXTENSION {
1144 PHW_DEVICE_EXTENSION HwDeviceExtension;
1145 ULONG DevIndex;
1146 } ISR2_DEVICE_EXTENSION, *PISR2_DEVICE_EXTENSION;
1147
1148 #define HBAFLAGS_DMA_DISABLED 0x01
1149 #define HBAFLAGS_DMA_DISABLED_LBA48 0x02
1150
1151 extern UCHAR pciBuffer[256];
1152 extern PBUSMASTER_CONTROLLER_INFORMATION BMList;
1153 extern ULONG BMListLen;
1154 extern ULONG IsaCount;
1155 extern ULONG MCACount;
1156
1157 //extern const CHAR retry_Wdma[MAX_RETRIES+1];
1158 //extern const CHAR retry_Udma[MAX_RETRIES+1];
1159
1160 extern VOID
1161 NTAPI
1162 UniataEnumBusMasterController(
1163 IN PVOID DriverObject,
1164 PVOID Argument2
1165 );
1166
1167 extern ULONG NTAPI
1168 UniataFindCompatBusMasterController1(
1169 IN PVOID HwDeviceExtension,
1170 IN PVOID Context,
1171 IN PVOID BusInformation,
1172 IN PCHAR ArgumentString,
1173 IN OUT PPORT_CONFIGURATION_INFORMATION ConfigInfo,
1174 OUT PBOOLEAN Again
1175 );
1176
1177 extern ULONG NTAPI
1178 UniataFindCompatBusMasterController2(
1179 IN PVOID HwDeviceExtension,
1180 IN PVOID Context,
1181 IN PVOID BusInformation,
1182 IN PCHAR ArgumentString,
1183 IN OUT PPORT_CONFIGURATION_INFORMATION ConfigInfo,
1184 OUT PBOOLEAN Again
1185 );
1186
1187 #define UNIATA_ALLOCATE_NEW_LUNS 0x00
1188
1189 extern BOOLEAN
1190 NTAPI
1191 UniataAllocateLunExt(
1192 PHW_DEVICE_EXTENSION deviceExtension,
1193 ULONG NewNumberChannels
1194 );
1195
1196 extern ULONG NTAPI
1197 UniataFindBusMasterController(
1198 IN PVOID HwDeviceExtension,
1199 IN PVOID Context,
1200 IN PVOID BusInformation,
1201 IN PCHAR ArgumentString,
1202 IN OUT PPORT_CONFIGURATION_INFORMATION ConfigInfo,
1203 OUT PBOOLEAN Again
1204 );
1205
1206 extern ULONG NTAPI
1207 UniataFindFakeBusMasterController(
1208 IN PVOID HwDeviceExtension,
1209 IN PVOID Context,
1210 IN PVOID BusInformation,
1211 IN PCHAR ArgumentString,
1212 IN OUT PPORT_CONFIGURATION_INFORMATION ConfigInfo,
1213 OUT PBOOLEAN Again
1214 );
1215
1216 extern NTSTATUS
1217 NTAPI
1218 UniataConnectIntr2(
1219 IN PVOID HwDeviceExtension
1220 );
1221
1222 extern NTSTATUS
1223 NTAPI
1224 UniataDisconnectIntr2(
1225 IN PVOID HwDeviceExtension
1226 );
1227
1228 extern ULONG
1229 NTAPI
1230 ScsiPortGetBusDataByOffset(
1231 IN PVOID HwDeviceExtension,
1232 IN BUS_DATA_TYPE BusDataType,
1233 IN ULONG BusNumber,
1234 IN ULONG SlotNumber,
1235 IN PVOID Buffer,
1236 IN ULONG Offset,
1237 IN ULONG Length
1238 );
1239
1240 #define PCIBUSNUM_NOT_SPECIFIED (0xffffffffL)
1241 #define PCISLOTNUM_NOT_SPECIFIED (0xffffffffL)
1242
1243 extern ULONG
1244 NTAPI
1245 AtapiFindListedDev(
1246 PBUSMASTER_CONTROLLER_INFORMATION BusMasterAdapters,
1247 ULONG lim,
1248 IN PVOID HwDeviceExtension,
1249 IN ULONG BusNumber,
1250 IN ULONG SlotNumber,
1251 OUT PCI_SLOT_NUMBER* _slotData // optional
1252 );
1253
1254 extern ULONG
1255 NTAPI
1256 AtapiFindDev(
1257 IN PVOID HwDeviceExtension,
1258 IN BUS_DATA_TYPE BusDataType,
1259 IN ULONG BusNumber,
1260 IN ULONG SlotNumber,
1261 IN ULONG dev_id,
1262 IN ULONG RevID
1263 );
1264
1265 extern VOID
1266 NTAPI
1267 AtapiDmaAlloc(
1268 IN PVOID HwDeviceExtension,
1269 IN PPORT_CONFIGURATION_INFORMATION ConfigInfo,
1270 IN ULONG lChannel // logical channel,
1271 );
1272
1273 extern BOOLEAN
1274 NTAPI
1275 AtapiDmaSetup(
1276 IN PVOID HwDeviceExtension,
1277 IN ULONG DeviceNumber,
1278 IN ULONG lChannel, // logical channel,
1279 IN PSCSI_REQUEST_BLOCK Srb,
1280 IN PUCHAR data,
1281 IN ULONG count
1282 );
1283
1284 extern BOOLEAN
1285 NTAPI
1286 AtapiDmaPioSync(
1287 PVOID HwDeviceExtension,
1288 PSCSI_REQUEST_BLOCK Srb,
1289 PUCHAR data,
1290 ULONG count
1291 );
1292
1293 extern BOOLEAN
1294 NTAPI
1295 AtapiDmaDBSync(
1296 PHW_CHANNEL chan,
1297 PSCSI_REQUEST_BLOCK Srb
1298 );
1299
1300 extern VOID
1301 NTAPI
1302 AtapiDmaStart(
1303 IN PVOID HwDeviceExtension,
1304 IN ULONG DeviceNumber,
1305 IN ULONG lChannel, // logical channel,
1306 IN PSCSI_REQUEST_BLOCK Srb
1307 );
1308
1309 extern UCHAR
1310 NTAPI
1311 AtapiDmaDone(
1312 IN PVOID HwDeviceExtension,
1313 IN ULONG DeviceNumber,
1314 IN ULONG lChannel, // logical channel,
1315 IN PSCSI_REQUEST_BLOCK Srb
1316 );
1317
1318 extern VOID
1319 NTAPI
1320 AtapiDmaReinit(
1321 IN PHW_DEVICE_EXTENSION deviceExtension,
1322 IN PHW_LU_EXTENSION LunExt,
1323 IN PATA_REQ AtaReq
1324 );
1325
1326 extern VOID
1327 NTAPI
1328 AtapiDmaInit__(
1329 IN PHW_DEVICE_EXTENSION deviceExtension,
1330 IN PHW_LU_EXTENSION LunExt
1331 );
1332
1333 extern VOID
1334 NTAPI
1335 AtapiDmaInit(
1336 IN PVOID HwDeviceExtension,
1337 IN ULONG DeviceNumber,
1338 IN ULONG lChannel, // logical channel,
1339 // is always 0 except simplex-only and multi-channel controllers
1340 IN SCHAR apiomode,
1341 IN SCHAR wdmamode,
1342 IN SCHAR udmamode
1343 );
1344
1345 extern BOOLEAN NTAPI
1346 AtapiInterrupt2(
1347 IN PKINTERRUPT Interrupt,
1348 IN PVOID HwDeviceExtension
1349 );
1350
1351 extern PDRIVER_OBJECT SavedDriverObject;
1352
1353 extern BOOLEAN
1354 NTAPI
1355 UniataChipDetectChannels(
1356 IN PVOID HwDeviceExtension,
1357 IN PPCI_COMMON_CONFIG pciData, // optional
1358 IN ULONG DeviceNumber,
1359 IN PPORT_CONFIGURATION_INFORMATION ConfigInfo
1360 );
1361
1362 extern NTSTATUS
1363 NTAPI
1364 UniataChipDetect(
1365 IN PVOID HwDeviceExtension,
1366 IN PPCI_COMMON_CONFIG pciData, // optional
1367 IN ULONG DeviceNumber,
1368 IN OUT PPORT_CONFIGURATION_INFORMATION ConfigInfo,
1369 IN BOOLEAN* simplexOnly
1370 );
1371
1372 extern BOOLEAN
1373 NTAPI
1374 AtapiChipInit(
1375 IN PVOID HwDeviceExtension,
1376 IN ULONG DeviceNumber,
1377 IN ULONG c
1378 );
1379
1380 extern ULONG
1381 NTAPI
1382 AtapiGetIoRange(
1383 IN PVOID HwDeviceExtension,
1384 IN PPORT_CONFIGURATION_INFORMATION ConfigInfo,
1385 IN PPCI_COMMON_CONFIG pciData,
1386 IN ULONG SystemIoBusNumber,
1387 IN ULONG rid,
1388 IN ULONG offset,
1389 IN ULONG length //range id
1390 );
1391
1392 /****************** 1 *****************/
1393 #define GetPciConfig1(offs, op) { \
1394 ScsiPortGetBusDataByOffset(HwDeviceExtension, \
1395 PCIConfiguration, \
1396 SystemIoBusNumber, \
1397 slotNumber, \
1398 &op, \
1399 offs, \
1400 1); \
1401 }
1402
1403 #define SetPciConfig1(offs, op) { \
1404 UCHAR _a = op; \
1405 ScsiPortSetBusDataByOffset(HwDeviceExtension, \
1406 PCIConfiguration, \
1407 SystemIoBusNumber, \
1408 slotNumber, \
1409 &_a, \
1410 offs, \
1411 1); \
1412 }
1413
1414 #define ChangePciConfig1(offs, _op) { \
1415 UCHAR a = 0; \
1416 GetPciConfig1(offs, a); \
1417 a = (UCHAR)(_op); \
1418 SetPciConfig1(offs, a); \
1419 }
1420
1421 /****************** 2 *****************/
1422 #define GetPciConfig2(offs, op) { \
1423 ScsiPortGetBusDataByOffset(HwDeviceExtension, \
1424 PCIConfiguration, \
1425 SystemIoBusNumber, \
1426 slotNumber, \
1427 &op, \
1428 offs, \
1429 2); \
1430 }
1431
1432 #define SetPciConfig2(offs, op) { \
1433 USHORT _a = op; \
1434 ScsiPortSetBusDataByOffset(HwDeviceExtension, \
1435 PCIConfiguration, \
1436 SystemIoBusNumber, \
1437 slotNumber, \
1438 &_a, \
1439 offs, \
1440 2); \
1441 }
1442
1443 #define ChangePciConfig2(offs, _op) { \
1444 USHORT a = 0; \
1445 GetPciConfig2(offs, a); \
1446 a = (USHORT)(_op); \
1447 SetPciConfig2(offs, a); \
1448 }
1449
1450 /****************** 4 *****************/
1451 #define GetPciConfig4(offs, op) { \
1452 ScsiPortGetBusDataByOffset(HwDeviceExtension, \
1453 PCIConfiguration, \
1454 SystemIoBusNumber, \
1455 slotNumber, \
1456 &op, \
1457 offs, \
1458 4); \
1459 }
1460
1461 #define SetPciConfig4(offs, op) { \
1462 ULONG _a = op; \
1463 ScsiPortSetBusDataByOffset(HwDeviceExtension, \
1464 PCIConfiguration, \
1465 SystemIoBusNumber, \
1466 slotNumber, \
1467 &_a, \
1468 offs, \
1469 4); \
1470 }
1471
1472 #define ChangePciConfig4(offs, _op) { \
1473 ULONG a = 0; \
1474 GetPciConfig4(offs, a); \
1475 a = _op; \
1476 SetPciConfig4(offs, a); \
1477 }
1478
1479 #ifndef GetDmaStatus
1480 #define GetDmaStatus(de, c) \
1481 (((de)->BusMaster) ? AtapiReadPort1(&((de)->chan[c]), IDX_BM_Status) : 0)
1482 #endif //GetDmaStatus
1483
1484 #ifdef USE_OWN_DMA
1485 #define AtapiVirtToPhysAddr(hwde, srb, phaddr, plen, phaddru) \
1486 AtapiVirtToPhysAddr_(hwde, srb, phaddr, plen, phaddru);
1487 #else
1488 #define AtapiVirtToPhysAddr(hwde, srb, phaddr, plen, phaddru) \
1489 (ScsiPortConvertPhysicalAddressToUlong/*(ULONG)ScsiPortGetVirtualAddress*/(/*hwde,*/ \
1490 ScsiPortGetPhysicalAddress(hwde, srb, phaddr, plen)))
1491 #endif //USE_OWN_DMA
1492
1493 VOID
1494 DDKFASTAPI
1495 AtapiWritePort4(
1496 IN PHW_CHANNEL chan,
1497 IN ULONGIO_PTR port,
1498 IN ULONG data
1499 );
1500
1501 VOID
1502 DDKFASTAPI
1503 AtapiWritePort2(
1504 IN PHW_CHANNEL chan,
1505 IN ULONGIO_PTR port,
1506 IN USHORT data
1507 );
1508
1509 VOID
1510 DDKFASTAPI
1511 AtapiWritePort1(
1512 IN PHW_CHANNEL chan,
1513 IN ULONGIO_PTR port,
1514 IN UCHAR data
1515 );
1516
1517 VOID
1518 DDKFASTAPI
1519 AtapiWritePortEx4(
1520 IN PHW_CHANNEL chan,
1521 IN ULONGIO_PTR port,
1522 IN ULONG offs,
1523 IN ULONG data
1524 );
1525
1526 VOID
1527 DDKFASTAPI
1528 AtapiWritePortEx1(
1529 IN PHW_CHANNEL chan,
1530 IN ULONGIO_PTR port,
1531 IN ULONG offs,
1532 IN UCHAR data
1533 );
1534
1535 ULONG
1536 DDKFASTAPI
1537 AtapiReadPort4(
1538 IN PHW_CHANNEL chan,
1539 IN ULONGIO_PTR port
1540 );
1541
1542 USHORT
1543 DDKFASTAPI
1544 AtapiReadPort2(
1545 IN PHW_CHANNEL chan,
1546 IN ULONGIO_PTR port
1547 );
1548
1549 UCHAR
1550 DDKFASTAPI
1551 AtapiReadPort1(
1552 IN PHW_CHANNEL chan,
1553 IN ULONGIO_PTR port
1554 );
1555
1556 ULONG
1557 DDKFASTAPI
1558 AtapiReadPortEx4(
1559 IN PHW_CHANNEL chan,
1560 IN ULONGIO_PTR port,
1561 IN ULONG offs
1562 );
1563
1564 UCHAR
1565 DDKFASTAPI
1566 AtapiReadPortEx1(
1567 IN PHW_CHANNEL chan,
1568 IN ULONGIO_PTR port,
1569 IN ULONG offs
1570 );
1571
1572 VOID
1573 DDKFASTAPI
1574 AtapiWriteBuffer4(
1575 IN PHW_CHANNEL chan,
1576 IN ULONGIO_PTR _port,
1577 IN PVOID Buffer,
1578 IN ULONG Count,
1579 IN ULONG Timing
1580 );
1581
1582 VOID
1583 DDKFASTAPI
1584 AtapiWriteBuffer2(
1585 IN PHW_CHANNEL chan,
1586 IN ULONGIO_PTR _port,
1587 IN PVOID Buffer,
1588 IN ULONG Count,
1589 IN ULONG Timing
1590 );
1591
1592 VOID
1593 DDKFASTAPI
1594 AtapiReadBuffer4(
1595 IN PHW_CHANNEL chan,
1596 IN ULONGIO_PTR _port,
1597 IN PVOID Buffer,
1598 IN ULONG Count,
1599 IN ULONG Timing
1600 );
1601
1602 VOID
1603 DDKFASTAPI
1604 AtapiReadBuffer2(
1605 IN PHW_CHANNEL chan,
1606 IN ULONGIO_PTR _port,
1607 IN PVOID Buffer,
1608 IN ULONG Count,
1609 IN ULONG Timing
1610 );
1611
1612 /*#define GET_CHANNEL(Srb) (Srb->TargetId >> 1)
1613 #define GET_LDEV(Srb) (Srb->TargetId)
1614 #define GET_LDEV2(P, T, L) (T)*/
1615
1616 #define GET_CHANNEL(Srb) (Srb->PathId)
1617 //#define GET_LDEV(Srb) (Srb->TargetId | (Srb->PathId << 1))
1618 //#define GET_LDEV2(P, T, L) (T | ((P)<<1))
1619 #define GET_CDEV(Srb) (Srb->TargetId)
1620
1621 VOID
1622 NTAPI
1623 AtapiSetupLunPtrs(
1624 IN PHW_CHANNEL chan,
1625 IN PHW_DEVICE_EXTENSION deviceExtension,
1626 IN ULONG c
1627 );
1628 /*
1629 #define AtapiSetupLunPtrs(chan, deviceExtension, c) \
1630 { \
1631 chan->DeviceExtension = deviceExtension; \
1632 chan->lChannel = c; \
1633 chan->lun[0] = &(deviceExtension->lun[c*2+0]); \
1634 chan->lun[1] = &(deviceExtension->lun[c*2+1]); \
1635 chan->AltRegMap = deviceExtension->AltRegMap; \
1636 chan->NextDpcChan = -1; \
1637 chan->lun[0]->DeviceExtension = deviceExtension; \
1638 chan->lun[1]->DeviceExtension = deviceExtension; \
1639 }
1640 */
1641 BOOLEAN
1642 NTAPI
1643 AtapiReadChipConfig(
1644 IN PVOID HwDeviceExtension,
1645 IN ULONG DeviceNumber,
1646 IN ULONG channel // physical channel
1647 );
1648
1649 VOID
1650 NTAPI
1651 UniataForgetDevice(
1652 PHW_LU_EXTENSION LunExt
1653 );
1654
1655 extern ULONG SkipRaids;
1656 extern ULONG ForceSimplex;
1657 extern BOOLEAN g_opt_AtapiDmaRawRead;
1658
1659 extern BOOLEAN InDriverEntry;
1660
1661 extern BOOLEAN g_opt_Verbose;
1662 extern ULONG g_opt_VirtualMachine;
1663
1664 #define VM_AUTO 0x00
1665 #define VM_NONE 0x01
1666 #define VM_VBOX 0x02
1667 #define VM_VMWARE 0x03
1668 #define VM_QEMU 0x04
1669
1670 #define VM_MAX_KNOWN VM_QEMU
1671
1672 extern BOOLEAN WinVer_WDM_Model;
1673
1674 #endif //__IDE_BUSMASTER_H__