Update of /cvsroot/alsa/alsa-driver/isa
In directory usw-pr-cvs1:/tmp/cvs-serv10991

Modified Files:
        sscape.c 
Log Message:
Update by Chris Rankin.
Added module parameters.  non-pnp cards should work (in theory), too.



Index: sscape.c
===================================================================
RCS file: /cvsroot/alsa/alsa-driver/isa/sscape.c,v
retrieving revision 1.9
retrieving revision 1.10
diff -u -r1.9 -r1.10
--- sscape.c    21 Oct 2002 18:52:09 -0000      1.9
+++ sscape.c    22 Oct 2002 10:45:19 -0000      1.10
@@ -29,9 +29,9 @@
 #include <linux/init.h>
 #include <linux/delay.h>
 #ifndef LINUX_ISAPNP_H
-#include <linux/isapnp.h>
-#define isapnp_card pci_bus
-#define isapnp_dev pci_dev
+#  include <linux/isapnp.h>
+#  define isapnp_card pci_bus
+#  define isapnp_dev pci_dev
 #endif
 #include <linux/spinlock.h>
 #include <asm/dma.h>
@@ -53,11 +53,36 @@
 MODULE_LICENSE("GPL");
 
 static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX;
+static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR;
+static long port[SNDRV_CARDS] = { [0 ... (SNDRV_CARDS-1)] = SNDRV_AUTO_PORT };
+static int irq[SNDRV_CARDS] = SNDRV_DEFAULT_IRQ;
+static int mpu_irq[SNDRV_CARDS] = SNDRV_DEFAULT_IRQ;
+static int dma[SNDRV_CARDS] = SNDRV_DEFAULT_DMA;
 
 MODULE_PARM(index, "1-" __MODULE_STRING(SNDRV_CARDS) "i");
-MODULE_PARM_DESC(index, "Index number for this soundcard");
+MODULE_PARM_DESC(index, "Index number for SoundScape soundcard");
 MODULE_PARM_SYNTAX(index, SNDRV_INDEX_DESC);
 
+MODULE_PARM(id, "1-" __MODULE_STRING(SNDRV_CARDS) "s");
+MODULE_PARM_DESC(id, "Description for SoundScape card");
+MODULE_PARM_SYNTAX(id, SNDRV_ID_DESC);
+
+MODULE_PARM(port, "1-" __MODULE_STRING(SNDRV_CARDS) "l");
+MODULE_PARM_DESC(port, "Port # for SoundScape driver.");
+MODULE_PARM_SYNTAX(port, SNDRV_ENABLED);
+
+MODULE_PARM(irq, "1-" __MODULE_STRING(SNDRV_CARDS) "i");
+MODULE_PARM_DESC(irq, "IRQ # for SoundScape driver.");
+MODULE_PARM_SYNTAX(irq, SNDRV_IRQ_DESC);
+
+MODULE_PARM(mpu_irq, "1-" __MODULE_STRING(SNDRV_CARDS) "i");
+MODULE_PARM_DESC(mpu_irq, "MPU401 IRQ # for SoundScape driver.");
+MODULE_PARM_SYNTAX(mpu_irq, SNDRV_IRQ_DESC);
+
+MODULE_PARM(dma, "1-" __MODULE_STRING(SNDRV_CARDS) "i");
+MODULE_PARM_DESC(dma, "DMA # for SoundScape driver.");
+MODULE_PARM_SYNTAX(dma, SNDRV_DMA8_DESC);
+  
 static const struct isapnp_card_id sscape_pnpids[] __devinitdata = {
        {ISAPNP_CARD_ID('E', 'N', 'S', 0x3081), .devs = {ISAPNP_DEVICE_ID('E', 'N', 
'S', 0x0000)}},
        {ISAPNP_CARD_END}
@@ -66,7 +91,6 @@
 ISAPNP_CARD_TABLE(sscape_pnpids);
 
 static snd_card_t *sscape_card[SNDRV_CARDS];
-static unsigned __initdata sscape_count;
 
 
 #define MPU401_IO(i)     ((i) + 0)
@@ -130,8 +154,15 @@
        int hw_in_use;
        unsigned long midi_usage;
        unsigned char midi_vol;
+
+#ifdef __ISAPNP__
+       struct isapnp_dev *isapnp;
+#endif
 };
 
