Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/shaggy...
[pandora-kernel.git] / drivers / isdn / i4l / isdn_common.c
index 81accdf..6a2ef0a 100644 (file)
@@ -11,7 +11,6 @@
  *
  */
 
-#include <linux/config.h>
 #include <linux/module.h>
 #include <linux/init.h>
 #include <linux/poll.h>
@@ -340,6 +339,16 @@ isdn_command(isdn_ctrl *cmd)
                printk(KERN_WARNING "isdn_command command(%x) driver -1\n", cmd->command);
                return(1);
        }
+       if (!dev->drv[cmd->driver]) {
+               printk(KERN_WARNING "isdn_command command(%x) dev->drv[%d] NULL\n",
+                       cmd->command, cmd->driver);
+               return(1);
+       }
+       if (!dev->drv[cmd->driver]->interface) {
+               printk(KERN_WARNING "isdn_command command(%x) dev->drv[%d]->interface NULL\n",
+                       cmd->command, cmd->driver);
+               return(1);
+       }
        if (cmd->command == ISDN_CMD_SETL2) {
                int idx = isdn_dc2minor(cmd->driver, cmd->arg & 255);
                unsigned long l2prot = (cmd->arg >> 8) & 255;
@@ -933,7 +942,7 @@ isdn_readbchan_tty(int di, int channel, struct tty_struct *tty, int cisco_hack)
                        count_put = count_pull;
                        if(count_put > 1)
                                tty_insert_flip_string(tty, skb->data, count_put - 1);
-                       last = skb->data[count_put] - 1;
+                       last = skb->data[count_put - 1];
                        len -= count_put;
 #ifdef CONFIG_ISDN_AUDIO
                }
@@ -1050,7 +1059,7 @@ isdn_info_update(void)
 static ssize_t
 isdn_read(struct file *file, char __user *buf, size_t count, loff_t * off)
 {
-       uint minor = MINOR(file->f_dentry->d_inode->i_rdev);
+       uint minor = iminor(file->f_path.dentry->d_inode);
        int len = 0;
        int drvidx;
        int chidx;
@@ -1125,9 +1134,12 @@ isdn_read(struct file *file, char __user *buf, size_t count, loff_t * off)
                if (dev->drv[drvidx]->interface->readstat) {
                        if (count > dev->drv[drvidx]->stavail)
                                count = dev->drv[drvidx]->stavail;
-                       len = dev->drv[drvidx]->interface->
-                               readstat(buf, count, drvidx,
-                                        isdn_minor2chan(minor));
+                       len = dev->drv[drvidx]->interface->readstat(buf, count,
+                                               drvidx, isdn_minor2chan(minor));
+                       if (len < 0) {
+                               retval = len;
+                               goto out;
+                       }
                } else {
                        len = 0;
                }
@@ -1154,7 +1166,7 @@ isdn_read(struct file *file, char __user *buf, size_t count, loff_t * off)
 static ssize_t
 isdn_write(struct file *file, const char __user *buf, size_t count, loff_t * off)
 {
-       uint minor = MINOR(file->f_dentry->d_inode->i_rdev);
+       uint minor = iminor(file->f_path.dentry->d_inode);
        int drvidx;
        int chidx;
        int retval;
@@ -1216,7 +1228,7 @@ static unsigned int
 isdn_poll(struct file *file, poll_table * wait)
 {
        unsigned int mask = 0;
-       unsigned int minor = MINOR(file->f_dentry->d_inode->i_rdev);
+       unsigned int minor = iminor(file->f_path.dentry->d_inode);
        int drvidx = isdn_minor2drv(minor - ISDN_MINOR_CTRL);
 
        lock_kernel();
@@ -1257,7 +1269,7 @@ isdn_poll(struct file *file, poll_table * wait)
 static int
 isdn_ioctl(struct inode *inode, struct file *file, uint cmd, ulong arg)
 {
-       uint minor = MINOR(inode->i_rdev);
+       uint minor = iminor(inode);
        isdn_ctrl c;
        int drvidx;
        int chidx;
@@ -1708,7 +1720,7 @@ isdn_ioctl(struct inode *inode, struct file *file, uint cmd, ulong arg)
 static int
 isdn_open(struct inode *ino, struct file *filep)
 {
-       uint minor = MINOR(ino->i_rdev);
+       uint minor = iminor(ino);
        int drvidx;
        int chidx;
        int retval = -ENODEV;
@@ -1770,7 +1782,7 @@ isdn_open(struct inode *ino, struct file *filep)
 static int
 isdn_close(struct inode *ino, struct file *filep)
 {
-       uint minor = MINOR(ino->i_rdev);
+       uint minor = iminor(ino);
 
        lock_kernel();
        if (minor == ISDN_MINOR_STATUS) {
@@ -1903,6 +1915,11 @@ isdn_free_channel(int di, int ch, int usage)
 {
        int i;
 
+       if ((di < 0) || (ch < 0)) {
+               printk(KERN_WARNING "%s: called with invalid drv(%d) or channel(%d)\n",
+                       __FUNCTION__, di, ch);
+               return;
+       }
        for (i = 0; i < ISDN_MAX_CHANNELS; i++)
                if (((!usage) || ((dev->usage[i] & ISDN_USAGE_MASK) == usage)) &&
                    (dev->drvmap[i] == di) &&
@@ -1918,7 +1935,8 @@ isdn_free_channel(int di, int ch, int usage)
                        dev->v110[i] = NULL;
 // 20.10.99 JIM, try to reinitialize v110 !
                        isdn_info_update();
-                       skb_queue_purge(&dev->drv[di]->rpqueue[ch]);
+                       if (dev->drv[di])
+                               skb_queue_purge(&dev->drv[di]->rpqueue[ch]);
                }
 }
 
@@ -2054,21 +2072,19 @@ isdn_add_channels(isdn_driver_t *d, int drvidx, int n, int adding)
 
        if ((adding) && (d->rcverr))
                kfree(d->rcverr);
-       if (!(d->rcverr = kmalloc(sizeof(int) * m, GFP_ATOMIC))) {
+       if (!(d->rcverr = kzalloc(sizeof(int) * m, GFP_ATOMIC))) {
                printk(KERN_WARNING "register_isdn: Could not alloc rcverr\n");
                return -1;
        }
-       memset((char *) d->rcverr, 0, sizeof(int) * m);
 
        if ((adding) && (d->rcvcount))
                kfree(d->rcvcount);
-       if (!(d->rcvcount = kmalloc(sizeof(int) * m, GFP_ATOMIC))) {
+       if (!(d->rcvcount = kzalloc(sizeof(int) * m, GFP_ATOMIC))) {
                printk(KERN_WARNING "register_isdn: Could not alloc rcvcount\n");
                if (!adding)
                        kfree(d->rcverr);
                return -1;
        }
-       memset((char *) d->rcvcount, 0, sizeof(int) * m);
 
        if ((adding) && (d->rpqueue)) {
                for (j = 0; j < d->channels; j++)
@@ -2208,11 +2224,10 @@ register_isdn(isdn_if * i)
                printk(KERN_WARNING "register_isdn: No write routine given.\n");
                return 0;
        }
-       if (!(d = kmalloc(sizeof(isdn_driver_t), GFP_KERNEL))) {
+       if (!(d = kzalloc(sizeof(isdn_driver_t), GFP_KERNEL))) {
                printk(KERN_WARNING "register_isdn: Could not alloc driver-struct\n");
                return 0;
        }
-       memset((char *) d, 0, sizeof(isdn_driver_t));
 
        d->maxbufsize = i->maxbufsize;
        d->pktcount = 0;