aboutsummaryrefslogtreecommitdiffstats
path: root/sound/core/rawmidi.c
diff options
context:
space:
mode:
Diffstat (limited to 'sound/core/rawmidi.c')
-rw-r--r--sound/core/rawmidi.c26
1 files changed, 25 insertions, 1 deletions
diff --git a/sound/core/rawmidi.c b/sound/core/rawmidi.c
index ebf6e49ad3d4..1bb95aeea084 100644
--- a/sound/core/rawmidi.c
+++ b/sound/core/rawmidi.c
@@ -379,8 +379,10 @@ static int snd_rawmidi_open(struct inode *inode, struct file *file)
379 if (rmidi == NULL) 379 if (rmidi == NULL)
380 return -ENODEV; 380 return -ENODEV;
381 381
382 if (!try_module_get(rmidi->card->module)) 382 if (!try_module_get(rmidi->card->module)) {
383 snd_card_unref(rmidi->card);
383 return -ENXIO; 384 return -ENXIO;
385 }
384 386
385 mutex_lock(&rmidi->open_mutex); 387 mutex_lock(&rmidi->open_mutex);
386 card = rmidi->card; 388 card = rmidi->card;
@@ -422,6 +424,10 @@ static int snd_rawmidi_open(struct inode *inode, struct file *file)
422 mutex_unlock(&rmidi->open_mutex); 424 mutex_unlock(&rmidi->open_mutex);
423 schedule(); 425 schedule();
424 mutex_lock(&rmidi->open_mutex); 426 mutex_lock(&rmidi->open_mutex);
427 if (rmidi->card->shutdown) {
428 err = -ENODEV;
429 break;
430 }
425 if (signal_pending(current)) { 431 if (signal_pending(current)) {
426 err = -ERESTARTSYS; 432 err = -ERESTARTSYS;
427 break; 433 break;
@@ -440,6 +446,7 @@ static int snd_rawmidi_open(struct inode *inode, struct file *file)
440#endif 446#endif
441 file->private_data = rawmidi_file; 447 file->private_data = rawmidi_file;
442 mutex_unlock(&rmidi->open_mutex); 448 mutex_unlock(&rmidi->open_mutex);
449 snd_card_unref(rmidi->card);
443 return 0; 450 return 0;
444 451
445 __error: 452 __error:
@@ -447,6 +454,7 @@ static int snd_rawmidi_open(struct inode *inode, struct file *file)
447 __error_card: 454 __error_card:
448 mutex_unlock(&rmidi->open_mutex); 455 mutex_unlock(&rmidi->open_mutex);
449 module_put(rmidi->card->module); 456 module_put(rmidi->card->module);
457 snd_card_unref(rmidi->card);
450 return err; 458 return err;
451} 459}
452 460
@@ -991,6 +999,8 @@ static ssize_t snd_rawmidi_read(struct file *file, char __user *buf, size_t coun
991 spin_unlock_irq(&runtime->lock); 999 spin_unlock_irq(&runtime->lock);
992 schedule(); 1000 schedule();
993 remove_wait_queue(&runtime->sleep, &wait); 1001 remove_wait_queue(&runtime->sleep, &wait);
1002 if (rfile->rmidi->card->shutdown)
1003 return -ENODEV;
994 if (signal_pending(current)) 1004 if (signal_pending(current))
995 return result > 0 ? result : -ERESTARTSYS; 1005 return result > 0 ? result : -ERESTARTSYS;
996 if (!runtime->avail) 1006 if (!runtime->avail)
@@ -1234,6 +1244,8 @@ static ssize_t snd_rawmidi_write(struct file *file, const char __user *buf,
1234 spin_unlock_irq(&runtime->lock); 1244 spin_unlock_irq(&runtime->lock);
1235 timeout = schedule_timeout(30 * HZ); 1245 timeout = schedule_timeout(30 * HZ);
1236 remove_wait_queue(&runtime->sleep, &wait); 1246 remove_wait_queue(&runtime->sleep, &wait);
1247 if (rfile->rmidi->card->shutdown)
1248 return -ENODEV;
1237 if (signal_pending(current)) 1249 if (signal_pending(current))
1238 return result > 0 ? result : -ERESTARTSYS; 1250 return result > 0 ? result : -ERESTARTSYS;
1239 if (!runtime->avail && !timeout) 1251 if (!runtime->avail && !timeout)
@@ -1609,9 +1621,20 @@ static int snd_rawmidi_dev_register(struct snd_device *device)
1609static int snd_rawmidi_dev_disconnect(struct snd_device *device) 1621static int snd_rawmidi_dev_disconnect(struct snd_device *device)
1610{ 1622{
1611 struct snd_rawmidi *rmidi = device->device_data; 1623 struct snd_rawmidi *rmidi = device->device_data;
1624 int dir;
1612 1625
1613 mutex_lock(&register_mutex); 1626 mutex_lock(&register_mutex);
1627 mutex_lock(&rmidi->open_mutex);
1628 wake_up(&rmidi->open_wait);
1614 list_del_init(&rmidi->list); 1629 list_del_init(&rmidi->list);
1630 for (dir = 0; dir < 2; dir++) {
1631 struct snd_rawmidi_substream *s;
1632 list_for_each_entry(s, &rmidi->streams[dir].substreams, list) {
1633 if (s->runtime)
1634 wake_up(&s->runtime->sleep);
1635 }
1636 }
1637
1615#ifdef CONFIG_SND_OSSEMUL 1638#ifdef CONFIG_SND_OSSEMUL
1616 if (rmidi->ossreg) { 1639 if (rmidi->ossreg) {
1617 if ((int)rmidi->device == midi_map[rmidi->card->number]) { 1640 if ((int)rmidi->device == midi_map[rmidi->card->number]) {
@@ -1626,6 +1649,7 @@ static int snd_rawmidi_dev_disconnect(struct snd_device *device)
1626 } 1649 }
1627#endif /* CONFIG_SND_OSSEMUL */ 1650#endif /* CONFIG_SND_OSSEMUL */
1628 snd_unregister_device(SNDRV_DEVICE_TYPE_RAWMIDI, rmidi->card, rmidi->device); 1651 snd_unregister_device(SNDRV_DEVICE_TYPE_RAWMIDI, rmidi->card, rmidi->device);
1652 mutex_unlock(&rmidi->open_mutex);
1629 mutex_unlock(&register_mutex); 1653 mutex_unlock(&register_mutex);
1630 return 0; 1654 return 0;
1631} 1655}