#include <spi_flash.h>
#include <jffs2/load_kernel.h>
#include <linux/mtd/mtd.h>
+#include <linux/ctype.h>
static int dfu_get_medium_size_sf(struct dfu_entity *dfu, u64 *size)
{
static int dfu_read_medium_sf(struct dfu_entity *dfu, u64 offset, void *buf,
long *len)
{
- return spi_flash_read(dfu->data.sf.dev, dfu->data.sf.start + offset,
- *len, buf);
+ long seglen = *len;
+ int ret;
+
+ if (seglen > (16 << 20))
+ seglen = (16 << 20);
+
+ ret = spi_flash_read(dfu->data.sf.dev, dfu->data.sf.start + offset,
+ seglen, buf);
+ if (!ret)
+ *len = seglen;
+
+ return ret;
}
static u64 find_sector(struct dfu_entity *dfu, u64 start, u64 offset)
static void dfu_free_entity_sf(struct dfu_entity *dfu)
{
- spi_flash_free(dfu->data.sf.dev);
+ /*
+ * In the DM case it is not necessary to free the SPI device.
+ * For the non-DM case we must ensure that the the SPI device is only
+ * freed once.
+ */
+ if (!CONFIG_IS_ENABLED(DM_SPI_FLASH)) {
+ struct spi_flash *dev = dfu->data.sf.dev;
+
+ if (!dev)
+ return;
+ dfu->data.sf.dev = NULL;
+ list_for_each_entry(dfu, &dfu_list, list) {
+ if (dfu->data.sf.dev == dev)
+ dfu->data.sf.dev = NULL;
+ }
+ spi_flash_free(dev);
+ }
}
static struct spi_flash *parse_dev(char *devstr)
dev = spi_flash_probe(bus, cs, speed, mode);
if (!dev) {
- printf("Failed to create SPI flash at %d:%d:%d:%d\n",
+ printf("Failed to create SPI flash at %u:%u:%u:%u\n",
bus, cs, speed, mode);
return NULL;
}
return dev;
}
-int dfu_fill_entity_sf(struct dfu_entity *dfu, char *devstr, char *s)
+int dfu_fill_entity_sf(struct dfu_entity *dfu, char *devstr, char **argv, int argc)
{
- char *st;
+ char *s;
char *devstr_bkup = strdup(devstr);
dfu->data.sf.dev = parse_dev(devstr_bkup);
dfu->dev_type = DFU_DEV_SF;
dfu->max_buf_size = dfu->data.sf.dev->sector_size;
- st = strsep(&s, " ");
- if (!strcmp(st, "raw")) {
+ if (argc != 3)
+ return -EINVAL;
+ if (!strcmp(argv[0], "raw")) {
dfu->layout = DFU_RAW_ADDR;
- dfu->data.sf.start = simple_strtoul(s, &s, 16);
- s++;
- dfu->data.sf.size = simple_strtoul(s, &s, 16);
+ dfu->data.sf.start = hextoul(argv[1], &s);
+ if (*s)
+ return -EINVAL;
+ dfu->data.sf.size = hextoul(argv[2], &s);
+ if (*s)
+ return -EINVAL;
} else if (CONFIG_IS_ENABLED(DFU_SF_PART) &&
- (!strcmp(st, "part") || !strcmp(st, "partubi"))) {
+ (!strcmp(argv[0], "part") || !strcmp(argv[0], "partubi"))) {
char mtd_id[32];
struct mtd_device *mtd_dev;
u8 part_num;
dfu->layout = DFU_RAW_ADDR;
- dev = simple_strtoul(s, &s, 10);
- s++;
- part = simple_strtoul(s, &s, 10);
+ dev = dectoul(argv[1], &s);
+ if (*s)
+ return -EINVAL;
+ part = dectoul(argv[2], &s);
+ if (*s)
+ return -EINVAL;
sprintf(mtd_id, "%s%d,%d", "nor", dev, part - 1);
printf("using id '%s'\n", mtd_id);
}
dfu->data.sf.start = pi->offset;
dfu->data.sf.size = pi->size;
- if (!strcmp(st, "partubi"))
+ if (!strcmp(argv[0], "partubi"))
dfu->data.sf.ubi = 1;
} else {
- printf("%s: Memory layout (%s) not supported!\n", __func__, st);
+ printf("%s: Memory layout (%s) not supported!\n", __func__, argv[0]);
spi_flash_free(dfu->data.sf.dev);
return -1;
}