1 /** @file
2    This file contains all helper functions on the ATAPI command
3 
4   Copyright (c) 2006 - 2010, 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
LS120GetMediaStatus(IN IDE_BLK_IO_DEV * IdeDev)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
LS120EnableMediaStatus(IN IDE_BLK_IO_DEV * IdeDev,IN BOOLEAN Enable)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
AtapiReadPendingData(IN IDE_BLK_IO_DEV * IdeDev)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
PioReadWriteData(IN IDE_BLK_IO_DEV * IdeDev,IN UINT16 * Buffer,IN UINT32 ByteCount,IN BOOLEAN Read,IN UINTN TimeOut)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
AtapiPacketCommandIn(IN IDE_BLK_IO_DEV * IdeDev,IN ATAPI_PACKET_COMMAND * Packet,IN UINT16 * Buffer,IN UINT32 ByteCount,IN UINTN TimeOut)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
AtapiPacketCommandOut(IN IDE_BLK_IO_DEV * IdeDev,IN ATAPI_PACKET_COMMAND * Packet,IN UINT16 * Buffer,IN UINT32 ByteCount,IN UINTN TimeOut)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
AtapiInquiry(IN IDE_BLK_IO_DEV * IdeDev)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
ATAPIIdentify(IN IDE_BLK_IO_DEV * IdeDev)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
AtapiRequestSense(IN IDE_BLK_IO_DEV * IdeDev,OUT UINTN * SenseCounts)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
ParseSenseData(IN IDE_BLK_IO_DEV * IdeDev,IN UINTN SenseCount,OUT SENSE_RESULT * Result)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
AtapiTestUnitReady(IN IDE_BLK_IO_DEV * IdeDev,OUT SENSE_RESULT * SResult)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
AtapiReadCapacity(IN IDE_BLK_IO_DEV * IdeDev,OUT SENSE_RESULT * SResult)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 = (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 =  (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
IsLS120orZipWriteProtected(IN IDE_BLK_IO_DEV * IdeDev,OUT BOOLEAN * WriteProtected)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
AtapiDetectMedia(IN IDE_BLK_IO_DEV * IdeDev,OUT BOOLEAN * MediaChange)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
AtapiReadSectors(IN IDE_BLK_IO_DEV * IdeDev,IN VOID * Buffer,IN EFI_LBA Lba,IN UINTN NumberOfBlocks)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
AtapiWriteSectors(IN IDE_BLK_IO_DEV * IdeDev,IN VOID * Buffer,IN EFI_LBA Lba,IN UINTN NumberOfBlocks)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
AtapiSoftReset(IN IDE_BLK_IO_DEV * IdeDev)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
AtapiBlkIoReadBlocks(IN IDE_BLK_IO_DEV * IdeBlkIoDevice,IN UINT32 MediaId,IN EFI_LBA Lba,IN UINTN BufferSize,OUT VOID * Buffer)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
AtapiBlkIoWriteBlocks(IN IDE_BLK_IO_DEV * IdeBlkIoDevice,IN UINT32 MediaId,IN EFI_LBA Lba,IN UINTN BufferSize,OUT VOID * Buffer)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 
1953