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