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