⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 rio_linux.c

📁 linux 内核源代码
💻 C
📖 第 1 页 / 共 3 页
字号:
	rio_dprintk(RIO_DEBUG_IFLOW, "riointr() doing host %p type %d\n", ptr, HostP->Type);	clear_bit(RIO_BOARD_INTR_LOCK, &HostP->locks);	rio_dprintk(RIO_DEBUG_IFLOW, "rio: exit rio_interrupt (%d/%d)\n", irq, HostP->Ivec);	func_exit();	return IRQ_HANDLED;}static void rio_pollfunc(unsigned long data){	func_enter();	rio_interrupt(0, &p->RIOHosts[data]);	mod_timer(&p->RIOHosts[data].timer, jiffies + rio_poll);	func_exit();}/* ********************************************************************** * *                Here are the routines that actually                     * *              interface with the generic_serial driver                  * * ********************************************************************** *//* Ehhm. I don't know how to fiddle with interrupts on the Specialix    cards. ....   Hmm. Ok I figured it out. You don't.  -- REW */static void rio_disable_tx_interrupts(void *ptr){	func_enter();	/*  port->gs.flags &= ~GS_TX_INTEN; */	func_exit();}static void rio_enable_tx_interrupts(void *ptr){	struct Port *PortP = ptr;	/* int hn; */	func_enter();	/* hn = PortP->HostP - p->RIOHosts;	   rio_dprintk (RIO_DEBUG_TTY, "Pushing host %d\n", hn);	   rio_interrupt (-1,(void *) hn, NULL); */	RIOTxEnable((char *) PortP);	/*	 * In general we cannot count on "tx empty" interrupts, although	 * the interrupt routine seems to be able to tell the difference.	 */	PortP->gs.flags &= ~GS_TX_INTEN;	func_exit();}static void rio_disable_rx_interrupts(void *ptr){	func_enter();	func_exit();}static void rio_enable_rx_interrupts(void *ptr){	/*  struct rio_port *port = ptr; */	func_enter();	func_exit();}/* Jeez. Isn't this simple?  */static int rio_get_CD(void *ptr){	struct Port *PortP = ptr;	int rv;	func_enter();	rv = (PortP->ModemState & MSVR1_CD) != 0;	rio_dprintk(RIO_DEBUG_INIT, "Getting CD status: %d\n", rv);	func_exit();	return rv;}/* Jeez. Isn't this simple? Actually, we can sync with the actual port   by just pushing stuff into the queue going to the port... */static int rio_chars_in_buffer(void *ptr){	func_enter();	func_exit();	return 0;}/* Nothing special here... */static void rio_shutdown_port(void *ptr){	struct Port *PortP;	func_enter();	PortP = (struct Port *) ptr;	PortP->gs.tty = NULL;	func_exit();}/* I haven't the foggiest why the decrement use count has to happen   here. The whole linux serial drivers stuff needs to be redesigned.   My guess is that this is a hack to minimize the impact of a bug   elsewhere. Thinking about it some more. (try it sometime) Try   running minicom on a serial port that is driven by a modularized   driver. Have the modem hangup. Then remove the driver module. Then   exit minicom.  I expect an "oops".  -- REW */static void rio_hungup(void *ptr){	struct Port *PortP;	func_enter();	PortP = (struct Port *) ptr;	PortP->gs.tty = NULL;	func_exit();}/* The standard serial_close would become shorter if you'd wrap it like   this.    rs_close (...){save_flags;cli;real_close();dec_use_count;restore_flags;} */static void rio_close(void *ptr){	struct Port *PortP;	func_enter();	PortP = (struct Port *) ptr;	riotclose(ptr);	if (PortP->gs.count) {		printk(KERN_ERR "WARNING port count:%d\n", PortP->gs.count);		PortP->gs.count = 0;	}	PortP->gs.tty = NULL;	func_exit();}static int rio_fw_ioctl(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg){	int rc = 0;	func_enter();	/* The "dev" argument isn't used. */	rc = riocontrol(p, 0, cmd, arg, capable(CAP_SYS_ADMIN));	func_exit();	return rc;}extern int RIOShortCommand(struct rio_info *p, struct Port *PortP, int command, int len, int arg);static int rio_ioctl(struct tty_struct *tty, struct file *filp, unsigned int cmd, unsigned long arg){	void __user *argp = (void __user *)arg;	int rc;	struct Port *PortP;	int ival;	func_enter();	PortP = (struct Port *) tty->driver_data;	rc = 0;	switch (cmd) {	case TIOCSSOFTCAR:		if ((rc = get_user(ival, (unsigned __user *) argp)) == 0) {			tty->termios->c_cflag = (tty->termios->c_cflag & ~CLOCAL) | (ival ? CLOCAL : 0);		}		break;	case TIOCGSERIAL:		rc = -EFAULT;		if (access_ok(VERIFY_WRITE, argp, sizeof(struct serial_struct)))			rc = gs_getserial(&PortP->gs, argp);		break;	case TCSBRK:		if (PortP->State & RIO_DELETED) {			rio_dprintk(RIO_DEBUG_TTY, "BREAK on deleted RTA\n");			rc = -EIO;		} else {			if (RIOShortCommand(p, PortP, SBREAK, 2, 250) == RIO_FAIL) {				rio_dprintk(RIO_DEBUG_INTR, "SBREAK RIOShortCommand failed\n");				rc = -EIO;			}		}		break;	case TCSBRKP:		if (PortP->State & RIO_DELETED) {			rio_dprintk(RIO_DEBUG_TTY, "BREAK on deleted RTA\n");			rc = -EIO;		} else {			int l;			l = arg ? arg * 100 : 250;			if (l > 255)				l = 255;			if (RIOShortCommand(p, PortP, SBREAK, 2, arg ? arg * 100 : 250) == RIO_FAIL) {				rio_dprintk(RIO_DEBUG_INTR, "SBREAK RIOShortCommand failed\n");				rc = -EIO;			}		}		break;	case TIOCSSERIAL:		rc = -EFAULT;		if (access_ok(VERIFY_READ, argp, sizeof(struct serial_struct)))			rc = gs_setserial(&PortP->gs, argp);		break;	default:		rc = -ENOIOCTLCMD;		break;	}	func_exit();	return rc;}/* The throttle/unthrottle scheme for the Specialix card is different * from other drivers and deserves some explanation.  * The Specialix hardware takes care of XON/XOFF * and CTS/RTS flow control itself.  This means that all we have to * do when signalled by the upper tty layer to throttle/unthrottle is * to make a note of it here.  When we come to read characters from the * rx buffers on the card (rio_receive_chars()) we look to see if the * upper layer can accept more (as noted here in rio_rx_throt[]).  * If it can't we simply don't remove chars from the cards buffer.  * When the tty layer can accept chars, we again note that here and when * rio_receive_chars() is called it will remove them from the cards buffer. * The card will notice that a ports buffer has drained below some low * water mark and will unflow control the line itself, using whatever * flow control scheme is in use for that port. -- Simon Allen */static void rio_throttle(struct tty_struct *tty){	struct Port *port = (struct Port *) tty->driver_data;	func_enter();	/* If the port is using any type of input flow	 * control then throttle the port.	 */	if ((tty->termios->c_cflag & CRTSCTS) || (I_IXOFF(tty))) {		port->State |= RIO_THROTTLE_RX;	}	func_exit();}static void rio_unthrottle(struct tty_struct *tty){	struct Port *port = (struct Port *) tty->driver_data;	func_enter();	/* Always unthrottle even if flow control is not enabled on	 * this port in case we disabled flow control while the port	 * was throttled	 */	port->State &= ~RIO_THROTTLE_RX;	func_exit();	return;}/* ********************************************************************** * *                    Here are the initialization routines.               * * ********************************************************************** */static struct vpd_prom *get_VPD_PROM(struct Host *hp){	static struct vpd_prom vpdp;	char *p;	int i;	func_enter();	rio_dprintk(RIO_DEBUG_PROBE, "Going to verify vpd prom at %p.\n", hp->Caddr + RIO_VPD_ROM);	p = (char *) &vpdp;	for (i = 0; i < sizeof(struct vpd_prom); i++)		*p++ = readb(hp->Caddr + RIO_VPD_ROM + i * 2);	/* read_rio_byte (hp, RIO_VPD_ROM + i*2); */	/* Terminate the identifier string.	 *** requires one extra byte in struct vpd_prom *** */	*p++ = 0;	if (rio_debug & RIO_DEBUG_PROBE)		my_hd((char *) &vpdp, 0x20);	func_exit();	return &vpdp;}static const struct tty_operations rio_ops = {	.open = riotopen,	.close = gs_close,	.write = gs_write,	.put_char = gs_put_char,	.flush_chars = gs_flush_chars,	.write_room = gs_write_room,	.chars_in_buffer = gs_chars_in_buffer,	.flush_buffer = gs_flush_buffer,	.ioctl = rio_ioctl,	.throttle = rio_throttle,	.unthrottle = rio_unthrottle,	.set_termios = gs_set_termios,	.stop = gs_stop,	.start = gs_start,	.hangup = gs_hangup,};static int rio_init_drivers(void){	int error = -ENOMEM;	rio_driver = alloc_tty_driver(256);	if (!rio_driver)		goto out;	rio_driver2 = alloc_tty_driver(256);	if (!rio_driver2)		goto out1;	func_enter();	rio_driver->owner = THIS_MODULE;	rio_driver->driver_name = "specialix_rio";	rio_driver->name = "ttySR";	rio_driver->major = RIO_NORMAL_MAJOR0;	rio_driver->type = TTY_DRIVER_TYPE_SERIAL;	rio_driver->subtype = SERIAL_TYPE_NORMAL;	rio_driver->init_termios = tty_std_termios;	rio_driver->init_termios.c_cflag = B9600 | CS8 | CREAD | HUPCL | CLOCAL;	rio_driver->flags = TTY_DRIVER_REAL_RAW;	tty_set_operations(rio_driver, &rio_ops);	rio_driver2->owner = THIS_MODULE;	rio_driver2->driver_name = "specialix_rio";	rio_driver2->name = "ttySR";	rio_driver2->major = RIO_NORMAL_MAJOR1;	rio_driver2->type = TTY_DRIVER_TYPE_SERIAL;	rio_driver2->subtype = SERIAL_TYPE_NORMAL;	rio_driver2->init_termios = tty_std_termios;	rio_driver2->init_termios.c_cflag = B9600 | CS8 | CREAD | HUPCL | CLOCAL;	rio_driver2->flags = TTY_DRIVER_REAL_RAW;	tty_set_operations(rio_driver2, &rio_ops);	rio_dprintk(RIO_DEBUG_INIT, "set_termios = %p\n", gs_set_termios);	if ((error = tty_register_driver(rio_driver)))		goto out2;	if ((error = tty_register_driver(rio_driver2)))		goto out3;	func_exit();	return 0;      out3:	tty_unregister_driver(rio_driver);      out2:	put_tty_driver(rio_driver2);      out1:	put_tty_driver(rio_driver);      out:	printk(KERN_ERR "rio: Couldn't register a rio driver, error = %d\n", error);	return 1;}static void *ckmalloc(int size){	void *p;	p = kzalloc(size, GFP_KERNEL);	return p;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -