Merge with 2.4.0-test3-pre4.
[linux-2.6/linux-mips.git] / drivers / usb / serial / visor.c
bloba455e8dc8035ea8d07fa79be757b4c088d9baef0
1 /*
2 * USB HandSpring Visor driver
4 * Copyright (C) 1999, 2000
5 * Greg Kroah-Hartman (greg@kroah.com)
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
12 * See Documentation/usb/usb-serial.txt for more information on using this driver
14 * (07/03/2000) gkh
15 * Added visor_set_ioctl and visor_set_termios functions (they don't do much
16 * of anything, but are good for debugging.)
18 * (06/25/2000) gkh
19 * Fixed bug in visor_unthrottle that should help with the disconnect in PPP
20 * bug that people have been reporting.
22 * (06/23/2000) gkh
23 * Cleaned up debugging statements in a quest to find UHCI timeout bug.
25 * (04/27/2000) Ryan VanderBijl
26 * Fixed memory leak in visor_close
28 * (03/26/2000) gkh
29 * Split driver up into device specific pieces.
33 #include <linux/config.h>
34 #include <linux/kernel.h>
35 #include <linux/sched.h>
36 #include <linux/signal.h>
37 #include <linux/errno.h>
38 #include <linux/poll.h>
39 #include <linux/init.h>
40 #include <linux/malloc.h>
41 #include <linux/fcntl.h>
42 #include <linux/tty_driver.h>
43 #include <linux/tty_flip.h>
44 #include <linux/tty.h>
45 #include <linux/module.h>
46 #include <linux/spinlock.h>
48 #ifdef CONFIG_USB_SERIAL_DEBUG
49 #define DEBUG
50 #else
51 #undef DEBUG
52 #endif
53 #include <linux/usb.h>
55 #include "usb-serial.h"
57 #include "visor.h"
60 /* function prototypes for a handspring visor */
61 static int visor_open (struct usb_serial_port *port, struct file *filp);
62 static void visor_close (struct usb_serial_port *port, struct file *filp);
63 static void visor_throttle (struct usb_serial_port *port);
64 static void visor_unthrottle (struct usb_serial_port *port);
65 static int visor_startup (struct usb_serial *serial);
66 static int visor_ioctl (struct usb_serial_port *port, struct file * file, unsigned int cmd, unsigned long arg);
67 static void visor_set_termios (struct usb_serial_port *port, struct termios *old_termios);
69 /* All of the device info needed for the Handspring Visor */
70 static __u16 handspring_vendor_id = HANDSPRING_VENDOR_ID;
71 static __u16 handspring_product_id = HANDSPRING_VISOR_ID;
72 struct usb_serial_device_type handspring_device = {
73 name: "Handspring Visor",
74 idVendor: &handspring_vendor_id, /* the Handspring vendor ID */
75 idProduct: &handspring_product_id, /* the Handspring Visor product id */
76 needs_interrupt_in: MUST_HAVE_NOT, /* this device must not have an interrupt in endpoint */
77 needs_bulk_in: MUST_HAVE, /* this device must have a bulk in endpoint */
78 needs_bulk_out: MUST_HAVE, /* this device must have a bulk out endpoint */
79 num_interrupt_in: 0,
80 num_bulk_in: 2,
81 num_bulk_out: 2,
82 num_ports: 2,
83 open: visor_open,
84 close: visor_close,
85 throttle: visor_throttle,
86 unthrottle: visor_unthrottle,
87 startup: visor_startup,
88 ioctl: visor_ioctl,
89 set_termios: visor_set_termios,
93 /******************************************************************************
94 * Handspring Visor specific driver functions
95 ******************************************************************************/
96 static int visor_open (struct usb_serial_port *port, struct file *filp)
98 dbg(__FUNCTION__ " - port %d", port->number);
100 if (port->active) {
101 dbg (__FUNCTION__ " - device already open");
102 return -EINVAL;
105 port->active = 1;
107 /*Start reading from the device*/
108 if (usb_submit_urb(port->read_urb))
109 dbg(__FUNCTION__ " - usb_submit_urb(read bulk) failed");
111 return (0);
115 static void visor_close (struct usb_serial_port *port, struct file * filp)
117 struct usb_serial *serial = port->serial;
118 unsigned char *transfer_buffer = kmalloc (0x12, GFP_KERNEL);
120 dbg(__FUNCTION__ " - port %d", port->number);
122 if (!transfer_buffer) {
123 err(__FUNCTION__ " - kmalloc(%d) failed.", 0x12);
124 } else {
125 /* send a shutdown message to the device */
126 usb_control_msg (serial->dev, usb_rcvctrlpipe(serial->dev, 0), VISOR_CLOSE_NOTIFICATION,
127 0xc2, 0x0000, 0x0000, transfer_buffer, 0x12, 300);
128 kfree (transfer_buffer);
131 /* shutdown our bulk reads and writes */
132 usb_unlink_urb (port->write_urb);
133 usb_unlink_urb (port->read_urb);
134 port->active = 0;
138 static void visor_throttle (struct usb_serial_port *port)
140 dbg(__FUNCTION__ " - port %d", port->number);
142 usb_unlink_urb (port->read_urb);
144 return;
148 static void visor_unthrottle (struct usb_serial_port *port)
150 dbg(__FUNCTION__ " - port %d", port->number);
152 if (usb_submit_urb (port->read_urb))
153 dbg(__FUNCTION__ " - usb_submit_urb(read bulk) failed");
155 return;
159 static int visor_startup (struct usb_serial *serial)
161 int response;
162 int i;
163 unsigned char *transfer_buffer = kmalloc (256, GFP_KERNEL);
165 if (!transfer_buffer) {
166 err(__FUNCTION__ " - kmalloc(%d) failed.", 256);
167 return -ENOMEM;
170 dbg(__FUNCTION__);
172 dbg(__FUNCTION__ " - Set config to 1");
173 usb_set_configuration (serial->dev, 1);
175 /* send a get connection info request */
176 response = usb_control_msg (serial->dev, usb_rcvctrlpipe(serial->dev, 0), VISOR_GET_CONNECTION_INFORMATION,
177 0xc2, 0x0000, 0x0000, transfer_buffer, 0x12, 300);
178 if (response < 0) {
179 err(__FUNCTION__ " - error getting connection information");
180 } else {
181 struct visor_connection_info *connection_info = (struct visor_connection_info *)transfer_buffer;
182 char *string;
183 info("%s: Number of ports: %d", serial->type->name, connection_info->num_ports);
184 for (i = 0; i < connection_info->num_ports; ++i) {
185 switch (connection_info->connections[i].port_function_id) {
186 case VISOR_FUNCTION_GENERIC:
187 string = "Generic";
188 break;
189 case VISOR_FUNCTION_DEBUGGER:
190 string = "Debugger";
191 break;
192 case VISOR_FUNCTION_HOTSYNC:
193 string = "HotSync";
194 break;
195 case VISOR_FUNCTION_CONSOLE:
196 string = "Console";
197 break;
198 case VISOR_FUNCTION_REMOTE_FILE_SYS:
199 string = "Remote File System";
200 break;
201 default:
202 string = "unknown";
203 break;
205 info("%s: port %d, is for %s use and is bound to ttyUSB%d", serial->type->name, connection_info->connections[i].port, string, serial->minor + i);
209 /* ask for the number of bytes available, but ignore the response as it is broken */
210 response = usb_control_msg (serial->dev, usb_rcvctrlpipe(serial->dev, 0), VISOR_REQUEST_BYTES_AVAILABLE,
211 0xc2, 0x0000, 0x0005, transfer_buffer, 0x02, 300);
212 if (response < 0) {
213 err(__FUNCTION__ " - error getting bytes available request");
216 kfree (transfer_buffer);
218 /* continue on with initialization */
219 return (0);
223 static int visor_ioctl (struct usb_serial_port *port, struct file * file, unsigned int cmd, unsigned long arg)
225 dbg(__FUNCTION__ " - port %d, cmd 0x%.4x", port->number, cmd);
227 return -ENOIOCTLCMD;
231 /* This function is all nice and good, but we don't change anything based on it :) */
232 static void visor_set_termios (struct usb_serial_port *port, struct termios *old_termios)
234 unsigned int cflag = port->tty->termios->c_cflag;
236 dbg(__FUNCTION__ " - port %d", port->number);
238 /* check that they really want us to change something */
239 if (old_termios) {
240 if ((cflag == old_termios->c_cflag) &&
241 (RELEVANT_IFLAG(port->tty->termios->c_iflag) == RELEVANT_IFLAG(old_termios->c_iflag))) {
242 dbg(__FUNCTION__ " - nothing to change...");
243 return;
247 if ((!port->tty) || (!port->tty->termios)) {
248 dbg(__FUNCTION__" - no tty structures");
249 return;
252 /* get the byte size */
253 switch (cflag & CSIZE) {
254 case CS5: dbg(__FUNCTION__ " - data bits = 5"); break;
255 case CS6: dbg(__FUNCTION__ " - data bits = 6"); break;
256 case CS7: dbg(__FUNCTION__ " - data bits = 7"); break;
257 default:
258 case CS8: dbg(__FUNCTION__ " - data bits = 8"); break;
261 /* determine the parity */
262 if (cflag & PARENB)
263 if (cflag & PARODD)
264 dbg(__FUNCTION__ " - parity = odd");
265 else
266 dbg(__FUNCTION__ " - parity = even");
267 else
268 dbg(__FUNCTION__ " - parity = none");
270 /* figure out the stop bits requested */
271 if (cflag & CSTOPB)
272 dbg(__FUNCTION__ " - stop bits = 2");
273 else
274 dbg(__FUNCTION__ " - stop bits = 1");
277 /* figure out the flow control settings */
278 if (cflag & CRTSCTS)
279 dbg(__FUNCTION__ " - RTS/CTS is enabled");
280 else
281 dbg(__FUNCTION__ " - RTS/CTS is disabled");
283 /* determine software flow control */
284 if (I_IXOFF(port->tty))
285 dbg(__FUNCTION__ " - XON/XOFF is enabled, XON = %2x, XOFF = %2x", START_CHAR(port->tty), STOP_CHAR(port->tty));
286 else
287 dbg(__FUNCTION__ " - XON/XOFF is disabled");
289 /* get the baud rate wanted */
290 dbg(__FUNCTION__ " - baud rate = %d", tty_get_baud_rate(port->tty));
292 return;