Re: [PATCH] USB: Allow transfer_buffer with transfer_dma, take #5

Tony Lindgren <[email protected]>
Newsgroups gmane.linux.usb.devel
Message-ID <[email protected]>
* Alan Stern <[email protected]> [070329 16:14]:
> On Thu, 29 Mar 2007, Tony Lindgren wrote:
> 
> You left out part of my suggestion (setting the pointer to NULL):
> 
> > > > +#ifndef CONFIG_HIGHMEM
> > > >  			io->urbs [i]->transfer_buffer =
> > > >  				page_address (sg [i].page) + sg [i].offset;
> > > 
> > > Insert here:
> > > 
> > > +#else
> > > +			io->urbs[i]->transfer_buffer = NULL;
> 
> ^^^ You didn't do this.
> 
> > > 
> > > > +#endif
> > > > +		} else {
> > > >  			len = sg [i].length;
> > > > +			io->urbs [i]->transfer_buffer =
> > > > +				page_address (sg [i].page) + sg [i].offset;
> > > >  		}

Sorry I missed that, here's one more version.

Looks like I had some strangeness connecting to SMTP server, please
ignore similar copy this same message if it got sent..

Tony

-------------------------------------------------------------------------
Take Surveys. Earn Cash. Influence the Future of IT
Join SourceForge.net's Techsay panel and you'll get the chance to share your
opinions on IT & business topics through brief surveys-and earn cash
http://www.techsay.com/default.php?page=join.php&p=sourceforge&CID=DEVDEV

_______________________________________________
[email protected]
To unsubscribe, use the last form field at:
https://lists.sourceforge.net/lists/listinfo/linux-usb-devel
usb-core-allow-transfer-buffer.patch (text/x-diff, 1.7 KB)
From: Tony Lindgren <[email protected]>
Subject: USB: Allow transfer_buffer with transfer_dma

In case a DMA channel for an endpoint is temporarily
unavailable, some host controller drivers may still be
able to transfer the data using PIO. Without this patch
the transfer_buffer is not mapped, and host controller
does not know what to use for PIO.

Signed-off-by: Tony Lindgren <[email protected]>

--- a/drivers/usb/core/message.c
+++ b/drivers/usb/core/message.c
@@ -412,15 +412,30 @@ int usb_sg_init (
 		io->urbs [i]->status = -EINPROGRESS;
 		io->urbs [i]->actual_length = 0;
 
+                /*
+		 * Some systems can revert to PIO if DMA is temporarily
+		 * unavailable; for their sake both transfer_buffer and
+		 * transfer_dma must be set properly.  However this is
+		 * possible only on systems with no high memory, since
+		 * DMA buffers located in high memory are not directly
+		 * addressable by the kernel for PIO.  When high memory
+		 * is available, we NULL out transfer_buffer to avoid
+		 * keeping a stale pointer and to help spot possible
+		 * addressing 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);
+			io->urbs[i]->transfer_dma = sg_dma_address(sg + i);
+			len = sg_dma_len(sg + i);
+#ifndef CONFIG_HIGHMEM
+			io->urbs[i]->transfer_buffer =
+				page_address(sg[i].page) + sg[i].offset;
+#else
+			io->urbs[i]->transfer_buffer = NULL;
+#endif
 		} else {
-			/* hc may use _only_ transfer_buffer */
-			io->urbs [i]->transfer_buffer =
-				page_address (sg [i].page) + sg [i].offset;
-			len = sg [i].length;
+			len = sg[i].length;
+			io->urbs[i]->transfer_buffer =
+				page_address(sg[i].page) + sg[i].offset;
 		}
 
 		if (length) {
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.