~ubuntu-branches/ubuntu/vivid/oss4/vivid-proposed

« back to all changes in this revision

Viewing changes to .pc/103_kfreebsd-gnu.patch/kernel/framework/sndstat/oss_sndstat.c

  • Committer: Package Import Robot
  • Author(s): Sebastien NOEL
  • Date: 2012-11-19 11:47:24 UTC
  • mfrom: (1.1.6)
  • Revision ID: package-import@ubuntu.com-20121119114724-svu8mq7x3pk64nez
Tags: 4.2-build2007-1
* New upstream release.
* Acknowledge NMU, thanks Michael Gilbert.
* Add debian/patches/110_ld-as-needed.patch: Rearrange order of linker
  arguments to fix building with "ld --as-needed" (closes: #630737).
* Add missing dependency on dpkg-dev to oss4-dkms and oss4-source
  (closes: #687086).
* Fix typo in the changelog (closes: #628876, #675933)
* Add debian/patches/002_fix-linux-oss_native_word.patch (closes: #693657).
  Thanks to Ben Hutchings.
* Add debian/patches/003_linux-error-logging-fixes.patch (closes: #693657).
  Thanks to Ben Hutchings.
* check for /lib/modules/${kernelver}/build in addition of
  /lib/modules/${kernelver}/source (closes: #587191).
* oss4-dkms.dkms.in: fix 'CLEAN' rules (closes: #653374).

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * Purpose: /dev/sndstat driver
 
3
 *
 
4
 * Description:
 
5
 */
 
6
/*
 
7
 *
 
8
 * This file is part of Open Sound System.
 
9
 *
 
10
 * Copyright (C) 4Front Technologies 1996-2008.
 
11
 *
 
12
 * This this source file is released under GPL v2 license (no other versions).
 
13
 * See the COPYING file included in the main directory of this source
 
14
 * distribution for the license terms and conditions.
 
15
 *
 
16
 */
 
17
 
 
18
#include <oss_config.h>
 
19
#include <midi_core.h>
 
20
 
 
21
static char *sndstat_buf = NULL;
 
22
static int sndstat_len, sndstat_ptr;
 
23
static volatile int sndstat_busy = 0;
 
24
 
 
25
/*
 
26
 * All kind of status messages
 
27
 */
 
28
#define MAX_MESSAGE 50
 
29
static char *messages[MAX_MESSAGE];
 
30
static int nmessages;           /* # of display messages (/dev/sndstat) */
 
31
 
 
32
static int
 
33
put_status (const char *s)
 
34
{
 
35
  int l = strlen (s);
 
36
 
 
37
  if (sndstat_len + l >= 4000)
 
38
    return 0;
 
39
 
 
40
  memcpy (&sndstat_buf[sndstat_len], s, l);
 
41
  sndstat_len += l;
 
42
 
 
43
  return 1;
 
44
}
 
45
 
 
46
static int
 
47
put_status_int (unsigned int val, int radix)
 
48
{
 
49
  char buf[11], *rx = "%d";
 
50
 
 
51
  if (!val)
 
52
    return put_status ("0");
 
53
 
 
54
  if (radix == 16)
 
55
    rx = "%x";
 
56
  sprintf (buf, rx, val);
 
57
 
 
58
  return put_status (buf);
 
59
}
 
60
 
 
61
static void
 
62
init_status (void)
 
63
{
 
64
  /*
 
65
   * Write the status information to the sndstat_buf and update sndstat_len.
 
66
   * There is a limit of 4000 bytes for the data.
 
67
   */
 
68
 
 
69
  int i, p, missing_devs = 0;
 
70
  int notify = 0;
 
71
  extern char *oss_license_string;
 
72
 
 
73
  sndstat_ptr = 0;
 
74
 
 
75
  put_status ("OSS " OSS_VERSION_STRING);
 
76
  put_status (oss_license_string);
 
77
  put_status (" (C) 4Front Technologies 1996-2012\n");
 
78
 
 
79
#ifdef LICENSED_VERSION
 
80
  oss_print_license (put_status, put_status_int);
 
81
#endif
 
82
 
 
83
#ifdef OSS_CONFIG_OPTIONS
 
84
  put_status ("\nSource configration options: ");
 
85
  put_status (OSS_CONFIG_OPTIONS);
 
86
  put_status ("\n");
 
87
#endif
 
88
 
 
89
#ifdef OSS_HG_INFO
 
90
  put_status ("\nHg revision: ");
 
91
  put_status (OSS_HG_INFO);
 
92
  put_status ("\n");
 
93
#endif
 
94
 
 
95
  if (nmessages > 0)
 
96
    {
 
97
      put_status ("\n");
 
98
 
 
99
      for (i = 0; i < nmessages; i++)
 
100
        {
 
101
          if (!put_status (messages[i]))
 
102
            return;
 
103
        }
 
104
 
 
105
      put_status ("\n");
 
106
    }
 
107
 
 
108
#if defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__)
 
109
  {
 
110
#if defined(__FreeBSD__)
 
111
    extern char version[];
 
112
#endif
 
113
 
 
114
    put_status ("Kernel: ");
 
115
    put_status (version);
 
116
    put_status ("\n");
 
117
  }
 
118
#endif
 
119
 
 
120
#if 0
 
121
/*
 
122
 * This code is obsolete and not functional at this moment.
 
123
 */
 
124
  if (!put_status ("\nDevice objects:\n"))
 
125
    return;
 
126
 
 
127
  for (i = 0; i < oss_num_cards; i++)
 
128
    {
 
129
      char tmp[256];
 
130
 
 
131
      oss_get_cardinfo (i, tmp, sizeof (tmp) - 1);
 
132
      if (!put_status (tmp))
 
133
        return;
 
134
      if (!put_status ("\n"))
 
135
        return;
 
136
    }
 
137
 
 
138
#endif
 
139
 
 
140
  if (!put_status ("\nAudio devices:\n"))
 
141
    return;
 
142
 
 
143
  missing_devs = 0;
 
144
 
 
145
  if (audio_devfiles != NULL)
 
146
    for (i = 0; i < MAX_AUDIO_DEVFILES +100 && missing_devs < 40; i++)
 
147
      {
 
148
        int j, d;
 
149
#if 0
 
150
        if (i < num_audio_devfiles)
 
151
        if (audio_devfiles[i]->card_number != cardno)
 
152
          {
 
153
            put_status (" \n");
 
154
            cardno = audio_devfiles[i]->card_number;
 
155
          }
 
156
#endif
 
157
/*
 
158
 * New device numbering scheme may have /dev/dsp# devices in different
 
159
 * order than the order of devices in audio_devices[]. Find the right device
 
160
 * based on the adev->real_dev number. Note that device numbering may have
 
161
 * holes if devices have been removed after running ossdevlinks -f last time.
 
162
 */
 
163
        d = -1;
 
164
        for (j = 0; j < num_audio_devfiles; j++)
 
165
          {
 
166
            if (audio_devfiles[j]->real_dev == i)
 
167
              {
 
168
                if (j != i)
 
169
                  notify = 1;
 
170
                d = audio_devfiles[j]->audio_devfile;
 
171
                break;
 
172
              }
 
173
          }
 
174
 
 
175
        if (d == -1)
 
176
          {
 
177
            missing_devs++;
 
178
            continue;
 
179
          }
 
180
 
 
181
        if (missing_devs > 0)   /* There is a hole in numbering */
 
182
          for (j = i - missing_devs; j < i; j++)
 
183
            {
 
184
              notify = 1;
 
185
              if (!put_status_int (j, 10))
 
186
                return;
 
187
              if (!put_status (": (Undefined or removed device)\n"))
 
188
                return;
 
189
            }
 
190
        missing_devs = 0;
 
191
 
 
192
        if (!put_status_int (i, 10))
 
193
          return;
 
194
        if (!put_status (": "))
 
195
          return;
 
196
        if (!audio_devfiles[d]->enabled || audio_devfiles[d]->unloaded)
 
197
          put_status ("(");
 
198
 
 
199
        if (!put_status (audio_devfiles[d]->name))
 
200
          return;
 
201
        if (!audio_devfiles[d]->enabled || audio_devfiles[d]->unloaded)
 
202
          put_status (")");
 
203
 
 
204
        if ((audio_devfiles[d]->flags & ADEV_DUPLEX)
 
205
            || (audio_devfiles[d]->flags & ADEV_NOINPUT)
 
206
            || (audio_devfiles[d]->flags & ADEV_NOOUTPUT))
 
207
          {
 
208
            int nn = 0;
 
209
 
 
210
            if (!put_status (" ("))
 
211
              return;
 
212
 
 
213
            if (audio_devfiles[d]->flags & ADEV_NOINPUT)
 
214
              {
 
215
                if (nn++)
 
216
                  put_status (",");
 
217
                if (!put_status ("OUTPUT"))
 
218
                  return;
 
219
              }
 
220
 
 
221
            if (audio_devfiles[d]->flags & ADEV_NOOUTPUT)
 
222
              {
 
223
                if (nn++)
 
224
                  put_status (",");
 
225
                if (!put_status ("INPUT"))
 
226
                  return;
 
227
              }
 
228
 
 
229
            if (audio_devfiles[d]->flags & ADEV_DUPLEX)
 
230
              {
 
231
                if (nn++)
 
232
                  put_status (",");
 
233
                if (!put_status ("DUPLEX"))
 
234
                  return;
 
235
              }
 
236
            if (!put_status (")"))
 
237
              return;
 
238
          }
 
239
 
 
240
        if (!put_status ("\n"))
 
241
          return;
 
242
 
 
243
        {
 
244
          adev_t *adev = audio_devfiles[d];
 
245
          int n = 0, single = 0;
 
246
          if (adev->next_out == NULL)
 
247
            single = 1;
 
248
 
 
249
          while (adev != NULL)
 
250
            {
 
251
              if (adev->open_mode != 0)
 
252
                {
 
253
                  if (i < 10)
 
254
                    {
 
255
                      if (!put_status ("   "))
 
256
                        return;
 
257
                    }
 
258
                  else
 
259
                    {
 
260
                      if (!put_status ("    "))
 
261
                        return;
 
262
                    }
 
263
 
 
264
                  if (single)
 
265
                    {
 
266
                      put_status ("Opened ");
 
267
                      if (adev->open_mode & OPEN_READ)
 
268
                        put_status ("IN");
 
269
                      if (adev->open_mode & OPEN_WRITE)
 
270
                        put_status ("OUT");
 
271
                      put_status (" by ");
 
272
                    }
 
273
                  else
 
274
                    {
 
275
                      put_status ("Engine ");
 
276
                      put_status_int (n + 1, 10);
 
277
                      put_status (" opened ");
 
278
                      if (adev->open_mode & OPEN_READ)
 
279
                        put_status ("IN");
 
280
                      if (adev->open_mode & OPEN_WRITE)
 
281
                        put_status ("OUT");
 
282
                      put_status (" by ");
 
283
                    }
 
284
 
 
285
                  if (adev->pid != -1 || *adev->label != 0)
 
286
                    {
 
287
                      if (*adev->label != 0)
 
288
                        {
 
289
                          if (!put_status (adev->label))
 
290
                            return;
 
291
                          if (!put_status ("/"))
 
292
                            return;
 
293
                        }
 
294
 
 
295
                      put_status_int (adev->pid, 10);
 
296
                    }
 
297
                  else
 
298
                    {
 
299
                      if (!put_status ("unknown application"))
 
300
                        return;
 
301
                    }
 
302
 
 
303
                  if (!put_status (" @ "))
 
304
                    return;
 
305
                  if (!put_status_int (adev->user_parms.rate, 10))
 
306
                    return;
 
307
                  if (!put_status ("/"))
 
308
                    return;
 
309
                  if (!put_status_int (adev->hw_parms.rate, 10))
 
310
                    return;
 
311
                  if (!put_status (" Hz"))
 
312
                    return;
 
313
 
 
314
#if 1
 
315
                  if (!put_status (" Fragment: "))
 
316
                    return;
 
317
 
 
318
                  if (!put_status (audio_show_latency (adev->engine_num)))
 
319
                    return;
 
320
#endif
 
321
 
 
322
                  if (!put_status ("\n"))
 
323
                    return;
 
324
 
 
325
                  if (*adev->song_name != 0)
 
326
                    {
 
327
                      if (i < 10)
 
328
                        {
 
329
                          if (!put_status ("   "))
 
330
                            return;
 
331
                        }
 
332
                      else
 
333
                        {
 
334
                          if (!put_status ("    "))
 
335
                            return;
 
336
                        }
 
337
 
 
338
                      if (!put_status ("Song name: "))
 
339
                        return;
 
340
                      if (!put_status (adev->song_name))
 
341
                        return;
 
342
                      if (!put_status ("\n"))
 
343
                        return;
 
344
                    }
 
345
                }
 
346
 
 
347
              adev = adev->next_out;
 
348
              n++;
 
349
            }
 
350
        }
 
351
      }
 
352
 
 
353
#ifdef CONFIG_OSS_MIDI
 
354
  if (!put_status ("\nMIDI devices:\n"))
 
355
    return;
 
356
 
 
357
  missing_devs = 0;
 
358
  for (i = 0; i < MAX_MIDI_DEV * 2 && missing_devs < 16; i++)
 
359
    {
 
360
      int j, d = -1;
 
361
 
 
362
      for (j = 0; j < num_mididevs; j++)
 
363
        if (midi_devs[j]->real_dev == i)
 
364
          {
 
365
            d = j;
 
366
            if (j != i)
 
367
              notify = 1;
 
368
          }
 
369
 
 
370
      if (d == -1)
 
371
        {
 
372
          missing_devs++;
 
373
          continue;
 
374
        }
 
375
 
 
376
      for (j = i - missing_devs; j < i; j++)
 
377
        {
 
378
          notify = 1;
 
379
          if (!put_status_int (j, 10))
 
380
            return;
 
381
          if (!put_status (": (Unknown or removed device)\n"))
 
382
            return;
 
383
        }
 
384
      missing_devs = 0;
 
385
 
 
386
      if (!put_status_int (i, 10))
 
387
        return;
 
388
      if (!put_status (": "))
 
389
        return;
 
390
      if (!midi_devs[d]->enabled || midi_devs[d]->unloaded)
 
391
        put_status ("(");
 
392
      if (!put_status (midi_devs[d]->name))
 
393
        return;
 
394
      if (!midi_devs[d]->enabled || midi_devs[d]->unloaded)
 
395
        put_status (")");
 
396
      if (!put_status ("\n"))
 
397
        return;
 
398
 
 
399
      if (midi_devs[d]->pid != -1)
 
400
        {
 
401
          if (i < 10)
 
402
            {
 
403
              if (!put_status ("   "))
 
404
                return;
 
405
            }
 
406
          else
 
407
            {
 
408
              if (!put_status ("    "))
 
409
                return;
 
410
            }
 
411
          if (!put_status ("Open by "))
 
412
            return;
 
413
          if (!put_status_int (midi_devs[d]->pid, 10))
 
414
            return;
 
415
          if (*midi_devs[d]->cmd != 0)
 
416
            {
 
417
              if (!put_status ("/"))
 
418
                return;
 
419
              if (!put_status (midi_devs[d]->cmd))
 
420
                return;
 
421
            }
 
422
          if (!put_status ("\n"))
 
423
            return;
 
424
          if (midi_devs[d]->d->ioctl)
 
425
            {
 
426
              oss_longname_t song_name;
 
427
 
 
428
              if (midi_devs[d]->d->ioctl (d, SNDCTL_GETSONG,
 
429
                                          (ioctl_arg) song_name) >= 0
 
430
                  && *song_name != 0)
 
431
                {
 
432
                  if (!put_status ("   Song name: "))
 
433
                    return;
 
434
                  if (!put_status (song_name))
 
435
                    return;
 
436
                  if (!put_status ("\n"))
 
437
                    return;
 
438
                }
 
439
            }
 
440
        }
 
441
    }
 
442
#endif
 
443
 
 
444
#if 0
 
445
  /* TODO: No timer available at this moment */
 
446
  if (!put_status ("\nTimers:\n"))
 
447
    return;
 
448
 
 
449
  for (i = 0; i < oss_num_timers; i++)
 
450
    {
 
451
      if (!put_status_int (i, 10))
 
452
        return;
 
453
      if (!put_status (": "))
 
454
        return;
 
455
      if (!put_status (oss_timer_devs[i]->info.name))
 
456
        return;
 
457
      if (!put_status ("\n"))
 
458
        return;
 
459
    }
 
460
#endif
 
461
 
 
462
  if (!put_status ("\nMixers:\n"))
 
463
    return;
 
464
 
 
465
  missing_devs = 0;
 
466
 
 
467
  for (i = 0; i < MAX_MIXER_DEV * 2 && missing_devs < 10; i++)
 
468
    {
 
469
      int j, d = -1;
 
470
 
 
471
      for (j = 0; j < num_mixers; j++)
 
472
        if (mixer_devs[j]->real_dev == i)
 
473
          {
 
474
            if (j != i)
 
475
              notify = 1;
 
476
            d = j;
 
477
          }
 
478
 
 
479
      if (d == -1)
 
480
        {
 
481
          missing_devs++;
 
482
          continue;
 
483
        }
 
484
 
 
485
      for (j = i - missing_devs; j < i; j++)
 
486
        {
 
487
          notify = 1;
 
488
          if (!put_status_int (j, 10))
 
489
            return;
 
490
          if (!put_status (": (Uninstalled or removed device\n"))
 
491
            return;
 
492
        }
 
493
      missing_devs = 0;
 
494
 
 
495
      if (!put_status_int (i, 10))
 
496
        return;
 
497
      if (!put_status (": "))
 
498
        return;
 
499
 
 
500
      if (!mixer_devs[d]->enabled || mixer_devs[d]->unloaded)
 
501
        if (!put_status ("("))
 
502
          return;
 
503
 
 
504
      if (!put_status (mixer_devs[d]->name))
 
505
        return;
 
506
 
 
507
      if (!mixer_devs[d]->enabled || mixer_devs[d]->unloaded)
 
508
        if (!put_status (")"))
 
509
          return;
 
510
 
 
511
      if (!put_status ("\n"))
 
512
        return;
 
513
    }
 
514
 
 
515
#if 1
 
516
  p = 0;
 
517
  for (i = 0; i < OSS_HISTORY_SIZE; i++)
 
518
    if (*oss_history[i] != 0)
 
519
      p++;
 
520
 
 
521
  if (p > 0)
 
522
#ifdef GET_PROCESS_UID
 
523
    if (GET_PROCESS_UID () == 0)
 
524
#endif
 
525
      {
 
526
        if (!put_status ("\nHistory:\n"))
 
527
          return;
 
528
 
 
529
        p = oss_history_p;
 
530
 
 
531
        for (i = 0; i < OSS_HISTORY_SIZE; i++)
 
532
          {
 
533
            int ix = (p + i) % OSS_HISTORY_SIZE;
 
534
 
 
535
            if (*oss_history[ix] == 0)
 
536
              continue;
 
537
 
 
538
            if (!put_status (oss_history[ix]))
 
539
              return;
 
540
            if (!put_status ("\n"))
 
541
              return;
 
542
          }
 
543
      }
 
544
#endif
 
545
#if 0
 
546
  if (!put_status
 
547
      ("\n\nNOTICE! This /dev/sndstat file is obsolete - use the ossinfo command instead\n"))
 
548
    return;
 
549
#endif
 
550
  if (notify)
 
551
    {
 
552
      if (!put_status
 
553
          ("\n\nWARNING! Legacy device numbering in /dev/sndstat is different from actual device numbering\n"))
 
554
        return;
 
555
    }
 
556
 
 
557
  put_status ("\n\nNOTICE! Device numbers shown above may be wrong.\n");
 
558
  put_status ("        Use the ossinfo command to find out the correct device names.\n");
 
559
 
 
560
  sndstat_buf[sndstat_len] = 0;
 
561
}
 
562
 
 
563
void
 
564
store_msg (char *msg)
 
565
{
 
566
  char *s;
 
567
 
 
568
  if (strlen (msg) > 100 || nmessages >= MAX_MESSAGE)
 
569
    return;
 
570
 
 
571
  s = PMALLOC (NULL, strlen (msg) + 1);
 
572
  if (s == NULL)
 
573
    {
 
574
      return;
 
575
    }
 
576
  strcpy (s, msg);
 
577
  messages[nmessages++] = s;
 
578
}
 
579
 
 
580
static int
 
581
read_status (uio_t * buf, int count)
 
582
{
 
583
  /*
 
584
   * Return at most 'count' bytes from the sndstat_buf.
 
585
   */
 
586
  int l, c;
 
587
 
 
588
  l = count;
 
589
  c = sndstat_len - sndstat_ptr;
 
590
 
 
591
  if (l > c)
 
592
    l = c;
 
593
  if (l <= 0)
 
594
    return 0;
 
595
 
 
596
  if (uiomove (&sndstat_buf[sndstat_ptr], l, UIO_READ, buf) != 0)
 
597
    return OSS_EFAULT;
 
598
  sndstat_ptr += l;
 
599
 
 
600
  return l;
 
601
}
 
602
 
 
603
/*ARGSUSED*/
 
604
static int
 
605
sndstat_open (int dev, int dev_class, struct fileinfo *file,
 
606
              int recursive, int open_flags, int *redirect)
 
607
{
 
608
  /* TODO: Concurrency control */
 
609
  if (sndstat_busy)
 
610
    return OSS_EBUSY;
 
611
  sndstat_busy = 1;
 
612
 
 
613
  if ((sndstat_buf = KERNEL_MALLOC (4096)) == NULL)
 
614
    {
 
615
      sndstat_busy = 0;
 
616
      return OSS_ENOMEM;
 
617
    }
 
618
 
 
619
  sndstat_len = 0;
 
620
  init_status ();
 
621
  sndstat_ptr = 0;
 
622
 
 
623
  return 0;
 
624
}
 
625
 
 
626
/*ARGSUSED*/
 
627
static void
 
628
sndstat_close (int dev, struct fileinfo *file)
 
629
{
 
630
  KERNEL_FREE (sndstat_buf);
 
631
  sndstat_buf = NULL;
 
632
  sndstat_busy = 0;
 
633
}
 
634
 
 
635
/*ARGSUSED*/
 
636
static int
 
637
sndstat_read (int dev, struct fileinfo *file, uio_t * buf, int count)
 
638
{
 
639
  int l;
 
640
  l = read_status (buf, count);
 
641
  return l;
 
642
}
 
643
 
 
644
/*ARGSUSED*/
 
645
static int
 
646
sndstat_write (int dev, struct fileinfo *file, uio_t * buf, int count)
 
647
{
 
648
/*
 
649
 * This dummy write routine will be used for some internal management purposes
 
650
 * in the future. At this moment it just tells the osscore module that it 
 
651
 * should permit detaching itself.
 
652
 */
 
653
#ifdef sun
 
654
  extern int oss_detach_enabled;
 
655
  oss_detach_enabled = 1;
 
656
  return count;
 
657
#else
 
658
  return OSS_EIO;
 
659
#endif
 
660
}
 
661
 
 
662
/*ARGSUSED*/
 
663
static int
 
664
sndstat_ioctl (int dev, struct fileinfo *bogus,
 
665
               unsigned int cmd, ioctl_arg arg)
 
666
{
 
667
  if (cmd == OSS_GETVERSION)
 
668
    return *arg = OSS_VERSION;
 
669
 
 
670
  return OSS_EINVAL;
 
671
}
 
672
 
 
673
static oss_cdev_drv_t sndstat_cdev_drv = {
 
674
  sndstat_open,
 
675
  sndstat_close,
 
676
  sndstat_read,
 
677
  sndstat_write,
 
678
  sndstat_ioctl
 
679
};
 
680
 
 
681
void
 
682
install_sndstat (oss_device_t * osdev)
 
683
{
 
684
  //static int already_installed=0;
 
685
 
 
686
  // if (!already_installed++) // TODO: Is it necessaary to prevent loading sndstat multiple times?
 
687
  oss_install_chrdev (osdev, "sndstat", OSS_DEV_STATUS, 0, &sndstat_cdev_drv,
 
688
                      0);
 
689
}