Merge branch 'master' of git://www.denx.de/git/u-boot-usb
This commit is contained in:
		
						commit
						15c5cdf5aa
					
				
							
								
								
									
										7
									
								
								README
								
								
								
								
							
							
						
						
									
										7
									
								
								README
								
								
								
								
							|  | @ -1367,6 +1367,13 @@ The following options need to be configured: | ||||||
| 			for your device | 			for your device | ||||||
| 			- CONFIG_USBD_PRODUCTID 0xFFFF | 			- CONFIG_USBD_PRODUCTID 0xFFFF | ||||||
| 
 | 
 | ||||||
|  | 		Some USB device drivers may need to check USB cable attachment. | ||||||
|  | 		In this case you can enable following config in BoardName.h: | ||||||
|  | 			CONFIG_USB_CABLE_CHECK | ||||||
|  | 			This enables function definition: | ||||||
|  | 			- usb_cable_connected() in include/usb.h | ||||||
|  | 			Implementation of this function is board-specific. | ||||||
|  | 
 | ||||||
| - ULPI Layer Support: | - ULPI Layer Support: | ||||||
| 		The ULPI (UTMI Low Pin (count) Interface) PHYs are supported via | 		The ULPI (UTMI Low Pin (count) Interface) PHYs are supported via | ||||||
| 		the generic ULPI layer. The generic layer accesses the ULPI PHY | 		the generic ULPI layer. The generic layer accesses the ULPI PHY | ||||||
|  |  | ||||||
|  | @ -7,3 +7,4 @@ | ||||||
| 
 | 
 | ||||||
| obj-$(CONFIG_SOFT_I2C_MULTI_BUS) += multi_i2c.o | obj-$(CONFIG_SOFT_I2C_MULTI_BUS) += multi_i2c.o | ||||||
| obj-$(CONFIG_THOR_FUNCTION) += thor.o | obj-$(CONFIG_THOR_FUNCTION) += thor.o | ||||||
|  | obj-$(CONFIG_CMD_USB_MASS_STORAGE) += ums.o | ||||||
|  |  | ||||||
|  | @ -0,0 +1,76 @@ | ||||||
|  | /*
 | ||||||
|  |  * Copyright (C) 2013 Samsung Electronics | ||||||
|  |  * Lukasz Majewski <l.majewski@samsung.com> | ||||||
|  |  * | ||||||
|  |  * SPDX-License-Identifier:	GPL-2.0+ | ||||||
|  |  */ | ||||||
|  | 
 | ||||||
|  | #include <common.h> | ||||||
|  | #include <usb_mass_storage.h> | ||||||
|  | #include <part.h> | ||||||
|  | 
 | ||||||
