67 Notify(PSTR(
"\r\nLockMedia\r\n"), 0x80);
68 Notify(PSTR(
"---------\r\n"), 0x80);
79 for (uint8_t i = 0; i < 16; i++)
85 return (HandleSCSIError(Transaction(&cbw, 0, NULL, 0)));
98 Notify(PSTR(
"\r\nMediaCTL\r\n"), 0x80);
99 Notify(PSTR(
"-----------------\r\n"), 0x80);
112 for (uint8_t i = 0; i < 16; i++)
116 cbw.
CBWCB[1] = lun << 5;
117 cbw.
CBWCB[4] = ctl & 0x03;
119 rcode = HandleSCSIError(Transaction(&cbw, 0, NULL, 0));
134 uint8_t
BulkOnly::Read(uint8_t lun, uint32_t addr, uint16_t bsize, uint8_t blocks, uint8_t *buf) {
136 Notify(PSTR(
"\r\nRead LUN:\t"), 0x80);
137 D_PrintHex<uint8_t > (lun, 0x90);
139 Notify(PSTR(
"\r\nLBA:\t\t"), 0x90);
140 D_PrintHex<uint32_t > (addr, 0x90);
141 Notify(PSTR(
"\r\nblocks:\t\t"), 0x90);
142 D_PrintHex<uint8_t > (blocks, 0x90);
143 Notify(PSTR(
"\r\nblock size:\t"), 0x90);
144 D_PrintHex<uint16_t > (bsize, 0x90);
145 Notify(PSTR(
"\r\n---------\r\n"), 0x80);
155 for (uint8_t i = 0; i < 16; i++)
159 cbw.
CBWCB[1] = lun << 5;
160 cbw.
CBWCB[2] = ((addr >> 24) & 0xff);
161 cbw.
CBWCB[3] = ((addr >> 16) & 0xff);
162 cbw.
CBWCB[4] = ((addr >> 8) & 0xff);
163 cbw.
CBWCB[5] = (addr & 0xff);
164 cbw.
CBWCB[8] = blocks;
167 uint8_t er = HandleSCSIError(Transaction(&cbw, bsize, buf, 0));
171 if (!TestUnitReady(lun))
goto again;
186 uint8_t
BulkOnly::Write(uint8_t lun, uint32_t addr, uint16_t bsize, uint8_t blocks,
const uint8_t * buf) {
189 Notify(PSTR(
"\r\nWrite LUN:\t"), 0x80);
190 D_PrintHex<uint8_t > (lun, 0x90);
192 Notify(PSTR(
"\r\nLBA:\t\t"), 0x90);
193 D_PrintHex<uint32_t > (addr, 0x90);
194 Notify(PSTR(
"\r\nblocks:\t\t"), 0x90);
195 D_PrintHex<uint8_t > (blocks, 0x90);
196 Notify(PSTR(
"\r\nblock size:\t"), 0x90);
197 D_PrintHex<uint16_t > (bsize, 0x90);
198 Notify(PSTR(
"\r\n---------\r\n"), 0x80);
210 for (uint8_t i = 0; i < 16; i++)
214 cbw.
CBWCB[1] = lun << 5;
215 cbw.
CBWCB[2] = ((addr >> 24) & 0xff);
216 cbw.
CBWCB[3] = ((addr >> 16) & 0xff);
217 cbw.
CBWCB[4] = ((addr >> 8) & 0xff);
218 cbw.
CBWCB[5] = (addr & 0xff);
222 uint8_t er = HandleSCSIError(Transaction(&cbw, bsize, (
void*)buf, 0));
226 if (!TestUnitReady(lun))
goto again;
274 uint8_t buf[constBufSize];
313 goto FailGetDevDescr;
329 #ifdef DEBUG_USB_HOST
385 goto FailSetDevTblEntry;
389 for (uint8_t i = 0; i < num_of_conf; i++) {
400 goto FailGetConfDescr;
418 goto FailSetConfDescr;
428 ErrorMessage<uint8_t > (PSTR(
"MaxLUN"),
bMaxLUN);
434 for (uint8_t lun = 0; lun <=
bMaxLUN; lun++) {
438 ErrorMessage<uint8_t > (PSTR(
"Inquiry"), rcode);
440 uint8_t tries = 0xf0;
441 while (rcode = TestUnitReady(lun)) {
442 if (rcode == 0x08)
break;
447 }
else delay(2 * (tries + 1));
453 LUNOk[lun] = CheckLUN(lun);
463 for (uint8_t i = 1; i == 0; i++) {
466 for (uint8_t lun = 0; lun <=
bMaxLUN; lun++) good |=
LUNOk[lun];
488 #ifdef DEBUG_USB_HOST
494 #ifdef DEBUG_USB_HOST
500 #ifdef DEBUG_USB_HOST
505 FailInvalidSectorSize:
506 #ifdef DEBUG_USB_HOST
507 USBTRACE(
"Sector Size is NOT VALID: ");
512 #ifdef DEBUG_USB_HOST
518 #ifdef DEBUG_USB_HOST
523 #ifdef DEBUG_USB_HOST
540 ErrorMessage<uint8_t > (PSTR(
"Conf.Val"), conf);
541 ErrorMessage<uint8_t > (PSTR(
"Iface Num"), iface);
542 ErrorMessage<uint8_t > (PSTR(
"Alt.Set"), alt);
583 boolean BulkOnly::CheckLUN(uint8_t lun) {
586 for (uint8_t i = 0; i<
sizeof (
Capacity); i++) capacity.
data[i] = 0;
588 rcode = ReadCapacity(lun,
sizeof (
Capacity), (uint8_t*) & capacity);
593 ErrorMessage<uint8_t > (PSTR(
">>>>>>>>>>>>>>>>CAPACITY OK ON LUN"), lun);
594 for (uint8_t i = 0; i<
sizeof (
Capacity); i++)
595 D_PrintHex<uint8_t > (capacity.
data[i], 0x80);
596 Notify(PSTR(
"\r\n\r\n"), 0x80);
598 uint32_t c = ((uint32_t)capacity.
data[4] << 24) + ((uint32_t)capacity.
data[5] << 16) + ((uint32_t)capacity.
data[6] << 8) + (uint32_t)capacity.
data[7];
599 if (c != 0x0200LU && c != 0x0400LU && c != 0x0800LU && c != 0x1000LU) {
604 CurrentCapacity[lun] = ((uint32_t)capacity.
data[0] << 24) + ((uint32_t)capacity.
data[1] << 16) + ((uint32_t)capacity.
data[2] << 8) + (uint32_t)capacity.
data[3];
608 ErrorMessage<uint8_t > (PSTR(
">>>>>>>>>>>>>>>>BUGGY FIRMWARE. CAPACITY FAIL ON LUN"), lun);
613 if (!TestUnitReady(lun))
return true;
623 void BulkOnly::CheckMedia() {
624 for (uint8_t lun = 0; lun <=
bMaxLUN; lun++) {
625 if (TestUnitReady(lun)) {
630 LUNOk[lun] = CheckLUN(lun);
633 printf(
"}}}}}}}}}}}}}}}}STATUS ");
634 for (uint8_t lun = 0; lun <=
bMaxLUN; lun++) {
677 uint8_t BulkOnly::GetMaxLUN(uint8_t *plun) {
678 uint8_t ret =
pUsb->
ctrlReq(
bAddress, 0,
bmREQ_MASSIN,
MASS_REQ_GET_MAX_LUN, 0, 0,
bIface, 1, 1, plun, NULL);
695 uint8_t BulkOnly::Inquiry(uint8_t lun, uint16_t bsize, uint8_t *buf) {
696 Notify(PSTR(
"\r\nInquiry\r\n"), 0x80);
697 Notify(PSTR(
"---------\r\n"), 0x80);
708 for (uint8_t i = 0; i < 16; i++)
712 cbw.
CBWCB[1] = lun << 5;
713 cbw.
CBWCB[4] = bsize;
715 uint8_t rc = HandleSCSIError(Transaction(&cbw, bsize, buf, 0));
718 printf(
"LUN %i `", lun);
719 for (
int i = 8; i < 36; i++) printf(
"%c", buf[i]);
720 printf(
"'\r\nQualifier %1.1X ", (buf[0]&0xE0) >> 5);
721 printf(
"Device type %2.2X ", buf[0]&0x1f);
722 printf(
"RMB %1.1X ", buf[1]&0x80 >> 7);
723 printf(
"SSCS% 1.1X ", buf[5]&0x80 >> 7);
725 printf(
"SCSI version %2.2X\r\nDevice conforms to ", sv);
728 printf(
"No specific");
739 printf(
"ANSI INCITS 301-1997 (SPC)");
742 printf(
"ANSI INCITS 351-2001 (SPC-2)");
745 printf(
"ANSI INCITS 408-2005 (SPC-4)");
748 printf(
"T10/1731-D (SPC-4)");
753 printf(
" standards.\r\n");
767 uint8_t BulkOnly::RequestSense(uint8_t lun, uint16_t size, uint8_t *buf) {
768 Notify(PSTR(
"\r\nRequestSense\r\n"), 0x80);
769 Notify(PSTR(
"----------------\r\n"), 0x80);
781 for (uint8_t i = 0; i < 16; i++)
785 cbw.
CBWCB[1] = lun << 5;
788 return Transaction(&cbw, size, buf, 0);
799 uint8_t BulkOnly::ReadCapacity(uint8_t lun, uint16_t bsize, uint8_t *buf) {
800 Notify(PSTR(
"\r\nReadCapacity\r\n"), 0x80);
801 Notify(PSTR(
"---------------\r\n"), 0x80);
812 for (uint8_t i = 0; i < 16; i++)
816 cbw.
CBWCB[1] = lun << 5;
818 return HandleSCSIError(Transaction(&cbw, bsize, buf, 0));
827 uint8_t BulkOnly::TestUnitReady(uint8_t lun) {
832 Notify(PSTR(
"\r\nTestUnitReady\r\n"), 0x80);
833 Notify(PSTR(
"-----------------\r\n"), 0x80);
845 for (uint8_t i = 0; i < 16; i++)
850 rc = HandleSCSIError(Transaction(&cbw, 0, NULL, 0));
862 uint8_t BulkOnly::Page3F(uint8_t lun) {
864 for (
int i = 0; i < 192; i++) {
868 uint8_t rc = ModeSense(lun, 0, 0x3f, 0, 192, buf);
870 WriteOk[lun] = ((buf[2] & 0x80) == 0);
871 Notify(PSTR(
"Mode Sense: "), 0x80);
872 for (
int i = 0; i < 4; i++) {
873 D_PrintHex<uint8_t > (buf[i], 0x80);
876 Notify(PSTR(
"\r\n"), 0x80);
899 uint8_t BulkOnly::ClearEpHalt(uint8_t index) {
910 ErrorMessage<uint8_t > (PSTR(
"ClearEpHalt"), ret);
924 void BulkOnly::Reset() {
925 while (
pUsb->
ctrlReq(
bAddress, 0,
bmREQ_MASSOUT,
MASS_REQ_BOMSR, 0, 0,
bIface, 0, 0, NULL, NULL) == 0x01) delay(6);
933 uint8_t BulkOnly::ResetRecovery() {
934 Notify(PSTR(
"\r\nResetRecovery\r\n"), 0x80);
935 Notify(PSTR(
"-----------------\r\n"), 0x80);
952 void BulkOnly::ClearAllEP() {
983 Notify(PSTR(
"CSW:Sig error\r\n"), 0x80);
988 Notify(PSTR(
"CSW:Wrong tag\r\n"), 0x80);
1002 uint8_t BulkOnly::HandleUsbError(uint8_t error, uint8_t index) {
1008 while (error && count) {
1010 ErrorMessage<uint8_t > (PSTR(
"USB Error"), error);
1011 ErrorMessage<uint8_t > (PSTR(
"Index"), index);
1052 ErrorMessage<uint8_t > (PSTR(
"\r\nUSB"), error);
1070 uint8_t BulkOnly::Transaction(
CommandBlockWrapper *pcbw, uint16_t buf_size,
void *buf, uint8_t flags) {
1080 ErrorMessage<uint32_t > (PSTR(
"CBW.dCBWTag"), pcbw->
dCBWTag);
1084 ret = HandleUsbError(usberr, epDataOutIndex);
1087 ErrorMessage<uint8_t > (PSTR(
"============================ CBW"), ret);
1092 uint8_t rbuf[bytes];
1098 ret = HandleUsbError(usberr, epDataInIndex);
1101 ret = HandleUsbError(usberr, epDataOutIndex);
1104 ErrorMessage<uint8_t > (PSTR(
"============================ DAT"), ret);
1116 ClearEpHalt(epDataInIndex);
1118 if (tries) ResetRecovery();
1121 Notify(PSTR(
"CBW:\t\tOK\r\n"), 0x80);
1122 Notify(PSTR(
"Data Stage:\tOK\r\n"), 0x80);
1129 ret = HandleUsbError(usberr, epDataInIndex);
1131 ErrorMessage<uint8_t > (PSTR(
"============================ CSW"), ret);
1134 if (IsValidCSW(&csw, pcbw)) {
1138 Notify(PSTR(
"CSW:\t\tOK\r\n\r\n"), 0x80);
1141 Notify(PSTR(
"Invalid CSW\r\n"), 0x80);
1163 uint8_t BulkOnly::ModeSense(uint8_t lun, uint8_t pc, uint8_t page, uint8_t subpage, uint8_t len, uint8_t * pbuf) {
1164 Notify(PSTR(
"\r\rModeSense\r\n"), 0x80);
1165 Notify(PSTR(
"------------\r\n"), 0x80);
1177 for (uint8_t i = 0; i < 16; i++)
1181 cbw.
CBWCB[2] = ((pc << 6) | page);
1182 cbw.
CBWCB[3] = subpage;
1185 return HandleSCSIError(Transaction(&cbw, 512, pbuf, 0));
1194 uint8_t BulkOnly::SetCurLUN(uint8_t lun) {
1207 uint8_t BulkOnly::HandleSCSIError(uint8_t status) {
1216 ErrorMessage<uint8_t > (PSTR(
"Phase Error"), status);
1217 ErrorMessage<uint8_t > (PSTR(
"LUN"),
bTheLUN);
1221 ErrorMessage<uint8_t > (PSTR(
"SCSI Error"), status);
1222 ErrorMessage<uint8_t > (PSTR(
"LUN"),
bTheLUN);
1231 ErrorMessage<uint8_t > (PSTR(
"Response Code"), rsp.bResponseCode);
1232 if (rsp.bResponseCode & 0x80) {
1233 Notify(PSTR(
"Information field: "), 0x80);
1234 for (
int i = 0; i < 4; i++) {
1235 D_PrintHex<uint8_t > (rsp.CmdSpecificInformation[i], 0x80);
1238 Notify(PSTR(
"\r\n"), 0x80);
1240 ErrorMessage<uint8_t > (PSTR(
"Sense Key"), rsp.bmSenseKey);
1241 ErrorMessage<uint8_t > (PSTR(
"Add Sense Code"), rsp.bAdditionalSenseCode);
1242 ErrorMessage<uint8_t > (PSTR(
"Add Sense Qual"), rsp.bAdditionalSenseQualifier);
1244 switch (rsp.bmSenseKey) {
1250 switch (rsp.bAdditionalSenseCode) {
1257 switch (rsp.bAdditionalSenseCode) {
1265 switch (rsp.bAdditionalSenseCode) {
1278 ErrorMessage<uint8_t > (PSTR(
"Gen SCSI Err"), status);
1279 ErrorMessage<uint8_t > (PSTR(
"LUN"),
bTheLUN);
1299 Notify(PSTR(
"Endpoint descriptor:"), 0x80);
1300 Notify(PSTR(
"\r\nLength:\t\t"), 0x80);
1301 D_PrintHex<uint8_t > (ep_ptr->
bLength, 0x80);
1302 Notify(PSTR(
"\r\nType:\t\t"), 0x80);
1304 Notify(PSTR(
"\r\nAddress:\t"), 0x80);
1306 Notify(PSTR(
"\r\nAttributes:\t"), 0x80);
1308 Notify(PSTR(
"\r\nMaxPktSize:\t"), 0x80);
1310 Notify(PSTR(
"\r\nPoll Intrv:\t"), 0x80);
1311 D_PrintHex<uint8_t > (ep_ptr->
bInterval, 0x80);
1312 Notify(PSTR(
"\r\n"), 0x80);
1329 Notify(PSTR(
"\r\nRead (With parser)\r\n"), 0x80);
1330 Notify(PSTR(
"---------\r\n"), 0x80);
1341 for (uint8_t i = 0; i < 16; i++)
1345 cbw.
CBWCB[8] = blocks;
1346 cbw.
CBWCB[2] = ((addr >> 24) & 0xff);
1347 cbw.
CBWCB[3] = ((addr >> 16) & 0xff);
1348 cbw.
CBWCB[4] = ((addr >> 8) & 0xff);
1349 cbw.
CBWCB[5] = (addr & 0xff);
1351 return HandleSCSIError(Transaction(&cbw, bsize, prs, 1));
1361 uint8_t SubmitCBW(uint8_t cmd, uint8_t cmdsz, uint8_t lun, uint16_t bsize, uint8_t *buf, uint8_t flags) {
1370 for (uint8_t i = 0; i < 16; i++) cbw.
CBWCB[i] = 0;
1372 cbw.
CBWCB[1] = lun << 5;
1373 cbw.
CBWCB[4] = bsize;