示例#1
0
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;
}
示例#2
0
文件: usb_boot.c 项目: MaxChina/linux
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;
}