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:
Stephan Aßmus 2010-09-28 17:30:15 +00:00
parent af3b61f013
commit 395346c411
1 changed files with 10 additions and 10 deletions

View File

@ -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);