tty: declare MODULE_FIRMWARE in various drivers
[deliverable/linux.git] / drivers / char / ip2 / ip2main.c
CommitLineData
1da177e4
LT
1/*
2*
3* (c) 1999 by Computone Corporation
4*
5********************************************************************************
6*
7* PACKAGE: Linux tty Device Driver for IntelliPort family of multiport
8* serial I/O controllers.
9*
10* DESCRIPTION: Mainline code for the device driver
11*
12*******************************************************************************/
13// ToDo:
14//
15// Fix the immediate DSS_NOW problem.
16// Work over the channel stats return logic in ip2_ipl_ioctl so they
17// make sense for all 256 possible channels and so the user space
18// utilities will compile and work properly.
19//
20// Done:
21//
22// 1.2.14 /\/\|=mhw=|\/\/
23// Added bounds checking to ip2_ipl_ioctl to avoid potential terroristic acts.
24// Changed the definition of ip2trace to be more consistent with kernel style
25// Thanks to Andreas Dilger <adilger@turbolabs.com> for these updates
26//
27// 1.2.13 /\/\|=mhw=|\/\/
28// DEVFS: Renamed ttf/{n} to tts/F{n} and cuf/{n} to cua/F{n} to conform
29// to agreed devfs serial device naming convention.
30//
31// 1.2.12 /\/\|=mhw=|\/\/
32// Cleaned up some remove queue cut and paste errors
33//
34// 1.2.11 /\/\|=mhw=|\/\/
35// Clean up potential NULL pointer dereferences
36// Clean up devfs registration
37// Add kernel command line parsing for io and irq
9c4b562a 38// Compile defaults for io and irq are now set in ip2.c not ip2.h!
1da177e4
LT
39// Reworked poll_only hack for explicit parameter setting
40// You must now EXPLICITLY set poll_only = 1 or set all irqs to 0
41// Merged ip2_loadmain and old_ip2_init
42// Converted all instances of interruptible_sleep_on into queue calls
43// Most of these had no race conditions but better to clean up now
44//
45// 1.2.10 /\/\|=mhw=|\/\/
46// Fixed the bottom half interrupt handler and enabled USE_IQI
47// to split the interrupt handler into a formal top-half / bottom-half
48// Fixed timing window on high speed processors that queued messages to
49// the outbound mail fifo faster than the board could handle.
50//
51// 1.2.9
52// Four box EX was barfing on >128k kmalloc, made structure smaller by
53// reducing output buffer size
54//
55// 1.2.8
56// Device file system support (MHW)
57//
58// 1.2.7
59// Fixed
60// Reload of ip2 without unloading ip2main hangs system on cat of /proc/modules
61//
62// 1.2.6
63//Fixes DCD problems
64// DCD was not reported when CLOCAL was set on call to TIOCMGET
65//
66//Enhancements:
67// TIOCMGET requests and waits for status return
68// No DSS interrupts enabled except for DCD when needed
69//
70// For internal use only
71//
72//#define IP2DEBUG_INIT
73//#define IP2DEBUG_OPEN
74//#define IP2DEBUG_WRITE
75//#define IP2DEBUG_READ
76//#define IP2DEBUG_IOCTL
77//#define IP2DEBUG_IPL
78
79//#define IP2DEBUG_TRACE
80//#define DEBUG_FIFO
81
82/************/
83/* Includes */
84/************/
1da177e4
LT
85
86#include <linux/ctype.h>
87#include <linux/string.h>
88#include <linux/fcntl.h>
89#include <linux/errno.h>
90#include <linux/module.h>
91#include <linux/signal.h>
92#include <linux/sched.h>
1da177e4
LT
93#include <linux/timer.h>
94#include <linux/interrupt.h>
95#include <linux/pci.h>
96#include <linux/mm.h>
97#include <linux/slab.h>
98#include <linux/major.h>
99#include <linux/wait.h>
100#include <linux/device.h>
f2b9857e 101#include <linux/smp_lock.h>
547d8bb7
DW
102#include <linux/firmware.h>
103#include <linux/platform_device.h>
1da177e4
LT
104
105#include <linux/tty.h>
106#include <linux/tty_flip.h>
107#include <linux/termios.h>
108#include <linux/tty_driver.h>
109#include <linux/serial.h>
110#include <linux/ptrace.h>
111#include <linux/ioport.h>
112
113#include <linux/cdk.h>
114#include <linux/comstats.h>
115#include <linux/delay.h>
116#include <linux/bitops.h>
117
118#include <asm/system.h>
119#include <asm/io.h>
120#include <asm/irq.h>
121
122#include <linux/vmalloc.h>
123#include <linux/init.h>
1da177e4
LT
124
125#include <asm/uaccess.h>
126
9c4b562a
AB
127#include "ip2types.h"
128#include "ip2trace.h"
129#include "ip2ioctl.h"
130#include "ip2.h"
131#include "i2ellis.h"
132#include "i2lib.h"
1da177e4
LT
133
134/*****************
135 * /proc/ip2mem *
136 *****************/
137
138#include <linux/proc_fs.h>
4a5cdb5b 139#include <linux/seq_file.h>
1da177e4 140
4a5cdb5b 141static const struct file_operations ip2mem_proc_fops;
cdda7cd9 142static const struct file_operations ip2_proc_fops;
1da177e4
LT
143
144/********************/
145/* Type Definitions */
146/********************/
147
148/*************/
149/* Constants */
150/*************/
151
152/* String constants to identify ourselves */
cf176bc3
JS
153static const char pcName[] = "Computone IntelliPort Plus multiport driver";
154static const char pcVersion[] = "1.2.14";
1da177e4
LT
155
156/* String constants for port names */
cf176bc3
JS
157static const char pcDriver_name[] = "ip2";
158static const char pcIpl[] = "ip2ipl";
1da177e4 159
1da177e4
LT
160/***********************/
161/* Function Prototypes */
162/***********************/
163
164/* Global module entry functions */
165
166/* Private (static) functions */
167static int ip2_open(PTTY, struct file *);
168static void ip2_close(PTTY, struct file *);
d9e39538 169static int ip2_write(PTTY, const unsigned char *, int);
f34d7a5b 170static int ip2_putchar(PTTY, unsigned char);
1da177e4
LT
171static void ip2_flush_chars(PTTY);
172static int ip2_write_room(PTTY);
173static int ip2_chars_in_buf(PTTY);
174static void ip2_flush_buffer(PTTY);
175static int ip2_ioctl(PTTY, struct file *, UINT, ULONG);
606d099c 176static void ip2_set_termios(PTTY, struct ktermios *);
1da177e4
LT
177static void ip2_set_line_discipline(PTTY);
178static void ip2_throttle(PTTY);
179static void ip2_unthrottle(PTTY);
180static void ip2_stop(PTTY);
181static void ip2_start(PTTY);
182static void ip2_hangup(PTTY);
183static int ip2_tiocmget(struct tty_struct *tty, struct file *file);
184static int ip2_tiocmset(struct tty_struct *tty, struct file *file,
185 unsigned int set, unsigned int clear);
186
187static void set_irq(int, int);
c4028958 188static void ip2_interrupt_bh(struct work_struct *work);
7d12e780 189static irqreturn_t ip2_interrupt(int irq, void *dev_id);
1da177e4
LT
190static void ip2_poll(unsigned long arg);
191static inline void service_all_boards(void);
c4028958
DH
192static void do_input(struct work_struct *);
193static void do_status(struct work_struct *);
1da177e4
LT
194
195static void ip2_wait_until_sent(PTTY,int);
196
606d099c 197static void set_params (i2ChanStrPtr, struct ktermios *);
1da177e4
LT
198static int get_serial_info(i2ChanStrPtr, struct serial_struct __user *);
199static int set_serial_info(i2ChanStrPtr, struct serial_struct __user *);
200
201static ssize_t ip2_ipl_read(struct file *, char __user *, size_t, loff_t *);
202static ssize_t ip2_ipl_write(struct file *, const char __user *, size_t, loff_t *);
47be36a2 203static long ip2_ipl_ioctl(struct file *, UINT, ULONG);
1da177e4
LT
204static int ip2_ipl_open(struct inode *, struct file *);
205
206static int DumpTraceBuffer(char __user *, int);
207static int DumpFifoBuffer( char __user *, int);
208
547d8bb7 209static void ip2_init_board(int, const struct firmware *);
1da177e4 210static unsigned short find_eisa_board(int);
02c95a62 211static int ip2_setup(char *str);
1da177e4
LT
212
213/***************/
214/* Static Data */
215/***************/
216
217static struct tty_driver *ip2_tty_driver;
218
219/* Here, then is a table of board pointers which the interrupt routine should
220 * scan through to determine who it must service.
221 */
222static unsigned short i2nBoards; // Number of boards here
223
224static i2eBordStrPtr i2BoardPtrTable[IP2_MAX_BOARDS];
225
226static i2ChanStrPtr DevTable[IP2_MAX_PORTS];
227//DevTableMem just used to save addresses for kfree
228static void *DevTableMem[IP2_MAX_BOARDS];
229
230/* This is the driver descriptor for the ip2ipl device, which is used to
231 * download the loadware to the boards.
232 */
62322d25 233static const struct file_operations ip2_ipl = {
1da177e4
LT
234 .owner = THIS_MODULE,
235 .read = ip2_ipl_read,
236 .write = ip2_ipl_write,
47be36a2 237 .unlocked_ioctl = ip2_ipl_ioctl,
1da177e4
LT
238 .open = ip2_ipl_open,
239};
240
cf176bc3
JS
241static unsigned long irq_counter;
242static unsigned long bh_counter;
1da177e4
LT
243
244// Use immediate queue to service interrupts
245#define USE_IQI
246//#define USE_IQ // PCI&2.2 needs work
247
248/* The timer_list entry for our poll routine. If interrupt operation is not
249 * selected, the board is serviced periodically to see if anything needs doing.
250 */
251#define POLL_TIMEOUT (jiffies + 1)
8d06afab 252static DEFINE_TIMER(PollTimer, ip2_poll, 0, 0);
1da177e4
LT
253
254#ifdef IP2DEBUG_TRACE
255/* Trace (debug) buffer data */
256#define TRACEMAX 1000
257static unsigned long tracebuf[TRACEMAX];
258static int tracestuff;
259static int tracestrip;
260static int tracewrap;
261#endif
262
263/**********/
264/* Macros */
265/**********/
266
795877cf 267#ifdef IP2DEBUG_OPEN
7d7b93c1
AC
268#define DBG_CNT(s) printk(KERN_DEBUG "(%s): [%x] ttyc=%d, modc=%x -> %s\n", \
269 tty->name,(pCh->flags), \
1da177e4
LT
270 tty->count,/*GET_USE_COUNT(module)*/0,s)
271#else
272#define DBG_CNT(s)
273#endif
274
275/********/
276/* Code */
277/********/
278
9c4b562a
AB
279#include "i2ellis.c" /* Extremely low-level interface services */
280#include "i2cmd.c" /* Standard loadware command definitions */
281#include "i2lib.c" /* High level interface services */
1da177e4
LT
282
283/* Configuration area for modprobe */
284
285MODULE_AUTHOR("Doug McNash");
286MODULE_DESCRIPTION("Computone IntelliPort Plus Driver");
47babd4c 287MODULE_LICENSE("GPL");
1da177e4 288
02c95a62
RM
289#define MAX_CMD_STR 50
290
cf176bc3 291static int poll_only;
02c95a62 292static char cmd[MAX_CMD_STR];
1da177e4
LT
293
294static int Eisa_irq;
295static int Eisa_slot;
296
297static int iindx;
298static char rirqs[IP2_MAX_BOARDS];
299static int Valid_Irqs[] = { 3, 4, 5, 7, 10, 11, 12, 15, 0};
300
47babd4c
JS
301/* Note: Add compiled in defaults to these arrays, not to the structure
302 in ip2.h any longer. That structure WILL get overridden
303 by these values, or command line values, or insmod values!!! =mhw=
304*/
305static int io[IP2_MAX_BOARDS];
306static int irq[IP2_MAX_BOARDS] = { -1, -1, -1, -1 };
307
308MODULE_AUTHOR("Doug McNash");
309MODULE_DESCRIPTION("Computone IntelliPort Plus Driver");
310module_param_array(irq, int, NULL, 0);
311MODULE_PARM_DESC(irq, "Interrupts for IntelliPort Cards");
312module_param_array(io, int, NULL, 0);
313MODULE_PARM_DESC(io, "I/O ports for IntelliPort Cards");
314module_param(poll_only, bool, 0);
315MODULE_PARM_DESC(poll_only, "Do not use card interrupts");
02c95a62
RM
316module_param_string(ip2, cmd, MAX_CMD_STR, 0);
317MODULE_PARM_DESC(ip2, "Contains module parameter passed with 'ip2='");
47babd4c 318
1da177e4 319/* for sysfs class support */
ca8eca68 320static struct class *ip2_class;
1da177e4 321
f1ddfd95 322/* Some functions to keep track of what irqs we have */
1da177e4 323
f1ddfd95 324static int __init is_valid_irq(int irq)
1da177e4
LT
325{
326 int *i = Valid_Irqs;
327
f1ddfd95 328 while (*i != 0 && *i != irq)
1da177e4 329 i++;
f1ddfd95
JS
330
331 return *i;
1da177e4
LT
332}
333
f1ddfd95 334static void __init mark_requested_irq(char irq)
1da177e4
LT
335{
336 rirqs[iindx++] = irq;
337}
338
f1ddfd95 339static int __exit clear_requested_irq(char irq)
1da177e4
LT
340{
341 int i;
f1ddfd95 342 for (i = 0; i < IP2_MAX_BOARDS; ++i) {
1da177e4
LT
343 if (rirqs[i] == irq) {
344 rirqs[i] = 0;
345 return 1;
346 }
347 }
348 return 0;
349}
1da177e4 350
f1ddfd95 351static int have_requested_irq(char irq)
1da177e4 352{
f1ddfd95
JS
353 /* array init to zeros so 0 irq will not be requested as a side
354 * effect */
1da177e4 355 int i;
f1ddfd95 356 for (i = 0; i < IP2_MAX_BOARDS; ++i)
1da177e4
LT
357 if (rirqs[i] == irq)
358 return 1;
1da177e4
LT
359 return 0;
360}
361
1da177e4
LT
362/******************************************************************************/
363/* Function: cleanup_module() */
364/* Parameters: None */
365/* Returns: Nothing */
366/* */
367/* Description: */
368/* This is a required entry point for an installable module. It has to return */
369/* the device and the driver to a passive state. It should not be necessary */
370/* to reset the board fully, especially as the loadware is downloaded */
371/* externally rather than in the driver. We just want to disable the board */
372/* and clear the loadware to a reset state. To allow this there has to be a */
373/* way to detect whether the board has the loadware running at init time to */
374/* handle subsequent installations of the driver. All memory allocated by the */
375/* driver should be returned since it may be unloaded from memory. */
376/******************************************************************************/
7ccd7020 377static void __exit ip2_cleanup_module(void)
1da177e4
LT
378{
379 int err;
380 int i;
381
9d020a2e 382 del_timer_sync(&PollTimer);
1da177e4
LT
383
384 /* Reset the boards we have. */
f1ddfd95
JS
385 for (i = 0; i < IP2_MAX_BOARDS; i++)
386 if (i2BoardPtrTable[i])
387 iiReset(i2BoardPtrTable[i]);
1da177e4
LT
388
389 /* The following is done at most once, if any boards were installed. */
f1ddfd95
JS
390 for (i = 0; i < IP2_MAX_BOARDS; i++) {
391 if (i2BoardPtrTable[i]) {
392 iiResetDelay(i2BoardPtrTable[i]);
1da177e4 393 /* free io addresses and Tibet */
f1ddfd95 394 release_region(ip2config.addr[i], 8);
07c015e7 395 device_destroy(ip2_class, MKDEV(IP2_IPL_MAJOR, 4 * i));
f1ddfd95
JS
396 device_destroy(ip2_class, MKDEV(IP2_IPL_MAJOR,
397 4 * i + 1));
1da177e4
LT
398 }
399 /* Disable and remove interrupt handler. */
f1ddfd95
JS
400 if (ip2config.irq[i] > 0 &&
401 have_requested_irq(ip2config.irq[i])) {
402 free_irq(ip2config.irq[i], (void *)&pcName);
403 clear_requested_irq(ip2config.irq[i]);
1da177e4
LT
404 }
405 }
ca8eca68 406 class_destroy(ip2_class);
f1ddfd95
JS
407 err = tty_unregister_driver(ip2_tty_driver);
408 if (err)
409 printk(KERN_ERR "IP2: failed to unregister tty driver (%d)\n",
410 err);
1da177e4 411 put_tty_driver(ip2_tty_driver);
68fc4fab 412 unregister_chrdev(IP2_IPL_MAJOR, pcIpl);
c74c120a 413 remove_proc_entry("ip2mem", NULL);
1da177e4 414
f1ddfd95 415 /* free memory */
1da177e4
LT
416 for (i = 0; i < IP2_MAX_BOARDS; i++) {
417 void *pB;
418#ifdef CONFIG_PCI
419 if (ip2config.type[i] == PCI && ip2config.pci_dev[i]) {
420 pci_disable_device(ip2config.pci_dev[i]);
1aff0eca 421 pci_dev_put(ip2config.pci_dev[i]);
1da177e4
LT
422 ip2config.pci_dev[i] = NULL;
423 }
424#endif
7ccd7020
JS
425 pB = i2BoardPtrTable[i];
426 if (pB != NULL) {
f1ddfd95 427 kfree(pB);
1da177e4
LT
428 i2BoardPtrTable[i] = NULL;
429 }
f1ddfd95
JS
430 if (DevTableMem[i] != NULL) {
431 kfree(DevTableMem[i]);
1da177e4
LT
432 DevTableMem[i] = NULL;
433 }
434 }
1da177e4 435}
83e422b7 436module_exit(ip2_cleanup_module);
1da177e4 437
b68e31d0 438static const struct tty_operations ip2_ops = {
1da177e4
LT
439 .open = ip2_open,
440 .close = ip2_close,
441 .write = ip2_write,
442 .put_char = ip2_putchar,
443 .flush_chars = ip2_flush_chars,
444 .write_room = ip2_write_room,
445 .chars_in_buffer = ip2_chars_in_buf,
446 .flush_buffer = ip2_flush_buffer,
447 .ioctl = ip2_ioctl,
448 .throttle = ip2_throttle,
449 .unthrottle = ip2_unthrottle,
450 .set_termios = ip2_set_termios,
451 .set_ldisc = ip2_set_line_discipline,
452 .stop = ip2_stop,
453 .start = ip2_start,
454 .hangup = ip2_hangup,
1da177e4
LT
455 .tiocmget = ip2_tiocmget,
456 .tiocmset = ip2_tiocmset,
cdda7cd9 457 .proc_fops = &ip2_proc_fops,
1da177e4
LT
458};
459
460/******************************************************************************/
461/* Function: ip2_loadmain() */
462/* Parameters: irq, io from command line of insmod et. al. */
463/* pointer to fip firmware and firmware size for boards */
464/* Returns: Success (0) */
465/* */
466/* Description: */
467/* This was the required entry point for all drivers (now in ip2.c) */
468/* It performs all */
469/* initialisation of the devices and driver structures, and registers itself */
470/* with the relevant kernel modules. */
471/******************************************************************************/
0f2ed4c6
TG
472/* IRQF_DISABLED - if set blocks all interrupts else only this line */
473/* IRQF_SHARED - for shared irq PCI or maybe EISA only */
1da177e4
LT
474/* SA_RANDOM - can be source for cert. random number generators */
475#define IP2_SA_FLAGS 0
476
547d8bb7
DW
477
478static const struct firmware *ip2_request_firmware(void)
479{
480 struct platform_device *pdev;
481 const struct firmware *fw;
482
483 pdev = platform_device_register_simple("ip2", 0, NULL, 0);
484 if (IS_ERR(pdev)) {
485 printk(KERN_ERR "Failed to register platform device for ip2\n");
486 return NULL;
487 }
488 if (request_firmware(&fw, "intelliport2.bin", &pdev->dev)) {
489 printk(KERN_ERR "Failed to load firmware 'intelliport2.bin'\n");
490 fw = NULL;
491 }
492 platform_device_unregister(pdev);
493 return fw;
494}
495
47babd4c
JS
496/******************************************************************************
497 * ip2_setup:
498 * str: kernel command line string
499 *
500 * Can't autoprobe the boards so user must specify configuration on
501 * kernel command line. Sane people build it modular but the others
502 * come here.
503 *
504 * Alternating pairs of io,irq for up to 4 boards.
505 * ip2=io0,irq0,io1,irq1,io2,irq2,io3,irq3
506 *
507 * io=0 => No board
508 * io=1 => PCI
509 * io=2 => EISA
510 * else => ISA I/O address
511 *
512 * irq=0 or invalid for ISA will revert to polling mode
513 *
514 * Any value = -1, do not overwrite compiled in value.
515 *
516 ******************************************************************************/
517static int __init ip2_setup(char *str)
518{
519 int j, ints[10]; /* 4 boards, 2 parameters + 2 */
520 unsigned int i;
521
522 str = get_options(str, ARRAY_SIZE(ints), ints);
523
524 for (i = 0, j = 1; i < 4; i++) {
525 if (j > ints[0])
526 break;
527 if (ints[j] >= 0)
528 io[i] = ints[j];
529 j++;
530 if (j > ints[0])
531 break;
532 if (ints[j] >= 0)
533 irq[i] = ints[j];
534 j++;
535 }
536 return 1;
537}
538__setup("ip2=", ip2_setup);
47babd4c 539
f1ddfd95 540static int __init ip2_loadmain(void)
1da177e4
LT
541{
542 int i, j, box;
543 int err = 0;
1da177e4
LT
544 i2eBordStrPtr pB = NULL;
545 int rc = -1;
547d8bb7 546 const struct firmware *fw = NULL;
02c95a62
RM
547 char *str;
548
549 str = cmd;
1da177e4 550
47babd4c
JS
551 if (poll_only) {
552 /* Hard lock the interrupts to zero */
553 irq[0] = irq[1] = irq[2] = irq[3] = poll_only = 0;
554 }
555
02c95a62
RM
556 /* Check module parameter with 'ip2=' has been passed or not */
557 if (!poll_only && (!strncmp(str, "ip2=", 4)))
558 ip2_setup(str);
559
f1ddfd95 560 ip2trace(ITRC_NO_PORT, ITRC_INIT, ITRC_ENTER, 0);
1da177e4
LT
561
562 /* process command line arguments to modprobe or
563 insmod i.e. iop & irqp */
564 /* irqp and iop should ALWAYS be specified now... But we check
565 them individually just to be sure, anyways... */
f1ddfd95 566 for (i = 0; i < IP2_MAX_BOARDS; ++i) {
47babd4c
JS
567 ip2config.addr[i] = io[i];
568 if (irq[i] >= 0)
569 ip2config.irq[i] = irq[i];
570 else
571 ip2config.irq[i] = 0;
f1ddfd95
JS
572 /* This is a little bit of a hack. If poll_only=1 on command
573 line back in ip2.c OR all IRQs on all specified boards are
574 explicitly set to 0, then drop to poll only mode and override
575 PCI or EISA interrupts. This superceeds the old hack of
576 triggering if all interrupts were zero (like da default).
577 Still a hack but less prone to random acts of terrorism.
578
579 What we really should do, now that the IRQ default is set
580 to -1, is to use 0 as a hard coded, do not probe.
581
582 /\/\|=mhw=|\/\/
583 */
47babd4c 584 poll_only |= irq[i];
1da177e4
LT
585 }
586 poll_only = !poll_only;
587
1da177e4 588 /* Announce our presence */
f1ddfd95 589 printk(KERN_INFO "%s version %s\n", pcName, pcVersion);
1da177e4
LT
590
591 ip2_tty_driver = alloc_tty_driver(IP2_MAX_PORTS);
592 if (!ip2_tty_driver)
593 return -ENOMEM;
594
1da177e4 595 /* Initialise all the boards we can find (up to the maximum). */
f1ddfd95
JS
596 for (i = 0; i < IP2_MAX_BOARDS; ++i) {
597 switch (ip2config.addr[i]) {
1da177e4
LT
598 case 0: /* skip this slot even if card is present */
599 break;
600 default: /* ISA */
601 /* ISA address must be specified */
f1ddfd95
JS
602 if (ip2config.addr[i] < 0x100 ||
603 ip2config.addr[i] > 0x3f8) {
604 printk(KERN_ERR "IP2: Bad ISA board %d "
605 "address %x\n", i,
606 ip2config.addr[i]);
1da177e4 607 ip2config.addr[i] = 0;
f1ddfd95
JS
608 break;
609 }
610 ip2config.type[i] = ISA;
611
612 /* Check for valid irq argument, set for polling if
613 * invalid */
614 if (ip2config.irq[i] &&
615 !is_valid_irq(ip2config.irq[i])) {
616 printk(KERN_ERR "IP2: Bad IRQ(%d) specified\n",
617 ip2config.irq[i]);
618 /* 0 is polling and is valid in that sense */
619 ip2config.irq[i] = 0;
1da177e4
LT
620 }
621 break;
622 case PCI:
623#ifdef CONFIG_PCI
f1ddfd95 624 {
795877cf 625 struct pci_dev *pdev = NULL;
f1ddfd95
JS
626 u32 addr;
627 int status;
628
629 pdev = pci_get_device(PCI_VENDOR_ID_COMPUTONE,
630 PCI_DEVICE_ID_COMPUTONE_IP2EX, pdev);
631 if (pdev == NULL) {
632 ip2config.addr[i] = 0;
633 printk(KERN_ERR "IP2: PCI board %d not "
634 "found\n", i);
635 break;
1da177e4 636 }
f1ddfd95
JS
637
638 if (pci_enable_device(pdev)) {
639 dev_err(&pdev->dev, "can't enable device\n");
795877cf 640 goto out;
f1ddfd95
JS
641 }
642 ip2config.type[i] = PCI;
643 ip2config.pci_dev[i] = pci_dev_get(pdev);
644 status = pci_read_config_dword(pdev, PCI_BASE_ADDRESS_1,
645 &addr);
646 if (addr & 1)
647 ip2config.addr[i] = (USHORT)(addr & 0xfffe);
648 else
649 dev_err(&pdev->dev, "I/O address error\n");
650
651 ip2config.irq[i] = pdev->irq;
795877cf
RM
652out:
653 pci_dev_put(pdev);
f1ddfd95 654 }
1da177e4 655#else
f1ddfd95
JS
656 printk(KERN_ERR "IP2: PCI card specified but PCI "
657 "support not enabled.\n");
658 printk(KERN_ERR "IP2: Recompile kernel with CONFIG_PCI "
659 "defined!\n");
1da177e4
LT
660#endif /* CONFIG_PCI */
661 break;
662 case EISA:
f1ddfd95
JS
663 ip2config.addr[i] = find_eisa_board(Eisa_slot + 1);
664 if (ip2config.addr[i] != 0) {
1da177e4
LT
665 /* Eisa_irq set as side effect, boo */
666 ip2config.type[i] = EISA;
667 }
668 ip2config.irq[i] = Eisa_irq;
669 break;
670 } /* switch */
671 } /* for */
1aff0eca 672
f1ddfd95
JS
673 for (i = 0; i < IP2_MAX_BOARDS; ++i) {
674 if (ip2config.addr[i]) {
978550b8
MK
675 pB = kzalloc(sizeof(i2eBordStr), GFP_KERNEL);
676 if (pB) {
1da177e4 677 i2BoardPtrTable[i] = pB;
f1ddfd95
JS
678 iiSetAddress(pB, ip2config.addr[i],
679 ii2DelayTimer);
680 iiReset(pB);
681 } else
682 printk(KERN_ERR "IP2: board memory allocation "
683 "error\n");
1da177e4
LT
684 }
685 }
f1ddfd95
JS
686 for (i = 0; i < IP2_MAX_BOARDS; ++i) {
687 pB = i2BoardPtrTable[i];
688 if (pB != NULL) {
689 iiResetDelay(pB);
1da177e4
LT
690 break;
691 }
692 }
f1ddfd95 693 for (i = 0; i < IP2_MAX_BOARDS; ++i) {
547d8bb7
DW
694 /* We don't want to request the firmware unless we have at
695 least one board */
f1ddfd95 696 if (i2BoardPtrTable[i] != NULL) {
547d8bb7
DW
697 if (!fw)
698 fw = ip2_request_firmware();
699 if (!fw)
700 break;
701 ip2_init_board(i, fw);
1da177e4
LT
702 }
703 }
547d8bb7
DW
704 if (fw)
705 release_firmware(fw);
1da177e4 706
f1ddfd95 707 ip2trace(ITRC_NO_PORT, ITRC_INIT, 2, 0);
1da177e4
LT
708
709 ip2_tty_driver->owner = THIS_MODULE;
710 ip2_tty_driver->name = "ttyF";
1da177e4
LT
711 ip2_tty_driver->driver_name = pcDriver_name;
712 ip2_tty_driver->major = IP2_TTY_MAJOR;
713 ip2_tty_driver->minor_start = 0;
714 ip2_tty_driver->type = TTY_DRIVER_TYPE_SERIAL;
715 ip2_tty_driver->subtype = SERIAL_TYPE_NORMAL;
716 ip2_tty_driver->init_termios = tty_std_termios;
717 ip2_tty_driver->init_termios.c_cflag = B9600|CS8|CREAD|HUPCL|CLOCAL;
f1ddfd95
JS
718 ip2_tty_driver->flags = TTY_DRIVER_REAL_RAW |
719 TTY_DRIVER_DYNAMIC_DEV;
1da177e4
LT
720 tty_set_operations(ip2_tty_driver, &ip2_ops);
721
f1ddfd95 722 ip2trace(ITRC_NO_PORT, ITRC_INIT, 3, 0);
1da177e4 723
f1ddfd95
JS
724 err = tty_register_driver(ip2_tty_driver);
725 if (err) {
726 printk(KERN_ERR "IP2: failed to register tty driver\n");
1da177e4 727 put_tty_driver(ip2_tty_driver);
f1ddfd95
JS
728 return err; /* leaking resources */
729 }
730
731 err = register_chrdev(IP2_IPL_MAJOR, pcIpl, &ip2_ipl);
732 if (err) {
733 printk(KERN_ERR "IP2: failed to register IPL device (%d)\n",
734 err);
1da177e4
LT
735 } else {
736 /* create the sysfs class */
ca8eca68 737 ip2_class = class_create(THIS_MODULE, "ip2");
1da177e4
LT
738 if (IS_ERR(ip2_class)) {
739 err = PTR_ERR(ip2_class);
740 goto out_chrdev;
741 }
742 }
743 /* Register the read_procmem thing */
4a5cdb5b 744 if (!proc_create("ip2mem",0,NULL,&ip2mem_proc_fops)) {
1da177e4 745 printk(KERN_ERR "IP2: failed to register read_procmem\n");
f1ddfd95
JS
746 return -EIO; /* leaking resources */
747 }
1da177e4 748
f1ddfd95
JS
749 ip2trace(ITRC_NO_PORT, ITRC_INIT, 4, 0);
750 /* Register the interrupt handler or poll handler, depending upon the
751 * specified interrupt.
752 */
1da177e4 753
f1ddfd95
JS
754 for (i = 0; i < IP2_MAX_BOARDS; ++i) {
755 if (ip2config.addr[i] == 0)
756 continue;
1da177e4 757
f1ddfd95
JS
758 pB = i2BoardPtrTable[i];
759 if (pB != NULL) {
03457cd4
GKH
760 device_create(ip2_class, NULL,
761 MKDEV(IP2_IPL_MAJOR, 4 * i),
762 NULL, "ipl%d", i);
763 device_create(ip2_class, NULL,
764 MKDEV(IP2_IPL_MAJOR, 4 * i + 1),
765 NULL, "stat%d", i);
f1ddfd95
JS
766
767 for (box = 0; box < ABS_MAX_BOXES; box++)
768 for (j = 0; j < ABS_BIGGEST_BOX; j++)
769 if (pB->i2eChannelMap[box] & (1 << j))
770 tty_register_device(
771 ip2_tty_driver,
772 j + ABS_BIGGEST_BOX *
773 (box+i*ABS_MAX_BOXES),
774 NULL);
775 }
1da177e4 776
f1ddfd95
JS
777 if (poll_only) {
778 /* Poll only forces driver to only use polling and
779 to ignore the probed PCI or EISA interrupts. */
780 ip2config.irq[i] = CIR_POLL;
781 }
782 if (ip2config.irq[i] == CIR_POLL) {
1da177e4 783retry:
9d020a2e
AM
784 if (!timer_pending(&PollTimer)) {
785 mod_timer(&PollTimer, POLL_TIMEOUT);
f1ddfd95 786 printk(KERN_INFO "IP2: polling\n");
1da177e4 787 }
f1ddfd95
JS
788 } else {
789 if (have_requested_irq(ip2config.irq[i]))
790 continue;
791 rc = request_irq(ip2config.irq[i], ip2_interrupt,
792 IP2_SA_FLAGS |
793 (ip2config.type[i] == PCI ? IRQF_SHARED : 0),
794 pcName, i2BoardPtrTable[i]);
795 if (rc) {
796 printk(KERN_ERR "IP2: request_irq failed: "
797 "error %d\n", rc);
798 ip2config.irq[i] = CIR_POLL;
799 printk(KERN_INFO "IP2: Polling %ld/sec.\n",
800 (POLL_TIMEOUT - jiffies));
801 goto retry;
1da177e4 802 }
f1ddfd95
JS
803 mark_requested_irq(ip2config.irq[i]);
804 /* Initialise the interrupt handler bottom half
805 * (aka slih). */
1da177e4
LT
806 }
807 }
f1ddfd95
JS
808
809 for (i = 0; i < IP2_MAX_BOARDS; ++i) {
810 if (i2BoardPtrTable[i]) {
811 /* set and enable board interrupt */
812 set_irq(i, ip2config.irq[i]);
813 }
814 }
815
816 ip2trace(ITRC_NO_PORT, ITRC_INIT, ITRC_RETURN, 0);
817
818 return 0;
1da177e4 819
1da177e4
LT
820out_chrdev:
821 unregister_chrdev(IP2_IPL_MAJOR, "ip2");
f1ddfd95 822 /* unregister and put tty here */
1da177e4
LT
823 return err;
824}
47babd4c 825module_init(ip2_loadmain);
1da177e4 826
1da177e4
LT
827/******************************************************************************/
828/* Function: ip2_init_board() */
829/* Parameters: Index of board in configuration structure */
830/* Returns: Success (0) */
831/* */
832/* Description: */
833/* This function initializes the specified board. The loadware is copied to */
834/* the board, the channel structures are initialized, and the board details */
835/* are reported on the console. */
836/******************************************************************************/
673e321c 837static void
547d8bb7 838ip2_init_board(int boardnum, const struct firmware *fw)
1da177e4
LT
839{
840 int i;
841 int nports = 0, nboxes = 0;
842 i2ChanStrPtr pCh;
843 i2eBordStrPtr pB = i2BoardPtrTable[boardnum];
844
845 if ( !iiInitialize ( pB ) ) {
846 printk ( KERN_ERR "IP2: Failed to initialize board at 0x%x, error %d\n",
847 pB->i2eBase, pB->i2eError );
848 goto err_initialize;
849 }
850 printk(KERN_INFO "IP2: Board %d: addr=0x%x irq=%d\n", boardnum + 1,
851 ip2config.addr[boardnum], ip2config.irq[boardnum] );
852
853 if (!request_region( ip2config.addr[boardnum], 8, pcName )) {
854 printk(KERN_ERR "IP2: bad addr=0x%x\n", ip2config.addr[boardnum]);
855 goto err_initialize;
856 }
857
547d8bb7 858 if ( iiDownloadAll ( pB, (loadHdrStrPtr)fw->data, 1, fw->size )
1da177e4
LT
859 != II_DOWN_GOOD ) {
860 printk ( KERN_ERR "IP2: failed to download loadware\n" );
861 goto err_release_region;
862 } else {
863 printk ( KERN_INFO "IP2: fv=%d.%d.%d lv=%d.%d.%d\n",
864 pB->i2ePom.e.porVersion,
865 pB->i2ePom.e.porRevision,
866 pB->i2ePom.e.porSubRev, pB->i2eLVersion,
867 pB->i2eLRevision, pB->i2eLSub );
868 }
869
870 switch ( pB->i2ePom.e.porID & ~POR_ID_RESERVED ) {
871
872 default:
873 printk( KERN_ERR "IP2: Unknown board type, ID = %x\n",
874 pB->i2ePom.e.porID );
875 nports = 0;
876 goto err_release_region;
877 break;
878
879 case POR_ID_II_4: /* IntelliPort-II, ISA-4 (4xRJ45) */
880 printk ( KERN_INFO "IP2: ISA-4\n" );
881 nports = 4;
882 break;
883
884 case POR_ID_II_8: /* IntelliPort-II, 8-port using standard brick. */
885 printk ( KERN_INFO "IP2: ISA-8 std\n" );
886 nports = 8;
887 break;
888
889 case POR_ID_II_8R: /* IntelliPort-II, 8-port using RJ11's (no CTS) */
890 printk ( KERN_INFO "IP2: ISA-8 RJ11\n" );
891 nports = 8;
892 break;
893
894 case POR_ID_FIIEX: /* IntelliPort IIEX */
895 {
896 int portnum = IP2_PORTS_PER_BOARD * boardnum;
897 int box;
898
899 for( box = 0; box < ABS_MAX_BOXES; ++box ) {
900 if ( pB->i2eChannelMap[box] != 0 ) {
901 ++nboxes;
902 }
903 for( i = 0; i < ABS_BIGGEST_BOX; ++i ) {
904 if ( pB->i2eChannelMap[box] & 1<< i ) {
905 ++nports;
906 }
907 }
908 }
909 DevTableMem[boardnum] = pCh =
910 kmalloc( sizeof(i2ChanStr) * nports, GFP_KERNEL );
911 if ( !pCh ) {
912 printk ( KERN_ERR "IP2: (i2_init_channel:) Out of memory.\n");
913 goto err_release_region;
914 }
915 if ( !i2InitChannels( pB, nports, pCh ) ) {
916 printk(KERN_ERR "IP2: i2InitChannels failed: %d\n",pB->i2eError);
917 kfree ( pCh );
918 goto err_release_region;
919 }
920 pB->i2eChannelPtr = &DevTable[portnum];
921 pB->i2eChannelCnt = ABS_MOST_PORTS;
922
923 for( box = 0; box < ABS_MAX_BOXES; ++box, portnum += ABS_BIGGEST_BOX ) {
924 for( i = 0; i < ABS_BIGGEST_BOX; ++i ) {
925 if ( pB->i2eChannelMap[box] & (1 << i) ) {
926 DevTable[portnum + i] = pCh;
927 pCh->port_index = portnum + i;
928 pCh++;
929 }
930 }
931 }
932 printk(KERN_INFO "IP2: EX box=%d ports=%d %d bit\n",
933 nboxes, nports, pB->i2eDataWidth16 ? 16 : 8 );
934 }
935 goto ex_exit;
936 }
937 DevTableMem[boardnum] = pCh =
938 kmalloc ( sizeof (i2ChanStr) * nports, GFP_KERNEL );
939 if ( !pCh ) {
940 printk ( KERN_ERR "IP2: (i2_init_channel:) Out of memory.\n");
941 goto err_release_region;
942 }
943 pB->i2eChannelPtr = pCh;
944 pB->i2eChannelCnt = nports;
945 if ( !i2InitChannels( pB, nports, pCh ) ) {
946 printk(KERN_ERR "IP2: i2InitChannels failed: %d\n",pB->i2eError);
947 kfree ( pCh );
948 goto err_release_region;
949 }
950 pB->i2eChannelPtr = &DevTable[IP2_PORTS_PER_BOARD * boardnum];
951
952 for( i = 0; i < pB->i2eChannelCnt; ++i ) {
953 DevTable[IP2_PORTS_PER_BOARD * boardnum + i] = pCh;
954 pCh->port_index = (IP2_PORTS_PER_BOARD * boardnum) + i;
955 pCh++;
956 }
957ex_exit:
c4028958 958 INIT_WORK(&pB->tqueue_interrupt, ip2_interrupt_bh);
1da177e4
LT
959 return;
960
961err_release_region:
962 release_region(ip2config.addr[boardnum], 8);
963err_initialize:
964 kfree ( pB );
965 i2BoardPtrTable[boardnum] = NULL;
966 return;
967}
968
969/******************************************************************************/
970/* Function: find_eisa_board ( int start_slot ) */
971/* Parameters: First slot to check */
972/* Returns: Address of EISA IntelliPort II controller */
973/* */
974/* Description: */
975/* This function searches for an EISA IntelliPort controller, starting */
976/* from the specified slot number. If the motherboard is not identified as an */
977/* EISA motherboard, or no valid board ID is selected it returns 0. Otherwise */
978/* it returns the base address of the controller. */
979/******************************************************************************/
673e321c 980static unsigned short
1da177e4
LT
981find_eisa_board( int start_slot )
982{
983 int i, j;
984 unsigned int idm = 0;
985 unsigned int idp = 0;
986 unsigned int base = 0;
987 unsigned int value;
988 int setup_address;
989 int setup_irq;
990 int ismine = 0;
991
992 /*
993 * First a check for an EISA motherboard, which we do by comparing the
994 * EISA ID registers for the system board and the first couple of slots.
995 * No slot ID should match the system board ID, but on an ISA or PCI
996 * machine the odds are that an empty bus will return similar values for
997 * each slot.
998 */
999 i = 0x0c80;
1000 value = (inb(i) << 24) + (inb(i+1) << 16) + (inb(i+2) << 8) + inb(i+3);
1001 for( i = 0x1c80; i <= 0x4c80; i += 0x1000 ) {
1002 j = (inb(i)<<24)+(inb(i+1)<<16)+(inb(i+2)<<8)+inb(i+3);
1003 if ( value == j )
1004 return 0;
1005 }
1006
1007 /*
1008 * OK, so we are inclined to believe that this is an EISA machine. Find
1009 * an IntelliPort controller.
1010 */
1011 for( i = start_slot; i < 16; i++ ) {
1012 base = i << 12;
1013 idm = (inb(base + 0xc80) << 8) | (inb(base + 0xc81) & 0xff);
1014 idp = (inb(base + 0xc82) << 8) | (inb(base + 0xc83) & 0xff);
1015 ismine = 0;
1016 if ( idm == 0x0e8e ) {
1017 if ( idp == 0x0281 || idp == 0x0218 ) {
1018 ismine = 1;
1019 } else if ( idp == 0x0282 || idp == 0x0283 ) {
1020 ismine = 3; /* Can do edge-trigger */
1021 }
1022 if ( ismine ) {
1023 Eisa_slot = i;
1024 break;
1025 }
1026 }
1027 }
1028 if ( !ismine )
1029 return 0;
1030
1031 /* It's some sort of EISA card, but at what address is it configured? */
1032
1033 setup_address = base + 0xc88;
1034 value = inb(base + 0xc86);
1035 setup_irq = (value & 8) ? Valid_Irqs[value & 7] : 0;
1036
1037 if ( (ismine & 2) && !(value & 0x10) ) {
1038 ismine = 1; /* Could be edging, but not */
1039 }
1040
1041 if ( Eisa_irq == 0 ) {
1042 Eisa_irq = setup_irq;
1043 } else if ( Eisa_irq != setup_irq ) {
1044 printk ( KERN_ERR "IP2: EISA irq mismatch between EISA controllers\n" );
1045 }
1046
1047#ifdef IP2DEBUG_INIT
1048printk(KERN_DEBUG "Computone EISA board in slot %d, I.D. 0x%x%x, Address 0x%x",
1049 base >> 12, idm, idp, setup_address);
1050 if ( Eisa_irq ) {
1051 printk(KERN_DEBUG ", Interrupt %d %s\n",
1052 setup_irq, (ismine & 2) ? "(edge)" : "(level)");
1053 } else {
1054 printk(KERN_DEBUG ", (polled)\n");
1055 }
1056#endif
1057 return setup_address;
1058}
1059
1060/******************************************************************************/
1061/* Function: set_irq() */
1062/* Parameters: index to board in board table */
1063/* IRQ to use */
1064/* Returns: Success (0) */
1065/* */
1066/* Description: */
1067/******************************************************************************/
1068static void
1069set_irq( int boardnum, int boardIrq )
1070{
1071 unsigned char tempCommand[16];
1072 i2eBordStrPtr pB = i2BoardPtrTable[boardnum];
1073 unsigned long flags;
1074
1075 /*
1076 * Notify the boards they may generate interrupts. This is done by
1077 * sending an in-line command to channel 0 on each board. This is why
1078 * the channels have to be defined already. For each board, if the
1079 * interrupt has never been defined, we must do so NOW, directly, since
1080 * board will not send flow control or even give an interrupt until this
1081 * is done. If polling we must send 0 as the interrupt parameter.
1082 */
1083
1084 // We will get an interrupt here at the end of this function
1085
1086 iiDisableMailIrq(pB);
1087
1088 /* We build up the entire packet header. */
1089 CHANNEL_OF(tempCommand) = 0;
1090 PTYPE_OF(tempCommand) = PTYPE_INLINE;
1091 CMD_COUNT_OF(tempCommand) = 2;
1092 (CMD_OF(tempCommand))[0] = CMDVALUE_IRQ;
1093 (CMD_OF(tempCommand))[1] = boardIrq;
1094 /*
1095 * Write to FIFO; don't bother to adjust fifo capacity for this, since
1096 * board will respond almost immediately after SendMail hit.
1097 */
cf1c63c3 1098 write_lock_irqsave(&pB->write_fifo_spinlock, flags);
1da177e4 1099 iiWriteBuf(pB, tempCommand, 4);
cf1c63c3 1100 write_unlock_irqrestore(&pB->write_fifo_spinlock, flags);
1da177e4
LT
1101 pB->i2eUsingIrq = boardIrq;
1102 pB->i2eOutMailWaiting |= MB_OUT_STUFFED;
1103
1104 /* Need to update number of boards before you enable mailbox int */
1105 ++i2nBoards;
1106
1107 CHANNEL_OF(tempCommand) = 0;
1108 PTYPE_OF(tempCommand) = PTYPE_BYPASS;
1109 CMD_COUNT_OF(tempCommand) = 6;
1110 (CMD_OF(tempCommand))[0] = 88; // SILO
1111 (CMD_OF(tempCommand))[1] = 64; // chars
1112 (CMD_OF(tempCommand))[2] = 32; // ms
1113
1114 (CMD_OF(tempCommand))[3] = 28; // MAX_BLOCK
1115 (CMD_OF(tempCommand))[4] = 64; // chars
1116
1117 (CMD_OF(tempCommand))[5] = 87; // HW_TEST
cf1c63c3 1118 write_lock_irqsave(&pB->write_fifo_spinlock, flags);
1da177e4 1119 iiWriteBuf(pB, tempCommand, 8);
cf1c63c3 1120 write_unlock_irqrestore(&pB->write_fifo_spinlock, flags);
1da177e4
LT
1121
1122 CHANNEL_OF(tempCommand) = 0;
1123 PTYPE_OF(tempCommand) = PTYPE_BYPASS;
1124 CMD_COUNT_OF(tempCommand) = 1;
1125 (CMD_OF(tempCommand))[0] = 84; /* get BOX_IDS */
1126 iiWriteBuf(pB, tempCommand, 3);
1127
1128#ifdef XXX
1129 // enable heartbeat for test porpoises
1130 CHANNEL_OF(tempCommand) = 0;
1131 PTYPE_OF(tempCommand) = PTYPE_BYPASS;
1132 CMD_COUNT_OF(tempCommand) = 2;
1133 (CMD_OF(tempCommand))[0] = 44; /* get ping */
1134 (CMD_OF(tempCommand))[1] = 200; /* 200 ms */
cf1c63c3 1135 write_lock_irqsave(&pB->write_fifo_spinlock, flags);
1da177e4 1136 iiWriteBuf(pB, tempCommand, 4);
cf1c63c3 1137 write_unlock_irqrestore(&pB->write_fifo_spinlock, flags);
1da177e4
LT
1138#endif
1139
1140 iiEnableMailIrq(pB);
1141 iiSendPendingMail(pB);
1142}
1143
1144/******************************************************************************/
1145/* Interrupt Handler Section */
1146/******************************************************************************/
1147
1148static inline void
1149service_all_boards(void)
1150{
1151 int i;
1152 i2eBordStrPtr pB;
1153
1154 /* Service every board on the list */
1155 for( i = 0; i < IP2_MAX_BOARDS; ++i ) {
1156 pB = i2BoardPtrTable[i];
1157 if ( pB ) {
1158 i2ServiceBoard( pB );
1159 }
1160 }
1161}
1162
1163
1164/******************************************************************************/
c4028958
DH
1165/* Function: ip2_interrupt_bh(work) */
1166/* Parameters: work - pointer to the board structure */
1da177e4
LT
1167/* Returns: Nothing */
1168/* */
1169/* Description: */
1170/* Service the board in a bottom half interrupt handler and then */
1171/* reenable the board's interrupts if it has an IRQ number */
1172/* */
1173/******************************************************************************/
1174static void
c4028958 1175ip2_interrupt_bh(struct work_struct *work)
1da177e4 1176{
c4028958 1177 i2eBordStrPtr pB = container_of(work, i2eBordStr, tqueue_interrupt);
1da177e4
LT
1178// pB better well be set or we have a problem! We can only get
1179// here from the IMMEDIATE queue. Here, we process the boards.
1180// Checking pB doesn't cost much and it saves us from the sanity checkers.
1181
1182 bh_counter++;
1183
1184 if ( pB ) {
1185 i2ServiceBoard( pB );
1186 if( pB->i2eUsingIrq ) {
1187// Re-enable his interrupts
1188 iiEnableMailIrq(pB);
1189 }
1190 }
1191}
1192
1193
1194/******************************************************************************/
7d12e780 1195/* Function: ip2_interrupt(int irq, void *dev_id) */
1da177e4
LT
1196/* Parameters: irq - interrupt number */
1197/* pointer to optional device ID structure */
1da177e4
LT
1198/* Returns: Nothing */
1199/* */
1200/* Description: */
1201/* */
1202/* Our task here is simply to identify each board which needs servicing. */
1203/* If we are queuing then, queue it to be serviced, and disable its irq */
1204/* mask otherwise process the board directly. */
1205/* */
1206/* We could queue by IRQ but that just complicates things on both ends */
1207/* with very little gain in performance (how many instructions does */
1208/* it take to iterate on the immediate queue). */
1209/* */
1210/* */
1211/******************************************************************************/
f3518e4e
JG
1212static void
1213ip2_irq_work(i2eBordStrPtr pB)
1214{
1215#ifdef USE_IQI
1216 if (NO_MAIL_HERE != ( pB->i2eStartMail = iiGetMail(pB))) {
1217// Disable his interrupt (will be enabled when serviced)
1218// This is mostly to protect from reentrancy.
1219 iiDisableMailIrq(pB);
1220
1221// Park the board on the immediate queue for processing.
1222 schedule_work(&pB->tqueue_interrupt);
1223
1224// Make sure the immediate queue is flagged to fire.
1225 }
1226#else
1227
1228// We are using immediate servicing here. This sucks and can
1229// cause all sorts of havoc with ppp and others. The failsafe
1230// check on iiSendPendingMail could also throw a hairball.
1231
1232 i2ServiceBoard( pB );
1233
1234#endif /* USE_IQI */
1235}
1236
6bd3bd67
JG
1237static void
1238ip2_polled_interrupt(void)
1da177e4
LT
1239{
1240 int i;
1241 i2eBordStrPtr pB;
1da177e4 1242
7ccd7020 1243 ip2trace(ITRC_NO_PORT, ITRC_INTR, 99, 1, 0);
1da177e4
LT
1244
1245 /* Service just the boards on the list using this irq */
1246 for( i = 0; i < i2nBoards; ++i ) {
1247 pB = i2BoardPtrTable[i];
1248
1249// Only process those boards which match our IRQ.
1250// IRQ = 0 for polled boards, we won't poll "IRQ" boards
1251
7ccd7020 1252 if (pB && pB->i2eUsingIrq == 0)
f3518e4e 1253 ip2_irq_work(pB);
1da177e4
LT
1254 }
1255
1256 ++irq_counter;
1257
1258 ip2trace (ITRC_NO_PORT, ITRC_INTR, ITRC_RETURN, 0 );
6bd3bd67
JG
1259}
1260
1261static irqreturn_t
1262ip2_interrupt(int irq, void *dev_id)
1263{
1264 i2eBordStrPtr pB = dev_id;
1265
1266 ip2trace (ITRC_NO_PORT, ITRC_INTR, 99, 1, pB->i2eUsingIrq );
1267
1268 ip2_irq_work(pB);
1269
1270 ++irq_counter;
1271
1272 ip2trace (ITRC_NO_PORT, ITRC_INTR, ITRC_RETURN, 0 );
1273 return IRQ_HANDLED;
1da177e4
LT
1274}
1275
1276/******************************************************************************/
1277/* Function: ip2_poll(unsigned long arg) */
1278/* Parameters: ? */
1279/* Returns: Nothing */
1280/* */
1281/* Description: */
1282/* This function calls the library routine i2ServiceBoard for each board in */
1283/* the board table. This is used instead of the interrupt routine when polled */
1284/* mode is specified. */
1285/******************************************************************************/
1286static void
1287ip2_poll(unsigned long arg)
1288{
1289 ip2trace (ITRC_NO_PORT, ITRC_INTR, 100, 0 );
1290
1da177e4
LT
1291 // Just polled boards, IRQ = 0 will hit all non-interrupt boards.
1292 // It will NOT poll boards handled by hard interrupts.
8dfba4d7 1293 // The issue of queued BH interrupts is handled in ip2_interrupt().
6bd3bd67 1294 ip2_polled_interrupt();
1da177e4 1295
9d020a2e 1296 mod_timer(&PollTimer, POLL_TIMEOUT);
1da177e4
LT
1297
1298 ip2trace (ITRC_NO_PORT, ITRC_INTR, ITRC_RETURN, 0 );
1299}
1300
c4028958 1301static void do_input(struct work_struct *work)
1da177e4 1302{
c4028958 1303 i2ChanStrPtr pCh = container_of(work, i2ChanStr, tqueue_input);
1da177e4
LT
1304 unsigned long flags;
1305
1306 ip2trace(CHANN, ITRC_INPUT, 21, 0 );
1307
1308 // Data input
1309 if ( pCh->pTTY != NULL ) {
cf1c63c3 1310 read_lock_irqsave(&pCh->Ibuf_spinlock, flags);
1da177e4 1311 if (!pCh->throttled && (pCh->Ibuf_stuff != pCh->Ibuf_strip)) {
cf1c63c3 1312 read_unlock_irqrestore(&pCh->Ibuf_spinlock, flags);
1da177e4
LT
1313 i2Input( pCh );
1314 } else
cf1c63c3 1315 read_unlock_irqrestore(&pCh->Ibuf_spinlock, flags);
1da177e4
LT
1316 } else {
1317 ip2trace(CHANN, ITRC_INPUT, 22, 0 );
1318
1319 i2InputFlush( pCh );
1320 }
1321}
1322
1323// code duplicated from n_tty (ldisc)
1324static inline void isig(int sig, struct tty_struct *tty, int flush)
1325{
a352def2 1326 /* FIXME: This is completely bogus */
ab521dc0
EB
1327 if (tty->pgrp)
1328 kill_pgrp(tty->pgrp, sig, 1);
1da177e4 1329 if (flush || !L_NOFLSH(tty)) {
c65c9bc3
AC
1330 if ( tty->ldisc->ops->flush_buffer )
1331 tty->ldisc->ops->flush_buffer(tty);
1da177e4
LT
1332 i2InputFlush( tty->driver_data );
1333 }
1334}
1335
c4028958 1336static void do_status(struct work_struct *work)
1da177e4 1337{
c4028958 1338 i2ChanStrPtr pCh = container_of(work, i2ChanStr, tqueue_status);
1da177e4
LT
1339 int status;
1340
1341 status = i2GetStatus( pCh, (I2_BRK|I2_PAR|I2_FRA|I2_OVR) );
1342
1343 ip2trace (CHANN, ITRC_STATUS, 21, 1, status );
1344
1345 if (pCh->pTTY && (status & (I2_BRK|I2_PAR|I2_FRA|I2_OVR)) ) {
1346 if ( (status & I2_BRK) ) {
1347 // code duplicated from n_tty (ldisc)
1348 if (I_IGNBRK(pCh->pTTY))
1349 goto skip_this;
1350 if (I_BRKINT(pCh->pTTY)) {
1351 isig(SIGINT, pCh->pTTY, 1);
1352 goto skip_this;
1353 }
1354 wake_up_interruptible(&pCh->pTTY->read_wait);
1355 }
1356#ifdef NEVER_HAPPENS_AS_SETUP_XXX
1357 // and can't work because we don't know the_char
1358 // as the_char is reported on a separate path
1359 // The intelligent board does this stuff as setup
1360 {
1361 char brkf = TTY_NORMAL;
1362 unsigned char brkc = '\0';
1363 unsigned char tmp;
1364 if ( (status & I2_BRK) ) {
1365 brkf = TTY_BREAK;
1366 brkc = '\0';
1367 }
1368 else if (status & I2_PAR) {
1369 brkf = TTY_PARITY;
1370 brkc = the_char;
1371 } else if (status & I2_FRA) {
1372 brkf = TTY_FRAME;
1373 brkc = the_char;
1374 } else if (status & I2_OVR) {
1375 brkf = TTY_OVERRUN;
1376 brkc = the_char;
1377 }
1378 tmp = pCh->pTTY->real_raw;
1379 pCh->pTTY->real_raw = 0;
a352def2 1380 pCh->pTTY->ldisc->ops.receive_buf( pCh->pTTY, &brkc, &brkf, 1 );
1da177e4
LT
1381 pCh->pTTY->real_raw = tmp;
1382 }
1383#endif /* NEVER_HAPPENS_AS_SETUP_XXX */
1384 }
1385skip_this:
1386
1387 if ( status & (I2_DDCD | I2_DDSR | I2_DCTS | I2_DRI) ) {
1388 wake_up_interruptible(&pCh->delta_msr_wait);
1389
1390 if ( (pCh->flags & ASYNC_CHECK_CD) && (status & I2_DDCD) ) {
1391 if ( status & I2_DCD ) {
1392 if ( pCh->wopen ) {
1393 wake_up_interruptible ( &pCh->open_wait );
1394 }
1395 } else {
1396 if (pCh->pTTY && (!(pCh->pTTY->termios->c_cflag & CLOCAL)) ) {
1397 tty_hangup( pCh->pTTY );
1398 }
1399 }
1400 }
1401 }
1402
1403 ip2trace (CHANN, ITRC_STATUS, 26, 0 );
1404}
1405
1406/******************************************************************************/
1407/* Device Open/Close/Ioctl Entry Point Section */
1408/******************************************************************************/
1409
1410/******************************************************************************/
1411/* Function: open_sanity_check() */
1412/* Parameters: Pointer to tty structure */
1413/* Pointer to file structure */
1414/* Returns: Success or failure */
1415/* */
1416/* Description: */
1417/* Verifies the structure magic numbers and cross links. */
1418/******************************************************************************/
1419#ifdef IP2DEBUG_OPEN
1420static void
1421open_sanity_check( i2ChanStrPtr pCh, i2eBordStrPtr pBrd )
1422{
1423 if ( pBrd->i2eValid != I2E_MAGIC ) {
1424 printk(KERN_ERR "IP2: invalid board structure\n" );
1425 } else if ( pBrd != pCh->pMyBord ) {
1426 printk(KERN_ERR "IP2: board structure pointer mismatch (%p)\n",
1427 pCh->pMyBord );
1428 } else if ( pBrd->i2eChannelCnt < pCh->port_index ) {
1429 printk(KERN_ERR "IP2: bad device index (%d)\n", pCh->port_index );
1430 } else if (&((i2ChanStrPtr)pBrd->i2eChannelPtr)[pCh->port_index] != pCh) {
1431 } else {
1432 printk(KERN_INFO "IP2: all pointers check out!\n" );
1433 }
1434}
1435#endif
1436
1437
1438/******************************************************************************/
1439/* Function: ip2_open() */
1440/* Parameters: Pointer to tty structure */
1441/* Pointer to file structure */
1442/* Returns: Success or failure */
1443/* */
1444/* Description: (MANDATORY) */
1445/* A successful device open has to run a gauntlet of checks before it */
1446/* completes. After some sanity checking and pointer setup, the function */
1447/* blocks until all conditions are satisfied. It then initialises the port to */
1448/* the default characteristics and returns. */
1449/******************************************************************************/
1450static int
1451ip2_open( PTTY tty, struct file *pFile )
1452{
1453 wait_queue_t wait;
1454 int rc = 0;
1455 int do_clocal = 0;
1456 i2ChanStrPtr pCh = DevTable[tty->index];
1457
1458 ip2trace (tty->index, ITRC_OPEN, ITRC_ENTER, 0 );
1459
1460 if ( pCh == NULL ) {
1461 return -ENODEV;
1462 }
1463 /* Setup pointer links in device and tty structures */
1464 pCh->pTTY = tty;
1465 tty->driver_data = pCh;
1466
1467#ifdef IP2DEBUG_OPEN
1468 printk(KERN_DEBUG \
1469 "IP2:open(tty=%p,pFile=%p):dev=%s,ch=%d,idx=%d\n",
1470 tty, pFile, tty->name, pCh->infl.hd.i2sChannel, pCh->port_index);
1471 open_sanity_check ( pCh, pCh->pMyBord );
1472#endif
1473
1474 i2QueueCommands(PTYPE_INLINE, pCh, 100, 3, CMD_DTRUP,CMD_RTSUP,CMD_DCD_REP);
1475 pCh->dataSetOut |= (I2_DTR | I2_RTS);
1476 serviceOutgoingFifo( pCh->pMyBord );
1477
1478 /* Block here until the port is ready (per serial and istallion) */
1479 /*
1480 * 1. If the port is in the middle of closing wait for the completion
1481 * and then return the appropriate error.
1482 */
1483 init_waitqueue_entry(&wait, current);
1484 add_wait_queue(&pCh->close_wait, &wait);
1485 set_current_state( TASK_INTERRUPTIBLE );
1486
1487 if ( tty_hung_up_p(pFile) || ( pCh->flags & ASYNC_CLOSING )) {
1488 if ( pCh->flags & ASYNC_CLOSING ) {
1489 schedule();
1490 }
1491 if ( tty_hung_up_p(pFile) ) {
1492 set_current_state( TASK_RUNNING );
1493 remove_wait_queue(&pCh->close_wait, &wait);
1494 return( pCh->flags & ASYNC_HUP_NOTIFY ) ? -EAGAIN : -ERESTARTSYS;
1495 }
1496 }
1497 set_current_state( TASK_RUNNING );
1498 remove_wait_queue(&pCh->close_wait, &wait);
1499
1500 /*
1501 * 3. Handle a non-blocking open of a normal port.
1502 */
1503 if ( (pFile->f_flags & O_NONBLOCK) || (tty->flags & (1<<TTY_IO_ERROR) )) {
1504 pCh->flags |= ASYNC_NORMAL_ACTIVE;
1505 goto noblock;
1506 }
1507 /*
1508 * 4. Now loop waiting for the port to be free and carrier present
1509 * (if required).
1510 */
1511 if ( tty->termios->c_cflag & CLOCAL )
1512 do_clocal = 1;
1513
1514#ifdef IP2DEBUG_OPEN
1515 printk(KERN_DEBUG "OpenBlock: do_clocal = %d\n", do_clocal);
1516#endif
1517
1518 ++pCh->wopen;
1519
1520 init_waitqueue_entry(&wait, current);
1521 add_wait_queue(&pCh->open_wait, &wait);
1522
1523 for(;;) {
1524 i2QueueCommands(PTYPE_INLINE, pCh, 100, 2, CMD_DTRUP, CMD_RTSUP);
1525 pCh->dataSetOut |= (I2_DTR | I2_RTS);
1526 set_current_state( TASK_INTERRUPTIBLE );
1527 serviceOutgoingFifo( pCh->pMyBord );
1528 if ( tty_hung_up_p(pFile) ) {
1529 set_current_state( TASK_RUNNING );
1530 remove_wait_queue(&pCh->open_wait, &wait);
1531 return ( pCh->flags & ASYNC_HUP_NOTIFY ) ? -EBUSY : -ERESTARTSYS;
1532 }
1533 if (!(pCh->flags & ASYNC_CLOSING) &&
1534 (do_clocal || (pCh->dataSetIn & I2_DCD) )) {
1535 rc = 0;
1536 break;
1537 }
1538
1539#ifdef IP2DEBUG_OPEN
1540 printk(KERN_DEBUG "ASYNC_CLOSING = %s\n",
1541 (pCh->flags & ASYNC_CLOSING)?"True":"False");
1542 printk(KERN_DEBUG "OpenBlock: waiting for CD or signal\n");
1543#endif
1544 ip2trace (CHANN, ITRC_OPEN, 3, 2, 0,
1545 (pCh->flags & ASYNC_CLOSING) );
1546 /* check for signal */
1547 if (signal_pending(current)) {
1548 rc = (( pCh->flags & ASYNC_HUP_NOTIFY ) ? -EAGAIN : -ERESTARTSYS);
1549 break;
1550 }
1551 schedule();
1552 }
1553 set_current_state( TASK_RUNNING );
1554 remove_wait_queue(&pCh->open_wait, &wait);
1555
1556 --pCh->wopen; //why count?
1557
1558 ip2trace (CHANN, ITRC_OPEN, 4, 0 );
1559
1560 if (rc != 0 ) {
1561 return rc;
1562 }
1563 pCh->flags |= ASYNC_NORMAL_ACTIVE;
1564
1565noblock:
1566
1567 /* first open - Assign termios structure to port */
1568 if ( tty->count == 1 ) {
1569 i2QueueCommands(PTYPE_INLINE, pCh, 0, 2, CMD_CTSFL_DSAB, CMD_RTSFL_DSAB);
1570 /* Now we must send the termios settings to the loadware */
1571 set_params( pCh, NULL );
1572 }
1573
1574 /*
1575 * Now set any i2lib options. These may go away if the i2lib code ends
1576 * up rolled into the mainline.
1577 */
1578 pCh->channelOptions |= CO_NBLOCK_WRITE;
1579
1580#ifdef IP2DEBUG_OPEN
1581 printk (KERN_DEBUG "IP2: open completed\n" );
1582#endif
1583 serviceOutgoingFifo( pCh->pMyBord );
1584
1585 ip2trace (CHANN, ITRC_OPEN, ITRC_RETURN, 0 );
1586
1587 return 0;
1588}
1589
1590/******************************************************************************/
1591/* Function: ip2_close() */
1592/* Parameters: Pointer to tty structure */
1593/* Pointer to file structure */
1594/* Returns: Nothing */
1595/* */
1596/* Description: */
1597/* */
1598/* */
1599/******************************************************************************/
1600static void
1601ip2_close( PTTY tty, struct file *pFile )
1602{
1603 i2ChanStrPtr pCh = tty->driver_data;
1604
1605 if ( !pCh ) {
1606 return;
1607 }
1608
1609 ip2trace (CHANN, ITRC_CLOSE, ITRC_ENTER, 0 );
1610
1611#ifdef IP2DEBUG_OPEN
1612 printk(KERN_DEBUG "IP2:close %s:\n",tty->name);
1613#endif
1614
1615 if ( tty_hung_up_p ( pFile ) ) {
1616
1617 ip2trace (CHANN, ITRC_CLOSE, 2, 1, 2 );
1618
1619 return;
1620 }
1621 if ( tty->count > 1 ) { /* not the last close */
1622
1623 ip2trace (CHANN, ITRC_CLOSE, 2, 1, 3 );
1624
1625 return;
1626 }
1627 pCh->flags |= ASYNC_CLOSING; // last close actually
1628
1629 tty->closing = 1;
1630
1631 if (pCh->ClosingWaitTime != ASYNC_CLOSING_WAIT_NONE) {
1632 /*
1633 * Before we drop DTR, make sure the transmitter has completely drained.
1634 * This uses an timeout, after which the close
1635 * completes.
1636 */
1637 ip2_wait_until_sent(tty, pCh->ClosingWaitTime );
1638 }
1639 /*
1640 * At this point we stop accepting input. Here we flush the channel
1641 * input buffer which will allow the board to send up more data. Any
1642 * additional input is tossed at interrupt/poll time.
1643 */
1644 i2InputFlush( pCh );
1645
1646 /* disable DSS reporting */
1647 i2QueueCommands(PTYPE_INLINE, pCh, 100, 4,
1648 CMD_DCD_NREP, CMD_CTS_NREP, CMD_DSR_NREP, CMD_RI_NREP);
1649 if ( !tty || (tty->termios->c_cflag & HUPCL) ) {
1650 i2QueueCommands(PTYPE_INLINE, pCh, 100, 2, CMD_RTSDN, CMD_DTRDN);
1651 pCh->dataSetOut &= ~(I2_DTR | I2_RTS);
1652 i2QueueCommands( PTYPE_INLINE, pCh, 100, 1, CMD_PAUSE(25));
1653 }
1654
1655 serviceOutgoingFifo ( pCh->pMyBord );
1656
f34d7a5b 1657 tty_ldisc_flush(tty);
a6fc819e 1658 tty_driver_flush_buffer(tty);
1da177e4
LT
1659 tty->closing = 0;
1660
1661 pCh->pTTY = NULL;
1662
1663 if (pCh->wopen) {
1664 if (pCh->ClosingDelay) {
1665 msleep_interruptible(jiffies_to_msecs(pCh->ClosingDelay));
1666 }
1667 wake_up_interruptible(&pCh->open_wait);
1668 }
1669
1670 pCh->flags &=~(ASYNC_NORMAL_ACTIVE|ASYNC_CLOSING);
1671 wake_up_interruptible(&pCh->close_wait);
1672
1673#ifdef IP2DEBUG_OPEN
1674 DBG_CNT("ip2_close: after wakeups--");
1675#endif
1676
1677
1678 ip2trace (CHANN, ITRC_CLOSE, ITRC_RETURN, 1, 1 );
1679
1680 return;
1681}
1682
1683/******************************************************************************/
1684/* Function: ip2_hangup() */
1685/* Parameters: Pointer to tty structure */
1686/* Returns: Nothing */
1687/* */
1688/* Description: */
1689/* */
1690/* */
1691/******************************************************************************/
1692static void
1693ip2_hangup ( PTTY tty )
1694{
1695 i2ChanStrPtr pCh = tty->driver_data;
1696
1697 if( !pCh ) {
1698 return;
1699 }
1700
1701 ip2trace (CHANN, ITRC_HANGUP, ITRC_ENTER, 0 );
1702
1703 ip2_flush_buffer(tty);
1704
1705 /* disable DSS reporting */
1706
1707 i2QueueCommands(PTYPE_BYPASS, pCh, 0, 1, CMD_DCD_NREP);
1708 i2QueueCommands(PTYPE_INLINE, pCh, 0, 2, CMD_CTSFL_DSAB, CMD_RTSFL_DSAB);
1709 if ( (tty->termios->c_cflag & HUPCL) ) {
1710 i2QueueCommands(PTYPE_BYPASS, pCh, 0, 2, CMD_RTSDN, CMD_DTRDN);
1711 pCh->dataSetOut &= ~(I2_DTR | I2_RTS);
1712 i2QueueCommands( PTYPE_INLINE, pCh, 100, 1, CMD_PAUSE(25));
1713 }
1714 i2QueueCommands(PTYPE_INLINE, pCh, 1, 3,
1715 CMD_CTS_NREP, CMD_DSR_NREP, CMD_RI_NREP);
1716 serviceOutgoingFifo ( pCh->pMyBord );
1717
1718 wake_up_interruptible ( &pCh->delta_msr_wait );
1719
1720 pCh->flags &= ~ASYNC_NORMAL_ACTIVE;
1721 pCh->pTTY = NULL;
1722 wake_up_interruptible ( &pCh->open_wait );
1723
1724 ip2trace (CHANN, ITRC_HANGUP, ITRC_RETURN, 0 );
1725}
1726
1727/******************************************************************************/
1728/******************************************************************************/
1729/* Device Output Section */
1730/******************************************************************************/
1731/******************************************************************************/
1732
1733/******************************************************************************/
1734/* Function: ip2_write() */
1735/* Parameters: Pointer to tty structure */
1736/* Flag denoting data is in user (1) or kernel (0) space */
1737/* Pointer to data */
1738/* Number of bytes to write */
1739/* Returns: Number of bytes actually written */
1740/* */
1741/* Description: (MANDATORY) */
1742/* */
1743/* */
1744/******************************************************************************/
1745static int
d9e39538 1746ip2_write( PTTY tty, const unsigned char *pData, int count)
1da177e4
LT
1747{
1748 i2ChanStrPtr pCh = tty->driver_data;
1749 int bytesSent = 0;
1750 unsigned long flags;
1751
1752 ip2trace (CHANN, ITRC_WRITE, ITRC_ENTER, 2, count, -1 );
1753
1754 /* Flush out any buffered data left over from ip2_putchar() calls. */
1755 ip2_flush_chars( tty );
1756
1757 /* This is the actual move bit. Make sure it does what we need!!!!! */
cf1c63c3 1758 write_lock_irqsave(&pCh->Pbuf_spinlock, flags);
f061c584 1759 bytesSent = i2Output( pCh, pData, count);
cf1c63c3 1760 write_unlock_irqrestore(&pCh->Pbuf_spinlock, flags);
1da177e4
LT
1761
1762 ip2trace (CHANN, ITRC_WRITE, ITRC_RETURN, 1, bytesSent );
1763
1764 return bytesSent > 0 ? bytesSent : 0;
1765}
1766
1767/******************************************************************************/
1768/* Function: ip2_putchar() */
1769/* Parameters: Pointer to tty structure */
1770/* Character to write */
1771/* Returns: Nothing */
1772/* */
1773/* Description: */
1774/* */
1775/* */
1776/******************************************************************************/
f34d7a5b 1777static int
1da177e4
LT
1778ip2_putchar( PTTY tty, unsigned char ch )
1779{
1780 i2ChanStrPtr pCh = tty->driver_data;
1781 unsigned long flags;
1782
1783// ip2trace (CHANN, ITRC_PUTC, ITRC_ENTER, 1, ch );
1784
cf1c63c3 1785 write_lock_irqsave(&pCh->Pbuf_spinlock, flags);
1da177e4
LT
1786 pCh->Pbuf[pCh->Pbuf_stuff++] = ch;
1787 if ( pCh->Pbuf_stuff == sizeof pCh->Pbuf ) {
cf1c63c3 1788 write_unlock_irqrestore(&pCh->Pbuf_spinlock, flags);
1da177e4
LT
1789 ip2_flush_chars( tty );
1790 } else
cf1c63c3 1791 write_unlock_irqrestore(&pCh->Pbuf_spinlock, flags);
f34d7a5b 1792 return 1;
1da177e4
LT
1793
1794// ip2trace (CHANN, ITRC_PUTC, ITRC_RETURN, 1, ch );
1795}
1796
1797/******************************************************************************/
1798/* Function: ip2_flush_chars() */
1799/* Parameters: Pointer to tty structure */
1800/* Returns: Nothing */
1801/* */
1802/* Description: */
1803/* */
1804/******************************************************************************/
1805static void
1806ip2_flush_chars( PTTY tty )
1807{
1808 int strip;
1809 i2ChanStrPtr pCh = tty->driver_data;
1810 unsigned long flags;
1811
cf1c63c3 1812 write_lock_irqsave(&pCh->Pbuf_spinlock, flags);
1da177e4
LT
1813 if ( pCh->Pbuf_stuff ) {
1814
1815// ip2trace (CHANN, ITRC_PUTC, 10, 1, strip );
1816
1817 //
1818 // We may need to restart i2Output if it does not fullfill this request
1819 //
f061c584 1820 strip = i2Output( pCh, pCh->Pbuf, pCh->Pbuf_stuff);
1da177e4
LT
1821 if ( strip != pCh->Pbuf_stuff ) {
1822 memmove( pCh->Pbuf, &pCh->Pbuf[strip], pCh->Pbuf_stuff - strip );
1823 }
1824 pCh->Pbuf_stuff -= strip;
1825 }
cf1c63c3 1826 write_unlock_irqrestore(&pCh->Pbuf_spinlock, flags);
1da177e4
LT
1827}
1828
1829/******************************************************************************/
1830/* Function: ip2_write_room() */
1831/* Parameters: Pointer to tty structure */
1832/* Returns: Number of bytes that the driver can accept */
1833/* */
1834/* Description: */
1835/* */
1836/******************************************************************************/
1837static int
1838ip2_write_room ( PTTY tty )
1839{
1840 int bytesFree;
1841 i2ChanStrPtr pCh = tty->driver_data;
1842 unsigned long flags;
1843
cf1c63c3 1844 read_lock_irqsave(&pCh->Pbuf_spinlock, flags);
1da177e4 1845 bytesFree = i2OutputFree( pCh ) - pCh->Pbuf_stuff;
cf1c63c3 1846 read_unlock_irqrestore(&pCh->Pbuf_spinlock, flags);
1da177e4
LT
1847
1848 ip2trace (CHANN, ITRC_WRITE, 11, 1, bytesFree );
1849
1850 return ((bytesFree > 0) ? bytesFree : 0);
1851}
1852
1853/******************************************************************************/
1854/* Function: ip2_chars_in_buf() */
1855/* Parameters: Pointer to tty structure */
1856/* Returns: Number of bytes queued for transmission */
1857/* */
1858/* Description: */
1859/* */
1860/* */
1861/******************************************************************************/
1862static int
1863ip2_chars_in_buf ( PTTY tty )
1864{
1865 i2ChanStrPtr pCh = tty->driver_data;
1866 int rc;
1867 unsigned long flags;
1868
1869 ip2trace (CHANN, ITRC_WRITE, 12, 1, pCh->Obuf_char_count + pCh->Pbuf_stuff );
1870
1871#ifdef IP2DEBUG_WRITE
1872 printk (KERN_DEBUG "IP2: chars in buffer = %d (%d,%d)\n",
1873 pCh->Obuf_char_count + pCh->Pbuf_stuff,
1874 pCh->Obuf_char_count, pCh->Pbuf_stuff );
1875#endif
cf1c63c3 1876 read_lock_irqsave(&pCh->Obuf_spinlock, flags);
1da177e4 1877 rc = pCh->Obuf_char_count;
cf1c63c3
JS
1878 read_unlock_irqrestore(&pCh->Obuf_spinlock, flags);
1879 read_lock_irqsave(&pCh->Pbuf_spinlock, flags);
1da177e4 1880 rc += pCh->Pbuf_stuff;
cf1c63c3 1881 read_unlock_irqrestore(&pCh->Pbuf_spinlock, flags);
1da177e4
LT
1882 return rc;
1883}
1884
1885/******************************************************************************/
1886/* Function: ip2_flush_buffer() */
1887/* Parameters: Pointer to tty structure */
1888/* Returns: Nothing */
1889/* */
1890/* Description: */
1891/* */
1892/* */
1893/******************************************************************************/
1894static void
1895ip2_flush_buffer( PTTY tty )
1896{
1897 i2ChanStrPtr pCh = tty->driver_data;
1898 unsigned long flags;
1899
1900 ip2trace (CHANN, ITRC_FLUSH, ITRC_ENTER, 0 );
1901
1902#ifdef IP2DEBUG_WRITE
1903 printk (KERN_DEBUG "IP2: flush buffer\n" );
1904#endif
cf1c63c3 1905 write_lock_irqsave(&pCh->Pbuf_spinlock, flags);
1da177e4 1906 pCh->Pbuf_stuff = 0;
cf1c63c3 1907 write_unlock_irqrestore(&pCh->Pbuf_spinlock, flags);
1da177e4
LT
1908 i2FlushOutput( pCh );
1909 ip2_owake(tty);
1910
1911 ip2trace (CHANN, ITRC_FLUSH, ITRC_RETURN, 0 );
1912
1913}
1914
1915/******************************************************************************/
1916/* Function: ip2_wait_until_sent() */
1917/* Parameters: Pointer to tty structure */
1918/* Timeout for wait. */
1919/* Returns: Nothing */
1920/* */
1921/* Description: */
1922/* This function is used in place of the normal tty_wait_until_sent, which */
1923/* only waits for the driver buffers to be empty (or rather, those buffers */
1924/* reported by chars_in_buffer) which doesn't work for IP2 due to the */
1925/* indeterminate number of bytes buffered on the board. */
1926/******************************************************************************/
1927static void
1928ip2_wait_until_sent ( PTTY tty, int timeout )
1929{
1930 int i = jiffies;
1931 i2ChanStrPtr pCh = tty->driver_data;
1932
1933 tty_wait_until_sent(tty, timeout );
1934 if ( (i = timeout - (jiffies -i)) > 0)
1935 i2DrainOutput( pCh, i );
1936}
1937
1938/******************************************************************************/
1939/******************************************************************************/
1940/* Device Input Section */
1941/******************************************************************************/
1942/******************************************************************************/
1943
1944/******************************************************************************/
1945/* Function: ip2_throttle() */
1946/* Parameters: Pointer to tty structure */
1947/* Returns: Nothing */
1948/* */
1949/* Description: */
1950/* */
1951/* */
1952/******************************************************************************/
1953static void
1954ip2_throttle ( PTTY tty )
1955{
1956 i2ChanStrPtr pCh = tty->driver_data;
1957
1958#ifdef IP2DEBUG_READ
1959 printk (KERN_DEBUG "IP2: throttle\n" );
1960#endif
1961 /*
1962 * Signal the poll/interrupt handlers not to forward incoming data to
1963 * the line discipline. This will cause the buffers to fill up in the
1964 * library and thus cause the library routines to send the flow control
1965 * stuff.
1966 */
1967 pCh->throttled = 1;
1968}
1969
1970/******************************************************************************/
1971/* Function: ip2_unthrottle() */
1972/* Parameters: Pointer to tty structure */
1973/* Returns: Nothing */
1974/* */
1975/* Description: */
1976/* */
1977/* */
1978/******************************************************************************/
1979static void
1980ip2_unthrottle ( PTTY tty )
1981{
1982 i2ChanStrPtr pCh = tty->driver_data;
1983 unsigned long flags;
1984
1985#ifdef IP2DEBUG_READ
1986 printk (KERN_DEBUG "IP2: unthrottle\n" );
1987#endif
1988
1989 /* Pass incoming data up to the line discipline again. */
1990 pCh->throttled = 0;
1991 i2QueueCommands(PTYPE_BYPASS, pCh, 0, 1, CMD_RESUME);
1992 serviceOutgoingFifo( pCh->pMyBord );
cf1c63c3 1993 read_lock_irqsave(&pCh->Ibuf_spinlock, flags);
1da177e4 1994 if ( pCh->Ibuf_stuff != pCh->Ibuf_strip ) {
cf1c63c3 1995 read_unlock_irqrestore(&pCh->Ibuf_spinlock, flags);
1da177e4
LT
1996#ifdef IP2DEBUG_READ
1997 printk (KERN_DEBUG "i2Input called from unthrottle\n" );
1998#endif
1999 i2Input( pCh );
2000 } else
cf1c63c3 2001 read_unlock_irqrestore(&pCh->Ibuf_spinlock, flags);
1da177e4
LT
2002}
2003
2004static void
2005ip2_start ( PTTY tty )
2006{
2007 i2ChanStrPtr pCh = DevTable[tty->index];
2008
2009 i2QueueCommands(PTYPE_BYPASS, pCh, 0, 1, CMD_RESUME);
2010 i2QueueCommands(PTYPE_BYPASS, pCh, 100, 1, CMD_UNSUSPEND);
2011 i2QueueCommands(PTYPE_BYPASS, pCh, 100, 1, CMD_RESUME);
2012#ifdef IP2DEBUG_WRITE
2013 printk (KERN_DEBUG "IP2: start tx\n" );
2014#endif
2015}
2016
2017static void
2018ip2_stop ( PTTY tty )
2019{
2020 i2ChanStrPtr pCh = DevTable[tty->index];
2021
2022 i2QueueCommands(PTYPE_BYPASS, pCh, 100, 1, CMD_SUSPEND);
2023#ifdef IP2DEBUG_WRITE
2024 printk (KERN_DEBUG "IP2: stop tx\n" );
2025#endif
2026}
2027
2028/******************************************************************************/
2029/* Device Ioctl Section */
2030/******************************************************************************/
2031
2032static int ip2_tiocmget(struct tty_struct *tty, struct file *file)
2033{
2034 i2ChanStrPtr pCh = DevTable[tty->index];
d9e39538 2035#ifdef ENABLE_DSSNOW
1da177e4 2036 wait_queue_t wait;
d9e39538 2037#endif
1da177e4
LT
2038
2039 if (pCh == NULL)
2040 return -ENODEV;
2041
2042/*
2043 FIXME - the following code is causing a NULL pointer dereference in
2044 2.3.51 in an interrupt handler. It's suppose to prompt the board
2045 to return the DSS signal status immediately. Why doesn't it do
2046 the same thing in 2.2.14?
2047*/
2048
2049/* This thing is still busted in the 1.2.12 driver on 2.4.x
2050 and even hoses the serial console so the oops can be trapped.
2051 /\/\|=mhw=|\/\/ */
2052
2053#ifdef ENABLE_DSSNOW
2054 i2QueueCommands(PTYPE_BYPASS, pCh, 100, 1, CMD_DSS_NOW);
2055
2056 init_waitqueue_entry(&wait, current);
2057 add_wait_queue(&pCh->dss_now_wait, &wait);
2058 set_current_state( TASK_INTERRUPTIBLE );
2059
2060 serviceOutgoingFifo( pCh->pMyBord );
2061
2062 schedule();
2063
2064 set_current_state( TASK_RUNNING );
2065 remove_wait_queue(&pCh->dss_now_wait, &wait);
2066
2067 if (signal_pending(current)) {
2068 return -EINTR;
2069 }
2070#endif
2071 return ((pCh->dataSetOut & I2_RTS) ? TIOCM_RTS : 0)
2072 | ((pCh->dataSetOut & I2_DTR) ? TIOCM_DTR : 0)
2073 | ((pCh->dataSetIn & I2_DCD) ? TIOCM_CAR : 0)
2074 | ((pCh->dataSetIn & I2_RI) ? TIOCM_RNG : 0)
2075 | ((pCh->dataSetIn & I2_DSR) ? TIOCM_DSR : 0)
2076 | ((pCh->dataSetIn & I2_CTS) ? TIOCM_CTS : 0);
2077}
2078
2079static int ip2_tiocmset(struct tty_struct *tty, struct file *file,
2080 unsigned int set, unsigned int clear)
2081{
2082 i2ChanStrPtr pCh = DevTable[tty->index];
2083
2084 if (pCh == NULL)
2085 return -ENODEV;
2086
2087 if (set & TIOCM_RTS) {
2088 i2QueueCommands(PTYPE_INLINE, pCh, 100, 1, CMD_RTSUP);
2089 pCh->dataSetOut |= I2_RTS;
2090 }
2091 if (set & TIOCM_DTR) {
2092 i2QueueCommands(PTYPE_INLINE, pCh, 100, 1, CMD_DTRUP);
2093 pCh->dataSetOut |= I2_DTR;
2094 }
2095
2096 if (clear & TIOCM_RTS) {
2097 i2QueueCommands(PTYPE_INLINE, pCh, 100, 1, CMD_RTSDN);
2098 pCh->dataSetOut &= ~I2_RTS;
2099 }
2100 if (clear & TIOCM_DTR) {
2101 i2QueueCommands(PTYPE_INLINE, pCh, 100, 1, CMD_DTRDN);
2102 pCh->dataSetOut &= ~I2_DTR;
2103 }
2104 serviceOutgoingFifo( pCh->pMyBord );
2105 return 0;
2106}
2107
2108/******************************************************************************/
2109/* Function: ip2_ioctl() */
2110/* Parameters: Pointer to tty structure */
2111/* Pointer to file structure */
2112/* Command */
2113/* Argument */
2114/* Returns: Success or failure */
2115/* */
2116/* Description: */
2117/* */
2118/* */
2119/******************************************************************************/
2120static int
2121ip2_ioctl ( PTTY tty, struct file *pFile, UINT cmd, ULONG arg )
2122{
2123 wait_queue_t wait;
2124 i2ChanStrPtr pCh = DevTable[tty->index];
d9e39538 2125 i2eBordStrPtr pB;
1da177e4
LT
2126 struct async_icount cprev, cnow; /* kernel counter temps */
2127 struct serial_icounter_struct __user *p_cuser;
2128 int rc = 0;
2129 unsigned long flags;
2130 void __user *argp = (void __user *)arg;
2131
d9e39538 2132 if ( pCh == NULL )
1da177e4 2133 return -ENODEV;
d9e39538
AC
2134
2135 pB = pCh->pMyBord;
1da177e4
LT
2136
2137 ip2trace (CHANN, ITRC_IOCTL, ITRC_ENTER, 2, cmd, arg );
2138
2139#ifdef IP2DEBUG_IOCTL
2140 printk(KERN_DEBUG "IP2: ioctl cmd (%x), arg (%lx)\n", cmd, arg );
2141#endif
2142
2143 switch(cmd) {
2144 case TIOCGSERIAL:
2145
2146 ip2trace (CHANN, ITRC_IOCTL, 2, 1, rc );
2147
2148 rc = get_serial_info(pCh, argp);
2149 if (rc)
2150 return rc;
2151 break;
2152
2153 case TIOCSSERIAL:
2154
2155 ip2trace (CHANN, ITRC_IOCTL, 3, 1, rc );
2156
2157 rc = set_serial_info(pCh, argp);
2158 if (rc)
2159 return rc;
2160 break;
2161
2162 case TCXONC:
2163 rc = tty_check_change(tty);
2164 if (rc)
2165 return rc;
2166 switch (arg) {
2167 case TCOOFF:
2168 //return -ENOIOCTLCMD;
2169 break;
2170 case TCOON:
2171 //return -ENOIOCTLCMD;
2172 break;
2173 case TCIOFF:
2174 if (STOP_CHAR(tty) != __DISABLED_CHAR) {
2175 i2QueueCommands( PTYPE_BYPASS, pCh, 100, 1,
2176 CMD_XMIT_NOW(STOP_CHAR(tty)));
2177 }
2178 break;
2179 case TCION:
2180 if (START_CHAR(tty) != __DISABLED_CHAR) {
2181 i2QueueCommands( PTYPE_BYPASS, pCh, 100, 1,
2182 CMD_XMIT_NOW(START_CHAR(tty)));
2183 }
2184 break;
2185 default:
2186 return -EINVAL;
2187 }
2188 return 0;
2189
2190 case TCSBRK: /* SVID version: non-zero arg --> no break */
2191 rc = tty_check_change(tty);
2192
2193 ip2trace (CHANN, ITRC_IOCTL, 4, 1, rc );
2194
2195 if (!rc) {
2196 ip2_wait_until_sent(tty,0);
2197 if (!arg) {
2198 i2QueueCommands(PTYPE_INLINE, pCh, 100, 1, CMD_SEND_BRK(250));
2199 serviceOutgoingFifo( pCh->pMyBord );
2200 }
2201 }
2202 break;
2203
2204 case TCSBRKP: /* support for POSIX tcsendbreak() */
2205 rc = tty_check_change(tty);
2206
2207 ip2trace (CHANN, ITRC_IOCTL, 5, 1, rc );
2208
2209 if (!rc) {
2210 ip2_wait_until_sent(tty,0);
2211 i2QueueCommands(PTYPE_INLINE, pCh, 100, 1,
2212 CMD_SEND_BRK(arg ? arg*100 : 250));
2213 serviceOutgoingFifo ( pCh->pMyBord );
2214 }
2215 break;
2216
2217 case TIOCGSOFTCAR:
2218
2219 ip2trace (CHANN, ITRC_IOCTL, 6, 1, rc );
2220
2221 rc = put_user(C_CLOCAL(tty) ? 1 : 0, (unsigned long __user *)argp);
2222 if (rc)
2223 return rc;
2224 break;
2225
2226 case TIOCSSOFTCAR:
2227
2228 ip2trace (CHANN, ITRC_IOCTL, 7, 1, rc );
2229
2230 rc = get_user(arg,(unsigned long __user *) argp);
2231 if (rc)
2232 return rc;
2233 tty->termios->c_cflag = ((tty->termios->c_cflag & ~CLOCAL)
2234 | (arg ? CLOCAL : 0));
2235
2236 break;
2237
2238 /*
2239 * Wait for any of the 4 modem inputs (DCD,RI,DSR,CTS) to change - mask
2240 * passed in arg for lines of interest (use |'ed TIOCM_RNG/DSR/CD/CTS
2241 * for masking). Caller should use TIOCGICOUNT to see which one it was
2242 */
2243 case TIOCMIWAIT:
cf1c63c3 2244 write_lock_irqsave(&pB->read_fifo_spinlock, flags);
1da177e4 2245 cprev = pCh->icount; /* note the counters on entry */
cf1c63c3 2246 write_unlock_irqrestore(&pB->read_fifo_spinlock, flags);
1da177e4
LT
2247 i2QueueCommands(PTYPE_BYPASS, pCh, 100, 4,
2248 CMD_DCD_REP, CMD_CTS_REP, CMD_DSR_REP, CMD_RI_REP);
2249 init_waitqueue_entry(&wait, current);
2250 add_wait_queue(&pCh->delta_msr_wait, &wait);
2251 set_current_state( TASK_INTERRUPTIBLE );
2252
2253 serviceOutgoingFifo( pCh->pMyBord );
2254 for(;;) {
2255 ip2trace (CHANN, ITRC_IOCTL, 10, 0 );
2256
2257 schedule();
2258
2259 ip2trace (CHANN, ITRC_IOCTL, 11, 0 );
2260
2261 /* see if a signal did it */
2262 if (signal_pending(current)) {
2263 rc = -ERESTARTSYS;
2264 break;
2265 }
cf1c63c3 2266 write_lock_irqsave(&pB->read_fifo_spinlock, flags);
1da177e4 2267 cnow = pCh->icount; /* atomic copy */
cf1c63c3 2268 write_unlock_irqrestore(&pB->read_fifo_spinlock, flags);
1da177e4
LT
2269 if (cnow.rng == cprev.rng && cnow.dsr == cprev.dsr &&
2270 cnow.dcd == cprev.dcd && cnow.cts == cprev.cts) {
2271 rc = -EIO; /* no change => rc */
2272 break;
2273 }
2274 if (((arg & TIOCM_RNG) && (cnow.rng != cprev.rng)) ||
2275 ((arg & TIOCM_DSR) && (cnow.dsr != cprev.dsr)) ||
2276 ((arg & TIOCM_CD) && (cnow.dcd != cprev.dcd)) ||
2277 ((arg & TIOCM_CTS) && (cnow.cts != cprev.cts)) ) {
2278 rc = 0;
2279 break;
2280 }
2281 cprev = cnow;
2282 }
2283 set_current_state( TASK_RUNNING );
2284 remove_wait_queue(&pCh->delta_msr_wait, &wait);
2285
2286 i2QueueCommands(PTYPE_BYPASS, pCh, 100, 3,
2287 CMD_CTS_NREP, CMD_DSR_NREP, CMD_RI_NREP);
2288 if ( ! (pCh->flags & ASYNC_CHECK_CD)) {
2289 i2QueueCommands(PTYPE_BYPASS, pCh, 100, 1, CMD_DCD_NREP);
2290 }
2291 serviceOutgoingFifo( pCh->pMyBord );
2292 return rc;
2293 break;
2294
2295 /*
2296 * Get counter of input serial line interrupts (DCD,RI,DSR,CTS)
2297 * Return: write counters to the user passed counter struct
2298 * NB: both 1->0 and 0->1 transitions are counted except for RI where
2299 * only 0->1 is counted. The controller is quite capable of counting
2300 * both, but this done to preserve compatibility with the standard
2301 * serial driver.
2302 */
2303 case TIOCGICOUNT:
2304 ip2trace (CHANN, ITRC_IOCTL, 11, 1, rc );
2305
cf1c63c3 2306 write_lock_irqsave(&pB->read_fifo_spinlock, flags);
1da177e4 2307 cnow = pCh->icount;
cf1c63c3 2308 write_unlock_irqrestore(&pB->read_fifo_spinlock, flags);
1da177e4
LT
2309 p_cuser = argp;
2310 rc = put_user(cnow.cts, &p_cuser->cts);
2311 rc = put_user(cnow.dsr, &p_cuser->dsr);
2312 rc = put_user(cnow.rng, &p_cuser->rng);
2313 rc = put_user(cnow.dcd, &p_cuser->dcd);
2314 rc = put_user(cnow.rx, &p_cuser->rx);
2315 rc = put_user(cnow.tx, &p_cuser->tx);
2316 rc = put_user(cnow.frame, &p_cuser->frame);
2317 rc = put_user(cnow.overrun, &p_cuser->overrun);
2318 rc = put_user(cnow.parity, &p_cuser->parity);
2319 rc = put_user(cnow.brk, &p_cuser->brk);
2320 rc = put_user(cnow.buf_overrun, &p_cuser->buf_overrun);
2321 break;
2322
2323 /*
2324 * The rest are not supported by this driver. By returning -ENOIOCTLCMD they
2325 * will be passed to the line discipline for it to handle.
2326 */
2327 case TIOCSERCONFIG:
2328 case TIOCSERGWILD:
2329 case TIOCSERGETLSR:
2330 case TIOCSERSWILD:
2331 case TIOCSERGSTRUCT:
2332 case TIOCSERGETMULTI:
2333 case TIOCSERSETMULTI:
2334
2335 default:
2336 ip2trace (CHANN, ITRC_IOCTL, 12, 0 );
2337
2338 rc = -ENOIOCTLCMD;
2339 break;
2340 }
2341
2342 ip2trace (CHANN, ITRC_IOCTL, ITRC_RETURN, 0 );
2343
2344 return rc;
2345}
2346
2347/******************************************************************************/
2348/* Function: GetSerialInfo() */
2349/* Parameters: Pointer to channel structure */
2350/* Pointer to old termios structure */
2351/* Returns: Nothing */
2352/* */
2353/* Description: */
2354/* This is to support the setserial command, and requires processing of the */
2355/* standard Linux serial structure. */
2356/******************************************************************************/
2357static int
2358get_serial_info ( i2ChanStrPtr pCh, struct serial_struct __user *retinfo )
2359{
2360 struct serial_struct tmp;
2361
2362 memset ( &tmp, 0, sizeof(tmp) );
2363 tmp.type = pCh->pMyBord->channelBtypes.bid_value[(pCh->port_index & (IP2_PORTS_PER_BOARD-1))/16];
2364 if (BID_HAS_654(tmp.type)) {
2365 tmp.type = PORT_16650;
2366 } else {
2367 tmp.type = PORT_CIRRUS;
2368 }
2369 tmp.line = pCh->port_index;
2370 tmp.port = pCh->pMyBord->i2eBase;
2371 tmp.irq = ip2config.irq[pCh->port_index/64];
2372 tmp.flags = pCh->flags;
2373 tmp.baud_base = pCh->BaudBase;
2374 tmp.close_delay = pCh->ClosingDelay;
2375 tmp.closing_wait = pCh->ClosingWaitTime;
2376 tmp.custom_divisor = pCh->BaudDivisor;
2377 return copy_to_user(retinfo,&tmp,sizeof(*retinfo));
2378}
2379
2380/******************************************************************************/
2381/* Function: SetSerialInfo() */
2382/* Parameters: Pointer to channel structure */
2383/* Pointer to old termios structure */
2384/* Returns: Nothing */
2385/* */
2386/* Description: */
2387/* This function provides support for setserial, which uses the TIOCSSERIAL */
2388/* ioctl. Not all setserial parameters are relevant. If the user attempts to */
2389/* change the IRQ, address or type of the port the ioctl fails. */
2390/******************************************************************************/
2391static int
2392set_serial_info( i2ChanStrPtr pCh, struct serial_struct __user *new_info )
2393{
2394 struct serial_struct ns;
2395 int old_flags, old_baud_divisor;
2396
2397 if (copy_from_user(&ns, new_info, sizeof (ns)))
2398 return -EFAULT;
2399
2400 /*
2401 * We don't allow setserial to change IRQ, board address, type or baud
2402 * base. Also line nunber as such is meaningless but we use it for our
2403 * array index so it is fixed also.
2404 */
2405 if ( (ns.irq != ip2config.irq[pCh->port_index])
2406 || ((int) ns.port != ((int) (pCh->pMyBord->i2eBase)))
2407 || (ns.baud_base != pCh->BaudBase)
2408 || (ns.line != pCh->port_index) ) {
2409 return -EINVAL;
2410 }
2411
2412 old_flags = pCh->flags;
2413 old_baud_divisor = pCh->BaudDivisor;
2414
2415 if ( !capable(CAP_SYS_ADMIN) ) {
2416 if ( ( ns.close_delay != pCh->ClosingDelay ) ||
2417 ( (ns.flags & ~ASYNC_USR_MASK) !=
2418 (pCh->flags & ~ASYNC_USR_MASK) ) ) {
2419 return -EPERM;
2420 }
2421
2422 pCh->flags = (pCh->flags & ~ASYNC_USR_MASK) |
2423 (ns.flags & ASYNC_USR_MASK);
2424 pCh->BaudDivisor = ns.custom_divisor;
2425 } else {
2426 pCh->flags = (pCh->flags & ~ASYNC_FLAGS) |
2427 (ns.flags & ASYNC_FLAGS);
2428 pCh->BaudDivisor = ns.custom_divisor;
2429 pCh->ClosingDelay = ns.close_delay * HZ/100;
2430 pCh->ClosingWaitTime = ns.closing_wait * HZ/100;
2431 }
2432
2433 if ( ( (old_flags & ASYNC_SPD_MASK) != (pCh->flags & ASYNC_SPD_MASK) )
2434 || (old_baud_divisor != pCh->BaudDivisor) ) {
2435 // Invalidate speed and reset parameters
2436 set_params( pCh, NULL );
2437 }
2438
2439 return 0;
2440}
2441
2442/******************************************************************************/
2443/* Function: ip2_set_termios() */
2444/* Parameters: Pointer to tty structure */
2445/* Pointer to old termios structure */
2446/* Returns: Nothing */
2447/* */
2448/* Description: */
2449/* */
2450/* */
2451/******************************************************************************/
2452static void
606d099c 2453ip2_set_termios( PTTY tty, struct ktermios *old_termios )
1da177e4
LT
2454{
2455 i2ChanStrPtr pCh = (i2ChanStrPtr)tty->driver_data;
2456
2457#ifdef IP2DEBUG_IOCTL
2458 printk (KERN_DEBUG "IP2: set termios %p\n", old_termios );
2459#endif
2460
2461 set_params( pCh, old_termios );
2462}
2463
2464/******************************************************************************/
2465/* Function: ip2_set_line_discipline() */
2466/* Parameters: Pointer to tty structure */
2467/* Returns: Nothing */
2468/* */
2469/* Description: Does nothing */
2470/* */
2471/* */
2472/******************************************************************************/
2473static void
2474ip2_set_line_discipline ( PTTY tty )
2475{
2476#ifdef IP2DEBUG_IOCTL
2477 printk (KERN_DEBUG "IP2: set line discipline\n" );
2478#endif
2479
2480 ip2trace (((i2ChanStrPtr)tty->driver_data)->port_index, ITRC_IOCTL, 16, 0 );
2481
2482}
2483
2484/******************************************************************************/
2485/* Function: SetLine Characteristics() */
2486/* Parameters: Pointer to channel structure */
2487/* Returns: Nothing */
2488/* */
2489/* Description: */
2490/* This routine is called to update the channel structure with the new line */
2491/* characteristics, and send the appropriate commands to the board when they */
2492/* change. */
2493/******************************************************************************/
2494static void
606d099c 2495set_params( i2ChanStrPtr pCh, struct ktermios *o_tios )
1da177e4
LT
2496{
2497 tcflag_t cflag, iflag, lflag;
2498 char stop_char, start_char;
606d099c 2499 struct ktermios dummy;
1da177e4
LT
2500
2501 lflag = pCh->pTTY->termios->c_lflag;
2502 cflag = pCh->pTTY->termios->c_cflag;
2503 iflag = pCh->pTTY->termios->c_iflag;
2504
2505 if (o_tios == NULL) {
2506 dummy.c_lflag = ~lflag;
2507 dummy.c_cflag = ~cflag;
2508 dummy.c_iflag = ~iflag;
2509 o_tios = &dummy;
2510 }
2511
2512 {
2513 switch ( cflag & CBAUD ) {
2514 case B0:
2515 i2QueueCommands( PTYPE_BYPASS, pCh, 100, 2, CMD_RTSDN, CMD_DTRDN);
2516 pCh->dataSetOut &= ~(I2_DTR | I2_RTS);
2517 i2QueueCommands( PTYPE_INLINE, pCh, 100, 1, CMD_PAUSE(25));
2518 pCh->pTTY->termios->c_cflag |= (CBAUD & o_tios->c_cflag);
2519 goto service_it;
2520 break;
2521 case B38400:
2522 /*
2523 * This is the speed that is overloaded with all the other high
2524 * speeds, depending upon the flag settings.
2525 */
2526 if ( ( pCh->flags & ASYNC_SPD_MASK ) == ASYNC_SPD_HI ) {
2527 pCh->speed = CBR_57600;
2528 } else if ( (pCh->flags & ASYNC_SPD_MASK) == ASYNC_SPD_VHI ) {
2529 pCh->speed = CBR_115200;
2530 } else if ( (pCh->flags & ASYNC_SPD_MASK) == ASYNC_SPD_CUST ) {
2531 pCh->speed = CBR_C1;
2532 } else {
2533 pCh->speed = CBR_38400;
2534 }
2535 break;
2536 case B50: pCh->speed = CBR_50; break;
2537 case B75: pCh->speed = CBR_75; break;
2538 case B110: pCh->speed = CBR_110; break;
2539 case B134: pCh->speed = CBR_134; break;
2540 case B150: pCh->speed = CBR_150; break;
2541 case B200: pCh->speed = CBR_200; break;
2542 case B300: pCh->speed = CBR_300; break;
2543 case B600: pCh->speed = CBR_600; break;
2544 case B1200: pCh->speed = CBR_1200; break;
2545 case B1800: pCh->speed = CBR_1800; break;
2546 case B2400: pCh->speed = CBR_2400; break;
2547 case B4800: pCh->speed = CBR_4800; break;
2548 case B9600: pCh->speed = CBR_9600; break;
2549 case B19200: pCh->speed = CBR_19200; break;
2550 case B57600: pCh->speed = CBR_57600; break;
2551 case B115200: pCh->speed = CBR_115200; break;
2552 case B153600: pCh->speed = CBR_153600; break;
2553 case B230400: pCh->speed = CBR_230400; break;
2554 case B307200: pCh->speed = CBR_307200; break;
2555 case B460800: pCh->speed = CBR_460800; break;
2556 case B921600: pCh->speed = CBR_921600; break;
2557 default: pCh->speed = CBR_9600; break;
2558 }
2559 if ( pCh->speed == CBR_C1 ) {
2560 // Process the custom speed parameters.
2561 int bps = pCh->BaudBase / pCh->BaudDivisor;
2562 if ( bps == 921600 ) {
2563 pCh->speed = CBR_921600;
2564 } else {
2565 bps = bps/10;
2566 i2QueueCommands( PTYPE_INLINE, pCh, 100, 1, CMD_BAUD_DEF1(bps) );
2567 }
2568 }
2569 i2QueueCommands( PTYPE_INLINE, pCh, 100, 1, CMD_SETBAUD(pCh->speed));
2570
2571 i2QueueCommands ( PTYPE_INLINE, pCh, 100, 2, CMD_DTRUP, CMD_RTSUP);
2572 pCh->dataSetOut |= (I2_DTR | I2_RTS);
2573 }
2574 if ( (CSTOPB & cflag) ^ (CSTOPB & o_tios->c_cflag))
2575 {
2576 i2QueueCommands ( PTYPE_INLINE, pCh, 100, 1,
2577 CMD_SETSTOP( ( cflag & CSTOPB ) ? CST_2 : CST_1));
2578 }
2579 if (((PARENB|PARODD) & cflag) ^ ((PARENB|PARODD) & o_tios->c_cflag))
2580 {
2581 i2QueueCommands ( PTYPE_INLINE, pCh, 100, 1,
2582 CMD_SETPAR(
2583 (cflag & PARENB ? (cflag & PARODD ? CSP_OD : CSP_EV) : CSP_NP)
2584 )
2585 );
2586 }
2587 /* byte size and parity */
2588 if ( (CSIZE & cflag)^(CSIZE & o_tios->c_cflag))
2589 {
2590 int datasize;
2591 switch ( cflag & CSIZE ) {
2592 case CS5: datasize = CSZ_5; break;
2593 case CS6: datasize = CSZ_6; break;
2594 case CS7: datasize = CSZ_7; break;
2595 case CS8: datasize = CSZ_8; break;
2596 default: datasize = CSZ_5; break; /* as per serial.c */
2597 }
2598 i2QueueCommands ( PTYPE_INLINE, pCh, 100, 1, CMD_SETBITS(datasize) );
2599 }
2600 /* Process CTS flow control flag setting */
2601 if ( (cflag & CRTSCTS) ) {
2602 i2QueueCommands(PTYPE_INLINE, pCh, 100,
2603 2, CMD_CTSFL_ENAB, CMD_RTSFL_ENAB);
2604 } else {
2605 i2QueueCommands(PTYPE_INLINE, pCh, 100,
2606 2, CMD_CTSFL_DSAB, CMD_RTSFL_DSAB);
2607 }
2608 //
2609 // Process XON/XOFF flow control flags settings
2610 //
2611 stop_char = STOP_CHAR(pCh->pTTY);
2612 start_char = START_CHAR(pCh->pTTY);
2613
2614 //////////// can't be \000
2615 if (stop_char == __DISABLED_CHAR )
2616 {
2617 stop_char = ~__DISABLED_CHAR;
2618 }
2619 if (start_char == __DISABLED_CHAR )
2620 {
2621 start_char = ~__DISABLED_CHAR;
2622 }
2623 /////////////////////////////////
2624
2625 if ( o_tios->c_cc[VSTART] != start_char )
2626 {
2627 i2QueueCommands(PTYPE_BYPASS, pCh, 100, 1, CMD_DEF_IXON(start_char));
2628 i2QueueCommands(PTYPE_INLINE, pCh, 100, 1, CMD_DEF_OXON(start_char));
2629 }
2630 if ( o_tios->c_cc[VSTOP] != stop_char )
2631 {
2632 i2QueueCommands(PTYPE_BYPASS, pCh, 100, 1, CMD_DEF_IXOFF(stop_char));
2633 i2QueueCommands(PTYPE_INLINE, pCh, 100, 1, CMD_DEF_OXOFF(stop_char));
2634 }
2635 if (stop_char == __DISABLED_CHAR )
2636 {
2637 stop_char = ~__DISABLED_CHAR; //TEST123
2638 goto no_xoff;
2639 }
2640 if ((iflag & (IXOFF))^(o_tios->c_iflag & (IXOFF)))
2641 {
2642 if ( iflag & IXOFF ) { // Enable XOFF output flow control
2643 i2QueueCommands(PTYPE_INLINE, pCh, 100, 1, CMD_OXON_OPT(COX_XON));
2644 } else { // Disable XOFF output flow control
2645no_xoff:
2646 i2QueueCommands(PTYPE_INLINE, pCh, 100, 1, CMD_OXON_OPT(COX_NONE));
2647 }
2648 }
2649 if (start_char == __DISABLED_CHAR )
2650 {
2651 goto no_xon;
2652 }
2653 if ((iflag & (IXON|IXANY)) ^ (o_tios->c_iflag & (IXON|IXANY)))
2654 {
2655 if ( iflag & IXON ) {
2656 if ( iflag & IXANY ) { // Enable XON/XANY output flow control
2657 i2QueueCommands(PTYPE_INLINE, pCh, 100, 1, CMD_IXON_OPT(CIX_XANY));
2658 } else { // Enable XON output flow control
2659 i2QueueCommands(PTYPE_INLINE, pCh, 100, 1, CMD_IXON_OPT(CIX_XON));
2660 }
2661 } else { // Disable XON output flow control
2662no_xon:
2663 i2QueueCommands(PTYPE_INLINE, pCh, 100, 1, CMD_IXON_OPT(CIX_NONE));
2664 }
2665 }
2666 if ( (iflag & ISTRIP) ^ ( o_tios->c_iflag & (ISTRIP)) )
2667 {
2668 i2QueueCommands(PTYPE_INLINE, pCh, 100, 1,
2669 CMD_ISTRIP_OPT((iflag & ISTRIP ? 1 : 0)));
2670 }
2671 if ( (iflag & INPCK) ^ ( o_tios->c_iflag & (INPCK)) )
2672 {
2673 i2QueueCommands(PTYPE_INLINE, pCh, 100, 1,
2674 CMD_PARCHK((iflag & INPCK) ? CPK_ENAB : CPK_DSAB));
2675 }
2676
2677 if ( (iflag & (IGNBRK|PARMRK|BRKINT|IGNPAR))
2678 ^ ( o_tios->c_iflag & (IGNBRK|PARMRK|BRKINT|IGNPAR)) )
2679 {
2680 char brkrpt = 0;
2681 char parrpt = 0;
2682
2683 if ( iflag & IGNBRK ) { /* Ignore breaks altogether */
2684 /* Ignore breaks altogether */
2685 i2QueueCommands(PTYPE_INLINE, pCh, 100, 1, CMD_BRK_NREP);
2686 } else {
2687 if ( iflag & BRKINT ) {
2688 if ( iflag & PARMRK ) {
2689 brkrpt = 0x0a; // exception an inline triple
2690 } else {
2691 brkrpt = 0x1a; // exception and NULL
2692 }
2693 brkrpt |= 0x04; // flush input
2694 } else {
2695 if ( iflag & PARMRK ) {
2696 brkrpt = 0x0b; //POSIX triple \0377 \0 \0
2697 } else {
2698 brkrpt = 0x01; // Null only
2699 }
2700 }
2701 i2QueueCommands(PTYPE_INLINE, pCh, 100, 1, CMD_BRK_REP(brkrpt));
2702 }
2703
2704 if (iflag & IGNPAR) {
2705 parrpt = 0x20;
2706 /* would be 2 for not cirrus bug */
2707 /* would be 0x20 cept for cirrus bug */
2708 } else {
2709 if ( iflag & PARMRK ) {
2710 /*
2711 * Replace error characters with 3-byte sequence (\0377,\0,char)
2712 */
2713 parrpt = 0x04 ;
2714 i2QueueCommands(PTYPE_INLINE, pCh, 100, 1, CMD_ISTRIP_OPT((char)0));
2715 } else {
2716 parrpt = 0x03;
2717 }
2718 }
2719 i2QueueCommands(PTYPE_INLINE, pCh, 100, 1, CMD_SET_ERROR(parrpt));
2720 }
2721 if (cflag & CLOCAL) {
2722 // Status reporting fails for DCD if this is off
2723 i2QueueCommands(PTYPE_INLINE, pCh, 100, 1, CMD_DCD_NREP);
2724 pCh->flags &= ~ASYNC_CHECK_CD;
2725 } else {
2726 i2QueueCommands(PTYPE_INLINE, pCh, 100, 1, CMD_DCD_REP);
2727 pCh->flags |= ASYNC_CHECK_CD;
2728 }
2729
1da177e4
LT
2730service_it:
2731 i2DrainOutput( pCh, 100 );
2732}
2733
2734/******************************************************************************/
2735/* IPL Device Section */
2736/******************************************************************************/
2737
2738/******************************************************************************/
2739/* Function: ip2_ipl_read() */
2740/* Parameters: Pointer to device inode */
2741/* Pointer to file structure */
2742/* Pointer to data */
2743/* Number of bytes to read */
2744/* Returns: Success or failure */
2745/* */
2746/* Description: Ugly */
2747/* */
2748/* */
2749/******************************************************************************/
2750
2751static
2752ssize_t
2753ip2_ipl_read(struct file *pFile, char __user *pData, size_t count, loff_t *off )
2754{
a7113a96 2755 unsigned int minor = iminor(pFile->f_path.dentry->d_inode);
1da177e4
LT
2756 int rc = 0;
2757
2758#ifdef IP2DEBUG_IPL
2759 printk (KERN_DEBUG "IP2IPL: read %p, %d bytes\n", pData, count );
2760#endif
2761
2762 switch( minor ) {
2763 case 0: // IPL device
2764 rc = -EINVAL;
2765 break;
2766 case 1: // Status dump
2767 rc = -EINVAL;
2768 break;
2769 case 2: // Ping device
2770 rc = -EINVAL;
2771 break;
2772 case 3: // Trace device
2773 rc = DumpTraceBuffer ( pData, count );
2774 break;
2775 case 4: // Trace device
2776 rc = DumpFifoBuffer ( pData, count );
2777 break;
2778 default:
2779 rc = -ENODEV;
2780 break;
2781 }
2782 return rc;
2783}
2784
2785static int
2786DumpFifoBuffer ( char __user *pData, int count )
2787{
2788#ifdef DEBUG_FIFO
2789 int rc;
2790 rc = copy_to_user(pData, DBGBuf, count);
2791
2792 printk(KERN_DEBUG "Last index %d\n", I );
2793
2794 return count;
2795#endif /* DEBUG_FIFO */
2796 return 0;
2797}
2798
2799static int
2800DumpTraceBuffer ( char __user *pData, int count )
2801{
2802#ifdef IP2DEBUG_TRACE
2803 int rc;
2804 int dumpcount;
2805 int chunk;
2806 int *pIndex = (int __user *)pData;
2807
2808 if ( count < (sizeof(int) * 6) ) {
2809 return -EIO;
2810 }
2811 rc = put_user(tracewrap, pIndex );
2812 rc = put_user(TRACEMAX, ++pIndex );
2813 rc = put_user(tracestrip, ++pIndex );
2814 rc = put_user(tracestuff, ++pIndex );
2815 pData += sizeof(int) * 6;
2816 count -= sizeof(int) * 6;
2817
2818 dumpcount = tracestuff - tracestrip;
2819 if ( dumpcount < 0 ) {
2820 dumpcount += TRACEMAX;
2821 }
2822 if ( dumpcount > count ) {
2823 dumpcount = count;
2824 }
2825 chunk = TRACEMAX - tracestrip;
2826 if ( dumpcount > chunk ) {
2827 rc = copy_to_user(pData, &tracebuf[tracestrip],
2828 chunk * sizeof(tracebuf[0]) );
2829 pData += chunk * sizeof(tracebuf[0]);
2830 tracestrip = 0;
2831 chunk = dumpcount - chunk;
2832 } else {
2833 chunk = dumpcount;
2834 }
2835 rc = copy_to_user(pData, &tracebuf[tracestrip],
2836 chunk * sizeof(tracebuf[0]) );
2837 tracestrip += chunk;
2838 tracewrap = 0;
2839
2840 rc = put_user(tracestrip, ++pIndex );
2841 rc = put_user(tracestuff, ++pIndex );
2842
2843 return dumpcount;
2844#else
2845 return 0;
2846#endif
2847}
2848
2849/******************************************************************************/
2850/* Function: ip2_ipl_write() */
2851/* Parameters: */
2852/* Pointer to file structure */
2853/* Pointer to data */
2854/* Number of bytes to write */
2855/* Returns: Success or failure */
2856/* */
2857/* Description: */
2858/* */
2859/* */
2860/******************************************************************************/
2861static ssize_t
2862ip2_ipl_write(struct file *pFile, const char __user *pData, size_t count, loff_t *off)
2863{
2864#ifdef IP2DEBUG_IPL
2865 printk (KERN_DEBUG "IP2IPL: write %p, %d bytes\n", pData, count );
2866#endif
2867 return 0;
2868}
2869
2870/******************************************************************************/
2871/* Function: ip2_ipl_ioctl() */
2872/* Parameters: Pointer to device inode */
2873/* Pointer to file structure */
2874/* Command */
2875/* Argument */
2876/* Returns: Success or failure */
2877/* */
2878/* Description: */
2879/* */
2880/* */
2881/******************************************************************************/
47be36a2
AC
2882static long
2883ip2_ipl_ioctl (struct file *pFile, UINT cmd, ULONG arg )
1da177e4 2884{
47be36a2 2885 unsigned int iplminor = iminor(pFile->f_path.dentry->d_inode);
1da177e4
LT
2886 int rc = 0;
2887 void __user *argp = (void __user *)arg;
2888 ULONG __user *pIndex = argp;
2889 i2eBordStrPtr pB = i2BoardPtrTable[iplminor / 4];
2890 i2ChanStrPtr pCh;
2891
2892#ifdef IP2DEBUG_IPL
2893 printk (KERN_DEBUG "IP2IPL: ioctl cmd %d, arg %ld\n", cmd, arg );
2894#endif
2895
47be36a2
AC
2896 lock_kernel();
2897
1da177e4
LT
2898 switch ( iplminor ) {
2899 case 0: // IPL device
2900 rc = -EINVAL;
2901 break;
2902 case 1: // Status dump
2903 case 5:
2904 case 9:
2905 case 13:
2906 switch ( cmd ) {
2907 case 64: /* Driver - ip2stat */
7d7b93c1 2908 rc = put_user(-1, pIndex++ );
1da177e4
LT
2909 rc = put_user(irq_counter, pIndex++ );
2910 rc = put_user(bh_counter, pIndex++ );
2911 break;
2912
2913 case 65: /* Board - ip2stat */
2914 if ( pB ) {
2915 rc = copy_to_user(argp, pB, sizeof(i2eBordStr));
cf1c63c3 2916 rc = put_user(inb(pB->i2eStatus),
1da177e4
LT
2917 (ULONG __user *)(arg + (ULONG)(&pB->i2eStatus) - (ULONG)pB ) );
2918 } else {
2919 rc = -ENODEV;
2920 }
2921 break;
2922
2923 default:
2924 if (cmd < IP2_MAX_PORTS) {
2925 pCh = DevTable[cmd];
2926 if ( pCh )
2927 {
2928 rc = copy_to_user(argp, pCh, sizeof(i2ChanStr));
2929 } else {
2930 rc = -ENODEV;
2931 }
2932 } else {
2933 rc = -EINVAL;
2934 }
2935 }
2936 break;
2937
2938 case 2: // Ping device
2939 rc = -EINVAL;
2940 break;
2941 case 3: // Trace device
def9391c
AM
2942 /*
2943 * akpm: This used to write a whole bunch of function addresses
2944 * to userspace, which generated lots of put_user() warnings.
2945 * I killed it all. Just return "success" and don't do
2946 * anything.
2947 */
2948 if (cmd == 1)
2949 rc = 0;
2950 else
1da177e4 2951 rc = -EINVAL;
1da177e4
LT
2952 break;
2953
2954 default:
2955 rc = -ENODEV;
2956 break;
2957 }
47be36a2 2958 unlock_kernel();
1da177e4
LT
2959 return rc;
2960}
2961
2962/******************************************************************************/
2963/* Function: ip2_ipl_open() */
2964/* Parameters: Pointer to device inode */
2965/* Pointer to file structure */
2966/* Returns: Success or failure */
2967/* */
2968/* Description: */
2969/* */
2970/* */
2971/******************************************************************************/
2972static int
2973ip2_ipl_open( struct inode *pInode, struct file *pFile )
2974{
1da177e4
LT
2975
2976#ifdef IP2DEBUG_IPL
2977 printk (KERN_DEBUG "IP2IPL: open\n" );
2978#endif
f2b9857e 2979 cycle_kernel_lock();
1da177e4
LT
2980 return 0;
2981}
1da177e4
LT
2982
2983static int
4a5cdb5b 2984proc_ip2mem_show(struct seq_file *m, void *v)
1da177e4
LT
2985{
2986 i2eBordStrPtr pB;
2987 i2ChanStrPtr pCh;
2988 PTTY tty;
2989 int i;
2990
1da177e4
LT
2991#define FMTLINE "%3d: 0x%08x 0x%08x 0%011o 0%011o\n"
2992#define FMTLIN2 " 0x%04x 0x%04x tx flow 0x%x\n"
2993#define FMTLIN3 " 0x%04x 0x%04x rc flow\n"
2994
4a5cdb5b 2995 seq_printf(m,"\n");
1da177e4
LT
2996
2997 for( i = 0; i < IP2_MAX_BOARDS; ++i ) {
2998 pB = i2BoardPtrTable[i];
2999 if ( pB ) {
4a5cdb5b
AD
3000 seq_printf(m,"board %d:\n",i);
3001 seq_printf(m,"\tFifo rem: %d mty: %x outM %x\n",
1da177e4
LT
3002 pB->i2eFifoRemains,pB->i2eWaitingForEmptyFifo,pB->i2eOutMailWaiting);
3003 }
3004 }
3005
4a5cdb5b 3006 seq_printf(m,"#: tty flags, port flags, cflags, iflags\n");
1da177e4 3007 for (i=0; i < IP2_MAX_PORTS; i++) {
1da177e4
LT
3008 pCh = DevTable[i];
3009 if (pCh) {
3010 tty = pCh->pTTY;
3011 if (tty && tty->count) {
4a5cdb5b 3012 seq_printf(m,FMTLINE,i,(int)tty->flags,pCh->flags,
1da177e4
LT
3013 tty->termios->c_cflag,tty->termios->c_iflag);
3014
4a5cdb5b 3015 seq_printf(m,FMTLIN2,
1da177e4 3016 pCh->outfl.asof,pCh->outfl.room,pCh->channelNeeds);
4a5cdb5b 3017 seq_printf(m,FMTLIN3,pCh->infl.asof,pCh->infl.room);
1da177e4
LT
3018 }
3019 }
3020 }
4a5cdb5b
AD
3021 return 0;
3022}
3023
3024static int proc_ip2mem_open(struct inode *inode, struct file *file)
3025{
3026 return single_open(file, proc_ip2mem_show, NULL);
1da177e4
LT
3027}
3028
4a5cdb5b
AD
3029static const struct file_operations ip2mem_proc_fops = {
3030 .owner = THIS_MODULE,
3031 .open = proc_ip2mem_open,
3032 .read = seq_read,
3033 .llseek = seq_lseek,
3034 .release = single_release,
3035};
3036
1da177e4
LT
3037/*
3038 * This is the handler for /proc/tty/driver/ip2
3039 *
3040 * This stretch of code has been largely plagerized from at least three
3041 * different sources including ip2mkdev.c and a couple of other drivers.
3042 * The bugs are all mine. :-) =mhw=
3043 */
cdda7cd9 3044static int ip2_proc_show(struct seq_file *m, void *v)
1da177e4
LT
3045{
3046 int i, j, box;
1da177e4
LT
3047 int boxes = 0;
3048 int ports = 0;
3049 int tports = 0;
1da177e4 3050 i2eBordStrPtr pB;
cdda7cd9 3051 char *sep;
1da177e4 3052
cdda7cd9
AD
3053 seq_printf(m, "ip2info: 1.0 driver: %s\n", pcVersion);
3054 seq_printf(m, "Driver: SMajor=%d CMajor=%d IMajor=%d MaxBoards=%d MaxBoxes=%d MaxPorts=%d\n",
1da177e4
LT
3055 IP2_TTY_MAJOR, IP2_CALLOUT_MAJOR, IP2_IPL_MAJOR,
3056 IP2_MAX_BOARDS, ABS_MAX_BOXES, ABS_BIGGEST_BOX);
3057
3058 for( i = 0; i < IP2_MAX_BOARDS; ++i ) {
3059 /* This need to be reset for a board by board count... */
3060 boxes = 0;
3061 pB = i2BoardPtrTable[i];
3062 if( pB ) {
3063 switch( pB->i2ePom.e.porID & ~POR_ID_RESERVED )
3064 {
3065 case POR_ID_FIIEX:
cdda7cd9
AD
3066 seq_printf(m, "Board %d: EX ports=", i);
3067 sep = "";
1da177e4
LT
3068 for( box = 0; box < ABS_MAX_BOXES; ++box )
3069 {
3070 ports = 0;
3071
3072 if( pB->i2eChannelMap[box] != 0 ) ++boxes;
3073 for( j = 0; j < ABS_BIGGEST_BOX; ++j )
3074 {
3075 if( pB->i2eChannelMap[box] & 1<< j ) {
3076 ++ports;
3077 }
3078 }
cdda7cd9
AD
3079 seq_printf(m, "%s%d", sep, ports);
3080 sep = ",";
1da177e4
LT
3081 tports += ports;
3082 }
cdda7cd9 3083 seq_printf(m, " boxes=%d width=%d", boxes, pB->i2eDataWidth16 ? 16 : 8);
1da177e4
LT
3084 break;
3085
3086 case POR_ID_II_4:
cdda7cd9 3087 seq_printf(m, "Board %d: ISA-4 ports=4 boxes=1", i);
1da177e4
LT
3088 tports = ports = 4;
3089 break;
3090
3091 case POR_ID_II_8:
cdda7cd9 3092 seq_printf(m, "Board %d: ISA-8-std ports=8 boxes=1", i);
1da177e4
LT
3093 tports = ports = 8;
3094 break;
3095
3096 case POR_ID_II_8R:
cdda7cd9 3097 seq_printf(m, "Board %d: ISA-8-RJ11 ports=8 boxes=1", i);
1da177e4
LT
3098 tports = ports = 8;
3099 break;
3100
3101 default:
cdda7cd9 3102 seq_printf(m, "Board %d: unknown", i);
1da177e4
LT
3103 /* Don't try and probe for minor numbers */
3104 tports = ports = 0;
3105 }
3106
3107 } else {
3108 /* Don't try and probe for minor numbers */
cdda7cd9 3109 seq_printf(m, "Board %d: vacant", i);
1da177e4
LT
3110 tports = ports = 0;
3111 }
3112
3113 if( tports ) {
cdda7cd9
AD
3114 seq_puts(m, " minors=");
3115 sep = "";
1da177e4
LT
3116 for ( box = 0; box < ABS_MAX_BOXES; ++box )
3117 {
3118 for ( j = 0; j < ABS_BIGGEST_BOX; ++j )
3119 {
3120 if ( pB->i2eChannelMap[box] & (1 << j) )
3121 {
cdda7cd9 3122 seq_printf(m, "%s%d", sep,
1da177e4
LT
3123 j + ABS_BIGGEST_BOX *
3124 (box+i*ABS_MAX_BOXES));
cdda7cd9 3125 sep = ",";
1da177e4
LT
3126 }
3127 }
3128 }
1da177e4 3129 }
cdda7cd9 3130 seq_putc(m, '\n');
1da177e4 3131 }
cdda7cd9
AD
3132 return 0;
3133 }
1da177e4 3134
cdda7cd9
AD
3135static int ip2_proc_open(struct inode *inode, struct file *file)
3136{
3137 return single_open(file, ip2_proc_show, NULL);
3138}
1da177e4 3139
cdda7cd9
AD
3140static const struct file_operations ip2_proc_fops = {
3141 .owner = THIS_MODULE,
3142 .open = ip2_proc_open,
3143 .read = seq_read,
3144 .llseek = seq_lseek,
3145 .release = single_release,
3146};
1da177e4
LT
3147
3148/******************************************************************************/
3149/* Function: ip2trace() */
3150/* Parameters: Value to add to trace buffer */
3151/* Returns: Nothing */
3152/* */
3153/* Description: */
3154/* */
3155/* */
3156/******************************************************************************/
3157#ifdef IP2DEBUG_TRACE
3158void
3159ip2trace (unsigned short pn, unsigned char cat, unsigned char label, unsigned long codes, ...)
3160{
3161 long flags;
3162 unsigned long *pCode = &codes;
3163 union ip2breadcrumb bc;
3164 i2ChanStrPtr pCh;
3165
3166
3167 tracebuf[tracestuff++] = jiffies;
3168 if ( tracestuff == TRACEMAX ) {
3169 tracestuff = 0;
3170 }
3171 if ( tracestuff == tracestrip ) {
3172 if ( ++tracestrip == TRACEMAX ) {
3173 tracestrip = 0;
3174 }
3175 ++tracewrap;
3176 }
3177
3178 bc.hdr.port = 0xff & pn;
3179 bc.hdr.cat = cat;
3180 bc.hdr.codes = (unsigned char)( codes & 0xff );
3181 bc.hdr.label = label;
3182 tracebuf[tracestuff++] = bc.value;
3183
3184 for (;;) {
3185 if ( tracestuff == TRACEMAX ) {
3186 tracestuff = 0;
3187 }
3188 if ( tracestuff == tracestrip ) {
3189 if ( ++tracestrip == TRACEMAX ) {
3190 tracestrip = 0;
3191 }
3192 ++tracewrap;
3193 }
3194
3195 if ( !codes-- )
3196 break;
3197
3198 tracebuf[tracestuff++] = *++pCode;
3199 }
3200}
3201#endif
3202
3203
3204MODULE_LICENSE("GPL");
eb0e71c7
CS
3205
3206static struct pci_device_id ip2main_pci_tbl[] __devinitdata = {
3207 { PCI_DEVICE(PCI_VENDOR_ID_COMPUTONE, PCI_DEVICE_ID_COMPUTONE_IP2EX) },
3208 { }
3209};
3210
3211MODULE_DEVICE_TABLE(pci, ip2main_pci_tbl);
e6c4ef98
BH
3212
3213MODULE_FIRMWARE("intelliport2.bin");
This page took 0.655882 seconds and 5 git commands to generate.