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