mirror of
https://github.com/genodelabs/genode.git
synced 2024-12-20 06:07:59 +00:00
usb_block: support iomega zip drives
This patch enhances the initialization sequence by issueing a START_STOP SCSI command when needed. Fixes #3469
This commit is contained in:
parent
67a3c2ea4b
commit
23c2606ce0
@ -105,6 +105,23 @@ struct Request_sense : Usb::Cbw, Scsi::Request_sense
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
struct Start_stop : Usb::Cbw, Scsi::Start_stop
|
||||||
|
{
|
||||||
|
Start_stop(addr_t addr, uint32_t tag, uint8_t lun)
|
||||||
|
:
|
||||||
|
Cbw(addr, tag, 0, Usb::ENDPOINT_IN, lun, Scsi::Start_stop::LENGTH),
|
||||||
|
Scsi::Start_stop(addr+15)
|
||||||
|
{ if (verbose_scsi) dump(); }
|
||||||
|
|
||||||
|
void dump()
|
||||||
|
{
|
||||||
|
Genode::log("--- Dump START_STOP command --");
|
||||||
|
Cbw::dump();
|
||||||
|
Scsi::Start_stop::dump();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
struct Inquiry : Usb::Cbw, Scsi::Inquiry
|
struct Inquiry : Usb::Cbw, Scsi::Inquiry
|
||||||
{
|
{
|
||||||
Inquiry(addr_t addr, uint32_t tag, uint8_t lun)
|
Inquiry(addr_t addr, uint32_t tag, uint8_t lun)
|
||||||
|
@ -169,6 +169,7 @@ struct Usb::Block_driver : Usb::Completion,
|
|||||||
|
|
||||||
bool no_medium = false;
|
bool no_medium = false;
|
||||||
bool try_again = false;
|
bool try_again = false;
|
||||||
|
bool start_stop = false;
|
||||||
|
|
||||||
Usb::Device &device;
|
Usb::Device &device;
|
||||||
uint8_t interface;
|
uint8_t interface;
|
||||||
@ -249,22 +250,42 @@ struct Usb::Block_driver : Usb::Completion,
|
|||||||
uint8_t const asc = r.read<Request_sense_response::Asc>();
|
uint8_t const asc = r.read<Request_sense_response::Asc>();
|
||||||
uint8_t const asq = r.read<Request_sense_response::Asq>();
|
uint8_t const asq = r.read<Request_sense_response::Asq>();
|
||||||
|
|
||||||
enum { MEDIUM_NOT_PRESENT = 0x3a, NOT_READY_TO_READY_CHANGE = 0x28 };
|
bool error = false;
|
||||||
|
|
||||||
|
enum { MEDIUM_NOT_PRESENT = 0x3a,
|
||||||
|
NOT_READY_TO_READY_CHANGE = 0x28,
|
||||||
|
POWER_ON_OR_RESET_OCCURRED = 0x29,
|
||||||
|
LOGICAL_UNIT_NOT_READY = 0x04 };
|
||||||
switch (asc) {
|
switch (asc) {
|
||||||
|
|
||||||
case MEDIUM_NOT_PRESENT:
|
case MEDIUM_NOT_PRESENT:
|
||||||
Genode::error("Not ready - medium not present");
|
Genode::error("Not ready - medium not present");
|
||||||
no_medium = true;
|
no_medium = true;
|
||||||
break;
|
break;
|
||||||
case NOT_READY_TO_READY_CHANGE: /* asq == 0x00 */
|
|
||||||
|
case NOT_READY_TO_READY_CHANGE: /* asq == 0x00 */
|
||||||
|
case POWER_ON_OR_RESET_OCCURRED: /* asq == 0x00 */
|
||||||
Genode::warning("Not ready - try again");
|
Genode::warning("Not ready - try again");
|
||||||
try_again = true;
|
try_again = true;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case LOGICAL_UNIT_NOT_READY:
|
||||||
|
|
||||||
|
if (asq == 2) start_stop = true; /* initializing command required */
|
||||||
|
else if (asq == 1) try_again = true; /* initializing in progress */
|
||||||
|
else error = true;
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
error = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (error)
|
||||||
Genode::error("Request_sense_response asc: ",
|
Genode::error("Request_sense_response asc: ",
|
||||||
Hex(asc, Hex::PREFIX, Hex::PAD),
|
Hex(asc, Hex::PREFIX, Hex::PAD),
|
||||||
" asq: ", Hex(asq, Hex::PREFIX, Hex::PAD));
|
" asq: ", Hex(asq, Hex::PREFIX, Hex::PAD));
|
||||||
break;
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case Csw::LENGTH:
|
case Csw::LENGTH:
|
||||||
@ -489,6 +510,14 @@ struct Usb::Block_driver : Usb::Completion,
|
|||||||
/* do nothing for now */
|
/* do nothing for now */
|
||||||
} else if (init.try_again) {
|
} else if (init.try_again) {
|
||||||
init.try_again = false;
|
init.try_again = false;
|
||||||
|
} else if (init.start_stop) {
|
||||||
|
|
||||||
|
init.start_stop = false;
|
||||||
|
Start_stop start_stop((addr_t)cbw_buffer, SS_TAG, active_lun);
|
||||||
|
|
||||||
|
cbw(cbw_buffer, init, true);
|
||||||
|
csw(init, true);
|
||||||
|
|
||||||
} else break;
|
} else break;
|
||||||
} else break;
|
} else break;
|
||||||
|
|
||||||
|
@ -47,6 +47,7 @@ namespace Scsi {
|
|||||||
struct Request_sense_response;
|
struct Request_sense_response;
|
||||||
struct Capacity_response_10;
|
struct Capacity_response_10;
|
||||||
struct Capacity_response_16;
|
struct Capacity_response_16;
|
||||||
|
struct Start_stop_response;
|
||||||
|
|
||||||
struct Cmd_6;
|
struct Cmd_6;
|
||||||
struct Test_unit_ready;
|
struct Test_unit_ready;
|
||||||
@ -274,7 +275,6 @@ struct Scsi::Inquiry : Cmd_6
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
/* not in use for now but might come in handy in the future */
|
|
||||||
struct Scsi::Start_stop : Genode::Mmio
|
struct Scsi::Start_stop : Genode::Mmio
|
||||||
{
|
{
|
||||||
enum { LENGTH = 6 };
|
enum { LENGTH = 6 };
|
||||||
|
Loading…
Reference in New Issue
Block a user