static struct snd_minor *autoload_device(unsigned int minor) { int dev; mutex_unlock(&sound_mutex); /* release lock temporarily */ dev = SNDRV_MINOR_DEVICE(minor); if (dev == SNDRV_MINOR_CONTROL) { /* /dev/aloadC? */ int card = SNDRV_MINOR_CARD(minor); if (snd_cards[card] == NULL) snd_request_card(card); } else if (dev == SNDRV_MINOR_GLOBAL) { /* /dev/aloadSEQ */ snd_request_other(minor); } mutex_lock(&sound_mutex); /* reacuire lock */ return snd_minors[minor]; }
static struct snd_minor *autoload_device(unsigned int minor) { int dev; mutex_unlock(&sound_mutex); dev = SNDRV_MINOR_DEVICE(minor); if (dev == SNDRV_MINOR_CONTROL) { int card = SNDRV_MINOR_CARD(minor); if (snd_cards[card] == NULL) snd_request_card(card); } else if (dev == SNDRV_MINOR_GLOBAL) { snd_request_other(minor); } mutex_lock(&sound_mutex); return snd_minors[minor]; }
static int __snd_open(struct inode *inode, struct file *file) { unsigned int minor = iminor(inode); struct snd_minor *mptr = NULL; const struct file_operations *old_fops; int err = 0; if (minor >= ARRAY_SIZE(snd_minors)) return -ENODEV; mptr = snd_minors[minor]; if (mptr == NULL) { #ifdef CONFIG_MODULES int dev = SNDRV_MINOR_DEVICE(minor); if (dev == SNDRV_MINOR_CONTROL) { /* /dev/aloadC? */ int card = SNDRV_MINOR_CARD(minor); if (snd_cards[card] == NULL) snd_request_card(card); } else if (dev == SNDRV_MINOR_GLOBAL) { /* /dev/aloadSEQ */ snd_request_other(minor); } #ifndef CONFIG_SND_DYNAMIC_MINORS /* /dev/snd/{controlC?,seq} */ mptr = snd_minors[minor]; if (mptr == NULL) #endif #endif return -ENODEV; } old_fops = file->f_op; file->f_op = fops_get(mptr->f_ops); if (file->f_op == NULL) { file->f_op = old_fops; return -ENODEV; } if (file->f_op->open) err = file->f_op->open(inode, file); if (err) { fops_put(file->f_op); file->f_op = fops_get(old_fops); } fops_put(old_fops); return err; }
static int snd_hwdep_open(struct inode *inode, struct file * file) { int major = imajor(inode); int cardnum; int device; snd_hwdep_t *hw; int err; wait_queue_t wait; if (major == snd_major) { cardnum = SNDRV_MINOR_CARD(iminor(inode)); device = SNDRV_MINOR_DEVICE(iminor(inode)) - SNDRV_MINOR_HWDEP; #ifdef CONFIG_SND_OSSEMUL } else if (major == SOUND_MAJOR) { cardnum = SNDRV_MINOR_OSS_CARD(iminor(inode)); device = 0; #endif } else return -ENXIO; cardnum %= SNDRV_CARDS; device %= SNDRV_MINOR_HWDEPS; hw = snd_hwdep_devices[(cardnum * SNDRV_MINOR_HWDEPS) + device]; if (hw == NULL) return -ENODEV; if (!hw->ops.open) return -ENXIO; #ifdef CONFIG_SND_OSSEMUL if (major == SOUND_MAJOR && hw->oss_type < 0) return -ENXIO; #endif if (!try_module_get(hw->card->module)) return -EFAULT; init_waitqueue_entry(&wait, current); add_wait_queue(&hw->open_wait, &wait); down(&hw->open_mutex); while (1) { if (hw->exclusive && hw->used > 0) { err = -EBUSY; break; } err = hw->ops.open(hw, file); if (err >= 0) break; if (err == -EAGAIN) { if (file->f_flags & O_NONBLOCK) { err = -EBUSY; break; } } else break; set_current_state(TASK_INTERRUPTIBLE); up(&hw->open_mutex); schedule(); down(&hw->open_mutex); if (signal_pending(current)) { err = -ERESTARTSYS; break; } } remove_wait_queue(&hw->open_wait, &wait); if (err >= 0) { err = snd_card_file_add(hw->card, file); if (err >= 0) { file->private_data = hw; hw->used++; } else { if (hw->ops.release) hw->ops.release(hw, file); } } up(&hw->open_mutex); if (err < 0) module_put(hw->card->module); return err; }