aboutsummaryrefslogtreecommitdiff
path: root/drivers/char/dtlk.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/char/dtlk.c')
-rw-r--r--drivers/char/dtlk.c30
1 files changed, 18 insertions, 12 deletions
diff --git a/drivers/char/dtlk.c b/drivers/char/dtlk.c
index abde6ddefe6..65a8d96c0e9 100644
--- a/drivers/char/dtlk.c
+++ b/drivers/char/dtlk.c
@@ -56,6 +56,8 @@
#include <linux/errno.h> /* for -EBUSY */
#include <linux/ioport.h> /* for request_region */
#include <linux/delay.h> /* for loops_per_jiffy */
+#include <linux/sched.h>
+#include <linux/mutex.h>
#include <asm/io.h> /* for inb_p, outb_p, inb, outb, etc. */
#include <asm/uaccess.h> /* for get_user, etc. */
#include <linux/wait.h> /* for wait_queue */
@@ -71,6 +73,7 @@
#define TRACE_RET ((void) 0)
#endif /* TRACING */
+static DEFINE_MUTEX(dtlk_mutex);
static void dtlk_timer_tick(unsigned long data);
static int dtlk_major;
@@ -91,8 +94,8 @@ static ssize_t dtlk_write(struct file *, const char __user *,
static unsigned int dtlk_poll(struct file *, poll_table *);
static int dtlk_open(struct inode *, struct file *);
static int dtlk_release(struct inode *, struct file *);
-static int dtlk_ioctl(struct inode *inode, struct file *file,
- unsigned int cmd, unsigned long arg);
+static long dtlk_ioctl(struct file *file,
+ unsigned int cmd, unsigned long arg);
static const struct file_operations dtlk_fops =
{
@@ -100,9 +103,10 @@ static const struct file_operations dtlk_fops =
.read = dtlk_read,
.write = dtlk_write,
.poll = dtlk_poll,
- .ioctl = dtlk_ioctl,
+ .unlocked_ioctl = dtlk_ioctl,
.open = dtlk_open,
.release = dtlk_release,
+ .llseek = no_llseek,
};
/* local prototypes */
@@ -121,7 +125,7 @@ static char dtlk_write_tts(char);
static ssize_t dtlk_read(struct file *file, char __user *buf,
size_t count, loff_t * ppos)
{
- unsigned int minor = iminor(file->f_path.dentry->d_inode);
+ unsigned int minor = iminor(file_inode(file));
char ch;
int i = 0, retries;
@@ -173,7 +177,7 @@ static ssize_t dtlk_write(struct file *file, const char __user *buf,
}
#endif
- if (iminor(file->f_path.dentry->d_inode) != DTLK_MINOR)
+ if (iminor(file_inode(file)) != DTLK_MINOR)
return -EINVAL;
while (1) {
@@ -261,10 +265,9 @@ static void dtlk_timer_tick(unsigned long data)
wake_up_interruptible(&dtlk_process_list);
}
-static int dtlk_ioctl(struct inode *inode,
- struct file *file,
- unsigned int cmd,
- unsigned long arg)
+static long dtlk_ioctl(struct file *file,
+ unsigned int cmd,
+ unsigned long arg)
{
char __user *argp = (char __user *)arg;
struct dtlk_settings *sp;
@@ -274,7 +277,9 @@ static int dtlk_ioctl(struct inode *inode,
switch (cmd) {
case DTLK_INTERROGATE:
+ mutex_lock(&dtlk_mutex);
sp = dtlk_interrogate();
+ mutex_unlock(&dtlk_mutex);
if (copy_to_user(argp, sp, sizeof(struct dtlk_settings)))
return -EINVAL;
return 0;
@@ -288,6 +293,7 @@ static int dtlk_ioctl(struct inode *inode,
}
}
+/* Note that nobody ever sets dtlk_busy... */
static int dtlk_open(struct inode *inode, struct file *file)
{
TRACE_TEXT("(dtlk_open");
@@ -568,7 +574,7 @@ static char dtlk_read_tts(void)
portval = inb_p(dtlk_port_tts);
} while ((portval & TTS_READABLE) == 0 &&
retries++ < DTLK_MAX_RETRIES);
- if (retries == DTLK_MAX_RETRIES)
+ if (retries > DTLK_MAX_RETRIES)
printk(KERN_ERR "dtlk_read_tts() timeout\n");
ch = inb_p(dtlk_port_tts); /* input from TTS port */
@@ -580,7 +586,7 @@ static char dtlk_read_tts(void)
portval = inb_p(dtlk_port_tts);
} while ((portval & TTS_READABLE) != 0 &&
retries++ < DTLK_MAX_RETRIES);
- if (retries == DTLK_MAX_RETRIES)
+ if (retries > DTLK_MAX_RETRIES)
printk(KERN_ERR "dtlk_read_tts() timeout\n");
TRACE_RET;
@@ -637,7 +643,7 @@ static char dtlk_write_tts(char ch)
while ((inb_p(dtlk_port_tts) & TTS_WRITABLE) == 0 &&
retries++ < DTLK_MAX_RETRIES) /* DT ready? */
;
- if (retries == DTLK_MAX_RETRIES)
+ if (retries > DTLK_MAX_RETRIES)
printk(KERN_ERR "dtlk_write_tts() timeout\n");
outb_p(ch, dtlk_port_tts); /* output to TTS port */