diff --git a/drivers/media/dvb/siano/sms-cards.h b/drivers/media/dvb/siano/sms-cards.h index 7ba3df63dffef78284f40d22e97f014b06402a32..9e93f0b5b2316bc0113de3377be63e245d87e34d 100644 --- a/drivers/media/dvb/siano/sms-cards.h +++ b/drivers/media/dvb/siano/sms-cards.h @@ -31,8 +31,8 @@ #define SMS1XXX_BOARD_SIANO_VEGA 5 struct sms_board { - char *name; enum sms_device_type_st type; + char *name, *fw[DEVICE_MODE_MAX]; }; struct sms_board *sms_get_board(int id); diff --git a/drivers/media/dvb/siano/smscoreapi.c b/drivers/media/dvb/siano/smscoreapi.c index bbb3ad9c804ac3819d1eead61b73a8ec689e616b..eaa7cf22715b37066b39b63a2e4ce04b59d1907d 100644 --- a/drivers/media/dvb/siano/smscoreapi.c +++ b/drivers/media/dvb/siano/smscoreapi.c @@ -32,6 +32,7 @@ #include #include "smscoreapi.h" +#include "sms-cards.h" int sms_debug; module_param_named(debug, sms_debug, int, 0644); @@ -600,7 +601,7 @@ static int smscore_load_firmware_from_file(struct smscore_device_t *coredev, sms_info("failed to open \"%s\"", filename); return rc; } - sms_info("read FW %s, size=%d\"", filename, fw->size); + sms_info("read FW %s, size=%d", filename, fw->size); fw_buffer = kmalloc(ALIGN(fw->size, SMS_ALLOC_ALIGNMENT), GFP_KERNEL | GFP_DMA); if (fw_buffer) { @@ -736,6 +737,12 @@ static char *smscore_fw_lkup[][SMS_NUM_OF_DEVICE_TYPES] = { {"none", "none", "none", "cmmb_vega_12mhz.inp"} }; +static inline char *sms_get_fw_name(struct smscore_device_t *coredev, + int mode, enum sms_device_type_st type) +{ + char **fw = sms_get_board(smscore_get_board_id(coredev))->fw; + return (fw && fw[mode]) ? fw[mode] : smscore_fw_lkup[mode][type]; +} /** * calls device handler to change mode of operation @@ -776,12 +783,26 @@ int smscore_set_device_mode(struct smscore_device_t *coredev, int mode) } if (!(coredev->modes_supported & (1 << mode))) { + char *fw_filename; + type = smscore_registry_gettype(coredev->devpath); - rc = smscore_load_firmware_from_file( - coredev, smscore_fw_lkup[mode][type], NULL); + fw_filename = sms_get_fw_name(coredev, mode, type); + + rc = smscore_load_firmware_from_file(coredev, + fw_filename, NULL); if (rc < 0) { - sms_err("load firmware failed %d", rc); - return rc; + sms_err("error %d loading firmware: %s, " + "trying again with default firmware", + rc, fw_filename); + + /* try again with the default firmware */ + rc = smscore_load_firmware_from_file(coredev, + smscore_fw_lkup[mode][type], NULL); + + if (rc < 0) { + sms_err("load firmware failed %d", rc); + return rc; + } } } else sms_info("mode %d supported by running " diff --git a/drivers/media/dvb/siano/smsusb.c b/drivers/media/dvb/siano/smsusb.c index e7e0fe735427c822d2e94a226ad71872723f3579..f85210f2bd0d58af3399203e3a410ce39f33bafc 100644 --- a/drivers/media/dvb/siano/smsusb.c +++ b/drivers/media/dvb/siano/smsusb.c @@ -216,6 +216,7 @@ static int smsusb1_load_firmware(struct usb_device *udev, int id) sms_err("failed to allocate firmware buffer"); rc = -ENOMEM; } + sms_info("read FW %s, size=%d", smsusb1_fw_lkup[id], fw->size); release_firmware(fw);