mirror of
https://github.com/u-boot/u-boot.git
synced 2025-04-23 22:14:54 +00:00
Merge tag 'u-boot-dfu-next-20240402' of https://source.denx.de/u-boot/custodians/u-boot-dfu
u-boot-dfu-next-20240402 - Implement Qualcomm wrapper for dwc3 - Multiple sector size support for UMS - CDC ACM gadget initialization fix - Refactor board code from dwc3 to prepare better interrupt support - Bugfix for for qcom-smmu when compiling with -DDEBUG
This commit is contained in:
commit
cdfcc37428
15 changed files with 178 additions and 95 deletions
|
@ -418,12 +418,6 @@ out:
|
||||||
return rv;
|
return rv;
|
||||||
}
|
}
|
||||||
|
|
||||||
int dm_usb_gadget_handle_interrupts(struct udevice *dev)
|
|
||||||
{
|
|
||||||
dwc3_uboot_handle_interrupt(dev);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void dwc3_nxp_usb_phy_init(struct dwc3_device *dwc3)
|
static void dwc3_nxp_usb_phy_init(struct dwc3_device *dwc3)
|
||||||
{
|
{
|
||||||
u32 RegData;
|
u32 RegData;
|
||||||
|
|
|
@ -122,12 +122,6 @@ static struct dwc3_device dwc3_device_data = {
|
||||||
.index = 0,
|
.index = 0,
|
||||||
};
|
};
|
||||||
|
|
||||||
int dm_usb_gadget_handle_interrupts(struct udevice *dev)
|
|
||||||
{
|
|
||||||
dwc3_uboot_handle_interrupt(dev);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int board_usb_init(int index, enum usb_init_type init)
|
int board_usb_init(int index, enum usb_init_type init)
|
||||||
{
|
{
|
||||||
struct exynos_usb3_phy *phy = (struct exynos_usb3_phy *)
|
struct exynos_usb3_phy *phy = (struct exynos_usb3_phy *)
|
||||||
|
|
|
@ -50,12 +50,6 @@ static struct dwc3_device dwc3_device_data = {
|
||||||
.index = 0,
|
.index = 0,
|
||||||
};
|
};
|
||||||
|
|
||||||
int dm_usb_gadget_handle_interrupts(struct udevice *dev)
|
|
||||||
{
|
|
||||||
dwc3_uboot_handle_interrupt(dev);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int board_usb_init(int index, enum usb_init_type init)
|
int board_usb_init(int index, enum usb_init_type init)
|
||||||
{
|
{
|
||||||
int node;
|
int node;
|
||||||
|
|
|
@ -759,17 +759,6 @@ static struct ti_usb_phy_device usb_phy2_device = {
|
||||||
.usb2_phy_power = (void *)USB2_PHY2_POWER,
|
.usb2_phy_power = (void *)USB2_PHY2_POWER,
|
||||||
.index = 1,
|
.index = 1,
|
||||||
};
|
};
|
||||||
|
|
||||||
int dm_usb_gadget_handle_interrupts(struct udevice *dev)
|
|
||||||
{
|
|
||||||
u32 status;
|
|
||||||
|
|
||||||
status = dwc3_omap_uboot_interrupt_status(dev);
|
|
||||||
if (status)
|
|
||||||
dwc3_uboot_handle_interrupt(dev);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
#endif /* CONFIG_USB_DWC3 */
|
#endif /* CONFIG_USB_DWC3 */
|
||||||
|
|
||||||
#if defined(CONFIG_USB_DWC3) || defined(CONFIG_USB_XHCI_OMAP)
|
#if defined(CONFIG_USB_DWC3) || defined(CONFIG_USB_XHCI_OMAP)
|
||||||
|
|
|
@ -88,10 +88,6 @@ static int ums_init(const char *devtype, const char *devnums_part_str)
|
||||||
if (!strchr(devnum_part_str, ':'))
|
if (!strchr(devnum_part_str, ':'))
|
||||||
partnum = 0;
|
partnum = 0;
|
||||||
|
|
||||||
/* f_mass_storage.c assumes SECTOR_SIZE sectors */
|
|
||||||
if (block_dev->blksz != SECTOR_SIZE)
|
|
||||||
goto cleanup;
|
|
||||||
|
|
||||||
ums_new = realloc(ums, (ums_count + 1) * sizeof(*ums));
|
ums_new = realloc(ums, (ums_count + 1) * sizeof(*ums));
|
||||||
if (!ums_new)
|
if (!ums_new)
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
|
|
|
@ -319,7 +319,7 @@ static int qcom_smmu_connect(struct udevice *dev)
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
static inline void dump_boot_mappings(struct arm_smmu_priv *priv)
|
static inline void dump_boot_mappings(struct qcom_smmu_priv *priv)
|
||||||
{
|
{
|
||||||
u32 val;
|
u32 val;
|
||||||
int i;
|
int i;
|
||||||
|
|
|
@ -983,18 +983,32 @@ void dwc3_uboot_exit(int index)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
MODULE_ALIAS("platform:dwc3");
|
||||||
|
MODULE_AUTHOR("Felipe Balbi <balbi@ti.com>");
|
||||||
|
MODULE_LICENSE("GPL v2");
|
||||||
|
MODULE_DESCRIPTION("DesignWare USB3 DRD Controller Driver");
|
||||||
|
|
||||||
|
#if !CONFIG_IS_ENABLED(DM_USB_GADGET)
|
||||||
|
__weak int dwc3_uboot_interrupt_status(struct udevice *dev)
|
||||||
|
{
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* dwc3_uboot_handle_interrupt - handle dwc3 core interrupt
|
* dm_usb_gadget_handle_interrupts - handle dwc3 core interrupt
|
||||||
* @dev: device of this controller
|
* @dev: device of this controller
|
||||||
*
|
*
|
||||||
* Invokes dwc3 gadget interrupts.
|
* Invokes dwc3 gadget interrupts.
|
||||||
*
|
*
|
||||||
* Generally called from board file.
|
* Generally called from board file.
|
||||||
*/
|
*/
|
||||||
void dwc3_uboot_handle_interrupt(struct udevice *dev)
|
int dm_usb_gadget_handle_interrupts(struct udevice *dev)
|
||||||
{
|
{
|
||||||
struct dwc3 *dwc = NULL;
|
struct dwc3 *dwc = NULL;
|
||||||
|
|
||||||
|
if (!dwc3_uboot_interrupt_status(dev))
|
||||||
|
return 0;
|
||||||
|
|
||||||
list_for_each_entry(dwc, &dwc3_list, list) {
|
list_for_each_entry(dwc, &dwc3_list, list) {
|
||||||
if (dwc->dev != dev)
|
if (dwc->dev != dev)
|
||||||
continue;
|
continue;
|
||||||
|
@ -1002,12 +1016,10 @@ void dwc3_uboot_handle_interrupt(struct udevice *dev)
|
||||||
dwc3_gadget_uboot_handle_interrupt(dwc);
|
dwc3_gadget_uboot_handle_interrupt(dwc);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
MODULE_ALIAS("platform:dwc3");
|
return 0;
|
||||||
MODULE_AUTHOR("Felipe Balbi <balbi@ti.com>");
|
}
|
||||||
MODULE_LICENSE("GPL v2");
|
#endif
|
||||||
MODULE_DESCRIPTION("DesignWare USB3 DRD Controller Driver");
|
|
||||||
|
|
||||||
#if CONFIG_IS_ENABLED(PHY) && CONFIG_IS_ENABLED(DM_USB)
|
#if CONFIG_IS_ENABLED(PHY) && CONFIG_IS_ENABLED(DM_USB)
|
||||||
int dwc3_setup_phy(struct udevice *dev, struct phy_bulk *phys)
|
int dwc3_setup_phy(struct udevice *dev, struct phy_bulk *phys)
|
||||||
|
|
|
@ -425,6 +425,77 @@ struct dwc3_glue_ops ti_ops = {
|
||||||
.glue_configure = dwc3_ti_glue_configure,
|
.glue_configure = dwc3_ti_glue_configure,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/* USB QSCRATCH Hardware registers */
|
||||||
|
#define QSCRATCH_GENERAL_CFG 0x08
|
||||||
|
#define PIPE_UTMI_CLK_SEL BIT(0)
|
||||||
|
#define PIPE3_PHYSTATUS_SW BIT(3)
|
||||||
|
#define PIPE_UTMI_CLK_DIS BIT(8)
|
||||||
|
|
||||||
|
#define QSCRATCH_HS_PHY_CTRL 0x10
|
||||||
|
#define UTMI_OTG_VBUS_VALID BIT(20)
|
||||||
|
#define SW_SESSVLD_SEL BIT(28)
|
||||||
|
|
||||||
|
#define QSCRATCH_SS_PHY_CTRL 0x30
|
||||||
|
#define LANE0_PWR_PRESENT BIT(24)
|
||||||
|
|
||||||
|
#define PWR_EVNT_IRQ_STAT_REG 0x58
|
||||||
|
#define PWR_EVNT_LPM_IN_L2_MASK BIT(4)
|
||||||
|
#define PWR_EVNT_LPM_OUT_L2_MASK BIT(5)
|
||||||
|
|
||||||
|
#define SDM845_QSCRATCH_BASE_OFFSET 0xf8800
|
||||||
|
#define SDM845_QSCRATCH_SIZE 0x400
|
||||||
|
#define SDM845_DWC3_CORE_SIZE 0xcd00
|
||||||
|
|
||||||
|
static void dwc3_qcom_vbus_override_enable(void __iomem *qscratch_base, bool enable)
|
||||||
|
{
|
||||||
|
if (enable) {
|
||||||
|
setbits_le32(qscratch_base + QSCRATCH_SS_PHY_CTRL,
|
||||||
|
LANE0_PWR_PRESENT);
|
||||||
|
setbits_le32(qscratch_base + QSCRATCH_HS_PHY_CTRL,
|
||||||
|
UTMI_OTG_VBUS_VALID | SW_SESSVLD_SEL);
|
||||||
|
} else {
|
||||||
|
clrbits_le32(qscratch_base + QSCRATCH_SS_PHY_CTRL,
|
||||||
|
LANE0_PWR_PRESENT);
|
||||||
|
clrbits_le32(qscratch_base + QSCRATCH_HS_PHY_CTRL,
|
||||||
|
UTMI_OTG_VBUS_VALID | SW_SESSVLD_SEL);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* For controllers running without superspeed PHYs */
|
||||||
|
static void dwc3_qcom_select_utmi_clk(void __iomem *qscratch_base)
|
||||||
|
{
|
||||||
|
/* Configure dwc3 to use UTMI clock as PIPE clock not present */
|
||||||
|
setbits_le32(qscratch_base + QSCRATCH_GENERAL_CFG,
|
||||||
|
PIPE_UTMI_CLK_DIS);
|
||||||
|
|
||||||
|
setbits_le32(qscratch_base + QSCRATCH_GENERAL_CFG,
|
||||||
|
PIPE_UTMI_CLK_SEL | PIPE3_PHYSTATUS_SW);
|
||||||
|
|
||||||
|
clrbits_le32(qscratch_base + QSCRATCH_GENERAL_CFG,
|
||||||
|
PIPE_UTMI_CLK_DIS);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void dwc3_qcom_glue_configure(struct udevice *dev, int index,
|
||||||
|
enum usb_dr_mode mode)
|
||||||
|
{
|
||||||
|
struct dwc3_glue_data *glue = dev_get_plat(dev);
|
||||||
|
void __iomem *qscratch_base = map_physmem(glue->regs, 0x400, MAP_NOCACHE);
|
||||||
|
if (IS_ERR_OR_NULL(qscratch_base)) {
|
||||||
|
log_err("%s: Invalid qscratch base address\n", dev->name);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (dev_read_bool(dev, "qcom,select-utmi-as-pipe-clk"))
|
||||||
|
dwc3_qcom_select_utmi_clk(qscratch_base);
|
||||||
|
|
||||||
|
if (mode != USB_DR_MODE_HOST)
|
||||||
|
dwc3_qcom_vbus_override_enable(qscratch_base, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
struct dwc3_glue_ops qcom_ops = {
|
||||||
|
.glue_configure = dwc3_qcom_glue_configure,
|
||||||
|
};
|
||||||
|
|
||||||
static int dwc3_rk_glue_get_ctrl_dev(struct udevice *dev, ofnode *node)
|
static int dwc3_rk_glue_get_ctrl_dev(struct udevice *dev, ofnode *node)
|
||||||
{
|
{
|
||||||
*node = dev_ofnode(dev);
|
*node = dev_ofnode(dev);
|
||||||
|
@ -512,6 +583,14 @@ static int dwc3_glue_reset_init(struct udevice *dev,
|
||||||
else if (ret)
|
else if (ret)
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
|
if (device_is_compatible(dev, "qcom,dwc3")) {
|
||||||
|
reset_assert_bulk(&glue->resets);
|
||||||
|
/* We should wait at least 6 sleep clock cycles, that's
|
||||||
|
* (6 / 32764) * 1000000 ~= 200us. But some platforms
|
||||||
|
* have slower sleep clocks so we'll play it safe.
|
||||||
|
*/
|
||||||
|
udelay(500);
|
||||||
|
}
|
||||||
ret = reset_deassert_bulk(&glue->resets);
|
ret = reset_deassert_bulk(&glue->resets);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
reset_release_bulk(&glue->resets);
|
reset_release_bulk(&glue->resets);
|
||||||
|
@ -629,7 +708,7 @@ static const struct udevice_id dwc3_glue_ids[] = {
|
||||||
{ .compatible = "rockchip,rk3399-dwc3" },
|
{ .compatible = "rockchip,rk3399-dwc3" },
|
||||||
{ .compatible = "rockchip,rk3568-dwc3", .data = (ulong)&rk_ops },
|
{ .compatible = "rockchip,rk3568-dwc3", .data = (ulong)&rk_ops },
|
||||||
{ .compatible = "rockchip,rk3588-dwc3", .data = (ulong)&rk_ops },
|
{ .compatible = "rockchip,rk3588-dwc3", .data = (ulong)&rk_ops },
|
||||||
{ .compatible = "qcom,dwc3" },
|
{ .compatible = "qcom,dwc3", .data = (ulong)&qcom_ops },
|
||||||
{ .compatible = "fsl,imx8mp-dwc3", .data = (ulong)&imx8mp_ops },
|
{ .compatible = "fsl,imx8mp-dwc3", .data = (ulong)&imx8mp_ops },
|
||||||
{ .compatible = "fsl,imx8mq-dwc3" },
|
{ .compatible = "fsl,imx8mq-dwc3" },
|
||||||
{ .compatible = "intel,tangier-dwc3" },
|
{ .compatible = "intel,tangier-dwc3" },
|
||||||
|
|
|
@ -428,7 +428,7 @@ void dwc3_omap_uboot_exit(int index)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* dwc3_omap_uboot_interrupt_status - check the status of interrupt
|
* dwc3_uboot_interrupt_status - check the status of interrupt
|
||||||
* @dev: device of this controller
|
* @dev: device of this controller
|
||||||
*
|
*
|
||||||
* Checks the status of interrupts and returns true if an interrupt
|
* Checks the status of interrupts and returns true if an interrupt
|
||||||
|
@ -436,7 +436,7 @@ void dwc3_omap_uboot_exit(int index)
|
||||||
*
|
*
|
||||||
* Generally called from board file.
|
* Generally called from board file.
|
||||||
*/
|
*/
|
||||||
int dwc3_omap_uboot_interrupt_status(struct udevice *dev)
|
int dwc3_uboot_interrupt_status(struct udevice *dev)
|
||||||
{
|
{
|
||||||
struct dwc3_omap *omap = NULL;
|
struct dwc3_omap *omap = NULL;
|
||||||
|
|
||||||
|
|
|
@ -623,12 +623,21 @@ static void acm_stdio_puts(struct stdio_dev *dev, const char *str)
|
||||||
|
|
||||||
static int acm_stdio_start(struct stdio_dev *dev)
|
static int acm_stdio_start(struct stdio_dev *dev)
|
||||||
{
|
{
|
||||||
|
struct udevice *udc;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
if (dev->priv) { /* function already exist */
|
if (dev->priv) { /* function already exist */
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ret = udc_device_get_by_index(0, &udc);
|
||||||
|
if (ret) {
|
||||||
|
pr_err("USB init failed: %d\n", ret);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
g_dnl_clear_detach();
|
||||||
|
|
||||||
ret = g_dnl_register("usb_serial_acm");
|
ret = g_dnl_register("usb_serial_acm");
|
||||||
if (ret)
|
if (ret)
|
||||||
return ret;
|
return ret;
|
||||||
|
|
|
@ -240,6 +240,7 @@
|
||||||
/* #define DUMP_MSGS */
|
/* #define DUMP_MSGS */
|
||||||
|
|
||||||
#include <config.h>
|
#include <config.h>
|
||||||
|
#include <div64.h>
|
||||||
#include <hexdump.h>
|
#include <hexdump.h>
|
||||||
#include <log.h>
|
#include <log.h>
|
||||||
#include <malloc.h>
|
#include <malloc.h>
|
||||||
|
@ -724,12 +725,13 @@ static int do_read(struct fsg_common *common)
|
||||||
curlun->sense_data = SS_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE;
|
curlun->sense_data = SS_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE;
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
file_offset = ((loff_t) lba) << 9;
|
file_offset = ((loff_t)lba) << curlun->blkbits;
|
||||||
|
|
||||||
/* Carry out the file reads */
|
/* Carry out the file reads */
|
||||||
amount_left = common->data_size_from_cmnd;
|
amount_left = common->data_size_from_cmnd;
|
||||||
if (unlikely(amount_left == 0))
|
if (unlikely(amount_left == 0)) {
|
||||||
return -EIO; /* No default reply */
|
return -EIO; /* No default reply */
|
||||||
|
}
|
||||||
|
|
||||||
for (;;) {
|
for (;;) {
|
||||||
|
|
||||||
|
@ -768,13 +770,13 @@ static int do_read(struct fsg_common *common)
|
||||||
|
|
||||||
/* Perform the read */
|
/* Perform the read */
|
||||||
rc = ums[common->lun].read_sector(&ums[common->lun],
|
rc = ums[common->lun].read_sector(&ums[common->lun],
|
||||||
file_offset / SECTOR_SIZE,
|
lldiv(file_offset, curlun->blksize),
|
||||||
amount / SECTOR_SIZE,
|
lldiv(amount, curlun->blksize),
|
||||||
(char __user *)bh->buf);
|
(char __user *)bh->buf);
|
||||||
if (!rc)
|
if (!rc)
|
||||||
return -EIO;
|
return -EIO;
|
||||||
|
|
||||||
nread = rc * SECTOR_SIZE;
|
nread = rc * curlun->blksize;
|
||||||
|
|
||||||
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,
|
||||||
|
@ -787,7 +789,7 @@ static int do_read(struct fsg_common *common)
|
||||||
} else if (nread < amount) {
|
} else if (nread < amount) {
|
||||||
LDBG(curlun, "partial file read: %d/%u\n",
|
LDBG(curlun, "partial file read: %d/%u\n",
|
||||||
(int) nread, amount);
|
(int) nread, amount);
|
||||||
nread -= (nread & 511); /* Round down to a block */
|
nread -= (nread & (curlun->blksize - 1)); /* Round down to a block */
|
||||||
}
|
}
|
||||||
file_offset += nread;
|
file_offset += nread;
|
||||||
amount_left -= nread;
|
amount_left -= nread;
|
||||||
|
@ -861,7 +863,7 @@ static int do_write(struct fsg_common *common)
|
||||||
|
|
||||||
/* Carry out the file writes */
|
/* Carry out the file writes */
|
||||||
get_some_more = 1;
|
get_some_more = 1;
|
||||||
file_offset = usb_offset = ((loff_t) lba) << 9;
|
file_offset = usb_offset = ((loff_t)lba) << curlun->blkbits;
|
||||||
amount_left_to_req = common->data_size_from_cmnd;
|
amount_left_to_req = common->data_size_from_cmnd;
|
||||||
amount_left_to_write = common->data_size_from_cmnd;
|
amount_left_to_write = common->data_size_from_cmnd;
|
||||||
|
|
||||||
|
@ -893,7 +895,7 @@ static int do_write(struct fsg_common *common)
|
||||||
curlun->info_valid = 1;
|
curlun->info_valid = 1;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
amount -= (amount & 511);
|
amount -= (amount & (curlun->blksize - 1));
|
||||||
if (amount == 0) {
|
if (amount == 0) {
|
||||||
|
|
||||||
/* Why were we were asked to transfer a
|
/* Why were we were asked to transfer a
|
||||||
|
@ -942,12 +944,12 @@ static int do_write(struct fsg_common *common)
|
||||||
|
|
||||||
/* Perform the write */
|
/* Perform the write */
|
||||||
rc = ums[common->lun].write_sector(&ums[common->lun],
|
rc = ums[common->lun].write_sector(&ums[common->lun],
|
||||||
file_offset / SECTOR_SIZE,
|
lldiv(file_offset, curlun->blksize),
|
||||||
amount / SECTOR_SIZE,
|
lldiv(amount, curlun->blksize),
|
||||||
(char __user *)bh->buf);
|
(char __user *)bh->buf);
|
||||||
if (!rc)
|
if (!rc)
|
||||||
return -EIO;
|
return -EIO;
|
||||||
nwritten = rc * SECTOR_SIZE;
|
nwritten = rc * curlun->blksize;
|
||||||
|
|
||||||
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,
|
||||||
|
@ -960,7 +962,7 @@ static int do_write(struct fsg_common *common)
|
||||||
} else if (nwritten < amount) {
|
} else if (nwritten < amount) {
|
||||||
LDBG(curlun, "partial file write: %d/%u\n",
|
LDBG(curlun, "partial file write: %d/%u\n",
|
||||||
(int) nwritten, amount);
|
(int) nwritten, amount);
|
||||||
nwritten -= (nwritten & 511);
|
nwritten -= (nwritten & (curlun->blksize - 1));
|
||||||
/* Round down to a block */
|
/* Round down to a block */
|
||||||
}
|
}
|
||||||
file_offset += nwritten;
|
file_offset += nwritten;
|
||||||
|
@ -1034,8 +1036,8 @@ static int do_verify(struct fsg_common *common)
|
||||||
return -EIO; /* No default reply */
|
return -EIO; /* No default reply */
|
||||||
|
|
||||||
/* Prepare to carry out the file verify */
|
/* Prepare to carry out the file verify */
|
||||||
amount_left = verification_length << 9;
|
amount_left = verification_length << curlun->blkbits;
|
||||||
file_offset = ((loff_t) lba) << 9;
|
file_offset = ((loff_t) lba) << curlun->blkbits;
|
||||||
|
|
||||||
/* Write out all the dirty buffers before invalidating them */
|
/* Write out all the dirty buffers before invalidating them */
|
||||||
|
|
||||||
|
@ -1058,12 +1060,12 @@ static int do_verify(struct fsg_common *common)
|
||||||
|
|
||||||
/* Perform the read */
|
/* Perform the read */
|
||||||
rc = ums[common->lun].read_sector(&ums[common->lun],
|
rc = ums[common->lun].read_sector(&ums[common->lun],
|
||||||
file_offset / SECTOR_SIZE,
|
lldiv(file_offset, curlun->blksize),
|
||||||
amount / SECTOR_SIZE,
|
lldiv(amount, curlun->blksize),
|
||||||
(char __user *)bh->buf);
|
(char __user *)bh->buf);
|
||||||
if (!rc)
|
if (!rc)
|
||||||
return -EIO;
|
return -EIO;
|
||||||
nread = rc * SECTOR_SIZE;
|
nread = rc * curlun->blksize;
|
||||||
|
|
||||||
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,
|
||||||
|
@ -1075,7 +1077,7 @@ static int do_verify(struct fsg_common *common)
|
||||||
} else if (nread < amount) {
|
} else if (nread < amount) {
|
||||||
LDBG(curlun, "partial file verify: %d/%u\n",
|
LDBG(curlun, "partial file verify: %d/%u\n",
|
||||||
(int) nread, amount);
|
(int) nread, amount);
|
||||||
nread -= (nread & 511); /* Round down to a sector */
|
nread -= (nread & (curlun->blksize - 1)); /* Round down to a sector */
|
||||||
}
|
}
|
||||||
if (nread == 0) {
|
if (nread == 0) {
|
||||||
curlun->sense_data = SS_UNRECOVERED_READ_ERROR;
|
curlun->sense_data = SS_UNRECOVERED_READ_ERROR;
|
||||||
|
@ -1183,7 +1185,7 @@ static int do_read_capacity(struct fsg_common *common, struct fsg_buffhd *bh)
|
||||||
|
|
||||||
put_unaligned_be32(curlun->num_sectors - 1, &buf[0]);
|
put_unaligned_be32(curlun->num_sectors - 1, &buf[0]);
|
||||||
/* Max logical block */
|
/* Max logical block */
|
||||||
put_unaligned_be32(512, &buf[4]); /* Block length */
|
put_unaligned_be32(curlun->blksize, &buf[4]); /* Block length */
|
||||||
return 8;
|
return 8;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1370,7 +1372,7 @@ static int do_read_format_capacities(struct fsg_common *common,
|
||||||
|
|
||||||
put_unaligned_be32(curlun->num_sectors, &buf[0]);
|
put_unaligned_be32(curlun->num_sectors, &buf[0]);
|
||||||
/* Number of blocks */
|
/* Number of blocks */
|
||||||
put_unaligned_be32(512, &buf[4]); /* Block length */
|
put_unaligned_be32(curlun->blksize, &buf[4]); /* Block length */
|
||||||
buf[4] = 0x02; /* Current capacity */
|
buf[4] = 0x02; /* Current capacity */
|
||||||
return 12;
|
return 12;
|
||||||
}
|
}
|
||||||
|
@ -1781,6 +1783,16 @@ static int check_command(struct fsg_common *common, int cmnd_size,
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* wrapper of check_command for data size in blocks handling */
|
||||||
|
static int check_command_size_in_blocks(struct fsg_common *common,
|
||||||
|
int cmnd_size, enum data_direction data_dir,
|
||||||
|
unsigned int mask, int needs_medium, const char *name)
|
||||||
|
{
|
||||||
|
common->data_size_from_cmnd <<= common->luns[common->lun].blkbits;
|
||||||
|
return check_command(common, cmnd_size, data_dir,
|
||||||
|
mask, needs_medium, name);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static int do_scsi_command(struct fsg_common *common)
|
static int do_scsi_command(struct fsg_common *common)
|
||||||
{
|
{
|
||||||
|
@ -1865,8 +1877,8 @@ static int do_scsi_command(struct fsg_common *common)
|
||||||
|
|
||||||
case SC_READ_6:
|
case SC_READ_6:
|
||||||
i = common->cmnd[4];
|
i = common->cmnd[4];
|
||||||
common->data_size_from_cmnd = (i == 0 ? 256 : i) << 9;
|
common->data_size_from_cmnd = (i == 0 ? 256 : i);
|
||||||
reply = check_command(common, 6, DATA_DIR_TO_HOST,
|
reply = check_command_size_in_blocks(common, 6, DATA_DIR_TO_HOST,
|
||||||
(7<<1) | (1<<4), 1,
|
(7<<1) | (1<<4), 1,
|
||||||
"READ(6)");
|
"READ(6)");
|
||||||
if (reply == 0)
|
if (reply == 0)
|
||||||
|
@ -1875,8 +1887,8 @@ static int do_scsi_command(struct fsg_common *common)
|
||||||
|
|
||||||
case SC_READ_10:
|
case SC_READ_10:
|
||||||
common->data_size_from_cmnd =
|
common->data_size_from_cmnd =
|
||||||
get_unaligned_be16(&common->cmnd[7]) << 9;
|
get_unaligned_be16(&common->cmnd[7]);
|
||||||
reply = check_command(common, 10, DATA_DIR_TO_HOST,
|
reply = check_command_size_in_blocks(common, 10, DATA_DIR_TO_HOST,
|
||||||
(1<<1) | (0xf<<2) | (3<<7), 1,
|
(1<<1) | (0xf<<2) | (3<<7), 1,
|
||||||
"READ(10)");
|
"READ(10)");
|
||||||
if (reply == 0)
|
if (reply == 0)
|
||||||
|
@ -1885,8 +1897,8 @@ static int do_scsi_command(struct fsg_common *common)
|
||||||
|
|
||||||
case SC_READ_12:
|
case SC_READ_12:
|
||||||
common->data_size_from_cmnd =
|
common->data_size_from_cmnd =
|
||||||
get_unaligned_be32(&common->cmnd[6]) << 9;
|
get_unaligned_be32(&common->cmnd[6]);
|
||||||
reply = check_command(common, 12, DATA_DIR_TO_HOST,
|
reply = check_command_size_in_blocks(common, 12, DATA_DIR_TO_HOST,
|
||||||
(1<<1) | (0xf<<2) | (0xf<<6), 1,
|
(1<<1) | (0xf<<2) | (0xf<<6), 1,
|
||||||
"READ(12)");
|
"READ(12)");
|
||||||
if (reply == 0)
|
if (reply == 0)
|
||||||
|
@ -1983,8 +1995,8 @@ static int do_scsi_command(struct fsg_common *common)
|
||||||
|
|
||||||
case SC_WRITE_6:
|
case SC_WRITE_6:
|
||||||
i = common->cmnd[4];
|
i = common->cmnd[4];
|
||||||
common->data_size_from_cmnd = (i == 0 ? 256 : i) << 9;
|
common->data_size_from_cmnd = (i == 0 ? 256 : i);
|
||||||
reply = check_command(common, 6, DATA_DIR_FROM_HOST,
|
reply = check_command_size_in_blocks(common, 6, DATA_DIR_FROM_HOST,
|
||||||
(7<<1) | (1<<4), 1,
|
(7<<1) | (1<<4), 1,
|
||||||
"WRITE(6)");
|
"WRITE(6)");
|
||||||
if (reply == 0)
|
if (reply == 0)
|
||||||
|
@ -1993,8 +2005,8 @@ static int do_scsi_command(struct fsg_common *common)
|
||||||
|
|
||||||
case SC_WRITE_10:
|
case SC_WRITE_10:
|
||||||
common->data_size_from_cmnd =
|
common->data_size_from_cmnd =
|
||||||
get_unaligned_be16(&common->cmnd[7]) << 9;
|
get_unaligned_be16(&common->cmnd[7]);
|
||||||
reply = check_command(common, 10, DATA_DIR_FROM_HOST,
|
reply = check_command_size_in_blocks(common, 10, DATA_DIR_FROM_HOST,
|
||||||
(1<<1) | (0xf<<2) | (3<<7), 1,
|
(1<<1) | (0xf<<2) | (3<<7), 1,
|
||||||
"WRITE(10)");
|
"WRITE(10)");
|
||||||
if (reply == 0)
|
if (reply == 0)
|
||||||
|
@ -2003,8 +2015,8 @@ static int do_scsi_command(struct fsg_common *common)
|
||||||
|
|
||||||
case SC_WRITE_12:
|
case SC_WRITE_12:
|
||||||
common->data_size_from_cmnd =
|
common->data_size_from_cmnd =
|
||||||
get_unaligned_be32(&common->cmnd[6]) << 9;
|
get_unaligned_be32(&common->cmnd[6]);
|
||||||
reply = check_command(common, 12, DATA_DIR_FROM_HOST,
|
reply = check_command_size_in_blocks(common, 12, DATA_DIR_FROM_HOST,
|
||||||
(1<<1) | (0xf<<2) | (0xf<<6), 1,
|
(1<<1) | (0xf<<2) | (0xf<<6), 1,
|
||||||
"WRITE(12)");
|
"WRITE(12)");
|
||||||
if (reply == 0)
|
if (reply == 0)
|
||||||
|
@ -2497,7 +2509,7 @@ static struct fsg_common *fsg_common_init(struct fsg_common *common,
|
||||||
for (i = 0; i < nluns; i++) {
|
for (i = 0; i < nluns; i++) {
|
||||||
common->luns[i].removable = 1;
|
common->luns[i].removable = 1;
|
||||||
|
|
||||||
rc = fsg_lun_open(&common->luns[i], ums[i].num_sectors, "");
|
rc = fsg_lun_open(&common->luns[i], ums[i].num_sectors, ums->block_dev.blksz, "");
|
||||||
if (rc)
|
if (rc)
|
||||||
goto error_luns;
|
goto error_luns;
|
||||||
}
|
}
|
||||||
|
|
|
@ -269,6 +269,7 @@ struct device_attribute { int i; };
|
||||||
#define ETOOSMALL 525
|
#define ETOOSMALL 525
|
||||||
|
|
||||||
#include <log.h>
|
#include <log.h>
|
||||||
|
#include <linux/log2.h>
|
||||||
#include <usb_mass_storage.h>
|
#include <usb_mass_storage.h>
|
||||||
#include <dm/device_compat.h>
|
#include <dm/device_compat.h>
|
||||||
|
|
||||||
|
@ -290,6 +291,8 @@ struct fsg_lun {
|
||||||
u32 sense_data;
|
u32 sense_data;
|
||||||
u32 sense_data_info;
|
u32 sense_data_info;
|
||||||
u32 unit_attention_data;
|
u32 unit_attention_data;
|
||||||
|
unsigned int blkbits;
|
||||||
|
unsigned int blksize; /* logical block size of bound block device */
|
||||||
|
|
||||||
struct device dev;
|
struct device dev;
|
||||||
};
|
};
|
||||||
|
@ -566,7 +569,7 @@ static struct usb_gadget_strings fsg_stringtab = {
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static int fsg_lun_open(struct fsg_lun *curlun, unsigned int num_sectors,
|
static int fsg_lun_open(struct fsg_lun *curlun, unsigned int num_sectors,
|
||||||
const char *filename)
|
unsigned int sector_size, const char *filename)
|
||||||
{
|
{
|
||||||
int ro;
|
int ro;
|
||||||
|
|
||||||
|
@ -574,9 +577,12 @@ static int fsg_lun_open(struct fsg_lun *curlun, unsigned int num_sectors,
|
||||||
ro = curlun->initially_ro;
|
ro = curlun->initially_ro;
|
||||||
|
|
||||||
curlun->ro = ro;
|
curlun->ro = ro;
|
||||||
curlun->file_length = num_sectors << 9;
|
curlun->file_length = num_sectors * sector_size;
|
||||||
curlun->num_sectors = num_sectors;
|
curlun->num_sectors = num_sectors;
|
||||||
debug("open backing file: %s\n", filename);
|
curlun->blksize = sector_size;
|
||||||
|
curlun->blkbits = order_base_2(sector_size >> 9) + 9;
|
||||||
|
debug("blksize: %u\n", sector_size);
|
||||||
|
debug("open backing file: '%s'\n", filename);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -27,5 +27,4 @@ struct dwc3_omap_device {
|
||||||
|
|
||||||
int dwc3_omap_uboot_init(struct dwc3_omap_device *dev);
|
int dwc3_omap_uboot_init(struct dwc3_omap_device *dev);
|
||||||
void dwc3_omap_uboot_exit(int index);
|
void dwc3_omap_uboot_exit(int index);
|
||||||
int dwc3_omap_uboot_interrupt_status(struct udevice *dev);
|
|
||||||
#endif /* __DWC3_OMAP_UBOOT_H_ */
|
#endif /* __DWC3_OMAP_UBOOT_H_ */
|
||||||
|
|
|
@ -44,7 +44,7 @@ struct dwc3_device {
|
||||||
|
|
||||||
int dwc3_uboot_init(struct dwc3_device *dev);
|
int dwc3_uboot_init(struct dwc3_device *dev);
|
||||||
void dwc3_uboot_exit(int index);
|
void dwc3_uboot_exit(int index);
|
||||||
void dwc3_uboot_handle_interrupt(struct udevice *dev);
|
int dwc3_uboot_interrupt_status(struct udevice *dev);
|
||||||
|
|
||||||
struct phy;
|
struct phy;
|
||||||
#if CONFIG_IS_ENABLED(PHY) && CONFIG_IS_ENABLED(DM_USB)
|
#if CONFIG_IS_ENABLED(PHY) && CONFIG_IS_ENABLED(DM_USB)
|
||||||
|
|
|
@ -7,7 +7,6 @@
|
||||||
#ifndef __USB_MASS_STORAGE_H__
|
#ifndef __USB_MASS_STORAGE_H__
|
||||||
#define __USB_MASS_STORAGE_H__
|
#define __USB_MASS_STORAGE_H__
|
||||||
|
|
||||||
#define SECTOR_SIZE 0x200
|
|
||||||
#include <part.h>
|
#include <part.h>
|
||||||
#include <linux/usb/composite.h>
|
#include <linux/usb/composite.h>
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue