static int bebob_probe(struct fw_unit *unit, const struct ieee1394_device_id *entry) { struct snd_card *card; struct snd_bebob *bebob; const struct snd_bebob_spec *spec; unsigned int card_index; int err; mutex_lock(&devices_mutex); for (card_index = 0; card_index < SNDRV_CARDS; card_index++) { if (!test_bit(card_index, devices_used) && enable[card_index]) break; } if (card_index >= SNDRV_CARDS) { err = -ENOENT; goto end; } if ((entry->vendor_id == VEN_FOCUSRITE) && (entry->model_id == MODEL_FOCUSRITE_SAFFIRE_BOTH)) spec = get_saffire_spec(unit); else if ((entry->vendor_id == VEN_MAUDIO1) && (entry->model_id == MODEL_MAUDIO_AUDIOPHILE_BOTH) && !check_audiophile_booted(unit)) spec = NULL; else spec = (const struct snd_bebob_spec *)entry->driver_data; if (spec == NULL) { if ((entry->vendor_id == VEN_MAUDIO1) || (entry->vendor_id == VEN_MAUDIO2)) err = snd_bebob_maudio_load_firmware(unit); else err = -ENOSYS; goto end; } err = snd_card_new(&unit->device, index[card_index], id[card_index], THIS_MODULE, sizeof(struct snd_bebob), &card); if (err < 0) goto end; bebob = card->private_data; bebob->card_index = card_index; set_bit(card_index, devices_used); card->private_free = bebob_card_free; bebob->card = card; bebob->unit = fw_unit_get(unit); bebob->spec = spec; mutex_init(&bebob->mutex); spin_lock_init(&bebob->lock); init_waitqueue_head(&bebob->hwdep_wait); err = name_device(bebob, entry->vendor_id); if (err < 0) goto error; if ((entry->vendor_id == VEN_MAUDIO1) && (entry->model_id == MODEL_MAUDIO_FW1814)) err = snd_bebob_maudio_special_discover(bebob, true); else if ((entry->vendor_id == VEN_MAUDIO1) && (entry->model_id == MODEL_MAUDIO_PROJECTMIX)) err = snd_bebob_maudio_special_discover(bebob, false); else err = snd_bebob_stream_discover(bebob); if (err < 0) goto error; snd_bebob_proc_init(bebob); if ((bebob->midi_input_ports > 0) || (bebob->midi_output_ports > 0)) { err = snd_bebob_create_midi_devices(bebob); if (err < 0) goto error; } err = snd_bebob_create_pcm_devices(bebob); if (err < 0) goto error; err = snd_bebob_create_hwdep_device(bebob); if (err < 0) goto error; err = snd_bebob_stream_init_duplex(bebob); if (err < 0) goto error; if (!bebob->maudio_special_quirk) { err = snd_card_register(card); if (err < 0) { snd_bebob_stream_destroy_duplex(bebob); goto error; } } else { /* * This is a workaround. This bus reset seems to have an effect * to make devices correctly handling transactions. Without * this, the devices have gap_count mismatch. This causes much * failure of transaction. * * Just after registration, user-land application receive * signals from dbus and starts I/Os. To avoid I/Os till the * future bus reset, registration is done in next update(). */ bebob->deferred_registration = true; fw_schedule_bus_reset(fw_parent_device(bebob->unit)->card, false, true); } dev_set_drvdata(&unit->device, bebob); end: mutex_unlock(&devices_mutex); return err; error: mutex_unlock(&devices_mutex); snd_card_free(card); return err; }
static void do_registration(struct work_struct *work) { struct snd_bebob *bebob = container_of(work, struct snd_bebob, dwork.work); unsigned int card_index; int err; if (bebob->registered) return; mutex_lock(&devices_mutex); for (card_index = 0; card_index < SNDRV_CARDS; card_index++) { if (!test_bit(card_index, devices_used) && enable[card_index]) break; } if (card_index >= SNDRV_CARDS) { mutex_unlock(&devices_mutex); return; } err = snd_card_new(&bebob->unit->device, index[card_index], id[card_index], THIS_MODULE, 0, &bebob->card); if (err < 0) { mutex_unlock(&devices_mutex); return; } err = name_device(bebob); if (err < 0) goto error; if (bebob->spec == &maudio_special_spec) { if (bebob->entry->model_id == MODEL_MAUDIO_FW1814) err = snd_bebob_maudio_special_discover(bebob, true); else err = snd_bebob_maudio_special_discover(bebob, false); } else { err = snd_bebob_stream_discover(bebob); } if (err < 0) goto error; err = snd_bebob_stream_init_duplex(bebob); if (err < 0) goto error; snd_bebob_proc_init(bebob); if (bebob->midi_input_ports > 0 || bebob->midi_output_ports > 0) { err = snd_bebob_create_midi_devices(bebob); if (err < 0) goto error; } err = snd_bebob_create_pcm_devices(bebob); if (err < 0) goto error; err = snd_bebob_create_hwdep_device(bebob); if (err < 0) goto error; err = snd_card_register(bebob->card); if (err < 0) goto error; set_bit(card_index, devices_used); mutex_unlock(&devices_mutex); /* * After registered, bebob instance can be released corresponding to * releasing the sound card instance. */ bebob->card->private_free = bebob_card_free; bebob->card->private_data = bebob; bebob->registered = true; return; error: mutex_unlock(&devices_mutex); snd_bebob_stream_destroy_duplex(bebob); snd_card_free(bebob->card); dev_info(&bebob->unit->device, "Sound card registration failed: %d\n", err); }
static int snd_bebob_probe(struct fw_unit *unit, const struct ieee1394_device_id *entry) { struct snd_card *card; struct snd_bebob *bebob; int card_index, err; mutex_lock(&devices_mutex); /* check registered cards */ for (card_index = 0; card_index < SNDRV_CARDS; card_index += 1) { if (!(devices_used & BIT(card_index)) && enable[card_index]) break; } if (card_index >= SNDRV_CARDS) { err = -ENOENT; goto end; } /* create card */ err = snd_card_create(index[card_index], id[card_index], THIS_MODULE, sizeof(struct snd_bebob), &card); if (err < 0) goto end; card->private_free = snd_bebob_card_free; /* initialize myself */ bebob = card->private_data; bebob->card = card; bebob->device = fw_parent_device(unit); bebob->unit = unit; bebob->card_index = -1; mutex_init(&bebob->mutex); spin_lock_init(&bebob->lock); bebob->spec = (const struct snd_bebob_spec *)entry->driver_data; /* try to load firmware if necessary */ if (!bebob->spec->load) goto loaded; /* MAudio Audiophile has the same id for both */ else if ((entry->model_id == MODEL_MAUDIO_AUDIOPHILE_BOTH) && check_audiophile_booted(bebob)) goto loaded; else { bebob->spec->load(bebob); /* just do this */ err = 0; snd_printk(KERN_INFO"loading firmware\n"); goto error; } loaded: if (!bebob->spec->discover) goto error; err = bebob->spec->discover(bebob); if (err < 0) goto error; /* name device with communication */ err = name_device(bebob, entry->vendor_id); if (err < 0) goto error; /* create devices */ err = snd_bebob_create_pcm_devices(bebob); if (err < 0) goto error; err = snd_bebob_create_control_devices(bebob); if (err < 0) goto error; snd_bebob_create_midi_devices(bebob); /* proc interfaces */ snd_bebob_proc_init(bebob); /* register card and device */ snd_card_set_dev(card, &unit->device); err = snd_card_register(card); if (err < 0) { snd_card_free(card); goto error; } dev_set_drvdata(&unit->device, bebob); devices_used |= BIT(card_index); bebob->card_index = card_index; /* proved */ err = 0; goto end; error: snd_card_free(card); end: mutex_unlock(&devices_mutex); return err; }