OpenCores
URL https://opencores.org/ocsvn/or1k/or1k/trunk

Subversion Repositories or1k

[/] [or1k/] [trunk/] [linux/] [linux-2.4/] [drivers/] [sbus/] [audio/] [audio.c] - Blame information for rev 1765

Details | Compare with Previous | View Log

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

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.