unsigned int dma_buf_id;
        size_t dma_max;
        /* -- hardware operations -- */
-       unsigned int open_flag: 1;      /* lowlevel device has been opened */
        snd_pcm_ops_t *ops;
        /* -- runtime information -- */
        snd_pcm_runtime_t *runtime;
 
                if (snd_pcm_running(substream))
                        snd_pcm_stop(substream, SNDRV_PCM_STATE_SETUP);
                snd_pcm_stream_unlock_irq(substream);
-               if (substream->open_flag) {
+               if (substream->ffile != NULL) {
                        if (substream->ops->hw_free != NULL)
                                substream->ops->hw_free(substream);
                        substream->ops->close(substream);
-                       substream->open_flag = 0;
+                       substream->ffile = NULL;
                }
-               substream->ffile = NULL;
                snd_pcm_oss_release_substream(substream);
                snd_pcm_release_substream(substream);
        }
                        snd_pcm_oss_release_file(pcm_oss_file);
                        return err;
                }
-               psubstream->open_flag = 1;
+               psubstream->ffile = file;
                err = snd_pcm_hw_constraints_complete(psubstream);
                if (err < 0) {
                        snd_printd("snd_pcm_hw_constraint_complete failed\n");
                        snd_pcm_oss_release_file(pcm_oss_file);
                        return err;
                }
-               psubstream->ffile = file;
                snd_pcm_oss_init_substream(psubstream, psetup, minor);
        }
        if (csubstream != NULL) {
                        snd_pcm_oss_release_file(pcm_oss_file);
                        return err;
                }
-               csubstream->open_flag = 1;
+               csubstream->ffile = file;
                err = snd_pcm_hw_constraints_complete(csubstream);
                if (err < 0) {
                        snd_printd("snd_pcm_hw_constraint_complete failed\n");
                        snd_pcm_oss_release_file(pcm_oss_file);
                        return err;
                }
-               csubstream->ffile = file;
                snd_pcm_oss_init_substream(csubstream, csetup, minor);
        }
 
 
                if (((avail < runtime->control->avail_min && size > avail) ||
                   (size >= runtime->xfer_align && avail < runtime->xfer_align))) {
                        wait_queue_t wait;
-                       enum { READY, SIGNALED, ERROR, SUSPENDED, EXPIRED } state;
+                       enum { READY, SIGNALED, ERROR, SUSPENDED, EXPIRED, DROPPED } state;
                        long tout;
 
                        if (nonblock) {
                                case SNDRV_PCM_STATE_SUSPENDED:
                                        state = SUSPENDED;
                                        goto _end_loop;
+                               case SNDRV_PCM_STATE_SETUP:
+                                       state = DROPPED;
+                                       goto _end_loop;
                                default:
                                        break;
                                }
                                snd_printd("playback write error (DMA or IRQ trouble?)\n");
                                err = -EIO;
                                goto _end_unlock;
+                       case DROPPED:
+                               err = -EBADFD;
+                               goto _end_unlock;
                        default:
                                break;
                        }
                } else if ((avail < runtime->control->avail_min && size > avail) ||
                           (size >= runtime->xfer_align && avail < runtime->xfer_align)) {
                        wait_queue_t wait;
-                       enum { READY, SIGNALED, ERROR, SUSPENDED, EXPIRED } state;
+                       enum { READY, SIGNALED, ERROR, SUSPENDED, EXPIRED, DROPPED } state;
                        long tout;
 
                        if (nonblock) {
                                        goto _end_loop;
                                case SNDRV_PCM_STATE_DRAINING:
                                        goto __draining;
+                               case SNDRV_PCM_STATE_SETUP:
+                                       state = DROPPED;
+                                       goto _end_loop;
                                default:
                                        break;
                                }
                                snd_printd("capture read error (DMA or IRQ trouble?)\n");
                                err = -EIO;
                                goto _end_unlock;
+                       case DROPPED:
+                               err = -EBADFD;
+                               goto _end_unlock;
                        default:
                                break;
                        }
 
        runtime = substream->runtime;
        str = substream->pstr;
        snd_pcm_unlink(substream);
-       if (substream->open_flag) {
+       if (substream->ffile != NULL) {
                if (substream->ops->hw_free != NULL)
                        substream->ops->hw_free(substream);
                substream->ops->close(substream);
-               substream->open_flag = 0;
+               substream->ffile = NULL;
        }
-       substream->ffile = NULL;
        snd_pcm_remove_file(str, pcm_file);
        snd_pcm_release_substream(substream);
        kfree(pcm_file);
                snd_pcm_release_file(pcm_file);
                return err;
        }
-       substream->open_flag = 1;
+       substream->ffile = file;
 
        err = snd_pcm_hw_constraints_complete(substream);
        if (err < 0) {
                snd_printd("snd_pcm_hw_constraints_complete failed\n");
-               substream->ops->close(substream);
                snd_pcm_release_file(pcm_file);
                return err;
        }
 
-       substream->ffile = file;
-
        file->private_data = pcm_file;
        *rpcm_file = pcm_file;
        return 0;
 
                for (s = 0; s < 2; ++s) {
                        snd_pcm_substream_t *substream;
                        substream = pcm->streams[s].substream;
-                       if (substream && substream->open_flag)
+                       if (substream && substream->ffile != NULL)
                                err = -EBUSY;
                }
        }