2
* Purpose: OSS device autodetection utility for Solaris
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.
20
#include <libdevinfo.h>
21
#include <sys/types.h>
24
#include <sys/utsname.h>
26
#include <sys/systeminfo.h>
28
static int use_force = 0;
29
static char arch[32] = "";
30
static int install_imux = 0;
31
static int install_userdev = 0;
32
static char *safe_mode="";
34
/* List of all modules installed in the system (OSS and non-oss) */
36
static char *installed_modules[MAX_MODS];
40
FILE *drivers_f = NULL;
42
static const char *ossdevs[] = {
54
scan_devdir (char *path)
61
char fullname[256], *devpart, devclass[256], *s;
64
if ((dir = opendir (path)) == NULL)
70
while ((de = readdir (dir)) != NULL)
72
if (de->d_name[0] == '.')
75
sprintf (fullname, "%s/%s", path, de->d_name);
77
if (stat (fullname, &st) == -1)
83
if (S_ISDIR (st.st_mode))
85
scan_devdir (fullname);
90
if (!S_ISCHR (st.st_mode))
95
* Find the device name part (after ":").
109
strcpy (devclass, devpart);
120
* Check if this kind of devices are known by OSS
124
for (i = 0; !ok && ossdevs[i] != NULL; i++)
125
if (strcmp (devclass, ossdevs[i]) == 0)
131
sprintf (devname, "/dev/%s", devpart);
134
if (symlink (fullname, devname) == -1)
155
char *key, *driver, *name;
156
int is_3rdparty, reload;
159
#define MAX_DRIVERS 1000
160
static driver_def_t drivers[MAX_DRIVERS];
161
static int ndrivers = 0;
163
#define MAX_MODULES 32
164
static module_def_t modules[MAX_MODULES];
165
static int nmodules = 0;
167
static int verbose = 0;
170
install_driver (driver_def_t * drv, char *drv_id)
175
printf ("Install module '%s' (%s)\n", drv->driver, drv_id);
177
for (i = 0; i < nmodules; i++)
178
if (strcmp (drv->driver, modules[i].driver) == 0)
180
for (j = 0; j < modules[i].nids; j++)
182
if (strcmp (drv_id, modules[i].ids[j]) == 0)
186
strcat (modules[i].idlist, " \"");
187
strcat (modules[i].idlist, drv_id);
188
strcat (modules[i].idlist, "\"");
190
if (modules[i].nids < 32)
192
int n = modules[i].nids++;
193
modules[i].ids[n] = strdup (drv_id);
198
if (nmodules >= MAX_MODULES)
200
fprintf (stderr, "Too many OSS modules\n");
204
modules[nmodules].name = drv->name;
205
modules[nmodules].driver = drv->driver;
206
sprintf (modules[nmodules].idlist, "\"%s\"", drv_id);
207
modules[nmodules].nids = 1;
208
modules[nmodules].ids[0] = strdup (drv_id);
209
modules[nmodules].pass = 0;
212
* Hot-pluggable modules should be loaded after other modules.
214
if (strcmp (drv->driver, "oss_usb") == 0)
215
modules[nmodules].pass = 1;
221
find_and_install_driver (char *key)
226
for (i = 0; i < ndrivers; i++)
227
if (strcmp (drivers[i].key, key) == 0)
230
printf ("\nDetected %s: %s (driver=%s)\n",
231
key, drivers[i].name, drivers[i].driver);
232
install_driver (&drivers[i], key);
238
check_name (char *key, char *realname)
242
if (realname == NULL)
245
for (i = 0; i < ndrivers; i++)
246
if (strcmp (drivers[i].key, key) == 0)
249
printf ("\nDetected %s: %s (driver=%s)\n",
250
realname, drivers[i].name, drivers[i].driver);
251
/* install_driver(&drivers[i], realname); */
252
install_driver (&drivers[i], key);
259
check_node (di_node_t node, int level, char *realname)
263
while (node != DI_NODE_NIL)
265
char *name = di_node_name (node), *p;
273
for (j = 1; j < level; j++)
275
printf ("%s ", name);
278
/* if (realname==NULL) */
283
if (check_name (name, realname))
287
char *drv = di_driver_name (node);
288
char *bnd = di_binding_name (node);
293
printf ("*match (driver=%s, binding=%s, instance=%d)*", drv,
294
bnd, di_instance (node));
302
n = di_compatible_names (node, &cnames);
304
for (i = 0; i < n; i++)
309
for (j = 1; j < level; j++)
311
printf (" = %s ", p);
314
if (check_name (p, realname))
318
char *drv = di_driver_name (node);
319
char *bnd = di_binding_name (node);
324
printf ("*match (driver=%s, binding=%s, instance=%d)*",
325
drv, bnd, di_instance (node));
332
p = p + strlen (p) + 1;
336
{ /* Handle properties */
337
di_prop_t prop = DI_PROP_NIL;
339
while ((prop = di_prop_next (node, prop)) != DI_PROP_NIL)
341
printf ("\tProp '%s'}n", di_prop_name (prop));
346
check_node (di_child_node (node), level + 1, realname);
348
node = di_sibling_node (node);
355
load_devlist (const char *fname, int is_3rdparty)
359
char *driver, *key, *name;
361
if ((f = fopen (fname, "r")) == NULL)
367
while (fgets (line, sizeof (line) - 1, f) != NULL)
372
if (*p == '#' || *p == '\n')
377
/* Drivers with upper case names are unsupported ones */
378
if ((*line >= 'A' && *line <= 'Z') || (*line == '\0'))
384
while (*p && *p != '\t' && *p != ' ')
391
* PCI subvendor ID's are marked as pcsNN,MM in devices.list. Convert them
392
* to pciNN,MM for Solaris
394
if (strncmp (key, "pcs", 3) == 0)
397
while (*p && *p != '\t')
404
printf ("device=%s, name=%s, driver=%s\n", key, name, driver);
406
if (ndrivers >= MAX_DRIVERS)
408
printf ("Too many drivers defined in drivers.list\n");
412
drivers[ndrivers].key = strdup (key);
413
drivers[ndrivers].driver = strdup (driver);
414
drivers[ndrivers].name = strdup (name);
415
drivers[ndrivers].is_3rdparty = is_3rdparty;
416
drivers[ndrivers].reload = 0;
425
check_conf (char *modname, int is_virtual, char *options)
427
char fname[256], drivername[256];
432
sprintf (fname, "/kernel/drv/%s.conf", modname);
433
sprintf (drivername, "/kernel/drv/%s%s", arch, modname);
435
sprintf (fname, "/kernel/drv/%s.conf", modname);
436
sprintf (drivername, "/kernel/drv/%s%s", arch, modname);
439
/* fprintf(start_script, "/usr/sbin/modload %s\n", drivername); */
442
if (stat (fname, &st) != -1) /* File already exists */
445
fprintf (stderr, "\n\nWarning! Config file %s was missing!\n\n", fname);
447
if ((f = fopen (fname, "w")) == NULL)
452
fprintf (f, "# Open Sound System configuration file\n");
455
fprintf (f, "name=\"%s\" parent=\"pseudo\" instance=0%s;\n", modname,
458
fprintf (f, "interrupt-priorities=9%s;\n", options);
464
load_name_to_major (void)
469
if ((f = fopen ("/etc/name_to_major", "r")) == NULL)
472
while (fgets (line, sizeof (line), f) != NULL)
476
while (*p && *p != ' ')
480
if (*line == '\0') continue;
482
if (nmods < MAX_MODS)
484
installed_modules[nmods++] = strdup (line);
488
* Force reinstall of imux if it is currently installed in the system
490
if (strcmp (line, "oss_imux") == 0)
492
if (strcmp (line, "oss_userdev") == 0)
500
add_drv (char *name, char *drv, char *parms)
505
printf ("add_drv %s%s %s\n", safe_mode, parms, drv);
506
sprintf (tmp, "add_drv %s%s %s", safe_mode, parms, drv);
511
fprintf (stderr, "%s\n", tmp);
513
/* save the driver and name info in installed_drivers file except osscore */
515
fprintf (drivers_f, "%s #%s\n", drv, name);
521
load_license (char *fname)
526
if (stat (fname, &st) == -1)
527
return; /* Doesn't exist */
529
if (stat ("/usr/sbin/osslic", &st) == -1)
530
return; /* No osslic utility in the system. No need to install license. */
532
sprintf (cmd, "/usr/sbin/osslic -q %s", fname);
537
forceload_drivers (char *fname)
542
if ((f = fopen (fname, "r")) == NULL)
545
while (fgets (line, sizeof (line), f) != NULL)
547
p = strchr (line, '\n');
549
find_and_install_driver (line);
554
main (int argc, char *argv[])
562
char *cmd = "/usr/sbin/modinfo | grep osscommon";
565
if (sysinfo (SI_ARCHITECTURE_K, tmp, sizeof (tmp)) == -1)
567
perror ("sysinfo SI_ARCHITECTURE_K");
571
if (sysinfo (SI_ARCHITECTURE, tmp, sizeof (tmp)) == -1)
573
perror ("sysinfo SI_ARCHITECTURE");
578
load_name_to_major ();
581
if (strcmp (tmp, "sparc") == 0)
582
sprintf (arch, "sparcv9/", tmp);
584
if (strcmp (tmp, "amd64") == 0)
585
sprintf (arch, "%s/", tmp);
588
while ((c = getopt (argc, argv, "vfiudlVS")) != EOF)
597
case 'S': /* Safe mode */
606
case 'd': /* Obolete under Solaris. */
610
load_license ("/etc/oss/license.asc");
615
load_license ("/etc/oss/license.asc");
617
load_devlist ("/etc/oss/devices.list", 0);
619
if ((drivers_f = fopen ("/etc/oss/installed_drivers", "w")) == NULL)
621
perror ("/etc/oss/installed_drivers");
625
if (stat ("/etc/oss_3rdparty", &st) != -1)
626
load_devlist ("/etc/oss_3rdparty", 1);
628
if ((root_node = di_init ("/", DINFOSUBTREE)) == DI_NODE_NIL)
630
printf ("di_init() failed\n");
633
check_node (root_node, 0, NULL);
638
* Force unconditional loading of the USB driver and few others to make
639
* hotplugging possible.
641
forceload_drivers ("/etc/oss/forceload.conf");
645
for (i = 0; i < nmodules; i++)
647
printf ("Would add %s -i '%s'\n", modules[i].driver,
650
printf ("Skipping actual device installation\n");
657
* Unload drivers that appear to be loaded
659
for (i = 0; i < nmods; i++)
663
for (j = 0; j < ndrivers && !ok; j++)
665
if (strcmp (installed_modules[i], drivers[j].driver) == 0)
668
if (strcmp (drivers[j].key, "$PSEUDO") == 0 ||
669
drivers[j].is_3rdparty)
671
if (drivers[j].is_3rdparty)
672
printf ("Removed 3rd party driver %s\n",
674
drivers[j].reload = 1;
682
sprintf (tmp, "rem_drv %s\n", installed_modules[i]);
683
printf ("rem_drv %s\n", installed_modules[i]);
690
* Tell the osscore module to go away by writing something to /dev/sndstat
691
* (at this moment it doesn't matter what is written).
694
system ("rem_drv osscore");
698
/* Find the osscommon module's PID and pass it to moduload to unload it */
699
if ((ptr = popen (cmd, "r")) != NULL)
701
if (fscanf (ptr, "%d", &pid) == 1 && pid > 0)
703
sprintf (tmp, "modunload -i %d", pid);
704
fprintf (stderr, "unloaded osscommon\n");
711
/* Now start loading all the modules */
712
check_conf ("osscore", 1, "");
714
if (add_drv ("OSS Core Devices", "osscore", "-m '* 0666 root sys'") != 0)
716
fprintf (stderr, "Installing OSS (osscore) failed\n");
720
for (pass = 0; pass < 2; pass++)
721
for (i = 0; i < nmodules; i++)
722
if (modules[i].pass == pass)
724
check_conf (modules[i].driver, 0, "");
725
sprintf (tmp, "-m '* 0666 root sys' -i '%s'", modules[i].idlist);
726
if (add_drv (modules[i].name, modules[i].driver, tmp) != 0)
728
fprintf (stderr, "Installing OSS (%s) failed\n",
736
check_conf ("oss_imux", 1, "");
737
add_drv ("OSS Input Multiplexer", "oss_imux", "-m '* 0666 root sys'");
742
check_conf ("oss_userdev", 1, "");
743
add_drv ("OSS User space device driver", "oss_userdev", "-m '* 0666 root sys'");
747
if (stat("/kernel/drv/sparcv9/oss_sadasupport", &st) != -1)
748
if (stat("/kernel/misc/sparcv9/audiosup", &st) != -1)
750
if (stat("/kernel/drv/oss_sadasupport", &st) != -1)
751
if (stat("/kernel/misc/audiosup", &st) != -1)
754
check_conf ("oss_sadasupport", 1, "");
755
add_drv ("SADA emulation layer", "oss_sadasupport", "-m '* 0666 root sys'");
758
for (i = 0; i < ndrivers; i++)
759
if (drivers[i].reload)
760
if (!drivers[i].is_3rdparty)
762
check_conf (drivers[i].driver, 1, "");
763
add_drv (drivers[i].name, drivers[i].driver,
764
"-m '* 0666 root sys'");
770
if (strcmp (drivers[i].key, "$PSEUDO") == 0)
772
add_drv (drivers[i].name, drivers[i].driver,
773
"-m '* 0666 root sys'");
777
sprintf (parms, "-i '%s' -m '* 0666 root sys'", drivers[i].key);
778
printf ("Attempting to reload %s\n", drivers[i].driver);
779
add_drv (drivers[i].name, drivers[i].driver, parms);
783
* Reload the previous default settings if they were ever saved.
785
if (stat ("/etc/oss/mixer.save", &st) != -1 ||
786
stat ("/etc/oss/dspdevs.map", &st) != -1)
787
system ("savemixer -L");
792
printf ("Restarting OSS - Please wait\r");