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 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 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; }