@@ -424,6 +424,10 @@ static int snd_rawmidi_open(struct inode *inode, struct file *file)
424424 mutex_unlock (& rmidi -> open_mutex );
425425 schedule ();
426426 mutex_lock (& rmidi -> open_mutex );
427+ if (rmidi -> card -> shutdown ) {
428+ err = - ENODEV ;
429+ break ;
430+ }
427431 if (signal_pending (current )) {
428432 err = - ERESTARTSYS ;
429433 break ;
@@ -995,6 +999,8 @@ static ssize_t snd_rawmidi_read(struct file *file, char __user *buf, size_t coun
995999 spin_unlock_irq (& runtime -> lock );
9961000 schedule ();
9971001 remove_wait_queue (& runtime -> sleep , & wait );
1002+ if (rfile -> rmidi -> card -> shutdown )
1003+ return - ENODEV ;
9981004 if (signal_pending (current ))
9991005 return result > 0 ? result : - ERESTARTSYS ;
10001006 if (!runtime -> avail )
@@ -1238,6 +1244,8 @@ static ssize_t snd_rawmidi_write(struct file *file, const char __user *buf,
12381244 spin_unlock_irq (& runtime -> lock );
12391245 timeout = schedule_timeout (30 * HZ );
12401246 remove_wait_queue (& runtime -> sleep , & wait );
1247+ if (rfile -> rmidi -> card -> shutdown )
1248+ return - ENODEV ;
12411249 if (signal_pending (current ))
12421250 return result > 0 ? result : - ERESTARTSYS ;
12431251 if (!runtime -> avail && !timeout )
@@ -1613,9 +1621,20 @@ static int snd_rawmidi_dev_register(struct snd_device *device)
16131621static int snd_rawmidi_dev_disconnect (struct snd_device * device )
16141622{
16151623 struct snd_rawmidi * rmidi = device -> device_data ;
1624+ int dir ;
16161625
16171626 mutex_lock (& register_mutex );
1627+ mutex_lock (& rmidi -> open_mutex );
1628+ wake_up (& rmidi -> open_wait );
16181629 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+
16191638#ifdef CONFIG_SND_OSSEMUL
16201639 if (rmidi -> ossreg ) {
16211640 if ((int )rmidi -> device == midi_map [rmidi -> card -> number ]) {
@@ -1630,6 +1649,7 @@ static int snd_rawmidi_dev_disconnect(struct snd_device *device)
16301649 }
16311650#endif /* CONFIG_SND_OSSEMUL */
16321651 snd_unregister_device (SNDRV_DEVICE_TYPE_RAWMIDI , rmidi -> card , rmidi -> device );
1652+ mutex_unlock (& rmidi -> open_mutex );
16331653 mutex_unlock (& register_mutex );
16341654 return 0 ;
16351655}
0 commit comments