Merge master.kernel.org:/pub/scm/linux/kernel/git/perex/alsa

This commit is contained in:
Linus Torvalds 2005-11-07 08:09:02 -08:00
commit 8f0cb147b2
165 changed files with 3679 additions and 3016 deletions

View File

@ -167,7 +167,7 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed.
spdif - Support SPDIF I/O spdif - Support SPDIF I/O
- Default: disabled - Default: disabled
Module supports autoprobe and multiple chips (max 8). This module supports one chip and autoprobe.
The power-management is supported. The power-management is supported.
@ -206,7 +206,7 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed.
See "AC97 Quirk Option" section below. See "AC97 Quirk Option" section below.
spdif_aclink - S/PDIF transfer over AC-link (default = 1) spdif_aclink - S/PDIF transfer over AC-link (default = 1)
This module supports up to 8 cards and autoprobe. This module supports one card and autoprobe.
ATI IXP has two different methods to control SPDIF output. One is ATI IXP has two different methods to control SPDIF output. One is
over AC-link and another is over the "direct" SPDIF output. The over AC-link and another is over the "direct" SPDIF output. The
@ -218,7 +218,7 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed.
Module for ATI IXP 150/200/250 AC97 modem controllers. Module for ATI IXP 150/200/250 AC97 modem controllers.
Module supports up to 8 cards. This module supports one card and autoprobe.
Note: The default index value of this module is -2, i.e. the first Note: The default index value of this module is -2, i.e. the first
slot is excluded. slot is excluded.
@ -637,7 +637,7 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed.
model - force the model name model - force the model name
position_fix - Fix DMA pointer (0 = auto, 1 = none, 2 = POSBUF, 3 = FIFO size) position_fix - Fix DMA pointer (0 = auto, 1 = none, 2 = POSBUF, 3 = FIFO size)
Module supports up to 8 cards. This module supports one card and autoprobe.
Each codec may have a model table for different configurations. Each codec may have a model table for different configurations.
If your machine isn't listed there, the default (usually minimal) If your machine isn't listed there, the default (usually minimal)
@ -663,6 +663,10 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed.
adjusted. Appearing only when compiled with adjusted. Appearing only when compiled with
$CONFIG_SND_DEBUG=y $CONFIG_SND_DEBUG=y
ALC260
hp HP machines
fujitsu Fujitsu S7020
CMI9880 CMI9880
minimal 3-jack in back minimal 3-jack in back
min_fp 3-jack in back, 2-jack in front min_fp 3-jack in back, 2-jack in front
@ -811,7 +815,7 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed.
semaphores (e.g. on some ASUS laptops) semaphores (e.g. on some ASUS laptops)
(default off) (default off)
Module supports autoprobe and multiple bus-master chips (max 8). This module supports one chip and autoprobe.
Note: the latest driver supports auto-detection of chip clock. Note: the latest driver supports auto-detection of chip clock.
if you still encounter too fast playback, specify the clock if you still encounter too fast playback, specify the clock
@ -830,7 +834,7 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed.
ac97_clock - AC'97 codec clock base (0 = auto-detect) ac97_clock - AC'97 codec clock base (0 = auto-detect)
This module supports up to 8 cards and autoprobe. This module supports one card and autoprobe.
Note: The default index value of this module is -2, i.e. the first Note: The default index value of this module is -2, i.e. the first
slot is excluded. slot is excluded.
@ -950,8 +954,10 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed.
use_cache - 0 or 1 (disabled by default) use_cache - 0 or 1 (disabled by default)
vaio_hack - alias buffer_top=0x25a800 vaio_hack - alias buffer_top=0x25a800
reset_workaround - enable AC97 RESET workaround for some laptops reset_workaround - enable AC97 RESET workaround for some laptops
reset_workaround2 - enable extended AC97 RESET workaround for some
other laptops
Module supports autoprobe and multiple chips (max 8). This module supports one chip and autoprobe.
The power-management is supported. The power-management is supported.
@ -980,6 +986,11 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed.
workaround is enabled automatically. For other laptops with a workaround is enabled automatically. For other laptops with a
hard freeze, you can try reset_workaround=1 option. hard freeze, you can try reset_workaround=1 option.
Note: Dell Latitude CSx laptops have another problem regarding
AC97 RESET. On these laptops, reset_workaround2 option is
turned on as default. This option is worth to try if the
previous reset_workaround option doesn't help.
Note: This driver is really crappy. It's a porting from the Note: This driver is really crappy. It's a porting from the
OSS driver, which is a result of black-magic reverse engineering. OSS driver, which is a result of black-magic reverse engineering.
The detection of codec will fail if the driver is loaded *after* The detection of codec will fail if the driver is loaded *after*
@ -1310,7 +1321,7 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed.
ac97_quirk - AC'97 workaround for strange hardware ac97_quirk - AC'97 workaround for strange hardware
See "AC97 Quirk Option" section below. See "AC97 Quirk Option" section below.
Module supports autoprobe and multiple bus-master chips (max 8). This module supports one chip and autoprobe.
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
@ -1352,7 +1363,7 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed.
ac97_clock - AC'97 codec clock base (default 48000Hz) ac97_clock - AC'97 codec clock base (default 48000Hz)
Module supports up to 8 cards. This module supports one card and autoprobe.
Note: The default index value of this module is -2, i.e. the first Note: The default index value of this module is -2, i.e. the first
slot is excluded. slot is excluded.

View File

@ -18,8 +18,8 @@
</affiliation> </affiliation>
</author> </author>
<date>March 6, 2005</date> <date>October 6, 2005</date>
<edition>0.3.4</edition> <edition>0.3.5</edition>
<abstract> <abstract>
<para> <para>
@ -30,7 +30,7 @@
<legalnotice> <legalnotice>
<para> <para>
Copyright (c) 2002-2004 Takashi Iwai <email>tiwai@suse.de</email> Copyright (c) 2002-2005 Takashi Iwai <email>tiwai@suse.de</email>
</para> </para>
<para> <para>
@ -1433,25 +1433,10 @@
<informalexample> <informalexample>
<programlisting> <programlisting>
<![CDATA[ <![CDATA[
if (chip->res_port) { release_and_free_resource(chip->res_port);
release_resource(chip->res_port);
kfree_nocheck(chip->res_port);
}
]]> ]]>
</programlisting> </programlisting>
</informalexample> </informalexample>
As you can see, the resource pointer is also to be freed
via <function>kfree_nocheck()</function> after
<function>release_resource()</function> is called. You
cannot use <function>kfree()</function> here, because on ALSA,
<function>kfree()</function> may be a wrapper to its own
allocator with the memory debugging. Since the resource pointer
is allocated externally outside the ALSA, it must be released
via the native
<function>kfree()</function>.
<function>kfree_nocheck()</function> is used for that; it calls
the native <function>kfree()</function> without wrapper.
</para> </para>
<para> <para>
@ -2190,8 +2175,7 @@ struct _snd_pcm_runtime {
unsigned int rate_den; unsigned int rate_den;
/* -- SW params -- */ /* -- SW params -- */
int tstamp_timespec; /* use timeval (0) or timespec (1) */ struct timespec tstamp_mode; /* mmap timestamp is updated */
snd_pcm_tstamp_t tstamp_mode; /* mmap timestamp is updated */
unsigned int period_step; unsigned int period_step;
unsigned int sleep_min; /* min ticks to sleep */ unsigned int sleep_min; /* min ticks to sleep */
snd_pcm_uframes_t xfer_align; /* xfer size need to be a multiple */ snd_pcm_uframes_t xfer_align; /* xfer size need to be a multiple */
@ -3709,8 +3693,7 @@ struct _snd_pcm_runtime {
<para> <para>
Here, the chip instance is retrieved via Here, the chip instance is retrieved via
<function>snd_kcontrol_chip()</function> macro. This macro <function>snd_kcontrol_chip()</function> macro. This macro
converts from kcontrol-&gt;private_data to the type defined by just accesses to kcontrol-&gt;private_data. The
<type>chip_t</type>. The
kcontrol-&gt;private_data field is kcontrol-&gt;private_data field is
given as the argument of <function>snd_ctl_new()</function> given as the argument of <function>snd_ctl_new()</function>
(see the later subsection (see the later subsection
@ -5998,32 +5981,23 @@ struct _snd_pcm_runtime {
The first argument is the expression to evaluate, and the The first argument is the expression to evaluate, and the
second argument is the action if it fails. When second argument is the action if it fails. When
<constant>CONFIG_SND_DEBUG</constant>, is set, it will show an <constant>CONFIG_SND_DEBUG</constant>, is set, it will show an
error message such as <computeroutput>BUG? (xxx) (called from error message such as <computeroutput>BUG? (xxx)</computeroutput>
yyy)</computeroutput>. When no debug flag is set, this is together with stack trace.
ignored.
</para> </para>
</section>
<section id="useful-functions-snd-runtime-check">
<title><function>snd_runtime_check()</function></title>
<para> <para>
This macro is quite similar with When no debug flag is set, this macro is ignored.
<function>snd_assert()</function>. Unlike
<function>snd_assert()</function>, the expression is always
evaluated regardless of
<constant>CONFIG_SND_DEBUG</constant>. When
<constant>CONFIG_SND_DEBUG</constant> is set, the macro will
show a message like <computeroutput>ERROR (xx) (called from
yyy)</computeroutput>.
</para> </para>
</section> </section>
<section id="useful-functions-snd-bug"> <section id="useful-functions-snd-bug">
<title><function>snd_BUG()</function></title> <title><function>snd_BUG()</function></title>
<para> <para>
It calls <function>snd_assert(0,)</function> -- that is, just It shows <computeroutput>BUG?</computeroutput> message and
prints the error message at the point. It's useful to show that stack trace as well as <function>snd_assert</function> at the point.
a fatal error happens there. It's useful to show that a fatal error happens there.
</para>
<para>
When no debug flag is set, this macro is ignored.
</para> </para>
</section> </section>
</chapter> </chapter>

View File

@ -149,8 +149,22 @@ static void get_rtc_alm_time (struct rtc_time *alm_tm);
#ifdef RTC_IRQ #ifdef RTC_IRQ
static void rtc_dropped_irq(unsigned long data); static void rtc_dropped_irq(unsigned long data);
static void set_rtc_irq_bit(unsigned char bit); static void set_rtc_irq_bit_locked(unsigned char bit);
static void mask_rtc_irq_bit(unsigned char bit); static void mask_rtc_irq_bit_locked(unsigned char bit);
static inline void set_rtc_irq_bit(unsigned char bit)
{
spin_lock_irq(&rtc_lock);
set_rtc_irq_bit_locked(bit);
spin_unlock_irq(&rtc_lock);
}
static void mask_rtc_irq_bit(unsigned char bit)
{
spin_lock_irq(&rtc_lock);
mask_rtc_irq_bit_locked(bit);
spin_unlock_irq(&rtc_lock);
}
#endif #endif
static int rtc_proc_open(struct inode *inode, struct file *file); static int rtc_proc_open(struct inode *inode, struct file *file);
@ -401,18 +415,19 @@ static int rtc_do_ioctl(unsigned int cmd, unsigned long arg, int kernel)
} }
case RTC_PIE_OFF: /* Mask periodic int. enab. bit */ case RTC_PIE_OFF: /* Mask periodic int. enab. bit */
{ {
mask_rtc_irq_bit(RTC_PIE); unsigned long flags; /* can be called from isr via rtc_control() */
spin_lock_irqsave (&rtc_lock, flags);
mask_rtc_irq_bit_locked(RTC_PIE);
if (rtc_status & RTC_TIMER_ON) { if (rtc_status & RTC_TIMER_ON) {
spin_lock_irq (&rtc_lock);
rtc_status &= ~RTC_TIMER_ON; rtc_status &= ~RTC_TIMER_ON;
del_timer(&rtc_irq_timer); del_timer(&rtc_irq_timer);
spin_unlock_irq (&rtc_lock);
} }
spin_unlock_irqrestore (&rtc_lock, flags);
return 0; return 0;
} }
case RTC_PIE_ON: /* Allow periodic ints */ case RTC_PIE_ON: /* Allow periodic ints */
{ {
unsigned long flags; /* can be called from isr via rtc_control() */
/* /*
* We don't really want Joe User enabling more * We don't really want Joe User enabling more
* than 64Hz of interrupts on a multi-user machine. * than 64Hz of interrupts on a multi-user machine.
@ -421,14 +436,14 @@ static int rtc_do_ioctl(unsigned int cmd, unsigned long arg, int kernel)
(!capable(CAP_SYS_RESOURCE))) (!capable(CAP_SYS_RESOURCE)))
return -EACCES; return -EACCES;
spin_lock_irqsave (&rtc_lock, flags);
if (!(rtc_status & RTC_TIMER_ON)) { if (!(rtc_status & RTC_TIMER_ON)) {
spin_lock_irq (&rtc_lock);
rtc_irq_timer.expires = jiffies + HZ/rtc_freq + 2*HZ/100; rtc_irq_timer.expires = jiffies + HZ/rtc_freq + 2*HZ/100;
add_timer(&rtc_irq_timer); add_timer(&rtc_irq_timer);
rtc_status |= RTC_TIMER_ON; rtc_status |= RTC_TIMER_ON;
spin_unlock_irq (&rtc_lock);
} }
set_rtc_irq_bit(RTC_PIE); set_rtc_irq_bit_locked(RTC_PIE);
spin_unlock_irqrestore (&rtc_lock, flags);
return 0; return 0;
} }
case RTC_UIE_OFF: /* Mask ints from RTC updates. */ case RTC_UIE_OFF: /* Mask ints from RTC updates. */
@ -609,6 +624,7 @@ static int rtc_do_ioctl(unsigned int cmd, unsigned long arg, int kernel)
{ {
int tmp = 0; int tmp = 0;
unsigned char val; unsigned char val;
unsigned long flags; /* can be called from isr via rtc_control() */
/* /*
* The max we can do is 8192Hz. * The max we can do is 8192Hz.
@ -631,9 +647,9 @@ static int rtc_do_ioctl(unsigned int cmd, unsigned long arg, int kernel)
if (arg != (1<<tmp)) if (arg != (1<<tmp))
return -EINVAL; return -EINVAL;
spin_lock_irq(&rtc_lock); spin_lock_irqsave(&rtc_lock, flags);
if (hpet_set_periodic_freq(arg)) { if (hpet_set_periodic_freq(arg)) {
spin_unlock_irq(&rtc_lock); spin_unlock_irqrestore(&rtc_lock, flags);
return 0; return 0;
} }
rtc_freq = arg; rtc_freq = arg;
@ -641,7 +657,7 @@ static int rtc_do_ioctl(unsigned int cmd, unsigned long arg, int kernel)
val = CMOS_READ(RTC_FREQ_SELECT) & 0xf0; val = CMOS_READ(RTC_FREQ_SELECT) & 0xf0;
val |= (16 - tmp); val |= (16 - tmp);
CMOS_WRITE(val, RTC_FREQ_SELECT); CMOS_WRITE(val, RTC_FREQ_SELECT);
spin_unlock_irq(&rtc_lock); spin_unlock_irqrestore(&rtc_lock, flags);
return 0; return 0;
} }
#endif #endif
@ -844,12 +860,15 @@ int rtc_control(rtc_task_t *task, unsigned int cmd, unsigned long arg)
#ifndef RTC_IRQ #ifndef RTC_IRQ
return -EIO; return -EIO;
#else #else
spin_lock_irq(&rtc_task_lock); unsigned long flags;
if (cmd != RTC_PIE_ON && cmd != RTC_PIE_OFF && cmd != RTC_IRQP_SET)
return -EINVAL;
spin_lock_irqsave(&rtc_task_lock, flags);
if (rtc_callback != task) { if (rtc_callback != task) {
spin_unlock_irq(&rtc_task_lock); spin_unlock_irqrestore(&rtc_task_lock, flags);
return -ENXIO; return -ENXIO;
} }
spin_unlock_irq(&rtc_task_lock); spin_unlock_irqrestore(&rtc_task_lock, flags);
return rtc_do_ioctl(cmd, arg, 1); return rtc_do_ioctl(cmd, arg, 1);
#endif #endif
} }
@ -1306,40 +1325,32 @@ static void get_rtc_alm_time(struct rtc_time *alm_tm)
* meddles with the interrupt enable/disable bits. * meddles with the interrupt enable/disable bits.
*/ */
static void mask_rtc_irq_bit(unsigned char bit) static void mask_rtc_irq_bit_locked(unsigned char bit)
{ {
unsigned char val; unsigned char val;
spin_lock_irq(&rtc_lock); if (hpet_mask_rtc_irq_bit(bit))
if (hpet_mask_rtc_irq_bit(bit)) {
spin_unlock_irq(&rtc_lock);
return; return;
}
val = CMOS_READ(RTC_CONTROL); val = CMOS_READ(RTC_CONTROL);
val &= ~bit; val &= ~bit;
CMOS_WRITE(val, RTC_CONTROL); CMOS_WRITE(val, RTC_CONTROL);
CMOS_READ(RTC_INTR_FLAGS); CMOS_READ(RTC_INTR_FLAGS);
rtc_irq_data = 0; rtc_irq_data = 0;
spin_unlock_irq(&rtc_lock);
} }
static void set_rtc_irq_bit(unsigned char bit) static void set_rtc_irq_bit_locked(unsigned char bit)
{ {
unsigned char val; unsigned char val;
spin_lock_irq(&rtc_lock); if (hpet_set_rtc_irq_bit(bit))
if (hpet_set_rtc_irq_bit(bit)) {
spin_unlock_irq(&rtc_lock);
return; return;
}
val = CMOS_READ(RTC_CONTROL); val = CMOS_READ(RTC_CONTROL);
val |= bit; val |= bit;
CMOS_WRITE(val, RTC_CONTROL); CMOS_WRITE(val, RTC_CONTROL);
CMOS_READ(RTC_INTR_FLAGS); CMOS_READ(RTC_INTR_FLAGS);
rtc_irq_data = 0; rtc_irq_data = 0;
spin_unlock_irq(&rtc_lock);
} }
#endif #endif

View File

@ -387,15 +387,6 @@
#define AC97_RATES_MIC_ADC 4 #define AC97_RATES_MIC_ADC 4
#define AC97_RATES_SPDIF 5 #define AC97_RATES_SPDIF 5
/* shared controllers */
enum {
AC97_SHARED_TYPE_NONE,
AC97_SHARED_TYPE_ICH,
AC97_SHARED_TYPE_ATIIXP,
AC97_SHARED_TYPE_VIA,
AC97_SHARED_TYPES
};
/* /*
* *
*/ */
@ -468,7 +459,6 @@ struct _snd_ac97_bus {
unsigned short used_slots[2][4]; /* actually used PCM slots */ unsigned short used_slots[2][4]; /* actually used PCM slots */
unsigned short pcms_count; /* count of PCMs */ unsigned short pcms_count; /* count of PCMs */
struct ac97_pcm *pcms; struct ac97_pcm *pcms;
unsigned int shared_type; /* type of shared controller betwen audio and modem */
ac97_t *codec[4]; ac97_t *codec[4];
snd_info_entry_t *proc; snd_info_entry_t *proc;
}; };

View File

@ -29,7 +29,6 @@
#include <linux/pm.h> /* pm_message_t */ #include <linux/pm.h> /* pm_message_t */
/* Typedef's */ /* Typedef's */
typedef struct timespec snd_timestamp_t;
typedef struct sndrv_interval snd_interval_t; typedef struct sndrv_interval snd_interval_t;
typedef enum sndrv_card_type snd_card_type; typedef enum sndrv_card_type snd_card_type;
typedef struct sndrv_xferi snd_xferi_t; typedef struct sndrv_xferi snd_xferi_t;
@ -256,6 +255,7 @@ typedef struct _snd_minor snd_minor_t;
/* sound.c */ /* sound.c */
extern int snd_major;
extern int snd_ecards_limit; extern int snd_ecards_limit;
void snd_request_card(int card); void snd_request_card(int card);
@ -285,39 +285,6 @@ int snd_oss_init_module(void);
/* memory.c */ /* memory.c */
#ifdef CONFIG_SND_DEBUG_MEMORY
void snd_memory_init(void);
void snd_memory_done(void);
int snd_memory_info_init(void);
int snd_memory_info_done(void);
void *snd_hidden_kmalloc(size_t size, gfp_t flags);
void *snd_hidden_kzalloc(size_t size, gfp_t flags);
void *snd_hidden_kcalloc(size_t n, size_t size, gfp_t flags);
void snd_hidden_kfree(const void *obj);
void *snd_hidden_vmalloc(unsigned long size);
void snd_hidden_vfree(void *obj);
char *snd_hidden_kstrdup(const char *s, gfp_t flags);
#define kmalloc(size, flags) snd_hidden_kmalloc(size, flags)
#define kzalloc(size, flags) snd_hidden_kzalloc(size, flags)
#define kcalloc(n, size, flags) snd_hidden_kcalloc(n, size, flags)
#define kfree(obj) snd_hidden_kfree(obj)
#define vmalloc(size) snd_hidden_vmalloc(size)
#define vfree(obj) snd_hidden_vfree(obj)
#define kmalloc_nocheck(size, flags) snd_wrapper_kmalloc(size, flags)
#define vmalloc_nocheck(size) snd_wrapper_vmalloc(size)
#define kfree_nocheck(obj) snd_wrapper_kfree(obj)
#define vfree_nocheck(obj) snd_wrapper_vfree(obj)
#define kstrdup(s, flags) snd_hidden_kstrdup(s, flags)
#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 vmalloc_nocheck(size) vmalloc(size)
#define kfree_nocheck(obj) kfree(obj)
#define vfree_nocheck(obj) vfree(obj)
#endif
int copy_to_user_fromio(void __user *dst, const volatile void __iomem *src, size_t count); int copy_to_user_fromio(void __user *dst, const volatile void __iomem *src, size_t count);
int copy_from_user_toio(volatile void __iomem *dst, const void __user *src, size_t count); int copy_from_user_toio(volatile void __iomem *dst, const void __user *src, size_t count);
@ -373,8 +340,9 @@ unsigned int snd_dma_pointer(unsigned long dma, unsigned int size);
#endif #endif
/* misc.c */ /* misc.c */
struct resource;
void release_and_free_resource(struct resource *res);
int snd_task_name(struct task_struct *task, char *name, size_t size);
#ifdef CONFIG_SND_VERBOSE_PRINTK #ifdef CONFIG_SND_VERBOSE_PRINTK
void snd_verbose_printk(const char *file, int line, const char *format, ...) void snd_verbose_printk(const char *file, int line, const char *format, ...)
__attribute__ ((format (printf, 3, 4))); __attribute__ ((format (printf, 3, 4)));
@ -429,34 +397,24 @@ void snd_verbose_printd(const char *file, int line, const char *format, ...)
* When CONFIG_SND_DEBUG is not set, the expression is executed but * When CONFIG_SND_DEBUG is not set, the expression is executed but
* not checked. * not checked.
*/ */
#define snd_assert(expr, args...) do {\ #define snd_assert(expr, args...) do { \
if (unlikely(!(expr))) { \ if (unlikely(!(expr))) { \
snd_printk(KERN_ERR "BUG? (%s) (called from %p)\n", __ASTRING__(expr), __builtin_return_address(0));\ snd_printk(KERN_ERR "BUG? (%s)\n", __ASTRING__(expr)); \
args;\ dump_stack(); \
}\ args; \
} \
} while (0) } while (0)
/**
* snd_runtime_check - run-time assertion macro #define snd_BUG() do { \
* @expr: expression snd_printk(KERN_ERR "BUG?\n"); \
* @args...: the action dump_stack(); \
*
* This macro checks the expression in run-time and invokes the commands
* given in the rest arguments if the assertion is failed.
* Unlike snd_assert(), the action commands are executed even if
* CONFIG_SND_DEBUG is not set but without any error messages.
*/
#define snd_runtime_check(expr, args...) do {\
if (unlikely(!(expr))) { \
snd_printk(KERN_ERR "ERROR (%s) (called from %p)\n", __ASTRING__(expr), __builtin_return_address(0));\
args;\
}\
} while (0) } while (0)
#else /* !CONFIG_SND_DEBUG */ #else /* !CONFIG_SND_DEBUG */
#define snd_printd(fmt, args...) /* nothing */ #define snd_printd(fmt, args...) /* nothing */
#define snd_assert(expr, args...) (void)(expr) #define snd_assert(expr, args...) (void)(expr)
#define snd_runtime_check(expr, args...) do { if (!(expr)) { args; } } while (0) #define snd_BUG() /* nothing */
#endif /* CONFIG_SND_DEBUG */ #endif /* CONFIG_SND_DEBUG */
@ -473,30 +431,6 @@ void snd_verbose_printd(const char *file, int line, const char *format, ...)
#define snd_printdd(format, args...) /* nothing */ #define snd_printdd(format, args...) /* nothing */
#endif #endif
#define snd_BUG() snd_assert(0, )
static inline void snd_timestamp_now(struct timespec *tstamp, int timespec)
{
struct timeval val;
/* FIXME: use a linear time source */
do_gettimeofday(&val);
tstamp->tv_sec = val.tv_sec;
tstamp->tv_nsec = val.tv_usec;
if (timespec)
tstamp->tv_nsec *= 1000L;
}
static inline void snd_timestamp_zero(struct timespec *tstamp)
{
tstamp->tv_sec = 0;
tstamp->tv_nsec = 0;
}
static inline int snd_timestamp_null(struct timespec *tstamp)
{
return tstamp->tv_sec == 0 && tstamp->tv_nsec == 0;
}
#define SNDRV_OSS_VERSION ((3<<16)|(8<<8)|(1<<4)|(0)) /* 3.8.1a */ #define SNDRV_OSS_VERSION ((3<<16)|(8<<8)|(1<<4)|(0)) /* 3.8.1a */

View File

@ -44,21 +44,4 @@
#include <linux/module.h> #include <linux/module.h>
/*
* ==========================================================================
*/
#ifdef CONFIG_SND_DEBUG_MEMORY
#include <linux/slab.h>
#include <linux/vmalloc.h>
void *snd_wrapper_kmalloc(size_t, gfp_t);
#undef kmalloc
void snd_wrapper_kfree(const void *);
#undef kfree
void *snd_wrapper_vmalloc(size_t);
#undef vmalloc
void snd_wrapper_vfree(void *);
#undef vfree
#endif
#endif /* __SOUND_DRIVER_H */ #endif /* __SOUND_DRIVER_H */

View File

@ -48,7 +48,8 @@
/* FIXME? - according to the OSS driver the EMU10K1 needs a 29 bit DMA mask */ /* FIXME? - according to the OSS driver the EMU10K1 needs a 29 bit DMA mask */
#define EMU10K1_DMA_MASK 0x7fffffffUL /* 31bit */ #define EMU10K1_DMA_MASK 0x7fffffffUL /* 31bit */
#define AUDIGY_DMA_MASK 0xffffffffUL /* 32bit */ #define AUDIGY_DMA_MASK 0x7fffffffUL /* 31bit FIXME - 32 should work? */
/* See ALSA bug #1276 - rlrevell */
#define TMEMSIZE 256*1024 #define TMEMSIZE 256*1024
#define TMEMSIZEREG 4 #define TMEMSIZEREG 4

View File

@ -27,8 +27,9 @@
#define SNDRV_MINOR(card, dev) (((card) << 5) | (dev)) #define SNDRV_MINOR(card, dev) (((card) << 5) | (dev))
#define SNDRV_MINOR_CONTROL 0 /* 0 - 0 */ #define SNDRV_MINOR_CONTROL 0 /* 0 - 0 */
#define SNDRV_MINOR_SEQUENCER 1 #define SNDRV_MINOR_GLOBAL 1 /* 1 */
#define SNDRV_MINOR_TIMER (1+32) #define SNDRV_MINOR_SEQUENCER (SNDRV_MINOR_GLOBAL + 0 * 32)
#define SNDRV_MINOR_TIMER (SNDRV_MINOR_GLOBAL + 1 * 32)
#define SNDRV_MINOR_HWDEP 4 /* 4 - 7 */ #define SNDRV_MINOR_HWDEP 4 /* 4 - 7 */
#define SNDRV_MINOR_HWDEPS 4 #define SNDRV_MINOR_HWDEPS 4
#define SNDRV_MINOR_RAWMIDI 8 /* 8 - 15 */ #define SNDRV_MINOR_RAWMIDI 8 /* 8 - 15 */
@ -39,12 +40,9 @@
#define SNDRV_DEVICE_TYPE_CONTROL SNDRV_MINOR_CONTROL #define SNDRV_DEVICE_TYPE_CONTROL SNDRV_MINOR_CONTROL
#define SNDRV_DEVICE_TYPE_HWDEP SNDRV_MINOR_HWDEP #define SNDRV_DEVICE_TYPE_HWDEP SNDRV_MINOR_HWDEP
#define SNDRV_DEVICE_TYPE_MIXER SNDRV_MINOR_MIXER
#define SNDRV_DEVICE_TYPE_RAWMIDI SNDRV_MINOR_RAWMIDI #define SNDRV_DEVICE_TYPE_RAWMIDI SNDRV_MINOR_RAWMIDI
#define SNDRV_DEVICE_TYPE_PCM_PLAYBACK SNDRV_MINOR_PCM_PLAYBACK #define SNDRV_DEVICE_TYPE_PCM_PLAYBACK SNDRV_MINOR_PCM_PLAYBACK
#define SNDRV_DEVICE_TYPE_PCM_PLOOP SNDRV_MINOR_PCM_PLOOP
#define SNDRV_DEVICE_TYPE_PCM_CAPTURE SNDRV_MINOR_PCM_CAPTURE #define SNDRV_DEVICE_TYPE_PCM_CAPTURE SNDRV_MINOR_PCM_CAPTURE
#define SNDRV_DEVICE_TYPE_PCM_CLOOP SNDRV_MINOR_PCM_CLOOP
#define SNDRV_DEVICE_TYPE_SEQUENCER SNDRV_MINOR_SEQUENCER #define SNDRV_DEVICE_TYPE_SEQUENCER SNDRV_MINOR_SEQUENCER
#define SNDRV_DEVICE_TYPE_TIMER SNDRV_MINOR_TIMER #define SNDRV_DEVICE_TYPE_TIMER SNDRV_MINOR_TIMER

View File

@ -281,7 +281,7 @@ typedef struct {
struct _snd_pcm_runtime { struct _snd_pcm_runtime {
/* -- Status -- */ /* -- Status -- */
snd_pcm_substream_t *trigger_master; snd_pcm_substream_t *trigger_master;
snd_timestamp_t trigger_tstamp; /* trigger timestamp */ struct timespec trigger_tstamp; /* trigger timestamp */
int overrange; int overrange;
snd_pcm_uframes_t avail_max; snd_pcm_uframes_t avail_max;
snd_pcm_uframes_t hw_ptr_base; /* Position at buffer restart */ snd_pcm_uframes_t hw_ptr_base; /* Position at buffer restart */
@ -306,7 +306,6 @@ struct _snd_pcm_runtime {
unsigned int rate_den; unsigned int rate_den;
/* -- SW params -- */ /* -- SW params -- */
int tstamp_timespec; /* use timeval (0) or timespec (1) */
snd_pcm_tstamp_t tstamp_mode; /* mmap timestamp is updated */ snd_pcm_tstamp_t tstamp_mode; /* mmap timestamp is updated */
unsigned int period_step; unsigned int period_step;
unsigned int sleep_min; /* min ticks to sleep */ unsigned int sleep_min; /* min ticks to sleep */

View File

@ -88,6 +88,7 @@ struct _snd_timer_hardware {
struct _snd_timer { struct _snd_timer {
snd_timer_class_t tmr_class; snd_timer_class_t tmr_class;
snd_card_t *card; snd_card_t *card;
struct module *module;
int tmr_device; int tmr_device;
int tmr_subdevice; int tmr_subdevice;
char id[64]; char id[64];

View File

@ -1,3 +1,3 @@
/* include/version.h. Generated by configure. */ /* include/version.h. Generated by configure. */
#define CONFIG_SND_VERSION "1.0.10rc1" #define CONFIG_SND_VERSION "1.0.10rc3"
#define CONFIG_SND_DATE " (Mon Sep 12 08:13:09 2005 UTC)" #define CONFIG_SND_DATE " (Mon Nov 07 13:30:21 2005 UTC)"

View File

@ -48,6 +48,14 @@ config SND
For more information, see <http://www.alsa-project.org/> For more information, see <http://www.alsa-project.org/>
config SND_AC97_CODEC
tristate
select SND_PCM
select SND_AC97_BUS
config SND_AC97_BUS
tristate
source "sound/core/Kconfig" source "sound/core/Kconfig"
source "sound/drivers/Kconfig" source "sound/drivers/Kconfig"

View File

@ -127,12 +127,6 @@ config SND_DEBUG
help help
Say Y here to enable ALSA debug code. Say Y here to enable ALSA debug code.
config SND_DEBUG_MEMORY
bool "Debug memory"
depends on SND_DEBUG
help
Say Y here to enable debugging of memory allocations.
config SND_DEBUG_DETECT config SND_DEBUG_DETECT
bool "Debug detection" bool "Debug detection"
depends on SND_DEBUG depends on SND_DEBUG

View File

@ -3,8 +3,7 @@
# Copyright (c) 1999,2001 by Jaroslav Kysela <perex@suse.cz> # Copyright (c) 1999,2001 by Jaroslav Kysela <perex@suse.cz>
# #
snd-objs := sound.o init.o memory.o info.o control.o misc.o \ snd-objs := sound.o init.o memory.o info.o control.o misc.o device.o
device.o wrappers.o
ifeq ($(CONFIG_ISA_DMA_API),y) ifeq ($(CONFIG_ISA_DMA_API),y)
snd-objs += isadma.o snd-objs += isadma.o
endif endif

View File

@ -144,7 +144,7 @@ void snd_ctl_notify(snd_card_t *card, unsigned int mask, snd_ctl_elem_id_t *id)
snd_ctl_file_t *ctl; snd_ctl_file_t *ctl;
snd_kctl_event_t *ev; snd_kctl_event_t *ev;
snd_runtime_check(card != NULL && id != NULL, return); snd_assert(card != NULL && id != NULL, return);
read_lock(&card->ctl_files_rwlock); read_lock(&card->ctl_files_rwlock);
#if defined(CONFIG_SND_MIXER_OSS) || defined(CONFIG_SND_MIXER_OSS_MODULE) #if defined(CONFIG_SND_MIXER_OSS) || defined(CONFIG_SND_MIXER_OSS_MODULE)
card->mixer_oss_change_count++; card->mixer_oss_change_count++;
@ -193,8 +193,8 @@ snd_kcontrol_t *snd_ctl_new(snd_kcontrol_t * control, unsigned int access)
snd_kcontrol_t *kctl; snd_kcontrol_t *kctl;
unsigned int idx; unsigned int idx;
snd_runtime_check(control != NULL, return NULL); snd_assert(control != NULL, return NULL);
snd_runtime_check(control->count > 0, return NULL); snd_assert(control->count > 0, return NULL);
kctl = kzalloc(sizeof(*kctl) + sizeof(snd_kcontrol_volatile_t) * control->count, GFP_KERNEL); kctl = kzalloc(sizeof(*kctl) + sizeof(snd_kcontrol_volatile_t) * control->count, GFP_KERNEL);
if (kctl == NULL) if (kctl == NULL)
return NULL; return NULL;
@ -220,7 +220,7 @@ snd_kcontrol_t *snd_ctl_new1(const snd_kcontrol_new_t * ncontrol, void *private_
snd_kcontrol_t kctl; snd_kcontrol_t kctl;
unsigned int access; unsigned int access;
snd_runtime_check(ncontrol != NULL, return NULL); snd_assert(ncontrol != NULL, return NULL);
snd_assert(ncontrol->info != NULL, return NULL); snd_assert(ncontrol->info != NULL, return NULL);
memset(&kctl, 0, sizeof(kctl)); memset(&kctl, 0, sizeof(kctl));
kctl.id.iface = ncontrol->iface; kctl.id.iface = ncontrol->iface;
@ -309,7 +309,7 @@ int snd_ctl_add(snd_card_t * card, snd_kcontrol_t * kcontrol)
snd_ctl_elem_id_t id; snd_ctl_elem_id_t id;
unsigned int idx; unsigned int idx;
snd_runtime_check(card != NULL && kcontrol != NULL, return -EINVAL); snd_assert(card != NULL && kcontrol != NULL, return -EINVAL);
snd_assert(kcontrol->info != NULL, return -EINVAL); snd_assert(kcontrol->info != NULL, return -EINVAL);
id = kcontrol->id; id = kcontrol->id;
down_write(&card->controls_rwsem); down_write(&card->controls_rwsem);
@ -355,7 +355,7 @@ int snd_ctl_remove(snd_card_t * card, snd_kcontrol_t * kcontrol)
snd_ctl_elem_id_t id; snd_ctl_elem_id_t id;
unsigned int idx; unsigned int idx;
snd_runtime_check(card != NULL && kcontrol != NULL, return -EINVAL); snd_assert(card != NULL && kcontrol != NULL, return -EINVAL);
list_del(&kcontrol->list); list_del(&kcontrol->list);
card->controls_count -= kcontrol->count; card->controls_count -= kcontrol->count;
id = kcontrol->id; id = kcontrol->id;
@ -468,7 +468,7 @@ snd_kcontrol_t *snd_ctl_find_numid(snd_card_t * card, unsigned int numid)
struct list_head *list; struct list_head *list;
snd_kcontrol_t *kctl; snd_kcontrol_t *kctl;
snd_runtime_check(card != NULL && numid != 0, return NULL); snd_assert(card != NULL && numid != 0, return NULL);
list_for_each(list, &card->controls) { list_for_each(list, &card->controls) {
kctl = snd_kcontrol(list); kctl = snd_kcontrol(list);
if (kctl->id.numid <= numid && kctl->id.numid + kctl->count > numid) if (kctl->id.numid <= numid && kctl->id.numid + kctl->count > numid)
@ -494,7 +494,7 @@ snd_kcontrol_t *snd_ctl_find_id(snd_card_t * card, snd_ctl_elem_id_t *id)
struct list_head *list; struct list_head *list;
snd_kcontrol_t *kctl; snd_kcontrol_t *kctl;
snd_runtime_check(card != NULL && id != NULL, return NULL); snd_assert(card != NULL && id != NULL, return NULL);
if (id->numid != 0) if (id->numid != 0)
return snd_ctl_find_numid(card, id->numid); return snd_ctl_find_numid(card, id->numid);
list_for_each(list, &card->controls) { list_for_each(list, &card->controls) {
@ -1215,7 +1215,7 @@ static int _snd_ctl_unregister_ioctl(snd_kctl_ioctl_func_t fcn, struct list_head
struct list_head *list; struct list_head *list;
snd_kctl_ioctl_t *p; snd_kctl_ioctl_t *p;
snd_runtime_check(fcn != NULL, return -EINVAL); snd_assert(fcn != NULL, return -EINVAL);
down_write(&snd_ioctl_rwsem); down_write(&snd_ioctl_rwsem);
list_for_each(list, lists) { list_for_each(list, lists) {
p = list_entry(list, snd_kctl_ioctl_t, list); p = list_entry(list, snd_kctl_ioctl_t, list);

View File

@ -81,20 +81,16 @@ static int snd_hwdep_open(struct inode *inode, struct file * file)
int err; int err;
wait_queue_t wait; wait_queue_t wait;
switch (major) { if (major == snd_major) {
case CONFIG_SND_MAJOR:
cardnum = SNDRV_MINOR_CARD(iminor(inode)); cardnum = SNDRV_MINOR_CARD(iminor(inode));
device = SNDRV_MINOR_DEVICE(iminor(inode)) - SNDRV_MINOR_HWDEP; device = SNDRV_MINOR_DEVICE(iminor(inode)) - SNDRV_MINOR_HWDEP;
break;
#ifdef CONFIG_SND_OSSEMUL #ifdef CONFIG_SND_OSSEMUL
case SOUND_MAJOR: } else if (major == SOUND_MAJOR) {
cardnum = SNDRV_MINOR_OSS_CARD(iminor(inode)); cardnum = SNDRV_MINOR_OSS_CARD(iminor(inode));
device = 0; device = 0;
break;
#endif #endif
default: } else
return -ENXIO; return -ENXIO;
}
cardnum %= SNDRV_CARDS; cardnum %= SNDRV_CARDS;
device %= SNDRV_MINOR_HWDEPS; device %= SNDRV_MINOR_HWDEPS;
hw = snd_hwdep_devices[(cardnum * SNDRV_MINOR_HWDEPS) + device]; hw = snd_hwdep_devices[(cardnum * SNDRV_MINOR_HWDEPS) + device];

View File

@ -566,7 +566,6 @@ int __init snd_info_init(void)
} }
#endif #endif
snd_info_version_init(); snd_info_version_init();
snd_memory_info_init();
snd_minor_info_init(); snd_minor_info_init();
snd_minor_info_oss_init(); snd_minor_info_oss_init();
snd_card_info_init(); snd_card_info_init();
@ -578,7 +577,6 @@ int __exit snd_info_done(void)
snd_card_info_done(); snd_card_info_done();
snd_minor_info_oss_done(); snd_minor_info_oss_done();
snd_minor_info_done(); snd_minor_info_done();
snd_memory_info_done();
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)

View File

@ -420,7 +420,7 @@ int snd_card_register(snd_card_t * card)
int err; int err;
snd_info_entry_t *entry; snd_info_entry_t *entry;
snd_runtime_check(card != NULL, return -EINVAL); snd_assert(card != NULL, return -EINVAL);
if ((err = snd_device_register_all(card)) < 0) if ((err = snd_device_register_all(card)) < 0)
return err; return err;
write_lock(&snd_card_rwlock); write_lock(&snd_card_rwlock);
@ -524,7 +524,8 @@ int __init snd_card_info_init(void)
snd_info_entry_t *entry; snd_info_entry_t *entry;
entry = snd_info_create_module_entry(THIS_MODULE, "cards", NULL); entry = snd_info_create_module_entry(THIS_MODULE, "cards", NULL);
snd_runtime_check(entry != NULL, return -ENOMEM); if (! entry)
return -ENOMEM;
entry->c.text.read_size = PAGE_SIZE; entry->c.text.read_size = PAGE_SIZE;
entry->c.text.read = snd_card_info_read; entry->c.text.read = snd_card_info_read;
if (snd_info_register(entry) < 0) { if (snd_info_register(entry) < 0) {
@ -840,7 +841,7 @@ static int snd_generic_resume(struct device *dev)
card = get_snd_generic_card(dev); card = get_snd_generic_card(dev);
if (card->power_state == SNDRV_CTL_POWER_D0) if (card->power_state == SNDRV_CTL_POWER_D0)
return 0; return 0;
if (card->pm_suspend) if (card->pm_resume)
card->pm_resume(card); card->pm_resume(card);
snd_power_change_state(card, SNDRV_CTL_POWER_D0); snd_power_change_state(card, SNDRV_CTL_POWER_D0);
return 0; return 0;

View File

@ -1,7 +1,7 @@
/* /*
* Copyright (c) by Jaroslav Kysela <perex@suse.cz> * Copyright (c) by Jaroslav Kysela <perex@suse.cz>
* *
* Memory allocation helpers. * Misc memory accessors
* *
* *
* This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify
@ -20,221 +20,9 @@
* *
*/ */
#include <sound/driver.h> #include <linux/config.h>
#include <asm/io.h> #include <asm/io.h>
#include <asm/uaccess.h> #include <asm/uaccess.h>
#include <linux/init.h>
#include <linux/slab.h>
#include <linux/time.h>
#include <linux/pci.h>
#include <sound/core.h>
#include <sound/info.h>
/*
* memory allocation helpers and debug routines
*/
#ifdef CONFIG_SND_DEBUG_MEMORY
struct snd_alloc_track {
unsigned long magic;
void *caller;
size_t size;
struct list_head list;
long data[0];
};
#define snd_alloc_track_entry(obj) (struct snd_alloc_track *)((char*)obj - (unsigned long)((struct snd_alloc_track *)0)->data)
static long snd_alloc_kmalloc;
static long snd_alloc_vmalloc;
static LIST_HEAD(snd_alloc_kmalloc_list);
static LIST_HEAD(snd_alloc_vmalloc_list);
static DEFINE_SPINLOCK(snd_alloc_kmalloc_lock);
static DEFINE_SPINLOCK(snd_alloc_vmalloc_lock);
#define KMALLOC_MAGIC 0x87654321
#define VMALLOC_MAGIC 0x87654320
static snd_info_entry_t *snd_memory_info_entry;
void __init snd_memory_init(void)
{
snd_alloc_kmalloc = 0;
snd_alloc_vmalloc = 0;
}
void snd_memory_done(void)
{
struct list_head *head;
struct snd_alloc_track *t;
if (snd_alloc_kmalloc > 0)
snd_printk(KERN_ERR "Not freed snd_alloc_kmalloc = %li\n", snd_alloc_kmalloc);
if (snd_alloc_vmalloc > 0)
snd_printk(KERN_ERR "Not freed snd_alloc_vmalloc = %li\n", snd_alloc_vmalloc);
list_for_each_prev(head, &snd_alloc_kmalloc_list) {
t = list_entry(head, struct snd_alloc_track, list);
if (t->magic != KMALLOC_MAGIC) {
snd_printk(KERN_ERR "Corrupted kmalloc\n");
break;
}
snd_printk(KERN_ERR "kmalloc(%ld) from %p not freed\n", (long) t->size, t->caller);
}
list_for_each_prev(head, &snd_alloc_vmalloc_list) {
t = list_entry(head, struct snd_alloc_track, list);
if (t->magic != VMALLOC_MAGIC) {
snd_printk(KERN_ERR "Corrupted vmalloc\n");
break;
}
snd_printk(KERN_ERR "vmalloc(%ld) from %p not freed\n", (long) t->size, t->caller);
}
}
static void *__snd_kmalloc(size_t size, gfp_t flags, void *caller)
{
unsigned long cpu_flags;
struct snd_alloc_track *t;
void *ptr;
ptr = snd_wrapper_kmalloc(size + sizeof(struct snd_alloc_track), flags);
if (ptr != NULL) {
t = (struct snd_alloc_track *)ptr;
t->magic = KMALLOC_MAGIC;
t->caller = caller;
spin_lock_irqsave(&snd_alloc_kmalloc_lock, cpu_flags);
list_add_tail(&t->list, &snd_alloc_kmalloc_list);
spin_unlock_irqrestore(&snd_alloc_kmalloc_lock, cpu_flags);
t->size = size;
snd_alloc_kmalloc += size;
ptr = t->data;
}
return ptr;
}
#define _snd_kmalloc(size, flags) __snd_kmalloc((size), (flags), __builtin_return_address(0));
void *snd_hidden_kmalloc(size_t size, gfp_t flags)
{
return _snd_kmalloc(size, flags);
}
void *snd_hidden_kzalloc(size_t size, gfp_t flags)
{
void *ret = _snd_kmalloc(size, flags);
if (ret)
memset(ret, 0, size);
return ret;
}
EXPORT_SYMBOL(snd_hidden_kzalloc);
void *snd_hidden_kcalloc(size_t n, size_t size, gfp_t flags)
{
void *ret = NULL;
if (n != 0 && size > INT_MAX / n)
return ret;
return snd_hidden_kzalloc(n * size, flags);
}
void snd_hidden_kfree(const void *obj)
{
unsigned long flags;
struct snd_alloc_track *t;
if (obj == NULL)
return;
t = snd_alloc_track_entry(obj);
if (t->magic != KMALLOC_MAGIC) {
snd_printk(KERN_WARNING "bad kfree (called from %p)\n", __builtin_return_address(0));
return;
}
spin_lock_irqsave(&snd_alloc_kmalloc_lock, flags);
list_del(&t->list);
spin_unlock_irqrestore(&snd_alloc_kmalloc_lock, flags);
t->magic = 0;
snd_alloc_kmalloc -= t->size;
obj = t;
snd_wrapper_kfree(obj);
}
void *snd_hidden_vmalloc(unsigned long size)
{
void *ptr;
ptr = snd_wrapper_vmalloc(size + sizeof(struct snd_alloc_track));
if (ptr) {
struct snd_alloc_track *t = (struct snd_alloc_track *)ptr;
t->magic = VMALLOC_MAGIC;
t->caller = __builtin_return_address(0);
spin_lock(&snd_alloc_vmalloc_lock);
list_add_tail(&t->list, &snd_alloc_vmalloc_list);
spin_unlock(&snd_alloc_vmalloc_lock);
t->size = size;
snd_alloc_vmalloc += size;
ptr = t->data;
}
return ptr;
}
void snd_hidden_vfree(void *obj)
{
struct snd_alloc_track *t;
if (obj == NULL)
return;
t = snd_alloc_track_entry(obj);
if (t->magic != VMALLOC_MAGIC) {
snd_printk(KERN_ERR "bad vfree (called from %p)\n", __builtin_return_address(0));
return;
}
spin_lock(&snd_alloc_vmalloc_lock);
list_del(&t->list);
spin_unlock(&snd_alloc_vmalloc_lock);
t->magic = 0;
snd_alloc_vmalloc -= t->size;
obj = t;
snd_wrapper_vfree(obj);
}
char *snd_hidden_kstrdup(const char *s, gfp_t flags)
{
int len;
char *buf;
if (!s) return NULL;
len = strlen(s) + 1;
buf = _snd_kmalloc(len, flags);
if (buf)
memcpy(buf, s, len);
return buf;
}
static void snd_memory_info_read(snd_info_entry_t *entry, snd_info_buffer_t * buffer)
{
snd_iprintf(buffer, "kmalloc: %li bytes\n", snd_alloc_kmalloc);
snd_iprintf(buffer, "vmalloc: %li bytes\n", snd_alloc_vmalloc);
}
int __init snd_memory_info_init(void)
{
snd_info_entry_t *entry;
entry = snd_info_create_module_entry(THIS_MODULE, "meminfo", NULL);
if (entry) {
entry->c.text.read_size = 256;
entry->c.text.read = snd_memory_info_read;
if (snd_info_register(entry) < 0) {
snd_info_free_entry(entry);
entry = NULL;
}
}
snd_memory_info_entry = entry;
return 0;
}
int __exit snd_memory_info_done(void)
{
if (snd_memory_info_entry)
snd_info_unregister(snd_memory_info_entry);
return 0;
}
#endif /* CONFIG_SND_DEBUG_MEMORY */
/** /**
* copy_to_user_fromio - copy data from mmio-space to user-space * copy_to_user_fromio - copy data from mmio-space to user-space

View File

@ -23,17 +23,15 @@
#include <linux/init.h> #include <linux/init.h>
#include <linux/sched.h> #include <linux/sched.h>
#include <linux/time.h> #include <linux/time.h>
#include <linux/ioport.h>
#include <sound/core.h> #include <sound/core.h>
int snd_task_name(struct task_struct *task, char *name, size_t size) void release_and_free_resource(struct resource *res)
{ {
unsigned int idx; if (res) {
release_resource(res);
snd_assert(task != NULL && name != NULL && size >= 2, return -EINVAL); kfree(res);
for (idx = 0; idx < sizeof(task->comm) && idx + 1 < size; idx++) }
name[idx] = task->comm[idx];
name[idx] = '\0';
return 0;
} }
#ifdef CONFIG_SND_VERBOSE_PRINTK #ifdef CONFIG_SND_VERBOSE_PRINTK

View File

@ -521,9 +521,13 @@ static void snd_mixer_oss_get_volume1_vol(snd_mixer_oss_file_t *fmixer,
uctl = kzalloc(sizeof(*uctl), GFP_KERNEL); uctl = kzalloc(sizeof(*uctl), GFP_KERNEL);
if (uinfo == NULL || uctl == NULL) if (uinfo == NULL || uctl == NULL)
goto __unalloc; goto __unalloc;
snd_runtime_check(!kctl->info(kctl, uinfo), goto __unalloc); if (kctl->info(kctl, uinfo))
snd_runtime_check(!kctl->get(kctl, uctl), goto __unalloc); goto __unalloc;
snd_runtime_check(uinfo->type != SNDRV_CTL_ELEM_TYPE_BOOLEAN || uinfo->value.integer.min != 0 || uinfo->value.integer.max != 1, goto __unalloc); if (kctl->get(kctl, uctl))
goto __unalloc;
if (uinfo->type == SNDRV_CTL_ELEM_TYPE_BOOLEAN &&
uinfo->value.integer.min == 0 && uinfo->value.integer.max == 1)
goto __unalloc;
*left = snd_mixer_oss_conv1(uctl->value.integer.value[0], uinfo->value.integer.min, uinfo->value.integer.max, &pslot->volume[0]); *left = snd_mixer_oss_conv1(uctl->value.integer.value[0], uinfo->value.integer.min, uinfo->value.integer.max, &pslot->volume[0]);
if (uinfo->count > 1) if (uinfo->count > 1)
*right = snd_mixer_oss_conv1(uctl->value.integer.value[1], uinfo->value.integer.min, uinfo->value.integer.max, &pslot->volume[1]); *right = snd_mixer_oss_conv1(uctl->value.integer.value[1], uinfo->value.integer.min, uinfo->value.integer.max, &pslot->volume[1]);
@ -555,8 +559,10 @@ static void snd_mixer_oss_get_volume1_sw(snd_mixer_oss_file_t *fmixer,
uctl = kzalloc(sizeof(*uctl), GFP_KERNEL); uctl = kzalloc(sizeof(*uctl), GFP_KERNEL);
if (uinfo == NULL || uctl == NULL) if (uinfo == NULL || uctl == NULL)
goto __unalloc; goto __unalloc;
snd_runtime_check(!kctl->info(kctl, uinfo), goto __unalloc); if (kctl->info(kctl, uinfo))
snd_runtime_check(!kctl->get(kctl, uctl), goto __unalloc); goto __unalloc;
if (kctl->get(kctl, uctl))
goto __unalloc;
if (!uctl->value.integer.value[0]) { if (!uctl->value.integer.value[0]) {
*left = 0; *left = 0;
if (uinfo->count == 1) if (uinfo->count == 1)
@ -616,12 +622,16 @@ static void snd_mixer_oss_put_volume1_vol(snd_mixer_oss_file_t *fmixer,
uctl = kzalloc(sizeof(*uctl), GFP_KERNEL); uctl = kzalloc(sizeof(*uctl), GFP_KERNEL);
if (uinfo == NULL || uctl == NULL) if (uinfo == NULL || uctl == NULL)
goto __unalloc; goto __unalloc;
snd_runtime_check(!kctl->info(kctl, uinfo), goto __unalloc); if (kctl->info(kctl, uinfo))
snd_runtime_check(uinfo->type != SNDRV_CTL_ELEM_TYPE_BOOLEAN || uinfo->value.integer.min != 0 || uinfo->value.integer.max != 1, goto __unalloc); goto __unalloc;
if (uinfo->type == SNDRV_CTL_ELEM_TYPE_BOOLEAN &&
uinfo->value.integer.min == 0 && uinfo->value.integer.max == 1)
goto __unalloc;
uctl->value.integer.value[0] = snd_mixer_oss_conv2(left, uinfo->value.integer.min, uinfo->value.integer.max); uctl->value.integer.value[0] = snd_mixer_oss_conv2(left, uinfo->value.integer.min, uinfo->value.integer.max);
if (uinfo->count > 1) if (uinfo->count > 1)
uctl->value.integer.value[1] = snd_mixer_oss_conv2(right, uinfo->value.integer.min, uinfo->value.integer.max); uctl->value.integer.value[1] = snd_mixer_oss_conv2(right, uinfo->value.integer.min, uinfo->value.integer.max);
snd_runtime_check((res = kctl->put(kctl, uctl)) >= 0, goto __unalloc); if ((res = kctl->put(kctl, uctl)) < 0)
goto __unalloc;
if (res > 0) if (res > 0)
snd_ctl_notify(card, SNDRV_CTL_EVENT_MASK_VALUE, &kctl->id); snd_ctl_notify(card, SNDRV_CTL_EVENT_MASK_VALUE, &kctl->id);
__unalloc: __unalloc:
@ -653,7 +663,8 @@ static void snd_mixer_oss_put_volume1_sw(snd_mixer_oss_file_t *fmixer,
uctl = kzalloc(sizeof(*uctl), GFP_KERNEL); uctl = kzalloc(sizeof(*uctl), GFP_KERNEL);
if (uinfo == NULL || uctl == NULL) if (uinfo == NULL || uctl == NULL)
goto __unalloc; goto __unalloc;
snd_runtime_check(!kctl->info(kctl, uinfo), goto __unalloc); if (kctl->info(kctl, uinfo))
goto __unalloc;
if (uinfo->count > 1) { if (uinfo->count > 1) {
uctl->value.integer.value[0] = left > 0 ? 1 : 0; uctl->value.integer.value[0] = left > 0 ? 1 : 0;
uctl->value.integer.value[route ? 3 : 1] = right > 0 ? 1 : 0; uctl->value.integer.value[route ? 3 : 1] = right > 0 ? 1 : 0;
@ -664,7 +675,8 @@ static void snd_mixer_oss_put_volume1_sw(snd_mixer_oss_file_t *fmixer,
} else { } else {
uctl->value.integer.value[0] = (left > 0 || right > 0) ? 1 : 0; uctl->value.integer.value[0] = (left > 0 || right > 0) ? 1 : 0;
} }
snd_runtime_check((res = kctl->put(kctl, uctl)) >= 0, goto __unalloc); if ((res = kctl->put(kctl, uctl)) < 0)
goto __unalloc;
if (res > 0) if (res > 0)
snd_ctl_notify(card, SNDRV_CTL_EVENT_MASK_VALUE, &kctl->id); snd_ctl_notify(card, SNDRV_CTL_EVENT_MASK_VALUE, &kctl->id);
__unalloc: __unalloc:
@ -776,9 +788,14 @@ static int snd_mixer_oss_get_recsrc2(snd_mixer_oss_file_t *fmixer, unsigned int
} }
down_read(&card->controls_rwsem); down_read(&card->controls_rwsem);
kctl = snd_mixer_oss_test_id(mixer, "Capture Source", 0); kctl = snd_mixer_oss_test_id(mixer, "Capture Source", 0);
snd_runtime_check(kctl != NULL, err = -ENOENT; goto __unlock); if (! kctl) {
snd_runtime_check(!(err = kctl->info(kctl, uinfo)), goto __unlock); err = -ENOENT;
snd_runtime_check(!(err = kctl->get(kctl, uctl)), goto __unlock); goto __unlock;
}
if ((err = kctl->info(kctl, uinfo)) < 0)
goto __unlock;
if ((err = kctl->get(kctl, uctl)) < 0)
goto __unlock;
for (idx = 0; idx < 32; idx++) { for (idx = 0; idx < 32; idx++) {
if (!(mixer->mask_recsrc & (1 << idx))) if (!(mixer->mask_recsrc & (1 << idx)))
continue; continue;
@ -821,8 +838,12 @@ static int snd_mixer_oss_put_recsrc2(snd_mixer_oss_file_t *fmixer, unsigned int
} }
down_read(&card->controls_rwsem); down_read(&card->controls_rwsem);
kctl = snd_mixer_oss_test_id(mixer, "Capture Source", 0); kctl = snd_mixer_oss_test_id(mixer, "Capture Source", 0);
snd_runtime_check(kctl != NULL, err = -ENOENT; goto __unlock); if (! kctl) {
snd_runtime_check(!(err = kctl->info(kctl, uinfo)), goto __unlock); err = -ENOENT;
goto __unlock;
}
if ((err = kctl->info(kctl, uinfo)) < 0)
goto __unlock;
for (idx = 0; idx < 32; idx++) { for (idx = 0; idx < 32; idx++) {
if (!(mixer->mask_recsrc & (1 << idx))) if (!(mixer->mask_recsrc & (1 << idx)))
continue; continue;
@ -836,10 +857,11 @@ static int snd_mixer_oss_put_recsrc2(snd_mixer_oss_file_t *fmixer, unsigned int
break; break;
slot = NULL; slot = NULL;
} }
snd_runtime_check(slot != NULL, goto __unlock); if (! slot)
goto __unlock;
for (idx = 0; idx < uinfo->count; idx++) for (idx = 0; idx < uinfo->count; idx++)
uctl->value.enumerated.item[idx] = slot->capture_item; uctl->value.enumerated.item[idx] = slot->capture_item;
snd_runtime_check((err = kctl->put(kctl, uctl)) >= 0, ); err = kctl->put(kctl, uctl);
if (err > 0) if (err > 0)
snd_ctl_notify(fmixer->card, SNDRV_CTL_EVENT_MASK_VALUE, &kctl->id); snd_ctl_notify(fmixer->card, SNDRV_CTL_EVENT_MASK_VALUE, &kctl->id);
err = 0; err = 0;
@ -1008,7 +1030,8 @@ static int snd_mixer_oss_build_input(snd_mixer_oss_t *mixer, struct snd_mixer_os
up_read(&mixer->card->controls_rwsem); up_read(&mixer->card->controls_rwsem);
if (slot.present != 0) { if (slot.present != 0) {
pslot = (struct slot *)kmalloc(sizeof(slot), GFP_KERNEL); pslot = (struct slot *)kmalloc(sizeof(slot), GFP_KERNEL);
snd_runtime_check(pslot != NULL, return -ENOMEM); if (! pslot)
return -ENOMEM;
*pslot = slot; *pslot = slot;
pslot->signature = SNDRV_MIXER_OSS_SIGNATURE; pslot->signature = SNDRV_MIXER_OSS_SIGNATURE;
pslot->assigned = ptr; pslot->assigned = ptr;
@ -1271,7 +1294,8 @@ static int snd_mixer_oss_notify_handler(snd_card_t * card, int cmd)
card, 0, card, 0,
&snd_mixer_oss_reg, &snd_mixer_oss_reg,
name)) < 0) { name)) < 0) {
snd_printk("unable to register OSS mixer device %i:%i\n", card->number, 0); snd_printk(KERN_ERR "unable to register OSS mixer device %i:%i\n",
card->number, 0);
kfree(mixer); kfree(mixer);
return err; return err;
} }

View File

@ -1821,6 +1821,17 @@ static int snd_pcm_oss_open_file(struct file *file,
} }
static int snd_task_name(struct task_struct *task, char *name, size_t size)
{
unsigned int idx;
snd_assert(task != NULL && name != NULL && size >= 2, return -EINVAL);
for (idx = 0; idx < sizeof(task->comm) && idx + 1 < size; idx++)
name[idx] = task->comm[idx];
name[idx] = '\0';
return 0;
}
static int snd_pcm_oss_open(struct inode *inode, struct file *file) static int snd_pcm_oss_open(struct inode *inode, struct file *file)
{ {
int minor = iminor(inode); int minor = iminor(inode);
@ -2446,7 +2457,8 @@ static void register_oss_dsp(snd_pcm_t *pcm, int index)
if (snd_register_oss_device(SNDRV_OSS_DEVICE_TYPE_PCM, if (snd_register_oss_device(SNDRV_OSS_DEVICE_TYPE_PCM,
pcm->card, index, &snd_pcm_oss_reg, pcm->card, index, &snd_pcm_oss_reg,
name) < 0) { name) < 0) {
snd_printk("unable to register OSS PCM device %i:%i\n", pcm->card->number, pcm->device); snd_printk(KERN_ERR "unable to register OSS PCM device %i:%i\n",
pcm->card->number, pcm->device);
} }
} }
@ -2528,11 +2540,13 @@ static int __init alsa_pcm_oss_init(void)
/* check device map table */ /* check device map table */
for (i = 0; i < SNDRV_CARDS; i++) { for (i = 0; i < SNDRV_CARDS; i++) {
if (dsp_map[i] < 0 || dsp_map[i] >= SNDRV_PCM_DEVICES) { if (dsp_map[i] < 0 || dsp_map[i] >= SNDRV_PCM_DEVICES) {
snd_printk("invalid dsp_map[%d] = %d\n", i, dsp_map[i]); snd_printk(KERN_ERR "invalid dsp_map[%d] = %d\n",
i, dsp_map[i]);
dsp_map[i] = 0; dsp_map[i] = 0;
} }
if (adsp_map[i] < 0 || adsp_map[i] >= SNDRV_PCM_DEVICES) { if (adsp_map[i] < 0 || adsp_map[i] >= SNDRV_PCM_DEVICES) {
snd_printk("invalid adsp_map[%d] = %d\n", i, adsp_map[i]); snd_printk(KERN_ERR "invalid adsp_map[%d] = %d\n",
i, adsp_map[i]);
adsp_map[i] = 1; adsp_map[i] = 1;
} }
} }

View File

@ -273,7 +273,8 @@ static void snd_pcm_proc_info_read(snd_pcm_substream_t *substream, snd_info_buff
snd_pcm_info_t *info; snd_pcm_info_t *info;
int err; int err;
snd_runtime_check(substream, return); if (! substream)
return;
info = kmalloc(sizeof(*info), GFP_KERNEL); info = kmalloc(sizeof(*info), GFP_KERNEL);
if (! info) { if (! info) {

View File

@ -152,13 +152,12 @@ static inline snd_pcm_uframes_t snd_pcm_update_hw_ptr_pos(snd_pcm_substream_t *s
if (pos == SNDRV_PCM_POS_XRUN) if (pos == SNDRV_PCM_POS_XRUN)
return pos; /* XRUN */ return pos; /* XRUN */
if (runtime->tstamp_mode & SNDRV_PCM_TSTAMP_MMAP) if (runtime->tstamp_mode & SNDRV_PCM_TSTAMP_MMAP)
snd_timestamp_now((snd_timestamp_t*)&runtime->status->tstamp, runtime->tstamp_timespec); getnstimeofday((struct timespec *)&runtime->status->tstamp);
#ifdef CONFIG_SND_DEBUG #ifdef CONFIG_SND_DEBUG
if (pos >= runtime->buffer_size) { if (pos >= runtime->buffer_size) {
snd_printk(KERN_ERR "BUG: stream = %i, pos = 0x%lx, buffer size = 0x%lx, period size = 0x%lx\n", substream->stream, pos, runtime->buffer_size, runtime->period_size); snd_printk(KERN_ERR "BUG: stream = %i, pos = 0x%lx, buffer size = 0x%lx, period size = 0x%lx\n", substream->stream, pos, runtime->buffer_size, runtime->period_size);
} else }
#endif #endif
snd_runtime_check(pos < runtime->buffer_size, return 0);
pos -= pos % runtime->min_align; pos -= pos % runtime->min_align;
return pos; return pos;
} }

View File

@ -565,9 +565,9 @@ int snd_pcm_status(snd_pcm_substream_t *substream,
if (runtime->tstamp_mode & SNDRV_PCM_TSTAMP_MMAP) if (runtime->tstamp_mode & SNDRV_PCM_TSTAMP_MMAP)
status->tstamp = runtime->status->tstamp; status->tstamp = runtime->status->tstamp;
else else
snd_timestamp_now(&status->tstamp, runtime->tstamp_timespec); getnstimeofday(&status->tstamp);
} else } else
snd_timestamp_now(&status->tstamp, runtime->tstamp_timespec); getnstimeofday(&status->tstamp);
status->appl_ptr = runtime->control->appl_ptr; status->appl_ptr = runtime->control->appl_ptr;
status->hw_ptr = runtime->status->hw_ptr; status->hw_ptr = runtime->status->hw_ptr;
if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
@ -652,7 +652,7 @@ static void snd_pcm_trigger_tstamp(snd_pcm_substream_t *substream)
if (runtime->trigger_master == NULL) if (runtime->trigger_master == NULL)
return; return;
if (runtime->trigger_master == substream) { if (runtime->trigger_master == substream) {
snd_timestamp_now(&runtime->trigger_tstamp, runtime->tstamp_timespec); getnstimeofday(&runtime->trigger_tstamp);
} else { } else {
snd_pcm_trigger_tstamp(runtime->trigger_master); snd_pcm_trigger_tstamp(runtime->trigger_master);
runtime->trigger_tstamp = runtime->trigger_master->runtime->trigger_tstamp; runtime->trigger_tstamp = runtime->trigger_master->runtime->trigger_tstamp;
@ -1522,7 +1522,6 @@ static int snd_pcm_drop(snd_pcm_substream_t *substream)
/* WARNING: Don't forget to fput back the file */ /* WARNING: Don't forget to fput back the file */
extern int snd_major;
static struct file *snd_pcm_file_fd(int fd) static struct file *snd_pcm_file_fd(int fd)
{ {
struct file *file; struct file *file;
@ -2053,7 +2052,8 @@ static int snd_pcm_open(struct inode *inode, struct file *file)
snd_pcm_file_t *pcm_file; snd_pcm_file_t *pcm_file;
wait_queue_t wait; wait_queue_t wait;
snd_runtime_check(device >= SNDRV_MINOR_PCM_PLAYBACK && device < SNDRV_MINOR_DEVICES, return -ENXIO); if (device < SNDRV_MINOR_PCM_PLAYBACK || device >= SNDRV_MINOR_DEVICES)
return -ENXIO;
pcm = snd_pcm_devices[(cardnum * SNDRV_PCM_DEVICES) + (device % SNDRV_MINOR_PCMS)]; pcm = snd_pcm_devices[(cardnum * SNDRV_PCM_DEVICES) + (device % SNDRV_MINOR_PCMS)];
if (pcm == NULL) { if (pcm == NULL) {
err = -ENODEV; err = -ENODEV;
@ -2445,14 +2445,8 @@ static int snd_pcm_common_ioctl1(snd_pcm_substream_t *substream,
return put_user(SNDRV_PCM_VERSION, (int __user *)arg) ? -EFAULT : 0; return put_user(SNDRV_PCM_VERSION, (int __user *)arg) ? -EFAULT : 0;
case SNDRV_PCM_IOCTL_INFO: case SNDRV_PCM_IOCTL_INFO:
return snd_pcm_info_user(substream, arg); return snd_pcm_info_user(substream, arg);
case SNDRV_PCM_IOCTL_TSTAMP: case SNDRV_PCM_IOCTL_TSTAMP: /* just for compatibility */
{
int xarg;
if (get_user(xarg, (int __user *)arg))
return -EFAULT;
substream->runtime->tstamp_timespec = xarg ? 1 : 0;
return 0; return 0;
}
case SNDRV_PCM_IOCTL_HW_REFINE: case SNDRV_PCM_IOCTL_HW_REFINE:
return snd_pcm_hw_refine_user(substream, arg); return snd_pcm_hw_refine_user(substream, arg);
case SNDRV_PCM_IOCTL_HW_PARAMS: case SNDRV_PCM_IOCTL_HW_PARAMS:

View File

@ -378,24 +378,20 @@ static int snd_rawmidi_open(struct inode *inode, struct file *file)
struct list_head *list; struct list_head *list;
snd_ctl_file_t *kctl; snd_ctl_file_t *kctl;
switch (maj) { if (maj == snd_major) {
case CONFIG_SND_MAJOR:
cardnum = SNDRV_MINOR_CARD(iminor(inode)); cardnum = SNDRV_MINOR_CARD(iminor(inode));
cardnum %= SNDRV_CARDS; cardnum %= SNDRV_CARDS;
device = SNDRV_MINOR_DEVICE(iminor(inode)) - SNDRV_MINOR_RAWMIDI; device = SNDRV_MINOR_DEVICE(iminor(inode)) - SNDRV_MINOR_RAWMIDI;
device %= SNDRV_MINOR_RAWMIDIS; device %= SNDRV_MINOR_RAWMIDIS;
break;
#ifdef CONFIG_SND_OSSEMUL #ifdef CONFIG_SND_OSSEMUL
case SOUND_MAJOR: } else if (maj == SOUND_MAJOR) {
cardnum = SNDRV_MINOR_OSS_CARD(iminor(inode)); cardnum = SNDRV_MINOR_OSS_CARD(iminor(inode));
cardnum %= SNDRV_CARDS; cardnum %= SNDRV_CARDS;
device = SNDRV_MINOR_OSS_DEVICE(iminor(inode)) == SNDRV_MINOR_OSS_MIDI ? device = SNDRV_MINOR_OSS_DEVICE(iminor(inode)) == SNDRV_MINOR_OSS_MIDI ?
midi_map[cardnum] : amidi_map[cardnum]; midi_map[cardnum] : amidi_map[cardnum];
break;
#endif #endif
default: } else
return -ENXIO; return -ENXIO;
}
rmidi = snd_rawmidi_devices[(cardnum * SNDRV_RAWMIDI_DEVICES) + device]; rmidi = snd_rawmidi_devices[(cardnum * SNDRV_RAWMIDI_DEVICES) + device];
if (rmidi == NULL) if (rmidi == NULL)
@ -411,7 +407,7 @@ static int snd_rawmidi_open(struct inode *inode, struct file *file)
if (err < 0) if (err < 0)
return -ENODEV; return -ENODEV;
fflags = snd_rawmidi_file_flags(file); fflags = snd_rawmidi_file_flags(file);
if ((file->f_flags & O_APPEND) || maj != CONFIG_SND_MAJOR) /* OSS emul? */ if ((file->f_flags & O_APPEND) || maj == SOUND_MAJOR) /* OSS emul? */
fflags |= SNDRV_RAWMIDI_LFLG_APPEND; fflags |= SNDRV_RAWMIDI_LFLG_APPEND;
fflags |= SNDRV_RAWMIDI_LFLG_NOOPENLOCK; fflags |= SNDRV_RAWMIDI_LFLG_NOOPENLOCK;
rawmidi_file = kmalloc(sizeof(*rawmidi_file), GFP_KERNEL); rawmidi_file = kmalloc(sizeof(*rawmidi_file), GFP_KERNEL);

View File

@ -60,7 +60,6 @@ static struct _snd_timer_hardware rtc_hw = {
static int rtctimer_freq = RTC_FREQ; /* frequency */ static int rtctimer_freq = RTC_FREQ; /* frequency */
static snd_timer_t *rtctimer; static snd_timer_t *rtctimer;
static atomic_t rtc_inc = ATOMIC_INIT(0);
static rtc_task_t rtc_task; static rtc_task_t rtc_task;
@ -94,7 +93,6 @@ rtctimer_start(snd_timer_t *timer)
snd_assert(rtc != NULL, return -EINVAL); snd_assert(rtc != NULL, return -EINVAL);
rtc_control(rtc, RTC_IRQP_SET, rtctimer_freq); rtc_control(rtc, RTC_IRQP_SET, rtctimer_freq);
rtc_control(rtc, RTC_PIE_ON, 0); rtc_control(rtc, RTC_PIE_ON, 0);
atomic_set(&rtc_inc, 0);
return 0; return 0;
} }
@ -112,12 +110,7 @@ rtctimer_stop(snd_timer_t *timer)
*/ */
static void rtctimer_interrupt(void *private_data) static void rtctimer_interrupt(void *private_data)
{ {
int ticks; snd_timer_interrupt(private_data, 1);
atomic_inc(&rtc_inc);
ticks = atomic_read(&rtc_inc);
snd_timer_interrupt((snd_timer_t*)private_data, ticks);
atomic_sub(ticks, &rtc_inc);
} }
@ -126,17 +119,13 @@ static void rtctimer_interrupt(void *private_data)
*/ */
static int __init rtctimer_init(void) static int __init rtctimer_init(void)
{ {
int order, err; int err;
snd_timer_t *timer; snd_timer_t *timer;
if (rtctimer_freq < 2 || rtctimer_freq > 8192) { if (rtctimer_freq < 2 || rtctimer_freq > 8192 ||
snd_printk(KERN_ERR "rtctimer: invalid frequency %d\n", rtctimer_freq); (rtctimer_freq & (rtctimer_freq - 1)) != 0) {
return -EINVAL; snd_printk(KERN_ERR "rtctimer: invalid frequency %d\n",
} rtctimer_freq);
for (order = 1; rtctimer_freq > order; order <<= 1)
;
if (rtctimer_freq != order) {
snd_printk(KERN_ERR "rtctimer: invalid frequency %d\n", rtctimer_freq);
return -EINVAL; return -EINVAL;
} }
@ -145,6 +134,7 @@ static int __init rtctimer_init(void)
if (err < 0) if (err < 0)
return err; return err;
timer->module = THIS_MODULE;
strcpy(timer->name, "RTC timer"); strcpy(timer->name, "RTC timer");
timer->hw = rtc_hw; timer->hw = rtc_hw;
timer->hw.resolution = NANO_SEC / rtctimer_freq; timer->hw.resolution = NANO_SEC / rtctimer_freq;

View File

@ -109,8 +109,7 @@ void snd_seq_instr_list_free(snd_seq_kinstr_list_t **list_ptr)
spin_lock_irqsave(&list->lock, flags); spin_lock_irqsave(&list->lock, flags);
while (instr->use) { while (instr->use) {
spin_unlock_irqrestore(&list->lock, flags); spin_unlock_irqrestore(&list->lock, flags);
set_current_state(TASK_INTERRUPTIBLE); schedule_timeout_interruptible(1);
schedule_timeout(1);
spin_lock_irqsave(&list->lock, flags); spin_lock_irqsave(&list->lock, flags);
} }
spin_unlock_irqrestore(&list->lock, flags); spin_unlock_irqrestore(&list->lock, flags);
@ -199,10 +198,8 @@ int snd_seq_instr_list_free_cond(snd_seq_kinstr_list_t *list,
while (flist) { while (flist) {
instr = flist; instr = flist;
flist = instr->next; flist = instr->next;
while (instr->use) { while (instr->use)
set_current_state(TASK_INTERRUPTIBLE); schedule_timeout_interruptible(1);
schedule_timeout(1);
}
if (snd_seq_instr_free(instr, atomic)<0) if (snd_seq_instr_free(instr, atomic)<0)
snd_printk(KERN_WARNING "instrument free problem\n"); snd_printk(KERN_WARNING "instrument free problem\n");
instr = next; instr = next;
@ -554,8 +551,7 @@ static int instr_free(snd_seq_kinstr_ops_t *ops,
instr->ops->notify(instr->ops->private_data, instr, SNDRV_SEQ_INSTR_NOTIFY_REMOVE); instr->ops->notify(instr->ops->private_data, instr, SNDRV_SEQ_INSTR_NOTIFY_REMOVE);
while (instr->use) { while (instr->use) {
spin_unlock_irqrestore(&list->lock, flags); spin_unlock_irqrestore(&list->lock, flags);
set_current_state(TASK_INTERRUPTIBLE); schedule_timeout_interruptible(1);
schedule_timeout(1);
spin_lock_irqsave(&list->lock, flags); spin_lock_irqsave(&list->lock, flags);
} }
spin_unlock_irqrestore(&list->lock, flags); spin_unlock_irqrestore(&list->lock, flags);

View File

@ -39,8 +39,7 @@ void snd_use_lock_sync_helper(snd_use_lock_t *lockp, const char *file, int line)
snd_printk(KERN_WARNING "seq_lock: timeout [%d left] in %s:%d\n", atomic_read(lockp), file, line); snd_printk(KERN_WARNING "seq_lock: timeout [%d left] in %s:%d\n", atomic_read(lockp), file, line);
break; break;
} }
set_current_state(TASK_UNINTERRUPTIBLE); schedule_timeout_uninterruptible(1);
schedule_timeout(1);
max_count--; max_count--;
} }
} }

View File

@ -423,8 +423,7 @@ int snd_seq_pool_done(pool_t *pool)
snd_printk(KERN_WARNING "snd_seq_pool_done timeout: %d cells remain\n", atomic_read(&pool->counter)); snd_printk(KERN_WARNING "snd_seq_pool_done timeout: %d cells remain\n", atomic_read(&pool->counter));
break; break;
} }
set_current_state(TASK_UNINTERRUPTIBLE); schedule_timeout_uninterruptible(1);
schedule_timeout(1);
max_count--; max_count--;
} }

View File

@ -449,11 +449,9 @@ snd_seq_midisynth_unregister_port(snd_seq_device_t *dev)
client->ports_per_device[device] = 0; client->ports_per_device[device] = 0;
msynth = client->ports[device]; msynth = client->ports[device];
client->ports[device] = NULL; client->ports[device] = NULL;
snd_runtime_check(msynth != NULL || ports <= 0, goto __skip);
for (p = 0; p < ports; p++) for (p = 0; p < ports; p++)
snd_seq_midisynth_delete(&msynth[p]); snd_seq_midisynth_delete(&msynth[p]);
kfree(msynth); kfree(msynth);
__skip:
client->num_ports--; client->num_ports--;
if (client->num_ports <= 0) { if (client->num_ports <= 0) {
snd_seq_delete_kernel_client(client->seq_client); snd_seq_delete_kernel_client(client->seq_client);

View File

@ -34,10 +34,15 @@ extern int seq_default_timer_device;
extern int seq_default_timer_subdevice; extern int seq_default_timer_subdevice;
extern int seq_default_timer_resolution; extern int seq_default_timer_resolution;
/* allowed sequencer timer frequencies, in Hz */
#define MIN_FREQUENCY 10
#define MAX_FREQUENCY 6250
#define DEFAULT_FREQUENCY 1000
#define SKEW_BASE 0x10000 /* 16bit shift */ #define SKEW_BASE 0x10000 /* 16bit shift */
static void snd_seq_timer_set_tick_resolution(seq_timer_tick_t *tick, static void snd_seq_timer_set_tick_resolution(seq_timer_tick_t *tick,
int tempo, int ppq, int nticks) int tempo, int ppq)
{ {
if (tempo < 1000000) if (tempo < 1000000)
tick->resolution = (tempo * 1000) / ppq; tick->resolution = (tempo * 1000) / ppq;
@ -51,7 +56,6 @@ static void snd_seq_timer_set_tick_resolution(seq_timer_tick_t *tick,
} }
if (tick->resolution <= 0) if (tick->resolution <= 0)
tick->resolution = 1; tick->resolution = 1;
tick->resolution *= nticks;
snd_seq_timer_update_tick(tick, 0); snd_seq_timer_update_tick(tick, 0);
} }
@ -100,7 +104,7 @@ void snd_seq_timer_defaults(seq_timer_t * tmr)
/* setup defaults */ /* setup defaults */
tmr->ppq = 96; /* 96 PPQ */ tmr->ppq = 96; /* 96 PPQ */
tmr->tempo = 500000; /* 120 BPM */ tmr->tempo = 500000; /* 120 BPM */
snd_seq_timer_set_tick_resolution(&tmr->tick, tmr->tempo, tmr->ppq, 1); snd_seq_timer_set_tick_resolution(&tmr->tick, tmr->tempo, tmr->ppq);
tmr->running = 0; tmr->running = 0;
tmr->type = SNDRV_SEQ_TIMER_ALSA; tmr->type = SNDRV_SEQ_TIMER_ALSA;
@ -183,7 +187,7 @@ int snd_seq_timer_set_tempo(seq_timer_t * tmr, int tempo)
spin_lock_irqsave(&tmr->lock, flags); spin_lock_irqsave(&tmr->lock, flags);
if ((unsigned int)tempo != tmr->tempo) { if ((unsigned int)tempo != tmr->tempo) {
tmr->tempo = tempo; tmr->tempo = tempo;
snd_seq_timer_set_tick_resolution(&tmr->tick, tmr->tempo, tmr->ppq, 1); snd_seq_timer_set_tick_resolution(&tmr->tick, tmr->tempo, tmr->ppq);
} }
spin_unlock_irqrestore(&tmr->lock, flags); spin_unlock_irqrestore(&tmr->lock, flags);
return 0; return 0;
@ -207,7 +211,7 @@ int snd_seq_timer_set_ppq(seq_timer_t * tmr, int ppq)
} }
tmr->ppq = ppq; tmr->ppq = ppq;
snd_seq_timer_set_tick_resolution(&tmr->tick, tmr->tempo, tmr->ppq, 1); snd_seq_timer_set_tick_resolution(&tmr->tick, tmr->tempo, tmr->ppq);
spin_unlock_irqrestore(&tmr->lock, flags); spin_unlock_irqrestore(&tmr->lock, flags);
return 0; return 0;
} }
@ -326,17 +330,26 @@ int snd_seq_timer_stop(seq_timer_t * tmr)
static int initialize_timer(seq_timer_t *tmr) static int initialize_timer(seq_timer_t *tmr)
{ {
snd_timer_t *t; snd_timer_t *t;
unsigned long freq;
t = tmr->timeri->timer; t = tmr->timeri->timer;
snd_assert(t, return -EINVAL); snd_assert(t, return -EINVAL);
freq = tmr->preferred_resolution;
if (!freq)
freq = DEFAULT_FREQUENCY;
else if (freq < MIN_FREQUENCY)
freq = MIN_FREQUENCY;
else if (freq > MAX_FREQUENCY)
freq = MAX_FREQUENCY;
tmr->ticks = 1; tmr->ticks = 1;
if (tmr->preferred_resolution && if (!(t->hw.flags & SNDRV_TIMER_HW_SLAVE)) {
! (t->hw.flags & SNDRV_TIMER_HW_SLAVE)) {
unsigned long r = t->hw.resolution; unsigned long r = t->hw.resolution;
if (! r && t->hw.c_resolution) if (! r && t->hw.c_resolution)
r = t->hw.c_resolution(t); r = t->hw.c_resolution(t);
if (r) { if (r) {
tmr->ticks = (unsigned int)(1000000000uL / (r * tmr->preferred_resolution)); tmr->ticks = (unsigned int)(1000000000uL / (r * freq));
if (! tmr->ticks) if (! tmr->ticks)
tmr->ticks = 1; tmr->ticks = 1;
} }

View File

@ -130,7 +130,7 @@ static int snd_open(struct inode *inode, struct file *file)
struct file_operations *old_fops; struct file_operations *old_fops;
int err = 0; int err = 0;
if (dev != SNDRV_MINOR_SEQUENCER && dev != SNDRV_MINOR_TIMER) { if (dev != SNDRV_MINOR_GLOBAL) {
if (snd_cards[card] == NULL) { if (snd_cards[card] == NULL) {
#ifdef CONFIG_KMOD #ifdef CONFIG_KMOD
snd_request_card(card); snd_request_card(card);
@ -287,7 +287,7 @@ static void snd_minor_info_read(snd_info_entry_t *entry, snd_info_buffer_t * buf
for (card = 0; card < SNDRV_CARDS; card++) { for (card = 0; card < SNDRV_CARDS; card++) {
list_for_each(list, &snd_minors_hash[card]) { list_for_each(list, &snd_minors_hash[card]) {
mptr = list_entry(list, snd_minor_t, list); mptr = list_entry(list, snd_minor_t, list);
if (SNDRV_MINOR_DEVICE(mptr->number) != SNDRV_MINOR_SEQUENCER) { if (SNDRV_MINOR_DEVICE(mptr->number) != SNDRV_MINOR_GLOBAL) {
if ((device = mptr->device) >= 0) if ((device = mptr->device) >= 0)
snd_iprintf(buffer, "%3i: [%i-%2i]: %s\n", mptr->number, card, device, mptr->comment); snd_iprintf(buffer, "%3i: [%i-%2i]: %s\n", mptr->number, card, device, mptr->comment);
else else
@ -350,9 +350,7 @@ static int __init alsa_sound_init(void)
devfs_remove("snd"); devfs_remove("snd");
return -EIO; return -EIO;
} }
snd_memory_init();
if (snd_info_init() < 0) { if (snd_info_init() < 0) {
snd_memory_done();
unregister_chrdev(major, "alsa"); unregister_chrdev(major, "alsa");
devfs_remove("snd"); devfs_remove("snd");
return -ENOMEM; return -ENOMEM;
@ -381,7 +379,6 @@ static void __exit alsa_sound_exit(void)
#endif #endif
snd_info_minor_unregister(); snd_info_minor_unregister();
snd_info_done(); snd_info_done();
snd_memory_done();
if (unregister_chrdev(major, "alsa") != 0) if (unregister_chrdev(major, "alsa") != 0)
snd_printk(KERN_ERR "unable to unregister major device number %d\n", major); snd_printk(KERN_ERR "unable to unregister major device number %d\n", major);
devfs_remove("snd"); devfs_remove("snd");
@ -403,14 +400,6 @@ EXPORT_SYMBOL(snd_register_oss_device);
EXPORT_SYMBOL(snd_unregister_oss_device); EXPORT_SYMBOL(snd_unregister_oss_device);
#endif #endif
/* memory.c */ /* memory.c */
#ifdef CONFIG_SND_DEBUG_MEMORY
EXPORT_SYMBOL(snd_hidden_kmalloc);
EXPORT_SYMBOL(snd_hidden_kcalloc);
EXPORT_SYMBOL(snd_hidden_kfree);
EXPORT_SYMBOL(snd_hidden_vmalloc);
EXPORT_SYMBOL(snd_hidden_vfree);
EXPORT_SYMBOL(snd_hidden_kstrdup);
#endif
EXPORT_SYMBOL(copy_to_user_fromio); EXPORT_SYMBOL(copy_to_user_fromio);
EXPORT_SYMBOL(copy_from_user_toio); EXPORT_SYMBOL(copy_from_user_toio);
/* init.c */ /* init.c */
@ -487,17 +476,10 @@ EXPORT_SYMBOL(snd_ctl_unregister_ioctl_compat);
EXPORT_SYMBOL(snd_ctl_elem_read); EXPORT_SYMBOL(snd_ctl_elem_read);
EXPORT_SYMBOL(snd_ctl_elem_write); EXPORT_SYMBOL(snd_ctl_elem_write);
/* misc.c */ /* misc.c */
EXPORT_SYMBOL(snd_task_name); EXPORT_SYMBOL(release_and_free_resource);
#ifdef CONFIG_SND_VERBOSE_PRINTK #ifdef CONFIG_SND_VERBOSE_PRINTK
EXPORT_SYMBOL(snd_verbose_printk); EXPORT_SYMBOL(snd_verbose_printk);
#endif #endif
#if defined(CONFIG_SND_DEBUG) && defined(CONFIG_SND_VERBOSE_PRINTK) #if defined(CONFIG_SND_DEBUG) && defined(CONFIG_SND_VERBOSE_PRINTK)
EXPORT_SYMBOL(snd_verbose_printd); EXPORT_SYMBOL(snd_verbose_printd);
#endif
/* wrappers */
#ifdef CONFIG_SND_DEBUG_MEMORY
EXPORT_SYMBOL(snd_wrapper_kmalloc);
EXPORT_SYMBOL(snd_wrapper_kfree);
EXPORT_SYMBOL(snd_wrapper_vmalloc);
EXPORT_SYMBOL(snd_wrapper_vfree);
#endif #endif

View File

@ -55,7 +55,7 @@ MODULE_PARM_DESC(timer_limit, "Maximum global timers in system.");
typedef struct { typedef struct {
snd_timer_instance_t *timeri; snd_timer_instance_t *timeri;
int tread; /* enhanced read with timestamps and events */ int tread; /* enhanced read with timestamps and events */
unsigned long ticks; unsigned long ticks;
unsigned long overrun; unsigned long overrun;
int qhead; int qhead;
@ -95,7 +95,8 @@ static void snd_timer_reschedule(snd_timer_t * timer, unsigned long ticks_left);
* create a timer instance with the given owner string. * create a timer instance with the given owner string.
* when timer is not NULL, increments the module counter * when timer is not NULL, increments the module counter
*/ */
static snd_timer_instance_t *snd_timer_instance_new(char *owner, snd_timer_t *timer) static snd_timer_instance_t *snd_timer_instance_new(char *owner,
snd_timer_t *timer)
{ {
snd_timer_instance_t *timeri; snd_timer_instance_t *timeri;
timeri = kzalloc(sizeof(*timeri), GFP_KERNEL); timeri = kzalloc(sizeof(*timeri), GFP_KERNEL);
@ -113,7 +114,7 @@ static snd_timer_instance_t *snd_timer_instance_new(char *owner, snd_timer_t *ti
INIT_LIST_HEAD(&timeri->slave_active_head); INIT_LIST_HEAD(&timeri->slave_active_head);
timeri->timer = timer; timeri->timer = timer;
if (timer && timer->card && !try_module_get(timer->card->module)) { if (timer && !try_module_get(timer->module)) {
kfree(timeri->owner); kfree(timeri->owner);
kfree(timeri); kfree(timeri);
return NULL; return NULL;
@ -131,7 +132,7 @@ static snd_timer_t *snd_timer_find(snd_timer_id_t *tid)
struct list_head *p; struct list_head *p;
list_for_each(p, &snd_timer_list) { list_for_each(p, &snd_timer_list) {
timer = (snd_timer_t *)list_entry(p, snd_timer_t, device_list); timer = list_entry(p, snd_timer_t, device_list);
if (timer->tmr_class != tid->dev_class) if (timer->tmr_class != tid->dev_class)
continue; continue;
@ -186,13 +187,14 @@ static void snd_timer_check_slave(snd_timer_instance_t *slave)
/* FIXME: it's really dumb to look up all entries.. */ /* FIXME: it's really dumb to look up all entries.. */
list_for_each(p, &snd_timer_list) { list_for_each(p, &snd_timer_list) {
timer = (snd_timer_t *)list_entry(p, snd_timer_t, device_list); timer = list_entry(p, snd_timer_t, device_list);
list_for_each(q, &timer->open_list_head) { list_for_each(q, &timer->open_list_head) {
master = (snd_timer_instance_t *)list_entry(q, snd_timer_instance_t, open_list); master = list_entry(q, snd_timer_instance_t, open_list);
if (slave->slave_class == master->slave_class && if (slave->slave_class == master->slave_class &&
slave->slave_id == master->slave_id) { slave->slave_id == master->slave_id) {
list_del(&slave->open_list); list_del(&slave->open_list);
list_add_tail(&slave->open_list, &master->slave_list_head); list_add_tail(&slave->open_list,
&master->slave_list_head);
spin_lock_irq(&slave_active_lock); spin_lock_irq(&slave_active_lock);
slave->master = master; slave->master = master;
slave->timer = master->timer; slave->timer = master->timer;
@ -216,7 +218,7 @@ static void snd_timer_check_master(snd_timer_instance_t *master)
/* check all pending slaves */ /* check all pending slaves */
list_for_each_safe(p, n, &snd_timer_slave_list) { list_for_each_safe(p, n, &snd_timer_slave_list) {
slave = (snd_timer_instance_t *)list_entry(p, snd_timer_instance_t, open_list); slave = list_entry(p, snd_timer_instance_t, open_list);
if (slave->slave_class == master->slave_class && if (slave->slave_class == master->slave_class &&
slave->slave_id == master->slave_id) { slave->slave_id == master->slave_id) {
list_del(p); list_del(p);
@ -225,7 +227,8 @@ static void snd_timer_check_master(snd_timer_instance_t *master)
slave->master = master; slave->master = master;
slave->timer = master->timer; slave->timer = master->timer;
if (slave->flags & SNDRV_TIMER_IFLG_RUNNING) if (slave->flags & SNDRV_TIMER_IFLG_RUNNING)
list_add_tail(&slave->active_list, &master->slave_active_head); list_add_tail(&slave->active_list,
&master->slave_active_head);
spin_unlock_irq(&slave_active_lock); spin_unlock_irq(&slave_active_lock);
} }
} }
@ -241,7 +244,7 @@ int snd_timer_open(snd_timer_instance_t **ti,
{ {
snd_timer_t *timer; snd_timer_t *timer;
snd_timer_instance_t *timeri = NULL; snd_timer_instance_t *timeri = NULL;
if (tid->dev_class == SNDRV_TIMER_CLASS_SLAVE) { if (tid->dev_class == SNDRV_TIMER_CLASS_SLAVE) {
/* open a slave instance */ /* open a slave instance */
if (tid->dev_sclass <= SNDRV_TIMER_SCLASS_NONE || if (tid->dev_sclass <= SNDRV_TIMER_SCLASS_NONE ||
@ -251,6 +254,10 @@ int snd_timer_open(snd_timer_instance_t **ti,
} }
down(&register_mutex); down(&register_mutex);
timeri = snd_timer_instance_new(owner, NULL); timeri = snd_timer_instance_new(owner, NULL);
if (!timeri) {
up(&register_mutex);
return -ENOMEM;
}
timeri->slave_class = tid->dev_sclass; timeri->slave_class = tid->dev_sclass;
timeri->slave_id = tid->device; timeri->slave_id = tid->device;
timeri->flags |= SNDRV_TIMER_IFLG_SLAVE; timeri->flags |= SNDRV_TIMER_IFLG_SLAVE;
@ -272,33 +279,36 @@ int snd_timer_open(snd_timer_instance_t **ti,
timer = snd_timer_find(tid); timer = snd_timer_find(tid);
} }
#endif #endif
if (timer) { if (!timer) {
if (!list_empty(&timer->open_list_head)) {
timeri = (snd_timer_instance_t *)list_entry(timer->open_list_head.next, snd_timer_instance_t, open_list);
if (timeri->flags & SNDRV_TIMER_IFLG_EXCLUSIVE) {
up(&register_mutex);
return -EBUSY;
}
}
timeri = snd_timer_instance_new(owner, timer);
if (timeri) {
timeri->slave_class = tid->dev_sclass;
timeri->slave_id = slave_id;
if (list_empty(&timer->open_list_head) && timer->hw.open)
timer->hw.open(timer);
list_add_tail(&timeri->open_list, &timer->open_list_head);
snd_timer_check_master(timeri);
}
} else {
up(&register_mutex); up(&register_mutex);
return -ENODEV; return -ENODEV;
} }
if (!list_empty(&timer->open_list_head)) {
timeri = list_entry(timer->open_list_head.next,
snd_timer_instance_t, open_list);
if (timeri->flags & SNDRV_TIMER_IFLG_EXCLUSIVE) {
up(&register_mutex);
return -EBUSY;
}
}
timeri = snd_timer_instance_new(owner, timer);
if (!timeri) {
up(&register_mutex);
return -ENOMEM;
}
timeri->slave_class = tid->dev_sclass;
timeri->slave_id = slave_id;
if (list_empty(&timer->open_list_head) && timer->hw.open)
timer->hw.open(timer);
list_add_tail(&timeri->open_list, &timer->open_list_head);
snd_timer_check_master(timeri);
up(&register_mutex); up(&register_mutex);
*ti = timeri; *ti = timeri;
return 0; return 0;
} }
static int _snd_timer_stop(snd_timer_instance_t * timeri, int keep_flag, enum sndrv_timer_event event); static int _snd_timer_stop(snd_timer_instance_t * timeri,
int keep_flag, enum sndrv_timer_event event);
/* /*
* close a timer instance * close a timer instance
@ -338,11 +348,12 @@ int snd_timer_close(snd_timer_instance_t * timeri)
spin_unlock_irq(&timer->lock); spin_unlock_irq(&timer->lock);
down(&register_mutex); down(&register_mutex);
list_del(&timeri->open_list); list_del(&timeri->open_list);
if (timer && list_empty(&timer->open_list_head) && timer->hw.close) if (timer && list_empty(&timer->open_list_head) &&
timer->hw.close)
timer->hw.close(timer); timer->hw.close(timer);
/* remove slave links */ /* remove slave links */
list_for_each_safe(p, n, &timeri->slave_list_head) { list_for_each_safe(p, n, &timeri->slave_list_head) {
slave = (snd_timer_instance_t *)list_entry(p, snd_timer_instance_t, open_list); slave = list_entry(p, snd_timer_instance_t, open_list);
spin_lock_irq(&slave_active_lock); spin_lock_irq(&slave_active_lock);
_snd_timer_stop(slave, 1, SNDRV_TIMER_EVENT_RESOLUTION); _snd_timer_stop(slave, 1, SNDRV_TIMER_EVENT_RESOLUTION);
list_del(p); list_del(p);
@ -357,8 +368,8 @@ int snd_timer_close(snd_timer_instance_t * timeri)
timeri->private_free(timeri); timeri->private_free(timeri);
kfree(timeri->owner); kfree(timeri->owner);
kfree(timeri); kfree(timeri);
if (timer && timer->card) if (timer)
module_put(timer->card->module); module_put(timer->module);
return 0; return 0;
} }
@ -376,7 +387,8 @@ unsigned long snd_timer_resolution(snd_timer_instance_t * timeri)
return 0; return 0;
} }
static void snd_timer_notify1(snd_timer_instance_t *ti, enum sndrv_timer_event event) static void snd_timer_notify1(snd_timer_instance_t *ti,
enum sndrv_timer_event event)
{ {
snd_timer_t *timer; snd_timer_t *timer;
unsigned long flags; unsigned long flags;
@ -385,9 +397,11 @@ static void snd_timer_notify1(snd_timer_instance_t *ti, enum sndrv_timer_event e
struct list_head *n; struct list_head *n;
struct timespec tstamp; struct timespec tstamp;
snd_timestamp_now(&tstamp, 1); getnstimeofday(&tstamp);
snd_assert(event >= SNDRV_TIMER_EVENT_START && event <= SNDRV_TIMER_EVENT_PAUSE, return); snd_assert(event >= SNDRV_TIMER_EVENT_START &&
if (event == SNDRV_TIMER_EVENT_START || event == SNDRV_TIMER_EVENT_CONTINUE) event <= SNDRV_TIMER_EVENT_PAUSE, return);
if (event == SNDRV_TIMER_EVENT_START ||
event == SNDRV_TIMER_EVENT_CONTINUE)
resolution = snd_timer_resolution(ti); resolution = snd_timer_resolution(ti);
if (ti->ccallback) if (ti->ccallback)
ti->ccallback(ti, SNDRV_TIMER_EVENT_START, &tstamp, resolution); ti->ccallback(ti, SNDRV_TIMER_EVENT_START, &tstamp, resolution);
@ -400,14 +414,15 @@ static void snd_timer_notify1(snd_timer_instance_t *ti, enum sndrv_timer_event e
return; return;
spin_lock_irqsave(&timer->lock, flags); spin_lock_irqsave(&timer->lock, flags);
list_for_each(n, &ti->slave_active_head) { list_for_each(n, &ti->slave_active_head) {
ts = (snd_timer_instance_t *)list_entry(n, snd_timer_instance_t, active_list); ts = list_entry(n, snd_timer_instance_t, active_list);
if (ts->ccallback) if (ts->ccallback)
ts->ccallback(ti, event + 100, &tstamp, resolution); ts->ccallback(ti, event + 100, &tstamp, resolution);
} }
spin_unlock_irqrestore(&timer->lock, flags); spin_unlock_irqrestore(&timer->lock, flags);
} }
static int snd_timer_start1(snd_timer_t *timer, snd_timer_instance_t *timeri, unsigned long sticks) static int snd_timer_start1(snd_timer_t *timer, snd_timer_instance_t *timeri,
unsigned long sticks)
{ {
list_del(&timeri->active_list); list_del(&timeri->active_list);
list_add_tail(&timeri->active_list, &timer->active_list_head); list_add_tail(&timeri->active_list, &timer->active_list_head);
@ -434,14 +449,15 @@ static int snd_timer_start_slave(snd_timer_instance_t *timeri)
spin_lock_irqsave(&slave_active_lock, flags); spin_lock_irqsave(&slave_active_lock, flags);
timeri->flags |= SNDRV_TIMER_IFLG_RUNNING; timeri->flags |= SNDRV_TIMER_IFLG_RUNNING;
if (timeri->master) if (timeri->master)
list_add_tail(&timeri->active_list, &timeri->master->slave_active_head); list_add_tail(&timeri->active_list,
&timeri->master->slave_active_head);
spin_unlock_irqrestore(&slave_active_lock, flags); spin_unlock_irqrestore(&slave_active_lock, flags);
return 1; /* delayed start */ return 1; /* delayed start */
} }
/* /*
* start the timer instance * start the timer instance
*/ */
int snd_timer_start(snd_timer_instance_t * timeri, unsigned int ticks) int snd_timer_start(snd_timer_instance_t * timeri, unsigned int ticks)
{ {
snd_timer_t *timer; snd_timer_t *timer;
@ -467,7 +483,8 @@ int snd_timer_start(snd_timer_instance_t * timeri, unsigned int ticks)
return result; return result;
} }
static int _snd_timer_stop(snd_timer_instance_t * timeri, int keep_flag, enum sndrv_timer_event event) static int _snd_timer_stop(snd_timer_instance_t * timeri,
int keep_flag, enum sndrv_timer_event event)
{ {
snd_timer_t *timer; snd_timer_t *timer;
unsigned long flags; unsigned long flags;
@ -501,7 +518,8 @@ static int _snd_timer_stop(snd_timer_instance_t * timeri, int keep_flag, enum sn
} }
} }
if (!keep_flag) if (!keep_flag)
timeri->flags &= ~(SNDRV_TIMER_IFLG_RUNNING|SNDRV_TIMER_IFLG_START); timeri->flags &=
~(SNDRV_TIMER_IFLG_RUNNING | SNDRV_TIMER_IFLG_START);
spin_unlock_irqrestore(&timer->lock, flags); spin_unlock_irqrestore(&timer->lock, flags);
__end: __end:
if (event != SNDRV_TIMER_EVENT_RESOLUTION) if (event != SNDRV_TIMER_EVENT_RESOLUTION)
@ -578,7 +596,7 @@ static void snd_timer_reschedule(snd_timer_t * timer, unsigned long ticks_left)
struct list_head *p; struct list_head *p;
list_for_each(p, &timer->active_list_head) { list_for_each(p, &timer->active_list_head) {
ti = (snd_timer_instance_t *)list_entry(p, snd_timer_instance_t, active_list); ti = list_entry(p, snd_timer_instance_t, active_list);
if (ti->flags & SNDRV_TIMER_IFLG_START) { if (ti->flags & SNDRV_TIMER_IFLG_START) {
ti->flags &= ~SNDRV_TIMER_IFLG_START; ti->flags &= ~SNDRV_TIMER_IFLG_START;
ti->flags |= SNDRV_TIMER_IFLG_RUNNING; ti->flags |= SNDRV_TIMER_IFLG_RUNNING;
@ -615,11 +633,11 @@ static void snd_timer_tasklet(unsigned long arg)
/* now process all callbacks */ /* now process all callbacks */
while (!list_empty(&timer->sack_list_head)) { while (!list_empty(&timer->sack_list_head)) {
p = timer->sack_list_head.next; /* get first item */ p = timer->sack_list_head.next; /* get first item */
ti = (snd_timer_instance_t *)list_entry(p, snd_timer_instance_t, ack_list); ti = list_entry(p, snd_timer_instance_t, ack_list);
/* remove from ack_list and make empty */ /* remove from ack_list and make empty */
list_del_init(p); list_del_init(p);
ticks = ti->pticks; ticks = ti->pticks;
ti->pticks = 0; ti->pticks = 0;
resolution = ti->resolution; resolution = ti->resolution;
@ -644,7 +662,7 @@ void snd_timer_interrupt(snd_timer_t * timer, unsigned long ticks_left)
{ {
snd_timer_instance_t *ti, *ts; snd_timer_instance_t *ti, *ts;
unsigned long resolution, ticks; unsigned long resolution, ticks;
struct list_head *p, *q, *n; struct list_head *p, *q, *n, *ack_list_head;
int use_tasklet = 0; int use_tasklet = 0;
if (timer == NULL) if (timer == NULL)
@ -659,11 +677,12 @@ void snd_timer_interrupt(snd_timer_t * timer, unsigned long ticks_left)
resolution = timer->hw.resolution; resolution = timer->hw.resolution;
/* loop for all active instances /* loop for all active instances
* here we cannot use list_for_each because the active_list of a processed * Here we cannot use list_for_each because the active_list of a
* instance is relinked to done_list_head before callback is called. * processed instance is relinked to done_list_head before the callback
* is called.
*/ */
list_for_each_safe(p, n, &timer->active_list_head) { list_for_each_safe(p, n, &timer->active_list_head) {
ti = (snd_timer_instance_t *)list_entry(p, snd_timer_instance_t, active_list); ti = list_entry(p, snd_timer_instance_t, active_list);
if (!(ti->flags & SNDRV_TIMER_IFLG_RUNNING)) if (!(ti->flags & SNDRV_TIMER_IFLG_RUNNING))
continue; continue;
ti->pticks += ticks_left; ti->pticks += ticks_left;
@ -681,26 +700,19 @@ void snd_timer_interrupt(snd_timer_t * timer, unsigned long ticks_left)
if (--timer->running) if (--timer->running)
list_del(p); list_del(p);
} }
if (list_empty(&ti->ack_list)) { if ((timer->hw.flags & SNDRV_TIMER_HW_TASKLET) ||
if ((timer->hw.flags & SNDRV_TIMER_HW_TASKLET) || (ti->flags & SNDRV_TIMER_IFLG_FAST))
(ti->flags & SNDRV_TIMER_IFLG_FAST)) { ack_list_head = &timer->ack_list_head;
list_add_tail(&ti->ack_list, &timer->ack_list_head); else
} else { ack_list_head = &timer->sack_list_head;
list_add_tail(&ti->ack_list, &timer->sack_list_head); if (list_empty(&ti->ack_list))
} list_add_tail(&ti->ack_list, ack_list_head);
}
list_for_each(q, &ti->slave_active_head) { list_for_each(q, &ti->slave_active_head) {
ts = (snd_timer_instance_t *)list_entry(q, snd_timer_instance_t, active_list); ts = list_entry(q, snd_timer_instance_t, active_list);
ts->pticks = ti->pticks; ts->pticks = ti->pticks;
ts->resolution = resolution; ts->resolution = resolution;
if (list_empty(&ts->ack_list)) { if (list_empty(&ts->ack_list))
if ((timer->hw.flags & SNDRV_TIMER_HW_TASKLET) || list_add_tail(&ts->ack_list, ack_list_head);
(ti->flags & SNDRV_TIMER_IFLG_FAST)) {
list_add_tail(&ts->ack_list, &timer->ack_list_head);
} else {
list_add_tail(&ts->ack_list, &timer->sack_list_head);
}
}
} }
} }
if (timer->flags & SNDRV_TIMER_FLG_RESCHED) if (timer->flags & SNDRV_TIMER_FLG_RESCHED)
@ -723,11 +735,11 @@ void snd_timer_interrupt(snd_timer_t * timer, unsigned long ticks_left)
/* now process all fast callbacks */ /* now process all fast callbacks */
while (!list_empty(&timer->ack_list_head)) { while (!list_empty(&timer->ack_list_head)) {
p = timer->ack_list_head.next; /* get first item */ p = timer->ack_list_head.next; /* get first item */
ti = (snd_timer_instance_t *)list_entry(p, snd_timer_instance_t, ack_list); ti = list_entry(p, snd_timer_instance_t, ack_list);
/* remove from ack_list and make empty */ /* remove from ack_list and make empty */
list_del_init(p); list_del_init(p);
ticks = ti->pticks; ticks = ti->pticks;
ti->pticks = 0; ti->pticks = 0;
@ -751,7 +763,8 @@ void snd_timer_interrupt(snd_timer_t * timer, unsigned long ticks_left)
*/ */
int snd_timer_new(snd_card_t *card, char *id, snd_timer_id_t *tid, snd_timer_t ** rtimer) int snd_timer_new(snd_card_t *card, char *id, snd_timer_id_t *tid,
snd_timer_t **rtimer)
{ {
snd_timer_t *timer; snd_timer_t *timer;
int err; int err;
@ -779,9 +792,12 @@ int snd_timer_new(snd_card_t *card, char *id, snd_timer_id_t *tid, snd_timer_t *
INIT_LIST_HEAD(&timer->ack_list_head); INIT_LIST_HEAD(&timer->ack_list_head);
INIT_LIST_HEAD(&timer->sack_list_head); INIT_LIST_HEAD(&timer->sack_list_head);
spin_lock_init(&timer->lock); spin_lock_init(&timer->lock);
tasklet_init(&timer->task_queue, snd_timer_tasklet, (unsigned long)timer); tasklet_init(&timer->task_queue, snd_timer_tasklet,
(unsigned long)timer);
if (card != NULL) { if (card != NULL) {
if ((err = snd_device_new(card, SNDRV_DEV_TIMER, timer, &ops)) < 0) { timer->module = card->module;
err = snd_device_new(card, SNDRV_DEV_TIMER, timer, &ops);
if (err < 0) {
snd_timer_free(timer); snd_timer_free(timer);
return err; return err;
} }
@ -811,14 +827,15 @@ static int snd_timer_dev_register(snd_device_t *dev)
snd_timer_t *timer1; snd_timer_t *timer1;
struct list_head *p; struct list_head *p;
snd_assert(timer != NULL && timer->hw.start != NULL && timer->hw.stop != NULL, return -ENXIO); snd_assert(timer != NULL && timer->hw.start != NULL &&
timer->hw.stop != NULL, return -ENXIO);
if (!(timer->hw.flags & SNDRV_TIMER_HW_SLAVE) && if (!(timer->hw.flags & SNDRV_TIMER_HW_SLAVE) &&
!timer->hw.resolution && timer->hw.c_resolution == NULL) !timer->hw.resolution && timer->hw.c_resolution == NULL)
return -EINVAL; return -EINVAL;
down(&register_mutex); down(&register_mutex);
list_for_each(p, &snd_timer_list) { list_for_each(p, &snd_timer_list) {
timer1 = (snd_timer_t *)list_entry(p, snd_timer_t, device_list); timer1 = list_entry(p, snd_timer_t, device_list);
if (timer1->tmr_class > timer->tmr_class) if (timer1->tmr_class > timer->tmr_class)
break; break;
if (timer1->tmr_class < timer->tmr_class) if (timer1->tmr_class < timer->tmr_class)
@ -857,7 +874,7 @@ static int snd_timer_unregister(snd_timer_t *timer)
snd_printk(KERN_WARNING "timer 0x%lx is busy?\n", (long)timer); snd_printk(KERN_WARNING "timer 0x%lx is busy?\n", (long)timer);
list_for_each_safe(p, n, &timer->open_list_head) { list_for_each_safe(p, n, &timer->open_list_head) {
list_del_init(p); list_del_init(p);
ti = (snd_timer_instance_t *)list_entry(p, snd_timer_instance_t, open_list); ti = list_entry(p, snd_timer_instance_t, open_list);
ti->timer = NULL; ti->timer = NULL;
} }
} }
@ -872,15 +889,18 @@ static int snd_timer_dev_unregister(snd_device_t *device)
return snd_timer_unregister(timer); return snd_timer_unregister(timer);
} }
void snd_timer_notify(snd_timer_t *timer, enum sndrv_timer_event event, struct timespec *tstamp) void snd_timer_notify(snd_timer_t *timer, enum sndrv_timer_event event,
struct timespec *tstamp)
{ {
unsigned long flags; unsigned long flags;
unsigned long resolution = 0; unsigned long resolution = 0;
snd_timer_instance_t *ti, *ts; snd_timer_instance_t *ti, *ts;
struct list_head *p, *n; struct list_head *p, *n;
snd_runtime_check(timer->hw.flags & SNDRV_TIMER_HW_SLAVE, return); if (! (timer->hw.flags & SNDRV_TIMER_HW_SLAVE))
snd_assert(event >= SNDRV_TIMER_EVENT_MSTART && event <= SNDRV_TIMER_EVENT_MRESUME, return); return;
snd_assert(event >= SNDRV_TIMER_EVENT_MSTART &&
event <= SNDRV_TIMER_EVENT_MRESUME, return);
spin_lock_irqsave(&timer->lock, flags); spin_lock_irqsave(&timer->lock, flags);
if (event == SNDRV_TIMER_EVENT_MSTART || if (event == SNDRV_TIMER_EVENT_MSTART ||
event == SNDRV_TIMER_EVENT_MCONTINUE || event == SNDRV_TIMER_EVENT_MCONTINUE ||
@ -891,11 +911,11 @@ void snd_timer_notify(snd_timer_t *timer, enum sndrv_timer_event event, struct t
resolution = timer->hw.resolution; resolution = timer->hw.resolution;
} }
list_for_each(p, &timer->active_list_head) { list_for_each(p, &timer->active_list_head) {
ti = (snd_timer_instance_t *)list_entry(p, snd_timer_instance_t, active_list); ti = list_entry(p, snd_timer_instance_t, active_list);
if (ti->ccallback) if (ti->ccallback)
ti->ccallback(ti, event, tstamp, resolution); ti->ccallback(ti, event, tstamp, resolution);
list_for_each(n, &ti->slave_active_head) { list_for_each(n, &ti->slave_active_head) {
ts = (snd_timer_instance_t *)list_entry(n, snd_timer_instance_t, active_list); ts = list_entry(n, snd_timer_instance_t, active_list);
if (ts->ccallback) if (ts->ccallback)
ts->ccallback(ts, event, tstamp, resolution); ts->ccallback(ts, event, tstamp, resolution);
} }
@ -909,7 +929,7 @@ void snd_timer_notify(snd_timer_t *timer, enum sndrv_timer_event event, struct t
int snd_timer_global_new(char *id, int device, snd_timer_t **rtimer) int snd_timer_global_new(char *id, int device, snd_timer_t **rtimer)
{ {
snd_timer_id_t tid; snd_timer_id_t tid;
tid.dev_class = SNDRV_TIMER_CLASS_GLOBAL; tid.dev_class = SNDRV_TIMER_CLASS_GLOBAL;
tid.dev_sclass = SNDRV_TIMER_SCLASS_NONE; tid.dev_sclass = SNDRV_TIMER_SCLASS_NONE;
tid.card = -1; tid.card = -1;
@ -937,7 +957,7 @@ int snd_timer_global_unregister(snd_timer_t *timer)
return snd_timer_unregister(timer); return snd_timer_unregister(timer);
} }
/* /*
* System timer * System timer
*/ */
@ -1013,7 +1033,8 @@ static int snd_timer_register_system(void)
struct snd_timer_system_private *priv; struct snd_timer_system_private *priv;
int err; int err;
if ((err = snd_timer_global_new("system", SNDRV_TIMER_GLOBAL_SYSTEM, &timer)) < 0) err = snd_timer_global_new("system", SNDRV_TIMER_GLOBAL_SYSTEM, &timer);
if (err < 0)
return err; return err;
strcpy(timer->name, "system timer"); strcpy(timer->name, "system timer");
timer->hw = snd_timer_system; timer->hw = snd_timer_system;
@ -1044,33 +1065,41 @@ static void snd_timer_proc_read(snd_info_entry_t *entry,
down(&register_mutex); down(&register_mutex);
list_for_each(p, &snd_timer_list) { list_for_each(p, &snd_timer_list) {
timer = (snd_timer_t *)list_entry(p, snd_timer_t, device_list); timer = list_entry(p, snd_timer_t, device_list);
switch (timer->tmr_class) { switch (timer->tmr_class) {
case SNDRV_TIMER_CLASS_GLOBAL: case SNDRV_TIMER_CLASS_GLOBAL:
snd_iprintf(buffer, "G%i: ", timer->tmr_device); snd_iprintf(buffer, "G%i: ", timer->tmr_device);
break; break;
case SNDRV_TIMER_CLASS_CARD: case SNDRV_TIMER_CLASS_CARD:
snd_iprintf(buffer, "C%i-%i: ", timer->card->number, timer->tmr_device); snd_iprintf(buffer, "C%i-%i: ",
timer->card->number, timer->tmr_device);
break; break;
case SNDRV_TIMER_CLASS_PCM: case SNDRV_TIMER_CLASS_PCM:
snd_iprintf(buffer, "P%i-%i-%i: ", timer->card->number, timer->tmr_device, timer->tmr_subdevice); snd_iprintf(buffer, "P%i-%i-%i: ", timer->card->number,
timer->tmr_device, timer->tmr_subdevice);
break; break;
default: default:
snd_iprintf(buffer, "?%i-%i-%i-%i: ", timer->tmr_class, timer->card ? timer->card->number : -1, timer->tmr_device, timer->tmr_subdevice); snd_iprintf(buffer, "?%i-%i-%i-%i: ", timer->tmr_class,
timer->card ? timer->card->number : -1,
timer->tmr_device, timer->tmr_subdevice);
} }
snd_iprintf(buffer, "%s :", timer->name); snd_iprintf(buffer, "%s :", timer->name);
if (timer->hw.resolution) if (timer->hw.resolution)
snd_iprintf(buffer, " %lu.%03luus (%lu ticks)", timer->hw.resolution / 1000, timer->hw.resolution % 1000, timer->hw.ticks); snd_iprintf(buffer, " %lu.%03luus (%lu ticks)",
timer->hw.resolution / 1000,
timer->hw.resolution % 1000,
timer->hw.ticks);
if (timer->hw.flags & SNDRV_TIMER_HW_SLAVE) if (timer->hw.flags & SNDRV_TIMER_HW_SLAVE)
snd_iprintf(buffer, " SLAVE"); snd_iprintf(buffer, " SLAVE");
snd_iprintf(buffer, "\n"); snd_iprintf(buffer, "\n");
spin_lock_irqsave(&timer->lock, flags); spin_lock_irqsave(&timer->lock, flags);
list_for_each(q, &timer->open_list_head) { list_for_each(q, &timer->open_list_head) {
ti = (snd_timer_instance_t *)list_entry(q, snd_timer_instance_t, open_list); ti = list_entry(q, snd_timer_instance_t, open_list);
snd_iprintf(buffer, " Client %s : %s : lost interrupts %li\n", snd_iprintf(buffer, " Client %s : %s\n",
ti->owner ? ti->owner : "unknown", ti->owner ? ti->owner : "unknown",
ti->flags & (SNDRV_TIMER_IFLG_START|SNDRV_TIMER_IFLG_RUNNING) ? "running" : "stopped", ti->flags & (SNDRV_TIMER_IFLG_START |
ti->lost); SNDRV_TIMER_IFLG_RUNNING)
? "running" : "stopped");
} }
spin_unlock_irqrestore(&timer->lock, flags); spin_unlock_irqrestore(&timer->lock, flags);
} }
@ -1088,7 +1117,7 @@ static void snd_timer_user_interrupt(snd_timer_instance_t *timeri,
snd_timer_user_t *tu = timeri->callback_data; snd_timer_user_t *tu = timeri->callback_data;
snd_timer_read_t *r; snd_timer_read_t *r;
int prev; int prev;
spin_lock(&tu->qlock); spin_lock(&tu->qlock);
if (tu->qused > 0) { if (tu->qused > 0) {
prev = tu->qtail == 0 ? tu->queue_size - 1 : tu->qtail - 1; prev = tu->qtail == 0 ? tu->queue_size - 1 : tu->qtail - 1;
@ -1113,7 +1142,8 @@ static void snd_timer_user_interrupt(snd_timer_instance_t *timeri,
wake_up(&tu->qchange_sleep); wake_up(&tu->qchange_sleep);
} }
static void snd_timer_user_append_to_tqueue(snd_timer_user_t *tu, snd_timer_tread_t *tread) static void snd_timer_user_append_to_tqueue(snd_timer_user_t *tu,
snd_timer_tread_t *tread)
{ {
if (tu->qused >= tu->queue_size) { if (tu->qused >= tu->queue_size) {
tu->overrun++; tu->overrun++;
@ -1132,7 +1162,8 @@ static void snd_timer_user_ccallback(snd_timer_instance_t *timeri,
snd_timer_user_t *tu = timeri->callback_data; snd_timer_user_t *tu = timeri->callback_data;
snd_timer_tread_t r1; snd_timer_tread_t r1;
if (event >= SNDRV_TIMER_EVENT_START && event <= SNDRV_TIMER_EVENT_PAUSE) if (event >= SNDRV_TIMER_EVENT_START &&
event <= SNDRV_TIMER_EVENT_PAUSE)
tu->tstamp = *tstamp; tu->tstamp = *tstamp;
if ((tu->filter & (1 << event)) == 0 || !tu->tread) if ((tu->filter & (1 << event)) == 0 || !tu->tread)
return; return;
@ -1155,15 +1186,17 @@ static void snd_timer_user_tinterrupt(snd_timer_instance_t *timeri,
struct timespec tstamp; struct timespec tstamp;
int prev, append = 0; int prev, append = 0;
snd_timestamp_zero(&tstamp); memset(&tstamp, 0, sizeof(tstamp));
spin_lock(&tu->qlock); spin_lock(&tu->qlock);
if ((tu->filter & ((1 << SNDRV_TIMER_EVENT_RESOLUTION)|(1 << SNDRV_TIMER_EVENT_TICK))) == 0) { if ((tu->filter & ((1 << SNDRV_TIMER_EVENT_RESOLUTION) |
(1 << SNDRV_TIMER_EVENT_TICK))) == 0) {
spin_unlock(&tu->qlock); spin_unlock(&tu->qlock);
return; return;
} }
if (tu->last_resolution != resolution || ticks > 0) if (tu->last_resolution != resolution || ticks > 0)
snd_timestamp_now(&tstamp, 1); getnstimeofday(&tstamp);
if ((tu->filter & (1 << SNDRV_TIMER_EVENT_RESOLUTION)) && tu->last_resolution != resolution) { if ((tu->filter & (1 << SNDRV_TIMER_EVENT_RESOLUTION)) &&
tu->last_resolution != resolution) {
r1.event = SNDRV_TIMER_EVENT_RESOLUTION; r1.event = SNDRV_TIMER_EVENT_RESOLUTION;
r1.tstamp = tstamp; r1.tstamp = tstamp;
r1.val = resolution; r1.val = resolution;
@ -1201,7 +1234,7 @@ static void snd_timer_user_tinterrupt(snd_timer_instance_t *timeri,
static int snd_timer_user_open(struct inode *inode, struct file *file) static int snd_timer_user_open(struct inode *inode, struct file *file)
{ {
snd_timer_user_t *tu; snd_timer_user_t *tu;
tu = kzalloc(sizeof(*tu), GFP_KERNEL); tu = kzalloc(sizeof(*tu), GFP_KERNEL);
if (tu == NULL) if (tu == NULL)
return -ENOMEM; return -ENOMEM;
@ -1210,7 +1243,8 @@ static int snd_timer_user_open(struct inode *inode, struct file *file)
init_MUTEX(&tu->tread_sem); init_MUTEX(&tu->tread_sem);
tu->ticks = 1; tu->ticks = 1;
tu->queue_size = 128; tu->queue_size = 128;
tu->queue = (snd_timer_read_t *)kmalloc(tu->queue_size * sizeof(snd_timer_read_t), GFP_KERNEL); tu->queue = kmalloc(tu->queue_size * sizeof(snd_timer_read_t),
GFP_KERNEL);
if (tu->queue == NULL) { if (tu->queue == NULL) {
kfree(tu); kfree(tu);
return -ENOMEM; return -ENOMEM;
@ -1259,7 +1293,7 @@ static int snd_timer_user_next_device(snd_timer_id_t __user *_tid)
snd_timer_id_t id; snd_timer_id_t id;
snd_timer_t *timer; snd_timer_t *timer;
struct list_head *p; struct list_head *p;
if (copy_from_user(&id, _tid, sizeof(id))) if (copy_from_user(&id, _tid, sizeof(id)))
return -EFAULT; return -EFAULT;
down(&register_mutex); down(&register_mutex);
@ -1267,7 +1301,8 @@ static int snd_timer_user_next_device(snd_timer_id_t __user *_tid)
if (list_empty(&snd_timer_list)) if (list_empty(&snd_timer_list))
snd_timer_user_zero_id(&id); snd_timer_user_zero_id(&id);
else { else {
timer = (snd_timer_t *)list_entry(snd_timer_list.next, snd_timer_t, device_list); timer = list_entry(snd_timer_list.next,
snd_timer_t, device_list);
snd_timer_user_copy_id(&id, timer); snd_timer_user_copy_id(&id, timer);
} }
} else { } else {
@ -1275,7 +1310,7 @@ static int snd_timer_user_next_device(snd_timer_id_t __user *_tid)
case SNDRV_TIMER_CLASS_GLOBAL: case SNDRV_TIMER_CLASS_GLOBAL:
id.device = id.device < 0 ? 0 : id.device + 1; id.device = id.device < 0 ? 0 : id.device + 1;
list_for_each(p, &snd_timer_list) { list_for_each(p, &snd_timer_list) {
timer = (snd_timer_t *)list_entry(p, snd_timer_t, device_list); timer = list_entry(p, snd_timer_t, device_list);
if (timer->tmr_class > SNDRV_TIMER_CLASS_GLOBAL) { if (timer->tmr_class > SNDRV_TIMER_CLASS_GLOBAL) {
snd_timer_user_copy_id(&id, timer); snd_timer_user_copy_id(&id, timer);
break; break;
@ -1299,12 +1334,16 @@ static int snd_timer_user_next_device(snd_timer_id_t __user *_tid)
if (id.device < 0) { if (id.device < 0) {
id.device = 0; id.device = 0;
} else { } else {
id.subdevice = id.subdevice < 0 ? 0 : id.subdevice + 1; if (id.subdevice < 0) {
id.subdevice = 0;
} else {
id.subdevice++;
}
} }
} }
} }
list_for_each(p, &snd_timer_list) { list_for_each(p, &snd_timer_list) {
timer = (snd_timer_t *)list_entry(p, snd_timer_t, device_list); timer = list_entry(p, snd_timer_t, device_list);
if (timer->tmr_class > id.dev_class) { if (timer->tmr_class > id.dev_class) {
snd_timer_user_copy_id(&id, timer); snd_timer_user_copy_id(&id, timer);
break; break;
@ -1343,9 +1382,10 @@ static int snd_timer_user_next_device(snd_timer_id_t __user *_tid)
if (copy_to_user(_tid, &id, sizeof(*_tid))) if (copy_to_user(_tid, &id, sizeof(*_tid)))
return -EFAULT; return -EFAULT;
return 0; return 0;
} }
static int snd_timer_user_ginfo(struct file *file, snd_timer_ginfo_t __user *_ginfo) static int snd_timer_user_ginfo(struct file *file,
snd_timer_ginfo_t __user *_ginfo)
{ {
snd_timer_ginfo_t *ginfo; snd_timer_ginfo_t *ginfo;
snd_timer_id_t tid; snd_timer_id_t tid;
@ -1389,7 +1429,8 @@ static int snd_timer_user_ginfo(struct file *file, snd_timer_ginfo_t __user *_gi
return err; return err;
} }
static int snd_timer_user_gparams(struct file *file, snd_timer_gparams_t __user *_gparams) static int snd_timer_user_gparams(struct file *file,
snd_timer_gparams_t __user *_gparams)
{ {
snd_timer_gparams_t gparams; snd_timer_gparams_t gparams;
snd_timer_t *t; snd_timer_t *t;
@ -1399,23 +1440,26 @@ static int snd_timer_user_gparams(struct file *file, snd_timer_gparams_t __user
return -EFAULT; return -EFAULT;
down(&register_mutex); down(&register_mutex);
t = snd_timer_find(&gparams.tid); t = snd_timer_find(&gparams.tid);
if (t != NULL) { if (!t) {
if (list_empty(&t->open_list_head)) {
if (t->hw.set_period)
err = t->hw.set_period(t, gparams.period_num, gparams.period_den);
else
err = -ENOSYS;
} else {
err = -EBUSY;
}
} else {
err = -ENODEV; err = -ENODEV;
goto _error;
} }
if (!list_empty(&t->open_list_head)) {
err = -EBUSY;
goto _error;
}
if (!t->hw.set_period) {
err = -ENOSYS;
goto _error;
}
err = t->hw.set_period(t, gparams.period_num, gparams.period_den);
_error:
up(&register_mutex); up(&register_mutex);
return err; return err;
} }
static int snd_timer_user_gstatus(struct file *file, snd_timer_gstatus_t __user *_gstatus) static int snd_timer_user_gstatus(struct file *file,
snd_timer_gstatus_t __user *_gstatus)
{ {
snd_timer_gstatus_t gstatus; snd_timer_gstatus_t gstatus;
snd_timer_id_t tid; snd_timer_id_t tid;
@ -1435,7 +1479,8 @@ static int snd_timer_user_gstatus(struct file *file, snd_timer_gstatus_t __user
else else
gstatus.resolution = t->hw.resolution; gstatus.resolution = t->hw.resolution;
if (t->hw.precise_resolution) { if (t->hw.precise_resolution) {
t->hw.precise_resolution(t, &gstatus.resolution_num, &gstatus.resolution_den); t->hw.precise_resolution(t, &gstatus.resolution_num,
&gstatus.resolution_den);
} else { } else {
gstatus.resolution_num = gstatus.resolution; gstatus.resolution_num = gstatus.resolution;
gstatus.resolution_den = 1000000000uL; gstatus.resolution_den = 1000000000uL;
@ -1449,13 +1494,14 @@ static int snd_timer_user_gstatus(struct file *file, snd_timer_gstatus_t __user
return err; return err;
} }
static int snd_timer_user_tselect(struct file *file, snd_timer_select_t __user *_tselect) static int snd_timer_user_tselect(struct file *file,
snd_timer_select_t __user *_tselect)
{ {
snd_timer_user_t *tu; snd_timer_user_t *tu;
snd_timer_select_t tselect; snd_timer_select_t tselect;
char str[32]; char str[32];
int err = 0; int err = 0;
tu = file->private_data; tu = file->private_data;
down(&tu->tread_sem); down(&tu->tread_sem);
if (tu->timeri) { if (tu->timeri) {
@ -1469,7 +1515,8 @@ static int snd_timer_user_tselect(struct file *file, snd_timer_select_t __user *
sprintf(str, "application %i", current->pid); sprintf(str, "application %i", current->pid);
if (tselect.id.dev_class != SNDRV_TIMER_CLASS_SLAVE) if (tselect.id.dev_class != SNDRV_TIMER_CLASS_SLAVE)
tselect.id.dev_sclass = SNDRV_TIMER_SCLASS_APPLICATION; tselect.id.dev_sclass = SNDRV_TIMER_SCLASS_APPLICATION;
if ((err = snd_timer_open(&tu->timeri, str, &tselect.id, current->pid)) < 0) err = snd_timer_open(&tu->timeri, str, &tselect.id, current->pid);
if (err < 0)
goto __err; goto __err;
kfree(tu->queue); kfree(tu->queue);
@ -1477,21 +1524,24 @@ static int snd_timer_user_tselect(struct file *file, snd_timer_select_t __user *
kfree(tu->tqueue); kfree(tu->tqueue);
tu->tqueue = NULL; tu->tqueue = NULL;
if (tu->tread) { if (tu->tread) {
tu->tqueue = (snd_timer_tread_t *)kmalloc(tu->queue_size * sizeof(snd_timer_tread_t), GFP_KERNEL); tu->tqueue = kmalloc(tu->queue_size * sizeof(snd_timer_tread_t),
GFP_KERNEL);
if (tu->tqueue == NULL) if (tu->tqueue == NULL)
err = -ENOMEM; err = -ENOMEM;
} else { } else {
tu->queue = (snd_timer_read_t *)kmalloc(tu->queue_size * sizeof(snd_timer_read_t), GFP_KERNEL); tu->queue = kmalloc(tu->queue_size * sizeof(snd_timer_read_t),
GFP_KERNEL);
if (tu->queue == NULL) if (tu->queue == NULL)
err = -ENOMEM; err = -ENOMEM;
} }
if (err < 0) { if (err < 0) {
snd_timer_close(tu->timeri); snd_timer_close(tu->timeri);
tu->timeri = NULL; tu->timeri = NULL;
} else { } else {
tu->timeri->flags |= SNDRV_TIMER_IFLG_FAST; tu->timeri->flags |= SNDRV_TIMER_IFLG_FAST;
tu->timeri->callback = tu->tread ? snd_timer_user_tinterrupt : snd_timer_user_interrupt; tu->timeri->callback = tu->tread
? snd_timer_user_tinterrupt : snd_timer_user_interrupt;
tu->timeri->ccallback = snd_timer_user_ccallback; tu->timeri->ccallback = snd_timer_user_ccallback;
tu->timeri->callback_data = (void *)tu; tu->timeri->callback_data = (void *)tu;
} }
@ -1501,7 +1551,8 @@ static int snd_timer_user_tselect(struct file *file, snd_timer_select_t __user *
return err; return err;
} }
static int snd_timer_user_info(struct file *file, snd_timer_info_t __user *_info) static int snd_timer_user_info(struct file *file,
snd_timer_info_t __user *_info)
{ {
snd_timer_user_t *tu; snd_timer_user_t *tu;
snd_timer_info_t *info; snd_timer_info_t *info;
@ -1528,7 +1579,8 @@ static int snd_timer_user_info(struct file *file, snd_timer_info_t __user *_info
return err; return err;
} }
static int snd_timer_user_params(struct file *file, snd_timer_params_t __user *_params) static int snd_timer_user_params(struct file *file,
snd_timer_params_t __user *_params)
{ {
snd_timer_user_t *tu; snd_timer_user_t *tu;
snd_timer_params_t params; snd_timer_params_t params;
@ -1536,7 +1588,7 @@ static int snd_timer_user_params(struct file *file, snd_timer_params_t __user *_
snd_timer_read_t *tr; snd_timer_read_t *tr;
snd_timer_tread_t *ttr; snd_timer_tread_t *ttr;
int err; int err;
tu = file->private_data; tu = file->private_data;
snd_assert(tu->timeri != NULL, return -ENXIO); snd_assert(tu->timeri != NULL, return -ENXIO);
t = tu->timeri->timer; t = tu->timeri->timer;
@ -1547,7 +1599,8 @@ static int snd_timer_user_params(struct file *file, snd_timer_params_t __user *_
err = -EINVAL; err = -EINVAL;
goto _end; goto _end;
} }
if (params.queue_size > 0 && (params.queue_size < 32 || params.queue_size > 1024)) { if (params.queue_size > 0 &&
(params.queue_size < 32 || params.queue_size > 1024)) {
err = -EINVAL; err = -EINVAL;
goto _end; goto _end;
} }
@ -1580,16 +1633,19 @@ static int snd_timer_user_params(struct file *file, snd_timer_params_t __user *_
if (params.flags & SNDRV_TIMER_PSFLG_EARLY_EVENT) if (params.flags & SNDRV_TIMER_PSFLG_EARLY_EVENT)
tu->timeri->flags |= SNDRV_TIMER_IFLG_EARLY_EVENT; tu->timeri->flags |= SNDRV_TIMER_IFLG_EARLY_EVENT;
spin_unlock_irq(&t->lock); spin_unlock_irq(&t->lock);
if (params.queue_size > 0 && (unsigned int)tu->queue_size != params.queue_size) { if (params.queue_size > 0 &&
(unsigned int)tu->queue_size != params.queue_size) {
if (tu->tread) { if (tu->tread) {
ttr = (snd_timer_tread_t *)kmalloc(params.queue_size * sizeof(snd_timer_tread_t), GFP_KERNEL); ttr = kmalloc(params.queue_size * sizeof(*ttr),
GFP_KERNEL);
if (ttr) { if (ttr) {
kfree(tu->tqueue); kfree(tu->tqueue);
tu->queue_size = params.queue_size; tu->queue_size = params.queue_size;
tu->tqueue = ttr; tu->tqueue = ttr;
} }
} else { } else {
tr = (snd_timer_read_t *)kmalloc(params.queue_size * sizeof(snd_timer_read_t), GFP_KERNEL); tr = kmalloc(params.queue_size * sizeof(*tr),
GFP_KERNEL);
if (tr) { if (tr) {
kfree(tu->queue); kfree(tu->queue);
tu->queue_size = params.queue_size; tu->queue_size = params.queue_size;
@ -1613,7 +1669,6 @@ static int snd_timer_user_params(struct file *file, snd_timer_params_t __user *_
tu->qused++; tu->qused++;
tu->qtail++; tu->qtail++;
} }
} }
tu->filter = params.filter; tu->filter = params.filter;
tu->ticks = params.ticks; tu->ticks = params.ticks;
@ -1624,11 +1679,12 @@ static int snd_timer_user_params(struct file *file, snd_timer_params_t __user *_
return err; return err;
} }
static int snd_timer_user_status(struct file *file, snd_timer_status_t __user *_status) static int snd_timer_user_status(struct file *file,
snd_timer_status_t __user *_status)
{ {
snd_timer_user_t *tu; snd_timer_user_t *tu;
snd_timer_status_t status; snd_timer_status_t status;
tu = file->private_data; tu = file->private_data;
snd_assert(tu->timeri != NULL, return -ENXIO); snd_assert(tu->timeri != NULL, return -ENXIO);
memset(&status, 0, sizeof(status)); memset(&status, 0, sizeof(status));
@ -1648,7 +1704,7 @@ static int snd_timer_user_start(struct file *file)
{ {
int err; int err;
snd_timer_user_t *tu; snd_timer_user_t *tu;
tu = file->private_data; tu = file->private_data;
snd_assert(tu->timeri != NULL, return -ENXIO); snd_assert(tu->timeri != NULL, return -ENXIO);
snd_timer_stop(tu->timeri); snd_timer_stop(tu->timeri);
@ -1661,7 +1717,7 @@ static int snd_timer_user_stop(struct file *file)
{ {
int err; int err;
snd_timer_user_t *tu; snd_timer_user_t *tu;
tu = file->private_data; tu = file->private_data;
snd_assert(tu->timeri != NULL, return -ENXIO); snd_assert(tu->timeri != NULL, return -ENXIO);
return (err = snd_timer_stop(tu->timeri)) < 0 ? err : 0; return (err = snd_timer_stop(tu->timeri)) < 0 ? err : 0;
@ -1671,7 +1727,7 @@ static int snd_timer_user_continue(struct file *file)
{ {
int err; int err;
snd_timer_user_t *tu; snd_timer_user_t *tu;
tu = file->private_data; tu = file->private_data;
snd_assert(tu->timeri != NULL, return -ENXIO); snd_assert(tu->timeri != NULL, return -ENXIO);
tu->timeri->lost = 0; tu->timeri->lost = 0;
@ -1682,7 +1738,7 @@ static int snd_timer_user_pause(struct file *file)
{ {
int err; int err;
snd_timer_user_t *tu; snd_timer_user_t *tu;
tu = file->private_data; tu = file->private_data;
snd_assert(tu->timeri != NULL, return -ENXIO); snd_assert(tu->timeri != NULL, return -ENXIO);
return (err = snd_timer_pause(tu->timeri)) < 0 ? err : 0; return (err = snd_timer_pause(tu->timeri)) < 0 ? err : 0;
@ -1695,12 +1751,13 @@ enum {
SNDRV_TIMER_IOCTL_PAUSE_OLD = _IO('T', 0x23), SNDRV_TIMER_IOCTL_PAUSE_OLD = _IO('T', 0x23),
}; };
static long snd_timer_user_ioctl(struct file *file, unsigned int cmd, unsigned long arg) static long snd_timer_user_ioctl(struct file *file, unsigned int cmd,
unsigned long arg)
{ {
snd_timer_user_t *tu; snd_timer_user_t *tu;
void __user *argp = (void __user *)arg; void __user *argp = (void __user *)arg;
int __user *p = argp; int __user *p = argp;
tu = file->private_data; tu = file->private_data;
switch (cmd) { switch (cmd) {
case SNDRV_TIMER_IOCTL_PVERSION: case SNDRV_TIMER_IOCTL_PVERSION:
@ -1710,7 +1767,7 @@ static long snd_timer_user_ioctl(struct file *file, unsigned int cmd, unsigned l
case SNDRV_TIMER_IOCTL_TREAD: case SNDRV_TIMER_IOCTL_TREAD:
{ {
int xarg; int xarg;
down(&tu->tread_sem); down(&tu->tread_sem);
if (tu->timeri) { /* too late */ if (tu->timeri) { /* too late */
up(&tu->tread_sem); up(&tu->tread_sem);
@ -1758,7 +1815,7 @@ static int snd_timer_user_fasync(int fd, struct file * file, int on)
{ {
snd_timer_user_t *tu; snd_timer_user_t *tu;
int err; int err;
tu = file->private_data; tu = file->private_data;
err = fasync_helper(fd, file, on, &tu->fasync); err = fasync_helper(fd, file, on, &tu->fasync);
if (err < 0) if (err < 0)
@ -1766,12 +1823,13 @@ static int snd_timer_user_fasync(int fd, struct file * file, int on)
return 0; return 0;
} }
static ssize_t snd_timer_user_read(struct file *file, char __user *buffer, size_t count, loff_t *offset) static ssize_t snd_timer_user_read(struct file *file, char __user *buffer,
size_t count, loff_t *offset)
{ {
snd_timer_user_t *tu; snd_timer_user_t *tu;
long result = 0, unit; long result = 0, unit;
int err = 0; int err = 0;
tu = file->private_data; tu = file->private_data;
unit = tu->tread ? sizeof(snd_timer_tread_t) : sizeof(snd_timer_read_t); unit = tu->tread ? sizeof(snd_timer_tread_t) : sizeof(snd_timer_read_t);
spin_lock_irq(&tu->qlock); spin_lock_irq(&tu->qlock);
@ -1805,12 +1863,14 @@ static ssize_t snd_timer_user_read(struct file *file, char __user *buffer, size_
goto _error; goto _error;
if (tu->tread) { if (tu->tread) {
if (copy_to_user(buffer, &tu->tqueue[tu->qhead++], sizeof(snd_timer_tread_t))) { if (copy_to_user(buffer, &tu->tqueue[tu->qhead++],
sizeof(snd_timer_tread_t))) {
err = -EFAULT; err = -EFAULT;
goto _error; goto _error;
} }
} else { } else {
if (copy_to_user(buffer, &tu->queue[tu->qhead++], sizeof(snd_timer_read_t))) { if (copy_to_user(buffer, &tu->queue[tu->qhead++],
sizeof(snd_timer_read_t))) {
err = -EFAULT; err = -EFAULT;
goto _error; goto _error;
} }
@ -1837,7 +1897,7 @@ static unsigned int snd_timer_user_poll(struct file *file, poll_table * wait)
tu = file->private_data; tu = file->private_data;
poll_wait(file, &tu->qchange_sleep, wait); poll_wait(file, &tu->qchange_sleep, wait);
mask = 0; mask = 0;
if (tu->qused) if (tu->qused)
mask |= POLLIN | POLLRDNORM; mask |= POLLIN | POLLRDNORM;
@ -1881,9 +1941,11 @@ static int __init alsa_timer_init(void)
snd_info_entry_t *entry; snd_info_entry_t *entry;
#ifdef SNDRV_OSS_INFO_DEV_TIMERS #ifdef SNDRV_OSS_INFO_DEV_TIMERS
snd_oss_info_register(SNDRV_OSS_INFO_DEV_TIMERS, SNDRV_CARDS - 1, "system timer"); snd_oss_info_register(SNDRV_OSS_INFO_DEV_TIMERS, SNDRV_CARDS - 1,
"system timer");
#endif #endif
if ((entry = snd_info_create_module_entry(THIS_MODULE, "timers", NULL)) != NULL) { entry = snd_info_create_module_entry(THIS_MODULE, "timers", NULL);
if (entry != NULL) {
entry->c.text.read_size = SNDRV_TIMER_DEVICES * 128; entry->c.text.read_size = SNDRV_TIMER_DEVICES * 128;
entry->c.text.read = snd_timer_proc_read; entry->c.text.read = snd_timer_proc_read;
if (snd_info_register(entry) < 0) { if (snd_info_register(entry) < 0) {
@ -1893,10 +1955,12 @@ static int __init alsa_timer_init(void)
} }
snd_timer_proc_entry = entry; snd_timer_proc_entry = entry;
if ((err = snd_timer_register_system()) < 0) if ((err = snd_timer_register_system()) < 0)
snd_printk(KERN_ERR "unable to register system timer (%i)\n", err); snd_printk(KERN_ERR "unable to register system timer (%i)\n",
err);
if ((err = snd_register_device(SNDRV_DEVICE_TYPE_TIMER, if ((err = snd_register_device(SNDRV_DEVICE_TYPE_TIMER,
NULL, 0, &snd_timer_reg, "timer"))<0) NULL, 0, &snd_timer_reg, "timer"))<0)
snd_printk(KERN_ERR "unable to register timer device (%i)\n", err); snd_printk(KERN_ERR "unable to register timer device (%i)\n",
err);
return 0; return 0;
} }
@ -1907,7 +1971,7 @@ static void __exit alsa_timer_exit(void)
snd_unregister_device(SNDRV_DEVICE_TYPE_TIMER, NULL, 0); snd_unregister_device(SNDRV_DEVICE_TYPE_TIMER, NULL, 0);
/* unregister the system timer */ /* unregister the system timer */
list_for_each_safe(p, n, &snd_timer_list) { list_for_each_safe(p, n, &snd_timer_list) {
snd_timer_t *timer = (snd_timer_t *)list_entry(p, snd_timer_t, device_list); snd_timer_t *timer = list_entry(p, snd_timer_t, device_list);
snd_timer_unregister(timer); snd_timer_unregister(timer);
} }
if (snd_timer_proc_entry) { if (snd_timer_proc_entry) {

View File

@ -1,50 +0,0 @@
/*
* Various wrappers
* Copyright (c) by 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
*
*/
#include <linux/config.h>
#include <linux/module.h>
#include <linux/slab.h>
#include <linux/ioport.h>
#include <linux/vmalloc.h>
#include <linux/fs.h>
#ifdef CONFIG_SND_DEBUG_MEMORY
void *snd_wrapper_kmalloc(size_t size, gfp_t flags)
{
return kmalloc(size, flags);
}
void snd_wrapper_kfree(const void *obj)
{
kfree(obj);
}
void *snd_wrapper_vmalloc(unsigned long size)
{
return vmalloc(size);
}
void snd_wrapper_vfree(void *obj)
{
vfree(obj);
}
#endif

View File

@ -423,10 +423,7 @@ static void snd_mpu401_uart_free(snd_rawmidi_t *rmidi)
mpu401_t *mpu = rmidi->private_data; mpu401_t *mpu = rmidi->private_data;
if (mpu->irq_flags && mpu->irq >= 0) if (mpu->irq_flags && mpu->irq >= 0)
free_irq(mpu->irq, (void *) mpu); free_irq(mpu->irq, (void *) mpu);
if (mpu->res) { release_and_free_resource(mpu->res);
release_resource(mpu->res);
kfree_nocheck(mpu->res);
}
kfree(mpu); kfree(mpu);
} }

View File

@ -717,10 +717,7 @@ static void free_mtpav(mtpav_t * crd)
spin_unlock_irqrestore(&crd->spinlock, flags); spin_unlock_irqrestore(&crd->spinlock, flags);
if (crd->irq >= 0) if (crd->irq >= 0)
free_irq(crd->irq, (void *)crd); free_irq(crd->irq, (void *)crd);
if (crd->res_port) { release_and_free_resource(crd->res_port);
release_resource(crd->res_port);
kfree_nocheck(crd->res_port);
}
kfree(crd); kfree(crd);
} }

View File

@ -325,14 +325,8 @@ static int snd_opl3_free(opl3_t *opl3)
snd_assert(opl3 != NULL, return -ENXIO); snd_assert(opl3 != NULL, return -ENXIO);
if (opl3->private_free) if (opl3->private_free)
opl3->private_free(opl3); opl3->private_free(opl3);
if (opl3->res_l_port) { release_and_free_resource(opl3->res_l_port);
release_resource(opl3->res_l_port); release_and_free_resource(opl3->res_r_port);
kfree_nocheck(opl3->res_l_port);
}
if (opl3->res_r_port) {
release_resource(opl3->res_r_port);
kfree_nocheck(opl3->res_r_port);
}
kfree(opl3); kfree(opl3);
return 0; return 0;
} }

View File

@ -169,14 +169,8 @@ static void snd_opl4_free(opl4_t *opl4)
#ifdef CONFIG_PROC_FS #ifdef CONFIG_PROC_FS
snd_opl4_free_proc(opl4); snd_opl4_free_proc(opl4);
#endif #endif
if (opl4->res_fm_port) { release_and_free_resource(opl4->res_fm_port);
release_resource(opl4->res_fm_port); release_and_free_resource(opl4->res_pcm_port);
kfree_nocheck(opl4->res_fm_port);
}
if (opl4->res_pcm_port) {
release_resource(opl4->res_pcm_port);
kfree_nocheck(opl4->res_pcm_port);
}
kfree(opl4); kfree(opl4);
} }

View File

@ -749,10 +749,7 @@ static int snd_uart16550_free(snd_uart16550_t *uart)
{ {
if (uart->irq >= 0) if (uart->irq >= 0)
free_irq(uart->irq, (void *)uart); free_irq(uart->irq, (void *)uart);
if (uart->res_base) { release_and_free_resource(uart->res_base);
release_resource(uart->res_base);
kfree_nocheck(uart->res_base);
}
kfree(uart); kfree(uart);
return 0; return 0;
}; };

View File

@ -79,7 +79,7 @@ static int snd_pcm_alloc_vmalloc_buffer(snd_pcm_substream_t *subs, size_t size)
/* already allocated */ /* already allocated */
if (runtime->dma_bytes >= size) if (runtime->dma_bytes >= size)
return 0; /* already enough large */ return 0; /* already enough large */
vfree_nocheck(runtime->dma_area); /* bypass the memory wrapper */ vfree(runtime->dma_area);
} }
runtime->dma_area = vmalloc_32(size); runtime->dma_area = vmalloc_32(size);
if (! runtime->dma_area) if (! runtime->dma_area)
@ -98,7 +98,7 @@ static int snd_pcm_free_vmalloc_buffer(snd_pcm_substream_t *subs)
{ {
snd_pcm_runtime_t *runtime = subs->runtime; snd_pcm_runtime_t *runtime = subs->runtime;
if (runtime->dma_area) { if (runtime->dma_area) {
vfree_nocheck(runtime->dma_area); /* bypass the memory wrapper */ vfree(runtime->dma_area);
runtime->dma_area = NULL; runtime->dma_area = NULL;
} }
return 0; return 0;

View File

@ -75,7 +75,7 @@ int snd_cs8427_reg_write(snd_i2c_device_t *device, unsigned char reg, unsigned c
buf[0] = reg & 0x7f; buf[0] = reg & 0x7f;
buf[1] = val; buf[1] = val;
if ((err = snd_i2c_sendbytes(device, buf, 2)) != 2) { if ((err = snd_i2c_sendbytes(device, buf, 2)) != 2) {
snd_printk("unable to send bytes 0x%02x:0x%02x to CS8427 (%i)\n", buf[0], buf[1], err); snd_printk(KERN_ERR "unable to send bytes 0x%02x:0x%02x to CS8427 (%i)\n", buf[0], buf[1], err);
return err < 0 ? err : -EIO; return err < 0 ? err : -EIO;
} }
return 0; return 0;
@ -87,11 +87,11 @@ static int snd_cs8427_reg_read(snd_i2c_device_t *device, unsigned char reg)
unsigned char buf; unsigned char buf;
if ((err = snd_i2c_sendbytes(device, &reg, 1)) != 1) { if ((err = snd_i2c_sendbytes(device, &reg, 1)) != 1) {
snd_printk("unable to send register 0x%x byte to CS8427\n", reg); snd_printk(KERN_ERR "unable to send register 0x%x byte to CS8427\n", reg);
return err < 0 ? err : -EIO; return err < 0 ? err : -EIO;
} }
if ((err = snd_i2c_readbytes(device, &buf, 1)) != 1) { if ((err = snd_i2c_readbytes(device, &buf, 1)) != 1) {
snd_printk("unable to read register 0x%x byte from CS8427\n", reg); snd_printk(KERN_ERR "unable to read register 0x%x byte from CS8427\n", reg);
return err < 0 ? err : -EIO; return err < 0 ? err : -EIO;
} }
return buf; return buf;
@ -210,7 +210,7 @@ int snd_cs8427_create(snd_i2c_bus_t *bus,
snd_i2c_lock(bus); snd_i2c_lock(bus);
if ((err = snd_cs8427_reg_read(device, CS8427_REG_ID_AND_VER)) != CS8427_VER8427A) { if ((err = snd_cs8427_reg_read(device, CS8427_REG_ID_AND_VER)) != CS8427_VER8427A) {
snd_i2c_unlock(bus); snd_i2c_unlock(bus);
snd_printk("unable to find CS8427 signature (expected 0x%x, read 0x%x), initialization is not completed\n", CS8427_VER8427A, err); snd_printk(KERN_ERR "unable to find CS8427 signature (expected 0x%x, read 0x%x), initialization is not completed\n", CS8427_VER8427A, err);
return -EFAULT; return -EFAULT;
} }
/* turn off run bit while making changes to configuration */ /* turn off run bit while making changes to configuration */
@ -260,7 +260,7 @@ int snd_cs8427_create(snd_i2c_bus_t *bus,
snd_i2c_sendbytes(device, buf, 1); snd_i2c_sendbytes(device, buf, 1);
snd_i2c_readbytes(device, buf, 127); snd_i2c_readbytes(device, buf, 127);
for (xx = 0; xx < 127; xx++) for (xx = 0; xx < 127; xx++)
printk("reg[0x%x] = 0x%x\n", xx+1, buf[xx]); printk(KERN_DEBUG "reg[0x%x] = 0x%x\n", xx+1, buf[xx]);
} }
#endif #endif
@ -302,8 +302,7 @@ static void snd_cs8427_reset(snd_i2c_device_t *cs8427)
snd_i2c_unlock(cs8427->bus); snd_i2c_unlock(cs8427->bus);
if (!(data & CS8427_UNLOCK)) if (!(data & CS8427_UNLOCK))
break; break;
set_current_state(TASK_UNINTERRUPTIBLE); schedule_timeout_uninterruptible(1);
schedule_timeout(1);
} }
snd_i2c_lock(cs8427->bus); snd_i2c_lock(cs8427->bus);
chip->regmap[CS8427_REG_CLOCKSOURCE] &= ~CS8427_RXDMASK; chip->regmap[CS8427_REG_CLOCKSOURCE] &= ~CS8427_RXDMASK;
@ -354,12 +353,12 @@ static int snd_cs8427_qsubcode_get(snd_kcontrol_t *kcontrol,
snd_i2c_lock(device->bus); snd_i2c_lock(device->bus);
if ((err = snd_i2c_sendbytes(device, &reg, 1)) != 1) { if ((err = snd_i2c_sendbytes(device, &reg, 1)) != 1) {
snd_printk("unable to send register 0x%x byte to CS8427\n", reg); snd_printk(KERN_ERR "unable to send register 0x%x byte to CS8427\n", reg);
snd_i2c_unlock(device->bus); snd_i2c_unlock(device->bus);
return err < 0 ? err : -EIO; return err < 0 ? err : -EIO;
} }
if ((err = snd_i2c_readbytes(device, ucontrol->value.bytes.data, 10)) != 10) { if ((err = snd_i2c_readbytes(device, ucontrol->value.bytes.data, 10)) != 10) {
snd_printk("unable to read Q-subcode bytes from CS8427\n"); snd_printk(KERN_ERR "unable to read Q-subcode bytes from CS8427\n");
snd_i2c_unlock(device->bus); snd_i2c_unlock(device->bus);
return err < 0 ? err : -EIO; return err < 0 ? err : -EIO;
} }

View File

@ -56,9 +56,9 @@ static void reg_dump(ak4114_t *ak4114)
{ {
int i; int i;
printk("AK4114 REG DUMP:\n"); printk(KERN_DEBUG "AK4114 REG DUMP:\n");
for (i = 0; i < 0x20; i++) for (i = 0; i < 0x20; i++)
printk("reg[%02x] = %02x (%02x)\n", i, reg_read(ak4114, i), i < sizeof(ak4114->regmap) ? ak4114->regmap[i] : 0); printk(KERN_DEBUG "reg[%02x] = %02x (%02x)\n", i, reg_read(ak4114, i), i < sizeof(ak4114->regmap) ? ak4114->regmap[i] : 0);
} }
#endif #endif
@ -552,7 +552,7 @@ int snd_ak4114_check_rate_and_errors(ak4114_t *ak4114, unsigned int flags)
if (!(flags & AK4114_CHECK_NO_RATE) && runtime && runtime->rate != res) { if (!(flags & AK4114_CHECK_NO_RATE) && runtime && runtime->rate != res) {
snd_pcm_stream_lock_irqsave(ak4114->capture_substream, _flags); snd_pcm_stream_lock_irqsave(ak4114->capture_substream, _flags);
if (snd_pcm_running(ak4114->capture_substream)) { if (snd_pcm_running(ak4114->capture_substream)) {
// printk("rate changed (%i <- %i)\n", runtime->rate, res); // printk(KERN_DEBUG "rate changed (%i <- %i)\n", runtime->rate, res);
snd_pcm_stop(ak4114->capture_substream, SNDRV_PCM_STATE_DRAINING); snd_pcm_stop(ak4114->capture_substream, SNDRV_PCM_STATE_DRAINING);
res = 1; res = 1;
} }

View File

@ -54,9 +54,9 @@ static void reg_dump(ak4117_t *ak4117)
{ {
int i; int i;
printk("AK4117 REG DUMP:\n"); printk(KERN_DEBUG "AK4117 REG DUMP:\n");
for (i = 0; i < 0x1b; i++) for (i = 0; i < 0x1b; i++)
printk("reg[%02x] = %02x (%02x)\n", i, reg_read(ak4117, i), i < sizeof(ak4117->regmap) ? ak4117->regmap[i] : 0); printk(KERN_DEBUG "reg[%02x] = %02x (%02x)\n", i, reg_read(ak4117, i), i < sizeof(ak4117->regmap) ? ak4117->regmap[i] : 0);
} }
#endif #endif
@ -477,7 +477,7 @@ int snd_ak4117_check_rate_and_errors(ak4117_t *ak4117, unsigned int flags)
goto __rate; goto __rate;
rcs0 = reg_read(ak4117, AK4117_REG_RCS0); rcs0 = reg_read(ak4117, AK4117_REG_RCS0);
rcs2 = reg_read(ak4117, AK4117_REG_RCS2); rcs2 = reg_read(ak4117, AK4117_REG_RCS2);
// printk("AK IRQ: rcs0 = 0x%x, rcs1 = 0x%x, rcs2 = 0x%x\n", rcs0, rcs1, rcs2); // printk(KERN_DEBUG "AK IRQ: rcs0 = 0x%x, rcs1 = 0x%x, rcs2 = 0x%x\n", rcs0, rcs1, rcs2);
spin_lock_irqsave(&ak4117->lock, _flags); spin_lock_irqsave(&ak4117->lock, _flags);
if (rcs0 & AK4117_PAR) if (rcs0 & AK4117_PAR)
ak4117->parity_errors++; ak4117->parity_errors++;
@ -530,7 +530,7 @@ int snd_ak4117_check_rate_and_errors(ak4117_t *ak4117, unsigned int flags)
if (!(flags & AK4117_CHECK_NO_RATE) && runtime && runtime->rate != res) { if (!(flags & AK4117_CHECK_NO_RATE) && runtime && runtime->rate != res) {
snd_pcm_stream_lock_irqsave(ak4117->substream, _flags); snd_pcm_stream_lock_irqsave(ak4117->substream, _flags);
if (snd_pcm_running(ak4117->substream)) { if (snd_pcm_running(ak4117->substream)) {
// printk("rate changed (%i <- %i)\n", runtime->rate, res); // printk(KERN_DEBUG "rate changed (%i <- %i)\n", runtime->rate, res);
snd_pcm_stop(ak4117->substream, SNDRV_PCM_STATE_DRAINING); snd_pcm_stop(ak4117->substream, SNDRV_PCM_STATE_DRAINING);
wake_up(&runtime->sleep); wake_up(&runtime->sleep);
res = 1; res = 1;

View File

@ -58,7 +58,7 @@ static void snd_tea6330t_set(tea6330t_t *tea,
unsigned char addr, unsigned char value) unsigned char addr, unsigned char value)
{ {
#if 0 #if 0
printk("set - 0x%x/0x%x\n", addr, value); printk(KERN_DEBUG "set - 0x%x/0x%x\n", addr, value);
#endif #endif
snd_i2c_write(tea->bus, TEA6330T_ADDR, addr, value, 1); snd_i2c_write(tea->bus, TEA6330T_ADDR, addr, value, 1);
} }

View File

@ -542,10 +542,7 @@ static int snd_ad1816a_probe(ad1816a_t *chip)
static int snd_ad1816a_free(ad1816a_t *chip) static int snd_ad1816a_free(ad1816a_t *chip)
{ {
if (chip->res_port) { release_and_free_resource(chip->res_port);
release_resource(chip->res_port);
kfree_nocheck(chip->res_port);
}
if (chip->irq >= 0) if (chip->irq >= 0)
free_irq(chip->irq, (void *) chip); free_irq(chip->irq, (void *) chip);
if (chip->dma1 >= 0) { if (chip->dma1 >= 0) {

View File

@ -109,7 +109,7 @@ void snd_ad1848_out(ad1848_t *chip,
udelay(100); udelay(100);
#ifdef CONFIG_SND_DEBUG #ifdef CONFIG_SND_DEBUG
if (inb(AD1848P(chip, REGSEL)) & AD1848_INIT) if (inb(AD1848P(chip, REGSEL)) & AD1848_INIT)
snd_printk("auto calibration time out - reg = 0x%x, value = 0x%x\n", reg, value); snd_printk(KERN_WARNING "auto calibration time out - reg = 0x%x, value = 0x%x\n", reg, value);
#endif #endif
outb(chip->mce_bit | reg, AD1848P(chip, REGSEL)); outb(chip->mce_bit | reg, AD1848P(chip, REGSEL));
outb(chip->image[reg] = value, AD1848P(chip, REG)); outb(chip->image[reg] = value, AD1848P(chip, REG));
@ -139,7 +139,7 @@ static unsigned char snd_ad1848_in(ad1848_t *chip, unsigned char reg)
udelay(100); udelay(100);
#ifdef CONFIG_SND_DEBUG #ifdef CONFIG_SND_DEBUG
if (inb(AD1848P(chip, REGSEL)) & AD1848_INIT) if (inb(AD1848P(chip, REGSEL)) & AD1848_INIT)
snd_printk("auto calibration time out - reg = 0x%x\n", reg); snd_printk(KERN_WARNING "auto calibration time out - reg = 0x%x\n", reg);
#endif #endif
outb(chip->mce_bit | reg, AD1848P(chip, REGSEL)); outb(chip->mce_bit | reg, AD1848P(chip, REGSEL));
mb(); mb();
@ -185,13 +185,13 @@ static void snd_ad1848_mce_up(ad1848_t *chip)
udelay(100); udelay(100);
#ifdef CONFIG_SND_DEBUG #ifdef CONFIG_SND_DEBUG
if (inb(AD1848P(chip, REGSEL)) & AD1848_INIT) if (inb(AD1848P(chip, REGSEL)) & AD1848_INIT)
snd_printk("mce_up - auto calibration time out (0)\n"); snd_printk(KERN_WARNING "mce_up - auto calibration time out (0)\n");
#endif #endif
spin_lock_irqsave(&chip->reg_lock, flags); spin_lock_irqsave(&chip->reg_lock, flags);
chip->mce_bit |= AD1848_MCE; chip->mce_bit |= AD1848_MCE;
timeout = inb(AD1848P(chip, REGSEL)); timeout = inb(AD1848P(chip, REGSEL));
if (timeout == 0x80) if (timeout == 0x80)
snd_printk("mce_up [0x%lx]: serious init problem - codec still busy\n", chip->port); snd_printk(KERN_WARNING "mce_up [0x%lx]: serious init problem - codec still busy\n", chip->port);
if (!(timeout & AD1848_MCE)) if (!(timeout & AD1848_MCE))
outb(chip->mce_bit | (timeout & 0x1f), AD1848P(chip, REGSEL)); outb(chip->mce_bit | (timeout & 0x1f), AD1848P(chip, REGSEL));
spin_unlock_irqrestore(&chip->reg_lock, flags); spin_unlock_irqrestore(&chip->reg_lock, flags);
@ -214,13 +214,13 @@ static void snd_ad1848_mce_down(ad1848_t *chip)
#endif #endif
#ifdef CONFIG_SND_DEBUG #ifdef CONFIG_SND_DEBUG
if (inb(AD1848P(chip, REGSEL)) & AD1848_INIT) if (inb(AD1848P(chip, REGSEL)) & AD1848_INIT)
snd_printk("mce_down [0x%lx] - auto calibration time out (0)\n", AD1848P(chip, REGSEL)); snd_printk(KERN_WARNING "mce_down [0x%lx] - auto calibration time out (0)\n", AD1848P(chip, REGSEL));
#endif #endif
chip->mce_bit &= ~AD1848_MCE; chip->mce_bit &= ~AD1848_MCE;
timeout = inb(AD1848P(chip, REGSEL)); timeout = inb(AD1848P(chip, REGSEL));
outb(chip->mce_bit | (timeout & 0x1f), AD1848P(chip, REGSEL)); outb(chip->mce_bit | (timeout & 0x1f), AD1848P(chip, REGSEL));
if (timeout == 0x80) if (timeout == 0x80)
snd_printk("mce_down [0x%lx]: serious init problem - codec still busy\n", chip->port); snd_printk(KERN_WARNING "mce_down [0x%lx]: serious init problem - codec still busy\n", chip->port);
if ((timeout & AD1848_MCE) == 0) { if ((timeout & AD1848_MCE) == 0) {
spin_unlock_irqrestore(&chip->reg_lock, flags); spin_unlock_irqrestore(&chip->reg_lock, flags);
return; return;
@ -240,11 +240,10 @@ static void snd_ad1848_mce_down(ad1848_t *chip)
while (snd_ad1848_in(chip, AD1848_TEST_INIT) & AD1848_CALIB_IN_PROGRESS) { while (snd_ad1848_in(chip, AD1848_TEST_INIT) & AD1848_CALIB_IN_PROGRESS) {
spin_unlock_irqrestore(&chip->reg_lock, flags); spin_unlock_irqrestore(&chip->reg_lock, flags);
if (time <= 0) { if (time <= 0) {
snd_printk("mce_down - auto calibration time out (2)\n"); snd_printk(KERN_ERR "mce_down - auto calibration time out (2)\n");
return; return;
} }
set_current_state(TASK_INTERRUPTIBLE); time = schedule_timeout_interruptible(time);
time = schedule_timeout(time);
spin_lock_irqsave(&chip->reg_lock, flags); spin_lock_irqsave(&chip->reg_lock, flags);
} }
#if 0 #if 0
@ -254,11 +253,10 @@ static void snd_ad1848_mce_down(ad1848_t *chip)
while (inb(AD1848P(chip, REGSEL)) & AD1848_INIT) { while (inb(AD1848P(chip, REGSEL)) & AD1848_INIT) {
spin_unlock_irqrestore(&chip->reg_lock, flags); spin_unlock_irqrestore(&chip->reg_lock, flags);
if (time <= 0) { if (time <= 0) {
snd_printk("mce_down - auto calibration time out (3)\n"); snd_printk(KERN_ERR "mce_down - auto calibration time out (3)\n");
return; return;
} }
set_current_state(TASK_INTERRUPTIBLE); time = schedule_timeout_interruptible(time);
time = schedule_timeout(time);
spin_lock_irqsave(&chip->reg_lock, flags); spin_lock_irqsave(&chip->reg_lock, flags);
} }
spin_unlock_irqrestore(&chip->reg_lock, flags); spin_unlock_irqrestore(&chip->reg_lock, flags);
@ -846,10 +844,7 @@ static int snd_ad1848_capture_close(snd_pcm_substream_t * substream)
static int snd_ad1848_free(ad1848_t *chip) static int snd_ad1848_free(ad1848_t *chip)
{ {
if (chip->res_port) { release_and_free_resource(chip->res_port);
release_resource(chip->res_port);
kfree_nocheck(chip->res_port);
}
if (chip->irq >= 0) if (chip->irq >= 0)
free_irq(chip->irq, (void *) chip); free_irq(chip->irq, (void *) chip);
if (chip->dma >= 0) { if (chip->dma >= 0) {

View File

@ -1417,14 +1417,8 @@ static int snd_cs4231_pm_resume(snd_card_t *card)
static int snd_cs4231_free(cs4231_t *chip) static int snd_cs4231_free(cs4231_t *chip)
{ {
if (chip->res_port) { release_and_free_resource(chip->res_port);
release_resource(chip->res_port); release_and_free_resource(chip->res_cport);
kfree_nocheck(chip->res_port);
}
if (chip->res_cport) {
release_resource(chip->res_cport);
kfree_nocheck(chip->res_cport);
}
if (chip->irq >= 0) { if (chip->irq >= 0) {
disable_irq(chip->irq); disable_irq(chip->irq);
if (!(chip->hwshare & CS4231_HWSHARE_IRQ)) if (!(chip->hwshare & CS4231_HWSHARE_IRQ))

View File

@ -379,12 +379,8 @@ static void snd_card_cs4236_free(snd_card_t *card)
{ {
struct snd_card_cs4236 *acard = (struct snd_card_cs4236 *)card->private_data; struct snd_card_cs4236 *acard = (struct snd_card_cs4236 *)card->private_data;
if (acard) { if (acard)
if (acard->res_sb_port) { release_and_free_resource(acard->res_sb_port);
release_resource(acard->res_sb_port);
kfree_nocheck(acard->res_sb_port);
}
}
} }
#ifdef CONFIG_PNP #ifdef CONFIG_PNP

View File

@ -173,7 +173,10 @@ static unsigned char divisor_to_rate_register(unsigned int divisor)
case 2117: return 6; case 2117: return 6;
case 2558: return 7; case 2558: return 7;
default: default:
snd_runtime_check(divisor >= 21 && divisor <= 192, return 192); if (divisor < 21 || divisor > 192) {
snd_BUG();
return 192;
}
return divisor; return divisor;
} }
} }

View File

@ -606,8 +606,7 @@ static int snd_es1688_free(es1688_t *chip)
{ {
if (chip->res_port) { if (chip->res_port) {
snd_es1688_init(chip, 0); snd_es1688_init(chip, 0);
release_resource(chip->res_port); release_and_free_resource(chip->res_port);
kfree_nocheck(chip->res_port);
} }
if (chip->irq >= 0) if (chip->irq >= 0)
free_irq(chip->irq, (void *) chip); free_irq(chip->irq, (void *) chip);

View File

@ -173,7 +173,7 @@ static int snd_es18xx_dsp_command(es18xx_t *chip, unsigned char val)
outb(val, chip->port + 0x0C); outb(val, chip->port + 0x0C);
return 0; return 0;
} }
snd_printk("dsp_command: timeout (0x%x)\n", val); snd_printk(KERN_ERR "dsp_command: timeout (0x%x)\n", val);
return -EINVAL; return -EINVAL;
} }
@ -184,7 +184,8 @@ static int snd_es18xx_dsp_get_byte(es18xx_t *chip)
for(i = MILLISECOND/10; i; i--) for(i = MILLISECOND/10; i; i--)
if (inb(chip->port + 0x0C) & 0x40) if (inb(chip->port + 0x0C) & 0x40)
return inb(chip->port + 0x0A); return inb(chip->port + 0x0A);
snd_printk("dsp_get_byte failed: 0x%lx = 0x%x!!!\n", chip->port + 0x0A, inb(chip->port + 0x0A)); snd_printk(KERN_ERR "dsp_get_byte failed: 0x%lx = 0x%x!!!\n",
chip->port + 0x0A, inb(chip->port + 0x0A));
return -ENODEV; return -ENODEV;
} }
@ -204,7 +205,7 @@ static int snd_es18xx_write(es18xx_t *chip,
end: end:
spin_unlock_irqrestore(&chip->reg_lock, flags); spin_unlock_irqrestore(&chip->reg_lock, flags);
#ifdef REG_DEBUG #ifdef REG_DEBUG
snd_printk("Reg %02x set to %02x\n", reg, data); snd_printk(KERN_DEBUG "Reg %02x set to %02x\n", reg, data);
#endif #endif
return ret; return ret;
} }
@ -223,7 +224,7 @@ static int snd_es18xx_read(es18xx_t *chip, unsigned char reg)
data = snd_es18xx_dsp_get_byte(chip); data = snd_es18xx_dsp_get_byte(chip);
ret = data; ret = data;
#ifdef REG_DEBUG #ifdef REG_DEBUG
snd_printk("Reg %02x now is %02x (%d)\n", reg, data, ret); snd_printk(KERN_DEBUG "Reg %02x now is %02x (%d)\n", reg, data, ret);
#endif #endif
end: end:
spin_unlock_irqrestore(&chip->reg_lock, flags); spin_unlock_irqrestore(&chip->reg_lock, flags);
@ -259,7 +260,8 @@ static int snd_es18xx_bits(es18xx_t *chip, unsigned char reg,
if (ret < 0) if (ret < 0)
goto end; goto end;
#ifdef REG_DEBUG #ifdef REG_DEBUG
snd_printk("Reg %02x was %02x, set to %02x (%d)\n", reg, old, new, ret); snd_printk(KERN_DEBUG "Reg %02x was %02x, set to %02x (%d)\n",
reg, old, new, ret);
#endif #endif
} }
ret = oval; ret = oval;
@ -277,7 +279,7 @@ static inline void snd_es18xx_mixer_write(es18xx_t *chip,
outb(data, chip->port + 0x05); outb(data, chip->port + 0x05);
spin_unlock_irqrestore(&chip->mixer_lock, flags); spin_unlock_irqrestore(&chip->mixer_lock, flags);
#ifdef REG_DEBUG #ifdef REG_DEBUG
snd_printk("Mixer reg %02x set to %02x\n", reg, data); snd_printk(KERN_DEBUG "Mixer reg %02x set to %02x\n", reg, data);
#endif #endif
} }
@ -290,7 +292,7 @@ static inline int snd_es18xx_mixer_read(es18xx_t *chip, unsigned char reg)
data = inb(chip->port + 0x05); data = inb(chip->port + 0x05);
spin_unlock_irqrestore(&chip->mixer_lock, flags); spin_unlock_irqrestore(&chip->mixer_lock, flags);
#ifdef REG_DEBUG #ifdef REG_DEBUG
snd_printk("Mixer reg %02x now is %02x\n", reg, data); snd_printk(KERN_DEBUG "Mixer reg %02x now is %02x\n", reg, data);
#endif #endif
return data; return data;
} }
@ -309,7 +311,8 @@ static inline int snd_es18xx_mixer_bits(es18xx_t *chip, unsigned char reg,
new = (old & ~mask) | (val & mask); new = (old & ~mask) | (val & mask);
outb(new, chip->port + 0x05); outb(new, chip->port + 0x05);
#ifdef REG_DEBUG #ifdef REG_DEBUG
snd_printk("Mixer reg %02x was %02x, set to %02x\n", reg, old, new); snd_printk(KERN_DEBUG "Mixer reg %02x was %02x, set to %02x\n",
reg, old, new);
#endif #endif
} }
spin_unlock_irqrestore(&chip->mixer_lock, flags); spin_unlock_irqrestore(&chip->mixer_lock, flags);
@ -329,7 +332,8 @@ static inline int snd_es18xx_mixer_writable(es18xx_t *chip, unsigned char reg,
new = inb(chip->port + 0x05); new = inb(chip->port + 0x05);
spin_unlock_irqrestore(&chip->mixer_lock, flags); spin_unlock_irqrestore(&chip->mixer_lock, flags);
#ifdef REG_DEBUG #ifdef REG_DEBUG
snd_printk("Mixer reg %02x was %02x, set to %02x, now is %02x\n", reg, old, expected, new); snd_printk(KERN_DEBUG "Mixer reg %02x was %02x, set to %02x, now is %02x\n",
reg, old, expected, new);
#endif #endif
return expected == new; return expected == new;
} }
@ -1281,7 +1285,7 @@ static void __devinit snd_es18xx_config_write(es18xx_t *chip,
outb(reg, chip->ctrl_port); outb(reg, chip->ctrl_port);
outb(data, chip->ctrl_port + 1); outb(data, chip->ctrl_port + 1);
#ifdef REG_DEBUG #ifdef REG_DEBUG
snd_printk("Config reg %02x set to %02x\n", reg, data); snd_printk(KERN_DEBUG "Config reg %02x set to %02x\n", reg, data);
#endif #endif
} }
@ -1346,7 +1350,7 @@ static int __devinit snd_es18xx_initialize(es18xx_t *chip)
irqmask = 3; irqmask = 3;
break; break;
default: default:
snd_printk("invalid irq %d\n", chip->irq); snd_printk(KERN_ERR "invalid irq %d\n", chip->irq);
return -ENODEV; return -ENODEV;
} }
switch (chip->dma1) { switch (chip->dma1) {
@ -1360,7 +1364,7 @@ static int __devinit snd_es18xx_initialize(es18xx_t *chip)
dma1mask = 3; dma1mask = 3;
break; break;
default: default:
snd_printk("invalid dma1 %d\n", chip->dma1); snd_printk(KERN_ERR "invalid dma1 %d\n", chip->dma1);
return -ENODEV; return -ENODEV;
} }
switch (chip->dma2) { switch (chip->dma2) {
@ -1377,7 +1381,7 @@ static int __devinit snd_es18xx_initialize(es18xx_t *chip)
dma2mask = 3; dma2mask = 3;
break; break;
default: default:
snd_printk("invalid dma2 %d\n", chip->dma2); snd_printk(KERN_ERR "invalid dma2 %d\n", chip->dma2);
return -ENODEV; return -ENODEV;
} }
@ -1440,7 +1444,7 @@ static int __devinit snd_es18xx_identify(es18xx_t *chip)
/* reset */ /* reset */
if (snd_es18xx_reset(chip) < 0) { if (snd_es18xx_reset(chip) < 0) {
snd_printk("reset at 0x%lx failed!!!\n", chip->port); snd_printk(KERN_ERR "reset at 0x%lx failed!!!\n", chip->port);
return -ENODEV; return -ENODEV;
} }
@ -1527,7 +1531,7 @@ static int __devinit snd_es18xx_probe(es18xx_t *chip)
chip->caps = ES18XX_PCM2 | ES18XX_RECMIX | ES18XX_AUXB | ES18XX_DUPLEX_SAME | ES18XX_HWV; chip->caps = ES18XX_PCM2 | ES18XX_RECMIX | ES18XX_AUXB | ES18XX_DUPLEX_SAME | ES18XX_HWV;
break; break;
default: default:
snd_printk("[0x%lx] unsupported chip ES%x\n", snd_printk(KERN_ERR "[0x%lx] unsupported chip ES%x\n",
chip->port, chip->version); chip->port, chip->version);
return -ENODEV; return -ENODEV;
} }
@ -1640,18 +1644,9 @@ static int snd_es18xx_resume(snd_card_t *card)
static int snd_es18xx_free(es18xx_t *chip) static int snd_es18xx_free(es18xx_t *chip)
{ {
if (chip->res_port) { release_and_free_resource(chip->res_port);
release_resource(chip->res_port); release_and_free_resource(chip->res_ctrl_port);
kfree_nocheck(chip->res_port); release_and_free_resource(chip->res_mpu_port);
}
if (chip->res_ctrl_port) {
release_resource(chip->res_ctrl_port);
kfree_nocheck(chip->res_ctrl_port);
}
if (chip->res_mpu_port) {
release_resource(chip->res_mpu_port);
kfree_nocheck(chip->res_mpu_port);
}
if (chip->irq >= 0) if (chip->irq >= 0)
free_irq(chip->irq, (void *) chip); free_irq(chip->irq, (void *) chip);
if (chip->dma1 >= 0) { if (chip->dma1 >= 0) {

View File

@ -199,7 +199,7 @@ int snd_gf1_dma_transfer_block(snd_gus_card_t * gus,
block = kmalloc(sizeof(*block), atomic ? GFP_ATOMIC : GFP_KERNEL); block = kmalloc(sizeof(*block), atomic ? GFP_ATOMIC : GFP_KERNEL);
if (block == NULL) { if (block == NULL) {
snd_printk("gf1: DMA transfer failure; not enough memory\n"); snd_printk(KERN_ERR "gf1: DMA transfer failure; not enough memory\n");
return -ENOMEM; return -ENOMEM;
} }
*block = *__block; *block = *__block;

View File

@ -343,7 +343,7 @@ void snd_gf1_pokew(snd_gus_card_t * gus, unsigned int addr, unsigned short data)
#ifdef CONFIG_SND_DEBUG #ifdef CONFIG_SND_DEBUG
if (!gus->interwave) if (!gus->interwave)
snd_printk("snd_gf1_pokew - GF1!!!\n"); snd_printk(KERN_DEBUG "snd_gf1_pokew - GF1!!!\n");
#endif #endif
spin_lock_irqsave(&gus->reg_lock, flags); spin_lock_irqsave(&gus->reg_lock, flags);
outb(SNDRV_GF1_GW_DRAM_IO_LOW, gus->gf1.reg_regsel); outb(SNDRV_GF1_GW_DRAM_IO_LOW, gus->gf1.reg_regsel);
@ -367,7 +367,7 @@ unsigned short snd_gf1_peekw(snd_gus_card_t * gus, unsigned int addr)
#ifdef CONFIG_SND_DEBUG #ifdef CONFIG_SND_DEBUG
if (!gus->interwave) if (!gus->interwave)
snd_printk("snd_gf1_peekw - GF1!!!\n"); snd_printk(KERN_DEBUG "snd_gf1_peekw - GF1!!!\n");
#endif #endif
spin_lock_irqsave(&gus->reg_lock, flags); spin_lock_irqsave(&gus->reg_lock, flags);
outb(SNDRV_GF1_GW_DRAM_IO_LOW, gus->gf1.reg_regsel); outb(SNDRV_GF1_GW_DRAM_IO_LOW, gus->gf1.reg_regsel);
@ -393,7 +393,7 @@ void snd_gf1_dram_setmem(snd_gus_card_t * gus, unsigned int addr,
#ifdef CONFIG_SND_DEBUG #ifdef CONFIG_SND_DEBUG
if (!gus->interwave) if (!gus->interwave)
snd_printk("snd_gf1_dram_setmem - GF1!!!\n"); snd_printk(KERN_DEBUG "snd_gf1_dram_setmem - GF1!!!\n");
#endif #endif
addr &= ~1; addr &= ~1;
count >>= 1; count >>= 1;
@ -449,30 +449,30 @@ void snd_gf1_print_voice_registers(snd_gus_card_t * gus)
int voice, ctrl; int voice, ctrl;
voice = gus->gf1.active_voice; voice = gus->gf1.active_voice;
printk(" -%i- GF1 voice ctrl, ramp ctrl = 0x%x, 0x%x\n", voice, ctrl = snd_gf1_i_read8(gus, 0), snd_gf1_i_read8(gus, 0x0d)); printk(KERN_INFO " -%i- GF1 voice ctrl, ramp ctrl = 0x%x, 0x%x\n", voice, ctrl = snd_gf1_i_read8(gus, 0), snd_gf1_i_read8(gus, 0x0d));
printk(" -%i- GF1 frequency = 0x%x\n", voice, snd_gf1_i_read16(gus, 1)); printk(KERN_INFO " -%i- GF1 frequency = 0x%x\n", voice, snd_gf1_i_read16(gus, 1));
printk(" -%i- GF1 loop start, end = 0x%x (0x%x), 0x%x (0x%x)\n", voice, snd_gf1_i_read_addr(gus, 2, ctrl & 4), snd_gf1_i_read_addr(gus, 2, (ctrl & 4) ^ 4), snd_gf1_i_read_addr(gus, 4, ctrl & 4), snd_gf1_i_read_addr(gus, 4, (ctrl & 4) ^ 4)); printk(KERN_INFO " -%i- GF1 loop start, end = 0x%x (0x%x), 0x%x (0x%x)\n", voice, snd_gf1_i_read_addr(gus, 2, ctrl & 4), snd_gf1_i_read_addr(gus, 2, (ctrl & 4) ^ 4), snd_gf1_i_read_addr(gus, 4, ctrl & 4), snd_gf1_i_read_addr(gus, 4, (ctrl & 4) ^ 4));
printk(" -%i- GF1 ramp start, end, rate = 0x%x, 0x%x, 0x%x\n", voice, snd_gf1_i_read8(gus, 7), snd_gf1_i_read8(gus, 8), snd_gf1_i_read8(gus, 6)); printk(KERN_INFO " -%i- GF1 ramp start, end, rate = 0x%x, 0x%x, 0x%x\n", voice, snd_gf1_i_read8(gus, 7), snd_gf1_i_read8(gus, 8), snd_gf1_i_read8(gus, 6));
printk(" -%i- GF1 volume = 0x%x\n", voice, snd_gf1_i_read16(gus, 9)); printk(KERN_INFO" -%i- GF1 volume = 0x%x\n", voice, snd_gf1_i_read16(gus, 9));
printk(" -%i- GF1 position = 0x%x (0x%x)\n", voice, snd_gf1_i_read_addr(gus, 0x0a, ctrl & 4), snd_gf1_i_read_addr(gus, 0x0a, (ctrl & 4) ^ 4)); printk(KERN_INFO " -%i- GF1 position = 0x%x (0x%x)\n", voice, snd_gf1_i_read_addr(gus, 0x0a, ctrl & 4), snd_gf1_i_read_addr(gus, 0x0a, (ctrl & 4) ^ 4));
if (gus->interwave && snd_gf1_i_read8(gus, 0x19) & 0x01) { /* enhanced mode */ if (gus->interwave && snd_gf1_i_read8(gus, 0x19) & 0x01) { /* enhanced mode */
mode = snd_gf1_i_read8(gus, 0x15); mode = snd_gf1_i_read8(gus, 0x15);
printk(" -%i- GFA1 mode = 0x%x\n", voice, mode); printk(KERN_INFO " -%i- GFA1 mode = 0x%x\n", voice, mode);
if (mode & 0x01) { /* Effect processor */ if (mode & 0x01) { /* Effect processor */
printk(" -%i- GFA1 effect address = 0x%x\n", voice, snd_gf1_i_read_addr(gus, 0x11, ctrl & 4)); printk(KERN_INFO " -%i- GFA1 effect address = 0x%x\n", voice, snd_gf1_i_read_addr(gus, 0x11, ctrl & 4));
printk(" -%i- GFA1 effect volume = 0x%x\n", voice, snd_gf1_i_read16(gus, 0x16)); printk(KERN_INFO " -%i- GFA1 effect volume = 0x%x\n", voice, snd_gf1_i_read16(gus, 0x16));
printk(" -%i- GFA1 effect volume final = 0x%x\n", voice, snd_gf1_i_read16(gus, 0x1d)); printk(KERN_INFO " -%i- GFA1 effect volume final = 0x%x\n", voice, snd_gf1_i_read16(gus, 0x1d));
printk(" -%i- GFA1 effect acumulator = 0x%x\n", voice, snd_gf1_i_read8(gus, 0x14)); printk(KERN_INFO " -%i- GFA1 effect acumulator = 0x%x\n", voice, snd_gf1_i_read8(gus, 0x14));
} }
if (mode & 0x20) { if (mode & 0x20) {
printk(" -%i- GFA1 left offset = 0x%x (%i)\n", voice, snd_gf1_i_read16(gus, 0x13), snd_gf1_i_read16(gus, 0x13) >> 4); printk(KERN_INFO " -%i- GFA1 left offset = 0x%x (%i)\n", voice, snd_gf1_i_read16(gus, 0x13), snd_gf1_i_read16(gus, 0x13) >> 4);
printk(" -%i- GFA1 left offset final = 0x%x (%i)\n", voice, snd_gf1_i_read16(gus, 0x1c), snd_gf1_i_read16(gus, 0x1c) >> 4); printk(KERN_INFO " -%i- GFA1 left offset final = 0x%x (%i)\n", voice, snd_gf1_i_read16(gus, 0x1c), snd_gf1_i_read16(gus, 0x1c) >> 4);
printk(" -%i- GFA1 right offset = 0x%x (%i)\n", voice, snd_gf1_i_read16(gus, 0x0c), snd_gf1_i_read16(gus, 0x0c) >> 4); printk(KERN_INFO " -%i- GFA1 right offset = 0x%x (%i)\n", voice, snd_gf1_i_read16(gus, 0x0c), snd_gf1_i_read16(gus, 0x0c) >> 4);
printk(" -%i- GFA1 right offset final = 0x%x (%i)\n", voice, snd_gf1_i_read16(gus, 0x1b), snd_gf1_i_read16(gus, 0x1b) >> 4); printk(KERN_INFO " -%i- GFA1 right offset final = 0x%x (%i)\n", voice, snd_gf1_i_read16(gus, 0x1b), snd_gf1_i_read16(gus, 0x1b) >> 4);
} else } else
printk(" -%i- GF1 pan = 0x%x\n", voice, snd_gf1_i_read8(gus, 0x0c)); printk(KERN_INFO " -%i- GF1 pan = 0x%x\n", voice, snd_gf1_i_read8(gus, 0x0c));
} else } else
printk(" -%i- GF1 pan = 0x%x\n", voice, snd_gf1_i_read8(gus, 0x0c)); printk(KERN_INFO " -%i- GF1 pan = 0x%x\n", voice, snd_gf1_i_read8(gus, 0x0c));
} }
#if 0 #if 0
@ -481,45 +481,45 @@ void snd_gf1_print_global_registers(snd_gus_card_t * gus)
{ {
unsigned char global_mode = 0x00; unsigned char global_mode = 0x00;
printk(" -G- GF1 active voices = 0x%x\n", snd_gf1_i_look8(gus, SNDRV_GF1_GB_ACTIVE_VOICES)); printk(KERN_INFO " -G- GF1 active voices = 0x%x\n", snd_gf1_i_look8(gus, SNDRV_GF1_GB_ACTIVE_VOICES));
if (gus->interwave) { if (gus->interwave) {
global_mode = snd_gf1_i_read8(gus, SNDRV_GF1_GB_GLOBAL_MODE); global_mode = snd_gf1_i_read8(gus, SNDRV_GF1_GB_GLOBAL_MODE);
printk(" -G- GF1 global mode = 0x%x\n", global_mode); printk(KERN_INFO " -G- GF1 global mode = 0x%x\n", global_mode);
} }
if (global_mode & 0x02) /* LFO enabled? */ if (global_mode & 0x02) /* LFO enabled? */
printk(" -G- GF1 LFO base = 0x%x\n", snd_gf1_i_look16(gus, SNDRV_GF1_GW_LFO_BASE)); printk(KERN_INFO " -G- GF1 LFO base = 0x%x\n", snd_gf1_i_look16(gus, SNDRV_GF1_GW_LFO_BASE));
printk(" -G- GF1 voices IRQ read = 0x%x\n", snd_gf1_i_look8(gus, SNDRV_GF1_GB_VOICES_IRQ_READ)); printk(KERN_INFO " -G- GF1 voices IRQ read = 0x%x\n", snd_gf1_i_look8(gus, SNDRV_GF1_GB_VOICES_IRQ_READ));
printk(" -G- GF1 DRAM DMA control = 0x%x\n", snd_gf1_i_look8(gus, SNDRV_GF1_GB_DRAM_DMA_CONTROL)); printk(KERN_INFO " -G- GF1 DRAM DMA control = 0x%x\n", snd_gf1_i_look8(gus, SNDRV_GF1_GB_DRAM_DMA_CONTROL));
printk(" -G- GF1 DRAM DMA high/low = 0x%x/0x%x\n", snd_gf1_i_look8(gus, SNDRV_GF1_GB_DRAM_DMA_HIGH), snd_gf1_i_read16(gus, SNDRV_GF1_GW_DRAM_DMA_LOW)); printk(KERN_INFO " -G- GF1 DRAM DMA high/low = 0x%x/0x%x\n", snd_gf1_i_look8(gus, SNDRV_GF1_GB_DRAM_DMA_HIGH), snd_gf1_i_read16(gus, SNDRV_GF1_GW_DRAM_DMA_LOW));
printk(" -G- GF1 DRAM IO high/low = 0x%x/0x%x\n", snd_gf1_i_look8(gus, SNDRV_GF1_GB_DRAM_IO_HIGH), snd_gf1_i_read16(gus, SNDRV_GF1_GW_DRAM_IO_LOW)); printk(KERN_INFO " -G- GF1 DRAM IO high/low = 0x%x/0x%x\n", snd_gf1_i_look8(gus, SNDRV_GF1_GB_DRAM_IO_HIGH), snd_gf1_i_read16(gus, SNDRV_GF1_GW_DRAM_IO_LOW));
if (!gus->interwave) if (!gus->interwave)
printk(" -G- GF1 record DMA control = 0x%x\n", snd_gf1_i_look8(gus, SNDRV_GF1_GB_REC_DMA_CONTROL)); printk(KERN_INFO " -G- GF1 record DMA control = 0x%x\n", snd_gf1_i_look8(gus, SNDRV_GF1_GB_REC_DMA_CONTROL));
printk(" -G- GF1 DRAM IO 16 = 0x%x\n", snd_gf1_i_look16(gus, SNDRV_GF1_GW_DRAM_IO16)); printk(KERN_INFO " -G- GF1 DRAM IO 16 = 0x%x\n", snd_gf1_i_look16(gus, SNDRV_GF1_GW_DRAM_IO16));
if (gus->gf1.enh_mode) { if (gus->gf1.enh_mode) {
printk(" -G- GFA1 memory config = 0x%x\n", snd_gf1_i_look16(gus, SNDRV_GF1_GW_MEMORY_CONFIG)); printk(KERN_INFO " -G- GFA1 memory config = 0x%x\n", snd_gf1_i_look16(gus, SNDRV_GF1_GW_MEMORY_CONFIG));
printk(" -G- GFA1 memory control = 0x%x\n", snd_gf1_i_look8(gus, SNDRV_GF1_GB_MEMORY_CONTROL)); printk(KERN_INFO " -G- GFA1 memory control = 0x%x\n", snd_gf1_i_look8(gus, SNDRV_GF1_GB_MEMORY_CONTROL));
printk(" -G- GFA1 FIFO record base = 0x%x\n", snd_gf1_i_look16(gus, SNDRV_GF1_GW_FIFO_RECORD_BASE_ADDR)); printk(KERN_INFO " -G- GFA1 FIFO record base = 0x%x\n", snd_gf1_i_look16(gus, SNDRV_GF1_GW_FIFO_RECORD_BASE_ADDR));
printk(" -G- GFA1 FIFO playback base = 0x%x\n", snd_gf1_i_look16(gus, SNDRV_GF1_GW_FIFO_PLAY_BASE_ADDR)); printk(KERN_INFO " -G- GFA1 FIFO playback base = 0x%x\n", snd_gf1_i_look16(gus, SNDRV_GF1_GW_FIFO_PLAY_BASE_ADDR));
printk(" -G- GFA1 interleave control = 0x%x\n", snd_gf1_i_look16(gus, SNDRV_GF1_GW_INTERLEAVE)); printk(KERN_INFO " -G- GFA1 interleave control = 0x%x\n", snd_gf1_i_look16(gus, SNDRV_GF1_GW_INTERLEAVE));
} }
} }
void snd_gf1_print_setup_registers(snd_gus_card_t * gus) void snd_gf1_print_setup_registers(snd_gus_card_t * gus)
{ {
printk(" -S- mix control = 0x%x\n", inb(GUSP(gus, MIXCNTRLREG))); printk(KERN_INFO " -S- mix control = 0x%x\n", inb(GUSP(gus, MIXCNTRLREG)));
printk(" -S- IRQ status = 0x%x\n", inb(GUSP(gus, IRQSTAT))); printk(KERN_INFO " -S- IRQ status = 0x%x\n", inb(GUSP(gus, IRQSTAT)));
printk(" -S- timer control = 0x%x\n", inb(GUSP(gus, TIMERCNTRL))); printk(KERN_INFO " -S- timer control = 0x%x\n", inb(GUSP(gus, TIMERCNTRL)));
printk(" -S- timer data = 0x%x\n", inb(GUSP(gus, TIMERDATA))); printk(KERN_INFO " -S- timer data = 0x%x\n", inb(GUSP(gus, TIMERDATA)));
printk(" -S- status read = 0x%x\n", inb(GUSP(gus, REGCNTRLS))); printk(KERN_INFO " -S- status read = 0x%x\n", inb(GUSP(gus, REGCNTRLS)));
printk(" -S- Sound Blaster control = 0x%x\n", snd_gf1_i_look8(gus, SNDRV_GF1_GB_SOUND_BLASTER_CONTROL)); printk(KERN_INFO " -S- Sound Blaster control = 0x%x\n", snd_gf1_i_look8(gus, SNDRV_GF1_GB_SOUND_BLASTER_CONTROL));
printk(" -S- AdLib timer 1/2 = 0x%x/0x%x\n", snd_gf1_i_look8(gus, SNDRV_GF1_GB_ADLIB_TIMER_1), snd_gf1_i_look8(gus, SNDRV_GF1_GB_ADLIB_TIMER_2)); printk(KERN_INFO " -S- AdLib timer 1/2 = 0x%x/0x%x\n", snd_gf1_i_look8(gus, SNDRV_GF1_GB_ADLIB_TIMER_1), snd_gf1_i_look8(gus, SNDRV_GF1_GB_ADLIB_TIMER_2));
printk(" -S- reset = 0x%x\n", snd_gf1_i_look8(gus, SNDRV_GF1_GB_RESET)); printk(KERN_INFO " -S- reset = 0x%x\n", snd_gf1_i_look8(gus, SNDRV_GF1_GB_RESET));
if (gus->interwave) { if (gus->interwave) {
printk(" -S- compatibility = 0x%x\n", snd_gf1_i_look8(gus, SNDRV_GF1_GB_COMPATIBILITY)); printk(KERN_INFO " -S- compatibility = 0x%x\n", snd_gf1_i_look8(gus, SNDRV_GF1_GB_COMPATIBILITY));
printk(" -S- decode control = 0x%x\n", snd_gf1_i_look8(gus, SNDRV_GF1_GB_DECODE_CONTROL)); printk(KERN_INFO " -S- decode control = 0x%x\n", snd_gf1_i_look8(gus, SNDRV_GF1_GB_DECODE_CONTROL));
printk(" -S- version number = 0x%x\n", snd_gf1_i_look8(gus, SNDRV_GF1_GB_VERSION_NUMBER)); printk(KERN_INFO " -S- version number = 0x%x\n", snd_gf1_i_look8(gus, SNDRV_GF1_GB_VERSION_NUMBER));
printk(" -S- MPU-401 emul. control A/B = 0x%x/0x%x\n", snd_gf1_i_look8(gus, SNDRV_GF1_GB_MPU401_CONTROL_A), snd_gf1_i_look8(gus, SNDRV_GF1_GB_MPU401_CONTROL_B)); printk(KERN_INFO " -S- MPU-401 emul. control A/B = 0x%x/0x%x\n", snd_gf1_i_look8(gus, SNDRV_GF1_GB_MPU401_CONTROL_A), snd_gf1_i_look8(gus, SNDRV_GF1_GB_MPU401_CONTROL_B));
printk(" -S- emulation IRQ = 0x%x\n", snd_gf1_i_look8(gus, SNDRV_GF1_GB_EMULATION_IRQ)); printk(KERN_INFO " -S- emulation IRQ = 0x%x\n", snd_gf1_i_look8(gus, SNDRV_GF1_GB_EMULATION_IRQ));
} }
} }

View File

@ -113,14 +113,8 @@ static int snd_gus_free(snd_gus_card_t *gus)
snd_gf1_stop(gus); snd_gf1_stop(gus);
snd_gus_init_dma_irq(gus, 0); snd_gus_init_dma_irq(gus, 0);
__hw_end: __hw_end:
if (gus->gf1.res_port1) { release_and_free_resource(gus->gf1.res_port1);
release_resource(gus->gf1.res_port1); release_and_free_resource(gus->gf1.res_port2);
kfree_nocheck(gus->gf1.res_port1);
}
if (gus->gf1.res_port2) {
release_resource(gus->gf1.res_port2);
kfree_nocheck(gus->gf1.res_port2);
}
if (gus->gf1.irq >= 0) if (gus->gf1.irq >= 0)
free_irq(gus->gf1.irq, (void *) gus); free_irq(gus->gf1.irq, (void *) gus);
if (gus->gf1.dma1 >= 0) { if (gus->gf1.dma1 >= 0) {
@ -252,7 +246,7 @@ static int snd_gus_detect_memory(snd_gus_card_t * gus)
snd_gf1_poke(gus, 0L, 0xaa); snd_gf1_poke(gus, 0L, 0xaa);
snd_gf1_poke(gus, 1L, 0x55); snd_gf1_poke(gus, 1L, 0x55);
if (snd_gf1_peek(gus, 0L) != 0xaa || snd_gf1_peek(gus, 1L) != 0x55) { if (snd_gf1_peek(gus, 0L) != 0xaa || snd_gf1_peek(gus, 1L) != 0x55) {
snd_printk("plain GF1 card at 0x%lx without onboard DRAM?\n", gus->gf1.port); snd_printk(KERN_ERR "plain GF1 card at 0x%lx without onboard DRAM?\n", gus->gf1.port);
return -ENOMEM; return -ENOMEM;
} }
for (idx = 1, d = 0xab; idx < 4; idx++, d++) { for (idx = 1, d = 0xab; idx < 4; idx++, d++) {
@ -305,20 +299,17 @@ static int snd_gus_init_dma_irq(snd_gus_card_t * gus, int latches)
dma2 = gus->gf1.dma2; dma2 = gus->gf1.dma2;
dma2 = dma2 < 0 ? -dma2 : dma2; dma2 = dma2 < 0 ? -dma2 : dma2;
dma2 = dmas[dma2 & 7]; dma2 = dmas[dma2 & 7];
#if 0
printk("dma1 = %i, dma2 = %i\n", gus->gf1.dma1, gus->gf1.dma2);
#endif
dma1 |= gus->equal_dma ? 0x40 : (dma2 << 3); dma1 |= gus->equal_dma ? 0x40 : (dma2 << 3);
if ((dma1 & 7) == 0 || (dma2 & 7) == 0) { if ((dma1 & 7) == 0 || (dma2 & 7) == 0) {
snd_printk("Error! DMA isn't defined.\n"); snd_printk(KERN_ERR "Error! DMA isn't defined.\n");
return -EINVAL; return -EINVAL;
} }
irq = gus->gf1.irq; irq = gus->gf1.irq;
irq = irq < 0 ? -irq : irq; irq = irq < 0 ? -irq : irq;
irq = irqs[irq & 0x0f]; irq = irqs[irq & 0x0f];
if (irq == 0) { if (irq == 0) {
snd_printk("Error! IRQ isn't defined.\n"); snd_printk(KERN_ERR "Error! IRQ isn't defined.\n");
return -EINVAL; return -EINVAL;
} }
irq |= 0x40; irq |= 0x40;
@ -406,8 +397,8 @@ static int snd_gus_check_version(snd_gus_card_t * gus)
strcpy(card->longname, "Gravis UltraSound Extreme"); strcpy(card->longname, "Gravis UltraSound Extreme");
gus->ess_flag = 1; gus->ess_flag = 1;
} else { } else {
snd_printk("unknown GF1 revision number at 0x%lx - 0x%x (0x%x)\n", gus->gf1.port, rev, val); snd_printk(KERN_ERR "unknown GF1 revision number at 0x%lx - 0x%x (0x%x)\n", gus->gf1.port, rev, val);
snd_printk(" please - report to <perex@suse.cz>\n"); snd_printk(KERN_ERR " please - report to <perex@suse.cz>\n");
} }
} }
} }
@ -431,7 +422,7 @@ int snd_gus_initialize(snd_gus_card_t *gus)
if (!gus->interwave) { if (!gus->interwave) {
if ((err = snd_gus_check_version(gus)) < 0) { if ((err = snd_gus_check_version(gus)) < 0) {
snd_printk("version check failed\n"); snd_printk(KERN_ERR "version check failed\n");
return err; return err;
} }
if ((err = snd_gus_detect_memory(gus)) < 0) if ((err = snd_gus_detect_memory(gus)) < 0)

View File

@ -198,7 +198,7 @@ snd_gf1_mem_block_t *snd_gf1_mem_alloc(snd_gf1_mem_t * alloc, int owner,
if (nblock != NULL) { if (nblock != NULL) {
if (size != (int)nblock->size) { if (size != (int)nblock->size) {
/* TODO: remove in the future */ /* TODO: remove in the future */
snd_printk("snd_gf1_mem_alloc - share: sizes differ\n"); snd_printk(KERN_ERR "snd_gf1_mem_alloc - share: sizes differ\n");
goto __std; goto __std;
} }
nblock->share++; nblock->share++;

View File

@ -333,8 +333,7 @@ static int snd_gf1_pcm_poke_block(snd_gus_card_t *gus, unsigned char *buf,
} }
} }
if (count > 0 && !in_interrupt()) { if (count > 0 && !in_interrupt()) {
set_current_state(TASK_INTERRUPTIBLE); schedule_timeout_interruptible(1);
schedule_timeout(1);
if (signal_pending(current)) if (signal_pending(current))
return -EAGAIN; return -EAGAIN;
} }
@ -698,7 +697,7 @@ static int snd_gf1_pcm_playback_close(snd_pcm_substream_t * substream)
gus_pcm_private_t *pcmp = runtime->private_data; gus_pcm_private_t *pcmp = runtime->private_data;
if (!wait_event_timeout(pcmp->sleep, (atomic_read(&pcmp->dma_count) <= 0), 2*HZ)) if (!wait_event_timeout(pcmp->sleep, (atomic_read(&pcmp->dma_count) <= 0), 2*HZ))
snd_printk("gf1 pcm - serious DMA problem\n"); snd_printk(KERN_ERR "gf1 pcm - serious DMA problem\n");
snd_gf1_dma_done(gus); snd_gf1_dma_done(gus);
return 0; return 0;

View File

@ -134,7 +134,7 @@ void snd_gf1_smart_stop_voice(snd_gus_card_t * gus, unsigned short voice)
spin_lock_irqsave(&gus->reg_lock, flags); spin_lock_irqsave(&gus->reg_lock, flags);
snd_gf1_select_voice(gus, voice); snd_gf1_select_voice(gus, voice);
#if 0 #if 0
printk(" -%i- smart stop voice - volume = 0x%x\n", voice, snd_gf1_i_read16(gus, SNDRV_GF1_VW_VOLUME)); printk(KERN_DEBUG " -%i- smart stop voice - volume = 0x%x\n", voice, snd_gf1_i_read16(gus, SNDRV_GF1_VW_VOLUME));
#endif #endif
snd_gf1_ctrl_stop(gus, SNDRV_GF1_VB_ADDRESS_CONTROL); snd_gf1_ctrl_stop(gus, SNDRV_GF1_VB_ADDRESS_CONTROL);
snd_gf1_ctrl_stop(gus, SNDRV_GF1_VB_VOLUME_CONTROL); snd_gf1_ctrl_stop(gus, SNDRV_GF1_VB_VOLUME_CONTROL);
@ -148,7 +148,7 @@ void snd_gf1_stop_voice(snd_gus_card_t * gus, unsigned short voice)
spin_lock_irqsave(&gus->reg_lock, flags); spin_lock_irqsave(&gus->reg_lock, flags);
snd_gf1_select_voice(gus, voice); snd_gf1_select_voice(gus, voice);
#if 0 #if 0
printk(" -%i- stop voice - volume = 0x%x\n", voice, snd_gf1_i_read16(gus, SNDRV_GF1_VW_VOLUME)); printk(KERN_DEBUG " -%i- stop voice - volume = 0x%x\n", voice, snd_gf1_i_read16(gus, SNDRV_GF1_VW_VOLUME));
#endif #endif
snd_gf1_ctrl_stop(gus, SNDRV_GF1_VB_ADDRESS_CONTROL); snd_gf1_ctrl_stop(gus, SNDRV_GF1_VB_ADDRESS_CONTROL);
snd_gf1_ctrl_stop(gus, SNDRV_GF1_VB_VOLUME_CONTROL); snd_gf1_ctrl_stop(gus, SNDRV_GF1_VB_VOLUME_CONTROL);

View File

@ -136,7 +136,7 @@ static void do_volume_envelope(snd_gus_card_t *gus, snd_gus_voice_t *voice)
snd_gf1_select_voice(gus, voice->number); snd_gf1_select_voice(gus, voice->number);
snd_gf1_ctrl_stop(gus, SNDRV_GF1_VB_VOLUME_CONTROL); snd_gf1_ctrl_stop(gus, SNDRV_GF1_VB_VOLUME_CONTROL);
snd_gf1_write16(gus, SNDRV_GF1_VW_VOLUME, voice->gf1_volume); snd_gf1_write16(gus, SNDRV_GF1_VW_VOLUME, voice->gf1_volume);
printk("gf1_volume = 0x%x\n", voice->gf1_volume); /* printk("gf1_volume = 0x%x\n", voice->gf1_volume); */
spin_unlock_irqrestore(&gus->reg_lock, flags); spin_unlock_irqrestore(&gus->reg_lock, flags);
return; return;
} }

View File

@ -104,7 +104,7 @@ static int snd_gf1_uart_output_open(snd_rawmidi_substream_t * substream)
gus->midi_substream_output = substream; gus->midi_substream_output = substream;
spin_unlock_irqrestore(&gus->uart_cmd_lock, flags); spin_unlock_irqrestore(&gus->uart_cmd_lock, flags);
#if 0 #if 0
snd_printk("write init - cmd = 0x%x, stat = 0x%x\n", gus->gf1.uart_cmd, snd_gf1_uart_stat(gus)); snd_printk(KERN_DEBUG "write init - cmd = 0x%x, stat = 0x%x\n", gus->gf1.uart_cmd, snd_gf1_uart_stat(gus));
#endif #endif
return 0; return 0;
} }
@ -126,7 +126,7 @@ static int snd_gf1_uart_input_open(snd_rawmidi_substream_t * substream)
for (i = 0; i < 1000 && (snd_gf1_uart_stat(gus) & 0x01); i++) for (i = 0; i < 1000 && (snd_gf1_uart_stat(gus) & 0x01); i++)
snd_gf1_uart_get(gus); /* clean Rx */ snd_gf1_uart_get(gus); /* clean Rx */
if (i >= 1000) if (i >= 1000)
snd_printk("gus midi uart init read - cleanup error\n"); snd_printk(KERN_ERR "gus midi uart init read - cleanup error\n");
} }
spin_unlock_irqrestore(&gus->uart_cmd_lock, flags); spin_unlock_irqrestore(&gus->uart_cmd_lock, flags);
#if 0 #if 0

View File

@ -119,7 +119,7 @@ unsigned short snd_gf1_translate_freq(snd_gus_card_t * gus, unsigned int freq16)
freq16 = 50; freq16 = 50;
if (freq16 & 0xf8000000) { if (freq16 & 0xf8000000) {
freq16 = ~0xf8000000; freq16 = ~0xf8000000;
snd_printk("snd_gf1_translate_freq: overflow - freq = 0x%x\n", freq16); snd_printk(KERN_ERR "snd_gf1_translate_freq: overflow - freq = 0x%x\n", freq16);
} }
return ((freq16 << 9) + (gus->gf1.playback_freq >> 1)) / gus->gf1.playback_freq; return ((freq16 << 9) + (gus->gf1.playback_freq >> 1)) / gus->gf1.playback_freq;
} }
@ -203,14 +203,14 @@ unsigned short snd_gf1_compute_freq(unsigned int freq,
fc = (freq << 10) / rate; fc = (freq << 10) / rate;
if (fc > 97391L) { if (fc > 97391L) {
fc = 97391; fc = 97391;
snd_printk("patch: (1) fc frequency overflow - %u\n", fc); snd_printk(KERN_ERR "patch: (1) fc frequency overflow - %u\n", fc);
} }
fc = (fc * 44100UL) / mix_rate; fc = (fc * 44100UL) / mix_rate;
while (scale--) while (scale--)
fc <<= 1; fc <<= 1;
if (fc > 65535L) { if (fc > 65535L) {
fc = 65535; fc = 65535;
snd_printk("patch: (2) fc frequency overflow - %u\n", fc); snd_printk(KERN_ERR "patch: (2) fc frequency overflow - %u\n", fc);
} }
return (unsigned short) fc; return (unsigned short) fc;
} }

View File

@ -437,7 +437,7 @@ static void __devinit snd_interwave_detect_memory(snd_gus_card_t * gus)
for (i = 0; i < 8; ++i) for (i = 0; i < 8; ++i)
iwave[i] = snd_gf1_peek(gus, bank_pos + i); iwave[i] = snd_gf1_peek(gus, bank_pos + i);
#ifdef CONFIG_SND_DEBUG_ROM #ifdef CONFIG_SND_DEBUG_ROM
printk("ROM at 0x%06x = %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x\n", bank_pos, printk(KERN_DEBUG "ROM at 0x%06x = %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x\n", bank_pos,
iwave[0], iwave[1], iwave[2], iwave[3], iwave[0], iwave[1], iwave[2], iwave[3],
iwave[4], iwave[5], iwave[6], iwave[7]); iwave[4], iwave[5], iwave[6], iwave[7]);
#endif #endif
@ -447,7 +447,7 @@ static void __devinit snd_interwave_detect_memory(snd_gus_card_t * gus)
for (i = 0; i < sizeof(struct rom_hdr); i++) for (i = 0; i < sizeof(struct rom_hdr); i++)
csum += snd_gf1_peek(gus, bank_pos + i); csum += snd_gf1_peek(gus, bank_pos + i);
#ifdef CONFIG_SND_DEBUG_ROM #ifdef CONFIG_SND_DEBUG_ROM
printk("ROM checksum = 0x%x (computed)\n", csum); printk(KERN_DEBUG "ROM checksum = 0x%x (computed)\n", csum);
#endif #endif
if (csum != 0) if (csum != 0)
continue; /* not valid rom */ continue; /* not valid rom */
@ -638,10 +638,7 @@ static void snd_interwave_free(snd_card_t *card)
if (iwcard == NULL) if (iwcard == NULL)
return; return;
#ifdef SNDRV_STB #ifdef SNDRV_STB
if (iwcard->i2c_res) { release_and_free_resource(iwcard->i2c_res);
release_resource(iwcard->i2c_res);
kfree_nocheck(iwcard->i2c_res);
}
#endif #endif
if (iwcard->irq >= 0) if (iwcard->irq >= 0)
free_irq(iwcard->irq, (void *)iwcard); free_irq(iwcard->irq, (void *)iwcard);

View File

@ -656,10 +656,7 @@ static int snd_opl3sa2_free(opl3sa2_t *chip)
{ {
if (chip->irq >= 0) if (chip->irq >= 0)
free_irq(chip->irq, (void *)chip); free_irq(chip->irq, (void *)chip);
if (chip->res_port) { release_and_free_resource(chip->res_port);
release_resource(chip->res_port);
kfree_nocheck(chip->res_port);
}
kfree(chip); kfree(chip);
return 0; return 0;
} }

View File

@ -299,10 +299,8 @@ static char * snd_opti9xx_names[] = {
static long snd_legacy_find_free_ioport(long *port_table, long size) static long snd_legacy_find_free_ioport(long *port_table, long size)
{ {
while (*port_table != -1) { while (*port_table != -1) {
struct resource *res; if (request_region(*port_table, size, "ALSA test")) {
if ((res = request_region(*port_table, size, "ALSA test")) != NULL) { release_region(*port_table, size);
release_resource(res);
kfree_nocheck(res);
return *port_table; return *port_table;
} }
port_table++; port_table++;
@ -1227,10 +1225,7 @@ static int snd_opti93x_probe(opti93x_t *chip)
static int snd_opti93x_free(opti93x_t *chip) static int snd_opti93x_free(opti93x_t *chip)
{ {
if (chip->res_port) { release_and_free_resource(chip->res_port);
release_resource(chip->res_port);
kfree_nocheck(chip->res_port);
}
if (chip->dma1 >= 0) { if (chip->dma1 >= 0) {
disable_dma(chip->dma1); disable_dma(chip->dma1);
free_dma(chip->dma1); free_dma(chip->dma1);
@ -1656,8 +1651,7 @@ static int __devinit snd_card_opti9xx_detect(snd_card_t *card, opti9xx_t *chip)
if (value == snd_opti9xx_read(chip, OPTi9XX_MC_REG(1))) if (value == snd_opti9xx_read(chip, OPTi9XX_MC_REG(1)))
return 1; return 1;
release_resource(chip->res_mc_base); release_and_free_resource(chip->res_mc_base);
kfree_nocheck(chip->res_mc_base);
chip->res_mc_base = NULL; chip->res_mc_base = NULL;
} }
@ -1683,8 +1677,7 @@ static int __devinit snd_card_opti9xx_detect(snd_card_t *card, opti9xx_t *chip)
if (snd_opti9xx_read(chip, OPTi9XX_MC_REG(7)) == 0xff - value) if (snd_opti9xx_read(chip, OPTi9XX_MC_REG(7)) == 0xff - value)
return 1; return 1;
release_resource(chip->res_mc_base); release_and_free_resource(chip->res_mc_base);
kfree_nocheck(chip->res_mc_base);
chip->res_mc_base = NULL; chip->res_mc_base = NULL;
} }
#endif /* OPTi93X */ #endif /* OPTi93X */
@ -1886,12 +1879,8 @@ static void snd_card_opti9xx_free(snd_card_t *card)
{ {
opti9xx_t *chip = (opti9xx_t *)card->private_data; opti9xx_t *chip = (opti9xx_t *)card->private_data;
if (chip) { if (chip)
if (chip->res_mc_base) { release_and_free_resource(chip->res_mc_base);
release_resource(chip->res_mc_base);
kfree_nocheck(chip->res_mc_base);
}
}
} }
static int snd_card_opti9xx_probe(struct pnp_card_link *pcard, static int snd_card_opti9xx_probe(struct pnp_card_link *pcard,

View File

@ -135,8 +135,7 @@ static void __init
snd_emu8000_read_wait(emu8000_t *emu) snd_emu8000_read_wait(emu8000_t *emu)
{ {
while ((EMU8000_SMALR_READ(emu) & 0x80000000) != 0) { while ((EMU8000_SMALR_READ(emu) & 0x80000000) != 0) {
set_current_state(TASK_INTERRUPTIBLE); schedule_timeout_interruptible(1);
schedule_timeout(1);
if (signal_pending(current)) if (signal_pending(current))
break; break;
} }
@ -148,8 +147,7 @@ static void __init
snd_emu8000_write_wait(emu8000_t *emu) snd_emu8000_write_wait(emu8000_t *emu)
{ {
while ((EMU8000_SMALW_READ(emu) & 0x80000000) != 0) { while ((EMU8000_SMALW_READ(emu) & 0x80000000) != 0) {
set_current_state(TASK_INTERRUPTIBLE); schedule_timeout_interruptible(1);
schedule_timeout(1);
if (signal_pending(current)) if (signal_pending(current))
break; break;
} }
@ -437,8 +435,7 @@ size_dram(emu8000_t *emu)
for (i = 0; i < 10000; i++) { for (i = 0; i < 10000; i++) {
if ((EMU8000_SMALW_READ(emu) & 0x80000000) == 0) if ((EMU8000_SMALW_READ(emu) & 0x80000000) == 0)
break; break;
set_current_state(TASK_INTERRUPTIBLE); schedule_timeout_interruptible(1);
schedule_timeout(1);
if (signal_pending(current)) if (signal_pending(current))
break; break;
} }
@ -1054,18 +1051,9 @@ __error:
*/ */
static int snd_emu8000_free(emu8000_t *hw) static int snd_emu8000_free(emu8000_t *hw)
{ {
if (hw->res_port1) { release_and_free_resource(hw->res_port1);
release_resource(hw->res_port1); release_and_free_resource(hw->res_port2);
kfree_nocheck(hw->res_port1); release_and_free_resource(hw->res_port3);
}
if (hw->res_port2) {
release_resource(hw->res_port2);
kfree_nocheck(hw->res_port2);
}
if (hw->res_port3) {
release_resource(hw->res_port3);
kfree_nocheck(hw->res_port3);
}
kfree(hw); kfree(hw);
return 0; return 0;
} }

View File

@ -109,8 +109,7 @@ static void
snd_emu8000_write_wait(emu8000_t *emu) snd_emu8000_write_wait(emu8000_t *emu)
{ {
while ((EMU8000_SMALW_READ(emu) & 0x80000000) != 0) { while ((EMU8000_SMALW_READ(emu) & 0x80000000) != 0) {
set_current_state(TASK_INTERRUPTIBLE); schedule_timeout_interruptible(1);
schedule_timeout(1);
if (signal_pending(current)) if (signal_pending(current))
break; break;
} }

View File

@ -117,8 +117,7 @@ snd_emu8000_write_wait(emu8000_t *emu, int can_schedule)
{ {
while ((EMU8000_SMALW_READ(emu) & 0x80000000) != 0) { while ((EMU8000_SMALW_READ(emu) & 0x80000000) != 0) {
if (can_schedule) { if (can_schedule) {
set_current_state(TASK_INTERRUPTIBLE); schedule_timeout_interruptible(1);
schedule_timeout(1);
if (signal_pending(current)) if (signal_pending(current))
break; break;
} }

View File

@ -56,7 +56,7 @@ static int snd_emu8000_new_device(snd_seq_device_t *dev)
emu->num_ports = hw->seq_ports; emu->num_ports = hw->seq_ports;
if (hw->memhdr) { if (hw->memhdr) {
snd_printk("memhdr is already initialized!?\n"); snd_printk(KERN_ERR "memhdr is already initialized!?\n");
snd_util_memhdr_free(hw->memhdr); snd_util_memhdr_free(hw->memhdr);
} }
hw->memhdr = snd_util_memhdr_new(hw->mem_size); hw->memhdr = snd_util_memhdr_new(hw->mem_size);

View File

@ -345,10 +345,7 @@ static void snd_sb16_free(snd_card_t *card)
if (acard == NULL) if (acard == NULL)
return; return;
if (acard->fm_res) { release_and_free_resource(acard->fm_res);
release_resource(acard->fm_res);
kfree_nocheck(acard->fm_res);
}
} }
#ifdef CONFIG_PNP #ifdef CONFIG_PNP

View File

@ -747,7 +747,7 @@ int snd_sb16dsp_configure(sb_t * chip)
unsigned char realirq, realdma, realmpureg; unsigned char realirq, realdma, realmpureg;
/* note: mpu register should be present only on SB16 Vibra soundcards */ /* note: mpu register should be present only on SB16 Vibra soundcards */
// printk("codec->irq=%i, codec->dma8=%i, codec->dma16=%i\n", chip->irq, chip->dma8, chip->dma16); // printk(KERN_DEBUG "codec->irq=%i, codec->dma8=%i, codec->dma16=%i\n", chip->irq, chip->dma8, chip->dma16);
spin_lock_irqsave(&chip->mixer_lock, flags); spin_lock_irqsave(&chip->mixer_lock, flags);
mpureg = snd_sbmixer_read(chip, SB_DSP4_MPUSETUP) & ~0x06; mpureg = snd_sbmixer_read(chip, SB_DSP4_MPUSETUP) & ~0x06;
spin_unlock_irqrestore(&chip->mixer_lock, flags); spin_unlock_irqrestore(&chip->mixer_lock, flags);
@ -821,9 +821,9 @@ int snd_sb16dsp_configure(sb_t * chip)
spin_unlock_irqrestore(&chip->mixer_lock, flags); spin_unlock_irqrestore(&chip->mixer_lock, flags);
if ((~realirq) & irqreg || (~realdma) & dmareg) { if ((~realirq) & irqreg || (~realdma) & dmareg) {
snd_printk("SB16 [0x%lx]: unable to set DMA & IRQ (PnP device?)\n", chip->port); snd_printk(KERN_ERR "SB16 [0x%lx]: unable to set DMA & IRQ (PnP device?)\n", chip->port);
snd_printk("SB16 [0x%lx]: wanted: irqreg=0x%x, dmareg=0x%x, mpureg = 0x%x\n", chip->port, realirq, realdma, realmpureg); snd_printk(KERN_ERR "SB16 [0x%lx]: wanted: irqreg=0x%x, dmareg=0x%x, mpureg = 0x%x\n", chip->port, realirq, realdma, realmpureg);
snd_printk("SB16 [0x%lx]: got: irqreg=0x%x, dmareg=0x%x, mpureg = 0x%x\n", chip->port, irqreg, dmareg, mpureg); snd_printk(KERN_ERR "SB16 [0x%lx]: got: irqreg=0x%x, dmareg=0x%x, mpureg = 0x%x\n", chip->port, irqreg, dmareg, mpureg);
return -ENODEV; return -ENODEV;
} }
return 0; return 0;

View File

@ -78,10 +78,7 @@ static void snd_sb8_free(snd_card_t *card)
if (acard == NULL) if (acard == NULL)
return; return;
if (acard->fm_res) { release_and_free_resource(acard->fm_res);
release_resource(acard->fm_res);
kfree_nocheck(acard->fm_res);
}
} }
static int __init snd_sb8_probe(int dev) static int __init snd_sb8_probe(int dev)

View File

@ -334,9 +334,6 @@ irqreturn_t snd_sb8dsp_interrupt(sb_t *chip)
snd_pcm_substream_t *substream; snd_pcm_substream_t *substream;
snd_pcm_runtime_t *runtime; snd_pcm_runtime_t *runtime;
#if 0
snd_printk("sb8: interrupt\n");
#endif
snd_sb_ack_8bit(chip); snd_sb_ack_8bit(chip);
switch (chip->mode) { switch (chip->mode) {
case SB_MODE_PLAYBACK_8: /* ok.. playback is active */ case SB_MODE_PLAYBACK_8: /* ok.. playback is active */

View File

@ -45,7 +45,7 @@ int snd_sbdsp_command(sb_t *chip, unsigned char val)
{ {
int i; int i;
#ifdef IO_DEBUG #ifdef IO_DEBUG
snd_printk("command 0x%x\n", val); snd_printk(KERN_DEBUG "command 0x%x\n", val);
#endif #endif
for (i = BUSY_LOOPS; i; i--) for (i = BUSY_LOOPS; i; i--)
if ((inb(SBP(chip, STATUS)) & 0x80) == 0) { if ((inb(SBP(chip, STATUS)) & 0x80) == 0) {
@ -64,7 +64,7 @@ int snd_sbdsp_get_byte(sb_t *chip)
if (inb(SBP(chip, DATA_AVAIL)) & 0x80) { if (inb(SBP(chip, DATA_AVAIL)) & 0x80) {
val = inb(SBP(chip, READ)); val = inb(SBP(chip, READ));
#ifdef IO_DEBUG #ifdef IO_DEBUG
snd_printk("get_byte 0x%x\n", val); snd_printk(KERN_DEBUG "get_byte 0x%x\n", val);
#endif #endif
return val; return val;
} }
@ -154,7 +154,7 @@ static int snd_sbdsp_probe(sb_t * chip)
str = "16"; str = "16";
break; break;
default: default:
snd_printk("SB [0x%lx]: unknown DSP chip version %i.%i\n", snd_printk(KERN_INFO "SB [0x%lx]: unknown DSP chip version %i.%i\n",
chip->port, major, minor); chip->port, major, minor);
return -ENODEV; return -ENODEV;
} }
@ -178,10 +178,8 @@ static int snd_sbdsp_probe(sb_t * chip)
static int snd_sbdsp_free(sb_t *chip) static int snd_sbdsp_free(sb_t *chip)
{ {
if (chip->res_port) { if (chip->res_port)
release_resource(chip->res_port); release_and_free_resource(chip->res_port);
kfree_nocheck(chip->res_port);
}
if (chip->irq >= 0) if (chip->irq >= 0)
free_irq(chip->irq, (void *) chip); free_irq(chip->irq, (void *) chip);
#ifdef CONFIG_ISA #ifdef CONFIG_ISA

View File

@ -36,7 +36,7 @@ void snd_sbmixer_write(sb_t *chip, unsigned char reg, unsigned char data)
outb(data, SBP(chip, MIXER_DATA)); outb(data, SBP(chip, MIXER_DATA));
udelay(10); udelay(10);
#ifdef IO_DEBUG #ifdef IO_DEBUG
snd_printk("mixer_write 0x%x 0x%x\n", reg, data); snd_printk(KERN_DEBUG "mixer_write 0x%x 0x%x\n", reg, data);
#endif #endif
} }
@ -49,7 +49,7 @@ unsigned char snd_sbmixer_read(sb_t *chip, unsigned char reg)
result = inb(SBP(chip, MIXER_DATA)); result = inb(SBP(chip, MIXER_DATA));
udelay(10); udelay(10);
#ifdef IO_DEBUG #ifdef IO_DEBUG
snd_printk("mixer_read 0x%x 0x%x\n", reg, result); snd_printk(KERN_DEBUG "mixer_read 0x%x 0x%x\n", reg, result);
#endif #endif
return result; return result;
} }

View File

@ -338,24 +338,10 @@ static inline void activate_ad1845_unsafe(unsigned io_base)
static void soundscape_free(snd_card_t * c) static void soundscape_free(snd_card_t * c)
{ {
register struct soundscape *sscape = get_card_soundscape(c); register struct soundscape *sscape = get_card_soundscape(c);
release_resource(sscape->io_res); release_and_free_resource(sscape->io_res);
kfree_nocheck(sscape->io_res);
free_dma(sscape->chip->dma1); free_dma(sscape->chip->dma1);
} }
/*
* Put this process into an idle wait-state for a certain number
* of "jiffies". The process can almost certainly be rescheduled
* while we're waiting, and so we must NOT be holding any spinlocks
* when we call this function. If we are then we risk DEADLOCK in
* SMP (Ha!) or pre-emptible kernels.
*/
static inline void sleep(long jiffs, int state)
{
set_current_state(state);
schedule_timeout(jiffs);
}
/* /*
* Tell the SoundScape to begin a DMA tranfer using the given channel. * Tell the SoundScape to begin a DMA tranfer using the given channel.
* All locking issues are left to the caller. * All locking issues are left to the caller.
@ -393,7 +379,7 @@ static int obp_startup_ack(struct soundscape *s, unsigned timeout)
unsigned long flags; unsigned long flags;
unsigned char x; unsigned char x;
sleep(1, TASK_INTERRUPTIBLE); schedule_timeout_interruptible(1);
spin_lock_irqsave(&s->lock, flags); spin_lock_irqsave(&s->lock, flags);
x = inb(HOST_DATA_IO(s->io_base)); x = inb(HOST_DATA_IO(s->io_base));
@ -420,7 +406,7 @@ static int host_startup_ack(struct soundscape *s, unsigned timeout)
unsigned long flags; unsigned long flags;
unsigned char x; unsigned char x;
sleep(1, TASK_INTERRUPTIBLE); schedule_timeout_interruptible(1);
spin_lock_irqsave(&s->lock, flags); spin_lock_irqsave(&s->lock, flags);
x = inb(HOST_DATA_IO(s->io_base)); x = inb(HOST_DATA_IO(s->io_base));
@ -1288,8 +1274,7 @@ static int __devinit create_sscape(const struct params *params, snd_card_t **rca
free_dma(params->dma1); free_dma(params->dma1);
_release_region: _release_region:
release_resource(io_res); release_and_free_resource(io_res);
kfree_nocheck(io_res);
return err; return err;
} }

View File

@ -379,10 +379,7 @@ snd_wavefront_free(snd_card_t *card)
snd_wavefront_card_t *acard = (snd_wavefront_card_t *)card->private_data; snd_wavefront_card_t *acard = (snd_wavefront_card_t *)card->private_data;
if (acard) { if (acard) {
if (acard->wavefront.res_base != NULL) { release_and_free_resource(acard->wavefront.res_base);
release_resource(acard->wavefront.res_base);
kfree_nocheck(acard->wavefront.res_base);
}
if (acard->wavefront.irq > 0) if (acard->wavefront.irq > 0)
free_irq(acard->wavefront.irq, (void *)acard); free_irq(acard->wavefront.irq, (void *)acard);
} }

View File

@ -275,8 +275,7 @@ static int
wavefront_sleep (int limit) wavefront_sleep (int limit)
{ {
set_current_state(TASK_INTERRUPTIBLE); schedule_timeout_interruptible(limit);
schedule_timeout(limit);
return signal_pending(current); return signal_pending(current);
} }
@ -1788,8 +1787,7 @@ wavefront_should_cause_interrupt (snd_wavefront_t *dev,
outb (val,port); outb (val,port);
spin_unlock_irq(&dev->irq_lock); spin_unlock_irq(&dev->irq_lock);
while (1) { while (1) {
set_current_state(TASK_INTERRUPTIBLE); if ((timeout = schedule_timeout_interruptible(timeout)) == 0)
if ((timeout = schedule_timeout(timeout)) == 0)
return; return;
if (dev->irq_ok) if (dev->irq_ok)
return; return;

View File

@ -57,8 +57,6 @@ MODULE_CLASSES("{sound}");
MODULE_DEVICES("{{AMD,Au1000 AC'97}}"); MODULE_DEVICES("{{AMD,Au1000 AC'97}}");
#endif #endif
#define chip_t au1000_t
#define PLAYBACK 0 #define PLAYBACK 0
#define CAPTURE 1 #define CAPTURE 1
#define AC97_SLOT_3 0x01 #define AC97_SLOT_3 0x01
@ -474,7 +472,7 @@ snd_au1000_ac97_read(ac97_t *ac97, unsigned short reg)
u32 volatile cmd; u32 volatile cmd;
u16 volatile data; u16 volatile data;
int i; int i;
spin_lock(au1000->ac97_lock); spin_lock(&au1000->ac97_lock);
/* would rather use the interupt than this polling but it works and I can't /* would rather use the interupt than this polling but it works and I can't
get the interupt driven case to work efficiently */ get the interupt driven case to work efficiently */
for (i = 0; i < 0x5000; i++) for (i = 0; i < 0x5000; i++)
@ -497,7 +495,7 @@ get the interupt driven case to work efficiently */
} }
data = au1000->ac97_ioport->cmd & 0xffff; data = au1000->ac97_ioport->cmd & 0xffff;
spin_unlock(au1000->ac97_lock); spin_unlock(&au1000->ac97_lock);
return data; return data;
@ -509,7 +507,7 @@ snd_au1000_ac97_write(ac97_t *ac97, unsigned short reg, unsigned short val)
{ {
u32 cmd; u32 cmd;
int i; int i;
spin_lock(au1000->ac97_lock); spin_lock(&au1000->ac97_lock);
/* would rather use the interupt than this polling but it works and I can't /* would rather use the interupt than this polling but it works and I can't
get the interupt driven case to work efficiently */ get the interupt driven case to work efficiently */
for (i = 0; i < 0x5000; i++) for (i = 0; i < 0x5000; i++)
@ -522,7 +520,7 @@ get the interupt driven case to work efficiently */
cmd &= ~AC97C_READ; cmd &= ~AC97C_READ;
cmd |= ((u32) val << AC97C_WD_BIT); cmd |= ((u32) val << AC97C_WD_BIT);
au1000->ac97_ioport->cmd = cmd; au1000->ac97_ioport->cmd = cmd;
spin_unlock(au1000->ac97_lock); spin_unlock(&au1000->ac97_lock);
} }
static void static void
snd_au1000_ac97_free(ac97_t *ac97) snd_au1000_ac97_free(ac97_t *ac97)
@ -606,8 +604,7 @@ snd_au1000_free(snd_card_t *card)
/* put internal AC97 block into reset */ /* put internal AC97 block into reset */
au1000->ac97_ioport->cntrl = AC97C_RS; au1000->ac97_ioport->cntrl = AC97C_RS;
au1000->ac97_ioport = NULL; au1000->ac97_ioport = NULL;
release_resource(au1000->ac97_res_port); release_and_free_resource(au1000->ac97_res_port);
kfree_nocheck(au1000->ac97_res_port);
} }
if (au1000->stream[PLAYBACK]->dma >= 0) if (au1000->stream[PLAYBACK]->dma >= 0)

View File

@ -1,13 +1,5 @@
# ALSA PCI drivers # ALSA PCI drivers
config SND_AC97_CODEC
tristate
select SND_PCM
select SND_AC97_BUS
config SND_AC97_BUS
tristate
menu "PCI devices" menu "PCI devices"
depends on SND!=n && PCI depends on SND!=n && PCI
@ -192,6 +184,7 @@ config SND_CA0106
tristate "SB Audigy LS / Live 24bit" tristate "SB Audigy LS / Live 24bit"
depends on SND depends on SND
select SND_AC97_CODEC select SND_AC97_CODEC
select SND_RAWMIDI
help help
Say Y here to include support for the Sound Blaster Audigy LS Say Y here to include support for the Sound Blaster Audigy LS
and Live 24bit. and Live 24bit.

View File

@ -220,12 +220,6 @@ const char *snd_ac97_stereo_enhancements[] =
/* 31 */ "Reserved 31" /* 31 */ "Reserved 31"
}; };
/*
* Shared AC97 controllers (ICH, ATIIXP...)
*/
static DECLARE_MUTEX(shared_codec_mutex);
static ac97_t *shared_codec[AC97_SHARED_TYPES][4];
/* /*
* I/O routines * I/O routines
@ -996,14 +990,8 @@ static int snd_ac97_free(ac97_t *ac97)
{ {
if (ac97) { if (ac97) {
snd_ac97_proc_done(ac97); snd_ac97_proc_done(ac97);
if (ac97->bus) { if (ac97->bus)
ac97->bus->codec[ac97->num] = NULL; ac97->bus->codec[ac97->num] = NULL;
if (ac97->bus->shared_type) {
down(&shared_codec_mutex);
shared_codec[ac97->bus->shared_type-1][ac97->num] = NULL;
up(&shared_codec_mutex);
}
}
if (ac97->private_free) if (ac97->private_free)
ac97->private_free(ac97); ac97->private_free(ac97);
kfree(ac97); kfree(ac97);
@ -1139,7 +1127,6 @@ snd_kcontrol_t *snd_ac97_cnew(const snd_kcontrol_new_t *_template, ac97_t * ac97
{ {
snd_kcontrol_new_t template; snd_kcontrol_new_t template;
memcpy(&template, _template, sizeof(template)); memcpy(&template, _template, sizeof(template));
snd_runtime_check(!template.index, return NULL);
template.index = ac97->num; template.index = ac97->num;
return snd_ctl_new1(&template, ac97); return snd_ctl_new1(&template, ac97);
} }
@ -1758,8 +1745,7 @@ static int ac97_reset_wait(ac97_t *ac97, int timeout, int with_modem)
if ((snd_ac97_read(ac97, AC97_REC_GAIN) & 0x7fff) == 0x0a05) if ((snd_ac97_read(ac97, AC97_REC_GAIN) & 0x7fff) == 0x0a05)
return 0; return 0;
} }
set_current_state(TASK_UNINTERRUPTIBLE); schedule_timeout_uninterruptible(1);
schedule_timeout(1);
} while (time_after_eq(end_time, jiffies)); } while (time_after_eq(end_time, jiffies));
return -ENODEV; return -ENODEV;
} }
@ -1889,21 +1875,6 @@ int snd_ac97_mixer(ac97_bus_t *bus, ac97_template_t *template, ac97_t **rac97)
snd_assert(bus != NULL && template != NULL, return -EINVAL); snd_assert(bus != NULL && template != NULL, return -EINVAL);
snd_assert(template->num < 4 && bus->codec[template->num] == NULL, return -EINVAL); snd_assert(template->num < 4 && bus->codec[template->num] == NULL, return -EINVAL);
snd_assert(bus->shared_type <= AC97_SHARED_TYPES, return -EINVAL);
if (bus->shared_type) {
/* already shared? */
down(&shared_codec_mutex);
ac97 = shared_codec[bus->shared_type-1][template->num];
if (ac97) {
if ((ac97_is_audio(ac97) && (template->scaps & AC97_SCAP_SKIP_AUDIO)) ||
(ac97_is_modem(ac97) && (template->scaps & AC97_SCAP_SKIP_MODEM))) {
up(&shared_codec_mutex);
return -EACCES; /* skip this */
}
}
up(&shared_codec_mutex);
}
card = bus->card; card = bus->card;
ac97 = kzalloc(sizeof(*ac97), GFP_KERNEL); ac97 = kzalloc(sizeof(*ac97), GFP_KERNEL);
if (ac97 == NULL) if (ac97 == NULL)
@ -2020,8 +1991,7 @@ int snd_ac97_mixer(ac97_bus_t *bus, ac97_template_t *template, ac97_t **rac97)
do { do {
if ((snd_ac97_read(ac97, AC97_POWERDOWN) & 0x0f) == 0x0f) if ((snd_ac97_read(ac97, AC97_POWERDOWN) & 0x0f) == 0x0f)
goto __ready_ok; goto __ready_ok;
set_current_state(TASK_UNINTERRUPTIBLE); schedule_timeout_uninterruptible(1);
schedule_timeout(1);
} while (time_after_eq(end_time, jiffies)); } while (time_after_eq(end_time, jiffies));
snd_printk(KERN_WARNING "AC'97 %d analog subsections not ready\n", ac97->num); snd_printk(KERN_WARNING "AC'97 %d analog subsections not ready\n", ac97->num);
} }
@ -2053,8 +2023,7 @@ int snd_ac97_mixer(ac97_bus_t *bus, ac97_template_t *template, ac97_t **rac97)
do { do {
if ((snd_ac97_read(ac97, AC97_EXTENDED_MSTATUS) & tmp) == tmp) if ((snd_ac97_read(ac97, AC97_EXTENDED_MSTATUS) & tmp) == tmp)
goto __ready_ok; goto __ready_ok;
set_current_state(TASK_UNINTERRUPTIBLE); schedule_timeout_uninterruptible(1);
schedule_timeout(1);
} while (time_after_eq(end_time, jiffies)); } while (time_after_eq(end_time, jiffies));
snd_printk(KERN_WARNING "MC'97 %d converters and GPIO not ready (0x%x)\n", ac97->num, snd_ac97_read(ac97, AC97_EXTENDED_MSTATUS)); snd_printk(KERN_WARNING "MC'97 %d converters and GPIO not ready (0x%x)\n", ac97->num, snd_ac97_read(ac97, AC97_EXTENDED_MSTATUS));
} }
@ -2077,6 +2046,8 @@ int snd_ac97_mixer(ac97_bus_t *bus, ac97_template_t *template, ac97_t **rac97)
snd_ac97_update_bits(ac97, AC97_GENERAL_PURPOSE, AC97_GP_DRSS_MASK, AC97_GP_DRSS_78); snd_ac97_update_bits(ac97, AC97_GENERAL_PURPOSE, AC97_GP_DRSS_MASK, AC97_GP_DRSS_78);
if ((snd_ac97_read(ac97, AC97_GENERAL_PURPOSE) & AC97_GP_DRSS_MASK) == AC97_GP_DRSS_78) if ((snd_ac97_read(ac97, AC97_GENERAL_PURPOSE) & AC97_GP_DRSS_MASK) == AC97_GP_DRSS_78)
ac97->flags |= AC97_DOUBLE_RATE; ac97->flags |= AC97_DOUBLE_RATE;
/* restore to slots 10/11 to avoid the confliction with surrounds */
snd_ac97_update_bits(ac97, AC97_GENERAL_PURPOSE, AC97_GP_DRSS_MASK, 0);
} }
if (ac97->ext_id & AC97_EI_VRA) { /* VRA support */ if (ac97->ext_id & AC97_EI_VRA) { /* VRA support */
snd_ac97_determine_rates(ac97, AC97_PCM_FRONT_DAC_RATE, 0, &ac97->rates[AC97_RATES_FRONT_DAC]); snd_ac97_determine_rates(ac97, AC97_PCM_FRONT_DAC_RATE, 0, &ac97->rates[AC97_RATES_FRONT_DAC]);
@ -2153,7 +2124,7 @@ int snd_ac97_mixer(ac97_bus_t *bus, ac97_template_t *template, ac97_t **rac97)
} }
} }
/* make sure the proper powerdown bits are cleared */ /* make sure the proper powerdown bits are cleared */
if (ac97->scaps) { if (ac97->scaps && ac97_is_audio(ac97)) {
reg = snd_ac97_read(ac97, AC97_EXTENDED_STATUS); reg = snd_ac97_read(ac97, AC97_EXTENDED_STATUS);
if (ac97->scaps & AC97_SCAP_SURROUND_DAC) if (ac97->scaps & AC97_SCAP_SURROUND_DAC)
reg &= ~AC97_EA_PRJ; reg &= ~AC97_EA_PRJ;
@ -2167,13 +2138,6 @@ int snd_ac97_mixer(ac97_bus_t *bus, ac97_template_t *template, ac97_t **rac97)
return err; return err;
} }
*rac97 = ac97; *rac97 = ac97;
if (bus->shared_type) {
down(&shared_codec_mutex);
shared_codec[bus->shared_type-1][ac97->num] = ac97;
up(&shared_codec_mutex);
}
return 0; return 0;
} }
@ -2295,8 +2259,7 @@ void snd_ac97_resume(ac97_t *ac97)
do { do {
if (snd_ac97_read(ac97, AC97_MASTER) == 0x8101) if (snd_ac97_read(ac97, AC97_MASTER) == 0x8101)
break; break;
set_current_state(TASK_UNINTERRUPTIBLE); schedule_timeout_uninterruptible(1);
schedule_timeout(1);
} while (time_after_eq(end_time, jiffies)); } while (time_after_eq(end_time, jiffies));
/* FIXME: extra delay */ /* FIXME: extra delay */
ac97->bus->ops->write(ac97, AC97_MASTER, 0x8000); ac97->bus->ops->write(ac97, AC97_MASTER, 0x8000);
@ -2308,8 +2271,7 @@ void snd_ac97_resume(ac97_t *ac97)
unsigned short val = snd_ac97_read(ac97, AC97_EXTENDED_MID); unsigned short val = snd_ac97_read(ac97, AC97_EXTENDED_MID);
if (val != 0xffff && (val & 1) != 0) if (val != 0xffff && (val & 1) != 0)
break; break;
set_current_state(TASK_UNINTERRUPTIBLE); schedule_timeout_uninterruptible(1);
schedule_timeout(1);
} while (time_after_eq(end_time, jiffies)); } while (time_after_eq(end_time, jiffies));
} }
__reset_ready: __reset_ready:

View File

@ -163,14 +163,24 @@ static int ac97_channel_mode_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t
.private_value = 1, \ .private_value = 1, \
} }
static inline int is_surround_on(ac97_t *ac97)
{
return ac97->channel_mode >= 1;
}
static inline int is_clfe_on(ac97_t *ac97)
{
return ac97->channel_mode >= 2;
}
static inline int is_shared_linein(ac97_t *ac97) static inline int is_shared_linein(ac97_t *ac97)
{ {
return ! ac97->indep_surround && ac97->channel_mode >= 1; return ! ac97->indep_surround && is_surround_on(ac97);
} }
static inline int is_shared_micin(ac97_t *ac97) static inline int is_shared_micin(ac97_t *ac97)
{ {
return ! ac97->indep_surround && ac97->channel_mode >= 2; return ! ac97->indep_surround && is_clfe_on(ac97);
} }
@ -1450,7 +1460,8 @@ int patch_ad1881(ac97_t * ac97)
codecs[1] = patch_ad1881_unchained(ac97, 1, (1<<14)); codecs[1] = patch_ad1881_unchained(ac97, 1, (1<<14));
codecs[2] = patch_ad1881_unchained(ac97, 2, (1<<13)); codecs[2] = patch_ad1881_unchained(ac97, 2, (1<<13));
snd_runtime_check(codecs[0] | codecs[1] | codecs[2], goto __end); if (! (codecs[0] || codecs[1] || codecs[2]))
goto __end;
for (idx = 0; idx < 3; idx++) for (idx = 0; idx < 3; idx++)
if (ac97->spec.ad18xx.unchained[idx]) if (ac97->spec.ad18xx.unchained[idx])
@ -1753,12 +1764,13 @@ static int snd_ac97_ad1888_downmix_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_va
static void ad1888_update_jacks(ac97_t *ac97) static void ad1888_update_jacks(ac97_t *ac97)
{ {
unsigned short val = 0;
if (! is_shared_linein(ac97))
val |= (1 << 12);
if (! is_shared_micin(ac97))
val |= (1 << 11);
/* shared Line-In */ /* shared Line-In */
snd_ac97_update_bits(ac97, AC97_AD_MISC, 1 << 12, snd_ac97_update_bits(ac97, AC97_AD_MISC, (1 << 11) | (1 << 12), val);
is_shared_linein(ac97) ? 0 : 1 << 12);
/* shared Mic */
snd_ac97_update_bits(ac97, AC97_AD_MISC, 1 << 11,
is_shared_micin(ac97) ? 0 : 1 << 11);
} }
static const snd_kcontrol_new_t snd_ac97_ad1888_controls[] = { static const snd_kcontrol_new_t snd_ac97_ad1888_controls[] = {
@ -1852,12 +1864,7 @@ static const snd_kcontrol_new_t snd_ac97_ad1985_controls[] = {
static void ad1985_update_jacks(ac97_t *ac97) static void ad1985_update_jacks(ac97_t *ac97)
{ {
/* shared Line-In */ ad1888_update_jacks(ac97);
snd_ac97_update_bits(ac97, AC97_AD_MISC, 1 << 12,
is_shared_linein(ac97) ? 0 : 1 << 12);
/* shared Mic */
snd_ac97_update_bits(ac97, AC97_AD_MISC, 1 << 11,
is_shared_micin(ac97) ? 0 : 1 << 11);
snd_ac97_update_bits(ac97, AC97_AD_SERIAL_CFG, 1 << 9, snd_ac97_update_bits(ac97, AC97_AD_SERIAL_CFG, 1 << 9,
is_shared_micin(ac97) ? 0 : 1 << 9); is_shared_micin(ac97) ? 0 : 1 << 9);
} }
@ -2442,21 +2449,37 @@ int patch_cm9739(ac97_t * ac97)
static void cm9761_update_jacks(ac97_t *ac97) static void cm9761_update_jacks(ac97_t *ac97)
{ {
unsigned short surr_vals[2][2] = { /* FIXME: check the bits for each model
{ 0x0008, 0x0400 }, /* off, on */ * model 83 is confirmed to work
{ 0x0000, 0x0408 }, /* off, on (9761-82 rev.B) */ */
static unsigned short surr_on[3][2] = {
{ 0x0008, 0x0000 }, /* 9761-78 & 82 */
{ 0x0000, 0x0008 }, /* 9761-82 rev.B */
{ 0x0000, 0x0008 }, /* 9761-83 */
}; };
unsigned short clfe_vals[2][2] = { static unsigned short clfe_on[3][2] = {
{ 0x2000, 0x1880 }, /* off, on */ { 0x0000, 0x1000 }, /* 9761-78 & 82 */
{ 0x1000, 0x2880 }, /* off, on (9761-82 rev.B) */ { 0x1000, 0x0000 }, /* 9761-82 rev.B */
{ 0x0000, 0x1000 }, /* 9761-83 */
}; };
static unsigned short surr_shared[3][2] = {
{ 0x0000, 0x0400 }, /* 9761-78 & 82 */
{ 0x0000, 0x0400 }, /* 9761-82 rev.B */
{ 0x0000, 0x0400 }, /* 9761-83 */
};
static unsigned short clfe_shared[3][2] = {
{ 0x2000, 0x0880 }, /* 9761-78 & 82 */
{ 0x0000, 0x2880 }, /* 9761-82 rev.B */
{ 0x2000, 0x0800 }, /* 9761-83 */
};
unsigned short val = 0;
/* shared Line-In */ val |= surr_on[ac97->spec.dev_flags][is_surround_on(ac97)];
snd_ac97_update_bits(ac97, AC97_CM9761_MULTI_CHAN, 0x0408, val |= clfe_on[ac97->spec.dev_flags][is_clfe_on(ac97)];
surr_vals[ac97->spec.dev_flags][is_shared_linein(ac97)]); val |= surr_shared[ac97->spec.dev_flags][is_shared_linein(ac97)];
/* shared Mic */ val |= clfe_shared[ac97->spec.dev_flags][is_shared_micin(ac97)];
snd_ac97_update_bits(ac97, AC97_CM9761_MULTI_CHAN, 0x3880,
clfe_vals[ac97->spec.dev_flags][is_shared_micin(ac97)]); snd_ac97_update_bits(ac97, AC97_CM9761_MULTI_CHAN, 0x3c88, val);
} }
static const snd_kcontrol_new_t snd_ac97_cm9761_controls[] = { static const snd_kcontrol_new_t snd_ac97_cm9761_controls[] = {
@ -2551,7 +2574,7 @@ int patch_cm9761(ac97_t *ac97)
snd_ac97_write_cache(ac97, AC97_MASTER, 0x8808); snd_ac97_write_cache(ac97, AC97_MASTER, 0x8808);
snd_ac97_write_cache(ac97, AC97_PCM, 0x8808); snd_ac97_write_cache(ac97, AC97_PCM, 0x8808);
ac97->spec.dev_flags = 0; /* 1 = model 82 revision B */ ac97->spec.dev_flags = 0; /* 1 = model 82 revision B, 2 = model 83 */
if (ac97->id == AC97_ID_CM9761_82) { if (ac97->id == AC97_ID_CM9761_82) {
unsigned short tmp; unsigned short tmp;
/* check page 1, reg 0x60 */ /* check page 1, reg 0x60 */
@ -2560,7 +2583,8 @@ int patch_cm9761(ac97_t *ac97)
tmp = snd_ac97_read(ac97, 0x60); tmp = snd_ac97_read(ac97, 0x60);
ac97->spec.dev_flags = tmp & 1; /* revision B? */ ac97->spec.dev_flags = tmp & 1; /* revision B? */
snd_ac97_write_cache(ac97, AC97_INT_PAGING, val); snd_ac97_write_cache(ac97, AC97_INT_PAGING, val);
} } else if (ac97->id == AC97_ID_CM9761_83)
ac97->spec.dev_flags = 2;
ac97->build_ops = &patch_cm9761_ops; ac97->build_ops = &patch_cm9761_ops;

View File

@ -303,6 +303,15 @@ int snd_ac97_set_rate(ac97_t *ac97, int reg, unsigned int rate)
AC97_EA_DRA, dbl ? AC97_EA_DRA : 0); AC97_EA_DRA, dbl ? AC97_EA_DRA : 0);
snd_ac97_update(ac97, reg, tmp & 0xffff); snd_ac97_update(ac97, reg, tmp & 0xffff);
snd_ac97_read(ac97, reg); snd_ac97_read(ac97, reg);
if ((ac97->ext_id & AC97_EI_DRA) && reg == AC97_PCM_FRONT_DAC_RATE) {
/* Intel controllers require double rate data to be put in
* slots 7+8
*/
snd_ac97_update_bits(ac97, AC97_GENERAL_PURPOSE,
AC97_GP_DRSS_MASK,
dbl ? AC97_GP_DRSS_78 : 0);
snd_ac97_read(ac97, AC97_GENERAL_PURPOSE);
}
return 0; return 0;
} }

View File

@ -50,7 +50,7 @@
#include "ad1889.h" #include "ad1889.h"
#include "ac97/ac97_id.h" #include "ac97/ac97_id.h"
#define AD1889_DRVVER "$Revision: 1.3 $" #define AD1889_DRVVER "$Revision: 1.4 $"
MODULE_AUTHOR("Kyle McMartin <kyle@parisc-linux.org>, Thibaut Varene <t-bone@parisc-linux.org>"); MODULE_AUTHOR("Kyle McMartin <kyle@parisc-linux.org>, Thibaut Varene <t-bone@parisc-linux.org>");
MODULE_DESCRIPTION("Analog Devices AD1889 ALSA sound driver"); MODULE_DESCRIPTION("Analog Devices AD1889 ALSA sound driver");
@ -982,8 +982,7 @@ snd_ad1889_create(snd_card_t *card,
return 0; return 0;
free_and_ret: free_and_ret:
if (chip) kfree(chip);
kfree(chip);
pci_disable_device(pci); pci_disable_device(pci);
return err; return err;

View File

@ -45,23 +45,25 @@ MODULE_DESCRIPTION("ALI M5451");
MODULE_LICENSE("GPL"); MODULE_LICENSE("GPL");
MODULE_SUPPORTED_DEVICE("{{ALI,M5451,pci},{ALI,M5451}}"); MODULE_SUPPORTED_DEVICE("{{ALI,M5451,pci},{ALI,M5451}}");
static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */ static int index = SNDRV_DEFAULT_IDX1; /* Index */
static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */ static char *id = SNDRV_DEFAULT_STR1; /* ID for this card */
static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP; static int pcm_channels = 32;
static int pcm_channels[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 32}; static int spdif = 0;
static int spdif[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 0};
module_param_array(index, int, NULL, 0444); module_param(index, int, 0444);
MODULE_PARM_DESC(index, "Index value for ALI M5451 PCI Audio."); MODULE_PARM_DESC(index, "Index value for ALI M5451 PCI Audio.");
module_param_array(id, charp, NULL, 0444); module_param(id, charp, 0444);
MODULE_PARM_DESC(id, "ID string for ALI M5451 PCI Audio."); MODULE_PARM_DESC(id, "ID string for ALI M5451 PCI Audio.");
module_param_array(enable, bool, NULL, 0444); module_param(pcm_channels, int, 0444);
MODULE_PARM_DESC(enable, "Enable ALI 5451 PCI Audio.");
module_param_array(pcm_channels, int, NULL, 0444);
MODULE_PARM_DESC(pcm_channels, "PCM Channels"); MODULE_PARM_DESC(pcm_channels, "PCM Channels");
module_param_array(spdif, bool, NULL, 0444); module_param(spdif, bool, 0444);
MODULE_PARM_DESC(spdif, "Support SPDIF I/O"); MODULE_PARM_DESC(spdif, "Support SPDIF I/O");
/* just for backward compatibility */
static int enable;
module_param(enable, bool, 0444);
/* /*
* Debug part definitions * Debug part definitions
*/ */
@ -396,10 +398,8 @@ static int snd_ali_codec_ready( ali_t *codec,
res = snd_ali_5451_peek(codec,port); res = snd_ali_5451_peek(codec,port);
if (! (res & 0x8000)) if (! (res & 0x8000))
return 0; return 0;
if (sched) { if (sched)
set_current_state(TASK_UNINTERRUPTIBLE); schedule_timeout_uninterruptible(1);
schedule_timeout(1);
}
} while (time_after_eq(end_time, jiffies)); } while (time_after_eq(end_time, jiffies));
snd_ali_5451_poke(codec, port, res & ~0x8000); snd_ali_5451_poke(codec, port, res & ~0x8000);
snd_printdd("ali_codec_ready: codec is not ready.\n "); snd_printdd("ali_codec_ready: codec is not ready.\n ");
@ -419,12 +419,10 @@ static int snd_ali_stimer_ready(ali_t *codec, int sched)
dwChk2 = snd_ali_5451_peek(codec, ALI_STIMER); dwChk2 = snd_ali_5451_peek(codec, ALI_STIMER);
if (dwChk2 != dwChk1) if (dwChk2 != dwChk1)
return 0; return 0;
if (sched) { if (sched)
set_current_state(TASK_UNINTERRUPTIBLE); schedule_timeout_uninterruptible(1);
schedule_timeout(1);
}
} while (time_after_eq(end_time, jiffies)); } while (time_after_eq(end_time, jiffies));
snd_printk("ali_stimer_read: stimer is not ready.\n"); snd_printk(KERN_ERR "ali_stimer_read: stimer is not ready.\n");
return -EIO; return -EIO;
} }
@ -436,7 +434,7 @@ static void snd_ali_codec_poke(ali_t *codec,int secondary,
unsigned int port = 0; unsigned int port = 0;
if (reg >= 0x80) { if (reg >= 0x80) {
snd_printk("ali_codec_poke: reg(%xh) invalid.\n", reg); snd_printk(KERN_ERR "ali_codec_poke: reg(%xh) invalid.\n", reg);
return; return;
} }
@ -465,7 +463,7 @@ static unsigned short snd_ali_codec_peek( ali_t *codec,
unsigned int port = 0; unsigned int port = 0;
if (reg >= 0x80) { if (reg >= 0x80) {
snd_printk("ali_codec_peek: reg(%xh) invalid.\n", reg); snd_printk(KERN_ERR "ali_codec_peek: reg(%xh) invalid.\n", reg);
return ~0; return ~0;
} }
@ -669,7 +667,7 @@ static int snd_ali_alloc_pcm_channel(ali_t *codec, int channel)
unsigned int idx = channel & 0x1f; unsigned int idx = channel & 0x1f;
if (codec->synth.chcnt >= ALI_CHANNELS){ if (codec->synth.chcnt >= ALI_CHANNELS){
snd_printk("ali_alloc_pcm_channel: no free channels.\n"); snd_printk(KERN_ERR "ali_alloc_pcm_channel: no free channels.\n");
return -1; return -1;
} }
@ -700,7 +698,7 @@ static int snd_ali_find_free_channel(ali_t * codec, int rec)
if ((result = snd_ali_alloc_pcm_channel(codec,idx)) >= 0) { if ((result = snd_ali_alloc_pcm_channel(codec,idx)) >= 0) {
return result; return result;
} else { } else {
snd_printk("ali_find_free_channel: record channel is busy now.\n"); snd_printk(KERN_ERR "ali_find_free_channel: record channel is busy now.\n");
return -1; return -1;
} }
} }
@ -712,7 +710,7 @@ static int snd_ali_find_free_channel(ali_t * codec, int rec)
if ((result = snd_ali_alloc_pcm_channel(codec,idx)) >= 0) { if ((result = snd_ali_alloc_pcm_channel(codec,idx)) >= 0) {
return result; return result;
} else { } else {
snd_printk("ali_find_free_channel: S/PDIF out channel is in busy now.\n"); snd_printk(KERN_ERR "ali_find_free_channel: S/PDIF out channel is in busy now.\n");
} }
} }
@ -720,7 +718,7 @@ static int snd_ali_find_free_channel(ali_t * codec, int rec)
if ((result = snd_ali_alloc_pcm_channel(codec,idx)) >= 0) if ((result = snd_ali_alloc_pcm_channel(codec,idx)) >= 0)
return result; return result;
} }
snd_printk("ali_find_free_channel: no free channels.\n"); snd_printk(KERN_ERR "ali_find_free_channel: no free channels.\n");
return -1; return -1;
} }
@ -734,7 +732,7 @@ static void snd_ali_free_channel_pcm(ali_t *codec, int channel)
return; return;
if (!(codec->synth.chmap & (1 << idx))) { if (!(codec->synth.chmap & (1 << idx))) {
snd_printk("ali_free_channel_pcm: channel %d is not in use.\n",channel); snd_printk(KERN_ERR "ali_free_channel_pcm: channel %d is not in use.\n",channel);
return; return;
} else { } else {
codec->synth.chmap &= ~(1 << idx); codec->synth.chmap &= ~(1 << idx);
@ -796,7 +794,7 @@ static void snd_ali_detect_spdif_rate(ali_t *codec)
} }
if (count > 50000) { if (count > 50000) {
snd_printk("ali_detect_spdif_rate: timeout!\n"); snd_printk(KERN_ERR "ali_detect_spdif_rate: timeout!\n");
return; return;
} }
@ -809,7 +807,7 @@ static void snd_ali_detect_spdif_rate(ali_t *codec)
} }
if (count > 50000) { if (count > 50000) {
snd_printk("ali_detect_spdif_rate: timeout!\n"); snd_printk(KERN_ERR "ali_detect_spdif_rate: timeout!\n");
return; return;
} }
@ -1077,7 +1075,7 @@ static snd_ali_voice_t *snd_ali_alloc_voice(ali_t * codec, int type, int rec, in
idx = channel > 0 ? snd_ali_alloc_pcm_channel(codec, channel) : idx = channel > 0 ? snd_ali_alloc_pcm_channel(codec, channel) :
snd_ali_find_free_channel(codec,rec); snd_ali_find_free_channel(codec,rec);
if(idx < 0) { if(idx < 0) {
snd_printk("ali_alloc_voice: err.\n"); snd_printk(KERN_ERR "ali_alloc_voice: err.\n");
spin_unlock_irqrestore(&codec->voice_alloc, flags); spin_unlock_irqrestore(&codec->voice_alloc, flags);
return NULL; return NULL;
} }
@ -1479,13 +1477,13 @@ static int snd_ali_prepare(snd_pcm_substream_t * substream)
} }
rate = snd_ali_get_spdif_in_rate(codec); rate = snd_ali_get_spdif_in_rate(codec);
if (rate == 0) { if (rate == 0) {
snd_printk("ali_capture_preapre: spdif rate detect err!\n"); snd_printk(KERN_WARNING "ali_capture_preapre: spdif rate detect err!\n");
rate = 48000; rate = 48000;
} }
bValue = inb(ALI_REG(codec,ALI_SPDIF_CTRL)); bValue = inb(ALI_REG(codec,ALI_SPDIF_CTRL));
if (bValue & 0x10) { if (bValue & 0x10) {
outb(bValue,ALI_REG(codec,ALI_SPDIF_CTRL)); outb(bValue,ALI_REG(codec,ALI_SPDIF_CTRL));
printk("clear SPDIF parity error flag.\n"); printk(KERN_WARNING "clear SPDIF parity error flag.\n");
} }
if (rate != 48000) if (rate != 48000)
@ -1795,6 +1793,7 @@ struct ali_pcm_description {
unsigned int capture_num; unsigned int capture_num;
snd_pcm_ops_t *playback_ops; snd_pcm_ops_t *playback_ops;
snd_pcm_ops_t *capture_ops; snd_pcm_ops_t *capture_ops;
unsigned short class;
}; };
@ -1813,12 +1812,11 @@ static int __devinit snd_ali_pcm(ali_t * codec, int device, struct ali_pcm_descr
err = snd_pcm_new(codec->card, desc->name, device, err = snd_pcm_new(codec->card, desc->name, device,
desc->playback_num, desc->capture_num, &pcm); desc->playback_num, desc->capture_num, &pcm);
if (err < 0) { if (err < 0) {
snd_printk("snd_ali_pcm: err called snd_pcm_new.\n"); snd_printk(KERN_ERR "snd_ali_pcm: err called snd_pcm_new.\n");
return err; return err;
} }
pcm->private_data = codec; pcm->private_data = codec;
pcm->private_free = snd_ali_pcm_free; pcm->private_free = snd_ali_pcm_free;
pcm->info_flags = 0;
if (desc->playback_ops) if (desc->playback_ops)
snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, desc->playback_ops); snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, desc->playback_ops);
if (desc->capture_ops) if (desc->capture_ops)
@ -1828,6 +1826,7 @@ static int __devinit snd_ali_pcm(ali_t * codec, int device, struct ali_pcm_descr
snd_dma_pci_data(codec->pci), 64*1024, 128*1024); snd_dma_pci_data(codec->pci), 64*1024, 128*1024);
pcm->info_flags = 0; pcm->info_flags = 0;
pcm->dev_class = desc->class;
pcm->dev_subclass = SNDRV_PCM_SUBCLASS_GENERIC_MIX; pcm->dev_subclass = SNDRV_PCM_SUBCLASS_GENERIC_MIX;
strcpy(pcm->name, desc->name); strcpy(pcm->name, desc->name);
codec->pcm[0] = pcm; codec->pcm[0] = pcm;
@ -1836,7 +1835,7 @@ static int __devinit snd_ali_pcm(ali_t * codec, int device, struct ali_pcm_descr
static struct ali_pcm_description ali_pcms[] = { static struct ali_pcm_description ali_pcms[] = {
{ "ALI 5451", ALI_CHANNELS, 1, &snd_ali_playback_ops, &snd_ali_capture_ops }, { "ALI 5451", ALI_CHANNELS, 1, &snd_ali_playback_ops, &snd_ali_capture_ops },
{ "ALI 5451 modem", 1, 1, &snd_ali_modem_playback_ops, &snd_ali_modem_capture_ops } { "ALI 5451 modem", 1, 1, &snd_ali_modem_playback_ops, &snd_ali_modem_capture_ops, SNDRV_PCM_CLASS_MODEM }
}; };
static int __devinit snd_ali_build_pcms(ali_t *codec) static int __devinit snd_ali_build_pcms(ali_t *codec)
@ -1991,7 +1990,7 @@ static int __devinit snd_ali_mixer(ali_t * codec)
for ( i = 0 ; i < codec->num_of_codecs ; i++) { for ( i = 0 ; i < codec->num_of_codecs ; i++) {
ac97.num = i; ac97.num = i;
if ((err = snd_ac97_mixer(codec->ac97_bus, &ac97, &codec->ac97[i])) < 0) { if ((err = snd_ac97_mixer(codec->ac97_bus, &ac97, &codec->ac97[i])) < 0) {
snd_printk("ali mixer %d creating error.\n", i); snd_printk(KERN_ERR "ali mixer %d creating error.\n", i);
if(i == 0) if(i == 0)
return err; return err;
codec->num_of_codecs = 1; codec->num_of_codecs = 1;
@ -2125,7 +2124,7 @@ static int snd_ali_chip_init(ali_t *codec)
snd_ali_printk("chip initializing ... \n"); snd_ali_printk("chip initializing ... \n");
if (snd_ali_reset_5451(codec)) { if (snd_ali_reset_5451(codec)) {
snd_printk("ali_chip_init: reset 5451 error.\n"); snd_printk(KERN_ERR "ali_chip_init: reset 5451 error.\n");
return -1; return -1;
} }
@ -2200,7 +2199,7 @@ static int __devinit snd_ali_resources(ali_t *codec)
codec->port = pci_resource_start(codec->pci, 0); codec->port = pci_resource_start(codec->pci, 0);
if (request_irq(codec->pci->irq, snd_ali_card_interrupt, SA_INTERRUPT|SA_SHIRQ, "ALI 5451", (void *)codec)) { if (request_irq(codec->pci->irq, snd_ali_card_interrupt, SA_INTERRUPT|SA_SHIRQ, "ALI 5451", (void *)codec)) {
snd_printk("Unable to request irq.\n"); snd_printk(KERN_ERR "Unable to request irq.\n");
return -EBUSY; return -EBUSY;
} }
codec->irq = codec->pci->irq; codec->irq = codec->pci->irq;
@ -2240,7 +2239,7 @@ static int __devinit snd_ali_create(snd_card_t * card,
/* check, if we can restrict PCI DMA transfers to 31 bits */ /* check, if we can restrict PCI DMA transfers to 31 bits */
if (pci_set_dma_mask(pci, 0x7fffffff) < 0 || if (pci_set_dma_mask(pci, 0x7fffffff) < 0 ||
pci_set_consistent_dma_mask(pci, 0x7fffffff) < 0) { pci_set_consistent_dma_mask(pci, 0x7fffffff) < 0) {
snd_printk("architecture does not support 31bit PCI busmaster DMA\n"); snd_printk(KERN_ERR "architecture does not support 31bit PCI busmaster DMA\n");
pci_disable_device(pci); pci_disable_device(pci);
return -ENXIO; return -ENXIO;
} }
@ -2329,7 +2328,7 @@ static int __devinit snd_ali_create(snd_card_t * card,
} }
if ((err = snd_ali_chip_init(codec)) < 0) { if ((err = snd_ali_chip_init(codec)) < 0) {
snd_printk("ali create: chip init error.\n"); snd_printk(KERN_ERR "ali create: chip init error.\n");
return err; return err;
} }
@ -2352,25 +2351,17 @@ static int __devinit snd_ali_create(snd_card_t * card,
static int __devinit snd_ali_probe(struct pci_dev *pci, static int __devinit snd_ali_probe(struct pci_dev *pci,
const struct pci_device_id *pci_id) const struct pci_device_id *pci_id)
{ {
static int dev;
snd_card_t *card; snd_card_t *card;
ali_t *codec; ali_t *codec;
int err; int err;
snd_ali_printk("probe ...\n"); snd_ali_printk("probe ...\n");
if (dev >= SNDRV_CARDS) card = snd_card_new(index, id, THIS_MODULE, 0);
return -ENODEV;
if (!enable[dev]) {
dev++;
return -ENOENT;
}
card = snd_card_new(index[dev], id[dev], THIS_MODULE, 0);
if (card == NULL) if (card == NULL)
return -ENOMEM; return -ENOMEM;
if ((err = snd_ali_create(card, pci, pcm_channels[dev], spdif[dev], &codec)) < 0) { if ((err = snd_ali_create(card, pci, pcm_channels, spdif, &codec)) < 0) {
snd_card_free(card); snd_card_free(card);
return err; return err;
} }
@ -2401,7 +2392,6 @@ static int __devinit snd_ali_probe(struct pci_dev *pci,
return err; return err;
} }
pci_set_drvdata(pci, card); pci_set_drvdata(pci, card);
dev++;
return 0; return 0;
} }

View File

@ -594,8 +594,7 @@ static int __devinit snd_als4000_create_gameport(snd_card_als4000_t *acard, int
acard->gameport = gp = gameport_allocate_port(); acard->gameport = gp = gameport_allocate_port();
if (!gp) { if (!gp) {
printk(KERN_ERR "als4000: cannot allocate memory for gameport\n"); printk(KERN_ERR "als4000: cannot allocate memory for gameport\n");
release_resource(r); release_and_free_resource(r);
kfree_nocheck(r);
return -ENOMEM; return -ENOMEM;
} }
@ -622,8 +621,7 @@ static void snd_als4000_free_gameport(snd_card_als4000_t *acard)
acard->gameport = NULL; acard->gameport = NULL;
snd_als4000_set_addr(acard->gcr, 0, 0, 0, 0); /* disable joystick */ snd_als4000_set_addr(acard->gcr, 0, 0, 0, 0); /* disable joystick */
release_resource(r); release_and_free_resource(r);
kfree_nocheck(r);
} }
} }
#else #else
@ -669,7 +667,7 @@ static int __devinit snd_card_als4000_probe(struct pci_dev *pci,
/* check, if we can restrict PCI DMA transfers to 24 bits */ /* check, if we can restrict PCI DMA transfers to 24 bits */
if (pci_set_dma_mask(pci, 0x00ffffff) < 0 || if (pci_set_dma_mask(pci, 0x00ffffff) < 0 ||
pci_set_consistent_dma_mask(pci, 0x00ffffff) < 0) { pci_set_consistent_dma_mask(pci, 0x00ffffff) < 0) {
snd_printk("architecture does not support 24bit PCI busmaster DMA\n"); snd_printk(KERN_ERR "architecture does not support 24bit PCI busmaster DMA\n");
pci_disable_device(pci); pci_disable_device(pci);
return -ENXIO; return -ENXIO;
} }

View File

@ -39,26 +39,27 @@ MODULE_DESCRIPTION("ATI IXP AC97 controller");
MODULE_LICENSE("GPL"); MODULE_LICENSE("GPL");
MODULE_SUPPORTED_DEVICE("{{ATI,IXP150/200/250/300/400}}"); MODULE_SUPPORTED_DEVICE("{{ATI,IXP150/200/250/300/400}}");
static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */ static int index = SNDRV_DEFAULT_IDX1; /* Index 0-MAX */
static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */ static char *id = SNDRV_DEFAULT_STR1; /* ID for this card */
static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP; /* Enable this card */ static int ac97_clock = 48000;
static int ac97_clock[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 48000}; static char *ac97_quirk;
static char *ac97_quirk[SNDRV_CARDS]; static int spdif_aclink = 1;
static int spdif_aclink[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 1};
module_param_array(index, int, NULL, 0444); module_param(index, int, 0444);
MODULE_PARM_DESC(index, "Index value for ATI IXP controller."); MODULE_PARM_DESC(index, "Index value for ATI IXP controller.");
module_param_array(id, charp, NULL, 0444); module_param(id, charp, 0444);
MODULE_PARM_DESC(id, "ID string for ATI IXP controller."); MODULE_PARM_DESC(id, "ID string for ATI IXP controller.");
module_param_array(enable, bool, NULL, 0444); module_param(ac97_clock, int, 0444);
MODULE_PARM_DESC(enable, "Enable audio part of ATI IXP controller.");
module_param_array(ac97_clock, int, NULL, 0444);
MODULE_PARM_DESC(ac97_clock, "AC'97 codec clock (default 48000Hz)."); MODULE_PARM_DESC(ac97_clock, "AC'97 codec clock (default 48000Hz).");
module_param_array(ac97_quirk, charp, NULL, 0444); module_param(ac97_quirk, charp, 0444);
MODULE_PARM_DESC(ac97_quirk, "AC'97 workaround for strange hardware."); MODULE_PARM_DESC(ac97_quirk, "AC'97 workaround for strange hardware.");
module_param_array(spdif_aclink, bool, NULL, 0444); module_param(spdif_aclink, bool, 0444);
MODULE_PARM_DESC(spdif_aclink, "S/PDIF over AC-link."); MODULE_PARM_DESC(spdif_aclink, "S/PDIF over AC-link.");
/* just for backward compatibility */
static int enable;
module_param(enable, bool, 0444);
/* /*
*/ */
@ -329,8 +330,7 @@ static int snd_atiixp_update_bits(atiixp_t *chip, unsigned int reg,
/* delay for one tick */ /* delay for one tick */
#define do_delay() do { \ #define do_delay() do { \
set_current_state(TASK_UNINTERRUPTIBLE); \ schedule_timeout_uninterruptible(1); \
schedule_timeout(1); \
} while (0) } while (0)
@ -1372,7 +1372,6 @@ static int __devinit snd_atiixp_mixer_new(atiixp_t *chip, int clock, const char
if ((err = snd_ac97_bus(chip->card, 0, &ops, chip, &pbus)) < 0) if ((err = snd_ac97_bus(chip->card, 0, &ops, chip, &pbus)) < 0)
return err; return err;
pbus->clock = clock; pbus->clock = clock;
pbus->shared_type = AC97_SHARED_TYPE_ATIIXP; /* shared with modem driver */
chip->ac97_bus = pbus; chip->ac97_bus = pbus;
codec_count = 0; codec_count = 0;
@ -1579,26 +1578,18 @@ static int __devinit snd_atiixp_create(snd_card_t *card,
static int __devinit snd_atiixp_probe(struct pci_dev *pci, static int __devinit snd_atiixp_probe(struct pci_dev *pci,
const struct pci_device_id *pci_id) const struct pci_device_id *pci_id)
{ {
static int dev;
snd_card_t *card; snd_card_t *card;
atiixp_t *chip; atiixp_t *chip;
unsigned char revision; unsigned char revision;
int err; int err;
if (dev >= SNDRV_CARDS) card = snd_card_new(index, id, THIS_MODULE, 0);
return -ENODEV;
if (!enable[dev]) {
dev++;
return -ENOENT;
}
card = snd_card_new(index[dev], id[dev], THIS_MODULE, 0);
if (card == NULL) if (card == NULL)
return -ENOMEM; return -ENOMEM;
pci_read_config_byte(pci, PCI_REVISION_ID, &revision); pci_read_config_byte(pci, PCI_REVISION_ID, &revision);
strcpy(card->driver, spdif_aclink[dev] ? "ATIIXP" : "ATIIXP-SPDMA"); strcpy(card->driver, spdif_aclink ? "ATIIXP" : "ATIIXP-SPDMA");
strcpy(card->shortname, "ATI IXP"); strcpy(card->shortname, "ATI IXP");
if ((err = snd_atiixp_create(card, pci, &chip)) < 0) if ((err = snd_atiixp_create(card, pci, &chip)) < 0)
goto __error; goto __error;
@ -1606,9 +1597,9 @@ static int __devinit snd_atiixp_probe(struct pci_dev *pci,
if ((err = snd_atiixp_aclink_reset(chip)) < 0) if ((err = snd_atiixp_aclink_reset(chip)) < 0)
goto __error; goto __error;
chip->spdif_over_aclink = spdif_aclink[dev]; chip->spdif_over_aclink = spdif_aclink;
if ((err = snd_atiixp_mixer_new(chip, ac97_clock[dev], ac97_quirk[dev])) < 0) if ((err = snd_atiixp_mixer_new(chip, ac97_clock, ac97_quirk)) < 0)
goto __error; goto __error;
if ((err = snd_atiixp_pcm_new(chip)) < 0) if ((err = snd_atiixp_pcm_new(chip)) < 0)
@ -1629,7 +1620,6 @@ static int __devinit snd_atiixp_probe(struct pci_dev *pci,
goto __error; goto __error;
pci_set_drvdata(pci, card); pci_set_drvdata(pci, card);
dev++;
return 0; return 0;
__error: __error:

View File

@ -39,20 +39,21 @@ MODULE_DESCRIPTION("ATI IXP MC97 controller");
MODULE_LICENSE("GPL"); MODULE_LICENSE("GPL");
MODULE_SUPPORTED_DEVICE("{{ATI,IXP150/200/250}}"); MODULE_SUPPORTED_DEVICE("{{ATI,IXP150/200/250}}");
static int index[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = -2}; /* Exclude the first card */ static int index = -2; /* Exclude the first card */
static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */ static char *id = SNDRV_DEFAULT_STR1; /* ID for this card */
static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP; /* Enable this card */ static int ac97_clock = 48000;
static int ac97_clock[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 48000};
module_param_array(index, int, NULL, 0444); module_param(index, int, 0444);
MODULE_PARM_DESC(index, "Index value for ATI IXP controller."); MODULE_PARM_DESC(index, "Index value for ATI IXP controller.");
module_param_array(id, charp, NULL, 0444); module_param(id, charp, 0444);
MODULE_PARM_DESC(id, "ID string for ATI IXP controller."); MODULE_PARM_DESC(id, "ID string for ATI IXP controller.");
module_param_array(enable, bool, NULL, 0444); module_param(ac97_clock, int, 0444);
MODULE_PARM_DESC(enable, "Enable audio part of ATI IXP controller.");
module_param_array(ac97_clock, int, NULL, 0444);
MODULE_PARM_DESC(ac97_clock, "AC'97 codec clock (default 48000Hz)."); MODULE_PARM_DESC(ac97_clock, "AC'97 codec clock (default 48000Hz).");
/* just for backward compatibility */
static int enable;
module_param(enable, bool, 0444);
/* /*
*/ */
@ -306,8 +307,7 @@ static int snd_atiixp_update_bits(atiixp_t *chip, unsigned int reg,
/* delay for one tick */ /* delay for one tick */
#define do_delay() do { \ #define do_delay() do { \
set_current_state(TASK_UNINTERRUPTIBLE); \ schedule_timeout_uninterruptible(1); \
schedule_timeout(1); \
} while (0) } while (0)
@ -989,6 +989,7 @@ static int __devinit snd_atiixp_pcm_new(atiixp_t *chip)
return err; return err;
snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &snd_atiixp_playback_ops); snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &snd_atiixp_playback_ops);
snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &snd_atiixp_capture_ops); snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &snd_atiixp_capture_ops);
pcm->dev_class = SNDRV_PCM_CLASS_MODEM;
pcm->private_data = chip; pcm->private_data = chip;
strcpy(pcm->name, "ATI IXP MC97"); strcpy(pcm->name, "ATI IXP MC97");
chip->pcmdevs[ATI_PCMDEV_ANALOG] = pcm; chip->pcmdevs[ATI_PCMDEV_ANALOG] = pcm;
@ -1067,7 +1068,6 @@ static int __devinit snd_atiixp_mixer_new(atiixp_t *chip, int clock)
if ((err = snd_ac97_bus(chip->card, 0, &ops, chip, &pbus)) < 0) if ((err = snd_ac97_bus(chip->card, 0, &ops, chip, &pbus)) < 0)
return err; return err;
pbus->clock = clock; pbus->clock = clock;
pbus->shared_type = AC97_SHARED_TYPE_ATIIXP; /* shared with audio driver */
chip->ac97_bus = pbus; chip->ac97_bus = pbus;
codec_count = 0; codec_count = 0;
@ -1256,20 +1256,12 @@ static int __devinit snd_atiixp_create(snd_card_t *card,
static int __devinit snd_atiixp_probe(struct pci_dev *pci, static int __devinit snd_atiixp_probe(struct pci_dev *pci,
const struct pci_device_id *pci_id) const struct pci_device_id *pci_id)
{ {
static int dev;
snd_card_t *card; snd_card_t *card;
atiixp_t *chip; atiixp_t *chip;
unsigned char revision; unsigned char revision;
int err; int err;
if (dev >= SNDRV_CARDS) card = snd_card_new(index, id, THIS_MODULE, 0);
return -ENODEV;
if (!enable[dev]) {
dev++;
return -ENOENT;
}
card = snd_card_new(index[dev], id[dev], THIS_MODULE, 0);
if (card == NULL) if (card == NULL)
return -ENOMEM; return -ENOMEM;
@ -1283,7 +1275,7 @@ static int __devinit snd_atiixp_probe(struct pci_dev *pci,
if ((err = snd_atiixp_aclink_reset(chip)) < 0) if ((err = snd_atiixp_aclink_reset(chip)) < 0)
goto __error; goto __error;
if ((err = snd_atiixp_mixer_new(chip, ac97_clock[dev])) < 0) if ((err = snd_atiixp_mixer_new(chip, ac97_clock)) < 0)
goto __error; goto __error;
if ((err = snd_atiixp_pcm_new(chip)) < 0) if ((err = snd_atiixp_pcm_new(chip)) < 0)
@ -1302,7 +1294,6 @@ static int __devinit snd_atiixp_probe(struct pci_dev *pci,
goto __error; goto __error;
pci_set_drvdata(pci, card); pci_set_drvdata(pci, card);
dev++;
return 0; return 0;
__error: __error:

View File

@ -178,11 +178,6 @@
#define EN_SPDIF 0x000c0000 #define EN_SPDIF 0x000c0000
#define VORTEX_CODEC_CHN 0x29080 #define VORTEX_CODEC_CHN 0x29080
#define VORTEX_CODEC_WRITE 0x00800000
#define VORTEX_CODEC_ADDSHIFT 16
#define VORTEX_CODEC_ADDMASK 0x7f0000 /* 0x000f0000 */
#define VORTEX_CODEC_DATSHIFT 0
#define VORTEX_CODEC_DATMASK 0xffff
#define VORTEX_CODEC_IO 0x29188 #define VORTEX_CODEC_IO 0x29188
/* SPDIF */ /* SPDIF */

View File

@ -162,11 +162,6 @@
#define EN_SPORT 0x00030000 #define EN_SPORT 0x00030000
#define EN_SPDIF 0x000c0000 #define EN_SPDIF 0x000c0000
#define VORTEX_CODEC_CHN 0x11880 #define VORTEX_CODEC_CHN 0x11880
#define VORTEX_CODEC_WRITE 0x00800000
#define VORTEX_CODEC_ADDSHIFT 16
#define VORTEX_CODEC_ADDMASK 0x7f0000 /* 0x000f0000 */
#define VORTEX_CODEC_DATSHIFT 0
#define VORTEX_CODEC_DATMASK 0xffff
#define VORTEX_CODEC_IO 0x11988 #define VORTEX_CODEC_IO 0x11988
#define VORTEX_SPDIF_FLAGS 0x1005c /* FIXME */ #define VORTEX_SPDIF_FLAGS 0x1005c /* FIXME */

View File

@ -194,11 +194,6 @@
#define VORTEX_CODEC_CTRL 0x29184 #define VORTEX_CODEC_CTRL 0x29184
#define VORTEX_CODEC_IO 0x29188 #define VORTEX_CODEC_IO 0x29188
#define VORTEX_CODEC_WRITE 0x00800000
#define VORTEX_CODEC_ADDSHIFT 16
#define VORTEX_CODEC_ADDMASK 0x7f0000 /* 0x000f0000 */
#define VORTEX_CODEC_DATSHIFT 0
#define VORTEX_CODEC_DATMASK 0xffff
#define VORTEX_CODEC_SPORTCTRL 0x2918c #define VORTEX_CODEC_SPORTCTRL 0x2918c

View File

@ -303,7 +303,7 @@ snd_vortex_probe(struct pci_dev *pci, const struct pci_device_id *pci_id)
if (snd_seq_device_new(card, 1, SNDRV_SEQ_DEV_ID_VORTEX_SYNTH, if (snd_seq_device_new(card, 1, SNDRV_SEQ_DEV_ID_VORTEX_SYNTH,
sizeof(snd_vortex_synth_arg_t), &wave) < 0 sizeof(snd_vortex_synth_arg_t), &wave) < 0
|| wave == NULL) { || wave == NULL) {
snd_printk("Can't initialize Aureal wavetable synth\n"); snd_printk(KERN_ERR "Can't initialize Aureal wavetable synth\n");
} else { } else {
snd_vortex_synth_arg_t *arg; snd_vortex_synth_arg_t *arg;

View File

@ -79,6 +79,14 @@
#define VORTEX_RESOURCE_A3D 0x00000004 #define VORTEX_RESOURCE_A3D 0x00000004
#define VORTEX_RESOURCE_LAST 0x00000005 #define VORTEX_RESOURCE_LAST 0x00000005
/* codec io: VORTEX_CODEC_IO bits */
#define VORTEX_CODEC_ID_SHIFT 24
#define VORTEX_CODEC_WRITE 0x00800000
#define VORTEX_CODEC_ADDSHIFT 16
#define VORTEX_CODEC_ADDMASK 0x7f0000
#define VORTEX_CODEC_DATSHIFT 0
#define VORTEX_CODEC_DATMASK 0xffff
/* Check for SDAC bit in "Extended audio ID" AC97 register */ /* Check for SDAC bit in "Extended audio ID" AC97 register */
//#define VORTEX_IS_QUAD(x) (((x)->codec == NULL) ? 0 : ((x)->codec->ext_id&0x80)) //#define VORTEX_IS_QUAD(x) (((x)->codec == NULL) ? 0 : ((x)->codec->ext_id&0x80))
#define VORTEX_IS_QUAD(x) ((x)->isquad) #define VORTEX_IS_QUAD(x) ((x)->isquad)

View File

@ -488,7 +488,7 @@ static void a3dsrc_ZeroStateA3D(a3dsrc_t * a)
int i, var, var2; int i, var, var2;
if ((a->vortex) == NULL) { if ((a->vortex) == NULL) {
printk("vortex: ZeroStateA3D: ERROR: a->vortex is NULL\n"); printk(KERN_ERR "vortex: ZeroStateA3D: ERROR: a->vortex is NULL\n");
return; return;
} }

View File

@ -2033,7 +2033,7 @@ vortex_adb_checkinout(vortex_t * vortex, int resmap[], int out, int restype)
} }
} }
} }
printk("vortex: FATAL: ResManager: resource type %d exhausted.\n", restype); printk(KERN_ERR "vortex: FATAL: ResManager: resource type %d exhausted.\n", restype);
return -ENOMEM; return -ENOMEM;
} }
@ -2165,7 +2165,7 @@ vortex_adb_allocroute(vortex_t * vortex, int dma, int nr_ch, int dir, int type)
memset(stream->resources, 0, memset(stream->resources, 0,
sizeof(unsigned char) * sizeof(unsigned char) *
VORTEX_RESOURCE_LAST); VORTEX_RESOURCE_LAST);
printk("vortex: out of A3D sources. Sorry\n"); printk(KERN_ERR "vortex: out of A3D sources. Sorry\n");
return -EBUSY; return -EBUSY;
} }
/* (De)Initialize A3D hardware source. */ /* (De)Initialize A3D hardware source. */
@ -2532,7 +2532,8 @@ vortex_codec_write(ac97_t * codec, unsigned short addr, unsigned short data)
hwwrite(card->mmio, VORTEX_CODEC_IO, hwwrite(card->mmio, VORTEX_CODEC_IO,
((addr << VORTEX_CODEC_ADDSHIFT) & VORTEX_CODEC_ADDMASK) | ((addr << VORTEX_CODEC_ADDSHIFT) & VORTEX_CODEC_ADDMASK) |
((data << VORTEX_CODEC_DATSHIFT) & VORTEX_CODEC_DATMASK) | ((data << VORTEX_CODEC_DATSHIFT) & VORTEX_CODEC_DATMASK) |
VORTEX_CODEC_WRITE); VORTEX_CODEC_WRITE |
(codec->num << VORTEX_CODEC_ID_SHIFT) );
/* Flush Caches. */ /* Flush Caches. */
hwread(card->mmio, VORTEX_CODEC_IO); hwread(card->mmio, VORTEX_CODEC_IO);
@ -2554,7 +2555,8 @@ static unsigned short vortex_codec_read(ac97_t * codec, unsigned short addr)
} }
} }
/* set up read address */ /* set up read address */
read_addr = ((addr << VORTEX_CODEC_ADDSHIFT) & VORTEX_CODEC_ADDMASK); read_addr = ((addr << VORTEX_CODEC_ADDSHIFT) & VORTEX_CODEC_ADDMASK) |
(codec->num << VORTEX_CODEC_ID_SHIFT) ;
hwwrite(card->mmio, VORTEX_CODEC_IO, read_addr); hwwrite(card->mmio, VORTEX_CODEC_IO, read_addr);
/* wait for address */ /* wait for address */

View File

@ -854,7 +854,7 @@ snd_vortex_peaks_get(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
vortex_Eqlzr_GetAllPeaks(vortex, peaks, &count); vortex_Eqlzr_GetAllPeaks(vortex, peaks, &count);
if (count != 20) { if (count != 20) {
printk("vortex: peak count error 20 != %d \n", count); printk(KERN_ERR "vortex: peak count error 20 != %d \n", count);
return -1; return -1;
} }
for (i = 0; i < 20; i++) for (i = 0; i < 20; i++)

View File

@ -90,7 +90,7 @@ static int vortex_wt_allocroute(vortex_t * vortex, int wt, int nr_ch)
hwwrite(vortex->mmio, WT_PARM(wt, 2), 0); hwwrite(vortex->mmio, WT_PARM(wt, 2), 0);
temp = hwread(vortex->mmio, WT_PARM(wt, 3)); temp = hwread(vortex->mmio, WT_PARM(wt, 3));
printk("vortex: WT PARM3: %x\n", temp); printk(KERN_DEBUG "vortex: WT PARM3: %x\n", temp);
//hwwrite(vortex->mmio, WT_PARM(wt, 3), temp); //hwwrite(vortex->mmio, WT_PARM(wt, 3), temp);
hwwrite(vortex->mmio, WT_DELAY(wt, 0), 0); hwwrite(vortex->mmio, WT_DELAY(wt, 0), 0);
@ -98,7 +98,7 @@ static int vortex_wt_allocroute(vortex_t * vortex, int wt, int nr_ch)
hwwrite(vortex->mmio, WT_DELAY(wt, 2), 0); hwwrite(vortex->mmio, WT_DELAY(wt, 2), 0);
hwwrite(vortex->mmio, WT_DELAY(wt, 3), 0); hwwrite(vortex->mmio, WT_DELAY(wt, 3), 0);
printk("vortex: WT GMODE: %x\n", hwread(vortex->mmio, WT_GMODE(wt))); printk(KERN_DEBUG "vortex: WT GMODE: %x\n", hwread(vortex->mmio, WT_GMODE(wt)));
hwwrite(vortex->mmio, WT_PARM(wt, 2), 0xffffffff); hwwrite(vortex->mmio, WT_PARM(wt, 2), 0xffffffff);
hwwrite(vortex->mmio, WT_PARM(wt, 3), 0xcff1c810); hwwrite(vortex->mmio, WT_PARM(wt, 3), 0xcff1c810);
@ -106,7 +106,7 @@ static int vortex_wt_allocroute(vortex_t * vortex, int wt, int nr_ch)
voice->parm0 = voice->parm1 = 0xcfb23e2f; voice->parm0 = voice->parm1 = 0xcfb23e2f;
hwwrite(vortex->mmio, WT_PARM(wt, 0), voice->parm0); hwwrite(vortex->mmio, WT_PARM(wt, 0), voice->parm0);
hwwrite(vortex->mmio, WT_PARM(wt, 1), voice->parm1); hwwrite(vortex->mmio, WT_PARM(wt, 1), voice->parm1);
printk("vortex: WT GMODE 2 : %x\n", hwread(vortex->mmio, WT_GMODE(wt))); printk(KERN_DEBUG "vortex: WT GMODE 2 : %x\n", hwread(vortex->mmio, WT_GMODE(wt)));
return 0; return 0;
} }
@ -203,7 +203,7 @@ vortex_wt_SetReg(vortex_t * vortex, unsigned char reg, int wt,
} }
} else { } else {
if (wt >= NR_WT) { if (wt >= NR_WT) {
printk("vortex: WT SetReg: voice out of range\n"); printk(KERN_ERR "vortex: WT SetReg: voice out of range\n");
return 0; return 0;
} }
} }

File diff suppressed because it is too large Load Diff

View File

@ -1,19 +1,17 @@
#ifndef __SOUND_AZF3328_H #ifndef __SOUND_AZT3328_H
#define __SOUND_AZF3328_H #define __SOUND_AZT3328_H
/* type argument to use for the I/O functions */ /* "PU" == "power-up value", as tested on PCI168 PCI rev. 10 */
#define WORD_VALUE 0x1000
#define DWORD_VALUE 0x2000
#define BYTE_VALUE 0x4000
/*** main I/O area port indices ***/ /*** main I/O area port indices ***/
/* (only 0x70 of 0x80 bytes saved/restored by Windows driver) */ /* (only 0x70 of 0x80 bytes saved/restored by Windows driver) */
/* the driver initialisation suggests a layout of 3 main areas: /* the driver initialisation suggests a layout of 4 main areas:
* from 0x00 (playback), from 0x20 (recording) and from 0x40 (maybe DirectX * from 0x00 (playback), from 0x20 (recording) and from 0x40 (maybe MPU401??).
* timer ???). and probably another area from 0x60 to 0x6f * And another area from 0x60 to 0x6f (DirectX timer, IRQ management,
* (IRQ management, power management etc. ???). */ * power management etc.???). */
/* playback area */
#define IDX_IO_PLAY_FLAGS 0x00 /** playback area **/
#define IDX_IO_PLAY_FLAGS 0x00 /* PU:0x0000 */
/* able to reactivate output after output muting due to 8/16bit /* able to reactivate output after output muting due to 8/16bit
* output change, just like 0x0002. * output change, just like 0x0002.
* 0x0001 is the only bit that's able to start the DMA counter */ * 0x0001 is the only bit that's able to start the DMA counter */
@ -29,7 +27,7 @@
#define DMA_EPILOGUE_SOMETHING 0x0010 #define DMA_EPILOGUE_SOMETHING 0x0010
#define DMA_SOMETHING_ELSE 0x0020 /* ??? */ #define DMA_SOMETHING_ELSE 0x0020 /* ??? */
#define SOMETHING_UNMODIFIABLE 0xffc0 /* unused ? not modifiable */ #define SOMETHING_UNMODIFIABLE 0xffc0 /* unused ? not modifiable */
#define IDX_IO_PLAY_IRQMASK 0x02 #define IDX_IO_PLAY_IRQTYPE 0x02 /* PU:0x0001 */
/* write back to flags in case flags are set, in order to ACK IRQ in handler /* write back to flags in case flags are set, in order to ACK IRQ in handler
* (bit 1 of port 0x64 indicates interrupt for one of these three types) * (bit 1 of port 0x64 indicates interrupt for one of these three types)
* sometimes in this case it just writes 0xffff to globally ACK all IRQs * sometimes in this case it just writes 0xffff to globally ACK all IRQs
@ -41,36 +39,39 @@
#define IRQMASK_SOME_STATUS_1 0x0008 /* \ related bits */ #define IRQMASK_SOME_STATUS_1 0x0008 /* \ related bits */
#define IRQMASK_SOME_STATUS_2 0x0010 /* / (checked together in loop) */ #define IRQMASK_SOME_STATUS_2 0x0010 /* / (checked together in loop) */
#define IRQMASK_UNMODIFIABLE 0xffe0 /* unused ? not modifiable */ #define IRQMASK_UNMODIFIABLE 0xffe0 /* unused ? not modifiable */
#define IDX_IO_PLAY_DMA_START_1 0x04 /* start address of 1st DMA play area */ #define IDX_IO_PLAY_DMA_START_1 0x04 /* start address of 1st DMA play area, PU:0x00000000 */
#define IDX_IO_PLAY_DMA_START_2 0x08 /* start address of 2nd DMA play area */ #define IDX_IO_PLAY_DMA_START_2 0x08 /* start address of 2nd DMA play area, PU:0x00000000 */
#define IDX_IO_PLAY_DMA_LEN_1 0x0c /* length of 1st DMA play area */ #define IDX_IO_PLAY_DMA_LEN_1 0x0c /* length of 1st DMA play area, PU:0x0000 */
#define IDX_IO_PLAY_DMA_LEN_2 0x0e /* length of 2nd DMA play area */ #define IDX_IO_PLAY_DMA_LEN_2 0x0e /* length of 2nd DMA play area, PU:0x0000 */
#define IDX_IO_PLAY_DMA_CURRPOS 0x10 /* current DMA position */ #define IDX_IO_PLAY_DMA_CURRPOS 0x10 /* current DMA position, PU:0x00000000 */
#define IDX_IO_PLAY_DMA_CURROFS 0x14 /* offset within current DMA play area */ #define IDX_IO_PLAY_DMA_CURROFS 0x14 /* offset within current DMA play area, PU:0x0000 */
#define IDX_IO_PLAY_SOUNDFORMAT 0x16 #define IDX_IO_PLAY_SOUNDFORMAT 0x16 /* PU:0x0010 */
/* all unspecified bits can't be modified */ /* all unspecified bits can't be modified */
#define SOUNDFORMAT_FREQUENCY_MASK 0x000f #define SOUNDFORMAT_FREQUENCY_MASK 0x000f
#define SOUNDFORMAT_XTAL1 0x00
#define SOUNDFORMAT_XTAL2 0x01
/* all _SUSPECTED_ values are not used by Windows drivers, so we don't /* all _SUSPECTED_ values are not used by Windows drivers, so we don't
* have any hard facts, only rough measurements */ * have any hard facts, only rough measurements */
#define SOUNDFORMAT_FREQ_SUSPECTED_4000 0x0c #define SOUNDFORMAT_FREQ_SUSPECTED_4000 0x0c | SOUNDFORMAT_XTAL1
#define SOUNDFORMAT_FREQ_SUSPECTED_4800 0x0a #define SOUNDFORMAT_FREQ_SUSPECTED_4800 0x0a | SOUNDFORMAT_XTAL1
#define SOUNDFORMAT_FREQ_5510 0x0d #define SOUNDFORMAT_FREQ_5510 0x0c | SOUNDFORMAT_XTAL2
#define SOUNDFORMAT_FREQ_6620 0x0b #define SOUNDFORMAT_FREQ_6620 0x0a | SOUNDFORMAT_XTAL2
#define SOUNDFORMAT_FREQ_8000 0x00 /* also 0x0e ? */ #define SOUNDFORMAT_FREQ_8000 0x00 | SOUNDFORMAT_XTAL1 /* also 0x0e | SOUNDFORMAT_XTAL1? */
#define SOUNDFORMAT_FREQ_9600 0x08 #define SOUNDFORMAT_FREQ_9600 0x08 | SOUNDFORMAT_XTAL1
#define SOUNDFORMAT_FREQ_SUSPECTED_12000 0x09 #define SOUNDFORMAT_FREQ_11025 0x00 | SOUNDFORMAT_XTAL2 /* also 0x0e | SOUNDFORMAT_XTAL2? */
#define SOUNDFORMAT_FREQ_11025 0x01 /* also 0x0f ? */ #define SOUNDFORMAT_FREQ_SUSPECTED_13240 0x08 | SOUNDFORMAT_XTAL2 /* seems to be 6620 *2 */
#define SOUNDFORMAT_FREQ_16000 0x02 #define SOUNDFORMAT_FREQ_16000 0x02 | SOUNDFORMAT_XTAL1
#define SOUNDFORMAT_FREQ_22050 0x03 #define SOUNDFORMAT_FREQ_22050 0x02 | SOUNDFORMAT_XTAL2
#define SOUNDFORMAT_FREQ_32000 0x04 #define SOUNDFORMAT_FREQ_32000 0x04 | SOUNDFORMAT_XTAL1
#define SOUNDFORMAT_FREQ_44100 0x05 #define SOUNDFORMAT_FREQ_44100 0x04 | SOUNDFORMAT_XTAL2
#define SOUNDFORMAT_FREQ_48000 0x06 #define SOUNDFORMAT_FREQ_48000 0x06 | SOUNDFORMAT_XTAL1
#define SOUNDFORMAT_FREQ_SUSPECTED_64000 0x07 #define SOUNDFORMAT_FREQ_SUSPECTED_66200 0x06 | SOUNDFORMAT_XTAL2 /* 66200 (13240 * 5); 64000 may have been nicer :-\ */
#define SOUNDFORMAT_FLAG_16BIT 0x0010 #define SOUNDFORMAT_FLAG_16BIT 0x0010
#define SOUNDFORMAT_FLAG_2CHANNELS 0x0020 #define SOUNDFORMAT_FLAG_2CHANNELS 0x0020
/* recording area (see also: playback bit flag definitions) */
#define IDX_IO_REC_FLAGS 0x20 /* ?? */ /** recording area (see also: playback bit flag definitions) **/
#define IDX_IO_REC_IRQMASK 0x22 /* ?? */ #define IDX_IO_REC_FLAGS 0x20 /* ??, PU:0x0000 */
#define IDX_IO_REC_IRQTYPE 0x22 /* ??, PU:0x0000 */
#define IRQ_REC_SOMETHING 0x0001 /* something & ACK */ #define IRQ_REC_SOMETHING 0x0001 /* something & ACK */
#define IRQ_FINISHED_RECBUF_1 0x0002 /* 1st dmabuf finished & ACK */ #define IRQ_FINISHED_RECBUF_1 0x0002 /* 1st dmabuf finished & ACK */
#define IRQ_FINISHED_RECBUF_2 0x0004 /* 2nd dmabuf finished & ACK */ #define IRQ_FINISHED_RECBUF_2 0x0004 /* 2nd dmabuf finished & ACK */
@ -78,39 +79,47 @@
* but OTOH they are most likely at port 0x22 instead */ * but OTOH they are most likely at port 0x22 instead */
#define IRQMASK_SOME_STATUS_1 0x0008 /* \ related bits */ #define IRQMASK_SOME_STATUS_1 0x0008 /* \ related bits */
#define IRQMASK_SOME_STATUS_2 0x0010 /* / (checked together in loop) */ #define IRQMASK_SOME_STATUS_2 0x0010 /* / (checked together in loop) */
#define IDX_IO_REC_DMA_START_1 0x24 #define IDX_IO_REC_DMA_START_1 0x24 /* PU:0x00000000 */
#define IDX_IO_REC_DMA_START_2 0x28 #define IDX_IO_REC_DMA_START_2 0x28 /* PU:0x00000000 */
#define IDX_IO_REC_DMA_LEN_1 0x2c #define IDX_IO_REC_DMA_LEN_1 0x2c /* PU:0x0000 */
#define IDX_IO_REC_DMA_LEN_2 0x2e #define IDX_IO_REC_DMA_LEN_2 0x2e /* PU:0x0000 */
#define IDX_IO_REC_DMA_CURRPOS 0x30 #define IDX_IO_REC_DMA_CURRPOS 0x30 /* PU:0x00000000 */
#define IDX_IO_REC_DMA_CURROFS 0x34 #define IDX_IO_REC_DMA_CURROFS 0x34 /* PU:0x00000000 */
#define IDX_IO_REC_SOUNDFORMAT 0x36 #define IDX_IO_REC_SOUNDFORMAT 0x36 /* PU:0x0000 */
/* some third area ? (after playback and recording) */
#define IDX_IO_SOMETHING_FLAGS 0x40 /* gets set to 0x34 just like port 0x0 and 0x20 on card init */ /** hmm, what is this I/O area for? MPU401?? (after playback, recording, ???, timer) **/
#define IDX_IO_SOMETHING_FLAGS 0x40 /* gets set to 0x34 just like port 0x0 and 0x20 on card init, PU:0x0000 */
/* general */ /* general */
#define IDX_IO_60H 0x60 /* writing 0xffff returns 0xffff */ #define IDX_IO_42H 0x42 /* PU:0x0001 */
#define IDX_IO_62H 0x62 /* writing to WORD 0x0062 can hang the box ! --> responsible for IRQ management as a whole ?? */
#define IDX_IO_IRQ63H 0x63 /* FIXME !! */ /** DirectX timer, main interrupt area (FIXME: and something else?) **/
#define IO_IRQ63H_SOMETHING 0x04 /* being set in IRQ handler in case port 0x00 had 0x0020 set upon IRQ handler */ #define IDX_IO_TIMER_VALUE 0x60 /* found this timer area by pure luck :-) */
#define TIMER_VALUE_MASK 0x000fffffUL /* timer countdown value; triggers IRQ when timer is finished */
#define TIMER_ENABLE_COUNTDOWN 0x01000000UL /* activate the timer countdown */
#define TIMER_ENABLE_IRQ 0x02000000UL /* trigger timer IRQ on zero transition */
#define TIMER_ACK_IRQ 0x04000000UL /* being set in IRQ handler in case port 0x00 (hmm, not port 0x64!?!?) had 0x0020 set upon IRQ handler */
#define IDX_IO_IRQSTATUS 0x64 #define IDX_IO_IRQSTATUS 0x64
#define IRQ_PLAYBACK 0x0001 #define IRQ_PLAYBACK 0x0001
#define IRQ_RECORDING 0x0002 #define IRQ_RECORDING 0x0002
#define IRQ_MPU401 0x0010 #define IRQ_MPU401 0x0010
#define IRQ_SOMEIRQ 0x0020 /* ???? */ #define IRQ_TIMER 0x0020 /* DirectX timer */
#define IRQ_WHO_KNOWS_UNUSED 0x00e0 /* probably unused */ #define IRQ_UNKNOWN1 0x0040 /* probably unused */
#define IRQ_UNKNOWN2 0x0080 /* probably unused */
#define IDX_IO_66H 0x66 /* writing 0xffff returns 0x0000 */ #define IDX_IO_66H 0x66 /* writing 0xffff returns 0x0000 */
#define IDX_IO_SOME_VALUE 0x68 /* this is always set to 0x3ff, and writable; maybe some buffer limit, but I couldn't find out more */ #define IDX_IO_SOME_VALUE 0x68 /* this is set to e.g. 0x3ff or 0x300, and writable; maybe some buffer limit, but I couldn't find out more, PU:0x00ff */
#define IDX_IO_6AH 0x6A /* this WORD can be set to have bits 0x0028 activated; actually inhibits PCM playback !!! maybe power management ?? */ #define IDX_IO_6AH 0x6A /* this WORD can be set to have bits 0x0028 activated; actually inhibits PCM playback!!! maybe power management?? */
#define IDX_IO_6CH 0x6C /* this WORD can have all its bits activated ? */ #define IDX_IO_6CH 0x6C
#define IDX_IO_6EH 0x6E /* writing 0xffff returns 0x83fe */ #define IDX_IO_6EH 0x6E /* writing 0xffff returns 0x83fe */
/* further I/O indices not saved/restored, so probably not used */ /* further I/O indices not saved/restored, so probably not used */
/*** I/O 2 area port indices ***/ /*** I/O 2 area port indices ***/
/* (only 0x06 of 0x08 bytes saved/restored by Windows driver) */ /* (only 0x06 of 0x08 bytes saved/restored by Windows driver) */
#define IDX_IO2_LEGACY_ADDR 0x04 #define IDX_IO2_LEGACY_ADDR 0x04
#define LEGACY_SOMETHING 0x01 /* OPL3 ?? */ #define LEGACY_SOMETHING 0x01 /* OPL3?? */
#define LEGACY_JOY 0x08 #define LEGACY_JOY 0x08
/*** mixer I/O area port indices ***/ /*** mixer I/O area port indices ***/
/* (only 0x22 of 0x40 bytes saved/restored by Windows driver) /* (only 0x22 of 0x40 bytes saved/restored by Windows driver)
* generally spoken: AC97 register index = AZF3328 mixer reg index + 2 * generally spoken: AC97 register index = AZF3328 mixer reg index + 2
@ -148,18 +157,18 @@
/* unlisted bits are unmodifiable */ /* unlisted bits are unmodifiable */
#define MIXER_ADVCTL1_3DWIDTH_MASK 0x000e #define MIXER_ADVCTL1_3DWIDTH_MASK 0x000e
#define MIXER_ADVCTL1_HIFI3D_MASK 0x0300 #define MIXER_ADVCTL1_HIFI3D_MASK 0x0300
#define IDX_MIXER_ADVCTL2 0x20 /* resembles AC97_GENERAL_PURPOSE reg ! */ #define IDX_MIXER_ADVCTL2 0x20 /* resembles AC97_GENERAL_PURPOSE reg! */
/* unlisted bits are unmodifiable */ /* unlisted bits are unmodifiable */
#define MIXER_ADVCTL2_BIT7 0x0080 /* WaveOut 3D Bypass ? mutes WaveOut at LineOut */ #define MIXER_ADVCTL2_BIT7 0x0080 /* WaveOut 3D Bypass? mutes WaveOut at LineOut */
#define MIXER_ADVCTL2_BIT8 0x0100 /* is this Modem Out Select ? */ #define MIXER_ADVCTL2_BIT8 0x0100 /* is this Modem Out Select? */
#define MIXER_ADVCTL2_BIT9 0x0200 /* Mono Select Source ? */ #define MIXER_ADVCTL2_BIT9 0x0200 /* Mono Select Source? */
#define MIXER_ADVCTL2_BIT13 0x2000 /* 3D enable ? */ #define MIXER_ADVCTL2_BIT13 0x2000 /* 3D enable? */
#define MIXER_ADVCTL2_BIT15 0x8000 /* unknown */ #define MIXER_ADVCTL2_BIT15 0x8000 /* unknown */
#define IDX_MIXER_SOMETHING30H 0x30 /* used, but unknown ??? */ #define IDX_MIXER_SOMETHING30H 0x30 /* used, but unknown??? */
/* driver internal flags */ /* driver internal flags */
#define SET_CHAN_LEFT 1 #define SET_CHAN_LEFT 1
#define SET_CHAN_RIGHT 2 #define SET_CHAN_RIGHT 2
#endif /* __SOUND_AZF3328_H */ #endif /* __SOUND_AZT3328_H */

View File

@ -1,3 +1,3 @@
snd-ca0106-objs := ca0106_main.o ca0106_proc.o ca0106_mixer.o snd-ca0106-objs := ca0106_main.o ca0106_proc.o ca0106_mixer.o ca_midi.o
obj-$(CONFIG_SND_CA0106) += snd-ca0106.o obj-$(CONFIG_SND_CA0106) += snd-ca0106.o

View File

@ -399,10 +399,24 @@
#define PLAYBACK_VOLUME2 0x6a /* Playback Analog volume per channel. Does not effect AC3 output */ #define PLAYBACK_VOLUME2 0x6a /* Playback Analog volume per channel. Does not effect AC3 output */
/* Similar to register 0x66, except that the destination is the I2S mixer instead of the SPDIF mixer. I.E. Outputs to the Analog outputs instead of SPDIF. */ /* Similar to register 0x66, except that the destination is the I2S mixer instead of the SPDIF mixer. I.E. Outputs to the Analog outputs instead of SPDIF. */
#define UNKNOWN6b 0x6b /* Unknown. Readonly. Default 00400000 00400000 00400000 00400000 */ #define UNKNOWN6b 0x6b /* Unknown. Readonly. Default 00400000 00400000 00400000 00400000 */
#define UART_A_DATA 0x6c /* Uart, used in setting sample rates, bits per sample etc. */ #define MIDI_UART_A_DATA 0x6c /* Midi Uart A Data */
#define UART_A_CMD 0x6d /* Uart, used in setting sample rates, bits per sample etc. */ #define MIDI_UART_A_CMD 0x6d /* Midi Uart A Command/Status */
#define UART_B_DATA 0x6e /* Uart, Unknown. */ #define MIDI_UART_B_DATA 0x6e /* Midi Uart B Data (currently unused) */
#define UART_B_CMD 0x6f /* Uart, Unknown. */ #define MIDI_UART_B_CMD 0x6f /* Midi Uart B Command/Status (currently unused) */
/* unique channel identifier for midi->channel */
#define CA0106_MIDI_CHAN_A 0x1
#define CA0106_MIDI_CHAN_B 0x2
/* from mpu401 */
#define CA0106_MIDI_INPUT_AVAIL 0x80
#define CA0106_MIDI_OUTPUT_READY 0x40
#define CA0106_MPU401_RESET 0xff
#define CA0106_MPU401_ENTER_UART 0x3f
#define CA0106_MPU401_ACK 0xfe
#define SAMPLE_RATE_TRACKER_STATUS 0x70 /* Readonly. Default 00108000 00108000 00500000 00500000 */ #define SAMPLE_RATE_TRACKER_STATUS 0x70 /* Readonly. Default 00108000 00108000 00500000 00500000 */
/* Estimated sample rate [19:0] Relative to 48kHz. 0x8000 = 1.0 /* Estimated sample rate [19:0] Relative to 48kHz. 0x8000 = 1.0
* Rate Locked [20] * Rate Locked [20]
@ -538,6 +552,8 @@
#define CONTROL_CENTER_LFE_CHANNEL 1 #define CONTROL_CENTER_LFE_CHANNEL 1
#define CONTROL_UNKNOWN_CHANNEL 2 #define CONTROL_UNKNOWN_CHANNEL 2
#include "ca_midi.h"
typedef struct snd_ca0106_channel ca0106_channel_t; typedef struct snd_ca0106_channel ca0106_channel_t;
typedef struct snd_ca0106 ca0106_t; typedef struct snd_ca0106 ca0106_t;
typedef struct snd_ca0106_pcm ca0106_pcm_t; typedef struct snd_ca0106_pcm ca0106_pcm_t;
@ -592,6 +608,9 @@ struct snd_ca0106 {
int capture_mic_line_in; int capture_mic_line_in;
struct snd_dma_buffer buffer; struct snd_dma_buffer buffer;
ca_midi_t midi;
ca_midi_t midi2;
}; };
int __devinit snd_ca0106_mixer(ca0106_t *emu); int __devinit snd_ca0106_mixer(ca0106_t *emu);

Some files were not shown because too many files have changed in this diff Show More