?lang_form? ?lang_select? ?lang_submit? ?lang_endform?
{HEADER END}
{BLAME START}

library

?curdirlinks? -

Blame information for rev 32

Line No. Rev Author Line
1 32 kaklik /******************************************************************************
2  
3 USB Host Mass Storage Device Driver
4  
5 This is the Mass Storage Class driver file for a USB Embedded Host device.
6 This file should be used in a project with usb_host.c to provided the USB
7 hardware interface.
8  
9 Acronyms/abbreviations used by this class:
10 * LUN - Logical Unit Number
11 * CBW - Command Block Wrapper
12 * CSW - Command Status Wrapper
13  
14 To interface with usb_host.c, the routine USBHostMSDClientInitialize() should be
15 specified as the Initialize() function, and USBHostMSDClientEventHandler() should
16 be specified as the EventHandler() function in the usbClientDrvTable[] array
17 declared in usb_config.h.
18  
19 This driver can be configured to use transfer events from usb_host.c. Transfer
20 events require more RAM and ROM than polling, but it cuts down or even
21 eliminates the required polling of the various USBxxxTasks functions. For this
22 class, USBHostMSDTasks() is compiled out if transfer events from usb_host.c
23 are used. However, USBHostTasks() still must be called to provide attach,
24 enumeration, and detach services. If transfer events from usb_host.c
25 are going to be used, USB_ENABLE_TRANSFER_EVENT should be defined. If transfer
26 status is going to be polled, USB_ENABLE_TRANSFER_EVENT should not be defined.
27  
28 This driver can also be configured to provide mass storage transfer events to
29 the next layer. Generating these events requires a small amount of extra ROM,
30 but no extra RAM. The layer above this driver must be configured to receive
31 and respond to the events. If mass storage transfer events are going to be
32 sent to the next layer, USB_MSD_ENABLE_TRANSFER_EVENT should be defined. If
33 mass storage transfer status is going to be polled,
34 USB_MSD_ENABLE_TRANSFER_EVENT should not be defined.
35  
36 Since mass storage is performed with bulk transfers, USB_SUPPORT_BULK_TRANSFERS
37 must be defined. For maximum throughput, it is recommended that
38 ALLOW_MULTIPLE_BULK_TRANSACTIONS_PER_FRAME be defined. For maximum
39 compatibility with mass storage devices, it is recommended that
40 ALLOW_MULTIPLE_NAKS_PER_FRAME not be defined.
41  
42 FileName: usb_host_msd.c
43 Dependencies: None
44 Processor: PIC24/dsPIC30/dsPIC33/PIC32MX
45 Compiler: C30/C32
46 Company: Microchip Technology, Inc.
47  
48 Software License Agreement
49  
50 The software supplied herewith by Microchip Technology Incorporated
51 (the “Company”) for its PICmicro® Microcontroller is intended and
52 supplied to you, the Company’s customer, for use solely and
53 exclusively on Microchip PICmicro Microcontroller products. The
54 software is owned by the Company and/or its supplier, and is
55 protected under applicable copyright laws. All rights are reserved.
56 Any use in violation of the foregoing restrictions may subject the
57 user to criminal sanctions under applicable laws, as well as to
58 civil liability for the breach of the terms and conditions of this
59 license.
60  
61 THIS SOFTWARE IS PROVIDED IN AN “AS IS” CONDITION. NO WARRANTIES,
62 WHETHER EXPRESS, IMPLIED OR STATUTORY, INCLUDING, BUT NOT LIMITED
63 TO, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
64 PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. THE COMPANY SHALL NOT,
65 IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL OR
66 CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER.
67  
68 Change History:
69 Rev Description
70 ---------- ----------------------------------------------------------
71 2.6 - 2.6a No change
72  
73 2.7 Fixed issue where a transfer event is incorrectly sent when
74 transfer events are enabled.
75  
76 2.7a No change
77  
78 *******************************************************************************/
79  
80  
81 #include <stdlib.h>
82 #include <string.h>
83 #include "Compiler.h"
84 #include "GenericTypeDefs.h"
85 #include "HardwareProfile.h"
86 #include "USB\usb.h"
87 #include "USB\usb_host_msd.h"
88  
89 //#define DEBUG_MODE
90 #ifdef DEBUG_MODE
91 #include "uart2.h"
92 #endif
93  
94  
95 // *****************************************************************************
96 // *****************************************************************************
97 // Section: Configuration
98 // *****************************************************************************
99 // *****************************************************************************
100  
101 // *****************************************************************************
102 /* Max Number of Supported Devices
103  
104 This value represents the maximum number of attached devices this class driver
105 can support. If the user does not define a value, it will be set to 1.
106 Currently this must be set to 1, due to limitations in the USB Host layer.
107 */
108 #ifndef USB_MAX_MASS_STORAGE_DEVICES
109 #define USB_MAX_MASS_STORAGE_DEVICES 1
110 #endif
111  
112 // *****************************************************************************
113 // *****************************************************************************
114 // Section: Constants
115 // *****************************************************************************
116 // *****************************************************************************
117  
118 // *****************************************************************************
119 // Section: State Machine Constants
120 // *****************************************************************************
121  
122 #ifndef USB_ENABLE_TRANSFER_EVENT
123  
124 #define STATE_MASK 0x00F0 //
125 #define SUBSTATE_MASK 0x000F //
126  
127 #define NEXT_STATE 0x0010 //
128 #define NEXT_SUBSTATE 0x0001 //
129  
130  
131 #define STATE_DETACHED 0x0000 //
132  
133 #define STATE_INITIALIZE_DEVICE 0x0010 //
134 #define SUBSTATE_WAIT_FOR_ENUMERATION 0x0000 //
135 #define SUBSTATE_SEND_GET_MAX_LUN 0x0001 //
136 #define SUBSTATE_WAIT_FOR_MAX_LUN 0x0002 //
137 #define SUBSTATE_GET_MAX_LUN_COMPLETE 0x0003 //
138  
139 #define STATE_RUNNING 0x0020 //
140 #define SUBSTATE_HOLDING 0x0000 //
141 #define SUBSTATE_SEND_CBW 0x0001 //
142 #define SUBSTATE_CBW_WAIT 0x0002 //
143 #define SUBSTATE_TRANSFER_DATA 0x0003 //
144 #define SUBSTATE_TRANSFER_WAIT 0x0004 //
145 #define SUBSTATE_REQUEST_CSW 0x0005 //
146 #define SUBSTATE_CSW_WAIT 0x0006 //
147 #define SUBSTATE_TRANSFER_DONE 0x0007 //
148  
149 #define STATE_MSD_RESET_RECOVERY 0x0030 //
150 #define SUBSTATE_SEND_RESET 0x0000 //
151 #define SUBSTATE_WAIT_FOR_RESET 0x0001 //
152 #define SUBSTATE_RESET_COMPLETE 0x0002 //
153  
154 #define STATE_MSD_CLEAR_DATA_IN 0x0040 //
155 #define SUBSTATE_SEND_CLEAR_IN 0x0000 //
156 #define SUBSTATE_WAIT_FOR_CLEAR_IN 0x0001 //
157 #define SUBSTATE_CLEAR_IN_COMPLETE 0x0002 //
158  
159 #define STATE_MSD_CLEAR_DATA_OUT 0x0050 //
160 #define SUBSTATE_SEND_CLEAR_OUT 0x0000 //
161 #define SUBSTATE_WAIT_FOR_CLEAR_OUT 0x0001 //
162 #define SUBSTATE_CLEAR_OUT_COMPLETE 0x0002 //
163  
164 #define STATE_HOLDING 0x0060 // Holding due to an error
165  
166 #else
167  
168 #define STATE_DETACHED 0x0000 //
169  
170 #define STATE_WAIT_FOR_MAX_LUN 0x0001 //
171  
172 #define STATE_RUNNING 0x0002 //
173 #define STATE_CBW_WAIT 0x0003 //
174 #define STATE_TRANSFER_WAIT 0x0004 //
175 #define STATE_CSW_WAIT 0x0005 //
176  
177 #define STATE_WAIT_FOR_RESET 0x0006 //
178 #define STATE_WAIT_FOR_CLEAR_IN 0x0007 //
179 #define STATE_WAIT_FOR_CLEAR_OUT 0x0008 //
180  
181 #define STATE_HOLDING 0x0009 // Holding due to an error
182  
183 #define STATE_REQUEST_CSW 0x000A // Dummy state
184  
185 #endif
186  
187  
188 // *****************************************************************************
189 // Section: Other Constants
190 // *****************************************************************************
191  
192 #define CBW_SIZE 31 // Number of bytes in the CBW.
193 #define CSW_SIZE 13 // Number of bytes in the CSW.
194  
195 #define CSW_RECEIVE_ATTEMPTS 100 // Number of attempts to obtain the CSW.
196  
197 #define USB_MSD_GET_MAX_LUN 0xFE // Device Request code to get the maximum LUN.
198 #define USB_MSD_RESET 0xFF // Device Request code to reset the device.
199 #define USB_MSD_DCBWSIGNATURE 0x43425355ul // Signature value for the CBW.
200 #define USB_MSD_DCSWSIGNATURE 0x53425355ul // Signature value for the CSW.
201  
202 #define MARK_RESET_RECOVERY 0x0E // Maintain with USB_MSD_DEVICE_INFO
203  
204  
205 //******************************************************************************
206 //******************************************************************************
207 // Section: Data Structures
208 //******************************************************************************
209 //******************************************************************************
210  
211 // *****************************************************************************
212 /* USB Mass Storage Device Information
213  
214 This structure is used to hold all the information about an attached Mass Storage device.
215 */
216 typedef struct _USB_MSD_DEVICE_INFO
217 {
218 BYTE blockData[31]; // Data buffer for device communication.
219 BYTE deviceAddress; // Address of the device on the bus.
220 BYTE clientDriverID; // Client driver ID for device requests.
221 BYTE errorCode; // Error code of last error.
222 BYTE state; // State machine state of the device.
223 BYTE returnState; // State to return to after performing error handling.
224 union
225 {
226 struct
227 {
228 BYTE bfDirection : 1; // Direction of current transfer (0=OUT, 1=IN).
229 BYTE bfReset : 1; // Flag indicating to perform Mass Storage Reset.
230 BYTE bfClearDataIN : 1; // Flag indicating to clear the IN endpoint.
231 BYTE bfClearDataOUT : 1; // Flag indicating to clear the OUT endpoint.
232 };
233 BYTE val;
234 } flags;
235 BYTE maxLUN; // The maximum Logical Unit Number of the device.
236 BYTE interface; // Interface number we are using.
237 BYTE endpointIN; // Bulk IN endpoint.
238 BYTE endpointOUT; // Bulk OUT endpoint.
239 BYTE endpointDATA; // Endpoint to use for the current transfer.
240 BYTE *userData; // Pointer to the user's data buffer.
241 DWORD userDataLength; // Length of the user's data buffer.
242 DWORD bytesTransferred; // Number of bytes transferred to/from the user's data buffer.
243 DWORD dCBWTag; // The value of the dCBWTag to verify against the dCSWtag.
244 BYTE attemptsCSW; // Number of attempts to retrieve the CSW.
245 } USB_MSD_DEVICE_INFO;
246  
247  
248 // *****************************************************************************
249 /* Command Block Wrapper
250  
251 This is the structure of the Command Block Wrapper, required at the beginning of
252 each mass storage transfer.
253 */
254 typedef struct _USB_MSD_CBW
255 {
256 DWORD dCBWSignature; // Signature, must be a specific constant.
257 DWORD dCBWTag; // Transaction tag. Value in the CSW must match.
258 DWORD dCBWDataTransferLength; // Length of the following data transfer.
259 union
260 {
261 struct
262 {
263 BYTE : 7;
264 BYTE bfDirection : 1; // Direction of data transfer (0=OUT, 1=IN).
265 };
266 BYTE val;
267 } bmCBWflags;
268 BYTE bCBWLUN; // Logical Unit Number (bits 3:0 only).
269 BYTE bCBWCBLength; // Length of command block (bits 4:0 only).
270 BYTE CBWCB[16]; // Command block.
271 } USB_MSD_CBW;
272  
273  
274 // *****************************************************************************
275 /* Command Status Wrapper
276  
277 This is the structure of the Command Status Wrapper, required at the end of
278 each mass storage transfer.
279 */
280 typedef struct _USB_MSD_CSW
281 {
282 DWORD dCSWSignature; // Signature, must be a specific constant.
283 DWORD dCSWTag; // Transaction tag. Must match the CBW.
284 DWORD dCSWDataResidue; // Count of data bytes not transferred.
285 BYTE dCSWStatus; // Result of requested operation.
286 } USB_MSD_CSW;
287  
288  
289 //******************************************************************************
290 //******************************************************************************
291 // Section: Local Prototypes
292 //******************************************************************************
293 //******************************************************************************
294  
295 DWORD _USBHostMSD_GetNextTag( void );
296 void _USBHostMSD_ResetStateJump( BYTE i );
297  
298  
299 //******************************************************************************
300 //******************************************************************************
301 // Section: Macros
302 //******************************************************************************
303 //******************************************************************************
304  
305 #ifndef USB_ENABLE_TRANSFER_EVENT
306 #define _USBHostMSD_SetNextState() { deviceInfoMSD[i].state = (deviceInfoMSD[i].state & STATE_MASK) + NEXT_STATE; }
307 #define _USBHostMSD_SetNextSubState() { deviceInfoMSD[i].state += NEXT_SUBSTATE; }
308 #define _USBHostMSD_TerminateTransfer( error ) { \
309 deviceInfoMSD[i].errorCode = error; \
310 deviceInfoMSD[i].state = STATE_RUNNING | SUBSTATE_TRANSFER_DONE; \
311 }
312 #else
313 #ifdef USB_MSD_ENABLE_TRANSFER_EVENT
314 #define _USBHostMSD_TerminateTransfer( error ) { \
315 deviceInfoMSD[i].errorCode = error; \
316 deviceInfoMSD[i].state = STATE_RUNNING; \
317 usbMediaInterfaceTable.EventHandler( deviceInfoMSD[i].deviceAddress, EVENT_MSD_TRANSFER, NULL, 0 ); \
318 }
319 #else
320 #define _USBHostMSD_TerminateTransfer( error ) { \
321 deviceInfoMSD[i].errorCode = error; \
322 deviceInfoMSD[i].state = STATE_RUNNING; \
323 }
324 #endif
325 #endif
326  
327  
328 //******************************************************************************
329 //******************************************************************************
330 // Section: MSD Host External Variables
331 //******************************************************************************
332 //******************************************************************************
333  
334 extern CLIENT_DRIVER_TABLE usbMediaInterfaceTable; // This table contains the initialization
335 // routine and event handler for the media
336 // interface layer of the application.
337 // It is defined in USBConfig.c.
338  
339 //******************************************************************************
340 //******************************************************************************
341 // Section: MSD Host Global Variables
342 //******************************************************************************
343 //******************************************************************************
344  
345 static DWORD dCBWTagNext = 0x12345678ul;
346 static USB_MSD_DEVICE_INFO deviceInfoMSD[USB_MAX_MASS_STORAGE_DEVICES] __attribute__ ((aligned));
347  
348  
349 // *****************************************************************************
350 // *****************************************************************************
351 // Section: Application Callable Functions
352 // *****************************************************************************
353 // *****************************************************************************
354  
355 /****************************************************************************
356 Function:
357 BYTE USBHostMSDDeviceStatus( BYTE deviceAddress )
358  
359 Description:
360 This function determines the status of a mass storage device.
361  
362 Precondition:
363 None
364  
365 Parameters:
366 BYTE deviceAddress - address of device to query
367  
368 Return Values:
369 USB_MSD_DEVICE_NOT_FOUND - Illegal device address, or the device is not
370 an MSD
371 USB_MSD_INITIALIZING - MSD is attached and in the process of
372 initializing
373 USB_MSD_NORMAL_RUNNING - MSD is in normal running mode
374 USB_MSD_RESETTING_DEVICE - MSD is resetting
375 USB_MSD_DEVICE_DETACHED - MSD detached. Should not occur
376 USB_MSD_ERROR_STATE - MSD is holding due to an error. No
377 communication is allowed.
378  
379 Other - Return codes from USBHostDeviceStatus() will
380 also be returned if the device is in the
381 process of enumerating.
382  
383 Remarks:
384 None
385 ***************************************************************************/
386  
387 BYTE USBHostMSDDeviceStatus( BYTE deviceAddress )
388 {
389 BYTE i;
390 BYTE status;
391  
392 // Make sure a valid device is being requested.
393 if ((deviceAddress == 0) || (deviceAddress > 127))
394 {
395 return USB_MSD_DEVICE_NOT_FOUND;
396 }
397  
398 // Find the correct device.
399 for (i=0; (i<USB_MAX_MASS_STORAGE_DEVICES) && (deviceInfoMSD[i].deviceAddress != deviceAddress); i++);
400 if (i == USB_MAX_MASS_STORAGE_DEVICES)
401 {
402 return USB_MSD_DEVICE_NOT_FOUND;
403 }
404  
405 status = USBHostDeviceStatus( deviceAddress );
406 if (status != USB_DEVICE_ATTACHED)
407 {
408 return status;
409 }
410 else
411 {
412 // The device is attached and done enumerating. We can get more specific now.
413  
414 #ifndef USB_ENABLE_TRANSFER_EVENT
415 switch (deviceInfoMSD[i].state & STATE_MASK)
416 {
417 case STATE_INITIALIZE_DEVICE:
418 return USB_MSD_INITIALIZING;
419 break;
420  
421 case STATE_RUNNING:
422 return USB_MSD_NORMAL_RUNNING;
423 break;
424  
425 case STATE_HOLDING:
426 return USB_MSD_ERROR_STATE;
427 break;
428  
429 case STATE_MSD_RESET_RECOVERY:
430 case STATE_MSD_CLEAR_DATA_IN:
431 case STATE_MSD_CLEAR_DATA_OUT:
432 return USB_MSD_RESETTING_DEVICE;
433 break;
434  
435 default:
436 return USB_MSD_DEVICE_DETACHED;
437 break;
438 }
439 #else
440 switch (deviceInfoMSD[i].state)
441 {
442 case STATE_WAIT_FOR_MAX_LUN:
443 return USB_MSD_INITIALIZING;
444 break;
445  
446 case STATE_RUNNING:
447 case STATE_CBW_WAIT:
448 case STATE_TRANSFER_WAIT:
449 case STATE_CSW_WAIT:
450 case STATE_REQUEST_CSW:
451 return USB_MSD_NORMAL_RUNNING;
452 break;
453  
454 case STATE_HOLDING:
455 return USB_MSD_ERROR_STATE;
456 break;
457  
458 case STATE_WAIT_FOR_RESET:
459 case STATE_WAIT_FOR_CLEAR_IN:
460 case STATE_WAIT_FOR_CLEAR_OUT:
461 return USB_MSD_RESETTING_DEVICE;
462 break;
463  
464 default:
465 return USB_MSD_DEVICE_DETACHED;
466 break;
467 }
468 #endif
469 }
470 }
471  
472  
473 /****************************************************************************
474 Function:
475 BYTE USBHostMSDResetDevice( BYTE deviceAddress )
476  
477 Summary:
478 This function starts a bulk-only mass storage reset.
479  
480 Description:
481 This function starts a bulk-only mass storage reset. A reset can be
482 issued only if the device is attached and not being initialized.
483  
484 Precondition:
485 None
486  
487 Parameters:
488 BYTE deviceAddress - Device address
489  
490 Return Values:
491 USB_SUCCESS - Reset started
492 USB_MSD_DEVICE_NOT_FOUND - No device with specified address
493 USB_MSD_ILLEGAL_REQUEST - Device is in an illegal state for reset
494  
495 Remarks:
496 None
497 ***************************************************************************/
498  
499 BYTE USBHostMSDResetDevice( BYTE deviceAddress )
500 {
501 BYTE i;
502  
503 // Make sure a valid device is being requested.
504 if ((deviceAddress == 0) || (deviceAddress > 127))
505 {
506 return USB_MSD_DEVICE_NOT_FOUND;
507 }
508  
509 // Find the correct device.
510 for (i=0; (i<USB_MAX_MASS_STORAGE_DEVICES) && (deviceInfoMSD[i].deviceAddress != deviceAddress); i++);
511 if (i == USB_MAX_MASS_STORAGE_DEVICES)
512 {
513 return USB_MSD_DEVICE_NOT_FOUND;
514 }
515  
516 #ifndef USB_ENABLE_TRANSFER_EVENT
517 if (((deviceInfoMSD[i].state & STATE_MASK) != STATE_DETACHED) &&
518 ((deviceInfoMSD[i].state & STATE_MASK) != STATE_INITIALIZE_DEVICE))
519 #else
520 if ((deviceInfoMSD[i].state == STATE_RUNNING) ||
521 (deviceInfoMSD[i].state == STATE_HOLDING ))
522 #endif
523 {
524 deviceInfoMSD[i].flags.val |= MARK_RESET_RECOVERY;
525 #ifndef USB_ENABLE_TRANSFER_EVENT
526 deviceInfoMSD[i].returnState = STATE_RUNNING | SUBSTATE_HOLDING;
527 #else
528 deviceInfoMSD[i].returnState = STATE_RUNNING;
529 #endif
530 _USBHostMSD_ResetStateJump( i );
531 return USB_SUCCESS;
532 }
533 return USB_MSD_ILLEGAL_REQUEST;
534 }
535  
536  
537 /****************************************************************************
538 Function:
539 void USBHostMSDTasks( void )
540  
541 Summary:
542 This function performs the maintenance tasks required by the mass storage
543 class.
544  
545 Description:
546 This function performs the maintenance tasks required by the mass storage
547 class. If transfer events from the host layer are not being used, then
548 it should be called on a regular basis by the application. If transfer
549 events from the host layer are being used, this function is compiled out,
550 and does not need to be called.
551  
552 Precondition:
553 USBHostMSDInitialize() has been called.
554  
555 Parameters:
556 None - None
557  
558 Returns:
559 None
560  
561 Remarks:
562 None
563 ***************************************************************************/
564  
565 void USBHostMSDTasks( void )
566 {
567  
568 #ifndef USB_ENABLE_TRANSFER_EVENT
569  
570 DWORD byteCount;
571 BYTE errorCode;
572 BYTE i;
573  
574 for (i=0; i<USB_MAX_MASS_STORAGE_DEVICES; i++)
575 {
576 if (deviceInfoMSD[i].deviceAddress != 0)
577 {
578 switch (deviceInfoMSD[i].state & STATE_MASK)
579 {
580 case STATE_DETACHED:
581 // No device attached.
582 break;
583  
584 case STATE_INITIALIZE_DEVICE:
585 switch (deviceInfoMSD[i].state & SUBSTATE_MASK)
586 {
587 case SUBSTATE_WAIT_FOR_ENUMERATION:
588 if (USBHostDeviceStatus( deviceInfoMSD[i].deviceAddress ) == USB_DEVICE_ATTACHED)
589 {
590 _USBHostMSD_SetNextSubState();
591 #ifdef DEBUG_MODE
592 UART2PrintString( "MSD: Getting max LUN...\r\n" );
593 #endif
594 }
595 break;
596  
597 case SUBSTATE_SEND_GET_MAX_LUN:
598 // If we are currently sending a token, we cannot do anything.
599 if (U1CONbits.TOKBUSY)
600 break;
601  
602 if (!USBHostIssueDeviceRequest( deviceInfoMSD[i].deviceAddress, USB_SETUP_DEVICE_TO_HOST | USB_SETUP_TYPE_CLASS | USB_SETUP_RECIPIENT_INTERFACE,
603 USB_MSD_GET_MAX_LUN, 0, deviceInfoMSD[i].interface, 1, deviceInfoMSD[i].blockData, USB_DEVICE_REQUEST_GET, deviceInfoMSD[i].clientDriverID ))
604 {
605 _USBHostMSD_SetNextSubState();
606 }
607 else
608 {
609 // We'll try again.
610 }
611 break;
612  
613 case SUBSTATE_WAIT_FOR_MAX_LUN:
614 if (USBHostTransferIsComplete( deviceInfoMSD[i].deviceAddress, 0, &errorCode, &byteCount ))
615 {
616 deviceInfoMSD[i].maxLUN = 0;
617 if (!errorCode)
618 {
619 deviceInfoMSD[i].maxLUN = deviceInfoMSD[i].blockData[0];
620 }
621 else
622 {
623 // Clear the STALL. Since it is EP0, we do not have to clear the stall.
624 USBHostClearEndpointErrors( deviceInfoMSD[i].deviceAddress, 0 );
625 }
626 _USBHostMSD_SetNextSubState();
627 }
628 break;
629  
630 case SUBSTATE_GET_MAX_LUN_COMPLETE:
631 #ifdef DEBUG_MODE
632 UART2PrintString( "MSD: Max LUN is " );
633 UART2PutHex( deviceInfoMSD[i].maxLUN );
634 UART2PrintString( "\r\nMSD: Running...\r\n" );
635 #endif
636  
637 // Tell the media interface layer that we have a MSD attached.
638 if (usbMediaInterfaceTable.Initialize( deviceInfoMSD[i].deviceAddress, usbMediaInterfaceTable.flags, 0 ))
639 {
640 usbMediaInterfaceTable.EventHandler( deviceInfoMSD[i].deviceAddress, EVENT_MSD_MAX_LUN, &(deviceInfoMSD[i].maxLUN), 1 );
641 _USBHostMSD_SetNextState();
642 }
643 else
644 {
645 // The media interface layer cannot support the device.
646 deviceInfoMSD[i].errorCode = USB_MSD_MEDIA_INTERFACE_ERROR;
647 deviceInfoMSD[i].state = STATE_HOLDING;
648 }
649 break;
650 }
651 break;
652  
653 case STATE_RUNNING:
654 switch (deviceInfoMSD[i].state & SUBSTATE_MASK)
655 {
656 case SUBSTATE_HOLDING:
657 break;
658  
659 case SUBSTATE_SEND_CBW:
660 #ifdef DEBUG_MODE
661 UART2PrintString( "MSD: Writing CBW\r\n" );
662 #endif
663 errorCode = USBHostWrite( deviceInfoMSD[i].deviceAddress, deviceInfoMSD[i].endpointOUT, deviceInfoMSD[i].blockData, CBW_SIZE );
664 if (errorCode)
665 {
666 _USBHostMSD_TerminateTransfer( errorCode );
667 }
668 else
669 {
670 _USBHostMSD_SetNextSubState();
671 }
672 break;
673  
674 case SUBSTATE_CBW_WAIT:
675 if (USBHostTransferIsComplete( deviceInfoMSD[i].deviceAddress, deviceInfoMSD[i].endpointOUT, &errorCode, &byteCount ))
676 {
677 if (errorCode)
678 {
679 #ifdef DEBUG_MODE
680 UART2PrintString( "MSD: Error with sending CBW\r\n" );
681 #endif
682 _USBHostMSD_TerminateTransfer( errorCode );
683 }
684 else if (byteCount != CBW_SIZE)
685 {
686 #ifdef DEBUG_MODE
687 UART2PrintString( "MSD: CBW size not correct\r\n" );
688 #endif
689 _USBHostMSD_TerminateTransfer( USB_MSD_CBW_ERROR );
690 }
691 else
692 {
693 if (((USB_MSD_CBW *)(deviceInfoMSD[i].blockData))->dCBWDataTransferLength == 0)
694 {
695 #ifdef DEBUG_MODE
696 UART2PrintString( "MSD: Transfer length=0\r\n" );
697 #endif
698 // Skip to get the CSW
699 deviceInfoMSD[i].state = STATE_RUNNING | SUBSTATE_REQUEST_CSW;
700 }
701 else
702 {
703 #ifdef DEBUG_MODE
704 UART2PrintString( "MSD: Going on...\r\n" );
705 #endif
706 _USBHostMSD_SetNextSubState();
707 }
708 }
709 }
710 break;
711  
712 case SUBSTATE_TRANSFER_DATA:
713 #ifdef DEBUG_MODE
714 UART2PrintString( "MSD: Transferring data, length ");
715 UART2PutHexDWord( deviceInfoMSD[i].userDataLength );
716 UART2PrintString( "\r\n" );
717 #endif
718 if (deviceInfoMSD[i].userDataLength == 0)
719 {
720 deviceInfoMSD[i].state = STATE_RUNNING | SUBSTATE_REQUEST_CSW;
721 }
722 else
723 {
724 if (!deviceInfoMSD[i].flags.bfDirection) // OUT
725 {
726 errorCode = USBHostWrite( deviceInfoMSD[i].deviceAddress, deviceInfoMSD[i].endpointDATA, deviceInfoMSD[i].userData, deviceInfoMSD[i].userDataLength );
727 }
728 else
729 {
730 errorCode = USBHostRead( deviceInfoMSD[i].deviceAddress, deviceInfoMSD[i].endpointDATA, deviceInfoMSD[i].userData, deviceInfoMSD[i].userDataLength );
731 }
732  
733 if (errorCode)
734 {
735 _USBHostMSD_TerminateTransfer( errorCode );
736 }
737 else
738 {
739 _USBHostMSD_SetNextSubState();
740 }
741 }
742 break;
743  
744 case SUBSTATE_TRANSFER_WAIT:
745 if (USBHostTransferIsComplete( deviceInfoMSD[i].deviceAddress, deviceInfoMSD[i].endpointDATA, &errorCode, &byteCount ))
746 {
747 if (errorCode)
748 {
749 if (errorCode == USB_ENDPOINT_STALLED)
750 {
751 // Clear the stall, then try to get the CSW.
752 #ifdef DEBUG_MODE
753 UART2PrintString( "MSD: Stall on data\r\n" );
754 #endif
755 USBHostClearEndpointErrors( deviceInfoMSD[i].deviceAddress, deviceInfoMSD[i].endpointDATA );
756 if (!deviceInfoMSD[i].flags.bfDirection) // OUT
757 {
758 deviceInfoMSD[i].flags.bfClearDataOUT = 1;
759 }
760 else
761 {
762 deviceInfoMSD[i].flags.bfClearDataIN = 1;
763 }
764 deviceInfoMSD[i].returnState = STATE_RUNNING | SUBSTATE_REQUEST_CSW;
765 _USBHostMSD_ResetStateJump( i );
766  
767 }
768 else
769 {
770 //Error recovery here is not explicitly covered in the spec. Unfortunately, some
771 // thumb drives generate a turn-around time error here sometimes.
772 //_USBHostMSD_TerminateTransfer( errorCode );
773 deviceInfoMSD[i].flags.val |= MARK_RESET_RECOVERY;
774 deviceInfoMSD[i].returnState = STATE_RUNNING | SUBSTATE_SEND_CBW; // Try the transfer again.
775 _USBHostMSD_ResetStateJump( i );
776 }
777 }
778 else
779 {
780 _USBHostMSD_SetNextSubState();
781 }
782 }
783 break;
784  
785 case SUBSTATE_REQUEST_CSW:
786 #ifdef DEBUG_MODE
787 UART2PrintString( "MSD: Getting CSW\r\n" );
788 #endif
789  
790 errorCode = USBHostRead( deviceInfoMSD[i].deviceAddress, deviceInfoMSD[i].endpointIN, deviceInfoMSD[i].blockData, CSW_SIZE );
791 if (errorCode)
792 {
793 _USBHostMSD_TerminateTransfer( errorCode );
794 }
795 else
796 {
797 _USBHostMSD_SetNextSubState();
798 }
799 break;
800  
801 case SUBSTATE_CSW_WAIT:
802 if (USBHostTransferIsComplete( deviceInfoMSD[i].deviceAddress, deviceInfoMSD[i].endpointIN, &errorCode, &byteCount ))
803 {
804 #ifdef DEBUG_MODE
805 UART2PrintString( "MSD: Got CSW-" );
806 #endif
807 if (errorCode)
808 {
809 deviceInfoMSD[i].attemptsCSW--;
810 if (deviceInfoMSD[i].attemptsCSW)
811 {
812 USBHostClearEndpointErrors( deviceInfoMSD[i].deviceAddress, deviceInfoMSD[i].endpointIN );
813 deviceInfoMSD[i].flags.bfClearDataIN = 1;
814 deviceInfoMSD[i].returnState = STATE_RUNNING | SUBSTATE_REQUEST_CSW;
815 _USBHostMSD_ResetStateJump( i );
816 }
817 else
818 {
819 _USBHostMSD_TerminateTransfer( errorCode );
820 }
821 }
822 else if ((byteCount != CSW_SIZE) |
823 (((USB_MSD_CSW *)(deviceInfoMSD[i].blockData))->dCSWSignature != USB_MSD_DCSWSIGNATURE) |
824 (((USB_MSD_CSW *)(deviceInfoMSD[i].blockData))->dCSWTag != deviceInfoMSD[i].dCBWTag) )
825 {
826 _USBHostMSD_TerminateTransfer( USB_MSD_CSW_ERROR );
827 }
828 else
829 {
830 deviceInfoMSD[i].bytesTransferred = deviceInfoMSD[i].userDataLength - ((USB_MSD_CSW *)(deviceInfoMSD[i].blockData))->dCSWDataResidue;
831  
832 if (((USB_MSD_CSW *)(deviceInfoMSD[i].blockData))->dCSWStatus != 0x00)
833 {
834 _USBHostMSD_TerminateTransfer( ((USB_MSD_CSW *)(deviceInfoMSD[i].blockData))->dCSWStatus | USB_MSD_ERROR );
835 }
836 else
837 {
838 _USBHostMSD_TerminateTransfer( USB_SUCCESS );
839 }
840  
841 // If we have a phase error, we need to perform corrective action instead of
842 // returning to normal running.
843 if (((USB_MSD_CSW *)(deviceInfoMSD[i].blockData))->dCSWStatus == MSD_PHASE_ERROR)
844 {
845 deviceInfoMSD[i].flags.val |= MARK_RESET_RECOVERY;
846 deviceInfoMSD[i].returnState = STATE_RUNNING | SUBSTATE_HOLDING;
847 _USBHostMSD_ResetStateJump( i );
848 }
849 }
850 }
851 break;
852  
853 case SUBSTATE_TRANSFER_DONE:
854 deviceInfoMSD[i].state = STATE_RUNNING | SUBSTATE_HOLDING;
855 #ifdef USB_MSD_ENABLE_TRANSFER_EVENT
856 usbMediaInterfaceTable.EventHandler( deviceInfoMSD[i].deviceAddress, EVENT_MSD_TRANSFER, NULL, 0 );
857 #endif
858 break;
859 }
860 break;
861  
862 case STATE_MSD_RESET_RECOVERY:
863 switch (deviceInfoMSD[i].state & SUBSTATE_MASK)
864 {
865 case SUBSTATE_SEND_RESET:
866 errorCode = USBHostIssueDeviceRequest( deviceInfoMSD[i].deviceAddress, USB_SETUP_HOST_TO_DEVICE | USB_SETUP_TYPE_CLASS | USB_SETUP_RECIPIENT_INTERFACE,
867 USB_MSD_RESET, 0, deviceInfoMSD[i].interface, 0, NULL, USB_DEVICE_REQUEST_SET, deviceInfoMSD[i].clientDriverID );
868  
869 if (errorCode)
870 {
871 //Error recovery here is not explicitly covered in the spec.
872 _USBHostMSD_TerminateTransfer( USB_MSD_RESET_ERROR );
873 }
874 else
875 {
876 _USBHostMSD_SetNextSubState();
877 }
878 break;
879  
880 case SUBSTATE_WAIT_FOR_RESET:
881 if (USBHostTransferIsComplete( deviceInfoMSD[i].deviceAddress, 0, &errorCode, &byteCount ))
882 {
883 if (errorCode)
884 {
885 //Error recovery here is not explicitly covered in the spec.
886 _USBHostMSD_TerminateTransfer( USB_MSD_RESET_ERROR );
887 }
888 else
889 {
890 deviceInfoMSD[i].flags.bfReset = 0;
891 _USBHostMSD_SetNextSubState();
892 }
893 }
894 break;
895  
896 case SUBSTATE_RESET_COMPLETE:
897 _USBHostMSD_ResetStateJump( i );
898 break;
899 }
900 break;
901  
902 case STATE_MSD_CLEAR_DATA_IN:
903 switch (deviceInfoMSD[i].state & SUBSTATE_MASK)
904 {
905 case SUBSTATE_SEND_CLEAR_IN:
906 errorCode = USBHostIssueDeviceRequest( deviceInfoMSD[i].deviceAddress, USB_SETUP_HOST_TO_DEVICE | USB_SETUP_TYPE_STANDARD | USB_SETUP_RECIPIENT_ENDPOINT,
907 USB_REQUEST_CLEAR_FEATURE, USB_FEATURE_ENDPOINT_HALT, deviceInfoMSD[i].endpointIN, 0, NULL, USB_DEVICE_REQUEST_SET, deviceInfoMSD[i].clientDriverID );
908  
909 if (errorCode)
910 {
911 //Error recovery here is not explicitly covered in the spec.
912 _USBHostMSD_TerminateTransfer( USB_MSD_RESET_ERROR );
913 }
914 else
915 {
916 _USBHostMSD_SetNextSubState();
917 }
918 break;
919  
920 case SUBSTATE_WAIT_FOR_CLEAR_IN:
921 if (USBHostTransferIsComplete( deviceInfoMSD[i].deviceAddress, 0, &errorCode, &byteCount ))
922 {
923 if (errorCode)
924 {
925 //Error recovery here is not explicitly covered in the spec.
926 _USBHostMSD_TerminateTransfer( USB_MSD_RESET_ERROR );
927 }
928 else
929 {
930 deviceInfoMSD[i].flags.bfClearDataIN = 0;
931 _USBHostMSD_SetNextSubState();
932 }
933 }
934 break;
935  
936 case SUBSTATE_CLEAR_IN_COMPLETE:
937 _USBHostMSD_ResetStateJump( i );
938 break;
939 }
940 break;
941  
942 case STATE_MSD_CLEAR_DATA_OUT:
943 switch (deviceInfoMSD[i].state & SUBSTATE_MASK)
944 {
945 case SUBSTATE_SEND_CLEAR_OUT:
946 errorCode = USBHostIssueDeviceRequest( deviceInfoMSD[i].deviceAddress, USB_SETUP_HOST_TO_DEVICE | USB_SETUP_TYPE_STANDARD | USB_SETUP_RECIPIENT_ENDPOINT,
947 USB_REQUEST_CLEAR_FEATURE, USB_FEATURE_ENDPOINT_HALT, deviceInfoMSD[i].endpointOUT, 0, NULL, USB_DEVICE_REQUEST_SET, deviceInfoMSD[i].clientDriverID );
948  
949 if (errorCode)
950 {
951 //Error recovery here is not explicitly covered in the spec.
952 _USBHostMSD_TerminateTransfer( USB_MSD_RESET_ERROR );
953 }
954 else
955 {
956 _USBHostMSD_SetNextSubState();
957 }
958 break;
959  
960 case SUBSTATE_WAIT_FOR_CLEAR_OUT:
961 if (USBHostTransferIsComplete( deviceInfoMSD[i].deviceAddress, 0, &errorCode, &byteCount ))
962 {
963 if (errorCode)
964 {
965 //Error recovery here is not explicitly covered in the spec.
966 _USBHostMSD_TerminateTransfer( USB_MSD_RESET_ERROR );
967 }
968 else
969 {
970 deviceInfoMSD[i].flags.bfClearDataOUT = 0;
971 _USBHostMSD_SetNextSubState();
972 }
973 }
974 break;
975  
976 case SUBSTATE_CLEAR_OUT_COMPLETE:
977 _USBHostMSD_ResetStateJump( i );
978 break;
979 }
980 break;
981  
982 case STATE_HOLDING:
983 break;
984 }
985 }
986 }
987 #endif
988 }
989  
990  
991 /****************************************************************************
992 Function:
993 void USBHostMSDTerminateTransfer( BYTE deviceAddress )
994  
995 Description:
996 This function terminates a mass storage transfer.
997  
998 Precondition:
999 None
1000  
1001 Parameters:
1002 BYTE deviceAddress - Device address
1003  
1004 Returns:
1005 None
1006  
1007 Remarks:
1008 After executing this function, the application may have to reset the
1009 device in order for the device to continue working properly.
1010 ***************************************************************************/
1011  
1012 void USBHostMSDTerminateTransfer( BYTE deviceAddress )
1013 {
1014 BYTE i;
1015  
1016 // Find the correct device.
1017 for (i=0; (i<USB_MAX_MASS_STORAGE_DEVICES) && (deviceInfoMSD[i].deviceAddress != deviceAddress); i++);
1018 if (i == USB_MAX_MASS_STORAGE_DEVICES)
1019 {
1020 return;
1021 }
1022  
1023 // We can only terminate transfers if we are in STATE_RUNNING. Otherwise, we
1024 // will cause major problems.
1025  
1026 #ifndef USB_ENABLE_TRANSFER_EVENT
1027 if ((deviceInfoMSD[i].state & STATE_MASK) == STATE_RUNNING)
1028 #else
1029 if ((deviceInfoMSD[i].state == STATE_RUNNING) ||
1030 (deviceInfoMSD[i].state == STATE_CBW_WAIT) ||
1031 (deviceInfoMSD[i].state == STATE_TRANSFER_WAIT) ||
1032 (deviceInfoMSD[i].state == STATE_CSW_WAIT))
1033 #endif
1034 {
1035 // Terminate any endpoint tranfers that are occurring.
1036 USBHostTerminateTransfer( deviceInfoMSD[i].deviceAddress, deviceInfoMSD[i].endpointIN );
1037 USBHostTerminateTransfer( deviceInfoMSD[i].deviceAddress, deviceInfoMSD[i].endpointOUT );
1038  
1039 // Set the state back to running and waiting for a transfer request.
1040 #ifndef USB_ENABLE_TRANSFER_EVENT
1041 deviceInfoMSD[i].state = STATE_RUNNING | SUBSTATE_HOLDING;
1042 #else
1043 deviceInfoMSD[i].state = STATE_RUNNING;
1044 #endif
1045 }
1046 return;
1047 }
1048  
1049 /****************************************************************************
1050 Function:
1051 BYTE USBHostMSDTransfer( BYTE deviceAddress, BYTE deviceLUN,
1052 BYTE direction, BYTE *commandBlock, BYTE commandBlockLength,
1053 BYTE *data, DWORD dataLength )
1054  
1055 Summary:
1056 This function starts a mass storage transfer.
1057  
1058 Description:
1059 This function starts a mass storage transfer. Usually, applications will
1060 probably utilize a read/write wrapper to access this function.
1061  
1062 Precondition:
1063 None
1064  
1065 Parameters:
1066 BYTE deviceAddress - Device address
1067 BYTE deviceLUN - Device LUN to access
1068 BYTE direction - 1=read, 0=write
1069 BYTE *commandBlock - Pointer to the command block for the CBW
1070 BYTE commandBlockLength - Length of the command block
1071 BYTE *data - Pointer to the data buffer
1072 DWORD dataLength - Byte size of the data buffer
1073  
1074  
1075 Return Values:
1076 USB_SUCCESS - Request started successfully
1077 USB_MSD_DEVICE_NOT_FOUND - No device with specified address
1078 USB_MSD_DEVICE_BUSY - Device not in proper state for performing
1079 a transfer
1080 USB_MSD_INVALID_LUN - Specified LUN does not exist
1081  
1082 Remarks:
1083 None
1084 ***************************************************************************/
1085  
1086 BYTE USBHostMSDTransfer( BYTE deviceAddress, BYTE deviceLUN, BYTE direction, BYTE *commandBlock,
1087 BYTE commandBlockLength, BYTE *data, DWORD dataLength )
1088 {
1089 BYTE i;
1090 BYTE j;
1091  
1092 #ifdef DEBUG_MODE
1093 UART2PrintString( "MSD: Transfer: " );
1094 if (direction)
1095 {
1096 UART2PrintString( "Read, " );
1097 }
1098 else
1099 {
1100 UART2PrintString( "Write, " );
1101 }
1102 #endif
1103  
1104 // Make sure a valid device is being requested.
1105 if ((deviceAddress == 0) || (deviceAddress > 127))
1106 {
1107 return USB_MSD_DEVICE_NOT_FOUND;
1108 }
1109  
1110 // Find the correct device.
1111 for (i=0; (i<USB_MAX_MASS_STORAGE_DEVICES) && (deviceInfoMSD[i].deviceAddress != deviceAddress); i++);
1112 if (i == USB_MAX_MASS_STORAGE_DEVICES)
1113 {
1114 return USB_MSD_DEVICE_NOT_FOUND;
1115 }
1116  
1117 // Make sure the device is in a state ready to read/write.
1118 #ifndef USB_ENABLE_TRANSFER_EVENT
1119 if (deviceInfoMSD[i].state != (STATE_RUNNING | SUBSTATE_HOLDING))
1120 #else
1121 if (deviceInfoMSD[i].state != STATE_RUNNING)
1122 #endif
1123 {
1124 return USB_MSD_DEVICE_BUSY;
1125 }
1126  
1127 // Verify the selected LUN.
1128 if (deviceLUN > deviceInfoMSD[i].maxLUN)
1129 {
1130 return USB_MSD_INVALID_LUN;
1131 }
1132  
1133 // Initialize the transfer information.
1134 deviceInfoMSD[i].attemptsCSW = CSW_RECEIVE_ATTEMPTS;
1135 deviceInfoMSD[i].bytesTransferred = 0;
1136 deviceInfoMSD[i].errorCode = USB_SUCCESS;
1137 deviceInfoMSD[i].flags.val = 0;
1138 deviceInfoMSD[i].flags.bfDirection = direction;
1139 deviceInfoMSD[i].userData = data;
1140 deviceInfoMSD[i].userDataLength = dataLength;
1141 deviceInfoMSD[i].dCBWTag = _USBHostMSD_GetNextTag();
1142 deviceInfoMSD[i].endpointDATA = deviceInfoMSD[i].endpointIN;
1143 if (!direction) // OUT
1144 {
1145 deviceInfoMSD[i].endpointDATA = deviceInfoMSD[i].endpointOUT;
1146 }
1147 #ifdef DEBUG_MODE
1148 UART2PrintString( "Data EP: " );
1149 UART2PutHex( deviceInfoMSD[i].endpointDATA );
1150 UART2PrintString( "\r\n" );
1151 #endif
1152  
1153 // Prepare the CBW so we can give the user back his command block RAM.
1154 ((USB_MSD_CBW *)(deviceInfoMSD[i].blockData))->dCBWSignature = USB_MSD_DCBWSIGNATURE;
1155 ((USB_MSD_CBW *)(deviceInfoMSD[i].blockData))->dCBWTag = deviceInfoMSD[i].dCBWTag;
1156 ((USB_MSD_CBW *)(deviceInfoMSD[i].blockData))->dCBWDataTransferLength = deviceInfoMSD[i].userDataLength;
1157 ((USB_MSD_CBW *)(deviceInfoMSD[i].blockData))->bmCBWflags.val = 0;
1158 ((USB_MSD_CBW *)(deviceInfoMSD[i].blockData))->bmCBWflags.bfDirection = direction;
1159 ((USB_MSD_CBW *)(deviceInfoMSD[i].blockData))->bCBWLUN = deviceLUN;
1160 ((USB_MSD_CBW *)(deviceInfoMSD[i].blockData))->bCBWCBLength = commandBlockLength;
1161 for (j=0; j<commandBlockLength; j++)
1162 {
1163 ((USB_MSD_CBW *)(deviceInfoMSD[i].blockData))->CBWCB[j] = commandBlock[j];
1164 }
1165  
1166 #ifndef USB_ENABLE_TRANSFER_EVENT
1167 // Jump to the transfer state.
1168 deviceInfoMSD[i].state = STATE_RUNNING | SUBSTATE_SEND_CBW;
1169 #else
1170 j = USBHostWrite( deviceInfoMSD[i].deviceAddress, deviceInfoMSD[i].endpointOUT, deviceInfoMSD[i].blockData, CBW_SIZE );
1171 if (j)
1172 {
1173 _USBHostMSD_TerminateTransfer( j );
1174 }
1175 else
1176 {
1177 deviceInfoMSD[i].state = STATE_CBW_WAIT;
1178 }
1179 #endif
1180  
1181 return USB_SUCCESS;
1182 }
1183  
1184  
1185 /****************************************************************************
1186 Function:
1187 BOOL USBHostMSDTransferIsComplete( BYTE deviceAddress,
1188 BYTE *errorCode, DWORD *byteCount )
1189  
1190 Summary:
1191 This function indicates whether or not the last transfer is complete.
1192  
1193 Description:
1194 This function indicates whether or not the last transfer is complete. If
1195 the functions returns TRUE, the returned byte count and error code are
1196 valid. Since only one transfer can be performed at once and only one
1197 endpoint can be used, we only need to know the device address.
1198  
1199 Precondition:
1200 None
1201  
1202 Parameters:
1203 BYTE deviceAddress - Device address
1204 BYTE *errorCode - Error code from last transfer
1205 DWORD *byteCount - Number of bytes transferred
1206  
1207 Return Values:
1208 TRUE - Transfer is complete, errorCode is valid
1209 FALSE - Transfer is not complete, errorCode is not valid
1210  
1211 Remarks:
1212 None
1213 ***************************************************************************/
1214  
1215 BOOL USBHostMSDTransferIsComplete( BYTE deviceAddress, BYTE *errorCode, DWORD *byteCount )
1216 {
1217 BYTE i;
1218  
1219 // Make sure a valid device is being requested.
1220 if ((deviceAddress == 0) || (deviceAddress > 127))
1221 {
1222 *errorCode = USB_MSD_DEVICE_NOT_FOUND;
1223 *byteCount = 0;
1224 return TRUE;
1225 }
1226  
1227 // Find the correct device.
1228 for (i=0; (i<USB_MAX_MASS_STORAGE_DEVICES) && (deviceInfoMSD[i].deviceAddress != deviceAddress); i++);
1229 if ((i == USB_MAX_MASS_STORAGE_DEVICES) || (deviceInfoMSD[i].state == STATE_DETACHED))
1230 {
1231 *errorCode = USB_MSD_DEVICE_NOT_FOUND;
1232 *byteCount = 0;
1233 return TRUE;
1234 }
1235  
1236 #ifndef USB_ENABLE_TRANSFER_EVENT
1237 if ( (deviceInfoMSD[i].state == (STATE_RUNNING | SUBSTATE_HOLDING)) ||
1238 ((deviceInfoMSD[i].state & STATE_MASK) == STATE_HOLDING))
1239 #else
1240 if ((deviceInfoMSD[i].state == STATE_RUNNING) ||
1241 (deviceInfoMSD[i].state == STATE_HOLDING))
1242 #endif
1243 {
1244 *byteCount = deviceInfoMSD[i].bytesTransferred;
1245 *errorCode = deviceInfoMSD[i].errorCode;
1246  
1247 return TRUE;
1248 }
1249 else
1250 {
1251 return FALSE;
1252 }
1253 }
1254  
1255  
1256 // *****************************************************************************
1257 // *****************************************************************************
1258 // Section: Host Stack Interface Functions
1259 // *****************************************************************************
1260 // *****************************************************************************
1261  
1262 /****************************************************************************
1263 Function:
1264 BOOL USBHostMSDInitialize( BYTE address, DWORD flags, BYTE clientDriverID )
1265  
1266 Summary:
1267 This function is the initialization routine for this client driver.
1268  
1269 Description:
1270 This function is the initialization routine for this client driver. It
1271 is called by the host layer when the USB device is being enumerated. For
1272 a mass storage device, we need to make sure that we have room for a new
1273 device, and that the device has at least one bulk IN and one bulk OUT
1274 endpoint.
1275  
1276 Precondition:
1277 None
1278  
1279 Parameters:
1280 BYTE address - Address of the new device
1281 DWORD flags - Initialization flags
1282 BYTE clientDriverID - ID to send when issuing a Device Request via
1283 USBHostIssueDeviceRequest(), USBHostSetDeviceConfiguration(),
1284 or USBHostSetDeviceInterface().
1285  
1286 Return Values:
1287 TRUE - We can support the device.
1288 FALSE - We cannot support the device.
1289  
1290 Remarks:
1291 None
1292 ***************************************************************************/
1293  
1294 BOOL USBHostMSDInitialize( BYTE address, DWORD flags, BYTE clientDriverID )
1295 {
1296 BYTE *descriptor;
1297 BYTE device;
1298 #ifdef USB_ENABLE_TRANSFER_EVENT
1299 BYTE errorCode;
1300 #endif
1301 WORD i;
1302 BYTE endpointIN;
1303 BYTE endpointOUT;
1304  
1305 #ifdef DEBUG_MODE
1306 UART2PrintString( "MSD: USBHostMSDClientInitialize(0x" );
1307 UART2PutHex( flags );
1308 UART2PrintString( ")\r\n" );
1309 #endif
1310  
1311 // Find the free slot in the table. If we cannot find one, kick off the device.
1312 for (device = 0; (device < USB_MAX_MASS_STORAGE_DEVICES) && (deviceInfoMSD[device].deviceAddress != 0); device++);
1313 if (device == USB_MAX_MASS_STORAGE_DEVICES)
1314 {
1315 #ifdef DEBUG_MODE
1316 UART2PrintString( "MSD: No free slots available for MSD.\r\n" );
1317 #endif
1318 // Kick off the device
1319 return FALSE;
1320 }
1321  
1322 #ifdef DEBUG_MODE
1323 UART2PrintString( "MSD: MSD attached.\r\n" );
1324 #endif
1325  
1326 descriptor = USBHostGetCurrentConfigurationDescriptor( address );
1327  
1328 i = 0;
1329  
1330 #ifdef DEBUG_MODE
1331 UART2PrintString("MSD: Checking descriptor " );
1332 UART2PutDec( descriptor[i+5] );
1333 UART2PrintString(" ...\r\n" );
1334 #endif
1335  
1336 // Find the next interface descriptor.
1337 while (i < ((USB_CONFIGURATION_DESCRIPTOR *)descriptor)->wTotalLength)
1338 {
1339 #ifdef DEBUG_MODE
1340 UART2PrintString("MSD: Checking interface...\r\n" );
1341 #endif
1342 // See if we are pointing to an interface descriptor.
1343 if (descriptor[i+1] == USB_DESCRIPTOR_INTERFACE)
1344 {
1345 // See if the interface is a Mass Storage Device interface.
1346 if (descriptor[i+5] == DEVICE_CLASS_MASS_STORAGE)
1347 {
1348 // See if the interface subclass and protocol are correct.
1349 if ((descriptor[i+6] == DEVICE_SUBCLASS_SCSI) &&
1350 (descriptor[i+7] == DEVICE_INTERFACE_PROTOCOL_BULK_ONLY))
1351 {
1352 deviceInfoMSD[device].interface = descriptor[i+2];
1353  
1354 // Look for bulk IN and OUT endpoints.
1355 endpointIN = 0;
1356 endpointOUT = 0;
1357  
1358 // Scan for endpoint descriptors.
1359 i += descriptor[i];
1360 while (descriptor[i+1] == USB_DESCRIPTOR_ENDPOINT)
1361 {
1362 if (descriptor[i+3] == 0x02) // Bulk
1363 {
1364 if (((descriptor[i+2] & 0x80) == 0x80) && (endpointIN == 0))
1365 {
1366 endpointIN = descriptor[i+2];
1367 }
1368 if (((descriptor[i+2] & 0x80) == 0x00) && (endpointOUT == 0))
1369 {
1370 endpointOUT = descriptor[i+2];
1371 }
1372 }
1373 i += descriptor[i];
1374 }
1375  
1376 if ((endpointIN != 0) && (endpointOUT != 0))
1377 {
1378 // Initialize the device information.
1379 deviceInfoMSD[device].deviceAddress = address;
1380 deviceInfoMSD[device].clientDriverID = clientDriverID;
1381 deviceInfoMSD[device].endpointIN = endpointIN;
1382 deviceInfoMSD[device].endpointOUT = endpointOUT;
1383 #ifdef DEBUG_MODE
1384 UART2PrintString( "MSD: Bulk endpoint IN: " );
1385 UART2PutHex( endpointIN );
1386 UART2PrintString( " Bulk endpoint OUT: " );
1387 UART2PutHex( endpointOUT );
1388 UART2PrintString( "\r\n" );
1389 #endif
1390 USBHostSetNAKTimeout( address, endpointIN, 1, USB_NUM_BULK_NAKS );
1391 USBHostSetNAKTimeout( address, endpointOUT, 1, USB_NUM_BULK_NAKS );
1392  
1393 #ifndef USB_ENABLE_TRANSFER_EVENT
1394 deviceInfoMSD[device].state = STATE_INITIALIZE_DEVICE;
1395 #else
1396 // Initiate the request to get the max LUN. If we can't initiate the request,
1397 // then we can't enumerate the device.
1398 errorCode = USBHostIssueDeviceRequest( deviceInfoMSD[device].deviceAddress,
1399 USB_SETUP_DEVICE_TO_HOST | USB_SETUP_TYPE_CLASS | USB_SETUP_RECIPIENT_INTERFACE,
1400 USB_MSD_GET_MAX_LUN, 0, deviceInfoMSD[device].interface, 1, deviceInfoMSD[device].blockData,
1401 USB_DEVICE_REQUEST_GET, deviceInfoMSD[device].clientDriverID );
1402 if (errorCode)
1403 {
1404 #ifdef DEBUG_MODE
1405 UART2PrintString( "MSD: Cannot get Max LUN - " );
1406 UART2PutHex( errorCode );
1407 UART2PrintString( "\r\n" );
1408 #endif
1409 return FALSE;
1410 }
1411 #ifdef DEBUG_MODE
1412 UART2PrintString( "MSD: Getting Max LUN\r\n" );
1413 #endif
1414 deviceInfoMSD[device].state = STATE_WAIT_FOR_MAX_LUN;
1415 #endif
1416  
1417 return TRUE;
1418 }
1419 }
1420 }
1421 }
1422  
1423 // Jump to the next descriptor in this configuration.
1424 i += descriptor[i];
1425 }
1426  
1427 // This configuration is not valid for a Mass storage device.
1428 return FALSE;
1429 }
1430  
1431  
1432 /****************************************************************************
1433 Function:
1434 BOOL USBHostMSDEventHandler( BYTE address, USB_EVENT event,
1435 void *data, DWORD size )
1436  
1437 Summary:
1438 This function is the event handler for this client driver.
1439  
1440 Description:
1441 This function is the event handler for this client driver. It is called
1442 by the host layer when various events occur.
1443  
1444 Precondition:
1445 The device has been initialized.
1446  
1447 Parameters:
1448 BYTE address - Address of the device
1449 USB_EVENT event - Event that has occurred
1450 void *data - Pointer to data pertinent to the event
1451 WORD size - Size of the data
1452  
1453 Return Values:
1454 TRUE - Event was handled
1455 FALSE - Event was not handled
1456  
1457 Remarks:
1458 None
1459 ***************************************************************************/
1460  
1461 BOOL USBHostMSDEventHandler( BYTE address, USB_EVENT event, void *data, DWORD size )
1462 {
1463 #if defined( USB_ENABLE_TRANSFER_EVENT )
1464 BYTE errorCode;
1465 #endif
1466 BYTE i;
1467  
1468 switch (event)
1469 {
1470 case EVENT_NONE: // No event occured (NULL event)
1471 USBTasks();
1472 return TRUE;
1473 break;
1474  
1475 case EVENT_DETACH: // USB cable has been detached (data: BYTE, address of device)
1476 #ifdef DEBUG_MODE
1477 UART2PrintString( "MSD: Detach\r\n" );
1478 #endif
1479  
1480 // Find the device in the table. If found, clear the important fields.
1481 for (i=0; (i<USB_MAX_MASS_STORAGE_DEVICES) && (deviceInfoMSD[i].deviceAddress != address); i++);
1482 if (i < USB_MAX_MASS_STORAGE_DEVICES)
1483 {
1484 deviceInfoMSD[i].deviceAddress = 0;
1485 deviceInfoMSD[i].state = STATE_DETACHED;
1486  
1487 // Inform the next higher layer of the event.
1488 usbMediaInterfaceTable.EventHandler( address, EVENT_DETACH, NULL, 0 );
1489 }
1490 return TRUE;
1491 break;
1492  
1493 case EVENT_TRANSFER: // A USB transfer has completed - optional
1494 #if defined( USB_ENABLE_TRANSFER_EVENT )
1495 #ifdef DEBUG_MODE
1496 UART2PrintString( "MSD: transfer event: " );
1497 UART2PutHex( address );
1498 UART2PrintString( "\r\n" );
1499 #endif
1500  
1501 for (i=0; (i<USB_MAX_MASS_STORAGE_DEVICES) && (deviceInfoMSD[i].deviceAddress != address); i++) {}
1502 if (i == USB_MAX_MASS_STORAGE_DEVICES)
1503 {
1504 #ifdef DEBUG_MODE
1505 UART2PrintString( "MSD: Unknown device\r\n" );
1506 #endif
1507 return FALSE;
1508 }
1509  
1510 #ifdef DEBUG_MODE
1511 UART2PrintString( "MSD: Device state: " );
1512 UART2PutHex( deviceInfoMSD[i].state );
1513 UART2PrintString( "\r\n" );
1514 #endif
1515 switch (deviceInfoMSD[i].state)
1516 {
1517 case STATE_WAIT_FOR_MAX_LUN:
1518 #ifdef DEBUG_MODE
1519 UART2PrintString( "MSD: Got Max LUN\r\n" );
1520 #endif
1521 deviceInfoMSD[i].maxLUN = 0;
1522 if (!((HOST_TRANSFER_DATA *)data)->bErrorCode)
1523 {
1524 deviceInfoMSD[i].maxLUN = deviceInfoMSD[i].blockData[0];
1525 }
1526 else
1527 {
1528 // Clear the STALL. Since it is EP0, we do not have to clear the stall.
1529 USBHostClearEndpointErrors( deviceInfoMSD[i].deviceAddress, 0 );
1530 }
1531  
1532 // Tell the media interface layer that we have a MSD attached.
1533 if (usbMediaInterfaceTable.Initialize( deviceInfoMSD[i].deviceAddress, usbMediaInterfaceTable.flags, 0 ))
1534 {
1535 usbMediaInterfaceTable.EventHandler( deviceInfoMSD[i].deviceAddress, EVENT_MSD_MAX_LUN, &(deviceInfoMSD[i].maxLUN), 1 );
1536 deviceInfoMSD[i].state = STATE_RUNNING;
1537 }
1538 else
1539 {
1540 // The media interface layer cannot support the device.
1541 deviceInfoMSD[i].errorCode = USB_MSD_MEDIA_INTERFACE_ERROR;
1542 deviceInfoMSD[i].state = STATE_HOLDING;
1543 }
1544 return TRUE;
1545 break;
1546  
1547 case STATE_RUNNING:
1548 // Shouldn't get any transfer events here.
1549 return FALSE;
1550 break;
1551  
1552 case STATE_CBW_WAIT:
1553 if (((HOST_TRANSFER_DATA *)data)->bErrorCode)
1554 {
1555 #ifdef DEBUG_MODE
1556 UART2PrintString( "MSD: Error with sending CBW\r\n" );
1557 #endif
1558 _USBHostMSD_TerminateTransfer( ((HOST_TRANSFER_DATA *)data)->bErrorCode );
1559 }
1560 else if (((HOST_TRANSFER_DATA *)data)->dataCount != CBW_SIZE)
1561 {
1562 #ifdef DEBUG_MODE
1563 UART2PrintString( "MSD: CBW size not correct\r\n" );
1564 #endif
1565 _USBHostMSD_TerminateTransfer( USB_MSD_CBW_ERROR );
1566 }
1567 else
1568 {
1569 if ((((USB_MSD_CBW *)(deviceInfoMSD[i].blockData))->dCBWDataTransferLength == 0) ||
1570 (deviceInfoMSD[i].userDataLength == 0))
1571 {
1572 #ifdef DEBUG_MODE
1573 UART2PrintString( "MSD: Transfer length=0\r\n" );
1574 #endif
1575  
1576 // Skip to getting the CSW
1577 #ifdef DEBUG_MODE
1578 UART2PrintString( "MSD: Getting CSW\r\n" );
1579 #endif
1580  
1581 errorCode = USBHostRead( deviceInfoMSD[i].deviceAddress, deviceInfoMSD[i].endpointIN, deviceInfoMSD[i].blockData, CSW_SIZE );
1582 if (errorCode)
1583 {
1584 _USBHostMSD_TerminateTransfer( errorCode );
1585 }
1586 else
1587 {
1588 deviceInfoMSD[i].state = STATE_CSW_WAIT;
1589 }
1590 }
1591 else
1592 {
1593 #ifdef DEBUG_MODE
1594 UART2PrintString( "MSD: Going on...\r\n" );
1595 #endif
1596 if (!deviceInfoMSD[i].flags.bfDirection) // OUT
1597 {
1598 errorCode = USBHostWrite( deviceInfoMSD[i].deviceAddress, deviceInfoMSD[i].endpointDATA, deviceInfoMSD[i].userData, deviceInfoMSD[i].userDataLength );
1599 }
1600 else
1601 {
1602 errorCode = USBHostRead( deviceInfoMSD[i].deviceAddress, deviceInfoMSD[i].endpointDATA, deviceInfoMSD[i].userData, deviceInfoMSD[i].userDataLength );
1603 }
1604  
1605 if (errorCode)
1606 {
1607 _USBHostMSD_TerminateTransfer( errorCode );
1608 }
1609 else
1610 {
1611 deviceInfoMSD[i].state = STATE_TRANSFER_WAIT;
1612 }
1613 }
1614 }
1615 return TRUE;
1616 break;
1617  
1618 case STATE_TRANSFER_WAIT:
1619 if (((HOST_TRANSFER_DATA *)data)->bErrorCode)
1620 {
1621 if (((HOST_TRANSFER_DATA *)data)->bErrorCode == USB_ENDPOINT_STALLED)
1622 {
1623 // Clear the stall, then try to get the CSW.
1624 USBHostClearEndpointErrors( deviceInfoMSD[i].deviceAddress, deviceInfoMSD[i].endpointDATA );
1625 if (!deviceInfoMSD[i].flags.bfDirection) // OUT
1626 {
1627 deviceInfoMSD[i].flags.bfClearDataOUT = 1;
1628 }
1629 else
1630 {
1631 deviceInfoMSD[i].flags.bfClearDataIN = 1;
1632 }
1633 deviceInfoMSD[i].returnState = STATE_REQUEST_CSW;
1634 _USBHostMSD_ResetStateJump( i );
1635  
1636 }
1637 else
1638 {
1639 //Error recovery here is not explicitly covered in the spec.
1640 //_USBHostMSD_TerminateTransfer( errorCode );
1641 deviceInfoMSD[i].flags.val |= MARK_RESET_RECOVERY;
1642 deviceInfoMSD[i].returnState = STATE_RUNNING;
1643 _USBHostMSD_ResetStateJump( i );
1644 }
1645 }
1646 else
1647 {
1648 #ifdef DEBUG_MODE
1649 UART2PrintString( "MSD: Getting CSW\r\n" );
1650 #endif
1651  
1652 errorCode = USBHostRead( deviceInfoMSD[i].deviceAddress, deviceInfoMSD[i].endpointIN, deviceInfoMSD[i].blockData, CSW_SIZE );
1653 if (errorCode)
1654 {
1655 _USBHostMSD_TerminateTransfer( errorCode );
1656 }
1657 else
1658 {
1659 deviceInfoMSD[i].state = STATE_CSW_WAIT;
1660 }
1661 }
1662 break;
1663  
1664 case STATE_CSW_WAIT:
1665 #ifdef DEBUG_MODE
1666 UART2PrintString( "MSD: Got CSW - " );
1667 #endif
1668 if (((HOST_TRANSFER_DATA *)data)->bErrorCode)
1669 {
1670 deviceInfoMSD[i].attemptsCSW--;
1671 if (deviceInfoMSD[i].attemptsCSW)
1672 {
1673 USBHostClearEndpointErrors( deviceInfoMSD[i].deviceAddress, deviceInfoMSD[i].endpointIN );
1674 deviceInfoMSD[i].flags.bfClearDataIN = 1;
1675 deviceInfoMSD[i].returnState = STATE_REQUEST_CSW;
1676 _USBHostMSD_ResetStateJump( i );
1677 }
1678 else
1679 {
1680 _USBHostMSD_TerminateTransfer( ((HOST_TRANSFER_DATA *)data)->bErrorCode );
1681 }
1682 }
1683 else if ((((HOST_TRANSFER_DATA *)data)->dataCount != CSW_SIZE) |
1684 (((USB_MSD_CSW *)(deviceInfoMSD[i].blockData))->dCSWSignature != USB_MSD_DCSWSIGNATURE) |
1685 (((USB_MSD_CSW *)(deviceInfoMSD[i].blockData))->dCSWTag != deviceInfoMSD[i].dCBWTag) )
1686 {
1687 _USBHostMSD_TerminateTransfer( USB_MSD_CSW_ERROR );
1688 }
1689 else
1690 {
1691 deviceInfoMSD[i].bytesTransferred = deviceInfoMSD[i].userDataLength - ((USB_MSD_CSW *)(deviceInfoMSD[i].blockData))->dCSWDataResidue;
1692  
1693 if (((USB_MSD_CSW *)(deviceInfoMSD[i].blockData))->dCSWStatus != 0x00)
1694 {
1695 _USBHostMSD_TerminateTransfer( ((USB_MSD_CSW *)(deviceInfoMSD[i].blockData))->dCSWStatus | USB_MSD_ERROR );
1696 }
1697 else
1698 {
1699 _USBHostMSD_TerminateTransfer( USB_SUCCESS );
1700 }
1701  
1702 // If we have a phase error, we need to perform corrective action instead of
1703 // returning to normal running.
1704 if (((USB_MSD_CSW *)(deviceInfoMSD[i].blockData))->dCSWStatus == MSD_PHASE_ERROR)
1705 {
1706 deviceInfoMSD[i].flags.val |= MARK_RESET_RECOVERY;
1707 deviceInfoMSD[i].returnState = STATE_RUNNING;
1708 _USBHostMSD_ResetStateJump( i );
1709 }
1710 }
1711 break;
1712  
1713 case STATE_WAIT_FOR_RESET:
1714 if (((HOST_TRANSFER_DATA *)data)->bErrorCode)
1715 {
1716 //Error recovery here is not explicitly covered in the spec.
1717 _USBHostMSD_TerminateTransfer( USB_MSD_RESET_ERROR );
1718 }
1719 else
1720 {
1721 deviceInfoMSD[i].flags.bfReset = 0;
1722 _USBHostMSD_ResetStateJump( i );
1723 }
1724 break;
1725  
1726 case STATE_WAIT_FOR_CLEAR_IN:
1727 if (errorCode)
1728 {
1729 //Error recovery here is not explicitly covered in the spec.
1730 _USBHostMSD_TerminateTransfer( USB_MSD_RESET_ERROR );
1731 }
1732 else
1733 {
1734 deviceInfoMSD[i].flags.bfClearDataIN = 0;
1735 _USBHostMSD_ResetStateJump( i );
1736 }
1737 break;
1738  
1739 case STATE_WAIT_FOR_CLEAR_OUT:
1740 if (errorCode)
1741 {
1742 //Error recovery here is not explicitly covered in the spec.
1743 _USBHostMSD_TerminateTransfer( USB_MSD_RESET_ERROR );
1744 }
1745 else
1746 {
1747 deviceInfoMSD[i].flags.bfClearDataOUT = 0;
1748 _USBHostMSD_ResetStateJump( i );
1749 }
1750 break;
1751  
1752 case STATE_HOLDING:
1753 break;
1754 }
1755 #endif
1756  
1757 case EVENT_SOF: // Start of frame - NOT NEEDED
1758 case EVENT_RESUME: // Device-mode resume received
1759 case EVENT_SUSPEND: // Device-mode suspend/idle event received
1760 case EVENT_RESET: // Device-mode bus reset received
1761 case EVENT_STALL: // A stall has occured
1762 return TRUE;
1763 break;
1764  
1765 default:
1766 return FALSE;
1767 break;
1768 }
1769 return FALSE;
1770 }
1771  
1772  
1773 // *****************************************************************************
1774 // *****************************************************************************
1775 // Section: Internal Functions
1776 // *****************************************************************************
1777 // *****************************************************************************
1778  
1779 /****************************************************************************
1780 Function:
1781 DWORD _USBHostMSD_GetNextTag( void )
1782  
1783 Description:
1784 Each bulk transfer has a transfer ID that is present in the CBW and must
1785 match in the CWS. This function gets the next ID number for a transfer.
1786  
1787 Precondition:
1788 None
1789  
1790 Parameters:
1791 None - None
1792  
1793 Returns:
1794 DWORD - Tag to use in the next CBW
1795  
1796 Remarks:
1797 None
1798 ***************************************************************************/
1799  
1800 DWORD _USBHostMSD_GetNextTag( void )
1801 {
1802 return dCBWTagNext++;
1803 }
1804  
1805  
1806 /****************************************************************************
1807 Function:
1808 void _USBHostMSD_ResetStateJump( BYTE i )
1809  
1810 Summary:
1811  
1812  
1813 Description:
1814 This function determines which portion of the reset processing needs to
1815 be executed next and jumps to that state.
1816  
1817 Precondition:
1818 The device information must be in the deviceInfoMSD array.
1819  
1820 Parameters:
1821 BYTE i - Index into the deviceInfoMSD structure for the device to reset.
1822  
1823 Returns:
1824 None
1825  
1826 Remarks:
1827 None
1828 ***************************************************************************/
1829  
1830 void _USBHostMSD_ResetStateJump( BYTE i )
1831 {
1832 #ifdef USB_ENABLE_TRANSFER_EVENT
1833 BYTE errorCode;
1834 #endif
1835  
1836 if (deviceInfoMSD[i].flags.bfReset)
1837 {
1838 #ifndef USB_ENABLE_TRANSFER_EVENT
1839 deviceInfoMSD[i].state = STATE_MSD_RESET_RECOVERY;
1840 #else
1841 errorCode = USBHostIssueDeviceRequest( deviceInfoMSD[i].deviceAddress, USB_SETUP_HOST_TO_DEVICE | USB_SETUP_TYPE_CLASS | USB_SETUP_RECIPIENT_INTERFACE,
1842 USB_MSD_RESET, 0, deviceInfoMSD[i].interface, 0, NULL, USB_DEVICE_REQUEST_SET, deviceInfoMSD[i].clientDriverID );
1843  
1844 if (errorCode)
1845 {
1846 //Error recovery here is not explicitly covered in the spec.
1847 _USBHostMSD_TerminateTransfer( USB_MSD_RESET_ERROR );
1848 }
1849 else
1850 {
1851 deviceInfoMSD[i].state = STATE_WAIT_FOR_RESET;
1852 }
1853 #endif
1854 }
1855 else if (deviceInfoMSD[i].flags.bfClearDataIN)
1856 {
1857 #ifndef USB_ENABLE_TRANSFER_EVENT
1858 deviceInfoMSD[i].state = STATE_MSD_CLEAR_DATA_IN;
1859 #else
1860 errorCode = USBHostIssueDeviceRequest( deviceInfoMSD[i].deviceAddress, USB_SETUP_HOST_TO_DEVICE | USB_SETUP_TYPE_STANDARD | USB_SETUP_RECIPIENT_ENDPOINT,
1861 USB_REQUEST_CLEAR_FEATURE, USB_FEATURE_ENDPOINT_HALT, deviceInfoMSD[i].endpointIN, 0, NULL, USB_DEVICE_REQUEST_SET, deviceInfoMSD[i].clientDriverID );
1862  
1863 if (errorCode)
1864 {
1865 //Error recovery here is not explicitly covered in the spec.
1866 _USBHostMSD_TerminateTransfer( USB_MSD_RESET_ERROR );
1867 }
1868 else
1869 {
1870 deviceInfoMSD[i].state = STATE_WAIT_FOR_CLEAR_IN;
1871 }
1872 #endif
1873 }
1874 else if (deviceInfoMSD[i].flags.bfClearDataOUT)
1875 {
1876 #ifndef USB_ENABLE_TRANSFER_EVENT
1877 deviceInfoMSD[i].state = STATE_MSD_CLEAR_DATA_OUT;
1878 #else
1879 errorCode = USBHostIssueDeviceRequest( deviceInfoMSD[i].deviceAddress, USB_SETUP_HOST_TO_DEVICE | USB_SETUP_TYPE_STANDARD | USB_SETUP_RECIPIENT_ENDPOINT,
1880 USB_REQUEST_CLEAR_FEATURE, USB_FEATURE_ENDPOINT_HALT, deviceInfoMSD[i].endpointOUT, 0, NULL, USB_DEVICE_REQUEST_SET, deviceInfoMSD[i].clientDriverID );
1881  
1882 if (errorCode)
1883 {
1884 //Error recovery here is not explicitly covered in the spec.
1885 _USBHostMSD_TerminateTransfer( USB_MSD_RESET_ERROR );
1886 }
1887 else
1888 {
1889 deviceInfoMSD[i].state = STATE_WAIT_FOR_CLEAR_OUT;
1890 }
1891 #endif
1892 }
1893 else
1894 {
1895 usbMediaInterfaceTable.EventHandler( deviceInfoMSD[i].deviceAddress, EVENT_MSD_RESET, NULL, 0 );
1896  
1897 // Clear the errors so we can try again.
1898 USBHostClearEndpointErrors( deviceInfoMSD[i].deviceAddress, deviceInfoMSD[i].endpointIN );
1899 USBHostClearEndpointErrors( deviceInfoMSD[i].deviceAddress, deviceInfoMSD[i].endpointOUT );
1900  
1901 #ifndef USB_ENABLE_TRANSFER_EVENT
1902 deviceInfoMSD[i].state = deviceInfoMSD[i].returnState;
1903 #else
1904 if (deviceInfoMSD[i].returnState == STATE_REQUEST_CSW)
1905 {
1906 // Request the CSW
1907 #ifdef DEBUG_MODE
1908 UART2PrintString( "MSD: Getting CSW\r\n" );
1909 #endif
1910  
1911 errorCode = USBHostRead( deviceInfoMSD[i].deviceAddress, deviceInfoMSD[i].endpointIN, deviceInfoMSD[i].blockData, CSW_SIZE );
1912 if (errorCode)
1913 {
1914 _USBHostMSD_TerminateTransfer( errorCode );
1915 }
1916 else
1917 {
1918 deviceInfoMSD[i].state = STATE_CSW_WAIT;
1919 }
1920 }
1921 else
1922 {
1923 deviceInfoMSD[i].state = deviceInfoMSD[i].returnState;
1924 }
1925 #endif
1926  
1927 }
1928 }
1929  
1930  
{BLAME END}
{FOOTER START}

Powered by WebSVN v2.8.3