mirror of
https://github.com/felis/USB_Host_Shield_2.0.git
synced 2024-03-22 11:31:26 +01:00
Convert CDB10 routines.
This commit is contained in:
parent
fee903bbac
commit
0c79e8e10f
2 changed files with 206 additions and 140 deletions
271
masstorage.cpp
271
masstorage.cpp
|
@ -70,6 +70,22 @@ uint8_t BulkOnly::SCSITransaction6(CDB6_t *cdb, uint16_t buf_size, void *buf, ui
|
||||||
return (HandleSCSIError(Transaction(&cbw, buf_size, buf)));
|
return (HandleSCSIError(Transaction(&cbw, buf_size, buf)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Wrap and execute a SCSI CDB with length of 10
|
||||||
|
*
|
||||||
|
* @param cdb CDB to execute
|
||||||
|
* @param buf_size Size of expected transaction
|
||||||
|
* @param buf Buffer
|
||||||
|
* @param dir MASS_CMD_DIR_IN | MASS_CMD_DIR_OUT
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
uint8_t BulkOnly::SCSITransaction10(CDB10_t *cdb, uint16_t buf_size, void *buf, uint8_t dir) {
|
||||||
|
// promote to 32bits.
|
||||||
|
CommandBlockWrapper cbw = CommandBlockWrapper(++dCBWTag, (uint32_t)buf_size, cdb, dir);
|
||||||
|
SetCurLUN(cdb->LUN);
|
||||||
|
return (HandleSCSIError(Transaction(&cbw, buf_size, buf)));
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Lock or Unlock the tray or door on device.
|
* Lock or Unlock the tray or door on device.
|
||||||
* Caution: Some devices with buggy firmware will lock up.
|
* Caution: Some devices with buggy firmware will lock up.
|
||||||
|
@ -133,18 +149,24 @@ uint8_t BulkOnly::Read(uint8_t lun, uint32_t addr, uint16_t bsize, uint8_t block
|
||||||
Notify(PSTR("\r\nblock size:\t"), 0x90);
|
Notify(PSTR("\r\nblock size:\t"), 0x90);
|
||||||
D_PrintHex<uint16_t > (bsize, 0x90);
|
D_PrintHex<uint16_t > (bsize, 0x90);
|
||||||
Notify(PSTR("\r\n---------\r\n"), 0x80);
|
Notify(PSTR("\r\n---------\r\n"), 0x80);
|
||||||
CommandBlockWrapper cbw = CommandBlockWrapper(0, ((uint32_t)bsize * blocks), MASS_CMD_DIR_IN, lun, 10, SCSI_CMD_READ_10);
|
|
||||||
cbw.CBWCB[1] = lun << 5;
|
//CommandBlockWrapper cbw = CommandBlockWrapper(0, ((uint32_t)bsize * blocks), MASS_CMD_DIR_IN, lun, 10, SCSI_CMD_READ_10);
|
||||||
cbw.CBWCB[2] = ((addr >> 24) & 0xff);
|
//cbw.CBWCB[1] = lun << 5;
|
||||||
cbw.CBWCB[3] = ((addr >> 16) & 0xff);
|
//cbw.CBWCB[2] = ((addr >> 24) & 0xff);
|
||||||
cbw.CBWCB[4] = ((addr >> 8) & 0xff);
|
//cbw.CBWCB[3] = ((addr >> 16) & 0xff);
|
||||||
cbw.CBWCB[5] = (addr & 0xff);
|
//cbw.CBWCB[4] = ((addr >> 8) & 0xff);
|
||||||
cbw.CBWCB[8] = blocks;
|
//cbw.CBWCB[5] = (addr & 0xff);
|
||||||
|
//cbw.CBWCB[8] = blocks;
|
||||||
|
|
||||||
|
CDB10_t cdb = CDB10_t(SCSI_CMD_READ_10, lun, blocks, addr);
|
||||||
|
|
||||||
again:
|
again:
|
||||||
cbw.dCBWTag = ++dCBWTag;
|
//cbw.dCBWTag = ++dCBWTag;
|
||||||
SetCurLUN(lun);
|
//SetCurLUN(lun);
|
||||||
uint8_t er = HandleSCSIError(Transaction(&cbw, bsize, buf));
|
//uint8_t er = HandleSCSIError(Transaction(&cbw, bsize, buf));
|
||||||
|
|
||||||
|
uint8_t er = SCSITransaction10(&cdb, ((uint16_t)bsize * blocks), buf, (uint8_t)MASS_CMD_DIR_IN);
|
||||||
|
|
||||||
if (er == MASS_ERR_STALL) {
|
if (er == MASS_ERR_STALL) {
|
||||||
MediaCTL(lun, 1);
|
MediaCTL(lun, 1);
|
||||||
delay(150);
|
delay(150);
|
||||||
|
@ -177,18 +199,23 @@ uint8_t BulkOnly::Write(uint8_t lun, uint32_t addr, uint16_t bsize, uint8_t bloc
|
||||||
D_PrintHex<uint16_t > (bsize, 0x90);
|
D_PrintHex<uint16_t > (bsize, 0x90);
|
||||||
Notify(PSTR("\r\n---------\r\n"), 0x80);
|
Notify(PSTR("\r\n---------\r\n"), 0x80);
|
||||||
//MediaCTL(lun, 0x01);
|
//MediaCTL(lun, 0x01);
|
||||||
CommandBlockWrapper cbw = CommandBlockWrapper(0, ((uint32_t)bsize * blocks), MASS_CMD_DIR_OUT, lun, 10, SCSI_CMD_WRITE_10);
|
|
||||||
cbw.CBWCB[1] = lun << 5;
|
//CommandBlockWrapper cbw = CommandBlockWrapper(0, ((uint32_t)bsize * blocks), MASS_CMD_DIR_OUT, lun, 10, SCSI_CMD_WRITE_10);
|
||||||
cbw.CBWCB[2] = ((addr >> 24) & 0xff);
|
//cbw.CBWCB[1] = lun << 5;
|
||||||
cbw.CBWCB[3] = ((addr >> 16) & 0xff);
|
//cbw.CBWCB[2] = ((addr >> 24) & 0xff);
|
||||||
cbw.CBWCB[4] = ((addr >> 8) & 0xff);
|
//cbw.CBWCB[3] = ((addr >> 16) & 0xff);
|
||||||
cbw.CBWCB[5] = (addr & 0xff);
|
//cbw.CBWCB[4] = ((addr >> 8) & 0xff);
|
||||||
cbw.CBWCB[8] = 1;
|
//cbw.CBWCB[5] = (addr & 0xff);
|
||||||
|
//cbw.CBWCB[8] = blocks;
|
||||||
|
|
||||||
|
CDB10_t cdb = CDB10_t(SCSI_CMD_WRITE_10, lun, blocks, addr);
|
||||||
|
|
||||||
again:
|
again:
|
||||||
cbw.dCBWTag = ++dCBWTag;
|
//cbw.dCBWTag = ++dCBWTag;
|
||||||
SetCurLUN(lun);
|
//SetCurLUN(lun);
|
||||||
uint8_t er = HandleSCSIError(Transaction(&cbw, bsize, (void*)buf));
|
//uint8_t er = HandleSCSIError(Transaction(&cbw, bsize, (void*)buf));
|
||||||
|
uint8_t er = SCSITransaction10(&cdb, ((uint16_t)bsize * blocks), (void*)buf, (uint8_t)MASS_CMD_DIR_OUT);
|
||||||
|
|
||||||
if (er == MASS_ERR_WRITE_STALL) {
|
if (er == MASS_ERR_WRITE_STALL) {
|
||||||
MediaCTL(lun, 1);
|
MediaCTL(lun, 1);
|
||||||
delay(150);
|
delay(150);
|
||||||
|
@ -397,14 +424,51 @@ uint8_t BulkOnly::Init(uint8_t parent, uint8_t port, bool lowspeed) {
|
||||||
|
|
||||||
delay(1000); // Delay a bit for slow firmware.
|
delay(1000); // Delay a bit for slow firmware.
|
||||||
|
|
||||||
//bTheLUN = bMaxLUN;
|
|
||||||
|
|
||||||
for (uint8_t lun = 0; lun <= bMaxLUN; lun++) {
|
for (uint8_t lun = 0; lun <= bMaxLUN; lun++) {
|
||||||
InquiryResponse response;
|
InquiryResponse response;
|
||||||
rcode = Inquiry(lun, sizeof (InquiryResponse), (uint8_t*) & response);
|
rcode = Inquiry(lun, sizeof (InquiryResponse), (uint8_t*) & response);
|
||||||
if (rcode) {
|
if (rcode) {
|
||||||
ErrorMessage<uint8_t > (PSTR("Inquiry"), rcode);
|
ErrorMessage<uint8_t > (PSTR("Inquiry"), rcode);
|
||||||
} else {
|
} else {
|
||||||
|
#if 0
|
||||||
|
printf("LUN %i `", lun);
|
||||||
|
uint8_t *buf = response.VendorID;
|
||||||
|
for (int i = 0; i < 28; i++) printf("%c", buf[i]);
|
||||||
|
printf("'\r\nQualifier %1.1X ", response.PeripheralQualifier);
|
||||||
|
printf("Device type %2.2X ", response.DeviceType);
|
||||||
|
printf("RMB %1.1X ", response.Removable);
|
||||||
|
printf("SSCS %1.1X ", response.SCCS);
|
||||||
|
uint8_t sv = response.Version;
|
||||||
|
printf("SCSI version %2.2X\r\nDevice conforms to ", sv);
|
||||||
|
switch (sv) {
|
||||||
|
case 0:
|
||||||
|
printf("No specific");
|
||||||
|
break;
|
||||||
|
/*
|
||||||
|
case 1:
|
||||||
|
printf("");
|
||||||
|
break;
|
||||||
|
*/
|
||||||
|
case 2:
|
||||||
|
printf("ANSI 2");
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
printf("ANSI INCITS 301-1997 (SPC)");
|
||||||
|
break;
|
||||||
|
case 4:
|
||||||
|
printf("ANSI INCITS 351-2001 (SPC-2)");
|
||||||
|
break;
|
||||||
|
case 5:
|
||||||
|
printf("ANSI INCITS 408-2005 (SPC-4)");
|
||||||
|
break;
|
||||||
|
case 6:
|
||||||
|
printf("T10/1731-D (SPC-4)");
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
printf("unknown");
|
||||||
|
}
|
||||||
|
printf(" standards.\r\n");
|
||||||
|
#endif
|
||||||
uint8_t tries = 0xf0;
|
uint8_t tries = 0xf0;
|
||||||
while (rcode = TestUnitReady(lun)) {
|
while (rcode = TestUnitReady(lun)) {
|
||||||
if (rcode == 0x08) break; // break on no media, this is OK to do.
|
if (rcode == 0x08) break; // break on no media, this is OK to do.
|
||||||
|
@ -444,7 +508,6 @@ uint8_t BulkOnly::Init(uint8_t parent, uint8_t port, bool lowspeed) {
|
||||||
|
|
||||||
if (rcode)
|
if (rcode)
|
||||||
goto FailOnInit;
|
goto FailOnInit;
|
||||||
|
|
||||||
USBTRACE("MS configured\r\n\r\n");
|
USBTRACE("MS configured\r\n\r\n");
|
||||||
|
|
||||||
bPollEnable = true;
|
bPollEnable = true;
|
||||||
|
@ -551,15 +614,15 @@ uint8_t BulkOnly::Release() {
|
||||||
boolean BulkOnly::CheckLUN(uint8_t lun) {
|
boolean BulkOnly::CheckLUN(uint8_t lun) {
|
||||||
uint8_t rcode;
|
uint8_t rcode;
|
||||||
Capacity capacity;
|
Capacity capacity;
|
||||||
for (uint8_t i = 0; i<sizeof (Capacity); i++) capacity.data[i] = 0;
|
for (uint8_t i = 0; i < 8; i++) capacity.data[i] = 0;
|
||||||
|
|
||||||
rcode = ReadCapacity(lun, sizeof (Capacity), (uint8_t*) & capacity);
|
rcode = ReadCapacity10(lun, (uint8_t*)capacity.data);
|
||||||
if (rcode) {
|
if (rcode) {
|
||||||
//printf(">>>>>>>>>>>>>>>>ReadCapacity returned %i\r\n", rcode);
|
//printf(">>>>>>>>>>>>>>>>ReadCapacity returned %i\r\n", rcode);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
ErrorMessage<uint8_t > (PSTR(">>>>>>>>>>>>>>>>CAPACITY OK ON LUN"), lun);
|
ErrorMessage<uint8_t > (PSTR(">>>>>>>>>>>>>>>>CAPACITY OK ON LUN"), lun);
|
||||||
for (uint8_t i = 0; i<sizeof (Capacity); i++)
|
for (uint8_t i = 0; i < 8 /*sizeof (Capacity)*/; i++)
|
||||||
D_PrintHex<uint8_t > (capacity.data[i], 0x80);
|
D_PrintHex<uint8_t > (capacity.data[i], 0x80);
|
||||||
Notify(PSTR("\r\n\r\n"), 0x80);
|
Notify(PSTR("\r\n\r\n"), 0x80);
|
||||||
// Only 512/1024/2048/4096 are valid values!
|
// Only 512/1024/2048/4096 are valid values!
|
||||||
|
@ -671,46 +734,6 @@ uint8_t BulkOnly::Inquiry(uint8_t lun, uint16_t bsize, uint8_t *buf) {
|
||||||
CDB6_t cdb = CDB6_t(SCSI_CMD_INQUIRY, lun, 0LU, (uint8_t)bsize, 0);
|
CDB6_t cdb = CDB6_t(SCSI_CMD_INQUIRY, lun, 0LU, (uint8_t)bsize, 0);
|
||||||
uint8_t rc = SCSITransaction6(&cdb, bsize, buf, (uint8_t)MASS_CMD_DIR_IN);
|
uint8_t rc = SCSITransaction6(&cdb, bsize, buf, (uint8_t)MASS_CMD_DIR_IN);
|
||||||
|
|
||||||
#if 0
|
|
||||||
if (!rc) {
|
|
||||||
printf("LUN %i `", lun);
|
|
||||||
for (int i = 8; i < 36; i++) printf("%c", buf[i]);
|
|
||||||
printf("'\r\nQualifier %1.1X ", (buf[0]&0xE0) >> 5);
|
|
||||||
printf("Device type %2.2X ", buf[0]&0x1f);
|
|
||||||
printf("RMB %1.1X ", buf[1]&0x80 >> 7);
|
|
||||||
printf("SSCS% 1.1X ", buf[5]&0x80 >> 7);
|
|
||||||
uint8_t sv = buf[2];
|
|
||||||
printf("SCSI version %2.2X\r\nDevice conforms to ", sv);
|
|
||||||
switch (sv) {
|
|
||||||
case 0:
|
|
||||||
printf("No specific");
|
|
||||||
break;
|
|
||||||
/*
|
|
||||||
case 1:
|
|
||||||
printf("");
|
|
||||||
break;
|
|
||||||
*/
|
|
||||||
case 2:
|
|
||||||
printf("ANSI 2");
|
|
||||||
break;
|
|
||||||
case 3:
|
|
||||||
printf("ANSI INCITS 301-1997 (SPC)");
|
|
||||||
break;
|
|
||||||
case 4:
|
|
||||||
printf("ANSI INCITS 351-2001 (SPC-2)");
|
|
||||||
break;
|
|
||||||
case 5:
|
|
||||||
printf("ANSI INCITS 408-2005 (SPC-4)");
|
|
||||||
break;
|
|
||||||
case 6:
|
|
||||||
printf("T10/1731-D (SPC-4)");
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
printf("unknown");
|
|
||||||
}
|
|
||||||
printf(" standards.\r\n");
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -748,7 +771,7 @@ uint8_t BulkOnly::TestUnitReady(uint8_t lun) {
|
||||||
* @param pbuf
|
* @param pbuf
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
uint8_t BulkOnly::ModeSense(uint8_t lun, uint8_t pc, uint8_t page, uint8_t subpage, uint8_t len, uint8_t * pbuf) {
|
uint8_t BulkOnly::ModeSense6(uint8_t lun, uint8_t pc, uint8_t page, uint8_t subpage, uint8_t len, uint8_t * pbuf) {
|
||||||
Notify(PSTR("\r\rModeSense\r\n"), 0x80);
|
Notify(PSTR("\r\rModeSense\r\n"), 0x80);
|
||||||
Notify(PSTR("------------\r\n"), 0x80);
|
Notify(PSTR("------------\r\n"), 0x80);
|
||||||
|
|
||||||
|
@ -758,8 +781,57 @@ uint8_t BulkOnly::ModeSense(uint8_t lun, uint8_t pc, uint8_t page, uint8_t subpa
|
||||||
//cbw.CBWCB[3] = subpage;
|
//cbw.CBWCB[3] = subpage;
|
||||||
//cbw.CBWCB[4] = len;
|
//cbw.CBWCB[4] = len;
|
||||||
//return HandleSCSIError(Transaction(&cbw, 512, pbuf));
|
//return HandleSCSIError(Transaction(&cbw, 512, pbuf));
|
||||||
CDB6_t cdb = CDB6_t(SCSI_CMD_TEST_UNIT_READY, lun, (uint32_t)((((pc << 6) | page) << 8) | subpage) , len, 0);
|
CDB6_t cdb = CDB6_t(SCSI_CMD_TEST_UNIT_READY, lun, (uint32_t)((((pc << 6) | page) << 8) | subpage), len, 0);
|
||||||
return SCSITransaction6(&cdb, 512, pbuf, (uint8_t)MASS_CMD_DIR_IN);
|
return SCSITransaction6(&cdb, len, pbuf, (uint8_t)MASS_CMD_DIR_IN);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* For driver use only.
|
||||||
|
*
|
||||||
|
* @param lun Logical Unit Number
|
||||||
|
* @param bsize
|
||||||
|
* @param buf
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
uint8_t BulkOnly::ReadCapacity10(uint8_t lun, uint8_t *buf) {
|
||||||
|
Notify(PSTR("\r\nReadCapacity\r\n"), 0x80);
|
||||||
|
Notify(PSTR("---------------\r\n"), 0x80);
|
||||||
|
#if 0
|
||||||
|
CommandBlockWrapper cbw = CommandBlockWrapper(++dCBWTag, 8, MASS_CMD_DIR_IN, lun, 10, SCSI_CMD_READ_CAPACITY_10);
|
||||||
|
SetCurLUN(lun);
|
||||||
|
cbw.CBWCB[1] = lun << 5;
|
||||||
|
return HandleSCSIError(Transaction(&cbw, 8, buf));
|
||||||
|
#else
|
||||||
|
CDB10_t cdb = CDB10_t(SCSI_CMD_READ_CAPACITY_10, lun);
|
||||||
|
return SCSITransaction10(&cdb, 8, buf, (uint8_t)MASS_CMD_DIR_IN);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* For driver use only.
|
||||||
|
*
|
||||||
|
* Page 3F contains write protect status.
|
||||||
|
*
|
||||||
|
* @param lun Logical Unit Number to test.
|
||||||
|
* @return Write protect switch status.
|
||||||
|
*/
|
||||||
|
uint8_t BulkOnly::Page3F(uint8_t lun) {
|
||||||
|
uint8_t buf[192];
|
||||||
|
for (int i = 0; i < 192; i++) {
|
||||||
|
buf[i] = 0x00;
|
||||||
|
}
|
||||||
|
WriteOk[lun] = true;
|
||||||
|
uint8_t rc = ModeSense6(lun, 0, 0x3f, 0, 192, buf);
|
||||||
|
if (!rc) {
|
||||||
|
WriteOk[lun] = ((buf[2] & 0x80) == 0);
|
||||||
|
Notify(PSTR("Mode Sense: "), 0x80);
|
||||||
|
for (int i = 0; i < 4; i++) {
|
||||||
|
D_PrintHex<uint8_t > (buf[i], 0x80);
|
||||||
|
Notify(PSTR(" "), 0x80);
|
||||||
|
}
|
||||||
|
Notify(PSTR("\r\n"), 0x80);
|
||||||
|
}
|
||||||
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -786,53 +858,6 @@ uint8_t BulkOnly::RequestSense(uint8_t lun, uint16_t size, uint8_t *buf) {
|
||||||
return Transaction(&cbw, size, buf);
|
return Transaction(&cbw, size, buf);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* For driver use only.
|
|
||||||
*
|
|
||||||
* Page 3F contains write protect status.
|
|
||||||
*
|
|
||||||
* @param lun Logical Unit Number to test.
|
|
||||||
* @return Write protect switch status.
|
|
||||||
*/
|
|
||||||
uint8_t BulkOnly::Page3F(uint8_t lun) {
|
|
||||||
uint8_t buf[192];
|
|
||||||
for (int i = 0; i < 192; i++) {
|
|
||||||
buf[i] = 0x00;
|
|
||||||
}
|
|
||||||
WriteOk[lun] = true;
|
|
||||||
uint8_t rc = ModeSense(lun, 0, 0x3f, 0, 192, buf);
|
|
||||||
if (!rc) {
|
|
||||||
WriteOk[lun] = ((buf[2] & 0x80) == 0);
|
|
||||||
Notify(PSTR("Mode Sense: "), 0x80);
|
|
||||||
for (int i = 0; i < 4; i++) {
|
|
||||||
D_PrintHex<uint8_t > (buf[i], 0x80);
|
|
||||||
Notify(PSTR(" "), 0x80);
|
|
||||||
}
|
|
||||||
Notify(PSTR("\r\n"), 0x80);
|
|
||||||
}
|
|
||||||
return rc;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* For driver use only.
|
|
||||||
*
|
|
||||||
* @param lun Logical Unit Number
|
|
||||||
* @param bsize
|
|
||||||
* @param buf
|
|
||||||
* @return
|
|
||||||
*/
|
|
||||||
uint8_t BulkOnly::ReadCapacity(uint8_t lun, uint16_t bsize, uint8_t *buf) {
|
|
||||||
Notify(PSTR("\r\nReadCapacity\r\n"), 0x80);
|
|
||||||
Notify(PSTR("---------------\r\n"), 0x80);
|
|
||||||
CommandBlockWrapper cbw = CommandBlockWrapper(++dCBWTag, bsize, MASS_CMD_DIR_IN, lun, 10, SCSI_CMD_READ_CAPACITY_10);
|
|
||||||
|
|
||||||
SetCurLUN(lun);
|
|
||||||
cbw.CBWCB[1] = lun << 5;
|
|
||||||
|
|
||||||
return HandleSCSIError(Transaction(&cbw, bsize, buf));
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
@ -1035,19 +1060,19 @@ uint8_t BulkOnly::Transaction(CommandBlockWrapper *pcbw, uint16_t buf_size, void
|
||||||
, uint8_t flags
|
, uint8_t flags
|
||||||
#endif
|
#endif
|
||||||
) {
|
) {
|
||||||
uint16_t bytes = (pcbw->dCBWDataTransferLength > buf_size) ? buf_size : pcbw->dCBWDataTransferLength;
|
|
||||||
boolean write = (pcbw->bmCBWFlags & MASS_CMD_DIR_IN) != MASS_CMD_DIR_IN;
|
|
||||||
#if WANT_PARSER
|
#if WANT_PARSER
|
||||||
|
uint16_t bytes = (pcbw->dCBWDataTransferLength > buf_size) ? buf_size : pcbw->dCBWDataTransferLength;
|
||||||
|
printf("Transfersize %i\r\n", bytes); delay(1000);
|
||||||
|
|
||||||
boolean callback = (flags & MASS_TRANS_FLG_CALLBACK) == MASS_TRANS_FLG_CALLBACK;
|
boolean callback = (flags & MASS_TRANS_FLG_CALLBACK) == MASS_TRANS_FLG_CALLBACK;
|
||||||
|
#else
|
||||||
|
uint16_t bytes = buf_size;
|
||||||
#endif
|
#endif
|
||||||
|
boolean write = (pcbw->bmCBWFlags & MASS_CMD_DIR_IN) != MASS_CMD_DIR_IN;
|
||||||
uint8_t ret = 0;
|
uint8_t ret = 0;
|
||||||
uint8_t usberr;
|
uint8_t usberr;
|
||||||
CommandStatusWrapper csw; // up here, we allocate ahead to save cpu cycles.
|
CommandStatusWrapper csw; // up here, we allocate ahead to save cpu cycles.
|
||||||
// Not needed any longer, the constructor ensures this now
|
|
||||||
// Fix reserved bits.
|
|
||||||
//pcbw->bmReserved1 = 0;
|
|
||||||
//pcbw->bmReserved2 = 0;
|
|
||||||
ErrorMessage<uint32_t > (PSTR("CBW.dCBWTag"), pcbw->dCBWTag);
|
ErrorMessage<uint32_t > (PSTR("CBW.dCBWTag"), pcbw->dCBWTag);
|
||||||
|
|
||||||
while ((usberr = pUsb->outTransfer(bAddress, epInfo[epDataOutIndex].epAddr, sizeof (CommandBlockWrapper), (uint8_t*)pcbw)) == hrBUSY) delay(1);
|
while ((usberr = pUsb->outTransfer(bAddress, epInfo[epDataOutIndex].epAddr, sizeof (CommandBlockWrapper), (uint8_t*)pcbw)) == hrBUSY) delay(1);
|
||||||
|
@ -1115,7 +1140,7 @@ uint8_t BulkOnly::Transaction(CommandBlockWrapper *pcbw, uint16_t buf_size, void
|
||||||
// Get a different device. It isn't compliant, and should have never passed Q&A.
|
// Get a different device. It isn't compliant, and should have never passed Q&A.
|
||||||
// I own one... 05e3:0701 Genesys Logic, Inc. USB 2.0 IDE Adapter.
|
// I own one... 05e3:0701 Genesys Logic, Inc. USB 2.0 IDE Adapter.
|
||||||
// Other devices that exhibit this behavior exist in the wild too.
|
// Other devices that exhibit this behavior exist in the wild too.
|
||||||
// Be sure to check for quirks on Linux before reporting a bug. --xxxajk
|
// Be sure to check quirks in the Linux source code before reporting a bug. --xxxajk
|
||||||
Notify(PSTR("Invalid CSW\r\n"), 0x80);
|
Notify(PSTR("Invalid CSW\r\n"), 0x80);
|
||||||
ResetRecovery();
|
ResetRecovery();
|
||||||
//return MASS_ERR_SUCCESS;
|
//return MASS_ERR_SUCCESS;
|
||||||
|
|
75
masstorage.h
75
masstorage.h
|
@ -196,6 +196,17 @@ struct Capacity {
|
||||||
//uint32_t dwBlockLength;
|
//uint32_t dwBlockLength;
|
||||||
} __attribute__((packed));
|
} __attribute__((packed));
|
||||||
|
|
||||||
|
struct BASICCDB {
|
||||||
|
uint8_t Opcode;
|
||||||
|
|
||||||
|
unsigned unused :5;
|
||||||
|
unsigned LUN : 3;
|
||||||
|
|
||||||
|
uint8_t info[12];
|
||||||
|
} __attribute__((packed));
|
||||||
|
|
||||||
|
typedef BASICCDB BASICCDB_t;
|
||||||
|
|
||||||
struct CDB6 {
|
struct CDB6 {
|
||||||
uint8_t Opcode;
|
uint8_t Opcode;
|
||||||
|
|
||||||
|
@ -208,12 +219,16 @@ struct CDB6 {
|
||||||
uint8_t Control;
|
uint8_t Control;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
CDB6(uint8_t _Opcode, uint8_t _LUN, uint32_t LBA, uint8_t _AllocationLength, uint8_t _Control) :
|
CDB6(uint8_t _Opcode, uint8_t _LUN, uint32_t LBA, uint8_t _AllocationLength, uint8_t _Control) :
|
||||||
Opcode(_Opcode), LUN(_LUN), LBAMSB((LBA >>16) & 0x1f), LBAHB((LBA >> 8) & 0xff), LBALB(LBA & 0xff),
|
Opcode(_Opcode), LUN(_LUN), LBAMSB((LBA >> 16) & 0x1f), LBAHB((LBA >> 8) & 0xff), LBALB(LBA & 0xff),
|
||||||
AllocationLength(_AllocationLength), Control(_Control) {}
|
AllocationLength(_AllocationLength), Control(_Control) {
|
||||||
|
}
|
||||||
|
|
||||||
CDB6(uint8_t _Opcode, uint8_t _LUN, uint8_t _AllocationLength, uint8_t _Control) :
|
CDB6(uint8_t _Opcode, uint8_t _LUN, uint8_t _AllocationLength, uint8_t _Control) :
|
||||||
Opcode(_Opcode), LUN(_LUN), LBAMSB(0), LBAHB(0), LBALB(0),
|
Opcode(_Opcode), LUN(_LUN), LBAMSB(0), LBAHB(0), LBALB(0),
|
||||||
AllocationLength(_AllocationLength), Control(_Control) {}
|
AllocationLength(_AllocationLength), Control(_Control) {
|
||||||
|
}
|
||||||
} __attribute__((packed));
|
} __attribute__((packed));
|
||||||
|
|
||||||
typedef CDB6 CDB6_t;
|
typedef CDB6 CDB6_t;
|
||||||
|
@ -222,7 +237,7 @@ struct CDB10 {
|
||||||
uint8_t Opcode;
|
uint8_t Opcode;
|
||||||
|
|
||||||
unsigned Service_Action : 5;
|
unsigned Service_Action : 5;
|
||||||
unsigned Misc : 3;
|
unsigned LUN : 3;
|
||||||
|
|
||||||
uint8_t LBA_L_M_MB;
|
uint8_t LBA_L_M_MB;
|
||||||
uint8_t LBA_L_M_LB;
|
uint8_t LBA_L_M_LB;
|
||||||
|
@ -235,8 +250,24 @@ struct CDB10 {
|
||||||
uint8_t ALC_LB;
|
uint8_t ALC_LB;
|
||||||
|
|
||||||
uint8_t Control;
|
uint8_t Control;
|
||||||
|
public:
|
||||||
|
|
||||||
};
|
CDB10(uint8_t _Opcode, uint8_t _LUN) :
|
||||||
|
Opcode(_Opcode), Service_Action(0), LUN(_LUN),
|
||||||
|
LBA_L_M_MB(0), LBA_L_M_LB(0), LBA_L_L_MB(0), LBA_L_L_LB(0),
|
||||||
|
Misc2(0), ALC_MB(0), ALC_LB(0), Control(0) {
|
||||||
|
}
|
||||||
|
// CDB10(uint8_t _Opcode, uint8_t _LUN, uint16_t xflen) :
|
||||||
|
// Opcode(_Opcode), Service_Action(0), LUN(_LUN),
|
||||||
|
// LBA_L_M_MB(0), LBA_L_M_LB(0), LBA_L_L_MB(0), LBA_L_L_LB(0),
|
||||||
|
// Misc2(0), ALC_MB((xflen >> 8) & 0xff), ALC_LB(xflen & 0xff), Control(0) {
|
||||||
|
// }
|
||||||
|
CDB10(uint8_t _Opcode, uint8_t _LUN, uint16_t xflen, uint32_t _LBA) :
|
||||||
|
Opcode(_Opcode), Service_Action(0), LUN(_LUN),
|
||||||
|
LBA_L_M_MB((_LBA >> 24) & 0xff), LBA_L_M_LB((_LBA >> 16) & 0xff), LBA_L_L_MB((_LBA >> 8) & 0xff), LBA_L_L_LB(_LBA & 0xff),
|
||||||
|
Misc2(0), ALC_MB((xflen >> 8) & 0xff), ALC_LB(xflen & 0xff), Control(0) {
|
||||||
|
}
|
||||||
|
} __attribute__((packed));
|
||||||
|
|
||||||
typedef CDB10 CDB10_t;
|
typedef CDB10 CDB10_t;
|
||||||
|
|
||||||
|
@ -254,7 +285,7 @@ struct CDB12 {
|
||||||
uint8_t ALC_L_MB;
|
uint8_t ALC_L_MB;
|
||||||
uint8_t ALC_L_LB;
|
uint8_t ALC_L_LB;
|
||||||
uint8_t Control;
|
uint8_t Control;
|
||||||
};
|
} __attribute__((packed));
|
||||||
|
|
||||||
typedef CDB12 CDB12_t;
|
typedef CDB12 CDB12_t;
|
||||||
|
|
||||||
|
@ -281,7 +312,7 @@ struct CDB_LBA32_16 {
|
||||||
|
|
||||||
uint8_t Misc2;
|
uint8_t Misc2;
|
||||||
uint8_t Control;
|
uint8_t Control;
|
||||||
};
|
} __attribute__((packed));
|
||||||
|
|
||||||
struct CDB_LBA64_16 {
|
struct CDB_LBA64_16 {
|
||||||
uint8_t Opcode;
|
uint8_t Opcode;
|
||||||
|
@ -304,7 +335,7 @@ struct CDB_LBA64_16 {
|
||||||
|
|
||||||
uint8_t Misc2;
|
uint8_t Misc2;
|
||||||
uint8_t Control;
|
uint8_t Control;
|
||||||
};
|
} __attribute__((packed));
|
||||||
|
|
||||||
struct InquiryResponse {
|
struct InquiryResponse {
|
||||||
uint8_t DeviceType : 5;
|
uint8_t DeviceType : 5;
|
||||||
|
@ -383,24 +414,33 @@ struct CommandBlockWrapper : public CommandBlockWrapperBase {
|
||||||
|
|
||||||
uint8_t CBWCB[16];
|
uint8_t CBWCB[16];
|
||||||
|
|
||||||
CommandBlockWrapper() : bmReserved1(0), bmReserved2(0) {
|
|
||||||
for(uint8_t i = 0; i < 16; i++) CBWCB[i] = 0;
|
|
||||||
}
|
|
||||||
public:
|
public:
|
||||||
|
// All zeroed.
|
||||||
|
CommandBlockWrapper() :
|
||||||
|
CommandBlockWrapperBase(0,0,0), bmReserved1(0), bmReserved2(0)
|
||||||
|
{
|
||||||
|
for (int i=0; i<16; i++) CBWCB[i]=0;
|
||||||
|
}
|
||||||
|
|
||||||
// Generic Wrap
|
// Generic Wrap, CDB zeroed.
|
||||||
CommandBlockWrapper(uint32_t tag, uint32_t xflen, uint8_t flgs, uint8_t lu, uint8_t cmdlen, uint8_t cmd) :
|
CommandBlockWrapper(uint32_t tag, uint32_t xflen, uint8_t flgs, uint8_t lu, uint8_t cmdlen, uint8_t cmd) :
|
||||||
CommandBlockWrapperBase(tag, xflen, flgs),
|
CommandBlockWrapperBase(tag, xflen, flgs),
|
||||||
bmReserved1(0), bmReserved2(0), bmCBWLUN(lu), bmCBWCBLength(cmdlen) {
|
bmReserved1(0), bmReserved2(0), bmCBWLUN(lu), bmCBWCBLength(cmdlen) {
|
||||||
for(uint8_t i = 1; i < cmdlen; i++) CBWCB[i] = 0;
|
for (int i=0; i<16; i++) CBWCB[i]=0;
|
||||||
CBWCB[0] = cmd;
|
((BASICCDB_t *)CBWCB)->LUN = cmd;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Wrap for CDB of 6
|
// Wrap for CDB of 6
|
||||||
CommandBlockWrapper(uint32_t tag, uint32_t xflen, CDB6_t *cdb, uint8_t dir) :
|
CommandBlockWrapper(uint32_t tag, uint32_t xflen, CDB6_t *cdb, uint8_t dir) :
|
||||||
CommandBlockWrapperBase(tag, xflen, dir),
|
CommandBlockWrapperBase(tag, xflen, dir),
|
||||||
bmReserved1(0), bmReserved2(0), bmCBWLUN(cdb->LUN), bmCBWCBLength(6) {
|
bmReserved1(0), bmReserved2(0), bmCBWLUN(cdb->LUN), bmCBWCBLength(6) {
|
||||||
memcpy(CBWCB, cdb, 6);
|
memcpy(&CBWCB, cdb, 6);
|
||||||
|
}
|
||||||
|
// Wrap for CDB of 10
|
||||||
|
CommandBlockWrapper(uint32_t tag, uint32_t xflen, CDB10_t *cdb, uint8_t dir) :
|
||||||
|
CommandBlockWrapperBase(tag, xflen, dir),
|
||||||
|
bmReserved1(0), bmReserved2(0), bmCBWLUN(cdb->LUN), bmCBWCBLength(10) {
|
||||||
|
memcpy(&CBWCB, cdb, 10);
|
||||||
}
|
}
|
||||||
} __attribute__((packed));
|
} __attribute__((packed));
|
||||||
|
|
||||||
|
@ -508,17 +548,18 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t SCSITransaction6(CDB6_t *cdb, uint16_t buf_size, void *buf, uint8_t dir);
|
uint8_t SCSITransaction6(CDB6_t *cdb, uint16_t buf_size, void *buf, uint8_t dir);
|
||||||
|
uint8_t SCSITransaction10(CDB10_t *cdb, uint16_t buf_size, void *buf, uint8_t dir);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
uint8_t Inquiry(uint8_t lun, uint16_t size, uint8_t *buf);
|
uint8_t Inquiry(uint8_t lun, uint16_t size, uint8_t *buf);
|
||||||
uint8_t TestUnitReady(uint8_t lun);
|
uint8_t TestUnitReady(uint8_t lun);
|
||||||
uint8_t RequestSense(uint8_t lun, uint16_t size, uint8_t *buf);
|
uint8_t RequestSense(uint8_t lun, uint16_t size, uint8_t *buf);
|
||||||
uint8_t ModeSense(uint8_t lun, uint8_t pc, uint8_t page, uint8_t subpage, uint8_t len, uint8_t *buf);
|
uint8_t ModeSense6(uint8_t lun, uint8_t pc, uint8_t page, uint8_t subpage, uint8_t len, uint8_t *buf);
|
||||||
uint8_t GetMaxLUN(uint8_t *max_lun);
|
uint8_t GetMaxLUN(uint8_t *max_lun);
|
||||||
uint8_t SetCurLUN(uint8_t lun);
|
uint8_t SetCurLUN(uint8_t lun);
|
||||||
void Reset();
|
void Reset();
|
||||||
uint8_t ResetRecovery();
|
uint8_t ResetRecovery();
|
||||||
uint8_t ReadCapacity(uint8_t lun, uint16_t size, uint8_t *buf);
|
uint8_t ReadCapacity10(uint8_t lun, uint8_t *buf);
|
||||||
void ClearAllEP();
|
void ClearAllEP();
|
||||||
void CheckMedia();
|
void CheckMedia();
|
||||||
boolean CheckLUN(uint8_t lun);
|
boolean CheckLUN(uint8_t lun);
|
||||||
|
|
Loading…
Reference in a new issue