static int bebob_probe(struct fw_unit *unit, const struct ieee1394_device_id *entry) { struct snd_bebob *bebob; const struct snd_bebob_spec *spec; 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) return snd_bebob_maudio_load_firmware(unit); else return -ENODEV; } /* Allocate this independent of sound card instance. */ bebob = kzalloc(sizeof(struct snd_bebob), GFP_KERNEL); if (bebob == NULL) return -ENOMEM; bebob->unit = fw_unit_get(unit); bebob->entry = entry; bebob->spec = spec; dev_set_drvdata(&unit->device, bebob); mutex_init(&bebob->mutex); spin_lock_init(&bebob->lock); init_waitqueue_head(&bebob->hwdep_wait); /* Allocate and register this sound card later. */ INIT_DEFERRABLE_WORK(&bebob->dwork, do_registration); if (entry->vendor_id != VEN_MAUDIO1 || (entry->model_id != MODEL_MAUDIO_FW1814 && entry->model_id != MODEL_MAUDIO_PROJECTMIX)) { snd_fw_schedule_registration(unit, &bebob->dwork); } 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(). */ fw_schedule_bus_reset(fw_parent_device(bebob->unit)->card, false, true); } return 0; }
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; }