ReactOS 0.4.15-dev-7842-g558ab78
id_ata.cpp
Go to the documentation of this file.
1/*++
2
3Copyright (c) 2002-2018 Alexandr A. Telyatnikov (Alter)
4
5Module Name:
6 id_ata.cpp
7
8Abstract:
9 This is the miniport driver for ATA/ATAPI IDE/SATA/AHCI controllers
10 with Busmaster DMA and Serial ATA support
11
12Author:
13 Alexander A. Telyatnikov (Alter)
14
15Environment:
16 kernel mode only
17
18Notes:
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
31Revision History:
32
33 The skeleton was taken from standard ATAPI.SYS from NT4 DDK by
34 Mike Glass (MGlass)
35 Chuck Park (ChuckP)
36
37 Some parts of code were taken from FreeBSD 4.3-6.1 ATA driver by
38 Søren Schmidt, Copyright (c) 1998-2007
39
40 All parts of code are significantly changed/updated by
41 Alter, Copyright (c) 2002-2014:
42
43 1. Internal command queueing/reordering
44 2. Drive identification
45 3. Support for 2 _independent_ channels in a single PCI device
46 4. Smart host<->drive transfer rate slowdown (for bad cable)
47 5. W2k support (binary compatibility)
48 6. HDD hot swap under NT4
49 7. XP support (binary compatibility)
50 8. Serial ATA (SATA/SATA2/SATA3) support
51 9. NT 3.51 support (binary compatibility)
52 10. AHCI support
53
54 etc. (See todo.txt)
55
56Licence:
57 GPLv2
58
59--*/
60
61#include "stdafx.h"
62
63#ifndef UNIATA_CORE
64
65static const CHAR ver_string[] = "\n\nATAPI IDE MiniPort Driver (UniATA) v 0." UNIATA_VER_STR "\n";
66
68
71
72#endif //UNIATA_CORE
73
74//UCHAR AtaCommands48[256];
75//UCHAR AtaCommandFlags[256];
76
79
82
83#ifdef _DEBUG
85#endif //_DEBUG
86
88
96
98
104
106
109
111
114
115//UCHAR EnableDma = FALSE;
116//UCHAR EnableReorder = FALSE;
117
119
121NTAPI
123 IN PVOID HwDeviceExtension,
125 IN UCHAR CompleteType
126 );
127
128VOID
129NTAPI
131 IN PHW_DEVICE_EXTENSION deviceExtension,
132 IN ULONG lChannel
133 );
134
135VOID
136NTAPI
138 PHW_DEVICE_EXTENSION deviceExtension,
139 PHW_LU_EXTENSION LunExt,
140 ULONG lChannel
141 );
142
143#define RESET_COMPLETE_CURRENT 0x00
144#define RESET_COMPLETE_ALL 0x01
145#define RESET_COMPLETE_NONE 0x02
146
147#ifndef UNIATA_CORE
148
149VOID
150NTAPI
152 IN PVOID HwDeviceExtension
153 );
154
155#ifdef UNIATA_USE_XXableInterrupts
156 #define RETTYPE_XXableInterrupts BOOLEAN
157 #define RETVAL_XXableInterrupts TRUE
158#else
159 #define RETTYPE_XXableInterrupts VOID
160 #define RETVAL_XXableInterrupts
161#endif
162
164NTAPI
166 IN PVOID HwDeviceExtension
167 );
168
170NTAPI
172 IN PVOID HwDeviceExtension
173 );
174
175VOID
176NTAPI
178 IN PVOID HwDeviceExtension,
179 IN ULONG lChannel,
180 IN PHW_TIMER HwScsiTimer,
181 IN ULONG MiniportTimerValue
182 );
183
185NTAPI
187 IN PVOID HwDeviceExtension,
188 IN SCSI_ADAPTER_CONTROL_TYPE ControlType,
190 );
191
192#endif //UNIATA_CORE
193
194#ifndef UNIATA_CORE
195
197NTAPI
200 IN PWSTR Name,
201 IN PWCHAR Str,
202 IN ULONG MaxLen
203 )
204{
205#define ITEMS_TO_QUERY 2 // always 1 greater than what is searched
208 UNICODE_STRING ustr;
209
210 ustr.Buffer = Str;
211 ustr.Length =
212 ustr.MaximumLength = (USHORT)MaxLen;
214
215 parameters[0].Flags = RTL_QUERY_REGISTRY_DIRECT;
216 parameters[0].Name = Name;
217 parameters[0].EntryContext = &ustr;
218 parameters[0].DefaultType = REG_SZ;
219 parameters[0].DefaultData = Str;
220 parameters[0].DefaultLength = MaxLen;
221
222 status = RtlQueryRegistryValues(RTL_REGISTRY_ABSOLUTE /*| RTL_REGISTRY_OPTIONAL*/,
223 RegistryPath, parameters, NULL, NULL);
224
225 if(!NT_SUCCESS(status))
226 return FALSE;
227
228 return TRUE;
229
230#undef ITEMS_TO_QUERY
231} // end AtapiRegGetStringParameterValue()
232
233
234#endif //UNIATA_CORE
235
236VOID
239 ULONG nano
240 )
241{
242 LONGLONG t;
243 LARGE_INTEGER t0;
244
245#ifdef NAVO_TEST
246 return;
247#endif //NAVO_TEST
248
249 if(!nano || !g_Perf || !g_PerfDt)
250 return;
251 t = (g_Perf * nano) / g_PerfDt / 1000;
252 if(!t) {
253 t = 1;
254 }
255 do {
257 t--;
258 } while(t);
259} // end UniataNanoSleep()
260
261#define AtapiWritePortN_template(_type, _Type, sz) \
262VOID \
263DDKFASTAPI \
264AtapiWritePort##sz( \
265 IN PHW_CHANNEL chan, \
266 IN ULONGIO_PTR _port, \
267 IN _type data \
268 ) \
269{ \
270 PIORES res; \
271 if(_port >= IDX_MAX_REG) { \
272 res = (PIORES)(_port); \
273 } else \
274 if(chan) { \
275 res = &chan->RegTranslation[_port]; \
276 } else { \
277 KdPrint(("invalid io write request @ ch %x, res* %x\n", chan, _port)); \
278 return; \
279 } \
280 if(res->Proc) { \
281 KdPrint(("PROC io write request @ ch %x, res* %x\n", chan, _port)); \
282 ASSERT(FALSE); /* We should never get here */ \
283 } \
284 if(!res->MemIo) { \
285 ScsiPortWritePort##_Type((_type*)(ULONGIO_PTR)(res->Addr), data); \
286 } else { \
287 /*KdPrint(("r_mem @ (%x) %x\n", _port, port));*/ \
288 ScsiPortWriteRegister##_Type((_type*)(ULONG_PTR)(res->Addr), data); \
289 } \
290 return; \
291}
292
296
297#define AtapiWritePortExN_template(_type, _Type, sz) \
298VOID \
299DDKFASTAPI \
300AtapiWritePortEx##sz( \
301 IN PHW_CHANNEL chan, \
302 IN ULONGIO_PTR _port, \
303 IN ULONG offs, \
304 IN _type data \
305 ) \
306{ \
307 PIORES res; \
308 if(_port >= IDX_MAX_REG) { \
309 res = (PIORES)(_port); \
310 } else \
311 if(chan) { \
312 res = &chan->RegTranslation[_port]; \
313 } else { \
314 KdPrint(("invalid io write request @ ch %x, res* %x, offs %x\n", chan, _port, offs)); \
315 return; \
316 } \
317 if(res->Proc) { \
318 KdPrint(("PROC io write request @ ch %x, res* %x, offs %x\n", chan, _port, offs)); \
319 ASSERT(FALSE); /* We should never get here */ \
320 } \
321 if(!res->MemIo) { \
322 ScsiPortWritePort##_Type((_type*)(ULONGIO_PTR)(res->Addr+offs), data); \
323 } else { \
324 /*KdPrint(("r_mem @ (%x) %x\n", _port, port));*/ \
325 ScsiPortWriteRegister##_Type((_type*)(ULONG_PTR)(res->Addr+offs), data); \
326 } \
327 return; \
328}
329
331//AtapiWritePortExN_template(USHORT, Ushort, 2);
333
334#define AtapiReadPortN_template(_type, _Type, sz) \
335_type \
336DDKFASTAPI \
337AtapiReadPort##sz( \
338 IN PHW_CHANNEL chan, \
339 IN ULONGIO_PTR _port \
340 ) \
341{ \
342 PIORES res; \
343 if(_port >= IDX_MAX_REG) { \
344 res = (PIORES)(_port); \
345 } else \
346 if(chan) { \
347 res = &chan->RegTranslation[_port]; \
348 } else { \
349 KdPrint(("invalid io read request @ ch %x, res* %x\n", chan, _port)); \
350 return (_type)(-1); \
351 } \
352 if(res->Proc) { \
353 KdPrint(("PROC io read request @ ch %x, res* %x\n", chan, _port)); \
354 ASSERT(FALSE); /* We should never get here */ \
355 } \
356 if(!res->MemIo) { \
357 /*KdPrint(("r_io @ (%x) %x\n", _port, res->Addr));*/ \
358 return ScsiPortReadPort##_Type((_type*)(ULONGIO_PTR)(res->Addr)); \
359 } else { \
360 /*KdPrint(("r_mem @ (%x) %x\n", _port, res->Addr));*/ \
361 return ScsiPortReadRegister##_Type((_type*)(ULONG_PTR)(res->Addr)); \
362 } \
363}
364
368
369#define AtapiReadPortExN_template(_type, _Type, sz) \
370_type \
371DDKFASTAPI \
372AtapiReadPortEx##sz( \
373 IN PHW_CHANNEL chan, \
374 IN ULONGIO_PTR _port, \
375 IN ULONG offs \
376 ) \
377{ \
378 PIORES res; \
379 if(_port >= IDX_MAX_REG) { \
380 res = (PIORES)(_port); \
381 } else \
382 if(chan) { \
383 res = &chan->RegTranslation[_port]; \
384 } else { \
385 KdPrint(("invalid io read request @ ch %x, res* %x, offs %x\n", chan, _port, offs)); \
386 return (_type)(-1); \
387 } \
388 if(res->Proc) { \
389 KdPrint(("PROC io read request @ ch %x, res* %x, offs %x\n", chan, _port, offs)); \
390 ASSERT(FALSE); /* We should never get here */ \
391 } \
392 if(!res->MemIo) { \
393 return ScsiPortReadPort##_Type((_type*)(ULONGIO_PTR)(res->Addr+offs)); \
394 } else { \
395 /*KdPrint(("r_mem @ (%x) %x\n", _port, port));*/ \
396 return ScsiPortReadRegister##_Type((_type*)(ULONG_PTR)(res->Addr+offs)); \
397 } \
398}
399
401//AtapiReadPortExN_template(USHORT, Ushort, 2);
403
404#define AtapiReadPortBufferN_template(_type, _Type, sz) \
405VOID \
406DDKFASTAPI \
407AtapiReadBuffer##sz( \
408 IN PHW_CHANNEL chan, \
409 IN ULONGIO_PTR _port, \
410 IN PVOID Buffer, \
411 IN ULONG Count, \
412 IN ULONG Timing \
413 ) \
414{ \
415 PIORES res; \
416 \
417 if(Timing) { \
418 while(Count) { \
419 (*((_type*)Buffer)) = AtapiReadPort##sz(chan, _port); \
420 Count--; \
421 Buffer = ((_type*)Buffer)+1; \
422 UniataNanoSleep(Timing); \
423 } \
424 return; \
425 } \
426 \
427 if(_port >= IDX_MAX_REG) { \
428 res = (PIORES)(_port); \
429 } else \
430 if(chan) { \
431 res = &chan->RegTranslation[_port]; \
432 } else { \
433 KdPrint(("invalid io read request @ ch %x, res* %x\n", chan, _port)); \
434 return; \
435 } \
436 if(!res->MemIo) { \
437 /*KdPrint(("r_io @ (%x) %x\n", _port, res->Addr));*/ \
438 ScsiPortReadPortBuffer##_Type((_type*)(ULONGIO_PTR)(res->Addr), (_type*)Buffer, Count); \
439 return; \
440 } \
441 while(Count) { \
442 (*((_type*)Buffer)) = ScsiPortReadRegister##_Type((_type*)(ULONG_PTR)(res->Addr)); \
443 Count--; \
444 Buffer = ((_type*)Buffer)+1; \
445 } \
446 return; \
447}
448
449#define AtapiWritePortBufferN_template(_type, _Type, sz) \
450VOID \
451DDKFASTAPI \
452AtapiWriteBuffer##sz( \
453 IN PHW_CHANNEL chan, \
454 IN ULONGIO_PTR _port, \
455 IN PVOID Buffer, \
456 IN ULONG Count, \
457 IN ULONG Timing \
458 ) \
459{ \
460 PIORES res; \
461 \
462 if(Timing) { \
463 while(Count) { \
464 AtapiWritePort##sz(chan, _port, *((_type*)Buffer)); \
465 Buffer = ((_type*)Buffer)+1; \
466 Count--; \
467 UniataNanoSleep(Timing); \
468 } \
469 return; \
470 } \
471 \
472 if(_port >= IDX_MAX_REG) { \
473 res = (PIORES)(_port); \
474 } else \
475 if(chan) { \
476 res = &chan->RegTranslation[_port]; \
477 } else { \
478 KdPrint(("invalid io write request @ ch %x, res* %x\n", chan, _port)); \
479 return; \
480 } \
481 if(!res->MemIo) { \
482 /*KdPrint(("r_io @ (%x) %x\n", _port, res->Addr));*/ \
483 ScsiPortWritePortBuffer##_Type((_type*)(ULONGIO_PTR)(res->Addr), (_type*)Buffer, Count); \
484 return; \
485 } \
486 while(Count) { \
487 ScsiPortWriteRegister##_Type((_type*)(ULONG_PTR)(res->Addr), *((_type*)Buffer)); \
488 Count--; \
489 Buffer = ((_type*)Buffer)+1; \
490 } \
491 return; \
492}
493
496
499
500
501UCHAR
504 IN PHW_CHANNEL chan
505 )
506{
507 UCHAR statusByte;
508 ULONG i;
509
510 // Assume, proper drive is already seleted
511 WaitOnBusyLong(chan);
512 for (i = 0; i < 0x10000; i++) {
513
514 GetStatus(chan, statusByte);
515 if (statusByte & IDE_STATUS_DRQ) {
516 // Suck out any remaining bytes and throw away.
519 } else {
520 break;
521 }
522 }
523 if(i) {
524 KdPrint2((PRINT_PREFIX "AtapiSuckPort2: overrun detected (%#x words)\n", i ));
525 }
526 return statusByte;
527} // AtapiSuckPort2()
528
529ULONG
532 IN PHW_CHANNEL chan,
535 )
536{
537 UCHAR statusByte;
538 ULONG i;
539 USHORT data;
540 BOOLEAN retry = FALSE;
541
542 // Assume, proper drive is already seleted
543 WaitOnBusyLong(chan);
544 for (i = 0; i < Count; i++) {
545
546 GetStatus(chan, statusByte);
547 if (statusByte & IDE_STATUS_DRQ) {
548 // Suck out any remaining bytes and throw away.
550 (*Buffer) = data;
551 Count--;
552 Buffer++;
554 retry = FALSE;
555 } else {
556 if(i<Count && !retry) {
557 KdPrint2((PRINT_PREFIX " wait...\n"));
558 WaitForDrq(chan);
559 retry = TRUE;
560 }
561 break;
562 }
563 }
564 if(i) {
565 KdPrint2((PRINT_PREFIX "AtapiSuckPortBuffer2: %#x words\n", i ));
566 if(i==Count) {
567 AtapiSuckPort2(chan);
568 }
569 }
570 return i;
571} // AtapiSuckPortBuffer2()
572
573#ifdef __REACTOS__
574VOID
576FillDeviceIdentificationString(
577 IN OUT PINQUIRYDATA InquiryData,
578 IN PIDENTIFY_DATA2 IdentifyData)
579{
580 ULONG i;
581 ULONG IdentifierLen, FirstWordLen;
582
583 /* We need to copy a field which is 20 chars long to two fields which are 8+16 bytes long (VendorId + ProductId)
584 * Note that a space will be added between those fields when displaying them.
585 * => Try to split identifier on space char.
586 */
587
588#define IDENTIFIER_LETTER(Identifier, i) (((PUCHAR)Identifier)[(i) ^ 1])
589
590 for (IdentifierLen = 20; IdentifierLen > 0 && IDENTIFIER_LETTER(IdentifyData->ModelNumber, IdentifierLen - 1) == ' '; IdentifierLen--)
591 ;
592
593 /* Strategy 1: copy first word to VendorId if len <= 8. Copy other chars to ProductId */
594 for (FirstWordLen = 0; IDENTIFIER_LETTER(IdentifyData->ModelNumber, FirstWordLen) != ' ' && FirstWordLen < IdentifierLen; FirstWordLen++)
595 ;
596 if (FirstWordLen <= 8)
597 {
598 for (i = 0; i < FirstWordLen; i++)
599 InquiryData->VendorId[i] = IDENTIFIER_LETTER(IdentifyData->ModelNumber, i);
600 for (i = FirstWordLen + 1; i < IdentifierLen; i++)
601 InquiryData->ProductId[i - FirstWordLen - 1] = IDENTIFIER_LETTER(IdentifyData->ModelNumber, i);
602 return;
603 }
604
605 /* Strategy 2: copy everything to ProductId */
606 if (IdentifierLen <= 16)
607 {
608 for (i = 0; i < IdentifierLen; i++)
609 InquiryData->ProductId[i] = IDENTIFIER_LETTER(IdentifyData->ModelNumber, i);
610 return;
611 }
612
613 /* Strategy 3: copy first to VendorId, then to ProductId */
614 for (i = 0; i < 24; i += 2)
615 MOV_DW_SWP(InquiryData->DeviceIdentificationString[i], ((PUCHAR)IdentifyData->ModelNumber)[i]);
616}
617#endif
618
619UCHAR
622 IN PHW_CHANNEL chan,
624 )
625{
626 if(!chan) {
627 return 0;
628 }
629/*
630 if(chan->lun[DeviceNumber] &&
631 (chan->lun[DeviceNumber]->DeviceFlags & DFLAGS_ATAPI_CHANGER)) {
632 KdPrint3((" Select %d\n", DeviceNumber));
633 }
634*/
635 if(chan->last_devsel == DeviceNumber) {
636 //KdPrint3((" Selected %d\n", DeviceNumber));
637 return 1;
638 }
640 chan->last_devsel = DeviceNumber ? 1 : 0;
642 //KdPrint3((" Select %d\n", DeviceNumber));
643 return 2;
644 }
645 //KdPrint3((" Select %d (%d ns)\n", DeviceNumber, g_opt_DriveSelectNanoDelay));
647 return 2;
648} // end SelectDrive()
649
650UCHAR
653 IN PHW_CHANNEL chan
654 )
655{
656 ULONG i;
658
659 GetStatus(chan, Status);
660 for (i=0; i<g_opt_WaitBusyCount; i++) {
661 if (Status & IDE_STATUS_BUSY) {
663 GetStatus(chan, Status);
664 continue;
665 } else {
666 break;
667 }
668 }
669 return Status;
670} // end WaitOnBusy()
671
672UCHAR
675 IN PHW_CHANNEL chan
676 )
677{
678 ULONG i;
680
681 Status = WaitOnBusy(chan);
682 if(!(Status & IDE_STATUS_BUSY))
683 return Status;
684 for (i=0; i<g_opt_WaitBusyLongCount; i++) {
685 GetStatus(chan, Status);
686 if (Status & IDE_STATUS_BUSY) {
688 continue;
689 } else {
690 break;
691 }
692 }
693 return Status;
694} // end WaitOnBusyLong()
695
696UCHAR
699 IN PHW_CHANNEL chan
700 )
701{
702 ULONG i;
704 for (i=0; i<g_opt_WaitBusyCount; i++) {
705 GetBaseStatus(chan, Status);
706 if (Status & IDE_STATUS_BUSY) {
708 continue;
709 } else {
710 break;
711 }
712 }
713 return Status;
714} // end WaitOnBaseBusy()
715
716UCHAR
719 IN PHW_CHANNEL chan
720 )
721{
722 ULONG i;
724
725 Status = WaitOnBaseBusy(chan);
726 if(!(Status & IDE_STATUS_BUSY))
727 return Status;
728 for (i=0; i<2000; i++) {
729 GetBaseStatus(chan, Status);
730 if (Status & IDE_STATUS_BUSY) {
732 continue;
733 } else {
734 break;
735 }
736 }
737 return Status;
738} // end WaitOnBaseBusyLong()
739
740UCHAR
743 IN struct _HW_DEVICE_EXTENSION* deviceExtension,
745 )
746{
747 UCHAR Status2;
748
749 if(Status == IDE_STATUS_WRONG) {
750 return IDE_STATUS_WRONG;
751 }
752 if(Status & IDE_STATUS_BUSY) {
753 return Status;
754 }
755// if(deviceExtension->HwFlags & UNIATA_SATA) {
756 if(UniataIsSATARangeAvailable(deviceExtension, 0)) {
758 return Status;
759 }
760 } else {
762 if ((Status & IDE_STATUS_BUSY) ||
763 (Status2 != IDE_STATUS_IDLE && Status2 != IDE_STATUS_DRDY)) {
764 return Status;
765 }
766 }
767 return IDE_STATUS_IDLE;
768} // end UniataIsIdle()
769
770UCHAR
773 IN PHW_CHANNEL chan
774 )
775{
776 ULONG i;
778 UCHAR Status2;
779 for (i=0; i<20000; i++) {
780 GetStatus(chan, Status);
781 Status2 = UniataIsIdle(chan->DeviceExtension, Status);
782 if(Status2 == IDE_STATUS_WRONG) {
783 // no drive ?
784 break;
785 } else
786 if(Status2 & IDE_STATUS_BUSY) {
788 continue;
789 } else {
790 break;
791 }
792 }
793 return Status;
794} // end WaitForIdleLong()
795
796UCHAR
799 IN PHW_CHANNEL chan
800 )
801{
802 ULONG i;
804 for (i=0; i<1000; i++) {
805 GetStatus(chan, Status);
806 if (Status & IDE_STATUS_BUSY) {
808 } else if (Status & IDE_STATUS_DRQ) {
809 break;
810 } else {
812 }
813 }
814 return Status;
815} // end WaitForDrq()
816
817UCHAR
820 IN PHW_CHANNEL chan
821 )
822{
823 ULONG i;
825 for (i=0; i<2; i++) {
826 GetStatus(chan, Status);
827 if (Status & IDE_STATUS_BUSY) {
829 } else if (Status & IDE_STATUS_DRQ) {
830 break;
831 } else {
833 }
834 }
835 return Status;
836} // end WaitShortForDrq()
837
838VOID
841 IN PHW_CHANNEL chan,
843 )
844{
845 //ULONG c = chan->lChannel;
846 ULONG i = 30 * 1000;
847 UCHAR dma_status = 0;
848 KdPrint2((PRINT_PREFIX "AtapiSoftReset:\n"));
849 UCHAR statusByte0, statusByte2;
850
851 if(chan->DeviceExtension->HwFlags & UNIATA_AHCI) {
852 UniataAhciSoftReset(chan->DeviceExtension, chan->lChannel, DeviceNumber);
853 return;
854 }
855
856 GetBaseStatus(chan, statusByte2);
857 KdPrint2((PRINT_PREFIX " statusByte2 %x:\n", statusByte2));
859 if(chan->lun[DeviceNumber]->DeviceFlags & DFLAGS_MANUAL_CHS) {
860 // For ESDI/MFM
861 KdPrint2((PRINT_PREFIX " ESDI/MFM\n"));
862 AtapiStallExecution(10000);
863 for (i = 0; i < 1000; i++) {
865 }
866/* } else
867 // Seems to be unnecessary, verified by KtP
868 if(!hasPCI) {
869 // original atapi.sys behavior for old ISA-only hardware
870 AtapiStallExecution(10000);
871 AtapiWritePort1(chan, IDX_IO1_o_Command, IDE_COMMAND_ATAPI_RESET);
872 for (i = 0; i < 1000; i++) {
873 AtapiStallExecution(999);
874 } */
875 } else {
877 GetBaseStatus(chan, statusByte2);
878 statusByte0 = statusByte2;
880
881 // Do not wait for BUSY assertion if it was initially set, jump to
882 // BUSY release wait loop
883 if(!(statusByte0 & IDE_STATUS_BUSY)) {
884 // Wait for BUSY assertion, in some cases delay may occure
885 // 100ms should be enough
887 i = 100;
888 } else {
889 i = 10*1000;
890 }
891 statusByte2 = AtapiReadPort1(chan, IDX_IO1_i_Status);
892 while (!(statusByte2 & IDE_STATUS_BUSY) &&
893 i--)
894 {
895 if(!(statusByte0 & IDE_STATUS_ERROR) && (statusByte2 & IDE_STATUS_ERROR)) {
896 KdPrint2((PRINT_PREFIX " Command aborted, statusByte2 %x:\n", statusByte2));
897 break;
898 }
900 }
901 }
902
903 i = 30 * 1000;
904 // ReactOS modification: Already stop looping when we know that the drive has finished resetting.
905 // Not all controllers clear the IDE_STATUS_BUSY flag (e.g. not the VMware one), so ensure that
906 // the maximum waiting time (30 * i = 0.9 seconds) does not exceed the one of the original
907 // implementation. (which is around 1 second)
909 i--)
910 {
912 }
913 KdPrint2((PRINT_PREFIX " set DFLAGS_REINIT_DMA\n"));
914 chan->lun[DeviceNumber]->DeviceFlags |= DFLAGS_REINIT_DMA;
915 }
916
917 chan->last_devsel = -1; // make sure proper drive would be selected
919 WaitOnBusy(chan);
920 GetBaseStatus(chan, statusByte2);
922
923 GetBaseStatus(chan, statusByte2);
924 if(chan && chan->DeviceExtension) {
925 dma_status = GetDmaStatus(chan->DeviceExtension, chan->lChannel);
926 KdPrint2((PRINT_PREFIX " DMA status %#x\n", dma_status));
927 } else {
928 KdPrint2((PRINT_PREFIX " can't get DMA status\n"));
929 }
930 if(dma_status & BM_STATUS_INTR) {
931 // bullshit, we have DMA interrupt, but had never initiate DMA operation
932 KdPrint2((PRINT_PREFIX " clear unexpected DMA intr on ATAPI reset\n"));
933 AtapiDmaDone(chan->DeviceExtension, DeviceNumber, chan->lChannel, NULL);
934 GetBaseStatus(chan, statusByte2);
935 }
936 if(chan->DeviceExtension->HwFlags & UNIATA_SATA) {
937 UniataSataClearErr(chan->DeviceExtension, chan->lChannel, UNIATA_SATA_IGNORE_CONNECT, DeviceNumber);
938/* if(!(chan->ChannelCtrlFlags & CTRFLAGS_NO_SLAVE)) {
939 UniataSataClearErr(chan->DeviceExtension, chan->lChannel, UNIATA_SATA_IGNORE_CONNECT, 1);
940 }*/
941 }
942 return;
943
944} // end AtapiSoftReset()
945
946VOID
949 IN struct _HW_CHANNEL* chan,
950 IN BOOLEAN DisableInterrupts,
951 IN ULONG Delay
952 )
953{
954 KdPrint2((PRINT_PREFIX "AtapiHardReset: %d, dis=%d\n", Delay, DisableInterrupts));
956 (DisableInterrupts ? IDE_DC_DISABLE_INTERRUPTS : 0));
957 chan->last_devsel = -1;
958 AtapiStallExecution(Delay);
960} // end AtapiHardReset()
961
962/*
963 Send command to device.
964 Translate to 48-Lba form if required
965*/
966UCHAR
967NTAPI
969 IN PHW_DEVICE_EXTENSION deviceExtension,
971 IN ULONG lChannel,
976 IN ULONG wait_flags
977 )
978{
979 PHW_CHANNEL chan = &(deviceExtension->chan[lChannel]);
980 UCHAR statusByte;
981 ULONG i;
982 PUCHAR plba;
983
984 KdPrint2((PRINT_PREFIX "AtaCommand48: cntrlr %#x:%#x dev %#x, cmd %#x, lba %#I64x count %#x feature %#x\n",
985 deviceExtension->DevIndex, deviceExtension->Channel, DeviceNumber, command, lba, count, feature ));
986
987 if(deviceExtension->HwFlags & UNIATA_AHCI) {
988 //PIDE_AHCI_CMD AHCI_CMD = &(chan->AhciCtlBlock->cmd);
989
990 KdPrint3((" (ahci)\n"));
991
992 statusByte = UniataAhciSendPIOCommand(deviceExtension, lChannel, DeviceNumber,
994 NULL,
995 0,
996 command,
997 lba, count,
998 feature,
999 0 /* ahci flags */ ,
1000 wait_flags,
1001 1000 /* timeout 1 sec */
1002 );
1003
1004 return statusByte;
1005 }
1006
1008
1009 statusByte = WaitOnBusy(chan);
1010
1011 /* ready to issue command ? */
1012 if (statusByte & IDE_STATUS_BUSY) {
1013 KdPrint2((PRINT_PREFIX " Returning BUSY status\n"));
1014 return statusByte;
1015 }
1016 // !!! We should not check ERROR condition here
1017 // ERROR bit may be asserted durring previous operation
1018 // and not cleared after SELECT
1019
1020 //>>>>>> NV: 2006/08/03
1023 KdPrint3((PRINT_PREFIX ": artificial bad block, lba %#I64x count %#x\n", lba, count));
1024 return IDE_STATUS_ERROR;
1025 //return SRB_STATUS_ERROR;
1026 }
1027 //<<<<<< NV: 2006/08/03
1028
1029 /* only use 48bit addressing if needed because of the overhead */
1031 chan->lun[DeviceNumber]->IdentifyData.FeaturesSupport.Address48)) {
1032
1033 KdPrint2((PRINT_PREFIX " dev %#x USE_LBA_48\n", DeviceNumber ));
1034 /* translate command into 48bit version */
1037 } else {
1038 KdPrint2((PRINT_PREFIX " unhandled LBA48 command\n"));
1039 return (UCHAR)-1;
1040 }
1041
1043 plba = (PUCHAR)&lba;
1044
1049 AtapiWritePort1(chan, IDX_IO1_o_BlockNumber, (UCHAR)(plba[3]));
1050 AtapiWritePort1(chan, IDX_IO1_o_BlockNumber, (UCHAR)(plba[0]));
1051 AtapiWritePort1(chan, IDX_IO1_o_CylinderLow, (UCHAR)(plba[4]));
1052 AtapiWritePort1(chan, IDX_IO1_o_CylinderLow, (UCHAR)(plba[1]));
1053 AtapiWritePort1(chan, IDX_IO1_o_CylinderHigh, (UCHAR)(plba[5]));
1054 AtapiWritePort1(chan, IDX_IO1_o_CylinderHigh, (UCHAR)(plba[2]));
1055
1056 //KdPrint2((PRINT_PREFIX "AtaCommand48: dev %#x USE_LBA48 (2)\n", DeviceNumber ));
1058 } else {
1059
1060 plba = (PUCHAR)&lba; //ktp
1061 chan->ChannelCtrlFlags &= ~CTRFLAGS_LBA48;
1062
1063 //if(feature ||
1064 // (chan->lun[DeviceNumber]->DeviceFlags & (DFLAGS_ATAPI_DEVICE | DFLAGS_TAPE_DEVICE | DFLAGS_LBA_ENABLED))) {
1066 //}
1071 if(chan->lun[DeviceNumber]->DeviceFlags & DFLAGS_LBA_ENABLED) {
1072 //KdPrint2((PRINT_PREFIX "AtaCommand28: dev %#x USE_LBA\n", DeviceNumber ));
1074 } else {
1075 //KdPrint2((PRINT_PREFIX "AtaCommand28: dev %#x USE_CHS\n", DeviceNumber ));
1077 }
1078 }
1079
1080 // write command code to device
1082
1083 switch (wait_flags) {
1084 case ATA_WAIT_INTR:
1085
1086 // caller requested wait for interrupt
1087 for(i=0;i<4;i++) {
1088 WaitOnBusy(chan);
1089 statusByte = WaitForDrq(chan);
1090 if (statusByte & IDE_STATUS_DRQ)
1091 break;
1093 KdPrint2((PRINT_PREFIX " retry waiting DRQ, status %#x\n", statusByte));
1094 }
1095
1096 return statusByte;
1097
1098 case ATA_WAIT_IDLE:
1099
1100 // caller requested wait for entering Wait state
1101 for (i=0; i<30 * 1000; i++) {
1102
1103 GetStatus(chan, statusByte);
1104 statusByte = UniataIsIdle(deviceExtension, statusByte);
1105 if(statusByte == IDE_STATUS_WRONG) {
1106 // no drive ?
1107 break;
1108 } else
1109 if(statusByte & IDE_STATUS_ERROR) {
1110 break;
1111 } else
1112 if(statusByte & IDE_STATUS_BUSY) {
1114 continue;
1115 } else
1116 if((statusByte & ~IDE_STATUS_INDEX) == IDE_STATUS_IDLE) {
1117 break;
1118 } else {
1119 //if(deviceExtension->HwFlags & UNIATA_SATA) {
1120 if(UniataIsSATARangeAvailable(deviceExtension, lChannel)) {
1121 break;
1122 }
1124 }
1125 }
1126 //statusByte |= IDE_STATUS_BUSY;
1127 break;
1128
1129 case ATA_WAIT_READY:
1130 statusByte = WaitOnBusyLong(chan);
1131 break;
1133 statusByte = WaitOnBaseBusyLong(chan);
1134 break;
1135 case ATA_IMMEDIATE:
1136 GetStatus(chan, statusByte);
1137 if (statusByte & IDE_STATUS_ERROR) {
1138 KdPrint2((PRINT_PREFIX " Warning: Immed Status %#x :(\n", statusByte));
1139 if(statusByte == (IDE_STATUS_IDLE | IDE_STATUS_ERROR)) {
1140 break;
1141 }
1142 KdPrint2((PRINT_PREFIX " try to continue\n"));
1143 statusByte &= ~IDE_STATUS_ERROR;
1144
1145 } else {
1146 //KdPrint2((PRINT_PREFIX " send Status %#x\n", statusByte));
1147 }
1149 // !!!!!
1152
1153 statusByte = IDE_STATUS_SUCCESS;
1154 break;
1155 }
1156
1157 //KdPrint2((PRINT_PREFIX " Status %#x\n", statusByte));
1158
1159 return statusByte;
1160} // end AtaCommand48()
1161
1162/*
1163 Send command to device.
1164 This is simply wrapper for AtaCommand48()
1165*/
1166UCHAR
1167NTAPI
1169 IN PHW_DEVICE_EXTENSION deviceExtension,
1171 IN ULONG lChannel,
1174 IN UCHAR head,
1175 IN UCHAR sector,
1176 IN UCHAR count,
1178 IN ULONG wait_flags
1179 )
1180{
1181 if(!(deviceExtension->HwFlags & UNIATA_AHCI)) {
1182 return AtaCommand48(deviceExtension, DeviceNumber, lChannel,
1183 command,
1184 (ULONG)sector | ((ULONG)cylinder << 8) | ((ULONG)(head & 0x0f) << 24),
1185 count, feature, wait_flags);
1186 } else {
1187 return UniataAhciSendPIOCommand(deviceExtension, lChannel, DeviceNumber,
1189 NULL,
1190 0,
1191 command,
1192 (ULONG)sector | ((ULONG)cylinder << 8) | ((ULONG)(head & 0x0f) << 24),
1193 count,
1194 feature,
1195 0 /* ahci flags */ ,
1196 wait_flags,
1197 1000 /* timeout 1 sec */
1198 );
1199
1200 }
1201} // end AtaCommand()
1202
1203LONG
1204NTAPI
1206{
1207 switch (pio) {
1208 default: return ATA_PIO;
1209 case 0: return ATA_PIO0;
1210 case 1: return ATA_PIO1;
1211 case 2: return ATA_PIO2;
1212 case 3: return ATA_PIO3;
1213 case 4: return ATA_PIO4;
1214 case 5: return ATA_PIO5;
1215 }
1216} // end AtaPio2Mode()
1217
1218LONG
1219NTAPI
1221{
1222 if (ident->PioTimingsValid) {
1223 if (ident->AdvancedPIOModes & AdvancedPIOModes_5)
1224 return 5;
1225 if (ident->AdvancedPIOModes & AdvancedPIOModes_4)
1226 return 4;
1227 if (ident->AdvancedPIOModes & AdvancedPIOModes_3)
1228 return 3;
1229 }
1230 if (ident->PioCycleTimingMode == 2)
1231 return 2;
1232 if (ident->PioCycleTimingMode == 1)
1233 return 1;
1234 if (ident->PioCycleTimingMode == 0)
1235 return 0;
1236 return IOMODE_NOT_SPECIFIED;
1237} // end AtaPioMode()
1238
1239LONG
1240NTAPI
1242{
1243 if (ident->MultiWordDMASupport & 0x04)
1244 return 2;
1245 if (ident->MultiWordDMASupport & 0x02)
1246 return 1;
1247 if (ident->MultiWordDMASupport & 0x01)
1248 return 0;
1249 return IOMODE_NOT_SPECIFIED;
1250} // end AtaWmode()
1251
1252LONG
1253NTAPI
1255{
1256 if (!ident->UdmaModesValid)
1257 return IOMODE_NOT_SPECIFIED;
1258 if (ident->UltraDMASupport & 0x40)
1259 return 6;
1260 if (ident->UltraDMASupport & 0x20)
1261 return 5;
1262 if (ident->UltraDMASupport & 0x10)
1263 return 4;
1264 if (ident->UltraDMASupport & 0x08)
1265 return 3;
1266 if (ident->UltraDMASupport & 0x04)
1267 return 2;
1268 if (ident->UltraDMASupport & 0x02)
1269 return 1;
1270 if (ident->UltraDMASupport & 0x01)
1271 return 0;
1272 return IOMODE_NOT_SPECIFIED;
1273} // end AtaUmode()
1274
1275LONG
1276NTAPI
1278 if(!ident->SataCapabilities ||
1279 ident->SataCapabilities == 0xffff) {
1280 return IOMODE_NOT_SPECIFIED;
1281 }
1282 if(ident->SataCapabilities & ATA_SATA_GEN3) {
1283 return ATA_SA600;
1284 } else
1285 if(ident->SataCapabilities & ATA_SATA_GEN2) {
1286 return ATA_SA300;
1287 } else
1288 if(ident->SataCapabilities & ATA_SATA_GEN1) {
1289 return ATA_SA150;
1290 }
1291 return IOMODE_NOT_SPECIFIED;
1292} // end AtaSAmode()
1293
1294#ifndef UNIATA_CORE
1295
1296VOID
1297NTAPI
1299 IN PVOID HwDeviceExtension
1300 )
1301{
1302 PHW_DEVICE_EXTENSION deviceExtension = (PHW_DEVICE_EXTENSION)HwDeviceExtension;
1303 PHW_TIMER HwScsiTimer;
1305 ULONG MiniportTimerValue;
1306 BOOLEAN recall = FALSE;
1307 ULONG lChannel;
1308 PHW_CHANNEL chan;
1309
1310 KdPrint2((PRINT_PREFIX "AtapiTimerDpc:\n"));
1311
1312 lChannel = deviceExtension->ActiveDpcChan = deviceExtension->FirstDpcChan;
1313 if(lChannel == CHAN_NOT_SPECIFIED) {
1314 KdPrint2((PRINT_PREFIX "AtapiTimerDpc: no items\n"));
1315 return;
1316 }
1317 chan = &(deviceExtension->chan[lChannel]);
1318
1319 while(TRUE) {
1320
1321 HwScsiTimer = chan->HwScsiTimer;
1322 chan->HwScsiTimer = NULL;
1323
1324 deviceExtension->FirstDpcChan = chan->NextDpcChan;
1325 if(deviceExtension->FirstDpcChan != CHAN_NOT_SPECIFIED) {
1326 recall = TRUE;
1327 }
1328
1329 HwScsiTimer(HwDeviceExtension);
1330
1332
1333 lChannel = deviceExtension->ActiveDpcChan = deviceExtension->FirstDpcChan;
1334 if(lChannel == CHAN_NOT_SPECIFIED) {
1335 KdPrint2((PRINT_PREFIX "AtapiTimerDpc: no more items\n"));
1336 deviceExtension->FirstDpcChan =
1337 deviceExtension->ActiveDpcChan = CHAN_NOT_SPECIFIED;
1338 return;
1339 }
1340
1342 KdPrint2((PRINT_PREFIX "AtapiTimerDpc: KeQuerySystemTime=%#x%#x\n", time.HighPart, time.LowPart));
1343
1344 chan = &deviceExtension->chan[lChannel];
1345 if(time.QuadPart >= chan->DpcTime - 10) {
1346 // call now
1347 KdPrint2((PRINT_PREFIX "AtapiTimerDpc: get next DPC, DpcTime1=%#x%#x\n",
1348 (ULONG)(chan->DpcTime >> 32), (ULONG)(chan->DpcTime)));
1349 continue;
1350 }
1351 break;
1352 }
1353
1354 if(recall) {
1355 deviceExtension->ActiveDpcChan = CHAN_NOT_SPECIFIED;
1356 MiniportTimerValue = (ULONG)(time.QuadPart - chan->DpcTime)/10;
1357 if(!MiniportTimerValue)
1358 MiniportTimerValue = 1;
1359
1360 KdPrint2((PRINT_PREFIX "AtapiTimerDpc: recall AtapiTimerDpc\n"));
1361 ScsiPortNotification(RequestTimerCall, HwDeviceExtension,
1363 MiniportTimerValue
1364 );
1365 }
1366 return;
1367
1368} // end AtapiTimerDpc()
1369
1370/*
1371 Wrapper for ScsiPort, that implements smart Dpc
1372 queueing. We need it to allow parallel functioning
1373 of IDE channels with shared interrupt. Standard Dpc mechanism
1374 cancels previous Dpc request (if any), but we need Dpc queue.
1375*/
1376VOID
1377NTAPI
1379 IN PVOID HwDeviceExtension,
1380 IN ULONG lChannel,
1381 IN PHW_TIMER HwScsiTimer,
1382 IN ULONG MiniportTimerValue
1383 )
1384{
1385 PHW_DEVICE_EXTENSION deviceExtension = (PHW_DEVICE_EXTENSION)HwDeviceExtension;
1387 LARGE_INTEGER time2;
1388 ULONG i;
1389 PHW_CHANNEL prev_chan;
1390 PHW_CHANNEL chan;
1391// BOOLEAN UseRequestTimerCall = TRUE;
1392
1393 KdPrint2((PRINT_PREFIX "AtapiQueueTimerDpc: dt=%d for lChn %#x\n", MiniportTimerValue, lChannel));
1395 time2 = time;
1396 KdPrint2((PRINT_PREFIX "AtapiQueueTimerDpc: KeQuerySystemTime=%#x%#x\n", time.HighPart, time.LowPart));
1397 time.QuadPart += MiniportTimerValue*10;
1398 KdPrint2((PRINT_PREFIX "AtapiQueueTimerDpc: KeQuerySystemTime2=%#x%#x\n", time.HighPart, time.LowPart));
1399
1400 KdPrint2((PRINT_PREFIX " ActiveDpcChan=%d, FirstDpcChan=%d\n", deviceExtension->ActiveDpcChan, deviceExtension->FirstDpcChan));
1401
1402 i = deviceExtension->FirstDpcChan;
1403 chan = prev_chan = NULL;
1404 while(i != CHAN_NOT_SPECIFIED) {
1405 prev_chan = chan;
1406 chan = &(deviceExtension->chan[i]);
1407 if(chan->DpcTime > time.QuadPart) {
1408 break;
1409 }
1410 i = chan->NextDpcChan;
1411 }
1412 chan = &(deviceExtension->chan[lChannel]);
1413 if(!prev_chan) {
1414 deviceExtension->FirstDpcChan = lChannel;
1415 } else {
1416 prev_chan->NextDpcChan = lChannel;
1417 }
1418 chan->NextDpcChan = i;
1419 chan->HwScsiTimer = HwScsiTimer;
1420 chan->DpcTime = time.QuadPart;
1421
1422 KdPrint2((PRINT_PREFIX "AtapiQueueTimerDpc: KeQuerySystemTime3=%#x%#x\n", time2.HighPart, time2.LowPart));
1423 if(time.QuadPart <= time2.QuadPart) {
1424 MiniportTimerValue = 1;
1425 } else {
1426 MiniportTimerValue = (ULONG)((time.QuadPart - time2.QuadPart) / 10);
1427 }
1428
1429 KdPrint2((PRINT_PREFIX "AtapiQueueTimerDpc: dt=%d for lChn %#x\n", MiniportTimerValue, lChannel));
1430 ScsiPortNotification(RequestTimerCall, HwDeviceExtension,
1432 MiniportTimerValue);
1433
1434} // end AtapiQueueTimerDpc()
1435
1436#endif //UNIATA_CORE
1437
1438#ifdef _DEBUG
1439VOID
1440NTAPI
1442 IN PHW_CHANNEL chan
1443 )
1444{
1445 ULONG j;
1446 UCHAR statusByteAlt;
1447
1448 GetStatus(chan, statusByteAlt);
1449 KdPrint2((PRINT_PREFIX " AltStatus (%#x)\n", statusByteAlt));
1450
1451 for(j=1; j<IDX_IO1_SZ; j++) {
1452 statusByteAlt = AtapiReadPort1(chan, IDX_IO1+j);
1454 " Reg_%#x (%#x) = %#x\n",
1455 j,
1456 chan->RegTranslation[IDX_IO1+j].Addr,
1457 statusByteAlt));
1458 }
1459 if(!chan->RegTranslation[IDX_BM_IO].Addr) {
1460 return;
1461 }
1462 for(j=0; j<IDX_BM_IO_SZ-1; j++) {
1463 statusByteAlt = AtapiReadPort1(chan, IDX_BM_IO+j);
1465 " BM_%#x (%#x) = %#x\n",
1466 j,
1467 chan->RegTranslation[IDX_BM_IO+j].Addr,
1468 statusByteAlt));
1469 }
1470 return;
1471} // end UniataDumpATARegs()
1472#endif //_DEBUG
1473
1474VOID
1475NTAPI
1477 IN PHW_CHANNEL chan,
1480 )
1481{
1482 if(chan->DeviceExtension->HwFlags & UNIATA_AHCI) {
1483 // AHCI
1485 } else {
1486 // SATA/PATA, assume drive is selected
1487 ULONG j;
1488 UCHAR statusByteAlt;
1489
1490 if((regs->bOpFlags & ATA_FLAGS_48BIT_COMMAND) == 0) {
1492 statusByteAlt = AtapiReadPort1(chan, IDX_IO1+j);
1493 ((PUCHAR)regs)[j-1] = statusByteAlt;
1494 }
1495 regs->bOpFlags = 0;
1496 } else {
1497 regs->bDriveHeadReg = AtapiReadPort1(chan, IDX_IO1_i_DriveSelect);
1499 statusByteAlt = AtapiReadPort1(chan, IDX_IO1+j);
1500 ((PUCHAR)regs)[j-1] = statusByteAlt;
1501 statusByteAlt = AtapiReadPort1(chan, IDX_IO1+j);
1502 ((PUCHAR)regs)[j+8-1] = statusByteAlt;
1503 }
1504 regs->bCommandReg = AtapiReadPort1(chan, IDX_IO1_i_Status);
1505 }
1506 }
1507 return;
1508} // end UniataSnapAtaRegs()
1509
1510/*++
1511
1512Routine Description:
1513
1514 Issue IDENTIFY command to a device.
1515
1516Arguments:
1517
1518 HwDeviceExtension - HBA miniport driver's adapter data storage
1519 DeviceNumber - Indicates which device.
1520 Command - Either the standard (EC) or the ATAPI packet (A1) IDENTIFY.
1521
1522Return Value:
1523
1524 TRUE if all goes well.
1525
1526--*/
1527BOOLEAN
1528NTAPI
1530 IN PVOID HwDeviceExtension,
1532 IN ULONG lChannel,
1534 IN BOOLEAN NoSetup
1535 )
1536{
1537 PHW_DEVICE_EXTENSION deviceExtension = (PHW_DEVICE_EXTENSION)HwDeviceExtension;
1538 PHW_CHANNEL chan = &(deviceExtension->chan[lChannel]);
1539 ULONG waitCount = 50000;
1540 ULONG j;
1541 UCHAR statusByte;
1542 //UCHAR statusByte2;
1543 UCHAR signatureLow,
1544 signatureHigh;
1545 BOOLEAN atapiDev = FALSE;
1546 BOOLEAN use_ahci = FALSE;
1547 PHW_LU_EXTENSION LunExt = chan->lun[DeviceNumber];
1548
1549 use_ahci = UniataIsSATARangeAvailable(deviceExtension, lChannel) &&
1550 (deviceExtension->HwFlags & UNIATA_AHCI);
1551
1553 if(chan->PmLunMap & (1 << DeviceNumber)) {
1554 // OK
1555 } else {
1556 KdPrint2((PRINT_PREFIX "IssueIdentify: PM empty port\n"));
1557 return FALSE;
1558 }
1559 } else
1561 KdPrint2((PRINT_PREFIX "IssueIdentify: NO SLAVE\n"));
1562 return FALSE;
1563 }
1564 if(LunExt->DeviceFlags & DFLAGS_HIDDEN) {
1565 KdPrint2((PRINT_PREFIX "IssueIdentify: HIDDEN\n"));
1566 return FALSE;
1567 }
1568
1569 if(use_ahci) {
1570 statusByte = WaitOnBusyLong(chan);
1571#ifdef _DEBUG
1572 if(!chan->AhciInternalAtaReq) {
1573 KdPrint2((PRINT_PREFIX "!AhciInternalAtaReq\n"));
1574 }
1575#endif
1576 } else {
1579 statusByte = WaitOnBusyLong(chan);
1580 // Check that the status register makes sense.
1581 GetBaseStatus(chan, statusByte);
1582 /*
1583 // unnecessary
1584 if(!hasPCI) {
1585 // original atapi.sys behavior for old ISA-only hardware
1586 AtapiStallExecution(100);
1587 }
1588 */
1589 }
1590
1592 // Mask status byte ERROR bits.
1593 statusByte = UniataIsIdle(deviceExtension, statusByte & ~(IDE_STATUS_ERROR | IDE_STATUS_INDEX));
1594 KdPrint2((PRINT_PREFIX "IssueIdentify: Checking for IDE. Status (%#x)\n", statusByte));
1595 // Check if register value is reasonable.
1596
1597 if(statusByte != IDE_STATUS_IDLE) {
1598
1599 // No reset here !!!
1600 KdPrint2((PRINT_PREFIX "IssueIdentify: statusByte != IDE_STATUS_IDLE\n"));
1601
1602 //if(!(deviceExtension->HwFlags & UNIATA_SATA)) {
1603 if(!UniataIsSATARangeAvailable(deviceExtension, lChannel)) {
1605 WaitOnBusyLong(chan);
1606
1607 signatureLow = AtapiReadPort1(chan, IDX_IO1_i_CylinderLow);
1608 signatureHigh = AtapiReadPort1(chan, IDX_IO1_i_CylinderHigh);
1609
1610 if (signatureLow == ATAPI_MAGIC_LSB &&
1611 signatureHigh == ATAPI_MAGIC_MSB) {
1612 // Device is Atapi.
1613 KdPrint2((PRINT_PREFIX "IssueIdentify: this is ATAPI (dev %d)\n", DeviceNumber));
1614 return FALSE;
1615 }
1616
1617 // We really should wait up to 31 seconds
1618 // The ATA spec. allows device 0 to come back from BUSY in 31 seconds!
1619 // (30 seconds for device 1)
1620 do {
1621 // Wait for Busy to drop.
1623 GetStatus(chan, statusByte);
1624 if(statusByte == IDE_STATUS_WRONG) {
1625 KdPrint2((PRINT_PREFIX "IssueIdentify: IDE_STATUS_WRONG (dev %d)\n", DeviceNumber));
1626 return FALSE;
1627 }
1628
1629 } while ((statusByte & IDE_STATUS_BUSY) && waitCount--);
1630 GetBaseStatus(chan, statusByte);
1631
1633 } else {
1634 GetBaseStatus(chan, statusByte);
1635 }
1636 // Another check for signature, to deal with one model Atapi that doesn't assert signature after
1637 // a soft reset.
1638 signatureLow = AtapiReadPort1(chan, IDX_IO1_i_CylinderLow);
1639 signatureHigh = AtapiReadPort1(chan, IDX_IO1_i_CylinderHigh);
1640
1641 if (signatureLow == ATAPI_MAGIC_LSB &&
1642 signatureHigh == ATAPI_MAGIC_MSB) {
1643 KdPrint2((PRINT_PREFIX "IssueIdentify: this is ATAPI (2) (dev %d)\n", DeviceNumber));
1644 // Device is Atapi.
1645 return FALSE;
1646 }
1647
1648 statusByte = UniataIsIdle(deviceExtension, statusByte) & ~IDE_STATUS_INDEX;
1649 if (statusByte != IDE_STATUS_IDLE) {
1650 // Give up on this.
1651 KdPrint2((PRINT_PREFIX "IssueIdentify: no dev (dev %d)\n", DeviceNumber));
1652 return FALSE;
1653 }
1654 }
1655 } else {
1656 KdPrint2((PRINT_PREFIX "IssueIdentify: Checking for ATAPI. Status (%#x)\n", statusByte));
1657 if(statusByte == IDE_STATUS_WRONG) {
1658 return FALSE;
1659 }
1660 //if(!(deviceExtension->HwFlags & UNIATA_SATA)) {
1661 if(!UniataIsSATARangeAvailable(deviceExtension, lChannel)) {
1662 statusByte = WaitForIdleLong(chan);
1663 KdPrint2((PRINT_PREFIX "IssueIdentify: Checking for ATAPI (2). Status (%#x)\n", statusByte));
1664 }
1665 atapiDev = TRUE;
1666 }
1667
1668// if(deviceExtension->HwFlags & UNIATA_SATA) {
1669 if(use_ahci) {
1670 statusByte = UniataAhciSendPIOCommand(HwDeviceExtension, lChannel, DeviceNumber,
1672 (PUCHAR)(&deviceExtension->FullIdentifyData),
1673 DEV_BSIZE,
1674 Command,
1675 0, 0,
1676 0,
1677 0 /* ahci flags */ ,
1679 1000 /* timeout 1 sec */
1680 );
1681 j = 9; // AHCI is rather different, skip loop at all
1682 } else
1683 if(LunExt->DeviceFlags & DFLAGS_MANUAL_CHS) {
1684 j = 9; // don't send IDENTIFY, assume it is not supported
1685 KdPrint2((PRINT_PREFIX "IssueIdentify: Manual CHS\n"));
1686 RtlZeroMemory(&(deviceExtension->FullIdentifyData), sizeof(deviceExtension->FullIdentifyData));
1687 RtlCopyMemory(&(deviceExtension->FullIdentifyData), &(LunExt->IdentifyData), sizeof(LunExt->IdentifyData));
1688 } else
1689 if(UniataIsSATARangeAvailable(deviceExtension, lChannel)) {
1690 j = 4; // skip old-style checks
1691 } else {
1692 j = 0;
1693 }
1694 for (; j < 4*2; j++) {
1695 // Send IDENTIFY command.
1696
1697 // Load CylinderHigh and CylinderLow with number bytes to transfer for old devices, use 0 for newer.
1698
1699 statusByte = AtaCommand(deviceExtension, DeviceNumber, lChannel, Command, (j < 4) ? DEV_BSIZE : 0 /* cyl */, 0, 0, 0, 0, ATA_WAIT_INTR);
1700 // Clear interrupt
1701
1702 if (!statusByte) {
1703 KdPrint2((PRINT_PREFIX "IssueIdentify: 0-status, not present\n"));
1704 return FALSE;
1705 } else
1706 if (statusByte & IDE_STATUS_DRQ) {
1707 // Read status to acknowledge any interrupts generated.
1708 KdPrint2((PRINT_PREFIX "IssueIdentify: IDE_STATUS_DRQ (%#x)\n", statusByte));
1709 GetBaseStatus(chan, statusByte);
1710 // One last check for Atapi.
1712 signatureLow = AtapiReadPort1(chan, IDX_IO1_i_CylinderLow);
1713 signatureHigh = AtapiReadPort1(chan, IDX_IO1_i_CylinderHigh);
1714
1715 if (signatureLow == ATAPI_MAGIC_LSB &&
1716 signatureHigh == ATAPI_MAGIC_MSB) {
1717 KdPrint2((PRINT_PREFIX "IssueIdentify: this is ATAPI (3) (dev %d)\n", DeviceNumber));
1718 // Device is Atapi.
1719 return FALSE;
1720 }
1721 }
1722 break;
1723 } else {
1724 KdPrint2((PRINT_PREFIX "IssueIdentify: !IDE_STATUS_DRQ (%#x)\n", statusByte));
1726 // Check the signature. If DRQ didn't come up it's likely Atapi.
1727 signatureLow = AtapiReadPort1(chan, IDX_IO1_i_CylinderLow);
1728 signatureHigh = AtapiReadPort1(chan, IDX_IO1_i_CylinderHigh);
1729
1730 if (signatureLow == ATAPI_MAGIC_LSB &&
1731 signatureHigh == ATAPI_MAGIC_MSB) {
1732 // Device is Atapi.
1733 KdPrint2((PRINT_PREFIX "IssueIdentify: this is ATAPI (4) (dev %d)\n", DeviceNumber));
1734 return FALSE;
1735 }
1736 } else {
1737 if(!(statusByte & IDE_STATUS_ERROR) && (statusByte & IDE_STATUS_BUSY)) {
1738 KdPrint2((PRINT_PREFIX "IssueIdentify: DRQ not asserted immediately, BUSY -> WaitForDrq\n"));
1739 break;
1740 }
1741 }
1742 // Device didn't respond correctly. It will be given one more chance.
1743 KdPrint2((PRINT_PREFIX "IssueIdentify: DRQ never asserted (%#x). Error reg (%#x)\n",
1744 statusByte, AtapiReadPort1(chan, IDX_IO1_i_Error)));
1745 GetBaseStatus(chan, statusByte);
1747
1748 AtapiDisableInterrupts(deviceExtension, lChannel);
1749 AtapiEnableInterrupts(deviceExtension, lChannel);
1750
1751 GetBaseStatus(chan, statusByte);
1752 //GetStatus(chan, statusByte);
1753 KdPrint2((PRINT_PREFIX "IssueIdentify: Status after soft reset (%#x)\n", statusByte));
1754 }
1755 }
1756 // Check for error on really stupid master devices that assert random
1757 // patterns of bits in the status register at the slave address.
1758 if ((Command == IDE_COMMAND_IDENTIFY) && (statusByte & IDE_STATUS_ERROR)) {
1759 KdPrint2((PRINT_PREFIX "IssueIdentify: Exit on error (%#x)\n", statusByte));
1760 return FALSE;
1761 }
1762
1763 if(use_ahci) {
1764 // everything should already be done by controller
1765 } else
1766 if(LunExt->DeviceFlags & DFLAGS_MANUAL_CHS) {
1767 j = 9; // don't send IDENTIFY, assume it is not supported
1768 KdPrint2((PRINT_PREFIX "IssueIdentify: Manual CHS (2)\n"));
1769 statusByte = WaitForDrq(chan);
1770 statusByte = WaitOnBusyLong(chan);
1771 KdPrint2((PRINT_PREFIX "IssueIdentify: statusByte %#x\n", statusByte));
1772 GetBaseStatus(chan, statusByte);
1773 } else {
1774
1775 KdPrint2((PRINT_PREFIX "IssueIdentify: Status before read words %#x\n", statusByte));
1776 // Suck out 256 words. After waiting for one model that asserts busy
1777 // after receiving the Packet Identify command.
1778 statusByte = WaitForDrq(chan);
1779 statusByte = WaitOnBusyLong(chan);
1780 KdPrint2((PRINT_PREFIX "IssueIdentify: statusByte %#x\n", statusByte));
1781
1782 if (!(statusByte & IDE_STATUS_DRQ)) {
1783 KdPrint2((PRINT_PREFIX "IssueIdentify: !IDE_STATUS_DRQ (2) (%#x)\n", statusByte));
1784 GetBaseStatus(chan, statusByte);
1785 return FALSE;
1786 }
1787 GetBaseStatus(chan, statusByte);
1788 KdPrint2((PRINT_PREFIX "IssueIdentify: BASE statusByte %#x\n", statusByte));
1789
1790#ifdef _DEBUG
1791 if(atapiDev) {
1793 KdPrint3((PRINT_PREFIX "IssueIdentify: iReason %x\n", j));
1794
1795 j =
1797
1798 j |=
1800 KdPrint3((PRINT_PREFIX "IssueIdentify: wCount %x\n", j));
1801
1802 }
1803#endif //_DEBUG
1804
1805 if (atapiDev || !(LunExt->DeviceFlags & DFLAGS_DWORDIO_ENABLED) ) {
1806
1807 KdPrint2((PRINT_PREFIX " use 16bit IO\n"));
1808 // ATI/SII chipsets with memory-mapped IO hangs when
1809 // I call ReadBuffer(), probably due to PCI burst/prefetch enabled
1810 // Unfortunately, I don't know yet how to workaround it except
1811 // spacifying manual delay in the way you see below.
1812 ReadBuffer(chan, (PUSHORT)&deviceExtension->FullIdentifyData, 256, PIO0_TIMING);
1813
1814 // Work around for some IDE and one model Atapi that will present more than
1815 // 256 bytes for the Identify data.
1816 KdPrint2((PRINT_PREFIX "IssueIdentify: suck data port\n", statusByte));
1817 statusByte = AtapiSuckPort2(chan);
1818 } else {
1819 KdPrint2((PRINT_PREFIX " use 32bit IO\n"));
1820 ReadBuffer2(chan, (PULONG)&deviceExtension->FullIdentifyData, 256/2, PIO0_TIMING);
1821 }
1822
1823 KdPrint2((PRINT_PREFIX "IssueIdentify: statusByte %#x\n", statusByte));
1824 statusByte = WaitForDrq(chan);
1825 KdPrint2((PRINT_PREFIX "IssueIdentify: statusByte %#x\n", statusByte));
1826 GetBaseStatus(chan, statusByte);
1827 }
1828 KdPrint2((PRINT_PREFIX "IssueIdentify: Status after read words %#x\n", statusByte));
1829
1830 if(NoSetup) {
1831 KdPrint2((PRINT_PREFIX "IssueIdentify: no setup, exiting\n"));
1832 return TRUE;
1833 }
1834
1835 KdPrint2((PRINT_PREFIX "Model: %20.20s\n", deviceExtension->FullIdentifyData.ModelNumber));
1836 KdPrint2((PRINT_PREFIX "FW: %4.4s\n", deviceExtension->FullIdentifyData.FirmwareRevision));
1837 KdPrint2((PRINT_PREFIX "S/N: %20.20s\n", deviceExtension->FullIdentifyData.SerialNumber));
1839 if((deviceExtension->FullIdentifyData.FirmwareRevision[0] == 0 ||
1840 deviceExtension->FullIdentifyData.FirmwareRevision[0] == ' ') &&
1841 (deviceExtension->FullIdentifyData.FirmwareRevision[1] == 0 ||
1842 deviceExtension->FullIdentifyData.FirmwareRevision[1] == ' ')) {
1843 // Check for BOCHS VM signature. If no additional PCI devices (e.g. VGA)
1844 // are declared BOCHS looks like regular PC
1845 if (!atapiDev && !AtapiStringCmp ((PCCHAR)(deviceExtension->FullIdentifyData.SerialNumber), "XBDH00", 6)) {
1846 KdPrint2((PRINT_PREFIX "IssueIdentify: BOCHS HDD\n"));
1848 } else
1849 if (atapiDev && !AtapiStringCmp ((PCCHAR)(deviceExtension->FullIdentifyData.SerialNumber), "XBDC00", 6)) {
1850 KdPrint2((PRINT_PREFIX "IssueIdentify: BOCHS CD\n"));
1852 }
1853 }
1854 }
1855
1856 KdPrint2((PRINT_PREFIX "Pio: %x\n", deviceExtension->FullIdentifyData.PioCycleTimingMode));
1857 if(deviceExtension->FullIdentifyData.PioTimingsValid) {
1858 KdPrint2((PRINT_PREFIX "APio: %x\n", deviceExtension->FullIdentifyData.AdvancedPIOModes));
1859 }
1860 KdPrint2((PRINT_PREFIX "SWDMA: %x\n", deviceExtension->FullIdentifyData.SingleWordDMAActive));
1861 KdPrint2((PRINT_PREFIX "MWDMA: %x\n", deviceExtension->FullIdentifyData.MultiWordDMAActive));
1862 if(deviceExtension->FullIdentifyData.UdmaModesValid) {
1863 KdPrint2((PRINT_PREFIX "UDMA: %x/%x\n", deviceExtension->FullIdentifyData.UltraDMAActive, deviceExtension->FullIdentifyData.UltraDMASupport));
1864 }
1865 KdPrint2((PRINT_PREFIX "SATA: %x\n", deviceExtension->FullIdentifyData.SataEnable));
1866 KdPrint2((PRINT_PREFIX "SATA support: %x, CAPs %#x\n",
1867 deviceExtension->FullIdentifyData.SataSupport,
1868 deviceExtension->FullIdentifyData.SataCapabilities));
1869
1870 LunExt->LimitedTransferMode =
1871 LunExt->OrigTransferMode =
1873 LunExt->TransferMode =
1875
1876 KdPrint2((PRINT_PREFIX "OrigTransferMode: %x, Active: %x\n", LunExt->OrigTransferMode, LunExt->TransferMode));
1877 KdPrint2((PRINT_PREFIX "Accoustic %d, cur %d\n",
1878 deviceExtension->FullIdentifyData.VendorAcoustic,
1879 deviceExtension->FullIdentifyData.CurrentAcoustic
1880 ));
1881 KdPrint2((PRINT_PREFIX "AdvPowerMode %d\n",
1882 deviceExtension->FullIdentifyData.CfAdvPowerMode
1883 ));
1884
1885 KdPrint2((PRINT_PREFIX "PowerMngt %d/%d, APM %d/%d\n",
1886 deviceExtension->FullIdentifyData.FeaturesEnabled.PowerMngt,
1887 deviceExtension->FullIdentifyData.FeaturesSupport.PowerMngt,
1888 deviceExtension->FullIdentifyData.FeaturesEnabled.APM,
1889 deviceExtension->FullIdentifyData.FeaturesSupport.APM
1890 ));
1891
1892 // Check out a few capabilities / limitations of the device.
1893 if (deviceExtension->FullIdentifyData.RemovableStatus & 1) {
1894 // Determine if this drive supports the MSN functions.
1895 KdPrint2((PRINT_PREFIX "IssueIdentify: Marking drive %d as removable. SFE = %d\n",
1897 deviceExtension->FullIdentifyData.RemovableStatus));
1899 }
1900 if(use_ahci) {
1901 // AHCI doesn't recommend using PIO and multiblock
1902 LunExt->MaximumBlockXfer = 0;
1903 } else
1904 if (deviceExtension->FullIdentifyData.MaximumBlockTransfer) {
1905 // Determine max. block transfer for this device.
1906 LunExt->MaximumBlockXfer =
1907 (UCHAR)(deviceExtension->FullIdentifyData.MaximumBlockTransfer & 0xFF);
1908 }
1909 LunExt->NumOfSectors = 0;
1911 ULONGLONG NumOfSectors=0;
1912 ULONGLONG NativeNumOfSectors=0;
1913 ULONGLONG cylinders=0;
1914 ULONGLONG tmp_cylinders=0;
1915
1916 KdPrint2((PRINT_PREFIX "PhysLogSectorSize %#x, %#x, offset %#x\n",
1917 deviceExtension->FullIdentifyData.PhysLogSectorSize,
1918 deviceExtension->FullIdentifyData.LargeSectorSize,
1919 deviceExtension->FullIdentifyData.LogicalSectorOffset
1920 ));
1921
1922 KdPrint2((PRINT_PREFIX "NV PM_Sup %d, PM_En %d, En %d, PM ver %#x ver %#x\n",
1923 deviceExtension->FullIdentifyData.NVCache_PM_Supported,
1924 deviceExtension->FullIdentifyData.NVCache_PM_Enabled,
1925 deviceExtension->FullIdentifyData.NVCache_Enabled,
1926 deviceExtension->FullIdentifyData.NVCache_PM_Version,
1927 deviceExtension->FullIdentifyData.NVCache_Version
1928 ));
1929
1930 KdPrint2((PRINT_PREFIX "R-rate %d\n",
1932 ));
1933 KdPrint2((PRINT_PREFIX "WC %d/%d, LA %d/%d, WB %d/%d, RB %d/%d, Q %d/%d\n",
1934 deviceExtension->FullIdentifyData.FeaturesEnabled.WriteCache,
1935 deviceExtension->FullIdentifyData.FeaturesSupport.WriteCache,
1936 deviceExtension->FullIdentifyData.FeaturesEnabled.LookAhead,
1937 deviceExtension->FullIdentifyData.FeaturesSupport.LookAhead,
1938 deviceExtension->FullIdentifyData.FeaturesEnabled.WriteBuffer,
1939 deviceExtension->FullIdentifyData.FeaturesSupport.WriteBuffer,
1940 deviceExtension->FullIdentifyData.FeaturesEnabled.ReadBuffer,
1941 deviceExtension->FullIdentifyData.FeaturesSupport.ReadBuffer,
1942 deviceExtension->FullIdentifyData.FeaturesEnabled.Queued,
1943 deviceExtension->FullIdentifyData.FeaturesSupport.Queued
1944 ));
1945
1946 KdPrint2((PRINT_PREFIX "Protected %d/%d status %#x, rev %#x\n",
1947 deviceExtension->FullIdentifyData.FeaturesEnabled.Protected,
1948 deviceExtension->FullIdentifyData.FeaturesSupport.Protected,
1949 deviceExtension->FullIdentifyData.SecurityStatus,
1950 deviceExtension->FullIdentifyData.MasterPasswdRevision
1951 ));
1952
1953 // Read very-old-style drive geometry
1954 KdPrint2((PRINT_PREFIX "CHS %#x:%#x:%#x\n",
1955 deviceExtension->FullIdentifyData.NumberOfCylinders,
1956 deviceExtension->FullIdentifyData.NumberOfHeads,
1957 deviceExtension->FullIdentifyData.SectorsPerTrack
1958 ));
1959 NumOfSectors = deviceExtension->FullIdentifyData.NumberOfCylinders *
1960 deviceExtension->FullIdentifyData.NumberOfHeads *
1961 deviceExtension->FullIdentifyData.SectorsPerTrack;
1962 KdPrint2((PRINT_PREFIX "NumOfSectors %#I64x\n", NumOfSectors));
1963 // Check for HDDs > 8Gb
1964 if ((deviceExtension->FullIdentifyData.NumberOfCylinders == 0x3fff) &&
1965/* (deviceExtension->FullIdentifyData.TranslationFieldsValid) &&*/
1966 deviceExtension->FullIdentifyData.NumberOfHeads &&
1967 deviceExtension->FullIdentifyData.SectorsPerTrack &&
1968 (NumOfSectors < deviceExtension->FullIdentifyData.UserAddressableSectors)) {
1969 KdPrint2((PRINT_PREFIX "NumberOfCylinders == 0x3fff\n"));
1970 cylinders =
1971 (deviceExtension->FullIdentifyData.UserAddressableSectors /
1972 (deviceExtension->FullIdentifyData.NumberOfHeads *
1973 deviceExtension->FullIdentifyData.SectorsPerTrack));
1974
1975 KdPrint2((PRINT_PREFIX "cylinders %#I64x\n", cylinders));
1976
1977 NumOfSectors = cylinders *
1978 deviceExtension->FullIdentifyData.NumberOfHeads *
1979 deviceExtension->FullIdentifyData.SectorsPerTrack;
1980
1981 KdPrint2((PRINT_PREFIX "NumOfSectors %#I64x\n", NumOfSectors));
1982 } else {
1983
1984 }
1985 // Check for LBA mode
1986 KdPrint2((PRINT_PREFIX "SupportLba flag %#x\n", deviceExtension->FullIdentifyData.SupportLba));
1987 KdPrint2((PRINT_PREFIX "SupportDMA flag %#x\n", deviceExtension->FullIdentifyData.SupportDma));
1988 KdPrint2((PRINT_PREFIX "SoftReset %#x\n", deviceExtension->FullIdentifyData.SoftReset));
1989 KdPrint2((PRINT_PREFIX "SupportIordy %#x, DisableIordy %#x\n",
1990 deviceExtension->FullIdentifyData.SupportIordy,
1991 deviceExtension->FullIdentifyData.DisableIordy
1992 ));
1993 KdPrint2((PRINT_PREFIX "MajorRevision %#x\n", deviceExtension->FullIdentifyData.MajorRevision));
1994 KdPrint2((PRINT_PREFIX "UserAddressableSectors %#x\n", deviceExtension->FullIdentifyData.UserAddressableSectors));
1995 if ( deviceExtension->FullIdentifyData.SupportLba
1996 ||
1997 (deviceExtension->FullIdentifyData.MajorRevision &&
1998/* deviceExtension->FullIdentifyData.TranslationFieldsValid &&*/
1999 deviceExtension->FullIdentifyData.UserAddressableSectors)) {
2000 KdPrint2((PRINT_PREFIX "LBA mode\n"));
2002 } else {
2003 KdPrint2((PRINT_PREFIX "Keep orig geometry\n"));
2005 goto skip_lba_staff;
2006 }
2007 // Check for LBA48 support
2008 if(LunExt->DeviceFlags & DFLAGS_LBA_ENABLED) {
2009 if(deviceExtension->FullIdentifyData.FeaturesSupport.Address48 &&
2010 deviceExtension->FullIdentifyData.FeaturesEnabled.Address48 &&
2011 deviceExtension->FullIdentifyData.NumberOfHeads &&
2012 deviceExtension->FullIdentifyData.SectorsPerTrack &&
2013 (deviceExtension->FullIdentifyData.UserAddressableSectors48 > NumOfSectors)
2014 ) {
2015 KdPrint2((PRINT_PREFIX "LBA48\n"));
2016 cylinders =
2017 (deviceExtension->FullIdentifyData.UserAddressableSectors48 /
2018 (deviceExtension->FullIdentifyData.NumberOfHeads *
2019 deviceExtension->FullIdentifyData.SectorsPerTrack));
2020
2021 KdPrint2((PRINT_PREFIX "cylinders %#I64x\n", cylinders));
2022
2023 NativeNumOfSectors = cylinders *
2024 deviceExtension->FullIdentifyData.NumberOfHeads *
2025 deviceExtension->FullIdentifyData.SectorsPerTrack;
2026
2027 KdPrint2((PRINT_PREFIX "NativeNumOfSectors %#I64x\n", NativeNumOfSectors));
2028
2029 if(NativeNumOfSectors > NumOfSectors) {
2030 KdPrint2((PRINT_PREFIX "Update NumOfSectors to %#I64x\n", NativeNumOfSectors));
2031 NumOfSectors = NativeNumOfSectors;
2032 }
2033 }
2034
2035 // Check drive capacity report for LBA48-capable drives.
2036 if(deviceExtension->FullIdentifyData.FeaturesSupport.Address48) {
2037 ULONG hNativeNumOfSectors;
2038 KdPrint2((PRINT_PREFIX "Use IDE_COMMAND_READ_NATIVE_SIZE48\n"));
2039
2040 statusByte = AtaCommand48(deviceExtension, DeviceNumber, lChannel,
2042
2043 if(!(statusByte & IDE_STATUS_ERROR)) {
2044 if(use_ahci) {
2045 NativeNumOfSectors = chan->AhciInternalAtaReq->ahci.in_lba;
2046 } else {
2047 NativeNumOfSectors = (ULONG)AtapiReadPort1(chan, IDX_IO1_i_BlockNumber) |
2050
2053
2054 KdPrint2((PRINT_PREFIX "Read high order bytes\n"));
2055 NativeNumOfSectors |=
2057 hNativeNumOfSectors=
2060 ((PULONG)&NativeNumOfSectors)[1] = hNativeNumOfSectors;
2061 }
2062 KdPrint2((PRINT_PREFIX "NativeNumOfSectors %#I64x\n", NativeNumOfSectors));
2063
2064 // Some drives report LBA48 capability while has capacity below 128Gb
2065 // Probably they support large block-counters.
2066 // But the problem is that some of them reports higher part of Max LBA equal to lower part.
2067 // Here we check this
2068 if((NativeNumOfSectors & 0xffffff) == ((NativeNumOfSectors >> 24) & 0xffffff)) {
2069 KdPrint2((PRINT_PREFIX "High-order bytes == Low-order bytes !!!\n"));
2070
2071 statusByte = AtaCommand48(deviceExtension, DeviceNumber, lChannel,
2073
2074 if(!(statusByte & IDE_STATUS_ERROR)) {
2075 if(use_ahci) {
2076 NativeNumOfSectors = chan->AhciInternalAtaReq->ahci.in_lba;
2077 } else {
2078 NativeNumOfSectors = (ULONGLONG)AtapiReadPort1(chan, IDX_IO1_i_BlockNumber) |
2084 ;
2085 }
2086 }
2087
2088 if((NativeNumOfSectors & 0xffffff) == ((NativeNumOfSectors >> 24) & 0xffffff)) {
2089 KdPrint2((PRINT_PREFIX "High-order bytes == Low-order bytes !!! (2)\n"));
2090 NativeNumOfSectors = 0;
2091 }
2092 }
2093
2094 if(NumOfSectors <= ATA_MAX_LBA28 &&
2095 NativeNumOfSectors > NumOfSectors) {
2096
2097 KdPrint2((PRINT_PREFIX "Use IDE_COMMAND_SET_NATIVE_SIZE48\n"));
2098 KdPrint2((PRINT_PREFIX "Update NumOfSectors to %#I64x\n", NativeNumOfSectors));
2099
2100 statusByte = AtaCommand48(deviceExtension, DeviceNumber, lChannel,
2101 IDE_COMMAND_SET_NATIVE_SIZE, NativeNumOfSectors, 0, 0, ATA_WAIT_READY);
2102 if(!(statusByte & IDE_STATUS_ERROR)) {
2103 NumOfSectors = NativeNumOfSectors;
2104 }
2105 }
2106 } // !error
2107 }
2108
2109 if(NumOfSectors < 0x2100000 /*&& NumOfSectors > 31*1000*1000*/) {
2110 // check for native LBA size
2111 // some drives report ~32Gb in Identify Block
2112 KdPrint2((PRINT_PREFIX "Use IDE_COMMAND_READ_NATIVE_SIZE\n"));
2113
2114 statusByte = AtaCommand(deviceExtension, DeviceNumber, lChannel, IDE_COMMAND_READ_NATIVE_SIZE,
2115 0, IDE_USE_LBA, 0, 0, 0, ATA_WAIT_READY);
2116
2117 if(!(statusByte & IDE_STATUS_ERROR)) {
2118 if(use_ahci) {
2119 NativeNumOfSectors = chan->AhciInternalAtaReq->ahci.in_lba;
2120 } else {
2121 NativeNumOfSectors = (ULONG)AtapiReadPort1(chan, IDX_IO1_i_BlockNumber) |
2124 (((ULONG)AtapiReadPort1(chan, IDX_IO1_i_DriveSelect) & 0xf) << 24);
2125 }
2126 KdPrint2((PRINT_PREFIX "NativeNumOfSectors %#I64x\n", NativeNumOfSectors));
2127
2128 if(NativeNumOfSectors > NumOfSectors) {
2129
2130 KdPrint2((PRINT_PREFIX "Use IDE_COMMAND_SET_NATIVE_SIZE\n"));
2131 KdPrint2((PRINT_PREFIX "Update NumOfSectors to %#I64x\n", NativeNumOfSectors));
2132
2133 statusByte = AtaCommand48(deviceExtension, DeviceNumber, lChannel,
2134 IDE_COMMAND_SET_NATIVE_SIZE, NativeNumOfSectors, 0, 0, ATA_WAIT_READY);
2135 if(!(statusByte & IDE_STATUS_ERROR)) {
2136 NumOfSectors = NativeNumOfSectors;
2137 }
2138 }
2139 }
2140 }
2141
2142 if(NumOfSectors > ATA_MAX_IOLBA28) {
2143 KdPrint2((PRINT_PREFIX "2TB threshold, force LBA64 WRITE requirement\n"));
2144 LunExt->DeviceFlags |= DFLAGS_LBA32plus;
2145 }
2146 } // if(LunExt->DeviceFlags & DFLAGS_LBA_ENABLED)
2147
2148 // fill IdentifyData with bogus geometry
2149 KdPrint2((PRINT_PREFIX "requested LunExt->GeomType=%x\n", LunExt->opt_GeomType));
2150 if(deviceExtension->FullIdentifyData.CurrentSectorsPerTrack &&
2151 deviceExtension->FullIdentifyData.NumberOfCurrentHeads) {
2152 tmp_cylinders = NumOfSectors / (deviceExtension->FullIdentifyData.CurrentSectorsPerTrack *
2153 deviceExtension->FullIdentifyData.NumberOfCurrentHeads);
2154 } else
2155 if(deviceExtension->FullIdentifyData.SectorsPerTrack &&
2156 deviceExtension->FullIdentifyData.NumberOfHeads) {
2157 KdPrint2((PRINT_PREFIX "Current C/H = %#I64x/%#I64x\n",
2159 deviceExtension->FullIdentifyData.NumberOfCurrentHeads));
2160 tmp_cylinders = NumOfSectors / (deviceExtension->FullIdentifyData.SectorsPerTrack *
2161 deviceExtension->FullIdentifyData.NumberOfHeads);
2162 } else {
2163 tmp_cylinders = 0;
2164 }
2165 KdPrint2((PRINT_PREFIX "tmp_cylinders = %#I64x\n", tmp_cylinders));
2166 if((tmp_cylinders < 0xffff) || (LunExt->opt_GeomType == GEOM_ORIG)) {
2167 // ok, we can keep original values
2168 if(LunExt->opt_GeomType == GEOM_AUTO) {
2169 LunExt->opt_GeomType = GEOM_ORIG;
2170 }
2171 } else {
2172 tmp_cylinders = NumOfSectors / (255*63);
2173 if(tmp_cylinders < 0xffff) {
2174 // we can use generic values for H/S for generic geometry approach
2175 if(LunExt->opt_GeomType == GEOM_AUTO) {
2176 LunExt->opt_GeomType = GEOM_STD;
2177 }
2178 } else {
2179 // we should use UNIATA geometry approach
2180 if(LunExt->opt_GeomType == GEOM_AUTO) {
2181 LunExt->opt_GeomType = GEOM_UNIATA;
2182 }
2183 }
2184 }
2185
2186 if(!deviceExtension->FullIdentifyData.SectorsPerTrack ||
2187 !deviceExtension->FullIdentifyData.NumberOfHeads) {
2188 KdPrint2((PRINT_PREFIX "Zero S/H -> Force Use GEOM_STD\n"));
2189 }
2190
2191 if(LunExt->opt_GeomType == GEOM_STD) {
2192 deviceExtension->FullIdentifyData.CurrentSectorsPerTrack =
2193 deviceExtension->FullIdentifyData.SectorsPerTrack = 63;
2194
2195 deviceExtension->FullIdentifyData.NumberOfCurrentHeads =
2196 deviceExtension->FullIdentifyData.NumberOfHeads = 255;
2197
2198 cylinders = NumOfSectors / (255*63);
2199 KdPrint2((PRINT_PREFIX "Use GEOM_STD, CHS=%I64x/%x/%x\n", cylinders, 255, 63));
2200 } else
2201 if(LunExt->opt_GeomType == GEOM_UNIATA) {
2202 while ((cylinders > 0xffff) && (deviceExtension->FullIdentifyData.SectorsPerTrack < 0x80)) {
2203 cylinders /= 2;
2204 KdPrint2((PRINT_PREFIX "cylinders /= 2\n"));
2205 deviceExtension->FullIdentifyData.SectorsPerTrack *= 2;
2206 deviceExtension->FullIdentifyData.CurrentSectorsPerTrack *= 2;
2207 }
2208 while ((cylinders > 0xffff) && (deviceExtension->FullIdentifyData.NumberOfHeads < 0x80)) {
2209 cylinders /= 2;
2210 KdPrint2((PRINT_PREFIX "cylinders /= 2 (2)\n"));
2211 deviceExtension->FullIdentifyData.NumberOfHeads *= 2;
2212 deviceExtension->FullIdentifyData.NumberOfCurrentHeads *= 2;
2213 }
2214 while ((cylinders > 0xffff) && (deviceExtension->FullIdentifyData.SectorsPerTrack < 0x8000)) {
2215 cylinders /= 2;
2216 KdPrint2((PRINT_PREFIX "cylinders /= 2 (3)\n"));
2217 deviceExtension->FullIdentifyData.SectorsPerTrack *= 2;
2218 deviceExtension->FullIdentifyData.CurrentSectorsPerTrack *= 2;
2219 }
2220 while ((cylinders > 0xffff) && (deviceExtension->FullIdentifyData.NumberOfHeads < 0x8000)) {
2221 cylinders /= 2;
2222 KdPrint2((PRINT_PREFIX "cylinders /= 2 (4)\n"));
2223 deviceExtension->FullIdentifyData.NumberOfHeads *= 2;
2224 deviceExtension->FullIdentifyData.NumberOfCurrentHeads *= 2;
2225 }
2226 KdPrint2((PRINT_PREFIX "Use GEOM_UNIATA, CHS=%I64x/%x/%x\n", cylinders,
2227 deviceExtension->FullIdentifyData.NumberOfCurrentHeads,
2228 deviceExtension->FullIdentifyData.CurrentSectorsPerTrack));
2229 }
2230 if(!cylinders) {
2231 KdPrint2((PRINT_PREFIX "cylinders = tmp_cylinders (%x = %x)\n", cylinders, tmp_cylinders));
2232 cylinders = tmp_cylinders;
2233 }
2235 deviceExtension->FullIdentifyData.NumberOfCylinders = (USHORT)cylinders;
2236
2237skip_lba_staff:
2238
2239 KdPrint2((PRINT_PREFIX "Geometry: C %#x (%#x)\n",
2240 deviceExtension->FullIdentifyData.NumberOfCylinders,
2242 ));
2243 KdPrint2((PRINT_PREFIX "Geometry: H %#x (%#x)\n",
2244 deviceExtension->FullIdentifyData.NumberOfHeads,
2245 deviceExtension->FullIdentifyData.NumberOfCurrentHeads
2246 ));
2247 KdPrint2((PRINT_PREFIX "Geometry: S %#x (%#x)\n",
2248 deviceExtension->FullIdentifyData.SectorsPerTrack,
2250 ));
2251
2252 if(NumOfSectors) {
2253 LunExt->NumOfSectors = NumOfSectors;
2254 }
2255 if(deviceExtension->FullIdentifyData.MajorRevision &&
2256 deviceExtension->FullIdentifyData.DoubleWordIo) {
2258 KdPrint2((PRINT_PREFIX "IssueIdentify: DWORDIO supported\n"));
2259 }
2260 } else {
2261 // ATAPI
2262 if(deviceExtension->FullIdentifyData.MajorRevision &&
2263 deviceExtension->FullIdentifyData.DoubleWordIo) {
2265 KdPrint2((PRINT_PREFIX "IssueIdentify: DFLAGS_DWORDIO_ENABLED.\n"));
2266 }
2267 if(deviceExtension->FullIdentifyData.AtapiDMA.DMADirRequired) {
2268 KdPrint2((PRINT_PREFIX "DMADirRequired.\n"));
2269 }
2270 if(deviceExtension->FullIdentifyData.AtapiByteCount0) {
2271 KdPrint2((PRINT_PREFIX "AtapiByteCount0=%x\n", deviceExtension->FullIdentifyData.AtapiByteCount0));
2272 }
2273 }
2274
2276 &deviceExtension->FullIdentifyData,sizeof(IDENTIFY_DATA2));
2277
2278 InitBadBlocks(LunExt);
2279
2280 if ((LunExt->IdentifyData.DrqType & ATAPI_DRQT_INTR) &&
2282
2283 // This device interrupts with the assertion of DRQ after receiving
2284 // Atapi Packet Command
2285 LunExt->DeviceFlags |= DFLAGS_INT_DRQ;
2286 KdPrint2((PRINT_PREFIX "IssueIdentify: Device interrupts on assertion of DRQ.\n"));
2287
2288 } else {
2289 KdPrint2((PRINT_PREFIX "IssueIdentify: Device does not interrupt on assertion of DRQ.\n"));
2290 }
2291
2293 // ATAPI branch
2294 if(LunExt->IdentifyData.DeviceType == ATAPI_TYPE_TAPE) {
2295 // This is a tape.
2297 KdPrint2((PRINT_PREFIX "IssueIdentify: Device is a tape drive.\n"));
2298 } else
2299 if(LunExt->IdentifyData.DeviceType == ATAPI_TYPE_CDROM ||
2300 LunExt->IdentifyData.DeviceType == ATAPI_TYPE_OPTICAL) {
2301 KdPrint2((PRINT_PREFIX "IssueIdentify: Device is CD/Optical drive.\n"));
2302 // set CD default costs
2306 statusByte = WaitForDrq(chan);
2307 } else {
2308 KdPrint2((PRINT_PREFIX "IssueIdentify: ATAPI drive type %#x.\n",
2309 LunExt->IdentifyData.DeviceType));
2310 }
2311 KdPrint2((PRINT_PREFIX "IssueIdentify: AtapiCmdSize %#x\n", deviceExtension->FullIdentifyData.AtapiCmdSize));
2312 } else {
2313 KdPrint2((PRINT_PREFIX "IssueIdentify: hard drive.\n"));
2314 }
2315
2316 GetBaseStatus(chan, statusByte);
2317 KdPrint2((PRINT_PREFIX "IssueIdentify: final Status on exit (%#x)\n", statusByte));
2318 return TRUE;
2319
2320} // end IssueIdentify()
2321
2322
2323/*++
2324
2325Routine Description:
2326 Set drive parameters using the IDENTIFY data.
2327
2328Arguments:
2329 HwDeviceExtension - HBA miniport driver's adapter data storage
2330 DeviceNumber - Indicates which device.
2331
2332Return Value:
2333 TRUE if all goes well.
2334
2335--*/
2336BOOLEAN
2337NTAPI
2339 IN PVOID HwDeviceExtension,
2341 IN ULONG lChannel
2342 )
2343{
2344 PHW_DEVICE_EXTENSION deviceExtension = (PHW_DEVICE_EXTENSION)HwDeviceExtension;
2345 PIDENTIFY_DATA2 identifyData;
2346 PHW_LU_EXTENSION LunExt;
2347// ULONG i;
2348 UCHAR statusByte;
2349 UCHAR errorByte;
2350
2351 LunExt = deviceExtension->chan[lChannel].lun[DeviceNumber];
2352 identifyData = &(LunExt->IdentifyData);
2353
2354 if(LunExt->DeviceFlags &
2356 return TRUE;
2357
2358 KdPrint2((PRINT_PREFIX "SetDriveParameters: Number of heads %#x\n", identifyData->NumberOfHeads));
2359 KdPrint2((PRINT_PREFIX "SetDriveParameters: Sectors per track %#x\n", identifyData->SectorsPerTrack));
2360
2361 // Send SET PARAMETER command.
2362 statusByte = AtaCommand(deviceExtension, DeviceNumber, lChannel,
2364 (identifyData->NumberOfHeads - 1), 0,
2365 (UCHAR)identifyData->SectorsPerTrack, 0, ATA_WAIT_IDLE);
2366
2367 statusByte = UniataIsIdle(deviceExtension, statusByte);
2368 if(statusByte & IDE_STATUS_ERROR) {
2369 errorByte = AtapiReadPort1(&deviceExtension->chan[lChannel], IDX_IO1_i_Error);
2370 KdPrint2((PRINT_PREFIX "SetDriveParameters: Error bit set. Status %#x, error %#x\n",
2371 errorByte, statusByte));
2372 return FALSE;
2373 }
2374
2375 if(statusByte == IDE_STATUS_IDLE) {
2376 return TRUE;
2377 }
2378
2379 return FALSE;
2380
2381} // end SetDriveParameters()
2382
2383VOID
2384NTAPI
2386 PHW_LU_EXTENSION LunExt
2387 )
2388{
2389 // keep only DFLAGS_HIDDEN flag
2390 LunExt->DeviceFlags &= DFLAGS_HIDDEN;
2391 LunExt->AtapiReadyWaitDelay = 0;
2392} // end UniataForgetDevice()
2393
2394
2395/*++
2396
2397Routine Description:
2398 Reset IDE controller and/or Atapi device.
2399 ->HwResetBus
2400
2401Arguments:
2402 HwDeviceExtension - HBA miniport driver's adapter data storage
2403
2404Return Value:
2405 Nothing.
2406
2407
2408--*/
2409BOOLEAN
2410NTAPI
2412 IN PVOID HwDeviceExtension,
2414 )
2415{
2416 KdPrint2((PRINT_PREFIX "AtapiResetController(%x)\n", PathId));
2417 return AtapiResetController__(HwDeviceExtension, PathId, RESET_COMPLETE_ALL);
2418} // end AtapiResetController()
2419
2420BOOLEAN
2421NTAPI
2423 IN PVOID HwDeviceExtension,
2424 IN ULONG PathId,
2425 IN BOOLEAN CompleteType
2426 )
2427{
2428 PHW_DEVICE_EXTENSION deviceExtension = (PHW_DEVICE_EXTENSION)HwDeviceExtension;
2429 ULONG numberChannels = deviceExtension->NumberChannels;
2430 PHW_CHANNEL chan = NULL;
2431 ULONG i,j;
2432 ULONG MaxLuns;
2433 UCHAR statusByte;
2434 PSCSI_REQUEST_BLOCK CurSrb;
2435 ULONG ChannelCtrlFlags;
2436 UCHAR dma_status = 0;
2437
2438 ULONG slotNumber = deviceExtension->slotNumber;
2439 ULONG SystemIoBusNumber = deviceExtension->SystemIoBusNumber;
2440 ULONG VendorID = deviceExtension->DevID & 0xffff;
2441#ifdef _DEBUG
2442 ULONG DeviceID = (deviceExtension->DevID >> 16) & 0xffff;
2443#endif
2444 //ULONG RevID = deviceExtension->RevID;
2445 ULONG ChipFlags = deviceExtension->HwFlags & CHIPFLAG_MASK;
2446 //UCHAR tmp8;
2447 USHORT tmp16;
2448
2449 KdPrint2((PRINT_PREFIX "AtapiResetController: Reset IDE %#x/%#x @ %#x\n", VendorID, DeviceID, slotNumber));
2450 KdPrint2((PRINT_PREFIX "simplexOnly %d, VM %x\n", deviceExtension->simplexOnly, g_opt_VirtualMachine));
2451
2452 if(!deviceExtension->simplexOnly && (PathId != CHAN_NOT_SPECIFIED)) {
2453 // we shall reset both channels on SimplexOnly devices,
2454 // It's not worth doing so on normal controllers
2455 j = PathId;
2456 numberChannels = min(j+1, deviceExtension->NumberChannels);
2457 } else {
2458 j=0;
2459 numberChannels = deviceExtension->NumberChannels;
2460 }
2461
2462 for (; j < numberChannels; j++) {
2463
2464 KdPrint2((PRINT_PREFIX "AtapiResetController: Reset lchannel %d[%d]\n", j, deviceExtension->Channel));
2465 chan = &(deviceExtension->chan[j]);
2466 MaxLuns = chan->NumberLuns;
2467 // Save control flags
2468 ChannelCtrlFlags = chan->ChannelCtrlFlags;
2469 KdPrint2((PRINT_PREFIX " CompleteType %#x, Luns %d, chan %#x, sptr %#x, flags %#x\n", CompleteType, MaxLuns, chan, &chan, ChannelCtrlFlags));
2470 //MaxLuns = (chan->ChannelCtrlFlags & CTRFLAGS_NO_SLAVE) ? 1 : 2;
2471 if(CompleteType != RESET_COMPLETE_NONE) {
2472#ifndef UNIATA_CORE
2473 while((CurSrb = UniataGetCurRequest(chan))) {
2474
2475 PHW_LU_EXTENSION LunExt;
2476 PATA_REQ AtaReq = (PATA_REQ)(CurSrb->SrbExtension);
2477
2478 i = GET_CDEV(CurSrb);
2479 KdPrint2((PRINT_PREFIX " Lun %x\n", i));
2480 LunExt = chan->lun[i];
2481
2482 KdPrint2((PRINT_PREFIX "AtapiResetController: pending SRB %#x, chan %#x\n", CurSrb, chan));
2483 if(CurSrb->Cdb[0] == SCSIOP_MECHANISM_STATUS) {
2484 KdPrint2((PRINT_PREFIX " was MechStatus\n"));
2485
2486 if(!(LunExt->DeviceFlags & DFLAGS_CHANGER_INITED)) {
2488 KdPrint2((PRINT_PREFIX " set DFLAGS_CHANGER_INITED\n"));
2489 }
2490 }
2491 // Check and see if we are processing an internal srb
2492 if (AtaReq->OriginalSrb) {
2493 KdPrint2((PRINT_PREFIX " restore original SRB %#x\n", AtaReq->OriginalSrb));
2494 AtaReq->Srb = AtaReq->OriginalSrb;
2495 CurSrb->SrbExtension = NULL;
2496 AtaReq->OriginalSrb = NULL;
2497 // NOTE: internal SRB doesn't get to SRB queue !!!
2498 CurSrb = AtaReq->Srb;
2499 }
2500
2501 // Remove current request from queue
2502 UniataRemoveRequest(chan, CurSrb);
2503
2504 // Check if request is in progress.
2505 ASSERT(AtaReq->Srb == CurSrb);
2506 if (CurSrb) {
2507 // Complete outstanding request with SRB_STATUS_BUS_RESET.
2508 UCHAR CurPathId = CurSrb->PathId;
2509 UCHAR TargetId = CurSrb->TargetId;
2510 UCHAR Lun = CurSrb->Lun;
2511
2514
2515 if (CurSrb->SenseInfoBuffer) {
2516
2517 PSENSE_DATA senseBuffer = (PSENSE_DATA)CurSrb->SenseInfoBuffer;
2518 KdPrint2((PRINT_PREFIX " senseBuffer %#x, chan %#x, ReqFlags %#x\n", senseBuffer, chan, AtaReq->Flags));
2519
2520 senseBuffer->ErrorCode = 0x70;
2521 senseBuffer->Valid = 1;
2522 senseBuffer->AdditionalSenseLength = 0xb;
2523 if(CompleteType == RESET_COMPLETE_ALL) {
2524 KdPrint2((PRINT_PREFIX "AtapiResetController: report SCSI_SENSE_UNIT_ATTENTION + SCSI_ADSENSE_BUS_RESET\n"));
2525 senseBuffer->SenseKey = SCSI_SENSE_UNIT_ATTENTION;
2528 } else {
2529 KdPrint2((PRINT_PREFIX "AtapiResetController: report SCSI_SENSE_ABORTED_COMMAND\n"));
2530 senseBuffer->SenseKey = SCSI_SENSE_ABORTED_COMMAND;
2531 senseBuffer->AdditionalSenseCode = 0;
2532 senseBuffer->AdditionalSenseCodeQualifier = 0;
2533 }
2534 }
2535
2536 if(!ATAPI_DEVICE(chan, i) && AtaReq->bcount && AtaReq->retry < MAX_RETRIES) {
2537 KdPrint2((PRINT_PREFIX "Save IDE retry status %d\n", AtaReq->retry));
2538 LunExt->errLastLba = AtaReq->lba;
2539 LunExt->errBCount = AtaReq->bcount;
2540 LunExt->errRetry = AtaReq->retry+1;
2541 //KdPrint2((PRINT_PREFIX "AtaReq->Flags & REQ_FLAG_RW_MASK = %x (%x)\n", (AtaReq->Flags & REQ_FLAG_RW_MASK), REQ_FLAG_READ));
2542 //KdPrint2((PRINT_PREFIX "ChannelCtrlFlags & CTRFLAGS_DMA_OPERATION = %x (%x)\n", ChannelCtrlFlags & CTRFLAGS_DMA_ACTIVE, CTRFLAGS_DMA_OPERATION));
2543 //KdPrint2((PRINT_PREFIX "g_opt_VirtualMachine = %x (%x)\n", g_opt_VirtualMachine, VM_BOCHS));
2544 if(((AtaReq->Flags & REQ_FLAG_RW_MASK) == REQ_FLAG_READ) &&
2545 (ChannelCtrlFlags & CTRFLAGS_DMA_OPERATION) &&
2547 KdPrint2((PRINT_PREFIX "set CTRFLAGS_DMA_BEFORE_R on BOCHS\n"));
2550 } else {
2551 KdPrint2((PRINT_PREFIX "do nothing\n"));
2552 }
2553 } else
2554 if(ATAPI_DEVICE(chan, i) && AtaReq->bcount && !AtaReq->retry) {
2555 KdPrint2((PRINT_PREFIX "Save ATAPI retry status %d\n", AtaReq->retry));
2556 LunExt->errLastLba = AtaReq->lba;
2557 LunExt->errBCount = AtaReq->bcount;
2558 LunExt->errRetry = AtaReq->retry+1;
2559 if(((AtaReq->Flags & REQ_FLAG_RW_MASK) == REQ_FLAG_READ) &&
2560 (ChannelCtrlFlags & CTRFLAGS_DMA_OPERATION) &&
2562 KdPrint2((PRINT_PREFIX "set CTRFLAGS_DMA_BEFORE_R on BOCHS ATAPI\n"));
2563 //g_opt_BochsDmaReadWorkaround = TRUE;
2565 } else {
2566 KdPrint2((PRINT_PREFIX "do nothing\n"));
2567 }
2568 } else {
2569 LunExt->errRetry = 0;
2570 }
2571
2572 // Clear request tracking fields.
2573 AtaReq->WordsLeft = 0;
2574 AtaReq->DataBuffer = NULL;
2575 AtaReq->TransferLength = 0;
2576 KdPrint2((PRINT_PREFIX "chan %#x\n", chan));
2577
2579 deviceExtension,
2580 CurSrb);
2581
2582 // Indicate ready for next request.
2584 deviceExtension,
2585 CurPathId,
2586 TargetId,
2587 Lun);
2588 }
2589 if(CompleteType != RESET_COMPLETE_ALL)
2590 break;
2591 } // end while()
2592#endif //UNIATA_CORE
2593 } // end if (!CompleteType != RESET_COMPLETE_NONE)
2594
2595 // Clear expecting interrupt flag.
2597 chan->RDP = FALSE;
2598 chan->ChannelCtrlFlags = ChannelCtrlFlags & CTRFLAGS_PERMANENT;
2601
2602 for (i = 0; i < MaxLuns; i++) {
2603 chan->lun[i]->PowerState = 0;
2604 }
2605 // Reset controller
2606 if(ChipFlags & UNIATA_AHCI) {
2607 KdPrint2((PRINT_PREFIX " AHCI path\n"));
2608 if(UniataAhciChanImplemented(deviceExtension, j)) {
2609#ifdef _DEBUG
2610 UniataDumpAhciPortRegs(chan);
2611#endif
2612 AtapiDisableInterrupts(deviceExtension, j);
2613 UniataAhciReset(HwDeviceExtension, j);
2614 } else {
2615 KdPrint2((PRINT_PREFIX " skip not implemented\n"));
2616 continue;
2617 }
2618 } else {
2619 KdPrint2((PRINT_PREFIX " ATA path, chan %#x\n", chan));
2620 KdPrint2((PRINT_PREFIX " disable intr (0)\n"));
2621 AtapiDisableInterrupts(deviceExtension, j);
2622 KdPrint2((PRINT_PREFIX " done\n"));
2623 switch(VendorID) {
2624 case ATA_INTEL_ID: {
2625 ULONG mask;
2626 ULONG pshift;
2627 ULONG timeout;
2628 if(!(ChipFlags & UNIATA_SATA)) {
2629 goto default_reset;
2630 }
2631 if(!UniataIsSATARangeAvailable(deviceExtension, j)) {
2632 goto default_reset;
2633 }
2634
2635#if 0
2636 /* ICH6 & ICH7 in compat mode has 4 SATA ports as master/slave on 2 ch's */
2637 if(ChipFlags & UNIATA_AHCI) {
2638 mask = 0x0005 << j;
2639 } else {
2640 /* ICH5 in compat mode has SATA ports as master/slave on 1 channel */
2641 GetPciConfig1(0x90, tmp8);
2642 if(tmp8 & 0x04) {
2643 mask = 0x0003;
2644 } else {
2645 mask = 0x0001 << j;
2646 }
2647 }
2648#else
2649 mask = 1 << chan->lun[0]->SATA_lun_map;
2650 if (MaxLuns > 1) {
2651 mask |= (1 << chan->lun[1]->SATA_lun_map);
2652 }
2653#endif
2654 ChangePciConfig2(0x92, a & ~mask);
2656 ChangePciConfig2(0x92, a | mask);
2657 timeout = 100;
2658
2659 /* Wait up to 1 sec for "connect well". */
2660 if (ChipFlags & (I6CH | I6CH2)) {
2661 pshift = 8;
2662 } else {
2663 pshift = 4;
2664 }
2665 while (timeout--) {
2666 GetPciConfig2(0x92, tmp16);
2667 if (((tmp16 >> pshift) & mask) == mask) {
2668 GetBaseStatus(chan, statusByte);
2669 if(statusByte != IDE_STATUS_WRONG) {
2670 break;
2671 }
2672 }
2673 AtapiStallExecution(10000);
2674 }
2675 break; }
2676 case ATA_SIS_ID: {
2677 KdPrint2((PRINT_PREFIX " SIS\n"));
2678 if(!(ChipFlags & UNIATA_SATA))
2679 goto default_reset;
2680 break; }
2681#if 0
2682 case ATA_NVIDIA_ID: {
2683 KdPrint2((PRINT_PREFIX " nVidia\n"));
2684 if(!(ChipFlags & UNIATA_SATA))
2685 goto default_reset;
2686 break; }
2687#else
2688 case ATA_NVIDIA_ID: {
2689 ULONG offs;
2690 ULONG Channel = deviceExtension->Channel + j;
2691 KdPrint2((PRINT_PREFIX " nVidia\n"));
2692 if(!(ChipFlags & UNIATA_SATA)) {
2693 goto default_reset;
2694 }
2695 offs = (ChipFlags & NV4OFF) ? 0x0440 : 0x0010;
2696
2697 KdPrint2((PRINT_PREFIX " disable Phy intr, offs %#x, c %u\n", offs, Channel));
2698 /* disable device and PHY state change interrupts */
2699 if(ChipFlags & NVQ) {
2700 KdPrint2((PRINT_PREFIX " NVQ, 32bits reg\n"));
2701 AtapiWritePortEx4(NULL, (ULONGIO_PTR)(&deviceExtension->BaseIoAddressSATA_0),offs+4,
2702 AtapiReadPortEx4(NULL, (ULONGIO_PTR)(&deviceExtension->BaseIoAddressSATA_0),offs+4) & ((~(ULONG)0x0000000d) << (!Channel*16)) );
2703 } else {
2704 AtapiWritePortEx1(NULL, (ULONGIO_PTR)(&deviceExtension->BaseIoAddressSATA_0),offs+1,
2705 AtapiReadPortEx1(NULL, (ULONGIO_PTR)(&deviceExtension->BaseIoAddressSATA_0),offs+1) & ((~(UCHAR)0x0d) << (!Channel*4)) );
2706 }
2707 tmp16 = UniataSataPhyEnable(HwDeviceExtension, j, 0/* dev0*/, UNIATA_SATA_RESET_ENABLE);
2708
2709 KdPrint2((PRINT_PREFIX " enable Phy intr, offs %#x\n", offs));
2710 /* enable device and PHY state change interrupts */
2711 if(ChipFlags & NVQ) {
2712 AtapiWritePortEx4(NULL, (ULONGIO_PTR)(&deviceExtension->BaseIoAddressSATA_0),offs+4,
2713 AtapiReadPortEx4(NULL, (ULONGIO_PTR)(&deviceExtension->BaseIoAddressSATA_0),offs+4) | (((ULONG)0x0000000d) << (!Channel*16)) );
2714 } else {
2715 AtapiWritePortEx1(NULL, (ULONGIO_PTR)(&deviceExtension->BaseIoAddressSATA_0),offs+1,
2716 AtapiReadPortEx1(NULL, (ULONGIO_PTR)(&deviceExtension->BaseIoAddressSATA_0),offs+1) | (((UCHAR)0x0d) << (!Channel*4)) );
2717 }
2718
2719 KdPrint2((PRINT_PREFIX " dev status %#x\n", tmp16));
2720 if(tmp16 != IDE_STATUS_WRONG) {
2721 goto default_reset;
2722 }
2723 break; }
2724#endif //0
2725 case ATA_SILICON_IMAGE_ID: {
2726 ULONG offset;
2727 ULONG Channel = deviceExtension->Channel + j;
2728 if(!(ChipFlags & UNIATA_SATA))
2729 goto default_reset;
2730 offset = ((Channel & 1) << 7) + ((Channel & 2) << 8);
2731 /* disable PHY state change interrupt */
2732 AtapiWritePortEx4(NULL, (ULONGIO_PTR)(&deviceExtension->BaseIoAddressSATA_0), 0x148 + offset, 0);
2733
2734 UniataSataClearErr(HwDeviceExtension, j, UNIATA_SATA_IGNORE_CONNECT, 0);
2735
2736 /* reset controller part for this channel */
2737 AtapiWritePortEx4(NULL, (ULONGIO_PTR)(&deviceExtension->BaseIoAddressSATA_0), 0x48,
2738 AtapiReadPortEx4(NULL, (ULONGIO_PTR)(&deviceExtension->BaseIoAddressSATA_0), 0x48) | (0xc0 >> Channel));
2739 AtapiStallExecution(1000);
2740 AtapiWritePortEx4(NULL, (ULONGIO_PTR)(&deviceExtension->BaseIoAddressSATA_0), 0x48,
2741 AtapiReadPortEx4(NULL, (ULONGIO_PTR)(&deviceExtension->BaseIoAddressSATA_0), 0x48) & ~(0xc0 >> Channel));
2742
2743
2744 break; }
2745 case ATA_PROMISE_ID: {
2746 break; }
2747 default:
2748 if(ChipFlags & UNIATA_SATA) {
2749 KdPrint2((PRINT_PREFIX " SATA generic reset\n"));
2750 UniataSataClearErr(HwDeviceExtension, j, UNIATA_SATA_IGNORE_CONNECT, 0);
2751 }
2752default_reset:
2753/*
2754 AtapiWritePort1(chan, IDX_IO2_o_Control, IDE_DC_DISABLE_INTERRUPTS |
2755 IDE_DC_RESET_CONTROLLER );
2756 chan->last_devsel = -1;
2757 KdPrint2((PRINT_PREFIX " wait a little\n"));
2758 AtapiStallExecution(10000);
2759 // Disable interrupts
2760 KdPrint2((PRINT_PREFIX " disable intr\n"));
2761 AtapiDisableInterrupts(deviceExtension, j);
2762 AtapiStallExecution(100);
2763 KdPrint2((PRINT_PREFIX " re-enable intr\n"));
2764 AtapiEnableInterrupts(deviceExtension, j);
2765 KdPrint2((PRINT_PREFIX " wait a little (2)\n"));
2766 AtapiStallExecution(100000);
2767*/
2768 AtapiHardReset(chan, TRUE, 100000);
2769 KdPrint2((PRINT_PREFIX " disable intr\n"));
2770 AtapiDisableInterrupts(deviceExtension, j);
2772 KdPrint2((PRINT_PREFIX " re-enable intr\n"));
2773 AtapiEnableInterrupts(deviceExtension, j);
2774 KdPrint2((PRINT_PREFIX " done\n"));
2775
2776 break;
2777 } // end switch()
2778
2779 //if(!(ChipFlags & UNIATA_SATA)) {}
2780 if(!UniataIsSATARangeAvailable(deviceExtension, j)) {
2781 // Reset DMA engine if active
2782 KdPrint2((PRINT_PREFIX " check DMA engine\n"));
2783 dma_status = GetDmaStatus(chan->DeviceExtension, chan->lChannel);
2784 KdPrint2((PRINT_PREFIX " DMA status %#x\n", dma_status));
2785 if((ChannelCtrlFlags & CTRFLAGS_DMA_ACTIVE) ||
2786 (dma_status & BM_STATUS_INTR)) {
2787 AtapiDmaDone(HwDeviceExtension, 0, j, NULL);
2788 }
2789 }
2790 } // ATA vs AHCI
2791
2792 // all these shall be performed inside AtapiHwInitialize__() ?
2793#if 1
2794 KdPrint2((PRINT_PREFIX " process connected devices 0 - %d\n", MaxLuns-1));
2795 // Do special processing for ATAPI and IDE disk devices.
2796 for (i = 0; i < MaxLuns; i++) {
2797
2798 // Check if device present.
2799 KdPrint2((PRINT_PREFIX " Chan %#x\n", chan));
2800 KdPrint2((PRINT_PREFIX " Lun %#x\n", i));
2801 KdPrint2((PRINT_PREFIX " Lun ptr %#x\n", chan->lun[i]));
2802 if (!(chan->lun[i]->DeviceFlags & DFLAGS_DEVICE_PRESENT)) {
2803 if(ChipFlags & UNIATA_AHCI) {
2804 // everything is done in UniataAhciReset()
2805 KdPrint2((PRINT_PREFIX " device have gone\n"));
2806 continue;
2807 }
2808#ifdef NAVO_TEST
2809 continue;
2810#else //NAVO_TEST
2811 //if(!CheckDevice(HwDeviceExtension, i, j, FALSE))
2812 if(!UniataAnybodyHome(HwDeviceExtension, j, i)) {
2813 continue;
2814 }
2815 if(!CheckDevice(HwDeviceExtension, j, i, TRUE)) {
2816 continue;
2817 }
2818 } else {
2819 if(ChipFlags & UNIATA_AHCI) {
2820 // everything is done in UniataAhciReset()
2821 KdPrint2((PRINT_PREFIX " found some device\n"));
2822
2823 if(!IssueIdentify(HwDeviceExtension,
2824 i, j,
2825 ATAPI_DEVICE(chan, i) ?
2827 FALSE)) {
2828 KdPrint2((PRINT_PREFIX " identify failed !\n"));
2829 UniataForgetDevice(chan->lun[i]);
2830 }
2831 continue;
2832 }
2833 if(!UniataAnybodyHome(HwDeviceExtension, j, i)) {
2834 KdPrint2((PRINT_PREFIX " device have gone\n"));
2835 UniataForgetDevice(chan->lun[i]);
2836 }
2837#endif //NAVO_TEST
2838 }
2839
2840 SelectDrive(chan, i);
2842 statusByte = WaitOnBusyLong(chan);
2843 statusByte = UniataIsIdle(deviceExtension, statusByte);
2844 if(statusByte == IDE_STATUS_WRONG) {
2846 "no drive, status %#x\n",
2847 statusByte));
2848 UniataForgetDevice(chan->lun[i]);
2849 } else
2850 // Check for ATAPI disk.
2851 if (ATAPI_DEVICE(chan, i)) {
2852 // Issue soft reset and issue identify.
2853 GetStatus(chan, statusByte);
2854 KdPrint2((PRINT_PREFIX "AtapiResetController: Status before Atapi reset (%#x).\n",
2855 statusByte));
2856
2857 AtapiDisableInterrupts(deviceExtension, j);
2858 AtapiSoftReset(chan, i);
2859 AtapiEnableInterrupts(deviceExtension, j);
2860
2861 GetStatus(chan, statusByte);
2862
2863 if(statusByte != IDE_STATUS_SUCCESS) {
2864 ULONG k;
2865 k = UniataAnybodyHome(deviceExtension, j, i);
2866 if(k == ATA_AT_HOME_HDD) {
2867 // device reset in progress, perform additional wait
2868 KdPrint2((PRINT_PREFIX " long reset, wait up to 4.5 s\n"));
2869 k = 30 * 1000;
2871 k--)
2872 {
2874 }
2875 KdPrint2((PRINT_PREFIX " exit after %u loops\n", k));
2876 GetStatus(chan, statusByte);
2877 }
2878 }
2879 if(statusByte == IDE_STATUS_SUCCESS) {
2880
2881 IssueIdentify(HwDeviceExtension,
2882 i, j,
2884 } else {
2885
2887 "AtapiResetController: Status after soft reset %#x\n",
2888 statusByte));
2889 }
2890 GetBaseStatus(chan, statusByte);
2891
2892 } else {
2893 // Issue identify and reinit after channel reset.
2894
2895 if (statusByte != IDE_STATUS_IDLE &&
2896 statusByte != IDE_STATUS_SUCCESS &&
2897 statusByte != IDE_STATUS_DRDY) {
2898// result2 = FALSE;
2899 KdPrint2((PRINT_PREFIX "AtapiResetController: IdeHardReset failed\n"));
2900 } else
2901 if(!IssueIdentify(HwDeviceExtension,
2902 i, j,
2904// result2 = FALSE;
2905 KdPrint2((PRINT_PREFIX "AtapiResetController: IDE IssueIdentify failed\n"));
2906 } else
2907 // Set disk geometry parameters.
2908 if (!SetDriveParameters(HwDeviceExtension, i, j)) {
2909 KdPrint2((PRINT_PREFIX "AtapiResetController: SetDriveParameters failed\n"));
2910 }
2911 GetBaseStatus(chan, statusByte);
2912 }
2913 // force DMA mode reinit
2914 KdPrint2((PRINT_PREFIX " set DFLAGS_REINIT_DMA\n"));
2915 chan->lun[i]->DeviceFlags |= DFLAGS_REINIT_DMA;
2916 }
2917#endif //0
2918
2919 // Enable interrupts, note, we can have here recursive disable
2921 KdPrint2((PRINT_PREFIX "AtapiResetController: deviceExtension->chan[%d].DisableIntr %d -> 1\n",
2922 j,
2923 chan->DisableIntr));
2924 AtapiEnableInterrupts(deviceExtension, j);
2925
2926 // Call the HwInitialize routine to setup multi-block.
2927 AtapiHwInitialize__(deviceExtension, j);
2928 } // for(channel)
2929 ScsiPortNotification(NextRequest, deviceExtension, NULL);
2930
2931 return TRUE;
2932
2933} // end AtapiResetController__()
2934
2935
2936/*++
2937
2938Routine Description:
2939 This routine maps ATAPI and IDE errors to specific SRB statuses.
2940
2941Arguments:
2942 HwDeviceExtension - HBA miniport driver's adapter data storage
2943 Srb - IO request packet
2944
2945Return Value:
2946 SRB status
2947
2948--*/
2949ULONG
2950NTAPI
2952 IN PVOID HwDeviceExtension,
2954 )
2955{
2956 PHW_DEVICE_EXTENSION deviceExtension = (PHW_DEVICE_EXTENSION)HwDeviceExtension;
2957 ULONG lChannel = GET_CHANNEL(Srb);
2958 PHW_CHANNEL chan = &(deviceExtension->chan[lChannel]);
2959// ULONG i;
2960 UCHAR errorByte = 0;
2961 UCHAR srbStatus = SRB_STATUS_SUCCESS;
2962 UCHAR scsiStatus;
2964 PHW_LU_EXTENSION LunExt = chan->lun[DeviceNumber];
2965
2966 // Read the error register.
2967
2968 if(deviceExtension->HwFlags & UNIATA_AHCI) {
2969 PATA_REQ AtaReq = (PATA_REQ)(Srb->SrbExtension);
2970 if(AtaReq) {
2971 errorByte = AtaReq->ahci.in_error;
2972 } else {
2973 }
2974 } else {
2975 errorByte = AtapiReadPort1(chan, IDX_IO1_i_Error);
2976 }
2978 "MapError: Error register is %#x\n",
2979 errorByte));
2980
2981 if (LunExt->DeviceFlags & DFLAGS_ATAPI_DEVICE) {
2982
2983 switch (errorByte >> 4) {
2985
2987 "ATAPI: No sense information\n"));
2988 scsiStatus = SCSISTAT_CHECK_CONDITION;
2989 srbStatus = SRB_STATUS_ERROR;
2990 break;
2991
2993
2995 "ATAPI: Recovered error\n"));
2996 scsiStatus = 0;
2997 srbStatus = SRB_STATUS_SUCCESS;
2998 break;
2999
3001
3003 "ATAPI: Device not ready\n"));
3004 scsiStatus = SCSISTAT_CHECK_CONDITION;
3005 srbStatus = SRB_STATUS_ERROR;
3006 break;
3007
3009
3011 "ATAPI: Media error\n"));
3012 scsiStatus = SCSISTAT_CHECK_CONDITION;
3013 srbStatus = SRB_STATUS_ERROR;
3014 break;
3015
3017
3019 "ATAPI: Hardware error\n"));
3020 scsiStatus = SCSISTAT_CHECK_CONDITION;
3021 srbStatus = SRB_STATUS_ERROR;
3022 break;
3023
3025
3027 "ATAPI: Illegal request\n"));
3028 scsiStatus = SCSISTAT_CHECK_CONDITION;
3029 srbStatus = SRB_STATUS_ERROR;
3030 break;
3031
3033
3035 "ATAPI: Unit attention\n"));
3036 scsiStatus = SCSISTAT_CHECK_CONDITION;
3037 srbStatus = SRB_STATUS_ERROR;
3038 break;
3039
3041
3043 "ATAPI: Data protect\n"));
3044 scsiStatus = SCSISTAT_CHECK_CONDITION;
3045 srbStatus = SRB_STATUS_ERROR;
3046 break;
3047
3049
3051 "ATAPI: Blank check\n"));
3052 scsiStatus = SCSISTAT_CHECK_CONDITION;
3053 srbStatus = SRB_STATUS_ERROR;
3054 break;
3055
3058 "Atapi: Command Aborted\n"));
3059 scsiStatus = SCSISTAT_CHECK_CONDITION;
3060 srbStatus = SRB_STATUS_ERROR;
3061 break;
3062
3063 default:
3064
3066 "ATAPI: Invalid sense information\n"));
3067 scsiStatus = 0;
3068 srbStatus = SRB_STATUS_ERROR;
3069 break;
3070 }
3071
3072 } else {
3073
3074 scsiStatus = 0;
3075
3076 // Save errorByte,to be used by SCSIOP_REQUEST_SENSE.
3077 chan->ReturningMediaStatus = errorByte;
3078
3079 if (errorByte & IDE_ERROR_MEDIA_CHANGE_REQ) {
3081 "IDE: Media change\n"));
3082 scsiStatus = SCSISTAT_CHECK_CONDITION;
3083 srbStatus = SRB_STATUS_ERROR;
3084
3085 if (Srb->SenseInfoBuffer) {
3086
3088
3089 senseBuffer->ErrorCode = 0x70;
3090 senseBuffer->Valid = 1;
3091 senseBuffer->AdditionalSenseLength = 0xb;
3092 senseBuffer->SenseKey = SCSI_SENSE_UNIT_ATTENTION;
3094 senseBuffer->AdditionalSenseCodeQualifier = 0;
3095
3096 srbStatus |= SRB_STATUS_AUTOSENSE_VALID;
3097 }
3098
3099 } else if (errorByte & IDE_ERROR_COMMAND_ABORTED) {
3101 "IDE: Command abort\n"));
3102 srbStatus = SRB_STATUS_ABORTED;
3103 scsiStatus = SCSISTAT_CHECK_CONDITION;
3104
3105 if (Srb->SenseInfoBuffer) {
3106
3108
3109 senseBuffer->ErrorCode = 0x70;
3110 senseBuffer->Valid = 1;
3111 senseBuffer->AdditionalSenseLength = 0xb;
3112 senseBuffer->SenseKey = SCSI_SENSE_ABORTED_COMMAND;
3113 senseBuffer->AdditionalSenseCode = 0;
3114 senseBuffer->AdditionalSenseCodeQualifier = 0;
3115
3116 srbStatus |= SRB_STATUS_AUTOSENSE_VALID;
3117 }
3118
3119 LunExt->ErrorCount++;
3120
3121 } else if (errorByte & IDE_ERROR_END_OF_MEDIA) {
3122
3124 "IDE: End of media\n"));
3125 scsiStatus = SCSISTAT_CHECK_CONDITION;
3126 srbStatus = SRB_STATUS_ERROR;
3127
3128 if (Srb->SenseInfoBuffer) {
3129
3131
3132 senseBuffer->ErrorCode = 0x70;
3133 senseBuffer->Valid = 1;
3134 senseBuffer->AdditionalSenseLength = 0xb;
3135 senseBuffer->SenseKey = SCSI_SENSE_UNIT_ATTENTION;
3138 senseBuffer->EndOfMedia = 1;
3139
3140 srbStatus |= SRB_STATUS_AUTOSENSE_VALID;
3141 }
3142
3143 if (!(LunExt->DeviceFlags & DFLAGS_MEDIA_STATUS_ENABLED)){
3144 LunExt->ErrorCount++;
3145 }
3146
3147 } else if (errorByte & IDE_ERROR_ILLEGAL_LENGTH) {
3148
3150 "IDE: Illegal length\n"));
3151 srbStatus = SRB_STATUS_INVALID_REQUEST;
3152
3153 if (Srb->SenseInfoBuffer) {
3154
3156
3157 senseBuffer->ErrorCode = 0x70;
3158 senseBuffer->Valid = 1;
3159 senseBuffer->AdditionalSenseLength = 0xb;
3160 senseBuffer->SenseKey = SCSI_SENSE_ILLEGAL_REQUEST;
3163 senseBuffer->IncorrectLength = 1;
3164
3165 srbStatus |= SRB_STATUS_AUTOSENSE_VALID;
3166 }
3167
3168 } else if (errorByte & IDE_ERROR_BAD_BLOCK) {
3169
3171 "IDE: Bad block\n"));
3172 srbStatus = SRB_STATUS_ERROR;
3173 scsiStatus = SCSISTAT_CHECK_CONDITION;
3174 if (Srb->SenseInfoBuffer) {
3175
3177
3178 senseBuffer->ErrorCode = 0x70;
3179 senseBuffer->Valid = 1;
3180 senseBuffer->AdditionalSenseLength = 0xb;
3181 senseBuffer->SenseKey = SCSI_SENSE_MEDIUM_ERROR;
3182 senseBuffer->AdditionalSenseCode = 0;
3183 senseBuffer->AdditionalSenseCodeQualifier = 0;
3184
3185 srbStatus |= SRB_STATUS_AUTOSENSE_VALID;
3186 }
3187
3188 } else if (errorByte & IDE_ERROR_ID_NOT_FOUND) {
3189
3191 "IDE: Id not found\n"));
3192 srbStatus = SRB_STATUS_ERROR;
3193 scsiStatus = SCSISTAT_CHECK_CONDITION;
3194
3195 if (Srb->SenseInfoBuffer) {
3196
3198
3199 senseBuffer->ErrorCode = 0x70;
3200 senseBuffer->Valid = 1;
3201 senseBuffer->AdditionalSenseLength = 0xb;
3202 senseBuffer->SenseKey = SCSI_SENSE_MEDIUM_ERROR;
3203 senseBuffer->AdditionalSenseCode = 0;
3204 senseBuffer->AdditionalSenseCodeQualifier = 0;
3205
3206 srbStatus |= SRB_STATUS_AUTOSENSE_VALID;
3207 }
3208
3209 LunExt->ErrorCount++;
3210
3211 } else if (errorByte & IDE_ERROR_MEDIA_CHANGE) {
3212
3214 "IDE: Media change\n"));
3215 scsiStatus = SCSISTAT_CHECK_CONDITION;
3216 srbStatus = SRB_STATUS_ERROR;
3217
3218 if (Srb->SenseInfoBuffer) {
3219
3221
3222 senseBuffer->ErrorCode = 0x70;
3223 senseBuffer->Valid = 1;
3224 senseBuffer->AdditionalSenseLength = 0xb;
3225 senseBuffer->SenseKey = SCSI_SENSE_UNIT_ATTENTION;
3227 senseBuffer->AdditionalSenseCodeQualifier = 0;
3228
3229 srbStatus |= SRB_STATUS_AUTOSENSE_VALID;
3230 }
3231
3232 } else if (errorByte & IDE_ERROR_DATA_ERROR) {
3233
3235 "IDE: Data error\n"));
3236 scsiStatus = SCSISTAT_CHECK_CONDITION;
3237 srbStatus = SRB_STATUS_ERROR;
3238
3239 if (!(LunExt->DeviceFlags & DFLAGS_MEDIA_STATUS_ENABLED)){
3240 LunExt->ErrorCount++;
3241 }
3242
3243 // Build sense buffer
3244 if (Srb->SenseInfoBuffer) {
3245
3247
3248 senseBuffer->ErrorCode = 0x70;
3249 senseBuffer->Valid = 1;
3250 senseBuffer->AdditionalSenseLength = 0xb;
3251 senseBuffer->SenseKey = SCSI_SENSE_MEDIUM_ERROR;
3252 senseBuffer->AdditionalSenseCode = 0;
3253 senseBuffer->AdditionalSenseCodeQualifier = 0;
3254
3255 srbStatus |= SRB_STATUS_AUTOSENSE_VALID;
3256 }
3257 }
3258
3259 if (LunExt->ErrorCount >= MAX_ERRORS) {
3260// deviceExtension->DWordIO = FALSE;
3261
3263 "MapError: ErrorCount >= MAX_ERRORS\n"));
3264
3265 LunExt->DeviceFlags &= ~DFLAGS_DWORDIO_ENABLED;
3266 LunExt->MaximumBlockXfer = 0;
3267 BrutePoint();
3268
3270 "MapError: Disabling 32-bit PIO and Multi-sector IOs\n"));
3271
3272 // Log the error.
3274 "ScsiPortLogError: devExt %#x, Srb %#x, P:T:D=%d:%d:%d, MsgId %#x (%d)\n",
3275 HwDeviceExtension,
3276 Srb,
3277 Srb->PathId,
3278 Srb->TargetId,
3279 Srb->Lun,
3281 4
3282 ));
3283 ScsiPortLogError( HwDeviceExtension,
3284 Srb,
3285 Srb->PathId,
3286 Srb->TargetId,
3287 Srb->Lun,
3289 4);
3290
3291 // Reprogram to not use Multi-sector.
3292 UCHAR statusByte;
3293
3294 if (LunExt->DeviceFlags & DFLAGS_DEVICE_PRESENT &&
3296
3297 statusByte = AtaCommand(deviceExtension, DeviceNumber, lChannel, IDE_COMMAND_SET_MULTIPLE, 0, 0, 0, 0, 0, ATA_WAIT_BASE_READY);
3298
3299 // Check for errors. Reset the value to 0 (disable MultiBlock) if the
3300 // command was aborted.
3301 if (statusByte & IDE_STATUS_ERROR) {
3302
3303 // Read the error register.
3304 errorByte = AtapiReadPort1(chan, IDX_IO1_i_Error);
3305
3306 KdPrint2((PRINT_PREFIX "MapError: Error setting multiple mode. Status %#x, error byte %#x\n",
3307 statusByte,
3308 errorByte));
3309
3310 // Adjust the devExt. value, if necessary.
3311 LunExt->MaximumBlockXfer = 0;
3312 BrutePoint();
3313
3314 }
3315 }
3316 }
3317 }
3318
3319 // Set SCSI status to indicate a check condition.
3320 Srb->ScsiStatus = scsiStatus;
3321
3322 return srbStatus;
3323
3324} // end MapError()
3325
3326
3327/*++
3328
3329Routine Description:
3330
3331Arguments:
3332 HwDeviceExtension - HBA miniport driver's adapter data storage
3333 ->HwInitialize
3334
3335Return Value:
3336 TRUE - if initialization successful.
3337 FALSE - if initialization unsuccessful.
3338
3339--*/
3340BOOLEAN
3341NTAPI
3343 IN PVOID HwDeviceExtension
3344 )
3345{
3346 PHW_DEVICE_EXTENSION deviceExtension = (PHW_DEVICE_EXTENSION)HwDeviceExtension;
3347 ULONG numberChannels = deviceExtension->NumberChannels;
3348 ULONG c;
3349
3350 KdPrint2((PRINT_PREFIX "AtapiHwInitialize: (base)\n"));
3351
3352 if(WinVer_WDM_Model) {
3354 }
3355 if(deviceExtension->MasterDev) {
3356 KdPrint2((PRINT_PREFIX " mark chan %d of master controller [%x] as inited\n",
3357 deviceExtension->Channel, deviceExtension->DevIndex));
3358 BMList[deviceExtension->DevIndex].ChanInitOk |= 0x01 << deviceExtension->Channel;
3359 }
3360
3361 /* do extra chipset specific setups */
3363/*
3364 if(deviceExtension->Isr2DevObj && (deviceExtension->HwFlags & UNIATA_SATA)) {
3365 KdPrint2((PRINT_PREFIX " enable ISR2 to catch unexpected interrupts\n"));
3366 BMList[deviceExtension->DevIndex].Isr2Enable = TRUE;
3367 }
3368*/
3369 for (c = 0; c < numberChannels; c++) {
3370 AtapiHwInitialize__(deviceExtension, c);
3371 }
3372 KdPrint2((PRINT_PREFIX "AtapiHwInitialize: (base) done\n"));
3373 return TRUE;
3374} // end AtapiHwInitialize()
3375
3376VOID
3377NTAPI
3379 IN PHW_DEVICE_EXTENSION deviceExtension,
3380 IN ULONG lChannel
3381 )
3382{
3383 ULONG i;
3384 UCHAR statusByte, errorByte;
3385 PHW_CHANNEL chan = &(deviceExtension->chan[lChannel]);
3386 PHW_LU_EXTENSION LunExt;
3387// ULONG tmp32;
3388 ULONG PreferedMode = 0xffffffff;
3389
3390 if((deviceExtension->HwFlags & UNIATA_AHCI) &&
3391 !UniataAhciChanImplemented(deviceExtension, lChannel)) {
3392 return;
3393 }
3394
3395 AtapiChipInit(deviceExtension, DEVNUM_NOT_SPECIFIED, lChannel);
3396 FindDevices(deviceExtension, 0, lChannel);
3397
3398 for (i = 0; i < chan->NumberLuns; i++) {
3399
3400 KdPrint3((PRINT_PREFIX "AtapiHwInitialize: lChannel %#x, dev %x\n", lChannel, i));
3401
3402 LunExt = chan->lun[i];
3403 // skip empty slots
3404 if (!(LunExt->DeviceFlags & DFLAGS_DEVICE_PRESENT)) {
3405 continue;
3406 }
3407
3408 AtapiDisableInterrupts(deviceExtension, lChannel);
3410
3411 if (!(LunExt->DeviceFlags & (DFLAGS_ATAPI_DEVICE | DFLAGS_MANUAL_CHS))) {
3412
3413 KdPrint2((PRINT_PREFIX "AtapiHwInitialize: IDE branch\n"));
3414 // Enable media status notification
3415 IdeMediaStatus(TRUE,deviceExtension,lChannel,(UCHAR)i);
3416
3417 // If supported, setup Multi-block transfers.
3418 statusByte = AtaCommand(deviceExtension, i, lChannel,
3419 IDE_COMMAND_SET_MULTIPLE, 0, 0, 0,
3421
3422 // Check for errors. Reset the value to 0 (disable MultiBlock) if the
3423 // command was aborted.
3424 if (statusByte & IDE_STATUS_ERROR) {
3425
3426 // Read the error register.
3427 errorByte = AtapiReadPort1(chan, IDX_IO1_i_Error);
3428
3429 KdPrint2((PRINT_PREFIX "AtapiHwInitialize: Error setting multiple mode. Status %#x, error byte %#x\n",
3430 statusByte,
3431 errorByte));
3432
3433 statusByte = AtaCommand(deviceExtension, i, lChannel,
3434 IDE_COMMAND_SET_MULTIPLE, 0, 0, 0,
3435 0, 0, ATA_WAIT_BASE_READY);
3436
3437 if (statusByte & IDE_STATUS_ERROR) {
3438 // Read the error register.
3439 errorByte = AtapiReadPort1(chan, IDX_IO1_i_Error);
3440
3441 KdPrint2((PRINT_PREFIX "AtapiHwInitialize: Error disabling multiple mode. Status %#x, error byte %#x\n",
3442 statusByte,
3443 errorByte));
3444 }
3445 // Adjust the devExt. value, if necessary.
3446 LunExt->MaximumBlockXfer = 0;
3447
3448 } else {
3450 "AtapiHwInitialize: Using Multiblock on Device %d. Blocks / int - %d\n",
3451 i,
3452 LunExt->MaximumBlockXfer));
3453 }
3454
3455 if(LunExt->IdentifyData.MajorRevision) {
3456
3457 if(LunExt->opt_ReadCacheEnable) {
3458 KdPrint2((PRINT_PREFIX " Try Enable Read Cache\n"));
3459 // If supported, setup read/write cacheing
3460 statusByte = AtaCommand(deviceExtension, i, lChannel,
3461 IDE_COMMAND_SET_FEATURES, 0, 0, 0,
3463
3464 // Check for errors.
3465 if (statusByte & IDE_STATUS_ERROR) {
3467 "AtapiHwInitialize: Enable read/write cacheing on Device %d failed\n",
3468 i));
3469 LunExt->DeviceFlags &= ~DFLAGS_RCACHE_ENABLED;
3470 } else {
3472 }
3473 } else {
3474 KdPrint2((PRINT_PREFIX " Disable Read Cache\n"));
3475 statusByte = AtaCommand(deviceExtension, i, lChannel,
3476 IDE_COMMAND_SET_FEATURES, 0, 0, 0,
3478 LunExt->DeviceFlags &= ~DFLAGS_RCACHE_ENABLED;
3479 }
3480 if(LunExt->IdentifyData.FeaturesSupport.WriteCache) {
3481 if(LunExt->opt_WriteCacheEnable) {
3482 KdPrint2((PRINT_PREFIX " Try Enable Write Cache\n"));
3483 // If supported & allowed, setup write cacheing
3484 statusByte = AtaCommand(deviceExtension, i, lChannel,
3485 IDE_COMMAND_SET_FEATURES, 0, 0, 0,
3487 // Check for errors.
3488 if (statusByte & IDE_STATUS_ERROR) {
3490 "AtapiHwInitialize: Enable write cacheing on Device %d failed\n",
3491 i));
3492 LunExt->DeviceFlags &= ~DFLAGS_WCACHE_ENABLED;
3493 } else {
3495 }
3496 } else {
3497 KdPrint2((PRINT_PREFIX " Disable Write Cache\n"));
3498 statusByte = AtaCommand(deviceExtension, i, lChannel,
3499 IDE_COMMAND_SET_FEATURES, 0, 0, 0,
3501 LunExt->DeviceFlags &= ~DFLAGS_WCACHE_ENABLED;
3502 }
3503 }
3504
3505 if(/*LunExt->IdentifyData.FeaturesSupport.PowerMngt ||*/
3506 LunExt->IdentifyData.FeaturesSupport.APM) {
3507
3508 if(LunExt->opt_AdvPowerMode) {
3509 KdPrint2((PRINT_PREFIX " Try Enable Adv. Power Mgmt\n"));
3510 // setup APM
3511 statusByte = AtaCommand(deviceExtension, i, lChannel,
3512 IDE_COMMAND_SET_FEATURES, 0, 0, 0,
3514 // Check for errors.
3515 if (statusByte & IDE_STATUS_ERROR) {
3517 "AtapiHwInitialize: Enable APM on Device %d failed\n",
3518 i));
3519 }
3520 } else {
3521 KdPrint2((PRINT_PREFIX " Disable Adv. Power Mgmt\n"));
3522 statusByte = AtaCommand(deviceExtension, i, lChannel,
3523 IDE_COMMAND_SET_FEATURES, 0, 0, 0,
3525 }
3526 }
3527 if(LunExt->IdentifyData.FeaturesSupport.AutoAcoustic) {
3528 if(LunExt->opt_AcousticMode) {
3529 KdPrint2((PRINT_PREFIX " Try Enable Acoustic Mgmt\n"));
3530 // setup acoustic mgmt
3531 statusByte = AtaCommand(deviceExtension, i, lChannel,
3532 IDE_COMMAND_SET_FEATURES, 0, 0, 0,
3534 // Check for errors.
3535 if (statusByte & IDE_STATUS_ERROR) {
3537 "AtapiHwInitialize: Enable Acoustic Mgmt on Device %d failed\n",
3538 i));
3539 }
3540 } else {
3541 KdPrint2((PRINT_PREFIX " Disable Acoustic Mgmt\n"));
3542 statusByte = AtaCommand(deviceExtension, i, lChannel,
3543 IDE_COMMAND_SET_FEATURES, 0, 0, 0,
3545 }
3546 }
3547 if(LunExt->IdentifyData.FeaturesSupport.Standby) {
3548 KdPrint2((PRINT_PREFIX " Try init standby timer: %d\n"));
3549 // setup standby timer
3550 statusByte = AtaCommand(deviceExtension, i, lChannel,
3551 IDE_COMMAND_IDLE, 0, 0, 0,
3553 // Check for errors.
3554 if (statusByte & IDE_STATUS_ERROR) {
3556 "AtapiHwInitialize: standby timer on Device %d failed\n",
3557 i));
3558 }
3559 }
3560 }
3561
3562 } else if (!(LunExt->DeviceFlags & DFLAGS_CHANGER_INITED)){
3563
3564 ULONG j;
3565 //BOOLEAN isSanyo = FALSE;
3566 CCHAR vendorId[26];
3567
3568 KdPrint2((PRINT_PREFIX "AtapiHwInitialize: ATAPI/Changer branch\n"));
3569
3570 // Attempt to identify any special-case devices - psuedo-atapi changers, atapi changers, etc.
3571 for (j = 0; j < 26; j += 2) {
3572
3573 // Build a buffer based on the identify data.
3574 MOV_DW_SWP(vendorId[j], ((PUCHAR)LunExt->IdentifyData.ModelNumber)[j]);
3575 }
3576
3577 if (!AtapiStringCmp (vendorId, "CD-ROM CDR", 11)) {
3578
3579 // Inquiry string for older model had a '-', newer is '_'
3580 if (vendorId[12] == 'C') {
3581
3582 // Torisan changer. Set the bit. This will be used in several places
3583 // acting like 1) a multi-lun device and 2) building the 'special' TUR's.
3585 LunExt->DiscsPresent = 3;
3586 //isSanyo = TRUE;
3587 }
3588 }
3589 }
3590
3591 PreferedMode = LunExt->opt_MaxTransferMode;
3592 if((PreferedMode == 0xffffffff) || (PreferedMode > chan->MaxTransferMode)) {
3593 KdPrint2((PRINT_PREFIX "MaxTransferMode (overriden): %#x\n", chan->MaxTransferMode));
3594 PreferedMode = chan->MaxTransferMode;
3595 }
3596
3597 if(LunExt->opt_PreferedTransferMode != 0xffffffff) {
3598 KdPrint2((PRINT_PREFIX "PreferedTransferMode: %#x\n", PreferedMode));
3599 PreferedMode = min(LunExt->opt_PreferedTransferMode, PreferedMode);
3600 }
3601
3602 KdPrint2((PRINT_PREFIX " try mode %#x\n", PreferedMode));
3603 LunExt->LimitedTransferMode =
3604 LunExt->TransferMode =
3605 (CHAR)PreferedMode;
3606
3607 AtapiDmaInit__(deviceExtension, LunExt);
3608
3609 LunExt->LimitedTransferMode =
3610 LunExt->TransferMode;
3611 KdPrint2((PRINT_PREFIX "Using %#x mode\n", LunExt->TransferMode));
3612
3613 // We need to get our device ready for action before
3614 // returning from this function
3615
3616 // According to the atapi spec 2.5 or 2.6, an atapi device
3617 // clears its status BSY bit when it is ready for atapi commands.
3618 // However, some devices (Panasonic SQ-TC500N) are still
3619 // not ready even when the status BSY is clear. They don't react
3620 // to atapi commands.
3621 //
3622 // Since there is really no other indication that tells us
3623 // the drive is really ready for action. We are going to check BSY
3624 // is clear and then just wait for an arbitrary amount of time!
3625 //
3626 if (LunExt->DeviceFlags & DFLAGS_ATAPI_DEVICE) {
3627 ULONG waitCount;
3628
3629 // have to get out of the loop sometime!
3630 // 10000 * 100us = 1000,000us = 1000ms = 1s
3631 waitCount = 10000;
3632 GetStatus(chan, statusByte);
3633 if(statusByte == IDE_STATUS_WRONG) {
3634 waitCount = 0;
3635 }
3636 while ((statusByte & IDE_STATUS_BUSY) && waitCount) {
3637
3638 KdPrint2((PRINT_PREFIX "Wait for ATAPI (status %x)\n", statusByte));
3639 // Wait for Busy to drop.
3641 GetStatus(chan, statusByte);
3642 waitCount--;
3643 }
3644
3645 // 5000 * 100us = 500,000us = 500ms = 0.5s
3646 if(statusByte != IDE_STATUS_WRONG) {
3647 waitCount = 5000;
3648 do {
3650 } while (waitCount--);
3651 }
3652 }
3653 GetBaseStatus(chan, statusByte);
3654 AtapiEnableInterrupts(deviceExtension, lChannel);
3656 }
3657
3658 return;
3659
3660} // end AtapiHwInitialize__()
3661
3662
3663#ifndef UNIATA_CORE
3664
3665VOID
3666NTAPI
3668 IN PVOID HwDeviceExtension,
3671{
3672 PHW_DEVICE_EXTENSION deviceExtension = (PHW_DEVICE_EXTENSION)HwDeviceExtension;
3673 ULONG lChannel = GET_CHANNEL(Srb);
3674 PHW_CHANNEL chan = &(deviceExtension->chan[lChannel]);
3676 PHW_LU_EXTENSION LunExt = chan->lun[DeviceNumber];
3677
3678 if (MechanismStatus) {
3679 LunExt->DiscsPresent = MechanismStatus->NumberAvailableSlots;
3680 if (LunExt->DiscsPresent > 1) {
3682 }
3683 }
3684 return;
3685} // end AtapiHwInitializeChanger()
3686
3687
3688/*++
3689
3690Routine Description:
3691 This routine will parse the string for a match on the keyword, then
3692 calculate the value for the keyword and return it to the caller.
3693
3694Arguments:
3695 String - The ASCII string to parse.
3696 KeyWord - The keyword for the value desired.
3697
3698Return Values:
3699 Zero if value not found
3700 Value converted from ASCII to binary.
3701
3702--*/
3703ULONG
3704NTAPI
3706 IN PCCH String,
3707 IN PCCH KeyWord
3708 )
3709{
3710 PCCH cptr;
3711 PCCH kptr;
3712 ULONG value;
3713 ULONG stringLength = 0;
3714 ULONG keyWordLength = 0;
3715 ULONG index;
3716
3717 if (!String) {
3718 return 0;
3719 }
3720 if (!KeyWord) {
3721 return 0;
3722 }
3723
3724 // Calculate the string length and lower case all characters.
3725 cptr = String;
3726 while (*cptr++) {
3727 stringLength++;
3728 }
3729
3730 // Calculate the keyword length.
3731 kptr = KeyWord;
3732 while (*kptr++) {
3733 keyWordLength++;
3734 }
3735
3736 if (keyWordLength > stringLength) {
3737
3738 // Can't possibly have a match.
3739 return 0;
3740 }
3741
3742 // Now setup and start the compare.
3743 cptr = String;
3744
3745ContinueSearch:
3746
3747 // The input string may start with white space. Skip it.
3748 while (*cptr == ' ' || *cptr == '\t') {
3749 cptr++;
3750 }
3751
3752 if (*cptr == '\0') {
3753 // end of string.
3754 return 0;
3755 }
3756
3757 kptr = KeyWord;
3758 while ((*cptr == *kptr) ||
3759 (*cptr >= 'A' && *cptr <= 'Z' && *cptr + ('a' - 'A') == *kptr) ||
3760 (*cptr >= 'a' && *cptr <= 'z' && *cptr - ('a' - 'A') == *kptr)) {
3761 cptr++;
3762 kptr++;
3763
3764 if (*cptr == '\0') {
3765 // end of string
3766 return 0;
3767 }
3768 }
3769
3770 if (*kptr == '\0') {
3771
3772 // May have a match backup and check for blank or equals.
3773 while (*cptr == ' ' || *cptr == '\t') {
3774 cptr++;
3775 }
3776
3777 // Found a match. Make sure there is an equals.
3778 if (*cptr != '=') {
3779
3780 // Not a match so move to the next semicolon.
3781 while (*cptr) {
3782 if (*cptr++ == ';') {
3783 goto ContinueSearch;
3784 }
3785 }
3786 return 0;
3787 }
3788 // Skip the equals sign.
3789 cptr++;
3790
3791 // Skip white space.
3792 while ((*cptr == ' ') || (*cptr == '\t')) {
3793 cptr++;
3794 }
3795
3796 if (*cptr == '\0') {
3797 // Early end of string, return not found
3798 return 0;
3799 }
3800
3801 if (*cptr == ';') {
3802 // This isn't it either.
3803 cptr++;
3804 goto ContinueSearch;
3805 }
3806
3807 value = 0;
3808 if ((*cptr == '0') && ((*(cptr + 1) == 'x') || (*(cptr + 1) == 'X'))) {
3809 // Value is in Hex. Skip the "0x"
3810 cptr += 2;
3811 for (index = 0; *(cptr + index); index++) {
3812
3813 if (*(cptr + index) == ' ' ||
3814 *(cptr + index) == '\t' ||
3815 *(cptr + index) == ';') {
3816 break;
3817 }
3818
3819 if ((*(cptr + index) >= '0') && (*(cptr + index) <= '9')) {
3820 value = (16 * value) + (*(cptr + index) - '0');
3821 } else {
3822 if ((*(cptr + index) >= 'a') && (*(cptr + index) <= 'f')) {
3823 value = (16 * value) + (*(cptr + index) - 'a' + 10);
3824 } else if ((*(cptr + index) >= 'A') && (*(cptr + index) <= 'F')) {
3825 value = (16 * value) + (*(cptr + index) - 'A' + 10);
3826 } else {
3827 // Syntax error, return not found.
3828 return 0;
3829 }
3830 }
3831 }
3832 } else {
3833
3834 // Value is in Decimal.
3835 for (index = 0; *(cptr + index); index++) {
3836
3837 if (*(cptr + index) == ' ' ||
3838 *(cptr + index) == '\t' ||
3839 *(cptr + index) == ';') {
3840 break;
3841 }
3842
3843 if ((*(cptr + index) >= '0') && (*(cptr + index) <= '9')) {
3844 value = (10 * value) + (*(cptr + index) - '0');
3845 } else {
3846
3847 // Syntax error return not found.
3848 return 0;
3849 }
3850 }
3851 }
3852
3853 return value;
3854 } else {
3855
3856 // Not a match check for ';' to continue search.
3857 while (*cptr) {
3858 if (*cptr++ == ';') {
3859 goto ContinueSearch;
3860 }
3861 }
3862
3863 return 0;
3864 }
3865} // end AtapiParseArgumentString()_
3866
3867/*
3868 Timer callback
3869*/
3870VOID
3871NTAPI
3873 IN PVOID HwDeviceExtension,
3874 IN UCHAR lChannel
3875 )
3876{
3877
3878 PHW_DEVICE_EXTENSION deviceExtension = (PHW_DEVICE_EXTENSION)HwDeviceExtension;
3879 PHW_CHANNEL chan = &(deviceExtension->chan[lChannel]);
3880 ULONG c, _c;
3881
3883 UCHAR statusByte;
3884
3885 KdPrint2((PRINT_PREFIX "AtapiCallBack:\n"));
3886 // If the last command was DSC restrictive, see if it's set. If so, the device is
3887 // ready for a new request. Otherwise, reset the timer and come back to here later.
3888
3889 // If ISR decided to wait for BUSY or DRQ in DPC, we shall also get here.
3890 // In this case chan->ExpectingInterrupt == TRUE, but interrupts are disabled, thus,
3891 // we shall have no problem with interrupt handler.
3892 if (!srb || chan->ExpectingInterrupt) {
3893 KdPrint2((PRINT_PREFIX "AtapiCallBack: Calling ISR directly due to BUSY\n"));
3894 chan->DpcState = DPC_STATE_TIMER;
3895 if(!AtapiInterrupt__(HwDeviceExtension, lChannel)) {
3897 KdPrint2((PRINT_PREFIX "AtapiCallBack: What's fucking this ???\n"));
3898 }
3899 goto ReturnCallback;
3900 }
3901
3902#ifdef _DEBUG
3903 if (!IS_RDP((srb->Cdb[0]))) {
3904 KdPrint2((PRINT_PREFIX "AtapiCallBack: Invalid CDB marked as RDP - %#x\n", srb->Cdb[0]));
3905 }
3906#endif
3907 if(!(chan->RDP)) {
3908 goto ReturnEnableIntr;
3909 }
3910 GetStatus(chan, statusByte);
3911 if (statusByte & IDE_STATUS_DSC) {
3912
3913 UCHAR PathId = srb->PathId;
3914 UCHAR TargetId = srb->TargetId;
3915 UCHAR Lun = srb->Lun;
3916
3917 KdPrint2((PRINT_PREFIX "AtapiCallBack: Found DSC for RDP - %#x\n", srb->Cdb[0]));
3918 AtapiDmaDBSync(chan, srb);
3919 UniataRemoveRequest(chan, srb);
3920 ScsiPortNotification(RequestComplete, deviceExtension, srb);
3921 // Clear current SRB.
3922 if(!deviceExtension->simplexOnly) {
3923 srb = UniataGetCurRequest(chan);
3924 } else {
3925 srb = NULL;
3926 }
3927 chan->RDP = FALSE;
3928
3929 // Ask for next request.
3931 deviceExtension,
3932 PathId,
3933 TargetId,
3934 Lun);
3935 ScsiPortNotification(NextRequest, deviceExtension, NULL);
3936
3937 if(srb) {
3938 AtapiStartIo__(HwDeviceExtension, srb, FALSE);
3939 }
3940
3941 } else {
3942 KdPrint2((PRINT_PREFIX "AtapiCallBack: Requesting another timer for Op %#x\n",
3943 srb->Cdb[0]));
3944
3945 AtapiQueueTimerDpc(HwDeviceExtension, lChannel,
3947 1000);
3948
3949 goto ReturnCallback;
3950 }
3951
3952ReturnEnableIntr:
3953
3954 if(CrNtInterlockedExchangeAdd(&(chan->DisableIntr), 0)) {
3955 KdPrint2((PRINT_PREFIX "AtapiCallBack: CallDisableInterrupts\n"));
3956 //ASSERT(KeGetCurrentIrql() <= DISPATCH_LEVEL);
3957#ifdef UNIATA_USE_XXableInterrupts
3959 // must be called on DISPATCH_LEVEL
3962#else
3963 AtapiEnableInterrupts(HwDeviceExtension, lChannel);
3966 // Will raise IRQL to DIRQL
3967 AtapiQueueTimerDpc(HwDeviceExtension, lChannel,
3969 1);
3970 KdPrint2((PRINT_PREFIX "AtapiInterrupt: Timer DPC inited\n"));
3971#endif // UNIATA_USE_XXableInterrupts
3972 } else {
3973 //ASSERT(!deviceExtension->simplexOnly);
3974 }
3975
3976ReturnCallback:
3977
3978 // Check other channel
3979 // In simplex mode no interrupts must appear on other channels
3980 for(_c=0; _c<deviceExtension->NumberChannels; _c++) {
3981 c = (_c+deviceExtension->FirstChannelToCheck) % deviceExtension->NumberChannels;
3982
3983 if(c == lChannel) {
3984 continue;
3985 }
3986
3987 chan = &(deviceExtension->chan[c]);
3988
3989 if((ULONG)CrNtInterlockedCompareExchange(CRNT_ILK_PTYPE &(chan->CheckIntr),
3992 {
3993 //ASSERT(!deviceExtension->simplexOnly);
3994 chan->DpcState = DPC_STATE_ISR;
3995 if(!AtapiInterrupt__(HwDeviceExtension, (UCHAR)c)) {
3997 }
3998 }
3999 }
4000 KdPrint2((PRINT_PREFIX "AtapiCallBack: return\n"));
4001 return;
4002
4003} // end AtapiCallBack__()
4004
4005VOID
4006NTAPI
4008 IN PVOID HwDeviceExtension
4009 )
4010{
4011 AtapiCallBack__(HwDeviceExtension, (UCHAR)((PHW_DEVICE_EXTENSION)HwDeviceExtension)->ActiveDpcChan);
4012} // end AtapiCallBack_X()
4013
4014#endif //UNIATA_CORE
4015
4016/*++
4017
4018Routine Description:
4019
4020 This is the interrupt service routine for ATAPI IDE miniport driver.
4021
4022Arguments:
4023
4024 HwDeviceExtension - HBA miniport driver's adapter data storage
4025
4026Return Value:
4027
4028 TRUE if expecting an interrupt.
4029
4030--*/
4031BOOLEAN
4032NTAPI
4034 IN PVOID HwDeviceExtension
4035 )
4036{
4037 PHW_DEVICE_EXTENSION deviceExtension = (PHW_DEVICE_EXTENSION)HwDeviceExtension;
4038 ULONG c, _c;
4040 ULONG c_state;
4041 ULONG i_res = 0;
4042 ULONG pass;
4043 //BOOLEAN checked[AHCI_MAX_PORT];
4044 ULONG hIS;
4045 ULONG checked;
4046
4047 KdPrint2((PRINT_PREFIX "Intr: DeviceID+VendorID/Rev %#x/%#x (ex %d)\n",
4048 deviceExtension->DevID, deviceExtension->RevID, deviceExtension->ExpectingInterrupt ));
4049
4050 if(deviceExtension->HwFlags & UNIATA_AHCI) {
4051 // AHCI may generate state change notification, never skip this check
4052 hIS = UniataAhciReadHostPort4(deviceExtension, IDX_AHCI_IS);
4053 KdPrint2((PRINT_PREFIX "AtapiInterrupt(base): AHCI: hIS=%x cntrlr %#x chan %#x\n",hIS, deviceExtension->DevIndex, deviceExtension->Channel));
4054 if(!hIS) {
4055 return FALSE;
4056 }
4057 // assume all non-interrupted ports to be already checked
4058 checked = ~hIS;
4059 // assume all not implemented ports to be already checked
4060 checked |= ~deviceExtension->AHCI_PI;
4061 } else {
4062 checked = 0; // assume all ports are not checked
4063 }
4064
4065 if(!deviceExtension->ExpectingInterrupt) {
4066 // if we do not expect interrupt, exit now,
4067 // but keep in mind that it can be unexpected one
4068 // Note: this is just a hint, not exact counter
4069 KdPrint2((PRINT_PREFIX "unexpected, 1st chance\n"));
4070 //deviceExtension->ExpectingInterrupt++;
4071 //return FALSE;
4072 }
4073 // clear this flag now, it can be set again in sub-calls
4074 deviceExtension->ExpectingInterrupt=0;
4075
4076
4077// for(_c=0; _c<deviceExtension->NumberChannels; _c++) {
4078// checked[_c] = (UCHAR)((hIS >> _c) & 0x01);
4079// }
4080
4081// fc =
4082 for(pass=0; pass<2; pass++) {
4083 //KdPrint2((PRINT_PREFIX "AtapiInterrupt(base): pass %d\n", pass));
4084 if(status && pass) {
4085 // we catched some expected interrupts now.
4086 // do not touch unexpected until next ISR call
4087 break;
4088 }
4089 for(_c=0; _c<deviceExtension->NumberChannels; _c++) {
4090
4091 c = (_c+deviceExtension->FirstChannelToCheck) % deviceExtension->NumberChannels;
4092
4093 if((checked>>c) & 0x01)
4094 continue;
4095
4096 // check non-empty and expecting interrupt channels first
4097 if(!pass && !deviceExtension->chan[c].ExpectingInterrupt)
4098 continue;
4099
4100 checked |= (ULONG)1 << c;
4101
4102 KdPrint2((PRINT_PREFIX "AtapiInterrupt(base): cntrlr %#x chan %#x\n",deviceExtension->DevIndex, c));
4103
4104 if(CrNtInterlockedExchangeAdd(&(deviceExtension->chan[c].DisableIntr), 0)) {
4105 // we get here on idle channels or when ISR is posted to DPC
4106 KdPrint2((PRINT_PREFIX "AtapiInterrupt(base): disabled INTR on ch %d\n", c));
4107 continue;
4108 }
4109 // lock channel. Wait, while 2nd ISR checks interrupt on this channel
4110 do {
4111 KdPrint2((PRINT_PREFIX "AtapiInterrupt(base): try lock\n"));
4112 // c_state = deviceExtension->chan[c].CheckIntr;
4113 // if (deviceExtension->chan[c].CheckIntr == CHECK_INTR_DETECTED) {
4114 // deviceExtension->chan[c].CheckIntr = CHECK_INTR_ACTIVE;
4115 // }
4116 c_state =
4117 (ULONG)CrNtInterlockedCompareExchange(CRNT_ILK_PTYPE &(deviceExtension->chan[c].CheckIntr),
4120 if(c_state == CHECK_INTR_IDLE) {
4121 // c_state = deviceExtension->chan[c].CheckIntr;
4122 // if (deviceExtension->chan[c].CheckIntr == CHECK_INTR_IDLE) {
4123 // deviceExtension->chan[c].CheckIntr = CHECK_INTR_ACTIVE
4124 // }
4125 c_state =
4126 (ULONG)CrNtInterlockedCompareExchange(CRNT_ILK_PTYPE &(deviceExtension->chan[c].CheckIntr),
4129 }
4130 } while(c_state == CHECK_INTR_CHECK);
4131 KdPrint2((PRINT_PREFIX "AtapiInterrupt(base): locked\n"));
4132 // check if already serviced
4133 if(c_state == CHECK_INTR_ACTIVE) {
4134 KdPrint2((PRINT_PREFIX "AtapiInterrupt(base): CHECK_INTR_ACTIVE\n"));
4135 continue;
4136 }
4137
4138 if((c_state == CHECK_INTR_DETECTED) ||
4139 (i_res = AtapiCheckInterrupt__(deviceExtension, (UCHAR)c))) {
4140
4141 if(i_res == INTERRUPT_REASON_UNEXPECTED) {
4142 KdPrint2((PRINT_PREFIX "AtapiInterrupt(base): Catch unexpected\n"));
4143 InterlockedExchange(&(deviceExtension->chan[c].CheckIntr), CHECK_INTR_IDLE);
4144 //return TRUE;
4145 status = TRUE;
4146 continue;
4147 }
4148 // disable interrupts on other channel of legacy mode
4149 // ISA-bridged onboard controller
4150 if(deviceExtension->simplexOnly /*||
4151 ((WinVer_Id() > WinVer_NT) && BMList[deviceExtension->DevIndex].MasterDev)*/) {
4152 AtapiDisableInterrupts(deviceExtension, !c);
4153 }
4154
4155 deviceExtension->chan[c].DpcState = DPC_STATE_ISR;
4156 if(AtapiInterrupt__(HwDeviceExtension, (UCHAR)c)) {
4157 deviceExtension->LastInterruptedChannel = (UCHAR)c;
4158 KdPrint2((PRINT_PREFIX "AtapiInterrupt(base): return status TRUE\n"));
4159 status = TRUE;
4160 } else {
4161 KdPrint2((PRINT_PREFIX "AtapiInterrupt(base): set CHECK_INTR_IDLE\n"));
4162 InterlockedExchange(&(deviceExtension->chan[c].CheckIntr), CHECK_INTR_IDLE);
4163 }
4164
4165 // re-enable interrupts on other channel
4166 if(deviceExtension->simplexOnly /*||
4167 ((WinVer_Id() > WinVer_NT) && BMList[deviceExtension->DevIndex].MasterDev)*/) {
4168 AtapiEnableInterrupts(deviceExtension, !c);
4169 }
4170
4171 } else {
4172 KdPrint2((PRINT_PREFIX "AtapiInterrupt(base): set CHECK_INTR_IDLE (2)\n"));
4173 InterlockedExchange(&(deviceExtension->chan[c].CheckIntr), CHECK_INTR_IDLE);
4174 }
4175
4176 }
4177 }
4178 KdPrint2((PRINT_PREFIX "AtapiInterrupt(base): exit with status %#x\n", status));
4179 if(status) {
4180 deviceExtension->FirstChannelToCheck++;
4181 if(deviceExtension->FirstChannelToCheck >= deviceExtension->NumberChannels)
4182 deviceExtension->FirstChannelToCheck = 0;
4183 }
4184 return status;
4185} // end AtapiInterrupt()
4186
4187//ULONG i2c = 0;
4188#ifndef UNIATA_CORE
4189
4190BOOLEAN
4191NTAPI
4194 IN PVOID Isr2HwDeviceExtension
4195 )
4196{
4197 // This ISR is intended to catch interrupts when we are already in other ISR instance
4198 // for the same device. This may happen when we have multiple channels,
4199 // especially on SMP machines
4200
4201 PISR2_DEVICE_EXTENSION Isr2DeviceExtension = (PISR2_DEVICE_EXTENSION)Isr2HwDeviceExtension;
4202 PHW_DEVICE_EXTENSION deviceExtension = Isr2DeviceExtension->HwDeviceExtension;
4203 ULONG c;
4205 ULONG c_count = 0;
4206 ULONG i_res;
4207 ULONG hIS;
4208 ULONG checked;
4209
4210 // we should never get here for ISA/MCA
4211 if(!BMList[deviceExtension->DevIndex].Isr2Enable) {
4212 KdPrint2((PRINT_PREFIX "AtapiInterrupt2: NOT ACTIVE cntrlr %#x chan %#x\n",deviceExtension->DevIndex, deviceExtension->Channel));
4213 return FALSE;
4214 }
4215
4216 if(deviceExtension->HwFlags & UNIATA_AHCI) {
4217 // AHCI may generate state change notification, never skip this check
4218 hIS = UniataAhciReadHostPort4(deviceExtension, IDX_AHCI_IS);
4219 KdPrint2((PRINT_PREFIX "AtapiInterrupt2: AHCI: hIS=%x cntrlr %#x chan %#x\n",hIS, deviceExtension->DevIndex, deviceExtension->Channel));
4220 if(!hIS) {
4221 return FALSE;
4222 }
4223 // assume all non-interrupted ports to be already checked
4224 checked = ~hIS;
4225 // assume all not implemented ports to be already checked
4226 checked |= ~deviceExtension->AHCI_PI;
4227
4228 } else {
4229 checked = 0; // assume all ports are not checked
4230 }
4231 if(!deviceExtension->ExpectingInterrupt) {
4232 KdPrint2((PRINT_PREFIX "AtapiInterrupt2: !deviceExtension->ExpectingInterrupt\n"));
4233 deviceExtension->ExpectingInterrupt++;
4234 return FALSE;
4235 }
4236 //deviceExtension->ExpectingInterrupt = 0;
4237
4238 for(c=0; c<deviceExtension->NumberChannels; c++) {
4239 KdPrint2((PRINT_PREFIX "AtapiInterrupt2: cntrlr %#x chan %#x\n",deviceExtension->DevIndex, c));
4240
4241 if((checked>>c) & 0x01)
4242 continue;
4243
4244 checked |= (ULONG)1 << c;
4245
4246 if(CrNtInterlockedExchangeAdd(&(deviceExtension->chan[c].DisableIntr), 0)) {
4247 KdPrint2((PRINT_PREFIX "AtapiInterrupt2: disabled INTR\n"));
4248 continue;
4249 }
4250
4251 if((ULONG)CrNtInterlockedCompareExchange(CRNT_ILK_PTYPE &(deviceExtension->chan[c].CheckIntr),
4254 {
4255 KdPrint2((PRINT_PREFIX "AtapiInterrupt2: !CHECK_INTR_IDLE\n"));
4256 // hunt on unexpected intr (Some devices generate double interrupts,
4257 // some controllers (at least CMD649) interrupt twice with small delay.
4258 // If interrupts are disabled, they queue interrupt and re-issue it later,
4259 // when we do not expect it.
4260 continue;
4261 }
4262
4263 c_count++;
4264 if((i_res = AtapiCheckInterrupt__(deviceExtension, (UCHAR)c))) {
4265
4266 KdPrint2((PRINT_PREFIX "AtapiInterrupt2: intr\n"));
4267 if(i_res == INTERRUPT_REASON_UNEXPECTED) {
4268 KdPrint2((PRINT_PREFIX "AtapiInterrupt2: Catch unexpected\n"));
4269 InterlockedExchange(&(deviceExtension->chan[c].CheckIntr), CHECK_INTR_IDLE);
4270 return TRUE;
4271 }
4272
4273 status = TRUE;
4275 } else {
4276 InterlockedExchange(&(deviceExtension->chan[c].CheckIntr), CHECK_INTR_IDLE);
4277 }
4278 }
4279 KdPrint2((PRINT_PREFIX "AtapiInterrupt2: status %d, c_count %d\n", status, c_count));
4280 if(status && (c_count != deviceExtension->NumberChannels)) {
4281 // there is an active ISR/DPC for one channel, but
4282 // we have an interrupt from another one
4283 // Lets inform current ISR/DPC about new interrupt
4285 } else {
4286 status = FALSE;
4287 }
4288 KdPrint2((PRINT_PREFIX "AtapiInterrupt2: return %d\n", status));
4289 return status;
4290
4291} // end AtapiInterrupt2()
4292
4294NTAPI
4296 IN PVOID HwDeviceExtension
4297 )
4298{
4299 PHW_DEVICE_EXTENSION deviceExtension = (PHW_DEVICE_EXTENSION)HwDeviceExtension;
4300 ULONG c;
4301
4302 for(c=0; c<deviceExtension->NumberChannels; c++) {
4303 KdPrint2((PRINT_PREFIX "AtapiInterruptDpc: %#x\n",c));
4304
4305 if(!(deviceExtension->chan[c].ChannelCtrlFlags & CTRFLAGS_DPC_REQ)) {
4306
4307 if((ULONG)CrNtInterlockedCompareExchange(CRNT_ILK_PTYPE &(deviceExtension->chan[c].CheckIntr),
4310 {
4311 continue;
4312 }
4313
4314 } else {
4315 deviceExtension->chan[c].ChannelCtrlFlags &= ~CTRFLAGS_DPC_REQ;
4316 }
4317/*
4318 if(OldReqState != REQ_STATE_DPC_INTR_REQ) {
4319 AtapiDisableInterrupts(deviceExtension, lChannel);
4320 }
4321*/
4322 deviceExtension->chan[c].DpcState = DPC_STATE_DPC;
4323 if(!AtapiInterrupt__(HwDeviceExtension, (UCHAR)c)) {
4324 InterlockedExchange(&(deviceExtension->chan[c].CheckIntr), CHECK_INTR_IDLE);
4325 }
4326 }
4328} // end AtapiInterruptDpc()
4329
4330
4332NTAPI
4334 IN PVOID HwDeviceExtension
4335 )
4336{
4337 PHW_DEVICE_EXTENSION deviceExtension = (PHW_DEVICE_EXTENSION)HwDeviceExtension;
4338 KdPrint2((PRINT_PREFIX "AtapiEnableInterrupts__():\n"));
4339 ULONG c;
4340 PHW_CHANNEL chan = NULL;
4341
4342 for(c=0; c<deviceExtension->NumberChannels; c++) {
4343 KdPrint2((PRINT_PREFIX "AtapiEnableInterrupts__(2): %#x\n",c));
4344 chan = &(deviceExtension->chan[c]);
4345
4347 // enable intrs on requested channel
4348 chan->ChannelCtrlFlags &= ~CTRFLAGS_ENABLE_INTR_REQ;
4349 AtapiEnableInterrupts(HwDeviceExtension, c);
4352
4353 // check if current or other channel(s) interrupted
4354 //AtapiInterrupt(HwDeviceExtension);
4355
4356 if(deviceExtension->simplexOnly) {
4357 break;
4358 }
4359 } else {
4360 // check if other channel(s) interrupted
4361 // must do nothing in simplex mode
4362 if((ULONG)CrNtInterlockedCompareExchange(CRNT_ILK_PTYPE &(chan->CheckIntr),
4365 continue;
4366 }
4367 //ASSERT(!deviceExtension->simplexOnly);
4368 chan->DpcState = DPC_STATE_ISR;
4369 if(!AtapiInterrupt__(HwDeviceExtension, (UCHAR)c)) {
4371 }
4372 }
4373 }
4374 // In simplex mode next command must be sent to device here
4375 if(deviceExtension->simplexOnly && chan) {
4377 chan = UniataGetNextChannel(chan);
4378 if(chan) {
4379 srb = UniataGetCurRequest(chan);
4380 } else {
4381 srb = NULL;
4382 }
4383 if(srb) {
4384 AtapiStartIo__(HwDeviceExtension, srb, FALSE);
4385 }
4386 }
4387
4389
4390} // end AtapiEnableInterrupts__()
4391
4392#endif //UNIATA_CORE
4393
4394
4395VOID
4396NTAPI
4398 IN PVOID HwDeviceExtension,
4399 IN ULONG c
4400 )
4401{
4402 PHW_DEVICE_EXTENSION deviceExtension = (PHW_DEVICE_EXTENSION)HwDeviceExtension;
4403 PHW_CHANNEL chan;
4404 //UCHAR statusByte;
4405
4406 if(c >= deviceExtension->NumberChannels) {
4407 KdPrint2((PRINT_PREFIX "AtapiEnableInterrupts_%d: WRONG CHANNEL\n",c));
4408 return;
4409 }
4410 if((deviceExtension->HwFlags & UNIATA_AHCI) &&
4411 !UniataAhciChanImplemented(deviceExtension, c)) {
4412 KdPrint2((PRINT_PREFIX "AtapiEnableInterrupts_%d: not imp. CHANNEL\n",c));
4413 return;
4414 }
4415
4416 chan = &(deviceExtension->chan[c]);
4417 KdPrint2((PRINT_PREFIX "AtapiEnableInterrupts_%d: %d\n",c, chan->DisableIntr));
4418 if(!InterlockedDecrement(&chan->DisableIntr)) {
4419 if(deviceExtension->HwFlags & UNIATA_AHCI) {
4423 ((/*ch->pm_level == */0) ? ATA_AHCI_P_IX_PRC | ATA_AHCI_P_IX_PC : 0) |
4424 ATA_AHCI_P_IX_PRC | ATA_AHCI_P_IX_PC | /* DEBUG */
4428 );
4429 } else {
4430 //SelectDrive(chan, 0);
4431 //GetBaseStatus(chan, statusByte);
4433 0 | IDE_DC_A_4BIT );
4434 //if(chan->NumberLuns) {
4435 // SelectDrive(chan, 1);
4436 // GetBaseStatus(chan, statusByte);
4437 // AtapiWritePort1(chan, IDX_IO2_o_Control,
4438 // IDE_DC_A_4BIT );
4439 // SelectDrive(chan, chan->cur_cdev);
4440 //}
4441 }
4442 chan->ChannelCtrlFlags &= ~CTRFLAGS_INTR_DISABLED;
4443 } else {
4444 if(deviceExtension->HwFlags & UNIATA_AHCI) {
4445 // keep interrupts disabled
4447 } else {
4449 IDE_DC_DISABLE_INTERRUPTS /*| IDE_DC_A_4BIT*/ );
4450 }
4451 }
4452 return;
4453} // end AtapiEnableInterrupts()
4454
4455VOID
4456NTAPI
4458 IN PVOID HwDeviceExtension,
4459 IN ULONG c
4460 )
4461{
4462 PHW_DEVICE_EXTENSION deviceExtension = (PHW_DEVICE_EXTENSION)HwDeviceExtension;
4463 PHW_CHANNEL chan;
4464 if(c >= deviceExtension->NumberChannels) {
4465 KdPrint2((PRINT_PREFIX "AtapiDisableInterrupts_%d: WRONG CHANNEL\n",c));
4466 return;
4467 }
4468 chan = &(deviceExtension->chan[c]);
4469 KdPrint2((PRINT_PREFIX "AtapiDisableInterrupts_%d: %d\n",c, chan->DisableIntr));
4470 // mark channel as busy
4471 if(InterlockedIncrement(&chan->DisableIntr)) {
4472 if(deviceExtension->HwFlags & UNIATA_AHCI) {
4474 } else {
4475 //SelectDrive(chan, 0);
4477 IDE_DC_DISABLE_INTERRUPTS /*| IDE_DC_A_4BIT*/ );
4478 //if(chan->NumberLuns) {
4479 // SelectDrive(chan, 1);
4480 // AtapiWritePort1(chan, IDX_IO2_o_Control,
4481 // IDE_DC_DISABLE_INTERRUPTS /*| IDE_DC_A_4BIT*/ );
4482 // SelectDrive(chan, chan->cur_cdev);
4483 //}
4484 }
4486 }
4487
4488 return;
4489} // end AtapiDisableInterrupts()
4490
4491VOID
4493 IN struct _HW_CHANNEL* chan,
4494 IN BOOLEAN Expecting
4495 )
4496{
4497 chan->ExpectingInterrupt = Expecting;
4498 if(Expecting) {
4499 chan->DeviceExtension->ExpectingInterrupt++;
4500 } else
4501 if(chan->DeviceExtension->ExpectingInterrupt) {
4502 chan->DeviceExtension->ExpectingInterrupt--;
4503 }
4504 return;
4505} // end UniataExpectChannelInterrupt()
4506
4507/*
4508 Check hardware for interrupt state
4509 */
4510BOOLEAN
4511NTAPI
4513 IN PVOID HwDeviceExtension,
4514 IN UCHAR c // logical channel
4515 )
4516{
4517 PHW_DEVICE_EXTENSION deviceExtension = (PHW_DEVICE_EXTENSION)HwDeviceExtension;
4518 PHW_CHANNEL chan = &(deviceExtension->chan[c]);
4519 PHW_LU_EXTENSION LunExt;
4520
4521 ULONG VendorID = deviceExtension->DevID & 0xffff;
4522 ULONG ChipType = deviceExtension->HwFlags & CHIPTYPE_MASK;
4523
4524 ULONG status;
4525 ULONG pr_status = 0;
4526 UCHAR dma_status = 0;
4527 UCHAR reg8 = 0;
4528 ULONG reg32 = 0;
4529 UCHAR statusByte = 0;
4530 ULONG slotNumber = deviceExtension->slotNumber;
4531 ULONG SystemIoBusNumber = deviceExtension->SystemIoBusNumber;
4532 ULONG ChipFlags = deviceExtension->HwFlags & CHIPFLAG_MASK;
4533 UCHAR Channel;
4534 UCHAR lChannel;
4535 BOOLEAN DmaTransfer = FALSE;
4536 BOOLEAN OurInterrupt = FALSE;
4537 BOOLEAN StatusValid = FALSE;
4538// ULONG k;
4539 UCHAR interruptReason;
4540 BOOLEAN EarlyIntr = FALSE;
4541 BOOLEAN SingleBlockIntr = FALSE;
4542
4543 KdPrint2((PRINT_PREFIX "AtapiCheckInterrupt__:\n"));
4544
4545 lChannel = c;
4546 Channel = (UCHAR)(deviceExtension->Channel + lChannel);
4547 LunExt = chan->lun[chan->cur_cdev];
4548
4549 //KdPrint2((PRINT_PREFIX "AtapiCheckInterrupt__ chan %#x:\n", chan));
4550 //KdPrint2((PRINT_PREFIX "AtapiCheckInterrupt__ (%d/%d):\n", Channel, chan->cur_cdev));
4551
4552 if((ChipFlags & UNIATA_AHCI) &&
4553 UniataIsSATARangeAvailable(deviceExtension, lChannel)) {
4554
4555 if(!UniataAhciChanImplemented(deviceExtension, lChannel)) {
4556 return OurInterrupt;
4557 }
4558
4559 OurInterrupt = UniataAhciStatus(HwDeviceExtension, lChannel, DEVNUM_NOT_SPECIFIED);
4560 if((OurInterrupt == INTERRUPT_REASON_UNEXPECTED) &&
4561 (LunExt->DeviceFlags & DFLAGS_ATAPI_DEVICE)) {
4562 UniataAhciWaitCommandReady(chan, 2 /* ms */ );
4563 statusByte = (UCHAR)UniataAhciWaitReady(chan, 0 /* immediate */);
4564 if(!(statusByte & (IDE_STATUS_BUSY)) ) {
4565 KdPrint2((PRINT_PREFIX "ATAPI special case READY\n"));
4566 //deviceExtension->ExpectingInterrupt++; // will be updated in ISR on ReturnEnableInterrupts
4567 OurInterrupt = INTERRUPT_REASON_OUR;
4568 } else
4569 if((statusByte & (IDE_STATUS_BUSY | IDE_STATUS_DRDY)) == (IDE_STATUS_BUSY | IDE_STATUS_DRDY) ) {
4570 KdPrint2((PRINT_PREFIX "ATAPI special case pre ERR-READY\n"));
4571 OurInterrupt = INTERRUPT_REASON_OUR;
4572 } else
4573 if(statusByte & IDE_STATUS_ERROR) {
4574 KdPrint2((PRINT_PREFIX "ATAPI special case ERR-READY\n"));
4575 OurInterrupt = INTERRUPT_REASON_OUR;
4576 } else {
4577 KdPrint2((PRINT_PREFIX "ATAPI special case ? %x\n", statusByte));
4578 OurInterrupt = INTERRUPT_REASON_OUR;
4579 }
4580 }
4581 return OurInterrupt;
4582 }
4583
4585 DmaTransfer = TRUE;
4586 KdPrint2((PRINT_PREFIX " cntrlr %#x:%#x, lch %#x DmaTransfer = TRUE\n", deviceExtension->DevIndex,
4587 deviceExtension->Channel + c, c));
4588 } else {
4589 KdPrint2((PRINT_PREFIX " cntrlr %#x:%#x, lch %#x DmaTransfer = FALSE\n", deviceExtension->DevIndex,
4590 deviceExtension->Channel + c, c));
4591 dma_status = GetDmaStatus(deviceExtension, lChannel);
4592 KdPrint2((PRINT_PREFIX " DMA status %#x\n", dma_status));
4593 }
4594
4595 // do controller-specific interrupt servicing staff
4596 if(deviceExtension->UnknownDev) {
4597 KdPrint2((PRINT_PREFIX " UnknownDev\n"));
4598 goto check_unknown;
4599 }
4600
4601 // Attention !
4602 // We can catch (BM_STATUS_ACTIVE + BM_STATUS_INTR) when operation is actually completed
4603 // Such behavior was observed with Intel ICH-xxx chips
4604 // This condition shall also be treated as 'our interrupt' because of BM_STATUS_INTR flag
4605
4606 switch(VendorID) {
4607
4608 case ATA_PROMISE_ID: {
4609 switch(ChipType) {
4610 case PROLD:
4611 case PRNEW:
4612 status = AtapiReadPortEx4(chan, (ULONGIO_PTR)(&deviceExtension->BaseIoAddressBM_0),0x1c);
4613 if (!DmaTransfer)
4614 break;
4615 if (!(status &
4616 ((Channel) ? 0x00004000 : 0x00000400))) {
4617 KdPrint2((PRINT_PREFIX " Promise old/new unexpected\n"));
4619 }
4620 break;
4621 case PRTX:
4624 if (!DmaTransfer)
4625 break;
4626 if(!(status & 0x20)) {
4627 KdPrint2((PRINT_PREFIX " Promise tx unexpected\n"));
4629 }
4630 break;
4631 case PRMIO: {
4632 ULONG stat_reg = (ChipFlags & PRG2) ? 0x60 : 0x6c;
4633 status = AtapiReadPortEx4(chan, (ULONGIO_PTR)(&deviceExtension->BaseIoAddressBM_0),0x40);
4634 AtapiWritePortEx4(chan, (ULONGIO_PTR)(&deviceExtension->BaseIoAddressBM_0),0x40, status);
4635
4636 if(status & (1 << (Channel+1))) {
4637 // our
4638 } else {
4639 KdPrint2((PRINT_PREFIX " Promise mio unexpected\n"));
4641 }
4642
4643 if(!(ChipFlags & UNIATA_SATA))
4644 break;
4645
4646 pr_status = AtapiReadPortEx4(chan, (ULONGIO_PTR)(&deviceExtension->BaseIoAddressBM_0),stat_reg);
4647 AtapiWritePortEx4(chan, (ULONGIO_PTR)(&deviceExtension->BaseIoAddressBM_0),stat_reg, (pr_status & (0x11 << Channel)));
4648 if(pr_status & (0x11 << Channel)) {
4649 // TODO: reset channel
4650 KdPrint2((PRINT_PREFIX " Promise mio unexpected + reset req\n"));
4651 UniataSataEvent(deviceExtension, lChannel, UNIATA_SATA_EVENT_DETACH, 0);
4652 }
4653 if(!(status & (0x01 << Channel))) {
4654 // Connect event
4655 KdPrint2((PRINT_PREFIX " Promise mio unexpected attach\n"));
4656 UniataSataEvent(deviceExtension, lChannel, UNIATA_SATA_EVENT_ATTACH, 0);
4657 }
4658 if(UniataSataClearErr(HwDeviceExtension, c, UNIATA_SATA_DO_CONNECT, 0)) {
4659 OurInterrupt = INTERRUPT_REASON_UNEXPECTED;
4660 } else {
4662 }
4663
4664 AtapiWritePort4(chan, IDX_BM_DeviceSpecific0, 0x00000001);
4665 break; }
4666 }
4667 break; }
4668 case ATA_NVIDIA_ID: {
4669 if(!(ChipFlags & UNIATA_SATA) || (ChipFlags & NVGEN))
4670 break;
4671
4672 KdPrint2((PRINT_PREFIX "NVIDIA\n"));
4673
4674 ULONG offs = (ChipFlags & NV4OFF) ? 0x0440 : 0x0010;
4675 ULONG shift = Channel * ((ChipFlags & NVQ) ? 4 : 16);
4676
4677 /* get and clear interrupt status */
4678 if(ChipFlags & NVQ) {
4679 pr_status = AtapiReadPortEx4(chan, (ULONGIO_PTR)(&deviceExtension->BaseIoAddressSATA_0),offs);
4680 AtapiWritePortEx4(chan, (ULONGIO_PTR)(&deviceExtension->BaseIoAddressSATA_0),offs, (0x0fUL << shift) | 0x00f000f0);
4681 } else {
4682 pr_status = AtapiReadPortEx1(chan, (ULONGIO_PTR)(&deviceExtension->BaseIoAddressSATA_0),offs);
4683 AtapiWritePortEx1(chan, (ULONGIO_PTR)(&deviceExtension->BaseIoAddressSATA_0),offs, (0x0f << shift));
4684 }
4685 KdPrint2((PRINT_PREFIX " pr_status %x, shift %x\n", pr_status, shift));
4686
4687 /* check for and handle connect events */
4688 if(((pr_status & (0x0cUL << shift)) == (0x04UL << shift)) ) {
4689 UniataSataEvent(deviceExtension, lChannel, UNIATA_SATA_EVENT_ATTACH, 0);
4690 }
4691 /* check for and handle disconnect events */
4692 if((pr_status & (0x08UL << shift)) &&
4693 !((pr_status & (0x04UL << shift) &&
4695 UniataSataEvent(deviceExtension, lChannel, UNIATA_SATA_EVENT_DETACH, 0);
4696 }
4697 /* do we have any device action ? */
4698 if(!(pr_status & (0x01UL << shift))) {
4699 KdPrint2((PRINT_PREFIX " nVidia unexpected\n"));
4700 if(UniataSataClearErr(HwDeviceExtension, c, UNIATA_SATA_DO_CONNECT, 0)) {
4701 OurInterrupt = INTERRUPT_REASON_UNEXPECTED;
4702 } else {
4704 }
4705 }
4706
4707 break; }
4708 case ATA_ATI_ID:
4709 KdPrint2((PRINT_PREFIX "ATI\n"));
4710 if(ChipType == SIIMIO) {
4711 // fall to SiI
4712 } else {
4713 break;
4714 }
4716
4717 if(ChipType == SIIMIO) {
4718
4720 KdPrint2((PRINT_PREFIX " Sii DS0 %x\n", reg32));
4721 if(reg32 == 0xffffffff) {
4722 KdPrint2((PRINT_PREFIX " Sii mio unexpected\n"));
4724 }
4726 KdPrint2((PRINT_PREFIX " Sii mio unexpected (2)\n"));
4728 }
4729
4730 if(ChipFlags & UNIATA_SATA) {
4731 if(reg32 & (BM_DS0_SII_DMA_SATA_IRQ | BM_DS0_SII_IRQ)) {
4732
4733 /* SIEN doesn't mask SATA IRQs on some 3112s. Those
4734 * controllers continue to assert IRQ as long as
4735 * SError bits are pending. Clear SError immediately.
4736 */
4737 if(UniataSataClearErr(HwDeviceExtension, c, UNIATA_SATA_DO_CONNECT, 0)) {
4738 OurInterrupt = INTERRUPT_REASON_UNEXPECTED;
4739 }
4740 }
4741 }
4742
4743 if (!DmaTransfer)
4744 break;
4745 if (!((dma_status = GetDmaStatus(deviceExtension, lChannel)) & BM_STATUS_INTR)) {
4746 KdPrint2((PRINT_PREFIX " Sii mio unexpected (3)\n"));
4747 return OurInterrupt;
4748 }
4749 AtapiWritePort1(chan, IDX_BM_Status, dma_status & ~BM_STATUS_ERR);
4750 goto skip_dma_stat_check;
4751
4752 } else {
4753 if(!(deviceExtension->HwFlags & SIIINTR))
4754 break;
4755 GetPciConfig1(0x71, reg8);
4756 KdPrint2((PRINT_PREFIX " 0x71 = %#x\n", reg8));
4757 if (!(reg8 &
4758 (Channel ? 0x08 : 0x04))) {
4760 }
4761 if (!DmaTransfer) {
4762 KdPrint2((PRINT_PREFIX " cmd our\n"));
4763 OurInterrupt = INTERRUPT_REASON_UNEXPECTED;
4764 }
4765 SetPciConfig1(0x71, (Channel ? 0x08 : 0x04));
4766 }
4767 break;
4768
4769 case ATA_ACARD_ID:
4770 if (!DmaTransfer)
4771 break;
4772 //dma_status = GetDmaStatus(deviceExtension, lChannel);
4773 if (!((dma_status = GetDmaStatus(deviceExtension, lChannel)) & BM_STATUS_INTR)) {
4774 KdPrint2((PRINT_PREFIX " Acard unexpected\n"));
4776 }
4777 AtapiWritePort1(chan, IDX_BM_Status, dma_status | BM_STATUS_INTR);
4781 goto skip_dma_stat_check;
4782 case ATA_INTEL_ID:
4783 if(UniataIsSATARangeAvailable(deviceExtension, lChannel)) {
4784 if(ChipFlags & UNIATA_AHCI) {
4785 // Do nothing here
4786 } else
4787 if(ChipFlags & UNIATA_SATA) {
4788 if(UniataSataClearErr(HwDeviceExtension, c, UNIATA_SATA_DO_CONNECT, 0)) {
4789 OurInterrupt = INTERRUPT_REASON_UNEXPECTED;
4790 }
4791 if(!(chan->ChannelCtrlFlags & CTRFLAGS_NO_SLAVE)) {
4793 OurInterrupt = INTERRUPT_REASON_UNEXPECTED;
4794 }
4795 }
4796 }
4797 }
4798 break;
4799 default:
4800 if(UniataIsSATARangeAvailable(deviceExtension, lChannel)) {
4801 if(ChipFlags & UNIATA_AHCI) {
4802 // Do nothing here
4803 } else
4804 if(ChipFlags & UNIATA_SATA) {
4805 if(UniataSataClearErr(HwDeviceExtension, c, UNIATA_SATA_DO_CONNECT, 0)) {
4806 OurInterrupt = INTERRUPT_REASON_UNEXPECTED;
4807 }
4808 }
4809 }
4810 }
4811check_unknown:
4812 KdPrint2((PRINT_PREFIX " perform generic check\n"));
4813 if (DmaTransfer) {
4814 if (!((dma_status = GetDmaStatus(deviceExtension, lChannel)) & BM_STATUS_INTR)) {
4815 KdPrint2((PRINT_PREFIX " DmaTransfer + !BM_STATUS_INTR (%x)\n", dma_status));
4816 if(dma_status & BM_STATUS_ERR) {
4817 KdPrint2((PRINT_PREFIX " DmaTransfer + BM_STATUS_ERR -> our\n"));
4818 OurInterrupt = INTERRUPT_REASON_UNEXPECTED;
4819 } else {
4820 KdPrint2((PRINT_PREFIX " getting status...\n"));
4821 GetStatus(chan, statusByte);
4822 StatusValid = 1;
4823 KdPrint2((PRINT_PREFIX " status %#x\n", statusByte));
4824 if(statusByte & IDE_STATUS_ERROR) {
4825 KdPrint2((PRINT_PREFIX " IDE_STATUS_ERROR -> our\n", statusByte));
4826 OurInterrupt = INTERRUPT_REASON_UNEXPECTED;
4827 } else
4828 if ((statusByte & IDE_STATUS_DSC) &&
4829 (LunExt->DeviceFlags & DFLAGS_ATAPI_DEVICE) &&
4830 (dma_status == BM_STATUS_ACTIVE)) {
4831 KdPrint2((PRINT_PREFIX " special case DMA + ATAPI + IDE_STATUS_DSC -> our\n", statusByte));
4832 // some devices interrupts on each block transfer even in DMA mode
4833 if(LunExt->TransferMode >= ATA_SDMA && LunExt->TransferMode <= ATA_WDMA2) {
4834 KdPrint2((PRINT_PREFIX " wait for completion\n"));
4836 //GetBaseStatus(chan, statusByte);
4837 //return INTERRUPT_REASON_IGNORE;
4838 SingleBlockIntr = TRUE;
4839 }
4840 } else {
4842 }
4843 }
4844 }
4845 } else {
4846 if(dma_status & BM_STATUS_INTR) {
4847 // bullshit, we have DMA interrupt, but had never initiate DMA operation
4848 KdPrint2((PRINT_PREFIX " clear unexpected DMA intr\n"));
4849 AtapiDmaDone(deviceExtension, DEVNUM_NOT_SPECIFIED ,lChannel, NULL);
4850 // catch it !
4851 OurInterrupt = INTERRUPT_REASON_UNEXPECTED;
4852 }
4853 }
4854skip_dma_stat_check:
4855 if(!(ChipFlags & UNIATA_SATA) && chan->ExpectingInterrupt) {
4857 }
4858
4859 /* if drive is busy it didn't interrupt */
4860 /* the exception is DCS + BSY state of ATAPI devices */
4861 if(!StatusValid) {
4862 KdPrint2((PRINT_PREFIX " getting status...\n"));
4863 GetStatus(chan, statusByte);
4864 }
4865 if(LunExt->DeviceFlags & DFLAGS_ATAPI_DEVICE) {
4866 KdPrint3((PRINT_PREFIX " ATAPI status %#x\n", statusByte));
4867 } else {
4868 KdPrint2((PRINT_PREFIX " IDE status %#x\n", statusByte));
4869 }
4870 if (statusByte == IDE_STATUS_WRONG) {
4871 // interrupt from empty controller ?
4872 } else
4873 if (statusByte & IDE_STATUS_BUSY) {
4874 if(!chan->ExpectingInterrupt) {
4875 KdPrint3((PRINT_PREFIX " unexpected intr + BUSY\n"));
4876 return OurInterrupt;
4877 }
4878
4879 if(LunExt->DeviceFlags & DFLAGS_ATAPI_DEVICE) {
4880 KdPrint2((PRINT_PREFIX " ATAPI additional check\n"));
4881 } else {
4882 KdPrint2((PRINT_PREFIX " expecting intr + BUSY (3), non ATAPI\n"));
4884 }
4885 if((statusByte & ~(IDE_STATUS_DRQ | IDE_STATUS_INDEX)) !=
4887 KdPrint3((PRINT_PREFIX " unexpected status, seems it is not our\n"));
4889 }
4890 if(!(LunExt->DeviceFlags & DFLAGS_INT_DRQ) && (statusByte & IDE_STATUS_DRQ)) {
4891 KdPrint3((PRINT_PREFIX " unexpected DRQ, seems it is not our\n"));
4893 }
4894
4895 EarlyIntr = TRUE;
4896
4897 if(dma_status & BM_STATUS_INTR) {
4898 KdPrint3((PRINT_PREFIX " our interrupt with BSY set, try wait in ISR or post to DPC\n"));
4899 /* clear interrupt and get status */
4900 GetBaseStatus(chan, statusByte);
4901 if(!(dma_status & BM_STATUS_ACTIVE)) {
4902 AtapiDmaDone(deviceExtension, DEVNUM_NOT_SPECIFIED ,lChannel, NULL);
4903 }
4904 KdPrint3((PRINT_PREFIX " base status %#x (+BM_STATUS_INTR)\n", statusByte));
4905 return INTERRUPT_REASON_OUR;
4906 }
4907
4908 if(g_WaitBusyInISR) {
4909 GetStatus(chan, statusByte);
4910 KdPrint2((PRINT_PREFIX " status re-check %#x\n", statusByte));
4911 reg8 = AtapiReadPort1(chan, IDX_IO1_i_Error);
4912 KdPrint2((PRINT_PREFIX " Error reg (%#x)\n", reg8));
4913 if (!(statusByte & IDE_STATUS_BUSY)) {
4914 KdPrint2((PRINT_PREFIX " expecting intr + cleared BUSY\n"));
4915 }
4916 if (statusByte & IDE_STATUS_BUSY) {
4917 KdPrint2((PRINT_PREFIX " still BUSY, seems it is not our\n"));
4919 }
4920 }
4921
4922 }
4923
4924 /* clear interrupt and get status */
4925 GetBaseStatus(chan, statusByte);
4926 KdPrint2((PRINT_PREFIX " base status %#x\n", statusByte));
4927 if (statusByte == IDE_STATUS_WRONG) {
4928 // interrupt from empty controller ?
4929 } else
4930 if(!(statusByte & (IDE_STATUS_DRQ | IDE_STATUS_DRDY))) {
4931 KdPrint2((PRINT_PREFIX " no DRQ/DRDY set\n"));
4932 return OurInterrupt;
4933 }
4934
4935#ifndef UNIATA_PIO_ONLY
4936 if(DmaTransfer) {
4937 if(!SingleBlockIntr && (!EarlyIntr || g_WaitBusyInISR)) {
4938 dma_status = AtapiDmaDone(HwDeviceExtension, DEVNUM_NOT_SPECIFIED, lChannel, NULL/*srb*/);
4939 } else {
4941 PATA_REQ AtaReq = srb ? (PATA_REQ)(srb->SrbExtension) : NULL;
4942
4943 //ASSERT(AtaReq);
4944
4945 if(SingleBlockIntr) {
4946 KdPrint2((PRINT_PREFIX " set REQ_STATE_ATAPI_EXPECTING_DATA_INTR2.\n"));
4947 } else {
4948 KdPrint2((PRINT_PREFIX " set REQ_STATE_EARLY_INTR.\n"));
4949 }
4950 if(AtaReq) {
4952 }
4953 }
4954 }
4955#endif //
4956
4957 if (!(chan->ExpectingInterrupt)) {
4958
4959 KdPrint2((PRINT_PREFIX " Unexpected interrupt.\n"));
4960
4961 if(LunExt->DeviceFlags & DFLAGS_ATAPI_DEVICE) {
4962 KdPrint2((PRINT_PREFIX " ATAPI additional check\n"));
4963 } else {
4964 KdPrint2((PRINT_PREFIX " OurInterrupt = %d\n", OurInterrupt));
4965 return OurInterrupt;
4966 }
4968 KdPrint3((PRINT_PREFIX "AtapiCheckInterrupt__: ATAPI int reason %x\n", interruptReason));
4969 return OurInterrupt;
4970 }
4971 //ASSERT(!chan->queue_depth || chan->cur_req);
4972
4973 KdPrint2((PRINT_PREFIX "AtapiCheckInterrupt__: exit with TRUE\n"));
4974 return INTERRUPT_REASON_OUR;
4975
4976} // end AtapiCheckInterrupt__()
4977
4978
4979BOOLEAN
4980NTAPI
4982 IN PVOID HwDeviceExtension,
4983 IN UCHAR c
4984 )
4985{
4986 PHW_DEVICE_EXTENSION deviceExtension = (PHW_DEVICE_EXTENSION)HwDeviceExtension;
4987 PHW_CHANNEL chan = &(deviceExtension->chan[c]);
4988 // Get current Srb
4990 PATA_REQ AtaReq = srb ? (PATA_REQ)(srb->SrbExtension) : NULL;
4991
4992 ULONG wordCount = 0, wordsThisInterrupt = DEV_BSIZE/2;
4994 UCHAR dma_status = 0;
4995 ULONG i;
4996 ULONG k;
4997 UCHAR statusByte = 0,interruptReason;
4998
4999 BOOLEAN atapiDev = FALSE;
5000
5001#ifdef _DEBUG
5002 UCHAR Channel;
5003#endif //_DEBUG
5004 UCHAR lChannel;
5006 BOOLEAN DmaTransfer = FALSE;
5007 UCHAR error = 0;
5008 ULONG TimerValue = 1000;
5009 ULONG TotalTimerValue = 0;
5010#ifdef UNIATA_USE_XXableInterrupts
5012#else
5013 BOOLEAN InDpc = (chan->DpcState != DPC_STATE_ISR);
5014#endif // UNIATA_USE_XXableInterrupts
5015 BOOLEAN UseDpc = deviceExtension->UseDpc;
5016// BOOLEAN RestoreUseDpc = FALSE;
5017 BOOLEAN DataOverrun = FALSE;
5018 BOOLEAN NoStartIo = TRUE;
5020
5021 KdPrint2((PRINT_PREFIX "AtapiInterrupt:\n"));
5022 if(InDpc) {
5023 KdPrint2((PRINT_PREFIX " InDpc = TRUE\n"));
5024 //ASSERT((chan->ChannelCtrlFlags & CTRFLAGS_INTR_DISABLED));
5025 }
5026
5027 UCHAR PathId;
5029 UCHAR Lun;
5030 UCHAR OldReqState = REQ_STATE_NONE;
5031 //ULONG ldev;
5032 PHW_LU_EXTENSION LunExt;
5033
5034 lChannel = c;
5035
5036#ifdef _DEBUG
5037 Channel = (UCHAR)(deviceExtension->Channel + lChannel);
5038
5039 KdPrint2((PRINT_PREFIX " cntrlr %#x:%d, irql %#x, c %d\n", deviceExtension->DevIndex, Channel, KeGetCurrentIrql(), c));
5040#endif //_DEBUG
5041
5043 (AtaReq && (AtaReq->Flags & REQ_FLAG_DMA_OPERATION)) ||
5044 (deviceExtension->HwFlags & UNIATA_AHCI)) {
5045 DmaTransfer = TRUE;
5046 KdPrint2((PRINT_PREFIX " DmaTransfer = TRUE\n"));
5047 }
5048
5049 if (srb) {
5050 PathId = srb->PathId;
5051 TargetId = srb->TargetId;
5052 Lun = srb->Lun;
5053 } else {
5054 PathId = (UCHAR)c;
5055 TargetId =
5056 Lun = 0;
5057 goto enqueue_next_req;
5058 }
5059
5060 //ldev = GET_LDEV2(PathId, TargetId, Lun);
5062 LunExt = chan->lun[DeviceNumber];
5063 atapiDev = (LunExt->DeviceFlags & DFLAGS_ATAPI_DEVICE) ? TRUE : FALSE;
5064 KdPrint2((PRINT_PREFIX " dev_type %s\n", atapiDev ? "ATAPI" : "IDE"));
5065
5066 // check if we are in ISR DPC
5067 if(InDpc) {
5068 KdPrint2((PRINT_PREFIX " InDpc -> CTRFLAGS_INTR_DISABLED\n"));
5069 goto ServiceInterrupt;
5070 }
5071
5072 if (DmaTransfer) {
5073 dma_status = GetDmaStatus(deviceExtension, lChannel);
5074 }
5075
5076 if (!(chan->ExpectingInterrupt)) {
5077
5078 KdPrint2((PRINT_PREFIX " Unexpected interrupt for this channel.\n"));
5079 return FALSE;
5080 }
5081
5082 // change request state
5083 if(AtaReq) {
5084 OldReqState = AtaReq->ReqState;
5086 KdPrint2((PRINT_PREFIX " OldReqState = %x\n", OldReqState));
5087 }
5088
5089 // We don't want using DPC for fast operations, like
5090 // DMA completion, sending CDB, short ATAPI transfers, etc.
5091 // !!!! BUT !!!!
5092 // We MUST use DPC, because of interprocessor synchronization
5093 // on multiprocessor platforms
5094
5095 if(DmaTransfer)
5096 goto ServiceInterrupt;
5097
5098 switch(OldReqState) {
5100 KdPrint3((PRINT_PREFIX " EXPECTING_CMD_INTR\n"));
5105 KdPrint2((PRINT_PREFIX " continue service interrupt\n"));
5106 goto ServiceInterrupt;
5108 KdPrint2((PRINT_PREFIX " do nothing on interrupt\n"));
5109 return TRUE;
5110 }
5111
5112 if((!DmaTransfer && !atapiDev) || deviceExtension->DriverMustPoll) {
5113 KdPrint2((PRINT_PREFIX " service PIO HDD\n"));
5114 UseDpc = FALSE;
5115 }
5116
5117#ifndef UNIATA_CORE
5118
5119 if(!UseDpc)
5120 goto ServiceInterrupt;
5121
5122#ifdef UNIATA_USE_XXableInterrupts
5123 if(InDpc) {
5124 KdPrint2((PRINT_PREFIX " Unexpected InDpc\n"));
5125 ASSERT(FALSE);
5126 // shall never get here
5127 TimerValue = 1;
5128 goto CallTimerDpc;
5129 }
5130
5131 KdPrint2((PRINT_PREFIX " this is direct DPC call on DRQL\n"));
5132 if(AtaReq) {
5134 KdPrint2((PRINT_PREFIX " ReqState -> REQ_STATE_DPC_INTR_REQ\n"));
5135 } else {
5136 KdPrint2((PRINT_PREFIX " DPC without AtaReq!!!\n"));
5137 }
5138#else
5139 KdPrint2((PRINT_PREFIX "call service interrupt\n"));
5140 goto ServiceInterrupt;
5141#endif // UNIATA_USE_XXableInterrupts
5142
5143PostToDpc:
5144
5145 // Attention !!!
5146 // AtapiInterruptDpc() is called on DISPATCH_LEVEL
5147 // We always get here when are called from timer callback, which is invoked on DRQL.
5148 // It is intended to lower IRQL and let other interrupts to be serviced while we are waiting for BUSY release
5149
5150 KdPrint2((PRINT_PREFIX "AtapiInterrupt: start DPC init...\n"));
5151 // disable interrupts for this channel,
5152 // but avoid recursion and double-disable
5153 if(OldReqState != REQ_STATE_DPC_WAIT_BUSY1) {
5155 AtapiDisableInterrupts(deviceExtension, lChannel);
5156 }
5157 // go to ISR DPC
5159
5160#ifdef UNIATA_USE_XXableInterrupts
5161 // Will lower IRQL to DISPATCH_LEVEL
5162 ScsiPortNotification(CallEnableInterrupts, HwDeviceExtension,
5163 /*c ?*/ AtapiInterruptDpc/*_1 : AtapiInterruptDpc_0*/);
5164 KdPrint2((PRINT_PREFIX "AtapiInterrupt: DPC inited\n"));
5165#else
5166 // Will raise IRQL to DIRQL
5167 AtapiQueueTimerDpc(HwDeviceExtension, c,
5169 TimerValue);
5170 KdPrint2((PRINT_PREFIX "AtapiInterrupt: Timer DPC inited\n"));
5171#endif // UNIATA_USE_XXableInterrupts
5172 return TRUE;
5173
5174#ifndef UNIATA_CORE
5175CallTimerDpc:
5177CallTimerDpc2:
5178 if(!InDpc && OldReqState != REQ_STATE_DPC_WAIT_BUSY1) {
5179 // we must block interrupts from this channel
5180 // If device generate new interrupt before we get to DPC,
5181 // ISR will assume, that it is NOT our interrupt
5182 AtapiDisableInterrupts(deviceExtension, lChannel);
5183 // We should not clean ExpectingInterrupt flag on channel, since it is used in DPC
5184 }
5185 // Will raise IRQL to DIRQL
5186 AtapiQueueTimerDpc(HwDeviceExtension, c,
5188 TimerValue);
5189 return TRUE;
5190#endif //UNIATA_CORE
5191
5192ServiceInterrupt:
5193
5194 if(AtaReq && InDpc) {
5195 switch(AtaReq->ReqState) {
5197 goto PIO_wait_DRQ0;
5199 goto PIO_wait_busy;
5201 goto PIO_wait_DRQ;
5203 goto continue_err;
5206 // continue normal execution
5207 break;
5208 }
5209 }
5210#else
5211ServiceInterrupt:
5212#endif //UNIATA_CORE
5213/*
5214 // make additional delay for old devices (if we are not in DPC)
5215 if((!LunExt->IdentifyData.MajorRevision || (deviceExtension->lun[DeviceNumber].TransferMode < ATA_PIO4))
5216 &&
5217 !InDpc &&
5218 !atapiDev &&
5219 !(deviceExtension->HwFlags & UNIATA_SATA)
5220 ) {
5221 KdPrint2((PRINT_PREFIX " additional delay 10us for old devices\n"));
5222 AtapiStallExecution(10);
5223 }
5224*/
5225
5226 /* clear interrupt and get status */
5227 if(deviceExtension->HwFlags & UNIATA_AHCI) {
5228 UniataAhciEndTransaction(HwDeviceExtension, lChannel, DeviceNumber, srb);
5229 statusByte = (UCHAR)(AtaReq->ahci.in_status & IDE_STATUS_MASK);
5230
5232 KdPrint3((PRINT_PREFIX "Err intr (%#x), SE (%#x)\n",
5234 chan->AhciLastSError));
5235 if(chan->AhciLastIS & ~ATA_AHCI_P_IX_OF) {
5236
5237 if((chan->AhciLastIS == ATA_AHCI_P_IX_INF) &&
5238 !(statusByte & IDE_STATUS_ERROR) &&
5239 !chan->AhciLastSError &&
5240 srb && (srb->SrbFlags & SRB_FLAGS_DATA_IN)
5241 ) {
5242 KdPrint3((PRINT_PREFIX "ATA_AHCI_P_IX_INF on READ, assume underflow\n"));
5243 // continue processing in regular way
5244 } else {
5245
5246 //KdPrint3((PRINT_PREFIX "Err mask (%#x)\n", chan->AhciLastIS & ~ATA_AHCI_P_IX_OF));
5247 // We have some other error except Overflow
5248 // Just signal ERROR, operation will be aborted in ERROR branch.
5249 statusByte |= IDE_STATUS_ERROR;
5250 AtaReq->ahci.in_serror = chan->AhciLastSError;
5252 KdPrint2((PRINT_PREFIX "Unrecoverable\n"));
5253 NoRetry = TRUE;
5254 }
5255 }
5256 } else {
5257 // We have only Overflow. Abort operation and continue
5258#ifdef _DEBUG
5259 UniataDumpAhciPortRegs(chan);
5260#endif
5261 if(!UniataAhciAbortOperation(chan)) {
5262 KdPrint2((PRINT_PREFIX "need UniataAhciReset\n"));
5263 }
5264#ifdef _DEBUG
5265 UniataDumpAhciPortRegs(chan);
5266#endif
5268 }
5269 }
5270
5271 } else {
5272 GetBaseStatus(chan, statusByte);
5273 }
5274 if(atapiDev) {
5275 KdPrint3((PRINT_PREFIX "AtapiInterrupt: ATAPI Entered with status (%#x)\n", statusByte));
5276 } else {
5277 KdPrint2((PRINT_PREFIX "AtapiInterrupt: Entered with status (%#x)\n", statusByte));
5278 }
5279
5280 if(!UseDpc) {
5281 KdPrint2((PRINT_PREFIX " operate like in DPC\n"));
5282 InDpc = TRUE;
5283 }
5284
5285 if (!atapiDev) {
5286 // IDE
5287 if(deviceExtension->HwFlags & UNIATA_AHCI) {
5288 KdPrint3((PRINT_PREFIX " AHCI branch (IDE)\n"));
5289 } else
5290 if (statusByte & IDE_STATUS_BUSY) {
5291 if (deviceExtension->DriverMustPoll) {
5292 // Crashdump is polling and we got caught with busy asserted.
5293 // Just go away, and we will be polled again shortly.
5294 KdPrint2((PRINT_PREFIX " Hit BUSY while polling during crashdump.\n"));
5295 goto ReturnEnableIntr;
5296 }
5297try_dpc_wait:
5298 // Ensure BUSY is non-asserted.
5299 // make a very small idle before falling to DPC
5300 k = (InDpc && UseDpc) ? 1000 : 2;
5301
5302 for (i = 0; i < k; i++) {
5303
5304 GetBaseStatus(chan, statusByte);
5305 if (!(statusByte & IDE_STATUS_BUSY)) {
5306 break;
5307 }
5309 }
5310
5311 if (!InDpc && UseDpc && i == 2) {
5312
5313 KdPrint2((PRINT_PREFIX " BUSY on entry. Status %#x, Base IO %#x\n", statusByte));
5314
5315 TimerValue = 50;
5317
5318#ifndef UNIATA_CORE
5319 goto PostToDpc;
5320#else //UNIATA_CORE
5321 AtapiStallExecution(TimerValue);
5322 goto ServiceInterrupt;
5323#endif //UNIATA_CORE
5324 } else
5325 if (InDpc && i == k) {
5326 // reset the controller.
5328 " Resetting due to BUSY on entry - %#x.\n",
5329 statusByte));
5330 goto IntrPrepareResetController;
5331 }
5332 }
5333 } else {
5334 // ATAPI
5335 if(!LunExt->IdentifyData.MajorRevision &&
5336 InDpc &&
5338 !(deviceExtension->HwFlags & UNIATA_SATA)
5339 ) {
5340 //KdPrint2((PRINT_PREFIX " additional delay 10us for old devices (2)\n"));
5341 //AtapiStallExecution(10);
5342 }
5343 if(deviceExtension->HwFlags & UNIATA_AHCI) {
5344 KdPrint3((PRINT_PREFIX " AHCI branch (ATAPI)\n"));
5345 } else {
5347 KdPrint3((PRINT_PREFIX "AtapiInterrupt: iReason %x\n", interruptReason));
5348 }
5349
5350 if (statusByte & IDE_STATUS_BUSY) {
5351 //if(chan->ChannelCtrlFlags & CTRFLAGS_DSC_BSY) {}
5352/*
5353#ifndef UNIATA_CORE
5354 // This is just workaround
5355 // We should DISABLE interrupts before entering WAIT state
5356 UniataExpectChannelInterrupt(chan, TRUE);
5357#endif //UNIATA_CORE
5358*/
5359 KdPrint3((PRINT_PREFIX " BUSY on ATAPI device, waiting %d us\n", LunExt->AtapiReadyWaitDelay));
5360#ifndef UNIATA_CORE
5361 if(LunExt->AtapiReadyWaitDelay && (LunExt->AtapiReadyWaitDelay > g_opt_MaxIsrWait) && !InDpc && UseDpc) {
5362 TimerValue = LunExt->AtapiReadyWaitDelay;
5363 KdPrint2((PRINT_PREFIX " too long wait: ISR -> DPC (0)\n"));
5365 goto CallTimerDpc2;
5366 }
5367#endif //UNIATA_CORE
5368 TimerValue = 10;
5369 for(k=20; k; k--) {
5370 GetBaseStatus(chan, statusByte);
5371 KdPrint3((PRINT_PREFIX " status re-check %#x\n", statusByte));
5372 KdPrint3((PRINT_PREFIX " Error reg (%#x)\n",
5374 if (!(statusByte & IDE_STATUS_BUSY)) {
5375 KdPrint2((PRINT_PREFIX " expecting intr + cleared BUSY\n"));
5376 break;
5377 }
5378 TotalTimerValue += TimerValue;
5379 if(k <= 1) {
5380 KdPrint3((PRINT_PREFIX " too long wait -> DPC\n"));
5381 if(!InDpc) {
5382 KdPrint2((PRINT_PREFIX " too long wait: ISR -> DPC\n"));
5383 TimerValue = 100;
5385 } else {
5386 KdPrint2((PRINT_PREFIX " too long wait: DPC -> DPC\n"));
5387 TimerValue = 1000;
5389 }
5390#ifndef UNIATA_CORE
5391 if(UseDpc) {
5392 if(!LunExt->AtapiReadyWaitDelay) {
5393 LunExt->AtapiReadyWaitDelay = TotalTimerValue*2/3;
5394 }
5395 goto CallTimerDpc2;
5396 }
5397#endif //UNIATA_CORE
5398 }
5399
5400 AtapiStallExecution(TimerValue);
5401 TimerValue += 10;
5402 }
5403 if(!LunExt->AtapiReadyWaitDelay) {
5404 LunExt->AtapiReadyWaitDelay = TotalTimerValue*2/3;
5405 KdPrint2((PRINT_PREFIX " store AtapiReadyWaitDelay: %d\n", LunExt->AtapiReadyWaitDelay));
5406 }
5407 if (statusByte & IDE_STATUS_BUSY) {
5408 KdPrint3((PRINT_PREFIX " expecting intr + BUSY (2), try DPC wait\n"));
5409 goto try_dpc_wait;
5410 }
5411 }
5412 }
5413
5414 if(AtaReq && DmaTransfer && !(deviceExtension->HwFlags & UNIATA_AHCI)) {
5415 switch(OldReqState) {
5418
5420 KdPrint2((PRINT_PREFIX "AtapiInterrupt: DMA still active\n"));
5421 dma_status = AtapiDmaDone(HwDeviceExtension, DEVNUM_NOT_SPECIFIED, lChannel, NULL/*srb*/);
5422 }
5423 break;
5424 }
5425 }
5426
5427//retry_check:
5428 // Check for error conditions.
5429 if ((statusByte & IDE_STATUS_ERROR) ||
5430 (dma_status & BM_STATUS_ERR)) {
5431
5432 if(deviceExtension->HwFlags & UNIATA_AHCI) {
5433 error = AtaReq->ahci.in_error;
5434 // wait ready
5435#ifdef _DEBUG
5436 UniataDumpAhciPortRegs(chan);
5437#endif
5438 if(!UniataAhciAbortOperation(chan)) {
5439 KdPrint2((PRINT_PREFIX "need UniataAhciReset\n"));
5440 }
5441 // clear interrupts again
5443#ifdef _DEBUG
5444 UniataDumpAhciPortRegs(chan);
5445#endif
5446 UniataAhciStatus(HwDeviceExtension, lChannel, DEVNUM_NOT_SPECIFIED);
5447 if(NoRetry) {
5448 AtaReq->retry += MAX_RETRIES;
5449 if(!error && (statusByte & IDE_STATUS_ERROR)) {
5450 KdPrint2((PRINT_PREFIX "AtapiInterrupt: force error status\n"));
5452 }
5453 }
5454#ifdef _DEBUG
5455 UniataDumpAhciPortRegs(chan);
5456#endif
5457 } else {
5459 }
5460 KdPrint2((PRINT_PREFIX "AtapiInterrupt: Error %#x\n", error));
5461/*
5462 if(error & IDE_STATUS_CORRECTED_ERROR) {
5463 KdPrint2((PRINT_PREFIX "AtapiInterrupt: (corrected)\n"));
5464 statusByte &= ~IDE_STATUS_ERROR;
5465 goto retry_check;
5466 }
5467*/
5468 if(AtaReq) {
5469 KdPrint2((PRINT_PREFIX " Bad Lba %#I64x\n", AtaReq->lba));
5470 } else {
5471 KdPrint2((PRINT_PREFIX " Bad Lba unknown\n"));
5472 }
5473
5474 if(deviceExtension->HwFlags & UNIATA_AHCI) {
5475 KdPrint2((PRINT_PREFIX " no wait ready after error\n"));
5476 } else
5477 if(!atapiDev) {
5478 KdPrint2((PRINT_PREFIX " wait 100 ready after IDE error\n"));
5480 } else {
5481 KdPrint2((PRINT_PREFIX " wait 10 ready after ATAPI error\n"));
5483 }
5484continue_err:
5485
5486 KdPrint3((PRINT_PREFIX " Intr on DRQ %x\n",
5487 LunExt->DeviceFlags & DFLAGS_INT_DRQ));
5488
5489 for (k = atapiDev ? 0 : 200; k; k--) {
5490 GetBaseStatus(chan, statusByte);
5491 if (!(statusByte & IDE_STATUS_DRQ)) {
5493 } else {
5494 break;
5495 }
5496 }
5497
5498 if (!atapiDev) {
5499 /* if this is a UDMA CRC error, reinject request */
5500
5501 AtaReq->retry++;
5502 if(AtaReq->retry < MAX_RETRIES) {
5503#ifdef IO_STATISTICS
5504 chan->lun[DeviceNumber]->ModeErrorCount[AtaReq->retry]++;
5505#endif //IO_STATISTICS
5506 if(DmaTransfer /*&&
5507 (error & IDE_ERROR_ICRC)*/) {
5508 KdPrint2((PRINT_PREFIX "Errors in DMA mode\n"));
5509 if(AtaReq->retry < MAX_RETRIES) {
5510//fallback_pio:
5511 if(!(deviceExtension->HwFlags & UNIATA_AHCI)) {
5512 //AtaReq->Flags &= ~REQ_FLAG_DMA_OPERATION;
5513 // Downrate will happen in AtapiDmaReinit(), try UDMA-2 for HDD only
5514 AtaReq->Flags |= REQ_FLAG_FORCE_DOWNRATE;
5515 }
5516 AtaReq->ReqState = REQ_STATE_QUEUED;
5517 goto reenqueue_req;
5518 }
5519 } else {
5520 if(!(AtaReq->Flags & REQ_FLAG_FORCE_DOWNRATE)) {
5521 AtaReq->retry++;
5522 }
5523 KdPrint2((PRINT_PREFIX "Errors in PIO mode\n"));
5524 }
5525 }
5526 } else {
5528 KdPrint3((PRINT_PREFIX "AtapiInterrupt: ATAPI Error, int reason %x\n", interruptReason));
5529
5530 if(UniataIsSATARangeAvailable(deviceExtension, lChannel)) {
5531 if(deviceExtension->HwFlags & UNIATA_AHCI) {
5532 // Do nothing here
5533 } else
5534 if(deviceExtension->HwFlags & UNIATA_SATA) {
5535 UniataSataClearErr(HwDeviceExtension, lChannel, UNIATA_SATA_IGNORE_CONNECT, 0);
5536 }
5537 }
5538
5539 if(DmaTransfer && (chan->lun[DeviceNumber]->TransferMode > ATA_UDMA2) &&
5540 ((error >> 4) == SCSI_SENSE_HARDWARE_ERROR)) {
5541 if(AtaReq->retry < MAX_RETRIES) {
5542//fallback_pio:
5543 // Downrate will happen in AtapiDmaReinit(), use PIO immediately for ATAPI
5544 AtaReq->Flags &= ~REQ_FLAG_DMA_OPERATION;
5545 AtaReq->Flags |= REQ_FLAG_FORCE_DOWNRATE;
5546// LunExt->DeviceFlags |= DFLAGS_FORCE_DOWNRATE;
5547 AtaReq->ReqState = REQ_STATE_QUEUED;
5548 goto reenqueue_req;
5549 }
5550 } else {
5551 if(!(AtaReq->Flags & REQ_FLAG_FORCE_DOWNRATE)) {
5552 AtaReq->retry++;
5553 }
5554 KdPrint3((PRINT_PREFIX "Errors in PIO mode\n"));
5555 }
5556 }
5557
5558 KdPrint3((PRINT_PREFIX "AtapiInterrupt: Error\n"));
5559 if (srb->Cdb[0] != SCSIOP_REQUEST_SENSE) {
5560 // Fail this request.
5562 goto CompleteRequest;
5563 } else {
5564 KdPrint2((PRINT_PREFIX " continue with SCSIOP_REQUEST_SENSE\n"));
5565 }
5566 } else
5567 if(AtaReq->Flags & REQ_FLAG_FORCE_DOWNRATE_LBA48) {
5568 KdPrint2((PRINT_PREFIX "DMA doesn't work right with LBA48\n"));
5569 deviceExtension->HbaCtrlFlags |= HBAFLAGS_DMA_DISABLED_LBA48;
5570 } else
5571 if(AtaReq->Flags & REQ_FLAG_FORCE_DOWNRATE) {
5572#ifdef IO_STATISTICS
5573 KdPrint2((PRINT_PREFIX "Some higher mode doesn't work right :((\n"));
5574 KdPrint2((PRINT_PREFIX "Recovery stats[%d]: %d vs %d\n",
5575 AtaReq->retry,
5576 LunExt->RecoverCount[AtaReq->retry],
5577 LunExt->BlockIoCount
5578 ));
5579 LunExt->RecoverCount[AtaReq->retry]++;
5580 if(LunExt->RecoverCount[AtaReq->retry] >= LunExt->BlockIoCount/3 ||
5581 (deviceExtension->HwFlags & UNIATA_NO80CHK)
5582 ) {
5583#else
5584 if(deviceExtension->HwFlags & UNIATA_NO80CHK) {
5585#endif //IO_STATISTICS
5586 KdPrint2((PRINT_PREFIX "Limit transfer rate to %x\n", LunExt->TransferMode));
5587 LunExt->LimitedTransferMode =
5588 LunExt->TransferMode;
5589 }
5590 }
5591#ifdef IO_STATISTICS
5592 if(AtaReq->bcount) {
5593 // we need stats for Read/Write operations
5594 LunExt->BlockIoCount++;
5595 }
5596 LunExt->IoCount++;
5597#endif //IO_STATISTICS
5598
5599continue_PIO:
5600
5601 // check reason for this interrupt.
5602 if (atapiDev) {
5603
5604 KdPrint2((PRINT_PREFIX "AtapiInterrupt: ATAPI branch\n"));
5605 // ATAPI branch
5606
5608 KdPrint3((PRINT_PREFIX "AtapiInterrupt: iReason %x\n", interruptReason));
5609 if(DmaTransfer) {
5610 wordsThisInterrupt = DEV_BSIZE/2*512;
5611 } else {
5612 wordsThisInterrupt = DEV_BSIZE/2;
5613 }
5614
5615 } else {
5616
5617 // ATA branch
5618
5619 if(DmaTransfer) {
5620 // simulate DRQ for DMA transfers
5621 statusByte |= IDE_STATUS_DRQ;
5622 }
5623 if (statusByte & IDE_STATUS_DRQ) {
5624
5625 if(DmaTransfer) {
5626 wordsThisInterrupt = DEV_BSIZE/2*512;
5627 } else
5628 if (LunExt->MaximumBlockXfer) {
5629 wordsThisInterrupt = DEV_BSIZE/2 * LunExt->MaximumBlockXfer;
5630 }
5631
5632 if (srb->SrbFlags & SRB_FLAGS_DATA_IN) {
5633
5634 interruptReason = ATAPI_IR_IO_toHost;
5635
5636 } else if (srb->SrbFlags & SRB_FLAGS_DATA_OUT) {
5637 interruptReason = ATAPI_IR_IO_toDev;
5638
5639 } else {
5641 goto CompleteRequest;
5642 }
5643
5644 } else if (statusByte & IDE_STATUS_BUSY) {
5645
5646 //AtapiEnableInterrupts(deviceExtension, lChannel);
5647 KdPrint2((PRINT_PREFIX "AtapiInterrupt: return FALSE on ATA IDE_STATUS_BUSY\n"));
5648 return FALSE;
5649
5650 } else {
5651
5652 KdPrint2((PRINT_PREFIX "AtapiInterrupt: !DRQ, !BUSY, WordsLeft %#x\n", AtaReq->WordsLeft));
5653 if (AtaReq->WordsLeft) {
5654
5655 // Funky behaviour seen with PCI IDE (not all, just one).
5656PIO_wait_DRQ0:
5657 // The ISR hits with DRQ low, but comes up later.
5658 for (k = 0; k < 5000; k++) {
5659 GetBaseStatus(chan, statusByte);
5660 if (statusByte & IDE_STATUS_DRQ) {
5661 break;
5662 }
5663 if(!InDpc) {
5664 // goto DPC
5666 TimerValue = 100;
5667 KdPrint2((PRINT_PREFIX "AtapiInterrupt: go to DPC (drq0)\n"));
5668#ifndef UNIATA_CORE
5669 goto PostToDpc;
5670#else //UNIATA_CORE
5671 AtapiStallExecution(TimerValue);
5672 goto ServiceInterrupt;
5673#endif //UNIATA_CORE
5674 }
5676 }
5677 if (k == 5000) {
5678 // reset the controller.
5679 KdPrint2((PRINT_PREFIX "AtapiInterrupt: Resetting due to DRQ not up. Status %#x\n",
5680 statusByte));
5681IntrPrepareResetController:
5682 AtapiResetController__(HwDeviceExtension, lChannel, RESET_COMPLETE_CURRENT);
5683 goto ReturnEnableIntr;
5684
5685 } else {
5686 interruptReason = (srb->SrbFlags & SRB_FLAGS_DATA_IN) ? ATAPI_IR_IO_toHost : ATAPI_IR_IO_toDev;
5687 }
5688
5689 } else {
5690 // Command complete - verify, write, or the SMART enable/disable.
5691 // Also get_media_status
5692 interruptReason = ATAPI_IR_IO_toHost | ATAPI_IR_COD_Cmd;
5693 }
5694 }
5695 }
5696
5697 KdPrint2((PRINT_PREFIX "AtapiInterrupt: i-reason=%d, status=%#x\n", interruptReason, statusByte));
5698 if(deviceExtension->HwFlags & UNIATA_AHCI) {
5699 KdPrint2((PRINT_PREFIX " AHCI path, WordsTransfered %x, WordsLeft %x\n", AtaReq->WordsTransfered, AtaReq->WordsLeft));
5700/* if(chan->AhciLastIS & ATA_AHCI_P_IX_OF) {
5701 //status = SRB_STATUS_DATA_OVERRUN;
5702 DataOverrun = TRUE;
5703 } else {
5704 status = SRB_STATUS_SUCCESS;
5705 }*/
5706 if(AtaReq->WordsTransfered >= AtaReq->WordsLeft) {
5707 AtaReq->WordsLeft = 0;
5708 } else {
5709 AtaReq->WordsLeft -= AtaReq->WordsTransfered;
5710 }
5711 //if(AtaReq->WordsLeft && (status == SRB_STATUS_SUCCESS)) {
5712 // status = SRB_STATUS_DATA_OVERRUN;
5713 //}
5715 chan->ChannelCtrlFlags &= ~CTRFLAGS_DMA_OPERATION;
5716 goto CompleteRequest;
5717 } else
5718 if ((interruptReason == ATAPI_IR_COD_Cmd) && (statusByte & IDE_STATUS_DRQ)) {
5720 AtapiDmaDBPreSync(HwDeviceExtension, chan, srb);
5721 }
5722 // Write the packet.
5723 KdPrint3((PRINT_PREFIX "AtapiInterrupt: Writing Atapi packet.\n"));
5724 // Send CDB to device.
5725 WriteBuffer(chan, (PUSHORT)srb->Cdb,
5726 LunExt->IdentifyData.AtapiCmdSize ? 8 : 6,
5727 /*0*/ PIO0_TIMING);
5729
5731 KdPrint2((PRINT_PREFIX "AtapiInterrupt: AtapiDmaStart().\n"));
5732 AtapiDmaStart(HwDeviceExtension, DeviceNumber, lChannel, srb);
5733 }
5734
5735 goto ReturnEnableIntr;
5736
5737 } else if ((interruptReason == ATAPI_IR_IO_toDev) && (statusByte & IDE_STATUS_DRQ)) {
5738
5739 // Write the data.
5740 if (atapiDev) {
5741
5742 // Pick up bytes to transfer and convert to words.
5743 wordCount =
5745
5746 wordCount |=
5748
5749 // Covert bytes to words.
5750 wordCount >>= 1;
5751 KdPrint2((PRINT_PREFIX "AtapiInterrupt: get W wordCount %#x\n", wordCount));
5752
5753 if (wordCount != AtaReq->WordsLeft) {
5755 "AtapiInterrupt: %d words requested; %d words xferred\n",
5756 AtaReq->WordsLeft,
5757 wordCount));
5758 }
5759
5760 // Verify this makes sense.
5761 if (wordCount > AtaReq->WordsLeft) {
5762 wordCount = AtaReq->WordsLeft;
5764 "AtapiInterrupt: Write underrun\n"));
5765 DataOverrun = TRUE;
5766 }
5767
5768 } else {
5769
5770 // IDE path. Check if words left is at least DEV_BSIZE/2 = 256.
5771 if (AtaReq->WordsLeft < wordsThisInterrupt) {
5772 // Transfer only words requested.
5773 wordCount = AtaReq->WordsLeft;
5774 } else {
5775 // Transfer next block.
5776 wordCount = wordsThisInterrupt;
5777 }
5778 }
5779
5780 if (DmaTransfer &&
5782 //ASSERT(AtaReq->WordsLeft == wordCount);
5785 "IdeIntr: DMA tmp INTR %#x vs %#x\n", AtaReq->WordsLeft, wordCount));
5786 if(AtaReq->WordsLeft > wordCount) {
5787 AtaReq->WordsLeft -= wordCount;
5788 AtaReq->WordsTransfered += wordCount;
5790 goto ReturnEnableIntr;
5791 }
5792 dma_status = AtapiDmaDone(HwDeviceExtension, DEVNUM_NOT_SPECIFIED, lChannel, NULL/*srb*/);
5793 }
5794 AtaReq->WordsTransfered = AtaReq->WordsLeft;
5795 AtaReq->WordsLeft = 0;
5797 chan->ChannelCtrlFlags &= ~CTRFLAGS_DMA_OPERATION;
5798 goto CompleteRequest;
5799 }
5800
5801 // Ensure that this is a write command.
5802 if (srb->SrbFlags & SRB_FLAGS_DATA_OUT) {
5803
5805 "AtapiInterrupt: Write interrupt\n"));
5806
5807 statusByte = WaitOnBusy(chan);
5808
5809 if (/*atapiDev || */ !(LunExt->DeviceFlags & DFLAGS_DWORDIO_ENABLED)
5810 || (wordCount & 1)) {
5811
5812 WriteBuffer(chan,
5813 AtaReq->DataBuffer,
5814 wordCount,
5815 UniataGetPioTiming(LunExt));
5816 } else {
5817
5818 WriteBuffer2(chan,
5819 (PULONG)(AtaReq->DataBuffer),
5820 wordCount / 2,
5821 UniataGetPioTiming(LunExt));
5822 }
5823 } else {
5824
5826 "AtapiInterrupt: Int reason %#x, but srb is for a read %#x.\n",
5827 interruptReason,
5828 srb));
5829
5830 // Fail this request.
5832 if(!wordCount && atapiDev && (srb->Cdb[0] != SCSIOP_REQUEST_SENSE)) {
5833 // some devices feel bad after incorrect commands and may need reset
5835 "AtapiInterrupt: Try ATAPI reset\n"));
5836
5837 AtapiDisableInterrupts(deviceExtension, lChannel);
5839 AtapiEnableInterrupts(deviceExtension, lChannel);
5842
5843// goto IntrPrepareResetController;
5844 }
5845 goto CompleteRequest;
5846 }
5847 // Advance data buffer pointer and bytes left.
5848 AtaReq->DataBuffer += wordCount;
5849 AtaReq->WordsLeft -= wordCount;
5850 AtaReq->WordsTransfered += wordCount;
5851
5852 if (atapiDev) {
5854 }
5855
5856 goto ReturnEnableIntr;
5857
5858 } else if (interruptReason == ATAPI_IR_IO_toHost && (statusByte & IDE_STATUS_DRQ)) {
5859
5860continue_read_drq:
5861
5862 if (atapiDev) {
5863
5864 // Pick up bytes to transfer and convert to words.
5865 wordCount =
5868
5869 // Convert bytes to words.
5870 KdPrint2((PRINT_PREFIX "AtapiInterrupt: get R byteCount %#x\n", wordCount));
5871 wordCount >>= 1;
5872 /*
5873 When ATAPI 64k PIO read is requested we may have 0xfffe byte
5874 count reported for 0x10000 bytes in single interrupt.
5875 It is not allowed to read entire 64k block with DwordIo intead of
5876 wait for last word.
5877 */
5878 if (wordCount != AtaReq->WordsLeft) {
5880 "AtapiInterrupt: %d words requested; %d words xferred\n",
5881 AtaReq->WordsLeft,
5882 wordCount));
5883 }
5884
5885 // Verify this makes sense.
5886 if (wordCount > AtaReq->WordsLeft) {
5887 wordCount = AtaReq->WordsLeft;
5888 DataOverrun = TRUE;
5889 }
5890
5891 } else {
5892
5893 // Check if words left is at least 256.
5894 if (AtaReq->WordsLeft < wordsThisInterrupt) {
5895 // Transfer only words requested.
5896 wordCount = AtaReq->WordsLeft;
5897 } else {
5898 // Transfer next block.
5899 wordCount = wordsThisInterrupt;
5900 }
5901 }
5902
5903 if(DmaTransfer &&
5907 "IdeIntr: DMA tmp INTR %#x vs %#x\n", AtaReq->WordsLeft, wordCount));
5908 if(AtaReq->WordsLeft > wordCount) {
5909 AtaReq->WordsLeft -= wordCount;
5910 AtaReq->WordsTransfered += wordCount;
5912 goto ReturnEnableIntr;
5913 }
5914 dma_status = AtapiDmaDone(HwDeviceExtension, DEVNUM_NOT_SPECIFIED, lChannel, NULL/*srb*/);
5915 }
5916 //ASSERT(AtaReq->WordsLeft == wordCount);
5917 AtaReq->WordsTransfered = AtaReq->WordsLeft;
5918 AtaReq->WordsLeft = 0;
5920 chan->ChannelCtrlFlags &= ~CTRFLAGS_DMA_OPERATION;
5921 goto CompleteRequest;
5922 }
5923 // Ensure that this is a read command.
5924 if (srb->SrbFlags & SRB_FLAGS_DATA_IN) {
5925
5926/* KdPrint2((
5927 "AtapiInterrupt: Read interrupt\n"));*/
5928
5929 statusByte = WaitOnBusy(chan);
5930
5931 if(wordCount&1 && atapiDev && (g_opt_VirtualMachine == VM_BOCHS)) {
5933 "IdeIntr: unaligned ATAPI %#x Words\n", wordCount));
5934 } else
5935 if(LunExt->DeviceFlags & DFLAGS_DWORDIO_ENABLED) {
5937 "IdeIntr: pre-Read %#x Dwords\n", wordCount/2));
5938
5939 ReadBuffer2(chan,
5940 (PULONG)(AtaReq->DataBuffer),
5941 wordCount / 2,
5942 UniataGetPioTiming(LunExt));
5943 // Advance data buffer pointer and bytes left.
5944 AtaReq->DataBuffer += wordCount & ~1;
5945 AtaReq->WordsLeft -= wordCount & ~1;
5946 AtaReq->WordsTransfered += wordCount & ~1;
5947 wordCount &= 1;
5948 }
5949 if (wordCount) {
5951 "IdeIntr: Read %#x words\n", wordCount));
5952
5953 ReadBuffer(chan,
5954 AtaReq->DataBuffer,
5955 wordCount,
5956 UniataGetPioTiming(LunExt));
5957 }
5958
5959 KdPrint2(("IdeIntr: PIO Read AtaReq->DataBuffer %#x, srb->DataBuffer %#x\n", AtaReq->DataBuffer, (srb ? srb->DataBuffer : (void*)-1) ));
5960 //KdDump(AtaReq->DataBuffer, wordCount*2);
5961 if(srb && atapiDev && srb->Cdb[0] == SCSIOP_REQUEST_SENSE) {
5962 KdDump(AtaReq->DataBuffer, wordCount*2);
5963 }
5964
5965 GetBaseStatus(chan, statusByte);
5966 KdPrint2((PRINT_PREFIX " status re-check %#x\n", statusByte));
5967
5968 if(DataOverrun) {
5969 KdPrint2((PRINT_PREFIX " DataOverrun\n"));
5970 AtapiSuckPort2(chan);
5971 GetBaseStatus(chan, statusByte);
5972 }
5973
5974 if(statusByte & IDE_STATUS_BUSY) {
5975 for (i = 0; i < 2; i++) {
5977 GetBaseStatus(chan, statusByte);
5978 if (!(statusByte & IDE_STATUS_BUSY)) {
5979 break;
5980 }
5981 }
5982 }
5983
5984 } else {
5985
5987 "AtapiInterrupt: Int reason %#x, but srb is for a read %#x.\n",
5988 interruptReason,
5989 srb));
5990
5991 // Fail this request.
5993 goto CompleteRequest;
5994 }
5995//continue_atapi_pio_read:
5996 // Advance data buffer pointer and bytes left.
5997 AtaReq->DataBuffer += wordCount;
5998 AtaReq->WordsLeft -= wordCount;
5999 AtaReq->WordsTransfered += wordCount;
6000
6001 // Check for read command complete.
6002 if (AtaReq->WordsLeft == 0) {
6003
6004 KdPrint2((PRINT_PREFIX "AtapiInterrupt: all transferred, AtaReq->WordsLeft == 0\n"));
6005 if (atapiDev) {
6006
6007 if(LunExt->IdentifyData.DeviceType == ATAPI_TYPE_CDROM) {
6008
6009 // Work around to make many atapi devices return correct sector size
6010 // of 2048. Also certain devices will have sector count == 0x00, check
6011 // for that also.
6012 if (srb->Cdb[0] == SCSIOP_READ_CAPACITY) {
6013
6014 AtaReq->DataBuffer -= AtaReq->WordsTransfered;
6015 if (AtaReq->DataBuffer[0] == 0x00) {
6016 *((ULONG *) &(AtaReq->DataBuffer[0])) = 0xFFFFFF7F;
6017 }
6018
6019 *((ULONG *) &(AtaReq->DataBuffer[2])) = 0x00080000;
6020 AtaReq->DataBuffer += AtaReq->WordsTransfered;
6021 }
6022#ifndef UNIATA_INIT_CHANGERS
6023 else
6024 if (srb->Cdb[0] == SCSIOP_MECHANISM_STATUS) {
6025
6026 KdPrint3((PRINT_PREFIX "AtapiInterrupt: SCSIOP_MECHANISM_STATUS status %#x\n", status));
6027 // Bingo!!
6028 AtapiHwInitializeChanger (HwDeviceExtension,
6029 srb,
6032 KdPrint2((PRINT_PREFIX " set DFLAGS_CHANGER_INITED\n"));
6033 }
6034#endif // UNIATA_INIT_CHANGERS
6035 }
6036 GetStatus(chan, statusByte);
6037 if(!(statusByte & IDE_STATUS_BUSY)) {
6038 // Assume command is completed if BUSY is cleared
6039 // and all data read
6040 // Optionally, we may receive COMPLETE interrupt later and
6041 // treat it as unexpected
6042 KdPrint2((PRINT_PREFIX "AtapiInterrupt: early complete ? status %x\n", statusByte));
6043
6045 goto CompleteRequest;
6046 }
6047
6048 } else {
6049
6050 /*
6051 // Completion for IDE drives.
6052 if (AtaReq->WordsLeft) {
6053 status = SRB_STATUS_DATA_OVERRUN;
6054 } else {
6055 status = SRB_STATUS_SUCCESS;
6056 }
6057
6058 goto CompleteRequest;
6059 */
6061 goto CompleteRequest;
6062
6063 }
6064 } else {
6065 if (atapiDev) {
6067 GetStatus(chan, statusByte);
6068 if(!(statusByte & IDE_STATUS_BUSY)) {
6069 // Assume command is completed if BUSY is cleared
6070 // even if NOT all data read
6071 // Optionally, we may receive COMPLETE interrupt later and
6072 // treat it as unexpected
6073 KdPrint2((PRINT_PREFIX "AtapiInterrupt: early complete + underrun ? status %x\n", statusByte));
6074
6076 goto CompleteRequest;
6077 }
6078 } else {
6079 if(!atapiDev && !DataOverrun && (srb->SrbFlags & SRB_FLAGS_DATA_IN) &&
6080 ((statusByte & ~IDE_STATUS_INDEX) == (IDE_STATUS_IDLE | IDE_STATUS_DRQ))) {
6081 KdPrint2((PRINT_PREFIX " HDD read data ready \n"));
6082 goto continue_read_drq;
6083 }
6084 }
6085 }
6086
6087 goto ReturnEnableIntr;
6088
6089 } else if (interruptReason == (ATAPI_IR_IO_toHost | ATAPI_IR_COD_Cmd) && !(statusByte & IDE_STATUS_DRQ)) {
6090
6091 KdPrint2((PRINT_PREFIX "AtapiInterrupt: interruptReason = CompleteRequest\n"));
6092 // Command complete. We exactly know this because of IReason.
6093
6094 if(DmaTransfer) {
6095 KdPrint2((PRINT_PREFIX "AtapiInterrupt: CompleteRequest, was DmaTransfer\n"));
6096 AtaReq->WordsTransfered += AtaReq->WordsLeft;
6097 AtaReq->WordsLeft = 0;
6098 } else {
6099 KdPrint2((PRINT_PREFIX "AtapiInterrupt: CompleteRequest, was PIO\n"));
6100
6101 wordCount = AtaReq->WordsLeft;
6102 // Advance data buffer pointer and bytes left.
6103 AtaReq->DataBuffer += wordCount;
6104 AtaReq->WordsLeft -= wordCount;
6105 AtaReq->WordsTransfered += wordCount;
6106
6107 KdPrint2((PRINT_PREFIX "AtapiInterrupt: wordCount %#x, WordsTransfered %#x\n", wordCount, AtaReq->WordsTransfered));
6108
6109 }
6110 //if (AtaReq->WordsLeft) {
6111 // status = SRB_STATUS_DATA_OVERRUN;
6112 //} else {
6114 //}
6115
6116#ifdef UNIATA_DUMP_ATAPI
6117 if(srb &&
6118 srb->SrbFlags & SRB_FLAGS_DATA_IN) {
6119 UCHAR ScsiCommand;
6120 PCDB Cdb;
6121 PCHAR CdbData;
6122 PCHAR ModeSelectData;
6123 ULONG CdbDataLen;
6125
6126 Cdb = (PCDB)(Srb->Cdb);
6127 ScsiCommand = Cdb->CDB6.OperationCode;
6128 CdbData = (PCHAR)(Srb->DataBuffer);
6129 CdbDataLen = Srb->DataTransferLength;
6130
6131 if(CdbDataLen > 0x1000) {
6132 CdbDataLen = 0x1000;
6133 }
6134
6135 KdPrint(("--\n"));
6136 KdPrint2(("DeviceID+VendorID/Rev %#x/%#x\n", deviceExtension->DevID, deviceExtension->RevID));
6137 KdPrint2(("P:T:D=%d:%d:%d\n",
6138 Srb->PathId,
6139 Srb->TargetId,
6140 Srb->Lun));
6141 KdPrint(("Complete SCSI Command %2.2x\n", ScsiCommand));
6142 KdDump(Cdb, 16);
6143
6144 if(ScsiCommand == SCSIOP_MODE_SENSE) {
6145 KdPrint(("ModeSense 6\n"));
6147 ModeSelectData = CdbData+4;
6148 KdDump(CdbData, CdbDataLen);
6149 } else
6150 if(ScsiCommand == SCSIOP_MODE_SENSE10) {
6151 KdPrint(("ModeSense 10\n"));
6153 ModeSelectData = CdbData+8;
6154 KdDump(CdbData, CdbDataLen);
6155 } else {
6156 if(srb->SrbFlags & SRB_FLAGS_DATA_IN) {
6157 KdPrint(("Read buffer from device:\n"));
6158 KdDump(CdbData, CdbDataLen);
6159 }
6160 }
6161 KdPrint(("--\n"));
6162 }
6163#endif //UNIATA_DUMP_ATAPI
6164
6166
6167 KdPrint2((PRINT_PREFIX "AtapiInterrupt: CompleteRequest, srbstatus %x\n", status));
6168 // Check and see if we are processing our secret (mechanism status/request sense) srb
6169
6170 if(AtaReq->WordsLeft && (status == SRB_STATUS_SUCCESS)) {
6171 KdPrint2((PRINT_PREFIX "WordsLeft %#x -> SRB_STATUS_DATA_OVERRUN\n", AtaReq->WordsLeft));
6173 }
6174
6175 if (AtaReq->OriginalSrb) {
6176
6177 ULONG srbStatus;
6178
6179 KdPrint2((PRINT_PREFIX "AtapiInterrupt: OriginalSrb != NULL\n"));
6180 if (srb->Cdb[0] == SCSIOP_MECHANISM_STATUS) {
6181#ifdef UNIATA_INIT_CHANGERS
6182 // We can get here only when UNIATA_INIT_CHANGERS is defined
6183 KdPrint3((PRINT_PREFIX "AtapiInterrupt: SCSIOP_MECHANISM_STATUS status %#x\n", status));
6184 if (status == SRB_STATUS_SUCCESS) {
6185 // Bingo!!
6186 AtapiHwInitializeChanger (HwDeviceExtension,
6187 srb,
6189
6190 // Get ready to issue the original srb
6191 srb = AtaReq->Srb = AtaReq->OriginalSrb;
6192 AtaReq->OriginalSrb = NULL;
6193
6194 } else {
6195 // failed! Get the sense key and maybe try again
6196 srb = AtaReq->Srb = BuildRequestSenseSrb (
6197 HwDeviceExtension,
6198 AtaReq->OriginalSrb);
6199 }
6200/*
6201 // do not enable interrupts in DPC, do not waste time, do it now!
6202 if(UseDpc && chan->DisableIntr) {
6203 AtapiEnableInterrupts(HwDeviceExtension, c);
6204 UseDpc = FALSE;
6205 RestoreUseDpc = TRUE;
6206 }
6207*/
6208 srbStatus = AtapiSendCommand(HwDeviceExtension, srb, CMD_ACTION_ALL);
6209
6210 KdPrint3((PRINT_PREFIX "AtapiInterrupt: chan->ExpectingInterrupt %d (1)\n", chan->ExpectingInterrupt));
6211
6212 if (srbStatus == SRB_STATUS_PENDING) {
6213 KdPrint2((PRINT_PREFIX "AtapiInterrupt: send orig SRB_STATUS_PENDING (1)\n"));
6214 goto ReturnEnableIntr;
6215 }
6216/*
6217 if(RestoreUseDpc) {
6218 // restore state on error
6219 UseDpc = TRUE;
6220 AtapiDisableInterrupts(HwDeviceExtension, c);
6221 }
6222*/
6223#else
6224 KdPrint((PRINT_PREFIX "AtapiInterrupt: ERROR: internal SCSIOP_MECHANISM_STATUS !!!!\n"));
6225 ASSERT(FALSE);
6226#endif // UNIATA_INIT_CHANGERS
6227 } else { // srb->Cdb[0] == SCSIOP_REQUEST_SENSE)
6228
6229 PSENSE_DATA senseData = (PSENSE_DATA) srb->DataBuffer;
6230#ifdef __REACTOS__
6231 (void)senseData;
6232#endif
6233
6234 KdPrint3((PRINT_PREFIX "AtapiInterrupt: ATAPI command status %#x\n", status));
6236 // Check to see if we at least get mininum number of bytes
6237 if ((srb->DataTransferLength - AtaReq->WordsLeft) >
6238 (FIELD_OFFSET (SENSE_DATA, AdditionalSenseLength) + sizeof(senseData->AdditionalSenseLength))) {
6240 }
6241 }
6242
6243 if (status == SRB_STATUS_SUCCESS) {
6244#ifndef UNIATA_CORE
6245#ifdef UNIATA_INIT_CHANGERS
6246 if ((senseData->SenseKey != SCSI_SENSE_ILLEGAL_REQUEST) &&
6247 FALSE &&
6248 chan->MechStatusRetryCount) {
6249
6250 KdPrint3((PRINT_PREFIX "AtapiInterrupt: MechStatusRetryCount %#x\n", chan->MechStatusRetryCount));
6251 // The sense key doesn't say the last request is illegal, so try again
6252 chan->MechStatusRetryCount--;
6253 srb = AtaReq->Srb = BuildMechanismStatusSrb (
6254 HwDeviceExtension,
6255 AtaReq->OriginalSrb);
6256 } else
6257#endif // UNIATA_INIT_CHANGERS
6258 {
6259 // Get ready to issue the original srb
6260 srb = AtaReq->Srb = AtaReq->OriginalSrb;
6261 AtaReq->OriginalSrb = NULL;
6262 }
6263#endif //UNIATA_CORE
6264/*
6265 // do not enable interrupts in DPC, do not waste time, do it now!
6266 if(UseDpc && chan->DisableIntr) {
6267 AtapiEnableInterrupts(HwDeviceExtension, c);
6268 UseDpc = FALSE;
6269 RestoreUseDpc = TRUE;
6270 }
6271*/
6272 srbStatus = AtapiSendCommand(HwDeviceExtension, srb, CMD_ACTION_ALL);
6273
6274 KdPrint3((PRINT_PREFIX "AtapiInterrupt: chan->ExpectingInterrupt %d (2)\n", chan->ExpectingInterrupt));
6275
6276 if (srbStatus == SRB_STATUS_PENDING) {
6277 KdPrint2((PRINT_PREFIX "AtapiInterrupt: send orig SRB_STATUS_PENDING (2)\n"));
6278 goto ReturnEnableIntr;
6279 }
6280/*
6281 if(RestoreUseDpc) {
6282 // restore state on error
6283 UseDpc = TRUE;
6284 AtapiDisableInterrupts(HwDeviceExtension, c);
6285 }
6286*/
6287 }
6288 }
6289
6290 // If we get here, it means AtapiSendCommand() has failed
6291 // Can't recover. Pretend the original srb has failed and complete it.
6292
6293 KdPrint3((PRINT_PREFIX "AtapiInterrupt: Error. complete OriginalSrb\n"));
6294
6295 if (AtaReq->OriginalSrb) {
6296 srb = AtaReq->Srb = AtaReq->OriginalSrb;
6297 AtaReq->OriginalSrb = NULL;
6298 }
6299
6300 KdPrint2((PRINT_PREFIX "AtapiInterrupt: chan->ExpectingInterrupt %d (3)\n", chan->ExpectingInterrupt));
6301
6302 // fake an error and read no data
6304 srb->ScsiStatus = 0;
6305 AtaReq->DataBuffer = (PUSHORT)(srb->DataBuffer);
6306 AtaReq->WordsLeft = srb->DataTransferLength;
6307 chan->RDP = FALSE;
6308
6309 } else if (status == SRB_STATUS_ERROR) {
6310
6311 // Map error to specific SRB status and handle request sense.
6312 KdPrint3((PRINT_PREFIX "AtapiInterrupt: Error. Begin mapping...\n"));
6313 status = MapError(deviceExtension,
6314 srb);
6315
6316 chan->RDP = FALSE;
6317
6318 } else if(!DmaTransfer) {
6319
6320 KdPrint2((PRINT_PREFIX "AtapiInterrupt: PIO completion\n"));
6321 // Command complete.
6322PIO_wait_busy:
6323 KdPrint2((PRINT_PREFIX "AtapiInterrupt: PIO completion, wait BUSY\n"));
6324 // Wait for busy to drop.
6325 for (i = 0; i < 5*30; i++) {
6326 GetBaseStatus(chan, statusByte);
6327 if (!(statusByte & IDE_STATUS_BUSY)) {
6328 break;
6329 }
6330 if(!InDpc) {
6331 // goto DPC
6333 TimerValue = 200;
6334 KdPrint2((PRINT_PREFIX "AtapiInterrupt: go to DPC (busy)\n"));
6335#ifndef UNIATA_CORE
6336 goto PostToDpc;
6337#else //UNIATA_CORE
6338 AtapiStallExecution(TimerValue);
6339 goto ServiceInterrupt;
6340#endif //UNIATA_CORE
6341 }
6343 }
6344
6345 if (i == 5*30) {
6346
6347 // reset the controller.
6349 "AtapiInterrupt: Resetting due to BSY still up - %#x.\n",
6350 statusByte));
6351 goto IntrPrepareResetController;
6352 }
6353 // Check to see if DRQ is still up.
6354 if(statusByte & IDE_STATUS_DRQ) {
6355 KdPrint2((PRINT_PREFIX "AtapiInterrupt: DRQ...\n"));
6356 if(srb) {
6357 if(srb->SrbFlags & SRB_FLAGS_DATA_IN) {
6358 KdPrint2((PRINT_PREFIX "srb %x data in\n", srb));
6359 } else {
6360 KdPrint2((PRINT_PREFIX "srb %x data out\n", srb));
6361 }
6362 } else {
6363 KdPrint2((PRINT_PREFIX "srb NULL\n"));
6364 }
6365 if(AtaReq) {
6366 KdPrint2((PRINT_PREFIX "AtaReq %x AtaReq->WordsLeft=%x\n", AtaReq, AtaReq->WordsLeft));
6367 } else {
6368 KdPrint2((PRINT_PREFIX "AtaReq NULL\n"));
6369 }
6370 if(AtaReq && AtaReq->WordsLeft /*&&
6371 !(LunExt->DeviceFlags & (DFLAGS_ATAPI_DEVICE | DFLAGS_TAPE_DEVICE | DFLAGS_LBA_ENABLED))*/) {
6372 KdPrint2((PRINT_PREFIX "DRQ+AtaReq->WordsLeft -> next portion\n"));
6373 goto continue_PIO;
6374 }
6375 }
6376 //if (atapiDev && (statusByte & IDE_STATUS_DRQ)) {}
6377 //if ((statusByte & IDE_STATUS_DRQ)) {}
6378 if((statusByte & IDE_STATUS_DRQ) &&
6380
6381PIO_wait_DRQ:
6382 KdPrint2((PRINT_PREFIX "AtapiInterrupt: PIO_wait_DRQ\n"));
6383 for (i = 0; i < 200; i++) {
6384 GetBaseStatus(chan, statusByte);
6385 if (!(statusByte & IDE_STATUS_DRQ)) {
6386 break;
6387 }
6388 if(!InDpc) {
6389 // goto DPC
6390 KdPrint2((PRINT_PREFIX "AtapiInterrupt: go to DPC (drq)\n"));
6392 TimerValue = 100;
6393#ifndef UNIATA_CORE
6394 goto PostToDpc;
6395#else //UNIATA_CORE
6396 AtapiStallExecution(TimerValue);
6397 goto ServiceInterrupt;
6398#endif //UNIATA_CORE
6399 }
6401 }
6402
6403 if (i == 200) {
6404 // reset the controller.
6405 KdPrint2((PRINT_PREFIX "AtapiInterrupt: Resetting due to DRQ still up - %#x\n",
6406 statusByte));
6407 goto IntrPrepareResetController;
6408 }
6409 }
6410 if(atapiDev) {
6411 KdPrint2(("IdeIntr: ATAPI Read AtaReq->DataBuffer %#x, srb->DataBuffer %#x, len %#x\n",
6412 AtaReq->DataBuffer, (srb ? srb->DataBuffer : (void*)(-1)), srb->DataTransferLength ));
6413 //KdDump(srb->DataBuffer, srb->DataTransferLength);
6414 }
6415 if(!AtapiDmaPioSync(HwDeviceExtension, srb, (PUCHAR)(srb->DataBuffer), srb->DataTransferLength)) {
6416 KdPrint2(("IdeIntr: Can't sync DMA and PIO buffers\n"));
6417 }
6418 }
6419
6420 // Clear interrupt expecting flag.
6422 // clear this flag now, it can be set again in sub-calls
6425
6426 // Sanity check that there is a current request.
6427 if(srb != NULL) {
6428 // Set status in SRB.
6429 srb->SrbStatus = (UCHAR)status;
6430
6431 // Check for underflow.
6432 if(AtaReq->WordsLeft) {
6433
6434 KdPrint2((PRINT_PREFIX "AtapiInterrupt: Check for underflow, AtaReq->WordsLeft %x\n", AtaReq->WordsLeft));
6435 // Subtract out residual words and update if filemark hit,
6436 // setmark hit , end of data, end of media...
6437 if (!(LunExt->DeviceFlags & DFLAGS_TAPE_DEVICE)) {
6439 srb->DataTransferLength -= AtaReq->WordsLeft*2;
6440 } else {
6441 srb->DataTransferLength = 0;
6442 }
6443 } else {
6444 srb->DataTransferLength -= AtaReq->WordsLeft*2;
6445 }
6446 }
6447 if(status == SRB_STATUS_SUCCESS) {
6448 //if(!(deviceExtension->HwFlags & UNIATA_AHCI) && !atapiDev) {
6449 // // This should be set in UniataAhciEndTransaction() for AHCI
6450 // AtaReq->WordsTransfered += AtaReq->bcount * DEV_BSIZE/2;
6451 //}
6452 if(!atapiDev &&
6453 AtaReq->WordsTransfered*2 < AtaReq->TransferLength) {
6454 KdPrint2((PRINT_PREFIX "AtapiInterrupt: more I/O required (%x of %x bytes) -> reenqueue\n",
6455 AtaReq->WordsTransfered*2, AtaReq->TransferLength));
6456 AtaReq->Flags &= ~REQ_FLAG_DMA_OPERATION;
6458 goto reenqueue_req;
6459 } else {
6460 KdPrint2((PRINT_PREFIX " Transfered %x, full size %x\n",
6461 AtaReq->WordsTransfered*2, AtaReq->TransferLength));
6462 }
6463 }
6464
6465 if (srb->Function != SRB_FUNCTION_IO_CONTROL) {
6466
6467CompleteRDP:
6468 // Indicate command complete.
6469 if (!(chan->RDP)) {
6470 KdPrint2((PRINT_PREFIX "AtapiInterrupt: RequestComplete\n"));
6471IntrCompleteReq:
6472
6473 if (status == SRB_STATUS_SUCCESS &&
6474 srb->SenseInfoBuffer &&
6475 srb->SenseInfoBufferLength >= sizeof(SENSE_DATA)) {
6476
6477 PSENSE_DATA senseBuffer = (PSENSE_DATA)srb->SenseInfoBuffer;
6478
6479 KdPrint2((PRINT_PREFIX "AtapiInterrupt: set AutoSense\n"));
6480 senseBuffer->ErrorCode = 0;
6481 senseBuffer->Valid = 1;
6482 senseBuffer->AdditionalSenseLength = 0xb;
6483 senseBuffer->SenseKey = 0;
6484 senseBuffer->AdditionalSenseCode = 0;
6485 senseBuffer->AdditionalSenseCodeQualifier = 0;
6486
6488 }
6489 AtapiDmaDBSync(chan, srb);
6490 KdPrint2((PRINT_PREFIX "AtapiInterrupt: remove srb %#x, status %x\n", srb, status));
6491 UniataRemoveRequest(chan, srb);
6492 KdPrint2((PRINT_PREFIX "AtapiInterrupt: RequestComplete, srb %#x\n", srb));
6494 deviceExtension,
6495 srb);
6496 }
6497 } else {
6498
6499 KdPrint2((PRINT_PREFIX "AtapiInterrupt: IOCTL completion\n"));
6500
6501 if (status != SRB_STATUS_SUCCESS) {
6503 KdPrint2((PRINT_PREFIX "AtapiInterrupt: error %#x\n", error));
6504 }
6505
6506 if(!AtapiStringCmp( (PCHAR)(((PSRB_IO_CONTROL)(srb->DataBuffer))->Signature),"SCSIDISK",sizeof("SCSIDISK")-1)) {
6507
6508 PSENDCMDOUTPARAMS cmdOutParameters = (PSENDCMDOUTPARAMS)(((PUCHAR)srb->DataBuffer) + sizeof(SRB_IO_CONTROL));
6509 // Build the SMART status block depending upon the completion status.
6510 cmdOutParameters->cBufferSize = wordCount;
6511 cmdOutParameters->DriverStatus.bDriverError = (error) ? SMART_IDE_ERROR : 0;
6512 cmdOutParameters->DriverStatus.bIDEError = error;
6513
6514 // If the sub-command is return smart status, jam the value from cylinder low and high, into the
6515 // data buffer.
6516 if (chan->SmartCommand == RETURN_SMART_STATUS) {
6517 PIDEREGS_EX regs = (PIDEREGS_EX)&(cmdOutParameters->bBuffer);
6518
6519 regs->bOpFlags = 0;
6520 UniataSnapAtaRegs(chan, 0, regs);
6521
6522 regs->bCommandReg = SMART_CMD;
6523 regs->bFeaturesReg = RETURN_SMART_STATUS;
6524
6525 cmdOutParameters->cBufferSize = 8;
6526 }
6527 chan->SmartCommand = 0; // cleanup after execution
6528 }
6529 // Indicate command complete.
6530 goto IntrCompleteReq;
6531 }
6532
6533 } else {
6534
6535 KdPrint2((PRINT_PREFIX "AtapiInterrupt: No SRB!\n"));
6536 }
6537
6538 if (chan->RDP) {
6539 // Check DSC
6540 for (i = 0; i < 5; i++) {
6541 GetBaseStatus(chan, statusByte);
6542 if(!(statusByte & IDE_STATUS_BUSY)) {
6543 KdPrint2((PRINT_PREFIX "AtapiInterrupt: RDP + cleared BUSY\n"));
6544 chan->RDP = FALSE;
6545 goto CompleteRDP;
6546 } else
6547 if (statusByte & IDE_STATUS_DSC) {
6548 KdPrint2((PRINT_PREFIX "AtapiInterrupt: Clear RDP\n"));
6549 chan->RDP = FALSE;
6550 goto CompleteRDP;
6551 }
6553 }
6554 }
6555 // RDP can be cleared since previous check
6556 if (chan->RDP) {
6557 KdPrint2((PRINT_PREFIX "AtapiInterrupt: RequestTimerCall 2000\n"));
6558
6559 TimerValue = 2000;
6560#ifndef UNIATA_CORE
6561 goto CallTimerDpc;
6562#else //UNIATA_CORE
6563 AtapiStallExecution(TimerValue);
6564 goto ServiceInterrupt;
6565#endif //UNIATA_CORE
6566 }
6567
6568// ASSERT(KeGetCurrentIrql() == DISPATCH_LEVEL);
6569enqueue_next_req:
6570 // Get next request
6571 srb = UniataGetCurRequest(chan);
6572
6573reenqueue_req:
6574
6575#ifndef UNIATA_CORE
6576 KdPrint2((PRINT_PREFIX "AtapiInterrupt: NextRequest, srb=%#x\n",srb));
6577 if(!srb) {
6579 deviceExtension,
6580 NULL);
6581 } else {
6583 deviceExtension,
6584 PathId,
6585 TargetId,
6586 Lun);
6587 // in simplex mode next command must NOT be sent here
6588 if(!deviceExtension->simplexOnly) {
6589 AtapiStartIo__(HwDeviceExtension, srb, FALSE);
6590 }
6591 }
6592 // Try to get SRB fron any non-empty queue (later)
6593 if(deviceExtension->simplexOnly) {
6594 NoStartIo = FALSE;
6595 }
6596#endif //UNIATA_CORE
6597
6598 goto ReturnEnableIntr;
6599
6600 } else {
6601
6602 // Unexpected int. Catch it
6603 KdPrint2((PRINT_PREFIX "AtapiInterrupt: Unexpected ATAPI interrupt. InterruptReason %#x. Status %#x.\n",
6604 interruptReason,
6605 statusByte));
6606
6608 if(interruptReason == ATAPI_IR_IO_toDev && !(statusByte & IDE_STATUS_DRQ) && !DmaTransfer) {
6609 statusByte = WaitForDrq(chan);
6610 if(statusByte & IDE_STATUS_DRQ) {
6611 goto continue_PIO;
6612 }
6613 }
6614 }
6615
6616 if(OldReqState == REQ_STATE_DPC_WAIT_BUSY0 &&
6617 AtaReq->WordsLeft == 0) {
6618 KdPrint2((PRINT_PREFIX "AtapiInterrupt: pending WAIT_BUSY0. Complete.\n"));
6620 chan->ChannelCtrlFlags &= ~CTRFLAGS_DMA_OPERATION;
6621 goto CompleteRequest;
6622 }
6623 }
6624
6625ReturnEnableIntr:
6626
6627 KdPrint2((PRINT_PREFIX "AtapiInterrupt: ReturnEnableIntr\n",srb));
6628 //UniataExpectChannelInterrupt(chan, TRUE); // device may interrupt
6629 deviceExtension->ExpectingInterrupt = TRUE;
6630 if(UseDpc) {
6631 if(CrNtInterlockedExchangeAdd(&(chan->DisableIntr), 0)) {
6632 KdPrint2((PRINT_PREFIX "AtapiInterrupt: call AtapiEnableInterrupts__()\n"));
6633#ifdef UNIATA_USE_XXableInterrupts
6634 //ASSERT(KeGetCurrentIrql() <= DISPATCH_LEVEL);
6636 // must be called on DISPATCH_LEVEL
6639#else
6640 AtapiEnableInterrupts(HwDeviceExtension, c);
6643 // Will raise IRQL to DIRQL
6644#ifndef UNIATA_CORE
6645 AtapiQueueTimerDpc(HwDeviceExtension, lChannel,
6647 1);
6648#endif // UNIATA_CORE
6649 KdPrint2((PRINT_PREFIX "AtapiInterrupt: Timer DPC inited\n"));
6650#endif // UNIATA_USE_XXableInterrupts
6651 }
6652 }
6653
6655 // in simplex mode next command must be sent here if
6656 // DPC is not used
6657 KdPrint2((PRINT_PREFIX "AtapiInterrupt: exiting, UseDpc=%d, NoStartIo=%d\n", UseDpc, NoStartIo));
6658
6659#ifndef UNIATA_CORE
6660 if(!UseDpc && /*deviceExtension->simplexOnly &&*/ !NoStartIo) {
6661 chan = UniataGetNextChannel(chan);
6662 if(chan) {
6663 srb = UniataGetCurRequest(chan);
6664 } else {
6665 srb = NULL;
6666 }
6667 KdPrint2((PRINT_PREFIX "AtapiInterrupt: run srb %x\n", srb));
6668 if(srb) {
6669 AtapiStartIo__(HwDeviceExtension, srb, FALSE);
6670 }
6671 }
6672#endif //UNIATA_CORE
6673 return TRUE;
6674
6675} // end AtapiInterrupt__()
6676
6677#ifndef UNIATA_CORE
6678
6679/*++
6680
6681Routine Description:
6682
6683 This routine handles SMART enable, disable, read attributes and threshold commands.
6684
6685Arguments:
6686
6687 HwDeviceExtension - HBA miniport driver's adapter data storage
6688 Srb - IO request packet
6689
6690Return Value:
6691
6692 SRB status
6693
6694--*/
6695ULONG
6696NTAPI
6698 IN PVOID HwDeviceExtension,
6700 IN ULONG targetId // assume it is always valid
6701 )
6702{
6703 PHW_DEVICE_EXTENSION deviceExtension = (PHW_DEVICE_EXTENSION)HwDeviceExtension;
6704 ULONG c ; // = GET_CHANNEL(Srb); may be invalid
6705 PHW_CHANNEL chan ; // = &(deviceExtension->chan[c]);
6706 PATA_REQ AtaReq = (PATA_REQ)(Srb->SrbExtension);
6707 PSENDCMDOUTPARAMS cmdOutParameters = (PSENDCMDOUTPARAMS)(((PUCHAR)Srb->DataBuffer) + sizeof(SRB_IO_CONTROL));
6708 SENDCMDINPARAMS cmdInParameters = *(PSENDCMDINPARAMS)(((PUCHAR)Srb->DataBuffer) + sizeof(SRB_IO_CONTROL));
6709 PIDEREGS regs = &cmdInParameters.irDriveRegs;
6710// ULONG i;
6711 UCHAR statusByte;
6713
6714 if (regs->bCommandReg != SMART_CMD) {
6716 "IdeSendSmartCommand: bCommandReg != SMART_CMD\n"));
6718 }
6719
6720 c = targetId / deviceExtension->NumberLuns;
6721 DeviceNumber = targetId % deviceExtension->NumberLuns;
6722 KdPrint2((PRINT_PREFIX " c %d, dev %d\n", c, DeviceNumber));
6723
6724 chan = &(deviceExtension->chan[c]);
6725
6726 chan->SmartCommand = regs->bFeaturesReg;
6727
6728 // Determine which of the commands to carry out.
6729 switch(regs->bFeaturesReg) {
6730 case READ_ATTRIBUTES:
6731 case READ_THRESHOLDS:
6732 case READ_LOG_SECTOR:
6733 case WRITE_LOG_SECTOR:
6734
6737 "IdeSendSmartCommand: wrong buffer size\n"));
6739 }
6740
6741 statusByte = WaitOnBusy(chan);
6742
6743 if (statusByte & IDE_STATUS_BUSY) {
6745 "IdeSendSmartCommand: Returning BUSY status\n"));
6746 return SRB_STATUS_BUSY;
6747 }
6748
6749 // Zero the ouput buffer as the input buffer info. has been saved off locally (the buffers are the same).
6750 RtlZeroMemory(cmdOutParameters, sizeof(SENDCMDOUTPARAMS) + READ_ATTRIBUTE_BUFFER_SIZE - 1);
6751
6752 // Set data buffer pointer and words left.
6753 AtaReq->DataBuffer = (PUSHORT)cmdOutParameters->bBuffer;
6755
6756 statusByte = AtaCommand(deviceExtension, DeviceNumber, c,
6757 regs->bCommandReg,
6758 (USHORT)(regs->bCylLowReg) | (((USHORT)(regs->bCylHighReg)) << 8),
6759 0,
6760 regs->bSectorNumberReg,
6761 regs->bSectorCountReg,
6762 regs->bFeaturesReg,
6764
6765 if(!(statusByte & IDE_STATUS_ERROR)) {
6766 // Wait for interrupt.
6767 return SRB_STATUS_PENDING;
6768 }
6769 return SRB_STATUS_ERROR;
6770
6771 case ENABLE_SMART:
6772 case DISABLE_SMART:
6777 case AUTO_OFFLINE:
6778
6779 statusByte = WaitOnBusy(chan);
6780
6781 if (statusByte & IDE_STATUS_BUSY) {
6783 "IdeSendSmartCommand: Returning BUSY status\n"));
6784 return SRB_STATUS_BUSY;
6785 }
6786
6787 // Zero the ouput buffer as the input buffer info. has been saved off locally (the buffers are the same).
6788 RtlZeroMemory(cmdOutParameters, sizeof(SENDCMDOUTPARAMS) - 1);
6789
6790 // Set data buffer pointer and indicate no data transfer.
6791 AtaReq->DataBuffer = (PUSHORT)cmdOutParameters->bBuffer;
6792 AtaReq->WordsLeft = 0;
6793
6794 statusByte = AtaCommand(deviceExtension, DeviceNumber, c,
6795 regs->bCommandReg,
6796 (USHORT)(regs->bCylLowReg) | (((USHORT)(regs->bCylHighReg)) << 8),
6797 0,
6798 regs->bSectorNumberReg,
6799 regs->bSectorCountReg,
6800 regs->bFeaturesReg,
6802
6803 if(!(statusByte & IDE_STATUS_ERROR)) {
6804 // Wait for interrupt.
6805 UniataExpectChannelInterrupt(chan, TRUE); // device may interrupt
6806 return SRB_STATUS_PENDING;
6807 }
6808 return SRB_STATUS_ERROR;
6809 } // end switch(regs->bFeaturesReg)
6810
6812
6813} // end IdeSendSmartCommand()
6814
6815#endif //UNIATA_CORE
6816
6818NTAPI
6820 PHW_LU_EXTENSION LunExt,
6821 ULONGLONG startingSector,
6822 PULONG max_bcount
6823 )
6824{
6825 UCHAR drvSelect,sectorNumber;
6827 ULONG tmp;
6828
6829 if(LunExt->DeviceFlags & DFLAGS_LBA_ENABLED) {
6830 (*max_bcount) = 0;
6831 if(LunExt->LimitedTransferMode >= ATA_DMA) {
6832 if(LunExt->DeviceExtension) {
6833 (*max_bcount) = LunExt->DeviceExtension->MaximumDmaTransferLength / DEV_BSIZE;
6834 }
6835 }
6836 return startingSector;
6837 }
6838 tmp = LunExt->IdentifyData.SectorsPerTrack *
6840 if(!tmp) {
6841 KdPrint2((PRINT_PREFIX "UniAtaCalculateLBARegs: 0-sized\n"));
6842 cylinder = 0;
6843 drvSelect = 0;
6844 sectorNumber = 1;
6845 (*max_bcount) = LunExt->IdentifyData.SectorsPerTrack;
6846 } else {
6847 cylinder = (USHORT)(startingSector / tmp);
6848 drvSelect = (UCHAR)((startingSector % tmp) / LunExt->IdentifyData.SectorsPerTrack);
6849 sectorNumber = (UCHAR)(startingSector % LunExt->IdentifyData.SectorsPerTrack) + 1;
6850 (*max_bcount) = LunExt->IdentifyData.SectorsPerTrack - sectorNumber + 1;
6851 KdPrint2((PRINT_PREFIX "UniAtaCalculateLBARegs: C:H:S=%#x:%#x:%#x, max_bc %#x\n",
6852 cylinder, drvSelect, sectorNumber, (*max_bcount)));
6853 }
6854
6855 return (ULONG)(sectorNumber&0xff) | (((ULONG)cylinder&0xffff)<<8) | (((ULONG)drvSelect&0xf)<<24);
6856} // end UniAtaCalculateLBARegs()
6857
6859NTAPI
6861 PHW_LU_EXTENSION LunExt,
6863 )
6864{
6865 ULONG drvSelect,sectorNumber;
6867 ULONG tmp;
6868
6869 if(LunExt->DeviceFlags & DFLAGS_LBA_ENABLED) {
6870 return lba;
6871 }
6872 tmp = LunExt->IdentifyData.SectorsPerTrack *
6874
6875 cylinder = (USHORT)((lba >> 8) & 0xffff);
6876 drvSelect = (UCHAR)((lba >> 24) & 0xf);
6877 sectorNumber = (UCHAR)(lba & 0xff);
6878
6879 lba = sectorNumber-1 +
6880 (drvSelect*LunExt->IdentifyData.SectorsPerTrack) +
6881 (cylinder*tmp);
6882
6883 return lba;
6884} // end UniAtaCalculateLBARegsBack()
6885
6886
6887/*++
6888
6889Routine Description:
6890
6891 This routine handles IDE read and writes.
6892
6893Arguments:
6894
6895 HwDeviceExtension - HBA miniport driver's adapter data storage
6896 Srb - IO request packet
6897
6898Return Value:
6899
6900 SRB status
6901
6902--*/
6903ULONG
6904NTAPI
6906 IN PVOID HwDeviceExtension,
6908 IN ULONG CmdAction
6909 )
6910{
6911 PHW_DEVICE_EXTENSION deviceExtension = (PHW_DEVICE_EXTENSION)HwDeviceExtension;
6912 UCHAR lChannel = GET_CHANNEL(Srb);
6913 PHW_CHANNEL chan = &(deviceExtension->chan[lChannel]);
6914 PHW_LU_EXTENSION LunExt;
6915 PATA_REQ AtaReq = (PATA_REQ)(Srb->SrbExtension);
6916 //ULONG ldev = GET_LDEV(Srb);
6918 ULONGLONG startingSector=0;
6919 ULONG max_bcount = 0;
6920 ULONG wordCount = 0;
6921 UCHAR statusByte,statusByte2;
6922 UCHAR cmd;
6923 ULONGLONG lba;
6924 BOOLEAN use_dma = FALSE;
6925 ULONG fis_size;
6926
6928 LunExt = chan->lun[DeviceNumber];
6929
6930 if((CmdAction & CMD_ACTION_PREPARE) &&
6932
6933 if(LunExt->opt_ReadOnly &&
6935 if(LunExt->opt_ReadOnly == 1) {
6936 KdPrint2((PRINT_PREFIX "Abort WRITE (Soft R/O)\n"));
6937 return SRB_STATUS_ERROR;
6938 } else {
6939 KdPrint2((PRINT_PREFIX "Ignore WRITE (Soft R/O)\n"));
6940 return SRB_STATUS_SUCCESS;
6941 }
6942 }
6943
6944 // Set data buffer pointer and words left.
6945 AtaReq->Flags &= ~REQ_FLAG_DMA_OPERATION;
6946
6947 if(AtaReq->WordsTransfered) {
6948 AtaReq->DataBuffer = ((PUSHORT)(Srb->DataBuffer)) + AtaReq->WordsTransfered;
6949 startingSector = (UniAtaCalculateLBARegsBack(LunExt, AtaReq->lba)) /* latest lba */ + AtaReq->bcount /* previous bcount */;
6950 AtaReq->bcount = (AtaReq->TransferLength - AtaReq->WordsTransfered*2 + DEV_BSIZE-1) / DEV_BSIZE;
6951 KdPrint2((PRINT_PREFIX "IdeReadWrite (Chained REQ): Starting sector %I64x, OrigWordsRequested %#x, WordsTransfered %#x, DevSize %#x\n",
6952 startingSector,
6953 AtaReq->TransferLength/2,
6954 AtaReq->WordsTransfered,
6955 AtaReq->bcount));
6956 } else {
6957 AtaReq->DataBuffer = (PUSHORT)(Srb->DataBuffer);
6959 // Set up 1st block.
6960 switch(Srb->Cdb[0]) {
6961 case SCSIOP_WRITE:
6962 if(LunExt->DeviceFlags & DFLAGS_LBA32plus) {
6963 KdPrint2((PRINT_PREFIX "Attention: SCSIOP_WRITE on 2TB\n"));
6964 //return SRB_STATUS_ERROR;
6965 }
6966 // FALLTHROUGH
6967 case SCSIOP_READ:
6968 MOV_DD_SWP(startingSector, ((PCDB)Srb->Cdb)->CDB10.LBA);
6969 MOV_SWP_DW2DD(AtaReq->bcount, ((PCDB)Srb->Cdb)->CDB10.TransferBlocks);
6970 break;
6971 case SCSIOP_WRITE12:
6972 if(LunExt->DeviceFlags & DFLAGS_LBA32plus) {
6973 KdPrint2((PRINT_PREFIX "Attention: SCSIOP_WRITE12 on 2TB\n"));
6974 //return SRB_STATUS_ERROR;
6975 }
6976 // FALLTHROUGH
6977 case SCSIOP_READ12:
6978 MOV_DD_SWP(startingSector, ((PCDB)Srb->Cdb)->CDB12READWRITE.LBA);
6979 MOV_DD_SWP(AtaReq->bcount, ((PCDB)Srb->Cdb)->CDB12READWRITE.NumOfBlocks);
6980 break;
6981 case SCSIOP_READ16:
6982 case SCSIOP_WRITE16:
6983 MOV_QD_SWP(startingSector, ((PCDB)Srb->Cdb)->CDB16READWRITE.LBA);
6984 MOV_DD_SWP(AtaReq->bcount, ((PCDB)Srb->Cdb)->CDB16READWRITE.NumOfBlocks);
6985 break;
6986 }
6987 KdPrint2((PRINT_PREFIX "IdeReadWrite (Orig REQ): Starting sector %I64x, OrigWordsRequested %#x, DevSize %#x\n",
6988 startingSector,
6989 AtaReq->TransferLength/2,
6990 AtaReq->bcount));
6991 }
6992 lba = UniAtaCalculateLBARegs(LunExt, startingSector, &max_bcount);
6993
6994 if(max_bcount) {
6995 AtaReq->bcount = min(AtaReq->bcount, max_bcount);
6996 }
6997 AtaReq->WordsLeft = min(AtaReq->TransferLength - AtaReq->WordsTransfered*2,
6998 AtaReq->bcount * DEV_BSIZE) / 2;
6999
7000 KdPrint2((PRINT_PREFIX "IdeReadWrite (REQ): Starting sector is %I64x, Number of WORDS %#x, DevSize %#x\n",
7001 startingSector,
7002 AtaReq->WordsLeft,
7003 AtaReq->bcount));
7004
7005 AtaReq->lba = lba;
7006 if(LunExt->errRetry &&
7007 lba == LunExt->errLastLba &&
7008 /* AtaReq->bcount && */ // errRetry can be set only for non-zero bcount
7009 AtaReq->bcount == LunExt->errBCount) {
7010 KdPrint3((PRINT_PREFIX "IdeReadWrite: Retry after BUS_RESET %d @%#I64x (%#x)\n",
7011 LunExt->errRetry, LunExt->errLastLba, LunExt->errBCount));
7012 if(AtaReq->retry < MAX_RETRIES) {
7013 AtaReq->retry = LunExt->errRetry;
7014 AtaReq->Flags |= REQ_FLAG_FORCE_DOWNRATE;
7015 }
7016 LunExt->errRetry = 0;
7017 }
7018
7019 // assume best case here
7020 // we cannot reinit Dma until previous request is completed
7021 if(deviceExtension->HwFlags & UNIATA_AHCI) {
7022 UniataAhciSetupCmdPtr(AtaReq);
7023 if(!AtapiDmaSetup(HwDeviceExtension, DeviceNumber, lChannel, Srb,
7024 (PUCHAR)(AtaReq->DataBuffer),
7025 AtaReq->bcount * DEV_BSIZE)) {
7026 KdPrint3((PRINT_PREFIX "IdeReadWrite: AHCI !DMA\n"));
7027 return SRB_STATUS_ERROR;
7028 }
7029 } else
7030 if ((LunExt->LimitedTransferMode >= ATA_DMA)) {
7031 use_dma = TRUE;
7032 // this will set REQ_FLAG_DMA_OPERATION in AtaReq->Flags on success
7033 if(!AtapiDmaSetup(HwDeviceExtension, DeviceNumber, lChannel, Srb,
7034 (PUCHAR)(AtaReq->DataBuffer),
7035 AtaReq->bcount * DEV_BSIZE)) {
7036 use_dma = FALSE;
7037 }
7038 }
7039
7040 if(deviceExtension->HwFlags & UNIATA_AHCI) {
7041 KdPrint2((PRINT_PREFIX "IdeReadWrite: setup AHCI FIS\n"));
7042 RtlZeroMemory(&(AtaReq->ahci.ahci_cmd_ptr->cfis), sizeof(AtaReq->ahci_cmd0.cfis));
7043
7044 fis_size = UniataAhciSetupFIS_H2D(deviceExtension, DeviceNumber, lChannel,
7045 &(AtaReq->ahci.ahci_cmd_ptr->cfis[0]),
7047 lba,
7048 (USHORT)(AtaReq->bcount),
7049 0
7050 /*,(AtaReq->Flags & REQ_FLAG_READ) ? 0 : ATA_AHCI_CMD_WRITE*/
7051 );
7052
7053 if(!fis_size) {
7054 KdPrint3((PRINT_PREFIX "IdeReadWrite: AHCI !FIS\n"));
7055 return SRB_STATUS_ERROR;
7056 }
7057
7058 AtaReq->ahci.io_cmd_flags = UniAtaAhciAdjustIoFlags(0, (AtaReq->Flags & REQ_FLAG_READ) ? 0 : ATA_AHCI_CMD_WRITE, fis_size, DeviceNumber);
7059 KdPrint2((PRINT_PREFIX "IdeReadWrite ahci io flags %x: \n", AtaReq->ahci.io_cmd_flags));
7060 }
7061
7063
7064 } else { // exec_only
7065 KdPrint2((PRINT_PREFIX "IdeReadWrite (ExecOnly): \n"));
7066 lba = AtaReq->lba;
7067
7068 if(AtaReq->Flags & REQ_FLAG_DMA_OPERATION) {
7069 use_dma = TRUE;
7070 }
7071 }
7072 if(!(CmdAction & CMD_ACTION_EXEC)) {
7073
7074 return SRB_STATUS_PENDING;
7075 }
7076
7077 // if this is queued request, reinit DMA and check
7078 // if DMA mode is still available
7079 AtapiDmaReinit(deviceExtension, LunExt, AtaReq);
7080 if (/*EnableDma &&*/
7081 (LunExt->TransferMode >= ATA_DMA)) {
7082 use_dma = TRUE;
7083 } else {
7084 AtaReq->Flags &= ~REQ_FLAG_DMA_OPERATION;
7085 use_dma = FALSE;
7086 }
7087
7088 // Check if write request.
7090
7091 // Prepare read command.
7092 if(use_dma) {
7094 } else
7095 if(LunExt->MaximumBlockXfer) {
7097 } else {
7099 }
7100 } else {
7101
7102 // Prepare write command.
7103 if (use_dma) {
7104 wordCount = AtaReq->bcount*DEV_BSIZE/2;
7106 } else
7107 if (LunExt->MaximumBlockXfer) {
7108 wordCount = DEV_BSIZE/2 * LunExt->MaximumBlockXfer;
7109
7110 if (AtaReq->WordsLeft < wordCount) {
7111 // Transfer only words requested.
7112 wordCount = AtaReq->WordsLeft;
7113 }
7115
7116 } else {
7117 wordCount = DEV_BSIZE/2;
7119 }
7120 }
7121
7122 // Send IO command.
7123 KdPrint2((PRINT_PREFIX "IdeReadWrite: Lba %#I64x, Count %#x(%#x)\n", lba, ((Srb->DataTransferLength + 0x1FF) / 0x200),
7124 ((wordCount*2 + DEV_BSIZE-1) / DEV_BSIZE)));
7125 if(use_dma) {
7127 } else {
7128 chan->ChannelCtrlFlags &= ~CTRFLAGS_DMA_OPERATION;
7129 }
7130
7131 if(deviceExtension->HwFlags & UNIATA_AHCI) {
7132 // AHCI doesn't distinguish DMA and PIO
7133 //AtapiDmaStart(HwDeviceExtension, DeviceNumber, lChannel, Srb);
7134 UniataAhciBeginTransaction(HwDeviceExtension, lChannel, DeviceNumber, Srb);
7135 UniataExpectChannelInterrupt(chan, TRUE); // device may interrupt
7138 return SRB_STATUS_PENDING;
7139 }
7140
7141 if ((Srb->SrbFlags & SRB_FLAGS_DATA_IN) ||
7142 use_dma) {
7143 if(use_dma) {
7144 AtapiDmaDBPreSync(HwDeviceExtension, chan, Srb);
7147 KdPrint2((PRINT_PREFIX "CTRFLAGS_DMA_BEFORE_R on BOCHS\n"));
7148 AtapiDmaStart(HwDeviceExtension, DeviceNumber, lChannel, Srb);
7149 }
7150 }
7151 statusByte2 = AtaCommand48(deviceExtension, DeviceNumber, lChannel,
7152 cmd, lba,
7153 (USHORT)(AtaReq->bcount),
7154// (UCHAR)((wordCount*2 + DEV_BSIZE-1) / DEV_BSIZE),
7155 0, ATA_IMMEDIATE);
7156/* if(statusByte2 != IDE_STATUS_WRONG) {
7157 GetStatus(chan, statusByte2);
7158 }*/
7159 if(statusByte2 & IDE_STATUS_ERROR) {
7160 // Unfortunately, we cannot handle errors in such a way in real life (except known bad blocks).
7161 // Because some devices doesn't reset ERR from previous command immediately after getting new one.
7162 // On the other hand we cannot wait here because of possible timeout condition
7163 statusByte = AtapiReadPort1(chan, IDX_IO1_i_Error);
7164 KdPrint2((PRINT_PREFIX "IdeReadWrite: status %#x, error %#x\n", statusByte2, statusByte));
7165 return SRB_STATUS_ERROR;
7166 }
7167 if(use_dma) {
7170 //GetStatus(chan, statusByte2);
7171 AtapiDmaStart(HwDeviceExtension, DeviceNumber, lChannel, Srb);
7172 }
7173 }
7174 return SRB_STATUS_PENDING;
7175 }
7176
7177 statusByte = AtaCommand48(deviceExtension, DeviceNumber, lChannel,
7178 cmd, lba,
7179 (USHORT)(AtaReq->bcount),
7180// (UCHAR)((wordCount*2 + DEV_BSIZE-1) / DEV_BSIZE),
7181 0, ATA_WAIT_INTR);
7182
7183 if (!(statusByte & IDE_STATUS_DRQ) ||
7184 statusByte == IDE_STATUS_WRONG) {
7185
7186 if(statusByte == IDE_STATUS_WRONG) {
7188 "IdeReadWrite: error sending command (%#x)\n",
7189 statusByte));
7190 } else {
7192 "IdeReadWrite: DRQ never asserted (%#x)\n",
7193 statusByte));
7194 }
7195
7196 AtaReq->WordsLeft = 0;
7197
7198 // Clear interrupt expecting flag.
7202
7203 // Clear current SRB.
7204 UniataRemoveRequest(chan, Srb);
7205
7206 return (statusByte == IDE_STATUS_WRONG) ? SRB_STATUS_ERROR : SRB_STATUS_TIMEOUT;
7207 }
7208
7212
7213 // Write next DEV_BSIZE/2*N words.
7214 if (!(LunExt->DeviceFlags & DFLAGS_DWORDIO_ENABLED) || (wordCount & 1)) {
7216 "IdeReadWrite: Write %#x words\n", wordCount));
7217
7218 WriteBuffer(chan,
7219 AtaReq->DataBuffer,
7220 wordCount,
7221 UniataGetPioTiming(LunExt));
7222
7223 } else {
7224
7226 "IdeReadWrite: Write %#x Dwords\n", wordCount/2));
7227
7228 WriteBuffer2(chan,
7229 (PULONG)(AtaReq->DataBuffer),
7230 wordCount / 2,
7231 UniataGetPioTiming(LunExt));
7232 }
7233
7234 // Adjust buffer address and words left count.
7235 AtaReq->WordsLeft -= wordCount;
7236 AtaReq->DataBuffer += wordCount;
7237 AtaReq->WordsTransfered += wordCount;
7238
7239 // Wait for interrupt.
7240 return SRB_STATUS_PENDING;
7241
7242} // end IdeReadWrite()
7243
7244#ifndef UNIATA_CORE
7245
7246/*++
7247
7248Routine Description:
7249 This routine handles IDE Verify.
7250
7251Arguments:
7252 HwDeviceExtension - HBA miniport driver's adapter data storage
7253 Srb - IO request packet
7254 `
7255Return Value:
7256 SRB status
7257
7258--*/
7259ULONG
7260NTAPI
7262 IN PVOID HwDeviceExtension,
7264 )
7265{
7266 PHW_DEVICE_EXTENSION deviceExtension = (PHW_DEVICE_EXTENSION)HwDeviceExtension;
7267 UCHAR lChannel = GET_CHANNEL(Srb);
7268 PHW_CHANNEL chan = &(deviceExtension->chan[lChannel]);
7269 PATA_REQ AtaReq = (PATA_REQ)(Srb->SrbExtension);
7270 PHW_LU_EXTENSION LunExt;
7271 //ULONG ldev = GET_LDEV(Srb);
7273 UCHAR statusByte;
7274 ULONGLONG startingSector=0;
7275 ULONG max_bcount;
7277 ULONGLONG endSector;
7279 ULONGLONG lba;
7280
7281 LunExt = chan->lun[DeviceNumber];
7282 // Drive has these number sectors.
7283 if(!(sectors = (ULONG)(LunExt->NumOfSectors))) {
7285 LunExt->IdentifyData.NumberOfHeads *
7287 }
7288
7290 "IdeVerify: Total sectors %#I64x\n",
7291 sectors));
7292
7293 // Get starting sector number from CDB.
7294 switch(Srb->Cdb[0]) {
7295 case SCSIOP_VERIFY:
7296 MOV_DD_SWP(startingSector, ((PCDB)Srb->Cdb)->CDB10.LBA);
7297 MOV_SWP_DW2DD(sectorCount, ((PCDB)Srb->Cdb)->CDB10.TransferBlocks);
7298 break;
7299 case SCSIOP_VERIFY12:
7300 MOV_DD_SWP(startingSector, ((PCDB)Srb->Cdb)->CDB12READWRITE.LBA);
7301 MOV_DD_SWP(sectorCount, ((PCDB)Srb->Cdb)->CDB12READWRITE.NumOfBlocks);
7302 break;
7303 case SCSIOP_VERIFY16:
7304 MOV_QD_SWP(startingSector, ((PCDB)Srb->Cdb)->CDB16READWRITE.LBA);
7305 MOV_DD_SWP(sectorCount, ((PCDB)Srb->Cdb)->CDB16READWRITE.NumOfBlocks);
7306 break;
7307 }
7308
7310 "IdeVerify: Starting sector %#I64x. Number of blocks %#x\n",
7311 startingSector,
7312 sectorCount));
7313
7314 endSector = startingSector + sectorCount;
7315
7317 "IdeVerify: Ending sector %#I64x\n",
7318 endSector));
7319
7320 if (endSector > sectors) {
7321
7322 // Too big, round down.
7324 "IdeVerify: Truncating request to %#x blocks\n",
7325 sectors - startingSector - 1));
7326
7327 sectorCount = (ULONG)(sectors - startingSector - 1);
7328
7329 } else {
7330
7331 // Set up sector count register. Round up to next block.
7332 if (sectorCount > 0xFF) {
7333 sectorCount = (USHORT)0xFF;
7334 }
7335 }
7336
7337 // Set data buffer pointer and words left.
7338 AtaReq->DataBuffer = (PUSHORT)Srb->DataBuffer;
7339 AtaReq->WordsLeft = Srb->DataTransferLength / 2;
7340
7341 // Indicate expecting an interrupt.
7344
7345 lba = UniAtaCalculateLBARegs(LunExt, startingSector, &max_bcount);
7346
7347 statusByte = AtaCommand48(deviceExtension, LunExt->Lun, GET_CHANNEL(Srb),
7350 0, ATA_IMMEDIATE);
7351
7352 if(!(statusByte & IDE_STATUS_ERROR)) {
7353 // Wait for interrupt.
7355 return SRB_STATUS_PENDING;
7356 }
7357 return SRB_STATUS_ERROR;
7358
7359} // end IdeVerify()
7360
7361#endif //UNIATA_CORE
7362
7363/*++
7364
7365Routine Description:
7366 Send ATAPI packet command to device.
7367
7368Arguments:
7369 HwDeviceExtension - HBA miniport driver's adapter data storage
7370 Srb - IO request packet
7371
7372Return Value:
7373
7374--*/
7375ULONG
7376NTAPI
7378 IN PVOID HwDeviceExtension,
7380 IN ULONG CmdAction
7381 )
7382{
7383 PHW_DEVICE_EXTENSION deviceExtension = (PHW_DEVICE_EXTENSION)HwDeviceExtension;
7384 UCHAR lChannel = GET_CHANNEL(Srb);
7385 PHW_CHANNEL chan = &(deviceExtension->chan[lChannel]);
7386 PATA_REQ AtaReq = (PATA_REQ)(Srb->SrbExtension);
7387 PHW_LU_EXTENSION LunExt;
7388 //ULONG ldev = GET_LDEV(Srb);
7390 ULONG flags;
7391 UCHAR statusByte,statusByte0,byteCountLow,byteCountHigh;
7392 UCHAR interruptReason;
7393 BOOLEAN use_dma = FALSE;
7394 BOOLEAN dma_reinited = FALSE;
7395 BOOLEAN retried = FALSE;
7396 ULONG fis_size, i;
7397 UCHAR FeatureReg=0;
7398
7399 LunExt = chan->lun[DeviceNumber];
7400
7401 KdPrint3((PRINT_PREFIX "AtapiSendCommand: req state %#x, Action %x\n", AtaReq->ReqState, CmdAction));
7404
7405
7406#ifdef UNIATA_DUMP_ATAPI
7407 if(CmdAction & CMD_ACTION_PREPARE) {
7408 UCHAR ScsiCommand;
7409 PCDB Cdb;
7410 PCHAR CdbData;
7411 PCHAR ModeSelectData;
7412 ULONG CdbDataLen;
7413
7414 Cdb = (PCDB)(Srb->Cdb);
7415 ScsiCommand = Cdb->CDB6.OperationCode;
7416 CdbData = (PCHAR)(Srb->DataBuffer);
7417 CdbDataLen = Srb->DataTransferLength;
7418
7419 if(CdbDataLen > 0x1000) {
7420 CdbDataLen = 0x1000;
7421 }
7422
7423 KdPrint(("--\n"));
7424 KdPrint2(("DeviceID+VendorID/Rev %#x/%#x\n", deviceExtension->DevID, deviceExtension->RevID));
7425 KdPrint2(("P:T:D=%d:%d:%d\n",
7426 Srb->PathId,
7427 Srb->TargetId,
7428 Srb->Lun));
7429 KdPrint(("SCSI Command %2.2x\n", ScsiCommand));
7430 KdDump(Cdb, 16);
7431
7432 if(ScsiCommand == SCSIOP_WRITE_CD) {
7433 KdPrint(("Write10, LBA %2.2x%2.2x%2.2x%2.2x\n",
7434 Cdb->WRITE_CD.LBA[0],
7435 Cdb->WRITE_CD.LBA[1],
7436 Cdb->WRITE_CD.LBA[2],
7437 Cdb->WRITE_CD.LBA[3]
7438 ));
7439 } else
7440 if(ScsiCommand == SCSIOP_WRITE12) {
7441 KdPrint(("Write12, LBA %2.2x%2.2x%2.2x%2.2x\n",
7442 Cdb->CDB12READWRITE.LBA[0],
7443 Cdb->CDB12READWRITE.LBA[1],
7444 Cdb->CDB12READWRITE.LBA[2],
7445 Cdb->CDB12READWRITE.LBA[3]
7446 ));
7447 } else
7448 if(ScsiCommand == SCSIOP_WRITE16) {
7449 KdPrint(("Write16, LBA %2.2x%2.2x%2.2x%2.2x%2.2x%2.2x%2.2x%2.2x\n",
7450 Cdb->CDB16READWRITE.LBA[0],
7451 Cdb->CDB16READWRITE.LBA[1],
7452 Cdb->CDB16READWRITE.LBA[2],
7453 Cdb->CDB16READWRITE.LBA[3],
7454 Cdb->CDB16READWRITE.LBA[4],
7455 Cdb->CDB16READWRITE.LBA[5],
7456 Cdb->CDB16READWRITE.LBA[6],
7457 Cdb->CDB16READWRITE.LBA[7]
7458 ));
7459 } else
7460 if(ScsiCommand == SCSIOP_MODE_SELECT) {
7461 KdPrint(("ModeSelect 6\n"));
7463 ModeSelectData = CdbData+4;
7464 KdDump(CdbData, CdbDataLen);
7465 } else
7466 if(ScsiCommand == SCSIOP_MODE_SELECT10) {
7467 KdPrint(("ModeSelect 10\n"));
7469 ModeSelectData = CdbData+8;
7470 KdDump(CdbData, CdbDataLen);
7471 } else {
7473 KdPrint(("Send buffer to device:\n"));
7474 KdDump(CdbData, CdbDataLen);
7475 }
7476 }
7477 KdPrint(("--\n"));
7478 }
7479#endif //UNIATA_DUMP_ATAPI
7480
7481
7482 if(CmdAction == CMD_ACTION_PREPARE) {
7483 KdPrint2((PRINT_PREFIX "AtapiSendCommand: CMD_ACTION_PREPARE, Cdb %x\n", &(Srb->Cdb)));
7484
7485 switch (Srb->Cdb[0]) {
7486 case SCSIOP_RECEIVE:
7487 case SCSIOP_SEND:
7488 case SCSIOP_READ:
7489 case SCSIOP_WRITE:
7490 case SCSIOP_READ12:
7491 case SCSIOP_WRITE12:
7492 case SCSIOP_READ16:
7493 case SCSIOP_WRITE16:
7494 // all right
7495 break;
7496 case SCSIOP_READ_CD:
7497 case SCSIOP_READ_CD_MSF:
7498 if(deviceExtension->opt_AtapiDmaRawRead) {
7499 // all right
7500 break;
7501 }
7502 /* FALL THROUGH */
7503 default:
7504 KdPrint2((PRINT_PREFIX "AtapiSendCommand: SRB_STATUS_BUSY\n"));
7505 return SRB_STATUS_BUSY;
7506 }
7507 //
7508#ifdef UNIATA_INIT_CHANGERS
7509 if (!(LunExt->DeviceFlags & DFLAGS_CHANGER_INITED) &&
7510 !AtaReq->OriginalSrb) {
7511 KdPrint2((PRINT_PREFIX "AtapiSendCommand: SRB_STATUS_BUSY (2)\n"));
7512 return SRB_STATUS_BUSY;
7513 }
7514#endif // UNIATA_INIT_CHANGERS
7515 }
7516
7517#ifndef UNIATA_CORE
7518 // standard atapi.sys claims:
7519
7520 // We need to know how many platters our atapi cd-rom device might have.
7521 // Before anyone tries to send a srb to our target for the first time,
7522 // we must "secretly" send down a separate mechanism status srb in order to
7523 // initialize our device extension changer data. That's how we know how
7524 // many platters our target has.
7525
7526 // BUT!
7527 // some devices freeze (sometimes) forever on this command
7528 // Let CD-ROM driver send this command itself, if it find it necessary
7529 // We shall just parse output (if any)
7530
7531#ifdef UNIATA_INIT_CHANGERS
7532 if (!(LunExt->DeviceFlags & DFLAGS_CHANGER_INITED) &&
7533 !AtaReq->OriginalSrb) {
7534
7535 ULONG srbStatus;
7536
7537 KdPrint3((PRINT_PREFIX "AtapiSendCommand: BuildMechanismStatusSrb()\n"));
7538 // Set this flag now. If the device hangs on the mech. status
7539 // command, we will not have the chance to set it.
7541
7542 chan->MechStatusRetryCount = 3;
7543 AtaReq->OriginalSrb = Srb;
7544 AtaReq->Srb = BuildMechanismStatusSrb (
7545 HwDeviceExtension,
7546 Srb);
7547
7548 KdPrint3((PRINT_PREFIX "AtapiSendCommand: AtapiSendCommand recursive\n"));
7549 srbStatus = AtapiSendCommand(HwDeviceExtension, AtaReq->Srb, CMD_ACTION_ALL);
7550 if (srbStatus == SRB_STATUS_PENDING) {
7551 KdPrint2((PRINT_PREFIX "AtapiSendCommand: SRB_STATUS_PENDING (2)\n"));
7552 return srbStatus;
7553 } else {
7554
7555 // failed! Get the sense key and maybe try again
7556 AtaReq->Srb = BuildRequestSenseSrb ( HwDeviceExtension,
7557 AtaReq->OriginalSrb);
7558
7559 srbStatus = AtapiSendCommand(HwDeviceExtension, AtaReq->Srb, CMD_ACTION_ALL);
7560
7561 KdPrint3((PRINT_PREFIX "AtapiSendCommand: chan->ExpectingInterrupt %d (1)\n", chan->ExpectingInterrupt));
7562
7563 if (srbStatus == SRB_STATUS_PENDING) {
7564 KdPrint2((PRINT_PREFIX "AtapiSendCommand: send orig SRB_STATUS_PENDING (2.1)\n"));
7565 return srbStatus;
7566 }
7567
7568 // failed again ? should not get here
7569 AtaReq->Srb = AtaReq->OriginalSrb;
7570 AtaReq->OriginalSrb = NULL;
7571 // fall out
7572 }
7573 }
7574#endif // UNIATA_INIT_CHANGERS
7575#endif //UNIATA_CORE
7576
7577 if((CmdAction & CMD_ACTION_PREPARE) &&
7579
7580 KdPrint2((PRINT_PREFIX "AtapiSendCommand: prepare..., ATAPI CMD %x (Cdb %x)\n", Srb->Cdb[0], &(Srb->Cdb)));
7581
7582 if(!LunExt->IdentifyData.AtapiCmdSize &&
7583 (Srb->CdbLength > 12)) {
7584 KdPrint2((PRINT_PREFIX "Cdb16 not supported\n"));
7586 }
7587
7588 // Set data buffer pointer and words left.
7589 AtaReq->DataBuffer = (PUSHORT)Srb->DataBuffer;
7590 AtaReq->WordsLeft = Srb->DataTransferLength / 2;
7592 AtaReq->Flags &= ~REQ_FLAG_DMA_OPERATION;
7593 // reset this to force PRD init. May be already setup by recursive SRB
7594 AtaReq->dma_entries = 0;
7595
7596 // check if reorderable
7597 switch(Srb->Cdb[0]) {
7598 case SCSIOP_READ16:
7599 case SCSIOP_WRITE16:
7600
7601 MOV_DD_SWP(AtaReq->bcount, ((PCDB)Srb->Cdb)->CDB16READWRITE.NumOfBlocks);
7602 MOV_QD_SWP(AtaReq->lba, ((PCDB)Srb->Cdb)->CDB16READWRITE.LBA);
7603 goto GetLba2;
7604
7605 case SCSIOP_READ12:
7606 case SCSIOP_WRITE12:
7607
7608 MOV_DD_SWP(AtaReq->bcount, ((PCDB)Srb->Cdb)->CDB12READWRITE.NumOfBlocks);
7609 goto GetLba;
7610
7611 case SCSIOP_READ:
7612 case SCSIOP_WRITE:
7613
7614 MOV_SWP_DW2DD(AtaReq->bcount, ((PCDB)Srb->Cdb)->CDB10.TransferBlocks);
7615GetLba:
7616 MOV_DD_SWP(AtaReq->lba, ((PCDB)Srb->Cdb)->CDB10.LBA);
7617GetLba2:
7619 AtaReq->Flags &= ~REQ_FLAG_RW_MASK;
7620 AtaReq->Flags |= (Srb->Cdb[0] == SCSIOP_WRITE ||
7621 Srb->Cdb[0] == SCSIOP_WRITE12 ||
7622 Srb->Cdb[0] == SCSIOP_WRITE16) ?
7624 break;
7625 default:
7626 AtaReq->Flags &= ~REQ_FLAG_RW_MASK;
7627 if(!AtaReq->TransferLength) {
7628 KdPrint((" assume 0-transfer\n"));
7629 } else
7631 KdPrint((" assume OUT\n"));
7632 AtaReq->Flags |= REQ_FLAG_WRITE;
7633 } else
7635 KdPrint((" assume IN\n"));
7636 AtaReq->Flags |= REQ_FLAG_READ;
7637 }
7638 break;
7639 }
7640
7641 // check if DMA read/write
7642 if(g_opt_AtapiNoDma) {
7643 KdPrint2((PRINT_PREFIX "AtapiSendCommand: CTRFLAGS_DMA_BEFORE_R => no dma\n"));
7644 use_dma = FALSE;
7645 } else
7646 if(deviceExtension->HwFlags & UNIATA_AHCI) {
7647 KdPrint2((PRINT_PREFIX "AtapiSendCommand: force use dma (ahci)\n"));
7648 use_dma = TRUE;
7649 goto setup_dma;
7650 } else
7651/* if((deviceExtension->HwFlags & UNIATA_SATA) && (LunExt->OrigTransferMode >= ATA_DMA)) {
7652 KdPrint2((PRINT_PREFIX "AtapiSendCommand: force use dma (sata)\n"));
7653 use_dma = TRUE;
7654 goto setup_dma;
7655 } else*/
7656 if(Srb->Cdb[0] == SCSIOP_REQUEST_SENSE) {
7657 KdPrint2((PRINT_PREFIX "AtapiSendCommand: SCSIOP_REQUEST_SENSE, no DMA setup\n"));
7658 } else
7659 if(AtaReq->TransferLength && !(AtaReq->TransferLength & 0x0f)) {
7660 KdPrint2((PRINT_PREFIX "AtapiSendCommand: try DMA setup\n"));
7661 // try use DMA if TransferLength is 16-byte aligned
7662 switch(Srb->Cdb[0]) {
7663 case SCSIOP_WRITE:
7664 case SCSIOP_WRITE12:
7665 case SCSIOP_WRITE16:
7666 case SCSIOP_SEND:
7668 break;
7669 /* FALLTHROUGH */
7670 case SCSIOP_RECEIVE:
7671 case SCSIOP_READ:
7672 case SCSIOP_READ12:
7673 case SCSIOP_READ16:
7674
7675 if(deviceExtension->opt_AtapiDmaReadWrite) {
7676call_dma_setup:
7677 if(deviceExtension->HwFlags & UNIATA_AHCI) {
7678 KdPrint2((PRINT_PREFIX "AtapiSendCommand: use dma (ahci)\n"));
7679 use_dma = TRUE;
7680 } else
7681 if(AtapiDmaSetup(HwDeviceExtension, DeviceNumber, lChannel, Srb,
7682 (PUCHAR)(AtaReq->DataBuffer),
7684 /*((Srb->DataTransferLength + DEV_BSIZE-1) & ~(DEV_BSIZE-1))*/
7685 )) {
7686 KdPrint2((PRINT_PREFIX "AtapiSendCommand: use dma\n"));
7687 use_dma = TRUE;
7688 }
7689 }
7690 break;
7691 case SCSIOP_READ_CD:
7692 case SCSIOP_READ_CD_MSF:
7693 if(deviceExtension->opt_AtapiDmaRawRead)
7694 goto call_dma_setup;
7695 break;
7696 default:
7697
7698 if(deviceExtension->opt_AtapiDmaControlCmd) {
7700 // read operation
7701 use_dma = TRUE;
7702 } else {
7703 // write operation
7704 if(chan->ChannelCtrlFlags & CTRFLAGS_DMA_RO) {
7705 KdPrint2((PRINT_PREFIX "dma RO\n"));
7706 use_dma = FALSE;
7707 } else {
7708 use_dma = TRUE;
7709 }
7710 }
7711 }
7712 break;
7713 }
7714 // try setup DMA
7715setup_dma:
7716 if(use_dma) {
7717 if(deviceExtension->HwFlags & UNIATA_AHCI) {
7718 KdPrint2((PRINT_PREFIX "AtapiSendCommand: use dma (ahci)\n"));
7719 //use_dma = TRUE;
7720 } else
7721 if(!AtapiDmaSetup(HwDeviceExtension, DeviceNumber, lChannel, Srb,
7722 (PUCHAR)(AtaReq->DataBuffer),
7724 KdPrint2((PRINT_PREFIX "AtapiSendCommand: no dma\n"));
7725 use_dma = FALSE;
7726 } else {
7727 KdPrint2((PRINT_PREFIX "AtapiSendCommand: use dma\n"));
7728 }
7729 }
7730 } else {
7731 KdPrint2((PRINT_PREFIX "AtapiSendCommand: zero/unaligned transfer %x, no DMA setup\n", AtaReq->TransferLength));
7732 }
7733
7734
7735 if(deviceExtension->HwFlags & UNIATA_AHCI) {
7736
7737 UniataAhciSetupCmdPtr(AtaReq);
7738
7739 if(!Srb->DataTransferLength) {
7740 KdPrint2((PRINT_PREFIX "zero-transfer\n"));
7741 use_dma = FALSE;
7742 } else
7743 if(!AtapiDmaSetup(HwDeviceExtension, DeviceNumber, lChannel, Srb,
7744 (PUCHAR)(AtaReq->DataBuffer),
7746 KdPrint2((PRINT_PREFIX "AtapiSendCommand: no AHCI dma!\n"));
7747 return SRB_STATUS_ERROR;
7748 }
7749 if(!use_dma) {
7750 AtaReq->Flags &= ~REQ_FLAG_DMA_OPERATION;
7751 } else {
7752 FeatureReg |= ATA_F_DMA;
7753 if(LunExt->IdentifyData.AtapiDMA.DMADirRequired) {
7755 KdPrint2((PRINT_PREFIX "Set DMADir.\n"));
7756 FeatureReg |= ATA_F_DMAREAD;
7757 }
7758 }
7759 }
7760
7761 KdPrint2((PRINT_PREFIX "AtapiSendCommand: setup AHCI FIS\n"));
7762 // this is done in UniataAhciSetupFIS_H2D()
7763 //RtlZeroMemory(&(AtaReq->ahci.ahci_cmd_ptr->cfis), sizeof(AtaReq->ahci_cmd0.cfis));
7764 RtlCopyMemory(&(AtaReq->ahci.ahci_cmd_ptr->acmd), Srb->Cdb, Srb->CdbLength);
7765
7766 fis_size = UniataAhciSetupFIS_H2D(deviceExtension, DeviceNumber, lChannel,
7767 &(AtaReq->ahci.ahci_cmd_ptr->cfis[0]),
7768 IDE_COMMAND_ATAPI_PACKET /* command */,
7769 0 /* lba */,
7770 (Srb->DataTransferLength >= 0x10000) ? (USHORT)(0xffff) : (USHORT)(Srb->DataTransferLength),
7771 FeatureReg/* feature */
7772 );
7773
7774 if(!fis_size) {
7775 KdPrint3((PRINT_PREFIX "AtapiSendCommand: AHCI !FIS\n"));
7776 return SRB_STATUS_ERROR;
7777 }
7778
7779 AtaReq->ahci.io_cmd_flags = UniAtaAhciAdjustIoFlags(0,
7782 fis_size, DeviceNumber);
7783
7784 KdPrint2((PRINT_PREFIX "AtapiSendCommand ahci io flags %x: \n", AtaReq->ahci.io_cmd_flags));
7785 }
7786
7787 } else {
7788 if(AtaReq->Flags & REQ_FLAG_DMA_OPERATION) {
7789 // if this is queued request, reinit DMA and check
7790 // if DMA mode is still available
7791 KdPrint2((PRINT_PREFIX "AtapiSendCommand: AtapiDmaReinit() (1)\n"));
7792 AtapiDmaReinit(deviceExtension, LunExt, AtaReq);
7793 if (/*EnableDma &&*/
7794 (LunExt->TransferMode >= ATA_DMA)) {
7795 KdPrint2((PRINT_PREFIX "AtapiSendCommand: use dma (2)\n"));
7796 use_dma = TRUE;
7797 } else {
7798 AtaReq->Flags &= ~REQ_FLAG_DMA_OPERATION;
7799 KdPrint2((PRINT_PREFIX "AtapiSendCommand: no dma (2)\n"));
7800 use_dma = FALSE;
7801 }
7802 dma_reinited = TRUE;
7803 }
7804 }
7805
7806 if(!(CmdAction & CMD_ACTION_EXEC)) {
7807 KdPrint2((PRINT_PREFIX "AtapiSendCommand: !CMD_ACTION_EXEC => SRB_STATUS_PENDING\n"));
7808 return SRB_STATUS_PENDING;
7809 }
7810 KdPrint3((PRINT_PREFIX "AtapiSendCommand: use_dma=%d, Cmd %x\n", use_dma, Srb->Cdb[0]));
7811 if(AtaReq->Flags & REQ_FLAG_DMA_OPERATION) {
7812 KdPrint2((PRINT_PREFIX " REQ_FLAG_DMA_OPERATION\n"));
7813 }
7814
7815 if((Srb->Cdb[0] == SCSIOP_REQUEST_SENSE) && !(deviceExtension->HwFlags & UNIATA_SATA)) {
7816 KdPrint2((PRINT_PREFIX "AtapiSendCommand: SCSIOP_REQUEST_SENSE -> no dma setup (2)\n"));
7817 use_dma = FALSE;
7818 AtaReq->Flags &= ~REQ_FLAG_DMA_OPERATION;
7819 AtapiDmaReinit(deviceExtension, LunExt, AtaReq);
7820 } if(AtaReq->TransferLength) {
7821 if(!dma_reinited) {
7822 KdPrint2((PRINT_PREFIX "AtapiSendCommand: AtapiDmaReinit()\n"));
7823 AtapiDmaReinit(deviceExtension, LunExt, AtaReq);
7824 if (/*EnableDma &&*/
7825 (LunExt->TransferMode >= ATA_DMA)) {
7826 use_dma = TRUE;
7827 } else {
7828 AtaReq->Flags &= ~REQ_FLAG_DMA_OPERATION;
7829 use_dma = FALSE;
7830 }
7831 }
7832 } else {
7833 KdPrint2((PRINT_PREFIX "AtapiSendCommand: zero transfer\n"));
7834 use_dma = FALSE;
7835 AtaReq->Flags &= ~REQ_FLAG_DMA_OPERATION;
7836 if(!deviceExtension->opt_AtapiDmaZeroTransfer && !(deviceExtension->HwFlags & UNIATA_SATA)) {
7837 KdPrint2((PRINT_PREFIX "AtapiSendCommand: AtapiDmaReinit() to PIO\n"));
7838 AtapiDmaReinit(deviceExtension, LunExt, AtaReq);
7839 }
7840 }
7841 KdPrint2((PRINT_PREFIX "AtapiSendCommand: use_dma=%d\n", use_dma));
7842 if(AtaReq->Flags & REQ_FLAG_DMA_OPERATION) {
7843 KdPrint2((PRINT_PREFIX " REQ_FLAG_DMA_OPERATION\n"));
7844 }
7845
7846 KdPrint2((PRINT_PREFIX "AtapiSendCommand: CMD_ACTION_EXEC\n"));
7847
7848 KdPrint3((PRINT_PREFIX "AtapiSendCommand: Cdb %x Command %#x to TargetId %d lun %d\n",
7849 &(Srb->Cdb), Srb->Cdb[0], Srb->TargetId, Srb->Lun));
7850
7851 // Make sure command is to ATAPI device.
7852 flags = LunExt->DeviceFlags;
7854 if((Srb->Lun) > (LunExt->DiscsPresent - 1)) {
7855
7856 // Indicate no device found at this address.
7859 }
7860 } else if(Srb->Lun > 0) {
7863 }
7864
7865 if(!(flags & DFLAGS_ATAPI_DEVICE)) {
7868 }
7869retry:
7870 // Select device 0 or 1. Or more for PM
7872
7873 // Verify that controller is ready for next command.
7874 GetStatus(chan, statusByte);
7875 KdPrint3((PRINT_PREFIX "AtapiSendCommand: Entered with status %#x\n", statusByte));
7876
7877 if(statusByte == IDE_STATUS_WRONG) {
7878 KdPrint2((PRINT_PREFIX "AtapiSendCommand: bad status 0xff on entry\n"));
7879 goto make_reset;
7880 }
7881 if(statusByte & IDE_STATUS_BUSY) {
7882 if(statusByte & IDE_STATUS_DSC) {
7883 KdPrint2((PRINT_PREFIX "AtapiSendCommand: DSC on entry (%#x), try exec\n", statusByte));
7884 } else {
7885 KdPrint2((PRINT_PREFIX "AtapiSendCommand: Device busy (%#x) -> reset\n", statusByte));
7886 // We have to make reset here, since we are expecting device to be available
7887 //return SRB_STATUS_BUSY; // this cause queue freeze
7888 goto make_reset;
7889 }
7890 }
7891 if(deviceExtension->HwFlags & UNIATA_AHCI) {
7892 ULONG CI;
7893 // Check if command list is free
7895 if(CI) {
7896 // controller is busy, however we expect it to be free
7897 KdPrint2((PRINT_PREFIX "AtapiSendCommand: Controller busy (CI=%#x) -> reset\n", CI));
7898 goto make_reset;
7899 }
7900 }
7901 if(statusByte & IDE_STATUS_ERROR) {
7902 if (Srb->Cdb[0] != SCSIOP_REQUEST_SENSE) {
7903
7904 KdPrint3((PRINT_PREFIX "AtapiSendCommand: Error on entry: (%#x)\n", statusByte));
7905 // Read the error reg. to clear it and fail this request.
7907 return MapError(deviceExtension, Srb);
7908 } else {
7909 KdPrint2((PRINT_PREFIX " continue with SCSIOP_REQUEST_SENSE\n", statusByte));
7910 }
7911 }
7912 // If a tape drive doesn't have DSC set and the last command is restrictive, don't send
7913 // the next command. See discussion of Restrictive Delayed Process commands in QIC-157.
7914 if((!(statusByte & IDE_STATUS_DSC)) &&
7916
7918 KdPrint2((PRINT_PREFIX "AtapiSendCommand: DSC not set. %#x => SRB_STATUS_PENDING\n",statusByte));
7919 AtaReq->ReqState = REQ_STATE_QUEUED;
7920 return SRB_STATUS_PENDING;
7921 }
7922
7923 if(IS_RDP(Srb->Cdb[0])) {
7924 chan->RDP = TRUE;
7925 KdPrint2((PRINT_PREFIX "AtapiSendCommand: %#x mapped as DSC restrictive\n", Srb->Cdb[0]));
7926 } else {
7927 chan->RDP = FALSE;
7928 }
7929 if(statusByte & IDE_STATUS_DRQ) {
7930
7931 KdPrint3((PRINT_PREFIX "AtapiSendCommand: Entered with status (%#x). Attempting to recover.\n",
7932 statusByte));
7933 // Try to drain the data that one preliminary device thinks that it has
7934 // to transfer. Hopefully this random assertion of DRQ will not be present
7935 // in production devices.
7936 statusByte = AtapiSuckPort2(chan);
7937/*
7938 for (i = 0; i < 0x10000; i++) {
7939 GetStatus(chan, statusByte);
7940 if(statusByte & IDE_STATUS_DRQ) {
7941 AtapiReadPort2(chan, IDX_IO1_i_Data);
7942 } else {
7943 break;
7944 }
7945 }
7946*/
7947 if (statusByte & IDE_STATUS_DRQ) {
7948 KdPrint3((PRINT_PREFIX "AtapiSendCommand: DRQ still asserted. Status (%#x)\n", statusByte));
7949make_reset:
7950 AtapiDisableInterrupts(deviceExtension, lChannel);
7951
7953
7954 KdPrint2((PRINT_PREFIX "AtapiSendCommand: Issued soft reset to Atapi device. \n"));
7955 // Re-initialize Atapi device.
7956 CheckDevice(HwDeviceExtension, GET_CHANNEL(Srb), DeviceNumber, TRUE);
7957/*
7958 IssueIdentify(HwDeviceExtension, DeviceNumber, GET_CHANNEL(Srb),
7959 IDE_COMMAND_ATAPI_IDENTIFY, FALSE);
7960*/
7961 // Inform the port driver that the bus has been reset.
7962 ScsiPortNotification(ResetDetected, HwDeviceExtension, 0);
7963 // Clean up device extension fields that AtapiStartIo won't.
7965 chan->RDP = FALSE;
7966 InterlockedExchange(&(deviceExtension->chan[GET_CHANNEL(Srb)].CheckIntr),
7968
7969 AtapiEnableInterrupts(deviceExtension, lChannel);
7970/*
7971 AtaReq->ReqState = REQ_STATE_TRANSFER_COMPLETE;
7972 return SRB_STATUS_BUS_RESET;
7973*/
7974 if(!retried) {
7975 KdPrint3((PRINT_PREFIX "AtapiSendCommand: retry after reset.\n"));
7976 retried = TRUE;
7977 goto retry;
7978 }
7979 KdPrint3((PRINT_PREFIX "AtapiSendCommand: selection timeout.\n"));
7982 }
7983 }
7984
7986 // As the cdrom driver sets the LUN field in the cdb, it must be removed.
7987 Srb->Cdb[1] &= ~0xE0;
7989 // Torisan changer. TUR's are overloaded to be platter switches.
7990 Srb->Cdb[7] = Srb->Lun;
7991 }
7992 }
7993
7994 // SETUP DMA !!!!!
7995
7996 if(use_dma) {
7998 } else {
7999 chan->ChannelCtrlFlags &= ~CTRFLAGS_DMA_OPERATION;
8000 }
8001
8002 if(deviceExtension->HwFlags & UNIATA_AHCI) {
8003 KdPrint2((PRINT_PREFIX "AtapiSendCommand: AHCI, begin transaction\n"));
8004 //AtaReq->Flags = ~REQ_FLAG_DMA_OPERATION; // keep proped DMA flag for proper RETRY handling
8006 UniataAhciBeginTransaction(HwDeviceExtension, lChannel, DeviceNumber, Srb);
8007 return SRB_STATUS_PENDING;
8008 }
8009
8010 statusByte = WaitOnBusy(chan);
8011 KdPrint3((PRINT_PREFIX "AtapiSendCommand: Entry Status (%#x)\n",
8012 statusByte));
8013
8014 if(use_dma) {
8015 FeatureReg |= ATA_F_DMA;
8016 if(LunExt->IdentifyData.AtapiDMA.DMADirRequired) {
8018 FeatureReg |= ATA_F_DMAREAD;
8019 }
8020 }
8021 }
8022
8023 // Write transfer byte count to registers.
8024 if (Srb->DataTransferLength >= 0x10000) {
8025 byteCountLow = byteCountHigh = 0xFF;
8026 } else {
8027 byteCountLow = (UCHAR)(Srb->DataTransferLength & 0xFF);
8028 byteCountHigh = (UCHAR)(Srb->DataTransferLength >> 8);
8029 }
8030
8031 KdPrint3((PRINT_PREFIX "AtapiSendCommand: F:%#x, CntHL:%#x:%#x.\n", FeatureReg, byteCountHigh, byteCountLow));
8032
8033 if (flags & DFLAGS_INT_DRQ) {
8034 // This device interrupts when ready to receive the packet.
8035 KdPrint3((PRINT_PREFIX "AtapiSendCommand: Wait for int. to send packet. Status (%#x)\n",
8036 statusByte));
8037
8042 // inform driver that packet command must be sent in ISR
8044 } else {
8045 // This device quickly sets DRQ when ready to receive the packet.
8046 KdPrint2((PRINT_PREFIX "AtapiSendCommand: Poll for int. to send packet. Status (%#x)\n",
8047 statusByte));
8048
8053
8055 AtapiDisableInterrupts(deviceExtension, lChannel);
8056 }
8057 // remember status. Later we may check if error appeared after cmd packet
8058 statusByte0 = statusByte;
8059 }
8060
8061 // must be already selected, experimental for ROS BUG-9119
8062 //AtapiWritePort1(chan, IDX_IO1_o_DriveSelect, IDE_USE_LBA | (DeviceNumber ? IDE_DRIVE_2 : IDE_DRIVE_1) );
8064 AtapiWritePort1(chan, IDX_ATAPI_IO1_o_Feature /*IDX_IO1_o_Feature*/, FeatureReg);
8065 //AtapiWritePort1(chan, IDX_ATAPI_IO1_o_Unused0, 0); // experimental for ROS BUG-9119
8066 //AtapiWritePort1(chan, IDX_ATAPI_IO1_o_Unused1, 0); // experimental for ROS BUG-9119
8067 AtapiWritePort1(chan, IDX_ATAPI_IO1_o_ByteCountLow, byteCountLow);
8068 AtapiWritePort1(chan, IDX_ATAPI_IO1_o_ByteCountHigh, byteCountHigh);
8069 // Write ATAPI packet command.
8071
8072 if (flags & DFLAGS_INT_DRQ) {
8073 // Wait for interrupt and send PACKET there
8074 KdPrint3((PRINT_PREFIX "AtapiSendCommand: return SRB_STATUS_PENDING (DRQ)\n"));
8075 return SRB_STATUS_PENDING;
8076 }
8077
8078 WaitOnBusy(chan);
8079/*
8080 // Wait for DRQ.
8081 statusByte = WaitForDrq(chan);
8082
8083 // Need to read status register and clear interrupt (if any)
8084 GetBaseStatus(chan, statusByte);
8085
8086 if (!(statusByte & IDE_STATUS_DRQ)) {
8087 if(g_opt_AtapiSendDisableIntr) {
8088 AtapiEnableInterrupts(deviceExtension, lChannel);
8089 }
8090 KdPrint3((PRINT_PREFIX "AtapiSendCommand: DRQ never asserted (%#x)\n", statusByte));
8091 AtaReq->ReqState = REQ_STATE_TRANSFER_COMPLETE;
8092 return SRB_STATUS_ERROR;
8093 }
8094*/
8095 GetStatus(chan, statusByte);
8096 KdPrint3((PRINT_PREFIX "AtapiSendCommand: status (%#x)\n", statusByte));
8097
8098 //statusByte = WaitOnBaseBusy(chan);
8099
8100 // Indicate expecting an interrupt and wait for it.
8102
8103 for(i=0; i<5000; i++) {
8105 GetStatus(chan, statusByte);
8106 } else {
8107 GetBaseStatus(chan, statusByte);
8108 }
8109 interruptReason = AtapiReadPort1(chan, IDX_ATAPI_IO1_i_InterruptReason);
8110 //KdPrint3((PRINT_PREFIX "AtapiSendCommand: iReason %x (%d)\n", interruptReason, i));
8111 if(((interruptReason & ATAPI_IR_COD) == ATAPI_IR_COD_Cmd) &&
8112 (((statusByte & (IDE_STATUS_BUSY | IDE_STATUS_DRQ)) == IDE_STATUS_DRQ))) {
8113 break;
8114 }
8116#ifdef _DEBUG
8117// KdPrint3((PRINT_PREFIX "AtapiSendCommand: wait CoD, status (%#x)\n", interruptReason));
8118#endif // _DEBUG
8119 }
8120 if(((interruptReason & ATAPI_IR_COD) != ATAPI_IR_COD_Cmd) ||
8121 (((statusByte & (IDE_STATUS_BUSY | IDE_STATUS_DRQ)) != IDE_STATUS_DRQ)) ) {
8122 KdPrint3((PRINT_PREFIX "AtapiSendCommand: no CoD raised, abort cmd\n"));
8123 KdPrint3((PRINT_PREFIX "AtapiSendCommand: iReason %x (%d)\n", interruptReason, i));
8124 KdPrint3((PRINT_PREFIX "AtapiSendCommand: status (%#x)\n", statusByte));
8126 AtapiEnableInterrupts(deviceExtension, lChannel);
8127 }
8128 KdPrint3((PRINT_PREFIX "AtapiSendCommand: DRQ+CoD never asserted\n"));
8129 statusByte = AtapiReadPort1(chan, IDX_IO1_i_Error);
8130 KdPrint3((PRINT_PREFIX "AtapiSendCommand: Err on cmd: (%#x)\n", statusByte));
8131 if(statusByte >> 4) {
8132 GetBaseStatus(chan, statusByte);
8134 return MapError(deviceExtension, Srb);
8135 }
8136 goto make_reset;
8137// AtaReq->ReqState = REQ_STATE_TRANSFER_COMPLETE;
8138// return SRB_STATUS_ERROR;
8139 } else {
8140 KdPrint3((PRINT_PREFIX "AtapiSendCommand: ready for packet, status %#x, i=%d\n", interruptReason, i));
8141 }
8142 // clear interrupt
8143 GetBaseStatus(chan, statusByte);
8144
8146 AtapiDmaDBPreSync(HwDeviceExtension, chan, Srb);
8147 }
8149 AtapiEnableInterrupts(deviceExtension, lChannel);
8150 }
8151
8152 // Send CDB to device.
8153 WriteBuffer(chan,
8154 (PUSHORT)Srb->Cdb,
8155 LunExt->IdentifyData.AtapiCmdSize ? 8 : 6,
8156 /*0*/ PIO0_TIMING);
8157
8158 GetStatus(chan, statusByte);
8159 KdPrint3((PRINT_PREFIX "AtapiSendCommand: cmd status (%#x)\n", statusByte));
8160
8161 // When we operate in DMA mode, we should not start transfer when there is an error on entry
8162 // Interrupt may never come in such case.
8163 if(statusByte & IDE_STATUS_ERROR) {
8164
8165 GetBaseStatus(chan, statusByte);
8166 KdPrint3((PRINT_PREFIX "AtapiSendCommand: Error on cmd: (%#x)\n", statusByte));
8167
8169 KdPrint3((PRINT_PREFIX "AtapiSendCommand: iReason %x\n", interruptReason));
8170
8171 // TODO: we should check interruptReason and decide what to do now
8172
8173 // Read the error reg. to clear it and fail this request.
8175 return MapError(deviceExtension, Srb);
8176 }
8177 if(statusByte & IDE_STATUS_DRQ) {
8178 // Some devices require this. If error condition is not checked in such a way,
8179 // device may not operate correctly and would be treated as failed
8180 // (and finally invisible for OS)
8181 KdPrint3((PRINT_PREFIX "AtapiSendCommand: DRQ on cmd: (%#x)\n", statusByte));
8182 // Read the error reg. to clear it and fail this request.
8183 statusByte = AtapiReadPort1(chan, IDX_IO1_i_Error);
8184 KdPrint3((PRINT_PREFIX "AtapiSendCommand: Err on cmd: (%#x)\n", statusByte));
8185 if(statusByte >> 4) {
8186 GetBaseStatus(chan, statusByte);
8188 return MapError(deviceExtension, Srb);
8189 }
8190 }
8191
8193 AtapiDmaStart(HwDeviceExtension, DeviceNumber, lChannel, Srb);
8194 }
8195
8199
8200 KdPrint3((PRINT_PREFIX "AtapiSendCommand: ExpectingInterrupt (%#x)\n", chan->ExpectingInterrupt));
8201
8202 KdPrint2((PRINT_PREFIX "AtapiSendCommand: return SRB_STATUS_PENDING (3)\n"));
8203 return SRB_STATUS_PENDING;
8204
8205} // end AtapiSendCommand()
8206
8207
8208#ifndef UNIATA_CORE
8209
8210/*++
8211
8212Routine Description:
8213 Program ATA registers for IDE disk transfer.
8214
8215Arguments:
8216 HwDeviceExtension - ATAPI driver storage.
8217 Srb - System request block.
8218
8219Return Value:
8220 SRB status (pending if all goes well).
8221
8222--*/
8223
8224#ifdef _DEBUG
8225ULONG check_point = 0;
8226#define SetCheckPoint(cp) { check_point = (cp) ; }
8227#else
8228#define SetCheckPoint(cp)
8229#endif
8230
8231ULONG
8232NTAPI
8234 IN PVOID HwDeviceExtension,
8236 IN ULONG CmdAction
8237 )
8238{
8239 SetCheckPoint(1);
8240 KdPrint2((PRINT_PREFIX "** Ide: Command: entryway\n"));
8241 SetCheckPoint(2);
8242
8243 PHW_DEVICE_EXTENSION deviceExtension = (PHW_DEVICE_EXTENSION)HwDeviceExtension;
8244 SetCheckPoint(3);
8245 UCHAR lChannel;
8246 PHW_CHANNEL chan;
8247 PCDB cdb;
8248 PHW_LU_EXTENSION LunExt;
8249
8250 SetCheckPoint(4);
8251
8252 UCHAR statusByte,errorByte;
8254 ULONG i;
8255 ULONGLONG lba;
8256 PMODE_PARAMETER_HEADER modeData;
8257 //ULONG ldev;
8259 PATA_REQ AtaReq;
8260 UCHAR command;
8261
8262 SetCheckPoint(5);
8263 //ULONG __ebp__ = 0;
8264
8265 SetCheckPoint(0x20);
8266 KdPrint2((PRINT_PREFIX "** Ide: Command:\n\n"));
8267/* __asm {
8268 mov eax,ebp
8269 mov __ebp__, eax
8270 }*/
8271 /*KdPrint2((PRINT_PREFIX "** Ide: Command EBP %#x, pCdb %#x, cmd %#x\n",
8272 __ebp__, &(Srb->Cdb[0]), Srb->Cdb[0]));
8273 KdPrint2((PRINT_PREFIX "** Ide: Command %s\n",
8274 (CmdAction == CMD_ACTION_PREPARE) ? "Prep " : ""));
8275 KdPrint2((PRINT_PREFIX "** Ide: Command Srb %#x\n",
8276 Srb));
8277 KdPrint2((PRINT_PREFIX "** Ide: Command SrbExt %#x\n",
8278 Srb->SrbExtension));
8279 KdPrint2((PRINT_PREFIX "** Ide: Command to device %d\n",
8280 Srb->TargetId));*/
8281
8282 SetCheckPoint(0x30);
8283 AtaReq = (PATA_REQ)(Srb->SrbExtension);
8284
8285 KdPrint2((PRINT_PREFIX "** Ide: Command &AtaReq %#x\n",
8286 &AtaReq));
8287 KdPrint2((PRINT_PREFIX "** Ide: Command AtaReq %#x\n",
8288 AtaReq));
8289 KdPrint2((PRINT_PREFIX "** --- **\n"));
8290
8291 lChannel = GET_CHANNEL(Srb);
8292 chan = &(deviceExtension->chan[lChannel]);
8293 //ldev = GET_LDEV(Srb);
8295 LunExt = chan->lun[DeviceNumber];
8296
8297 SetCheckPoint(0x40);
8300
8301 cdb = (PCDB)(Srb->Cdb);
8302
8303 if(CmdAction == CMD_ACTION_PREPARE) {
8304 switch (Srb->Cdb[0]) {
8306 if( cdb->SERVICE_ACTION16.ServiceAction==SCSIOP_SA_READ_CAPACITY16 ) {
8307 // ok
8308 } else {
8309 goto default_no_prep;
8310 }
8311#ifdef NAVO_TEST
8312 case SCSIOP_INQUIRY: // now it requires device access
8313#endif //NAVO_TEST
8315 case SCSIOP_READ:
8316 case SCSIOP_WRITE:
8317 case SCSIOP_READ12:
8318 case SCSIOP_WRITE12:
8319 case SCSIOP_READ16:
8320 case SCSIOP_WRITE16:
8322 // all right
8323 KdPrint2((PRINT_PREFIX "** Ide: Command continue prep\n"));
8324 SetCheckPoint(50);
8325 break;
8326 default:
8327default_no_prep:
8328 SetCheckPoint(0);
8329 KdPrint2((PRINT_PREFIX "** Ide: Command break prep\n"));
8330 return SRB_STATUS_BUSY;
8331 }
8332 }
8333
8334 SetCheckPoint(0x100 | Srb->Cdb[0]);
8335 switch (Srb->Cdb[0]) {
8336 case SCSIOP_INQUIRY:
8337
8339 "IdeSendCommand: SCSIOP_INQUIRY PATH:LUN:TID = %#x:%#x:%#x\n",
8340 Srb->PathId, Srb->Lun, Srb->TargetId));
8341 // Filter out wrong TIDs.
8342 if ((Srb->Lun != 0) ||
8343 (Srb->PathId >= deviceExtension->NumberChannels) ||
8344 (Srb->TargetId >= deviceExtension->NumberLuns)) {
8345
8347 "IdeSendCommand: SCSIOP_INQUIRY rejected\n"));
8348 // Indicate no device found at this address.
8350 break;
8351
8352 } else {
8353
8355 "IdeSendCommand: SCSIOP_INQUIRY ok\n"));
8356 PINQUIRYDATA inquiryData = (PINQUIRYDATA)(Srb->DataBuffer);
8357 PIDENTIFY_DATA2 identifyData = &(LunExt->IdentifyData);
8358
8359 if (!(chan->lun[DeviceNumber]->DeviceFlags & DFLAGS_DEVICE_PRESENT)) {
8360
8361 if(!CheckDevice(HwDeviceExtension, lChannel, DeviceNumber, FALSE)) {
8363 "IdeSendCommand: SCSIOP_INQUIRY rejected (2)\n"));
8364 // Indicate no device found at this address.
8365#ifndef NAVO_TEST
8367 break;
8368 }
8369 } else {
8370 if(!UniataAnybodyHome(HwDeviceExtension, lChannel, DeviceNumber)) {
8372 "IdeSendCommand: SCSIOP_INQUIRY device have gone\n"));
8373 // Indicate no device found at this address.
8375#endif //NAVO_TEST
8377 break;
8378 }
8379 }
8380
8381 // Zero INQUIRY data structure.
8383
8384 // Standard IDE interface only supports disks.
8385 inquiryData->DeviceType = DIRECT_ACCESS_DEVICE;
8386
8387 // Set the removable bit, if applicable.
8388 if (LunExt->DeviceFlags & DFLAGS_REMOVABLE_DRIVE) {
8390 "RemovableMedia\n"));
8391 inquiryData->RemovableMedia = 1;
8392 }
8393 // Set the Relative Addressing (LBA) bit, if applicable.
8394 if (LunExt->DeviceFlags & DFLAGS_LBA_ENABLED) {
8395 inquiryData->RelativeAddressing = 1;
8397 "RelativeAddressing\n"));
8398 }
8399 // Set the CommandQueue bit
8400 inquiryData->CommandQueue = 1;
8401
8402 // Fill in vendor identification fields.
8403#ifdef __REACTOS__
8404 FillDeviceIdentificationString(inquiryData, identifyData);
8405#else
8406 for (i = 0; i < 24; i += 2) {
8407 MOV_DW_SWP(inquiryData->DeviceIdentificationString[i], ((PUCHAR)identifyData->ModelNumber)[i]);
8408 }
8409#endif
8410/*
8411 // Initialize unused portion of product id.
8412 for (i = 0; i < 4; i++) {
8413 inquiryData->ProductId[12+i] = ' ';
8414 }
8415*/
8416 // Move firmware revision from IDENTIFY data to
8417 // product revision in INQUIRY data.
8418 for (i = 0; i < 4; i += 2) {
8419 MOV_DW_SWP(inquiryData->ProductRevisionLevel[i], ((PUCHAR)identifyData->FirmwareRevision)[i]);
8420 }
8421
8423 }
8424
8425 break;
8426
8427 case SCSIOP_REPORT_LUNS: {
8428
8429 ULONG alen;
8430 PREPORT_LUNS_INFO_HDR LunInfo;
8431
8433 "IdeSendCommand: SCSIOP_REPORT_LUNS PATH:LUN:TID = %#x:%#x:%#x\n",
8434 Srb->PathId, Srb->Lun, Srb->TargetId));
8435
8436 MOV_DD_SWP(alen, cdb->REPORT_LUNS.AllocationLength);
8437
8438 if(alen < 16) {
8439 goto invalid_cdb;
8440 }
8441 alen = 8;
8442
8443 LunInfo = (PREPORT_LUNS_INFO_HDR)(Srb->DataBuffer);
8444 RtlZeroMemory(LunInfo, 16);
8445
8446 MOV_DD_SWP( LunInfo->ListLength, alen );
8447 Srb->DataTransferLength = 16;
8449
8450 break; }
8451
8452 case SCSIOP_MODE_SENSE:
8453
8455 "IdeSendCommand: SCSIOP_MODE_SENSE PATH:LUN:TID = %#x:%#x:%#x\n",
8456 Srb->PathId, Srb->Lun, Srb->TargetId));
8457
8458 if(cdb->MODE_SENSE.PageCode == MODE_PAGE_POWER_CONDITION) {
8460
8461 KdPrint2((PRINT_PREFIX "MODE_PAGE_POWER_CONDITION\n"));
8463 if(cdb->MODE_SENSE.AllocationLength < sizeof(MODE_POWER_CONDITION_PAGE)) {
8465 } else {
8466 RtlZeroMemory(modeData, sizeof(MODE_POWER_CONDITION_PAGE));
8468#ifdef __REACTOS__
8470#else
8472#endif
8473 modeData->Byte3.Fields.Idle = LunExt->PowerState <= StartStop_Power_Idle;
8474 modeData->Byte3.Fields.Standby = LunExt->PowerState == StartStop_Power_Standby;
8477 }
8478 } else
8479 if(cdb->MODE_SENSE.PageCode == MODE_PAGE_CACHING) {
8480 PMODE_CACHING_PAGE modeData;
8481
8482 KdPrint2((PRINT_PREFIX "MODE_PAGE_CACHING\n"));
8483 modeData = (PMODE_CACHING_PAGE)(Srb->DataBuffer);
8484 if(cdb->MODE_SENSE.AllocationLength < sizeof(MODE_CACHING_PAGE)) {
8486 } else {
8487 RtlZeroMemory(modeData, sizeof(MODE_CACHING_PAGE));
8488 modeData->PageCode = MODE_PAGE_CACHING;
8489 modeData->PageLength = sizeof(MODE_CACHING_PAGE)-sizeof(MODE_PARAMETER_HEADER);
8490 modeData->ReadDisableCache = (LunExt->DeviceFlags & DFLAGS_RCACHE_ENABLED) ? 0 : 1;
8491 modeData->WriteCacheEnable = (LunExt->DeviceFlags & DFLAGS_WCACHE_ENABLED) ? 1 : 0;
8494 }
8495 } else
8497
8498 // This is used to determine if the media is write-protected.
8499 // Since IDE does not support mode sense then we will modify just the portion we need
8500 // so the higher level driver can determine if media is protected.
8501
8502 //SelectDrive(chan, DeviceNumber);
8503 //AtapiWritePort1(chan, IDX_IO1_o_Command,IDE_COMMAND_GET_MEDIA_STATUS);
8504 //statusByte = WaitOnBusy(chan);
8505 statusByte = AtaCommand(deviceExtension, DeviceNumber, lChannel, IDE_COMMAND_GET_MEDIA_STATUS, 0, 0, 0, 0, 0, ATA_WAIT_READY);
8506
8507 if (!(statusByte & IDE_STATUS_ERROR)) {
8508
8509 // no error occured return success, media is not protected
8514
8515 } else {
8516
8517 // error occured, handle it locally, clear interrupt
8518 errorByte = AtapiReadPort1(chan, IDX_IO1_i_Error);
8519
8520 GetBaseStatus(chan, statusByte);
8525
8526 if (errorByte & IDE_ERROR_DATA_ERROR) {
8527
8528 //media is write-protected, set bit in mode sense buffer
8530
8533 }
8534 }
8536 } else {
8538 }
8539 break;
8540
8542
8544 "IdeSendCommand: SCSIOP_TEST_UNIT_READY PATH:LUN:TID = %#x:%#x:%#x\n",
8545 Srb->PathId, Srb->Lun, Srb->TargetId));
8546 if (chan->lun[DeviceNumber]->DeviceFlags & DFLAGS_MEDIA_STATUS_ENABLED) {
8547
8548 // Select device 0 or 1.
8549 //SelectDrive(chan, DeviceNumber);
8550 //AtapiWritePort1(chan, IDX_IO1_o_Command,IDE_COMMAND_GET_MEDIA_STATUS);
8551 // Wait for busy. If media has not changed, return success
8552 //statusByte = WaitOnBusy(chan);
8553 statusByte = AtaCommand(deviceExtension, DeviceNumber, lChannel, IDE_COMMAND_GET_MEDIA_STATUS, 0, 0, 0, 0, 0, ATA_WAIT_READY);
8554
8555 if (!(statusByte & IDE_STATUS_ERROR)){
8560 } else {
8561 errorByte = AtapiReadPort1(chan, IDX_IO1_i_Error);
8562 if (errorByte == IDE_ERROR_DATA_ERROR){
8563
8564 // Special case: If current media is write-protected,
8565 // the 0xDA command will always fail since the write-protect bit
8566 // is sticky,so we can ignore this error
8567 GetBaseStatus(chan, statusByte);
8572
8573 } else {
8574
8575 // Request sense buffer to be build
8580 }
8581 }
8582 } else {
8584 }
8585
8586 break;
8587
8589
8591 "** IdeSendCommand: SCSIOP_READ_CAPACITY PATH:LUN:TID = %#x:%#x:%#x\n",
8592 Srb->PathId, Srb->Lun, Srb->TargetId));
8593 // Claim 512 byte blocks (big-endian).
8594 //((PREAD_CAPACITY_DATA)Srb->DataBuffer)->BytesPerBlock = 0x20000;
8595 i = DEV_BSIZE;
8597 MOV_DD_SWP( ((PREAD_CAPACITY_DATA)Srb->DataBuffer)->BytesPerBlock, i );
8598
8599 // Calculate last sector.
8600 if(!(i = (ULONG)LunExt->NumOfSectors)) {
8601 i = LunExt->IdentifyData.SectorsPerTrack *
8602 LunExt->IdentifyData.NumberOfHeads *
8604 }
8605 i--;
8606
8607 //((PREAD_CAPACITY_DATA)Srb->DataBuffer)->LogicalBlockAddress =
8608 // (((PUCHAR)&i)[0] << 24) | (((PUCHAR)&i)[1] << 16) |
8609 // (((PUCHAR)&i)[2] << 8) | ((PUCHAR)&i)[3];
8610
8611 MOV_DD_SWP( ((PREAD_CAPACITY_DATA)Srb->DataBuffer)->LogicalBlockAddress, i );
8612
8614 "** IDE disk %#x - #sectors %#x, #heads %#x, #cylinders %#x\n",
8615 Srb->TargetId,
8619
8620
8622 break;
8623
8625
8626 if( cdb->SERVICE_ACTION16.ServiceAction==SCSIOP_SA_READ_CAPACITY16 ) {
8628 "** IdeSendCommand: SCSIOP_READ_CAPACITY PATH:LUN:TID = %#x:%#x:%#x\n",
8629 Srb->PathId, Srb->Lun, Srb->TargetId));
8630 // Claim 512 byte blocks (big-endian).
8631 //((PREAD_CAPACITY_DATA)Srb->DataBuffer)->BytesPerBlock = 0x20000;
8632 i = DEV_BSIZE;
8634 MOV_DD_SWP( ((PREAD_CAPACITY16_DATA)Srb->DataBuffer)->BytesPerBlock, i );
8635
8636 // Calculate last sector.
8637 if(!(lba = LunExt->NumOfSectors)) {
8638 lba = LunExt->IdentifyData.SectorsPerTrack *
8639 LunExt->IdentifyData.NumberOfHeads *
8641 }
8642 lba--;
8643 MOV_QD_SWP( ((PREAD_CAPACITY16_DATA)Srb->DataBuffer)->LogicalBlockAddress, lba );
8644
8646 "** IDE disk %#x - #sectors %#x, #heads %#x, #cylinders %#x (16)\n",
8647 Srb->TargetId,
8651
8653 } else {
8654 goto default_abort;
8655 }
8656 break;
8657
8658 case SCSIOP_VERIFY:
8659 case SCSIOP_VERIFY12:
8660 case SCSIOP_VERIFY16:
8661
8663 "IdeSendCommand: SCSIOP_VERIFY PATH:LUN:TID = %#x:%#x:%#x\n",
8664 Srb->PathId, Srb->Lun, Srb->TargetId));
8665 status = IdeVerify(HwDeviceExtension,Srb);
8666
8667 break;
8668
8669 case SCSIOP_READ:
8670 case SCSIOP_WRITE:
8671 case SCSIOP_READ12:
8672 case SCSIOP_WRITE12:
8673 case SCSIOP_READ16:
8674 case SCSIOP_WRITE16:
8675
8677 "IdeSendCommand: SCSIOP_%s PATH:LUN:TID = %#x:%#x:%#x\n",
8678 (Srb->Cdb[0] == SCSIOP_WRITE) ? "WRITE" : "READ",
8679 Srb->PathId, Srb->Lun, Srb->TargetId));
8680 AtaReq->Flags &= ~REQ_FLAG_RW_MASK;
8681 AtaReq->Flags |= (Srb->Cdb[0] == SCSIOP_WRITE ||
8682 Srb->Cdb[0] == SCSIOP_WRITE12 ||
8684 status = IdeReadWrite(HwDeviceExtension,
8685 Srb, CmdAction);
8686 break;
8687
8689
8691 "IdeSendCommand: SCSIOP_START_STOP_UNIT immed %d PATH:LUN:TID = %#x:%#x:%#x\n",
8692 cdb->START_STOP.Immediate, Srb->PathId, Srb->Lun, Srb->TargetId));
8693 //Determine what type of operation we should perform
8694
8695 command = 0;
8696
8697 if(cdb->START_STOP.FL ||
8698 cdb->START_STOP.FormatLayerNumber ||
8699 cdb->START_STOP.Reserved2 ||
8700 cdb->START_STOP.Reserved2_2 ||
8701 cdb->START_STOP.Reserved3 ||
8702 FALSE) {
8703 goto invalid_cdb;
8704 }
8705
8706 if (cdb->START_STOP.PowerConditions) {
8707 KdPrint2((PRINT_PREFIX "START_STOP Power %d\n", cdb->START_STOP.PowerConditions));
8708 switch(cdb->START_STOP.PowerConditions) {
8711 break;
8714 break;
8716 // TODO: we should save power state in order to know
8717 // that RESET sould be issued to revert device into
8718 // operable state
8719
8721 break;
8722 default:
8723 goto invalid_cdb;
8724 }
8725 LunExt->PowerState = cdb->START_STOP.PowerConditions;
8726 } else
8727 if (cdb->START_STOP.LoadEject == 1) {
8728 KdPrint2((PRINT_PREFIX "START_STOP eject\n"));
8729 // Eject media,
8730 // first select device 0 or 1.
8731 //SelectDrive(chan, DeviceNumber);
8732 //AtapiWritePort1(chan, IDX_IO1_o_Command,IDE_COMMAND_MEDIA_EJECT);
8734 } else
8735 if (cdb->START_STOP.Start == 0) {
8736 KdPrint2((PRINT_PREFIX "START_STOP standby\n"));
8738 } else {
8739 // TODO: we may need to perform hard reset (after sleep) or
8740 // issue IDE_COMMAND_IDLE_IMMED in order to activate device
8741 KdPrint2((PRINT_PREFIX "START_STOP activate\n"));
8742
8743 if(LunExt->PowerState == StartStop_Power_Sleep) {
8744 UniataUserDeviceReset(deviceExtension, LunExt, lChannel);
8746 break;
8747 } else
8748 if(LunExt->PowerState > StartStop_Power_Idle) {
8749 KdPrint2((PRINT_PREFIX " issue IDLE\n"));
8751 } else {
8752 KdPrint2((PRINT_PREFIX " do nothing\n"));
8754 break;
8755 }
8756 }
8757 if(command) {
8758 statusByte = WaitOnBaseBusy(chan);
8759 statusByte = AtaCommand(deviceExtension, DeviceNumber, lChannel, command, 0, 0, 0, 0, 0,
8760 cdb->START_STOP.Immediate ? ATA_IMMEDIATE : ATA_WAIT_READY);
8762 //UniataExpectChannelInterrupt(chan, TRUE); // device may interrupt
8763
8764 } else {
8765invalid_cdb:
8766 KdPrint2((PRINT_PREFIX "START_STOP invalid\n"));
8767 if (Srb->SenseInfoBuffer) {
8768
8770
8771 senseBuffer->ErrorCode = 0x70;
8772 senseBuffer->Valid = 1;
8773 senseBuffer->AdditionalSenseLength = 0xb;
8774 senseBuffer->SenseKey = SCSI_SENSE_ILLEGAL_REQUEST;
8776 senseBuffer->AdditionalSenseCodeQualifier = 0;
8777
8780 }
8782 }
8783 break;
8784
8786
8787 cdb = (PCDB)Srb->Cdb;
8788
8789 if(LunExt->IdentifyData.Removable) {
8790 statusByte = WaitOnBaseBusy(chan);
8791
8792 //SelectDrive(chan, DeviceNumber);
8793 if (cdb->MEDIA_REMOVAL.Prevent == TRUE) {
8794 //AtapiWritePort1(chan, IDX_IO1_o_Command,IDE_COMMAND_DOOR_LOCK);
8795 statusByte = AtaCommand(deviceExtension, DeviceNumber, lChannel, IDE_COMMAND_DOOR_LOCK, 0, 0, 0, 0, 0, ATA_IMMEDIATE);
8796 } else {
8797 //AtapiWritePort1(chan, IDX_IO1_o_Command,IDE_COMMAND_DOOR_UNLOCK);
8798 statusByte = AtaCommand(deviceExtension, DeviceNumber, lChannel, IDE_COMMAND_DOOR_UNLOCK, 0, 0, 0, 0, 0, ATA_IMMEDIATE);
8799 }
8801 } else {
8803 }
8804 break;
8805
8806#if 0
8807 // Note: I don't implement this, because NTFS driver too often issues this command
8808 // It causes awful performance degrade. However, if somebody wants, I will implement
8809 // SCSIOP_FLUSH_BUFFER/SCSIOP_SYNCHRONIZE_CACHE optionally.
8812
8816// status = SRB_STATUS_PENDING;
8817 statusByte = WaitOnBusy(chan);
8818 break;
8819#endif
8820
8822 // this function makes sense buffers to report the results
8823 // of the original GET_MEDIA_STATUS command
8824
8826 "IdeSendCommand: SCSIOP_REQUEST_SENSE PATH:LUN:TID = %#x:%#x:%#x\n",
8827 Srb->PathId, Srb->Lun, Srb->TargetId));
8829 status = IdeBuildSenseBuffer(HwDeviceExtension,Srb);
8830 break;
8831 }
8833 break;
8834
8835 // ATA_PASSTHORUGH
8837 {
8839 BOOLEAN use_dma = FALSE;
8840 ULONG to_lim;
8841
8842 regs = (PIDEREGS_EX) &(Srb->Cdb[2]);
8843
8844 if(chan->DeviceExtension->HwFlags & UNIATA_SATA) {
8845 //lChannel = Srb->TargetId >> 1;
8846 } else {
8848 regs->bDriveHeadReg &= 0x0f;
8849 regs->bDriveHeadReg |= (UCHAR) (((DeviceNumber & 0x1) << 4) | 0xA0);
8850 }
8851
8852 if((regs->bOpFlags & 1) == 0) { // execute ATA command
8853
8855 "IdeSendCommand: SCSIOP_ATA_PASSTHROUGH (exec) PATH:LUN:TID = %#x:%#x:%#x\n",
8856 Srb->PathId, Srb->Lun, Srb->TargetId));
8857
8859 to_lim = Srb->TimeOutValue;
8860 } else {
8861 if(Srb->TimeOutValue <= 2) {
8862 to_lim = Srb->TimeOutValue*900;
8863 } else {
8864 to_lim = (Srb->TimeOutValue*999) - 500;
8865 }
8866 }
8867
8868 AtapiDisableInterrupts(deviceExtension, lChannel);
8869
8870 if(chan->DeviceExtension->HwFlags & UNIATA_AHCI) {
8871 // AHCI
8872 statusByte = UniataAhciSendPIOCommandDirect(
8873 deviceExtension,
8874 lChannel,
8876 Srb,
8877 regs,
8879 to_lim
8880 );
8881 if(statusByte == IDE_STATUS_WRONG) {
8882 goto passthrough_err;
8883 }
8884 if(statusByte & (IDE_STATUS_BUSY | IDE_STATUS_ERROR)) {
8886 goto passthrough_err;
8887 }
8888 goto passthrough_done;
8889 }
8890
8891 // SATA/PATA
8892 if((AtaCommandFlags[regs->bCommandReg] & ATA_CMD_FLAG_DMA) || (regs->bOpFlags & UNIATA_SPTI_EX_USE_DMA)) {
8893 if((chan->lun[DeviceNumber]->LimitedTransferMode >= ATA_DMA)) {
8894 use_dma = TRUE;
8895 // this will set REQ_FLAG_DMA_OPERATION in AtaReq->Flags on success
8896 if(!AtapiDmaSetup(HwDeviceExtension, DeviceNumber, lChannel, Srb,
8897 (PUCHAR)(Srb->DataBuffer),
8898 ((Srb->DataTransferLength + DEV_BSIZE-1) & ~(DEV_BSIZE-1)))) {
8899 use_dma = FALSE;
8900 }
8901 }
8902 }
8903
8904 AtapiWritePort1(chan, IDX_IO1_o_DriveSelect, regs->bDriveHeadReg);
8906 if(use_dma) {
8907 AtapiDmaDBPreSync(HwDeviceExtension, chan, Srb);
8908 }
8909
8910 if((regs->bOpFlags & ATA_FLAGS_48BIT_COMMAND) == 0) { // execute ATA command
8911 AtapiWritePort1(chan, IDX_IO1_o_Feature, regs->bFeaturesReg);
8912 AtapiWritePort1(chan, IDX_IO1_o_BlockCount, regs->bSectorCountReg);
8913 AtapiWritePort1(chan, IDX_IO1_o_BlockNumber, regs->bSectorNumberReg);
8914 AtapiWritePort1(chan, IDX_IO1_o_CylinderLow, regs->bCylLowReg);
8915 AtapiWritePort1(chan, IDX_IO1_o_CylinderHigh, regs->bCylHighReg);
8916 } else {
8917 AtapiWritePort1(chan, IDX_IO1_o_Feature, regs->bFeaturesRegH);
8918 AtapiWritePort1(chan, IDX_IO1_o_Feature, regs->bFeaturesReg);
8919 AtapiWritePort1(chan, IDX_IO1_o_BlockCount, regs->bSectorCountRegH);
8920 AtapiWritePort1(chan, IDX_IO1_o_BlockCount, regs->bSectorCountReg);
8921 AtapiWritePort1(chan, IDX_IO1_o_BlockNumber, regs->bSectorNumberRegH);
8922 AtapiWritePort1(chan, IDX_IO1_o_BlockNumber, regs->bSectorNumberReg);
8923 AtapiWritePort1(chan, IDX_IO1_o_CylinderLow, regs->bCylLowRegH);
8924 AtapiWritePort1(chan, IDX_IO1_o_CylinderLow, regs->bCylLowReg);
8925 AtapiWritePort1(chan, IDX_IO1_o_CylinderHigh, regs->bCylHighRegH);
8926 AtapiWritePort1(chan, IDX_IO1_o_CylinderHigh, regs->bCylHighReg);
8927 }
8928 AtapiWritePort1(chan, IDX_IO1_o_Command, regs->bCommandReg);
8929
8930 if(use_dma) {
8931 GetBaseStatus(chan, statusByte);
8932 if(statusByte & IDE_STATUS_ERROR) {
8933 goto passthrough_err;
8934 }
8935 AtapiDmaStart(HwDeviceExtension, DeviceNumber, lChannel, Srb);
8936 }
8937
8938 ScsiPortStallExecution(1); // wait for busy to be set
8939
8940 for(i=0; i<to_lim;i+=2) { // 2 msec from WaitOnBaseBusy()
8941 statusByte = WaitOnBaseBusy(chan); // wait for busy to be clear, up to 2 msec
8942 GetBaseStatus(chan, statusByte);
8943 if(statusByte & IDE_STATUS_ERROR) {
8944 break;
8945 }
8946 if(!(statusByte & IDE_STATUS_BUSY)) {
8947 break;
8948 }
8949 }
8950 if(i >= to_lim) {
8951 //if(regs->bOpFlags & UNIATA_SPTI_EX_FREEZE_TO) {
8952 //}
8953 AtapiResetController__(HwDeviceExtension, lChannel, RESET_COMPLETE_NONE);
8954 goto passthrough_err;
8955 }
8956
8957 if(use_dma) {
8958 AtapiCheckInterrupt__(deviceExtension, (UCHAR)lChannel);
8959 }
8960 AtapiDmaDone(deviceExtension, DeviceNumber, lChannel, NULL);
8961 GetBaseStatus(chan, statusByte);
8962
8963 if(statusByte & (IDE_STATUS_BUSY | IDE_STATUS_ERROR)) {
8964 AtapiSuckPort2(chan);
8965passthrough_err:
8966 if (Srb->SenseInfoBuffer) {
8967
8969
8970 senseBuffer->ErrorCode = 0x70;
8971 senseBuffer->Valid = 1;
8972 senseBuffer->AdditionalSenseLength = 0xb;
8973 senseBuffer->SenseKey = SCSI_SENSE_ABORTED_COMMAND;
8974 senseBuffer->AdditionalSenseCode = 0;
8975 senseBuffer->AdditionalSenseCodeQualifier = 0;
8976
8979 }
8981 } else {
8982
8983 if(!use_dma) {
8984 if (statusByte & IDE_STATUS_DRQ) {
8986 ReadBuffer(chan,
8989 0);
8990 } else if (Srb->SrbFlags & SRB_FLAGS_DATA_OUT) {
8991 WriteBuffer(chan,
8994 0);
8995 }
8996 }
8997 }
8999 }
9000passthrough_done:;
9001 AtapiEnableInterrupts(deviceExtension, lChannel);
9002
9003 } else { // read task register
9004
9005 BOOLEAN use48;
9007
9009 "IdeSendCommand: SCSIOP_ATA_PASSTHROUGH (snap) PATH:LUN:TID = %#x:%#x:%#x\n",
9010 Srb->PathId, Srb->Lun, Srb->TargetId));
9011
9012 if((Srb->DataTransferLength >= sizeof(IDEREGS_EX)) &&
9013 (regs->bOpFlags & ATA_FLAGS_48BIT_COMMAND)) {
9014 use48 = TRUE;
9015 } else
9016 if(Srb->DataTransferLength >= sizeof(IDEREGS)) {
9017 use48 = FALSE;
9018 } else {
9019 KdPrint2((PRINT_PREFIX " buffer too small \n"));
9021 break;
9022 }
9023 RtlZeroMemory(regs, use48 ? sizeof(IDEREGS_EX) : sizeof(IDEREGS));
9024 regs->bOpFlags = use48 ? ATA_FLAGS_48BIT_COMMAND : 0;
9025 UniataSnapAtaRegs(chan, 0, regs);
9026
9028 }
9029 break;
9030 }
9031
9032 default:
9033default_abort:
9035 "IdeSendCommand: Unsupported command %#x\n",
9036 Srb->Cdb[0]));
9037
9039
9040 } // end switch
9041
9042 if(status == SRB_STATUS_PENDING) {
9043 KdPrint2((PRINT_PREFIX "IdeSendCommand: SRB_STATUS_PENDING\n"));
9044 if(CmdAction & CMD_ACTION_EXEC) {
9045 KdPrint2((PRINT_PREFIX "IdeSendCommand: REQ_STATE_EXPECTING_INTR\n"));
9047 }
9048 } else {
9049 KdPrint2((PRINT_PREFIX "IdeSendCommand: REQ_STATE_TRANSFER_COMPLETE\n"));
9051 }
9052
9053 return status;
9054
9055} // end IdeSendCommand()
9056
9057
9058/*++
9059
9060Routine Description:
9061 Enables disables media status notification
9062
9063Arguments:
9064 HwDeviceExtension - ATAPI driver storage.
9065
9066--*/
9067VOID
9068NTAPI
9070 BOOLEAN EnableMSN,
9071 IN PVOID HwDeviceExtension,
9072 IN ULONG lChannel,
9074 )
9075{
9076 PHW_DEVICE_EXTENSION deviceExtension = (PHW_DEVICE_EXTENSION)HwDeviceExtension;
9077 PHW_CHANNEL chan;
9078 UCHAR statusByte,errorByte;
9079
9080 chan = &(deviceExtension->chan[lChannel]);
9082
9083 if (EnableMSN == TRUE){
9084
9085 // If supported enable Media Status Notification support
9086 if ((chan->lun[DeviceNumber]->DeviceFlags & DFLAGS_REMOVABLE_DRIVE)) {
9087
9088 // enable
9089 statusByte = AtaCommand(deviceExtension, DeviceNumber, lChannel,
9090 IDE_COMMAND_SET_FEATURES, 0, 0, 0,
9092
9093 if (statusByte & IDE_STATUS_ERROR) {
9094 // Read the error register.
9095 errorByte = AtapiReadPort1(chan, IDX_IO1_i_Error);
9096
9098 "IdeMediaStatus: Error enabling media status. Status %#x, error byte %#x\n",
9099 statusByte,
9100 errorByte));
9101 } else {
9102 chan->lun[DeviceNumber]->DeviceFlags |= DFLAGS_MEDIA_STATUS_ENABLED;
9103 KdPrint2((PRINT_PREFIX "IdeMediaStatus: Media Status Notification Supported\n"));
9104 chan->ReturningMediaStatus = 0;
9105
9106 }
9107
9108 }
9109 } else { // end if EnableMSN == TRUE
9110
9111 // disable if previously enabled
9112 if ((chan->lun[DeviceNumber]->DeviceFlags & DFLAGS_MEDIA_STATUS_ENABLED)) {
9113
9114 statusByte = AtaCommand(deviceExtension, DeviceNumber, lChannel,
9115 IDE_COMMAND_SET_FEATURES, 0, 0, 0,
9117 chan->lun[DeviceNumber]->DeviceFlags &= ~DFLAGS_MEDIA_STATUS_ENABLED;
9118 }
9119
9120
9121 }
9122
9123
9124} // end IdeMediaStatus()
9125
9126
9127/*++
9128
9129Routine Description:
9130
9131 Builts an artificial sense buffer to report the results of a GET_MEDIA_STATUS
9132 command. This function is invoked to satisfy the SCSIOP_REQUEST_SENSE.
9133Arguments:
9134
9135 HwDeviceExtension - ATAPI driver storage.
9136 Srb - System request block.
9137
9138Return Value:
9139
9140 SRB status (ALWAYS SUCCESS).
9141
9142--*/
9143ULONG
9144NTAPI
9146 IN PVOID HwDeviceExtension,
9148 )
9149{
9150 PHW_DEVICE_EXTENSION deviceExtension = (PHW_DEVICE_EXTENSION)HwDeviceExtension;
9151// ULONG status;
9152 PSENSE_DATA senseBuffer = (PSENSE_DATA)Srb->DataBuffer;
9153 UCHAR ReturningMediaStatus = deviceExtension->chan[GET_CHANNEL(Srb)].ReturningMediaStatus;
9154
9155 if (senseBuffer){
9156
9157 if(ReturningMediaStatus & IDE_ERROR_MEDIA_CHANGE) {
9158
9159 senseBuffer->ErrorCode = 0x70;
9160 senseBuffer->Valid = 1;
9161 senseBuffer->AdditionalSenseLength = 0xb;
9162 senseBuffer->SenseKey = SCSI_SENSE_UNIT_ATTENTION;
9164 senseBuffer->AdditionalSenseCodeQualifier = 0;
9165 } else if(ReturningMediaStatus & IDE_ERROR_MEDIA_CHANGE_REQ) {
9166
9167 senseBuffer->ErrorCode = 0x70;
9168 senseBuffer->Valid = 1;
9169 senseBuffer->AdditionalSenseLength = 0xb;
9170 senseBuffer->SenseKey = SCSI_SENSE_UNIT_ATTENTION;
9172 senseBuffer->AdditionalSenseCodeQualifier = 0;
9173 } else if(ReturningMediaStatus & IDE_ERROR_END_OF_MEDIA) {
9174
9175 senseBuffer->ErrorCode = 0x70;
9176 senseBuffer->Valid = 1;
9177 senseBuffer->AdditionalSenseLength = 0xb;
9178 senseBuffer->SenseKey = SCSI_SENSE_NOT_READY;
9180 senseBuffer->AdditionalSenseCodeQualifier = 0;
9181 } else if(ReturningMediaStatus & IDE_ERROR_DATA_ERROR) {
9182
9183 senseBuffer->ErrorCode = 0x70;
9184 senseBuffer->Valid = 1;
9185 senseBuffer->AdditionalSenseLength = 0xb;
9186 senseBuffer->SenseKey = SCSI_SENSE_DATA_PROTECT;
9187 senseBuffer->AdditionalSenseCode = 0;
9188 senseBuffer->AdditionalSenseCodeQualifier = 0;
9189 }
9190 return SRB_STATUS_SUCCESS;
9191 }
9192 return SRB_STATUS_ERROR;
9193
9194}// End of IdeBuildSenseBuffer
9195
9196VOID
9197NTAPI
9199 PHW_DEVICE_EXTENSION deviceExtension,
9200 PHW_LU_EXTENSION LunExt,
9201 ULONG lChannel
9202 )
9203{
9204 ULONG i;
9205 AtapiDisableInterrupts(deviceExtension, lChannel);
9206 if ((LunExt->DeviceFlags & DFLAGS_ATAPI_DEVICE) &&
9207 (LunExt->PowerState != StartStop_Power_Sleep)) {
9208 KdPrint2((PRINT_PREFIX "UniataUserDeviceReset: Reset ATAPI\n"));
9209 AtapiSoftReset(&(deviceExtension->chan[lChannel]), LunExt->Lun);
9210 } else {
9211 KdPrint2((PRINT_PREFIX "UniataUserDeviceReset: Reset IDE -> reset entire channel\n"));
9212 AtapiResetController__(deviceExtension, lChannel, RESET_COMPLETE_NONE);
9213 for(i=0; i<deviceExtension->NumberLuns; i++) {
9214 deviceExtension->chan[lChannel].lun[i]->DeviceFlags |= DFLAGS_REINIT_DMA;
9215 }
9216 }
9217 LunExt->DeviceFlags |= DFLAGS_REINIT_DMA; // force PIO/DMA reinit
9218 AtapiEnableInterrupts(deviceExtension, lChannel);
9219 return;
9220} // end UniataUserDeviceReset()
9221
9222BOOLEAN
9223NTAPI
9225 PHW_DEVICE_EXTENSION deviceExtension,
9226 PHW_CHANNEL chan,
9228 )
9229{
9230 BOOLEAN PostReq = FALSE;
9231 if(TopLevel) {
9232 KdPrint3((PRINT_PREFIX "UniataNeedQueueing: TopLevel, qd=%x\n", chan->queue_depth));
9233 if(chan->queue_depth > 0) {
9234#if 0
9235 if(atapiDev &&
9236 ((Srb->Cdb[0] == SCSIOP_TEST_UNIT_READY)/* ||
9237 (Srb->Cdb[0] == SCSIOP_REQUEST_SENSE)*/) ) {
9238 KdPrint2((PRINT_PREFIX "spec: SCSIOP_TEST_UNIT_READY\n"));
9239 //PostReq = FALSE;
9241 goto skip_exec;
9242 } else {
9243 PostReq = TRUE;
9244 }
9245#else
9246 PostReq = TRUE;
9247#endif
9248 } else
9249 if(deviceExtension->simplexOnly && deviceExtension->queue_depth > 0) {
9250 PostReq = TRUE;
9251 }
9252 } else {
9253 KdPrint3((PRINT_PREFIX "UniataNeedQueueing: qd=%x\n", chan->queue_depth));
9254 }
9255 return PostReq;
9256} // end UniataNeedQueueing()
9257
9258/*++
9259
9260Routine Description:
9261
9262 This routine is called from the SCSI port driver synchronized
9263 with the kernel to start an IO request.
9264 ->HwStartIo
9265
9266Arguments:
9267
9268 HwDeviceExtension - HBA miniport driver's adapter data storage
9269 Srb - IO request packet
9270
9271Return Value:
9272
9273 TRUE
9274
9275--*/
9276BOOLEAN
9277NTAPI
9279 IN PVOID HwDeviceExtension,
9281 )
9282{
9283 return AtapiStartIo__(HwDeviceExtension, Srb, TRUE);
9284} // end AtapiStartIo()
9285
9286BOOLEAN
9287NTAPI
9289 IN PVOID HwDeviceExtension,
9292 )
9293{
9294 PHW_DEVICE_EXTENSION deviceExtension = (PHW_DEVICE_EXTENSION)HwDeviceExtension;
9295 UCHAR lChannel;
9296 PHW_CHANNEL chan;
9297 PHW_LU_EXTENSION LunExt;
9298 ULONG status;
9299 //ULONG ldev;
9301 UCHAR PathId;
9303 UCHAR Lun;
9304 PATA_REQ AtaReq;
9305 PSCSI_REQUEST_BLOCK tmpSrb;
9306 BOOLEAN PostReq = FALSE;
9307 BOOLEAN atapiDev;
9308 BOOLEAN commPort = FALSE;
9309
9310 // deviceExtension->Isr2DevObj must always be NULL for non-PCI
9311 if(deviceExtension->Isr2DevObj && !BMList[deviceExtension->DevIndex].Isr2Enable) {
9312 KdPrint2((PRINT_PREFIX "Isr2Enable -> 1\n"));
9313 BMList[deviceExtension->DevIndex].Isr2Enable = TRUE;
9314 }
9315// deviceExtension->QueueNewIrql = max(deviceExtension->QueueNewIrql, KeGetCurrentIrql());
9316
9317/* KeBugCheckEx(0xc000000e,
9318 (Srb->PathId<<16) | (Srb->TargetId<<8) | (Srb->Lun),
9319 Srb->Function,
9320 TopLevel, 0x80000001);
9321*/
9322 if(TopLevel && Srb && Srb->SrbExtension) {
9323 KdPrint2((PRINT_PREFIX "TopLevel\n"));
9324 //RtlZeroMemory(Srb->SrbExtension, sizeof(ATA_REQ));
9326 }
9327
9328 do { // fetch all queued commands for the channel (if valid)
9329
9330 lChannel = GET_CHANNEL(Srb);
9331 //ldev = GET_LDEV(Srb);
9332 chan = NULL;
9333 LunExt = NULL;
9335 commPort = FALSE;
9336
9337 //ASSERT(deviceExtension);
9338 //ASSERT(chan);
9339
9341 "** AtapiStartIo: Function %#x, PATH:LUN:TID = %#x:%#x:%#x\n",
9343 KdPrint2((PRINT_PREFIX " DeviceID+VendorID/Rev %#x/%#x\n", deviceExtension->DevID, deviceExtension->RevID));
9344
9345 if(lChannel == deviceExtension->NumberChannels &&
9346 !Srb->Lun && !Srb->TargetId &&
9349 ) {
9350 // This is our virtual device
9352 "AtapiStartIo: Communication port\n"));
9354
9355 if(Srb->DataTransferLength < sizeof(PINQUIRYDATA)) {
9356 KdPrint2((PRINT_PREFIX "AtapiStartIo: Buffer too small: %#x < %#x\n", Srb->DataTransferLength,
9357 sizeof(PINQUIRYDATA) ));
9358wrong_buffer_size:
9360 goto complete_req;
9361 }
9362
9363 PINQUIRYDATA inquiryData = (PINQUIRYDATA)(Srb->DataBuffer);
9364
9366 " INQUIRY\n"));
9367 // Zero INQUIRY data structure.
9369
9370 inquiryData->DeviceType = COMMUNICATION_DEVICE;
9371
9372 // Fill in vendor identification fields.
9373 RtlCopyMemory(&inquiryData->VendorId, &uniata_comm_name, 28);
9374
9376 goto complete_req;
9377 }
9378 commPort = TRUE;
9379 /* Pass IOCTL request down */
9380 } else
9381 if(lChannel >= deviceExtension->NumberChannels ||
9382 Srb->TargetId /*DeviceNumber*/ >= deviceExtension->NumberLuns ||
9383 Srb->Lun) {
9384
9385 if(lChannel >= deviceExtension->NumberChannels) {
9386 chan = NULL;
9387 }
9388
9389reject_srb:
9390 //if(!CheckDevice(HwDeviceExtension, lChannel, DeviceNumber, FALSE)) {
9392 "AtapiStartIo: SRB rejected\n"));
9393 // Indicate no device found at this address.
9394 KdPrint2((PRINT_PREFIX "SRB_STATUS_SELECTION_TIMEOUT\n"));
9396 goto complete_req;
9397 //}
9398 } else
9399 if((deviceExtension->HwFlags & UNIATA_AHCI) &&
9400 !UniataAhciChanImplemented(deviceExtension, lChannel)) {
9401 chan = NULL;
9402 }
9403
9404 if(!commPort) {
9405 chan = &(deviceExtension->chan[lChannel]);
9406 LunExt = chan->lun[DeviceNumber];
9407 if(!LunExt) {
9408 goto reject_srb;
9409 }
9410 atapiDev = (LunExt->DeviceFlags & DFLAGS_ATAPI_DEVICE) ? TRUE : FALSE;
9411 } else {
9412 atapiDev = FALSE;
9413 }
9414
9415#ifdef _DEBUG
9416 if(!commPort && !LunExt) {
9417#if 0
9418 PrintNtConsole("de = %#x, chan = %#x , dev %#x, nchan %#x\n",
9419 deviceExtension,
9420 chan, DeviceNumber,
9421 deviceExtension->NumberChannels);
9422 PrintNtConsole("lchan = %#x, cdev %#x, lun0 %#x\n",
9423 lChannel, GET_CDEV(Srb), deviceExtension->chan[0].lun[0]);
9424 PrintNtConsole("Function %#x, PATH:LUN:TID = %#x:%#x:%#x\n",
9426#endif //0
9427/*
9428 int i;
9429 for(i=0; i<1000; i++) {
9430 AtapiStallExecution(3*1000);
9431 }
9432*/
9433 goto reject_srb;
9434 }
9435#endif //_DEBUG
9436
9437 // Determine which function.
9438 switch (Srb->Function) {
9439
9441
9442 if(!LunExt || !(LunExt->DeviceFlags & DFLAGS_DEVICE_PRESENT)) {
9443 if(Srb->Cdb[0] == SCSIOP_ATA_PASSTHROUGH) {
9444 // let passthrough go
9445 } else
9446 if(Srb->Cdb[0] == SCSIOP_INQUIRY) {
9447 // let INQUIRY go
9448 } else {
9449
9450 //if(!CheckDevice(HwDeviceExtension, lChannel, DeviceNumber, FALSE)) {
9452 "AtapiStartIo: EXECUTE_SCSI rejected (2)\n"));
9453 // Indicate no device found at this address.
9454 KdPrint2((PRINT_PREFIX "SRB_STATUS_SELECTION_TIMEOUT\n"));
9456 break;
9457 //}
9458 }
9459 } else {
9461 " SRB %#x, CDB %#x, AtaReq %#x, SCmd %#x\n", Srb, &(Srb->Cdb), Srb->SrbExtension, Srb->Cdb[0]));
9462 }
9463/*
9464 __try {
9465 if(Srb->DataTransferLength) {
9466 UCHAR a;
9467 a = ((PUCHAR)(Srb->DataBuffer))[0];
9468 g_foo += a;
9469 }
9470 } __except(EXCEPTION_EXECUTE_HANDLER) {
9471 KdPrint3((PRINT_PREFIX
9472 "AtapiStartIo: Bad data buffer -> EXECUTE_SCSI rejected\n"));
9473 // Indicate no device found at this address.
9474 KdPrint3((PRINT_PREFIX "SRB_STATUS_ERROR\n"));
9475 status = SRB_STATUS_ERROR;
9476 KdPrint2((PRINT_PREFIX " *** Exception...\n"));
9477 ASSERT(FALSE);
9478 break;
9479 }
9480*/
9481 PostReq = UniataNeedQueueing(deviceExtension, chan, TopLevel);
9482
9483 if(PostReq) {
9484
9485 KdPrint3((PRINT_PREFIX "Non-empty queue\n"));
9486 if (atapiDev &&
9487 (Srb->Cdb[0] != SCSIOP_ATA_PASSTHROUGH)) {
9488 KdPrint3((PRINT_PREFIX "Try ATAPI prepare\n"));
9489
9490 status = AtapiSendCommand(HwDeviceExtension, Srb, CMD_ACTION_PREPARE);
9491 } else {
9492 KdPrint2((PRINT_PREFIX "Try IDE prepare\n"));
9493 status = IdeSendCommand(HwDeviceExtension, Srb, CMD_ACTION_PREPARE);
9494 }
9495 /*KeBugCheckEx(0xc000000e,
9496 (Srb->PathId<<16) | (Srb->TargetId<<8) | (Srb->Lun),
9497 Srb->Function,
9498 status, 0x80000001);*/
9499 if(status == SRB_STATUS_BUSY)
9501 // Insert requests AFTER they have been initialized on
9502 // CMD_ACTION_PREPARE stage
9503 // we should not check TopLevel here (it is always TRUE)
9504 //ASSERT(chan->lun[GET_CDEV(Srb)]);
9505 UniataQueueRequest(chan, Srb);
9506
9507 KdPrint2((PRINT_PREFIX "AtapiStartIo: Already have %d request(s)!\n", chan->queue_depth));
9508
9509 } else {
9510
9511 // Send command to device.
9512 KdPrint2((PRINT_PREFIX "Send to device %x\n", Srb->Cdb[0]));
9513 if(TopLevel) {
9514 KdPrint2((PRINT_PREFIX "TopLevel (2), srb %#x\n", Srb));
9515 AtaReq = (PATA_REQ)(Srb->SrbExtension);
9516 KdPrint2((PRINT_PREFIX "TopLevel (3), AtaReq %#x\n", AtaReq));
9517 //ASSERT(!AtaReq->Flags);
9518 //ASSERT(chan->lun[GET_CDEV(Srb)]);
9519 UniataQueueRequest(chan, Srb);
9520// AtaReq = (PATA_REQ)(Srb->SrbExtension);
9521 //ASSERT(!AtaReq->Flags);
9522 AtaReq->ReqState = REQ_STATE_QUEUED;
9523 //ASSERT(!AtaReq->Flags);
9524 }
9525
9526#ifndef NAVO_TEST
9527 if(!LunExt || !(LunExt->DeviceFlags & DFLAGS_DEVICE_PRESENT)) {
9528 if(!LunExt) {
9529 goto reject_srb;
9530 }
9531 if(Srb->Cdb[0] == SCSIOP_INQUIRY) {
9532 if(UniataAnybodyHome(deviceExtension, chan->lChannel, DeviceNumber)) {
9533 if(!CheckDevice(HwDeviceExtension, chan->lChannel, DeviceNumber, TRUE)) {
9534 goto reject_srb;
9535 }
9536 }
9537 if(!(LunExt->DeviceFlags & DFLAGS_DEVICE_PRESENT)) {
9538 goto reject_srb;
9539 }
9540 } else
9541 if(Srb->Cdb[0] == SCSIOP_ATA_PASSTHROUGH) {
9542 // allow
9543 } else {
9544 goto reject_srb;
9545 }
9546 }
9547#endif //NAVO_TEST
9548
9549 if(atapiDev &&
9550 (Srb->Cdb[0] != SCSIOP_ATA_PASSTHROUGH)/* &&
9551 (Srb->Cdb[0] != SCSIOP_REPORT_LUNS)*/) {
9552 KdPrint3((PRINT_PREFIX "Try ATAPI send %x\n", Srb->Cdb[0]));
9553#ifdef __REACTOS__
9555
9556 if (Srb->Cdb[0] == SCSIOP_INQUIRY &&
9557 (LunExt->DeviceFlags & DFLAGS_ATAPI_DEVICE) &&
9558 (LunExt->IdentifyData.DeviceType == ATAPI_TYPE_CDROM ||
9559 LunExt->IdentifyData.DeviceType == ATAPI_TYPE_OPTICAL) &&
9560 LunExt->IdentifyData.ModelNumber[0])
9561 {
9562 ULONG j;
9563 CCHAR vendorId[26];
9564
9565 // Attempt to identify known broken CD/DVD drives
9566 for (j = 0; j < sizeof(vendorId); j += 2)
9567 {
9568 // Build a buffer based on the identify data.
9569 MOV_DW_SWP(vendorId[j], ((PUCHAR)LunExt->IdentifyData.ModelNumber)[j]);
9570 }
9571
9572 // Emulate INQUIRY support for broken CD/DVD drives (e.g. Microsoft Xbox).
9573 // Currently we implement it by explicitly checking the drive name from ATA IDENTIFY PACKET.
9574 if (!AtapiStringCmp(vendorId, "THOMSON-DVD", 11) ||
9575 !AtapiStringCmp(vendorId, "PHILIPS XBOX DVD DRIVE", 22) ||
9576 !AtapiStringCmp(vendorId, "PHILIPS J5 3235C", 16) ||
9577 !AtapiStringCmp(vendorId, "SAMSUNG DVD-ROM SDG-605B", 24))
9578 {
9579 // TODO:
9580 // Better send INQUIRY and then check for chan->ReturningMediaStatus >> 4 == SCSI_SENSE_ILLEGAL_REQUEST
9581 // in AtapiInterrupt__() and emulate the response only in this case.
9582
9583 // If this hack stays for long enough, consider adding Xbox 360 drive names to the condition,
9584 // as they are affected by the same problem.
9585
9586 // See https://jira.reactos.org/browse/CORE-16692
9587 ULONG i;
9588 PINQUIRYDATA inquiryData = (PINQUIRYDATA)(Srb->DataBuffer);
9589 PIDENTIFY_DATA2 identifyData = &(LunExt->IdentifyData);
9590
9591 // Zero INQUIRY data structure.
9593
9594 // This is ATAPI CD- or DVD-ROM.
9596
9597 // Set the removable bit, if applicable.
9598 if (LunExt->DeviceFlags & DFLAGS_REMOVABLE_DRIVE) {
9600 "RemovableMedia\n"));
9601 inquiryData->RemovableMedia = 1;
9602 }
9603 // Set the Relative Addressing (LBA) bit, if applicable.
9604 if (LunExt->DeviceFlags & DFLAGS_LBA_ENABLED) {
9605 inquiryData->RelativeAddressing = 1;
9607 "RelativeAddressing\n"));
9608 }
9609 // Set the CommandQueue bit
9610 inquiryData->CommandQueue = 1;
9611
9612 // Fill in vendor identification fields.
9613#ifdef __REACTOS__
9614 FillDeviceIdentificationString(inquiryData, identifyData);
9615#else
9616 for (i = 0; i < 24; i += 2) {
9617 MOV_DW_SWP(inquiryData->DeviceIdentificationString[i], ((PUCHAR)identifyData->ModelNumber)[i]);
9618 }
9619#endif
9620
9621 // Move firmware revision from IDENTIFY data to
9622 // product revision in INQUIRY data.
9623 for (i = 0; i < 4; i += 2) {
9624 MOV_DW_SWP(inquiryData->ProductRevisionLevel[i], ((PUCHAR)identifyData->FirmwareRevision)[i]);
9625 }
9626
9628 }
9629 }
9630
9632#endif
9633 status = AtapiSendCommand(HwDeviceExtension, Srb, CMD_ACTION_ALL);
9634 } else {
9635 KdPrint2((PRINT_PREFIX "Try IDE send\n"));
9636/* {
9637 ULONG __ebp__ = 0;
9638 ULONG __esp__ = 0;
9639
9640 KdPrint2((PRINT_PREFIX "** before IdeSendCommand:\n"));
9641 __asm {
9642 mov eax,ebp
9643 mov __ebp__, eax
9644 mov eax,esp
9645 mov __esp__, eax
9646 }
9647 KdPrint2((PRINT_PREFIX "** before Ide: EBP:%#x ESP:%#x\n", __ebp__, __esp__));
9648 }*/
9649 status = IdeSendCommand(HwDeviceExtension, Srb, CMD_ACTION_ALL);
9650 }
9651/* KeBugCheckEx(0xc000000e,
9652 (Srb->PathId<<16) | (Srb->TargetId<<8) | (Srb->Lun),
9653 Srb->Function,
9654 status, 0x80000002);*/
9655
9656 }
9657//skip_exec:
9658 TopLevel = FALSE;
9659
9660 break;
9661
9663
9664 tmpSrb = ScsiPortGetSrb(HwDeviceExtension, Srb->PathId, Srb->TargetId, Srb->Lun,
9665 Srb->QueueTag);
9666 // Verify that SRB to abort is still outstanding.
9667 if((tmpSrb != Srb->NextSrb) ||
9668 !chan->queue_depth) {
9669
9670 KdPrint2((PRINT_PREFIX "AtapiStartIo: SRB to abort already completed\n"));
9671
9672 // Complete abort SRB.
9674 break;
9675 }
9676
9677 AtaReq = (PATA_REQ)(tmpSrb->SrbExtension);
9679 if (!AtapiResetController__(deviceExtension, lChannel, RESET_COMPLETE_CURRENT)) {
9680 KdPrint2((PRINT_PREFIX "AtapiStartIo: Abort command failed\n"));
9681 // Log reset failure.
9683 "ScsiPortLogError: devExt %#x, Srb %#x, P:T:D=%d:%d:%d, MsgId %#x (%d)\n",
9684 HwDeviceExtension, NULL, 0, 0, 0, SP_INTERNAL_ADAPTER_ERROR, 5 << 8
9685 ));
9686 ScsiPortLogError(HwDeviceExtension, NULL, 0, 0, 0, SP_INTERNAL_ADAPTER_ERROR, 5 << 8);
9688
9689 } else {
9691 }
9692 } else {
9693 KdPrint2((PRINT_PREFIX "AtapiInterrupt: remove aborted srb %#x\n", tmpSrb));
9694 if (tmpSrb->SenseInfoBuffer &&
9695 tmpSrb->SenseInfoBufferLength >= sizeof(SENSE_DATA)) {
9696
9697 PSENSE_DATA senseBuffer = (PSENSE_DATA)tmpSrb->SenseInfoBuffer;
9698
9699 senseBuffer->ErrorCode = 0;
9700 senseBuffer->Valid = 1;
9701 senseBuffer->AdditionalSenseLength = 0xb;
9702 senseBuffer->SenseKey = SCSI_SENSE_ABORTED_COMMAND;
9703 senseBuffer->AdditionalSenseCode = 0;
9704 senseBuffer->AdditionalSenseCodeQualifier = 0;
9705
9707 }
9708 AtapiDmaDBSync(chan, tmpSrb);
9709 UniataRemoveRequest(chan, tmpSrb);
9710 // Indicate command complete.
9712 deviceExtension,
9713 tmpSrb);
9715 }
9716 break;
9717
9718 // Abort function indicates that a request timed out.
9719 // Call reset routine. Card will only be reset if
9720 // status indicates something is wrong.
9721 // Fall through to reset code.
9722
9725
9726 // Reset single device.
9727 // For now we support only Lun=0
9728
9729 // Note: reset is immediate command, it cannot be queued since it is usually used to
9730 // revert not-responding device to operational state
9731 KdPrint2((PRINT_PREFIX "AtapiStartIo: Reset device request received\n"));
9732 UniataUserDeviceReset(deviceExtension, LunExt, lChannel);
9734 break;
9735
9737do_bus_reset:
9738 // Reset Atapi and SCSI bus.
9739
9740 // Note: reset is immediate command, it cannot be queued since it is usually used to
9741 // revert not- responding device to operational state
9742 KdPrint2((PRINT_PREFIX "AtapiStartIo: Reset bus request received\n"));
9743 if (!AtapiResetController__(deviceExtension, lChannel, RESET_COMPLETE_ALL)) {
9744 KdPrint2((PRINT_PREFIX "AtapiStartIo: Reset bus failed\n"));
9745 // Log reset failure.
9747 "ScsiPortLogError: devExt %#x, Srb %#x, P:T:D=%d:%d:%d, MsgId %#x (%d) - (2)\n",
9748 HwDeviceExtension, NULL, 0, 0, 0, SP_INTERNAL_ADAPTER_ERROR, 5 << 8
9749 ));
9750 ScsiPortLogError(HwDeviceExtension, NULL, 0, 0, 0, SP_INTERNAL_ADAPTER_ERROR, 5 << 8);
9752
9753 } else {
9755 }
9756
9757 break;
9758
9760
9761 KdPrint2((PRINT_PREFIX "AtapiStartIo: Shutdown\n"));
9762 if(!LunExt || !(LunExt->DeviceFlags & DFLAGS_DEVICE_PRESENT)) {
9763 KdPrint2((PRINT_PREFIX "AtapiStartIo: Shutdown - no such device\n"));
9764 } else
9765 if(atapiDev) {
9766 // FLUSH ATAPI device - do nothing
9767 KdPrint2((PRINT_PREFIX "AtapiStartIo: Shutdown - ATAPI device\n"));
9768 } else {
9769 // FLUSH IDE/ATA device
9770 KdPrint2((PRINT_PREFIX "AtapiStartIo: Shutdown - IDE device\n"));
9771 AtapiDisableInterrupts(deviceExtension, lChannel);
9772 status = AtaCommand(deviceExtension, DeviceNumber, GET_CHANNEL(Srb),
9773 IDE_COMMAND_FLUSH_CACHE, 0, 0, 0, 0, 0, ATA_WAIT_IDLE);
9774 // If supported & allowed, reset write cacheing
9775 if(LunExt->DeviceFlags & DFLAGS_WCACHE_ENABLED) {
9776
9777 // Disable write cache
9778 status = AtaCommand(deviceExtension, DeviceNumber, lChannel,
9779 IDE_COMMAND_SET_FEATURES, 0, 0, 0,
9781 // Check for errors.
9782 if (status & IDE_STATUS_ERROR) {
9784 "AtapiHwInitialize: Disable write cacheing on Device %d failed\n",
9785 DeviceNumber));
9786 }
9787 LunExt->DeviceFlags &= ~DFLAGS_WCACHE_ENABLED;
9788
9789 // Re-enable write cache
9790 status = AtaCommand(deviceExtension, DeviceNumber, lChannel,
9791 IDE_COMMAND_SET_FEATURES, 0, 0, 0,
9793 // Check for errors.
9794 if (status & IDE_STATUS_ERROR) {
9796 "AtapiHwInitialize: Enable write cacheing on Device %d failed\n",
9797 DeviceNumber));
9798 LunExt->DeviceFlags &= ~DFLAGS_WCACHE_ENABLED;
9799 } else {
9801 }
9802 }
9803
9804 AtapiEnableInterrupts(deviceExtension, lChannel);
9805 }
9807
9808 break;
9809
9810 case SRB_FUNCTION_FLUSH:
9811
9812 KdPrint2((PRINT_PREFIX "AtapiStartIo: Flush (do nothing)\n"));
9814 break;
9815
9817
9818 ULONG len;
9819
9820 KdPrint2((PRINT_PREFIX "AtapiStartIo: SRB_FUNCTION_IO_CONTROL\n"));
9821
9823
9824 if(!AtapiStringCmp( (PCHAR)(((PSRB_IO_CONTROL)(Srb->DataBuffer))->Signature),"SCSIDISK",sizeof("SCSIDISK")-1)) {
9825
9826 ULONG targetId = (ULONG)(-1);
9827
9828 if(len < sizeof(SRB_IO_CONTROL)) {
9829 goto wrong_buffer_size;
9830 }
9831
9832 // extract bogus bus address
9833 switch (((PSRB_IO_CONTROL)(Srb->DataBuffer))->ControlCode) {
9835 PGETVERSIONINPARAMS versionParameters = (PGETVERSIONINPARAMS)(((PUCHAR)Srb->DataBuffer) + sizeof(SRB_IO_CONTROL));
9836
9837 if(len < sizeof(SRB_IO_CONTROL)+sizeof(GETVERSIONINPARAMS)) {
9838 goto wrong_buffer_size;
9839 }
9840
9841 targetId = versionParameters->bIDEDeviceMap;
9842 KdPrint2((PRINT_PREFIX "targetId (smart ver) %d\n", targetId));
9843 break; }
9856 {
9857 PSENDCMDINPARAMS cmdInParameters = (PSENDCMDINPARAMS)(((PUCHAR)Srb->DataBuffer) + sizeof(SRB_IO_CONTROL));
9858
9859 if(len < sizeof(SRB_IO_CONTROL)+sizeof(SENDCMDINPARAMS) - 1) {
9860 goto wrong_buffer_size;
9861 }
9862
9863 targetId = cmdInParameters->bDriveNumber;
9864 KdPrint2((PRINT_PREFIX "targetId (smart/ident) %d\n", targetId));
9865 break; }
9866 default:
9867invalid_request:
9868 KdPrint2((PRINT_PREFIX "AtapiStartIo: invalid IoControl %#x for SCSIDISK signature\n",
9869 ((PSRB_IO_CONTROL)(Srb->DataBuffer))->ControlCode ));
9871 goto complete_req;
9872 } // end switch()
9873
9874 // adjust (if necessary) bus address
9875 if(targetId != (ULONG)(-1)) {
9876
9877 // This is done because of how the IOCTL_SCSI_MINIPORT
9878 // determines 'targetid's'. Disk.sys places the real target id value
9879 // in the DeviceMap field. Once we do some parameter checking, the value passed
9880 // back to the application will be determined.
9881
9882 if (deviceExtension->NumberChannels == 1) {
9883 // do this for legacy controllers and legacy callers
9884 KdPrint2((PRINT_PREFIX "AtapiStartIo: legacy call\n"));
9885 DeviceNumber = (targetId & 0x01);
9886 lChannel = 0;
9887 } else
9888 if(commPort) {
9889 // do this for smartmontools, sending IOCTLs to PhysicalDrive%d
9890 // due to DISK.SYS design bug, we have invalid SCSI address in SRB
9891 KdPrint2((PRINT_PREFIX "AtapiStartIo: legacy call (2)\n"));
9892 if(deviceExtension->HwFlags & UNIATA_AHCI) {
9893 lChannel = (UCHAR)targetId / 2;
9894 DeviceNumber = 0;
9895 } else {
9896 lChannel = (UCHAR)(targetId / 2);
9897 DeviceNumber = targetId & 0x01;
9898 }
9899 } else {
9900 // otherwise assume lChannel and DeviceNumber from Srb are ok
9901 }
9902 if(lChannel >= deviceExtension->NumberChannels ||
9903 DeviceNumber >= deviceExtension->NumberLuns) {
9905 "AtapiStartIo: SCSIDISK IOCTL for non-exestent drive %d -> EXECUTE_SCSI rejected (2)\n",
9906 targetId));
9907 // Indicate no device found at this address.
9908 goto reject_srb;
9909 }
9910 targetId = lChannel*deviceExtension->NumberLuns+DeviceNumber;
9911 chan = &(deviceExtension->chan[lChannel]);
9912 LunExt = chan->lun[DeviceNumber];
9913 if(!LunExt) {
9914 goto reject_srb;
9915 }
9916 atapiDev = (LunExt->DeviceFlags & DFLAGS_ATAPI_DEVICE) ? TRUE : FALSE;
9917
9918 if (!(LunExt->DeviceFlags & DFLAGS_DEVICE_PRESENT)) {
9919 goto reject_srb;
9920 }
9921 }
9922
9923 switch (((PSRB_IO_CONTROL)(Srb->DataBuffer))->ControlCode) {
9925
9926 PGETVERSIONINPARAMS versionParameters = (PGETVERSIONINPARAMS)(((PUCHAR)Srb->DataBuffer) + sizeof(SRB_IO_CONTROL));
9927 UCHAR deviceNumberMap;
9928
9929 KdPrint2((PRINT_PREFIX "AtapiStartIo: IOCTL_SCSI_MINIPORT_SMART_VERSION\n"));
9930
9931 // Version and revision per SMART 1.03
9932
9933 versionParameters->bVersion = 1;
9934 versionParameters->bRevision = 1;
9935 versionParameters->bReserved = 0;
9936
9937 // Indicate that support for IDE IDENTIFY, ATAPI IDENTIFY and SMART commands.
9939
9940 if (atapiDev) {
9941 goto invalid_request;
9942 }
9943
9944 // NOTE: This will only set the bit
9945 // corresponding to this drive's target id.
9946 // The bit mask is as follows:
9947 //
9948 // -Sec Pri
9949 // S M S M
9950 // 3 2 1 0
9951
9952 if(chan->DeviceExtension->HwFlags & UNIATA_AHCI) {
9953 deviceNumberMap = 1 << lChannel;
9954 DeviceNumber = 0;
9955 } else
9956 if (deviceExtension->NumberChannels == 1) {
9957 if (chan->PrimaryAddress) {
9958 deviceNumberMap = 1 << DeviceNumber;
9959 } else {
9960 deviceNumberMap = 4 << DeviceNumber;
9961 }
9962 } else {
9963 deviceNumberMap = 1 << (DeviceNumber+lChannel*2);
9964 }
9965
9966 versionParameters->bIDEDeviceMap = deviceNumberMap;
9967
9969 break;
9970 }
9971
9973
9974 PSENDCMDOUTPARAMS cmdOutParameters = (PSENDCMDOUTPARAMS)(((PUCHAR)Srb->DataBuffer) + sizeof(SRB_IO_CONTROL));
9975 SENDCMDINPARAMS cmdInParameters = *(PSENDCMDINPARAMS)(((PUCHAR)Srb->DataBuffer) + sizeof(SRB_IO_CONTROL));
9976
9977 KdPrint2((PRINT_PREFIX "AtapiStartIo: IOCTL_SCSI_MINIPORT_IDENTIFY\n"));
9978 // Extract the target.
9979 KdPrint2((PRINT_PREFIX "targetId %d\n", targetId));
9980
9981 switch(cmdInParameters.irDriveRegs.bCommandReg) {
9982 case ID_CMD:
9983 if(atapiDev) {
9984 KdPrint2((PRINT_PREFIX "Error: ID_CMD for ATAPI\n"));
9985 goto invalid_request;
9986 }
9987 /* FALL THROUGH */
9988 case ATAPI_ID_CMD:
9989
9990 if(!atapiDev &&
9991 (cmdInParameters.irDriveRegs.bCommandReg == ATAPI_ID_CMD)) {
9992 KdPrint2((PRINT_PREFIX "Error: ATAPI_ID_CMD for non-ATAPI\n"));
9993 goto invalid_request;
9994 }
9995
9997 // Zero the output buffer
9998 RtlZeroMemory(cmdOutParameters, len);
9999/* for (i = 0; i < (sizeof(SENDCMDOUTPARAMS) + IDENTIFY_BUFFER_SIZE - 1); i++) {
10000 ((PUCHAR)cmdOutParameters)[i] = 0;
10001 }*/
10002
10003 // Build status block.
10004 cmdOutParameters->cBufferSize = min(IDENTIFY_BUFFER_SIZE, len - sizeof(SENDCMDOUTPARAMS) + 1);
10005 cmdOutParameters->DriverStatus.bDriverError = 0;
10006 cmdOutParameters->DriverStatus.bIDEError = 0;
10007
10008 // Extract the identify data from the device extension.
10009 ScsiPortMoveMemory (cmdOutParameters->bBuffer, &(LunExt->IdentifyData),
10010 cmdOutParameters->cBufferSize);
10011
10012 if((cmdOutParameters->cBufferSize == IDENTIFY_BUFFER_SIZE) &&
10013 (LunExt->IdentifyData.ChecksumValid == ATA_ChecksumValid)) {
10014 // adjust checksum if it is possible
10015 CHAR csum = 0;
10016 ULONG i;
10017
10018 for(i=0; i < IDENTIFY_BUFFER_SIZE-1; i++) {
10019 csum += (CHAR)(cmdOutParameters->bBuffer[i]);
10020 }
10021 cmdOutParameters->bBuffer[i] = -csum;
10022 KdPrint2((PRINT_PREFIX "AtapiStartIo: adjust checksum %d\n"));
10023 }
10024 KdPrint2((PRINT_PREFIX "AtapiStartIo: IOCTL_SCSI_MINIPORT_IDENTIFY Ok\n"));
10025
10027
10028 break;
10029 default:
10030 KdPrint2((PRINT_PREFIX "AtapiStartIo: not supported ID code %x\n",
10031 cmdInParameters.irDriveRegs.bCommandReg));
10033 break;
10034 }
10035 break;
10036 }
10037/*
10038 case IOCTL_SCSI_MINIPORT_READ_SMART_ATTRIBS:
10039 case IOCTL_SCSI_MINIPORT_READ_SMART_THRESHOLDS:
10040 case IOCTL_SCSI_MINIPORT_ENABLE_SMART:
10041 case IOCTL_SCSI_MINIPORT_DISABLE_SMART:
10042 case IOCTL_SCSI_MINIPORT_RETURN_STATUS:
10043 case IOCTL_SCSI_MINIPORT_ENABLE_DISABLE_AUTOSAVE:
10044 case IOCTL_SCSI_MINIPORT_SAVE_ATTRIBUTE_VALUES:
10045 case IOCTL_SCSI_MINIPORT_EXECUTE_OFFLINE_DIAGS:
10046*/
10047 default:
10048 // *all* IOCTLs here are SMART
10049 if(commPort) {
10051 "AtapiStartIo: SCSIDISK Smart IOCTL for commPort -> EXECUTE_SCSI rejected (3)\n"));
10052 }
10053 if (atapiDev) {
10054 goto invalid_request;
10055 }
10056
10057 PostReq = UniataNeedQueueing(deviceExtension, chan, TopLevel);
10058
10059 if(PostReq || TopLevel) {
10060 UniataQueueRequest(chan, Srb);
10061 AtaReq = (PATA_REQ)(Srb->SrbExtension);
10062 AtaReq->ReqState = REQ_STATE_QUEUED;
10063 }
10064
10065 if(PostReq) {
10066
10067 KdPrint2((PRINT_PREFIX "Non-empty queue (SMART)\n"));
10069
10070 KdPrint2((PRINT_PREFIX "AtapiStartIo: Already have %d request(s)!\n", chan->queue_depth));
10071 } else {
10072
10073 status = IdeSendSmartCommand(HwDeviceExtension, Srb, targetId);
10074 }
10075 break;
10076
10077 // we should not get here, checked above
10078/* default :
10079 KdPrint2((PRINT_PREFIX "AtapiStartIo: invalid IoControl %#x for SCSIDISK signature\n",
10080 ((PSRB_IO_CONTROL)(Srb->DataBuffer))->ControlCode ));
10081 status = SRB_STATUS_INVALID_REQUEST;
10082 break;
10083*/
10084 }
10085 } else
10086 if(!AtapiStringCmp( (PCHAR)(((PSRB_IO_CONTROL)(Srb->DataBuffer))->Signature),"-UNIATA-", sizeof("-UNIATA-")-1)) {
10087
10089 //ULONG ldev = GET_LDEV2(AtaCtl->addr.PathId, AtaCtl->addr.TargetId, 0);
10090 ULONG DeviceNumber = AtaCtl->addr.TargetId;
10091 BOOLEAN bad_ldev;
10092 ULONG i, pos;
10093
10094 pos = FIELD_OFFSET(UNIATA_CTL, RawData);
10095 //chan = &(deviceExtension->chan[lChannel]);
10096 if(len < pos) {
10097 KdPrint2((PRINT_PREFIX "AtapiStartIo: AtaCtl Buffer too small: %#x < %#x\n", len,
10098 FIELD_OFFSET(UNIATA_CTL, RawData) ));
10099 goto wrong_buffer_size;
10100 }
10101
10102 if(AtaCtl->addr.Lun ||
10103 AtaCtl->addr.TargetId >= deviceExtension->NumberLuns ||
10104 AtaCtl->addr.PathId >= deviceExtension->NumberChannels) {
10105
10106 chan = NULL;
10107 bad_ldev = TRUE;
10108 LunExt = NULL;
10109
10110 } else {
10111 bad_ldev = FALSE;
10112 lChannel = AtaCtl->addr.PathId;
10113 chan = &(deviceExtension->chan[lChannel]);
10114 LunExt = chan->lun[DeviceNumber];
10115 }
10116
10117 KdPrint2((PRINT_PREFIX "AtapiStartIo: -UNIATA- %#x, dev %#x\n", AtaCtl->hdr.ControlCode, DeviceNumber));
10118
10119 /* check for valid LUN */
10120 switch (AtaCtl->hdr.ControlCode) {
10123 // this would be BUS reset
10124 if(bad_ldev &&
10125 (AtaCtl->addr.PathId >= deviceExtension->NumberChannels ||
10126 AtaCtl->addr.TargetId != 0xff ||
10127 AtaCtl->addr.Lun != 0
10128 )) {
10130 DeviceNumber < deviceExtension->NumberLuns) { // AtaCtl->addr.TargetId != 0xff
10131 lChannel = AtaCtl->addr.PathId;
10132 chan = &(deviceExtension->chan[lChannel]);
10133 LunExt = chan->lun[DeviceNumber];
10134 // OK
10135 } else {
10136 goto handle_bad_ldev;
10137 }
10138 } else {
10139 lChannel = AtaCtl->addr.PathId;
10140 chan = &(deviceExtension->chan[lChannel]);
10141 }
10142 break;
10147// case IOCTL_SCSI_MINIPORT_UNIATA_REG_IO:
10148 if(bad_ldev) {
10149handle_bad_ldev:
10151 "AtapiStartIo: bad_ldev -> IOCTL SRB rejected\n"));
10152 // Indicate no device found at this address.
10153 goto reject_srb;
10154 }
10155 }
10156
10157 /* check if queueing is necessary */
10158 switch (AtaCtl->hdr.ControlCode) {
10160 if(!LunExt->nBadBlocks) {
10161 break;
10162 }
10163 goto uata_ctl_queue;
10165 if(len < pos+sizeof(AtaCtl->SetMode)) {
10166 KdPrint2((PRINT_PREFIX "AtapiStartIo: AtaCtl Buffer too small: %#x < %#x\n", len,
10167 pos+sizeof(AtaCtl->SetMode) ));
10168 goto wrong_buffer_size;
10169 }
10170 if(!AtaCtl->SetMode.ApplyImmediately) {
10171 break;
10172 }
10173 goto uata_ctl_queue;
10175 //case IOCTL_SCSI_MINIPORT_UNIATA_RESET_DEVICE: reset must be processed immediately
10176uata_ctl_queue:
10177 KdPrint2((PRINT_PREFIX "put to queue (UNIATA)\n"));
10178 PostReq = UniataNeedQueueing(deviceExtension, chan, TopLevel);
10179
10180 if(PostReq || TopLevel) {
10181 UniataQueueRequest(chan, Srb);
10182 AtaReq = (PATA_REQ)(Srb->SrbExtension);
10183 AtaReq->ReqState = REQ_STATE_QUEUED;
10184 }
10185 if(PostReq) {
10186 KdPrint2((PRINT_PREFIX "Non-empty queue (UNIATA)\n"));
10188
10189 KdPrint2((PRINT_PREFIX "AtapiStartIo: Already have %d request(s)!\n", chan->queue_depth));
10190 goto complete_req;
10191 }
10192 } // end switch (AtaCtl->hdr.ControlCode)
10193
10194 /* process request */
10195 switch (AtaCtl->hdr.ControlCode) {
10197
10198 KdPrint2((PRINT_PREFIX "AtapiStartIo: rescan bus\n"));
10199
10200 if(len < pos+sizeof(AtaCtl->FindDelDev)) {
10201 KdPrint2((PRINT_PREFIX "AtapiStartIo: AtaCtl Buffer too small: %#x < %#x\n", len,
10202 pos+sizeof(AtaCtl->FindDelDev) ));
10203 goto wrong_buffer_size;
10204 }
10206 KdPrint2((PRINT_PREFIX "AtapiStartIo: unhide from further detection\n"));
10207 if(AtaCtl->addr.TargetId != 0xff) {
10208 LunExt->DeviceFlags &= ~DFLAGS_HIDDEN;
10209 } else {
10210 }
10211 }
10212
10213 for(i=0; i<AtaCtl->FindDelDev.WaitForPhysicalLink && i<30; i++) {
10214 AtapiStallExecution(1000 * 1000);
10215 }
10216
10217 FindDevices(HwDeviceExtension,
10218 ((AtaCtl->addr.TargetId == 0xff) && (AtaCtl->FindDelDev.Flags & UNIATA_ADD_FLAGS_UNHIDE))
10220 AtaCtl->addr.PathId);
10222
10223 break;
10224
10226
10227 KdPrint2((PRINT_PREFIX "AtapiStartIo: remove %#x:%#x\n", AtaCtl->addr.PathId, AtaCtl->addr.TargetId));
10228
10229 if(len < pos+sizeof(AtaCtl->FindDelDev)) {
10230 KdPrint2((PRINT_PREFIX "AtapiStartIo: AtaCtl Buffer too small: %#x < %#x\n", len,
10231 pos+sizeof(AtaCtl->FindDelDev) ));
10232 goto wrong_buffer_size;
10233 }
10234 LunExt->DeviceFlags = 0;
10236 KdPrint2((PRINT_PREFIX "AtapiStartIo: hide from further detection\n"));
10237 //LunExt->DeviceFlags |= DFLAGS_HIDDEN;
10238 UniataForgetDevice(LunExt);
10239 }
10240
10241 for(i=0; i<AtaCtl->FindDelDev.WaitForPhysicalLink && i<30; i++) {
10242 AtapiStallExecution(1000 * 1000);
10243 }
10244
10246 break;
10247 }
10249
10250 KdPrint2((PRINT_PREFIX "AtapiStartIo: Set transfer mode\n"));
10251
10252 if(len < pos+sizeof(AtaCtl->SetMode)) {
10253 KdPrint2((PRINT_PREFIX "AtapiStartIo: AtaCtl Buffer too small: %#x < %#x\n", len,
10254 pos+sizeof(AtaCtl->SetMode) ));
10255 goto wrong_buffer_size;
10256 }
10257 if(AtaCtl->SetMode.OrigMode != IOMODE_NOT_SPECIFIED) {
10258 LunExt->OrigTransferMode = (UCHAR)(AtaCtl->SetMode.OrigMode);
10259 }
10260 if(AtaCtl->SetMode.MaxMode != IOMODE_NOT_SPECIFIED) {
10261 LunExt->LimitedTransferMode = (UCHAR)(AtaCtl->SetMode.MaxMode);
10262 if(LunExt->LimitedTransferMode >
10263 LunExt->OrigTransferMode) {
10264 // check for incorrect value
10265 LunExt->LimitedTransferMode =
10266 LunExt->OrigTransferMode;
10267 }
10268 }
10269 LunExt->TransferMode = min(LunExt->LimitedTransferMode, LunExt->OrigTransferMode);
10270
10271 LunExt->DeviceFlags |= DFLAGS_REINIT_DMA; // force PIO/DMA reinit
10272 if(AtaCtl->SetMode.ApplyImmediately) {
10273 AtapiDmaInit__(deviceExtension, LunExt);
10274 }
10275/* LunExt->TransferMode =
10276 LunExt->LimitedTransferMode = (UCHAR)(setTransferMode->Mode);*/
10278 break;
10279 }
10281
10282 KdPrint2((PRINT_PREFIX "AtapiStartIo: Get transfer mode\n"));
10283
10284 if(len < pos+sizeof(AtaCtl->GetMode)) {
10285 KdPrint2((PRINT_PREFIX "AtapiStartIo: AtaCtl Buffer too small: %#x < %#x\n", len,
10286 pos+sizeof(AtaCtl->GetMode) ));
10287 goto wrong_buffer_size;
10288 }
10289 AtaCtl->GetMode.OrigMode = LunExt->OrigTransferMode;
10290 AtaCtl->GetMode.MaxMode = LunExt->LimitedTransferMode;
10291 AtaCtl->GetMode.CurrentMode = LunExt->TransferMode;
10292 AtaCtl->GetMode.PhyMode = LunExt->PhyTransferMode;
10293
10295 break;
10296 }
10298
10299 KdPrint2((PRINT_PREFIX "AtapiStartIo: Get version\n"));
10300
10301 if(len < pos+sizeof(AtaCtl->Version)) {
10302 KdPrint2((PRINT_PREFIX "AtapiStartIo: AtaCtl Buffer too small: %#x < %#x\n", len,
10303 pos+sizeof(AtaCtl->Version) ));
10304 goto wrong_buffer_size;
10305 }
10306 AtaCtl->Version.Length = sizeof(GETDRVVERSION);
10311
10313 break;
10314 }
10316
10317 KdPrint2((PRINT_PREFIX "AtapiStartIo: Get adapter info\n"));
10318
10319 if(len < pos+sizeof(AtaCtl->AdapterInfo)) {
10320 KdPrint2((PRINT_PREFIX "AtapiStartIo: AtaCtl Buffer too small: %#x < %#x\n", len,
10321 pos+sizeof(AtaCtl->AdapterInfo) ));
10322 goto wrong_buffer_size;
10323 }
10324 AtaCtl->AdapterInfo.HeaderLength = sizeof(ADAPTERINFO);
10325
10326 AtaCtl->AdapterInfo.DevID = deviceExtension->DevID;
10327 AtaCtl->AdapterInfo.RevID = deviceExtension->RevID;
10328 AtaCtl->AdapterInfo.slotNumber = deviceExtension->slotNumber;
10329 AtaCtl->AdapterInfo.SystemIoBusNumber = deviceExtension->SystemIoBusNumber;
10330 AtaCtl->AdapterInfo.DevIndex = deviceExtension->DevIndex;
10331 AtaCtl->AdapterInfo.Channel = deviceExtension->Channel;
10332 AtaCtl->AdapterInfo.HbaCtrlFlags = deviceExtension->HbaCtrlFlags;
10333 AtaCtl->AdapterInfo.simplexOnly= deviceExtension->simplexOnly;
10334 AtaCtl->AdapterInfo.MemIo = FALSE;/*deviceExtension->MemIo;*/
10335 AtaCtl->AdapterInfo.UnknownDev = deviceExtension->UnknownDev;
10336 AtaCtl->AdapterInfo.MasterDev = deviceExtension->MasterDev;
10337 AtaCtl->AdapterInfo.MaxTransferMode = deviceExtension->MaxTransferMode;
10338 AtaCtl->AdapterInfo.HwFlags = deviceExtension->HwFlags;
10340 AtaCtl->AdapterInfo.BusInterruptLevel = deviceExtension->BusInterruptLevel;
10341 AtaCtl->AdapterInfo.InterruptMode = deviceExtension->InterruptMode;
10342 AtaCtl->AdapterInfo.BusInterruptVector = deviceExtension->BusInterruptVector;
10343 AtaCtl->AdapterInfo.NumberChannels = deviceExtension->NumberChannels;
10344 AtaCtl->AdapterInfo.NumberLuns = (UCHAR)deviceExtension->NumberLuns;
10345 AtaCtl->AdapterInfo.AdapterInterfaceType = deviceExtension->AdapterInterfaceType;
10346 if(deviceExtension->FullDevName) {
10347 strncpy(AtaCtl->AdapterInfo.DeviceName, deviceExtension->FullDevName, 64);
10348 }
10350 AtaCtl->AdapterInfo.LunInfoValid = FALSE;
10352
10353 pos += AtaCtl->AdapterInfo.HeaderLength;
10354
10355 // zero tail
10356 RtlZeroMemory(((PCHAR)AtaCtl)+pos,
10357 len-pos);
10358
10359 if(len >= pos+AtaCtl->AdapterInfo.NumberChannels*sizeof(CHANINFO)) {
10360 PCHANINFO ChanInfo = (PCHANINFO)( ((PCHAR)AtaCtl)+pos );
10361 PHW_CHANNEL cur_chan;
10362 KdPrint2((PRINT_PREFIX "AtapiStartIo: Fill channel info\n"));
10363 for(i=0;i<AtaCtl->AdapterInfo.NumberChannels;i++) {
10364 KdPrint2((PRINT_PREFIX "chan[%d] %x\n", i, cur_chan));
10365 cur_chan = &(deviceExtension->chan[i]);
10366 ChanInfo->MaxTransferMode = cur_chan->MaxTransferMode;
10367 ChanInfo->ChannelCtrlFlags = cur_chan->ChannelCtrlFlags;
10368 RtlCopyMemory(&(ChanInfo->QueueStat), &(cur_chan->QueueStat), sizeof(ChanInfo->QueueStat));
10369 ChanInfo->ReorderCount = cur_chan->ReorderCount;
10370 ChanInfo->IntersectCount = cur_chan->IntersectCount;
10371 ChanInfo->TryReorderCount = cur_chan->TryReorderCount;
10372 ChanInfo->TryReorderHeadCount = cur_chan->TryReorderHeadCount;
10373 ChanInfo->TryReorderTailCount = cur_chan->TryReorderTailCount;
10374 //ChanInfo->opt_MaxTransferMode = cur_chan->opt_MaxTransferMode;
10375 ChanInfo++;
10376 }
10377 AtaCtl->AdapterInfo.ChanInfoValid = TRUE;
10378 AtaCtl->AdapterInfo.ChanHeaderLength = sizeof(*ChanInfo);
10379 }
10380
10382 break;
10383 }
10385
10386 KdPrint2((PRINT_PREFIX "AtapiStartIo: Forget BB list\n"));
10387
10388 ForgetBadBlocks(LunExt);
10389
10391 break;
10392 }
10394
10395 KdPrint2((PRINT_PREFIX "AtapiStartIo: Reset device\n"));
10396
10397 if(bad_ldev) {
10398 goto do_bus_reset;
10399 } else {
10400 UniataUserDeviceReset(deviceExtension, LunExt, AtaCtl->addr.PathId);
10401 }
10402
10404 break;
10405 }
10406 default :
10407 KdPrint2((PRINT_PREFIX "AtapiStartIo: invalid IoControl %#x for -UNIATA- signature\n",
10408 AtaCtl->hdr.ControlCode ));
10410 break;
10411 }
10412
10413 } else {
10414 KdPrint2((PRINT_PREFIX "AtapiStartIo: IoControl signature incorrect. Send %s, expected %s or %s\n",
10415 ((PSRB_IO_CONTROL)(Srb->DataBuffer))->Signature,
10416 "SCSIDISK", "-UNIATA-"));
10417
10419 break;
10420 }
10421
10422 break;
10423 } // end SRB_FUNCTION_IO_CONTROL
10424 default:
10425
10426 KdPrint2((PRINT_PREFIX "AtapiStartIo: Unknown IOCTL\n"));
10427 // Indicate unsupported command.
10429
10430// break;
10431
10432 } // end switch
10433
10434complete_req:
10435
10436 PathId = Srb->PathId;
10438 Lun = Srb->Lun;
10439
10440 if (status != SRB_STATUS_PENDING) {
10441
10443 "AtapiStartIo: Srb %#x complete with status %#x\n",
10444 Srb,
10445 status));
10446
10447 // Set status in SRB.
10449
10450 if(chan && Srb) {
10451 KdPrint2((PRINT_PREFIX "AtapiStartIo: AtapiDmaDBSync(%x, %x)\n", chan, Srb));
10452 AtapiDmaDBSync(chan, Srb);
10453 }
10454 KdPrint2((PRINT_PREFIX "AtapiStartIo: UniataRemoveRequest(%x, %x)\n", chan, Srb));
10455 UniataRemoveRequest(chan, Srb);
10456 // Indicate command complete.
10457 KdPrint2((PRINT_PREFIX "AtapiStartIo: ScsiPortNotification\n"));
10459 deviceExtension,
10460 Srb);
10461
10462 KdPrint2((PRINT_PREFIX "AtapiStartIo: UniataGetCurRequest\n"));
10463 // Remove current Srb & get next one
10464 if((Srb = UniataGetCurRequest(chan))) {
10465 AtaReq = (PATA_REQ)(Srb->SrbExtension);
10466 if(AtaReq->ReqState > REQ_STATE_QUEUED) {
10467 // current request is under precessing, thus
10468 // we should do nothing here
10469 Srb = NULL;
10470 }
10471 }
10472 KdPrint2((PRINT_PREFIX "AtapiStartIo: chan %x, Src %x\n", chan, Srb));
10473 if(!chan) {
10474 //ASSERT(TopLevel);
10475 }
10476 }
10477 KdPrint2((PRINT_PREFIX "AtapiStartIo: next Srb %x\n", Srb));
10478
10479 } while (Srb && (status != SRB_STATUS_PENDING));
10480
10481 KdPrint2((PRINT_PREFIX "AtapiStartIo: query PORT for next request\n"));
10482 // Indicate ready for next request.
10484 deviceExtension,
10485 NULL);
10486
10488 deviceExtension,
10489 PathId,
10490 TargetId,
10491 Lun);
10492
10493 return TRUE;
10494
10495} // end AtapiStartIo__()
10496
10497#if 0
10498void
10499NTAPI
10500UniataInitAtaCommands()
10501{
10502 int i;
10503 UCHAR command;
10504 UCHAR flags;
10505
10506 KdPrint2((PRINT_PREFIX "UniataInitAtaCommands:\n"));
10507
10508 for(i=0; i<256; i++) {
10509
10510 flags = 0;
10511 command = i;
10512
10513 //KdPrint2((PRINT_PREFIX "cmd %2.2x: ", command));
10514
10515 switch(command) {
10534 case IDE_COMMAND_DATA_SET_MGMT: // TRIM
10535 //KdPrint2((PRINT_PREFIX "DMA "));
10537 }
10538
10539 switch(command) {
10543
10545 /* FALL THROUGH */
10546
10547 case IDE_COMMAND_READ48:
10561
10562 //KdPrint2((PRINT_PREFIX "48 "));
10564 /* FALL THROUGH */
10565
10566 case IDE_COMMAND_READ:
10570 case IDE_COMMAND_WRITE:
10575 case IDE_COMMAND_VERIFY:
10576
10577 //KdPrint2((PRINT_PREFIX "LBA "));
10579 }
10580
10581 switch(command) {
10584 // we cannot set LBA flag for these commands to avoid BadBlock handling
10585 //flags |= ATA_CMD_FLAG_LBAIOsupp;
10587
10590
10592 }
10593
10595
10596 switch (command) {
10597 case IDE_COMMAND_READ:
10598 command = IDE_COMMAND_READ48; break;
10605 case IDE_COMMAND_WRITE:
10615 // case IDE_COMMAND_READ_NATIVE_SIZE:
10616 // command = IDE_COMMAND_READ_NATIVE_SIZE48; break;
10619 case IDE_COMMAND_VERIFY:
10621 default:
10622 //KdPrint2((PRINT_PREFIX "!28->48 "));
10623 flags &= ~ATA_CMD_FLAG_48supp;
10624 }
10625
10626 switch (command) {
10627 case IDE_COMMAND_READ:
10639 //KdPrint2((PRINT_PREFIX "RD "));
10641 break;
10642 case IDE_COMMAND_WRITE:
10652 //KdPrint2((PRINT_PREFIX "WR "));
10654 break;
10655 }
10656
10657 //KdPrint2((PRINT_PREFIX "\t -> %2.2x (%2.2x)\n", command, flags));
10660 }
10661} // end UniataInitAtaCommands()
10662#endif
10663
10664/*++
10665
10666Routine Description:
10667
10668 Installable driver initialization entry point for system.
10669
10670Arguments:
10671
10672 Driver Object
10673
10674Return Value:
10675
10676 Status from ScsiPortInitialize()
10677
10678--*/
10679extern "C"
10680ULONG
10681NTAPI
10685 )
10686{
10687 HW_INITIALIZATION_DATA_COMMON hwInitializationData;
10688 ULONG adapterCount;
10689 ULONG i, c, alt, pref_alt;
10690 ULONG statusToReturn, newStatus;
10692 BOOLEAN ReEnter = FALSE;
10693// WCHAR a;
10694#ifndef USE_REACTOS_DDK
10696#endif
10697
10699 BOOLEAN PrimaryClaimed = FALSE;
10700 BOOLEAN SecondaryClaimed = FALSE;
10701 BOOLEAN IgnoreIsaCompatiblePci = FALSE;
10702 BOOLEAN IgnoreNativePci = FALSE;
10703
10704 LARGE_INTEGER t0, t1;
10705
10706 KdPrint2((PRINT_PREFIX "%s", (PCCHAR)ver_string));
10707 //a = (WCHAR)strlen(ver_string);
10708
10709 statusToReturn = 0xffffffff;
10710
10711 // Zero out structure.
10712 RtlZeroMemory(((PCHAR)&hwInitializationData), sizeof(hwInitializationData));
10713
10714 // Set size of hwInitializationData.
10715 hwInitializationData.comm.HwInitializationDataSize =
10716 sizeof(hwInitializationData.comm) +
10717// sizeof(hwInitializationData.nt4) +
10718 ((WinVer_Id() <= WinVer_NT) ? 0 : sizeof(hwInitializationData.w2k));
10719 KdPrint(("HwInitializationDataSize = %x\n", hwInitializationData.comm.HwInitializationDataSize));
10720
10721 // Set entry points.
10722 hwInitializationData.comm.HwInitialize = (PHW_INITIALIZE)AtapiHwInitialize;
10723 hwInitializationData.comm.HwResetBus = (PHW_RESET_BUS)AtapiResetController;
10724 hwInitializationData.comm.HwStartIo = (PHW_STARTIO)AtapiStartIo;
10725 hwInitializationData.comm.HwInterrupt = (PHW_INTERRUPT)AtapiInterrupt;
10726
10727 // Specify size of extensions.
10728 hwInitializationData.comm.DeviceExtensionSize = sizeof(HW_DEVICE_EXTENSION);
10729 hwInitializationData.comm.SpecificLuExtensionSize = sizeof(HW_LU_EXTENSION);
10730 hwInitializationData.comm.SrbExtensionSize = sizeof(ATA_REQ);
10731
10732 // Indicate PIO device.
10733 hwInitializationData.comm.MapBuffers = TRUE;
10734
10735 // Request and parse arument string.
10736 KdPrint2((PRINT_PREFIX "\n\nUniATA: parse ArgumentString\n"));
10737 // Zero out structure.
10738 hwInitializationData.comm.NumberOfAccessRanges = 2;
10739 hwInitializationData.comm.HwFindAdapter = AtapiReadArgumentString;
10741 Argument2,
10742 &hwInitializationData.comm,
10743 &adapterCount);
10744
10745 if(!g_Dump) {
10748 if(g_opt_Verbose) {
10749 _PrintNtConsole("Universal ATA driver v 0." UNIATA_VER_STR "\n");
10750 }
10751 IgnoreIsaCompatiblePci = (BOOLEAN)AtapiRegCheckDevValue(NULL, CHAN_NOT_SPECIFIED, DEVNUM_NOT_SPECIFIED, L"IgnoreIsaCompatiblePci", IgnoreIsaCompatiblePci) ? TRUE : FALSE;
10752 IgnoreNativePci = (BOOLEAN)AtapiRegCheckDevValue(NULL, CHAN_NOT_SPECIFIED, DEVNUM_NOT_SPECIFIED, L"IgnoreNativePci", IgnoreNativePci) ? TRUE : FALSE;
10753 } else {
10754 KdPrint(("crashdump mode\n"));
10755 }
10756
10757 if(!SavedDriverObject) {
10759#ifdef USE_REACTOS_DDK
10760 KdPrint(("UniATA Init: OS should be ReactOS\n"));
10761 MajorVersion=0x04;
10762 MinorVersion=0x01;
10763 BuildNumber=1;
10765#else
10766 // we are here for the 1st time
10767 // init CrossNT and get OS version
10769 KdPrint(("UniATA Init: CrNtInit failed with status %#x\n", status));
10770 //HalDisplayString((PUCHAR)"DbgPrnHkInitialize: CrNtInit failed\n");
10771 return status;
10772 }
10774#endif // USE_REACTOS_DDK
10775 KdPrint(("UniATA Init: OS ver %x.%x (%d), %d CPU(s)\n", MajorVersion, MinorVersion, BuildNumber, CPU_num));
10776
10777 KeQuerySystemTime(&t0);
10778 do {
10779 KeQuerySystemTime(&t1);
10780 } while(t0.QuadPart == t1.QuadPart);
10781 t0=t1;
10782 g_Perf=0;
10783 do {
10784 KeQuerySystemTime(&t1);
10785 g_Perf++;
10786 } while(t0.QuadPart == t1.QuadPart);
10787 g_PerfDt = (ULONG)((t1.QuadPart - t0.QuadPart)/10);
10788 KdPrint(("Performance calibration: dt=%d, counter=%I64d\n", g_PerfDt, g_Perf ));
10789 } else {
10790 KdPrint(("UniATA Init: ReEnter\n"));
10791 ReEnter = TRUE;
10792 }
10793
10794 // (re)read bad block list
10796
10797 if(!ReEnter) {
10798 // init ATA command translation table
10799 //UniataInitAtaCommands();
10800
10801 // get registry path to settings
10804 SavedRegPath.Length = min(RegistryPath->Length, 255*sizeof(WCHAR));
10805 SavedRegPath.MaximumLength = 255*sizeof(WCHAR);
10808 }
10809
10810 if(WinVer_Id() >= WinVer_2k) {
10811#ifndef __REACTOS__
10812 if(AtapiRegCheckParameterValue(NULL, L"Paramaters\\PnpInterface", L"1", 0)) {
10813#else
10814 if(AtapiRegCheckParameterValue(NULL, L"Parameters\\PnpInterface", L"1", 0)) {
10815#endif
10816 KdPrint(("UniATA: Behave as WDM, mlia (1)\n"));
10818 }
10819#ifndef __REACTOS__
10820 if(AtapiRegCheckParameterValue(NULL, L"Paramaters\\PnpInterface", L"5", 0)) {
10821#else
10822 if(AtapiRegCheckParameterValue(NULL, L"Parameters\\PnpInterface", L"5", 0)) {
10823#endif
10824 KdPrint(("UniATA: Behave as WDM, mlia (5)\n"));
10826 }
10827 }
10828
10831#ifdef _DEBUG
10833#endif //_DEBUG
10834
10835 // Set PnP-specific API
10836 if(WinVer_Id() > WinVer_NT) {
10837 KdPrint(("set NeedPhysicalAddresses = TRUE\n"));
10838 hwInitializationData.comm.NeedPhysicalAddresses = TRUE;
10839 KdPrint(("set AtapiAdapterControl() ptr\n"));
10841 }
10842
10843 KdPrint2((PRINT_PREFIX "\n\nUniATA init... (%d)\n", ReEnter));
10844 if(!ReEnter) {
10845
10849 }
10852 }
10853 // Pre-scan PCI bus, also check if we are under VM
10854 // But do not perform scan if PCI bus is claimed as unused
10855 if(!IgnoreIsaCompatiblePci || !IgnoreNativePci) {
10856 KdPrint2((PRINT_PREFIX "\nATAPI IDE enum supported PCI BusMaster Devices\n"));
10858 }
10859
10860 switch(g_opt_VirtualMachine) {
10861 case VM_VBOX:
10862 KdPrint2((PRINT_PREFIX "adjust options for VirtualBox\n"));
10863 // adjust options for VirtualBox
10864 g_opt_WaitBusyCount = 20000;
10865 g_opt_WaitBusyDelay = 150;
10866 g_opt_WaitDrqDelay = 100;
10868 g_opt_MaxIsrWait = 200;
10871 break;
10872 case VM_BOCHS:
10873 KdPrint2((PRINT_PREFIX "adjust options for Bochs\n"));
10875 }
10876
10877 if(!hasPCI) {
10878 KdPrint2((PRINT_PREFIX "old slow machine, adjust timings\n"));
10879 // old slow machine, adjust timings (us)
10881 g_opt_WaitBusyCount = 20000;
10882 g_opt_WaitBusyDelay = 150;
10883 g_opt_WaitDrqDelay = 100;
10885 g_opt_MaxIsrWait = 200;
10887 }
10890 }
10891 if(CPU_num > 1) {
10893 }
10894
10905 } // end !re-enter
10906
10907 // Look for legacy ISA-bridged PCI IDE controller (onboard)
10908 KdPrint2((PRINT_PREFIX "\n\nATAPI IDE: Look for legacy ISA-bridged PCI IDE controller (onboard)\n"));
10909 KdPrint2((PRINT_PREFIX "\n\nATAPI IDE: BMListLen %d\n", BMListLen));
10910 for (i=0; i <BMListLen; i++) {
10911
10912 if(!BMList[i].MasterDev) {
10913 KdPrint2((PRINT_PREFIX "!BMList[i].MasterDev\n"));
10914 break;
10915 }
10916 if(IgnoreIsaCompatiblePci) {
10917 break;
10918 }
10919 if(ReEnter) {
10920 KdPrint2((PRINT_PREFIX "ReEnter, skip it\n"));
10921 if(BMList[i].ChanInitOk & 0x03) {
10922 KdPrint2((PRINT_PREFIX "Already initialized, skip it\n"));
10923 statusToReturn =
10924 newStatus = STATUS_SUCCESS;
10925 }
10926 continue;
10927 }
10928 //BMList[i].AltInitMasterDev = (UCHAR)0xff;
10929
10930 if(GlobalConfig->AtDiskPrimaryAddressClaimed)
10931 PrimaryClaimed = TRUE;
10932 if(GlobalConfig->AtDiskSecondaryAddressClaimed)
10933 SecondaryClaimed = TRUE;
10934 pref_alt = 0;
10935
10936 if(!WinVer_WDM_Model && !PrimaryClaimed && !SecondaryClaimed && !g_Dump &&
10937 !(BMList[i].ChanInitOk & 0x80)) {
10938
10939 // We just want to claim our PCI device in compatible mode, since we shall not
10940 // tell system that we use it inside HwInitialize
10941 // Even more, we shall cheat system, that work with ISA
10942 // Note: this call may (but not 'must' or 'can') cause IO resource
10943 // reallocation and switch to native mode if HAL supports this
10944 newStatus = (ULONG)UniataClaimLegacyPCIIDE(i);
10945 // Special check for NT3.51/NT4 (not ReactOS !!!)
10946 if(((NTSTATUS)newStatus == STATUS_CONFLICTING_ADDRESSES) &&
10947 //(BMList[i].ChanInitOk & 0x40) &&
10948 /*CPU_num > 1 &&*/
10949 (WinVer_Id() <= WinVer_NT)) {
10950 // Some NT3/4 SMP (but not only) HALs cannot reallocate IO resources of
10951 // BusMaster PCI controller
10952 // Since nobody claimed Primary/Secondary yet, try init and claim them
10953 // However it is not 100% safe way, especially under ReactOS, which doesn't resolve
10954 // conflicts yet.
10955 // We relay on ScsiPort internal checks
10956 KdPrint2((PRINT_PREFIX "Can't acquire PCI part of BusMaster on SMP NT3/4 system, try init anyway.\n"));
10957 newStatus = STATUS_SUCCESS;
10958 // Prefer alternative init method (try to change Isa -> PCI in ConfigInfo first)
10959 pref_alt = 1;
10960 }
10961 if(newStatus != STATUS_SUCCESS) {
10962 KdPrint2((PRINT_PREFIX "Can't acquire PCI part of BusMaster, try as pure ISA later.\n"));
10963 break;
10964 }
10965 }
10966
10967 if(g_opt_Verbose) {
10968 _PrintNtConsole("Init standard Dual-channel PCI ATA controller:");
10969 }
10970
10971 for(alt = 0; alt < (ULONG)(WinVer_WDM_Model ? 1 : 2) ; alt++) {
10972
10973 for(c=0; c<2; c++) {
10974 // check is channel is manually excluded
10975 if(AtapiRegCheckDevValue(NULL, c, DEVNUM_NOT_SPECIFIED, L"IgnoreIsaCompatiblePci", 0)) {
10976 break;
10977 }
10978 if(c==0) {
10979 if(PrimaryClaimed) {
10980 KdPrint2((PRINT_PREFIX "Primary already claimed\n"));
10981 continue;
10982 }
10983 } else
10984 if(c==1) {
10985 if(SecondaryClaimed) {
10986 KdPrint2((PRINT_PREFIX "Secondary already claimed\n"));
10987 continue;
10988 }
10989 }
10990
10991 if((WinVer_Id() < WinVer_2k)) {
10992 // do not even try if already claimed
10993 if(c==0) {
10994 GlobalConfig->AtDiskPrimaryAddressClaimed = FALSE;
10995 } else
10996 if(c==1) {
10997 GlobalConfig->AtDiskSecondaryAddressClaimed = FALSE;
10998 }
10999 }
11000 if(!WinVer_WDM_Model) {
11001 hwInitializationData.comm.HwFindAdapter = UniataFindBusMasterController;
11002 } else {
11003 // in WDM model things are different....
11004 hwInitializationData.comm.HwFindAdapter = (c == 0) ?
11006 }
11007 hwInitializationData.comm.NumberOfAccessRanges = 6;
11008 hwInitializationData.comm.AdapterInterfaceType = Isa;
11009
11010 if(!WinVer_WDM_Model) {
11011 BMList[i].channel = (UCHAR)c;
11012 }
11013
11014 KdPrint2((PRINT_PREFIX "Try init channel %d, method %d\n", c, alt));
11015 newStatus = ScsiPortInitialize(DriverObject,
11016 Argument2,
11017 &hwInitializationData.comm,
11018 UlongToPtr(i | ((alt ^ pref_alt) ? 0x80000000 : 0)));
11019 KdPrint2((PRINT_PREFIX "ScsiPortInitialize Status %#x\n", newStatus));
11020 if (newStatus < statusToReturn) {
11021 statusToReturn = newStatus;
11022 }
11023 if (newStatus == STATUS_SUCCESS) {
11024 if(WinVer_Id() < WinVer_2k) {
11025 // This should be done in HwInitialize under w2k+ to ensure that
11026 // channel is actually initialized
11027 BMList[i].ChanInitOk |= 0x01 << c;
11028 } else {
11029 if(BMList[i].ChanInitOk & (0x01 << c)) {
11030 KdPrint2((PRINT_PREFIX "HwInit passed\n"));
11031 }
11032 }
11033/*
11034 if(BMList[i].MasterDev && (WinVer_Id() > WinVer_NT)) {
11035 c = 1; // this will break our for()
11036 BMList[i].ChanInitOk |= 0x01 << c;
11037 }
11038*/
11039 }
11040 }
11041/* if(WinVer_Id() >= WinVer_2k) {
11042 // the following didn't work under higher OSes,
11043 // until we move setting of FLAGS to HwInit
11044 KdPrint2((PRINT_PREFIX "make still one attempt\n"));
11045 continue;
11046 }*/
11047 if(BMList[i].ChanInitOk & 0x03) {
11048 // Under NT we receive status immediately, so
11049 // we can omit alternative init method if STATUS_SUCCESS returned.
11050 // Under w2k+ we relay on flags, set in HwInitialize.
11051 KdPrint2((PRINT_PREFIX "Ok, no more retries required\n"));
11052 break;
11053 } else
11054 if(WinVer_Id() >= WinVer_2k) {
11055 // try AltInit if HwInit was not called immediately under w2k+
11056 KdPrint2((PRINT_PREFIX "make still one attempt w2k+\n"));
11057 } else {
11058 // if (WinVer_Id() == WinVer_NT) and some error occured
11059 // try alternative init method
11060 KdPrint2((PRINT_PREFIX "make still one attempt w2k+\n"));
11061 }
11062 } // for(alt...)
11063 if(g_opt_Verbose) {
11064 if(BMList[i].ChanInitOk & 0x03) {
11065 _PrintNtConsole(" OK\n");
11066 } else {
11067 _PrintNtConsole(" failed\n");
11068 }
11069 }
11070
11071 }
11072
11073/* KeBugCheckEx(0xc000000e,
11074 (i << 16) | BMList[0].ChanInitOk,
11075 c,
11076 newStatus, statusToReturn);*/
11077
11078 // Look for PCI IDE controller
11079 KdPrint2((PRINT_PREFIX "\n\nATAPI IDE: Look for PCI IDE controller\n"));
11080 KdPrint2((PRINT_PREFIX "\n\nATAPI IDE: i %d, BMListLen %d\n", i, BMListLen));
11081 for (; i <BMListLen; i++) {
11082
11083 if(IgnoreNativePci) {
11084 break;
11085 }
11086/* if(BMList[i].MasterDev)
11087 continue;*/
11088 if(g_opt_Verbose) {
11089 _PrintNtConsole("Init PCI ATA controller Vendor/Dev %4.4s//%4.4s at PCI Address %d:%d:%d",
11090 BMList[i].VendorId, BMList[i].DeviceId,
11091 BMList[i].busNumber,
11092 BMList[i].slotNumber % PCI_MAX_FUNCTION,
11093 (BMList[i].slotNumber / PCI_MAX_FUNCTION) % PCI_MAX_DEVICES);
11094 }
11095
11096 hwInitializationData.comm.HwFindAdapter = UniataFindBusMasterController;
11097 hwInitializationData.comm.NumberOfAccessRanges = 6;
11098 hwInitializationData.comm.AdapterInterfaceType = PCIBus;
11099
11100 hwInitializationData.comm.VendorId = (PVOID)BMList[i].VendorId;
11101 hwInitializationData.comm.VendorIdLength = (USHORT) BMList[i].VendorIdLength;
11102 hwInitializationData.comm.DeviceId = (PVOID)BMList[i].DeviceId;
11103 hwInitializationData.comm.DeviceIdLength = (USHORT) BMList[i].DeviceIdLength;
11104
11105 BMList[i].channel = 0/*(UCHAR)c*/;
11106
11107 KdPrint2((PRINT_PREFIX "Try init %4.4s %4.4s \n",
11108 hwInitializationData.comm.VendorId,
11109 hwInitializationData.comm.DeviceId));
11110 newStatus = ScsiPortInitialize(DriverObject,
11111 Argument2,
11112 &hwInitializationData.comm,
11113 UlongToPtr(i));
11114 KdPrint2((PRINT_PREFIX "ScsiPortInitialize Status %#x\n", newStatus));
11115 if(newStatus == (ULONG)STATUS_DEVICE_DOES_NOT_EXIST && BMList[i].NeedAltInit) {
11116 // Note: this is actually a BUG in scsiport.sys
11117 // It stops scanning PCI bus when reaches empty PCI Function inside Slot
11118 // However, this PCI Slot may have higher non-empty Functions
11119 // UniATA will perform all staff instead of ScsiPort under NT,
11120 // but for ReactOS it is better to patch ScsiPort.
11121 KdPrint2((PRINT_PREFIX "STATUS_DEVICE_DOES_NOT_EXIST, try workaround\n"));
11122 hwInitializationData.comm.AdapterInterfaceType = Isa;
11123 newStatus = ScsiPortInitialize(DriverObject,
11124 Argument2,
11125 &hwInitializationData.comm,
11126 UlongToPtr(i | 0x80000000));
11127 KdPrint2((PRINT_PREFIX "ScsiPortInitialize Status %#x (2)\n", newStatus));
11128 }
11129 if (newStatus < statusToReturn)
11130 statusToReturn = newStatus;
11131
11132 if(g_opt_Verbose) {
11133 if(newStatus == STATUS_SUCCESS) {
11134 _PrintNtConsole(" OK\n");
11135 } else {
11136 _PrintNtConsole(" failed\n");
11137 }
11138 }
11139
11140 }
11141
11142/* KeBugCheckEx(0xc000000e,
11143 i,
11144 c,
11145 newStatus, statusToReturn);*/
11146
11147 // --------------
11148
11149 hwInitializationData.comm.VendorId = 0;
11150 hwInitializationData.comm.VendorIdLength = 0;
11151 hwInitializationData.comm.DeviceId = 0;
11152 hwInitializationData.comm.DeviceIdLength = 0;
11153
11154 if(!BMListLen) {
11155 hwInitializationData.comm.SrbExtensionSize = //FIELD_OFFSET(ATA_REQ, ata);
11156 sizeof(ATA_REQ);
11157 KdPrint2((PRINT_PREFIX "using AtaReq sz %x\n", hwInitializationData.comm.SrbExtensionSize));
11158 }
11159
11160 // The adapter count is used by the find adapter routine to track how
11161 // which adapter addresses have been tested.
11162
11163 // Indicate 2 access ranges and reset FindAdapter.
11164 hwInitializationData.comm.NumberOfAccessRanges = 2;
11165 hwInitializationData.comm.HwFindAdapter = AtapiFindIsaController;
11166
11168 // Indicate ISA bustype.
11169 hwInitializationData.comm.AdapterInterfaceType = Isa;
11170 adapterCount = 0;
11171
11172 // Call initialization for ISA bustype.
11173 KdPrint2((PRINT_PREFIX "\n\nATAPI IDE: Look for ISA Controllers\n"));
11174 newStatus = ScsiPortInitialize(DriverObject,
11175 Argument2,
11176 &hwInitializationData.comm,
11177 &adapterCount);
11178 KdPrint2((PRINT_PREFIX "ScsiPortInitialize Status %#x\n", newStatus));
11179 if (newStatus < statusToReturn)
11180 statusToReturn = newStatus;
11181 }
11183 // Set up for MCA
11184 KdPrint2((PRINT_PREFIX "\n\nATAPI IDE: Look for MCA Controllers\n"));
11185 hwInitializationData.comm.AdapterInterfaceType = MicroChannel;
11186 adapterCount = 0;
11187
11188 newStatus = ScsiPortInitialize(DriverObject,
11189 Argument2,
11190 &hwInitializationData.comm,
11191 &adapterCount);
11192 KdPrint2((PRINT_PREFIX "ScsiPortInitialize Status %#x\n", newStatus));
11193 if (newStatus < statusToReturn)
11194 statusToReturn = newStatus;
11195 }
11197
11198 KdPrint2((PRINT_PREFIX "\n\nLeave UNIATA MiniPort DriverEntry with status %#x\n", statusToReturn));
11199
11200 return statusToReturn;
11201
11202} // end DriverEntry()
11203
11204
11206NTAPI
11208 IN PVOID HwDeviceExtension,
11210 )
11211{
11212 PHW_DEVICE_EXTENSION deviceExtension = (PHW_DEVICE_EXTENSION)HwDeviceExtension;
11214 PCDB cdb;
11215 PATA_REQ AtaReq = (PATA_REQ)(Srb->SrbExtension);
11216
11217 srb = &(deviceExtension->chan[GET_CHANNEL(Srb)].InternalSrb);
11218
11219 RtlZeroMemory((PCHAR) srb, sizeof(SCSI_REQUEST_BLOCK));
11220
11221 srb->PathId = (UCHAR)(Srb->PathId);
11222 srb->TargetId = (UCHAR)(Srb->TargetId);
11224 srb->Length = sizeof(SCSI_REQUEST_BLOCK);
11225
11226 // Set flags to disable synchronous negociation.
11228
11229 // Set timeout to 4 seconds.
11230 srb->TimeOutValue = 4;
11231
11232 srb->CdbLength = 6;
11233 srb->DataBuffer = &(deviceExtension->chan[GET_CHANNEL(Srb)].MechStatusData);
11235 srb->SrbExtension = AtaReq;
11236
11237 // Set CDB operation code.
11238 cdb = (PCDB)srb->Cdb;
11239 cdb->MECH_STATUS.OperationCode = SCSIOP_MECHANISM_STATUS;
11240 cdb->MECH_STATUS.AllocationLength[1] = sizeof(MECHANICAL_STATUS_INFORMATION_HEADER);
11241
11242 KdPrint2((PRINT_PREFIX " MechanismStatusSrb %#x\n", srb));
11243
11244 return srb;
11245} // end BuildMechanismStatusSrb()
11246
11247#endif //UNIATA_CORE
11248
11250NTAPI
11252 IN PVOID HwDeviceExtension,
11254 )
11255{
11256 PHW_DEVICE_EXTENSION deviceExtension = (PHW_DEVICE_EXTENSION)HwDeviceExtension;
11258 PCDB cdb;
11259 PATA_REQ AtaReq = (PATA_REQ)(Srb->SrbExtension);
11260
11261 srb = &(deviceExtension->chan[GET_CHANNEL(Srb)].InternalSrb);
11262
11263 RtlZeroMemory((PCHAR) srb, sizeof(SCSI_REQUEST_BLOCK));
11264
11265 srb->PathId = (UCHAR)(Srb->PathId);
11266 srb->TargetId = (UCHAR)(Srb->TargetId);
11268 srb->Length = sizeof(SCSI_REQUEST_BLOCK);
11269
11270 // Set flags to disable synchronous negociation.
11272
11273 // Set timeout to 2 seconds.
11274 srb->TimeOutValue = 4;
11275
11276 srb->CdbLength = 6;
11277 srb->DataBuffer = &(deviceExtension->chan[GET_CHANNEL(Srb)].MechStatusSense);
11278 srb->DataTransferLength = sizeof(SENSE_DATA);
11279 srb->SrbExtension = AtaReq;
11280
11281 // Set CDB operation code.
11282 cdb = (PCDB)srb->Cdb;
11283 cdb->CDB6INQUIRY.OperationCode = SCSIOP_REQUEST_SENSE;
11284 cdb->CDB6INQUIRY.AllocationLength = sizeof(SENSE_DATA);
11285
11286 KdPrint2((PRINT_PREFIX " RequestSenseSrb %#x\n", srb));
11287
11288 return srb;
11289} // end BuildRequestSenseSrb()
11290
11291#ifndef UNIATA_CORE
11292
11293ULONG
11294NTAPI
11296 IN PVOID HwDeviceExtension,
11297 IN PCWCH NamePrefix,
11298 IN ULONG chan,
11299 IN ULONG dev,
11300 IN PCWSTR Name,
11301 IN ULONG Default
11302 )
11303{
11304 WCHAR namex[160];
11305 ULONG val = Default;
11306
11308 HwDeviceExtension, NamePrefix, Name, val);
11309
11310 if(chan != CHAN_NOT_SPECIFIED) {
11311 swprintf(namex, L"%s\\Chan_%1.1d", NamePrefix, chan);
11313 HwDeviceExtension, namex, Name, val);
11314 if(dev != DEVNUM_NOT_SPECIFIED) {
11315 swprintf(namex, L"%s\\Chan_%1.1d\\%s", NamePrefix, chan, (dev & 0x01) ? L"Lun_1" : L"Lun_0");
11317 HwDeviceExtension, namex, Name, val);
11318 }
11319 }
11320 return val;
11321} // end AtapiRegCheckDevLunValue()
11322
11323ULONG
11324NTAPI
11327 IN PUCHAR Str,
11329 )
11330{
11331 ULONG i,j;
11332 WCHAR a;
11333
11334 for(i=0, j=0; i<Length; i++, j++) {
11335 // fix byte-order
11336 a = Str[i ^ 0x01];
11337 if(!a) {
11338 Buffer[j] = 0;
11339 return j;
11340 } else
11341 if(a == ' ') {
11342 Buffer[j] = '_';
11343 } else
11344 if((a == '_') ||
11345 (a == '#') ||
11346 (a == '\\') ||
11347 (a == '\"') ||
11348 (a == '\'') ||
11349 (a < ' ') ||
11350 (a >= 127)) {
11351 Buffer[j] = '#';
11352 j++;
11353 swprintf(Buffer+j, L"%2.2x", a);
11354 j++;
11355 } else {
11356 Buffer[j] = a;
11357 }
11358 }
11359 Buffer[j] = 0;
11360 return j;
11361} // end EncodeVendorStr()
11362
11363ULONG
11364NTAPI
11366 IN PVOID HwDeviceExtension,
11367 IN ULONG chan,
11368 IN ULONG dev,
11369 IN PCWSTR Name,
11370 IN ULONG Default
11371 )
11372{
11373 PHW_DEVICE_EXTENSION deviceExtension = (PHW_DEVICE_EXTENSION)HwDeviceExtension;
11374// WCHAR name0[11];
11375// WCHAR name1[11+4+5];
11376// WCHAR name2[11+4+4+10];
11377// WCHAR name3[11+4+4+5+20];
11378// WCHAR name3[11+4+4+5+20+1];
11379 WCHAR namex[160];
11380
11381 WCHAR namev[16];
11382 WCHAR named[16];
11383 WCHAR names[20];
11384
11385 IN ULONG VendorID;
11388 IN ULONG HwFlags;
11389
11390 ULONG val = Default;
11391
11392 KdPrint(( " Parameter %ws\n", Name));
11393
11394 if(deviceExtension) {
11395 VendorID = deviceExtension->DevID & 0xffff;
11396 DeviceID = (deviceExtension->DevID >> 16) & 0xffff;
11397 SlotNumber = deviceExtension->slotNumber;
11398 HwFlags = deviceExtension->HwFlags;
11399 } else {
11400 VendorID = 0xffff;
11401 DeviceID = 0xffff;
11402 SlotNumber = 0xffffffff;
11403 HwFlags = 0;
11404 }
11405
11407 HwDeviceExtension, L"Parameters", chan, dev, Name, val);
11408
11409 if(deviceExtension) {
11410
11411 if(HwFlags & UNIATA_SATA) {
11412 swprintf(namev, L"\\SATA");
11413 swprintf(namex, L"Parameters%s", namev);
11415 HwDeviceExtension, namex, chan, dev, Name, val);
11416 }
11417 if(HwFlags & UNIATA_AHCI) {
11418 swprintf(namev, L"\\AHCI");
11419 swprintf(namex, L"Parameters%s", namev);
11421 HwDeviceExtension, namex, chan, dev, Name, val);
11422 }
11423 if(!(HwFlags & (UNIATA_SATA | UNIATA_AHCI))) {
11424 swprintf(namev, L"\\PATA");
11425 swprintf(namex, L"Parameters%s", namev);
11427 HwDeviceExtension, namex, chan, dev, Name, val);
11428 }
11429
11430 if(deviceExtension->AdapterInterfaceType == PCIBus) {
11431 // PCI
11432 swprintf(namev, L"\\IDE_%d", deviceExtension->DevIndex);
11433 swprintf(namex, L"Parameters%s", namev);
11435 HwDeviceExtension, namex, chan, dev, Name, val);
11436
11437
11438 swprintf(namev, L"\\Ven_%4.4x", VendorID);
11439 swprintf(named, L"\\Dev_%4.4x", DeviceID);
11440 swprintf(names, L"\\Slot_%8.8x", SlotNumber);
11441
11442 swprintf(namex, L"Parameters%s", namev);
11444 HwDeviceExtension, namex, chan, dev, Name, val);
11445
11446 swprintf(namex, L"Parameters%s%s", namev, named);
11448 HwDeviceExtension, namex, chan, dev, Name, val);
11449
11450 swprintf(namex, L"Parameters%s%s%s", namev, named, names);
11452 HwDeviceExtension, namex, chan, dev, Name, val);
11453 } else
11454 if(deviceExtension->AdapterInterfaceType == Isa) {
11455 // Isa
11456 swprintf(namev, L"\\IDE_%d", deviceExtension->DevIndex+BMListLen);
11457 swprintf(namex, L"Parameters%s", namev);
11459 HwDeviceExtension, namex, chan, dev, Name, val);
11460
11461 swprintf(namev, L"\\ISA_%d", deviceExtension->DevIndex);
11462 swprintf(namex, L"Parameters%s", namev);
11464 HwDeviceExtension, namex, chan, dev, Name, val);
11465
11466 } else
11467 if(deviceExtension->AdapterInterfaceType == MicroChannel) {
11468 // MicroChannel
11469 swprintf(namev, L"\\IDE_%d", deviceExtension->DevIndex+BMListLen+IsaCount);
11470 swprintf(namex, L"Parameters%s", namev);
11472 HwDeviceExtension, namex, chan, dev, Name, val);
11473
11474 swprintf(namev, L"\\MCA_%d", deviceExtension->DevIndex);
11475 swprintf(namex, L"Parameters%s", namev);
11477 HwDeviceExtension, namex, chan, dev, Name, val);
11478
11479 }
11480 }
11481
11482 KdPrint(( " Parameter %ws = %#x\n", Name, val));
11483 return val;
11484
11485} // end AtapiRegCheckDevValue()
11486
11487/*
11488 The user must specify that Xxx is to run on the platform
11489 by setting the registry value HKEY_LOCAL_MACHINE\System\CurrentControlSet\
11490 Services\UniATA\Xxx:REG_DWORD:Zzz.
11491
11492 The user can override the global setting to enable or disable Xxx on a
11493 specific cdrom device by setting the key HKEY_LOCAL_MACHINE\System\
11494 CurrentControlSet\Services\UniATA\Parameters\Device<N>\Xxx:REG_DWORD to one or zero.
11495
11496 If this registry value does not exist or contains the value zero then
11497 the timer to check for media change does not run.
11498
11499 Arguments:
11500
11501 RegistryPath - pointer to the unicode string inside
11502 ...\CurrentControlSet\Services\UniATA
11503 DeviceNumber - The number of the HBA device object
11504
11505 Returns: Registry Key value
11506 */
11507ULONG
11508NTAPI
11510 IN PVOID HwDeviceExtension,
11511 IN PCWSTR PathSuffix,
11512 IN PCWSTR Name,
11513 IN ULONG Default
11514 )
11515{
11516#define ITEMS_TO_QUERY 2 // always 1 greater than what is searched
11517
11518// PHW_DEVICE_EXTENSION deviceExtension = (PHW_DEVICE_EXTENSION)HwDeviceExtension;
11520 LONG zero = Default;
11521
11523
11524// LONG tmp = 0;
11525 LONG doRun = Default;
11526
11528
11529 UNICODE_STRING paramPath;
11530
11531 if(g_Dump) {
11532 goto failed;
11533 }
11534
11535 // <SavedRegPath><PathSuffix> -> <Name>
11536// KdPrint(( "AtapiCheckRegValue: %ws -> %ws\n", PathSuffix, Name));
11537// KdPrint(( "AtapiCheckRegValue: RegistryPath %ws\n", RegistryPath->Buffer));
11538
11539 paramPath.Length = 0;
11540 paramPath.MaximumLength = RegistryPath->Length +
11541 (wcslen(PathSuffix)+2)*sizeof(WCHAR);
11542 paramPath.Buffer = (PWCHAR)ExAllocatePool(NonPagedPool, paramPath.MaximumLength);
11543 if(!paramPath.Buffer) {
11544 KdPrint(("AtapiCheckRegValue: couldn't allocate paramPath\n"));
11545 return Default;
11546 }
11547
11548 RtlZeroMemory(paramPath.Buffer, paramPath.MaximumLength);
11550 RtlAppendUnicodeToString(&paramPath, L"\\");
11551 RtlAppendUnicodeToString(&paramPath, REGRTL_STR_PTYPE PathSuffix);
11552
11553 // Check for the Xxx value.
11555
11556 parameters[0].Flags = RTL_QUERY_REGISTRY_DIRECT;
11557 parameters[0].Name = REGRTL_STR_PTYPE Name;
11558 parameters[0].EntryContext = &doRun;
11559 parameters[0].DefaultType = REG_DWORD;
11560 parameters[0].DefaultData = &zero;
11561 parameters[0].DefaultLength = sizeof(ULONG);
11562
11563 status = RtlQueryRegistryValues(RTL_REGISTRY_ABSOLUTE /*| RTL_REGISTRY_OPTIONAL*/,
11564 paramPath.Buffer, parameters, NULL, NULL);
11565 if(NT_SUCCESS(status)) {
11566 KdPrint(( "AtapiCheckRegValue: %ws -> %ws is %#x\n", PathSuffix, Name, doRun));
11567 }
11568
11569 ExFreePool(paramPath.Buffer);
11570
11571 if(!NT_SUCCESS(status)) {
11572failed:
11573 doRun = Default;
11574 }
11575
11576 return doRun;
11577
11578#undef ITEMS_TO_QUERY
11579
11580} // end AtapiRegCheckParameterValue()
11581
11582
11584NTAPI
11586 IN PVOID HwDeviceExtension,
11587 IN SCSI_ADAPTER_CONTROL_TYPE ControlType,
11589 )
11590{
11591 PHW_DEVICE_EXTENSION deviceExtension = (PHW_DEVICE_EXTENSION)HwDeviceExtension;
11592 PSCSI_SUPPORTED_CONTROL_TYPE_LIST pControlTypeList;
11593 ULONG numberChannels = deviceExtension->NumberChannels;
11594 ULONG c;
11596
11597 KdPrint(( "AtapiAdapterControl: %#x\n", ControlType));
11598
11599 switch(ControlType) {
11601 BOOLEAN supportedTypes[ScsiAdapterControlMax] = {
11602 TRUE, // ScsiQuerySupportedControlTypes
11603 TRUE, // ScsiStopAdapter
11604 TRUE, // ScsiRestartAdapter
11605 FALSE, // ScsiSetBootConfig
11606 FALSE // ScsiSetRunningConfig
11607 };
11608
11610 ULONG i;
11611
11612 pControlTypeList = (PSCSI_SUPPORTED_CONTROL_TYPE_LIST) Parameters;
11613
11614 if(pControlTypeList->MaxControlType < lim) {
11615 lim = pControlTypeList->MaxControlType;
11616 }
11617
11618 for(i = 0; i < lim; i++) {
11619 pControlTypeList->SupportedTypeList[i] = supportedTypes[i];
11620 }
11621
11622 break;
11623
11624 }
11625 case ScsiStopAdapter: {
11626
11627 KdPrint(( "AtapiAdapterControl: ScsiStopAdapter\n"));
11628 // Shut down all interrupts on the adapter. They'll get re-enabled
11629 // by the initialization routines.
11630 for (c = 0; c < numberChannels; c++) {
11631 AtapiResetController(deviceExtension, c);
11632 AtapiDisableInterrupts(deviceExtension, c);
11633 }
11634 if(deviceExtension->AdapterInterfaceType == PCIBus) {
11635 // we must never get here for non-PCI
11636 /*status =*/ UniataDisconnectIntr2(HwDeviceExtension);
11637 BMList[deviceExtension->DevIndex].Isr2Enable = FALSE;
11638 }
11639 break;
11640 }
11641 case ScsiRestartAdapter: {
11642
11643 KdPrint(( "AtapiAdapterControl: ScsiRestartAdapter\n"));
11644 // Enable all the interrupts on the adapter while port driver call
11645 // for power up an HBA that was shut down for power management
11646
11648 status = UniataConnectIntr2(HwDeviceExtension);
11649 if(NT_SUCCESS(status)) {
11650 for (c = 0; c < numberChannels; c++) {
11651 AtapiChipInit(HwDeviceExtension, DEVNUM_NOT_SPECIFIED, c);
11652 FindDevices(HwDeviceExtension, 0, c);
11653 AtapiEnableInterrupts(deviceExtension, c);
11654 AtapiHwInitialize__(deviceExtension, c);
11655 }
11656 if(deviceExtension->Isr2DevObj) {
11657 // we must never get here for non-PCI
11658 BMList[deviceExtension->DevIndex].Isr2Enable = TRUE;
11659 }
11660 }
11661
11662 break;
11663 }
11664
11665 default: {
11666 KdPrint(( "AtapiAdapterControl: default => return ScsiAdapterControlUnsuccessful\n"));
11668 }
11669 }
11670
11672} // end AtapiAdapterControl()
11673
11674#endif //UNIATA_CORE
11675
11676extern "C"
11678VOID
11679NTAPI
11682 );
11683
11684#define DEBUG_MSG_BUFFER_SIZE 512
11685
11686extern "C"
11687VOID
11688_cdecl
11690 PCCH DebugMessage,
11691 ...
11692 )
11693{
11694 //int len;
11695 UCHAR dbg_print_tmp_buff[DEBUG_MSG_BUFFER_SIZE];
11696// UNICODE_STRING msgBuff;
11697 va_list ap;
11698 va_start(ap, DebugMessage);
11699
11700 /*len =*/ _vsnprintf((PCHAR)&dbg_print_tmp_buff[0], DEBUG_MSG_BUFFER_SIZE-1, DebugMessage, ap);
11701
11702 dbg_print_tmp_buff[DEBUG_MSG_BUFFER_SIZE-1] = 0;
11703
11704 //DbgPrint(((PCHAR)&(dbg_print_tmp_buff[0]))); // already done in KdPrint macro
11705 HalDisplayString(dbg_print_tmp_buff);
11706
11707#ifdef _DEBUG
11708 if(g_LogToDisplay > 1) {
11710 }
11711#endif // _DEBUG
11712
11713 va_end(ap);
11714
11715} // end PrintNtConsole()
11716
unsigned char BOOLEAN
char * strncpy(char *DstString, const char *SrcString, ACPI_SIZE Count)
Definition: utclib.c:427
char * va_list
Definition: acmsvcex.h:78
#define va_end(ap)
Definition: acmsvcex.h:90
#define va_start(ap, A)
Definition: acmsvcex.h:91
struct outqueuenode * head
Definition: adnsresfilter.c:66
struct NameRec_ * Name
Definition: cdprocs.h:460
#define InterlockedIncrement
Definition: armddk.h:53
#define InterlockedExchange
Definition: armddk.h:54
#define InterlockedDecrement
Definition: armddk.h:52
UCHAR const AtaCommands48[256]
Definition: atacmd_map.h:5
UCHAR const AtaCommandFlags[256]
Definition: atacmd_map.h:25
#define MOV_DD_SWP(a, b)
Definition: atactl.cpp:27
#define MOV_DW_SWP(a, b)
Definition: atactl.cpp:20
#define DFLAGS_ATAPI_DEVICE
Definition: atapi.h:41
#define GetBaseStatus(BaseIoAddress, Status)
Definition: atapi.h:331
#define DFLAGS_SANYO_ATAPI_CHANGER
Definition: atapi.h:49
#define WaitForDrq(BaseIoAddress, Status)
Definition: atapi.h:387
#define DFLAGS_ATAPI_CHANGER
Definition: atapi.h:48
#define WriteBuffer(BaseIoAddress, Buffer, Count)
Definition: atapi.h:344
#define DFLAGS_CHANGER_INITED
Definition: atapi.h:50
#define IDE_COMMAND_GET_MEDIA_STATUS
Definition: atapi.h:116
#define ATAPI_IR_COD
Definition: atapi.h:185
#define IDE_COMMAND_ATAPI_IDENTIFY
Definition: atapi.h:110
#define IDE_COMMAND_SET_DRIVE_PARAMETERS
Definition: atapi.h:108
#define IDE_COMMAND_WRITE_DMA
Definition: atapi.h:115
#define WaitShortForDrq(BaseIoAddress, Status)
Definition: atapi.h:403
#define ReadBuffer(BaseIoAddress, Buffer, Count)
Definition: atapi.h:339
#define IDE_COMMAND_IDENTIFY
Definition: atapi.h:118
#define WaitOnBaseBusy(BaseIoAddress, Status)
Definition: atapi.h:373
#define IDE_COMMAND_WRITE_MULTIPLE
Definition: atapi.h:112
#define IDE_COMMAND_WRITE
Definition: atapi.h:105
#define IDE_COMMAND_VERIFY
Definition: atapi.h:106
#define IDE_COMMAND_READ_MULTIPLE
Definition: atapi.h:111
#define IDE_COMMAND_READ_DMA
Definition: atapi.h:114
#define IDE_COMMAND_ATAPI_PACKET
Definition: atapi.h:109
#define GetStatus(BaseIoAddress, Status)
Definition: atapi.h:328
#define DFLAGS_TAPE_DEVICE
Definition: atapi.h:42
#define IS_RDP(OperationCode)
Definition: atapi.h:453
#define DFLAGS_MEDIA_STATUS_ENABLED
Definition: atapi.h:47
#define IDE_COMMAND_ATAPI_RESET
Definition: atapi.h:102
#define IDE_COMMAND_MEDIA_EJECT
Definition: atapi.h:119
#define DFLAGS_REMOVABLE_DRIVE
Definition: atapi.h:45
#define IDE_COMMAND_SET_MULTIPLE
Definition: atapi.h:113
#define IDE_COMMAND_READ
Definition: atapi.h:104
#define WaitOnBusy(BaseIoAddress, Status)
Definition: atapi.h:359
#define DFLAGS_DEVICE_PRESENT
Definition: atapi.h:40
#define WriteBuffer2(BaseIoAddress, Buffer, Count)
Definition: atapi.h:354
#define DFLAGS_INT_DRQ
Definition: atapi.h:43
#define MAX_ERRORS
Definition: atapi.h:55
#define ReadBuffer2(BaseIoAddress, Buffer, Count)
Definition: atapi.h:349
#define AtapiSoftReset(BaseIoAddress, DeviceNumber)
Definition: atapi.h:418
struct _HW_LU_EXTENSION HW_LU_EXTENSION
struct _HW_DEVICE_EXTENSION * PHW_DEVICE_EXTENSION
struct _HW_DEVICE_EXTENSION HW_DEVICE_EXTENSION
void NTAPI InitBadBlocks(IN PHW_LU_EXTENSION LunExt)
void NTAPI ForgetBadBlocks(IN PHW_LU_EXTENSION LunExt)
bool NTAPI CheckIfBadBlock(IN PHW_LU_EXTENSION LunExt, IN ULONGLONG lba, IN ULONG count)
#define ID_CMD
Definition: helper.h:20
#define SMART_CMD
Definition: helper.h:21
struct _SENDCMDINPARAMS SENDCMDINPARAMS
#define ATAPI_ID_CMD
Definition: helper.h:19
struct _SENDCMDOUTPARAMS * PSENDCMDOUTPARAMS
struct _SENDCMDOUTPARAMS SENDCMDOUTPARAMS
struct _SENDCMDINPARAMS * PSENDCMDINPARAMS
LONG NTSTATUS
Definition: precomp.h:26
#define index(s, c)
Definition: various.h:29
#define CHAR(Char)
#define UNIATA_NO80CHK
Definition: bm_devs_decl.h:630
#define ATA_INTEL_ID
Definition: bm_devs_decl.h:184
#define NV4OFF
Definition: bm_devs_decl.h:697
#define PIO0_TIMING
Definition: bm_devs_decl.h:53
#define PRNEW
Definition: bm_devs_decl.h:646
#define NVQ
Definition: bm_devs_decl.h:698
#define PRTX
Definition: bm_devs_decl.h:647
#define CHIPTYPE_MASK
Definition: bm_devs_decl.h:620
#define SIIMIO
Definition: bm_devs_decl.h:665
#define UNIATA_SATA
Definition: bm_devs_decl.h:626
#define ATA_ACARD_ID
Definition: bm_devs_decl.h:111
#define PRG2
Definition: bm_devs_decl.h:654
#define UNIATA_AHCI
Definition: bm_devs_decl.h:629
#define NVGEN
Definition: bm_devs_decl.h:699
#define PROLD
Definition: bm_devs_decl.h:645
#define ATA_PROMISE_ID
Definition: bm_devs_decl.h:454
#define PRMIO
Definition: bm_devs_decl.h:648
#define ATA_SIS_ID
Definition: bm_devs_decl.h:521
#define I6CH2
Definition: bm_devs_decl.h:693
#define ATA_NVIDIA_ID
Definition: bm_devs_decl.h:355
#define ATA_ATI_ID
Definition: bm_devs_decl.h:147
#define UniataGetPioTiming(LunExt)
Definition: bm_devs_decl.h:56
#define I6CH
Definition: bm_devs_decl.h:692
#define SIIINTR
Definition: bm_devs_decl.h:668
#define CHIPFLAG_MASK
Definition: bm_devs_decl.h:621
#define ATA_SILICON_IMAGE_ID
Definition: bm_devs_decl.h:507
ULONG NTAPI ScsiPortInitialize(IN PVOID Argument1, IN PVOID Argument2, IN PHW_INITIALIZATION_DATA HwInitializationData, IN PVOID HwContext OPTIONAL)
Definition: scsiport.c:1133
VOID __cdecl ScsiPortNotification(IN SCSI_NOTIFICATION_TYPE NotificationType, IN PVOID HwDeviceExtension, IN ...)
Definition: scsiport.c:1324
VOID NTAPI ScsiPortLogError(IN PVOID HwDeviceExtension, IN PSCSI_REQUEST_BLOCK Srb OPTIONAL, IN UCHAR PathId, IN UCHAR TargetId, IN UCHAR Lun, IN ULONG ErrorCode, IN ULONG UniqueId)
Definition: scsiport.c:1299
VOID NTAPI ScsiPortMoveMemory(IN PVOID WriteBuffer, IN PVOID ReadBuffer, IN ULONG Length)
Definition: scsiport.c:1314
VOID NTAPI ScsiPortStallExecution(IN ULONG Delay)
Definition: scsiport.c:1489
PSCSI_REQUEST_BLOCK NTAPI ScsiPortGetSrb(IN PVOID DeviceExtension, IN UCHAR PathId, IN UCHAR TargetId, IN UCHAR Lun, IN LONG QueueTag)
Definition: scsiport.c:658
VOID NTAPI AtapiDmaInit__(IN PHW_DEVICE_EXTENSION deviceExtension, IN PHW_LU_EXTENSION LunExt)
Definition: id_dma.cpp:857
#define BM_DS0_SII_DMA_COMPLETE
Definition: bsmaster.h:160
#define ATA_AHCI_P_IX_PC
Definition: bsmaster.h:505
#define CTRFLAGS_AHCI_PM
Definition: bsmaster.h:1143
#define CHECK_INTR_CHECK
Definition: bsmaster.h:1068
UCHAR NTAPI AtapiDmaDone(IN PVOID HwDeviceExtension, IN ULONG DeviceNumber, IN ULONG lChannel, IN PSCSI_REQUEST_BLOCK Srb)
Definition: id_dma.cpp:685
#define IDX_AHCI_P_IE
Definition: bsmaster.h:685
#define REORDER_MCOST_SWITCH_RW_CD
Definition: bsmaster.h:986
#define ATA_AHCI_P_IX_HBD
Definition: bsmaster.h:513
#define IDX_BM_IO
Definition: bsmaster.h:163
#define REQ_STATE_PREPARE_TO_TRANSFER
Definition: bsmaster.h:946
#define ATA_AHCI_P_IX_DS
Definition: bsmaster.h:501
#define BM_STATUS_ERR
Definition: bsmaster.h:143
#define REQ_STATE_PROCESSING_INTR
Definition: bsmaster.h:958
ULONG BMListLen
Definition: id_probe.cpp:54
#define REQ_STATE_ATAPI_EXPECTING_DATA_INTR
Definition: bsmaster.h:952
#define ATA_AHCI_P_IX_TFE
Definition: bsmaster.h:515
VOID DDKFASTAPI AtapiWritePortEx1(IN PHW_CHANNEL chan, IN ULONGIO_PTR port, IN ULONG offs, IN UCHAR data)
ULONG NTAPI UniataFindCompatBusMasterController1(IN PVOID HwDeviceExtension, IN PVOID Context, IN PVOID BusInformation, IN PCHAR ArgumentString, IN OUT PPORT_CONFIGURATION_INFORMATION ConfigInfo, OUT PBOOLEAN Again)
Definition: id_probe.cpp:924
#define IDX_BM_DeviceSpecific1
Definition: bsmaster.h:170
#define ATA_AHCI_P_IX_DI
Definition: bsmaster.h:506
ULONG NTAPI UniataFindCompatBusMasterController2(IN PVOID HwDeviceExtension, IN PVOID Context, IN PVOID BusInformation, IN PCHAR ArgumentString, IN OUT PPORT_CONFIGURATION_INFORMATION ConfigInfo, OUT PBOOLEAN Again)
Definition: id_probe.cpp:945
#define ATA_SE_HANDSHAKE_ERR
Definition: bsmaster.h:421
#define CTRFLAGS_INTR_DISABLED
Definition: bsmaster.h:1134
#define REQ_STATE_READY_TO_TRANSFER
Definition: bsmaster.h:948
#define CTRFLAGS_DPC_REQ
Definition: bsmaster.h:1135
BOOLEAN NTAPI AtapiDmaDBPreSync(IN PVOID HwDeviceExtension, PHW_CHANNEL chan, PSCSI_REQUEST_BLOCK Srb)
Definition: id_dma.cpp:553
#define VM_BOCHS
Definition: bsmaster.h:1906
#define ATA_AHCI_CMD_PREFETCH
Definition: bsmaster.h:817
#define VM_AUTO
Definition: bsmaster.h:1901
BOOLEAN NTAPI AtapiDmaSetup(IN PVOID HwDeviceExtension, IN ULONG DeviceNumber, IN ULONG lChannel, IN PSCSI_REQUEST_BLOCK Srb, IN PUCHAR data, IN ULONG count)
Definition: id_dma.cpp:247
#define REQ_STATE_DPC_WAIT_BUSY0
Definition: bsmaster.h:964
#define REQ_STATE_DPC_WAIT_DRQ
Definition: bsmaster.h:967
#define REORDER_COST_SWITCH_RW_CD
Definition: bsmaster.h:985
#define BM_DS0_SII_DMA_ENABLE
Definition: bsmaster.h:156
ULONG IsaCount
Definition: id_probe.cpp:55
BOOLEAN NTAPI AtapiDmaDBSync(PHW_CHANNEL chan, PSCSI_REQUEST_BLOCK Srb)
Definition: id_dma.cpp:532
#define IDX_BM_DeviceSpecific0
Definition: bsmaster.h:168
#define ATA_AHCI_CMD_WRITE
Definition: bsmaster.h:816
UCHAR DDKFASTAPI AtapiReadPort1(IN PHW_CHANNEL chan, IN ULONGIO_PTR port)
#define REORDER_MCOST_SEEK_BACK_CD
Definition: bsmaster.h:987
#define VM_MAX_KNOWN
Definition: bsmaster.h:1909
#define REQ_FLAG_DMA_OPERATION
Definition: bsmaster.h:932
ULONG DDKFASTAPI AtapiReadPort4(IN PHW_CHANNEL chan, IN ULONGIO_PTR port)
#define IDX_AHCI_IS
Definition: bsmaster.h:272
ULONG NTAPI UniataFindBusMasterController(IN PVOID HwDeviceExtension, IN PVOID Context, IN PVOID BusInformation, IN PCHAR ArgumentString, IN OUT PPORT_CONFIGURATION_INFORMATION ConfigInfo, OUT PBOOLEAN Again)
Definition: id_probe.cpp:988
#define ATA_AHCI_P_IX_HBF
Definition: bsmaster.h:514
#define GetPciConfig1(offs, op)
Definition: bsmaster.h:1620
#define ATA_WAIT_IDLE
Definition: bsmaster.h:63
#define REQ_FLAG_RW_MASK
Definition: bsmaster.h:934
struct _ISR2_DEVICE_EXTENSION * PISR2_DEVICE_EXTENSION
#define REQ_STATE_ATAPI_EXPECTING_DATA_INTR2
Definition: bsmaster.h:953
#define ATA_AHCI_CMD_ATAPI
Definition: bsmaster.h:815
#define REQ_FLAG_FORCE_DOWNRATE
Definition: bsmaster.h:931
#define BM_STATUS_ACTIVE
Definition: bsmaster.h:142
VOID DDKFASTAPI AtapiWritePortEx4(IN PHW_CHANNEL chan, IN ULONGIO_PTR port, IN ULONG offs, IN ULONG data)
#define CTRFLAGS_ENABLE_INTR_REQ
Definition: bsmaster.h:1136
#define REQ_STATE_DPC_WAIT_BUSY
Definition: bsmaster.h:966
#define REQ_FLAG_WRITE
Definition: bsmaster.h:936
#define BM_DS0_SII_DMA_ERROR
Definition: bsmaster.h:159
#define ATA_AHCI_P_IX_SDB
Definition: bsmaster.h:502
#define ATA_WAIT_READY
Definition: bsmaster.h:57
#define IDX_BM_Status
Definition: bsmaster.h:169
NTSTATUS NTAPI UniataClaimLegacyPCIIDE(ULONG i)
Definition: id_probe.cpp:1939
#define CHECK_INTR_IDLE
Definition: bsmaster.h:1069
#define ChangePciConfig2(offs, _op)
Definition: bsmaster.h:1670
#define ATA_MAX_LBA28
Definition: bsmaster.h:95
#define ATA_AHCI_P_IX_IF
Definition: bsmaster.h:512
#define REQ_STATE_DPC_WAIT_BUSY1
Definition: bsmaster.h:965
#define REQ_STATE_NONE
Definition: bsmaster.h:943
#define REQ_FLAG_REORDERABLE_CMD
Definition: bsmaster.h:933
NTSTATUS NTAPI UniataConnectIntr2(IN PVOID HwDeviceExtension)
Definition: id_probe.cpp:2050
#define REQ_FLAG_FORCE_DOWNRATE_LBA48
Definition: bsmaster.h:937
union _ATA_REQ ATA_REQ
#define GEOM_STD
Definition: bsmaster.h:1149
#define ATA_AHCI_P_IX_DHR
Definition: bsmaster.h:499
#define VM_NONE
Definition: bsmaster.h:1902
#define CHECK_INTR_DETECTED
Definition: bsmaster.h:1067
#define BM_DS0_SII_IRQ
Definition: bsmaster.h:157
#define HBAFLAGS_DMA_DISABLED_LBA48
Definition: bsmaster.h:1359
#define CTRFLAGS_LBA48
Definition: bsmaster.h:1137
ULONG DDKFASTAPI AtapiReadPortEx4(IN PHW_CHANNEL chan, IN ULONGIO_PTR port, IN ULONG offs)
#define VM_QEMU
Definition: bsmaster.h:1905
#define ATA_SE_LINKSEQ_ERR
Definition: bsmaster.h:422
#define REQ_STATE_ATAPI_DO_NOTHING_INTR
Definition: bsmaster.h:954
#define ATA_AHCI_P_IX_DP
Definition: bsmaster.h:504
#define ATA_AHCI_P_IX_INF
Definition: bsmaster.h:511
#define BM_DS0_SII_DMA_SATA_IRQ
Definition: bsmaster.h:158
#define CTRFLAGS_DMA_OPERATION
Definition: bsmaster.h:1133
#define DEV_BSIZE
Definition: bsmaster.h:103
#define GET_CDEV(Srb)
Definition: bsmaster.h:1850
#define DPC_STATE_DPC
Definition: bsmaster.h:1156
#define ATA_AHCI_P_IX_PRC
Definition: bsmaster.h:508
#define IDX_BM_IO_SZ
Definition: bsmaster.h:165
#define CTRFLAGS_PERMANENT
Definition: bsmaster.h:1146
#define ATA_SE_UNKNOWN_FIS
Definition: bsmaster.h:424
#define REQ_STATE_EXPECTING_INTR
Definition: bsmaster.h:950
VOID DDKFASTAPI AtapiWritePort4(IN PHW_CHANNEL chan, IN ULONGIO_PTR port, IN ULONG data)
#define REQ_STATE_ATAPI_EXPECTING_CMD_INTR
Definition: bsmaster.h:951
#define GET_CHANNEL(Srb)
Definition: bsmaster.h:1847
union _ATA_REQ * PATA_REQ
#define ATA_AHCI_P_IX_UF
Definition: bsmaster.h:503
#define IDX_BM_Command
Definition: bsmaster.h:167
BOOLEAN NTAPI AtapiDmaPioSync(PVOID HwDeviceExtension, PSCSI_REQUEST_BLOCK Srb, PUCHAR data, ULONG count)
Definition: id_dma.cpp:467
#define ATA_MAX_IOLBA28
Definition: bsmaster.h:94
#define CMD_ACTION_PREPARE
Definition: bsmaster.h:974
#define GEOM_AUTO
Definition: bsmaster.h:1148
#define ATA_AHCI_P_IX_CPD
Definition: bsmaster.h:516
#define REQ_STATE_EARLY_INTR
Definition: bsmaster.h:956
PDRIVER_OBJECT SavedDriverObject
Definition: id_probe.cpp:69
#define REQ_STATE_PREPARE_TO_NEXT
Definition: bsmaster.h:947
#define ATA_SE_TRANSPORT_ERR
Definition: bsmaster.h:423
#define ATA_WAIT_BASE_READY
Definition: bsmaster.h:62
#define IDX_AHCI_P_CI
Definition: bsmaster.h:686
#define REQ_STATE_TRANSFER_COMPLETE
Definition: bsmaster.h:971
#define ATA_IMMEDIATE
Definition: bsmaster.h:55
#define BM_STATUS_INTR
Definition: bsmaster.h:144
#define VM_VBOX
Definition: bsmaster.h:1903
#define GetPciConfig2(offs, op)
Definition: bsmaster.h:1649
#define REQ_STATE_DPC_WAIT_DRQ_ERR
Definition: bsmaster.h:969
VOID DDKFASTAPI AtapiWritePort1(IN PHW_CHANNEL chan, IN ULONGIO_PTR port, IN UCHAR data)
#define REQ_STATE_QUEUED
Definition: bsmaster.h:944
#define CTRFLAGS_NO_SLAVE
Definition: bsmaster.h:1139
#define CHECK_INTR_ACTIVE
Definition: bsmaster.h:1066
#define DPC_STATE_ISR
Definition: bsmaster.h:1155
#define REQ_STATE_DPC_WAIT_DRQ0
Definition: bsmaster.h:968
VOID NTAPI AtapiDmaReinit(IN PHW_DEVICE_EXTENSION deviceExtension, IN PHW_LU_EXTENSION LunExt, IN PATA_REQ AtaReq)
Definition: id_dma.cpp:754
NTSTATUS NTAPI UniataDisconnectIntr2(IN PVOID HwDeviceExtension)
Definition: id_probe.cpp:2172
#define IDX_SATA_SStatus
Definition: bsmaster.h:457
#define BM_COMMAND_START_STOP
Definition: bsmaster.h:150
UCHAR DDKFASTAPI AtapiReadPortEx1(IN PHW_CHANNEL chan, IN ULONGIO_PTR port, IN ULONG offs)
#define GEOM_UNIATA
Definition: bsmaster.h:1150
#define REQ_STATE_DPC_INTR_REQ
Definition: bsmaster.h:960
USHORT DDKFASTAPI AtapiReadPort2(IN PHW_CHANNEL chan, IN ULONGIO_PTR port)
#define REQ_FLAG_READ
Definition: bsmaster.h:935
BOOLEAN NTAPI AtapiChipInit(IN PVOID HwDeviceExtension, IN ULONG DeviceNumber, IN ULONG c)
Definition: id_init.cpp:1879
#define GetDmaStatus(de, c)
Definition: bsmaster.h:1711
#define GEOM_ORIG
Definition: bsmaster.h:1151
#define SetPciConfig1(offs, op)
Definition: bsmaster.h:1630
VOID NTAPI AtapiDmaStart(IN PVOID HwDeviceExtension, IN ULONG DeviceNumber, IN ULONG lChannel, IN PSCSI_REQUEST_BLOCK Srb)
Definition: id_dma.cpp:588
#define ATA_AHCI_P_IX_PS
Definition: bsmaster.h:500
#define CTRFLAGS_DMA_RO
Definition: bsmaster.h:1132
#define CMD_ACTION_EXEC
Definition: bsmaster.h:975
VOID NTAPI UniataEnumBusMasterController(IN PVOID DriverObject, PVOID Argument2)
Definition: id_probe.cpp:245
#define MAX_RETRIES
Definition: bsmaster.h:72
#define CMD_ACTION_ALL
Definition: bsmaster.h:976
#define ATA_WAIT_INTR
Definition: bsmaster.h:56
PBUSMASTER_CONTROLLER_INFORMATION BMList
Definition: id_probe.cpp:53
#define ATA_AHCI_P_IX_OF
Definition: bsmaster.h:510
#define DPC_STATE_TIMER
Definition: bsmaster.h:1157
#define CTRFLAGS_DMA_ACTIVE
Definition: bsmaster.h:1131
_In_ PSCSI_REQUEST_BLOCK Srb
Definition: cdrom.h:989
#define SCSISTAT_CHECK_CONDITION
Definition: cdrw_hw.h:1079
#define COMMUNICATION_DEVICE
Definition: cdrw_hw.h:1153
#define SCSIOP_MODE_SENSE10
Definition: cdrw_hw.h:946
struct _INQUIRYDATA * PINQUIRYDATA
#define SCSI_SENSE_NO_SENSE
Definition: cdrw_hw.h:1187
#define SCSIOP_READ_CD
Definition: cdrw_hw.h:967
struct _MODE_POWER_CONDITION_PAGE * PMODE_POWER_CONDITION_PAGE
#define SCSIOP_WRITE_CD
Definition: cdrw_hw.h:907
#define IOCTL_SCSI_MINIPORT_SAVE_ATTRIBUTE_VALUES
Definition: cdrw_hw.h:1465
#define SCSIOP_INQUIRY
Definition: cdrw_hw.h:888
#define IOCTL_SCSI_MINIPORT_READ_SMART_ATTRIBS
Definition: cdrw_hw.h:1459
#define SCSIOP_REQUEST_SENSE
Definition: cdrw_hw.h:870
struct _MODE_CACHING_PAGE * PMODE_CACHING_PAGE
#define SCSIOP_TEST_UNIT_READY
Definition: cdrw_hw.h:866
#define IOCTL_SCSI_MINIPORT_DISABLE_SMART
Definition: cdrw_hw.h:1462
#define SCSI_SENSE_DATA_PROTECT
Definition: cdrw_hw.h:1194
#define SCSI_ADSENSE_INVALID_VALUE
Definition: cdrw_hw.h:1267
#define SCSI_ADSENSE_INVALID_CDB
Definition: cdrw_hw.h:1265
struct _MODE_POWER_CONDITION_PAGE MODE_POWER_CONDITION_PAGE
#define SCSIOP_MEDIUM_REMOVAL
Definition: cdrw_hw.h:902
#define DIRECT_ACCESS_DEVICE
Definition: cdrw_hw.h:1144
#define SCSI_SENSE_MEDIUM_ERROR
Definition: cdrw_hw.h:1190
struct _SENSE_DATA * PSENSE_DATA
struct _MODE_CACHING_PAGE MODE_CACHING_PAGE
#define IOCTL_SCSI_MINIPORT_ENABLE_DISABLE_AUTOSAVE
Definition: cdrw_hw.h:1464
struct _MECHANICAL_STATUS_INFORMATION_HEADER MECHANICAL_STATUS_INFORMATION_HEADER
#define MODE_PAGE_CACHING
Definition: cdrw_hw.h:846
#define READ_ONLY_DIRECT_ACCESS_DEVICE
Definition: cdrw_hw.h:1149
#define SCSIOP_VERIFY12
Definition: cdrw_hw.h:962
#define SCSI_ADSENSE_MEDIA_STATE
Definition: cdrw_hw.h:1292
#define SCSIOP_READ_CAPACITY
Definition: cdrw_hw.h:904
#define SCSIOP_FLUSH_BUFFER
Definition: cdrw_hw.h:886
#define SCSIOP_RECEIVE
Definition: cdrw_hw.h:875
#define SCSIOP_WRITE
Definition: cdrw_hw.h:906
#define SCSIOP_MECHANISM_STATUS
Definition: cdrw_hw.h:966
#define IOCTL_SCSI_MINIPORT_IDENTIFY
Definition: cdrw_hw.h:1458
struct _SENSE_DATA SENSE_DATA
#define SCSIOP_VERIFY
Definition: cdrw_hw.h:912
#define SCSI_SENSEQ_SCSI_BUS
Definition: cdrw_hw.h:1402
#define IOCTL_SCSI_MINIPORT_EXECUTE_OFFLINE_DIAGS
Definition: cdrw_hw.h:1466
#define SCSIOP_READ12
Definition: cdrw_hw.h:956
#define SCSI_SENSEQ_END_OF_MEDIUM
Definition: cdrw_hw.h:1414
#define SCSI_SENSE_ILLEGAL_REQUEST
Definition: cdrw_hw.h:1192
#define IOCTL_SCSI_MINIPORT_READ_SMART_THRESHOLDS
Definition: cdrw_hw.h:1460
#define IOCTL_SCSI_MINIPORT_ENABLE_SMART
Definition: cdrw_hw.h:1461
#define SCSIOP_MODE_SENSE
Definition: cdrw_hw.h:896
#define SCSI_SENSE_UNIT_ATTENTION
Definition: cdrw_hw.h:1193
#define SCSIOP_WRITE12
Definition: cdrw_hw.h:957
#define SCSI_ADSENSE_NO_MEDIA_IN_DEVICE
Definition: cdrw_hw.h:1221
#define IOCTL_SCSI_MINIPORT_RETURN_STATUS
Definition: cdrw_hw.h:1463
#define SCSI_SENSEQ_PARAM_INVALID_VALUE
Definition: cdrw_hw.h:1360
#define SCSI_ADSENSE_MEDIUM_CHANGED
Definition: cdrw_hw.h:1288
#define MODE_PAGE_POWER_CONDITION
Definition: cdrw_hw.h:850
#define IOCTL_SCSI_MINIPORT_SMART_VERSION
Definition: cdrw_hw.h:1457
#define SCSIOP_READ_CD_MSF
Definition: cdrw_hw.h:964
union _CDB * PCDB
#define MODE_DSP_WRITE_PROTECT
Definition: cdrw_hw.h:2523
#define SCSIOP_SEND
Definition: cdrw_hw.h:878
#define SCSIOP_START_STOP_UNIT
Definition: cdrw_hw.h:897
#define SCSI_SENSE_BLANK_CHECK
Definition: cdrw_hw.h:1195
#define SCSI_SENSE_HARDWARE_ERROR
Definition: cdrw_hw.h:1191
struct _MODE_PARAMETER_HEADER * PMODE_PARAMETER_HEADER
#define SCSI_SENSE_RECOVERED_ERROR
Definition: cdrw_hw.h:1188
#define SCSIOP_MODE_SELECT10
Definition: cdrw_hw.h:943
#define SCSIOP_READ
Definition: cdrw_hw.h:905
#define SCSIOP_MODE_SELECT
Definition: cdrw_hw.h:891
#define SCSI_SENSE_NOT_READY
Definition: cdrw_hw.h:1189
#define SCSI_SENSE_ABORTED_COMMAND
Definition: cdrw_hw.h:1198
#define SCSI_ADSENSE_BUS_RESET
Definition: cdrw_hw.h:1289
#define SCSIOP_SYNCHRONIZE_CACHE
Definition: cdrw_hw.h:918
Definition: bufpool.h:45
_In_ ULONG _In_ BOOLEAN _In_ ULONG _In_ UCHAR _In_ UCHAR _In_ UCHAR Lun
Definition: classpnp.h:1315
_In_ ULONG _In_ BOOLEAN _In_ ULONG _In_ UCHAR PathId
Definition: classpnp.h:1313
_In_ PVOID Argument2
Definition: classpnp.h:721
_In_ ULONG _In_ BOOLEAN _In_ ULONG _In_ UCHAR _In_ UCHAR TargetId
Definition: classpnp.h:1314
_In_ PCHAR _In_ ULONG DeviceNumber
Definition: classpnp.h:1230
GLUquadricObj * cylinder
Definition: cylfrac.c:44
UINT sectorCount[1]
Definition: diskio.c:16
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
#define CI(cs)
Definition: fontdlg.c:68
MMRESULT FindDevices()
Definition: utils.c:159
#define swprintf
Definition: precomp.h:40
DRIVER_INITIALIZE DriverEntry
Definition: condrv.c:21
NTSTATUS NTAPI CompleteRequest(IN PIRP Irp, IN NTSTATUS Status, IN ULONG_PTR Information)
Definition: dispatch.c:19
#define DDKFASTAPI
Definition: config.h:144
#define REGRTL_STR_PTYPE
Definition: config.h:105
#define CRNT_ILK_PTYPE
Definition: config.h:104
#define UlongToPtr(u)
Definition: config.h:106
#define CRNT_ILK_TYPE
Definition: config.h:103
#define ULONGIO_PTR
Definition: config.h:102
#define MOV_SWP_DW2DD(a, b)
Definition: misc.h:131
#define MOV_QD_SWP(a, b)
Definition: misc.h:63
#define SCSIOP_READ16
Definition: scsi.h:914
#define SCSIOP_REPORT_LUNS
Definition: scsi.h:921
#define SCSIOP_SA_READ_CAPACITY16
Definition: scsi.h:919
#define StartStop_Power_Sleep
Definition: scsi.h:409
#define SCSIOP_SERVICE_ACTION16
Definition: scsi.h:917
#define IOCTL_SCSI_MINIPORT_WRITE_SMART_LOG
Definition: scsi.h:1421
#define SCSIOP_VERIFY16
Definition: scsi.h:916
#define StartStop_Power_Idle
Definition: scsi.h:407
struct _REPORT_LUNS_INFO_HDR * PREPORT_LUNS_INFO_HDR
#define IOCTL_SCSI_MINIPORT_READ_SMART_LOG
Definition: scsi.h:1420
#define IOCTL_SCSI_MINIPORT_ENABLE_DISABLE_AUTO_OFFLINE
Definition: scsi.h:1419
#define StartStop_Power_Standby
Definition: scsi.h:408
#define SCSIOP_WRITE16
Definition: scsi.h:915
struct _SCSI_REQUEST_BLOCK SCSI_REQUEST_BLOCK
BOOLEAN(NTAPI * PHW_INTERRUPT)(IN PVOID DeviceExtension)
Definition: srb.h:450
@ ScsiRestartAdapter
Definition: srb.h:179
@ ScsiQuerySupportedControlTypes
Definition: srb.h:177
@ ScsiAdapterControlMax
Definition: srb.h:182
@ ScsiStopAdapter
Definition: srb.h:178
#define SRB_FUNCTION_RESET_DEVICE
Definition: srb.h:327
#define SRB_STATUS_BUS_RESET
Definition: srb.h:353
#define SRB_FUNCTION_RESET_LOGICAL_UNIT
Definition: srb.h:334
@ ScsiAdapterControlSuccess
Definition: srb.h:191
@ ScsiAdapterControlUnsuccessful
Definition: srb.h:192
VOID(NTAPI * PHW_TIMER)(IN PVOID DeviceExtension)
Definition: srb.h:456
#define SRB_FUNCTION_IO_CONTROL
Definition: srb.h:317
enum _SCSI_ADAPTER_CONTROL_TYPE SCSI_ADAPTER_CONTROL_TYPE
enum _SCSI_ADAPTER_CONTROL_STATUS SCSI_ADAPTER_CONTROL_STATUS
#define SRB_FUNCTION_EXECUTE_SCSI
Definition: srb.h:315
#define SRB_STATUS_DATA_OVERRUN
Definition: srb.h:357
#define SRB_FLAGS_DATA_OUT
Definition: srb.h:401
#define SRB_STATUS_ABORTED
Definition: srb.h:342
#define SRB_STATUS_PENDING
Definition: srb.h:340
#define SP_BAD_FW_WARNING
Definition: srb.h:512
struct _SCSI_SUPPORTED_CONTROL_TYPE_LIST * PSCSI_SUPPORTED_CONTROL_TYPE_LIST
#define SRB_FUNCTION_RESET_BUS
Definition: srb.h:326
#define SRB_FUNCTION_FLUSH
Definition: srb.h:323
BOOLEAN(NTAPI * PHW_STARTIO)(IN PVOID DeviceExtension, IN PSCSI_REQUEST_BLOCK Srb)
Definition: srb.h:443
#define SP_INTERNAL_ADAPTER_ERROR
Definition: srb.h:509
#define SRB_STATUS_TIMEOUT
Definition: srb.h:349
#define SRB_FUNCTION_SHUTDOWN
Definition: srb.h:322
BOOLEAN(NTAPI * PHW_RESET_BUS)(IN PVOID DeviceExtension, IN ULONG PathId)
Definition: srb.h:479
#define SRB_STATUS_AUTOSENSE_VALID
Definition: srb.h:387
#define SRB_FLAGS_DATA_IN
Definition: srb.h:400
#define SRB_STATUS_ERROR
Definition: srb.h:344
#define SRB_STATUS_ABORT_FAILED
Definition: srb.h:343
#define SRB_STATUS_SELECTION_TIMEOUT
Definition: srb.h:350
SCSI_ADAPTER_CONTROL_STATUS(NTAPI * PHW_ADAPTER_CONTROL)(IN PVOID DeviceExtension, IN SCSI_ADAPTER_CONTROL_TYPE ControlType, IN PVOID Parameters)
Definition: srb.h:494
#define SRB_FLAGS_DISABLE_SYNCH_TRANSFER
Definition: srb.h:397
@ ResetDetected
Definition: srb.h:534
@ RequestTimerCall
Definition: srb.h:537
@ CallEnableInterrupts
Definition: srb.h:536
@ CallDisableInterrupts
Definition: srb.h:535
@ RequestComplete
Definition: srb.h:531
@ NextRequest
Definition: srb.h:532
@ NextLuRequest
Definition: srb.h:533
#define SRB_STATUS_BUSY
Definition: srb.h:345
#define SRB_STATUS_SUCCESS
Definition: srb.h:341
BOOLEAN(NTAPI * PHW_INITIALIZE)(IN PVOID DeviceExtension)
Definition: srb.h:437
#define SRB_STATUS_INVALID_REQUEST
Definition: srb.h:346
#define SRB_FUNCTION_ABORT_COMMAND
Definition: srb.h:324
#define KdPrint(x)
Definition: env_spec_w32.h:288
UNICODE_STRING * PUNICODE_STRING
Definition: env_spec_w32.h:373
#define KdDump(a, b)
Definition: env_spec_w32.h:312
NTSTATUS RtlAppendUnicodeToString(IN PUNICODE_STRING Str1, IN PWSTR Str2)
Definition: string_lib.cpp:62
#define KeQuerySystemTime(t)
Definition: env_spec_w32.h:570
#define KeGetCurrentIrql()
Definition: env_spec_w32.h:706
#define ExFreePool(addr)
Definition: env_spec_w32.h:352
#define NonPagedPool
Definition: env_spec_w32.h:307
#define DISPATCH_LEVEL
Definition: env_spec_w32.h:696
#define BrutePoint()
Definition: env_spec_w32.h:504
IN PFCB IN PCCB IN TYPE_OF_OPEN IN BOOLEAN IN BOOLEAN TopLevel
Definition: fatprocs.h:2417
#define ExAllocatePool(type, size)
Definition: fbtusb.h:44
NTSTATUS CrNtInit(IN PDRIVER_OBJECT DriverObject, IN PUNICODE_STRING RegistryPath)
#define WinVer_2k
Definition: CrossNt.h:114
ULONG BuildNumber
Definition: ros_glue.cpp:6
#define WinVer_Id()
Definition: CrossNt.h:109
#define WinVer_NT
Definition: CrossNt.h:112
ULONG MajorVersion
Definition: ros_glue.cpp:4
ULONG MinorVersion
Definition: ros_glue.cpp:5
@ NoRetry
Definition: fxpkgpnp.hpp:202
Status
Definition: gdiplustypes.h:25
GLuint GLuint GLsizei count
Definition: gl.h:1545
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
Definition: gl.h:1950
GLdouble GLdouble t
Definition: gl.h:2047
GLuint GLuint * names
Definition: glext.h:11545
const GLubyte * c
Definition: glext.h:8905
GLuint index
Definition: glext.h:6031
GLenum GLint GLuint mask
Definition: glext.h:6028
GLbitfield flags
Definition: glext.h:7161
GLuint GLfloat * val
Definition: glext.h:7180
GLenum GLsizei len
Definition: glext.h:6722
GLboolean GLboolean GLboolean GLboolean a
Definition: glext.h:6204
GLintptr offset
Definition: glext.h:5920
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint GLint GLint j
Definition: glfuncs.h:250
#define IDE_STATUS_WRONG
Definition: hwide.h:121
#define IDE_DC_USE_HOB
Definition: hwide.h:141
#define IDX_IO1_o_BlockNumber
Definition: hwide.h:56
#define IDX_ATAPI_IO1_o_Command
Definition: hwide.h:103
#define IDX_IO1_o_CylinderHigh
Definition: hwide.h:58
#define IDE_STATUS_INDEX
Definition: hwide.h:111
#define IDE_STATUS_DRDY
Definition: hwide.h:117
#define IDX_ATAPI_IO1_i_InterruptReason
Definition: hwide.h:89
#define IDE_ERROR_END_OF_MEDIA
Definition: hwide.h:154
#define ATAPI_MAGIC_MSB
Definition: hwide.h:287
#define IDX_ATAPI_IO1_o_ByteCountHigh
Definition: hwide.h:101
#define IDX_IO1_i_BlockNumber
Definition: hwide.h:44
#define IDE_USE_LBA
Definition: hwide.h:133
#define IDE_STATUS_BUSY
Definition: hwide.h:119
#define IDE_STATUS_ERROR
Definition: hwide.h:110
#define IDE_STATUS_SUCCESS
Definition: hwide.h:109
#define IDX_ATAPI_IO1_i_ByteCountHigh
Definition: hwide.h:92
#define IDE_STATUS_MASK
Definition: hwide.h:122
#define IDE_DRIVE_SELECT_1
Definition: hwide.h:130
#define IDX_IO1_o_Feature
Definition: hwide.h:54
#define IDE_DC_RESET_CONTROLLER
Definition: hwide.h:139
#define IDX_IO1_i_Status
Definition: hwide.h:48
#define IDX_IO1_i_DriveSelect
Definition: hwide.h:47
#define IDE_ERROR_ILLEGAL_LENGTH
Definition: hwide.h:156
#define IDE_STATUS_DRQ
Definition: hwide.h:113
#define IDE_ERROR_COMMAND_ABORTED
Definition: hwide.h:153
#define IDX_IO1_i_CylinderLow
Definition: hwide.h:45
#define ATA_PIO
Definition: hwide.h:161
#define IDE_DRIVE_1
Definition: hwide.h:128
#define IDX_ATAPI_IO1_o_ByteCountLow
Definition: hwide.h:100
#define IDE_ERROR_MEDIA_CHANGE
Definition: hwide.h:150
#define IDX_ATAPI_IO1_i_ByteCountLow
Definition: hwide.h:91
#define IDE_ERROR_MEDIA_CHANGE_REQ
Definition: hwide.h:152
#define IDX_IO1_i_CylinderHigh
Definition: hwide.h:46
#define IDE_DC_A_4BIT
Definition: hwide.h:140
#define IDE_DRIVE_SELECT_2
Definition: hwide.h:131
#define IDE_STATUS_IDLE
Definition: hwide.h:118
#define IDX_IO1_o_DriveSelect
Definition: hwide.h:59
#define IDX_IO1_o_Command
Definition: hwide.h:60
#define IDE_ERROR_DATA_ERROR
Definition: hwide.h:149
#define IDX_ATAPI_IO1_o_Feature
Definition: hwide.h:97
#define IDE_STATUS_DSC
Definition: hwide.h:114
#define IDX_IO1_i_Error
Definition: hwide.h:42
#define IDE_DC_DISABLE_INTERRUPTS
Definition: hwide.h:138
#define IDE_DC_REENABLE_CONTROLLER
Definition: hwide.h:142
#define IDE_ERROR_ID_NOT_FOUND
Definition: hwide.h:151
#define IDX_IO2_o_Control
Definition: hwide.h:62
#define IDE_ERROR_BAD_BLOCK
Definition: hwide.h:148
#define IDE_DRIVE_2
Definition: hwide.h:129
#define IDX_IO1_o_BlockCount
Definition: hwide.h:55
#define IDX_IO1_o_CylinderLow
Definition: hwide.h:57
#define IDX_ATAPI_IO1_i_Error
Definition: hwide.h:88
#define IDX_IO1_i_Data
Definition: hwide.h:41
#define ATAPI_MAGIC_LSB
Definition: hwide.h:286
@ PCIBus
Definition: hwresource.cpp:142
@ MicroChannel
Definition: hwresource.cpp:140
@ Isa
Definition: hwresource.cpp:138
RETTYPE_XXableInterrupts NTAPI AtapiEnableInterrupts__(IN PVOID HwDeviceExtension)
Definition: id_ata.cpp:4333
#define RETVAL_XXableInterrupts
Definition: id_ata.cpp:160
LONG NTAPI AtaPio2Mode(LONG pio)
Definition: id_ata.cpp:1205
NTHALAPI VOID NTAPI HalDisplayString(PUCHAR String)
VOID NTAPI AtapiCallBack_X(IN PVOID HwDeviceExtension)
Definition: id_ata.cpp:4007
BOOLEAN WinVer_WDM_Model
Definition: id_ata.cpp:112
ULONG NTAPI AtapiRegCheckDevValue(IN PVOID HwDeviceExtension, IN ULONG chan, IN ULONG dev, IN PCWSTR Name, IN ULONG Default)
Definition: id_ata.cpp:11365
BOOLEAN g_opt_AtapiNoDma
Definition: id_ata.cpp:101
BOOLEAN NTAPI AtapiResetController__(IN PVOID HwDeviceExtension, IN ULONG PathId, IN UCHAR CompleteType)
Definition: id_ata.cpp:2422
BOOLEAN NTAPI AtapiInterrupt2(IN PKINTERRUPT Interrupt, IN PVOID Isr2HwDeviceExtension)
Definition: id_ata.cpp:4192
LONGLONG g_Perf
Definition: id_ata.cpp:80
VOID NTAPI AtapiQueueTimerDpc(IN PVOID HwDeviceExtension, IN ULONG lChannel, IN PHW_TIMER HwScsiTimer, IN ULONG MiniportTimerValue)
Definition: id_ata.cpp:1378
ULONG NTAPI IdeBuildSenseBuffer(IN PVOID HwDeviceExtension, IN PSCSI_REQUEST_BLOCK Srb)
Definition: id_ata.cpp:9145
#define SetCheckPoint(cp)
Definition: id_ata.cpp:8228
UCHAR DDKFASTAPI SelectDrive(IN PHW_CHANNEL chan, IN ULONG DeviceNumber)
Definition: id_ata.cpp:621
BOOLEAN NTAPI AtapiStartIo__(IN PVOID HwDeviceExtension, IN PSCSI_REQUEST_BLOCK Srb, IN BOOLEAN TopLevel)
Definition: id_ata.cpp:9288
ULONG NTAPI AtapiSendCommand(IN PVOID HwDeviceExtension, IN PSCSI_REQUEST_BLOCK Srb, IN ULONG CmdAction)
Definition: id_ata.cpp:7377
#define RESET_COMPLETE_CURRENT
Definition: id_ata.cpp:143
ULONG g_WaitBusyInISR
Definition: id_ata.cpp:87
BOOLEAN NTAPI AtapiRegGetStringParameterValue(IN PWSTR RegistryPath, IN PWSTR Name, IN PWCHAR Str, IN ULONG MaxLen)
Definition: id_ata.cpp:198
static const CHAR ver_string[]
Definition: id_ata.cpp:65
#define AtapiWritePortExN_template(_type, _Type, sz)
Definition: id_ata.cpp:297
ULONG g_opt_WaitBusyCount
Definition: id_ata.cpp:90
#define AtapiReadPortBufferN_template(_type, _Type, sz)
Definition: id_ata.cpp:404
BOOLEAN g_opt_BochsDmaReadWorkaround
Definition: id_ata.cpp:102
UCHAR DDKFASTAPI UniataIsIdle(IN struct _HW_DEVICE_EXTENSION *deviceExtension, IN UCHAR Status)
Definition: id_ata.cpp:742
VOID NTAPI UniataSnapAtaRegs(IN PHW_CHANNEL chan, IN ULONG DeviceNumber, IN OUT PIDEREGS_EX regs)
Definition: id_ata.cpp:1476
PSCSI_REQUEST_BLOCK NTAPI BuildRequestSenseSrb(IN PVOID HwDeviceExtension, IN PSCSI_REQUEST_BLOCK Srb)
Definition: id_ata.cpp:11251
ULONG g_opt_WaitBusyResetCount
Definition: id_ata.cpp:89
VOID NTAPI UniataForgetDevice(PHW_LU_EXTENSION LunExt)
Definition: id_ata.cpp:2385
ULONG NTAPI IdeReadWrite(IN PVOID HwDeviceExtension, IN PSCSI_REQUEST_BLOCK Srb, IN ULONG CmdAction)
Definition: id_ata.cpp:6905
ULONGLONG NTAPI UniAtaCalculateLBARegsBack(PHW_LU_EXTENSION LunExt, ULONGLONG lba)
Definition: id_ata.cpp:6860
UCHAR DDKFASTAPI AtapiSuckPort2(IN PHW_CHANNEL chan)
Definition: id_ata.cpp:503
LONG NTAPI AtaWmode(PIDENTIFY_DATA2 ident)
Definition: id_ata.cpp:1241
ULONGLONG NTAPI UniAtaCalculateLBARegs(PHW_LU_EXTENSION LunExt, ULONGLONG startingSector, PULONG max_bcount)
Definition: id_ata.cpp:6819
BOOLEAN NTAPI AtapiInterrupt__(IN PVOID HwDeviceExtension, IN UCHAR c)
Definition: id_ata.cpp:4981
BOOLEAN NTAPI AtapiInterrupt(IN PVOID HwDeviceExtension)
Definition: id_ata.cpp:4033
ULONG NTAPI EncodeVendorStr(OUT PWCHAR Buffer, IN PUCHAR Str, IN ULONG Length)
Definition: id_ata.cpp:11325
UCHAR DDKFASTAPI WaitOnBusyLong(IN PHW_CHANNEL chan)
Definition: id_ata.cpp:674
VOID NTAPI AtapiHwInitializeChanger(IN PVOID HwDeviceExtension, IN PSCSI_REQUEST_BLOCK Srb, IN PMECHANICAL_STATUS_INFORMATION_HEADER MechanismStatus)
Definition: id_ata.cpp:3667
#define RETTYPE_XXableInterrupts
Definition: id_ata.cpp:159
SCSI_ADAPTER_CONTROL_STATUS NTAPI AtapiAdapterControl(IN PVOID HwDeviceExtension, IN SCSI_ADAPTER_CONTROL_TYPE ControlType, IN PVOID Parameters)
Definition: id_ata.cpp:11585
ULONG NTAPI IdeSendSmartCommand(IN PVOID HwDeviceExtension, IN PSCSI_REQUEST_BLOCK Srb, IN ULONG targetId)
Definition: id_ata.cpp:6697
UCHAR DDKFASTAPI WaitOnBaseBusyLong(IN PHW_CHANNEL chan)
Definition: id_ata.cpp:718
BOOLEAN g_opt_Verbose
Definition: id_ata.cpp:110
UCHAR NTAPI AtaCommand(IN PHW_DEVICE_EXTENSION deviceExtension, IN ULONG DeviceNumber, IN ULONG lChannel, IN UCHAR command, IN USHORT cylinder, IN UCHAR head, IN UCHAR sector, IN UCHAR count, IN UCHAR feature, IN ULONG wait_flags)
Definition: id_ata.cpp:1168
ULONG CPU_num
Definition: id_ata.cpp:113
ULONG NTAPI MapError(IN PVOID HwDeviceExtension, IN PSCSI_REQUEST_BLOCK Srb)
Definition: id_ata.cpp:2951
VOID _cdecl _PrintNtConsole(PCCH DebugMessage,...)
Definition: id_ata.cpp:11689
ULONG NTAPI AtapiRegCheckParameterValue(IN PVOID HwDeviceExtension, IN PCWSTR PathSuffix, IN PCWSTR Name, IN ULONG Default)
Definition: id_ata.cpp:11509
#define AtapiReadPortExN_template(_type, _Type, sz)
Definition: id_ata.cpp:369
VOID DDKFASTAPI UniataNanoSleep(ULONG nano)
Definition: id_ata.cpp:238
ULONG NTAPI AtapiRegCheckDevLunValue(IN PVOID HwDeviceExtension, IN PCWCH NamePrefix, IN ULONG chan, IN ULONG dev, IN PCWSTR Name, IN ULONG Default)
Definition: id_ata.cpp:11295
ULONG g_opt_VirtualMachine
Definition: id_ata.cpp:105
ULONG SkipRaids
Definition: id_ata.cpp:77
BOOLEAN NTAPI AtapiCheckInterrupt__(IN PVOID HwDeviceExtension, IN UCHAR c)
Definition: id_ata.cpp:4512
UNICODE_STRING SavedRegPath
Definition: id_ata.cpp:69
BOOLEAN NTAPI AtapiResetController(IN PVOID HwDeviceExtension, IN ULONG PathId)
Definition: id_ata.cpp:2411
BOOLEAN NTAPI AtapiHwInitialize(IN PVOID HwDeviceExtension)
Definition: id_ata.cpp:3342
VOID NTAPI UniataUserDeviceReset(PHW_DEVICE_EXTENSION deviceExtension, PHW_LU_EXTENSION LunExt, ULONG lChannel)
Definition: id_ata.cpp:9198
ULONG g_opt_WaitDrqDelay
Definition: id_ata.cpp:92
BOOLEAN NTAPI AtapiStartIo(IN PVOID HwDeviceExtension, IN PSCSI_REQUEST_BLOCK Srb)
Definition: id_ata.cpp:9278
#define AtapiReadPortN_template(_type, _Type, sz)
Definition: id_ata.cpp:334
RETTYPE_XXableInterrupts NTAPI AtapiInterruptDpc(IN PVOID HwDeviceExtension)
Definition: id_ata.cpp:4295
BOOLEAN g_Dump
Definition: id_ata.cpp:108
ULONG NTAPI AtapiParseArgumentString(IN PCCH String, IN PCCH KeyWord)
Definition: id_ata.cpp:3705
ULONG g_opt_DriveSelectNanoDelay
Definition: id_ata.cpp:97
VOID NTAPI AtapiTimerDpc(IN PVOID HwDeviceExtension)
Definition: id_ata.cpp:1298
VOID NTAPI AtapiEnableInterrupts(IN PVOID HwDeviceExtension, IN ULONG c)
Definition: id_ata.cpp:4397
#define AtapiWritePortN_template(_type, _Type, sz)
Definition: id_ata.cpp:261
ULONG g_opt_WaitBusyDelay
Definition: id_ata.cpp:91
VOID UniataExpectChannelInterrupt(IN struct _HW_CHANNEL *chan, IN BOOLEAN Expecting)
Definition: id_ata.cpp:4492
LONG NTAPI AtaSAmode(PIDENTIFY_DATA2 ident)
Definition: id_ata.cpp:1277
ULONG g_opt_MaxIsrWait
Definition: id_ata.cpp:95
ULONG NTAPI IdeSendCommand(IN PVOID HwDeviceExtension, IN PSCSI_REQUEST_BLOCK Srb, IN ULONG CmdAction)
Definition: id_ata.cpp:8233
VOID NTAPI AtapiHwInitialize__(IN PHW_DEVICE_EXTENSION deviceExtension, IN ULONG lChannel)
Definition: id_ata.cpp:3378
BOOLEAN InDriverEntry
Definition: id_ata.cpp:107
BOOLEAN g_opt_AtapiSendDisableIntr
Definition: id_ata.cpp:99
VOID NTAPI AtapiDisableInterrupts(IN PVOID HwDeviceExtension, IN ULONG c)
Definition: id_ata.cpp:4457
#define DEBUG_MSG_BUFFER_SIZE
Definition: id_ata.cpp:11684
BOOLEAN g_opt_AtapiDmaRawRead
Definition: id_ata.cpp:100
BOOLEAN NTAPI SetDriveParameters(IN PVOID HwDeviceExtension, IN ULONG DeviceNumber, IN ULONG lChannel)
Definition: id_ata.cpp:2338
VOID NTAPI AtapiCallBack__(IN PVOID HwDeviceExtension, IN UCHAR lChannel)
Definition: id_ata.cpp:3872
BOOLEAN NTAPI IssueIdentify(IN PVOID HwDeviceExtension, IN ULONG DeviceNumber, IN ULONG lChannel, IN UCHAR Command, IN BOOLEAN NoSetup)
Definition: id_ata.cpp:1529
VOID NTAPI IdeMediaStatus(BOOLEAN EnableMSN, IN PVOID HwDeviceExtension, IN ULONG lChannel, IN ULONG DeviceNumber)
Definition: id_ata.cpp:9069
#define AtapiWritePortBufferN_template(_type, _Type, sz)
Definition: id_ata.cpp:449
PSCSI_REQUEST_BLOCK NTAPI BuildMechanismStatusSrb(IN PVOID HwDeviceExtension, IN PSCSI_REQUEST_BLOCK Srb)
Definition: id_ata.cpp:11207
BOOLEAN NTAPI UniataNeedQueueing(PHW_DEVICE_EXTENSION deviceExtension, PHW_CHANNEL chan, BOOLEAN TopLevel)
Definition: id_ata.cpp:9224
UCHAR NTAPI AtaCommand48(IN PHW_DEVICE_EXTENSION deviceExtension, IN ULONG DeviceNumber, IN ULONG lChannel, IN UCHAR command, IN ULONGLONG lba, IN USHORT count, IN USHORT feature, IN ULONG wait_flags)
Definition: id_ata.cpp:968
ULONG g_opt_WaitBusyLongDelay
Definition: id_ata.cpp:94
#define ITEMS_TO_QUERY
ULONG NTAPI IdeVerify(IN PVOID HwDeviceExtension, IN PSCSI_REQUEST_BLOCK Srb)
Definition: id_ata.cpp:7261
#define RESET_COMPLETE_NONE
Definition: id_ata.cpp:145
ULONG DDKFASTAPI AtapiSuckPortBuffer2(IN PHW_CHANNEL chan, IN PUSHORT Buffer, IN ULONG Count)
Definition: id_ata.cpp:531
#define RESET_COMPLETE_ALL
Definition: id_ata.cpp:144
LONG NTAPI AtaPioMode(PIDENTIFY_DATA2 ident)
Definition: id_ata.cpp:1220
VOID DDKFASTAPI AtapiHardReset(IN struct _HW_CHANNEL *chan, IN BOOLEAN DisableInterrupts, IN ULONG Delay)
Definition: id_ata.cpp:948
LONG NTAPI AtaUmode(PIDENTIFY_DATA2 ident)
Definition: id_ata.cpp:1254
WCHAR SavedRegPathBuffer[256]
Definition: id_ata.cpp:70
UCHAR DDKFASTAPI WaitForIdleLong(IN PHW_CHANNEL chan)
Definition: id_ata.cpp:772
ULONG ForceSimplex
Definition: id_ata.cpp:78
BOOLEAN hasPCI
Definition: id_ata.cpp:103
UCHAR g_foo
Definition: id_ata.cpp:118
ULONG g_PerfDt
Definition: id_ata.cpp:81
ULONG g_opt_WaitBusyLongCount
Definition: id_ata.cpp:93
static const CHAR uniata_comm_name[]
Definition: id_ata.cpp:67
VOID NTAPI UniataRemoveRequest(IN PHW_CHANNEL chan, IN PSCSI_REQUEST_BLOCK Srb)
Definition: id_queue.cpp:265
VOID NTAPI UniataQueueRequest(IN PHW_CHANNEL chan, IN PSCSI_REQUEST_BLOCK Srb)
Definition: id_queue.cpp:93
PHW_CHANNEL NTAPI UniataGetNextChannel(IN PHW_CHANNEL chan)
Definition: id_queue.cpp:376
PSCSI_REQUEST_BLOCK NTAPI UniataGetCurRequest(IN PHW_CHANNEL chan)
Definition: id_queue.cpp:358
ULONG NTAPI UniataAhciSetupFIS_H2D(IN PHW_DEVICE_EXTENSION deviceExtension, IN ULONG DeviceNumber, IN ULONG lChannel, OUT PUCHAR fis, IN UCHAR command, IN ULONGLONG lba, IN USHORT count, IN USHORT feature)
Definition: id_sata.cpp:1241
ULONG NTAPI UniataAhciWaitReady(IN PHW_CHANNEL chan, IN ULONG timeout)
Definition: id_sata.cpp:1853
UCHAR NTAPI UniataAhciStatus(IN PVOID HwDeviceExtension, IN ULONG lChannel, IN ULONG DeviceNumber)
Definition: id_sata.cpp:1131
VOID NTAPI UniataAhciSnapAtaRegs(IN PHW_CHANNEL chan, IN ULONG DeviceNumber, IN OUT PIDEREGS_EX regs)
Definition: id_sata.cpp:1216
VOID NTAPI UniataAhciReset(IN PVOID HwDeviceExtension, IN ULONG lChannel)
Definition: id_sata.cpp:1925
UCHAR NTAPI UniataAhciBeginTransaction(IN PVOID HwDeviceExtension, IN ULONG lChannel, IN ULONG DeviceNumber, IN PSCSI_REQUEST_BLOCK Srb)
Definition: id_sata.cpp:2171
UCHAR NTAPI UniataSataPhyEnable(IN PVOID HwDeviceExtension, IN ULONG lChannel, IN ULONG pm_port, IN BOOLEAN doReset)
Definition: id_sata.cpp:124
UCHAR NTAPI UniataAhciSendPIOCommand(IN PVOID HwDeviceExtension, IN ULONG lChannel, IN ULONG DeviceNumber, IN PSCSI_REQUEST_BLOCK Srb, IN PUCHAR data, IN ULONG length, IN UCHAR command, IN ULONGLONG lba, IN USHORT bcount, IN USHORT feature, IN USHORT ahci_flags, IN ULONG wait_flags, IN ULONG timeout)
Definition: id_sata.cpp:1538
BOOLEAN NTAPI UniataSataClearErr(IN PVOID HwDeviceExtension, IN ULONG lChannel, IN BOOLEAN do_connect, IN ULONG pm_port)
Definition: id_sata.cpp:186
UCHAR NTAPI UniataAhciWaitCommandReady(IN PHW_CHANNEL chan, IN ULONG timeout)
Definition: id_sata.cpp:1434
BOOLEAN NTAPI UniataAhciAbortOperation(IN PHW_CHANNEL chan)
Definition: id_sata.cpp:1765
ULONG NTAPI UniataAhciSoftReset(IN PVOID HwDeviceExtension, IN ULONG lChannel, IN ULONG DeviceNumber)
Definition: id_sata.cpp:1787
UCHAR NTAPI UniataAhciSendPIOCommandDirect(IN PVOID HwDeviceExtension, IN ULONG lChannel, IN ULONG DeviceNumber, IN PSCSI_REQUEST_BLOCK Srb, IN PIDEREGS_EX regs, IN ULONG wait_flags, IN ULONG timeout)
Definition: id_sata.cpp:1655
ULONG NTAPI UniataSataReadPort4(IN PHW_CHANNEL chan, IN ULONG io_port_ndx, IN ULONG pm_port)
Definition: id_sata.cpp:270
BOOLEAN NTAPI UniataSataEvent(IN PVOID HwDeviceExtension, IN ULONG lChannel, IN ULONG Action, IN ULONG pm_port)
Definition: id_sata.cpp:233
VOID UniataAhciSetupCmdPtr(IN OUT PATA_REQ AtaReq)
Definition: id_sata.cpp:2611
UCHAR NTAPI UniataAhciEndTransaction(IN PVOID HwDeviceExtension, IN ULONG lChannel, IN ULONG DeviceNumber, IN PSCSI_REQUEST_BLOCK Srb)
Definition: id_sata.cpp:2294
#define UNIATA_SATA_IGNORE_CONNECT
Definition: id_sata.h:61
__inline ULONG UniataAhciReadChannelPort4(IN PHW_CHANNEL chan, IN ULONG io_port_ndx)
Definition: id_sata.h:290
#define UNIATA_SATA_EVENT_ATTACH
Definition: id_sata.h:72
__inline USHORT UniAtaAhciAdjustIoFlags(IN UCHAR command, IN USHORT ahci_flags, IN ULONG fis_size, IN ULONG DeviceNumber)
Definition: id_sata.h:357
#define UNIATA_SATA_RESET_ENABLE
Definition: id_sata.h:48
__inline BOOLEAN UniataAhciChanImplemented(IN PHW_DEVICE_EXTENSION deviceExtension, IN ULONG c)
Definition: id_sata.h:415
#define UNIATA_SATA_DO_CONNECT
Definition: id_sata.h:60
__inline BOOLEAN UniataIsSATARangeAvailable(IN PHW_DEVICE_EXTENSION deviceExtension, IN ULONG lChannel)
Definition: id_sata.h:91
#define UNIATA_SATA_EVENT_DETACH
Definition: id_sata.h:73
__inline VOID UniataAhciWriteChannelPort4(IN PHW_CHANNEL chan, IN ULONG io_port_ndx, IN ULONG data)
Definition: id_sata.h:302
#define UniataAhciReadHostPort4(deviceExtension, io_port_ndx)
Definition: id_sata.h:313
_CRTIMP size_t __cdecl wcslen(_In_z_ const wchar_t *_Str)
NTSYSAPI NTSTATUS WINAPI RtlQueryRegistryValues(ULONG, PCWSTR, PRTL_QUERY_REGISTRY_TABLE, PVOID, PVOID)
PCONFIGURATION_INFORMATION NTAPI IoGetConfigurationInformation(VOID)
Returns a pointer to the I/O manager's global configuration information structure.
Definition: iorsrce.c:998
uint32_t sector
Definition: isohybrid.c:61
#define a
Definition: ke_i.h:78
#define c
Definition: ke_i.h:80
CCHAR KeNumberProcessors
Definition: krnlinit.c:35
#define REG_SZ
Definition: layer.c:22
__u16 time
Definition: mkdosfs.c:8
__u8 sectors[2]
Definition: mkdosfs.c:8
#define error(str)
Definition: mkdosfs.c:1605
#define PCHAR
Definition: match.c:90
#define ASSERT(a)
Definition: mode.c:44
INTERNETFEATURELIST feature
Definition: misc.c:1719
#define shift
Definition: input.c:1755
#define min(a, b)
Definition: monoChain.cc:55
int k
Definition: mpi.c:3369
int Count
Definition: noreturn.cpp:7
#define RTL_REGISTRY_ABSOLUTE
Definition: nt_native.h:161
#define RTL_QUERY_REGISTRY_DIRECT
Definition: nt_native.h:144
CONST WCHAR * PCWCH
Definition: ntbasedef.h:411
CONST CHAR * PCCH
Definition: ntbasedef.h:392
#define EXECUTE_OFFLINE_DIAGS
Definition: ntdddisk.h:748
#define CAP_ATAPI_ID_CMD
Definition: ntdddisk.h:662
#define READ_ATTRIBUTE_BUFFER_SIZE
Definition: ntdddisk.h:731
#define ENABLE_SMART
Definition: ntdddisk.h:751
#define SAVE_ATTRIBUTE_VALUES
Definition: ntdddisk.h:747
#define RETURN_SMART_STATUS
Definition: ntdddisk.h:753
#define READ_THRESHOLDS
Definition: ntdddisk.h:745
#define IDENTIFY_BUFFER_SIZE
Definition: ntdddisk.h:732
struct _GETVERSIONINPARAMS GETVERSIONINPARAMS
#define SMART_IDE_ERROR
Definition: ntdddisk.h:706
#define DISABLE_SMART
Definition: ntdddisk.h:752
#define READ_ATTRIBUTES
Definition: ntdddisk.h:744
struct _GETVERSIONINPARAMS * PGETVERSIONINPARAMS
#define CAP_ATA_ID_CMD
Definition: ntdddisk.h:661
#define ENABLE_DISABLE_AUTOSAVE
Definition: ntdddisk.h:746
#define CAP_SMART_CMD
Definition: ntdddisk.h:663
_In_ ULONG _In_ ULONG _In_ ULONG Length
Definition: ntddpcm.h:102
#define NTHALAPI
Definition: ntoskrnl.h:40
#define STATUS_CONFLICTING_ADDRESSES
Definition: ntstatus.h:261
#define STATUS_DEVICE_DOES_NOT_EXIST
Definition: ntstatus.h:428
#define L(x)
Definition: ntvdm.h:50
#define BOOLEAN
Definition: pedump.c:73
long LONG
Definition: pedump.c:60
unsigned short USHORT
Definition: pedump.c:61
struct @5011 regs[]
_In_opt_ WDFREQUEST _In_ ULONG _In_ BOOLEAN _In_ PCDB Cdb
Definition: scratch.h:159
struct _SRB_IO_CONTROL SRB_IO_CONTROL
#define REG_DWORD
Definition: sdbapi.c:596
int zero
Definition: sehframes.cpp:29
#define STATUS_SUCCESS
Definition: shellext.h:65
Definition: shell.h:41
ULONG Channel
Definition: uata_ctl.h:124
CHAR DeviceName[64]
Definition: uata_ctl.h:136
ULONG BusInterruptLevel
Definition: uata_ctl.h:138
ULONG DevID
Definition: uata_ctl.h:118
BOOLEAN ChanHeaderLengthValid
Definition: uata_ctl.h:150
ULONG MaxTransferMode
Definition: uata_ctl.h:132
UCHAR NumberLuns
Definition: uata_ctl.h:148
ULONG NumberChannels
Definition: uata_ctl.h:145
ULONG RevID
Definition: uata_ctl.h:119
BOOLEAN MemIo
Definition: uata_ctl.h:128
ULONG InterruptMode
Definition: uata_ctl.h:139
BOOLEAN UnknownDev
Definition: uata_ctl.h:129
BOOLEAN MasterDev
Definition: uata_ctl.h:130
ULONG HwFlags
Definition: uata_ctl.h:133
BOOLEAN ChanInfoValid
Definition: uata_ctl.h:146
ULONG DevIndex
Definition: uata_ctl.h:122
ULONG HbaCtrlFlags
Definition: uata_ctl.h:126
ULONG slotNumber
Definition: uata_ctl.h:120
BOOLEAN LunInfoValid
Definition: uata_ctl.h:149
ULONG OrigAdapterInterfaceType
Definition: uata_ctl.h:134
ULONG AdapterInterfaceType
Definition: uata_ctl.h:152
ULONG SystemIoBusNumber
Definition: uata_ctl.h:121
BOOLEAN simplexOnly
Definition: uata_ctl.h:127
ULONG HeaderLength
Definition: uata_ctl.h:117
ULONG BusInterruptVector
Definition: uata_ctl.h:140
ULONG Flags
Definition: uata_ctl.h:73
ULONG WaitForPhysicalLink
Definition: uata_ctl.h:72
ULONG MaxTransferMode
Definition: uata_ctl.h:104
LONGLONG ReorderCount
Definition: uata_ctl.h:107
LONGLONG QueueStat[MAX_QUEUE_STAT]
Definition: uata_ctl.h:106
LONGLONG TryReorderHeadCount
Definition: uata_ctl.h:110
LONGLONG IntersectCount
Definition: uata_ctl.h:108
LONGLONG TryReorderTailCount
Definition: uata_ctl.h:111
LONGLONG TryReorderCount
Definition: uata_ctl.h:109
ULONG ChannelCtrlFlags
Definition: uata_ctl.h:105
BOOLEAN AtDiskPrimaryAddressClaimed
Definition: iotypes.h:4482
BOOLEAN AtDiskSecondaryAddressClaimed
Definition: iotypes.h:4483
UCHAR bIDEError
Definition: helper.h:3
UCHAR bDriverError
Definition: helper.h:2
USHORT VersionMj
Definition: uata_ctl.h:96
USHORT SubVerMn
Definition: uata_ctl.h:99
USHORT SubVerMj
Definition: uata_ctl.h:98
USHORT VersionMn
Definition: uata_ctl.h:97
ULONG Length
Definition: uata_ctl.h:95
ULONG OrigMode
Definition: uata_ctl.h:89
ULONG CurrentMode
Definition: uata_ctl.h:90
BOOLEAN PrimaryAddress
Definition: bsmaster.h:1036
ULONG ChannelCtrlFlags
Definition: bsmaster.h:1059
BOOLEAN RDP
Definition: bsmaster.h:1033
ULONG MechStatusRetryCount
Definition: bsmaster.h:1054
ULONG queue_depth
Definition: bsmaster.h:1027
SENSE_DATA MechStatusSense
Definition: bsmaster.h:1053
LONG CheckIntr
Definition: bsmaster.h:1062
ULONG NumberLuns
Definition: bsmaster.h:1090
SCSI_REQUEST_BLOCK InternalSrb
Definition: bsmaster.h:1055
PHW_TIMER HwScsiTimer
Definition: bsmaster.h:1072
ULONG cur_cdev
Definition: bsmaster.h:1022
UCHAR ReturningMediaStatus
Definition: bsmaster.h:1043
PATA_REQ AhciInternalAtaReq
Definition: bsmaster.h:1113
LONGLONG TryReorderHeadCount
Definition: bsmaster.h:1121
ULONG lChannel
Definition: bsmaster.h:1064
ULONG PmLunMap
Definition: bsmaster.h:1091
LONG DisableIntr
Definition: bsmaster.h:1061
ULONG AhciLastIS
Definition: bsmaster.h:1108
ULONG AhciLastSError
Definition: bsmaster.h:1109
ULONG NextDpcChan
Definition: bsmaster.h:1071
UCHAR DpcState
Definition: bsmaster.h:1030
struct _HW_LU_EXTENSION * lun[IDE_MAX_LUN_PER_CHAN]
Definition: bsmaster.h:1088
LONGLONG IntersectCount
Definition: bsmaster.h:1119
BOOLEAN ExpectingInterrupt
Definition: bsmaster.h:1032
LONGLONG ReorderCount
Definition: bsmaster.h:1118
MECHANICAL_STATUS_INFORMATION_HEADER MechStatusData
Definition: bsmaster.h:1052
UCHAR SmartCommand
Definition: bsmaster.h:1039
LONGLONG TryReorderTailCount
Definition: bsmaster.h:1122
LONGLONG TryReorderCount
Definition: bsmaster.h:1120
LONGLONG QueueStat[MAX_QUEUE_STAT]
Definition: bsmaster.h:1117
LONGLONG DpcTime
Definition: bsmaster.h:1073
ULONG MaxTransferMode
Definition: bsmaster.h:1057
struct _HW_DEVICE_EXTENSION * DeviceExtension
Definition: bsmaster.h:1087
IDENTIFY_DATA FullIdentifyData
Definition: atapi.c:145
ULONG NumberChannels
Definition: atapi.c:68
BOOLEAN DriverMustPoll
Definition: atapi.c:111
INTERFACE_TYPE AdapterInterfaceType
Definition: bsmaster.h:1316
BOOLEAN ExpectingInterrupt
Definition: atapi.c:99
BOOLEAN opt_AtapiDmaReadWrite
Definition: bsmaster.h:1339
PDEVICE_OBJECT Isr2DevObj
Definition: bsmaster.h:1281
INTERFACE_TYPE OrigAdapterInterfaceType
Definition: bsmaster.h:1315
BOOLEAN opt_AtapiDmaRawRead
Definition: bsmaster.h:1338
ULONG InterruptMode
Definition: atapi.c:47
UCHAR LastInterruptedChannel
Definition: bsmaster.h:1259
PHW_CHANNEL chan
Definition: bsmaster.h:1257
BOOLEAN opt_AtapiDmaControlCmd
Definition: bsmaster.h:1337
BOOLEAN opt_AtapiDmaZeroTransfer
Definition: bsmaster.h:1336
PHW_ADAPTER_CONTROL HwAdapterControl
Definition: srb.h:596
HW_INITIALIZATION_DATA_2K w2k
Definition: srb.h:602
HW_INITIALIZATION_DATA comm
Definition: srb.h:601
PHW_INTERRUPT HwInterrupt
Definition: srb.h:569
PHW_RESET_BUS HwResetBus
Definition: srb.h:571
USHORT VendorIdLength
Definition: srb.h:586
PHW_STARTIO HwStartIo
Definition: srb.h:568
BOOLEAN NeedPhysicalAddresses
Definition: srb.h:581
ULONG SpecificLuExtensionSize
Definition: srb.h:575
ULONG SrbExtensionSize
Definition: srb.h:576
ULONG HwInitializationDataSize
Definition: srb.h:550
USHORT DeviceIdLength
Definition: srb.h:589
PHW_INITIALIZE HwInitialize
Definition: srb.h:567
ULONG DeviceExtensionSize
Definition: srb.h:574
INTERFACE_TYPE AdapterInterfaceType
Definition: srb.h:565
PHW_FIND_ADAPTER HwFindAdapter
Definition: srb.h:570
BOOLEAN MapBuffers
Definition: srb.h:580
ULONG NumberOfAccessRanges
Definition: srb.h:577
UCHAR opt_StandbyTimer
Definition: bsmaster.h:1202
UCHAR opt_AdvPowerMode
Definition: bsmaster.h:1200
LONGLONG RwSwitchMCost
Definition: bsmaster.h:1182
BOOLEAN opt_ReadCacheEnable
Definition: bsmaster.h:1197
UCHAR opt_ReadOnly
Definition: bsmaster.h:1199
ULONGLONG NumOfSectors
Definition: bsmaster.h:1163
LONGLONG RwSwitchCost
Definition: bsmaster.h:1181
struct _HW_DEVICE_EXTENSION * DeviceExtension
Definition: bsmaster.h:1218
UCHAR TransferMode
Definition: bsmaster.h:1171
ULONG opt_MaxTransferMode
Definition: bsmaster.h:1195
IDENTIFY_DATA2 IdentifyData
Definition: bsmaster.h:1162
ULONGLONG errLastLba
Definition: bsmaster.h:1222
LONGLONG RecoverCount[MAX_RETRIES]
Definition: bsmaster.h:1230
UCHAR MaximumBlockXfer
Definition: bsmaster.h:1168
ULONG DiscsPresent
Definition: bsmaster.h:1165
UCHAR LimitedTransferMode
Definition: bsmaster.h:1172
ULONG opt_PreferedTransferMode
Definition: bsmaster.h:1196
UCHAR OrigTransferMode
Definition: bsmaster.h:1173
LONGLONG IoCount
Definition: bsmaster.h:1231
UCHAR PhyTransferMode
Definition: bsmaster.h:1174
BOOLEAN opt_WriteCacheEnable
Definition: bsmaster.h:1198
ULONG AtapiReadyWaitDelay
Definition: bsmaster.h:1191
LONGLONG BlockIoCount
Definition: bsmaster.h:1232
ULONG opt_GeomType
Definition: bsmaster.h:1194
LONGLONG SeekBackMCost
Definition: bsmaster.h:1183
UCHAR opt_AcousticMode
Definition: bsmaster.h:1201
USHORT NumberOfHeads
Definition: atapi.h:252
USHORT NumberOfCylinders
Definition: atapi.h:250
USHORT FirmwareRevision[4]
Definition: atapi.h:261
USHORT SectorsPerTrack
Definition: atapi.h:255
USHORT ModelNumber[20]
Definition: atapi.h:262
USHORT NumberOfCurrentCylinders
Definition: hwide.h:208
USHORT NVCache_PM_Enabled
Definition: atapi.h:928
USHORT SoftReset
Definition: hwide.h:197
USHORT UltraDMASupport
Definition: atapi.h:830
USHORT VendorAcoustic
Definition: atapi.h:847
USHORT NumberOfCurrentHeads
Definition: hwide.h:209
ULONG UserAddressableSectors
Definition: hwide.h:213
USHORT SataSupport
Definition: hwide.h:232
USHORT CurrentAcoustic
Definition: atapi.h:846
USHORT NominalMediaRotationRate
Definition: atapi.h:936
USHORT SupportIordy
Definition: hwide.h:196
USHORT SataEnable
Definition: hwide.h:233
USHORT NumberOfHeads
Definition: hwide.h:178
UCHAR PioCycleTimingMode
Definition: hwide.h:203
USHORT SerialNumber[10]
Definition: hwide.h:183
USHORT UdmaModesValid
Definition: atapi.h:688
USHORT NumberOfCylinders
Definition: hwide.h:176
USHORT AtapiByteCount0
Definition: atapi.h:878
ULONGLONG UserAddressableSectors48
Definition: hwide.h:280
struct _IDENTIFY_DATA::@182 FeaturesEnabled
ULONG LargeSectorSize
Definition: atapi.h:872
USHORT PioTimingsValid
Definition: atapi.h:687
USHORT CurrentSectorsPerTrack
Definition: hwide.h:210
USHORT DoubleWordIo
Definition: hwide.h:191
USHORT SecurityStatus
Definition: atapi.h:883
USHORT MasterPasswdRevision
Definition: atapi.h:837
USHORT PhysLogSectorSize
Definition: atapi.h:859
USHORT SataCapabilities
Definition: hwide.h:230
USHORT MajorRevision
Definition: hwide.h:234
USHORT UltraDMAActive
Definition: atapi.h:831
struct _IDENTIFY_DATA::@182 FeaturesSupport
UCHAR AtapiCmdSize
Definition: hwide.h:169
USHORT NVCache_Version
Definition: atapi.h:933
USHORT SupportDma
Definition: hwide.h:193
USHORT SingleWordDMAActive
Definition: hwide.h:215
USHORT AdvancedPIOModes
Definition: hwide.h:218
struct _IDENTIFY_DATA::@1059::@1074 AtapiDMA
USHORT FirmwareRevision[4]
Definition: hwide.h:187
USHORT NVCache_PM_Supported
Definition: atapi.h:927
USHORT NVCache_Enabled
Definition: atapi.h:930
USHORT NVCache_PM_Version
Definition: atapi.h:932
USHORT SectorsPerTrack
Definition: hwide.h:181
UCHAR MaximumBlockTransfer
Definition: atapi.h:207
USHORT RemovableStatus
Definition: atapi.h:881
USHORT MultiWordDMAActive
Definition: hwide.h:217
USHORT SupportLba
Definition: hwide.h:194
USHORT CfAdvPowerMode
Definition: atapi.h:898
USHORT LogicalSectorOffset
Definition: atapi.h:920
USHORT DisableIordy
Definition: hwide.h:195
USHORT ModelNumber[20]
Definition: hwide.h:188
Definition: helper.h:8
UCHAR bCommandReg
Definition: helper.h:15
UCHAR cfis[64]
Definition: bsmaster.h:807
UCHAR CommandQueue
Definition: cdrw_hw.h:1125
UCHAR RemovableMedia
Definition: cdrw_hw.h:1119
UCHAR ProductRevisionLevel[4]
Definition: cdrw_hw.h:1134
UCHAR DeviceIdentificationString[28]
Definition: scsi.h:1104
UCHAR RelativeAddressing
Definition: cdrw_hw.h:1131
UCHAR VendorId[8]
Definition: cdrw_hw.h:1132
UCHAR DeviceType
Definition: cdrw_hw.h:1116
PHW_DEVICE_EXTENSION HwDeviceExtension
Definition: bsmaster.h:1351
UCHAR WriteCacheEnable
Definition: cdrw_hw.h:2779
UCHAR ReadDisableCache
Definition: cdrw_hw.h:2777
UCHAR DeviceSpecificParameter
Definition: cdrw_hw.h:2507
struct _MODE_POWER_CONDITION_PAGE::@893::@894 Fields
union _MODE_POWER_CONDITION_PAGE::@893 Byte3
UCHAR ListLength[4]
Definition: scsi.h:2932
UCHAR PathId
Definition: scsi_port.h:149
UCHAR TargetId
Definition: scsi_port.h:150
UCHAR QueueTag
Definition: srb.h:256
ULONG TimeOutValue
Definition: srb.h:262
UCHAR TargetId
Definition: srb.h:254
UCHAR SenseInfoBufferLength
Definition: srb.h:259
PVOID DataBuffer
Definition: srb.h:263
UCHAR PathId
Definition: srb.h:253
UCHAR CdbLength
Definition: srb.h:258
UCHAR Cdb[16]
Definition: srb.h:279
PVOID SenseInfoBuffer
Definition: srb.h:264
UCHAR Function
Definition: srb.h:250
UCHAR ScsiStatus
Definition: srb.h:252
ULONG DataTransferLength
Definition: srb.h:261
PVOID SrbExtension
Definition: srb.h:267
struct _SCSI_REQUEST_BLOCK * NextSrb
Definition: srb.h:265
ULONG SrbFlags
Definition: srb.h:260
USHORT Length
Definition: srb.h:249
UCHAR SrbStatus
Definition: srb.h:251
OUT BOOLEAN SupportedTypeList[0]
Definition: srb.h:221
UCHAR bDriveNumber
Definition: helper.h:33
IDEREGS irDriveRegs
Definition: helper.h:32
UCHAR bBuffer[1]
Definition: helper.h:27
ULONG cBufferSize
Definition: helper.h:25
DRIVERSTATUS DriverStatus
Definition: helper.h:26
UCHAR AdditionalSenseLength
Definition: cdrw_hw.h:1173
UCHAR AdditionalSenseCode
Definition: cdrw_hw.h:1175
UCHAR ErrorCode
Definition: cdrw_hw.h:1164
UCHAR AdditionalSenseCodeQualifier
Definition: cdrw_hw.h:1176
UCHAR EndOfMedia
Definition: cdrw_hw.h:1170
UCHAR IncorrectLength
Definition: cdrw_hw.h:1169
UCHAR SenseKey
Definition: cdrw_hw.h:1167
UCHAR Valid
Definition: cdrw_hw.h:1165
BOOLEAN ApplyImmediately
Definition: uata_ctl.h:83
ULONG OrigMode
Definition: uata_ctl.h:82
ULONG ControlCode
Definition: scsi_port.h:128
SCSI_ADDRESS addr
Definition: uata_ctl.h:296
ADDREMOVEDEV FindDelDev
Definition: uata_ctl.h:300
SRB_IO_CONTROL hdr
Definition: uata_ctl.h:295
GETDRVVERSION Version
Definition: uata_ctl.h:306
ADAPTERINFO AdapterInfo
Definition: uata_ctl.h:303
SETTRANSFERMODE SetMode
Definition: uata_ctl.h:301
GETTRANSFERMODE GetMode
Definition: uata_ctl.h:302
USHORT MaximumLength
Definition: env_spec_w32.h:370
Definition: ftp_var.h:139
Definition: ffs.h:52
Definition: ps.c:97
Definition: dhcpd.h:245
#define max(a, b)
Definition: svc.c:63
uint16_t * PWSTR
Definition: typedefs.h:56
uint32_t * PULONG
Definition: typedefs.h:59
const uint16_t * PCWSTR
Definition: typedefs.h:57
#define FIELD_OFFSET(t, f)
Definition: typedefs.h:255
int64_t LONGLONG
Definition: typedefs.h:68
#define NTAPI
Definition: typedefs.h:36
void * PVOID
Definition: typedefs.h:50
uint16_t * PUSHORT
Definition: typedefs.h:56
#define RtlCopyMemory(Destination, Source, Length)
Definition: typedefs.h:263
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
#define IN
Definition: typedefs.h:39
uint16_t * PWCHAR
Definition: typedefs.h:56
unsigned char * PUCHAR
Definition: typedefs.h:53
uint32_t ULONG
Definition: typedefs.h:59
uint64_t ULONGLONG
Definition: typedefs.h:67
#define OUT
Definition: typedefs.h:40
char CCHAR
Definition: typedefs.h:51
char * PCHAR
Definition: typedefs.h:51
pass
Definition: typegen.h:25
#define IOCTL_SCSI_MINIPORT_UNIATA_GET_VERSION
Definition: uata_ctl.h:69
struct _ADAPTERINFO ADAPTERINFO
#define IOCTL_SCSI_MINIPORT_UNIATA_SET_MAX_MODE
Definition: uata_ctl.h:62
#define UNIATA_REMOVE_FLAGS_HIDE
Definition: uata_ctl.h:75
#define UNIATA_ADD_FLAGS_UNHIDE
Definition: uata_ctl.h:76
#define IOCTL_SCSI_MINIPORT_UNIATA_DELETE_DEVICE
Definition: uata_ctl.h:61
#define IOCTL_SCSI_MINIPORT_UNIATA_FIND_DEVICES
Definition: uata_ctl.h:60
#define UNIATA_SPTI_EX_USE_DMA
Definition: uata_ctl.h:258
#define IOCTL_SCSI_MINIPORT_UNIATA_RESETBB
Definition: uata_ctl.h:66
#define IOCTL_SCSI_MINIPORT_UNIATA_GET_MODE
Definition: uata_ctl.h:63
struct _UNIATA_CTL * PUNIATA_CTL
#define IOCTL_SCSI_MINIPORT_UNIATA_RESET_DEVICE
Definition: uata_ctl.h:67
#define UNIATA_COMM_PORT_VENDOR_STR
Definition: uata_ctl.h:56
struct _IDEREGS_EX * PIDEREGS_EX
#define UNIATA_SPTI_EX_SPEC_TO
Definition: uata_ctl.h:261
struct _CHANINFO * PCHANINFO
#define IOCTL_SCSI_MINIPORT_UNIATA_ADAPTER_INFO
Definition: uata_ctl.h:64
struct _GETDRVVERSION GETDRVVERSION
#define ATA_FLAGS_48BIT_COMMAND
Definition: uata_ctl.h:223
#define lba
#define ATA_C_F_DIS_RCACHE
Definition: atapi.h:567
#define ATAPI_IR_IO_toHost
Definition: atapi.h:549
#define DFLAGS_LBA_ENABLED
Definition: atapi.h:247
#define INTERRUPT_REASON_UNEXPECTED
Definition: atapi.h:1280
#define ATA_C_F_DIS_MEDIASTAT
Definition: atapi.h:576
#define SCSIOP_ATA_PASSTHROUGH
Definition: atapi.h:411
#define PrintNtConsole(x)
Definition: atapi.h:1629
#define ATA_C_F_DIS_WCACHE
Definition: atapi.h:564
#define IDE_COMMAND_READ_DMA_Q48
Definition: atapi.h:354
VOID NTAPI UniataDumpATARegs(IN struct _HW_CHANNEL *chan)
#define DFLAGS_ORIG_GEOMETRY
Definition: atapi.h:251
#define AdvancedPIOModes_3
Definition: atapi.h:726
#define ATA_DMA
Definition: atapi.h:316
#define ATA_PIO4
Definition: atapi.h:313
#define IDE_COMMAND_DATA_SET_MGMT
Definition: atapi.h:347
#define UNIATA_FIND_DEV_UNHIDE
Definition: atapi.h:1360
#define ATA_SATA_GEN3
Definition: atapi.h:759
#define ATAPI_TYPE_TAPE
Definition: atapi.h:622
#define ATA_CMD_FLAG_Out
Definition: atapi.h:1603
#define UniAta_need_lba48(command, lba, count, supp48)
Definition: atapi.h:1609
#define ATA_PIO1
Definition: atapi.h:310
#define ATA_UDMA2
Definition: atapi.h:330
#define ATAPI_DEVICE(chan, dev)
Definition: atapi.h:1624
#define IDE_COMMAND_TRUSTED_SEND_DMA
Definition: atapi.h:379
#define ATA_CMD_FLAG_FUA
Definition: atapi.h:1601
#define DFLAGS_LBA32plus
Definition: atapi.h:256
#define READ_LOG_SECTOR
Definition: atapi.h:591
#define ATA_SATA_GEN2
Definition: atapi.h:758
#define DFLAGS_MANUAL_CHS
Definition: atapi.h:255
#define ATA_SDMA
Definition: atapi.h:317
#define ATA_CMD_FLAG_In
Definition: atapi.h:1602
#define ATA_SA150
Definition: atapi.h:337
#define IDE_COMMAND_FLUSH_CACHE48
Definition: atapi.h:405
#define IDE_COMMAND_WRITE_DMA_Q
Definition: atapi.h:390
#define ATA_WDMA2
Definition: atapi.h:325
#define ATA_AT_HOME_HDD
Definition: atapi.h:1592
#define AtapiStallExecution(dt)
Definition: atapi.h:158
#define ATA_F_DMA
Definition: atapi.h:557
#define ATA_F_DMAREAD
Definition: atapi.h:559
#define ATA_ChecksumValid
Definition: atapi.h:978
#define DFLAGS_WCACHE_ENABLED
Definition: atapi.h:249
#define ATAPI_IR_Mask
Definition: atapi.h:551
#define KdPrint3(_x_)
Definition: atapi.h:153
#define IDE_COMMAND_VERIFY48
Definition: atapi.h:373
#define DFLAGS_HIDDEN
Definition: atapi.h:253
ULONG g_LogToDisplay
#define IDE_COMMAND_TRUSTED_RCV_DMA
Definition: atapi.h:377
#define IDE_COMMAND_SET_FEATURES
Definition: atapi.h:407
#define IDE_COMMAND_READ_STREAM48
Definition: atapi.h:358
ULONG NTAPI CheckDevice(IN PVOID HwDeviceExtension, IN ULONG Channel, IN ULONG deviceNumber, IN BOOLEAN ResetBus)
Definition: id_probe.cpp:2897
#define IDE_COMMAND_WRITE_DMA48
Definition: atapi.h:363
#define ATAPI_TYPE_CDROM
Definition: atapi.h:623
#define IDE_COMMAND_IDLE_IMMED
Definition: atapi.h:396
#define IDE_COMMAND_WRITE_DMA_Q48
Definition: atapi.h:364
#define ATA_SA300
Definition: atapi.h:338
#define IDE_COMMAND_WRITE_STREAM_DMA48
Definition: atapi.h:367
#define IDE_COMMAND_WRITE_FUA_DMA48
Definition: atapi.h:369
#define KdPrint2(_x_)
Definition: atapi.h:154
#define DEVNUM_NOT_SPECIFIED
Definition: atapi.h:1483
#define ATA_CMD_FLAG_DMA
Definition: atapi.h:1600
#define ATA_C_F_DIS_APM
Definition: atapi.h:579
#define DFLAGS_RCACHE_ENABLED
Definition: atapi.h:250
#define ATA_PIO5
Definition: atapi.h:314
#define DFLAGS_REINIT_DMA
Definition: atapi.h:252
#define ATA_C_F_ENAB_RCACHE
Definition: atapi.h:566
#define DFLAGS_DWORDIO_ENABLED
Definition: atapi.h:248
#define ATAPI_DRQT_INTR
Definition: atapi.h:616
#define IDX_IO1
Definition: atapi.h:194
#define IDE_COMMAND_WRITE_STREAM48
Definition: atapi.h:368
#define INTERRUPT_REASON_IGNORE
Definition: atapi.h:1278
#define IDE_COMMAND_FLUSH_CACHE
Definition: atapi.h:401
#define ATAPI_IR_COD_Cmd
Definition: atapi.h:545
#define ATA_C_F_ENAB_APM
Definition: atapi.h:578
#define IDE_COMMAND_WRITE_FUA_DMA_Q48
Definition: atapi.h:370
#define IDE_COMMAND_READ48
Definition: atapi.h:352
#define IDE_COMMAND_WRITE_MUL48
Definition: atapi.h:366
#define ATA_CMD_FLAG_48
Definition: atapi.h:1599
#define IDE_COMMAND_READ_NATIVE_SIZE
Definition: atapi.h:408
#define IDE_COMMAND_READ_NATIVE_SIZE48
Definition: atapi.h:355
#define ATA_CMD_FLAG_48supp
Definition: atapi.h:1598
#define AtapiStringCmp(s1, s2, n)
Definition: atapi.h:1256
#define IDE_COMMAND_SET_NATIVE_SIZE48
Definition: atapi.h:365
#define Connect_DbgPrint()
Definition: atapi.h:156
#define IDE_COMMAND_READ_DMA48
Definition: atapi.h:353
#define CHAN_NOT_SPECIFIED
Definition: atapi.h:1481
#define AdvancedPIOModes_4
Definition: atapi.h:727
#define IDE_COMMAND_READ_STREAM_DMA48
Definition: atapi.h:357
#define IDE_COMMAND_READ_DMA_Q
Definition: atapi.h:387
#define IDE_COMMAND_SLEEP
Definition: atapi.h:400
#define ATA_SATA_GEN1
Definition: atapi.h:757
#define ATA_SA600
Definition: atapi.h:339
#define AUTO_OFFLINE
Definition: atapi.h:594
__inline LONG ata_cur_mode_from_ident(PIDENTIFY_DATA ident, BOOLEAN Active)
Definition: atapi.h:1648
#define IDE_COMMAND_STANDBY_IMMED
Definition: atapi.h:395
#define AdvancedPIOModes_5
Definition: atapi.h:728
#define WRITE_LOG_SECTOR
Definition: atapi.h:592
#define IDE_COMMAND_WRITE_MUL_FUA48
Definition: atapi.h:391
#define IDE_COMMAND_READ_MUL48
Definition: atapi.h:356
#define ATAPI_IR_IO_toDev
Definition: atapi.h:548
#define IDE_COMMAND_SET_NATIVE_SIZE
Definition: atapi.h:409
#define IOMODE_NOT_SPECIFIED
Definition: atapi.h:1484
#define IDE_COMMAND_WRITE48
Definition: atapi.h:362
#define IDE_COMMAND_DOOR_UNLOCK
Definition: atapi.h:394
ULONG NTAPI UniataAnybodyHome(IN PVOID HwDeviceExtension, IN ULONG Channel, IN ULONG deviceNumber)
Definition: id_probe.cpp:2778
#define UniAtaClearAtaReq(AtaReq)
Definition: atapi.h:1615
#define IDENT_MODE_ACTIVE
Definition: atapi.h:1644
#define ATA_C_F_DIS_ACOUSTIC
Definition: atapi.h:585
#define ATA_C_F_ENAB_ACOUSTIC
Definition: atapi.h:584
#define PRINT_PREFIX
Definition: atapi.h:150
ULONG NTAPI AtapiReadArgumentString(IN PVOID HwDeviceExtension, IN PVOID Context, IN PVOID BusInformation, IN PCHAR ArgumentString, IN OUT PPORT_CONFIGURATION_INFORMATION ConfigInfo, OUT PBOOLEAN Again)
Definition: id_probe.cpp:2754
#define IDE_COMMAND_WRITE_LOG_DMA48
Definition: atapi.h:375
#define IDE_COMMAND_READ_LOG_DMA48
Definition: atapi.h:374
#define ATAPI_TYPE_OPTICAL
Definition: atapi.h:624
#define IDX_IO1_SZ
Definition: atapi.h:195
#define ATA_PIO2
Definition: atapi.h:311
#define ATA_PIO0
Definition: atapi.h:309
#define INTERRUPT_REASON_OUR
Definition: atapi.h:1279
#define ATA_C_F_ENAB_WCACHE
Definition: atapi.h:563
#define ATA_CMD_FLAG_LBAIOsupp
Definition: atapi.h:1597
ULONG NTAPI AtapiFindIsaController(IN PVOID HwDeviceExtension, IN PVOID Context, IN PVOID BusInformation, IN PCHAR ArgumentString, IN OUT PPORT_CONFIGURATION_INFORMATION ConfigInfo, OUT PBOOLEAN Again)
Definition: id_probe.cpp:2243
#define ATA_C_F_ENAB_MEDIASTAT
Definition: atapi.h:575
#define ATA_PIO3
Definition: atapi.h:312
#define IDE_COMMAND_IDLE
Definition: atapi.h:398
#define IDE_COMMAND_DOOR_LOCK
Definition: atapi.h:393
#define IDENT_MODE_MAX
Definition: atapi.h:1643
#define UNIATA_VER_MN
Definition: uniata_ver.h:4
#define UNIATA_VER_MJ
Definition: uniata_ver.h:3
#define UNIATA_VER_SUB_MN
Definition: uniata_ver.h:6
#define UNIATA_VER_STR
Definition: uniata_ver.h:1
#define UNIATA_VER_SUB_MJ
Definition: uniata_ver.h:5
IDE_AHCI_CMD ahci_cmd0
Definition: bsmaster.h:922
ULONG bcount
Definition: bsmaster.h:887
UCHAR retry
Definition: bsmaster.h:889
struct _ATA_REQ::@1158::@1160::@1164::@1167 ahci
ULONG WordsTransfered
Definition: bsmaster.h:886
LONGLONG lba
Definition: bsmaster.h:885
PSCSI_REQUEST_BLOCK Srb
Definition: bsmaster.h:880
PUSHORT DataBuffer
Definition: bsmaster.h:882
ULONG TransferLength
Definition: bsmaster.h:884
PSCSI_REQUEST_BLOCK OriginalSrb
Definition: bsmaster.h:895
ULONG dma_entries
Definition: bsmaster.h:897
UCHAR Flags
Definition: bsmaster.h:892
UCHAR ReqState
Definition: bsmaster.h:893
ULONG WordsLeft
Definition: bsmaster.h:883
Definition: cdrw_hw.h:28
struct _CDB::_SERVICE_ACTION16 SERVICE_ACTION16
struct _CDB::_MEDIA_REMOVAL MEDIA_REMOVAL
struct _CDB::_MECH_STATUS MECH_STATUS
struct _CDB::_CDB16READWRITE CDB16READWRITE
struct _CDB::_CDB6 CDB6
struct _CDB::_WRITE_CD WRITE_CD
struct _CDB::_CDB12READWRITE CDB12READWRITE
struct _CDB::_CDB6INQUIRY CDB6INQUIRY
struct _CDB::_START_STOP START_STOP
struct _CDB::_MODE_SENSE MODE_SENSE
struct _CDB::_REPORT_LUNS REPORT_LUNS
LONGLONG QuadPart
Definition: typedefs.h:114
ULONG LowPart
Definition: typedefs.h:106
Definition: pdh_main.c:94
unsigned char Uchar
Definition: utypes.h:45
unsigned short Ushort
Definition: utypes.h:44
unsigned long Ulong
Definition: utypes.h:42
_Must_inspect_result_ _In_ WDFDEVICE _In_ WDFSTRING String
Definition: wdfdevice.h:2433
_Must_inspect_result_ _In_ PDRIVER_OBJECT _In_ PCUNICODE_STRING RegistryPath
Definition: wdfdriver.h:215
_Must_inspect_result_ _In_ PDRIVER_OBJECT DriverObject
Definition: wdfdriver.h:213
_Must_inspect_result_ _In_ WDFDEVICE _In_ PWDF_INTERRUPT_CONFIG _In_opt_ PWDF_OBJECT_ATTRIBUTES _Out_ WDFINTERRUPT * Interrupt
Definition: wdfinterrupt.h:379
_Must_inspect_result_ _In_ WDFQUEUE _In_opt_ WDFREQUEST _In_opt_ WDFFILEOBJECT _Inout_opt_ PWDF_REQUEST_PARAMETERS Parameters
Definition: wdfio.h:869
_Must_inspect_result_ _In_ PWDFDEVICE_INIT _In_ PCUNICODE_STRING DeviceID
Definition: wdfpdo.h:278
_In_ WDFIORESREQLIST _In_ ULONG SlotNumber
Definition: wdfresource.h:68
_In_ ULONG _In_ ULONG_PTR ident
Definition: winddi.h:3994
void int int ULONGLONG int va_list * ap
Definition: winesup.h:36
struct _DRIVER_OBJECT * PDRIVER_OBJECT
#define PCI_MAX_FUNCTION
Definition: iotypes.h:3599
#define PCI_MAX_DEVICES
Definition: iotypes.h:3598
#define _vsnprintf
Definition: xmlstorage.h:202
unsigned char UCHAR
Definition: xmlstorage.h:181
__wchar_t WCHAR
Definition: xmlstorage.h:180
char CHAR
Definition: xmlstorage.h:175