Patch by Matthias: The residue field is not maintained
correctly by all USB devices, so calculate it instead. Gets some USB disk devices working like the SuperTOP. MacOS X is doing the same thing, as researched by Jérôme. Closes ticket #6604. Thanks! git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@38836 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
parent
af3b61f013
commit
395346c411
@ -362,16 +362,14 @@ usb_disk_operation(device_lun *lun, uint8 operation, uint8 opLength,
|
|||||||
|
|
||||||
switch (status.status) {
|
switch (status.status) {
|
||||||
case CSW_STATUS_COMMAND_PASSED:
|
case CSW_STATUS_COMMAND_PASSED:
|
||||||
case CSW_STATUS_COMMAND_FAILED: {
|
case CSW_STATUS_COMMAND_FAILED:
|
||||||
if (status.data_residue > command.data_transfer_length) {
|
{
|
||||||
// command status wrapper is not meaningful
|
// The residue from "status.data_residue" is not maintained
|
||||||
TRACE_ALWAYS("command status wrapper has invalid residue\n");
|
// correctly by some devices, so calculate it instead.
|
||||||
usb_disk_reset_recovery(device);
|
uint32 residue = command.data_transfer_length - transferedData;
|
||||||
return B_ERROR;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (dataLength != NULL) {
|
if (dataLength != NULL) {
|
||||||
*dataLength -= status.data_residue;
|
*dataLength -= residue;
|
||||||
if (transferedData < *dataLength) {
|
if (transferedData < *dataLength) {
|
||||||
TRACE_ALWAYS("less data transfered than indicated\n");
|
TRACE_ALWAYS("less data transfered than indicated\n");
|
||||||
*dataLength = transferedData;
|
*dataLength = transferedData;
|
||||||
@ -393,14 +391,16 @@ usb_disk_operation(device_lun *lun, uint8 operation, uint8 opLength,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
case CSW_STATUS_PHASE_ERROR: {
|
case CSW_STATUS_PHASE_ERROR:
|
||||||
|
{
|
||||||
// a protocol or device error occured
|
// a protocol or device error occured
|
||||||
TRACE_ALWAYS("phase error in operation 0x%02x\n", operation);
|
TRACE_ALWAYS("phase error in operation 0x%02x\n", operation);
|
||||||
usb_disk_reset_recovery(device);
|
usb_disk_reset_recovery(device);
|
||||||
return B_ERROR;
|
return B_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
default: {
|
default:
|
||||||
|
{
|
||||||
// command status wrapper is not meaningful
|
// command status wrapper is not meaningful
|
||||||
TRACE_ALWAYS("command status wrapper has invalid status\n");
|
TRACE_ALWAYS("command status wrapper has invalid status\n");
|
||||||
usb_disk_reset_recovery(device);
|
usb_disk_reset_recovery(device);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user