Commit 035c7f48 authored by Jaroslav Kysela's avatar Jaroslav Kysela

Merge suse.cz:/home/perex/bk/linux-sound/linux-2.5

into suse.cz:/home/perex/bk/linux-sound/linux-sound
parents b5939deb 5500d6fa
...@@ -53,14 +53,9 @@ Module parameters ...@@ -53,14 +53,9 @@ Module parameters
for soundcards which are not installed in your system for soundcards which are not installed in your system
device_mode device_mode
- specifies permission mask for dynamic sound device filesystem - specifies permission mask for dynamic sound device filesystem
(available only when DEVFS is enabled)
- default value = 0666 - default value = 0666
- for example 'device_mode=0660' - for example 'device_mode=0660'
device_gid
- specifies GID number for dynamic sound device filesystem
- default value = 0 (root)
device_uid
- specifies UID number for dynamic sound device filesystem
- default value = 0 (root)
Module snd-pcm-oss Module snd-pcm-oss
...@@ -144,6 +139,7 @@ Module parameters ...@@ -144,6 +139,7 @@ Module parameters
Module for ALi M5451 PCI chip. Module for ALi M5451 PCI chip.
pcm_channels - Number of hardware channels assigned for PCM pcm_channels - Number of hardware channels assigned for PCM
spdif - Support SPDIF I/O (disabled by default)
Module supports autoprobe and multiple chips (max 8). Module supports autoprobe and multiple chips (max 8).
...@@ -846,6 +842,20 @@ Module parameters ...@@ -846,6 +842,20 @@ Module parameters
Module supports up to 8 cards. Module supports up to 8 cards.
Module snd-sscape
-----------------
Module for ENSONIQ SoundScape PnP cards.
port - Port # (PnP setup)
irq - IRQ # (PnP setup)
mpu_irq - MPU-401 IRQ # (PnP setup)
dma - DMA # (PnP setup)
Module supports up to 8 cards. ISA PnP must be enabled.
You need sscape_ctl tool in alsa-tools package for loading
the microcode.
Module snd-sun-amd7930 (on sparc only) Module snd-sun-amd7930 (on sparc only)
-------------------------------------- --------------------------------------
...@@ -945,19 +955,34 @@ Module parameters ...@@ -945,19 +955,34 @@ Module parameters
Module snd-via82xx Module snd-via82xx
------------------ ------------------
Module for AC'97 motherboards based on VIA 82C686A/686B, 8233 Module for AC'97 motherboards based on VIA 82C686A/686B, 8233,
(south) bridge. 8233A, 8233C, 8235 (south) bridge.
mpu_port - 0x300,0x310,0x320,0x330, otherwise obtain BIOS setup mpu_port - 0x300,0x310,0x320,0x330, otherwise obtain BIOS setup
[VIA686A/686B only]
ac97_clock - AC'97 codec clock base (default 48000Hz) ac97_clock - AC'97 codec clock base (default 48000Hz)
dxs_support - support DXS channels,
0 = auto (default), 1 = enable, 2 = disable,
3 = 48k only
[VIA8233/C,8235 only]
Module supports autoprobe and multiple bus-master chips (max 8). Module supports autoprobe and multiple bus-master chips (max 8).
Note: on some SMP motherboards like MSI 694D the interrupts might Note: on some SMP motherboards like MSI 694D the interrupts might
not be generated properly. In such a case, please try to not be generated properly. In such a case, please try to
set the SMP (or MPS) version on BIOS to 1.1 instead of set the SMP (or MPS) version on BIOS to 1.1 instead of
default value 1.4. Then the interrupt number will be default value 1.4. Then the interrupt number will be
assigned under 15. You might also upgrade your BIOS. assigned under 15. You might also upgrade your BIOS.
Note: VIA8233/5 (not VIA8233A) can support DXS (direct sound)
channels as the first PCM. With this device, up to 4
streams can be played at the same time. If the playback on
this PCM is noisy, try to specify dxs_channels option to 2
or 3.
Note: for the MPU401 on VIA823x, use snd-mpu401 driver
additonally.
Module snd-virmidi Module snd-virmidi
------------------ ------------------
......
...@@ -115,8 +115,7 @@ or ...@@ -115,8 +115,7 @@ or
% aplay -Dspdif foo.wav % aplay -Dspdif foo.wav
So far, only S16LE format is supported. Still no 24bit. Sorry, not 24bit format is also supported experimentally.
enough info for this.
The playback and capture over SPDIF use normal DAC and ADC, The playback and capture over SPDIF use normal DAC and ADC,
respectively, so you cannot playback both analog and digital streams respectively, so you cannot playback both analog and digital streams
......
...@@ -1538,11 +1538,12 @@ ...@@ -1538,11 +1538,12 @@
<informalexample> <informalexample>
<programlisting> <programlisting>
<![CDATA[ <![CDATA[
static void snd_mychip_interrupt(int irq, void *dev_id, static irqreturn_t snd_mychip_interrupt(int irq, void *dev_id,
struct pt_regs *regs) struct pt_regs *regs)
{ {
mychip_t *chip = snd_magic_cast(mychip_t, dev_id, return); mychip_t *chip = snd_magic_cast(mychip_t, dev_id, return);
.... ....
return IRQ_HANDLED;
} }
]]> ]]>
</programlisting> </programlisting>
...@@ -3149,8 +3150,8 @@ struct _snd_pcm_runtime { ...@@ -3149,8 +3150,8 @@ struct _snd_pcm_runtime {
<title>Interrupt Handler Case #1</title> <title>Interrupt Handler Case #1</title>
<programlisting> <programlisting>
<![CDATA[ <![CDATA[
static void snd_mychip_interrupt(int irq, void *dev_id, static irqreturn_t snd_mychip_interrupt(int irq, void *dev_id,
struct pt_regs *regs) struct pt_regs *regs)
{ {
mychip_t *chip = snd_magic_cast(mychip_t, dev_id, return); mychip_t *chip = snd_magic_cast(mychip_t, dev_id, return);
spin_lock(&chip->lock); spin_lock(&chip->lock);
...@@ -3160,9 +3161,11 @@ struct _snd_pcm_runtime { ...@@ -3160,9 +3161,11 @@ struct _snd_pcm_runtime {
spin_unlock(&chip->lock); spin_unlock(&chip->lock);
snd_pcm_period_elapsed(chip->substream); snd_pcm_period_elapsed(chip->substream);
spin_lock(&chip->lock); spin_lock(&chip->lock);
// acknowledge the interrupt if necessary
} }
.... ....
spin_unlock(&chip->lock); spin_unlock(&chip->lock);
return IRQ_HANDLED;
} }
]]> ]]>
</programlisting> </programlisting>
...@@ -3191,8 +3194,8 @@ struct _snd_pcm_runtime { ...@@ -3191,8 +3194,8 @@ struct _snd_pcm_runtime {
<title>Interrupt Handler Case #2</title> <title>Interrupt Handler Case #2</title>
<programlisting> <programlisting>
<![CDATA[ <![CDATA[
static void snd_mychip_interrupt(int irq, void *dev_id, static irqreturn_t snd_mychip_interrupt(int irq, void *dev_id,
struct pt_regs *regs) struct pt_regs *regs)
{ {
mychip_t *chip = snd_magic_cast(mychip_t, dev_id, return); mychip_t *chip = snd_magic_cast(mychip_t, dev_id, return);
spin_lock(&chip->lock); spin_lock(&chip->lock);
...@@ -3221,9 +3224,11 @@ struct _snd_pcm_runtime { ...@@ -3221,9 +3224,11 @@ struct _snd_pcm_runtime {
snd_pcm_period_elapsed(substream); snd_pcm_period_elapsed(substream);
spin_lock(&chip->lock); spin_lock(&chip->lock);
} }
// acknowledge the interrupt if necessary
} }
.... ....
spin_unlock(&chip->lock); spin_unlock(&chip->lock);
return IRQ_HANDLED;
} }
]]> ]]>
</programlisting> </programlisting>
......
...@@ -249,7 +249,7 @@ control. In fact, the controls with "XXX [Playback|Capture] ...@@ -249,7 +249,7 @@ control. In fact, the controls with "XXX [Playback|Capture]
[Volume|Switch]" will be checked in addition. [Volume|Switch]" will be checked in addition.
The current assignment of these mixer elements is listed in the proc The current assignment of these mixer elements is listed in the proc
file, /proc/asound/cardX/mixer_oss, which will be like the following file, /proc/asound/cardX/oss_mixer, which will be like the following
VOLUME "Master" 0 VOLUME "Master" 0
BASS "" 0 BASS "" 0
...@@ -267,7 +267,7 @@ For changing the assignment, you can write the configuration to this ...@@ -267,7 +267,7 @@ For changing the assignment, you can write the configuration to this
proc file. For example, to map "Wave Playback" to the PCM volume, proc file. For example, to map "Wave Playback" to the PCM volume,
send the command like the following: send the command like the following:
% echo 'VOLUME "Wave Playback" 0' > /proc/asound/card0/mixer_oss % echo 'VOLUME "Wave Playback" 0' > /proc/asound/card0/oss_mixer
The command is exactly as same as listed in the proc file. You can The command is exactly as same as listed in the proc file. You can
change one or more elements, one volume per line. In the last change one or more elements, one volume per line. In the last
......
...@@ -293,6 +293,7 @@ struct _snd_ac97 { ...@@ -293,6 +293,7 @@ struct _snd_ac97 {
unsigned short codec_cfg[3]; // CODEC_CFG bits unsigned short codec_cfg[3]; // CODEC_CFG bits
struct semaphore mutex; struct semaphore mutex;
} ad18xx; } ad18xx;
unsigned int dev_flags; /* device specific */
} spec; } spec;
}; };
...@@ -329,7 +330,7 @@ void snd_ac97_suspend(ac97_t *ac97); ...@@ -329,7 +330,7 @@ void snd_ac97_suspend(ac97_t *ac97);
void snd_ac97_resume(ac97_t *ac97); void snd_ac97_resume(ac97_t *ac97);
#endif #endif
enum { AC97_TUNE_HP_ONLY, AC97_TUNE_SWAP_HP }; enum { AC97_TUNE_HP_ONLY, AC97_TUNE_SWAP_HP, AC97_TUNE_SWAP_SURROUND };
struct ac97_quirk { struct ac97_quirk {
unsigned short vendor; unsigned short vendor;
......
#ifndef __SOUND_AK4XXX_ADDA_H
#define __SOUND_AK4XXX_ADDA_H
/*
* ALSA driver for AK4524 / AK4528 / AK4529 / AK4355 / AK4381
* AD and DA converters
*
* Copyright (c) 2000 Jaroslav Kysela <perex@suse.cz>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
*/
#ifndef AK4XXX_MAX_CHIPS
#define AK4XXX_MAX_CHIPS 4
#endif
typedef struct snd_akm4xxx akm4xxx_t;
struct snd_ak4xxx_ops {
void (*lock)(akm4xxx_t *ak, int chip);
void (*unlock)(akm4xxx_t *ak, int chip);
void (*write)(akm4xxx_t *ak, int chip, unsigned char reg, unsigned char val);
// unsigned char (*read)(akm4xxx_t *ak, int chip, unsigned char reg);
void (*set_rate_val)(akm4xxx_t *ak, unsigned int rate);
};
struct snd_akm4xxx {
snd_card_t *card;
unsigned int num_adcs; /* AK4524 or AK4528 ADCs */
unsigned int num_dacs; /* AK4524 or AK4528 DACs */
unsigned char images[AK4XXX_MAX_CHIPS][16]; /* saved register image */
unsigned char ipga_gain[AK4XXX_MAX_CHIPS][2]; /* saved register image for IPGA (AK4528) */
unsigned long private_value[AK4XXX_MAX_CHIPS]; /* helper for driver */
void *private_data[AK4XXX_MAX_CHIPS]; /* helper for driver */
/* template should fill the following fields */
unsigned int idx_offset; /* control index offset */
enum {
SND_AK4524, SND_AK4528, SND_AK4529, SND_AK4355, SND_AK4381
} type;
struct snd_ak4xxx_ops ops;
};
void snd_akm4xxx_write(akm4xxx_t *ak, int chip, unsigned char reg, unsigned char val);
void snd_akm4xxx_reset(akm4xxx_t *ak, int state);
void snd_akm4xxx_init(akm4xxx_t *ak);
int snd_akm4xxx_build_controls(akm4xxx_t *ak);
#endif /* __SOUND_AK4XXX_ADDA_H */
...@@ -596,7 +596,7 @@ struct sndrv_seq_remove_events { ...@@ -596,7 +596,7 @@ struct sndrv_seq_remove_events {
#define SNDRV_SEQ_PORT_TYPE_MIDI_MT32 (1<<5) /* MT-32 compatible device */ #define SNDRV_SEQ_PORT_TYPE_MIDI_MT32 (1<<5) /* MT-32 compatible device */
/* other standards...*/ /* other standards...*/
#define SNDRV_SEQ_PORT_TYPE_SYNTH (1<<10) /* Synth device */ #define SNDRV_SEQ_PORT_TYPE_SYNTH (1<<10) /* Synth device (no MIDI compatible - direct wavetable) */
#define SNDRV_SEQ_PORT_TYPE_DIRECT_SAMPLE (1<<11) /* Sampling device (support sample download) */ #define SNDRV_SEQ_PORT_TYPE_DIRECT_SAMPLE (1<<11) /* Sampling device (support sample download) */
#define SNDRV_SEQ_PORT_TYPE_SAMPLE (1<<12) /* Sampling device (sample can be downloaded at any time) */ #define SNDRV_SEQ_PORT_TYPE_SAMPLE (1<<12) /* Sampling device (sample can be downloaded at any time) */
/*...*/ /*...*/
......
...@@ -184,7 +184,7 @@ static inline void snd_power_unlock(snd_card_t *card) ...@@ -184,7 +184,7 @@ static inline void snd_power_unlock(snd_card_t *card)
up(&card->power_lock); up(&card->power_lock);
} }
void snd_power_wait(snd_card_t *card); int snd_power_wait(snd_card_t *card, unsigned int power_state, struct file *file);
static inline unsigned int snd_power_get_state(snd_card_t *card) static inline unsigned int snd_power_get_state(snd_card_t *card)
{ {
...@@ -199,7 +199,7 @@ static inline void snd_power_change_state(snd_card_t *card, unsigned int state) ...@@ -199,7 +199,7 @@ static inline void snd_power_change_state(snd_card_t *card, unsigned int state)
#else #else
#define snd_power_lock(card) do { (void)(card); } while (0) #define snd_power_lock(card) do { (void)(card); } while (0)
#define snd_power_unlock(card) do { (void)(card); } while (0) #define snd_power_unlock(card) do { (void)(card); } while (0)
#define snd_power_wait(card) do { (void)(card); } while (0) static inline int snd_power_wait(snd_card_t *card, unsigned int state, struct file *file) { return 0; }
#define snd_power_get_state(card) SNDRV_CTL_POWER_D0 #define snd_power_get_state(card) SNDRV_CTL_POWER_D0
#define snd_power_change_state(card, state) do { (void)(card); } while (0) #define snd_power_change_state(card, state) do { (void)(card); } while (0)
#endif #endif
...@@ -211,8 +211,8 @@ struct _snd_minor { ...@@ -211,8 +211,8 @@ struct _snd_minor {
int number; /* minor number */ int number; /* minor number */
int device; /* device number */ int device; /* device number */
const char *comment; /* for /proc/asound/devices */ const char *comment; /* for /proc/asound/devices */
snd_info_entry_t *dev; /* for /proc/asound/dev */
struct file_operations *f_ops; /* file operations */ struct file_operations *f_ops; /* file operations */
char name[0]; /* device name (keep at the end of structure) */
}; };
typedef struct _snd_minor snd_minor_t; typedef struct _snd_minor snd_minor_t;
...@@ -240,12 +240,13 @@ int snd_minor_info_done(void); ...@@ -240,12 +240,13 @@ int snd_minor_info_done(void);
/* sound_oss.c */ /* sound_oss.c */
#ifdef CONFIG_SND_OSSEMUL #ifdef CONFIG_SND_OSSEMUL
int snd_minor_info_oss_init(void); int snd_minor_info_oss_init(void);
int snd_minor_info_oss_done(void); int snd_minor_info_oss_done(void);
int snd_oss_init_module(void); int snd_oss_init_module(void);
#else
#define snd_minor_info_oss_init() /*NOP*/
#define snd_minor_info_oss_done() /*NOP*/
#define snd_oss_init_module() /*NOP*/
#endif #endif
/* memory.c */ /* memory.c */
...@@ -268,6 +269,10 @@ void snd_hidden_vfree(void *obj); ...@@ -268,6 +269,10 @@ void snd_hidden_vfree(void *obj);
#define kfree_nocheck(obj) snd_wrapper_kfree(obj) #define kfree_nocheck(obj) snd_wrapper_kfree(obj)
#define vfree_nocheck(obj) snd_wrapper_vfree(obj) #define vfree_nocheck(obj) snd_wrapper_vfree(obj)
#else #else
#define snd_memory_init() /*NOP*/
#define snd_memory_done() /*NOP*/
#define snd_memory_info_init() /*NOP*/
#define snd_memory_info_done() /*NOP*/
#define kmalloc_nocheck(size, flags) kmalloc(size, flags) #define kmalloc_nocheck(size, flags) kmalloc(size, flags)
#define vmalloc_nocheck(size) vmalloc(size) #define vmalloc_nocheck(size) vmalloc(size)
#define kfree_nocheck(obj) kfree(obj) #define kfree_nocheck(obj) kfree(obj)
......
...@@ -48,7 +48,7 @@ ...@@ -48,7 +48,7 @@
#define CS8427_REG_UDATABUF 0x13 #define CS8427_REG_UDATABUF 0x13
#define CS8427_REG_QSUBCODE 0x14 /* 0x14-0x1d (10 bytes) */ #define CS8427_REG_QSUBCODE 0x14 /* 0x14-0x1d (10 bytes) */
#define CS8427_REG_OMCKRMCKRATIO 0x1e #define CS8427_REG_OMCKRMCKRATIO 0x1e
#define CS8427_REG_CORU_DATABUF 0x20 #define CS8427_REG_CORU_DATABUF 0x20 /* 24 byte buffer area */
#define CS8427_REG_ID_AND_VER 0x7f #define CS8427_REG_ID_AND_VER 0x7f
/* CS8427_REG_CONTROL1 bits */ /* CS8427_REG_CONTROL1 bits */
...@@ -188,6 +188,7 @@ ...@@ -188,6 +188,7 @@
int snd_cs8427_detect(snd_i2c_bus_t *bus, unsigned char addr); int snd_cs8427_detect(snd_i2c_bus_t *bus, unsigned char addr);
int snd_cs8427_create(snd_i2c_bus_t *bus, unsigned char addr, snd_i2c_device_t **r_cs8427); int snd_cs8427_create(snd_i2c_bus_t *bus, unsigned char addr, snd_i2c_device_t **r_cs8427);
void snd_cs8427_reset(snd_i2c_device_t *cs8427);
int snd_cs8427_iec958_build(snd_i2c_device_t *cs8427, snd_pcm_substream_t *playback_substream, snd_pcm_substream_t *capture_substream); int snd_cs8427_iec958_build(snd_i2c_device_t *cs8427, snd_pcm_substream_t *playback_substream, snd_pcm_substream_t *capture_substream);
int snd_cs8427_iec958_active(snd_i2c_device_t *cs8427, int active); int snd_cs8427_iec958_active(snd_i2c_device_t *cs8427, int active);
int snd_cs8427_iec958_pcm(snd_i2c_device_t *cs8427, unsigned int rate); int snd_cs8427_iec958_pcm(snd_i2c_device_t *cs8427, unsigned int rate);
......
...@@ -69,20 +69,15 @@ struct snd_info_entry_ops { ...@@ -69,20 +69,15 @@ struct snd_info_entry_ops {
struct vm_area_struct * vma); struct vm_area_struct * vma);
}; };
struct snd_info_entry_device {
unsigned short major;
unsigned short minor;
};
struct snd_info_entry { struct snd_info_entry {
const char *name; const char *name;
mode_t mode; mode_t mode;
long size; long size;
unsigned short content; unsigned short content;
unsigned short disconnected: 1;
union { union {
struct snd_info_entry_text text; struct snd_info_entry_text text;
struct snd_info_entry_ops *ops; struct snd_info_entry_ops *ops;
struct snd_info_entry_device device;
} c; } c;
snd_info_entry_t *parent; snd_info_entry_t *parent;
snd_card_t *card; snd_card_t *card;
......
...@@ -53,7 +53,7 @@ static const char __module_generic_string_##name [] \ ...@@ -53,7 +53,7 @@ static const char __module_generic_string_##name [] \
#define SNDRV_DEFAULT_STR { [0 ... (SNDRV_CARDS-1)] = NULL } #define SNDRV_DEFAULT_STR { [0 ... (SNDRV_CARDS-1)] = NULL }
#define SNDRV_DEFAULT_ENABLE { 1, [1 ... (SNDRV_CARDS-1)] = 0 } #define SNDRV_DEFAULT_ENABLE { 1, [1 ... (SNDRV_CARDS-1)] = 0 }
#define SNDRV_DEFAULT_ENABLE_PNP { [0 ... (SNDRV_CARDS-1)] = 1 } #define SNDRV_DEFAULT_ENABLE_PNP { [0 ... (SNDRV_CARDS-1)] = 1 }
#ifdef __ISAPNP__ #ifdef CONFIG_PNP
#define SNDRV_DEFAULT_ENABLE_ISAPNP SNDRV_DEFAULT_ENABLE_PNP #define SNDRV_DEFAULT_ENABLE_ISAPNP SNDRV_DEFAULT_ENABLE_PNP
#else #else
#define SNDRV_DEFAULT_ENABLE_ISAPNP SNDRV_DEFAULT_ENABLE #define SNDRV_DEFAULT_ENABLE_ISAPNP SNDRV_DEFAULT_ENABLE
......
...@@ -22,7 +22,6 @@ ...@@ -22,7 +22,6 @@
* *
*/ */
#include <linux/interrupt.h>
#include "rawmidi.h" #include "rawmidi.h"
#include <linux/interrupt.h> #include <linux/interrupt.h>
...@@ -50,8 +49,6 @@ ...@@ -50,8 +49,6 @@
#define MPU401_MODE_BIT_OUTPUT 1 #define MPU401_MODE_BIT_OUTPUT 1
#define MPU401_MODE_BIT_INPUT_TRIGGER 2 #define MPU401_MODE_BIT_INPUT_TRIGGER 2
#define MPU401_MODE_BIT_OUTPUT_TRIGGER 3 #define MPU401_MODE_BIT_OUTPUT_TRIGGER 3
#define MPU401_MODE_BIT_RX_LOOP 4
#define MPU401_MODE_BIT_TX_LOOP 5
#define MPU401_MODE_INPUT (1<<MPU401_MODE_BIT_INPUT) #define MPU401_MODE_INPUT (1<<MPU401_MODE_BIT_INPUT)
#define MPU401_MODE_OUTPUT (1<<MPU401_MODE_BIT_OUTPUT) #define MPU401_MODE_OUTPUT (1<<MPU401_MODE_BIT_OUTPUT)
...@@ -88,6 +85,9 @@ struct _snd_mpu401 { ...@@ -88,6 +85,9 @@ struct _snd_mpu401 {
spinlock_t input_lock; spinlock_t input_lock;
spinlock_t output_lock; spinlock_t output_lock;
spinlock_t timer_lock; spinlock_t timer_lock;
atomic_t rx_loop;
atomic_t tx_loop;
struct timer_list timer; struct timer_list timer;
......
...@@ -317,8 +317,8 @@ struct _snd_pcm_runtime { ...@@ -317,8 +317,8 @@ struct _snd_pcm_runtime {
snd_pcm_uframes_t silence_size; /* Silence filling size */ snd_pcm_uframes_t silence_size; /* Silence filling size */
snd_pcm_uframes_t boundary; /* pointers wrap point */ snd_pcm_uframes_t boundary; /* pointers wrap point */
snd_pcm_uframes_t silenced_start; snd_pcm_uframes_t silence_start; /* starting pointer to silence area */
snd_pcm_uframes_t silenced_size; snd_pcm_uframes_t silence_filled; /* size filled with silence */
snd_pcm_sync_id_t sync; /* hardware synchronization ID */ snd_pcm_sync_id_t sync; /* hardware synchronization ID */
...@@ -328,7 +328,6 @@ struct _snd_pcm_runtime { ...@@ -328,7 +328,6 @@ struct _snd_pcm_runtime {
atomic_t mmap_count; atomic_t mmap_count;
/* -- locking / scheduling -- */ /* -- locking / scheduling -- */
spinlock_t lock;
wait_queue_head_t sleep; wait_queue_head_t sleep;
struct timer_list tick_timer; struct timer_list tick_timer;
struct fasync_struct *fasync; struct fasync_struct *fasync;
...@@ -360,6 +359,11 @@ struct _snd_pcm_runtime { ...@@ -360,6 +359,11 @@ struct _snd_pcm_runtime {
#endif #endif
}; };
typedef struct _snd_pcm_group { /* keep linked substreams */
spinlock_t lock;
struct list_head substreams;
} snd_pcm_group_t;
struct _snd_pcm_substream { struct _snd_pcm_substream {
snd_pcm_t *pcm; snd_pcm_t *pcm;
snd_pcm_str_t *pstr; snd_pcm_str_t *pstr;
...@@ -383,8 +387,10 @@ struct _snd_pcm_substream { ...@@ -383,8 +387,10 @@ struct _snd_pcm_substream {
/* -- next substream -- */ /* -- next substream -- */
snd_pcm_substream_t *next; snd_pcm_substream_t *next;
/* -- linked substreams -- */ /* -- linked substreams -- */
snd_pcm_substream_t *link_next; struct list_head link_list; /* linked list member */
snd_pcm_substream_t *link_prev; snd_pcm_group_t self_group; /* fake group for non linked substream (with substream lock inside) */
snd_pcm_group_t *group; /* pointer to current group */
/* -- assigned files -- */
snd_pcm_file_t *file; snd_pcm_file_t *file;
struct file *ffile; struct file *ffile;
#if defined(CONFIG_SND_PCM_OSS) || defined(CONFIG_SND_PCM_OSS_MODULE) #if defined(CONFIG_SND_PCM_OSS) || defined(CONFIG_SND_PCM_OSS_MODULE)
...@@ -468,6 +474,8 @@ int snd_pcm_notify(snd_pcm_notify_t *notify, int nfree); ...@@ -468,6 +474,8 @@ int snd_pcm_notify(snd_pcm_notify_t *notify, int nfree);
* Native I/O * Native I/O
*/ */
extern rwlock_t snd_pcm_link_rwlock;
int snd_pcm_info(snd_pcm_substream_t * substream, snd_pcm_info_t *info); int snd_pcm_info(snd_pcm_substream_t * substream, snd_pcm_info_t *info);
int snd_pcm_info_user(snd_pcm_substream_t * substream, snd_pcm_info_t *info); int snd_pcm_info_user(snd_pcm_substream_t * substream, snd_pcm_info_t *info);
int snd_pcm_status(snd_pcm_substream_t * substream, snd_pcm_status_t *status); int snd_pcm_status(snd_pcm_substream_t * substream, snd_pcm_status_t *status);
...@@ -568,6 +576,53 @@ static inline void div64_32(u_int64_t *n, u_int32_t div, u_int32_t *rem) ...@@ -568,6 +576,53 @@ static inline void div64_32(u_int64_t *n, u_int32_t div, u_int32_t *rem)
* PCM library * PCM library
*/ */
static inline int snd_pcm_stream_linked(snd_pcm_substream_t *substream)
{
return substream->group != &substream->self_group;
}
static inline void snd_pcm_stream_lock(snd_pcm_substream_t *substream)
{
read_lock(&snd_pcm_link_rwlock);
spin_lock(&substream->self_group.lock);
}
static inline void snd_pcm_stream_unlock(snd_pcm_substream_t *substream)
{
spin_unlock(&substream->self_group.lock);
read_unlock(&snd_pcm_link_rwlock);
}
static inline void snd_pcm_stream_lock_irq(snd_pcm_substream_t *substream)
{
read_lock_irq(&snd_pcm_link_rwlock);
spin_lock(&substream->self_group.lock);
}
static inline void snd_pcm_stream_unlock_irq(snd_pcm_substream_t *substream)
{
spin_unlock(&substream->self_group.lock);
read_unlock_irq(&snd_pcm_link_rwlock);
}
#define snd_pcm_stream_lock_irqsave(substream, flags) \
do { \
read_lock_irqsave(&snd_pcm_link_rwlock, (flags)); \
spin_lock(&substream->self_group.lock); \
} while (0)
#define snd_pcm_stream_unlock_irqrestore(substream, flags) \
do { \
spin_unlock(&substream->self_group.lock); \
read_unlock_irqrestore(&snd_pcm_link_rwlock, (flags)); \
} while (0)
#define snd_pcm_group_for_each(pos, substream) \
list_for_each(pos, &substream->group->substreams)
#define snd_pcm_group_substream_entry(pos) \
list_entry(pos, snd_pcm_substream_t, link_list)
static inline int snd_pcm_running(snd_pcm_substream_t *substream) static inline int snd_pcm_running(snd_pcm_substream_t *substream)
{ {
return (substream->runtime->status->state == SNDRV_PCM_STATE_RUNNING || return (substream->runtime->status->state == SNDRV_PCM_STATE_RUNNING ||
......
...@@ -40,10 +40,11 @@ enum sb_hw_type { ...@@ -40,10 +40,11 @@ enum sb_hw_type {
SB_HW_DT019X, /* Diamond Tech. DT-019X / Avance Logic ALS-007 */ SB_HW_DT019X, /* Diamond Tech. DT-019X / Avance Logic ALS-007 */
}; };
#define SB_OPEN_PCM 0x01 #define SB_OPEN_PCM 0x01
#define SB_OPEN_MIDI_INPUT 0x02 #define SB_OPEN_MIDI_INPUT 0x02
#define SB_OPEN_MIDI_OUTPUT 0x04 #define SB_OPEN_MIDI_OUTPUT 0x04
#define SB_OPEN_MIDI_TRIGGER 0x08 #define SB_OPEN_MIDI_INPUT_TRIGGER 0x08
#define SB_OPEN_MIDI_OUTPUT_TRIGGER 0x10
#define SB_MODE_HALT 0x00 #define SB_MODE_HALT 0x00
#define SB_MODE_PLAYBACK_8 0x01 #define SB_MODE_PLAYBACK_8 0x01
...@@ -157,6 +158,7 @@ typedef struct _snd_sb sb_t; ...@@ -157,6 +158,7 @@ typedef struct _snd_sb sb_t;
#define SB_DSP_STEREO_16BIT 0xac #define SB_DSP_STEREO_16BIT 0xac
#define SB_DSP_MIDI_INPUT_IRQ 0x31 #define SB_DSP_MIDI_INPUT_IRQ 0x31
#define SB_DSP_MIDI_UART_IRQ 0x35
#define SB_DSP_MIDI_OUTPUT 0x38 #define SB_DSP_MIDI_OUTPUT 0x38
#define SB_DSP4_OUT8_AI 0xc6 #define SB_DSP4_OUT8_AI 0xc6
...@@ -295,13 +297,13 @@ int snd_sbmixer_new(sb_t *chip); ...@@ -295,13 +297,13 @@ int snd_sbmixer_new(sb_t *chip);
/* sb8_init.c */ /* sb8_init.c */
int snd_sb8dsp_pcm(sb_t *chip, int device, snd_pcm_t ** rpcm); int snd_sb8dsp_pcm(sb_t *chip, int device, snd_pcm_t ** rpcm);
/* sb8.c */ /* sb8.c */
void snd_sb8dsp_interrupt(sb_t *chip); irqreturn_t snd_sb8dsp_interrupt(sb_t *chip);
int snd_sb8_playback_open(snd_pcm_substream_t *substream); int snd_sb8_playback_open(snd_pcm_substream_t *substream);
int snd_sb8_capture_open(snd_pcm_substream_t *substream); int snd_sb8_capture_open(snd_pcm_substream_t *substream);
int snd_sb8_playback_close(snd_pcm_substream_t *substream); int snd_sb8_playback_close(snd_pcm_substream_t *substream);
int snd_sb8_capture_close(snd_pcm_substream_t *substream); int snd_sb8_capture_close(snd_pcm_substream_t *substream);
/* midi8.c */ /* midi8.c */
void snd_sb8dsp_midi_interrupt(sb_t *chip); irqreturn_t snd_sb8dsp_midi_interrupt(sb_t *chip);
int snd_sb8dsp_midi(sb_t *chip, int device, snd_rawmidi_t ** rrawmidi); int snd_sb8dsp_midi(sb_t *chip, int device, snd_rawmidi_t ** rrawmidi);
/* sb16_init.c */ /* sb16_init.c */
......
...@@ -15,7 +15,7 @@ ...@@ -15,7 +15,7 @@
* features support * features support
*/ */
/* $Id: uda1341.h,v 1.4 2003/02/25 12:48:16 perex Exp $ */ /* $Id: uda1341.h,v 1.5 2003/04/19 13:34:32 perex Exp $ */
#define UDA1341_ALSA_NAME "snd-uda1341" #define UDA1341_ALSA_NAME "snd-uda1341"
...@@ -210,6 +210,10 @@ enum uda1341_config { ...@@ -210,6 +210,10 @@ enum uda1341_config {
CMD_IG, CMD_IG,
CMD_AGC_TIME, CMD_AGC_TIME,
CMD_AGC_LEVEL, CMD_AGC_LEVEL,
#ifdef CONFIG_PM
CMD_SUSPEND,
CMD_RESUME,
#endif
CMD_LAST, CMD_LAST,
}; };
...@@ -221,19 +225,6 @@ enum write_through { ...@@ -221,19 +225,6 @@ enum write_through {
}; };
int __init snd_chip_uda1341_mixer_new(snd_card_t *card, struct l3_client **clnt); int __init snd_chip_uda1341_mixer_new(snd_card_t *card, struct l3_client **clnt);
void __init snd_chip_uda1341_mixer_del(snd_card_t *card);
#ifdef DEBUG_MODE
#define DEBUG(format, args...) do{printk(format, ##args);}while(0)
#else
#define DEBUG(format, args...) /* nothing */
#endif
#ifdef DEBUG_FUNCTION_NAMES
#define DEBUG_NAME(format, args...) do{printk(format, ##args);}while(0)
#else
#define DEBUG_NAME(format, args...) /* nothing */
#endif
/* /*
* Local variables: * Local variables:
......
/* include/version.h. Generated by configure. */ /* include/version.h. Generated by configure. */
#define CONFIG_SND_VERSION "0.9.2" #define CONFIG_SND_VERSION "0.9.3c"
#define CONFIG_SND_DATE " (Thu Mar 20 13:31:57 2003 UTC)" #define CONFIG_SND_DATE " (Wed May 21 16:40:34 2003 UTC)"
This diff is collapsed.
...@@ -69,6 +69,7 @@ obj-$(CONFIG_SND_SB16) += snd-pcm.o snd-timer.o snd-page-alloc.o snd.o snd-rawmi ...@@ -69,6 +69,7 @@ obj-$(CONFIG_SND_SB16) += snd-pcm.o snd-timer.o snd-page-alloc.o snd.o snd-rawmi
obj-$(CONFIG_SND_SBAWE) += snd-pcm.o snd-timer.o snd-page-alloc.o snd.o snd-rawmidi.o snd-hwdep.o obj-$(CONFIG_SND_SBAWE) += snd-pcm.o snd-timer.o snd-page-alloc.o snd.o snd-rawmidi.o snd-hwdep.o
obj-$(CONFIG_SND_ES968) += snd-pcm.o snd-timer.o snd-page-alloc.o snd.o snd-rawmidi.o obj-$(CONFIG_SND_ES968) += snd-pcm.o snd-timer.o snd-page-alloc.o snd.o snd-rawmidi.o
obj-$(CONFIG_SND_WAVEFRONT) += snd-pcm.o snd-timer.o snd-page-alloc.o snd.o snd-rawmidi.o snd-hwdep.o obj-$(CONFIG_SND_WAVEFRONT) += snd-pcm.o snd-timer.o snd-page-alloc.o snd.o snd-rawmidi.o snd-hwdep.o
obj-$(CONFIG_SND_SSCAPE) += snd-pcm.o snd-timer.o snd-page-alloc.o snd.o snd-rawmidi.o snd-hwdep.o
obj-$(CONFIG_SND_ALS4000) += snd-pcm.o snd-timer.o snd-page-alloc.o snd.o snd-rawmidi.o snd-hwdep.o obj-$(CONFIG_SND_ALS4000) += snd-pcm.o snd-timer.o snd-page-alloc.o snd.o snd-rawmidi.o snd-hwdep.o
obj-$(CONFIG_SND_CMIPCI) += snd-pcm.o snd-timer.o snd-page-alloc.o snd.o snd-rawmidi.o snd-hwdep.o obj-$(CONFIG_SND_CMIPCI) += snd-pcm.o snd-timer.o snd-page-alloc.o snd.o snd-rawmidi.o snd-hwdep.o
obj-$(CONFIG_SND_CS4281) += snd-pcm.o snd-timer.o snd-page-alloc.o snd.o snd-rawmidi.o snd-hwdep.o obj-$(CONFIG_SND_CS4281) += snd-pcm.o snd-timer.o snd-page-alloc.o snd.o snd-rawmidi.o snd-hwdep.o
...@@ -78,6 +79,7 @@ obj-$(CONFIG_SND_ES1938) += snd-pcm.o snd-timer.o snd-page-alloc.o snd.o snd-hwd ...@@ -78,6 +79,7 @@ obj-$(CONFIG_SND_ES1938) += snd-pcm.o snd-timer.o snd-page-alloc.o snd.o snd-hwd
obj-$(CONFIG_SND_ES1968) += snd-pcm.o snd-timer.o snd-page-alloc.o snd.o snd-rawmidi.o obj-$(CONFIG_SND_ES1968) += snd-pcm.o snd-timer.o snd-page-alloc.o snd.o snd-rawmidi.o
obj-$(CONFIG_SND_FM801) += snd-pcm.o snd-timer.o snd-page-alloc.o snd.o snd-rawmidi.o snd-hwdep.o obj-$(CONFIG_SND_FM801) += snd-pcm.o snd-timer.o snd-page-alloc.o snd.o snd-rawmidi.o snd-hwdep.o
obj-$(CONFIG_SND_ICE1712) += snd-pcm.o snd-timer.o snd-page-alloc.o snd.o snd-rawmidi.o obj-$(CONFIG_SND_ICE1712) += snd-pcm.o snd-timer.o snd-page-alloc.o snd.o snd-rawmidi.o
obj-$(CONFIG_SND_ICE1724) += snd-pcm.o snd-timer.o snd-page-alloc.o snd.o snd-rawmidi.o
obj-$(CONFIG_SND_INTEL8X0) += snd-pcm.o snd-timer.o snd-page-alloc.o snd.o snd-rawmidi.o obj-$(CONFIG_SND_INTEL8X0) += snd-pcm.o snd-timer.o snd-page-alloc.o snd.o snd-rawmidi.o
obj-$(CONFIG_SND_MAESTRO3) += snd-pcm.o snd-timer.o snd-page-alloc.o snd.o obj-$(CONFIG_SND_MAESTRO3) += snd-pcm.o snd-timer.o snd-page-alloc.o snd.o
obj-$(CONFIG_SND_RME32) += snd-pcm.o snd-timer.o snd-page-alloc.o snd.o obj-$(CONFIG_SND_RME32) += snd-pcm.o snd-timer.o snd-page-alloc.o snd.o
...@@ -90,7 +92,7 @@ obj-$(CONFIG_SND_EMU10K1) += snd-pcm.o snd-timer.o snd-page-alloc.o snd.o snd-ra ...@@ -90,7 +92,7 @@ obj-$(CONFIG_SND_EMU10K1) += snd-pcm.o snd-timer.o snd-page-alloc.o snd.o snd-ra
obj-$(CONFIG_SND_KORG1212) += snd-pcm.o snd-timer.o snd-page-alloc.o snd.o obj-$(CONFIG_SND_KORG1212) += snd-pcm.o snd-timer.o snd-page-alloc.o snd.o
obj-$(CONFIG_SND_NM256) += snd-pcm.o snd-timer.o snd-page-alloc.o snd.o obj-$(CONFIG_SND_NM256) += snd-pcm.o snd-timer.o snd-page-alloc.o snd.o
obj-$(CONFIG_SND_RME9652) += snd-pcm.o snd-timer.o snd-page-alloc.o snd.o obj-$(CONFIG_SND_RME9652) += snd-pcm.o snd-timer.o snd-page-alloc.o snd.o
obj-$(CONFIG_SND_HDSP) += snd-pcm.o snd-timer.o snd-page-alloc.o snd.o snd-rawmidi.o obj-$(CONFIG_SND_HDSP) += snd-pcm.o snd-timer.o snd-page-alloc.o snd.o snd-rawmidi.o snd-hwdep.o
obj-$(CONFIG_SND_TRIDENT) += snd-pcm.o snd-timer.o snd-page-alloc.o snd.o snd-rawmidi.o obj-$(CONFIG_SND_TRIDENT) += snd-pcm.o snd-timer.o snd-page-alloc.o snd.o snd-rawmidi.o
obj-$(CONFIG_SND_YMFPCI) += snd-pcm.o snd-timer.o snd-page-alloc.o snd.o snd-rawmidi.o snd-hwdep.o obj-$(CONFIG_SND_YMFPCI) += snd-pcm.o snd-timer.o snd-page-alloc.o snd.o snd-rawmidi.o snd-hwdep.o
obj-$(CONFIG_SND_POWERMAC) += snd-pcm.o snd-timer.o snd-page-alloc.o snd.o obj-$(CONFIG_SND_POWERMAC) += snd-pcm.o snd-timer.o snd-page-alloc.o snd.o
......
...@@ -396,10 +396,6 @@ static snd_kcontrol_t *_ctl_find_id(snd_card_t * card, snd_ctl_elem_id_t *id) ...@@ -396,10 +396,6 @@ static snd_kcontrol_t *_ctl_find_id(snd_card_t * card, snd_ctl_elem_id_t *id)
continue; continue;
if (kctl->id.index + kctl->count <= id->index) if (kctl->id.index + kctl->count <= id->index)
continue; continue;
if (kctl->id.index != id->index) {
printk("BOOOR: %i, %i, %i\n", kctl->id.index, kctl->count, id->index);
continue;
}
return kctl; return kctl;
} }
return NULL; return NULL;
...@@ -772,9 +768,9 @@ static int snd_ctl_ioctl(struct inode *inode, struct file *file, ...@@ -772,9 +768,9 @@ static int snd_ctl_ioctl(struct inode *inode, struct file *file,
return -EPERM; return -EPERM;
#ifdef CONFIG_PM #ifdef CONFIG_PM
if (card->set_power_state) { if (card->set_power_state) {
snd_power_lock(card); snd_power_lock(card);
err = card->set_power_state(card, err); err = card->set_power_state(card, err);
snd_power_unlock(card); snd_power_unlock(card);
} else } else
#endif #endif
err = -ENOPROTOOPT; err = -ENOPROTOOPT;
......
...@@ -41,7 +41,6 @@ int snd_info_check_reserved_words(const char *str) ...@@ -41,7 +41,6 @@ int snd_info_check_reserved_words(const char *str)
{ {
static char *reserved[] = static char *reserved[] =
{ {
"dev",
"version", "version",
"meminfo", "meminfo",
"memdebug", "memdebug",
...@@ -69,9 +68,6 @@ int snd_info_check_reserved_words(const char *str) ...@@ -69,9 +68,6 @@ int snd_info_check_reserved_words(const char *str)
#ifdef CONFIG_PROC_FS #ifdef CONFIG_PROC_FS
extern int major;
extern struct file_operations snd_fops;
static DECLARE_MUTEX(info_mutex); static DECLARE_MUTEX(info_mutex);
typedef struct _snd_info_private_data { typedef struct _snd_info_private_data {
...@@ -120,33 +116,12 @@ int snd_iprintf(snd_info_buffer_t * buffer, char *fmt,...) ...@@ -120,33 +116,12 @@ int snd_iprintf(snd_info_buffer_t * buffer, char *fmt,...)
*/ */
struct proc_dir_entry *snd_proc_root = NULL; struct proc_dir_entry *snd_proc_root = NULL;
struct proc_dir_entry *snd_proc_dev = NULL;
snd_info_entry_t *snd_seq_root = NULL; snd_info_entry_t *snd_seq_root = NULL;
#ifdef CONFIG_SND_OSSEMUL #ifdef CONFIG_SND_OSSEMUL
snd_info_entry_t *snd_oss_root = NULL; snd_info_entry_t *snd_oss_root = NULL;
#endif #endif
#ifdef LINUX_2_2 #ifndef LINUX_2_2
static void snd_info_fill_inode(struct inode *inode, int fill)
{
if (fill)
MOD_INC_USE_COUNT;
else
MOD_DEC_USE_COUNT;
}
static inline void snd_info_entry_prepare(struct proc_dir_entry *de)
{
de->fill_inode = snd_info_fill_inode;
}
void snd_remove_proc_entry(struct proc_dir_entry *parent,
struct proc_dir_entry *de)
{
if (parent && de)
proc_unregister(parent, de->low_ino);
}
#else
static inline void snd_info_entry_prepare(struct proc_dir_entry *de) static inline void snd_info_entry_prepare(struct proc_dir_entry *de)
{ {
de->owner = THIS_MODULE; de->owner = THIS_MODULE;
...@@ -296,7 +271,7 @@ static int snd_info_entry_open(struct inode *inode, struct file *file) ...@@ -296,7 +271,7 @@ static int snd_info_entry_open(struct inode *inode, struct file *file)
down(&info_mutex); down(&info_mutex);
p = PDE(inode); p = PDE(inode);
entry = p == NULL ? NULL : (snd_info_entry_t *)p->data; entry = p == NULL ? NULL : (snd_info_entry_t *)p->data;
if (entry == NULL) { if (entry == NULL || entry->disconnected) {
up(&info_mutex); up(&info_mutex);
return -ENODEV; return -ENODEV;
} }
...@@ -538,66 +513,8 @@ static struct inode_operations snd_info_entry_inode_operations = ...@@ -538,66 +513,8 @@ static struct inode_operations snd_info_entry_inode_operations =
{ {
&snd_info_entry_operations, /* default sound info directory file-ops */ &snd_info_entry_operations, /* default sound info directory file-ops */
}; };
static struct inode_operations snd_info_device_inode_operations =
{
&snd_fops, /* default sound info directory file-ops */
};
#endif /* LINUX_2_2 */ #endif /* LINUX_2_2 */
static int snd_info_card_readlink(struct dentry *dentry,
char *buffer, int buflen)
{
char *s = PDE(dentry->d_inode)->data;
#ifndef LINUX_2_2
return vfs_readlink(dentry, buffer, buflen, s);
#else
int len;
if (s == NULL)
return -EIO;
len = strlen(s);
if (len > buflen)
len = buflen;
if (copy_to_user(buffer, s, len))
return -EFAULT;
return len;
#endif
}
#ifndef LINUX_2_2
static int snd_info_card_followlink(struct dentry *dentry,
struct nameidata *nd)
{
char *s = PDE(dentry->d_inode)->data;
return vfs_follow_link(nd, s);
}
#else
static struct dentry *snd_info_card_followlink(struct dentry *dentry,
struct dentry *base,
unsigned int follow)
{
char *s = PDE(dentry->d_inode)->data;
return lookup_dentry(s, base, follow);
}
#endif
#ifdef LINUX_2_2
static struct file_operations snd_info_card_link_operations =
{
NULL
};
#endif
struct inode_operations snd_info_card_link_inode_operations =
{
#ifdef LINUX_2_2
.default_file_ops = &snd_info_card_link_operations,
#endif
.readlink = snd_info_card_readlink,
.follow_link = snd_info_card_followlink,
};
/** /**
* snd_create_proc_entry - create a procfs entry * snd_create_proc_entry - create a procfs entry
* @name: the name of the proc file * @name: the name of the proc file
...@@ -627,10 +544,6 @@ int __init snd_info_init(void) ...@@ -627,10 +544,6 @@ int __init snd_info_init(void)
if (p == NULL) if (p == NULL)
return -ENOMEM; return -ENOMEM;
snd_proc_root = p; snd_proc_root = p;
p = snd_create_proc_entry("dev", S_IFDIR | S_IRUGO | S_IXUGO, snd_proc_root);
if (p == NULL)
return -ENOMEM;
snd_proc_dev = p;
#ifdef CONFIG_SND_OSSEMUL #ifdef CONFIG_SND_OSSEMUL
{ {
snd_info_entry_t *entry; snd_info_entry_t *entry;
...@@ -658,13 +571,9 @@ int __init snd_info_init(void) ...@@ -658,13 +571,9 @@ int __init snd_info_init(void)
} }
#endif #endif
snd_info_version_init(); snd_info_version_init();
#ifdef CONFIG_SND_DEBUG_MEMORY
snd_memory_info_init(); snd_memory_info_init();
#endif
snd_minor_info_init(); snd_minor_info_init();
#ifdef CONFIG_SND_OSSEMUL
snd_minor_info_oss_init(); snd_minor_info_oss_init();
#endif
snd_card_info_init(); snd_card_info_init();
return 0; return 0;
} }
...@@ -672,13 +581,9 @@ int __init snd_info_init(void) ...@@ -672,13 +581,9 @@ int __init snd_info_init(void)
int __exit snd_info_done(void) int __exit snd_info_done(void)
{ {
snd_card_info_done(); snd_card_info_done();
#ifdef CONFIG_SND_OSSEMUL
snd_minor_info_oss_done(); snd_minor_info_oss_done();
#endif
snd_minor_info_done(); snd_minor_info_done();
#ifdef CONFIG_SND_DEBUG_MEMORY
snd_memory_info_done(); snd_memory_info_done();
#endif
snd_info_version_done(); snd_info_version_done();
if (snd_proc_root) { if (snd_proc_root) {
#if defined(CONFIG_SND_SEQUENCER) || defined(CONFIG_SND_SEQUENCER_MODULE) #if defined(CONFIG_SND_SEQUENCER) || defined(CONFIG_SND_SEQUENCER_MODULE)
...@@ -689,7 +594,6 @@ int __exit snd_info_done(void) ...@@ -689,7 +594,6 @@ int __exit snd_info_done(void)
if (snd_oss_root) if (snd_oss_root)
snd_info_unregister(snd_oss_root); snd_info_unregister(snd_oss_root);
#endif #endif
snd_remove_proc_entry(snd_proc_root, snd_proc_dev);
snd_remove_proc_entry(&proc_root, snd_proc_root); snd_remove_proc_entry(&proc_root, snd_proc_root);
} }
return 0; return 0;
...@@ -729,7 +633,6 @@ int snd_info_card_create(snd_card_t * card) ...@@ -729,7 +633,6 @@ int snd_info_card_create(snd_card_t * card)
*/ */
int snd_info_card_register(snd_card_t * card) int snd_info_card_register(snd_card_t * card)
{ {
char *s;
struct proc_dir_entry *p; struct proc_dir_entry *p;
snd_assert(card != NULL, return -ENXIO); snd_assert(card != NULL, return -ENXIO);
...@@ -737,19 +640,9 @@ int snd_info_card_register(snd_card_t * card) ...@@ -737,19 +640,9 @@ int snd_info_card_register(snd_card_t * card)
if (!strcmp(card->id, card->proc_root->name)) if (!strcmp(card->id, card->proc_root->name))
return 0; return 0;
s = snd_kmalloc_strdup(card->proc_root->name, GFP_KERNEL); p = proc_symlink(card->id, snd_proc_root, card->proc_root->name);
if (s == NULL)
return -ENOMEM;
p = snd_create_proc_entry(card->id, S_IFLNK | S_IRUGO | S_IWUGO | S_IXUGO, snd_proc_root);
if (p == NULL) if (p == NULL)
return -ENOMEM; return -ENOMEM;
p->data = s;
#ifndef LINUX_2_2
p->owner = card->module;
p->proc_iops = &snd_info_card_link_inode_operations;
#else
p->ops = &snd_info_card_link_inode_operations;
#endif
card->proc_root_link = p; card->proc_root_link = p;
return 0; return 0;
} }
...@@ -760,13 +653,8 @@ int snd_info_card_register(snd_card_t * card) ...@@ -760,13 +653,8 @@ int snd_info_card_register(snd_card_t * card)
*/ */
int snd_info_card_free(snd_card_t * card) int snd_info_card_free(snd_card_t * card)
{ {
void *data;
snd_assert(card != NULL, return -ENXIO); snd_assert(card != NULL, return -ENXIO);
if (card->proc_root_link) { if (card->proc_root_link) {
data = card->proc_root_link->data;
card->proc_root_link->data = NULL;
kfree(data);
snd_remove_proc_entry(snd_proc_root, card->proc_root_link); snd_remove_proc_entry(snd_proc_root, card->proc_root_link);
card->proc_root_link = NULL; card->proc_root_link = NULL;
} }
...@@ -941,6 +829,13 @@ static int snd_info_dev_register_entry(snd_device_t *device) ...@@ -941,6 +829,13 @@ static int snd_info_dev_register_entry(snd_device_t *device)
return snd_info_register(entry); return snd_info_register(entry);
} }
static int snd_info_dev_disconnect_entry(snd_device_t *device)
{
snd_info_entry_t *entry = snd_magic_cast(snd_info_entry_t, device->device_data, return -ENXIO);
entry->disconnected = 1;
return 0;
}
static int snd_info_dev_unregister_entry(snd_device_t *device) static int snd_info_dev_unregister_entry(snd_device_t *device)
{ {
snd_info_entry_t *entry = snd_magic_cast(snd_info_entry_t, device->device_data, return -ENXIO); snd_info_entry_t *entry = snd_magic_cast(snd_info_entry_t, device->device_data, return -ENXIO);
...@@ -973,7 +868,7 @@ int snd_card_proc_new(snd_card_t *card, const char *name, ...@@ -973,7 +868,7 @@ int snd_card_proc_new(snd_card_t *card, const char *name,
static snd_device_ops_t ops = { static snd_device_ops_t ops = {
.dev_free = snd_info_dev_free_entry, .dev_free = snd_info_dev_free_entry,
.dev_register = snd_info_dev_register_entry, .dev_register = snd_info_dev_register_entry,
// .dev_disconnect = snd_info_dev_disconnect_entry, .dev_disconnect = snd_info_dev_disconnect_entry,
.dev_unregister = snd_info_dev_unregister_entry .dev_unregister = snd_info_dev_unregister_entry
}; };
snd_info_entry_t *entry; snd_info_entry_t *entry;
...@@ -1008,97 +903,6 @@ void snd_info_free_entry(snd_info_entry_t * entry) ...@@ -1008,97 +903,6 @@ void snd_info_free_entry(snd_info_entry_t * entry)
snd_magic_kfree(entry); snd_magic_kfree(entry);
} }
#ifdef LINUX_2_2
static void snd_info_device_fill_inode(struct inode *inode, int fill)
{
struct proc_dir_entry *de;
snd_info_entry_t *entry;
if (!fill) {
MOD_DEC_USE_COUNT;
return;
}
MOD_INC_USE_COUNT;
de = PDE(inode);
if (de == NULL)
return;
entry = (snd_info_entry_t *) de->data;
if (entry == NULL)
return;
inode->i_gid = device_gid;
inode->i_uid = device_uid;
inode->i_rdev = MKDEV(entry->c.device.major, entry->c.device.minor);
}
static inline void snd_info_device_entry_prepare(struct proc_dir_entry *de, snd_info_entry_t *entry)
{
de->fill_inode = snd_info_device_fill_inode;
de->ops = &snd_info_device_inode_operations;
}
#else
static inline void snd_info_device_entry_prepare(struct proc_dir_entry *de, snd_info_entry_t *entry)
{
de->rdev = mk_kdev(entry->c.device.major, entry->c.device.minor);
de->owner = THIS_MODULE;
}
#endif /* LINUX_2_2 */
/*
* create a procfs device file
*/
snd_info_entry_t *snd_info_create_device(const char *name, unsigned int number, unsigned int mode)
{
unsigned short _major = number >> 16;
unsigned short minor = (unsigned short) number;
snd_info_entry_t *entry;
struct proc_dir_entry *p = NULL;
if (!_major)
_major = major;
if (!mode)
mode = S_IFCHR | S_IRUGO | S_IWUGO;
mode &= (device_mode & (S_IRUGO | S_IWUGO)) | S_IFCHR | S_IFBLK;
entry = snd_info_create_module_entry(THIS_MODULE, name, NULL);
if (entry == NULL)
return NULL;
entry->content = SNDRV_INFO_CONTENT_DEVICE;
entry->mode = mode;
entry->c.device.major = _major;
entry->c.device.minor = minor;
down(&info_mutex);
p = create_proc_entry(entry->name, entry->mode, snd_proc_dev);
if (p) {
snd_info_device_entry_prepare(p, entry);
} else {
up(&info_mutex);
snd_info_free_entry(entry);
return NULL;
}
p->gid = device_gid;
p->uid = device_uid;
p->data = (void *) entry;
entry->p = p;
up(&info_mutex);
if (strncmp(name, "controlC", 8) != 0) /* created in sound.c */
devfs_mk_cdev(MKDEV(_major, minor), mode, "snd/%s", name);
return entry;
}
/*
* release a procfs device file
*/
void snd_info_free_device(snd_info_entry_t * entry)
{
snd_runtime_check(entry, return);
down(&info_mutex);
snd_remove_proc_entry(snd_proc_dev, entry->p);
up(&info_mutex);
if (entry->p && strncmp(entry->name, "controlC", 8))
devfs_remove("snd/%s", entry->name);
snd_info_free_entry(entry);
}
/** /**
* snd_info_register - register the info entry * snd_info_register - register the info entry
* @entry: the info entry * @entry: the info entry
......
...@@ -252,6 +252,10 @@ int snd_card_free(snd_card_t * card) ...@@ -252,6 +252,10 @@ int snd_card_free(snd_card_t * card)
snd_cards_count--; snd_cards_count--;
write_unlock(&snd_card_rwlock); write_unlock(&snd_card_rwlock);
#ifdef CONFIG_PM
wake_up(&card->power_sleep);
#endif
/* wait, until all devices are ready for the free operation */ /* wait, until all devices are ready for the free operation */
wait_event(card->shutdown_sleep, card->files == NULL); wait_event(card->shutdown_sleep, card->files == NULL);
...@@ -662,21 +666,35 @@ int snd_card_file_remove(snd_card_t *card, struct file *file) ...@@ -662,21 +666,35 @@ int snd_card_file_remove(snd_card_t *card, struct file *file)
/** /**
* snd_power_wait - wait until the power-state is changed. * snd_power_wait - wait until the power-state is changed.
* @card: soundcard structure * @card: soundcard structure
* @power_state: expected power state
* @file: file structure for the O_NONBLOCK check (optional)
* *
* Waits until the power-state is changed. * Waits until the power-state is changed.
* *
* Note: the power lock must be active before call. * Note: the power lock must be active before call.
*/ */
void snd_power_wait(snd_card_t *card) int snd_power_wait(snd_card_t *card, unsigned int power_state, struct file *file)
{ {
wait_queue_t wait; wait_queue_t wait;
/* fastpath */
if (snd_power_get_state(card) == power_state)
return 0;
init_waitqueue_entry(&wait, current); init_waitqueue_entry(&wait, current);
add_wait_queue(&card->power_sleep, &wait); add_wait_queue(&card->power_sleep, &wait);
snd_power_unlock(card); while (1) {
set_current_state(TASK_UNINTERRUPTIBLE); if (card->shutdown)
schedule_timeout(30 * HZ); return -ENODEV;
remove_wait_queue(&card->power_sleep, &wait); if (snd_power_get_state(card) == power_state) {
snd_power_lock(card); remove_wait_queue(&card->power_sleep, &wait);
return 0;
}
if (file && (file->f_flags & O_NONBLOCK))
return -EAGAIN;
snd_power_unlock(card);
set_current_state(TASK_UNINTERRUPTIBLE);
schedule_timeout(30 * HZ);
snd_power_lock(card);
}
} }
#endif /* CONFIG_PM */ #endif /* CONFIG_PM */
...@@ -21,7 +21,6 @@ ...@@ -21,7 +21,6 @@
#include <sound/driver.h> #include <sound/driver.h>
#include <linux/time.h> #include <linux/time.h>
#include <linux/slab.h> #include <linux/slab.h>
#include <linux/compat.h>
#include <sound/core.h> #include <sound/core.h>
#include <sound/pcm.h> #include <sound/pcm.h>
#include "ioctl32.h" #include "ioctl32.h"
...@@ -137,10 +136,15 @@ struct sndrv_pcm_channel_info32 { ...@@ -137,10 +136,15 @@ struct sndrv_pcm_channel_info32 {
COPY(step);\ COPY(step);\
} }
struct timeval32 {
s32 tv_sec;
s32 tv_usec;
} __attribute__((packed));
struct sndrv_pcm_status32 { struct sndrv_pcm_status32 {
s32 state; s32 state;
struct compat_timespec trigger_tstamp; struct timeval32 trigger_tstamp;
struct compat_timespec tstamp; struct timeval32 tstamp;
u32 appl_ptr; u32 appl_ptr;
u32 hw_ptr; u32 hw_ptr;
s32 delay; s32 delay;
...@@ -155,9 +159,9 @@ struct sndrv_pcm_status32 { ...@@ -155,9 +159,9 @@ struct sndrv_pcm_status32 {
{\ {\
COPY(state);\ COPY(state);\
COPY(trigger_tstamp.tv_sec);\ COPY(trigger_tstamp.tv_sec);\
COPY(trigger_tstamp.tv_nsec);\ COPY(trigger_tstamp.tv_usec);\
COPY(tstamp.tv_sec);\ COPY(tstamp.tv_sec);\
COPY(tstamp.tv_nsec);\ COPY(tstamp.tv_usec);\
COPY(appl_ptr);\ COPY(appl_ptr);\
COPY(hw_ptr);\ COPY(hw_ptr);\
COPY(delay);\ COPY(delay);\
......
...@@ -21,7 +21,6 @@ ...@@ -21,7 +21,6 @@
#include <sound/driver.h> #include <sound/driver.h>
#include <linux/time.h> #include <linux/time.h>
#include <linux/fs.h> #include <linux/fs.h>
#include <linux/compat.h>
#include <sound/core.h> #include <sound/core.h>
#include <sound/rawmidi.h> #include <sound/rawmidi.h>
#include <asm/uaccess.h> #include <asm/uaccess.h>
...@@ -43,9 +42,14 @@ struct sndrv_rawmidi_params32 { ...@@ -43,9 +42,14 @@ struct sndrv_rawmidi_params32 {
COPY(no_active_sensing);\ COPY(no_active_sensing);\
} }
struct timeval32 {
s32 tv_sec;
s32 tv_usec;
} __attribute__((packed));
struct sndrv_rawmidi_status32 { struct sndrv_rawmidi_status32 {
s32 stream; s32 stream;
struct compat_timespec tstamp; struct timeval32 tstamp;
u32 avail; u32 avail;
u32 xruns; u32 xruns;
unsigned char reserved[16]; unsigned char reserved[16];
...@@ -55,7 +59,7 @@ struct sndrv_rawmidi_status32 { ...@@ -55,7 +59,7 @@ struct sndrv_rawmidi_status32 {
{\ {\
COPY(stream);\ COPY(stream);\
COPY(tstamp.tv_sec);\ COPY(tstamp.tv_sec);\
COPY(tstamp.tv_nsec);\ COPY(tstamp.tv_usec);\
COPY(avail);\ COPY(avail);\
COPY(xruns);\ COPY(xruns);\
} }
......
...@@ -21,7 +21,6 @@ ...@@ -21,7 +21,6 @@
#include <sound/driver.h> #include <sound/driver.h>
#include <linux/time.h> #include <linux/time.h>
#include <linux/fs.h> #include <linux/fs.h>
#include <linux/compat.h>
#include <sound/core.h> #include <sound/core.h>
#include <sound/timer.h> #include <sound/timer.h>
#include <asm/uaccess.h> #include <asm/uaccess.h>
...@@ -32,7 +31,7 @@ struct sndrv_timer_info32 { ...@@ -32,7 +31,7 @@ struct sndrv_timer_info32 {
s32 card; s32 card;
unsigned char id[64]; unsigned char id[64];
unsigned char name[80]; unsigned char name[80];
u32 reserved0; u32 ticks;
u32 resolution; u32 resolution;
unsigned char reserved[64]; unsigned char reserved[64];
}; };
...@@ -43,11 +42,17 @@ struct sndrv_timer_info32 { ...@@ -43,11 +42,17 @@ struct sndrv_timer_info32 {
COPY(card);\ COPY(card);\
memcpy(dst->id, src->id, sizeof(src->id));\ memcpy(dst->id, src->id, sizeof(src->id));\
memcpy(dst->name, src->name, sizeof(src->name));\ memcpy(dst->name, src->name, sizeof(src->name));\
COPY(ticks);\
COPY(resolution);\ COPY(resolution);\
} }
struct timeval32 {
s32 tv_sec;
s32 tv_usec;
};
struct sndrv_timer_status32 { struct sndrv_timer_status32 {
struct compat_timespec tstamp; struct timeval32 tstamp;
u32 resolution; u32 resolution;
u32 lost; u32 lost;
u32 overrun; u32 overrun;
...@@ -58,7 +63,7 @@ struct sndrv_timer_status32 { ...@@ -58,7 +63,7 @@ struct sndrv_timer_status32 {
#define CVT_sndrv_timer_status()\ #define CVT_sndrv_timer_status()\
{\ {\
COPY(tstamp.tv_sec);\ COPY(tstamp.tv_sec);\
COPY(tstamp.tv_nsec);\ COPY(tstamp.tv_usec);\
COPY(resolution);\ COPY(resolution);\
COPY(lost);\ COPY(lost);\
COPY(overrun);\ COPY(overrun);\
......
...@@ -98,7 +98,7 @@ struct snd_mem_list { ...@@ -98,7 +98,7 @@ struct snd_mem_list {
* again. * again.
*/ */
void *snd_pci_hack_alloc_consistent(struct pci_dev *hwdev, size_t size, static void *snd_pci_hack_alloc_consistent(struct pci_dev *hwdev, size_t size,
dma_addr_t *dma_handle) dma_addr_t *dma_handle)
{ {
void *ret; void *ret;
......
...@@ -1477,10 +1477,10 @@ static int snd_pcm_oss_release_file(snd_pcm_oss_file_t *pcm_oss_file) ...@@ -1477,10 +1477,10 @@ static int snd_pcm_oss_release_file(snd_pcm_oss_file_t *pcm_oss_file)
continue; continue;
runtime = substream->runtime; runtime = substream->runtime;
spin_lock_irq(&runtime->lock); snd_pcm_stream_lock_irq(substream);
if (snd_pcm_running(substream)) if (snd_pcm_running(substream))
snd_pcm_stop(substream, SNDRV_PCM_STATE_SETUP); snd_pcm_stop(substream, SNDRV_PCM_STATE_SETUP);
spin_unlock_irq(&runtime->lock); snd_pcm_stream_unlock_irq(substream);
if (substream->open_flag) { if (substream->open_flag) {
if (substream->ops->hw_free != NULL) if (substream->ops->hw_free != NULL)
substream->ops->hw_free(substream); substream->ops->hw_free(substream);
...@@ -1918,21 +1918,21 @@ static unsigned int snd_pcm_oss_poll(struct file *file, poll_table * wait) ...@@ -1918,21 +1918,21 @@ static unsigned int snd_pcm_oss_poll(struct file *file, poll_table * wait)
if (psubstream != NULL) { if (psubstream != NULL) {
snd_pcm_runtime_t *runtime = psubstream->runtime; snd_pcm_runtime_t *runtime = psubstream->runtime;
poll_wait(file, &runtime->sleep, wait); poll_wait(file, &runtime->sleep, wait);
spin_lock_irq(&runtime->lock); snd_pcm_stream_lock_irq(psubstream);
if (runtime->status->state != SNDRV_PCM_STATE_DRAINING && if (runtime->status->state != SNDRV_PCM_STATE_DRAINING &&
(runtime->status->state != SNDRV_PCM_STATE_RUNNING || (runtime->status->state != SNDRV_PCM_STATE_RUNNING ||
snd_pcm_oss_playback_ready(psubstream))) snd_pcm_oss_playback_ready(psubstream)))
mask |= POLLOUT | POLLWRNORM; mask |= POLLOUT | POLLWRNORM;
spin_unlock_irq(&runtime->lock); snd_pcm_stream_unlock_irq(psubstream);
} }
if (csubstream != NULL) { if (csubstream != NULL) {
snd_pcm_runtime_t *runtime = csubstream->runtime; snd_pcm_runtime_t *runtime = csubstream->runtime;
poll_wait(file, &runtime->sleep, wait); poll_wait(file, &runtime->sleep, wait);
spin_lock_irq(&runtime->lock); snd_pcm_stream_lock_irq(csubstream);
if (runtime->status->state != SNDRV_PCM_STATE_RUNNING || if (runtime->status->state != SNDRV_PCM_STATE_RUNNING ||
snd_pcm_oss_capture_ready(csubstream)) snd_pcm_oss_capture_ready(csubstream))
mask |= POLLIN | POLLRDNORM; mask |= POLLIN | POLLRDNORM;
spin_unlock_irq(&runtime->lock); snd_pcm_stream_unlock_irq(csubstream);
} }
return mask; return mask;
......
...@@ -317,10 +317,10 @@ static void snd_pcm_substream_proc_hw_params_read(snd_info_entry_t *entry, snd_i ...@@ -317,10 +317,10 @@ static void snd_pcm_substream_proc_hw_params_read(snd_info_entry_t *entry, snd_i
snd_iprintf(buffer, "closed\n"); snd_iprintf(buffer, "closed\n");
return; return;
} }
spin_lock_irq(&runtime->lock); snd_pcm_stream_lock_irq(substream);
if (runtime->status->state == SNDRV_PCM_STATE_OPEN) { if (runtime->status->state == SNDRV_PCM_STATE_OPEN) {
snd_iprintf(buffer, "no setup\n"); snd_iprintf(buffer, "no setup\n");
spin_unlock_irq(&runtime->lock); snd_pcm_stream_unlock_irq(substream);
return; return;
} }
snd_iprintf(buffer, "access: %s\n", snd_pcm_access_name(runtime->access)); snd_iprintf(buffer, "access: %s\n", snd_pcm_access_name(runtime->access));
...@@ -340,7 +340,7 @@ static void snd_pcm_substream_proc_hw_params_read(snd_info_entry_t *entry, snd_i ...@@ -340,7 +340,7 @@ static void snd_pcm_substream_proc_hw_params_read(snd_info_entry_t *entry, snd_i
snd_iprintf(buffer, "OSS periods: %u\n", runtime->oss.periods); snd_iprintf(buffer, "OSS periods: %u\n", runtime->oss.periods);
} }
#endif #endif
spin_unlock_irq(&runtime->lock); snd_pcm_stream_unlock_irq(substream);
} }
static void snd_pcm_substream_proc_sw_params_read(snd_info_entry_t *entry, snd_info_buffer_t *buffer) static void snd_pcm_substream_proc_sw_params_read(snd_info_entry_t *entry, snd_info_buffer_t *buffer)
...@@ -351,10 +351,10 @@ static void snd_pcm_substream_proc_sw_params_read(snd_info_entry_t *entry, snd_i ...@@ -351,10 +351,10 @@ static void snd_pcm_substream_proc_sw_params_read(snd_info_entry_t *entry, snd_i
snd_iprintf(buffer, "closed\n"); snd_iprintf(buffer, "closed\n");
return; return;
} }
spin_lock_irq(&runtime->lock); snd_pcm_stream_lock_irq(substream);
if (runtime->status->state == SNDRV_PCM_STATE_OPEN) { if (runtime->status->state == SNDRV_PCM_STATE_OPEN) {
snd_iprintf(buffer, "no setup\n"); snd_iprintf(buffer, "no setup\n");
spin_unlock_irq(&runtime->lock); snd_pcm_stream_unlock_irq(substream);
return; return;
} }
snd_iprintf(buffer, "tstamp_mode: %s\n", snd_pcm_tstamp_mode_name(runtime->tstamp_mode)); snd_iprintf(buffer, "tstamp_mode: %s\n", snd_pcm_tstamp_mode_name(runtime->tstamp_mode));
...@@ -367,7 +367,7 @@ static void snd_pcm_substream_proc_sw_params_read(snd_info_entry_t *entry, snd_i ...@@ -367,7 +367,7 @@ static void snd_pcm_substream_proc_sw_params_read(snd_info_entry_t *entry, snd_i
snd_iprintf(buffer, "silence_threshold: %lu\n", runtime->silence_threshold); snd_iprintf(buffer, "silence_threshold: %lu\n", runtime->silence_threshold);
snd_iprintf(buffer, "silence_size: %lu\n", runtime->silence_size); snd_iprintf(buffer, "silence_size: %lu\n", runtime->silence_size);
snd_iprintf(buffer, "boundary: %lu\n", runtime->boundary); snd_iprintf(buffer, "boundary: %lu\n", runtime->boundary);
spin_unlock_irq(&runtime->lock); snd_pcm_stream_unlock_irq(substream);
} }
static void snd_pcm_substream_proc_status_read(snd_info_entry_t *entry, snd_info_buffer_t *buffer) static void snd_pcm_substream_proc_status_read(snd_info_entry_t *entry, snd_info_buffer_t *buffer)
...@@ -588,13 +588,15 @@ int snd_pcm_new_stream(snd_pcm_t *pcm, int stream, int substream_count) ...@@ -588,13 +588,15 @@ int snd_pcm_new_stream(snd_pcm_t *pcm, int stream, int substream_count)
pstr->substream = substream; pstr->substream = substream;
else else
prev->next = substream; prev->next = substream;
substream->link_next = substream;
substream->link_prev = substream;
err = snd_pcm_substream_proc_init(substream); err = snd_pcm_substream_proc_init(substream);
if (err < 0) { if (err < 0) {
snd_magic_kfree(substream); snd_magic_kfree(substream);
return err; return err;
} }
substream->group = &substream->self_group;
spin_lock_init(&substream->self_group.lock);
INIT_LIST_HEAD(&substream->self_group.substreams);
list_add_tail(&substream->link_list, &substream->self_group.substreams);
spin_lock_init(&substream->timer_lock); spin_lock_init(&substream->timer_lock);
prev = substream; prev = substream;
} }
...@@ -793,7 +795,6 @@ int snd_pcm_open_substream(snd_pcm_t *pcm, int stream, ...@@ -793,7 +795,6 @@ int snd_pcm_open_substream(snd_pcm_t *pcm, int stream,
memset((void*)runtime->control, 0, size); memset((void*)runtime->control, 0, size);
init_waitqueue_head(&runtime->sleep); init_waitqueue_head(&runtime->sleep);
spin_lock_init(&runtime->lock);
atomic_set(&runtime->mmap_count, 0); atomic_set(&runtime->mmap_count, 0);
init_timer(&runtime->tick_timer); init_timer(&runtime->tick_timer);
runtime->tick_timer.function = snd_pcm_tick_timer_func; runtime->tick_timer.function = snd_pcm_tick_timer_func;
...@@ -1022,6 +1023,7 @@ EXPORT_SYMBOL(snd_pcm_release_substream); ...@@ -1022,6 +1023,7 @@ EXPORT_SYMBOL(snd_pcm_release_substream);
EXPORT_SYMBOL(snd_pcm_format_name); EXPORT_SYMBOL(snd_pcm_format_name);
EXPORT_SYMBOL(snd_pcm_subformat_name); EXPORT_SYMBOL(snd_pcm_subformat_name);
/* pcm_native.c */ /* pcm_native.c */
EXPORT_SYMBOL(snd_pcm_link_rwlock);
EXPORT_SYMBOL(snd_pcm_start); EXPORT_SYMBOL(snd_pcm_start);
#ifdef CONFIG_PM #ifdef CONFIG_PM
EXPORT_SYMBOL(snd_pcm_suspend); EXPORT_SYMBOL(snd_pcm_suspend);
......
This diff is collapsed.
This diff is collapsed.
...@@ -65,6 +65,7 @@ obj-$(call sequencer,$(CONFIG_SND_SB16)) += $(RAWMIDI_OBJS) $(OPL3_OBJS) ...@@ -65,6 +65,7 @@ obj-$(call sequencer,$(CONFIG_SND_SB16)) += $(RAWMIDI_OBJS) $(OPL3_OBJS)
obj-$(call sequencer,$(CONFIG_SND_SBAWE)) += $(RAWMIDI_OBJS) $(OPL3_OBJS) snd-seq-virmidi.o obj-$(call sequencer,$(CONFIG_SND_SBAWE)) += $(RAWMIDI_OBJS) $(OPL3_OBJS) snd-seq-virmidi.o
obj-$(call sequencer,$(CONFIG_SND_ES968)) += $(RAWMIDI_OBJS) obj-$(call sequencer,$(CONFIG_SND_ES968)) += $(RAWMIDI_OBJS)
obj-$(call sequencer,$(CONFIG_SND_WAVEFRONT)) += $(RAWMIDI_OBJS) $(OPL3_OBJS) obj-$(call sequencer,$(CONFIG_SND_WAVEFRONT)) += $(RAWMIDI_OBJS) $(OPL3_OBJS)
obj-$(call sequencer,$(CONFIG_SND_SSCAPE)) += $(RAWMIDI_OBJS)
obj-$(call sequencer,$(CONFIG_SND_ALS4000)) += $(RAWMIDI_OBJS) $(OPL3_OBJS) obj-$(call sequencer,$(CONFIG_SND_ALS4000)) += $(RAWMIDI_OBJS) $(OPL3_OBJS)
obj-$(call sequencer,$(CONFIG_SND_CMIPCI)) += $(RAWMIDI_OBJS) $(OPL3_OBJS) obj-$(call sequencer,$(CONFIG_SND_CMIPCI)) += $(RAWMIDI_OBJS) $(OPL3_OBJS)
obj-$(call sequencer,$(CONFIG_SND_CS4281)) += $(RAWMIDI_OBJS) $(OPL3_OBJS) obj-$(call sequencer,$(CONFIG_SND_CS4281)) += $(RAWMIDI_OBJS) $(OPL3_OBJS)
...@@ -74,6 +75,7 @@ obj-$(call sequencer,$(CONFIG_SND_ES1938)) += $(RAWMIDI_OBJS) $(OPL3_OBJS) ...@@ -74,6 +75,7 @@ obj-$(call sequencer,$(CONFIG_SND_ES1938)) += $(RAWMIDI_OBJS) $(OPL3_OBJS)
obj-$(call sequencer,$(CONFIG_SND_ES1968)) += $(RAWMIDI_OBJS) obj-$(call sequencer,$(CONFIG_SND_ES1968)) += $(RAWMIDI_OBJS)
obj-$(call sequencer,$(CONFIG_SND_FM801)) += $(RAWMIDI_OBJS) $(OPL3_OBJS) obj-$(call sequencer,$(CONFIG_SND_FM801)) += $(RAWMIDI_OBJS) $(OPL3_OBJS)
obj-$(call sequencer,$(CONFIG_SND_ICE1712)) += $(RAWMIDI_OBJS) obj-$(call sequencer,$(CONFIG_SND_ICE1712)) += $(RAWMIDI_OBJS)
obj-$(call sequencer,$(CONFIG_SND_ICE1724)) += $(RAWMIDI_OBJS)
obj-$(call sequencer,$(CONFIG_SND_INTEL8X0)) += $(RAWMIDI_OBJS) obj-$(call sequencer,$(CONFIG_SND_INTEL8X0)) += $(RAWMIDI_OBJS)
obj-$(call sequencer,$(CONFIG_SND_SONICVIBES)) += $(RAWMIDI_OBJS) $(OPL3_OBJS) obj-$(call sequencer,$(CONFIG_SND_SONICVIBES)) += $(RAWMIDI_OBJS) $(OPL3_OBJS)
obj-$(call sequencer,$(CONFIG_SND_VIA82XX)) += $(RAWMIDI_OBJS) obj-$(call sequencer,$(CONFIG_SND_VIA82XX)) += $(RAWMIDI_OBJS)
......
...@@ -20,7 +20,6 @@ ...@@ -20,7 +20,6 @@
*/ */
#include <linux/config.h> #include <linux/config.h>
#include <linux/version.h>
#include <linux/pci.h> #include <linux/pci.h>
#include <linux/slab.h> #include <linux/slab.h>
#include <linux/mm.h> #include <linux/mm.h>
......
...@@ -35,11 +35,12 @@ ...@@ -35,11 +35,12 @@
#define SNDRV_OS_MINORS 256 #define SNDRV_OS_MINORS 256
int major = CONFIG_SND_MAJOR; static int major = CONFIG_SND_MAJOR;
int snd_major;
static int cards_limit = SNDRV_CARDS; static int cards_limit = SNDRV_CARDS;
int device_mode = S_IFCHR | S_IRUGO | S_IWUGO; #ifdef CONFIG_DEVFS_FS
int device_gid = 0; static int device_mode = S_IFCHR | S_IRUGO | S_IWUGO;
int device_uid = 0; #endif
MODULE_AUTHOR("Jaroslav Kysela <perex@suse.cz>"); MODULE_AUTHOR("Jaroslav Kysela <perex@suse.cz>");
MODULE_DESCRIPTION("Advanced Linux Sound Architecture driver for soundcards."); MODULE_DESCRIPTION("Advanced Linux Sound Architecture driver for soundcards.");
...@@ -52,15 +53,11 @@ MODULE_PARM_SYNTAX(major, "default:116,skill:devel"); ...@@ -52,15 +53,11 @@ MODULE_PARM_SYNTAX(major, "default:116,skill:devel");
MODULE_PARM(cards_limit, "i"); MODULE_PARM(cards_limit, "i");
MODULE_PARM_DESC(cards_limit, "Count of soundcards installed in the system."); MODULE_PARM_DESC(cards_limit, "Count of soundcards installed in the system.");
MODULE_PARM_SYNTAX(cards_limit, "default:8,skill:advanced"); MODULE_PARM_SYNTAX(cards_limit, "default:8,skill:advanced");
#ifdef CONFIG_DEVFS_FS
MODULE_PARM(device_mode, "i"); MODULE_PARM(device_mode, "i");
MODULE_PARM_DESC(device_mode, "Device file permission mask for sound dynamic device filesystem."); MODULE_PARM_DESC(device_mode, "Device file permission mask for devfs.");
MODULE_PARM_SYNTAX(device_mode, "default:0666,base:8"); MODULE_PARM_SYNTAX(device_mode, "default:0666,base:8");
MODULE_PARM(device_gid, "i"); #endif
MODULE_PARM_DESC(device_gid, "Device file GID for sound dynamic device filesystem.");
MODULE_PARM_SYNTAX(device_gid, "default:0");
MODULE_PARM(device_uid, "i");
MODULE_PARM_DESC(device_uid, "Device file UID for sound dynamic device filesystem.");
MODULE_PARM_SYNTAX(device_uid, "default:0");
int snd_ecards_limit; int snd_ecards_limit;
...@@ -210,22 +207,25 @@ int snd_register_device(int type, snd_card_t * card, int dev, snd_minor_t * reg, ...@@ -210,22 +207,25 @@ int snd_register_device(int type, snd_card_t * card, int dev, snd_minor_t * reg,
if (minor < 0) if (minor < 0)
return minor; return minor;
preg = (snd_minor_t *)kmalloc(sizeof(snd_minor_t), GFP_KERNEL); snd_assert(name, return -EINVAL);
preg = (snd_minor_t *)kmalloc(sizeof(snd_minor_t) + strlen(name) + 1, GFP_KERNEL);
if (preg == NULL) if (preg == NULL)
return -ENOMEM; return -ENOMEM;
*preg = *reg; *preg = *reg;
preg->number = minor; preg->number = minor;
preg->device = dev; preg->device = dev;
preg->dev = NULL; strcpy(preg->name, name);
down(&sound_mutex); down(&sound_mutex);
if (snd_minor_search(minor)) { if (snd_minor_search(minor)) {
up(&sound_mutex); up(&sound_mutex);
kfree(preg); kfree(preg);
return -EBUSY; return -EBUSY;
} }
if (name)
preg->dev = snd_info_create_device(name, minor, 0);
list_add_tail(&preg->list, &snd_minors_hash[SNDRV_MINOR_CARD(minor)]); list_add_tail(&preg->list, &snd_minors_hash[SNDRV_MINOR_CARD(minor)]);
#ifdef CONFIG_DEVFS_FS
if (strncmp(name, "controlC", 8)) /* created in sound.c */
devfs_mk_cdev(MKDEV(major, minor), S_IFCHR | device_mode, "snd/%s", name);
#endif
up(&sound_mutex); up(&sound_mutex);
return 0; return 0;
} }
...@@ -253,8 +253,10 @@ int snd_unregister_device(int type, snd_card_t * card, int dev) ...@@ -253,8 +253,10 @@ int snd_unregister_device(int type, snd_card_t * card, int dev)
up(&sound_mutex); up(&sound_mutex);
return -EINVAL; return -EINVAL;
} }
if (mptr->dev) #ifdef CONFIG_DEVFS_FS
snd_info_free_device(mptr->dev); if (strncmp(mptr->name, "controlC", 8)) /* created in sound.c */
devfs_remove("snd/%s", mptr->name);
#endif
list_del(&mptr->list); list_del(&mptr->list);
up(&sound_mutex); up(&sound_mutex);
kfree(mptr); kfree(mptr);
...@@ -321,10 +323,15 @@ int __exit snd_minor_info_done(void) ...@@ -321,10 +323,15 @@ int __exit snd_minor_info_done(void)
static int __init alsa_sound_init(void) static int __init alsa_sound_init(void)
{ {
#ifdef CONFIG_DEVFS_FS
short controlnum; short controlnum;
int err = 0; #endif
#ifdef CONFIG_SND_OSSEMUL
int err;
#endif
int card; int card;
snd_major = major;
snd_ecards_limit = cards_limit; snd_ecards_limit = cards_limit;
for (card = 0; card < SNDRV_CARDS; card++) for (card = 0; card < SNDRV_CARDS; card++)
INIT_LIST_HEAD(&snd_minors_hash[card]); INIT_LIST_HEAD(&snd_minors_hash[card]);
...@@ -335,6 +342,7 @@ static int __init alsa_sound_init(void) ...@@ -335,6 +342,7 @@ static int __init alsa_sound_init(void)
devfs_mk_dir("snd"); devfs_mk_dir("snd");
if (register_chrdev(major, "alsa", &snd_fops)) { if (register_chrdev(major, "alsa", &snd_fops)) {
snd_printk(KERN_ERR "unable to register native major device number %d\n", major); snd_printk(KERN_ERR "unable to register native major device number %d\n", major);
devfs_remove("snd");
return -EIO; return -EIO;
} }
#ifdef CONFIG_SND_DEBUG_MEMORY #ifdef CONFIG_SND_DEBUG_MEMORY
...@@ -344,24 +352,24 @@ static int __init alsa_sound_init(void) ...@@ -344,24 +352,24 @@ static int __init alsa_sound_init(void)
#ifdef CONFIG_SND_DEBUG_MEMORY #ifdef CONFIG_SND_DEBUG_MEMORY
snd_memory_done(); snd_memory_done();
#endif #endif
unregister_chrdev(major, "alsa");
devfs_remove("snd");
return -ENOMEM; return -ENOMEM;
} }
#ifdef CONFIG_SND_OSSEMUL #ifdef CONFIG_SND_OSSEMUL
snd_info_minor_register(); snd_info_minor_register();
#endif #endif
#ifdef CONFIG_DEVFS_FS
for (controlnum = 0; controlnum < cards_limit; controlnum++) { for (controlnum = 0; controlnum < cards_limit; controlnum++)
devfs_mk_cdev(MKDEV(major, controlnum<<5), devfs_mk_cdev(MKDEV(major, controlnum<<5), S_IFCHR | device_mode, "snd/controlC%d", controlnum);
device_mode | S_IFCHR, "snd/controlC%d", controlnum); #endif
}
#ifndef MODULE #ifndef MODULE
printk(KERN_INFO "Advanced Linux Sound Architecture Driver Version " CONFIG_SND_VERSION CONFIG_SND_DATE ".\n"); printk(KERN_INFO "Advanced Linux Sound Architecture Driver Version " CONFIG_SND_VERSION CONFIG_SND_DATE ".\n");
#endif #endif
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,3,0) && defined(CONFIG_APM) #if LINUX_VERSION_CODE < KERNEL_VERSION(2,3,0) && defined(CONFIG_APM)
pm_init(); pm_init();
#endif #endif
return err; return 0;
} }
static void __exit alsa_sound_exit(void) static void __exit alsa_sound_exit(void)
...@@ -390,6 +398,7 @@ module_init(alsa_sound_init) ...@@ -390,6 +398,7 @@ module_init(alsa_sound_init)
module_exit(alsa_sound_exit) module_exit(alsa_sound_exit)
/* sound.c */ /* sound.c */
EXPORT_SYMBOL(snd_major);
EXPORT_SYMBOL(snd_ecards_limit); EXPORT_SYMBOL(snd_ecards_limit);
#if defined(CONFIG_KMOD) #if defined(CONFIG_KMOD)
EXPORT_SYMBOL(snd_request_card); EXPORT_SYMBOL(snd_request_card);
...@@ -453,8 +462,6 @@ EXPORT_SYMBOL(snd_info_get_str); ...@@ -453,8 +462,6 @@ EXPORT_SYMBOL(snd_info_get_str);
EXPORT_SYMBOL(snd_info_create_module_entry); EXPORT_SYMBOL(snd_info_create_module_entry);
EXPORT_SYMBOL(snd_info_create_card_entry); EXPORT_SYMBOL(snd_info_create_card_entry);
EXPORT_SYMBOL(snd_info_free_entry); EXPORT_SYMBOL(snd_info_free_entry);
EXPORT_SYMBOL(snd_info_create_device);
EXPORT_SYMBOL(snd_info_free_device);
EXPORT_SYMBOL(snd_info_register); EXPORT_SYMBOL(snd_info_register);
EXPORT_SYMBOL(snd_info_unregister); EXPORT_SYMBOL(snd_info_unregister);
EXPORT_SYMBOL(snd_card_proc_new); EXPORT_SYMBOL(snd_card_proc_new);
......
...@@ -107,7 +107,6 @@ int snd_register_oss_device(int type, snd_card_t * card, int dev, snd_minor_t * ...@@ -107,7 +107,6 @@ int snd_register_oss_device(int type, snd_card_t * card, int dev, snd_minor_t *
*preg = *reg; *preg = *reg;
preg->number = minor; preg->number = minor;
preg->device = dev; preg->device = dev;
preg->dev = NULL;
down(&sound_oss_mutex); down(&sound_oss_mutex);
list_add_tail(&preg->list, &snd_oss_minors_hash[cidx]); list_add_tail(&preg->list, &snd_oss_minors_hash[cidx]);
minor_unit = SNDRV_MINOR_OSS_DEVICE(minor); minor_unit = SNDRV_MINOR_OSS_DEVICE(minor);
......
...@@ -247,8 +247,8 @@ static void snd_card_dummy_pcm_timer_function(unsigned long data) ...@@ -247,8 +247,8 @@ static void snd_card_dummy_pcm_timer_function(unsigned long data)
dpcm->pcm_irq_pos += dpcm->pcm_jiffie; dpcm->pcm_irq_pos += dpcm->pcm_jiffie;
dpcm->pcm_buf_pos += dpcm->pcm_jiffie; dpcm->pcm_buf_pos += dpcm->pcm_jiffie;
dpcm->pcm_buf_pos %= dpcm->pcm_size; dpcm->pcm_buf_pos %= dpcm->pcm_size;
while (dpcm->pcm_irq_pos >= dpcm->pcm_count) { if (dpcm->pcm_irq_pos >= dpcm->pcm_count) {
dpcm->pcm_irq_pos -= dpcm->pcm_count; dpcm->pcm_irq_pos %= dpcm->pcm_count;
snd_pcm_period_elapsed(dpcm->substream); snd_pcm_period_elapsed(dpcm->substream);
} }
spin_unlock_irq(&dpcm->lock); spin_unlock_irq(&dpcm->lock);
......
...@@ -31,6 +31,7 @@ obj-$(CONFIG_SND_ES1938) += snd-mpu401-uart.o ...@@ -31,6 +31,7 @@ obj-$(CONFIG_SND_ES1938) += snd-mpu401-uart.o
obj-$(CONFIG_SND_ES1968) += snd-mpu401-uart.o obj-$(CONFIG_SND_ES1968) += snd-mpu401-uart.o
obj-$(CONFIG_SND_FM801) += snd-mpu401-uart.o obj-$(CONFIG_SND_FM801) += snd-mpu401-uart.o
obj-$(CONFIG_SND_ICE1712) += snd-mpu401-uart.o obj-$(CONFIG_SND_ICE1712) += snd-mpu401-uart.o
obj-$(CONFIG_SND_ICE1724) += snd-mpu401-uart.o
obj-$(CONFIG_SND_INTEL8X0) += snd-mpu401-uart.o obj-$(CONFIG_SND_INTEL8X0) += snd-mpu401-uart.o
obj-$(CONFIG_SND_SONICVIBES) += snd-mpu401-uart.o obj-$(CONFIG_SND_SONICVIBES) += snd-mpu401-uart.o
obj-$(CONFIG_SND_VIA82XX) += snd-mpu401-uart.o obj-$(CONFIG_SND_VIA82XX) += snd-mpu401-uart.o
...@@ -38,5 +39,6 @@ obj-$(CONFIG_SND_ALI5451) += snd-mpu401-uart.o ...@@ -38,5 +39,6 @@ obj-$(CONFIG_SND_ALI5451) += snd-mpu401-uart.o
obj-$(CONFIG_SND_TRIDENT) += snd-mpu401-uart.o obj-$(CONFIG_SND_TRIDENT) += snd-mpu401-uart.o
obj-$(CONFIG_SND_YMFPCI) += snd-mpu401-uart.o obj-$(CONFIG_SND_YMFPCI) += snd-mpu401-uart.o
obj-$(CONFIG_SND_PC98_CS4232) += snd-mpu401-uart.o obj-$(CONFIG_SND_PC98_CS4232) += snd-mpu401-uart.o
obj-$(CONFIG_SND_SSCAPE) += snd-mpu401-uart.o
obj-m := $(sort $(obj-m)) obj-m := $(sort $(obj-m))
...@@ -90,27 +90,27 @@ static void snd_mpu401_uart_clear_rx(mpu401_t *mpu) ...@@ -90,27 +90,27 @@ static void snd_mpu401_uart_clear_rx(mpu401_t *mpu)
#endif #endif
} }
static irqreturn_t _snd_mpu401_uart_interrupt(mpu401_t *mpu) static void _snd_mpu401_uart_interrupt(mpu401_t *mpu)
{ {
spin_lock(&mpu->input_lock);
if (test_bit(MPU401_MODE_BIT_INPUT, &mpu->mode)) { if (test_bit(MPU401_MODE_BIT_INPUT, &mpu->mode)) {
if (! test_and_set_bit(MPU401_MODE_BIT_RX_LOOP, &mpu->mode)) { atomic_dec(&mpu->rx_loop);
spin_lock(&mpu->input_lock); snd_mpu401_uart_input_read(mpu);
snd_mpu401_uart_input_read(mpu); atomic_inc(&mpu->rx_loop);
spin_unlock(&mpu->input_lock); } else {
clear_bit(MPU401_MODE_BIT_RX_LOOP, &mpu->mode);
}
} else
snd_mpu401_uart_clear_rx(mpu); snd_mpu401_uart_clear_rx(mpu);
}
spin_unlock(&mpu->input_lock);
/* ok. for better Tx performance try do some output when input is done */ /* ok. for better Tx performance try do some output when input is done */
if (test_bit(MPU401_MODE_BIT_OUTPUT, &mpu->mode) && if (test_bit(MPU401_MODE_BIT_OUTPUT, &mpu->mode) &&
test_bit(MPU401_MODE_BIT_OUTPUT_TRIGGER, &mpu->mode)) { test_bit(MPU401_MODE_BIT_OUTPUT_TRIGGER, &mpu->mode)) {
spin_lock(&mpu->output_lock); if (spin_trylock(&mpu->output_lock)) {
snd_mpu401_uart_output_write(mpu); atomic_dec(&mpu->tx_loop);
spin_unlock(&mpu->output_lock); snd_mpu401_uart_output_write(mpu);
atomic_inc(&mpu->tx_loop);
spin_unlock(&mpu->output_lock);
}
} }
/* FIXME! This should really check whether the irq was for us */
return IRQ_HANDLED;
} }
/** /**
...@@ -127,7 +127,8 @@ irqreturn_t snd_mpu401_uart_interrupt(int irq, void *dev_id, struct pt_regs *reg ...@@ -127,7 +127,8 @@ irqreturn_t snd_mpu401_uart_interrupt(int irq, void *dev_id, struct pt_regs *reg
if (mpu == NULL) if (mpu == NULL)
return IRQ_NONE; return IRQ_NONE;
return _snd_mpu401_uart_interrupt(mpu); _snd_mpu401_uart_interrupt(mpu);
return IRQ_HANDLED;
} }
/* /*
...@@ -242,6 +243,7 @@ static int snd_mpu401_uart_input_open(snd_rawmidi_substream_t * substream) ...@@ -242,6 +243,7 @@ static int snd_mpu401_uart_input_open(snd_rawmidi_substream_t * substream)
snd_mpu401_uart_cmd(mpu, MPU401_ENTER_UART, 1); snd_mpu401_uart_cmd(mpu, MPU401_ENTER_UART, 1);
} }
mpu->substream_input = substream; mpu->substream_input = substream;
atomic_set(&mpu->rx_loop, 1);
set_bit(MPU401_MODE_BIT_INPUT, &mpu->mode); set_bit(MPU401_MODE_BIT_INPUT, &mpu->mode);
return 0; return 0;
} }
...@@ -259,6 +261,7 @@ static int snd_mpu401_uart_output_open(snd_rawmidi_substream_t * substream) ...@@ -259,6 +261,7 @@ static int snd_mpu401_uart_output_open(snd_rawmidi_substream_t * substream)
snd_mpu401_uart_cmd(mpu, MPU401_ENTER_UART, 1); snd_mpu401_uart_cmd(mpu, MPU401_ENTER_UART, 1);
} }
mpu->substream_output = substream; mpu->substream_output = substream;
atomic_set(&mpu->tx_loop, 1);
set_bit(MPU401_MODE_BIT_OUTPUT, &mpu->mode); set_bit(MPU401_MODE_BIT_OUTPUT, &mpu->mode);
return 0; return 0;
} }
...@@ -312,12 +315,15 @@ static void snd_mpu401_uart_input_trigger(snd_rawmidi_substream_t * substream, i ...@@ -312,12 +315,15 @@ static void snd_mpu401_uart_input_trigger(snd_rawmidi_substream_t * substream, i
/* read data in advance */ /* read data in advance */
/* prevent double enter via rawmidi->event callback */ /* prevent double enter via rawmidi->event callback */
if (! test_and_set_bit(MPU401_MODE_BIT_RX_LOOP, &mpu->mode)) { if (atomic_dec_and_test(&mpu->rx_loop)) {
spin_lock_irqsave(&mpu->input_lock, flags); local_irq_save(flags);
snd_mpu401_uart_input_read(mpu); if (spin_trylock(&mpu->input_lock)) {
spin_unlock_irqrestore(&mpu->input_lock, flags); snd_mpu401_uart_input_read(mpu);
clear_bit(MPU401_MODE_BIT_RX_LOOP, &mpu->mode); spin_unlock(&mpu->input_lock);
}
local_irq_restore(flags);
} }
atomic_inc(&mpu->rx_loop);
} else { } else {
if (mpu->irq < 0) if (mpu->irq < 0)
snd_mpu401_uart_remove_timer(mpu, 1); snd_mpu401_uart_remove_timer(mpu, 1);
...@@ -371,9 +377,11 @@ static void snd_mpu401_uart_output_write(mpu401_t * mpu) ...@@ -371,9 +377,11 @@ static void snd_mpu401_uart_output_write(mpu401_t * mpu)
break; break;
} }
} }
if (timeout == 0)
break; /* Tx FIFO full - try again later */
} else { } else {
snd_mpu401_uart_remove_timer (mpu, 0); snd_mpu401_uart_remove_timer (mpu, 0);
max = 1; /* no other data - leave the tx loop */ break; /* no other data - leave the tx loop */
} }
} while (--max > 0); } while (--max > 0);
} }
...@@ -389,6 +397,7 @@ static void snd_mpu401_uart_output_trigger(snd_rawmidi_substream_t * substream, ...@@ -389,6 +397,7 @@ static void snd_mpu401_uart_output_trigger(snd_rawmidi_substream_t * substream,
mpu = snd_magic_cast(mpu401_t, substream->rmidi->private_data, return); mpu = snd_magic_cast(mpu401_t, substream->rmidi->private_data, return);
if (up) { if (up) {
set_bit(MPU401_MODE_BIT_OUTPUT_TRIGGER, &mpu->mode); set_bit(MPU401_MODE_BIT_OUTPUT_TRIGGER, &mpu->mode);
/* try to add the timer at each output trigger, /* try to add the timer at each output trigger,
* since the output timer might have been removed in * since the output timer might have been removed in
* snd_mpu401_uart_output_write(). * snd_mpu401_uart_output_write().
...@@ -397,12 +406,15 @@ static void snd_mpu401_uart_output_trigger(snd_rawmidi_substream_t * substream, ...@@ -397,12 +406,15 @@ static void snd_mpu401_uart_output_trigger(snd_rawmidi_substream_t * substream,
/* output pending data */ /* output pending data */
/* prevent double enter via rawmidi->event callback */ /* prevent double enter via rawmidi->event callback */
if (! test_and_set_bit(MPU401_MODE_BIT_TX_LOOP, &mpu->mode)) { if (atomic_dec_and_test(&mpu->tx_loop)) {
spin_lock_irqsave(&mpu->output_lock, flags); local_irq_save(flags);
snd_mpu401_uart_output_write(mpu); if (spin_trylock(&mpu->output_lock)) {
spin_unlock_irqrestore(&mpu->output_lock, flags); snd_mpu401_uart_output_write(mpu);
clear_bit(MPU401_MODE_BIT_TX_LOOP, &mpu->mode); spin_unlock(&mpu->output_lock);
}
local_irq_restore(flags);
} }
atomic_inc(&mpu->tx_loop);
} else { } else {
snd_mpu401_uart_remove_timer(mpu, 0); snd_mpu401_uart_remove_timer(mpu, 0);
clear_bit(MPU401_MODE_BIT_OUTPUT_TRIGGER, &mpu->mode); clear_bit(MPU401_MODE_BIT_OUTPUT_TRIGGER, &mpu->mode);
......
...@@ -160,17 +160,11 @@ static int snd_opl3_detect(opl3_t * opl3) ...@@ -160,17 +160,11 @@ static int snd_opl3_detect(opl3_t * opl3)
opl3->hardware = OPL3_HW_OPL2; opl3->hardware = OPL3_HW_OPL2;
} else { } else {
/* /*
* Detect availability of OPL4. Unfortunately, the OPL4 * If we had an OPL4 chip, opl3->hardware would have been set
* port of the chip may not be connected to the PC bus. * by the OPL4 driver; so we can assume OPL3 here.
*/ */
snd_assert(opl3->r_port != 0, return -ENODEV); snd_assert(opl3->r_port != 0, return -ENODEV);
opl3->command(opl3, OPL3_RIGHT | OPL3_REG_MODE, OPL3_OPL3_ENABLE | OPL3_OPL4_ENABLE); opl3->hardware = OPL3_HW_OPL3;
/* All OPL4 registers are readable. */
if (inb(opl3->r_port + 1) == (OPL3_OPL3_ENABLE | OPL3_OPL4_ENABLE)) {
opl3->hardware = OPL3_HW_OPL4;
} else {
opl3->hardware = OPL3_HW_OPL3;
}
} }
return 0; return 0;
} }
......
...@@ -11,6 +11,8 @@ ifeq ($(subst m,y,$(CONFIG_L3)),y) ...@@ -11,6 +11,8 @@ ifeq ($(subst m,y,$(CONFIG_L3)),y)
obj-$(CONFIG_L3) += l3/ obj-$(CONFIG_L3) += l3/
endif endif
obj-$(CONFIG_SND) += other/
# Toplevel Module Dependency # Toplevel Module Dependency
obj-$(CONFIG_SND_INTERWAVE_STB) += snd-tea6330t.o snd-i2c.o obj-$(CONFIG_SND_INTERWAVE_STB) += snd-tea6330t.o snd-i2c.o
obj-$(CONFIG_SND_ICE1712) += snd-cs8427.o snd-i2c.o obj-$(CONFIG_SND_ICE1712) += snd-cs8427.o snd-i2c.o
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment