linux-old/drivers/sbus/audio/audio.c
<<
>>
Prefs
   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
  68static int  audio_input_buffers = 8;
  69MODULE_PARM(audio_input_buffers, "i");
  70MODULE_PARM_DESC(audio_input_buffers,"Number of input 8KB buffers.");
  71
  72static int  audio_output_buffers = 8;
  73MODULE_PARM(audio_output_buffers, "i");
  74MODULE_PARM_DESC(audio_output_buffers,"Number of output 8KB buffer.");
  75
  76static short lis_get_elist_ent( strevent_t *list, pid_t pid );
  77static int lis_add_to_elist( strevent_t **list, pid_t pid, short events );
  78static int lis_del_from_elist( strevent_t **list, pid_t pid, short events );
  79static void lis_free_elist( strevent_t **list);
  80static void kill_procs( struct strevent *elist, int sig, short e);
  81
  82static struct sparcaudio_driver *drivers[SPARCAUDIO_MAX_DEVICES];
  83static devfs_handle_t devfs_handle;
  84 
  85
  86void 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
 158void 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
 209static 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
 228static 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
 288static 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
 303static 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
 404static 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. */
 621static __inline__ int 
 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
 635static __inline__ int 
 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 */
 654static 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
1704static struct file_operations sparcaudioctl_fops = {
1705        owner:          THIS_MODULE,
1706        poll:           sparcaudio_poll,
1707        ioctl:          sparcaudio_ioctl,
1708};
1709
1710static 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
1844static 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
1896static 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
1907static 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
1920static 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
1928int 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
2060kmalloc_failed4:
2061        kfree(drv->input_buffer);
2062
2063kmalloc_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
2070kmalloc_failed2:
2071        kfree(drv->output_buffer);
2072
2073kmalloc_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
2084int 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
2126EXPORT_SYMBOL(register_sparcaudio_driver);
2127EXPORT_SYMBOL(unregister_sparcaudio_driver);
2128EXPORT_SYMBOL(sparcaudio_output_done);
2129EXPORT_SYMBOL(sparcaudio_input_done);
2130
2131static 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
2141static void __exit sparcaudio_exit(void)
2142{
2143        devfs_unregister_chrdev(SOUND_MAJOR, "sparcaudio");
2144        devfs_unregister (devfs_handle);
2145}
2146
2147module_init(sparcaudio_init);
2148module_exit(sparcaudio_exit);
2149MODULE_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
2157static int
2158lis_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
2213static int
2214lis_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
2238static void
2239lis_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
2255static short
2256lis_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
2271static void 
2272kill_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
lxr.linux.no kindly hosted by Redpill Linpro AS, provider of Linux consulting and operations services since 1995.