metro-usb.c (7b96c686223a5c902d6a59c7d178f3904f0ab757) | metro-usb.c (68e24113457e437b1576670f2419b77ed0531e9e) |
---|---|
1/* 2 Some of this code is credited to Linux USB open source files that are 3 distributed with Linux. 4 5 Copyright: 2007 Metrologic Instruments. All rights reserved. 6 Copyright: 2011 Azimut Ltd. <http://azimutrzn.ru/> 7*/ 8 9#include <linux/kernel.h> 10#include <linux/init.h> 11#include <linux/tty.h> 12#include <linux/module.h> 13#include <linux/usb.h> 14#include <linux/errno.h> 15#include <linux/slab.h> 16#include <linux/tty_driver.h> 17#include <linux/tty_flip.h> 18#include <linux/moduleparam.h> 19#include <linux/spinlock.h> | 1/* 2 Some of this code is credited to Linux USB open source files that are 3 distributed with Linux. 4 5 Copyright: 2007 Metrologic Instruments. All rights reserved. 6 Copyright: 2011 Azimut Ltd. <http://azimutrzn.ru/> 7*/ 8 9#include <linux/kernel.h> 10#include <linux/init.h> 11#include <linux/tty.h> 12#include <linux/module.h> 13#include <linux/usb.h> 14#include <linux/errno.h> 15#include <linux/slab.h> 16#include <linux/tty_driver.h> 17#include <linux/tty_flip.h> 18#include <linux/moduleparam.h> 19#include <linux/spinlock.h> |
20#include <linux/errno.h> | |
21#include <linux/uaccess.h> 22#include <linux/usb/serial.h> 23 24/* Version Information */ 25#define DRIVER_VERSION "v1.2.0.0" 26#define DRIVER_DESC "Metrologic Instruments Inc. - USB-POS driver" 27 28/* Product information. */ --- 22 unchanged lines hidden (view full) --- 51 { USB_DEVICE(FOCUS_VENDOR_ID, FOCUS_PRODUCT_ID_UNI) }, 52 { }, /* Terminating entry. */ 53}; 54MODULE_DEVICE_TABLE(usb, id_table); 55 56/* Input parameter constants. */ 57static bool debug; 58 | 20#include <linux/uaccess.h> 21#include <linux/usb/serial.h> 22 23/* Version Information */ 24#define DRIVER_VERSION "v1.2.0.0" 25#define DRIVER_DESC "Metrologic Instruments Inc. - USB-POS driver" 26 27/* Product information. */ --- 22 unchanged lines hidden (view full) --- 50 { USB_DEVICE(FOCUS_VENDOR_ID, FOCUS_PRODUCT_ID_UNI) }, 51 { }, /* Terminating entry. */ 52}; 53MODULE_DEVICE_TABLE(usb, id_table); 54 55/* Input parameter constants. */ 56static bool debug; 57 |
58/* UNI-Directional mode commands for device configure */ 59#define UNI_CMD_OPEN 0x80 60#define UNI_CMD_CLOSE 0xFF 61 62inline int metrousb_is_unidirectional_mode(struct usb_serial_port *port) 63{ 64 __u16 product_id = le16_to_cpu( 65 port->serial->dev->descriptor.idProduct); 66 67 return product_id == FOCUS_PRODUCT_ID_UNI; 68} 69 70static int metrousb_send_unidirectional_cmd(u8 cmd, struct usb_serial_port *port) 71{ 72 int ret; 73 int actual_len; 74 u8 *buffer_cmd = NULL; 75 76 if (!metrousb_is_unidirectional_mode(port)) 77 return 0; 78 79 buffer_cmd = kzalloc(sizeof(cmd), GFP_KERNEL); 80 if (!buffer_cmd) 81 return -ENOMEM; 82 83 *buffer_cmd = cmd; 84 85 ret = usb_interrupt_msg(port->serial->dev, 86 usb_sndintpipe(port->serial->dev, port->interrupt_out_endpointAddress), 87 buffer_cmd, sizeof(cmd), 88 &actual_len, USB_CTRL_SET_TIMEOUT); 89 90 kfree(buffer_cmd); 91 92 if (ret < 0) 93 return ret; 94 else if (actual_len != sizeof(cmd)) 95 return -EIO; 96 return 0; 97} 98 |
|
59static void metrousb_read_int_callback(struct urb *urb) 60{ 61 struct usb_serial_port *port = urb->context; 62 struct metrousb_private *metro_priv = usb_get_serial_port_data(port); 63 struct tty_struct *tty; 64 unsigned char *data = urb->transfer_buffer; 65 int throttled = 0; 66 int result = 0; --- 6 unchanged lines hidden (view full) --- 73 /* Success status, read from the port. */ 74 break; 75 case -ECONNRESET: 76 case -ENOENT: 77 case -ESHUTDOWN: 78 /* urb has been terminated. */ 79 dev_dbg(&port->dev, 80 "%s - urb shutting down, error code=%d\n", | 99static void metrousb_read_int_callback(struct urb *urb) 100{ 101 struct usb_serial_port *port = urb->context; 102 struct metrousb_private *metro_priv = usb_get_serial_port_data(port); 103 struct tty_struct *tty; 104 unsigned char *data = urb->transfer_buffer; 105 int throttled = 0; 106 int result = 0; --- 6 unchanged lines hidden (view full) --- 113 /* Success status, read from the port. */ 114 break; 115 case -ECONNRESET: 116 case -ENOENT: 117 case -ESHUTDOWN: 118 /* urb has been terminated. */ 119 dev_dbg(&port->dev, 120 "%s - urb shutting down, error code=%d\n", |
81 __func__, result); | 121 __func__, urb->status); |
82 return; 83 default: 84 dev_dbg(&port->dev, 85 "%s - non-zero urb received, error code=%d\n", | 122 return; 123 default: 124 dev_dbg(&port->dev, 125 "%s - non-zero urb received, error code=%d\n", |
86 __func__, result); | 126 __func__, urb->status); |
87 goto exit; 88 } 89 90 91 /* Set the data read from the usb port into the serial port buffer. */ 92 tty = tty_port_tty_get(&port->port); 93 if (!tty) { | 127 goto exit; 128 } 129 130 131 /* Set the data read from the usb port into the serial port buffer. */ 132 tty = tty_port_tty_get(&port->port); 133 if (!tty) { |
94 dev_dbg(&port->dev, "%s - bad tty pointer - exiting\n", | 134 dev_err(&port->dev, "%s - bad tty pointer - exiting\n", |
95 __func__); 96 return; 97 } 98 99 if (tty && urb->actual_length) { 100 /* Loop through the data copying each byte to the tty layer. */ 101 tty_insert_flip_string(tty, data, urb->actual_length); 102 --- 13 unchanged lines hidden (view full) --- 116 usb_rcvintpipe(port->serial->dev, port->interrupt_in_endpointAddress), 117 port->interrupt_in_urb->transfer_buffer, 118 port->interrupt_in_urb->transfer_buffer_length, 119 metrousb_read_int_callback, port, 1); 120 121 result = usb_submit_urb(port->interrupt_in_urb, GFP_ATOMIC); 122 123 if (result) | 135 __func__); 136 return; 137 } 138 139 if (tty && urb->actual_length) { 140 /* Loop through the data copying each byte to the tty layer. */ 141 tty_insert_flip_string(tty, data, urb->actual_length); 142 --- 13 unchanged lines hidden (view full) --- 156 usb_rcvintpipe(port->serial->dev, port->interrupt_in_endpointAddress), 157 port->interrupt_in_urb->transfer_buffer, 158 port->interrupt_in_urb->transfer_buffer_length, 159 metrousb_read_int_callback, port, 1); 160 161 result = usb_submit_urb(port->interrupt_in_urb, GFP_ATOMIC); 162 163 if (result) |
124 dev_dbg(&port->dev, | 164 dev_err(&port->dev, |
125 "%s - failed submitting interrupt in urb, error code=%d\n", 126 __func__, result); 127 } 128 return; 129 130exit: 131 /* Try to resubmit the urb. */ 132 result = usb_submit_urb(urb, GFP_ATOMIC); 133 if (result) | 165 "%s - failed submitting interrupt in urb, error code=%d\n", 166 __func__, result); 167 } 168 return; 169 170exit: 171 /* Try to resubmit the urb. */ 172 result = usb_submit_urb(urb, GFP_ATOMIC); 173 if (result) |
134 dev_dbg(&port->dev, | 174 dev_err(&port->dev, |
135 "%s - failed submitting interrupt in urb, error code=%d\n", 136 __func__, result); 137} 138 | 175 "%s - failed submitting interrupt in urb, error code=%d\n", 176 __func__, result); 177} 178 |
179static void metrousb_write_int_callback(struct urb *urb) 180{ 181 struct usb_serial_port *port = urb->context; 182 183 dev_warn(&port->dev, "%s not implemented yet.\n", 184 __func__); 185} 186 |
|
139static void metrousb_cleanup(struct usb_serial_port *port) 140{ 141 dev_dbg(&port->dev, "%s\n", __func__); 142 143 if (port->serial->dev) { 144 /* Shutdown any interrupt in urbs. */ 145 if (port->interrupt_in_urb) { 146 usb_unlink_urb(port->interrupt_in_urb); 147 usb_kill_urb(port->interrupt_in_urb); 148 } | 187static void metrousb_cleanup(struct usb_serial_port *port) 188{ 189 dev_dbg(&port->dev, "%s\n", __func__); 190 191 if (port->serial->dev) { 192 /* Shutdown any interrupt in urbs. */ 193 if (port->interrupt_in_urb) { 194 usb_unlink_urb(port->interrupt_in_urb); 195 usb_kill_urb(port->interrupt_in_urb); 196 } |
197 198 /* Send deactivate cmd to device */ 199 metrousb_send_unidirectional_cmd(UNI_CMD_CLOSE, port); |
|
149 } 150} 151 152static int metrousb_open(struct tty_struct *tty, struct usb_serial_port *port) 153{ 154 struct usb_serial *serial = port->serial; 155 struct metrousb_private *metro_priv = usb_get_serial_port_data(port); 156 unsigned long flags = 0; 157 int result = 0; 158 159 dev_dbg(&port->dev, "%s\n", __func__); 160 161 /* Make sure the urb is initialized. */ 162 if (!port->interrupt_in_urb) { | 200 } 201} 202 203static int metrousb_open(struct tty_struct *tty, struct usb_serial_port *port) 204{ 205 struct usb_serial *serial = port->serial; 206 struct metrousb_private *metro_priv = usb_get_serial_port_data(port); 207 unsigned long flags = 0; 208 int result = 0; 209 210 dev_dbg(&port->dev, "%s\n", __func__); 211 212 /* Make sure the urb is initialized. */ 213 if (!port->interrupt_in_urb) { |
163 dev_dbg(&port->dev, "%s - interrupt urb not initialized\n", | 214 dev_err(&port->dev, "%s - interrupt urb not initialized\n", |
164 __func__); 165 return -ENODEV; 166 } 167 168 /* Set the private data information for the port. */ 169 spin_lock_irqsave(&metro_priv->lock, flags); 170 metro_priv->control_state = 0; 171 metro_priv->throttled = 0; --- 14 unchanged lines hidden (view full) --- 186 usb_fill_int_urb(port->interrupt_in_urb, serial->dev, 187 usb_rcvintpipe(serial->dev, port->interrupt_in_endpointAddress), 188 port->interrupt_in_urb->transfer_buffer, 189 port->interrupt_in_urb->transfer_buffer_length, 190 metrousb_read_int_callback, port, 1); 191 result = usb_submit_urb(port->interrupt_in_urb, GFP_KERNEL); 192 193 if (result) { | 215 __func__); 216 return -ENODEV; 217 } 218 219 /* Set the private data information for the port. */ 220 spin_lock_irqsave(&metro_priv->lock, flags); 221 metro_priv->control_state = 0; 222 metro_priv->throttled = 0; --- 14 unchanged lines hidden (view full) --- 237 usb_fill_int_urb(port->interrupt_in_urb, serial->dev, 238 usb_rcvintpipe(serial->dev, port->interrupt_in_endpointAddress), 239 port->interrupt_in_urb->transfer_buffer, 240 port->interrupt_in_urb->transfer_buffer_length, 241 metrousb_read_int_callback, port, 1); 242 result = usb_submit_urb(port->interrupt_in_urb, GFP_KERNEL); 243 244 if (result) { |
194 dev_dbg(&port->dev, | 245 dev_err(&port->dev, |
195 "%s - failed submitting interrupt in urb, error code=%d\n", 196 __func__, result); 197 goto exit; 198 } 199 | 246 "%s - failed submitting interrupt in urb, error code=%d\n", 247 __func__, result); 248 goto exit; 249 } 250 |
251 /* Send activate cmd to device */ 252 result = metrousb_send_unidirectional_cmd(UNI_CMD_OPEN, port); 253 if (result) { 254 dev_err(&port->dev, 255 "%s - failed to configure device for port number=%d, error code=%d\n", 256 __func__, port->number, result); 257 goto exit; 258 } 259 |
|
200 dev_dbg(&port->dev, "%s - port open\n", __func__); 201exit: 202 return result; 203} 204 205static int metrousb_set_modem_ctrl(struct usb_serial *serial, unsigned int control_state) 206{ 207 int retval = 0; --- 8 unchanged lines hidden (view full) --- 216 if (control_state & TIOCM_RTS) 217 mcr |= METROUSB_MCR_RTS; 218 219 /* Send the command to the usb port. */ 220 retval = usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev, 0), 221 METROUSB_SET_REQUEST_TYPE, METROUSB_SET_MODEM_CTRL_REQUEST, 222 control_state, 0, NULL, 0, WDR_TIMEOUT); 223 if (retval < 0) | 260 dev_dbg(&port->dev, "%s - port open\n", __func__); 261exit: 262 return result; 263} 264 265static int metrousb_set_modem_ctrl(struct usb_serial *serial, unsigned int control_state) 266{ 267 int retval = 0; --- 8 unchanged lines hidden (view full) --- 276 if (control_state & TIOCM_RTS) 277 mcr |= METROUSB_MCR_RTS; 278 279 /* Send the command to the usb port. */ 280 retval = usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev, 0), 281 METROUSB_SET_REQUEST_TYPE, METROUSB_SET_MODEM_CTRL_REQUEST, 282 control_state, 0, NULL, 0, WDR_TIMEOUT); 283 if (retval < 0) |
224 dev_dbg(&serial->dev->dev, | 284 dev_err(&serial->dev->dev, |
225 "%s - set modem ctrl=0x%x failed, error code=%d\n", 226 __func__, mcr, retval); 227 228 return retval; 229} 230 231static void metrousb_shutdown(struct usb_serial *serial) 232{ --- 116 unchanged lines hidden (view full) --- 349 spin_lock_irqsave(&metro_priv->lock, flags); 350 metro_priv->throttled = 0; 351 spin_unlock_irqrestore(&metro_priv->lock, flags); 352 353 /* Submit the urb to read from the port. */ 354 port->interrupt_in_urb->dev = port->serial->dev; 355 result = usb_submit_urb(port->interrupt_in_urb, GFP_ATOMIC); 356 if (result) | 285 "%s - set modem ctrl=0x%x failed, error code=%d\n", 286 __func__, mcr, retval); 287 288 return retval; 289} 290 291static void metrousb_shutdown(struct usb_serial *serial) 292{ --- 116 unchanged lines hidden (view full) --- 409 spin_lock_irqsave(&metro_priv->lock, flags); 410 metro_priv->throttled = 0; 411 spin_unlock_irqrestore(&metro_priv->lock, flags); 412 413 /* Submit the urb to read from the port. */ 414 port->interrupt_in_urb->dev = port->serial->dev; 415 result = usb_submit_urb(port->interrupt_in_urb, GFP_ATOMIC); 416 if (result) |
357 dev_dbg(tty->dev, | 417 dev_err(tty->dev, |
358 "failed submitting interrupt in urb error code=%d\n", 359 result); 360} 361 | 418 "failed submitting interrupt in urb error code=%d\n", 419 result); 420} 421 |
362static struct usb_driver metrousb_driver = { 363 .name = "metro-usb", 364 .probe = usb_serial_probe, 365 .disconnect = usb_serial_disconnect, 366 .id_table = id_table 367}; 368 | |
369static struct usb_serial_driver metrousb_device = { 370 .driver = { 371 .owner = THIS_MODULE, 372 .name = "metro-usb", 373 }, | 422static struct usb_serial_driver metrousb_device = { 423 .driver = { 424 .owner = THIS_MODULE, 425 .name = "metro-usb", 426 }, |
374 .description = "Metrologic USB to serial converter.", | 427 .description = "Metrologic USB to Serial", |
375 .id_table = id_table, 376 .num_ports = 1, 377 .open = metrousb_open, 378 .close = metrousb_cleanup, 379 .read_int_callback = metrousb_read_int_callback, | 428 .id_table = id_table, 429 .num_ports = 1, 430 .open = metrousb_open, 431 .close = metrousb_cleanup, 432 .read_int_callback = metrousb_read_int_callback, |
433 .write_int_callback = metrousb_write_int_callback, |
|
380 .attach = metrousb_startup, 381 .release = metrousb_shutdown, 382 .throttle = metrousb_throttle, 383 .unthrottle = metrousb_unthrottle, 384 .tiocmget = metrousb_tiocmget, 385 .tiocmset = metrousb_tiocmset, 386}; 387 388static struct usb_serial_driver * const serial_drivers[] = { 389 &metrousb_device, 390 NULL, 391}; 392 | 434 .attach = metrousb_startup, 435 .release = metrousb_shutdown, 436 .throttle = metrousb_throttle, 437 .unthrottle = metrousb_unthrottle, 438 .tiocmget = metrousb_tiocmget, 439 .tiocmset = metrousb_tiocmset, 440}; 441 442static struct usb_serial_driver * const serial_drivers[] = { 443 &metrousb_device, 444 NULL, 445}; 446 |
393module_usb_serial_driver(metrousb_driver, serial_drivers); | 447module_usb_serial_driver(serial_drivers, id_table); |
394 395MODULE_LICENSE("GPL"); 396MODULE_AUTHOR("Philip Nicastro"); 397MODULE_AUTHOR("Aleksey Babahin <tamerlan311@gmail.com>"); 398MODULE_DESCRIPTION(DRIVER_DESC); 399 400/* Module input parameters */ 401module_param(debug, bool, S_IRUGO | S_IWUSR); 402MODULE_PARM_DESC(debug, "Print debug info (bool 1=on, 0=off)"); | 448 449MODULE_LICENSE("GPL"); 450MODULE_AUTHOR("Philip Nicastro"); 451MODULE_AUTHOR("Aleksey Babahin <tamerlan311@gmail.com>"); 452MODULE_DESCRIPTION(DRIVER_DESC); 453 454/* Module input parameters */ 455module_param(debug, bool, S_IRUGO | S_IWUSR); 456MODULE_PARM_DESC(debug, "Print debug info (bool 1=on, 0=off)"); |