[media] dvb_usb_v2: pass (struct dvb_usb_device *) as a parameter for fw download
authorAntti Palosaari <crope@iki.fi>
Wed, 23 May 2012 23:45:05 +0000 (20:45 -0300)
committerMauro Carvalho Chehab <mchehab@redhat.com>
Sat, 4 Aug 2012 10:56:20 +0000 (07:56 -0300)
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>
drivers/media/dvb/dvb-usb/dvb_usb.h
drivers/media/dvb/dvb-usb/dvb_usb_common.h
drivers/media/dvb/dvb-usb/dvb_usb_firmware.c
drivers/media/dvb/dvb-usb/dvb_usb_init.c

index 101191e73661d91ffb75dc21b3025107907b0442..e3d55525dec595bc9cf173a2bf8d5f59e0687889 100644 (file)
@@ -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 {
index 24341bde02d8af67b0ee6813bc68d04abbe77c32..dd275cdc10821c944be472c45c36ac92658a9078 100644 (file)
@@ -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);
 
index 20f2ed782dd7095eca3f5e860ed06176a29bc6ee..dd9f8220adeae508487b9758585f211da5715418 100644 (file)
@@ -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;
index 662c25840f3c46ac1921b062a65f21aef8dfcf49..9c03a3266be2cb0f1e9727ddf3d98a23508b0c1e 100644 (file)
@@ -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);