diff options
Diffstat (limited to 'drivers/usb/serial/airprime.c')
-rw-r--r-- | drivers/usb/serial/airprime.c | 353 |
1 files changed, 0 insertions, 353 deletions
diff --git a/drivers/usb/serial/airprime.c b/drivers/usb/serial/airprime.c deleted file mode 100644 index 0798c14ce787..000000000000 --- a/drivers/usb/serial/airprime.c +++ /dev/null | |||
@@ -1,353 +0,0 @@ | |||
1 | /* | ||
2 | * AirPrime CDMA Wireless Serial USB driver | ||
3 | * | ||
4 | * Copyright (C) 2005-2006 Greg Kroah-Hartman <gregkh@suse.de> | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or | ||
7 | * modify it under the terms of the GNU General Public License version | ||
8 | * 2 as published by the Free Software Foundation. | ||
9 | */ | ||
10 | |||
11 | #include <linux/kernel.h> | ||
12 | #include <linux/init.h> | ||
13 | #include <linux/tty.h> | ||
14 | #include <linux/tty_flip.h> | ||
15 | #include <linux/module.h> | ||
16 | #include <linux/usb.h> | ||
17 | #include <linux/usb/serial.h> | ||
18 | |||
19 | static struct usb_device_id id_table [] = { | ||
20 | { USB_DEVICE(0x0c88, 0x17da) }, /* Kyocera Wireless KPC650/Passport */ | ||
21 | { }, | ||
22 | }; | ||
23 | MODULE_DEVICE_TABLE(usb, id_table); | ||
24 | |||
25 | #define URB_TRANSFER_BUFFER_SIZE 4096 | ||
26 | #define NUM_READ_URBS 4 | ||
27 | #define NUM_WRITE_URBS 4 | ||
28 | #define NUM_BULK_EPS 3 | ||
29 | #define MAX_BULK_EPS 6 | ||
30 | |||
31 | /* if overridden by the user, then use their value for the size of the | ||
32 | * read and write urbs, and the number of endpoints */ | ||
33 | static int buffer_size = URB_TRANSFER_BUFFER_SIZE; | ||
34 | static int endpoints = NUM_BULK_EPS; | ||
35 | static int debug; | ||
36 | struct airprime_private { | ||
37 | spinlock_t lock; | ||
38 | int outstanding_urbs; | ||
39 | int throttled; | ||
40 | struct urb *read_urbp[NUM_READ_URBS]; | ||
41 | |||
42 | /* Settings for the port */ | ||
43 | int rts_state; /* Handshaking pins (outputs) */ | ||
44 | int dtr_state; | ||
45 | int cts_state; /* Handshaking pins (inputs) */ | ||
46 | int dsr_state; | ||
47 | int dcd_state; | ||
48 | int ri_state; | ||
49 | }; | ||
50 | |||
51 | static int airprime_send_setup(struct usb_serial_port *port) | ||
52 | { | ||
53 | struct usb_serial *serial = port->serial; | ||
54 | struct airprime_private *priv; | ||
55 | |||
56 | dbg("%s", __func__); | ||
57 | |||
58 | if (port->number != 0) | ||
59 | return 0; | ||
60 | |||
61 | priv = usb_get_serial_port_data(port); | ||
62 | |||
63 | if (port->tty) { | ||
64 | int val = 0; | ||
65 | if (priv->dtr_state) | ||
66 | val |= 0x01; | ||
67 | if (priv->rts_state) | ||
68 | val |= 0x02; | ||
69 | |||
70 | return usb_control_msg(serial->dev, | ||
71 | usb_rcvctrlpipe(serial->dev, 0), | ||
72 | 0x22, 0x21, val, 0, NULL, 0, | ||
73 | USB_CTRL_SET_TIMEOUT); | ||
74 | } | ||
75 | |||
76 | return 0; | ||
77 | } | ||
78 | |||
79 | static void airprime_read_bulk_callback(struct urb *urb) | ||
80 | { | ||
81 | struct usb_serial_port *port = urb->context; | ||
82 | unsigned char *data = urb->transfer_buffer; | ||
83 | struct tty_struct *tty; | ||
84 | int result; | ||
85 | int status = urb->status; | ||
86 | |||
87 | dbg("%s - port %d", __func__, port->number); | ||
88 | |||
89 | if (status) { | ||
90 | dbg("%s - nonzero read bulk status received: %d", | ||
91 | __func__, status); | ||
92 | return; | ||
93 | } | ||
94 | usb_serial_debug_data(debug, &port->dev, __func__, | ||
95 | urb->actual_length, data); | ||
96 | |||
97 | tty = port->tty; | ||
98 | if (tty && urb->actual_length) { | ||
99 | tty_insert_flip_string(tty, data, urb->actual_length); | ||
100 | tty_flip_buffer_push(tty); | ||
101 | } | ||
102 | |||
103 | result = usb_submit_urb(urb, GFP_ATOMIC); | ||
104 | if (result) | ||
105 | dev_err(&port->dev, | ||
106 | "%s - failed resubmitting read urb, error %d\n", | ||
107 | __func__, result); | ||
108 | return; | ||
109 | } | ||
110 | |||
111 | static void airprime_write_bulk_callback(struct urb *urb) | ||
112 | { | ||
113 | struct usb_serial_port *port = urb->context; | ||
114 | struct airprime_private *priv = usb_get_serial_port_data(port); | ||
115 | int status = urb->status; | ||
116 | unsigned long flags; | ||
117 | |||
118 | dbg("%s - port %d", __func__, port->number); | ||
119 | |||
120 | /* free up the transfer buffer, as usb_free_urb() does not do this */ | ||
121 | kfree(urb->transfer_buffer); | ||
122 | |||
123 | if (status) | ||
124 | dbg("%s - nonzero write bulk status received: %d", | ||
125 | __func__, status); | ||
126 | spin_lock_irqsave(&priv->lock, flags); | ||
127 | --priv->outstanding_urbs; | ||
128 | spin_unlock_irqrestore(&priv->lock, flags); | ||
129 | |||
130 | usb_serial_port_softint(port); | ||
131 | } | ||
132 | |||
133 | static int airprime_open(struct usb_serial_port *port, struct file *filp) | ||
134 | { | ||
135 | struct airprime_private *priv = usb_get_serial_port_data(port); | ||
136 | struct usb_serial *serial = port->serial; | ||
137 | struct urb *urb; | ||
138 | char *buffer = NULL; | ||
139 | int i; | ||
140 | int result = 0; | ||
141 | |||
142 | dbg("%s - port %d", __func__, port->number); | ||
143 | |||
144 | /* initialize our private data structure if it isn't already created */ | ||
145 | if (!priv) { | ||
146 | priv = kzalloc(sizeof(*priv), GFP_KERNEL); | ||
147 | if (!priv) { | ||
148 | result = -ENOMEM; | ||
149 | goto out; | ||
150 | } | ||
151 | spin_lock_init(&priv->lock); | ||
152 | usb_set_serial_port_data(port, priv); | ||
153 | } | ||
154 | |||
155 | /* Set some sane defaults */ | ||
156 | priv->rts_state = 1; | ||
157 | priv->dtr_state = 1; | ||
158 | |||
159 | for (i = 0; i < NUM_READ_URBS; ++i) { | ||
160 | buffer = kmalloc(buffer_size, GFP_KERNEL); | ||
161 | if (!buffer) { | ||
162 | dev_err(&port->dev, "%s - out of memory.\n", | ||
163 | __func__); | ||
164 | result = -ENOMEM; | ||
165 | goto errout; | ||
166 | } | ||
167 | urb = usb_alloc_urb(0, GFP_KERNEL); | ||
168 | if (!urb) { | ||
169 | kfree(buffer); | ||
170 | dev_err(&port->dev, "%s - no more urbs?\n", | ||
171 | __func__); | ||
172 | result = -ENOMEM; | ||
173 | goto errout; | ||
174 | } | ||
175 | usb_fill_bulk_urb(urb, serial->dev, | ||
176 | usb_rcvbulkpipe(serial->dev, | ||
177 | port->bulk_out_endpointAddress), | ||
178 | buffer, buffer_size, | ||
179 | airprime_read_bulk_callback, port); | ||
180 | result = usb_submit_urb(urb, GFP_KERNEL); | ||
181 | if (result) { | ||
182 | usb_free_urb(urb); | ||
183 | kfree(buffer); | ||
184 | dev_err(&port->dev, | ||
185 | "%s - failed submitting read urb %d for port %d, error %d\n", | ||
186 | __func__, i, port->number, result); | ||
187 | goto errout; | ||
188 | } | ||
189 | /* remember this urb so we can kill it when the | ||
190 | port is closed */ | ||
191 | priv->read_urbp[i] = urb; | ||
192 | } | ||
193 | |||
194 | airprime_send_setup(port); | ||
195 | |||
196 | goto out; | ||
197 | |||
198 | errout: | ||
199 | /* some error happened, cancel any submitted urbs and clean up | ||
200 | anything that got allocated successfully */ | ||
201 | |||
202 | while (i-- != 0) { | ||
203 | urb = priv->read_urbp[i]; | ||
204 | buffer = urb->transfer_buffer; | ||
205 | usb_kill_urb(urb); | ||
206 | usb_free_urb(urb); | ||
207 | kfree(buffer); | ||
208 | } | ||
209 | |||
210 | out: | ||
211 | return result; | ||
212 | } | ||
213 | |||
214 | static void airprime_close(struct usb_serial_port *port, struct file *filp) | ||
215 | { | ||
216 | struct airprime_private *priv = usb_get_serial_port_data(port); | ||
217 | int i; | ||
218 | |||
219 | dbg("%s - port %d", __func__, port->number); | ||
220 | |||
221 | priv->rts_state = 0; | ||
222 | priv->dtr_state = 0; | ||
223 | |||
224 | mutex_lock(&port->serial->disc_mutex); | ||
225 | if (!port->serial->disconnected) | ||
226 | airprime_send_setup(port); | ||
227 | mutex_unlock(&port->serial->disc_mutex); | ||
228 | |||
229 | for (i = 0; i < NUM_READ_URBS; ++i) { | ||
230 | usb_kill_urb(priv->read_urbp[i]); | ||
231 | kfree(priv->read_urbp[i]->transfer_buffer); | ||
232 | usb_free_urb(priv->read_urbp[i]); | ||
233 | } | ||
234 | |||
235 | /* free up private structure */ | ||
236 | kfree(priv); | ||
237 | usb_set_serial_port_data(port, NULL); | ||
238 | } | ||
239 | |||
240 | static int airprime_write(struct usb_serial_port *port, | ||
241 | const unsigned char *buf, int count) | ||
242 | { | ||
243 | struct airprime_private *priv = usb_get_serial_port_data(port); | ||
244 | struct usb_serial *serial = port->serial; | ||
245 | struct urb *urb; | ||
246 | unsigned char *buffer; | ||
247 | unsigned long flags; | ||
248 | int status; | ||
249 | dbg("%s - port %d", __func__, port->number); | ||
250 | |||
251 | spin_lock_irqsave(&priv->lock, flags); | ||
252 | if (priv->outstanding_urbs > NUM_WRITE_URBS) { | ||
253 | spin_unlock_irqrestore(&priv->lock, flags); | ||
254 | dbg("%s - write limit hit\n", __func__); | ||
255 | return 0; | ||
256 | } | ||
257 | spin_unlock_irqrestore(&priv->lock, flags); | ||
258 | buffer = kmalloc(count, GFP_ATOMIC); | ||
259 | if (!buffer) { | ||
260 | dev_err(&port->dev, "out of memory\n"); | ||
261 | return -ENOMEM; | ||
262 | } | ||
263 | urb = usb_alloc_urb(0, GFP_ATOMIC); | ||
264 | if (!urb) { | ||
265 | dev_err(&port->dev, "no more free urbs\n"); | ||
266 | kfree(buffer); | ||
267 | return -ENOMEM; | ||
268 | } | ||
269 | memcpy(buffer, buf, count); | ||
270 | |||
271 | usb_serial_debug_data(debug, &port->dev, __func__, count, buffer); | ||
272 | |||
273 | usb_fill_bulk_urb(urb, serial->dev, | ||
274 | usb_sndbulkpipe(serial->dev, | ||
275 | port->bulk_out_endpointAddress), | ||
276 | buffer, count, | ||
277 | airprime_write_bulk_callback, port); | ||
278 | |||
279 | /* send it down the pipe */ | ||
280 | status = usb_submit_urb(urb, GFP_ATOMIC); | ||
281 | if (status) { | ||
282 | dev_err(&port->dev, | ||
283 | "%s - usb_submit_urb(write bulk) failed with status = %d\n", | ||
284 | __func__, status); | ||
285 | count = status; | ||
286 | kfree(buffer); | ||
287 | } else { | ||
288 | spin_lock_irqsave(&priv->lock, flags); | ||
289 | ++priv->outstanding_urbs; | ||
290 | spin_unlock_irqrestore(&priv->lock, flags); | ||
291 | } | ||
292 | /* we are done with this urb, so let the host driver | ||
293 | * really free it when it is finished with it */ | ||
294 | usb_free_urb(urb); | ||
295 | return count; | ||
296 | } | ||
297 | |||
298 | static struct usb_driver airprime_driver = { | ||
299 | .name = "airprime", | ||
300 | .probe = usb_serial_probe, | ||
301 | .disconnect = usb_serial_disconnect, | ||
302 | .id_table = id_table, | ||
303 | .no_dynamic_id = 1, | ||
304 | }; | ||
305 | |||
306 | static struct usb_serial_driver airprime_device = { | ||
307 | .driver = { | ||
308 | .owner = THIS_MODULE, | ||
309 | .name = "airprime", | ||
310 | }, | ||
311 | .usb_driver = &airprime_driver, | ||
312 | .id_table = id_table, | ||
313 | .open = airprime_open, | ||
314 | .close = airprime_close, | ||
315 | .write = airprime_write, | ||
316 | }; | ||
317 | |||
318 | static int __init airprime_init(void) | ||
319 | { | ||
320 | int retval; | ||
321 | |||
322 | airprime_device.num_ports = endpoints; | ||
323 | if (endpoints < 0 || endpoints >= MAX_BULK_EPS) | ||
324 | airprime_device.num_ports = NUM_BULK_EPS; | ||
325 | |||
326 | retval = usb_serial_register(&airprime_device); | ||
327 | if (retval) | ||
328 | return retval; | ||
329 | retval = usb_register(&airprime_driver); | ||
330 | if (retval) | ||
331 | usb_serial_deregister(&airprime_device); | ||
332 | return retval; | ||
333 | } | ||
334 | |||
335 | static void __exit airprime_exit(void) | ||
336 | { | ||
337 | dbg("%s", __func__); | ||
338 | |||
339 | usb_deregister(&airprime_driver); | ||
340 | usb_serial_deregister(&airprime_device); | ||
341 | } | ||
342 | |||
343 | module_init(airprime_init); | ||
344 | module_exit(airprime_exit); | ||
345 | MODULE_LICENSE("GPL"); | ||
346 | |||
347 | module_param(debug, bool, S_IRUGO | S_IWUSR); | ||
348 | MODULE_PARM_DESC(debug, "Debug enabled"); | ||
349 | module_param(buffer_size, int, 0); | ||
350 | MODULE_PARM_DESC(buffer_size, | ||
351 | "Size of the transfer buffers in bytes (default 4096)"); | ||
352 | module_param(endpoints, int, 0); | ||
353 | MODULE_PARM_DESC(endpoints, "Number of bulk EPs to configure (default 3)"); | ||