patch-2.1.113 linux/drivers/char/lp_m68k.c
Next file: linux/drivers/char/macmouse.c
Previous file: linux/drivers/char/lp_intern.c
Back to the patch index
Back to the overall index
- Lines: 232
- Date:
Thu Jul 30 11:17:12 1998
- Orig file:
v2.1.112/linux/drivers/char/lp_m68k.c
- Orig date:
Tue Jul 21 00:15:31 1998
diff -u --recursive --new-file v2.1.112/linux/drivers/char/lp_m68k.c linux/drivers/char/lp_m68k.c
@@ -173,13 +173,14 @@
}
#if WHICH_DRIVER == FORCE_INTERRUPT
-static long lp_write(struct inode *inode, struct file *file,
- const char *buf, unsigned long count)
+static ssize_t lp_write(struct file *file, const char *buf,
+ size_t count, loff_t *ppos)
#else
-static long lp_write_interrupt(struct inode *inode, struct file *file,
- const char *buf, unsigned long count)
+static ssize_t lp_write_interrupt(struct file *file, const char *buf,
+ size_t count, loff_t *ppos)
#endif
{
+ struct inode *inode = file->f_dentry->d_inode;
unsigned long total_bytes_written = 0;
unsigned int flags;
int rc;
@@ -190,7 +191,9 @@
lp_table[dev]->bytes_written = 0; /* init buffer read-pointer */
lp_error = 0;
lp_table[dev]->copy_size = (count <= LP_BUFFER_SIZE ? count : LP_BUFFER_SIZE);
- copy_from_user(lp_table[dev]->lp_buffer, buf, lp_table[dev]->copy_size);
+ if (copy_from_user(lp_table[dev]->lp_buffer, buf,
+ lp_table[dev]->copy_size))
+ return -EFAULT;
while (lp_table[dev]->copy_size) {
save_flags(flags);
cli(); /* no interrupts now */
@@ -223,10 +226,9 @@
rc = total_bytes_written + lp_table[dev]->bytes_written;
if (signal_pending(current)) {
- if (rc)
- return rc;
- else
- return -EINTR;
+ if (rc == 0)
+ rc = -EINTR;
+ return rc;
}
if (lp_error) {
@@ -267,13 +269,14 @@
#if WHICH_DRIVER != FORCE_INTERRUPT
#if WHICH_DRIVER == FORCE_POLLING
-static long lp_write(struct inode *inode, struct file *file,
- const char *buf, unsigned long count)
+static ssize_t lp_write(struct file *file, const char *buf,
+ size_t count, loff_t *ppos)
#else
-static long lp_write_polled(struct inode *inode, struct file *file,
- const char *buf, unsigned long count)
+static ssize_t lp_write_polled(struct file *file, const char *buf,
+ size_t count, loff_t *ppos)
#endif
{
+ struct inode *inode = file->f_dentry->d_inode;
char *temp = buf;
int dev = MINOR(inode->i_rdev);
@@ -287,52 +290,53 @@
temp = buf;
while (count > 0) {
- if (lp_char_polled(get_user(temp), dev)) {
+ int c;
+ if (get_user(c, temp))
+ return -EFAULT;
+ if (lp_char_polled(c, dev)) {
/* only update counting vars if character was printed */
count--; temp++;
#ifdef LP_DEBUG
lp_total_chars++;
#endif
} else { /* if printer timed out */
+ unsigned long timeout = LP_TIMEOUT_POLLED;
+ int error = 0;
if (lp_table[dev]->lp_has_pout(dev)) {
printk(KERN_NOTICE "lp%d: out of paper\n",dev);
if (lp_table[dev]->flags & LP_ABORT)
- return temp - buf ? temp-buf : -ENOSPC;
- current->state = TASK_INTERRUPTIBLE;
- current->timeout = jiffies + LP_TIMEOUT_POLLED;
- schedule();
+ error = -ENOSPC;
} else if (!lp_table[dev]->lp_is_online(dev)) {
printk(KERN_NOTICE "lp%d: off-line\n",dev);
if (lp_table[dev]->flags & LP_ABORT)
- return temp - buf ? temp-buf : -EIO;
- current->state = TASK_INTERRUPTIBLE;
- current->timeout = jiffies + LP_TIMEOUT_POLLED;
- schedule();
+ error = -EIO;
} else
/* not offline or out of paper. on fire? */
if (lp_table[dev]->lp_is_busy(dev)) {
printk(KERN_NOTICE "lp%d: on fire\n",dev);
if (lp_table[dev]->flags & LP_ABORT)
- return temp - buf ? temp-buf : -EFAULT;
- current->state = TASK_INTERRUPTIBLE;
- current->timeout = jiffies + LP_TIMEOUT_POLLED;
- schedule();
+ error = -EIO;
}
+ else
+ timeout = lp_table[dev]->time;
/* check for signals before going to sleep */
- if (signal_pending(current)) {
+ if (error == 0 && signal_pending(current))
+ error = -EINTR;
+ if (error) {
if (temp != buf)
return temp-buf;
else
- return -EINTR;
+ return error;
}
+
#ifdef LP_DEBUG
printk("lp sleeping at %d characters for %d jiffies\n",
- lp_total_chars, lp_table[dev]->time);
+ lp_total_chars, timeout);
lp_total_chars = 0;
#endif
current->state = TASK_INTERRUPTIBLE;
- current->timeout = jiffies + lp_table[dev]->time;
+ current->timeout = jiffies + timeout;
schedule();
}
}
@@ -343,13 +347,13 @@
unsigned int lp_irq = 0;
#if WHICH_DRIVER == PREFER_INTERRUPT
-static long lp_write(struct inode *inode, struct file *file,
- const char *buf, unsigned long count)
+static ssize_t lp_write(struct file *file, const char *buf, size_t count,
+ loff_t *ppos)
{
if (lp_irq)
- return lp_write_interrupt(inode, file, buf, count);
+ return lp_write_interrupt(file, buf, count, ppos);
else
- return lp_write_polled(inode, file, buf, count);
+ return lp_write_polled(file, buf, count, ppos);
}
#endif
@@ -363,8 +367,12 @@
int dev = MINOR(inode->i_rdev);
int ret;
+ MOD_INC_USE_COUNT;
+
+ ret = -ENODEV;
if (dev >= MAX_LP)
- return -ENODEV;
+ goto out_err;
+
#ifdef CONFIG_KMOD
if (!lp_table[dev]) {
char modname[30];
@@ -374,22 +382,25 @@
}
#endif
if (!lp_table[dev])
- return -ENODEV;
+ goto out_err;
if (!(lp_table[dev]->flags & LP_EXIST))
- return -ENODEV;
+ goto out_err;
+ ret = -EBUSY;
if (lp_table[dev]->flags & LP_BUSY)
- return -EBUSY;
+ goto out_err;
lp_table[dev]->flags |= LP_BUSY;
ret = lp_table[dev]->lp_open(dev);
if (ret != 0) {
lp_table[dev]->flags &= ~LP_BUSY;
- }
- else {
- MOD_INC_USE_COUNT;
+ goto out_err;
}
return ret;
+
+out_err:
+ MOD_DEC_USE_COUNT;
+ return ret;
}
static int lp_release(struct inode *inode, struct file *file)
@@ -407,15 +418,16 @@
unsigned int cmd, unsigned long arg)
{
unsigned int minor = MINOR(inode->i_rdev);
- int retval = 0;
+ int retval = -ENODEV;
#ifdef LP_DEBUG
printk("lp%d ioctl, cmd: 0x%x, arg: 0x%x\n", minor, cmd, arg);
#endif
if (minor >= max_lp)
- return -ENODEV;
+ goto out;
if (!(lp_table[minor]->flags & LP_EXIST))
- return -ENODEV;
+ goto out;
+ retval = 0;
switch (cmd) {
case LPTIME:
lp_table[minor]->time = arg;
@@ -437,11 +449,11 @@
retval = lp_irq;
break;
default:
+ retval = -EINVAL;
if (lp_table[minor]->lp_ioctl)
retval = lp_table[minor]->lp_ioctl(minor, cmd, arg);
- else
- retval = -EINVAL;
}
+out:
return retval;
}
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen, slshen@lbl.gov