📄 ip2main.c
字号:
// Some functions to keep track of what irq's we havestatic int __initis_valid_irq(int irq){ int *i = Valid_Irqs; while ((*i != 0) && (*i != irq)) { i++; } return (*i);}static void __initmark_requested_irq( char irq ){ rirqs[iindx++] = irq;}static int __initclear_requested_irq( char irq ){ int i; for ( i = 0; i < IP2_MAX_BOARDS; ++i ) { if (rirqs[i] == irq) { rirqs[i] = 0; return 1; } } return 0;}static int __inithave_requested_irq( char irq ){ // array init to zeros so 0 irq will not be requested as a side effect int i; for ( i = 0; i < IP2_MAX_BOARDS; ++i ) { if (rirqs[i] == irq) return 1; } return 0;}/******************************************************************************//* Function: init_module() *//* Parameters: None *//* Returns: Success (0) *//* *//* Description: *//* This is a required entry point for an installable module. It simply calls *//* the driver initialisation function and returns what it returns. *//******************************************************************************/#ifdef MODULEintinit_module(void){#ifdef IP2DEBUG_INIT printk (KERN_DEBUG "Loading module ...\n" );#endif //was return old_ip2_init(); return 0;}#endif /* MODULE *//******************************************************************************//* Function: cleanup_module() *//* Parameters: None *//* Returns: Nothing *//* *//* Description: *//* This is a required entry point for an installable module. It has to return *//* the device and the driver to a passive state. It should not be necessary *//* to reset the board fully, especially as the loadware is downloaded *//* externally rather than in the driver. We just want to disable the board *//* and clear the loadware to a reset state. To allow this there has to be a *//* way to detect whether the board has the loadware running at init time to *//* handle subsequent installations of the driver. All memory allocated by the *//* driver should be returned since it may be unloaded from memory. *//******************************************************************************/#ifdef MODULEvoidcleanup_module(void){ int err; int i;#ifdef IP2DEBUG_INIT printk (KERN_DEBUG "Unloading %s: version %s\n", pcName, pcVersion );#endif /* Stop poll timer if we had one. */ if ( TimerOn ) { del_timer ( &PollTimer ); TimerOn = 0; } /* Reset the boards we have. */ for( i = 0; i < IP2_MAX_BOARDS; ++i ) { if ( i2BoardPtrTable[i] ) { iiReset( i2BoardPtrTable[i] ); } } /* The following is done at most once, if any boards were installed. */ for ( i = 0; i < IP2_MAX_BOARDS; ++i ) { if ( i2BoardPtrTable[i] ) { iiResetDelay( i2BoardPtrTable[i] ); /* free io addresses and Tibet */ release_region( ip2config.addr[i], 8 );#ifdef CONFIG_DEVFS_FS devfs_unregister (i2BoardPtrTable[i]->devfs_ipl_handle); devfs_unregister (i2BoardPtrTable[i]->devfs_stat_handle);#endif } /* Disable and remove interrupt handler. */ if ( (ip2config.irq[i] > 0) && have_requested_irq(ip2config.irq[i]) ) { free_irq ( ip2config.irq[i], (void *)&pcName); clear_requested_irq( ip2config.irq[i]); } } if ( ( err = tty_unregister_driver ( &ip2_tty_driver ) ) ) { printk(KERN_ERR "IP2: failed to unregister tty driver (%d)\n", err); } if ( ( err = tty_unregister_driver ( &ip2_callout_driver ) ) ) { printk(KERN_ERR "IP2: failed to unregister callout driver (%d)\n", err); }#ifdef CONFIG_DEVFS_FS if ( ( err = devfs_unregister_chrdev ( IP2_IPL_MAJOR, pcIpl ) ) )#else if ( ( err = unregister_chrdev ( IP2_IPL_MAJOR, pcIpl ) ) )#endif { printk(KERN_ERR "IP2: failed to unregister IPL driver (%d)\n", err); } remove_proc_entry("ip2mem", &proc_root); // free memory for (i = 0; i < IP2_MAX_BOARDS; i++) { void *pB; if ((pB = i2BoardPtrTable[i]) != 0 ) { kfree ( pB ); i2BoardPtrTable[i] = NULL; } if ((DevTableMem[i]) != NULL ) { kfree ( DevTableMem[i] ); DevTableMem[i] = NULL; } } /* Cleanup the iiEllis subsystem. */ iiEllisCleanup();#ifdef IP2DEBUG_INIT printk (KERN_DEBUG "IP2 Unloaded\n" );#endif}#endif /* MODULE *//******************************************************************************//* Function: old_ip2_init() *//* Parameters: irq, io from command line of insmod et. al. *//* Returns: Success (0) *//* *//* Description: *//* This was the required entry point for all drivers (now in ip2.c) *//* It performs all *//* initialisation of the devices and driver structures, and registers itself *//* with the relevant kernel modules. *//******************************************************************************//* SA_INTERRUPT- if set blocks all interrupts else only this line *//* SA_SHIRQ - for shared irq PCI or maybe EISA only *//* SA_RANDOM - can be source for cert. random number generators */#define IP2_SA_FLAGS 0int __initold_ip2_init(void){#ifdef CONFIG_DEVFS_FS static devfs_handle_t devfs_handle; int j, box;#endif int i; int err; int status = 0; static int loaded; i2eBordStrPtr pB = NULL; int rc = -1;#ifdef IP2DEBUG_TRACE ip2trace (ITRC_NO_PORT, ITRC_INIT, ITRC_ENTER, 0 );#endif /* Announce our presence */ printk( KERN_INFO "%s version %s\n", pcName, pcVersion ); // ip2 can be unloaded and reloaded for no good reason // we can't let that happen here or bad things happen // second load hoses board but not system - fixme later if (loaded) { printk( KERN_INFO "Still loaded\n" ); return 0; } loaded++; /* if all irq config is zero we shall poll_only */ for ( i = 0; i < IP2_MAX_BOARDS; ++i ) { poll_only |= ip2config.irq[i]; } poll_only = !poll_only; /* Initialise the iiEllis subsystem. */ iiEllisInit(); /* Initialize arrays. */ memset( i2BoardPtrTable, 0, sizeof i2BoardPtrTable ); memset( DevTable, 0, sizeof DevTable ); memset( TtyTable, 0, sizeof TtyTable ); memset( Termios, 0, sizeof Termios ); memset( TermiosLocked, 0, sizeof TermiosLocked ); /* Initialise all the boards we can find (up to the maximum). */ for ( i = 0; i < IP2_MAX_BOARDS; ++i ) { switch ( ip2config.addr[i] ) { case 0: /* skip this slot even if card is present */ break; default: /* ISA */ /* ISA address must be specified */ if ( (ip2config.addr[i] < 0x100) || (ip2config.addr[i] > 0x3f8) ) { printk ( KERN_ERR "IP2: Bad ISA board %d address %x\n", i, ip2config.addr[i] ); ip2config.addr[i] = 0; } else { ip2config.type[i] = ISA; /* Check for valid irq argument, set for polling if invalid */ if (ip2config.irq[i] && !is_valid_irq(ip2config.irq[i])) { printk(KERN_ERR "IP2: Bad IRQ(%d) specified\n",ip2config.irq[i]); ip2config.irq[i] = 0;// 0 is polling and is valid in that sense } } break; case PCI:#ifdef CONFIG_PCI#if (LINUX_VERSION_CODE < 0x020163) /* 2.1.99 */ if (pcibios_present()) { unsigned char pci_bus, pci_devfn; int Pci_index = 0; status = pcibios_find_device(PCI_VENDOR_ID_COMPUTONE, PCI_DEVICE_ID_COMPUTONE_IP2EX, Pci_index, &pci_bus, &pci_devfn); if (status == 0) { unsigned int addr; unsigned char pci_irq; ip2config.type[i] = PCI; /* * Update Pci_index, so that the next time we go * searching for a PCI board we find a different * one. */ ++Pci_index; pcibios_read_config_dword(pci_bus, pci_devfn, PCI_BASE_ADDRESS_1, &addr); if ( addr & 1 ) { ip2config.addr[i]=(USHORT)(addr&0xfffe); } else { printk( KERN_ERR "IP2: PCI I/O address error\n"); } pcibios_read_config_byte(pci_bus, pci_devfn, PCI_INTERRUPT_LINE, &pci_irq); if (!is_valid_irq(pci_irq)) { printk( KERN_ERR "IP2: Bad PCI BIOS IRQ(%d)\n",pci_irq); pci_irq = 0; } ip2config.irq[i] = pci_irq; } else { // ann error ip2config.addr[i] = 0; if (status == PCIBIOS_DEVICE_NOT_FOUND) { printk( KERN_ERR "IP2: PCI board %d not found\n", i ); } else { pcibios_strerror(status); } } } #else /* LINUX_VERSION_CODE > 2.1.99 */ if (pci_present()) { struct pci_dev *pci_dev_i = NULL; pci_dev_i = pci_find_device(PCI_VENDOR_ID_COMPUTONE, PCI_DEVICE_ID_COMPUTONE_IP2EX, pci_dev_i); if (pci_dev_i != NULL) { unsigned int addr; unsigned char pci_irq; ip2config.type[i] = PCI; status = pci_read_config_dword(pci_dev_i, PCI_BASE_ADDRESS_1, &addr); if ( addr & 1 ) { ip2config.addr[i]=(USHORT)(addr&0xfffe); } else { printk( KERN_ERR "IP2: PCI I/O address error\n"); } status = pci_read_config_byte(pci_dev_i, PCI_INTERRUPT_LINE, &pci_irq); if (!is_valid_irq(pci_irq)) { printk( KERN_ERR "IP2: Bad PCI BIOS IRQ(%d)\n",pci_irq); pci_irq = 0; } ip2config.irq[i] = pci_irq; } else { // ann error ip2config.addr[i] = 0; if (status == PCIBIOS_DEVICE_NOT_FOUND) { printk( KERN_ERR "IP2: PCI board %d not found\n", i ); } else { pcibios_strerror(status); } } } #endif /* ! 2_0_X */#else printk( KERN_ERR "IP2: PCI card specified but PCI support not\n"); printk( KERN_ERR "IP2: configured in this kernel.\n"); printk( KERN_ERR "IP2: Recompile kernel with CONFIG_PCI defined!\n");#endif /* CONFIG_PCI */ break; case EISA: if ( (ip2config.addr[i] = find_eisa_board( Eisa_slot + 1 )) != 0) { /* Eisa_irq set as side effect, boo */ ip2config.type[i] = EISA; } ip2config.irq[i] = Eisa_irq; break; } /* switch */ } /* for */ for ( i = 0; i < IP2_MAX_BOARDS; ++i ) { if ( ip2config.addr[i] ) { pB = kmalloc( sizeof(i2eBordStr), GFP_KERNEL); if ( pB != NULL ) { i2BoardPtrTable[i] = pB; memset( pB, 0, sizeof(i2eBordStr) ); iiSetAddress( pB, ip2config.addr[i], ii2DelayTimer ); iiReset( pB ); } else { printk(KERN_ERR "IP2: board memory allocation error\n"); } } } for ( i = 0; i < IP2_MAX_BOARDS; ++i ) { if ( ( pB = i2BoardPtrTable[i] ) != NULL ) { iiResetDelay( pB ); break; } } for ( i = 0; i < IP2_MAX_BOARDS; ++i ) { if ( i2BoardPtrTable[i] != NULL ) { ip2_init_board( i ); } }#ifdef IP2DEBUG_TRACE ip2trace (ITRC_NO_PORT, ITRC_INIT, 2, 0 );#endif /* Zero out the normal tty device structure. */ memset ( &ip2_tty_driver, 0, sizeof ip2_tty_driver ); /* Initialise the relevant fields. */ ip2_tty_driver.magic = TTY_DRIVER_MAGIC; ip2_tty_driver.name = pcTty;#if LINUX_VERSION_CODE > KERNEL_VERSION(2,1,0) ip2_tty_driver.driver_name = pcDriver_name; ip2_tty_driver.read_proc = ip2_read_proc;#endif ip2_tty_driver.major = IP2_TTY_MAJOR; ip2_tty_driver.minor_start = 0; ip2_tty_driver.num = IP2_MAX_PORTS; ip2_tty_driver.type = TTY_DRIVER_TYPE_SERIAL; ip2_tty_driver.subtype = SERIAL_TYPE_NORMAL; ip2_tty_driver.init_termios = tty_std_termios; ip2_tty_driver.init_termios.c_cflag = B9600|CS8|CREAD|HUPCL|CLOCAL;#ifdef CONFIG_DEVFS_FS ip2_tty_driver.flags = TTY_DRIVER_REAL_RAW | TTY_DRIVER_NO_DEVFS;#else ip2_tty_driver.flags = TTY_DRIVER_REAL_RAW;#endif ip2_tty_driver.refcount = &ref_count; ip2_tty_driver.table = TtyTable; ip2_tty_driver.termios = Termios; ip2_tty_driver.termios_locked = TermiosLocked; /* Setup the pointers to the implemented functions. */ ip2_tty_driver.open = ip2_open; ip2_tty_driver.close = ip2_close; ip2_tty_driver.write = ip2_write; ip2_tty_driver.put_char = ip2_putchar; ip2_tty_driver.flush_chars = ip2_flush_chars; ip2_tty_driver.write_room = ip2_write_room; ip2_tty_driver.chars_in_buffer = ip2_chars_in_buf; ip2_tty_driver.flush_buffer = ip2_flush_buffer; ip2_tty_driver.ioctl = ip2_ioctl; ip2_tty_driver.throttle = ip2_throttle; ip2_tty_driver.unthrottle = ip2_unthrottle; ip2_tty_driver.set_termios = ip2_set_termios; ip2_tty_driver.set_ldisc = ip2_set_line_discipline; ip2_tty_driver.stop = ip2_stop; ip2_tty_driver.start = ip2_start; ip2_tty_driver.hangup = ip2_hangup;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -