aboutsummaryrefslogtreecommitdiffstats
path: root/samsung-ipc/device/galaxysmtd/galaxysmtd_ipc.c
diff options
context:
space:
mode:
Diffstat (limited to 'samsung-ipc/device/galaxysmtd/galaxysmtd_ipc.c')
-rw-r--r--samsung-ipc/device/galaxysmtd/galaxysmtd_ipc.c644
1 files changed, 0 insertions, 644 deletions
diff --git a/samsung-ipc/device/galaxysmtd/galaxysmtd_ipc.c b/samsung-ipc/device/galaxysmtd/galaxysmtd_ipc.c
deleted file mode 100644
index 7ddfb91..0000000
--- a/samsung-ipc/device/galaxysmtd/galaxysmtd_ipc.c
+++ /dev/null
@@ -1,644 +0,0 @@
-/**
- * This file is part of libsamsung-ipc.
- *
- * Copyright (C) 2011 Paul Kocialkowski <contact@paulk.fr>
- * Joerie de Gram <j.de.gram@gmail.com>
- * Simon Busch <morphis@gravedo.de>
- *
- * libsamsung-ipc is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * libsamsung-ipc is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with libsamsung-ipc. If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include <stdlib.h>
-#include <stdint.h>
-#include <unistd.h>
-#include <stdbool.h>
-#include <termios.h>
-#include <fcntl.h>
-#include <string.h>
-#include <sys/mman.h>
-#include <sys/ioctl.h>
-#include <sys/stat.h>
-#include <sys/socket.h>
-#include <sys/types.h>
-#include <asm/types.h>
-#include <mtd/mtd-abi.h>
-#include <assert.h>
-
-#include <radio.h>
-
-#include "galaxysmtd_modem_ctl.h"
-#include "galaxysmtd_nv_data.h"
-#include "galaxysmtd_ipc.h"
-#include "ipc_private.h"
-
-int wake_lock_fd= -1;
-int wake_unlock_fd= -1;
-
-int galaxysmtd_modem_bootstrap(struct ipc_client *client)
-{
- int s3c2410_serial3_fd= -1;
- int modem_ctl_fd= -1;
-
- /* Control variables. */
- int boot_tries_count=0;
- int rc=0;
-
- /* Boot variables */
- uint8_t *radio_img_p=NULL;
- uint8_t bootcore_version=0;
- uint8_t info_size=0;
- uint8_t crc_byte=0;
- int block_size=0;
-
- /* s3c2410 serial setup variables. */
- struct termios termios;
- int serial;
-
- /* fds maniplation variables */
- struct timeval timeout;
- fd_set fds;
-
- /* nv_data variables */
- void *nv_data_p;
-
- /* General purpose variables. */
- uint8_t data;
- uint16_t data_16;
- uint8_t *data_p;
- unsigned int modem_ctl_data;
- int i;
- void *onedram_map=NULL;
-
- ipc_client_log(client, "galaxysmtd_ipc_bootstrap: enter");
-
-boot_loop_start:
- if(boot_tries_count > 5)
- {
- ipc_client_log(client, "galaxysmtd_ipc_bootstrap: boot has failed too many times.");
- goto error;
- }
-
- //TODO try to disable svnet0 first?
-
- /* Read the radio.img image. */
- ipc_client_log(client, "galaxysmtd_ipc_bootstrap: reading radio image");
- radio_img_p = ipc_mtd_read(client, "/dev/block/bml12", RADIO_IMG_SIZE, 0x1000);
- if (radio_img_p == NULL) {
- goto error;
- }
- ipc_client_log(client, "galaxysmtd_ipc_bootstrap: radio image read");
-
- ipc_client_log(client, "galaxysmtd_ipc_bootstrap: open modem_ctl");
- modem_ctl_fd = open("/dev/onedram", O_RDWR);
- if(modem_ctl_fd < 0)
- goto error_loop;
-
- /* Reset the modem before init to send the first part of modem.bin. */
- ipc_client_power_off(client);
- ipc_client_log(client, "galaxysmtd_ipc_bootstrap: sent PHONE \"off\" command");
- usleep(1000);
- ipc_client_power_on(client);
- ipc_client_log(client, "galaxysmtd_ipc_bootstrap: sent PHONE \"on\" command");
- usleep(200000);
-
- ipc_client_log(client, "galaxysmtd_ipc_bootstrap: open s3c2410_serial3");
- s3c2410_serial3_fd = open("/dev/s3c2410_serial3", O_RDWR);
- if(s3c2410_serial3_fd < 0)
- goto error_loop;
-
- /* Setup the s3c2410 serial. */
- ipc_client_log(client, "galaxysmtd_ipc_bootstrap: setup s3c2410_serial3");
-
- ioctl(s3c2410_serial3_fd, TIOCMGET, &serial); //FIXME
- ioctl(s3c2410_serial3_fd, TIOCMSET, &serial); //FIXME
-
- tcgetattr(s3c2410_serial3_fd, &termios); //FIXME
- tcsetattr(s3c2410_serial3_fd, TCSANOW, &termios); //FIXME
-
- tcgetattr(s3c2410_serial3_fd, &termios);
-
- cfmakeraw(&termios);
- cfsetispeed(&termios, B115200);
- cfsetospeed(&termios, B115200);
-
- tcsetattr(s3c2410_serial3_fd, TCSANOW, &termios);
-
- /* Send 'AT' in ASCII. */
- ipc_client_log(client, "galaxysmtd_ipc_bootstrap: sending AT in ASCII");
- for(i=0 ; i < 20 ; i++)
- {
- rc = write(s3c2410_serial3_fd, "AT", 2);
- usleep(50000);
- }
- ipc_client_log(client, "galaxysmtd_ipc_bootstrap: sending AT in ASCII done");
-
- usleep(50000); //FIXME
-
- /* Get and check bootcore version. */
- read(s3c2410_serial3_fd, &bootcore_version, sizeof(bootcore_version));
- ipc_client_log(client, "galaxysmtd_ipc_bootstrap: got bootcore version: 0x%x", bootcore_version);
-
- if(bootcore_version != BOOTCORE_VERSION)
- goto error_loop;
-
- /* Get info_size. */
- read(s3c2410_serial3_fd, &info_size, sizeof(info_size));
- ipc_client_log(client, "galaxysmtd_ipc_bootstrap: got info_size: 0x%x", info_size);
-
- /* Send PSI magic. */
- data=PSI_MAGIC;
- write(s3c2410_serial3_fd, &data, sizeof(data));
- ipc_client_log(client, "galaxysmtd_ipc_bootstrap: sent PSI_MAGIC (0x%x)", PSI_MAGIC);
-
- /* Send PSI data len. */
- data_16=PSI_DATA_LEN;
- data_p=(uint8_t *)&data_16;
-
- for(i=0 ; i < 2 ; i++)
- {
- write(s3c2410_serial3_fd, data_p, 1);
- data_p++;
- }
- ipc_client_log(client, "galaxysmtd_ipc_bootstrap: sent PSI_DATA_LEN (0x%x)", PSI_DATA_LEN);
-
- /* Write the first part of modem.img. */
- FD_ZERO(&fds);
- FD_SET(s3c2410_serial3_fd, &fds);
-
- timeout.tv_sec=5;
- timeout.tv_usec=0;
-
- data_p=radio_img_p;
-
- ipc_client_log(client, "galaxysmtd_ipc_bootstrap: sending the first part of modem.bin");
-
- crc_byte=0;
- for(i=0 ; i < PSI_DATA_LEN ; i++)
- {
- if(select(FD_SETSIZE, NULL, &fds, NULL, &timeout) == 0)
- {
- ipc_client_log(client, "galaxysmtd_ipc_bootstrap: select timeout passed");
- goto error_loop;
- }
-
- write(s3c2410_serial3_fd, data_p, 1);
- crc_byte=crc_byte ^ *data_p;
-
- data_p++;
- }
-
- ipc_client_log(client, "galaxysmtd_ipc_bootstrap: first part of modem.bin sent; crc_byte is 0x%x", crc_byte);
-
- if(select(FD_SETSIZE, NULL, &fds, NULL, &timeout) == 0)
- {
- ipc_client_log(client, "galaxysmtd_ipc_bootstrap: select timeout passed");
- goto error_loop;
- }
-
- write(s3c2410_serial3_fd, &crc_byte, sizeof(crc_byte));
-
- ipc_client_log(client, "galaxysmtd_ipc_bootstrap: crc_byte sent");
-
- ipc_client_log(client, "galaxysmtd_ipc_bootstrap: wait for ACK");
- data = 0;
- for(i = 0 ; data != 0x01 ; i++)
- {
- if(select(FD_SETSIZE, &fds, NULL, NULL, &timeout) == 0)
- {
- ipc_client_log(client, "galaxysmtd_ipc_bootstrap: select timeout passed");
- goto error_loop;
- }
-
- read(s3c2410_serial3_fd, &data, sizeof(data));
-
- if(i > 50)
- {
- ipc_client_log(client, "galaxysmtd_ipc_bootstrap: fairly too much attempts to get ACK");
- goto error_loop;
- }
- }
- ipc_client_log(client, "galaxysmtd_ipc_bootstrap: got ACK");
-
- ipc_client_log(client, "galaxysmtd_ipc_bootstrap: close s3c2410_serial3");
- close(s3c2410_serial3_fd);
-
- FD_ZERO(&fds);
- FD_SET(modem_ctl_fd, &fds);
-
- ipc_client_log(client, "galaxysmtd_ipc_bootstrap: wait for 0x12341234");
- if(select(modem_ctl_fd+1, &fds, NULL, NULL, &timeout) == 0)
- {
- ipc_client_log(client, "galaxysmtd_ipc_bootstrap: select timeout passed");
- goto error_loop;
- }
-
- read(modem_ctl_fd, &modem_ctl_data, sizeof(modem_ctl_data));
- if(modem_ctl_data != 0x12341234) {
- ipc_client_log(client, "galaxysmtd_ipc_bootstrap: wrong ACK flag from modem_ctl");
- goto error_loop;
- }
- ipc_client_log(client, "galaxysmtd_ipc_bootstrap: got 0x12341234");
-
- ipc_client_log(client, "galaxysmtd_ipc_bootstrap: writing the rest of modem.bin to modem_ctl.");
-
- /* Pointer to the remaining part of radio.img. */
- data_p=radio_img_p + PSI_DATA_LEN;
-
- size_t map_length = 16773120; //magic buflen comes from proprietary ril trace
- onedram_map = mmap(NULL, map_length, PROT_READ|PROT_WRITE, MAP_SHARED, modem_ctl_fd, 0);
- if(onedram_map == -1) {
- ipc_client_log(client, "galaxysmtd_ipc_bootstrap: could not map onedram to memory");
- goto error_loop;
- }
-
- memcpy(onedram_map, data_p, RADIO_IMG_SIZE - PSI_DATA_LEN);
-
- free(radio_img_p);
-
- /* nv_data part. */
-
- /* Check if all the nv_data files are ok. */
- nv_data_check(client);
-
- /* Check if the MD5 is ok. */
- nv_data_md5_check(client);
-
- /* Write nv_data.bin to modem_ctl. */
- ipc_client_log(client, "galaxysmtd_ipc_bootstrap: write nv_data to modem_ctl");
-
- nv_data_p = ipc_file_read(client, "/efs/nv_data.bin", NV_DATA_SIZE, 1024);
- if (nv_data_p == NULL)
- goto error;
- data_p = nv_data_p;
-
- //seems 0xd80000 is the absolute maximum for the radio_img, like crespo
- //uses. it creates a gap though, since we only write 0x9fb000 bytes to /dev/onedram
- memcpy(onedram_map + 0xd80000, data_p, NV_DATA_SIZE);
-
- ipc_client_log(client, "galaxysmtd_ipc_bootstrap: done writing nv_data");
-
- free(nv_data_p);
- munmap(onedram_map, map_length);
-
- //TODO finalize bootstrap
- ioctl(modem_ctl_fd, 0x6f22, 0); //magic request comes from proprietary ril trace
-
- ipc_client_log(client, "galaxysmtd_ipc_bootstrap: send 0x45674567");
- modem_ctl_data = 0x45674567;
- write(modem_ctl_fd, &modem_ctl_data, sizeof(modem_ctl_data));
-
- ipc_client_log(client, "galaxysmtd_ipc_bootstrap: wait for 0xabcdabcd");
- for(i = 0 ; modem_ctl_data != 0xabcdabcd ; i++)
- {
- if(select(FD_SETSIZE, &fds, NULL, NULL, &timeout) == 0)
- {
- ipc_client_log(client, "galaxysmtd_ipc_bootstrap: select timeout passed");
- goto error_loop;
- }
-
- read(modem_ctl_fd, &modem_ctl_data, sizeof(modem_ctl_data));
-
- if(i > 10)
- {
- ipc_client_log(client, "galaxysmtd_ipc_bootstrap: fairly too much attempts to get 0xabcdabcd");
- goto error_loop;
- }
- }
- ipc_client_log(client, "galaxysmtd_ipc_bootstrap: got 0xabcdabcd");
-
- close(modem_ctl_fd);
-
- rc = 0;
- goto exit;
-
-error_loop:
- ipc_client_log(client, "%s: something went wrong", __func__);
- boot_tries_count++;
- sleep(2);
-
- goto boot_loop_start;
-
-error:
- ipc_client_log(client, "%s: something went wrong", __func__);
- rc = 1;
-exit:
- ipc_client_log(client, "galaxysmtd_ipc_bootstrap: exit");
- return rc;
-}
-
-int crespo_ipc_client_send(struct ipc_client *client, struct ipc_message_info *request)
-{
- struct modem_io modem_data;
- struct ipc_header reqhdr;
- int rc = 0;
-
- memset(&modem_data, 0, sizeof(struct modem_io));
- modem_data.size = request->length + sizeof(struct ipc_header);
-
- reqhdr.mseq = request->mseq;
- reqhdr.aseq = request->aseq;
- reqhdr.group = request->group;
- reqhdr.index = request->index;
- reqhdr.type = request->type;
- reqhdr.length = (uint16_t) (request->length + sizeof(struct ipc_header));
-
- modem_data.data = malloc(reqhdr.length);
-
- memcpy(modem_data.data, &reqhdr, sizeof(struct ipc_header));
- memcpy((unsigned char *) (modem_data.data + sizeof(struct ipc_header)), request->data, request->length);
-
- assert(client->handlers->write != NULL);
-
- ipc_client_log(client, "INFO: crespo_ipc_client_send: Modem SEND FMT (id=%d cmd=%d size=%d)!", modem_data.id, modem_data.cmd, modem_data.size);
- ipc_client_log(client, "INFO: crespo_ipc_client_send: request: type = %d (%s), group = %d, index = %d (%s)",
- request->type, ipc_request_type_to_str(request->type), request->group, request->index, ipc_command_type_to_str(IPC_COMMAND(request)));
-
-#ifdef DEBUG
- if(request->length > 0)
- {
- ipc_client_log(client, "INFO: ==== DATA DUMP ====");
- ipc_hex_dump(client, (void *) request->data, request->length);
- }
-#endif
-
- ipc_client_log(client, "");
-
- rc = client->handlers->write((uint8_t*) &modem_data, sizeof(struct modem_io), client->handlers->write_data);
- return rc;
-}
-
-int wake_lock(char *lock_name, int len)
-{
- int rc = 0;
-
- wake_lock_fd = open("/sys/power/wake_lock", O_RDWR);
- rc = write(wake_lock_fd, lock_name, len);
- close(wake_lock_fd);
-
- return rc;
-}
-
-int wake_unlock(char *lock_name, int len)
-{
- int rc = 0;
-
- wake_lock_fd = open("/sys/power/wake_unlock", O_RDWR);
- rc = write(wake_lock_fd, lock_name, len);
- close(wake_unlock_fd);
-
- return rc;
-}
-
-int galaxysmtd_ipc_client_recv(struct ipc_client *client, struct ipc_message_info *response)
-{
- struct modem_io modem_data;
- struct ipc_header *resphdr;
- int bread = 0;
-
- memset(&modem_data, 0, sizeof(struct modem_io));
- modem_data.data = malloc(MAX_MODEM_DATA_SIZE);
- modem_data.size = MAX_MODEM_DATA_SIZE;
-
- memset(response, 0, sizeof(struct ipc_message_info));
-
- wake_lock("secril_fmt-interface", 20);
-
- assert(client->handlers->read != NULL);
- ipc_client_log(client, "INFO: galaxysmtd_ipc_client_recv -> read");
- bread = client->handlers->read((uint8_t*) &modem_data, sizeof(struct modem_io) + MAX_MODEM_DATA_SIZE, client->handlers->read_data);
- ipc_client_log(client, "INFO: galaxysmtd_ipc_client_recv read something");
- if (bread < 0)
- {
- ipc_client_log(client, "ERROR: galaxysmtd_ipc_client_recv: can't receive enough bytes from modem to process incoming response!");
- return 1;
- }
-
- ipc_client_log(client, "INFO: galaxysmtd_ipc_client_recv: Modem RECV FMT (id=%d cmd=%d size=%d)!", modem_data.id, modem_data.cmd, modem_data.size);
-
- if(modem_data.size <= 0 || modem_data.size >= 0x1000 || modem_data.data == NULL)
- {
- ipc_client_log(client, "ERROR: galaxysmtd_ipc_client_recv: we retrieve less bytes from the modem than we exepected!");
- return 1;
- }
-
- /* You MUST send back modem_data */
-
- resphdr = (struct ipc_header *) modem_data.data;
-
- response->mseq = resphdr->mseq;
- response->aseq = resphdr->aseq;
- response->group = resphdr->group;
- response->index = resphdr->index;
- response->type = resphdr->type;
- response->length = modem_data.size - sizeof(struct ipc_header);
- response->data = NULL;
-
- ipc_client_log(client, "INFO: crespo_ipc_client_recv: response: type = %d (%s), group = %d, index = %d (%s)",
- resphdr->type, ipc_response_type_to_str(resphdr->type), resphdr->group, resphdr->index, ipc_command_type_to_str(IPC_COMMAND(resphdr)));
-
- if(response->length > 0)
- {
-#ifdef DEBUG
- ipc_client_log(client, "INFO: ==== DATA DUMP ====");
- ipc_hex_dump(client, (void *) (modem_data.data + sizeof(struct ipc_header)), response->length);
-#endif
- response->data = malloc(response->length);
- memcpy(response->data, (uint8_t *) modem_data.data + sizeof(struct ipc_header), response->length);
- }
-
- free(modem_data.data);
-
- ipc_client_log(client, "");
-
- wake_unlock("secril_fmt-interface", 20);
-
- return 0;
-}
-
-int galaxysmtd_ipc_open(void *data, unsigned int size, void *io_data)
-{
- int type = *((int *) data);
- int fd = -1;
- int ret;
- char sadata[14];
-
- if(io_data == NULL)
- goto error;
-
- memset(sadata, 0, 14);
-
- const struct sockaddr saddr = {
- .sa_family = 0x23,
- .sa_data = sadata,
- };
-
- switch(type)
- {
- case IPC_CLIENT_TYPE_FMT:
- sadata[2] = 1;
- break;
- case IPC_CLIENT_TYPE_RFS:
- sadata[2] = 'A';
- break;
- default:
- break;
- }
-
- fd = socket(0x23, SOCK_DGRAM, 0);
-
- if(fd < 0)
- goto error;
-
- ret = setsockopt(fd, SOL_SOCKET, SO_BINDTODEVICE, "svnet0", 16);
- if(ret<0)
- goto error;
-
- ret = setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, "\1\0\0\0", 4);
- if(ret<0)
- goto error;
-
- ret = bind(fd, &saddr, sizeof(struct sockaddr));
- if(ret<0)
- goto error;
-
- if(type == IPC_CLIENT_TYPE_RFS) {
- ret = setsockopt(fd, SOL_SOCKET, 0x21, "", 4);
- }
-
- *((int*)io_data) = fd;
- goto end;
-
-error:
- return -1;
-
-end:
- return 0;
-}
-
-int crespo_ipc_close(void *data, unsigned int size, void *io_data)
-{
- int fd = -1;
-
- if(io_data == NULL)
- return -1;
-
- fd = *((int *) io_data);
-
- if(fd < 0)
- return -1;
-
- close(fd);
-
- return 0;
-}
-
-int galaxysmtd_ipc_read(void *data, unsigned int size, void *io_data)
-{
- int fd = -1;
- int rc;
-
- if(io_data == NULL)
- return -1;
-
- if(data == NULL)
- return -1;
-
- fd = *((int *) io_data);
-
- if(fd < 0)
- return -1;
-
- rc = recvfrom(fd, data, size, 0, NULL, NULL);
-
- if(rc < 0)
- return -1;
-
- return 0;
-}
-
-int crespo_ipc_write(void *data, unsigned int size, void *io_data)
-{
- int fd = -1;
- int rc;
-
- if(io_data == NULL)
- return -1;
-
- fd = *((int *) io_data);
-
- if(fd < 0)
- return -1;
-
- rc = ioctl(fd, IOCTL_MODEM_SEND, data);
-
- if(rc < 0)
- return -1;
-
- return 0;
-}
-
-int galaxysmtd_ipc_power_on(void *data)
-{
- int fd = open("/sys/class/modemctl/xmm/control", O_RDWR);
- int rc;
-
- if(fd < 0)
- return -1;
-
- rc = write(fd, "on", 2);
- close(fd);
-
- if(rc < 0)
- return -1;
-
- //TODO should check if nothing was written as well?
-
- return 0;
-}
-
-int galaxysmtd_ipc_power_off(void *data)
-{
- int fd = open("/sys/class/modemctl/xmm/control", O_RDWR);
- int rc;
-
- if(fd < 0)
- return -1;
-
- rc = write(fd, "off", 3);
- close(fd);
-
- if(rc < 0)
- return -1;
-
- //TODO should check if nothing was written as well?
-
- return 0;
-}
-
-struct ipc_handlers ipc_default_handlers = {
- .read = galaxysmtd_ipc_read,
- .write = crespo_ipc_write,
- .open = galaxysmtd_ipc_open,
- .close = crespo_ipc_close,
- .power_on = galaxysmtd_ipc_power_on,
- .power_off = galaxysmtd_ipc_power_off,
-};
-
-struct ipc_ops ipc_ops = {
- .send = crespo_ipc_client_send,
- .recv = galaxysmtd_ipc_client_recv,
- .bootstrap = galaxysmtd_modem_bootstrap,
-};
-
-// vim:ts=4:sw=4:expandtab