Commit 3c47f2f4 authored by Tom Rini's avatar Tom Rini
Browse files

Merge branch 'master' of git://git.denx.de/u-boot-usb

parents 0ce033d2 ae003d05
......@@ -42,6 +42,7 @@
#include <power/max8997_muic.h>
#include <power/battery.h>
#include <power/max17042_fg.h>
#include <usb_mass_storage.h>
#include "setup.h"
......@@ -791,3 +792,65 @@ void init_panel_info(vidinfo_t *vid)
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
......@@ -179,6 +179,7 @@ COBJS-y += cmd_usb.o
COBJS-y += usb.o usb_hub.o
COBJS-$(CONFIG_USB_STORAGE) += usb_storage.o
endif
COBJS-$(CONFIG_CMD_USB_MASS_STORAGE) += cmd_usb_mass_storage.o
COBJS-$(CONFIG_CMD_XIMG) += cmd_ximg.o
COBJS-$(CONFIG_YAFFS2) += cmd_yaffs2.o
COBJS-$(CONFIG_CMD_SPL) += cmd_spl.o
......
......@@ -50,12 +50,15 @@ static int do_dfu(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
if (ret)
return CMD_RET_FAILURE;
if (strcmp(argv[3], "list") == 0) {
if (argc > 3 && strcmp(argv[3], "list") == 0) {
dfu_show_entities();
goto done;
}
#ifdef CONFIG_TRATS
board_usb_init();
#endif
g_dnl_register(s);
while (1) {
if (ctrlc())
......
/*
* Copyright (C) 2011 Samsung Electronics
* Lukasz Majewski <l.majewski@samsung.com>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of
* the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
* MA 02111-1307 USA
*/
#include <errno.h>
#include <common.h>
#include <command.h>
#include <g_dnl.h>
#include <usb_mass_storage.h>
int do_usb_mass_storage(cmd_tbl_t *cmdtp, int flag,
int argc, char * const argv[])
{
char *ep;
unsigned int dev_num = 0, offset = 0, part_size = 0;
int rc;
struct ums_board_info *ums_info;
static char *s = "ums";
if (argc < 2) {
printf("usage: ums <dev> - e.g. ums 0\n");
return 0;
}
dev_num = (int)simple_strtoul(argv[1], &ep, 16);
if (dev_num) {
puts("\nSet eMMC device to 0! - e.g. ums 0\n");
goto fail;
}
board_usb_init();
ums_info = board_ums_init(dev_num, offset, part_size);
if (!ums_info) {
printf("MMC: %d -> NOT available\n", dev_num);
goto fail;
}
rc = fsg_init(ums_info);
if (rc) {
printf("cmd ums: fsg_init failed\n");
goto fail;
}
g_dnl_register(s);
while (1) {
/* Handle control-c and timeouts */
if (ctrlc()) {
printf("The remote end did not respond in time.\n");
goto exit;
}
usb_gadget_handle_interrupts();
/* Check if USB cable has been detached */
if (fsg_main_thread(NULL) == EIO)
goto exit;
}
exit:
g_dnl_unregister();
return 0;
fail:
return -1;
}
U_BOOT_CMD(ums, CONFIG_SYS_MAXARGS, 1, do_usb_mass_storage,
"Use the UMS [User Mass Storage]",
"ums - User Mass Storage Gadget"
);
......@@ -21,6 +21,7 @@
#include <common.h>
#include <malloc.h>
#include <errno.h>
#include <dfu.h>
enum dfu_mmc_op {
......@@ -153,6 +154,10 @@ int dfu_read_medium_mmc(struct dfu_entity *dfu, void *buf, long *len)
int dfu_fill_entity_mmc(struct dfu_entity *dfu, char *s)
{
int dev, part;
struct mmc *mmc;
block_dev_desc_t *blk_dev;
disk_partition_t partinfo;
char *st;
dfu->dev_type = DFU_DEV_MMC;
......@@ -166,8 +171,34 @@ int dfu_fill_entity_mmc(struct dfu_entity *dfu, char *s)
dfu->layout = DFU_FS_FAT;
} else if (!strcmp(st, "ext4")) {
dfu->layout = DFU_FS_EXT4;
} else if (!strcmp(st, "part")) {
dfu->layout = DFU_RAW_ADDR;
dev = simple_strtoul(s, &s, 10);
s++;
part = simple_strtoul(s, &s, 10);
mmc = find_mmc_device(dev);
if (mmc == NULL || mmc_init(mmc)) {
printf("%s: could not find mmc device #%d!\n", __func__, dev);
return -ENODEV;
}
blk_dev = &mmc->block_dev;
if (get_partition_info(blk_dev, part, &partinfo) != 0) {
printf("%s: could not find partition #%d on mmc device #%d!\n",
__func__, part, dev);
return -ENODEV;
}
dfu->data.mmc.lba_start = partinfo.start;
dfu->data.mmc.lba_size = partinfo.size;
dfu->data.mmc.lba_blk_size = partinfo.blksz;
} else {
printf("%s: Memory layout (%s) not supported!\n", __func__, st);
return -ENODEV;
}
if (dfu->layout == DFU_FS_EXT4 || dfu->layout == DFU_FS_FAT) {
......
......@@ -63,7 +63,7 @@
/*
* Buffers to hold input and output data
*/
#define USBTTY_BUFFER_SIZE 256
#define USBTTY_BUFFER_SIZE 2048
static circbuf_t usbtty_input;
static circbuf_t usbtty_output;
......
......@@ -265,10 +265,6 @@ static int smsc95xx_eeprom_confirm_not_busy(struct ueth_data *dev)
do {
smsc95xx_read_reg(dev, E2P_CMD, &val);
if (!(val & E2P_CMD_LOADED_)) {
debug("No EEPROM present\n");
return -1;
}
if (!(val & E2P_CMD_BUSY_))
return 0;
udelay(40);
......
......@@ -25,15 +25,21 @@ include $(TOPDIR)/config.mk
LIB := $(obj)libusb_gadget.o
# if defined(CONFIG_USB_GADGET) || defined(CONFIG_USB_ETHER)
# Everytime you forget how crufty makefiles can get things like
# this remind you...
ifneq (,$(CONFIG_USB_GADGET)$(CONFIG_USB_ETHER))
COBJS-y += epautoconf.o config.o usbstring.o
endif
# new USB gadget layer dependencies
ifdef CONFIG_USB_GADGET
COBJS-y += epautoconf.o config.o usbstring.o
COBJS-$(CONFIG_USB_GADGET_S3C_UDC_OTG) += s3c_udc_otg.o
COBJS-$(CONFIG_USBDOWNLOAD_GADGET) += g_dnl.o
COBJS-$(CONFIG_DFU_FUNCTION) += f_dfu.o
endif
ifdef CONFIG_USB_ETHER
COBJS-y += ether.o epautoconf.o config.o usbstring.o
COBJS-y += ether.o
COBJS-$(CONFIG_USB_ETH_RNDIS) += rndis.o
COBJS-$(CONFIG_MV_UDC) += mv_udc.o
COBJS-$(CONFIG_CPU_PXA25X) += pxa25x_udc.o
......
......@@ -859,6 +859,25 @@ unknown:
if (&f->list == &cdev->config->functions)
f = NULL;
break;
/*
* dfu-util (version 0.5) sets bmRequestType.Receipent = Device
* for non-standard request (w_value = 0x21,
* bRequest = GET_DESCRIPTOR in this case).
* When only one interface is registered (as it is done now),
* then this request shall be handled as it was requested for
* interface.
*
* In the below code it is checked if only one interface is
* present and proper function for it is extracted. Due to that
* function's setup (f->setup) is called to handle this
* special non-standard request.
*/
case USB_RECIP_DEVICE:
debug("cdev->config->next_interface_id: %d intf: %d\n",
cdev->config->next_interface_id, intf);
if (cdev->config->next_interface_id == 1)
f = cdev->config->interface[intf];
break;
}
if (f && f->setup)
......
......@@ -164,6 +164,9 @@ static void handle_getstatus(struct usb_request *req)
/* send status response */
dstat->bStatus = f_dfu->dfu_status;
dstat->bwPollTimeout[0] = 0;
dstat->bwPollTimeout[1] = 0;
dstat->bwPollTimeout[2] = 0;
dstat->bState = f_dfu->dfu_state;
dstat->iString = 0;
}
......
This diff is collapsed.
......@@ -31,6 +31,7 @@
#include "gadget_chips.h"
#include "composite.c"
#include "f_mass_storage.c"
/*
* One needs to define the following:
......@@ -104,6 +105,8 @@ static int g_dnl_do_config(struct usb_configuration *c)
printf("GADGET DRIVER: %s\n", s);
if (!strcmp(s, "usb_dnl_dfu"))
ret = dfu_add(c);
else if (!strcmp(s, "usb_dnl_ums"))
ret = fsg_add(c);
return ret;
}
......@@ -188,6 +191,9 @@ int g_dnl_register(const char *type)
if (!strcmp(type, "dfu")) {
strcpy(name, shortname);
strcat(name, type);
} else if (!strcmp(type, "ums")) {
strcpy(name, shortname);
strcat(name, type);
} else {
printf("%s: unknown command: %s\n", __func__, type);
return -EINVAL;
......
/*
* storage_common.c -- Common definitions for mass storage functionality
*
* Copyright (C) 2003-2008 Alan Stern
* Copyeight (C) 2009 Samsung Electronics
* Author: Michal Nazarewicz (m.nazarewicz@samsung.com)
*
* Ported to u-boot:
* Andrzej Pietrasiewicz <andrzej.p@samsung.com>
*
* Code refactoring & cleanup:
* Łukasz Majewski <l.majewski@samsung.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
/*
* This file requires the following identifiers used in USB strings to
* be defined (each of type pointer to char):
* - fsg_string_manufacturer -- name of the manufacturer
* - fsg_string_product -- name of the product
* - fsg_string_serial -- product's serial
* - fsg_string_config -- name of the configuration
* - fsg_string_interface -- name of the interface
* The first four are only needed when FSG_DESCRIPTORS_DEVICE_STRINGS
* macro is defined prior to including this file.
*/
/*
* When FSG_NO_INTR_EP is defined fsg_fs_intr_in_desc and
* fsg_hs_intr_in_desc objects as well as
* FSG_FS_FUNCTION_PRE_EP_ENTRIES and FSG_HS_FUNCTION_PRE_EP_ENTRIES
* macros are not defined.
*
* When FSG_NO_DEVICE_STRINGS is defined FSG_STRING_MANUFACTURER,
* FSG_STRING_PRODUCT, FSG_STRING_SERIAL and FSG_STRING_CONFIG are not
* defined (as well as corresponding entries in string tables are
* missing) and FSG_STRING_INTERFACE has value of zero.
*
* When FSG_NO_OTG is defined fsg_otg_desc won't be defined.
*/
/*
* When FSG_BUFFHD_STATIC_BUFFER is defined when this file is included
* the fsg_buffhd structure's buf field will be an array of FSG_BUFLEN
* characters rather then a pointer to void.
*/
/* #include <asm/unaligned.h> */
/*
* Thanks to NetChip Technologies for donating this product ID.
*
* DO NOT REUSE THESE IDs with any other driver!! Ever!!
* Instead: allocate your own, using normal USB-IF procedures.
*/
#define FSG_VENDOR_ID 0x0525 /* NetChip */
#define FSG_PRODUCT_ID 0xa4a5 /* Linux-USB File-backed Storage Gadget */
/*-------------------------------------------------------------------------*/
#ifndef DEBUG
#undef VERBOSE_DEBUG
#undef DUMP_MSGS
#endif /* !DEBUG */
#ifdef VERBOSE_DEBUG
#define VLDBG LDBG
#else
#define VLDBG(lun, fmt, args...) do { } while (0)
#endif /* VERBOSE_DEBUG */
/*
#define LDBG(lun, fmt, args...) dev_dbg (&(lun)->dev, fmt, ## args)
#define LERROR(lun, fmt, args...) dev_err (&(lun)->dev, fmt, ## args)
#define LWARN(lun, fmt, args...) dev_warn(&(lun)->dev, fmt, ## args)
#define LINFO(lun, fmt, args...) dev_info(&(lun)->dev, fmt, ## args)
*/
#define LDBG(lun, fmt, args...) do { } while (0)
#define LERROR(lun, fmt, args...) do { } while (0)
#define LWARN(lun, fmt, args...) do { } while (0)
#define LINFO(lun, fmt, args...) do { } while (0)
/*
* Keep those macros in sync with those in
* include/linux/usb/composite.h or else GCC will complain. If they
* are identical (the same names of arguments, white spaces in the
* same places) GCC will allow redefinition otherwise (even if some
* white space is removed or added) warning will be issued.
*
* Those macros are needed here because File Storage Gadget does not
* include the composite.h header. For composite gadgets those macros
* are redundant since composite.h is included any way.
*
* One could check whether those macros are already defined (which
* would indicate composite.h had been included) or not (which would
* indicate we were in FSG) but this is not done because a warning is
* desired if definitions here differ from the ones in composite.h.
*
* We want the definitions to match and be the same in File Storage
* Gadget as well as Mass Storage Function (and so composite gadgets
* using MSF). If someone changes them in composite.h it will produce
* a warning in this file when building MSF.
*/
#define DBG(d, fmt, args...) debug(fmt , ## args)
#define VDBG(d, fmt, args...) debug(fmt , ## args)
/* #define ERROR(d, fmt, args...) printf(fmt , ## args) */
/* #define WARNING(d, fmt, args...) printf(fmt , ## args) */
/* #define INFO(d, fmt, args...) printf(fmt , ## args) */
/* #define DBG(d, fmt, args...) do { } while (0) */
/* #define VDBG(d, fmt, args...) do { } while (0) */
#define ERROR(d, fmt, args...) do { } while (0)
#define WARNING(d, fmt, args...) do { } while (0)
#define INFO(d, fmt, args...) do { } while (0)
#ifdef DUMP_MSGS
/* dump_msg(fsg, const char * label, const u8 * buf, unsigned length); */
# define dump_msg(fsg, label, buf, length) do { \
if (length < 512) { \
DBG(fsg, "%s, length %u:\n", label, length); \
print_hex_dump(KERN_DEBUG, "", DUMP_PREFIX_OFFSET, \
16, 1, buf, length, 0); \
} \
} while (0)
# define dump_cdb(fsg) do { } while (0)
#else
# define dump_msg(fsg, /* const char * */ label, \
/* const u8 * */ buf, /* unsigned */ length) do { } while (0)
# ifdef VERBOSE_DEBUG
# define dump_cdb(fsg) \
print_hex_dump(KERN_DEBUG, "SCSI CDB: ", DUMP_PREFIX_NONE, \
16, 1, (fsg)->cmnd, (fsg)->cmnd_size, 0) \
# else
# define dump_cdb(fsg) do { } while (0)
# endif /* VERBOSE_DEBUG */
#endif /* DUMP_MSGS */
/*-------------------------------------------------------------------------*/
/* SCSI device types */
#define TYPE_DISK 0x00
#define TYPE_CDROM 0x05
/* USB protocol value = the transport method */
#define USB_PR_CBI 0x00 /* Control/Bulk/Interrupt */
#define USB_PR_CB 0x01 /* Control/Bulk w/o interrupt */
#define USB_PR_BULK 0x50 /* Bulk-only */
/* USB subclass value = the protocol encapsulation */
#define USB_SC_RBC 0x01 /* Reduced Block Commands (flash) */
#define USB_SC_8020 0x02 /* SFF-8020i, MMC-2, ATAPI (CD-ROM) */
#define USB_SC_QIC 0x03 /* QIC-157 (tape) */
#define USB_SC_UFI 0x04 /* UFI (floppy) */
#define USB_SC_8070 0x05 /* SFF-8070i (removable) */
#define USB_SC_SCSI 0x06 /* Transparent SCSI */
/* Bulk-only data structures */
/* Command Block Wrapper */
struct fsg_bulk_cb_wrap {
__le32 Signature; /* Contains 'USBC' */
u32 Tag; /* Unique per command id */
__le32 DataTransferLength; /* Size of the data */
u8 Flags; /* Direction in bit 7 */
u8 Lun; /* LUN (normally 0) */
u8 Length; /* Of the CDB, <= MAX_COMMAND_SIZE */
u8 CDB[16]; /* Command Data Block */
};
#define USB_BULK_CB_WRAP_LEN 31
#define USB_BULK_CB_SIG 0x43425355 /* Spells out USBC */
#define USB_BULK_IN_FLAG 0x80
/* Command Status Wrapper */
struct bulk_cs_wrap {
__le32 Signature; /* Should = 'USBS' */
u32 Tag; /* Same as original command */
__le32 Residue; /* Amount not transferred */
u8 Status; /* See below */
};
#define USB_BULK_CS_WRAP_LEN 13
#define USB_BULK_CS_SIG 0x53425355 /* Spells out 'USBS' */
#define USB_STATUS_PASS 0
#define USB_STATUS_FAIL 1
#define USB_STATUS_PHASE_ERROR 2
/* Bulk-only class specific requests */
#define USB_BULK_RESET_REQUEST 0xff
#define USB_BULK_GET_MAX_LUN_REQUEST 0xfe
/* CBI Interrupt data structure */
struct interrupt_data {
u8 bType;
u8 bValue;
};
#define CBI_INTERRUPT_DATA_LEN 2
/* CBI Accept Device-Specific Command request */
#define USB_CBI_ADSC_REQUEST 0x00
/* Length of a SCSI Command Data Block */
#define MAX_COMMAND_SIZE 16
/* SCSI commands that we recognize */
#define SC_FORMAT_UNIT 0x04
#define SC_INQUIRY 0x12
#define SC_MODE_SELECT_6 0x15
#define SC_MODE_SELECT_10 0x55
#define SC_MODE_SENSE_6 0x1a
#define SC_MODE_SENSE_10 0x5a
#define SC_PREVENT_ALLOW_MEDIUM_REMOVAL 0x1e
#define SC_READ_6 0x08
#define SC_READ_10 0x28
#define SC_READ_12 0xa8
#define SC_READ_CAPACITY 0x25
#define SC_READ_FORMAT_CAPACITIES 0x23
#define SC_READ_HEADER 0x44
#define SC_READ_TOC 0x43
#define SC_RELEASE 0x17
#define SC_REQUEST_SENSE 0x03
#define SC_RESERVE 0x16
#define SC_SEND_DIAGNOSTIC 0x1d
#define SC_START_STOP_UNIT 0x1b
#define SC_SYNCHRONIZE_CACHE 0x35
#define SC_TEST_UNIT_READY 0x00
#define SC_VERIFY 0x2f
#define SC_WRITE_6 0x0a
#define SC_WRITE_10 0x2a
#define SC_WRITE_12 0xaa
/* SCSI Sense Key/Additional Sense Code/ASC Qualifier values */
#define SS_NO_SENSE 0
#define SS_COMMUNICATION_FAILURE 0x040800
#define SS_INVALID_COMMAND 0x052000
#define SS_INVALID_FIELD_IN_CDB 0x052400
#define SS_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE 0x052100
#define SS_LOGICAL_UNIT_NOT_SUPPORTED 0x052500
#define SS_MEDIUM_NOT_PRESENT 0x023a00
#define SS_MEDIUM_REMOVAL_PREVENTED 0x055302
#define SS_NOT_READY_TO_READY_TRANSITION 0x062800