diff options
Diffstat (limited to 'arch/um/drivers/hostaudio_kern.c')
-rw-r--r-- | arch/um/drivers/hostaudio_kern.c | 160 |
1 files changed, 73 insertions, 87 deletions
diff --git a/arch/um/drivers/hostaudio_kern.c b/arch/um/drivers/hostaudio_kern.c index f61fa0562202..10e08a8c17c3 100644 --- a/arch/um/drivers/hostaudio_kern.c +++ b/arch/um/drivers/hostaudio_kern.c | |||
@@ -15,11 +15,11 @@ | |||
15 | #include "os.h" | 15 | #include "os.h" |
16 | 16 | ||
17 | struct hostaudio_state { | 17 | struct hostaudio_state { |
18 | int fd; | 18 | int fd; |
19 | }; | 19 | }; |
20 | 20 | ||
21 | struct hostmixer_state { | 21 | struct hostmixer_state { |
22 | int fd; | 22 | int fd; |
23 | }; | 23 | }; |
24 | 24 | ||
25 | #define HOSTAUDIO_DEV_DSP "/dev/sound/dsp" | 25 | #define HOSTAUDIO_DEV_DSP "/dev/sound/dsp" |
@@ -72,12 +72,12 @@ MODULE_PARM_DESC(mixer, MIXER_HELP); | |||
72 | static ssize_t hostaudio_read(struct file *file, char __user *buffer, | 72 | static ssize_t hostaudio_read(struct file *file, char __user *buffer, |
73 | size_t count, loff_t *ppos) | 73 | size_t count, loff_t *ppos) |
74 | { | 74 | { |
75 | struct hostaudio_state *state = file->private_data; | 75 | struct hostaudio_state *state = file->private_data; |
76 | void *kbuf; | 76 | void *kbuf; |
77 | int err; | 77 | int err; |
78 | 78 | ||
79 | #ifdef DEBUG | 79 | #ifdef DEBUG |
80 | printk("hostaudio: read called, count = %d\n", count); | 80 | printk("hostaudio: read called, count = %d\n", count); |
81 | #endif | 81 | #endif |
82 | 82 | ||
83 | kbuf = kmalloc(count, GFP_KERNEL); | 83 | kbuf = kmalloc(count, GFP_KERNEL); |
@@ -91,7 +91,7 @@ static ssize_t hostaudio_read(struct file *file, char __user *buffer, | |||
91 | if(copy_to_user(buffer, kbuf, err)) | 91 | if(copy_to_user(buffer, kbuf, err)) |
92 | err = -EFAULT; | 92 | err = -EFAULT; |
93 | 93 | ||
94 | out: | 94 | out: |
95 | kfree(kbuf); | 95 | kfree(kbuf); |
96 | return(err); | 96 | return(err); |
97 | } | 97 | } |
@@ -99,12 +99,12 @@ static ssize_t hostaudio_read(struct file *file, char __user *buffer, | |||
99 | static ssize_t hostaudio_write(struct file *file, const char __user *buffer, | 99 | static ssize_t hostaudio_write(struct file *file, const char __user *buffer, |
100 | size_t count, loff_t *ppos) | 100 | size_t count, loff_t *ppos) |
101 | { | 101 | { |
102 | struct hostaudio_state *state = file->private_data; | 102 | struct hostaudio_state *state = file->private_data; |
103 | void *kbuf; | 103 | void *kbuf; |
104 | int err; | 104 | int err; |
105 | 105 | ||
106 | #ifdef DEBUG | 106 | #ifdef DEBUG |
107 | printk("hostaudio: write called, count = %d\n", count); | 107 | printk("hostaudio: write called, count = %d\n", count); |
108 | #endif | 108 | #endif |
109 | 109 | ||
110 | kbuf = kmalloc(count, GFP_KERNEL); | 110 | kbuf = kmalloc(count, GFP_KERNEL); |
@@ -128,24 +128,24 @@ static ssize_t hostaudio_write(struct file *file, const char __user *buffer, | |||
128 | static unsigned int hostaudio_poll(struct file *file, | 128 | static unsigned int hostaudio_poll(struct file *file, |
129 | struct poll_table_struct *wait) | 129 | struct poll_table_struct *wait) |
130 | { | 130 | { |
131 | unsigned int mask = 0; | 131 | unsigned int mask = 0; |
132 | 132 | ||
133 | #ifdef DEBUG | 133 | #ifdef DEBUG |
134 | printk("hostaudio: poll called (unimplemented)\n"); | 134 | printk("hostaudio: poll called (unimplemented)\n"); |
135 | #endif | 135 | #endif |
136 | 136 | ||
137 | return(mask); | 137 | return(mask); |
138 | } | 138 | } |
139 | 139 | ||
140 | static int hostaudio_ioctl(struct inode *inode, struct file *file, | 140 | static int hostaudio_ioctl(struct inode *inode, struct file *file, |
141 | unsigned int cmd, unsigned long arg) | 141 | unsigned int cmd, unsigned long arg) |
142 | { | 142 | { |
143 | struct hostaudio_state *state = file->private_data; | 143 | struct hostaudio_state *state = file->private_data; |
144 | unsigned long data = 0; | 144 | unsigned long data = 0; |
145 | int err; | 145 | int err; |
146 | 146 | ||
147 | #ifdef DEBUG | 147 | #ifdef DEBUG |
148 | printk("hostaudio: ioctl called, cmd = %u\n", cmd); | 148 | printk("hostaudio: ioctl called, cmd = %u\n", cmd); |
149 | #endif | 149 | #endif |
150 | switch(cmd){ | 150 | switch(cmd){ |
151 | case SNDCTL_DSP_SPEED: | 151 | case SNDCTL_DSP_SPEED: |
@@ -182,42 +182,40 @@ static int hostaudio_ioctl(struct inode *inode, struct file *file, | |||
182 | 182 | ||
183 | static int hostaudio_open(struct inode *inode, struct file *file) | 183 | static int hostaudio_open(struct inode *inode, struct file *file) |
184 | { | 184 | { |
185 | struct hostaudio_state *state; | 185 | struct hostaudio_state *state; |
186 | int r = 0, w = 0; | 186 | int r = 0, w = 0; |
187 | int ret; | 187 | int ret; |
188 | 188 | ||
189 | #ifdef DEBUG | 189 | #ifdef DEBUG |
190 | printk("hostaudio: open called (host: %s)\n", dsp); | 190 | printk("hostaudio: open called (host: %s)\n", dsp); |
191 | #endif | 191 | #endif |
192 | 192 | ||
193 | state = kmalloc(sizeof(struct hostaudio_state), GFP_KERNEL); | 193 | state = kmalloc(sizeof(struct hostaudio_state), GFP_KERNEL); |
194 | if(state == NULL) | 194 | if(state == NULL) |
195 | return(-ENOMEM); | 195 | return(-ENOMEM); |
196 | 196 | ||
197 | if(file->f_mode & FMODE_READ) r = 1; | 197 | if(file->f_mode & FMODE_READ) r = 1; |
198 | if(file->f_mode & FMODE_WRITE) w = 1; | 198 | if(file->f_mode & FMODE_WRITE) w = 1; |
199 | 199 | ||
200 | ret = os_open_file(dsp, of_set_rw(OPENFLAGS(), r, w), 0); | 200 | ret = os_open_file(dsp, of_set_rw(OPENFLAGS(), r, w), 0); |
201 | if(ret < 0){ | 201 | if(ret < 0){ |
202 | kfree(state); | 202 | kfree(state); |
203 | return(ret); | 203 | return(ret); |
204 | } | 204 | } |
205 | |||
206 | state->fd = ret; | 205 | state->fd = ret; |
207 | file->private_data = state; | 206 | file->private_data = state; |
208 | return(0); | 207 | return(0); |
209 | } | 208 | } |
210 | 209 | ||
211 | static int hostaudio_release(struct inode *inode, struct file *file) | 210 | static int hostaudio_release(struct inode *inode, struct file *file) |
212 | { | 211 | { |
213 | struct hostaudio_state *state = file->private_data; | 212 | struct hostaudio_state *state = file->private_data; |
214 | 213 | ||
215 | #ifdef DEBUG | 214 | #ifdef DEBUG |
216 | printk("hostaudio: release called\n"); | 215 | printk("hostaudio: release called\n"); |
217 | #endif | 216 | #endif |
218 | 217 | os_close_file(state->fd); | |
219 | os_close_file(state->fd); | 218 | kfree(state); |
220 | kfree(state); | ||
221 | 219 | ||
222 | return(0); | 220 | return(0); |
223 | } | 221 | } |
@@ -227,10 +225,10 @@ static int hostaudio_release(struct inode *inode, struct file *file) | |||
227 | static int hostmixer_ioctl_mixdev(struct inode *inode, struct file *file, | 225 | static int hostmixer_ioctl_mixdev(struct inode *inode, struct file *file, |
228 | unsigned int cmd, unsigned long arg) | 226 | unsigned int cmd, unsigned long arg) |
229 | { | 227 | { |
230 | struct hostmixer_state *state = file->private_data; | 228 | struct hostmixer_state *state = file->private_data; |
231 | 229 | ||
232 | #ifdef DEBUG | 230 | #ifdef DEBUG |
233 | printk("hostmixer: ioctl called\n"); | 231 | printk("hostmixer: ioctl called\n"); |
234 | #endif | 232 | #endif |
235 | 233 | ||
236 | return(os_ioctl_generic(state->fd, cmd, arg)); | 234 | return(os_ioctl_generic(state->fd, cmd, arg)); |
@@ -238,68 +236,67 @@ static int hostmixer_ioctl_mixdev(struct inode *inode, struct file *file, | |||
238 | 236 | ||
239 | static int hostmixer_open_mixdev(struct inode *inode, struct file *file) | 237 | static int hostmixer_open_mixdev(struct inode *inode, struct file *file) |
240 | { | 238 | { |
241 | struct hostmixer_state *state; | 239 | struct hostmixer_state *state; |
242 | int r = 0, w = 0; | 240 | int r = 0, w = 0; |
243 | int ret; | 241 | int ret; |
244 | 242 | ||
245 | #ifdef DEBUG | 243 | #ifdef DEBUG |
246 | printk("hostmixer: open called (host: %s)\n", mixer); | 244 | printk("hostmixer: open called (host: %s)\n", mixer); |
247 | #endif | 245 | #endif |
248 | 246 | ||
249 | state = kmalloc(sizeof(struct hostmixer_state), GFP_KERNEL); | 247 | state = kmalloc(sizeof(struct hostmixer_state), GFP_KERNEL); |
250 | if(state == NULL) return(-ENOMEM); | 248 | if(state == NULL) return(-ENOMEM); |
251 | 249 | ||
252 | if(file->f_mode & FMODE_READ) r = 1; | 250 | if(file->f_mode & FMODE_READ) r = 1; |
253 | if(file->f_mode & FMODE_WRITE) w = 1; | 251 | if(file->f_mode & FMODE_WRITE) w = 1; |
254 | 252 | ||
255 | ret = os_open_file(mixer, of_set_rw(OPENFLAGS(), r, w), 0); | 253 | ret = os_open_file(mixer, of_set_rw(OPENFLAGS(), r, w), 0); |
256 | 254 | ||
257 | if(ret < 0){ | 255 | if(ret < 0){ |
258 | printk("hostaudio_open_mixdev failed to open '%s', err = %d\n", | 256 | printk("hostaudio_open_mixdev failed to open '%s', err = %d\n", |
259 | dsp, -ret); | 257 | dsp, -ret); |
260 | kfree(state); | 258 | kfree(state); |
261 | return(ret); | 259 | return(ret); |
262 | } | 260 | } |
263 | 261 | ||
264 | file->private_data = state; | 262 | file->private_data = state; |
265 | return(0); | 263 | return(0); |
266 | } | 264 | } |
267 | 265 | ||
268 | static int hostmixer_release(struct inode *inode, struct file *file) | 266 | static int hostmixer_release(struct inode *inode, struct file *file) |
269 | { | 267 | { |
270 | struct hostmixer_state *state = file->private_data; | 268 | struct hostmixer_state *state = file->private_data; |
271 | 269 | ||
272 | #ifdef DEBUG | 270 | #ifdef DEBUG |
273 | printk("hostmixer: release called\n"); | 271 | printk("hostmixer: release called\n"); |
274 | #endif | 272 | #endif |
275 | 273 | ||
276 | os_close_file(state->fd); | 274 | os_close_file(state->fd); |
277 | kfree(state); | 275 | kfree(state); |
278 | 276 | ||
279 | return(0); | 277 | return(0); |
280 | } | 278 | } |
281 | 279 | ||
282 | |||
283 | /* kernel module operations */ | 280 | /* kernel module operations */ |
284 | 281 | ||
285 | static const struct file_operations hostaudio_fops = { | 282 | static const struct file_operations hostaudio_fops = { |
286 | .owner = THIS_MODULE, | 283 | .owner = THIS_MODULE, |
287 | .llseek = no_llseek, | 284 | .llseek = no_llseek, |
288 | .read = hostaudio_read, | 285 | .read = hostaudio_read, |
289 | .write = hostaudio_write, | 286 | .write = hostaudio_write, |
290 | .poll = hostaudio_poll, | 287 | .poll = hostaudio_poll, |
291 | .ioctl = hostaudio_ioctl, | 288 | .ioctl = hostaudio_ioctl, |
292 | .mmap = NULL, | 289 | .mmap = NULL, |
293 | .open = hostaudio_open, | 290 | .open = hostaudio_open, |
294 | .release = hostaudio_release, | 291 | .release = hostaudio_release, |
295 | }; | 292 | }; |
296 | 293 | ||
297 | static const struct file_operations hostmixer_fops = { | 294 | static const struct file_operations hostmixer_fops = { |
298 | .owner = THIS_MODULE, | 295 | .owner = THIS_MODULE, |
299 | .llseek = no_llseek, | 296 | .llseek = no_llseek, |
300 | .ioctl = hostmixer_ioctl_mixdev, | 297 | .ioctl = hostmixer_ioctl_mixdev, |
301 | .open = hostmixer_open_mixdev, | 298 | .open = hostmixer_open_mixdev, |
302 | .release = hostmixer_release, | 299 | .release = hostmixer_release, |
303 | }; | 300 | }; |
304 | 301 | ||
305 | struct { | 302 | struct { |
@@ -313,42 +310,31 @@ MODULE_LICENSE("GPL"); | |||
313 | 310 | ||
314 | static int __init hostaudio_init_module(void) | 311 | static int __init hostaudio_init_module(void) |
315 | { | 312 | { |
316 | printk(KERN_INFO "UML Audio Relay (host dsp = %s, host mixer = %s)\n", | 313 | printk(KERN_INFO "UML Audio Relay (host dsp = %s, host mixer = %s)\n", |
317 | dsp, mixer); | 314 | dsp, mixer); |
318 | 315 | ||
319 | module_data.dev_audio = register_sound_dsp(&hostaudio_fops, -1); | 316 | module_data.dev_audio = register_sound_dsp(&hostaudio_fops, -1); |
320 | if(module_data.dev_audio < 0){ | 317 | if(module_data.dev_audio < 0){ |
321 | printk(KERN_ERR "hostaudio: couldn't register DSP device!\n"); | 318 | printk(KERN_ERR "hostaudio: couldn't register DSP device!\n"); |
322 | return -ENODEV; | 319 | return -ENODEV; |
323 | } | 320 | } |
324 | 321 | ||
325 | module_data.dev_mixer = register_sound_mixer(&hostmixer_fops, -1); | 322 | module_data.dev_mixer = register_sound_mixer(&hostmixer_fops, -1); |
326 | if(module_data.dev_mixer < 0){ | 323 | if(module_data.dev_mixer < 0){ |
327 | printk(KERN_ERR "hostmixer: couldn't register mixer " | 324 | printk(KERN_ERR "hostmixer: couldn't register mixer " |
328 | "device!\n"); | 325 | "device!\n"); |
329 | unregister_sound_dsp(module_data.dev_audio); | 326 | unregister_sound_dsp(module_data.dev_audio); |
330 | return -ENODEV; | 327 | return -ENODEV; |
331 | } | 328 | } |
332 | 329 | ||
333 | return 0; | 330 | return 0; |
334 | } | 331 | } |
335 | 332 | ||
336 | static void __exit hostaudio_cleanup_module (void) | 333 | static void __exit hostaudio_cleanup_module (void) |
337 | { | 334 | { |
338 | unregister_sound_mixer(module_data.dev_mixer); | 335 | unregister_sound_mixer(module_data.dev_mixer); |
339 | unregister_sound_dsp(module_data.dev_audio); | 336 | unregister_sound_dsp(module_data.dev_audio); |
340 | } | 337 | } |
341 | 338 | ||
342 | module_init(hostaudio_init_module); | 339 | module_init(hostaudio_init_module); |
343 | module_exit(hostaudio_cleanup_module); | 340 | module_exit(hostaudio_cleanup_module); |
344 | |||
345 | /* | ||
346 | * Overrides for Emacs so that we follow Linus's tabbing style. | ||
347 | * Emacs will notice this stuff at the end of the file and automatically | ||
348 | * adjust the settings for this buffer only. This must remain at the end | ||
349 | * of the file. | ||
350 | * --------------------------------------------------------------------------- | ||
351 | * Local variables: | ||
352 | * c-file-style: "linux" | ||
353 | * End: | ||
354 | */ | ||