]> git.proxmox.com Git - mirror_edk2.git/blob - EdkModulePkg/Bus/Pci/IdeBus/Dxe/ata.c
88e81c0ada92d6e7f436249335fe72f1108fee97
[mirror_edk2.git] / EdkModulePkg / Bus / Pci / IdeBus / Dxe / ata.c
1 /*++
2
3 Copyright (c) 2006, Intel Corporation
4 All rights reserved. This program and the accompanying materials
5 are licensed and made available under the terms and conditions of the BSD License
6 which accompanies this distribution. The full text of the license may be found at
7 http://opensource.org/licenses/bsd-license.php
8
9 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
10 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
11
12 Module Name:
13
14 ata.c
15
16 Abstract:
17
18 Revision History
19
20 2002-6: Add Atapi6 enhancement, support >120GB hard disk, including
21 update - ATAIdentity() func
22 update - AtaBlockIoReadBlocks() func
23 update - AtaBlockIoWriteBlocks() func
24 add - AtaAtapi6Identify() func
25 add - AtaReadSectorsExt() func
26 add - AtaWriteSectorsExt() func
27 add - AtaPioDataInExt() func
28 add - AtaPioDataOutExt() func
29
30 --*/
31
32 #include "idebus.h"
33
34
35 EFI_STATUS
36 AtaReadSectorsExt (
37 IN IDE_BLK_IO_DEV *IdeDev,
38 IN OUT VOID *DataBuffer,
39 IN EFI_LBA StartLba,
40 IN UINTN NumberOfBlocks
41 );
42
43 EFI_STATUS
44 AtaWriteSectorsExt (
45 IN IDE_BLK_IO_DEV *IdeDev,
46 IN VOID *DataBuffer,
47 IN EFI_LBA StartLba,
48 IN UINTN NumberOfBlocks
49 );
50
51 EFI_STATUS
52 AtaPioDataInExt (
53 IN IDE_BLK_IO_DEV *IdeDev,
54 IN OUT VOID *Buffer,
55 IN UINT32 ByteCount,
56 IN UINT8 AtaCommand,
57 IN EFI_LBA StartLba,
58 IN UINT16 SectorCount
59 );
60
61 EFI_STATUS
62 AtaPioDataOutExt (
63 IN IDE_BLK_IO_DEV *IdeDev,
64 IN VOID *Buffer,
65 IN UINT32 ByteCount,
66 IN UINT8 AtaCommand,
67 IN EFI_LBA StartLba,
68 IN UINT16 SectorCount
69 );
70
71 EFI_STATUS
72 ATAIdentify (
73 IN IDE_BLK_IO_DEV *IdeDev
74 )
75 /*++
76 Name:
77 ATAIdentify
78
79
80 Purpose:
81 This function is called by DiscoverIdeDevice() during its device
82 identification. It sends out the ATA Identify Command to the
83 specified device. Only ATA device responses to this command. If
84 the command succeeds, it returns the Identify data structure which
85 contains information about the device. This function extracts the
86 information it needs to fill the IDE_BLK_IO_DEV data structure,
87 including device type, media block size, media capacity, and etc.
88
89
90 Parameters:
91 IDE_BLK_IO_DEV IN *IdeDev
92 pointer pointing to IDE_BLK_IO_DEV data structure,used
93 to record all the information of the IDE device.
94
95
96 Returns:
97 EFI_SUCCESS
98 Identify ATA device successfully.
99
100 EFI_DEVICE_ERROR
101 ATA Identify Device Command failed or device is not
102 ATA device.
103
104
105 Notes:
106 parameter IdeDev will be updated in this function.
107 --*/
108 // TODO: function comment is missing 'Routine Description:'
109 // TODO: function comment is missing 'Arguments:'
110 // TODO: IdeDev - add argument and description to function comment
111 {
112 EFI_STATUS Status;
113 EFI_IDENTIFY_DATA *AtaIdentifyPointer;
114 UINT32 Capacity;
115 UINT8 DeviceSelect;
116
117 //
118 // AtaIdentifyPointer is used for accommodating returned IDENTIFY data of
119 // the ATA Identify command
120 //
121 AtaIdentifyPointer = (EFI_IDENTIFY_DATA *) AllocateZeroPool (sizeof (EFI_IDENTIFY_DATA));
122
123 //
124 // use ATA PIO Data In protocol to send ATA Identify command
125 // and receive data from device
126 //
127 DeviceSelect = 0;
128 DeviceSelect = (UINT8) ((IdeDev->Device) << 4);
129 Status = AtaPioDataIn (
130 IdeDev,
131 (VOID *) AtaIdentifyPointer,
132 sizeof (EFI_IDENTIFY_DATA),
133 IDENTIFY_DRIVE_CMD,
134 DeviceSelect,
135 0,
136 0,
137 0,
138 0
139 );
140 //
141 // If ATA Identify command succeeds, then according to the received
142 // IDENTIFY data,
143 // identify the device type ( ATA or not ).
144 // If ATA device, fill the information in IdeDev.
145 // If not ATA device, return IDE_DEVICE_ERROR
146 //
147 if (!EFI_ERROR (Status)) {
148
149 IdeDev->pIdData = AtaIdentifyPointer;
150
151 //
152 // Print ATA Module Name
153 //
154 PrintAtaModuleName (IdeDev);
155
156 //
157 // bit 15 of pAtaIdentify->config is used to identify whether device is
158 // ATA device or ATAPI device.
159 // if 0, means ATA device; if 1, means ATAPI device.
160 //
161 if ((AtaIdentifyPointer->AtaData.config & 0x8000) == 0x00) {
162 //
163 // Detect if support S.M.A.R.T. If yes, enable it as default
164 //
165 AtaSMARTSupport (IdeDev);
166
167 //
168 // Check whether this device needs 48-bit addressing (ATAPI-6 ata device)
169 //
170 Status = AtaAtapi6Identify (IdeDev);
171 if (!EFI_ERROR (Status)) {
172 //
173 // It's a disk with >120GB capacity, initialized in AtaAtapi6Identify()
174 //
175 return EFI_SUCCESS;
176 }
177 //
178 // This is a hard disk <= 120GB capacity, treat it as normal hard disk
179 //
180 IdeDev->Type = IdeHardDisk;
181
182 //
183 // Block Media Information:
184 // Media->LogicalPartition , Media->WriteCaching will be filled
185 // in the DiscoverIdeDevcie() function.
186 //
187 IdeDev->BlkIo.Media->IoAlign = 4;
188 IdeDev->BlkIo.Media->MediaId = 1;
189 IdeDev->BlkIo.Media->RemovableMedia = FALSE;
190 IdeDev->BlkIo.Media->MediaPresent = TRUE;
191 IdeDev->BlkIo.Media->ReadOnly = FALSE;
192 IdeDev->BlkIo.Media->BlockSize = 0x200;
193
194 //
195 // Calculate device capacity
196 //
197 Capacity = ((UINT32)AtaIdentifyPointer->AtaData.user_addressable_sectors_hi << 16) |
198 AtaIdentifyPointer->AtaData.user_addressable_sectors_lo ;
199 IdeDev->BlkIo.Media->LastBlock = Capacity - 1;
200
201 return EFI_SUCCESS;
202
203 }
204 }
205
206 gBS->FreePool (AtaIdentifyPointer);
207 //
208 // Make sure the pIdData will not be freed again.
209 //
210 IdeDev->pIdData = NULL;
211
212 return EFI_DEVICE_ERROR;
213 }
214
215
216 EFI_STATUS
217 AtaAtapi6Identify (
218 IN IDE_BLK_IO_DEV *IdeDev
219 )
220 /*++
221 Name:
222
223 AtaAtapi6Identify
224
225 Purpose:
226
227 This function is called by ATAIdentify() to identity whether this disk
228 supports ATA/ATAPI6 48bit addressing, ie support >120G capacity
229
230 Parameters:
231 IDE_BLK_IO_DEV IN *IdeDev
232 pointer pointing to IDE_BLK_IO_DEV data structure, used
233 to record all the information of the IDE device.
234
235 Returns:
236
237 EFI_SUCCESS - The disk specified by IdeDev is a Atapi6 supported one
238 and 48-bit addressing must be used
239
240 EFI_UNSUPPORTED - The disk dosn't not support Atapi6 or it supports but
241 the capacity is below 120G, 48bit addressing is not
242 needed
243
244 Notes:
245
246 This function must be called after DEVICE_IDENTITY command has been
247 successfully returned
248 --*/
249 // TODO: function comment is missing 'Routine Description:'
250 // TODO: function comment is missing 'Arguments:'
251 // TODO: IdeDev - add argument and description to function comment
252 {
253 UINT8 Index;
254 EFI_LBA TmpLba;
255 EFI_LBA Capacity;
256 EFI_IDENTIFY_DATA *Atapi6IdentifyStruct;
257
258 if (IdeDev->pIdData == NULL) {
259 return EFI_UNSUPPORTED;
260 }
261
262 Atapi6IdentifyStruct = IdeDev->pIdData;
263
264 if ((Atapi6IdentifyStruct->AtapiData.cmd_set_support_83 & bit10) == 0) {
265 //
266 // The device dosn't support 48 bit addressing
267 //
268 return EFI_UNSUPPORTED;
269 }
270
271 //
272 // 48 bit address feature set is supported, get maximum capacity
273 //
274 Capacity = Atapi6IdentifyStruct->AtapiData.max_user_lba_for_48bit_addr[0];
275 for (Index = 1; Index < 4; Index++) {
276 //
277 // Lower byte goes first: word[100] is the lowest word, word[103] is highest
278 //
279 TmpLba = Atapi6IdentifyStruct->AtapiData.max_user_lba_for_48bit_addr[Index];
280 Capacity |= LShiftU64 (TmpLba, 16 * Index);
281 }
282
283 if (Capacity > MAX_28BIT_ADDRESSING_CAPACITY) {
284 //
285 // Capacity exceeds 120GB. 48-bit addressing is really needed
286 //
287 IdeDev->Type = Ide48bitAddressingHardDisk;
288
289 //
290 // Fill block media information:Media->LogicalPartition ,
291 // Media->WriteCaching will be filledin the DiscoverIdeDevcie() function.
292 //
293 IdeDev->BlkIo.Media->IoAlign = 4;
294 IdeDev->BlkIo.Media->MediaId = 1;
295 IdeDev->BlkIo.Media->RemovableMedia = FALSE;
296 IdeDev->BlkIo.Media->MediaPresent = TRUE;
297 IdeDev->BlkIo.Media->ReadOnly = FALSE;
298 IdeDev->BlkIo.Media->BlockSize = 0x200;
299 IdeDev->BlkIo.Media->LastBlock = Capacity - 1;
300
301 return EFI_SUCCESS;
302 }
303
304 return EFI_UNSUPPORTED;
305 }
306
307 VOID
308 PrintAtaModuleName (
309 IN IDE_BLK_IO_DEV *IdeDev
310 )
311 /*++
312 Name:
313 PrintAtaModuleName
314
315
316 Purpose:
317 This function is called by ATAIdentify() or ATAPIIdentify()
318 to print device's module name.
319
320
321 Parameters:
322 IDE_BLK_IO_DEV IN *IdeDev
323 pointer pointing to IDE_BLK_IO_DEV data structure, used
324 to record all the information of the IDE device.
325
326 Returns:
327 no returns.
328
329 Notes:
330 --*/
331 // TODO: function comment is missing 'Routine Description:'
332 // TODO: function comment is missing 'Arguments:'
333 // TODO: IdeDev - add argument and description to function comment
334 {
335 if (IdeDev->pIdData == NULL) {
336 return ;
337 }
338
339 SwapStringChars (IdeDev->ModelName, IdeDev->pIdData->AtaData.ModelName, 40);
340 IdeDev->ModelName[40] = 0x00;
341 }
342
343 EFI_STATUS
344 AtaPioDataIn (
345 IN IDE_BLK_IO_DEV *IdeDev,
346 IN VOID *Buffer,
347 IN UINT32 ByteCount,
348 IN UINT8 AtaCommand,
349 IN UINT8 Head,
350 IN UINT8 SectorCount,
351 IN UINT8 SectorNumber,
352 IN UINT8 CylinderLsb,
353 IN UINT8 CylinderMsb
354 )
355 /*++
356 Name:
357 AtaPioDataIn
358
359
360 Purpose:
361 This function is used to send out ATA commands conforms to the
362 PIO Data In Protocol.
363
364
365 Parameters:
366 IDE_BLK_IO_DEV IN *IdeDev
367 pointer pointing to IDE_BLK_IO_DEV data structure, used
368 to record all the information of the IDE device.
369
370 VOID IN *Buffer
371 buffer contained data transferred from device to host.
372
373 UINT32 IN ByteCount
374 data size in byte unit of the buffer.
375
376 UINT8 IN AtaCommand
377 value of the Command Register
378
379 UINT8 IN Head
380 value of the Head/Device Register
381
382 UINT8 IN SectorCount
383 value of the Sector Count Register
384
385 UINT8 IN SectorNumber
386 value of the Sector Number Register
387
388 UINT8 IN CylinderLsb
389 value of the low byte of the Cylinder Register
390
391 UINT8 IN CylinderMsb
392 value of the high byte of the Cylinder Register
393
394
395 Returns:
396 EFI_SUCCESS
397 send out the ATA command and device send required
398 data successfully.
399
400 EFI_DEVICE_ERROR
401 command sent failed.
402 Notes:
403 --*/
404 // TODO: function comment is missing 'Routine Description:'
405 // TODO: function comment is missing 'Arguments:'
406 // TODO: IdeDev - add argument and description to function comment
407 // TODO: Buffer - add argument and description to function comment
408 // TODO: ByteCount - add argument and description to function comment
409 // TODO: AtaCommand - add argument and description to function comment
410 // TODO: Head - add argument and description to function comment
411 // TODO: SectorCount - add argument and description to function comment
412 // TODO: SectorNumber - add argument and description to function comment
413 // TODO: CylinderLsb - add argument and description to function comment
414 // TODO: CylinderMsb - add argument and description to function comment
415 {
416 UINTN WordCount;
417 UINTN Increment;
418 UINT16 *Buffer16;
419 EFI_STATUS Status;
420
421 Status = WaitForBSYClear (IdeDev, ATATIMEOUT);
422 if (EFI_ERROR (Status)) {
423 return EFI_DEVICE_ERROR;
424 }
425
426 //
427 // e0:1110,0000-- bit7 and bit5 are reserved bits.
428 // bit6 set means LBA mode
429 //
430 IDEWritePortB (
431 IdeDev->PciIo,
432 IdeDev->IoPort->Head,
433 (UINT8) ((IdeDev->Device << 4) | 0xe0 | Head)
434 );
435
436 //
437 // All ATAPI device's ATA commands can be issued regardless of the
438 // state of the DRDY
439 //
440 if (IdeDev->Type == IdeHardDisk) {
441
442 Status = DRDYReady (IdeDev, ATATIMEOUT);
443 if (EFI_ERROR (Status)) {
444 return EFI_DEVICE_ERROR;
445 }
446 }
447 //
448 // set all the command parameters
449 // Before write to all the following registers, BSY and DRQ must be 0.
450 //
451 Status = DRQClear2 (IdeDev, ATATIMEOUT);
452 if (EFI_ERROR (Status)) {
453 return EFI_DEVICE_ERROR;
454 }
455
456 if (AtaCommand == SET_FEATURES_CMD) {
457 IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->Reg1.Feature, 0x03);
458 }
459
460 IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->SectorCount, SectorCount);
461 IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->SectorNumber, SectorNumber);
462 IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->CylinderLsb, CylinderLsb);
463 IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->CylinderMsb, CylinderMsb);
464
465 //
466 // send command via Command Register
467 //
468 IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->Reg.Command, AtaCommand);
469
470 Buffer16 = (UINT16 *) Buffer;
471
472 //
473 // According to PIO data in protocol, host can perform a series of reads to
474 // the data register after each time device set DRQ ready;
475 // The data size of "a series of read" is command specific.
476 // For most ATA command, data size received from device will not exceed
477 // 1 sector, hence the data size for "a series of read" can be the whole data
478 // size of one command request.
479 // For ATA command such as Read Sector command, the data size of one ATA
480 // command request is often larger than 1 sector, according to the
481 // Read Sector command, the data size of "a series of read" is exactly 1
482 // sector.
483 // Here for simplification reason, we specify the data size for
484 // "a series of read" to 1 sector (256 words) if data size of one ATA command
485 // request is larger than 256 words.
486 //
487 Increment = 256;
488
489 //
490 // used to record bytes of currently transfered data
491 //
492 WordCount = 0;
493
494 while (WordCount < ByteCount / 2) {
495 //
496 // Poll DRQ bit set, data transfer can be performed only when DRQ is ready.
497 //
498 Status = DRQReady2 (IdeDev, ATATIMEOUT);
499 if (EFI_ERROR (Status)) {
500 return EFI_DEVICE_ERROR;
501 }
502
503 Status = CheckErrorStatus (IdeDev);
504 if (EFI_ERROR (Status)) {
505 return EFI_DEVICE_ERROR;
506 }
507
508 //
509 // Get the byte count for one series of read
510 //
511 if ((WordCount + Increment) > ByteCount / 2) {
512 Increment = ByteCount / 2 - WordCount;
513 }
514
515 IDEReadPortWMultiple (
516 IdeDev->PciIo,
517 IdeDev->IoPort->Data,
518 Increment,
519 Buffer16
520 );
521
522 WordCount += Increment;
523 Buffer16 += Increment;
524
525 }
526
527 DRQClear (IdeDev, ATATIMEOUT);
528
529 return CheckErrorStatus (IdeDev);
530 }
531
532 EFI_STATUS
533 AtaPioDataOut (
534 IN IDE_BLK_IO_DEV *IdeDev,
535 IN VOID *Buffer,
536 IN UINT32 ByteCount,
537 IN UINT8 AtaCommand,
538 IN UINT8 Head,
539 IN UINT8 SectorCount,
540 IN UINT8 SectorNumber,
541 IN UINT8 CylinderLsb,
542 IN UINT8 CylinderMsb
543 )
544 /*++
545 Name:
546 AtaPioDataOut
547
548
549 Purpose:
550 This function is used to send out ATA commands conforms to the
551 PIO Data Out Protocol.
552
553
554 Parameters:
555 IDE_BLK_IO_DEV IN *IdeDev
556 pointer pointing to IDE_BLK_IO_DEV data structure, used
557 to record all the information of the IDE device.
558
559 VOID IN *Buffer
560 buffer contained data transferred from host to device.
561
562 UINT32 IN ByteCount
563 data size in byte unit of the buffer.
564
565 UINT8 IN AtaCommand
566 value of the Command Register
567
568 UINT8 IN Head
569 value of the Head/Device Register
570
571 UINT8 IN SectorCount
572 value of the Sector Count Register
573
574 UINT8 IN SectorNumber
575 value of the Sector Number Register
576
577 UINT8 IN CylinderLsb
578 value of the low byte of the Cylinder Register
579
580 UINT8 IN CylinderMsb
581 value of the high byte of the Cylinder Register
582
583
584 Returns:
585 EFI_SUCCESS
586 send out the ATA command and device received required
587 data successfully.
588
589 EFI_DEVICE_ERROR
590 command sent failed.
591
592 Notes:
593 --*/
594 // TODO: function comment is missing 'Routine Description:'
595 // TODO: function comment is missing 'Arguments:'
596 // TODO: IdeDev - add argument and description to function comment
597 // TODO: Buffer - add argument and description to function comment
598 // TODO: ByteCount - add argument and description to function comment
599 // TODO: AtaCommand - add argument and description to function comment
600 // TODO: Head - add argument and description to function comment
601 // TODO: SectorCount - add argument and description to function comment
602 // TODO: SectorNumber - add argument and description to function comment
603 // TODO: CylinderLsb - add argument and description to function comment
604 // TODO: CylinderMsb - add argument and description to function comment
605 {
606 UINTN WordCount;
607 UINTN Increment;
608 UINT16 *Buffer16;
609 EFI_STATUS Status;
610
611 Status = WaitForBSYClear (IdeDev, ATATIMEOUT);
612 if (EFI_ERROR (Status)) {
613 return EFI_DEVICE_ERROR;
614 }
615
616 //
617 // select device via Head/Device register.
618 // Before write Head/Device register, BSY and DRQ must be 0.
619 //
620 Status = DRQClear2 (IdeDev, ATATIMEOUT);
621 if (EFI_ERROR (Status)) {
622 return EFI_DEVICE_ERROR;
623 }
624
625 //
626 // e0:1110,0000-- bit7 and bit5 are reserved bits.
627 // bit6 set means LBA mode
628 //
629 IDEWritePortB (
630 IdeDev->PciIo,
631 IdeDev->IoPort->Head,
632 (UINT8) ((IdeDev->Device << 4) | 0xe0 | Head)
633 );
634
635 Status = DRDYReady (IdeDev, ATATIMEOUT);
636 if (EFI_ERROR (Status)) {
637 return EFI_DEVICE_ERROR;
638 }
639
640 //
641 // set all the command parameters
642 // Before write to all the following registers, BSY and DRQ must be 0.
643 //
644 Status = DRQClear2 (IdeDev, ATATIMEOUT);
645 if (EFI_ERROR (Status)) {
646 return EFI_DEVICE_ERROR;
647 }
648
649 IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->SectorCount, SectorCount);
650 IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->SectorNumber, SectorNumber);
651 IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->CylinderLsb, CylinderLsb);
652 IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->CylinderMsb, CylinderMsb);
653
654 //
655 // send command via Command Register
656 //
657 IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->Reg.Command, AtaCommand);
658
659 Buffer16 = (UINT16 *) Buffer;
660
661 //
662 // According to PIO data out protocol, host can perform a series of
663 // writes to the data register after each time device set DRQ ready;
664 // The data size of "a series of read" is command specific.
665 // For most ATA command, data size written to device will not exceed 1 sector,
666 // hence the data size for "a series of write" can be the data size of one
667 // command request.
668 // For ATA command such as Write Sector command, the data size of one
669 // ATA command request is often larger than 1 sector, according to the
670 // Write Sector command, the data size of "a series of read" is exactly
671 // 1 sector.
672 // Here for simplification reason, we specify the data size for
673 // "a series of write" to 1 sector (256 words) if data size of one ATA command
674 // request is larger than 256 words.
675 //
676 Increment = 256;
677 WordCount = 0;
678
679 while (WordCount < ByteCount / 2) {
680
681 //
682 // DRQReady2-- read Alternate Status Register to determine the DRQ bit
683 // data transfer can be performed only when DRQ is ready.
684 //
685 Status = DRQReady2 (IdeDev, ATATIMEOUT);
686 if (EFI_ERROR (Status)) {
687 return EFI_DEVICE_ERROR;
688 }
689
690 Status = CheckErrorStatus (IdeDev);
691 if (EFI_ERROR (Status)) {
692 return EFI_DEVICE_ERROR;
693 }
694
695 //
696 // Check the remaining byte count is less than 512 bytes
697 //
698 if ((WordCount + Increment) > ByteCount / 2) {
699 Increment = ByteCount / 2 - WordCount;
700 }
701 //
702 // perform a series of write without check DRQ ready
703 //
704
705 IDEWritePortWMultiple (
706 IdeDev->PciIo,
707 IdeDev->IoPort->Data,
708 Increment,
709 Buffer16
710 );
711 WordCount += Increment;
712 Buffer16 += Increment;
713
714 }
715
716 DRQClear (IdeDev, ATATIMEOUT);
717
718 return CheckErrorStatus (IdeDev);
719 }
720
721 EFI_STATUS
722 CheckErrorStatus (
723 IN IDE_BLK_IO_DEV *IdeDev
724 )
725 /*++
726 Name:
727 CheckErrorStatus
728
729
730 Purpose:
731 This function is used to analyze the Status Register and print out
732 some debug information and if there is ERR bit set in the Status
733 Register, the Error Register's value is also be parsed and print out.
734
735
736 Parameters:
737 IDE_BLK_IO_DEV IN *IdeDev
738 pointer pointing to IDE_BLK_IO_DEV data structure, used
739 to record all the information of the IDE device.
740
741 Returns:
742 EFI_SUCCESS
743 No err information in the Status Register.
744
745 EFI_DEVICE_ERROR
746 Any err information in the Status Register.
747
748 Notes:
749 --*/
750 // TODO: function comment is missing 'Routine Description:'
751 // TODO: function comment is missing 'Arguments:'
752 // TODO: IdeDev - add argument and description to function comment
753 {
754 UINT8 StatusRegister;
755
756 //#ifdef EFI_DEBUG
757
758 UINT8 ErrorRegister;
759
760 //#endif
761
762 StatusRegister = IDEReadPortB (IdeDev->PciIo, IdeDev->IoPort->Reg.Status);
763
764 DEBUG_CODE (
765
766 if (StatusRegister & DWF) {
767 DEBUG (
768 (EFI_D_BLKIO,
769 "CheckErrorStatus()-- %02x : Error : Write Fault\n",
770 StatusRegister)
771 );
772 }
773
774 if (StatusRegister & CORR) {
775 DEBUG (
776 (EFI_D_BLKIO,
777 "CheckErrorStatus()-- %02x : Error : Corrected Data\n",
778 StatusRegister)
779 );
780 }
781
782 if (StatusRegister & ERR) {
783 ErrorRegister = IDEReadPortB (IdeDev->PciIo, IdeDev->IoPort->Reg1.Error);
784
785 if (ErrorRegister & BBK_ERR) {
786 DEBUG (
787 (EFI_D_BLKIO,
788 "CheckErrorStatus()-- %02x : Error : Bad Block Detected\n",
789 ErrorRegister)
790 );
791 }
792
793 if (ErrorRegister & UNC_ERR) {
794 DEBUG (
795 (EFI_D_BLKIO,
796 "CheckErrorStatus()-- %02x : Error : Uncorrectable Data\n",
797 ErrorRegister)
798 );
799 }
800
801 if (ErrorRegister & MC_ERR) {
802 DEBUG (
803 (EFI_D_BLKIO,
804 "CheckErrorStatus()-- %02x : Error : Media Change\n",
805 ErrorRegister)
806 );
807 }
808
809 if (ErrorRegister & ABRT_ERR) {
810 DEBUG (
811 (EFI_D_BLKIO,
812 "CheckErrorStatus()-- %02x : Error : Abort\n",
813 ErrorRegister)
814 );
815 }
816
817 if (ErrorRegister & TK0NF_ERR) {
818 DEBUG (
819 (EFI_D_BLKIO,
820 "CheckErrorStatus()-- %02x : Error : Track 0 Not Found\n",
821 ErrorRegister)
822 );
823 }
824
825 if (ErrorRegister & AMNF_ERR) {
826 DEBUG (
827 (EFI_D_BLKIO,
828 "CheckErrorStatus()-- %02x : Error : Address Mark Not Found\n",
829 ErrorRegister)
830 );
831 }
832
833 }
834 );
835
836 if ((StatusRegister & (ERR | DWF | CORR)) == 0) {
837 return EFI_SUCCESS;
838 }
839
840 return EFI_DEVICE_ERROR;
841
842 }
843
844 EFI_STATUS
845 AtaReadSectors (
846 IN IDE_BLK_IO_DEV *IdeDev,
847 IN VOID *DataBuffer,
848 IN EFI_LBA Lba,
849 IN UINTN NumberOfBlocks
850 )
851 /*++
852 Name:
853 AtaReadSectors
854
855
856 Purpose:
857 This function is called by the AtaBlkIoReadBlocks() to perform
858 reading from media in block unit.
859
860
861 Parameters:
862 IDE_BLK_IO_DEV IN *IdeDev
863 pointer pointing to IDE_BLK_IO_DEV data structure, used
864 to record all the information of the IDE device.
865
866 VOID IN *DataBuffer
867 A pointer to the destination buffer for the data.
868
869 EFI_LBA IN Lba
870 The starting logical block address to read from
871 on the device media.
872
873 UINTN IN NumberOfBlocks
874 The number of transfer data blocks.
875
876 Returns:
877 return status is fully dependent on the return status
878 of AtaPioDataIn() function.
879
880 Notes:
881 --*/
882 // TODO: function comment is missing 'Routine Description:'
883 // TODO: function comment is missing 'Arguments:'
884 // TODO: IdeDev - add argument and description to function comment
885 // TODO: DataBuffer - add argument and description to function comment
886 // TODO: Lba - add argument and description to function comment
887 // TODO: NumberOfBlocks - add argument and description to function comment
888 {
889 EFI_STATUS Status;
890 UINTN BlocksRemaining;
891 UINT32 Lba32;
892 UINT8 Lba0;
893 UINT8 Lba1;
894 UINT8 Lba2;
895 UINT8 Lba3;
896 UINT8 AtaCommand;
897 UINT8 SectorCount8;
898 UINT16 SectorCount;
899 UINTN ByteCount;
900 VOID *Buffer;
901
902 Buffer = DataBuffer;
903
904 //
905 // Using ATA Read Sector(s) command (opcode=0x20) with PIO DATA IN protocol
906 //
907 AtaCommand = READ_SECTORS_CMD;
908
909
910 BlocksRemaining = NumberOfBlocks;
911
912 Lba32 = (UINT32) Lba;
913
914 Status = EFI_SUCCESS;
915
916 while (BlocksRemaining > 0) {
917
918 //
919 // in ATA-3 spec, LBA is in 28 bit width
920 //
921 Lba0 = (UINT8) Lba32;
922 Lba1 = (UINT8) (Lba32 >> 8);
923 Lba2 = (UINT8) (Lba32 >> 16);
924 //
925 // low 4 bit of Lba3 stands for LBA bit24~bit27.
926 //
927 Lba3 = (UINT8) ((Lba32 >> 24) & 0x0f);
928
929 if (BlocksRemaining >= 0x100) {
930
931 //
932 // SectorCount8 is sent to Sector Count register, 0x00 means 256
933 // sectors to be read
934 //
935 SectorCount8 = 0x00;
936 //
937 // SectorCount is used to record the number of sectors to be read
938 //
939 SectorCount = 256;
940 } else {
941
942 SectorCount8 = (UINT8) BlocksRemaining;
943 SectorCount = (UINT16) BlocksRemaining;
944 }
945
946 //
947 // ByteCount is the number of bytes that will be read
948 //
949 ByteCount = SectorCount * (IdeDev->BlkIo.Media->BlockSize);
950
951 //
952 // call AtaPioDataIn() to send Read Sector Command and receive data read
953 //
954 Status = AtaPioDataIn (
955 IdeDev,
956 Buffer,
957 (UINT32) ByteCount,
958 AtaCommand,
959 Lba3,
960 SectorCount8,
961 Lba0,
962 Lba1,
963 Lba2
964 );
965 if (EFI_ERROR (Status)) {
966 return Status;
967 }
968
969 Lba32 += SectorCount;
970 Buffer = ((UINT8 *) Buffer + ByteCount);
971 BlocksRemaining -= SectorCount;
972 }
973
974 return Status;
975 }
976
977 EFI_STATUS
978 AtaWriteSectors (
979 IN IDE_BLK_IO_DEV *IdeDev,
980 IN VOID *BufferData,
981 IN EFI_LBA Lba,
982 IN UINTN NumberOfBlocks
983 )
984 /*++
985 Name:
986 AtaWriteSectors
987
988
989 Purpose:
990 This function is called by the AtaBlkIoWriteBlocks() to perform
991 writing onto media in block unit.
992
993
994 Parameters:
995 IDE_BLK_IO_DEV IN *IdeDev
996 pointer pointing to IDE_BLK_IO_DEV data structure,used
997 to record all the information of the IDE device.
998
999 VOID IN *BufferData
1000 A pointer to the source buffer for the data.
1001
1002 EFI_LBA IN Lba
1003 The starting logical block address to write onto
1004 the device media.
1005
1006 UINTN IN NumberOfBlocks
1007 The number of transfer data blocks.
1008
1009
1010 Returns:
1011 return status is fully dependent on the return status
1012 of AtaPioDataOut() function.
1013
1014 Notes:
1015 --*/
1016 // TODO: function comment is missing 'Routine Description:'
1017 // TODO: function comment is missing 'Arguments:'
1018 // TODO: IdeDev - add argument and description to function comment
1019 // TODO: BufferData - add argument and description to function comment
1020 // TODO: Lba - add argument and description to function comment
1021 // TODO: NumberOfBlocks - add argument and description to function comment
1022 {
1023 EFI_STATUS Status;
1024 UINTN BlocksRemaining;
1025 UINT32 Lba32;
1026 UINT8 Lba0;
1027 UINT8 Lba1;
1028 UINT8 Lba2;
1029 UINT8 Lba3;
1030 UINT8 AtaCommand;
1031 UINT8 SectorCount8;
1032 UINT16 SectorCount;
1033 UINTN ByteCount;
1034 VOID *Buffer;
1035
1036 Buffer = BufferData;
1037
1038 //
1039 // Using Write Sector(s) command (opcode=0x30) with PIO DATA OUT protocol
1040 //
1041 AtaCommand = WRITE_SECTORS_CMD;
1042
1043 BlocksRemaining = NumberOfBlocks;
1044
1045 Lba32 = (UINT32) Lba;
1046
1047 Status = EFI_SUCCESS;
1048
1049 while (BlocksRemaining > 0) {
1050
1051 Lba0 = (UINT8) Lba32;
1052 Lba1 = (UINT8) (Lba32 >> 8);
1053 Lba2 = (UINT8) (Lba32 >> 16);
1054 Lba3 = (UINT8) ((Lba32 >> 24) & 0x0f);
1055
1056 if (BlocksRemaining >= 0x100) {
1057
1058 //
1059 // SectorCount8 is sent to Sector Count register, 0x00 means 256 sectors
1060 // to be written
1061 //
1062 SectorCount8 = 0x00;
1063 //
1064 // SectorCount is used to record the number of sectors to be written
1065 //
1066 SectorCount = 256;
1067 } else {
1068
1069 SectorCount8 = (UINT8) BlocksRemaining;
1070 SectorCount = (UINT16) BlocksRemaining;
1071 }
1072
1073 ByteCount = SectorCount * (IdeDev->BlkIo.Media->BlockSize);
1074
1075 Status = AtaPioDataOut (
1076 IdeDev,
1077 Buffer,
1078 (UINT32) ByteCount,
1079 AtaCommand,
1080 Lba3,
1081 SectorCount8,
1082 Lba0,
1083 Lba1,
1084 Lba2
1085 );
1086 if (EFI_ERROR (Status)) {
1087 return Status;
1088 }
1089
1090 Lba32 += SectorCount;
1091 Buffer = ((UINT8 *) Buffer + ByteCount);
1092 BlocksRemaining -= SectorCount;
1093 }
1094
1095 return Status;
1096 }
1097
1098 EFI_STATUS
1099 AtaSoftReset (
1100 IN IDE_BLK_IO_DEV *IdeDev
1101 )
1102 /*++
1103 Name:
1104 AtaSoftReset
1105
1106 Purpose:
1107 This function is used to implement the Soft Reset on the specified
1108 device. But, the ATA Soft Reset mechanism is so strong a reset method
1109 that it will force resetting on both devices connected to the
1110 same cable.
1111 It is called by IdeBlkIoReset(), a interface function of Block
1112 I/O protocol.
1113 This function can also be used by the ATAPI device to perform reset when
1114 ATAPI Reset command is failed.
1115
1116 Parameters:
1117 IDE_BLK_IO_DEV IN *IdeDev
1118 pointer pointing to IDE_BLK_IO_DEV data structure, used
1119 to record all the information of the IDE device.
1120 Returns:
1121 EFI_SUCCESS
1122 Soft reset completes successfully.
1123
1124 EFI_DEVICE_ERROR
1125 Any step during the reset process is failed.
1126 Notes:
1127 The registers initial values after ATA soft reset are different
1128 to the ATA device and ATAPI device.
1129 --*/
1130 // TODO: function comment is missing 'Routine Description:'
1131 // TODO: function comment is missing 'Arguments:'
1132 // TODO: IdeDev - add argument and description to function comment
1133 {
1134
1135 UINT8 DeviceControl;
1136
1137 DeviceControl = 0;
1138 //
1139 // set SRST bit to initiate soft reset
1140 //
1141 DeviceControl |= SRST;
1142
1143 //
1144 // disable Interrupt
1145 //
1146 DeviceControl |= bit1;
1147
1148 IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->Alt.DeviceControl, DeviceControl);
1149
1150 gBS->Stall (10);
1151
1152 //
1153 // Enable interrupt to support UDMA, and clear SRST bit
1154 //
1155 DeviceControl = 0;
1156 IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->Alt.DeviceControl, DeviceControl);
1157
1158 //
1159 // slave device needs at most 31s to clear BSY
1160 //
1161 if (WaitForBSYClear (IdeDev, 31000) == EFI_TIMEOUT) {
1162 return EFI_DEVICE_ERROR;
1163 }
1164
1165 return EFI_SUCCESS;
1166 }
1167
1168 EFI_STATUS
1169 AtaBlkIoReadBlocks (
1170 IN IDE_BLK_IO_DEV *IdeBlkIoDevice,
1171 IN UINT32 MediaId,
1172 IN EFI_LBA LBA,
1173 IN UINTN BufferSize,
1174 OUT VOID *Buffer
1175 )
1176 /*++
1177 Name:
1178 AtaBlkIoReadBlocks
1179
1180
1181 Purpose:
1182 This function is the ATA implementation for ReadBlocks in the
1183 Block I/O Protocol interface.
1184
1185
1186 Parameters:
1187 IDE_BLK_IO_DEV IN *IdeBlkIoDevice
1188 Indicates the calling context.
1189
1190 UINT32 IN MediaId
1191 The media id that the read request is for.
1192
1193 EFI_LBA IN LBA
1194 The starting logical block address to read from
1195 on the device.
1196
1197 UINTN IN BufferSize
1198 The size of the Buffer in bytes. This must be a
1199 multiple of the intrinsic block size of the device.
1200
1201 VOID OUT *Buffer
1202 A pointer to the destination buffer for the data.
1203 The caller is responsible for either having implicit
1204 or explicit ownership of the memory that data is read into.
1205
1206 Returns:
1207 EFI_SUCCESS
1208 Read Blocks successfully.
1209
1210 EFI_DEVICE_ERROR
1211 Read Blocks failed.
1212
1213 EFI_NO_MEDIA
1214 There is no media in the device.
1215
1216 EFI_MEDIA_CHANGE
1217 The MediaId is not for the current media.
1218
1219 EFI_BAD_BUFFER_SIZE
1220 The BufferSize parameter is not a multiple of the
1221 intrinsic block size of the device.
1222
1223 EFI_INVALID_PARAMETER
1224 The read request contains LBAs that are not valid,
1225 or the data buffer is not valid.
1226
1227 Notes:
1228 If Read Block error because of device error, this function will call
1229 AtaSoftReset() function to reset device.
1230 --*/
1231 // TODO: function comment is missing 'Routine Description:'
1232 // TODO: function comment is missing 'Arguments:'
1233 // TODO: IdeBlkIoDevice - add argument and description to function comment
1234 // TODO: MediaId - add argument and description to function comment
1235 // TODO: LBA - add argument and description to function comment
1236 // TODO: BufferSize - add argument and description to function comment
1237 // TODO: Buffer - add argument and description to function comment
1238 // TODO: EFI_MEDIA_CHANGED - add return value to function comment
1239 {
1240 EFI_BLOCK_IO_MEDIA *Media;
1241 UINTN BlockSize;
1242 UINTN NumberOfBlocks;
1243 EFI_STATUS Status;
1244
1245 if (Buffer == NULL) {
1246 return EFI_INVALID_PARAMETER;
1247 }
1248
1249 if (BufferSize == 0) {
1250 return EFI_SUCCESS;
1251 }
1252
1253 Status = EFI_SUCCESS;
1254
1255 //
1256 // Get the intrinsic block size
1257 //
1258 Media = IdeBlkIoDevice->BlkIo.Media;
1259 BlockSize = Media->BlockSize;
1260
1261 NumberOfBlocks = BufferSize / BlockSize;
1262
1263 if (MediaId != Media->MediaId) {
1264 return EFI_MEDIA_CHANGED;
1265 }
1266
1267 if (BufferSize % BlockSize != 0) {
1268 return EFI_BAD_BUFFER_SIZE;
1269 }
1270
1271 if (!(Media->MediaPresent)) {
1272 return EFI_NO_MEDIA;
1273 }
1274
1275 if (LBA > Media->LastBlock) {
1276 return EFI_INVALID_PARAMETER;
1277 }
1278
1279 if ((LBA + NumberOfBlocks - 1) > Media->LastBlock) {
1280 return EFI_INVALID_PARAMETER;
1281 }
1282
1283 if ((Media->IoAlign > 1) && (((UINTN) Buffer & (Media->IoAlign - 1)) != 0)) {
1284 return EFI_INVALID_PARAMETER;
1285 }
1286
1287 if (IdeBlkIoDevice->Type == Ide48bitAddressingHardDisk) {
1288 //
1289 // For ATA/ATAPI-6 device(capcity > 120GB), use ATA-6 read block mechanism
1290 //
1291 Status = AtaUdmaReadExt (IdeBlkIoDevice, Buffer, LBA, NumberOfBlocks);
1292 if (EFI_ERROR (Status)) {
1293 Status = AtaReadSectorsExt (IdeBlkIoDevice, Buffer, LBA, NumberOfBlocks);
1294 }
1295 } else {
1296 //
1297 // For ATA-3 compatible device, use ATA-3 read block mechanism
1298 // Notice DMA operation can only handle 32bit address
1299 //
1300 if ((UINTN) Buffer <= 0xFFFFFFFF) {
1301 Status = AtaUdmaRead (IdeBlkIoDevice, Buffer, LBA, NumberOfBlocks);
1302 }
1303
1304 if (EFI_ERROR (Status) || ((UINTN) Buffer > 0xFFFFFFFF)) {
1305 Status = AtaReadSectors (IdeBlkIoDevice, Buffer, LBA, NumberOfBlocks);
1306 }
1307 }
1308
1309 if (EFI_ERROR (Status)) {
1310 AtaSoftReset (IdeBlkIoDevice);
1311 return EFI_DEVICE_ERROR;
1312 }
1313
1314 return EFI_SUCCESS;
1315
1316 }
1317
1318 EFI_STATUS
1319 AtaBlkIoWriteBlocks (
1320 IN IDE_BLK_IO_DEV *IdeBlkIoDevice,
1321 IN UINT32 MediaId,
1322 IN EFI_LBA LBA,
1323 IN UINTN BufferSize,
1324 OUT VOID *Buffer
1325 )
1326 /*++
1327 Name:
1328 AtaBlkIoWriteBlocks
1329
1330
1331 Purpose:
1332 This function is the ATA implementation for WriteBlocks in the
1333 Block I/O Protocol interface.
1334
1335 Parameters:
1336 IDE_BLK_IO_DEV IN *IdeBlkIoDevice
1337 Indicates the calling context.
1338
1339 UINT32 IN MediaId
1340 The media id that the write request is for.
1341
1342 EFI_LBA IN LBA
1343 The starting logical block address to write onto
1344 the device.
1345
1346 UINTN IN BufferSize
1347 The size of the Buffer in bytes. This must be a
1348 multiple of the intrinsic block size of the device.
1349
1350 VOID OUT *Buffer
1351 A pointer to the source buffer for the data.
1352 The caller is responsible for either having implicit
1353 or explicit ownership of the memory that data is
1354 written from.
1355
1356
1357 Returns:
1358 EFI_SUCCESS
1359 Write Blocks successfully.
1360
1361 EFI_DEVICE_ERROR
1362 Write Blocks failed.
1363
1364 EFI_NO_MEDIA
1365 There is no media in the device.
1366
1367 EFI_MEDIA_CHANGE
1368 The MediaId is not for the current media.
1369
1370 EFI_BAD_BUFFER_SIZE
1371 The BufferSize parameter is not a multiple of the
1372 intrinsic block size of the device.
1373
1374 EFI_INVALID_PARAMETER
1375 The write request contains LBAs that are not valid,
1376 or the data buffer is not valid.
1377
1378 Notes:
1379 If Write Block error because of device error, this function will call
1380 AtaSoftReset() function to reset device.
1381 --*/
1382 // TODO: function comment is missing 'Routine Description:'
1383 // TODO: function comment is missing 'Arguments:'
1384 // TODO: IdeBlkIoDevice - add argument and description to function comment
1385 // TODO: MediaId - add argument and description to function comment
1386 // TODO: LBA - add argument and description to function comment
1387 // TODO: BufferSize - add argument and description to function comment
1388 // TODO: Buffer - add argument and description to function comment
1389 // TODO: EFI_MEDIA_CHANGED - add return value to function comment
1390 {
1391
1392 EFI_BLOCK_IO_MEDIA *Media;
1393 UINTN BlockSize;
1394 UINTN NumberOfBlocks;
1395 EFI_STATUS Status;
1396
1397 if (Buffer == NULL) {
1398 return EFI_INVALID_PARAMETER;
1399 }
1400
1401 if (BufferSize == 0) {
1402 return EFI_SUCCESS;
1403 }
1404
1405 Status = EFI_SUCCESS;
1406
1407 //
1408 // Get the intrinsic block size
1409 //
1410 Media = IdeBlkIoDevice->BlkIo.Media;
1411 BlockSize = Media->BlockSize;
1412 NumberOfBlocks = BufferSize / BlockSize;
1413
1414 if (MediaId != Media->MediaId) {
1415 return EFI_MEDIA_CHANGED;
1416 }
1417
1418 if (BufferSize % BlockSize != 0) {
1419 return EFI_BAD_BUFFER_SIZE;
1420 }
1421
1422 if (LBA > Media->LastBlock) {
1423 return EFI_INVALID_PARAMETER;
1424 }
1425
1426 if ((LBA + NumberOfBlocks - 1) > Media->LastBlock) {
1427 return EFI_INVALID_PARAMETER;
1428 }
1429
1430 if ((Media->IoAlign > 1) && (((UINTN) Buffer & (Media->IoAlign - 1)) != 0)) {
1431 return EFI_INVALID_PARAMETER;
1432 }
1433
1434 if (IdeBlkIoDevice->Type == Ide48bitAddressingHardDisk) {
1435 //
1436 // For ATA/ATAPI-6 device(capcity > 120GB), use ATA-6 write block mechanism
1437 //
1438 Status = AtaUdmaWriteExt (IdeBlkIoDevice, Buffer, LBA, NumberOfBlocks);
1439 if (EFI_ERROR (Status)) {
1440 Status = AtaWriteSectorsExt (IdeBlkIoDevice, Buffer, LBA, NumberOfBlocks);
1441 }
1442 } else {
1443 //
1444 // For ATA-3 compatible device, use ATA-3 write block mechanism
1445 //
1446 Status = AtaUdmaWrite (IdeBlkIoDevice, Buffer, LBA, NumberOfBlocks);
1447 if (EFI_ERROR (Status) || ((UINTN) Buffer > 0xFFFFFFFF)) {
1448 Status = AtaWriteSectors (IdeBlkIoDevice, Buffer, LBA, NumberOfBlocks);
1449 }
1450 }
1451
1452 if (EFI_ERROR (Status)) {
1453 AtaSoftReset (IdeBlkIoDevice);
1454 return EFI_DEVICE_ERROR;
1455 }
1456
1457 return EFI_SUCCESS;
1458 }
1459
1460 EFI_STATUS
1461 AtaReadSectorsExt (
1462 IN IDE_BLK_IO_DEV *IdeDev,
1463 IN VOID *DataBuffer,
1464 IN EFI_LBA StartLba,
1465 IN UINTN NumberOfBlocks
1466 )
1467 /*++
1468 Name:
1469
1470 AtaReadSectorsExt
1471
1472 Purpose:
1473
1474 This function is called by the AtaBlkIoReadBlocks() to perform
1475 reading from media in block unit. The function has been enhanced to
1476 support >120GB access and transfer at most 65536 blocks per command
1477
1478 Parameters:
1479
1480 IDE_BLK_IO_DEV IN *IdeDev
1481 pointer pointing to IDE_BLK_IO_DEV data structure, used
1482 to record all the information of the IDE device.
1483
1484 VOID IN *DataBuffer
1485 A pointer to the destination buffer for the data.
1486
1487 EFI_LBA IN StartLba
1488 The starting logical block address to read from
1489 on the device media.
1490
1491 UINTN IN NumberOfBlocks
1492 The number of transfer data blocks.
1493
1494 Returns:
1495
1496 return status is fully dependent on the return status
1497 of AtaPioDataInExt() function.
1498
1499 Notes:
1500 --*/
1501 // TODO: function comment is missing 'Routine Description:'
1502 // TODO: function comment is missing 'Arguments:'
1503 // TODO: IdeDev - add argument and description to function comment
1504 // TODO: DataBuffer - add argument and description to function comment
1505 // TODO: StartLba - add argument and description to function comment
1506 // TODO: NumberOfBlocks - add argument and description to function comment
1507 {
1508 EFI_STATUS Status;
1509 UINTN BlocksRemaining;
1510 EFI_LBA Lba64;
1511 UINT8 AtaCommand;
1512 UINT16 SectorCount;
1513 UINT32 ByteCount;
1514 VOID *Buffer;
1515
1516 //
1517 // Using ATA "Read Sectors Ext" command(opcode=0x24) with PIO DATA IN protocol
1518 //
1519 AtaCommand = READ_SECTORS_EXT_CMD;
1520 Buffer = DataBuffer;
1521 BlocksRemaining = NumberOfBlocks;
1522 Lba64 = StartLba;
1523 Status = EFI_SUCCESS;
1524
1525 while (BlocksRemaining > 0) {
1526
1527 if (BlocksRemaining >= 0x10000) {
1528 //
1529 // SectorCount is used to record the number of sectors to be read
1530 // Max 65536 sectors can be transfered at a time.
1531 //
1532 SectorCount = 0xffff;
1533 } else {
1534 SectorCount = (UINT16) BlocksRemaining;
1535 }
1536
1537 //
1538 // ByteCount is the number of bytes that will be read
1539 //
1540 ByteCount = SectorCount * (IdeDev->BlkIo.Media->BlockSize);
1541
1542 //
1543 // call AtaPioDataInExt() to send Read Sector Command and receive data read
1544 //
1545 Status = AtaPioDataInExt (
1546 IdeDev,
1547 Buffer,
1548 ByteCount,
1549 AtaCommand,
1550 Lba64,
1551 SectorCount
1552 );
1553 if (EFI_ERROR (Status)) {
1554 return Status;
1555 }
1556
1557 Lba64 += SectorCount;
1558 Buffer = ((UINT8 *) Buffer + ByteCount);
1559 BlocksRemaining -= SectorCount;
1560 }
1561
1562 return Status;
1563 }
1564
1565 EFI_STATUS
1566 AtaWriteSectorsExt (
1567 IN IDE_BLK_IO_DEV *IdeDev,
1568 IN VOID *DataBuffer,
1569 IN EFI_LBA StartLba,
1570 IN UINTN NumberOfBlocks
1571 )
1572 /*++
1573 Name:
1574
1575 AtaWriteSectorsExt
1576
1577 Purpose:
1578
1579 This function is called by the AtaBlkIoWriteBlocks() to perform
1580 writing onto media in block unit. The function has been enhanced to
1581 support >120GB access and transfer at most 65536 blocks per command
1582
1583 Parameters:
1584
1585 IDE_BLK_IO_DEV IN *IdeDev
1586 pointer pointing to IDE_BLK_IO_DEV data structure,used
1587 to record all the information of the IDE device.
1588
1589 VOID IN *DataBuffer
1590 A pointer to the source buffer for the data.
1591
1592 EFI_LBA IN Lba
1593 The starting logical block address to write onto
1594 the device media.
1595
1596 UINTN IN NumberOfBlocks
1597 The number of transfer data blocks.
1598
1599 Returns:
1600
1601 return status is fully dependent on the return status
1602 of AtaPioDataOutExt() function.
1603
1604 Notes:
1605 --*/
1606 // TODO: function comment is missing 'Routine Description:'
1607 // TODO: function comment is missing 'Arguments:'
1608 // TODO: IdeDev - add argument and description to function comment
1609 // TODO: DataBuffer - add argument and description to function comment
1610 // TODO: StartLba - add argument and description to function comment
1611 // TODO: NumberOfBlocks - add argument and description to function comment
1612 {
1613 EFI_STATUS Status;
1614 EFI_LBA Lba64;
1615 UINTN BlocksRemaining;
1616 UINT8 AtaCommand;
1617 UINT16 SectorCount;
1618 UINT32 ByteCount;
1619 VOID *Buffer;
1620
1621 //
1622 // Using ATA "Write Sectors Ext" cmd(opcode=0x24) with PIO DATA OUT protocol
1623 //
1624 AtaCommand = WRITE_SECTORS_EXT_CMD;
1625 Lba64 = StartLba;
1626 Buffer = DataBuffer;
1627 BlocksRemaining = NumberOfBlocks;
1628
1629 Status = EFI_SUCCESS;
1630
1631 while (BlocksRemaining > 0) {
1632
1633 if (BlocksRemaining >= 0x10000) {
1634 //
1635 // SectorCount is used to record the number of sectors to be written.
1636 // Max 65536 sectors can be transfered at a time.
1637 //
1638 SectorCount = 0xffff;
1639 } else {
1640 SectorCount = (UINT16) BlocksRemaining;
1641 }
1642
1643 //
1644 // ByteCount is the number of bytes that will be written
1645 //
1646 ByteCount = SectorCount * (IdeDev->BlkIo.Media->BlockSize);
1647
1648 //
1649 // Call AtaPioDataOutExt() to send "Write Sectors Ext" Command
1650 //
1651 Status = AtaPioDataOutExt (
1652 IdeDev,
1653 Buffer,
1654 ByteCount,
1655 AtaCommand,
1656 Lba64,
1657 SectorCount
1658 );
1659 if (EFI_ERROR (Status)) {
1660 return Status;
1661 }
1662
1663 Lba64 += SectorCount;
1664 Buffer = ((UINT8 *) Buffer + ByteCount);
1665 BlocksRemaining -= SectorCount;
1666 }
1667
1668 return Status;
1669 }
1670
1671 EFI_STATUS
1672 AtaPioDataInExt (
1673 IN IDE_BLK_IO_DEV *IdeDev,
1674 IN OUT VOID *Buffer,
1675 IN UINT32 ByteCount,
1676 IN UINT8 AtaCommand,
1677 IN EFI_LBA StartLba,
1678 IN UINT16 SectorCount
1679 )
1680 /*++
1681 Name:
1682
1683 AtaPioDataInExt
1684
1685 Purpose:
1686
1687 This function is used to send out ATA commands conforms to the
1688 PIO Data In Protocol, supporting ATA/ATAPI-6 standard
1689
1690 Comparing with ATA-3 data in protocol, we have two differents here:
1691 1. Do NOT wait for DRQ clear before sending command into IDE device.(the
1692 wait will frequently fail... cause writing function return error)
1693
1694 2. Do NOT wait for DRQ clear after all data readed.(the wait greatly
1695 slow down writing performance by 100 times!)
1696
1697
1698 Parameters:
1699
1700 IDE_BLK_IO_DEV IN *IdeDev
1701 pointer pointing to IDE_BLK_IO_DEV data structure, used
1702 to record all the information of the IDE device.
1703
1704 VOID IN OUT *Buffer
1705 buffer contained data transferred from device to host.
1706
1707 UINT32 IN ByteCount
1708 data size in byte unit of the buffer.
1709
1710 UINT8 IN AtaCommand
1711 value of the Command Register
1712
1713 EFI_LBA IN StartLba
1714 the start LBA of this transaction
1715
1716 UINT16 IN SectorCount
1717 the count of sectors to be transfered
1718
1719 Returns:
1720
1721 EFI_SUCCESS
1722 send out the ATA command and device send required
1723 data successfully.
1724
1725 EFI_DEVICE_ERROR
1726 command sent failed.
1727 Notes:
1728 --*/
1729 // TODO: function comment is missing 'Routine Description:'
1730 // TODO: function comment is missing 'Arguments:'
1731 // TODO: IdeDev - add argument and description to function comment
1732 // TODO: Buffer - add argument and description to function comment
1733 // TODO: ByteCount - add argument and description to function comment
1734 // TODO: AtaCommand - add argument and description to function comment
1735 // TODO: StartLba - add argument and description to function comment
1736 // TODO: SectorCount - add argument and description to function comment
1737 {
1738 UINT8 DevSel;
1739 UINT8 SectorCount8;
1740 UINT8 LbaLow;
1741 UINT8 LbaMid;
1742 UINT8 LbaHigh;
1743 UINTN WordCount;
1744 UINTN Increment;
1745 UINT16 *Buffer16;
1746 EFI_STATUS Status;
1747
1748 Status = WaitForBSYClear (IdeDev, ATATIMEOUT);
1749 if (EFI_ERROR (Status)) {
1750 return EFI_DEVICE_ERROR;
1751 }
1752
1753 //
1754 // Select device, set bit6 as 1 to indicate LBA mode is used
1755 //
1756 DevSel = (UINT8) (IdeDev->Device << 4);
1757 DevSel |= 0x40;
1758 IDEWritePortB (
1759 IdeDev->PciIo,
1760 IdeDev->IoPort->Head,
1761 DevSel
1762 );
1763
1764 //
1765 // Wait for DRDY singnal asserting. ATAPI device needn't wait
1766 //
1767 if ( (IdeDev->Type == IdeHardDisk) ||
1768 (IdeDev->Type == Ide48bitAddressingHardDisk)) {
1769
1770 Status = DRDYReady (IdeDev, ATATIMEOUT);
1771 if (EFI_ERROR (Status)) {
1772 return EFI_DEVICE_ERROR;
1773 }
1774 }
1775
1776 //
1777 // Fill feature register if needed
1778 //
1779 if (AtaCommand == SET_FEATURES_CMD) {
1780 IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->Reg1.Feature, 0x03);
1781 }
1782
1783 //
1784 // Fill the sector count register, which is a two-byte FIFO. Need write twice.
1785 //
1786 SectorCount8 = (UINT8) (SectorCount >> 8);
1787 IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->SectorCount, SectorCount8);
1788
1789 SectorCount8 = (UINT8) SectorCount;
1790 IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->SectorCount, SectorCount8);
1791
1792 //
1793 // Fill the start LBA registers, which are also two-byte FIFO
1794 //
1795 LbaLow = (UINT8) RShiftU64 (StartLba, 24);
1796 LbaMid = (UINT8) RShiftU64 (StartLba, 32);
1797 LbaHigh = (UINT8) RShiftU64 (StartLba, 40);
1798 IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->SectorNumber, LbaLow);
1799 IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->CylinderLsb, LbaMid);
1800 IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->CylinderMsb, LbaHigh);
1801
1802 LbaLow = (UINT8) StartLba;
1803 LbaMid = (UINT8) RShiftU64 (StartLba, 8);
1804 LbaHigh = (UINT8) RShiftU64 (StartLba, 16);
1805 IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->SectorNumber, LbaLow);
1806 IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->CylinderLsb, LbaMid);
1807 IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->CylinderMsb, LbaHigh);
1808
1809 //
1810 // Send command via Command Register, invoking the processing of this command
1811 //
1812 IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->Reg.Command, AtaCommand);
1813
1814 Buffer16 = (UINT16 *) Buffer;
1815
1816 //
1817 // According to PIO data in protocol, host can perform a series of reads to
1818 // the data register after each time device set DRQ ready;
1819 //
1820
1821 //
1822 // 256 words
1823 //
1824 Increment = 256;
1825
1826 //
1827 // used to record bytes of currently transfered data
1828 //
1829 WordCount = 0;
1830
1831 while (WordCount < ByteCount / 2) {
1832 //
1833 // Poll DRQ bit set, data transfer can be performed only when DRQ is ready.
1834 //
1835 Status = DRQReady2 (IdeDev, ATATIMEOUT);
1836 if (EFI_ERROR (Status)) {
1837 return EFI_DEVICE_ERROR;
1838 }
1839
1840 Status = CheckErrorStatus (IdeDev);
1841 if (EFI_ERROR (Status)) {
1842 return EFI_DEVICE_ERROR;
1843 }
1844
1845 //
1846 // Get the byte count for one series of read
1847 //
1848 if ((WordCount + Increment) > ByteCount / 2) {
1849 Increment = ByteCount / 2 - WordCount;
1850 }
1851
1852 IDEReadPortWMultiple (
1853 IdeDev->PciIo,
1854 IdeDev->IoPort->Data,
1855 Increment,
1856 Buffer16
1857 );
1858
1859 WordCount += Increment;
1860 Buffer16 += Increment;
1861
1862 }
1863
1864 return CheckErrorStatus (IdeDev);
1865 }
1866
1867 EFI_STATUS
1868 AtaPioDataOutExt (
1869 IN IDE_BLK_IO_DEV *IdeDev,
1870 IN VOID *Buffer,
1871 IN UINT32 ByteCount,
1872 IN UINT8 AtaCommand,
1873 IN EFI_LBA StartLba,
1874 IN UINT16 SectorCount
1875 )
1876 /*++
1877 Name:
1878
1879 AtaPioDataOutExt
1880
1881 Purpose:
1882
1883 This function is used to send out ATA commands conforms to the
1884 PIO Data Out Protocol, supporting ATA/ATAPI-6 standard
1885
1886 Comparing with ATA-3 data out protocol, we have two differents here:
1887 1. Do NOT wait for DRQ clear before sending command into IDE device.(the
1888 wait will frequently fail... cause writing function return error)
1889
1890 2. Do NOT wait for DRQ clear after all data readed.(the wait greatly
1891 slow down writing performance by 100 times!)
1892
1893 Parameters:
1894
1895 IDE_BLK_IO_DEV IN *IdeDev
1896 pointer pointing to IDE_BLK_IO_DEV data structure, used
1897 to record all the information of the IDE device.
1898
1899 VOID IN *Buffer
1900 buffer contained data transferred from host to device.
1901
1902 UINT32 IN ByteCount
1903 data size in byte unit of the buffer.
1904
1905 UINT8 IN AtaCommand
1906 value of the Command Register
1907
1908 EFI_LBA IN StartLba
1909 the start LBA of this transaction
1910
1911 UINT16 IN SectorCount
1912 the count of sectors to be transfered
1913
1914 Returns:
1915
1916 EFI_SUCCESS
1917 send out the ATA command and device receive required
1918 data successfully.
1919
1920 EFI_DEVICE_ERROR
1921 command sent failed.
1922 Notes:
1923 --*/
1924 // TODO: function comment is missing 'Routine Description:'
1925 // TODO: function comment is missing 'Arguments:'
1926 // TODO: IdeDev - add argument and description to function comment
1927 // TODO: Buffer - add argument and description to function comment
1928 // TODO: ByteCount - add argument and description to function comment
1929 // TODO: AtaCommand - add argument and description to function comment
1930 // TODO: StartLba - add argument and description to function comment
1931 // TODO: SectorCount - add argument and description to function comment
1932 {
1933 UINT8 DevSel;
1934 UINT8 SectorCount8;
1935 UINT8 LbaLow;
1936 UINT8 LbaMid;
1937 UINT8 LbaHigh;
1938 UINTN WordCount;
1939 UINTN Increment;
1940 UINT16 *Buffer16;
1941 EFI_STATUS Status;
1942
1943 Status = WaitForBSYClear (IdeDev, ATATIMEOUT);
1944 if (EFI_ERROR (Status)) {
1945 return EFI_DEVICE_ERROR;
1946 }
1947
1948 //
1949 // Select device. Set bit6 as 1 to indicate LBA mode is used
1950 //
1951 DevSel = (UINT8) (IdeDev->Device << 4);
1952 DevSel |= 0x40;
1953 IDEWritePortB (
1954 IdeDev->PciIo,
1955 IdeDev->IoPort->Head,
1956 DevSel
1957 );
1958
1959 //
1960 // Wait for DRDY singnal asserting.
1961 //
1962 Status = DRDYReady (IdeDev, ATATIMEOUT);
1963 if (EFI_ERROR (Status)) {
1964 return EFI_DEVICE_ERROR;
1965 }
1966
1967 //
1968 // Fill feature register if needed
1969 //
1970 if (AtaCommand == SET_FEATURES_CMD) {
1971 IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->Reg1.Feature, 0x03);
1972 }
1973
1974 //
1975 // Fill the sector count register, which is a two-byte FIFO. Need write twice.
1976 //
1977 SectorCount8 = (UINT8) (SectorCount >> 8);
1978 IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->SectorCount, SectorCount8);
1979
1980 SectorCount8 = (UINT8) SectorCount;
1981 IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->SectorCount, SectorCount8);
1982
1983 //
1984 // Fill the start LBA registers, which are also two-byte FIFO
1985 //
1986 LbaLow = (UINT8) RShiftU64 (StartLba, 24);
1987 LbaMid = (UINT8) RShiftU64 (StartLba, 32);
1988 LbaHigh = (UINT8) RShiftU64 (StartLba, 40);
1989 IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->SectorNumber, LbaLow);
1990 IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->CylinderLsb, LbaMid);
1991 IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->CylinderMsb, LbaHigh);
1992
1993 LbaLow = (UINT8) StartLba;
1994 LbaMid = (UINT8) RShiftU64 (StartLba, 8);
1995 LbaHigh = (UINT8) RShiftU64 (StartLba, 16);
1996 IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->SectorNumber, LbaLow);
1997 IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->CylinderLsb, LbaMid);
1998 IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->CylinderMsb, LbaHigh);
1999
2000 //
2001 // Send command via Command Register, invoking the processing of this command
2002 //
2003 IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->Reg.Command, AtaCommand);
2004
2005 Buffer16 = (UINT16 *) Buffer;
2006
2007 //
2008 // According to PIO Data Out protocol, host can perform a series of writes to
2009 // the data register after each time device set DRQ ready;
2010 //
2011 Increment = 256;
2012
2013 //
2014 // used to record bytes of currently transfered data
2015 //
2016 WordCount = 0;
2017
2018 while (WordCount < ByteCount / 2) {
2019 //
2020 // Poll DRQ bit set, data transfer can be performed only when DRQ is ready.
2021 //
2022 Status = DRQReady2 (IdeDev, ATATIMEOUT);
2023 if (EFI_ERROR (Status)) {
2024 return EFI_DEVICE_ERROR;
2025 }
2026
2027 Status = CheckErrorStatus (IdeDev);
2028 if (EFI_ERROR (Status)) {
2029 return EFI_DEVICE_ERROR;
2030 }
2031
2032 //
2033 // Write data into device by one series of writing to data register
2034 //
2035 if ((WordCount + Increment) > ByteCount / 2) {
2036 Increment = ByteCount / 2 - WordCount;
2037 }
2038
2039 IDEWritePortWMultiple (
2040 IdeDev->PciIo,
2041 IdeDev->IoPort->Data,
2042 Increment,
2043 Buffer16
2044 );
2045
2046 WordCount += Increment;
2047 Buffer16 += Increment;
2048
2049 }
2050 //
2051 // while
2052 //
2053
2054 return CheckErrorStatus (IdeDev);
2055 }
2056
2057
2058 VOID
2059 AtaSMARTSupport (
2060 IN IDE_BLK_IO_DEV *IdeDev
2061 )
2062 /*++
2063 Name:
2064 AtaSMARTSupport
2065
2066 Purpose:
2067
2068 Enable SMART of the disk if supported
2069
2070 Parameters:
2071
2072 IDE_BLK_IO_DEV IN *IdeDev
2073 pointer pointing to IDE_BLK_IO_DEV data structure,used
2074 to record all the information of the IDE device.
2075
2076 Returns:
2077
2078 NONE
2079 --*/
2080 // TODO: function comment is missing 'Routine Description:'
2081 // TODO: function comment is missing 'Arguments:'
2082 // TODO: IdeDev - add argument and description to function comment
2083 {
2084 EFI_STATUS Status;
2085 BOOLEAN SMARTSupported;
2086 UINT8 Device;
2087 EFI_IDENTIFY_DATA *TmpAtaIdentifyPointer;
2088 UINT8 DeviceSelect;
2089 UINT8 LBAMid;
2090 UINT8 LBAHigh;
2091
2092 //
2093 // Detect if the device supports S.M.A.R.T.
2094 //
2095 if ((IdeDev->pIdData->AtaData.command_set_supported_83 & 0xc000) != 0x4000) {
2096 //
2097 // Data in word 82 is not valid (bit15 shall be zero and bit14 shall be to one)
2098 //
2099 return ;
2100 } else {
2101 if ((IdeDev->pIdData->AtaData.command_set_supported_82 & 0x0001) != 0x0001) {
2102 //
2103 // S.M.A.R.T is not supported by the device
2104 //
2105 SMARTSupported = FALSE;
2106 } else {
2107 SMARTSupported = TRUE;
2108 }
2109 }
2110
2111 if (!SMARTSupported) {
2112 //
2113 // Report nonsupport status code
2114 //
2115 REPORT_STATUS_CODE (
2116 EFI_ERROR_CODE | EFI_ERROR_MINOR,
2117 (EFI_IO_BUS_ATA_ATAPI | EFI_IOB_ATA_BUS_SMART_NOTSUPPORTED)
2118 );
2119 } else {
2120 //
2121 // Enable this feature
2122 //
2123 REPORT_STATUS_CODE (
2124 EFI_PROGRESS_CODE,
2125 (EFI_IO_BUS_ATA_ATAPI | EFI_IOB_ATA_BUS_SMART_ENABLE)
2126 );
2127
2128 Device = (UINT8) ((IdeDev->Device << 4) | 0xe0);
2129 Status = AtaNonDataCommandIn (
2130 IdeDev,
2131 ATA_SMART_CMD,
2132 Device,
2133 ATA_SMART_ENABLE_OPERATION,
2134 0,
2135 0,
2136 ATA_CONSTANT_4F,
2137 ATA_CONSTANT_C2
2138 );
2139 //
2140 // Detect if this feature is enabled
2141 //
2142 TmpAtaIdentifyPointer = (EFI_IDENTIFY_DATA *) AllocateZeroPool (sizeof (EFI_IDENTIFY_DATA));
2143
2144 DeviceSelect = (UINT8) ((IdeDev->Device) << 4);
2145 Status = AtaPioDataIn (
2146 IdeDev,
2147 (VOID *) TmpAtaIdentifyPointer,
2148 sizeof (EFI_IDENTIFY_DATA),
2149 IDENTIFY_DRIVE_CMD,
2150 DeviceSelect,
2151 0,
2152 0,
2153 0,
2154 0
2155 );
2156 if (EFI_ERROR (Status)) {
2157 gBS->FreePool (TmpAtaIdentifyPointer);
2158 return ;
2159 }
2160
2161 //
2162 // Check if the feature is enabled
2163 //
2164 if ((TmpAtaIdentifyPointer->AtaData.command_set_feature_enb_85 & 0x0001) == 0x0001) {
2165 //
2166 // Read status data
2167 //
2168 AtaNonDataCommandIn (
2169 IdeDev,
2170 ATA_SMART_CMD,
2171 Device,
2172 ATA_SMART_RETURN_STATUS,
2173 0,
2174 0,
2175 ATA_CONSTANT_4F,
2176 ATA_CONSTANT_C2
2177 );
2178 LBAMid = IDEReadPortB (IdeDev->PciIo, IdeDev->IoPort->CylinderLsb);
2179 LBAHigh = IDEReadPortB (IdeDev->PciIo, IdeDev->IoPort->CylinderMsb);
2180
2181 if ((LBAMid == 0x4f) && (LBAHigh == 0xc2)) {
2182 //
2183 // The threshold exceeded condition is not detected by the device
2184 //
2185 REPORT_STATUS_CODE (
2186 EFI_PROGRESS_CODE,
2187 (EFI_IO_BUS_ATA_ATAPI | EFI_IOB_ATA_BUS_SMART_UNDERTHRESHOLD)
2188 );
2189
2190 } else if ((LBAMid == 0xf4) && (LBAHigh == 0x2c)) {
2191 //
2192 // The threshold exceeded condition is detected by the device
2193 //
2194 REPORT_STATUS_CODE (
2195 EFI_PROGRESS_CODE,
2196 (EFI_IO_BUS_ATA_ATAPI | EFI_IOB_ATA_BUS_SMART_OVERTHRESHOLD)
2197 );
2198 }
2199
2200 } else {
2201 //
2202 // Report disabled status code
2203 //
2204 REPORT_STATUS_CODE (
2205 EFI_ERROR_CODE | EFI_ERROR_MINOR,
2206 (EFI_IO_BUS_ATA_ATAPI | EFI_IOB_ATA_BUS_SMART_DISABLED)
2207 );
2208 }
2209
2210 gBS->FreePool (TmpAtaIdentifyPointer);
2211 }
2212
2213 return ;
2214 }
2215
2216 EFI_STATUS
2217 AtaCommandIssueExt (
2218 IN IDE_BLK_IO_DEV *IdeDev,
2219 IN UINT8 AtaCommand,
2220 IN UINT8 Device,
2221 IN UINT16 Feature,
2222 IN UINT16 SectorCount,
2223 IN EFI_LBA LbaAddress
2224 )
2225 /*++
2226
2227 Routine Description:
2228
2229 Send ATA Ext command into device with NON_DATA protocol
2230
2231 Arguments:
2232
2233 IdeDev - Standard IDE device private data structure
2234 AtaCommand - The ATA command to be sent
2235 Device - The value in Device register
2236 Feature - The value in Feature register
2237 SectorCount - The value in SectorCount register
2238 LbaAddress - The LBA address in 48-bit mode
2239
2240 Returns:
2241
2242 EFI_SUCCESS - Reading succeed
2243 EFI_DEVICE_ERROR - Error executing commands on this device
2244
2245 --*/
2246 {
2247 EFI_STATUS Status;
2248 UINT8 SectorCount8;
2249 UINT8 Feature8;
2250 UINT8 LbaLow;
2251 UINT8 LbaMid;
2252 UINT8 LbaHigh;
2253
2254 Status = WaitForBSYClear (IdeDev, ATATIMEOUT);
2255 if (EFI_ERROR (Status)) {
2256 return EFI_DEVICE_ERROR;
2257 }
2258
2259 //
2260 // Select device (bit4), set LBA mode(bit6) (use 0xe0 for compatibility)
2261 //
2262 IDEWritePortB (
2263 IdeDev->PciIo,
2264 IdeDev->IoPort->Head,
2265 (UINT8) ((IdeDev->Device << 4) | 0xe0)
2266 );
2267
2268 //
2269 // ATA commands for ATA device must be issued when DRDY is set
2270 //
2271 Status = DRDYReady (IdeDev, ATATIMEOUT);
2272 if (EFI_ERROR (Status)) {
2273 return EFI_DEVICE_ERROR;
2274 }
2275
2276 //
2277 // Pass parameter into device register block
2278 //
2279 IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->Head, Device);
2280
2281 //
2282 // Fill the feature register, which is a two-byte FIFO. Need write twice.
2283 //
2284 Feature8 = (UINT8) (Feature >> 8);
2285 IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->Reg1.Feature, Feature8);
2286
2287 Feature8 = (UINT8) Feature;
2288 IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->Reg1.Feature, Feature8);
2289
2290 //
2291 // Fill the sector count register, which is a two-byte FIFO. Need write twice.
2292 //
2293 SectorCount8 = (UINT8) (SectorCount >> 8);
2294 IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->SectorCount, SectorCount8);
2295
2296 SectorCount8 = (UINT8) SectorCount;
2297 IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->SectorCount, SectorCount8);
2298
2299 //
2300 // Fill the start LBA registers, which are also two-byte FIFO
2301 //
2302 LbaLow = (UINT8) RShiftU64 (LbaAddress, 24);
2303 IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->SectorNumber, LbaLow);
2304 LbaLow = (UINT8) LbaAddress;
2305 IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->SectorNumber, LbaLow);
2306
2307 LbaMid = (UINT8) RShiftU64 (LbaAddress, 32);
2308 IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->CylinderLsb, LbaMid);
2309 LbaMid = (UINT8) RShiftU64 (LbaAddress, 8);
2310 IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->CylinderLsb, LbaMid);
2311
2312 LbaHigh = (UINT8) RShiftU64 (LbaAddress, 40);
2313 IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->CylinderMsb, LbaHigh);
2314 LbaHigh = (UINT8) RShiftU64 (LbaAddress, 16);
2315 IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->CylinderMsb, LbaHigh);
2316
2317 //
2318 // Work around for Segate 160G disk writing
2319 //
2320 gBS->Stall (1800);
2321
2322 //
2323 // Send command via Command Register
2324 //
2325 IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->Reg.Command, AtaCommand);
2326
2327 //
2328 // Stall at least 400ns
2329 //
2330 gBS->Stall (100);
2331
2332 return EFI_SUCCESS;
2333 }
2334
2335 EFI_STATUS
2336 AtaCommandIssue (
2337 IN IDE_BLK_IO_DEV *IdeDev,
2338 IN UINT8 AtaCommand,
2339 IN UINT8 Device,
2340 IN UINT16 Feature,
2341 IN UINT16 SectorCount,
2342 IN EFI_LBA LbaAddress
2343 )
2344 /*++
2345
2346 Routine Description:
2347
2348 Send ATA Ext command into device with NON_DATA protocol
2349
2350 Arguments:
2351
2352 IdeDev - Standard IDE device private data structure
2353 AtaCommand - The ATA command to be sent
2354 Device - The value in Device register
2355 Feature - The value in Feature register
2356 SectorCount - The value in SectorCount register
2357 LbaAddress - The LBA address in 48-bit mode
2358
2359 Returns:
2360
2361 EFI_SUCCESS - Reading succeed
2362 EFI_DEVICE_ERROR - Error executing commands on this device
2363
2364 --*/
2365 {
2366 EFI_STATUS Status;
2367 UINT8 SectorCount8;
2368 UINT8 Feature8;
2369 UINT8 Lba0;
2370 UINT8 Lba1;
2371 UINT8 Lba2;
2372 UINT8 Lba3;
2373
2374 Status = WaitForBSYClear (IdeDev, ATATIMEOUT);
2375 if (EFI_ERROR (Status)) {
2376 return EFI_DEVICE_ERROR;
2377 }
2378
2379 //
2380 // Select device (bit4), set LBA mode(bit6) (use 0xe0 for compatibility)
2381 //
2382 IDEWritePortB (
2383 IdeDev->PciIo,
2384 IdeDev->IoPort->Head,
2385 (UINT8) ((IdeDev->Device << 4) | 0xe0)
2386 );
2387
2388 //
2389 // ATA commands for ATA device must be issued when DRDY is set
2390 //
2391 Status = DRDYReady (IdeDev, ATATIMEOUT);
2392 if (EFI_ERROR (Status)) {
2393 return EFI_DEVICE_ERROR;
2394 }
2395
2396 Lba0 = (UINT8) LbaAddress;
2397 Lba1 = (UINT8) RShiftU64 (LbaAddress, 8);
2398 Lba2 = (UINT8) RShiftU64 (LbaAddress, 16);
2399 Lba3 = (UINT8) RShiftU64 (LbaAddress, 24);
2400 Device |= Lba3;
2401
2402 //
2403 // Pass parameter into device register block
2404 //
2405 IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->Head, Device);
2406
2407 //
2408 // Fill the feature register, which is a two-byte FIFO. Need write twice.
2409 //
2410 Feature8 = (UINT8) Feature;
2411 IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->Reg1.Feature, Feature8);
2412
2413 //
2414 // Fill the sector count register, which is a two-byte FIFO. Need write twice.
2415 //
2416 SectorCount8 = (UINT8) SectorCount;
2417 IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->SectorCount, SectorCount8);
2418
2419 //
2420 // Fill the start LBA registers, which are also two-byte FIFO
2421 //
2422
2423 IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->SectorNumber, Lba0);
2424 IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->CylinderLsb, Lba1);
2425 IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->CylinderMsb, Lba2);
2426
2427 //
2428 // Send command via Command Register
2429 //
2430 IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->Reg.Command, AtaCommand);
2431
2432 //
2433 // Stall at least 400ns
2434 //
2435 gBS->Stall (100);
2436
2437 return EFI_SUCCESS;
2438 }
2439
2440 EFI_STATUS
2441 AtaUdmaReadExt (
2442 IN IDE_BLK_IO_DEV *IdeDev,
2443 IN VOID *DataBuffer,
2444 IN EFI_LBA StartLba,
2445 IN UINTN NumberOfBlocks
2446 )
2447 /*++
2448 Name:
2449
2450 AtaUdmaReadExt
2451
2452 Purpose:
2453
2454 This function is called by the AtaBlkIoReadBlocks() to perform
2455 reading from media in block unit. The function has been enhanced to
2456 support >120GB access and transfer at most 65536 blocks per command
2457
2458 Parameters:
2459
2460 IDE_BLK_IO_DEV IN *IdeDev
2461 pointer pointing to IDE_BLK_IO_DEV data structure, used
2462 to record all the information of the IDE device.
2463
2464 VOID IN *DataBuffer
2465 A pointer to the destination buffer for the data.
2466
2467 EFI_LBA IN StartLba
2468 The starting logical block address to read from
2469 on the device media.
2470
2471 UINTN IN NumberOfBlocks
2472 The number of transfer data blocks.
2473
2474 Returns:
2475
2476 The device status of UDMA operation. If the operation is
2477 successful, return EFI_SUCCESS.
2478
2479 --*/
2480 // TODO: function comment is missing 'Routine Description:'
2481 // TODO: function comment is missing 'Arguments:'
2482 // TODO: IdeDev - add argument and description to function comment
2483 // TODO: DataBuffer - add argument and description to function comment
2484 // TODO: StartLba - add argument and description to function comment
2485 // TODO: NumberOfBlocks - add argument and description to function comment
2486 // TODO: EFI_UNSUPPORTED - add return value to function comment
2487 // TODO: EFI_DEVICE_ERROR - add return value to function comment
2488 // TODO: EFI_DEVICE_ERROR - add return value to function comment
2489 // TODO: EFI_DEVICE_ERROR - add return value to function comment
2490 {
2491 IDE_DMA_PRD *PrdAddr;
2492 IDE_DMA_PRD *UsedPrdAddr;
2493 IDE_DMA_PRD *TempPrdAddr;
2494 UINT8 RegisterValue;
2495 UINT8 Device;
2496 UINT64 IoPortForBmic;
2497 UINT64 IoPortForBmis;
2498 UINT64 IoPortForBmid;
2499 EFI_STATUS Status;
2500 UINTN PrdTableNum;
2501 UINTN ByteCount;
2502 UINTN ByteAvailable;
2503 UINT8 *PrdBuffer;
2504 UINTN RemainBlockNum;
2505 UINT8 DeviceControl;
2506
2507 //
2508 // Channel and device differential. Select device.
2509 //
2510 Device = (UINT8) ((IdeDev->Device << 4) | 0xe0);
2511
2512 //
2513 // Enable interrupt to support UDMA and Select device
2514 //
2515 DeviceControl = 0;
2516 IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->Alt.DeviceControl, DeviceControl);
2517
2518 IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->Head, Device);
2519
2520 if (IdePrimary == IdeDev->Channel) {
2521 IoPortForBmic = IdeDev->IoPort->BusMasterBaseAddr + BMICP_OFFSET;
2522 IoPortForBmis = IdeDev->IoPort->BusMasterBaseAddr + BMISP_OFFSET;
2523 IoPortForBmid = IdeDev->IoPort->BusMasterBaseAddr + BMIDP_OFFSET;
2524 } else {
2525 if (IdeSecondary == IdeDev->Channel) {
2526 IoPortForBmic = IdeDev->IoPort->BusMasterBaseAddr + BMICS_OFFSET;
2527 IoPortForBmis = IdeDev->IoPort->BusMasterBaseAddr + BMISS_OFFSET;
2528 IoPortForBmid = IdeDev->IoPort->BusMasterBaseAddr + BMIDS_OFFSET;
2529 } else {
2530 return EFI_UNSUPPORTED;
2531 }
2532 }
2533
2534 RemainBlockNum = NumberOfBlocks;
2535 while (RemainBlockNum > 0) {
2536
2537 if (RemainBlockNum >= MAX_DMA_EXT_COMMAND_SECTORS) {
2538 //
2539 // SectorCount is used to record the number of sectors to be read
2540 // Max 65536 sectors can be transfered at a time.
2541 //
2542 NumberOfBlocks = MAX_DMA_EXT_COMMAND_SECTORS;
2543 RemainBlockNum -= MAX_DMA_EXT_COMMAND_SECTORS;
2544 } else {
2545 NumberOfBlocks = (UINT16) RemainBlockNum;
2546 RemainBlockNum = 0;
2547 }
2548
2549 //
2550 // Calculate the number of PRD table to make sure the memory region
2551 // not cross 64K boundary
2552 //
2553 ByteCount = NumberOfBlocks * IdeDev->BlkIo.Media->BlockSize;
2554 PrdTableNum = ((ByteCount >> 16) + 1) + 1;
2555
2556 //
2557 // Build PRD table
2558 //
2559 PrdAddr = (IDE_DMA_PRD *) AllocateZeroPool ((2 * PrdTableNum * sizeof (IDE_DMA_PRD)));
2560
2561 //
2562 // To make sure PRD is allocated in one 64K page
2563 //
2564 if (((UINTN) PrdAddr & 0x0FFFF) > (((UINTN) PrdAddr + PrdTableNum * sizeof (IDE_DMA_PRD) - 1) & 0x0FFFF)) {
2565 UsedPrdAddr = (IDE_DMA_PRD *) ((UINTN) ((UINT8 *) PrdAddr + 0x10000) & 0xFFFF0000);
2566 } else {
2567 if ((UINTN) PrdAddr & 0x03) {
2568 UsedPrdAddr = (IDE_DMA_PRD *) ((UINTN) ((UINT8 *) PrdAddr + 0x04) & 0xFFFFFFFC);
2569 } else {
2570 UsedPrdAddr = PrdAddr;
2571 }
2572 }
2573
2574 //
2575 // Build the PRD table
2576 //
2577 PrdBuffer = DataBuffer;
2578 TempPrdAddr = UsedPrdAddr;
2579 while (TRUE) {
2580
2581 ByteAvailable = 0x10000 - ((UINTN) PrdBuffer & 0xFFFF);
2582
2583 if (ByteCount <= ByteAvailable) {
2584 TempPrdAddr->RegionBaseAddr = (UINT32) ((UINTN) PrdBuffer);
2585 TempPrdAddr->ByteCount = (UINT16) ByteCount;
2586 TempPrdAddr->EndOfTable = 0x8000;
2587 break;
2588 }
2589
2590 TempPrdAddr->RegionBaseAddr = (UINT32) ((UINTN) PrdBuffer);
2591 TempPrdAddr->ByteCount = (UINT16) ByteAvailable;
2592
2593 ByteCount -= ByteAvailable;
2594 PrdBuffer += ByteAvailable;
2595 TempPrdAddr++;
2596 }
2597
2598 //
2599 // Set the base address to BMID register
2600 //
2601 IdeDev->PciIo->Io.Write (
2602 IdeDev->PciIo,
2603 EfiPciIoWidthUint32,
2604 EFI_PCI_IO_PASS_THROUGH_BAR,
2605 IoPortForBmid,
2606 1,
2607 &UsedPrdAddr
2608 );
2609
2610 //
2611 // Set BMIC register to identify the operation direction
2612 //
2613 IdeDev->PciIo->Io.Read (
2614 IdeDev->PciIo,
2615 EfiPciIoWidthUint8,
2616 EFI_PCI_IO_PASS_THROUGH_BAR,
2617 IoPortForBmic,
2618 1,
2619 &RegisterValue
2620 );
2621
2622 RegisterValue |= BMIC_nREAD;
2623
2624 IdeDev->PciIo->Io.Write (
2625 IdeDev->PciIo,
2626 EfiPciIoWidthUint8,
2627 EFI_PCI_IO_PASS_THROUGH_BAR,
2628 IoPortForBmic,
2629 1,
2630 &RegisterValue
2631 );
2632
2633 //
2634 // Read BMIS register and clear ERROR and INTR bit
2635 //
2636 IdeDev->PciIo->Io.Read (
2637 IdeDev->PciIo,
2638 EfiPciIoWidthUint8,
2639 EFI_PCI_IO_PASS_THROUGH_BAR,
2640 IoPortForBmis,
2641 1,
2642 &RegisterValue
2643 );
2644
2645 RegisterValue |= BMIS_INTERRUPT | BMIS_ERROR;
2646
2647 IdeDev->PciIo->Io.Write (
2648 IdeDev->PciIo,
2649 EfiPciIoWidthUint8,
2650 EFI_PCI_IO_PASS_THROUGH_BAR,
2651 IoPortForBmis,
2652 1,
2653 &RegisterValue
2654 );
2655
2656 //
2657 // Issue READ DMA EXT command
2658 //
2659 Status = AtaCommandIssueExt (
2660 IdeDev,
2661 READ_DMA_EXT_CMD,
2662 Device,
2663 0,
2664 (UINT16) NumberOfBlocks,
2665 StartLba
2666 );
2667 if (EFI_ERROR (Status)) {
2668 gBS->FreePool (PrdAddr);
2669 return EFI_DEVICE_ERROR;
2670 }
2671
2672 //
2673 // Set START bit of BMIC register
2674 //
2675 IdeDev->PciIo->Io.Read (
2676 IdeDev->PciIo,
2677 EfiPciIoWidthUint8,
2678 EFI_PCI_IO_PASS_THROUGH_BAR,
2679 IoPortForBmic,
2680 1,
2681 &RegisterValue
2682 );
2683
2684 RegisterValue |= BMIC_START;
2685
2686 IdeDev->PciIo->Io.Write (
2687 IdeDev->PciIo,
2688 EfiPciIoWidthUint8,
2689 EFI_PCI_IO_PASS_THROUGH_BAR,
2690 IoPortForBmic,
2691 1,
2692 &RegisterValue
2693 );
2694
2695 //
2696 // Check the INTERRUPT and ERROR bit of BMIS
2697 //
2698 while (TRUE) {
2699
2700 IdeDev->PciIo->Io.Read (
2701 IdeDev->PciIo,
2702 EfiPciIoWidthUint8,
2703 EFI_PCI_IO_PASS_THROUGH_BAR,
2704 IoPortForBmis,
2705 1,
2706 &RegisterValue
2707 );
2708 if (RegisterValue & (BMIS_INTERRUPT | BMIS_ERROR)) {
2709 if (RegisterValue & BMIS_ERROR) {
2710 gBS->FreePool (PrdAddr);
2711 return EFI_DEVICE_ERROR;
2712 }
2713 break;
2714 }
2715
2716 gBS->Stall (1000);
2717 }
2718
2719 gBS->FreePool (PrdAddr);
2720
2721 //
2722 // Set START bit of BMIC register
2723 //
2724 IdeDev->PciIo->Io.Read (
2725 IdeDev->PciIo,
2726 EfiPciIoWidthUint8,
2727 EFI_PCI_IO_PASS_THROUGH_BAR,
2728 IoPortForBmic,
2729 1,
2730 &RegisterValue
2731 );
2732
2733 RegisterValue &= ~((UINT8) BMIC_START);
2734
2735 IdeDev->PciIo->Io.Write (
2736 IdeDev->PciIo,
2737 EfiPciIoWidthUint8,
2738 EFI_PCI_IO_PASS_THROUGH_BAR,
2739 IoPortForBmic,
2740 1,
2741 &RegisterValue
2742 );
2743
2744 if (RegisterValue & BMIS_ERROR) {
2745 return EFI_DEVICE_ERROR;
2746 }
2747
2748 DataBuffer = (UINT8 *) DataBuffer + NumberOfBlocks * IdeDev->BlkIo.Media->BlockSize;
2749 StartLba += NumberOfBlocks;
2750 }
2751
2752 return EFI_SUCCESS;
2753 }
2754
2755 EFI_STATUS
2756 AtaUdmaRead (
2757 IN IDE_BLK_IO_DEV *IdeDev,
2758 IN VOID *DataBuffer,
2759 IN EFI_LBA StartLba,
2760 IN UINTN NumberOfBlocks
2761 )
2762 /*++
2763 Name:
2764
2765 AtaUdmaRead
2766
2767 Purpose:
2768
2769 This function is called by the AtaBlkIoReadBlocks() to perform
2770 reading from media in block unit. The function has been enhanced to
2771 support >120GB access and transfer at most 65536 blocks per command
2772
2773 Parameters:
2774
2775 IDE_BLK_IO_DEV IN *IdeDev
2776 pointer pointing to IDE_BLK_IO_DEV data structure, used
2777 to record all the information of the IDE device.
2778
2779 VOID IN *DataBuffer
2780 A pointer to the destination buffer for the data.
2781
2782 EFI_LBA IN StartLba
2783 The starting logical block address to read from
2784 on the device media.
2785
2786 UINTN IN NumberOfBlocks
2787 The number of transfer data blocks.
2788
2789 Returns:
2790
2791 The device status of UDMA operation. If the operation is
2792 successful, return EFI_SUCCESS.
2793
2794 --*/
2795 // TODO: function comment is missing 'Routine Description:'
2796 // TODO: function comment is missing 'Arguments:'
2797 // TODO: IdeDev - add argument and description to function comment
2798 // TODO: DataBuffer - add argument and description to function comment
2799 // TODO: StartLba - add argument and description to function comment
2800 // TODO: NumberOfBlocks - add argument and description to function comment
2801 // TODO: EFI_UNSUPPORTED - add return value to function comment
2802 // TODO: EFI_DEVICE_ERROR - add return value to function comment
2803 // TODO: EFI_DEVICE_ERROR - add return value to function comment
2804 // TODO: EFI_DEVICE_ERROR - add return value to function comment
2805 {
2806 IDE_DMA_PRD *PrdAddr;
2807 IDE_DMA_PRD *UsedPrdAddr;
2808 IDE_DMA_PRD *TempPrdAddr;
2809 UINT8 RegisterValue;
2810 UINT8 Device;
2811 UINT64 IoPortForBmic;
2812 UINT64 IoPortForBmis;
2813 UINT64 IoPortForBmid;
2814 EFI_STATUS Status;
2815 UINTN PrdTableNum;
2816 UINTN ByteCount;
2817 UINTN ByteAvailable;
2818 UINT8 *PrdBuffer;
2819 UINTN RemainBlockNum;
2820 UINT8 DeviceControl;
2821
2822 //
2823 // Channel and device differential
2824 //
2825 Device = (UINT8) ((IdeDev->Device << 4) | 0xe0);
2826
2827 //
2828 // Enable interrupt to support UDMA and Select device
2829 //
2830 DeviceControl = 0;
2831 IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->Alt.DeviceControl, DeviceControl);
2832
2833 IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->Head, Device);
2834
2835 if (IdePrimary == IdeDev->Channel) {
2836 IoPortForBmic = IdeDev->IoPort->BusMasterBaseAddr + BMICP_OFFSET;
2837 IoPortForBmis = IdeDev->IoPort->BusMasterBaseAddr + BMISP_OFFSET;
2838 IoPortForBmid = IdeDev->IoPort->BusMasterBaseAddr + BMIDP_OFFSET;
2839 } else {
2840 if (IdeSecondary == IdeDev->Channel) {
2841 IoPortForBmic = IdeDev->IoPort->BusMasterBaseAddr + BMICS_OFFSET;
2842 IoPortForBmis = IdeDev->IoPort->BusMasterBaseAddr + BMISS_OFFSET;
2843 IoPortForBmid = IdeDev->IoPort->BusMasterBaseAddr + BMIDS_OFFSET;
2844 } else {
2845 return EFI_UNSUPPORTED;
2846 }
2847 }
2848
2849 RemainBlockNum = NumberOfBlocks;
2850 while (RemainBlockNum > 0) {
2851
2852 if (RemainBlockNum >= MAX_DMA_COMMAND_SECTORS) {
2853 //
2854 // SectorCount is used to record the number of sectors to be read
2855 // Max 256 sectors can be transfered at a time.
2856 //
2857 NumberOfBlocks = MAX_DMA_COMMAND_SECTORS;
2858 RemainBlockNum -= MAX_DMA_COMMAND_SECTORS;
2859 } else {
2860 NumberOfBlocks = (UINT16) RemainBlockNum;
2861 RemainBlockNum = 0;
2862 }
2863
2864 //
2865 // Calculate the number of PRD table to make sure the memory region
2866 // not cross 64K boundary
2867 //
2868 ByteCount = NumberOfBlocks * IdeDev->BlkIo.Media->BlockSize;
2869 PrdTableNum = ((ByteCount >> 16) + 1) + 1;
2870
2871 //
2872 // Build PRD table
2873 //
2874 PrdAddr = (IDE_DMA_PRD *) AllocateZeroPool ((2 * PrdTableNum * sizeof (IDE_DMA_PRD)));
2875 //
2876 // To make sure PRD is allocated in one 64K page
2877 //
2878 if (((UINTN) PrdAddr & 0x0FFFF) > (((UINTN) PrdAddr + PrdTableNum * sizeof (IDE_DMA_PRD) - 1) & 0x0FFFF)) {
2879 UsedPrdAddr = (IDE_DMA_PRD *) ((UINTN) ((UINT8 *) PrdAddr + 0x10000) & 0xFFFF0000);
2880 } else {
2881 if ((UINTN) PrdAddr & 0x03) {
2882 UsedPrdAddr = (IDE_DMA_PRD *) ((UINTN) ((UINT8 *) PrdAddr + 0x04) & 0xFFFFFFFC);
2883 } else {
2884 UsedPrdAddr = PrdAddr;
2885 }
2886 }
2887
2888 //
2889 // Build the PRD table
2890 //
2891 PrdBuffer = DataBuffer;
2892 TempPrdAddr = UsedPrdAddr;
2893 while (TRUE) {
2894
2895 ByteAvailable = 0x10000 - ((UINTN) PrdBuffer & 0xFFFF);
2896
2897 if (ByteCount <= ByteAvailable) {
2898 TempPrdAddr->RegionBaseAddr = (UINT32) ((UINTN) PrdBuffer);
2899 TempPrdAddr->ByteCount = (UINT16) ByteCount;
2900 TempPrdAddr->EndOfTable = 0x8000;
2901 break;
2902 }
2903
2904 TempPrdAddr->RegionBaseAddr = (UINT32) ((UINTN) PrdBuffer);
2905 TempPrdAddr->ByteCount = (UINT16) ByteAvailable;
2906
2907 ByteCount -= ByteAvailable;
2908 PrdBuffer += ByteAvailable;
2909 TempPrdAddr++;
2910 }
2911
2912 //
2913 // Set the base address to BMID register
2914 //
2915 IdeDev->PciIo->Io.Write (
2916 IdeDev->PciIo,
2917 EfiPciIoWidthUint32,
2918 EFI_PCI_IO_PASS_THROUGH_BAR,
2919 IoPortForBmid,
2920 1,
2921 &UsedPrdAddr
2922 );
2923
2924 //
2925 // Set BMIC register to identify the operation direction
2926 //
2927 IdeDev->PciIo->Io.Read (
2928 IdeDev->PciIo,
2929 EfiPciIoWidthUint8,
2930 EFI_PCI_IO_PASS_THROUGH_BAR,
2931 IoPortForBmic,
2932 1,
2933 &RegisterValue
2934 );
2935
2936 RegisterValue |= BMIC_nREAD;
2937
2938 IdeDev->PciIo->Io.Write (
2939 IdeDev->PciIo,
2940 EfiPciIoWidthUint8,
2941 EFI_PCI_IO_PASS_THROUGH_BAR,
2942 IoPortForBmic,
2943 1,
2944 &RegisterValue
2945 );
2946
2947 //
2948 // Read BMIS register and clear ERROR and INTR bit
2949 //
2950 IdeDev->PciIo->Io.Read (
2951 IdeDev->PciIo,
2952 EfiPciIoWidthUint8,
2953 EFI_PCI_IO_PASS_THROUGH_BAR,
2954 IoPortForBmis,
2955 1,
2956 &RegisterValue
2957 );
2958
2959 RegisterValue |= (BMIS_INTERRUPT | BMIS_ERROR);
2960
2961 IdeDev->PciIo->Io.Write (
2962 IdeDev->PciIo,
2963 EfiPciIoWidthUint8,
2964 EFI_PCI_IO_PASS_THROUGH_BAR,
2965 IoPortForBmis,
2966 1,
2967 &RegisterValue
2968 );
2969
2970 //
2971 // Issue READ DMA command
2972 //
2973 Status = AtaCommandIssue (
2974 IdeDev,
2975 READ_DMA_CMD,
2976 Device,
2977 0,
2978 (UINT16) NumberOfBlocks,
2979 StartLba
2980 );
2981 if (EFI_ERROR (Status)) {
2982 gBS->FreePool (PrdAddr);
2983 return EFI_DEVICE_ERROR;
2984 }
2985
2986 //
2987 // Set START bit of BMIC register
2988 //
2989 IdeDev->PciIo->Io.Read (
2990 IdeDev->PciIo,
2991 EfiPciIoWidthUint8,
2992 EFI_PCI_IO_PASS_THROUGH_BAR,
2993 IoPortForBmic,
2994 1,
2995 &RegisterValue
2996 );
2997
2998 RegisterValue |= BMIC_START;
2999
3000 IdeDev->PciIo->Io.Write (
3001 IdeDev->PciIo,
3002 EfiPciIoWidthUint8,
3003 EFI_PCI_IO_PASS_THROUGH_BAR,
3004 IoPortForBmic,
3005 1,
3006 &RegisterValue
3007 );
3008
3009 //
3010 // Check the INTERRUPT and ERROR bit of BMIS
3011 //
3012 while (TRUE) {
3013
3014 IdeDev->PciIo->Io.Read (
3015 IdeDev->PciIo,
3016 EfiPciIoWidthUint8,
3017 EFI_PCI_IO_PASS_THROUGH_BAR,
3018 IoPortForBmis,
3019 1,
3020 &RegisterValue
3021 );
3022 if (RegisterValue & (BMIS_INTERRUPT | BMIS_ERROR)) {
3023 if (RegisterValue & BMIS_ERROR) {
3024 gBS->FreePool (PrdAddr);
3025 return EFI_DEVICE_ERROR;
3026 }
3027 break;
3028 }
3029
3030 gBS->Stall (1000);
3031 }
3032
3033 gBS->FreePool (PrdAddr);
3034
3035 //
3036 // Set START bit of BMIC register
3037 //
3038 IdeDev->PciIo->Io.Read (
3039 IdeDev->PciIo,
3040 EfiPciIoWidthUint8,
3041 EFI_PCI_IO_PASS_THROUGH_BAR,
3042 IoPortForBmic,
3043 1,
3044 &RegisterValue
3045 );
3046
3047 RegisterValue &= ~((UINT8) BMIC_START);
3048
3049 IdeDev->PciIo->Io.Write (
3050 IdeDev->PciIo,
3051 EfiPciIoWidthUint8,
3052 EFI_PCI_IO_PASS_THROUGH_BAR,
3053 IoPortForBmic,
3054 1,
3055 &RegisterValue
3056 );
3057
3058 if (RegisterValue & BMIS_ERROR) {
3059 return EFI_DEVICE_ERROR;
3060 }
3061
3062 DataBuffer = (UINT8 *) DataBuffer + NumberOfBlocks * IdeDev->BlkIo.Media->BlockSize;
3063 StartLba += NumberOfBlocks;
3064 }
3065
3066 return EFI_SUCCESS;
3067 }
3068
3069 EFI_STATUS
3070 AtaUdmaWriteExt (
3071 IN IDE_BLK_IO_DEV *IdeDev,
3072 IN VOID *DataBuffer,
3073 IN EFI_LBA StartLba,
3074 IN UINTN NumberOfBlocks
3075 )
3076 /*++
3077 Name:
3078
3079 AtaUdmaWriteExt
3080
3081 Purpose:
3082
3083 This function is called by the AtaBlkIoWriteBlocks() to perform
3084 writing to media in block unit. The function has been enhanced to
3085 support >120GB access and transfer at most 65536 blocks per command
3086
3087 Parameters:
3088
3089 IDE_BLK_IO_DEV IN *IdeDev
3090 pointer pointing to IDE_BLK_IO_DEV data structure, used
3091 to record all the information of the IDE device.
3092
3093 VOID IN *DataBuffer
3094 A pointer to the source buffer for the data.
3095
3096 EFI_LBA IN StartLba
3097 The starting logical block address to write to
3098 on the device media.
3099
3100 UINTN IN NumberOfBlocks
3101 The number of transfer data blocks.
3102
3103 Returns:
3104
3105 The device status of UDMA operation. If the operation is
3106 successful, return EFI_SUCCESS.
3107
3108 --*/
3109 // TODO: function comment is missing 'Routine Description:'
3110 // TODO: function comment is missing 'Arguments:'
3111 // TODO: IdeDev - add argument and description to function comment
3112 // TODO: DataBuffer - add argument and description to function comment
3113 // TODO: StartLba - add argument and description to function comment
3114 // TODO: NumberOfBlocks - add argument and description to function comment
3115 // TODO: EFI_UNSUPPORTED - add return value to function comment
3116 // TODO: EFI_DEVICE_ERROR - add return value to function comment
3117 // TODO: EFI_DEVICE_ERROR - add return value to function comment
3118 {
3119 IDE_DMA_PRD *PrdAddr;
3120 IDE_DMA_PRD *UsedPrdAddr;
3121 IDE_DMA_PRD *TempPrdAddr;
3122 UINT8 RegisterValue;
3123 UINT8 Device;
3124 UINT64 IoPortForBmic;
3125 UINT64 IoPortForBmis;
3126 UINT64 IoPortForBmid;
3127 EFI_STATUS Status;
3128 UINTN PrdTableNum;
3129 UINTN ByteCount;
3130 UINTN ByteAvailable;
3131 UINT8 *PrdBuffer;
3132 UINTN RemainBlockNum;
3133 UINT8 DeviceControl;
3134
3135 //
3136 // Channel and device differential
3137 //
3138 Device = (UINT8) ((IdeDev->Device << 4) | 0xe0);
3139
3140 //
3141 // Enable interrupt to support UDMA and Select device
3142 //
3143 DeviceControl = 0;
3144 IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->Alt.DeviceControl, DeviceControl);
3145
3146 IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->Head, Device);
3147
3148 if (IdePrimary == IdeDev->Channel) {
3149 IoPortForBmic = IdeDev->IoPort->BusMasterBaseAddr + BMICP_OFFSET;
3150 IoPortForBmis = IdeDev->IoPort->BusMasterBaseAddr + BMISP_OFFSET;
3151 IoPortForBmid = IdeDev->IoPort->BusMasterBaseAddr + BMIDP_OFFSET;
3152 } else {
3153 if (IdeSecondary == IdeDev->Channel) {
3154 IoPortForBmic = IdeDev->IoPort->BusMasterBaseAddr + BMICS_OFFSET;
3155 IoPortForBmis = IdeDev->IoPort->BusMasterBaseAddr + BMISS_OFFSET;
3156 IoPortForBmid = IdeDev->IoPort->BusMasterBaseAddr + BMIDS_OFFSET;
3157 } else {
3158 return EFI_UNSUPPORTED;
3159 }
3160 }
3161
3162 RemainBlockNum = NumberOfBlocks;
3163 while (RemainBlockNum > 0) {
3164
3165 if (RemainBlockNum >= MAX_DMA_EXT_COMMAND_SECTORS) {
3166 //
3167 // SectorCount is used to record the number of sectors to be read
3168 // Max 65536 sectors can be transfered at a time.
3169 //
3170 NumberOfBlocks = MAX_DMA_EXT_COMMAND_SECTORS;
3171 RemainBlockNum -= MAX_DMA_EXT_COMMAND_SECTORS;
3172 } else {
3173 NumberOfBlocks = (UINT16) RemainBlockNum;
3174 RemainBlockNum = 0;
3175 }
3176
3177 //
3178 // Calculate the number of PRD table to make sure the memory region
3179 // not cross 64K boundary
3180 //
3181 ByteCount = NumberOfBlocks * IdeDev->BlkIo.Media->BlockSize;
3182 PrdTableNum = ((ByteCount >> 16) + 1) + 1;
3183
3184 //
3185 // Build PRD table
3186 //
3187 PrdAddr = (IDE_DMA_PRD *) AllocateZeroPool ((2 * PrdTableNum * sizeof (IDE_DMA_PRD)));
3188 //
3189 // To make sure PRD is allocated in one 64K page
3190 //
3191 if (((UINTN) PrdAddr & 0x0FFFF) > (((UINTN) PrdAddr + PrdTableNum * sizeof (IDE_DMA_PRD) - 1) & 0x0FFFF)) {
3192 UsedPrdAddr = (IDE_DMA_PRD *) ((UINTN) ((UINT8 *) PrdAddr + 0x10000) & 0xFFFF0000);
3193 } else {
3194 if ((UINTN) PrdAddr & 0x03) {
3195 UsedPrdAddr = (IDE_DMA_PRD *) ((UINTN) ((UINT8 *) PrdAddr + 0x04) & 0xFFFFFFFC);
3196 } else {
3197 UsedPrdAddr = PrdAddr;
3198 }
3199 }
3200
3201 //
3202 // Build the PRD table
3203 //
3204 PrdBuffer = DataBuffer;
3205 TempPrdAddr = UsedPrdAddr;
3206 while (TRUE) {
3207
3208 ByteAvailable = 0x10000 - ((UINTN) PrdBuffer & 0xFFFF);
3209
3210 if (ByteCount <= ByteAvailable) {
3211 TempPrdAddr->RegionBaseAddr = (UINT32) ((UINTN) PrdBuffer);
3212 TempPrdAddr->ByteCount = (UINT16) ByteCount;
3213 TempPrdAddr->EndOfTable = 0x8000;
3214 break;
3215 }
3216
3217 TempPrdAddr->RegionBaseAddr = (UINT32) ((UINTN) PrdBuffer);
3218 TempPrdAddr->ByteCount = (UINT16) ByteAvailable;
3219
3220 ByteCount -= ByteAvailable;
3221 PrdBuffer += ByteAvailable;
3222 TempPrdAddr++;
3223 }
3224
3225 //
3226 // Set the base address to BMID register
3227 //
3228 IdeDev->PciIo->Io.Write (
3229 IdeDev->PciIo,
3230 EfiPciIoWidthUint32,
3231 EFI_PCI_IO_PASS_THROUGH_BAR,
3232 IoPortForBmid,
3233 1,
3234 &UsedPrdAddr
3235 );
3236
3237 //
3238 // Set BMIC register to identify the operation direction
3239 //
3240 IdeDev->PciIo->Io.Read (
3241 IdeDev->PciIo,
3242 EfiPciIoWidthUint8,
3243 EFI_PCI_IO_PASS_THROUGH_BAR,
3244 IoPortForBmic,
3245 1,
3246 &RegisterValue
3247 );
3248 //
3249 // 0000 1000
3250 //
3251 RegisterValue &= ~((UINT8) BMIC_nREAD);
3252
3253 IdeDev->PciIo->Io.Write (
3254 IdeDev->PciIo,
3255 EfiPciIoWidthUint8,
3256 EFI_PCI_IO_PASS_THROUGH_BAR,
3257 IoPortForBmic,
3258 1,
3259 &RegisterValue
3260 );
3261
3262 //
3263 // Read BMIS register and clear ERROR and INTR bit
3264 //
3265 IdeDev->PciIo->Io.Read (
3266 IdeDev->PciIo,
3267 EfiPciIoWidthUint8,
3268 EFI_PCI_IO_PASS_THROUGH_BAR,
3269 IoPortForBmis,
3270 1,
3271 &RegisterValue
3272 );
3273
3274 RegisterValue |= (BMIS_INTERRUPT | BMIS_ERROR);
3275
3276 IdeDev->PciIo->Io.Write (
3277 IdeDev->PciIo,
3278 EfiPciIoWidthUint8,
3279 EFI_PCI_IO_PASS_THROUGH_BAR,
3280 IoPortForBmis,
3281 1,
3282 &RegisterValue
3283 );
3284
3285 //
3286 // Issue WRITE DMA EXT command
3287 //
3288 Status = AtaCommandIssueExt (
3289 IdeDev,
3290 WRITE_DMA_EXT_CMD,
3291 Device,
3292 0,
3293 (UINT16) NumberOfBlocks,
3294 StartLba
3295 );
3296 if (EFI_ERROR (Status)) {
3297 gBS->FreePool (PrdAddr);
3298 return EFI_DEVICE_ERROR;
3299 }
3300
3301 //
3302 // Set START bit of BMIC register
3303 //
3304 IdeDev->PciIo->Io.Read (
3305 IdeDev->PciIo,
3306 EfiPciIoWidthUint8,
3307 EFI_PCI_IO_PASS_THROUGH_BAR,
3308 IoPortForBmic,
3309 1,
3310 &RegisterValue
3311 );
3312
3313 RegisterValue |= BMIC_START;
3314
3315 IdeDev->PciIo->Io.Write (
3316 IdeDev->PciIo,
3317 EfiPciIoWidthUint8,
3318 EFI_PCI_IO_PASS_THROUGH_BAR,
3319 IoPortForBmic,
3320 1,
3321 &RegisterValue
3322 );
3323
3324 //
3325 // Check the INTERRUPT and ERROR bit of BMIS
3326 //
3327 while (TRUE) {
3328
3329 IdeDev->PciIo->Io.Read (
3330 IdeDev->PciIo,
3331 EfiPciIoWidthUint8,
3332 EFI_PCI_IO_PASS_THROUGH_BAR,
3333 IoPortForBmis,
3334 1,
3335 &RegisterValue
3336 );
3337 if (RegisterValue & (BMIS_INTERRUPT | BMIS_ERROR)) {
3338 if (RegisterValue & BMIS_ERROR) {
3339 gBS->FreePool (PrdAddr);
3340 return EFI_DEVICE_ERROR;
3341 }
3342 break;
3343 }
3344
3345 gBS->Stall (1000);
3346 }
3347
3348 gBS->FreePool (PrdAddr);
3349
3350 //
3351 // Set START bit of BMIC register
3352 //
3353 IdeDev->PciIo->Io.Read (
3354 IdeDev->PciIo,
3355 EfiPciIoWidthUint8,
3356 EFI_PCI_IO_PASS_THROUGH_BAR,
3357 IoPortForBmic,
3358 1,
3359 &RegisterValue
3360 );
3361
3362 RegisterValue &= ~((UINT8) BMIC_START);
3363
3364 IdeDev->PciIo->Io.Write (
3365 IdeDev->PciIo,
3366 EfiPciIoWidthUint8,
3367 EFI_PCI_IO_PASS_THROUGH_BAR,
3368 IoPortForBmic,
3369 1,
3370 &RegisterValue
3371 );
3372
3373 DataBuffer = (UINT8 *) DataBuffer + NumberOfBlocks * IdeDev->BlkIo.Media->BlockSize;
3374 StartLba += NumberOfBlocks;
3375 }
3376
3377 return EFI_SUCCESS;
3378 }
3379
3380 EFI_STATUS
3381 AtaUdmaWrite (
3382 IN IDE_BLK_IO_DEV *IdeDev,
3383 IN VOID *DataBuffer,
3384 IN EFI_LBA StartLba,
3385 IN UINTN NumberOfBlocks
3386 )
3387 /*++
3388 Name:
3389
3390 AtaUdmaWrite
3391
3392 Purpose:
3393
3394 This function is called by the AtaBlkIoWriteBlocks() to perform
3395 writing to media in block unit. The function has been enhanced to
3396 support >120GB access and transfer at most 65536 blocks per command
3397
3398 Parameters:
3399
3400 IDE_BLK_IO_DEV IN *IdeDev
3401 pointer pointing to IDE_BLK_IO_DEV data structure, used
3402 to record all the information of the IDE device.
3403
3404 VOID IN *DataBuffer
3405 A pointer to the source buffer for the data.
3406
3407 EFI_LBA IN StartLba
3408 The starting logical block address to write to
3409 on the device media.
3410
3411 UINTN IN NumberOfBlocks
3412 The number of transfer data blocks.
3413
3414 Returns:
3415
3416 The device status of UDMA operation. If the operation is
3417 successful, return EFI_SUCCESS.
3418
3419 --*/
3420 // TODO: function comment is missing 'Routine Description:'
3421 // TODO: function comment is missing 'Arguments:'
3422 // TODO: IdeDev - add argument and description to function comment
3423 // TODO: DataBuffer - add argument and description to function comment
3424 // TODO: StartLba - add argument and description to function comment
3425 // TODO: NumberOfBlocks - add argument and description to function comment
3426 // TODO: EFI_UNSUPPORTED - add return value to function comment
3427 // TODO: EFI_DEVICE_ERROR - add return value to function comment
3428 // TODO: EFI_DEVICE_ERROR - add return value to function comment
3429 {
3430 IDE_DMA_PRD *PrdAddr;
3431 IDE_DMA_PRD *UsedPrdAddr;
3432 IDE_DMA_PRD *TempPrdAddr;
3433 UINT8 RegisterValue;
3434 UINT8 Device;
3435 UINT64 IoPortForBmic;
3436 UINT64 IoPortForBmis;
3437 UINT64 IoPortForBmid;
3438 EFI_STATUS Status;
3439 UINTN PrdTableNum;
3440 UINTN ByteCount;
3441 UINTN ByteAvailable;
3442 UINT8 *PrdBuffer;
3443 UINTN RemainBlockNum;
3444 UINT8 DeviceControl;
3445
3446 //
3447 // Channel and device differential
3448 //
3449 Device = (UINT8) ((IdeDev->Device << 4) | 0xe0);
3450
3451 //
3452 // Enable interrupt to support UDMA
3453 //
3454 DeviceControl = 0;
3455 IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->Alt.DeviceControl, DeviceControl);
3456
3457 IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->Head, Device);
3458
3459 if (IdePrimary == IdeDev->Channel) {
3460 IoPortForBmic = IdeDev->IoPort->BusMasterBaseAddr + BMICP_OFFSET;
3461 IoPortForBmis = IdeDev->IoPort->BusMasterBaseAddr + BMISP_OFFSET;
3462 IoPortForBmid = IdeDev->IoPort->BusMasterBaseAddr + BMIDP_OFFSET;
3463 } else {
3464 if (IdeSecondary == IdeDev->Channel) {
3465 IoPortForBmic = IdeDev->IoPort->BusMasterBaseAddr + BMICS_OFFSET;
3466 IoPortForBmis = IdeDev->IoPort->BusMasterBaseAddr + BMISS_OFFSET;
3467 IoPortForBmid = IdeDev->IoPort->BusMasterBaseAddr + BMIDS_OFFSET;
3468 } else {
3469 return EFI_UNSUPPORTED;
3470 }
3471 }
3472
3473 RemainBlockNum = NumberOfBlocks;
3474 while (RemainBlockNum > 0) {
3475
3476 if (RemainBlockNum >= MAX_DMA_COMMAND_SECTORS) {
3477 //
3478 // SectorCount is used to record the number of sectors to be read
3479 // Max 256 sectors can be transfered at a time.
3480 //
3481 NumberOfBlocks = MAX_DMA_COMMAND_SECTORS;
3482 RemainBlockNum -= MAX_DMA_COMMAND_SECTORS;
3483 } else {
3484 NumberOfBlocks = (UINT16) RemainBlockNum;
3485 RemainBlockNum = 0;
3486 }
3487
3488 //
3489 // Calculate the number of PRD table to make sure the memory region
3490 // not cross 64K boundary
3491 //
3492 ByteCount = NumberOfBlocks * IdeDev->BlkIo.Media->BlockSize;
3493 PrdTableNum = ((ByteCount >> 16) + 1) + 1;
3494
3495 //
3496 // Build PRD table
3497 //
3498 PrdAddr = (IDE_DMA_PRD *) AllocateZeroPool ((2 * PrdTableNum * sizeof (IDE_DMA_PRD)));
3499
3500 //
3501 // To make sure PRD is allocated in one 64K page
3502 //
3503 if (((UINTN) PrdAddr & 0x0FFFF) > (((UINTN) PrdAddr + PrdTableNum * sizeof (IDE_DMA_PRD) - 1) & 0x0FFFF)) {
3504 UsedPrdAddr = (IDE_DMA_PRD *) ((UINTN) ((UINT8 *) PrdAddr + 0x10000) & 0xFFFF0000);
3505 } else {
3506 if ((UINTN) PrdAddr & 0x03) {
3507 UsedPrdAddr = (IDE_DMA_PRD *) ((UINTN) ((UINT8 *) PrdAddr + 0x04) & 0xFFFFFFFC);
3508 } else {
3509 UsedPrdAddr = PrdAddr;
3510 }
3511 }
3512
3513 //
3514 // Build the PRD table
3515 //
3516 PrdBuffer = DataBuffer;
3517 TempPrdAddr = UsedPrdAddr;
3518 while (TRUE) {
3519
3520 ByteAvailable = 0x10000 - ((UINTN) PrdBuffer & 0xFFFF);
3521
3522 if (ByteCount <= ByteAvailable) {
3523 TempPrdAddr->RegionBaseAddr = (UINT32) ((UINTN) PrdBuffer);
3524 TempPrdAddr->ByteCount = (UINT16) ByteCount;
3525 TempPrdAddr->EndOfTable = 0x8000;
3526 break;
3527 }
3528
3529 TempPrdAddr->RegionBaseAddr = (UINT32) ((UINTN) PrdBuffer);
3530 TempPrdAddr->ByteCount = (UINT16) ByteAvailable;
3531
3532 ByteCount -= ByteAvailable;
3533 PrdBuffer += ByteAvailable;
3534 TempPrdAddr++;
3535 }
3536
3537 //
3538 // Set the base address to BMID register
3539 //
3540 IdeDev->PciIo->Io.Write (
3541 IdeDev->PciIo,
3542 EfiPciIoWidthUint32,
3543 EFI_PCI_IO_PASS_THROUGH_BAR,
3544 IoPortForBmid,
3545 1,
3546 &UsedPrdAddr
3547 );
3548
3549 //
3550 // Set BMIC register to identify the operation direction
3551 //
3552 IdeDev->PciIo->Io.Read (
3553 IdeDev->PciIo,
3554 EfiPciIoWidthUint8,
3555 EFI_PCI_IO_PASS_THROUGH_BAR,
3556 IoPortForBmic,
3557 1,
3558 &RegisterValue
3559 );
3560 //
3561 // 0000 1000
3562 //
3563 RegisterValue &= ~((UINT8) BMIC_nREAD);
3564
3565 IdeDev->PciIo->Io.Write (
3566 IdeDev->PciIo,
3567 EfiPciIoWidthUint8,
3568 EFI_PCI_IO_PASS_THROUGH_BAR,
3569 IoPortForBmic,
3570 1,
3571 &RegisterValue
3572 );
3573
3574 //
3575 // Read BMIS register and clear ERROR and INTR bit
3576 //
3577 IdeDev->PciIo->Io.Read (
3578 IdeDev->PciIo,
3579 EfiPciIoWidthUint8,
3580 EFI_PCI_IO_PASS_THROUGH_BAR,
3581 IoPortForBmis,
3582 1,
3583 &RegisterValue
3584 );
3585
3586 RegisterValue |= (BMIS_INTERRUPT | BMIS_ERROR);
3587
3588 IdeDev->PciIo->Io.Write (
3589 IdeDev->PciIo,
3590 EfiPciIoWidthUint8,
3591 EFI_PCI_IO_PASS_THROUGH_BAR,
3592 IoPortForBmis,
3593 1,
3594 &RegisterValue
3595 );
3596
3597 //
3598 // Issue WRITE DMA command
3599 //
3600 Status = AtaCommandIssue (
3601 IdeDev,
3602 WRITE_DMA_CMD,
3603 Device,
3604 0,
3605 (UINT16) NumberOfBlocks,
3606 StartLba
3607 );
3608 if (EFI_ERROR (Status)) {
3609 gBS->FreePool (PrdAddr);
3610 return EFI_DEVICE_ERROR;
3611 }
3612
3613 //
3614 // Set START bit of BMIC register
3615 //
3616 IdeDev->PciIo->Io.Read (
3617 IdeDev->PciIo,
3618 EfiPciIoWidthUint8,
3619 EFI_PCI_IO_PASS_THROUGH_BAR,
3620 IoPortForBmic,
3621 1,
3622 &RegisterValue
3623 );
3624
3625 RegisterValue |= BMIC_START;
3626
3627 IdeDev->PciIo->Io.Write (
3628 IdeDev->PciIo,
3629 EfiPciIoWidthUint8,
3630 EFI_PCI_IO_PASS_THROUGH_BAR,
3631 IoPortForBmic,
3632 1,
3633 &RegisterValue
3634 );
3635
3636 //
3637 // Check the INTERRUPT and ERROR bit of BMIS
3638 //
3639 while (TRUE) {
3640
3641 IdeDev->PciIo->Io.Read (
3642 IdeDev->PciIo,
3643 EfiPciIoWidthUint8,
3644 EFI_PCI_IO_PASS_THROUGH_BAR,
3645 IoPortForBmis,
3646 1,
3647 &RegisterValue
3648 );
3649 if (RegisterValue & (BMIS_INTERRUPT | BMIS_ERROR)) {
3650 if (RegisterValue & BMIS_ERROR) {
3651 gBS->FreePool (PrdAddr);
3652 return EFI_DEVICE_ERROR;
3653 }
3654 break;
3655 }
3656
3657 gBS->Stall (1000);
3658 }
3659
3660 gBS->FreePool (PrdAddr);
3661
3662 //
3663 // Set START bit of BMIC register
3664 //
3665 IdeDev->PciIo->Io.Read (
3666 IdeDev->PciIo,
3667 EfiPciIoWidthUint8,
3668 EFI_PCI_IO_PASS_THROUGH_BAR,
3669 IoPortForBmic,
3670 1,
3671 &RegisterValue
3672 );
3673
3674 RegisterValue &= ~((UINT8) BMIC_START);
3675
3676 IdeDev->PciIo->Io.Write (
3677 IdeDev->PciIo,
3678 EfiPciIoWidthUint8,
3679 EFI_PCI_IO_PASS_THROUGH_BAR,
3680 IoPortForBmic,
3681 1,
3682 &RegisterValue
3683 );
3684
3685 DataBuffer = (UINT8 *) DataBuffer + NumberOfBlocks * IdeDev->BlkIo.Media->BlockSize;
3686 StartLba += NumberOfBlocks;
3687 }
3688
3689 return EFI_SUCCESS;
3690 }