Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 184222
b: refs/heads/master
c: 05b4149
h: refs/heads/master
v: v3
  • Loading branch information
Jan Kiszka authored and David S. Miller committed Feb 17, 2010
1 parent cdc73fb commit dac7907
Show file tree
Hide file tree
Showing 2 changed files with 89 additions and 94 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: eca39dd830dbc58061aa6cd68853c39055236be3
refs/heads/master: 05b4149433ffae789edaf569da8d998c93eed1aa
181 changes: 88 additions & 93 deletions trunk/drivers/isdn/capi/capi.c
Original file line number Diff line number Diff line change
Expand Up @@ -141,7 +141,7 @@ struct capidev {

struct capincci *nccis;

struct mutex ncci_list_mtx;
struct mutex lock;
};

/* -------- global variables ---------------------------------------- */
Expand Down Expand Up @@ -574,38 +574,31 @@ static void capi_recv_message(struct capi20_appl *ap, struct sk_buff *skb)
u16 datahandle;
#endif /* CONFIG_ISDN_CAPI_MIDDLEWARE */
struct capincci *np;
u32 ncci;
unsigned long flags;

mutex_lock(&cdev->lock);

if (CAPIMSG_CMD(skb->data) == CAPI_CONNECT_B3_CONF) {
u16 info = CAPIMSG_U16(skb->data, 12); // Info field
if ((info & 0xff00) == 0) {
mutex_lock(&cdev->ncci_list_mtx);
if ((info & 0xff00) == 0)
capincci_alloc(cdev, CAPIMSG_NCCI(skb->data));
mutex_unlock(&cdev->ncci_list_mtx);
}
}
if (CAPIMSG_CMD(skb->data) == CAPI_CONNECT_B3_IND) {
mutex_lock(&cdev->ncci_list_mtx);
if (CAPIMSG_CMD(skb->data) == CAPI_CONNECT_B3_IND)
capincci_alloc(cdev, CAPIMSG_NCCI(skb->data));
mutex_unlock(&cdev->ncci_list_mtx);
}

spin_lock_irqsave(&workaround_lock, flags);
if (CAPIMSG_COMMAND(skb->data) != CAPI_DATA_B3) {
skb_queue_tail(&cdev->recvqueue, skb);
wake_up_interruptible(&cdev->recvwait);
spin_unlock_irqrestore(&workaround_lock, flags);
return;
goto unlock_out;
}
ncci = CAPIMSG_CONTROL(skb->data);
for (np = cdev->nccis; np && np->ncci != ncci; np = np->next)
;

np = capincci_find(cdev, CAPIMSG_CONTROL(skb->data));
if (!np) {
printk(KERN_ERR "BUG: capi_signal: ncci not found\n");
skb_queue_tail(&cdev->recvqueue, skb);
wake_up_interruptible(&cdev->recvwait);
spin_unlock_irqrestore(&workaround_lock, flags);
return;
goto unlock_out;
}

#ifndef CONFIG_ISDN_CAPI_MIDDLEWARE
Expand All @@ -618,8 +611,7 @@ static void capi_recv_message(struct capi20_appl *ap, struct sk_buff *skb)
if (!mp) {
skb_queue_tail(&cdev->recvqueue, skb);
wake_up_interruptible(&cdev->recvwait);
spin_unlock_irqrestore(&workaround_lock, flags);
return;
goto unlock_out;
}
if (CAPIMSG_SUBCOMMAND(skb->data) == CAPI_IND) {
datahandle = CAPIMSG_U16(skb->data, CAPIMSG_BASELEN+4+4+2);
Expand Down Expand Up @@ -652,7 +644,9 @@ static void capi_recv_message(struct capi20_appl *ap, struct sk_buff *skb)
}
#endif /* CONFIG_ISDN_CAPI_MIDDLEWARE */

unlock_out:
spin_unlock_irqrestore(&workaround_lock, flags);
mutex_unlock(&cdev->lock);
}

