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