[media] dvb_usb_v2: use identify_state() to resolve firmware name
Merge get_firmware_name() to identify_state(). It is wise to resolve firmware name in that routine as it does decision wether or not to load firmware at all. It is one very rarely needed callback less. Signed-off-by: Antti Palosaari <crope@iki.fi> Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
This commit is contained in:
Родитель
b905a2a133
Коммит
a0921af7eb
|
@ -324,7 +324,7 @@ static struct i2c_algorithm af9015_i2c_algo = {
|
||||||
.functionality = af9015_i2c_func,
|
.functionality = af9015_i2c_func,
|
||||||
};
|
};
|
||||||
|
|
||||||
static int af9015_identify_state(struct dvb_usb_device *d)
|
static int af9015_identify_state(struct dvb_usb_device *d, const char **name)
|
||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
u8 reply;
|
u8 reply;
|
||||||
|
|
|
@ -278,7 +278,7 @@ static struct i2c_algorithm af9035_i2c_algo = {
|
||||||
.functionality = af9035_i2c_functionality,
|
.functionality = af9035_i2c_functionality,
|
||||||
};
|
};
|
||||||
|
|
||||||
static int af9035_identify_state(struct dvb_usb_device *d)
|
static int af9035_identify_state(struct dvb_usb_device *d, const char **name)
|
||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
u8 wbuf[1] = { 1 };
|
u8 wbuf[1] = { 1 };
|
||||||
|
|
|
@ -197,11 +197,12 @@ struct dvb_usb_device_properties {
|
||||||
struct module *owner;
|
struct module *owner;
|
||||||
short *adapter_nr;
|
short *adapter_nr;
|
||||||
u8 bInterfaceNumber;
|
u8 bInterfaceNumber;
|
||||||
|
|
||||||
int size_of_priv;
|
int size_of_priv;
|
||||||
|
|
||||||
|
#define WARM 0
|
||||||
|
#define COLD 1
|
||||||
|
int (*identify_state) (struct dvb_usb_device *, const char **);
|
||||||
const char *firmware;
|
const char *firmware;
|
||||||
int (*get_firmware_name) (struct dvb_usb_device *, const char **);
|
|
||||||
#define RECONNECTS_USB 1
|
#define RECONNECTS_USB 1
|
||||||
int (*download_firmware) (struct dvb_usb_device *,
|
int (*download_firmware) (struct dvb_usb_device *,
|
||||||
const struct firmware *);
|
const struct firmware *);
|
||||||
|
@ -219,10 +220,6 @@ struct dvb_usb_device_properties {
|
||||||
int (*streaming_ctrl) (struct dvb_usb_adapter *, int);
|
int (*streaming_ctrl) (struct dvb_usb_adapter *, int);
|
||||||
int (*fe_ioctl_override) (struct dvb_frontend *,
|
int (*fe_ioctl_override) (struct dvb_frontend *,
|
||||||
unsigned int, void *, unsigned int);
|
unsigned int, void *, unsigned int);
|
||||||
|
|
||||||
#define WARM 0
|
|
||||||
#define COLD 1
|
|
||||||
int (*identify_state) (struct dvb_usb_device *);
|
|
||||||
int (*init) (struct dvb_usb_device *);
|
int (*init) (struct dvb_usb_device *);
|
||||||
void (*disconnect) (struct dvb_usb_device *);
|
void (*disconnect) (struct dvb_usb_device *);
|
||||||
int (*get_rc_config) (struct dvb_usb_device *, struct dvb_usb_rc *);
|
int (*get_rc_config) (struct dvb_usb_device *, struct dvb_usb_rc *);
|
||||||
|
|
|
@ -24,19 +24,10 @@ module_param_named(force_pid_filter_usage, dvb_usb_force_pid_filter_usage,
|
||||||
MODULE_PARM_DESC(force_pid_filter_usage, "force all dvb-usb-devices to use a" \
|
MODULE_PARM_DESC(force_pid_filter_usage, "force all dvb-usb-devices to use a" \
|
||||||
" PID filter, if any (default: 0).");
|
" PID filter, if any (default: 0).");
|
||||||
|
|
||||||
static int dvb_usbv2_download_firmware(struct dvb_usb_device *d)
|
static int dvb_usbv2_download_firmware(struct dvb_usb_device *d, const char *name)
|
||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
const struct firmware *fw = NULL;
|
const struct firmware *fw;
|
||||||
const char *name;
|
|
||||||
|
|
||||||
/* resolve firmware name */
|
|
||||||
name = d->props->firmware;
|
|
||||||
if (d->props->get_firmware_name) {
|
|
||||||
ret = d->props->get_firmware_name(d, &name);
|
|
||||||
if (ret < 0)
|
|
||||||
goto err;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!d->props->download_firmware) {
|
if (!d->props->download_firmware) {
|
||||||
ret = -EINVAL;
|
ret = -EINVAL;
|
||||||
|
@ -395,7 +386,6 @@ static void dvb_usbv2_init_work(struct work_struct *work)
|
||||||
int ret;
|
int ret;
|
||||||
struct dvb_usb_device *d =
|
struct dvb_usb_device *d =
|
||||||
container_of(work, struct dvb_usb_device, probe_work);
|
container_of(work, struct dvb_usb_device, probe_work);
|
||||||
bool cold = false;
|
|
||||||
|
|
||||||
d->work_pid = current->pid;
|
d->work_pid = current->pid;
|
||||||
|
|
||||||
|
@ -411,42 +401,44 @@ static void dvb_usbv2_init_work(struct work_struct *work)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (d->props->identify_state) {
|
if (d->props->identify_state) {
|
||||||
ret = d->props->identify_state(d);
|
const char *name = NULL;
|
||||||
|
ret = d->props->identify_state(d, &name);
|
||||||
if (ret == 0) {
|
if (ret == 0) {
|
||||||
;
|
;
|
||||||
} else if (ret == COLD) {
|
} else if (ret == COLD) {
|
||||||
cold = true;
|
|
||||||
ret = 0;
|
|
||||||
} else {
|
|
||||||
goto err_usb_driver_release_interface;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (cold) {
|
|
||||||
pr_info("%s: found a '%s' in cold state\n",
|
pr_info("%s: found a '%s' in cold state\n",
|
||||||
KBUILD_MODNAME, d->name);
|
KBUILD_MODNAME, d->name);
|
||||||
ret = dvb_usbv2_download_firmware(d);
|
|
||||||
|
if (!name)
|
||||||
|
name = d->props->firmware;
|
||||||
|
|
||||||
|
ret = dvb_usbv2_download_firmware(d, name);
|
||||||
if (ret == 0) {
|
if (ret == 0) {
|
||||||
/* device is warm, continue initialization */
|
/* device is warm, continue initialization */
|
||||||
;
|
;
|
||||||
} else if (ret == RECONNECTS_USB) {
|
} else if (ret == RECONNECTS_USB) {
|
||||||
/*
|
/*
|
||||||
* USB core will call disconnect() and then probe()
|
* USB core will call disconnect() and then
|
||||||
* as device reconnects itself from the USB bus.
|
* probe() as device reconnects itself from the
|
||||||
* disconnect() will release all driver resources
|
* USB bus. disconnect() will release all driver
|
||||||
* and probe() is called for 'new' device. As 'new'
|
* resources and probe() is called for 'new'
|
||||||
* device is warm we should never go here again.
|
* device. As 'new' device is warm we should
|
||||||
|
* never go here again.
|
||||||
*/
|
*/
|
||||||
return;
|
return;
|
||||||
} else {
|
} else {
|
||||||
/* Unexpected fatal error. We must unregister driver
|
/* Unexpected error. We must unregister driver
|
||||||
* manually from the device, because device is already
|
* manually from the device, because device is
|
||||||
* register by returning from probe() with success.
|
* already register by returning from probe()
|
||||||
* usb_driver_release_interface() finally calls
|
* with success. usb_driver_release_interface()
|
||||||
* disconnect() in order to free resources.
|
* finally calls disconnect() in order to free
|
||||||
|
* resources.
|
||||||
*/
|
*/
|
||||||
goto err_usb_driver_release_interface;
|
goto err_usb_driver_release_interface;
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
goto err_usb_driver_release_interface;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pr_info("%s: found a '%s' in warm state\n", KBUILD_MODNAME, d->name);
|
pr_info("%s: found a '%s' in warm state\n", KBUILD_MODNAME, d->name);
|
||||||
|
|
|
@ -182,7 +182,7 @@ static struct i2c_algorithm ec168_i2c_algo = {
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Callbacks for DVB USB */
|
/* Callbacks for DVB USB */
|
||||||
static int ec168_identify_state(struct dvb_usb_device *d)
|
static int ec168_identify_state(struct dvb_usb_device *d, const char **name)
|
||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
u8 reply;
|
u8 reply;
|
||||||
|
|
Загрузка…
Ссылка в новой задаче