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