87 return (HandleSCSIError(Transaction(&cbw, buf_size, buf)));
103 return (HandleSCSIError(Transaction(&cbw, buf_size, buf)));
154 uint8_t
BulkOnly::Read(uint8_t lun, uint32_t addr, uint16_t bsize, uint8_t blocks, uint8_t *buf) {
157 D_PrintHex<uint8_t > (lun, 0x90);
159 D_PrintHex<uint32_t > (addr, 0x90);
161 D_PrintHex<uint8_t > (blocks, 0x90);
163 D_PrintHex<uint16_t > (bsize, 0x90);
173 if(!TestUnitReady(lun))
goto again;
188 uint8_t
BulkOnly::Write(uint8_t lun, uint32_t addr, uint16_t bsize, uint8_t blocks,
const uint8_t * buf) {
192 D_PrintHex<uint8_t > (lun, 0x90);
194 D_PrintHex<uint32_t > (addr, 0x90);
196 D_PrintHex<uint8_t > (blocks, 0x90);
198 D_PrintHex<uint16_t > (bsize, 0x90);
208 if(!TestUnitReady(lun))
goto again;
255 uint8_t buf[constBufSize];
294 goto FailGetDevDescr;
310 #ifdef DEBUG_USB_HOST 365 goto FailSetDevTblEntry;
369 for(uint8_t i = 0; i < num_of_conf; i++) {
380 goto FailGetConfDescr;
398 goto FailSetConfDescr;
412 for(uint8_t lun = 0; lun <=
bMaxLUN; lun++) {
416 ErrorMessage<uint8_t > (
PSTR(
"Inquiry"), rcode);
419 printf(
"LUN %i `", lun);
421 for(
int i = 0; i < 28; i++) printf(
"%c", buf[i]);
423 printf(
"Device type %2.2X ", response.
DeviceType);
424 printf(
"RMB %1.1X ", response.
Removable);
425 printf(
"SSCS %1.1X ", response.
SCCS);
427 printf(
"SCSI version %2.2X\r\nDevice conforms to ", sv);
430 printf(
"No specific");
433 printf(
"ANSI X3.131-1986 (ANSI 1)");
436 printf(
"ANSI X3.131-1994 (ANSI 2)");
439 printf(
"ANSI INCITS 301-1997 (SPC)");
442 printf(
"ANSI INCITS 351-2001 (SPC-2)");
445 printf(
"ANSI INCITS 408-2005 (SPC-4)");
448 printf(
"T10/1731-D (SPC-4)");
453 printf(
" standards.\r\n");
455 uint8_t tries = 0xf0;
456 while((rcode = TestUnitReady(lun))) {
457 if(rcode == 0x08)
break;
462 }
else delay(2 * (tries + 1));
468 LUNOk[lun] = CheckLUN(lun);
482 #ifdef DEBUG_USB_HOST 492 #ifdef DEBUG_USB_HOST 498 #ifdef DEBUG_USB_HOST 504 #ifdef DEBUG_USB_HOST 516 #ifdef DEBUG_USB_HOST 522 #ifdef DEBUG_USB_HOST 526 #ifdef DEBUG_USB_HOST 544 ErrorMessage<uint8_t > (
PSTR(
"Conf.Val"), conf);
545 ErrorMessage<uint8_t > (
PSTR(
"Iface Num"), iface);
546 ErrorMessage<uint8_t > (
PSTR(
"Alt.Set"), alt);
604 bool BulkOnly::CheckLUN(uint8_t lun) {
607 for(uint8_t i = 0; i < 8; i++) capacity.
data[i] = 0;
609 rcode = ReadCapacity10(lun, (uint8_t*)capacity.
data);
614 ErrorMessage<uint8_t > (
PSTR(
">>>>>>>>>>>>>>>>CAPACITY OK ON LUN"), lun);
615 for(uint8_t i = 0; i < 8 ; i++)
616 D_PrintHex<uint8_t > (capacity.
data[i], 0x80);
620 if(c != 0x0200LU && c != 0x0400LU && c != 0x0800LU && c != 0x1000LU) {
630 ErrorMessage<uint8_t > (
PSTR(
">>>>>>>>>>>>>>>>BUGGY FIRMWARE. CAPACITY FAIL ON LUN"), lun);
635 if(!TestUnitReady(lun))
return true;
644 void BulkOnly::CheckMedia() {
645 for(uint8_t lun = 0; lun <=
bMaxLUN; lun++) {
646 if(TestUnitReady(lun)) {
651 LUNOk[lun] = CheckLUN(lun);
654 printf(
"}}}}}}}}}}}}}}}}STATUS ");
655 for(uint8_t lun = 0; lun <=
bMaxLUN; lun++) {
698 uint8_t BulkOnly::GetMaxLUN(uint8_t *plun) {
699 uint8_t ret =
pUsb->
ctrlReq(
bAddress, 0,
bmREQ_MASSIN,
MASS_REQ_GET_MAX_LUN, 0, 0,
bIface, 1, 1, plun, NULL);
715 uint8_t BulkOnly::Inquiry(uint8_t lun, uint16_t bsize, uint8_t *buf) {
731 uint8_t BulkOnly::TestUnitReady(uint8_t lun) {
755 uint8_t BulkOnly::ModeSense6(uint8_t lun, uint8_t pc, uint8_t page, uint8_t subpage, uint8_t len, uint8_t * pbuf) {
771 uint8_t BulkOnly::ReadCapacity10(uint8_t lun, uint8_t *buf) {
787 uint8_t BulkOnly::Page3F(uint8_t lun) {
789 for(
int i = 0; i < 192; i++) {
793 uint8_t rc = ModeSense6(lun, 0, 0x3f, 0, 192, buf);
795 WriteOk[lun] = ((buf[2] & 0x80) == 0);
797 for(
int i = 0; i < 4; i++) {
798 D_PrintHex<uint8_t > (buf[i], 0x80);
814 uint8_t BulkOnly::RequestSense(uint8_t lun, uint16_t size, uint8_t *buf) {
821 return Transaction(&cbw, size, buf);
839 uint8_t BulkOnly::ClearEpHalt(uint8_t index) {
845 while((ret = (
pUsb->
ctrlReq(
bAddress, 0,
USB_SETUP_HOST_TO_DEVICE |
USB_SETUP_TYPE_STANDARD |
USB_SETUP_RECIPIENT_ENDPOINT,
USB_REQUEST_CLEAR_FEATURE,
USB_FEATURE_ENDPOINT_HALT, 0, ((index ==
epDataInIndex) ? (0x80 |
epInfo[index].
epAddr) :
epInfo[index].
epAddr), 0, 0, NULL, NULL)) == 0x01))
849 ErrorMessage<uint8_t > (
PSTR(
"ClearEpHalt"), ret);
862 void BulkOnly::Reset() {
863 while(
pUsb->
ctrlReq(
bAddress, 0,
bmREQ_MASSOUT,
MASS_REQ_BOMSR, 0, 0,
bIface, 0, 0, NULL, NULL) == 0x01) delay(6);
871 uint8_t BulkOnly::ResetRecovery() {
890 void BulkOnly::ClearAllEP() {
942 uint8_t BulkOnly::HandleUsbError(uint8_t error, uint8_t index) {
948 while(error && count) {
950 ErrorMessage<uint8_t > (
PSTR(
"USB Error"), error);
951 ErrorMessage<uint8_t > (
PSTR(
"Index"), index);
988 ErrorMessage<uint8_t > (
PSTR(
"\r\nUSB"), error);
1021 printf(
"Transfersize %i\r\n", bytes);
1026 uint16_t bytes = buf_size;
1033 ErrorMessage<uint32_t > (
PSTR(
"CBW.dCBWTag"), pcbw->
dCBWTag);
1037 ret = HandleUsbError(usberr, epDataOutIndex);
1040 ErrorMessage<uint8_t > (
PSTR(
"============================ CBW"), ret);
1046 uint8_t rbuf[bytes];
1059 ret = HandleUsbError(usberr, epDataOutIndex);
1062 ErrorMessage<uint8_t > (
PSTR(
"============================ DAT"), ret);
1073 ClearEpHalt(epDataInIndex);
1074 if(tries) ResetRecovery();
1086 ErrorMessage<uint8_t > (
PSTR(
"============================ CSW"), ret);
1089 if(IsValidCSW(&csw, pcbw)) {
1117 uint8_t BulkOnly::SetCurLUN(uint8_t lun) {
1130 uint8_t BulkOnly::HandleSCSIError(uint8_t status) {
1137 ErrorMessage<uint8_t > (
PSTR(
"Phase Error"), status);
1143 ErrorMessage<uint8_t > (
PSTR(
"SCSI Error"), status);
1152 ErrorMessage<uint8_t > (
PSTR(
"Response Code"), rsp.bResponseCode);
1153 if(rsp.bResponseCode & 0x80) {
1155 for(
int i = 0; i < 4; i++) {
1156 D_PrintHex<uint8_t > (rsp.CmdSpecificInformation[i], 0x80);
1161 ErrorMessage<uint8_t > (
PSTR(
"Sense Key"), rsp.bmSenseKey);
1162 ErrorMessage<uint8_t > (
PSTR(
"Add Sense Code"), rsp.bAdditionalSenseCode);
1163 ErrorMessage<uint8_t > (
PSTR(
"Add Sense Qual"), rsp.bAdditionalSenseQualifier);
1165 switch(rsp.bmSenseKey) {
1167 switch(rsp.bAdditionalSenseCode) {
1174 switch(rsp.bAdditionalSenseCode) {
1181 switch(rsp.bAdditionalSenseCode) {
1195 ErrorMessage<uint8_t > (
PSTR(
"Gen SCSI Err"), status);
1217 D_PrintHex<uint8_t > (ep_ptr->
bLength, 0x80);
1227 D_PrintHex<uint8_t > (ep_ptr->
bInterval, 0x80);
1244 Notify(
PSTR(
"\r\nRead (With parser)\r\n"), 0x80);
1257 cbw.
CBWCB[8] = blocks;
1258 cbw.
CBWCB[2] = ((addr >> 24) & 0xff);
1259 cbw.
CBWCB[3] = ((addr >> 16) & 0xff);
1260 cbw.
CBWCB[4] = ((addr >> 8) & 0xff);
1261 cbw.
CBWCB[5] = (addr & 0xff);
1263 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
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)
#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(...)
#define SCSI_CMD_MODE_SENSE_6
static const uint8_t epDataInIndex
bool WriteProtected(uint8_t lun)
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
#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
uint8_t inTransfer(uint8_t addr, uint8_t ep, uint16_t *nbytesptr, uint8_t *data, uint8_t bInterval=0)
uint8_t bNumConfigurations
#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)
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
uint8_t Init(uint8_t parent, uint8_t port, bool lowspeed)
#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