unsigned int cctdev_poll(struct file *filp, poll_table *wait) { struct cctdev_dev *dev = filp->private_data; int minor_num; unsigned int mask = 0; F_ENTER(); minor_num = MINOR(dev->cdev.dev); down(&txCittyBuf[minor_num].gSem); poll_wait(filp, &txCittyBuf[minor_num].gInq, wait); if (txCittyBuf[minor_num].iBufOut != txCittyBuf[minor_num].iBufIn) mask |= POLLIN | POLLRDNORM; mask |= POLLOUT | POLLWRNORM; up(&txCittyBuf[minor_num].gSem); F_LEAVE(); return mask; }
/* the real citty_ioctl function. * The above is done to get the small functions*/ static int citty_ioctl(struct tty_struct *tty, unsigned int cmd, unsigned long arg) { struct file *file = NULL; F_ENTER(); switch (cmd) { case TIOCGSERIAL: return citty_ioctl_tiocgserial(tty, file, cmd, arg); case TIOCMIWAIT: return citty_ioctl_tiocmiwait(tty, file, cmd, arg); case TIOCGICOUNT: return citty_ioctl_tiocgicount(tty, file, cmd, arg); case TCSETS: return citty_ioctl_tcsets(tty, file, cmd, arg); case TCGETS: /* 0x5401 ioctls.h */ return citty_ioctl_tcgets(tty, file, cmd, arg); case TCSETSF: /* 0x5404 */ case TCSETAF: /* 0x5408 */ return 0; /* has to return zero for qtopia to work */ default: PDEBUG("citty_ioctl cmd: %d.\n", cmd); return -ENOIOCTLCMD; /* for PPPD to work? */ break; } F_LEAVE(); }
static int citty_ioctl_tiocgicount(struct tty_struct *tty, struct file *file, unsigned int cmd, unsigned long arg) { struct citty_port *citty = tty->driver_data; F_ENTER(); if (cmd == TIOCGICOUNT) { struct async_icount cnow = citty->icount; struct serial_icounter_struct icount; icount.cts = cnow.cts; icount.dsr = cnow.dsr; icount.rng = cnow.rng; icount.dcd = cnow.dcd; icount.rx = cnow.rx; icount.tx = cnow.tx; icount.frame = cnow.frame; icount.overrun = cnow.overrun; icount.parity = cnow.parity; icount.brk = cnow.brk; icount.buf_overrun = cnow.buf_overrun; if (copy_to_user((void __user *)arg, &icount, sizeof(icount))) return -EFAULT; return 0; } F_LEAVE(); return -ENOIOCTLCMD; }
static void __exit citty_exit(void) { struct citty_port *citty = NULL; int i; F_ENTER(); /* unregister devices */ for (i = 0; i < CITTY_TTY_MINORS; ++i) { down(&sem_lock_tty[i]); citty = citty_table[i]; if (citty) { citty_table[i] = NULL; kfree(citty); } up(&sem_lock_tty[i]); tty_port_destroy(&citty_port_table[i]); tty_unregister_device(citty_tty_driver, i); cci_free_buffer(&txCittyBuf[i]); } /* unregister driver */ tty_unregister_driver(citty_tty_driver); put_tty_driver(citty_tty_driver); /* clean up for the cctdev stuff */ cctdev_cleanup_module(); F_LEAVE(); }
int cctdev_open(struct inode *inode, struct file *filp) { struct cctdev_dev *dev; /* device information */ F_ENTER(); dev = container_of(inode->i_cdev, struct cctdev_dev, cdev); filp->private_data = dev; /* for other methods */ /* now trim to 0 the length of the device if open was write-only */ /* if ( (filp->f_flags & O_ACCMODE) == O_WRONLY) { if (down_interruptible(&dev->sem)) return -ERESTARTSYS; up(&dev->sem); } */ /* used to keep track of how many readers */ down(&dev->sem); if (filp->f_mode & FMODE_READ) dev->nreaders++; if (filp->f_mode & FMODE_WRITE) dev->nwriters++; up(&dev->sem); F_LEAVE(); return nonseekable_open(inode, filp); /* success */ }
static int citty_write_room(struct tty_struct *tty) { struct citty_port *citty = NULL; int index = tty->index; int room = -EINVAL; F_ENTER(); down(&sem_lock_tty[index]); citty = citty_table[index]; if (!citty) { up(&sem_lock_tty[index]); return -ENODEV; } if (!citty->port->count) { PDEBUG("citty_write_room: no port is open."); /* port was not opened */ goto exit; } /* calculate how much room is left in the device */ /* CHECKPOINT */ /* room = CITTY_BUF_SIZE * spacefree( &txCittyBuf ); */ room = CITTY_BUF_SIZE * spacefree(&txCittyBuf[tty->index]); exit: up(&sem_lock_tty[index]); F_LEAVE(); return room; }
void cci_init_buffer(struct buf_struct *buffer) { int i; F_ENTER(); for (i = 0; i < NUM_CITTY_BUF; i++) { buffer->pBuf[i] = kmalloc(CITTY_BUF_SIZE, GFP_KERNEL); if (!buffer->pBuf[i]) printk(KERN_ERR "Failed to allocate memory.\n"); buffer->iBufIn = 0; buffer->iBufOut = 0; } sema_init(&(buffer->gSem), 1); /* init the queue */ init_waitqueue_head(&(buffer->gInq)); init_waitqueue_head(&(buffer->gOutq)); F_LEAVE(); }
static void __exit cidatatty_exit(void) { struct cidatatty_port *cidatatty; int i; F_ENTER(); /* unregister device */ for (i = 0; i < CIDATATTY_TTY_MINORS; ++i) { cidatatty = cidatatty_table[i].data_port; if (cidatatty) { /* close the port */ while (cidatatty->port.count) do_close(cidatatty); cidatatty_table[i].data_port = NULL; tty_port_destroy(&cidatatty->port); kfree(cidatatty); } tty_unregister_device(cidatatty_tty_driver, i); } /* unregister driver */ tty_unregister_driver(cidatatty_tty_driver); cctdatadev_cleanup_module(); F_LEAVE(); }
static void citty_close(struct tty_struct *tty, struct file *file) { struct citty_port *citty = NULL; int index = tty->index; F_ENTER(); down(&sem_lock_tty[index]); citty = citty_table[index]; /* Modified by Rovin Yu: release citty and related resource */ if (citty) { if (!citty->port->count) { /* port was never opened */ goto exit; } --citty->port->count; PDEBUG("citty_close: index is %d, count is %d\n", index, citty->port->count); if (citty->port->count <= 0) { citty_table[index] = NULL; kfree(citty); } } exit: up(&sem_lock_tty[index]); F_LEAVE(); }
static void __exit citty_exit(void) { struct citty_serial *citty; int i; F_ENTER(); for (i = 0; i < CITTY_TTY_MINORS; ++i) tty_unregister_device(citty_tty_driver, i); tty_unregister_driver(citty_tty_driver); put_tty_driver(citty_tty_driver); /* free the memory */ for (i = 0; i < CITTY_TTY_MINORS; ++i) { down(&sem[i]); citty = citty_table[i]; if (citty) { kfree(citty); citty_table[i] = NULL; //cci_free_buffer(&txCittyBuf[i]); } up(&sem[i]); cci_free_buffer(&txCittyBuf[i]); //Modified by Rovin to move here } /* clean up for the cctdev stuff */ cctdev_cleanup_module(); F_LEAVE(); }
static int citty_ioctl(struct tty_struct *tty, struct file *file, unsigned int cmd, unsigned long arg) #endif { #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 39) struct file *file = NULL; #endif F_ENTER(); switch (cmd) { case TIOCGSERIAL: return citty_ioctl_tiocgserial(tty, file, cmd, arg); case TIOCMIWAIT: return citty_ioctl_tiocmiwait(tty, file, cmd, arg); case TIOCGICOUNT: return citty_ioctl_tiocgicount(tty, file, cmd, arg); case TCSETS: return citty_ioctl_tcsets(tty, file, cmd, arg); case TCGETS: //0x5401 ioctls.h return citty_ioctl_tcgets(tty, file, cmd, arg); case TCSETSF: //0x5404 case TCSETAF: //0x5408 return 0; //has to return zero for qtopia to work default: PDEBUG("citty_ioctl cmd: %d.\n", cmd); return -ENOIOCTLCMD; // for PPPD to work? break; } F_LEAVE(); }
static int __init citty_init(void) { int retval; int i; F_ENTER(); /* allocate the tty driver */ citty_tty_driver = alloc_tty_driver(CITTY_TTY_MINORS); if (!citty_tty_driver) return -ENOMEM; /* initialize the tty driver */ citty_tty_driver->owner = THIS_MODULE; citty_tty_driver->driver_name = "citty_tty"; citty_tty_driver->name = "citty"; citty_tty_driver->major = CITTY_TTY_MAJOR; citty_tty_driver->type = TTY_DRIVER_TYPE_SERIAL; citty_tty_driver->subtype = SERIAL_TYPE_NORMAL; citty_tty_driver->flags = TTY_DRIVER_REAL_RAW | TTY_DRIVER_DYNAMIC_DEV; citty_tty_driver->init_termios = tty_std_termios; /* B115200 | CS8 | CREAD | HUPCL | CLOCAL; */ citty_tty_driver->init_termios.c_cflag = B9600 | CS8 | CREAD | CLOCAL; citty_tty_driver->init_termios.c_iflag = IGNBRK | IGNCR | IGNPAR; citty_tty_driver->init_termios.c_oflag = 0; citty_tty_driver->init_termios.c_lflag = 0; tty_set_operations(citty_tty_driver, &serial_ops); /* register the tty driver */ retval = tty_register_driver(citty_tty_driver); if (retval) { printk(KERN_ERR "failed to register citty tty driver"); put_tty_driver(citty_tty_driver); citty_tty_driver = NULL; return retval; } /* register tty devices */ for (i = 0; i < CITTY_TTY_MINORS; ++i) { /* Init buffer */ cci_init_buffer(&txCittyBuf[i]); sema_init(&sem_lock_tty[i], 1); tty_port_init(&citty_port_table[i]); tty_port_register_device(&citty_port_table[i], citty_tty_driver, i, NULL); } printk(KERN_INFO DRIVER_DESC " " DRIVER_VERSION "\n"); cctdev_init_module(); F_LEAVE(); return retval; }
static void cidatatty_close(struct tty_struct *tty, struct file *file) { struct cidatatty_port *cidatatty = tty->driver_data; F_ENTER(); if (cidatatty) do_close(cidatatty); F_LEAVE(); }
static int citty_open(struct tty_struct *tty, struct file *file) { struct citty_serial *citty; int index; F_ENTER(); schedule(); /* initialize the pointer in case something fails */ tty->driver_data = NULL; /* get the serial object associated with this tty pointer */ index = tty->index; if (!cctdev_ready || (cctdev_devices[index].nreaders == 0 && cctdev_devices[index].nwriters == 0)) return -EAGAIN; down(&sem[index]); citty = citty_table[index]; if (citty == NULL) { /* first time accessing this device, let's create it */ citty = kmalloc(sizeof(*citty), GFP_KERNEL); if (!citty) { up(&sem[index]); return -ENOMEM; } citty->open_count = 0; citty_table[index] = citty; } /* save our structure within the tty structure */ tty->driver_data = citty; /* vcy */ tty->flags = TTY_NO_WRITE_SPLIT | tty->flags; citty->tty = tty; ++citty->open_count; if (citty->open_count == 1) { /* this is the first time this port is opened */ /* do any hardware initialization needed here */ } up(&sem[index]); F_LEAVE(); return 0; }
static int citty_open(struct tty_struct *tty, struct file *file) { struct citty_port *citty = NULL; int index = tty->index; F_ENTER(); schedule(); /* initialize the pointer in case something fails */ tty->driver_data = NULL; /* get the serial object associated with this tty pointer */ if (!cctdev_ready || (cctdev_devices[index].nreaders == 0 && cctdev_devices[index].nwriters == 0)) return -EAGAIN; mutex_lock(&mutex_lock_tty[index]); citty = citty_table[index]; if (!citty) { citty = kmalloc(sizeof(*citty), GFP_KERNEL); if (!citty) { mutex_unlock(&mutex_lock_tty[index]); return -ENOMEM; } /* save tty_port structure within the our structure */ citty_table[index] = citty; citty->port = &citty_port_table[index]; citty->port->count = 0; } /* do the real open operation */ /* save our structure within the tty structure */ tty->driver_data = citty; /* vcy */ tty->flags = TTY_NO_WRITE_SPLIT | tty->flags; /* save tty_struct within the tty_port structure */ citty->port->tty = tty; ++citty->port->count; if (citty->port->count == 1) { /* this is the first time this port is opened */ /* do any hardware initialization needed here */ } mutex_unlock(&mutex_lock_tty[index]); F_LEAVE(); return 0; }
static int citty_write(struct tty_struct *tty, const unsigned char *buffer, int count) { struct citty_port *citty = NULL; int index = tty->index; int retval = -EINVAL; F_ENTER(); /* for some reason, this function is called with count == 0 */ if (count <= 0) { printk(KERN_ERR "Error: count is %d.\n", count); return 0; } down(&sem_lock_tty[index]); citty = citty_table[index]; if (!citty) { up(&sem_lock_tty[index]); PDEBUG("Warning: citty_write: citty is NULL\n"); return -ENODEV; } if (!citty->port->count) { printk(KERN_ERR "Error: citty_write: port was not open\n"); /* port was not opened */ goto exit; } #ifdef DEBUG_BUF_CONTENT /* int i; */ printk(KERN_DEBUG "CITTY Tx Buffer datalen is %d\n data:", count); for (i = 0; i < count; i++) printk(KERN_DEBUG "%02x(%c)", buffer[i]&0xff, buffer[i]&0xff); /* printk(KERN_DEBUG " %02x", buffer[i]&0xff ); */ printk(KERN_DEBUG "\n"); #endif /* * packet is ready for transmission: * write the packet to TxCitty buffer */ retval = write_citty_buffer(&txCittyBuf[tty->index], buffer, count, COPY_FROM_CITTY); exit: up(&sem_lock_tty[index]); F_LEAVE(); return retval; }
static int citty_ioctl_tcgets(struct tty_struct *tty, struct file *file, unsigned int cmd, unsigned long arg) { F_ENTER(); if (copy_to_user((void *)arg, tty->termios, sizeof(struct termios))) { printk("Failed to copy to user for tcgets.\n"); return -EFAULT; } F_LEAVE(); return 0; }
/* * Set up the char_dev structure for this device. */ static void cctdev_setup_cdev(struct cctdev_dev *dev, int index) { int err, devno = MKDEV(cctdev_major, cctdev_minor + index); F_ENTER(); cdev_init(&dev->cdev, &cctdev_fops); dev->cdev.owner = THIS_MODULE; dev->cdev.ops = &cctdev_fops; err = cdev_add(&dev->cdev, devno, 1); /* Fail gracefully if need be */ if (err) printk(KERN_NOTICE "Error %d adding cctdev%d", err, index); F_LEAVE(); }
static int citty_tiocmset(struct tty_struct *tty, struct file *file, unsigned int set, unsigned int clear) #endif { struct citty_serial *citty = tty->driver_data; unsigned int mcr = citty->mcr; F_ENTER(); if (set & TIOCM_RTS) mcr |= MCR_RTS; if (set & TIOCM_DTR) mcr |= MCR_RTS; if (set & TIOCM_LOOP) mcr |= MCR_RTS; if (set & TIOCM_CTS) mcr |= MCR_RTS; if (set & TIOCM_RI) mcr |= MCR_RTS; if (set & TIOCM_DSR) mcr |= MCR_RTS; if (set & TIOCM_CAR) mcr |= MCR_RTS; if (clear & TIOCM_RTS) mcr &= ~MCR_RTS; if (clear & TIOCM_DTR) mcr &= ~MCR_RTS; if (clear & TIOCM_LOOP) mcr &= ~MCR_RTS; if (clear & TIOCM_CTS) mcr &= ~MCR_RTS; if (clear & TIOCM_CAR) mcr &= ~MCR_RTS; if (clear & TIOCM_RI) mcr &= ~MCR_RTS; if (clear & TIOCM_DSR) mcr &= ~MCR_RTS; /* set the new MCR value in the device */ citty->mcr = mcr; F_LEAVE(); return 0; }
static int citty_ioctl_tiocmiwait(struct tty_struct *tty, struct file *file, unsigned int cmd, unsigned long arg) { struct citty_serial *citty = tty->driver_data; F_ENTER(); if (cmd == TIOCMIWAIT) { DECLARE_WAITQUEUE(wait, current); struct async_icount cnow; struct async_icount cprev; cprev = citty->icount; while (1) { add_wait_queue(&citty->wait, &wait); set_current_state(TASK_INTERRUPTIBLE); schedule(); remove_wait_queue(&citty->wait, &wait); /* see if a signal woke us up */ if (signal_pending(current)) return -ERESTARTSYS; cnow = citty->icount; if (cnow.rng == cprev.rng && cnow.dsr == cprev.dsr && cnow.dcd == cprev.dcd && cnow.cts == cprev.cts) return -EIO; /* no change => error */ if (((arg & TIOCM_RNG) && (cnow.rng != cprev.rng)) || ((arg & TIOCM_DSR) && (cnow.dsr != cprev.dsr)) || ((arg & TIOCM_CD) && (cnow.dcd != cprev.dcd)) || ((arg & TIOCM_CTS) && (cnow.cts != cprev.cts)) ) { return 0; } cprev = cnow; } } F_LEAVE(); return -ENOIOCTLCMD; }
int cctdatadev_open(struct inode *inode, struct file *filp) { struct cctdatadev_dev *dev; F_ENTER(); #if 1 dev = container_of(inode->i_cdev, struct cctdatadev_dev, cdev); filp->private_data = dev; /* for other methods */ /* used to keep track of how many readers */ if (filp->f_mode & FMODE_READ) dev->nreaders++; if (filp->f_mode & FMODE_WRITE) dev->nwriters++; #endif F_LEAVE(); return nonseekable_open(inode, filp); /* success */ }
/******************************************************************* * FUNCTION: cctdev_read * * DESCRIPTION: To pass the data from TxBuffer to CI * * RETURNS: utlFAILED or utlSUCCESS * *******************************************************************/ ssize_t cctdev_read(struct file *filp, char __user *buf, size_t count, loff_t *f_pos) { struct cctdev_dev *dev = filp->private_data; ssize_t retval = 0; int minor_num; F_ENTER(); /* Extract Minor Number*/ minor_num = MINOR(dev->cdev.dev); PDEBUG("txCittyBuf[%d].iBufOut: %d, iBufIn: %d\n", minor_num, txCittyBuf[minor_num].iBufOut, txCittyBuf[minor_num].iBufIn); retval = read_citty_buffer( buf, &txCittyBuf[minor_num], COPY_TO_USER); F_LEAVE(); return retval; }
static int citty_tiocmget(struct tty_struct *tty) { struct citty_port *citty = tty->driver_data; unsigned int result = 0; unsigned int msr = citty->msr; unsigned int mcr = citty->mcr; F_ENTER(); result = ((mcr & MCR_DTR) ? TIOCM_DTR : 0) | /* DTR is set */ ((mcr & MCR_RTS) ? TIOCM_RTS : 0) | /* RTS is set */ ((mcr & MCR_LOOP) ? TIOCM_LOOP : 0) | /* LOOP is set */ ((msr & MSR_CTS) ? TIOCM_CTS : 0) | /* CTS is set */ ((msr & MSR_CD) ? TIOCM_CAR : 0) | /* CD is set */ ((msr & MSR_RI) ? TIOCM_RI : 0) | /* RI is set */ ((msr & MSR_DSR) ? TIOCM_DSR : 0); /* DSR is set */ F_LEAVE(); return result; }
static int citty_tiocmget(struct tty_struct *tty, struct file *file) #endif { struct citty_serial *citty = tty->driver_data; unsigned int result = 0; unsigned int msr = citty->msr; unsigned int mcr = citty->mcr; F_ENTER(); result = ((mcr & MCR_DTR) ? TIOCM_DTR : 0) | /* DTR is set */ ((mcr & MCR_RTS) ? TIOCM_RTS : 0) | /* RTS is set */ ((mcr & MCR_LOOP) ? TIOCM_LOOP : 0) | /* LOOP is set */ ((msr & MSR_CTS) ? TIOCM_CTS : 0) | /* CTS is set */ ((msr & MSR_CD) ? TIOCM_CAR : 0) | /* Carrier detect is set*/ ((msr & MSR_RI) ? TIOCM_RI : 0) | /* Ring Indicator is set */ ((msr & MSR_DSR) ? TIOCM_DSR : 0); /* DSR is set */ F_LEAVE(); return result; }
int cctdev_open(struct inode *inode, struct file *filp) { struct cctdev_dev *dev; /* device information */ F_ENTER(); dev = container_of(inode->i_cdev, struct cctdev_dev, cdev); filp->private_data = dev; /* for other methods */ /* used to keep track of how many readers */ mutex_lock(&dev->lock); if (filp->f_mode & FMODE_READ) dev->nreaders++; if (filp->f_mode & FMODE_WRITE) dev->nwriters++; mutex_unlock(&dev->lock); F_LEAVE(); return nonseekable_open(inode, filp); /* success */ }
static int cidatatty_ioctl_tiocgserial(struct tty_struct *tty, struct file *file, unsigned int cmd, unsigned long arg) { struct cidatatty_port *cidatatty = tty->driver_data; F_ENTER(); if (cmd == TIOCGSERIAL) { struct serial_struct tmp; if (!arg) return -EFAULT; memset(&tmp, 0, sizeof(tmp)); tmp.type = cidatatty->serial.type; tmp.line = cidatatty->serial.line; tmp.port = cidatatty->serial.port; tmp.irq = cidatatty->serial.irq; tmp.flags = ASYNC_SKIP_TEST | ASYNC_AUTO_IRQ; tmp.xmit_fifo_size = cidatatty->serial.xmit_fifo_size; tmp.baud_base = cidatatty->serial.baud_base; tmp.close_delay = 5 * HZ; tmp.closing_wait = 30 * HZ; tmp.custom_divisor = cidatatty->serial.custom_divisor; tmp.hub6 = cidatatty->serial.hub6; tmp.io_type = cidatatty->serial.io_type; if (copy_to_user ((void __user *)arg, &tmp, sizeof(struct serial_struct))) return -EFAULT; return 0; } F_LEAVE(); return -ENOIOCTLCMD; }
static int citty_ioctl_tcsets(struct tty_struct *tty, struct file *file, unsigned int cmd, unsigned long arg) { F_ENTER(); memcpy((void *)&tty->termios, (void *)arg, sizeof(struct ktermios)); /* struct termios * new_termios = (struct termios *) arg; tty->termios->c_iflag = new_termios->c_iflag; tty->termios->c_oflag = new_termios->c_oflag; tty->termios->c_cflag = new_termios->c_cflag; tty->termios->c_lflag = new_termios->c_lflag; tty->termios->c_line = new_termios->c_line; int i; for(i = 0; i <NCCS; i++) tty->termios->c_cc[i] = new_termios->c_cc[i]; */ F_LEAVE(); return 0; }
static int citty_read_proc(char *page, char **start, off_t off, int count, int *eof, void *data) { struct citty_serial *citty; off_t begin = 0; int length = 0; int i; F_ENTER(); length += sprintf(page, "cittyserinfo:1.0 driver:%s\n", DRIVER_VERSION); for (i = 0; i < CITTY_TTY_MINORS && length < PAGE_SIZE; ++i) { citty = citty_table[i]; if (citty == NULL) continue; length += sprintf(page + length, "%d\n", i); if ((length + begin) > (off + count)) goto done; if ((length + begin) < off) { begin += length; length = 0; } } *eof = 1; done: if (off >= (length + begin)) return 0; *start = page + (off - begin); F_LEAVE(); return (count < begin + length - off) ? count : begin + length - off; }
static int citty_read_proc(struct file *filp, char __user *buf, size_t count, loff_t *f_pos) { struct citty_port *citty = NULL; int length = 0; int i; char temp[256] = { 0 }; int rc = -EFAULT; F_ENTER(); for (i = 0; i < CITTY_TTY_MINORS; ++i) { citty = citty_table[i]; if (citty == NULL) continue; length += snprintf(temp + length, sizeof(temp) - length, "%d,", i); } if (length > 0) temp[length - 1] = '\0'; if (length + 1 > count) { printk(KERN_ERR "%s: error: no enough space.\n", __func__); goto err_exit; } if (copy_to_user(buf, (void *)&temp, length + 1)) { printk(KERN_ERR "%s: copy_to_user failed.\n", __func__); goto err_exit; } printk(KERN_DEBUG "citty read proc: %s\n", temp); rc = 0; err_exit: F_LEAVE(); return rc; }
static void citty_set_termios(struct tty_struct *tty, struct ktermios *old_termios) { unsigned int cflag; F_ENTER(); cflag = tty->termios.c_cflag; /* check that they really want us to change something */ if (old_termios) { if ((cflag == old_termios->c_cflag) && (RELEVANT_IFLAG(tty->termios.c_iflag) == RELEVANT_IFLAG(old_termios->c_iflag))) { PDEBUG(" - nothing to change...\n"); return; } } /* get the byte size */ switch (cflag & CSIZE) { case CS5: PDEBUG(" - data bits = 5\n"); break; case CS6: PDEBUG(" - data bits = 6\n"); break; case CS7: PDEBUG(" - data bits = 7\n"); break; default: case CS8: PDEBUG(" - data bits = 8\n"); break; } /* determine the parity */ if (cflag & PARENB) if (cflag & PARODD) PDEBUG(" - parity = odd\n"); else PDEBUG(" - parity = even\n"); else PDEBUG(" - parity = none\n"); /* figure out the stop bits requested */ if (cflag & CSTOPB) PDEBUG(" - stop bits = 2\n"); else PDEBUG(" - stop bits = 1\n"); /* figure out the hardware flow control settings */ if (cflag & CRTSCTS) PDEBUG(" - RTS/CTS is enabled\n"); else PDEBUG(" - RTS/CTS is disabled\n"); /* determine software flow control */ /* if we are implementing XON/XOFF, set the start and * stop character in the device */ if (I_IXOFF(tty) || I_IXON(tty)) { /* CHECKPOINT */ /* Invalid code here; * seems software flow control is not supported */ #if 0 unsigned char stop_char = STOP_CHAR(tty); unsigned char start_char = START_CHAR(tty); /* if we are implementing INBOUND XON/XOFF */ if (I_IXOFF(tty)) PDEBUG(" - INBOUND XON/XOFF is enabled, " \ "XON = %2x, XOFF = %2x", start_char, stop_char); else PDEBUG(" - INBOUND XON/XOFF is disabled"); /* if we are implementing OUTBOUND XON/XOFF */ if (I_IXON(tty)) PDEBUG(" - OUTBOUND XON/XOFF is enabled, " \ "XON = %2x, XOFF = %2x", start_char, stop_char); else PDEBUG(" - OUTBOUND XON/XOFF is disabled"); #endif } /* get the baud rate wanted */ PDEBUG(" - baud rate = %d", tty_get_baud_rate(tty)); F_LEAVE(); }