+#define INVALID_IRQ  ((unsigned)-1)
+
+
 static inline struct soundscape *get_card_soundscape(snd_card_t * c)
 {
        return (struct soundscape *) (c->private_data);
@@ -432,8 +463,8 @@
  * Upload a byte-stream into the SoundScape using DMA channel A.
  */
 static int upload_dma_data(struct soundscape *s,
-                          const unsigned char *data, unsigned long size,
-                          unsigned long dmasize)
+                           const unsigned char *data, unsigned long size,
+                           unsigned long dmasize)
 {
        unsigned long flags;
        struct dmabuf dma;
@@ -512,7 +543,7 @@
                ret = -EAGAIN;
        }
 
-      _release_dma:
+       _release_dma:
        /*
         * NOTE!!! We are NOT holding any spinlocks at this point !!!
         */
@@ -569,7 +600,7 @@
  * userspace memory addresses.
  */
 static int sscape_upload_microcode(struct soundscape *sscape,
-                                  const struct sscape_microcode *mc)
+                                   const struct sscape_microcode *mc)
 {
        unsigned long flags;
        int ret;
@@ -626,7 +657,7 @@
 }
 
 static int sscape_hw_ioctl(snd_hwdep_t * hw, struct file *file,
-                          unsigned int cmd, unsigned long arg)
+                           unsigned int cmd, unsigned long arg)
 {
        struct soundscape *sscape = get_hwdep_soundscape(hw);
        int err = -EBUSY;
@@ -686,7 +717,7 @@
  * Mixer control for the SoundScape's MIDI device.
  */
 static int sscape_midi_info(snd_kcontrol_t * ctl,
-                           snd_ctl_elem_info_t * uinfo)
+                            snd_ctl_elem_info_t * uinfo)
 {
        uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
        uinfo->count = 1;
@@ -696,7 +727,7 @@
 }
 
 static int sscape_midi_get(snd_kcontrol_t * kctl,
-                          snd_ctl_elem_value_t * uctl)
+                           snd_ctl_elem_value_t * uctl)
 {
        cs4231_t *chip = snd_kcontrol_chip(kctl);
        snd_card_t *card = chip->card;
@@ -716,7 +747,7 @@
 }
 
 static int sscape_midi_put(snd_kcontrol_t * kctl,
-                          snd_ctl_elem_value_t * uctl)
+                           snd_ctl_elem_value_t * uctl)
 {
        cs4231_t *chip = snd_kcontrol_chip(kctl);
        snd_card_t *card = chip->card;
@@ -777,9 +808,9 @@
        for (cfg = 0; cfg < ARRAY_SIZE(valid_irq); ++cfg) {
                if (irq == valid_irq[cfg])
                        return cfg;
-       }                       /* for */
+       } /* for */
 
-       return 0xff;
+       return INVALID_IRQ;
 }
 
 
@@ -831,7 +862,7 @@
         */
        retval = 1;
 
-      _done:
+       _done:
        spin_unlock_irqrestore(&s->lock, flags);
        return retval;
 }
@@ -889,10 +920,10 @@
 
 #define MPU401_SHARE_HARDWARE  1
        if ((err = snd_mpu401_uart_new(card, devnum,
-                                      MPU401_HW_MPU401,
-                                      port, MPU401_SHARE_HARDWARE,
-                                      irq, SA_INTERRUPT,
-                                      &rawmidi)) == 0) {
+                                      MPU401_HW_MPU401,
+                                      port, MPU401_SHARE_HARDWARE,
+                                      irq, SA_INTERRUPT,
+                                      &rawmidi)) == 0) {
                mpu401_t *mpu = (mpu401_t *) rawmidi->private_data;
                mpu->open_input = mpu401_open;
                mpu->open_output = mpu401_open;
@@ -1061,54 +1092,100 @@
                strcpy(card->driver, "SoundScape");
                strcpy(card->shortname, pcm->name);
                snprintf(card->longname, sizeof(card->longname),
-                        "%s at 0x%lx, IRQ %d, DMA %d\n",
-                        pcm->name, chip->port, chip->irq, chip->dma1);
+                        "%s at 0x%lx, IRQ %d, DMA %d\n",
+                        pcm->name, chip->port, chip->irq, chip->dma1);
                chip->set_playback_format = ad1845_playback_format;
                chip->set_capture_format = ad1845_capture_format;
                sscape->chip = chip;
        }
 
