#define KERNEL
#include <linux/types.h>
#include <linux/fs.h>
-#include <linux/mm.h> /* for verify_area */
+#include <linux/mm.h>
#include <linux/errno.h> /* for -EBUSY */
#include <linux/ioport.h> /* for request_region */
#include <linux/delay.h> /* for loops_per_jiffy */
#include <linux/init.h> /* for __init, module_{init,exit} */
#include <linux/poll.h> /* for POLLIN, etc. */
#include <linux/dtlk.h> /* local header file for DoubleTalk values */
-#include <linux/devfs_fs_kernel.h>
#include <linux/smp_lock.h>
#ifdef TRACING
static struct timer_list dtlk_timer;
/* prototypes for file_operations struct */
-static ssize_t dtlk_read(struct file *, char *,
+static ssize_t dtlk_read(struct file *, char __user *,
size_t nbytes, loff_t * ppos);
-static ssize_t dtlk_write(struct file *, const char *,
+static ssize_t dtlk_write(struct file *, const char __user *,
size_t nbytes, loff_t * ppos);
static unsigned int dtlk_poll(struct file *, poll_table *);
static int dtlk_open(struct inode *, struct file *);
static int dtlk_ioctl(struct inode *inode, struct file *file,
unsigned int cmd, unsigned long arg);
-static struct file_operations dtlk_fops =
+static const struct file_operations dtlk_fops =
{
.owner = THIS_MODULE,
.read = dtlk_read,
};
/* local prototypes */
-static void dtlk_delay(int ms);
static int dtlk_dev_probe(void);
static struct dtlk_settings *dtlk_interrogate(void);
static int dtlk_readable(void);
*/
static void dtlk_timer_tick(unsigned long data);
-static ssize_t dtlk_read(struct file *file, char *buf,
+static ssize_t dtlk_read(struct file *file, char __user *buf,
size_t count, loff_t * ppos)
{
- unsigned int minor = iminor(file->f_dentry->d_inode);
+ unsigned int minor = iminor(file->f_path.dentry->d_inode);
char ch;
int i = 0, retries;
- /* Can't seek (pread) on the DoubleTalk. */
- if (ppos != &file->f_pos)
- return -ESPIPE;
-
TRACE_TEXT("(dtlk_read");
/* printk("DoubleTalk PC - dtlk_read()\n"); */
return i;
if (file->f_flags & O_NONBLOCK)
break;
- dtlk_delay(100);
+ msleep_interruptible(100);
}
if (retries == loops_per_jiffy)
printk(KERN_ERR "dtlk_read times out\n");
return -EAGAIN;
}
-static ssize_t dtlk_write(struct file *file, const char *buf,
+static ssize_t dtlk_write(struct file *file, const char __user *buf,
size_t count, loff_t * ppos)
{
int i = 0, retries = 0, ch;
}
#endif
- /* Can't seek (pwrite) on the DoubleTalk. */
- if (ppos != &file->f_pos)
- return -ESPIPE;
-
- if (iminor(file->f_dentry->d_inode) != DTLK_MINOR)
+ if (iminor(file->f_path.dentry->d_inode) != DTLK_MINOR)
return -EINVAL;
while (1) {
rate to 500 bytes/sec, but that's
still enough to keep up with the
speech synthesizer. */
- dtlk_delay(1);
+ msleep_interruptible(1);
else {
/* the RDY bit goes zero 2-3 usec
after writing, and goes 1 again
if (file->f_flags & O_NONBLOCK)
break;
- dtlk_delay(1);
+ msleep_interruptible(1);
if (++retries > 10 * HZ) { /* wait no more than 10 sec
from last write */
unsigned int cmd,
unsigned long arg)
{
+ char __user *argp = (char __user *)arg;
struct dtlk_settings *sp;
char portval;
TRACE_TEXT(" dtlk_ioctl");
case DTLK_INTERROGATE:
sp = dtlk_interrogate();
- if (copy_to_user((char *) arg, (char *) sp,
- sizeof(struct dtlk_settings)))
+ if (copy_to_user(argp, sp, sizeof(struct dtlk_settings)))
return -EINVAL;
return 0;
case DTLK_STATUS:
portval = inb_p(dtlk_port_tts);
- return put_user(portval, (char *) arg);
+ return put_user(portval, argp);
default:
return -EINVAL;
{
TRACE_TEXT("(dtlk_open");
+ nonseekable_open(inode, file);
switch (iminor(inode)) {
case DTLK_MINOR:
if (dtlk_busy)
return -EBUSY;
- return 0;
+ return nonseekable_open(inode, file);
default:
return -ENXIO;
if (dtlk_dev_probe() == 0)
printk(", MAJOR %d\n", dtlk_major);
- devfs_mk_cdev(MKDEV(dtlk_major, DTLK_MINOR),
- S_IFCHR | S_IRUSR | S_IWUSR, "dtlk");
-
init_timer(&dtlk_timer);
dtlk_timer.function = dtlk_timer_tick;
init_waitqueue_head(&dtlk_process_list);
static void __exit dtlk_cleanup (void)
{
dtlk_write_bytes("goodbye", 8);
- current->state = TASK_INTERRUPTIBLE;
- schedule_timeout(5 * HZ / 10); /* nap 0.50 sec but
+ msleep_interruptible(500); /* nap 0.50 sec but
could be awakened
earlier by
signals... */
dtlk_write_tts(DTLK_CLEAR);
unregister_chrdev(dtlk_major, "dtlk");
- devfs_remove("dtlk");
release_region(dtlk_port_lpc, DTLK_IO_EXTENT);
}
/* ------------------------------------------------------------------------ */
-/* sleep for ms milliseconds */
-static void dtlk_delay(int ms)
-{
- current->state = TASK_INTERRUPTIBLE;
- schedule_timeout((ms * HZ + 1000 - HZ) / 1000);
-}
-
static int dtlk_readable(void)
{
#ifdef TRACING
/* posting an index takes 18 msec. Here, we
wait up to 100 msec to see whether it
appears. */
- dtlk_delay(100);
+ msleep_interruptible(100);
dtlk_has_indexing = dtlk_readable();
#ifdef TRACING
printk(", indexing %d\n", dtlk_has_indexing);
release_region(dtlk_portlist[i], DTLK_IO_EXTENT);
}
- printk(KERN_INFO "\nDoubleTalk PC - not found\n");
+ printk(KERN_INFO "DoubleTalk PC - not found\n");
return -ENODEV;
}