File: /usr/src/linux/drivers/usb/serial/belkin_sa.c

1     /*
2      * Belkin USB Serial Adapter Driver
3      *
4      *  Copyright (C) 2000
5      *      William Greathouse (wgreathouse@smva.com)
6      *
7      *  This program is largely derived from work by the linux-usb group
8      *  and associated source files.  Please see the usb/serial files for
9      *  individual credits and copyrights.
10      *  
11      * 	This program is free software; you can redistribute it and/or modify
12      * 	it under the terms of the GNU General Public License as published by
13      * 	the Free Software Foundation; either version 2 of the License, or
14      * 	(at your option) any later version.
15      *
16      * See Documentation/usb/usb-serial.txt for more information on using this driver
17      *
18      * TODO:
19      * -- Add true modem contol line query capability.  Currently we track the
20      *    states reported by the interrupt and the states we request.
21      * -- Add error reporting back to application for UART error conditions.
22      *    Just point me at how to implement this and I'll do it. I've put the
23      *    framework in, but haven't analyzed the "tty_flip" interface yet.
24      * -- Add support for flush commands
25      * -- Add everything that is missing :)
26      * 
27      * (30-May-2001 gkh
28      *	switched from using spinlock to a semaphore, which fixes lots of problems.
29      *
30      * 08-Apr-2001 gb
31      *	- Identify version on module load.
32      *
33      * 12-Mar-2001 gkh
34      *	- Added support for the GoHubs GO-COM232 device which is the same as the
35      *	  Peracom device.
36      *
37      * 06-Nov-2000 gkh
38      *	- Added support for the old Belkin and Peracom devices.
39      *	- Made the port able to be opened multiple times.
40      *	- Added some defaults incase the line settings are things these devices
41      *	  can't support. 
42      *
43      * 18-Oct-2000 William Greathouse
44      *    Released into the wild (linux-usb-devel)
45      *
46      * 17-Oct-2000 William Greathouse
47      *    Add code to recognize firmware version and set hardware flow control
48      *    appropriately.  Belkin states that firmware prior to 3.05 does not
49      *    operate correctly in hardware handshake mode.  I have verified this
50      *    on firmware 2.05 -- for both RTS and DTR input flow control, the control
51      *    line is not reset.  The test performed by the Belkin Win* driver is
52      *    to enable hardware flow control for firmware 2.06 or greater and
53      *    for 1.00 or prior.  I am only enabling for 2.06 or greater.
54      *
55      * 12-Oct-2000 William Greathouse
56      *    First cut at supporting Belkin USB Serial Adapter F5U103
57      *    I did not have a copy of the original work to support this
58      *    adapter, so pardon any stupid mistakes.  All of the information
59      *    I am using to write this driver was acquired by using a modified
60      *    UsbSnoop on Windows2000 and from examining the other USB drivers.
61      */
62     
63     #include <linux/config.h>
64     #include <linux/kernel.h>
65     #include <linux/sched.h>
66     #include <linux/signal.h>
67     #include <linux/errno.h>
68     #include <linux/poll.h>
69     #include <linux/init.h>
70     #include <linux/slab.h>
71     #include <linux/fcntl.h>
72     #include <linux/tty.h>
73     #include <linux/tty_driver.h>
74     #include <linux/tty_flip.h>
75     #include <linux/module.h>
76     #include <linux/spinlock.h>
77     #include <linux/usb.h>
78     
79     #ifdef CONFIG_USB_SERIAL_DEBUG
80      	static int debug = 1;
81     #else
82      	static int debug;
83     #endif
84     
85     #include "usb-serial.h"
86     #include "belkin_sa.h"
87     
88     /*
89      * Version Information
90      */
91     #define DRIVER_VERSION "v1.1"
92     #define DRIVER_AUTHOR "William Greathouse <wgreathouse@smva.com>"
93     #define DRIVER_DESC "USB Belkin Serial converter driver"
94     
95     /* function prototypes for a Belkin USB Serial Adapter F5U103 */
96     static int  belkin_sa_startup		(struct usb_serial *serial);
97     static void belkin_sa_shutdown		(struct usb_serial *serial);
98     static int  belkin_sa_open		(struct usb_serial_port *port, struct file *filp);
99     static void belkin_sa_close		(struct usb_serial_port *port, struct file *filp);
100     static void belkin_sa_read_int_callback (struct urb *urb);
101     static void belkin_sa_set_termios	(struct usb_serial_port *port, struct termios * old);
102     static int  belkin_sa_ioctl		(struct usb_serial_port *port, struct file * file, unsigned int cmd, unsigned long arg);
103     static void belkin_sa_break_ctl		(struct usb_serial_port *port, int break_state );
104     
105     
106     static __devinitdata struct usb_device_id id_table_combined [] = {
107     	{ USB_DEVICE(BELKIN_SA_VID, BELKIN_SA_PID) },
108     	{ USB_DEVICE(BELKIN_OLD_VID, BELKIN_OLD_PID) },
109     	{ USB_DEVICE(PERACOM_VID, PERACOM_PID) },
110     	{ USB_DEVICE(GOHUBS_VID, GOHUBS_PID) },
111     	{ }							/* Terminating entry */
112     };
113     
114     static __devinitdata struct usb_device_id belkin_sa_table [] = {
115     	{ USB_DEVICE(BELKIN_SA_VID, BELKIN_SA_PID) },
116     	{ }							/* Terminating entry */
117     };
118     
119     static __devinitdata struct usb_device_id belkin_old_table [] = {
120     	{ USB_DEVICE(BELKIN_OLD_VID, BELKIN_OLD_PID) },
121     	{ }							/* Terminating entry */
122     };
123     
124     static __devinitdata struct usb_device_id peracom_table [] = {
125     	{ USB_DEVICE(PERACOM_VID, PERACOM_PID) },
126     	{ }							/* Terminating entry */
127     };
128     
129     static __devinitdata struct usb_device_id gocom232_table [] = {
130     	{ USB_DEVICE(GOHUBS_VID, GOHUBS_PID) },
131     	{ }							/* Terminating entry */
132     };
133     
134     MODULE_DEVICE_TABLE (usb, id_table_combined);
135     
136     /* All of the device info needed for the Belkin serial converter */
137     struct usb_serial_device_type belkin_sa_device = {
138     	name:			"Belkin F5U103 USB Serial Adapter",
139     	id_table:		belkin_sa_table,		/* the Belkin F5U103 device */
140     	needs_interrupt_in:	MUST_HAVE,			/* this device must have an interrupt in endpoint */
141     	needs_bulk_in:		MUST_HAVE,			/* this device must have a bulk in endpoint */
142     	needs_bulk_out:		MUST_HAVE,			/* this device must have a bulk out endpoint */
143     	num_interrupt_in:	1,
144     	num_bulk_in:		1,
145     	num_bulk_out:		1,
146     	num_ports:		1,
147     	open:			belkin_sa_open,
148     	close:			belkin_sa_close,
149     	read_int_callback:	belkin_sa_read_int_callback,	/* How we get the status info */
150     	ioctl:			belkin_sa_ioctl,
151     	set_termios:		belkin_sa_set_termios,
152     	break_ctl:		belkin_sa_break_ctl,
153     	startup:		belkin_sa_startup,
154     	shutdown:		belkin_sa_shutdown,
155     };
156     
157     
158     /* This driver also supports the "old" school Belkin single port adaptor */
159     struct usb_serial_device_type belkin_old_device = {
160     	name:			"Belkin USB Serial Adapter",
161     	id_table:		belkin_old_table,		/* the old Belkin device */
162     	needs_interrupt_in:	MUST_HAVE,			/* this device must have an interrupt in endpoint */
163     	needs_bulk_in:		MUST_HAVE,			/* this device must have a bulk in endpoint */
164     	needs_bulk_out:		MUST_HAVE,			/* this device must have a bulk out endpoint */
165     	num_interrupt_in:	1,
166     	num_bulk_in:		1,
167     	num_bulk_out:		1,
168     	num_ports:		1,
169     	open:			belkin_sa_open,
170     	close:			belkin_sa_close,
171     	read_int_callback:	belkin_sa_read_int_callback,	/* How we get the status info */
172     	ioctl:			belkin_sa_ioctl,
173     	set_termios:		belkin_sa_set_termios,
174     	break_ctl:		belkin_sa_break_ctl,
175     	startup:		belkin_sa_startup,
176     	shutdown:		belkin_sa_shutdown,
177     };
178     
179     /* this driver also works for the Peracom single port adapter */
180     struct usb_serial_device_type peracom_device = {
181     	name:			"Peracom single port USB Serial Adapter",
182     	id_table:		peracom_table,			/* the Peracom device */
183     	needs_interrupt_in:	MUST_HAVE,			/* this device must have an interrupt in endpoint */
184     	needs_bulk_in:		MUST_HAVE,			/* this device must have a bulk in endpoint */
185     	needs_bulk_out:		MUST_HAVE,			/* this device must have a bulk out endpoint */
186     	num_interrupt_in:	1,
187     	num_bulk_in:		1,
188     	num_bulk_out:		1,
189     	num_ports:		1,
190     	open:			belkin_sa_open,
191     	close:			belkin_sa_close,
192     	read_int_callback:	belkin_sa_read_int_callback,	/* How we get the status info */
193     	ioctl:			belkin_sa_ioctl,
194     	set_termios:		belkin_sa_set_termios,
195     	break_ctl:		belkin_sa_break_ctl,
196     	startup:		belkin_sa_startup,
197     	shutdown:		belkin_sa_shutdown,
198     };
199     
200     /* the GoHubs Go-COM232 device is the same as the Peracom single port adapter */
201     struct usb_serial_device_type gocom232_device = {
202     	name:			"GO-COM232 USB Serial Converter",
203     	id_table:		gocom232_table,			/* the GO-COM232 device */
204     	needs_interrupt_in:	MUST_HAVE,			/* this device must have an interrupt in endpoint */
205     	needs_bulk_in:		MUST_HAVE,			/* this device must have a bulk in endpoint */
206     	needs_bulk_out:		MUST_HAVE,			/* this device must have a bulk out endpoint */
207     	num_interrupt_in:	1,
208     	num_bulk_in:		1,
209     	num_bulk_out:		1,
210     	num_ports:		1,
211     	open:			belkin_sa_open,
212     	close:			belkin_sa_close,
213     	read_int_callback:	belkin_sa_read_int_callback,	/* How we get the status info */
214     	ioctl:			belkin_sa_ioctl,
215     	set_termios:		belkin_sa_set_termios,
216     	break_ctl:		belkin_sa_break_ctl,
217     	startup:		belkin_sa_startup,
218     	shutdown:		belkin_sa_shutdown,
219     };
220     
221     
222     struct belkin_sa_private {
223     	unsigned long		control_state;
224     	unsigned char		last_lsr;
225     	unsigned char		last_msr;
226     	int			bad_flow_control;
227     };
228     
229     
230     /*
231      * ***************************************************************************
232      * Belkin USB Serial Adapter F5U103 specific driver functions
233      * ***************************************************************************
234      */
235     
236     #define WDR_TIMEOUT (HZ * 5 ) /* default urb timeout */
237     
238     /* assumes that struct usb_serial *serial is available */
239     #define BSA_USB_CMD(c,v) usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev, 0), \
240     					    (c), BELKIN_SA_SET_REQUEST_TYPE, \
241     					    (v), 0, NULL, 0, WDR_TIMEOUT)
242     
243     /* do some startup allocations not currently performed by usb_serial_probe() */
244     static int belkin_sa_startup (struct usb_serial *serial)
245     {
246     	struct usb_device *dev = serial->dev;
247     	struct belkin_sa_private *priv;
248     
249     	/* allocate the private data structure */
250     	serial->port->private = kmalloc(sizeof(struct belkin_sa_private), GFP_KERNEL);
251     	if (!serial->port->private)
252     		return (-1); /* error */
253     	priv = (struct belkin_sa_private *)serial->port->private;
254     	/* set initial values for control structures */
255     	priv->control_state = 0;
256     	priv->last_lsr = 0;
257     	priv->last_msr = 0;
258     	/* see comments at top of file */
259     	priv->bad_flow_control = (dev->descriptor.bcdDevice <= 0x0206) ? 1 : 0;
260     	info("bcdDevice: %04x, bfc: %d", dev->descriptor.bcdDevice, priv->bad_flow_control);
261     
262     	init_waitqueue_head(&serial->port->write_wait);
263     	
264     	return (0);
265     }
266     
267     
268     static void belkin_sa_shutdown (struct usb_serial *serial)
269     {
270     	int i;
271     	
272     	dbg (__FUNCTION__);
273     
274     	/* stop reads and writes on all ports */
275     	for (i=0; i < serial->num_ports; ++i) {
276     		while (serial->port[i].open_count > 0) {
277     			belkin_sa_close (&serial->port[i], NULL);
278     		}
279     		/* My special items, the standard routines free my urbs */
280     		if (serial->port[i].private)
281     			kfree(serial->port[i].private);
282     	}
283     }
284     
285     
286     static int  belkin_sa_open (struct usb_serial_port *port, struct file *filp)
287     {
288     	int retval = 0;
289     
290     	dbg(__FUNCTION__" port %d", port->number);
291     
292     	down (&port->sem);
293     	
294     	++port->open_count;
295     	MOD_INC_USE_COUNT;
296     	
297     	if (!port->active) {
298     		port->active = 1;
299     
300     		/*Start reading from the device*/
301     		/* TODO: Look at possibility of submitting mulitple URBs to device to
302     		 *       enhance buffering.  Win trace shows 16 initial read URBs.
303     		 */
304     		port->read_urb->dev = port->serial->dev;
305     		retval = usb_submit_urb(port->read_urb);
306     		if (retval) {
307     			err("usb_submit_urb(read bulk) failed");
308     			goto exit;
309     		}
310     
311     		port->interrupt_in_urb->dev = port->serial->dev;
312     		retval = usb_submit_urb(port->interrupt_in_urb);
313     		if (retval)
314     			err(" usb_submit_urb(read int) failed");
315     	}
316     	
317     exit:
318     	up (&port->sem);
319     
320     	return retval;
321     } /* belkin_sa_open */
322     
323     
324     static void belkin_sa_close (struct usb_serial_port *port, struct file *filp)
325     {
326     	dbg(__FUNCTION__" port %d", port->number);
327     
328     	down (&port->sem);
329     
330     	--port->open_count;
331     
332     	if (port->open_count <= 0) {
333     		/* shutdown our bulk reads and writes */
334     		usb_unlink_urb (port->write_urb);
335     		usb_unlink_urb (port->read_urb);
336     		usb_unlink_urb (port->interrupt_in_urb);	/* wgg - do I need this? I think so. */
337     		port->active = 0;
338     	}
339     	
340     	up (&port->sem);
341     	MOD_DEC_USE_COUNT;
342     } /* belkin_sa_close */
343     
344     
345     static void belkin_sa_read_int_callback (struct urb *urb)
346     {
347     	struct usb_serial_port *port = (struct usb_serial_port *)urb->context;
348     	struct belkin_sa_private *priv = (struct belkin_sa_private *)port->private;
349     	struct usb_serial *serial;
350     	unsigned char *data = urb->transfer_buffer;
351     
352     	/* the urb might have been killed. */
353     	if (urb->status)
354     		return;
355     	
356     	if (port_paranoia_check (port, "belkin_sa_read_interrupt")) return;
357     
358     	serial = port->serial;
359     	if (serial_paranoia_check (serial, "belkin_sa_read_interrupt")) return;
360     	
361     	usb_serial_debug_data (__FILE__, __FUNCTION__, urb->actual_length, data);
362     
363     	/* Handle known interrupt data */
364     	/* ignore data[0] and data[1] */
365     
366     	priv->last_msr = data[BELKIN_SA_MSR_INDEX];
367     	
368     	/* Record Control Line states */
369     	if (priv->last_msr & BELKIN_SA_MSR_DSR)
370     		priv->control_state |= TIOCM_DSR;
371     	else
372     		priv->control_state &= ~TIOCM_DSR;
373     
374     	if (priv->last_msr & BELKIN_SA_MSR_CTS)
375     		priv->control_state |= TIOCM_CTS;
376     	else
377     		priv->control_state &= ~TIOCM_CTS;
378     
379     	if (priv->last_msr & BELKIN_SA_MSR_RI)
380     		priv->control_state |= TIOCM_RI;
381     	else
382     		priv->control_state &= ~TIOCM_RI;
383     
384     	if (priv->last_msr & BELKIN_SA_MSR_CD)
385     		priv->control_state |= TIOCM_CD;
386     	else
387     		priv->control_state &= ~TIOCM_CD;
388     
389     	/* Now to report any errors */
390     	priv->last_lsr = data[BELKIN_SA_LSR_INDEX];
391     #if 0
392     	/*
393     	 * fill in the flip buffer here, but I do not know the relation
394     	 * to the current/next receive buffer or characters.  I need
395     	 * to look in to this before committing any code.
396     	 */
397     	if (priv->last_lsr & BELKIN_SA_LSR_ERR) {
398     		tty = port->tty;
399     		/* Overrun Error */
400     		if (priv->last_lsr & BELKIN_SA_LSR_OE) {
401     		}
402     		/* Parity Error */
403     		if (priv->last_lsr & BELKIN_SA_LSR_PE) {
404     		}
405     		/* Framing Error */
406     		if (priv->last_lsr & BELKIN_SA_LSR_FE) {
407     		}
408     		/* Break Indicator */
409     		if (priv->last_lsr & BELKIN_SA_LSR_BI) {
410     		}
411     	}
412     #endif
413     
414     	/* INT urbs are automatically re-submitted */
415     }
416     
417     static void belkin_sa_set_termios (struct usb_serial_port *port, struct termios *old_termios)
418     {
419     	struct usb_serial *serial = port->serial;
420     	struct belkin_sa_private *priv = (struct belkin_sa_private *)port->private;
421     	unsigned int iflag = port->tty->termios->c_iflag;
422     	unsigned int cflag = port->tty->termios->c_cflag;
423     	unsigned int old_iflag = old_termios->c_iflag;
424     	unsigned int old_cflag = old_termios->c_cflag;
425     	__u16 urb_value = 0; /* Will hold the new flags */
426     	
427     	/* Set the baud rate */
428     	if( (cflag&CBAUD) != (old_cflag&CBAUD) ) {
429     		/* reassert DTR and (maybe) RTS on transition from B0 */
430     		if( (old_cflag&CBAUD) == B0 ) {
431     			priv->control_state |= (TIOCM_DTR|TIOCM_RTS);
432     			if (BSA_USB_CMD(BELKIN_SA_SET_DTR_REQUEST, 1) < 0)
433     				err("Set DTR error");
434     			/* don't set RTS if using hardware flow control */
435     			if (!(old_cflag&CRTSCTS) )
436     				if (BSA_USB_CMD(BELKIN_SA_SET_RTS_REQUEST, 1) < 0)
437     					err("Set RTS error");
438     		}
439     
440     		switch(cflag & CBAUD) {
441     			case B0: /* handled below */ break;
442     			case B300: urb_value = BELKIN_SA_BAUD(300); break;
443     			case B600: urb_value = BELKIN_SA_BAUD(600); break;
444     			case B1200: urb_value = BELKIN_SA_BAUD(1200); break;
445     			case B2400: urb_value = BELKIN_SA_BAUD(2400); break;
446     			case B4800: urb_value = BELKIN_SA_BAUD(4800); break;
447     			case B9600: urb_value = BELKIN_SA_BAUD(9600); break;
448     			case B19200: urb_value = BELKIN_SA_BAUD(19200); break;
449     			case B38400: urb_value = BELKIN_SA_BAUD(38400); break;
450     			case B57600: urb_value = BELKIN_SA_BAUD(57600); break;
451     			case B115200: urb_value = BELKIN_SA_BAUD(115200); break;
452     			case B230400: urb_value = BELKIN_SA_BAUD(230400); break;
453     			default: err("BELKIN USB Serial Adapter: unsupported baudrate request, using default of 9600");
454     				urb_value = BELKIN_SA_BAUD(9600); break;
455     		}
456     		if ((cflag & CBAUD) != B0 ) {
457     			if (BSA_USB_CMD(BELKIN_SA_SET_BAUDRATE_REQUEST, urb_value) < 0)
458     				err("Set baudrate error");
459     		} else {
460     			/* Disable flow control */
461     			if (BSA_USB_CMD(BELKIN_SA_SET_FLOW_CTRL_REQUEST, BELKIN_SA_FLOW_NONE) < 0)
462     				err("Disable flowcontrol error");
463     
464     			/* Drop RTS and DTR */
465     			priv->control_state &= ~(TIOCM_DTR | TIOCM_RTS);
466     			if (BSA_USB_CMD(BELKIN_SA_SET_DTR_REQUEST, 0) < 0)
467     				err("DTR LOW error");
468     			if (BSA_USB_CMD(BELKIN_SA_SET_RTS_REQUEST, 0) < 0)
469     				err("RTS LOW error");
470     		}
471     	}
472     
473     	/* set the parity */
474     	if( (cflag&(PARENB|PARODD)) != (old_cflag&(PARENB|PARODD)) ) {
475     		if (cflag & PARENB)
476     			urb_value = (cflag & PARODD) ?  BELKIN_SA_PARITY_ODD : BELKIN_SA_PARITY_EVEN;
477     		else
478     			urb_value = BELKIN_SA_PARITY_NONE;
479     		if (BSA_USB_CMD(BELKIN_SA_SET_PARITY_REQUEST, urb_value) < 0)
480     			err("Set parity error");
481     	}
482     
483     	/* set the number of data bits */
484     	if( (cflag&CSIZE) != (old_cflag&CSIZE) ) {
485     		switch (cflag & CSIZE) {
486     			case CS5: urb_value = BELKIN_SA_DATA_BITS(5); break;
487     			case CS6: urb_value = BELKIN_SA_DATA_BITS(6); break;
488     			case CS7: urb_value = BELKIN_SA_DATA_BITS(7); break;
489     			case CS8: urb_value = BELKIN_SA_DATA_BITS(8); break;
490     			default: err("CSIZE was not CS5-CS8, using default of 8");
491     				urb_value = BELKIN_SA_DATA_BITS(8);
492     				break;
493     		}
494     		if (BSA_USB_CMD(BELKIN_SA_SET_DATA_BITS_REQUEST, urb_value) < 0)
495     			err("Set data bits error");
496     	}
497     
498     	/* set the number of stop bits */
499     	if( (cflag&CSTOPB) != (old_cflag&CSTOPB) ) {
500     		urb_value = (cflag & CSTOPB) ? BELKIN_SA_STOP_BITS(2) : BELKIN_SA_STOP_BITS(1);
501     		if (BSA_USB_CMD(BELKIN_SA_SET_STOP_BITS_REQUEST, urb_value) < 0)
502     			err("Set stop bits error");
503     	}
504     
505     	/* Set flow control */
506     	if( (iflag&IXOFF)   != (old_iflag&IXOFF)
507     	||	(iflag&IXON)    != (old_iflag&IXON)
508     	||  (cflag&CRTSCTS) != (old_cflag&CRTSCTS) ) {
509     		urb_value = 0;
510     		if ((iflag & IXOFF) || (iflag & IXON))
511     			urb_value |= (BELKIN_SA_FLOW_OXON | BELKIN_SA_FLOW_IXON);
512     		else
513     			urb_value &= ~(BELKIN_SA_FLOW_OXON | BELKIN_SA_FLOW_IXON);
514     
515     		if (cflag & CRTSCTS)
516     			urb_value |=  (BELKIN_SA_FLOW_OCTS | BELKIN_SA_FLOW_IRTS);
517     		else
518     			urb_value &= ~(BELKIN_SA_FLOW_OCTS | BELKIN_SA_FLOW_IRTS);
519     
520     		if (priv->bad_flow_control)
521     			urb_value &= ~(BELKIN_SA_FLOW_IRTS);
522     
523     		if (BSA_USB_CMD(BELKIN_SA_SET_FLOW_CTRL_REQUEST, urb_value) < 0)
524     			err("Set flow control error");
525     	}
526     } /* belkin_sa_set_termios */
527     
528     
529     static void belkin_sa_break_ctl( struct usb_serial_port *port, int break_state )
530     {
531     	struct usb_serial *serial = port->serial;
532     
533     	if (BSA_USB_CMD(BELKIN_SA_SET_BREAK_REQUEST, break_state ? 1 : 0) < 0)
534     		err("Set break_ctl %d", break_state);
535     }
536     
537     
538     static int belkin_sa_ioctl (struct usb_serial_port *port, struct file * file, unsigned int cmd, unsigned long arg)
539     {
540     	struct usb_serial *serial = port->serial;
541     	__u16 urb_value; /* Will hold the new flags */
542     	struct belkin_sa_private *priv = (struct belkin_sa_private *)port->private;
543     	int  ret, mask;
544     	
545     	/* Based on code from acm.c and others */
546     	switch (cmd) {
547     	case TIOCMGET:
548     		return put_user(priv->control_state, (unsigned long *) arg);
549     		break;
550     
551     	case TIOCMSET: /* Turns on and off the lines as specified by the mask */
552     	case TIOCMBIS: /* turns on (Sets) the lines as specified by the mask */
553     	case TIOCMBIC: /* turns off (Clears) the lines as specified by the mask */
554     		if (get_user(mask, (unsigned long *) arg))
555     			return -EFAULT;
556     
557     		if ((cmd == TIOCMSET) || (mask & TIOCM_RTS)) {
558     			/* RTS needs set */
559     			urb_value = ((cmd == TIOCMSET) && (mask & TIOCM_RTS)) || (cmd == TIOCMBIS) ? 1 : 0;
560     			if (urb_value)
561     				priv->control_state |= TIOCM_RTS;
562     			else
563     				priv->control_state &= ~TIOCM_RTS;
564     
565     			if ((ret = BSA_USB_CMD(BELKIN_SA_SET_RTS_REQUEST, urb_value)) < 0) {
566     				err("Set RTS error %d", ret);
567     				return(ret);
568     			}
569     		}
570     
571     		if ((cmd == TIOCMSET) || (mask & TIOCM_DTR)) {
572     			/* DTR needs set */
573     			urb_value = ((cmd == TIOCMSET) && (mask & TIOCM_DTR)) || (cmd == TIOCMBIS) ? 1 : 0;
574     			if (urb_value)
575     				priv->control_state |= TIOCM_DTR;
576     			else
577     				priv->control_state &= ~TIOCM_DTR;
578     			if ((ret = BSA_USB_CMD(BELKIN_SA_SET_DTR_REQUEST, urb_value)) < 0) {
579     				err("Set DTR error %d", ret);
580     				return(ret);
581     			}
582     		}
583     		break;
584     					
585     	case TIOCMIWAIT:
586     		/* wait for any of the 4 modem inputs (DCD,RI,DSR,CTS)*/
587     		/* TODO */
588     		return( 0 );
589     
590     	case TIOCGICOUNT:
591     		/* return count of modemline transitions */
592     		/* TODO */
593     		return 0;
594     
595     	default:
596     		dbg("belkin_sa_ioctl arg not supported - 0x%04x",cmd);
597     		return(-ENOIOCTLCMD);
598     		break;
599     	}
600     	return 0;
601     } /* belkin_sa_ioctl */
602     
603     
604     static int __init belkin_sa_init (void)
605     {
606     	usb_serial_register (&belkin_sa_device);
607     	usb_serial_register (&belkin_old_device);
608     	usb_serial_register (&peracom_device);
609     	usb_serial_register (&gocom232_device);
610     	info(DRIVER_VERSION ":" DRIVER_DESC);
611     	return 0;
612     }
613     
614     
615     static void __exit belkin_sa_exit (void)
616     {
617     	usb_serial_deregister (&belkin_sa_device);
618     	usb_serial_deregister (&belkin_old_device);
619     	usb_serial_deregister (&peracom_device);
620     	usb_serial_deregister (&gocom232_device);
621     }
622     
623     
624     module_init (belkin_sa_init);
625     module_exit (belkin_sa_exit);
626     
627     MODULE_AUTHOR( DRIVER_AUTHOR );
628     MODULE_DESCRIPTION( DRIVER_DESC );
629     MODULE_LICENSE("GPL");
630     
631     MODULE_PARM(debug, "i");
632     MODULE_PARM_DESC(debug, "Debug enabled or not");
633     
634