mirror of
https://github.com/genodelabs/genode.git
synced 2025-05-04 09:43:06 +00:00
parent
0ef7e58ef9
commit
230ed1de37
@ -14,7 +14,7 @@ driver:
|
|||||||
!<start name="usb_block_drv">
|
!<start name="usb_block_drv">
|
||||||
! <resource name="RAM" quantum="4M"/>
|
! <resource name="RAM" quantum="4M"/>
|
||||||
! <provides> <service name="Block"/> </provides>
|
! <provides> <service name="Block"/> </provides>
|
||||||
! <config label="usb_stick" report="yes" writeable="yes" interface="0" lun="0"/>
|
! <config label="usb_stick" report="yes" writeable="yes" interface="0" lun="0" reset_device="no" verbose_scsi="no"/>
|
||||||
! <route>
|
! <route>
|
||||||
! <service name="Usb"> <child name="usb_drv"/> </service>
|
! <service name="Usb"> <child name="usb_drv"/> </service>
|
||||||
! <any-service> <parent/> <any-child/> </any-service>
|
! <any-service> <parent/> <any-child/> </any-service>
|
||||||
@ -63,7 +63,10 @@ session client to write to the USB device. Independent thereof the driver will
|
|||||||
query the device and will set the Block session operations accordingly. The
|
query the device and will set the Block session operations accordingly. The
|
||||||
'interface' specifies the USB interface the driver should use. If the device
|
'interface' specifies the USB interface the driver should use. If the device
|
||||||
provides multiple SCSI devices the 'lun' attribute is used to select the right
|
provides multiple SCSI devices the 'lun' attribute is used to select the right
|
||||||
one.
|
one. When 'reset_device' is enabled, a 'bulk-only mass storage reset' command
|
||||||
|
is sent to the device at the beginning of the initialization step. This command
|
||||||
|
caused problems on at least one device, so it is omitted by default. The
|
||||||
|
'verbose_scsi' attribute can be useful for debugging.
|
||||||
|
|
||||||
The configuration of the USB block driver cannot be changed at run-time. The
|
The configuration of the USB block driver cannot be changed at run-time. The
|
||||||
driver is either used in a static system configuration where it is configured
|
driver is either used in a static system configuration where it is configured
|
||||||
|
@ -153,6 +153,8 @@ struct Usb::Block_driver : Usb::Completion,
|
|||||||
uint8_t ep_in = 0;
|
uint8_t ep_in = 0;
|
||||||
uint8_t ep_out = 0;
|
uint8_t ep_out = 0;
|
||||||
|
|
||||||
|
bool reset_device = false;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Completion used while initializing the device
|
* Completion used while initializing the device
|
||||||
*/
|
*/
|
||||||
@ -354,7 +356,8 @@ struct Usb::Block_driver : Usb::Completion,
|
|||||||
* Initialize device
|
* Initialize device
|
||||||
*
|
*
|
||||||
* All USB transfers in this method are done synchronously. First we reset
|
* All USB transfers in this method are done synchronously. First we reset
|
||||||
* the device, than we query the max LUN. Afterwards we start sending CBWs.
|
* the device (optional), then we query the max LUN. Afterwards we start
|
||||||
|
* sending CBWs.
|
||||||
*
|
*
|
||||||
* Since it might take some time for the device to get ready to use, we
|
* Since it might take some time for the device to get ready to use, we
|
||||||
* have to check the SCSI logical unit several times.
|
* have to check the SCSI logical unit several times.
|
||||||
@ -405,21 +408,30 @@ struct Usb::Block_driver : Usb::Completion,
|
|||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
/* reset */
|
|
||||||
Usb::Packet_descriptor p = iface.alloc(0);
|
/*
|
||||||
iface.control_transfer(p, 0x21, 0xff, 0, active_interface, 100);
|
* reset
|
||||||
if (!p.succeded) {
|
*
|
||||||
Genode::error("Could not reset device");
|
* This command caused write command errors on a
|
||||||
|
* 'SanDisk Cruzer Force' (0781:557d) USB stick, so it is
|
||||||
|
* omitted by default.
|
||||||
|
*/
|
||||||
|
if (reset_device) {
|
||||||
|
Usb::Packet_descriptor p = iface.alloc(0);
|
||||||
|
iface.control_transfer(p, 0x21, 0xff, 0, active_interface, 100);
|
||||||
|
if (!p.succeded) {
|
||||||
|
Genode::error("Could not reset device");
|
||||||
|
iface.release(p);
|
||||||
|
throw -1;
|
||||||
|
}
|
||||||
iface.release(p);
|
iface.release(p);
|
||||||
throw -1;
|
|
||||||
}
|
}
|
||||||
iface.release(p);
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Let us do GetMaxLUN and simply ignore the return value because none
|
* Let us do GetMaxLUN and simply ignore the return value because none
|
||||||
* of the devices that were tested did infact report another value than 0.
|
* of the devices that were tested did infact report another value than 0.
|
||||||
*/
|
*/
|
||||||
p = iface.alloc(1);
|
Usb::Packet_descriptor p = iface.alloc(1);
|
||||||
iface.control_transfer(p, 0xa1, 0xfe, 0, active_interface, 100);
|
iface.control_transfer(p, 0xa1, 0xfe, 0, active_interface, 100);
|
||||||
uint8_t max_lun = *(uint8_t*)iface.content(p);
|
uint8_t max_lun = *(uint8_t*)iface.content(p);
|
||||||
if (p.succeded && max_lun == 0) { max_lun = 1; }
|
if (p.succeded && max_lun == 0) { max_lun = 1; }
|
||||||
@ -728,6 +740,8 @@ struct Usb::Block_driver : Usb::Completion,
|
|||||||
active_interface = node.attribute_value<unsigned long>("interface", 0);
|
active_interface = node.attribute_value<unsigned long>("interface", 0);
|
||||||
active_lun = node.attribute_value<unsigned long>("lun", 0);
|
active_lun = node.attribute_value<unsigned long>("lun", 0);
|
||||||
|
|
||||||
|
reset_device = node.attribute_value<bool>("reset_device", false);
|
||||||
|
|
||||||
verbose_scsi = node.attribute_value<bool>("verbose_scsi", false);
|
verbose_scsi = node.attribute_value<bool>("verbose_scsi", false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user