コード例 #1
0
int dvb_usbv2_probe(struct usb_interface *intf,
		const struct usb_device_id *id)
{
	int ret;
	struct dvb_usb_device *d;
	struct usb_device *udev = interface_to_usbdev(intf);
	struct dvb_usb_driver_info *driver_info =
			(struct dvb_usb_driver_info *) id->driver_info;

	dev_dbg(&udev->dev, "%s: bInterfaceNumber=%d\n", __func__,
			intf->cur_altsetting->desc.bInterfaceNumber);

	if (!id->driver_info) {
		dev_err(&udev->dev, "%s: driver_info failed\n", KBUILD_MODNAME);
		ret = -ENODEV;
		goto err;
	}

	d = kzalloc(sizeof(struct dvb_usb_device), GFP_KERNEL);
	if (!d) {
		dev_err(&udev->dev, "%s: kzalloc() failed\n", KBUILD_MODNAME);
		ret = -ENOMEM;
		goto err;
	}

	d->name = driver_info->name;
	d->rc_map = driver_info->rc_map;
	d->udev = udev;
	d->props = driver_info->props;

	if (intf->cur_altsetting->desc.bInterfaceNumber !=
			d->props->bInterfaceNumber) {
		ret = -ENODEV;
		goto err_free_all;
	}

	mutex_init(&d->usb_mutex);
	mutex_init(&d->i2c_mutex);

	if (d->props->size_of_priv) {
		d->priv = kzalloc(d->props->size_of_priv, GFP_KERNEL);
		if (!d->priv) {
			dev_err(&d->udev->dev, "%s: kzalloc() failed\n",
					KBUILD_MODNAME);
			ret = -ENOMEM;
			goto err_free_all;
		}
	}

	if (d->props->identify_state) {
		const char *name = NULL;
		ret = d->props->identify_state(d, &name);
		if (ret == 0) {
			;
		} else if (ret == COLD) {
			dev_info(&d->udev->dev,
					"%s: found a '%s' in cold state\n",
					KBUILD_MODNAME, d->name);

			if (!name)
				name = d->props->firmware;

			ret = dvb_usbv2_download_firmware(d, name);
			if (ret == 0) {
				/* device is warm, continue initialization */
				;
			} else if (ret == RECONNECTS_USB) {
				/*
				 * USB core will call disconnect() and then
				 * probe() as device reconnects itself from the
				 * USB bus. disconnect() will release all driver
				 * resources and probe() is called for 'new'
				 * device. As 'new' device is warm we should
				 * never go here again.
				 */
				goto exit;
			} else {
				goto err_free_all;
			}
		} else {
			goto err_free_all;
		}
	}

	dev_info(&d->udev->dev, "%s: found a '%s' in warm state\n",
			KBUILD_MODNAME, d->name);

	ret = dvb_usbv2_init(d);
	if (ret < 0)
		goto err_free_all;

	dev_info(&d->udev->dev,
			"%s: '%s' successfully initialized and connected\n",
			KBUILD_MODNAME, d->name);
exit:
	usb_set_intfdata(intf, d);

	return 0;
err_free_all:
	dvb_usbv2_exit(d);
err:
	dev_dbg(&udev->dev, "%s: failed=%d\n", __func__, ret);
	return ret;
}
コード例 #2
0
ファイル: dvb_usb_core.c プロジェクト: Kratos1982/UbuntuTouch
/*
 * udev, which is used for the firmware downloading, requires we cannot
 * block during module_init(). module_init() calls USB probe() which
 * is this routine. Due to that we delay actual operation using workqueue
 * and return always success here.
 */
static void dvb_usbv2_init_work(struct work_struct *work)
{
	int ret;
	struct dvb_usb_device *d =
			container_of(work, struct dvb_usb_device, probe_work);

	d->work_pid = current->pid;
	dev_dbg(&d->udev->dev, "%s: work_pid=%d\n", __func__, d->work_pid);

	if (d->props->size_of_priv) {
		d->priv = kzalloc(d->props->size_of_priv, GFP_KERNEL);
		if (!d->priv) {
			dev_err(&d->udev->dev, "%s: kzalloc() failed\n",
					KBUILD_MODNAME);
			ret = -ENOMEM;
			goto err_usb_driver_release_interface;
		}
	}

	if (d->props->identify_state) {
		const char *name = NULL;
		ret = d->props->identify_state(d, &name);
		if (ret == 0) {
			;
		} else if (ret == COLD) {
			dev_info(&d->udev->dev,
					"%s: found a '%s' in cold state\n",
					KBUILD_MODNAME, d->name);

			if (!name)
				name = d->props->firmware;

			ret = dvb_usbv2_download_firmware(d, name);
			if (ret == 0) {
				/* device is warm, continue initialization */
				;
			} else if (ret == RECONNECTS_USB) {
				/*
				 * USB core will call disconnect() and then
				 * probe() as device reconnects itself from the
				 * USB bus. disconnect() will release all driver
				 * resources and probe() is called for 'new'
				 * device. As 'new' device is warm we should
				 * never go here again.
				 */
				return;
			} else {
				/*
				 * Unexpected error. We must unregister driver
				 * manually from the device, because device is
				 * already register by returning from probe()
				 * with success. usb_driver_release_interface()
				 * finally calls disconnect() in order to free
				 * resources.
				 */
				goto err_usb_driver_release_interface;
			}
		} else {
			goto err_usb_driver_release_interface;
		}
	}

	dev_info(&d->udev->dev, "%s: found a '%s' in warm state\n",
			KBUILD_MODNAME, d->name);

	ret = dvb_usbv2_init(d);
	if (ret < 0)
		goto err_usb_driver_release_interface;

	dev_info(&d->udev->dev,
			"%s: '%s' successfully initialized and connected\n",
			KBUILD_MODNAME, d->name);

	return;
err_usb_driver_release_interface:
	dev_info(&d->udev->dev, "%s: '%s' error while loading driver (%d)\n",
			KBUILD_MODNAME, d->name, ret);
	usb_driver_release_interface(to_usb_driver(d->intf->dev.driver),
			d->intf);
	dev_dbg(&d->udev->dev, "%s: failed=%d\n", __func__, ret);
	return;
}