~ubuntu-branches/ubuntu/oneiric/oss4/oneiric-proposed

« back to all changes in this revision

Viewing changes to setup/Linux/oss/build/osscore.c

  • Committer: Bazaar Package Importer
  • Author(s): Stefano Rivera
  • Date: 2011-06-16 20:37:48 UTC
  • mfrom: (5.1.3 sid)
  • Revision ID: james.westby@ubuntu.com-20110616203748-jbrxik6ql33z54co
Tags: 4.2-build2004-1ubuntu1
* Merge from Debian unstable.
  - Supports our current kernel (LP: #746048)
  Remaining changes:
  - debian/oss4-dkms.dkms.in: s/source/build/ in Kernel headers paths.
* ld-as-needed.patch: Re-order CC arguments to enable building with ld
  --as-needed (LP: #770972)

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * Purpose: Linux kernel version specific wrapper routines.
 
3
 *
 
4
 * This file will be shipped in source format and compiled in the target
 
5
 * (customer) system. In this way minor changes between Linux versions
 
6
 * can be fixed by the customer.
 
7
 */
 
8
 
 
9
/*
 
10
 * Copyright (C) 4Front Technologies 2005-2009. Released under GPL2 license.
 
11
 */
 
12
//#include <linux/config.h>
 
13
typedef int *ioctl_arg;
 
14
#include <linux/init.h>
 
15
#include <linux/module.h>
 
16
#include <linux/delay.h>
 
17
#include <stdarg.h>
 
18
#include <linux/vmalloc.h>
 
19
#include "timestamp.h"
 
20
#include "local_config.h"
 
21
#include "oss_exports.h"
 
22
#include "wrap.h"
 
23
#include "ossdip.h"
 
24
#include <linux/version.h>
 
25
#include <linux/fs.h>
 
26
#include <linux/poll.h>
 
27
#include <linux/time.h>
 
28
#include <linux/proc_fs.h>
 
29
#include <linux/spinlock.h>
 
30
#include <linux/pci.h>
 
31
#include <linux/irq.h>
 
32
#include <linux/sched.h>
 
33
#include <linux/interrupt.h>
 
34
#undef strlen
 
35
#undef strcpy
 
36
#define strlen oss_strlen
 
37
#define strcpy oss_strcpy
 
38
 
 
39
typedef struct _smap_t dmap_t;
 
40
 
 
41
#include "soundcard.h"
 
42
#include "audio_core.h"
 
43
#include "mixer_core.h"
 
44
#include "ubuntu_version_hack.inc"
 
45
 
 
46
MODULE_LICENSE ("GPL v2");
 
47
MODULE_DESCRIPTION ("Open Sound System core services");
 
48
MODULE_AUTHOR ("4Front Technologies (support@opensound.com)");
 
49
 
 
50
struct _oss_mutex_t
 
51
{
 
52
  /* Caution! This definition must match cuckoo.h */
 
53
  spinlock_t lock;
 
54
  int filler;                   /* Make sure this structure doesn't become zero length */
 
55
};
 
56
 
 
57
static oss_device_t *core_osdev = NULL;
 
58
/*
 
59
 * Minor device list
 
60
 */
 
61
#define MAX_MINOR 256
 
62
typedef struct
 
63
{
 
64
  int major, minor;
 
65
  char name[32];
 
66
} oss_minor_t;
 
67
 
 
68
static oss_minor_t minors[MAX_MINOR];
 
69
static int nminors = 0;
 
70
 
 
71
/* 
 
72
 * Sleep flags. Make sure these definitions match oss_config.h.
 
73
 */
 
74
#define WK_NONE         0x00
 
75
#define WK_WAKEUP       0x01
 
76
#define WK_TIMEOUT      0x02
 
77
#define WK_SIGNAL       0x04
 
78
#define WK_SLEEP        0x08
 
79
#define WK_SELECT       0x10
 
80
 
 
81
time_t
 
82
oss_get_time (void)
 
83
{
 
84
#if 1
 
85
  return get_seconds ();
 
86
#else
 
87
  return xtime.tv_sec;
 
88
#endif
 
89
}
 
90
 
 
91
void *oss_memset (void *t, int val, size_t l);
 
92
 
 
93
void *
 
94
oss_kmem_alloc (size_t size)
 
95
{
 
96
  void *ptr;
 
97
  if ((ptr = vmalloc (size)) == NULL)
 
98
    {
 
99
      oss_cmn_err (CE_WARN, "vmalloc(%d) failed\n", size);
 
100
      return NULL;
 
101
    }
 
102
  memset (ptr, 0, size);
 
103
  return ptr;
 
104
}
 
105
 
 
106
void
 
107
oss_kmem_free (void *addr)
 
108
{
 
109
  vfree (addr);
 
110
}
 
111
 
 
112
/* oss_pmalloc() moved to os_linux.c */
 
113
 
 
114
extern oss_native_word
 
115
oss_virt_to_bus (void *addr)
 
116
{
 
117
  return virt_to_bus (addr);
 
118
}
 
119
 
 
120
void *
 
121
oss_memcpy (void *t_, const void *f_, size_t l)
 
122
{
 
123
  unsigned char *t = t_;
 
124
  unsigned const char *f = f_;
 
125
  int i;
 
126
 
 
127
  for (i = 0; i < l; i++)
 
128
    *t++ = *f++;
 
129
 
 
130
  return t;
 
131
}
 
132
 
 
133
void *
 
134
oss_memset (void *t, int val, size_t l)
 
135
{
 
136
  char *c = t;
 
137
  while (l-- > 0)
 
138
    *c++ = val;
 
139
 
 
140
  return t;
 
141
}
 
142
 
 
143
int
 
144
oss_strcmp (const char *s1, const char *s2)
 
145
{
 
146
  while (*s1 && *s2)
 
147
    {
 
148
      if (*s1 != *s2)
 
149
        return *s1 - *s2;
 
150
      s1++;
 
151
      s2++;
 
152
    }
 
153
 
 
154
  return *s1 - *s2;
 
155
}
 
156
 
 
157
int
 
158
oss_strncmp (const char *s1, const char *s2, size_t len)
 
159
{
 
160
  while (*s1 && *s2 && len--)
 
161
    {
 
162
      if (*s1 != *s2)
 
163
        return *s1 - *s2;
 
164
      s1++;
 
165
      s2++;
 
166
    }
 
167
 
 
168
  return *s1 - *s2;
 
169
}
 
170
 
 
171
char *
 
172
oss_strcpy (char *s1, const char *s2)
 
173
{
 
174
  char *s = s1;
 
175
 
 
176
  while (*s2)
 
177
    *s1++ = *s2++;
 
178
  *s1 = '\0';
 
179
  return s;
 
180
}
 
181
 
 
182
size_t
 
183
oss_strlen (const char *s)
 
184
{
 
185
  int i;
 
186
 
 
187
  for (i = 0; s[i]; i++);
 
188
 
 
189
  return i;
 
190
}
 
191
 
 
192
char *
 
193
oss_strncpy (char *s1, const char *s2, size_t l)
 
194
{
 
195
  char *s = s1;
 
196
  int n = 0;
 
197
 
 
198
  while (*s2)
 
199
    {
 
200
      if (n++ >= l)
 
201
        return s;
 
202
 
 
203
      *s1++ = *s2++;
 
204
    }
 
205
  *s1 = '\0';
 
206
  return s;
 
207
}
 
208
 
 
209
int oss_hz = HZ;
 
210
extern int max_intrate;
 
211
extern int detect_trace;
 
212
extern int src_quality;
 
213
extern int flat_device_model;
 
214
extern int vmix_disabled;
 
215
extern int vmix_no_autoattach;
 
216
extern int vmix_loopdevs;
 
217
extern int ac97_amplifier;
 
218
extern int ac97_recselect;
 
219
extern int cooked_enable;
 
220
extern int dma_buffsize;
 
221
extern int excl_policy;
 
222
extern int mixer_muted;
 
223
 
 
224
module_param (oss_hz, int, S_IRUGO);
 
225
module_param (max_intrate, int, S_IRUGO);
 
226
module_param (detect_trace, int, S_IRUGO);
 
227
module_param (src_quality, int, S_IRUGO);
 
228
module_param (flat_device_model, int, S_IRUGO);
 
229
module_param (vmix_disabled, int, S_IRUGO);
 
230
module_param (vmix_no_autoattach, int, S_IRUGO);
 
231
module_param (vmix_loopdevs, int, S_IRUGO);
 
232
module_param (ac97_amplifier, int, S_IRUGO);
 
233
module_param (ac97_recselect, int, S_IRUGO);
 
234
module_param (cooked_enable, int, S_IRUGO);
 
235
module_param (dma_buffsize, int, S_IRUGO);
 
236
module_param (excl_policy, int, S_IRUGO);
 
237
module_param (mixer_muted, int, S_IRUGO);
 
238
 
 
239
static struct proc_dir_entry *oss_proc_root = NULL;
 
240
static struct proc_dir_entry *oss_proc_devfiles = NULL;
 
241
 
 
242
static ssize_t
 
243
oss_read_devfiles (struct file *file, char __user * buf, size_t count,
 
244
                   loff_t * ppos)
 
245
{
 
246
  static char tmp[8192];
 
247
  char *s;
 
248
  static int eof = 0;
 
249
  int i;
 
250
 
 
251
  if (eof)
 
252
    {
 
253
      eof = 0;
 
254
      return 0;
 
255
    }
 
256
 
 
257
  *tmp = 0;
 
258
  s = tmp;
 
259
 
 
260
  for (i = 0; i < nminors; i++)
 
261
    {
 
262
      if (strlen (tmp) > sizeof (tmp) - 20)
 
263
        {
 
264
          printk (KERN_ALERT "osscore: Procfs buffer too small\n");
 
265
          return -ENOMEM;
 
266
        }
 
267
 
 
268
      s += sprintf (s, "%s %d %d\n",
 
269
                    minors[i].name, minors[i].major, minors[i].minor);
 
270
    }
 
271
 
 
272
  if (copy_to_user (buf, (void *) tmp, strlen (tmp)))
 
273
    return -EFAULT;
 
274
 
 
275
  eof = 1;
 
276
  return strlen (tmp);
 
277
}
 
278
 
 
279
static struct file_operations oss_proc_operations = {
 
280
  .read = oss_read_devfiles,
 
281
};
 
282
 
 
283
static void
 
284
init_proc_fs (void)
 
285
{
 
286
  if ((oss_proc_root =
 
287
       create_proc_entry ("opensound", 0700 | S_IFDIR, NULL)) == NULL)
 
288
    {
 
289
      oss_cmn_err (CE_CONT, "Cannot create /proc/opensound\n");
 
290
      return;
 
291
    }
 
292
 
 
293
  if ((oss_proc_devfiles =
 
294
       create_proc_entry ("devfiles", 0600, oss_proc_root)) == NULL)
 
295
    {
 
296
      oss_cmn_err (CE_CONT, "Cannot create /proc/opensound/devfiles\n");
 
297
      return;
 
298
    }
 
299
 
 
300
  oss_proc_devfiles->proc_fops = &oss_proc_operations;
 
301
}
 
302
 
 
303
static void
 
304
uninit_proc_fs (void)
 
305
{
 
306
  if (oss_proc_root)
 
307
    {
 
308
      if (oss_proc_devfiles)
 
309
        remove_proc_entry ("devfiles", oss_proc_root);
 
310
      remove_proc_entry ("opensound", NULL);
 
311
    }
 
312
}
 
313
 
 
314
static int
 
315
osscore_init (void)
 
316
{
 
317
  if ((core_osdev =
 
318
       osdev_create (NULL, DRV_UNKNOWN, 0, "osscore", NULL)) == NULL)
 
319
    {
 
320
      oss_cmn_err (CE_WARN, "Failed to allocate OSDEV structure\n");
 
321
      return -ENOMEM;
 
322
    }
 
323
 
 
324
  osdev_set_owner (core_osdev, THIS_MODULE);
 
325
 
 
326
  init_proc_fs ();
 
327
 
 
328
  return oss_init_osscore (core_osdev);
 
329
}
 
330
 
 
331
static void
 
332
osscore_exit (void)
 
333
{
 
334
  uninit_proc_fs ();
 
335
  oss_uninit_osscore (core_osdev);
 
336
}
 
337
 
 
338
void
 
339
oss_udelay (unsigned long d)
 
340
{
 
341
  udelay (d);
 
342
}
 
343
 
 
344
oss_mutex_t
 
345
oss_mutex_init (void)
 
346
{
 
347
  oss_mutex_t mutex;
 
348
 
 
349
  if ((mutex = vmalloc (sizeof (*mutex))) == NULL)
 
350
    {
 
351
      oss_cmn_err (CE_WARN, "vmalloc(%d) failed (mutex)\n", sizeof (*mutex));
 
352
      return NULL;
 
353
    }
 
354
 
 
355
  spin_lock_init (&(mutex->lock));
 
356
 
 
357
  return mutex;
 
358
}
 
359
 
 
360
void
 
361
oss_mutex_cleanup (oss_mutex_t mutex)
 
362
{
 
363
  vfree (mutex);
 
364
}
 
365
 
 
366
void
 
367
oss_spin_lock_irqsave (oss_mutex_t mutex, oss_native_word * flags)
 
368
{
 
369
  unsigned long flag;
 
370
  if (mutex == NULL)
 
371
    return;
 
372
  spin_lock_irqsave (&mutex->lock, flag);
 
373
  *flags = flag;
 
374
}
 
375
 
 
376
void
 
377
oss_spin_unlock_irqrestore (oss_mutex_t mutex, oss_native_word flags)
 
378
{
 
379
  if (mutex == NULL)
 
380
    return;
 
381
  spin_unlock_irqrestore (&mutex->lock, flags);
 
382
}
 
383
 
 
384
void
 
385
oss_spin_lock (oss_mutex_t mutex)
 
386
{
 
387
  if (mutex == NULL)
 
388
    return;
 
389
  spin_lock (&mutex->lock);
 
390
}
 
391
 
 
392
void
 
393
oss_spin_unlock (oss_mutex_t mutex)
 
394
{
 
395
  if (mutex == NULL)
 
396
    return;
 
397
  spin_unlock (&mutex->lock);
 
398
}
 
399
 
 
400
void *
 
401
oss_map_pci_mem (oss_device_t * osdev, int size, unsigned long offset)
 
402
{
 
403
#ifdef __arm__
 
404
  return (void*)offset;
 
405
#else
 
406
  return ioremap (offset, size);
 
407
#endif
 
408
}
 
409
 
 
410
void
 
411
oss_unmap_pci_mem (void *addr)
 
412
{
 
413
#ifndef __arm__
 
414
  iounmap (addr);
 
415
#endif
 
416
}
 
417
 
 
418
unsigned long long
 
419
oss_get_jiffies (void)
 
420
{
 
421
  return jiffies_64;
 
422
}
 
423
 
 
424
char *
 
425
oss_get_procname (void)
 
426
{
 
427
  return current->comm;
 
428
}
 
429
 
 
430
int
 
431
oss_get_pid (void)
 
432
{
 
433
  return current->pid;
 
434
}
 
435
 
 
436
int
 
437
oss_get_uid (void)
 
438
{
 
439
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,29)
 
440
  return current->cred->uid;
 
441
#else
 
442
  return current->uid;
 
443
#endif
 
444
}
 
445
 
 
446
typedef struct tmout_desc
 
447
{
 
448
  volatile int active;
 
449
  int timestamp;
 
450
  void (*func) (void *);
 
451
  void *arg;
 
452
 
 
453
  struct timer_list timer;
 
454
} tmout_desc_t;
 
455
 
 
456
static volatile int next_id = 0;
 
457
#define MAX_TMOUTS 128
 
458
 
 
459
tmout_desc_t tmouts[MAX_TMOUTS] = { {0} };
 
460
 
 
461
int timeout_random = 0x12123400;
 
462
 
 
463
void
 
464
oss_timer_callback (unsigned long id)
 
465
{
 
466
  tmout_desc_t *tmout;
 
467
  int ix;
 
468
  void *arg;
 
469
 
 
470
  timeout_random++;
 
471
 
 
472
  ix = id & 0xff;
 
473
  if (ix < 0 || ix >= MAX_TMOUTS)
 
474
    return;
 
475
  tmout = &tmouts[ix];
 
476
 
 
477
  if (tmout->timestamp != id)   /* Expired timer */
 
478
    return;
 
479
 
 
480
  if (!tmout->active)
 
481
    return;
 
482
 
 
483
  arg = tmout->arg;
 
484
  tmout->active = 0;
 
485
  tmout->timestamp = 0;
 
486
 
 
487
  tmout->func (arg);
 
488
}
 
489
 
 
490
timeout_id_t
 
491
oss_timeout (void (*func) (void *), void *arg, unsigned long long ticks)
 
492
{
 
493
  tmout_desc_t *tmout = NULL;
 
494
  int id, n;
 
495
 
 
496
  timeout_random++;
 
497
 
 
498
  n = 0;
 
499
  id = -1;
 
500
 
 
501
  while (id == -1 && n < MAX_TMOUTS)
 
502
    {
 
503
      if (!tmouts[next_id].active)
 
504
        {
 
505
          tmouts[next_id].active = 1;
 
506
          id = next_id++;
 
507
          tmout = &tmouts[id];
 
508
          break;
 
509
        }
 
510
 
 
511
      next_id = (next_id + 1) % MAX_TMOUTS;
 
512
    }
 
513
 
 
514
  if (id == -1)                 /* No timer slots available */
 
515
    {
 
516
      oss_cmn_err (CE_WARN, "Timeout table full\n");
 
517
      return 0;
 
518
    }
 
519
 
 
520
  tmout->func = func;
 
521
  tmout->arg = arg;
 
522
  tmout->timestamp = id | (timeout_random & ~0xff);
 
523
 
 
524
  init_timer (&tmout->timer);
 
525
  tmout->timer.expires = jiffies + ticks;
 
526
  tmout->timer.data = id | (timeout_random & ~0xff);
 
527
  tmout->timer.function = oss_timer_callback;
 
528
  add_timer (&tmout->timer);
 
529
 
 
530
  return id | (timeout_random & ~0xff);
 
531
}
 
532
 
 
533
void
 
534
oss_untimeout (timeout_id_t id)
 
535
{
 
536
  tmout_desc_t *tmout;
 
537
  int ix;
 
538
 
 
539
  ix = id & 0xff;
 
540
  if (ix < 0 || ix >= MAX_TMOUTS)
 
541
    return;
 
542
 
 
543
  timeout_random++;
 
544
  tmout = &tmouts[ix];
 
545
 
 
546
  if (tmout->timestamp != id)   /* Expired timer */
 
547
    return;
 
548
  if (tmout->active)
 
549
    del_timer (&tmout->timer);
 
550
  tmout->active = 0;
 
551
  tmout->timestamp = 0;
 
552
}
 
553
 
 
554
int
 
555
oss_uiomove (void *addr, size_t nbytes, enum uio_rw rwflag, uio_t * uio)
 
556
{
 
557
/*
 
558
 * NOTE! Returns 0 upon success and EFAULT on failure (instead of -EFAULT
 
559
 * (for Solaris/BSD compatibilityi)).
 
560
 */
 
561
 
 
562
  int c;
 
563
  char *address = addr;
 
564
 
 
565
  if (rwflag != uio->rw)
 
566
    {
 
567
      oss_cmn_err (CE_WARN, "uiomove: Bad direction\n");
 
568
      return EFAULT;
 
569
    }
 
570
 
 
571
  if (uio->resid < nbytes)
 
572
    {
 
573
      oss_cmn_err (CE_WARN, "uiomove: Bad count %d (%d)\n", nbytes,
 
574
                   uio->resid);
 
575
      return EFAULT;
 
576
    }
 
577
 
 
578
  if (uio->kernel_space)
 
579
    return EFAULT;
 
580
 
 
581
  switch (rwflag)
 
582
    {
 
583
    case UIO_READ:
 
584
      c = nbytes;
 
585
      if (c > 10)
 
586
        c = 0;
 
587
 
 
588
      if ((c = copy_to_user (uio->ptr, address, nbytes) != 0))
 
589
        {
 
590
          uio->resid -= nbytes;
 
591
          oss_cmn_err (CE_CONT, "copy_to_user(%d) failed (%d)\n", nbytes, c);
 
592
          return EFAULT;
 
593
        }
 
594
      break;
 
595
 
 
596
    case UIO_WRITE:
 
597
      if (copy_from_user (address, uio->ptr, nbytes) != 0)
 
598
        {
 
599
          oss_cmn_err (CE_CONT, "copy_from_user failed\n");
 
600
          uio->resid -= nbytes;
 
601
          return EFAULT;
 
602
        }
 
603
      break;
 
604
    }
 
605
 
 
606
  uio->resid -= nbytes;
 
607
  uio->ptr += nbytes;
 
608
 
 
609
  return 0;
 
610
}
 
611
 
 
612
int
 
613
oss_create_uio (uio_t * uio, char *buf, size_t count, uio_rw_t rw,
 
614
                int is_kernel)
 
615
{
 
616
  memset (uio, 0, sizeof (*uio));
 
617
 
 
618
  if (is_kernel)
 
619
    {
 
620
      oss_cmn_err (CE_CONT,
 
621
                   "oss_create_uio: Kernel space buffers not supported\n");
 
622
      return -EIO;
 
623
    }
 
624
 
 
625
  uio->ptr = buf;
 
626
  uio->resid = count;
 
627
  uio->kernel_space = is_kernel;
 
628
  uio->rw = rw;
 
629
 
 
630
  return 0;
 
631
}
 
632
 
 
633
void
 
634
oss_cmn_err (int level, const char *s, ...)
 
635
{
 
636
  char tmp[1024], *a[6];
 
637
  va_list ap;
 
638
  int i, n = 0;
 
639
 
 
640
  va_start (ap, s);
 
641
 
 
642
  for (i = 0; i < strlen (s); i++)
 
643
    if (s[i] == '%')
 
644
      n++;
 
645
 
 
646
  for (i = 0; i < n && i < 6; i++)
 
647
    a[i] = va_arg (ap, char *);
 
648
 
 
649
  for (i = n; i < 6; i++)
 
650
    a[i] = NULL;
 
651
 
 
652
  if (level == CE_CONT)
 
653
    {
 
654
      sprintf (tmp, s, a[0], a[1], a[2], a[3], a[4], a[5], NULL,
 
655
               NULL, NULL, NULL);
 
656
      printk ("%s", tmp);
 
657
    }
 
658
  else
 
659
    {
 
660
      strcpy (tmp, "osscore: ");
 
661
      sprintf (tmp + strlen (tmp), s, a[0], a[1], a[2], a[3], a[4], a[5],
 
662
               NULL, NULL, NULL, NULL);
 
663
      if (level == CE_PANIC)
 
664
        panic (tmp);
 
665
 
 
666
      printk (KERN_ALERT "%s", tmp);
 
667
    }
 
668
#if 0
 
669
  /* This may cause a crash under SMP */
 
670
  if (sound_started)
 
671
    store_msg (tmp);
 
672
#endif
 
673
 
 
674
  va_end (ap);
 
675
}
 
676
 
 
677
/*
 
678
 * Sleep/wakeup
 
679
 */
 
680
 
 
681
struct oss_wait_queue
 
682
{
 
683
  volatile int flags;
 
684
  wait_queue_head_t wq;
 
685
};
 
686
 
 
687
struct oss_wait_queue *
 
688
oss_create_wait_queue (oss_device_t * osdev, const char *name)
 
689
{
 
690
  struct oss_wait_queue *wq;
 
691
 
 
692
  if ((wq = vmalloc (sizeof (*wq))) == NULL)
 
693
    {
 
694
      oss_cmn_err (CE_WARN, "vmalloc(%d) failed (wq)\n", sizeof (*wq));
 
695
      return NULL;
 
696
    }
 
697
  init_waitqueue_head (&wq->wq);
 
698
 
 
699
  return wq;
 
700
}
 
701
 
 
702
void
 
703
oss_reset_wait_queue (struct oss_wait_queue *wq)
 
704
{
 
705
  wq->flags = 0;
 
706
}
 
707
 
 
708
void
 
709
oss_remove_wait_queue (struct oss_wait_queue *wq)
 
710
{
 
711
  vfree (wq);
 
712
}
 
713
 
 
714
int
 
715
oss_sleep (struct oss_wait_queue *wq, oss_mutex_t * mutex, int ticks,
 
716
           oss_native_word * flags, unsigned int *status)
 
717
{
 
718
  int result = 0;
 
719
  *status = 0;
 
720
 
 
721
  if (wq == NULL)
 
722
    return 0;
 
723
 
 
724
  wq->flags = 0;
 
725
  oss_spin_unlock_irqrestore (*mutex, *flags);
 
726
 
 
727
  if (ticks <= 0)
 
728
    result = wait_event_interruptible (wq->wq, (wq->flags & WK_WAKEUP));
 
729
  else
 
730
    result =
 
731
      wait_event_interruptible_timeout (wq->wq, (wq->flags & WK_WAKEUP),
 
732
                                        ticks);
 
733
 
 
734
  oss_spin_lock_irqsave (*mutex, flags);
 
735
 
 
736
  if (result < 0)               /* Signal received */
 
737
    {
 
738
      *status |= WK_SIGNAL;
 
739
      return 1;
 
740
    }
 
741
 
 
742
  if (!(wq->flags & WK_WAKEUP)) /* Timeout */
 
743
    {
 
744
      return 0;
 
745
    }
 
746
 
 
747
  return 1;
 
748
}
 
749
 
 
750
int
 
751
oss_register_poll (struct oss_wait_queue *wq, oss_mutex_t * mutex,
 
752
                   oss_native_word * flags, oss_poll_event_t * ev)
 
753
{
 
754
  oss_spin_unlock_irqrestore (*mutex, *flags);
 
755
  poll_wait ((struct file *) ev->file, &wq->wq,
 
756
             (struct poll_table_struct *) ev->wait);
 
757
  oss_spin_lock_irqsave (*mutex, flags);
 
758
  return 0;
 
759
}
 
760
 
 
761
void
 
762
oss_wakeup (struct oss_wait_queue *wq, oss_mutex_t * mutex,
 
763
            oss_native_word * flags, short events)
 
764
{
 
765
  if (wq == NULL)
 
766
    return;
 
767
 
 
768
  wq->flags |= WK_WAKEUP;
 
769
  oss_spin_unlock_irqrestore (*mutex, *flags);
 
770
  wake_up (&wq->wq);
 
771
  oss_spin_lock_irqsave (*mutex, flags);
 
772
}
 
773
 
 
774
void
 
775
oss_reserve_pages (oss_native_word start_addr, oss_native_word end_addr)
 
776
{
 
777
  struct page *page, *lastpage;
 
778
 
 
779
  lastpage = virt_to_page (end_addr);
 
780
 
 
781
  for (page = virt_to_page (start_addr); page <= lastpage; page++)
 
782
    set_bit (PG_reserved, &page->flags);
 
783
}
 
784
 
 
785
void
 
786
oss_unreserve_pages (oss_native_word start_addr, oss_native_word end_addr)
 
787
{
 
788
  struct page *page, *lastpage;
 
789
 
 
790
  lastpage = virt_to_page (end_addr);
 
791
 
 
792
  for (page = virt_to_page (start_addr); page <= lastpage; page++)
 
793
    clear_bit (PG_reserved, &page->flags);
 
794
}
 
795
 
 
796
void *
 
797
oss_contig_malloc (oss_device_t * osdev, int buffsize, oss_uint64_t memlimit,
 
798
                   oss_native_word * phaddr)
 
799
{
 
800
  char *start_addr, *end_addr;
 
801
  int sz, size;
 
802
  int flags = 0;
 
803
 
 
804
  *phaddr = 0;
 
805
 
 
806
#ifdef GFP_DMA32
 
807
  if (memlimit < 0x0000000100000000LL)
 
808
    flags |= GFP_DMA32;
 
809
#endif
 
810
 
 
811
  if (memlimit < 0x00000000ffffffffLL)
 
812
    flags |= GFP_DMA;
 
813
 
 
814
  start_addr = NULL;
 
815
 
 
816
  for (sz = 0, size = PAGE_SIZE; size < buffsize; sz++, size <<= 1);
 
817
 
 
818
  if (buffsize != (PAGE_SIZE * (1 << sz)))
 
819
    {
 
820
#if 0
 
821
      printk
 
822
        ("Contig_malloc: Invalid size %d != %ld\n", buffsize,
 
823
         PAGE_SIZE * (1 << sz));
 
824
#endif
 
825
    }
 
826
 
 
827
  start_addr = (char *) __get_free_pages (GFP_KERNEL | flags, sz);
 
828
 
 
829
  if (start_addr == NULL)
 
830
    {
 
831
      cmn_err (CE_NOTE, "Failed to allocate memory buffer of %d bytes\n",
 
832
               buffsize);
 
833
      return NULL;
 
834
    }
 
835
  else
 
836
    {
 
837
      /* make some checks */
 
838
      end_addr = start_addr + buffsize - 1;
 
839
 
 
840
      oss_reserve_pages ((oss_native_word) start_addr,
 
841
                         (oss_native_word) end_addr);
 
842
    }
 
843
 
 
844
  *phaddr = virt_to_bus (start_addr);
 
845
  return start_addr;
 
846
}
 
847
 
 
848
void
 
849
oss_contig_free (oss_device_t * osdev, void *p, int buffsize)
 
850
{
 
851
  int sz, size;
 
852
  caddr_t start_addr, end_addr;
 
853
 
 
854
  if (p == NULL)
 
855
    return;
 
856
 
 
857
  for (sz = 0, size = PAGE_SIZE; size < buffsize; sz++, size <<= 1);
 
858
 
 
859
  start_addr = p;
 
860
  end_addr = p + buffsize - 1;
 
861
 
 
862
  oss_unreserve_pages ((oss_native_word) start_addr,
 
863
                       (oss_native_word) end_addr);
 
864
  free_pages ((unsigned long) p, sz);
 
865
}
 
866
 
 
867
/*
 
868
 * These typedefs must match definition of struct file_operations.
 
869
 * (See notes in routine oss_register_chrdev).
 
870
 */
 
871
typedef ssize_t (*read_t) (struct file *, char *, size_t, loff_t *);
 
872
typedef ssize_t (*write_t) (struct file *, const char *, size_t, loff_t *);
 
873
typedef unsigned int (*poll_t) (struct file *, poll_table *);
 
874
typedef poll_table select_table;
 
875
 
 
876
typedef int (*readdir_t) (struct inode *, struct file *, void *, filldir_t);
 
877
typedef int (*ioctl_t) (struct inode *, struct file *, unsigned int,
 
878
                        unsigned long);
 
879
typedef long (*new_ioctl_t) (struct file *, unsigned int, unsigned long);
 
880
typedef int (*mmap_t) (struct file *, struct vm_area_struct *);
 
881
typedef int (*open_t) (struct inode *, struct file *);
 
882
 
 
883
typedef int (*release_t) (struct inode *, struct file *);
 
884
typedef int (*fasync_t) (int, struct file *, int);
 
885
typedef int (*fsync_t) (struct inode *, struct file *);
 
886
 
 
887
static loff_t
 
888
oss_no_llseek (struct file *file, loff_t offset, int orig)
 
889
{
 
890
  return -EINVAL;
 
891
}
 
892
 
 
893
static int
 
894
oss_no_fsync (struct file *f, struct dentry *d, int datasync)
 
895
{
 
896
  return -EINVAL;
 
897
}
 
898
 
 
899
static int
 
900
oss_no_fasync (int x, struct file *f, int m)
 
901
{
 
902
  return -EINVAL;
 
903
}
 
904
 
 
905
/*
 
906
 *      Wrappers for installing and uninstalling character and block devices.
 
907
 *
 
908
 *      The oss_file_operation_handle structure differs from kernel's
 
909
 *      file_operations structure in parameters of the driver entry points.
 
910
 *      Kernel inode, file, wait_struct, vm_are_struct etc. typed arguments
 
911
 *      are replaced by wrapper handles.
 
912
 */
 
913
 
 
914
static struct file_operations *
 
915
alloc_fop (oss_device_t * osdev, struct oss_file_operation_handle *op)
 
916
{
 
917
/*
 
918
 *      This routine performs initialization of kernel file_operations structure
 
919
 *      from oss_file_operation_handle structure. Each procedure pointer is copied
 
920
 *      to a temporary variable before doing the actual assignment. This 
 
921
 *      prevents unnecessary warnings while it still enables compatibility
 
922
 *      warnings.
 
923
 *
 
924
 *      Any warning given by this routine may indicate that kernel fs
 
925
 *      call interface has changed significantly (added parameters to the routines).
 
926
 *      In this case definition routine in oss_file_operation_handle must be updated
 
927
 *      and WRAPPER_VERSION must be incremented.
 
928
 */
 
929
 
 
930
  struct file_operations *fop;
 
931
 
 
932
  poll_t tmp_poll = (poll_t) op->poll;
 
933
  read_t tmp_read = (read_t) op->read;
 
934
  write_t tmp_write = (write_t) op->write;
 
935
  /* readdir_t tmp_readdir = (readdir_t)op->readdir; */
 
936
#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,35)
 
937
  ioctl_t tmp_ioctl = (ioctl_t) op->ioctl;
 
938
#endif
 
939
  mmap_t tmp_mmap = (mmap_t) op->mmap;
 
940
  open_t tmp_open = (open_t) op->open;
 
941
  release_t tmp_release = (release_t) op->release;
 
942
  new_ioctl_t tmp_unlocked_ioctl = (new_ioctl_t) op->unlocked_ioctl;
 
943
  new_ioctl_t tmp_compat_ioctl = (new_ioctl_t) op->compat_ioctl;
 
944
 
 
945
  fop = (struct file_operations *)
 
946
    oss_kmem_alloc (sizeof (struct file_operations));
 
947
 
 
948
  memset ((char *) fop, 0, sizeof (struct file_operations));
 
949
 
 
950
/*
 
951
 *      Now the assignment
 
952
 */
 
953
  fop->llseek = oss_no_llseek;
 
954
  fop->read = tmp_read;
 
955
  fop->write = tmp_write;
 
956
  fop->readdir = NULL;          /* tmp_readdir; */
 
957
  fop->poll = tmp_poll;
 
958
#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,35)
 
959
  fop->ioctl = tmp_ioctl;
 
960
#endif
 
961
  fop->mmap = tmp_mmap;
 
962
  fop->open = tmp_open;
 
963
  fop->release = tmp_release;
 
964
  fop->fsync = oss_no_fsync;
 
965
  fop->fasync = oss_no_fasync;
 
966
  fop->lock = NULL;
 
967
  fop->flush = NULL;
 
968
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
 
969
  fop->owner = osdev_get_owner (osdev);
 
970
#endif
 
971
#ifdef HAVE_UNLOCKED_IOCTL
 
972
  fop->unlocked_ioctl = tmp_unlocked_ioctl;
 
973
#endif
 
974
#ifdef HAVE_COMPAT_IOCTL
 
975
  fop->compat_ioctl = tmp_compat_ioctl;
 
976
#endif
 
977
 
 
978
  return fop;
 
979
}
 
980
 
 
981
int
 
982
oss_register_chrdev (oss_device_t * osdev, unsigned int major,
 
983
                     const char *name, struct oss_file_operation_handle *op)
 
984
{
 
985
  int maj;
 
986
  maj = register_chrdev (major, name, alloc_fop (osdev, op));
 
987
 
 
988
  return maj;
 
989
}
 
990
 
 
991
void
 
992
oss_register_minor (int major, int minor, char *name)
 
993
{
 
994
  if (nminors >= MAX_MINOR)
 
995
    {
 
996
      oss_cmn_err (CE_WARN, "Too many device files\n");
 
997
      return;
 
998
    }
 
999
 
 
1000
  minors[nminors].major = major;
 
1001
  minors[nminors].minor = minor;
 
1002
  strcpy (minors[nminors].name, name);
 
1003
  nminors++;
 
1004
}
 
1005
 
 
1006
int
 
1007
oss_unregister_chrdev (unsigned int major, const char *name)
 
1008
{
 
1009
  unregister_chrdev (major, name);
 
1010
  return 0;
 
1011
}
 
1012
 
 
1013
int
 
1014
oss_inode_get_minor (oss_inode_handle_t * inode)
 
1015
{
 
1016
  return MINOR (((struct inode *) inode)->i_rdev);
 
1017
}
 
1018
 
 
1019
int
 
1020
oss_file_get_flags (oss_file_handle_t * file)
 
1021
{
 
1022
  return ((struct file *) file)->f_flags;
 
1023
}
 
1024
 
 
1025
void *
 
1026
oss_file_get_private (oss_file_handle_t * file)
 
1027
{
 
1028
  return ((struct file *) file)->private_data;
 
1029
}
 
1030
 
 
1031
void
 
1032
oss_file_set_private (oss_file_handle_t * file, void *v)
 
1033
{
 
1034
  ((struct file *) file)->private_data = v;
 
1035
}
 
1036
 
 
1037
int
 
1038
oss_vma_get_flags (oss_vm_area_handle_t * vma)
 
1039
{
 
1040
  return ((struct vm_area_struct *) vma)->vm_flags;
 
1041
}
 
1042
 
 
1043
int
 
1044
oss_do_mmap (oss_vm_area_handle_t * v, oss_native_word dmabuf_phys,
 
1045
             int bytes_in_use)
 
1046
{
 
1047
  struct vm_area_struct *vma = (struct vm_area_struct *) v;
 
1048
  int res, size;
 
1049
 
 
1050
  if (vma->vm_pgoff != 0)
 
1051
    {
 
1052
      oss_cmn_err (CE_WARN, "mmap() offset must be 0.\n");
 
1053
      return -EINVAL;
 
1054
    }
 
1055
 
 
1056
  size = vma->vm_end - vma->vm_start;
 
1057
 
 
1058
  if (size != bytes_in_use)
 
1059
    {
 
1060
      oss_cmn_err (CE_WARN, "mmap() size = %ld. Should be %d\n",
 
1061
                   size, bytes_in_use);
 
1062
      return -EBUSY;
 
1063
    }
 
1064
 
 
1065
#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,13)
 
1066
  res = io_remap_page_range (vma, vma->vm_start,
 
1067
                             dmabuf_phys, size, vma->vm_page_prot);
 
1068
 
 
1069
#else
 
1070
  res = io_remap_pfn_range (vma, vma->vm_start,
 
1071
                            dmabuf_phys >> PAGE_SHIFT,
 
1072
                            size, vma->vm_page_prot);
 
1073
#endif
 
1074
 
 
1075
  if (res)
 
1076
    {
 
1077
      oss_cmn_err (CE_WARN, "io_remap_pfn_range returned %d\n", res);
 
1078
      return -EAGAIN;
 
1079
    }
 
1080
 
 
1081
  return 0;
 
1082
}
 
1083
 
 
1084
/* As a special exception, if you link this library with other files,
 
1085
   some of which are compiled with GCC, to produce an executable,
 
1086
   this library does not by itself cause the resulting executable
 
1087
   to be covered by the GNU General Public License.
 
1088
   This exception does not however invalidate any other reasons why
 
1089
   the executable file might be covered by the GNU General Public License.  */
 
1090
 
 
1091
typedef unsigned int UQItype __attribute__ ((mode (QI)));
 
1092
typedef int SItype __attribute__ ((mode (SI)));
 
1093
typedef unsigned int USItype __attribute__ ((mode (SI)));
 
1094
typedef int DItype __attribute__ ((mode (DI)));
 
1095
typedef unsigned int UDItype __attribute__ ((mode (DI)));
 
1096
 
 
1097
typedef int word_type __attribute__ ((mode (__word__)));
 
1098
 
 
1099
/* DIstructs are pairs of SItype values in the order determined by
 
1100
   little/big ENDIAN.  */
 
1101
 
 
1102
#if defined(__i386__) || defined(__x86_64__)
 
1103
struct DIstruct
 
1104
{
 
1105
  SItype low, high;
 
1106
};
 
1107
#endif
 
1108
 
 
1109
 
 
1110
#ifndef __arm__
 
1111
/* We need this union to unpack/pack DImode values, since we don't have
 
1112
   any arithmetic yet.  Incoming DImode parameters are stored into the
 
1113
   `ll' field, and the unpacked result is read from the struct `s'.  */
 
1114
 
 
1115
typedef union
 
1116
{
 
1117
  struct DIstruct s;
 
1118
  DItype ll;
 
1119
} DIunion;
 
1120
 
 
1121
 
 
1122
/*  From gcc/longlong.h  */
 
1123
 
 
1124
#ifndef SI_TYPE_SIZE
 
1125
#define SI_TYPE_SIZE 32
 
1126
#endif
 
1127
 
 
1128
#define __BITS4 (SI_TYPE_SIZE / 4)
 
1129
#define __ll_B (1L << (SI_TYPE_SIZE / 2))
 
1130
#define __ll_lowpart(t) ((USItype) (t) % __ll_B)
 
1131
#define __ll_highpart(t) ((USItype) (t) / __ll_B)
 
1132
 
 
1133
#if defined(__i386__) || defined(__x86_64__)
 
1134
#define sub_ddmmss(sh, sl, ah, al, bh, bl) \
 
1135
  __asm__ ("subl %5,%1\n"                                               \
 
1136
        "sbbl %3,%0"                                                    \
 
1137
           : "=r" ((USItype) (sh)),                                     \
 
1138
             "=&r" ((USItype) (sl))                                     \
 
1139
           : "0" ((USItype) (ah)),                                      \
 
1140
             "g" ((USItype) (bh)),                                      \
 
1141
             "1" ((USItype) (al)),                                      \
 
1142
             "g" ((USItype) (bl)))
 
1143
#define umul_ppmm(w1, w0, u, v) \
 
1144
  __asm__ ("mull %3"                                                    \
 
1145
           : "=a" ((USItype) (w0)),                                     \
 
1146
             "=d" ((USItype) (w1))                                      \
 
1147
           : "%0" ((USItype) (u)),                                      \
 
1148
             "rm" ((USItype) (v)))
 
1149
#define udiv_qrnnd(q, r, n1, n0, d) \
 
1150
  __asm__ ("divl %4"                                                    \
 
1151
           : "=a" ((USItype) (q)),                                      \
 
1152
             "=d" ((USItype) (r))                                       \
 
1153
           : "0" ((USItype) (n0)),                                      \
 
1154
             "1" ((USItype) (n1)),                                      \
 
1155
             "rm" ((USItype) (d)))
 
1156
#define count_leading_zeros(count, x) \
 
1157
  do {                                                                  \
 
1158
    USItype __cbtmp;                                                    \
 
1159
    __asm__ ("bsrl %1,%0"                                               \
 
1160
             : "=r" (__cbtmp) : "rm" ((USItype) (x)));                  \
 
1161
    (count) = __cbtmp ^ 31;                                             \
 
1162
  } while (0)
 
1163
#endif /* __i386__ */
 
1164
 
 
1165
/* If this machine has no inline assembler, use C macros.  */
 
1166
 
 
1167
/* Define this unconditionally, so it can be used for debugging.  */
 
1168
#define __udiv_qrnnd_c(q, r, n1, n0, d)  \
 
1169
  do { \
 
1170
    USItype __d1, __d0, __q1, __q0;                                     \
 
1171
    USItype __r1, __r0, __m;                                            \
 
1172
    __d1 = __ll_highpart (d);                                           \
 
1173
    __d0 = __ll_lowpart (d);                                            \
 
1174
                                                                        \
 
1175
    __r1 = (n1) % __d1;                                                 \
 
1176
    __q1 = (n1) / __d1;                                                 \
 
1177
    __m = (USItype) __q1 * __d0;                                        \
 
1178
    __r1 = __r1 * __ll_B | __ll_highpart (n0);                          \
 
1179
    if (__r1 < __m)                                                     \
 
1180
      {                                                                 \
 
1181
        __q1--, __r1 += (d);                                            \
 
1182
        if (__r1 >= (d)) /* i.e. we didn't get carry when adding to __r1 */\
 
1183
          if (__r1 < __m)                                               \
 
1184
            __q1--, __r1 += (d);                                        \
 
1185
      }                                                                 \
 
1186
    __r1 -= __m;                                                        \
 
1187
                                                                        \
 
1188
    __r0 = __r1 % __d1;                                                 \
 
1189
    __q0 = __r1 / __d1;                                                 \
 
1190
    __m = (USItype) __q0 * __d0;                                        \
 
1191
    __r0 = __r0 * __ll_B | __ll_lowpart (n0);                           \
 
1192
    if (__r0 < __m)                                                     \
 
1193
      {                                                                 \
 
1194
        __q0--, __r0 += (d);                                            \
 
1195
        if (__r0 >= (d))                                                \
 
1196
          if (__r0 < __m)                                               \
 
1197
            __q0--, __r0 += (d);                                        \
 
1198
      }                                                                 \
 
1199
    __r0 -= __m;                                                        \
 
1200
                                                                        \
 
1201
    (q) = (USItype) __q1 * __ll_B | __q0;                               \
 
1202
    (r) = __r0;                                                         \
 
1203
  } while (0)
 
1204
 
 
1205
/* If udiv_qrnnd was not defined for this processor, use __udiv_qrnnd_c.  */
 
1206
#if !defined (udiv_qrnnd)
 
1207
#define UDIV_NEEDS_NORMALIZATION 1
 
1208
#define udiv_qrnnd __udiv_qrnnd_c
 
1209
#endif
 
1210
 
 
1211
/*  End of gcc/longlong.h  */
 
1212
 
 
1213
 
 
1214
static inline DItype
 
1215
__negdi2 (DItype u)
 
1216
{
 
1217
  DIunion w;
 
1218
  DIunion uu;
 
1219
 
 
1220
  uu.ll = u;
 
1221
 
 
1222
  w.s.low = -uu.s.low;
 
1223
  w.s.high = -uu.s.high - ((USItype) w.s.low > 0);
 
1224
 
 
1225
  return w.ll;
 
1226
}
 
1227
 
 
1228
static inline UDItype
 
1229
__udivmoddi4 (UDItype n, UDItype d, UDItype * rp)
 
1230
{
 
1231
  DIunion ww;
 
1232
  DIunion nn, dd;
 
1233
  DIunion rr;
 
1234
  USItype d0, d1, n0, n1, n2;
 
1235
  USItype q0, q1;
 
1236
  USItype b, bm;
 
1237
 
 
1238
  nn.ll = n;
 
1239
  dd.ll = d;
 
1240
 
 
1241
  d0 = dd.s.low;
 
1242
  d1 = dd.s.high;
 
1243
  n0 = nn.s.low;
 
1244
  n1 = nn.s.high;
 
1245
 
 
1246
#ifndef UDIV_NEEDS_NORMALIZATION
 
1247
  if (d1 == 0)
 
1248
    {
 
1249
      if (d0 > n1)
 
1250
        {
 
1251
          /* 0q = nn / 0D */
 
1252
 
 
1253
          udiv_qrnnd (q0, n0, n1, n0, d0);
 
1254
          q1 = 0;
 
1255
 
 
1256
          /* Remainder in n0.  */
 
1257
        }
 
1258
      else
 
1259
        {
 
1260
          /* qq = NN / 0d */
 
1261
 
 
1262
          if (d0 == 0)
 
1263
            d0 = 1 / d0;        /* Divide intentionally by zero.  */
 
1264
 
 
1265
          udiv_qrnnd (q1, n1, 0, n1, d0);
 
1266
          udiv_qrnnd (q0, n0, n1, n0, d0);
 
1267
 
 
1268
          /* Remainder in n0.  */
 
1269
        }
 
1270
 
 
1271
      if (rp != 0)
 
1272
        {
 
1273
          rr.s.low = n0;
 
1274
          rr.s.high = 0;
 
1275
          *rp = rr.ll;
 
1276
        }
 
1277
    }
 
1278
 
 
1279
#else /* UDIV_NEEDS_NORMALIZATION */
 
1280
 
 
1281
  if (d1 == 0)
 
1282
    {
 
1283
      if (d0 > n1)
 
1284
        {
 
1285
          /* 0q = nn / 0D */
 
1286
 
 
1287
          count_leading_zeros (bm, d0);
 
1288
 
 
1289
          if (bm != 0)
 
1290
            {
 
1291
              /* Normalize, i.e. make the most significant bit of the
 
1292
                 denominator set.  */
 
1293
 
 
1294
              d0 = d0 << bm;
 
1295
              n1 = (n1 << bm) | (n0 >> (SI_TYPE_SIZE - bm));
 
1296
              n0 = n0 << bm;
 
1297
            }
 
1298
 
 
1299
          udiv_qrnnd (q0, n0, n1, n0, d0);
 
1300
          q1 = 0;
 
1301
 
 
1302
          /* Remainder in n0 >> bm.  */
 
1303
        }
 
1304
      else
 
1305
        {
 
1306
          /* qq = NN / 0d */
 
1307
 
 
1308
          if (d0 == 0)
 
1309
            d0 = 1 / d0;        /* Divide intentionally by zero.  */
 
1310
 
 
1311
          count_leading_zeros (bm, d0);
 
1312
 
 
1313
          if (bm == 0)
 
1314
            {
 
1315
              /* From (n1 >= d0) /\ (the most significant bit of d0 is set),
 
1316
                 conclude (the most significant bit of n1 is set) /\ (the
 
1317
                 leading quotient digit q1 = 1).
 
1318
 
 
1319
                 This special case is necessary, not an optimization.
 
1320
                 (Shifts counts of SI_TYPE_SIZE are undefined.)  */
 
1321
 
 
1322
              n1 -= d0;
 
1323
              q1 = 1;
 
1324
            }
 
1325
          else
 
1326
            {
 
1327
              /* Normalize.  */
 
1328
 
 
1329
              b = SI_TYPE_SIZE - bm;
 
1330
 
 
1331
              d0 = d0 << bm;
 
1332
              n2 = n1 >> b;
 
1333
              n1 = (n1 << bm) | (n0 >> b);
 
1334
              n0 = n0 << bm;
 
1335
 
 
1336
              udiv_qrnnd (q1, n1, n2, n1, d0);
 
1337
            }
 
1338
 
 
1339
          /* n1 != d0...  */
 
1340
 
 
1341
          udiv_qrnnd (q0, n0, n1, n0, d0);
 
1342
 
 
1343
          /* Remainder in n0 >> bm.  */
 
1344
        }
 
1345
 
 
1346
      if (rp != 0)
 
1347
        {
 
1348
          rr.s.low = n0 >> bm;
 
1349
          rr.s.high = 0;
 
1350
          *rp = rr.ll;
 
1351
        }
 
1352
    }
 
1353
#endif /* UDIV_NEEDS_NORMALIZATION */
 
1354
 
 
1355
  else
 
1356
    {
 
1357
      if (d1 > n1)
 
1358
        {
 
1359
          /* 00 = nn / DD */
 
1360
 
 
1361
          q0 = 0;
 
1362
          q1 = 0;
 
1363
 
 
1364
          /* Remainder in n1n0.  */
 
1365
          if (rp != 0)
 
1366
            {
 
1367
              rr.s.low = n0;
 
1368
              rr.s.high = n1;
 
1369
              *rp = rr.ll;
 
1370
            }
 
1371
        }
 
1372
      else
 
1373
        {
 
1374
          /* 0q = NN / dd */
 
1375
 
 
1376
          count_leading_zeros (bm, d1);
 
1377
          if (bm == 0)
 
1378
            {
 
1379
              /* From (n1 >= d1) /\ (the most significant bit of d1 is set),
 
1380
                 conclude (the most significant bit of n1 is set) /\ (the
 
1381
                 quotient digit q0 = 0 or 1).
 
1382
 
 
1383
                 This special case is necessary, not an optimization.  */
 
1384
 
 
1385
              /* The condition on the next line takes advantage of that
 
1386
                 n1 >= d1 (true due to program flow).  */
 
1387
              if (n1 > d1 || n0 >= d0)
 
1388
                {
 
1389
                  q0 = 1;
 
1390
                  sub_ddmmss (n1, n0, n1, n0, d1, d0);
 
1391
                }
 
1392
              else
 
1393
                q0 = 0;
 
1394
 
 
1395
              q1 = 0;
 
1396
 
 
1397
              if (rp != 0)
 
1398
                {
 
1399
                  rr.s.low = n0;
 
1400
                  rr.s.high = n1;
 
1401
                  *rp = rr.ll;
 
1402
                }
 
1403
            }
 
1404
          else
 
1405
            {
 
1406
              USItype m1, m0;
 
1407
              /* Normalize.  */
 
1408
 
 
1409
              b = SI_TYPE_SIZE - bm;
 
1410
 
 
1411
              d1 = (d1 << bm) | (d0 >> b);
 
1412
              d0 = d0 << bm;
 
1413
              n2 = n1 >> b;
 
1414
              n1 = (n1 << bm) | (n0 >> b);
 
1415
              n0 = n0 << bm;
 
1416
 
 
1417
              udiv_qrnnd (q0, n1, n2, n1, d1);
 
1418
              umul_ppmm (m1, m0, q0, d0);
 
1419
 
 
1420
              if (m1 > n1 || (m1 == n1 && m0 > n0))
 
1421
                {
 
1422
                  q0--;
 
1423
                  sub_ddmmss (m1, m0, m1, m0, d1, d0);
 
1424
                }
 
1425
 
 
1426
              q1 = 0;
 
1427
 
 
1428
              /* Remainder in (n1n0 - m1m0) >> bm.  */
 
1429
              if (rp != 0)
 
1430
                {
 
1431
                  sub_ddmmss (n1, n0, n1, n0, m1, m0);
 
1432
                  rr.s.low = (n1 << b) | (n0 >> bm);
 
1433
                  rr.s.high = n1 >> bm;
 
1434
                  *rp = rr.ll;
 
1435
                }
 
1436
            }
 
1437
        }
 
1438
    }
 
1439
 
 
1440
  ww.s.low = q0;
 
1441
  ww.s.high = q1;
 
1442
  return ww.ll;
 
1443
}
 
1444
 
 
1445
DItype
 
1446
__divdi3 (DItype u, DItype v)
 
1447
{
 
1448
  word_type c = 0;
 
1449
  DIunion uu, vv;
 
1450
  DItype w;
 
1451
 
 
1452
  uu.ll = u;
 
1453
  vv.ll = v;
 
1454
 
 
1455
  if (uu.s.high < 0)
 
1456
    c = ~c, uu.ll = __negdi2 (uu.ll);
 
1457
  if (vv.s.high < 0)
 
1458
    c = ~c, vv.ll = __negdi2 (vv.ll);
 
1459
 
 
1460
  w = __udivmoddi4 (uu.ll, vv.ll, (UDItype *) 0);
 
1461
  if (c)
 
1462
    w = __negdi2 (w);
 
1463
 
 
1464
  return w;
 
1465
}
 
1466
 
 
1467
 
 
1468
DItype
 
1469
__moddi3 (DItype u, DItype v)
 
1470
{
 
1471
  word_type c = 0;
 
1472
  DIunion uu, vv;
 
1473
  DItype w;
 
1474
 
 
1475
  uu.ll = u;
 
1476
  vv.ll = v;
 
1477
 
 
1478
  if (uu.s.high < 0)
 
1479
    c = ~c, uu.ll = __negdi2 (uu.ll);
 
1480
  if (vv.s.high < 0)
 
1481
    vv.ll = __negdi2 (vv.ll);
 
1482
 
 
1483
  (void) __udivmoddi4 (uu.ll, vv.ll, (UDItype *) & w);
 
1484
  if (c)
 
1485
    w = __negdi2 (w);
 
1486
 
 
1487
  return w;
 
1488
}
 
1489
 
 
1490
 
 
1491
UDItype
 
1492
__umoddi3 (UDItype u, UDItype v)
 
1493
{
 
1494
  UDItype w;
 
1495
 
 
1496
  (void) __udivmoddi4 (u, v, (UDItype *) & w);
 
1497
 
 
1498
  return w;
 
1499
}
 
1500
 
 
1501
 
 
1502
UDItype
 
1503
__udivdi3 (UDItype n, UDItype d)
 
1504
{
 
1505
  return __udivmoddi4 (n, d, (UDItype *) 0);
 
1506
}
 
1507
#endif
 
1508
 
 
1509
#ifdef __arm__
 
1510
void
 
1511
raise(void)
 
1512
{
 
1513
        oss_cmn_err (CE_PANIC, "raise() got called\n");
 
1514
}
 
1515
 
 
1516
#endif
 
1517
 
 
1518
dev_info_t *
 
1519
oss_create_pcidip (struct pci_dev * pcidev)
 
1520
{
 
1521
  dev_info_t *dip;
 
1522
 
 
1523
  if ((dip = oss_pmalloc (sizeof (*dip))) == NULL)
 
1524
    return NULL;
 
1525
 
 
1526
  memset (dip, 0, sizeof (*dip));
 
1527
  dip->pcidev = pcidev;
 
1528
 
 
1529
  return dip;
 
1530
}
 
1531
 
 
1532
int
 
1533
osscore_pci_read_config_byte (dev_info_t * dip, unsigned int where,
 
1534
                              unsigned char *val)
 
1535
{
 
1536
  return pci_read_config_byte (dip->pcidev, where, val);
 
1537
}
 
1538
 
 
1539
int
 
1540
osscore_pci_read_config_irq (dev_info_t * dip, unsigned int where,
 
1541
                             unsigned char *val)
 
1542
{
 
1543
  *val = dip->pcidev->irq;
 
1544
  return 0;                     // PCIBIOS_SUCCESSFUL
 
1545
}
 
1546
 
 
1547
int
 
1548
osscore_pci_read_config_word (dev_info_t * dip, unsigned int where,
 
1549
                              unsigned short *val)
 
1550
{
 
1551
  if (dip == NULL)
 
1552
    {
 
1553
      oss_cmn_err (CE_CONT, "osscore_pci_read_config_word: dip==NULL\n");
 
1554
      return -1;
 
1555
    }
 
1556
  return pci_read_config_word (dip->pcidev, where, val);
 
1557
}
 
1558
 
 
1559
int
 
1560
osscore_pci_read_config_dword (dev_info_t * dip, unsigned int where,
 
1561
                               unsigned int *val)
 
1562
{
 
1563
  return pci_read_config_dword (dip->pcidev, where, val);
 
1564
}
 
1565
 
 
1566
int
 
1567
osscore_pci_write_config_byte (dev_info_t * dip, unsigned int where,
 
1568
                               unsigned char val)
 
1569
{
 
1570
  return pci_write_config_byte (dip->pcidev, where, val);
 
1571
}
 
1572
 
 
1573
int
 
1574
osscore_pci_write_config_word (dev_info_t * dip, unsigned int where,
 
1575
                               unsigned short val)
 
1576
{
 
1577
  return pci_write_config_word (dip->pcidev, where, val);
 
1578
}
 
1579
 
 
1580
int
 
1581
osscore_pci_write_config_dword (dev_info_t * dip, unsigned int where,
 
1582
                                unsigned int val)
 
1583
{
 
1584
  return pci_write_config_dword (dip->pcidev, where, val);
 
1585
}
 
1586
 
 
1587
int
 
1588
osscore_pci_enable_msi (dev_info_t * dip)
 
1589
{
 
1590
  pci_enable_msi (dip->pcidev);
 
1591
  return (dip->pcidev->irq);
 
1592
}
 
1593
 
 
1594
/* These definitions must match with oss_config.h */
 
1595
typedef int (*oss_tophalf_handler_t) (struct _oss_device_t * osdev);
 
1596
typedef void (*oss_bottomhalf_handler_t) (struct _oss_device_t * osdev);
 
1597
 
 
1598
typedef struct
 
1599
{
 
1600
  int irq;
 
1601
  oss_device_t *osdev;
 
1602
  oss_tophalf_handler_t top;
 
1603
  oss_bottomhalf_handler_t bottom;
 
1604
} osscore_intr_t;
 
1605
 
 
1606
#define MAX_INTRS       32
 
1607
 
 
1608
static osscore_intr_t intrs[MAX_INTRS] = { {0} };
 
1609
static int nintrs = 0;
 
1610
 
 
1611
static irqreturn_t
 
1612
osscore_intr (int irq, void *arg)
 
1613
{
 
1614
  int serviced;
 
1615
  osscore_intr_t *intr = arg;
 
1616
 
 
1617
  if (intr->osdev == NULL || intr->top == NULL) /* Removed interrupt */
 
1618
    return 0;
 
1619
 
 
1620
  serviced = intr->top (intr->osdev);
 
1621
  oss_inc_intrcount (intr->osdev, serviced);
 
1622
  if (serviced)
 
1623
    {
 
1624
      if (intr->bottom != NULL)
 
1625
        intr->bottom (intr->osdev);
 
1626
      return IRQ_HANDLED;
 
1627
    }
 
1628
  return IRQ_NONE;
 
1629
}
 
1630
 
 
1631
extern int oss_pci_read_config_irq (oss_device_t * osdev, unsigned long where,
 
1632
                                    unsigned char *val);
 
1633
 
 
1634
char *
 
1635
oss_pci_read_devpath (dev_info_t * dip)
 
1636
{
 
1637
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,30)
 
1638
  return dev_name(&dip->pcidev->dev);
 
1639
#else
 
1640
  return dip->pcidev->dev.bus_id;
 
1641
#endif
 
1642
}
 
