From c053a5cffcccb5eaac6dad33e16437ac43931f12 Mon Sep 17 00:00:00 2001 From: Jaroslav Kysela Date: Sun, 22 Sep 2002 08:58:04 +0000 Subject: [PATCH] Added sscape_ctl tool --- Makefile | 2 +- sscape_ctl/Makefile.am | 14 +++ sscape_ctl/configure.in | 52 ++++++++++ sscape_ctl/cvscompile | 24 +++++ sscape_ctl/sscape_ctl.c | 221 ++++++++++++++++++++++++++++++++++++++++ 5 files changed, 312 insertions(+), 1 deletion(-) create mode 100644 sscape_ctl/Makefile.am create mode 100644 sscape_ctl/configure.in create mode 100644 sscape_ctl/cvscompile create mode 100644 sscape_ctl/sscape_ctl.c diff --git a/Makefile b/Makefile index 3a7b70e..38bb29e 100644 --- a/Makefile +++ b/Makefile @@ -1,6 +1,6 @@ VERSION = 0.9.0rc1 TOP = . -SUBDIRS = ac3dec as10k1 envy24control sb16_csp seq +SUBDIRS = ac3dec as10k1 envy24control sb16_csp seq sscape_ctl all: @for i in $(SUBDIRS); do cd $(TOP)/$$i; ./cvscompile; cd ..; make -C $$i; done diff --git a/sscape_ctl/Makefile.am b/sscape_ctl/Makefile.am new file mode 100644 index 0000000..737e51b --- /dev/null +++ b/sscape_ctl/Makefile.am @@ -0,0 +1,14 @@ +# # Process this file with automake to produce Makefile.in. +AUTOMAKE_OPTIONS = 1.3 foreign + +CFLAGS = -Wall -g + +bin_PROGRAMS = sscape_ctl + +sscape_ctl_SOURCES = sscape_ctl.c + +alsa-dist: distdir + @rm -rf ../distdir/sscape_ctl + @mkdir -p ../distdir/sscape_ctl + @cp -RLpv $(distdir)/* ../distdir/sscape_ctl + @rm -rf $(distdir) diff --git a/sscape_ctl/configure.in b/sscape_ctl/configure.in new file mode 100644 index 0000000..c28b853 --- /dev/null +++ b/sscape_ctl/configure.in @@ -0,0 +1,52 @@ +AC_INIT(sscape_ctl.c) +AM_INIT_AUTOMAKE(sscape_ctl, 0.1.0) +AC_PROG_CC +AC_PROG_INSTALL +AC_HEADER_STDC +AM_PATH_ALSA(0.9.0) + +dnl kernel header files +AC_MSG_CHECKING(for kernel header files) +AC_ARG_WITH(kernel, + [ --with-kernel=ver specify kernel version (for example 2.5.5-pre1)], + [kerneldir="$withval"], [kerneldir=""]) +if test "$kerneldir" != "" -a -r "/lib/modules/$kerneldir/build/include/sound"; then + kerneldir="/lib/modules/$kerneldir/build/include" + AC_MSG_RESULT($kerneldir) +else + if test -z "$kerneldir"; then + AC_MSG_RESULT("not specified") + else + AC_MSG_RESULT("directory /lib/modules/$kerneldir/build/include/sound not found") + fi + kerneldir="" +fi + +dnl path for sound/asound.h +AC_MSG_CHECKING(for directory with ALSA kernel headers) +AC_ARG_WITH(soundbase, + [ --with-soundbase=dir specify base directory with kernel sound headers (optional)], + [soundbasedir="$withval"], [soundbasedir="$kerneldir"]) +if test "$soundbasedir" != "" -a -r "$soundbasedir/sound" ; then + ALSA_CFLAGS="$ALSA_CFLAGS -I$soundbasedir" + CFLAGS="$CFLAGS -I$soundbasedir" + AC_MSG_RESULT($ALSA_CFLAGS) +else + if test "x$prefix" != xNONE; then + aprefix=$prefix + else + aprefix=$ac_default_prefix + fi + if test -z "$soundbasedir" -a -r "$aprefix/include/sound"; then + ALSA_CFLAGS="$ALSA_CFLAGS -I$aprefix/include" + CFLAGS="$CFLAGS -I$aprefix/include" + AC_MSG_RESULT($ALSA_CFLAGS) + else + AC_MSG_RESULT("not specified - using C compilator defaults") + fi +fi + +CFLAGS="$CFLAGS $ALSA_FLAGS" +LDFLAGS="$LDFLAGS $ALSA_LIBS" + +AC_OUTPUT(Makefile) diff --git a/sscape_ctl/cvscompile b/sscape_ctl/cvscompile new file mode 100644 index 0000000..01e8151 --- /dev/null +++ b/sscape_ctl/cvscompile @@ -0,0 +1,24 @@ +#!/bin/bash + +if test "x$AUTOMAKE_DIR" = "x"; then + if test -d /usr/local/share/automake; then + AUTOMAKE_DIR=/usr/local/share/automake + fi + if test -d /usr/share/automake; then + AUTOMAKE_DIR="/usr/share/automake" + fi +fi + +for f in install-sh mkinstalldirs missing; do + cp -av $AUTOMAKE_DIR/$f . +done + +aclocal $ACLOCAL_FLAGS +automake --foreign --add-missing +autoconf +export CFLAGS='-O2 -Wall -pipe -g' +echo "CFLAGS=$CFLAGS" +echo "./configure $@" +./configure $@ +unset CFLAGS +make diff --git a/sscape_ctl/sscape_ctl.c b/sscape_ctl/sscape_ctl.c new file mode 100644 index 0000000..4f533d1 --- /dev/null +++ b/sscape_ctl/sscape_ctl.c @@ -0,0 +1,221 @@ +#include +#include +#include + +#include +#include +#include +#include +#include + +#include +#include + + +const char default_dir[] = "/sndscape"; +const char scope[] = "scope.cod"; + + +void +safe_close(int fd) +{ + int err; + while (((err = close(fd)) != 0) && (errno == EINTR)) {} +} + +size_t +get_directory(const char *dir, char *buffer, size_t bufsize) +{ + size_t len; + + len = snprintf(buffer, bufsize, "%s/", dir); + if (len >= bufsize) + return 0; + + if ((len > 1) && (buffer[len - 1] == '/') && (buffer[len - 2] == '/')) + { + buffer[--len] = '\0'; + } + + return len; +} + + +size_t +get_bootfile(const char *filename, char *buffer, size_t bufsize) +{ + size_t len = snprintf(buffer, bufsize, "%s", filename); + if (len >= bufsize) + return 0; + return len; +} + + +size_t +get_mcodefile(unsigned version, char *buffer, size_t bufsize) +{ + static const char sndscape[] = "sndscape.co%u"; + + size_t len = snprintf(buffer, bufsize, sndscape, version); + if (len >= bufsize) + return 0; + return len; +} + + +int +load_bootblock(const char *fname, struct sscape_bootblock *boot) +{ + int err; + int fd; + + printf("Bootblock: %s\n", fname); + + err = fd = open(fname, O_RDONLY); + if (err >= 0) + { + int save_errno; + + err = read(fd, boot->code, sizeof(boot->code)); + if (err >= 0) + { + printf("Bootblock: read %d bytes\n", err); + err = 0; + } + + save_errno = errno; + safe_close(fd); + errno = save_errno; + } + + return err; +} + + +int +load_microcode(const char *fname, struct sscape_microcode *microcode) +{ + int err; + int fd; + + printf("Microcode: %s\n", fname); + + err = fd = open(fname, O_RDONLY); + if (err >= 0) + { + int save_errno; + + err = read(fd, microcode->code, sizeof(microcode->code)); + if (err >= 0) + { + printf("Microcode: read %d bytes\n", err); + err = 0; + } + + save_errno = errno; + safe_close(fd); + errno = save_errno; + } + + return err; +} + +static const struct option long_option[] = { + { "card", 1, NULL, 'c' }, + { "directory", 1, NULL, 'd' }, + { NULL, 0, NULL, '\0' } +}; + +static const char option[] = "c:d:"; + +int +main(int argc, char *argv[]) +{ + char devicename[32]; + int ret, err; + snd_hwdep_t *handle; + + const char *directory = default_dir; + int card = 0; + + int oindex; + int c; + + while ( (c = getopt_long(argc, argv, option, long_option, &oindex)) != EOF ) + { + switch(c) + { + case 'c': + card = snd_card_get_index(optarg); + if (card < 0 || card > 31) { + fprintf(stderr, "Wrong -c argument '%s'\n", optarg); + return EXIT_FAILURE; + } + break; + + case 'd': + directory = optarg; + break; + + default: + fprintf(stderr, "Unknown option \'%c\'\n", c); + break; + } /* switch */ + } /* while */ + + ret = EXIT_FAILURE; + sprintf(devicename, "hw:%i,0", card); + err = snd_hwdep_open(&handle, devicename, O_WRONLY); + if (err < 0) + { + fprintf(stderr, "Error opening %s: %s\n", devicename, snd_strerror(err)); + } + else + { + char filename[FILENAME_MAX]; + size_t len; + + struct sscape_bootblock boot; + struct sscape_microcode microcode; + + if ((len = get_directory(directory, filename, sizeof(filename))) == 0) + { + fprintf(stderr, "Invalid directory - pathname too long\n"); + } + else if (get_bootfile(scope, filename + len, sizeof(filename) - len) == 0) + { + fprintf(stderr, "Invalid filename - full pathname too long\n"); + } + else if (load_bootblock(filename, &boot) < 0) + { + fprintf(stderr, "Failed to load file [%s]: %s\n", + filename, strerror(errno)); + } + else if (snd_hwdep_ioctl(handle, SND_SSCAPE_LOAD_BOOTB, &boot) < 0) + { + fprintf(stderr, "IOCTL error: %s\n", strerror(errno)); + } + else if (get_mcodefile(boot.version & 0x0f, + filename + len, sizeof(filename) - len) == 0) + { + fprintf(stderr, "Invalid filename - full pathname too long\n"); + } + else if (load_microcode(filename, µcode) < 0) + { + fprintf(stderr, "Failed to load microcode [%s]\n", filename); + } + else if (snd_hwdep_ioctl(handle, SND_SSCAPE_LOAD_MCODE, µcode) < 0) + { + fprintf(stderr, "IOCTL error: %s\n", strerror(errno)); + } + else + { + printf("Microcode loaded.\n"); + ret = EXIT_SUCCESS; + } + snd_hwdep_close(handle); + } + + return ret; +} + -- 2.47.1