diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2010-10-28 12:13:00 -0700 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2010-10-28 12:13:00 -0700 |
commit | f063a0c0c995d010960efcc1b2ed14b99674f25c (patch) | |
tree | 106e30acd1a58b3cf9f3c15abe1de83f1919e03b /drivers/staging/speakup/devsynth.c | |
parent | 3c3762957818dc902222733a8184f23102e24472 (diff) | |
parent | 5af634789c93b97cfb314a102436716be8fbc577 (diff) | |
download | op-kernel-dev-f063a0c0c995d010960efcc1b2ed14b99674f25c.zip op-kernel-dev-f063a0c0c995d010960efcc1b2ed14b99674f25c.tar.gz |
Merge git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/staging-2.6
* git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/staging-2.6: (841 commits)
Staging: brcm80211: fix usage of roundup in structures
Staging: bcm: fix up network device reference counting
Staging: keucr: fix up US_ macro change
staging: brcm80211: brcmfmac: Removed codeversion from firmware filenames.
staging: brcm80211: Remove unnecessary header files.
staging: brcm80211: Remove unnecessary includes from bcmutils.c
staging: brcm80211: Removed unnecessary pktsetprio() function.
Staging: brcm80211: remove typedefs.h
Staging: brcm80211: remove uintptr typedef usage
Staging: hv: remove struct vmbus_channel_interface
Staging: hv: remove Open from struct vmbus_channel_interface
Staging: hv: storvsc: call vmbus_open directly
Staging: hv: netvsc: call vmbus_open directly
Staging: hv: channel: export vmbus_open to modules
Staging: hv: remove Close from struct vmbus_channel_interface
Staging: hv: netvsc: call vmbus_close directly
Staging: hv: storvsc: call vmbus_close directly
Staging: hv: channel: export vmbus_close to modules
Staging: hv: remove SendPacket from struct vmbus_channel_interface
Staging: hv: storvsc: call vmbus_sendpacket directly
...
Fix up conflicts in
drivers/staging/cx25821/cx25821-audio-upstream.c
drivers/staging/cx25821/cx25821-audio.h
due to warring whitespace cleanups (neither of which were all that great)
Diffstat (limited to 'drivers/staging/speakup/devsynth.c')
-rw-r--r-- | drivers/staging/speakup/devsynth.c | 94 |
1 files changed, 94 insertions, 0 deletions
diff --git a/drivers/staging/speakup/devsynth.c b/drivers/staging/speakup/devsynth.c new file mode 100644 index 0000000..39dc586 --- /dev/null +++ b/drivers/staging/speakup/devsynth.c @@ -0,0 +1,94 @@ +#include <linux/errno.h> +#include <linux/miscdevice.h> /* for misc_register, and SYNTH_MINOR */ +#include <linux/types.h> +#include <linux/uaccess.h> + +#include "speakup.h" +#include "spk_priv.h" + +#ifndef SYNTH_MINOR +#define SYNTH_MINOR 25 +#endif + +static int misc_registered; +static int dev_opened; + +static ssize_t speakup_file_write(struct file *fp, const char *buffer, + size_t nbytes, loff_t *ppos) +{ + size_t count = nbytes; + const char *ptr = buffer; + int bytes; + unsigned long flags; + u_char buf[256]; + if (synth == NULL) + return -ENODEV; + while (count > 0) { + bytes = min_t(size_t, count, sizeof(buf)); + if (copy_from_user(buf, ptr, bytes)) + return -EFAULT; + count -= bytes; + ptr += bytes; + spk_lock(flags); + synth_write(buf, bytes); + spk_unlock(flags); + } + return (ssize_t) nbytes; +} + +static ssize_t speakup_file_read(struct file *fp, char *buf, size_t nbytes, + loff_t *ppos) +{ + return 0; +} + +static int speakup_file_open(struct inode *ip, struct file *fp) +{ + if (synth == NULL) + return -ENODEV; + if (xchg(&dev_opened, 1)) + return -EBUSY; + return 0; +} + +static int speakup_file_release(struct inode *ip, struct file *fp) +{ + dev_opened = 0; + return 0; +} + +static const struct file_operations synth_fops = { + .read = speakup_file_read, + .write = speakup_file_write, + .open = speakup_file_open, + .release = speakup_file_release, +}; + +static struct miscdevice synth_device = { + .minor = SYNTH_MINOR, + .name = "synth", + .fops = &synth_fops, +}; + +void speakup_register_devsynth(void) +{ + if (misc_registered != 0) + return; +/* zero it so if register fails, deregister will not ref invalid ptrs */ + if (misc_register(&synth_device)) + pr_warn("Couldn't initialize miscdevice /dev/synth.\n"); + else { + pr_info("initialized device: /dev/synth, node (MAJOR %d, MINOR %d)\n", + MISC_MAJOR, SYNTH_MINOR); + misc_registered = 1; + } +} + +void speakup_unregister_devsynth(void) +{ + if (!misc_registered) + return; + pr_info("speakup: unregistering synth device /dev/synth\n"); + misc_deregister(&synth_device); + misc_registered = 0; +} |