diff options
Diffstat (limited to 'drivers/usb')
-rw-r--r-- | drivers/usb/core/message.c | 16 |
1 files changed, 15 insertions, 1 deletions
diff --git a/drivers/usb/core/message.c b/drivers/usb/core/message.c index da4ee07e0094..b7434787db5f 100644 --- a/drivers/usb/core/message.c +++ b/drivers/usb/core/message.c | |||
@@ -412,10 +412,24 @@ int usb_sg_init ( | |||
412 | io->urbs [i]->status = -EINPROGRESS; | 412 | io->urbs [i]->status = -EINPROGRESS; |
413 | io->urbs [i]->actual_length = 0; | 413 | io->urbs [i]->actual_length = 0; |
414 | 414 | ||
415 | /* | ||
416 | * Some systems need to revert to PIO when DMA is temporarily | ||
417 | * unavailable. For their sakes, both transfer_buffer and | ||
418 | * transfer_dma are set when possible. However this can only | ||
419 | * work on systems without HIGHMEM, since DMA buffers located | ||
420 | * in high memory are not directly addressable by the CPU for | ||
421 | * PIO ... so when HIGHMEM is in use, transfer_buffer is NULL | ||
422 | * to prevent stale pointers and to help spot bugs. | ||
423 | */ | ||
415 | if (dma) { | 424 | if (dma) { |
416 | /* hc may use _only_ transfer_dma */ | ||
417 | io->urbs [i]->transfer_dma = sg_dma_address (sg + i); | 425 | io->urbs [i]->transfer_dma = sg_dma_address (sg + i); |
418 | len = sg_dma_len (sg + i); | 426 | len = sg_dma_len (sg + i); |
427 | #ifdef CONFIG_HIGHMEM | ||
428 | io->urbs[i]->transfer_buffer = NULL; | ||
429 | #else | ||
430 | io->urbs[i]->transfer_buffer = | ||
431 | page_address(sg[i].page) + sg[i].offset; | ||
432 | #endif | ||
419 | } else { | 433 | } else { |
420 | /* hc may use _only_ transfer_buffer */ | 434 | /* hc may use _only_ transfer_buffer */ |
421 | io->urbs [i]->transfer_buffer = | 435 | io->urbs [i]->transfer_buffer = |