static int oxfw_probe(struct fw_unit *unit, const struct ieee1394_device_id *entry) { struct snd_oxfw *oxfw; if (entry->vendor_id == VENDOR_LOUD && !detect_loud_models(unit)) return -ENODEV; /* Allocate this independent of sound card instance. */ oxfw = kzalloc(sizeof(struct snd_oxfw), GFP_KERNEL); if (oxfw == NULL) return -ENOMEM; oxfw->entry = entry; oxfw->unit = fw_unit_get(unit); dev_set_drvdata(&unit->device, oxfw); mutex_init(&oxfw->mutex); spin_lock_init(&oxfw->lock); init_waitqueue_head(&oxfw->hwdep_wait); /* Allocate and register this sound card later. */ INIT_DEFERRABLE_WORK(&oxfw->dwork, do_registration); snd_fw_schedule_registration(unit, &oxfw->dwork); return 0; }
/** * fw_iso_resources_init - initializes a &struct fw_iso_resources * @r: the resource manager to initialize * @unit: the device unit for which the resources will be needed * * If the device does not support all channel numbers, change @r->channels_mask * after calling this function. */ int fw_iso_resources_init(struct fw_iso_resources *r, struct fw_unit *unit) { r->channels_mask = ~0uLL; r->unit = fw_unit_get(unit); mutex_init(&r->mutex); r->allocated = false; return 0; }
/** * fw_iso_resources_init - initializes a &struct fw_iso_resources * @r: the resource manager to initialize * @unit: the device unit for which the resources will be needed * * If the device does not support all channel numbers, change @r->channels_mask * after calling this function. */ int fw_iso_resources_init(struct fw_iso_resources *r, struct fw_unit *unit) { r->buffer = kmalloc(2 * 4, GFP_KERNEL); if (!r->buffer) return -ENOMEM; r->channels_mask = ~0uLL; r->unit = fw_unit_get(unit); mutex_init(&r->mutex); r->allocated = false; return 0; }
/** * amdtp_out_stream_init - initialize an AMDTP output stream structure * @s: the AMDTP output stream to initialize * @unit: the target of the stream * @flags: the packet transmission method to use */ int amdtp_out_stream_init(struct amdtp_out_stream *s, struct fw_unit *unit, enum cip_out_flags flags) { if (flags != CIP_NONBLOCKING) return -EINVAL; s->unit = fw_unit_get(unit); s->flags = flags; s->context = ERR_PTR(-1); mutex_init(&s->mutex); s->packet_index = 0; return 0; }
static int snd_ff_probe(struct fw_unit *unit, const struct ieee1394_device_id *entry) { struct snd_ff *ff; ff = devm_kzalloc(&unit->device, sizeof(struct snd_ff), GFP_KERNEL); if (!ff) return -ENOMEM; ff->unit = fw_unit_get(unit); dev_set_drvdata(&unit->device, ff); mutex_init(&ff->mutex); spin_lock_init(&ff->lock); init_waitqueue_head(&ff->hwdep_wait); ff->spec = (const struct snd_ff_spec *)entry->driver_data; /* Register this sound card later. */ INIT_DEFERRABLE_WORK(&ff->dwork, do_registration); snd_fw_schedule_registration(unit, &ff->dwork); return 0; }
static int motu_probe(struct fw_unit *unit, const struct ieee1394_device_id *entry) { struct snd_motu *motu; /* Allocate this independently of sound card instance. */ motu = devm_kzalloc(&unit->device, sizeof(struct snd_motu), GFP_KERNEL); if (!motu) return -ENOMEM; motu->unit = fw_unit_get(unit); dev_set_drvdata(&unit->device, motu); motu->spec = (const struct snd_motu_spec *)entry->driver_data; mutex_init(&motu->mutex); spin_lock_init(&motu->lock); init_waitqueue_head(&motu->hwdep_wait); /* Allocate and register this sound card later. */ INIT_DEFERRABLE_WORK(&motu->dwork, do_registration); snd_fw_schedule_registration(unit, &motu->dwork); return 0; }
static int snd_dg00x_probe(struct fw_unit *unit, const struct ieee1394_device_id *entry) { struct snd_dg00x *dg00x; /* Allocate this independent of sound card instance. */ dg00x = kzalloc(sizeof(struct snd_dg00x), GFP_KERNEL); if (dg00x == NULL) return -ENOMEM; dg00x->unit = fw_unit_get(unit); dev_set_drvdata(&unit->device, dg00x); mutex_init(&dg00x->mutex); spin_lock_init(&dg00x->lock); init_waitqueue_head(&dg00x->hwdep_wait); /* Allocate and register this sound card later. */ INIT_DEFERRABLE_WORK(&dg00x->dwork, do_registration); snd_fw_schedule_registration(unit, &dg00x->dwork); return 0; }
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 efw_probe(struct fw_unit *unit, const struct ieee1394_device_id *entry) { struct snd_card *card; struct snd_efw *efw; int card_index, err; mutex_lock(&devices_mutex); /* check registered cards */ 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; } err = snd_card_new(&unit->device, index[card_index], id[card_index], THIS_MODULE, sizeof(struct snd_efw), &card); if (err < 0) goto end; efw = card->private_data; efw->card_index = card_index; set_bit(card_index, devices_used); card->private_free = efw_card_free; efw->card = card; efw->unit = fw_unit_get(unit); mutex_init(&efw->mutex); spin_lock_init(&efw->lock); init_waitqueue_head(&efw->hwdep_wait); /* prepare response buffer */ snd_efw_resp_buf_size = clamp(snd_efw_resp_buf_size, SND_EFW_RESPONSE_MAXIMUM_BYTES, 4096U); efw->resp_buf = kzalloc(snd_efw_resp_buf_size, GFP_KERNEL); if (efw->resp_buf == NULL) { err = -ENOMEM; goto error; } efw->pull_ptr = efw->push_ptr = efw->resp_buf; snd_efw_transaction_add_instance(efw); err = get_hardware_info(efw); if (err < 0) goto error; if (entry->model_id == MODEL_ECHO_AUDIOFIRE_2) efw->is_af2 = true; if (entry->model_id == MODEL_ECHO_AUDIOFIRE_9) efw->is_af9 = true; snd_efw_proc_init(efw); if (efw->midi_out_ports || efw->midi_in_ports) { err = snd_efw_create_midi_devices(efw); if (err < 0) goto error; } err = snd_efw_create_pcm_devices(efw); if (err < 0) goto error; err = snd_efw_create_hwdep_device(efw); if (err < 0) goto error; err = snd_efw_stream_init_duplex(efw); if (err < 0) goto error; err = snd_card_register(card); if (err < 0) { snd_efw_stream_destroy_duplex(efw); goto error; } dev_set_drvdata(&unit->device, efw); end: mutex_unlock(&devices_mutex); return err; error: snd_efw_transaction_remove_instance(efw); 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_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 oxfw_probe(struct fw_unit *unit, const struct ieee1394_device_id *id) { struct snd_card *card; struct snd_oxfw *oxfw; int err; if ((id->vendor_id == VENDOR_LOUD) && !detect_loud_models(unit)) return -ENODEV; err = snd_card_new(&unit->device, -1, NULL, THIS_MODULE, sizeof(*oxfw), &card); if (err < 0) return err; card->private_free = oxfw_card_free; oxfw = card->private_data; oxfw->card = card; mutex_init(&oxfw->mutex); oxfw->unit = fw_unit_get(unit); oxfw->device_info = (const struct device_info *)id->driver_data; spin_lock_init(&oxfw->lock); init_waitqueue_head(&oxfw->hwdep_wait); err = snd_oxfw_stream_discover(oxfw); if (err < 0) goto error; err = name_card(oxfw); if (err < 0) goto error; err = snd_oxfw_create_pcm(oxfw); if (err < 0) goto error; if (oxfw->device_info) { err = snd_oxfw_create_mixer(oxfw); if (err < 0) goto error; } snd_oxfw_proc_init(oxfw); err = snd_oxfw_create_midi(oxfw); if (err < 0) goto error; err = snd_oxfw_create_hwdep(oxfw); if (err < 0) goto error; err = snd_oxfw_stream_init_simplex(oxfw, &oxfw->rx_stream); if (err < 0) goto error; if (oxfw->has_output) { err = snd_oxfw_stream_init_simplex(oxfw, &oxfw->tx_stream); if (err < 0) goto error; } err = snd_card_register(card); if (err < 0) { snd_oxfw_stream_destroy_simplex(oxfw, &oxfw->rx_stream); if (oxfw->has_output) snd_oxfw_stream_destroy_simplex(oxfw, &oxfw->tx_stream); goto error; } dev_set_drvdata(&unit->device, oxfw); return 0; error: snd_card_free(card); return err; }