diff options
author | Alon Ziv <alon+git@nolaviz.org> | 2010-10-10 02:32:19 -0400 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@suse.de> | 2010-10-22 13:22:09 -0400 |
commit | 0d930e51cfe6f748339d7d13b3fad2b91a1d92c2 (patch) | |
tree | cb6b1223824ce45dc385f4d4e488a564fdef08f0 /drivers/usb/serial | |
parent | 97cd8dc4ca9a1a5efb2cc38758e01492e3b013e2 (diff) |
USB: opticon: Add Opticon OPN2001 write support
OPN2001 expects write operations to arrive as a vendor-specific command
through the control pipe (instead of using a separate bulk-out pipe).
Signed-off-by: Alon Ziv <alon-git@nolaviz.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Diffstat (limited to 'drivers/usb/serial')
-rw-r--r-- | drivers/usb/serial/opticon.c | 30 |
1 files changed, 26 insertions, 4 deletions
diff --git a/drivers/usb/serial/opticon.c b/drivers/usb/serial/opticon.c index 9ff19c8a122e..4fe7c3d9ef98 100644 --- a/drivers/usb/serial/opticon.c +++ b/drivers/usb/serial/opticon.c | |||
@@ -187,6 +187,9 @@ static void opticon_write_bulk_callback(struct urb *urb) | |||
187 | /* free up the transfer buffer, as usb_free_urb() does not do this */ | 187 | /* free up the transfer buffer, as usb_free_urb() does not do this */ |
188 | kfree(urb->transfer_buffer); | 188 | kfree(urb->transfer_buffer); |
189 | 189 | ||
190 | /* setup packet may be set if we're using it for writing */ | ||
191 | kfree(urb->setup_packet); | ||
192 | |||
190 | if (status) | 193 | if (status) |
191 | dbg("%s - nonzero write bulk status received: %d", | 194 | dbg("%s - nonzero write bulk status received: %d", |
192 | __func__, status); | 195 | __func__, status); |
@@ -237,10 +240,29 @@ static int opticon_write(struct tty_struct *tty, struct usb_serial_port *port, | |||
237 | 240 | ||
238 | usb_serial_debug_data(debug, &port->dev, __func__, count, buffer); | 241 | usb_serial_debug_data(debug, &port->dev, __func__, count, buffer); |
239 | 242 | ||
240 | usb_fill_bulk_urb(urb, serial->dev, | 243 | if (port->bulk_out_endpointAddress) { |
241 | usb_sndbulkpipe(serial->dev, | 244 | usb_fill_bulk_urb(urb, serial->dev, |
242 | port->bulk_out_endpointAddress), | 245 | usb_sndbulkpipe(serial->dev, |
243 | buffer, count, opticon_write_bulk_callback, priv); | 246 | port->bulk_out_endpointAddress), |
247 | buffer, count, opticon_write_bulk_callback, priv); | ||
248 | } else { | ||
249 | struct usb_ctrlrequest *dr; | ||
250 | |||
251 | dr = kmalloc(sizeof(struct usb_ctrlrequest), GFP_NOIO); | ||
252 | if (!dr) | ||
253 | return -ENOMEM; | ||
254 | |||
255 | dr->bRequestType = USB_TYPE_VENDOR | USB_RECIP_INTERFACE | USB_DIR_OUT; | ||
256 | dr->bRequest = 0x01; | ||
257 | dr->wValue = 0; | ||
258 | dr->wIndex = 0; | ||
259 | dr->wLength = cpu_to_le16(count); | ||
260 | |||
261 | usb_fill_control_urb(urb, serial->dev, | ||
262 | usb_sndctrlpipe(serial->dev, 0), | ||
263 | (unsigned char *)dr, buffer, count, | ||
264 | opticon_write_bulk_callback, priv); | ||
265 | } | ||
244 | 266 | ||
245 | /* send it down the pipe */ | 267 | /* send it down the pipe */ |
246 | status = usb_submit_urb(urb, GFP_ATOMIC); | 268 | status = usb_submit_urb(urb, GFP_ATOMIC); |