198773c8cfeef655fa63d95134c94b5a79d18eb35Madan Ankapura/* 298773c8cfeef655fa63d95134c94b5a79d18eb35Madan Ankapura * Copyright (C) 2011 The Android Open Source Project 398773c8cfeef655fa63d95134c94b5a79d18eb35Madan Ankapura * 498773c8cfeef655fa63d95134c94b5a79d18eb35Madan Ankapura * Licensed under the Apache License, Version 2.0 (the "License"); 598773c8cfeef655fa63d95134c94b5a79d18eb35Madan Ankapura * you may not use this file except in compliance with the License. 698773c8cfeef655fa63d95134c94b5a79d18eb35Madan Ankapura * You may obtain a copy of the License at 798773c8cfeef655fa63d95134c94b5a79d18eb35Madan Ankapura * 898773c8cfeef655fa63d95134c94b5a79d18eb35Madan Ankapura * http://www.apache.org/licenses/LICENSE-2.0 998773c8cfeef655fa63d95134c94b5a79d18eb35Madan Ankapura * 1098773c8cfeef655fa63d95134c94b5a79d18eb35Madan Ankapura * Unless required by applicable law or agreed to in writing, software 1198773c8cfeef655fa63d95134c94b5a79d18eb35Madan Ankapura * distributed under the License is distributed on an "AS IS" BASIS, 1298773c8cfeef655fa63d95134c94b5a79d18eb35Madan Ankapura * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1398773c8cfeef655fa63d95134c94b5a79d18eb35Madan Ankapura * See the License for the specific language governing permissions and 1498773c8cfeef655fa63d95134c94b5a79d18eb35Madan Ankapura * limitations under the License. 1598773c8cfeef655fa63d95134c94b5a79d18eb35Madan Ankapura */ 1698773c8cfeef655fa63d95134c94b5a79d18eb35Madan Ankapura 1798773c8cfeef655fa63d95134c94b5a79d18eb35Madan Ankapura#include <errno.h> 1898773c8cfeef655fa63d95134c94b5a79d18eb35Madan Ankapura#include <fcntl.h> 1998773c8cfeef655fa63d95134c94b5a79d18eb35Madan Ankapura#include <linux/usbdevice_fs.h> 2098773c8cfeef655fa63d95134c94b5a79d18eb35Madan Ankapura#include <stdarg.h> 2198773c8cfeef655fa63d95134c94b5a79d18eb35Madan Ankapura#include <stdio.h> 2298773c8cfeef655fa63d95134c94b5a79d18eb35Madan Ankapura#include <stdlib.h> 2398773c8cfeef655fa63d95134c94b5a79d18eb35Madan Ankapura#include <string.h> 2498773c8cfeef655fa63d95134c94b5a79d18eb35Madan Ankapura#include <sys/ioctl.h> 2598773c8cfeef655fa63d95134c94b5a79d18eb35Madan Ankapura#include <sys/mman.h> 2698773c8cfeef655fa63d95134c94b5a79d18eb35Madan Ankapura#include <sys/stat.h> 2798773c8cfeef655fa63d95134c94b5a79d18eb35Madan Ankapura#include <sys/types.h> 2898773c8cfeef655fa63d95134c94b5a79d18eb35Madan Ankapura#include <time.h> 2998773c8cfeef655fa63d95134c94b5a79d18eb35Madan Ankapura#include <unistd.h> 3098773c8cfeef655fa63d95134c94b5a79d18eb35Madan Ankapura#include <termios.h> 3198773c8cfeef655fa63d95134c94b5a79d18eb35Madan Ankapura 3298773c8cfeef655fa63d95134c94b5a79d18eb35Madan Ankapura#include "update_cdma_modem.h" 3398773c8cfeef655fa63d95134c94b5a79d18eb35Madan Ankapura 3498773c8cfeef655fa63d95134c94b5a79d18eb35Madan Ankapura 3598773c8cfeef655fa63d95134c94b5a79d18eb35Madan Ankapura#define MODEM_DEVNODE "/dev/cdma_boot0" 3698773c8cfeef655fa63d95134c94b5a79d18eb35Madan Ankapura 3798773c8cfeef655fa63d95134c94b5a79d18eb35Madan Ankapura#define IOCTL_MODEM_ON _IO('o', 0x19) 3898773c8cfeef655fa63d95134c94b5a79d18eb35Madan Ankapura#define IOCTL_MODEM_OFF _IO('o', 0x20) 3998773c8cfeef655fa63d95134c94b5a79d18eb35Madan Ankapura#define IOCTL_MODEM_RESET _IO('o', 0x21) 4098773c8cfeef655fa63d95134c94b5a79d18eb35Madan Ankapura#define IOCTL_MODEM_BOOT_ON _IO('o', 0x22) 4198773c8cfeef655fa63d95134c94b5a79d18eb35Madan Ankapura#define IOCTL_MODEM_BOOT_OFF _IO('o', 0x23) 4298773c8cfeef655fa63d95134c94b5a79d18eb35Madan Ankapura#define IOCTL_MODEM_START _IO('o', 0x24) 4398773c8cfeef655fa63d95134c94b5a79d18eb35Madan Ankapura#define IOCTL_MODEM_SEND _IO('o', 0x25) 4498773c8cfeef655fa63d95134c94b5a79d18eb35Madan Ankapura#define IOCTL_MODEM_RECV _IO('o', 0x26) 4598773c8cfeef655fa63d95134c94b5a79d18eb35Madan Ankapura#define IOCTL_MODEM_STATUS _IO('o', 0x27) 4698773c8cfeef655fa63d95134c94b5a79d18eb35Madan Ankapura#define IOCTL_MODEM_GOTA_START _IO('o', 0x28) 4798773c8cfeef655fa63d95134c94b5a79d18eb35Madan Ankapura#define IOCTL_MODEM_FW_UPDATE _IO('o', 0x29) 4898773c8cfeef655fa63d95134c94b5a79d18eb35Madan Ankapura 4998773c8cfeef655fa63d95134c94b5a79d18eb35Madan Ankapura/* buffer type for modem image */ 5098773c8cfeef655fa63d95134c94b5a79d18eb35Madan Ankapurastruct dpram_firmware { 5198773c8cfeef655fa63d95134c94b5a79d18eb35Madan Ankapura char *firmware; 5298773c8cfeef655fa63d95134c94b5a79d18eb35Madan Ankapura int size; 5398773c8cfeef655fa63d95134c94b5a79d18eb35Madan Ankapura int is_delta; 5498773c8cfeef655fa63d95134c94b5a79d18eb35Madan Ankapura}; 5598773c8cfeef655fa63d95134c94b5a79d18eb35Madan Ankapura 5698773c8cfeef655fa63d95134c94b5a79d18eb35Madan Ankapurastatic int modem_download_ioctl_fw(int sel, struct dpram_firmware* fw) 5798773c8cfeef655fa63d95134c94b5a79d18eb35Madan Ankapura{ 5898773c8cfeef655fa63d95134c94b5a79d18eb35Madan Ankapura int fd = open(MODEM_DEVNODE, O_RDWR); 5998773c8cfeef655fa63d95134c94b5a79d18eb35Madan Ankapura if (fd < 0) { 6098773c8cfeef655fa63d95134c94b5a79d18eb35Madan Ankapura fprintf(stderr, "Unable to open modem device (%s)\n", strerror(errno)); 6198773c8cfeef655fa63d95134c94b5a79d18eb35Madan Ankapura return -1; 6298773c8cfeef655fa63d95134c94b5a79d18eb35Madan Ankapura } 6398773c8cfeef655fa63d95134c94b5a79d18eb35Madan Ankapura int ret = (fw != NULL) ? ioctl(fd, sel, fw) : ioctl(fd, sel); 6498773c8cfeef655fa63d95134c94b5a79d18eb35Madan Ankapura close(fd); 6598773c8cfeef655fa63d95134c94b5a79d18eb35Madan Ankapura 6698773c8cfeef655fa63d95134c94b5a79d18eb35Madan Ankapura return ret; 6798773c8cfeef655fa63d95134c94b5a79d18eb35Madan Ankapura} 6898773c8cfeef655fa63d95134c94b5a79d18eb35Madan Ankapura 6998773c8cfeef655fa63d95134c94b5a79d18eb35Madan Ankapurastatic int modem_download_ioctl(int sel) 7098773c8cfeef655fa63d95134c94b5a79d18eb35Madan Ankapura{ 7198773c8cfeef655fa63d95134c94b5a79d18eb35Madan Ankapura return modem_download_ioctl_fw(sel, NULL); 7298773c8cfeef655fa63d95134c94b5a79d18eb35Madan Ankapura} 7398773c8cfeef655fa63d95134c94b5a79d18eb35Madan Ankapura 7498773c8cfeef655fa63d95134c94b5a79d18eb35Madan Ankapuraint update_cdma_modem(const char* image_data, size_t image_size) { 7598773c8cfeef655fa63d95134c94b5a79d18eb35Madan Ankapura int ret; 7698773c8cfeef655fa63d95134c94b5a79d18eb35Madan Ankapura struct dpram_firmware fw; 7798773c8cfeef655fa63d95134c94b5a79d18eb35Madan Ankapura 7898773c8cfeef655fa63d95134c94b5a79d18eb35Madan Ankapura ret = modem_download_ioctl(IOCTL_MODEM_GOTA_START); 7998773c8cfeef655fa63d95134c94b5a79d18eb35Madan Ankapura if (ret < 0) { 8098773c8cfeef655fa63d95134c94b5a79d18eb35Madan Ankapura fprintf(stderr, "IOCTL_MODEM_GOTA_START failed: (%d)\n", ret); 8198773c8cfeef655fa63d95134c94b5a79d18eb35Madan Ankapura return -1; 8298773c8cfeef655fa63d95134c94b5a79d18eb35Madan Ankapura } 8398773c8cfeef655fa63d95134c94b5a79d18eb35Madan Ankapura 8498773c8cfeef655fa63d95134c94b5a79d18eb35Madan Ankapura ret = modem_download_ioctl(IOCTL_MODEM_BOOT_ON); 8598773c8cfeef655fa63d95134c94b5a79d18eb35Madan Ankapura if (ret < 0) { 8698773c8cfeef655fa63d95134c94b5a79d18eb35Madan Ankapura fprintf(stderr, "IOCTL_MODEM_BOOT_ON failed: (%d)\n", ret); 8798773c8cfeef655fa63d95134c94b5a79d18eb35Madan Ankapura return -1; 8898773c8cfeef655fa63d95134c94b5a79d18eb35Madan Ankapura } 8998773c8cfeef655fa63d95134c94b5a79d18eb35Madan Ankapura 9098773c8cfeef655fa63d95134c94b5a79d18eb35Madan Ankapura fw.firmware = image_data; 9198773c8cfeef655fa63d95134c94b5a79d18eb35Madan Ankapura fw.size = image_size; 9298773c8cfeef655fa63d95134c94b5a79d18eb35Madan Ankapura fw.is_delta = 0; 9398773c8cfeef655fa63d95134c94b5a79d18eb35Madan Ankapura 9498773c8cfeef655fa63d95134c94b5a79d18eb35Madan Ankapura ret = modem_download_ioctl_fw(IOCTL_MODEM_FW_UPDATE, &fw); 9598773c8cfeef655fa63d95134c94b5a79d18eb35Madan Ankapura if (ret < 0) { 9698773c8cfeef655fa63d95134c94b5a79d18eb35Madan Ankapura fprintf(stderr, "IOCTL_MODEM_FW_UPDATE failed: (%d)\n", ret); 9798773c8cfeef655fa63d95134c94b5a79d18eb35Madan Ankapura return -1; 9898773c8cfeef655fa63d95134c94b5a79d18eb35Madan Ankapura } 9998773c8cfeef655fa63d95134c94b5a79d18eb35Madan Ankapura 10098773c8cfeef655fa63d95134c94b5a79d18eb35Madan Ankapura ret = modem_download_ioctl(IOCTL_MODEM_BOOT_OFF); 10198773c8cfeef655fa63d95134c94b5a79d18eb35Madan Ankapura if (ret < 0) { 10298773c8cfeef655fa63d95134c94b5a79d18eb35Madan Ankapura fprintf(stderr, "IOCTL_MODEM_BOOT_OFF failed: (%d)\n", ret); 10398773c8cfeef655fa63d95134c94b5a79d18eb35Madan Ankapura return -1; 10498773c8cfeef655fa63d95134c94b5a79d18eb35Madan Ankapura } 10598773c8cfeef655fa63d95134c94b5a79d18eb35Madan Ankapura 10698773c8cfeef655fa63d95134c94b5a79d18eb35Madan Ankapura printf("Firmware update was successful\n"); 10798773c8cfeef655fa63d95134c94b5a79d18eb35Madan Ankapura 10898773c8cfeef655fa63d95134c94b5a79d18eb35Madan Ankapura return 0; 10998773c8cfeef655fa63d95134c94b5a79d18eb35Madan Ankapura} 110