aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb/serial/generic.c
diff options
context:
space:
mode:
authorJohan Hovold <jhovold@gmail.com>2010-03-17 18:06:08 -0400
committerGreg Kroah-Hartman <gregkh@suse.de>2010-05-20 16:21:35 -0400
commiteaa3bcb06aed1ac1d6d9e3edd3b5f72ea57a6ac0 (patch)
treea55b216df6a5977ab8d502df44397ef7ebbb11bc /drivers/usb/serial/generic.c
parent25d514ca227e1ac81d0906a4ccf2aa171f50a600 (diff)
USB: serial: generalise write buffer preparation
Generalise write buffer preparation. This allows for drivers to manipulate (e.g. add headers) to bulk out data before it is sent. This adds a new function pointer to usb_serial_driver: int (*prepare_write_buffer)(struct usb_serial_port *port, void **dest, size_t size, const void *src, size_t count); The function is generic and can be used with either kfifo-based or multi-urb writes: If *dest is NULL the implementation should allocate dest. If src is NULL the implementation should use the port write fifo. If not set, a generic implementation is used which simply uses memcpy or kfifo_out. Signed-off-by: Johan Hovold <jhovold@gmail.com> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Diffstat (limited to 'drivers/usb/serial/generic.c')
-rw-r--r--drivers/usb/serial/generic.c47
1 files changed, 34 insertions, 13 deletions
diff --git a/drivers/usb/serial/generic.c b/drivers/usb/serial/generic.c
index ad4823bbfa19..1a134f9c64f3 100644
--- a/drivers/usb/serial/generic.c
+++ b/drivers/usb/serial/generic.c
@@ -167,12 +167,35 @@ void usb_serial_generic_close(struct usb_serial_port *port)
167} 167}
168EXPORT_SYMBOL_GPL(usb_serial_generic_close); 168EXPORT_SYMBOL_GPL(usb_serial_generic_close);
169 169
170int usb_serial_generic_prepare_write_buffer(struct usb_serial_port *port,
171 void **dest, size_t size, const void *src, size_t count)
172{
173 if (!*dest) {
174 size = count;
175 *dest = kmalloc(count, GFP_ATOMIC);
176 if (!*dest) {
177 dev_err(&port->dev, "%s - could not allocate buffer\n",
178 __func__);
179 return -ENOMEM;
180 }
181 }
182 if (src) {
183 count = size;
184 memcpy(*dest, src, size);
185 } else {
186 count = kfifo_out_locked(&port->write_fifo, *dest, size,
187 &port->lock);
188 }
189 return count;
190}
191EXPORT_SYMBOL_GPL(usb_serial_generic_prepare_write_buffer);
192
170static int usb_serial_multi_urb_write(struct tty_struct *tty, 193static int usb_serial_multi_urb_write(struct tty_struct *tty,
171 struct usb_serial_port *port, const unsigned char *buf, int count) 194 struct usb_serial_port *port, const unsigned char *buf, int count)
172{ 195{
173 unsigned long flags; 196 unsigned long flags;
174 struct urb *urb; 197 struct urb *urb;
175 unsigned char *buffer; 198 void *buffer;
176 int status; 199 int status;
177 200
178 spin_lock_irqsave(&port->lock, flags); 201 spin_lock_irqsave(&port->lock, flags);
@@ -191,16 +214,14 @@ static int usb_serial_multi_urb_write(struct tty_struct *tty,
191 goto err_urb; 214 goto err_urb;
192 } 215 }
193 216
217 buffer = NULL;
194 count = min_t(int, count, PAGE_SIZE); 218 count = min_t(int, count, PAGE_SIZE);
195 buffer = kmalloc(count, GFP_ATOMIC); 219 count = port->serial->type->prepare_write_buffer(port, &buffer, 0,
196 if (!buffer) { 220 buf, count);
197 dev_err(&port->dev, "%s - could not allocate buffer\n", 221 if (count < 0) {
198 __func__); 222 status = count;
199 status = -ENOMEM;
200 goto err_buf; 223 goto err_buf;
201 } 224 }
202
203 memcpy(buffer, buf, count);
204 usb_serial_debug_data(debug, &port->dev, __func__, count, buffer); 225 usb_serial_debug_data(debug, &port->dev, __func__, count, buffer);
205 usb_fill_bulk_urb(urb, port->serial->dev, 226 usb_fill_bulk_urb(urb, port->serial->dev,
206 usb_sndbulkpipe(port->serial->dev, 227 usb_sndbulkpipe(port->serial->dev,
@@ -242,7 +263,6 @@ err_urb:
242 */ 263 */
243static int usb_serial_generic_write_start(struct usb_serial_port *port) 264static int usb_serial_generic_write_start(struct usb_serial_port *port)
244{ 265{
245 unsigned char *data;
246 int result; 266 int result;
247 int count; 267 int count;
248 unsigned long flags; 268 unsigned long flags;
@@ -255,10 +275,11 @@ static int usb_serial_generic_write_start(struct usb_serial_port *port)
255 port->write_urb_busy = 1; 275 port->write_urb_busy = 1;
256 spin_unlock_irqrestore(&port->lock, flags); 276 spin_unlock_irqrestore(&port->lock, flags);
257 277
258 data = port->write_urb->transfer_buffer; 278 count = port->serial->type->prepare_write_buffer(port,
259 count = kfifo_out_locked(&port->write_fifo, data, port->bulk_out_size, &port->lock); 279 &port->write_urb->transfer_buffer,
260 usb_serial_debug_data(debug, &port->dev, __func__, count, data); 280 port->bulk_out_size, NULL, 0);
261 281 usb_serial_debug_data(debug, &port->dev, __func__,
282 count, port->write_urb->transfer_buffer);
262 port->write_urb->transfer_buffer_length = count; 283 port->write_urb->transfer_buffer_length = count;
263 284
264 /* send the data out the bulk port */ 285 /* send the data out the bulk port */