|  | static int ums_read_sector(struct ums *ums_dev, | ||||||
|  | 			   ulong start, lbaint_t blkcnt, void *buf) | ||||||
|  | { | ||||||
|  | 	block_dev_desc_t *block_dev = &ums_dev->mmc->block_dev; | ||||||
|  | 	lbaint_t blkstart = start + ums_dev->start_sector; | ||||||
|  | 	int dev_num = block_dev->dev; | ||||||
|  | 
 | ||||||
|  | 	return block_dev->block_read(dev_num, blkstart, blkcnt, buf); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | static int ums_write_sector(struct ums *ums_dev, | ||||||
|  | 			    ulong start, lbaint_t blkcnt, const void *buf) | ||||||
|  | { | ||||||
|  | 	block_dev_desc_t *block_dev = &ums_dev->mmc->block_dev; | ||||||
|  | 	lbaint_t blkstart = start + ums_dev->start_sector; | ||||||
|  | 	int dev_num = block_dev->dev; | ||||||
|  | 
 | ||||||
|  | 	return block_dev->block_write(dev_num, blkstart, blkcnt, buf); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | static struct ums ums_dev = { | ||||||
|  | 	.read_sector = ums_read_sector, | ||||||
|  | 	.write_sector = ums_write_sector, | ||||||
|  | 	.name = "UMS disk", | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | static struct ums *ums_disk_init(struct mmc *mmc) | ||||||
|  | { | ||||||
|  | 	uint64_t mmc_end_sector = mmc->capacity / SECTOR_SIZE; | ||||||
|  | 	uint64_t ums_end_sector = UMS_NUM_SECTORS + UMS_START_SECTOR; | ||||||
|  | 
 | ||||||
|  | 	if (!mmc_end_sector) { | ||||||
|  | 		error("MMC capacity is not valid"); | ||||||
|  | 		return NULL; | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	ums_dev.mmc = mmc; | ||||||
|  | 
 | ||||||
|  | 	if (ums_end_sector <= mmc_end_sector) { | ||||||
|  | 		ums_dev.start_sector = UMS_START_SECTOR; | ||||||
|  | 		if (UMS_NUM_SECTORS) | ||||||
|  | 			ums_dev.num_sectors = UMS_NUM_SECTORS; | ||||||
|  | 		else | ||||||
|  | 			ums_dev.num_sectors = mmc_end_sector - UMS_START_SECTOR; | ||||||
|  | 	} else { | ||||||
|  | 		ums_dev.num_sectors = mmc_end_sector; | ||||||
|  | 		puts("UMS: defined bad disk parameters. Using default.\n"); | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	printf("UMS: disk start sector: %#x, count: %#x\n", | ||||||
|  | 	       ums_dev.start_sector, ums_dev.num_sectors); | ||||||
|  | 
 | ||||||
|  | 	return &ums_dev; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | struct ums *ums_init(unsigned int dev_num) | ||||||
|  | { | ||||||
|  | 	struct mmc *mmc = NULL; | ||||||
|  | 
 | ||||||
|  | 	mmc = find_mmc_device(dev_num); | ||||||
|  | 	if (!mmc) | ||||||
|  | 		return NULL; | ||||||
|  | 
 | ||||||
|  | 	return ums_disk_init(mmc); | ||||||
|  | } | ||||||
|  | @ -772,65 +772,3 @@ void init_panel_info(vidinfo_t *vid) | ||||||
| 
 | 
 | ||||||
| 	setenv("lcdinfo", "lcd=s6e8ax0"); | 	setenv("lcdinfo", "lcd=s6e8ax0"); | ||||||
| } | } | ||||||
| 
 |  | ||||||
| #ifdef CONFIG_USB_GADGET_MASS_STORAGE |  | ||||||
| static int ums_read_sector(struct ums_device *ums_dev, |  | ||||||
| 			   ulong start, lbaint_t blkcnt, void *buf) |  | ||||||
| { |  | ||||||
| 	if (ums_dev->mmc->block_dev.block_read(ums_dev->dev_num, |  | ||||||
| 			start + ums_dev->offset, blkcnt, buf) != blkcnt) |  | ||||||
| 		return -1; |  | ||||||
| 
 |  | ||||||
| 	return 0; |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| static int ums_write_sector(struct ums_device *ums_dev, |  | ||||||
| 			    ulong start, lbaint_t blkcnt, const void *buf) |  | ||||||
| { |  | ||||||
| 	if (ums_dev->mmc->block_dev.block_write(ums_dev->dev_num, |  | ||||||
| 			start + ums_dev->offset, blkcnt, buf) != blkcnt) |  | ||||||
| 		return -1; |  | ||||||
| 
 |  | ||||||
| 	return 0; |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| static void ums_get_capacity(struct ums_device *ums_dev, |  | ||||||
| 			     long long int *capacity) |  | ||||||
| { |  | ||||||
| 	long long int tmp_capacity; |  | ||||||
| 
 |  | ||||||
| 	tmp_capacity = (long long int) ((ums_dev->offset + ums_dev->part_size) |  | ||||||
| 					* SECTOR_SIZE); |  | ||||||
| 	*capacity = ums_dev->mmc->capacity - tmp_capacity; |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| static struct ums_board_info ums_board = { |  | ||||||
| 	.read_sector = ums_read_sector, |  | ||||||
| 	.write_sector = ums_write_sector, |  | ||||||
| 	.get_capacity = ums_get_capacity, |  | ||||||
| 	.name = "TRATS UMS disk", |  | ||||||
| 	.ums_dev = { |  | ||||||
| 		.mmc = NULL, |  | ||||||
| 		.dev_num = 0, |  | ||||||
| 		.offset = 0, |  | ||||||
| 		.part_size = 0. |  | ||||||
| 	}, |  | ||||||
| }; |  | ||||||
| 
 |  | ||||||
| struct ums_board_info *board_ums_init(unsigned int dev_num, unsigned int offset, |  | ||||||
| 				      unsigned int part_size) |  | ||||||
| { |  | ||||||
| 	struct mmc *mmc; |  | ||||||
| 
 |  | ||||||
| 	mmc = find_mmc_device(dev_num); |  | ||||||
| 	if (!mmc) |  | ||||||
| 		return NULL; |  | ||||||
| 
 |  | ||||||
| 	ums_board.ums_dev.mmc = mmc; |  | ||||||
| 	ums_board.ums_dev.dev_num = dev_num; |  | ||||||
| 	ums_board.ums_dev.offset = offset; |  | ||||||
| 	ums_board.ums_dev.part_size = part_size; |  | ||||||
| 
 |  | ||||||
| 	return &ums_board; |  | ||||||
| } |  | ||||||
| #endif |  | ||||||
|  |  | ||||||
|  | @ -5,6 +5,7 @@ | ||||||
|  * SPDX-License-Identifier:	GPL-2.0+ |  * SPDX-License-Identifier:	GPL-2.0+ | ||||||
|  */ |  */ | ||||||
| 
 | 
 | ||||||
|  | #include <errno.h> | ||||||
| #include <common.h> | #include <common.h> | ||||||
| #include <command.h> | #include <command.h> | ||||||
| #include <g_dnl.h> | #include <g_dnl.h> | ||||||
|  | @ -20,55 +21,49 @@ int do_usb_mass_storage(cmd_tbl_t *cmdtp, int flag, | ||||||
| 	const char *usb_controller = argv[1]; | 	const char *usb_controller = argv[1]; | ||||||
| 	const char *mmc_devstring  = argv[2]; | 	const char *mmc_devstring  = argv[2]; | ||||||
| 
 | 
 | ||||||
| 	unsigned int dev_num = (unsigned int)(simple_strtoul(mmc_devstring, | 	unsigned int dev_num = simple_strtoul(mmc_devstring, NULL, 0); | ||||||
| 				NULL, 0)); | 
 | ||||||
| 	if (dev_num) { | 	struct ums *ums = ums_init(dev_num); | ||||||
| 		error("Set eMMC device to 0! - e.g. ums 0"); | 	if (!ums) | ||||||
| 		goto fail; | 		return CMD_RET_FAILURE; | ||||||
| 	} |  | ||||||
| 
 | 
 | ||||||
| 	unsigned int controller_index = (unsigned int)(simple_strtoul( | 	unsigned int controller_index = (unsigned int)(simple_strtoul( | ||||||
| 					usb_controller,	NULL, 0)); | 					usb_controller,	NULL, 0)); | ||||||
| 	if (board_usb_init(controller_index, USB_INIT_DEVICE)) { | 	if (board_usb_init(controller_index, USB_INIT_DEVICE)) { | ||||||
| 		error("Couldn't init USB controller."); | 		error("Couldn't init USB controller."); | ||||||
| 		goto fail; | 		return CMD_RET_FAILURE; | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	struct ums_board_info *ums_info = board_ums_init(dev_num, 0, 0); | 	int rc = fsg_init(ums); | ||||||
| 	if (!ums_info) { |  | ||||||
| 		error("MMC: %d -> NOT available", dev_num); |  | ||||||
| 		goto fail; |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	int rc = fsg_init(ums_info); |  | ||||||
| 	if (rc) { | 	if (rc) { | ||||||
| 		error("fsg_init failed"); | 		error("fsg_init failed"); | ||||||
| 		goto fail; | 		return CMD_RET_FAILURE; | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	g_dnl_register("ums"); | 	g_dnl_register("ums"); | ||||||
| 
 | 
 | ||||||
| 	while (1) { | 	while (1) { | ||||||
| 		/* Handle control-c and timeouts */ | 		usb_gadget_handle_interrupts(); | ||||||
| 		if (ctrlc()) { | 
 | ||||||
| 			error("The remote end did not respond in time."); | 		rc = fsg_main_thread(NULL); | ||||||
|  | 		if (rc) { | ||||||
|  | 			/* Check I/O error */ | ||||||
|  | 			if (rc == -EIO) | ||||||
|  | 				printf("\rCheck USB cable connection\n"); | ||||||
|  | 
 | ||||||
|  | 			/* Check CTRL+C */ | ||||||
|  | 			if (rc == -EPIPE) | ||||||
|  | 				printf("\rCTRL+C - Operation aborted\n"); | ||||||
|  | 
 | ||||||
| 			goto exit; | 			goto exit; | ||||||
| 		} | 		} | ||||||
| 
 |  | ||||||
| 		usb_gadget_handle_interrupts(); |  | ||||||
| 		/* Check if USB cable has been detached */ |  | ||||||
| 		if (fsg_main_thread(NULL) == EIO) |  | ||||||
| 			goto exit; |  | ||||||
| 	} | 	} | ||||||
| exit: | exit: | ||||||
| 	g_dnl_unregister(); | 	g_dnl_unregister(); | ||||||
| 	return 0; | 	return CMD_RET_SUCCESS; | ||||||
| 
 |  | ||||||
| fail: |  | ||||||
| 	return -1; |  | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| U_BOOT_CMD(ums, CONFIG_SYS_MAXARGS, 1, do_usb_mass_storage, | U_BOOT_CMD(ums, CONFIG_SYS_MAXARGS, 1, do_usb_mass_storage, | ||||||
| 	"Use the UMS [User Mass Storage]", | 	"Use the UMS [User Mass Storage]", | ||||||
| 	"<USB_controller> <mmc_dev>" | 	"ums <USB_controller> <mmc_dev>  e.g. ums 0 0" | ||||||
| ); | ); | ||||||
|  |  | ||||||
|  | @ -229,6 +229,7 @@ static int dfu_read_buffer_fill(struct dfu_entity *dfu, void *buf, int size) | ||||||
| 			dfu->crc = crc32(dfu->crc, buf, chunk); | 			dfu->crc = crc32(dfu->crc, buf, chunk); | ||||||
| 			dfu->i_buf += chunk; | 			dfu->i_buf += chunk; | ||||||
| 			dfu->b_left -= chunk; | 			dfu->b_left -= chunk; | ||||||
|  | 			dfu->r_left -= chunk; | ||||||
| 			size -= chunk; | 			size -= chunk; | ||||||
| 			buf += chunk; | 			buf += chunk; | ||||||
| 			readn += chunk; | 			readn += chunk; | ||||||
|  | @ -287,7 +288,7 @@ int dfu_read(struct dfu_entity *dfu, void *buf, int size, int blk_seq_num) | ||||||
| 		dfu->offset = 0; | 		dfu->offset = 0; | ||||||
| 		dfu->i_buf_end = dfu_get_buf() + dfu_buf_size; | 		dfu->i_buf_end = dfu_get_buf() + dfu_buf_size; | ||||||
| 		dfu->i_buf = dfu->i_buf_start; | 		dfu->i_buf = dfu->i_buf_start; | ||||||
| 		dfu->b_left = 0; | 		dfu->b_left = min(dfu_buf_size, dfu->r_left); | ||||||
| 
 | 
 | ||||||
| 		dfu->bad_skip = 0; | 		dfu->bad_skip = 0; | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -121,6 +121,7 @@ static int dfu_read_medium_nand(struct dfu_entity *dfu, u64 offset, void *buf, | ||||||
| 
 | 
 | ||||||
| 	switch (dfu->layout) { | 	switch (dfu->layout) { | ||||||
| 	case DFU_RAW_ADDR: | 	case DFU_RAW_ADDR: | ||||||
|  | 		*len = dfu->data.nand.size; | ||||||
| 		ret = nand_block_read(dfu, offset, buf, len); | 		ret = nand_block_read(dfu, offset, buf, len); | ||||||
| 		break; | 		break; | ||||||
| 	default: | 	default: | ||||||
|  |  | ||||||
|  | @ -243,6 +243,7 @@ | ||||||
| #include <config.h> | #include <config.h> | ||||||
| #include <malloc.h> | #include <malloc.h> | ||||||
| #include <common.h> | #include <common.h> | ||||||
|  | #include <usb.h> | ||||||
| 
 | 
 | ||||||
| #include <linux/err.h> | #include <linux/err.h> | ||||||
| #include <linux/usb/ch9.h> | #include <linux/usb/ch9.h> | ||||||
|  | @ -441,7 +442,7 @@ static void set_bulk_out_req_length(struct fsg_common *common, | ||||||
| 
 | 
 | ||||||
| /*-------------------------------------------------------------------------*/ | /*-------------------------------------------------------------------------*/ | ||||||
| 
 | 
 | ||||||
| struct ums_board_info			*ums_info; | struct ums *ums; | ||||||
| struct fsg_common *the_fsg_common; | struct fsg_common *the_fsg_common; | ||||||
| 
 | 
 | ||||||
| static int fsg_set_halt(struct fsg_dev *fsg, struct usb_ep *ep) | static int fsg_set_halt(struct fsg_dev *fsg, struct usb_ep *ep) | ||||||
|  | @ -675,6 +676,18 @@ static int sleep_thread(struct fsg_common *common) | ||||||
| 			k++; | 			k++; | ||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
|  | 		if (k == 10) { | ||||||
|  | 			/* Handle CTRL+C */ | ||||||
|  | 			if (ctrlc()) | ||||||
|  | 				return -EPIPE; | ||||||
|  | #ifdef CONFIG_USB_CABLE_CHECK | ||||||
|  | 			/* Check cable connection */ | ||||||
|  | 			if (!usb_cable_connected()) | ||||||
|  | 				return -EIO; | ||||||
|  | #endif | ||||||
|  | 			k = 0; | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
| 		usb_gadget_handle_interrupts(); | 		usb_gadget_handle_interrupts(); | ||||||
| 	} | 	} | ||||||
| 	common->thread_wakeup_needed = 0; | 	common->thread_wakeup_needed = 0; | ||||||
|  | @ -757,14 +770,14 @@ static int do_read(struct fsg_common *common) | ||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
| 		/* Perform the read */ | 		/* Perform the read */ | ||||||
| 		nread = 0; | 		rc = ums->read_sector(ums, | ||||||
| 		rc = ums_info->read_sector(&(ums_info->ums_dev), |  | ||||||
| 				      file_offset / SECTOR_SIZE, | 				      file_offset / SECTOR_SIZE, | ||||||
| 				      amount / SECTOR_SIZE, | 				      amount / SECTOR_SIZE, | ||||||
| 				      (char __user *)bh->buf); | 				      (char __user *)bh->buf); | ||||||
| 		if (rc) | 		if (!rc) | ||||||
| 			return -EIO; | 			return -EIO; | ||||||
| 		nread = amount; | 
 | ||||||
|  | 		nread = rc * SECTOR_SIZE; | ||||||
| 
 | 
 | ||||||
| 		VLDBG(curlun, "file read %u @ %llu -> %d\n", amount, | 		VLDBG(curlun, "file read %u @ %llu -> %d\n", amount, | ||||||
| 				(unsigned long long) file_offset, | 				(unsigned long long) file_offset, | ||||||
|  | @ -931,13 +944,13 @@ static int do_write(struct fsg_common *common) | ||||||
| 			amount = bh->outreq->actual; | 			amount = bh->outreq->actual; | ||||||
| 
 | 
 | ||||||
| 			/* Perform the write */ | 			/* Perform the write */ | ||||||
| 			rc = ums_info->write_sector(&(ums_info->ums_dev), | 			rc = ums->write_sector(ums, | ||||||
| 					       file_offset / SECTOR_SIZE, | 					       file_offset / SECTOR_SIZE, | ||||||
| 					       amount / SECTOR_SIZE, | 					       amount / SECTOR_SIZE, | ||||||
| 					       (char __user *)bh->buf); | 					       (char __user *)bh->buf); | ||||||
| 			if (rc) | 			if (!rc) | ||||||
| 				return -EIO; | 				return -EIO; | ||||||
| 			nwritten = amount; | 			nwritten = rc * SECTOR_SIZE; | ||||||
| 
 | 
 | ||||||
| 			VLDBG(curlun, "file write %u @ %llu -> %d\n", amount, | 			VLDBG(curlun, "file write %u @ %llu -> %d\n", amount, | ||||||
| 					(unsigned long long) file_offset, | 					(unsigned long long) file_offset, | ||||||
|  | @ -959,6 +972,8 @@ static int do_write(struct fsg_common *common) | ||||||
| 
 | 
 | ||||||
| 			/* If an error occurred, report it and its position */ | 			/* If an error occurred, report it and its position */ | ||||||
| 			if (nwritten < amount) { | 			if (nwritten < amount) { | ||||||
|  | 				printf("nwritten:%d amount:%d\n", nwritten, | ||||||
|  | 				       amount); | ||||||
| 				curlun->sense_data = SS_WRITE_ERROR; | 				curlun->sense_data = SS_WRITE_ERROR; | ||||||
| 				curlun->info_valid = 1; | 				curlun->info_valid = 1; | ||||||
| 				break; | 				break; | ||||||
|  | @ -1045,14 +1060,13 @@ static int do_verify(struct fsg_common *common) | ||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
| 		/* Perform the read */ | 		/* Perform the read */ | ||||||
| 		nread = 0; | 		rc = ums->read_sector(ums, | ||||||
| 		rc = ums_info->read_sector(&(ums_info->ums_dev), |  | ||||||
| 				      file_offset / SECTOR_SIZE, | 				      file_offset / SECTOR_SIZE, | ||||||
| 				      amount / SECTOR_SIZE, | 				      amount / SECTOR_SIZE, | ||||||
| 				      (char __user *)bh->buf); | 				      (char __user *)bh->buf); | ||||||
| 		if (rc) | 		if (!rc) | ||||||
| 			return -EIO; | 			return -EIO; | ||||||
| 		nread = amount; | 		nread = rc * SECTOR_SIZE; | ||||||
| 
 | 
 | ||||||
| 		VLDBG(curlun, "file read %u @ %llu -> %d\n", amount, | 		VLDBG(curlun, "file read %u @ %llu -> %d\n", amount, | ||||||
| 				(unsigned long long) file_offset, | 				(unsigned long long) file_offset, | ||||||
|  | @ -1100,7 +1114,7 @@ static int do_inquiry(struct fsg_common *common, struct fsg_buffhd *bh) | ||||||
| 	buf[4] = 31;		/* Additional length */ | 	buf[4] = 31;		/* Additional length */ | ||||||
| 				/* No special options */ | 				/* No special options */ | ||||||
| 	sprintf((char *) (buf + 8), "%-8s%-16s%04x", (char*) vendor_id , | 	sprintf((char *) (buf + 8), "%-8s%-16s%04x", (char*) vendor_id , | ||||||
| 			ums_info->name, (u16) 0xffff); | 			ums->name, (u16) 0xffff); | ||||||
| 
 | 
 | ||||||
| 	return 36; | 	return 36; | ||||||
| } | } | ||||||
|  | @ -2386,6 +2400,7 @@ static void handle_exception(struct fsg_common *common) | ||||||
| 
 | 
 | ||||||
| int fsg_main_thread(void *common_) | int fsg_main_thread(void *common_) | ||||||
| { | { | ||||||
|  | 	int ret; | ||||||
| 	struct fsg_common	*common = the_fsg_common; | 	struct fsg_common	*common = the_fsg_common; | ||||||
| 	/* The main loop */ | 	/* The main loop */ | ||||||
| 	do { | 	do { | ||||||
|  | @ -2395,12 +2410,16 @@ int fsg_main_thread(void *common_) | ||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
| 		if (!common->running) { | 		if (!common->running) { | ||||||
| 			sleep_thread(common); | 			ret = sleep_thread(common); | ||||||
|  | 			if (ret) | ||||||
|  | 				return ret; | ||||||
|  | 
 | ||||||
| 			continue; | 			continue; | ||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
| 		if (get_next_command(common)) | 		ret = get_next_command(common); | ||||||
| 			continue; | 		if (ret) | ||||||
|  | 			return ret; | ||||||
| 
 | 
 | ||||||
| 		if (!exception_in_progress(common)) | 		if (!exception_in_progress(common)) | ||||||
| 			common->state = FSG_STATE_DATA_PHASE; | 			common->state = FSG_STATE_DATA_PHASE; | ||||||
|  | @ -2753,9 +2772,9 @@ int fsg_add(struct usb_configuration *c) | ||||||
| 	return fsg_bind_config(c->cdev, c, fsg_common); | 	return fsg_bind_config(c->cdev, c, fsg_common); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| int fsg_init(struct ums_board_info *ums) | int fsg_init(struct ums *ums_dev) | ||||||
| { | { | ||||||
| 	ums_info = ums; | 	ums = ums_dev; | ||||||
| 
 | 
 | ||||||
| 	return 0; | 	return 0; | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -33,6 +33,9 @@ | ||||||
| #define STRING_PRODUCT 2 | #define STRING_PRODUCT 2 | ||||||
| /* Index of String Descriptor describing this configuration */ | /* Index of String Descriptor describing this configuration */ | ||||||
| #define STRING_USBDOWN 2 | #define STRING_USBDOWN 2 | ||||||
|  | /* Index of String serial */ | ||||||
|  | #define STRING_SERIAL  3 | ||||||
|  | #define MAX_STRING_SERIAL	32 | ||||||
| /* Number of supported configurations */ | /* Number of supported configurations */ | ||||||
| #define CONFIGURATION_NUMBER 1 | #define CONFIGURATION_NUMBER 1 | ||||||
| 
 | 
 | ||||||
|  | @ -40,8 +43,16 @@ | ||||||
| 
 | 
 | ||||||
| static const char shortname[] = "usb_dnl_"; | static const char shortname[] = "usb_dnl_"; | ||||||
| static const char product[] = "USB download gadget"; | static const char product[] = "USB download gadget"; | ||||||
|  | static char g_dnl_serial[MAX_STRING_SERIAL]; | ||||||
| static const char manufacturer[] = CONFIG_G_DNL_MANUFACTURER; | static const char manufacturer[] = CONFIG_G_DNL_MANUFACTURER; | ||||||
| 
 | 
 | ||||||
|  | void g_dnl_set_serialnumber(char *s) | ||||||
|  | { | ||||||
|  | 	memset(g_dnl_serial, 0, MAX_STRING_SERIAL); | ||||||
|  | 	if (strlen(s) < MAX_STRING_SERIAL) | ||||||
|  | 		strncpy(g_dnl_serial, s, strlen(s)); | ||||||
|  | } | ||||||
|  | 
 | ||||||
| static struct usb_device_descriptor device_desc = { | static struct usb_device_descriptor device_desc = { | ||||||
| 	.bLength = sizeof device_desc, | 	.bLength = sizeof device_desc, | ||||||
| 	.bDescriptorType = USB_DT_DEVICE, | 	.bDescriptorType = USB_DT_DEVICE, | ||||||
|  | @ -53,6 +64,7 @@ static struct usb_device_descriptor device_desc = { | ||||||
| 	.idVendor = __constant_cpu_to_le16(CONFIG_G_DNL_VENDOR_NUM), | 	.idVendor = __constant_cpu_to_le16(CONFIG_G_DNL_VENDOR_NUM), | ||||||
| 	.idProduct = __constant_cpu_to_le16(CONFIG_G_DNL_PRODUCT_NUM), | 	.idProduct = __constant_cpu_to_le16(CONFIG_G_DNL_PRODUCT_NUM), | ||||||
| 	.iProduct = STRING_PRODUCT, | 	.iProduct = STRING_PRODUCT, | ||||||
|  | 	.iSerialNumber = STRING_SERIAL, | ||||||
| 	.bNumConfigurations = 1, | 	.bNumConfigurations = 1, | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
|  | @ -63,6 +75,7 @@ static struct usb_device_descriptor device_desc = { | ||||||
| static struct usb_string g_dnl_string_defs[] = { | static struct usb_string g_dnl_string_defs[] = { | ||||||
| 	{.s = manufacturer}, | 	{.s = manufacturer}, | ||||||
| 	{.s = product}, | 	{.s = product}, | ||||||
|  | 	{.s = g_dnl_serial}, | ||||||
| 	{ }		/* end of list */ | 	{ }		/* end of list */ | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
|  | @ -156,6 +169,13 @@ static int g_dnl_bind(struct usb_composite_dev *cdev) | ||||||
| 	g_dnl_string_defs[1].id = id; | 	g_dnl_string_defs[1].id = id; | ||||||
| 	device_desc.iProduct = id; | 	device_desc.iProduct = id; | ||||||
| 
 | 
 | ||||||
|  | 	id = usb_string_id(cdev); | ||||||
|  | 	if (id < 0) | ||||||
|  | 		return id; | ||||||
|  | 
 | ||||||
|  | 	g_dnl_string_defs[2].id = id; | ||||||
|  | 	device_desc.iSerialNumber = id; | ||||||
|  | 
 | ||||||
| 	g_dnl_bind_fixup(&device_desc, cdev->driver->name); | 	g_dnl_bind_fixup(&device_desc, cdev->driver->name); | ||||||
| 	ret = g_dnl_config_register(cdev); | 	ret = g_dnl_config_register(cdev); | ||||||
| 	if (ret) | 	if (ret) | ||||||
|  |  | ||||||
|  | @ -275,7 +275,6 @@ struct rw_semaphore { int i; }; | ||||||
| #define ETOOSMALL	525 | #define ETOOSMALL	525 | ||||||
| 
 | 
 | ||||||
| #include <usb_mass_storage.h> | #include <usb_mass_storage.h> | ||||||
| extern struct ums_board_info		*ums_info; |  | ||||||
| 
 | 
 | ||||||
| /*-------------------------------------------------------------------------*/ | /*-------------------------------------------------------------------------*/ | ||||||
| 
 | 
 | ||||||
|  | @ -573,36 +572,16 @@ static struct usb_gadget_strings	fsg_stringtab = { | ||||||
| static int fsg_lun_open(struct fsg_lun *curlun, const char *filename) | static int fsg_lun_open(struct fsg_lun *curlun, const char *filename) | ||||||
| { | { | ||||||
| 	int				ro; | 	int				ro; | ||||||
| 	int				rc = -EINVAL; |  | ||||||
| 	loff_t				size; |  | ||||||
| 	loff_t				num_sectors; |  | ||||||
| 	loff_t				min_sectors; |  | ||||||
| 
 | 
 | ||||||
| 	/* R/W if we can, R/O if we must */ | 	/* R/W if we can, R/O if we must */ | ||||||
| 	ro = curlun->initially_ro; | 	ro = curlun->initially_ro; | ||||||
| 
 | 
 | ||||||
| 	ums_info->get_capacity(&(ums_info->ums_dev), &size); |  | ||||||
| 	if (size < 0) { |  | ||||||
| 		printf("unable to find file size: %s\n", filename); |  | ||||||
| 		rc = (int) size; |  | ||||||
| 		goto out; |  | ||||||
| 	} |  | ||||||
| 	num_sectors = size >> 9;	/* File size in 512-byte blocks */ |  | ||||||
| 	min_sectors = 1; |  | ||||||
| 	if (num_sectors < min_sectors) { |  | ||||||
| 		printf("file too small: %s\n", filename); |  | ||||||
| 		rc = -ETOOSMALL; |  | ||||||
| 		goto out; |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	curlun->ro = ro; | 	curlun->ro = ro; | ||||||
| 	curlun->file_length = size; | 	curlun->file_length = ums->num_sectors << 9; | ||||||
| 	curlun->num_sectors = num_sectors; | 	curlun->num_sectors = ums->num_sectors; | ||||||
| 	debug("open backing file: %s\n", filename); | 	debug("open backing file: %s\n", filename); | ||||||
| 	rc = 0; |  | ||||||
| 
 | 
 | ||||||
| out: | 	return 0; | ||||||
| 	return rc; |  | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| static void fsg_lun_close(struct fsg_lun *curlun) | static void fsg_lun_close(struct fsg_lun *curlun) | ||||||
|  |  | ||||||
|  | @ -1548,7 +1548,7 @@ int submit_common_msg(struct usb_device *dev, unsigned long pipe, void *buffer, | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	dev->status = stat; | 	dev->status = stat; | ||||||
| 	dev->act_len = transfer_len; | 	dev->act_len = urb->actual_length; | ||||||
| 
 | 
 | ||||||
| #ifdef DEBUG | #ifdef DEBUG | ||||||
| 	pkt_print(urb, dev, pipe, buffer, transfer_len, | 	pkt_print(urb, dev, pipe, buffer, transfer_len, | ||||||
|  |  | ||||||
|  | @ -321,9 +321,7 @@ | ||||||
| #define CONFIG_SYS_VIDEO_LOGO_MAX_SIZE ((500 * 120 * 4) + (1 << 12)) | #define CONFIG_SYS_VIDEO_LOGO_MAX_SIZE ((500 * 120 * 4) + (1 << 12)) | ||||||
| 
 | 
 | ||||||
| #define CONFIG_CMD_USB_MASS_STORAGE | #define CONFIG_CMD_USB_MASS_STORAGE | ||||||
| #if defined(CONFIG_CMD_USB_MASS_STORAGE) |  | ||||||
| #define CONFIG_USB_GADGET_MASS_STORAGE | #define CONFIG_USB_GADGET_MASS_STORAGE | ||||||
| #endif |  | ||||||
| 
 | 
 | ||||||
| /* Pass open firmware flat tree */ | /* Pass open firmware flat tree */ | ||||||
| #define CONFIG_OF_LIBFDT    1 | #define CONFIG_OF_LIBFDT    1 | ||||||
|  |  | ||||||
|  | @ -13,5 +13,6 @@ | ||||||
| int g_dnl_bind_fixup(struct usb_device_descriptor *, const char *); | int g_dnl_bind_fixup(struct usb_device_descriptor *, const char *); | ||||||
| int g_dnl_register(const char *s); | int g_dnl_register(const char *s); | ||||||
| void g_dnl_unregister(void); | void g_dnl_unregister(void); | ||||||
|  | void g_dnl_set_serialnumber(char *); | ||||||
| 
 | 
 | ||||||
| #endif /* __G_DOWNLOAD_H_ */ | #endif /* __G_DOWNLOAD_H_ */ | ||||||
|  |  | ||||||
|  | @ -197,6 +197,16 @@ int board_usb_init(int index, enum usb_init_type init); | ||||||
|  */ |  */ | ||||||
| int board_usb_cleanup(int index, enum usb_init_type init); | int board_usb_cleanup(int index, enum usb_init_type init); | ||||||
| 
 | 
 | ||||||
|  | /*
 | ||||||
|  |  * If CONFIG_USB_CABLE_CHECK is set then this function | ||||||
|  |  * should be defined in board file. | ||||||
|  |  * | ||||||
|  |  * @return 1 if cable is connected and 0 otherwise. | ||||||
|  |  */ | ||||||
|  | #ifdef CONFIG_USB_CABLE_CHECK | ||||||
|  | int usb_cable_connected(void); | ||||||
|  | #endif | ||||||
|  | 
 | ||||||
| #ifdef CONFIG_USB_STORAGE | #ifdef CONFIG_USB_STORAGE | ||||||
| 
 | 
 | ||||||
| #define USB_MAX_STOR_DEV 5 | #define USB_MAX_STOR_DEV 5 | ||||||
|  |  | ||||||
|  | @ -9,32 +9,33 @@ | ||||||
| #define __USB_MASS_STORAGE_H__ | #define __USB_MASS_STORAGE_H__ | ||||||
| 
 | 
 | ||||||
| #define SECTOR_SIZE		0x200 | #define SECTOR_SIZE		0x200 | ||||||
| 
 |  | ||||||
| #include <mmc.h> | #include <mmc.h> | ||||||
| #include <linux/usb/composite.h> | #include <linux/usb/composite.h> | ||||||
| 
 | 
 | ||||||
| struct ums_device { | #ifndef UMS_START_SECTOR | ||||||
| 	struct mmc *mmc; | #define UMS_START_SECTOR	0 | ||||||
| 	int dev_num; | #endif | ||||||
| 	int offset; |  | ||||||
| 	int part_size; |  | ||||||
| }; |  | ||||||
| 
 | 
 | ||||||
| struct ums_board_info { | #ifndef UMS_NUM_SECTORS | ||||||
| 	int (*read_sector)(struct ums_device *ums_dev, | #define UMS_NUM_SECTORS		0 | ||||||
|  | #endif | ||||||
|  | 
 | ||||||
|  | struct ums { | ||||||
|  | 	int (*read_sector)(struct ums *ums_dev, | ||||||
| 			   ulong start, lbaint_t blkcnt, void *buf); | 			   ulong start, lbaint_t blkcnt, void *buf); | ||||||
| 	int (*write_sector)(struct ums_device *ums_dev, | 	int (*write_sector)(struct ums *ums_dev, | ||||||
| 			    ulong start, lbaint_t blkcnt, const void *buf); | 			    ulong start, lbaint_t blkcnt, const void *buf); | ||||||
| 	void (*get_capacity)(struct ums_device *ums_dev, | 	unsigned int start_sector; | ||||||
| 			     long long int *capacity); | 	unsigned int num_sectors; | ||||||
| 	const char *name; | 	const char *name; | ||||||
| 	struct ums_device ums_dev; | 	struct mmc *mmc; | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| int fsg_init(struct ums_board_info *); | extern struct ums *ums; | ||||||
|  | 
 | ||||||
|  | int fsg_init(struct ums *); | ||||||
| void fsg_cleanup(void); | void fsg_cleanup(void); | ||||||
| struct ums_board_info *board_ums_init(unsigned int, unsigned int, | struct ums *ums_init(unsigned int); | ||||||
| 				      unsigned int); |  | ||||||
| int fsg_main_thread(void *); | int fsg_main_thread(void *); | ||||||
| 
 | 
 | ||||||
| #ifdef CONFIG_USB_GADGET_MASS_STORAGE | #ifdef CONFIG_USB_GADGET_MASS_STORAGE | ||||||
|  |  | ||||||
		Loading…
	
		Reference in New Issue