1643
 
 
1644
int
 
1645
oss_register_interrupts (oss_device_t * osdev, int irqnum,
 
1646
                         oss_tophalf_handler_t top,
 
1647
                         oss_bottomhalf_handler_t bottom)
 
1648
{
 
1649
 
 
1650
  unsigned char pci_irq_line;
 
1651
  osscore_intr_t *intr;
 
1652
  char *name;
 
1653
  int err;
 
1654
 
 
1655
  if (nintrs >= MAX_INTRS)
 
1656
    {
 
1657
      oss_cmn_err (CE_CONT,
 
1658
                   "oss_register_interrupts: Too many interrupt handlers\n");
 
1659
      return -ENOMEM;
 
1660
    }
 
1661
 
 
1662
  intr = &intrs[nintrs];
 
1663
 
 
1664
  if (oss_pci_read_config_irq (osdev, PCI_INTERRUPT_LINE, &pci_irq_line) > 0)
 
1665
    return -EIO;
 
1666
 
 
1667
  intr->irq = pci_irq_line;
 
1668
  intr->osdev = osdev;
 
1669
  intr->top = top;
 
1670
  intr->bottom = bottom;
 
1671
 
 
1672
  name = osdev_get_nick (osdev);
 
1673
#ifndef IRQF_SHARED
 
1674
#define IRQF_SHARED SA_SHIRQ
 
1675
#endif
 
1676
 
 
1677
  if ((err =
 
1678
       request_irq (pci_irq_line, osscore_intr, IRQF_SHARED, name, intr)) < 0)
 
1679
    {
 
1680
      oss_cmn_err (CE_CONT, "request_irq(%d) failed, err=%d\n", pci_irq_line,
 
1681
                   err);
 
1682
      return err;
 
1683
    }
 
1684
 
 
1685
  nintrs++;
 
1686
 
 
1687
  return 0;
 
1688
}
 
1689
 
 
1690
void
 
1691
oss_unregister_interrupts (oss_device_t * osdev)
 
1692
{
 
1693
  int i;
 
1694
 
 
1695
  for (i = 0; i < nintrs; i++)
 
1696
    if (intrs[i].osdev == osdev)
 
1697
      {
 
1698
        free_irq (intrs[i].irq, &intrs[i]);
 
1699
        intrs[i].osdev = NULL;
 
1700
        intrs[i].top = NULL;
 
1701
        intrs[i].bottom = NULL;
 
1702
      }
 
1703
}
 
1704
 
 
1705
int
 
1706
oss_copy_to_user (void *to, const void *from, unsigned long n)
 
1707
{
 
1708
  return copy_to_user (to, from, n);
 
1709
}
 
1710
 
 
1711
int
 
1712
oss_copy_from_user (void *to, const void *from, unsigned long n)
 
1713
{
 
1714
  return copy_from_user (to, from, n);
 
1715
}
 
1716
 
 
1717
static int refcount = 0;
 
1718
 
 
1719
typedef struct
 
1720
{
 
1721
  struct module *module;
 
1722
  int active;
 
1723
} oss_module_t;
 
1724
 
 
1725
#define OSS_MAX_MODULES 50
 
1726
 
 
1727
static oss_module_t oss_modules[OSS_MAX_MODULES];
 
