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