File: /usr/src/linux/drivers/sbus/audio/audio.c

1     /* $Id: audio.c,v 1.61 2001/08/13 14:40:12 davem 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     
2144     /*
2145      * Code from Linux Streams, Copyright 1995 by
2146      * Graham Wheeler, Francisco J. Ballesteros, Denis Froschauer
2147      * and available under GPL 
2148      */
2149     
2150     static int
2151     lis_add_to_elist( strevent_t **list, pid_t pid, short events )
2152     {
2153             strevent_t *ev = NULL;
2154     
2155             if (*list != NULL) {
2156                     for (ev = (*list)->se_next;
2157                          ev != *list && ev->se_pid < pid;
2158                          ev = ev->se_next)
2159                             ;
2160             }
2161     
2162             if (ev == NULL || ev == *list) {             /* no slot for pid in list */
2163                     ev = (strevent_t *) kmalloc(sizeof(strevent_t), GFP_KERNEL);
2164                     if (ev == NULL)
2165                             return(-ENOMEM);
2166     
2167                     if (!*list) {                   /* create dummy head node */
2168                             strevent_t *hd;
2169     
2170                             hd = (strevent_t *) kmalloc(sizeof(strevent_t), GFP_KERNEL);
2171                             if (hd == NULL) {
2172                                     kfree(ev);
2173                                     return(-ENOMEM);
2174                             }
2175                             (*list = hd)->se_pid = 0;
2176                             hd->se_next = hd->se_prev = hd;         /* empty list */
2177                     }
2178     
2179                     /* link node last in the list */
2180                     ev->se_prev = (*list)->se_prev;
2181                     (*list)->se_prev->se_next = ev;
2182                     ((*list)->se_prev = ev)->se_next = *list;
2183     
2184                     ev->se_pid = pid;
2185                     ev->se_evs = 0;
2186             } else if (ev->se_pid != pid) {  /* link node in the middle of the list */
2187                     strevent_t *new;
2188     
2189                     new = (strevent_t *) kmalloc(sizeof(strevent_t), GFP_KERNEL);
2190                     if (new == NULL)
2191                             return -ENOMEM;
2192     
2193                     new->se_prev = ev->se_prev;
2194                     new->se_next = ev;
2195                     ev->se_prev->se_next = new;
2196                     ev->se_prev = new;
2197                     ev = new;                              /* use new element */
2198                     ev->se_pid = pid;
2199                     ev->se_evs = 0;
2200             }
2201     
2202             ev->se_evs |= events;
2203             return 0;
2204     }
2205     
2206     static int
2207     lis_del_from_elist( strevent_t **list, pid_t pid, short events )
2208     {
2209             strevent_t *ev = NULL;     
2210     
2211             if (*list != NULL) {
2212                     for (ev = (*list)->se_next;
2213                          ev != *list && ev->se_pid < pid;
2214                          ev = ev->se_next)
2215                             ;
2216             }
2217     
2218             if (ev == NULL || ev == *list || ev->se_pid != pid)
2219                     return 1;
2220     
2221             if ((ev->se_evs &= ~events) == 0) {        /* unlink */
2222                     if (ev->se_next)                        /* should always be true */
2223                             ev->se_next->se_prev = ev->se_prev;
2224                     if (ev->se_prev)                        /* should always be true */
2225                             ev->se_prev->se_next = ev->se_next;
2226                     kfree(ev);
2227             }
2228             return 0;
2229     }
2230     
2231     static void
2232     lis_free_elist( strevent_t **list )
2233     {
2234             strevent_t  *ev;     
2235             strevent_t  *nxt;
2236     
2237             for (ev = *list; ev != NULL; ) {
2238                     nxt = ev->se_next;
2239                     kfree(ev);
2240                     ev = nxt;
2241                     if (ev == *list)
2242                             break;                /* all done */
2243             }
2244     
2245             *list = NULL;
2246     }
2247     
2248     static short
2249     lis_get_elist_ent( strevent_t *list, pid_t pid )
2250     {
2251             strevent_t *ev = NULL;
2252     
2253             if (list == NULL)
2254                     return 0;
2255     
2256             for(ev = list->se_next ; ev != list && ev->se_pid < pid; ev = ev->se_next)
2257                     ;
2258             if (ev != list && ev->se_pid == pid)
2259                     return ev->se_evs;
2260             else
2261                     return 0;
2262     }
2263     
2264     static void 
2265     kill_procs( struct strevent *elist, int sig, short e)
2266     {
2267             strevent_t *ev;
2268             int res;
2269     
2270             if (elist) {
2271                     for(ev = elist->se_next ; ev != elist; ev = ev->se_next)
2272                             if ((ev->se_evs & e) != 0) {
2273                                     res = kill_proc(ev->se_pid, SIGPOLL, 1);
2274     
2275                                     if (res < 0) {
2276                                             if (res == -3) {
2277                                                     lis_del_from_elist(&elist,
2278                                                                        ev->se_pid,
2279                                                                        S_ALL);
2280                                                     continue;
2281                                             }
2282                                             dprintk(("kill_proc: errno %d\n",res));
2283                                     }
2284                             }
2285             }
2286     }
2287     
2288     /*
2289      * Overrides for Emacs so that we follow Linus's tabbing style.
2290      * Emacs will notice this stuff at the end of the file and automatically
2291      * adjust the settings for this buffer only.  This must remain at the end
2292      * of the file.
2293      * ---------------------------------------------------------------------------
2294      * Local variables:
2295      * c-indent-level: 4
2296      * c-brace-imaginary-offset: 0
2297      * c-brace-offset: -4
2298      * c-argdecl-indent: 4
2299      * c-label-offset: -4
2300      * c-continued-statement-offset: 4
2301      * c-continued-brace-offset: 0
2302      * indent-tabs-mode: nil
2303      * tab-width: 8
2304      * End:
2305      */
2306