1728
static int num_oss_modules = 0;
 
1729
 
 
1730
void
 
1731
oss_inc_refcounts (void)
 
1732
{
 
1733
  int i;
 
1734
  refcount++;
 
1735
  for (i = 0; i < num_oss_modules; i++)
 
1736
    if (oss_modules[i].active)
 
1737
      {
 
1738
        if (!try_module_get (oss_modules[i].module))
 
1739
          oss_cmn_err (CE_WARN, "try_module_get() failed\n");
 
1740
      }
 
1741
}
 
1742
 
 
1743
void
 
1744
oss_dec_refcounts (void)
 
1745
{
 
1746
  int i;
 
1747
  refcount--;
 
1748
  for (i = 0; i < num_oss_modules; i++)
 
1749
    if (oss_modules[i].active)
 
1750
      {
 
1751
        module_put (oss_modules[i].module);
 
1752
      }
 
1753
}
 
1754
 
 
1755
void
 
1756
oss_register_module (struct module *mod)
 
1757
{
 
1758
  int i, n = -1;
 
1759
 
 
1760
  for (i = 0; i < num_oss_modules; i++)
 
1761
    if (!oss_modules[i].active)
 
1762
      {
 
1763
        n = i;
 
1764
        break;
 
1765
      }
 
1766
 
 
1767
  if (n == -1)
 
1768
    {
 
1769
      if (num_oss_modules >= OSS_MAX_MODULES)
 
1770
        {
 
1771
          printk (KERN_ALERT "Too many OSS modules\n");
 
1772
          return;
 
1773
        }
 
1774
 
 
1775
      n = num_oss_modules++;
 
1776
    }
 
1777
 
 
1778
  oss_modules[n].module = mod;
 
1779
  oss_modules[n].active = 1;
 
1780
}
 
1781
 
 
1782
void
 
1783
oss_unregister_module (struct module *mod)
 
1784
{
 
1785
  int i;
 
1786
 
 
1787
  for (i = 0; i < num_oss_modules; i++)
 
1788
    if (oss_modules[i].active && oss_modules[i].module == mod)
 
1789
      {
 
1790
        oss_modules[i].active = 0;
 
1791
        oss_modules[i].module = NULL;
 
1792
        return;
 
1793
      }
 
1794
}
 
1795
 
 
1796
module_init (osscore_init);
 
1797
module_exit (osscore_exit);
 
1798
 
 
1799
#ifdef CONFIG_OSS_VMIX_FLOAT
 
1800
 
 
1801
#define FP_SAVE(envbuf)         asm ("fnsave %0":"=m" (*envbuf));
 
1802
#define FP_RESTORE(envbuf)              asm ("frstor %0":"=m" (*envbuf));
 
1803
 
 
1804
/* SSE/SSE2 compatible macros */
 
1805
#define FX_SAVE(envbuf)         asm ("fxsave %0":"=m" (*envbuf));
 
1806
#define FX_RESTORE(envbuf)              asm ("fxrstor %0":"=m" (*envbuf));
 
1807
 
 
1808
static int old_arch = 0;        /* No SSE/SSE2 instructions */
 