/* -------- file_operations for capidev ----------------------------- */
Expand Down Expand Up @@ -730,9 +724,9 @@ capi_write(struct file *file, const char __user *buf, size_t count, loff_t *ppos
CAPIMSG_SETAPPID(skb->data, cdev->ap.applid);

if (CAPIMSG_CMD(skb->data) == CAPI_DISCONNECT_B3_RESP) {
mutex_lock(&cdev->ncci_list_mtx);
mutex_lock(&cdev->lock);
capincci_free(cdev, CAPIMSG_NCCI(skb->data));
mutex_unlock(&cdev->ncci_list_mtx);
mutex_unlock(&cdev->lock);
}

cdev->errcode = capi20_put_message(&cdev->ap, skb);
Expand Down Expand Up @@ -765,30 +759,35 @@ capi_ioctl(struct inode *inode, struct file *file,
unsigned int cmd, unsigned long arg)
{
struct capidev *cdev = file->private_data;
struct capi20_appl *ap = &cdev->ap;
capi_ioctl_struct data;
int retval = -EINVAL;
void __user *argp = (void __user *)arg;

switch (cmd) {
case CAPI_REGISTER:
{
if (ap->applid)
return -EEXIST;
mutex_lock(&cdev->lock);

if (copy_from_user(&cdev->ap.rparam, argp,
sizeof(struct capi_register_params)))
return -EFAULT;

cdev->ap.private = cdev;
cdev->ap.recv_message = capi_recv_message;
cdev->errcode = capi20_register(ap);
if (cdev->errcode) {
ap->applid = 0;
return -EIO;
}
if (cdev->ap.applid) {
retval = -EEXIST;
goto register_out;
}
if (copy_from_user(&cdev->ap.rparam, argp,
sizeof(struct capi_register_params))) {
retval = -EFAULT;
goto register_out;
}
cdev->ap.private = cdev;
cdev->ap.recv_message = capi_recv_message;
cdev->errcode = capi20_register(&cdev->ap);
retval = (int)cdev->ap.applid;
if (cdev->errcode) {
cdev->ap.applid = 0;
retval = -EIO;
}
return (int)ap->applid;

register_out:
mutex_unlock(&cdev->lock);
return retval;

case CAPI_GET_VERSION:
{
Expand Down Expand Up @@ -887,68 +886,67 @@ capi_ioctl(struct inode *inode, struct file *file,
return 0;

case CAPI_SET_FLAGS:
case CAPI_CLR_FLAGS:
{
unsigned userflags;
if (copy_from_user(&userflags, argp,
sizeof(userflags)))
return -EFAULT;
if (cmd == CAPI_SET_FLAGS)
cdev->userflags |= userflags;
else
cdev->userflags &= ~userflags;
}
return 0;
case CAPI_CLR_FLAGS: {
unsigned userflags;

if (copy_from_user(&userflags, argp, sizeof(userflags)))
return -EFAULT;

mutex_lock(&cdev->lock);
if (cmd == CAPI_SET_FLAGS)
cdev->userflags |= userflags;
else
cdev->userflags &= ~userflags;
mutex_unlock(&cdev->lock);
return 0;
}
case CAPI_GET_FLAGS:
if (copy_to_user(argp, &cdev->userflags,
sizeof(cdev->userflags)))
return -EFAULT;
return 0;

case CAPI_NCCI_OPENCOUNT:
{
struct capincci *nccip;
unsigned ncci;
int count = 0;
if (copy_from_user(&ncci, argp, sizeof(ncci)))
return -EFAULT;
case CAPI_NCCI_OPENCOUNT: {
struct capincci *nccip;
unsigned ncci;
int count = 0;

mutex_lock(&cdev->ncci_list_mtx);
if ((nccip = capincci_find(cdev, (u32) ncci)) == NULL) {
mutex_unlock(&cdev->ncci_list_mtx);
return 0;
}
count += capincci_minor_opencount(nccip);
mutex_unlock(&cdev->ncci_list_mtx);
return count;
}
return 0;
if (copy_from_user(&ncci, argp, sizeof(ncci)))
return -EFAULT;

mutex_lock(&cdev->lock);
nccip = capincci_find(cdev, (u32)ncci);
if (nccip)
count = capincci_minor_opencount(nccip);
mutex_unlock(&cdev->lock);
return count;
}

#ifdef CONFIG_ISDN_CAPI_MIDDLEWARE
case CAPI_NCCI_GETUNIT:
{
struct capincci *nccip;
struct capiminor *mp;
unsigned ncci;
int unit = 0;
if (copy_from_user(&ncci, argp,
sizeof(ncci)))
return -EFAULT;
mutex_lock(&cdev->ncci_list_mtx);
nccip = capincci_find(cdev, (u32) ncci);
if (!nccip || (mp = nccip->minorp) == NULL) {
mutex_unlock(&cdev->ncci_list_mtx);
return -ESRCH;
}
unit = mp->minor;
mutex_unlock(&cdev->ncci_list_mtx);
return unit;
case CAPI_NCCI_GETUNIT: {
struct capincci *nccip;
struct capiminor *mp;
unsigned ncci;
int unit = -ESRCH;

if (copy_from_user(&ncci, argp, sizeof(ncci)))
return -EFAULT;

mutex_lock(&cdev->lock);
nccip = capincci_find(cdev, (u32)ncci);
if (nccip) {
mp = nccip->minorp;
if (mp)
unit = mp->minor;
}
return 0;
mutex_unlock(&cdev->lock);
return unit;
}
#endif /* CONFIG_ISDN_CAPI_MIDDLEWARE */

default:
return -EINVAL;
}
return -EINVAL;
}

static int capi_open(struct inode *inode, struct file *file)
Expand All @@ -959,7 +957,7 @@ static int capi_open(struct inode *inode, struct file *file)
if (!cdev)
return -ENOMEM;

mutex_init(&cdev->ncci_list_mtx);
mutex_init(&cdev->lock);
skb_queue_head_init(&cdev->recvqueue);
init_waitqueue_head(&cdev->recvwait);
file->private_data = cdev;
Expand All @@ -979,15 +977,10 @@ static int capi_release(struct inode *inode, struct file *file)
list_del(&cdev->list);
mutex_unlock(&capidev_list_lock);

if (cdev->ap.applid) {
if (cdev->ap.applid)
capi20_release(&cdev->ap);
cdev->ap.applid = 0;
}
skb_queue_purge(&cdev->recvqueue);

mutex_lock(&cdev->ncci_list_mtx);
capincci_free(cdev, 0xffffffff);
mutex_unlock(&cdev->ncci_list_mtx);

kfree(cdev);
return 0;
Expand Down Expand Up @@ -1446,11 +1439,13 @@ static int capi20ncci_proc_show(struct seq_file *m, void *v)
mutex_lock(&capidev_list_lock);
list_for_each(l, &capidev_list) {
cdev = list_entry(l, struct capidev, list);
mutex_lock(&cdev->lock);
for (np=cdev->nccis; np; np = np->next) {
seq_printf(m, "%d 0x%x\n",
cdev->ap.applid,
np->ncci);
}
mutex_unlock(&cdev->lock);
}
mutex_unlock(&capidev_list_lock);
return 0;
Expand Down

0 comments on commit dac7907

Please sign in to comment.