diff options
Diffstat (limited to 'sound/core/pcm_native.c')
-rw-r--r-- | sound/core/pcm_native.c | 40 |
1 files changed, 27 insertions, 13 deletions
diff --git a/sound/core/pcm_native.c b/sound/core/pcm_native.c index bb40c016135e..9010306bcead 100644 --- a/sound/core/pcm_native.c +++ b/sound/core/pcm_native.c | |||
@@ -62,6 +62,7 @@ static int snd_pcm_hw_refine_old_user(struct snd_pcm_substream *substream, | |||
62 | struct snd_pcm_hw_params_old __user * _oparams); | 62 | struct snd_pcm_hw_params_old __user * _oparams); |
63 | static int snd_pcm_hw_params_old_user(struct snd_pcm_substream *substream, | 63 | static int snd_pcm_hw_params_old_user(struct snd_pcm_substream *substream, |
64 | struct snd_pcm_hw_params_old __user * _oparams); | 64 | struct snd_pcm_hw_params_old __user * _oparams); |
65 | static int snd_pcm_open(struct file *file, struct snd_pcm *pcm, int stream); | ||
65 | 66 | ||
66 | /* | 67 | /* |
67 | * | 68 | * |
@@ -1554,7 +1555,8 @@ static struct file *snd_pcm_file_fd(int fd) | |||
1554 | { | 1555 | { |
1555 | struct file *file; | 1556 | struct file *file; |
1556 | struct inode *inode; | 1557 | struct inode *inode; |
1557 | unsigned short minor; | 1558 | unsigned int minor; |
1559 | |||
1558 | file = fget(fd); | 1560 | file = fget(fd); |
1559 | if (!file) | 1561 | if (!file) |
1560 | return NULL; | 1562 | return NULL; |
@@ -1565,8 +1567,8 @@ static struct file *snd_pcm_file_fd(int fd) | |||
1565 | return NULL; | 1567 | return NULL; |
1566 | } | 1568 | } |
1567 | minor = iminor(inode); | 1569 | minor = iminor(inode); |
1568 | if (minor >= 256 || | 1570 | if (!snd_lookup_minor_data(minor, SNDRV_DEVICE_TYPE_PCM_PLAYBACK) && |
1569 | minor % SNDRV_MINOR_DEVICES < SNDRV_MINOR_PCM_PLAYBACK) { | 1571 | !snd_lookup_minor_data(minor, SNDRV_DEVICE_TYPE_PCM_CAPTURE)) { |
1570 | fput(file); | 1572 | fput(file); |
1571 | return NULL; | 1573 | return NULL; |
1572 | } | 1574 | } |
@@ -2071,18 +2073,30 @@ static int snd_pcm_open_file(struct file *file, | |||
2071 | return 0; | 2073 | return 0; |
2072 | } | 2074 | } |
2073 | 2075 | ||
2074 | static int snd_pcm_open(struct inode *inode, struct file *file) | 2076 | static int snd_pcm_playback_open(struct inode *inode, struct file *file) |
2077 | { | ||
2078 | struct snd_pcm *pcm; | ||
2079 | |||
2080 | pcm = snd_lookup_minor_data(iminor(inode), | ||
2081 | SNDRV_DEVICE_TYPE_PCM_PLAYBACK); | ||
2082 | return snd_pcm_open(file, pcm, SNDRV_PCM_STREAM_PLAYBACK); | ||
2083 | } | ||
2084 | |||
2085 | static int snd_pcm_capture_open(struct inode *inode, struct file *file) | ||
2075 | { | 2086 | { |
2076 | int cardnum = SNDRV_MINOR_CARD(iminor(inode)); | ||
2077 | int device = SNDRV_MINOR_DEVICE(iminor(inode)); | ||
2078 | int err; | ||
2079 | struct snd_pcm *pcm; | 2087 | struct snd_pcm *pcm; |
2088 | |||
2089 | pcm = snd_lookup_minor_data(iminor(inode), | ||
2090 | SNDRV_DEVICE_TYPE_PCM_CAPTURE); | ||
2091 | return snd_pcm_open(file, pcm, SNDRV_PCM_STREAM_CAPTURE); | ||
2092 | } | ||
2093 | |||
2094 | static int snd_pcm_open(struct file *file, struct snd_pcm *pcm, int stream) | ||
2095 | { | ||
2096 | int err; | ||
2080 | struct snd_pcm_file *pcm_file; | 2097 | struct snd_pcm_file *pcm_file; |
2081 | wait_queue_t wait; | 2098 | wait_queue_t wait; |
2082 | 2099 | ||
2083 | if (device < SNDRV_MINOR_PCM_PLAYBACK || device >= SNDRV_MINOR_DEVICES) | ||
2084 | return -ENXIO; | ||
2085 | pcm = snd_pcm_devices[(cardnum * SNDRV_PCM_DEVICES) + (device % SNDRV_MINOR_PCMS)]; | ||
2086 | if (pcm == NULL) { | 2100 | if (pcm == NULL) { |
2087 | err = -ENODEV; | 2101 | err = -ENODEV; |
2088 | goto __error1; | 2102 | goto __error1; |
@@ -2098,7 +2112,7 @@ static int snd_pcm_open(struct inode *inode, struct file *file) | |||
2098 | add_wait_queue(&pcm->open_wait, &wait); | 2112 | add_wait_queue(&pcm->open_wait, &wait); |
2099 | down(&pcm->open_mutex); | 2113 | down(&pcm->open_mutex); |
2100 | while (1) { | 2114 | while (1) { |
2101 | err = snd_pcm_open_file(file, pcm, device >= SNDRV_MINOR_PCM_CAPTURE ? SNDRV_PCM_STREAM_CAPTURE : SNDRV_PCM_STREAM_PLAYBACK, &pcm_file); | 2115 | err = snd_pcm_open_file(file, pcm, stream, &pcm_file); |
2102 | if (err >= 0) | 2116 | if (err >= 0) |
2103 | break; | 2117 | break; |
2104 | if (err == -EAGAIN) { | 2118 | if (err == -EAGAIN) { |
@@ -3375,7 +3389,7 @@ struct file_operations snd_pcm_f_ops[2] = { | |||
3375 | .owner = THIS_MODULE, | 3389 | .owner = THIS_MODULE, |
3376 | .write = snd_pcm_write, | 3390 | .write = snd_pcm_write, |
3377 | .writev = snd_pcm_writev, | 3391 | .writev = snd_pcm_writev, |
3378 | .open = snd_pcm_open, | 3392 | .open = snd_pcm_playback_open, |
3379 | .release = snd_pcm_release, | 3393 | .release = snd_pcm_release, |
3380 | .poll = snd_pcm_playback_poll, | 3394 | .poll = snd_pcm_playback_poll, |
3381 | .unlocked_ioctl = snd_pcm_playback_ioctl, | 3395 | .unlocked_ioctl = snd_pcm_playback_ioctl, |
@@ -3387,7 +3401,7 @@ struct file_operations snd_pcm_f_ops[2] = { | |||
3387 | .owner = THIS_MODULE, | 3401 | .owner = THIS_MODULE, |
3388 | .read = snd_pcm_read, | 3402 | .read = snd_pcm_read, |
3389 | .readv = snd_pcm_readv, | 3403 | .readv = snd_pcm_readv, |
3390 | .open = snd_pcm_open, | 3404 | .open = snd_pcm_capture_open, |
3391 | .release = snd_pcm_release, | 3405 | .release = snd_pcm_release, |
3392 | .poll = snd_pcm_capture_poll, | 3406 | .poll = snd_pcm_capture_poll, |
3393 | .unlocked_ioctl = snd_pcm_capture_ioctl, | 3407 | .unlocked_ioctl = snd_pcm_capture_ioctl, |