aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb
diff options
context:
space:
mode:
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>2012-09-24 15:42:19 -0400
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2012-09-24 15:42:19 -0400
commit64f0d8cd089ee7e501116181a343c3739df5fe53 (patch)
tree96d6c7741048ad32034bbd139a6f2b9b3c2433b2 /drivers/usb
parentf3f4bf5cf0896e58e9831ea53bcb8c7d88127d20 (diff)
USB: serial: remove vizzini driver
It's out-dated for the tty-layer stuff, and would require a bunch of work. That's not really a big deal, the big issue is that there is no company contact for the hardware, so questions we have about it (like why isn't this just handled by the cdc-acm driver instead?) go unanswered. So drop the driver. If someone comes along to help answer the questions, we can easily revert this and fix up the code. Cc: Alan Cox <alan@lxorguk.ukuu.org.uk> Cc: Rob Duncan <rob.duncan@exar.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers/usb')
-rw-r--r--drivers/usb/serial/Kconfig8
-rw-r--r--drivers/usb/serial/Makefile1
-rw-r--r--drivers/usb/serial/vizzini.c1354
3 files changed, 0 insertions, 1363 deletions
diff --git a/drivers/usb/serial/Kconfig b/drivers/usb/serial/Kconfig
index a5c144694005..f604f707a058 100644
--- a/drivers/usb/serial/Kconfig
+++ b/drivers/usb/serial/Kconfig
@@ -182,14 +182,6 @@ config USB_SERIAL_VISOR
182 To compile this driver as a module, choose M here: the 182 To compile this driver as a module, choose M here: the
183 module will be called visor. 183 module will be called visor.
184 184
185config USB_SERIAL_VIZZINI
186 tristate "USB Vizzini Serial Converter Driver"
187 help
188 Say Y here if you have a Vizzini USB to serial device.
189
190 To compile this driver as a module, choose M here: the
191 module will be called vizzini.
192
193config USB_SERIAL_IPAQ 185config USB_SERIAL_IPAQ
194 tristate "USB PocketPC PDA Driver" 186 tristate "USB PocketPC PDA Driver"
195 help 187 help
diff --git a/drivers/usb/serial/Makefile b/drivers/usb/serial/Makefile
index 5fd21a01b009..45871f9ad1e1 100644
--- a/drivers/usb/serial/Makefile
+++ b/drivers/usb/serial/Makefile
@@ -59,7 +59,6 @@ obj-$(CONFIG_USB_SERIAL_SYMBOL) += symbolserial.o
59obj-$(CONFIG_USB_SERIAL_WWAN) += usb_wwan.o 59obj-$(CONFIG_USB_SERIAL_WWAN) += usb_wwan.o
60obj-$(CONFIG_USB_SERIAL_TI) += ti_usb_3410_5052.o 60obj-$(CONFIG_USB_SERIAL_TI) += ti_usb_3410_5052.o
61obj-$(CONFIG_USB_SERIAL_VISOR) += visor.o 61obj-$(CONFIG_USB_SERIAL_VISOR) += visor.o
62obj-$(CONFIG_USB_SERIAL_VIZZINI) += vizzini.o
63obj-$(CONFIG_USB_SERIAL_WHITEHEAT) += whiteheat.o 62obj-$(CONFIG_USB_SERIAL_WHITEHEAT) += whiteheat.o
64obj-$(CONFIG_USB_SERIAL_XIRCOM) += keyspan_pda.o 63obj-$(CONFIG_USB_SERIAL_XIRCOM) += keyspan_pda.o
65obj-$(CONFIG_USB_SERIAL_VIVOPAY_SERIAL) += vivopay-serial.o 64obj-$(CONFIG_USB_SERIAL_VIVOPAY_SERIAL) += vivopay-serial.o
diff --git a/drivers/usb/serial/vizzini.c b/drivers/usb/serial/vizzini.c
deleted file mode 100644
index 7f436949dd99..000000000000
--- a/drivers/usb/serial/vizzini.c
+++ /dev/null
@@ -1,1354 +0,0 @@
1/*
2 * vizzini.c
3 *
4 * Copyright (c) 2011 Exar Corporation, Inc.
5 *
6 * ChangeLog:
7 * v0.76- Support for 3.0.0 (Ubuntu 11.10) (Removed all Kernel source
8 * compiler conditions and now the base is Kernel 3.0. Ravi Reddy)
9 * v0.75- Support for 2.6.38.8 (Ubuntu 11.04) - Added
10 * .usb_driver = &vizzini_driver.
11 * v0.74- Support for 2.6.35.22 (Ubuntu 10.10) - Added
12 * #include <linux/slab.h> to fix kmalloc/kfree error.
13 * v0.73- Fixed VZIOC_SET_REG (by Ravi Reddy).
14 * v0.72- Support for 2.6.32.21 (by Ravi Reddy, for Ubuntu 10.04).
15 * v0.71- Support for 2.6.31.
16 * v0.5 - Tentative support for compiling with the CentOS 5.1
17 * kernel (2.6.18-53).
18 * v0.4 - First version. Lots of stuff lifted from
19 * cdc-acm.c (credits due to Armin Fuerst, Pavel Machek,
20 * Johannes Erdfelt, Vojtech Pavlik, David Kubicek) and
21 * and sierra.c (credit due to Kevin Lloyd).
22 */
23
24/*
25 * This program is free software; you can redistribute it and/or modify
26 * it under the terms of the GNU General Public License as published by
27 * the Free Software Foundation; either version 2 of the License, or
28 * (at your option) any later version.
29 *
30 * This program is distributed in the hope that it will be useful,
31 * but WITHOUT ANY WARRANTY; without even the implied warranty of
32 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
33 * GNU General Public License for more details.
34 *
35 * You should have received a copy of the GNU General Public License
36 * along with this program; if not, write to the Free Software
37 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
38 */
39
40#define DRIVER_VERSION "v.0.76"
41#define DRIVER_AUTHOR "Rob Duncan <rob.duncan@exar.com>"
42#define DRIVER_DESC "USB Driver for Vizzini USB serial port"
43
44#undef VIZZINI_IWA
45
46
47#include <linux/kernel.h>
48#include <linux/jiffies.h>
49#include <linux/errno.h>
50#include <linux/tty.h>
51#include <linux/tty_flip.h>
52#include <linux/module.h>
53#include <linux/usb.h>
54#include <linux/usb/serial.h>
55#include <linux/serial.h>
56#include <linux/slab.h>
57#include <linux/uaccess.h>
58#include <asm/unaligned.h>
59
60#include <linux/usb/cdc.h>
61#ifndef CDC_DATA_INTERFACE_TYPE
62#define CDC_DATA_INTERFACE_TYPE 0x0a
63#endif
64#ifndef USB_RT_ACM
65#define USB_RT_ACM (USB_TYPE_CLASS | USB_RECIP_INTERFACE)
66#define ACM_CTRL_DTR 0x01
67#define ACM_CTRL_RTS 0x02
68#define ACM_CTRL_DCD 0x01
69#define ACM_CTRL_DSR 0x02
70#define ACM_CTRL_BRK 0x04
71#define ACM_CTRL_RI 0x08
72#define ACM_CTRL_FRAMING 0x10
73#define ACM_CTRL_PARITY 0x20
74#define ACM_CTRL_OVERRUN 0x40
75#endif
76
77#define XR_SET_REG 0
78#define XR_GETN_REG 1
79
80#define UART_0_REG_BLOCK 0
81#define UART_1_REG_BLOCK 1
82#define UART_2_REG_BLOCK 2
83#define UART_3_REG_BLOCK 3
84#define URM_REG_BLOCK 4
85#define PRM_REG_BLOCK 5
86#define EPMERR_REG_BLOCK 6
87#define RAMCTL_REG_BLOCK 0x64
88#define TWI_ROM_REG_BLOCK 0x65
89#define EPLOCALS_REG_BLOCK 0x66
90
91#define MEM_SHADOW_REG_SIZE_S 5
92#define MEM_SHADOW_REG_SIZE (1 << MEM_SHADOW_REG_SIZE_S)
93
94#define MEM_EP_LOCALS_SIZE_S 3
95#define MEM_EP_LOCALS_SIZE (1 << MEM_EP_LOCALS_SIZE_S)
96
97#define EP_WIDE_MODE 0x03
98
99
100#define UART_GPIO_MODE 0x01a
101
102#define UART_GPIO_MODE_SEL_M 0x7
103#define UART_GPIO_MODE_SEL_S 0
104#define UART_GPIO_MODE_SEL 0x007
105
106#define UART_GPIO_MODE_SEL_GPIO (0x0 << UART_GPIO_MODE_SEL_S)
107#define UART_GPIO_MODE_SEL_RTS_CTS (0x1 << UART_GPIO_MODE_SEL_S)
108#define UART_GPIO_MODE_SEL_DTR_DSR (0x2 << UART_GPIO_MODE_SEL_S)
109#define UART_GPIO_MODE_SEL_XCVR_EN_ACT (0x3 << UART_GPIO_MODE_SEL_S)
110#define UART_GPIO_MODE_SEL_XCVR_EN_FLOW (0x4 << UART_GPIO_MODE_SEL_S)
111
112#define UART_GPIO_MODE_XCVR_EN_POL_M 0x1
113#define UART_GPIO_MODE_XCVR_EN_POL_S 3
114#define UART_GPIO_MODE_XCVR_EN_POL 0x008
115
116#define UART_ENABLE 0x003
117#define UART_ENABLE_TX_M 0x1
118#define UART_ENABLE_TX_S 0
119#define UART_ENABLE_TX 0x001
120#define UART_ENABLE_RX_M 0x1
121#define UART_ENABLE_RX_S 1
122#define UART_ENABLE_RX 0x002
123
124#define UART_CLOCK_DIVISOR_0 0x004
125#define UART_CLOCK_DIVISOR_1 0x005
126#define UART_CLOCK_DIVISOR_2 0x006
127
128#define UART_CLOCK_DIVISOR_2_MSB_M 0x7
129#define UART_CLOCK_DIVISOR_2_MSB_S 0
130#define UART_CLOCK_DIVISOR_2_MSB 0x007
131#define UART_CLOCK_DIVISOR_2_DIAGMODE_M 0x1
132#define UART_CLOCK_DIVISOR_2_DIAGMODE_S 3
133#define UART_CLOCK_DIVISOR_2_DIAGMODE 0x008
134
135#define UART_TX_CLOCK_MASK_0 0x007
136#define UART_TX_CLOCK_MASK_1 0x008
137
138#define UART_RX_CLOCK_MASK_0 0x009
139#define UART_RX_CLOCK_MASK_1 0x00a
140
141#define UART_FORMAT 0x00b
142
143#define UART_FORMAT_SIZE_M 0xf
144#define UART_FORMAT_SIZE_S 0
145#define UART_FORMAT_SIZE 0x00f
146
147#define UART_FORMAT_SIZE_7 (0x7 << UART_FORMAT_SIZE_S)
148#define UART_FORMAT_SIZE_8 (0x8 << UART_FORMAT_SIZE_S)
149#define UART_FORMAT_SIZE_9 (0x9 << UART_FORMAT_SIZE_S)
150
151#define UART_FORMAT_PARITY_M 0x7
152#define UART_FORMAT_PARITY_S 4
153#define UART_FORMAT_PARITY 0x070
154
155#define UART_FORMAT_PARITY_NONE (0x0 << UART_FORMAT_PARITY_S)
156#define UART_FORMAT_PARITY_ODD (0x1 << UART_FORMAT_PARITY_S)
157#define UART_FORMAT_PARITY_EVEN (0x2 << UART_FORMAT_PARITY_S)
158#define UART_FORMAT_PARITY_1 (0x3 << UART_FORMAT_PARITY_S)
159#define UART_FORMAT_PARITY_0 (0x4 << UART_FORMAT_PARITY_S)
160
161#define UART_FORMAT_STOP_M 0x1
162#define UART_FORMAT_STOP_S 7
163#define UART_FORMAT_STOP 0x080
164
165#define UART_FORMAT_STOP_1 (0x0 << UART_FORMAT_STOP_S)
166#define UART_FORMAT_STOP_2 (0x1 << UART_FORMAT_STOP_S)
167
168#define UART_FORMAT_MODE_7N1 0
169#define UART_FORMAT_MODE_RES1 1
170#define UART_FORMAT_MODE_RES2 2
171#define UART_FORMAT_MODE_RES3 3
172#define UART_FORMAT_MODE_7N2 4
173#define UART_FORMAT_MODE_7P1 5
174#define UART_FORMAT_MODE_8N1 6
175#define UART_FORMAT_MODE_RES7 7
176#define UART_FORMAT_MODE_7P2 8
177#define UART_FORMAT_MODE_8N2 9
178#define UART_FORMAT_MODE_8P1 10
179#define UART_FORMAT_MODE_9N1 11
180#define UART_FORMAT_MODE_8P2 12
181#define UART_FORMAT_MODE_RESD 13
182#define UART_FORMAT_MODE_RESE 14
183#define UART_FORMAT_MODE_9N2 15
184
185#define UART_FLOW 0x00c
186
187#define UART_FLOW_MODE_M 0x7
188#define UART_FLOW_MODE_S 0
189#define UART_FLOW_MODE 0x007
190
191#define UART_FLOW_MODE_NONE (0x0 << UART_FLOW_MODE_S)
192#define UART_FLOW_MODE_HW (0x1 << UART_FLOW_MODE_S)
193#define UART_FLOW_MODE_SW (0x2 << UART_FLOW_MODE_S)
194#define UART_FLOW_MODE_ADDR_MATCH (0x3 << UART_FLOW_MODE_S)
195#define UART_FLOW_MODE_ADDR_MATCH_TX (0x4 << UART_FLOW_MODE_S)
196
197#define UART_FLOW_HALF_DUPLEX_M 0x1
198#define UART_FLOW_HALF_DUPLEX_S 3
199#define UART_FLOW_HALF_DUPLEX 0x008
200
201#define UART_LOOPBACK_CTL 0x012
202#define UART_LOOPBACK_CTL_ENABLE_M 0x1
203#define UART_LOOPBACK_CTL_ENABLE_S 2
204#define UART_LOOPBACK_CTL_ENABLE 0x004
205#define UART_LOOPBACK_CTL_RX_SOURCE_M 0x3
206#define UART_LOOPBACK_CTL_RX_SOURCE_S 0
207#define UART_LOOPBACK_CTL_RX_SOURCE 0x003
208#define UART_LOOPBACK_CTL_RX_UART0 (0x0 << UART_LOOPBACK_CTL_RX_SOURCE_S)
209#define UART_LOOPBACK_CTL_RX_UART1 (0x1 << UART_LOOPBACK_CTL_RX_SOURCE_S)
210#define UART_LOOPBACK_CTL_RX_UART2 (0x2 << UART_LOOPBACK_CTL_RX_SOURCE_S)
211#define UART_LOOPBACK_CTL_RX_UART3 (0x3 << UART_LOOPBACK_CTL_RX_SOURCE_S)
212
213#define UART_CHANNEL_NUM 0x00d
214
215#define UART_XON_CHAR 0x010
216#define UART_XOFF_CHAR 0x011
217
218#define UART_GPIO_SET 0x01d
219#define UART_GPIO_CLR 0x01e
220#define UART_GPIO_STATUS 0x01f
221
222#define URM_ENABLE_BASE 0x010
223#define URM_ENABLE_0 0x010
224#define URM_ENABLE_0_TX_M 0x1
225#define URM_ENABLE_0_TX_S 0
226#define URM_ENABLE_0_TX 0x001
227#define URM_ENABLE_0_RX_M 0x1
228#define URM_ENABLE_0_RX_S 1
229#define URM_ENABLE_0_RX 0x002
230
231#define URM_RX_FIFO_RESET_0 0x018
232#define URM_RX_FIFO_RESET_1 0x019
233#define URM_RX_FIFO_RESET_2 0x01a
234#define URM_RX_FIFO_RESET_3 0x01b
235#define URM_TX_FIFO_RESET_0 0x01c
236#define URM_TX_FIFO_RESET_1 0x01d
237#define URM_TX_FIFO_RESET_2 0x01e
238#define URM_TX_FIFO_RESET_3 0x01f
239
240
241#define RAMCTL_REGS_TXFIFO_0_LEVEL 0x000
242#define RAMCTL_REGS_TXFIFO_1_LEVEL 0x001
243#define RAMCTL_REGS_TXFIFO_2_LEVEL 0x002
244#define RAMCTL_REGS_TXFIFO_3_LEVEL 0x003
245#define RAMCTL_REGS_RXFIFO_0_LEVEL 0x004
246
247#define RAMCTL_REGS_RXFIFO_0_LEVEL_LEVEL_M 0x7ff
248#define RAMCTL_REGS_RXFIFO_0_LEVEL_LEVEL_S 0
249#define RAMCTL_REGS_RXFIFO_0_LEVEL_LEVEL 0x7ff
250#define RAMCTL_REGS_RXFIFO_0_LEVEL_STALE_M 0x1
251#define RAMCTL_REGS_RXFIFO_0_LEVEL_STALE_S 11
252#define RAMCTL_REGS_RXFIFO_0_LEVEL_STALE 0x800
253
254#define RAMCTL_REGS_RXFIFO_1_LEVEL 0x005
255#define RAMCTL_REGS_RXFIFO_2_LEVEL 0x006
256#define RAMCTL_REGS_RXFIFO_3_LEVEL 0x007
257
258#define RAMCTL_BUFFER_PARITY 0x1
259#define RAMCTL_BUFFER_BREAK 0x2
260#define RAMCTL_BUFFER_FRAME 0x4
261#define RAMCTL_BUFFER_OVERRUN 0x8
262
263#define N_IN_URB 4
264#define N_OUT_URB 4
265#define IN_BUFLEN 4096
266
267static struct usb_device_id id_table[] = {
268 { USB_DEVICE(0x04e2, 0x1410) },
269 { USB_DEVICE(0x04e2, 0x1412) },
270 { USB_DEVICE(0x04e2, 0x1414) },
271 { }
272};
273MODULE_DEVICE_TABLE(usb, id_table);
274
275struct vizzini_serial_private {
276 struct usb_interface *data_interface;
277};
278
279struct vizzini_port_private {
280 spinlock_t lock;
281 int outstanding_urbs;
282
283 struct urb *in_urbs[N_IN_URB];
284 char *in_buffer[N_IN_URB];
285
286 int ctrlin;
287 int ctrlout;
288 int clocal;
289
290 int block;
291 int preciseflags; /* USB: wide mode, TTY: flags per character */
292 int trans9; /* USB: wide mode, serial 9N1 */
293 unsigned int baud_base; /* setserial: used to hack in non-standard baud rates */
294 int have_extra_byte;
295 int extra_byte;
296
297 int bcd_device;
298
299#ifdef VIZZINI_IWA
300 int iwa;
301#endif
302};
303
304
305static int vizzini_rev_a(struct usb_serial_port *port)
306{
307 struct vizzini_port_private *portdata = usb_get_serial_port_data(port);
308 return portdata->bcd_device == 0;
309}
310
311static int acm_ctrl_msg(struct usb_serial_port *port, int request,
312 int value, void *buf, int len)
313{
314 struct usb_serial *serial = port->serial;
315 int retval = usb_control_msg(serial->dev,
316 usb_sndctrlpipe(serial->dev, 0),
317 request,
318 USB_RT_ACM,
319 value,
320 serial->interface->cur_altsetting->desc.bInterfaceNumber,
321 buf,
322 len,
323 5000);
324 dev_dbg(&port->dev, "acm_control_msg: rq: 0x%02x val: %#x len: %#x result: %d\n", request, value, len, retval);
325 return retval < 0 ? retval : 0;
326}
327
328#define acm_set_control(port, control) \
329 acm_ctrl_msg(port, USB_CDC_REQ_SET_CONTROL_LINE_STATE, control, NULL, 0)
330#define acm_set_line(port, line) \
331 acm_ctrl_msg(port, USB_CDC_REQ_SET_LINE_CODING, 0, line, sizeof *(line))
332#define acm_send_break(port, ms) \
333 acm_ctrl_msg(port, USB_CDC_REQ_SEND_BREAK, ms, NULL, 0)
334
335static int vizzini_set_reg(struct usb_serial_port *port, int block, int regnum, int value)
336{
337 struct usb_serial *serial = port->serial;
338 int result;
339
340 result = usb_control_msg(serial->dev, /* usb device */
341 usb_sndctrlpipe(serial->dev, 0), /* endpoint pipe */
342 XR_SET_REG, /* request */
343 USB_DIR_OUT | USB_TYPE_VENDOR, /* request_type */
344 value, /* request value */
345 regnum | (block << 8), /* index */
346 NULL, /* data */
347 0, /* size */
348 5000); /* timeout */
349
350 return result;
351}
352
353static void vizzini_disable(struct usb_serial_port *port)
354{
355 struct vizzini_port_private *portdata = usb_get_serial_port_data(port);
356 int block = portdata->block;
357
358 vizzini_set_reg(port, block, UART_ENABLE, 0);
359 vizzini_set_reg(port, URM_REG_BLOCK, URM_ENABLE_BASE + block, 0);
360}
361
362static void vizzini_enable(struct usb_serial_port *port)
363{
364 struct vizzini_port_private *portdata = usb_get_serial_port_data(port);
365 int block = portdata->block;
366
367 vizzini_set_reg(port, URM_REG_BLOCK, URM_ENABLE_BASE + block, URM_ENABLE_0_TX);
368 vizzini_set_reg(port, block, UART_ENABLE, UART_ENABLE_TX | UART_ENABLE_RX);
369 vizzini_set_reg(port, URM_REG_BLOCK, URM_ENABLE_BASE + block, URM_ENABLE_0_TX | URM_ENABLE_0_RX);
370}
371
372struct vizzini_baud_rate {
373 unsigned int tx;
374 unsigned int rx0;
375 unsigned int rx1;
376};
377
378static struct vizzini_baud_rate vizzini_baud_rates[] = {
379 { 0x000, 0x000, 0x000 },
380 { 0x000, 0x000, 0x000 },
381 { 0x100, 0x000, 0x100 },
382 { 0x020, 0x400, 0x020 },
383 { 0x010, 0x100, 0x010 },
384 { 0x208, 0x040, 0x208 },
385 { 0x104, 0x820, 0x108 },
386 { 0x844, 0x210, 0x884 },
387 { 0x444, 0x110, 0x444 },
388 { 0x122, 0x888, 0x224 },
389 { 0x912, 0x448, 0x924 },
390 { 0x492, 0x248, 0x492 },
391 { 0x252, 0x928, 0x292 },
392 { 0X94A, 0X4A4, 0XA52 },
393 { 0X52A, 0XAA4, 0X54A },
394 { 0XAAA, 0x954, 0X4AA },
395 { 0XAAA, 0x554, 0XAAA },
396 { 0x555, 0XAD4, 0X5AA },
397 { 0XB55, 0XAB4, 0X55A },
398 { 0X6B5, 0X5AC, 0XB56 },
399 { 0X5B5, 0XD6C, 0X6D6 },
400 { 0XB6D, 0XB6A, 0XDB6 },
401 { 0X76D, 0X6DA, 0XBB6 },
402 { 0XEDD, 0XDDA, 0X76E },
403 { 0XDDD, 0XBBA, 0XEEE },
404 { 0X7BB, 0XF7A, 0XDDE },
405 { 0XF7B, 0XEF6, 0X7DE },
406 { 0XDF7, 0XBF6, 0XF7E },
407 { 0X7F7, 0XFEE, 0XEFE },
408 { 0XFDF, 0XFBE, 0X7FE },
409 { 0XF7F, 0XEFE, 0XFFE },
410 { 0XFFF, 0XFFE, 0XFFD },
411};
412
413static int vizzini_set_baud_rate(struct usb_serial_port *port, unsigned int rate)
414{
415 struct vizzini_port_private *portdata = usb_get_serial_port_data(port);
416 int block = portdata->block;
417 unsigned int divisor = 48000000 / rate;
418 unsigned int i = ((32 * 48000000) / rate) & 0x1f;
419 unsigned int tx_mask = vizzini_baud_rates[i].tx;
420 unsigned int rx_mask = (divisor & 1) ? vizzini_baud_rates[i].rx1 : vizzini_baud_rates[i].rx0;
421
422 dev_dbg(&port->dev, "Setting baud rate to %d: i=%u div=%u tx=%03x rx=%03x\n", rate, i, divisor, tx_mask, rx_mask);
423
424 vizzini_set_reg(port, block, UART_CLOCK_DIVISOR_0, (divisor >> 0) & 0xff);
425 vizzini_set_reg(port, block, UART_CLOCK_DIVISOR_1, (divisor >> 8) & 0xff);
426 vizzini_set_reg(port, block, UART_CLOCK_DIVISOR_2, (divisor >> 16) & 0xff);
427 vizzini_set_reg(port, block, UART_TX_CLOCK_MASK_0, (tx_mask >> 0) & 0xff);
428 vizzini_set_reg(port, block, UART_TX_CLOCK_MASK_1, (tx_mask >> 8) & 0xff);
429 vizzini_set_reg(port, block, UART_RX_CLOCK_MASK_0, (rx_mask >> 0) & 0xff);
430 vizzini_set_reg(port, block, UART_RX_CLOCK_MASK_1, (rx_mask >> 8) & 0xff);
431
432 return -EINVAL;
433}
434
435static void vizzini_set_termios(struct tty_struct *tty_param,
436 struct usb_serial_port *port,
437 struct ktermios *old_termios)
438{
439 struct vizzini_port_private *portdata = usb_get_serial_port_data(port);
440 unsigned int cflag, block;
441 speed_t rate;
442 unsigned int format_size, format_parity, format_stop, flow, gpio_mode;
443 struct tty_struct *tty = port->port.tty;
444
445 cflag = tty->termios->c_cflag;
446
447 portdata->clocal = ((cflag & CLOCAL) != 0);
448
449 block = portdata->block;
450
451 vizzini_disable(port);
452
453 if ((cflag & CSIZE) == CS7) {
454 format_size = UART_FORMAT_SIZE_7;
455 } else if ((cflag & CSIZE) == CS5) {
456 /* Enabling 5-bit mode is really 9-bit mode! */
457 format_size = UART_FORMAT_SIZE_9;
458 } else {
459 format_size = UART_FORMAT_SIZE_8;
460 }
461 portdata->trans9 = (format_size == UART_FORMAT_SIZE_9);
462
463 if (cflag & PARENB) {
464 if (cflag & PARODD) {
465 if (cflag & CMSPAR)
466 format_parity = UART_FORMAT_PARITY_1;
467 else
468 format_parity = UART_FORMAT_PARITY_ODD;
469 } else {
470 if (cflag & CMSPAR)
471 format_parity = UART_FORMAT_PARITY_0;
472 else
473 format_parity = UART_FORMAT_PARITY_EVEN;
474 }
475 } else {
476 format_parity = UART_FORMAT_PARITY_NONE;
477 }
478
479 if (cflag & CSTOPB)
480 format_stop = UART_FORMAT_STOP_2;
481 else
482 format_stop = UART_FORMAT_STOP_1;
483
484#ifdef VIZZINI_IWA
485 if (format_size == UART_FORMAT_SIZE_8) {
486 portdata->iwa = format_parity;
487 if (portdata->iwa != UART_FORMAT_PARITY_NONE) {
488 format_size = UART_FORMAT_SIZE_9;
489 format_parity = UART_FORMAT_PARITY_NONE;
490 }
491 } else {
492 portdata->iwa = UART_FORMAT_PARITY_NONE;
493 }
494#endif
495 vizzini_set_reg(port, block, UART_FORMAT, format_size | format_parity | format_stop);
496
497 if (cflag & CRTSCTS) {
498 flow = UART_FLOW_MODE_HW;
499 gpio_mode = UART_GPIO_MODE_SEL_RTS_CTS;
500 } else if (I_IXOFF(tty) || I_IXON(tty)) {
501 unsigned char start_char = START_CHAR(tty);
502 unsigned char stop_char = STOP_CHAR(tty);
503
504 flow = UART_FLOW_MODE_SW;
505 gpio_mode = UART_GPIO_MODE_SEL_GPIO;
506
507 vizzini_set_reg(port, block, UART_XON_CHAR, start_char);
508 vizzini_set_reg(port, block, UART_XOFF_CHAR, stop_char);
509 } else {
510 flow = UART_FLOW_MODE_NONE;
511 gpio_mode = UART_GPIO_MODE_SEL_GPIO;
512 }
513
514 vizzini_set_reg(port, block, UART_FLOW, flow);
515 vizzini_set_reg(port, block, UART_GPIO_MODE, gpio_mode);
516
517 if (portdata->trans9) {
518 /* Turn on wide mode if we're 9-bit transparent. */
519 vizzini_set_reg(port, EPLOCALS_REG_BLOCK, (block * MEM_EP_LOCALS_SIZE) + EP_WIDE_MODE, 1);
520#ifdef VIZZINI_IWA
521 } else if (portdata->iwa != UART_FORMAT_PARITY_NONE) {
522 vizzini_set_reg(port, EPLOCALS_REG_BLOCK, (block * MEM_EP_LOCALS_SIZE) + EP_WIDE_MODE, 1);
523#endif
524 } else if (!portdata->preciseflags) {
525 /* Turn off wide mode unless we have precise flags. */
526 vizzini_set_reg(port, EPLOCALS_REG_BLOCK, (block * MEM_EP_LOCALS_SIZE) + EP_WIDE_MODE, 0);
527 }
528
529 rate = tty_get_baud_rate(tty);
530 if (rate)
531 vizzini_set_baud_rate(port, rate);
532
533 vizzini_enable(port);
534}
535
536static void vizzini_break_ctl(struct tty_struct *tty, int break_state)
537{
538 struct usb_serial_port *port = tty->driver_data;
539
540 dev_dbg(&port->dev, "BREAK %d\n", break_state);
541 if (break_state)
542 acm_send_break(port, 0x10);
543 else
544 acm_send_break(port, 0x000);
545}
546
547static int vizzini_tiocmget(struct tty_struct *tty)
548{
549 struct usb_serial_port *port = tty->driver_data;
550 struct vizzini_port_private *portdata = usb_get_serial_port_data(port);
551
552 return (portdata->ctrlout & ACM_CTRL_DTR ? TIOCM_DTR : 0) |
553 (portdata->ctrlout & ACM_CTRL_RTS ? TIOCM_RTS : 0) |
554 (portdata->ctrlin & ACM_CTRL_DSR ? TIOCM_DSR : 0) |
555 (portdata->ctrlin & ACM_CTRL_RI ? TIOCM_RI : 0) |
556 (portdata->ctrlin & ACM_CTRL_DCD ? TIOCM_CD : 0) |
557 TIOCM_CTS;
558}
559
560static int vizzini_tiocmset(struct tty_struct *tty,
561 unsigned int set, unsigned int clear)
562{
563 struct usb_serial_port *port = tty->driver_data;
564 struct vizzini_port_private *portdata = usb_get_serial_port_data(port);
565 unsigned int newctrl;
566
567 newctrl = portdata->ctrlout;
568 set = (set & TIOCM_DTR ? ACM_CTRL_DTR : 0) | (set & TIOCM_RTS ? ACM_CTRL_RTS : 0);
569 clear = (clear & TIOCM_DTR ? ACM_CTRL_DTR : 0) | (clear & TIOCM_RTS ? ACM_CTRL_RTS : 0);
570
571 newctrl = (newctrl & ~clear) | set;
572
573 if (portdata->ctrlout == newctrl)
574 return 0;
575 return acm_set_control(port, portdata->ctrlout = newctrl);
576}
577
578static int vizzini_ioctl(struct tty_struct *tty, unsigned int cmd, unsigned long arg)
579{
580 struct usb_serial_port *port = tty->driver_data;
581 struct vizzini_port_private *portdata = usb_get_serial_port_data(port);
582 struct serial_struct ss;
583
584 dev_dbg(&port->dev, "%s %08x\n", __func__, cmd);
585
586 switch (cmd) {
587 case TIOCGSERIAL:
588 if (!arg)
589 return -EFAULT;
590 memset(&ss, 0, sizeof(ss));
591 ss.baud_base = portdata->baud_base;
592 if (copy_to_user((void __user *)arg, &ss, sizeof(ss)))
593 return -EFAULT;
594 break;
595
596 case TIOCSSERIAL:
597 if (!arg)
598 return -EFAULT;
599 if (copy_from_user(&ss, (void __user *)arg, sizeof(ss)))
600 return -EFAULT;
601 portdata->baud_base = ss.baud_base;
602 dev_dbg(&port->dev, "baud_base=%d\n", portdata->baud_base);
603
604 vizzini_disable(port);
605 if (portdata->baud_base)
606 vizzini_set_baud_rate(port, portdata->baud_base);
607 vizzini_enable(port);
608 break;
609
610 default:
611 return -ENOIOCTLCMD;
612 }
613
614 return 0;
615}
616
617#ifdef VIZZINI_IWA
618static const int vizzini_parity[] = {
619 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0,
620 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1,
621 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1,
622 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0,
623 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1,
624 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0,
625 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0,
626 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1,
627 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1,
628 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0,
629 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0,
630 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1,
631 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0,
632 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1,
633 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1,
634 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0
635};
636#endif
637
638static void vizzini_out_callback(struct urb *urb)
639{
640 struct usb_serial_port *port = urb->context;
641 struct vizzini_port_private *portdata = usb_get_serial_port_data(port);
642 int status = urb->status;
643 unsigned long flags;
644
645 dev_dbg(&port->dev, "%s - port %d\n", __func__, port->number);
646
647 /* free up the transfer buffer, as usb_free_urb() does not do this */
648 kfree(urb->transfer_buffer);
649
650 if (status)
651 dev_dbg(&port->dev, "%s - nonzero write bulk status received: %d\n", __func__, status);
652
653 spin_lock_irqsave(&portdata->lock, flags);
654 --portdata->outstanding_urbs;
655 spin_unlock_irqrestore(&portdata->lock, flags);
656
657 usb_serial_port_softint(port);
658}
659
660static int vizzini_write_room(struct tty_struct *tty)
661{
662 struct usb_serial_port *port = tty->driver_data;
663 struct vizzini_port_private *portdata = usb_get_serial_port_data(port);
664 unsigned long flags;
665
666 dev_dbg(&port->dev, "%s - port %d\n", __func__, port->number);
667
668 /* try to give a good number back based on if we have any free urbs at
669 * this point in time */
670 spin_lock_irqsave(&portdata->lock, flags);
671 if (portdata->outstanding_urbs > N_OUT_URB * 2 / 3) {
672 spin_unlock_irqrestore(&portdata->lock, flags);
673 dev_dbg(&port->dev, "%s - write limit hit\n", __func__);
674 return 0;
675 }
676 spin_unlock_irqrestore(&portdata->lock, flags);
677
678 return 2048;
679}
680
681static int vizzini_write(struct tty_struct *tty, struct usb_serial_port *port,
682 const unsigned char *buf, int count)
683{
684 struct vizzini_port_private *portdata = usb_get_serial_port_data(port);
685 struct usb_serial *serial = port->serial;
686 int bufsize = count;
687 unsigned long flags;
688 unsigned char *buffer;
689 struct urb *urb;
690 int status;
691
692 portdata = usb_get_serial_port_data(port);
693
694 dev_dbg(&port->dev, "%s: write (%d chars)\n", __func__, count);
695
696 spin_lock_irqsave(&portdata->lock, flags);
697 if (portdata->outstanding_urbs > N_OUT_URB) {
698 spin_unlock_irqrestore(&portdata->lock, flags);
699 dev_dbg(&port->dev, "%s - write limit hit\n", __func__);
700 return 0;
701 }
702 portdata->outstanding_urbs++;
703 spin_unlock_irqrestore(&portdata->lock, flags);
704
705#ifdef VIZZINI_IWA
706 if (portdata->iwa != UART_FORMAT_PARITY_NONE)
707 bufsize = count * 2;
708#endif
709 buffer = kmalloc(bufsize, GFP_ATOMIC);
710
711 if (!buffer) {
712 dev_err(&port->dev, "out of memory\n");
713 count = -ENOMEM;
714 goto error_no_buffer;
715 }
716
717 urb = usb_alloc_urb(0, GFP_ATOMIC);
718 if (!urb) {
719 dev_err(&port->dev, "no more free urbs\n");
720 count = -ENOMEM;
721 goto error_no_urb;
722 }
723
724#ifdef VIZZINI_IWA
725 if (portdata->iwa != UART_FORMAT_PARITY_NONE) {
726 int i;
727 char *b = buffer;
728 for (i = 0; i < count; ++i) {
729 int c, p = 0;
730 c = buf[i];
731 switch (portdata->iwa) {
732 case UART_FORMAT_PARITY_ODD:
733 p = !vizzini_parity[c];
734 break;
735 case UART_FORMAT_PARITY_EVEN:
736 p = vizzini_parity[c];
737 break;
738 case UART_FORMAT_PARITY_1:
739 p = 1;
740 break;
741 case UART_FORMAT_PARITY_0:
742 p = 0;
743 break;
744 }
745 *b++ = c;
746 *b++ = p;
747 }
748 } else
749#endif
750 memcpy(buffer, buf, count);
751
752 usb_fill_bulk_urb(urb, serial->dev,
753 usb_sndbulkpipe(serial->dev,
754 port->bulk_out_endpointAddress),
755 buffer, bufsize, vizzini_out_callback, port);
756
757 /* send it down the pipe */
758 status = usb_submit_urb(urb, GFP_ATOMIC);
759 if (status) {
760 dev_err(&port->dev, "%s - usb_submit_urb(write bulk) failed with status = %d\n", __func__, status);
761 count = status;
762 goto error;
763 }
764
765 /* we are done with this urb, so let the host driver
766 * really free it when it is finished with it */
767 usb_free_urb(urb);
768
769 return count;
770error:
771 usb_free_urb(urb);
772error_no_urb:
773 kfree(buffer);
774error_no_buffer:
775 spin_lock_irqsave(&portdata->lock, flags);
776 --portdata->outstanding_urbs;
777 spin_unlock_irqrestore(&portdata->lock, flags);
778 return count;
779}
780
781static void vizzini_in_callback(struct urb *urb)
782{
783 int endpoint = usb_pipeendpoint(urb->pipe);
784 struct usb_serial_port *port = urb->context;
785 struct vizzini_port_private *portdata = usb_get_serial_port_data(port);
786 struct tty_struct *tty = port->port.tty;
787 int preciseflags = portdata->preciseflags;
788 char *transfer_buffer = urb->transfer_buffer;
789 int length, room, have_extra_byte;
790 int err;
791
792 if (urb->status) {
793 dev_dbg(&port->dev, "%s: nonzero status: %d on endpoint %02x.\n", __func__, urb->status, endpoint);
794 return;
795 }
796
797#ifdef VIZZINI_IWA
798 if (portdata->iwa != UART_FORMAT_PARITY_NONE)
799 preciseflags = true;
800#endif
801
802 length = urb->actual_length;
803 if (length == 0) {
804 dev_dbg(&port->dev, "%s: empty read urb received\n", __func__);
805 err = usb_submit_urb(urb, GFP_ATOMIC);
806 if (err)
807 dev_err(&port->dev, "resubmit read urb failed. (%d)\n", err);
808 return;
809 }
810
811 length = length + (portdata->have_extra_byte ? 1 : 0);
812 have_extra_byte = (preciseflags && (length & 1));
813 length = (preciseflags) ? (length / 2) : length;
814
815 room = tty_buffer_request_room(tty, length);
816 if (room != length)
817 dev_dbg(&port->dev, "Not enough room in TTY buf, dropped %d chars.\n", length - room);
818
819 if (room) {
820 if (preciseflags) {
821 char *dp = transfer_buffer;
822 int i, ch, ch_flags;
823
824 for (i = 0; i < room; ++i) {
825 char tty_flag;
826
827 if (i == 0) {
828 if (portdata->have_extra_byte)
829 ch = portdata->extra_byte;
830 else
831 ch = *dp++;
832 } else {
833 ch = *dp++;
834 }
835 ch_flags = *dp++;
836
837#ifdef VIZZINI_IWA
838 {
839 int p;
840 switch (portdata->iwa) {
841 case UART_FORMAT_PARITY_ODD:
842 p = !vizzini_parity[ch];
843 break;
844 case UART_FORMAT_PARITY_EVEN:
845 p = vizzini_parity[ch];
846 break;
847 case UART_FORMAT_PARITY_1:
848 p = 1;
849 break;
850 case UART_FORMAT_PARITY_0:
851 p = 0;
852 break;
853 default:
854 p = 0;
855 break;
856 }
857 ch_flags ^= p;
858 }
859#endif
860 if (ch_flags & RAMCTL_BUFFER_PARITY)
861 tty_flag = TTY_PARITY;
862 else if (ch_flags & RAMCTL_BUFFER_BREAK)
863 tty_flag = TTY_BREAK;
864 else if (ch_flags & RAMCTL_BUFFER_FRAME)
865 tty_flag = TTY_FRAME;
866 else if (ch_flags & RAMCTL_BUFFER_OVERRUN)
867 tty_flag = TTY_OVERRUN;
868 else
869 tty_flag = TTY_NORMAL;
870
871 tty_insert_flip_char(tty, ch, tty_flag);
872 }
873 } else {
874 tty_insert_flip_string(tty, transfer_buffer, room);
875 }
876
877 tty_flip_buffer_push(tty);
878 }
879
880 portdata->have_extra_byte = have_extra_byte;
881 if (have_extra_byte)
882 portdata->extra_byte = transfer_buffer[urb->actual_length - 1];
883
884 err = usb_submit_urb(urb, GFP_ATOMIC);
885 if (err)
886 dev_err(&port->dev, "resubmit read urb failed. (%d)\n", err);
887}
888
889static void vizzini_int_callback(struct urb *urb)
890{
891 struct usb_serial_port *port = urb->context;
892 struct vizzini_port_private *portdata = usb_get_serial_port_data(port);
893 struct tty_struct *tty = port->port.tty;
894
895 struct usb_cdc_notification *dr = urb->transfer_buffer;
896 unsigned char *data;
897 int newctrl;
898 int status;
899
900 switch (urb->status) {
901 case 0:
902 /* success */
903 break;
904 case -ECONNRESET:
905 case -ENOENT:
906 case -ESHUTDOWN:
907 /* this urb is terminated, clean up */
908 dev_dbg(&port->dev, "urb shutting down with status: %d\n", urb->status);
909 return;
910 default:
911 dev_dbg(&port->dev, "nonzero urb status received: %d\n", urb->status);
912 goto exit;
913 }
914
915 data = (unsigned char *)(dr + 1);
916 switch (dr->bNotificationType) {
917
918 case USB_CDC_NOTIFY_NETWORK_CONNECTION:
919 dev_dbg(&port->dev, "%s network\n", dr->wValue ? "connected to" : "disconnected from");
920 break;
921
922 case USB_CDC_NOTIFY_SERIAL_STATE:
923 newctrl = le16_to_cpu(get_unaligned((__le16 *)data));
924
925 if (!portdata->clocal && (portdata->ctrlin & ~newctrl & ACM_CTRL_DCD)) {
926 dev_dbg(&port->dev, "calling hangup\n");
927 tty_hangup(tty);
928 }
929
930 portdata->ctrlin = newctrl;
931
932 dev_dbg(&port->dev, "input control lines: dcd%c dsr%c break%c ring%c framing%c parity%c overrun%c\n",
933 portdata->ctrlin & ACM_CTRL_DCD ? '+' : '-',
934 portdata->ctrlin & ACM_CTRL_DSR ? '+' : '-',
935 portdata->ctrlin & ACM_CTRL_BRK ? '+' : '-',
936 portdata->ctrlin & ACM_CTRL_RI ? '+' : '-',
937 portdata->ctrlin & ACM_CTRL_FRAMING ? '+' : '-',
938 portdata->ctrlin & ACM_CTRL_PARITY ? '+' : '-',
939 portdata->ctrlin & ACM_CTRL_OVERRUN ? '+' : '-');
940 break;
941
942 default:
943 dev_dbg(&port->dev, "unknown notification %d received: index %d len %d data0 %d data1 %d\n",
944 dr->bNotificationType, dr->wIndex,
945 dr->wLength, data[0], data[1]);
946 break;
947 }
948exit:
949 dev_dbg(&port->dev, "Resubmitting interrupt IN urb %p\n", urb);
950 status = usb_submit_urb(urb, GFP_ATOMIC);
951 if (status)
952 dev_err(&port->dev, "usb_submit_urb failed with result %d", status);
953}
954
955static int vizzini_open(struct tty_struct *tty_param, struct usb_serial_port *port)
956{
957 struct vizzini_port_private *portdata;
958 struct usb_serial *serial = port->serial;
959 struct tty_struct *tty = port->port.tty;
960 int i;
961 struct urb *urb;
962 int result;
963
964 portdata = usb_get_serial_port_data(port);
965
966 acm_set_control(port, portdata->ctrlout = ACM_CTRL_DTR | ACM_CTRL_RTS);
967
968 /* Reset low level data toggle and start reading from endpoints */
969 for (i = 0; i < N_IN_URB; i++) {
970 dev_dbg(&port->dev, "%s urb %d\n", __func__, i);
971
972 urb = portdata->in_urbs[i];
973 if (!urb)
974 continue;
975 if (urb->dev != serial->dev) {
976 dev_dbg(&port->dev, "%s: dev %p != %p\n", __func__,
977 urb->dev, serial->dev);
978 continue;
979 }
980
981 /*
982 * make sure endpoint data toggle is synchronized with the
983 * device
984 */
985 /* dev_dbg(&port->dev, "%s clearing halt on %x\n", __func__, urb->pipe); */
986 /* usb_clear_halt(urb->dev, urb->pipe); */
987
988 dev_dbg(&port->dev, "%s submitting urb %p\n", __func__, urb);
989 result = usb_submit_urb(urb, GFP_KERNEL);
990 if (result) {
991 dev_err(&port->dev, "submit urb %d failed (%d) %d\n",
992 i, result, urb->transfer_buffer_length);
993 }
994 }
995
996 tty->low_latency = 1;
997
998 /* start up the interrupt endpoint if we have one */
999 if (port->interrupt_in_urb) {
1000 result = usb_submit_urb(port->interrupt_in_urb, GFP_KERNEL);
1001 if (result)
1002 dev_err(&port->dev, "submit irq_in urb failed %d\n",
1003 result);
1004 }
1005 return 0;
1006}
1007
1008static void vizzini_close(struct usb_serial_port *port)
1009{
1010 int i;
1011 struct usb_serial *serial = port->serial;
1012 struct vizzini_port_private *portdata;
1013 struct tty_struct *tty = port->port.tty;
1014
1015 portdata = usb_get_serial_port_data(port);
1016
1017 acm_set_control(port, portdata->ctrlout = 0);
1018
1019 if (serial->dev) {
1020 /* Stop reading/writing urbs */
1021 for (i = 0; i < N_IN_URB; i++)
1022 usb_kill_urb(portdata->in_urbs[i]);
1023 }
1024
1025 usb_kill_urb(port->interrupt_in_urb);
1026
1027 tty = NULL; /* FIXME */
1028}
1029
1030static int vizzini_attach(struct usb_serial *serial)
1031{
1032 struct vizzini_serial_private *serial_priv = usb_get_serial_data(serial);
1033 struct usb_interface *interface = serial_priv->data_interface;
1034 struct usb_host_interface *iface_desc;
1035 struct usb_endpoint_descriptor *endpoint;
1036 struct usb_endpoint_descriptor *bulk_in_endpoint = NULL;
1037 struct usb_endpoint_descriptor *bulk_out_endpoint = NULL;
1038
1039 struct usb_serial_port *port;
1040 struct vizzini_port_private *portdata;
1041 struct urb *urb;
1042 int i, j;
1043
1044 /* Assume that there's exactly one serial port. */
1045 port = serial->port[0];
1046
1047 /* The usb_serial is now fully set up, but we want to make a
1048 * couple of modifications. Namely, it was configured based
1049 * upon the control interface and not the data interface, so
1050 * it has no notion of the bulk in and out endpoints. So we
1051 * essentially do some of the same allocations and
1052 * configurations that the usb-serial core would have done if
1053 * it had not made any faulty assumptions about the
1054 * endpoints. */
1055
1056 iface_desc = interface->cur_altsetting;
1057 for (i = 0; i < iface_desc->desc.bNumEndpoints; ++i) {
1058 endpoint = &iface_desc->endpoint[i].desc;
1059
1060 if (usb_endpoint_is_bulk_in(endpoint))
1061 bulk_in_endpoint = endpoint;
1062
1063 if (usb_endpoint_is_bulk_out(endpoint))
1064 bulk_out_endpoint = endpoint;
1065 }
1066
1067 if (!bulk_out_endpoint || !bulk_in_endpoint) {
1068 dev_dbg(&port->dev, "Missing endpoint!\n");
1069 return -EINVAL;
1070 }
1071
1072 port->bulk_out_endpointAddress = bulk_out_endpoint->bEndpointAddress;
1073 port->bulk_in_endpointAddress = bulk_in_endpoint->bEndpointAddress;
1074
1075 portdata = kzalloc(sizeof(*portdata), GFP_KERNEL);
1076 if (!portdata) {
1077 dev_dbg(&port->dev, "%s: kmalloc for vizzini_port_private (%d) failed!.\n",
1078 __func__, i);
1079 return -ENOMEM;
1080 }
1081 spin_lock_init(&portdata->lock);
1082 for (j = 0; j < N_IN_URB; j++) {
1083 portdata->in_buffer[j] = kmalloc(IN_BUFLEN, GFP_KERNEL);
1084 if (!portdata->in_buffer[j]) {
1085 for (--j; j >= 0; j--)
1086 kfree(portdata->in_buffer[j]);
1087 kfree(portdata);
1088 return -ENOMEM;
1089 }
1090 }
1091
1092 /* Bulk OUT endpoints 0x1..0x4 map to register blocks 0..3 */
1093 portdata->block = port->bulk_out_endpointAddress - 1;
1094
1095 usb_set_serial_port_data(port, portdata);
1096
1097 portdata->bcd_device = le16_to_cpu(serial->dev->descriptor.bcdDevice);
1098 if (vizzini_rev_a(port))
1099 dev_info(&port->dev, "Adapting to revA silicon\n");
1100
1101 /* initialize the in urbs */
1102 for (j = 0; j < N_IN_URB; ++j) {
1103 urb = usb_alloc_urb(0, GFP_KERNEL);
1104 if (urb == NULL) {
1105 dev_dbg(&port->dev, "%s: alloc for in port failed.\n", __func__);
1106 continue;
1107 }
1108 /* Fill URB using supplied data. */
1109 dev_dbg(&port->dev, "Filling URB %p, EP=%d buf=%p len=%d\n", urb, port->bulk_in_endpointAddress, portdata->in_buffer[j], IN_BUFLEN);
1110 usb_fill_bulk_urb(urb, serial->dev,
1111 usb_rcvbulkpipe(serial->dev,
1112 port->bulk_in_endpointAddress),
1113 portdata->in_buffer[j], IN_BUFLEN,
1114 vizzini_in_callback, port);
1115 portdata->in_urbs[j] = urb;
1116 }
1117
1118 return 0;
1119}
1120
1121static void vizzini_serial_disconnect(struct usb_serial *serial)
1122{
1123 struct usb_serial_port *port;
1124 struct vizzini_port_private *portdata;
1125 int i, j;
1126
1127 dev_dbg(&serial->dev->dev, "%s %p\n", __func__, serial);
1128
1129 for (i = 0; i < serial->num_ports; ++i) {
1130 port = serial->port[i];
1131 if (!port)
1132 continue;
1133 portdata = usb_get_serial_port_data(port);
1134 if (!portdata)
1135 continue;
1136
1137 for (j = 0; j < N_IN_URB; j++) {
1138 usb_kill_urb(portdata->in_urbs[j]);
1139 usb_free_urb(portdata->in_urbs[j]);
1140 }
1141 }
1142}
1143
1144static void vizzini_serial_release(struct usb_serial *serial)
1145{
1146 struct usb_serial_port *port;
1147 struct vizzini_port_private *portdata;
1148 int i, j;
1149
1150 dev_dbg(&serial->dev->dev, "%s %p\n", __func__, serial);
1151
1152 for (i = 0; i < serial->num_ports; ++i) {
1153 port = serial->port[i];
1154 if (!port)
1155 continue;
1156 portdata = usb_get_serial_port_data(port);
1157 if (!portdata)
1158 continue;
1159
1160 for (j = 0; j < N_IN_URB; j++)
1161 kfree(portdata->in_buffer[j]);
1162
1163 kfree(portdata);
1164 usb_set_serial_port_data(port, NULL);
1165 }
1166}
1167
1168static int vizzini_calc_num_ports(struct usb_serial *serial)
1169{
1170 return 1;
1171}
1172
1173static int vizzini_probe(struct usb_serial *serial,
1174 const struct usb_device_id *id)
1175{
1176 struct usb_interface *intf = serial->interface;
1177 unsigned char *buffer = intf->altsetting->extra;
1178 int buflen = intf->altsetting->extralen;
1179 struct usb_device *usb_dev = interface_to_usbdev(intf);
1180 struct usb_cdc_union_desc *union_header = NULL;
1181 struct usb_cdc_country_functional_desc *cfd = NULL;
1182 int call_interface_num = -1;
1183 int data_interface_num;
1184 struct usb_interface *control_interface;
1185 struct usb_interface *data_interface;
1186 struct usb_endpoint_descriptor *epctrl;
1187 struct usb_endpoint_descriptor *epread;
1188 struct usb_endpoint_descriptor *epwrite;
1189 struct vizzini_serial_private *serial_priv;
1190
1191 if (!buffer) {
1192 dev_err(&intf->dev, "Weird descriptor references\n");
1193 return -EINVAL;
1194 }
1195
1196 if (!buflen) {
1197 if (intf->cur_altsetting->endpoint->extralen && intf->cur_altsetting->endpoint->extra) {
1198 dev_dbg(&intf->dev, "Seeking extra descriptors on endpoint\n");
1199 buflen = intf->cur_altsetting->endpoint->extralen;
1200 buffer = intf->cur_altsetting->endpoint->extra;
1201 } else {
1202 dev_err(&intf->dev, "Zero length descriptor references\n");
1203 return -EINVAL;
1204 }
1205 }
1206
1207 while (buflen > 0) {
1208 if (buffer[1] != USB_DT_CS_INTERFACE) {
1209 dev_err(&intf->dev, "skipping garbage\n");
1210 goto next_desc;
1211 }
1212
1213 switch (buffer[2]) {
1214 case USB_CDC_UNION_TYPE: /* we've found it */
1215 if (union_header) {
1216 dev_err(&intf->dev, "More than one union descriptor, skipping ...\n");
1217 goto next_desc;
1218 }
1219 union_header = (struct usb_cdc_union_desc *)buffer;
1220 break;
1221 case USB_CDC_COUNTRY_TYPE: /* export through sysfs */
1222 cfd = (struct usb_cdc_country_functional_desc *)buffer;
1223 break;
1224 case USB_CDC_HEADER_TYPE: /* maybe check version */
1225 break; /* for now we ignore it */
1226 case USB_CDC_CALL_MANAGEMENT_TYPE:
1227 call_interface_num = buffer[4];
1228 break;
1229 default:
1230 /* there are LOTS more CDC descriptors that
1231 * could legitimately be found here.
1232 */
1233 dev_dbg(&intf->dev, "Ignoring descriptor: type %02x, length %d\n", buffer[2], buffer[0]);
1234 break;
1235 }
1236next_desc:
1237 buflen -= buffer[0];
1238 buffer += buffer[0];
1239 }
1240
1241 if (!union_header) {
1242 if (call_interface_num > 0) {
1243 dev_dbg(&intf->dev, "No union descriptor, using call management descriptor\n");
1244 data_interface = usb_ifnum_to_if(usb_dev, (data_interface_num = call_interface_num));
1245 control_interface = intf;
1246 } else {
1247 dev_dbg(&intf->dev, "No union descriptor, giving up\n");
1248 return -ENODEV;
1249 }
1250 } else {
1251 control_interface = usb_ifnum_to_if(usb_dev, union_header->bMasterInterface0);
1252 data_interface = usb_ifnum_to_if(usb_dev, (data_interface_num = union_header->bSlaveInterface0));
1253 if (!control_interface || !data_interface) {
1254 dev_dbg(&intf->dev, "no interfaces\n");
1255 return -ENODEV;
1256 }
1257 }
1258
1259 if (data_interface_num != call_interface_num)
1260 dev_dbg(&intf->dev, "Separate call control interface. That is not fully supported.\n");
1261
1262 /* workaround for switched interfaces */
1263 if (data_interface->cur_altsetting->desc.bInterfaceClass != CDC_DATA_INTERFACE_TYPE) {
1264 if (control_interface->cur_altsetting->desc.bInterfaceClass == CDC_DATA_INTERFACE_TYPE) {
1265 struct usb_interface *t;
1266
1267 t = control_interface;
1268 control_interface = data_interface;
1269 data_interface = t;
1270 } else {
1271 return -EINVAL;
1272 }
1273 }
1274
1275 /* Accept probe requests only for the control interface */
1276 if (intf != control_interface)
1277 return -ENODEV;
1278
1279 if (usb_interface_claimed(data_interface)) { /* valid in this context */
1280 dev_dbg(&intf->dev, "The data interface isn't available\n");
1281 return -EBUSY;
1282 }
1283
1284 if (data_interface->cur_altsetting->desc.bNumEndpoints < 2)
1285 return -EINVAL;
1286
1287 epctrl = &control_interface->cur_altsetting->endpoint[0].desc;
1288 epread = &data_interface->cur_altsetting->endpoint[0].desc;
1289 epwrite = &data_interface->cur_altsetting->endpoint[1].desc;
1290 if (!usb_endpoint_dir_in(epread)) {
1291 struct usb_endpoint_descriptor *t;
1292 t = epread;
1293 epread = epwrite;
1294 epwrite = t;
1295 }
1296
1297 /* The documentation suggests that we allocate private storage
1298 * with the attach() entry point, but we can't allow the data
1299 * interface to remain unclaimed until then; so we need
1300 * somewhere to save the claimed interface now. */
1301 serial_priv = kzalloc(sizeof(struct vizzini_serial_private),
1302 GFP_KERNEL);
1303 if (!serial_priv)
1304 goto alloc_fail;
1305 usb_set_serial_data(serial, serial_priv);
1306
1307 //usb_driver_claim_interface(&vizzini_driver, data_interface, NULL);
1308
1309 /* Don't set the data interface private data. When we
1310 * disconnect we test this field against NULL to discover
1311 * whether we're dealing with the control or data
1312 * interface. */
1313 serial_priv->data_interface = data_interface;
1314
1315 return 0;
1316
1317alloc_fail:
1318 return -ENOMEM;
1319}
1320
1321static struct usb_serial_driver vizzini_device = {
1322 .driver = {
1323 .owner = THIS_MODULE,
1324 .name = "vizzini",
1325 },
1326 .description = "Vizzini USB serial port",
1327 .id_table = id_table,
1328 .calc_num_ports = vizzini_calc_num_ports,
1329 .probe = vizzini_probe,
1330 .open = vizzini_open,
1331 .close = vizzini_close,
1332 .write = vizzini_write,
1333 .write_room = vizzini_write_room,
1334 .ioctl = vizzini_ioctl,
1335 .set_termios = vizzini_set_termios,
1336 .break_ctl = vizzini_break_ctl,
1337 .tiocmget = vizzini_tiocmget,
1338 .tiocmset = vizzini_tiocmset,
1339 .attach = vizzini_attach,
1340 .disconnect = vizzini_serial_disconnect,
1341 .release = vizzini_serial_release,
1342 .read_int_callback = vizzini_int_callback,
1343};
1344
1345static struct usb_serial_driver * const serial_drivers[] = {
1346 &vizzini_device, NULL
1347};
1348
1349module_usb_serial_driver(serial_drivers, id_table);
1350
1351MODULE_AUTHOR(DRIVER_AUTHOR);
1352MODULE_DESCRIPTION(DRIVER_DESC);
1353MODULE_VERSION(DRIVER_VERSION);
1354MODULE_LICENSE("GPL");