1 //(c)2010 by Texas Instruments Incorporated, All Rights Reserved.
2 /*----------------------------------------------------------------------------+
3  |                                                                             |
4  |                              Texas Instruments                              |
5  |                                                                             |
6  |                          MSP430 USB-Example (MSC Driver)                    |
7  |                                                                             |
8  +-----------------------------------------------------------------------------+
9  |  Source: Msc_Scsi.c, File Version 1.03                                      |
10  |  Description: This file contains the SCSI command handlers, MSC stack       |
11  |               internal functions.                                           |
12  |  Author: Biju, MSP                                                          |
13  |                                                                             |
14  |  WHO          WHEN         WHAT                                             |
15  |  ---          ----------   ------------------------------------------------ |
16  |  MSP          2010/02/16   Created                                          |
17  |  Biju,MSP     2010/07/15   Fixed CV bugs                                    |
18  |  RSTO         2010/10/15   Improving READ/WRITE functionality               |
19  +----------------------------------------------------------------------------*/
20 
21 /*----------------------------------------------------------------------------+
22  | Includes                                                                    |
23  +----------------------------------------------------------------------------*/
24 #include "../USB_Common/types.h"
25 #include "../USB_Common/device.h"
26 #include "../USB_Common/defMSP430USB.h"
27 #include "../USB_Common/usb.h"
28 #include "../USB_MSC_API/UsbMscScsi.h"
29 #include "../USB_MSC_API/UsbMsc.h"
30 #include <descriptors.h>
31 #include <string.h>
32 
33 #ifdef _MSC_
34 
35 /*----------------------------------------------------------------------------+
36  | Internal Definitions                                                        |
37  +----------------------------------------------------------------------------*/
38 //Error codes
39 #define RESCODE_CURRENT_ERROR                    0x70
40 
41 #define S_NO_SENSE                               0x00
42 #define S_NOT_READY                              0x02
43 #define S_MEDIUM_ERROR                           0x03
44 #define S_ILLEGAL_REQUEST                        0x05
45 #define S_UNITATTN                               0x06
46 #define S_WRITE_PROTECTED                        0x07
47 #define S_ABORTED_COMMAND                        0x0B
48 
49 #define ASC_NOT_READY                            0x04
50 #define ASCQ_NOT_READY                           0x03
51 
52 #define ASC_MEDIUM_NOT_PRESENT                   0x3A
53 #define ASCQ_MEDIUM_NOT_PRESENT                  0x00
54 
55 #define ASC_INVALID_COMMAND_OP_CODE              0x20
56 #define ASCQ_INVALID_COMMAND_OP_CODE             0x00
57 
58 #define ASC_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE   0x21
59 #define ASCQ_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE  0x00
60 
61 #define ASC_INVALID_FIELD_IN_CDB                 0x24
62 #define ASCQ_INVALID_FIELD_IN_CDB                0x00
63 
64 #define ASC_INVALID_PARAMETER_LIST               0x26
65 #define ASCQ_INVALID_PARAMETER_LIST              0x02
66 
67 #define ASC_ABORTED_DATAPHASE_ERROR              0x4B
68 #define ASCQ_ABORTED_DATAPHASE_ERROR             0x00
69 
70 #define ASC_ILLEGAL_REQUEST                      0x20
71 #define ASCQ_ILLEGAL_REQUEST                     0x00
72 
73 #define ASC_UNITATTN_READY_NOTREADY              0x28
74 #define ASCQ_UNITATTN_READY_NOTREADY             0x00
75 
76 #define ASC_WRITE_PROTECTED                      0X27
77 #define ASCQ_WRITE_PROTECTED                     0X00
78 
79 #define ASC_WRITE_FAULT                          0x03
80 #define ASCQ_WRITE_FAULT                         0x00
81 
82 #define ASC_UNRECOVERED_READ                     0x11
83 #define ASCQ_UNRECOVERED_READ                    0x00
84 
85 #define DIRECTION_IN    0x80
86 #define DIRECTION_OUT   0x00
87 
88 #define EP_MAX_PACKET_SIZE      0x40
89 
90 VOID usbStallEndpoint (BYTE);
91 BYTE Scsi_Verify_CBW ();
92 
93 extern struct config_struct USBMSC_config;
94 
95 extern VOID *(*USB_TX_memcpy)(VOID * dest, const VOID * source, size_t count);
96 extern VOID *(*USB_RX_memcpy)(VOID * dest, const VOID * source, size_t count);
97 
98 extern __no_init tEDB __data16 tInputEndPointDescriptorBlock[];
99 extern __no_init tEDB __data16 tOutputEndPointDescriptorBlock[];
100 /*----------------------------------------------------------------------------+
101  | Global Variables                                                            |
102  +----------------------------------------------------------------------------*/
103 
104 struct _MscWriteControl MscWriteControl;
105 struct _MscReadControl MscReadControl;
106 struct _MscControl MscControl[MSC_MAX_LUN_NUMBER] = {0};
107 
108 /* Structure internal to stack for maintaining LBA info,buffer address etc */
109 USBMSC_RWbuf_Info sRwbuf;
110 
111 __no_init CBW McsCbw;
112 __no_init CSW McsCsw;
113 
114 struct _MscState MscState;
115 
116 /*----------------------------------------------------------------------------+
117  | Initiliazing Command data                                                   |
118  +----------------------------------------------------------------------------*/
119 BYTE Scsi_Standard_Inquiry_Data[256];
120 
121 REQUEST_SENSE_RESPONSE RequestSenseResponse;
122 
123 struct _Scsi_Read_Capacity Scsi_Read_Capacity_10[MSC_MAX_LUN_NUMBER];
124 
125 const struct _Report_Luns Report_Luns =  {{0x02,0x00,0x00,0x00},
126                                           {0x00,0x00,0x00,0x00},
127                                           {0x00,0x00,0x00,0x00,0x00,0x00,0x00,
128                                            0x00}};
129 
130 BYTE Scsi_Mode_Sense_6[SCSI_MODE_SENSE_6_CMD_LEN] = {0x03,0,0,0 };              //No mode sense parameter
131 
132 BYTE Scsi_Mode_Sense_10[SCSI_MODE_SENSE_10_CMD_LEN] = {0,0x06,0,0,0,0,0,0 };    //No mode sense parameter
133 
134 BYTE Scsi_Read_Format_Capacity[SCSI_READ_FORMAT_CAPACITY_CMD_LEN] =
135 {0x00,0x00,0x00,0x08,0x01,0x00,0x00,0x00,0x03,0x00,0x02,0x00};
136 
137 /*Default values initialized for SCSI Inquiry data */
138 const BYTE bScsi_Standard_Inquiry_Data[SCSI_SCSI_INQUIRY_CMD_LEN] = {
139 #ifdef CDROM_SUPPORT
140     0x05,                                                                       //Peripheral qualifier & peripheral device type
141 #else
142     0x00,                                                                       //Peripheral qualifier & peripheral device type
143 #endif
144     0x80,                                                                       //Removable medium
145     0x02,                                                                       //Version of the standard (SPC-2)
146     0x02,                                                                       //No NormACA, No HiSup, response data format=2
147     0x1F,                                                                       //No extra parameters
148     0x00,                                                                       //No flags
149     0x00,                                                                       //0x80 => BQue => Basic Task Management supported
150     0x00,                                                                       //No flags
151     /* 'T','I',' ',' ',' ',' ',' ',' ',
152      * 'M','a','s','s',' ','S','t','o','r','a','g','e', */
153 };
154 
155 #ifdef CDROM_SUPPORT
156 
157 /* SCSI TOC Record - Pg.459 of mmc6r02g.pdf */
158 const BYTE Scsi_Read_TOC_PMA_ATIP_F1[Scsi_Read_TOC_PMA_ATIP_F1_LEN] = {
159                 0x00, 0x12,                  // Length
160                 0x01,                        // First Track
161                 0x01,                        // Last Track
162 
163                 0x00,                        // Reserved
164                 0x14,                        // ADR/CTL
165                 0x01,                        // Track Number
166                 0x00,                        // Reserved
167                 0x00, 0x00, 0x02, 0x00,      // Track Address (TIME Form)
168                 0x00,0x00,0x00,0x00,         // Padding
169                 0x00,0x00,0x00,0x00
170 };
171 
172 const BYTE Scsi_Read_TOC_PMA_ATIP_F2[Scsi_Read_TOC_PMA_ATIP_F2_LEN] = {
173                 0x00, 0x2E,                  // Length
174                 0x01,                        // First Track
175                 0x01,                        // Last Track
176                 0x01,                        // Reserved
177                 0x14,                        // ADR/CTL
178                 0x00,                        // Track Number
179                 0xA0,                        // Reserved
180                 0x00, 0x00, 0x00, 0x00,      // Track Address (TIME Form)
181                 0x01,0x00,0x00,0x01,         // Padding/Descriptors
182                 0x14,0x00,0xA1,0x00,
183                 0x00,0x00,0x00,0x01,
184                 0x00,0x00,0x01,0x14,
185                 0x00,0xA2,0x00,0x00,
186                 0x00,0x00,0x1C,0x35,
187                 0x30,0x01,0x14,0x00,
188                 0x01,0x00,0x00,0x00,
189                 0x00,0x00,0x02,0x00
190 };
191 
192 /* GET_CONFIGURATION Response Pg. 312 of mmc6r02g.pdf */
193 const BYTE Scsi_Get_Configuration_Descriptor[SCSI_GET_CONFIGURATION_LEN] = {
194 
195                 /* Feature Header */
196                 0x00,0x00,0x00,0x00         // Length
197 };
198 
199 /* EVENT STATUS Response Pg. 316 of mmc6r02g.pdf */
200 const BYTE Scsi_Event_Status_Descriptor[SCSI_EVENT_STATUS_LEN] = {
201 
202                 /* Feature Header */
203                 0x00,0x06,                  // Event Descriptor Length
204                 0x04,                       // NEA/Reserved/Notification Class
205                 0x54,                       // Supported Event Classes
206                 0x02,                       // Reserved/Event Code
207                 0x02,
208                 0x00,0x00
209 };
210 
211 
212 /* READ_DISC_INFORMATION Response Pg. 374 of mmc6r02g.pdf  */
213 const BYTE Scsi_Disc_Information_Descriptor[SCSI_READ_DISC_INFORMATION_LEN] = {
214 
215                 0x00,0x00,                      // Disc Information Length
216                 0x00,                           // Disc Information Type, Non-Erasable, Last Session, Finalized
217                 0x00,                           // First Track on Disc
218                 0x00,                           // Number of Sessions
219                 0x00,                           // First Track Number in Last Session
220                 0x00,                           // Last Track Number in Last Session
221                 0x00,                           // BG/Barcode/ID Disable
222                 0x00,                           // Disc Type (CD-ROM)
223                 0x00,                           // Number of Sessions (MSB)
224                 0x00,                           // First Track Number in Last Session (MSB)
225                 0x00,                           // Last Track Number in Last Sessions (MSB)
226                 0x00,0x00,0x00,0x00,            // Disc ID
227                 0x00,0x00,0x00,0x00,            // Last Session Lead-In Address
228                 0x00,0x00,0x00,0x00,            // Last Lead-Out Start Address
229                 0x00,0x00,0x00,0x00,            // Bar Code (Not Supported)
230                 0x00,0x00,0x00,0x00,
231                 0x00,                           // Disc Application Code (Not Supported)
232                 0x00,0x00,0x00                   // No OPC Entries
233 };
234 
235 VOID Scsi_Read_TocPmaAtip(BYTE intfNum);
236 VOID Scsi_Get_Configuration(BYTE intfNum);
237 VOID Scsi_Event_Status_Notification(BYTE intfNum);
238 VOID Scsi_Read_Disc_Information(BYTE intfNum);
239 
240 #endif
241 /*----------------------------------------------------------------------------+
242  | Functions                                                                   |
243  +----------------------------------------------------------------------------*/
Reset_RequestSenseResponse(VOID)244 VOID Reset_RequestSenseResponse (VOID)
245 {
246     int i;
247 
248     RequestSenseResponse.ResponseCode = RESCODE_CURRENT_ERROR;
249     RequestSenseResponse.VALID = 0;                                             //no data in the information field
250     RequestSenseResponse.Obsolete = 0x00;
251     RequestSenseResponse.SenseKey = S_NO_SENSE;
252     RequestSenseResponse.ILI = 0;
253     RequestSenseResponse.EOM = 0;
254     RequestSenseResponse.FILEMARK = 0;
255     RequestSenseResponse.Information[0] = 0x00;
256     RequestSenseResponse.Information[1] = 0x00;
257     RequestSenseResponse.Information[2] = 0x00;
258     RequestSenseResponse.Information[3] = 0x00;
259     RequestSenseResponse.AddSenseLen = 0x0a;
260     RequestSenseResponse.CmdSpecificInfo[0] = 0x00;
261     RequestSenseResponse.CmdSpecificInfo[1] = 0x00;
262     RequestSenseResponse.CmdSpecificInfo[2] = 0x00;
263     RequestSenseResponse.CmdSpecificInfo[3] = 0x00;
264     RequestSenseResponse.ASC = 0x00;
265     RequestSenseResponse.ASCQ = 0x00;
266     RequestSenseResponse.FRUC = 0x00;
267     RequestSenseResponse.SenseKeySpecific[0] = 0x00;
268     RequestSenseResponse.SenseKeySpecific[1] = 0x00;
269     RequestSenseResponse.SenseKeySpecific[2] = 0x00;
270     for (i = 0; i < 14; i++){
271         RequestSenseResponse.padding[i] = 0x00;
272     }
273 }
274 
275 //----------------------------------------------------------------------------
276 
Check_CBW(BYTE intfNum,BYTE Dir_Dev_Exp,DWORD Bytes_Dev_Exp)277 BYTE Check_CBW (BYTE intfNum,BYTE Dir_Dev_Exp, DWORD Bytes_Dev_Exp)
278 {
279     if (McsCbw.CBWCB[0] == SCSI_INQUIRY || McsCbw.CBWCB[0] ==
280         SCSI_REQUEST_SENSE){
281         return (SUCCESS);
282     }
283 
284     if (Dir_Dev_Exp == McsCbw.bmCBWFlags){                  //all is right. Host is sending direction as expected by device
285         if (McsCbw.dCBWDataTransferLength < Bytes_Dev_Exp){ //Host expect less data to send or receive then device
286             MscState.Scsi_Status = SCSI_PHASE_ERROR;
287             MscState.Scsi_Residue = 0 ;
288             if (McsCbw.bmCBWFlags == DIRECTION_IN){
289                 usbStallInEndpoint(intfNum);
290             } else {
291                 usbStallOutEndpoint(intfNum);
292             }
293         } else if ((McsCbw.dCBWDataTransferLength > Bytes_Dev_Exp) &&
294                    (McsCbw.CBWCB[0] != SCSI_MODE_SENSE_6) &&
295                    (McsCbw.CBWCB[0] != SCSI_MODE_SENSE_10) &&
296                    (McsCbw.CBWCB[0] != SCSI_READ_TOC_PMA_ATIP)){
297             MscState.Scsi_Status = SCSI_FAILED;
298             MscState.Scsi_Residue = McsCbw.dCBWDataTransferLength -
299                                     Bytes_Dev_Exp;
300             if (McsCbw.bmCBWFlags == DIRECTION_IN){
301                 usbStallInEndpoint(intfNum);
302             } else {
303                 usbStallOutEndpoint(intfNum);
304             }
305         } else {
306             return ( SUCCESS) ;
307         }
308     } else {    //Direction mismatch
309         MscState.Scsi_Residue = McsCbw.dCBWDataTransferLength;
310         MscState.Scsi_Status = SCSI_FAILED;
311         if (McsCbw.bmCBWFlags == DIRECTION_IN){
312             usbStallInEndpoint(intfNum);
313         } else if ((McsCbw.bmCBWFlags == DIRECTION_OUT) &&
314                    (McsCbw.CBWCB[0] == SCSI_READ_10)){
315             usbStallOutEndpoint(intfNum);
316         }
317     }
318 
319     //Indicates a generic failure. Read/write failure/sense data is handled separately
320     if (MscState.Scsi_Status != SCSI_READWRITE_FAIL){
321         RequestSenseResponse.ResponseCode = RESCODE_CURRENT_ERROR;
322         RequestSenseResponse.VALID = 1;
323         RequestSenseResponse.AddSenseLen = 0xA0;
324         RequestSenseResponse.SenseKey = S_ILLEGAL_REQUEST;
325         RequestSenseResponse.ASC = ASC_INVALID_PARAMETER_LIST;
326         RequestSenseResponse.ASCQ = ASCQ_INVALID_PARAMETER_LIST;
327     }
328 
329     return (FAILURE);
330 }
331 
332 //----------------------------------------------------------------------------
Scsi_Verify_CBW()333 BYTE Scsi_Verify_CBW ()
334 {
335     /*(5.2.3) Devices must consider the CBW meaningful if no reserved bits
336      * are set, the LUN number indicates a LUN supported by the device,
337      * bCBWCBLength is in the range of 1 through 16, and the length and
338      * content of the CBWCB field are appropriate to the SubClass.
339      */
340     if ((MscState.bMscResetRequired || McsCbw.dCBWSignature !=
341          CBW_SIGNATURE) ||              //Check for correct CBW signature
342         ((McsCbw.bmCBWFlags != DIRECTION_IN && McsCbw.bmCBWFlags !=
343           DIRECTION_OUT) ||
344          (McsCbw.bCBWLUN & 0xF0) ||     //Upper bits have to be zero
345          (McsCbw.bCBWCBLength > 16))){  //maximum length is 16
346         MscState.bMscResetRequired = TRUE;
347         usbStallEndpoint(MSC0_INTFNUM);
348         usbClearOEPByteCount(MSC0_INTFNUM);
349         MscState.Scsi_Status = SCSI_FAILED;
350         MscState.Scsi_Residue = 0;
351         return (FAILURE);
352     }
353     MscState.Scsi_Status = SCSI_PASSED;
354     return (SUCCESS);
355 }
356 
357 //----------------------------------------------------------------------------
Scsi_Send_CSW(BYTE intfNum)358 BYTE Scsi_Send_CSW (BYTE intfNum)
359 {
360     BYTE retval = 0;
361 
362     //Populate the CSW to be sent
363     McsCsw.dCSWSignature = CSW_SIGNATURE;
364     McsCsw.dCSWTag = McsCbw.dCBWTag;
365     McsCsw.bCSWStatus = MscState.Scsi_Status;
366     McsCsw.dCSWDataResidue = MscState.Scsi_Residue;
367     retval = MscSendData((PBYTE)&McsCsw, CSW_LENGTH);   //Sending CSW
368     MscState.Scsi_Status = SCSI_PASSED;
369     return (retval);
370 }
371 
372 //----------------------------------------------------------------------------
373 
Scsi_Inquiry(BYTE intfNum)374 VOID Scsi_Inquiry (BYTE intfNum)
375 {
376     //int index;
377 
378     //clear the inquiry array
379     memset(Scsi_Standard_Inquiry_Data, 256, 0);
380     //copy the inquiry data from flash to RAM
381 
382     memcpy(Scsi_Standard_Inquiry_Data,
383         bScsi_Standard_Inquiry_Data,
384         SCSI_SCSI_INQUIRY_CMD_LEN);
385 
386 
387 
388     //get the values from USB_Config
389     Scsi_Standard_Inquiry_Data[1] = USBMSC_config.LUN[McsCbw.bCBWLUN].removable;
390     memcpy(&Scsi_Standard_Inquiry_Data[8],
391         USBMSC_config.LUN[McsCbw.bCBWLUN].t10VID,
392         8);
393     memcpy(&Scsi_Standard_Inquiry_Data[16],
394         USBMSC_config.LUN[McsCbw.bCBWLUN].t10PID,
395         16);
396     memcpy(&Scsi_Standard_Inquiry_Data[32],
397         USBMSC_config.LUN[McsCbw.bCBWLUN].t10rev,
398         4);
399 
400     if (McsCbw.dCBWDataTransferLength < SCSI_SCSI_INQUIRY_CMD_LEN){
401         if (McsCbw.dCBWDataTransferLength == 0){
402             MscState.Scsi_Residue = 0;
403             return;
404         }
405         if (SUCCESS ==
406             MscSendData((PBYTE)Scsi_Standard_Inquiry_Data,
407                 McsCbw.dCBWDataTransferLength)){
408             MscState.Scsi_Residue = 0;
409         } else {
410             MscState.Scsi_Status = SCSI_FAILED;
411         }
412     } else if (McsCbw.dCBWDataTransferLength > SCSI_SCSI_INQUIRY_CMD_LEN){
413         Reset_RequestSenseResponse();
414 
415         RequestSenseResponse.ResponseCode = RESCODE_CURRENT_ERROR;
416         RequestSenseResponse.VALID = 1;
417         RequestSenseResponse.SenseKey = S_ILLEGAL_REQUEST;
418         RequestSenseResponse.ASC = ASC_INVALID_FIELD_IN_CDB;
419         RequestSenseResponse.ASCQ = ASCQ_INVALID_FIELD_IN_CDB;
420         usbStallInEndpoint(intfNum);
421         MscState.Scsi_Status = SCSI_FAILED;
422     } else {
423         if (SUCCESS ==
424             MscSendData((PBYTE)Scsi_Standard_Inquiry_Data,
425                 SCSI_SCSI_INQUIRY_CMD_LEN)){
426             MscState.Scsi_Residue = 0;
427         } else {
428             MscState.Scsi_Status = SCSI_FAILED;
429         }
430     }
431 }
432 
433 //----------------------------------------------------------------------------
434 
Scsi_Read_Capacity10(BYTE intfNum)435 VOID Scsi_Read_Capacity10 (BYTE intfNum)
436 {
437     if (FAILURE == Check_CBW(intfNum,DIRECTION_IN,SCSI_READ_CAPACITY_CMD_LEN)){
438         return;
439     }
440     if (SUCCESS !=
441         MscSendData( (PBYTE)&Scsi_Read_Capacity_10[McsCbw.bCBWLUN],
442             SCSI_READ_CAPACITY_CMD_LEN)){
443         MscState.Scsi_Status = SCSI_FAILED;
444     }
445 }
446 
447 
448 //----------------------------------------------------------------------------
449 
Scsi_Read10(BYTE intfNum)450 VOID Scsi_Read10 (BYTE intfNum)
451 {
452     WORD wLBA_len;
453     unsigned short bGIE;
454     DWORD dLBA;
455 
456     /* Get first LBA: convert 4 bytes into DWORD */
457     dLBA = McsCbw.CBWCB[2];
458     dLBA <<= 8;
459     dLBA += McsCbw.CBWCB[3];
460     dLBA <<= 8;
461     dLBA += McsCbw.CBWCB[4];
462     dLBA <<= 8;
463     dLBA += McsCbw.CBWCB[5];
464 
465     /* Get number of requested logical blocks */
466     wLBA_len = McsCbw.CBWCB[7];
467     wLBA_len <<= 8;
468     wLBA_len += McsCbw.CBWCB[8];
469 
470     if (FAILURE ==
471         Check_CBW( intfNum, DIRECTION_IN, ((DWORD)wLBA_len) *
472             MscControl[McsCbw.bCBWLUN].lbaSize)){
473         return;
474     }
475 
476     bGIE  = (__get_SR_register() & GIE);    //save interrupt status
477     _DINT_FET();
478 
479     //Populating stack internal structure required for READ/WRITE
480     MscReadControl.lba = dLBA;              //the first LBA number.
481     MscReadControl.lbaCount = wLBA_len;     //how many LBAs to read.
482     MscReadControl.XorY = 0;
483 
484     sRwbuf.bufferAddr = MscControl[McsCbw.bCBWLUN].xBufferAddr;
485     sRwbuf.lun = McsCbw.bCBWLUN;
486 
487     //set LBA count
488     sRwbuf.lbCount = wLBA_len >
489         MscControl[McsCbw.bCBWLUN].lbaBufCapacity ?
490         MscControl[McsCbw.bCBWLUN].lbaBufCapacity : wLBA_len;
491     sRwbuf.operation = kUSBMSC_READ;
492     sRwbuf.lba = dLBA;
493     sRwbuf.returnCode = kUSBMSC_RWSuccess;
494     sRwbuf.XorY = 0;
495     sRwbuf.xBufFull = 0;
496     sRwbuf.xWordCnt = 0;
497     sRwbuf.yBufFull = 0;
498     sRwbuf.yWordCnt = 0;
499     sRwbuf.bufferProcessed = 0;
500     sRwbuf.firstFlag = 0;
501     //buffer is prepared, let user's Application fill data.
502     USBMSC_handleBufferEvent();
503 
504     __bis_SR_register(bGIE);                //restore interrupt status
505 }
506 
507 //----------------------------------------------------------------------------
508 
Scsi_Write10(BYTE intfNum)509 VOID Scsi_Write10 (BYTE intfNum)
510 {
511     WORD wLBA_len;
512     unsigned short bGIE;
513     /* Get first LBA: convert 4 bytes into DWORD */
514     DWORD dLBA = McsCbw.CBWCB[2];
515 
516     dLBA <<= 8;
517     dLBA += McsCbw.CBWCB[3];
518     dLBA <<= 8;
519     dLBA += McsCbw.CBWCB[4];
520     dLBA <<= 8;
521     dLBA += McsCbw.CBWCB[5];
522 
523     /* Get number of requested logical blocks */
524     wLBA_len = McsCbw.CBWCB[7];
525     wLBA_len <<= 8;
526     wLBA_len += McsCbw.CBWCB[8];
527 
528     if (FAILURE ==
529         Check_CBW(intfNum,DIRECTION_OUT,((DWORD)wLBA_len) *
530             MscControl[McsCbw.bCBWLUN].lbaSize)){
531         return;
532     }
533     bGIE = (__get_SR_register() & GIE);         //save interrupt status
534     _DINT_FET();
535 
536     //calculate the whole size to receive (Host to MSP430)
537     MscWriteControl.dwBytesToReceiveLeft = (DWORD)wLBA_len *
538         MscControl[McsCbw.bCBWLUN].lbaSize;
539     MscWriteControl.pUserBuffer = MscControl[McsCbw.bCBWLUN].xBufferAddr;
540     MscWriteControl.wFreeBytesLeft =
541         MscControl[McsCbw.bCBWLUN].wMscUserBufferSize;
542 
543     /*Populating stack internal structure required for READ/WRITE */
544 
545     MscWriteControl.bWriteProcessing = TRUE;    //indicate that we are in WRITE phase
546     MscWriteControl.lba = dLBA;
547     MscWriteControl.wCurrentByte = 0;           //reset internal variable
548     MscWriteControl.lbaCount = 0;               //reset internal variable
549     MscWriteControl.XorY = 0;
550 
551     sRwbuf.lun = McsCbw.bCBWLUN;
552     sRwbuf.operation = 0;
553     sRwbuf.lba = 0;
554     sRwbuf.lbCount = 0;
555     sRwbuf.bufferAddr = MscControl[McsCbw.bCBWLUN].xBufferAddr;
556     sRwbuf.returnCode = 0;
557     sRwbuf.XorY = 0;
558     sRwbuf.xBufFull = 0;
559     sRwbuf.yBufFull = 0;
560     sRwbuf.bufferProcessed = 0;
561     sRwbuf.firstFlag = 0;
562     sRwbuf.xlba = 0;
563     sRwbuf.xlbaCount = 0;
564     sRwbuf.ylba = 0;
565     sRwbuf.ylbaCount = 0;
566 
567     __bis_SR_register(bGIE);                    //restore interrupt status
568 }
569 
570 //----------------------------------------------------------------------------
571 
Scsi_Mode_Sense6(BYTE intfNum)572 VOID Scsi_Mode_Sense6 (BYTE intfNum)
573 {
574     if (FAILURE == Check_CBW(intfNum,DIRECTION_IN,SCSI_MODE_SENSE_6_CMD_LEN)){
575         return;
576     }
577     /* Fix for SDOCM00077834 - Set WP bit. WP bit is BIT7 in byte 3 */
578     Scsi_Mode_Sense_6[2] |= (MscControl[McsCbw.bCBWLUN].bWriteProtected << 0x7);
579 
580     if (SUCCESS !=
581         MscSendData((PBYTE)Scsi_Mode_Sense_6, SCSI_MODE_SENSE_6_CMD_LEN)){
582         MscState.Scsi_Status = SCSI_FAILED;
583     }
584 }
585 
586 //----------------------------------------------------------------------------
587 
Scsi_Mode_Sense10(BYTE intfNum)588 VOID Scsi_Mode_Sense10 (BYTE intfNum)
589 {
590     if (FAILURE == Check_CBW(intfNum,DIRECTION_IN,SCSI_MODE_SENSE_10_CMD_LEN)){
591         return;
592     }
593     /* Fix for SDOCM00077834 - Set WP bit. WP bit is BIT7 in byte 3 */
594     Scsi_Mode_Sense_10[4] |= (MscControl[McsCbw.bCBWLUN].bWriteProtected << 0x7);
595 
596     if (SUCCESS !=
597         MscSendData((PBYTE)Scsi_Mode_Sense_10, SCSI_MODE_SENSE_10_CMD_LEN)){
598         MscState.Scsi_Status = SCSI_FAILED;
599     }
600 }
601 
602 //----------------------------------------------------------------------------
603 
Scsi_Request_Sense(BYTE intfNum)604 VOID Scsi_Request_Sense (BYTE intfNum)
605 {
606     if (FAILURE == Check_CBW(intfNum,DIRECTION_IN,SCSI_REQ_SENSE_CMD_LEN)){
607         return;
608     }
609 
610     //If there is attention needed, setup the request sense response. The
611     //bUnitAttention flag is set in USBMSC_updateMediaInfo() when the volume
612     //is removed or inserted. Note that the response is different for the
613     //removed and inserted case.
614     if (MscState.bUnitAttention == TRUE){
615         //Check if the volume was removed.
616         if (MscControl[McsCbw.bCBWLUN].bMediaPresent ==
617             kUSBMSC_MEDIA_NOT_PRESENT){
618             Reset_RequestSenseResponse();
619             RequestSenseResponse.VALID = 1;
620             RequestSenseResponse.SenseKey = S_NOT_READY;
621             RequestSenseResponse.ASC = ASC_MEDIUM_NOT_PRESENT;
622             RequestSenseResponse.ASCQ = ASCQ_MEDIUM_NOT_PRESENT;
623         }
624         //Otherwise it was inserted.
625         else {
626             Reset_RequestSenseResponse();
627             RequestSenseResponse.VALID = 1;
628             RequestSenseResponse.SenseKey = S_UNITATTN;
629             RequestSenseResponse.ASC = ASC_UNITATTN_READY_NOTREADY;
630             RequestSenseResponse.ASCQ = ASCQ_UNITATTN_READY_NOTREADY;
631         }
632     }
633 
634     if (McsCbw.dCBWDataTransferLength < SCSI_REQ_SENSE_CMD_LEN){
635         if (SUCCESS ==
636             MscSendData((PBYTE)&RequestSenseResponse,
637                 McsCbw.dCBWDataTransferLength)){
638             MscState.Scsi_Residue = 0;
639         } else {
640             MscState.Scsi_Status = SCSI_FAILED;
641         }
642     } else if (McsCbw.dCBWDataTransferLength > SCSI_REQ_SENSE_CMD_LEN){
643         RequestSenseResponse.AddSenseLen +=
644             (McsCbw.dCBWDataTransferLength -  SCSI_REQ_SENSE_CMD_LEN);
645         if (SUCCESS ==
646             MscSendData((PBYTE)&RequestSenseResponse,
647                 McsCbw.dCBWDataTransferLength)){
648             MscState.Scsi_Residue = 0;
649         } else {
650             MscState.Scsi_Status = SCSI_FAILED;
651         }
652     } else {
653         if (SUCCESS ==
654             MscSendData((PBYTE)&RequestSenseResponse,SCSI_REQ_SENSE_CMD_LEN)){
655             MscState.Scsi_Residue = 0;
656         } else {
657             MscState.Scsi_Status = SCSI_FAILED;
658         }
659     }
660 
661     //Clear the bUnitAttention flag after the response was properly sent via
662     //MscSendData().
663     if (MscState.bUnitAttention == TRUE){
664         MscState.bUnitAttention = FALSE;
665     }
666 }
667 
668 //----------------------------------------------------------------------------
669 
Scsi_Test_Unit_Ready(BYTE intfNum)670 VOID Scsi_Test_Unit_Ready (BYTE intfNum)
671 {
672     if (SUCCESS != Check_CBW(intfNum,DIRECTION_OUT,0)){
673         MscState.Scsi_Status = SCSI_FAILED;
674     }
675 
676     Reset_RequestSenseResponse();
677 }
678 
679 //----------------------------------------------------------------------------
680 
Scsi_Unknown_Request(BYTE intfNum)681 VOID Scsi_Unknown_Request (BYTE intfNum)
682 {
683     Reset_RequestSenseResponse();
684 
685     RequestSenseResponse.ResponseCode = RESCODE_CURRENT_ERROR;
686     RequestSenseResponse.VALID = 1;
687     RequestSenseResponse.AddSenseLen = 0xA0;
688     RequestSenseResponse.SenseKey = S_ILLEGAL_REQUEST;
689     RequestSenseResponse.ASC = ASC_INVALID_COMMAND_OP_CODE;
690     RequestSenseResponse.ASCQ = ASCQ_INVALID_COMMAND_OP_CODE;
691     MscState.Scsi_Residue = 0;
692     MscState.Scsi_Status = SCSI_FAILED;
693 
694     if (McsCbw.dCBWDataTransferLength && (McsCbw.bmCBWFlags == DIRECTION_IN)){
695         MscState.bMcsCommandSupported = FALSE;
696         usbStallInEndpoint(intfNum);
697     }
698     if (McsCbw.dCBWDataTransferLength && (McsCbw.bmCBWFlags == DIRECTION_OUT)){
699         MscState.bMcsCommandSupported = FALSE;
700         usbStallOutEndpoint(intfNum);
701     }
702 }
703 
704 //----------------------------------------------------------------------------
705 
Scsi_Report_Luns(BYTE intfNum)706 VOID Scsi_Report_Luns (BYTE intfNum)
707 {
708     if (FAILURE ==
709         Check_CBW( intfNum, DIRECTION_IN, SCSI_REPORT_LUNS_CMD_LEN)){
710         return;
711     }
712     if (SUCCESS !=
713         MscSendData( (PBYTE)&Report_Luns, SCSI_REPORT_LUNS_CMD_LEN)){
714         MscState.Scsi_Status = SCSI_FAILED;
715     }
716 }
717 
718 //----------------------------------------------------------------------------
719 
Scsi_Cmd_Parser(BYTE intfNum)720 BYTE Scsi_Cmd_Parser (BYTE intfNum)
721 {
722     BYTE ret = kUSBMSC_cmdBeingProcessed;
723 
724     //MscState.Scsi_Status = SCSI_FAILED;
725     MscState.Scsi_Residue = McsCbw.dCBWDataTransferLength;
726 
727     //fails the commands during UNIT ATTENTION
728     if ((MscState.bUnitAttention) && (McsCbw.CBWCB[0] != SCSI_INQUIRY) &&
729         (McsCbw.CBWCB[0] != SCSI_REQUEST_SENSE)){
730         MscState.Scsi_Status = SCSI_FAILED;
731         return (kUSB_generalError);
732     }
733 
734     if (!McsCbw.bCBWCBLength){
735         return (kUSB_generalError);
736     }
737 
738     switch (McsCbw.CBWCB[0])                                        //SCSI Operation code
739     {
740         case SCSI_READ_10:
741             if (MscControl[McsCbw.bCBWLUN].xBufferAddr == NULL){    //Check for null address.
742                 ret = kUSB_generalError;
743                 SET_RequestsenseNotReady();
744                 MscState.Scsi_Status = SCSI_FAILED;
745                 usbStallInEndpoint(intfNum);
746                 break;
747             }
748 
749             if (MscControl[McsCbw.bCBWLUN].bMediaPresent ==
750                 kUSBMSC_MEDIA_NOT_PRESENT){                         //Check for media present. Do this for any command that accesses
751                                                                     //media.
752                 ret = kUSB_generalError;
753                 SET_RequestsenseMediaNotPresent();
754                 usbStallInEndpoint(intfNum);
755                 break;
756             }
757             Scsi_Read10(intfNum);
758             break;
759 
760         case SCSI_WRITE_10:
761             if (MscControl[McsCbw.bCBWLUN].xBufferAddr == NULL){    //Check for null address.
762                 ret = kUSB_generalError;
763                 SET_RequestsenseNotReady();
764                 MscState.Scsi_Status = SCSI_FAILED;
765                 break;
766             }
767 
768             if (MscControl[McsCbw.bCBWLUN].bMediaPresent ==
769                 kUSBMSC_MEDIA_NOT_PRESENT){                         //Check for media present. Do this for any command that accesses
770                                                                     //media.
771                 ret = kUSB_generalError;
772                 SET_RequestsenseMediaNotPresent();
773                 usbStallOutEndpoint(intfNum);
774                 break;
775             }
776 
777             if (MscControl[McsCbw.bCBWLUN].bWriteProtected){        //Do this only for WRITE
778                 ret = kUSB_generalError;
779                                                                     //Set REQUEST SENSE with "write protected"
780                 Reset_RequestSenseResponse();
781                 RequestSenseResponse.VALID = 1;
782                 RequestSenseResponse.SenseKey = S_WRITE_PROTECTED;
783                 RequestSenseResponse.ASC = ASC_WRITE_PROTECTED;
784                 RequestSenseResponse.ASCQ = ASCQ_WRITE_PROTECTED;
785                 MscWriteControl.bWriteProcessing = FALSE;
786                                                                     //Send CSW with error status
787                 MscState.Scsi_Residue = 1;
788                 MscState.Scsi_Status = SCSI_FAILED;
789                 usbStallOutEndpoint(intfNum);
790                 break;
791             }
792 
793             Scsi_Write10(intfNum);
794             break;
795 
796         case START_STOP_UNIT:
797         case PREVENT_ALLW_MDM:
798         case SCSI_MODE_SELECT_10:
799         case SCSI_MODE_SELECT_6:
800         case SCSI_TEST_UNIT_READY:
801             if (MscControl[McsCbw.bCBWLUN].bMediaPresent ==
802                 kUSBMSC_MEDIA_NOT_PRESENT){                         //Check for media present. Do this for any command that accesses
803                                                                     //media.
804                 ret = kUSB_generalError;
805                 SET_RequestsenseMediaNotPresent();
806                 break;
807             }
808             Scsi_Test_Unit_Ready(intfNum);
809             break;
810 
811         case SCSI_SET_CD_SPEED:
812             break;
813         case SCSI_INQUIRY:
814             Scsi_Inquiry(intfNum);
815             break;
816 
817         case SCSI_MODE_SENSE_6:
818             Scsi_Mode_Sense6(intfNum);
819             break;
820 
821         case SCSI_MODE_SENSE_10:
822             Scsi_Mode_Sense10(intfNum);
823             break;
824 
825         case SCSI_READ_CAPACITY_10:
826             if (MscControl[McsCbw.bCBWLUN].bMediaPresent ==
827                 kUSBMSC_MEDIA_NOT_PRESENT){             //Check for media present. Do this for any command that accesses media.
828                 ret = kUSB_generalError;
829                 SET_RequestsenseMediaNotPresent();
830                 usbStallInEndpoint(intfNum);
831                 break;
832             }
833             Scsi_Read_Capacity10(intfNum);
834             break;
835 
836         case SCSI_REQUEST_SENSE:
837             Scsi_Request_Sense(intfNum);
838             break;
839 
840         case SCSI_REPORT_LUNS:
841             if (MscControl[McsCbw.bCBWLUN].bMediaPresent ==
842                 kUSBMSC_MEDIA_NOT_PRESENT){             //Check for media present. Do this for any command that accesses media.
843                 ret = kUSB_generalError;
844                 SET_RequestsenseMediaNotPresent();
845                 if (McsCbw.bmCBWFlags == DIRECTION_IN){
846                     usbStallInEndpoint(intfNum);
847                 } else {
848                     usbStallOutEndpoint(intfNum);
849                 }
850                 break;
851             }
852             Scsi_Report_Luns(intfNum);
853             break;
854         case SCSI_VERIFY:
855                                                         /* Fix for SDOCM00078183 */
856                                                         /* NOTE: we are assuming that BYTCHK=0 and PASSing the command. */
857             break;
858 #ifdef CDROM_SUPPORT
859 
860         case SCSI_READ_TOC_PMA_ATIP:
861             if (MscControl[McsCbw.bCBWLUN].bMediaPresent ==
862                 kUSBMSC_MEDIA_NOT_PRESENT){             //Check for media present. Do this for any command that accesses media.
863                 ret = kUSB_generalError;
864                 SET_RequestsenseMediaNotPresent();
865                 usbStallInEndpoint(intfNum);
866                 break;
867             }
868             Scsi_Read_TocPmaAtip(intfNum);
869             break;
870 
871         case SCSI_GET_CONFIGURATION:
872                 if (MscControl[McsCbw.bCBWLUN].bMediaPresent ==
873                     kUSBMSC_MEDIA_NOT_PRESENT){             //Check for media present. Do this for any command that accesses media.
874                         ret = kUSB_generalError;
875                         SET_RequestsenseMediaNotPresent();
876                         usbStallInEndpoint(intfNum);
877                         break;
878                 }
879                 Scsi_Get_Configuration(intfNum);
880                 break;
881         case SCSI_EVENT_STATUS:
882                 if (MscControl[McsCbw.bCBWLUN].bMediaPresent ==
883                     kUSBMSC_MEDIA_NOT_PRESENT){             //Check for media present. Do this for any command that accesses media.
884                         ret = kUSB_generalError;
885                         SET_RequestsenseMediaNotPresent();
886                         usbStallInEndpoint(intfNum);
887                         break;
888                 }
889                 Scsi_Event_Status_Notification(intfNum);
890                 break;
891 
892         case SCSI_READ_DISC_INFORMATION:
893 
894                 if (MscControl[McsCbw.bCBWLUN].bMediaPresent ==
895                     kUSBMSC_MEDIA_NOT_PRESENT){             //Check for media present. Do this for any command that accesses media.
896                         ret = kUSB_generalError;
897                         SET_RequestsenseMediaNotPresent();
898                         usbStallInEndpoint(intfNum);
899                         break;
900                 }
901 
902                 Scsi_Read_Disc_Information(intfNum);
903                 break;
904 #endif
905         default:
906             ret = kUSB_generalError;
907             Scsi_Unknown_Request(intfNum);
908             break;
909     }
910     return (ret);
911 }
912 
913 //-------------------------------------------------------------------------------------------------------
914 /* This function is called only from ISR(only on Input endpoint interrupt to transfer data to host)
915  * This function actually performs the data transfer to host Over USB */
MSCToHostFromBuffer()916 BOOL MSCToHostFromBuffer ()
917 {
918     //Check if there are any pending LBAs to process
919     BYTE * pEP1;
920     BYTE * pEP2;
921     BYTE * pCT1;
922     BYTE * pCT2;
923     BYTE bWakeUp = FALSE;                               //per default we do not wake up after interrupt
924     BYTE edbIndex;
925     BYTE bCount;
926 
927     if (MscControl[sRwbuf.lun].yBufferAddr == NULL) {
928         //Check if there are any pending data to send
929         if (MscReadControl.dwBytesToSendLeft == 0){
930             //no more data to send - clear ready busy status
931             MscReadControl.bReadProcessing = FALSE;
932 
933             //check if more LBA to send out pending...
934             if (MscReadControl.lbaCount > 0){
935                 sRwbuf.lba = MscReadControl.lba;            //update current lba
936                 sRwbuf.lbCount = MscControl[sRwbuf.lun].lbaBufCapacity >
937                                  MscReadControl.lbaCount ?
938                                  MscReadControl.lbaCount : MscControl[sRwbuf.lun].
939                                  lbaBufCapacity;            //update LBA count
940                 sRwbuf.operation = kUSBMSC_READ;            //start data READ phase
941                 sRwbuf.returnCode = kUSBMSC_RWSuccess;
942                 sRwbuf.bufferAddr = MscControl[sRwbuf.lun].xBufferAddr;
943                 sRwbuf.XorY = 0;                        //only one buffer is active
944                 //buffer is prepared, let user's Application fill data.
945                 USBMSC_handleBufferEvent();
946             }
947             return (TRUE);                                  //data sent out - wake up!
948         }
949     }
950     else {
951         if ((MscReadControl.lbaCount > 0) && (sRwbuf.bufferProcessed == 1)) {
952         if ((sRwbuf.XorY == 0) && (sRwbuf.yBufFull == 0)){
953             sRwbuf.bufferProcessed = 0;
954             sRwbuf.XorY = 1;
955             sRwbuf.bufferAddr = MscControl[sRwbuf.lun].yBufferAddr;
956                 sRwbuf.lba = MscReadControl.lba;            //update current lba
957                 sRwbuf.lbCount = MscControl[sRwbuf.lun].lbaBufCapacity >
958                                  MscReadControl.lbaCount ?
959                                  MscReadControl.lbaCount : MscControl[sRwbuf.lun].
960                                  lbaBufCapacity;            //update LBA count
961                 sRwbuf.operation = kUSBMSC_READ;            //start data READ phase
962                 sRwbuf.returnCode = kUSBMSC_RWSuccess;
963                 //buffer is prepared, let user's Application fill data.
964                 USBMSC_handleBufferEvent();
965         }
966         else if ((sRwbuf.XorY == 1) && (sRwbuf.xBufFull == 0)){
967             sRwbuf.bufferProcessed = 0;
968             sRwbuf.XorY = 0;
969             sRwbuf.bufferAddr = MscControl[sRwbuf.lun].xBufferAddr;
970                 sRwbuf.lba = MscReadControl.lba;            //update current lba
971                 sRwbuf.lbCount = MscControl[sRwbuf.lun].lbaBufCapacity >
972                                  MscReadControl.lbaCount ?
973                                  MscReadControl.lbaCount : MscControl[sRwbuf.lun].
974                                  lbaBufCapacity;            //update LBA count
975                 sRwbuf.operation = kUSBMSC_READ;            //start data READ phase
976                 sRwbuf.returnCode = kUSBMSC_RWSuccess;
977                 //buffer is prepared, let user's Application fill data.
978                 USBMSC_handleBufferEvent();
979         }
980         }
981 
982         //Check if there are any pending data to send
983         if (MscReadControl.dwBytesToSendLeft == 0){
984             //no more data to send - clear ready busy status
985             MscReadControl.bReadProcessing = FALSE;
986 
987             if (MscReadControl.XorY == 0) {
988                 sRwbuf.xBufFull = 0;
989                 sRwbuf.xWordCnt = 0;
990                 if (sRwbuf.yBufFull) {
991                     MscSendData(MscControl[sRwbuf.lun].yBufferAddr, sRwbuf.yWordCnt);
992                     MscReadControl.XorY = 1;
993                 }
994             }
995             else {
996                 sRwbuf.yBufFull = 0;
997                 sRwbuf.yWordCnt = 0;
998                 if (sRwbuf.xBufFull) {
999                     MscSendData(MscControl[sRwbuf.lun].xBufferAddr, sRwbuf.xWordCnt);
1000                     MscReadControl.XorY = 0;
1001                 }
1002             }
1003 
1004             return (TRUE);                                  //data sent out - wake up!
1005         }
1006     }
1007 
1008 
1009     edbIndex = stUsbHandle[MSC0_INTFNUM].edb_Index;
1010 
1011     //check if the endpoint is stalled = do not send data.
1012     if (tInputEndPointDescriptorBlock[edbIndex].bEPCNF & EPCNF_STALL){
1013         return (TRUE);
1014     }
1015 
1016     //send one chunk of 64 bytes
1017     //check what is current buffer: X or Y
1018     if (MscReadControl.bCurrentBufferXY == X_BUFFER){   //X is current buffer
1019         //this is the active EP buffer
1020         pEP1 = (BYTE*)stUsbHandle[MSC0_INTFNUM].iep_X_Buffer;
1021         pCT1 = &tInputEndPointDescriptorBlock[edbIndex].bEPBCTX;
1022 
1023         //second EP buffer
1024         pEP2 = (BYTE*)stUsbHandle[MSC0_INTFNUM].iep_Y_Buffer;
1025         pCT2 = &tInputEndPointDescriptorBlock[edbIndex].bEPBCTY;
1026     } else {
1027         //this is the active EP buffer
1028         pEP1 = (BYTE*)stUsbHandle[MSC0_INTFNUM].iep_Y_Buffer;
1029         pCT1 = &tInputEndPointDescriptorBlock[edbIndex].bEPBCTY;
1030 
1031         //second EP buffer
1032         pEP2 = (BYTE*)stUsbHandle[MSC0_INTFNUM].iep_X_Buffer;
1033         pCT2 = &tInputEndPointDescriptorBlock[edbIndex].bEPBCTX;
1034     }
1035 
1036     //how many byte we can send over one endpoint buffer
1037     bCount =
1038         (MscReadControl.dwBytesToSendLeft >
1039          EP_MAX_PACKET_SIZE) ? EP_MAX_PACKET_SIZE : MscReadControl.
1040         dwBytesToSendLeft;
1041 
1042     if (*pCT1 & EPBCNT_NAK){
1043         USB_TX_memcpy(pEP1, MscReadControl.pUserBuffer, bCount);    //copy data into IEPx X or Y buffer
1044         *pCT1 = bCount;                                             //Set counter for usb In-Transaction
1045         MscReadControl.bCurrentBufferXY =
1046             (MscReadControl.bCurrentBufferXY + 1) & 0x01;           //switch buffer
1047         MscReadControl.dwBytesToSendLeft -= bCount;
1048         MscReadControl.pUserBuffer += bCount;                       //move buffer pointer
1049 
1050         //try to send data over second buffer
1051         if ((MscReadControl.dwBytesToSendLeft > 0) &&               //do we have more data to send?
1052             (*pCT2 & EPBCNT_NAK)){                                  //if the second buffer is free?
1053             //how many byte we can send over one endpoint buffer
1054             bCount =
1055                 (MscReadControl.dwBytesToSendLeft >
1056                  EP_MAX_PACKET_SIZE) ? EP_MAX_PACKET_SIZE : MscReadControl.
1057                 dwBytesToSendLeft;
1058             //copy data into IEPx X or Y buffer
1059             USB_TX_memcpy(pEP2, MscReadControl.pUserBuffer, bCount);
1060             //Set counter for usb In-Transaction
1061             *pCT2 = bCount;
1062             //switch buffer
1063             MscReadControl.bCurrentBufferXY =
1064                 (MscReadControl.bCurrentBufferXY + 1) & 0x01;
1065             MscReadControl.dwBytesToSendLeft -= bCount;
1066             //move buffer pointer
1067             MscReadControl.pUserBuffer += bCount;
1068         }
1069     } //if(*pCT1 & EPBCNT_NAK)
1070     return (bWakeUp);
1071 }
1072 
1073 //------------------------------------------------------------------------------------------------------
1074 
1075 //This function used to initialize the sending process.
1076 //Use this by functiosn for send CSW or send LBA
1077 //To use only by STACK itself, not by application
1078 //Returns: SUCCESS or FAILURE
MscSendData(const BYTE * data,WORD size)1079 BYTE MscSendData (const BYTE* data, WORD size)
1080 {
1081     BYTE edbIndex;
1082     unsigned short bGIE;
1083 
1084     edbIndex = stUsbHandle[MSC0_INTFNUM].edb_Index;
1085 
1086     if (size == 0){
1087         return (FAILURE);
1088     }
1089 
1090     bGIE  = (__get_SR_register() & GIE);            //save interrupt status
1091     //atomic operation - disable interrupts
1092     _DINT_FET();                          //Disable global interrupts
1093 
1094     //do not access USB memory if suspended (PLL off). It may produce BUS_ERROR
1095     if ((bFunctionSuspended) ||
1096         (bEnumerationStatus != ENUMERATION_COMPLETE)){
1097         //data can not be read because of USB suspended
1098         __bis_SR_register(bGIE);                    //restore interrupt status
1099         return (FAILURE);
1100     }
1101 
1102     if ((MscReadControl.dwBytesToSendLeft != 0) ||  //data was not sent out
1103         (MscReadControl.bReadProcessing == TRUE)){  //still processing previous data
1104         //the USB still sends previous data, we have to wait
1105         __bis_SR_register(bGIE);                    //restore interrupt status
1106         return (FAILURE);
1107     }
1108 
1109     //This function generate the USB interrupt. The data will be sent out from interrupt
1110 
1111     MscReadControl.bReadProcessing = TRUE;          //set reading busy status.
1112     MscReadControl.dwBytesToSendLeft = size;
1113     MscReadControl.pUserBuffer = (BYTE*)data;
1114 
1115     //trigger Endpoint Interrupt - to start send operation
1116     USBIEPIFG |= 1 << (edbIndex + 1);               //IEPIFGx;
1117 
1118     __bis_SR_register(bGIE);                        //restore interrupt status
1119 
1120     return (SUCCESS);
1121 }
1122 
1123 //This function copies data from OUT endpoint into user's buffer
1124 //This function to call only from MSCFromHostToBuffer()
1125 //Arguments:
1126 //pEP - pointer to EP to copy from
1127 //pCT - pointer to EP control reg
1128 //
MscCopyUsbToBuff(BYTE * pEP,BYTE * pCT)1129 VOID MscCopyUsbToBuff (BYTE* pEP, BYTE* pCT)
1130 {
1131     BYTE nCount;
1132 
1133     nCount = *pCT & (~EPBCNT_NAK);
1134 
1135     //how many bytes we can receive to avoid overflow
1136     nCount =
1137         (nCount >
1138          MscWriteControl.dwBytesToReceiveLeft) ? MscWriteControl.
1139         dwBytesToReceiveLeft :
1140         nCount;
1141 
1142     USB_RX_memcpy(MscWriteControl.pUserBuffer, pEP, nCount);    //copy data from OEPx X or Y buffer
1143     MscWriteControl.dwBytesToReceiveLeft -= nCount;
1144     MscWriteControl.pUserBuffer += nCount;                      //move buffer pointer
1145                                                                 //to read rest of data next time from this place
1146     MscWriteControl.wFreeBytesLeft -= nCount;                   //update counter
1147 
1148     MscWriteControl.wCurrentByte += nCount;
1149     if (MscWriteControl.wCurrentByte >= MscControl[sRwbuf.lun].lbaSize){
1150         MscWriteControl.wCurrentByte = 0;
1151         MscWriteControl.lbaCount++;
1152     }
1153 
1154     //switch current buffer
1155     MscWriteControl.bCurrentBufferXY =
1156         (MscWriteControl.bCurrentBufferXY + 1) & 0x01;
1157 
1158     //clear NAK, EP ready to receive data
1159     *pCT = 0x00;
1160 }
1161 
1162 //------------------------------------------------------------------------------------------------------
1163 /* This function is called only from ISR(only on Output endpoint interrupt, to recv data from host)
1164  * This function actually recieves the data from host Over USB */
MSCFromHostToBuffer()1165 BOOL MSCFromHostToBuffer ()
1166 {
1167     BYTE * pEP1;
1168     BYTE nTmp1;
1169     BYTE bWakeUp = FALSE;                                   //per default we do not wake up after interrupt
1170     BYTE edbIndex;
1171 
1172     edbIndex = stUsbHandle[MSC0_INTFNUM].edb_Index;
1173 
1174     if (MscState.stallEndpoint == TRUE) {
1175         tOutputEndPointDescriptorBlock[edbIndex].bEPCNF |= EPCNF_STALL;
1176         return TRUE;
1177     }
1178 
1179     if (MscState.bMscCbwReceived == TRUE){
1180         //previous CBW is not performed, so exit interrupt hendler
1181         //and trigger it again later
1182         return (TRUE);                                      //true for wake up!
1183     }
1184 
1185     if (!MscWriteControl.bWriteProcessing){                 //receiving CBW
1186         //CBW will be received here....
1187         //check what is current buffer: X or Y
1188         if (MscWriteControl.bCurrentBufferXY == X_BUFFER){  //X is current buffer
1189             //this is the active EP buffer
1190             pEP1 = (BYTE*)stUsbHandle[MSC0_INTFNUM].oep_X_Buffer;
1191             MscWriteControl.pCT1 =
1192                 &tOutputEndPointDescriptorBlock[edbIndex].bEPBCTX;
1193             MscWriteControl.pCT2 =
1194                 &tOutputEndPointDescriptorBlock[edbIndex].bEPBCTY;
1195         } else {
1196             //this is the active EP buffer
1197             pEP1 = (BYTE*)stUsbHandle[MSC0_INTFNUM].oep_Y_Buffer;
1198             MscWriteControl.pCT1 =
1199                 &tOutputEndPointDescriptorBlock[edbIndex].bEPBCTY;
1200             MscWriteControl.pCT2 =
1201                 &tOutputEndPointDescriptorBlock[edbIndex].bEPBCTX;
1202         }
1203 
1204         //how many byte we can get from one endpoint buffer
1205         nTmp1 = *MscWriteControl.pCT1;
1206 
1207         if (nTmp1 & EPBCNT_NAK){
1208             BYTE nCount;
1209 
1210             //switch current buffer
1211             MscWriteControl.bCurrentBufferXY =
1212                 (MscWriteControl.bCurrentBufferXY + 1) & 0x01;
1213 
1214             nTmp1 = nTmp1 & 0x7f;                           //clear NAK bit
1215             nCount = (nTmp1 > sizeof(McsCbw)) ? sizeof(McsCbw) : nTmp1;
1216             USB_RX_memcpy(&McsCbw, pEP1, nCount);           //copy data from OEPx X or Y buffer
1217 
1218             //clear NAK, EP ready to receive data
1219             *MscWriteControl.pCT1 = 0x00;
1220 
1221             //set flag and check the CBW from the usbmsc_poll
1222             MscState.bMscCbwReceived = TRUE;
1223 
1224             //second 64b buffer will be not read out here because the CBW is <64 bytes
1225         }
1226 
1227         bWakeUp = TRUE;                                     //wake up to perform CBW
1228         return (bWakeUp);
1229     }
1230 
1231     //if we are here - LBAs will be received
1232     if (MscControl[sRwbuf.lun].yBufferAddr == NULL) {
1233 
1234         /*Check if there are any pending LBAs to process */
1235         if (MscWriteControl.dwBytesToReceiveLeft > 0){
1236             //read one chunk of 64 bytes
1237 
1238             //check what is current buffer: X or Y
1239             if (MscWriteControl.bCurrentBufferXY == X_BUFFER){  //X is current buffer
1240                 //this is the active EP buffer
1241                 pEP1 = (BYTE*)stUsbHandle[MSC0_INTFNUM].oep_X_Buffer;
1242                 MscWriteControl.pCT1 =
1243                     &tOutputEndPointDescriptorBlock[edbIndex].bEPBCTX;
1244 
1245                 //second EP buffer
1246                 MscWriteControl.pEP2 =
1247                     (BYTE*)stUsbHandle[MSC0_INTFNUM].oep_Y_Buffer;
1248                 MscWriteControl.pCT2 =
1249                     &tOutputEndPointDescriptorBlock[edbIndex].bEPBCTY;
1250             } else {
1251                 //this is the active EP buffer
1252                 pEP1 = (BYTE*)stUsbHandle[MSC0_INTFNUM].oep_Y_Buffer;
1253                 MscWriteControl.pCT1 =
1254                     &tOutputEndPointDescriptorBlock[edbIndex].bEPBCTY;
1255 
1256                 //second EP buffer
1257                 MscWriteControl.pEP2 =
1258                     (BYTE*)stUsbHandle[MSC0_INTFNUM].oep_X_Buffer;
1259                 MscWriteControl.pCT2 =
1260                     &tOutputEndPointDescriptorBlock[edbIndex].bEPBCTX;
1261             }
1262 
1263             //how many byte we can get from one endpoint buffer
1264             nTmp1 = *MscWriteControl.pCT1;
1265 
1266             if ((nTmp1 & EPBCNT_NAK) &&
1267                 (MscWriteControl.wFreeBytesLeft >= 64)){
1268                 //copy data from Endpoint
1269                 MscCopyUsbToBuff(pEP1, MscWriteControl.pCT1);
1270 
1271                 nTmp1 = *MscWriteControl.pCT2;
1272 
1273                 //try read data from second buffer
1274                 if ((MscWriteControl.dwBytesToReceiveLeft > 0) &&   //do we have more data to send?
1275                     (MscWriteControl.wFreeBytesLeft >= 64) &&
1276                     (nTmp1 & EPBCNT_NAK)){                          //if the second buffer has received data?
1277                     //copy data from Endpoint
1278                     MscCopyUsbToBuff(MscWriteControl.pEP2, MscWriteControl.pCT2);
1279                     //MscWriteControl.pCT1 = MscWriteControl.pCT2;
1280                 }
1281 
1282                 if ((MscWriteControl.wFreeBytesLeft == 0) ||        //user's buffer is full, give it to User
1283                     (MscWriteControl.dwBytesToReceiveLeft == 0)){   //or no bytes to read left - give it to User
1284                     sRwbuf.operation = kUSBMSC_WRITE;
1285                     sRwbuf.lba = MscWriteControl.lba;               //copy lba number
1286                     MscWriteControl.lba += MscWriteControl.lbaCount;
1287                     sRwbuf.lbCount = MscWriteControl.lbaCount;      //copy lba count
1288                     MscWriteControl.wCurrentByte = 0;
1289                     MscWriteControl.lbaCount = 0;
1290 
1291                     //call event handler, we are ready with data
1292                     bWakeUp = USBMSC_handleBufferEvent();
1293                 } //if (wFreeBytesLeft == 0)
1294             }
1295         } //if (MscWriteControl.dwBytesToReceiveLeft > 0)
1296         else {
1297             //perform error handling here, if required.
1298             bWakeUp = TRUE;
1299         }
1300     }
1301     else {
1302         //if we are here - LBAs will be received
1303         if (sRwbuf.bufferProcessed == 1) {
1304             if (sRwbuf.XorY == 0) {
1305                 sRwbuf.xBufFull = 0;
1306                 if (sRwbuf.yBufFull) {
1307                     sRwbuf.bufferProcessed = 0;
1308                     sRwbuf.XorY = 1;
1309                     sRwbuf.bufferAddr = MscControl[McsCbw.bCBWLUN].yBufferAddr;
1310                     sRwbuf.operation = kUSBMSC_WRITE;
1311                     sRwbuf.lba = sRwbuf.ylba;               //copy lba number
1312                     sRwbuf.lbCount = sRwbuf.ylbaCount;      //copy lba count
1313 
1314                     //call event handler, we are ready with data
1315                     bWakeUp = USBMSC_handleBufferEvent();
1316                 }
1317             }
1318             else {
1319                 sRwbuf.yBufFull = 0;
1320                 if (sRwbuf.xBufFull) {
1321                     sRwbuf.bufferProcessed = 0;
1322                     sRwbuf.XorY = 0;
1323                     sRwbuf.bufferAddr = MscControl[McsCbw.bCBWLUN].xBufferAddr;
1324                     sRwbuf.operation = kUSBMSC_WRITE;
1325                     sRwbuf.lba = sRwbuf.xlba;               //copy lba number
1326                     sRwbuf.lbCount = sRwbuf.xlbaCount;      //copy lba count
1327 
1328                     //call event handler, we are ready with data
1329                     bWakeUp = USBMSC_handleBufferEvent();
1330                 }
1331             }
1332         }
1333 
1334         /*Check if there are any pending LBAs to process */
1335         if (MscWriteControl.dwBytesToReceiveLeft > 0){
1336             //read one chunk of 64 bytes
1337 
1338         if (MscWriteControl.wFreeBytesLeft == 0) {
1339             P7OUT &= ~BIT1;
1340             P7OUT &= ~BIT2;
1341             P7OUT &= ~BIT3;
1342                 if (MscWriteControl.XorY == 0) {
1343                     if (sRwbuf.yBufFull == 0) {
1344                         P7OUT |= BIT1;
1345                         P7OUT |= BIT3;
1346                         MscWriteControl.lba += MscWriteControl.lbaCount;
1347                         MscWriteControl.wCurrentByte = 0;
1348                         MscWriteControl.lbaCount = 0;
1349                         MscWriteControl.pUserBuffer = MscControl[sRwbuf.lun].yBufferAddr;
1350                         MscWriteControl.XorY = 1;
1351                         MscWriteControl.wFreeBytesLeft =
1352                             MscControl[sRwbuf.lun].wMscUserBufferSize;
1353                     }
1354                 }
1355                 else {
1356                     if (sRwbuf.xBufFull == 0) {
1357                         P7OUT |= BIT1;
1358                         P7OUT |= BIT2;
1359                         MscWriteControl.lba += MscWriteControl.lbaCount;
1360                         MscWriteControl.wCurrentByte = 0;
1361                         MscWriteControl.lbaCount = 0;
1362                         MscWriteControl.pUserBuffer = MscControl[sRwbuf.lun].xBufferAddr;
1363                         MscWriteControl.XorY = 0;
1364                         MscWriteControl.wFreeBytesLeft =
1365                             MscControl[sRwbuf.lun].wMscUserBufferSize;
1366                     }
1367                 }
1368             }
1369 
1370 
1371             //check what is current buffer: X or Y
1372             if (MscWriteControl.bCurrentBufferXY == X_BUFFER){  //X is current buffer
1373                 //this is the active EP buffer
1374                 pEP1 = (BYTE*)stUsbHandle[MSC0_INTFNUM].oep_X_Buffer;
1375                 MscWriteControl.pCT1 =
1376                     &tOutputEndPointDescriptorBlock[edbIndex].bEPBCTX;
1377 
1378                 //second EP buffer
1379                 MscWriteControl.pEP2 =
1380                     (BYTE*)stUsbHandle[MSC0_INTFNUM].oep_Y_Buffer;
1381                 MscWriteControl.pCT2 =
1382                     &tOutputEndPointDescriptorBlock[edbIndex].bEPBCTY;
1383             } else {
1384                 //this is the active EP buffer
1385                 pEP1 = (BYTE*)stUsbHandle[MSC0_INTFNUM].oep_Y_Buffer;
1386                 MscWriteControl.pCT1 =
1387                     &tOutputEndPointDescriptorBlock[edbIndex].bEPBCTY;
1388 
1389                 //second EP buffer
1390                 MscWriteControl.pEP2 =
1391                     (BYTE*)stUsbHandle[MSC0_INTFNUM].oep_X_Buffer;
1392                 MscWriteControl.pCT2 =
1393                     &tOutputEndPointDescriptorBlock[edbIndex].bEPBCTX;
1394             }
1395 
1396             //how many byte we can get from one endpoint buffer
1397             nTmp1 = *MscWriteControl.pCT1;
1398 
1399             if ((nTmp1 & EPBCNT_NAK) &&
1400                 (MscWriteControl.wFreeBytesLeft >= 64)){
1401                 //copy data from Endpoint
1402                 MscCopyUsbToBuff(pEP1, MscWriteControl.pCT1);
1403 
1404                 nTmp1 = *MscWriteControl.pCT2;
1405 
1406                 //try read data from second buffer
1407                 if ((MscWriteControl.dwBytesToReceiveLeft > 0) &&   //do we have more data to send?
1408                     (MscWriteControl.wFreeBytesLeft >= 64) &&
1409                     (nTmp1 & EPBCNT_NAK)){                          //if the second buffer has received data?
1410                     //copy data from Endpoint
1411                     MscCopyUsbToBuff(MscWriteControl.pEP2, MscWriteControl.pCT2);
1412                     //MscWriteControl.pCT1 = MscWriteControl.pCT2;
1413                 }
1414 
1415                 if ((MscWriteControl.wFreeBytesLeft == 0) ||        //user's buffer is full, give it to User
1416                     (MscWriteControl.dwBytesToReceiveLeft == 0)){   //or no bytes to read left - give it to User
1417 
1418                     if (sRwbuf.firstFlag == 0) {
1419                         sRwbuf.firstFlag = 1;
1420                         sRwbuf.operation = kUSBMSC_WRITE;
1421                         sRwbuf.lba = MscWriteControl.lba;               //copy lba number
1422                         sRwbuf.lbCount = MscWriteControl.lbaCount;      //copy lba count
1423 
1424                         //call event handler, we are ready with data
1425                         bWakeUp = USBMSC_handleBufferEvent();
1426                     }
1427                     if (MscWriteControl.XorY == 0) {
1428                         sRwbuf.xBufFull = 1;
1429                         sRwbuf.xlba = MscWriteControl.lba;
1430                         sRwbuf.xlbaCount = MscWriteControl.lbaCount;
1431                     }
1432                     else {
1433                         sRwbuf.yBufFull = 1;
1434                         sRwbuf.ylba = MscWriteControl.lba;
1435                         sRwbuf.ylbaCount = MscWriteControl.lbaCount;
1436                     }
1437                     return (TRUE);
1438                 } //if (wFreeBytesLeft == 0)
1439             }
1440         } //if (MscWriteControl.dwBytesToReceiveLeft > 0)
1441         else {
1442             if (sRwbuf.xBufFull ==0 && sRwbuf.yBufFull == 0) {
1443                 MscWriteControl.pUserBuffer = NULL;         //no more receiving pending
1444                 MscWriteControl.bWriteProcessing = FALSE;   //ready to receive next CBW
1445             }
1446             bWakeUp = TRUE;
1447         }
1448     }
1449     return (bWakeUp);
1450 }
1451 
1452 //--------------------------------------------------------------------------------------
1453 /*This function is called by application to indicate buffer processed and ready for stack to operate on */
USBMSC_bufferProcessed()1454 BYTE USBMSC_bufferProcessed ()
1455 {
1456     unsigned short bGIE;
1457     BYTE edbIndex;
1458 
1459     bGIE  = (__get_SR_register() & GIE);            //save interrupt status
1460     //Disable interrupt
1461     _DINT_FET();
1462 
1463     if (MscControl[sRwbuf.lun].yBufferAddr == NULL) {
1464         /*
1465          * Fix for SDOCM00078384
1466          * Reset bWriteProcessing after last buffer is processed by the application
1467          */
1468         if (sRwbuf.operation == kUSBMSC_WRITE &&
1469             MscWriteControl.dwBytesToReceiveLeft == 0){ //the Receive opereation (MSC_WRITE) is completed
1470             MscWriteControl.pUserBuffer = NULL;         //no more receiving pending
1471             MscWriteControl.bWriteProcessing = FALSE;   //ready to receive next CBW
1472         }
1473 
1474         if (sRwbuf.operation == kUSBMSC_WRITE && sRwbuf.returnCode ==
1475             kUSBMSC_RWSuccess){
1476             //initialize user buffer.
1477             MscWriteControl.pUserBuffer = MscControl[sRwbuf.lun].xBufferAddr;
1478             MscWriteControl.wFreeBytesLeft =
1479                 MscControl[sRwbuf.lun].wMscUserBufferSize;
1480             sRwbuf.operation = NULL;                    //no operation pending...
1481             //read out next portion of data if available.
1482             MSCFromHostToBuffer();
1483         } else if (sRwbuf.operation == kUSBMSC_READ && sRwbuf.returnCode ==
1484                    kUSBMSC_RWSuccess){
1485             WORD wCnt = sRwbuf.lbCount * MscControl[sRwbuf.lun].lbaSize;
1486 
1487             //trigger sending LBA(s)
1488             MscSendData(sRwbuf.bufferAddr, wCnt);
1489 
1490             if (sRwbuf.lbCount >= MscReadControl.lbaCount){
1491                 //all bytes sent, reset structure
1492                 MscReadControl.lbaCount = 0;
1493             } else {
1494                 //update read structure
1495                 MscReadControl.lbaCount -= sRwbuf.lbCount;
1496                 MscReadControl.lba += sRwbuf.lbCount;
1497 
1498             }
1499             sRwbuf.operation = NULL;                                        //no operation pending...
1500         }
1501     }
1502     else {
1503         if (sRwbuf.operation == kUSBMSC_WRITE && sRwbuf.returnCode ==
1504             kUSBMSC_RWSuccess){
1505             P7OUT &= ~BIT0;
1506             //initialize user buffer.
1507             sRwbuf.bufferProcessed = 1;
1508             if (sRwbuf.XorY == 0) {
1509                 sRwbuf.xBufFull = 0;
1510             }
1511             else {
1512                 sRwbuf.yBufFull = 0;
1513             }
1514             sRwbuf.operation = NULL;                    //no operation pending...
1515             //read out next portion of data if available.
1516             MSCFromHostToBuffer();
1517         } else if (sRwbuf.operation == kUSBMSC_READ && sRwbuf.returnCode ==
1518                    kUSBMSC_RWSuccess){
1519             WORD wCnt = sRwbuf.lbCount * MscControl[sRwbuf.lun].lbaSize;
1520 
1521             sRwbuf.bufferProcessed = 1;
1522 
1523             if (sRwbuf.XorY == 0) {
1524                 sRwbuf.xBufFull = 1;
1525                 sRwbuf.xWordCnt = wCnt;
1526             }
1527             else {
1528                 sRwbuf.yBufFull = 1;
1529                 sRwbuf.yWordCnt = wCnt;
1530             }
1531 
1532             if (sRwbuf.firstFlag == 0) {
1533                 //trigger sending LBA(s)
1534                 sRwbuf.firstFlag = 1;
1535                 MscSendData(sRwbuf.bufferAddr, wCnt);
1536             }
1537             else {
1538                 edbIndex = stUsbHandle[MSC0_INTFNUM].edb_Index;
1539                 //trigger Endpoint Interrupt - to start send operation
1540                 USBIEPIFG |= 1 << (edbIndex + 1);               //IEPIFGx;
1541             }
1542 
1543             if (sRwbuf.lbCount >= MscReadControl.lbaCount){
1544                 //all bytes sent, reset structure
1545                 MscReadControl.lbaCount = 0;
1546                 sRwbuf.operation = NULL;
1547             } else {
1548                 //update read structure
1549                 MscReadControl.lbaCount -= sRwbuf.lbCount;
1550                 MscReadControl.lba += sRwbuf.lbCount;
1551             }
1552             sRwbuf.operation = NULL;                                        //no operation pending...
1553         }
1554     }
1555 
1556     switch (sRwbuf.returnCode)
1557     {
1558         case kUSBMSC_RWSuccess:
1559             MscState.Scsi_Residue = 0;
1560             Reset_RequestSenseResponse();
1561             break;
1562         //Set RequestSenseResponse if necessary?  Maybe initialized values OK?
1563 
1564         case kUSBMSC_RWNotReady:
1565             MscState.Scsi_Status = SCSI_FAILED;
1566             MscState.Scsi_Residue = 1;
1567             Reset_RequestSenseResponse();
1568             RequestSenseResponse.VALID = 1;
1569             RequestSenseResponse.SenseKey = S_NOT_READY;
1570             RequestSenseResponse.ASC = ASC_NOT_READY;
1571             RequestSenseResponse.ASCQ = ASCQ_NOT_READY;
1572             break;
1573 
1574         case kUSBMSC_RWIllegalReq:
1575             MscState.Scsi_Status = SCSI_FAILED;
1576             MscState.Scsi_Residue = 0;
1577             Reset_RequestSenseResponse();
1578             RequestSenseResponse.VALID = 1;
1579             RequestSenseResponse.SenseKey = S_ILLEGAL_REQUEST;
1580             RequestSenseResponse.ASC = ASC_ILLEGAL_REQUEST;
1581             RequestSenseResponse.ASCQ = ASCQ_ILLEGAL_REQUEST;
1582             break;
1583 
1584         case kUSBMSC_RWUnitAttn:
1585             MscState.Scsi_Status = SCSI_FAILED;
1586             MscState.Scsi_Residue = 0;
1587             Reset_RequestSenseResponse();
1588             RequestSenseResponse.VALID = 1;
1589             RequestSenseResponse.SenseKey = S_UNITATTN;
1590             RequestSenseResponse.ASC = ASC_UNITATTN_READY_NOTREADY;
1591             RequestSenseResponse.ASCQ = ASCQ_UNITATTN_READY_NOTREADY;
1592             break;
1593 
1594         case kUSBMSC_RWLbaOutOfRange:
1595             MscState.Scsi_Status = SCSI_FAILED;
1596             MscState.Scsi_Residue = 0;
1597             Reset_RequestSenseResponse();
1598             RequestSenseResponse.VALID = 1;
1599             RequestSenseResponse.SenseKey = S_ILLEGAL_REQUEST;
1600             RequestSenseResponse.ASC = ASC_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE;
1601             RequestSenseResponse.ASCQ = ASCQ_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE;
1602             break;
1603 
1604         case kUSBMSC_RWMedNotPresent:
1605             MscState.Scsi_Status = SCSI_FAILED;
1606             MscState.Scsi_Residue = 0;
1607             Reset_RequestSenseResponse();
1608             RequestSenseResponse.VALID = 1;
1609             RequestSenseResponse.SenseKey = S_NOT_READY;
1610             RequestSenseResponse.ASC = ASC_MEDIUM_NOT_PRESENT;
1611             RequestSenseResponse.ASCQ = ASCQ_MEDIUM_NOT_PRESENT;
1612             break;
1613 
1614         case kUSBMSC_RWDevWriteFault:
1615             MscState.Scsi_Status = SCSI_FAILED;
1616             MscState.Scsi_Residue = 0;
1617             Reset_RequestSenseResponse();
1618             RequestSenseResponse.VALID = 1;
1619             RequestSenseResponse.SenseKey = S_MEDIUM_ERROR;
1620             RequestSenseResponse.ASC = ASC_WRITE_FAULT;
1621             RequestSenseResponse.ASCQ = ASCQ_WRITE_FAULT;
1622             break;
1623 
1624         case kUSBMSC_RWUnrecoveredRead:
1625             MscState.Scsi_Status = SCSI_FAILED;
1626             MscState.Scsi_Residue = 0;
1627             Reset_RequestSenseResponse();
1628             RequestSenseResponse.VALID = 1;
1629             RequestSenseResponse.SenseKey = S_MEDIUM_ERROR;
1630             RequestSenseResponse.ASC = ASC_UNRECOVERED_READ;
1631             RequestSenseResponse.ASCQ = ASCQ_UNRECOVERED_READ;
1632             break;
1633 
1634         case kUSBMSC_RWWriteProtected:
1635             MscState.Scsi_Status = SCSI_FAILED;
1636             MscState.Scsi_Residue = 0;
1637             Reset_RequestSenseResponse();
1638             RequestSenseResponse.VALID = 1;
1639             RequestSenseResponse.SenseKey =  S_WRITE_PROTECTED;
1640             RequestSenseResponse.ASC = ASC_WRITE_PROTECTED;
1641             RequestSenseResponse.ASCQ = ASCQ_WRITE_PROTECTED;
1642             break;
1643                                                         //case breakouts for all the codes
1644     }
1645 
1646     if (sRwbuf.returnCode != kUSBMSC_RWSuccess){
1647         sRwbuf.operation = NULL;                        //no operation pending...
1648         if (McsCbw.bmCBWFlags == DIRECTION_IN){
1649             usbStallInEndpoint(MSC0_INTFNUM);
1650             MscReadControl.bReadProcessing = FALSE;     //ready to receive next CBW
1651             MscReadControl.pUserBuffer = NULL;          //no more receiving pending
1652             MscReadControl.lbaCount = 0;
1653         } else {
1654             //we need to stall only if not all af data was transfered
1655             if (MscWriteControl.dwBytesToReceiveLeft > 0){
1656                 usbStallOutEndpoint(MSC0_INTFNUM);
1657             }
1658             MscWriteControl.bWriteProcessing = FALSE;   //ready to receive next CBW
1659             MscWriteControl.pUserBuffer = NULL;         //no more receiving pending
1660             *MscWriteControl.pCT1 = 0x00;               //clear NAK, EP ready to receive next data
1661             *MscWriteControl.pCT2 = 0x00;               //clear NAK, EP ready to receive next data
1662         }
1663     }
1664 
1665     __bis_SR_register(bGIE);                            //restore interrupt status
1666     return (kUSB_succeed);
1667 }
1668 
1669 //-------------------------------------------------------------------------------------------
Msc_ResetFlags()1670 VOID Msc_ResetFlags ()
1671 {
1672     MscState.bMscCbwReceived = FALSE;
1673 }
1674 
1675 //-------------------------------------------------------------------------------------------
Msc_ResetStruct()1676 VOID Msc_ResetStruct ()
1677 {
1678     memset(&sRwbuf,0,sizeof(USBMSC_RWbuf_Info));
1679     memset(&McsCbw,0,sizeof(CBW));
1680     memset(&McsCsw,0,sizeof(CSW));
1681 
1682     MscReadControl.pUserBuffer = NULL;
1683     MscReadControl.dwBytesToSendLeft = 0;
1684     MscReadControl.bReadProcessing = FALSE;
1685 
1686     MscWriteControl.bWriteProcessing = FALSE;
1687     MscWriteControl.pUserBuffer = NULL;
1688     MscWriteControl.dwBytesToReceiveLeft = 0;   //holds how many bytes is still requested by WRITE operation (Host to MSP430)
1689     //we do not reset the bCurrentBufferXY, becuase the buffer doesnt changed if he MSC reseted.
1690     //The bCurrentBufferXY should be reseted in USB_Reset()
1691 
1692     Reset_RequestSenseResponse();
1693 }
1694 
1695 //-------------------------------------------------------------------------------------------
MscResetData()1696 VOID MscResetData ()
1697 {
1698     Msc_ResetStruct();
1699 
1700     memset(&MscWriteControl, 0, sizeof(MscWriteControl));
1701     memset(&MscReadControl, 0, sizeof(MscReadControl));
1702 }
1703 
1704 //-------------------------------------------------------------------------------------------
MscResetCtrlLun()1705 VOID MscResetCtrlLun ()
1706 {
1707     int i;
1708 
1709     for (i = 0; i < MSC_MAX_LUN_NUMBER; i++)
1710     {
1711         MscControl[i].bMediaPresent = 0x80;
1712         MscControl[i].bWriteProtected = FALSE;
1713     }
1714 }
1715 
1716 //-------------------------------------------------------------------------------------------
1717 /* This function can be called by application to get the current status of stack operation */
USBMSC_getState()1718 BYTE USBMSC_getState ()
1719 {
1720     BYTE state;
1721 
1722     if (sRwbuf.operation == 0 && MscState.bMscSendCsw == FALSE){
1723         state = kUSBMSC_idle;
1724     } else if (sRwbuf.operation == kUSBMSC_READ && sRwbuf.lbCount > 0){
1725         state =  kUSBMSC_readInProgress;
1726     } else if (sRwbuf.operation == kUSBMSC_WRITE && sRwbuf.lbCount > 0){
1727         state =  kUSBMSC_writeInProgress;
1728     } else if (sRwbuf.operation == 0 && MscState.bMscSendCsw == TRUE){
1729         state =  kUSBMSC_cmdBeingProcessed;
1730     }
1731     return (state);
1732 }
1733 
1734 //-------------------------------------------------------------------------------------------
USBMSC_updateMediaInfo(BYTE lun,struct USBMSC_mediaInfoStr * info)1735 BYTE USBMSC_updateMediaInfo ( BYTE lun,  struct USBMSC_mediaInfoStr *info)
1736 {
1737     BYTE state;
1738 
1739     Scsi_Read_Capacity_10[lun].lLba[0] = (BYTE)(info->lastBlockLba >> 24);
1740     Scsi_Read_Capacity_10[lun].lLba[1] = (BYTE)(info->lastBlockLba >> 16);
1741     Scsi_Read_Capacity_10[lun].lLba[2] = (BYTE)(info->lastBlockLba >> 8);
1742     Scsi_Read_Capacity_10[lun].lLba[3] = (BYTE)(info->lastBlockLba);
1743 
1744     Scsi_Read_Capacity_10[lun].bLength[0] = (BYTE)(info->bytesPerBlock >> 24);
1745     Scsi_Read_Capacity_10[lun].bLength[1] = (BYTE)(info->bytesPerBlock >> 16);
1746     Scsi_Read_Capacity_10[lun].bLength[2] = (BYTE)(info->bytesPerBlock >> 8);
1747     Scsi_Read_Capacity_10[lun].bLength[3] = (BYTE)(info->bytesPerBlock);
1748 
1749     MscControl[lun].lbaSize = (WORD)Scsi_Read_Capacity_10[lun].bLength[2] <<
1750                               8 | Scsi_Read_Capacity_10[lun].bLength[3];
1751 
1752     //If the LUN was reported as not removable, then leave mediaPresent/mediaChanged as
1753     //their initialized defaults.
1754     if (USBMSC_config.LUN[lun].removable){
1755         if (((MscControl[lun].bMediaPresent == kUSBMSC_MEDIA_NOT_PRESENT)) &&
1756             (info->mediaPresent == kUSBMSC_MEDIA_PRESENT)){             //If media was inserted...
1757             //Set Unit Attention flag. This flag is used in Scsi_Request_Sense().
1758             MscState.bUnitAttention = TRUE;
1759             MscState.Scsi_Status = SCSI_FAILED;
1760         }
1761 
1762         if ((MscControl[lun].bMediaPresent == kUSBMSC_MEDIA_PRESENT &&
1763              ((info->mediaPresent == kUSBMSC_MEDIA_NOT_PRESENT))) ||    //If media was removed...
1764             ((info->mediaPresent == kUSBMSC_MEDIA_PRESENT) &&
1765              (info->mediaChanged))){                                    //Or if media still present, but has changed...
1766             //Set Unit Attention flag. This flag is used in Scsi_Request_Sense().
1767             MscState.bUnitAttention = TRUE;
1768             MscState.Scsi_Status = SCSI_FAILED;
1769             state = USBMSC_getState();
1770 
1771             if (state ==  kUSBMSC_readInProgress || state ==
1772                 kUSBMSC_writeInProgress){
1773                 if (McsCbw.bmCBWFlags == DIRECTION_IN){
1774                     usbStallInEndpoint(MSC0_INTFNUM);
1775                 } else {
1776                     usbStallOutEndpoint(MSC0_INTFNUM);
1777                 }
1778 
1779                 Msc_ResetStateMachine();
1780                 Msc_ResetFlags();
1781                 Msc_ResetStruct();
1782                 MscState.isMSCConfigured = TRUE;
1783 
1784                 Scsi_Send_CSW(MSC0_INTFNUM);
1785             }
1786         }
1787         MscControl[lun].bMediaPresent = info->mediaPresent;
1788     }
1789 
1790     MscControl[lun].bWriteProtected = info->writeProtected;
1791     return (kUSB_succeed);
1792 }
1793 
1794 //-------------------------------------------------------------------------------------------
USBMSC_registerBufInfo(BYTE lun,BYTE * RWbuf_x,BYTE * RWbuf_y,WORD size)1795 BYTE USBMSC_registerBufInfo (BYTE lun, BYTE *RWbuf_x, BYTE *RWbuf_y, WORD size)
1796 {
1797     MscControl[lun].wMscUserBufferSize = 0;
1798     MscControl[lun].xBufferAddr = NULL;
1799     MscControl[lun].yBufferAddr = NULL; //this version supports only X buffer.
1800 
1801     //check if arguments are valid
1802     if ((size < MscControl[lun].lbaSize) ||
1803         (RWbuf_x == NULL)){             //Need at least one buffer
1804         return (kUSB_generalError);
1805     }
1806 
1807     MscControl[lun].wMscUserBufferSize = size;
1808     MscControl[lun].lbaBufCapacity = MscControl[lun].wMscUserBufferSize /
1809                                      MscControl[lun].lbaSize;
1810     MscControl[lun].xBufferAddr = RWbuf_x;
1811     MscControl[lun].yBufferAddr = RWbuf_y;
1812     return (kUSB_succeed);
1813 }
1814 
1815 //-------------------------------------------------------------------------------------------
SET_RequestsenseNotReady()1816 VOID SET_RequestsenseNotReady ()
1817 {
1818     //Set REQUEST SENSE with "not ready"
1819     Reset_RequestSenseResponse();
1820     RequestSenseResponse.VALID = 1;
1821     RequestSenseResponse.SenseKey = S_NOT_READY;
1822     RequestSenseResponse.ASC = ASC_NOT_READY;
1823     RequestSenseResponse.ASCQ = ASCQ_NOT_READY;
1824     //Send CSW with error status
1825     MscState.Scsi_Status = SCSI_FAILED;
1826 }
1827 
1828 //-------------------------------------------------------------------------------------------
SET_RequestsenseMediaNotPresent()1829 VOID SET_RequestsenseMediaNotPresent ()
1830 {
1831     //Set REQUEST SENSE with "not ready"
1832     Reset_RequestSenseResponse();
1833     RequestSenseResponse.VALID = 1;
1834     RequestSenseResponse.SenseKey = S_NOT_READY;
1835     RequestSenseResponse.ASC = ASC_MEDIUM_NOT_PRESENT;
1836     RequestSenseResponse.ASCQ = ASCQ_MEDIUM_NOT_PRESENT;
1837     //Send CSW with error status
1838     MscState.Scsi_Status = SCSI_FAILED;
1839 }
1840 
1841 //-------------------------------------------------------------------------------------------
usbClearOEPByteCount(BYTE intfNum)1842 VOID usbClearOEPByteCount (BYTE intfNum)
1843 {
1844     BYTE edbIndex;
1845 
1846     edbIndex = stUsbHandle[intfNum].edb_Index;
1847     tOutputEndPointDescriptorBlock[edbIndex].bEPBCTX = 0;
1848 }
1849 
1850 //-------------------------------------------------------------------------------------------
usbStallEndpoint(BYTE intfNum)1851 VOID usbStallEndpoint (BYTE intfNum)
1852 {
1853     BYTE edbIndex;
1854 
1855     edbIndex = stUsbHandle[intfNum].edb_Index;
1856     tOutputEndPointDescriptorBlock[edbIndex].bEPCNF |= EPCNF_STALL;
1857     tInputEndPointDescriptorBlock[edbIndex].bEPCNF |= EPCNF_STALL;
1858 }
1859 
1860 //-------------------------------------------------------------------------------------------
usbStallInEndpoint(BYTE intfNum)1861 VOID usbStallInEndpoint (BYTE intfNum)
1862 {
1863     BYTE edbIndex;
1864 
1865     edbIndex = stUsbHandle[intfNum].edb_Index;
1866     tInputEndPointDescriptorBlock[edbIndex].bEPCNF |= EPCNF_STALL;
1867 }
1868 
1869 //-------------------------------------------------------------------------------------------
usbStallOutEndpoint(BYTE intfNum)1870 VOID usbStallOutEndpoint (BYTE intfNum)
1871 {
1872     BYTE edbIndex;
1873 
1874     edbIndex = stUsbHandle[intfNum].edb_Index;
1875     tOutputEndPointDescriptorBlock[edbIndex].bEPCNF |= EPCNF_STALL;
1876     MscState.stallEndpoint = TRUE;
1877 }
1878 
1879 //-------------------------------------------------------------------------------------------
USBMSC_fetchInfoStruct(VOID)1880 USBMSC_RWbuf_Info* USBMSC_fetchInfoStruct (VOID)
1881 {
1882     return (&sRwbuf);
1883 }
1884 
1885 #ifdef CDROM_SUPPORT
1886 //----------------------------------------------------------------------------
1887 
Scsi_Read_TocPmaAtip(BYTE intfNum)1888 VOID Scsi_Read_TocPmaAtip(BYTE intfNum)
1889 {
1890     if(McsCbw.CBWCB[2] & 0x01) {
1891 
1892     if (SUCCESS !=
1893             MscSendData( (PBYTE)&Scsi_Read_TOC_PMA_ATIP_F1[McsCbw.bCBWLUN],
1894                     Scsi_Read_TOC_PMA_ATIP_F1_LEN)){
1895             MscState.Scsi_Status = SCSI_FAILED;
1896         }
1897     } else {
1898 
1899         if (SUCCESS !=
1900             MscSendData( (PBYTE)&Scsi_Read_TOC_PMA_ATIP_F2[McsCbw.bCBWLUN],
1901                     Scsi_Read_TOC_PMA_ATIP_F2_LEN)){
1902             MscState.Scsi_Status = SCSI_FAILED;
1903         }
1904     }
1905 }
1906 
Scsi_Get_Configuration(BYTE intfNum)1907 VOID Scsi_Get_Configuration(BYTE intfNum) {
1908 
1909     if (FAILURE == Check_CBW(intfNum,DIRECTION_IN,SCSI_GET_CONFIGURATION_LEN)){
1910         return;
1911     }
1912 
1913         if (SUCCESS !=
1914             MscSendData( (PBYTE)&Scsi_Get_Configuration_Descriptor[McsCbw.bCBWLUN],
1915                     SCSI_GET_CONFIGURATION_LEN)){
1916             MscState.Scsi_Status = SCSI_FAILED;
1917         }
1918 }
1919 
Scsi_Event_Status_Notification(BYTE intfNum)1920 VOID Scsi_Event_Status_Notification(BYTE intfNum) {
1921 
1922        if (FAILURE == Check_CBW(intfNum,DIRECTION_IN,SCSI_EVENT_STATUS_LEN)){
1923            return;
1924         }
1925         if (SUCCESS !=
1926             MscSendData( (PBYTE)&Scsi_Event_Status_Descriptor[McsCbw.bCBWLUN],
1927                     SCSI_EVENT_STATUS_LEN)){
1928             MscState.Scsi_Status = SCSI_FAILED;
1929         }
1930 }
1931 
Scsi_Read_Disc_Information(BYTE intfNum)1932 VOID Scsi_Read_Disc_Information(BYTE intfNum) {
1933 
1934 
1935     if (FAILURE == Check_CBW(intfNum,DIRECTION_IN,SCSI_READ_DISC_INFORMATION_LEN)){
1936         return;
1937     }
1938     if (SUCCESS !=
1939         MscSendData( (PBYTE)&Scsi_Disc_Information_Descriptor[McsCbw.bCBWLUN],
1940                 SCSI_READ_DISC_INFORMATION_LEN)){
1941         MscState.Scsi_Status = SCSI_FAILED;
1942     }
1943 }
1944 
1945 #endif
1946 
1947 #endif  //_MSC_
1948 
1949 /*----------------------------------------------------------------------------+
1950  | End of source file                                                          |
1951  +----------------------------------------------------------------------------*/
1952 /*------------------------ Nothing Below This Line --------------------------*/
1953