Message ID | 1334215049-20362-4-git-send-email-l.majewski@samsung.com |
---|---|
State | Changes Requested |
Delegated to: | Marek Vasut |
Headers | show |
Dear Lukasz Majewski, > Support for THOR download protocol. Those files are necessary for > proper f_usbd_thor function proper work. > > Signed-off-by: Lukasz Majewski <l.majewski@samsung.com> > Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com> > Cc: Marek Vasut <marex@denx.de> > --- > drivers/usb/gadget/prot_thor.c | 247 > ++++++++++++++++++++++++++++++++++++++++ drivers/usb/gadget/prot_thor.h | > 112 ++++++++++++++++++ > include/usbd_thor.h | 108 +++++++++++++++++ > 3 files changed, 467 insertions(+), 0 deletions(-) > create mode 100644 drivers/usb/gadget/prot_thor.c > create mode 100644 drivers/usb/gadget/prot_thor.h > create mode 100644 include/usbd_thor.h > > diff --git a/drivers/usb/gadget/prot_thor.c > b/drivers/usb/gadget/prot_thor.c new file mode 100644 > index 0000000..9b2610d > --- /dev/null > +++ b/drivers/usb/gadget/prot_thor.c > @@ -0,0 +1,247 @@ > +/* > + * prot_thor.c -- USB THOR Downloader protocol > + * > + * Copyright (C) 2012 Samsung Electronics > + * Lukasz Majewski <l.majewski@samsung.com> > + * > + * This program 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 2 of the License, or > + * (at your option) any later version. > + * > + * This program 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 this program; if not, write to the Free Software > + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 > USA + * > + */ > +#undef DEBUG > +#include <common.h> > +#include <errno.h> > +#include <g_dnl.h> > +#include "prot_thor.h" > + > +static void send_rsp(const rsp_box *rsp) > +{ > + /* should be copy on dma duffer */ > + memcpy(usbd_tx_data_buf, rsp, sizeof(rsp_box)); > + pkt_upload(usbd_tx_data_buf, sizeof(rsp_box)); > + > + debug("-RSP: %d, %d\n", rsp->rsp, rsp->rsp_data); You should really unify these debug outputs > +} > + > +static void send_data_rsp(s32 ack, s32 count) > +{ > + data_rsp_box rsp; > + > + rsp.ack = ack; > + rsp.count = count; > + > + /* should be copy on dma duffer */ > + memcpy(usbd_tx_data_buf, &rsp, sizeof(data_rsp_box)); > + pkt_upload(usbd_tx_data_buf, sizeof(data_rsp_box)); > + > + debug("-DATA RSP: %d, %d\n", ack, count); > +} > + > +static int process_rqt_info(const rqt_box *rqt) > +{ > + rsp_box rsp = {0, }; > + > + rsp.rsp = rqt->rqt; > + rsp.rsp_data = rqt->rqt_data; > + > + switch (rqt->rqt_data) { > + case RQT_INFO_VER_PROTOCOL: > + rsp.int_data[0] = VER_PROTOCOL_MAJOR; > + rsp.int_data[1] = VER_PROTOCOL_MINOR; > + break; > + case RQT_INIT_VER_HW: > + sprintf(rsp.str_data[0], "%x", checkboard()); > + break; > + case RQT_INIT_VER_BOOT: > + sprintf(rsp.str_data[0], "%s", getenv("ver")); > + break; > + case RQT_INIT_VER_KERNEL: > + sprintf(rsp.str_data[0], "%s", "k unknown"); > + break; > + case RQT_INIT_VER_PLATFORM: > + sprintf(rsp.str_data[0], "%s", "p unknown"); > + break; > + case RQT_INIT_VER_CSC: > + sprintf(rsp.str_data[0], "%s", "c unknown"); > + break; > + default: > + return 0; > + } > + > + send_rsp(&rsp); > + return 1; > +} > + > +static int process_rqt_cmd(const rqt_box *rqt) > +{ > + rsp_box rsp = {0, }; > + > + rsp.rsp = rqt->rqt; > + rsp.rsp_data = rqt->rqt_data; > + > + switch (rqt->rqt_data) { > + case RQT_CMD_REBOOT: > + debug("TARGET RESET\n"); > + send_rsp(&rsp); > + run_command("reset", 0); > + break; > + case RQT_CMD_POWEROFF: > + case RQT_CMD_EFSCLEAR: > + send_rsp(&rsp); > + default: > + printf("Command not supported -> cmd: %d\n", rqt->rqt_data); > + return -1; > + } > + > + return 0; > +} > + > +static unsigned long download(unsigned int total, unsigned int > packet_size, + struct g_dnl *dnl) > +{ > + int count = 0; > + unsigned int rcv_cnt; > + static int sect_start = 92160; /* Hardcoded -> will be fixed -> */ > + unsigned int dma_buffer_address = CONFIG_SYS_DOWN_ADDR; > + > + do { > + if (packet_size == PKT_DOWNLOAD_SIZE) > + dma_buffer_address = > + CONFIG_SYS_DOWN_ADDR + (count * packet_size); > + > + usbd_set_dma((char *) dma_buffer_address, > + packet_size); > + > + rcv_cnt += usbd_rx_data(); > + debug("RCV data count: %u\n", rcv_cnt); > + > + /* Store data after receiving a "chunk" packet */ > + if (packet_size == PKT_DOWNLOAD_CHUNK_SIZE && > + (rcv_cnt % PKT_DOWNLOAD_CHUNK_SIZE) == 0) { > + dnl->p = (sect_start + count * > + (PKT_DOWNLOAD_CHUNK_SIZE >> 9)); > + debug("DNL STORE dnl->p: %d\n", dnl->p); > + dnl->store(dnl, dnl->medium); > + } > + send_data_rsp(0, ++count); > + } while (rcv_cnt < total); > + > + debug("rcv: %d dnl: %d\n", rcv_cnt, total); > + > + return rcv_cnt; > +} > + > +static int process_rqt_download(const rqt_box *rqt, struct g_dnl *dnl) > +{ > + static unsigned long download_total_size, cnt; > + static char f_name[F_NAME_BUF_SIZE]; > + rsp_box rsp = {0, }; > + int file_type; > + int ret = 1; > + > + rsp.rsp = rqt->rqt; > + rsp.rsp_data = rqt->rqt_data; > + > + switch (rqt->rqt_data) { > + case RQT_DL_INIT: > + download_total_size = rqt->int_data[0]; > + > + debug("INIT: total %d bytes\n", rqt->int_data[0]); > + break; > + case RQT_DL_FILE_INFO: > + file_type = rqt->int_data[0]; > + if (file_type == FILE_TYPE_PIT) { > + puts("PIT table file - not supported\n"); > + return -1; > + } > + > + dnl->file_size = rqt->int_data[1]; > + memcpy(f_name, rqt->str_data[0], sizeof(f_name)); > + > + debug("INFO: name(%s, %d), size(%d), type(%d)\n", > + f_name, 0, dnl->file_size, file_type); > + > + if (dnl->file_size > PKT_DOWNLOAD_CHUNK_SIZE) > + dnl->packet_size = PKT_DOWNLOAD_CHUNK_SIZE; > + else > + dnl->packet_size = PKT_DOWNLOAD_SIZE; > + > + printf("%s: dnl->file_size: %d dnl->packet_size: %d\n", > + __func__, dnl->file_size, dnl->packet_size); Make this debug or sanitize? > + > + rsp.int_data[0] = dnl->packet_size; > + > + dnl->file_name = f_name; > + ret = 0; > + > + break; > + case RQT_DL_FILE_START: > + send_rsp(&rsp); > + > + cnt = download(download_total_size, dnl->packet_size, dnl); > + > + dnl->store(dnl, dnl->medium); > + > + return cnt; > + case RQT_DL_FILE_END: > + debug("DL FILE_END\n"); > + break; > + case RQT_DL_EXIT: > + debug("DL EXIT\n"); > + ret = 0; > + > + break; > + default: > + printf("Operation not supported: %d\n", rqt->rqt_data); > + return -1; > + } > + > + send_rsp(&rsp); > + return ret; > +} > + > +int process_data(struct g_dnl *dnl) > +{ > + rqt_box rqt; > + int ret = 1; > + > + memset(&rqt, 0, sizeof(rqt)); > + memcpy(&rqt, usbd_rx_data_buf, sizeof(rqt)); > + > + debug("+RQT: %d, %d\n", rqt.rqt, rqt.rqt_data); > + > + switch (rqt.rqt) { > + case RQT_INFO: > + ret = process_rqt_info(&rqt); > + break; > + case RQT_CMD: > + ret = process_rqt_cmd(&rqt); > + break; > + case RQT_DL: > + ret = process_rqt_download(&rqt, dnl); > + break; > + case RQT_UL: > + puts("RQT: UPLOAD not supported!\n"); > + break; > + default: > + printf("unknown request (%d)\n", rqt.rqt); > + ret = 0; > + } > + > + /* exit code: */ > + /* 0 - success */ > + /* < 0 - Error code */ > + > + return ret; > +} > diff --git a/drivers/usb/gadget/prot_thor.h > b/drivers/usb/gadget/prot_thor.h new file mode 100644 > index 0000000..6e72c75 > --- /dev/null > +++ b/drivers/usb/gadget/prot_thor.h > @@ -0,0 +1,112 @@ > +/* > + * THOR protocol internals > + * > + * Copyright (C) 2012 Samsung Electronics > + * Lukasz Majewski <l.majewski@samsung.com> > + * > + * This program 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 2 of > + * the License, or (at your option) any later version. > + * > + * This program 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 this program; if not, write to the Free Software > + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, > + * MA 02111-1307 USA > + */ > + > +#ifndef __PROT_THOR_H_ > +#define __PROT_THOR_H_ > + > +#include <common.h> > +#include <linux/usb/f_usbd_thor.h> > + > +#define VER_PROTOCOL_MAJOR 4 > +#define VER_PROTOCOL_MINOR 0 > + > +enum rqt { > + RQT_INFO = 200, > + RQT_CMD, > + RQT_DL, > + RQT_UL, > +}; > + > +enum rqt_data { > + /* RQT_INFO */ > + RQT_INFO_VER_PROTOCOL = 1, > + RQT_INIT_VER_HW, > + RQT_INIT_VER_BOOT, > + RQT_INIT_VER_KERNEL, > + RQT_INIT_VER_PLATFORM, > + RQT_INIT_VER_CSC, > + > + /* RQT_CMD */ > + RQT_CMD_REBOOT = 1, > + RQT_CMD_POWEROFF, > + RQT_CMD_EFSCLEAR, > + > + /* RQT_DL */ > + RQT_DL_INIT = 1, > + RQT_DL_FILE_INFO, > + RQT_DL_FILE_START, > + RQT_DL_FILE_END, > + RQT_DL_EXIT, > + > + /* RQT_UL */ > + RQT_UL_INIT = 1, > + RQT_UL_START, > + RQT_UL_END, > + RQT_UL_EXIT, > +}; > + > +typedef struct _rqt_box { /* total: 256B */ > + s32 rqt; /* request id */ > + s32 rqt_data; /* request data id */ > + s32 int_data[14]; /* int data */ > + char str_data[5][32]; /* string data */ > + char md5[32]; /* md5 checksum */ > +} __attribute__((packed)) rqt_box; > + > +typedef struct _rsp_box { /* total: 128B */ > + s32 rsp; /* response id (= request id) */ > + s32 rsp_data; /* response data id */ > + s32 ack; /* ack */ > + s32 int_data[5]; /* int data */ > + char str_data[3][32]; /* string data */ > +} __attribute__((packed)) rsp_box; > + > +typedef struct _data_rsp_box { /* total: 8B */ > + s32 ack; /* response id (= request id) */ > + s32 count; /* response data id */ > +} __attribute__((packed)) data_rsp_box; > + > +enum { > + FILE_TYPE_NORMAL, > + FILE_TYPE_PIT, > +}; > + > +#define F_NAME_BUF_SIZE 32 > + > +/* download packet size */ > +#define PKT_DOWNLOAD_SIZE (1 << 20) /* 1 MiB */ > +#define PKT_DOWNLOAD_CHUNK_SIZE (32 << 20) /* 32 MiB */ > + > +int process_data(struct g_dnl *dnl); > + > +static inline int pkt_download(void *dest, const int size) > +{ > + usbd_set_dma((char *)dest, size); > + return usbd_rx_data(); > +} > + > +static inline void pkt_upload(void *src, const int size) > +{ > + usbd_tx_data((char *)src, size); > +} > + > +#endif /* __PROT_THOR_H__ */ > diff --git a/include/usbd_thor.h b/include/usbd_thor.h > new file mode 100644 > index 0000000..d31bb35 > --- /dev/null > +++ b/include/usbd_thor.h > @@ -0,0 +1,108 @@ > +/* > + * USB Downloader for SLP > + * > + * Copyright (C) 2011-2012 Samsung Electronics > + * Minkyu Kang <mk7.kang@samsung.com> > + * Sanghee Kim <sh0130.kim@samsung.com> > + * Lukasz Majewski <l.majewski@samsung.com> > + * > + */ > + > +#ifndef _USBD_H_ > +#define _USBD_H_ > + > +#define msleep(a) udelay(a * 1000) > + > +/* > + * updateflag is consist of below bit. > + * 7: RESERVED. > + * 6: RESERVED. > + * 5: RESERVED. > + * 4: SLP_MMC_RESIZE_REQUIRED > + * 3: SLP_ROOTFS_NEW > + * 2: SLP_KERNEL_NEW > + * 1: SLP_SBL_NEW > + * 0: SLP_PBL_NEW > + */ > +enum { > + SLP_PBL_NEW = 0, > + SLP_SBL_NEW, > + SLP_KERNEL_NEW, > + SLP_ROOTFS_NEW, > + SLP_MMC_RESIZE_REQUIRED > +}; > + > +/* status definition */ > +enum { > + STATUS_DONE = 0, > + STATUS_RETRY, > + STATUS_ERROR, > +}; > + > +/* download mode definition */ > +enum { > + MODE_NORMAL = 0, > + MODE_FORCE, > +}; > + > +/* end mode */ > +enum { > + END_BOOT = 0, > + END_RETRY, > + END_FAIL, > + END_NORMAL, > +}; > +/* > + * USB Downloader Operations > + * All functions and valuable are mandatory > + * > + * usb_init : initialize the USB Controller and check the connection > + * usb_stop : stop and release USB > + * send_data : send the data (BULK ONLY!!) > + * recv_data : receive the data and returns received size (BULK ONLY!!) > + * recv_setup : setup download address, length and DMA setting for receive > + * tx_data : send data address > + * rx_data : receive data address > + * tx_len : size of send data > + * rx_len : size of receive data > + * ram_addr : address of will be stored data on RAM > + * > + * mmc_dev : device number of mmc > + * mmc_max : number of max blocks > + * mmc_blk : mmc block size > + * mmc_total : mmc total blocks > + */ > +struct usbd_ops { > + int (*usb_init)(void); > + void (*usb_stop)(void); > + void (*send_data)(char *, int); > + int (*recv_data)(void); > + void (*recv_setup)(char *, int); > +#ifdef CONFIG_USB_S5PC_DMA > + void (*prepare_dma)(void * , u32 , uchar); > + void (*dma_done)(int); > +#endif > + char *tx_data; > + char *rx_data; > + ulong tx_len; > + ulong rx_len; > + ulong ram_addr; > + > + /* mmc device info */ > + uint mmc_dev; > + uint mmc_max; > + uint mmc_blk; > + uint mmc_total; > + > + void (*set_logo)(char *, int); > + void (*set_progress)(int); > + void (*cpu_reset)(void); > + void (*down_start)(void); > + void (*down_cancel)(int); > +}; > + > +/* This function is interfaced between USB Device Controller and USB > Downloader + * Must Implementation this function at USB Controller!! */ > +struct usbd_ops *usbd_set_interface(struct usbd_ops *); > + > +#endif /* _USBD_H_ */
Dear Lukasz Majewski, In message <1334215049-20362-4-git-send-email-l.majewski@samsung.com> you wrote: > Support for THOR download protocol. Those files are necessary for > proper f_usbd_thor function proper work. > > Signed-off-by: Lukasz Majewski <l.majewski@samsung.com> > Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com> > Cc: Marek Vasut <marex@denx.de> > --- > drivers/usb/gadget/prot_thor.c | 247 ++++++++++++++++++++++++++++++++++++++++ > drivers/usb/gadget/prot_thor.h | 112 ++++++++++++++++++ > include/usbd_thor.h | 108 +++++++++++++++++ > 3 files changed, 467 insertions(+), 0 deletions(-) > create mode 100644 drivers/usb/gadget/prot_thor.c > create mode 100644 drivers/usb/gadget/prot_thor.h > create mode 100644 include/usbd_thor.h Please see previous comments, and fix checkpatch warnings. Best regards, Wolfgang Denk
diff --git a/drivers/usb/gadget/prot_thor.c b/drivers/usb/gadget/prot_thor.c new file mode 100644 index 0000000..9b2610d --- /dev/null +++ b/drivers/usb/gadget/prot_thor.c @@ -0,0 +1,247 @@ +/* + * prot_thor.c -- USB THOR Downloader protocol + * + * Copyright (C) 2012 Samsung Electronics + * Lukasz Majewski <l.majewski@samsung.com> + * + * This program 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 2 of the License, or + * (at your option) any later version. + * + * This program 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 this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ +#undef DEBUG +#include <common.h> +#include <errno.h> +#include <g_dnl.h> +#include "prot_thor.h" + +static void send_rsp(const rsp_box *rsp) +{ + /* should be copy on dma duffer */ + memcpy(usbd_tx_data_buf, rsp, sizeof(rsp_box)); + pkt_upload(usbd_tx_data_buf, sizeof(rsp_box)); + + debug("-RSP: %d, %d\n", rsp->rsp, rsp->rsp_data); +} + +static void send_data_rsp(s32 ack, s32 count) +{ + data_rsp_box rsp; + + rsp.ack = ack; + rsp.count = count; + + /* should be copy on dma duffer */ + memcpy(usbd_tx_data_buf, &rsp, sizeof(data_rsp_box)); + pkt_upload(usbd_tx_data_buf, sizeof(data_rsp_box)); + + debug("-DATA RSP: %d, %d\n", ack, count); +} + +static int process_rqt_info(const rqt_box *rqt) +{ + rsp_box rsp = {0, }; + + rsp.rsp = rqt->rqt; + rsp.rsp_data = rqt->rqt_data; + + switch (rqt->rqt_data) { + case RQT_INFO_VER_PROTOCOL: + rsp.int_data[0] = VER_PROTOCOL_MAJOR; + rsp.int_data[1] = VER_PROTOCOL_MINOR; + break; + case RQT_INIT_VER_HW: + sprintf(rsp.str_data[0], "%x", checkboard()); + break; + case RQT_INIT_VER_BOOT: + sprintf(rsp.str_data[0], "%s", getenv("ver")); + break; + case RQT_INIT_VER_KERNEL: + sprintf(rsp.str_data[0], "%s", "k unknown"); + break; + case RQT_INIT_VER_PLATFORM: + sprintf(rsp.str_data[0], "%s", "p unknown"); + break; + case RQT_INIT_VER_CSC: + sprintf(rsp.str_data[0], "%s", "c unknown"); + break; + default: + return 0; + } + + send_rsp(&rsp); + return 1; +} + +static int process_rqt_cmd(const rqt_box *rqt) +{ + rsp_box rsp = {0, }; + + rsp.rsp = rqt->rqt; + rsp.rsp_data = rqt->rqt_data; + + switch (rqt->rqt_data) { + case RQT_CMD_REBOOT: + debug("TARGET RESET\n"); + send_rsp(&rsp); + run_command("reset", 0); + break; + case RQT_CMD_POWEROFF: + case RQT_CMD_EFSCLEAR: + send_rsp(&rsp); + default: + printf("Command not supported -> cmd: %d\n", rqt->rqt_data); + return -1; + } + + return 0; +} + +static unsigned long download(unsigned int total, unsigned int packet_size, + struct g_dnl *dnl) +{ + int count = 0; + unsigned int rcv_cnt; + static int sect_start = 92160; /* Hardcoded -> will be fixed -> */ + unsigned int dma_buffer_address = CONFIG_SYS_DOWN_ADDR; + + do { + if (packet_size == PKT_DOWNLOAD_SIZE) + dma_buffer_address = + CONFIG_SYS_DOWN_ADDR + (count * packet_size); + + usbd_set_dma((char *) dma_buffer_address, + packet_size); + + rcv_cnt += usbd_rx_data(); + debug("RCV data count: %u\n", rcv_cnt); + + /* Store data after receiving a "chunk" packet */ + if (packet_size == PKT_DOWNLOAD_CHUNK_SIZE && + (rcv_cnt % PKT_DOWNLOAD_CHUNK_SIZE) == 0) { + dnl->p = (sect_start + count * + (PKT_DOWNLOAD_CHUNK_SIZE >> 9)); + debug("DNL STORE dnl->p: %d\n", dnl->p); + dnl->store(dnl, dnl->medium); + } + send_data_rsp(0, ++count); + } while (rcv_cnt < total); + + debug("rcv: %d dnl: %d\n", rcv_cnt, total); + + return rcv_cnt; +} + +static int process_rqt_download(const rqt_box *rqt, struct g_dnl *dnl) +{ + static unsigned long download_total_size, cnt; + static char f_name[F_NAME_BUF_SIZE]; + rsp_box rsp = {0, }; + int file_type; + int ret = 1; + + rsp.rsp = rqt->rqt; + rsp.rsp_data = rqt->rqt_data; + + switch (rqt->rqt_data) { + case RQT_DL_INIT: + download_total_size = rqt->int_data[0]; + + debug("INIT: total %d bytes\n", rqt->int_data[0]); + break; + case RQT_DL_FILE_INFO: + file_type = rqt->int_data[0]; + if (file_type == FILE_TYPE_PIT) { + puts("PIT table file - not supported\n"); + return -1; + } + + dnl->file_size = rqt->int_data[1]; + memcpy(f_name, rqt->str_data[0], sizeof(f_name)); + + debug("INFO: name(%s, %d), size(%d), type(%d)\n", + f_name, 0, dnl->file_size, file_type); + + if (dnl->file_size > PKT_DOWNLOAD_CHUNK_SIZE) + dnl->packet_size = PKT_DOWNLOAD_CHUNK_SIZE; + else + dnl->packet_size = PKT_DOWNLOAD_SIZE; + + printf("%s: dnl->file_size: %d dnl->packet_size: %d\n", + __func__, dnl->file_size, dnl->packet_size); + + rsp.int_data[0] = dnl->packet_size; + + dnl->file_name = f_name; + ret = 0; + + break; + case RQT_DL_FILE_START: + send_rsp(&rsp); + + cnt = download(download_total_size, dnl->packet_size, dnl); + + dnl->store(dnl, dnl->medium); + + return cnt; + case RQT_DL_FILE_END: + debug("DL FILE_END\n"); + break; + case RQT_DL_EXIT: + debug("DL EXIT\n"); + ret = 0; + + break; + default: + printf("Operation not supported: %d\n", rqt->rqt_data); + return -1; + } + + send_rsp(&rsp); + return ret; +} + +int process_data(struct g_dnl *dnl) +{ + rqt_box rqt; + int ret = 1; + + memset(&rqt, 0, sizeof(rqt)); + memcpy(&rqt, usbd_rx_data_buf, sizeof(rqt)); + + debug("+RQT: %d, %d\n", rqt.rqt, rqt.rqt_data); + + switch (rqt.rqt) { + case RQT_INFO: + ret = process_rqt_info(&rqt); + break; + case RQT_CMD: + ret = process_rqt_cmd(&rqt); + break; + case RQT_DL: + ret = process_rqt_download(&rqt, dnl); + break; + case RQT_UL: + puts("RQT: UPLOAD not supported!\n"); + break; + default: + printf("unknown request (%d)\n", rqt.rqt); + ret = 0; + } + + /* exit code: */ + /* 0 - success */ + /* < 0 - Error code */ + + return ret; +} diff --git a/drivers/usb/gadget/prot_thor.h b/drivers/usb/gadget/prot_thor.h new file mode 100644 index 0000000..6e72c75 --- /dev/null +++ b/drivers/usb/gadget/prot_thor.h @@ -0,0 +1,112 @@ +/* + * THOR protocol internals + * + * Copyright (C) 2012 Samsung Electronics + * Lukasz Majewski <l.majewski@samsung.com> + * + * This program 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 2 of + * the License, or (at your option) any later version. + * + * This program 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 this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#ifndef __PROT_THOR_H_ +#define __PROT_THOR_H_ + +#include <common.h> +#include <linux/usb/f_usbd_thor.h> + +#define VER_PROTOCOL_MAJOR 4 +#define VER_PROTOCOL_MINOR 0 + +enum rqt { + RQT_INFO = 200, + RQT_CMD, + RQT_DL, + RQT_UL, +}; + +enum rqt_data { + /* RQT_INFO */ + RQT_INFO_VER_PROTOCOL = 1, + RQT_INIT_VER_HW, + RQT_INIT_VER_BOOT, + RQT_INIT_VER_KERNEL, + RQT_INIT_VER_PLATFORM, + RQT_INIT_VER_CSC, + + /* RQT_CMD */ + RQT_CMD_REBOOT = 1, + RQT_CMD_POWEROFF, + RQT_CMD_EFSCLEAR, + + /* RQT_DL */ + RQT_DL_INIT = 1, + RQT_DL_FILE_INFO, + RQT_DL_FILE_START, + RQT_DL_FILE_END, + RQT_DL_EXIT, + + /* RQT_UL */ + RQT_UL_INIT = 1, + RQT_UL_START, + RQT_UL_END, + RQT_UL_EXIT, +}; + +typedef struct _rqt_box { /* total: 256B */ + s32 rqt; /* request id */ + s32 rqt_data; /* request data id */ + s32 int_data[14]; /* int data */ + char str_data[5][32]; /* string data */ + char md5[32]; /* md5 checksum */ +} __attribute__((packed)) rqt_box; + +typedef struct _rsp_box { /* total: 128B */ + s32 rsp; /* response id (= request id) */ + s32 rsp_data; /* response data id */ + s32 ack; /* ack */ + s32 int_data[5]; /* int data */ + char str_data[3][32]; /* string data */ +} __attribute__((packed)) rsp_box; + +typedef struct _data_rsp_box { /* total: 8B */ + s32 ack; /* response id (= request id) */ + s32 count; /* response data id */ +} __attribute__((packed)) data_rsp_box; + +enum { + FILE_TYPE_NORMAL, + FILE_TYPE_PIT, +}; + +#define F_NAME_BUF_SIZE 32 + +/* download packet size */ +#define PKT_DOWNLOAD_SIZE (1 << 20) /* 1 MiB */ +#define PKT_DOWNLOAD_CHUNK_SIZE (32 << 20) /* 32 MiB */ + +int process_data(struct g_dnl *dnl); + +static inline int pkt_download(void *dest, const int size) +{ + usbd_set_dma((char *)dest, size); + return usbd_rx_data(); +} + +static inline void pkt_upload(void *src, const int size) +{ + usbd_tx_data((char *)src, size); +} + +#endif /* __PROT_THOR_H__ */ diff --git a/include/usbd_thor.h b/include/usbd_thor.h new file mode 100644 index 0000000..d31bb35 --- /dev/null +++ b/include/usbd_thor.h @@ -0,0 +1,108 @@ +/* + * USB Downloader for SLP + * + * Copyright (C) 2011-2012 Samsung Electronics + * Minkyu Kang <mk7.kang@samsung.com> + * Sanghee Kim <sh0130.kim@samsung.com> + * Lukasz Majewski <l.majewski@samsung.com> + * + */ + +#ifndef _USBD_H_ +#define _USBD_H_ + +#define msleep(a) udelay(a * 1000) + +/* + * updateflag is consist of below bit. + * 7: RESERVED. + * 6: RESERVED. + * 5: RESERVED. + * 4: SLP_MMC_RESIZE_REQUIRED + * 3: SLP_ROOTFS_NEW + * 2: SLP_KERNEL_NEW + * 1: SLP_SBL_NEW + * 0: SLP_PBL_NEW + */ +enum { + SLP_PBL_NEW = 0, + SLP_SBL_NEW, + SLP_KERNEL_NEW, + SLP_ROOTFS_NEW, + SLP_MMC_RESIZE_REQUIRED +}; + +/* status definition */ +enum { + STATUS_DONE = 0, + STATUS_RETRY, + STATUS_ERROR, +}; + +/* download mode definition */ +enum { + MODE_NORMAL = 0, + MODE_FORCE, +}; + +/* end mode */ +enum { + END_BOOT = 0, + END_RETRY, + END_FAIL, + END_NORMAL, +}; +/* + * USB Downloader Operations + * All functions and valuable are mandatory + * + * usb_init : initialize the USB Controller and check the connection + * usb_stop : stop and release USB + * send_data : send the data (BULK ONLY!!) + * recv_data : receive the data and returns received size (BULK ONLY!!) + * recv_setup : setup download address, length and DMA setting for receive + * tx_data : send data address + * rx_data : receive data address + * tx_len : size of send data + * rx_len : size of receive data + * ram_addr : address of will be stored data on RAM + * + * mmc_dev : device number of mmc + * mmc_max : number of max blocks + * mmc_blk : mmc block size + * mmc_total : mmc total blocks + */ +struct usbd_ops { + int (*usb_init)(void); + void (*usb_stop)(void); + void (*send_data)(char *, int); + int (*recv_data)(void); + void (*recv_setup)(char *, int); +#ifdef CONFIG_USB_S5PC_DMA + void (*prepare_dma)(void * , u32 , uchar); + void (*dma_done)(int); +#endif + char *tx_data; + char *rx_data; + ulong tx_len; + ulong rx_len; + ulong ram_addr; + + /* mmc device info */ + uint mmc_dev; + uint mmc_max; + uint mmc_blk; + uint mmc_total; + + void (*set_logo)(char *, int); + void (*set_progress)(int); + void (*cpu_reset)(void); + void (*down_start)(void); + void (*down_cancel)(int); +}; + +/* This function is interfaced between USB Device Controller and USB Downloader + * Must Implementation this function at USB Controller!! */ +struct usbd_ops *usbd_set_interface(struct usbd_ops *); + +#endif /* _USBD_H_ */