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);
602 bool BulkOnly::CheckLUN(uint8_t lun) {
605 for(uint8_t i = 0; i < 8; i++) capacity.
data[i] = 0;
607 rcode = ReadCapacity10(lun, (uint8_t*)capacity.
data);
612 ErrorMessage<uint8_t > (
PSTR(
">>>>>>>>>>>>>>>>CAPACITY OK ON LUN"), lun);
613 for(uint8_t i = 0; i < 8 ; i++)
614 D_PrintHex<uint8_t > (capacity.
data[i], 0x80);
618 if(c != 0x0200LU && c != 0x0400LU && c != 0x0800LU && c != 0x1000LU) {
628 ErrorMessage<uint8_t > (
PSTR(
">>>>>>>>>>>>>>>>BUGGY FIRMWARE. CAPACITY FAIL ON LUN"), lun);
633 if(!TestUnitReady(lun))
return true;
642 void BulkOnly::CheckMedia() {
643 for(uint8_t lun = 0; lun <=
bMaxLUN; lun++) {
644 if(TestUnitReady(lun)) {
649 LUNOk[lun] = CheckLUN(lun);
652 printf(
"}}}}}}}}}}}}}}}}STATUS ");
653 for(uint8_t lun = 0; lun <=
bMaxLUN; lun++) {
696 uint8_t BulkOnly::GetMaxLUN(uint8_t *plun) {
697 uint8_t ret =
pUsb->
ctrlReq(
bAddress, 0,
bmREQ_MASSIN,
MASS_REQ_GET_MAX_LUN, 0, 0,
bIface, 1, 1, plun, NULL);
713 uint8_t BulkOnly::Inquiry(uint8_t lun, uint16_t bsize, uint8_t *buf) {
729 uint8_t BulkOnly::TestUnitReady(uint8_t lun) {
753 uint8_t BulkOnly::ModeSense6(uint8_t lun, uint8_t pc, uint8_t page, uint8_t subpage, uint8_t len, uint8_t * pbuf) {
769 uint8_t BulkOnly::ReadCapacity10(uint8_t lun, uint8_t *buf) {
785 uint8_t BulkOnly::Page3F(uint8_t lun) {
787 for(
int i = 0; i < 192; i++) {
791 uint8_t rc = ModeSense6(lun, 0, 0x3f, 0, 192, buf);
793 WriteOk[lun] = ((buf[2] & 0x80) == 0);
795 for(
int i = 0; i < 4; i++) {
796 D_PrintHex<uint8_t > (buf[i], 0x80);
812 uint8_t BulkOnly::RequestSense(uint8_t lun, uint16_t size, uint8_t *buf) {
819 return Transaction(&cbw, size, buf);
837 uint8_t BulkOnly::ClearEpHalt(uint8_t index) {
843 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))
847 ErrorMessage<uint8_t > (
PSTR(
"ClearEpHalt"), ret);
861 void BulkOnly::Reset() {
862 while(
pUsb->
ctrlReq(
bAddress, 0,
bmREQ_MASSOUT,
MASS_REQ_BOMSR, 0, 0,
bIface, 0, 0, NULL, NULL) == 0x01) delay(6);
870 uint8_t BulkOnly::ResetRecovery() {
889 void BulkOnly::ClearAllEP() {
941 uint8_t BulkOnly::HandleUsbError(uint8_t error, uint8_t index) {
947 while(error && count) {
949 ErrorMessage<uint8_t > (
PSTR(
"USB Error"), error);
950 ErrorMessage<uint8_t > (
PSTR(
"Index"), index);
987 ErrorMessage<uint8_t > (
PSTR(
"\r\nUSB"), error);
1020 printf(
"Transfersize %i\r\n", bytes);
1025 uint16_t bytes = buf_size;
1032 ErrorMessage<uint32_t > (
PSTR(
"CBW.dCBWTag"), pcbw->
dCBWTag);
1036 ret = HandleUsbError(usberr, epDataOutIndex);
1039 ErrorMessage<uint8_t > (
PSTR(
"============================ CBW"), ret);
1045 uint8_t rbuf[bytes];
1055 ret = HandleUsbError(usberr, epDataInIndex);
1058 ret = HandleUsbError(usberr, epDataOutIndex);
1061 ErrorMessage<uint8_t > (
PSTR(
"============================ DAT"), ret);
1072 ClearEpHalt(epDataInIndex);
1073 if(tries) ResetRecovery();
1083 ret = HandleUsbError(usberr, epDataInIndex);
1085 ErrorMessage<uint8_t > (
PSTR(
"============================ CSW"), ret);
1088 if(IsValidCSW(&csw, pcbw)) {
1116 uint8_t BulkOnly::SetCurLUN(uint8_t lun) {
1129 uint8_t BulkOnly::HandleSCSIError(uint8_t status) {
1136 ErrorMessage<uint8_t > (
PSTR(
"Phase Error"), status);
1142 ErrorMessage<uint8_t > (
PSTR(
"SCSI Error"), status);
1151 ErrorMessage<uint8_t > (
PSTR(
"Response Code"), rsp.bResponseCode);
1152 if(rsp.bResponseCode & 0x80) {
1154 for(
int i = 0; i < 4; i++) {
1155 D_PrintHex<uint8_t > (rsp.CmdSpecificInformation[i], 0x80);
1160 ErrorMessage<uint8_t > (
PSTR(
"Sense Key"), rsp.bmSenseKey);
1161 ErrorMessage<uint8_t > (
PSTR(
"Add Sense Code"), rsp.bAdditionalSenseCode);
1162 ErrorMessage<uint8_t > (
PSTR(
"Add Sense Qual"), rsp.bAdditionalSenseQualifier);
1164 switch(rsp.bmSenseKey) {
1166 switch(rsp.bAdditionalSenseCode) {
1173 switch(rsp.bAdditionalSenseCode) {
1180 switch(rsp.bAdditionalSenseCode) {
1194 ErrorMessage<uint8_t > (
PSTR(
"Gen SCSI Err"), status);
1216 D_PrintHex<uint8_t > (ep_ptr->
bLength, 0x80);
1226 D_PrintHex<uint8_t > (ep_ptr->
bInterval, 0x80);
1243 Notify(
PSTR(
"\r\nRead (With parser)\r\n"), 0x80);
1256 cbw.
CBWCB[8] = blocks;
1257 cbw.
CBWCB[2] = ((addr >> 24) & 0xff);
1258 cbw.
CBWCB[3] = ((addr >> 16) & 0xff);
1259 cbw.
CBWCB[4] = ((addr >> 8) & 0xff);
1260 cbw.
CBWCB[5] = (addr & 0xff);
1262 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(...)
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
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
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