mirror of
https://github.com/AsahiLinux/u-boot
synced 2025-02-26 12:27:12 +00:00
Merge branch 'master' of git://www.denx.de/git/u-boot-usb
This commit is contained in:
commit
15c5cdf5aa
15 changed files with 205 additions and 158 deletions
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
|
||||||
|
|
76
board/samsung/common/ums.c
Normal file
76
board/samsung/common/ums.c
Normal file
|
@ -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…
Add table
Reference in a new issue