summaryrefslogtreecommitdiffstats
path: root/libdpf/dpflib.c
diff options
context:
space:
mode:
Diffstat (limited to 'libdpf/dpflib.c')
-rw-r--r--libdpf/dpflib.c640
1 files changed, 361 insertions, 279 deletions
diff --git a/libdpf/dpflib.c b/libdpf/dpflib.c
index cfda55b..3af8ebb 100644
--- a/libdpf/dpflib.c
+++ b/libdpf/dpflib.c
@@ -8,7 +8,7 @@
* One day we might use a proper protocol like netpp.
*
*/
-
+
// FIXME: Put all those SCSI commands in one (wrapped) place.
#include "dpf.h"
@@ -49,326 +49,401 @@ int dpf_query(DPFHANDLE h)
-int dpf_open(const char *dev, DPFHANDLE *h)
+int
+dpf_open (const char *dev, DPFHANDLE * h)
{
- int error = 0;
- DPFContext *dpf;
- int i;
- usb_dev_handle *u;
-
- int fd;
-
- if (!dev) {
- fprintf(stderr, "Please specify a string like 'usb0' or a sg device\n");
- return DEVERR_OPEN;
- }
-
- if (strncmp(dev, "usb", 3) == 0) {
- i = dev[3] - '0';
- error = dpf_usb_open(i, &u);
- if (error < 0) return error;
- if (!u) return DEVERR_OPEN;
- i = error; // USB mode
- error = 0;
- } else {
- fprintf(stderr, "Opening generic SCSI device '%s'\n", dev);
- if (sgdev_open(dev, &fd) < 0) return DEVERR_OPEN;
- i = MODE_SG;
- }
-
- dpf = (DPFHANDLE) malloc(sizeof(DPFContext));
- if (!dpf) return DEVERR_MALLOC;
-
- dpf->flags = 0;
- dpf->mode = i;
-
- switch (dpf->mode) {
- case MODE_USB:
- dpf->dev.udev = u;
- error = probe(dpf);
- fprintf(stderr, "Got LCD dimensions: %dx%d\n",
- dpf->width, dpf->height);
- dpf->methods = scsi_methods;
- break;
- case MODE_USBHID:
- dpf->dev.udev = u;
- dpf->methods = hid_methods;
- break;
- case MODE_SG:
- dpf->dev.fd = fd;
- dpf->methods = scsi_methods;
- break;
- default:
- fprintf(stderr, "Unknown interface mode\n");
- error = -1;
- }
-
- *h = dpf;
- return error;
+ int error = 0;
+ DPFContext *dpf;
+ int i;
+ usb_dev_handle *u;
+
+ int fd;
+
+ if (!dev)
+ {
+ fprintf (stderr,
+ "Please specify a string like 'usb0' or a sg device\n");
+ return DEVERR_OPEN;
+ }
+
+ if (strncmp (dev, "usb", 3) == 0)
+ {
+ i = dev[3] - '0';
+ error = dpf_usb_open (i, &u);
+ if (error < 0)
+ return error;
+ if (!u)
+ return DEVERR_OPEN;
+ i = error; // USB mode
+ error = 0;
+ }
+ else
+ {
+ fprintf (stderr, "Opening generic SCSI device '%s'\n", dev);
+ if (sgdev_open (dev, &fd) < 0)
+ return DEVERR_OPEN;
+ i = MODE_SG;
+ }
+
+ dpf = (DPFHANDLE) malloc (sizeof (DPFContext));
+ if (!dpf)
+ return DEVERR_MALLOC;
+
+ dpf->flags = 0;
+ dpf->mode = i;
+
+ switch (dpf->mode)
+ {
+ case MODE_USB:
+ dpf->dev.udev = u;
+ error = probe (dpf);
+ fprintf (stderr, "Got LCD dimensions: %dx%d\n",
+ dpf->width, dpf->height);
+ dpf->methods = scsi_methods;
+ break;
+ case MODE_USBHID:
+ dpf->dev.udev = u;
+ dpf->methods = hid_methods;
+ break;
+ case MODE_SG:
+ dpf->dev.fd = fd;
+ dpf->methods = scsi_methods;
+ break;
+ default:
+ fprintf (stderr, "Unknown interface mode\n");
+ error = -1;
+ }
+
+ *h = dpf;
+ return error;
}
-void dpf_close(DPFContext *h)
+void
+dpf_close (DPFContext * h)
{
- switch (h->mode) {
- case MODE_USBHID:
- case MODE_SG:
- close(h->dev.fd);
- break;
- case MODE_USB:
- usb_release_interface(h->dev.udev, 0);
- usb_close(h->dev.udev);
- break;
- }
- free(h);
+ switch (h->mode)
+ {
+ case MODE_USBHID:
+ case MODE_SG:
+ close (h->dev.fd);
+ break;
+ case MODE_USB:
+ usb_release_interface (h->dev.udev, 0);
+ usb_close (h->dev.udev);
+ break;
+ }
+ free (h);
}
-const char *dev_errstr(int err)
+const char *
+dev_errstr (int err)
{
- switch (err) {
- case DEVERR_FILE: return "File I/O error";
- case DEVERR_OPEN: return "File open error";
- case DEVERR_HEX: return "Hex file error";
- case DEVERR_CHK: return "Checksum error";
- case DEVERR_IO: return "Common I/O error";
- case DEVERR_UNSUPP: return "Unsupported feature";
- default: return "Unknown error";
- }
+ switch (err)
+ {
+ case DEVERR_FILE:
+ return "File I/O error";
+ case DEVERR_OPEN:
+ return "File open error";
+ case DEVERR_HEX:
+ return "Hex file error";
+ case DEVERR_CHK:
+ return "Checksum error";
+ case DEVERR_IO:
+ return "Common I/O error";
+ case DEVERR_UNSUPP:
+ return "Unsupported feature";
+ default:
+ return "Unknown error";
+ }
}
-int flash_probe(DPFContext *h, unsigned char *id)
+int
+flash_probe (DPFContext * h, unsigned char *id)
{
- return h->methods.flash_probe(h, id);
+ return h->methods.flash_probe (h, id);
}
-int flash_cmd(DPFContext *h, int command, int cmdlen, ADDR addr)
+int
+flash_cmd (DPFContext * h, int command, int cmdlen, ADDR addr)
{
- return h->methods.flash_cmd(h, command, cmdlen, addr);
+ return h->methods.flash_cmd (h, command, cmdlen, addr);
}
/* Flash functions, API */
-int flash_read(DPFContext *h, unsigned char *buf, ADDR offset, int len)
+int
+flash_read (DPFContext * h, unsigned char *buf, ADDR offset, int len)
{
- return h->methods.flash_read(h, buf, offset, len);
+ return h->methods.flash_read (h, buf, offset, len);
}
-int flash_status_wait(DPFContext *h, uint8_t mask)
+int
+flash_status_wait (DPFContext * h, uint8_t mask)
{
- int error;
- uint8_t status;
-
- do {
- error = h->methods.flash_status(h, &status);
- } while ((status & mask) && !error);
-
- return error;
+ int error;
+ uint8_t status;
+
+ do
+ {
+ error = h->methods.flash_status (h, &status);
+ }
+ while ((status & mask) && !error);
+
+ return error;
}
-int flash_write(DPFContext *h, const unsigned char *buf, ADDR offset, int len)
+int
+flash_write (DPFContext * h, const unsigned char *buf, ADDR offset, int len)
{
- int n;
- int error = 0;
-
- while (len > 0) {
- error = h->methods.flash_cmd(h, SPM_WREN, 1, 0);
- DEB(printf("Write pages at %06x\n", offset));
- n = h->methods.flash_writechunk(h, buf, offset, len);
- error = flash_status_wait(h, SPS_WIP);
-
- if (n < 0) break;
- len -= n; buf += n; offset += n;
- }
- return error;
+ int n;
+ int error = 0;
+
+ while (len > 0)
+ {
+ error = h->methods.flash_cmd (h, SPM_WREN, 1, 0);
+ DEB (printf ("Write pages at %06x\n", offset));
+ n = h->methods.flash_writechunk (h, buf, offset, len);
+ error = flash_status_wait (h, SPS_WIP);
+
+ if (n < 0)
+ break;
+ len -= n;
+ buf += n;
+ offset += n;
+ }
+ return error;
}
/* Mid level flash */
-int load_ihx(DPFContext *h, const char *fname, unsigned char *data,
- unsigned int *buflen, unsigned int reloc)
+int
+load_ihx (DPFContext * h, const char *fname, unsigned char *data,
+ unsigned int *buflen, unsigned int reloc)
{
- unsigned char csum_is, csum_need;
- int ret;
- FILE *f;
-
- static char line[512];
- static unsigned char buf[0x100];
- int count;
- unsigned int addr, len, type;
- unsigned short b;
- unsigned int total = 0;
-
- DEB(printf("Opening %s...\n", fname));
- f = fopen(fname, "r");
- if (f == NULL) {
- return DEVERR_OPEN;
+ unsigned char csum_is, csum_need;
+ int ret;
+ FILE *f;
+
+ static char line[512];
+ static unsigned char buf[0x100];
+ int count;
+ unsigned int addr, len, type;
+ unsigned short b;
+ unsigned int total = 0;
+
+ DEB (printf ("Opening %s...\n", fname));
+ f = fopen (fname, "r");
+ if (f == NULL)
+ {
+ return DEVERR_OPEN;
}
- while(1) {
- fgets(line, sizeof(line), f);
+ while (1)
+ {
+ fgets (line, sizeof (line), f);
- if (feof(f) || ferror(f)) break;
+ if (feof (f) || ferror (f))
+ break;
- if ((line[0] != ':') || (strlen(line) < 9)) {
- fprintf(stderr, "invalid line in ihx\n");
- break;
+ if ((line[0] != ':') || (strlen (line) < 9))
+ {
+ fprintf (stderr, "invalid line in ihx\n");
+ break;
}
- ret = sscanf(&line[1], "%02x", &len);
- if (ret != 1) { ret = DEVERR_HEX; break; }
+ ret = sscanf (&line[1], "%02x", &len);
+ if (ret != 1)
+ {
+ ret = DEVERR_HEX;
+ break;
+ }
- ret = sscanf(&line[3], "%04x", &addr);
- if (ret != 1) { ret = DEVERR_HEX; break; }
+ ret = sscanf (&line[3], "%04x", &addr);
+ if (ret != 1)
+ {
+ ret = DEVERR_HEX;
+ break;
+ }
- ret = sscanf(&line[7], "%02x", &type);
- if (ret != 1) { ret = DEVERR_HEX; break; }
+ ret = sscanf (&line[7], "%02x", &type);
+ if (ret != 1)
+ {
+ ret = DEVERR_HEX;
+ break;
+ }
#ifdef DEBUG
- printf("len %u addr %04x type %u\n", len, addr, type);
+ printf ("len %u addr %04x type %u\n", len, addr, type);
#endif
- if (type == 1) break;
+ if (type == 1)
+ break;
+
+ if (type != 0)
+ {
+ fprintf (stderr, "ihx: unknown type %u\n", type);
+ continue;
+ }
+
+ csum_need = len + (addr & 0xff) + (addr >> 8) + type;
+
+ total += len;
+ if (total > *buflen)
+ {
+ fprintf (stderr, "Buffer length exceeded. IHX file too big.\n");
+ ret = DEVERR_HEX;
+ break;
+ }
- if (type != 0) {
- fprintf(stderr, "ihx: unknown type %u\n", type);
- continue;
+ if (len > sizeof (buf))
+ {
+ fprintf (stderr, "Buffer length exceeded. Too long lines.\n");
+ ret = DEVERR_HEX;
+ break;
}
- csum_need = len + (addr & 0xff) + (addr >> 8) + type;
-
- total += len;
- if (total > *buflen) {
- fprintf(stderr, "Buffer length exceeded. IHX file too big.\n");
- ret = DEVERR_HEX;
- break;
- }
-
- if (len > sizeof(buf)) {
- fprintf(stderr, "Buffer length exceeded. Too long lines.\n");
- ret = DEVERR_HEX;
- break;
- }
-
- for(count = 0; count < len; count++) {
- ret = sscanf(&line[9 + count * 2], "%02hx", &b);
- if (ret != 1) {
- fprintf(stderr, "hex file: could not parse data!\n");
- break;
+ for (count = 0; count < len; count++)
+ {
+ ret = sscanf (&line[9 + count * 2], "%02hx", &b);
+ if (ret != 1)
+ {
+ fprintf (stderr, "hex file: could not parse data!\n");
+ break;
}
- buf[count] = b;
- csum_need += buf[count];
+ buf[count] = b;
+ csum_need += buf[count];
}
- if (ret != 1) { ret = DEVERR_HEX; break; }
+ if (ret != 1)
+ {
+ ret = DEVERR_HEX;
+ break;
+ }
- ret = sscanf(&line[9 + len * 2], "%02hx", &b);
- if (ret != 1) { ret = DEVERR_HEX; break; }
+ ret = sscanf (&line[9 + len * 2], "%02hx", &b);
+ if (ret != 1)
+ {
+ ret = DEVERR_HEX;
+ break;
+ }
- csum_is = b;
- if (((csum_need+csum_is) & 0xff) != 0x00) {
- fprintf(stderr, "ihx: checksum failure! is: %02x should be:%02x\n",
+ csum_is = b;
+ if (((csum_need + csum_is) & 0xff) != 0x00)
+ {
+ fprintf (stderr, "ihx: checksum failure! is: %02x should be:%02x\n",
csum_is, csum_need);
- ret = DEVERR_CHK;
- break;
+ ret = DEVERR_CHK;
+ break;
}
- if (addr < reloc) {
- fprintf(stderr, "Bad relocation value\n");
- ret = DEVERR_HEX;
- break;
- }
- // Copy to data buffer at relocated address
- if (data) {
- DEB(printf("Patching at offset %08x, chunk size %d\n",
- addr - reloc, len));
- memcpy(&data[addr - reloc], buf, len);
- } else {
- DEB(printf("Writing to %04x (CODE: %04x), chunk size %d\n",
- addr - reloc, addr, len));
- h->methods.mem_write(h, addr - reloc, buf, len);
- }
+ if (addr < reloc)
+ {
+ fprintf (stderr, "Bad relocation value\n");
+ ret = DEVERR_HEX;
+ break;
+ }
+ // Copy to data buffer at relocated address
+ if (data)
+ {
+ DEB (printf ("Patching at offset %08x, chunk size %d\n",
+ addr - reloc, len));
+ memcpy (&data[addr - reloc], buf, len);
+ }
+ else
+ {
+ DEB (printf ("Writing to %04x (CODE: %04x), chunk size %d\n",
+ addr - reloc, addr, len));
+ h->methods.mem_write (h, addr - reloc, buf, len);
+ }
}
- *buflen = total;
- fclose(f);
- return ret;
+ *buflen = total;
+ fclose (f);
+ return ret;
}
-int flash_erase_full(DPFContext *h)
+int
+flash_erase_full (DPFContext * h)
{
- flash_cmd(h, SPM_RES, 1, 0);
- flash_cmd(h, SPM_WRSR, 2, 0); // clr status
- flash_cmd(h, SPM_WREN, 1, 0);
- flash_cmd(h, SPM_FLASH_BE, 1, 0);
- printf("Erase full flash...\n");
+ flash_cmd (h, SPM_RES, 1, 0);
+ flash_cmd (h, SPM_WRSR, 2, 0); // clr status
+ flash_cmd (h, SPM_WREN, 1, 0);
+ flash_cmd (h, SPM_FLASH_BE, 1, 0);
+ printf ("Erase full flash...\n");
- return flash_status_wait(h, SPS_WIP);
+ return flash_status_wait (h, SPS_WIP);
}
-int flash_erase(DPFContext *h, ADDR addr)
+int
+flash_erase (DPFContext * h, ADDR addr)
{
- int error;
- flash_cmd(h, SPM_RES, 1, 0);
- flash_cmd(h, SPM_WREN, 1, 0);
- flash_cmd(h, SPM_WRSR, 2, 0); // clr status
+ int error;
+ flash_cmd (h, SPM_RES, 1, 0);
+ flash_cmd (h, SPM_WREN, 1, 0);
+ flash_cmd (h, SPM_WRSR, 2, 0); // clr status
- // now erase flash sector:
- flash_cmd(h, SPM_WREN, 1, 0);
- flash_cmd(h, SPM_FLASH_SE, 4, addr);
+ // now erase flash sector:
+ flash_cmd (h, SPM_WREN, 1, 0);
+ flash_cmd (h, SPM_FLASH_SE, 4, addr);
- error = flash_status_wait(h, SPS_WIP);
- flash_cmd(h, SPM_WRDI, 1, 0);
+ error = flash_status_wait (h, SPS_WIP);
+ flash_cmd (h, SPM_WRDI, 1, 0);
- return error;
+ return error;
}
-int dpf_flash_lock(DPFContext *h, char enable)
+int
+dpf_flash_lock (DPFContext * h, char enable)
{
- if (h->methods.flash_lock)
- return h->methods.flash_lock(h, enable);
- else
- return DEVERR_UNSUPP;
+ if (h->methods.flash_lock)
+ return h->methods.flash_lock (h, enable);
+ else
+ return DEVERR_UNSUPP;
}
-int patch_sector(DPFContext *h,
- ADDR reloc, unsigned long addr, const char *hexfile)
+int
+patch_sector (DPFContext * h,
+ ADDR reloc, unsigned long addr, const char *hexfile)
{
- int error;
- unsigned short offset;
- static
- unsigned char readbuf[0x10000];
- unsigned int len = sizeof(readbuf);
-
- offset = addr & 0xffff;
- addr -= offset;
-
- error = flash_read(h, readbuf, addr, 0x10000);
- if (error < 0) {
- perror("Reading flash");
- return error;
- }
-
- error = load_ihx(h, hexfile, &readbuf[offset], &len, reloc);
- if (error < 0) {
- fprintf(stderr, "Failed to load HEX file\n");
- return error;
- }
- // Lock DPF handler so nothing can interfere with the flashing (in case
- // we flash ourselves)
- dpf_flash_lock(h, 1);
- error = flash_cmd(h, SPM_WREN, 1, 0);
- error = flash_cmd(h, SPM_WRSR, 2, 0); // clr status
-
- error = flash_erase(h, addr);
- if (error < 0) return error;
-
- error = flash_write(h, readbuf, addr, 0x10000); // clr status
- dpf_flash_lock(h, 0);
-
- return error;
+ int error;
+ unsigned short offset;
+ static unsigned char readbuf[0x10000];
+ unsigned int len = sizeof (readbuf);
+
+ offset = addr & 0xffff;
+ addr -= offset;
+
+ error = flash_read (h, readbuf, addr, 0x10000);
+ if (error < 0)
+ {
+ perror ("Reading flash");
+ return error;
+ }
+
+ error = load_ihx (h, hexfile, &readbuf[offset], &len, reloc);
+ if (error < 0)
+ {
+ fprintf (stderr, "Failed to load HEX file\n");
+ return error;
+ }
+ // Lock DPF handler so nothing can interfere with the flashing (in case
+ // we flash ourselves)
+ dpf_flash_lock (h, 1);
+ error = flash_cmd (h, SPM_WREN, 1, 0);
+ error = flash_cmd (h, SPM_WRSR, 2, 0); // clr status
+
+ error = flash_erase (h, addr);
+ if (error < 0)
+ return error;
+
+ error = flash_write (h, readbuf, addr, 0x10000); // clr status
+ dpf_flash_lock (h, 0);
+
+ return error;
}
////////////////////////////////////////////////////////////////////////////
@@ -376,42 +451,51 @@ int patch_sector(DPFContext *h,
// These require a hacked command handler with extended command set.
-int load_hexfile(DPFContext *h, const char *hexfile)
+int
+load_hexfile (DPFContext * h, const char *hexfile)
{
- unsigned int len = 0xc000;
- int error;
+ unsigned int len = 0xc000;
+ int error;
- error = load_ihx(h, hexfile, 0, &len, 0x800);
- return error;
+ error = load_ihx (h, hexfile, 0, &len, 0x800);
+ return error;
}
#define CHUNK_SIZE 1024
-int read_mem(DPFContext *h, unsigned char *buf, ADDR src, unsigned short len)
+int
+read_mem (DPFContext * h, unsigned char *buf, ADDR src, unsigned short len)
{
- int error = 0;
- if (!h->methods.mem_read) return DEVERR_UNSUPP;
-
- while (len > CHUNK_SIZE && error >= 0) {
- error = h->methods.mem_read(h, buf, src, CHUNK_SIZE);
- src += CHUNK_SIZE; len -= CHUNK_SIZE; buf += CHUNK_SIZE;
- }
- error = h->methods.mem_read(h, buf, src, len);
-
- return error;
+ int error = 0;
+ if (!h->methods.mem_read)
+ return DEVERR_UNSUPP;
+
+ while (len > CHUNK_SIZE && error >= 0)
+ {
+ error = h->methods.mem_read (h, buf, src, CHUNK_SIZE);
+ src += CHUNK_SIZE;
+ len -= CHUNK_SIZE;
+ buf += CHUNK_SIZE;
+ }
+ error = h->methods.mem_read (h, buf, src, len);
+
+ return error;
}
-int write_mem(DPFContext *h, ADDR dst, const unsigned char *buf, unsigned short len)
+int
+write_mem (DPFContext * h, ADDR dst, const unsigned char *buf,
+ unsigned short len)
{
- return h->methods.mem_write(h, dst, buf, len);
+ return h->methods.mem_write (h, dst, buf, len);
}
-int code_go(DPFContext *h, ADDR start)
+int
+code_go (DPFContext * h, ADDR start)
{
- printf("Executing applet..\n");
- if (h->methods.go)
- return h->methods.go(h, start);
- return DEVERR_UNSUPP;
+ printf ("Executing applet..\n");
+ if (h->methods.go)
+ return h->methods.go (h, start);
+ return DEVERR_UNSUPP;
}
@@ -423,14 +507,12 @@ int code_go(DPFContext *h, ADDR start)
* into start address
*/
-int dpf_bootstrap(DPFContext *h,
- ADDR dest, unsigned char *src, unsigned short n, ADDR start)
+int
+dpf_bootstrap (DPFContext * h,
+ ADDR dest, unsigned char *src, unsigned short n, ADDR start)
{
- if (h->methods.bootstrap)
- return h->methods.bootstrap(h, dest, src, n, start);
- else
- return DEVERR_UNSUPP;
+ if (h->methods.bootstrap)
+ return h->methods.bootstrap (h, dest, src, n, start);
+ else
+ return DEVERR_UNSUPP;
}
-
-
-