*/
timeout = jiffies+HZ;
while(port->IER & IER_TXEMPTY) {
- msleep_interruptible(jiffies_to_msecs(port->timeout));
+ current->state = TASK_INTERRUPTIBLE;
+ schedule_timeout(port->timeout);
if (time_after(jiffies, timeout)) {
printk (KERN_INFO "Timeout waiting for close\n");
break;
port->tty = NULL;
if (port->blocked_open) {
if (port->close_delay) {
- msleep_interruptible(jiffies_to_msecs(port->close_delay));
+ current->state = TASK_INTERRUPTIBLE;
+ schedule_timeout(port->close_delay);
}
wake_up_interruptible(&port->open_wait);
}
}
-static int sx_write(struct tty_struct * tty,
+static int sx_write(struct tty_struct * tty, int from_user,
const unsigned char *buf, int count)
{
struct specialix_port *port = (struct specialix_port *)tty->driver_data;
return 0;
save_flags(flags);
- while (1) {
- cli();
- c = min_t(int, count, min(SERIAL_XMIT_SIZE - port->xmit_cnt - 1,
- SERIAL_XMIT_SIZE - port->xmit_head));
- if (c <= 0) {
+ if (from_user) {
+ down(&tmp_buf_sem);
+ while (1) {
+ c = min_t(int, count, min(SERIAL_XMIT_SIZE - port->xmit_cnt - 1,
+ SERIAL_XMIT_SIZE - port->xmit_head));
+ if (c <= 0)
+ break;
+
+ c -= copy_from_user(tmp_buf, buf, c);
+ if (!c) {
+ if (!total)
+ total = -EFAULT;
+ break;
+ }
+
+ cli();
+ c = min_t(int, c, min(SERIAL_XMIT_SIZE - port->xmit_cnt - 1,
+ SERIAL_XMIT_SIZE - port->xmit_head));
+ memcpy(port->xmit_buf + port->xmit_head, tmp_buf, c);
+ port->xmit_head = (port->xmit_head + c) & (SERIAL_XMIT_SIZE-1);
+ port->xmit_cnt += c;
restore_flags(flags);
- break;
+
+ buf += c;
+ count -= c;
+ total += c;
}
- memcpy(port->xmit_buf + port->xmit_head, buf, c);
- port->xmit_head = (port->xmit_head + c) & (SERIAL_XMIT_SIZE-1);
- port->xmit_cnt += c;
- restore_flags(flags);
+ up(&tmp_buf_sem);
+ } else {
+ while (1) {
+ cli();
+ c = min_t(int, count, min(SERIAL_XMIT_SIZE - port->xmit_cnt - 1,
+ SERIAL_XMIT_SIZE - port->xmit_head));
+ if (c <= 0) {
+ restore_flags(flags);
+ break;
+ }
+ memcpy(port->xmit_buf + port->xmit_head, buf, c);
+ port->xmit_head = (port->xmit_head + c) & (SERIAL_XMIT_SIZE-1);
+ port->xmit_cnt += c;
+ restore_flags(flags);
- buf += c;
- count -= c;
- total += c;
+ buf += c;
+ count -= c;
+ total += c;
+ }
}
cli();
int irq [SX_NBOARD] = {0,};
-module_param_array(iobase, int, NULL, 0);
-module_param_array(irq, int, NULL, 0);
+MODULE_PARM(iobase,"1-" __MODULE_STRING(SX_NBOARD) "i");
+MODULE_PARM(irq,"1-" __MODULE_STRING(SX_NBOARD) "i");
/*
* You can setup up to 4 boards.