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