diff options
Diffstat (limited to 'drivers/usb/serial')
| -rw-r--r-- | drivers/usb/serial/Kconfig | 17 | ||||
| -rw-r--r-- | drivers/usb/serial/Makefile | 2 | ||||
| -rw-r--r-- | drivers/usb/serial/digi_acceleport.c | 28 | ||||
| -rw-r--r-- | drivers/usb/serial/garmin_gps.c | 2 | ||||
| -rw-r--r-- | drivers/usb/serial/ipw.c | 4 | ||||
| -rw-r--r-- | drivers/usb/serial/iuu_phoenix.c | 38 | ||||
| -rw-r--r-- | drivers/usb/serial/mos7840.c | 38 | ||||
| -rw-r--r-- | drivers/usb/serial/opticon.c | 358 | ||||
| -rw-r--r-- | drivers/usb/serial/option.c | 11 | ||||
| -rw-r--r-- | drivers/usb/serial/siemens_mpi.c | 77 | ||||
| -rw-r--r-- | drivers/usb/serial/spcp8x5.c | 20 | ||||
| -rw-r--r-- | drivers/usb/serial/usb_debug.c | 2 |
12 files changed, 527 insertions, 70 deletions
diff --git a/drivers/usb/serial/Kconfig b/drivers/usb/serial/Kconfig index 70338f4ec918..b361f05cafac 100644 --- a/drivers/usb/serial/Kconfig +++ b/drivers/usb/serial/Kconfig | |||
| @@ -496,6 +496,14 @@ config USB_SERIAL_SAFE_PADDED | |||
| 496 | bool "USB Secure Encapsulated Driver - Padded" | 496 | bool "USB Secure Encapsulated Driver - Padded" |
| 497 | depends on USB_SERIAL_SAFE | 497 | depends on USB_SERIAL_SAFE |
| 498 | 498 | ||
| 499 | config USB_SERIAL_SIEMENS_MPI | ||
| 500 | tristate "USB Siemens MPI driver" | ||
| 501 | help | ||
| 502 | Say M here if you want to use a Siemens USB/MPI adapter. | ||
| 503 | |||
| 504 | To compile this driver as a module, choose M here: the | ||
| 505 | module will be called siemens_mpi. | ||
| 506 | |||
| 499 | config USB_SERIAL_SIERRAWIRELESS | 507 | config USB_SERIAL_SIERRAWIRELESS |
| 500 | tristate "USB Sierra Wireless Driver" | 508 | tristate "USB Sierra Wireless Driver" |
| 501 | help | 509 | help |
| @@ -565,6 +573,15 @@ config USB_SERIAL_OMNINET | |||
| 565 | To compile this driver as a module, choose M here: the | 573 | To compile this driver as a module, choose M here: the |
| 566 | module will be called omninet. | 574 | module will be called omninet. |
| 567 | 575 | ||
| 576 | config USB_SERIAL_OPTICON | ||
| 577 | tristate "USB Opticon Barcode driver (serial mode)" | ||
| 578 | help | ||
| 579 | Say Y here if you want to use a Opticon USB Barcode device | ||
| 580 | in serial emulation mode. | ||
| 581 | |||
| 582 | To compile this driver as a module, choose M here: the | ||
| 583 | module will be called opticon. | ||
| 584 | |||
| 568 | config USB_SERIAL_DEBUG | 585 | config USB_SERIAL_DEBUG |
| 569 | tristate "USB Debugging Device" | 586 | tristate "USB Debugging Device" |
| 570 | help | 587 | help |
diff --git a/drivers/usb/serial/Makefile b/drivers/usb/serial/Makefile index 6047f818adfe..b75be91eb8f1 100644 --- a/drivers/usb/serial/Makefile +++ b/drivers/usb/serial/Makefile | |||
| @@ -41,10 +41,12 @@ obj-$(CONFIG_USB_SERIAL_MOS7840) += mos7840.o | |||
| 41 | obj-$(CONFIG_USB_SERIAL_MOTOROLA) += moto_modem.o | 41 | obj-$(CONFIG_USB_SERIAL_MOTOROLA) += moto_modem.o |
| 42 | obj-$(CONFIG_USB_SERIAL_NAVMAN) += navman.o | 42 | obj-$(CONFIG_USB_SERIAL_NAVMAN) += navman.o |
| 43 | obj-$(CONFIG_USB_SERIAL_OMNINET) += omninet.o | 43 | obj-$(CONFIG_USB_SERIAL_OMNINET) += omninet.o |
| 44 | obj-$(CONFIG_USB_SERIAL_OPTICON) += opticon.o | ||
| 44 | obj-$(CONFIG_USB_SERIAL_OPTION) += option.o | 45 | obj-$(CONFIG_USB_SERIAL_OPTION) += option.o |
| 45 | obj-$(CONFIG_USB_SERIAL_OTI6858) += oti6858.o | 46 | obj-$(CONFIG_USB_SERIAL_OTI6858) += oti6858.o |
| 46 | obj-$(CONFIG_USB_SERIAL_PL2303) += pl2303.o | 47 | obj-$(CONFIG_USB_SERIAL_PL2303) += pl2303.o |
| 47 | obj-$(CONFIG_USB_SERIAL_SAFE) += safe_serial.o | 48 | obj-$(CONFIG_USB_SERIAL_SAFE) += safe_serial.o |
| 49 | obj-$(CONFIG_USB_SERIAL_SIEMENS_MPI) += siemens_mpi.o | ||
| 48 | obj-$(CONFIG_USB_SERIAL_SIERRAWIRELESS) += sierra.o | 50 | obj-$(CONFIG_USB_SERIAL_SIERRAWIRELESS) += sierra.o |
| 49 | obj-$(CONFIG_USB_SERIAL_SPCP8X5) += spcp8x5.o | 51 | obj-$(CONFIG_USB_SERIAL_SPCP8X5) += spcp8x5.o |
| 50 | obj-$(CONFIG_USB_SERIAL_TI) += ti_usb_3410_5052.o | 52 | obj-$(CONFIG_USB_SERIAL_TI) += ti_usb_3410_5052.o |
diff --git a/drivers/usb/serial/digi_acceleport.c b/drivers/usb/serial/digi_acceleport.c index 69f84f0ea6fe..38ba4ea8b6bf 100644 --- a/drivers/usb/serial/digi_acceleport.c +++ b/drivers/usb/serial/digi_acceleport.c | |||
| @@ -635,8 +635,7 @@ static int digi_write_oob_command(struct usb_serial_port *port, | |||
| 635 | 635 | ||
| 636 | spin_lock_irqsave(&oob_priv->dp_port_lock, flags); | 636 | spin_lock_irqsave(&oob_priv->dp_port_lock, flags); |
| 637 | while (count > 0) { | 637 | while (count > 0) { |
| 638 | while (oob_port->write_urb->status == -EINPROGRESS | 638 | while (oob_priv->dp_write_urb_in_use) { |
| 639 | || oob_priv->dp_write_urb_in_use) { | ||
| 640 | cond_wait_interruptible_timeout_irqrestore( | 639 | cond_wait_interruptible_timeout_irqrestore( |
| 641 | &oob_port->write_wait, DIGI_RETRY_TIMEOUT, | 640 | &oob_port->write_wait, DIGI_RETRY_TIMEOUT, |
| 642 | &oob_priv->dp_port_lock, flags); | 641 | &oob_priv->dp_port_lock, flags); |
| @@ -699,9 +698,8 @@ static int digi_write_inb_command(struct usb_serial_port *port, | |||
| 699 | 698 | ||
| 700 | spin_lock_irqsave(&priv->dp_port_lock, flags); | 699 | spin_lock_irqsave(&priv->dp_port_lock, flags); |
| 701 | while (count > 0 && ret == 0) { | 700 | while (count > 0 && ret == 0) { |
| 702 | while ((port->write_urb->status == -EINPROGRESS | 701 | while (priv->dp_write_urb_in_use && |
| 703 | || priv->dp_write_urb_in_use) | 702 | time_before(jiffies, timeout)) { |
| 704 | && time_before(jiffies, timeout)) { | ||
| 705 | cond_wait_interruptible_timeout_irqrestore( | 703 | cond_wait_interruptible_timeout_irqrestore( |
| 706 | &port->write_wait, DIGI_RETRY_TIMEOUT, | 704 | &port->write_wait, DIGI_RETRY_TIMEOUT, |
| 707 | &priv->dp_port_lock, flags); | 705 | &priv->dp_port_lock, flags); |
| @@ -779,8 +777,7 @@ static int digi_set_modem_signals(struct usb_serial_port *port, | |||
| 779 | spin_lock_irqsave(&oob_priv->dp_port_lock, flags); | 777 | spin_lock_irqsave(&oob_priv->dp_port_lock, flags); |
| 780 | spin_lock(&port_priv->dp_port_lock); | 778 | spin_lock(&port_priv->dp_port_lock); |
| 781 | 779 | ||
| 782 | while (oob_port->write_urb->status == -EINPROGRESS || | 780 | while (oob_priv->dp_write_urb_in_use) { |
| 783 | oob_priv->dp_write_urb_in_use) { | ||
| 784 | spin_unlock(&port_priv->dp_port_lock); | 781 | spin_unlock(&port_priv->dp_port_lock); |
| 785 | cond_wait_interruptible_timeout_irqrestore( | 782 | cond_wait_interruptible_timeout_irqrestore( |
| 786 | &oob_port->write_wait, DIGI_RETRY_TIMEOUT, | 783 | &oob_port->write_wait, DIGI_RETRY_TIMEOUT, |
| @@ -1168,12 +1165,10 @@ static int digi_write(struct tty_struct *tty, struct usb_serial_port *port, | |||
| 1168 | 1165 | ||
| 1169 | /* be sure only one write proceeds at a time */ | 1166 | /* be sure only one write proceeds at a time */ |
| 1170 | /* there are races on the port private buffer */ | 1167 | /* there are races on the port private buffer */ |
| 1171 | /* and races to check write_urb->status */ | ||
| 1172 | spin_lock_irqsave(&priv->dp_port_lock, flags); | 1168 | spin_lock_irqsave(&priv->dp_port_lock, flags); |
| 1173 | 1169 | ||
| 1174 | /* wait for urb status clear to submit another urb */ | 1170 | /* wait for urb status clear to submit another urb */ |
| 1175 | if (port->write_urb->status == -EINPROGRESS || | 1171 | if (priv->dp_write_urb_in_use) { |
| 1176 | priv->dp_write_urb_in_use) { | ||
| 1177 | /* buffer data if count is 1 (probably put_char) if possible */ | 1172 | /* buffer data if count is 1 (probably put_char) if possible */ |
| 1178 | if (count == 1 && priv->dp_out_buf_len < DIGI_OUT_BUF_SIZE) { | 1173 | if (count == 1 && priv->dp_out_buf_len < DIGI_OUT_BUF_SIZE) { |
| 1179 | priv->dp_out_buf[priv->dp_out_buf_len++] = *buf; | 1174 | priv->dp_out_buf[priv->dp_out_buf_len++] = *buf; |
| @@ -1236,7 +1231,7 @@ static void digi_write_bulk_callback(struct urb *urb) | |||
| 1236 | int ret = 0; | 1231 | int ret = 0; |
| 1237 | int status = urb->status; | 1232 | int status = urb->status; |
| 1238 | 1233 | ||
| 1239 | dbg("digi_write_bulk_callback: TOP, urb->status=%d", status); | 1234 | dbg("digi_write_bulk_callback: TOP, status=%d", status); |
| 1240 | 1235 | ||
| 1241 | /* port and serial sanity check */ | 1236 | /* port and serial sanity check */ |
| 1242 | if (port == NULL || (priv = usb_get_serial_port_data(port)) == NULL) { | 1237 | if (port == NULL || (priv = usb_get_serial_port_data(port)) == NULL) { |
| @@ -1266,8 +1261,7 @@ static void digi_write_bulk_callback(struct urb *urb) | |||
| 1266 | /* try to send any buffered data on this port, if it is open */ | 1261 | /* try to send any buffered data on this port, if it is open */ |
| 1267 | spin_lock(&priv->dp_port_lock); | 1262 | spin_lock(&priv->dp_port_lock); |
| 1268 | priv->dp_write_urb_in_use = 0; | 1263 | priv->dp_write_urb_in_use = 0; |
| 1269 | if (port->port.count && port->write_urb->status != -EINPROGRESS | 1264 | if (port->port.count && priv->dp_out_buf_len > 0) { |
| 1270 | && priv->dp_out_buf_len > 0) { | ||
| 1271 | *((unsigned char *)(port->write_urb->transfer_buffer)) | 1265 | *((unsigned char *)(port->write_urb->transfer_buffer)) |
| 1272 | = (unsigned char)DIGI_CMD_SEND_DATA; | 1266 | = (unsigned char)DIGI_CMD_SEND_DATA; |
| 1273 | *((unsigned char *)(port->write_urb->transfer_buffer) + 1) | 1267 | *((unsigned char *)(port->write_urb->transfer_buffer) + 1) |
| @@ -1305,8 +1299,7 @@ static int digi_write_room(struct tty_struct *tty) | |||
| 1305 | 1299 | ||
| 1306 | spin_lock_irqsave(&priv->dp_port_lock, flags); | 1300 | spin_lock_irqsave(&priv->dp_port_lock, flags); |
| 1307 | 1301 | ||
| 1308 | if (port->write_urb->status == -EINPROGRESS || | 1302 | if (priv->dp_write_urb_in_use) |
| 1309 | priv->dp_write_urb_in_use) | ||
| 1310 | room = 0; | 1303 | room = 0; |
| 1311 | else | 1304 | else |
| 1312 | room = port->bulk_out_size - 2 - priv->dp_out_buf_len; | 1305 | room = port->bulk_out_size - 2 - priv->dp_out_buf_len; |
| @@ -1322,8 +1315,7 @@ static int digi_chars_in_buffer(struct tty_struct *tty) | |||
| 1322 | struct usb_serial_port *port = tty->driver_data; | 1315 | struct usb_serial_port *port = tty->driver_data; |
| 1323 | struct digi_port *priv = usb_get_serial_port_data(port); | 1316 | struct digi_port *priv = usb_get_serial_port_data(port); |
| 1324 | 1317 | ||
| 1325 | if (port->write_urb->status == -EINPROGRESS | 1318 | if (priv->dp_write_urb_in_use) { |
| 1326 | || priv->dp_write_urb_in_use) { | ||
| 1327 | dbg("digi_chars_in_buffer: port=%d, chars=%d", | 1319 | dbg("digi_chars_in_buffer: port=%d, chars=%d", |
| 1328 | priv->dp_port_num, port->bulk_out_size - 2); | 1320 | priv->dp_port_num, port->bulk_out_size - 2); |
| 1329 | /* return(port->bulk_out_size - 2); */ | 1321 | /* return(port->bulk_out_size - 2); */ |
| @@ -1702,7 +1694,7 @@ static int digi_read_inb_callback(struct urb *urb) | |||
| 1702 | /* short/multiple packet check */ | 1694 | /* short/multiple packet check */ |
| 1703 | if (urb->actual_length != len + 2) { | 1695 | if (urb->actual_length != len + 2) { |
| 1704 | dev_err(&port->dev, "%s: INCOMPLETE OR MULTIPLE PACKET, " | 1696 | dev_err(&port->dev, "%s: INCOMPLETE OR MULTIPLE PACKET, " |
| 1705 | "urb->status=%d, port=%d, opcode=%d, len=%d, " | 1697 | "status=%d, port=%d, opcode=%d, len=%d, " |
| 1706 | "actual_length=%d, status=%d\n", __func__, status, | 1698 | "actual_length=%d, status=%d\n", __func__, status, |
| 1707 | priv->dp_port_num, opcode, len, urb->actual_length, | 1699 | priv->dp_port_num, opcode, len, urb->actual_length, |
| 1708 | port_status); | 1700 | port_status); |
diff --git a/drivers/usb/serial/garmin_gps.c b/drivers/usb/serial/garmin_gps.c index 8e6a66e38db2..a26a0e2cdb4a 100644 --- a/drivers/usb/serial/garmin_gps.c +++ b/drivers/usb/serial/garmin_gps.c | |||
| @@ -1056,7 +1056,7 @@ static void garmin_write_bulk_callback(struct urb *urb) | |||
| 1056 | 1056 | ||
| 1057 | if (status) { | 1057 | if (status) { |
| 1058 | dbg("%s - nonzero write bulk status received: %d", | 1058 | dbg("%s - nonzero write bulk status received: %d", |
| 1059 | __func__, urb->status); | 1059 | __func__, status); |
| 1060 | spin_lock_irqsave(&garmin_data_p->lock, flags); | 1060 | spin_lock_irqsave(&garmin_data_p->lock, flags); |
| 1061 | garmin_data_p->flags |= CLEAR_HALT_REQUIRED; | 1061 | garmin_data_p->flags |= CLEAR_HALT_REQUIRED; |
| 1062 | spin_unlock_irqrestore(&garmin_data_p->lock, flags); | 1062 | spin_unlock_irqrestore(&garmin_data_p->lock, flags); |
diff --git a/drivers/usb/serial/ipw.c b/drivers/usb/serial/ipw.c index 3ac59a8a980f..f530032ed93d 100644 --- a/drivers/usb/serial/ipw.c +++ b/drivers/usb/serial/ipw.c | |||
| @@ -473,7 +473,7 @@ static struct usb_serial_driver ipw_device = { | |||
| 473 | 473 | ||
| 474 | 474 | ||
| 475 | 475 | ||
| 476 | static int usb_ipw_init(void) | 476 | static int __init usb_ipw_init(void) |
| 477 | { | 477 | { |
| 478 | int retval; | 478 | int retval; |
| 479 | 479 | ||
| @@ -490,7 +490,7 @@ static int usb_ipw_init(void) | |||
| 490 | return 0; | 490 | return 0; |
| 491 | } | 491 | } |
| 492 | 492 | ||
| 493 | static void usb_ipw_exit(void) | 493 | static void __exit usb_ipw_exit(void) |
| 494 | { | 494 | { |
| 495 | usb_deregister(&usb_ipw_driver); | 495 | usb_deregister(&usb_ipw_driver); |
| 496 | usb_serial_deregister(&ipw_device); | 496 | usb_serial_deregister(&ipw_device); |
diff --git a/drivers/usb/serial/iuu_phoenix.c b/drivers/usb/serial/iuu_phoenix.c index e320972cb227..2314c6ae4fc2 100644 --- a/drivers/usb/serial/iuu_phoenix.c +++ b/drivers/usb/serial/iuu_phoenix.c | |||
| @@ -190,10 +190,12 @@ static void iuu_rxcmd(struct urb *urb) | |||
| 190 | { | 190 | { |
| 191 | struct usb_serial_port *port = urb->context; | 191 | struct usb_serial_port *port = urb->context; |
| 192 | int result; | 192 | int result; |
| 193 | int status = urb->status; | ||
| 194 | |||
| 193 | dbg("%s - enter", __func__); | 195 | dbg("%s - enter", __func__); |
| 194 | 196 | ||
| 195 | if (urb->status) { | 197 | if (status) { |
| 196 | dbg("%s - urb->status = %d", __func__, urb->status); | 198 | dbg("%s - status = %d", __func__, status); |
| 197 | /* error stop all */ | 199 | /* error stop all */ |
| 198 | return; | 200 | return; |
| 199 | } | 201 | } |
| @@ -245,10 +247,12 @@ static void iuu_update_status_callback(struct urb *urb) | |||
| 245 | struct usb_serial_port *port = urb->context; | 247 | struct usb_serial_port *port = urb->context; |
| 246 | struct iuu_private *priv = usb_get_serial_port_data(port); | 248 | struct iuu_private *priv = usb_get_serial_port_data(port); |
| 247 | u8 *st; | 249 | u8 *st; |
| 250 | int status = urb->status; | ||
| 251 | |||
| 248 | dbg("%s - enter", __func__); | 252 | dbg("%s - enter", __func__); |
| 249 | 253 | ||
| 250 | if (urb->status) { | 254 | if (status) { |
| 251 | dbg("%s - urb->status = %d", __func__, urb->status); | 255 | dbg("%s - status = %d", __func__, status); |
| 252 | /* error stop all */ | 256 | /* error stop all */ |
| 253 | return; | 257 | return; |
| 254 | } | 258 | } |
| @@ -274,9 +278,9 @@ static void iuu_status_callback(struct urb *urb) | |||
| 274 | { | 278 | { |
| 275 | struct usb_serial_port *port = urb->context; | 279 | struct usb_serial_port *port = urb->context; |
| 276 | int result; | 280 | int result; |
| 277 | dbg("%s - enter", __func__); | 281 | int status = urb->status; |
| 278 | 282 | ||
| 279 | dbg("%s - urb->status = %d", __func__, urb->status); | 283 | dbg("%s - status = %d", __func__, status); |
| 280 | usb_fill_bulk_urb(port->read_urb, port->serial->dev, | 284 | usb_fill_bulk_urb(port->read_urb, port->serial->dev, |
| 281 | usb_rcvbulkpipe(port->serial->dev, | 285 | usb_rcvbulkpipe(port->serial->dev, |
| 282 | port->bulk_in_endpointAddress), | 286 | port->bulk_in_endpointAddress), |
| @@ -618,11 +622,12 @@ static void read_buf_callback(struct urb *urb) | |||
| 618 | struct usb_serial_port *port = urb->context; | 622 | struct usb_serial_port *port = urb->context; |
| 619 | unsigned char *data = urb->transfer_buffer; | 623 | unsigned char *data = urb->transfer_buffer; |
| 620 | struct tty_struct *tty; | 624 | struct tty_struct *tty; |
| 621 | dbg("%s - urb->status = %d", __func__, urb->status); | 625 | int status = urb->status; |
| 622 | 626 | ||
| 623 | if (urb->status) { | 627 | dbg("%s - status = %d", __func__, status); |
| 624 | dbg("%s - urb->status = %d", __func__, urb->status); | 628 | |
| 625 | if (urb->status == -EPROTO) { | 629 | if (status) { |
| 630 | if (status == -EPROTO) { | ||
| 626 | /* reschedule needed */ | 631 | /* reschedule needed */ |
| 627 | } | 632 | } |
| 628 | return; | 633 | return; |
| @@ -695,7 +700,7 @@ static void iuu_uart_read_callback(struct urb *urb) | |||
| 695 | struct usb_serial_port *port = urb->context; | 700 | struct usb_serial_port *port = urb->context; |
| 696 | struct iuu_private *priv = usb_get_serial_port_data(port); | 701 | struct iuu_private *priv = usb_get_serial_port_data(port); |
| 697 | unsigned long flags; | 702 | unsigned long flags; |
| 698 | int status; | 703 | int status = urb->status; |
| 699 | int error = 0; | 704 | int error = 0; |
| 700 | int len = 0; | 705 | int len = 0; |
| 701 | unsigned char *data = urb->transfer_buffer; | 706 | unsigned char *data = urb->transfer_buffer; |
| @@ -703,8 +708,8 @@ static void iuu_uart_read_callback(struct urb *urb) | |||
| 703 | 708 | ||
| 704 | dbg("%s - enter", __func__); | 709 | dbg("%s - enter", __func__); |
| 705 | 710 | ||
| 706 | if (urb->status) { | 711 | if (status) { |
| 707 | dbg("%s - urb->status = %d", __func__, urb->status); | 712 | dbg("%s - status = %d", __func__, status); |
| 708 | /* error stop all */ | 713 | /* error stop all */ |
| 709 | return; | 714 | return; |
| 710 | } | 715 | } |
| @@ -782,12 +787,11 @@ static void read_rxcmd_callback(struct urb *urb) | |||
| 782 | { | 787 | { |
| 783 | struct usb_serial_port *port = urb->context; | 788 | struct usb_serial_port *port = urb->context; |
| 784 | int result; | 789 | int result; |
| 785 | dbg("%s - enter", __func__); | 790 | int status = urb->status; |
| 786 | 791 | ||
| 787 | dbg("%s - urb->status = %d", __func__, urb->status); | 792 | dbg("%s - status = %d", __func__, status); |
| 788 | 793 | ||
| 789 | if (urb->status) { | 794 | if (status) { |
| 790 | dbg("%s - urb->status = %d", __func__, urb->status); | ||
| 791 | /* error stop all */ | 795 | /* error stop all */ |
| 792 | return; | 796 | return; |
| 793 | } | 797 | } |
diff --git a/drivers/usb/serial/mos7840.c b/drivers/usb/serial/mos7840.c index 96a8c7713212..2c20e88a91b3 100644 --- a/drivers/usb/serial/mos7840.c +++ b/drivers/usb/serial/mos7840.c | |||
| @@ -214,6 +214,7 @@ struct moschip_port { | |||
| 214 | spinlock_t pool_lock; | 214 | spinlock_t pool_lock; |
| 215 | struct urb *write_urb_pool[NUM_URBS]; | 215 | struct urb *write_urb_pool[NUM_URBS]; |
| 216 | char busy[NUM_URBS]; | 216 | char busy[NUM_URBS]; |
| 217 | bool read_urb_busy; | ||
| 217 | }; | 218 | }; |
| 218 | 219 | ||
| 219 | 220 | ||
| @@ -679,26 +680,30 @@ static void mos7840_bulk_in_callback(struct urb *urb) | |||
| 679 | struct tty_struct *tty; | 680 | struct tty_struct *tty; |
| 680 | int status = urb->status; | 681 | int status = urb->status; |
| 681 | 682 | ||
| 682 | if (status) { | ||
| 683 | dbg("nonzero read bulk status received: %d", status); | ||
| 684 | return; | ||
| 685 | } | ||
| 686 | |||
| 687 | mos7840_port = urb->context; | 683 | mos7840_port = urb->context; |
| 688 | if (!mos7840_port) { | 684 | if (!mos7840_port) { |
| 689 | dbg("%s", "NULL mos7840_port pointer \n"); | 685 | dbg("%s", "NULL mos7840_port pointer \n"); |
| 686 | mos7840_port->read_urb_busy = false; | ||
| 687 | return; | ||
| 688 | } | ||
| 689 | |||
| 690 | if (status) { | ||
| 691 | dbg("nonzero read bulk status received: %d", status); | ||
| 692 | mos7840_port->read_urb_busy = false; | ||
| 690 | return; | 693 | return; |
| 691 | } | 694 | } |
| 692 | 695 | ||
| 693 | port = (struct usb_serial_port *)mos7840_port->port; | 696 | port = (struct usb_serial_port *)mos7840_port->port; |
| 694 | if (mos7840_port_paranoia_check(port, __func__)) { | 697 | if (mos7840_port_paranoia_check(port, __func__)) { |
| 695 | dbg("%s", "Port Paranoia failed \n"); | 698 | dbg("%s", "Port Paranoia failed \n"); |
| 699 | mos7840_port->read_urb_busy = false; | ||
| 696 | return; | 700 | return; |
| 697 | } | 701 | } |
| 698 | 702 | ||
| 699 | serial = mos7840_get_usb_serial(port, __func__); | 703 | serial = mos7840_get_usb_serial(port, __func__); |
| 700 | if (!serial) { | 704 | if (!serial) { |
| 701 | dbg("%s\n", "Bad serial pointer "); | 705 | dbg("%s\n", "Bad serial pointer "); |
| 706 | mos7840_port->read_urb_busy = false; | ||
| 702 | return; | 707 | return; |
| 703 | } | 708 | } |
| 704 | 709 | ||
| @@ -725,17 +730,19 @@ static void mos7840_bulk_in_callback(struct urb *urb) | |||
| 725 | 730 | ||
| 726 | if (!mos7840_port->read_urb) { | 731 | if (!mos7840_port->read_urb) { |
| 727 | dbg("%s", "URB KILLED !!!\n"); | 732 | dbg("%s", "URB KILLED !!!\n"); |
| 733 | mos7840_port->read_urb_busy = false; | ||
| 728 | return; | 734 | return; |
| 729 | } | 735 | } |
| 730 | 736 | ||
| 731 | 737 | ||
| 732 | mos7840_port->read_urb->dev = serial->dev; | 738 | mos7840_port->read_urb->dev = serial->dev; |
| 733 | 739 | ||
| 740 | mos7840_port->read_urb_busy = true; | ||
| 734 | retval = usb_submit_urb(mos7840_port->read_urb, GFP_ATOMIC); | 741 | retval = usb_submit_urb(mos7840_port->read_urb, GFP_ATOMIC); |
| 735 | 742 | ||
| 736 | if (retval) { | 743 | if (retval) { |
| 737 | dbg(" usb_submit_urb(read bulk) failed, retval = %d", | 744 | dbg("usb_submit_urb(read bulk) failed, retval = %d", retval); |
| 738 | retval); | 745 | mos7840_port->read_urb_busy = false; |
| 739 | } | 746 | } |
| 740 | } | 747 | } |
| 741 | 748 | ||
| @@ -1055,10 +1062,12 @@ static int mos7840_open(struct tty_struct *tty, | |||
| 1055 | 1062 | ||
| 1056 | dbg("mos7840_open: bulkin endpoint is %d\n", | 1063 | dbg("mos7840_open: bulkin endpoint is %d\n", |
| 1057 | port->bulk_in_endpointAddress); | 1064 | port->bulk_in_endpointAddress); |
| 1065 | mos7840_port->read_urb_busy = true; | ||
| 1058 | response = usb_submit_urb(mos7840_port->read_urb, GFP_KERNEL); | 1066 | response = usb_submit_urb(mos7840_port->read_urb, GFP_KERNEL); |
| 1059 | if (response) { | 1067 | if (response) { |
| 1060 | dev_err(&port->dev, "%s - Error %d submitting control urb\n", | 1068 | dev_err(&port->dev, "%s - Error %d submitting control urb\n", |
| 1061 | __func__, response); | 1069 | __func__, response); |
| 1070 | mos7840_port->read_urb_busy = false; | ||
| 1062 | } | 1071 | } |
| 1063 | 1072 | ||
| 1064 | /* initialize our wait queues */ | 1073 | /* initialize our wait queues */ |
| @@ -1227,6 +1236,7 @@ static void mos7840_close(struct tty_struct *tty, | |||
| 1227 | if (mos7840_port->read_urb) { | 1236 | if (mos7840_port->read_urb) { |
| 1228 | dbg("%s", "Shutdown bulk read\n"); | 1237 | dbg("%s", "Shutdown bulk read\n"); |
| 1229 | usb_kill_urb(mos7840_port->read_urb); | 1238 | usb_kill_urb(mos7840_port->read_urb); |
| 1239 | mos7840_port->read_urb_busy = false; | ||
| 1230 | } | 1240 | } |
| 1231 | if ((&mos7840_port->control_urb)) { | 1241 | if ((&mos7840_port->control_urb)) { |
| 1232 | dbg("%s", "Shutdown control read\n"); | 1242 | dbg("%s", "Shutdown control read\n"); |
| @@ -2043,14 +2053,14 @@ static void mos7840_change_port_settings(struct tty_struct *tty, | |||
| 2043 | Data = 0x0c; | 2053 | Data = 0x0c; |
| 2044 | mos7840_set_uart_reg(port, INTERRUPT_ENABLE_REGISTER, Data); | 2054 | mos7840_set_uart_reg(port, INTERRUPT_ENABLE_REGISTER, Data); |
| 2045 | 2055 | ||
| 2046 | if (mos7840_port->read_urb->status != -EINPROGRESS) { | 2056 | if (mos7840_port->read_urb_busy == false) { |
| 2047 | mos7840_port->read_urb->dev = serial->dev; | 2057 | mos7840_port->read_urb->dev = serial->dev; |
| 2048 | 2058 | mos7840_port->read_urb_busy = true; | |
| 2049 | status = usb_submit_urb(mos7840_port->read_urb, GFP_ATOMIC); | 2059 | status = usb_submit_urb(mos7840_port->read_urb, GFP_ATOMIC); |
| 2050 | |||
| 2051 | if (status) { | 2060 | if (status) { |
| 2052 | dbg(" usb_submit_urb(read bulk) failed, status = %d", | 2061 | dbg("usb_submit_urb(read bulk) failed, status = %d", |
| 2053 | status); | 2062 | status); |
| 2063 | mos7840_port->read_urb_busy = false; | ||
| 2054 | } | 2064 | } |
| 2055 | } | 2065 | } |
| 2056 | wake_up(&mos7840_port->delta_msr_wait); | 2066 | wake_up(&mos7840_port->delta_msr_wait); |
| @@ -2117,12 +2127,14 @@ static void mos7840_set_termios(struct tty_struct *tty, | |||
| 2117 | return; | 2127 | return; |
| 2118 | } | 2128 | } |
| 2119 | 2129 | ||
| 2120 | if (mos7840_port->read_urb->status != -EINPROGRESS) { | 2130 | if (mos7840_port->read_urb_busy == false) { |
| 2121 | mos7840_port->read_urb->dev = serial->dev; | 2131 | mos7840_port->read_urb->dev = serial->dev; |
| 2132 | mos7840_port->read_urb_busy = true; | ||
| 2122 | status = usb_submit_urb(mos7840_port->read_urb, GFP_ATOMIC); | 2133 | status = usb_submit_urb(mos7840_port->read_urb, GFP_ATOMIC); |
| 2123 | if (status) { | 2134 | if (status) { |
| 2124 | dbg(" usb_submit_urb(read bulk) failed, status = %d", | 2135 | dbg("usb_submit_urb(read bulk) failed, status = %d", |
| 2125 | status); | 2136 | status); |
| 2137 | mos7840_port->read_urb_busy = false; | ||
| 2126 | } | 2138 | } |
| 2127 | } | 2139 | } |
| 2128 | return; | 2140 | return; |
diff --git a/drivers/usb/serial/opticon.c b/drivers/usb/serial/opticon.c new file mode 100644 index 000000000000..cea326f1f105 --- /dev/null +++ b/drivers/usb/serial/opticon.c | |||
| @@ -0,0 +1,358 @@ | |||
| 1 | /* | ||
| 2 | * Opticon USB barcode to serial driver | ||
| 3 | * | ||
| 4 | * Copyright (C) 2008 Greg Kroah-Hartman <gregkh@suse.de> | ||
| 5 | * Copyright (C) 2008 Novell Inc. | ||
| 6 | * | ||
| 7 | * This program is free software; you can redistribute it and/or | ||
| 8 | * modify it under the terms of the GNU General Public License version | ||
| 9 | * 2 as published by the Free Software Foundation. | ||
| 10 | */ | ||
| 11 | |||
| 12 | #include <linux/kernel.h> | ||
| 13 | #include <linux/init.h> | ||
| 14 | #include <linux/tty.h> | ||
| 15 | #include <linux/tty_driver.h> | ||
| 16 | #include <linux/tty_flip.h> | ||
| 17 | #include <linux/module.h> | ||
| 18 | #include <linux/usb.h> | ||
| 19 | #include <linux/usb/serial.h> | ||
| 20 | #include <linux/uaccess.h> | ||
| 21 | |||
| 22 | static int debug; | ||
| 23 | |||
| 24 | static struct usb_device_id id_table[] = { | ||
| 25 | { USB_DEVICE(0x065a, 0x0009) }, | ||
| 26 | { }, | ||
| 27 | }; | ||
| 28 | MODULE_DEVICE_TABLE(usb, id_table); | ||
| 29 | |||
| 30 | /* This structure holds all of the individual device information */ | ||
| 31 | struct opticon_private { | ||
| 32 | struct usb_device *udev; | ||
| 33 | struct usb_serial *serial; | ||
| 34 | struct usb_serial_port *port; | ||
| 35 | unsigned char *bulk_in_buffer; | ||
| 36 | struct urb *bulk_read_urb; | ||
| 37 | int buffer_size; | ||
| 38 | u8 bulk_address; | ||
| 39 | spinlock_t lock; /* protects the following flags */ | ||
| 40 | bool throttled; | ||
| 41 | bool actually_throttled; | ||
| 42 | bool rts; | ||
| 43 | }; | ||
| 44 | |||
| 45 | static void opticon_bulk_callback(struct urb *urb) | ||
| 46 | { | ||
| 47 | struct opticon_private *priv = urb->context; | ||
| 48 | unsigned char *data = urb->transfer_buffer; | ||
| 49 | struct usb_serial_port *port = priv->port; | ||
| 50 | int status = urb->status; | ||
| 51 | struct tty_struct *tty; | ||
| 52 | int result; | ||
| 53 | int available_room = 0; | ||
| 54 | int data_length; | ||
| 55 | |||
| 56 | dbg("%s - port %d", __func__, port->number); | ||
| 57 | |||
| 58 | switch (status) { | ||
| 59 | case 0: | ||
| 60 | /* success */ | ||
| 61 | break; | ||
| 62 | case -ECONNRESET: | ||
| 63 | case -ENOENT: | ||
| 64 | case -ESHUTDOWN: | ||
| 65 | /* this urb is terminated, clean up */ | ||
| 66 | dbg("%s - urb shutting down with status: %d", | ||
| 67 | __func__, status); | ||
| 68 | return; | ||
| 69 | default: | ||
| 70 | dbg("%s - nonzero urb status received: %d", | ||
| 71 | __func__, status); | ||
| 72 | goto exit; | ||
| 73 | } | ||
| 74 | |||
| 75 | usb_serial_debug_data(debug, &port->dev, __func__, urb->actual_length, | ||
| 76 | data); | ||
| 77 | |||
| 78 | if (urb->actual_length > 2) { | ||
| 79 | data_length = urb->actual_length - 2; | ||
| 80 | |||
| 81 | /* | ||
| 82 | * Data from the device comes with a 2 byte header: | ||
| 83 | * | ||
| 84 | * <0x00><0x00>data... | ||
| 85 | * This is real data to be sent to the tty layer | ||
| 86 | * <0x00><0x01)level | ||
| 87 | * This is a RTS level change, the third byte is the RTS | ||
| 88 | * value (0 for low, 1 for high). | ||
| 89 | */ | ||
| 90 | if ((data[0] == 0x00) && (data[1] == 0x00)) { | ||
| 91 | /* real data, send it to the tty layer */ | ||
| 92 | tty = tty_port_tty_get(&port->port); | ||
| 93 | if (tty) { | ||
| 94 | available_room = tty_buffer_request_room(tty, | ||
| 95 | data_length); | ||
| 96 | if (available_room) { | ||
| 97 | tty_insert_flip_string(tty, data, | ||
| 98 | available_room); | ||
| 99 | tty_flip_buffer_push(tty); | ||
| 100 | } | ||
| 101 | tty_kref_put(tty); | ||
| 102 | } | ||
| 103 | } else { | ||
| 104 | if ((data[0] == 0x00) && (data[1] == 0x01)) { | ||
| 105 | if (data[2] == 0x00) | ||
| 106 | priv->rts = false; | ||
| 107 | else | ||
| 108 | priv->rts = true; | ||
| 109 | /* FIXME change the RTS level */ | ||
| 110 | } else { | ||
| 111 | dev_dbg(&priv->udev->dev, | ||
| 112 | "Unknown data packet received from the device:" | ||
| 113 | " %2x %2x\n", | ||
| 114 | data[0], data[1]); | ||
| 115 | } | ||
| 116 | } | ||
| 117 | } else { | ||
| 118 | dev_dbg(&priv->udev->dev, | ||
| 119 | "Improper ammount of data received from the device, " | ||
| 120 | "%d bytes", urb->actual_length); | ||
| 121 | } | ||
| 122 | |||
| 123 | exit: | ||
| 124 | spin_lock(&priv->lock); | ||
| 125 | |||
| 126 | /* Continue trying to always read if we should */ | ||
| 127 | if (!priv->throttled) { | ||
| 128 | usb_fill_bulk_urb(priv->bulk_read_urb, priv->udev, | ||
| 129 | usb_rcvbulkpipe(priv->udev, | ||
| 130 | priv->bulk_address), | ||
| 131 | priv->bulk_in_buffer, priv->buffer_size, | ||
| 132 | opticon_bulk_callback, priv); | ||
| 133 | result = usb_submit_urb(port->read_urb, GFP_ATOMIC); | ||
| 134 | if (result) | ||
| 135 | dev_err(&port->dev, | ||
| 136 | "%s - failed resubmitting read urb, error %d\n", | ||
| 137 | __func__, result); | ||
| 138 | } else | ||
| 139 | priv->actually_throttled = true; | ||
| 140 | spin_unlock(&priv->lock); | ||
| 141 | } | ||
| 142 | |||
| 143 | static int opticon_open(struct tty_struct *tty, struct usb_serial_port *port, | ||
| 144 | struct file *filp) | ||
| 145 | { | ||
| 146 | struct opticon_private *priv = usb_get_serial_data(port->serial); | ||
| 147 | unsigned long flags; | ||
| 148 | int result = 0; | ||
| 149 | |||
| 150 | dbg("%s - port %d", __func__, port->number); | ||
| 151 | |||
| 152 | spin_lock_irqsave(&priv->lock, flags); | ||
| 153 | priv->throttled = false; | ||
| 154 | priv->actually_throttled = false; | ||
| 155 | priv->port = port; | ||
| 156 | spin_unlock_irqrestore(&priv->lock, flags); | ||
| 157 | |||
| 158 | /* | ||
| 159 | * Force low_latency on so that our tty_push actually forces the data | ||
| 160 | * through, otherwise it is scheduled, and with high data rates (like | ||
| 161 | * with OHCI) data can get lost. | ||
| 162 | */ | ||
| 163 | if (tty) | ||
| 164 | tty->low_latency = 1; | ||
| 165 | |||
| 166 | /* Start reading from the device */ | ||
| 167 | usb_fill_bulk_urb(priv->bulk_read_urb, priv->udev, | ||
| 168 | usb_rcvbulkpipe(priv->udev, | ||
| 169 | priv->bulk_address), | ||
| 170 | priv->bulk_in_buffer, priv->buffer_size, | ||
| 171 | opticon_bulk_callback, priv); | ||
| 172 | result = usb_submit_urb(priv->bulk_read_urb, GFP_KERNEL); | ||
| 173 | if (result) | ||
| 174 | dev_err(&port->dev, | ||
| 175 | "%s - failed resubmitting read urb, error %d\n", | ||
| 176 | __func__, result); | ||
| 177 | return result; | ||
| 178 | } | ||
| 179 | |||
| 180 | static void opticon_close(struct tty_struct *tty, struct usb_serial_port *port, | ||
| 181 | struct file *filp) | ||
| 182 | { | ||
| 183 | struct opticon_private *priv = usb_get_serial_data(port->serial); | ||
| 184 | |||
| 185 | dbg("%s - port %d", __func__, port->number); | ||
| 186 | |||
| 187 | /* shutdown our urbs */ | ||
| 188 | usb_kill_urb(priv->bulk_read_urb); | ||
| 189 | } | ||
| 190 | |||
| 191 | static void opticon_throttle(struct tty_struct *tty) | ||
| 192 | { | ||
| 193 | struct usb_serial_port *port = tty->driver_data; | ||
| 194 | struct opticon_private *priv = usb_get_serial_data(port->serial); | ||
| 195 | unsigned long flags; | ||
| 196 | |||
| 197 | dbg("%s - port %d", __func__, port->number); | ||
| 198 | spin_lock_irqsave(&priv->lock, flags); | ||
| 199 | priv->throttled = true; | ||
| 200 | spin_unlock_irqrestore(&priv->lock, flags); | ||
| 201 | } | ||
| 202 | |||
| 203 | |||
| 204 | static void opticon_unthrottle(struct tty_struct *tty) | ||
| 205 | { | ||
| 206 | struct usb_serial_port *port = tty->driver_data; | ||
| 207 | struct opticon_private *priv = usb_get_serial_data(port->serial); | ||
| 208 | unsigned long flags; | ||
| 209 | int result; | ||
| 210 | |||
| 211 | dbg("%s - port %d", __func__, port->number); | ||
| 212 | |||
| 213 | spin_lock_irqsave(&priv->lock, flags); | ||
| 214 | priv->throttled = false; | ||
| 215 | priv->actually_throttled = false; | ||
| 216 | spin_unlock_irqrestore(&priv->lock, flags); | ||
| 217 | |||
| 218 | priv->bulk_read_urb->dev = port->serial->dev; | ||
| 219 | result = usb_submit_urb(priv->bulk_read_urb, GFP_ATOMIC); | ||
| 220 | if (result) | ||
| 221 | dev_err(&port->dev, | ||
| 222 | "%s - failed submitting read urb, error %d\n", | ||
| 223 | __func__, result); | ||
| 224 | } | ||
| 225 | |||
| 226 | static int opticon_startup(struct usb_serial *serial) | ||
| 227 | { | ||
| 228 | struct opticon_private *priv; | ||
| 229 | struct usb_host_interface *intf; | ||
| 230 | int i; | ||
| 231 | int retval = -ENOMEM; | ||
| 232 | bool bulk_in_found = false; | ||
| 233 | |||
| 234 | /* create our private serial structure */ | ||
| 235 | priv = kzalloc(sizeof(*priv), GFP_KERNEL); | ||
| 236 | if (priv == NULL) { | ||
| 237 | dev_err(&serial->dev->dev, "%s - Out of memory\n", __func__); | ||
| 238 | return -ENOMEM; | ||
| 239 | } | ||
| 240 | spin_lock_init(&priv->lock); | ||
| 241 | priv->serial = serial; | ||
| 242 | priv->port = serial->port[0]; | ||
| 243 | priv->udev = serial->dev; | ||
| 244 | |||
| 245 | /* find our bulk endpoint */ | ||
| 246 | intf = serial->interface->altsetting; | ||
| 247 | for (i = 0; i < intf->desc.bNumEndpoints; ++i) { | ||
| 248 | struct usb_endpoint_descriptor *endpoint; | ||
| 249 | |||
| 250 | endpoint = &intf->endpoint[i].desc; | ||
| 251 | if (!usb_endpoint_is_bulk_in(endpoint)) | ||
| 252 | continue; | ||
| 253 | |||
| 254 | priv->bulk_read_urb = usb_alloc_urb(0, GFP_KERNEL); | ||
| 255 | if (!priv->bulk_read_urb) { | ||
| 256 | dev_err(&priv->udev->dev, "out of memory\n"); | ||
| 257 | goto error; | ||
| 258 | } | ||
| 259 | |||
| 260 | priv->buffer_size = le16_to_cpu(endpoint->wMaxPacketSize) * 2; | ||
| 261 | priv->bulk_in_buffer = kmalloc(priv->buffer_size, GFP_KERNEL); | ||
| 262 | if (!priv->bulk_in_buffer) { | ||
| 263 | dev_err(&priv->udev->dev, "out of memory\n"); | ||
| 264 | goto error; | ||
| 265 | } | ||
| 266 | |||
| 267 | priv->bulk_address = endpoint->bEndpointAddress; | ||
| 268 | |||
| 269 | /* set up our bulk urb */ | ||
| 270 | usb_fill_bulk_urb(priv->bulk_read_urb, priv->udev, | ||
| 271 | usb_rcvbulkpipe(priv->udev, | ||
| 272 | endpoint->bEndpointAddress), | ||
| 273 | priv->bulk_in_buffer, priv->buffer_size, | ||
| 274 | opticon_bulk_callback, priv); | ||
| 275 | |||
| 276 | bulk_in_found = true; | ||
| 277 | break; | ||
| 278 | } | ||
| 279 | |||
| 280 | if (!bulk_in_found) { | ||
| 281 | dev_err(&priv->udev->dev, | ||
| 282 | "Error - the proper endpoints were not found!\n"); | ||
| 283 | goto error; | ||
| 284 | } | ||
| 285 | |||
| 286 | usb_set_serial_data(serial, priv); | ||
| 287 | return 0; | ||
| 288 | |||
| 289 | error: | ||
| 290 | usb_free_urb(priv->bulk_read_urb); | ||
| 291 | kfree(priv->bulk_in_buffer); | ||
| 292 | kfree(priv); | ||
| 293 | return retval; | ||
| 294 | } | ||
| 295 | |||
| 296 | static void opticon_shutdown(struct usb_serial *serial) | ||
| 297 | { | ||
| 298 | struct opticon_private *priv = usb_get_serial_data(serial); | ||
| 299 | |||
| 300 | dbg("%s", __func__); | ||
| 301 | |||
| 302 | usb_kill_urb(priv->bulk_read_urb); | ||
| 303 | usb_free_urb(priv->bulk_read_urb); | ||
| 304 | kfree(priv->bulk_in_buffer); | ||
| 305 | kfree(priv); | ||
| 306 | usb_set_serial_data(serial, NULL); | ||
| 307 | } | ||
| 308 | |||
| 309 | |||
| 310 | static struct usb_driver opticon_driver = { | ||
| 311 | .name = "opticon", | ||
| 312 | .probe = usb_serial_probe, | ||
| 313 | .disconnect = usb_serial_disconnect, | ||
| 314 | .id_table = id_table, | ||
| 315 | .no_dynamic_id = 1, | ||
| 316 | }; | ||
| 317 | |||
| 318 | static struct usb_serial_driver opticon_device = { | ||
| 319 | .driver = { | ||
| 320 | .owner = THIS_MODULE, | ||
| 321 | .name = "opticon", | ||
| 322 | }, | ||
| 323 | .id_table = id_table, | ||
| 324 | .usb_driver = &opticon_driver, | ||
| 325 | .num_ports = 1, | ||
| 326 | .attach = opticon_startup, | ||
| 327 | .open = opticon_open, | ||
| 328 | .close = opticon_close, | ||
| 329 | .shutdown = opticon_shutdown, | ||
| 330 | .throttle = opticon_throttle, | ||
| 331 | .unthrottle = opticon_unthrottle, | ||
| 332 | }; | ||
| 333 | |||
| 334 | static int __init opticon_init(void) | ||
| 335 | { | ||
| 336 | int retval; | ||
| 337 | |||
| 338 | retval = usb_serial_register(&opticon_device); | ||
| 339 | if (retval) | ||
| 340 | return retval; | ||
| 341 | retval = usb_register(&opticon_driver); | ||
| 342 | if (retval) | ||
| 343 | usb_serial_deregister(&opticon_device); | ||
| 344 | return retval; | ||
| 345 | } | ||
| 346 | |||
| 347 | static void __exit opticon_exit(void) | ||
| 348 | { | ||
| 349 | usb_deregister(&opticon_driver); | ||
| 350 | usb_serial_deregister(&opticon_device); | ||
| 351 | } | ||
| 352 | |||
| 353 | module_init(opticon_init); | ||
| 354 | module_exit(opticon_exit); | ||
| 355 | MODULE_LICENSE("GPL"); | ||
| 356 | |||
| 357 | module_param(debug, bool, S_IRUGO | S_IWUSR); | ||
| 358 | MODULE_PARM_DESC(debug, "Debug enabled or not"); | ||
diff --git a/drivers/usb/serial/option.c b/drivers/usb/serial/option.c index 809697b3c7fc..5ed183477aaf 100644 --- a/drivers/usb/serial/option.c +++ b/drivers/usb/serial/option.c | |||
| @@ -522,9 +522,9 @@ static int debug; | |||
| 522 | /* per port private data */ | 522 | /* per port private data */ |
| 523 | 523 | ||
| 524 | #define N_IN_URB 4 | 524 | #define N_IN_URB 4 |
| 525 | #define N_OUT_URB 1 | 525 | #define N_OUT_URB 4 |
| 526 | #define IN_BUFLEN 4096 | 526 | #define IN_BUFLEN 4096 |
| 527 | #define OUT_BUFLEN 128 | 527 | #define OUT_BUFLEN 4096 |
| 528 | 528 | ||
| 529 | struct option_port_private { | 529 | struct option_port_private { |
| 530 | /* Input endpoints and buffer for this port */ | 530 | /* Input endpoints and buffer for this port */ |
| @@ -654,10 +654,6 @@ static int option_write(struct tty_struct *tty, struct usb_serial_port *port, | |||
| 654 | usb_unlink_urb(this_urb); | 654 | usb_unlink_urb(this_urb); |
| 655 | continue; | 655 | continue; |
| 656 | } | 656 | } |
| 657 | if (this_urb->status != 0) | ||
| 658 | dbg("usb_write %p failed (err=%d)", | ||
| 659 | this_urb, this_urb->status); | ||
| 660 | |||
| 661 | dbg("%s: endpoint %d buf %d", __func__, | 657 | dbg("%s: endpoint %d buf %d", __func__, |
| 662 | usb_pipeendpoint(this_urb->pipe), i); | 658 | usb_pipeendpoint(this_urb->pipe), i); |
| 663 | 659 | ||
| @@ -669,8 +665,7 @@ static int option_write(struct tty_struct *tty, struct usb_serial_port *port, | |||
| 669 | err = usb_submit_urb(this_urb, GFP_ATOMIC); | 665 | err = usb_submit_urb(this_urb, GFP_ATOMIC); |
| 670 | if (err) { | 666 | if (err) { |
| 671 | dbg("usb_submit_urb %p (write bulk) failed " | 667 | dbg("usb_submit_urb %p (write bulk) failed " |
| 672 | "(%d, has %d)", this_urb, | 668 | "(%d)", this_urb, err); |
| 673 | err, this_urb->status); | ||
| 674 | clear_bit(i, &portdata->out_busy); | 669 | clear_bit(i, &portdata->out_busy); |
| 675 | continue; | 670 | continue; |
| 676 | } | 671 | } |
diff --git a/drivers/usb/serial/siemens_mpi.c b/drivers/usb/serial/siemens_mpi.c new file mode 100644 index 000000000000..951ea0c6ba77 --- /dev/null +++ b/drivers/usb/serial/siemens_mpi.c | |||
| @@ -0,0 +1,77 @@ | |||
| 1 | /* | ||
| 2 | * Siemens USB-MPI Serial USB driver | ||
| 3 | * | ||
| 4 | * Copyright (C) 2005 Thomas Hergenhahn <thomas.hergenhahn@suse.de> | ||
| 5 | * Copyright (C) 2005,2008 Greg Kroah-Hartman <gregkh@suse.de> | ||
| 6 | * | ||
| 7 | * This program is free software; you can redistribute it and/or | ||
| 8 | * modify it under the terms of the GNU General Public License version | ||
| 9 | * 2 as published by the Free Software Foundation. | ||
| 10 | */ | ||
| 11 | |||
| 12 | #include <linux/kernel.h> | ||
| 13 | #include <linux/init.h> | ||
| 14 | #include <linux/tty.h> | ||
| 15 | #include <linux/module.h> | ||
| 16 | #include <linux/usb.h> | ||
| 17 | #include <linux/usb/serial.h> | ||
| 18 | |||
| 19 | /* Version Information */ | ||
| 20 | #define DRIVER_VERSION "Version 0.1 09/26/2005" | ||
| 21 | #define DRIVER_AUTHOR "Thomas Hergenhahn@web.de http://libnodave.sf.net" | ||
| 22 | #define DRIVER_DESC "Driver for Siemens USB/MPI adapter" | ||
| 23 | |||
| 24 | |||
| 25 | static struct usb_device_id id_table[] = { | ||
| 26 | /* Vendor and product id for 6ES7-972-0CB20-0XA0 */ | ||
| 27 | { USB_DEVICE(0x908, 0x0004) }, | ||
| 28 | { }, | ||
| 29 | }; | ||
| 30 | MODULE_DEVICE_TABLE(usb, id_table); | ||
| 31 | |||
| 32 | static struct usb_driver siemens_usb_mpi_driver = { | ||
| 33 | .name = "siemens_mpi", | ||
| 34 | .probe = usb_serial_probe, | ||
| 35 | .disconnect = usb_serial_disconnect, | ||
| 36 | .id_table = id_table, | ||
| 37 | }; | ||
| 38 | |||
| 39 | static struct usb_serial_driver siemens_usb_mpi_device = { | ||
| 40 | .driver = { | ||
| 41 | .owner = THIS_MODULE, | ||
| 42 | .name = "siemens_mpi", | ||
| 43 | }, | ||
| 44 | .id_table = id_table, | ||
| 45 | .num_ports = 1, | ||
| 46 | }; | ||
| 47 | |||
| 48 | static int __init siemens_usb_mpi_init(void) | ||
| 49 | { | ||
| 50 | int retval; | ||
| 51 | |||
| 52 | retval = usb_serial_register(&siemens_usb_mpi_device); | ||
| 53 | if (retval) | ||
| 54 | goto failed_usb_serial_register; | ||
| 55 | retval = usb_register(&siemens_usb_mpi_driver); | ||
| 56 | if (retval) | ||
| 57 | goto failed_usb_register; | ||
| 58 | printk(KERN_INFO DRIVER_DESC "\n"); | ||
| 59 | printk(KERN_INFO DRIVER_VERSION " " DRIVER_AUTHOR "\n"); | ||
| 60 | return retval; | ||
| 61 | failed_usb_register: | ||
| 62 | usb_serial_deregister(&siemens_usb_mpi_device); | ||
| 63 | failed_usb_serial_register: | ||
| 64 | return retval; | ||
| 65 | } | ||
| 66 | |||
| 67 | static void __exit siemens_usb_mpi_exit(void) | ||
| 68 | { | ||
| 69 | usb_deregister(&siemens_usb_mpi_driver); | ||
| 70 | usb_serial_deregister(&siemens_usb_mpi_device); | ||
| 71 | } | ||
| 72 | |||
| 73 | module_init(siemens_usb_mpi_init); | ||
| 74 | module_exit(siemens_usb_mpi_exit); | ||
| 75 | MODULE_AUTHOR(DRIVER_AUTHOR); | ||
| 76 | MODULE_DESCRIPTION(DRIVER_DESC); | ||
| 77 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/usb/serial/spcp8x5.c b/drivers/usb/serial/spcp8x5.c index a65bc2bd8e71..5e7528cc81a8 100644 --- a/drivers/usb/serial/spcp8x5.c +++ b/drivers/usb/serial/spcp8x5.c | |||
| @@ -709,21 +709,20 @@ static void spcp8x5_read_bulk_callback(struct urb *urb) | |||
| 709 | unsigned char *data = urb->transfer_buffer; | 709 | unsigned char *data = urb->transfer_buffer; |
| 710 | unsigned long flags; | 710 | unsigned long flags; |
| 711 | int i; | 711 | int i; |
| 712 | int result; | 712 | int result = urb->status; |
| 713 | u8 status = 0; | 713 | u8 status; |
| 714 | char tty_flag; | 714 | char tty_flag; |
| 715 | 715 | ||
| 716 | dev_dbg(&port->dev, "start, urb->status = %d, " | 716 | dev_dbg(&port->dev, "start, result = %d, urb->actual_length = %d\n,", |
| 717 | "urb->actual_length = %d\n,", urb->status, urb->actual_length); | 717 | result, urb->actual_length); |
| 718 | 718 | ||
| 719 | /* check the urb status */ | 719 | /* check the urb status */ |
| 720 | if (urb->status) { | 720 | if (result) { |
| 721 | if (!port->port.count) | 721 | if (!port->port.count) |
| 722 | return; | 722 | return; |
| 723 | if (urb->status == -EPROTO) { | 723 | if (result == -EPROTO) { |
| 724 | /* spcp8x5 mysteriously fails with -EPROTO */ | 724 | /* spcp8x5 mysteriously fails with -EPROTO */ |
| 725 | /* reschedule the read */ | 725 | /* reschedule the read */ |
| 726 | urb->status = 0; | ||
| 727 | urb->dev = port->serial->dev; | 726 | urb->dev = port->serial->dev; |
| 728 | result = usb_submit_urb(urb , GFP_ATOMIC); | 727 | result = usb_submit_urb(urb , GFP_ATOMIC); |
| 729 | if (result) | 728 | if (result) |
| @@ -833,8 +832,9 @@ static void spcp8x5_write_bulk_callback(struct urb *urb) | |||
| 833 | struct usb_serial_port *port = urb->context; | 832 | struct usb_serial_port *port = urb->context; |
| 834 | struct spcp8x5_private *priv = usb_get_serial_port_data(port); | 833 | struct spcp8x5_private *priv = usb_get_serial_port_data(port); |
| 835 | int result; | 834 | int result; |
| 835 | int status = urb->status; | ||
| 836 | 836 | ||
| 837 | switch (urb->status) { | 837 | switch (status) { |
| 838 | case 0: | 838 | case 0: |
| 839 | /* success */ | 839 | /* success */ |
| 840 | break; | 840 | break; |
| @@ -843,14 +843,14 @@ static void spcp8x5_write_bulk_callback(struct urb *urb) | |||
| 843 | case -ESHUTDOWN: | 843 | case -ESHUTDOWN: |
| 844 | /* this urb is terminated, clean up */ | 844 | /* this urb is terminated, clean up */ |
| 845 | dev_dbg(&port->dev, "urb shutting down with status: %d\n", | 845 | dev_dbg(&port->dev, "urb shutting down with status: %d\n", |
| 846 | urb->status); | 846 | status); |
| 847 | priv->write_urb_in_use = 0; | 847 | priv->write_urb_in_use = 0; |
| 848 | return; | 848 | return; |
| 849 | default: | 849 | default: |
| 850 | /* error in the urb, so we have to resubmit it */ | 850 | /* error in the urb, so we have to resubmit it */ |
| 851 | dbg("%s - Overflow in write", __func__); | 851 | dbg("%s - Overflow in write", __func__); |
| 852 | dbg("%s - nonzero write bulk status received: %d", | 852 | dbg("%s - nonzero write bulk status received: %d", |
| 853 | __func__, urb->status); | 853 | __func__, status); |
| 854 | port->write_urb->transfer_buffer_length = 1; | 854 | port->write_urb->transfer_buffer_length = 1; |
| 855 | port->write_urb->dev = port->serial->dev; | 855 | port->write_urb->dev = port->serial->dev; |
| 856 | result = usb_submit_urb(port->write_urb, GFP_ATOMIC); | 856 | result = usb_submit_urb(port->write_urb, GFP_ATOMIC); |
diff --git a/drivers/usb/serial/usb_debug.c b/drivers/usb/serial/usb_debug.c index fc5d9952b03b..6c9cbb59552a 100644 --- a/drivers/usb/serial/usb_debug.c +++ b/drivers/usb/serial/usb_debug.c | |||
| @@ -31,7 +31,7 @@ static struct usb_driver debug_driver = { | |||
| 31 | .no_dynamic_id = 1, | 31 | .no_dynamic_id = 1, |
| 32 | }; | 32 | }; |
| 33 | 33 | ||
| 34 | int usb_debug_open(struct tty_struct *tty, struct usb_serial_port *port, | 34 | static int usb_debug_open(struct tty_struct *tty, struct usb_serial_port *port, |
| 35 | struct file *filp) | 35 | struct file *filp) |
| 36 | { | 36 | { |
| 37 | port->bulk_out_size = USB_DEBUG_MAX_PACKET_SIZE; | 37 | port->bulk_out_size = USB_DEBUG_MAX_PACKET_SIZE; |
