]> git.proxmox.com Git - mirror_edk2.git/blame - MdeModulePkg/Bus/Usb/UsbBotPei/PeiAtapi.c
UefiCpuPkg: Move AsmRelocateApLoopStart from Mpfuncs.nasm to AmdSev.nasm
[mirror_edk2.git] / MdeModulePkg / Bus / Usb / UsbBotPei / PeiAtapi.c
CommitLineData
4b1bf81c 1/** @file\r
0dbaba42 2Pei USB ATAPI command implementations.\r
4b1bf81c 3\r
d1102dba 4Copyright (c) 1999 - 2018, Intel Corporation. All rights reserved.<BR>\r
be8d6ef3 5Copyright (C) 2022 Advanced Micro Devices, Inc. All rights reserved.<BR>\r
d1102dba 6\r
9d510e61 7SPDX-License-Identifier: BSD-2-Clause-Patent\r
4b1bf81c 8\r
9**/\r
10\r
11#include "UsbBotPeim.h"\r
12#include "BotPeim.h"\r
13\r
1436aea4 14#define MAXSENSEKEY 5\r
4b1bf81c 15\r
16/**\r
17 Sends out ATAPI Inquiry Packet Command to the specified device. This command will\r
18 return INQUIRY data of the device.\r
19\r
20 @param PeiServices The pointer of EFI_PEI_SERVICES.\r
21 @param PeiBotDevice The pointer to PEI_BOT_DEVICE instance.\r
22\r
23 @retval EFI_SUCCESS Inquiry command completes successfully.\r
24 @retval EFI_DEVICE_ERROR Inquiry command failed.\r
25\r
26**/\r
27EFI_STATUS\r
28PeiUsbInquiry (\r
29 IN EFI_PEI_SERVICES **PeiServices,\r
30 IN PEI_BOT_DEVICE *PeiBotDevice\r
31 )\r
32{\r
33 ATAPI_PACKET_COMMAND Packet;\r
34 EFI_STATUS Status;\r
1436aea4 35 ATAPI_INQUIRY_DATA Idata;\r
4b1bf81c 36\r
37 //\r
38 // fill command packet\r
39 //\r
40 ZeroMem (&Packet, sizeof (ATAPI_PACKET_COMMAND));\r
41 ZeroMem (&Idata, sizeof (ATAPI_INQUIRY_DATA));\r
42\r
1436aea4
MK
43 Packet.Inquiry.opcode = ATA_CMD_INQUIRY;\r
44 Packet.Inquiry.page_code = 0;\r
45 Packet.Inquiry.allocation_length = 36;\r
4b1bf81c 46\r
47 //\r
48 // Send scsi INQUIRY command packet.\r
49 // According to SCSI Primary Commands-2 spec, host only needs to\r
50 // retrieve the first 36 bytes for standard INQUIRY data.\r
51 //\r
52 Status = PeiAtapiCommand (\r
1436aea4
MK
53 PeiServices,\r
54 PeiBotDevice,\r
55 &Packet,\r
56 (UINT8)sizeof (ATAPI_PACKET_COMMAND),\r
57 &Idata,\r
58 36,\r
59 EfiUsbDataIn,\r
60 2000\r
61 );\r
4b1bf81c 62\r
63 if (EFI_ERROR (Status)) {\r
64 return EFI_DEVICE_ERROR;\r
65 }\r
66\r
67 if ((Idata.peripheral_type & 0x1f) == 0x05) {\r
1436aea4
MK
68 PeiBotDevice->DeviceType = USBCDROM;\r
69 PeiBotDevice->Media.BlockSize = 0x800;\r
3fe5862f
FT
70 PeiBotDevice->Media2.ReadOnly = TRUE;\r
71 PeiBotDevice->Media2.RemovableMedia = TRUE;\r
72 PeiBotDevice->Media2.BlockSize = 0x800;\r
4b1bf81c 73 } else {\r
1436aea4
MK
74 PeiBotDevice->DeviceType = USBFLOPPY;\r
75 PeiBotDevice->Media.BlockSize = 0x200;\r
3fe5862f
FT
76 PeiBotDevice->Media2.ReadOnly = FALSE;\r
77 PeiBotDevice->Media2.RemovableMedia = TRUE;\r
78 PeiBotDevice->Media2.BlockSize = 0x200;\r
4b1bf81c 79 }\r
80\r
81 return EFI_SUCCESS;\r
82}\r
83\r
84/**\r
85 Sends out ATAPI Test Unit Ready Packet Command to the specified device\r
86 to find out whether device is accessible.\r
87\r
88 @param PeiServices The pointer of EFI_PEI_SERVICES.\r
89 @param PeiBotDevice The pointer to PEI_BOT_DEVICE instance.\r
90\r
91 @retval EFI_SUCCESS TestUnit command executed successfully.\r
92 @retval EFI_DEVICE_ERROR Device cannot be executed TestUnit command successfully.\r
93\r
94**/\r
95EFI_STATUS\r
96PeiUsbTestUnitReady (\r
97 IN EFI_PEI_SERVICES **PeiServices,\r
98 IN PEI_BOT_DEVICE *PeiBotDevice\r
99 )\r
100{\r
101 ATAPI_PACKET_COMMAND Packet;\r
102 EFI_STATUS Status;\r
103\r
104 //\r
105 // fill command packet\r
106 //\r
107 ZeroMem (&Packet, sizeof (ATAPI_PACKET_COMMAND));\r
108 Packet.TestUnitReady.opcode = ATA_CMD_TEST_UNIT_READY;\r
109\r
110 //\r
111 // send command packet\r
112 //\r
113 Status = PeiAtapiCommand (\r
1436aea4
MK
114 PeiServices,\r
115 PeiBotDevice,\r
116 &Packet,\r
117 (UINT8)sizeof (ATAPI_PACKET_COMMAND),\r
118 NULL,\r
119 0,\r
120 EfiUsbNoData,\r
121 2000\r
122 );\r
4b1bf81c 123\r
124 if (EFI_ERROR (Status)) {\r
125 return EFI_DEVICE_ERROR;\r
126 }\r
127\r
128 return EFI_SUCCESS;\r
129}\r
130\r
131/**\r
132 Sends out ATAPI Request Sense Packet Command to the specified device.\r
133\r
134 @param PeiServices The pointer of EFI_PEI_SERVICES.\r
135 @param PeiBotDevice The pointer to PEI_BOT_DEVICE instance.\r
136 @param SenseCounts Length of sense buffer.\r
137 @param SenseKeyBuffer Pointer to sense buffer.\r
138\r
139 @retval EFI_SUCCESS Command executed successfully.\r
140 @retval EFI_DEVICE_ERROR Some device errors happen.\r
141\r
142**/\r
143EFI_STATUS\r
144PeiUsbRequestSense (\r
145 IN EFI_PEI_SERVICES **PeiServices,\r
146 IN PEI_BOT_DEVICE *PeiBotDevice,\r
147 OUT UINTN *SenseCounts,\r
148 IN UINT8 *SenseKeyBuffer\r
149 )\r
150{\r
1436aea4
MK
151 EFI_STATUS Status;\r
152 ATAPI_PACKET_COMMAND Packet;\r
153 UINT8 *Ptr;\r
154 BOOLEAN SenseReq;\r
155 ATAPI_REQUEST_SENSE_DATA *Sense;\r
4b1bf81c 156\r
157 *SenseCounts = 0;\r
158\r
159 //\r
160 // fill command packet for Request Sense Packet Command\r
161 //\r
162 ZeroMem (&Packet, sizeof (ATAPI_PACKET_COMMAND));\r
163 Packet.RequestSence.opcode = ATA_CMD_REQUEST_SENSE;\r
1436aea4 164 Packet.RequestSence.allocation_length = (UINT8)sizeof (ATAPI_REQUEST_SENSE_DATA);\r
4b1bf81c 165\r
166 Ptr = SenseKeyBuffer;\r
167\r
168 SenseReq = TRUE;\r
169\r
170 //\r
171 // request sense data from device continuously\r
172 // until no sense data exists in the device.\r
173 //\r
174 while (SenseReq) {\r
1436aea4 175 Sense = (ATAPI_REQUEST_SENSE_DATA *)Ptr;\r
4b1bf81c 176\r
177 //\r
178 // send out Request Sense Packet Command and get one Sense\r
179 // data form device.\r
180 //\r
181 Status = PeiAtapiCommand (\r
1436aea4
MK
182 PeiServices,\r
183 PeiBotDevice,\r
184 &Packet,\r
185 (UINT8)sizeof (ATAPI_PACKET_COMMAND),\r
186 (VOID *)Ptr,\r
187 sizeof (ATAPI_REQUEST_SENSE_DATA),\r
188 EfiUsbDataIn,\r
189 2000\r
190 );\r
4b1bf81c 191\r
192 //\r
193 // failed to get Sense data\r
194 //\r
195 if (EFI_ERROR (Status)) {\r
196 if (*SenseCounts == 0) {\r
197 return EFI_DEVICE_ERROR;\r
198 } else {\r
199 return EFI_SUCCESS;\r
200 }\r
201 }\r
202\r
203 if (Sense->sense_key != ATA_SK_NO_SENSE) {\r
4b1bf81c 204 Ptr += sizeof (ATAPI_REQUEST_SENSE_DATA);\r
205 //\r
206 // Ptr is byte based pointer\r
207 //\r
208 (*SenseCounts)++;\r
209\r
210 if (*SenseCounts == MAXSENSEKEY) {\r
211 break;\r
212 }\r
4b1bf81c 213 } else {\r
214 //\r
215 // when no sense key, skip out the loop\r
216 //\r
217 SenseReq = FALSE;\r
218 }\r
219 }\r
220\r
221 return EFI_SUCCESS;\r
222}\r
223\r
224/**\r
225 Sends out ATAPI Read Capacity Packet Command to the specified device.\r
226 This command will return the information regarding the capacity of the\r
227 media in the device.\r
228\r
229 @param PeiServices The pointer of EFI_PEI_SERVICES.\r
230 @param PeiBotDevice The pointer to PEI_BOT_DEVICE instance.\r
231\r
232 @retval EFI_SUCCESS Command executed successfully.\r
233 @retval EFI_DEVICE_ERROR Some device errors happen.\r
234\r
235**/\r
236EFI_STATUS\r
237PeiUsbReadCapacity (\r
238 IN EFI_PEI_SERVICES **PeiServices,\r
239 IN PEI_BOT_DEVICE *PeiBotDevice\r
240 )\r
241{\r
1436aea4
MK
242 EFI_STATUS Status;\r
243 ATAPI_PACKET_COMMAND Packet;\r
244 ATAPI_READ_CAPACITY_DATA Data;\r
245 UINT32 LastBlock;\r
4b1bf81c 246\r
247 ZeroMem (&Data, sizeof (ATAPI_READ_CAPACITY_DATA));\r
248 ZeroMem (&Packet, sizeof (ATAPI_PACKET_COMMAND));\r
249\r
250 Packet.Inquiry.opcode = ATA_CMD_READ_CAPACITY;\r
251\r
252 //\r
253 // send command packet\r
254 //\r
255 Status = PeiAtapiCommand (\r
1436aea4
MK
256 PeiServices,\r
257 PeiBotDevice,\r
258 &Packet,\r
259 (UINT8)sizeof (ATAPI_PACKET_COMMAND),\r
260 (VOID *)&Data,\r
261 sizeof (ATAPI_READ_CAPACITY_DATA),\r
262 EfiUsbDataIn,\r
263 2000\r
264 );\r
4b1bf81c 265\r
266 if (EFI_ERROR (Status)) {\r
267 return EFI_DEVICE_ERROR;\r
268 }\r
1436aea4
MK
269\r
270 LastBlock = ((UINT32)Data.LastLba3 << 24) | (Data.LastLba2 << 16) | (Data.LastLba1 << 8) | Data.LastLba0;\r
4b1bf81c 271\r
3fe5862f 272 if (LastBlock == 0xFFFFFFFF) {\r
87000d77 273 DEBUG ((DEBUG_INFO, "The usb device LBA count is larger than 0xFFFFFFFF!\n"));\r
3fe5862f
FT
274 }\r
275\r
276 PeiBotDevice->Media.LastBlock = LastBlock;\r
277 PeiBotDevice->Media.MediaPresent = TRUE;\r
4b1bf81c 278\r
3fe5862f
FT
279 PeiBotDevice->Media2.LastBlock = LastBlock;\r
280 PeiBotDevice->Media2.MediaPresent = TRUE;\r
4b1bf81c 281\r
282 return EFI_SUCCESS;\r
283}\r
284\r
285/**\r
286 Sends out ATAPI Read Format Capacity Data Command to the specified device.\r
287 This command will return the information regarding the capacity of the\r
288 media in the device.\r
289\r
290 @param PeiServices The pointer of EFI_PEI_SERVICES.\r
291 @param PeiBotDevice The pointer to PEI_BOT_DEVICE instance.\r
292\r
293 @retval EFI_SUCCESS Command executed successfully.\r
294 @retval EFI_DEVICE_ERROR Some device errors happen.\r
295\r
296**/\r
297EFI_STATUS\r
298PeiUsbReadFormattedCapacity (\r
299 IN EFI_PEI_SERVICES **PeiServices,\r
300 IN PEI_BOT_DEVICE *PeiBotDevice\r
301 )\r
302{\r
1436aea4
MK
303 EFI_STATUS Status;\r
304 ATAPI_PACKET_COMMAND Packet;\r
305 ATAPI_READ_FORMAT_CAPACITY_DATA FormatData;\r
306 UINT32 LastBlock;\r
4b1bf81c 307\r
308 ZeroMem (&FormatData, sizeof (ATAPI_READ_FORMAT_CAPACITY_DATA));\r
309 ZeroMem (&Packet, sizeof (ATAPI_PACKET_COMMAND));\r
310\r
1436aea4
MK
311 Packet.ReadFormatCapacity.opcode = ATA_CMD_READ_FORMAT_CAPACITY;\r
312 Packet.ReadFormatCapacity.allocation_length_lo = 12;\r
4b1bf81c 313\r
314 //\r
315 // send command packet\r
316 //\r
317 Status = PeiAtapiCommand (\r
1436aea4
MK
318 PeiServices,\r
319 PeiBotDevice,\r
320 &Packet,\r
321 (UINT8)sizeof (ATAPI_PACKET_COMMAND),\r
322 (VOID *)&FormatData,\r
323 sizeof (ATAPI_READ_FORMAT_CAPACITY_DATA),\r
324 EfiUsbDataIn,\r
325 2000\r
326 );\r
4b1bf81c 327\r
328 if (EFI_ERROR (Status)) {\r
329 return EFI_DEVICE_ERROR;\r
330 }\r
331\r
332 if (FormatData.DesCode == 3) {\r
333 //\r
334 // Media is not present\r
335 //\r
336 PeiBotDevice->Media.MediaPresent = FALSE;\r
337 PeiBotDevice->Media.LastBlock = 0;\r
1436aea4
MK
338 PeiBotDevice->Media2.MediaPresent = FALSE;\r
339 PeiBotDevice->Media2.LastBlock = 0;\r
4b1bf81c 340 } else {\r
1436aea4 341 LastBlock = ((UINT32)FormatData.LastLba3 << 24) | (FormatData.LastLba2 << 16) | (FormatData.LastLba1 << 8) | FormatData.LastLba0;\r
3fe5862f 342 if (LastBlock == 0xFFFFFFFF) {\r
87000d77 343 DEBUG ((DEBUG_INFO, "The usb device LBA count is larger than 0xFFFFFFFF!\n"));\r
3fe5862f 344 }\r
4b1bf81c 345\r
3fe5862f 346 PeiBotDevice->Media.LastBlock = LastBlock;\r
4b1bf81c 347\r
348 PeiBotDevice->Media.LastBlock--;\r
349\r
350 PeiBotDevice->Media.MediaPresent = TRUE;\r
3fe5862f
FT
351\r
352 PeiBotDevice->Media2.MediaPresent = TRUE;\r
353 PeiBotDevice->Media2.LastBlock = PeiBotDevice->Media.LastBlock;\r
4b1bf81c 354 }\r
355\r
356 return EFI_SUCCESS;\r
357}\r
358\r
359/**\r
360 Execute Read(10) ATAPI command on a specific SCSI target.\r
361\r
362 Executes the ATAPI Read(10) command on the ATAPI target specified by PeiBotDevice.\r
363\r
364 @param PeiServices The pointer of EFI_PEI_SERVICES.\r
365 @param PeiBotDevice The pointer to PEI_BOT_DEVICE instance.\r
366 @param Buffer The pointer to data buffer.\r
367 @param Lba The start logic block address of reading.\r
368 @param NumberOfBlocks The block number of reading.\r
369\r
370 @retval EFI_SUCCESS Command executed successfully.\r
371 @retval EFI_DEVICE_ERROR Some device errors happen.\r
372\r
373**/\r
374EFI_STATUS\r
375PeiUsbRead10 (\r
376 IN EFI_PEI_SERVICES **PeiServices,\r
377 IN PEI_BOT_DEVICE *PeiBotDevice,\r
378 IN VOID *Buffer,\r
379 IN EFI_PEI_LBA Lba,\r
380 IN UINTN NumberOfBlocks\r
381 )\r
382{\r
383 ATAPI_PACKET_COMMAND Packet;\r
384 ATAPI_READ10_CMD *Read10Packet;\r
385 UINT16 MaxBlock;\r
be8d6ef3
AC
386 UINT32 BlocksRemaining;\r
387 UINT32 SectorCount;\r
4b1bf81c 388 UINT32 Lba32;\r
389 UINT32 BlockSize;\r
390 UINT32 ByteCount;\r
391 VOID *PtrBuffer;\r
392 EFI_STATUS Status;\r
be8d6ef3 393 UINT32 TimeOut;\r
4b1bf81c 394\r
395 //\r
396 // prepare command packet for the Inquiry Packet Command.\r
397 //\r
398 ZeroMem (&Packet, sizeof (ATAPI_PACKET_COMMAND));\r
1436aea4
MK
399 Read10Packet = &Packet.Read10;\r
400 Lba32 = (UINT32)Lba;\r
401 PtrBuffer = Buffer;\r
4b1bf81c 402\r
1436aea4 403 BlockSize = (UINT32)PeiBotDevice->Media.BlockSize;\r
4b1bf81c 404\r
be8d6ef3
AC
405 MaxBlock = (UINT16)(MAX_UINT16 / BlockSize);\r
406 ASSERT (NumberOfBlocks < MAX_UINT32);\r
407 BlocksRemaining = (UINT32)NumberOfBlocks;\r
4b1bf81c 408\r
1436aea4 409 Status = EFI_SUCCESS;\r
4b1bf81c 410 while (BlocksRemaining > 0) {\r
be8d6ef3 411 SectorCount = MIN (BlocksRemaining, MaxBlock);\r
1436aea4 412\r
4b1bf81c 413 //\r
414 // fill the Packet data structure\r
415 //\r
416 Read10Packet->opcode = ATA_CMD_READ_10;\r
417\r
418 //\r
419 // Lba0 ~ Lba3 specify the start logical block address of the data transfer.\r
420 // Lba0 is MSB, Lba3 is LSB\r
421 //\r
1436aea4
MK
422 Read10Packet->Lba3 = (UINT8)(Lba32 & 0xff);\r
423 Read10Packet->Lba2 = (UINT8)(Lba32 >> 8);\r
424 Read10Packet->Lba1 = (UINT8)(Lba32 >> 16);\r
425 Read10Packet->Lba0 = (UINT8)(Lba32 >> 24);\r
4b1bf81c 426\r
427 //\r
428 // TranLen0 ~ TranLen1 specify the transfer length in block unit.\r
429 // TranLen0 is MSB, TranLen is LSB\r
430 //\r
1436aea4
MK
431 Read10Packet->TranLen1 = (UINT8)(SectorCount & 0xff);\r
432 Read10Packet->TranLen0 = (UINT8)(SectorCount >> 8);\r
4b1bf81c 433\r
1436aea4 434 ByteCount = SectorCount * BlockSize;\r
4b1bf81c 435\r
be8d6ef3 436 TimeOut = SectorCount * 2000;\r
4b1bf81c 437\r
438 //\r
439 // send command packet\r
440 //\r
441 Status = PeiAtapiCommand (\r
1436aea4
MK
442 PeiServices,\r
443 PeiBotDevice,\r
444 &Packet,\r
445 (UINT8)sizeof (ATAPI_PACKET_COMMAND),\r
446 (VOID *)PtrBuffer,\r
447 ByteCount,\r
448 EfiUsbDataIn,\r
be8d6ef3 449 (UINT16)MIN (TimeOut, MAX_UINT16)\r
1436aea4 450 );\r
4b1bf81c 451\r
452 if (Status != EFI_SUCCESS) {\r
453 return Status;\r
454 }\r
455\r
be8d6ef3 456 ASSERT (Lba32 <= (MAX_UINT32-SectorCount));\r
1436aea4
MK
457 Lba32 += SectorCount;\r
458 PtrBuffer = (UINT8 *)PtrBuffer + SectorCount * BlockSize;\r
be8d6ef3 459 BlocksRemaining = BlocksRemaining - SectorCount;\r
4b1bf81c 460 }\r
461\r
462 return Status;\r
463}\r
464\r
d1102dba 465/**\r
4b1bf81c 466 Check if there is media according to sense data.\r
467\r
468 @param SenseData Pointer to sense data.\r
469 @param SenseCounts Count of sense data.\r
470\r
471 @retval TRUE No media\r
472 @retval FALSE Media exists\r
473\r
474**/\r
475BOOLEAN\r
476IsNoMedia (\r
1436aea4
MK
477 IN ATAPI_REQUEST_SENSE_DATA *SenseData,\r
478 IN UINTN SenseCounts\r
4b1bf81c 479 )\r
480{\r
481 ATAPI_REQUEST_SENSE_DATA *SensePtr;\r
3fe5862f
FT
482 UINTN Index;\r
483 BOOLEAN NoMedia;\r
4b1bf81c 484\r
1436aea4
MK
485 NoMedia = FALSE;\r
486 SensePtr = SenseData;\r
4b1bf81c 487\r
488 for (Index = 0; Index < SenseCounts; Index++) {\r
4b1bf81c 489 switch (SensePtr->sense_key) {\r
1436aea4
MK
490 case ATA_SK_NOT_READY:\r
491 switch (SensePtr->addnl_sense_code) {\r
492 //\r
493 // if no media, fill IdeDev parameter with specific info.\r
494 //\r
495 case ATA_ASC_NO_MEDIA:\r
496 NoMedia = TRUE;\r
497 break;\r
498\r
499 default:\r
500 break;\r
501 }\r
4b1bf81c 502\r
4b1bf81c 503 break;\r
504\r
505 default:\r
506 break;\r
4b1bf81c 507 }\r
508\r
509 SensePtr++;\r
510 }\r
511\r
512 return NoMedia;\r
513}\r
514\r
d1102dba 515/**\r
4b1bf81c 516 Check if there is media error according to sense data.\r
517\r
518 @param SenseData Pointer to sense data.\r
519 @param SenseCounts Count of sense data.\r
520\r
521 @retval TRUE Media error\r
522 @retval FALSE No media error\r
523\r
524**/\r
525BOOLEAN\r
526IsMediaError (\r
1436aea4
MK
527 IN ATAPI_REQUEST_SENSE_DATA *SenseData,\r
528 IN UINTN SenseCounts\r
4b1bf81c 529 )\r
530{\r
531 ATAPI_REQUEST_SENSE_DATA *SensePtr;\r
3fe5862f
FT
532 UINTN Index;\r
533 BOOLEAN Error;\r
4b1bf81c 534\r
1436aea4
MK
535 SensePtr = SenseData;\r
536 Error = FALSE;\r
4b1bf81c 537\r
538 for (Index = 0; Index < SenseCounts; Index++) {\r
4b1bf81c 539 switch (SensePtr->sense_key) {\r
1436aea4
MK
540 //\r
541 // Medium error case\r
542 //\r
543 case ATA_SK_MEDIUM_ERROR:\r
544 switch (SensePtr->addnl_sense_code) {\r
545 case ATA_ASC_MEDIA_ERR1:\r
546 //\r
547 // fall through\r
548 //\r
549 case ATA_ASC_MEDIA_ERR2:\r
550 //\r
551 // fall through\r
552 //\r
553 case ATA_ASC_MEDIA_ERR3:\r
554 //\r
555 // fall through\r
556 //\r
557 case ATA_ASC_MEDIA_ERR4:\r
558 Error = TRUE;\r
559 break;\r
560\r
561 default:\r
562 break;\r
563 }\r
4b1bf81c 564\r
4b1bf81c 565 break;\r
4b1bf81c 566\r
1436aea4
MK
567 //\r
568 // Medium upside-down case\r
569 //\r
570 case ATA_SK_NOT_READY:\r
571 switch (SensePtr->addnl_sense_code) {\r
572 case ATA_ASC_MEDIA_UPSIDE_DOWN:\r
573 Error = TRUE;\r
574 break;\r
575\r
576 default:\r
577 break;\r
578 }\r
4b1bf81c 579\r
4b1bf81c 580 break;\r
581\r
582 default:\r
583 break;\r
4b1bf81c 584 }\r
585\r
586 SensePtr++;\r
587 }\r
588\r
589 return Error;\r
590}\r
591\r
d1102dba 592/**\r
4b1bf81c 593 Check if media is changed according to sense data.\r
594\r
595 @param SenseData Pointer to sense data.\r
596 @param SenseCounts Count of sense data.\r
597\r
598 @retval TRUE There is media change event.\r
599 @retval FALSE media is NOT changed.\r
600\r
601**/\r
602BOOLEAN\r
603IsMediaChange (\r
1436aea4
MK
604 IN ATAPI_REQUEST_SENSE_DATA *SenseData,\r
605 IN UINTN SenseCounts\r
4b1bf81c 606 )\r
607{\r
608 ATAPI_REQUEST_SENSE_DATA *SensePtr;\r
609 UINTN Index;\r
610 BOOLEAN MediaChange;\r
611\r
612 MediaChange = FALSE;\r
613\r
1436aea4 614 SensePtr = SenseData;\r
4b1bf81c 615\r
616 for (Index = 0; Index < SenseCounts; Index++) {\r
617 //\r
618 // catch media change sense key and addition sense data\r
619 //\r
620 switch (SensePtr->sense_key) {\r
1436aea4
MK
621 case ATA_SK_UNIT_ATTENTION:\r
622 switch (SensePtr->addnl_sense_code) {\r
623 case ATA_ASC_MEDIA_CHANGE:\r
624 MediaChange = TRUE;\r
625 break;\r
626\r
627 default:\r
628 break;\r
629 }\r
630\r
4b1bf81c 631 break;\r
632\r
633 default:\r
634 break;\r
4b1bf81c 635 }\r
636\r
637 SensePtr++;\r
638 }\r
639\r
640 return MediaChange;\r
641}\r