*
********************************************************************/
-#include <linux/config.h>
#include <linux/init.h>
#include <linux/module.h>
#include <linux/fs.h>
static int ircomm_tty_open(struct tty_struct *tty, struct file *filp);
static void ircomm_tty_close(struct tty_struct * tty, struct file *filp);
-static int ircomm_tty_write(struct tty_struct * tty, int from_user,
+static int ircomm_tty_write(struct tty_struct * tty,
const unsigned char *buf, int count);
static int ircomm_tty_write_room(struct tty_struct *tty);
static void ircomm_tty_throttle(struct tty_struct *tty);
static void ircomm_tty_send_xchar(struct tty_struct *tty, char ch);
static void ircomm_tty_wait_until_sent(struct tty_struct *tty, int timeout);
static void ircomm_tty_hangup(struct tty_struct *tty);
-static void ircomm_tty_do_softint(void *private_);
+static void ircomm_tty_do_softint(struct work_struct *work);
static void ircomm_tty_shutdown(struct ircomm_tty_cb *self);
+static void ircomm_tty_stop(struct tty_struct *tty);
static int ircomm_tty_data_indication(void *instance, void *sap,
struct sk_buff *skb);
hashbin_t *ircomm_tty = NULL;
-static struct tty_operations ops = {
+static const struct tty_operations ops = {
.open = ircomm_tty_open,
.close = ircomm_tty_close,
.write = ircomm_tty_write,
* Init IrCOMM TTY layer/driver
*
*/
-int __init ircomm_tty_init(void)
+static int __init ircomm_tty_init(void)
{
driver = alloc_tty_driver(IRCOMM_TTY_PORTS);
if (!driver)
return -ENOMEM;
ircomm_tty = hashbin_new(HB_LOCK);
if (ircomm_tty == NULL) {
- ERROR("%s(), can't allocate hashbin!\n", __FUNCTION__);
+ IRDA_ERROR("%s(), can't allocate hashbin!\n", __FUNCTION__);
put_tty_driver(driver);
return -ENOMEM;
}
driver->owner = THIS_MODULE;
driver->driver_name = "ircomm";
driver->name = "ircomm";
- driver->devfs_name = "ircomm";
driver->major = IRCOMM_TTY_MAJOR;
driver->minor_start = IRCOMM_TTY_MINOR;
driver->type = TTY_DRIVER_TYPE_SERIAL;
driver->flags = TTY_DRIVER_REAL_RAW;
tty_set_operations(driver, &ops);
if (tty_register_driver(driver)) {
- ERROR("%s(): Couldn't register serial driver\n", __FUNCTION__);
+ IRDA_ERROR("%s(): Couldn't register serial driver\n",
+ __FUNCTION__);
put_tty_driver(driver);
return -1;
}
{
IRDA_DEBUG(0, "%s()\n", __FUNCTION__ );
- ASSERT(self != NULL, return;);
- ASSERT(self->magic == IRCOMM_TTY_MAGIC, return;);
+ IRDA_ASSERT(self != NULL, return;);
+ IRDA_ASSERT(self->magic == IRCOMM_TTY_MAGIC, return;);
ircomm_tty_shutdown(self);
* Remove IrCOMM TTY layer/driver
*
*/
-void __exit ircomm_tty_cleanup(void)
+static void __exit ircomm_tty_cleanup(void)
{
int ret;
ret = tty_unregister_driver(driver);
if (ret) {
- ERROR("%s(), failed to unregister driver\n", __FUNCTION__);
+ IRDA_ERROR("%s(), failed to unregister driver\n",
+ __FUNCTION__);
return;
}
IRDA_DEBUG(2, "%s()\n", __FUNCTION__ );
- ASSERT(self != NULL, return -1;);
- ASSERT(self->magic == IRCOMM_TTY_MAGIC, return -1;);
+ IRDA_ASSERT(self != NULL, return -1;);
+ IRDA_ASSERT(self->magic == IRCOMM_TTY_MAGIC, return -1;);
/* Check if already open */
if (test_and_set_bit(ASYNC_B_INITIALIZED, &self->flags)) {
/* Connect IrCOMM link with remote device */
ret = ircomm_tty_attach_cable(self);
if (ret < 0) {
- ERROR("%s(), error attaching cable!\n", __FUNCTION__);
+ IRDA_ERROR("%s(), error attaching cable!\n", __FUNCTION__);
goto err;
}
self = hashbin_lock_find(ircomm_tty, line, NULL);
if (!self) {
/* No, so make new instance */
- self = kmalloc(sizeof(struct ircomm_tty_cb), GFP_KERNEL);
+ self = kzalloc(sizeof(struct ircomm_tty_cb), GFP_KERNEL);
if (self == NULL) {
- ERROR("%s(), kmalloc failed!\n", __FUNCTION__);
+ IRDA_ERROR("%s(), kmalloc failed!\n", __FUNCTION__);
return -ENOMEM;
}
- memset(self, 0, sizeof(struct ircomm_tty_cb));
self->magic = IRCOMM_TTY_MAGIC;
self->flow = FLOW_STOP;
self->line = line;
- INIT_WORK(&self->tqueue, ircomm_tty_do_softint, self);
+ INIT_WORK(&self->tqueue, ircomm_tty_do_softint);
self->max_header_size = IRCOMM_TTY_HDR_UNINITIALISED;
self->max_data_size = IRCOMM_TTY_DATA_UNINITIALISED;
self->close_delay = 5*HZ/10;
*/
if (wait_event_interruptible(self->close_wait, !test_bit(ASYNC_B_CLOSING, &self->flags))) {
- WARNING("%s - got signal while blocking on ASYNC_CLOSING!\n",
- __FUNCTION__);
+ IRDA_WARNING("%s - got signal while blocking on ASYNC_CLOSING!\n",
+ __FUNCTION__);
return -ERESTARTSYS;
}
if (!tty)
return;
- ASSERT(self != NULL, return;);
- ASSERT(self->magic == IRCOMM_TTY_MAGIC, return;);
+ IRDA_ASSERT(self != NULL, return;);
+ IRDA_ASSERT(self->magic == IRCOMM_TTY_MAGIC, return;);
spin_lock_irqsave(&self->spinlock, flags);
}
if (--self->open_count < 0) {
- ERROR("%s(), bad serial port count for ttys%d: %d\n",
- __FUNCTION__, self->line, self->open_count);
+ IRDA_ERROR("%s(), bad serial port count for ttys%d: %d\n",
+ __FUNCTION__, self->line, self->open_count);
self->open_count = 0;
}
if (self->open_count) {
self->tty = NULL;
if (self->blocked_open) {
- if (self->close_delay) {
- current->state = TASK_INTERRUPTIBLE;
- schedule_timeout(self->close_delay);
- }
+ if (self->close_delay)
+ schedule_timeout_interruptible(self->close_delay);
wake_up_interruptible(&self->open_wait);
}
{
struct ircomm_tty_cb *self = (struct ircomm_tty_cb *) tty->driver_data;
- ASSERT(self != NULL, return;);
- ASSERT(self->magic == IRCOMM_TTY_MAGIC, return;);
+ IRDA_ASSERT(self != NULL, return;);
+ IRDA_ASSERT(self->magic == IRCOMM_TTY_MAGIC, return;);
/*
* Let do_softint() do this to avoid race condition with
}
/*
- * Function ircomm_tty_do_softint (private_)
+ * Function ircomm_tty_do_softint (work)
*
* We use this routine to give the write wakeup to the user at at a
* safe time (as fast as possible after write have completed). This
* can be compared to the Tx interrupt.
*/
-static void ircomm_tty_do_softint(void *private_)
+static void ircomm_tty_do_softint(struct work_struct *work)
{
- struct ircomm_tty_cb *self = (struct ircomm_tty_cb *) private_;
+ struct ircomm_tty_cb *self =
+ container_of(work, struct ircomm_tty_cb, tqueue);
struct tty_struct *tty;
unsigned long flags;
struct sk_buff *skb, *ctrl_skb;
}
/*
- * Function ircomm_tty_write (tty, from_user, buf, count)
+ * Function ircomm_tty_write (tty, buf, count)
*
* This routine is called by the kernel to write a series of characters
* to the tty device. The characters may come from user space or kernel
* space. This routine will return the number of characters actually
* accepted for writing. This routine is mandatory.
*/
-static int ircomm_tty_write(struct tty_struct *tty, int from_user,
- const unsigned char *ubuf, int count)
+static int ircomm_tty_write(struct tty_struct *tty,
+ const unsigned char *buf, int count)
{
struct ircomm_tty_cb *self = (struct ircomm_tty_cb *) tty->driver_data;
- unsigned char *kbuf; /* Buffer in kernel space */
unsigned long flags;
struct sk_buff *skb;
int tailroom = 0;
IRDA_DEBUG(2, "%s(), count=%d, hw_stopped=%d\n", __FUNCTION__ , count,
tty->hw_stopped);
- ASSERT(self != NULL, return -1;);
- ASSERT(self->magic == IRCOMM_TTY_MAGIC, return -1;);
+ IRDA_ASSERT(self != NULL, return -1;);
+ IRDA_ASSERT(self->magic == IRCOMM_TTY_MAGIC, return -1;);
/* We may receive packets from the TTY even before we have finished
* our setup. Not cool.
if (count < 1)
return 0;
- /* Additional copy to avoid copy_from_user() under spinlock.
- * We tradeoff this extra copy to allow to pack more the
- * IrCOMM frames. This is advantageous because the IrDA link
- * is the bottleneck. */
- if (from_user) {
- kbuf = kmalloc(count, GFP_KERNEL);
- if (kbuf == NULL)
- return -ENOMEM;
- if (copy_from_user(kbuf, ubuf, count)) {
- kfree(kbuf);
- return -EFAULT;
- }
- } else
- /* The buffer is already in kernel space */
- kbuf = (unsigned char *) ubuf;
-
/* Protect our manipulation of self->tx_skb and related */
spin_lock_irqsave(&self->spinlock, flags);
}
} else {
/* Prepare a full sized frame */
- skb = dev_alloc_skb(self->max_data_size+
- self->max_header_size);
+ skb = alloc_skb(self->max_data_size+
+ self->max_header_size,
+ GFP_ATOMIC);
if (!skb) {
spin_unlock_irqrestore(&self->spinlock, flags);
- if (from_user)
- kfree(kbuf);
return -ENOBUFS;
}
skb_reserve(skb, self->max_header_size);
}
/* Copy data */
- memcpy(skb_put(skb,size), kbuf + len, size);
+ memcpy(skb_put(skb,size), buf + len, size);
count -= size;
len += size;
spin_unlock_irqrestore(&self->spinlock, flags);
- if (from_user)
- kfree(kbuf);
-
/*
* Schedule a new thread which will transmit the frame as soon
* as possible, but at a safe point in time. We do this so the
unsigned long flags;
int ret;
- ASSERT(self != NULL, return -1;);
- ASSERT(self->magic == IRCOMM_TTY_MAGIC, return -1;);
+ IRDA_ASSERT(self != NULL, return -1;);
+ IRDA_ASSERT(self->magic == IRCOMM_TTY_MAGIC, return -1;);
#ifdef IRCOMM_NO_TX_BEFORE_INIT
/* max_header_size tells us if the channel is initialised or not. */
IRDA_DEBUG(2, "%s()\n", __FUNCTION__ );
- ASSERT(self != NULL, return;);
- ASSERT(self->magic == IRCOMM_TTY_MAGIC, return;);
+ IRDA_ASSERT(self != NULL, return;);
+ IRDA_ASSERT(self->magic == IRCOMM_TTY_MAGIC, return;);
orig_jiffies = jiffies;
spin_lock_irqsave(&self->spinlock, flags);
while (self->tx_skb && self->tx_skb->len) {
spin_unlock_irqrestore(&self->spinlock, flags);
- current->state = TASK_INTERRUPTIBLE;
- schedule_timeout(poll_time);
+ schedule_timeout_interruptible(poll_time);
spin_lock_irqsave(&self->spinlock, flags);
if (signal_pending(current))
break;
IRDA_DEBUG(2, "%s()\n", __FUNCTION__ );
- ASSERT(self != NULL, return;);
- ASSERT(self->magic == IRCOMM_TTY_MAGIC, return;);
+ IRDA_ASSERT(self != NULL, return;);
+ IRDA_ASSERT(self->magic == IRCOMM_TTY_MAGIC, return;);
/* Software flow control? */
if (I_IXOFF(tty))
IRDA_DEBUG(2, "%s()\n", __FUNCTION__ );
- ASSERT(self != NULL, return;);
- ASSERT(self->magic == IRCOMM_TTY_MAGIC, return;);
+ IRDA_ASSERT(self != NULL, return;);
+ IRDA_ASSERT(self->magic == IRCOMM_TTY_MAGIC, return;);
/* Using software flow control? */
if (I_IXOFF(tty)) {
unsigned long flags;
int len = 0;
- ASSERT(self != NULL, return -1;);
- ASSERT(self->magic == IRCOMM_TTY_MAGIC, return -1;);
+ IRDA_ASSERT(self != NULL, return -1;);
+ IRDA_ASSERT(self->magic == IRCOMM_TTY_MAGIC, return -1;);
spin_lock_irqsave(&self->spinlock, flags);
{
unsigned long flags;
- ASSERT(self != NULL, return;);
- ASSERT(self->magic == IRCOMM_TTY_MAGIC, return;);
+ IRDA_ASSERT(self != NULL, return;);
+ IRDA_ASSERT(self->magic == IRCOMM_TTY_MAGIC, return;);
IRDA_DEBUG(0, "%s()\n", __FUNCTION__ );
IRDA_DEBUG(0, "%s()\n", __FUNCTION__ );
- ASSERT(self != NULL, return;);
- ASSERT(self->magic == IRCOMM_TTY_MAGIC, return;);
+ IRDA_ASSERT(self != NULL, return;);
+ IRDA_ASSERT(self->magic == IRCOMM_TTY_MAGIC, return;);
if (!tty)
return;
* This routine notifies the tty driver that it should stop outputting
* characters to the tty device.
*/
-void ircomm_tty_stop(struct tty_struct *tty)
+static void ircomm_tty_stop(struct tty_struct *tty)
{
struct ircomm_tty_cb *self = (struct ircomm_tty_cb *) tty->driver_data;
- ASSERT(self != NULL, return;);
- ASSERT(self->magic == IRCOMM_TTY_MAGIC, return;);
+ IRDA_ASSERT(self != NULL, return;);
+ IRDA_ASSERT(self->magic == IRCOMM_TTY_MAGIC, return;);
ircomm_flow_request(self->ircomm, FLOW_STOP);
}
IRDA_DEBUG(0, "%s()\n", __FUNCTION__ );
- ASSERT(self != NULL, return;);
- ASSERT(self->magic == IRCOMM_TTY_MAGIC, return;);
+ IRDA_ASSERT(self != NULL, return;);
+ IRDA_ASSERT(self->magic == IRCOMM_TTY_MAGIC, return;);
tty = self->tty;
IRDA_DEBUG(2, "%s()\n", __FUNCTION__ );
- ASSERT(self != NULL, return -1;);
- ASSERT(self->magic == IRCOMM_TTY_MAGIC, return -1;);
- ASSERT(skb != NULL, return -1;);
+ IRDA_ASSERT(self != NULL, return -1;);
+ IRDA_ASSERT(self->magic == IRCOMM_TTY_MAGIC, return -1;);
+ IRDA_ASSERT(skb != NULL, return -1;);
if (!self->tty) {
IRDA_DEBUG(0, "%s(), no tty!\n", __FUNCTION__ );
IRDA_DEBUG(4, "%s()\n", __FUNCTION__ );
- ASSERT(self != NULL, return -1;);
- ASSERT(self->magic == IRCOMM_TTY_MAGIC, return -1;);
- ASSERT(skb != NULL, return -1;);
+ IRDA_ASSERT(self != NULL, return -1;);
+ IRDA_ASSERT(self->magic == IRCOMM_TTY_MAGIC, return -1;);
+ IRDA_ASSERT(skb != NULL, return -1;);
clen = skb->data[0];
struct ircomm_tty_cb *self = (struct ircomm_tty_cb *) instance;
struct tty_struct *tty;
- ASSERT(self != NULL, return;);
- ASSERT(self->magic == IRCOMM_TTY_MAGIC, return;);
+ IRDA_ASSERT(self != NULL, return;);
+ IRDA_ASSERT(self->magic == IRCOMM_TTY_MAGIC, return;);
tty = self->tty;