1. Replace file I/O of reading firmware by request_firmware().
2. Coding style clean up.

Signed-off-by: Macpaul Lin <[email protected]>
Cc: Paul Stewart <[email protected]>
Cc: Ben Chan <[email protected]>
Cc: Sage Ahn <[email protected]>
Cc: Greg Kroah-Hartman <[email protected]>
---
 drivers/staging/gdm72xx/usb_boot.c | 207 ++++++++++++++++++-------------------
 1 file changed, 99 insertions(+), 108 deletions(-)

diff --git a/drivers/staging/gdm72xx/usb_boot.c 
b/drivers/staging/gdm72xx/usb_boot.c
index e3dbd5a..e1cd017 100644
--- a/drivers/staging/gdm72xx/usb_boot.c
+++ b/drivers/staging/gdm72xx/usb_boot.c
@@ -18,25 +18,29 @@
 #include <linux/usb.h>
 #include <linux/unistd.h>
 #include <linux/slab.h>
+#include <linux/firmware.h>
 
 #include <asm/byteorder.h>
 #include "gdm_usb.h"
 #include "usb_boot.h"
 
-#define DN_KERNEL_MAGIC_NUMBER         0x10760001
-#define DN_ROOTFS_MAGIC_NUMBER         0x10760002
+#define DN_KERNEL_MAGIC_NUMBER 0x10760001
+#define DN_ROOTFS_MAGIC_NUMBER 0x10760002
 
-#define DOWNLOAD_SIZE  1024
+#define DOWNLOAD_SIZE          1024
 
-#define DH2B(x)                __cpu_to_be32(x)
-#define DL2H(x)                __le32_to_cpu(x)
+#define DH2B(x)                        __cpu_to_be32(x)
+#define DL2H(x)                        __le32_to_cpu(x)
 
-#define MIN(a, b)      ((a) > (b) ? (b) : (a))
+#define MIN(a, b)              ((a) > (b) ? (b) : (a))
 
 #define MAX_IMG_CNT            16
