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 | |
| 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>
| -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); |
