Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
L
linux
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Kirill Smelkov
linux
Commits
6176fadc
Commit
6176fadc
authored
Feb 23, 2015
by
Takashi Iwai
Browse files
Options
Browse Files
Download
Plain Diff
Merge branch 'topic/seq-cleanup' into for-next
parents
66c21c5a
54a721ab
Changes
12
Show whitespace changes
Inline
Side-by-side
Showing
12 changed files
with
256 additions
and
576 deletions
+256
-576
include/sound/seq_device.h
include/sound/seq_device.h
+29
-17
include/sound/seq_kernel.h
include/sound/seq_kernel.h
+1
-5
sound/core/seq/oss/seq_oss.c
sound/core/seq/oss/seq_oss.c
+13
-9
sound/core/seq/oss/seq_oss_synth.c
sound/core/seq/oss/seq_oss_synth.c
+4
-2
sound/core/seq/oss/seq_oss_synth.h
sound/core/seq/oss/seq_oss_synth.h
+2
-2
sound/core/seq/seq_device.c
sound/core/seq/seq_device.c
+134
-435
sound/core/seq/seq_dummy.c
sound/core/seq/seq_dummy.c
+1
-5
sound/core/seq/seq_midi.c
sound/core/seq/seq_midi.c
+14
-22
sound/drivers/opl3/opl3_seq.c
sound/drivers/opl3/opl3_seq.c
+14
-20
sound/drivers/opl4/opl4_seq.c
sound/drivers/opl4/opl4_seq.c
+14
-19
sound/isa/sb/emu8000_synth.c
sound/isa/sb/emu8000_synth.c
+15
-20
sound/pci/emu10k1/emu10k1_synth.c
sound/pci/emu10k1/emu10k1_synth.c
+15
-20
No files found.
include/sound/seq_device.h
View file @
6176fadc
...
...
@@ -25,29 +25,26 @@
* registered device information
*/
#define ID_LEN 32
/* status flag */
#define SNDRV_SEQ_DEVICE_FREE 0
#define SNDRV_SEQ_DEVICE_REGISTERED 1
struct
snd_seq_device
{
/* device info */
struct
snd_card
*
card
;
/* sound card */
int
device
;
/* device number */
c
har
id
[
ID_LEN
];
/* driver id */
c
onst
char
*
id
;
/* driver id */
char
name
[
80
];
/* device name */
int
argsize
;
/* size of the argument */
void
*
driver_data
;
/* private data for driver */
int
status
;
/* flag - read only */
void
*
private_data
;
/* private data for the caller */
void
(
*
private_free
)(
struct
snd_seq_device
*
device
);
struct
list_head
list
;
/* link to next device */
struct
device
dev
;
};
#define to_seq_dev(_dev) \
container_of(_dev, struct snd_seq_device, dev)
/* sequencer driver */
/* driver operators
*
init_devic
e:
*
prob
e:
* Initialize the device with given parameters.
* Typically,
* 1. call snd_hwdep_new
...
...
@@ -55,25 +52,40 @@ struct snd_seq_device {
* 3. call snd_hwdep_register
* 4. store the instance to dev->driver_data pointer.
*
*
free_devic
e:
*
remov
e:
* Release the private data.
* Typically, call snd_device_free(dev->card, dev->driver_data)
*/
struct
snd_seq_dev_ops
{
int
(
*
init_device
)(
struct
snd_seq_device
*
dev
);
int
(
*
free_device
)(
struct
snd_seq_device
*
dev
);
struct
snd_seq_driver
{
struct
device_driver
driver
;
char
*
id
;
int
argsize
;
};
#define to_seq_drv(_drv) \
container_of(_drv, struct snd_seq_driver, driver)
/*
* prototypes
*/
#ifdef CONFIG_MODULES
void
snd_seq_device_load_drivers
(
void
);
int
snd_seq_device_new
(
struct
snd_card
*
card
,
int
device
,
char
*
id
,
int
argsize
,
struct
snd_seq_device
**
result
);
int
snd_seq_device_register_driver
(
char
*
id
,
struct
snd_seq_dev_ops
*
entry
,
int
argsize
);
int
snd_seq_device_unregister_driver
(
char
*
id
);
#else
#define snd_seq_device_load_drivers()
#endif
int
snd_seq_device_new
(
struct
snd_card
*
card
,
int
device
,
const
char
*
id
,
int
argsize
,
struct
snd_seq_device
**
result
);
#define SNDRV_SEQ_DEVICE_ARGPTR(dev) (void *)((char *)(dev) + sizeof(struct snd_seq_device))
int
__must_check
__snd_seq_driver_register
(
struct
snd_seq_driver
*
drv
,
struct
module
*
mod
);
#define snd_seq_driver_register(drv) \
__snd_seq_driver_register(drv, THIS_MODULE)
void
snd_seq_driver_unregister
(
struct
snd_seq_driver
*
drv
);
#define module_snd_seq_driver(drv) \
module_driver(drv, snd_seq_driver_register, snd_seq_driver_unregister)
/*
* id strings for generic devices
...
...
include/sound/seq_kernel.h
View file @
6176fadc
...
...
@@ -99,13 +99,9 @@ int snd_seq_event_port_attach(int client, struct snd_seq_port_callback *pcbp,
int
snd_seq_event_port_detach
(
int
client
,
int
port
);
#ifdef CONFIG_MODULES
void
snd_seq_autoload_lock
(
void
);
void
snd_seq_autoload_unlock
(
void
);
void
snd_seq_autoload_init
(
void
);
#define snd_seq_autoload_exit() snd_seq_autoload_lock()
void
snd_seq_autoload_exit
(
void
);
#else
#define snd_seq_autoload_lock()
#define snd_seq_autoload_unlock()
#define snd_seq_autoload_init()
#define snd_seq_autoload_exit()
#endif
...
...
sound/core/seq/oss/seq_oss.c
View file @
6176fadc
...
...
@@ -65,15 +65,20 @@ static unsigned int odev_poll(struct file *file, poll_table * wait);
* module interface
*/
static
struct
snd_seq_driver
seq_oss_synth_driver
=
{
.
driver
=
{
.
name
=
KBUILD_MODNAME
,
.
probe
=
snd_seq_oss_synth_probe
,
.
remove
=
snd_seq_oss_synth_remove
,
},
.
id
=
SNDRV_SEQ_DEV_ID_OSS
,
.
argsize
=
sizeof
(
struct
snd_seq_oss_reg
),
};
static
int
__init
alsa_seq_oss_init
(
void
)
{
int
rc
;
static
struct
snd_seq_dev_ops
ops
=
{
snd_seq_oss_synth_register
,
snd_seq_oss_synth_unregister
,
};
snd_seq_autoload_lock
();
if
((
rc
=
register_device
())
<
0
)
goto
error
;
if
((
rc
=
register_proc
())
<
0
)
{
...
...
@@ -86,8 +91,8 @@ static int __init alsa_seq_oss_init(void)
goto
error
;
}
if
((
rc
=
snd_seq_device_register_driver
(
SNDRV_SEQ_DEV_ID_OSS
,
&
ops
,
sizeof
(
struct
snd_seq_oss_reg
)))
<
0
)
{
rc
=
snd_seq_driver_register
(
&
seq_oss_synth_driver
);
if
(
rc
<
0
)
{
snd_seq_oss_delete_client
();
unregister_proc
();
unregister_device
();
...
...
@@ -98,13 +103,12 @@ static int __init alsa_seq_oss_init(void)
snd_seq_oss_synth_init
();
error:
snd_seq_autoload_unlock
();
return
rc
;
}
static
void
__exit
alsa_seq_oss_exit
(
void
)
{
snd_seq_d
evice_unregister_driver
(
SNDRV_SEQ_DEV_ID_OSS
);
snd_seq_d
river_unregister
(
&
seq_oss_synth_driver
);
snd_seq_oss_delete_client
();
unregister_proc
();
unregister_device
();
...
...
sound/core/seq/oss/seq_oss_synth.c
View file @
6176fadc
...
...
@@ -98,8 +98,9 @@ snd_seq_oss_synth_init(void)
* registration of the synth device
*/
int
snd_seq_oss_synth_
register
(
struct
snd_seq_device
*
dev
)
snd_seq_oss_synth_
probe
(
struct
device
*
_
dev
)
{
struct
snd_seq_device
*
dev
=
to_seq_dev
(
_dev
);
int
i
;
struct
seq_oss_synth
*
rec
;
struct
snd_seq_oss_reg
*
reg
=
SNDRV_SEQ_DEVICE_ARGPTR
(
dev
);
...
...
@@ -149,8 +150,9 @@ snd_seq_oss_synth_register(struct snd_seq_device *dev)
int
snd_seq_oss_synth_
unregister
(
struct
snd_seq_device
*
dev
)
snd_seq_oss_synth_
remove
(
struct
device
*
_
dev
)
{
struct
snd_seq_device
*
dev
=
to_seq_dev
(
_dev
);
int
index
;
struct
seq_oss_synth
*
rec
=
dev
->
driver_data
;
unsigned
long
flags
;
...
...
sound/core/seq/oss/seq_oss_synth.h
View file @
6176fadc
...
...
@@ -28,8 +28,8 @@
#include <sound/seq_device.h>
void
snd_seq_oss_synth_init
(
void
);
int
snd_seq_oss_synth_
register
(
struct
snd_seq_
device
*
dev
);
int
snd_seq_oss_synth_
unregister
(
struct
snd_seq_
device
*
dev
);
int
snd_seq_oss_synth_
probe
(
struct
device
*
dev
);
int
snd_seq_oss_synth_
remove
(
struct
device
*
dev
);
void
snd_seq_oss_synth_setup
(
struct
seq_oss_devinfo
*
dp
);
void
snd_seq_oss_synth_setup_midi
(
struct
seq_oss_devinfo
*
dp
);
void
snd_seq_oss_synth_cleanup
(
struct
seq_oss_devinfo
*
dp
);
...
...
sound/core/seq/seq_device.c
View file @
6176fadc
...
...
@@ -36,6 +36,7 @@
*
*/
#include <linux/device.h>
#include <linux/init.h>
#include <linux/module.h>
#include <sound/core.h>
...
...
@@ -51,74 +52,44 @@ MODULE_AUTHOR("Takashi Iwai <tiwai@suse.de>");
MODULE_DESCRIPTION
(
"ALSA sequencer device management"
);
MODULE_LICENSE
(
"GPL"
);
/* driver state */
#define DRIVER_EMPTY 0
#define DRIVER_LOADED (1<<0)
#define DRIVER_REQUESTED (1<<1)
#define DRIVER_LOCKED (1<<2)
#define DRIVER_REQUESTING (1<<3)
struct
ops_list
{
char
id
[
ID_LEN
];
/* driver id */
int
driver
;
/* driver state */
int
used
;
/* reference counter */
int
argsize
;
/* argument size */
/* operators */
struct
snd_seq_dev_ops
ops
;
/* registered devices */
struct
list_head
dev_list
;
/* list of devices */
int
num_devices
;
/* number of associated devices */
int
num_init_devices
;
/* number of initialized devices */
struct
mutex
reg_mutex
;
struct
list_head
list
;
/* next driver */
};
/*
* bus definition
*/
static
int
snd_seq_bus_match
(
struct
device
*
dev
,
struct
device_driver
*
drv
)
{
struct
snd_seq_device
*
sdev
=
to_seq_dev
(
dev
);
struct
snd_seq_driver
*
sdrv
=
to_seq_drv
(
drv
);
return
strcmp
(
sdrv
->
id
,
sdev
->
id
)
==
0
&&
sdrv
->
argsize
==
sdev
->
argsize
;
}
static
LIST_HEAD
(
opslist
);
static
int
num_ops
;
static
DEFINE_MUTEX
(
ops_mutex
);
#ifdef CONFIG_PROC_FS
static
struct
snd_info_entry
*
info_entry
;
#endif
static
struct
bus_type
snd_seq_bus_type
=
{
.
name
=
"snd_seq"
,
.
match
=
snd_seq_bus_match
,
};
/*
* pro
totypes
* pro
c interface -- just for compatibility
*/
static
int
snd_seq_device_free
(
struct
snd_seq_device
*
dev
);
static
int
snd_seq_device_dev_free
(
struct
snd_device
*
device
);
static
int
snd_seq_device_dev_register
(
struct
snd_device
*
device
);
static
int
snd_seq_device_dev_disconnect
(
struct
snd_device
*
device
);
static
int
init_device
(
struct
snd_seq_device
*
dev
,
struct
ops_list
*
ops
);
static
int
free_device
(
struct
snd_seq_device
*
dev
,
struct
ops_list
*
ops
);
static
struct
ops_list
*
find_driver
(
char
*
id
,
int
create_if_empty
);
static
struct
ops_list
*
create_driver
(
char
*
id
);
static
void
unlock_driver
(
struct
ops_list
*
ops
);
static
void
remove_drivers
(
void
);
#ifdef CONFIG_PROC_FS
static
struct
snd_info_entry
*
info_entry
;
/*
* show all drivers and their status
*/
static
int
print_dev_info
(
struct
device
*
dev
,
void
*
data
)
{
struct
snd_seq_device
*
sdev
=
to_seq_dev
(
dev
);
struct
snd_info_buffer
*
buffer
=
data
;
snd_iprintf
(
buffer
,
"snd-%s,%s,%d
\n
"
,
sdev
->
id
,
dev
->
driver
?
"loaded"
:
"empty"
,
dev
->
driver
?
1
:
0
);
return
0
;
}
#ifdef CONFIG_PROC_FS
static
void
snd_seq_device_info
(
struct
snd_info_entry
*
entry
,
struct
snd_info_buffer
*
buffer
)
{
struct
ops_list
*
ops
;
mutex_lock
(
&
ops_mutex
);
list_for_each_entry
(
ops
,
&
opslist
,
list
)
{
snd_iprintf
(
buffer
,
"snd-%s%s%s%s,%d
\n
"
,
ops
->
id
,
ops
->
driver
&
DRIVER_LOADED
?
",loaded"
:
(
ops
->
driver
==
DRIVER_EMPTY
?
",empty"
:
""
),
ops
->
driver
&
DRIVER_REQUESTED
?
",requested"
:
""
,
ops
->
driver
&
DRIVER_LOCKED
?
",locked"
:
""
,
ops
->
num_devices
);
}
mutex_unlock
(
&
ops_mutex
);
bus_for_each_dev
(
&
snd_seq_bus_type
,
NULL
,
buffer
,
print_dev_info
);
}
#endif
...
...
@@ -127,64 +98,32 @@ static void snd_seq_device_info(struct snd_info_entry *entry,
*/
#ifdef CONFIG_MODULES
/*
avoid auto-loading during module_init()
*/
/*
flag to block auto-loading
*/
static
atomic_t
snd_seq_in_init
=
ATOMIC_INIT
(
1
);
/* blocked as default */
void
snd_seq_autoload_lock
(
void
)
{
atomic_inc
(
&
snd_seq_in_init
);
}
void
snd_seq_autoload_unlock
(
void
)
static
int
request_seq_drv
(
struct
device
*
dev
,
void
*
data
)
{
atomic_dec
(
&
snd_seq_in_init
);
struct
snd_seq_device
*
sdev
=
to_seq_dev
(
dev
);
if
(
!
dev
->
driver
)
request_module
(
"snd-%s"
,
sdev
->
id
);
return
0
;
}
static
void
autoload_drivers
(
void
)
static
void
autoload_drivers
(
struct
work_struct
*
work
)
{
/* avoid reentrance */
if
(
atomic_inc_return
(
&
snd_seq_in_init
)
==
1
)
{
struct
ops_list
*
ops
;
mutex_lock
(
&
ops_mutex
);
list_for_each_entry
(
ops
,
&
opslist
,
list
)
{
if
((
ops
->
driver
&
DRIVER_REQUESTING
)
&&
!
(
ops
->
driver
&
DRIVER_REQUESTED
))
{
ops
->
used
++
;
mutex_unlock
(
&
ops_mutex
);
ops
->
driver
|=
DRIVER_REQUESTED
;
request_module
(
"snd-%s"
,
ops
->
id
);
mutex_lock
(
&
ops_mutex
);
ops
->
used
--
;
}
}
mutex_unlock
(
&
ops_mutex
);
}
if
(
atomic_inc_return
(
&
snd_seq_in_init
)
==
1
)
bus_for_each_dev
(
&
snd_seq_bus_type
,
NULL
,
NULL
,
request_seq_drv
);
atomic_dec
(
&
snd_seq_in_init
);
}
static
void
call_autoload
(
struct
work_struct
*
work
)
{
autoload_drivers
();
}
static
DECLARE_WORK
(
autoload_work
,
call_autoload
);
static
void
try_autoload
(
struct
ops_list
*
ops
)
{
if
(
!
ops
->
driver
)
{
ops
->
driver
|=
DRIVER_REQUESTING
;
schedule_work
(
&
autoload_work
);
}
}
static
DECLARE_WORK
(
autoload_work
,
autoload_drivers
);
static
void
queue_autoload_drivers
(
void
)
{
struct
ops_list
*
ops
;
mutex_lock
(
&
ops_mutex
);
list_for_each_entry
(
ops
,
&
opslist
,
list
)
try_autoload
(
ops
);
mutex_unlock
(
&
ops_mutex
);
schedule_work
(
&
autoload_work
);
}
void
snd_seq_autoload_init
(
void
)
...
...
@@ -195,384 +134,143 @@ void snd_seq_autoload_init(void)
queue_autoload_drivers
();
#endif
}
#else
#define try_autoload(ops)
/* NOP */
#endif
EXPORT_SYMBOL
(
snd_seq_autoload_init
);
void
snd_seq_
device_load_drivers
(
void
)
void
snd_seq_
autoload_exit
(
void
)
{
#ifdef CONFIG_MODULES
queue_autoload_drivers
();
flush_work
(
&
autoload_work
);
#endif
atomic_inc
(
&
snd_seq_in_init
);
}
EXPORT_SYMBOL
(
snd_seq_autoload_exit
);
/*
* register a sequencer device
* card = card info
* device = device number (if any)
* id = id of driver
* result = return pointer (NULL allowed if unnecessary)
*/
int
snd_seq_device_new
(
struct
snd_card
*
card
,
int
device
,
char
*
id
,
int
argsize
,
struct
snd_seq_device
**
result
)
void
snd_seq_device_load_drivers
(
void
)
{
struct
snd_seq_device
*
dev
;
struct
ops_list
*
ops
;
int
err
;
static
struct
snd_device_ops
dops
=
{
.
dev_free
=
snd_seq_device_dev_free
,
.
dev_register
=
snd_seq_device_dev_register
,
.
dev_disconnect
=
snd_seq_device_dev_disconnect
,
};
if
(
result
)
*
result
=
NULL
;
if
(
snd_BUG_ON
(
!
id
))
return
-
EINVAL
;
ops
=
find_driver
(
id
,
1
);
if
(
ops
==
NULL
)
return
-
ENOMEM
;
dev
=
kzalloc
(
sizeof
(
*
dev
)
*
2
+
argsize
,
GFP_KERNEL
);
if
(
dev
==
NULL
)
{
unlock_driver
(
ops
);
return
-
ENOMEM
;
}
/* set up device info */
dev
->
card
=
card
;
dev
->
device
=
device
;
strlcpy
(
dev
->
id
,
id
,
sizeof
(
dev
->
id
));
dev
->
argsize
=
argsize
;
dev
->
status
=
SNDRV_SEQ_DEVICE_FREE
;
/* add this device to the list */
mutex_lock
(
&
ops
->
reg_mutex
);
list_add_tail
(
&
dev
->
list
,
&
ops
->
dev_list
);
ops
->
num_devices
++
;
mutex_unlock
(
&
ops
->
reg_mutex
);
if
((
err
=
snd_device_new
(
card
,
SNDRV_DEV_SEQUENCER
,
dev
,
&
dops
))
<
0
)
{
snd_seq_device_free
(
dev
);
return
err
;
}
try_autoload
(
ops
);
unlock_driver
(
ops
);
if
(
result
)
*
result
=
dev
;
return
0
;
queue_autoload_drivers
();
flush_work
(
&
autoload_work
);
}
EXPORT_SYMBOL
(
snd_seq_device_load_drivers
);
#else
#define queue_autoload_drivers()
/* NOP */
#endif
/*
*
free the existing device
*
device management
*/
static
int
snd_seq_device_free
(
struct
snd_seq_device
*
dev
)
{
struct
ops_list
*
ops
;
if
(
snd_BUG_ON
(
!
dev
))
return
-
EINVAL
;
ops
=
find_driver
(
dev
->
id
,
0
);
if
(
ops
==
NULL
)
return
-
ENXIO
;
/* remove the device from the list */
mutex_lock
(
&
ops
->
reg_mutex
);
list_del
(
&
dev
->
list
);
ops
->
num_devices
--
;
mutex_unlock
(
&
ops
->
reg_mutex
);
free_device
(
dev
,
ops
);
if
(
dev
->
private_free
)
dev
->
private_free
(
dev
);
kfree
(
dev
);
unlock_driver
(
ops
);
return
0
;
}
static
int
snd_seq_device_dev_free
(
struct
snd_device
*
device
)
{
struct
snd_seq_device
*
dev
=
device
->
device_data
;
return
snd_seq_device_free
(
dev
);
put_device
(
&
dev
->
dev
);
return
0
;
}
/*
* register the device
*/
static
int
snd_seq_device_dev_register
(
struct
snd_device
*
device
)
{
struct
snd_seq_device
*
dev
=
device
->
device_data
;
struct
ops_list
*
ops
;
ops
=
find_driver
(
dev
->
id
,
0
);
if
(
ops
==
NULL
)
return
-
ENOENT
;
/* initialize this device if the corresponding driver was
* already loaded
*/
if
(
ops
->
driver
&
DRIVER_LOADED
)
init_device
(
dev
,
ops
);
int
err
;
unlock_driver
(
ops
);
err
=
device_add
(
&
dev
->
dev
);
if
(
err
<
0
)
return
err
;
if
(
!
dev
->
dev
.
driver
)
queue_autoload_drivers
();
return
0
;
}
/*
* disconnect the device
*/
static
int
snd_seq_device_dev_disconnect
(
struct
snd_device
*
device
)
{
struct
snd_seq_device
*
dev
=
device
->
device_data
;
struct
ops_list
*
ops
;
ops
=
find_driver
(
dev
->
id
,
0
);
if
(
ops
==
NULL
)
return
-
ENOENT
;
free_device
(
dev
,
ops
);
unlock_driver
(
ops
);
device_del
(
&
dev
->
dev
);
return
0
;
}
/*
* register device driver
* id = driver id
* entry = driver operators - duplicated to each instance
*/
int
snd_seq_device_register_driver
(
char
*
id
,
struct
snd_seq_dev_ops
*
entry
,
int
argsize
)
static
void
snd_seq_dev_release
(
struct
device
*
dev
)
{
struct
ops_list
*
ops
;
struct
snd_seq_device
*
dev
;
if
(
id
==
NULL
||
entry
==
NULL
||
entry
->
init_device
==
NULL
||
entry
->
free_device
==
NULL
)
return
-
EINVAL
;
ops
=
find_driver
(
id
,
1
);
if
(
ops
==
NULL
)
return
-
ENOMEM
;
if
(
ops
->
driver
&
DRIVER_LOADED
)
{
pr_warn
(
"ALSA: seq: driver_register: driver '%s' already exists
\n
"
,
id
);
unlock_driver
(
ops
);
return
-
EBUSY
;
}
struct
snd_seq_device
*
sdev
=
to_seq_dev
(
dev
);
mutex_lock
(
&
ops
->
reg_mutex
);
/* copy driver operators */
ops
->
ops
=
*
entry
;
ops
->
driver
|=
DRIVER_LOADED
;
ops
->
argsize
=
argsize
;
/* initialize existing devices if necessary */
list_for_each_entry
(
dev
,
&
ops
->
dev_list
,
list
)
{
init_device
(
dev
,
ops
);
}
mutex_unlock
(
&
ops
->
reg_mutex
);
unlock_driver
(
ops
);
return
0
;
if
(
sdev
->
private_free
)
sdev
->
private_free
(
sdev
);
kfree
(
sdev
);
}
/*
* create driver record
*/
static
struct
ops_list
*
create_driver
(
char
*
id
)
{
struct
ops_list
*
ops
;
ops
=
kzalloc
(
sizeof
(
*
ops
),
GFP_KERNEL
);
if
(
ops
==
NULL
)
return
ops
;
/* set up driver entry */
strlcpy
(
ops
->
id
,
id
,
sizeof
(
ops
->
id
));
mutex_init
(
&
ops
->
reg_mutex
);
/*
* The ->reg_mutex locking rules are per-driver, so we create
* separate per-driver lock classes:
*/
lockdep_set_class
(
&
ops
->
reg_mutex
,
(
struct
lock_class_key
*
)
id
);
ops
->
driver
=
DRIVER_EMPTY
;
INIT_LIST_HEAD
(
&
ops
->
dev_list
);
/* lock this instance */
ops
->
used
=
1
;
/* register driver entry */
mutex_lock
(
&
ops_mutex
);
list_add_tail
(
&
ops
->
list
,
&
opslist
);
num_ops
++
;
mutex_unlock
(
&
ops_mutex
);
return
ops
;
}
/*
* unregister the specified driver
* register a sequencer device
* card = card info
* device = device number (if any)
* id = id of driver
* result = return pointer (NULL allowed if unnecessary)
*/
int
snd_seq_device_unregister_driver
(
char
*
id
)
int
snd_seq_device_new
(
struct
snd_card
*
card
,
int
device
,
const
char
*
id
,
int
argsize
,
struct
snd_seq_device
**
result
)
{
struct
ops_list
*
ops
;
struct
snd_seq_device
*
dev
;
int
err
;
static
struct
snd_device_ops
dops
=
{
.
dev_free
=
snd_seq_device_dev_free
,
.
dev_register
=
snd_seq_device_dev_register
,
.
dev_disconnect
=
snd_seq_device_dev_disconnect
,
};
ops
=
find_driver
(
id
,
0
);
if
(
ops
==
NULL
)
return
-
ENXIO
;
if
(
!
(
ops
->
driver
&
DRIVER_LOADED
)
||
(
ops
->
driver
&
DRIVER_LOCKED
))
{
pr_err
(
"ALSA: seq: driver_unregister: cannot unload driver '%s': status=%x
\n
"
,
id
,
ops
->
driver
);
unlock_driver
(
ops
);
return
-
EBUSY
;
}
/* close and release all devices associated with this driver */
mutex_lock
(
&
ops
->
reg_mutex
);
ops
->
driver
|=
DRIVER_LOCKED
;
/* do not remove this driver recursively */
list_for_each_entry
(
dev
,
&
ops
->
dev_list
,
list
)
{
free_device
(
dev
,
ops
);
}
ops
->
driver
=
0
;
if
(
ops
->
num_init_devices
>
0
)
pr_err
(
"ALSA: seq: free_driver: init_devices > 0!! (%d)
\n
"
,
ops
->
num_init_devices
);
mutex_unlock
(
&
ops
->
reg_mutex
);
if
(
result
)
*
result
=
NULL
;
unlock_driver
(
ops
);
if
(
snd_BUG_ON
(
!
id
))
return
-
EINVAL
;
/* remove empty driver entries */
remove_drivers
();
dev
=
kzalloc
(
sizeof
(
*
dev
)
+
argsize
,
GFP_KERNEL
);
if
(
!
dev
)
return
-
ENOMEM
;
return
0
;
}
/* set up device info */
dev
->
card
=
card
;
dev
->
device
=
device
;
dev
->
id
=
id
;
dev
->
argsize
=
argsize
;
device_initialize
(
&
dev
->
dev
);
dev
->
dev
.
parent
=
&
card
->
card_dev
;
dev
->
dev
.
bus
=
&
snd_seq_bus_type
;
dev
->
dev
.
release
=
snd_seq_dev_release
;
dev_set_name
(
&
dev
->
dev
,
"%s-%d-%d"
,
dev
->
id
,
card
->
number
,
device
);
/*
* remove empty driver entries
*/
static
void
remove_drivers
(
void
)
{
struct
list_head
*
head
;
mutex_lock
(
&
ops_mutex
);
head
=
opslist
.
next
;
while
(
head
!=
&
opslist
)
{
struct
ops_list
*
ops
=
list_entry
(
head
,
struct
ops_list
,
list
);
if
(
!
(
ops
->
driver
&
DRIVER_LOADED
)
&&
ops
->
used
==
0
&&
ops
->
num_devices
==
0
)
{
head
=
head
->
next
;
list_del
(
&
ops
->
list
);
kfree
(
ops
);
num_ops
--
;
}
else
head
=
head
->
next
;
/* add this device to the list */
err
=
snd_device_new
(
card
,
SNDRV_DEV_SEQUENCER
,
dev
,
&
dops
);
if
(
err
<
0
)
{
put_device
(
&
dev
->
dev
);
return
err
;
}
mutex_unlock
(
&
ops_mutex
);
}
/*
* initialize the device - call init_device operator
*/
static
int
init_device
(
struct
snd_seq_device
*
dev
,
struct
ops_list
*
ops
)
{
if
(
!
(
ops
->
driver
&
DRIVER_LOADED
))
return
0
;
/* driver is not loaded yet */
if
(
dev
->
status
!=
SNDRV_SEQ_DEVICE_FREE
)
return
0
;
/* already initialized */
if
(
ops
->
argsize
!=
dev
->
argsize
)
{
pr_err
(
"ALSA: seq: incompatible device '%s' for plug-in '%s' (%d %d)
\n
"
,
dev
->
name
,
ops
->
id
,
ops
->
argsize
,
dev
->
argsize
);
return
-
EINVAL
;
}
if
(
ops
->
ops
.
init_device
(
dev
)
>=
0
)
{
dev
->
status
=
SNDRV_SEQ_DEVICE_REGISTERED
;
ops
->
num_init_devices
++
;
}
else
{
pr_err
(
"ALSA: seq: init_device failed: %s: %s
\n
"
,
dev
->
name
,
dev
->
id
);
}
if
(
result
)
*
result
=
dev
;
return
0
;
}
EXPORT_SYMBOL
(
snd_seq_device_new
);
/*
*
release the device - call free_device operator
*
driver registration
*/
static
int
free_device
(
struct
snd_seq_device
*
dev
,
struct
ops_list
*
ops
)
int
__snd_seq_driver_register
(
struct
snd_seq_driver
*
drv
,
struct
module
*
mod
)
{
int
result
;
if
(
!
(
ops
->
driver
&
DRIVER_LOADED
))
return
0
;
/* driver is not loaded yet */
if
(
dev
->
status
!=
SNDRV_SEQ_DEVICE_REGISTERED
)
return
0
;
/* not registered */
if
(
ops
->
argsize
!=
dev
->
argsize
)
{
pr_err
(
"ALSA: seq: incompatible device '%s' for plug-in '%s' (%d %d)
\n
"
,
dev
->
name
,
ops
->
id
,
ops
->
argsize
,
dev
->
argsize
);
if
(
WARN_ON
(
!
drv
->
driver
.
name
||
!
drv
->
id
))
return
-
EINVAL
;
}
if
((
result
=
ops
->
ops
.
free_device
(
dev
))
>=
0
||
result
==
-
ENXIO
)
{
dev
->
status
=
SNDRV_SEQ_DEVICE_FREE
;
dev
->
driver_data
=
NULL
;
ops
->
num_init_devices
--
;
}
else
{
pr_err
(
"ALSA: seq: free_device failed: %s: %s
\n
"
,
dev
->
name
,
dev
->
id
);
}
return
0
;
drv
->
driver
.
bus
=
&
snd_seq_bus_type
;
drv
->
driver
.
owner
=
mod
;
return
driver_register
(
&
drv
->
driver
);
}
EXPORT_SYMBOL_GPL
(
__snd_seq_driver_register
);
/*
* find the matching driver with given id
*/
static
struct
ops_list
*
find_driver
(
char
*
id
,
int
create_if_empty
)
void
snd_seq_driver_unregister
(
struct
snd_seq_driver
*
drv
)
{
struct
ops_list
*
ops
;
mutex_lock
(
&
ops_mutex
);
list_for_each_entry
(
ops
,
&
opslist
,
list
)
{
if
(
strcmp
(
ops
->
id
,
id
)
==
0
)
{
ops
->
used
++
;
mutex_unlock
(
&
ops_mutex
);
return
ops
;
}
}
mutex_unlock
(
&
ops_mutex
);
if
(
create_if_empty
)
return
create_driver
(
id
);
return
NULL
;
driver_unregister
(
&
drv
->
driver
);
}
static
void
unlock_driver
(
struct
ops_list
*
ops
)
{
mutex_lock
(
&
ops_mutex
);
ops
->
used
--
;
mutex_unlock
(
&
ops_mutex
);
}
EXPORT_SYMBOL_GPL
(
snd_seq_driver_unregister
);
/*
* module part
*/
static
int
__init
alsa_seq_device
_init
(
void
)
static
int
__init
seq_dev_proc
_init
(
void
)
{
#ifdef CONFIG_PROC_FS
info_entry
=
snd_info_create_module_entry
(
THIS_MODULE
,
"drivers"
,
...
...
@@ -589,28 +287,29 @@ static int __init alsa_seq_device_init(void)
return
0
;
}
static
int
__init
alsa_seq_device_init
(
void
)
{
int
err
;
err
=
bus_register
(
&
snd_seq_bus_type
);
if
(
err
<
0
)
return
err
;
err
=
seq_dev_proc_init
();
if
(
err
<
0
)
bus_unregister
(
&
snd_seq_bus_type
);
return
err
;
}
static
void
__exit
alsa_seq_device_exit
(
void
)
{
#ifdef CONFIG_MODULES
cancel_work_sync
(
&
autoload_work
);
#endif
remove_drivers
();
#ifdef CONFIG_PROC_FS
snd_info_free_entry
(
info_entry
);
#endif
if
(
num_ops
)
pr_err
(
"ALSA: seq: drivers not released (%d)
\n
"
,
num_ops
);
bus_unregister
(
&
snd_seq_bus_type
);
}
module_init
(
alsa_seq_device_init
)
module_exit
(
alsa_seq_device_exit
)
EXPORT_SYMBOL
(
snd_seq_device_load_drivers
);
EXPORT_SYMBOL
(
snd_seq_device_new
);
EXPORT_SYMBOL
(
snd_seq_device_register_driver
);
EXPORT_SYMBOL
(
snd_seq_device_unregister_driver
);
#ifdef CONFIG_MODULES
EXPORT_SYMBOL
(
snd_seq_autoload_init
);
EXPORT_SYMBOL
(
snd_seq_autoload_lock
);
EXPORT_SYMBOL
(
snd_seq_autoload_unlock
);
#endif
sound/core/seq/seq_dummy.c
View file @
6176fadc
...
...
@@ -214,11 +214,7 @@ delete_client(void)
static
int
__init
alsa_seq_dummy_init
(
void
)
{
int
err
;
snd_seq_autoload_lock
();
err
=
register_client
();
snd_seq_autoload_unlock
();
return
err
;
return
register_client
();
}
static
void
__exit
alsa_seq_dummy_exit
(
void
)
...
...
sound/core/seq/seq_midi.c
View file @
6176fadc
...
...
@@ -273,8 +273,9 @@ static void snd_seq_midisynth_delete(struct seq_midisynth *msynth)
/* register new midi synth port */
static
int
snd_seq_midisynth_
register_port
(
struct
snd_seq_device
*
dev
)
snd_seq_midisynth_
probe
(
struct
device
*
_
dev
)
{
struct
snd_seq_device
*
dev
=
to_seq_dev
(
_dev
);
struct
seq_midisynth_client
*
client
;
struct
seq_midisynth
*
msynth
,
*
ms
;
struct
snd_seq_port_info
*
port
;
...
...
@@ -427,8 +428,9 @@ snd_seq_midisynth_register_port(struct snd_seq_device *dev)
/* release midi synth port */
static
int
snd_seq_midisynth_
unregister_port
(
struct
snd_seq_device
*
dev
)
snd_seq_midisynth_
remove
(
struct
device
*
_
dev
)
{
struct
snd_seq_device
*
dev
=
to_seq_dev
(
_dev
);
struct
seq_midisynth_client
*
client
;
struct
seq_midisynth
*
msynth
;
struct
snd_card
*
card
=
dev
->
card
;
...
...
@@ -457,24 +459,14 @@ snd_seq_midisynth_unregister_port(struct snd_seq_device *dev)
return
0
;
}
static
struct
snd_seq_driver
seq_midisynth_driver
=
{
.
driver
=
{
.
name
=
KBUILD_MODNAME
,
.
probe
=
snd_seq_midisynth_probe
,
.
remove
=
snd_seq_midisynth_remove
,
},
.
id
=
SNDRV_SEQ_DEV_ID_MIDISYNTH
,
.
argsize
=
0
,
};
static
int
__init
alsa_seq_midi_init
(
void
)
{
static
struct
snd_seq_dev_ops
ops
=
{
snd_seq_midisynth_register_port
,
snd_seq_midisynth_unregister_port
,
};
memset
(
&
synths
,
0
,
sizeof
(
synths
));
snd_seq_autoload_lock
();
snd_seq_device_register_driver
(
SNDRV_SEQ_DEV_ID_MIDISYNTH
,
&
ops
,
0
);
snd_seq_autoload_unlock
();
return
0
;
}
static
void
__exit
alsa_seq_midi_exit
(
void
)
{
snd_seq_device_unregister_driver
(
SNDRV_SEQ_DEV_ID_MIDISYNTH
);
}
module_init
(
alsa_seq_midi_init
)
module_exit
(
alsa_seq_midi_exit
)
module_snd_seq_driver
(
seq_midisynth_driver
);
sound/drivers/opl3/opl3_seq.c
View file @
6176fadc
...
...
@@ -216,8 +216,9 @@ static int snd_opl3_synth_create_port(struct snd_opl3 * opl3)
/* ------------------------------ */
static
int
snd_opl3_seq_
new_device
(
struct
snd_seq_device
*
dev
)
static
int
snd_opl3_seq_
probe
(
struct
device
*
_
dev
)
{
struct
snd_seq_device
*
dev
=
to_seq_dev
(
_dev
);
struct
snd_opl3
*
opl3
;
int
client
,
err
;
char
name
[
32
];
...
...
@@ -257,8 +258,9 @@ static int snd_opl3_seq_new_device(struct snd_seq_device *dev)
return
0
;
}
static
int
snd_opl3_seq_
delete_device
(
struct
snd_seq_device
*
dev
)
static
int
snd_opl3_seq_
remove
(
struct
device
*
_
dev
)
{
struct
snd_seq_device
*
dev
=
to_seq_dev
(
_dev
);
struct
snd_opl3
*
opl3
;
opl3
=
*
(
struct
snd_opl3
**
)
SNDRV_SEQ_DEVICE_ARGPTR
(
dev
);
...
...
@@ -275,22 +277,14 @@ static int snd_opl3_seq_delete_device(struct snd_seq_device *dev)
return
0
;
}
static
int
__init
alsa_opl3_seq_init
(
void
)
{
static
struct
snd_seq_dev_ops
ops
=
{
snd_opl3_seq_new_device
,
snd_opl3_seq_delete_device
};
return
snd_seq_device_register_driver
(
SNDRV_SEQ_DEV_ID_OPL3
,
&
ops
,
sizeof
(
struct
snd_opl3
*
));
}
static
void
__exit
alsa_opl3_seq_exit
(
void
)
{
snd_seq_device_unregister_driver
(
SNDRV_SEQ_DEV_ID_OPL3
);
}
static
struct
snd_seq_driver
opl3_seq_driver
=
{
.
driver
=
{
.
name
=
KBUILD_MODNAME
,
.
probe
=
snd_opl3_seq_probe
,
.
remove
=
snd_opl3_seq_remove
,
},
.
id
=
SNDRV_SEQ_DEV_ID_OPL3
,
.
argsize
=
sizeof
(
struct
snd_opl3
*
),
};
module_init
(
alsa_opl3_seq_init
)
module_exit
(
alsa_opl3_seq_exit
)
module_snd_seq_driver
(
opl3_seq_driver
);
sound/drivers/opl4/opl4_seq.c
View file @
6176fadc
...
...
@@ -124,8 +124,9 @@ static void snd_opl4_seq_free_port(void *private_data)
snd_midi_channel_free_set
(
opl4
->
chset
);
}
static
int
snd_opl4_seq_
new_device
(
struct
snd_seq_device
*
dev
)
static
int
snd_opl4_seq_
probe
(
struct
device
*
_
dev
)
{
struct
snd_seq_device
*
dev
=
to_seq_dev
(
_dev
);
struct
snd_opl4
*
opl4
;
int
client
;
struct
snd_seq_port_callback
pcallbacks
;
...
...
@@ -180,8 +181,9 @@ static int snd_opl4_seq_new_device(struct snd_seq_device *dev)
return
0
;
}
static
int
snd_opl4_seq_
delete_device
(
struct
snd_seq_device
*
dev
)
static
int
snd_opl4_seq_
remove
(
struct
device
*
_
dev
)
{
struct
snd_seq_device
*
dev
=
to_seq_dev
(
_dev
);
struct
snd_opl4
*
opl4
;
opl4
=
*
(
struct
snd_opl4
**
)
SNDRV_SEQ_DEVICE_ARGPTR
(
dev
);
...
...
@@ -195,21 +197,14 @@ static int snd_opl4_seq_delete_device(struct snd_seq_device *dev)
return
0
;
}
static
int
__init
alsa_opl4_synth_init
(
void
)
{
static
struct
snd_seq_dev_ops
ops
=
{
snd_opl4_seq_new_device
,
snd_opl4_seq_delete_device
};
return
snd_seq_device_register_driver
(
SNDRV_SEQ_DEV_ID_OPL4
,
&
ops
,
sizeof
(
struct
snd_opl4
*
));
}
static
void
__exit
alsa_opl4_synth_exit
(
void
)
{
snd_seq_device_unregister_driver
(
SNDRV_SEQ_DEV_ID_OPL4
);
}
static
struct
snd_seq_driver
opl4_seq_driver
=
{
.
driver
=
{
.
name
=
KBUILD_MODNAME
,
.
probe
=
snd_opl4_seq_probe
,
.
remove
=
snd_opl4_seq_remove
,
},
.
id
=
SNDRV_SEQ_DEV_ID_OPL4
,
.
argsize
=
sizeof
(
struct
snd_opl4
*
),
};
module_init
(
alsa_opl4_synth_init
)
module_exit
(
alsa_opl4_synth_exit
)
module_snd_seq_driver
(
opl4_seq_driver
);
sound/isa/sb/emu8000_synth.c
View file @
6176fadc
...
...
@@ -34,8 +34,9 @@ MODULE_LICENSE("GPL");
/*
* create a new hardware dependent device for Emu8000
*/
static
int
snd_emu8000_
new_device
(
struct
snd_seq_device
*
dev
)
static
int
snd_emu8000_
probe
(
struct
device
*
_
dev
)
{
struct
snd_seq_device
*
dev
=
to_seq_dev
(
_dev
);
struct
snd_emu8000
*
hw
;
struct
snd_emux
*
emu
;
...
...
@@ -93,8 +94,9 @@ static int snd_emu8000_new_device(struct snd_seq_device *dev)
/*
* free all resources
*/
static
int
snd_emu8000_
delete_device
(
struct
snd_seq_device
*
dev
)
static
int
snd_emu8000_
remove
(
struct
device
*
_
dev
)
{
struct
snd_seq_device
*
dev
=
to_seq_dev
(
_dev
);
struct
snd_emu8000
*
hw
;
if
(
dev
->
driver_data
==
NULL
)
...
...
@@ -114,21 +116,14 @@ static int snd_emu8000_delete_device(struct snd_seq_device *dev)
* INIT part
*/
static
int
__init
alsa_emu8000_init
(
void
)
{
static
struct
snd_seq_dev_ops
ops
=
{
snd_emu8000_new_device
,
snd_emu8000_delete_device
,
};
return
snd_seq_device_register_driver
(
SNDRV_SEQ_DEV_ID_EMU8000
,
&
ops
,
sizeof
(
struct
snd_emu8000
*
));
}
static
void
__exit
alsa_emu8000_exit
(
void
)
{
snd_seq_device_unregister_driver
(
SNDRV_SEQ_DEV_ID_EMU8000
);
}
module_init
(
alsa_emu8000_init
)
module_exit
(
alsa_emu8000_exit
)
static
struct
snd_seq_driver
emu8000_driver
=
{
.
driver
=
{
.
name
=
KBUILD_MODNAME
,
.
probe
=
snd_emu8000_probe
,
.
remove
=
snd_emu8000_remove
,
},
.
id
=
SNDRV_SEQ_DEV_ID_EMU8000
,
.
argsize
=
sizeof
(
struct
snd_emu8000
*
),
};
module_snd_seq_driver
(
emu8000_driver
);
sound/pci/emu10k1/emu10k1_synth.c
View file @
6176fadc
...
...
@@ -29,8 +29,9 @@ MODULE_LICENSE("GPL");
/*
* create a new hardware dependent device for Emu10k1
*/
static
int
snd_emu10k1_synth_
new_device
(
struct
snd_seq_device
*
dev
)
static
int
snd_emu10k1_synth_
probe
(
struct
device
*
_
dev
)
{
struct
snd_seq_device
*
dev
=
to_seq_dev
(
_dev
);
struct
snd_emux
*
emux
;
struct
snd_emu10k1
*
hw
;
struct
snd_emu10k1_synth_arg
*
arg
;
...
...
@@ -79,8 +80,9 @@ static int snd_emu10k1_synth_new_device(struct snd_seq_device *dev)
return
0
;
}
static
int
snd_emu10k1_synth_
delete_device
(
struct
snd_seq_device
*
dev
)
static
int
snd_emu10k1_synth_
remove
(
struct
device
*
_
dev
)
{
struct
snd_seq_device
*
dev
=
to_seq_dev
(
_dev
);
struct
snd_emux
*
emux
;
struct
snd_emu10k1
*
hw
;
unsigned
long
flags
;
...
...
@@ -104,21 +106,14 @@ static int snd_emu10k1_synth_delete_device(struct snd_seq_device *dev)
* INIT part
*/
static
int
__init
alsa_emu10k1_synth_init
(
void
)
{
static
struct
snd_seq_dev_ops
ops
=
{
snd_emu10k1_synth_new_device
,
snd_emu10k1_synth_delete_device
,
};
return
snd_seq_device_register_driver
(
SNDRV_SEQ_DEV_ID_EMU10K1_SYNTH
,
&
ops
,
sizeof
(
struct
snd_emu10k1_synth_arg
));
}
static
void
__exit
alsa_emu10k1_synth_exit
(
void
)
{
snd_seq_device_unregister_driver
(
SNDRV_SEQ_DEV_ID_EMU10K1_SYNTH
);
}
module_init
(
alsa_emu10k1_synth_init
)
module_exit
(
alsa_emu10k1_synth_exit
)
static
struct
snd_seq_driver
emu10k1_synth_driver
=
{
.
driver
=
{
.
name
=
KBUILD_MODNAME
,
.
probe
=
snd_emu10k1_synth_probe
,
.
remove
=
snd_emu10k1_synth_remove
,
},
.
id
=
SNDRV_SEQ_DEV_ID_EMU10K1_SYNTH
,
.
argsize
=
sizeof
(
struct
snd_emu10k1_synth_arg
),
};
module_snd_seq_driver
(
emu10k1_synth_driver
);
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment