usb_disk: Lock memory before acquiring device locks.
Otherwise, if we are locking memory that's mapped from this same usb_disk device, we'll cause a double lock. Should fix #19715. But really, we should probably be using an IOScheduler here, so the next commit will implement that. Change-Id: Icd62955338ef66444ec6a14e0310f60061456d8f Reviewed-on: https://review.haiku-os.org/c/haiku/+/9610 Reviewed-by: waddlesplash <[email protected]> Tested-by: Commit checker robot <[email protected]>
This commit is contained in:
committed by
waddlesplash
parent
fb6c279a24
commit
505b9a5c31
@@ -1817,19 +1817,12 @@ usb_disk_ioctl(void *cookie, uint32 op, void *buffer, size_t length)
|
||||
static status_t
|
||||
usb_disk_bounced_io(device_lun *lun, io_request *request)
|
||||
{
|
||||
ASSERT(request->Buffer()->IsPhysical() || request->Buffer()->IsMemoryLocked());
|
||||
|
||||
DMAResource* dmaResource = get_dma_resource(lun->device, lun->block_size);
|
||||
if (dmaResource == NULL)
|
||||
return B_NO_INIT;
|
||||
|
||||
if (!request->Buffer()->IsPhysical()) {
|
||||
status_t status = request->Buffer()->LockMemory(request->TeamID(), request->IsWrite());
|
||||
if (status != B_OK) {
|
||||
TRACE_ALWAYS("failed to lock memory: %s\n", strerror(status));
|
||||
return status;
|
||||
}
|
||||
// SetStatusAndNotify() takes care of unlocking memory if necessary.
|
||||
}
|
||||
|
||||
status_t status = B_OK;
|
||||
while (request->RemainingBytes() > 0) {
|
||||
IOOperation operation;
|
||||
@@ -1919,6 +1912,17 @@ usb_disk_io(void *cookie, io_request *request)
|
||||
device_lun *lun = (device_lun *)cookie;
|
||||
disk_device *device = lun->device;
|
||||
|
||||
const bool needsBounce = usb_disk_needs_bounce(lun, request);
|
||||
|
||||
if (needsBounce && !request->Buffer()->IsPhysical()) {
|
||||
status_t status = request->Buffer()->LockMemory(request->TeamID(), request->IsWrite());
|
||||
if (status != B_OK) {
|
||||
TRACE_ALWAYS("failed to lock memory: %s\n", strerror(status));
|
||||
return status;
|
||||
}
|
||||
// SetStatusAndNotify() takes care of unlocking memory if necessary.
|
||||
}
|
||||
|
||||
RecursiveLocker ioLocker(device->io_lock);
|
||||
MutexLocker deviceLocker(device->lock);
|
||||
|
||||
@@ -1926,7 +1930,7 @@ usb_disk_io(void *cookie, io_request *request)
|
||||
return B_DEV_NOT_READY;
|
||||
|
||||
status_t status;
|
||||
if (!usb_disk_needs_bounce(lun, request)) {
|
||||
if (!needsBounce) {
|
||||
status = usb_disk_direct_io(lun, request);
|
||||
} else {
|
||||
status = usb_disk_bounced_io(lun, request);
|
||||
|
||||
Reference in New Issue
Block a user