{
        struct ddb *dev = file->private_data;
        void *parg = (void *)arg;
-       int res = -EFAULT;
+       int res;
 
        switch (cmd) {
        case IOCTL_DDB_FLASHIO:
                u8 *rbuf, *wbuf;
 
                if (copy_from_user(&fio, parg, sizeof(fio)))
-                       break;
-               if (fio.write_len + fio.read_len > 1028) {
-                       printk(KERN_ERR "IOBUF too small\n");
-                       return -ENOMEM;
-               }
+                       return -EFAULT;
+
+               if (fio.write_len > 1028 || fio.read_len > 1028)
+                       return -EINVAL;
+               if (fio.write_len + fio.read_len > 1028)
+                       return -EINVAL;
+
                wbuf = &dev->iobuf[0];
-               if (!wbuf)
-                       return -ENOMEM;
                rbuf = wbuf + fio.write_len;
-               if (copy_from_user(wbuf, fio.write_buf, fio.write_len)) {
-                       vfree(wbuf);
-                       break;
-               }
-               res = flashio(dev, wbuf, fio.write_len,
-                             rbuf, fio.read_len);
+
+               if (copy_from_user(wbuf, fio.write_buf, fio.write_len))
+                       return -EFAULT;
+               res = flashio(dev, wbuf, fio.write_len, rbuf, fio.read_len);
+               if (res)
+                       return res;
                if (copy_to_user(fio.read_buf, rbuf, fio.read_len))
-                       res = -EFAULT;
+                       return -EFAULT;
                break;
        }
        default:
-               break;
+               return -ENOTTY;
        }
-       return res;
+       return 0;
 }
 
 static const struct file_operations ddb_fops = {