summaryrefslogtreecommitdiffstats
path: root/drivers/media/dvb/dvb-usb/dvb_usb_init.c
diff options
context:
space:
mode:
authorAntti Palosaari2012-05-24 01:45:05 +0200
committerMauro Carvalho Chehab2012-08-04 12:56:20 +0200
commit496e82789935df7a9b13ce58807973004e443847 (patch)
treec34197165962d0b0c0bb688b02482fa497488dae /drivers/media/dvb/dvb-usb/dvb_usb_init.c
parent[media] dvb_usb_v2: remove adapter_nums parameter from dvb_usbv2_device_init() (diff)
downloadkernel-qcow2-linux-496e82789935df7a9b13ce58807973004e443847.tar.gz
kernel-qcow2-linux-496e82789935df7a9b13ce58807973004e443847.tar.xz
kernel-qcow2-linux-496e82789935df7a9b13ce58807973004e443847.zip
[media] dvb_usb_v2: pass (struct dvb_usb_device *) as a parameter for fw download
Change parameter (struct usb_device *) => (struct dvb_usb_device *) for .identify_state() and .download_firmware() callbacks. struct usb_device * did not provide handle for the DVB USB driver state. Change DVB USB framework to alloc space for the priv earlier and pass that pointer to the device driver using (struct dvb_usb_device *) as a callback parameter. Signed-off-by: Antti Palosaari <crope@iki.fi> Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
Diffstat (limited to 'drivers/media/dvb/dvb-usb/dvb_usb_init.c')
-rw-r--r--drivers/media/dvb/dvb-usb/dvb_usb_init.c86
1 files changed, 56 insertions, 30 deletions
diff --git a/drivers/media/dvb/dvb-usb/dvb_usb_init.c b/drivers/media/dvb/dvb-usb/dvb_usb_init.c
index 662c25840f3c..9c03a3266be2 100644
--- a/drivers/media/dvb/dvb-usb/dvb_usb_init.c
+++ b/drivers/media/dvb/dvb-usb/dvb_usb_init.c
@@ -147,14 +147,6 @@ static int dvb_usb_init(struct dvb_usb_device *d)
d->state = DVB_USB_STATE_INIT;
- if (d->props.size_of_priv > 0) {
- d->priv = kzalloc(d->props.size_of_priv, GFP_KERNEL);
- if (d->priv == NULL) {
- err("no memory for priv in 'struct dvb_usb_device'");
- return -ENOMEM;
- }
- }
-
/* check the capabilities and set appropriate variables */
dvb_usb_device_power_ctrl(d, 1);
@@ -175,12 +167,12 @@ static int dvb_usb_init(struct dvb_usb_device *d)
}
/* determine the name and the state of the just found USB device */
-static struct dvb_usb_device_description *dvb_usb_find_device(struct usb_device *udev, struct dvb_usb_device_properties *props, int *cold)
+static struct dvb_usb_device_description *dvb_usb_find_device(struct usb_device *udev, struct dvb_usb_device_properties *props, bool *cold)
{
int i, j;
struct dvb_usb_device_description *desc = NULL;
- *cold = -1;
+ *cold = true;
for (i = 0; i < props->num_device_descs; i++) {
@@ -188,7 +180,7 @@ static struct dvb_usb_device_description *dvb_usb_find_device(struct usb_device
deb_info("check for cold %x %x\n", props->devices[i].cold_ids[j]->idVendor, props->devices[i].cold_ids[j]->idProduct);
if (props->devices[i].cold_ids[j]->idVendor == le16_to_cpu(udev->descriptor.idVendor) &&
props->devices[i].cold_ids[j]->idProduct == le16_to_cpu(udev->descriptor.idProduct)) {
- *cold = 1;
+ *cold = true;
desc = &props->devices[i];
break;
}
@@ -201,16 +193,13 @@ static struct dvb_usb_device_description *dvb_usb_find_device(struct usb_device
deb_info("check for warm %x %x\n", props->devices[i].warm_ids[j]->idVendor, props->devices[i].warm_ids[j]->idProduct);
if (props->devices[i].warm_ids[j]->idVendor == le16_to_cpu(udev->descriptor.idVendor) &&
props->devices[i].warm_ids[j]->idProduct == le16_to_cpu(udev->descriptor.idProduct)) {
- *cold = 0;
+ *cold = false;
desc = &props->devices[i];
break;
}
}
}
- if (desc != NULL && props->identify_state != NULL)
- props->identify_state(udev, props, &desc, cold);
-
return desc;
}
@@ -233,38 +222,68 @@ int dvb_usb_device_power_ctrl(struct dvb_usb_device *d, int onoff)
* USB
*/
int dvb_usbv2_device_init(struct usb_interface *intf,
- const struct usb_device_id *id)
+ const struct usb_device_id *id)
{
struct usb_device *udev = interface_to_usbdev(intf);
struct dvb_usb_device *d = NULL;
struct dvb_usb_device_description *desc = NULL;
struct dvb_usb_device_properties *props =
(struct dvb_usb_device_properties *) id->driver_info;
+ int ret = -ENOMEM;
+ bool cold;
+
+ d = kzalloc(sizeof(struct dvb_usb_device), GFP_KERNEL);
+ if (d == NULL) {
+ err("no memory for 'struct dvb_usb_device'");
+ return -ENOMEM;
+ }
+
+ d->udev = udev;
+ memcpy(&d->props, props, sizeof(struct dvb_usb_device_properties));
- int ret = -ENOMEM, cold = 0;
+ if (d->props.size_of_priv > 0) {
+ d->priv = kzalloc(d->props.size_of_priv, GFP_KERNEL);
+ if (d->priv == NULL) {
+ err("no memory for priv in 'struct dvb_usb_device'");
+ ret = -ENOMEM;
+ goto err_kfree;
+ }
+ }
if ((desc = dvb_usb_find_device(udev, props, &cold)) == NULL) {
deb_err("something went very wrong, device was not found in current device list - let's see what comes next.\n");
- return -ENODEV;
+ ret = -ENODEV;
+ goto err_kfree;
+ }
+
+ d->desc = desc;
+
+ if (d->props.identify_state) {
+ ret = d->props.identify_state(d);
+ if (ret == 0) {
+ ;
+ } else if (ret == COLD) {
+ cold = true;
+ ret = 0;
+ } else {
+ goto err_kfree;
+ }
}
if (cold) {
info("found a '%s' in cold state, will try to load a firmware", desc->name);
- ret = dvb_usb_download_firmware(udev, props);
- if (!props->no_reconnect || ret != 0)
- return ret;
+ ret = dvb_usb_download_firmware(d);
+ if (ret == 0) {
+ ;
+ } else if (ret == RECONNECTS_USB) {
+ ret = 0;
+ goto err_kfree;
+ } else {
+ goto err_kfree;
+ }
}
info("found a '%s' in warm state.", desc->name);
- d = kzalloc(sizeof(struct dvb_usb_device), GFP_KERNEL);
- if (d == NULL) {
- err("no memory for 'struct dvb_usb_device'");
- return -ENOMEM;
- }
-
- d->udev = udev;
- memcpy(&d->props, props, sizeof(struct dvb_usb_device_properties));
- d->desc = desc;
usb_set_intfdata(intf, d);
@@ -274,6 +293,13 @@ int dvb_usbv2_device_init(struct usb_interface *intf,
info("%s successfully initialized and connected.", desc->name);
else
info("%s error while loading driver (%d)", desc->name, ret);
+
+ return 0;
+
+err_kfree:
+ kfree(d->priv);
+ kfree(d);
+
return ret;
}
EXPORT_SYMBOL(dvb_usbv2_device_init);