]> git.proxmox.com Git - mirror_edk2.git/blob - EdkModulePkg/Bus/Pci/IdeBus/Dxe/atapi.c
Partially make EdkModulePkg pass intel IPF compiler with /W4 /WX switched on.
[mirror_edk2.git] / EdkModulePkg / Bus / Pci / IdeBus / Dxe / atapi.c
1 /** @file
2 Copyright (c) 2006, Intel Corporation
3 All rights reserved. This program and the accompanying materials
4 are licensed and made available under the terms and conditions of the BSD License
5 which accompanies this distribution. The full text of the license may be found at
6 http://opensource.org/licenses/bsd-license.php
7
8 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
9 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
10
11 **/
12
13 #include "idebus.h"
14
15 /**
16 This function is used to get the current status of the media residing
17 in the LS-120 drive or ZIP drive. The media status is returned in the
18 Error Status.
19
20 @param[in] *IdeDev
21 pointer pointing to IDE_BLK_IO_DEV data structure, used
22 to record all the information of the IDE device.
23
24 @retval EFI_SUCCESS
25 The media status is achieved successfully and the media
26 can be read/written.
27
28 @retval EFI_DEVICE_ERROR
29 Get Media Status Command is failed.
30
31 @retval EFI_NO_MEDIA
32 There is no media in the drive.
33
34 @retval EFI_WRITE_PROTECTED
35 The media is writing protected.
36
37 @note
38 This function must be called after the LS120EnableMediaStatus()
39 with second parameter set to TRUE
40 (means enable media status notification) is called.
41
42 **/
43 STATIC
44 EFI_STATUS
45 LS120GetMediaStatus (
46 IN IDE_BLK_IO_DEV *IdeDev
47 )
48 {
49 UINT8 DeviceSelect;
50 UINT8 StatusValue;
51 EFI_STATUS EfiStatus;
52 //
53 // Poll Alternate Register for BSY clear within timeout.
54 //
55 EfiStatus = WaitForBSYClear2 (IdeDev, ATATIMEOUT);
56 if (EFI_ERROR (EfiStatus)) {
57 return EFI_DEVICE_ERROR;
58 }
59
60 //
61 // Select device via Device/Head Register.
62 //
63 DeviceSelect = (UINT8) ((IdeDev->Device) << 4 | 0xe0);
64 IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->Head, DeviceSelect);
65
66 //
67 // Poll Alternate Register for DRDY set within timeout.
68 // After device is selected, DRDY set indicates the device is ready to
69 // accept command.
70 //
71 EfiStatus = DRDYReady2 (IdeDev, ATATIMEOUT);
72 if (EFI_ERROR (EfiStatus)) {
73 return EFI_DEVICE_ERROR;
74 }
75
76 //
77 // Get Media Status Command is sent
78 //
79 IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->Reg.Command, 0xDA);
80
81 //
82 // BSY bit will clear after command is complete.
83 //
84 EfiStatus = WaitForBSYClear2 (IdeDev, ATATIMEOUT);
85 if (EFI_ERROR (EfiStatus)) {
86 return EFI_DEVICE_ERROR;
87 }
88
89 //
90 // the media status is returned by the command in the ERROR register
91 //
92 StatusValue = IDEReadPortB (IdeDev->PciIo, IdeDev->IoPort->Reg1.Error);
93
94 if (StatusValue & bit1) {
95 return EFI_NO_MEDIA;
96 }
97
98 if (StatusValue & bit6) {
99 return EFI_WRITE_PROTECTED;
100 } else {
101 return EFI_SUCCESS;
102 }
103 }
104
105 /**
106 This function is used to send Enable Media Status Notification Command
107 or Disable Media Status Notification Command.
108
109 @param[in] *IdeDev
110 pointer pointing to IDE_BLK_IO_DEV data structure, used
111 to record all the information of the IDE device.
112
113 @param[in] Enable
114 a flag that indicates whether enable or disable media
115 status notification.
116
117 @retval EFI_SUCCESS
118 If command completes successfully.
119
120 @retval EFI_DEVICE_ERROR
121 If command failed.
122
123 **/
124 STATIC
125 EFI_STATUS
126 LS120EnableMediaStatus (
127 IN IDE_BLK_IO_DEV *IdeDev,
128 IN BOOLEAN Enable
129 )
130 {
131 UINT8 DeviceSelect;
132 EFI_STATUS Status;
133
134 //
135 // Poll Alternate Register for BSY clear within timeout.
136 //
137 Status = WaitForBSYClear2 (IdeDev, ATATIMEOUT);
138 if (EFI_ERROR (Status)) {
139 return EFI_DEVICE_ERROR;
140 }
141
142 //
143 // Select device via Device/Head Register.
144 //
145 DeviceSelect = (UINT8) ((IdeDev->Device) << 4 | 0xe0);
146 IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->Head, DeviceSelect);
147
148 //
149 // Poll Alternate Register for DRDY set within timeout.
150 // After device is selected, DRDY set indicates the device is ready to
151 // accept command.
152 //
153 Status = DRDYReady2 (IdeDev, ATATIMEOUT);
154 if (EFI_ERROR (Status)) {
155 return EFI_DEVICE_ERROR;
156 }
157
158 if (Enable) {
159 //
160 // 0x95: Enable media status notification
161 //
162 IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->Reg1.Feature, 0x95);
163 } else {
164 //
165 // 0x31: Disable media status notification
166 //
167 IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->Reg1.Feature, 0x31);
168 }
169 //
170 // Set Feature Command is sent
171 //
172 IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->Reg.Command, 0xEF);
173
174 //
175 // BSY bit will clear after command is complete.
176 //
177 Status = WaitForBSYClear (IdeDev, ATATIMEOUT);
178 if (EFI_ERROR (Status)) {
179 return EFI_DEVICE_ERROR;
180 }
181
182 return EFI_SUCCESS;
183 }
184
185 /**
186 This function is called by DiscoverIdeDevice() during its device
187 identification.
188
189 Its main purpose is to get enough information for the device media
190 to fill in the Media data structure of the Block I/O Protocol interface.
191
192 There are 5 steps to reach such objective:
193
194 1. Sends out the ATAPI Identify Command to the specified device.
195 Only ATAPI device responses to this command. If the command succeeds,
196 it returns the Identify data structure which filled with information
197 about the device. Since the ATAPI device contains removable media,
198 the only meaningful information is the device module name.
199
200 2. Sends out ATAPI Inquiry Packet Command to the specified device.
201 This command will return inquiry data of the device, which contains
202 the device type information.
203
204 3. Allocate sense data space for future use. We don't detect the media
205 presence here to improvement boot performance, especially when CD
206 media is present. The media detection will be performed just before
207 each BLK_IO read/write
208
209 @param[in] *IdeDev
210 pointer pointing to IDE_BLK_IO_DEV data structure, used
211 to record all the information of the IDE device.
212
213 @retval EFI_SUCCESS
214 Identify ATAPI device successfully.
215
216 @retval EFI_DEVICE_ERROR
217 ATAPI Identify Device Command failed or device type
218 is not supported by this IDE driver.
219
220 @note
221 Parameter "IdeDev" will be updated in this function.
222
223 TODO: EFI_OUT_OF_RESOURCES - add return value to function comment
224 TODO: EFI_OUT_OF_RESOURCES - add return value to function comment
225 **/
226 EFI_STATUS
227 ATAPIIdentify (
228 IN IDE_BLK_IO_DEV *IdeDev
229 )
230 {
231 EFI_IDENTIFY_DATA *AtapiIdentifyPointer;
232 UINT8 DeviceSelect;
233 EFI_STATUS Status;
234
235 //
236 // device select bit
237 //
238 DeviceSelect = 0;
239 DeviceSelect = (UINT8) ((IdeDev->Device) << 4);
240
241 AtapiIdentifyPointer = AllocatePool (sizeof (EFI_IDENTIFY_DATA));
242 if (AtapiIdentifyPointer == NULL) {
243 return EFI_OUT_OF_RESOURCES;
244 }
245 //
246 // Send ATAPI Identify Command to get IDENTIFY data.
247 //
248 Status = AtaPioDataIn (
249 IdeDev,
250 (VOID *) AtapiIdentifyPointer,
251 sizeof (EFI_IDENTIFY_DATA),
252 ATAPI_IDENTIFY_DEVICE_CMD,
253 DeviceSelect,
254 0,
255 0,
256 0,
257 0
258 );
259
260 if (EFI_ERROR (Status)) {
261 gBS->FreePool (AtapiIdentifyPointer);
262 return EFI_DEVICE_ERROR;
263 }
264
265 IdeDev->pIdData = AtapiIdentifyPointer;
266 PrintAtaModuleName (IdeDev);
267
268 //
269 // Send ATAPI Inquiry Packet Command to get INQUIRY data.
270 //
271 Status = AtapiInquiry (IdeDev);
272 if (EFI_ERROR (Status)) {
273 gBS->FreePool (IdeDev->pIdData);
274 //
275 // Make sure the pIdData will not be freed again.
276 //
277 IdeDev->pIdData = NULL;
278 return EFI_DEVICE_ERROR;
279 }
280 //
281 // Get media removable info from INQUIRY data.
282 //
283 IdeDev->BlkIo.Media->RemovableMedia = (UINT8) ((IdeDev->pInquiryData->RMB & 0x80) == 0x80);
284
285 //
286 // Identify device type via INQUIRY data.
287 //
288 switch (IdeDev->pInquiryData->peripheral_type & 0x1f) {
289
290 //
291 // Magnetic Disk
292 //
293 case 0x00:
294
295 //
296 // device is LS120 or ZIP drive.
297 //
298 IdeDev->Type = IdeMagnetic;
299
300 IdeDev->BlkIo.Media->MediaId = 0;
301 //
302 // Give initial value
303 //
304 IdeDev->BlkIo.Media->MediaPresent = FALSE;
305
306 IdeDev->BlkIo.Media->LastBlock = 0;
307 IdeDev->BlkIo.Media->BlockSize = 0x200;
308 break;
309
310 //
311 // CD-ROM
312 //
313 case 0x05:
314
315 IdeDev->Type = IdeCdRom;
316 IdeDev->BlkIo.Media->MediaId = 0;
317 //
318 // Give initial value
319 //
320 IdeDev->BlkIo.Media->MediaPresent = FALSE;
321
322 IdeDev->BlkIo.Media->LastBlock = 0;
323 IdeDev->BlkIo.Media->BlockSize = 0x800;
324 IdeDev->BlkIo.Media->ReadOnly = TRUE;
325 break;
326
327 //
328 // Tape
329 //
330 case 0x01:
331
332 //
333 // WORM
334 //
335 case 0x04:
336
337 //
338 // Optical
339 //
340 case 0x07:
341
342 default:
343 IdeDev->Type = IdeUnknown;
344 gBS->FreePool (IdeDev->pIdData);
345 gBS->FreePool (IdeDev->pInquiryData);
346 //
347 // Make sure the pIdData and pInquiryData will not be freed again.
348 //
349 IdeDev->pIdData = NULL;
350 IdeDev->pInquiryData = NULL;
351 return EFI_DEVICE_ERROR;
352 }
353
354 //
355 // original sense data numbers
356 //
357 IdeDev->SenseDataNumber = 20;
358
359 IdeDev->SenseData = AllocatePool (IdeDev->SenseDataNumber * sizeof (REQUEST_SENSE_DATA));
360 if (IdeDev->SenseData == NULL) {
361 gBS->FreePool (IdeDev->pIdData);
362 gBS->FreePool (IdeDev->pInquiryData);
363 //
364 // Make sure the pIdData and pInquiryData will not be freed again.
365 //
366 IdeDev->pIdData = NULL;
367 IdeDev->pInquiryData = NULL;
368 return EFI_OUT_OF_RESOURCES;
369 }
370
371 return EFI_SUCCESS;
372 }
373
374 /**
375 Sends out ATAPI Inquiry Packet Command to the specified device.
376 This command will return INQUIRY data of the device.
377
378 @param[in] *IdeDev
379 pointer pointing to IDE_BLK_IO_DEV data structure, used
380 to record all the information of the IDE device.
381
382 @retval EFI_SUCCESS
383 Inquiry command completes successfully.
384
385 @retval EFI_DEVICE_ERROR
386 Inquiry command failed.
387
388 @note
389 Parameter "IdeDev" will be updated in this function.
390
391 **/
392 EFI_STATUS
393 AtapiInquiry (
394 IN IDE_BLK_IO_DEV *IdeDev
395 )
396 {
397 ATAPI_PACKET_COMMAND Packet;
398 EFI_STATUS Status;
399 INQUIRY_DATA *InquiryData;
400
401 //
402 // prepare command packet for the ATAPI Inquiry Packet Command.
403 //
404 ZeroMem (&Packet, sizeof (ATAPI_PACKET_COMMAND));
405 Packet.Inquiry.opcode = INQUIRY;
406 Packet.Inquiry.page_code = 0;
407 Packet.Inquiry.allocation_length = sizeof (INQUIRY_DATA);
408
409 InquiryData = AllocatePool (sizeof (INQUIRY_DATA));
410 if (InquiryData == NULL) {
411 return EFI_DEVICE_ERROR;
412 }
413
414 //
415 // Send command packet and get requested Inquiry data.
416 //
417 Status = AtapiPacketCommandIn (
418 IdeDev,
419 &Packet,
420 (UINT16 *) InquiryData,
421 sizeof (INQUIRY_DATA),
422 ATAPITIMEOUT
423 );
424 if (EFI_ERROR (Status)) {
425 gBS->FreePool (InquiryData);
426 return EFI_DEVICE_ERROR;
427 }
428
429 IdeDev->pInquiryData = InquiryData;
430
431 return EFI_SUCCESS;
432 }
433
434 /**
435 This function is used to send out ATAPI commands conforms to the
436 Packet Command with PIO Data In Protocol.
437
438 @param[in] *IdeDev
439 pointer pointing to IDE_BLK_IO_DEV data structure, used
440 to record all the information of the IDE device.
441
442 @param[in] *Packet
443 pointer pointing to ATAPI_PACKET_COMMAND data structure
444 which contains the contents of the command.
445
446 @param[in] *Buffer
447 buffer contained data transferred from device to host.
448
449 @param[in] ByteCount
450 data size in byte unit of the buffer.
451
452 @param[in] TimeOut
453 this parameter is used to specify the timeout
454 value for the PioReadWriteData() function.
455
456 @retval EFI_SUCCESS
457 send out the ATAPI packet command successfully
458 and device sends data successfully.
459
460 @retval EFI_DEVICE_ERROR
461 the device failed to send data.
462
463 **/
464 EFI_STATUS
465 AtapiPacketCommandIn (
466 IN IDE_BLK_IO_DEV *IdeDev,
467 IN ATAPI_PACKET_COMMAND *Packet,
468 IN UINT16 *Buffer,
469 IN UINT32 ByteCount,
470 IN UINTN TimeOut
471 )
472 {
473 UINT16 *CommandIndex;
474 EFI_STATUS Status;
475 UINT32 Count;
476
477 //
478 // Set all the command parameters by fill related registers.
479 // Before write to all the following registers, BSY and DRQ must be 0.
480 //
481 Status = DRQClear2 (IdeDev, ATAPITIMEOUT);
482 if (EFI_ERROR (Status)) {
483 return Status;
484 }
485
486 //
487 // Select device via Device/Head Register.
488 //
489 IDEWritePortB (
490 IdeDev->PciIo,
491 IdeDev->IoPort->Head,
492 (UINT8) ((IdeDev->Device << 4) | DEFAULT_CMD) // DEFAULT_CMD: 0xa0 (1010,0000)
493 );
494
495 //
496 // No OVL; No DMA
497 //
498 IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->Reg1.Feature, 0x00);
499
500 //
501 // set the transfersize to MAX_ATAPI_BYTE_COUNT to let the device
502 // determine how many data should be transferred.
503 //
504 IDEWritePortB (
505 IdeDev->PciIo,
506 IdeDev->IoPort->CylinderLsb,
507 (UINT8) (MAX_ATAPI_BYTE_COUNT & 0x00ff)
508 );
509 IDEWritePortB (
510 IdeDev->PciIo,
511 IdeDev->IoPort->CylinderMsb,
512 (UINT8) (MAX_ATAPI_BYTE_COUNT >> 8)
513 );
514
515 //
516 // DEFAULT_CTL:0x0a (0000,1010)
517 // Disable interrupt
518 //
519 IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->Alt.DeviceControl, DEFAULT_CTL);
520
521 //
522 // Send Packet command to inform device
523 // that the following data bytes are command packet.
524 //
525 IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->Reg.Command, PACKET_CMD);
526
527 Status = DRQReady (IdeDev, ATAPITIMEOUT);
528 if (EFI_ERROR (Status)) {
529 return Status;
530 }
531
532 //
533 // Send out command packet
534 //
535 CommandIndex = Packet->Data16;
536 for (Count = 0; Count < 6; Count++, CommandIndex++) {
537
538 IDEWritePortW (IdeDev->PciIo, IdeDev->IoPort->Data, *CommandIndex);
539 gBS->Stall (10);
540 }
541
542 //
543 // call PioReadWriteData() function to get
544 // requested transfer data form device.
545 //
546 return PioReadWriteData (IdeDev, Buffer, ByteCount, 1, TimeOut);
547 }
548
549 /**
550 This function is used to send out ATAPI commands conforms to the
551 Packet Command with PIO Data Out Protocol.
552
553 @param[in] *IdeDev
554 pointer pointing to IDE_BLK_IO_DEV data structure, used
555 to record all the information of the IDE device.
556
557 @param[in] *Packet
558 pointer pointing to ATAPI_PACKET_COMMAND data structure
559 which contains the contents of the command.
560
561 @param[in] *Buffer
562 buffer contained data transferred from host to device.
563
564 @param[in] ByteCount
565 data size in byte unit of the buffer.
566
567 @param[in] TimeOut
568 this parameter is used to specify the timeout
569 value for the PioReadWriteData() function.
570
571 @retval EFI_SUCCESS
572 send out the ATAPI packet command successfully
573 and device received data successfully.
574
575 @retval EFI_DEVICE_ERROR
576 the device failed to send data.
577
578 **/
579 EFI_STATUS
580 AtapiPacketCommandOut (
581 IN IDE_BLK_IO_DEV *IdeDev,
582 IN ATAPI_PACKET_COMMAND *Packet,
583 IN UINT16 *Buffer,
584 IN UINT32 ByteCount,
585 IN UINTN TimeOut
586 )
587 {
588 UINT16 *CommandIndex;
589 EFI_STATUS Status;
590 UINT32 Count;
591
592 //
593 // set all the command parameters
594 // Before write to all the following registers, BSY and DRQ must be 0.
595 //
596 Status = DRQClear2 (IdeDev, ATAPITIMEOUT);
597 if (EFI_ERROR (Status)) {
598 return Status;
599 }
600
601 //
602 // Select device via Device/Head Register.
603 //
604 IDEWritePortB (
605 IdeDev->PciIo,
606 IdeDev->IoPort->Head,
607 (UINT8) ((IdeDev->Device << 4) | DEFAULT_CMD) // DEFAULT_CMD: 0xa0 (1010,0000)
608 );
609
610 //
611 // No OVL; No DMA
612 //
613 IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->Reg1.Feature, 0x00);
614
615 //
616 // set the transfersize to MAX_ATAPI_BYTE_COUNT to
617 // let the device determine how many data should be transferred.
618 //
619 IDEWritePortB (
620 IdeDev->PciIo,
621 IdeDev->IoPort->CylinderLsb,
622 (UINT8) (MAX_ATAPI_BYTE_COUNT & 0x00ff)
623 );
624 IDEWritePortB (
625 IdeDev->PciIo,
626 IdeDev->IoPort->CylinderMsb,
627 (UINT8) (MAX_ATAPI_BYTE_COUNT >> 8)
628 );
629
630 //
631 // DEFAULT_CTL:0x0a (0000,1010)
632 // Disable interrupt
633 //
634 IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->Alt.DeviceControl, DEFAULT_CTL);
635
636 //
637 // Send Packet command to inform device
638 // that the following data bytes are command packet.
639 //
640 IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->Reg.Command, PACKET_CMD);
641
642 Status = DRQReady2 (IdeDev, ATAPITIMEOUT);
643 if (EFI_ERROR (Status)) {
644 return Status;
645 }
646
647 //
648 // Send out command packet
649 //
650 CommandIndex = Packet->Data16;
651 for (Count = 0; Count < 6; Count++, CommandIndex++) {
652 IDEWritePortW (IdeDev->PciIo, IdeDev->IoPort->Data, *CommandIndex);
653 gBS->Stall (10);
654 }
655
656 //
657 // call PioReadWriteData() function to send requested transfer data to device.
658 //
659 return PioReadWriteData (IdeDev, Buffer, ByteCount, 0, TimeOut);
660 }
661
662 /**
663 This function is called by either AtapiPacketCommandIn() or
664 AtapiPacketCommandOut(). It is used to transfer data between
665 host and device. The data direction is specified by the fourth
666 parameter.
667
668 @param[in] *IdeDev
669 pointer pointing to IDE_BLK_IO_DEV data structure, used
670 to record all the information of the IDE device.
671
672 @param[in] *Buffer
673 buffer contained data transferred between host and device.
674
675 @param[in] ByteCount
676 data size in byte unit of the buffer.
677
678 @param[in] Read
679 flag used to determine the data transfer direction.
680 Read equals 1, means data transferred from device to host;
681 Read equals 0, means data transferred from host to device.
682
683 @param[in] TimeOut
684 timeout value for wait DRQ ready before each data
685 stream's transfer.
686
687 @retval EFI_SUCCESS
688 data is transferred successfully.
689
690 @retval EFI_DEVICE_ERROR
691 the device failed to transfer data.
692
693 **/
694 EFI_STATUS
695 PioReadWriteData (
696 IN IDE_BLK_IO_DEV *IdeDev,
697 IN UINT16 *Buffer,
698 IN UINT32 ByteCount,
699 IN BOOLEAN Read,
700 IN UINTN TimeOut
701 )
702 {
703 //
704 // required transfer data in word unit.
705 //
706 UINT32 RequiredWordCount;
707
708 //
709 // actual transfer data in word unit.
710 //
711 UINT32 ActualWordCount;
712 UINT32 WordCount;
713 EFI_STATUS Status;
714 UINT16 *PtrBuffer;
715
716 //
717 // No data transfer is premitted.
718 //
719 if (ByteCount == 0) {
720 return EFI_SUCCESS;
721 }
722 //
723 // for performance, we assert the ByteCount is an even number
724 // which is actually a resonable assumption
725 ASSERT((ByteCount%2) == 0);
726
727 PtrBuffer = Buffer;
728 RequiredWordCount = ByteCount / 2;
729 //
730 // ActuralWordCount means the word count of data really transferred.
731 //
732 ActualWordCount = 0;
733
734 while (ActualWordCount < RequiredWordCount) {
735
736 //
737 // before each data transfer stream, the host should poll DRQ bit ready,
738 // to see whether indicates device is ready to transfer data.
739 //
740 Status = DRQReady2 (IdeDev, TimeOut);
741 if (EFI_ERROR (Status)) {
742 return CheckErrorStatus (IdeDev);
743 }
744
745 //
746 // read Status Register will clear interrupt
747 //
748 IDEReadPortB (IdeDev->PciIo, IdeDev->IoPort->Reg.Status);
749
750 //
751 // get current data transfer size from Cylinder Registers.
752 //
753 WordCount = IDEReadPortB (IdeDev->PciIo, IdeDev->IoPort->CylinderMsb) << 8;
754 WordCount = WordCount | IDEReadPortB (IdeDev->PciIo, IdeDev->IoPort->CylinderLsb);
755 WordCount = WordCount & 0xffff;
756 WordCount /= 2;
757
758 WordCount = EFI_MIN (WordCount, (RequiredWordCount - ActualWordCount));
759
760 if (Read) {
761 IDEReadPortWMultiple (
762 IdeDev->PciIo,
763 IdeDev->IoPort->Data,
764 WordCount,
765 PtrBuffer
766 );
767 } else {
768 IDEWritePortWMultiple (
769 IdeDev->PciIo,
770 IdeDev->IoPort->Data,
771 WordCount,
772 PtrBuffer
773 );
774 }
775
776 PtrBuffer += WordCount;
777 ActualWordCount += WordCount;
778 }
779
780 if (Read) {
781 //
782 // In the case where the drive wants to send more data than we need to read,
783 // the DRQ bit will be set and cause delays from DRQClear2().
784 // We need to read data from the drive until it clears DRQ so we can move on.
785 //
786 AtapiReadPendingData (IdeDev);
787 }
788
789 //
790 // After data transfer is completed, normally, DRQ bit should clear.
791 //
792 Status = DRQClear2 (IdeDev, ATAPITIMEOUT);
793 if (EFI_ERROR (Status)) {
794 return EFI_DEVICE_ERROR;
795 }
796
797 //
798 // read status register to check whether error happens.
799 //
800 return CheckErrorStatus (IdeDev);
801 }
802
803 /**
804 Sends out ATAPI Test Unit Ready Packet Command to the specified device
805 to find out whether device is accessible.
806
807 @param[in] *IdeDev Pointer pointing to IDE_BLK_IO_DEV data structure, used
808 to record all the information of the IDE device.
809 @param[in] *SenseCount Sense count for this packet command
810
811 @retval EFI_SUCCESS Device is accessible.
812 @retval EFI_DEVICE_ERROR Device is not accessible.
813
814 **/
815 EFI_STATUS
816 AtapiTestUnitReady (
817 IN IDE_BLK_IO_DEV *IdeDev,
818 OUT UINTN *SenseCount
819 )
820 {
821 ATAPI_PACKET_COMMAND Packet;
822 EFI_STATUS Status;
823
824 *SenseCount = 0;
825
826 //
827 // fill command packet
828 //
829 ZeroMem (&Packet, sizeof (ATAPI_PACKET_COMMAND));
830 Packet.TestUnitReady.opcode = TEST_UNIT_READY;
831
832 //
833 // send command packet
834 //
835 Status = AtapiPacketCommandIn (IdeDev, &Packet, NULL, 0, ATAPITIMEOUT);
836 if (EFI_ERROR (Status)) {
837 return Status;
838 }
839
840 Status = AtapiRequestSense (IdeDev, SenseCount);
841 if (EFI_ERROR (Status)) {
842 *SenseCount = 0;
843 return Status;
844 }
845
846 return EFI_SUCCESS;
847 }
848
849 /**
850 Sends out ATAPI Request Sense Packet Command to the specified device.
851 This command will return all the current Sense data in the device.
852 This function will pack all the Sense data in one single buffer.
853
854 @param[in] *IdeDev
855 pointer pointing to IDE_BLK_IO_DEV data structure, used
856 to record all the information of the IDE device.
857
858 @param[out] **SenseBuffers
859 allocated in this function, and freed by the calling function.
860 This buffer is used to accommodate all the sense data returned
861 by the device.
862
863 @param[out] *BufUnit
864 record the unit size of the sense data block in the SenseBuffers,
865
866 @param[out] *BufNumbers
867 record the number of units in the SenseBuffers.
868
869 @retval EFI_SUCCESS
870 Request Sense command completes successfully.
871
872 @retval EFI_DEVICE_ERROR
873 Request Sense command failed.
874
875 **/
876 EFI_STATUS
877 AtapiRequestSense (
878 IN IDE_BLK_IO_DEV *IdeDev,
879 OUT UINTN *SenseCounts
880 )
881 {
882 EFI_STATUS Status;
883 REQUEST_SENSE_DATA *Sense;
884 UINT16 *Ptr;
885 BOOLEAN FetchSenseData;
886 ATAPI_PACKET_COMMAND Packet;
887
888 *SenseCounts = 0;
889
890 ZeroMem (IdeDev->SenseData, sizeof (REQUEST_SENSE_DATA) * (IdeDev->SenseDataNumber));
891 //
892 // fill command packet for Request Sense Packet Command
893 //
894 ZeroMem (&Packet, sizeof (ATAPI_PACKET_COMMAND));
895 Packet.RequestSence.opcode = REQUEST_SENSE;
896 Packet.RequestSence.allocation_length = sizeof (REQUEST_SENSE_DATA);
897
898 //
899 // initialize pointer
900 //
901 Ptr = (UINT16 *) IdeDev->SenseData;
902 //
903 // request sense data from device continuously until no sense data
904 // exists in the device.
905 //
906 for (FetchSenseData = TRUE; FetchSenseData;) {
907
908 Sense = (REQUEST_SENSE_DATA *) Ptr;
909
910 //
911 // send out Request Sense Packet Command and get one Sense data form device
912 //
913 Status = AtapiPacketCommandIn (
914 IdeDev,
915 &Packet,
916 Ptr,
917 sizeof (REQUEST_SENSE_DATA),
918 ATAPITIMEOUT
919 );
920 //
921 // failed to get Sense data
922 //
923 if (EFI_ERROR (Status)) {
924 if (*SenseCounts == 0) {
925 return EFI_DEVICE_ERROR;
926 } else {
927 return EFI_SUCCESS;
928 }
929 }
930
931 (*SenseCounts)++;
932 //
933 // We limit MAX sense data count to 20 in order to avoid dead loop. Some
934 // incompatible ATAPI devices don't retrive NO_SENSE when there is no media.
935 // In this case, dead loop occurs if we don't have a gatekeeper. 20 is
936 // supposed to be large enough for any ATAPI device.
937 //
938 if ((Sense->sense_key != SK_NO_SENSE) && ((*SenseCounts) < 20)) {
939 //
940 // Ptr is word-based pointer
941 //
942 Ptr += (sizeof (REQUEST_SENSE_DATA) + 1) >> 1;
943
944 } else {
945 //
946 // when no sense key, skip out the loop
947 //
948 FetchSenseData = FALSE;
949 }
950 }
951
952 return EFI_SUCCESS;
953 }
954
955 /**
956 Sends out ATAPI Read Capacity Packet Command to the specified device.
957 This command will return the information regarding the capacity of the
958 media in the device.
959
960 Current device status will impact device's response to the Read Capacity
961 Command. For example, if the device once reset, the Read Capacity
962 Command will fail. The Sense data record the current device status, so
963 if the Read Capacity Command failed, the Sense data must be requested
964 and be analyzed to determine if the Read Capacity Command should retry.
965
966 @param[in] *IdeDev Pointer pointing to IDE_BLK_IO_DEV data structure, used
967 to record all the information of the IDE device.
968 @param[in] SenseCount Sense count for this packet command
969
970 @retval EFI_SUCCESS Read Capacity Command finally completes successfully.
971 @retval EFI_DEVICE_ERROR Read Capacity Command failed because of device error.
972
973 @note Parameter "IdeDev" will be updated in this function.
974
975 TODO: EFI_NOT_READY - add return value to function comment
976 **/
977 EFI_STATUS
978 AtapiReadCapacity (
979 IN IDE_BLK_IO_DEV *IdeDev,
980 OUT UINTN *SenseCount
981 )
982 {
983 //
984 // status returned by Read Capacity Packet Command
985 //
986 EFI_STATUS Status;
987 EFI_STATUS SenseStatus;
988 ATAPI_PACKET_COMMAND Packet;
989
990 //
991 // used for capacity data returned from ATAPI device
992 //
993 READ_CAPACITY_DATA Data;
994 READ_FORMAT_CAPACITY_DATA FormatData;
995
996 *SenseCount = 0;
997
998 ZeroMem (&Data, sizeof (Data));
999 ZeroMem (&FormatData, sizeof (FormatData));
1000
1001 if (IdeDev->Type == IdeCdRom) {
1002
1003 ZeroMem (&Packet, sizeof (ATAPI_PACKET_COMMAND));
1004 Packet.Inquiry.opcode = READ_CAPACITY;
1005 Status = AtapiPacketCommandIn (
1006 IdeDev,
1007 &Packet,
1008 (UINT16 *) &Data,
1009 sizeof (READ_CAPACITY_DATA),
1010 ATAPITIMEOUT
1011 );
1012
1013 } else {
1014 //
1015 // Type == IdeMagnetic
1016 //
1017 ZeroMem (&Packet, sizeof (ATAPI_PACKET_COMMAND));
1018 Packet.ReadFormatCapacity.opcode = READ_FORMAT_CAPACITY;
1019 Packet.ReadFormatCapacity.allocation_length_lo = 12;
1020 Status = AtapiPacketCommandIn (
1021 IdeDev,
1022 &Packet,
1023 (UINT16 *) &FormatData,
1024 sizeof (READ_FORMAT_CAPACITY_DATA),
1025 ATAPITIMEOUT
1026 );
1027 }
1028
1029 if (Status == EFI_TIMEOUT) {
1030 *SenseCount = 0;
1031 return Status;
1032 }
1033
1034 SenseStatus = AtapiRequestSense (IdeDev, SenseCount);
1035
1036 if (!EFI_ERROR (SenseStatus)) {
1037
1038 if (!EFI_ERROR (Status)) {
1039
1040 if (IdeDev->Type == IdeCdRom) {
1041
1042 IdeDev->BlkIo.Media->LastBlock = (Data.LastLba3 << 24) |
1043 (Data.LastLba2 << 16) |
1044 (Data.LastLba1 << 8) |
1045 Data.LastLba0;
1046
1047 if (IdeDev->BlkIo.Media->LastBlock != 0) {
1048
1049 IdeDev->BlkIo.Media->BlockSize = (Data.BlockSize3 << 24) |
1050 (Data.BlockSize2 << 16) |
1051 (Data.BlockSize1 << 8) |
1052 Data.BlockSize0;
1053
1054 IdeDev->BlkIo.Media->MediaPresent = TRUE;
1055 } else {
1056 IdeDev->BlkIo.Media->MediaPresent = FALSE;
1057 return EFI_DEVICE_ERROR;
1058 }
1059
1060 IdeDev->BlkIo.Media->ReadOnly = TRUE;
1061
1062 //
1063 // Because the user data portion in the sector of the Data CD supported
1064 // is always 0x800
1065 //
1066 IdeDev->BlkIo.Media->BlockSize = 0x800;
1067 }
1068
1069 if (IdeDev->Type == IdeMagnetic) {
1070
1071 if (FormatData.DesCode == 3) {
1072 IdeDev->BlkIo.Media->MediaPresent = FALSE;
1073 IdeDev->BlkIo.Media->LastBlock = 0;
1074 } else {
1075
1076 IdeDev->BlkIo.Media->LastBlock = (FormatData.LastLba3 << 24) |
1077 (FormatData.LastLba2 << 16) |
1078 (FormatData.LastLba1 << 8) |
1079 FormatData.LastLba0;
1080 if (IdeDev->BlkIo.Media->LastBlock != 0) {
1081 IdeDev->BlkIo.Media->LastBlock--;
1082
1083 IdeDev->BlkIo.Media->BlockSize = (FormatData.BlockSize2 << 16) |
1084 (FormatData.BlockSize1 << 8) |
1085 FormatData.BlockSize0;
1086
1087 IdeDev->BlkIo.Media->MediaPresent = TRUE;
1088 } else {
1089 IdeDev->BlkIo.Media->MediaPresent = FALSE;
1090 //
1091 // Return EFI_NOT_READY operation succeeds but returned capacity is 0
1092 //
1093 return EFI_NOT_READY;
1094 }
1095
1096 IdeDev->BlkIo.Media->BlockSize = 0x200;
1097
1098 }
1099 }
1100 }
1101
1102 return EFI_SUCCESS;
1103
1104 } else {
1105 *SenseCount = 0;
1106 return EFI_DEVICE_ERROR;
1107 }
1108 }
1109
1110 /**
1111 Used before read/write blocks from/to ATAPI device media.
1112 Since ATAPI device media is removable, it is necessary to detect
1113 whether media is present and get current present media's
1114 information, and if media has been changed, Block I/O Protocol
1115 need to be reinstalled.
1116
1117 @param[in] *IdeDev
1118 pointer pointing to IDE_BLK_IO_DEV data structure, used
1119 to record all the information of the IDE device.
1120
1121 @param[out] *MediaChange
1122 return value that indicates if the media of the device has been
1123 changed.
1124
1125 @retval EFI_SUCCESS
1126 media found successfully.
1127
1128 @retval EFI_DEVICE_ERROR
1129 any error encounters during media detection.
1130
1131 @retval EFI_NO_MEDIA
1132 media not found.
1133
1134 @note
1135 parameter IdeDev may be updated in this function.
1136
1137 **/
1138 EFI_STATUS
1139 AtapiDetectMedia (
1140 IN IDE_BLK_IO_DEV *IdeDev,
1141 OUT BOOLEAN *MediaChange
1142 )
1143 {
1144 EFI_STATUS Status;
1145 EFI_STATUS CleanStateStatus;
1146 EFI_BLOCK_IO_MEDIA OldMediaInfo;
1147 UINTN RetryTimes;
1148 UINTN RetryNotReady;
1149 UINTN SenseCount;
1150 SENSE_RESULT SResult;
1151 BOOLEAN WriteProtected;
1152
1153 CopyMem (&OldMediaInfo, IdeDev->BlkIo.Media, sizeof (EFI_BLOCK_IO_MEDIA));
1154 *MediaChange = FALSE;
1155 //
1156 // Retry for SenseDeviceNotReadyNeedRetry.
1157 // Each retry takes 1s and we limit the upper boundary to
1158 // 120 times about 2 min.
1159 //
1160 RetryNotReady = 120;
1161
1162 //
1163 // Do Test Unit Ready
1164 //
1165 DoTUR:
1166 //
1167 // Retry 5 times
1168 //
1169 RetryTimes = 5;
1170 while (RetryTimes != 0) {
1171
1172 Status = AtapiTestUnitReady (IdeDev, &SenseCount);
1173
1174 if (EFI_ERROR (Status)) {
1175 //
1176 // Test Unit Ready error without sense data.
1177 // For some devices, this means there's extra data
1178 // that has not been read, so we read these extra
1179 // data out before going on.
1180 //
1181 CleanStateStatus = AtapiReadPendingData (IdeDev);
1182 if (EFI_ERROR (CleanStateStatus)) {
1183 //
1184 // Busy wait failed, try again
1185 //
1186 RetryTimes--;
1187 }
1188 //
1189 // Try again without counting down RetryTimes
1190 //
1191 continue;
1192 } else {
1193
1194 ParseSenseData (IdeDev, SenseCount, &SResult);
1195
1196 switch (SResult) {
1197 case SenseNoSenseKey:
1198 if (IdeDev->BlkIo.Media->MediaPresent) {
1199 goto Done;
1200 } else {
1201 //
1202 // Media present but the internal structure need refreshed.
1203 // Try Read Capacity
1204 //
1205 goto DoRC;
1206 }
1207 break;
1208
1209 case SenseDeviceNotReadyNeedRetry:
1210 if (--RetryNotReady == 0) {
1211 return EFI_DEVICE_ERROR;
1212 }
1213 gBS->Stall (1000 * STALL_1_MILLI_SECOND);
1214 continue;
1215 break;
1216
1217 case SenseNoMedia:
1218 IdeDev->BlkIo.Media->MediaPresent = FALSE;
1219 IdeDev->BlkIo.Media->LastBlock = 0;
1220 goto Done;
1221 break;
1222
1223 case SenseDeviceNotReadyNoRetry:
1224 case SenseMediaError:
1225 return EFI_DEVICE_ERROR;
1226
1227 case SenseMediaChange:
1228 IdeDev->BlkIo.Media->MediaId++;
1229 goto DoRC;
1230 break;
1231
1232 default:
1233 RetryTimes--;
1234 break;
1235 }
1236 }
1237 }
1238
1239 return EFI_DEVICE_ERROR;
1240
1241 //
1242 // Do Read Capacity
1243 //
1244 DoRC:
1245 RetryTimes = 5;
1246
1247 while (RetryTimes != 0) {
1248
1249 Status = AtapiReadCapacity (IdeDev, &SenseCount);
1250
1251 if (EFI_ERROR (Status)) {
1252 RetryTimes--;
1253 continue;
1254 } else {
1255
1256 ParseSenseData (IdeDev, SenseCount, &SResult);
1257
1258 switch (SResult) {
1259 case SenseNoSenseKey:
1260 goto Done;
1261 break;
1262
1263 case SenseDeviceNotReadyNeedRetry:
1264 //
1265 // We use Test Unit Ready to retry which
1266 // is faster.
1267 //
1268 goto DoTUR;
1269 break;
1270
1271 case SenseNoMedia:
1272 IdeDev->BlkIo.Media->MediaPresent = FALSE;
1273 IdeDev->BlkIo.Media->LastBlock = 0;
1274 goto Done;
1275 break;
1276
1277 case SenseDeviceNotReadyNoRetry:
1278 case SenseMediaError:
1279 return EFI_DEVICE_ERROR;
1280
1281 case SenseMediaChange:
1282 IdeDev->BlkIo.Media->MediaId++;
1283 continue;
1284 break;
1285
1286 default:
1287 RetryTimes--;
1288 break;
1289 }
1290 }
1291 }
1292
1293 return EFI_DEVICE_ERROR;
1294
1295 Done:
1296 //
1297 // the following code is to check the write-protected for LS120 media
1298 //
1299 if ((IdeDev->BlkIo.Media->MediaPresent) && (IdeDev->Type == IdeMagnetic)) {
1300
1301 Status = IsLS120orZipWriteProtected (IdeDev, &WriteProtected);
1302 if (!EFI_ERROR (Status)) {
1303
1304 if (WriteProtected) {
1305
1306 IdeDev->BlkIo.Media->ReadOnly = TRUE;
1307 } else {
1308
1309 IdeDev->BlkIo.Media->ReadOnly = FALSE;
1310 }
1311
1312 }
1313 }
1314
1315 if (IdeDev->BlkIo.Media->MediaId != OldMediaInfo.MediaId) {
1316 //
1317 // Media change information got from the device
1318 //
1319 *MediaChange = TRUE;
1320 }
1321
1322 if (IdeDev->BlkIo.Media->ReadOnly != OldMediaInfo.ReadOnly) {
1323 *MediaChange = TRUE;
1324 IdeDev->BlkIo.Media->MediaId += 1;
1325 }
1326
1327 if (IdeDev->BlkIo.Media->BlockSize != OldMediaInfo.BlockSize) {
1328 *MediaChange = TRUE;
1329 IdeDev->BlkIo.Media->MediaId += 1;
1330 }
1331
1332 if (IdeDev->BlkIo.Media->LastBlock != OldMediaInfo.LastBlock) {
1333 *MediaChange = TRUE;
1334 IdeDev->BlkIo.Media->MediaId += 1;
1335 }
1336
1337 if (IdeDev->BlkIo.Media->MediaPresent != OldMediaInfo.MediaPresent) {
1338 if (IdeDev->BlkIo.Media->MediaPresent) {
1339 //
1340 // when change from no media to media present, reset the MediaId to 1.
1341 //
1342 IdeDev->BlkIo.Media->MediaId = 1;
1343 } else {
1344 //
1345 // when no media, reset the MediaId to zero.
1346 //
1347 IdeDev->BlkIo.Media->MediaId = 0;
1348 }
1349
1350 *MediaChange = TRUE;
1351 }
1352
1353 //
1354 // if any change on current existing media,
1355 // the Block I/O protocol need to be reinstalled.
1356 //
1357 if (*MediaChange) {
1358 gBS->ReinstallProtocolInterface (
1359 IdeDev->Handle,
1360 &gEfiBlockIoProtocolGuid,
1361 &IdeDev->BlkIo,
1362 &IdeDev->BlkIo
1363 );
1364 }
1365
1366 if (IdeDev->BlkIo.Media->MediaPresent) {
1367 return EFI_SUCCESS;
1368 } else {
1369 return EFI_NO_MEDIA;
1370 }
1371 }
1372
1373 /**
1374 This function is called by the AtapiBlkIoReadBlocks() to perform
1375 read from media in block unit.
1376
1377 The main command used to access media here is READ(10) Command.
1378 READ(10) Command requests that the ATAPI device media transfer
1379 specified data to the host. Data is transferred in block(sector)
1380 unit. The maximum number of blocks that can be transferred once is
1381 65536. This is the main difference between READ(10) and READ(12)
1382 Command. The maximum number of blocks in READ(12) is 2 power 32.
1383
1384 @param[in] *IdeDev
1385 pointer pointing to IDE_BLK_IO_DEV data structure, used
1386 to record all the information of the IDE device.
1387
1388 @param[in] *Buffer
1389 A pointer to the destination buffer for the data.
1390
1391 @param[in] Lba
1392 The starting logical block address to read from
1393 on the device media.
1394
1395 @param[in] NumberOfBlocks
1396 The number of transfer data blocks.
1397
1398 @return status is fully dependent on the return status
1399 of AtapiPacketCommandIn() function.
1400
1401 **/
1402 EFI_STATUS
1403 AtapiReadSectors (
1404 IN IDE_BLK_IO_DEV *IdeDev,
1405 IN VOID *Buffer,
1406 IN EFI_LBA Lba,
1407 IN UINTN NumberOfBlocks
1408 )
1409 {
1410
1411 ATAPI_PACKET_COMMAND Packet;
1412 READ10_CMD *Read10Packet;
1413 EFI_STATUS Status;
1414 UINTN BlocksRemaining;
1415 UINT32 Lba32;
1416 UINT32 BlockSize;
1417 UINT32 ByteCount;
1418 UINT16 SectorCount;
1419 VOID *PtrBuffer;
1420 UINT16 MaxBlock;
1421 UINTN TimeOut;
1422
1423 //
1424 // fill command packet for Read(10) command
1425 //
1426 ZeroMem (&Packet, sizeof (ATAPI_PACKET_COMMAND));
1427 Read10Packet = &Packet.Read10;
1428 Lba32 = (UINT32) Lba;
1429 PtrBuffer = Buffer;
1430
1431 BlockSize = IdeDev->BlkIo.Media->BlockSize;
1432
1433 //
1434 // limit the data bytes that can be transferred by one Read(10) Command
1435 //
1436 MaxBlock = 65535;
1437
1438 BlocksRemaining = NumberOfBlocks;
1439
1440 Status = EFI_SUCCESS;
1441 while (BlocksRemaining > 0) {
1442
1443 if (BlocksRemaining <= MaxBlock) {
1444
1445 SectorCount = (UINT16) BlocksRemaining;
1446 } else {
1447
1448 SectorCount = MaxBlock;
1449 }
1450
1451 //
1452 // fill the Packet data structure
1453 //
1454
1455 Read10Packet->opcode = READ_10;
1456
1457 //
1458 // Lba0 ~ Lba3 specify the start logical block address of the data transfer.
1459 // Lba0 is MSB, Lba3 is LSB
1460 //
1461 Read10Packet->Lba3 = (UINT8) (Lba32 & 0xff);
1462 Read10Packet->Lba2 = (UINT8) (Lba32 >> 8);
1463 Read10Packet->Lba1 = (UINT8) (Lba32 >> 16);
1464 Read10Packet->Lba0 = (UINT8) (Lba32 >> 24);
1465
1466 //
1467 // TranLen0 ~ TranLen1 specify the transfer length in block unit.
1468 // TranLen0 is MSB, TranLen is LSB
1469 //
1470 Read10Packet->TranLen1 = (UINT8) (SectorCount & 0xff);
1471 Read10Packet->TranLen0 = (UINT8) (SectorCount >> 8);
1472
1473 ByteCount = SectorCount * BlockSize;
1474
1475 if (IdeDev->Type == IdeCdRom) {
1476 TimeOut = CDROMLONGTIMEOUT;
1477 } else {
1478 TimeOut = ATAPILONGTIMEOUT;
1479 }
1480
1481 Status = AtapiPacketCommandIn (
1482 IdeDev,
1483 &Packet,
1484 (UINT16 *) PtrBuffer,
1485 ByteCount,
1486 TimeOut
1487 );
1488 if (EFI_ERROR (Status)) {
1489 return Status;
1490 }
1491
1492 Lba32 += SectorCount;
1493 PtrBuffer = (UINT8 *) PtrBuffer + SectorCount * BlockSize;
1494 BlocksRemaining -= SectorCount;
1495 }
1496
1497 return Status;
1498 }
1499
1500 /**
1501 This function is called by the AtapiBlkIoWriteBlocks() to perform
1502 write onto media in block unit.
1503 The main command used to access media here is Write(10) Command.
1504 Write(10) Command requests that the ATAPI device media transfer
1505 specified data to the host. Data is transferred in block (sector)
1506 unit. The maximum number of blocks that can be transferred once is
1507 65536.
1508
1509 @param[in] *IdeDev
1510 pointer pointing to IDE_BLK_IO_DEV data structure, used
1511 to record all the information of the IDE device.
1512
1513 @param[in] *Buffer
1514 A pointer to the source buffer for the data.
1515
1516 @param[in] Lba
1517 The starting logical block address to write onto
1518 the device media.
1519
1520 @param[in] NumberOfBlocks
1521 The number of transfer data blocks.
1522
1523 @return status is fully dependent on the return status
1524 of AtapiPacketCommandOut() function.
1525
1526 **/
1527 EFI_STATUS
1528 AtapiWriteSectors (
1529 IN IDE_BLK_IO_DEV *IdeDev,
1530 IN VOID *Buffer,
1531 IN EFI_LBA Lba,
1532 IN UINTN NumberOfBlocks
1533 )
1534 {
1535
1536 ATAPI_PACKET_COMMAND Packet;
1537 READ10_CMD *Read10Packet;
1538
1539 EFI_STATUS Status;
1540 UINTN BlocksRemaining;
1541 UINT32 Lba32;
1542 UINT32 BlockSize;
1543 UINT32 ByteCount;
1544 UINT16 SectorCount;
1545 VOID *PtrBuffer;
1546 UINT16 MaxBlock;
1547
1548 //
1549 // fill command packet for Write(10) command
1550 // Write(10) command packet has the same data structure as
1551 // Read(10) command packet,
1552 // so here use the Read10Packet data structure
1553 // for the Write(10) command packet.
1554 //
1555 ZeroMem (&Packet, sizeof (ATAPI_PACKET_COMMAND));
1556 Read10Packet = &Packet.Read10;
1557
1558 Lba32 = (UINT32) Lba;
1559 PtrBuffer = Buffer;
1560
1561 BlockSize = IdeDev->BlkIo.Media->BlockSize;
1562
1563 //
1564 // limit the data bytes that can be transferred by one Read(10) Command
1565 //
1566 MaxBlock = (UINT16) (65536 / BlockSize);
1567
1568 BlocksRemaining = NumberOfBlocks;
1569
1570 Status = EFI_SUCCESS;
1571 while (BlocksRemaining > 0) {
1572
1573 if (BlocksRemaining >= MaxBlock) {
1574 SectorCount = MaxBlock;
1575 } else {
1576 SectorCount = (UINT16) BlocksRemaining;
1577 }
1578
1579 //
1580 // Command code is WRITE_10.
1581 //
1582 Read10Packet->opcode = WRITE_10;
1583
1584 //
1585 // Lba0 ~ Lba3 specify the start logical block address of the data transfer.
1586 // Lba0 is MSB, Lba3 is LSB
1587 //
1588 Read10Packet->Lba3 = (UINT8) (Lba32 & 0xff);
1589 Read10Packet->Lba2 = (UINT8) (Lba32 >> 8);
1590 Read10Packet->Lba1 = (UINT8) (Lba32 >> 16);
1591 Read10Packet->Lba0 = (UINT8) (Lba32 >> 24);
1592
1593 //
1594 // TranLen0 ~ TranLen1 specify the transfer length in block unit.
1595 // TranLen0 is MSB, TranLen is LSB
1596 //
1597 Read10Packet->TranLen1 = (UINT8) (SectorCount & 0xff);
1598 Read10Packet->TranLen0 = (UINT8) (SectorCount >> 8);
1599
1600 ByteCount = SectorCount * BlockSize;
1601
1602 Status = AtapiPacketCommandOut (
1603 IdeDev,
1604 &Packet,
1605 (UINT16 *) PtrBuffer,
1606 ByteCount,
1607 ATAPILONGTIMEOUT
1608 );
1609 if (EFI_ERROR (Status)) {
1610 return Status;
1611 }
1612
1613 Lba32 += SectorCount;
1614 PtrBuffer = ((UINT8 *) PtrBuffer + SectorCount * BlockSize);
1615 BlocksRemaining -= SectorCount;
1616 }
1617
1618 return Status;
1619 }
1620
1621 /**
1622 This function is used to implement the Soft Reset on the specified
1623 ATAPI device. Different from the AtaSoftReset(), here reset is a ATA
1624 Soft Reset Command special for ATAPI device, and it only take effects
1625 on the specified ATAPI device, not on the whole IDE bus.
1626 Since the ATAPI soft reset is needed when device is in exceptional
1627 condition (such as BSY bit is always set ), I think the Soft Reset
1628 command should be sent without waiting for the BSY clear and DRDY
1629 set.
1630 This function is called by IdeBlkIoReset(),
1631 a interface function of Block I/O protocol.
1632
1633 @param[in] *IdeDev
1634 pointer pointing to IDE_BLK_IO_DEV data structure, used
1635 to record all the information of the IDE device.
1636
1637 @retval EFI_SUCCESS
1638 Soft reset completes successfully.
1639
1640 @retval EFI_DEVICE_ERROR
1641 Any step during the reset process is failed.
1642
1643 **/
1644 EFI_STATUS
1645 AtapiSoftReset (
1646 IN IDE_BLK_IO_DEV *IdeDev
1647 )
1648 {
1649 UINT8 Command;
1650 UINT8 DeviceSelect;
1651 EFI_STATUS Status;
1652
1653 //
1654 // for ATAPI device, no need to wait DRDY ready after device selecting.
1655 // (bit7 and bit5 are both set to 1 for backward compatibility)
1656 //
1657 DeviceSelect = (UINT8) (((bit7 | bit5) | (IdeDev->Device << 4)));
1658 IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->Head, DeviceSelect);
1659
1660 Command = ATAPI_SOFT_RESET_CMD;
1661 IDEWritePortB (IdeDev->PciIo, IdeDev->IoPort->Reg.Command, Command);
1662
1663 //
1664 // BSY cleared is the only status return to the host by the device
1665 // when reset is completed.
1666 // slave device needs at most 31s to clear BSY
1667 //
1668 Status = WaitForBSYClear (IdeDev, 31000);
1669 if (EFI_ERROR (Status)) {
1670 return EFI_DEVICE_ERROR;
1671 }
1672
1673 //
1674 // stall 5 seconds to make the device status stable
1675 //
1676 gBS->Stall (5000000);
1677
1678 return EFI_SUCCESS;
1679 }
1680
1681 /**
1682 This function is the ATAPI implementation for ReadBlocks in the
1683 Block I/O Protocol interface.
1684
1685 @param[in] *IdeBlkIoDev
1686 Indicates the calling context.
1687
1688 @param[in] MediaId
1689 The media id that the read request is for.
1690
1691 @param[in] LBA
1692 The starting logical block address to read from
1693 on the device.
1694
1695 @param[in] BufferSize
1696 The size of the Buffer in bytes. This must be a
1697 multiple of the intrinsic block size of the device.
1698
1699 @param[out] *Buffer
1700 A pointer to the destination buffer for the data.
1701 The caller is responsible for either having implicit
1702 or explicit ownership of the memory that data is read into.
1703
1704 @retval EFI_SUCCESS
1705 Read Blocks successfully.
1706
1707 @retval EFI_DEVICE_ERROR
1708 Read Blocks failed.
1709
1710 @retval EFI_NO_MEDIA
1711 There is no media in the device.
1712
1713 @retval EFI_MEDIA_CHANGED
1714 The MediaId is not for the current media.
1715
1716 @retval EFI_BAD_BUFFER_SIZE
1717 The BufferSize parameter is not a multiple of the
1718 intrinsic block size of the device.
1719
1720 @retval EFI_INVALID_PARAMETER
1721 The read request contains LBAs that are not valid,
1722 or the data buffer is not valid.
1723
1724 **/
1725 EFI_STATUS
1726 AtapiBlkIoReadBlocks (
1727 IN IDE_BLK_IO_DEV *IdeBlkIoDevice,
1728 IN UINT32 MediaId,
1729 IN EFI_LBA LBA,
1730 IN UINTN BufferSize,
1731 OUT VOID *Buffer
1732 )
1733 {
1734 EFI_BLOCK_IO_MEDIA *Media;
1735 UINTN BlockSize;
1736 UINTN NumberOfBlocks;
1737 EFI_STATUS Status;
1738
1739 BOOLEAN MediaChange;
1740
1741 if (Buffer == NULL) {
1742 return EFI_INVALID_PARAMETER;
1743 }
1744
1745 if (BufferSize == 0) {
1746 return EFI_SUCCESS;
1747 }
1748
1749 //
1750 // ATAPI device media is removable, so it is a must
1751 // to detect media first before read operation
1752 //
1753 MediaChange = FALSE;
1754 Status = AtapiDetectMedia (IdeBlkIoDevice, &MediaChange);
1755 if (EFI_ERROR (Status)) {
1756
1757 if (IdeBlkIoDevice->Cache != NULL) {
1758 gBS->FreePool (IdeBlkIoDevice->Cache);
1759 IdeBlkIoDevice->Cache = NULL;
1760 }
1761
1762 return Status;
1763 }
1764 //
1765 // Get the intrinsic block size
1766 //
1767 Media = IdeBlkIoDevice->BlkIo.Media;
1768 BlockSize = Media->BlockSize;
1769
1770 NumberOfBlocks = BufferSize / BlockSize;
1771
1772 if (!(Media->MediaPresent)) {
1773
1774 if (IdeBlkIoDevice->Cache != NULL) {
1775 gBS->FreePool (IdeBlkIoDevice->Cache);
1776 IdeBlkIoDevice->Cache = NULL;
1777 }
1778 return EFI_NO_MEDIA;
1779
1780 }
1781
1782 if ((MediaId != Media->MediaId) || MediaChange) {
1783
1784 if (IdeBlkIoDevice->Cache != NULL) {
1785 gBS->FreePool (IdeBlkIoDevice->Cache);
1786 IdeBlkIoDevice->Cache = NULL;
1787 }
1788 return EFI_MEDIA_CHANGED;
1789 }
1790
1791 if (BufferSize % BlockSize != 0) {
1792 return EFI_BAD_BUFFER_SIZE;
1793 }
1794
1795 if (LBA > Media->LastBlock) {
1796 return EFI_INVALID_PARAMETER;
1797 }
1798
1799 if ((LBA + NumberOfBlocks - 1) > Media->LastBlock) {
1800 return EFI_INVALID_PARAMETER;
1801 }
1802
1803 if ((Media->IoAlign > 1) && (((UINTN) Buffer & (Media->IoAlign - 1)) != 0)) {
1804 return EFI_INVALID_PARAMETER;
1805 }
1806
1807 //
1808 // if all the parameters are valid, then perform read sectors command
1809 // to transfer data from device to host.
1810 //
1811 Status = AtapiReadSectors (IdeBlkIoDevice, Buffer, LBA, NumberOfBlocks);
1812 if (EFI_ERROR (Status)) {
1813 return EFI_DEVICE_ERROR;
1814 }
1815
1816 //
1817 // Read blocks succeeded
1818 //
1819
1820 //
1821 // save the first block to the cache for performance
1822 //
1823 if (LBA == 0 && !IdeBlkIoDevice->Cache) {
1824 IdeBlkIoDevice->Cache = AllocatePool (BlockSize);
1825 if (IdeBlkIoDevice != NULL) {
1826 CopyMem ((UINT8 *) IdeBlkIoDevice->Cache, (UINT8 *) Buffer, BlockSize);
1827 }
1828 }
1829
1830 return EFI_SUCCESS;
1831
1832 }
1833
1834 /**
1835 This function is the ATAPI implementation for WriteBlocks in the
1836 Block I/O Protocol interface.
1837
1838 @param[in] *This
1839 Indicates the calling context.
1840
1841 @param[in] MediaId
1842 The media id that the write request is for.
1843
1844 @param[in] LBA
1845 The starting logical block address to write onto
1846 the device.
1847
1848 @param[in] BufferSize
1849 The size of the Buffer in bytes. This must be a
1850 multiple of the intrinsic block size of the device.
1851
1852 @param[out] *Buffer
1853 A pointer to the source buffer for the data.
1854 The caller is responsible for either having implicit
1855 or explicit ownership of the memory that data is
1856 written from.
1857
1858 @retval EFI_SUCCESS
1859 Write Blocks successfully.
1860
1861 @retval EFI_DEVICE_ERROR
1862 Write Blocks failed.
1863
1864 @retval EFI_NO_MEDIA
1865 There is no media in the device.
1866
1867 @retval EFI_MEDIA_CHANGE
1868 The MediaId is not for the current media.
1869
1870 @retval EFI_BAD_BUFFER_SIZE
1871 The BufferSize parameter is not a multiple of the
1872 intrinsic block size of the device.
1873
1874 @retval EFI_INVALID_PARAMETER
1875 The write request contains LBAs that are not valid,
1876 or the data buffer is not valid.
1877
1878 TODO: EFI_MEDIA_CHANGED - add return value to function comment
1879 TODO: EFI_WRITE_PROTECTED - add return value to function comment
1880 **/
1881 EFI_STATUS
1882 AtapiBlkIoWriteBlocks (
1883 IN IDE_BLK_IO_DEV *IdeBlkIoDevice,
1884 IN UINT32 MediaId,
1885 IN EFI_LBA LBA,
1886 IN UINTN BufferSize,
1887 OUT VOID *Buffer
1888 )
1889 {
1890
1891 EFI_BLOCK_IO_MEDIA *Media;
1892 UINTN BlockSize;
1893 UINTN NumberOfBlocks;
1894 EFI_STATUS Status;
1895 BOOLEAN MediaChange;
1896
1897 if (LBA == 0 && IdeBlkIoDevice->Cache) {
1898 gBS->FreePool (IdeBlkIoDevice->Cache);
1899 IdeBlkIoDevice->Cache = NULL;
1900 }
1901
1902 if (Buffer == NULL) {
1903 return EFI_INVALID_PARAMETER;
1904 }
1905
1906 if (BufferSize == 0) {
1907 return EFI_SUCCESS;
1908 }
1909
1910 //
1911 // ATAPI device media is removable,
1912 // so it is a must to detect media first before write operation
1913 //
1914 MediaChange = FALSE;
1915 Status = AtapiDetectMedia (IdeBlkIoDevice, &MediaChange);
1916 if (EFI_ERROR (Status)) {
1917
1918 if (LBA == 0 && IdeBlkIoDevice->Cache) {
1919 gBS->FreePool (IdeBlkIoDevice->Cache);
1920 IdeBlkIoDevice->Cache = NULL;
1921 }
1922 return Status;
1923 }
1924
1925 //
1926 // Get the intrinsic block size
1927 //
1928 Media = IdeBlkIoDevice->BlkIo.Media;
1929 BlockSize = Media->BlockSize;
1930 NumberOfBlocks = BufferSize / BlockSize;
1931
1932 if (!(Media->MediaPresent)) {
1933
1934 if (LBA == 0 && IdeBlkIoDevice->Cache) {
1935 gBS->FreePool (IdeBlkIoDevice->Cache);
1936 IdeBlkIoDevice->Cache = NULL;
1937 }
1938 return EFI_NO_MEDIA;
1939 }
1940
1941 if ((MediaId != Media->MediaId) || MediaChange) {
1942
1943 if (LBA == 0 && IdeBlkIoDevice->Cache) {
1944 gBS->FreePool (IdeBlkIoDevice->Cache);
1945 IdeBlkIoDevice->Cache = NULL;
1946 }
1947 return EFI_MEDIA_CHANGED;
1948 }
1949
1950 if (Media->ReadOnly) {
1951 return EFI_WRITE_PROTECTED;
1952 }
1953
1954 if (BufferSize % BlockSize != 0) {
1955 return EFI_BAD_BUFFER_SIZE;
1956 }
1957
1958 if (LBA > Media->LastBlock) {
1959 return EFI_INVALID_PARAMETER;
1960 }
1961
1962 if ((LBA + NumberOfBlocks - 1) > Media->LastBlock) {
1963 return EFI_INVALID_PARAMETER;
1964 }
1965
1966 if ((Media->IoAlign > 1) && (((UINTN) Buffer & (Media->IoAlign - 1)) != 0)) {
1967 return EFI_INVALID_PARAMETER;
1968 }
1969
1970 //
1971 // if all the parameters are valid,
1972 // then perform write sectors command to transfer data from host to device.
1973 //
1974 Status = AtapiWriteSectors (IdeBlkIoDevice, Buffer, LBA, NumberOfBlocks);
1975 if (EFI_ERROR (Status)) {
1976 return EFI_DEVICE_ERROR;
1977 }
1978
1979 return EFI_SUCCESS;
1980
1981 }
1982
1983 /**
1984 This function is used to parse sense data. Only the first
1985 sense data is honoured.
1986
1987 @param[in] IdeDev Indicates the calling context.
1988 @param[in] SenseCount Count of sense data.
1989 @param[out] Result The parsed result.
1990
1991 @retval EFI_SUCCESS Successfully parsed.
1992 @retval EFI_INVALID_PARAMETER Count of sense data is zero.
1993
1994 **/
1995 EFI_STATUS
1996 ParseSenseData (
1997 IN IDE_BLK_IO_DEV *IdeDev,
1998 IN UINTN SenseCount,
1999 OUT SENSE_RESULT *Result
2000 )
2001 {
2002 REQUEST_SENSE_DATA *SenseData;
2003
2004 if (SenseCount == 0) {
2005 return EFI_INVALID_PARAMETER;
2006 }
2007
2008 //
2009 // Only use the first sense data
2010 //
2011 SenseData = IdeDev->SenseData;
2012 *Result = SenseOtherSense;
2013
2014 switch (SenseData->sense_key) {
2015 case SK_NO_SENSE:
2016 *Result = SenseNoSenseKey;
2017 break;
2018 case SK_NOT_READY:
2019 switch (SenseData->addnl_sense_code) {
2020 case ASC_NO_MEDIA:
2021 *Result = SenseNoMedia;
2022 break;
2023 case ASC_MEDIA_UPSIDE_DOWN:
2024 *Result = SenseMediaError;
2025 break;
2026 case ASC_NOT_READY:
2027 if (SenseData->addnl_sense_code_qualifier == ASCQ_IN_PROGRESS) {
2028 *Result = SenseDeviceNotReadyNeedRetry;
2029 } else {
2030 *Result = SenseDeviceNotReadyNoRetry;
2031 }
2032 break;
2033 }
2034 break;
2035 case SK_UNIT_ATTENTION:
2036 if (SenseData->addnl_sense_code == ASC_MEDIA_CHANGE) {
2037 *Result = SenseMediaChange;
2038 }
2039 break;
2040 case SK_MEDIUM_ERROR:
2041 switch (SenseData->addnl_sense_code) {
2042 case ASC_MEDIA_ERR1:
2043 case ASC_MEDIA_ERR2:
2044 case ASC_MEDIA_ERR3:
2045 case ASC_MEDIA_ERR4:
2046 *Result = SenseMediaError;
2047 break;
2048 }
2049 break;
2050 default:
2051 break;
2052 }
2053
2054 return EFI_SUCCESS;
2055 }
2056
2057 /**
2058 This function reads the pending data in the device.
2059
2060 @param[in] IdeDev Indicates the calling context.
2061
2062 @retval EFI_SUCCESS Successfully read.
2063 @retval EFI_NOT_READY The BSY is set avoiding reading.
2064
2065 **/
2066 EFI_STATUS
2067 AtapiReadPendingData (
2068 IN IDE_BLK_IO_DEV *IdeDev
2069 )
2070 {
2071 UINT8 AltRegister;
2072 UINT16 TempWordBuffer;
2073
2074 AltRegister = IDEReadPortB (IdeDev->PciIo, IdeDev->IoPort->Alt.AltStatus);
2075 if ((AltRegister & BSY) == BSY) {
2076 return EFI_NOT_READY;
2077 }
2078 if ((AltRegister & (BSY | DRQ)) == DRQ) {
2079 TempWordBuffer = IDEReadPortB (IdeDev->PciIo,IdeDev->IoPort->Alt.AltStatus);
2080 while ((TempWordBuffer & (BSY | DRQ)) == DRQ) {
2081 IDEReadPortWMultiple (
2082 IdeDev->PciIo,
2083 IdeDev->IoPort->Data,
2084 1,
2085 &TempWordBuffer
2086 );
2087 TempWordBuffer = IDEReadPortB (IdeDev->PciIo,IdeDev->IoPort->Alt.AltStatus);
2088 }
2089 }
2090 return EFI_SUCCESS;
2091 }
2092
2093 /**
2094 TODO: Add function description
2095
2096 @param IdeDev TODO: add argument description
2097 @param WriteProtected TODO: add argument description
2098
2099 @retval EFI_DEVICE_ERROR TODO: Add description for return value
2100 @retval EFI_DEVICE_ERROR TODO: Add description for return value
2101 @retval EFI_SUCCESS TODO: Add description for return value
2102
2103 **/
2104 EFI_STATUS
2105 IsLS120orZipWriteProtected (
2106 IN IDE_BLK_IO_DEV *IdeDev,
2107 OUT BOOLEAN *WriteProtected
2108 )
2109 {
2110 EFI_STATUS Status;
2111
2112 *WriteProtected = FALSE;
2113
2114 Status = LS120EnableMediaStatus (IdeDev, TRUE);
2115 if (EFI_ERROR (Status)) {
2116 return EFI_DEVICE_ERROR;
2117 }
2118
2119 //
2120 // the Get Media Status Command is only valid
2121 // if a Set Features/Enable Media Status Command has been priviously issued.
2122 //
2123 if (LS120GetMediaStatus (IdeDev) == EFI_WRITE_PROTECTED) {
2124
2125 *WriteProtected = TRUE;
2126 } else {
2127
2128 *WriteProtected = FALSE;
2129 }
2130
2131 //
2132 // After Get Media Status Command completes,
2133 // Set Features/Disable Media Command should be sent.
2134 //
2135 Status = LS120EnableMediaStatus (IdeDev, FALSE);
2136 if (EFI_ERROR (Status)) {
2137 return EFI_DEVICE_ERROR;
2138 }
2139
2140 return EFI_SUCCESS;
2141 }