Fixed EDKT532 and EDKT533
[mirror_edk2.git] / EdkModulePkg / Bus / Usb / UsbMassStorage / Dxe / UsbMassStorage.c
CommitLineData
878ddf1f 1/*++\r
2\r
4d1fe68e 3Copyright (c) 2006, Intel Corporation\r
4All rights reserved. This program and the accompanying materials\r
5are licensed and made available under the terms and conditions of the BSD License\r
6which accompanies this distribution. The full text of the license may be found at\r
7http://opensource.org/licenses/bsd-license.php\r
8\r
9THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
10WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
878ddf1f 11\r
12Module Name:\r
13\r
14 UsbMassStorage.c\r
4d1fe68e 15\r
878ddf1f 16Abstract:\r
17\r
18 USB Mass Storage Driver\r
19\r
20Revision History\r
21\r
22--*/\r
23\r
24#include "UsbMassStorage.h"\r
25#include "UsbMassStorageHelper.h"\r
26\r
878ddf1f 27//\r
28// Block I/O Protocol Interface\r
29//\r
30STATIC\r
31EFI_STATUS\r
32EFIAPI\r
33USBFloppyReset (\r
34 IN EFI_BLOCK_IO_PROTOCOL *This,\r
35 IN BOOLEAN ExtendedVerification\r
36 );\r
37\r
38STATIC\r
39EFI_STATUS\r
40EFIAPI\r
41USBFloppyReadBlocks (\r
42 IN EFI_BLOCK_IO_PROTOCOL *This,\r
43 IN UINT32 MediaId,\r
44 IN EFI_LBA LBA,\r
45 IN UINTN BufferSize,\r
46 OUT VOID *Buffer\r
47 );\r
48\r
49STATIC\r
50EFI_STATUS\r
51EFIAPI\r
52USBFloppyWriteBlocks (\r
53 IN EFI_BLOCK_IO_PROTOCOL *This,\r
54 IN UINT32 MediaId,\r
55 IN EFI_LBA LBA,\r
56 IN UINTN BufferSize,\r
57 IN VOID *Buffer\r
58 );\r
59\r
60STATIC\r
61EFI_STATUS\r
62EFIAPI\r
63USBFloppyFlushBlocks (\r
64 IN EFI_BLOCK_IO_PROTOCOL *This\r
65 );\r
66\r
67//\r
68// USB Floppy Driver Global Variables\r
69//\r
70EFI_DRIVER_BINDING_PROTOCOL gUSBFloppyDriverBinding = {\r
71 USBFloppyDriverBindingSupported,\r
72 USBFloppyDriverBindingStart,\r
73 USBFloppyDriverBindingStop,\r
61fb1657 74 0xa,\r
878ddf1f 75 NULL,\r
76 NULL\r
77};\r
78\r
79EFI_STATUS\r
80EFIAPI\r
81USBFloppyDriverBindingSupported (\r
82 IN EFI_DRIVER_BINDING_PROTOCOL *This,\r
83 IN EFI_HANDLE Controller,\r
84 IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath\r
85 )\r
86/*++\r
87\r
88 Routine Description:\r
89 Test to see if this driver supports ControllerHandle. Any ControllerHandle\r
90 that has UsbHcProtocol installed will be supported.\r
91\r
92 Arguments:\r
93 This - Protocol instance pointer.\r
94 Controller - Handle of device to test\r
95 RemainingDevicePath - Not used\r
96\r
97 Returns:\r
98 EFI_SUCCESS - This driver supports this device.\r
99 EFI_UNSUPPORTED - This driver does not support this device.\r
100\r
101--*/\r
102{\r
103 EFI_STATUS OpenStatus;\r
104 EFI_USB_ATAPI_PROTOCOL *AtapiProtocol;\r
105\r
106 //\r
107 // check whether EFI_USB_ATAPI_PROTOCOL exists, if it does,\r
108 // then the controller must be a USB Mass Storage Controller\r
109 //\r
110 OpenStatus = gBS->OpenProtocol (\r
111 Controller,\r
112 &gEfiUsbAtapiProtocolGuid,\r
113 (VOID **) &AtapiProtocol,\r
114 This->DriverBindingHandle,\r
115 Controller,\r
116 EFI_OPEN_PROTOCOL_BY_DRIVER\r
117 );\r
118 if (EFI_ERROR (OpenStatus)) {\r
119 return OpenStatus;\r
120 }\r
121\r
122 gBS->CloseProtocol (\r
123 Controller,\r
124 &gEfiUsbAtapiProtocolGuid,\r
125 This->DriverBindingHandle,\r
126 Controller\r
127 );\r
128\r
129 return EFI_SUCCESS;\r
130}\r
131\r
132EFI_STATUS\r
133EFIAPI\r
134USBFloppyDriverBindingStart (\r
135 IN EFI_DRIVER_BINDING_PROTOCOL *This,\r
136 IN EFI_HANDLE Controller,\r
137 IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath\r
138 )\r
139/*++\r
140\r
141 Routine Description:\r
142 Starting the Usb Bus Driver\r
143\r
144 Arguments:\r
145 This - Protocol instance pointer.\r
146 Controller - Handle of device to test\r
147 RemainingDevicePath - Not used\r
148\r
149 Returns:\r
150 EFI_SUCCESS - This driver supports this device.\r
151 EFI_UNSUPPORTED - This driver does not support this device.\r
152 EFI_DEVICE_ERROR - This driver cannot be started due to device\r
153 Error\r
154 EFI_OUT_OF_RESOURCES- Can't allocate memory resources\r
155 EFI_ALREADY_STARTED - Thios driver has been started\r
156--*/\r
4d1fe68e 157{\r
158 EFI_STATUS Status;\r
878ddf1f 159 EFI_USB_ATAPI_PROTOCOL *AtapiProtocol;\r
160 USB_FLOPPY_DEV *UsbFloppyDevice;\r
4d1fe68e 161\r
878ddf1f 162 UsbFloppyDevice = NULL;\r
163 //\r
164 // Check whether Usb Atapi Protocol attached on the controller handle.\r
165 //\r
166 Status = gBS->OpenProtocol (\r
167 Controller,\r
168 &gEfiUsbAtapiProtocolGuid,\r
169 (VOID **) &AtapiProtocol,\r
170 This->DriverBindingHandle,\r
171 Controller,\r
172 EFI_OPEN_PROTOCOL_BY_DRIVER\r
173 );\r
174 if (EFI_ERROR (Status)) {\r
175 return Status;\r
176 }\r
177\r
178 Status = gBS->AllocatePool (\r
179 EfiBootServicesData,\r
180 sizeof (USB_FLOPPY_DEV),\r
181 (VOID **) &UsbFloppyDevice\r
182 );\r
183 if (EFI_ERROR (Status)) {\r
184 gBS->CloseProtocol (\r
185 Controller,\r
186 &gEfiUsbAtapiProtocolGuid,\r
187 This->DriverBindingHandle,\r
188 Controller\r
189 );\r
190 return Status;\r
191 }\r
192\r
193 ZeroMem (UsbFloppyDevice, sizeof (USB_FLOPPY_DEV));\r
194\r
195 UsbFloppyDevice->Handle = Controller;\r
196 UsbFloppyDevice->BlkIo.Media = &UsbFloppyDevice->BlkMedia;\r
197 UsbFloppyDevice->Signature = USB_FLOPPY_DEV_SIGNATURE;\r
198 UsbFloppyDevice->BlkIo.Reset = USBFloppyReset;\r
199 UsbFloppyDevice->BlkIo.ReadBlocks = USBFloppyReadBlocks;\r
200 UsbFloppyDevice->BlkIo.WriteBlocks = USBFloppyWriteBlocks;\r
201 UsbFloppyDevice->BlkIo.FlushBlocks = USBFloppyFlushBlocks;\r
202 UsbFloppyDevice->AtapiProtocol = AtapiProtocol;\r
203\r
204 //\r
205 // Identify drive type and retrieve media information.\r
206 //\r
207 Status = USBFloppyIdentify (UsbFloppyDevice);\r
208 if (EFI_ERROR (Status)) {\r
209 if (UsbFloppyDevice->SenseData != NULL) {\r
210 gBS->FreePool (UsbFloppyDevice->SenseData);\r
211 }\r
212\r
213 gBS->FreePool (UsbFloppyDevice);\r
214 gBS->CloseProtocol (\r
215 Controller,\r
216 &gEfiUsbAtapiProtocolGuid,\r
217 This->DriverBindingHandle,\r
218 Controller\r
219 );\r
220 return Status;\r
221 }\r
222 //\r
223 // Install Block I/O protocol for the usb floppy device.\r
224 //\r
225 Status = gBS->InstallProtocolInterface (\r
226 &Controller,\r
227 &gEfiBlockIoProtocolGuid,\r
228 EFI_NATIVE_INTERFACE,\r
229 &UsbFloppyDevice->BlkIo\r
230 );\r
231 if (EFI_ERROR (Status)) {\r
232 if (UsbFloppyDevice->SenseData != NULL) {\r
233 gBS->FreePool (UsbFloppyDevice->SenseData);\r
234 }\r
235\r
236 gBS->FreePool (UsbFloppyDevice);\r
237 gBS->CloseProtocol (\r
238 Controller,\r
239 &gEfiUsbAtapiProtocolGuid,\r
240 This->DriverBindingHandle,\r
241 Controller\r
242 );\r
243 return Status;\r
244 }\r
245\r
246 return EFI_SUCCESS;\r
247\r
248}\r
249\r
250\r
251EFI_STATUS\r
252EFIAPI\r
253USBFloppyDriverBindingStop (\r
254 IN EFI_DRIVER_BINDING_PROTOCOL *This,\r
255 IN EFI_HANDLE Controller,\r
256 IN UINTN NumberOfChildren,\r
257 IN EFI_HANDLE *ChildHandleBuffer\r
258 )\r
259/*++\r
260\r
261 Routine Description:\r
262 Stop this driver on ControllerHandle. Support stoping any child handles\r
263 created by this driver.\r
264\r
265 Arguments:\r
266 This - Protocol instance pointer.\r
267 Controller - Handle of device to stop driver on\r
268 NumberOfChildren - Number of Children in the ChildHandleBuffer\r
269 ChildHandleBuffer - List of handles for the children we need to stop.\r
270\r
271 Returns:\r
272 EFI_SUCCESS\r
273 EFI_DEVICE_ERROR\r
274 others\r
275\r
4d1fe68e 276--*/\r
878ddf1f 277{\r
278 EFI_STATUS Status;\r
279 USB_FLOPPY_DEV *UsbFloppyDevice;\r
280 EFI_BLOCK_IO_PROTOCOL *BlkIo;\r
281\r
282 //\r
283 // First find USB_FLOPPY_DEV\r
284 //\r
285 gBS->OpenProtocol (\r
286 Controller,\r
287 &gEfiBlockIoProtocolGuid,\r
288 (VOID **) &BlkIo,\r
289 This->DriverBindingHandle,\r
290 Controller,\r
291 EFI_OPEN_PROTOCOL_GET_PROTOCOL\r
292 );\r
293\r
294 UsbFloppyDevice = USB_FLOPPY_DEV_FROM_THIS (BlkIo);\r
295\r
296 //\r
297 // Uninstall Block I/O protocol from the device handle\r
298 //\r
299 Status = gBS->UninstallProtocolInterface (\r
300 Controller,\r
301 &gEfiBlockIoProtocolGuid,\r
302 &UsbFloppyDevice->BlkIo\r
303 );\r
304 if (EFI_ERROR (Status)) {\r
305 return Status;\r
306 }\r
307 //\r
308 // Stop using EFI_USB_ATAPI_PROTOCOL\r
309 //\r
310 gBS->CloseProtocol (\r
311 Controller,\r
312 &gEfiUsbAtapiProtocolGuid,\r
313 This->DriverBindingHandle,\r
314 Controller\r
315 );\r
316\r
317 if (UsbFloppyDevice->SenseData != NULL) {\r
318 gBS->FreePool (UsbFloppyDevice->SenseData);\r
319 }\r
320\r
321 gBS->FreePool (UsbFloppyDevice);\r
322\r
323 return EFI_SUCCESS;\r
324}\r
325\r
326\r
327STATIC\r
328EFI_STATUS\r
329EFIAPI\r
330USBFloppyReset (\r
331 IN EFI_BLOCK_IO_PROTOCOL *This,\r
332 IN BOOLEAN ExtendedVerification\r
333 )\r
334/*++\r
335\r
336 Routine Description:\r
337 Implements EFI_BLOCK_IO_PROTOCOL.Reset() function.\r
4d1fe68e 338\r
878ddf1f 339 Arguments:\r
340 This The EFI_BLOCK_IO_PROTOCOL instance.\r
341 ExtendedVerification\r
342 Indicates that the driver may perform a more exhaustive\r
343 verification operation of the device during reset.\r
344 (This parameter is ingored in this driver.)\r
4d1fe68e 345\r
346 Returns:\r
878ddf1f 347 EFI_SUCCESS - Success\r
4d1fe68e 348--*/\r
878ddf1f 349{\r
350 USB_FLOPPY_DEV *UsbFloppyDevice;\r
351 EFI_USB_ATAPI_PROTOCOL *UsbAtapiInterface;\r
352 EFI_STATUS Status;\r
353\r
354 UsbFloppyDevice = USB_FLOPPY_DEV_FROM_THIS (This);\r
355\r
356 UsbAtapiInterface = UsbFloppyDevice->AtapiProtocol;\r
357\r
358 //\r
359 // directly calling EFI_USB_ATAPI_PROTOCOL.Reset() to implement reset.\r
360 //\r
4d1fe68e 361 Status = UsbAtapiInterface->UsbAtapiReset (UsbAtapiInterface, ExtendedVerification);\r
878ddf1f 362\r
363 return Status;\r
364}\r
365\r
366STATIC\r
367EFI_STATUS\r
368EFIAPI\r
369USBFloppyReadBlocks (\r
370 IN EFI_BLOCK_IO_PROTOCOL *This,\r
371 IN UINT32 MediaId,\r
372 IN EFI_LBA LBA,\r
373 IN UINTN BufferSize,\r
374 OUT VOID *Buffer\r
375 )\r
376/*++\r
377\r
378 Routine Description:\r
379 Implements EFI_BLOCK_IO_PROTOCOL.ReadBlocks() function.\r
4d1fe68e 380\r
878ddf1f 381 Arguments:\r
382 This The EFI_BLOCK_IO_PROTOCOL instance.\r
383 MediaId The media id that the read request is for.\r
384 LBA The starting logical block address to read from on the device.\r
385 BufferSize\r
4d1fe68e 386 The size of the Buffer in bytes. This must be a multiple of\r
878ddf1f 387 the intrinsic block size of the device.\r
4d1fe68e 388 Buffer A pointer to the destination buffer for the data. The caller\r
878ddf1f 389 is responsible for either having implicit or explicit ownership\r
4d1fe68e 390 of the buffer.\r
391\r
392 Returns:\r
878ddf1f 393 EFI_INVALID_PARAMETER - Parameter is error\r
4d1fe68e 394 EFI_SUCCESS - Success\r
878ddf1f 395 EFI_DEVICE_ERROR - Hardware Error\r
396 EFI_NO_MEDIA - No media\r
397 EFI_MEDIA_CHANGED - Media Change\r
398 EFI_BAD_BUFFER_SIZE - Buffer size is bad\r
4d1fe68e 399 --*/\r
878ddf1f 400{\r
401 USB_FLOPPY_DEV *UsbFloppyDevice;\r
402 EFI_STATUS Status;\r
403 EFI_BLOCK_IO_MEDIA *Media;\r
404 UINTN BlockSize;\r
405 UINTN NumberOfBlocks;\r
406 BOOLEAN MediaChange;\r
878ddf1f 407\r
878ddf1f 408 Status = EFI_SUCCESS;\r
409 MediaChange = FALSE;\r
878ddf1f 410 UsbFloppyDevice = USB_FLOPPY_DEV_FROM_THIS (This);\r
411\r
412 //\r
413 // Check parameters\r
414 //\r
415 if (!Buffer) {\r
416 Status = EFI_INVALID_PARAMETER;\r
417 goto Done;\r
418 }\r
419\r
420 if (BufferSize == 0) {\r
421 Status = EFI_SUCCESS;\r
422 goto Done;\r
423 }\r
424\r
425 UsbFloppyTestUnitReady (UsbFloppyDevice);\r
426\r
427 Status = UsbFloppyDetectMedia (UsbFloppyDevice, &MediaChange);\r
428 if (EFI_ERROR (Status)) {\r
429\r
430 Status = EFI_DEVICE_ERROR;\r
431 goto Done;\r
432 }\r
433\r
434 if (MediaChange) {\r
878ddf1f 435 gBS->ReinstallProtocolInterface (\r
436 UsbFloppyDevice->Handle,\r
437 &gEfiBlockIoProtocolGuid,\r
438 &UsbFloppyDevice->BlkIo,\r
439 &UsbFloppyDevice->BlkIo\r
440 );\r
878ddf1f 441 }\r
442\r
443 Media = UsbFloppyDevice->BlkIo.Media;\r
444 BlockSize = Media->BlockSize;\r
445 NumberOfBlocks = BufferSize / BlockSize;\r
446\r
447 if (!(Media->MediaPresent)) {\r
448 Status = EFI_NO_MEDIA;\r
449 goto Done;\r
450 }\r
451\r
452 if (MediaId != Media->MediaId) {\r
453 Status = EFI_MEDIA_CHANGED;\r
454 goto Done;\r
455 }\r
456\r
457 if (BufferSize % BlockSize != 0) {\r
458 Status = EFI_BAD_BUFFER_SIZE;\r
459 goto Done;\r
460 }\r
461\r
462 if (LBA > Media->LastBlock) {\r
463 Status = EFI_INVALID_PARAMETER;\r
464 goto Done;\r
465 }\r
466\r
467 if ((LBA + NumberOfBlocks - 1) > Media->LastBlock) {\r
468 Status = EFI_INVALID_PARAMETER;\r
469 goto Done;\r
470 }\r
471\r
472 if ((Media->IoAlign > 1) && (((UINTN) Buffer & (Media->IoAlign - 1)) != 0)) {\r
473 Status = EFI_INVALID_PARAMETER;\r
474 goto Done;\r
475 }\r
476\r
4d1fe68e 477 while (NumberOfBlocks > 0) {\r
878ddf1f 478\r
4d1fe68e 479 if (NumberOfBlocks > BLOCK_UNIT) {\r
480 Status = USBFloppyRead10 (UsbFloppyDevice, Buffer, LBA, BLOCK_UNIT);\r
481 } else {\r
482 Status = USBFloppyRead10 (UsbFloppyDevice, Buffer, LBA, NumberOfBlocks);\r
878ddf1f 483 }\r
484\r
878ddf1f 485 if (EFI_ERROR (Status)) {\r
486 This->Reset (This, TRUE);\r
487 Status = EFI_DEVICE_ERROR;\r
488 }\r
878ddf1f 489\r
4d1fe68e 490 if (NumberOfBlocks > BLOCK_UNIT) {\r
491 NumberOfBlocks -= BLOCK_UNIT;\r
492 LBA += BLOCK_UNIT;\r
493 Buffer = (UINT8 *) Buffer + This->Media->BlockSize * BLOCK_UNIT;\r
494 } else {\r
495 NumberOfBlocks -= NumberOfBlocks;\r
496 LBA += NumberOfBlocks;\r
497 Buffer = (UINT8 *) Buffer + This->Media->BlockSize * NumberOfBlocks;\r
498 }\r
499 }\r
500\r
501 Done:\r
878ddf1f 502 return Status;\r
503}\r
504\r
505STATIC\r
506EFI_STATUS\r
507EFIAPI\r
508USBFloppyWriteBlocks (\r
509 IN EFI_BLOCK_IO_PROTOCOL *This,\r
510 IN UINT32 MediaId,\r
511 IN EFI_LBA LBA,\r
512 IN UINTN BufferSize,\r
513 IN VOID *Buffer\r
514 )\r
515/*++\r
516\r
517 Routine Description:\r
518 Implements EFI_BLOCK_IO_PROTOCOL.WriteBlocks() function.\r
4d1fe68e 519\r
878ddf1f 520 Arguments:\r
521 This The EFI_BLOCK_IO_PROTOCOL instance.\r
522 MediaId The media id that the write request is for.\r
523 LBA The starting logical block address to be written.\r
4d1fe68e 524 The caller is responsible for writing to only\r
878ddf1f 525 legitimate locations.\r
526 BufferSize\r
4d1fe68e 527 The size of the Buffer in bytes. This must be a multiple of\r
878ddf1f 528 the intrinsic block size of the device.\r
4d1fe68e 529 Buffer A pointer to the source buffer for the data. The caller\r
878ddf1f 530 is responsible for either having implicit or explicit ownership\r
4d1fe68e 531 of the buffer.\r
532\r
533 Returns:\r
878ddf1f 534 EFI_INVALID_PARAMETER - Parameter is error\r
4d1fe68e 535 EFI_SUCCESS - Success\r
878ddf1f 536 EFI_DEVICE_ERROR - Hardware Error\r
537 EFI_NO_MEDIA - No media\r
538 EFI_MEDIA_CHANGED - Media Change\r
539 EFI_BAD_BUFFER_SIZE - Buffer size is bad\r
540\r
4d1fe68e 541--*/\r
878ddf1f 542{\r
543 USB_FLOPPY_DEV *UsbFloppyDevice;\r
544 EFI_STATUS Status;\r
545 EFI_BLOCK_IO_MEDIA *Media;\r
546 UINTN BlockSize;\r
547 UINTN NumberOfBlocks;\r
548 BOOLEAN MediaChange;\r
878ddf1f 549\r
878ddf1f 550 Status = EFI_SUCCESS;\r
551 MediaChange = FALSE;\r
878ddf1f 552\r
553 UsbFloppyDevice = USB_FLOPPY_DEV_FROM_THIS (This);\r
554\r
555 //\r
556 // Check parameters\r
557 //\r
558 if (!Buffer) {\r
559 Status = EFI_INVALID_PARAMETER;\r
560 goto Done;\r
561 }\r
562\r
563 if (BufferSize == 0) {\r
564 Status = EFI_SUCCESS;\r
565 goto Done;\r
566 }\r
567\r
568 UsbFloppyTestUnitReady (UsbFloppyDevice);\r
569\r
570 Status = UsbFloppyDetectMedia (UsbFloppyDevice, &MediaChange);\r
571 if (EFI_ERROR (Status)) {\r
572\r
573 Status = EFI_DEVICE_ERROR;\r
574 goto Done;\r
575 }\r
576\r
577 if (MediaChange) {\r
878ddf1f 578 gBS->ReinstallProtocolInterface (\r
579 UsbFloppyDevice->Handle,\r
580 &gEfiBlockIoProtocolGuid,\r
581 &UsbFloppyDevice->BlkIo,\r
582 &UsbFloppyDevice->BlkIo\r
583 );\r
878ddf1f 584 }\r
585\r
586 Media = UsbFloppyDevice->BlkIo.Media;\r
587 BlockSize = Media->BlockSize;\r
588 NumberOfBlocks = BufferSize / BlockSize;\r
589\r
590 if (!(Media->MediaPresent)) {\r
591 Status = EFI_NO_MEDIA;\r
592 goto Done;\r
593 }\r
594\r
595 if (MediaId != Media->MediaId) {\r
596 Status = EFI_MEDIA_CHANGED;\r
597 goto Done;\r
598 }\r
599\r
600 if (BufferSize % BlockSize != 0) {\r
601 Status = EFI_BAD_BUFFER_SIZE;\r
602 goto Done;\r
603 }\r
604\r
605 if (LBA > Media->LastBlock) {\r
606 Status = EFI_INVALID_PARAMETER;\r
607 goto Done;\r
608 }\r
609\r
610 if ((LBA + NumberOfBlocks - 1) > Media->LastBlock) {\r
611 Status = EFI_INVALID_PARAMETER;\r
612 goto Done;\r
613 }\r
614\r
615 if ((Media->IoAlign > 1) && (((UINTN) Buffer & (Media->IoAlign - 1)) != 0)) {\r
616 Status = EFI_INVALID_PARAMETER;\r
617 goto Done;\r
618 }\r
619\r
620 if (UsbFloppyDevice->BlkMedia.ReadOnly) {\r
621 Status = EFI_WRITE_PROTECTED;\r
622 goto Done;\r
623 }\r
624\r
4d1fe68e 625 while (NumberOfBlocks > 0) {\r
878ddf1f 626\r
4d1fe68e 627 if (NumberOfBlocks > BLOCK_UNIT) {\r
628 Status = USBFloppyWrite10 (UsbFloppyDevice, Buffer, LBA, BLOCK_UNIT);\r
629 } else {\r
630 Status = USBFloppyWrite10 (UsbFloppyDevice, Buffer, LBA, NumberOfBlocks);\r
878ddf1f 631 }\r
632\r
878ddf1f 633 if (EFI_ERROR (Status)) {\r
634 This->Reset (This, TRUE);\r
635 Status = EFI_DEVICE_ERROR;\r
636 }\r
4d1fe68e 637\r
638 if (NumberOfBlocks > BLOCK_UNIT) {\r
639 NumberOfBlocks -= BLOCK_UNIT;\r
640 LBA += BLOCK_UNIT;\r
641 Buffer = (UINT8 *) Buffer + This->Media->BlockSize * BLOCK_UNIT;\r
642 } else {\r
643 NumberOfBlocks -= NumberOfBlocks;\r
644 LBA += NumberOfBlocks;\r
645 Buffer = (UINT8 *) Buffer + This->Media->BlockSize * NumberOfBlocks;\r
646 }\r
647 }\r
878ddf1f 648\r
649Done:\r
4d1fe68e 650\r
878ddf1f 651 return Status;\r
652}\r
653\r
654STATIC\r
655EFI_STATUS\r
656EFIAPI\r
657USBFloppyFlushBlocks (\r
658 IN EFI_BLOCK_IO_PROTOCOL *This\r
659 )\r
660/*++\r
661\r
662 Routine Description:\r
663 Implements EFI_BLOCK_IO_PROTOCOL.FlushBlocks() function.\r
664 (In this driver, this function just returns EFI_SUCCESS.)\r
4d1fe68e 665\r
878ddf1f 666 Arguments:\r
667 This The EFI_BLOCK_IO_PROTOCOL instance.\r
4d1fe68e 668\r
669 Returns:\r
878ddf1f 670 EFI_SUCCESS - Success\r
4d1fe68e 671--*/\r
878ddf1f 672{\r
673 return EFI_SUCCESS;\r
674}\r