From david-b@pacbell.net Sat Mar 31 18:15:49 2007 From: Tony Lindgren Date: Sat, 31 Mar 2007 18:15:43 -0700 Subject: USB: Allow transfer_buffer with transfer_dma To: Tony Lindgren , Greg KH Cc: Alan Stern , Felipe Balbi Message-ID: <200703311815.43784.david-b@pacbell.net> Content-Disposition: inline From: Tony Lindgren Some host controller drivers may need a PIO fallback when a DMA channel is temporarily unavailable. This patch provides an address that such drivers can use for PIO in those cases, and nulls that field out when no such address is available (highmem) which should help usbmon. Signed-off-by: Tony Lindgren Signed-off-by: David Brownell Signed-off-by: Greg Kroah-Hartman --- drivers/usb/core/message.c | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) --- a/drivers/usb/core/message.c +++ b/drivers/usb/core/message.c @@ -412,10 +412,24 @@ int usb_sg_init ( io->urbs [i]->status = -EINPROGRESS; io->urbs [i]->actual_length = 0; + /* + * Some systems need to revert to PIO when DMA is temporarily + * unavailable. For their sakes, both transfer_buffer and + * transfer_dma are set when possible. However this can only + * work on systems without HIGHMEM, since DMA buffers located + * in high memory are not directly addressable by the CPU for + * PIO ... so when HIGHMEM is in use, transfer_buffer is NULL + * to prevent stale pointers and to help spot bugs. + */ if (dma) { - /* hc may use _only_ transfer_dma */ io->urbs [i]->transfer_dma = sg_dma_address (sg + i); len = sg_dma_len (sg + i); +#ifdef CONFIG_HIGHMEM + io->urbs[i]->transfer_buffer = NULL; +#else + io->urbs[i]->transfer_buffer = + page_address(sg[i].page) + sg[i].offset; +#endif } else { /* hc may use _only_ transfer_buffer */ io->urbs [i]->transfer_buffer =