00001
00035 #include "em_usb.h"
00036 #include "msdscsi.h"
00037 #include "msdbot.h"
00038
00041
00045 #define CBW_SCSI_READ10_INIT_DEFAULT \
00046 { \
00047 CBW_SIGNATURE, \
00048 0x78563412, \
00049 0x00000000, \
00050 { { 0, 0, 1 } }, \
00051 { { 0, 0 } }, \
00052 { { 10, 0 } }, \
00053 { SCSI_READ10, \
00054 0, 0, 0, 0, \
00055 0, 0, 0, 0, \
00056 0, 0, 0, 0, \
00057 0, 0, 0 } \
00058 }
00059
00060
00064 #define CBW_SCSI_WRITE10_INIT_DEFAULT \
00065 { \
00066 CBW_SIGNATURE, \
00067 0x78563412, \
00068 0x00000000, \
00069 { { 0, 0, 0 } }, \
00070 { { 0, 0 } }, \
00071 { { 10, 0 } }, \
00072 { SCSI_WRITE10, \
00073 0, 0, 0, 0, \
00074 0, 0, 0, 0, \
00075 0, 0, 0, 0, \
00076 0, 0, 0 } \
00077 }
00078
00079
00083 EFM32_ALIGN(4)
00084 static const char cbwInquiry[ CBW_LEN ] __attribute__ ((aligned(4))) =
00085 {
00086 'U', 'S', 'B', 'C',
00087 0x12, 0x34, 0x56, 0x78,
00088 SCSI_INQUIRYDATA_LEN,
00089 0x00, 0x00, 0x00,
00090 BOT_DIR_IN, 0x00, 6,
00091 SCSI_INQUIRY, 0x00, 0x00,
00092 0x00, SCSI_INQUIRYDATA_LEN,
00093 0x00, 0x00, 0x00, 0x00,
00094 0x00, 0x00, 0x00, 0x00,
00095 0x00, 0x00, 0x00
00096 };
00097
00098
00102 EFM32_ALIGN(4)
00103 static const char cbwReadCap[ CBW_LEN ] __attribute__ ((aligned(4))) =
00104 {
00105 'U', 'S', 'B', 'C',
00106 0x12, 0x34, 0x56, 0x78,
00107 SCSI_READCAPACITYDATA_LEN,
00108 0x00, 0x00, 0x00,
00109 BOT_DIR_IN, 0x00, 10,
00110 SCSI_READCAPACITY,
00111 0x00, 0x00, 0x00, 0x00,
00112 0x00, 0x00, 0x00, 0x00,
00113 0x00, 0x00, 0x00, 0x00,
00114 0x00, 0x00, 0x00
00115 };
00116
00117
00121 EFM32_ALIGN(4)
00122 static const char cbwRs[ CBW_LEN ] __attribute__ ((aligned(4))) =
00123 {
00124 'U', 'S', 'B', 'C',
00125 0x12, 0x34, 0x56, 0x78,
00126 SCSI_REQUESTSENSEDATA_LEN,
00127 0x00, 0x00, 0x00,
00128 BOT_DIR_IN, 0x00, 6,
00129 SCSI_REQUESTSENSE, 0x00,
00130 0x00, 0x00,
00131 SCSI_REQUESTSENSEDATA_LEN,
00132 0x00, 0x00, 0x00, 0x00,
00133 0x00, 0x00, 0x00, 0x00,
00134 0x00, 0x00, 0x00
00135 };
00136
00137
00141 EFM32_ALIGN(4)
00142 static const char cbwTur[ CBW_LEN ] __attribute__ ((aligned(4))) =
00143 {
00144 'U', 'S', 'B', 'C',
00145 0x12, 0x34, 0x56, 0x78,
00146 0x00, 0x00, 0x00, 0x00,
00147 BOT_DIR_IN, 0x00, 6,
00148 SCSI_TESTUNIT_READY, 0x00,
00149 0x00, 0x00, 0x00, 0x00,
00150 0x00, 0x00, 0x00, 0x00,
00151 0x00, 0x00, 0x00, 0x00,
00152 0x00, 0x00
00153 };
00154
00155
00156
00157 static uint32_t lbaCount = 0;
00158 static uint32_t lbaSize = 0;
00159
00162
00175 bool MSDSCSI_Init(USBH_Ep_TypeDef *out, USBH_Ep_TypeDef *in)
00176 {
00177
00178
00179 if ((sizeof(MSDSCSI_Read10_TypeDef) != SCSI_READ10_LEN) ||
00180 (sizeof(MSDSCSI_Write10_TypeDef) != SCSI_WRITE10_LEN) ||
00181 (sizeof(MSDSCSI_InquiryData_TypeDef) != SCSI_INQUIRYDATA_LEN) ||
00182 (sizeof(MSDSCSI_RequestSenseData_TypeDef) != SCSI_REQUESTSENSEDATA_LEN) ||
00183 (sizeof(MSDSCSI_ReadCapacityData_TypeDef) != SCSI_READCAPACITYDATA_LEN))
00184 {
00185 DEBUG_USB_API_PUTS("\nMSDSCSI_Init(), typedef size error");
00186 EFM_ASSERT(false);
00187 return false;
00188 }
00189
00190
00191 if (MSDBOT_Init(out, in) != MSDBOT_STATUS_OK)
00192 return false;
00193
00194 return true;
00195 }
00196
00197
00207 bool MSDSCSI_Inquiry(MSDSCSI_InquiryData_TypeDef *data)
00208 {
00209 if (MSDBOT_Xfer((void*) cbwInquiry, data) == SCSI_INQUIRYDATA_LEN)
00210 return true;
00211
00212 return false;
00213 }
00214
00215
00231 bool MSDSCSI_Read10(uint32_t lba, uint16_t sectors, void *data)
00232 {
00233 EFM32_ALIGN(4)
00234 MSDBOT_CBW_TypeDef cbw __attribute__ ((aligned(4))) = CBW_SCSI_READ10_INIT_DEFAULT;
00235
00236 MSDSCSI_Read10_TypeDef *cb = (MSDSCSI_Read10_TypeDef*) &cbw.CBWCB;
00237
00238 cbw.dCBWDataTransferLength = sectors * lbaSize;
00239 cb->Lba = __REV(lba);
00240 cb->TransferLength = __REV16(sectors);
00241
00242 if ((uint32_t) MSDBOT_Xfer(&cbw, data) == cbw.dCBWDataTransferLength)
00243 return true;
00244
00245 return false;
00246 }
00247
00248
00258 bool MSDSCSI_ReadCapacity(MSDSCSI_ReadCapacityData_TypeDef *data)
00259 {
00260 if (MSDBOT_Xfer((void*) cbwReadCap, data) == SCSI_READCAPACITYDATA_LEN)
00261 {
00262
00263 lbaCount = __REV(data->LogicalBlockAddress);
00264 lbaSize = __REV(data->LogicalBlockLength);
00265
00266 data->LogicalBlockAddress = lbaCount;
00267 data->LogicalBlockLength = lbaSize;
00268
00269 return true;
00270 }
00271
00272 return false;
00273 }
00274
00275
00285 bool MSDSCSI_RequestSense(MSDSCSI_RequestSenseData_TypeDef *data)
00286 {
00287 if (MSDBOT_Xfer((void*) cbwRs, data) == SCSI_REQUESTSENSEDATA_LEN)
00288 return true;
00289
00290 return false;
00291 }
00292
00293
00301 bool MSDSCSI_TestUnitReady(void)
00302 {
00303 if (MSDBOT_Xfer((void*) cbwTur, NULL) == MSDBOT_STATUS_OK)
00304 return true;
00305
00306 return false;
00307 }
00308
00309
00325 bool MSDSCSI_Write10(uint32_t lba, uint16_t sectors, const void *data)
00326 {
00327 EFM32_ALIGN(4)
00328 MSDBOT_CBW_TypeDef cbw __attribute__ ((aligned(4))) = CBW_SCSI_WRITE10_INIT_DEFAULT;
00329
00330 MSDSCSI_Write10_TypeDef *cb = (MSDSCSI_Write10_TypeDef*) &cbw.CBWCB;
00331
00332 cbw.dCBWDataTransferLength = sectors * lbaSize;
00333 cb->Lba = __REV(lba);
00334 cb->TransferLength = __REV16(sectors);
00335
00336 if ((uint32_t) MSDBOT_Xfer(&cbw, (void*) data) == cbw.dCBWDataTransferLength)
00337 return true;
00338
00339 return false;
00340 }