diff options
Diffstat (limited to 'drivers/usb/serial')
-rw-r--r-- | drivers/usb/serial/ark3116.c | 975 | ||||
-rw-r--r-- | drivers/usb/serial/ftdi_sio.c | 32 | ||||
-rw-r--r-- | drivers/usb/serial/ftdi_sio.h | 14 | ||||
-rw-r--r-- | drivers/usb/serial/mos7840.c | 24 | ||||
-rw-r--r-- | drivers/usb/serial/option.c | 39 | ||||
-rw-r--r-- | drivers/usb/serial/sierra.c | 91 |
6 files changed, 884 insertions, 291 deletions
diff --git a/drivers/usb/serial/ark3116.c b/drivers/usb/serial/ark3116.c index 131e61adaaf7..a9c2dec8e3fb 100644 --- a/drivers/usb/serial/ark3116.c +++ b/drivers/usb/serial/ark3116.c | |||
@@ -1,4 +1,6 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright (C) 2009 by Bart Hartgers (bart.hartgers+ark3116@gmail.com) | ||
3 | * Original version: | ||
2 | * Copyright (C) 2006 | 4 | * Copyright (C) 2006 |
3 | * Simon Schulz (ark3116_driver <at> auctionant.de) | 5 | * Simon Schulz (ark3116_driver <at> auctionant.de) |
4 | * | 6 | * |
@@ -6,10 +8,13 @@ | |||
6 | * - implements a driver for the arkmicro ark3116 chipset (vendor=0x6547, | 8 | * - implements a driver for the arkmicro ark3116 chipset (vendor=0x6547, |
7 | * productid=0x0232) (used in a datacable called KQ-U8A) | 9 | * productid=0x0232) (used in a datacable called KQ-U8A) |
8 | * | 10 | * |
9 | * - based on code by krisfx -> thanks !! | 11 | * Supports full modem status lines, break, hardware flow control. Does not |
10 | * (see http://www.linuxquestions.org/questions/showthread.php?p=2184457#post2184457) | 12 | * support software flow control, since I do not know how to enable it in hw. |
11 | * | 13 | * |
12 | * - based on logs created by usbsnoopy | 14 | * This driver is a essentially new implementation. I initially dug |
15 | * into the old ark3116.c driver and suddenly realized the ark3116 is | ||
16 | * a 16450 with a USB interface glued to it. See comments at the | ||
17 | * bottom of this file. | ||
13 | * | 18 | * |
14 | * This program is free software; you can redistribute it and/or modify it | 19 | * This program is free software; you can redistribute it and/or modify it |
15 | * under the terms of the GNU General Public License as published by the | 20 | * under the terms of the GNU General Public License as published by the |
@@ -19,15 +24,31 @@ | |||
19 | 24 | ||
20 | #include <linux/kernel.h> | 25 | #include <linux/kernel.h> |
21 | #include <linux/init.h> | 26 | #include <linux/init.h> |
27 | #include <linux/ioctl.h> | ||
22 | #include <linux/tty.h> | 28 | #include <linux/tty.h> |
29 | #include <linux/tty_flip.h> | ||
23 | #include <linux/module.h> | 30 | #include <linux/module.h> |
24 | #include <linux/usb.h> | 31 | #include <linux/usb.h> |
25 | #include <linux/usb/serial.h> | 32 | #include <linux/usb/serial.h> |
26 | #include <linux/serial.h> | 33 | #include <linux/serial.h> |
34 | #include <linux/serial_reg.h> | ||
27 | #include <linux/uaccess.h> | 35 | #include <linux/uaccess.h> |
28 | 36 | #include <linux/mutex.h> | |
37 | #include <linux/spinlock.h> | ||
29 | 38 | ||
30 | static int debug; | 39 | static int debug; |
40 | /* | ||
41 | * Version information | ||
42 | */ | ||
43 | |||
44 | #define DRIVER_VERSION "v0.5" | ||
45 | #define DRIVER_AUTHOR "Bart Hartgers <bart.hartgers+ark3116@gmail.com>" | ||
46 | #define DRIVER_DESC "USB ARK3116 serial/IrDA driver" | ||
47 | #define DRIVER_DEV_DESC "ARK3116 RS232/IrDA" | ||
48 | #define DRIVER_NAME "ark3116" | ||
49 | |||
50 | /* usb timeout of 1 second */ | ||
51 | #define ARK_TIMEOUT (1*HZ) | ||
31 | 52 | ||
32 | static struct usb_device_id id_table [] = { | 53 | static struct usb_device_id id_table [] = { |
33 | { USB_DEVICE(0x6547, 0x0232) }, | 54 | { USB_DEVICE(0x6547, 0x0232) }, |
@@ -45,118 +66,152 @@ static int is_irda(struct usb_serial *serial) | |||
45 | return 0; | 66 | return 0; |
46 | } | 67 | } |
47 | 68 | ||
48 | static inline void ARK3116_SND(struct usb_serial *serial, int seq, | 69 | struct ark3116_private { |
49 | __u8 request, __u8 requesttype, | 70 | wait_queue_head_t delta_msr_wait; |
50 | __u16 value, __u16 index) | 71 | struct async_icount icount; |
72 | int irda; /* 1 for irda device */ | ||
73 | |||
74 | /* protects hw register updates */ | ||
75 | struct mutex hw_lock; | ||
76 | |||
77 | int quot; /* baudrate divisor */ | ||
78 | __u32 lcr; /* line control register value */ | ||
79 | __u32 hcr; /* handshake control register (0x8) | ||
80 | * value */ | ||
81 | __u32 mcr; /* modem contol register value */ | ||
82 | |||
83 | /* protects the status values below */ | ||
84 | spinlock_t status_lock; | ||
85 | __u32 msr; /* modem status register value */ | ||
86 | __u32 lsr; /* line status register value */ | ||
87 | }; | ||
88 | |||
89 | static int ark3116_write_reg(struct usb_serial *serial, | ||
90 | unsigned reg, __u8 val) | ||
51 | { | 91 | { |
52 | int result; | 92 | int result; |
93 | /* 0xfe 0x40 are magic values taken from original driver */ | ||
53 | result = usb_control_msg(serial->dev, | 94 | result = usb_control_msg(serial->dev, |
54 | usb_sndctrlpipe(serial->dev, 0), | 95 | usb_sndctrlpipe(serial->dev, 0), |
55 | request, requesttype, value, index, | 96 | 0xfe, 0x40, val, reg, |
56 | NULL, 0x00, 1000); | 97 | NULL, 0, ARK_TIMEOUT); |
57 | dbg("%03d > ok", seq); | 98 | return result; |
58 | } | 99 | } |
59 | 100 | ||
60 | static inline void ARK3116_RCV(struct usb_serial *serial, int seq, | 101 | static int ark3116_read_reg(struct usb_serial *serial, |
61 | __u8 request, __u8 requesttype, | 102 | unsigned reg, unsigned char *buf) |
62 | __u16 value, __u16 index, __u8 expected, | ||
63 | char *buf) | ||
64 | { | 103 | { |
65 | int result; | 104 | int result; |
105 | /* 0xfe 0xc0 are magic values taken from original driver */ | ||
66 | result = usb_control_msg(serial->dev, | 106 | result = usb_control_msg(serial->dev, |
67 | usb_rcvctrlpipe(serial->dev, 0), | 107 | usb_rcvctrlpipe(serial->dev, 0), |
68 | request, requesttype, value, index, | 108 | 0xfe, 0xc0, 0, reg, |
69 | buf, 0x0000001, 1000); | 109 | buf, 1, ARK_TIMEOUT); |
70 | if (result) | 110 | if (result < 0) |
71 | dbg("%03d < %d bytes [0x%02X]", seq, result, | 111 | return result; |
72 | ((unsigned char *)buf)[0]); | ||
73 | else | 112 | else |
74 | dbg("%03d < 0 bytes", seq); | 113 | return buf[0]; |
75 | } | 114 | } |
76 | 115 | ||
77 | static inline void ARK3116_RCV_QUIET(struct usb_serial *serial, | 116 | static inline int calc_divisor(int bps) |
78 | __u8 request, __u8 requesttype, | ||
79 | __u16 value, __u16 index, char *buf) | ||
80 | { | 117 | { |
81 | usb_control_msg(serial->dev, | 118 | /* Original ark3116 made some exceptions in rounding here |
82 | usb_rcvctrlpipe(serial->dev, 0), | 119 | * because windows did the same. Assume that is not really |
83 | request, requesttype, value, index, | 120 | * necessary. |
84 | buf, 0x0000001, 1000); | 121 | * Crystal is 12MHz, probably because of USB, but we divide by 4? |
122 | */ | ||
123 | return (12000000 + 2*bps) / (4*bps); | ||
85 | } | 124 | } |
86 | 125 | ||
87 | static int ark3116_attach(struct usb_serial *serial) | 126 | static int ark3116_attach(struct usb_serial *serial) |
88 | { | 127 | { |
89 | char *buf; | 128 | struct usb_serial_port *port = serial->port[0]; |
129 | struct ark3116_private *priv; | ||
130 | |||
131 | /* make sure we have our end-points */ | ||
132 | if ((serial->num_bulk_in == 0) || | ||
133 | (serial->num_bulk_out == 0) || | ||
134 | (serial->num_interrupt_in == 0)) { | ||
135 | dev_err(&serial->dev->dev, | ||
136 | "%s - missing endpoint - " | ||
137 | "bulk in: %d, bulk out: %d, int in %d\n", | ||
138 | KBUILD_MODNAME, | ||
139 | serial->num_bulk_in, | ||
140 | serial->num_bulk_out, | ||
141 | serial->num_interrupt_in); | ||
142 | return -EINVAL; | ||
143 | } | ||
90 | 144 | ||
91 | buf = kmalloc(1, GFP_KERNEL); | 145 | priv = kzalloc(sizeof(struct ark3116_private), |
92 | if (!buf) { | 146 | GFP_KERNEL); |
93 | dbg("error kmalloc -> out of mem?"); | 147 | if (!priv) |
94 | return -ENOMEM; | 148 | return -ENOMEM; |
95 | } | ||
96 | 149 | ||
97 | if (is_irda(serial)) | 150 | init_waitqueue_head(&priv->delta_msr_wait); |
98 | dbg("IrDA mode"); | 151 | mutex_init(&priv->hw_lock); |
152 | spin_lock_init(&priv->status_lock); | ||
153 | |||
154 | priv->irda = is_irda(serial); | ||
99 | 155 | ||
100 | /* 3 */ | 156 | usb_set_serial_port_data(port, priv); |
101 | ARK3116_SND(serial, 3, 0xFE, 0x40, 0x0008, 0x0002); | ||
102 | ARK3116_SND(serial, 4, 0xFE, 0x40, 0x0008, 0x0001); | ||
103 | ARK3116_SND(serial, 5, 0xFE, 0x40, 0x0000, 0x0008); | ||
104 | ARK3116_SND(serial, 6, 0xFE, 0x40, is_irda(serial) ? 0x0001 : 0x0000, | ||
105 | 0x000B); | ||
106 | 157 | ||
107 | if (is_irda(serial)) { | 158 | /* setup the hardware */ |
108 | ARK3116_SND(serial, 1001, 0xFE, 0x40, 0x0000, 0x000C); | 159 | ark3116_write_reg(serial, UART_IER, 0); |
109 | ARK3116_SND(serial, 1002, 0xFE, 0x40, 0x0041, 0x000D); | 160 | /* disable DMA */ |
110 | ARK3116_SND(serial, 1003, 0xFE, 0x40, 0x0001, 0x000A); | 161 | ark3116_write_reg(serial, UART_FCR, 0); |
162 | /* handshake control */ | ||
163 | priv->hcr = 0; | ||
164 | ark3116_write_reg(serial, 0x8 , 0); | ||
165 | /* modem control */ | ||
166 | priv->mcr = 0; | ||
167 | ark3116_write_reg(serial, UART_MCR, 0); | ||
168 | |||
169 | if (!(priv->irda)) { | ||
170 | ark3116_write_reg(serial, 0xb , 0); | ||
171 | } else { | ||
172 | ark3116_write_reg(serial, 0xb , 1); | ||
173 | ark3116_write_reg(serial, 0xc , 0); | ||
174 | ark3116_write_reg(serial, 0xd , 0x41); | ||
175 | ark3116_write_reg(serial, 0xa , 1); | ||
111 | } | 176 | } |
112 | 177 | ||
113 | /* <-- seq7 */ | 178 | /* setup baudrate */ |
114 | ARK3116_RCV(serial, 7, 0xFE, 0xC0, 0x0000, 0x0003, 0x00, buf); | 179 | ark3116_write_reg(serial, UART_LCR, UART_LCR_DLAB); |
115 | ARK3116_SND(serial, 8, 0xFE, 0x40, 0x0080, 0x0003); | ||
116 | ARK3116_SND(serial, 9, 0xFE, 0x40, 0x001A, 0x0000); | ||
117 | ARK3116_SND(serial, 10, 0xFE, 0x40, 0x0000, 0x0001); | ||
118 | ARK3116_SND(serial, 11, 0xFE, 0x40, 0x0000, 0x0003); | ||
119 | |||
120 | /* <-- seq12 */ | ||
121 | ARK3116_RCV(serial, 12, 0xFE, 0xC0, 0x0000, 0x0004, 0x00, buf); | ||
122 | ARK3116_SND(serial, 13, 0xFE, 0x40, 0x0000, 0x0004); | ||
123 | |||
124 | /* 14 */ | ||
125 | ARK3116_RCV(serial, 14, 0xFE, 0xC0, 0x0000, 0x0004, 0x00, buf); | ||
126 | ARK3116_SND(serial, 15, 0xFE, 0x40, 0x0000, 0x0004); | ||
127 | |||
128 | /* 16 */ | ||
129 | ARK3116_RCV(serial, 16, 0xFE, 0xC0, 0x0000, 0x0004, 0x00, buf); | ||
130 | /* --> seq17 */ | ||
131 | ARK3116_SND(serial, 17, 0xFE, 0x40, 0x0001, 0x0004); | ||
132 | |||
133 | /* <-- seq18 */ | ||
134 | ARK3116_RCV(serial, 18, 0xFE, 0xC0, 0x0000, 0x0004, 0x01, buf); | ||
135 | |||
136 | /* --> seq19 */ | ||
137 | ARK3116_SND(serial, 19, 0xFE, 0x40, 0x0003, 0x0004); | ||
138 | |||
139 | /* <-- seq20 */ | ||
140 | /* seems like serial port status info (RTS, CTS, ...) */ | ||
141 | /* returns modem control line status?! */ | ||
142 | ARK3116_RCV(serial, 20, 0xFE, 0xC0, 0x0000, 0x0006, 0xFF, buf); | ||
143 | |||
144 | /* set 9600 baud & do some init?! */ | ||
145 | ARK3116_SND(serial, 147, 0xFE, 0x40, 0x0083, 0x0003); | ||
146 | ARK3116_SND(serial, 148, 0xFE, 0x40, 0x0038, 0x0000); | ||
147 | ARK3116_SND(serial, 149, 0xFE, 0x40, 0x0001, 0x0001); | ||
148 | if (is_irda(serial)) | ||
149 | ARK3116_SND(serial, 1004, 0xFE, 0x40, 0x0000, 0x0009); | ||
150 | ARK3116_SND(serial, 150, 0xFE, 0x40, 0x0003, 0x0003); | ||
151 | ARK3116_RCV(serial, 151, 0xFE, 0xC0, 0x0000, 0x0004, 0x03, buf); | ||
152 | ARK3116_SND(serial, 152, 0xFE, 0x40, 0x0000, 0x0003); | ||
153 | ARK3116_RCV(serial, 153, 0xFE, 0xC0, 0x0000, 0x0003, 0x00, buf); | ||
154 | ARK3116_SND(serial, 154, 0xFE, 0x40, 0x0003, 0x0003); | ||
155 | 180 | ||
156 | kfree(buf); | 181 | /* setup for 9600 8N1 */ |
182 | priv->quot = calc_divisor(9600); | ||
183 | ark3116_write_reg(serial, UART_DLL, priv->quot & 0xff); | ||
184 | ark3116_write_reg(serial, UART_DLM, (priv->quot>>8) & 0xff); | ||
185 | |||
186 | priv->lcr = UART_LCR_WLEN8; | ||
187 | ark3116_write_reg(serial, UART_LCR, UART_LCR_WLEN8); | ||
188 | |||
189 | ark3116_write_reg(serial, 0xe, 0); | ||
190 | |||
191 | if (priv->irda) | ||
192 | ark3116_write_reg(serial, 0x9, 0); | ||
193 | |||
194 | dev_info(&serial->dev->dev, | ||
195 | "%s using %s mode\n", | ||
196 | KBUILD_MODNAME, | ||
197 | priv->irda ? "IrDA" : "RS232"); | ||
157 | return 0; | 198 | return 0; |
158 | } | 199 | } |
159 | 200 | ||
201 | static void ark3116_release(struct usb_serial *serial) | ||
202 | { | ||
203 | struct usb_serial_port *port = serial->port[0]; | ||
204 | struct ark3116_private *priv = usb_get_serial_port_data(port); | ||
205 | |||
206 | /* device is closed, so URBs and DMA should be down */ | ||
207 | |||
208 | usb_set_serial_port_data(port, NULL); | ||
209 | |||
210 | mutex_destroy(&priv->hw_lock); | ||
211 | |||
212 | kfree(priv); | ||
213 | } | ||
214 | |||
160 | static void ark3116_init_termios(struct tty_struct *tty) | 215 | static void ark3116_init_termios(struct tty_struct *tty) |
161 | { | 216 | { |
162 | struct ktermios *termios = tty->termios; | 217 | struct ktermios *termios = tty->termios; |
@@ -172,200 +227,189 @@ static void ark3116_set_termios(struct tty_struct *tty, | |||
172 | struct ktermios *old_termios) | 227 | struct ktermios *old_termios) |
173 | { | 228 | { |
174 | struct usb_serial *serial = port->serial; | 229 | struct usb_serial *serial = port->serial; |
230 | struct ark3116_private *priv = usb_get_serial_port_data(port); | ||
175 | struct ktermios *termios = tty->termios; | 231 | struct ktermios *termios = tty->termios; |
176 | unsigned int cflag = termios->c_cflag; | 232 | unsigned int cflag = termios->c_cflag; |
177 | int baud; | 233 | int bps = tty_get_baud_rate(tty); |
178 | int ark3116_baud; | 234 | int quot; |
179 | char *buf; | 235 | __u8 lcr, hcr, eval; |
180 | char config; | 236 | |
181 | 237 | /* set data bit count */ | |
182 | config = 0; | 238 | switch (cflag & CSIZE) { |
183 | 239 | case CS5: | |
184 | dbg("%s - port %d", __func__, port->number); | 240 | lcr = UART_LCR_WLEN5; |
241 | break; | ||
242 | case CS6: | ||
243 | lcr = UART_LCR_WLEN6; | ||
244 | break; | ||
245 | case CS7: | ||
246 | lcr = UART_LCR_WLEN7; | ||
247 | break; | ||
248 | default: | ||
249 | case CS8: | ||
250 | lcr = UART_LCR_WLEN8; | ||
251 | break; | ||
252 | } | ||
253 | if (cflag & CSTOPB) | ||
254 | lcr |= UART_LCR_STOP; | ||
255 | if (cflag & PARENB) | ||
256 | lcr |= UART_LCR_PARITY; | ||
257 | if (!(cflag & PARODD)) | ||
258 | lcr |= UART_LCR_EPAR; | ||
259 | #ifdef CMSPAR | ||
260 | if (cflag & CMSPAR) | ||
261 | lcr |= UART_LCR_SPAR; | ||
262 | #endif | ||
263 | /* handshake control */ | ||
264 | hcr = (cflag & CRTSCTS) ? 0x03 : 0x00; | ||
265 | |||
266 | /* calc baudrate */ | ||
267 | dbg("%s - setting bps to %d", __func__, bps); | ||
268 | eval = 0; | ||
269 | switch (bps) { | ||
270 | case 0: | ||
271 | quot = calc_divisor(9600); | ||
272 | break; | ||
273 | default: | ||
274 | if ((bps < 75) || (bps > 3000000)) | ||
275 | bps = 9600; | ||
276 | quot = calc_divisor(bps); | ||
277 | break; | ||
278 | case 460800: | ||
279 | eval = 1; | ||
280 | quot = calc_divisor(bps); | ||
281 | break; | ||
282 | case 921600: | ||
283 | eval = 2; | ||
284 | quot = calc_divisor(bps); | ||
285 | break; | ||
286 | } | ||
185 | 287 | ||
288 | /* Update state: synchronize */ | ||
289 | mutex_lock(&priv->hw_lock); | ||
186 | 290 | ||
187 | cflag = termios->c_cflag; | 291 | /* keep old LCR_SBC bit */ |
188 | termios->c_cflag &= ~(CMSPAR|CRTSCTS); | 292 | lcr |= (priv->lcr & UART_LCR_SBC); |
189 | 293 | ||
190 | buf = kmalloc(1, GFP_KERNEL); | 294 | dbg("%s - setting hcr:0x%02x,lcr:0x%02x,quot:%d", |
191 | if (!buf) { | 295 | __func__, hcr, lcr, quot); |
192 | dbg("error kmalloc"); | ||
193 | *termios = *old_termios; | ||
194 | return; | ||
195 | } | ||
196 | 296 | ||
197 | /* set data bit count (8/7/6/5) */ | 297 | /* handshake control */ |
198 | if (cflag & CSIZE) { | 298 | if (priv->hcr != hcr) { |
199 | switch (cflag & CSIZE) { | 299 | priv->hcr = hcr; |
200 | case CS5: | 300 | ark3116_write_reg(serial, 0x8, hcr); |
201 | config |= 0x00; | ||
202 | dbg("setting CS5"); | ||
203 | break; | ||
204 | case CS6: | ||
205 | config |= 0x01; | ||
206 | dbg("setting CS6"); | ||
207 | break; | ||
208 | case CS7: | ||
209 | config |= 0x02; | ||
210 | dbg("setting CS7"); | ||
211 | break; | ||
212 | default: | ||
213 | dbg("CSIZE was set but not CS5-CS8, using CS8!"); | ||
214 | /* fall through */ | ||
215 | case CS8: | ||
216 | config |= 0x03; | ||
217 | dbg("setting CS8"); | ||
218 | break; | ||
219 | } | ||
220 | } | 301 | } |
221 | 302 | ||
222 | /* set parity (NONE/EVEN/ODD) */ | 303 | /* baudrate */ |
223 | if (cflag & PARENB) { | 304 | if (priv->quot != quot) { |
224 | if (cflag & PARODD) { | 305 | priv->quot = quot; |
225 | config |= 0x08; | 306 | priv->lcr = lcr; /* need to write lcr anyway */ |
226 | dbg("setting parity to ODD"); | 307 | |
227 | } else { | 308 | /* disable DMA since transmit/receive is |
228 | config |= 0x18; | 309 | * shadowed by UART_DLL |
229 | dbg("setting parity to EVEN"); | 310 | */ |
230 | } | 311 | ark3116_write_reg(serial, UART_FCR, 0); |
231 | } else { | 312 | |
232 | dbg("setting parity to NONE"); | 313 | ark3116_write_reg(serial, UART_LCR, |
314 | lcr|UART_LCR_DLAB); | ||
315 | ark3116_write_reg(serial, UART_DLL, quot & 0xff); | ||
316 | ark3116_write_reg(serial, UART_DLM, (quot>>8) & 0xff); | ||
317 | |||
318 | /* restore lcr */ | ||
319 | ark3116_write_reg(serial, UART_LCR, lcr); | ||
320 | /* magic baudrate thingy: not sure what it does, | ||
321 | * but windows does this as well. | ||
322 | */ | ||
323 | ark3116_write_reg(serial, 0xe, eval); | ||
324 | |||
325 | /* enable DMA */ | ||
326 | ark3116_write_reg(serial, UART_FCR, UART_FCR_DMA_SELECT); | ||
327 | } else if (priv->lcr != lcr) { | ||
328 | priv->lcr = lcr; | ||
329 | ark3116_write_reg(serial, UART_LCR, lcr); | ||
233 | } | 330 | } |
234 | 331 | ||
235 | /* set stop bit (1/2) */ | 332 | mutex_unlock(&priv->hw_lock); |
236 | if (cflag & CSTOPB) { | ||
237 | config |= 0x04; | ||
238 | dbg("setting 2 stop bits"); | ||
239 | } else { | ||
240 | dbg("setting 1 stop bit"); | ||
241 | } | ||
242 | 333 | ||
243 | /* set baudrate */ | 334 | /* check for software flow control */ |
244 | baud = tty_get_baud_rate(tty); | 335 | if (I_IXOFF(tty) || I_IXON(tty)) { |
245 | 336 | dev_warn(&serial->dev->dev, | |
246 | switch (baud) { | 337 | "%s: don't know how to do software flow control\n", |
247 | case 75: | 338 | KBUILD_MODNAME); |
248 | case 150: | ||
249 | case 300: | ||
250 | case 600: | ||
251 | case 1200: | ||
252 | case 1800: | ||
253 | case 2400: | ||
254 | case 4800: | ||
255 | case 9600: | ||
256 | case 19200: | ||
257 | case 38400: | ||
258 | case 57600: | ||
259 | case 115200: | ||
260 | case 230400: | ||
261 | case 460800: | ||
262 | /* Report the resulting rate back to the caller */ | ||
263 | tty_encode_baud_rate(tty, baud, baud); | ||
264 | break; | ||
265 | /* set 9600 as default (if given baudrate is invalid for example) */ | ||
266 | default: | ||
267 | tty_encode_baud_rate(tty, 9600, 9600); | ||
268 | case 0: | ||
269 | baud = 9600; | ||
270 | } | 339 | } |
271 | 340 | ||
272 | /* | 341 | /* Don't rewrite B0 */ |
273 | * found by try'n'error, be careful, maybe there are other options | 342 | if (tty_termios_baud_rate(termios)) |
274 | * for multiplicator etc! (3.5 for example) | 343 | tty_termios_encode_baud_rate(termios, bps, bps); |
275 | */ | 344 | } |
276 | if (baud == 460800) | ||
277 | /* strange, for 460800 the formula is wrong | ||
278 | * if using round() then 9600baud is wrong) */ | ||
279 | ark3116_baud = 7; | ||
280 | else | ||
281 | ark3116_baud = 3000000 / baud; | ||
282 | |||
283 | /* ? */ | ||
284 | ARK3116_RCV(serial, 0, 0xFE, 0xC0, 0x0000, 0x0003, 0x03, buf); | ||
285 | |||
286 | /* offset = buf[0]; */ | ||
287 | /* offset = 0x03; */ | ||
288 | /* dbg("using 0x%04X as target for 0x0003:", 0x0080 + offset); */ | ||
289 | |||
290 | /* set baudrate */ | ||
291 | dbg("setting baudrate to %d (->reg=%d)", baud, ark3116_baud); | ||
292 | ARK3116_SND(serial, 147, 0xFE, 0x40, 0x0083, 0x0003); | ||
293 | ARK3116_SND(serial, 148, 0xFE, 0x40, | ||
294 | (ark3116_baud & 0x00FF), 0x0000); | ||
295 | ARK3116_SND(serial, 149, 0xFE, 0x40, | ||
296 | (ark3116_baud & 0xFF00) >> 8, 0x0001); | ||
297 | ARK3116_SND(serial, 150, 0xFE, 0x40, 0x0003, 0x0003); | ||
298 | |||
299 | /* ? */ | ||
300 | ARK3116_RCV(serial, 151, 0xFE, 0xC0, 0x0000, 0x0004, 0x03, buf); | ||
301 | ARK3116_SND(serial, 152, 0xFE, 0x40, 0x0000, 0x0003); | ||
302 | |||
303 | /* set data bit count, stop bit count & parity: */ | ||
304 | dbg("updating bit count, stop bit or parity (cfg=0x%02X)", config); | ||
305 | ARK3116_RCV(serial, 153, 0xFE, 0xC0, 0x0000, 0x0003, 0x00, buf); | ||
306 | ARK3116_SND(serial, 154, 0xFE, 0x40, config, 0x0003); | ||
307 | 345 | ||
308 | if (cflag & CRTSCTS) | 346 | static void ark3116_close(struct usb_serial_port *port) |
309 | dbg("CRTSCTS not supported by chipset?!"); | 347 | { |
348 | struct usb_serial *serial = port->serial; | ||
310 | 349 | ||
311 | /* TEST ARK3116_SND(154, 0xFE, 0x40, 0xFFFF, 0x0006); */ | 350 | if (serial->dev) { |
351 | /* disable DMA */ | ||
352 | ark3116_write_reg(serial, UART_FCR, 0); | ||
312 | 353 | ||
313 | kfree(buf); | 354 | /* deactivate interrupts */ |
355 | ark3116_write_reg(serial, UART_IER, 0); | ||
314 | 356 | ||
315 | return; | 357 | /* shutdown any bulk reads that might be going on */ |
358 | if (serial->num_bulk_out) | ||
359 | usb_kill_urb(port->write_urb); | ||
360 | if (serial->num_bulk_in) | ||
361 | usb_kill_urb(port->read_urb); | ||
362 | if (serial->num_interrupt_in) | ||
363 | usb_kill_urb(port->interrupt_in_urb); | ||
364 | } | ||
316 | } | 365 | } |
317 | 366 | ||
318 | static int ark3116_open(struct tty_struct *tty, struct usb_serial_port *port) | 367 | static int ark3116_open(struct tty_struct *tty, struct usb_serial_port *port) |
319 | { | 368 | { |
320 | struct ktermios tmp_termios; | 369 | struct ark3116_private *priv = usb_get_serial_port_data(port); |
321 | struct usb_serial *serial = port->serial; | 370 | struct usb_serial *serial = port->serial; |
322 | char *buf; | 371 | unsigned char *buf; |
323 | int result = 0; | 372 | int result; |
324 | |||
325 | dbg("%s - port %d", __func__, port->number); | ||
326 | 373 | ||
327 | buf = kmalloc(1, GFP_KERNEL); | 374 | buf = kmalloc(1, GFP_KERNEL); |
328 | if (!buf) { | 375 | if (buf == NULL) |
329 | dbg("error kmalloc -> out of mem?"); | ||
330 | return -ENOMEM; | 376 | return -ENOMEM; |
331 | } | ||
332 | 377 | ||
333 | result = usb_serial_generic_open(tty, port); | 378 | result = usb_serial_generic_open(tty, port); |
334 | if (result) | 379 | if (result) { |
380 | dbg("%s - usb_serial_generic_open failed: %d", | ||
381 | __func__, result); | ||
335 | goto err_out; | 382 | goto err_out; |
383 | } | ||
336 | 384 | ||
337 | /* open */ | 385 | /* setup termios */ |
338 | ARK3116_RCV(serial, 111, 0xFE, 0xC0, 0x0000, 0x0003, 0x02, buf); | 386 | if (tty) |
339 | 387 | ark3116_set_termios(tty, port, NULL); | |
340 | ARK3116_SND(serial, 112, 0xFE, 0x40, 0x0082, 0x0003); | ||
341 | ARK3116_SND(serial, 113, 0xFE, 0x40, 0x001A, 0x0000); | ||
342 | ARK3116_SND(serial, 114, 0xFE, 0x40, 0x0000, 0x0001); | ||
343 | ARK3116_SND(serial, 115, 0xFE, 0x40, 0x0002, 0x0003); | ||
344 | |||
345 | ARK3116_RCV(serial, 116, 0xFE, 0xC0, 0x0000, 0x0004, 0x03, buf); | ||
346 | ARK3116_SND(serial, 117, 0xFE, 0x40, 0x0002, 0x0004); | ||
347 | |||
348 | ARK3116_RCV(serial, 118, 0xFE, 0xC0, 0x0000, 0x0004, 0x02, buf); | ||
349 | ARK3116_SND(serial, 119, 0xFE, 0x40, 0x0000, 0x0004); | ||
350 | |||
351 | ARK3116_RCV(serial, 120, 0xFE, 0xC0, 0x0000, 0x0004, 0x00, buf); | ||
352 | 388 | ||
353 | ARK3116_SND(serial, 121, 0xFE, 0x40, 0x0001, 0x0004); | 389 | /* remove any data still left: also clears error state */ |
390 | ark3116_read_reg(serial, UART_RX, buf); | ||
354 | 391 | ||
355 | ARK3116_RCV(serial, 122, 0xFE, 0xC0, 0x0000, 0x0004, 0x01, buf); | 392 | /* read modem status */ |
393 | priv->msr = ark3116_read_reg(serial, UART_MSR, buf); | ||
394 | /* read line status */ | ||
395 | priv->lsr = ark3116_read_reg(serial, UART_LSR, buf); | ||
356 | 396 | ||
357 | ARK3116_SND(serial, 123, 0xFE, 0x40, 0x0003, 0x0004); | 397 | result = usb_submit_urb(port->interrupt_in_urb, GFP_KERNEL); |
398 | if (result) { | ||
399 | dev_err(&port->dev, "submit irq_in urb failed %d\n", | ||
400 | result); | ||
401 | ark3116_close(port); | ||
402 | goto err_out; | ||
403 | } | ||
358 | 404 | ||
359 | /* returns different values (control lines?!) */ | 405 | /* activate interrupts */ |
360 | ARK3116_RCV(serial, 124, 0xFE, 0xC0, 0x0000, 0x0006, 0xFF, buf); | 406 | ark3116_write_reg(port->serial, UART_IER, UART_IER_MSI|UART_IER_RLSI); |
361 | 407 | ||
362 | /* initialise termios */ | 408 | /* enable DMA */ |
363 | if (tty) | 409 | ark3116_write_reg(port->serial, UART_FCR, UART_FCR_DMA_SELECT); |
364 | ark3116_set_termios(tty, port, &tmp_termios); | ||
365 | 410 | ||
366 | err_out: | 411 | err_out: |
367 | kfree(buf); | 412 | kfree(buf); |
368 | |||
369 | return result; | 413 | return result; |
370 | } | 414 | } |
371 | 415 | ||
@@ -373,6 +417,7 @@ static int ark3116_ioctl(struct tty_struct *tty, struct file *file, | |||
373 | unsigned int cmd, unsigned long arg) | 417 | unsigned int cmd, unsigned long arg) |
374 | { | 418 | { |
375 | struct usb_serial_port *port = tty->driver_data; | 419 | struct usb_serial_port *port = tty->driver_data; |
420 | struct ark3116_private *priv = usb_get_serial_port_data(port); | ||
376 | struct serial_struct serstruct; | 421 | struct serial_struct serstruct; |
377 | void __user *user_arg = (void __user *)arg; | 422 | void __user *user_arg = (void __user *)arg; |
378 | 423 | ||
@@ -394,9 +439,48 @@ static int ark3116_ioctl(struct tty_struct *tty, struct file *file, | |||
394 | if (copy_from_user(&serstruct, user_arg, sizeof(serstruct))) | 439 | if (copy_from_user(&serstruct, user_arg, sizeof(serstruct))) |
395 | return -EFAULT; | 440 | return -EFAULT; |
396 | return 0; | 441 | return 0; |
397 | default: | 442 | case TIOCMIWAIT: |
398 | dbg("%s cmd 0x%04x not supported", __func__, cmd); | 443 | for (;;) { |
444 | struct async_icount prev = priv->icount; | ||
445 | interruptible_sleep_on(&priv->delta_msr_wait); | ||
446 | /* see if a signal did it */ | ||
447 | if (signal_pending(current)) | ||
448 | return -ERESTARTSYS; | ||
449 | if ((prev.rng == priv->icount.rng) && | ||
450 | (prev.dsr == priv->icount.dsr) && | ||
451 | (prev.dcd == priv->icount.dcd) && | ||
452 | (prev.cts == priv->icount.cts)) | ||
453 | return -EIO; | ||
454 | if ((arg & TIOCM_RNG && | ||
455 | (prev.rng != priv->icount.rng)) || | ||
456 | (arg & TIOCM_DSR && | ||
457 | (prev.dsr != priv->icount.dsr)) || | ||
458 | (arg & TIOCM_CD && | ||
459 | (prev.dcd != priv->icount.dcd)) || | ||
460 | (arg & TIOCM_CTS && | ||
461 | (prev.cts != priv->icount.cts))) | ||
462 | return 0; | ||
463 | } | ||
399 | break; | 464 | break; |
465 | case TIOCGICOUNT: { | ||
466 | struct serial_icounter_struct icount; | ||
467 | struct async_icount cnow = priv->icount; | ||
468 | memset(&icount, 0, sizeof(icount)); | ||
469 | icount.cts = cnow.cts; | ||
470 | icount.dsr = cnow.dsr; | ||
471 | icount.rng = cnow.rng; | ||
472 | icount.dcd = cnow.dcd; | ||
473 | icount.rx = cnow.rx; | ||
474 | icount.tx = cnow.tx; | ||
475 | icount.frame = cnow.frame; | ||
476 | icount.overrun = cnow.overrun; | ||
477 | icount.parity = cnow.parity; | ||
478 | icount.brk = cnow.brk; | ||
479 | icount.buf_overrun = cnow.buf_overrun; | ||
480 | if (copy_to_user(user_arg, &icount, sizeof(icount))) | ||
481 | return -EFAULT; | ||
482 | return 0; | ||
483 | } | ||
400 | } | 484 | } |
401 | 485 | ||
402 | return -ENOIOCTLCMD; | 486 | return -ENOIOCTLCMD; |
@@ -405,32 +489,273 @@ static int ark3116_ioctl(struct tty_struct *tty, struct file *file, | |||
405 | static int ark3116_tiocmget(struct tty_struct *tty, struct file *file) | 489 | static int ark3116_tiocmget(struct tty_struct *tty, struct file *file) |
406 | { | 490 | { |
407 | struct usb_serial_port *port = tty->driver_data; | 491 | struct usb_serial_port *port = tty->driver_data; |
408 | struct usb_serial *serial = port->serial; | 492 | struct ark3116_private *priv = usb_get_serial_port_data(port); |
409 | char *buf; | 493 | __u32 status; |
410 | char temp; | 494 | __u32 ctrl; |
495 | unsigned long flags; | ||
496 | |||
497 | mutex_lock(&priv->hw_lock); | ||
498 | ctrl = priv->mcr; | ||
499 | mutex_unlock(&priv->hw_lock); | ||
500 | |||
501 | spin_lock_irqsave(&priv->status_lock, flags); | ||
502 | status = priv->msr; | ||
503 | spin_unlock_irqrestore(&priv->status_lock, flags); | ||
504 | |||
505 | return (status & UART_MSR_DSR ? TIOCM_DSR : 0) | | ||
506 | (status & UART_MSR_CTS ? TIOCM_CTS : 0) | | ||
507 | (status & UART_MSR_RI ? TIOCM_RI : 0) | | ||
508 | (status & UART_MSR_DCD ? TIOCM_CD : 0) | | ||
509 | (ctrl & UART_MCR_DTR ? TIOCM_DTR : 0) | | ||
510 | (ctrl & UART_MCR_RTS ? TIOCM_RTS : 0) | | ||
511 | (ctrl & UART_MCR_OUT1 ? TIOCM_OUT1 : 0) | | ||
512 | (ctrl & UART_MCR_OUT2 ? TIOCM_OUT2 : 0); | ||
513 | } | ||
411 | 514 | ||
412 | /* seems like serial port status info (RTS, CTS, ...) is stored | 515 | static int ark3116_tiocmset(struct tty_struct *tty, struct file *file, |
413 | * in reg(?) 0x0006 | 516 | unsigned set, unsigned clr) |
414 | * pcb connection point 11 = GND -> sets bit4 of response | 517 | { |
415 | * pcb connection point 7 = GND -> sets bit6 of response | 518 | struct usb_serial_port *port = tty->driver_data; |
519 | struct ark3116_private *priv = usb_get_serial_port_data(port); | ||
520 | |||
521 | /* we need to take the mutex here, to make sure that the value | ||
522 | * in priv->mcr is actually the one that is in the hardware | ||
416 | */ | 523 | */ |
417 | 524 | ||
418 | buf = kmalloc(1, GFP_KERNEL); | 525 | mutex_lock(&priv->hw_lock); |
419 | if (!buf) { | 526 | |
420 | dbg("error kmalloc"); | 527 | if (set & TIOCM_RTS) |
421 | return -ENOMEM; | 528 | priv->mcr |= UART_MCR_RTS; |
529 | if (set & TIOCM_DTR) | ||
530 | priv->mcr |= UART_MCR_DTR; | ||
531 | if (set & TIOCM_OUT1) | ||
532 | priv->mcr |= UART_MCR_OUT1; | ||
533 | if (set & TIOCM_OUT2) | ||
534 | priv->mcr |= UART_MCR_OUT2; | ||
535 | if (clr & TIOCM_RTS) | ||
536 | priv->mcr &= ~UART_MCR_RTS; | ||
537 | if (clr & TIOCM_DTR) | ||
538 | priv->mcr &= ~UART_MCR_DTR; | ||
539 | if (clr & TIOCM_OUT1) | ||
540 | priv->mcr &= ~UART_MCR_OUT1; | ||
541 | if (clr & TIOCM_OUT2) | ||
542 | priv->mcr &= ~UART_MCR_OUT2; | ||
543 | |||
544 | ark3116_write_reg(port->serial, UART_MCR, priv->mcr); | ||
545 | |||
546 | mutex_unlock(&priv->hw_lock); | ||
547 | |||
548 | return 0; | ||
549 | } | ||
550 | |||
551 | static void ark3116_break_ctl(struct tty_struct *tty, int break_state) | ||
552 | { | ||
553 | struct usb_serial_port *port = tty->driver_data; | ||
554 | struct ark3116_private *priv = usb_get_serial_port_data(port); | ||
555 | |||
556 | /* LCR is also used for other things: protect access */ | ||
557 | mutex_lock(&priv->hw_lock); | ||
558 | |||
559 | if (break_state) | ||
560 | priv->lcr |= UART_LCR_SBC; | ||
561 | else | ||
562 | priv->lcr &= ~UART_LCR_SBC; | ||
563 | |||
564 | ark3116_write_reg(port->serial, UART_LCR, priv->lcr); | ||
565 | |||
566 | mutex_unlock(&priv->hw_lock); | ||
567 | } | ||
568 | |||
569 | static void ark3116_update_msr(struct usb_serial_port *port, __u8 msr) | ||
570 | { | ||
571 | struct ark3116_private *priv = usb_get_serial_port_data(port); | ||
572 | unsigned long flags; | ||
573 | |||
574 | spin_lock_irqsave(&priv->status_lock, flags); | ||
575 | priv->msr = msr; | ||
576 | spin_unlock_irqrestore(&priv->status_lock, flags); | ||
577 | |||
578 | if (msr & UART_MSR_ANY_DELTA) { | ||
579 | /* update input line counters */ | ||
580 | if (msr & UART_MSR_DCTS) | ||
581 | priv->icount.cts++; | ||
582 | if (msr & UART_MSR_DDSR) | ||
583 | priv->icount.dsr++; | ||
584 | if (msr & UART_MSR_DDCD) | ||
585 | priv->icount.dcd++; | ||
586 | if (msr & UART_MSR_TERI) | ||
587 | priv->icount.rng++; | ||
588 | wake_up_interruptible(&priv->delta_msr_wait); | ||
422 | } | 589 | } |
590 | } | ||
423 | 591 | ||
424 | /* read register */ | 592 | static void ark3116_update_lsr(struct usb_serial_port *port, __u8 lsr) |
425 | ARK3116_RCV_QUIET(serial, 0xFE, 0xC0, 0x0000, 0x0006, buf); | 593 | { |
426 | temp = buf[0]; | 594 | struct ark3116_private *priv = usb_get_serial_port_data(port); |
427 | kfree(buf); | 595 | unsigned long flags; |
596 | |||
597 | spin_lock_irqsave(&priv->status_lock, flags); | ||
598 | /* combine bits */ | ||
599 | priv->lsr |= lsr; | ||
600 | spin_unlock_irqrestore(&priv->status_lock, flags); | ||
601 | |||
602 | if (lsr&UART_LSR_BRK_ERROR_BITS) { | ||
603 | if (lsr & UART_LSR_BI) | ||
604 | priv->icount.brk++; | ||
605 | if (lsr & UART_LSR_FE) | ||
606 | priv->icount.frame++; | ||
607 | if (lsr & UART_LSR_PE) | ||
608 | priv->icount.parity++; | ||
609 | if (lsr & UART_LSR_OE) | ||
610 | priv->icount.overrun++; | ||
611 | } | ||
612 | } | ||
428 | 613 | ||
429 | /* i do not really know if bit4=CTS and bit6=DSR... just a | 614 | static void ark3116_read_int_callback(struct urb *urb) |
430 | * quick guess! | 615 | { |
431 | */ | 616 | struct usb_serial_port *port = urb->context; |
432 | return (temp & (1<<4) ? TIOCM_CTS : 0) | 617 | int status = urb->status; |
433 | | (temp & (1<<6) ? TIOCM_DSR : 0); | 618 | const __u8 *data = urb->transfer_buffer; |
619 | int result; | ||
620 | |||
621 | switch (status) { | ||
622 | case -ECONNRESET: | ||
623 | case -ENOENT: | ||
624 | case -ESHUTDOWN: | ||
625 | /* this urb is terminated, clean up */ | ||
626 | dbg("%s - urb shutting down with status: %d", | ||
627 | __func__, status); | ||
628 | return; | ||
629 | default: | ||
630 | dbg("%s - nonzero urb status received: %d", | ||
631 | __func__, status); | ||
632 | break; | ||
633 | case 0: /* success */ | ||
634 | /* discovered this by trail and error... */ | ||
635 | if ((urb->actual_length == 4) && (data[0] == 0xe8)) { | ||
636 | const __u8 id = data[1]&UART_IIR_ID; | ||
637 | dbg("%s: iir=%02x", __func__, data[1]); | ||
638 | if (id == UART_IIR_MSI) { | ||
639 | dbg("%s: msr=%02x", __func__, data[3]); | ||
640 | ark3116_update_msr(port, data[3]); | ||
641 | break; | ||
642 | } else if (id == UART_IIR_RLSI) { | ||
643 | dbg("%s: lsr=%02x", __func__, data[2]); | ||
644 | ark3116_update_lsr(port, data[2]); | ||
645 | break; | ||
646 | } | ||
647 | } | ||
648 | /* | ||
649 | * Not sure what this data meant... | ||
650 | */ | ||
651 | usb_serial_debug_data(debug, &port->dev, | ||
652 | __func__, | ||
653 | urb->actual_length, | ||
654 | urb->transfer_buffer); | ||
655 | break; | ||
656 | } | ||
657 | |||
658 | result = usb_submit_urb(urb, GFP_ATOMIC); | ||
659 | if (result) | ||
660 | dev_err(&urb->dev->dev, | ||
661 | "%s - Error %d submitting interrupt urb\n", | ||
662 | __func__, result); | ||
663 | } | ||
664 | |||
665 | |||
666 | /* Data comes in via the bulk (data) URB, erors/interrupts via the int URB. | ||
667 | * This means that we cannot be sure which data byte has an associated error | ||
668 | * condition, so we report an error for all data in the next bulk read. | ||
669 | * | ||
670 | * Actually, there might even be a window between the bulk data leaving the | ||
671 | * ark and reading/resetting the lsr in the read_bulk_callback where an | ||
672 | * interrupt for the next data block could come in. | ||
673 | * Without somekind of ordering on the ark, we would have to report the | ||
674 | * error for the next block of data as well... | ||
675 | * For now, let's pretend this can't happen. | ||
676 | */ | ||
677 | |||
678 | static void send_to_tty(struct tty_struct *tty, | ||
679 | const unsigned char *chars, | ||
680 | size_t size, char flag) | ||
681 | { | ||
682 | if (size == 0) | ||
683 | return; | ||
684 | if (flag == TTY_NORMAL) { | ||
685 | tty_insert_flip_string(tty, chars, size); | ||
686 | } else { | ||
687 | int i; | ||
688 | for (i = 0; i < size; ++i) | ||
689 | tty_insert_flip_char(tty, chars[i], flag); | ||
690 | } | ||
691 | } | ||
692 | |||
693 | static void ark3116_read_bulk_callback(struct urb *urb) | ||
694 | { | ||
695 | struct usb_serial_port *port = urb->context; | ||
696 | struct ark3116_private *priv = usb_get_serial_port_data(port); | ||
697 | const __u8 *data = urb->transfer_buffer; | ||
698 | int status = urb->status; | ||
699 | struct tty_struct *tty; | ||
700 | unsigned long flags; | ||
701 | int result; | ||
702 | char flag; | ||
703 | __u32 lsr; | ||
704 | |||
705 | switch (status) { | ||
706 | case -ECONNRESET: | ||
707 | case -ENOENT: | ||
708 | case -ESHUTDOWN: | ||
709 | /* this urb is terminated, clean up */ | ||
710 | dbg("%s - urb shutting down with status: %d", | ||
711 | __func__, status); | ||
712 | return; | ||
713 | default: | ||
714 | dbg("%s - nonzero urb status received: %d", | ||
715 | __func__, status); | ||
716 | break; | ||
717 | case 0: /* success */ | ||
718 | |||
719 | spin_lock_irqsave(&priv->status_lock, flags); | ||
720 | lsr = priv->lsr; | ||
721 | /* clear error bits */ | ||
722 | priv->lsr &= ~UART_LSR_BRK_ERROR_BITS; | ||
723 | spin_unlock_irqrestore(&priv->status_lock, flags); | ||
724 | |||
725 | if (unlikely(lsr & UART_LSR_BI)) | ||
726 | flag = TTY_BREAK; | ||
727 | else if (unlikely(lsr & UART_LSR_PE)) | ||
728 | flag = TTY_PARITY; | ||
729 | else if (unlikely(lsr & UART_LSR_FE)) | ||
730 | flag = TTY_FRAME; | ||
731 | else | ||
732 | flag = TTY_NORMAL; | ||
733 | |||
734 | tty = tty_port_tty_get(&port->port); | ||
735 | if (tty) { | ||
736 | tty_buffer_request_room(tty, urb->actual_length + 1); | ||
737 | /* overrun is special, not associated with a char */ | ||
738 | if (unlikely(lsr & UART_LSR_OE)) | ||
739 | tty_insert_flip_char(tty, 0, TTY_OVERRUN); | ||
740 | send_to_tty(tty, data, urb->actual_length, flag); | ||
741 | tty_flip_buffer_push(tty); | ||
742 | tty_kref_put(tty); | ||
743 | } | ||
744 | |||
745 | /* Throttle the device if requested by tty */ | ||
746 | spin_lock_irqsave(&port->lock, flags); | ||
747 | port->throttled = port->throttle_req; | ||
748 | if (port->throttled) { | ||
749 | spin_unlock_irqrestore(&port->lock, flags); | ||
750 | return; | ||
751 | } else | ||
752 | spin_unlock_irqrestore(&port->lock, flags); | ||
753 | } | ||
754 | /* Continue reading from device */ | ||
755 | result = usb_submit_urb(urb, GFP_ATOMIC); | ||
756 | if (result) | ||
757 | dev_err(&urb->dev->dev, "%s - failed resubmitting" | ||
758 | " read urb, error %d\n", __func__, result); | ||
434 | } | 759 | } |
435 | 760 | ||
436 | static struct usb_driver ark3116_driver = { | 761 | static struct usb_driver ark3116_driver = { |
@@ -450,11 +775,17 @@ static struct usb_serial_driver ark3116_device = { | |||
450 | .usb_driver = &ark3116_driver, | 775 | .usb_driver = &ark3116_driver, |
451 | .num_ports = 1, | 776 | .num_ports = 1, |
452 | .attach = ark3116_attach, | 777 | .attach = ark3116_attach, |
778 | .release = ark3116_release, | ||
453 | .set_termios = ark3116_set_termios, | 779 | .set_termios = ark3116_set_termios, |
454 | .init_termios = ark3116_init_termios, | 780 | .init_termios = ark3116_init_termios, |
455 | .ioctl = ark3116_ioctl, | 781 | .ioctl = ark3116_ioctl, |
456 | .tiocmget = ark3116_tiocmget, | 782 | .tiocmget = ark3116_tiocmget, |
783 | .tiocmset = ark3116_tiocmset, | ||
457 | .open = ark3116_open, | 784 | .open = ark3116_open, |
785 | .close = ark3116_close, | ||
786 | .break_ctl = ark3116_break_ctl, | ||
787 | .read_int_callback = ark3116_read_int_callback, | ||
788 | .read_bulk_callback = ark3116_read_bulk_callback, | ||
458 | }; | 789 | }; |
459 | 790 | ||
460 | static int __init ark3116_init(void) | 791 | static int __init ark3116_init(void) |
@@ -465,7 +796,12 @@ static int __init ark3116_init(void) | |||
465 | if (retval) | 796 | if (retval) |
466 | return retval; | 797 | return retval; |
467 | retval = usb_register(&ark3116_driver); | 798 | retval = usb_register(&ark3116_driver); |
468 | if (retval) | 799 | if (retval == 0) { |
800 | printk(KERN_INFO "%s:" | ||
801 | DRIVER_VERSION ":" | ||
802 | DRIVER_DESC "\n", | ||
803 | KBUILD_MODNAME); | ||
804 | } else | ||
469 | usb_serial_deregister(&ark3116_device); | 805 | usb_serial_deregister(&ark3116_device); |
470 | return retval; | 806 | return retval; |
471 | } | 807 | } |
@@ -480,6 +816,109 @@ module_init(ark3116_init); | |||
480 | module_exit(ark3116_exit); | 816 | module_exit(ark3116_exit); |
481 | MODULE_LICENSE("GPL"); | 817 | MODULE_LICENSE("GPL"); |
482 | 818 | ||
819 | MODULE_AUTHOR(DRIVER_AUTHOR); | ||
820 | MODULE_DESCRIPTION(DRIVER_DESC); | ||
821 | |||
483 | module_param(debug, bool, S_IRUGO | S_IWUSR); | 822 | module_param(debug, bool, S_IRUGO | S_IWUSR); |
484 | MODULE_PARM_DESC(debug, "Debug enabled or not"); | 823 | MODULE_PARM_DESC(debug, "Enable debug"); |
485 | 824 | ||
825 | /* | ||
826 | * The following describes what I learned from studying the old | ||
827 | * ark3116.c driver, disassembling the windows driver, and some lucky | ||
828 | * guesses. Since I do not have any datasheet or other | ||
829 | * documentation, inaccuracies are almost guaranteed. | ||
830 | * | ||
831 | * Some specs for the ARK3116 can be found here: | ||
832 | * http://web.archive.org/web/20060318000438/ | ||
833 | * www.arkmicro.com/en/products/view.php?id=10 | ||
834 | * On that page, 2 GPIO pins are mentioned: I assume these are the | ||
835 | * OUT1 and OUT2 pins of the UART, so I added support for those | ||
836 | * through the MCR. Since the pins are not available on my hardware, | ||
837 | * I could not verify this. | ||
838 | * Also, it states there is "on-chip hardware flow control". I have | ||
839 | * discovered how to enable that. Unfortunately, I do not know how to | ||
840 | * enable XON/XOFF (software) flow control, which would need support | ||
841 | * from the chip as well to work. Because of the wording on the web | ||
842 | * page there is a real possibility the chip simply does not support | ||
843 | * software flow control. | ||
844 | * | ||
845 | * I got my ark3116 as part of a mobile phone adapter cable. On the | ||
846 | * PCB, the following numbered contacts are present: | ||
847 | * | ||
848 | * 1:- +5V | ||
849 | * 2:o DTR | ||
850 | * 3:i RX | ||
851 | * 4:i DCD | ||
852 | * 5:o RTS | ||
853 | * 6:o TX | ||
854 | * 7:i RI | ||
855 | * 8:i DSR | ||
856 | * 10:- 0V | ||
857 | * 11:i CTS | ||
858 | * | ||
859 | * On my chip, all signals seem to be 3.3V, but 5V tolerant. But that | ||
860 | * may be different for the one you have ;-). | ||
861 | * | ||
862 | * The windows driver limits the registers to 0-F, so I assume there | ||
863 | * are actually 16 present on the device. | ||
864 | * | ||
865 | * On an UART interrupt, 4 bytes of data come in on the interrupt | ||
866 | * endpoint. The bytes are 0xe8 IIR LSR MSR. | ||
867 | * | ||
868 | * The baudrate seems to be generated from the 12MHz crystal, using | ||
869 | * 4-times subsampling. So quot=12e6/(4*baud). Also see description | ||
870 | * of register E. | ||
871 | * | ||
872 | * Registers 0-7: | ||
873 | * These seem to be the same as for a regular 16450. The FCR is set | ||
874 | * to UART_FCR_DMA_SELECT (0x8), I guess to enable transfers between | ||
875 | * the UART and the USB bridge/DMA engine. | ||
876 | * | ||
877 | * Register 8: | ||
878 | * By trial and error, I found out that bit 0 enables hardware CTS, | ||
879 | * stopping TX when CTS is +5V. Bit 1 does the same for RTS, making | ||
880 | * RTS +5V when the 3116 cannot transfer the data to the USB bus | ||
881 | * (verified by disabling the reading URB). Note that as far as I can | ||
882 | * tell, the windows driver does NOT use this, so there might be some | ||
883 | * hardware bug or something. | ||
884 | * | ||
885 | * According to a patch provided here | ||
886 | * (http://lkml.org/lkml/2009/7/26/56), the ARK3116 can also be used | ||
887 | * as an IrDA dongle. Since I do not have such a thing, I could not | ||
888 | * investigate that aspect. However, I can speculate ;-). | ||
889 | * | ||
890 | * - IrDA encodes data differently than RS232. Most likely, one of | ||
891 | * the bits in registers 9..E enables the IR ENDEC (encoder/decoder). | ||
892 | * - Depending on the IR transceiver, the input and output need to be | ||
893 | * inverted, so there are probably bits for that as well. | ||
894 | * - IrDA is half-duplex, so there should be a bit for selecting that. | ||
895 | * | ||
896 | * This still leaves at least two registers unaccounted for. Perhaps | ||
897 | * The chip can do XON/XOFF or CRC in HW? | ||
898 | * | ||
899 | * Register 9: | ||
900 | * Set to 0x00 for IrDA, when the baudrate is initialised. | ||
901 | * | ||
902 | * Register A: | ||
903 | * Set to 0x01 for IrDA, at init. | ||
904 | * | ||
905 | * Register B: | ||
906 | * Set to 0x01 for IrDA, 0x00 for RS232, at init. | ||
907 | * | ||
908 | * Register C: | ||
909 | * Set to 00 for IrDA, at init. | ||
910 | * | ||
911 | * Register D: | ||
912 | * Set to 0x41 for IrDA, at init. | ||
913 | * | ||
914 | * Register E: | ||
915 | * Somekind of baudrate override. The windows driver seems to set | ||
916 | * this to 0x00 for normal baudrates, 0x01 for 460800, 0x02 for 921600. | ||
917 | * Since 460800 and 921600 cannot be obtained by dividing 3MHz by an integer, | ||
918 | * it could be somekind of subdivisor thingy. | ||
919 | * However,it does not seem to do anything: selecting 921600 (divisor 3, | ||
920 | * reg E=2), still gets 1 MHz. I also checked if registers 9, C or F would | ||
921 | * work, but they don't. | ||
922 | * | ||
923 | * Register F: unknown | ||
924 | */ | ||
diff --git a/drivers/usb/serial/ftdi_sio.c b/drivers/usb/serial/ftdi_sio.c index ebcc6d0e2e91..f99498fca99a 100644 --- a/drivers/usb/serial/ftdi_sio.c +++ b/drivers/usb/serial/ftdi_sio.c | |||
@@ -598,6 +598,20 @@ static struct usb_device_id id_table_combined [] = { | |||
598 | { USB_DEVICE(BANDB_VID, BANDB_USOTL4_PID) }, | 598 | { USB_DEVICE(BANDB_VID, BANDB_USOTL4_PID) }, |
599 | { USB_DEVICE(BANDB_VID, BANDB_USTL4_PID) }, | 599 | { USB_DEVICE(BANDB_VID, BANDB_USTL4_PID) }, |
600 | { USB_DEVICE(BANDB_VID, BANDB_USO9ML2_PID) }, | 600 | { USB_DEVICE(BANDB_VID, BANDB_USO9ML2_PID) }, |
601 | { USB_DEVICE(BANDB_VID, BANDB_USOPTL4_PID) }, | ||
602 | { USB_DEVICE(BANDB_VID, BANDB_USPTL4_PID) }, | ||
603 | { USB_DEVICE(BANDB_VID, BANDB_USO9ML2DR_2_PID) }, | ||
604 | { USB_DEVICE(BANDB_VID, BANDB_USO9ML2DR_PID) }, | ||
605 | { USB_DEVICE(BANDB_VID, BANDB_USOPTL4DR2_PID) }, | ||
606 | { USB_DEVICE(BANDB_VID, BANDB_USOPTL4DR_PID) }, | ||
607 | { USB_DEVICE(BANDB_VID, BANDB_485USB9F_2W_PID) }, | ||
608 | { USB_DEVICE(BANDB_VID, BANDB_485USB9F_4W_PID) }, | ||
609 | { USB_DEVICE(BANDB_VID, BANDB_232USB9M_PID) }, | ||
610 | { USB_DEVICE(BANDB_VID, BANDB_485USBTB_2W_PID) }, | ||
611 | { USB_DEVICE(BANDB_VID, BANDB_485USBTB_4W_PID) }, | ||
612 | { USB_DEVICE(BANDB_VID, BANDB_TTL5USB9M_PID) }, | ||
613 | { USB_DEVICE(BANDB_VID, BANDB_TTL3USB9M_PID) }, | ||
614 | { USB_DEVICE(BANDB_VID, BANDB_ZZ_PROG1_USB_PID) }, | ||
601 | { USB_DEVICE(FTDI_VID, EVER_ECO_PRO_CDS) }, | 615 | { USB_DEVICE(FTDI_VID, EVER_ECO_PRO_CDS) }, |
602 | { USB_DEVICE(FTDI_VID, FTDI_4N_GALAXY_DE_1_PID) }, | 616 | { USB_DEVICE(FTDI_VID, FTDI_4N_GALAXY_DE_1_PID) }, |
603 | { USB_DEVICE(FTDI_VID, FTDI_4N_GALAXY_DE_2_PID) }, | 617 | { USB_DEVICE(FTDI_VID, FTDI_4N_GALAXY_DE_2_PID) }, |
@@ -2195,15 +2209,21 @@ static void ftdi_set_termios(struct tty_struct *tty, | |||
2195 | 2209 | ||
2196 | /* Set number of data bits, parity, stop bits */ | 2210 | /* Set number of data bits, parity, stop bits */ |
2197 | 2211 | ||
2198 | termios->c_cflag &= ~CMSPAR; | ||
2199 | |||
2200 | urb_value = 0; | 2212 | urb_value = 0; |
2201 | urb_value |= (cflag & CSTOPB ? FTDI_SIO_SET_DATA_STOP_BITS_2 : | 2213 | urb_value |= (cflag & CSTOPB ? FTDI_SIO_SET_DATA_STOP_BITS_2 : |
2202 | FTDI_SIO_SET_DATA_STOP_BITS_1); | 2214 | FTDI_SIO_SET_DATA_STOP_BITS_1); |
2203 | urb_value |= (cflag & PARENB ? | 2215 | if (cflag & PARENB) { |
2204 | (cflag & PARODD ? FTDI_SIO_SET_DATA_PARITY_ODD : | 2216 | if (cflag & CMSPAR) |
2205 | FTDI_SIO_SET_DATA_PARITY_EVEN) : | 2217 | urb_value |= cflag & PARODD ? |
2206 | FTDI_SIO_SET_DATA_PARITY_NONE); | 2218 | FTDI_SIO_SET_DATA_PARITY_MARK : |
2219 | FTDI_SIO_SET_DATA_PARITY_SPACE; | ||
2220 | else | ||
2221 | urb_value |= cflag & PARODD ? | ||
2222 | FTDI_SIO_SET_DATA_PARITY_ODD : | ||
2223 | FTDI_SIO_SET_DATA_PARITY_EVEN; | ||
2224 | } else { | ||
2225 | urb_value |= FTDI_SIO_SET_DATA_PARITY_NONE; | ||
2226 | } | ||
2207 | if (cflag & CSIZE) { | 2227 | if (cflag & CSIZE) { |
2208 | switch (cflag & CSIZE) { | 2228 | switch (cflag & CSIZE) { |
2209 | case CS5: urb_value |= 5; dbg("Setting CS5"); break; | 2229 | case CS5: urb_value |= 5; dbg("Setting CS5"); break; |
diff --git a/drivers/usb/serial/ftdi_sio.h b/drivers/usb/serial/ftdi_sio.h index 6f31e0d71898..4586a24fafb0 100644 --- a/drivers/usb/serial/ftdi_sio.h +++ b/drivers/usb/serial/ftdi_sio.h | |||
@@ -662,6 +662,20 @@ | |||
662 | #define BANDB_USOTL4_PID 0xAC01 /* USOTL4 Isolated RS-485 Converter */ | 662 | #define BANDB_USOTL4_PID 0xAC01 /* USOTL4 Isolated RS-485 Converter */ |
663 | #define BANDB_USTL4_PID 0xAC02 /* USTL4 RS-485 Converter */ | 663 | #define BANDB_USTL4_PID 0xAC02 /* USTL4 RS-485 Converter */ |
664 | #define BANDB_USO9ML2_PID 0xAC03 /* USO9ML2 Isolated RS-232 Converter */ | 664 | #define BANDB_USO9ML2_PID 0xAC03 /* USO9ML2 Isolated RS-232 Converter */ |
665 | #define BANDB_USOPTL4_PID 0xAC11 | ||
666 | #define BANDB_USPTL4_PID 0xAC12 | ||
667 | #define BANDB_USO9ML2DR_2_PID 0xAC16 | ||
668 | #define BANDB_USO9ML2DR_PID 0xAC17 | ||
669 | #define BANDB_USOPTL4DR2_PID 0xAC18 /* USOPTL4R-2 2-port Isolated RS-232 Converter */ | ||
670 | #define BANDB_USOPTL4DR_PID 0xAC19 | ||
671 | #define BANDB_485USB9F_2W_PID 0xAC25 | ||
672 | #define BANDB_485USB9F_4W_PID 0xAC26 | ||
673 | #define BANDB_232USB9M_PID 0xAC27 | ||
674 | #define BANDB_485USBTB_2W_PID 0xAC33 | ||
675 | #define BANDB_485USBTB_4W_PID 0xAC34 | ||
676 | #define BANDB_TTL5USB9M_PID 0xAC49 | ||
677 | #define BANDB_TTL3USB9M_PID 0xAC50 | ||
678 | #define BANDB_ZZ_PROG1_USB_PID 0xBA02 | ||
665 | 679 | ||
666 | /* | 680 | /* |
667 | * RM Michaelides CANview USB (http://www.rmcan.com) | 681 | * RM Michaelides CANview USB (http://www.rmcan.com) |
diff --git a/drivers/usb/serial/mos7840.c b/drivers/usb/serial/mos7840.c index f11abf52be7d..485fa9c5b107 100644 --- a/drivers/usb/serial/mos7840.c +++ b/drivers/usb/serial/mos7840.c | |||
@@ -121,8 +121,14 @@ | |||
121 | * moschip_id_table_combined | 121 | * moschip_id_table_combined |
122 | */ | 122 | */ |
123 | #define USB_VENDOR_ID_BANDB 0x0856 | 123 | #define USB_VENDOR_ID_BANDB 0x0856 |
124 | #define BANDB_DEVICE_ID_USOPTL4_4 0xAC44 | 124 | #define BANDB_DEVICE_ID_USO9ML2_2 0xAC22 |
125 | #define BANDB_DEVICE_ID_USO9ML2_4 0xAC24 | ||
126 | #define BANDB_DEVICE_ID_US9ML2_2 0xAC29 | ||
127 | #define BANDB_DEVICE_ID_US9ML2_4 0xAC30 | ||
128 | #define BANDB_DEVICE_ID_USPTL4_2 0xAC31 | ||
129 | #define BANDB_DEVICE_ID_USPTL4_4 0xAC32 | ||
125 | #define BANDB_DEVICE_ID_USOPTL4_2 0xAC42 | 130 | #define BANDB_DEVICE_ID_USOPTL4_2 0xAC42 |
131 | #define BANDB_DEVICE_ID_USOPTL4_4 0xAC44 | ||
126 | 132 | ||
127 | /* This driver also supports | 133 | /* This driver also supports |
128 | * ATEN UC2324 device using Moschip MCS7840 | 134 | * ATEN UC2324 device using Moschip MCS7840 |
@@ -177,8 +183,14 @@ | |||
177 | static struct usb_device_id moschip_port_id_table[] = { | 183 | static struct usb_device_id moschip_port_id_table[] = { |
178 | {USB_DEVICE(USB_VENDOR_ID_MOSCHIP, MOSCHIP_DEVICE_ID_7840)}, | 184 | {USB_DEVICE(USB_VENDOR_ID_MOSCHIP, MOSCHIP_DEVICE_ID_7840)}, |
179 | {USB_DEVICE(USB_VENDOR_ID_MOSCHIP, MOSCHIP_DEVICE_ID_7820)}, | 185 | {USB_DEVICE(USB_VENDOR_ID_MOSCHIP, MOSCHIP_DEVICE_ID_7820)}, |
180 | {USB_DEVICE(USB_VENDOR_ID_BANDB, BANDB_DEVICE_ID_USOPTL4_4)}, | 186 | {USB_DEVICE(USB_VENDOR_ID_BANDB, BANDB_DEVICE_ID_USO9ML2_2)}, |
187 | {USB_DEVICE(USB_VENDOR_ID_BANDB, BANDB_DEVICE_ID_USO9ML2_4)}, | ||
188 | {USB_DEVICE(USB_VENDOR_ID_BANDB, BANDB_DEVICE_ID_US9ML2_2)}, | ||
189 | {USB_DEVICE(USB_VENDOR_ID_BANDB, BANDB_DEVICE_ID_US9ML2_4)}, | ||
190 | {USB_DEVICE(USB_VENDOR_ID_BANDB, BANDB_DEVICE_ID_USPTL4_2)}, | ||
191 | {USB_DEVICE(USB_VENDOR_ID_BANDB, BANDB_DEVICE_ID_USPTL4_4)}, | ||
181 | {USB_DEVICE(USB_VENDOR_ID_BANDB, BANDB_DEVICE_ID_USOPTL4_2)}, | 192 | {USB_DEVICE(USB_VENDOR_ID_BANDB, BANDB_DEVICE_ID_USOPTL4_2)}, |
193 | {USB_DEVICE(USB_VENDOR_ID_BANDB, BANDB_DEVICE_ID_USOPTL4_4)}, | ||
182 | {USB_DEVICE(USB_VENDOR_ID_ATENINTL, ATENINTL_DEVICE_ID_UC2324)}, | 194 | {USB_DEVICE(USB_VENDOR_ID_ATENINTL, ATENINTL_DEVICE_ID_UC2324)}, |
183 | {USB_DEVICE(USB_VENDOR_ID_ATENINTL, ATENINTL_DEVICE_ID_UC2322)}, | 195 | {USB_DEVICE(USB_VENDOR_ID_ATENINTL, ATENINTL_DEVICE_ID_UC2322)}, |
184 | {} /* terminating entry */ | 196 | {} /* terminating entry */ |
@@ -187,8 +199,14 @@ static struct usb_device_id moschip_port_id_table[] = { | |||
187 | static __devinitdata struct usb_device_id moschip_id_table_combined[] = { | 199 | static __devinitdata struct usb_device_id moschip_id_table_combined[] = { |
188 | {USB_DEVICE(USB_VENDOR_ID_MOSCHIP, MOSCHIP_DEVICE_ID_7840)}, | 200 | {USB_DEVICE(USB_VENDOR_ID_MOSCHIP, MOSCHIP_DEVICE_ID_7840)}, |
189 | {USB_DEVICE(USB_VENDOR_ID_MOSCHIP, MOSCHIP_DEVICE_ID_7820)}, | 201 | {USB_DEVICE(USB_VENDOR_ID_MOSCHIP, MOSCHIP_DEVICE_ID_7820)}, |
190 | {USB_DEVICE(USB_VENDOR_ID_BANDB, BANDB_DEVICE_ID_USOPTL4_4)}, | 202 | {USB_DEVICE(USB_VENDOR_ID_BANDB, BANDB_DEVICE_ID_USO9ML2_2)}, |
203 | {USB_DEVICE(USB_VENDOR_ID_BANDB, BANDB_DEVICE_ID_USO9ML2_4)}, | ||
204 | {USB_DEVICE(USB_VENDOR_ID_BANDB, BANDB_DEVICE_ID_US9ML2_2)}, | ||
205 | {USB_DEVICE(USB_VENDOR_ID_BANDB, BANDB_DEVICE_ID_US9ML2_4)}, | ||
206 | {USB_DEVICE(USB_VENDOR_ID_BANDB, BANDB_DEVICE_ID_USPTL4_2)}, | ||
207 | {USB_DEVICE(USB_VENDOR_ID_BANDB, BANDB_DEVICE_ID_USPTL4_4)}, | ||
191 | {USB_DEVICE(USB_VENDOR_ID_BANDB, BANDB_DEVICE_ID_USOPTL4_2)}, | 208 | {USB_DEVICE(USB_VENDOR_ID_BANDB, BANDB_DEVICE_ID_USOPTL4_2)}, |
209 | {USB_DEVICE(USB_VENDOR_ID_BANDB, BANDB_DEVICE_ID_USOPTL4_4)}, | ||
192 | {USB_DEVICE(USB_VENDOR_ID_ATENINTL, ATENINTL_DEVICE_ID_UC2324)}, | 210 | {USB_DEVICE(USB_VENDOR_ID_ATENINTL, ATENINTL_DEVICE_ID_UC2324)}, |
193 | {USB_DEVICE(USB_VENDOR_ID_ATENINTL, ATENINTL_DEVICE_ID_UC2322)}, | 211 | {USB_DEVICE(USB_VENDOR_ID_ATENINTL, ATENINTL_DEVICE_ID_UC2322)}, |
194 | {} /* terminating entry */ | 212 | {} /* terminating entry */ |
diff --git a/drivers/usb/serial/option.c b/drivers/usb/serial/option.c index 0577e4b61114..9a2b903492ec 100644 --- a/drivers/usb/serial/option.c +++ b/drivers/usb/serial/option.c | |||
@@ -580,12 +580,48 @@ static struct usb_device_id option_ids[] = { | |||
580 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0086, 0xff, 0xff, 0xff) }, | 580 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0086, 0xff, 0xff, 0xff) }, |
581 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x2002, 0xff, 0xff, 0xff) }, | 581 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x2002, 0xff, 0xff, 0xff) }, |
582 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x2003, 0xff, 0xff, 0xff) }, | 582 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x2003, 0xff, 0xff, 0xff) }, |
583 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0104, 0xff, 0xff, 0xff) }, | ||
584 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0106, 0xff, 0xff, 0xff) }, | ||
585 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0108, 0xff, 0xff, 0xff) }, | ||
586 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0113, 0xff, 0xff, 0xff) }, | ||
587 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0117, 0xff, 0xff, 0xff) }, | ||
588 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0118, 0xff, 0xff, 0xff) }, | ||
589 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0121, 0xff, 0xff, 0xff) }, | ||
590 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0122, 0xff, 0xff, 0xff) }, | ||
591 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0123, 0xff, 0xff, 0xff) }, | ||
592 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0124, 0xff, 0xff, 0xff) }, | ||
593 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0125, 0xff, 0xff, 0xff) }, | ||
594 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0126, 0xff, 0xff, 0xff) }, | ||
595 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0128, 0xff, 0xff, 0xff) }, | ||
596 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0142, 0xff, 0xff, 0xff) }, | ||
597 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0143, 0xff, 0xff, 0xff) }, | ||
598 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0144, 0xff, 0xff, 0xff) }, | ||
599 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0145, 0xff, 0xff, 0xff) }, | ||
600 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0146, 0xff, 0xff, 0xff) }, | ||
601 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0147, 0xff, 0xff, 0xff) }, | ||
602 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0148, 0xff, 0xff, 0xff) }, | ||
603 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0149, 0xff, 0xff, 0xff) }, | ||
604 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0150, 0xff, 0xff, 0xff) }, | ||
605 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0151, 0xff, 0xff, 0xff) }, | ||
606 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0152, 0xff, 0xff, 0xff) }, | ||
607 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0153, 0xff, 0xff, 0xff) }, | ||
608 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0154, 0xff, 0xff, 0xff) }, | ||
609 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0155, 0xff, 0xff, 0xff) }, | ||
610 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0156, 0xff, 0xff, 0xff) }, | ||
611 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0157, 0xff, 0xff, 0xff) }, | ||
612 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0158, 0xff, 0xff, 0xff) }, | ||
613 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0159, 0xff, 0xff, 0xff) }, | ||
614 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0160, 0xff, 0xff, 0xff) }, | ||
615 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0161, 0xff, 0xff, 0xff) }, | ||
616 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0162, 0xff, 0xff, 0xff) }, | ||
583 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0014, 0xff, 0xff, 0xff) }, /* ZTE CDMA products */ | 617 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0014, 0xff, 0xff, 0xff) }, /* ZTE CDMA products */ |
584 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0027, 0xff, 0xff, 0xff) }, | 618 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0027, 0xff, 0xff, 0xff) }, |
585 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0059, 0xff, 0xff, 0xff) }, | 619 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0059, 0xff, 0xff, 0xff) }, |
586 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0060, 0xff, 0xff, 0xff) }, | 620 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0060, 0xff, 0xff, 0xff) }, |
587 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0070, 0xff, 0xff, 0xff) }, | 621 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0070, 0xff, 0xff, 0xff) }, |
588 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0073, 0xff, 0xff, 0xff) }, | 622 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0073, 0xff, 0xff, 0xff) }, |
623 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0130, 0xff, 0xff, 0xff) }, | ||
624 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0141, 0xff, 0xff, 0xff) }, | ||
589 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, ZTE_PRODUCT_CDMA_TECH, 0xff, 0xff, 0xff) }, | 625 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, ZTE_PRODUCT_CDMA_TECH, 0xff, 0xff, 0xff) }, |
590 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, ZTE_PRODUCT_AC8710, 0xff, 0xff, 0xff) }, | 626 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, ZTE_PRODUCT_AC8710, 0xff, 0xff, 0xff) }, |
591 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, ZTE_PRODUCT_AC2726, 0xff, 0xff, 0xff) }, | 627 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, ZTE_PRODUCT_AC2726, 0xff, 0xff, 0xff) }, |
@@ -599,6 +635,7 @@ static struct usb_device_id option_ids[] = { | |||
599 | { USB_DEVICE(TOSHIBA_VENDOR_ID, TOSHIBA_PRODUCT_G450) }, | 635 | { USB_DEVICE(TOSHIBA_VENDOR_ID, TOSHIBA_PRODUCT_G450) }, |
600 | { USB_DEVICE(TOSHIBA_VENDOR_ID, TOSHIBA_PRODUCT_HSDPA_MINICARD ) }, /* Toshiba 3G HSDPA == Novatel Expedite EU870D MiniCard */ | 636 | { USB_DEVICE(TOSHIBA_VENDOR_ID, TOSHIBA_PRODUCT_HSDPA_MINICARD ) }, /* Toshiba 3G HSDPA == Novatel Expedite EU870D MiniCard */ |
601 | { USB_DEVICE(ALINK_VENDOR_ID, 0x9000) }, | 637 | { USB_DEVICE(ALINK_VENDOR_ID, 0x9000) }, |
638 | { USB_DEVICE(ALINK_VENDOR_ID, 0xce16) }, | ||
602 | { USB_DEVICE_AND_INTERFACE_INFO(ALINK_VENDOR_ID, ALINK_PRODUCT_3GU, 0xff, 0xff, 0xff) }, | 639 | { USB_DEVICE_AND_INTERFACE_INFO(ALINK_VENDOR_ID, ALINK_PRODUCT_3GU, 0xff, 0xff, 0xff) }, |
603 | { USB_DEVICE(ALCATEL_VENDOR_ID, ALCATEL_PRODUCT_X060S) }, | 640 | { USB_DEVICE(ALCATEL_VENDOR_ID, ALCATEL_PRODUCT_X060S) }, |
604 | { USB_DEVICE(AIRPLUS_VENDOR_ID, AIRPLUS_PRODUCT_MCD650) }, | 641 | { USB_DEVICE(AIRPLUS_VENDOR_ID, AIRPLUS_PRODUCT_MCD650) }, |
@@ -1312,7 +1349,7 @@ static int option_suspend(struct usb_serial *serial, pm_message_t message) | |||
1312 | 1349 | ||
1313 | dbg("%s entered", __func__); | 1350 | dbg("%s entered", __func__); |
1314 | 1351 | ||
1315 | if (serial->dev->auto_pm) { | 1352 | if (message.event & PM_EVENT_AUTO) { |
1316 | spin_lock_irq(&intfdata->susp_lock); | 1353 | spin_lock_irq(&intfdata->susp_lock); |
1317 | b = intfdata->in_flight; | 1354 | b = intfdata->in_flight; |
1318 | spin_unlock_irq(&intfdata->susp_lock); | 1355 | spin_unlock_irq(&intfdata->susp_lock); |
diff --git a/drivers/usb/serial/sierra.c b/drivers/usb/serial/sierra.c index 5019325ba25d..ac1b6449fb6a 100644 --- a/drivers/usb/serial/sierra.c +++ b/drivers/usb/serial/sierra.c | |||
@@ -16,8 +16,9 @@ | |||
16 | Portions based on the option driver by Matthias Urlichs <smurf@smurf.noris.de> | 16 | Portions based on the option driver by Matthias Urlichs <smurf@smurf.noris.de> |
17 | Whom based his on the Keyspan driver by Hugh Blemings <hugh@blemings.org> | 17 | Whom based his on the Keyspan driver by Hugh Blemings <hugh@blemings.org> |
18 | */ | 18 | */ |
19 | 19 | /* Uncomment to log function calls */ | |
20 | #define DRIVER_VERSION "v.1.3.8" | 20 | /* #define DEBUG */ |
21 | #define DRIVER_VERSION "v.1.7.16" | ||
21 | #define DRIVER_AUTHOR "Kevin Lloyd, Elina Pasheva, Matthew Safar, Rory Filer" | 22 | #define DRIVER_AUTHOR "Kevin Lloyd, Elina Pasheva, Matthew Safar, Rory Filer" |
22 | #define DRIVER_DESC "USB Driver for Sierra Wireless USB modems" | 23 | #define DRIVER_DESC "USB Driver for Sierra Wireless USB modems" |
23 | 24 | ||
@@ -33,8 +34,10 @@ | |||
33 | #define SWIMS_USB_REQUEST_SetPower 0x00 | 34 | #define SWIMS_USB_REQUEST_SetPower 0x00 |
34 | #define SWIMS_USB_REQUEST_SetNmea 0x07 | 35 | #define SWIMS_USB_REQUEST_SetNmea 0x07 |
35 | 36 | ||
36 | #define N_IN_URB 8 | 37 | #define N_IN_URB_HM 8 |
37 | #define N_OUT_URB 64 | 38 | #define N_OUT_URB_HM 64 |
39 | #define N_IN_URB 4 | ||
40 | #define N_OUT_URB 4 | ||
38 | #define IN_BUFLEN 4096 | 41 | #define IN_BUFLEN 4096 |
39 | 42 | ||
40 | #define MAX_TRANSFER (PAGE_SIZE - 512) | 43 | #define MAX_TRANSFER (PAGE_SIZE - 512) |
@@ -124,6 +127,23 @@ static int is_blacklisted(const u8 ifnum, | |||
124 | return 0; | 127 | return 0; |
125 | } | 128 | } |
126 | 129 | ||
130 | static int is_himemory(const u8 ifnum, | ||
131 | const struct sierra_iface_info *himemorylist) | ||
132 | { | ||
133 | const u8 *info; | ||
134 | int i; | ||
135 | |||
136 | if (himemorylist) { | ||
137 | info = himemorylist->ifaceinfo; | ||
138 | |||
139 | for (i=0; i < himemorylist->infolen; i++) { | ||
140 | if (info[i] == ifnum) | ||
141 | return 1; | ||
142 | } | ||
143 | } | ||
144 | return 0; | ||
145 | } | ||
146 | |||
127 | static int sierra_calc_interface(struct usb_serial *serial) | 147 | static int sierra_calc_interface(struct usb_serial *serial) |
128 | { | 148 | { |
129 | int interface; | 149 | int interface; |
@@ -186,6 +206,20 @@ static int sierra_probe(struct usb_serial *serial, | |||
186 | return result; | 206 | return result; |
187 | } | 207 | } |
188 | 208 | ||
209 | /* interfaces with higher memory requirements */ | ||
210 | static const u8 hi_memory_typeA_ifaces[] = { 0, 2 }; | ||
211 | static const struct sierra_iface_info typeA_interface_list = { | ||
212 | .infolen = ARRAY_SIZE(hi_memory_typeA_ifaces), | ||
213 | .ifaceinfo = hi_memory_typeA_ifaces, | ||
214 | }; | ||
215 | |||
216 | static const u8 hi_memory_typeB_ifaces[] = { 3, 4, 5, 6 }; | ||
217 | static const struct sierra_iface_info typeB_interface_list = { | ||
218 | .infolen = ARRAY_SIZE(hi_memory_typeB_ifaces), | ||
219 | .ifaceinfo = hi_memory_typeB_ifaces, | ||
220 | }; | ||
221 | |||
222 | /* 'blacklist' of interfaces not served by this driver */ | ||
189 | static const u8 direct_ip_non_serial_ifaces[] = { 7, 8, 9, 10, 11 }; | 223 | static const u8 direct_ip_non_serial_ifaces[] = { 7, 8, 9, 10, 11 }; |
190 | static const struct sierra_iface_info direct_ip_interface_blacklist = { | 224 | static const struct sierra_iface_info direct_ip_interface_blacklist = { |
191 | .infolen = ARRAY_SIZE(direct_ip_non_serial_ifaces), | 225 | .infolen = ARRAY_SIZE(direct_ip_non_serial_ifaces), |
@@ -286,8 +320,10 @@ struct sierra_port_private { | |||
286 | struct usb_anchor active; | 320 | struct usb_anchor active; |
287 | struct usb_anchor delayed; | 321 | struct usb_anchor delayed; |
288 | 322 | ||
323 | int num_out_urbs; | ||
324 | int num_in_urbs; | ||
289 | /* Input endpoints and buffers for this port */ | 325 | /* Input endpoints and buffers for this port */ |
290 | struct urb *in_urbs[N_IN_URB]; | 326 | struct urb *in_urbs[N_IN_URB_HM]; |
291 | 327 | ||
292 | /* Settings for the port */ | 328 | /* Settings for the port */ |
293 | int rts_state; /* Handshaking pins (outputs) */ | 329 | int rts_state; /* Handshaking pins (outputs) */ |
@@ -460,7 +496,7 @@ static int sierra_write(struct tty_struct *tty, struct usb_serial_port *port, | |||
460 | spin_lock_irqsave(&portdata->lock, flags); | 496 | spin_lock_irqsave(&portdata->lock, flags); |
461 | dev_dbg(&port->dev, "%s - outstanding_urbs: %d\n", __func__, | 497 | dev_dbg(&port->dev, "%s - outstanding_urbs: %d\n", __func__, |
462 | portdata->outstanding_urbs); | 498 | portdata->outstanding_urbs); |
463 | if (portdata->outstanding_urbs > N_OUT_URB) { | 499 | if (portdata->outstanding_urbs > portdata->num_out_urbs) { |
464 | spin_unlock_irqrestore(&portdata->lock, flags); | 500 | spin_unlock_irqrestore(&portdata->lock, flags); |
465 | dev_dbg(&port->dev, "%s - write limit hit\n", __func__); | 501 | dev_dbg(&port->dev, "%s - write limit hit\n", __func__); |
466 | return 0; | 502 | return 0; |
@@ -665,7 +701,7 @@ static int sierra_write_room(struct tty_struct *tty) | |||
665 | /* try to give a good number back based on if we have any free urbs at | 701 | /* try to give a good number back based on if we have any free urbs at |
666 | * this point in time */ | 702 | * this point in time */ |
667 | spin_lock_irqsave(&portdata->lock, flags); | 703 | spin_lock_irqsave(&portdata->lock, flags); |
668 | if (portdata->outstanding_urbs > N_OUT_URB * 2 / 3) { | 704 | if (portdata->outstanding_urbs > (portdata->num_out_urbs * 2) / 3) { |
669 | spin_unlock_irqrestore(&portdata->lock, flags); | 705 | spin_unlock_irqrestore(&portdata->lock, flags); |
670 | dev_dbg(&port->dev, "%s - write limit hit\n", __func__); | 706 | dev_dbg(&port->dev, "%s - write limit hit\n", __func__); |
671 | return 0; | 707 | return 0; |
@@ -680,7 +716,7 @@ static void sierra_stop_rx_urbs(struct usb_serial_port *port) | |||
680 | int i; | 716 | int i; |
681 | struct sierra_port_private *portdata = usb_get_serial_port_data(port); | 717 | struct sierra_port_private *portdata = usb_get_serial_port_data(port); |
682 | 718 | ||
683 | for (i = 0; i < ARRAY_SIZE(portdata->in_urbs); i++) | 719 | for (i = 0; i < portdata->num_in_urbs; i++) |
684 | usb_kill_urb(portdata->in_urbs[i]); | 720 | usb_kill_urb(portdata->in_urbs[i]); |
685 | 721 | ||
686 | usb_kill_urb(port->interrupt_in_urb); | 722 | usb_kill_urb(port->interrupt_in_urb); |
@@ -695,7 +731,7 @@ static int sierra_submit_rx_urbs(struct usb_serial_port *port, gfp_t mem_flags) | |||
695 | struct sierra_port_private *portdata = usb_get_serial_port_data(port); | 731 | struct sierra_port_private *portdata = usb_get_serial_port_data(port); |
696 | 732 | ||
697 | ok_cnt = 0; | 733 | ok_cnt = 0; |
698 | for (i = 0; i < ARRAY_SIZE(portdata->in_urbs); i++) { | 734 | for (i = 0; i < portdata->num_in_urbs; i++) { |
699 | urb = portdata->in_urbs[i]; | 735 | urb = portdata->in_urbs[i]; |
700 | if (!urb) | 736 | if (!urb) |
701 | continue; | 737 | continue; |
@@ -791,7 +827,7 @@ static void sierra_close(struct usb_serial_port *port) | |||
791 | /* Stop reading urbs */ | 827 | /* Stop reading urbs */ |
792 | sierra_stop_rx_urbs(port); | 828 | sierra_stop_rx_urbs(port); |
793 | /* .. and release them */ | 829 | /* .. and release them */ |
794 | for (i = 0; i < N_IN_URB; i++) { | 830 | for (i = 0; i < portdata->num_in_urbs; i++) { |
795 | sierra_release_urb(portdata->in_urbs[i]); | 831 | sierra_release_urb(portdata->in_urbs[i]); |
796 | portdata->in_urbs[i] = NULL; | 832 | portdata->in_urbs[i] = NULL; |
797 | } | 833 | } |
@@ -818,7 +854,7 @@ static int sierra_open(struct tty_struct *tty, struct usb_serial_port *port) | |||
818 | 854 | ||
819 | 855 | ||
820 | endpoint = port->bulk_in_endpointAddress; | 856 | endpoint = port->bulk_in_endpointAddress; |
821 | for (i = 0; i < ARRAY_SIZE(portdata->in_urbs); i++) { | 857 | for (i = 0; i < portdata->num_in_urbs; i++) { |
822 | urb = sierra_setup_urb(serial, endpoint, USB_DIR_IN, port, | 858 | urb = sierra_setup_urb(serial, endpoint, USB_DIR_IN, port, |
823 | IN_BUFLEN, GFP_KERNEL, | 859 | IN_BUFLEN, GFP_KERNEL, |
824 | sierra_indat_callback); | 860 | sierra_indat_callback); |
@@ -869,7 +905,9 @@ static int sierra_startup(struct usb_serial *serial) | |||
869 | { | 905 | { |
870 | struct usb_serial_port *port; | 906 | struct usb_serial_port *port; |
871 | struct sierra_port_private *portdata; | 907 | struct sierra_port_private *portdata; |
908 | struct sierra_iface_info *himemoryp = NULL; | ||
872 | int i; | 909 | int i; |
910 | u8 ifnum; | ||
873 | 911 | ||
874 | dev_dbg(&serial->dev->dev, "%s\n", __func__); | 912 | dev_dbg(&serial->dev->dev, "%s\n", __func__); |
875 | 913 | ||
@@ -886,13 +924,40 @@ static int sierra_startup(struct usb_serial *serial) | |||
886 | portdata = kzalloc(sizeof(*portdata), GFP_KERNEL); | 924 | portdata = kzalloc(sizeof(*portdata), GFP_KERNEL); |
887 | if (!portdata) { | 925 | if (!portdata) { |
888 | dev_dbg(&port->dev, "%s: kmalloc for " | 926 | dev_dbg(&port->dev, "%s: kmalloc for " |
889 | "sierra_port_private (%d) failed!.\n", | 927 | "sierra_port_private (%d) failed!\n", |
890 | __func__, i); | 928 | __func__, i); |
891 | return -ENOMEM; | 929 | return -ENOMEM; |
892 | } | 930 | } |
893 | spin_lock_init(&portdata->lock); | 931 | spin_lock_init(&portdata->lock); |
894 | init_usb_anchor(&portdata->active); | 932 | init_usb_anchor(&portdata->active); |
895 | init_usb_anchor(&portdata->delayed); | 933 | init_usb_anchor(&portdata->delayed); |
934 | ifnum = i; | ||
935 | /* Assume low memory requirements */ | ||
936 | portdata->num_out_urbs = N_OUT_URB; | ||
937 | portdata->num_in_urbs = N_IN_URB; | ||
938 | |||
939 | /* Determine actual memory requirements */ | ||
940 | if (serial->num_ports == 1) { | ||
941 | /* Get interface number for composite device */ | ||
942 | ifnum = sierra_calc_interface(serial); | ||
943 | himemoryp = | ||
944 | (struct sierra_iface_info *)&typeB_interface_list; | ||
945 | if (is_himemory(ifnum, himemoryp)) { | ||
946 | portdata->num_out_urbs = N_OUT_URB_HM; | ||
947 | portdata->num_in_urbs = N_IN_URB_HM; | ||
948 | } | ||
949 | } | ||
950 | else { | ||
951 | himemoryp = | ||
952 | (struct sierra_iface_info *)&typeA_interface_list; | ||
953 | if (is_himemory(i, himemoryp)) { | ||
954 | portdata->num_out_urbs = N_OUT_URB_HM; | ||
955 | portdata->num_in_urbs = N_IN_URB_HM; | ||
956 | } | ||
957 | } | ||
958 | dev_dbg(&serial->dev->dev, | ||
959 | "Memory usage (urbs) interface #%d, in=%d, out=%d\n", | ||
960 | ifnum,portdata->num_in_urbs, portdata->num_out_urbs ); | ||
896 | /* Set the port private data pointer */ | 961 | /* Set the port private data pointer */ |
897 | usb_set_serial_port_data(port, portdata); | 962 | usb_set_serial_port_data(port, portdata); |
898 | } | 963 | } |
@@ -940,7 +1005,7 @@ static int sierra_suspend(struct usb_serial *serial, pm_message_t message) | |||
940 | struct sierra_intf_private *intfdata; | 1005 | struct sierra_intf_private *intfdata; |
941 | int b; | 1006 | int b; |
942 | 1007 | ||
943 | if (serial->dev->auto_pm) { | 1008 | if (message.event & PM_EVENT_AUTO) { |
944 | intfdata = serial->private; | 1009 | intfdata = serial->private; |
945 | spin_lock_irq(&intfdata->susp_lock); | 1010 | spin_lock_irq(&intfdata->susp_lock); |
946 | b = intfdata->in_flight; | 1011 | b = intfdata->in_flight; |