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