import of ftp.dlink.com/GPL/DSMG-600_reB/ppclinux.tar.gz
[linux-2.4.21-pre4.git] / drivers / sbus / audio / audio.c
1 /* $Id: audio.c,v 1.1.1.1 2005/04/11 02:50:34 jack Exp $
2  * drivers/sbus/audio/audio.c
3  *
4  * Copyright 1996 Thomas K. Dyas (tdyas@noc.rutgers.edu)
5  * Copyright 1997,1998,1999 Derrick J. Brashear (shadow@dementia.org)
6  * Copyright 1997 Brent Baccala (baccala@freesoft.org)
7  * 
8  * Mixer code adapted from code contributed by and
9  * Copyright 1998 Michael Mraka (michael@fi.muni.cz)
10  * and with fixes from Michael Shuey (shuey@ecn.purdue.edu)
11  * The mixer code cheats; Sparc hardware doesn't generally allow independent
12  * line control, and this fakes it badly.
13  *
14  * SNDCTL_DSP_SETFMT based on code contributed by
15  * Ion Badulescu (ionut@moisil.cs.columbia.edu)
16  *
17  * This is the audio midlayer that sits between the VFS character
18  * devices and the low-level audio hardware device drivers.
19  */
20
21 #include <linux/config.h>
22 #include <linux/module.h>
23 #include <linux/errno.h>
24 #include <linux/fs.h>
25 #include <linux/kernel.h>
26 #include <linux/sched.h>
27 #include <linux/smp_lock.h>
28 #include <linux/mm.h>
29 #include <linux/tqueue.h>
30 #include <linux/major.h>
31 #include <linux/slab.h>
32 #include <linux/interrupt.h>
33 #include <linux/init.h>
34 #include <linux/soundcard.h>
35 #include <linux/devfs_fs_kernel.h>
36 #include <linux/delay.h>
37 #include <linux/poll.h>
38 #include <asm/pgtable.h>
39 #include <asm/uaccess.h>
40
41 #include <asm/audioio.h>
42
43 #undef __AUDIO_DEBUG
44 #define __AUDIO_ERROR
45 #undef __AUDIO_TRACE
46 #undef __AUDIO_OSSDEBUG
47 #ifdef __AUDIO_DEBUG
48 #define dprintk(x) printk x
49 #else
50 #define dprintk(x)
51 #endif
52 #ifdef __AUDIO_OSSDEBUG
53 #define oprintk(x) printk x
54 #else
55 #define oprintk(x)
56 #endif
57 #ifdef __AUDIO_ERROR
58 #define eprintk(x) printk x
59 #else
60 #define eprintk(x)
61 #endif
62 #ifdef __AUDIO_TRACE
63 #define tprintk(x) printk x
64 #else
65 #define tprintk(x)
66 #endif
67
68 static short lis_get_elist_ent( strevent_t *list, pid_t pid );
69 static int lis_add_to_elist( strevent_t **list, pid_t pid, short events );
70 static int lis_del_from_elist( strevent_t **list, pid_t pid, short events );
71 static void lis_free_elist( strevent_t **list);
72 static void kill_procs( struct strevent *elist, int sig, short e);
73
74 static struct sparcaudio_driver *drivers[SPARCAUDIO_MAX_DEVICES];
75 static devfs_handle_t devfs_handle;
76  
77
78 void sparcaudio_output_done(struct sparcaudio_driver * drv, int status)
79 {
80         /* If !status, just restart current output.
81          * If status & 1, a buffer is finished; make it available again.
82          * If status & 2, a buffer was claimed for DMA and is still in use.
83          *
84          * The playing_count for non-DMA hardware should never be non-zero.
85          * Value of status for non-DMA hardware should always be 1.
86          */
87         if (status & 1) {
88                 if (drv->playing_count) {
89                         drv->playing_count--;
90                 } else {
91                         drv->output_count--;
92                         drv->output_size -= drv->output_sizes[drv->output_front];
93                         if (drv->output_notify[drv->output_front] == 1) {
94                                 drv->output_eof++;
95                                 drv->output_notify[drv->output_front] = 0;
96                                 kill_procs(drv->sd_siglist,SIGPOLL,S_MSG);
97                         }
98                         drv->output_front = (drv->output_front + 1) % 
99                                 drv->num_output_buffers;
100                 }
101         }
102     
103         if (status & 2) {
104                 drv->output_count--;
105                 drv->playing_count++;
106                 drv->output_size -= drv->output_sizes[drv->output_front];
107                 if (drv->output_notify[drv->output_front] == 1) {
108                         drv->output_eof++;
109                         drv->output_notify[drv->output_front] = 0;
110                         kill_procs(drv->sd_siglist,SIGPOLL,S_MSG);
111                 }
112                 drv->output_front = (drv->output_front + 1) % 
113                         drv->num_output_buffers;
114         }
115
116         /* If we've played everything go inactive. */
117         if ((drv->output_count < 1) && (drv->playing_count < 1)) 
118                 drv->output_active = 0;
119
120         /* If we got back a buffer, see if anyone wants to write to it */
121         if ((status & 1) || ((drv->output_count + drv->playing_count) 
122                              < drv->num_output_buffers)) {
123                 wake_up_interruptible(&drv->output_write_wait);
124         }
125
126         /* If the output queue is empty, shut down the driver. */
127         if ((drv->output_count < 1) && (drv->playing_count < 1)) {
128                 kill_procs(drv->sd_siglist,SIGPOLL,S_MSG);
129
130                 /* Stop the lowlevel driver from outputing. */
131                 /* drv->ops->stop_output(drv); Should not be necessary  -- DJB 5/25/98 */
132                 drv->output_active = 0;
133                   
134                 /* Wake up any waiting writers or syncers and return. */
135                 wake_up_interruptible(&drv->output_write_wait);
136                 wake_up_interruptible(&drv->output_drain_wait);
137                 return;
138         }
139
140         /* Start next block of output if we have it */
141         if (drv->output_count > 0) {
142                 drv->ops->start_output(drv, drv->output_buffers[drv->output_front],
143                                        drv->output_sizes[drv->output_front]);
144                 drv->output_active = 1;
145         } else {
146                 drv->output_active = 0;
147         }
148 }
149
150 void sparcaudio_input_done(struct sparcaudio_driver * drv, int status)
151 {
152         /* Deal with the weird case here */
153         if (drv->duplex == 2) {
154                 if (drv->input_count < drv->num_input_buffers)
155                         drv->input_count++;
156                 drv->ops->start_input(drv, drv->input_buffers[drv->input_front],
157                                       drv->input_buffer_size);
158                 wake_up_interruptible(&drv->input_read_wait);
159                 return;
160         } 
161
162         /* If status % 2, they filled a buffer for us. 
163          * If status & 2, they took a buffer from us.
164          */
165         if ((status % 2) == 1) {
166                 drv->input_count++;
167                 drv->recording_count--;
168                 drv->input_size+=drv->input_buffer_size;
169         }
170
171         if (status > 1) {
172                 drv->recording_count++;
173                 drv->input_front = (drv->input_front + 1) % drv->num_input_buffers;
174         }
175
176         dprintk(("f%d r%d c%d u%d\n",
177                  drv->input_front, drv->input_rear,
178                  drv->input_count, drv->recording_count));
179
180         /* If the input queue is full, shutdown the driver. */
181         if ((drv->input_count + drv->recording_count) == drv->num_input_buffers) {
182                 kill_procs(drv->sd_siglist,SIGPOLL,S_MSG);
183
184                 /* Stop the lowlevel driver from inputing. */
185                 drv->ops->stop_input(drv);
186                 drv->input_active = 0;
187         } else {
188                 /* Otherwise, give the driver the next buffer. */
189                 drv->ops->start_input(drv, drv->input_buffers[drv->input_front],
190                                       drv->input_buffer_size);
191         }
192
193         /* Wake up any tasks that are waiting. */
194         wake_up_interruptible(&drv->input_read_wait);
195 }
196
197 /*
198  *      VFS layer interface
199  */
200
201 static unsigned int sparcaudio_poll(struct file *file, poll_table * wait)
202 {
203         unsigned int mask = 0;
204         struct inode *inode = file->f_dentry->d_inode;
205         struct sparcaudio_driver *drv = drivers[(MINOR(inode->i_rdev) >>
206                                                  SPARCAUDIO_DEVICE_SHIFT)];
207
208         poll_wait(file, &drv->input_read_wait, wait);
209         poll_wait(file, &drv->output_write_wait, wait);
210         if (((!file->f_flags & O_NONBLOCK) && drv->input_count) ||
211             (drv->input_size > drv->buffer_size)) {
212                 mask |= POLLIN | POLLRDNORM;
213         }
214         if ((drv->output_count + drv->playing_count) < (drv->num_output_buffers)) {
215                 mask |= POLLOUT | POLLWRNORM;
216         }
217         return mask;
218 }
219
220 static ssize_t sparcaudio_read(struct file * file, char *buf, 
221                                size_t count, loff_t *ppos)
222 {
223         struct inode *inode = file->f_dentry->d_inode;
224         struct sparcaudio_driver *drv = drivers[(MINOR(inode->i_rdev) >>
225                                                  SPARCAUDIO_DEVICE_SHIFT)];
226         int bytes_to_copy, bytes_read = 0, err;
227
228         if (! (file->f_mode & FMODE_READ))
229                 return -EINVAL;
230
231         if ((file->f_flags & O_NONBLOCK) && (drv->input_size < count))
232                 return -EAGAIN;
233     
234         while (count > 0) {
235                 if (drv->input_count == 0) {
236                         /* This *should* never happen. */
237                         if (file->f_flags & O_NONBLOCK) {
238                                 printk("Warning: audio input leak!\n");
239                                 return -EAGAIN;
240                         }
241                         interruptible_sleep_on(&drv->input_read_wait);
242                         if (signal_pending(current))
243                                 return -EINTR;
244                 }
245   
246                 bytes_to_copy = drv->input_buffer_size - drv->input_offset;
247                 if (bytes_to_copy > count)
248                         bytes_to_copy = count;
249
250                 err = verify_area(VERIFY_WRITE, buf, bytes_to_copy);
251                 if (err)
252                         return err;
253
254                 copy_to_user(buf, drv->input_buffers[drv->input_rear]+drv->input_offset, 
255                              bytes_to_copy);
256
257                 drv->input_offset += bytes_to_copy;
258                 drv->input_size -= bytes_to_copy;
259                 buf += bytes_to_copy;
260                 count -= bytes_to_copy;
261                 bytes_read += bytes_to_copy;
262
263                 if (drv->input_offset >= drv->input_buffer_size) {
264                         drv->input_rear = (drv->input_rear + 1) % 
265                                 drv->num_input_buffers;
266                         drv->input_count--;
267                         drv->input_offset = 0;
268                 }
269
270                 /* If we're in "loop audio" mode, try waking up the other side
271                  * in case they're waiting for us to eat a block. 
272                  */
273                 if (drv->duplex == 2)
274                         wake_up_interruptible(&drv->output_write_wait);
275         }
276
277         return bytes_read;
278 }
279
280 static void sparcaudio_sync_output(struct sparcaudio_driver * drv)
281 {
282         unsigned long flags;
283
284         /* If the low-level driver is not active, activate it. */
285         save_and_cli(flags);
286         if ((!drv->output_active) && (drv->output_count > 0)) {
287                 drv->ops->start_output(drv, 
288                                        drv->output_buffers[drv->output_front],
289                                        drv->output_sizes[drv->output_front]);
290                 drv->output_active = 1;
291         }
292         restore_flags(flags);
293 }
294
295 static ssize_t sparcaudio_write(struct file * file, const char *buf,
296                                 size_t count, loff_t *ppos)
297 {
298         struct inode *inode = file->f_dentry->d_inode;
299         struct sparcaudio_driver *drv = drivers[(MINOR(inode->i_rdev) >>
300                                                  SPARCAUDIO_DEVICE_SHIFT)];
301         int bytes_written = 0, bytes_to_copy, err;
302   
303         if (! (file->f_mode & FMODE_WRITE))
304                 return -EINVAL;
305
306         /* A signal they want notification when this is processed. Too bad
307          * sys_write doesn't tell us unless you patch it, in 2.0 kernels.
308          */
309         if (count == 0) {
310 #ifndef notdef
311                 drv->output_eof++;
312                 kill_procs(drv->sd_siglist,SIGPOLL,S_MSG);
313 #else
314                 /* Nice code, but the world isn't ready yet... */
315                 drv->output_notify[drv->output_rear] = 1;
316 #endif
317         }
318
319         /* Loop until all output is written to device. */
320         while (count > 0) {
321                 /* Check to make sure that an output buffer is available. */
322                 if (drv->num_output_buffers == (drv->output_count+drv->playing_count)) {
323                         /* We need buffers, so... */
324                         sparcaudio_sync_output(drv);
325                         if (file->f_flags & O_NONBLOCK)
326                                 return -EAGAIN;
327
328                         interruptible_sleep_on(&drv->output_write_wait);
329                         if (signal_pending(current))
330                                 return bytes_written > 0 ? bytes_written : -EINTR;
331                 }
332
333                 /* No buffers were freed. Go back to sleep */
334                 if (drv->num_output_buffers == (drv->output_count+drv->playing_count)) 
335                         continue;
336
337                 /* Deal with the weird case of a reader in the write area by trying to
338                  * let them keep ahead of us... Go to sleep until they start servicing.
339                  */
340                 if ((drv->duplex == 2) && (drv->flags & SDF_OPEN_READ) &&
341                     (drv->output_rear == drv->input_rear) && (drv->input_count > 0)) {
342                         if (file->f_flags & O_NONBLOCK)
343                                 return -EAGAIN;
344
345                         interruptible_sleep_on(&drv->output_write_wait);
346                         if (signal_pending(current))
347                                 return bytes_written > 0 ? bytes_written : -EINTR;
348                 }
349
350                 /* Determine how much we can copy in this iteration. */
351                 bytes_to_copy = count;
352                 if (bytes_to_copy > drv->output_buffer_size - drv->output_offset)
353                         bytes_to_copy = drv->output_buffer_size - drv->output_offset;
354     
355                 err = verify_area(VERIFY_READ, buf, bytes_to_copy);
356                 if (err)
357                         return err;
358
359                 copy_from_user(drv->output_buffers[drv->output_rear]+drv->output_offset,
360                                buf, bytes_to_copy);
361     
362                 /* Update the queue pointers. */
363                 buf += bytes_to_copy;
364                 count -= bytes_to_copy;
365                 bytes_written += bytes_to_copy;
366
367                 /* A block can get orphaned in a flush and not cleaned up. */
368                 if (drv->output_offset)
369                         drv->output_sizes[drv->output_rear] += bytes_to_copy;
370                 else
371                         drv->output_sizes[drv->output_rear] = bytes_to_copy;
372
373                 drv->output_notify[drv->output_rear] = 0;
374
375                 if (drv->output_sizes[drv->output_rear] == drv->output_buffer_size) {
376                         drv->output_rear = (drv->output_rear + 1) 
377                                 % drv->num_output_buffers;
378                         drv->output_count++;
379                         drv->output_offset = 0;
380                 } else {
381                         drv->output_offset += bytes_to_copy;
382                 }
383
384                 drv->output_size += bytes_to_copy;
385         }
386
387         sparcaudio_sync_output(drv);
388   
389         /* Return the number of bytes written to the caller. */
390         return bytes_written;
391 }
392
393 /* Add these in as new devices are supported. Belongs in audioio.h, actually */
394 #define MONO_DEVICES (SOUND_MASK_SPEAKER | SOUND_MASK_MIC)
395
396 static int sparcaudio_mixer_ioctl(struct inode * inode, struct file * file,
397                                   unsigned int cmd, unsigned int *arg)
398 {
399         struct sparcaudio_driver *drv = drivers[(MINOR(inode->i_rdev) >>
400                                                  SPARCAUDIO_DEVICE_SHIFT)];
401         unsigned long i = 0, j = 0, l = 0, m = 0;
402         unsigned int k = 0;
403
404         if (_SIOC_DIR(cmd) & _SIOC_WRITE)
405                 drv->mixer_modify_counter++;
406
407         if(cmd == SOUND_MIXER_INFO) {
408                 audio_device_t tmp;
409                 mixer_info info;
410                 int retval = -EINVAL;
411
412                 if(drv->ops->sunaudio_getdev) {
413                         drv->ops->sunaudio_getdev(drv, &tmp);
414                         memset(&info, 0, sizeof(info));
415                         strncpy(info.id, tmp.name, sizeof(info.id));
416                         strncpy(info.name, "Sparc Audio", sizeof(info.name));
417                         info.modify_counter = drv->mixer_modify_counter;
418
419                         if(copy_to_user((char *)arg, &info, sizeof(info)))
420                                 retval = -EFAULT;
421                         else
422                                 retval = 0;
423                 }
424                 return retval;
425   }
426
427         switch (cmd) {
428         case SOUND_MIXER_WRITE_RECLEV:
429                 if (get_user(k, (int *)arg))
430                         return -EFAULT;
431         iretry:
432                 oprintk(("setting input volume (0x%x)", k));
433                 if (drv->ops->get_input_channels)
434                         j = drv->ops->get_input_channels(drv);
435                 if (drv->ops->get_input_volume)
436                         l = drv->ops->get_input_volume(drv);
437                 if (drv->ops->get_input_balance)
438                         m = drv->ops->get_input_balance(drv);
439                 i = OSS_TO_GAIN(k);
440                 j = OSS_TO_BAL(k);
441                 oprintk((" for stereo to do %d (bal %d):", i, j));
442                 if (drv->ops->set_input_volume)
443                         drv->ops->set_input_volume(drv, i);
444                 if (drv->ops->set_input_balance)
445                         drv->ops->set_input_balance(drv, j);
446         case SOUND_MIXER_READ_RECLEV:
447                 if (drv->ops->get_input_volume)
448                         i = drv->ops->get_input_volume(drv);
449                 if (drv->ops->get_input_balance)
450                         j = drv->ops->get_input_balance(drv);
451                 oprintk((" got (0x%x)\n", BAL_TO_OSS(i,j)));
452                 i = BAL_TO_OSS(i,j);
453                 /* Try to be reasonable about volume changes */
454                 if ((cmd == SOUND_MIXER_WRITE_RECLEV) && (i != k) && 
455                     (i == BAL_TO_OSS(l,m))) {
456                         k += (OSS_LEFT(k) > OSS_LEFT(i)) ? 256 : -256;
457                         k += (OSS_RIGHT(k) > OSS_RIGHT(i)) ? 1 : -1;
458                         oprintk((" try 0x%x\n", k));
459                         goto iretry;
460                 }
461                 return put_user(i, (int *)arg);
462         case SOUND_MIXER_WRITE_VOLUME:
463                 if (get_user(k, (int *)arg))
464                         return -EFAULT;
465                 if (drv->ops->get_output_muted && drv->ops->set_output_muted) {
466                         i = drv->ops->get_output_muted(drv);
467                         if ((k == 0) || ((i == 0) && (OSS_LEFT(k) < 100)))
468                                 drv->ops->set_output_muted(drv, 1);
469                         else
470                                 drv->ops->set_output_muted(drv, 0);
471                 }
472         case SOUND_MIXER_READ_VOLUME:
473                 if (drv->ops->get_output_muted) 
474                         i = drv->ops->get_output_muted(drv);
475                 k = 0x6464 * (1 - i);
476                 return put_user(k, (int *)arg);
477         case SOUND_MIXER_WRITE_PCM:
478                 if (get_user(k, (int *)arg))
479                         return -EFAULT;
480         oretry:
481                 oprintk(("setting output volume (0x%x)\n", k));
482                 if (drv->ops->get_output_channels)
483                         j = drv->ops->get_output_channels(drv);
484                 if (drv->ops->get_output_volume)
485                         l = drv->ops->get_output_volume(drv);
486                 if (drv->ops->get_output_balance)
487                         m = drv->ops->get_output_balance(drv);
488                 oprintk((" started as (0x%x)\n", BAL_TO_OSS(l,m)));
489                 i = OSS_TO_GAIN(k);
490                 j = OSS_TO_BAL(k);
491                 oprintk((" for stereo to %d (bal %d)\n", i, j));
492                 if (drv->ops->set_output_volume)
493                         drv->ops->set_output_volume(drv, i);
494                 if (drv->ops->set_output_balance)
495                         drv->ops->set_output_balance(drv, j);
496         case SOUND_MIXER_READ_PCM:
497                 if (drv->ops->get_output_volume)
498                         i = drv->ops->get_output_volume(drv);
499                 if (drv->ops->get_output_balance)
500                         j = drv->ops->get_output_balance(drv);
501                 oprintk((" got 0x%x\n", BAL_TO_OSS(i,j)));
502                 i = BAL_TO_OSS(i,j);
503
504                 /* Try to be reasonable about volume changes */
505                 if ((cmd == SOUND_MIXER_WRITE_PCM) && (i != k) && 
506                     (i == BAL_TO_OSS(l,m))) {
507                         k += (OSS_LEFT(k) > OSS_LEFT(i)) ? 256 : -256;
508                         k += (OSS_RIGHT(k) > OSS_RIGHT(i)) ? 1 : -1;
509                         oprintk((" try 0x%x\n", k));
510                         goto oretry;
511                 }
512                 return put_user(i, (int *)arg);
513         case SOUND_MIXER_READ_SPEAKER:
514                 k = OSS_PORT_AUDIO(drv, AUDIO_SPEAKER);
515                 return put_user(k, (int *)arg);
516         case SOUND_MIXER_READ_MIC:
517                 k = OSS_IPORT_AUDIO(drv, AUDIO_MICROPHONE);
518                 return put_user(k, (int *)arg);
519         case SOUND_MIXER_READ_CD:
520                 k = OSS_IPORT_AUDIO(drv, AUDIO_CD);
521                 return put_user(k, (int *)arg);
522         case SOUND_MIXER_READ_LINE:
523                 k = OSS_IPORT_AUDIO(drv, AUDIO_LINE_IN);
524                 return put_user(k, (int *)arg);
525         case SOUND_MIXER_READ_LINE1:
526                 k = OSS_PORT_AUDIO(drv, AUDIO_HEADPHONE);
527                 return put_user(k, (int *)arg);
528         case SOUND_MIXER_READ_LINE2:
529                 k = OSS_PORT_AUDIO(drv, AUDIO_LINE_OUT);
530                 return put_user(k, (int *)arg);
531
532         case SOUND_MIXER_WRITE_MIC:
533         case SOUND_MIXER_WRITE_CD:
534         case SOUND_MIXER_WRITE_LINE:
535         case SOUND_MIXER_WRITE_LINE1:
536         case SOUND_MIXER_WRITE_LINE2:
537         case SOUND_MIXER_WRITE_SPEAKER:
538                 if (get_user(k, (int *)arg))
539                         return -EFAULT;
540                 OSS_TWIDDLE_IPORT(drv, cmd, SOUND_MIXER_WRITE_LINE, AUDIO_LINE_IN, k);
541                 OSS_TWIDDLE_IPORT(drv, cmd, SOUND_MIXER_WRITE_MIC, AUDIO_MICROPHONE, k);
542                 OSS_TWIDDLE_IPORT(drv, cmd, SOUND_MIXER_WRITE_CD, AUDIO_CD, k);
543
544                 OSS_TWIDDLE_PORT(drv, cmd, SOUND_MIXER_WRITE_SPEAKER, AUDIO_SPEAKER, k);
545                 OSS_TWIDDLE_PORT(drv, cmd, SOUND_MIXER_WRITE_LINE1, AUDIO_HEADPHONE, k);
546                 OSS_TWIDDLE_PORT(drv, cmd, SOUND_MIXER_WRITE_LINE2, AUDIO_LINE_OUT, k);
547                 return put_user(k, (int *)arg);
548         case SOUND_MIXER_READ_RECSRC: 
549                 if (drv->ops->get_input_port)
550                         i = drv->ops->get_input_port(drv);
551
552                 /* only one should ever be selected */
553                 if (i & AUDIO_CD) j = SOUND_MASK_CD;
554                 if (i & AUDIO_LINE_IN) j = SOUND_MASK_LINE;
555                 if (i & AUDIO_MICROPHONE) j = SOUND_MASK_MIC;
556     
557                 return put_user(j, (int *)arg);
558   case SOUND_MIXER_WRITE_RECSRC: 
559           if (!drv->ops->set_input_port)
560                   return -EINVAL;
561           if (get_user(k, (int *)arg))
562                   return -EFAULT;
563
564           /* only one should ever be selected */
565           if (k & SOUND_MASK_CD) j = AUDIO_CD;
566           if (k & SOUND_MASK_LINE) j = AUDIO_LINE_IN;
567           if (k & SOUND_MASK_MIC) j = AUDIO_MICROPHONE;
568           oprintk(("setting inport to %d\n", j));
569           i = drv->ops->set_input_port(drv, j);
570     
571           return put_user(i, (int *)arg);
572         case SOUND_MIXER_READ_RECMASK: 
573                 if (drv->ops->get_input_ports)
574                         i = drv->ops->get_input_ports(drv);
575                 /* what do we support? */
576                 if (i & AUDIO_MICROPHONE) j |= SOUND_MASK_MIC;
577                 if (i & AUDIO_LINE_IN) j |= SOUND_MASK_LINE;
578                 if (i & AUDIO_CD) j |= SOUND_MASK_CD;
579     
580                 return put_user(j, (int *)arg);
581         case SOUND_MIXER_READ_CAPS: /* mixer capabilities */
582                 i = SOUND_CAP_EXCL_INPUT;
583                 return put_user(i, (int *)arg);
584
585         case SOUND_MIXER_READ_DEVMASK: /* all supported devices */
586                 if (drv->ops->get_input_ports)
587                         i = drv->ops->get_input_ports(drv);
588                 /* what do we support? */
589                 if (i & AUDIO_MICROPHONE) j |= SOUND_MASK_MIC;
590                 if (i & AUDIO_LINE_IN) j |= SOUND_MASK_LINE;
591                 if (i & AUDIO_CD) j |= SOUND_MASK_CD;
592     
593                 if (drv->ops->get_output_ports)
594                         i = drv->ops->get_output_ports(drv);
595                 if (i & AUDIO_SPEAKER) j |= SOUND_MASK_SPEAKER;
596                 if (i & AUDIO_HEADPHONE) j |= SOUND_MASK_LINE1;
597                 if (i & AUDIO_LINE_OUT) j |= SOUND_MASK_LINE2;
598
599                 j |= SOUND_MASK_VOLUME;
600
601         case SOUND_MIXER_READ_STEREODEVS: /* what supports stereo */
602                 j |= SOUND_MASK_PCM|SOUND_MASK_RECLEV;
603
604                 if (cmd == SOUND_MIXER_READ_STEREODEVS)
605                         j &= ~(MONO_DEVICES);
606                 return put_user(j, (int *)arg);
607         default:
608                 return -EINVAL;
609         };
610 }
611
612 /* AUDIO_SETINFO uses these to set values if possible. */
613 static __inline__ int 
614 __sparcaudio_if_set_do(struct sparcaudio_driver *drv, 
615                        int (*set_function)(struct sparcaudio_driver *, int), 
616                        int (*get_function)(struct sparcaudio_driver *), 
617                        unsigned int value)
618 {
619         if (set_function && Modify(value))
620                 return (int) set_function(drv, value);
621         else if (get_function)
622                 return (int) get_function(drv);
623         else 
624                 return 0;
625 }
626
627 static __inline__ int 
628 __sparcaudio_if_setc_do(struct sparcaudio_driver *drv, 
629                         int (*set_function)(struct sparcaudio_driver *, int), 
630                         int (*get_function)(struct sparcaudio_driver *), 
631                         unsigned char value)
632 {
633         if (set_function && Modifyc(value))
634                 return (char) set_function(drv, (int)value);
635         else if (get_function)
636                 return (char) get_function(drv);
637         else 
638                 return 0;
639 }
640
641 /* I_FLUSH, I_{G,S}ETSIG, I_NREAD provided for SunOS compatibility
642  *
643  * I must admit I'm quite ashamed of the state of the ioctl handling,
644  * but I do have several optimizations which I'm planning. -- DJB
645  */
646 static int sparcaudio_ioctl(struct inode * inode, struct file * file,
647                             unsigned int cmd, unsigned long arg)
648 {
649         int retval = 0, i, j, k;
650         int minor = MINOR(inode->i_rdev);
651         struct audio_info ainfo;
652         audio_buf_info binfo;
653         count_info cinfo;
654         struct sparcaudio_driver *drv = 
655                 drivers[(minor >> SPARCAUDIO_DEVICE_SHIFT)];
656
657         switch (minor & 0xf) {
658         case SPARCAUDIO_MIXER_MINOR:
659                 return sparcaudio_mixer_ioctl(inode, file, cmd, (unsigned int *)arg);
660         case SPARCAUDIO_DSP16_MINOR:
661         case SPARCAUDIO_DSP_MINOR:
662         case SPARCAUDIO_AUDIO_MINOR:
663         case SPARCAUDIO_AUDIOCTL_MINOR:
664                 /* According to the OSS prog int, you can mixer ioctl /dev/dsp */
665                 if (_IOC_TYPE(cmd) == 'M')
666                         return sparcaudio_mixer_ioctl(inode, 
667                                                       file, cmd, (unsigned int *)arg);
668                 switch (cmd) {
669                 case I_GETSIG:
670                 case I_GETSIG_SOLARIS:
671                         j = (int) lis_get_elist_ent(drv->sd_siglist,current->pid);
672                         put_user(j, (int *)arg);
673                         retval = drv->input_count;
674                         break;
675
676                 case I_SETSIG:
677                 case I_SETSIG_SOLARIS:
678                         if ((minor & 0xf) == SPARCAUDIO_AUDIOCTL_MINOR) {
679                                 if (!arg) {
680                                         if (lis_del_from_elist(&(drv->sd_siglist),
681                                                                current->pid,S_ALL)) {
682                                                 retval = -EINVAL;
683                                         } else if (!drv->sd_siglist) {
684                                                 drv->sd_sigflags=0;
685                                         }
686                                 } else if (lis_add_to_elist(&(drv->sd_siglist),
687                                                             current->pid,
688                                                             (short)arg)) {
689                                         retval = -EAGAIN;
690                                 } else {
691                                         ((drv->sd_sigflags) |= (arg));
692                                 }
693                         }
694                         break;
695                 case I_NREAD:
696                 case I_NREAD_SOLARIS:
697                         /* According to the Solaris man page, this copies out
698                          * the size of the first streams buffer and returns 
699                          * the number of streams messages on the read queue as
700                          * as its retval. (streamio(7I)) This should work.
701                          */
702                         j = (drv->input_count > 0) ? drv->input_buffer_size : 0;
703                         put_user(j, (int *)arg);
704                         retval = drv->input_count;
705                         break;
706
707                         /* A poor substitute until we do true resizable buffers. */
708                 case SNDCTL_DSP_GETISPACE:
709                         binfo.fragstotal = drv->num_input_buffers;
710                         binfo.fragments = drv->num_input_buffers - 
711                                 (drv->input_count + drv->recording_count);
712                         binfo.fragsize = drv->input_buffer_size;
713                         binfo.bytes = binfo.fragments*binfo.fragsize;
714             
715                         retval = verify_area(VERIFY_WRITE, (int *)arg, sizeof(binfo));
716                         if (retval)
717                                 break;
718                         copy_to_user(&((char *)arg)[0], (char *)&binfo, sizeof(binfo));
719                         break;
720                 case SNDCTL_DSP_GETOSPACE:
721                         binfo.fragstotal = drv->num_output_buffers;
722                         binfo.fragments = drv->num_output_buffers - 
723                                 (drv->output_count + drv->playing_count + 
724                                  (drv->output_offset ? 1 : 0));
725                         binfo.fragsize = drv->output_buffer_size;
726                         binfo.bytes = binfo.fragments*binfo.fragsize + 
727                                 (drv->output_buffer_size - drv->output_offset);
728             
729                         retval = verify_area(VERIFY_WRITE, (int *)arg, sizeof(binfo));
730                         if (retval)
731                                 break;
732                         copy_to_user(&((char *)arg)[0], (char *)&binfo, sizeof(binfo));
733                         break;
734                 case SNDCTL_DSP_GETIPTR:
735                 case SNDCTL_DSP_GETOPTR:
736                         /* int bytes (number of bytes read/written since last)
737                          * int blocks (number of frags read/wrote since last call)
738                          * int ptr (current position of dma in buffer)
739                          */
740                         retval = 0;
741                         cinfo.bytes = 0;
742                         cinfo.ptr = 0;
743                         cinfo.blocks = 0;
744                         cinfo.bytes += cinfo.ptr;
745             
746                         retval = verify_area(VERIFY_WRITE, (int *)arg, sizeof(cinfo));
747                         if (retval)
748                                 break;
749                         copy_to_user(&((char *)arg)[0], (char *)&cinfo, sizeof(cinfo));
750                         break;
751                 case SNDCTL_DSP_SETFRAGMENT:
752                         /* XXX Small hack to get ESD/Enlightenment to work.  --DaveM */
753                         retval = 0;
754                         break;
755
756                 case SNDCTL_DSP_SUBDIVIDE:
757                         /* I don't understand what I need to do yet. */
758                         retval = -EINVAL;
759                         break;
760                 case SNDCTL_DSP_SETTRIGGER:
761                         /* This may not be 100% correct */
762                         if ((arg & PCM_ENABLE_INPUT) && drv->ops->get_input_pause &&
763                             drv->ops->set_input_pause) {
764                                 if (drv->ops->get_input_pause(drv))
765                                         drv->ops->set_input_pause(drv, 0);
766                         } else {
767                                 if (!drv->ops->get_input_pause(drv))
768                                         drv->ops->set_input_pause(drv, 1);
769                         }
770                         if ((arg & PCM_ENABLE_OUTPUT) && drv->ops->get_output_pause &&
771                             drv->ops->set_output_pause) {
772                                 if (drv->ops->get_output_pause(drv))
773                                         drv->ops->set_output_pause(drv, 0);
774                         } else {
775                                 if (!drv->ops->get_output_pause(drv))
776                                         drv->ops->set_output_pause(drv, 1);
777                         }
778                         break;
779                 case SNDCTL_DSP_GETTRIGGER:
780                         j = 0;
781                         if (drv->ops->get_input_pause) {
782                                 if (drv->ops->get_input_pause(drv))
783                                         j = PCM_ENABLE_INPUT;
784                         }
785                         if (drv->ops->get_output_pause) {
786                                 if (drv->ops->get_output_pause(drv))
787                                         j |= PCM_ENABLE_OUTPUT;
788                         }
789                         put_user(j, (int *)arg);
790                         break;
791                 case SNDCTL_DSP_GETBLKSIZE:
792                         j = drv->input_buffer_size;
793                         put_user(j, (int *)arg);
794                         break;
795                 case SNDCTL_DSP_SPEED:
796                         if ((!drv->ops->set_output_rate) && 
797                             (!drv->ops->set_input_rate)) {
798                                 retval = -EINVAL;
799                                 break;
800                         }
801                         get_user(i, (int *)arg)
802                         tprintk(("setting speed to %d\n", i));
803                         drv->ops->set_input_rate(drv, i);
804                         drv->ops->set_output_rate(drv, i);
805                         j = drv->ops->get_output_rate(drv);
806                         put_user(j, (int *)arg);
807                         break;
808                 case SNDCTL_DSP_GETCAPS:
809                         /* All Sparc audio hardware is full duplex.
810                          * 4231 supports DMA pointer reading, 7930 is byte at a time.
811                          * Pause functionality emulates trigger
812                          */
813                         j = DSP_CAP_DUPLEX | DSP_CAP_TRIGGER | DSP_CAP_REALTIME;
814                         put_user(j, (int *)arg);
815                         break;
816                 case SNDCTL_DSP_GETFMTS:
817                         if (drv->ops->get_formats) {
818                                 j = drv->ops->get_formats(drv);
819                                 put_user(j, (int *)arg);
820                         } else {
821                                 retval = -EINVAL;
822                         }
823                         break;
824                 case SNDCTL_DSP_SETFMT:
825                         /* need to decode into encoding, precision */
826                         get_user(i, (int *)arg);
827             
828                         /* handle special case here */
829                         if (i == AFMT_QUERY) {
830                                 j = drv->ops->get_output_encoding(drv);
831                                 k = drv->ops->get_output_precision(drv);
832                                 if (j == AUDIO_ENCODING_DVI) {
833                                         i = AFMT_IMA_ADPCM;
834                                 } else if (k == 8) {
835                                         switch (j) {
836                                         case AUDIO_ENCODING_ULAW:
837                                                 i = AFMT_MU_LAW;
838                                                 break;
839                                         case AUDIO_ENCODING_ALAW:
840                                                 i = AFMT_A_LAW;
841                                                 break;
842                                         case AUDIO_ENCODING_LINEAR8:
843                                                 i = AFMT_U8;
844                                                 break;
845                                         };
846                                 } else if (k == 16) {
847                                         switch (j) {
848                                         case AUDIO_ENCODING_LINEAR:
849                                                 i = AFMT_S16_BE;
850                                                 break;
851                                         case AUDIO_ENCODING_LINEARLE:
852                                                 i = AFMT_S16_LE;
853                                                 break;
854                                         };
855                                 } 
856                                 put_user(i, (int *)arg);
857                                 break;
858                         }
859
860                         /* Without these there's no point in trying */
861                         if (!drv->ops->set_input_precision ||
862                             !drv->ops->set_input_encoding ||
863                             !drv->ops->set_output_precision ||
864                             !drv->ops->set_output_encoding) {
865                                 eprintk(("missing set routines: failed\n"));
866                                 retval = -EINVAL;
867                                 break;
868                         }
869
870                         if (drv->ops->get_formats) {
871                                 if (!(drv->ops->get_formats(drv) & i)) {
872                                         dprintk(("format not supported\n"));
873                                         return -EINVAL;
874                                 }
875                         }
876                         switch (i) {
877                         case AFMT_S16_LE:
878                                 ainfo.record.precision = ainfo.play.precision = 16;
879                                 ainfo.record.encoding = ainfo.play.encoding =
880                                         AUDIO_ENCODING_LINEARLE;
881                                 break;
882                         case AFMT_S16_BE:
883                                 ainfo.record.precision = ainfo.play.precision = 16;
884                                 ainfo.record.encoding = ainfo.play.encoding =
885                                         AUDIO_ENCODING_LINEAR;
886                                 break;
887                         case AFMT_MU_LAW:
888                                 ainfo.record.precision = ainfo.play.precision = 8;
889                                 ainfo.record.encoding = ainfo.play.encoding =
890                                         AUDIO_ENCODING_ULAW;
891                                 break;
892                         case AFMT_A_LAW:
893                                 ainfo.record.precision = ainfo.play.precision = 8;
894                                 ainfo.record.encoding = ainfo.play.encoding =
895                                         AUDIO_ENCODING_ALAW;
896                                 break;
897                         case AFMT_U8:
898                                 ainfo.record.precision = ainfo.play.precision = 8;
899                                 ainfo.record.encoding = ainfo.play.encoding =
900                                         AUDIO_ENCODING_LINEAR8;
901                                 break;
902                         };
903                         tprintk(("setting fmt to enc %d pr %d\n",
904                                  ainfo.play.encoding,
905                                  ainfo.play.precision));
906                         if ((drv->ops->set_input_precision(drv,
907                                                            ainfo.record.precision) 
908                              < 0) ||
909                             (drv->ops->set_output_precision(drv,
910                                                             ainfo.play.precision)  
911                              < 0) ||
912                             (drv->ops->set_input_encoding(drv,
913                                                           ainfo.record.encoding)
914                              < 0) ||
915                             (drv->ops->set_output_encoding(drv,
916                                                            ainfo.play.encoding)
917                              < 0)) {
918                                 dprintk(("setting format: failed\n"));
919                                 return -EINVAL;
920                         }
921                         put_user(i, (int *)arg);
922                         break;
923                 case SNDCTL_DSP_CHANNELS:
924                         if ((!drv->ops->set_output_channels) && 
925                             (!drv->ops->set_input_channels)) {
926                                 retval = -EINVAL;
927                                 break;
928                         }
929                         get_user(i, (int *)arg);
930                         drv->ops->set_input_channels(drv, i);
931                         drv->ops->set_output_channels(drv, i);
932                         i = drv->ops->get_output_channels(drv);
933                         put_user(i, (int *)arg);
934                         break;
935                 case SNDCTL_DSP_STEREO:
936                         if ((!drv->ops->set_output_channels) && 
937                             (!drv->ops->set_input_channels)) {
938                                 retval = -EINVAL;
939                                 break;
940                         }
941                         get_user(i, (int *)arg);
942                         drv->ops->set_input_channels(drv, (i + 1));
943                         drv->ops->set_output_channels(drv, (i + 1));
944                         i = ((drv->ops->get_output_channels(drv)) - 1);
945                         put_user(i, (int *)arg);
946                         break;
947                 case SNDCTL_DSP_POST:
948                 case SNDCTL_DSP_SYNC:
949                 case AUDIO_DRAIN:
950                         /* Deal with weirdness so we can fill buffers */
951                         if (drv->output_offset) {
952                                 drv->output_offset = 0;
953                                 drv->output_rear = (drv->output_rear + 1)
954                                         % drv->num_output_buffers;
955                                 drv->output_count++;
956                         }
957                         if (drv->output_count > 0) {
958                                 sparcaudio_sync_output(drv);
959                                 /* Only pause for DRAIN/SYNC, not POST */
960                                 if (cmd != SNDCTL_DSP_POST) {
961                                         interruptible_sleep_on(&drv->output_drain_wait);
962                                         retval = (signal_pending(current)) ? -EINTR : 0;
963                                 }
964                         }
965                         break;
966                 case I_FLUSH:
967                 case I_FLUSH_SOLARIS:
968                         if (((unsigned int)arg == FLUSHW) || 
969                             ((unsigned int)arg == FLUSHRW)) {
970                                 if (file->f_mode & FMODE_WRITE) {
971                                         sparcaudio_sync_output(drv);
972                                         if (drv->output_active) {
973                                                 wake_up_interruptible(&drv->output_write_wait);
974                                                 drv->ops->stop_output(drv);
975                                         }
976                                         drv->output_offset = 0;
977                                         drv->output_active = 0;
978                                         drv->output_front = 0;
979                                         drv->output_rear = 0;
980                                         drv->output_count = 0;
981                                         drv->output_size = 0;
982                                         drv->playing_count = 0;
983                                         drv->output_eof = 0;
984                                 }
985                         }
986                         if (((unsigned int)arg == FLUSHR) || 
987                             ((unsigned int)arg == FLUSHRW)) {
988                                 if (drv->input_active && (file->f_mode & FMODE_READ)) {
989                                         wake_up_interruptible(&drv->input_read_wait);
990                                         drv->ops->stop_input(drv);
991                                         drv->input_active = 0;
992                                         drv->input_front = 0;
993                                         drv->input_rear = 0;
994                                         drv->input_count = 0;
995                                         drv->input_size = 0;
996                                         drv->input_offset = 0;
997                                         drv->recording_count = 0;
998                                 }
999                                 if ((file->f_mode & FMODE_READ) && 
1000                                     (drv->flags & SDF_OPEN_READ)) {
1001                                         if (drv->duplex == 2)
1002                                                 drv->input_count = drv->output_count;
1003                                         drv->ops->start_input(drv, 
1004                                                               drv->input_buffers[drv->input_front],
1005                                                               drv->input_buffer_size);
1006                                         drv->input_active = 1;
1007                                 }
1008                         }
1009                         if (((unsigned int)arg == FLUSHW) || 
1010                             ((unsigned int)arg == FLUSHRW)) {
1011                                 if ((file->f_mode & FMODE_WRITE) && 
1012                                     !(drv->flags & SDF_OPEN_WRITE)) {
1013                                         kill_procs(drv->sd_siglist,SIGPOLL,S_MSG);
1014                                         sparcaudio_sync_output(drv);
1015                                 }
1016                         }
1017                         break;
1018                 case SNDCTL_DSP_RESET:
1019                 case AUDIO_FLUSH:
1020                         if (drv->output_active && (file->f_mode & FMODE_WRITE)) {
1021                                 wake_up_interruptible(&drv->output_write_wait);
1022                                 drv->ops->stop_output(drv);
1023                                 drv->output_active = 0;
1024                                 drv->output_front = 0;
1025                                 drv->output_rear = 0;
1026                                 drv->output_count = 0;
1027                                 drv->output_size = 0;
1028                                 drv->playing_count = 0;
1029                                 drv->output_offset = 0;
1030                                 drv->output_eof = 0;
1031                         }
1032                         if (drv->input_active && (file->f_mode & FMODE_READ)) {
1033                                 wake_up_interruptible(&drv->input_read_wait);
1034                                 drv->ops->stop_input(drv);
1035                                 drv->input_active = 0;
1036                                 drv->input_front = 0;
1037                                 drv->input_rear = 0;
1038                                 drv->input_count = 0;
1039                                 drv->input_size = 0;
1040                                 drv->input_offset = 0;
1041                                 drv->recording_count = 0;
1042                         }
1043                         if ((file->f_mode & FMODE_READ) && 
1044                             !(drv->flags & SDF_OPEN_READ)) {
1045                                 drv->ops->start_input(drv, 
1046                                                       drv->input_buffers[drv->input_front],
1047                                                       drv->input_buffer_size);
1048                                 drv->input_active = 1;
1049                         }
1050                         if ((file->f_mode & FMODE_WRITE) && 
1051                             !(drv->flags & SDF_OPEN_WRITE)) {
1052                                 sparcaudio_sync_output(drv);
1053                         }
1054                         break;
1055                 case AUDIO_GETDEV:
1056                         if (drv->ops->sunaudio_getdev) {
1057                                 audio_device_t tmp;
1058               
1059                                 retval = verify_area(VERIFY_WRITE, (void *)arg, 
1060                                                      sizeof(audio_device_t));
1061                                 if (!retval)
1062                                         drv->ops->sunaudio_getdev(drv, &tmp);
1063                                 copy_to_user((audio_device_t *)arg, &tmp, sizeof(tmp));
1064                         } else {
1065                                 retval = -EINVAL;
1066                         }
1067                         break;
1068                 case AUDIO_GETDEV_SUNOS:
1069                         if (drv->ops->sunaudio_getdev_sunos) {
1070                                 int tmp = drv->ops->sunaudio_getdev_sunos(drv);
1071
1072                                 retval = verify_area(VERIFY_WRITE, (void *)arg, sizeof(int));
1073                                 if (!retval)
1074                                         copy_to_user((int *)arg, &tmp, sizeof(tmp));
1075                         } else {
1076                                 retval = -EINVAL;
1077                         }
1078                         break;
1079                 case AUDIO_GETINFO:
1080                         AUDIO_INITINFO(&ainfo);
1081
1082                         if (drv->ops->get_input_rate)
1083                                 ainfo.record.sample_rate =
1084                                         drv->ops->get_input_rate(drv);
1085                         else
1086                                 ainfo.record.sample_rate = (8000);
1087                         if (drv->ops->get_input_channels)
1088                                 ainfo.record.channels =
1089                                         drv->ops->get_input_channels(drv);
1090                         else
1091                                 ainfo.record.channels = (1);
1092                         if (drv->ops->get_input_precision)
1093                                 ainfo.record.precision =
1094                                         drv->ops->get_input_precision(drv);
1095                         else
1096                                 ainfo.record.precision = (8);
1097                         if (drv->ops->get_input_encoding)
1098                                 ainfo.record.encoding =
1099                                         drv->ops->get_input_encoding(drv);
1100                         else
1101                                 ainfo.record.encoding = (AUDIO_ENCODING_ULAW);
1102                         if (drv->ops->get_input_volume)
1103                                 ainfo.record.gain =
1104                                         drv->ops->get_input_volume(drv);
1105                         else
1106                                 ainfo.record.gain = (0);
1107                         if (drv->ops->get_input_port)
1108                                 ainfo.record.port =
1109                                         drv->ops->get_input_port(drv);
1110                         else
1111                                 ainfo.record.port = (0);
1112                         if (drv->ops->get_input_ports)
1113                                 ainfo.record.avail_ports = 
1114                                         drv->ops->get_input_ports(drv);
1115                         else
1116                                 ainfo.record.avail_ports = (0);
1117
1118                         /* To make e.g. vat happy, we let them think they control this */
1119                         ainfo.record.buffer_size = drv->buffer_size;
1120                         if (drv->ops->get_input_samples)
1121                                 ainfo.record.samples = drv->ops->get_input_samples(drv);
1122                         else
1123                                 ainfo.record.samples = 0;
1124
1125                         /* This is undefined in the record context in Solaris */
1126                         ainfo.record.eof = 0;
1127                         if (drv->ops->get_input_pause)
1128                                 ainfo.record.pause =
1129                                         drv->ops->get_input_pause(drv);
1130                         else
1131                                 ainfo.record.pause = 0;
1132                         if (drv->ops->get_input_error)
1133                                 ainfo.record.error = 
1134                                         (unsigned char) drv->ops->get_input_error(drv);
1135                         else
1136                                 ainfo.record.error = 0;
1137                         ainfo.record.waiting = 0;
1138                         if (drv->ops->get_input_balance)
1139                                 ainfo.record.balance =
1140                                         (unsigned char) drv->ops->get_input_balance(drv);
1141                         else
1142                                 ainfo.record.balance = (unsigned char)(AUDIO_MID_BALANCE);
1143                         ainfo.record.minordev = 4 + (minor << SPARCAUDIO_DEVICE_SHIFT);
1144                         ainfo.record.open = (drv->flags & SDF_OPEN_READ);
1145                         ainfo.record.active = 0;
1146
1147                         if (drv->ops->get_output_rate)
1148                                 ainfo.play.sample_rate =
1149                                         drv->ops->get_output_rate(drv);
1150                         else
1151                                 ainfo.play.sample_rate = (8000);
1152                         if (drv->ops->get_output_channels)
1153                                 ainfo.play.channels =
1154                                         drv->ops->get_output_channels(drv);
1155                         else
1156                                 ainfo.play.channels = (1);
1157                         if (drv->ops->get_output_precision)
1158                                 ainfo.play.precision =
1159                                         drv->ops->get_output_precision(drv);
1160                         else
1161                                 ainfo.play.precision = (8);
1162                         if (drv->ops->get_output_encoding)
1163                                 ainfo.play.encoding =
1164                                         drv->ops->get_output_encoding(drv);
1165                         else
1166                                 ainfo.play.encoding = (AUDIO_ENCODING_ULAW);
1167                         if (drv->ops->get_output_volume)
1168                                 ainfo.play.gain =
1169                                         drv->ops->get_output_volume(drv);
1170                         else
1171                                 ainfo.play.gain = (0);
1172                         if (drv->ops->get_output_port)
1173                                 ainfo.play.port =
1174                                         drv->ops->get_output_port(drv);
1175                         else
1176                                 ainfo.play.port = (0);
1177                         if (drv->ops->get_output_ports)
1178                                 ainfo.play.avail_ports = 
1179                                         drv->ops->get_output_ports(drv);
1180                         else
1181                                 ainfo.play.avail_ports = (0);
1182
1183                         /* This is not defined in the play context in Solaris */
1184                         ainfo.play.buffer_size = 0;
1185                         if (drv->ops->get_output_samples)
1186                                 ainfo.play.samples = drv->ops->get_output_samples(drv);
1187                         else
1188                                 ainfo.play.samples = 0;
1189                         ainfo.play.eof = drv->output_eof;
1190                         if (drv->ops->get_output_pause)
1191                                 ainfo.play.pause =
1192                                         drv->ops->get_output_pause(drv);
1193                         else
1194                                 ainfo.play.pause = 0;
1195                         if (drv->ops->get_output_error)
1196                                 ainfo.play.error =
1197                                         (unsigned char)drv->ops->get_output_error(drv);
1198                         else
1199                                 ainfo.play.error = 0;
1200                         ainfo.play.waiting = waitqueue_active(&drv->open_wait);
1201                         if (drv->ops->get_output_balance)
1202                                 ainfo.play.balance =
1203                                         (unsigned char)drv->ops->get_output_balance(drv);
1204                         else
1205                                 ainfo.play.balance = (unsigned char)(AUDIO_MID_BALANCE);
1206                         ainfo.play.minordev = 4 + (minor << SPARCAUDIO_DEVICE_SHIFT);
1207                         ainfo.play.open = (drv->flags & SDF_OPEN_WRITE);
1208                         ainfo.play.active = drv->output_active;
1209             
1210                         if (drv->ops->get_monitor_volume)
1211                                 ainfo.monitor_gain =
1212                                         drv->ops->get_monitor_volume(drv);
1213                         else
1214                                 ainfo.monitor_gain = (0);
1215
1216                         if (drv->ops->get_output_muted)
1217                                 ainfo.output_muted = 
1218                                         (unsigned char)drv->ops->get_output_muted(drv);
1219                         else
1220                                 ainfo.output_muted = (unsigned char)(0);
1221
1222                         retval = verify_area(VERIFY_WRITE, (void *)arg,
1223                                              sizeof(struct audio_info));
1224                         if (retval < 0)
1225                                 break;
1226
1227                         copy_to_user((struct audio_info *)arg, &ainfo, sizeof(ainfo));
1228                         break;
1229                 case AUDIO_SETINFO:
1230                 {
1231                         audio_info_t curinfo, newinfo;
1232               
1233                         if (verify_area(VERIFY_READ, (audio_info_t *)arg, 
1234                                         sizeof(audio_info_t))) {
1235                                 dprintk(("verify_area failed\n"));
1236                                 return -EINVAL;
1237                         }
1238                         copy_from_user(&ainfo, (audio_info_t *)arg, sizeof(audio_info_t));
1239
1240                         /* Without these there's no point in trying */
1241                         if (!drv->ops->get_input_precision ||
1242                             !drv->ops->get_input_channels ||
1243                             !drv->ops->get_input_rate ||
1244                             !drv->ops->get_input_encoding ||
1245                             !drv->ops->get_output_precision ||
1246                             !drv->ops->get_output_channels ||
1247                             !drv->ops->get_output_rate ||
1248                             !drv->ops->get_output_encoding) {
1249                                 eprintk(("missing get routines: failed\n"));
1250                                 retval = -EINVAL;
1251                                 break;
1252                         }
1253
1254                         /* Do bounds checking for things which always apply.
1255                          * Follow with enforcement of basic tenets of certain
1256                          * encodings. Everything over and above generic is
1257                          * enforced by the driver, which can assume that
1258                          * Martian cases are taken care of here.
1259                          */
1260                         if (Modify(ainfo.play.gain) && 
1261                             ((ainfo.play.gain > AUDIO_MAX_GAIN) || 
1262                              (ainfo.play.gain < AUDIO_MIN_GAIN))) {
1263                                 /* Need to differentiate this from e.g. the above error */
1264                                 eprintk(("play gain bounds: failed %d\n", ainfo.play.gain));
1265                                 retval = -EINVAL;
1266                                 break;
1267                         }
1268                         if (Modify(ainfo.record.gain) &&
1269                             ((ainfo.record.gain > AUDIO_MAX_GAIN) ||
1270                              (ainfo.record.gain < AUDIO_MIN_GAIN))) {
1271                                 eprintk(("rec gain bounds: failed %d\n", ainfo.record.gain));
1272                                 retval = -EINVAL;
1273                                 break;
1274                         }
1275                         if (Modify(ainfo.monitor_gain) &&
1276                             ((ainfo.monitor_gain > AUDIO_MAX_GAIN) ||
1277                              (ainfo.monitor_gain < AUDIO_MIN_GAIN))) {
1278                                 eprintk(("monitor gain bounds: failed\n"));
1279                                 retval = -EINVAL;
1280                                 break;
1281                         }
1282
1283                         /* Don't need to check less than zero on these */
1284                         if (Modifyc(ainfo.play.balance) &&
1285                             (ainfo.play.balance > AUDIO_RIGHT_BALANCE)) {
1286                                 eprintk(("play balance bounds: %d failed\n", 
1287                                          (int)ainfo.play.balance));
1288                                 retval = -EINVAL;
1289                                 break;
1290                         }
1291                         if (Modifyc(ainfo.record.balance) &&
1292                             (ainfo.record.balance > AUDIO_RIGHT_BALANCE)) {
1293                                 eprintk(("rec balance bounds: failed\n"));
1294                                 retval = -EINVAL;
1295                                 break;
1296                         }
1297               
1298                         /* If any of these changed, record them all, then make
1299                          * changes atomically. If something fails, back it all out.
1300                          */
1301                         if (Modify(ainfo.record.precision) || 
1302                             Modify(ainfo.record.sample_rate) ||
1303                             Modify(ainfo.record.channels) ||
1304                             Modify(ainfo.record.encoding) || 
1305                             Modify(ainfo.play.precision) || 
1306                             Modify(ainfo.play.sample_rate) ||
1307                             Modify(ainfo.play.channels) ||
1308                             Modify(ainfo.play.encoding)) {
1309                                 /* If they're trying to change something we
1310                                  * have no routine for, they lose.
1311                                  */
1312                                 if ((!drv->ops->set_input_encoding && 
1313                                      Modify(ainfo.record.encoding)) ||
1314                                     (!drv->ops->set_input_rate && 
1315                                      Modify(ainfo.record.sample_rate)) ||
1316                                     (!drv->ops->set_input_precision && 
1317                                      Modify(ainfo.record.precision)) ||
1318                                     (!drv->ops->set_input_channels && 
1319                                      Modify(ainfo.record.channels))) {
1320                                         eprintk(("rec set no routines: failed\n"));
1321                                         retval = -EINVAL;
1322                                         break;
1323                                 }                 
1324                   
1325                                 curinfo.record.encoding = 
1326                                         drv->ops->get_input_encoding(drv);
1327                                 curinfo.record.sample_rate = 
1328                                         drv->ops->get_input_rate(drv);     
1329                                 curinfo.record.precision = 
1330                                         drv->ops->get_input_precision(drv);        
1331                                 curinfo.record.channels = 
1332                                         drv->ops->get_input_channels(drv);         
1333                                 newinfo.record.encoding =
1334                                         Modify(ainfo.record.encoding) ? 
1335                                         ainfo.record.encoding :
1336                                         curinfo.record.encoding;
1337                                 newinfo.record.sample_rate =
1338                                         Modify(ainfo.record.sample_rate) ?
1339                                         ainfo.record.sample_rate :
1340                                         curinfo.record.sample_rate;
1341                                 newinfo.record.precision =
1342                                         Modify(ainfo.record.precision) ? 
1343                                         ainfo.record.precision :
1344                                         curinfo.record.precision;
1345                                 newinfo.record.channels =
1346                                         Modify(ainfo.record.channels) ? 
1347                                         ainfo.record.channels :
1348                                         curinfo.record.channels;
1349                     
1350                                 switch (newinfo.record.encoding) {
1351                                 case AUDIO_ENCODING_ALAW:
1352                                 case AUDIO_ENCODING_ULAW:
1353                                         if (newinfo.record.precision != 8) {
1354                                                 eprintk(("rec law precision bounds: "
1355                                                          "failed\n"));
1356                                                 retval = -EINVAL;
1357                                                 break;
1358                                         }
1359                                         if (newinfo.record.channels != 1) {
1360                                                 eprintk(("rec law channel bounds: "
1361                                                          "failed\n"));
1362                                                 retval = -EINVAL;
1363                                                 break;
1364                                         }
1365                                         break;
1366                                 case AUDIO_ENCODING_LINEAR:
1367                                 case AUDIO_ENCODING_LINEARLE:
1368                                         if (newinfo.record.precision != 16) {
1369                                                 eprintk(("rec lin precision bounds: "
1370                                                          "failed\n"));
1371                                                 retval = -EINVAL;
1372                                                 break;
1373                                         }
1374                                         if (newinfo.record.channels != 1 &&
1375                                             newinfo.record.channels != 2) {
1376                                                 eprintk(("rec lin channel bounds: "
1377                                                          "failed\n"));
1378                                                 retval = -EINVAL;
1379                                                 break;
1380                                         }
1381                                         break;
1382                                 case AUDIO_ENCODING_LINEAR8:
1383                                         if (newinfo.record.precision != 8) {
1384                                                 eprintk(("rec lin8 precision bounds: "
1385                                                          "failed\n"));
1386                                                 retval = -EINVAL;
1387                                                 break;
1388                                         }
1389                                         if (newinfo.record.channels != 1 && 
1390                                             newinfo.record.channels != 2) {
1391                                                 eprintk(("rec lin8 channel bounds: "
1392                                                          "failed\n"));
1393                                                 retval = -EINVAL;
1394                                                 break;
1395                                         }
1396                                 };
1397                   
1398                                 if (retval < 0)
1399                                         break;
1400                   
1401                                 /* If they're trying to change something we
1402                                  * have no routine for, they lose.
1403                                  */
1404                                 if ((!drv->ops->set_output_encoding && 
1405                                      Modify(ainfo.play.encoding)) ||
1406                                     (!drv->ops->set_output_rate && 
1407                                      Modify(ainfo.play.sample_rate)) ||
1408                                     (!drv->ops->set_output_precision && 
1409                                      Modify(ainfo.play.precision)) ||
1410                                     (!drv->ops->set_output_channels && 
1411                                      Modify(ainfo.play.channels))) {
1412                                         eprintk(("play set no routine: failed\n"));
1413                                         retval = -EINVAL;
1414                                         break;
1415                                 }                 
1416                   
1417                                 curinfo.play.encoding = 
1418                                         drv->ops->get_output_encoding(drv);
1419                                 curinfo.play.sample_rate = 
1420                                         drv->ops->get_output_rate(drv);    
1421                                 curinfo.play.precision = 
1422                                         drv->ops->get_output_precision(drv);       
1423                                 curinfo.play.channels = 
1424                                         drv->ops->get_output_channels(drv);        
1425                                 newinfo.play.encoding =
1426                                         Modify(ainfo.play.encoding) ? 
1427                                         ainfo.play.encoding :
1428                                                 curinfo.play.encoding;
1429                                 newinfo.play.sample_rate =
1430                                         Modify(ainfo.play.sample_rate) ? 
1431                                         ainfo.play.sample_rate :
1432                                                 curinfo.play.sample_rate;
1433                                 newinfo.play.precision =
1434                                         Modify(ainfo.play.precision) ? 
1435                                         ainfo.play.precision :
1436                                                 curinfo.play.precision;
1437                                 newinfo.play.channels =
1438                                         Modify(ainfo.play.channels) ? 
1439                                         ainfo.play.channels :
1440                                                 curinfo.play.channels;
1441                   
1442                                 switch (newinfo.play.encoding) {
1443                                 case AUDIO_ENCODING_ALAW:
1444                                 case AUDIO_ENCODING_ULAW:
1445                                         if (newinfo.play.precision != 8) {
1446                                                 eprintk(("play law precision bounds: "
1447                                                          "failed\n"));
1448                                                 retval = -EINVAL;
1449                                                 break;
1450                                         }
1451                                         if (newinfo.play.channels != 1) {
1452                                                 eprintk(("play law channel bounds: "
1453                                                          "failed\n"));
1454                                                 retval = -EINVAL;
1455                                                 break;
1456                                         }
1457                                         break;
1458                                 case AUDIO_ENCODING_LINEAR:
1459                                 case AUDIO_ENCODING_LINEARLE:
1460                                         if (newinfo.play.precision != 16) {
1461                                                 eprintk(("play lin precision bounds: "
1462                                                          "failed\n"));
1463                                                 retval = -EINVAL;
1464                                                 break;
1465                                         }
1466                                         if (newinfo.play.channels != 1 && 
1467                                             newinfo.play.channels != 2) {
1468                                                 eprintk(("play lin channel bounds: "
1469                                                          "failed\n"));
1470                                                 retval = -EINVAL;
1471                                                 break;
1472                                         }
1473                                         break;
1474                                 case AUDIO_ENCODING_LINEAR8:
1475                                         if (newinfo.play.precision != 8) {
1476                                                 eprintk(("play lin8 precision bounds: "
1477                                                          "failed\n"));
1478                                                 retval = -EINVAL;
1479                                                 break;
1480                                         }
1481                                         if (newinfo.play.channels != 1 && 
1482                                             newinfo.play.channels != 2) {
1483                                                 eprintk(("play lin8 channel bounds: "
1484                                                          "failed\n"));
1485                                                 retval = -EINVAL;
1486                                                 break;
1487                                         }
1488                                 };
1489                   
1490                                 if (retval < 0)
1491                                         break;
1492                   
1493                                 /* If we got this far, we're at least sane with
1494                                  * respect to generics. Try the changes.
1495                                  */
1496                                 if ((drv->ops->set_input_channels &&
1497                                      (drv->ops->set_input_channels(drv, 
1498                                                                    newinfo.record.channels)
1499                                       < 0)) ||
1500                                     (drv->ops->set_output_channels &&
1501                                      (drv->ops->set_output_channels(drv, 
1502                                                                     newinfo.play.channels)
1503                                       < 0)) ||
1504                                     (drv->ops->set_input_rate &&
1505                                      (drv->ops->set_input_rate(drv, 
1506                                                                newinfo.record.sample_rate) 
1507                                       < 0)) ||
1508                                     (drv->ops->set_output_rate &&
1509                                      (drv->ops->set_output_rate(drv, 
1510                                                                 newinfo.play.sample_rate) 
1511                                       < 0)) ||
1512                                     (drv->ops->set_input_precision &&
1513                                      (drv->ops->set_input_precision(drv, 
1514                                                                     newinfo.record.precision)
1515                                       < 0)) ||
1516                                     (drv->ops->set_output_precision &&
1517                                      (drv->ops->set_output_precision(drv, 
1518                                                                      newinfo.play.precision)
1519                                       < 0)) ||
1520                                     (drv->ops->set_input_encoding &&
1521                                      (drv->ops->set_input_encoding(drv, 
1522                                                                    newinfo.record.encoding)
1523                                       < 0)) ||
1524                                     (drv->ops->set_output_encoding &&
1525                                      (drv->ops->set_output_encoding(drv, 
1526                                                                     newinfo.play.encoding)
1527                                       < 0))) 
1528                                 {
1529                                         dprintk(("setting format: failed\n"));
1530                                         /* Pray we can set it all back. If not, uh... */
1531                                         if (drv->ops->set_input_channels)
1532                                                 drv->ops->set_input_channels(drv, 
1533                                                      curinfo.record.channels);
1534                                         if (drv->ops->set_output_channels)
1535                                                 drv->ops->set_output_channels(drv, 
1536                                                                               curinfo.play.channels);
1537                                         if (drv->ops->set_input_rate)
1538                                                 drv->ops->set_input_rate(drv, 
1539                                                                          curinfo.record.sample_rate);
1540                                         if (drv->ops->set_output_rate)
1541                                                 drv->ops->set_output_rate(drv, 
1542                                                                           curinfo.play.sample_rate);
1543                                         if (drv->ops->set_input_precision)
1544                                                 drv->ops->set_input_precision(drv, 
1545                                                                               curinfo.record.precision);
1546                                         if (drv->ops->set_output_precision)
1547                                                 drv->ops->set_output_precision(drv, 
1548                                                                                curinfo.play.precision);
1549                                         if (drv->ops->set_input_encoding)
1550                                                 drv->ops->set_input_encoding(drv, 
1551                                                                              curinfo.record.encoding);
1552                                         if (drv->ops->set_output_encoding)
1553                                                 drv->ops->set_output_encoding(drv, 
1554                                                                               curinfo.play.encoding);
1555                                         retval = -EINVAL;
1556                                         break;
1557                                 }
1558                         }
1559                         
1560                         if (retval < 0)
1561                                 break;
1562                         
1563                         newinfo.record.balance =
1564                                 __sparcaudio_if_setc_do(drv, 
1565                                                         drv->ops->set_input_balance, 
1566                                                         drv->ops->get_input_balance,
1567                                                         ainfo.record.balance);
1568                         newinfo.play.balance =
1569                                 __sparcaudio_if_setc_do(drv, 
1570                                                         drv->ops->set_output_balance, 
1571                                                         drv->ops->get_output_balance,
1572                                                         ainfo.play.balance);
1573                         newinfo.record.error =
1574                                 __sparcaudio_if_setc_do(drv, 
1575                                                         drv->ops->set_input_error, 
1576                                                         drv->ops->get_input_error,
1577                                                         ainfo.record.error);
1578                         newinfo.play.error =
1579                                 __sparcaudio_if_setc_do(drv, 
1580                                                         drv->ops->set_output_error, 
1581                                                         drv->ops->get_output_error,
1582                                                         ainfo.play.error);
1583                         newinfo.output_muted =
1584                                 __sparcaudio_if_setc_do(drv, 
1585                                                         drv->ops->set_output_muted, 
1586                                                         drv->ops->get_output_muted,
1587                                                         ainfo.output_muted);
1588                         newinfo.record.gain =
1589                                 __sparcaudio_if_set_do(drv, 
1590                                                        drv->ops->set_input_volume, 
1591                                                        drv->ops->get_input_volume,
1592                                                        ainfo.record.gain);
1593                         newinfo.play.gain =
1594                                 __sparcaudio_if_set_do(drv, 
1595                                                        drv->ops->set_output_volume, 
1596                                                        drv->ops->get_output_volume,
1597                                                        ainfo.play.gain);
1598                         newinfo.record.port =
1599                                 __sparcaudio_if_set_do(drv, 
1600                                                        drv->ops->set_input_port, 
1601                                                        drv->ops->get_input_port,
1602                                                        ainfo.record.port);
1603                         newinfo.play.port =
1604                                 __sparcaudio_if_set_do(drv, 
1605                                                        drv->ops->set_output_port, 
1606                                                        drv->ops->get_output_port,
1607                                                        ainfo.play.port);
1608                         newinfo.record.samples =
1609                                 __sparcaudio_if_set_do(drv, 
1610                                                        drv->ops->set_input_samples, 
1611                                                        drv->ops->get_input_samples,
1612                                                        ainfo.record.samples);
1613                         newinfo.play.samples =
1614                                 __sparcaudio_if_set_do(drv, 
1615                                                        drv->ops->set_output_samples, 
1616                                                        drv->ops->get_output_samples,
1617                                                        ainfo.play.samples);
1618                         newinfo.monitor_gain =
1619                                 __sparcaudio_if_set_do(drv, 
1620                                                        drv->ops->set_monitor_volume, 
1621                                                        drv->ops->get_monitor_volume,
1622                                                        ainfo.monitor_gain);
1623
1624                         if (Modify(ainfo.record.buffer_size)) {
1625                                 /* Should sanity check this */
1626                                 newinfo.record.buffer_size = ainfo.record.buffer_size;
1627                                 drv->buffer_size = ainfo.record.buffer_size;
1628                         } else {
1629                                 newinfo.record.buffer_size = drv->buffer_size;
1630                         }
1631
1632                         if (Modify(ainfo.play.eof)) {
1633                                 ainfo.play.eof = newinfo.play.eof;
1634                                 newinfo.play.eof = drv->output_eof;
1635                                 drv->output_eof = ainfo.play.eof;
1636                         } else {
1637                                 newinfo.play.eof = drv->output_eof;
1638                         }               
1639
1640                         if (drv->flags & SDF_OPEN_READ) {
1641                                 newinfo.record.pause =
1642                                         __sparcaudio_if_setc_do(drv, 
1643                                                                 drv->ops->set_input_pause, 
1644                                                                 drv->ops->get_input_pause,
1645                                                                 ainfo.record.pause);
1646                         } else if (drv->ops->get_input_pause) {
1647                                 newinfo.record.pause = drv->ops->get_input_pause(drv);
1648                         } else {
1649                                 newinfo.record.pause = 0;
1650                         }
1651
1652                         if (drv->flags & SDF_OPEN_WRITE) {
1653                                 newinfo.play.pause =
1654                                         __sparcaudio_if_setc_do(drv, 
1655                                                                 drv->ops->set_output_pause, 
1656                                                                 drv->ops->get_output_pause,
1657                                                                 ainfo.play.pause);
1658                         } else if (drv->ops->get_output_pause) {
1659                                 newinfo.play.pause = drv->ops->get_output_pause(drv);
1660                         } else {
1661                                 newinfo.play.pause = 0;
1662                         }
1663               
1664                         retval = verify_area(VERIFY_WRITE, (void *)arg,
1665                                              sizeof(struct audio_info));
1666
1667                         /* Even if we fail, if we made changes let's try notification */
1668                         if (!retval) 
1669                                 copy_to_user((struct audio_info *)arg, &newinfo, 
1670                                              sizeof(newinfo));
1671             
1672 #ifdef REAL_AUDIO_SIGNALS
1673                         kill_procs(drv->sd_siglist,SIGPOLL,S_MSG);
1674 #endif
1675                         break;
1676                 }
1677           
1678                 default:
1679                         if (drv->ops->ioctl)
1680                                 retval = drv->ops->ioctl(inode,file,cmd,arg,drv);
1681                         else
1682                                 retval = -EINVAL;
1683                 };
1684                 break;
1685         case SPARCAUDIO_STATUS_MINOR:
1686                 eprintk(("status minor not yet implemented\n"));
1687                 retval = -EINVAL;
1688         default:
1689                 eprintk(("unknown minor device number\n"));
1690                 retval = -EINVAL;
1691         }
1692         
1693         return retval;
1694 }
1695
1696 static struct file_operations sparcaudioctl_fops = {
1697         owner:          THIS_MODULE,
1698         poll:           sparcaudio_poll,
1699         ioctl:          sparcaudio_ioctl,
1700 };
1701
1702 static int sparcaudio_open(struct inode * inode, struct file * file)
1703 {
1704         int minor = MINOR(inode->i_rdev);
1705         struct sparcaudio_driver *drv = 
1706                 drivers[(minor >> SPARCAUDIO_DEVICE_SHIFT)];
1707         int err;
1708
1709         /* A low-level audio driver must exist. */
1710         if (!drv)
1711                 return -ENODEV;
1712
1713 #ifdef S_ZERO_WR
1714         /* This is how 2.0 ended up dealing with 0 len writes */
1715         inode->i_flags |= S_ZERO_WR;
1716 #endif
1717
1718         switch (minor & 0xf) {
1719         case SPARCAUDIO_AUDIOCTL_MINOR:
1720                 file->f_op = &sparcaudioctl_fops;
1721                 break;
1722         case SPARCAUDIO_DSP16_MINOR:
1723         case SPARCAUDIO_DSP_MINOR:
1724         case SPARCAUDIO_AUDIO_MINOR:
1725                 /* If the driver is busy, then wait to get through. */
1726         retry_open:
1727                 if (file->f_mode & FMODE_READ && drv->flags & SDF_OPEN_READ) {
1728                         if (file->f_flags & O_NONBLOCK)
1729                                 return -EBUSY;
1730
1731                         /* If something is now waiting, signal control device */
1732                         kill_procs(drv->sd_siglist,SIGPOLL,S_MSG);
1733
1734                         interruptible_sleep_on(&drv->open_wait);
1735                         if (signal_pending(current))
1736                                 return -EINTR;
1737                         goto retry_open;
1738                 }
1739                 if (file->f_mode & FMODE_WRITE && drv->flags & SDF_OPEN_WRITE) {
1740                         if (file->f_flags & O_NONBLOCK)
1741                                 return -EBUSY;
1742             
1743                         /* If something is now waiting, signal control device */
1744                         kill_procs(drv->sd_siglist,SIGPOLL,S_MSG);
1745
1746                         interruptible_sleep_on(&drv->open_wait);
1747                         if (signal_pending(current))
1748                                 return -EINTR;
1749                         goto retry_open;
1750                 }
1751
1752                 /* Allow the low-level driver to initialize itself. */
1753                 if (drv->ops->open) {
1754                         err = drv->ops->open(inode,file,drv);
1755                         if (err < 0)
1756                                 return err;
1757                 }
1758
1759                 /* Mark the driver as locked for read and/or write. */
1760                 if (file->f_mode & FMODE_READ) {
1761                         drv->input_offset = 0;
1762                         drv->input_front = 0;
1763                         drv->input_rear = 0;
1764                         drv->input_count = 0;
1765                         drv->input_size = 0;
1766                         drv->recording_count = 0;
1767
1768                         /* Clear pause */
1769                         if (drv->ops->set_input_pause)
1770                                 drv->ops->set_input_pause(drv, 0); 
1771                         drv->ops->start_input(drv, drv->input_buffers[drv->input_front],
1772                                               drv->input_buffer_size);
1773                         drv->input_active = 1;
1774                         drv->flags |= SDF_OPEN_READ;
1775                 }
1776
1777                 if (file->f_mode & FMODE_WRITE) {
1778                         drv->output_offset = 0;
1779                         drv->output_eof = 0;
1780                         drv->playing_count = 0;
1781                         drv->output_size = 0;
1782                         drv->output_front = 0;
1783                         drv->output_rear = 0;
1784                         drv->output_count = 0;
1785                         drv->output_active = 0;
1786
1787                         /* Clear pause */
1788                         if (drv->ops->set_output_pause)
1789                                 drv->ops->set_output_pause(drv, 0); 
1790                         drv->flags |= SDF_OPEN_WRITE;
1791                 }  
1792
1793                 break;
1794         case SPARCAUDIO_MIXER_MINOR:     
1795                 file->f_op = &sparcaudioctl_fops;
1796                 break;
1797
1798         default:
1799                 return -ENXIO;
1800         };
1801
1802         /* From the dbri driver:
1803          * SunOS 5.5.1 audio(7I) man page says:
1804          * "Upon the initial open() of the audio device, the driver
1805          *  will reset the data format of the device to the default
1806          *  state of 8-bit, 8KHz, mono u-law data."
1807          *
1808          * Of course, we only do this for /dev/audio, and assume
1809          * OSS semantics on /dev/dsp
1810          */
1811
1812         if ((minor & 0xf) == SPARCAUDIO_AUDIO_MINOR) {
1813                 if (file->f_mode & FMODE_WRITE) {
1814                         if (drv->ops->set_output_channels)
1815                                 drv->ops->set_output_channels(drv, 1);
1816                         if (drv->ops->set_output_encoding)
1817                                 drv->ops->set_output_encoding(drv, AUDIO_ENCODING_ULAW);
1818                         if (drv->ops->set_output_rate)
1819                                 drv->ops->set_output_rate(drv, 8000);
1820                 }          
1821
1822                 if (file->f_mode & FMODE_READ) {
1823                         if (drv->ops->set_input_channels)
1824                                 drv->ops->set_input_channels(drv, 1);
1825                         if (drv->ops->set_input_encoding)
1826                                 drv->ops->set_input_encoding(drv, AUDIO_ENCODING_ULAW);
1827                         if (drv->ops->set_input_rate)
1828                                 drv->ops->set_input_rate(drv, 8000);
1829                 }          
1830         }
1831
1832         /* Success! */
1833         return 0;
1834 }
1835
1836 static int sparcaudio_release(struct inode * inode, struct file * file)
1837 {
1838         struct sparcaudio_driver *drv = drivers[(MINOR(inode->i_rdev) >>
1839                                                  SPARCAUDIO_DEVICE_SHIFT)];
1840
1841         lock_kernel();
1842         if (file->f_mode & FMODE_READ) {
1843                 /* Stop input */
1844                 drv->ops->stop_input(drv);
1845                 drv->input_active = 0;
1846         }
1847
1848         if (file->f_mode & FMODE_WRITE) {
1849                 /* Anything in the queue? */
1850                 if (drv->output_offset) {
1851                         drv->output_offset = 0;
1852                         drv->output_rear = (drv->output_rear + 1)
1853                                 % drv->num_output_buffers;
1854                         drv->output_count++;
1855                 }
1856                 sparcaudio_sync_output(drv);
1857
1858                 /* Wait for any output still in the queue to be played. */
1859                 if ((drv->output_count > 0) || (drv->playing_count > 0))
1860                         interruptible_sleep_on(&drv->output_drain_wait);
1861
1862                 /* Force any output to be stopped. */
1863                 drv->ops->stop_output(drv);
1864                 drv->output_active = 0;
1865                 drv->playing_count = 0;
1866                 drv->output_eof = 0;
1867         }
1868
1869         /* Let the low-level driver do any release processing. */
1870         if (drv->ops->release)
1871                 drv->ops->release(inode,file,drv);
1872
1873         if (file->f_mode & FMODE_READ)
1874                 drv->flags &= ~(SDF_OPEN_READ);
1875
1876         if (file->f_mode & FMODE_WRITE) 
1877                 drv->flags &= ~(SDF_OPEN_WRITE);
1878
1879         /* Status changed. Signal control device */
1880         kill_procs(drv->sd_siglist,SIGPOLL,S_MSG);
1881
1882         wake_up_interruptible(&drv->open_wait);
1883         unlock_kernel();
1884
1885         return 0;
1886 }
1887
1888 static struct file_operations sparcaudio_fops = {
1889         owner:          THIS_MODULE,
1890         llseek:         no_llseek,
1891         read:           sparcaudio_read,
1892         write:          sparcaudio_write,
1893         poll:           sparcaudio_poll,
1894         ioctl:          sparcaudio_ioctl,
1895         open:           sparcaudio_open,
1896         release:        sparcaudio_release,
1897 };
1898
1899 static struct {
1900         unsigned short minor;
1901         char *name;
1902         umode_t mode;
1903 } dev_list[] = {
1904         { SPARCAUDIO_MIXER_MINOR, "mixer", S_IWUSR | S_IRUGO },
1905         { SPARCAUDIO_DSP_MINOR, "dsp", S_IWUGO | S_IRUSR | S_IRGRP },
1906         { SPARCAUDIO_AUDIO_MINOR, "audio", S_IWUGO | S_IRUSR | S_IRGRP },
1907         { SPARCAUDIO_DSP16_MINOR, "dspW", S_IWUGO | S_IRUSR | S_IRGRP },
1908         { SPARCAUDIO_STATUS_MINOR, "status", S_IRUGO },
1909         { SPARCAUDIO_AUDIOCTL_MINOR, "audioctl", S_IRUGO }
1910 };
1911
1912 static void sparcaudio_mkname (char *buf, char *name, int dev)
1913 {
1914         if (dev)
1915                 sprintf (buf, "%s%d", name, dev);
1916         else
1917                 sprintf (buf, "%s", name);
1918 }
1919
1920 int register_sparcaudio_driver(struct sparcaudio_driver *drv, int duplex)
1921 {
1922         int i, dev;
1923         unsigned short minor;
1924         char name_buf[32];
1925
1926         /* If we've used up SPARCAUDIO_MAX_DEVICES, fail */
1927         for (dev = 0; dev < SPARCAUDIO_MAX_DEVICES; dev++) {
1928                 if (drivers[dev] == NULL)
1929                         break;
1930         }
1931
1932         if (drivers[dev])
1933                 return -EIO;
1934
1935         /* Ensure that the driver has a proper operations structure. */
1936         if (!drv->ops || !drv->ops->start_output || !drv->ops->stop_output ||
1937             !drv->ops->start_input || !drv->ops->stop_input)
1938                 return -EINVAL;
1939
1940         /* Register ourselves with devfs */
1941         for (i=0; i < sizeof (dev_list) / sizeof (*dev_list); i++) {
1942                 sparcaudio_mkname (name_buf, dev_list[i].name, dev);
1943                 minor = (dev << SPARCAUDIO_DEVICE_SHIFT) | dev_list[i].minor;
1944                 devfs_register (devfs_handle, name_buf, DEVFS_FL_NONE,
1945                                 SOUND_MAJOR, minor, S_IFCHR | dev_list[i].mode,
1946                                 &sparcaudio_fops, NULL);
1947         }
1948
1949         /* Setup the circular queues of output and input buffers
1950          *
1951          * Each buffer is a single page, but output buffers might
1952          * be partially filled (by a write with count < output_buffer_size),
1953          * so each output buffer also has a paired output size.
1954          *
1955          * Input buffers, on the other hand, always fill completely,
1956          * so we don't need input counts - each contains input_buffer_size
1957          * bytes of audio data.
1958          *
1959          * TODO: Make number of input/output buffers tunable parameters
1960          */
1961
1962         init_waitqueue_head(&drv->open_wait);
1963         init_waitqueue_head(&drv->output_write_wait);
1964         init_waitqueue_head(&drv->output_drain_wait);
1965         init_waitqueue_head(&drv->input_read_wait);
1966
1967         drv->num_output_buffers = 8;
1968         drv->output_buffer_size = (4096 * 2);
1969         drv->playing_count = 0;
1970         drv->output_offset = 0;
1971         drv->output_eof = 0;
1972         drv->output_front = 0;
1973         drv->output_rear = 0;
1974         drv->output_count = 0;
1975         drv->output_active = 0;
1976         drv->output_buffers = kmalloc(drv->num_output_buffers * 
1977                                       sizeof(__u8 *), GFP_KERNEL);
1978         drv->output_sizes = kmalloc(drv->num_output_buffers * 
1979                                     sizeof(size_t), GFP_KERNEL);
1980         drv->output_notify = kmalloc(drv->num_output_buffers * 
1981                                     sizeof(char), GFP_KERNEL);
1982         if (!drv->output_buffers || !drv->output_sizes || !drv->output_notify)
1983                 goto kmalloc_failed1;
1984
1985         drv->output_buffer = kmalloc((drv->output_buffer_size * 
1986                                       drv->num_output_buffers),
1987                                      GFP_KERNEL);
1988         if (!drv->output_buffer)
1989                 goto kmalloc_failed2;
1990
1991         /* Allocate the pages for each output buffer. */
1992         for (i = 0; i < drv->num_output_buffers; i++) {
1993                 drv->output_buffers[i] = (void *)(drv->output_buffer + 
1994                                                   (i * drv->output_buffer_size));
1995                 drv->output_sizes[i] = 0;
1996                 drv->output_notify[i] = 0;
1997         }
1998
1999         /* Setup the circular queue of input buffers. */
2000         drv->num_input_buffers = 8;
2001         drv->input_buffer_size = (4096 * 2);
2002         drv->recording_count = 0;
2003         drv->input_front = 0;
2004         drv->input_rear = 0;
2005         drv->input_count = 0;
2006         drv->input_offset = 0;
2007         drv->input_size = 0;
2008         drv->input_active = 0;
2009         drv->input_buffers = kmalloc(drv->num_input_buffers * sizeof(__u8 *),
2010                                      GFP_KERNEL);
2011         drv->input_sizes = kmalloc(drv->num_input_buffers * 
2012                                    sizeof(size_t), GFP_KERNEL);
2013         if (!drv->input_buffers || !drv->input_sizes)
2014                 goto kmalloc_failed3;
2015
2016         /* Allocate the pages for each input buffer. */
2017         if (duplex == 1) {
2018                 drv->input_buffer = kmalloc((drv->input_buffer_size * 
2019                                              drv->num_input_buffers), 
2020                                             GFP_DMA);
2021                 if (!drv->input_buffer)
2022                         goto kmalloc_failed4;
2023
2024                 for (i = 0; i < drv->num_input_buffers; i++)
2025                         drv->input_buffers[i] = (void *)(drv->input_buffer + 
2026                                                          (i * drv->input_buffer_size));
2027         } else {
2028                 if (duplex == 2) {
2029                         drv->input_buffer = drv->output_buffer;
2030                         drv->input_buffer_size = drv->output_buffer_size;
2031                         drv->num_input_buffers = drv->num_output_buffers;
2032                         for (i = 0; i < drv->num_input_buffers; i++) 
2033                                 drv->input_buffers[i] = drv->output_buffers[i];
2034                 } else {
2035                         for (i = 0; i < drv->num_input_buffers; i++) 
2036                                 drv->input_buffers[i] = NULL;
2037                 }
2038         }
2039
2040         /* Take note of our duplexity */
2041         drv->duplex = duplex;
2042
2043         /* Ensure that the driver is marked as not being open. */
2044         drv->flags = 0;
2045
2046         MOD_INC_USE_COUNT;
2047
2048         /* Take driver slot, note which we took */
2049         drv->index = dev;
2050         drivers[dev] = drv;
2051
2052         return 0;
2053
2054 kmalloc_failed4:
2055         kfree(drv->input_buffer);
2056
2057 kmalloc_failed3:
2058         if (drv->input_sizes)
2059                 kfree(drv->input_sizes);
2060         if (drv->input_buffers)
2061                 kfree(drv->input_buffers);
2062         i = drv->num_output_buffers;
2063
2064 kmalloc_failed2:
2065         kfree(drv->output_buffer);
2066
2067 kmalloc_failed1:
2068         if (drv->output_buffers)
2069                 kfree(drv->output_buffers);
2070         if (drv->output_sizes)
2071                 kfree(drv->output_sizes);
2072         if (drv->output_notify)
2073                 kfree(drv->output_notify);
2074
2075         return -ENOMEM;
2076 }
2077
2078 int unregister_sparcaudio_driver(struct sparcaudio_driver *drv, int duplex)
2079 {
2080         devfs_handle_t de;
2081         int i;
2082         char name_buf[32];
2083
2084         /* Figure out which driver is unregistering */
2085         if (drivers[drv->index] != drv)
2086                 return -EIO;
2087
2088         /* Deallocate the queue of output buffers. */
2089         kfree(drv->output_buffer);
2090         kfree(drv->output_buffers);
2091         kfree(drv->output_sizes);
2092         kfree(drv->output_notify);
2093
2094         /* Deallocate the queue of input buffers. */
2095         if (duplex == 1) {
2096                 kfree(drv->input_buffer);
2097                 kfree(drv->input_sizes);
2098         }
2099         kfree(drv->input_buffers);
2100
2101         if (&(drv->sd_siglist) != NULL)
2102                 lis_free_elist( &(drv->sd_siglist) );
2103
2104         /* Unregister ourselves with devfs */
2105         for (i=0; i < sizeof (dev_list) / sizeof (*dev_list); i++) {
2106                 sparcaudio_mkname (name_buf, dev_list[i].name, drv->index);
2107                 de = devfs_find_handle (devfs_handle, name_buf, 0, 0,
2108                                         DEVFS_SPECIAL_CHR, 0);
2109                 devfs_unregister (de);
2110         }
2111
2112         MOD_DEC_USE_COUNT;
2113
2114         /* Null the appropriate driver */
2115         drivers[drv->index] = NULL;
2116
2117         return 0;
2118 }
2119
2120 EXPORT_SYMBOL(register_sparcaudio_driver);
2121 EXPORT_SYMBOL(unregister_sparcaudio_driver);
2122 EXPORT_SYMBOL(sparcaudio_output_done);
2123 EXPORT_SYMBOL(sparcaudio_input_done);
2124
2125 static int __init sparcaudio_init(void)
2126 {
2127         /* Register our character device driver with the VFS. */
2128         if (devfs_register_chrdev(SOUND_MAJOR, "sparcaudio", &sparcaudio_fops))
2129                 return -EIO;
2130
2131         devfs_handle = devfs_mk_dir (NULL, "sound", NULL);
2132         return 0;
2133 }
2134
2135 static void __exit sparcaudio_exit(void)
2136 {
2137         devfs_unregister_chrdev(SOUND_MAJOR, "sparcaudio");
2138         devfs_unregister (devfs_handle);
2139 }
2140
2141 module_init(sparcaudio_init);
2142 module_exit(sparcaudio_exit);
2143 MODULE_LICENSE("GPL");
2144
2145 /*
2146  * Code from Linux Streams, Copyright 1995 by
2147  * Graham Wheeler, Francisco J. Ballesteros, Denis Froschauer
2148  * and available under GPL 
2149  */
2150
2151 static int
2152 lis_add_to_elist( strevent_t **list, pid_t pid, short events )
2153 {
2154         strevent_t *ev = NULL;
2155
2156         if (*list != NULL) {
2157                 for (ev = (*list)->se_next;
2158                      ev != *list && ev->se_pid < pid;
2159                      ev = ev->se_next)
2160                         ;
2161         }
2162
2163         if (ev == NULL || ev == *list) {             /* no slot for pid in list */
2164                 ev = (strevent_t *) kmalloc(sizeof(strevent_t), GFP_KERNEL);
2165                 if (ev == NULL)
2166                         return(-ENOMEM);
2167
2168                 if (!*list) {                   /* create dummy head node */
2169                         strevent_t *hd;
2170
2171                         hd = (strevent_t *) kmalloc(sizeof(strevent_t), GFP_KERNEL);
2172                         if (hd == NULL) {
2173                                 kfree(ev);
2174                                 return(-ENOMEM);
2175                         }
2176                         (*list = hd)->se_pid = 0;
2177                         hd->se_next = hd->se_prev = hd;         /* empty list */
2178                 }
2179
2180                 /* link node last in the list */
2181                 ev->se_prev = (*list)->se_prev;
2182                 (*list)->se_prev->se_next = ev;
2183                 ((*list)->se_prev = ev)->se_next = *list;
2184
2185                 ev->se_pid = pid;
2186                 ev->se_evs = 0;
2187         } else if (ev->se_pid != pid) {  /* link node in the middle of the list */
2188                 strevent_t *new;
2189
2190                 new = (strevent_t *) kmalloc(sizeof(strevent_t), GFP_KERNEL);
2191                 if (new == NULL)
2192                         return -ENOMEM;
2193
2194                 new->se_prev = ev->se_prev;
2195                 new->se_next = ev;
2196                 ev->se_prev->se_next = new;
2197                 ev->se_prev = new;
2198                 ev = new;                              /* use new element */
2199                 ev->se_pid = pid;
2200                 ev->se_evs = 0;
2201         }
2202
2203         ev->se_evs |= events;
2204         return 0;
2205 }
2206
2207 static int
2208 lis_del_from_elist( strevent_t **list, pid_t pid, short events )
2209 {
2210         strevent_t *ev = NULL;     
2211
2212         if (*list != NULL) {
2213                 for (ev = (*list)->se_next;
2214                      ev != *list && ev->se_pid < pid;
2215                      ev = ev->se_next)
2216                         ;
2217         }
2218
2219         if (ev == NULL || ev == *list || ev->se_pid != pid)
2220                 return 1;
2221
2222         if ((ev->se_evs &= ~events) == 0) {        /* unlink */
2223                 if (ev->se_next)                        /* should always be true */
2224                         ev->se_next->se_prev = ev->se_prev;
2225                 if (ev->se_prev)                        /* should always be true */
2226                         ev->se_prev->se_next = ev->se_next;
2227                 kfree(ev);
2228         }
2229         return 0;
2230 }
2231
2232 static void
2233 lis_free_elist( strevent_t **list )
2234 {
2235         strevent_t  *ev;     
2236         strevent_t  *nxt;
2237
2238         for (ev = *list; ev != NULL; ) {
2239                 nxt = ev->se_next;
2240                 kfree(ev);
2241                 ev = nxt;
2242                 if (ev == *list)
2243                         break;                /* all done */
2244         }
2245
2246         *list = NULL;
2247 }
2248
2249 static short
2250 lis_get_elist_ent( strevent_t *list, pid_t pid )
2251 {
2252         strevent_t *ev = NULL;
2253
2254         if (list == NULL)
2255                 return 0;
2256
2257         for(ev = list->se_next ; ev != list && ev->se_pid < pid; ev = ev->se_next)
2258                 ;
2259         if (ev != list && ev->se_pid == pid)
2260                 return ev->se_evs;
2261         else
2262                 return 0;
2263 }
2264
2265 static void 
2266 kill_procs( struct strevent *elist, int sig, short e)
2267 {
2268         strevent_t *ev;
2269         int res;
2270
2271         if (elist) {
2272                 for(ev = elist->se_next ; ev != elist; ev = ev->se_next)
2273                         if ((ev->se_evs & e) != 0) {
2274                                 res = kill_proc(ev->se_pid, SIGPOLL, 1);
2275
2276                                 if (res < 0) {
2277                                         if (res == -3) {
2278                                                 lis_del_from_elist(&elist,
2279                                                                    ev->se_pid,
2280                                                                    S_ALL);
2281                                                 continue;
2282                                         }
2283                                         dprintk(("kill_proc: errno %d\n",res));
2284                                 }
2285                         }
2286         }
2287 }
2288
2289 /*
2290  * Overrides for Emacs so that we follow Linus's tabbing style.
2291  * Emacs will notice this stuff at the end of the file and automatically
2292  * adjust the settings for this buffer only.  This must remain at the end
2293  * of the file.
2294  * ---------------------------------------------------------------------------
2295  * Local variables:
2296  * c-indent-level: 4
2297  * c-brace-imaginary-offset: 0
2298  * c-brace-offset: -4
2299  * c-argdecl-indent: 4
2300  * c-label-offset: -4
2301  * c-continued-statement-offset: 4
2302  * c-continued-brace-offset: 0
2303  * indent-tabs-mode: nil
2304  * tab-width: 8
2305  * End:
2306  */