@@ -49,8 +49,6 @@ static struct snd_pcm *snd_pcm_get(struct snd_card *card, int device)
49
49
struct snd_pcm * pcm ;
50
50
51
51
list_for_each_entry (pcm , & snd_pcm_devices , list ) {
52
- if (pcm -> internal )
53
- continue ;
54
52
if (pcm -> card == card && pcm -> device == device )
55
53
return pcm ;
56
54
}
@@ -62,8 +60,6 @@ static int snd_pcm_next(struct snd_card *card, int device)
62
60
struct snd_pcm * pcm ;
63
61
64
62
list_for_each_entry (pcm , & snd_pcm_devices , list ) {
65
- if (pcm -> internal )
66
- continue ;
67
63
if (pcm -> card == card && pcm -> device > device )
68
64
return pcm -> device ;
69
65
else if (pcm -> card -> number > card -> number )
@@ -76,6 +72,9 @@ static int snd_pcm_add(struct snd_pcm *newpcm)
76
72
{
77
73
struct snd_pcm * pcm ;
78
74
75
+ if (newpcm -> internal )
76
+ return 0 ;
77
+
79
78
list_for_each_entry (pcm , & snd_pcm_devices , list ) {
80
79
if (pcm -> card == newpcm -> card && pcm -> device == newpcm -> device )
81
80
return - EBUSY ;
@@ -782,6 +781,9 @@ static int _snd_pcm_new(struct snd_card *card, const char *id, int device,
782
781
pcm -> card = card ;
783
782
pcm -> device = device ;
784
783
pcm -> internal = internal ;
784
+ mutex_init (& pcm -> open_mutex );
785
+ init_waitqueue_head (& pcm -> open_wait );
786
+ INIT_LIST_HEAD (& pcm -> list );
785
787
if (id )
786
788
strlcpy (pcm -> id , id , sizeof (pcm -> id ));
787
789
if ((err = snd_pcm_new_stream (pcm , SNDRV_PCM_STREAM_PLAYBACK , playback_count )) < 0 ) {
@@ -792,8 +794,6 @@ static int _snd_pcm_new(struct snd_card *card, const char *id, int device,
792
794
snd_pcm_free (pcm );
793
795
return err ;
794
796
}
795
- mutex_init (& pcm -> open_mutex );
796
- init_waitqueue_head (& pcm -> open_wait );
797
797
if ((err = snd_device_new (card , SNDRV_DEV_PCM , pcm , & ops )) < 0 ) {
798
798
snd_pcm_free (pcm );
799
799
return err ;
@@ -888,8 +888,9 @@ static int snd_pcm_free(struct snd_pcm *pcm)
888
888
889
889
if (!pcm )
890
890
return 0 ;
891
- list_for_each_entry (notify , & snd_pcm_notify_list , list ) {
892
- notify -> n_unregister (pcm );
891
+ if (!pcm -> internal ) {
892
+ list_for_each_entry (notify , & snd_pcm_notify_list , list )
893
+ notify -> n_unregister (pcm );
893
894
}
894
895
if (pcm -> private_free )
895
896
pcm -> private_free (pcm );
@@ -919,6 +920,9 @@ int snd_pcm_attach_substream(struct snd_pcm *pcm, int stream,
919
920
920
921
if (snd_BUG_ON (!pcm || !rsubstream ))
921
922
return - ENXIO ;
923
+ if (snd_BUG_ON (stream != SNDRV_PCM_STREAM_PLAYBACK &&
924
+ stream != SNDRV_PCM_STREAM_CAPTURE ))
925
+ return - EINVAL ;
922
926
* rsubstream = NULL ;
923
927
pstr = & pcm -> streams [stream ];
924
928
if (pstr -> substream == NULL || pstr -> substream_count == 0 )
@@ -927,25 +931,14 @@ int snd_pcm_attach_substream(struct snd_pcm *pcm, int stream,
927
931
card = pcm -> card ;
928
932
prefer_subdevice = snd_ctl_get_preferred_subdevice (card , SND_CTL_SUBDEV_PCM );
929
933
930
- switch (stream ) {
931
- case SNDRV_PCM_STREAM_PLAYBACK :
932
- if (pcm -> info_flags & SNDRV_PCM_INFO_HALF_DUPLEX ) {
933
- for (substream = pcm -> streams [SNDRV_PCM_STREAM_CAPTURE ].substream ; substream ; substream = substream -> next ) {
934
- if (SUBSTREAM_BUSY (substream ))
935
- return - EAGAIN ;
936
- }
937
- }
938
- break ;
939
- case SNDRV_PCM_STREAM_CAPTURE :
940
- if (pcm -> info_flags & SNDRV_PCM_INFO_HALF_DUPLEX ) {
941
- for (substream = pcm -> streams [SNDRV_PCM_STREAM_PLAYBACK ].substream ; substream ; substream = substream -> next ) {
942
- if (SUBSTREAM_BUSY (substream ))
943
- return - EAGAIN ;
944
- }
934
+ if (pcm -> info_flags & SNDRV_PCM_INFO_HALF_DUPLEX ) {
935
+ int opposite = !stream ;
936
+
937
+ for (substream = pcm -> streams [opposite ].substream ; substream ;
938
+ substream = substream -> next ) {
939
+ if (SUBSTREAM_BUSY (substream ))
940
+ return - EAGAIN ;
945
941
}
946
- break ;
947
- default :
948
- return - EINVAL ;
949
942
}
950
943
951
944
if (file -> f_flags & O_APPEND ) {
@@ -968,15 +961,12 @@ int snd_pcm_attach_substream(struct snd_pcm *pcm, int stream,
968
961
return 0 ;
969
962
}
970
963
971
- if (prefer_subdevice >= 0 ) {
972
- for (substream = pstr -> substream ; substream ; substream = substream -> next )
973
- if (!SUBSTREAM_BUSY (substream ) && substream -> number == prefer_subdevice )
974
- goto __ok ;
975
- }
976
- for (substream = pstr -> substream ; substream ; substream = substream -> next )
977
- if (!SUBSTREAM_BUSY (substream ))
964
+ for (substream = pstr -> substream ; substream ; substream = substream -> next ) {
965
+ if (!SUBSTREAM_BUSY (substream ) &&
966
+ (prefer_subdevice == -1 ||
967
+ substream -> number == prefer_subdevice ))
978
968
break ;
979
- __ok :
969
+ }
980
970
if (substream == NULL )
981
971
return - EAGAIN ;
982
972
@@ -1086,15 +1076,16 @@ static int snd_pcm_dev_register(struct snd_device *device)
1086
1076
if (snd_BUG_ON (!device || !device -> device_data ))
1087
1077
return - ENXIO ;
1088
1078
pcm = device -> device_data ;
1079
+ if (pcm -> internal )
1080
+ return 0 ;
1081
+
1089
1082
mutex_lock (& register_mutex );
1090
1083
err = snd_pcm_add (pcm );
1091
- if (err ) {
1092
- mutex_unlock (& register_mutex );
1093
- return err ;
1094
- }
1084
+ if (err )
1085
+ goto unlock ;
1095
1086
for (cidx = 0 ; cidx < 2 ; cidx ++ ) {
1096
1087
int devtype = -1 ;
1097
- if (pcm -> streams [cidx ].substream == NULL || pcm -> internal )
1088
+ if (pcm -> streams [cidx ].substream == NULL )
1098
1089
continue ;
1099
1090
switch (cidx ) {
1100
1091
case SNDRV_PCM_STREAM_PLAYBACK :
@@ -1109,9 +1100,8 @@ static int snd_pcm_dev_register(struct snd_device *device)
1109
1100
& snd_pcm_f_ops [cidx ], pcm ,
1110
1101
& pcm -> streams [cidx ].dev );
1111
1102
if (err < 0 ) {
1112
- list_del (& pcm -> list );
1113
- mutex_unlock (& register_mutex );
1114
- return err ;
1103
+ list_del_init (& pcm -> list );
1104
+ goto unlock ;
1115
1105
}
1116
1106
1117
1107
for (substream = pcm -> streams [cidx ].substream ; substream ; substream = substream -> next )
@@ -1121,8 +1111,9 @@ static int snd_pcm_dev_register(struct snd_device *device)
1121
1111
list_for_each_entry (notify , & snd_pcm_notify_list , list )
1122
1112
notify -> n_register (pcm );
1123
1113
1114
+ unlock :
1124
1115
mutex_unlock (& register_mutex );
1125
- return 0 ;
1116
+ return err ;
1126
1117
}
1127
1118
1128
1119
static int snd_pcm_dev_disconnect (struct snd_device * device )
@@ -1133,13 +1124,10 @@ static int snd_pcm_dev_disconnect(struct snd_device *device)
1133
1124
int cidx ;
1134
1125
1135
1126
mutex_lock (& register_mutex );
1136
- if (list_empty (& pcm -> list ))
1137
- goto unlock ;
1138
-
1139
1127
mutex_lock (& pcm -> open_mutex );
1140
1128
wake_up (& pcm -> open_wait );
1141
1129
list_del_init (& pcm -> list );
1142
- for (cidx = 0 ; cidx < 2 ; cidx ++ )
1130
+ for (cidx = 0 ; cidx < 2 ; cidx ++ ) {
1143
1131
for (substream = pcm -> streams [cidx ].substream ; substream ; substream = substream -> next ) {
1144
1132
snd_pcm_stream_lock_irq (substream );
1145
1133
if (substream -> runtime ) {
@@ -1149,18 +1137,20 @@ static int snd_pcm_dev_disconnect(struct snd_device *device)
1149
1137
}
1150
1138
snd_pcm_stream_unlock_irq (substream );
1151
1139
}
1152
- list_for_each_entry (notify , & snd_pcm_notify_list , list ) {
1153
- notify -> n_disconnect (pcm );
1140
+ }
1141
+ if (!pcm -> internal ) {
1142
+ list_for_each_entry (notify , & snd_pcm_notify_list , list )
1143
+ notify -> n_disconnect (pcm );
1154
1144
}
1155
1145
for (cidx = 0 ; cidx < 2 ; cidx ++ ) {
1156
- snd_unregister_device (& pcm -> streams [cidx ].dev );
1146
+ if (!pcm -> internal )
1147
+ snd_unregister_device (& pcm -> streams [cidx ].dev );
1157
1148
if (pcm -> streams [cidx ].chmap_kctl ) {
1158
1149
snd_ctl_remove (pcm -> card , pcm -> streams [cidx ].chmap_kctl );
1159
1150
pcm -> streams [cidx ].chmap_kctl = NULL ;
1160
1151
}
1161
1152
}
1162
1153
mutex_unlock (& pcm -> open_mutex );
1163
- unlock :
1164
1154
mutex_unlock (& register_mutex );
1165
1155
return 0 ;
1166
1156
}
0 commit comments