📄 8253xchr.c
字号:
/* * Initialize the Hardware */ sab8253x_init_lineS(port); /* nothing in this function * refers to tty structure */ /* Activate RTS */ RAISE(port,rts); /* Activate DTR */ RAISE(port,dtr); /* * Initialize the modem signals values */ port->dcd.val=ISON(port,dcd); port->cts.val=ISON(port,cts); port->dsr.val=ISON(port,dsr); /* * Finally, enable interrupts */ port->interrupt_mask0 = SAB82532_IMR0_RFS | SAB82532_IMR0_PCE | SAB82532_IMR0_PLLA | SAB82532_IMR0_RSC | SAB82532_IMR0_CDSC;#if 0 ((port->ccontrol.ccr2 & SAB82532_CCR2_TOE) ? SAB82532_IMR0_CDSC : 0); /* the weird way the cards work * when clocking CD seems to * monitor txclk*/#endif WRITEB(port,imr0,port->interrupt_mask0); port->interrupt_mask1 = SAB82532_IMR1_EOP | SAB82532_IMR1_XMR | SAB82532_IMR1_TIN | SAB82532_IMR1_XPR; WRITEB(port, imr1, port->interrupt_mask1); port->all_sent = 1; /* * and set the speed of the serial port */ sab8253x_change_speedN(port); port->flags |= FLAG8253X_INITIALIZED; /* bad name for indicating to other functionalities status */ port->receive_chars = sab8253x_receive_charsC; port->transmit_chars = sab8253x_transmit_charsS; port->check_status = sab8253x_check_statusC; port->receive_test = (SAB82532_ISR0_RME | SAB82532_ISR0_RFO | SAB82532_ISR0_RPF); port->transmit_test = (SAB82532_ISR1_ALLS | SAB82532_ISR1_RDO | SAB82532_ISR1_XPR | SAB82532_ISR1_XDU | SAB82532_ISR1_CSC); port->check_status_test = SAB82532_ISR1_CSC; restore_flags(flags); return 0; errout: restore_flags(flags); return retval;}static int sab8253x_block_til_readyC(struct file* filp, struct sab_port *port){ DECLARE_WAITQUEUE(wait, current); int retval; int do_clocal = 1; /* cheating -- I need to understand how signals behave synchronously better*/ unsigned long flags; /* * If the device is in the middle of being closed, then block * until it's done, and then try again. */ if (port->flags & FLAG8253X_CLOSING) { interruptible_sleep_on(&port->close_wait); /* finish up previous close */ #ifdef SERIAL_DO_RESTART if (port->flags & FLAG8253X_HUP_NOTIFY) { return -EAGAIN; } else { return -ERESTARTSYS; }#else return -EAGAIN;#endif } /* sort out async vs sync tty, not call out */ /* * If non-blocking mode is set, or the port is not enabled, * then make the check up front and then exit. */ if (filp->f_flags & O_NONBLOCK) { if (port->flags & FLAG8253X_CALLOUT_ACTIVE) { return -EBUSY; } port->flags |= FLAG8253X_NORMAL_ACTIVE; return 0; } if (port->flags & FLAG8253X_CALLOUT_ACTIVE) { if (port->normal_termios.c_cflag & CLOCAL) { do_clocal = 1; } } /* * Block waiting for the carrier detect and the line to become * free (i.e., not in use by the callout). While we are in * this loop, port->count is dropped by one, so that * sab8253x_close() knows when to free things. We restore it upon * exit, either normal or abnormal. */ /* The port decrement logic is probably */ /* broken -- hence if def'd out -- it does*/ retval = 0; add_wait_queue(&port->open_wait, &wait); /* starts the wait but does not block here */ port->blocked_open++; while (1) /* on some devices when providing clock have to just assume connection */ { save_flags(flags); cli(); if (!(port->flags & FLAG8253X_CALLOUT_ACTIVE)) { RAISE(port, dtr); RAISE(port, rts); /* maybe not correct for sync */ /* * ??? Why changing the mode here? * port->regs->rw.mode |= SAB82532_MODE_FRTS; * port->regs->rw.mode &= ~(SAB82532_MODE_RTS); */ } restore_flags(flags);; current->state = TASK_INTERRUPTIBLE; if (!(port->flags & FLAG8253X_INITIALIZED)) {#ifdef SERIAL_DO_RESTART if (port->flags & FLAG8253X_HUP_NOTIFY) { retval = -EAGAIN; } else { retval = -ERESTARTSYS; }#else retval = -EAGAIN;#endif break; } if (!(port->flags & FLAG8253X_CALLOUT_ACTIVE) && !(port->flags & FLAG8253X_CLOSING) && (do_clocal || ISON(port,dcd))) { break; }#ifdef DEBUG_OPEN printk("sab8253x_block_til_ready:2 flags = 0x%x\n",port->flags);#endif if (signal_pending(current)) { retval = -ERESTARTSYS; break; }#ifdef DEBUG_OPEN printk("sab8253x_block_til_readyC blocking: ttyS%d, count = %d, flags = %x, clocal = %d, vstr = %02x\n", port->line, port->count, port->flags, do_clocal, READB(port,vstr));#endif schedule(); } current->state = TASK_RUNNING; remove_wait_queue(&port->open_wait, &wait); port->blocked_open--; #ifdef DEBUG_OPEN printk("sab8253x_block_til_ready after blockingC: ttys%d, count = %d\n", port->line, port->count);#endif if (retval) { return retval; } port->flags |= FLAG8253X_NORMAL_ACTIVE; return 0;}int sab8253xc_open(struct inode *inodep, struct file *filep){ unsigned int line; unsigned int retval; unsigned int counter; SAB_PORT *port; line = MINOR(inodep->i_rdev); /* let's find which physical device to use */ /* minor dev number indexes through the port */ /* list */ for(counter = 0, port = AuraPortRoot; (counter < line) && (port != NULL); ++counter) { port = port->next; } if (!port) { printk(KERN_ALERT "sab8253xc_open: can't find structure for line %d\n", line); return -ENODEV; } if(port->function == FUNCTION_NA) { /* port 2 on 1020s and 1520s */ return -ENODEV; } switch(port->open_type) { case OPEN_ASYNC: if(!(port->flags & FLAG8253X_CALLOUT_ACTIVE)) { return -EBUSY; } break; case OPEN_SYNC_CHAR: case OPEN_NOT: port->tty = NULL; port->open_type = OPEN_SYNC_CHAR; break; default: return -EBUSY; } /* * Maybe start up serial port -- may already be running in callout mode */ if(Sab8253xSetUpLists(port)) { if(port->open_type == OPEN_SYNC_CHAR) { port->open_type = OPEN_NOT; } return -ENODEV; } if(Sab8253xInitDescriptors2(port, sab8253xc_listsize, sab8253xc_rbufsize)) { Sab8253xCleanUpTransceiveN(port); /* the network functions should be okay -- only difference */ /* is the crc32 that is appended */ if(port->open_type == OPEN_SYNC_CHAR) { port->open_type = OPEN_NOT; } return -ENODEV; } retval = sab8253x_startupC(port); /* does not do anything if call out active */ if (retval) { if(port->open_type == OPEN_SYNC_CHAR) { port->open_type = OPEN_NOT; } return retval; } MOD_INC_USE_COUNT; /* might block */ /* note logic different from tty open failure does not call the close routine */ retval = sab8253x_block_til_readyC(filep, port); /* need to wait for completion of callout */ if(retval) { if(port->open_type == OPEN_SYNC_CHAR) { port->open_type = OPEN_NOT; } MOD_DEC_USE_COUNT; /* something went wrong */ return retval; } port->tty = NULL; port->open_type = OPEN_SYNC_CHAR; if(Sab8253xSetUpLists(port)) { port->open_type = OPEN_NOT; return -ENODEV; } if(Sab8253xInitDescriptors2(port, sab8253xc_listsize, sab8253xc_rbufsize)) { port->open_type = OPEN_NOT; Sab8253xCleanUpTransceiveN(port); /* the network functions should be okay -- only difference */ /* is the crc32 that is appended */ return -ENODEV; } retval = sab8253x_startupC(port); /* ditto */ if (retval) { port->open_type = OPEN_NOT; Sab8253xCleanUpTransceiveN(port); return retval; } port->tx_full = 0; port->rx_empty = 1; port->count++; port->session = current->session; port->pgrp = current->pgrp; filep->private_data = port; MOD_INC_USE_COUNT; return 0; /* success */}int sab8253xc_release(struct inode *inodep, struct file *filep){ SAB_PORT *port = (SAB_PORT*) filep->private_data; unsigned long flags; save_flags(flags); cli(); --(port->count); if(port->count <= 0) { sab8253x_shutdownN(port); Sab8253xCleanUpTransceiveN(port); port->count = 0; port->open_type = OPEN_NOT; } sab8253xc_fasync(-1, filep, 0); MOD_DEC_USE_COUNT; restore_flags(flags); return 0;}unsigned int sab8253xc_poll(struct file *fileobj, struct poll_table_struct *polltab){ SAB_PORT *port = fileobj->private_data; unsigned int mask = 0; poll_wait(fileobj, &port->write_wait, polltab); poll_wait(fileobj, &port->read_wait, polltab); if(port->rx_empty == 0) { mask |= POLLIN | POLLRDNORM; } if(port->tx_full == 0) { mask |= POLLOUT | POLLWRNORM; } return mask;}int sab8253xc_ioctl(struct inode *iobj, struct file *fileobj, unsigned int cmd, unsigned long length){ return 0;}int sab8253xc_fasync(int fd, struct file * fileobj, int mode){ SAB_PORT *port = fileobj->private_data; return fasync_helper(fd, fileobj, mode, &port->async_queue); /* I am a little baffled -- does async_helper */ /* work on the basis of a port or on an open */ /* basis*/}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -