2
* Purpose: Operating system abstraction functions for SCO OpenServer/UnixWare
6
* This file is part of Open Sound System.
8
* Copyright (C) 4Front Technologies 1996-2008.
10
* This this source file is released under GPL v2 license (no other versions).
11
* See the COPYING file included in the main directory of this source
12
* distribution for the license terms and conditions.
16
#include "oss_config.h"
17
#include "midi_core.h"
24
* MAX_CARDS must be larger than life. The system will panic if there are
25
* more sound devices (cards os sound chips) than MAX_CARDS.
29
static oss_device_t *cards[MAX_CARDS];
30
int oss_num_cards = 0;
31
static int oss_expired = 0;
33
volatile int oss_open_devices = 0;
35
static bcb_t *oss_bcb;
38
* Driver information structures, for drv_attach().
40
static int oss_config (cfg_func_t func, void *idata, rm_key_t key);
42
static const drvops_t oss_ops = {
53
static const drvinfo_t oss_drvinfo = {
57
NULL, /* Not a STREAMS driver */
58
10 /* Must match $maxchan in Node file */
61
static physreq_t *physreq_isa = NULL; /* 24 bits */
62
static physreq_t *physreq_28bit = NULL;
63
static physreq_t *physreq_30bit = NULL;
64
static physreq_t *physreq_31bit = NULL;
65
static physreq_t *physreq_32bit = NULL;
76
#define MAX_MEMBLOCKS 1024
78
static mem_block_t memblocks[MAX_MEMBLOCKS];
79
static int num_memblocks = 0;
84
oss_kmem_alloc (size_t size, int flags, char *file, int line)
87
oss_kmem_alloc (size_t size, int flags)
91
* This routine allocates a memory block and stores length of it in
92
* the beginning. This length information can be used when later unallocating
99
ptr = kmem_zalloc (size + sizeof (uint64_t), flags);
101
cmn_err (CE_CONT, "kmalloc(%d, %s:%d)=%x\n", size, file, line, ptr);
107
len = (uint64_t *) ptr;
109
ptr += sizeof (uint64_t);
110
*len = size + sizeof (uint64_t);
116
for (i = 0; i < num_memblocks; i++)
117
if (memblocks[i].addr == NULL)
119
memblocks[i].addr = ptr;
120
memblocks[i].size = size;
121
strncpy (memblocks[i].file, file, 39);
122
memblocks[i].line = line;
128
if (num_memblocks < MAX_MEMBLOCKS)
130
memblocks[num_memblocks].addr = ptr;
131
memblocks[num_memblocks].size = size;
132
strncpy (memblocks[num_memblocks].file, file, 39);
133
memblocks[num_memblocks].line = line;
143
oss_kmem_free (void *addr, char *file, int line)
145
oss_kmem_free (void *addr)
156
ptr -= sizeof (uint64_t);
158
len = (uint64_t *) ptr;
160
kmem_free (ptr, *len);
165
for (i = 0; i < num_memblocks; i++)
166
if (addr == memblocks[i].addr)
168
memblocks[i].addr = NULL;
172
cmn_err (CE_WARN, "Bad kfree(%x, %s:%d)\n", addr, file, line);
177
* Table for permanently allocated memory (to be freed by _fini)
179
#define OSS_MAX_MEM 1024
180
void *oss_mem_blocks[OSS_MAX_MEM];
185
oss_pmalloc (size_t size, char *file, int line)
187
oss_pmalloc (size_t size)
192
mem_ptr = (oss_mem_blocks[oss_nblocks] =
193
oss_kmem_alloc (size, KM_SLEEP, file, line));
195
mem_ptr = (oss_mem_blocks[oss_nblocks] = KERNEL_MALLOC (size));
198
if (oss_nblocks <= OSS_MAX_MEM)
201
cmn_err (CE_NOTE, "Out of mem blocks\n");
206
__oss_alloc_dmabuf (int dev, dmap_p dmap, unsigned int alloc_flags,
207
oss_uint64_t maxaddr, int direction)
210
oss_native_word phaddr;
211
int size = 64 * 1024;
212
extern int dma_buffsize;
214
if (dma_buffsize > 16 && dma_buffsize <= 128)
215
size = dma_buffsize * 1024;
217
if (dmap->dmabuf != NULL)
221
* Some applications and virtual drivers need shorter buffer.
223
if (dmap->flags & DMAP_SMALLBUF)
225
size = SMALL_DMABUF_SIZE;
227
else if (dmap->flags & DMAP_MEDIUMBUF)
229
size = MEDIUM_DMABUF_SIZE;
232
if ((alloc_flags & DMABUF_SIZE_16BITS) && size > 32 * 1024)
236
oss_contig_malloc (audio_engines[dev]->osdev, size, maxaddr,
241
dmap->dmabuf_phys = phaddr;
242
dmap->buffsize = size;
248
oss_free_dmabuf (int dev, dmap_p dmap)
250
if (dmap->dmabuf == NULL)
253
oss_contig_free (audio_engines[dev]->osdev, dmap->dmabuf, dmap->buffsize);
255
dmap->dmabuf_phys = 0;
260
oss_contig_malloc (oss_device_t * osdev, int size, oss_uint64_t memlimit,
261
oss_native_word * phaddr)
264
physreq_t *preqp = physreq_32bit;
274
case MEMLIMIT_28BITS:
275
preqp = physreq_28bit;
277
case MEMLIMIT_30BITS:
278
preqp = physreq_30bit;
280
case MEMLIMIT_31BITS:
281
preqp = physreq_31bit;
283
case MEMLIMIT_32BITS:
284
preqp = physreq_32bit;
288
cmn_err (CE_WARN, "osscore: Bad DMA memlimit for %s\n", osdev->nick);
291
if ((p = kmem_alloc_phys (size, preqp, &pa, 0)) == NULL)
293
cmn_err (CE_WARN, "osscore: kmem_alloc_phys() failed\n");
302
oss_contig_free (oss_device_t * osdev, void *p, int sz)
312
oss_create_wait_queue (oss_device_t * osdev, const char *name)
316
if ((q = KERNEL_MALLOC (sizeof (*q))) == NULL)
318
cmn_err (CE_WARN, "osscore: Cannot allocate memory for a wait queue\n");
322
memset (q, 0, sizeof (*q));
324
if ((q->sv = SV_ALLOC (KM_SLEEP)) == NULL)
327
"osscore: Cannot allocate synchronization variable\n");
335
oss_reset_wait_queue (oss_wait_queue_t * wq)
341
oss_remove_wait_queue (oss_wait_queue_t * wq)
348
sleep_timeout (caddr_t arg)
350
oss_wait_queue_t *wq = (oss_wait_queue_t *) arg;
352
SV_BROADCAST (wq->sv, 0);
356
oss_sleep (oss_wait_queue_t * wq, oss_mutex_t * mutex, int ticks,
357
oss_native_word * flags, unsigned int *status)
366
cmn_err (CE_WARN, "osscore: Unallocated wait queue\n");
367
*status |= WK_SIGNAL;
371
tid = timeout (sleep_timeout, wq, ticks);
374
* Note SV_WAIT_SIG() will release the mutex/lock so we must re-acquire
375
* it before returning.
378
// Pop mutex because it will be released by SV_WAIT_SIG()
379
pop_mutex (*mutex, __FILE__, __LINE__);
381
if (!SV_WAIT_SIG (wq->sv, prihi, *mutex)) /* Signal */
383
*status |= WK_SIGNAL;
384
wq->flags |= WK_WAKEUP; /* Needed to prevent false timeout messages */
387
MUTEX_ENTER_IRQDISABLE (*mutex, *flags);
388
if (ticks > 0 && (wq->flags & WK_WAKEUP))
391
return (wq->flags & WK_WAKEUP);
395
oss_register_poll (oss_wait_queue_t * wq, oss_mutex_t * mutex,
396
oss_native_word * flags, oss_poll_event_t * ev)
398
// NOP: DDI8 doesn't support chpoll
402
oss_wakeup (oss_wait_queue_t * wq, oss_mutex_t * mutex,
403
oss_native_word * flags, short events)
405
wq->flags |= WK_WAKEUP;
406
SV_BROADCAST (wq->sv, 0);
410
oss_get_osid (oss_device_t * osdev)
416
grow_array(oss_device_t *osdev, oss_cdev_t ***arr, int *size, int element_size, int increment)
418
oss_cdev_t **old=*arr, **new = *arr;
419
int old_size = *size;
420
int new_size = *size;
422
new_size += increment;
424
if ((new=PMALLOC(osdev, new_size * element_size))==NULL)
427
memset(new, 0, new_size * element_size);
429
memcpy(new, old, old_size * element_size);
441
oss_install_chrdev (oss_device_t * osdev, char *name, int dev_class,
442
int instance, oss_cdev_drv_t * drv, int flags)
445
* oss_install_chrdev creates a character device (minor). However if
446
* name==NULL the device will not be exported (made visible to userland
451
oss_cdev_t *cdev = NULL;
453
if (dev_class != OSS_DEV_STATUS)
454
if (oss_expired && instance > 0)
457
* Find if this dev_class&instance already exists (after previous module
461
for (num = 0; num < oss_num_cdevs; num++)
462
if (oss_cdevs[num]->d == NULL) /* Unloaded driver */
463
if (oss_cdevs[num]->dev_class == dev_class
464
&& oss_cdevs[num]->instance == instance)
466
cdev = oss_cdevs[num];
472
if (oss_num_cdevs >= OSS_MAX_CDEVS)
474
if (!grow_array(osdev, &oss_cdevs, &oss_max_cdevs, sizeof(oss_cdev_t*), 100))
476
cmn_err (CE_WARN, "Cannot allocate new minor numbers.\n");
481
if ((cdev = PMALLOC (NULL, sizeof (*cdev))) == NULL)
483
cmn_err (CE_WARN, "Cannot allocate character device desc.\n");
486
num = oss_num_cdevs++;
489
memset (cdev, 0, sizeof (*cdev));
490
cdev->dev_class = dev_class;
491
cdev->instance = instance;
495
strncpy (cdev->name, name, sizeof (cdev->name) - 1);
497
strcpy (cdev->name, "NONE");
498
cdev->name[sizeof (cdev->name) - 1] = 0;
499
oss_cdevs[num] = cdev;
503
oss_find_minor (int dev_class, int instance)
507
for (i = 0; i < oss_num_cdevs; i++)
508
if (oss_cdevs[i]->d != NULL && oss_cdevs[i]->dev_class == dev_class
509
&& oss_cdevs[i]->instance == instance)
516
oss_get_cardinfo (int cardnum, oss_card_info * ci)
519
* Print information about a 'card' in a format suitable for /dev/sndstat
522
if (cardnum < 0 || cardnum >= oss_num_cards)
525
if (cards[cardnum]->name != NULL)
526
strncpy (ci->longname, cards[cardnum]->name, 128);
527
ci->shortname[127] = 0;
529
if (cards[cardnum]->nick != NULL)
530
strncpy (ci->shortname, cards[cardnum]->nick, 16);
531
ci->shortname[15] = 0;
533
if (cards[cardnum]->hw_info != NULL)
534
strncpy (ci->hw_info, cards[cardnum]->hw_info, sizeof (ci->hw_info) - 1);
535
ci->hw_info[sizeof (ci->hw_info) - 1] = 0;
541
oss_reserve_device (oss_device_t * osdev)
547
oss_unreserve_device (oss_device_t * osdev, int decrement)
550
if (osdev->refcount < 0)
555
* Some standard C library routines
558
memset (void *t, int c, size_t l)
565
for (i = 0; i < l; i++)
572
memcpy (void *t, const void *s, size_t l)
579
osdev_create (dev_info_t * dip, int dev_type, int instance, const char *nick,
582
oss_device_t *osdev = NULL;
594
* Don't accept any more drivers if expired
596
if (oss_expired && oss_num_cards > 0)
600
* Check if a driver/device was reinserted
602
if (dip != &ldip) /* Not a virtual driver */
603
for (i = 0; i < oss_num_cards; i++)
605
if (!cards[i]->available && cards[i]->key == *dip)
614
if (oss_num_cards >= MAX_CARDS)
616
cmn_err (CE_WARN, "Too many OSS devices. At most %d permitted.\n",
621
if ((osdev = PMALLOC (NULL, sizeof (*osdev))) == NULL)
623
cmn_err (CE_WARN, "osdev_create: Out of memory\n");
627
osdev->cardnum = oss_num_cards;
628
cards[oss_num_cards++] = osdev;
632
osdev->available = 1;
633
osdev->first_mixer = -1;
634
osdev->instance = instance;
635
osdev->dev_type = dev_type;
637
MUTEX_INIT (osdev, osdev->mutex, MH_GLOBAL);
638
sprintf (osdev->nick, "%s%d", nick, instance);
639
strcpy (osdev->modname, nick);
644
//pci_config_setup (dip, &osdev->pci_config_handle);
658
cmn_err (CE_WARN, "Bad device type\n");
663
* Create the device handle
669
unsigned int subvendor = 0;
670
pci_read_config_dword (osdev, 0x2c, &subvendor);
672
sprintf (osdev->handle, "PCI%08x-%d", subvendor, instance);
678
sprintf (osdev->handle, "USB-%s%d", handle, instance);
683
sprintf (osdev->handle, "%s%d", handle, instance);
690
osdev_clone (oss_device_t * orig_osdev, int new_instance)
694
osdev = PMALLOC (NULL, sizeof (*osdev));
697
cmn_err (CE_WARN, "osdev_create: Out of memory\n");
700
memcpy (osdev, orig_osdev, sizeof (*osdev));
701
osdev->dev_type = DRV_CLONE;
702
osdev->instance = new_instance;
703
sprintf (osdev->nick, "%s%d", orig_osdev->modname, new_instance);
704
sprintf (osdev->handle, "%s%d", orig_osdev->modname, new_instance);
710
osdev_delete (oss_device_t * osdev)
717
if (!osdev->available)
719
cmn_err (CE_WARN, "device %s, osdev already deleted\n", osdev->nick);
723
osdev->available = 0;
725
switch (osdev->dev_type)
732
* Mark all minor nodes for this module as invalid.
734
for (i = 0; i < oss_num_cdevs; i++)
735
if (oss_cdevs[i]->osdev == osdev)
737
oss_cdevs[i]->d = NULL;
738
oss_cdevs[i]->osdev = NULL;
739
strcpy (oss_cdevs[i]->name, "Removed device");
741
MUTEX_CLEANUP (osdev->mutex);
745
oss_register_device (oss_device_t * osdev, const char *name)
747
if ((osdev->name = PMALLOC (NULL, strlen (name) + 1)) == NULL)
749
cmn_err (CE_WARN, "Cannot allocate memory for device name\n");
750
osdev->name = "Unknown device";
752
strcpy (osdev->name, name);
757
oss_disable_device (oss_device_t * osdev)
761
* This routine should check if the device is ready to be unloaded (no devices are in use).
762
* If the device cannot be unloaded this routine must return OSS_EBUSY.
764
* If the device can be unloaded then disable any timers or other features that may cause the
765
* device to be called. Also mark the audio/midi/mixer/etc devices of this device to be disabled.
766
* However the interrupt handler should still stay enabled. The low level driver will call
767
* oss_unregister_interrupts() after it has cleared the interrupt enable register.
769
if (osdev->refcount > 0)
775
* Now mark all devices unavailable (for the time being)
778
for (i = 0; i < num_mixers; i++)
779
if (mixer_devs[i]->osdev == osdev)
781
mixer_devs[i]->unloaded = 1;
784
for (i = 0; i < num_mididevs; i++)
786
if (midi_devs[i]->osdev == osdev)
788
midi_devs[i]->unloaded = 1;
792
for (i = 0; i < num_audio_engines; i++)
793
if (audio_engines[i]->osdev == osdev)
795
audio_uninit_device (i);
802
oss_unregister_device (oss_device_t * osdev)
807
static int oss_context = 0; /* 0=user context, 1=interrupt context */
811
ossintr (void *idata)
813
oss_device_t *osdev = idata;
814
oss_native_word flags;
817
saved_context = oss_context;
818
if (oss_context == 1)
819
cmn_err (CE_WARN, "Recursive interrupt\n");
823
MUTEX_ENTER_IRQDISABLE (osdev->mutex, flags);
825
if (!osdev->tophalf_handler (osdev))
827
MUTEX_EXIT_IRQRESTORE (osdev->mutex, flags);
829
oss_context = saved_context;
834
if (osdev->bottomhalf_handler != NULL)
835
osdev->bottomhalf_handler (osdev);
837
MUTEX_EXIT_IRQRESTORE (osdev->mutex, flags);
839
oss_context = saved_context;
842
return ISTAT_ASSERTED;
846
oss_register_interrupts (oss_device_t * osdev, int intrnum,
847
oss_tophalf_handler_t top,
848
oss_bottomhalf_handler_t bottom)
854
cmn_err (CE_WARN, "Bad interrupt index (%d) for %s\n", intrnum,
861
cmn_err (CE_WARN, "oss_register_interrupts: Bad osdev\n");
865
if (osdev->tophalf_handler != NULL || osdev->bottomhalf_handler != NULL)
867
cmn_err (CE_WARN, "Interrupts already registered for %s\n",
874
cmn_err (CE_WARN, "Bad interrupt handler for %s\n", osdev->name);
878
osdev->tophalf_handler = top;
879
osdev->bottomhalf_handler = bottom;
881
(osdev->key, ossintr, osdev, osdev->drvinfo, &osdev->intr_cookie) == 0)
883
cmn_err (CE_WARN, "cm_intr_attach failed for %s\n", osdev->nick);
890
oss_unregister_interrupts (oss_device_t * osdev)
892
if (osdev->intr_cookie != NULL)
893
cm_intr_detach (osdev->intr_cookie);
894
osdev->intr_cookie = NULL;
898
ksprintn (ul, base, lenp)
900
register int base, *lenp;
901
{ /* A long in base 8, plus NULL. */
902
static char buf[sizeof (long) * NBBY / 3 + 2];
908
*++p = "0123456789abcdef"[ul % base];
917
oss_sprintf (char *buf, char *cfmt, ...)
919
const char *fmt = cfmt;
920
register char *p, *bp;
921
register int ch, base;
930
while ((ch = *(unsigned char *) fmt++) != '%')
931
if ((*bp++ = ch) == '\0')
934
return ((bp - buf) - 1);
939
switch (ch = *(unsigned char *) fmt++)
958
*bp++ = va_arg (ap, int);
962
p = va_arg (ap, char *);
969
ul = lflag ? va_arg (ap, long) : va_arg (ap, int);
980
ul = lflag ? va_arg (ap, unsigned long) : va_arg (ap, unsigned int);
986
ul = lflag ? va_arg (ap, unsigned long) : va_arg (ap, unsigned int);
992
ul = lflag ? va_arg (ap, unsigned long) : va_arg (ap, unsigned int);
995
for (p = (char *) ksprintn (ul, base, NULL); ch = *p--;)
1014
build_physreq (int bits)
1019
if ((pr = physreq_alloc (KM_SLEEP)) == NULL)
1022
pr->phys_align = 4096;
1023
pr->phys_boundary = 0;
1024
pr->phys_dmasize = bits;
1025
pr->phys_max_scgth = 0;
1026
pr->phys_flags = PREQ_PHYSCONTIG;
1028
if (physreq_prep (pr, KM_SLEEP) != B_TRUE)
1030
cmn_err (CE_WARN, "osscore: physreq_prep failed\n");
1037
* Driver info device file
1039
static int drvinfo_busy = 0;
1040
static int drvinfo_len = 0, drvinfo_ptr = 0;
1041
static char *drvinfo_buf = NULL;
1042
#define DRVINFO_SIZE 4096
1045
drvinfo_open (int dev, int dev_class, struct fileinfo *file,
1046
int recursive, int open_flags, int *redirect)
1054
if ((drvinfo_buf = KERNEL_MALLOC (DRVINFO_SIZE)) == NULL)
1056
cmn_err (CE_WARN, "Cannot allocate drvinfo buffer\n");
1063
for (i = 1; i < oss_num_cdevs; i++)
1064
if (oss_cdevs[i]->name[0] != 'N' || oss_cdevs[i]->name[1] != 'O' || oss_cdevs[i]->name[2] != 'N' || oss_cdevs[i]->name[3] != 'E') /* Not a dummy placeholder device */
1065
if (DRVINFO_SIZE - drvinfo_len > 32)
1067
char *s = drvinfo_buf + drvinfo_len;
1070
oss_sprintf (s, "%s %s %d\n", oss_cdevs[i]->name,
1071
oss_cdevs[i]->osdev->nick, i);
1079
drvinfo_close (int dev, struct fileinfo *file)
1081
KERNEL_FREE (drvinfo_buf);
1089
drvinfo_read (int dev, struct fileinfo *file, uio_t * buf, int count)
1092
* Return at most 'count' bytes from the drvinfo_buf.
1097
c = drvinfo_len - drvinfo_ptr;
1104
if (uiomove (&drvinfo_buf[drvinfo_ptr], l, UIO_READ, buf) != 0)
1111
static oss_cdev_drv_t drvinfo_cdev_drv = {
1118
install_drvinfo (oss_device_t * osdev)
1120
oss_install_chrdev (osdev, "ossinfo", OSS_DEV_MISC, 0, &drvinfo_cdev_drv,
1125
* Driver entry point routines
1132
oss_device_t *osdev;
1135
if ((err = drv_attach (&oss_drvinfo)) != 0)
1137
cmn_err (CE_WARN, "drv_attach failed %d\n", err);
1141
#ifdef LICENSED_VERSION
1142
if (drv_getparm (TIME, &t) != 0)
1144
cmn_err (CE_WARN, "drv_getparm(TIME) failed\n");
1148
if (!oss_license_handle_time (t))
1150
cmn_err (CE_WARN, "This version of Open Sound System has expired\n");
1152
"Please download the latest version from www.opensound.com\n");
1157
if ((osdev = osdev_create (NULL, DRV_VIRTUAL, 0, "oss", NULL)) == NULL)
1159
cmn_err (CE_WARN, "Creating osdev failed\n");
1164
* Allocate physrec structures for various memory ranges. Remember to free them in the _load
1167
physreq_isa = build_physreq (24);
1168
physreq_28bit = build_physreq (28);
1169
physreq_30bit = build_physreq (30);
1170
physreq_31bit = build_physreq (31);
1171
physreq_32bit = build_physreq (32);
1174
* Create the BCB structure
1176
oss_bcb = bcb_alloc (KM_SLEEP);
1177
oss_bcb->bcb_addrtypes = BA_UIO;
1178
oss_bcb->bcb_flags = 0;
1179
oss_bcb->bcb_max_xfer = 0;
1180
oss_bcb->bcb_granularity = 1;
1181
oss_bcb->bcb_physreqp = physreq_32bit;
1182
bcb_prep (oss_bcb, KM_SLEEP);
1184
install_drvinfo (osdev);
1185
oss_common_init (osdev);
1187
oss_register_device (osdev, "OSS core services");
1196
static int already_unloaded = 0;
1198
if (oss_open_devices > 0)
1200
drv_detach (&oss_drvinfo);
1202
if (already_unloaded)
1204
already_unloaded = 1;
1206
oss_unload_drivers ();
1208
physreq_free (physreq_isa);
1209
physreq_free (physreq_28bit);
1210
physreq_free (physreq_30bit);
1211
physreq_free (physreq_31bit);
1212
physreq_free (physreq_32bit);
1216
for (i = 0; i < oss_nblocks; i++)
1217
KERNEL_FREE (oss_mem_blocks[i]);
1224
oss_pci_byteswap (oss_device_t * osdev, int mode)
1230
oss_pcie_init (oss_device_t * osdev, int flags)
1232
/* TODO: Should we do something? */
1236
pci_read_config_byte (oss_device_t * osdev, offset_t where,
1240
if (cm_read_devconfig (osdev->key, where, val, sizeof (*val)) ==
1242
return PCIBIOS_SUCCESSFUL;
1244
return PCIBIOS_FAILED;
1248
pci_read_config_irq (oss_device_t * osdev, offset_t where, unsigned char *val)
1251
if (cm_read_devconfig (osdev->key, where, val, sizeof (*val)) ==
1253
return PCIBIOS_SUCCESSFUL;
1255
return PCIBIOS_FAILED;
1260
pci_read_config_word (oss_device_t * osdev, offset_t where,
1261
unsigned short *val)
1265
if (cm_read_devconfig (osdev->key, where, val, sizeof (*val)) ==
1267
return PCIBIOS_SUCCESSFUL;
1272
*val = osdev->vendor;
1273
return PCIBIOS_SUCCESSFUL;
1277
*val = osdev->product;
1278
return PCIBIOS_SUCCESSFUL;
1284
return PCIBIOS_FAILED;
1288
pci_read_config_dword (oss_device_t * osdev, offset_t where,
1292
if (cm_read_devconfig (osdev->key, where, val, sizeof (*val)) ==
1294
return PCIBIOS_SUCCESSFUL;
1296
return PCIBIOS_FAILED;
1300
pci_write_config_byte (oss_device_t * osdev, offset_t where,
1303
if (cm_write_devconfig (osdev->key, where, &val, sizeof (val)) ==
1305
return PCIBIOS_SUCCESSFUL;
1307
return PCIBIOS_FAILED;
1311
pci_write_config_word (oss_device_t * osdev, offset_t where,
1314
if (cm_write_devconfig (osdev->key, where, &val, sizeof (val)) ==
1316
return PCIBIOS_SUCCESSFUL;
1318
return PCIBIOS_FAILED;
1322
pci_write_config_dword (oss_device_t * osdev, offset_t where,
1325
if (cm_write_devconfig (osdev->key, where, &val, sizeof (val)) ==
1327
return PCIBIOS_SUCCESSFUL;
1329
return PCIBIOS_FAILED;
1333
* Entry point routines
1336
oss_config (cfg_func_t func, void *idata, rm_key_t key)
1342
oss_devinfo (void *idata, channel_t channel, di_parm_t parm, void *valp)
1353
*(bcb_t **) valp = oss_bcb;
1358
*(bcb_t **) valp = oss_bcb;
1370
oss_biostart (void *idata, channel_t channel, buf_t * bp)
1374
int count = bp->b_un.b_uio->uio_resid;
1377
if ((cdev = oss_cdevs[dev]) == NULL)
1379
bioerror (bp, ENXIO);
1384
cdev->file.acc_flags = 0;
1386
if (bp->b_flags & B_READ)
1388
/* Read operation */
1389
if (cdev->d->read == NULL)
1391
bioerror (bp, ENXIO);
1396
cdev->d->read (cdev->instance, &cdev->file, bp->b_un.b_uio, count);
1398
bioerror (bp, -retval);
1399
else if (retval < count)
1400
bp->b_resid = count - retval;
1406
/* Write operation */
1407
if (cdev->d->write == NULL)
1409
bioerror (bp, ENXIO);
1414
cdev->d->write (cdev->instance, &cdev->file, bp->b_un.b_uio, count);
1416
bioerror (bp, -retval);
1417
else if (retval < count)
1418
bp->b_resid = count - retval;
1424
oss_open (void *idata, channel_t * channelp,
1425
int open_flags, cred_t * crp, queue_t * q)
1427
oss_device_t *osdev;
1428
int dev = *channelp, tmpdev;
1434
if (dev >= OSS_MAX_CDEVS)
1437
if (dev >= oss_num_cdevs)
1442
if ((cdev = oss_cdevs[dev]) == NULL || cdev->d == NULL)
1445
if (cdev->d->open == NULL)
1450
memset (&cdev->file, 0, sizeof (cdev->file));
1451
cdev->file.mode = 0;
1452
cdev->file.acc_flags = open_flags;
1454
if (open_flags & FREAD && open_flags & FWRITE)
1455
cdev->file.mode = OPEN_READWRITE;
1456
else if (open_flags & FREAD)
1457
cdev->file.mode = OPEN_READ;
1458
else if (open_flags & FWRITE)
1459
cdev->file.mode = OPEN_WRITE;
1463
cdev->d->open (cdev->instance, cdev->dev_class, &cdev->file, 0, 0, &tmpdev);
1479
oss_close (void *idata, channel_t channel,
1480
int oflags, cred_t * crp, queue_t * q)
1487
if (dev >= OSS_MAX_CDEVS)
1490
if ((cdev = oss_cdevs[dev]) == NULL)
1493
if (cdev->open_count == 0) /* Not opened */
1496
cdev->d->close (cdev->instance, &cdev->file);
1504
oss_ioctl (void *idata, channel_t channel, int cmd, void *arg,
1505
int oflags, cred_t * crp, int *rvalp)
1510
char localbuf[256]; /* All frequently used ioctl calls fit in 256 bytes */
1511
char *buf = localbuf, *auxbuf = NULL;
1514
if ((cdev = oss_cdevs[dev]) == NULL || cdev->d->ioctl == NULL)
1515
return *rvalp = ENXIO;
1518
return *rvalp = ENODEV;
1520
if (cmd & (SIOC_OUT | SIOC_IN))
1523
len = __SIOC_SIZE (cmd);
1526
if (len > sizeof (localbuf))
1529
* For the few largest ioctl calls we need to allocate an off-stack
1530
* buffer because otherwise the kernel stack will overflow.
1531
* This approach is slower but fortunately "sane" applications don't
1532
* use these ioctl calls too frequently.
1534
if ((auxbuf = KERNEL_MALLOC (len)) == NULL)
1537
"Failed to allocate an ioctl buffer of %d bytes\n",
1539
return *rvalp = ENOMEM;
1544
if ((cmd & SIOC_IN) && len > 0)
1546
if (copyin ((char *) arg, buf, len) == -1)
1549
KERNEL_FREE (auxbuf);
1550
return *rvalp = EFAULT;
1556
retval = cdev->d->ioctl (cdev->instance, &cdev->file, cmd, (ioctl_arg) buf);
1558
if ((cmd & SIOC_OUT) && len > 0)
1560
if (copyout (buf, (char *) arg, len) == -1)
1563
KERNEL_FREE (auxbuf);
1564
return *rvalp = EFAULT;
1568
*rvalp = (((retval) < 0) ? -(retval) : 0);
1571
KERNEL_FREE (auxbuf);
1582
const char *filename;
1587
static mutex_debug_t mutex_tab[1024];
1588
static int n_mutexes = 0;
1591
push_mutex (void *mutex, const char *file, int line)
1594
//cmn_err(CE_CONT, "Push mutex %08x, %s:%d, context=%d\n", mutex, file, line, oss_context);
1596
for (i = 0; n == -1 && i < n_mutexes; i++)
1597
if (!mutex_tab[i].active)
1601
if (mutex_tab[i].mutex == mutex
1602
&& mutex_tab[i].context == oss_context)
1604
cmn_err (CE_NOTE, "Mutex %08x already held\n", mutex);
1605
cmn_err (CE_CONT, " Locked by %s:%d\n", mutex_tab[i].filename,
1607
cmn_err (CE_CONT, " Acquire by %s:%d\n", file, line);
1613
if (n_mutexes >= 1024)
1615
cmn_err (CE_NOTE, "Mutex debug table full\n");
1621
mutex_tab[n].active = 1;
1622
mutex_tab[n].mutex = mutex;
1623
mutex_tab[n].filename = file;
1624
mutex_tab[n].line = line;
1625
mutex_tab[n].context = oss_context;
1629
pop_mutex (void *mutex, const char *file, int line)
1633
//cmn_err(CE_CONT, "Pop mutex %08x, %s:%d, context=%d\n", mutex, file, line, oss_context);
1634
for (i = 0; i < n_mutexes; i++)
1635
if (mutex_tab[i].active && mutex_tab[i].mutex == mutex
1636
&& mutex_tab[i].context == oss_context)
1638
mutex_tab[i].active = 0;
1639
mutex_tab[i].filename = file;
1640
mutex_tab[i].line = line;
1644
cmn_err (CE_NOTE, "Mutex %08x not locked (%s:%d), context=%d\n",
1645
mutex, file, line, oss_context);
1646
for (i = 0; i < n_mutexes; i++)
1647
if (mutex_tab[i].active == 0 && mutex_tab[i].mutex == mutex)
1649
cmn_err (CE_CONT, " Previous unlock at %s:%d, context=%d\n",
1650
mutex_tab[i].filename, mutex_tab[i].line,
1651
mutex_tab[i].context);
1656
print_mutexes (void)
1660
for (i = 0; i < n_mutexes; i++)
1661
if (mutex_tab[i].active)
1664
cmn_err (CE_CONT, "%d mutexes held\n", n);
1666
for (i = 0; i < n_mutexes; i++)
1667
if (mutex_tab[i].active)
1668
cmn_err (CE_CONT, " %08x %s:%d\n", mutex_tab[i].mutex,
1669
mutex_tab[i].filename, mutex_tab[i].line);
1674
oss_get_procinfo(int what)