-      _error:
+       _error:
        return err;
 }
 
+
+struct params
+{
+       int index;
+       const char *id;
+       unsigned port;
+       int irq;
+       int mpu_irq;
+       int dma1;
+
+#ifdef __ISAPNP__
+       struct isapnp_dev *isapnp;
+#endif
+};
+
+
+static inline struct params*
+init_params(struct params *params,
+            int index,
+            const char *id,
+            unsigned port,
+            int irq,
+            int mpu_irq,
+            int dma1,
+            struct isapnp_dev *isapnp)
+{
+       params->index = index;
+       params->id = id;
+       params->port = port;
+       params->irq = irq;
+       params->mpu_irq = mpu_irq;  
+       params->dma1 = (dma1 & 0x03);
+
+#ifdef __ISAPNP__
+       params->isapnp = isapnp;
+#endif
+
+ return params;
+}
+
+
 /*
  * Create an ALSA soundcard entry for the SoundScape, using
  * the given list of port, IRQ and DMA resources.
  */
-static int __init create_sscape(unsigned port, int irq, int mpu_irq, int dma1, int 
dma2)
+static int __init create_sscape(const struct params *params)
 {
        snd_card_t *card;
        register struct soundscape *sscape;
-       register unsigned mpu_irq_cfg;
        register unsigned dma_cfg;
+       unsigned irq_cfg;
+       unsigned mpu_irq_cfg;
        struct resource *io_res;
        unsigned long flags;
        int err;
 
        /*
-        * Check that the driver can handle one more card ...
+        * Check that the user didn't pass us garbage data ...
         */
-       if (sscape_count >= ARRAY_SIZE(sscape_card)) {
-               printk(KERN_ERR "sscape: Maximum number of cards reached (%d)\n", 
sscape_count);
-               return -EBUSY;
+       irq_cfg = get_irq_config(params->irq);
+       if (irq_cfg == INVALID_IRQ) {
+               printk(KERN_ERR "sscape: Invalid IRQ %d\n", params->irq);
+               return -ENXIO;
+       }
+
+       mpu_irq_cfg = get_irq_config(params->mpu_irq);
+       if (mpu_irq_cfg == INVALID_IRQ) {
+               printk(KERN_ERR "sscape: Invalid IRQ %d\n", params->mpu_irq);
+               return -ENXIO;
        }
 
        /*
         * Grab IO ports that we will need to probe so that we
         * can detect and control this hardware ...
         */
-       if ((io_res = request_region(port, 8, "SoundScape")) == NULL) {
+       if ((io_res = request_region(params->port, 8, "SoundScape")) == NULL) {
                return -EBUSY;
        }
 
-       dma1 &= 0x03;
-       dma2 &= 0x03;
-
        /*
-        * Grab both DMA channels ...
+        * Grab both DMA channels (OK, only one for now) ...
         */
-       if ((err = request_dma(dma1, "SoundScape")) < 0) {
+       if ((err = request_dma(params->dma1, "SoundScape")) < 0) {
                goto _release_region;
        }
 
@@ -1116,7 +1193,7 @@
         * Create a new ALSA sound card entry, in anticipation
         * of detecting our hardware ...
         */
-       if ((card = snd_card_new(index[sscape_count], "SoundScape", THIS_MODULE, 
sizeof(struct soundscape))) == NULL) {
+       if ((card = snd_card_new(params->index, params->id, THIS_MODULE, sizeof(struct 
+soundscape))) == NULL) {
                err = -ENOMEM;
                goto _release_dma;
        }
@@ -1125,21 +1202,21 @@
        spin_lock_init(&sscape->lock);
        spin_lock_init(&sscape->fwlock);
        sscape->io_res = io_res;
-       sscape->io_base = port;
+       sscape->io_base = params->port;
 
        if (!detect_sscape(sscape)) {
-               printk(KERN_ERR "sscape: hardware not detected\n");
+               printk(KERN_ERR "sscape: hardware not detected at 0x%x\n", 
+sscape->io_base);
                err = -ENODEV;
                goto _release_card;
        }
 
-       printk(KERN_INFO "sscape: hardware detected at 0x%x, using IRQ %d, DMA 
%d,%d\n",
-              sscape->io_base, irq, dma1, dma2);
+       printk(KERN_INFO "sscape: hardware detected at 0x%x, using IRQ %d, DMA %d\n",
+                        sscape->io_base, params->irq, params->dma1);
 
        /*
         * Now create the hardware-specific device so that we can
         * load the microcode into the on-board processor.
-        * We cannot detect the AD1845 system until this firmware
+        * We cannot use the MPU-401 MIDI system until this firmware
         * has been loaded into the card.
         */
        if ((err = snd_hwdep_new(card, "MC68EC000", 0, &(sscape->hw))) < 0) {
@@ -1162,7 +1239,7 @@
 
        activate_ad1845_unsafe(sscape->io_base);
 
-       sscape_write_unsafe(sscape->io_base, GA_INTENA_REG, 0x00);      /* disable */
+       sscape_write_unsafe(sscape->io_base, GA_INTENA_REG, 0x00); /* disable */
        sscape_write_unsafe(sscape->io_base, GA_SMCFGA_REG, 0x2e);
        sscape_write_unsafe(sscape->io_base, GA_SMCFGB_REG, 0x00);
 
@@ -1174,9 +1251,10 @@
        sscape_write_unsafe(sscape->io_base, GA_DMAA_REG, dma_cfg);
        sscape_write_unsafe(sscape->io_base, GA_DMAB_REG, 0x20);
 
-       mpu_irq_cfg = get_irq_config(mpu_irq);
-       sscape_write_unsafe(sscape->io_base, GA_INTCFG_REG, 0xf0 | (mpu_irq_cfg << 2) 
| mpu_irq_cfg);
-       sscape_write_unsafe(sscape->io_base, GA_CDCFG_REG, 0x09 | DMA_8BIT | (dma1 << 
4) | (get_irq_config(irq) << 1));
+       sscape_write_unsafe(sscape->io_base,
+                           GA_INTCFG_REG, 0xf0 | (mpu_irq_cfg << 2) | mpu_irq_cfg);
+       sscape_write_unsafe(sscape->io_base,
+                           GA_CDCFG_REG, 0x09 | DMA_8BIT | (params->dma1 << 4) | 
+(irq_cfg << 1));
 
        spin_unlock_irqrestore(&sscape->lock, flags);
 
@@ -1184,13 +1262,15 @@
         * We have now enabled the codec chip, and so we should
         * detect the AD1845 device ...
         */
-       if ((err = create_ad1845(card, CODEC_IO(port), irq, dma1)) < 0) {
-               printk(KERN_ERR "sscape: No AD1845 device at 0x%x, IRQ %d\n", 
CODEC_IO(port), irq);
+       if ((err = create_ad1845(card, CODEC_IO(params->port), params->irq, 
+params->dma1)) < 0) {
+               printk(KERN_ERR "sscape: No AD1845 device at 0x%x, IRQ %d\n",
+                               CODEC_IO(params->port), params->irq);
                goto _release_card;
        }
 #define MIDI_DEVNUM  0
-       if ((err = create_mpu401(card, MIDI_DEVNUM, MPU401_IO(port), mpu_irq)) < 0) {
-               printk(KERN_ERR "sscape: Failed to create MPU-401 device at 0x%x\n", 
port);
+       if ((err = create_mpu401(card, MIDI_DEVNUM, MPU401_IO(params->port), 
+params->mpu_irq)) < 0) {
+               printk(KERN_ERR "sscape: Failed to create MPU-401 device at 0x%x\n",
+                               MPU401_IO(params->port));
                goto _release_card;
        }
 
@@ -1212,6 +1292,9 @@
        host_write_ctrl_unsafe(sscape->io_base, 0, 100);
        host_write_ctrl_unsafe(sscape->io_base, CMD_XXX_MIDI_VOL, 100);
 
+#ifdef __ISAPNP__
+       sscape->isapnp = params->isapnp;
+#endif
 
        /*
         * Now that we have successfully created this sound card,
@@ -1220,18 +1303,17 @@
         *       function now that our "constructor" has completed.
         */
        card->private_free = soundscape_free;
-       sscape_card[sscape_count] = card;
-       ++sscape_count;
+       sscape_card[card->number] = card;
 
        return 0;
 
-      _release_card:
+       _release_card:
        snd_card_free(card);
 
-      _release_dma:
-       free_dma(dma1);
+       _release_dma:
+       free_dma(params->dma1);
 
-      _release_region:
+       _release_region:
        release_resource(io_res);
        kfree_nocheck(io_res);
 
@@ -1239,11 +1321,51 @@
 }
 
 
-#ifdef MODULE
-static int __init sscape_module_probe(struct isapnp_card *card, const struct 
isapnp_card_id *id)
+#ifdef __ISAPNP__
+struct isapnp_data
 {
+       struct params *params;
+       unsigned cards;
+       unsigned idx;
+};
+
+static void* __initdata hackptr;
+
+
+static inline int __init get_next_autoindex(int i)
+{
+       while ((i < SNDRV_CARDS) && (port[i] != SNDRV_AUTO_PORT)) {
+               ++i;
+       } /* while */
+
+       return i;
+}
+
+
+static inline int __init is_port_known(unsigned io, struct params *params, int cards)
+{
+       while (--cards >= 0) {
+               if (params[cards].port == io)
+                       return 1;
+       } /* while */
+
+       return 0;
+}
+
+
+static int __init sscape_isapnp_card(struct isapnp_card *card, const struct 
+isapnp_card_id *pnpid)
+{
+       struct isapnp_data *data = hackptr;
        struct isapnp_dev *dev;
-       int ret = -ENODEV;
+       int ret;
+
+       /*
+        * Allow this function to fail *quietly* if all the ISA PnP
+        * devices were configured using module parameters instead.
+        */
+       if ((data->idx = get_next_autoindex(data->idx)) >= SNDRV_CARDS) {
+               return -ENOSPC;
+       }
 
        /*
         * We have found a candidate ISA PnP card. Now we
@@ -1262,19 +1384,43 @@
         */
        printk(KERN_INFO "sscape: %s\n", card->name);
 
-       dev = isapnp_find_dev(card, id->devs[0].vendor, id->devs[0].function, NULL);
+       /*
+        * Check that we still have room for another sound card ...
+        */
+       if (data->cards >= SNDRV_CARDS) {
+               printk(KERN_ERR "sscape: No room for another ALSA device\n");
+               return -ENOSPC;
+       }
+
+       ret = -ENODEV;
+
+       dev = isapnp_find_dev(card, pnpid->devs[0].vendor, pnpid->devs[0].function, 
+NULL);
        if (dev) {
                if (!dev->active) {
                        printk(KERN_INFO "sscape: device is inactive\n");
                } else {
+                       struct params *this;
+
                        /*
-                        * Use these resources to create a new instance of the sound 
driver
+                        * Read the correct parameters off the ISA PnP bus ...
                         */
-                       ret = create_sscape(dev->resource[0].start,
-                                           dev->irq_resource[0].start,
-                                           dev->irq_resource[1].start,
-                                           dev->dma_resource[0].start,
-                                           dev->dma_resource[1].start);
+                       this = init_params(&data->params[data->cards],
+                                          index[data->idx],
+                                          id[data->idx],
+                                          dev->resource[0].start,
+                                          dev->irq_resource[0].start,
+                                          dev->irq_resource[1].start,
+                                          dev->dma_resource[0].start,
+                                          dev);
+
+                       /*
+                        * Do we know about this sound card already?
+                        */
+                       if ( !is_port_known(this->port, data->params, data->cards) ) {
+                               ++(data->cards);
+                         ++(data->idx);
+                               ret = 0;
+                       }
                }
        }
 
@@ -1282,28 +1428,145 @@
 }
 
 
-static int __init sscape_init(void)
+static int __init sscape_isapnp_probe(struct params *sscape_params, int cards)
 {
-       int cards = isapnp_probe_cards(sscape_pnpids, sscape_module_probe);
-       if (cards > 0)
-               return 0;
-       if (!cards)
-               return -ENODEV;
+       struct isapnp_data  probe_data;
+
+       probe_data.params = sscape_params;
+       probe_data.cards = cards;
+       probe_data.idx = 0;
+
+       /*
+        * This is the best way to pass data into the ISA-PnP
+        * callback function. We have NO CHOICE but to use a
+        * global variable (Ewwwwwww!) ...
+        */
+       hackptr = &probe_data;
+       return isapnp_probe_cards(sscape_pnpids, sscape_isapnp_card);
+}
+#endif
+
+
+static int __init sscape_manual_probe(struct params *params)
+{
+       int cards = 0;
+       unsigned i;
+
+       for (i = 0; i < SNDRV_CARDS; ++i) {
+               /*
+                * We do NOT probe for ports.
+                * If we're not given a port number for this
+                * card then we completely ignore this line
+                * of parameters.
+                */
+               if (port[i] == SNDRV_AUTO_PORT)
+                       continue;
+
+               /*
+                * Make sure we were given ALL of the other parameters.
+                */
+               if ( (irq[i] == SNDRV_AUTO_IRQ) ||
+                    (mpu_irq[i] == SNDRV_AUTO_IRQ) ||
+                    (dma[i] == SNDRV_AUTO_DMA) ) {
+                       printk(KERN_INFO
+                              "sscape: insufficient parameters, need IO, IRQ, MPU-IRQ 
+and DMA\n");
+                       return -ENXIO;
+               }
+
+               /*
+                * This cards looks OK ...
+                */
+               init_params(params, index[i], id[i], port[i], irq[i], mpu_irq[i], 
+dma[i], NULL);
+               ++params;
+               ++cards;
+       } /* for */
+
        return cards;
 }
 
+
 static void __exit sscape_exit(void)
 {
-       unsigned i = 0;
+       unsigned i;
 
-       while ((i < ARRAY_SIZE(sscape_card)) && sscape_card[i]) {
+       for (i = 0; i < ARRAY_SIZE(sscape_card); ++i) {
                snd_card_free(sscape_card[i]);
-               ++i;
-       } /* while */
+       } /* for */
+}
+
+
+static int __init sscape_init(void)
+{
+       struct params sscape_params[ARRAY_SIZE(sscape_card)];
+       int cards;
+       int ret;
+       int i;
+
+       /*
+        * First check whether we were passed any parameters.
+        * These MUST take precedence over ANY automatic way
+        * of allocating cards, because the operator is
+        * S-P-E-L-L-I-N-G it out for us...
+        */
+       cards = sscape_manual_probe(sscape_params);
+       if (cards < 0)
+               return cards;
+
+#ifdef __ISAPNP__
+       if (cards < SNDRV_CARDS)
+               cards += sscape_isapnp_probe(sscape_params, cards);
+#endif
+
+       /*
+        * Now try to attach drivers for any cards we've found ...
+        */ 
+       ret = -ENODEV;
+
+       for (i = 0; i < cards; ++i) {
+               ret = create_sscape(&sscape_params[i]);
+
+               /*
+                * Did we create this SoundScape driver successfully?
+                */
+               if (ret != 0) {
+                       /*
+                        * Linux will NOT clean up automatically if the
+                        * module_init function fails ...
+                        */
+                       sscape_exit();
+                       break;
+               }
+       } /* for */
+
+       return ret;
 }
 
 module_init(sscape_init);
 module_exit(sscape_exit);
-#else
-#  error This driver can currently only be compiled as a module
+
+#ifndef MODULE
+
+/* format is: snd-sscape=index,id,port,irq,mpu_irq,dma */
+
+static int __init builtin_sscape_setup(char *str)
+{
+       static unsigned __initdata nr_dev;
+
+       if (nr_dev >= SNDRV_CARDS)
+               return 0;
+
+       (void)((get_option(&str, &index[nr_dev]) == 2) &&
+              (get_option(&str, (int*)&id[nr_dev]) == 2) &&
+              (get_option(&str, (int*)&port[nr_dev]) == 2) &&
+              (get_option(&str, &irq[nr_dev]) == 2) &&
+              (get_option(&str, &mpu_irq[nr_dev]) == 2) &&
+              (get_option(&str, &dma[nr_dev]) == 2)); 
+ 
+       ++nr_dev;
+       return 1;
+}
+
+__setup("snd-sscape=", builtin_sscape_setup);
+
 #endif
+



-------------------------------------------------------
This sf.net emial is sponsored by: Influence the future of 
Java(TM) technology. Join the Java Community Process(SM) (JCP(SM)) 
program now. http://ad.doubleclick.net/clk;4699841;7576301;v?
http://www.sun.com/javavote
_______________________________________________
Alsa-cvslog mailing list
[EMAIL PROTECTED]
https://lists.sourceforge.net/lists/listinfo/alsa-cvslog

Reply via email to