Beispiel #1
0
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);
}
Beispiel #2
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;
}