1809
 
 
1810
#if 0
 
1811
static inline unsigned long
 
1812
read_cr0 (void)
 
1813
{
 
1814
  unsigned long cr0;
 
1815
  asm volatile ("movq %%cr0,%0":"=r" (cr0));
 
1816
  return cr0;
 
1817
}
 
1818
 
 
1819
static inline void
 
1820
write_cr0 (unsigned long val)
 
1821
{
 
1822
  asm volatile ("movq %0,%%cr0"::"r" (val));
 
1823
}
 
1824
 
 
1825
static inline unsigned long
 
1826
read_cr4 (void)
 
1827
{
 
1828
  unsigned long cr4;
 
1829
  asm volatile ("movq %%cr4,%0":"=r" (cr4));
 
1830
  return cr4;
 
1831
}
 
1832
 
 
1833
static inline void
 
1834
write_cr4 (unsigned long val)
 
1835
{
 
1836
  asm volatile ("movq %0,%%cr4"::"r" (val));
 
1837
}
 
1838
#endif
 
1839
 
 
1840
static inline unsigned long long
 
1841
read_mxcsr (void)
 
1842
{
 
1843
  unsigned long long mxcsr;
 
1844
  asm volatile ("stmxcsr %0":"=m" (mxcsr));
 
1845
  return mxcsr;
 
1846
}
 
