Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

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