Loading drivers/media/common/siano/smscoreapi.c +214 −134 Original line number Diff line number Diff line Loading @@ -683,6 +683,7 @@ int smscore_register_device(struct smsdevice_params_t *params, /* init completion events */ init_completion(&dev->version_ex_done); init_completion(&dev->data_download_done); init_completion(&dev->data_validity_done); init_completion(&dev->trigger_done); init_completion(&dev->init_device_done); init_completion(&dev->reload_start_done); Loading Loading @@ -753,7 +754,13 @@ EXPORT_SYMBOL_GPL(smscore_register_device); static int smscore_sendrequest_and_wait(struct smscore_device_t *coredev, void *buffer, size_t size, struct completion *completion) { int rc = coredev->sendrequest_handler(coredev->context, buffer, size); int rc; if (completion == NULL) return -EINVAL; init_completion(completion); rc = coredev->sendrequest_handler(coredev->context, buffer, size); if (rc < 0) { sms_info("sendrequest returned error %d", rc); return rc; Loading Loading @@ -850,8 +857,9 @@ static int smscore_load_firmware_family2(struct smscore_device_t *coredev, void *buffer, size_t size) { struct SmsFirmware_ST *firmware = (struct SmsFirmware_ST *) buffer; struct SmsMsgHdr_ST *msg; u32 mem_address; struct SmsMsgData_ST4 *msg; u32 mem_address, calc_checksum = 0; u32 i, *ptr; u8 *payload = firmware->Payload; int rc = 0; firmware->StartAddress = le32_to_cpu(firmware->StartAddress); Loading @@ -874,34 +882,35 @@ static int smscore_load_firmware_family2(struct smscore_device_t *coredev, if (coredev->mode != DEVICE_MODE_NONE) { sms_debug("sending reload command."); SMS_INIT_MSG(msg, MSG_SW_RELOAD_START_REQ, SMS_INIT_MSG(&msg->xMsgHeader, MSG_SW_RELOAD_START_REQ, sizeof(struct SmsMsgHdr_ST)); rc = smscore_sendrequest_and_wait(coredev, msg, msg->msgLength, msg->xMsgHeader.msgLength, &coredev->reload_start_done); if (rc < 0) { sms_err("device reload failed, rc %d", rc); goto exit_fw_download; } mem_address = *(u32 *) &payload[20]; } for (i = 0, ptr = (u32 *)firmware->Payload; i < firmware->Length/4 ; i++, ptr++) calc_checksum += *ptr; while (size && rc >= 0) { struct SmsDataDownload_ST *DataMsg = (struct SmsDataDownload_ST *) msg; int payload_size = min((int) size, SMS_MAX_PAYLOAD_SIZE); SMS_INIT_MSG(msg, MSG_SMS_DATA_DOWNLOAD_REQ, SMS_INIT_MSG(&msg->xMsgHeader, MSG_SMS_DATA_DOWNLOAD_REQ, (u16)(sizeof(struct SmsMsgHdr_ST) + sizeof(u32) + payload_size)); DataMsg->MemAddr = mem_address; memcpy(DataMsg->Payload, payload, payload_size); if ((coredev->device_flags & SMS_ROM_NO_RESPONSE) && (coredev->mode == DEVICE_MODE_NONE)) rc = coredev->sendrequest_handler( coredev->context, DataMsg, DataMsg->xMsgHeader.msgLength); else rc = smscore_sendrequest_and_wait( coredev, DataMsg, rc = smscore_sendrequest_and_wait(coredev, DataMsg, DataMsg->xMsgHeader.msgLength, &coredev->data_download_done); Loading @@ -910,44 +919,65 @@ static int smscore_load_firmware_family2(struct smscore_device_t *coredev, mem_address += payload_size; } if (rc >= 0) { if (rc < 0) goto exit_fw_download; sms_err("sending MSG_SMS_DATA_VALIDITY_REQ expecting 0x%x", calc_checksum); SMS_INIT_MSG(&msg->xMsgHeader, MSG_SMS_DATA_VALIDITY_REQ, sizeof(msg->xMsgHeader) + sizeof(u32) * 3); msg->msgData[0] = firmware->StartAddress; /* Entry point */ msg->msgData[1] = firmware->Length; msg->msgData[2] = 0; /* Regular checksum*/ smsendian_handle_tx_message(msg); rc = smscore_sendrequest_and_wait(coredev, msg, msg->xMsgHeader.msgLength, &coredev->data_validity_done); if (rc < 0) goto exit_fw_download; if (coredev->mode == DEVICE_MODE_NONE) { struct SmsMsgData_ST *TriggerMsg = (struct SmsMsgData_ST *) msg; SMS_INIT_MSG(msg, MSG_SMS_SWDOWNLOAD_TRIGGER_REQ, sms_debug("sending MSG_SMS_SWDOWNLOAD_TRIGGER_REQ"); SMS_INIT_MSG(&msg->xMsgHeader, MSG_SMS_SWDOWNLOAD_TRIGGER_REQ, sizeof(struct SmsMsgHdr_ST) + sizeof(u32) * 5); TriggerMsg->msgData[0] = firmware->StartAddress; /* Entry point */ TriggerMsg->msgData[1] = 5; /* Priority */ TriggerMsg->msgData[1] = 6; /* Priority */ TriggerMsg->msgData[2] = 0x200; /* Stack size */ TriggerMsg->msgData[3] = 0; /* Parameter */ TriggerMsg->msgData[4] = 4; /* Task ID */ if (coredev->device_flags & SMS_ROM_NO_RESPONSE) { rc = coredev->sendrequest_handler( coredev->context, TriggerMsg, TriggerMsg->xMsgHeader.msgLength); msleep(100); } else rc = smscore_sendrequest_and_wait( coredev, TriggerMsg, smsendian_handle_tx_message((struct SmsMsgHdr_S *)msg); rc = smscore_sendrequest_and_wait(coredev, TriggerMsg, TriggerMsg->xMsgHeader.msgLength, &coredev->trigger_done); } else { SMS_INIT_MSG(msg, MSG_SW_RELOAD_EXEC_REQ, SMS_INIT_MSG(&msg->xMsgHeader, MSG_SW_RELOAD_EXEC_REQ, sizeof(struct SmsMsgHdr_ST)); rc = coredev->sendrequest_handler(coredev->context, msg, msg->msgLength); } msleep(500); smsendian_handle_tx_message((struct SmsMsgHdr_S *)msg); rc = coredev->sendrequest_handler(coredev->context, msg, msg->xMsgHeader.msgLength); } sms_debug("rc=%d, postload=%p ", rc, coredev->postload_handler); if (rc < 0) goto exit_fw_download; /* * backward compatibility - wait to device_ready_done for * not more than 400 ms */ msleep(400); exit_fw_download: sms_debug("rc=%d, postload=0x%p ", rc, coredev->postload_handler); kfree(msg); Loading @@ -956,6 +986,10 @@ static int smscore_load_firmware_family2(struct smscore_device_t *coredev, rc; } static char *smscore_get_fw_filename(struct smscore_device_t *coredev, int mode, int lookup); /** * loads specified firmware into a buffer and calls device loadfirmware_handler * Loading @@ -967,41 +1001,43 @@ static int smscore_load_firmware_family2(struct smscore_device_t *coredev, * @return 0 on success, <0 on error. */ static int smscore_load_firmware_from_file(struct smscore_device_t *coredev, char *filename, int mode, int lookup, loadfirmware_t loadfirmware_handler) { int rc = -ENOENT; u8 *fw_buf; u32 fw_buf_size; const struct firmware *fw; u8 *fw_buffer; if (loadfirmware_handler == NULL && !(coredev->device_flags & SMS_DEVICE_FAMILY2)) char *fw_filename = smscore_get_fw_filename(coredev, mode, lookup); if (!strcmp(fw_filename, "none")) return -ENOENT; if (loadfirmware_handler == NULL && !(coredev->device_flags & SMS_DEVICE_FAMILY2)) return -EINVAL; rc = request_firmware(&fw, filename, coredev->device); rc = request_firmware(&fw, fw_filename, coredev->device); if (rc < 0) { sms_info("failed to open \"%s\"", filename); sms_info("failed to open \"%s\"", fw_filename); return rc; } sms_info("read FW %s, size=%zd", filename, fw->size); fw_buffer = kmalloc(ALIGN(fw->size, SMS_ALLOC_ALIGNMENT), sms_info("read fw %s, buffer size=0x%zx", fw_filename, fw->size); fw_buf = kmalloc(ALIGN(fw->size, SMS_ALLOC_ALIGNMENT), GFP_KERNEL | GFP_DMA); if (fw_buffer) { memcpy(fw_buffer, fw->data, fw->size); rc = (coredev->device_flags & SMS_DEVICE_FAMILY2) ? smscore_load_firmware_family2(coredev, fw_buffer, fw->size) : loadfirmware_handler(coredev->context, fw_buffer, fw->size); kfree(fw_buffer); } else { if (!fw_buf) { sms_info("failed to allocate firmware buffer"); rc = -ENOMEM; return -ENOMEM; } memcpy(fw_buf, fw->data, fw->size); fw_buf_size = fw->size; rc = (coredev->device_flags & SMS_DEVICE_FAMILY2) ? smscore_load_firmware_family2(coredev, fw_buf, fw_buf_size) : loadfirmware_handler(coredev->context, fw_buf, fw_buf_size); kfree(fw_buf); release_firmware(fw); return rc; Loading Loading @@ -1050,7 +1086,9 @@ void smscore_unregister_device(struct smscore_device_t *coredev) sms_info("waiting for %d buffer(s)", coredev->num_buffers - num_buffers); kmutex_unlock(&g_smscore_deviceslock); msleep(100); kmutex_lock(&g_smscore_deviceslock); } sms_info("freed %d buffers", num_buffers); Loading Loading @@ -1107,30 +1145,73 @@ static int smscore_detect_mode(struct smscore_device_t *coredev) } static char *smscore_fw_lkup[][SMS_NUM_OF_DEVICE_TYPES] = { /*Stellar NOVA A0 Nova B0 VEGA*/ /*Stellar, NOVA A0, Nova B0, VEGA, VENICE, MING, PELE, RIO, DENVER_1530, DENVER_2160 */ /*DVBT*/ {"none", "dvb_nova_12mhz.inp", "dvb_nova_12mhz_b0.inp", "none"}, { "none", "dvb_nova_12mhz.inp", "dvb_nova_12mhz_b0.inp", "none", "none", "none", "none", "dvb_rio.inp", "none", "none" }, /*DVBH*/ {"none", "dvb_nova_12mhz.inp", "dvb_nova_12mhz_b0.inp", "none"}, { "none", "dvb_nova_12mhz.inp", "dvb_nova_12mhz_b0.inp", "none", "none", "none", "none", "dvbh_rio.inp", "none", "none" }, /*TDMB*/ {"none", "tdmb_nova_12mhz.inp", "tdmb_nova_12mhz_b0.inp", "none"}, { "none", "tdmb_nova_12mhz.inp", "tdmb_nova_12mhz_b0.inp", "none", "none", "none", "none", "none", "none", "tdmb_denver.inp" }, /*DABIP*/ {"none", "none", "none", "none"}, /*BDA*/ {"none", "dvb_nova_12mhz.inp", "dvb_nova_12mhz_b0.inp", "none"}, { "none", "none", "none", "none", "none", "none", "none", "none", "none", "none" }, /*DVBT_BDA*/ { "none", "dvb_nova_12mhz.inp", "dvb_nova_12mhz_b0.inp", "none", "none", "none", "none", "dvb_rio.inp", "none", "none" }, /*ISDBT*/ {"none", "isdbt_nova_12mhz.inp", "isdbt_nova_12mhz_b0.inp", "none"}, /*ISDBTBDA*/ {"none", "isdbt_nova_12mhz.inp", "isdbt_nova_12mhz_b0.inp", "none"}, { "none", "isdbt_nova_12mhz.inp", "isdbt_nova_12mhz_b0.inp", "none", "none", "none", "isdbt_pele.inp", "isdbt_rio.inp", "none", "none" }, /*ISDBT_BDA*/ { "none", "isdbt_nova_12mhz.inp", "isdbt_nova_12mhz_b0.inp", "none", "none", "none", "isdbt_pele.inp", "isdbt_rio.inp", "none", "none" }, /*CMMB*/ {"none", "none", "none", "cmmb_vega_12mhz.inp"} { "none", "none", "none", "cmmb_vega_12mhz.inp", "cmmb_venice_12mhz.inp", "cmmb_ming_app.inp", "none", "none", "none", "none" }, /*RAW - not supported*/ { "none", "none", "none", "none", "none", "none", "none", "none", "none", "none" }, /*FM*/ { "none", "none", "fm_radio.inp", "none", "none", "none", "none", "fm_radio_rio.inp", "none", "none" }, /*FM_BDA*/ { "none", "none", "fm_radio.inp", "none", "none", "none", "none", "fm_radio_rio.inp", "none", "none" }, /*ATSC*/ { "none", "none", "none", "none", "none", "none", "none", "none", "atsc_denver.inp", "none" } }; static inline char *sms_get_fw_name(struct smscore_device_t *coredev, int mode, enum sms_device_type_st type) /** * get firmware file name from one of the two mechanisms : sms_boards or * smscore_fw_lkup. * @param coredev pointer to a coredev object returned by * smscore_register_device * @param mode requested mode of operation * @param lookup if 1, always get the fw filename from smscore_fw_lkup * table. if 0, try first to get from sms_boards * * @return 0 on success, <0 on error. */ static char *smscore_get_fw_filename(struct smscore_device_t *coredev, int mode, int lookup) { char **fw = sms_get_board(smscore_get_board_id(coredev))->fw; return (fw && fw[mode]) ? fw[mode] : smscore_fw_lkup[mode][type]; char **fw; int board_id = smscore_get_board_id(coredev); enum sms_device_type_st type = smscore_registry_gettype(coredev->devpath); if ((board_id == SMS_BOARD_UNKNOWN) || (lookup == 1)) { sms_debug("trying to get fw name from lookup table mode %d type %d", mode, type); return smscore_fw_lkup[mode][type]; } sms_debug("trying to get fw name from sms_boards board_id %d mode %d", board_id, mode); fw = sms_get_board(board_id)->fw; if (fw == NULL) { sms_debug("cannot find fw name in sms_boards, getting from lookup table mode %d type %d", mode, type); return smscore_fw_lkup[mode][type]; } if (fw[mode] == NULL) { sms_debug("cannot find fw name in sms_boards, getting from lookup table mode %d type %d", mode, type); return smscore_fw_lkup[mode][type]; } return fw[mode]; } /** Loading @@ -1145,9 +1226,7 @@ static inline char *sms_get_fw_name(struct smscore_device_t *coredev, */ int smscore_set_device_mode(struct smscore_device_t *coredev, int mode) { void *buffer; int rc = 0; enum sms_device_type_st type; sms_debug("set device mode to %d", mode); if (coredev->device_flags & SMS_DEVICE_FAMILY2) { Loading @@ -1172,55 +1251,30 @@ 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); fw_filename = sms_get_fw_name(coredev, mode, type); rc = smscore_load_firmware_from_file(coredev, fw_filename, NULL); if (rc < 0) { sms_warn("error %d loading firmware: %s, " "trying again with default firmware", rc, fw_filename); mode, 0, NULL); /* try again with the default firmware */ fw_filename = smscore_fw_lkup[mode][type]; /* * try again with the default firmware - * get the fw filename from look-up table */ if (rc < 0) { sms_debug("error %d loading firmware, trying again with default firmware", rc); rc = smscore_load_firmware_from_file(coredev, fw_filename, NULL); mode, 1, NULL); if (rc < 0) { sms_warn("error %d loading " "firmware: %s", rc, fw_filename); sms_debug("error %d loading firmware", rc); return rc; } } sms_log("firmware download success: %s", fw_filename); } else sms_info("mode %d supported by running " "firmware", mode); buffer = kmalloc(sizeof(struct SmsMsgData_ST) + SMS_DMA_ALIGNMENT, GFP_KERNEL | GFP_DMA); if (buffer) { struct SmsMsgData_ST *msg = (struct SmsMsgData_ST *) SMS_ALIGN_ADDRESS(buffer); SMS_INIT_MSG(&msg->xMsgHeader, MSG_SMS_INIT_DEVICE_REQ, sizeof(struct SmsMsgData_ST)); msg->msgData[0] = mode; rc = smscore_sendrequest_and_wait( coredev, msg, msg->xMsgHeader.msgLength, &coredev->init_device_done); kfree(buffer); if (rc >= 0) sms_info("firmware download success"); } else { sms_err("Could not allocate buffer for " "init device message."); rc = -ENOMEM; sms_info("mode %d is already supported by running firmware", mode); } } else { if (mode < DEVICE_MODE_DVBT || mode > DEVICE_MODE_DVBT_BDA) { Loading @@ -1239,8 +1293,25 @@ int smscore_set_device_mode(struct smscore_device_t *coredev, int mode) } if (rc >= 0) { char *buffer; coredev->mode = mode; coredev->device_flags &= ~SMS_DEVICE_NOT_READY; buffer = kmalloc(sizeof(struct SmsMsgData_ST) + SMS_DMA_ALIGNMENT, GFP_KERNEL | GFP_DMA); if (buffer) { struct SmsMsgData_ST *msg = (struct SmsMsgData_ST *) SMS_ALIGN_ADDRESS(buffer); SMS_INIT_MSG(&msg->xMsgHeader, MSG_SMS_INIT_DEVICE_REQ, sizeof(struct SmsMsgData_ST)); msg->msgData[0] = mode; rc = smscore_sendrequest_and_wait( coredev, msg, msg->xMsgHeader.msgLength, &coredev->init_device_done); kfree(buffer); } } if (rc < 0) Loading Loading @@ -1371,6 +1442,15 @@ void smscore_onresponse(struct smscore_device_t *coredev, case MSG_SW_RELOAD_START_RES: complete(&coredev->reload_start_done); break; case MSG_SMS_DATA_VALIDITY_RES: { struct SmsMsgData_ST *validity = (struct SmsMsgData_ST *) phdr; sms_err("MSG_SMS_DATA_VALIDITY_RES, checksum = 0x%x", validity->msgData[0]); complete(&coredev->data_validity_done); break; } case MSG_SMS_DATA_DOWNLOAD_RES: complete(&coredev->data_download_done); break; Loading drivers/media/common/siano/smscoreapi.h +6 −2 Original line number Diff line number Diff line Loading @@ -162,6 +162,7 @@ struct smscore_device_t { /* host <--> device messages */ struct completion version_ex_done, data_download_done, trigger_done; struct completion data_validity_done, device_ready_done; struct completion init_device_done, reload_start_done, resume_done; struct completion gpio_configuration_done, gpio_set_level_done; struct completion gpio_get_level_done, ir_init_done; Loading Loading @@ -594,6 +595,11 @@ struct SmsMsgData_ST2 { u32 msgData[2]; }; struct SmsMsgData_ST4 { struct SmsMsgHdr_ST xMsgHeader; u32 msgData[4]; }; struct SmsDataDownload_ST { struct SmsMsgHdr_ST xMsgHeader; u32 MemAddr; Loading Loading @@ -998,8 +1004,6 @@ extern void smscore_onresponse(struct smscore_device_t *coredev, extern int smscore_get_common_buffer_size(struct smscore_device_t *coredev); extern int smscore_map_common_buffer(struct smscore_device_t *coredev, struct vm_area_struct *vma); extern int smscore_get_fw_filename(struct smscore_device_t *coredev, int mode, char *filename); extern int smscore_send_fw_file(struct smscore_device_t *coredev, u8 *ufwbuf, int size); Loading Loading
drivers/media/common/siano/smscoreapi.c +214 −134 Original line number Diff line number Diff line Loading @@ -683,6 +683,7 @@ int smscore_register_device(struct smsdevice_params_t *params, /* init completion events */ init_completion(&dev->version_ex_done); init_completion(&dev->data_download_done); init_completion(&dev->data_validity_done); init_completion(&dev->trigger_done); init_completion(&dev->init_device_done); init_completion(&dev->reload_start_done); Loading Loading @@ -753,7 +754,13 @@ EXPORT_SYMBOL_GPL(smscore_register_device); static int smscore_sendrequest_and_wait(struct smscore_device_t *coredev, void *buffer, size_t size, struct completion *completion) { int rc = coredev->sendrequest_handler(coredev->context, buffer, size); int rc; if (completion == NULL) return -EINVAL; init_completion(completion); rc = coredev->sendrequest_handler(coredev->context, buffer, size); if (rc < 0) { sms_info("sendrequest returned error %d", rc); return rc; Loading Loading @@ -850,8 +857,9 @@ static int smscore_load_firmware_family2(struct smscore_device_t *coredev, void *buffer, size_t size) { struct SmsFirmware_ST *firmware = (struct SmsFirmware_ST *) buffer; struct SmsMsgHdr_ST *msg; u32 mem_address; struct SmsMsgData_ST4 *msg; u32 mem_address, calc_checksum = 0; u32 i, *ptr; u8 *payload = firmware->Payload; int rc = 0; firmware->StartAddress = le32_to_cpu(firmware->StartAddress); Loading @@ -874,34 +882,35 @@ static int smscore_load_firmware_family2(struct smscore_device_t *coredev, if (coredev->mode != DEVICE_MODE_NONE) { sms_debug("sending reload command."); SMS_INIT_MSG(msg, MSG_SW_RELOAD_START_REQ, SMS_INIT_MSG(&msg->xMsgHeader, MSG_SW_RELOAD_START_REQ, sizeof(struct SmsMsgHdr_ST)); rc = smscore_sendrequest_and_wait(coredev, msg, msg->msgLength, msg->xMsgHeader.msgLength, &coredev->reload_start_done); if (rc < 0) { sms_err("device reload failed, rc %d", rc); goto exit_fw_download; } mem_address = *(u32 *) &payload[20]; } for (i = 0, ptr = (u32 *)firmware->Payload; i < firmware->Length/4 ; i++, ptr++) calc_checksum += *ptr; while (size && rc >= 0) { struct SmsDataDownload_ST *DataMsg = (struct SmsDataDownload_ST *) msg; int payload_size = min((int) size, SMS_MAX_PAYLOAD_SIZE); SMS_INIT_MSG(msg, MSG_SMS_DATA_DOWNLOAD_REQ, SMS_INIT_MSG(&msg->xMsgHeader, MSG_SMS_DATA_DOWNLOAD_REQ, (u16)(sizeof(struct SmsMsgHdr_ST) + sizeof(u32) + payload_size)); DataMsg->MemAddr = mem_address; memcpy(DataMsg->Payload, payload, payload_size); if ((coredev->device_flags & SMS_ROM_NO_RESPONSE) && (coredev->mode == DEVICE_MODE_NONE)) rc = coredev->sendrequest_handler( coredev->context, DataMsg, DataMsg->xMsgHeader.msgLength); else rc = smscore_sendrequest_and_wait( coredev, DataMsg, rc = smscore_sendrequest_and_wait(coredev, DataMsg, DataMsg->xMsgHeader.msgLength, &coredev->data_download_done); Loading @@ -910,44 +919,65 @@ static int smscore_load_firmware_family2(struct smscore_device_t *coredev, mem_address += payload_size; } if (rc >= 0) { if (rc < 0) goto exit_fw_download; sms_err("sending MSG_SMS_DATA_VALIDITY_REQ expecting 0x%x", calc_checksum); SMS_INIT_MSG(&msg->xMsgHeader, MSG_SMS_DATA_VALIDITY_REQ, sizeof(msg->xMsgHeader) + sizeof(u32) * 3); msg->msgData[0] = firmware->StartAddress; /* Entry point */ msg->msgData[1] = firmware->Length; msg->msgData[2] = 0; /* Regular checksum*/ smsendian_handle_tx_message(msg); rc = smscore_sendrequest_and_wait(coredev, msg, msg->xMsgHeader.msgLength, &coredev->data_validity_done); if (rc < 0) goto exit_fw_download; if (coredev->mode == DEVICE_MODE_NONE) { struct SmsMsgData_ST *TriggerMsg = (struct SmsMsgData_ST *) msg; SMS_INIT_MSG(msg, MSG_SMS_SWDOWNLOAD_TRIGGER_REQ, sms_debug("sending MSG_SMS_SWDOWNLOAD_TRIGGER_REQ"); SMS_INIT_MSG(&msg->xMsgHeader, MSG_SMS_SWDOWNLOAD_TRIGGER_REQ, sizeof(struct SmsMsgHdr_ST) + sizeof(u32) * 5); TriggerMsg->msgData[0] = firmware->StartAddress; /* Entry point */ TriggerMsg->msgData[1] = 5; /* Priority */ TriggerMsg->msgData[1] = 6; /* Priority */ TriggerMsg->msgData[2] = 0x200; /* Stack size */ TriggerMsg->msgData[3] = 0; /* Parameter */ TriggerMsg->msgData[4] = 4; /* Task ID */ if (coredev->device_flags & SMS_ROM_NO_RESPONSE) { rc = coredev->sendrequest_handler( coredev->context, TriggerMsg, TriggerMsg->xMsgHeader.msgLength); msleep(100); } else rc = smscore_sendrequest_and_wait( coredev, TriggerMsg, smsendian_handle_tx_message((struct SmsMsgHdr_S *)msg); rc = smscore_sendrequest_and_wait(coredev, TriggerMsg, TriggerMsg->xMsgHeader.msgLength, &coredev->trigger_done); } else { SMS_INIT_MSG(msg, MSG_SW_RELOAD_EXEC_REQ, SMS_INIT_MSG(&msg->xMsgHeader, MSG_SW_RELOAD_EXEC_REQ, sizeof(struct SmsMsgHdr_ST)); rc = coredev->sendrequest_handler(coredev->context, msg, msg->msgLength); } msleep(500); smsendian_handle_tx_message((struct SmsMsgHdr_S *)msg); rc = coredev->sendrequest_handler(coredev->context, msg, msg->xMsgHeader.msgLength); } sms_debug("rc=%d, postload=%p ", rc, coredev->postload_handler); if (rc < 0) goto exit_fw_download; /* * backward compatibility - wait to device_ready_done for * not more than 400 ms */ msleep(400); exit_fw_download: sms_debug("rc=%d, postload=0x%p ", rc, coredev->postload_handler); kfree(msg); Loading @@ -956,6 +986,10 @@ static int smscore_load_firmware_family2(struct smscore_device_t *coredev, rc; } static char *smscore_get_fw_filename(struct smscore_device_t *coredev, int mode, int lookup); /** * loads specified firmware into a buffer and calls device loadfirmware_handler * Loading @@ -967,41 +1001,43 @@ static int smscore_load_firmware_family2(struct smscore_device_t *coredev, * @return 0 on success, <0 on error. */ static int smscore_load_firmware_from_file(struct smscore_device_t *coredev, char *filename, int mode, int lookup, loadfirmware_t loadfirmware_handler) { int rc = -ENOENT; u8 *fw_buf; u32 fw_buf_size; const struct firmware *fw; u8 *fw_buffer; if (loadfirmware_handler == NULL && !(coredev->device_flags & SMS_DEVICE_FAMILY2)) char *fw_filename = smscore_get_fw_filename(coredev, mode, lookup); if (!strcmp(fw_filename, "none")) return -ENOENT; if (loadfirmware_handler == NULL && !(coredev->device_flags & SMS_DEVICE_FAMILY2)) return -EINVAL; rc = request_firmware(&fw, filename, coredev->device); rc = request_firmware(&fw, fw_filename, coredev->device); if (rc < 0) { sms_info("failed to open \"%s\"", filename); sms_info("failed to open \"%s\"", fw_filename); return rc; } sms_info("read FW %s, size=%zd", filename, fw->size); fw_buffer = kmalloc(ALIGN(fw->size, SMS_ALLOC_ALIGNMENT), sms_info("read fw %s, buffer size=0x%zx", fw_filename, fw->size); fw_buf = kmalloc(ALIGN(fw->size, SMS_ALLOC_ALIGNMENT), GFP_KERNEL | GFP_DMA); if (fw_buffer) { memcpy(fw_buffer, fw->data, fw->size); rc = (coredev->device_flags & SMS_DEVICE_FAMILY2) ? smscore_load_firmware_family2(coredev, fw_buffer, fw->size) : loadfirmware_handler(coredev->context, fw_buffer, fw->size); kfree(fw_buffer); } else { if (!fw_buf) { sms_info("failed to allocate firmware buffer"); rc = -ENOMEM; return -ENOMEM; } memcpy(fw_buf, fw->data, fw->size); fw_buf_size = fw->size; rc = (coredev->device_flags & SMS_DEVICE_FAMILY2) ? smscore_load_firmware_family2(coredev, fw_buf, fw_buf_size) : loadfirmware_handler(coredev->context, fw_buf, fw_buf_size); kfree(fw_buf); release_firmware(fw); return rc; Loading Loading @@ -1050,7 +1086,9 @@ void smscore_unregister_device(struct smscore_device_t *coredev) sms_info("waiting for %d buffer(s)", coredev->num_buffers - num_buffers); kmutex_unlock(&g_smscore_deviceslock); msleep(100); kmutex_lock(&g_smscore_deviceslock); } sms_info("freed %d buffers", num_buffers); Loading Loading @@ -1107,30 +1145,73 @@ static int smscore_detect_mode(struct smscore_device_t *coredev) } static char *smscore_fw_lkup[][SMS_NUM_OF_DEVICE_TYPES] = { /*Stellar NOVA A0 Nova B0 VEGA*/ /*Stellar, NOVA A0, Nova B0, VEGA, VENICE, MING, PELE, RIO, DENVER_1530, DENVER_2160 */ /*DVBT*/ {"none", "dvb_nova_12mhz.inp", "dvb_nova_12mhz_b0.inp", "none"}, { "none", "dvb_nova_12mhz.inp", "dvb_nova_12mhz_b0.inp", "none", "none", "none", "none", "dvb_rio.inp", "none", "none" }, /*DVBH*/ {"none", "dvb_nova_12mhz.inp", "dvb_nova_12mhz_b0.inp", "none"}, { "none", "dvb_nova_12mhz.inp", "dvb_nova_12mhz_b0.inp", "none", "none", "none", "none", "dvbh_rio.inp", "none", "none" }, /*TDMB*/ {"none", "tdmb_nova_12mhz.inp", "tdmb_nova_12mhz_b0.inp", "none"}, { "none", "tdmb_nova_12mhz.inp", "tdmb_nova_12mhz_b0.inp", "none", "none", "none", "none", "none", "none", "tdmb_denver.inp" }, /*DABIP*/ {"none", "none", "none", "none"}, /*BDA*/ {"none", "dvb_nova_12mhz.inp", "dvb_nova_12mhz_b0.inp", "none"}, { "none", "none", "none", "none", "none", "none", "none", "none", "none", "none" }, /*DVBT_BDA*/ { "none", "dvb_nova_12mhz.inp", "dvb_nova_12mhz_b0.inp", "none", "none", "none", "none", "dvb_rio.inp", "none", "none" }, /*ISDBT*/ {"none", "isdbt_nova_12mhz.inp", "isdbt_nova_12mhz_b0.inp", "none"}, /*ISDBTBDA*/ {"none", "isdbt_nova_12mhz.inp", "isdbt_nova_12mhz_b0.inp", "none"}, { "none", "isdbt_nova_12mhz.inp", "isdbt_nova_12mhz_b0.inp", "none", "none", "none", "isdbt_pele.inp", "isdbt_rio.inp", "none", "none" }, /*ISDBT_BDA*/ { "none", "isdbt_nova_12mhz.inp", "isdbt_nova_12mhz_b0.inp", "none", "none", "none", "isdbt_pele.inp", "isdbt_rio.inp", "none", "none" }, /*CMMB*/ {"none", "none", "none", "cmmb_vega_12mhz.inp"} { "none", "none", "none", "cmmb_vega_12mhz.inp", "cmmb_venice_12mhz.inp", "cmmb_ming_app.inp", "none", "none", "none", "none" }, /*RAW - not supported*/ { "none", "none", "none", "none", "none", "none", "none", "none", "none", "none" }, /*FM*/ { "none", "none", "fm_radio.inp", "none", "none", "none", "none", "fm_radio_rio.inp", "none", "none" }, /*FM_BDA*/ { "none", "none", "fm_radio.inp", "none", "none", "none", "none", "fm_radio_rio.inp", "none", "none" }, /*ATSC*/ { "none", "none", "none", "none", "none", "none", "none", "none", "atsc_denver.inp", "none" } }; static inline char *sms_get_fw_name(struct smscore_device_t *coredev, int mode, enum sms_device_type_st type) /** * get firmware file name from one of the two mechanisms : sms_boards or * smscore_fw_lkup. * @param coredev pointer to a coredev object returned by * smscore_register_device * @param mode requested mode of operation * @param lookup if 1, always get the fw filename from smscore_fw_lkup * table. if 0, try first to get from sms_boards * * @return 0 on success, <0 on error. */ static char *smscore_get_fw_filename(struct smscore_device_t *coredev, int mode, int lookup) { char **fw = sms_get_board(smscore_get_board_id(coredev))->fw; return (fw && fw[mode]) ? fw[mode] : smscore_fw_lkup[mode][type]; char **fw; int board_id = smscore_get_board_id(coredev); enum sms_device_type_st type = smscore_registry_gettype(coredev->devpath); if ((board_id == SMS_BOARD_UNKNOWN) || (lookup == 1)) { sms_debug("trying to get fw name from lookup table mode %d type %d", mode, type); return smscore_fw_lkup[mode][type]; } sms_debug("trying to get fw name from sms_boards board_id %d mode %d", board_id, mode); fw = sms_get_board(board_id)->fw; if (fw == NULL) { sms_debug("cannot find fw name in sms_boards, getting from lookup table mode %d type %d", mode, type); return smscore_fw_lkup[mode][type]; } if (fw[mode] == NULL) { sms_debug("cannot find fw name in sms_boards, getting from lookup table mode %d type %d", mode, type); return smscore_fw_lkup[mode][type]; } return fw[mode]; } /** Loading @@ -1145,9 +1226,7 @@ static inline char *sms_get_fw_name(struct smscore_device_t *coredev, */ int smscore_set_device_mode(struct smscore_device_t *coredev, int mode) { void *buffer; int rc = 0; enum sms_device_type_st type; sms_debug("set device mode to %d", mode); if (coredev->device_flags & SMS_DEVICE_FAMILY2) { Loading @@ -1172,55 +1251,30 @@ 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); fw_filename = sms_get_fw_name(coredev, mode, type); rc = smscore_load_firmware_from_file(coredev, fw_filename, NULL); if (rc < 0) { sms_warn("error %d loading firmware: %s, " "trying again with default firmware", rc, fw_filename); mode, 0, NULL); /* try again with the default firmware */ fw_filename = smscore_fw_lkup[mode][type]; /* * try again with the default firmware - * get the fw filename from look-up table */ if (rc < 0) { sms_debug("error %d loading firmware, trying again with default firmware", rc); rc = smscore_load_firmware_from_file(coredev, fw_filename, NULL); mode, 1, NULL); if (rc < 0) { sms_warn("error %d loading " "firmware: %s", rc, fw_filename); sms_debug("error %d loading firmware", rc); return rc; } } sms_log("firmware download success: %s", fw_filename); } else sms_info("mode %d supported by running " "firmware", mode); buffer = kmalloc(sizeof(struct SmsMsgData_ST) + SMS_DMA_ALIGNMENT, GFP_KERNEL | GFP_DMA); if (buffer) { struct SmsMsgData_ST *msg = (struct SmsMsgData_ST *) SMS_ALIGN_ADDRESS(buffer); SMS_INIT_MSG(&msg->xMsgHeader, MSG_SMS_INIT_DEVICE_REQ, sizeof(struct SmsMsgData_ST)); msg->msgData[0] = mode; rc = smscore_sendrequest_and_wait( coredev, msg, msg->xMsgHeader.msgLength, &coredev->init_device_done); kfree(buffer); if (rc >= 0) sms_info("firmware download success"); } else { sms_err("Could not allocate buffer for " "init device message."); rc = -ENOMEM; sms_info("mode %d is already supported by running firmware", mode); } } else { if (mode < DEVICE_MODE_DVBT || mode > DEVICE_MODE_DVBT_BDA) { Loading @@ -1239,8 +1293,25 @@ int smscore_set_device_mode(struct smscore_device_t *coredev, int mode) } if (rc >= 0) { char *buffer; coredev->mode = mode; coredev->device_flags &= ~SMS_DEVICE_NOT_READY; buffer = kmalloc(sizeof(struct SmsMsgData_ST) + SMS_DMA_ALIGNMENT, GFP_KERNEL | GFP_DMA); if (buffer) { struct SmsMsgData_ST *msg = (struct SmsMsgData_ST *) SMS_ALIGN_ADDRESS(buffer); SMS_INIT_MSG(&msg->xMsgHeader, MSG_SMS_INIT_DEVICE_REQ, sizeof(struct SmsMsgData_ST)); msg->msgData[0] = mode; rc = smscore_sendrequest_and_wait( coredev, msg, msg->xMsgHeader.msgLength, &coredev->init_device_done); kfree(buffer); } } if (rc < 0) Loading Loading @@ -1371,6 +1442,15 @@ void smscore_onresponse(struct smscore_device_t *coredev, case MSG_SW_RELOAD_START_RES: complete(&coredev->reload_start_done); break; case MSG_SMS_DATA_VALIDITY_RES: { struct SmsMsgData_ST *validity = (struct SmsMsgData_ST *) phdr; sms_err("MSG_SMS_DATA_VALIDITY_RES, checksum = 0x%x", validity->msgData[0]); complete(&coredev->data_validity_done); break; } case MSG_SMS_DATA_DOWNLOAD_RES: complete(&coredev->data_download_done); break; Loading
drivers/media/common/siano/smscoreapi.h +6 −2 Original line number Diff line number Diff line Loading @@ -162,6 +162,7 @@ struct smscore_device_t { /* host <--> device messages */ struct completion version_ex_done, data_download_done, trigger_done; struct completion data_validity_done, device_ready_done; struct completion init_device_done, reload_start_done, resume_done; struct completion gpio_configuration_done, gpio_set_level_done; struct completion gpio_get_level_done, ir_init_done; Loading Loading @@ -594,6 +595,11 @@ struct SmsMsgData_ST2 { u32 msgData[2]; }; struct SmsMsgData_ST4 { struct SmsMsgHdr_ST xMsgHeader; u32 msgData[4]; }; struct SmsDataDownload_ST { struct SmsMsgHdr_ST xMsgHeader; u32 MemAddr; Loading Loading @@ -998,8 +1004,6 @@ extern void smscore_onresponse(struct smscore_device_t *coredev, extern int smscore_get_common_buffer_size(struct smscore_device_t *coredev); extern int smscore_map_common_buffer(struct smscore_device_t *coredev, struct vm_area_struct *vma); extern int smscore_get_fw_filename(struct smscore_device_t *coredev, int mode, char *filename); extern int smscore_send_fw_file(struct smscore_device_t *coredev, u8 *ufwbuf, int size); Loading