1847
 
 
1848
static inline void
 
1849
write_mxcsr (unsigned long long val)
 
1850
{
 
1851
  asm volatile ("ldmxcsr %0"::"m" (val));
 
1852
}
 
1853
 
 
1854
int
 
1855
oss_fp_check (void)
 
1856
{
 
1857
  int eax, ebx, ecx, edx;
 
1858
#define FLAGS_ID (1<<21)
 
1859
 
 
1860
  oss_native_word flags_reg;
 
1861
 
 
1862
  local_save_flags (flags_reg);
 
1863
  flags_reg &= ~FLAGS_ID;
 
1864
  local_irq_restore (flags_reg);
 
1865
 
 
1866
  local_save_flags (flags_reg);
 
1867
  if (flags_reg & FLAGS_ID)
 
1868
    return 0;
 
1869
 
 
1870
  flags_reg |= FLAGS_ID;
 
1871
  local_irq_restore (flags_reg);
 
1872
 
 
1873
  local_save_flags (flags_reg);
 
1874
  if (!(flags_reg & FLAGS_ID))
 
1875
    return 0;
 
1876
 
 
1877
#define CPUID_FXSR      (1<<24)
 
1878
#define CPUID_SSE       (1<<25)
 
1879
#define CPUID_SSE2      (1<<26)
 
1880
 
 
1881
  cpuid (1, &eax, &ebx, &ecx, &edx);
 
1882
 
 
1883
  if (!(edx & CPUID_FXSR))
 
1884
    return -1;
 
1885
 
 
1886
  /*
 
1887
   * Older machines require different FP handling than the latest ones. Use the SSE
 
1888
   * instruction set as an indicator.
 
1889
   */
 
1890
  if (!(edx & CPUID_SSE))
 
1891
    old_arch = 1;
 
1892
 
 
1893
  return 1;
 
1894
}
 
1895
 
 
1896
void
 
1897
oss_fp_save (short *envbuf, unsigned int flags[])
 
1898
{
 
1899
  flags[0] = read_cr0 ();
 
1900
  write_cr0 (flags[0] & ~0x0e); /* Clear CR0.TS/MP/EM */
 
1901
 
 
1902
  if (old_arch)
 
1903
    {
 
1904
      FP_SAVE (envbuf);
 
1905
    }
 
1906
  else
 
1907
    {
 
1908
      flags[1] = read_cr4 ();
 
1909
      write_cr4 (flags[1] | 0x600);     /* Set OSFXSR & OSXMMEXCEPT */
 
1910
      FX_SAVE (envbuf);
 
1911
      asm ("fninit");
 
1912
      asm ("fwait");
 
1913
      write_mxcsr (0x1f80);
 
1914
    }
 
1915
  flags[2] = read_cr0 ();
 
1916
}
 
1917
 
 
1918
void
 
1919
oss_fp_restore (short *envbuf, unsigned int flags[])
 
1920
{
 
1921
  asm ("fwait");
 
1922
  if (old_arch)
 
1923
    {
 
1924
      FP_RESTORE (envbuf);
 
1925
    }
 
1926
  else
 
1927
    {
 
1928
      FX_RESTORE (envbuf);
 
1929
      write_cr4 (flags[1]);     /* Restore cr4 */
 
1930
    }
 
1931
  write_cr0 (flags[0]);         /* Restore cr0 */
 
1932
}
 
1933
#endif
 
1934
 
 
1935
#if 0
 
1936
void
 
1937
__stack_chk_fail (void)
 
1938
{
 
1939
  panic ("__stack_chk_fail\n");
 
1940
}
 
1941
#endif
 
1942
 
 
1943
/*
 
1944
 * Exported symbols
 
1945
 */
 
1946
 
 
1947
#define EXPORT_FUNC(name) extern void name(void);EXPORT_SYMBOL(name);
 
1948
#define EXPORT_DATA(name) extern int name;EXPORT_SYMBOL(name);
 
1949
 
 
1950
/* EXPORT_SYMBOL (__stack_chk_fail); */
 
1951
 
 
1952
#ifdef CONFIG_OSS_VMIX_FLOAT
 
1953
EXPORT_SYMBOL (oss_fp_check);
 
1954
EXPORT_SYMBOL (oss_fp_save);
 
1955
EXPORT_SYMBOL (oss_fp_restore);
 
1956
#endif
 
1957
 
 
1958
EXPORT_SYMBOL (oss_register_chrdev);
 
1959
EXPORT_SYMBOL (oss_unregister_chrdev);
 
1960
EXPORT_SYMBOL (oss_reserve_pages);
 
1961
EXPORT_SYMBOL (oss_unreserve_pages);
 
1962
EXPORT_FUNC (ac97_install);
 
1963
EXPORT_FUNC (ac97_install_full);
 
1964
EXPORT_FUNC (ac97_playrate);
 
1965
EXPORT_FUNC (ac97_recrate);
 
1966
EXPORT_FUNC (ac97_varrate);
 
1967
EXPORT_FUNC (ac97_override_control);
 
1968
EXPORT_FUNC (ac97_init_ext);
 
1969
EXPORT_FUNC (ac97_mixer_set);
 
1970
EXPORT_FUNC (ac97_spdif_setup);
 
1971
EXPORT_FUNC (ac97_spdifout_ctl);
 
1972
EXPORT_FUNC (ac97_remove_control);
 
1973
EXPORT_SYMBOL (ac97_amplifier);
 
1974
EXPORT_FUNC (ac97_disable_spdif);
 
1975
EXPORT_FUNC (ac97_enable_spdif);
 
1976
EXPORT_FUNC (ac97_mixext_ctl);
 
1977
EXPORT_FUNC (ac97_spdifin_ctl);
 
1978
EXPORT_FUNC (oss_pci_byteswap);
 
1979
EXPORT_SYMBOL (mixer_ext_truncate);
 
1980
EXPORT_SYMBOL (mixer_ext_rebuild_all);
 
1981
EXPORT_FUNC (remux_install);
 
1982
EXPORT_SYMBOL (oss_strlen);
 
1983
EXPORT_SYMBOL (oss_strcmp);
 
1984
EXPORT_FUNC (oss_install_mididev);
 
1985
EXPORT_DATA (detect_trace);
 
1986
EXPORT_SYMBOL (dmap_get_qhead);
 
1987
EXPORT_SYMBOL (dmap_get_qtail);
 
1988
EXPORT_FUNC (oss_alloc_dmabuf);
 
1989
EXPORT_SYMBOL (oss_contig_free);
 
1990
EXPORT_SYMBOL (oss_contig_malloc);
 
1991
EXPORT_FUNC (oss_disable_device);
 
1992
EXPORT_FUNC (oss_free_dmabuf);
 
1993
EXPORT_SYMBOL (oss_map_pci_mem);
 
1994
EXPORT_SYMBOL (oss_install_audiodev);
 
1995
EXPORT_SYMBOL (oss_install_audiodev_with_devname);
 
1996
EXPORT_FUNC (oss_audio_set_error);
 
1997
EXPORT_SYMBOL (load_mixer_volumes);
 
1998
EXPORT_SYMBOL (oss_unmap_pci_mem);
 
1999
EXPORT_SYMBOL (oss_memset);
 
2000
EXPORT_SYMBOL (oss_mutex_cleanup);
 
2001
EXPORT_SYMBOL (oss_mutex_init);
 
2002
EXPORT_SYMBOL (oss_register_device);
 
2003
EXPORT_SYMBOL (oss_register_interrupts);
 
2004
EXPORT_SYMBOL (oss_inc_intrcount);
 
2005
EXPORT_SYMBOL (oss_spin_lock);
 
2006
EXPORT_SYMBOL (oss_spin_lock_irqsave);
 
2007
EXPORT_SYMBOL (oss_spin_unlock);
 
2008
EXPORT_SYMBOL (oss_spin_unlock_irqrestore);
 
2009
EXPORT_SYMBOL (oss_udelay);
 
2010
EXPORT_FUNC (oss_unregister_device);
 
2011
EXPORT_SYMBOL (oss_unregister_interrupts);
 
2012
EXPORT_SYMBOL (oss_virt_to_bus);
 
2013
EXPORT_FUNC (oss_pci_read_config_byte);
 
2014
EXPORT_FUNC (oss_pci_read_config_word);
 
2015
EXPORT_FUNC (oss_pci_read_config_dword);
 
2016
EXPORT_FUNC (oss_pci_write_config_byte);
 
2017
EXPORT_FUNC (oss_pci_write_config_word);
 
2018
EXPORT_FUNC (oss_pci_write_config_dword);
 
2019
EXPORT_FUNC (oss_pci_enable_msi);
 
2020
EXPORT_SYMBOL (oss_pci_read_config_irq);
 
2021
EXPORT_SYMBOL (oss_pci_read_devpath);
 
2022
EXPORT_SYMBOL (oss_get_jiffies);
 
2023
EXPORT_SYMBOL (mixer_find_ext);
 
2024
EXPORT_SYMBOL (oss_install_mixer);
 
2025
EXPORT_SYMBOL (oss_strcpy);
 
2026
EXPORT_SYMBOL (oss_kmem_free);
 
2027
#ifndef __arm__
 
2028
EXPORT_FUNC (uart401_init);
 
2029
EXPORT_FUNC (uart401_disable);
 
2030
EXPORT_FUNC (uart401_irq);
 
2031
#endif
 
2032
EXPORT_SYMBOL (mixer_ext_set_init_fn);
 
2033
EXPORT_SYMBOL (mixer_ext_set_vmix_init_fn);
 
2034
#ifdef CONFIG_OSS_VMIX
 
2035
EXPORT_FUNC (vmix_attach_audiodev);
 
2036
EXPORT_FUNC (vmix_detach_audiodev);
 
2037
EXPORT_FUNC (vmix_change_devnames);
 
2038
#endif
 
2039
EXPORT_SYMBOL (mixer_ext_set_strings);
 
2040
EXPORT_SYMBOL (mixer_ext_create_group);
 
2041
EXPORT_SYMBOL (mixer_ext_create_group_flags);
 
2042
EXPORT_SYMBOL (mixer_ext_create_control);
 
2043
EXPORT_SYMBOL (oss_strncpy);
 
2044
EXPORT_SYMBOL (oss_memcpy);
 
2045
EXPORT_SYMBOL (oss_kmem_alloc);
 
2046
EXPORT_DATA (oss_hz);
 
2047
EXPORT_FUNC (oss_spdif_open);
 
