Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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>

+1372
+8
drivers/usb/serial/Kconfig
··· 182 182 To compile this driver as a module, choose M here: the 183 183 module will be called visor. 184 184 185 + config 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 + 185 193 config USB_SERIAL_IPAQ 186 194 tristate "USB PocketPC PDA Driver" 187 195 help
+1
drivers/usb/serial/Makefile
··· 59 59 obj-$(CONFIG_USB_SERIAL_WWAN) += usb_wwan.o 60 60 obj-$(CONFIG_USB_SERIAL_TI) += ti_usb_3410_5052.o 61 61 obj-$(CONFIG_USB_SERIAL_VISOR) += visor.o 62 + obj-$(CONFIG_USB_SERIAL_VIZZINI) += vizzini.o 62 63 obj-$(CONFIG_USB_SERIAL_WHITEHEAT) += whiteheat.o 63 64 obj-$(CONFIG_USB_SERIAL_XIRCOM) += keyspan_pda.o 64 65 obj-$(CONFIG_USB_SERIAL_VIVOPAY_SERIAL) += vivopay-serial.o
+1363
drivers/usb/serial/vizzini.c
··· 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 + 276 + static struct usb_device_id id_table[] = { 277 + { USB_DEVICE(0x04e2, 0x1410) }, 278 + { USB_DEVICE(0x04e2, 0x1412) }, 279 + { USB_DEVICE(0x04e2, 0x1414) }, 280 + { } 281 + }; 282 + MODULE_DEVICE_TABLE(usb, id_table); 283 + 284 + struct vizzini_serial_private { 285 + struct usb_interface *data_interface; 286 + }; 287 + 288 + struct 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 + 314 + static 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 + 320 + static 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 + 344 + static 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 + 362 + static 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 + 371 + static 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 + 381 + struct vizzini_baud_rate { 382 + unsigned int tx; 383 + unsigned int rx0; 384 + unsigned int rx1; 385 + }; 386 + 387 + static 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 + 422 + static 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 + 444 + static 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 + 545 + static 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 + 556 + static 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 + 569 + static 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 + 587 + static 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 627 + static 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 + 647 + static 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 + 669 + static 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 + 690 + static 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; 779 + error: 780 + usb_free_urb(urb); 781 + error_no_urb: 782 + kfree(buffer); 783 + error_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 + 790 + static 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 + 898 + static 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 + } 957 + exit: 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 + 964 + static 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 + 1017 + static 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 + 1039 + static 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 + 1130 + static 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 + 1153 + static 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 + 1177 + static int vizzini_calc_num_ports(struct usb_serial *serial) 1178 + { 1179 + return 1; 1180 + } 1181 + 1182 + static 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 + } 1245 + next_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 + 1326 + alloc_fail: 1327 + return -ENOMEM; 1328 + } 1329 + 1330 + static 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 + 1354 + static struct usb_serial_driver * const serial_drivers[] = { 1355 + &vizzini_device, NULL 1356 + }; 1357 + 1358 + module_usb_serial_driver(serial_drivers, id_table); 1359 + 1360 + MODULE_AUTHOR(DRIVER_AUTHOR); 1361 + MODULE_DESCRIPTION(DRIVER_DESC); 1362 + MODULE_VERSION(DRIVER_VERSION); 1363 + MODULE_LICENSE("GPL");