is->maxcid = 16; /* VJ: maxcid */
is->tk = current;
init_waitqueue_head(&is->wq);
- is->first = is->rq + NUM_RCV_BUFFS - 1; /* receive queue */
- is->last = is->rq;
is->minor = minor;
#ifdef CONFIG_ISDN_PPP_VJ
/*
isdn_ppp_release(struct inode *ino, struct file *file)
{
uint minor = minor(ino->i_rdev) - ISDN_MINOR_PPP;
- int i;
struct ippp_struct *is;
lock_kernel();
is->state &= ~IPPP_CONNECT;
isdn_net_hangup(is->idev);
}
- for (i = 0; i < NUM_RCV_BUFFS; i++) {
- if (is->rq[i].buf) {
- kfree(is->rq[i].buf);
- is->rq[i].buf = NULL;
- }
- }
- is->first = is->rq + NUM_RCV_BUFFS - 1; /* receive queue */
- is->last = is->rq;
+ skb_queue_purge(&is->rq);
#ifdef CONFIG_ISDN_PPP_VJ
/* TODO: if this was the previous master: link the slcomp to the new master */
isdn_ppp_poll(struct file *file, poll_table * wait)
{
unsigned int mask;
- struct ippp_buf_queue *bf;
- struct ippp_buf_queue *bl;
unsigned long flags;
struct ippp_struct *is;
- lock_kernel();
is = file->private_data;
if (is->debug & 0x2)
/* we're always ready to send .. */
mask = POLLOUT | POLLWRNORM;
- save_flags(flags);
- cli();
- bl = is->last;
- bf = is->first;
/*
* if IPPP_NOBLOCK is set we return even if we have nothing to read
*/
- if (bf->next != bl || (is->state & IPPP_NOBLOCK)) {
+ if (!skb_queue_empty(&is->rq) || is->state & IPPP_NOBLOCK) {
is->state &= ~IPPP_NOBLOCK;
mask |= POLLIN | POLLRDNORM;
}
- restore_flags(flags);
out:
- unlock_kernel();
return mask;
}
static int
isdn_ppp_fill_rq(unsigned char *buf, int len, int proto, int slot)
{
- struct ippp_buf_queue *bf,
- *bl;
- unsigned long flags;
- unsigned char *nbuf;
+ struct sk_buff *skb;
+ unsigned char *p;
struct ippp_struct *is;
if (slot < 0 || slot >= ISDN_MAX_CHANNELS) {
printk(KERN_DEBUG "ippp: device not activated.\n");
return 0;
}
- nbuf = (unsigned char *) kmalloc(len + 4, GFP_ATOMIC);
- if (!nbuf) {
- printk(KERN_WARNING "ippp: Can't alloc buf\n");
+ if (skb_queue_len(&is->rq) > IPPP_MAX_RQ_LEN) {
+ printk(KERN_WARNING "ippp: Queue is full\n");
return 0;
}
- nbuf[0] = PPP_ALLSTATIONS;
- nbuf[1] = PPP_UI;
- nbuf[2] = proto >> 8;
- nbuf[3] = proto & 0xff;
- memcpy(nbuf + 4, buf, len);
-
- save_flags(flags);
- cli();
-
- bf = is->first;
- bl = is->last;
-
- if (bf == bl) {
- printk(KERN_WARNING "ippp: Queue is full; discarding first buffer\n");
- bf = bf->next;
- kfree(bf->buf);
- is->first = bf;
+ skb = dev_alloc_skb(len + 4);
+ if (!skb) {
+ printk(KERN_WARNING "ippp: Can't alloc buf\n");
+ return 0;
}
- bl->buf = (char *) nbuf;
- bl->len = len + 4;
-
- is->last = bl->next;
- restore_flags(flags);
+ p = skb_put(skb, 4);
+ p += put_u8(p, PPP_ALLSTATIONS);
+ p += put_u8(p, PPP_UI);
+ p += put_u16(p, proto);
+ memcpy(skb_put(skb, len), buf, len);
- wake_up_interruptible(&is->wq);
+ skb_queue_tail(&is->rq, skb);
+ wake_up_interruptible(&is->wq);
return len;
}
isdn_ppp_read(struct file *file, char *buf, size_t count, loff_t *off)
{
struct ippp_struct *is;
- struct ippp_buf_queue *b;
- unsigned long flags;
- unsigned char *save_buf;
+ struct sk_buff *skb;
int retval;
if (off != &file->f_pos)
return -ESPIPE;
- lock_kernel();
-
is = file->private_data;
if (!(is->state & IPPP_OPEN)) {
retval = 0;
goto out;
}
- retval = verify_area(VERIFY_WRITE, (void *) buf, count);
- if (retval)
- goto out;
-
- save_flags(flags);
- cli();
-
- b = is->first->next;
- save_buf = b->buf;
- if (!save_buf) {
- restore_flags(flags);
+ skb = skb_dequeue(&is->rq);
+ if (!skb) {
retval = -EAGAIN;
goto out;
}
- if (b->len < count)
- count = b->len;
- b->buf = NULL;
- is->first = b;
-
- restore_flags(flags);
-
- if (copy_to_user(buf, save_buf, count)) {
- kfree(save_buf);
+ if (skb->len > count) {
+ retval = -EMSGSIZE;
+ goto out_free;
+ }
+ if (copy_to_user(buf, skb->data, skb->len)) {
retval = -EFAULT;
- goto out;
+ goto out_free;
}
- kfree(save_buf);
-
- retval = count;
+ retval = skb->len;
+ out_free:
+ dev_kfree_skb(skb);
out:
- unlock_kernel();
return retval;
}
}
memset((char *) ippp_table[i], 0, sizeof(struct ippp_struct));
ippp_table[i]->state = 0;
- ippp_table[i]->first = ippp_table[i]->rq + NUM_RCV_BUFFS - 1;
- ippp_table[i]->last = ippp_table[i]->rq;
-
- for (j = 0; j < NUM_RCV_BUFFS; j++) {
- ippp_table[i]->rq[j].buf = NULL;
- ippp_table[i]->rq[j].last = ippp_table[i]->rq +
- (NUM_RCV_BUFFS + j - 1) % NUM_RCV_BUFFS;
- ippp_table[i]->rq[j].next = ippp_table[i]->rq + (j + 1) % NUM_RCV_BUFFS;
- }
+ skb_queue_head_init(&ippp_table[i]->rq);
}
return 0;
}