diff options
author | Paul Kocialkowski <contact@paulk.fr> | 2012-07-05 12:34:02 +0200 |
---|---|---|
committer | Paul Kocialkowski <contact@paulk.fr> | 2012-07-05 12:34:02 +0200 |
commit | 985b168dc576ed35de631ff495fc30c6d2ffec50 (patch) | |
tree | db74af069b1aeda04e84a5db26dec23062347cca /samsung-ipc | |
parent | d4f9b162481e41076dd6520141b89db25e530d2d (diff) | |
download | hardware_replicant_libsamsung-ipc-985b168dc576ed35de631ff495fc30c6d2ffec50.tar.gz hardware_replicant_libsamsung-ipc-985b168dc576ed35de631ff495fc30c6d2ffec50.tar.bz2 hardware_replicant_libsamsung-ipc-985b168dc576ed35de631ff495fc30c6d2ffec50.zip |
XMM6260: Reworked modemctl and brought ipc client to most functions
* Radio parts are now generic for XMM6260 devices
* ipc client structure is now brought to most functions, to be used for logging
* fwloader_context was renamed to struct modemctl_io_data
* Generic XMM6260 radio parts are now part of struct modemctl_io_data
* Bare ioctls are used in modemctl (no need to log success)
Signed-off-by: Paul Kocialkowski <contact@paulk.fr>
Diffstat (limited to 'samsung-ipc')
-rw-r--r-- | samsung-ipc/device/xmm6260/fwloader_i9100.c | 219 | ||||
-rw-r--r-- | samsung-ipc/device/xmm6260/fwloader_i9100.h | 7 | ||||
-rw-r--r-- | samsung-ipc/device/xmm6260/fwloader_i9250.c | 215 | ||||
-rw-r--r-- | samsung-ipc/device/xmm6260/fwloader_i9250.h | 11 | ||||
-rw-r--r-- | samsung-ipc/device/xmm6260/modemctl_common.c | 40 | ||||
-rw-r--r-- | samsung-ipc/device/xmm6260/modemctl_common.h | 94 |
6 files changed, 299 insertions, 287 deletions
diff --git a/samsung-ipc/device/xmm6260/fwloader_i9100.c b/samsung-ipc/device/xmm6260/fwloader_i9100.c index f8b4312..02b3720 100644 --- a/samsung-ipc/device/xmm6260/fwloader_i9100.c +++ b/samsung-ipc/device/xmm6260/fwloader_i9100.c @@ -27,7 +27,7 @@ * Locations of the firmware components in the Samsung firmware */ -struct i9100_radio_part i9100_radio_parts[] = { +struct xmm6260_radio_part i9100_radio_parts[] = { [PSI] = { .offset = 0, .length = 0xf000, @@ -83,26 +83,27 @@ struct i9100_boot_cmd_desc i9100_boot_cmd_desc[] = { } }; -static int send_image(fwloader_context *ctx, enum xmm6260_image type) { +static int send_image(struct ipc_client *client, + struct modemctl_io_data *io_data, enum xmm6260_image type) { int ret = -1; - - if (type >= ARRAY_SIZE(i9100_radio_parts)) { + + if (type >= io_data->radio_parts_count) { _e("bad image type %x", type); goto fail; } - size_t length = i9100_radio_parts[type].length; - size_t offset = i9100_radio_parts[type].offset; + size_t length = io_data->radio_parts[type].length; + size_t offset = io_data->radio_parts[type].offset; size_t start = offset; size_t end = length + start; //dump some image bytes _d("image start"); - hexdump(ctx->radio_data + start, length); +// hexdump(io_data->radio_data + start, length); while (start < end) { - ret = write(ctx->boot_fd, ctx->radio_data + start, end - start); + ret = write(io_data->boot_fd, io_data->radio_data + start, end - start); if (ret < 0) { _d("failed to write image chunk"); goto fail; @@ -110,9 +111,9 @@ static int send_image(fwloader_context *ctx, enum xmm6260_image type) { start += ret; } - unsigned char crc = calculateCRC(ctx->radio_data, offset, length); + unsigned char crc = calculateCRC(io_data->radio_data, offset, length); - if ((ret = write(ctx->boot_fd, &crc, 1)) < 1) { + if ((ret = write(io_data->boot_fd, &crc, 1)) < 1) { _d("failed to write CRC"); goto fail; } @@ -126,7 +127,7 @@ fail: return ret; } -static int send_PSI(fwloader_context *ctx) { +static int send_PSI(struct ipc_client *client, struct modemctl_io_data *io_data) { size_t length = i9100_radio_parts[PSI].length; struct i9100_psi_header hdr = { @@ -135,13 +136,13 @@ static int send_PSI(fwloader_context *ctx) { .padding = 0xff, }; int ret = -1; - - if ((ret = write(ctx->boot_fd, &hdr, sizeof(hdr))) != sizeof(hdr)) { + + if ((ret = write(io_data->boot_fd, &hdr, sizeof(hdr))) != sizeof(hdr)) { _d("%s: failed to write header, ret %d", __func__, ret); goto fail; } - if ((ret = send_image(ctx, PSI)) < 0) { + if ((ret = send_image(client, io_data, PSI)) < 0) { _e("failed to send PSI image"); goto fail; } @@ -149,24 +150,24 @@ static int send_PSI(fwloader_context *ctx) { int i; for (i = 0; i < 22; i++) { char ack; - if (receive(ctx->boot_fd, &ack, 1) < 1) { + if (receive(io_data->boot_fd, &ack, 1) < 1) { _d("failed to read ACK byte %d", i); goto fail; } _d("%02x ", ack); } - if ((ret = expect_data(ctx->boot_fd, "\x1", 1)) < 0) { + if ((ret = expect_data(io_data->boot_fd, "\x1", 1)) < 0) { _d("failed to wait for first ACK"); goto fail; } - if ((ret = expect_data(ctx->boot_fd, "\x1", 1)) < 0) { + if ((ret = expect_data(io_data->boot_fd, "\x1", 1)) < 0) { _d("failed to wait for second ACK"); goto fail; } - - if ((ret = expect_data(ctx->boot_fd, PSI_ACK_MAGIC, 2)) < 0) { + + if ((ret = expect_data(io_data->boot_fd, PSI_ACK_MAGIC, 2)) < 0) { _e("failed to receive PSI ACK"); goto fail; } @@ -180,9 +181,9 @@ fail: return ret; } -static int send_EBL(fwloader_context *ctx) { +static int send_EBL(struct ipc_client *client, struct modemctl_io_data *io_data) { int ret; - int fd = ctx->boot_fd; + int fd = io_data->boot_fd; unsigned length = i9100_radio_parts[EBL].length; if ((ret = write(fd, &length, sizeof(length))) < 0) { @@ -194,12 +195,12 @@ static int send_EBL(fwloader_context *ctx) { _e("failed to wait for EBL header ACK"); goto fail; } - - if ((ret = send_image(ctx, EBL)) < 0) { + + if ((ret = send_image(client, io_data, EBL)) < 0) { _e("failed to send EBL image"); goto fail; } - + if ((ret = expect_data(fd, EBL_IMG_ACK_MAGIC, 2)) < 0) { _e("failed to wait for EBL image ACK"); goto fail; @@ -211,7 +212,8 @@ fail: return ret; } -static int bootloader_cmd(fwloader_context *ctx, enum xmm6260_boot_cmd cmd, +static int bootloader_cmd(struct ipc_client *client, + struct modemctl_io_data *io_data, enum xmm6260_boot_cmd cmd, void *data, size_t data_size) { int ret = 0; @@ -252,7 +254,7 @@ static int bootloader_cmd(fwloader_context *ctx, enum xmm6260_boot_cmd cmd, _d("bootloader cmd packet"); hexdump(cmd_data, buf_size); - if ((ret = write(ctx->boot_fd, cmd_data, buf_size)) < 0) { + if ((ret = write(io_data->boot_fd, cmd_data, buf_size)) < 0) { _e("failed to write command to socket"); goto done_or_fail; } @@ -273,7 +275,7 @@ static int bootloader_cmd(fwloader_context *ctx, enum xmm6260_boot_cmd cmd, struct i9100_boot_cmd ack = { .check = 0, }; - if ((ret = receive(ctx->boot_fd, &ack, sizeof(ack))) < 0) { + if ((ret = receive(io_data->boot_fd, &ack, sizeof(ack))) < 0) { _e("failed to receive ack for cmd %x", header.cmd); goto done_or_fail; } @@ -292,7 +294,7 @@ static int bootloader_cmd(fwloader_context *ctx, enum xmm6260_boot_cmd cmd, goto done_or_fail; } - if ((ret = receive(ctx->boot_fd, cmd_data, cmd_size)) < 0) { + if ((ret = receive(io_data->boot_fd, cmd_data, cmd_size)) < 0) { _e("failed to receive reply data"); goto done_or_fail; } @@ -313,11 +315,12 @@ done_or_fail: return ret; } -static int ack_BootInfo(fwloader_context *ctx) { +static int ack_BootInfo(struct ipc_client *client, + struct modemctl_io_data *io_data) { int ret; struct i9100_boot_info info; - - if ((ret = receive(ctx->boot_fd, &info, sizeof(info))) != sizeof(info)) { + + if ((ret = receive(io_data->boot_fd, &info, sizeof(info))) != sizeof(info)) { _e("failed to receive Boot Info ret=%d", ret); ret = -1; goto fail; @@ -327,7 +330,7 @@ static int ack_BootInfo(fwloader_context *ctx) { hexdump(&info, sizeof(info)); } - if ((ret = bootloader_cmd(ctx, SetPortConf, &info, sizeof(info))) < 0) { + if ((ret = bootloader_cmd(client, io_data, SetPortConf, &info, sizeof(info))) < 0) { _e("failed to send SetPortConf command"); goto fail; } @@ -341,14 +344,15 @@ fail: return ret; } -static int send_image_data(fwloader_context *ctx, uint32_t addr, +static int send_image_data(struct ipc_client *client, + struct modemctl_io_data *io_data, uint32_t addr, void *data, int data_len) { int ret = 0; int count = 0; char *data_p = (char *) data; - if ((ret = bootloader_cmd(ctx, ReqFlashSetAddress, &addr, 4)) < 0) { + if ((ret = bootloader_cmd(client, io_data, ReqFlashSetAddress, &addr, 4)) < 0) { _e("failed to send ReqFlashSetAddress"); goto fail; } @@ -360,7 +364,7 @@ static int send_image_data(fwloader_context *ctx, uint32_t addr, int rest = data_len - count; int chunk = rest < SEC_DOWNLOAD_CHUNK ? rest : SEC_DOWNLOAD_CHUNK; - ret = bootloader_cmd(ctx, ReqFlashWriteBlock, data_p, chunk); + ret = bootloader_cmd(client, io_data, ReqFlashWriteBlock, data_p, chunk); if (ret < 0) { _e("failed to send data chunk"); goto fail; @@ -376,28 +380,29 @@ fail: return ret; } -static int send_image_addr(fwloader_context *ctx, uint32_t addr, - enum xmm6260_image type) +static int send_image_addr(struct ipc_client *client, + struct modemctl_io_data *io_data, uint32_t addr, enum xmm6260_image type) { uint32_t offset = i9100_radio_parts[type].offset; uint32_t length = i9100_radio_parts[type].length; - char *start = ctx->radio_data + offset; + char *start = io_data->radio_data + offset; int ret = 0; - ret = send_image_data(ctx, addr, start, length); + ret = send_image_data(client, io_data, addr, start, length); return ret; } -static int send_SecureImage(fwloader_context *ctx) { +static int send_SecureImage(struct ipc_client *client, + struct modemctl_io_data *io_data) { int ret = 0; uint32_t sec_off = i9100_radio_parts[SECURE_IMAGE].offset; uint32_t sec_len = i9100_radio_parts[SECURE_IMAGE].length; - void *sec_img = ctx->radio_data + sec_off; + void *sec_img = io_data->radio_data + sec_off; void *nv_data = NULL; - if ((ret = bootloader_cmd(ctx, ReqSecStart, sec_img, sec_len)) < 0) { + if ((ret = bootloader_cmd(client, io_data, ReqSecStart, sec_img, sec_len)) < 0) { _e("failed to write ReqSecStart"); goto fail; } @@ -405,7 +410,7 @@ static int send_SecureImage(fwloader_context *ctx) { _d("sent ReqSecStart"); } - if ((ret = send_image_addr(ctx, FW_LOAD_ADDR, FIRMWARE)) < 0) { + if ((ret = send_image_addr(client, io_data, FW_LOAD_ADDR, FIRMWARE)) < 0) { _e("failed to send FIRMWARE image"); goto fail; } @@ -413,16 +418,16 @@ static int send_SecureImage(fwloader_context *ctx) { _d("sent FIRMWARE image"); } - nv_data_check(ctx->client); - nv_data_md5_check(ctx->client); + nv_data_check(client); + nv_data_md5_check(client); - nv_data = ipc_file_read(ctx->client, nv_data_path(ctx->client), 2 << 20, 1024); + nv_data = ipc_file_read(client, nv_data_path(client), 2 << 20, 1024); if (nv_data == NULL) { _e("failed to read NVDATA image"); goto fail; } - if ((ret = send_image_data(ctx, NVDATA_LOAD_ADDR, nv_data, 2 << 20)) < 0) { + if ((ret = send_image_data(client, io_data, NVDATA_LOAD_ADDR, nv_data, 2 << 20)) < 0) { _e("failed to send NVDATA image"); goto fail; } @@ -432,7 +437,7 @@ static int send_SecureImage(fwloader_context *ctx) { free(nv_data); - if ((ret = bootloader_cmd(ctx, ReqSecEnd, + if ((ret = bootloader_cmd(client, io_data, ReqSecEnd, BL_END_MAGIC, BL_END_MAGIC_LEN)) < 0) { _e("failed to write ReqSecEnd"); @@ -442,7 +447,7 @@ static int send_SecureImage(fwloader_context *ctx) { _d("sent ReqSecEnd"); } - ret = bootloader_cmd(ctx, ReqForceHwReset, + ret = bootloader_cmd(client, io_data, ReqForceHwReset, BL_RESET_MAGIC, BL_RESET_MAGIC_LEN); if (ret < 0) { _e("failed to write ReqForceHwReset"); @@ -463,11 +468,11 @@ fail: /* * Power management */ -static int i9100_ehci_setpower(bool enabled) { +static int i9100_ehci_setpower(struct ipc_client *client, bool enabled) { int ret = -1; - + _d("%s: enabled=%d", __func__, enabled); - + int ehci_fd = open(I9100_EHCI_PATH, O_RDWR); if (ehci_fd < 0) { _e("failed to open EHCI fd"); @@ -496,12 +501,13 @@ fail: return ret; } -static int reboot_modem_i9100(fwloader_context *ctx, bool hard) { +static int reboot_modem_i9100(struct ipc_client *client, + struct modemctl_io_data *io_data, bool hard) { int ret; - + //wait for link to become ready before redetection if (!hard) { - if ((ret = modemctl_wait_link_ready(ctx)) < 0) { + if ((ret = modemctl_wait_link_ready(client, io_data)) < 0) { _e("failed to wait for link to get ready for redetection"); goto fail; } @@ -513,8 +519,8 @@ static int reboot_modem_i9100(fwloader_context *ctx, bool hard) { /* * Disable the hardware to ensure consistent state */ - if (hard) { - if ((ret = modemctl_modem_power(ctx, false)) < 0) { + if (hard) { + if ((ret = modemctl_modem_power(client, io_data, false)) < 0) { _e("failed to disable xmm6260 power"); goto fail; } @@ -522,44 +528,44 @@ static int reboot_modem_i9100(fwloader_context *ctx, bool hard) { _d("disabled xmm6260 power"); } } - - if ((ret = modemctl_link_set_enabled(ctx, false)) < 0) { + + if ((ret = modemctl_link_set_enabled(client, io_data, false)) < 0) { _e("failed to disable I9100 HSIC link"); goto fail; } else { _d("disabled I9100 HSIC link"); } - - if ((ret = i9100_ehci_setpower(false)) < 0) { + + if ((ret = i9100_ehci_setpower(client, false)) < 0) { _e("failed to disable I9100 EHCI"); goto fail; } else { _d("disabled I9100 EHCI"); } - - if ((ret = modemctl_link_set_active(ctx, false)) < 0) { + + if ((ret = modemctl_link_set_active(client, io_data, false)) < 0) { _e("failed to deactivate I9100 HSIC link"); goto fail; } else { _d("deactivated I9100 HSIC link"); } - + /* * Now, initialize the hardware */ - - if ((ret = modemctl_link_set_enabled(ctx, true)) < 0) { + + if ((ret = modemctl_link_set_enabled(client, io_data, true)) < 0) { _e("failed to enable I9100 HSIC link"); goto fail; } else { _d("enabled I9100 HSIC link"); } - - if ((ret = i9100_ehci_setpower(true)) < 0) { + + if ((ret = i9100_ehci_setpower(client, true)) < 0) { _e("failed to enable I9100 EHCI"); goto fail; } @@ -567,16 +573,16 @@ static int reboot_modem_i9100(fwloader_context *ctx, bool hard) { _d("enabled I9100 EHCI"); } - if ((ret = modemctl_link_set_active(ctx, true)) < 0) { + if ((ret = modemctl_link_set_active(client, io_data, true)) < 0) { _e("failed to activate I9100 HSIC link"); goto fail; } else { _d("activated I9100 HSIC link"); } - + if (hard) { - if ((ret = modemctl_modem_power(ctx, true)) < 0) { + if ((ret = modemctl_modem_power(client, io_data, true)) < 0) { _e("failed to enable xmm6260 power"); goto fail; } @@ -585,65 +591,66 @@ static int reboot_modem_i9100(fwloader_context *ctx, bool hard) { } } - if ((ret = modemctl_wait_link_ready(ctx)) < 0) { + if ((ret = modemctl_wait_link_ready(client, io_data)) < 0) { _e("failed to wait for link to get ready"); goto fail; } else { _d("link ready"); } - + fail: return ret; } int boot_modem_i9100(struct ipc_client *client) { int ret = 0; - fwloader_context ctx; - memset(&ctx, 0, sizeof(ctx)); + struct modemctl_io_data io_data; + memset(&io_data, 0, sizeof(client, io_data)); - ctx.client = client; + io_data.radio_parts = i9100_radio_parts; + io_data.radio_parts_count = ARRAY_SIZE(i9100_radio_parts); - ctx.radio_fd = open(RADIO_IMAGE, O_RDONLY); - if (ctx.radio_fd < 0) { + io_data.radio_fd = open(RADIO_IMAGE, O_RDONLY); + if (io_data.radio_fd < 0) { _e("failed to open radio firmware"); goto fail; } else { - _d("opened radio image %s, fd=%d", RADIO_IMAGE, ctx.radio_fd); + _d("opened radio image %s, fd=%d", RADIO_IMAGE, io_data.radio_fd); } - if (fstat(ctx.radio_fd, &ctx.radio_stat) < 0) { + if (fstat(io_data.radio_fd, &io_data.radio_stat) < 0) { _e("failed to stat radio image, error %s", strerror(errno)); goto fail; } - ctx.radio_data = mmap(0, RADIO_MAP_SIZE, PROT_READ, MAP_SHARED, - ctx.radio_fd, 0); - if (ctx.radio_data == MAP_FAILED) { + io_data.radio_data = mmap(0, RADIO_MAP_SIZE, PROT_READ, MAP_SHARED, + io_data.radio_fd, 0); + if (io_data.radio_data == MAP_FAILED) { _e("failed to mmap radio image, error %s", strerror(errno)); goto fail; } - ctx.boot_fd = open(BOOT_DEV, O_RDWR | O_NOCTTY | O_NONBLOCK); - if (ctx.boot_fd < 0) { + io_data.boot_fd = open(BOOT_DEV, O_RDWR | O_NOCTTY | O_NONBLOCK); + if (io_data.boot_fd < 0) { _e("failed to open boot device"); goto fail; } else { - _d("opened boot device %s, fd=%d", BOOT_DEV, ctx.boot_fd); + _d("opened boot device %s, fd=%d", BOOT_DEV, io_data.boot_fd); } - ctx.link_fd = open(LINK_PM, O_RDWR); - if (ctx.link_fd < 0) { + io_data.link_fd = open(LINK_PM, O_RDWR); + if (io_data.link_fd < 0) { _e("failed to open link device"); goto fail; } else { - _d("opened link device %s, fd=%d", LINK_PM, ctx.link_fd); + _d("opened link device %s, fd=%d", LINK_PM, io_data.link_fd); } - if (reboot_modem_i9100(&ctx, true)) { + if (reboot_modem_i9100(client, &io_data, true)) { _e("failed to hard reset modem"); goto fail; } @@ -654,7 +661,7 @@ int boot_modem_i9100(struct ipc_client *client) { /* * Now, actually load the firmware */ - if (write(ctx.boot_fd, "ATAT", 4) != 4) { + if (write(io_data.boot_fd, "ATAT", 4) != 4) { _e("failed to write ATAT to boot socket"); goto fail; } @@ -663,17 +670,17 @@ int boot_modem_i9100(struct ipc_client *client) { } char buf[2]; - if (receive(ctx.boot_fd, buf, 1) < 0) { + if (receive(io_data.boot_fd, buf, 1) < 0) { _e("failed to receive bootloader ACK"); goto fail; } - if (receive(ctx.boot_fd, buf + 1, 1) < 0) { + if (receive(io_data.boot_fd, buf + 1, 1) < 0) { _e("failed to receive chip IP ACK"); goto fail; } _i("receive ID: [%02x %02x]", buf[0], buf[1]); - if ((ret = send_PSI(&ctx)) < 0) { + if ((ret = send_PSI(client, &io_data)) < 0) { _e("failed to upload PSI"); goto fail; } @@ -681,7 +688,7 @@ int boot_modem_i9100(struct ipc_client *client) { _d("PSI download complete"); } - if ((ret = send_EBL(&ctx)) < 0) { + if ((ret = send_EBL(client, &io_data)) < 0) { _e("failed to upload EBL"); goto fail; } @@ -689,7 +696,7 @@ int boot_modem_i9100(struct ipc_client *client) { _d("EBL download complete"); } - if ((ret = ack_BootInfo(&ctx)) < 0) { + if ((ret = ack_BootInfo(client, &io_data)) < 0) { _e("failed to receive Boot Info"); goto fail; } @@ -697,7 +704,7 @@ int boot_modem_i9100(struct ipc_client *client) { _d("Boot Info ACK done"); } - if ((ret = send_SecureImage(&ctx)) < 0) { + if ((ret = send_SecureImage(client, &io_data)) < 0) { _e("failed to upload Secure Image"); goto fail; } @@ -707,7 +714,7 @@ int boot_modem_i9100(struct ipc_client *client) { usleep(POST_BOOT_TIMEOUT_US); - if ((ret = reboot_modem_i9100(&ctx, false))) { + if ((ret = reboot_modem_i9100(client, &io_data, false))) { _e("failed to soft reset modem"); goto fail; } @@ -719,20 +726,20 @@ int boot_modem_i9100(struct ipc_client *client) { ret = 0; fail: - if (ctx.radio_data != MAP_FAILED) { - munmap(ctx.radio_data, RADIO_MAP_SIZE); + if (io_data.radio_data != MAP_FAILED) { + munmap(io_data.radio_data, RADIO_MAP_SIZE); } - if (ctx.link_fd >= 0) { - close(ctx.link_fd); + if (io_data.link_fd >= 0) { + close(io_data.link_fd); } - if (ctx.radio_fd >= 0) { - close(ctx.radio_fd); + if (io_data.radio_fd >= 0) { + close(io_data.radio_fd); } - if (ctx.boot_fd >= 0) { - close(ctx.boot_fd); + if (io_data.boot_fd >= 0) { + close(io_data.boot_fd); } return ret; diff --git a/samsung-ipc/device/xmm6260/fwloader_i9100.h b/samsung-ipc/device/xmm6260/fwloader_i9100.h index d027416..06dadd7 100644 --- a/samsung-ipc/device/xmm6260/fwloader_i9100.h +++ b/samsung-ipc/device/xmm6260/fwloader_i9100.h @@ -37,7 +37,7 @@ #define BL_END_MAGIC "\x00\x00" #define BL_END_MAGIC_LEN 2 -#define BL_RESET_MAGIC "\x01\x10\x11\x00" +#define BL_RESET_MAGIC "\x01\x10\x11\x00" #define BL_RESET_MAGIC_LEN 4 #define SEC_DOWNLOAD_CHUNK 16384 @@ -48,11 +48,6 @@ #define FW_LOAD_ADDR 0x60300000 #define NVDATA_LOAD_ADDR 0x60e80000 -struct i9100_radio_part { - size_t offset; - size_t length; -}; - struct i9100_boot_cmd_desc { unsigned code; size_t data_size; diff --git a/samsung-ipc/device/xmm6260/fwloader_i9250.c b/samsung-ipc/device/xmm6260/fwloader_i9250.c index f0e6222..7bec1ed 100644 --- a/samsung-ipc/device/xmm6260/fwloader_i9250.c +++ b/samsung-ipc/device/xmm6260/fwloader_i9250.c @@ -27,7 +27,7 @@ * Locations of the firmware components in the Samsung firmware */ -struct i9250_radio_part i9250_radio_parts[] = { +struct xmm6260_radio_part i9250_radio_parts[] = { [PSI] = { .offset = 0, .length = 0xf000, @@ -76,7 +76,8 @@ struct i9250_boot_cmd_desc i9250_boot_cmd_desc[] = { }, }; -static int reboot_modem_i9250(fwloader_context *ctx, bool hard) { +static int reboot_modem_i9250(struct ipc_client *client, + struct modemctl_io_data *io_data, bool hard) { int ret; if (!hard) { @@ -86,34 +87,34 @@ static int reboot_modem_i9250(fwloader_context *ctx, bool hard) { /* * Disable the hardware to ensure consistent state */ - if ((ret = modemctl_modem_power(ctx, false)) < 0) { + if ((ret = modemctl_modem_power(client, io_data, false)) < 0) { _e("failed to disable modem power"); goto fail; } else { _d("disabled modem power"); } - - if ((ret = modemctl_modem_boot_power(ctx, false)) < 0) { + + if ((ret = modemctl_modem_boot_power(client, io_data, false)) < 0) { _e("failed to disable modem boot power"); goto fail; } else { _d("disabled modem boot power"); } - + /* * Now, initialize the hardware */ - if ((ret = modemctl_modem_boot_power(ctx, true)) < 0) { + if ((ret = modemctl_modem_boot_power(client, io_data, true)) < 0) { _e("failed to enable modem boot power"); goto fail; } else { _d("enabled modem boot power"); } - - if ((ret = modemctl_modem_power(ctx, true)) < 0) { + + if ((ret = modemctl_modem_power(client, io_data, true)) < 0) { _e("failed to enable modem power"); goto fail; } @@ -125,9 +126,10 @@ fail: return ret; } -static int send_image_i9250(fwloader_context *ctx, enum xmm6260_image type) { +static int send_image_i9250(struct ipc_client *client, + struct modemctl_io_data *io_data, enum xmm6260_image type) { int ret = -1; - + if (type >= ARRAY_SIZE(i9250_radio_parts)) { _e("bad image type %x", type); goto fail; @@ -138,19 +140,19 @@ static int send_image_i9250(fwloader_context *ctx, enum xmm6260_image type) { size_t start = offset; size_t end = length + start; - - unsigned char crc = calculateCRC(ctx->radio_data, offset, length); + + unsigned char crc = calculateCRC(io_data->radio_data, offset, length); //dump some image bytes _d("image start"); - hexdump(ctx->radio_data + start, length); + hexdump(io_data->radio_data + start, length); size_t chunk_size = 0xdfc; while (start < end) { size_t remaining = end - start; size_t curr_chunk = chunk_size < remaining ? chunk_size : remaining; - ret = write(ctx->boot_fd, ctx->radio_data + start, curr_chunk); + ret = write(io_data->boot_fd, io_data->radio_data + start, curr_chunk); if (ret < 0) { _e("failed to write image chunk"); goto fail; @@ -160,7 +162,7 @@ static int send_image_i9250(fwloader_context *ctx, enum xmm6260_image type) { _d("sent image type=%d", type); if (type == EBL) { - if ((ret = write(ctx->boot_fd, &crc, 1)) < 1) { + if ((ret = write(io_data->boot_fd, &crc, 1)) < 1) { _e("failed to write EBL CRC"); goto fail; } @@ -171,7 +173,7 @@ static int send_image_i9250(fwloader_context *ctx, enum xmm6260_image type) { } uint32_t crc32 = (crc << 24) | 0xffffff; - if ((ret = write(ctx->boot_fd, &crc32, 4)) != 4) { + if ((ret = write(io_data->boot_fd, &crc32, 4)) != 4) { _e("failed to write CRC"); goto fail; } @@ -186,15 +188,16 @@ fail: return ret; } -static int send_PSI_i9250(fwloader_context *ctx) { +static int send_PSI_i9250(struct ipc_client *client, + struct modemctl_io_data *io_data) { int ret = -1; - if ((ret = write(ctx->boot_fd, I9250_PSI_START_MAGIC, 4)) < 0) { + if ((ret = write(io_data->boot_fd, I9250_PSI_START_MAGIC, 4)) < 0) { _d("%s: failed to write header, ret %d", __func__, ret); goto fail; } - if ((ret = send_image_i9250(ctx, PSI)) < 0) { + if ((ret = send_image_i9250(client, io_data, PSI)) < 0) { _e("failed to send PSI image"); goto fail; } @@ -205,10 +208,10 @@ static int send_PSI_i9250(fwloader_context *ctx) { "\x02\x00\x00\x00", "\x01\xdd\x00\x00", }; - + unsigned i; for (i = 0; i < ARRAY_SIZE(expected_acks); i++) { - ret = expect_data(ctx->boot_fd, expected_acks[i], 4); + ret = expect_data(io_data->boot_fd, expected_acks[i], 4); if (ret < 0) { _d("failed to wait for ack %d", i); goto fail; @@ -222,11 +225,12 @@ fail: return ret; } -static int send_EBL_i9250(fwloader_context *ctx) { +static int send_EBL_i9250(struct ipc_client *client, + struct modemctl_io_data *io_data) { int ret; - int fd = ctx->boot_fd; + int fd = io_data->boot_fd; unsigned length = i9250_radio_parts[EBL].length; - + if ((ret = write(fd, "\x04\x00\x00\x00", 4)) != 4) { _e("failed to write length of EBL length ('4') "); goto fail; @@ -246,14 +250,14 @@ static int send_EBL_i9250(fwloader_context *ctx) { _e("failed to wait for EBL header ACK"); goto fail; } - + length++; if ((ret = write(fd, &length, sizeof(length))) != sizeof(length)) { _e("failed to write EBL length + 1"); goto fail; } - - if ((ret = send_image_i9250(ctx, EBL)) < 0) { + + if ((ret = send_image_i9250(client, io_data, EBL)) < 0) { _e("failed to send EBL image"); goto fail; } @@ -280,8 +284,9 @@ fail: return ret; } -static int bootloader_cmd(fwloader_context *ctx, - enum xmm6260_boot_cmd cmd, void *data, size_t data_size) +static int bootloader_cmd(struct ipc_client *client, + struct modemctl_io_data *io_data, enum xmm6260_boot_cmd cmd, + void *data, size_t data_size) { int ret = 0; char *cmd_data = 0; @@ -325,7 +330,7 @@ static int bootloader_cmd(fwloader_context *ctx, hexdump(cmd_data, cmd_buffer_size); hexdump(cmd_data + cmd_buffer_size - 16, 16); - if ((ret = write(ctx->boot_fd, cmd_data, cmd_buffer_size)) < 0) { + if ((ret = write(io_data->boot_fd, cmd_data, cmd_buffer_size)) < 0) { _e("failed to write command to socket"); goto done_or_fail; } @@ -343,7 +348,7 @@ static int bootloader_cmd(fwloader_context *ctx, } uint32_t ack_length; - if ((ret = receive(ctx->boot_fd, &ack_length, 4)) < 0) { + if ((ret = receive(io_data->boot_fd, &ack_length, 4)) < 0) { _e("failed to receive ack header length"); goto done_or_fail; } @@ -360,7 +365,7 @@ static int bootloader_cmd(fwloader_context *ctx, memset(cmd_data, 0, ack_length); memcpy(cmd_data, &ack_length, 4); for (i = 0; i < (ack_length + 3) / 4; i++) { - if ((ret = receive(ctx->boot_fd, cmd_data + ((i + 1) << 2), 4)) < 0) { + if ((ret = receive(io_data->boot_fd, cmd_data + ((i + 1) << 2), 4)) < 0) { _e("failed to receive ack chunk"); goto done_or_fail; } @@ -372,7 +377,7 @@ static int bootloader_cmd(fwloader_context *ctx, struct i9250_boot_cmd_header *ack_hdr = (struct i9250_boot_cmd_header*)cmd_data; struct i9250_boot_tail_header *ack_tail = (struct i9250_boot_tail_header*) (cmd_data + ack_length + 4 - sizeof(struct i9250_boot_tail_header)); - + _d("ack code 0x%x checksum 0x%x", ack_hdr->cmd, ack_tail->checksum); if (ack_hdr->cmd != header.cmd) { _e("request and ack command codes do not match"); @@ -391,13 +396,14 @@ done_or_fail: return ret; } -static int ack_BootInfo_i9250(fwloader_context *ctx) { +static int ack_BootInfo_i9250(struct ipc_client *client, + struct modemctl_io_data *io_data) { int ret = -1; uint32_t boot_info_length; char *boot_info = 0; - if ((ret = receive(ctx->boot_fd, &boot_info_length, 4)) < 0) { + if ((ret = receive(io_data->boot_fd, &boot_info_length, 4)) < 0) { _e("failed to receive boot info length"); goto fail; } @@ -409,24 +415,24 @@ static int ack_BootInfo_i9250(fwloader_context *ctx) { _e("failed to allocate memory for boot info"); goto fail; } - + memset(boot_info, 0, boot_info_length); size_t boot_chunk = 4; size_t boot_chunk_count = (boot_info_length + boot_chunk - 1) / boot_chunk; unsigned i; for (i = 0; i < boot_chunk_count; i++) { - ret = receive(ctx->boot_fd, boot_info + (i * boot_chunk), boot_chunk); + ret = receive(io_data->boot_fd, boot_info + (i * boot_chunk), boot_chunk); if (ret < 0) { _e("failed to receive Boot Info chunk %i ret=%d", i, ret); goto fail; } } - + _d("received Boot Info"); hexdump(boot_info, boot_info_length); - ret = bootloader_cmd(ctx, SetPortConf, boot_info, boot_info_length); + ret = bootloader_cmd(client, io_data, SetPortConf, boot_info, boot_info_length); if (ret < 0) { _e("failed to send SetPortConf command"); goto fail; @@ -445,14 +451,15 @@ fail: return ret; } -static int send_secure_data(fwloader_context *ctx, uint32_t addr, +static int send_secure_data(struct ipc_client *client, + struct modemctl_io_data *io_data, uint32_t addr, void *data, int data_len) { int ret = 0; int count = 0; char *data_p = (char *) data; - if ((ret = bootloader_cmd(ctx, ReqFlashSetAddress, &addr, 4)) < 0) { + if ((ret = bootloader_cmd(client, io_data, ReqFlashSetAddress, &addr, 4)) < 0) { _e("failed to send ReqFlashSetAddress"); goto fail; } @@ -464,7 +471,7 @@ static int send_secure_data(fwloader_context *ctx, uint32_t addr, int rest = data_len - count; int chunk = rest < SEC_DOWNLOAD_CHUNK ? rest : SEC_DOWNLOAD_CHUNK; - ret = bootloader_cmd(ctx, ReqFlashWriteBlock, data_p, chunk); + ret = bootloader_cmd(client, io_data, ReqFlashWriteBlock, data_p, chunk); if (ret < 0) { _e("failed to send data chunk"); goto fail; @@ -480,20 +487,21 @@ fail: return ret; } -static int send_secure_image(fwloader_context *ctx, uint32_t addr, - enum xmm6260_image type) +static int send_secure_image(struct ipc_client *client, + struct modemctl_io_data *io_data, uint32_t addr, enum xmm6260_image type) { uint32_t offset = i9250_radio_parts[type].offset; uint32_t length = i9250_radio_parts[type].length; - char *start = ctx->radio_data + offset; + char *start = io_data->radio_data + offset; int ret = 0; - ret = send_secure_data(ctx, addr, start, length); + ret = send_secure_data(client, io_data, addr, start, length); return ret; } -static int send_mps_data(fwloader_context *ctx) { +static int send_mps_data(struct ipc_client *client, + struct modemctl_io_data *io_data) { int ret = 0; int mps_fd = -1; char mps_data[I9250_MPS_LENGTH] = {}; @@ -506,8 +514,8 @@ static int send_mps_data(fwloader_context *ctx) { else { read(mps_fd, mps_data, I9250_MPS_LENGTH); } - - if ((ret = bootloader_cmd(ctx, ReqFlashSetAddress, &addr, 4)) < 0) { + + if ((ret = bootloader_cmd(client, io_data, ReqFlashSetAddress, &addr, 4)) < 0) { _e("failed to send ReqFlashSetAddress"); goto fail; } @@ -515,7 +523,7 @@ static int send_mps_data(fwloader_context *ctx) { _d("sent ReqFlashSetAddress"); } - if ((ret = bootloader_cmd(ctx, ReqFlashWriteBlock, + if ((ret = bootloader_cmd(client, io_data, ReqFlashWriteBlock, mps_data, I9250_MPS_LENGTH)) < 0) { _e("failed to write MPS data to modem"); goto fail; @@ -530,15 +538,16 @@ fail: return ret; } -static int send_SecureImage_i9250(fwloader_context *ctx) { +static int send_SecureImage_i9250(struct ipc_client *client, + struct modemctl_io_data *io_data) { int ret = 0; uint32_t sec_off = i9250_radio_parts[SECURE_IMAGE].offset; uint32_t sec_len = i9250_radio_parts[SECURE_IMAGE].length; - void *sec_img = ctx->radio_data + sec_off; + void *sec_img = io_data->radio_data + sec_off; void *nv_data = NULL; - if ((ret = bootloader_cmd(ctx, ReqSecStart, sec_img, sec_len)) < 0) { + if ((ret = bootloader_cmd(client, io_data, ReqSecStart, sec_img, sec_len)) < 0) { _e("failed to write ReqSecStart"); goto fail; } @@ -546,24 +555,24 @@ static int send_SecureImage_i9250(fwloader_context *ctx) { _d("sent ReqSecStart"); } - if ((ret = send_secure_image(ctx, FW_LOAD_ADDR, FIRMWARE)) < 0) { + if ((ret = send_secure_image(client, io_data, FW_LOAD_ADDR, FIRMWARE)) < 0) { _e("failed to send FIRMWARE image"); goto fail; } else { _d("sent FIRMWARE image"); } - - nv_data_check(ctx->client); - nv_data_md5_check(ctx->client); - nv_data = ipc_file_read(ctx->client, nv_data_path(ctx->client), 2 << 20, 1024); + nv_data_check(client); + nv_data_md5_check(client); + + nv_data = ipc_file_read(client, nv_data_path(client), 2 << 20, 1024); if (nv_data == NULL) { _e("failed to read NVDATA image"); goto fail; } - if ((ret = send_secure_data(ctx, NVDATA_LOAD_ADDR, nv_data, 2 << 20)) < 0) { + if ((ret = send_secure_data(client, io_data, NVDATA_LOAD_ADDR, nv_data, 2 << 20)) < 0) { _e("failed to send NVDATA image"); goto fail; } @@ -573,7 +582,7 @@ static int send_SecureImage_i9250(fwloader_context *ctx) { free(nv_data); - if ((ret = send_mps_data(ctx)) < 0) { + if ((ret = send_mps_data(client, io_data)) < 0) { _e("failed to send MPS data"); goto fail; } @@ -581,7 +590,7 @@ static int send_SecureImage_i9250(fwloader_context *ctx) { _d("sent MPS data"); } - if ((ret = bootloader_cmd(ctx, ReqSecEnd, + if ((ret = bootloader_cmd(client, io_data, ReqSecEnd, BL_END_MAGIC, BL_END_MAGIC_LEN)) < 0) { _e("failed to write ReqSecEnd"); @@ -591,7 +600,7 @@ static int send_SecureImage_i9250(fwloader_context *ctx) { _d("sent ReqSecEnd"); } - ret = bootloader_cmd(ctx, ReqForceHwReset, + ret = bootloader_cmd(client, io_data, ReqForceHwReset, BL_RESET_MAGIC, BL_RESET_MAGIC_LEN); if (ret < 0) { _e("failed to write ReqForceHwReset"); @@ -607,42 +616,40 @@ fail: int boot_modem_i9250(struct ipc_client *client) { int ret = -1; - fwloader_context ctx; - memset(&ctx, 0, sizeof(ctx)); + struct modemctl_io_data io_data; + memset(&io_data, 0, sizeof(client, io_data)); - ctx.client = client; - - ctx.radio_fd = open(I9250_RADIO_IMAGE, O_RDONLY); - if (ctx.radio_fd < 0) { + io_data.radio_fd = open(I9250_RADIO_IMAGE, O_RDONLY); + if (io_data.radio_fd < 0) { _e("failed to open radio firmware"); goto fail; } else { - _d("opened radio image %s, fd=%d", I9250_RADIO_IMAGE, ctx.radio_fd); + _d("opened radio image %s, fd=%d", I9250_RADIO_IMAGE, io_data.radio_fd); } - if (fstat(ctx.radio_fd, &ctx.radio_stat) < 0) { + if (fstat(io_data.radio_fd, &io_data.radio_stat) < 0) { _e("failed to stat radio image, error %s", strerror(errno)); goto fail; } - ctx.radio_data = mmap(0, RADIO_MAP_SIZE, PROT_READ, MAP_SHARED, - ctx.radio_fd, 0); - if (ctx.radio_data == MAP_FAILED) { + io_data.radio_data = mmap(0, RADIO_MAP_SIZE, PROT_READ, MAP_SHARED, + io_data.radio_fd, 0); + if (io_data.radio_data == MAP_FAILED) { _e("failed to mmap radio image, error %s", strerror(errno)); goto fail; } - ctx.boot_fd = open(BOOT_DEV, O_RDWR | O_NOCTTY | O_NONBLOCK); - if (ctx.boot_fd < 0) { + io_data.boot_fd = open(BOOT_DEV, O_RDWR | O_NOCTTY | O_NONBLOCK); + if (io_data.boot_fd < 0) { _e("failed to open boot device"); goto fail; } else { - _d("opened boot device %s, fd=%d", BOOT_DEV, ctx.boot_fd); + _d("opened boot device %s, fd=%d", BOOT_DEV, io_data.boot_fd); } - if (reboot_modem_i9250(&ctx, true) < 0) { + if (reboot_modem_i9250(client, &io_data, true) < 0) { _e("failed to hard reset modem"); goto fail; } @@ -655,22 +662,22 @@ int boot_modem_i9250(struct ipc_client *client) { */ int i; for (i = 0; i < 2; i++) { - if (write(ctx.boot_fd, "ATAT", 4) != 4) { + if (write(io_data.boot_fd, "ATAT", 4) != 4) { _e("failed to write ATAT to boot socket"); goto fail; } else { _d("written ATAT to boot socket, waiting for ACK"); } - - if (read_select(ctx.boot_fd, 100) < 0) { + + if (read_select(io_data.boot_fd, 100) < 0) { _d("failed to select before next ACK, ignoring"); } } //FIXME: make sure it does not timeout or add the retry in the ril library - - if ((ret = read_select(ctx.boot_fd, 100)) < 0) { + + if ((ret = read_select(io_data.boot_fd, 100)) < 0) { _e("failed to wait for bootloader ready state"); goto fail; } @@ -681,7 +688,7 @@ int boot_modem_i9250(struct ipc_client *client) { ret = -ETIMEDOUT; for (i = 0; i < I9250_BOOT_REPLY_MAX; i++) { uint32_t id_buf; - if ((ret = receive(ctx.boot_fd, (void*)&id_buf, 4)) != 4) { + if ((ret = receive(io_data.boot_fd, (void*)&id_buf, 4)) != 4) { _e("failed receiving bootloader reply"); goto fail; } @@ -700,45 +707,45 @@ int boot_modem_i9250(struct ipc_client *client) { _d("got bootloader id marker"); } - if ((ret = send_PSI_i9250(&ctx)) < 0) { + if ((ret = send_PSI_i9250(client, &io_data)) < 0) { _e("failed to upload PSI"); goto fail; } else { _d("PSI download complete"); } - - close(ctx.boot_fd); - ctx.boot_fd = open(I9250_SECOND_BOOT_DEV, O_RDWR | O_NOCTTY | O_NONBLOCK); - if (ctx.boot_fd < 0) { + + close(io_data.boot_fd); + io_data.boot_fd = open(I9250_SECOND_BOOT_DEV, O_RDWR | O_NOCTTY | O_NONBLOCK); + if (io_data.boot_fd < 0) { _e("failed to open " I9250_SECOND_BOOT_DEV " control device"); goto fail; } else { - _d("opened second boot device %s, fd=%d", I9250_SECOND_BOOT_DEV, ctx.boot_fd); + _d("opened second boot device %s, fd=%d", I9250_SECOND_BOOT_DEV, io_data.boot_fd); } //RpsiCmdLoadAndExecute - if ((ret = write(ctx.boot_fd, I9250_PSI_CMD_EXEC, 4)) < 0) { + if ((ret = write(io_data.boot_fd, I9250_PSI_CMD_EXEC, 4)) < 0) { _e("failed writing cmd_load_exe_EBL"); goto fail; } - if ((ret = write(ctx.boot_fd, I9250_PSI_EXEC_DATA, 8)) < 0) { + if ((ret = write(io_data.boot_fd, I9250_PSI_EXEC_DATA, 8)) < 0) { _e("failed writing 8 bytes to boot1"); goto fail; } - if ((ret = expect_data(ctx.boot_fd, I9250_GENERAL_ACK, 4)) < 0) { + if ((ret = expect_data(io_data.boot_fd, I9250_GENERAL_ACK, 4)) < 0) { _e("failed to receive cmd_load_exe_EBL ack"); goto fail; } - if ((ret = expect_data(ctx.boot_fd, I9250_PSI_READY_ACK, 4)) < 0) { + if ((ret = expect_data(io_data.boot_fd, I9250_PSI_READY_ACK, 4)) < 0) { _e("failed to receive PSI ready ack"); goto fail; } - if ((ret = send_EBL_i9250(&ctx)) < 0) { + if ((ret = send_EBL_i9250(client, &io_data)) < 0) { _e("failed to upload EBL"); goto fail; } @@ -746,7 +753,7 @@ int boot_modem_i9250(struct ipc_client *client) { _d("EBL download complete"); } - if ((ret = ack_BootInfo_i9250(&ctx)) < 0) { + if ((ret = ack_BootInfo_i9250(client, &io_data)) < 0) { _e("failed to receive Boot Info"); goto fail; } @@ -754,7 +761,7 @@ int boot_modem_i9250(struct ipc_client *client) { _d("Boot Info ACK done"); } - if ((ret = send_SecureImage_i9250(&ctx)) < 0) { + if ((ret = send_SecureImage_i9250(client, &io_data)) < 0) { _e("failed to upload Secure Image"); goto fail; } @@ -762,7 +769,7 @@ int boot_modem_i9250(struct ipc_client *client) { _d("Secure Image download complete"); } - if ((ret = modemctl_wait_modem_online(&ctx))) { + if ((ret = modemctl_wait_modem_online(client, &io_data))) { _e("failed to wait for modem to become online"); goto fail; } @@ -771,16 +778,16 @@ int boot_modem_i9250(struct ipc_client *client) { ret = 0; fail: - if (ctx.radio_data != MAP_FAILED) { - munmap(ctx.radio_data, RADIO_MAP_SIZE); + if (io_data.radio_data != MAP_FAILED) { + munmap(io_data.radio_data, RADIO_MAP_SIZE); } - if (ctx.radio_fd >= 0) { - close(ctx.radio_fd); + if (io_data.radio_fd >= 0) { + close(io_data.radio_fd); } - if (ctx.boot_fd >= 0) { - close(ctx.boot_fd); + if (io_data.boot_fd >= 0) { + close(io_data.boot_fd); } return ret; diff --git a/samsung-ipc/device/xmm6260/fwloader_i9250.h b/samsung-ipc/device/xmm6260/fwloader_i9250.h index 41deb28..7fa1782 100644 --- a/samsung-ipc/device/xmm6260/fwloader_i9250.h +++ b/samsung-ipc/device/xmm6260/fwloader_i9250.h @@ -33,10 +33,10 @@ #define I9250_PSI_START_MAGIC "\xff\xf0\x00\x30" #define I9250_PSI_CMD_EXEC "\x08\x00\x00\x00" #define I9250_PSI_EXEC_DATA "\x00\x00\x00\x00\x02\x00\x02\x00" -#define I9250_PSI_READY_ACK "\x00\xaa\x00\x00" +#define I9250_PSI_READY_ACK "\x00\xaa\x00\x00" #define I9250_EBL_IMG_ACK_MAGIC "\x51\xa5\x00\x00" -#define I9250_EBL_HDR_ACK_MAGIC "\xcc\xcc\x00\x00" +#define I9250_EBL_HDR_ACK_MAGIC "\xcc\xcc\x00\x00" #define I9250_MPS_IMAGE_PATH "/factory/imei/mps_code.dat" #define I9250_MPS_LOAD_ADDR 0x61080000 @@ -51,14 +51,9 @@ #define BL_END_MAGIC "\x00\x00" #define BL_END_MAGIC_LEN 2 -#define BL_RESET_MAGIC "\x01\x10\x11\x00" +#define BL_RESET_MAGIC "\x01\x10\x11\x00" #define BL_RESET_MAGIC_LEN 4 -struct i9250_radio_part { - size_t offset; - size_t length; -}; - /* * on I9250, all commands need ACK and we do not need to * allocate a fixed size buffer diff --git a/samsung-ipc/device/xmm6260/modemctl_common.c b/samsung-ipc/device/xmm6260/modemctl_common.c index 253030a..8c37bce 100644 --- a/samsung-ipc/device/xmm6260/modemctl_common.c +++ b/samsung-ipc/device/xmm6260/modemctl_common.c @@ -25,13 +25,14 @@ /* * modemctl generic functions */ -int modemctl_link_set_active(fwloader_context *ctx, bool enabled) { +int modemctl_link_set_active(struct ipc_client *client, + struct modemctl_io_data *io_data, bool enabled) { unsigned status = enabled; int ret; unsigned long ioctl_code; ioctl_code = IOCTL_LINK_CONTROL_ACTIVE; - ret = c_ioctl(ctx->link_fd, ioctl_code, &status); + ret = ioctl(io_data->link_fd, ioctl_code, &status); if (ret < 0) { _d("failed to set link active to %d", enabled); @@ -43,13 +44,14 @@ fail: return ret; } -int modemctl_link_set_enabled(fwloader_context *ctx, bool enabled) { +int modemctl_link_set_enabled(struct ipc_client *client, + struct modemctl_io_data *io_data, bool enabled) { unsigned status = enabled; int ret; unsigned long ioctl_code; ioctl_code = IOCTL_LINK_CONTROL_ENABLE; - ret = c_ioctl(ctx->link_fd, ioctl_code, &status); + ret = ioctl(io_data->link_fd, ioctl_code, &status); if (ret < 0) { _d("failed to set link state to %d", enabled); @@ -61,7 +63,8 @@ fail: return ret; } -int modemctl_wait_link_ready(fwloader_context *ctx) { +int modemctl_wait_link_ready(struct ipc_client *client, + struct modemctl_io_data *io_data) { int ret; struct timeval tv_start = {}; @@ -73,7 +76,7 @@ int modemctl_wait_link_ready(fwloader_context *ctx) { long diff = 0; do { - ret = c_ioctl(ctx->link_fd, IOCTL_LINK_CONNECTED, 0); + ret = ioctl(io_data->link_fd, IOCTL_LINK_CONNECTED, 0); if (ret < 0) { goto fail; } @@ -90,12 +93,13 @@ int modemctl_wait_link_ready(fwloader_context *ctx) { } while (diff < LINK_TIMEOUT_MS); ret = -ETIMEDOUT; - + fail: return ret; } -int modemctl_wait_modem_online(fwloader_context *ctx) { +int modemctl_wait_modem_online(struct ipc_client *client, + struct modemctl_io_data *io_data) { int ret; struct timeval tv_start = {}; @@ -107,7 +111,7 @@ int modemctl_wait_modem_online(fwloader_context *ctx) { long diff = 0; do { - ret = c_ioctl(ctx->boot_fd, IOCTL_MODEM_STATUS, 0); + ret = ioctl(io_data->boot_fd, IOCTL_MODEM_STATUS, 0); if (ret < 0) { goto fail; } @@ -124,27 +128,29 @@ int modemctl_wait_modem_online(fwloader_context *ctx) { } while (diff < LINK_TIMEOUT_MS); ret = -ETIMEDOUT; - + fail: return ret; } -int modemctl_modem_power(fwloader_context *ctx, bool enabled) { +int modemctl_modem_power(struct ipc_client *client, + struct modemctl_io_data *io_data, bool enabled) { if (enabled) { - return c_ioctl(ctx->boot_fd, IOCTL_MODEM_ON, 0); + return ioctl(io_data->boot_fd, IOCTL_MODEM_ON, 0); } else { - return c_ioctl(ctx->boot_fd, IOCTL_MODEM_OFF, 0); + return ioctl(io_data->boot_fd, IOCTL_MODEM_OFF, 0); } return -1; } -int modemctl_modem_boot_power(fwloader_context *ctx, bool enabled) { +int modemctl_modem_boot_power(struct ipc_client *client, + struct modemctl_io_data *io_data, bool enabled) { if (enabled) { - return c_ioctl(ctx->boot_fd, IOCTL_MODEM_BOOT_ON, 0); + return ioctl(io_data->boot_fd, IOCTL_MODEM_BOOT_ON, 0); } else { - return c_ioctl(ctx->boot_fd, IOCTL_MODEM_BOOT_OFF, 0); + return ioctl(io_data->boot_fd, IOCTL_MODEM_BOOT_OFF, 0); } return -1; } @@ -153,7 +159,7 @@ unsigned char calculateCRC(void* data, size_t offset, size_t length) { unsigned char crc = 0; unsigned char *ptr = (unsigned char*)(data + offset); - + while (length--) { crc ^= *ptr++; } diff --git a/samsung-ipc/device/xmm6260/modemctl_common.h b/samsung-ipc/device/xmm6260/modemctl_common.h index 466c728..f0646df 100644 --- a/samsung-ipc/device/xmm6260/modemctl_common.h +++ b/samsung-ipc/device/xmm6260/modemctl_common.h @@ -26,7 +26,7 @@ #include "common.h" #include "log.h" -#include "io_helpers.h" +#include "io_helpers.h" //Samsung IOCTLs #include "modem_prj.h" @@ -43,16 +43,10 @@ #define RADIO_MAP_SIZE (16 << 20) -typedef struct { - int link_fd; - int boot_fd; - - int radio_fd; - char *radio_data; - struct stat radio_stat; - - struct ipc_client *client; -} fwloader_context; +struct xmm6260_radio_part { + size_t offset; + size_t length; +}; /* * Components of the Samsung XMM6260 firmware @@ -80,85 +74,93 @@ enum xmm6260_boot_cmd { ReqFlashWriteBlock, }; +struct modemctl_io_data { + int link_fd; + int boot_fd; + + int radio_fd; + char *radio_data; + struct stat radio_stat; + + struct xmm6260_radio_part *radio_parts; + int radio_parts_count; +}; + /* * Function prototypes */ -/* +/* * @brief Activates the modem <-> cpu link data transfer * - * @param ctx [in] firmware loader context + * @param client [in] ipc client + * @param io_data [in] modemctl-specific data * @param enabled [in] whether to enable or disable link data transport * @return Negative value indicating error code * @return ioctl call result */ -int modemctl_link_set_active(fwloader_context *ctx, bool enabled); +int modemctl_link_set_active(struct ipc_client *client, + struct modemctl_io_data *io_data, bool enabled); -/* +/* * @brief Activates the modem <-> cpu link connection * - * @param ctx [in] firmware loader context + * @param client [in] ipc client + * @param io_data [in] modemctl-specific data * @param enabled [in] the state to set link to * @return Negative value indicating error code * @return ioctl call result */ -int modemctl_link_set_enabled(fwloader_context *ctx, bool enabled); +int modemctl_link_set_enabled(struct ipc_client *client, + struct modemctl_io_data *io_data, bool enabled); -/* +/* * @brief Poll the link until it gets ready or times out * - * @param ctx [in] firmware loader context + * @param client [in] ipc client + * @param io_data [in] modemctl-specific data * @return Negative value indicating error code * @return ioctl call result */ -int modemctl_wait_link_ready(fwloader_context *ctx); +int modemctl_wait_link_ready(struct ipc_client *client, + struct modemctl_io_data *io_data); -/* +/* * @brief Poll the modem until it gets online or times out * - * @param ctx [in] firmware loader context + * @param client [in] ipc client + * @param io_data [in] modemctl-specific data * @return Negative value indicating error code * @return ioctl call result */ -int modemctl_wait_modem_online(fwloader_context *ctx); +int modemctl_wait_modem_online(struct ipc_client *client, + struct modemctl_io_data *io_data); -/* +/* * @brief Sets the modem power * - * @param ctx [in] firmware loader context + * @param client [in] ipc client + * @param io_data [in] modemctl-specific data * @param enabled [in] whether to enable or disable modem power * @return Negative value indicating error code * @return ioctl call result */ -int modemctl_modem_power(fwloader_context *ctx, bool enabled); +int modemctl_modem_power(struct ipc_client *client, + struct modemctl_io_data *io_data, bool enabled); -/* +/* * @brief Sets the modem bootloader power/UART configuration * - * @param ctx [in] firmware loader context + * @param client [in] ipc client + * @param io_data [in] modemctl-specific data * @param enabled [in] whether to enable or disable power * @return Negative value indicating error code * @return ioctl call result */ -int modemctl_modem_boot_power(fwloader_context *ctx, bool enabled); - -/* - * @brief Boots the modem on the I9100 (Galaxy S2) board - * - * @return Negative value indicating error code - * @return zero on success - */ -int boot_modem_i9100(struct ipc_client *client); - -/* - * @brief Boots the modem on the I9250 (Galaxy Nexus) board - * - * @return Negative value indicating error code - * @return zero on success - */ -int boot_modem_i9250(struct ipc_client *client); +int modemctl_modem_boot_power(struct ipc_client *client, + struct modemctl_io_data *io_data, bool enabled); -/* +/* * @brief Calculate the checksum for the XMM6260 bootloader protocol * * @param data [in] the data to calculate the checksum for |