aboutsummaryrefslogtreecommitdiffstats
path: root/sound/core/rawmidi.c
diff options
context:
space:
mode:
authorClemens Ladisch <clemens@ladisch.de>2005-11-20 08:06:59 -0500
committerJaroslav Kysela <perex@suse.cz>2006-01-03 06:29:17 -0500
commitf87135f56cb266e031f5ec081dfbde7e43f55e80 (patch)
treec048abae6bb04df53f5d8d7dcffbf2c28bc638ff /sound/core/rawmidi.c
parent6983b7240cd229787c3ee00e663ea94ea649d96a (diff)
[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>
Diffstat (limited to 'sound/core/rawmidi.c')
-rw-r--r--sound/core/rawmidi.c87
1 files changed, 44 insertions, 43 deletions
diff --git a/sound/core/rawmidi.c b/sound/core/rawmidi.c
index 7ac77e5ddcb1..e6ee0d813783 100644
--- a/sound/core/rawmidi.c
+++ b/sound/core/rawmidi.c
@@ -56,10 +56,22 @@ static int snd_rawmidi_dev_register(struct snd_device *device);
56static int snd_rawmidi_dev_disconnect(struct snd_device *device); 56static int snd_rawmidi_dev_disconnect(struct snd_device *device);
57static int snd_rawmidi_dev_unregister(struct snd_device *device); 57static int snd_rawmidi_dev_unregister(struct snd_device *device);
58 58
59static struct snd_rawmidi *snd_rawmidi_devices[SNDRV_CARDS * SNDRV_RAWMIDI_DEVICES]; 59static LIST_HEAD(snd_rawmidi_devices);
60
61static DECLARE_MUTEX(register_mutex); 60static DECLARE_MUTEX(register_mutex);
62 61
62static 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
63static inline unsigned short snd_rawmidi_file_flags(struct file *file) 75static inline unsigned short snd_rawmidi_file_flags(struct file *file)
64{ 76{
65 switch (file->f_mode & (FMODE_READ | FMODE_WRITE)) { 77 switch (file->f_mode & (FMODE_READ | FMODE_WRITE)) {
@@ -214,7 +226,7 @@ int snd_rawmidi_drain_input(struct snd_rawmidi_substream *substream)
214 return 0; 226 return 0;
215} 227}
216 228
217int snd_rawmidi_kernel_open(int cardnum, int device, int subdevice, 229int snd_rawmidi_kernel_open(struct snd_card *card, int device, int subdevice,
218 int mode, struct snd_rawmidi_file * rfile) 230 int mode, struct snd_rawmidi_file * rfile)
219{ 231{
220 struct snd_rawmidi *rmidi; 232 struct snd_rawmidi *rmidi;
@@ -225,7 +237,9 @@ int snd_rawmidi_kernel_open(int cardnum, int device, int subdevice,
225 237
226 if (rfile) 238 if (rfile)
227 rfile->input = rfile->output = NULL; 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 if (rmidi == NULL) { 243 if (rmidi == NULL) {
230 err = -ENODEV; 244 err = -ENODEV;
231 goto __error1; 245 goto __error1;
@@ -368,9 +382,8 @@ int snd_rawmidi_kernel_open(int cardnum, int device, int subdevice,
368static int snd_rawmidi_open(struct inode *inode, struct file *file) 382static int snd_rawmidi_open(struct inode *inode, struct file *file)
369{ 383{
370 int maj = imajor(inode); 384 int maj = imajor(inode);
371 int cardnum;
372 struct snd_card *card; 385 struct snd_card *card;
373 int device, subdevice; 386 int subdevice;
374 unsigned short fflags; 387 unsigned short fflags;
375 int err; 388 int err;
376 struct snd_rawmidi *rmidi; 389 struct snd_rawmidi *rmidi;
@@ -380,27 +393,18 @@ static int snd_rawmidi_open(struct inode *inode, struct file *file)
380 struct snd_ctl_file *kctl; 393 struct snd_ctl_file *kctl;
381 394
382 if (maj == snd_major) { 395 if (maj == snd_major) {
383 cardnum = SNDRV_MINOR_CARD(iminor(inode)); 396 rmidi = snd_lookup_minor_data(iminor(inode),
384 cardnum %= SNDRV_CARDS; 397 SNDRV_DEVICE_TYPE_RAWMIDI);
385 device = SNDRV_MINOR_DEVICE(iminor(inode)) - SNDRV_MINOR_RAWMIDI;
386 device %= SNDRV_MINOR_RAWMIDIS;
387#ifdef CONFIG_SND_OSSEMUL 398#ifdef CONFIG_SND_OSSEMUL
388 } else if (maj == SOUND_MAJOR) { 399 } else if (maj == SOUND_MAJOR) {
389 cardnum = SNDRV_MINOR_OSS_CARD(iminor(inode)); 400 rmidi = snd_lookup_oss_minor_data(iminor(inode),
390 cardnum %= SNDRV_CARDS; 401 SNDRV_OSS_DEVICE_TYPE_MIDI);
391 device = SNDRV_MINOR_OSS_DEVICE(iminor(inode)) == SNDRV_MINOR_OSS_MIDI ?
392 midi_map[cardnum] : amidi_map[cardnum];
393#endif 402#endif
394 } else 403 } else
395 return -ENXIO; 404 return -ENXIO;
396 405
397 rmidi = snd_rawmidi_devices[(cardnum * SNDRV_RAWMIDI_DEVICES) + device];
398 if (rmidi == NULL) 406 if (rmidi == NULL)
399 return -ENODEV; 407 return -ENODEV;
400#ifdef CONFIG_SND_OSSEMUL
401 if (maj == SOUND_MAJOR && !rmidi->ossreg)
402 return -ENXIO;
403#endif
404 if ((file->f_flags & O_APPEND) && !(file->f_flags & O_NONBLOCK)) 408 if ((file->f_flags & O_APPEND) && !(file->f_flags & O_NONBLOCK))
405 return -EINVAL; /* invalid combination */ 409 return -EINVAL; /* invalid combination */
406 card = rmidi->card; 410 card = rmidi->card;
@@ -430,7 +434,8 @@ static int snd_rawmidi_open(struct inode *inode, struct file *file)
430 } 434 }
431 } 435 }
432 up_read(&card->controls_rwsem); 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 if (err >= 0) 439 if (err >= 0)
435 break; 440 break;
436 if (err == -EAGAIN) { 441 if (err == -EAGAIN) {
@@ -570,9 +575,10 @@ int snd_rawmidi_info_select(struct snd_card *card, struct snd_rawmidi_info *info
570 struct snd_rawmidi_str *pstr; 575 struct snd_rawmidi_str *pstr;
571 struct snd_rawmidi_substream *substream; 576 struct snd_rawmidi_substream *substream;
572 struct list_head *list; 577 struct list_head *list;
573 if (info->device >= SNDRV_RAWMIDI_DEVICES) 578
574 return -ENXIO; 579 down(&register_mutex);
575 rmidi = snd_rawmidi_devices[card->number * SNDRV_RAWMIDI_DEVICES + info->device]; 580 rmidi = snd_rawmidi_search(card, info->device);
581 up(&register_mutex);
576 if (!rmidi) 582 if (!rmidi)
577 return -ENXIO; 583 return -ENXIO;
578 if (info->stream < 0 || info->stream > 1) 584 if (info->stream < 0 || info->stream > 1)
@@ -803,9 +809,7 @@ static int snd_rawmidi_control_ioctl(struct snd_card *card,
803 unsigned long arg) 809 unsigned long arg)
804{ 810{
805 void __user *argp = (void __user *)arg; 811 void __user *argp = (void __user *)arg;
806 unsigned int tmp;
807 812
808 tmp = card->number * SNDRV_RAWMIDI_DEVICES;
809 switch (cmd) { 813 switch (cmd) {
810 case SNDRV_CTL_IOCTL_RAWMIDI_NEXT_DEVICE: 814 case SNDRV_CTL_IOCTL_RAWMIDI_NEXT_DEVICE:
811 { 815 {
@@ -813,14 +817,16 @@ static int snd_rawmidi_control_ioctl(struct snd_card *card,
813 817
814 if (get_user(device, (int __user *)argp)) 818 if (get_user(device, (int __user *)argp))
815 return -EFAULT; 819 return -EFAULT;
820 down(&register_mutex);
816 device = device < 0 ? 0 : device + 1; 821 device = device < 0 ? 0 : device + 1;
817 while (device < SNDRV_RAWMIDI_DEVICES) { 822 while (device < SNDRV_RAWMIDI_DEVICES) {
818 if (snd_rawmidi_devices[tmp + device]) 823 if (snd_rawmidi_search(card, device))
819 break; 824 break;
820 device++; 825 device++;
821 } 826 }
822 if (device == SNDRV_RAWMIDI_DEVICES) 827 if (device == SNDRV_RAWMIDI_DEVICES)
823 device = -1; 828 device = -1;
829 up(&register_mutex);
824 if (put_user(device, (int __user *)argp)) 830 if (put_user(device, (int __user *)argp))
825 return -EFAULT; 831 return -EFAULT;
826 return 0; 832 return 0;
@@ -1493,7 +1499,7 @@ static void snd_rawmidi_dev_seq_free(struct snd_seq_device *device)
1493 1499
1494static int snd_rawmidi_dev_register(struct snd_device *device) 1500static int snd_rawmidi_dev_register(struct snd_device *device)
1495{ 1501{
1496 int idx, err; 1502 int err;
1497 struct snd_info_entry *entry; 1503 struct snd_info_entry *entry;
1498 char name[16]; 1504 char name[16];
1499 struct snd_rawmidi *rmidi = device->device_data; 1505 struct snd_rawmidi *rmidi = device->device_data;
@@ -1501,25 +1507,24 @@ static int snd_rawmidi_dev_register(struct snd_device *device)
1501 if (rmidi->device >= SNDRV_RAWMIDI_DEVICES) 1507 if (rmidi->device >= SNDRV_RAWMIDI_DEVICES)
1502 return -ENOMEM; 1508 return -ENOMEM;
1503 down(&register_mutex); 1509 down(&register_mutex);
1504 idx = (rmidi->card->number * SNDRV_RAWMIDI_DEVICES) + rmidi->device; 1510 if (snd_rawmidi_search(rmidi->card, rmidi->device)) {
1505 if (snd_rawmidi_devices[idx] != NULL) {
1506 up(&register_mutex); 1511 up(&register_mutex);
1507 return -EBUSY; 1512 return -EBUSY;
1508 } 1513 }
1509 snd_rawmidi_devices[idx] = rmidi; 1514 list_add_tail(&rmidi->list, &snd_rawmidi_devices);
1510 sprintf(name, "midiC%iD%i", rmidi->card->number, rmidi->device); 1515 sprintf(name, "midiC%iD%i", rmidi->card->number, rmidi->device);
1511 if ((err = snd_register_device(SNDRV_DEVICE_TYPE_RAWMIDI, 1516 if ((err = snd_register_device(SNDRV_DEVICE_TYPE_RAWMIDI,
1512 rmidi->card, rmidi->device, 1517 rmidi->card, rmidi->device,
1513 &snd_rawmidi_f_ops, name)) < 0) { 1518 &snd_rawmidi_f_ops, rmidi, name)) < 0) {
1514 snd_printk(KERN_ERR "unable to register rawmidi device %i:%i\n", rmidi->card->number, rmidi->device); 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 up(&register_mutex); 1521 up(&register_mutex);
1517 return err; 1522 return err;
1518 } 1523 }
1519 if (rmidi->ops && rmidi->ops->dev_register && 1524 if (rmidi->ops && rmidi->ops->dev_register &&
1520 (err = rmidi->ops->dev_register(rmidi)) < 0) { 1525 (err = rmidi->ops->dev_register(rmidi)) < 0) {
1521 snd_unregister_device(SNDRV_DEVICE_TYPE_RAWMIDI, rmidi->card, rmidi->device); 1526 snd_unregister_device(SNDRV_DEVICE_TYPE_RAWMIDI, rmidi->card, rmidi->device);
1522 snd_rawmidi_devices[idx] = NULL; 1527 list_del(&rmidi->list);
1523 up(&register_mutex); 1528 up(&register_mutex);
1524 return err; 1529 return err;
1525 } 1530 }
@@ -1527,8 +1532,8 @@ static int snd_rawmidi_dev_register(struct snd_device *device)
1527 rmidi->ossreg = 0; 1532 rmidi->ossreg = 0;
1528 if ((int)rmidi->device == midi_map[rmidi->card->number]) { 1533 if ((int)rmidi->device == midi_map[rmidi->card->number]) {
1529 if (snd_register_oss_device(SNDRV_OSS_DEVICE_TYPE_MIDI, 1534 if (snd_register_oss_device(SNDRV_OSS_DEVICE_TYPE_MIDI,
1530 rmidi->card, 0, 1535 rmidi->card, 0, &snd_rawmidi_f_ops,
1531 &snd_rawmidi_f_ops, name) < 0) { 1536 rmidi, name) < 0) {
1532 snd_printk(KERN_ERR "unable to register OSS rawmidi device %i:%i\n", rmidi->card->number, 0); 1537 snd_printk(KERN_ERR "unable to register OSS rawmidi device %i:%i\n", rmidi->card->number, 0);
1533 } else { 1538 } else {
1534 rmidi->ossreg++; 1539 rmidi->ossreg++;
@@ -1539,8 +1544,8 @@ static int snd_rawmidi_dev_register(struct snd_device *device)
1539 } 1544 }
1540 if ((int)rmidi->device == amidi_map[rmidi->card->number]) { 1545 if ((int)rmidi->device == amidi_map[rmidi->card->number]) {
1541 if (snd_register_oss_device(SNDRV_OSS_DEVICE_TYPE_MIDI, 1546 if (snd_register_oss_device(SNDRV_OSS_DEVICE_TYPE_MIDI,
1542 rmidi->card, 1, 1547 rmidi->card, 1, &snd_rawmidi_f_ops,
1543 &snd_rawmidi_f_ops, name) < 0) { 1548 rmidi, name) < 0) {
1544 snd_printk(KERN_ERR "unable to register OSS rawmidi device %i:%i\n", rmidi->card->number, 1); 1549 snd_printk(KERN_ERR "unable to register OSS rawmidi device %i:%i\n", rmidi->card->number, 1);
1545 } else { 1550 } else {
1546 rmidi->ossreg++; 1551 rmidi->ossreg++;
@@ -1576,24 +1581,20 @@ static int snd_rawmidi_dev_register(struct snd_device *device)
1576static int snd_rawmidi_dev_disconnect(struct snd_device *device) 1581static int snd_rawmidi_dev_disconnect(struct snd_device *device)
1577{ 1582{
1578 struct snd_rawmidi *rmidi = device->device_data; 1583 struct snd_rawmidi *rmidi = device->device_data;
1579 int idx;
1580 1584
1581 down(&register_mutex); 1585 down(&register_mutex);
1582 idx = (rmidi->card->number * SNDRV_RAWMIDI_DEVICES) + rmidi->device; 1586 list_del_init(&rmidi->list);
1583 snd_rawmidi_devices[idx] = NULL;
1584 up(&register_mutex); 1587 up(&register_mutex);
1585 return 0; 1588 return 0;
1586} 1589}
1587 1590
1588static int snd_rawmidi_dev_unregister(struct snd_device *device) 1591static int snd_rawmidi_dev_unregister(struct snd_device *device)
1589{ 1592{
1590 int idx;
1591 struct snd_rawmidi *rmidi = device->device_data; 1593 struct snd_rawmidi *rmidi = device->device_data;
1592 1594
1593 snd_assert(rmidi != NULL, return -ENXIO); 1595 snd_assert(rmidi != NULL, return -ENXIO);
1594 down(&register_mutex); 1596 down(&register_mutex);
1595 idx = (rmidi->card->number * SNDRV_RAWMIDI_DEVICES) + rmidi->device; 1597 list_del(&rmidi->list);
1596 snd_rawmidi_devices[idx] = NULL;
1597 if (rmidi->proc_entry) { 1598 if (rmidi->proc_entry) {
1598 snd_info_unregister(rmidi->proc_entry); 1599 snd_info_unregister(rmidi->proc_entry);
1599 rmidi->proc_entry = NULL; 1600 rmidi->proc_entry = NULL;