94 return (HandleSCSIError(Transaction(&cbw, buf_size, buf)));
110 return (HandleSCSIError(Transaction(&cbw, buf_size, buf)));
161 uint8_t
BulkOnly::Read(uint8_t lun, uint32_t addr, uint16_t bsize, uint8_t blocks, uint8_t *buf) {
164 D_PrintHex<uint8_t > (lun, 0x90);
166 D_PrintHex<uint32_t > (addr, 0x90);
168 D_PrintHex<uint8_t > (blocks, 0x90);
170 D_PrintHex<uint16_t > (bsize, 0x90);
180 if(!TestUnitReady(lun))
goto again;
195 uint8_t
BulkOnly::Write(uint8_t lun, uint32_t addr, uint16_t bsize, uint8_t blocks,
const uint8_t * buf) {
199 D_PrintHex<uint8_t > (lun, 0x90);
201 D_PrintHex<uint32_t > (addr, 0x90);
203 D_PrintHex<uint8_t > (blocks, 0x90);
205 D_PrintHex<uint16_t > (bsize, 0x90);
215 if(!TestUnitReady(lun))
goto again;
262 uint8_t buf[constBufSize];
301 goto FailGetDevDescr;
317 #ifdef DEBUG_USB_HOST 333 uint8_t
BulkOnly::Init(uint8_t parent __attribute__((unused)), uint8_t port __attribute__((unused)),
bool lowspeed) {
372 goto FailSetDevTblEntry;
376 for(uint8_t i = 0; i < num_of_conf; i++) {
387 goto FailGetConfDescr;
405 goto FailSetConfDescr;
419 for(uint8_t lun = 0; lun <=
bMaxLUN; lun++) {
423 ErrorMessage<uint8_t > (
PSTR(
"Inquiry"), rcode);
426 printf(
"LUN %i `", lun);
427 uint8_t *buf = response.VendorID;
428 for(
int i = 0; i < 28; i++) printf(
"%c", buf[i]);
429 printf(
"'\r\nQualifier %1.1X ", response.PeripheralQualifier);
430 printf(
"Device type %2.2X ", response.DeviceType);
431 printf(
"RMB %1.1X ", response.Removable);
432 printf(
"SSCS %1.1X ", response.SCCS);
433 uint8_t sv = response.Version;
434 printf(
"SCSI version %2.2X\r\nDevice conforms to ", sv);
437 printf(
"No specific");
440 printf(
"ANSI X3.131-1986 (ANSI 1)");
443 printf(
"ANSI X3.131-1994 (ANSI 2)");
446 printf(
"ANSI INCITS 301-1997 (SPC)");
449 printf(
"ANSI INCITS 351-2001 (SPC-2)");
452 printf(
"ANSI INCITS 408-2005 (SPC-4)");
455 printf(
"T10/1731-D (SPC-4)");
460 printf(
" standards.\r\n");
462 uint8_t tries = 0xf0;
463 while((rcode = TestUnitReady(lun))) {
464 if(rcode == 0x08)
break;
469 }
else delay(2 * (tries + 1));
475 LUNOk[lun] = CheckLUN(lun);
489 #ifdef DEBUG_USB_HOST 499 #ifdef DEBUG_USB_HOST 505 #ifdef DEBUG_USB_HOST 511 #ifdef DEBUG_USB_HOST 523 #ifdef DEBUG_USB_HOST 529 #ifdef DEBUG_USB_HOST 533 #ifdef DEBUG_USB_HOST 551 ErrorMessage<uint8_t > (
PSTR(
"Conf.Val"), conf);
552 ErrorMessage<uint8_t > (
PSTR(
"Iface Num"), iface);
553 ErrorMessage<uint8_t > (
PSTR(
"Alt.Set"), alt);
610 bool BulkOnly::CheckLUN(uint8_t lun) {
613 for(uint8_t i = 0; i < 8; i++) capacity.
data[i] = 0;
615 rcode = ReadCapacity10(lun, (uint8_t*)capacity.
data);
620 ErrorMessage<uint8_t > (
PSTR(
">>>>>>>>>>>>>>>>CAPACITY OK ON LUN"), lun);
621 for(uint8_t i = 0; i < 8 ; i++)
622 D_PrintHex<uint8_t > (capacity.
data[i], 0x80);
626 if(c != 0x0200LU && c != 0x0400LU && c != 0x0800LU && c != 0x1000LU) {
636 ErrorMessage<uint8_t > (
PSTR(
">>>>>>>>>>>>>>>>BUGGY FIRMWARE. CAPACITY FAIL ON LUN"), lun);
641 if(!TestUnitReady(lun))
return true;
650 void BulkOnly::CheckMedia() {
651 for(uint8_t lun = 0; lun <=
bMaxLUN; lun++) {
652 if(TestUnitReady(lun)) {
657 LUNOk[lun] = CheckLUN(lun);
660 printf(
"}}}}}}}}}}}}}}}}STATUS ");
661 for(uint8_t lun = 0; lun <=
bMaxLUN; lun++) {
704 uint8_t BulkOnly::GetMaxLUN(uint8_t *plun) {
705 uint8_t ret =
pUsb->
ctrlReq(
bAddress, 0,
bmREQ_MASSIN,
MASS_REQ_GET_MAX_LUN, 0, 0,
bIface, 1, 1, plun, NULL);
721 uint8_t BulkOnly::Inquiry(uint8_t lun, uint16_t bsize, uint8_t *buf) {
737 uint8_t BulkOnly::TestUnitReady(uint8_t lun) {
761 uint8_t BulkOnly::ModeSense6(uint8_t lun, uint8_t pc, uint8_t page, uint8_t subpage, uint8_t len, uint8_t * pbuf) {
777 uint8_t BulkOnly::ReadCapacity10(uint8_t lun, uint8_t *buf) {
793 uint8_t BulkOnly::Page3F(uint8_t lun) {
795 for(
int i = 0; i < 192; i++) {
799 uint8_t rc = ModeSense6(lun, 0, 0x3f, 0, 192, buf);
801 WriteOk[lun] = ((buf[2] & 0x80) == 0);
803 for(
int i = 0; i < 4; i++) {
804 D_PrintHex<uint8_t > (buf[i], 0x80);
820 uint8_t BulkOnly::RequestSense(uint8_t lun, uint16_t size, uint8_t *buf) {
827 return Transaction(&cbw, size, buf);
845 uint8_t BulkOnly::ClearEpHalt(uint8_t index) {
851 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))
855 ErrorMessage<uint8_t > (
PSTR(
"ClearEpHalt"), ret);
868 void BulkOnly::Reset() {
869 while(
pUsb->
ctrlReq(
bAddress, 0,
bmREQ_MASSOUT,
MASS_REQ_BOMSR, 0, 0,
bIface, 0, 0, NULL, NULL) == 0x01) delay(6);
877 uint8_t BulkOnly::ResetRecovery() {
896 void BulkOnly::ClearAllEP() {
948 uint8_t BulkOnly::HandleUsbError(uint8_t error, uint8_t index) {
954 while(error && count) {
956 ErrorMessage<uint8_t > (
PSTR(
"USB Error"), error);
957 ErrorMessage<uint8_t > (
PSTR(
"Index"), index);
994 ErrorMessage<uint8_t > (
PSTR(
"\r\nUSB"), error);
1027 printf(
"Transfersize %i\r\n", bytes);
1032 uint16_t bytes = buf_size;
1039 ErrorMessage<uint32_t > (
PSTR(
"CBW.dCBWTag"), pcbw->
dCBWTag);
1043 ret = HandleUsbError(usberr, epDataOutIndex);
1046 ErrorMessage<uint8_t > (
PSTR(
"============================ CBW"), ret);
1052 uint8_t rbuf[bytes];
1065 ret = HandleUsbError(usberr, epDataOutIndex);
1068 ErrorMessage<uint8_t > (
PSTR(
"============================ DAT"), ret);
1079 ClearEpHalt(epDataInIndex);
1080 if(tries) ResetRecovery();
1092 ErrorMessage<uint8_t > (
PSTR(
"============================ CSW"), ret);
1095 if(IsValidCSW(&csw, pcbw)) {
1123 uint8_t BulkOnly::SetCurLUN(uint8_t lun) {
1136 uint8_t BulkOnly::HandleSCSIError(uint8_t status) {
1143 ErrorMessage<uint8_t > (
PSTR(
"Phase Error"), status);
1149 ErrorMessage<uint8_t > (
PSTR(
"SCSI Error"), status);
1158 ErrorMessage<uint8_t > (
PSTR(
"Response Code"), rsp.bResponseCode);
1159 if(rsp.bResponseCode & 0x80) {
1161 for(
int i = 0; i < 4; i++) {
1162 D_PrintHex<uint8_t > (rsp.CmdSpecificInformation[i], 0x80);
1167 ErrorMessage<uint8_t > (
PSTR(
"Sense Key"), rsp.bmSenseKey);
1168 ErrorMessage<uint8_t > (
PSTR(
"Add Sense Code"), rsp.bAdditionalSenseCode);
1169 ErrorMessage<uint8_t > (
PSTR(
"Add Sense Qual"), rsp.bAdditionalSenseQualifier);
1171 switch(rsp.bmSenseKey) {
1173 switch(rsp.bAdditionalSenseCode) {
1180 switch(rsp.bAdditionalSenseCode) {
1187 switch(rsp.bAdditionalSenseCode) {
1201 ErrorMessage<uint8_t > (
PSTR(
"Gen SCSI Err"), status);
1223 D_PrintHex<uint8_t > (ep_ptr->
bLength, 0x80);
1233 D_PrintHex<uint8_t > (ep_ptr->
bInterval, 0x80);
1247 uint8_t
BulkOnly::Read(uint8_t lun __attribute__((unused)), uint32_t addr __attribute__((unused)), uint16_t bsize __attribute__((unused)), uint8_t blocks __attribute__((unused)),
USBReadParser * prs __attribute__((unused))) {
1250 Notify(
PSTR(
"\r\nRead (With parser)\r\n"), 0x80);
1263 cbw.
CBWCB[8] = blocks;
1264 cbw.
CBWCB[2] = ((addr >> 24) & 0xff);
1265 cbw.
CBWCB[3] = ((addr >> 16) & 0xff);
1266 cbw.
CBWCB[4] = ((addr >> 8) & 0xff);
1267 cbw.
CBWCB[5] = (addr & 0xff);
1269 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 USB_TRANSFER_TYPE_INTERRUPT
#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)
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 bmUSB_TRANSFER_TYPE
#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 USB_TRANSFER_TYPE_BULK
#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