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