32 bit sys ipc, stolen from ia64 ...
[linux-2.6/linux-mips.git] / drivers / usb / serial / keyspan.c
blob6bd9074a9a63cfd5b3e31bd9f6453336df8e3387
1 /*
2 Keyspan USB to Serial Converter driver
4 (C) Copyright (C) 2000
5 Hugh Blemings <hugh@linuxcare.com>
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or
10 (at your option) any later version.
12 See http://www.linuxcare.com.au/hugh/keyspan.html for more
13 information on this driver.
15 Code in this driver inspired by and in a number of places taken
16 from Brian Warner's original Keyspan-PDA driver.
18 This driver has been put together with the support of Innosys, Inc.
19 and Keyspan, Inc the manufacturers of the Keyspan USB-serial products.
20 Thanks Guys :)
22 Tip 'o the hat to Linuxcare for supporting staff in their work on
23 open source projects.
25 Sat Jul 8 11:11:48 EST 2000 Hugh
26 First public release - nothing works except the firmware upload.
27 Tested on PPC and x86 architectures, seems to behave...
32 #include <linux/config.h>
34 #ifdef CONFIG_USB_SERIAL_KEYSPAN
36 #include <linux/kernel.h>
37 #include <linux/sched.h>
38 #include <linux/signal.h>
39 #include <linux/errno.h>
40 #include <linux/poll.h>
41 #include <linux/init.h>
42 #include <linux/malloc.h>
43 #include <linux/fcntl.h>
44 #include <linux/tty_driver.h>
45 #include <linux/tty_flip.h>
46 #include <linux/tty.h>
47 #include <linux/module.h>
48 #include <linux/spinlock.h>
50 #ifdef CONFIG_USB_SERIAL_DEBUG
51 #define DEBUG
52 #else
53 #undef DEBUG
54 #endif
55 #include <linux/usb.h>
57 #include "usb-serial.h"
59 struct ezusb_hex_record {
60 __u16 address;
61 __u8 data_size;
62 __u8 data[16];
65 /* Conditionally include firmware images, if they aren't
66 included create a null pointer instead. Current
67 firmware images aren't optimised to remove duplicate
68 addresses. */
69 #ifdef CONFIG_USB_SERIAL_KEYSPAN_USA28
70 #include "keyspan_usa28_fw.h"
71 #else
72 static const struct ezusb_hex_record *keyspan_usa28_firmware = NULL;
73 #endif
75 #ifdef CONFIG_USB_SERIAL_KEYSPAN_USA28X
76 #include "keyspan_usa28x_fw.h"
77 #else
78 static const struct ezusb_hex_record *keyspan_usa28x_firmware = NULL;
79 #endif
81 #ifdef CONFIG_USB_SERIAL_KEYSPAN_USA19
82 #include "keyspan_usa19_fw.h"
83 #else
84 static const struct ezusb_hex_record *keyspan_usa19_firmware = NULL;
85 #endif
87 #ifdef CONFIG_USB_SERIAL_KEYSPAN_USA18X
88 #include "keyspan_usa18x_fw.h"
89 #else
90 static const struct ezusb_hex_record *keyspan_usa18x_firmware = NULL;
91 #endif
93 #ifdef CONFIG_USB_SERIAL_KEYSPAN_USA19W
94 #include "keyspan_usa19w_fw.h"
95 #else
96 static const struct ezusb_hex_record *keyspan_usa19w_firmware = NULL;
97 #endif
99 /* Include Keyspan message headers (not here yet, need some tweaks
100 to get clean build) */
101 /*#include "keyspan_usa26msg.h"*/
102 /*#include "keyspan_usa28msg.h"*/
104 /* If you don't get debugging output, uncomment the following
105 two lines to enable cheat. */
106 #undef dbg
107 #define dbg printk
110 /* function prototypes for Keyspan serial converter */
111 static int keyspan_open (struct usb_serial_port *port,
112 struct file *filp);
113 static void keyspan_close (struct usb_serial_port *port,
114 struct file *filp);
115 static int keyspan_startup (struct usb_serial *serial);
116 static void keyspan_shutdown (struct usb_serial *serial);
117 static void keyspan_rx_interrupt (struct urb *urb);
118 static void keyspan_rx_throttle (struct usb_serial_port *port);
119 static void keyspan_rx_unthrottle (struct usb_serial_port *port);
120 static int keyspan_write_room (struct usb_serial_port *port);
121 static int keyspan_write (struct usb_serial_port *port,
122 int from_user,
123 const unsigned char *buf,
124 int count);
125 static void keyspan_write_bulk_callback (struct urb *urb);
126 static int keyspan_chars_in_buffer (struct usb_serial_port *port);
127 static int keyspan_ioctl (struct usb_serial_port *port,
128 struct file *file,
129 unsigned int cmd,
130 unsigned long arg);
131 static void keyspan_set_termios (struct usb_serial_port *port,
132 struct termios *old);
133 static void keyspan_break_ctl (struct usb_serial_port *port,
134 int break_state);
135 static int keyspan_fake_startup (struct usb_serial *serial);
138 /* Functions - mostly stubs for now */
140 static void keyspan_rx_interrupt (struct urb *urb)
146 static void keyspan_rx_throttle (struct usb_serial_port *port)
148 dbg("keyspan_rx_throttle port %d", port->number);
152 static void keyspan_rx_unthrottle (struct usb_serial_port *port)
154 dbg("keyspan_rx_unthrottle port %d", port->number);
158 static void keyspan_break_ctl (struct usb_serial_port *port, int break_state)
160 dbg("keyspan_break_ctl");
164 static void keyspan_set_termios (struct usb_serial_port *port,
165 struct termios *old_termios)
167 dbg("keyspan_set_termios");
170 static int keyspan_ioctl(struct usb_serial_port *port, struct file *file,
171 unsigned int cmd, unsigned long arg)
174 dbg("keyspan_ioctl_info");
176 return -ENOIOCTLCMD;
179 static int keyspan_write(struct usb_serial_port *port, int from_user,
180 const unsigned char *buf, int count)
182 dbg("keyspan_write called\n");
183 return(count);
187 static void keyspan_write_bulk_callback (struct urb *urb)
190 dbg("keyspan_write_bulk_callback called\n");
194 static int keyspan_write_room (struct usb_serial_port *port)
196 dbg("keyspan_write_room called\n");
197 return (1);
202 static int keyspan_chars_in_buffer (struct usb_serial_port *port)
204 return (0);
208 static int keyspan_open (struct usb_serial_port *port, struct file *filp)
210 dbg("keyspan_open called\n");
211 return (0);
215 static void keyspan_close(struct usb_serial_port *port, struct file *filp)
217 dbg("keyspan_close called\n");
221 /* download the firmware to a pre-renumeration device */
222 static int keyspan_fake_startup (struct usb_serial *serial)
224 int response;
225 const struct ezusb_hex_record *record;
226 char *fw_name;
228 dbg("Keyspan startup version %04x product %04x\n", serial->dev->descriptor.bcdDevice,
229 serial->dev->descriptor.idProduct);
231 if ((serial->dev->descriptor.bcdDevice & 0x8000) != 0x8000) {
232 dbg("Firmware already loaded. Quitting.\n");
233 return(1);
236 /* Select firmware image on the basis of idProduct */
237 switch (serial->dev->descriptor.idProduct) {
238 case 0x0101: record = &keyspan_usa28_firmware[0];
239 fw_name = "USA28";
240 break;
242 case 0x0102: record = &keyspan_usa28x_firmware[0];
243 fw_name = "USA28X";
244 break;
246 case 0x0103: record = &keyspan_usa19_firmware[0];
247 fw_name = "USA19";
248 break;
250 case 0x0105: record = &keyspan_usa18x_firmware[0];
251 fw_name = "USA18X";
252 break;
254 case 0x0106: record = &keyspan_usa19w_firmware[0];
255 fw_name = "USA19W";
256 break;
258 default: record = NULL;
259 fw_name = "Unknown";
260 break;
263 if (record == NULL) {
264 err("Required keyspan firmware image (%s) unavailable.\n", fw_name);
265 return(1);
268 dbg("Uploading Keyspan %s firmware.\n", fw_name);
270 /* download the firmware image */
271 response = ezusb_set_reset(serial, 1);
273 while(record->address != 0xffff) {
274 response = ezusb_writememory(serial, record->address,
275 (unsigned char *)record->data,
276 record->data_size, 0xa0);
277 if (response < 0) {
278 err("ezusb_writememory failed for Keyspan"
279 "firmware (%d %04X %p %d)",
280 response,
281 record->address, record->data, record->data_size);
282 break;
284 record++;
286 /* bring device out of reset. Renumeration will occur in a moment
287 and the new device will bind to the real driver */
288 response = ezusb_set_reset(serial, 0);
290 /* we want this device to fail to have a driver assigned to it. */
291 return (1);
295 /* Gets called by the "real" driver (ie once firmware is loaded
296 and renumeration has taken place. */
297 static int keyspan_startup (struct usb_serial *serial)
299 dbg("keyspan_startup called.\n");
301 return (0);
304 static void keyspan_shutdown (struct usb_serial *serial)
306 dbg("keyspan_shutdown called.\n");
310 /* Miscellaneous defines, datastructures etc. */
312 #define KEYSPAN_VENDOR_ID 0x06cd
314 /* Device info needed for the Keyspan serial converter */
315 static __u16 keyspan_vendor_id = KEYSPAN_VENDOR_ID;
317 /* Product IDs for the five products supported, pre-renumeration */
318 static __u16 keyspan_usa18x_pre_product_id = 0x0105;
319 static __u16 keyspan_usa19_pre_product_id = 0x0103;
320 static __u16 keyspan_usa19w_pre_product_id = 0x0106;
321 static __u16 keyspan_usa28_pre_product_id = 0x0101;
322 static __u16 keyspan_usa28x_pre_product_id = 0x0102;
324 /* Product IDs post-renumeration */
325 static __u16 keyspan_usa18x_product_id = 0x0112;
326 static __u16 keyspan_usa19_product_id = 0x0107;
327 static __u16 keyspan_usa19w_product_id = 0x0108;
328 static __u16 keyspan_usa28_product_id = 0x010f;
329 static __u16 keyspan_usa28x_product_id = 0x0110;
331 /* Structs for the devices, pre and post renumeration.
332 These are incomplete at present - HAB 20000708 */
333 struct usb_serial_device_type keyspan_usa18x_pre_device = {
334 name: "Keyspan USA18X - (prerenumeration)",
335 idVendor: &keyspan_vendor_id,
336 idProduct: &keyspan_usa18x_pre_product_id,
337 needs_interrupt_in: DONT_CARE,
338 needs_bulk_in: DONT_CARE,
339 needs_bulk_out: DONT_CARE,
340 num_interrupt_in: NUM_DONT_CARE,
341 num_bulk_in: NUM_DONT_CARE,
342 num_bulk_out: NUM_DONT_CARE,
343 num_ports: 1,
344 startup: keyspan_fake_startup
347 struct usb_serial_device_type keyspan_usa19_pre_device = {
348 name: "Keyspan USA19 - (prerenumeration)",
349 idVendor: &keyspan_vendor_id,
350 idProduct: &keyspan_usa19_pre_product_id,
351 needs_interrupt_in: DONT_CARE,
352 needs_bulk_in: DONT_CARE,
353 needs_bulk_out: DONT_CARE,
354 num_interrupt_in: NUM_DONT_CARE,
355 num_bulk_in: NUM_DONT_CARE,
356 num_bulk_out: NUM_DONT_CARE,
357 num_ports: 1,
358 startup: keyspan_fake_startup
362 struct usb_serial_device_type keyspan_usa19w_pre_device = {
363 name: "Keyspan USA19W - (prerenumeration)",
364 idVendor: &keyspan_vendor_id,
365 idProduct: &keyspan_usa19w_pre_product_id,
366 needs_interrupt_in: DONT_CARE,
367 needs_bulk_in: DONT_CARE,
368 needs_bulk_out: DONT_CARE,
369 num_interrupt_in: NUM_DONT_CARE,
370 num_bulk_in: NUM_DONT_CARE,
371 num_bulk_out: NUM_DONT_CARE,
372 num_ports: 1,
373 startup: keyspan_fake_startup
377 struct usb_serial_device_type keyspan_usa28_pre_device = {
378 name: "Keyspan USA28 - (prerenumeration)",
379 idVendor: &keyspan_vendor_id,
380 idProduct: &keyspan_usa28_pre_product_id,
381 needs_interrupt_in: DONT_CARE,
382 needs_bulk_in: DONT_CARE,
383 needs_bulk_out: DONT_CARE,
384 num_interrupt_in: NUM_DONT_CARE,
385 num_bulk_in: NUM_DONT_CARE,
386 num_bulk_out: NUM_DONT_CARE,
387 num_ports: 2,
388 startup: keyspan_fake_startup
391 struct usb_serial_device_type keyspan_usa28x_pre_device = {
392 name: "Keyspan USA28X - (prerenumeration)",
393 idVendor: &keyspan_vendor_id,
394 idProduct: &keyspan_usa28x_pre_product_id,
395 needs_interrupt_in: DONT_CARE,
396 needs_bulk_in: DONT_CARE,
397 needs_bulk_out: DONT_CARE,
398 num_interrupt_in: NUM_DONT_CARE,
399 num_bulk_in: NUM_DONT_CARE,
400 num_bulk_out: NUM_DONT_CARE,
401 num_ports: 2,
402 startup: keyspan_fake_startup
406 struct usb_serial_device_type keyspan_usa18x_device = {
407 name: "Keyspan USA18X",
408 idVendor: &keyspan_vendor_id,
409 idProduct: &keyspan_usa18x_product_id,
410 needs_interrupt_in: DONT_CARE,
411 needs_bulk_in: DONT_CARE,
412 needs_bulk_out: DONT_CARE,
413 num_interrupt_in: NUM_DONT_CARE,
414 num_bulk_in: NUM_DONT_CARE,
415 num_bulk_out: NUM_DONT_CARE,
416 num_ports: 1,
417 open: keyspan_open,
418 close: keyspan_close,
419 throttle: keyspan_rx_throttle,
420 unthrottle: keyspan_rx_unthrottle,
421 set_termios: keyspan_set_termios,
424 struct usb_serial_device_type keyspan_usa19_device = {
425 name: "Keyspan USA19",
426 idVendor: &keyspan_vendor_id,
427 idProduct: &keyspan_usa19_product_id,
428 needs_interrupt_in: DONT_CARE,
429 needs_bulk_in: DONT_CARE,
430 needs_bulk_out: DONT_CARE,
431 num_interrupt_in: NUM_DONT_CARE,
432 num_bulk_in: NUM_DONT_CARE,
433 num_bulk_out: NUM_DONT_CARE,
434 num_ports: 1,
435 open: keyspan_open,
436 close: keyspan_close,
437 write: keyspan_write,
438 write_room: keyspan_write_room,
439 write_bulk_callback: keyspan_write_bulk_callback,
440 read_int_callback: keyspan_rx_interrupt,
441 chars_in_buffer: keyspan_chars_in_buffer,
442 throttle: keyspan_rx_throttle,
443 unthrottle: keyspan_rx_unthrottle,
444 ioctl: keyspan_ioctl,
445 set_termios: keyspan_set_termios,
446 break_ctl: keyspan_break_ctl,
447 startup: keyspan_startup,
448 shutdown: keyspan_shutdown,
452 struct usb_serial_device_type keyspan_usa19w_device = {
453 name: "Keyspan USA19W",
454 idVendor: &keyspan_vendor_id,
455 idProduct: &keyspan_usa19w_product_id,
456 needs_interrupt_in: DONT_CARE,
457 needs_bulk_in: DONT_CARE,
458 needs_bulk_out: DONT_CARE,
459 num_interrupt_in: NUM_DONT_CARE,
460 num_bulk_in: NUM_DONT_CARE,
461 num_bulk_out: NUM_DONT_CARE,
462 num_ports: 1,
463 open: keyspan_open,
464 close: keyspan_close,
465 throttle: keyspan_rx_throttle,
466 unthrottle: keyspan_rx_unthrottle,
467 set_termios: keyspan_set_termios,
471 struct usb_serial_device_type keyspan_usa28_device = {
472 name: "Keyspan USA28",
473 idVendor: &keyspan_vendor_id,
474 idProduct: &keyspan_usa28_product_id,
475 needs_interrupt_in: DONT_CARE,
476 needs_bulk_in: DONT_CARE,
477 needs_bulk_out: DONT_CARE,
478 num_interrupt_in: NUM_DONT_CARE,
479 num_bulk_in: NUM_DONT_CARE,
480 num_bulk_out: NUM_DONT_CARE,
481 num_ports: 2,
482 open: keyspan_open,
483 close: keyspan_close,
484 throttle: keyspan_rx_throttle,
485 unthrottle: keyspan_rx_unthrottle,
486 set_termios: keyspan_set_termios,
490 struct usb_serial_device_type keyspan_usa28x_device = {
491 name: "Keyspan USA28X",
492 idVendor: &keyspan_vendor_id,
493 idProduct: &keyspan_usa28x_product_id,
494 needs_interrupt_in: DONT_CARE,
495 needs_bulk_in: DONT_CARE,
496 needs_bulk_out: DONT_CARE,
497 num_interrupt_in: NUM_DONT_CARE,
498 num_bulk_in: NUM_DONT_CARE,
499 num_bulk_out: NUM_DONT_CARE,
500 num_ports: 2,
501 open: keyspan_open,
502 close: keyspan_close,
503 throttle: keyspan_rx_throttle,
504 unthrottle: keyspan_rx_unthrottle,
505 set_termios: keyspan_set_termios,
511 #endif /* CONFIG_USB_SERIAL_KEYSPAN */