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