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 PrintHex<uint8_t > (lun, 0x90);
139 Notify(PSTR(
"\r\nLBA:\t\t"), 0x90);
140 PrintHex<uint32_t > (addr, 0x90);
141 Notify(PSTR(
"\r\nblocks:\t\t"), 0x90);
142 PrintHex<uint8_t > (blocks, 0x90);
143 Notify(PSTR(
"\r\nblock size:\t"), 0x90);
144 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 PrintHex<uint8_t > (lun, 0x90);
192 Notify(PSTR(
"\r\nLBA:\t\t"), 0x90);
193 PrintHex<uint32_t > (addr, 0x90);
194 Notify(PSTR(
"\r\nblocks:\t\t"), 0x90);
195 PrintHex<uint8_t > (blocks, 0x90);
196 Notify(PSTR(
"\r\nblock size:\t"), 0x90);
197 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;
419 goto FailSetConfDescr;
429 ErrorMessage<uint8_t > (PSTR(
"MaxLUN"),
bMaxLUN);
435 for (uint8_t lun = 0; lun <=
bMaxLUN; lun++) {
439 ErrorMessage<uint8_t > (PSTR(
"Inquiry"), rcode);
441 uint8_t tries = 0xf0;
442 while (rcode = TestUnitReady(lun)) {
443 if (rcode == 0x08)
break;
448 }
else delay(2 * (tries + 1));
454 LUNOk[lun] = CheckLUN(lun);
464 for (uint8_t i = 1; i == 0; i++) {
467 for (uint8_t lun = 0; lun <=
bMaxLUN; lun++) good |=
LUNOk[lun];
489 #ifdef DEBUG_USB_HOST
495 #ifdef DEBUG_USB_HOST
501 #ifdef DEBUG_USB_HOST
506 FailInvalidSectorSize:
507 #ifdef DEBUG_USB_HOST
508 USBTRACE(
"Sector Size is NOT VALID: ");
513 #ifdef DEBUG_USB_HOST
519 #ifdef DEBUG_USB_HOST
524 #ifdef DEBUG_USB_HOST
548 boolean BulkOnly::CheckLUN(uint8_t lun) {
551 for (uint8_t i = 0; i<
sizeof (
Capacity); i++) capacity.
data[i] = 0;
553 rcode = ReadCapacity(lun,
sizeof (
Capacity), (uint8_t*) & capacity);
558 ErrorMessage<uint8_t > (PSTR(
">>>>>>>>>>>>>>>>CAPACITY OK ON LUN"), lun);
559 for (uint8_t i = 0; i<
sizeof (
Capacity); i++)
560 PrintHex<uint8_t > (capacity.
data[i], 0x80);
561 Notify(PSTR(
"\r\n\r\n"), 0x80);
563 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];
564 if (c != 0x0200LU && c != 0x0400LU && c != 0x0800LU && c != 0x1000LU) {
569 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];
573 ErrorMessage<uint8_t > (PSTR(
">>>>>>>>>>>>>>>>BUGGY FIRMWARE. CAPACITY FAIL ON LUN"), lun);
578 if (!TestUnitReady(lun))
return true;
588 void BulkOnly::CheckMedia() {
589 for (uint8_t lun = 0; lun <=
bMaxLUN; lun++) {
590 if (TestUnitReady(lun)) {
595 LUNOk[lun] = CheckLUN(lun);
598 printf(
"}}}}}}}}}}}}}}}}STATUS ");
599 for (uint8_t lun = 0; lun <=
bMaxLUN; lun++) {
642 uint8_t BulkOnly::GetMaxLUN(uint8_t *plun) {
643 uint8_t ret =
pUsb->
ctrlReq(
bAddress, 0,
bmREQ_MASSIN,
MASS_REQ_GET_MAX_LUN, 0, 0,
bIface, 1, 1, plun, NULL);
660 uint8_t BulkOnly::Inquiry(uint8_t lun, uint16_t bsize, uint8_t *buf) {
661 Notify(PSTR(
"\r\nInquiry\r\n"), 0x80);
662 Notify(PSTR(
"---------\r\n"), 0x80);
673 for (uint8_t i = 0; i < 16; i++)
677 cbw.
CBWCB[1] = lun << 5;
678 cbw.
CBWCB[4] = bsize;
680 uint8_t rc = HandleSCSIError(Transaction(&cbw, bsize, buf, 0));
683 printf(
"LUN %i `", lun);
684 for (
int i = 8; i < 36; i++) printf(
"%c", buf[i]);
685 printf(
"'\r\nQualifier %1.1X ", (buf[0]&0xE0) >> 5);
686 printf(
"Device type %2.2X ", buf[0]&0x1f);
687 printf(
"RMB %1.1X ", buf[1]&0x80 >> 7);
688 printf(
"SSCS% 1.1X ", buf[5]&0x80 >> 7);
690 printf(
"SCSI version %2.2X\r\nDevice conforms to ", sv);
693 printf(
"No specific");
704 printf(
"ANSI INCITS 301-1997 (SPC)");
707 printf(
"ANSI INCITS 351-2001 (SPC-2)");
710 printf(
"ANSI INCITS 408-2005 (SPC-4)");
713 printf(
"T10/1731-D (SPC-4)");
718 printf(
" standards.\r\n");
732 uint8_t BulkOnly::RequestSense(uint8_t lun, uint16_t size, uint8_t *buf) {
733 Notify(PSTR(
"\r\nRequestSense\r\n"), 0x80);
734 Notify(PSTR(
"----------------\r\n"), 0x80);
746 for (uint8_t i = 0; i < 16; i++)
750 cbw.
CBWCB[1] = lun << 5;
753 return Transaction(&cbw, size, buf, 0);
764 uint8_t BulkOnly::ReadCapacity(uint8_t lun, uint16_t bsize, uint8_t *buf) {
765 Notify(PSTR(
"\r\nReadCapacity\r\n"), 0x80);
766 Notify(PSTR(
"---------------\r\n"), 0x80);
777 for (uint8_t i = 0; i < 16; i++)
781 cbw.
CBWCB[1] = lun << 5;
783 return HandleSCSIError(Transaction(&cbw, bsize, buf, 0));
792 uint8_t BulkOnly::TestUnitReady(uint8_t lun) {
797 Notify(PSTR(
"\r\nTestUnitReady\r\n"), 0x80);
798 Notify(PSTR(
"-----------------\r\n"), 0x80);
810 for (uint8_t i = 0; i < 16; i++)
815 rc = HandleSCSIError(Transaction(&cbw, 0, NULL, 0));
827 uint8_t BulkOnly::Page3F(uint8_t lun) {
829 for (
int i = 0; i < 192; i++) {
833 uint8_t rc = ModeSense(lun, 0, 0x3f, 0, 192, buf);
835 WriteOk[lun] = ((buf[2] & 0x80) == 0);
836 Notify(PSTR(
"Mode Sense: "), 0x80);
837 for (
int i = 0; i < 4; i++) {
838 PrintHex<uint8_t > (buf[i], 0x80);
841 Notify(PSTR(
"\r\n"), 0x80);
864 uint8_t BulkOnly::ClearEpHalt(uint8_t index) {
875 ErrorMessage<uint8_t > (PSTR(
"ClearEpHalt"), ret);
889 void BulkOnly::Reset() {
890 while (
pUsb->
ctrlReq(
bAddress, 0,
bmREQ_MASSOUT,
MASS_REQ_BOMSR, 0, 0,
bIface, 0, 0, NULL, NULL) == 0x01) delay(6);
898 uint8_t BulkOnly::ResetRecovery() {
899 Notify(PSTR(
"\r\nResetRecovery\r\n"), 0x80);
900 Notify(PSTR(
"-----------------\r\n"), 0x80);
917 void BulkOnly::ClearAllEP() {
948 Notify(PSTR(
"CSW:Sig error\r\n"), 0x80);
953 Notify(PSTR(
"CSW:Wrong tag\r\n"), 0x80);
967 uint8_t BulkOnly::HandleUsbError(uint8_t error, uint8_t index) {
973 while (error && count) {
975 ErrorMessage<uint8_t > (PSTR(
"USB Error"), error);
976 ErrorMessage<uint8_t > (PSTR(
"Index"), index);
1017 ErrorMessage<uint8_t > (PSTR(
"\r\nUSB"), error);
1035 uint8_t BulkOnly::Transaction(
CommandBlockWrapper *pcbw, uint16_t buf_size,
void *buf, uint8_t flags) {
1045 ErrorMessage<uint32_t > (PSTR(
"CBW.dCBWTag"), pcbw->
dCBWTag);
1049 ret = HandleUsbError(usberr, epDataOutIndex);
1052 ErrorMessage<uint8_t > (PSTR(
"============================ CBW"), ret);
1057 uint8_t rbuf[bytes];
1063 ret = HandleUsbError(usberr, epDataInIndex);
1066 ret = HandleUsbError(usberr, epDataOutIndex);
1069 ErrorMessage<uint8_t > (PSTR(
"============================ DAT"), ret);
1081 ClearEpHalt(epDataInIndex);
1083 if (tries) ResetRecovery();
1086 Notify(PSTR(
"CBW:\t\tOK\r\n"), 0x80);
1087 Notify(PSTR(
"Data Stage:\tOK\r\n"), 0x80);
1094 ret = HandleUsbError(usberr, epDataInIndex);
1096 ErrorMessage<uint8_t > (PSTR(
"============================ CSW"), ret);
1099 if (IsValidCSW(&csw, pcbw)) {
1103 Notify(PSTR(
"CSW:\t\tOK\r\n\r\n"), 0x80);
1106 Notify(PSTR(
"Invalid CSW\r\n"), 0x80);
1128 uint8_t BulkOnly::ModeSense(uint8_t lun, uint8_t pc, uint8_t page, uint8_t subpage, uint8_t len, uint8_t * pbuf) {
1129 Notify(PSTR(
"\r\rModeSense\r\n"), 0x80);
1130 Notify(PSTR(
"------------\r\n"), 0x80);
1142 for (uint8_t i = 0; i < 16; i++)
1146 cbw.
CBWCB[2] = ((pc << 6) | page);
1147 cbw.
CBWCB[3] = subpage;
1150 return HandleSCSIError(Transaction(&cbw, 512, pbuf, 0));
1159 uint8_t BulkOnly::SetCurLUN(uint8_t lun) {
1172 uint8_t BulkOnly::HandleSCSIError(uint8_t status) {
1181 ErrorMessage<uint8_t > (PSTR(
"Phase Error"), status);
1182 ErrorMessage<uint8_t > (PSTR(
"LUN"),
bTheLUN);
1186 ErrorMessage<uint8_t > (PSTR(
"SCSI Error"), status);
1187 ErrorMessage<uint8_t > (PSTR(
"LUN"),
bTheLUN);
1196 ErrorMessage<uint8_t > (PSTR(
"Response Code"), rsp.bResponseCode);
1197 if (rsp.bResponseCode & 0x80) {
1198 Notify(PSTR(
"Information field: "), 0x80);
1199 for (
int i = 0; i < 4; i++) {
1200 PrintHex<uint8_t > (rsp.CmdSpecificInformation[i], 0x80);
1203 Notify(PSTR(
"\r\n"), 0x80);
1205 ErrorMessage<uint8_t > (PSTR(
"Sense Key"), rsp.bmSenseKey);
1206 ErrorMessage<uint8_t > (PSTR(
"Add Sense Code"), rsp.bAdditionalSenseCode);
1207 ErrorMessage<uint8_t > (PSTR(
"Add Sense Qual"), rsp.bAdditionalSenseQualifier);
1209 switch (rsp.bmSenseKey) {
1215 switch (rsp.bAdditionalSenseCode) {
1222 switch (rsp.bAdditionalSenseCode) {
1230 switch (rsp.bAdditionalSenseCode) {
1243 ErrorMessage<uint8_t > (PSTR(
"Gen SCSI Err"), status);
1244 ErrorMessage<uint8_t > (PSTR(
"LUN"),
bTheLUN);
1269 ErrorMessage<uint8_t > (PSTR(
"Conf.Val"), conf);
1270 ErrorMessage<uint8_t > (PSTR(
"Iface Num"), iface);
1271 ErrorMessage<uint8_t > (PSTR(
"Alt.Set"), alt);
1281 index = ((pep->
bEndpointAddress & 0x80) == 0x80) ? epDataInIndex : epDataOutIndex;
1300 Notify(PSTR(
"Endpoint descriptor:"), 0x80);
1301 Notify(PSTR(
"\r\nLength:\t\t"), 0x80);
1302 PrintHex<uint8_t > (ep_ptr->
bLength, 0x80);
1303 Notify(PSTR(
"\r\nType:\t\t"), 0x80);
1305 Notify(PSTR(
"\r\nAddress:\t"), 0x80);
1307 Notify(PSTR(
"\r\nAttributes:\t"), 0x80);
1309 Notify(PSTR(
"\r\nMaxPktSize:\t"), 0x80);
1311 Notify(PSTR(
"\r\nPoll Intrv:\t"), 0x80);
1312 PrintHex<uint8_t > (ep_ptr->
bInterval, 0x80);
1313 Notify(PSTR(
"\r\n"), 0x80);
1330 Notify(PSTR(
"\r\nRead (With parser)\r\n"), 0x80);
1331 Notify(PSTR(
"---------\r\n"), 0x80);
1342 for (uint8_t i = 0; i < 16; i++)
1346 cbw.
CBWCB[8] = blocks;
1347 cbw.
CBWCB[2] = ((addr >> 24) & 0xff);
1348 cbw.
CBWCB[3] = ((addr >> 16) & 0xff);
1349 cbw.
CBWCB[4] = ((addr >> 8) & 0xff);
1350 cbw.
CBWCB[5] = (addr & 0xff);
1352 return HandleSCSIError(Transaction(&cbw, bsize, prs, 1));
1362 uint8_t SubmitCBW(uint8_t cmd, uint8_t cmdsz, uint8_t lun, uint16_t bsize, uint8_t *buf, uint8_t flags) {
1371 for (uint8_t i = 0; i < 16; i++) cbw.
CBWCB[i] = 0;
1373 cbw.
CBWCB[1] = lun << 5;
1374 cbw.
CBWCB[4] = bsize;