Commit f87135f56cb266e031f5ec081dfbde7e43f55e80

Authored by Clemens Ladisch
Committed by Jaroslav Kysela
1 parent 6983b7240c

[ALSA] dynamic minors (3/6): store device-specific object pointers dynamically

Instead of storing the pointers to the device-specific structures in an
array, put them into the struct snd_minor, and look them up dynamically.

This makes the device type modules independent of the minor number
encoding.

Signed-off-by: Clemens Ladisch <clemens@ladisch.de>

Showing 17 changed files with 278 additions and 197 deletions Side-by-side Diff

include/sound/core.h
... ... @@ -187,6 +187,7 @@
187 187 int card; /* card number */
188 188 int device; /* device number */
189 189 struct file_operations *f_ops; /* file operations */
  190 + void *private_data; /* private data for f_ops->open */
190 191 char name[0]; /* device name (keep at the end of
191 192 structure) */
192 193 };
193 194  
194 195  
195 196  
... ... @@ -199,13 +200,17 @@
199 200 void snd_request_card(int card);
200 201  
201 202 int snd_register_device(int type, struct snd_card *card, int dev,
202   - struct file_operations *f_ops, const char *name);
  203 + struct file_operations *f_ops, void *private_data,
  204 + const char *name);
203 205 int snd_unregister_device(int type, struct snd_card *card, int dev);
  206 +void *snd_lookup_minor_data(unsigned int minor, int type);
204 207  
205 208 #ifdef CONFIG_SND_OSSEMUL
206 209 int snd_register_oss_device(int type, struct snd_card *card, int dev,
207   - struct file_operations *f_ops, const char *name);
  210 + struct file_operations *f_ops, void *private_data,
  211 + const char *name);
208 212 int snd_unregister_oss_device(int type, struct snd_card *card, int dev);
  213 +void *snd_lookup_oss_minor_data(unsigned int minor, int type);