-#define UIMG_PATH              "/lib/firmware/gdm72xx/gdmuimg.bin"
-#define KERN_PATH              "/lib/firmware/gdm72xx/zImage"
-#define FS_PATH                        "/lib/firmware/gdm72xx/ramdisk.jffs2"
+
+#define FW_DIR                 "gdm72xx/"
+
+#define FW_UIMG                        "gdmuimg.bin"
+#define FW_KERN                        "zImage"
+#define FW_FS                  "ramdisk.jffs2"
 
 struct dn_header {
        u32     magic_num;
@@ -44,23 +48,23 @@ struct dn_header {
 };
 
 struct img_header {
-       u32             magic_code;
-       u32             count;
-       u32             len;
-       u32             offset[MAX_IMG_CNT];
+       u32     magic_code;
+       u32     count;
+       u32     len;
+       u32     offset[MAX_IMG_CNT];
        char    hostname[32];
        char    date[32];
 };
 
 struct fw_info {
-       u32             id;
-       u32             len;
-       u32             kernel_len;
-       u32             rootfs_len;
-       u32             kernel_offset;
-       u32             rootfs_offset;
-       u32             fw_ver;
-       u32             mac_ver;
+       u32     id;
+       u32     len;
+       u32     kernel_len;
+       u32     rootfs_len;
+       u32     kernel_offset;
+       u32     rootfs_offset;
+       u32     fw_ver;
+       u32     mac_ver;
        char    hostname[32];
        char    userid[16];
        char    date[32];
@@ -107,13 +111,13 @@ static int gdm_wibro_recv(struct usb_device *usbdev, void 
*data, int len)
        return 0;
 }
 
-static int download_image(struct usb_device *usbdev, struct file *filp,
-                               loff_t *pos, u32 img_len, u32 magic_num)
+static int download_image(struct usb_device *usbdev,
+                               const struct firmware *firm,
+                               loff_t pos, u32 img_len, u32 magic_num)
 {
        struct dn_header h;
        int ret = 0;
        u32 size;
-       int len, readn;
 
        size = (img_len + DOWNLOAD_SIZE - 1) & ~(DOWNLOAD_SIZE - 1);
        h.magic_num = DH2B(magic_num);
@@ -123,43 +127,43 @@ static int download_image(struct usb_device *usbdev, 
struct file *filp,
        if (ret < 0)
                goto out;
 
-       readn = 0;
-       while ((len = filp->f_op->read(filp, tx_buf, DOWNLOAD_SIZE, pos))) {
-
-               if (len < 0) {
-                       ret = -1;
+       while (img_len > 0) {
+               if (img_len > DOWNLOAD_SIZE) {
+                       memcpy(tx_buf, firm->data + pos, DOWNLOAD_SIZE);
+                       ret = gdm_wibro_send(usbdev, tx_buf, DOWNLOAD_SIZE);
+               } else { /* the last chuch of data */
+                       memcpy(tx_buf, firm->data + pos, img_len);
+                       ret = gdm_wibro_send(usbdev, tx_buf, img_len);
                        goto out;
                }
-               readn += len;
 
-               ret = gdm_wibro_send(usbdev, tx_buf, DOWNLOAD_SIZE);
+               img_len -= DOWNLOAD_SIZE;
+               pos += DOWNLOAD_SIZE;
+
                if (ret < 0)
                        goto out;
-               if (readn >= img_len)
-                       break;
        }
 
-       if (readn < img_len) {
-               printk(KERN_ERR "gdmwm: Cannot read to the requested size. "
-                       "Read = %d Requested = %d\n", readn, img_len);
-               ret = -EIO;
-       }
 out:
-
        return ret;
 }
 
 int usb_boot(struct usb_device *usbdev, u16 pid)
 {
        int i, ret = 0;
-       struct file *filp = NULL;
-       struct inode *inode = NULL;
-       static mm_segment_t fs;
        struct img_header hdr;
        struct fw_info fw_info;
        loff_t pos = 0;
-       char *img_name = UIMG_PATH;
-       int len;
+       char *img_name = FW_DIR FW_UIMG;
+       const struct firmware *firm;
+
+       ret = request_firmware(&firm, img_name, &usbdev->dev);
+       if (ret < 0) {
+               printk(KERN_ERR
+                      "requesting firmware %s failed with error %d\n",
+                       img_name, ret);
+               return ret;
+       }
 
        tx_buf = kmalloc(DOWNLOAD_SIZE, GFP_KERNEL);
        if (tx_buf == NULL) {
@@ -167,29 +171,12 @@ int usb_boot(struct usb_device *usbdev, u16 pid)
                return -ENOMEM;
        }
 
-       fs = get_fs();
-       set_fs(get_ds());
-
-       filp = filp_open(img_name, O_RDONLY | O_LARGEFILE, 0);
-       if (IS_ERR(filp)) {
-               printk(KERN_ERR "Can't find %s.\n", img_name);
-               ret = PTR_ERR(filp);
-               goto restore_fs;
-       }
-
-       inode = filp->f_dentry->d_inode;
-       if (!S_ISREG(inode->i_mode)) {
-               printk(KERN_ERR "Invalid file type: %s\n", img_name);
-               ret = -EINVAL;
-               goto out;
-       }
-
-       len = filp->f_op->read(filp, (u8 *)&hdr, sizeof(hdr), &pos);
-       if (len != sizeof(hdr)) {
+       if (firm->size < sizeof(hdr)) {
                printk(KERN_ERR "gdmwm: Cannot read the image info.\n");
                ret = -EIO;
                goto out;
        }
+       memcpy((u8 *)&hdr, firm->data, sizeof(hdr));
 
        array_le32_to_cpu((u32 *)&hdr, 19);
 #if 0
@@ -217,13 +204,12 @@ int usb_boot(struct usb_device *usbdev, u16 pid)
                }
 
                pos = hdr.offset[i];
-               len = filp->f_op->read(filp, (u8 *)&fw_info, sizeof(fw_info),
-                                       &pos);
-               if (len != sizeof(fw_info)) {
+               if (firm->size < sizeof(fw_info) + pos) {
                        printk(KERN_ERR "gdmwm: Cannot read the FW info.\n");
                        ret = -EIO;
                        goto out;
                }
+               memcpy((u8 *)&fw_info, firm->data + pos, sizeof(fw_info));
 
                array_le32_to_cpu((u32 *)&fw_info, 8);
 #if 0
@@ -239,14 +225,23 @@ int usb_boot(struct usb_device *usbdev, u16 pid)
                        continue;
 
                pos = hdr.offset[i] + fw_info.kernel_offset;
-               ret = download_image(usbdev, filp, &pos, fw_info.kernel_len,
-                               DN_KERNEL_MAGIC_NUMBER);
+               if (firm->size < fw_info.kernel_len + pos) {
+                       printk(KERN_ERR "gdmwm: Kernel FW is too small.\n");
+                       goto out;
+               }
+
+               ret = download_image(usbdev, firm, pos,
+                               fw_info.kernel_len, DN_KERNEL_MAGIC_NUMBER);
                if (ret < 0)
                        goto out;
                printk(KERN_INFO "GCT: Kernel download success.\n");
 
                pos = hdr.offset[i] + fw_info.rootfs_offset;
-               ret = download_image(usbdev, filp, &pos, fw_info.rootfs_len,
+               if (firm->size < fw_info.rootfs_len + pos) {
+                       printk(KERN_ERR "gdmwm: Filesystem FW is too small.\n");
+                       goto out;
+               }
+               ret = download_image(usbdev, firm, pos, fw_info.rootfs_len,
                                DN_ROOTFS_MAGIC_NUMBER);
                if (ret < 0)
                        goto out;
@@ -260,10 +255,8 @@ int usb_boot(struct usb_device *usbdev, u16 pid)
                ret = -EINVAL;
        }
 out:
-       filp_close(filp, NULL);
-
-restore_fs:
-       set_fs(fs);
+       release_firmware(firm);
+       firm = NULL;
        kfree(tx_buf);
        return ret;
 }
@@ -293,38 +286,27 @@ out:
        return ret;
 }
 
-static int em_download_image(struct usb_device *usbdev, char *path,
+static int em_download_image(struct usb_device *usbdev, char *img_name,
                                char *type_string)
 {
-       struct file *filp;
-       struct inode *inode;
-       static mm_segment_t fs;
        char *buf = NULL;
        loff_t pos = 0;
        int ret = 0;
-       int len, readn = 0;
+       int len = 0;
+       int img_len = 0;
+       const struct firmware *firm;
        #if defined(GDM7205_PADDING)
        const int pad_size = GDM7205_PADDING;
        #else
        const int pad_size = 0;
        #endif
 
-       fs = get_fs();
-       set_fs(get_ds());
-
-       filp = filp_open(path, O_RDONLY | O_LARGEFILE, 0);
-       if (IS_ERR(filp)) {
-               printk(KERN_ERR "Can't find %s.\n", path);
-               set_fs(fs);
-               ret = -ENOENT;
-               goto restore_fs;
-       }
-
-       inode = filp->f_dentry->d_inode;
-       if (!S_ISREG(inode->i_mode)) {
-               printk(KERN_ERR "Invalid file type: %s\n", path);
-               ret = -EINVAL;
-               goto out;
+       ret = request_firmware(&firm, img_name, &usbdev->dev);
+       if (ret < 0) {
+               printk(KERN_ERR
+                      "requesting firmware %s failed with error %d\n",
+                       img_name, ret);
+               return ret;
        }
 
        buf = kmalloc(DOWNLOAD_CHUCK + pad_size, GFP_KERNEL);
@@ -338,15 +320,25 @@ static int em_download_image(struct usb_device *usbdev, 
char *path,
        if (ret < 0)
                goto out;
 
-       while ((len = filp->f_op->read(filp, buf+pad_size, DOWNLOAD_CHUCK,
-                                       &pos))) {
-               if (len < 0) {
-                       ret = -1;
-                       goto out;
+       img_len = firm->size;
+
+       if (img_len <= 0) {
+               ret = -1;
+               goto out;
+       }
+
+       while (img_len > 0) {
+               if (img_len > DOWNLOAD_CHUCK) {
+                       memcpy(buf+pad_size, firm->data + pos, DOWNLOAD_CHUCK);
+                       ret = gdm_wibro_send(usbdev, buf, len+pad_size);
+               } else { /* the last chuch of data */
+                       memcpy(buf+pad_size, firm->data + pos, img_len);
+                       ret = gdm_wibro_send(usbdev, buf, len+pad_size);
                }
-               readn += len;
 
-               ret = gdm_wibro_send(usbdev, buf, len+pad_size);
+               img_len -= DOWNLOAD_CHUCK;
+               pos += DOWNLOAD_CHUCK;
+
                if (ret < 0)
                        goto out;
 
@@ -360,11 +352,8 @@ static int em_download_image(struct usb_device *usbdev, 
char *path,
                goto out;
 
 out:
-       filp_close(filp, NULL);
-
-restore_fs:
-       set_fs(fs);
-
+       release_firmware(firm);
+       firm = NULL;
        kfree(buf);
 
        return ret;
@@ -382,13 +371,15 @@ static int em_fw_reset(struct usb_device *usbdev)
 int usb_emergency(struct usb_device *usbdev)
 {
        int ret;
+       char *kern_name = FW_DIR FW_KERN;
+       char *fs_name = FW_DIR FW_FS;
 
-       ret = em_download_image(usbdev, KERN_PATH, KERNEL_TYPE_STRING);
+       ret = em_download_image(usbdev, kern_name, KERNEL_TYPE_STRING);
        if (ret < 0)
                goto out;
        printk(KERN_INFO "GCT Emergency: Kernel download success.\n");
 
-       ret = em_download_image(usbdev, FS_PATH, FS_TYPE_STRING);
+       ret = em_download_image(usbdev, fs_name, FS_TYPE_STRING);
        if (ret < 0)
                goto out;
        printk(KERN_INFO "GCT Emergency: Filesystem download success.\n");
-- 
1.7.11.2.138.g2b53359

_______________________________________________
devel mailing list
[email protected]
http://driverdev.linuxdriverproject.org/mailman/listinfo/devel

Reply via email to