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