[PATCH]dma rules violation in the option driver

Oliver Neukum <[email protected]>
Newsgroups gmane.linux.usb.devel
Organization Novell
Message-ID <[email protected]>
Hi,

the option driver
- allocations 17K with kmalloc
- violates dma rules on inconsistent architectures

This patch fixes that using an array of USB buffers.

	Regards
		Oliver

Signed-off-by: Oliver Neukum <[email protected]>
-----

--- a/drivers/usb/serial/option.c	2007-03-27 13:31:04.000000000 +0200
+++ b/drivers/usb/serial/option.c	2007-03-27 14:21:21.000000000 +0200
@@ -226,10 +226,12 @@
 struct option_port_private {
 	/* Input endpoints and buffer for this port */
 	struct urb *in_urbs[N_IN_URB];
-	char in_buffer[N_IN_URB][IN_BUFLEN];
+	u8 *in_buffer[N_IN_URB];
+	dma_addr_t in_dma[N_IN_URB];
 	/* Output endpoints and buffer for this port */
 	struct urb *out_urbs[N_OUT_URB];
-	char out_buffer[N_OUT_URB][OUT_BUFLEN];
+	u8 *out_buffer[N_OUT_URB];
+	dma_addr_t out_dma[N_IN_URB];
 
 	/* Settings for the port */
 	int rts_state;	/* Handshaking pins (outputs) */
@@ -617,7 +619,7 @@
 
 /* Helper functions used by option_setup_urbs */
 static struct urb *option_setup_urb(struct usb_serial *serial, int endpoint,
-		int dir, void *ctx, char *buf, int len,
+		int dir, void *ctx, u8 **buf, int len, dma_addr_t *handle,
 		void (*callback)(struct urb *))
 {
 	struct urb *urb;
@@ -627,14 +629,23 @@
 
 	urb = usb_alloc_urb(0, GFP_KERNEL);		/* No ISO */
 	if (urb == NULL) {
-		dbg("%s: alloc for endpoint %d failed.", __FUNCTION__, endpoint);
+		dbg("%s: allocation of an urb for endpoint %d failed.", __FUNCTION__, endpoint);
+		return NULL;
+	}
+
+	*buf = usb_buffer_alloc(serial->dev, len, GFP_KERNEL, handle);
+	if (*buf == NULL) {
+		dbg("%s: allocation of a buffer for endpoint %d failed.", __FUNCTION__, endpoint);
+		usb_free_urb(urb);
 		return NULL;
 	}
 
 		/* Fill URB using supplied data. */
 	usb_fill_bulk_urb(urb, serial->dev,
 		      usb_sndbulkpipe(serial->dev, endpoint) | dir,
-		      buf, len, callback, ctx);
+		      *buf, len, callback, ctx);
+	urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
+	urb->transfer_dma = *handle;
 
 	return urb;
 }
@@ -656,14 +667,14 @@
 		for (j = 0; j < N_IN_URB; ++j) {
 			portdata->in_urbs[j] = option_setup_urb (serial,
                   	port->bulk_in_endpointAddress, USB_DIR_IN, port,
-                  	portdata->in_buffer[j], IN_BUFLEN, option_indat_callback);
+                  	&portdata->in_buffer[j], IN_BUFLEN, &portdata->in_dma[j], option_indat_callback);
 		}
 
 		/* outdat endpoints */
 		for (j = 0; j < N_OUT_URB; ++j) {
 			portdata->out_urbs[j] = option_setup_urb (serial,
                   	port->bulk_out_endpointAddress, USB_DIR_OUT, port,
-                  	portdata->out_buffer[j], OUT_BUFLEN, option_outdat_callback);
+                  	&portdata->out_buffer[j], OUT_BUFLEN, &portdata->out_dma[j], option_outdat_callback);
 		}
 	}
 }
@@ -754,12 +765,16 @@
 		for (j = 0; j < N_IN_URB; j++) {
 			if (portdata->in_urbs[j]) {
 				usb_free_urb(portdata->in_urbs[j]);
+				usb_buffer_free(serial->dev, IN_BUFLEN,
+					portdata->in_buffer[j], portdata->in_dma[j]);
 				portdata->in_urbs[j] = NULL;
 			}
 		}
 		for (j = 0; j < N_OUT_URB; j++) {
 			if (portdata->out_urbs[j]) {
 				usb_free_urb(portdata->out_urbs[j]);
+				usb_buffer_free(serial->dev, OUT_BUFLEN,
+					portdata->out_buffer[j], portdata->out_dma[j]);
 				portdata->out_urbs[j] = NULL;
 			}
 		}


-------------------------------------------------------------------------
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
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.