209 214 #endif
210 215  
211 216 int snd_minor_info_init(void);
include/sound/hwdep.h
... ... @@ -43,6 +43,7 @@
43 43  
44 44 struct snd_hwdep {
45 45 struct snd_card *card;
  46 + struct list_head list;
46 47 int device;
47 48 char id[32];
48 49 char name[80];
... ... @@ -412,6 +412,7 @@
412 412  
413 413 struct snd_pcm {
414 414 struct snd_card *card;
  415 + struct list_head list;
415 416 unsigned int device; /* device number */
416 417 unsigned int info_flags;
417 418 unsigned short dev_class;
... ... @@ -439,7 +440,6 @@
439 440 * Registering
440 441 */
441 442  
442   -extern struct snd_pcm *snd_pcm_devices[];
443 443 extern struct file_operations snd_pcm_f_ops[2];
444 444  
445 445 int snd_pcm_new(struct snd_card *card, char *id, int device,
include/sound/rawmidi.h
... ... @@ -113,7 +113,7 @@
113 113  
114 114 struct snd_rawmidi {
115 115 struct snd_card *card;
116   -
  116 + struct list_head list;
117 117 unsigned int device; /* device number */
118 118 unsigned int info_flags; /* SNDRV_RAWMIDI_INFO_XXXX */
119 119 char id[64];
... ... @@ -165,8 +165,8 @@
165 165 /* main midi functions */
166 166  
167 167 int snd_rawmidi_info_select(struct snd_card *card, struct snd_rawmidi_info *info);
168   -int snd_rawmidi_kernel_open(int cardnum, int device, int subdevice, int mode,
169   - struct snd_rawmidi_file *rfile);
  168 +int snd_rawmidi_kernel_open(struct snd_card *card, int device, int subdevice,
  169 + int mode, struct snd_rawmidi_file *rfile);
170 170 int snd_rawmidi_kernel_release(struct snd_rawmidi_file *rfile);
171 171 int snd_rawmidi_output_params(struct snd_rawmidi_substream *substream,
172 172 struct snd_rawmidi_params *params);
sound/core/control.c
... ... @@ -47,13 +47,12 @@
47 47  
48 48 static int snd_ctl_open(struct inode *inode, struct file *file)
49 49 {
50   - int cardnum = SNDRV_MINOR_CARD(iminor(inode));
51 50 unsigned long flags;
52 51 struct snd_card *card;
53 52 struct snd_ctl_file *ctl;
54 53 int err;
55 54  
56   - card = snd_cards[cardnum];
  55 + card = snd_lookup_minor_data(iminor(inode), SNDRV_DEVICE_TYPE_CONTROL);
57 56 if (!card) {
58 57 err = -ENODEV;
59 58 goto __error1;
... ... @@ -1277,8 +1276,8 @@
1277 1276 cardnum = card->number;
1278 1277 snd_assert(cardnum >= 0 && cardnum < SNDRV_CARDS, return -ENXIO);
1279 1278 sprintf(name, "controlC%i", cardnum);
1280   - if ((err = snd_register_device(SNDRV_DEVICE_TYPE_CONTROL,
1281   - card, -1, &snd_ctl_f_ops, name)) < 0)
  1279 + if ((err = snd_register_device(SNDRV_DEVICE_TYPE_CONTROL, card, -1,
  1280 + &snd_ctl_f_ops, card, name)) < 0)
1282 1281 return err;
1283 1282 return 0;
1284 1283 }
... ... @@ -35,8 +35,7 @@
35 35 MODULE_DESCRIPTION("Hardware dependent layer");
36 36 MODULE_LICENSE("GPL");
37 37  
38   -static struct snd_hwdep *snd_hwdep_devices[SNDRV_CARDS * SNDRV_MINOR_HWDEPS];
39   -
  38 +static LIST_HEAD(snd_hwdep_devices);
40 39 static DECLARE_MUTEX(register_mutex);
41 40  
42 41 static int snd_hwdep_free(struct snd_hwdep *hwdep);
43 42  
44 43  
... ... @@ -44,10 +43,20 @@
44 43 static int snd_hwdep_dev_register(struct snd_device *device);
45 44 static int snd_hwdep_dev_unregister(struct snd_device *device);
46 45  
47   -/*
48 46  
49   - */
  47 +static struct snd_hwdep *snd_hwdep_search(struct snd_card *card, int device)
  48 +{
  49 + struct list_head *p;
  50 + struct snd_hwdep *hwdep;
50 51  
  52 + list_for_each(p, &snd_hwdep_devices) {
  53 + hwdep = list_entry(p, struct snd_hwdep, list);
  54 + if (hwdep->card == card && hwdep->device == device)
  55 + return hwdep;
  56 + }
  57 + return NULL;
  58 +}
  59 +
51 60 static loff_t snd_hwdep_llseek(struct file * file, loff_t offset, int orig)
52 61 {
53 62 struct snd_hwdep *hw = file->private_data;
54 63  
55 64  
56 65  
57 66  
... ... @@ -77,34 +86,25 @@
77 86 static int snd_hwdep_open(struct inode *inode, struct file * file)
78 87 {
79 88 int major = imajor(inode);
80   - int cardnum;
81   - int device;
82 89 struct snd_hwdep *hw;
83 90 int err;
84 91 wait_queue_t wait;
85 92  
86 93 if (major == snd_major) {
87   - cardnum = SNDRV_MINOR_CARD(iminor(inode));
88   - device = SNDRV_MINOR_DEVICE(iminor(inode)) - SNDRV_MINOR_HWDEP;
  94 + hw = snd_lookup_minor_data(iminor(inode),
  95 + SNDRV_DEVICE_TYPE_HWDEP);
89 96 #ifdef CONFIG_SND_OSSEMUL
90 97 } else if (major == SOUND_MAJOR) {
91   - cardnum = SNDRV_MINOR_OSS_CARD(iminor(inode));
92   - device = 0;
  98 + hw = snd_lookup_oss_minor_data(iminor(inode),
  99 + SNDRV_OSS_DEVICE_TYPE_DMFM);
93 100 #endif
94 101 } else
95 102 return -ENXIO;
96   - cardnum %= SNDRV_CARDS;
97   - device %= SNDRV_MINOR_HWDEPS;
98   - hw = snd_hwdep_devices[(cardnum * SNDRV_MINOR_HWDEPS) + device];
99 103 if (hw == NULL)
100 104 return -ENODEV;
101 105  
102 106 if (!hw->ops.open)
103 107 return -ENXIO;
104   -#ifdef CONFIG_SND_OSSEMUL
105   - if (major == SOUND_MAJOR && hw->oss_type < 0)
106   - return -ENXIO;
107   -#endif
108 108  
109 109 if (!try_module_get(hw->card->module))
110 110 return -EFAULT;
... ... @@ -265,9 +265,6 @@
265 265 struct snd_ctl_file * control,
266 266 unsigned int cmd, unsigned long arg)
267 267 {
268   - unsigned int tmp;
269   -
270   - tmp = card->number * SNDRV_MINOR_HWDEPS;
271 268 switch (cmd) {
272 269 case SNDRV_CTL_IOCTL_HWDEP_NEXT_DEVICE:
273 270 {
274 271  
275 272  
... ... @@ -275,14 +272,16 @@
275 272  
276 273 if (get_user(device, (int __user *)arg))
277 274 return -EFAULT;
  275 + down(&register_mutex);
278 276 device = device < 0 ? 0 : device + 1;
279 277 while (device < SNDRV_MINOR_HWDEPS) {
280   - if (snd_hwdep_devices[tmp + device])
  278 + if (snd_hwdep_search(card, device))
281 279 break;
282 280 device++;
283 281 }
284 282 if (device >= SNDRV_MINOR_HWDEPS)
285 283 device = -1;
  284 + up(&register_mutex);
286 285 if (put_user(device, (int __user *)arg))
287 286 return -EFAULT;
288 287 return 0;
289 288  
... ... @@ -290,17 +289,19 @@
290 289 case SNDRV_CTL_IOCTL_HWDEP_INFO:
291 290 {
292 291 struct snd_hwdep_info __user *info = (struct snd_hwdep_info __user *)arg;
293   - int device;
  292 + int device, err;
294 293 struct snd_hwdep *hwdep;
295 294  
296 295 if (get_user(device, &info->device))
297 296 return -EFAULT;
298   - if (device < 0 || device >= SNDRV_MINOR_HWDEPS)
299   - return -ENXIO;
300   - hwdep = snd_hwdep_devices[tmp + device];
301   - if (hwdep == NULL)
302   - return -ENXIO;
303   - return snd_hwdep_info(hwdep, info);
  297 + down(&register_mutex);
  298 + hwdep = snd_hwdep_search(card, device);
  299 + if (hwdep)
  300 + err = snd_hwdep_info(hwdep, info);
  301 + else
  302 + err = -ENXIO;
  303 + up(&register_mutex);
  304 + return err;
304 305 }
305 306 }
306 307 return -ENOIOCTLCMD;
307 308  
308 309  
309 310  
310 311  
... ... @@ -397,23 +398,22 @@
397 398 static int snd_hwdep_dev_register(struct snd_device *device)
398 399 {
399 400 struct snd_hwdep *hwdep = device->device_data;
400   - int idx, err;
  401 + int err;
401 402 char name[32];
402 403  
403 404 down(&register_mutex);
404   - idx = (hwdep->card->number * SNDRV_MINOR_HWDEPS) + hwdep->device;
405   - if (snd_hwdep_devices[idx]) {
  405 + if (snd_hwdep_search(hwdep->card, hwdep->device)) {
406 406 up(&register_mutex);
407 407 return -EBUSY;
408 408 }
409   - snd_hwdep_devices[idx] = hwdep;
  409 + list_add_tail(&hwdep->list, &snd_hwdep_devices);
410 410 sprintf(name, "hwC%iD%i", hwdep->card->number, hwdep->device);
411 411 if ((err = snd_register_device(SNDRV_DEVICE_TYPE_HWDEP,
412 412 hwdep->card, hwdep->device,
413   - &snd_hwdep_f_ops, name)) < 0) {
  413 + &snd_hwdep_f_ops, hwdep, name)) < 0) {
414 414 snd_printk(KERN_ERR "unable to register hardware dependent device %i:%i\n",
415 415 hwdep->card->number, hwdep->device);
416   - snd_hwdep_devices[idx] = NULL;
  416 + list_del(&hwdep->list);
417 417 up(&register_mutex);
418 418 return err;
419 419 }
... ... @@ -425,7 +425,7 @@
425 425 } else {
426 426 if (snd_register_oss_device(hwdep->oss_type,
427 427 hwdep->card, hwdep->device,
428   - &snd_hwdep_f_ops,
  428 + &snd_hwdep_f_ops, hwdep,
429 429 hwdep->oss_dev) < 0) {
430 430 snd_printk(KERN_ERR "unable to register OSS compatibility device %i:%i\n",
431 431 hwdep->card->number, hwdep->device);
432 432  
... ... @@ -441,12 +441,10 @@
441 441 static int snd_hwdep_dev_unregister(struct snd_device *device)
442 442 {
443 443 struct snd_hwdep *hwdep = device->device_data;
444   - int idx;
445 444  
446 445 snd_assert(hwdep != NULL, return -ENXIO);
447 446 down(&register_mutex);
448   - idx = (hwdep->card->number * SNDRV_MINOR_HWDEPS) + hwdep->device;
449   - if (snd_hwdep_devices[idx] != hwdep) {
  447 + if (snd_hwdep_search(hwdep->card, hwdep->device) != hwdep) {
450 448 up(&register_mutex);
451 449 return -EINVAL;
452 450 }
... ... @@ -455,7 +453,7 @@
455 453 snd_unregister_oss_device(hwdep->oss_type, hwdep->card, hwdep->device);
456 454 #endif
457 455 snd_unregister_device(SNDRV_DEVICE_TYPE_HWDEP, hwdep->card, hwdep->device);
458   - snd_hwdep_devices[idx] = NULL;
  456 + list_del(&hwdep->list);
459 457 up(&register_mutex);
460 458 return snd_hwdep_free(hwdep);
461 459 }
462 460  
463 461  
... ... @@ -467,18 +465,14 @@
467 465 static void snd_hwdep_proc_read(struct snd_info_entry *entry,
468 466 struct snd_info_buffer *buffer)
469 467 {
470   - int idx;
  468 + struct list_head *p;
471 469 struct snd_hwdep *hwdep;
472 470  
473 471 down(&register_mutex);
474   - for (idx = 0; idx < SNDRV_CARDS * SNDRV_MINOR_HWDEPS; idx++) {
475   - hwdep = snd_hwdep_devices[idx];
476   - if (hwdep == NULL)
477   - continue;
  472 + list_for_each(p, &snd_hwdep_devices) {
  473 + hwdep = list_entry(p, struct snd_hwdep, list);
478 474 snd_iprintf(buffer, "%02i-%02i: %s\n",
479   - idx / SNDRV_MINOR_HWDEPS,
480   - idx % SNDRV_MINOR_HWDEPS,
481   - hwdep->name);
  475 + hwdep->card->number, hwdep->device, hwdep->name);
482 476 }
483 477 up(&register_mutex);
484 478 }
485 479  
... ... @@ -493,9 +487,8 @@
493 487 {
494 488 struct snd_info_entry *entry;
495 489  
496   - memset(snd_hwdep_devices, 0, sizeof(snd_hwdep_devices));
497 490 if ((entry = snd_info_create_module_entry(THIS_MODULE, "hwdep", NULL)) != NULL) {
498   - entry->c.text.read_size = 512;
  491 + entry->c.text.read_size = PAGE_SIZE;
499 492 entry->c.text.read = snd_hwdep_proc_read;
500 493 if (snd_info_register(entry) < 0) {
501 494 snd_info_free_entry(entry);
sound/core/oss/mixer_oss.c
... ... @@ -41,12 +41,13 @@
41 41  
42 42 static int snd_mixer_oss_open(struct inode *inode, struct file *file)
43 43 {
44   - int cardnum = SNDRV_MINOR_OSS_CARD(iminor(inode));
45 44 struct snd_card *card;
46 45 struct snd_mixer_oss_file *fmixer;
47 46 int err;
48 47  
49   - if ((card = snd_cards[cardnum]) == NULL)
  48 + card = snd_lookup_oss_minor_data(iminor(inode),
  49 + SNDRV_OSS_DEVICE_TYPE_MIXER);
  50 + if (card == NULL)
50 51 return -ENODEV;
51 52 if (card->mixer_oss == NULL)
52 53 return -ENODEV;
... ... @@ -1286,7 +1287,7 @@
1286 1287 sprintf(name, "mixer%i%i", card->number, 0);
1287 1288 if ((err = snd_register_oss_device(SNDRV_OSS_DEVICE_TYPE_MIXER,
1288 1289 card, 0,
1289   - &snd_mixer_oss_f_ops,
  1290 + &snd_mixer_oss_f_ops, card,
1290 1291 name)) < 0) {
1291 1292 snd_printk(KERN_ERR "unable to register OSS mixer device %i:%i\n",
1292 1293 card->number, 0);
sound/core/oss/pcm_oss.c
... ... @@ -1834,9 +1834,6 @@
1834 1834  
1835 1835 static int snd_pcm_oss_open(struct inode *inode, struct file *file)
1836 1836 {
1837   - int minor = iminor(inode);
1838   - int cardnum = SNDRV_MINOR_OSS_CARD(minor);
1839   - int device;
1840 1837 int err;
1841 1838 char task_name[32];
1842 1839 struct snd_pcm *pcm;
... ... @@ -1845,11 +1842,8 @@
1845 1842 int nonblock;
1846 1843 wait_queue_t wait;
1847 1844  
1848   - snd_assert(cardnum >= 0 && cardnum < SNDRV_CARDS, return -ENXIO);
1849   - device = SNDRV_MINOR_OSS_DEVICE(minor) == SNDRV_MINOR_OSS_PCM1 ?
1850   - adsp_map[cardnum] : dsp_map[cardnum];
1851   -
1852   - pcm = snd_pcm_devices[(cardnum * SNDRV_PCM_DEVICES) + device];
  1845 + pcm = snd_lookup_oss_minor_data(iminor(inode),
  1846 + SNDRV_OSS_DEVICE_TYPE_PCM);
1853 1847 if (pcm == NULL) {
1854 1848 err = -ENODEV;
1855 1849 goto __error1;
... ... @@ -1890,7 +1884,7 @@
1890 1884 down(&pcm->open_mutex);
1891 1885 while (1) {
1892 1886 err = snd_pcm_oss_open_file(file, pcm, &pcm_oss_file,
1893   - minor, psetup, csetup);
  1887 + iminor(inode), psetup, csetup);
1894 1888 if (err >= 0)
1895 1889 break;
1896 1890 if (err == -EAGAIN) {
... ... @@ -2450,7 +2444,7 @@
2450 2444 sprintf(name, "dsp%i%i", pcm->card->number, pcm->device);
2451 2445 if (snd_register_oss_device(SNDRV_OSS_DEVICE_TYPE_PCM,
2452 2446 pcm->card, index, &snd_pcm_oss_f_reg,
2453   - name) < 0) {
  2447 + pcm, name) < 0) {
2454 2448 snd_printk(KERN_ERR "unable to register OSS PCM device %i:%i\n",
2455 2449 pcm->card->number, pcm->device);
2456 2450 }
... ... @@ -33,7 +33,7 @@
33 33 MODULE_DESCRIPTION("Midlevel PCM code for ALSA.");
34 34 MODULE_LICENSE("GPL");
35 35  
36   -struct snd_pcm *snd_pcm_devices[SNDRV_CARDS * SNDRV_PCM_DEVICES];
  36 +static LIST_HEAD(snd_pcm_devices);
37 37 static LIST_HEAD(snd_pcm_notify_list);
38 38 static DECLARE_MUTEX(register_mutex);
39 39  
40 40  
... ... @@ -43,13 +43,23 @@
43 43 static int snd_pcm_dev_disconnect(struct snd_device *device);
44 44 static int snd_pcm_dev_unregister(struct snd_device *device);
45 45  
  46 +static struct snd_pcm *snd_pcm_search(struct snd_card *card, int device)
  47 +{
  48 + struct list_head *p;
  49 + struct snd_pcm *pcm;
  50 +
  51 + list_for_each(p, &snd_pcm_devices) {
  52 + pcm = list_entry(p, struct snd_pcm, list);
  53 + if (pcm->card == card && pcm->device == device)
  54 + return pcm;
  55 + }
  56 + return NULL;
  57 +}
  58 +
46 59 static int snd_pcm_control_ioctl(struct snd_card *card,
47 60 struct snd_ctl_file *control,
48 61 unsigned int cmd, unsigned long arg)
49 62 {
50   - unsigned int tmp;
51   -
52   - tmp = card->number * SNDRV_PCM_DEVICES;
53 63 switch (cmd) {
54 64 case SNDRV_CTL_IOCTL_PCM_NEXT_DEVICE:
55 65 {
56 66  
57 67  
... ... @@ -57,14 +67,16 @@
57 67  
58 68 if (get_user(device, (int __user *)arg))
59 69 return -EFAULT;
  70 + down(&register_mutex);
60 71 device = device < 0 ? 0 : device + 1;
61 72 while (device < SNDRV_PCM_DEVICES) {
62   - if (snd_pcm_devices[tmp + device])
  73 + if (snd_pcm_search(card, device))
63 74 break;
64 75 device++;
65 76 }
66 77 if (device == SNDRV_PCM_DEVICES)
67 78 device = -1;
  79 + up(&register_mutex);
68 80 if (put_user(device, (int __user *)arg))
69 81 return -EFAULT;
70 82 return 0;
71 83  
72 84  
73 85  
74 86  
... ... @@ -77,31 +89,44 @@
77 89 struct snd_pcm *pcm;
78 90 struct snd_pcm_str *pstr;
79 91 struct snd_pcm_substream *substream;
  92 + int err;
  93 +
80 94 info = (struct snd_pcm_info __user *)arg;
81 95 if (get_user(device, &info->device))
82 96 return -EFAULT;
83   - if (device >= SNDRV_PCM_DEVICES)
84   - return -ENXIO;
85   - pcm = snd_pcm_devices[tmp + device];
86   - if (pcm == NULL)
87   - return -ENXIO;
88 97 if (get_user(stream, &info->stream))
89 98 return -EFAULT;
90 99 if (stream < 0 || stream > 1)
91 100 return -EINVAL;
92   - pstr = &pcm->streams[stream];
93   - if (pstr->substream_count == 0)
94   - return -ENOENT;
95 101 if (get_user(subdevice, &info->subdevice))
96 102 return -EFAULT;
97   - if (subdevice >= pstr->substream_count)
98   - return -ENXIO;
99   - for (substream = pstr->substream; substream; substream = substream->next)
  103 + down(&register_mutex);
  104 + pcm = snd_pcm_search(card, device);
  105 + if (pcm == NULL) {
  106 + err = -ENXIO;
  107 + goto _error;
  108 + }
  109 + pstr = &pcm->streams[stream];
  110 + if (pstr->substream_count == 0) {
  111 + err = -ENOENT;
  112 + goto _error;
  113 + }
  114 + if (subdevice >= pstr->substream_count) {
  115 + err = -ENXIO;
  116 + goto _error;
  117 + }
  118 + for (substream = pstr->substream; substream;
  119 + substream = substream->next)
100 120 if (substream->number == (int)subdevice)
101 121 break;
102   - if (substream == NULL)
103   - return -ENXIO;
104   - return snd_pcm_info_user(substream, info);
  122 + if (substream == NULL) {
  123 + err = -ENXIO;
  124 + goto _error;
  125 + }
  126 + err = snd_pcm_info_user(substream, info);
  127 + _error:
  128 + up(&register_mutex);
  129 + return err;
105 130 }
106 131 case SNDRV_CTL_IOCTL_PCM_PREFER_SUBDEVICE:
107 132 {
... ... @@ -865,8 +890,7 @@
865 890  
866 891 static int snd_pcm_dev_register(struct snd_device *device)
867 892 {
868   - int idx, cidx, err;
869   - unsigned short minor;
  893 + int cidx, err;
870 894 struct snd_pcm_substream *substream;
871 895 struct list_head *list;
872 896 char str[16];
873 897  
... ... @@ -874,12 +898,11 @@
874 898  
875 899 snd_assert(pcm != NULL && device != NULL, return -ENXIO);
876 900 down(&register_mutex);
877   - idx = (pcm->card->number * SNDRV_PCM_DEVICES) + pcm->device;
878   - if (snd_pcm_devices[idx]) {
  901 + if (snd_pcm_search(pcm->card, pcm->device)) {
879 902 up(&register_mutex);
880 903 return -EBUSY;
881 904 }
882   - snd_pcm_devices[idx] = pcm;
  905 + list_add_tail(&pcm->list, &snd_pcm_devices);
883 906 for (cidx = 0; cidx < 2; cidx++) {
884 907 int devtype = -1;
885 908 if (pcm->streams[cidx].substream == NULL)
886 909  
887 910  
888 911  
... ... @@ -887,20 +910,19 @@
887 910 switch (cidx) {
888 911 case SNDRV_PCM_STREAM_PLAYBACK:
889 912 sprintf(str, "pcmC%iD%ip", pcm->card->number, pcm->device);
890   - minor = SNDRV_MINOR_PCM_PLAYBACK + idx;
891 913 devtype = SNDRV_DEVICE_TYPE_PCM_PLAYBACK;
892 914 break;
893 915 case SNDRV_PCM_STREAM_CAPTURE:
894 916 sprintf(str, "pcmC%iD%ic", pcm->card->number, pcm->device);
895   - minor = SNDRV_MINOR_PCM_CAPTURE + idx;
896 917 devtype = SNDRV_DEVICE_TYPE_PCM_CAPTURE;
897 918 break;
898 919 }
899 920 if ((err = snd_register_device(devtype, pcm->card,
900 921 pcm->device,
901   - &snd_pcm_f_ops[cidx], str)) < 0)
  922 + &snd_pcm_f_ops[cidx],
  923 + pcm, str)) < 0)
902 924 {
903   - snd_pcm_devices[idx] = NULL;
  925 + list_del(&pcm->list);
904 926 up(&register_mutex);
905 927 return err;
906 928 }
907 929  
... ... @@ -921,11 +943,10 @@
921 943 struct snd_pcm *pcm = device->device_data;
922 944 struct list_head *list;
923 945 struct snd_pcm_substream *substream;
924   - int idx, cidx;
  946 + int cidx;
925 947  
926 948 down(&register_mutex);
927   - idx = (pcm->card->number * SNDRV_PCM_DEVICES) + pcm->device;
928   - snd_pcm_devices[idx] = NULL;
  949 + list_del_init(&pcm->list);
929 950 for (cidx = 0; cidx < 2; cidx++)
930 951 for (substream = pcm->streams[cidx].substream; substream; substream = substream->next)
931 952 if (substream->runtime)
932 953  
... ... @@ -941,15 +962,14 @@
941 962  
942 963 static int snd_pcm_dev_unregister(struct snd_device *device)
943 964 {
944   - int idx, cidx, devtype;
  965 + int cidx, devtype;
945 966 struct snd_pcm_substream *substream;
946 967 struct list_head *list;
947 968 struct snd_pcm *pcm = device->device_data;
948 969  
949 970 snd_assert(pcm != NULL, return -ENXIO);
950 971 down(&register_mutex);
951   - idx = (pcm->card->number * SNDRV_PCM_DEVICES) + pcm->device;
952   - snd_pcm_devices[idx] = NULL;
  972 + list_del(&pcm->list);
953 973 for (cidx = 0; cidx < 2; cidx++) {
954 974 devtype = -1;
955 975 switch (cidx) {
956 976  
957 977  
... ... @@ -975,24 +995,19 @@
975 995  
976 996 int snd_pcm_notify(struct snd_pcm_notify *notify, int nfree)
977 997 {
978   - int idx;
  998 + struct list_head *p;
979 999  
980 1000 snd_assert(notify != NULL && notify->n_register != NULL && notify->n_unregister != NULL, return -EINVAL);
981 1001 down(&register_mutex);
982 1002 if (nfree) {
983 1003 list_del(&notify->list);
984   - for (idx = 0; idx < SNDRV_CARDS * SNDRV_PCM_DEVICES; idx++) {
985   - if (snd_pcm_devices[idx] == NULL)
986   - continue;
987   - notify->n_unregister(snd_pcm_devices[idx]);
988   - }
  1004 + list_for_each(p, &snd_pcm_devices)
  1005 + notify->n_unregister(list_entry(p,
  1006 + struct snd_pcm, list));
989 1007 } else {
990 1008 list_add_tail(&notify->list, &snd_pcm_notify_list);
991   - for (idx = 0; idx < SNDRV_CARDS * SNDRV_PCM_DEVICES; idx++) {
992   - if (snd_pcm_devices[idx] == NULL)
993   - continue;
994   - notify->n_register(snd_pcm_devices[idx]);
995   - }
  1009 + list_for_each(p, &snd_pcm_devices)
  1010 + notify->n_register(list_entry(p, struct snd_pcm, list));
996 1011 }
997 1012 up(&register_mutex);
998 1013 return 0;
999 1014  
... ... @@ -1005,16 +1020,14 @@
1005 1020 static void snd_pcm_proc_read(struct snd_info_entry *entry,
1006 1021 struct snd_info_buffer *buffer)
1007 1022 {
1008   - int idx;
  1023 + struct list_head *p;
1009 1024 struct snd_pcm *pcm;
1010 1025  
1011 1026 down(&register_mutex);
1012   - for (idx = 0; idx < SNDRV_CARDS * SNDRV_PCM_DEVICES; idx++) {
1013   - pcm = snd_pcm_devices[idx];
1014   - if (pcm == NULL)
1015   - continue;
1016   - snd_iprintf(buffer, "%02i-%02i: %s : %s", idx / SNDRV_PCM_DEVICES,
1017   - idx % SNDRV_PCM_DEVICES, pcm->id, pcm->name);
  1027 + list_for_each(p, &snd_pcm_devices) {
  1028 + pcm = list_entry(p, struct snd_pcm, list);
  1029 + snd_iprintf(buffer, "%02i-%02i: %s : %s",
  1030 + pcm->card->number, pcm->device, pcm->id, pcm->name);
1018 1031 if (pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream)
1019 1032 snd_iprintf(buffer, " : playback %i",
1020 1033 pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream_count);
... ... @@ -1063,7 +1076,6 @@
1063 1076 module_init(alsa_pcm_init)
1064 1077 module_exit(alsa_pcm_exit)
1065 1078  
1066   -EXPORT_SYMBOL(snd_pcm_devices);
1067 1079 EXPORT_SYMBOL(snd_pcm_new);
1068 1080 EXPORT_SYMBOL(snd_pcm_new_stream);
1069 1081 EXPORT_SYMBOL(snd_pcm_notify);
sound/core/pcm_native.c
... ... @@ -62,6 +62,7 @@
62 62 struct snd_pcm_hw_params_old __user * _oparams);
63 63 static int snd_pcm_hw_params_old_user(struct snd_pcm_substream *substream,
64 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 @@
1554 1555 {
1555 1556 struct file *file;
1556 1557 struct inode *inode;
1557   - unsigned short minor;
  1558 + unsigned int minor;
  1559 +
1558 1560 file = fget(fd);
1559 1561 if (!file)
1560 1562 return NULL;
... ... @@ -1565,8 +1567,8 @@
1565 1567 return NULL;
1566 1568 }
1567 1569 minor = iminor(inode);
1568   - if (minor >= 256 ||
1569   - minor % SNDRV_MINOR_DEVICES < SNDRV_MINOR_PCM_PLAYBACK) {
  1570 + if (!snd_lookup_minor_data(minor, SNDRV_DEVICE_TYPE_PCM_PLAYBACK) &&
  1571 + !snd_lookup_minor_data(minor, SNDRV_DEVICE_TYPE_PCM_CAPTURE)) {
1570 1572 fput(file);
1571 1573 return NULL;
1572 1574 }
1573 1575  
1574 1576  
1575 1577  
... ... @@ -2071,18 +2073,30 @@
2071 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)
2075 2077 {
2076   - int cardnum = SNDRV_MINOR_CARD(iminor(inode));
2077   - int device = SNDRV_MINOR_DEVICE(iminor(inode));
2078   - int err;
2079 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)
  2086 +{
  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 2097 struct snd_pcm_file *pcm_file;
2081 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 2100 if (pcm == NULL) {
2087 2101 err = -ENODEV;
2088 2102 goto __error1;
... ... @@ -2098,7 +2112,7 @@
2098 2112 add_wait_queue(&pcm->open_wait, &wait);
2099 2113 down(&pcm->open_mutex);
2100 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 2116 if (err >= 0)
2103 2117 break;
2104 2118 if (err == -EAGAIN) {
... ... @@ -3375,7 +3389,7 @@
3375 3389 .owner = THIS_MODULE,
3376 3390 .write = snd_pcm_write,
3377 3391 .writev = snd_pcm_writev,
3378   - .open = snd_pcm_open,
  3392 + .open = snd_pcm_playback_open,
3379 3393 .release = snd_pcm_release,
3380 3394 .poll = snd_pcm_playback_poll,
3381 3395 .unlocked_ioctl = snd_pcm_playback_ioctl,
... ... @@ -3387,7 +3401,7 @@
3387 3401 .owner = THIS_MODULE,
3388 3402 .read = snd_pcm_read,
3389 3403 .readv = snd_pcm_readv,
3390   - .open = snd_pcm_open,
  3404 + .open = snd_pcm_capture_open,
3391 3405 .release = snd_pcm_release,
3392 3406 .poll = snd_pcm_capture_poll,
3393 3407 .unlocked_ioctl = snd_pcm_capture_ioctl,
sound/core/rawmidi.c
... ... @@ -56,10 +56,22 @@
56 56 static int snd_rawmidi_dev_disconnect(struct snd_device *device);
57 57 static int snd_rawmidi_dev_unregister(struct snd_device *device);
58 58  
59   -static struct snd_rawmidi *snd_rawmidi_devices[SNDRV_CARDS * SNDRV_RAWMIDI_DEVICES];
60   -
  59 +static LIST_HEAD(snd_rawmidi_devices);
61 60 static DECLARE_MUTEX(register_mutex);
62 61  
  62 +static struct snd_rawmidi *snd_rawmidi_search(struct snd_card *card, int device)
  63 +{
  64 + struct list_head *p;
  65 + struct snd_rawmidi *rawmidi;
  66 +
  67 + list_for_each(p, &snd_rawmidi_devices) {
  68 + rawmidi = list_entry(p, struct snd_rawmidi, list);
  69 + if (rawmidi->card == card && rawmidi->device == device)
  70 + return rawmidi;
  71 + }
  72 + return NULL;
  73 +}
  74 +
63 75 static inline unsigned short snd_rawmidi_file_flags(struct file *file)
64 76 {
65 77 switch (file->f_mode & (FMODE_READ | FMODE_WRITE)) {
... ... @@ -214,7 +226,7 @@
214 226 return 0;
215 227 }
216 228  
217   -int snd_rawmidi_kernel_open(int cardnum, int device, int subdevice,
  229 +int snd_rawmidi_kernel_open(struct snd_card *card, int device, int subdevice,
218 230 int mode, struct snd_rawmidi_file * rfile)
219 231 {
220 232 struct snd_rawmidi *rmidi;
... ... @@ -225,7 +237,9 @@
225 237  
226 238 if (rfile)
227 239 rfile->input = rfile->output = NULL;
228   - rmidi = snd_rawmidi_devices[(cardnum * SNDRV_RAWMIDI_DEVICES) + device];
  240 + down(&register_mutex);
  241 + rmidi = snd_rawmidi_search(card, device);
  242 + up(&register_mutex);
229 243 if (rmidi == NULL) {
230 244 err = -ENODEV;
231 245 goto __error1;
232 246  
... ... @@ -368,9 +382,8 @@
368 382 static int snd_rawmidi_open(struct inode *inode, struct file *file)
369 383 {
370 384 int maj = imajor(inode);
371   - int cardnum;
372 385 struct snd_card *card;
373   - int device, subdevice;
  386 + int subdevice;
374 387 unsigned short fflags;
375 388 int err;
376 389 struct snd_rawmidi *rmidi;
377 390  
378 391  
379 392  
... ... @@ -380,27 +393,18 @@
380 393 struct snd_ctl_file *kctl;
381 394  
382 395 if (maj == snd_major) {
383   - cardnum = SNDRV_MINOR_CARD(iminor(inode));
384   - cardnum %= SNDRV_CARDS;
385   - device = SNDRV_MINOR_DEVICE(iminor(inode)) - SNDRV_MINOR_RAWMIDI;
386   - device %= SNDRV_MINOR_RAWMIDIS;
  396 + rmidi = snd_lookup_minor_data(iminor(inode),
  397 + SNDRV_DEVICE_TYPE_RAWMIDI);
387 398 #ifdef CONFIG_SND_OSSEMUL
388 399 } else if (maj == SOUND_MAJOR) {
389   - cardnum = SNDRV_MINOR_OSS_CARD(iminor(inode));
390   - cardnum %= SNDRV_CARDS;
391   - device = SNDRV_MINOR_OSS_DEVICE(iminor(inode)) == SNDRV_MINOR_OSS_MIDI ?
392   - midi_map[cardnum] : amidi_map[cardnum];
  400 + rmidi = snd_lookup_oss_minor_data(iminor(inode),
  401 + SNDRV_OSS_DEVICE_TYPE_MIDI);
393 402 #endif
394 403 } else
395 404 return -ENXIO;
396 405  
397   - rmidi = snd_rawmidi_devices[(cardnum * SNDRV_RAWMIDI_DEVICES) + device];
398 406 if (rmidi == NULL)
399 407 return -ENODEV;
400   -#ifdef CONFIG_SND_OSSEMUL
401   - if (maj == SOUND_MAJOR && !rmidi->ossreg)
402   - return -ENXIO;
403   -#endif
404 408 if ((file->f_flags & O_APPEND) && !(file->f_flags & O_NONBLOCK))
405 409 return -EINVAL; /* invalid combination */
406 410 card = rmidi->card;
... ... @@ -430,7 +434,8 @@
430 434 }
431 435 }
432 436 up_read(&card->controls_rwsem);
433   - err = snd_rawmidi_kernel_open(cardnum, device, subdevice, fflags, rawmidi_file);
  437 + err = snd_rawmidi_kernel_open(rmidi->card, rmidi->device,
  438 + subdevice, fflags, rawmidi_file);
434 439 if (err >= 0)
435 440 break;
436 441 if (err == -EAGAIN) {
... ... @@ -570,9 +575,10 @@
570 575 struct snd_rawmidi_str *pstr;
571 576 struct snd_rawmidi_substream *substream;
572 577 struct list_head *list;
573   - if (info->device >= SNDRV_RAWMIDI_DEVICES)
574   - return -ENXIO;
575   - rmidi = snd_rawmidi_devices[card->number * SNDRV_RAWMIDI_DEVICES + info->device];
  578 +
  579 + down(&register_mutex);
  580 + rmidi = snd_rawmidi_search(card, info->device);
  581 + up(&register_mutex);
576 582 if (!rmidi)
577 583 return -ENXIO;
578 584 if (info->stream < 0 || info->stream > 1)
579 585  
... ... @@ -803,9 +809,7 @@
803 809 unsigned long arg)
804 810 {
805 811 void __user *argp = (void __user *)arg;
806   - unsigned int tmp;
807 812  
808   - tmp = card->number * SNDRV_RAWMIDI_DEVICES;
809 813 switch (cmd) {
810 814 case SNDRV_CTL_IOCTL_RAWMIDI_NEXT_DEVICE:
811 815 {
812 816  
813 817  
... ... @@ -813,14 +817,16 @@
813 817  
814 818 if (get_user(device, (int __user *)argp))
815 819 return -EFAULT;
  820 + down(&register_mutex);
816 821 device = device < 0 ? 0 : device + 1;
817 822 while (device < SNDRV_RAWMIDI_DEVICES) {
818   - if (snd_rawmidi_devices[tmp + device])
  823 + if (snd_rawmidi_search(card, device))
819 824 break;
820 825 device++;
821 826 }
822 827 if (device == SNDRV_RAWMIDI_DEVICES)
823 828 device = -1;
  829 + up(&register_mutex);
824 830 if (put_user(device, (int __user *)argp))
825 831 return -EFAULT;
826 832 return 0;
... ... @@ -1493,7 +1499,7 @@
1493 1499  
1494 1500 static int snd_rawmidi_dev_register(struct snd_device *device)
1495 1501 {
1496   - int idx, err;
  1502 + int err;
1497 1503 struct snd_info_entry *entry;
1498 1504 char name[16];
1499 1505 struct snd_rawmidi *rmidi = device->device_data;
1500 1506  
1501 1507  
1502 1508  
1503 1509  
... ... @@ -1501,25 +1507,24 @@
1501 1507 if (rmidi->device >= SNDRV_RAWMIDI_DEVICES)
1502 1508 return -ENOMEM;
1503 1509 down(&register_mutex);
1504   - idx = (rmidi->card->number * SNDRV_RAWMIDI_DEVICES) + rmidi->device;
1505   - if (snd_rawmidi_devices[idx] != NULL) {
  1510 + if (snd_rawmidi_search(rmidi->card, rmidi->device)) {
1506 1511 up(&register_mutex);
1507 1512 return -EBUSY;
1508 1513 }
1509   - snd_rawmidi_devices[idx] = rmidi;
  1514 + list_add_tail(&rmidi->list, &snd_rawmidi_devices);
1510 1515 sprintf(name, "midiC%iD%i", rmidi->card->number, rmidi->device);
1511 1516 if ((err = snd_register_device(SNDRV_DEVICE_TYPE_RAWMIDI,
1512 1517 rmidi->card, rmidi->device,
1513   - &snd_rawmidi_f_ops, name)) < 0) {
  1518 + &snd_rawmidi_f_ops, rmidi, name)) < 0) {
1514 1519 snd_printk(KERN_ERR "unable to register rawmidi device %i:%i\n", rmidi->card->number, rmidi->device);
1515   - snd_rawmidi_devices[idx] = NULL;
  1520 + list_del(&rmidi->list);
1516 1521 up(&register_mutex);
1517 1522 return err;
1518 1523 }
1519 1524 if (rmidi->ops && rmidi->ops->dev_register &&
1520 1525 (err = rmidi->ops->dev_register(rmidi)) < 0) {
1521 1526 snd_unregister_device(SNDRV_DEVICE_TYPE_RAWMIDI, rmidi->card, rmidi->device);
1522   - snd_rawmidi_devices[idx] = NULL;
  1527 + list_del(&rmidi->list);
1523 1528 up(&register_mutex);
1524 1529 return err;
1525 1530 }
... ... @@ -1527,8 +1532,8 @@
1527 1532 rmidi->ossreg = 0;
1528 1533 if ((int)rmidi->device == midi_map[rmidi->card->number]) {
1529 1534 if (snd_register_oss_device(SNDRV_OSS_DEVICE_TYPE_MIDI,
1530   - rmidi->card, 0,
1531   - &snd_rawmidi_f_ops, name) < 0) {
  1535 + rmidi->card, 0, &snd_rawmidi_f_ops,
  1536 + rmidi, name) < 0) {
1532 1537 snd_printk(KERN_ERR "unable to register OSS rawmidi device %i:%i\n", rmidi->card->number, 0);
1533 1538 } else {
1534 1539 rmidi->ossreg++;
... ... @@ -1539,8 +1544,8 @@
1539 1544 }
1540 1545 if ((int)rmidi->device == amidi_map[rmidi->card->number]) {
1541 1546 if (snd_register_oss_device(SNDRV_OSS_DEVICE_TYPE_MIDI,
1542   - rmidi->card, 1,
1543   - &snd_rawmidi_f_ops, name) < 0) {
  1547 + rmidi->card, 1, &snd_rawmidi_f_ops,
  1548 + rmidi, name) < 0) {
1544 1549 snd_printk(KERN_ERR "unable to register OSS rawmidi device %i:%i\n", rmidi->card->number, 1);
1545 1550 } else {
1546 1551 rmidi->ossreg++;
1547 1552  
1548 1553  
1549 1554  
... ... @@ -1576,24 +1581,20 @@
1576 1581 static int snd_rawmidi_dev_disconnect(struct snd_device *device)
1577 1582 {
1578 1583 struct snd_rawmidi *rmidi = device->device_data;
1579   - int idx;
1580 1584  
1581 1585 down(&register_mutex);
1582   - idx = (rmidi->card->number * SNDRV_RAWMIDI_DEVICES) + rmidi->device;
1583   - snd_rawmidi_devices[idx] = NULL;
  1586 + list_del_init(&rmidi->list);
1584 1587 up(&register_mutex);
1585 1588 return 0;
1586 1589 }
1587 1590  
1588 1591 static int snd_rawmidi_dev_unregister(struct snd_device *device)
1589 1592 {
1590   - int idx;
1591 1593 struct snd_rawmidi *rmidi = device->device_data;
1592 1594  
1593 1595 snd_assert(rmidi != NULL, return -ENXIO);
1594 1596 down(&register_mutex);
1595   - idx = (rmidi->card->number * SNDRV_RAWMIDI_DEVICES) + rmidi->device;
1596   - snd_rawmidi_devices[idx] = NULL;
  1597 + list_del(&rmidi->list);
1597 1598 if (rmidi->proc_entry) {
1598 1599 snd_info_unregister(rmidi->proc_entry);
1599 1600 rmidi->proc_entry = NULL;
sound/core/seq/oss/seq_oss.c
... ... @@ -225,7 +225,7 @@
225 225 down(&register_mutex);
226 226 if ((rc = snd_register_oss_device(SNDRV_OSS_DEVICE_TYPE_SEQUENCER,
227 227 NULL, 0,
228   - &seq_oss_f_ops,
  228 + &seq_oss_f_ops, NULL,
229 229 SNDRV_SEQ_OSS_DEVNAME)) < 0) {
230 230 snd_printk(KERN_ERR "can't register device seq\n");
231 231 up(&register_mutex);
... ... @@ -233,7 +233,7 @@
233 233 }
234 234 if ((rc = snd_register_oss_device(SNDRV_OSS_DEVICE_TYPE_MUSIC,
235 235 NULL, 0,
236   - &seq_oss_f_ops,
  236 + &seq_oss_f_ops, NULL,
237 237 SNDRV_SEQ_OSS_DEVNAME)) < 0) {
238 238 snd_printk(KERN_ERR "can't register device music\n");
239 239 snd_unregister_oss_device(SNDRV_OSS_DEVICE_TYPE_SEQUENCER, NULL, 0);
sound/core/seq/seq_clientmgr.c
... ... @@ -2531,7 +2531,7 @@
2531 2531 return -ERESTARTSYS;
2532 2532  
2533 2533 if ((err = snd_register_device(SNDRV_DEVICE_TYPE_SEQUENCER, NULL, 0,
2534   - &snd_seq_f_ops, "seq")) < 0) {
  2534 + &snd_seq_f_ops, NULL, "seq")) < 0) {
2535 2535 up(&register_mutex);
2536 2536 return err;
2537 2537 }
sound/core/seq/seq_midi.c
... ... @@ -183,7 +183,10 @@
183 183 struct snd_rawmidi_params params;
184 184  
185 185 /* open midi port */
186   - if ((err = snd_rawmidi_kernel_open(msynth->card->number, msynth->device, msynth->subdevice, SNDRV_RAWMIDI_LFLG_INPUT, &msynth->input_rfile)) < 0) {
  186 + if ((err = snd_rawmidi_kernel_open(msynth->card, msynth->device,
  187 + msynth->subdevice,
  188 + SNDRV_RAWMIDI_LFLG_INPUT,
  189 + &msynth->input_rfile)) < 0) {
187 190 snd_printd("midi input open failed!!!\n");
188 191 return err;
189 192 }
... ... @@ -221,7 +224,10 @@
221 224 struct snd_rawmidi_params params;
222 225  
223 226 /* open midi port */
224   - if ((err = snd_rawmidi_kernel_open(msynth->card->number, msynth->device, msynth->subdevice, SNDRV_RAWMIDI_LFLG_OUTPUT, &msynth->output_rfile)) < 0) {
  227 + if ((err = snd_rawmidi_kernel_open(msynth->card, msynth->device,
  228 + msynth->subdevice,
  229 + SNDRV_RAWMIDI_LFLG_OUTPUT,
  230 + &msynth->output_rfile)) < 0) {
225 231 snd_printd("midi output open failed!!!\n");
226 232 return err;
227 233 }
... ... @@ -60,7 +60,6 @@
60 60 int snd_ecards_limit;
61 61  
62 62 static struct snd_minor *snd_minors[SNDRV_OS_MINORS];
63   -
64 63 static DECLARE_MUTEX(sound_mutex);
65 64  
66 65 extern struct class *sound_class;
... ... @@ -107,6 +106,31 @@
107 106  
108 107 #endif /* request_module support */
109 108  
  109 +/**
  110 + * snd_lookup_minor_data - get user data of a registered device
  111 + * @minor: the minor number
  112 + * @type: device type (SNDRV_DEVICE_TYPE_XXX)
  113 + *
  114 + * Checks that a minor device with the specified type is registered, and returns
  115 + * its user data pointer.
  116 + */
  117 +void *snd_lookup_minor_data(unsigned int minor, int type)
  118 +{
  119 + struct snd_minor *mreg;
  120 + void *private_data;
  121 +
  122 + if (minor > ARRAY_SIZE(snd_minors))
  123 + return NULL;
  124 + down(&sound_mutex);
  125 + mreg = snd_minors[minor];
  126 + if (mreg && mreg->type == type)
  127 + private_data = mreg->private_data;
  128 + else
  129 + private_data = NULL;
  130 + up(&sound_mutex);
  131 + return private_data;
  132 +}
  133 +
110 134 static int snd_open(struct inode *inode, struct file *file)
111 135 {
112 136 int minor = iminor(inode);
... ... @@ -183,6 +207,7 @@
183 207 * @card: the card instance
184 208 * @dev: the device index
185 209 * @f_ops: the file operations
  210 + * @private_data: user pointer for f_ops->open()
186 211 * @name: the device file name
187 212 *
188 213 * Registers an ALSA device file for the given card.
... ... @@ -191,7 +216,8 @@
191 216 * Retrurns zero if successful, or a negative error code on failure.
192 217 */
193 218 int snd_register_device(int type, struct snd_card *card, int dev,
194   - struct file_operations *f_ops, const char *name)
  219 + struct file_operations *f_ops, void *private_data,
  220 + const char *name)
195 221 {
196 222 int minor = snd_kernel_minor(type, card, dev);
197 223 struct snd_minor *preg;
... ... @@ -207,6 +233,7 @@
207 233 preg->card = card ? card->number : -1;
208 234 preg->device = dev;
209 235 preg->f_ops = f_ops;
  236 + preg->private_data = private_data;
210 237 strcpy(preg->name, name);
211 238 down(&sound_mutex);
212 239 if (snd_minors[minor]) {
213 240  
214 241  
... ... @@ -238,13 +265,18 @@
238 265 */
239 266 int snd_unregister_device(int type, struct snd_card *card, int dev)
240 267 {
241   - int minor = snd_kernel_minor(type, card, dev);
  268 + int cardnum, minor;
242 269 struct snd_minor *mptr;
243 270  
244   - if (minor < 0)
245   - return minor;
  271 + cardnum = card ? card->number : -1;
246 272 down(&sound_mutex);
247   - if ((mptr = snd_minors[minor]) == NULL) {
  273 + for (minor = 0; minor < ARRAY_SIZE(snd_minors); ++minor)
  274 + if ((mptr = snd_minors[minor]) != NULL &&
  275 + mptr->type == type &&
  276 + mptr->card == cardnum &&
  277 + mptr->device == dev)
  278 + break;
  279 + if (minor == ARRAY_SIZE(snd_minors)) {
248 280 up(&sound_mutex);
249 281 return -EINVAL;
250 282 }
251 283  
... ... @@ -392,9 +424,11 @@
392 424 #endif
393 425 EXPORT_SYMBOL(snd_register_device);
394 426 EXPORT_SYMBOL(snd_unregister_device);
  427 +EXPORT_SYMBOL(snd_lookup_minor_data);
395 428 #if defined(CONFIG_SND_OSSEMUL)
396 429 EXPORT_SYMBOL(snd_register_oss_device);
397 430 EXPORT_SYMBOL(snd_unregister_oss_device);
  431 +EXPORT_SYMBOL(snd_lookup_oss_minor_data);
398 432 #endif
399 433 /* memory.c */
400 434 EXPORT_SYMBOL(copy_to_user_fromio);
sound/core/sound_oss.c
... ... @@ -38,9 +38,25 @@
38 38 #define SNDRV_OSS_MINORS 128
39 39  
40 40 static struct snd_minor *snd_oss_minors[SNDRV_OSS_MINORS];
41   -
42 41 static DECLARE_MUTEX(sound_oss_mutex);
43 42  
  43 +void *snd_lookup_oss_minor_data(unsigned int minor, int type)
  44 +{
  45 + struct snd_minor *mreg;
  46 + void *private_data;
  47 +
  48 + if (minor > ARRAY_SIZE(snd_oss_minors))
  49 + return NULL;
  50 + down(&sound_oss_mutex);
  51 + mreg = snd_oss_minors[minor];
  52 + if (mreg && mreg->type == type)
  53 + private_data = mreg->private_data;
  54 + else
  55 + private_data = NULL;
  56 + up(&sound_oss_mutex);
  57 + return private_data;
  58 +}
  59 +
44 60 static int snd_oss_kernel_minor(int type, struct snd_card *card, int dev)
45 61 {
46 62 int minor;
... ... @@ -78,7 +94,8 @@
78 94 }
79 95  
80 96 int snd_register_oss_device(int type, struct snd_card *card, int dev,
81   - struct file_operations *f_ops, const char *name)
  97 + struct file_operations *f_ops, void *private_data,
  98 + const char *name)
82 99 {
83 100 int minor = snd_oss_kernel_minor(type, card, dev);
84 101 int minor_unit;
... ... @@ -97,6 +114,7 @@
97 114 preg->card = card ? card->number : -1;
98 115 preg->device = dev;
99 116 preg->f_ops = f_ops;
  117 + preg->private_data = private_data;
100 118 down(&sound_oss_mutex);
101 119 snd_oss_minors[minor] = preg;
102 120 minor_unit = SNDRV_MINOR_OSS_DEVICE(minor);
... ... @@ -121,6 +139,7 @@
121 139 carddev);
122 140 if (register2 != track2)
123 141 goto __end;
  142 + snd_oss_minors[track2] = preg;
124 143 }
125 144 up(&sound_oss_mutex);
126 145 return 0;
127 146  
... ... @@ -163,8 +182,10 @@
163 182 track2 = SNDRV_MINOR_OSS(cidx, SNDRV_MINOR_OSS_DMMIDI1);
164 183 break;
165 184 }
166   - if (track2 >= 0)
  185 + if (track2 >= 0) {
167 186 unregister_sound_special(track2);
  187 + snd_oss_minors[track2] = NULL;
  188 + }
168 189 snd_oss_minors[minor] = NULL;
169 190 up(&sound_oss_mutex);
170 191 kfree(mptr);
... ... @@ -1952,8 +1952,8 @@
1952 1952 if ((err = snd_timer_register_system()) < 0)
1953 1953 snd_printk(KERN_ERR "unable to register system timer (%i)\n",
1954 1954 err);
1955   - if ((err = snd_register_device(SNDRV_DEVICE_TYPE_TIMER,
1956   - NULL, 0, &snd_timer_f_ops, "timer")) < 0)
  1955 + if ((err = snd_register_device(SNDRV_DEVICE_TYPE_TIMER, NULL, 0,
  1956 + &snd_timer_f_ops, NULL, "timer")) < 0)
1957 1957 snd_printk(KERN_ERR "unable to register timer device (%i)\n",
1958 1958 err);
1959 1959 return 0;