2048
EXPORT_FUNC (oss_spdif_ioctl);
 
2049
EXPORT_FUNC (oss_spdif_install);
 
2050
EXPORT_FUNC (oss_spdif_uninstall);
 
2051
EXPORT_FUNC (oss_spdif_close);
 
2052
EXPORT_FUNC (oss_spdif_mix_init);
 
2053
EXPORT_FUNC (oss_spdif_setrate);
 
2054
EXPORT_FUNC (create_new_card);
 
2055
EXPORT_FUNC (oss_audio_ioctl);
 
2056
EXPORT_FUNC (oss_audio_open_engine);
 
2057
EXPORT_FUNC (oss_audio_release);
 
2058
EXPORT_FUNC (oss_audio_set_rate);
 
2059
EXPORT_SYMBOL (oss_uiomove);
 
2060
EXPORT_SYMBOL (oss_get_pid);
 
2061
EXPORT_SYMBOL (oss_get_uid);
 
2062
EXPORT_SYMBOL (oss_get_procname);
 
2063
EXPORT_SYMBOL (mix_cvt);
 
2064
EXPORT_FUNC (oss_audio_set_format);
 
2065
EXPORT_FUNC (oss_audio_set_channels);
 
2066
EXPORT_FUNC (midiparser_create);
 
2067
EXPORT_FUNC (midiparser_input);
 
2068
EXPORT_FUNC (midiparser_unalloc);
 
2069
EXPORT_FUNC (mixer_ext_create_device);
 
2070
EXPORT_SYMBOL (mixer_ext_recrw);
 
2071
EXPORT_SYMBOL (mixer_ext_rw);
 
2072
EXPORT_SYMBOL (mixer_ext_set_enum);
 
2073
EXPORT_SYMBOL (mixer_ext_set_description);
 
2074
EXPORT_SYMBOL (osdev_create);
 
2075
EXPORT_FUNC (osdev_clone);
 
2076
EXPORT_SYMBOL (osdev_delete);
 
2077
EXPORT_FUNC (oss_audio_chpoll);
 
2078
EXPORT_FUNC (oss_audio_delayed_attach);
 
2079
EXPORT_FUNC (oss_audio_read);
 
2080
EXPORT_FUNC (oss_audio_write);
 
2081
EXPORT_SYMBOL (oss_create_wait_queue);
 
2082
EXPORT_SYMBOL (oss_remove_wait_queue);
 
2083
EXPORT_SYMBOL (oss_reset_wait_queue);
 
2084
EXPORT_SYMBOL (oss_sleep);
 
2085
EXPORT_SYMBOL (oss_strncmp);
 
2086
EXPORT_SYMBOL (oss_timeout);
 
2087
EXPORT_SYMBOL (oss_untimeout);
 
2088
EXPORT_SYMBOL (oss_wakeup);
 
2089
#if 0
 
2090
EXPORT_FUNC (ossddk_ac97_install);
 
2091
EXPORT_FUNC (ossddk_ac97_is_varrate);
 
2092
EXPORT_FUNC (ossddk_ac97_remove);
 
2093
EXPORT_FUNC (ossddk_ac97_set_ext_init);
 
2094
EXPORT_FUNC (ossddk_ac97_set_playrate);
 
2095
EXPORT_FUNC (ossddk_ac97_set_recrate);
 
2096
EXPORT_FUNC (ossddk_adev_get_devc);
 
2097
EXPORT_FUNC (ossddk_adev_get_dmapin);
 
2098
EXPORT_FUNC (ossddk_adev_get_dmapout);
 
2099
EXPORT_FUNC (ossddk_adev_get_flags);
 
2100
EXPORT_FUNC (ossddk_adev_get_label);
 
2101
EXPORT_FUNC (ossddk_adev_get_portc);
 
2102
EXPORT_FUNC (ossddk_adev_get_portc_play);
 
2103
EXPORT_FUNC (ossddk_adev_get_portc_record);
 
2104
EXPORT_FUNC (ossddk_adev_get_songname);
 
2105
EXPORT_FUNC (ossddk_adev_set_buflimits);
 
2106
EXPORT_FUNC (ossddk_adev_set_caps);
 
2107
EXPORT_FUNC (ossddk_adev_set_channels);
 
2108
EXPORT_FUNC (ossddk_adev_set_devc);
 
2109
EXPORT_FUNC (ossddk_adev_set_enable_flag);
 
2110
EXPORT_FUNC (ossddk_adev_set_flags);
 
2111
EXPORT_FUNC (ossddk_adev_set_formats);
 
2112
EXPORT_FUNC (ossddk_adev_set_label);
 
2113
EXPORT_FUNC (ossddk_adev_set_magic);
 
2114
EXPORT_FUNC (ossddk_adev_set_mixer);
 
2115
EXPORT_FUNC (ossddk_adev_set_portc);
 
2116
EXPORT_FUNC (ossddk_adev_set_portc_play);
 
2117
EXPORT_FUNC (ossddk_adev_set_portc_record);
 
2118
EXPORT_FUNC (ossddk_adev_set_portnum);
 
2119
EXPORT_FUNC (ossddk_adev_set_rates);
 
2120
EXPORT_FUNC (ossddk_adev_set_ratesource);
 
2121
EXPORT_FUNC (ossddk_adev_set_songname);
 
2122
EXPORT_FUNC (ossddk_adev_set_unloaded_flag);
 
2123
EXPORT_FUNC (ossddk_audio_inputintr);
 
2124
EXPORT_FUNC (ossddk_audio_outputintr);
 
2125
EXPORT_FUNC (ossddk_disable_device);
 
2126
EXPORT_FUNC (ossddk_dmap_get_buffsize);
 
2127
EXPORT_FUNC (ossddk_dmap_get_buffused);
 
2128
EXPORT_FUNC (ossddk_dmap_get_dmabuf);
 
2129
EXPORT_FUNC (ossddk_dmap_get_fragsize);
 
2130
EXPORT_FUNC (ossddk_dmap_get_numfrags);
 
2131
EXPORT_FUNC (ossddk_dmap_get_phys);
 
2132
EXPORT_FUNC (ossddk_dmap_get_private);
 
2133
EXPORT_FUNC (ossddk_dmap_get_qhead);
 
2134
EXPORT_FUNC (ossddk_dmap_get_qtail);
 
2135
EXPORT_FUNC (ossddk_dmap_set_buffsize);
 
2136
EXPORT_FUNC (ossddk_dmap_set_callback);
 
2137
EXPORT_FUNC (ossddk_dmap_set_dmabuf);
 
2138
EXPORT_FUNC (ossddk_dmap_set_fragsize);
 
2139
EXPORT_FUNC (ossddk_dmap_set_numfrags);
 
2140
EXPORT_FUNC (ossddk_dmap_set_phys);
 
2141
EXPORT_FUNC (ossddk_dmap_set_playerror);
 
2142
EXPORT_FUNC (ossddk_dmap_set_private);
 
2143
EXPORT_FUNC (ossddk_dmap_set_recerror);
 
2144
EXPORT_FUNC (ossddk_install_audiodev);
 
2145
EXPORT_FUNC (ossddk_install_mixer);
 
2146
EXPORT_FUNC (ossddk_mixer_create_control);
 
2147
EXPORT_FUNC (ossddk_mixer_create_group);
 
2148
EXPORT_FUNC (ossddk_mixer_get_devc);
 
2149
EXPORT_FUNC (ossddk_mixer_set_strings);
 
2150
EXPORT_FUNC (ossddk_mixer_touch);
 
2151
EXPORT_FUNC (ossddk_mixer_truncate);
 
2152
EXPORT_FUNC (ossddk_osdev_get_devc);
 
2153
EXPORT_FUNC (ossddk_register_device);
 
2154
EXPORT_FUNC (ossddk_unregister_device);
 
2155
#endif
 
2156
EXPORT_SYMBOL (osdev_set_major);
 
2157
EXPORT_SYMBOL (osdev_set_owner);
 
2158
EXPORT_SYMBOL (osdev_get_owner);
 
2159
EXPORT_SYMBOL (oss_create_pcidip);
 
2160
EXPORT_SYMBOL (touch_mixer);
 
2161
EXPORT_SYMBOL (oss_mixer_ext);
 
2162
EXPORT_SYMBOL (oss_request_major);
 
2163
EXPORT_SYMBOL (audio_engines);
 
2164
EXPORT_DATA (midi_devs);
 
2165
EXPORT_SYMBOL (mixer_devs);
 
2166
EXPORT_SYMBOL (mixer_devs_p);
 
2167
EXPORT_DATA (num_audio_engines);
 
2168
EXPORT_DATA (num_mididevs);
 
2169
EXPORT_SYMBOL (num_mixers);
 
2170
EXPORT_DATA (oss_timing_mutex);
 
2171
EXPORT_DATA (oss_num_cards);
 
2172
EXPORT_FUNC (oss_do_timing);
 
2173
EXPORT_FUNC (oss_do_timing2);
 
2174
EXPORT_FUNC (oss_timing_enter);
 
2175
EXPORT_FUNC (oss_timing_leave);
 
2176
#ifndef __arm__
 
2177
EXPORT_SYMBOL (__udivdi3);
 
2178
EXPORT_SYMBOL (__umoddi3);
 
2179
EXPORT_SYMBOL (__divdi3);
 
2180
#else
 
2181
EXPORT_SYMBOL (raise);
 
2182
#endif
 
2183
EXPORT_SYMBOL (oss_copy_from_user);
 
2184
EXPORT_SYMBOL (oss_copy_to_user);
 
2185
EXPORT_SYMBOL (osdev_set_irqparms);
 
2186
EXPORT_SYMBOL (osdev_get_irqparms);
 
2187
EXPORT_SYMBOL (osdev_get_nick);
 
2188
EXPORT_SYMBOL (osdev_get_instance);
 
2189
EXPORT_SYMBOL (oss_inc_refcounts);
 
2190
EXPORT_SYMBOL (oss_dec_refcounts);
 
2191
EXPORT_SYMBOL (oss_register_module);
 
2192
EXPORT_SYMBOL (oss_unregister_module);
 
2193
EXPORT_SYMBOL (oss_audio_reset);
 
2194
EXPORT_SYMBOL (oss_audio_start_syncgroup);
 
2195
EXPORT_SYMBOL (oss_encode_enum);
 
2196
EXPORT_SYMBOL (dmap_get_qlen);
 
2197
EXPORT_SYMBOL (num_audio_devfiles);
 
2198
EXPORT_SYMBOL (oss_audio_inc_byte_counter);
 
2199
EXPORT_SYMBOL (oss_audio_register_client);
 
2200
EXPORT_SYMBOL (audio_devfiles);
 
2201
EXPORT_FUNC (oss_get_cardinfo);
 
2202
EXPORT_SYMBOL (oss_pmalloc);
 
2203
EXPORT_SYMBOL (oss_add_audio_devlist);
 
2204
EXPORT_FUNC (oss_memblk_malloc);
 
2205
EXPORT_FUNC (oss_memblk_free);
 
2206
EXPORT_FUNC (oss_memblk_unalloc);
 
2207
EXPORT_DATA (oss_global_memblk);
 
2208
EXPORT_FUNC (oss_get_procinfo);
 
2209
EXPORT_DATA (mixer_muted);
 
2210
 
 
2211
#ifdef CONFIG_OSS_MIDI
 
2212
EXPORT_FUNC (oss_midi_ioctl);
 
2213
EXPORT_FUNC (oss_midi_copy_timer);
 
2214
#endif