mirror of
https://github.com/linux-msm/qdl.git
synced 2026-02-25 13:12:25 -08:00
sahara: Load programmer at parse time
Lugging around the filename of the to-be-loaded Sahara image(s) prevents us from (in a later patch) load the programmer payload from an archive. So move the loading of the specified programmer image(s) to parse time and hold each one in memory instead. While doing this, move the "mappings" array (i.e. the list of Sahara images) to the stack instead, as it was already being passed as a parameter to the relevant function(s). sahara_run() is also extended to provide debug information about which images are being presented to the device. Signed-off-by: Bjorn Andersson <bjorn.andersson@oss.qualcomm.com>
This commit is contained in:
12
ks.c
12
ks.c
@@ -54,6 +54,8 @@ static void print_usage(FILE *out)
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
struct sahara_image mappings[MAPPING_SZ] = {};
|
||||
const char *filename;
|
||||
bool found_mapping = false;
|
||||
char *dev_node = NULL;
|
||||
long file_id;
|
||||
@@ -101,8 +103,12 @@ int main(int argc, char **argv)
|
||||
print_usage(stderr);
|
||||
return 1;
|
||||
}
|
||||
qdl.mappings[file_id] = &optarg[colon - optarg + 1];
|
||||
printf("Created mapping ID:%ld File:%s\n", file_id, qdl.mappings[file_id]);
|
||||
filename = &optarg[colon - optarg + 1];
|
||||
ret = load_sahara_image(filename, &mappings[file_id]);
|
||||
if (ret < 0)
|
||||
exit(1);
|
||||
|
||||
printf("Created mapping ID:%ld File:%s\n", file_id, filename);
|
||||
break;
|
||||
case 'h':
|
||||
print_usage(stdout);
|
||||
@@ -128,7 +134,7 @@ int main(int argc, char **argv)
|
||||
return 1;
|
||||
}
|
||||
|
||||
ret = sahara_run(&qdl, qdl.mappings, false, NULL, NULL);
|
||||
ret = sahara_run(&qdl, mappings, false, NULL, NULL);
|
||||
if (ret < 0)
|
||||
return 1;
|
||||
|
||||
|
||||
12
qdl.c
12
qdl.c
@@ -141,7 +141,8 @@ static void print_usage(FILE *out)
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
enum qdl_storage_type storage_type = QDL_STORAGE_UFS;
|
||||
char *prog_mbn;
|
||||
struct sahara_image sahara_images[MAPPING_SZ] = {};
|
||||
bool single_image = true;
|
||||
char *incdir = NULL;
|
||||
char *serial = NULL;
|
||||
const char *vip_generate_dir = NULL;
|
||||
@@ -256,9 +257,9 @@ int main(int argc, char **argv)
|
||||
if (qdl_debug)
|
||||
print_version();
|
||||
|
||||
prog_mbn = argv[optind++];
|
||||
if (access(prog_mbn, F_OK))
|
||||
errx(1, "unable to load programmer \"%s\"", prog_mbn);
|
||||
ret = load_sahara_image(argv[optind++], &sahara_images[0]);
|
||||
if (ret < 0)
|
||||
exit(1);
|
||||
|
||||
do {
|
||||
type = detect_type(argv[optind]);
|
||||
@@ -321,8 +322,7 @@ int main(int argc, char **argv)
|
||||
|
||||
qdl->storage_type = storage_type;
|
||||
|
||||
qdl->mappings[0] = prog_mbn;
|
||||
ret = sahara_run(qdl, qdl->mappings, true, NULL, NULL);
|
||||
ret = sahara_run(qdl, sahara_images, single_image, NULL, NULL);
|
||||
if (ret < 0)
|
||||
goto out_cleanup;
|
||||
|
||||
|
||||
14
qdl.h
14
qdl.h
@@ -61,11 +61,15 @@ struct qdl_device {
|
||||
void (*set_vip_transfer)(struct qdl_device *qdl, const char *signed_table,
|
||||
const char *chained_table);
|
||||
|
||||
char *mappings[MAPPING_SZ]; // array index is the id from the device
|
||||
|
||||
struct vip_transfer_data vip_data;
|
||||
};
|
||||
|
||||
struct sahara_image {
|
||||
const char *name;
|
||||
void *ptr;
|
||||
size_t len;
|
||||
};
|
||||
|
||||
struct libusb_device_handle;
|
||||
|
||||
struct qdl_device *qdl_init(enum QDL_DEVICE_TYPE type);
|
||||
@@ -83,8 +87,10 @@ struct qdl_device *sim_init(void);
|
||||
int firehose_run(struct qdl_device *qdl);
|
||||
int firehose_provision(struct qdl_device *qdl);
|
||||
int firehose_read_buf(struct qdl_device *qdl, struct read_op *read_op, void *out_buf, size_t out_size);
|
||||
int sahara_run(struct qdl_device *qdl, char *img_arr[], bool single_image,
|
||||
const char *ramdump_path, const char *ramdump_filter);
|
||||
int sahara_run(struct qdl_device *qdl, const struct sahara_image *images,
|
||||
bool single_image, const char *ramdump_path,
|
||||
const char *ramdump_filter);
|
||||
int load_sahara_image(const char *filename, struct sahara_image *image);
|
||||
void print_hex_dump(const char *prefix, const void *buf, size_t len);
|
||||
unsigned int attr_as_unsigned(xmlNode *node, const char *attr, int *errors);
|
||||
const char *attr_as_string(xmlNode *node, const char *attr, int *errors);
|
||||
|
||||
131
sahara.c
131
sahara.c
@@ -144,38 +144,15 @@ static void sahara_hello(struct qdl_device *qdl, struct sahara_pkt *pkt)
|
||||
qdl_write(qdl, &resp, resp.length, SAHARA_CMD_TIMEOUT_MS);
|
||||
}
|
||||
|
||||
static int sahara_read_common(struct qdl_device *qdl, int progfd, off_t offset, size_t len)
|
||||
static void sahara_read(struct qdl_device *qdl, struct sahara_pkt *pkt,
|
||||
const struct sahara_image *images,
|
||||
bool single_image)
|
||||
{
|
||||
ssize_t n;
|
||||
void *buf;
|
||||
int ret = 0;
|
||||
|
||||
buf = malloc(len);
|
||||
if (!buf)
|
||||
return -ENOMEM;
|
||||
|
||||
lseek(progfd, offset, SEEK_SET);
|
||||
n = read(progfd, buf, len);
|
||||
if (n != len) {
|
||||
ret = -errno;
|
||||
goto out;
|
||||
}
|
||||
|
||||
n = qdl_write(qdl, buf, n, SAHARA_CMD_TIMEOUT_MS);
|
||||
if (n != len)
|
||||
err(1, "failed to write %zu bytes to sahara", len);
|
||||
|
||||
free(buf);
|
||||
|
||||
out:
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void sahara_read(struct qdl_device *qdl, struct sahara_pkt *pkt, char *img_arr[], bool single_image)
|
||||
{
|
||||
unsigned int image;
|
||||
const struct sahara_image *image;
|
||||
unsigned int image_idx;
|
||||
size_t offset;
|
||||
size_t len;
|
||||
int ret;
|
||||
int fd;
|
||||
|
||||
assert(pkt->length == SAHARA_READ_DATA_LENGTH);
|
||||
|
||||
@@ -183,37 +160,39 @@ static void sahara_read(struct qdl_device *qdl, struct sahara_pkt *pkt, char *im
|
||||
pkt->read_req.image, pkt->read_req.offset, pkt->read_req.length);
|
||||
|
||||
if (single_image)
|
||||
image = 0;
|
||||
image_idx = 0;
|
||||
else
|
||||
image = pkt->read_req.image;
|
||||
image_idx = pkt->read_req.image;
|
||||
|
||||
if (image >= MAPPING_SZ || !img_arr[image]) {
|
||||
ux_err("device requested invalid image: %u\n", image);
|
||||
if (image_idx >= MAPPING_SZ || !images[image_idx].ptr) {
|
||||
ux_err("device requested invalid image: %u\n", image_idx);
|
||||
sahara_send_reset(qdl);
|
||||
return;
|
||||
}
|
||||
|
||||
fd = open(img_arr[image], O_RDONLY | O_BINARY);
|
||||
if (fd < 0) {
|
||||
ux_err("Can not open \"%s\": %s\n", img_arr[image], strerror(errno));
|
||||
// Maybe this read was optional. Notify device of error and let
|
||||
// it decide how to proceed.
|
||||
sahara_send_reset(qdl);
|
||||
offset = pkt->read_req.offset;
|
||||
len = pkt->read_req.length;
|
||||
|
||||
image = &images[image_idx];
|
||||
if (offset > image->len || offset + len > image->len) {
|
||||
ux_err("device requested invalid range of image %d\n", image_idx);
|
||||
return;
|
||||
}
|
||||
|
||||
ret = sahara_read_common(qdl, fd, pkt->read_req.offset, pkt->read_req.length);
|
||||
if (ret < 0)
|
||||
errx(1, "failed to read image chunk to sahara");
|
||||
|
||||
close(fd);
|
||||
ret = qdl_write(qdl, image->ptr + offset, len, SAHARA_CMD_TIMEOUT_MS);
|
||||
if (ret != len)
|
||||
err(1, "failed to write %zu bytes to sahara", len);
|
||||
}
|
||||
|
||||
static void sahara_read64(struct qdl_device *qdl, struct sahara_pkt *pkt, char *img_arr[], bool single_image)
|
||||
static void sahara_read64(struct qdl_device *qdl, struct sahara_pkt *pkt,
|
||||
const struct sahara_image *images,
|
||||
bool single_image)
|
||||
{
|
||||
unsigned int image;
|
||||
const struct sahara_image *image;
|
||||
unsigned int image_idx;
|
||||
size_t offset;
|
||||
size_t len;
|
||||
int ret;
|
||||
int fd;
|
||||
|
||||
assert(pkt->length == SAHARA_READ_DATA64_LENGTH);
|
||||
|
||||
@@ -221,29 +200,28 @@ static void sahara_read64(struct qdl_device *qdl, struct sahara_pkt *pkt, char *
|
||||
pkt->read64_req.image, pkt->read64_req.offset, pkt->read64_req.length);
|
||||
|
||||
if (single_image)
|
||||
image = 0;
|
||||
image_idx = 0;
|
||||
else
|
||||
image = pkt->read64_req.image;
|
||||
image_idx = pkt->read64_req.image;
|
||||
|
||||
if (image >= MAPPING_SZ || !img_arr[image]) {
|
||||
ux_err("device requested invalid image: %u\n", image);
|
||||
sahara_send_reset(qdl);
|
||||
return;
|
||||
}
|
||||
fd = open(img_arr[image], O_RDONLY | O_BINARY);
|
||||
if (fd < 0) {
|
||||
ux_err("Can not open \"%s\": %s\n", img_arr[image], strerror(errno));
|
||||
// Maybe this read was optional. Notify device of error and let
|
||||
// it decide how to proceed.
|
||||
if (image_idx >= MAPPING_SZ || !images[image_idx].ptr) {
|
||||
ux_err("device requested invalid image: %u\n", image_idx);
|
||||
sahara_send_reset(qdl);
|
||||
return;
|
||||
}
|
||||
|
||||
ret = sahara_read_common(qdl, fd, pkt->read64_req.offset, pkt->read64_req.length);
|
||||
if (ret < 0)
|
||||
errx(1, "failed to read image chunk to sahara");
|
||||
offset = pkt->read64_req.offset;
|
||||
len = pkt->read64_req.length;
|
||||
|
||||
close(fd);
|
||||
image = &images[image_idx];
|
||||
if (offset > image->len || offset + len > image->len) {
|
||||
ux_err("device requested invalid range of image %d\n", image_idx);
|
||||
return;
|
||||
}
|
||||
|
||||
ret = qdl_write(qdl, image->ptr + offset, len, SAHARA_CMD_TIMEOUT_MS);
|
||||
if (ret != len)
|
||||
err(1, "failed to write %zu bytes to sahara", len);
|
||||
}
|
||||
|
||||
static void sahara_eoi(struct qdl_device *qdl, struct sahara_pkt *pkt)
|
||||
@@ -436,8 +414,23 @@ static void sahara_debug64(struct qdl_device *qdl, struct sahara_pkt *pkt,
|
||||
sahara_send_reset(qdl);
|
||||
}
|
||||
|
||||
int sahara_run(struct qdl_device *qdl, char *img_arr[], bool single_image,
|
||||
const char *ramdump_path, const char *ramdump_filter)
|
||||
static void sahara_debug_list_images(const struct sahara_image *images, bool single_image)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (single_image)
|
||||
ux_debug("Sahara image id in read requests will be ignored\n");
|
||||
|
||||
ux_debug("Sahara images:\n");
|
||||
for (i = 0; i < MAPPING_SZ; i++) {
|
||||
if (images[i].ptr)
|
||||
ux_debug(" %2d: %s\n", i, images[i].name ? : "(unknown)");
|
||||
}
|
||||
}
|
||||
|
||||
int sahara_run(struct qdl_device *qdl, const struct sahara_image *images,
|
||||
bool single_image, const char *ramdump_path,
|
||||
const char *ramdump_filter)
|
||||
{
|
||||
struct sahara_pkt *pkt;
|
||||
char buf[4096];
|
||||
@@ -445,6 +438,8 @@ int sahara_run(struct qdl_device *qdl, char *img_arr[], bool single_image,
|
||||
bool done = false;
|
||||
int n;
|
||||
|
||||
sahara_debug_list_images(images, single_image);
|
||||
|
||||
/*
|
||||
* Don't need to do anything in simulation mode with Sahara,
|
||||
* we care only about Firehose protocol
|
||||
@@ -470,7 +465,7 @@ int sahara_run(struct qdl_device *qdl, char *img_arr[], bool single_image,
|
||||
sahara_hello(qdl, pkt);
|
||||
break;
|
||||
case SAHARA_READ_DATA_CMD:
|
||||
sahara_read(qdl, pkt, img_arr, single_image);
|
||||
sahara_read(qdl, pkt, images, single_image);
|
||||
break;
|
||||
case SAHARA_END_OF_IMAGE_CMD:
|
||||
sahara_eoi(qdl, pkt);
|
||||
@@ -486,7 +481,7 @@ int sahara_run(struct qdl_device *qdl, char *img_arr[], bool single_image,
|
||||
sahara_debug64(qdl, pkt, ramdump_path, ramdump_filter);
|
||||
break;
|
||||
case SAHARA_READ_DATA64_CMD:
|
||||
sahara_read64(qdl, pkt, img_arr, single_image);
|
||||
sahara_read64(qdl, pkt, images, single_image);
|
||||
break;
|
||||
case SAHARA_RESET_RESP_CMD:
|
||||
assert(pkt->length == SAHARA_RESET_LENGTH);
|
||||
|
||||
55
util.c
55
util.c
@@ -5,6 +5,7 @@
|
||||
*/
|
||||
#include <ctype.h>
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
@@ -12,7 +13,9 @@
|
||||
#include <stdlib.h>
|
||||
#include <libxml/parser.h>
|
||||
#include <libxml/tree.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "oscompat.h"
|
||||
#include "qdl.h"
|
||||
#include "version.h"
|
||||
|
||||
@@ -207,3 +210,55 @@ done:
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* load_sahara_image() - Load the content of the given file into the image
|
||||
* @filename: file to be loaded
|
||||
* @image: Sahara image object to be populated
|
||||
*
|
||||
* Read the content of the given @filename into the given @image, update the
|
||||
* @image->len, and then populate the @image->name for debugging purposes.
|
||||
*
|
||||
* Returns: 0 on success, -1 on error
|
||||
*/
|
||||
int load_sahara_image(const char *filename, struct sahara_image *image)
|
||||
{
|
||||
ssize_t n;
|
||||
off_t len;
|
||||
void *ptr;
|
||||
int fd;
|
||||
|
||||
fd = open(filename, O_RDONLY | O_BINARY);
|
||||
if (fd < 0) {
|
||||
ux_err("failed to read \"%s\"\n", filename);
|
||||
return -1;
|
||||
}
|
||||
|
||||
len = lseek(fd, 0, SEEK_END);
|
||||
if (len < 0) {
|
||||
ux_err("failed to find end of \"%s\"\n", filename);
|
||||
goto err_close;
|
||||
}
|
||||
lseek(fd, 0, SEEK_SET);
|
||||
|
||||
ptr = malloc(len);
|
||||
|
||||
n = read(fd, ptr, len);
|
||||
if (n != len) {
|
||||
ux_err("failed to read content of \"%s\"\n", filename);
|
||||
free(ptr);
|
||||
goto err_close;
|
||||
}
|
||||
|
||||
close(fd);
|
||||
|
||||
image->name = strdup(filename);
|
||||
image->ptr = ptr;
|
||||
image->len = len;
|
||||
|
||||
return 0;
|
||||
|
||||
err_close:
|
||||
close(fd);
|
||||
return -1;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user