70 return (HandleSCSIError(Transaction(&cbw, buf_size, buf)));
86 return (HandleSCSIError(Transaction(&cbw, buf_size, buf)));
98 Notify(PSTR(
"\r\nLockMedia\r\n"), 0x80);
99 Notify(PSTR(
"---------\r\n"), 0x80);
114 Notify(PSTR(
"\r\nMediaCTL\r\n"), 0x80);
115 Notify(PSTR(
"-----------------\r\n"), 0x80);
137 uint8_t
BulkOnly::Read(uint8_t lun, uint32_t addr, uint16_t bsize, uint8_t blocks, uint8_t *buf) {
139 Notify(PSTR(
"\r\nRead LUN:\t"), 0x80);
140 D_PrintHex<uint8_t > (lun, 0x90);
141 Notify(PSTR(
"\r\nLBA:\t\t"), 0x90);
142 D_PrintHex<uint32_t > (addr, 0x90);
143 Notify(PSTR(
"\r\nblocks:\t\t"), 0x90);
144 D_PrintHex<uint8_t > (blocks, 0x90);
145 Notify(PSTR(
"\r\nblock size:\t"), 0x90);
146 D_PrintHex<uint16_t > (bsize, 0x90);
147 Notify(PSTR(
"\r\n---------\r\n"), 0x80);
156 if (!TestUnitReady(lun))
goto again;
171 uint8_t
BulkOnly::Write(uint8_t lun, uint32_t addr, uint16_t bsize, uint8_t blocks,
const uint8_t * buf) {
174 Notify(PSTR(
"\r\nWrite LUN:\t"), 0x80);
175 D_PrintHex<uint8_t > (lun, 0x90);
176 Notify(PSTR(
"\r\nLBA:\t\t"), 0x90);
177 D_PrintHex<uint32_t > (addr, 0x90);
178 Notify(PSTR(
"\r\nblocks:\t\t"), 0x90);
179 D_PrintHex<uint8_t > (blocks, 0x90);
180 Notify(PSTR(
"\r\nblock size:\t"), 0x90);
181 D_PrintHex<uint16_t > (bsize, 0x90);
182 Notify(PSTR(
"\r\n---------\r\n"), 0x80);
191 if (!TestUnitReady(lun))
goto again;
238 uint8_t buf[constBufSize];
276 goto FailGetDevDescr;
292 #ifdef DEBUG_USB_HOST
348 goto FailSetDevTblEntry;
352 for (uint8_t i = 0; i < num_of_conf; i++) {
363 goto FailGetConfDescr;
381 goto FailSetConfDescr;
391 ErrorMessage<uint8_t > (PSTR(
"MaxLUN"),
bMaxLUN);
395 for (uint8_t lun = 0; lun <=
bMaxLUN; lun++) {
399 ErrorMessage<uint8_t > (PSTR(
"Inquiry"), rcode);
402 printf(
"LUN %i `", lun);
404 for (
int i = 0; i < 28; i++) printf(
"%c", buf[i]);
406 printf(
"Device type %2.2X ", response.
DeviceType);
407 printf(
"RMB %1.1X ", response.
Removable);
408 printf(
"SSCS %1.1X ", response.
SCCS);
410 printf(
"SCSI version %2.2X\r\nDevice conforms to ", sv);
413 printf(
"No specific");
416 printf(
"ANSI X3.131-1986 (ANSI 1)");
419 printf(
"ANSI X3.131-1994 (ANSI 2)");
422 printf(
"ANSI INCITS 301-1997 (SPC)");
425 printf(
"ANSI INCITS 351-2001 (SPC-2)");
428 printf(
"ANSI INCITS 408-2005 (SPC-4)");
431 printf(
"T10/1731-D (SPC-4)");
436 printf(
" standards.\r\n");
438 uint8_t tries = 0xf0;
439 while (rcode = TestUnitReady(lun)) {
440 if (rcode == 0x08)
break;
445 }
else delay(2 * (tries + 1));
451 LUNOk[lun] = CheckLUN(lun);
465 #ifdef DEBUG_USB_HOST
475 #ifdef DEBUG_USB_HOST
481 #ifdef DEBUG_USB_HOST
487 #ifdef DEBUG_USB_HOST
492 FailInvalidSectorSize:
493 #ifdef DEBUG_USB_HOST
494 USBTRACE(
"Sector Size is NOT VALID: ");
499 #ifdef DEBUG_USB_HOST
505 #ifdef DEBUG_USB_HOST
510 #ifdef DEBUG_USB_HOST
527 ErrorMessage<uint8_t > (PSTR(
"Conf.Val"), conf);
528 ErrorMessage<uint8_t > (PSTR(
"Iface Num"), iface);
529 ErrorMessage<uint8_t > (PSTR(
"Alt.Set"), alt);
570 boolean BulkOnly::CheckLUN(uint8_t lun) {
573 for (uint8_t i = 0; i < 8; i++) capacity.
data[i] = 0;
575 rcode = ReadCapacity10(lun, (uint8_t*)capacity.
data);
580 ErrorMessage<uint8_t > (PSTR(
">>>>>>>>>>>>>>>>CAPACITY OK ON LUN"), lun);
581 for (uint8_t i = 0; i < 8 ; i++)
582 D_PrintHex<uint8_t > (capacity.
data[i], 0x80);
583 Notify(PSTR(
"\r\n\r\n"), 0x80);
586 if (c != 0x0200LU && c != 0x0400LU && c != 0x0800LU && c != 0x1000LU) {
596 ErrorMessage<uint8_t > (PSTR(
">>>>>>>>>>>>>>>>BUGGY FIRMWARE. CAPACITY FAIL ON LUN"), lun);
601 if (!TestUnitReady(lun))
return true;
610 void BulkOnly::CheckMedia() {
611 for (uint8_t lun = 0; lun <=
bMaxLUN; lun++) {
612 if (TestUnitReady(lun)) {
617 LUNOk[lun] = CheckLUN(lun);
620 printf(
"}}}}}}}}}}}}}}}}STATUS ");
621 for (uint8_t lun = 0; lun <=
bMaxLUN; lun++) {
664 uint8_t BulkOnly::GetMaxLUN(uint8_t *plun) {
665 uint8_t ret =
pUsb->
ctrlReq(
bAddress, 0,
bmREQ_MASSIN,
MASS_REQ_GET_MAX_LUN, 0, 0,
bIface, 1, 1, plun, NULL);
681 uint8_t BulkOnly::Inquiry(uint8_t lun, uint16_t bsize, uint8_t *buf) {
682 Notify(PSTR(
"\r\nInquiry\r\n"), 0x80);
683 Notify(PSTR(
"---------\r\n"), 0x80);
697 uint8_t BulkOnly::TestUnitReady(uint8_t lun) {
702 Notify(PSTR(
"\r\nTestUnitReady\r\n"), 0x80);
703 Notify(PSTR(
"-----------------\r\n"), 0x80);
721 uint8_t BulkOnly::ModeSense6(uint8_t lun, uint8_t pc, uint8_t page, uint8_t subpage, uint8_t len, uint8_t * pbuf) {
722 Notify(PSTR(
"\r\rModeSense\r\n"), 0x80);
723 Notify(PSTR(
"------------\r\n"), 0x80);
737 uint8_t BulkOnly::ReadCapacity10(uint8_t lun, uint8_t *buf) {
738 Notify(PSTR(
"\r\nReadCapacity\r\n"), 0x80);
739 Notify(PSTR(
"---------------\r\n"), 0x80);
753 uint8_t BulkOnly::Page3F(uint8_t lun) {
755 for (
int i = 0; i < 192; i++) {
759 uint8_t rc = ModeSense6(lun, 0, 0x3f, 0, 192, buf);
761 WriteOk[lun] = ((buf[2] & 0x80) == 0);
762 Notify(PSTR(
"Mode Sense: "), 0x80);
763 for (
int i = 0; i < 4; i++) {
764 D_PrintHex<uint8_t > (buf[i], 0x80);
767 Notify(PSTR(
"\r\n"), 0x80);
780 uint8_t BulkOnly::RequestSense(uint8_t lun, uint16_t size, uint8_t *buf) {
781 Notify(PSTR(
"\r\nRequestSense\r\n"), 0x80);
782 Notify(PSTR(
"----------------\r\n"), 0x80);
787 return Transaction(&cbw, size, buf);
805 uint8_t BulkOnly::ClearEpHalt(uint8_t index) {
816 ErrorMessage<uint8_t > (PSTR(
"ClearEpHalt"), ret);
830 void BulkOnly::Reset() {
831 while (
pUsb->
ctrlReq(
bAddress, 0,
bmREQ_MASSOUT,
MASS_REQ_BOMSR, 0, 0,
bIface, 0, 0, NULL, NULL) == 0x01) delay(6);
839 uint8_t BulkOnly::ResetRecovery() {
840 Notify(PSTR(
"\r\nResetRecovery\r\n"), 0x80);
841 Notify(PSTR(
"-----------------\r\n"), 0x80);
858 void BulkOnly::ClearAllEP() {
893 Notify(PSTR(
"CSW:Sig error\r\n"), 0x80);
897 Notify(PSTR(
"CSW:Wrong tag\r\n"), 0x80);
910 uint8_t BulkOnly::HandleUsbError(uint8_t error, uint8_t index) {
916 while (error && count) {
918 ErrorMessage<uint8_t > (PSTR(
"USB Error"), error);
919 ErrorMessage<uint8_t > (PSTR(
"Index"), index);
956 ErrorMessage<uint8_t > (PSTR(
"\r\nUSB"), error);
989 printf(
"Transfersize %i\r\n", bytes);
994 uint16_t bytes = buf_size;
1001 ErrorMessage<uint32_t > (PSTR(
"CBW.dCBWTag"), pcbw->
dCBWTag);
1005 ret = HandleUsbError(usberr, epDataOutIndex);
1008 ErrorMessage<uint8_t > (PSTR(
"============================ CBW"), ret);
1014 uint8_t rbuf[bytes];
1024 ret = HandleUsbError(usberr, epDataInIndex);
1027 ret = HandleUsbError(usberr, epDataOutIndex);
1030 ErrorMessage<uint8_t > (PSTR(
"============================ DAT"), ret);
1041 ClearEpHalt(epDataInIndex);
1042 if (tries) ResetRecovery();
1045 Notify(PSTR(
"CBW:\t\tOK\r\n"), 0x80);
1046 Notify(PSTR(
"Data Stage:\tOK\r\n"), 0x80);
1052 ret = HandleUsbError(usberr, epDataInIndex);
1054 ErrorMessage<uint8_t > (PSTR(
"============================ CSW"), ret);
1057 if (IsValidCSW(&csw, pcbw)) {
1061 Notify(PSTR(
"CSW:\t\tOK\r\n\r\n"), 0x80);
1069 Notify(PSTR(
"Invalid CSW\r\n"), 0x80);
1085 uint8_t BulkOnly::SetCurLUN(uint8_t lun) {
1098 uint8_t BulkOnly::HandleSCSIError(uint8_t status) {
1105 ErrorMessage<uint8_t > (PSTR(
"Phase Error"), status);
1106 ErrorMessage<uint8_t > (PSTR(
"LUN"),
bTheLUN);
1111 ErrorMessage<uint8_t > (PSTR(
"SCSI Error"), status);
1112 ErrorMessage<uint8_t > (PSTR(
"LUN"),
bTheLUN);
1120 ErrorMessage<uint8_t > (PSTR(
"Response Code"), rsp.bResponseCode);
1121 if (rsp.bResponseCode & 0x80) {
1122 Notify(PSTR(
"Information field: "), 0x80);
1123 for (
int i = 0; i < 4; i++) {
1124 D_PrintHex<uint8_t > (rsp.CmdSpecificInformation[i], 0x80);
1127 Notify(PSTR(
"\r\n"), 0x80);
1129 ErrorMessage<uint8_t > (PSTR(
"Sense Key"), rsp.bmSenseKey);
1130 ErrorMessage<uint8_t > (PSTR(
"Add Sense Code"), rsp.bAdditionalSenseCode);
1131 ErrorMessage<uint8_t > (PSTR(
"Add Sense Qual"), rsp.bAdditionalSenseQualifier);
1133 switch (rsp.bmSenseKey) {
1135 switch (rsp.bAdditionalSenseCode) {
1142 switch (rsp.bAdditionalSenseCode) {
1149 switch (rsp.bAdditionalSenseCode) {
1163 ErrorMessage<uint8_t > (PSTR(
"Gen SCSI Err"), status);
1164 ErrorMessage<uint8_t > (PSTR(
"LUN"),
bTheLUN);
1183 Notify(PSTR(
"Endpoint descriptor:"), 0x80);
1184 Notify(PSTR(
"\r\nLength:\t\t"), 0x80);
1185 D_PrintHex<uint8_t > (ep_ptr->
bLength, 0x80);
1186 Notify(PSTR(
"\r\nType:\t\t"), 0x80);
1188 Notify(PSTR(
"\r\nAddress:\t"), 0x80);
1190 Notify(PSTR(
"\r\nAttributes:\t"), 0x80);
1192 Notify(PSTR(
"\r\nMaxPktSize:\t"), 0x80);
1194 Notify(PSTR(
"\r\nPoll Intrv:\t"), 0x80);
1195 D_PrintHex<uint8_t > (ep_ptr->
bInterval, 0x80);
1196 Notify(PSTR(
"\r\n"), 0x80);
1212 Notify(PSTR(
"\r\nRead (With parser)\r\n"), 0x80);
1213 Notify(PSTR(
"---------\r\n"), 0x80);
1225 cbw.
CBWCB[8] = blocks;
1226 cbw.
CBWCB[2] = ((addr >> 24) & 0xff);
1227 cbw.
CBWCB[3] = ((addr >> 16) & 0xff);
1228 cbw.
CBWCB[4] = ((addr >> 8) & 0xff);
1229 cbw.
CBWCB[5] = (addr & 0xff);
1231 return HandleSCSIError(Transaction(&cbw, bsize, prs, 1));
#define MASS_ERR_UNIT_BUSY
#define SCSI_S_ILLEGAL_REQUEST
uint8_t getConfDescr(uint8_t addr, uint8_t ep, uint16_t nbytes, uint8_t conf, uint8_t *dataptr)
uint8_t MediaCTL(uint8_t lun, uint8_t ctl)
#define USB_SETUP_HOST_TO_DEVICE
static const uint8_t epDataOutIndex
#define CP_MASK_COMPARE_PROTOCOL
#define USB_ERROR_EPINFO_IS_NULL
bool LUNOk[MASS_MAX_SUPPORTED_LUN]
#define SCSI_ASC_MEDIA_CHANGED
static const uint8_t epInterruptInIndex
#define MASS_ERR_MEDIA_CHANGED
#define MASS_ERR_NO_MEDIA
#define USB_CLASS_MASS_STORAGE
#define MASS_SUBCLASS_SCSI
#define SCSI_CMD_PREVENT_REMOVAL
#define SCSI_S_UNIT_ATTENTION
#define USB_REQUEST_CLEAR_FEATURE
virtual uint8_t ConfigureDevice(uint8_t parent, uint8_t port, bool lowspeed)
#define MASS_ERR_INVALID_CSW
uint8_t setConf(uint8_t addr, uint8_t ep, uint8_t conf_value)
#define SCSI_CMD_TEST_UNIT_READY
#define MASS_ERR_WRITE_PROTECTED
uint32_t CurrentCapacity[MASS_MAX_SUPPORTED_LUN]
bool WriteOk[MASS_MAX_SUPPORTED_LUN]
#define MASS_MAX_SUPPORTED_LUN
uint8_t SCSITransaction10(CDB10_t *cdb, uint16_t buf_size, void *buf, uint8_t dir)
void PrintEndpointDescriptor(const USB_ENDPOINT_DESCRIPTOR *ep_ptr)
virtual uint8_t Release()
#define MASS_TRANS_FLG_CALLBACK
#define USB_ERROR_FailGetDevDescr
uint8_t Read(uint8_t lun, uint32_t addr, uint16_t bsize, uint8_t blocks, uint8_t *buf)
#define NotifyFailGetDevDescr(...)
uint32_t dCBWDataTransferLength
uint8_t setEpInfoEntry(uint8_t addr, uint8_t epcount, EpInfo *eprecord_ptr)
#define CP_MASK_COMPARE_CLASS
uint8_t SCSITransaction6(CDB6_t *cdb, uint16_t buf_size, void *buf, uint8_t dir)
#define MASS_ERR_GENERAL_USB_ERROR
virtual void FreeAddress(uint8_t addr)=0
uint32_t GetCapacity(uint8_t lun)
uint8_t ctrlReq(uint8_t addr, uint8_t ep, uint8_t bmReqType, uint8_t bRequest, uint8_t wValLo, uint8_t wValHi, uint16_t wInd, uint16_t total, uint16_t nbytes, uint8_t *dataptr, USBReadParser *p)
virtual UsbDevice * GetUsbDevicePtr(uint8_t addr)=0
#define USB_FEATURE_ENDPOINT_HALT
uint8_t setAddr(uint8_t oldaddr, uint8_t ep, uint8_t newaddr)
#define NotifyFailGetConfDescr(...)
static const uint8_t epDataInIndex
uint8_t PeripheralQualifier
uint16_t CurrentSectorSize[MASS_MAX_SUPPORTED_LUN]
#define USB_SETUP_RECIPIENT_ENDPOINT
#define MASS_MAX_ENDPOINTS
#define SCSI_ASC_MEDIUM_NOT_PRESENT
bool LUNIsGood(uint8_t lun)
#define MASS_REQ_GET_MAX_LUN
uint8_t outTransfer(uint8_t addr, uint8_t ep, uint16_t nbytes, uint8_t *data)
#define MASS_ERR_NOT_IMPLEMENTED
uint16_t GetSectorSize(uint8_t lun)
#define MASS_ERR_GENERAL_SCSI_ERROR
#define MASS_ERR_DEVICE_DISCONNECTED
#define CP_MASK_COMPARE_SUBCLASS
uint8_t LockMedia(uint8_t lun, uint8_t lock)
EpInfo epInfo[MASS_MAX_ENDPOINTS]
#define MASS_ERR_WRITE_STALL
virtual uint8_t AllocAddress(uint8_t parent, bool is_hub=false, uint8_t port=0)=0
#define USB_ERROR_CLASS_INSTANCE_ALREADY_IN_USE
#define SCSI_CMD_START_STOP_UNIT
#define USB_ERROR_ADDRESS_NOT_FOUND_IN_POOL
uint8_t inTransfer(uint8_t addr, uint8_t ep, uint16_t *nbytesptr, uint8_t *data)
#define USB_DEV_CONFIG_ERROR_DEVICE_NOT_SUPPORTED
#define MASS_ERR_UNIT_NOT_READY
#define SCSI_CMD_READ_CAPACITY_10
#define MASS_ERR_CMD_NOT_SUPPORTED
#define MASS_CSW_SIGNATURE
#define USB_ERROR_OUT_OF_ADDRESS_SPACE_IN_POOL
uint8_t Write(uint8_t lun, uint32_t addr, uint16_t bsize, uint8_t blocks, const uint8_t *buf)
virtual void EndpointXtract(uint8_t conf, uint8_t iface, uint8_t alt, uint8_t proto, const USB_ENDPOINT_DESCRIPTOR *ep)
AddressPool & GetAddressPool()
#define SCSI_ASC_LBA_OUT_OF_RANGE
#define USB_SETUP_TYPE_STANDARD
virtual uint8_t Init(uint8_t parent, uint8_t port, bool lowspeed)
boolean WriteProtected(uint8_t lun)
#define BMAKE32(__usc3__, __usc2__, __usc1__, __usc0__)
uint8_t RegisterDeviceClass(USBDeviceConfig *pdev)
#define NotifyFailSetConfDescr(...)
#define MASS_CBW_SIGNATURE
#define MASS_ERR_INVALID_LUN
#define SCSI_CMD_REQUEST_SENSE
uint8_t getDevDescr(uint8_t addr, uint8_t ep, uint16_t nbytes, uint8_t *dataptr)
defined(USB_METHODS_INLINE)
#define NotifyFailSetDevTblEntry(...)
#define SCSI_CMD_WRITE_10
#define USB_ERROR_CONFIG_REQUIRES_ADDITIONAL_RESET