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; }
static void do_registration(struct work_struct *work) { struct snd_oxfw *oxfw = container_of(work, struct snd_oxfw, dwork.work); int err; if (oxfw->registered) return; err = snd_card_new(&oxfw->unit->device, -1, NULL, THIS_MODULE, 0, &oxfw->card); if (err < 0) return; err = name_card(oxfw); if (err < 0) goto error; err = detect_quirks(oxfw); if (err < 0) goto error; err = snd_oxfw_stream_discover(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_oxfw_create_pcm(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_card_register(oxfw->card); if (err < 0) goto error; /* * After registered, oxfw instance can be released corresponding to * releasing the sound card instance. */ oxfw->card->private_free = oxfw_card_free; oxfw->card->private_data = oxfw; oxfw->registered = true; return; error: snd_oxfw_stream_destroy_simplex(oxfw, &oxfw->rx_stream); if (oxfw->has_output) snd_oxfw_stream_destroy_simplex(oxfw, &oxfw->tx_stream); snd_card_free(oxfw->card); dev_info(&oxfw->unit->device, "Sound card registration failed: %d\n", err); }