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