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; size = ALIGN(img_len, DOWNLOAD_SIZE); h.magic_num = __cpu_to_be32(magic_num); h.file_size = __cpu_to_be32(size); ret = gdm_wibro_send(usbdev, &h, sizeof(h)); if (ret < 0) return ret; while (img_len > 0) { if (img_len > DOWNLOAD_SIZE) size = DOWNLOAD_SIZE; else size = img_len; /* the last chunk of data */ memcpy(tx_buf, firm->data + pos, size); ret = gdm_wibro_send(usbdev, tx_buf, size); if (ret < 0) return ret; img_len -= size; pos += size; } return ret; }
static int em_fw_reset(struct usb_device *usbdev) { int ret; /*Send ZLP*/ ret = gdm_wibro_send(usbdev, NULL, 0); return ret; }
static int download_image(struct usb_device *usbdev, struct file *filp, 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); h.file_size = DH2B(size); ret = gdm_wibro_send(usbdev, &h, sizeof(h)); if (ret < 0) goto out; readn = 0; while ((len = filp->f_op->read(filp, tx_buf, DOWNLOAD_SIZE, pos))) { if (len < 0) { ret = -1; goto out; } readn += len; ret = gdm_wibro_send(usbdev, tx_buf, 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; }
static int em_wait_ack(struct usb_device *usbdev, int send_zlp) { int ack; int ret = -1; if (send_zlp) { /*Send ZLP*/ ret = gdm_wibro_send(usbdev, NULL, 0); if (ret < 0) goto out; } /*Wait for ACK*/ ret = gdm_wibro_recv(usbdev, &ack, sizeof(ack)); if (ret < 0) goto out; out: return ret; }
static int em_download_image(struct usb_device *usbdev, char *path, 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; #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; } if (filp->f_dentry) { inode = filp->f_dentry->d_inode; if (!inode || !S_ISREG(inode->i_mode)) { printk(KERN_ERR "Invalid file type: %s\n", path); ret = -EINVAL; goto out; } } buf = (u8 *)kmalloc(DOWNLOAD_CHUCK + pad_size, GFP_KERNEL); if (buf == NULL) { printk(KERN_ERR "Error: kmalloc\n"); return -ENOMEM; } strcpy(buf+pad_size, type_string); ret = gdm_wibro_send(usbdev, buf, strlen(type_string)+pad_size); 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; } readn += len; ret = gdm_wibro_send(usbdev, buf, len+pad_size); if (ret < 0) goto out; ret = em_wait_ack(usbdev, ((len+pad_size) % 512 == 0)); if (ret < 0) goto out; } ret = em_wait_ack(usbdev, 1); if (ret < 0) goto out; out: filp_close(filp, current->files); restore_fs: set_fs(fs); if (buf) kfree(buf); return ret; }
static int em_download_image(struct usb_device *usbdev, const char *img_name, char *type_string) { char *buf = NULL; loff_t pos = 0; int ret = 0; int len; int img_len; const struct firmware *firm; #if defined(GDM7205_PADDING) const int pad_size = GDM7205_PADDING; #else const int pad_size = 0; #endif ret = request_firmware(&firm, img_name, &usbdev->dev); if (ret < 0) { dev_err(&usbdev->dev, "requesting firmware %s failed with error %d\n", img_name, ret); return ret; } buf = kmalloc(DOWNLOAD_CHUCK + pad_size, GFP_KERNEL); if (buf == NULL) return -ENOMEM; strcpy(buf+pad_size, type_string); ret = gdm_wibro_send(usbdev, buf, strlen(type_string)+pad_size); if (ret < 0) goto out; img_len = firm->size; if (img_len <= 0) { ret = -1; goto out; } while (img_len > 0) { if (img_len > DOWNLOAD_CHUCK) len = DOWNLOAD_CHUCK; else len = img_len; /* the last chunk of data */ memcpy(buf+pad_size, firm->data + pos, len); ret = gdm_wibro_send(usbdev, buf, len+pad_size); if (ret < 0) goto out; img_len -= DOWNLOAD_CHUCK; pos += DOWNLOAD_CHUCK; ret = em_wait_ack(usbdev, ((len+pad_size) % 512 == 0)); if (ret < 0) goto out; } ret = em_wait_ack(usbdev, 1); if (ret < 0) goto out; out: release_firmware(firm); kfree(buf); return ret; }