15 #include <linux/module.h>
16 #include <linux/kernel.h>
20 #include <linux/slab.h>
23 #include <asm/byteorder.h>
27 #define DN_KERNEL_MAGIC_NUMBER 0x10760001
28 #define DN_ROOTFS_MAGIC_NUMBER 0x10760002
30 #define DOWNLOAD_SIZE 1024
32 #define MAX_IMG_CNT 16
33 #define FW_DIR "gdm72xx/"
34 #define FW_UIMG "gdmuimg.bin"
35 #define FW_KERN "zImage"
36 #define FW_FS "ramdisk.jffs2"
67 static void array_le32_to_cpu(
u32 *arr,
int num)
70 for (i = 0; i < num; i++, arr++)
76 static int gdm_wibro_send(
struct usb_device *usbdev,
void *
data,
int len)
81 ret =
usb_bulk_msg(usbdev, usb_sndbulkpipe(usbdev, 1), data, len,
91 static int gdm_wibro_recv(
struct usb_device *usbdev,
void *data,
int len)
96 ret =
usb_bulk_msg(usbdev, usb_rcvbulkpipe(usbdev, 2), data, len,
107 static int download_image(
struct usb_device *usbdev,
119 ret = gdm_wibro_send(usbdev, &
h,
sizeof(
h));
123 while (img_len > 0) {
130 ret = gdm_wibro_send(usbdev,
tx_buf, size);
154 "requesting firmware %s failed with error %d\n",
165 if (firm->
size <
sizeof(hdr)) {
172 array_le32_to_cpu((
u32 *)&hdr, 19);
187 for (i = 0; i < hdr.
count; i++) {
190 "Entry = %d Offset = 0x%08x "
191 "Image length = 0x%08x\n",
198 if (firm->
size <
sizeof(fw_info) + pos) {
203 memcpy(&fw_info, firm->
data + pos,
sizeof(fw_info));
205 array_le32_to_cpu((
u32 *)&fw_info, 8);
207 if ((fw_info.
id & 0xfffff000) != 0x10767000) {
215 if ((fw_info.
id & 0xffff) != pid)
224 ret = download_image(usbdev, firm, pos,
235 ret = download_image(usbdev, firm, pos, fw_info.
rootfs_len,
244 if (i == hdr.
count) {
255 #define DOWNLOAD_CHUCK 2048
256 #define KERNEL_TYPE_STRING "linux"
257 #define FS_TYPE_STRING "rootfs"
259 static int em_wait_ack(
struct usb_device *usbdev,
int send_zlp)
266 ret = gdm_wibro_send(usbdev,
NULL, 0);
272 ret = gdm_wibro_recv(usbdev, &ack,
sizeof(ack));
279 static int em_download_image(
struct usb_device *usbdev,
const char *img_name,
288 #if defined(GDM7205_PADDING)
291 const int pad_size = 0;
297 "requesting firmware %s failed with error %d\n",
308 strcpy(buf+pad_size, type_string);
309 ret = gdm_wibro_send(usbdev, buf,
strlen(type_string)+pad_size);
313 img_len = firm->
size;
320 while (img_len > 0) {
327 ret = gdm_wibro_send(usbdev, buf, len+pad_size);
335 ret = em_wait_ack(usbdev, ((len+pad_size) % 512 == 0));
340 ret = em_wait_ack(usbdev, 1);
351 static int em_fw_reset(
struct usb_device *usbdev)
356 ret = gdm_wibro_send(usbdev,
NULL, 0);
376 ret = em_fw_reset(usbdev);