aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb/serial/ark3116.c
diff options
context:
space:
mode:
authorJeff Garzik <jeff@garzik.org>2006-09-27 18:13:53 -0400
committerJeff Garzik <jeff@garzik.org>2006-09-27 18:13:53 -0400
commitaebb1153ac54ddbbd3d3f0481a193f4bf0ead53b (patch)
tree57425aa83c8bed5b41af7e3408024fe1f2fdded9 /drivers/usb/serial/ark3116.c
parent022e7a12b6aa11a11de4d708fe8606c9a6734b37 (diff)
parenta77c64c1a641950626181b4857abb701d8f38ccc (diff)
Merge branch 'master' into upstream
Diffstat (limited to 'drivers/usb/serial/ark3116.c')
-rw-r--r--drivers/usb/serial/ark3116.c233
1 files changed, 130 insertions, 103 deletions
diff --git a/drivers/usb/serial/ark3116.c b/drivers/usb/serial/ark3116.c
index 970d9ef0a7a5..ca52f12f0e24 100644
--- a/drivers/usb/serial/ark3116.c
+++ b/drivers/usb/serial/ark3116.c
@@ -1,4 +1,7 @@
1/* 1/*
2 * Copyright (C) 2006
3 * Simon Schulz (ark3116_driver <at> auctionant.de)
4 *
2 * ark3116 5 * ark3116
3 * - implements a driver for the arkmicro ark3116 chipset (vendor=0x6547, 6 * - implements a driver for the arkmicro ark3116 chipset (vendor=0x6547,
4 * productid=0x0232) (used in a datacable called KQ-U8A) 7 * productid=0x0232) (used in a datacable called KQ-U8A)
@@ -8,8 +11,6 @@
8 * 11 *
9 * - based on logs created by usbsnoopy 12 * - based on logs created by usbsnoopy
10 * 13 *
11 * Author : Simon Schulz [ark3116_driver<AT>auctionant.de]
12 *
13 * This program is free software; you can redistribute it and/or modify it 14 * This program is free software; you can redistribute it and/or modify it
14 * under the terms of the GNU General Public License as published by the 15 * under the terms of the GNU General Public License as published by the
15 * Free Software Foundation; either version 2 of the License, or (at your 16 * Free Software Foundation; either version 2 of the License, or (at your
@@ -22,6 +23,8 @@
22#include <linux/module.h> 23#include <linux/module.h>
23#include <linux/usb.h> 24#include <linux/usb.h>
24#include <linux/usb/serial.h> 25#include <linux/usb/serial.h>
26#include <linux/serial.h>
27#include <asm/uaccess.h>
25 28
26 29
27static int debug; 30static int debug;
@@ -43,10 +46,10 @@ static inline void ARK3116_SND(struct usb_serial *serial, int seq,
43{ 46{
44 int result; 47 int result;
45 result = usb_control_msg(serial->dev, 48 result = usb_control_msg(serial->dev,
46 usb_sndctrlpipe(serial->dev,0), 49 usb_sndctrlpipe(serial->dev, 0),
47 request, requesttype, value, index, 50 request, requesttype, value, index,
48 NULL,0x00, 1000); 51 NULL, 0x00, 1000);
49 dbg("%03d > ok",seq); 52 dbg("%03d > ok", seq);
50} 53}
51 54
52static inline void ARK3116_RCV(struct usb_serial *serial, int seq, 55static inline void ARK3116_RCV(struct usb_serial *serial, int seq,
@@ -56,27 +59,25 @@ static inline void ARK3116_RCV(struct usb_serial *serial, int seq,
56{ 59{
57 int result; 60 int result;
58 result = usb_control_msg(serial->dev, 61 result = usb_control_msg(serial->dev,
59 usb_rcvctrlpipe(serial->dev,0), 62 usb_rcvctrlpipe(serial->dev, 0),
60 request, requesttype, value, index, 63 request, requesttype, value, index,
61 buf, 0x0000001, 1000); 64 buf, 0x0000001, 1000);
62 if (result) 65 if (result)
63 dbg("%03d < %d bytes [0x%02X]",seq, result, buf[0]); 66 dbg("%03d < %d bytes [0x%02X]", seq, result, buf[0]);
64 else 67 else
65 dbg("%03d < 0 bytes", seq); 68 dbg("%03d < 0 bytes", seq);
66} 69}
67 70
68
69static inline void ARK3116_RCV_QUIET(struct usb_serial *serial, 71static inline void ARK3116_RCV_QUIET(struct usb_serial *serial,
70 __u8 request, __u8 requesttype, 72 __u8 request, __u8 requesttype,
71 __u16 value, __u16 index, char *buf) 73 __u16 value, __u16 index, char *buf)
72{ 74{
73 usb_control_msg(serial->dev, 75 usb_control_msg(serial->dev,
74 usb_rcvctrlpipe(serial->dev,0), 76 usb_rcvctrlpipe(serial->dev, 0),
75 request, requesttype, value, index, 77 request, requesttype, value, index,
76 buf, 0x0000001, 1000); 78 buf, 0x0000001, 1000);
77} 79}
78 80
79
80static int ark3116_attach(struct usb_serial *serial) 81static int ark3116_attach(struct usb_serial *serial)
81{ 82{
82 char *buf; 83 char *buf;
@@ -84,10 +85,10 @@ static int ark3116_attach(struct usb_serial *serial)
84 int i; 85 int i;
85 86
86 for (i = 0; i < serial->num_ports; ++i) { 87 for (i = 0; i < serial->num_ports; ++i) {
87 priv = kmalloc (sizeof (struct ark3116_private), GFP_KERNEL); 88 priv = kmalloc(sizeof (struct ark3116_private), GFP_KERNEL);
88 if (!priv) 89 if (!priv)
89 goto cleanup; 90 goto cleanup;
90 memset (priv, 0x00, sizeof (struct ark3116_private)); 91 memset(priv, 0x00, sizeof (struct ark3116_private));
91 spin_lock_init(&priv->lock); 92 spin_lock_init(&priv->lock);
92 93
93 usb_set_serial_port_data(serial->port[i], priv); 94 usb_set_serial_port_data(serial->port[i], priv);
@@ -95,63 +96,62 @@ static int ark3116_attach(struct usb_serial *serial)
95 96
96 buf = kmalloc(1, GFP_KERNEL); 97 buf = kmalloc(1, GFP_KERNEL);
97 if (!buf) { 98 if (!buf) {
98 dbg("error kmalloc -> out of mem ?"); 99 dbg("error kmalloc -> out of mem?");
99 goto cleanup; 100 goto cleanup;
100 } 101 }
101 102
102 /* 3 */ 103 /* 3 */
103 ARK3116_SND(serial, 3,0xFE,0x40,0x0008,0x0002); 104 ARK3116_SND(serial, 3, 0xFE, 0x40, 0x0008, 0x0002);
104 ARK3116_SND(serial, 4,0xFE,0x40,0x0008,0x0001); 105 ARK3116_SND(serial, 4, 0xFE, 0x40, 0x0008, 0x0001);
105 ARK3116_SND(serial, 5,0xFE,0x40,0x0000,0x0008); 106 ARK3116_SND(serial, 5, 0xFE, 0x40, 0x0000, 0x0008);
106 ARK3116_SND(serial, 6,0xFE,0x40,0x0000,0x000B); 107 ARK3116_SND(serial, 6, 0xFE, 0x40, 0x0000, 0x000B);
107 108
108 /* <-- seq7 */ 109 /* <-- seq7 */
109 ARK3116_RCV(serial, 7,0xFE,0xC0,0x0000,0x0003, 0x00, buf); 110 ARK3116_RCV(serial, 7, 0xFE, 0xC0, 0x0000, 0x0003, 0x00, buf);
110 ARK3116_SND(serial, 8,0xFE,0x40,0x0080,0x0003); 111 ARK3116_SND(serial, 8, 0xFE, 0x40, 0x0080, 0x0003);
111 ARK3116_SND(serial, 9,0xFE,0x40,0x001A,0x0000); 112 ARK3116_SND(serial, 9, 0xFE, 0x40, 0x001A, 0x0000);
112 ARK3116_SND(serial,10,0xFE,0x40,0x0000,0x0001); 113 ARK3116_SND(serial, 10, 0xFE, 0x40, 0x0000, 0x0001);
113 ARK3116_SND(serial,11,0xFE,0x40,0x0000,0x0003); 114 ARK3116_SND(serial, 11, 0xFE, 0x40, 0x0000, 0x0003);
114 115
115 /* <-- seq12 */ 116 /* <-- seq12 */
116 ARK3116_RCV(serial,12,0xFE,0xC0,0x0000,0x0004, 0x00, buf); 117 ARK3116_RCV(serial, 12, 0xFE, 0xC0, 0x0000, 0x0004, 0x00, buf);
117 ARK3116_SND(serial,13,0xFE,0x40,0x0000,0x0004); 118 ARK3116_SND(serial, 13, 0xFE, 0x40, 0x0000, 0x0004);
118 119
119 /* 14 */ 120 /* 14 */
120 ARK3116_RCV(serial,14,0xFE,0xC0,0x0000,0x0004, 0x00, buf); 121 ARK3116_RCV(serial, 14, 0xFE, 0xC0, 0x0000, 0x0004, 0x00, buf);
121 ARK3116_SND(serial,15,0xFE,0x40,0x0000,0x0004); 122 ARK3116_SND(serial, 15, 0xFE, 0x40, 0x0000, 0x0004);
122 123
123 /* 16 */ 124 /* 16 */
124 ARK3116_RCV(serial,16,0xFE,0xC0,0x0000,0x0004, 0x00, buf); 125 ARK3116_RCV(serial, 16, 0xFE, 0xC0, 0x0000, 0x0004, 0x00, buf);
125 /* --> seq17 */ 126 /* --> seq17 */
126 ARK3116_SND(serial,17,0xFE,0x40,0x0001,0x0004); 127 ARK3116_SND(serial, 17, 0xFE, 0x40, 0x0001, 0x0004);
127 128
128 /* <-- seq18 */ 129 /* <-- seq18 */
129 ARK3116_RCV(serial,18,0xFE,0xC0,0x0000,0x0004, 0x01, buf); 130 ARK3116_RCV(serial, 18, 0xFE, 0xC0, 0x0000, 0x0004, 0x01, buf);
130 131
131 /* --> seq19 */ 132 /* --> seq19 */
132 ARK3116_SND(serial,19,0xFE,0x40,0x0003,0x0004); 133 ARK3116_SND(serial, 19, 0xFE, 0x40, 0x0003, 0x0004);
133
134 134
135 /* <-- seq20 */ 135 /* <-- seq20 */
136 /* seems like serial port status info (RTS, CTS,...) */ 136 /* seems like serial port status info (RTS, CTS, ...) */
137 /* returns modem control line status ?! */ 137 /* returns modem control line status?! */
138 ARK3116_RCV(serial,20,0xFE,0xC0,0x0000,0x0006, 0xFF, buf); 138 ARK3116_RCV(serial, 20, 0xFE, 0xC0, 0x0000, 0x0006, 0xFF, buf);
139 139
140 /* set 9600 baud & do some init ?! */ 140 /* set 9600 baud & do some init?! */
141 ARK3116_SND(serial,147,0xFE,0x40,0x0083,0x0003); 141 ARK3116_SND(serial, 147, 0xFE, 0x40, 0x0083, 0x0003);
142 ARK3116_SND(serial,148,0xFE,0x40,0x0038,0x0000); 142 ARK3116_SND(serial, 148, 0xFE, 0x40, 0x0038, 0x0000);
143 ARK3116_SND(serial,149,0xFE,0x40,0x0001,0x0001); 143 ARK3116_SND(serial, 149, 0xFE, 0x40, 0x0001, 0x0001);
144 ARK3116_SND(serial,150,0xFE,0x40,0x0003,0x0003); 144 ARK3116_SND(serial, 150, 0xFE, 0x40, 0x0003, 0x0003);
145 ARK3116_RCV(serial,151,0xFE,0xC0,0x0000,0x0004,0x03, buf); 145 ARK3116_RCV(serial, 151, 0xFE, 0xC0, 0x0000, 0x0004, 0x03, buf);
146 ARK3116_SND(serial,152,0xFE,0x40,0x0000,0x0003); 146 ARK3116_SND(serial, 152, 0xFE, 0x40, 0x0000, 0x0003);
147 ARK3116_RCV(serial,153,0xFE,0xC0,0x0000,0x0003,0x00, buf); 147 ARK3116_RCV(serial, 153, 0xFE, 0xC0, 0x0000, 0x0003, 0x00, buf);
148 ARK3116_SND(serial,154,0xFE,0x40,0x0003,0x0003); 148 ARK3116_SND(serial, 154, 0xFE, 0x40, 0x0003, 0x0003);
149 149
150 kfree(buf); 150 kfree(buf);
151 return(0); 151 return 0;
152 152
153cleanup: 153cleanup:
154 for (--i; i>=0; --i) 154 for (--i; i >= 0; --i)
155 usb_set_serial_port_data(serial->port[i], NULL); 155 usb_set_serial_port_data(serial->port[i], NULL);
156 return -ENOMEM; 156 return -ENOMEM;
157} 157}
@@ -180,7 +180,8 @@ static void ark3116_set_termios(struct usb_serial_port *port,
180 spin_lock_irqsave(&priv->lock, flags); 180 spin_lock_irqsave(&priv->lock, flags);
181 if (!priv->termios_initialized) { 181 if (!priv->termios_initialized) {
182 *(port->tty->termios) = tty_std_termios; 182 *(port->tty->termios) = tty_std_termios;
183 port->tty->termios->c_cflag = B9600 | CS8 | CREAD | HUPCL | CLOCAL; 183 port->tty->termios->c_cflag = B9600 | CS8
184 | CREAD | HUPCL | CLOCAL;
184 priv->termios_initialized = 1; 185 priv->termios_initialized = 1;
185 } 186 }
186 spin_unlock_irqrestore(&priv->lock, flags); 187 spin_unlock_irqrestore(&priv->lock, flags);
@@ -204,8 +205,8 @@ static void ark3116_set_termios(struct usb_serial_port *port,
204 } 205 }
205 206
206 /* set data bit count (8/7/6/5) */ 207 /* set data bit count (8/7/6/5) */
207 if (cflag & CSIZE){ 208 if (cflag & CSIZE) {
208 switch (cflag & CSIZE){ 209 switch (cflag & CSIZE) {
209 case CS5: 210 case CS5:
210 config |= 0x00; 211 config |= 0x00;
211 dbg("setting CS5"); 212 dbg("setting CS5");
@@ -219,7 +220,8 @@ static void ark3116_set_termios(struct usb_serial_port *port,
219 dbg("setting CS7"); 220 dbg("setting CS7");
220 break; 221 break;
221 default: 222 default:
222 err ("CSIZE was set but not CS5-CS8, using CS8!"); 223 err("CSIZE was set but not CS5-CS8, using CS8!");
224 /* fall through */
223 case CS8: 225 case CS8:
224 config |= 0x03; 226 config |= 0x03;
225 dbg("setting CS8"); 227 dbg("setting CS8");
@@ -227,8 +229,8 @@ static void ark3116_set_termios(struct usb_serial_port *port,
227 } 229 }
228 } 230 }
229 231
230 /* set parity (NONE,EVEN,ODD) */ 232 /* set parity (NONE/EVEN/ODD) */
231 if (cflag & PARENB){ 233 if (cflag & PARENB) {
232 if (cflag & PARODD) { 234 if (cflag & PARODD) {
233 config |= 0x08; 235 config |= 0x08;
234 dbg("setting parity to ODD"); 236 dbg("setting parity to ODD");
@@ -240,20 +242,19 @@ static void ark3116_set_termios(struct usb_serial_port *port,
240 dbg("setting parity to NONE"); 242 dbg("setting parity to NONE");
241 } 243 }
242 244
243 /* SET STOPBIT (1/2) */ 245 /* set stop bit (1/2) */
244 if (cflag & CSTOPB) { 246 if (cflag & CSTOPB) {
245 config |= 0x04; 247 config |= 0x04;
246 dbg ("setting 2 stop bits"); 248 dbg("setting 2 stop bits");
247 } else { 249 } else {
248 dbg ("setting 1 stop bit"); 250 dbg("setting 1 stop bit");
249 } 251 }
250 252
251 253 /* set baudrate */
252 /* set baudrate: */
253 baud = 0; 254 baud = 0;
254 switch (cflag & CBAUD){ 255 switch (cflag & CBAUD) {
255 case B0: 256 case B0:
256 err("can't set 0baud, using 9600 instead"); 257 err("can't set 0 baud, using 9600 instead");
257 break; 258 break;
258 case B75: baud = 75; break; 259 case B75: baud = 75; break;
259 case B150: baud = 150; break; 260 case B150: baud = 150; break;
@@ -285,38 +286,40 @@ static void ark3116_set_termios(struct usb_serial_port *port,
285 */ 286 */
286 if (baud == 460800) 287 if (baud == 460800)
287 /* strange, for 460800 the formula is wrong 288 /* strange, for 460800 the formula is wrong
288 * (dont use round(), then 9600baud is wrong) */ 289 * if using round() then 9600baud is wrong) */
289 ark3116_baud = 7; 290 ark3116_baud = 7;
290 else 291 else
291 ark3116_baud = 3000000 / baud; 292 ark3116_baud = 3000000 / baud;
292 293
293 /* ? */ 294 /* ? */
294 ARK3116_RCV(serial,0,0xFE,0xC0,0x0000,0x0003, 0x03, buf); 295 ARK3116_RCV(serial, 0, 0xFE, 0xC0, 0x0000, 0x0003, 0x03, buf);
296
295 /* offset = buf[0]; */ 297 /* offset = buf[0]; */
296 /* offset = 0x03; */ 298 /* offset = 0x03; */
297 /* dbg("using 0x%04X as target for 0x0003:",0x0080+offset); */ 299 /* dbg("using 0x%04X as target for 0x0003:", 0x0080 + offset); */
298
299 300
300 /* set baudrate */ 301 /* set baudrate */
301 dbg("setting baudrate to %d (->reg=%d)",baud,ark3116_baud); 302 dbg("setting baudrate to %d (->reg=%d)", baud, ark3116_baud);
302 ARK3116_SND(serial,147,0xFE,0x40,0x0083,0x0003); 303 ARK3116_SND(serial, 147, 0xFE, 0x40, 0x0083, 0x0003);
303 ARK3116_SND(serial,148,0xFE,0x40,(ark3116_baud & 0x00FF) ,0x0000); 304 ARK3116_SND(serial, 148, 0xFE, 0x40,
304 ARK3116_SND(serial,149,0xFE,0x40,(ark3116_baud & 0xFF00)>>8,0x0001); 305 (ark3116_baud & 0x00FF), 0x0000);
305 ARK3116_SND(serial,150,0xFE,0x40,0x0003,0x0003); 306 ARK3116_SND(serial, 149, 0xFE, 0x40,
307 (ark3116_baud & 0xFF00) >> 8, 0x0001);
308 ARK3116_SND(serial, 150, 0xFE, 0x40, 0x0003, 0x0003);
306 309
307 /* ? */ 310 /* ? */
308 ARK3116_RCV(serial,151,0xFE,0xC0,0x0000,0x0004,0x03, buf); 311 ARK3116_RCV(serial, 151, 0xFE, 0xC0, 0x0000, 0x0004, 0x03, buf);
309 ARK3116_SND(serial,152,0xFE,0x40,0x0000,0x0003); 312 ARK3116_SND(serial, 152, 0xFE, 0x40, 0x0000, 0x0003);
310 313
311 /* set data bit count, stop bit count & parity: */ 314 /* set data bit count, stop bit count & parity: */
312 dbg("updating bit count, stop bit or parity (cfg=0x%02X)", config); 315 dbg("updating bit count, stop bit or parity (cfg=0x%02X)", config);
313 ARK3116_RCV(serial,153,0xFE,0xC0,0x0000,0x0003,0x00, buf); 316 ARK3116_RCV(serial, 153, 0xFE, 0xC0, 0x0000, 0x0003, 0x00, buf);
314 ARK3116_SND(serial,154,0xFE,0x40,config,0x0003); 317 ARK3116_SND(serial, 154, 0xFE, 0x40, config, 0x0003);
315 318
316 if (cflag & CRTSCTS) 319 if (cflag & CRTSCTS)
317 dbg("CRTSCTS not supported by chipset ?!"); 320 dbg("CRTSCTS not supported by chipset?!");
318 321
319 /* TEST ARK3116_SND(154,0xFE,0x40,0xFFFF, 0x0006); */ 322 /* TEST ARK3116_SND(154, 0xFE, 0x40, 0xFFFF, 0x0006); */
320 323
321 kfree(buf); 324 kfree(buf);
322 return; 325 return;
@@ -329,11 +332,11 @@ static int ark3116_open(struct usb_serial_port *port, struct file *filp)
329 char *buf; 332 char *buf;
330 int result = 0; 333 int result = 0;
331 334
332 dbg("%s - port %d", __FUNCTION__, port->number); 335 dbg("%s - port %d", __FUNCTION__, port->number);
333 336
334 buf = kmalloc(1, GFP_KERNEL); 337 buf = kmalloc(1, GFP_KERNEL);
335 if (!buf) { 338 if (!buf) {
336 dbg("error kmalloc -> out of mem ?"); 339 dbg("error kmalloc -> out of mem?");
337 return -ENOMEM; 340 return -ENOMEM;
338 } 341 }
339 342
@@ -342,44 +345,68 @@ static int ark3116_open(struct usb_serial_port *port, struct file *filp)
342 return result; 345 return result;
343 346
344 /* open */ 347 /* open */
345 ARK3116_RCV(serial,111,0xFE,0xC0,0x0000,0x0003, 0x02, buf); 348 ARK3116_RCV(serial, 111, 0xFE, 0xC0, 0x0000, 0x0003, 0x02, buf);
346 349
347 ARK3116_SND(serial,112,0xFE,0x40,0x0082,0x0003); 350 ARK3116_SND(serial, 112, 0xFE, 0x40, 0x0082, 0x0003);
348 ARK3116_SND(serial,113,0xFE,0x40,0x001A,0x0000); 351 ARK3116_SND(serial, 113, 0xFE, 0x40, 0x001A, 0x0000);
349 ARK3116_SND(serial,114,0xFE,0x40,0x0000,0x0001); 352 ARK3116_SND(serial, 114, 0xFE, 0x40, 0x0000, 0x0001);
350 ARK3116_SND(serial,115,0xFE,0x40,0x0002,0x0003); 353 ARK3116_SND(serial, 115, 0xFE, 0x40, 0x0002, 0x0003);
351 354
352 ARK3116_RCV(serial,116,0xFE,0xC0,0x0000,0x0004, 0x03, buf); 355 ARK3116_RCV(serial, 116, 0xFE, 0xC0, 0x0000, 0x0004, 0x03, buf);
353 ARK3116_SND(serial,117,0xFE,0x40,0x0002,0x0004); 356 ARK3116_SND(serial, 117, 0xFE, 0x40, 0x0002, 0x0004);
354 357
355 ARK3116_RCV(serial,118,0xFE,0xC0,0x0000,0x0004, 0x02, buf); 358 ARK3116_RCV(serial, 118, 0xFE, 0xC0, 0x0000, 0x0004, 0x02, buf);
356 ARK3116_SND(serial,119,0xFE,0x40,0x0000,0x0004); 359 ARK3116_SND(serial, 119, 0xFE, 0x40, 0x0000, 0x0004);
357 360
358 ARK3116_RCV(serial,120,0xFE,0xC0,0x0000,0x0004, 0x00, buf); 361 ARK3116_RCV(serial, 120, 0xFE, 0xC0, 0x0000, 0x0004, 0x00, buf);
359 362
360 ARK3116_SND(serial,121,0xFE,0x40,0x0001,0x0004); 363 ARK3116_SND(serial, 121, 0xFE, 0x40, 0x0001, 0x0004);
361 364
362 ARK3116_RCV(serial,122,0xFE,0xC0,0x0000,0x0004, 0x01, buf); 365 ARK3116_RCV(serial, 122, 0xFE, 0xC0, 0x0000, 0x0004, 0x01, buf);
363 366
364 ARK3116_SND(serial,123,0xFE,0x40,0x0003,0x0004); 367 ARK3116_SND(serial, 123, 0xFE, 0x40, 0x0003, 0x0004);
365 368
366 /* returns different values (control lines ?!) */ 369 /* returns different values (control lines?!) */
367 ARK3116_RCV(serial,124,0xFE,0xC0,0x0000,0x0006, 0xFF, buf); 370 ARK3116_RCV(serial, 124, 0xFE, 0xC0, 0x0000, 0x0006, 0xFF, buf);
368 371
369 /* initialise termios: */ 372 /* initialise termios */
370 if (port->tty) 373 if (port->tty)
371 ark3116_set_termios(port, &tmp_termios); 374 ark3116_set_termios(port, &tmp_termios);
372 375
373 kfree(buf); 376 kfree(buf);
374 377
375 return result; 378 return result;
376
377} 379}
378 380
379static int ark3116_ioctl(struct usb_serial_port *port, struct file *file, 381static int ark3116_ioctl(struct usb_serial_port *port, struct file *file,
380 unsigned int cmd, unsigned long arg) 382 unsigned int cmd, unsigned long arg)
381{ 383{
382 dbg("ioctl not supported yet..."); 384 struct serial_struct serstruct;
385 void __user *user_arg = (void __user *)arg;
386
387 switch (cmd) {
388 case TIOCGSERIAL:
389 /* XXX: Some of these values are probably wrong. */
390 memset(&serstruct, 0, sizeof (serstruct));
391 serstruct.type = PORT_16654;
392 serstruct.line = port->serial->minor;
393 serstruct.port = port->number;
394 serstruct.custom_divisor = 0;
395 serstruct.baud_base = 460800;
396
397 if (copy_to_user(user_arg, &serstruct, sizeof (serstruct)))
398 return -EFAULT;
399
400 return 0;
401 case TIOCSSERIAL:
402 if (copy_from_user(&serstruct, user_arg, sizeof (serstruct)))
403 return -EFAULT;
404 return 0;
405 default:
406 dbg("%s cmd 0x%04x not supported", __FUNCTION__, cmd);
407 break;
408 }
409
383 return -ENOIOCTLCMD; 410 return -ENOIOCTLCMD;
384} 411}
385 412
@@ -389,7 +416,7 @@ static int ark3116_tiocmget(struct usb_serial_port *port, struct file *file)
389 char *buf; 416 char *buf;
390 char temp; 417 char temp;
391 418
392 /* seems like serial port status info (RTS, CTS,...) is stored 419 /* seems like serial port status info (RTS, CTS, ...) is stored
393 * in reg(?) 0x0006 420 * in reg(?) 0x0006
394 * pcb connection point 11 = GND -> sets bit4 of response 421 * pcb connection point 11 = GND -> sets bit4 of response
395 * pcb connection point 7 = GND -> sets bit6 of response 422 * pcb connection point 7 = GND -> sets bit6 of response
@@ -401,16 +428,16 @@ static int ark3116_tiocmget(struct usb_serial_port *port, struct file *file)
401 return -ENOMEM; 428 return -ENOMEM;
402 } 429 }
403 430
404 /* read register: */ 431 /* read register */
405 ARK3116_RCV_QUIET(serial,0xFE,0xC0,0x0000,0x0006,buf); 432 ARK3116_RCV_QUIET(serial, 0xFE, 0xC0, 0x0000, 0x0006, buf);
406 temp = buf[0]; 433 temp = buf[0];
407 kfree(buf); 434 kfree(buf);
408 435
409 /* i do not really know if bit4=CTS and bit6=DSR... was just a 436 /* i do not really know if bit4=CTS and bit6=DSR... just a
410 * quick guess !! 437 * quick guess!
411 */ 438 */
412 return (temp & (1<<4) ? TIOCM_CTS : 0) | 439 return (temp & (1<<4) ? TIOCM_CTS : 0)
413 (temp & (1<<6) ? TIOCM_DSR : 0); 440 | (temp & (1<<6) ? TIOCM_DSR : 0);
414} 441}
415 442
416static struct usb_driver ark3116_driver = { 443static struct usb_driver ark3116_driver = {