diff options
-rw-r--r-- | drivers/media/dvb/dvb-usb/dvb_usb.h | 11 | ||||
-rw-r--r-- | drivers/media/dvb/dvb-usb/dvb_usb_common.h | 2 | ||||
-rw-r--r-- | drivers/media/dvb/dvb-usb/dvb_usb_firmware.c | 16 | ||||
-rw-r--r-- | drivers/media/dvb/dvb-usb/dvb_usb_init.c | 86 |
4 files changed, 72 insertions, 43 deletions
diff --git a/drivers/media/dvb/dvb-usb/dvb_usb.h b/drivers/media/dvb/dvb-usb/dvb_usb.h index 101191e7366..e3d55525dec 100644 --- a/drivers/media/dvb/dvb-usb/dvb_usb.h +++ b/drivers/media/dvb/dvb-usb/dvb_usb.h @@ -275,9 +275,10 @@ struct dvb_usb_device_properties { #define CYPRESS_AN2235 2 #define CYPRESS_FX2 3 int usb_ctrl; - int (*download_firmware) (struct usb_device *, const struct firmware *); + +#define RECONNECTS_USB 1 + int (*download_firmware) (struct dvb_usb_device *, const struct firmware *); const char *firmware; - int no_reconnect; int size_of_priv; @@ -286,8 +287,10 @@ struct dvb_usb_device_properties { int (*power_ctrl) (struct dvb_usb_device *, int); int (*read_mac_address) (struct dvb_usb_device *, u8 []); - int (*identify_state) (struct usb_device *, struct dvb_usb_device_properties *, - struct dvb_usb_device_description **, int *); + +#define WARM 0 +#define COLD 1 + int (*identify_state) (struct dvb_usb_device *); int (*init) (struct dvb_usb_device *); struct { diff --git a/drivers/media/dvb/dvb-usb/dvb_usb_common.h b/drivers/media/dvb/dvb-usb/dvb_usb_common.h index 24341bde02d..dd275cdc108 100644 --- a/drivers/media/dvb/dvb-usb/dvb_usb_common.h +++ b/drivers/media/dvb/dvb-usb/dvb_usb_common.h @@ -25,7 +25,7 @@ extern int dvb_usb_disable_rc_polling; #define deb_uxfer(args...) dprintk(dvb_usb_debug,0x100,args) /* commonly used methods */ -extern int dvb_usb_download_firmware(struct usb_device *, struct dvb_usb_device_properties *); +extern int dvb_usb_download_firmware(struct dvb_usb_device *); extern int dvb_usb_device_power_ctrl(struct dvb_usb_device *d, int onoff); diff --git a/drivers/media/dvb/dvb-usb/dvb_usb_firmware.c b/drivers/media/dvb/dvb-usb/dvb_usb_firmware.c index 20f2ed782dd..dd9f8220ade 100644 --- a/drivers/media/dvb/dvb-usb/dvb_usb_firmware.c +++ b/drivers/media/dvb/dvb-usb/dvb_usb_firmware.c @@ -75,29 +75,29 @@ int usbv2_cypress_load_firmware(struct usb_device *udev, const struct firmware * } EXPORT_SYMBOL(usbv2_cypress_load_firmware); -int dvb_usb_download_firmware(struct usb_device *udev, struct dvb_usb_device_properties *props) +int dvb_usb_download_firmware(struct dvb_usb_device *d) { int ret; const struct firmware *fw = NULL; - if ((ret = request_firmware(&fw, props->firmware, &udev->dev)) != 0) { + if ((ret = request_firmware(&fw, d->props.firmware, &d->udev->dev)) != 0) { err("did not find the firmware file. (%s) " "Please see linux/Documentation/dvb/ for more details on firmware-problems. (%d)", - props->firmware,ret); + d->props.firmware,ret); return ret; } - info("downloading firmware from file '%s'",props->firmware); + info("downloading firmware from file '%s'", d->props.firmware); - switch (props->usb_ctrl) { + switch (d->props.usb_ctrl) { case CYPRESS_AN2135: case CYPRESS_AN2235: case CYPRESS_FX2: - ret = usbv2_cypress_load_firmware(udev, fw, props->usb_ctrl); + ret = usbv2_cypress_load_firmware(d->udev, fw, d->props.usb_ctrl); break; case DEVICE_SPECIFIC: - if (props->download_firmware) - ret = props->download_firmware(udev,fw); + if (d->props.download_firmware) + ret = d->props.download_firmware(d, fw); else { err("BUG: driver didn't specified a download_firmware-callback, although it claims to have a DEVICE_SPECIFIC one."); ret = -EINVAL; diff --git a/drivers/media/dvb/dvb-usb/dvb_usb_init.c b/drivers/media/dvb/dvb-usb/dvb_usb_init.c index 662c25840f3..9c03a3266be 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); |