USB: serial: metro-usb: fix up coding style errors
[deliverable/linux.git] / drivers / usb / serial / metro-usb.c
CommitLineData
43d186fe 1/*
d4cbd6e9
GKH
2 Some of this code is credited to Linux USB open source files that are
3 distributed with Linux.
43d186fe
AB
4
5 Copyright: 2007 Metrologic Instruments. All rights reserved.
6 Copyright: 2011 Azimut Ltd. <http://azimutrzn.ru/>
43d186fe
AB
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>
43d186fe 20#include <linux/errno.h>
d4cbd6e9 21#include <linux/uaccess.h>
43d186fe
AB
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
159d4d8d
GKH
28/* Product information. */
29#define FOCUS_VENDOR_ID 0x0C2E
30#define FOCUS_PRODUCT_ID 0x0720
31#define FOCUS_PRODUCT_ID_UNI 0x0710
32
33#define METROUSB_SET_REQUEST_TYPE 0x40
34#define METROUSB_SET_MODEM_CTRL_REQUEST 10
35#define METROUSB_SET_BREAK_REQUEST 0x40
36#define METROUSB_MCR_NONE 0x08 /* Deactivate DTR and RTS. */
37#define METROUSB_MCR_RTS 0x0a /* Activate RTS. */
38#define METROUSB_MCR_DTR 0x09 /* Activate DTR. */
d4cbd6e9 39#define WDR_TIMEOUT 5000 /* default urb timeout. */
159d4d8d
GKH
40
41/* Private data structure. */
42struct metrousb_private {
43 spinlock_t lock;
44 int throttled;
45 unsigned long control_state;
46};
47
43d186fe 48/* Device table list. */
d4cbd6e9 49static struct usb_device_id id_table[] = {
43d186fe
AB
50 { USB_DEVICE(FOCUS_VENDOR_ID, FOCUS_PRODUCT_ID) },
51 { USB_DEVICE(FOCUS_VENDOR_ID, FOCUS_PRODUCT_ID_UNI) },
43d186fe
AB
52 { }, /* Terminating entry. */
53};
54MODULE_DEVICE_TABLE(usb, id_table);
55
56/* Input parameter constants. */
fdac0f64 57static bool debug;
43d186fe
AB
58
59/* Function prototypes. */
d4cbd6e9
GKH
60static void metrousb_cleanup(struct usb_serial_port *port);
61static void metrousb_close(struct usb_serial_port *port);
62static int metrousb_open(struct tty_struct *tty, struct usb_serial_port *port);
63static void metrousb_read_int_callback(struct urb *urb);
64static void metrousb_shutdown(struct usb_serial *serial);
65static int metrousb_startup(struct usb_serial *serial);
43d186fe
AB
66static void metrousb_throttle(struct tty_struct *tty);
67static int metrousb_tiocmget(struct tty_struct *tty);
68static int metrousb_tiocmset(struct tty_struct *tty, unsigned int set, unsigned int clear);
69static void metrousb_unthrottle(struct tty_struct *tty);
70
71/* Driver structure. */
72static struct usb_driver metrousb_driver = {
73 .name = "metro-usb",
74 .probe = usb_serial_probe,
75 .disconnect = usb_serial_disconnect,
76 .id_table = id_table
77};
78
79/* Device structure. */
80static struct usb_serial_driver metrousb_device = {
81 .driver = {
82 .owner = THIS_MODULE,
83 .name = "metro-usb",
84 },
d4cbd6e9
GKH
85 .description = "Metrologic USB to serial converter.",
86 .id_table = id_table,
87 .num_ports = 1,
88 .open = metrousb_open,
89 .close = metrousb_close,
90 .read_int_callback = metrousb_read_int_callback,
91 .attach = metrousb_startup,
92 .release = metrousb_shutdown,
93 .throttle = metrousb_throttle,
94 .unthrottle = metrousb_unthrottle,
95 .tiocmget = metrousb_tiocmget,
96 .tiocmset = metrousb_tiocmset,
43d186fe
AB
97};
98
11a4f400
GKH
99static struct usb_serial_driver * const serial_drivers[] = {
100 &metrousb_device,
101 NULL,
102};
103
43d186fe
AB
104/* ----------------------------------------------------------------------------------------------
105 Description:
106 Clean up any urbs and port information.
107
108 Input:
109 struct usb_serial_port *: pointer to a usb_serial_port structure.
110
111 Output:
112 int: Returns true (0) if successful, false otherwise.
113*/
d4cbd6e9 114static void metrousb_cleanup(struct usb_serial_port *port)
43d186fe
AB
115{
116 dbg("METRO-USB - %s - port number=%d", __FUNCTION__, port->number);
117
118 if (port->serial->dev) {
119 /* Shutdown any interrupt in urbs. */
120 if (port->interrupt_in_urb) {
121 usb_unlink_urb(port->interrupt_in_urb);
122 usb_kill_urb(port->interrupt_in_urb);
123 }
43d186fe
AB
124 }
125}
126
127/* ----------------------------------------------------------------------------------------------
128 Description:
129 Close the open serial port. Cleanup any open serial port information.
130
131 Input:
132 struct usb_serial_port *: pointer to a usb_serial_port structure.
133 struct file *: pointer to a file structure.
134
135 Output:
136 int: Returns true (0) if successful, false otherwise.
137*/
d4cbd6e9 138static void metrousb_close(struct usb_serial_port *port)
43d186fe
AB
139{
140 dbg("METRO-USB - %s - port number=%d", __FUNCTION__, port->number);
141 metrousb_cleanup(port);
142}
143
43d186fe
AB
144/* ----------------------------------------------------------------------------------------------
145 Description:
146 Open the drivers serial port.
147
148 Input:
149 struct usb_serial_port *: pointer to a usb_serial_port structure.
150 struct file *: pointer to a file structure.
151
152 Output:
153 int: Returns true (0) if successful, false otherwise.
154*/
d4cbd6e9 155static int metrousb_open(struct tty_struct *tty, struct usb_serial_port *port)
43d186fe
AB
156{
157 struct usb_serial *serial = port->serial;
158 struct metrousb_private *metro_priv = usb_get_serial_port_data(port);
159 unsigned long flags = 0;
160 int result = 0;
161
162 dbg("METRO-USB - %s - port number=%d", __FUNCTION__, port->number);
163
164 /* Make sure the urb is initialized. */
165 if (!port->interrupt_in_urb) {
166 dbg("METRO-USB - %s - interrupt urb not initialized for port number=%d", __FUNCTION__, port->number);
167 return -ENODEV;
168 }
169
170 /* Set the private data information for the port. */
171 spin_lock_irqsave(&metro_priv->lock, flags);
172 metro_priv->control_state = 0;
173 metro_priv->throttled = 0;
174 spin_unlock_irqrestore(&metro_priv->lock, flags);
175
176 /*
177 * Force low_latency on so that our tty_push actually forces the data
178 * through, otherwise it is scheduled, and with high data rates (like
179 * with OHCI) data can get lost.
180 */
d4cbd6e9 181 if (tty)
43d186fe 182 tty->low_latency = 1;
43d186fe
AB
183
184 /* Clear the urb pipe. */
185 usb_clear_halt(serial->dev, port->interrupt_in_urb->pipe);
186
187 /* Start reading from the device */
d4cbd6e9
GKH
188 usb_fill_int_urb(port->interrupt_in_urb, serial->dev,
189 usb_rcvintpipe(serial->dev, port->interrupt_in_endpointAddress),
43d186fe
AB
190 port->interrupt_in_urb->transfer_buffer,
191 port->interrupt_in_urb->transfer_buffer_length,
192 metrousb_read_int_callback, port, 1);
193 result = usb_submit_urb(port->interrupt_in_urb, GFP_KERNEL);
194
195 if (result) {
196 dbg("METRO-USB - %s - failed submitting interrupt in urb for port number=%d, error code=%d"
197 , __FUNCTION__, port->number, result);
198 goto exit;
199 }
200
201 dbg("METRO-USB - %s - port open for port number=%d", __FUNCTION__, port->number);
202exit:
203 return result;
204}
205
206/* ----------------------------------------------------------------------------------------------
207 Description:
208 Read the port from the read interrupt.
209
210 Input:
211 struct urb *: urb structure to get data.
212 struct pt_regs *: pt_regs structure.
213
214 Output:
215 None:
216*/
d4cbd6e9 217static void metrousb_read_int_callback(struct urb *urb)
43d186fe
AB
218{
219 struct usb_serial_port *port = (struct usb_serial_port *)urb->context;
220 struct metrousb_private *metro_priv = usb_get_serial_port_data(port);
221 struct tty_struct *tty;
222 unsigned char *data = urb->transfer_buffer;
223 int throttled = 0;
224 int result = 0;
225 unsigned long flags = 0;
226
227 dbg("METRO-USB - %s - port number=%d", __FUNCTION__, port->number);
228
229 switch (urb->status) {
d4cbd6e9
GKH
230 case 0:
231 /* Success status, read from the port. */
232 break;
233 case -ECONNRESET:
234 case -ENOENT:
235 case -ESHUTDOWN:
236 /* urb has been terminated. */
237 dbg("METRO-USB - %s - urb shutting down, port number=%d, error code=%d",
238 __FUNCTION__, port->number, result);
239 return;
240 default:
241 dbg("METRO-USB - %s - non-zero urb received, port number=%d, error code=%d",
242 __FUNCTION__, port->number, result);
243 goto exit;
43d186fe
AB
244 }
245
246
247 /* Set the data read from the usb port into the serial port buffer. */
248 tty = tty_port_tty_get(&port->port);
249 if (!tty) {
250 dbg("%s - bad tty pointer - exiting", __func__);
251 return;
252 }
253
254 if (tty && urb->actual_length) {
d4cbd6e9 255 /* Loop through the data copying each byte to the tty layer. */
43d186fe
AB
256 tty_insert_flip_string(tty, data, urb->actual_length);
257
d4cbd6e9 258 /* Force the data to the tty layer. */
43d186fe
AB
259 tty_flip_buffer_push(tty);
260 }
261 tty_kref_put(tty);
262
263 /* Set any port variables. */
264 spin_lock_irqsave(&metro_priv->lock, flags);
265 throttled = metro_priv->throttled;
266 spin_unlock_irqrestore(&metro_priv->lock, flags);
267
268 /* Continue trying to read if set. */
269 if (!throttled) {
d4cbd6e9
GKH
270 usb_fill_int_urb(port->interrupt_in_urb, port->serial->dev,
271 usb_rcvintpipe(port->serial->dev, port->interrupt_in_endpointAddress),
272 port->interrupt_in_urb->transfer_buffer,
273 port->interrupt_in_urb->transfer_buffer_length,
274 metrousb_read_int_callback, port, 1);
43d186fe
AB
275
276 result = usb_submit_urb(port->interrupt_in_urb, GFP_ATOMIC);
277
278 if (result) {
279 dbg("METRO-USB - %s - failed submitting interrupt in urb for port number=%d, error code=%d",
280 __FUNCTION__, port->number, result);
281 }
282 }
283 return;
284
285exit:
286 /* Try to resubmit the urb. */
d4cbd6e9 287 result = usb_submit_urb(urb, GFP_ATOMIC);
43d186fe
AB
288 if (result) {
289 dbg("METRO-USB - %s - failed submitting interrupt in urb for port number=%d, error code=%d",
290 __FUNCTION__, port->number, result);
291 }
292}
293
294/* ----------------------------------------------------------------------------------------------
295 Description:
296 Set the modem control state for the entered serial port.
297
298 Input:
299 struct usb_serial_port *: pointer to a usb_serial_port structure.
300 unsigned int: control state value to set.
301
302 Output:
303 int: Returns true (0) if successful, false otherwise.
304*/
305static int metrousb_set_modem_ctrl(struct usb_serial *serial, unsigned int control_state)
306{
307 int retval = 0;
308 unsigned char mcr = METROUSB_MCR_NONE;
309
310 dbg("METRO-USB - %s - control state=%d", __FUNCTION__, control_state);
311
312 /* Set the modem control value. */
313 if (control_state & TIOCM_DTR)
314 mcr |= METROUSB_MCR_DTR;
315 if (control_state & TIOCM_RTS)
316 mcr |= METROUSB_MCR_RTS;
317
318 /* Send the command to the usb port. */
319 retval = usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev, 0),
320 METROUSB_SET_REQUEST_TYPE, METROUSB_SET_MODEM_CTRL_REQUEST,
321 control_state, 0, NULL, 0, WDR_TIMEOUT);
322 if (retval < 0)
323 dbg("METRO-USB - %s - set modem ctrl=0x%x failed, error code=%d", __FUNCTION__, mcr, retval);
324
325 return retval;
326}
327
328
329/* ----------------------------------------------------------------------------------------------
330 Description:
331 Shutdown the driver.
332
333 Input:
334 struct usb_serial *: pointer to a usb-serial structure.
335
336 Output:
337 int: Returns true (0) if successful, false otherwise.
338*/
d4cbd6e9 339static void metrousb_shutdown(struct usb_serial *serial)
43d186fe
AB
340{
341 int i = 0;
342
343 dbg("METRO-USB - %s", __FUNCTION__);
344
345 /* Stop reading and writing on all ports. */
d4cbd6e9 346 for (i = 0; i < serial->num_ports; ++i) {
43d186fe
AB
347 /* Close any open urbs. */
348 metrousb_cleanup(serial->port[i]);
349
350 /* Free memory. */
351 kfree(usb_get_serial_port_data(serial->port[i]));
352 usb_set_serial_port_data(serial->port[i], NULL);
353
354 dbg("METRO-USB - %s - freed port number=%d", __FUNCTION__, serial->port[i]->number);
355 }
356}
357
358/* ----------------------------------------------------------------------------------------------
359 Description:
360 Startup the driver.
361
362 Input:
363 struct usb_serial *: pointer to a usb-serial structure.
364
365 Output:
366 int: Returns true (0) if successful, false otherwise.
367*/
368static int metrousb_startup(struct usb_serial *serial)
369{
370 struct metrousb_private *metro_priv;
371 struct usb_serial_port *port;
372 int i = 0;
373
374 dbg("METRO-USB - %s", __FUNCTION__);
375
376 /* Loop through the serial ports setting up the private structures.
377 * Currently we only use one port. */
378 for (i = 0; i < serial->num_ports; ++i) {
379 port = serial->port[i];
380
381 /* Declare memory. */
d4cbd6e9 382 metro_priv = kmalloc(sizeof(struct metrousb_private), GFP_KERNEL);
43d186fe
AB
383 if (!metro_priv)
384 return -ENOMEM;
385
386 /* Clear memory. */
d4cbd6e9 387 memset(metro_priv, 0x00, sizeof(struct metrousb_private));
43d186fe
AB
388
389 /* Initialize memory. */
390 spin_lock_init(&metro_priv->lock);
391 usb_set_serial_port_data(port, metro_priv);
392
393 dbg("METRO-USB - %s - port number=%d.", __FUNCTION__, port->number);
394 }
395
396 return 0;
397}
398
399/* ----------------------------------------------------------------------------------------------
400 Description:
401 Set the serial port throttle to stop reading from the port.
402
403 Input:
404 struct usb_serial_port *: pointer to a usb_serial_port structure.
405
406 Output:
407 None:
408*/
d4cbd6e9 409static void metrousb_throttle(struct tty_struct *tty)
43d186fe
AB
410{
411 struct usb_serial_port *port = tty->driver_data;
412 struct metrousb_private *metro_priv = usb_get_serial_port_data(port);
413 unsigned long flags = 0;
414
415 dbg("METRO-USB - %s - port number=%d", __FUNCTION__, port->number);
416
417 /* Set the private information for the port to stop reading data. */
418 spin_lock_irqsave(&metro_priv->lock, flags);
419 metro_priv->throttled = 1;
420 spin_unlock_irqrestore(&metro_priv->lock, flags);
421}
422
423/* ----------------------------------------------------------------------------------------------
424 Description:
425 Get the serial port control line states.
426
427 Input:
428 struct usb_serial_port *: pointer to a usb_serial_port structure.
429 struct file *: pointer to a file structure.
430
431 Output:
432 int: Returns the state of the control lines.
433*/
d4cbd6e9 434static int metrousb_tiocmget(struct tty_struct *tty)
43d186fe
AB
435{
436 unsigned long control_state = 0;
437 struct usb_serial_port *port = tty->driver_data;
438 struct metrousb_private *metro_priv = usb_get_serial_port_data(port);
439 unsigned long flags = 0;
440
441 dbg("METRO-USB - %s - port number=%d", __FUNCTION__, port->number);
442
443 spin_lock_irqsave(&metro_priv->lock, flags);
444 control_state = metro_priv->control_state;
445 spin_unlock_irqrestore(&metro_priv->lock, flags);
446
447 return control_state;
448}
449
450/* ----------------------------------------------------------------------------------------------
451 Description:
452 Set the serial port control line states.
453
454 Input:
455 struct usb_serial_port *: pointer to a usb_serial_port structure.
456 struct file *: pointer to a file structure.
457 unsigned int: line state to set.
458 unsigned int: line state to clear.
459
460 Output:
461 int: Returns the state of the control lines.
462*/
d4cbd6e9
GKH
463static int metrousb_tiocmset(struct tty_struct *tty,
464 unsigned int set, unsigned int clear)
43d186fe
AB
465{
466 struct usb_serial_port *port = tty->driver_data;
467 struct usb_serial *serial = port->serial;
468 struct metrousb_private *metro_priv = usb_get_serial_port_data(port);
469 unsigned long flags = 0;
470 unsigned long control_state = 0;
471
472 dbg("METRO-USB - %s - port number=%d, set=%d, clear=%d", __FUNCTION__, port->number, set, clear);
473
474 spin_lock_irqsave(&metro_priv->lock, flags);
475 control_state = metro_priv->control_state;
476
d4cbd6e9 477 /* Set the RTS and DTR values. */
43d186fe
AB
478 if (set & TIOCM_RTS)
479 control_state |= TIOCM_RTS;
480 if (set & TIOCM_DTR)
481 control_state |= TIOCM_DTR;
482 if (clear & TIOCM_RTS)
483 control_state &= ~TIOCM_RTS;
484 if (clear & TIOCM_DTR)
485 control_state &= ~TIOCM_DTR;
486
487 metro_priv->control_state = control_state;
488 spin_unlock_irqrestore(&metro_priv->lock, flags);
489 return metrousb_set_modem_ctrl(serial, control_state);
490}
491
492/* ----------------------------------------------------------------------------------------------
493 Description:
494 Set the serial port unthrottle to resume reading from the port.
495
496 Input:
497 struct usb_serial_port *: pointer to a usb_serial_port structure.
498
499 Output:
500 None:
501*/
d4cbd6e9 502static void metrousb_unthrottle(struct tty_struct *tty)
43d186fe
AB
503{
504 struct usb_serial_port *port = tty->driver_data;
505 struct metrousb_private *metro_priv = usb_get_serial_port_data(port);
506 unsigned long flags = 0;
507 int result = 0;
508
509 dbg("METRO-USB - %s - port number=%d", __FUNCTION__, port->number);
510
511 /* Set the private information for the port to resume reading data. */
512 spin_lock_irqsave(&metro_priv->lock, flags);
513 metro_priv->throttled = 0;
514 spin_unlock_irqrestore(&metro_priv->lock, flags);
515
516 /* Submit the urb to read from the port. */
517 port->interrupt_in_urb->dev = port->serial->dev;
518 result = usb_submit_urb(port->interrupt_in_urb, GFP_ATOMIC);
519 if (result) {
520 dbg("METRO-USB - %s - failed submitting interrupt in urb for port number=%d, error code=%d",
521 __FUNCTION__, port->number, result);
522 }
523}
524
1935e357
GKH
525module_usb_serial_driver(metrousb_driver, serial_drivers);
526
43d186fe 527MODULE_LICENSE("GPL");
d4cbd6e9
GKH
528MODULE_AUTHOR("Philip Nicastro");
529MODULE_AUTHOR("Aleksey Babahin <tamerlan311@gmail.com>");
530MODULE_DESCRIPTION(DRIVER_DESC);
43d186fe
AB
531
532/* Module input parameters */
533module_param(debug, bool, S_IRUGO | S_IWUSR);
534MODULE_PARM_DESC(debug, "Print debug info (bool 1=on, 0=off)");
This page took 0.046782 seconds and 5 git commands to generate.