gadget: rockusb: Support rkusb_do_erase_force

Change-Id: Ia18c5a8414411044a72858d83ccddec63ac83e70
Signed-off-by: Jon Lin <jon.lin@rock-chips.com>
This commit is contained in:
Jon Lin 2020-10-30 21:27:40 +08:00 committed by Jianhong Chen
parent 3f04f6e376
commit e66d4537db
1 changed files with 91 additions and 6 deletions

View File

@ -9,6 +9,7 @@
#include <asm/arch/boot_mode.h>
#include <asm/arch/chip_info.h>
#include <write_keybox.h>
#include <linux/mtd/mtd.h>
#ifdef CONFIG_ROCKCHIP_VENDOR_PARTITION
#include <asm/arch/vendor.h>
@ -20,6 +21,9 @@
#define ROCKUSB_INTERFACE_SUB_CLASS 0x06
#define ROCKUSB_INTERFACE_PROTOCOL 0x05
#define ROCKCHIP_FLASH_BLOCK_SIZE 1024
#define ROCKCHIP_FLASH_PAGE_SIZE 4
static struct usb_interface_descriptor rkusb_intf_desc = {
.bLength = USB_DT_INTERFACE_SIZE,
.bDescriptorType = USB_DT_INTERFACE,
@ -209,18 +213,34 @@ static int rkusb_do_test_bad_block(struct fsg_common *common,
static int rkusb_do_read_flash_info(struct fsg_common *common,
struct fsg_buffhd *bh)
{
struct blk_desc *desc = &ums[common->lun].block_dev;
u8 *buf = (u8 *)bh->buf;
u32 len = sizeof(struct rk_flash_info);
struct rk_flash_info finfo = {
.block_size = 1024,
.block_size = ROCKCHIP_FLASH_BLOCK_SIZE,
.ecc_bits = 0,
.page_size = 4,
.page_size = ROCKCHIP_FLASH_PAGE_SIZE,
.access_time = 40,
.manufacturer = 0,
.flash_mask = 0
};
finfo.flash_size = (u32)ums[common->lun].block_dev.lba;
finfo.flash_size = (u32)desc->lba;
if (desc->if_type == IF_TYPE_MTD &&
(desc->devnum == BLK_MTD_NAND ||
desc->devnum == BLK_MTD_SPI_NAND)) {
struct mtd_info *mtd = (struct mtd_info *)desc->bdev->priv;
if (mtd) {
finfo.block_size = mtd->erasesize >> 9;
finfo.page_size = mtd->writesize >> 9;
}
}
debug("Flash info: block_size= %x page_size= %x\n", finfo.block_size,
finfo.page_size);
if (finfo.flash_size)
finfo.flash_mask = 1;
@ -293,6 +313,60 @@ out:
return rc;
}
static int rkusb_do_erase_force(struct fsg_common *common,
struct fsg_buffhd *bh)
{
struct blk_desc *desc = &ums[common->lun].block_dev;
struct fsg_lun *curlun = &common->luns[common->lun];
u16 block_size = ROCKCHIP_FLASH_BLOCK_SIZE;
u32 lba, amount;
loff_t file_offset;
int rc;
lba = get_unaligned_be32(&common->cmnd[2]);
if (lba >= curlun->num_sectors) {
curlun->sense_data = SS_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE;
rc = -EINVAL;
goto out;
}
if (desc->if_type == IF_TYPE_MTD &&
(desc->devnum == BLK_MTD_NAND ||
desc->devnum == BLK_MTD_SPI_NAND)) {
struct mtd_info *mtd = (struct mtd_info *)desc->bdev->priv;
if (mtd)
block_size = mtd->erasesize >> 9;
}
file_offset = ((loff_t)lba) * block_size;
amount = get_unaligned_be16(&common->cmnd[7]) * block_size;
debug("%s lba= %x, nsec= %x\n", __func__, lba,
(u32)get_unaligned_be16(&common->cmnd[7]));
if (unlikely(amount == 0)) {
curlun->sense_data = SS_INVALID_FIELD_IN_CDB;
rc = -EIO;
goto out;
}
/* Perform the erase */
rc = ums[common->lun].erase_sector(&ums[common->lun],
file_offset,
amount);
if (!rc) {
curlun->sense_data = SS_MEDIUM_NOT_PRESENT;
rc = -EIO;
}
out:
common->data_dir = DATA_DIR_NONE;
bh->state = BUF_STATE_EMPTY;
return rc;
}
#ifdef CONFIG_ROCKCHIP_VENDOR_PARTITION
static int rkusb_do_vs_write(struct fsg_common *common)
{
@ -464,11 +538,12 @@ static int rkusb_do_vs_read(struct fsg_common *common)
#endif
static int rkusb_do_read_capacity(struct fsg_common *common,
struct fsg_buffhd *bh)
struct fsg_buffhd *bh)
{
u8 *buf = (u8 *)bh->buf;
u32 len = common->data_size;
enum if_type type = ums[common->lun].block_dev.if_type;
int devnum = ums[common->lun].block_dev.devnum;
/*
* bit[0]: Direct LBA, 0: Disabled;
@ -484,8 +559,14 @@ static int rkusb_do_read_capacity(struct fsg_common *common,
else
buf[0] = BIT(0) | BIT(4);
if (type == IF_TYPE_MTD &&
(devnum == BLK_MTD_NAND ||
devnum == BLK_MTD_SPI_NAND))
buf[0] |= (1 << 6);
/* Set data xfer size */
common->residue = common->data_size_from_cmnd = len;
common->residue = len;
common->data_size_from_cmnd = len;
return len;
}
@ -545,6 +626,11 @@ static int rkusb_cmd_process(struct fsg_common *common,
rc = RKUSB_RC_FINISHED;
break;
case RKUSB_ERASE_10_FORCE:
*reply = rkusb_do_erase_force(common, bh);
rc = RKUSB_RC_FINISHED;
break;
case RKUSB_LBA_READ_10:
rkusb_fixup_cbwcb(common, bh);
common->cmnd[0] = SC_READ_10;
@ -603,7 +689,6 @@ static int rkusb_cmd_process(struct fsg_common *common,
case RKUSB_ERASE_10:
case RKUSB_WRITE_SPARE:
case RKUSB_READ_SPARE:
case RKUSB_ERASE_10_FORCE:
case RKUSB_GET_VERSION:
case RKUSB_ERASE_SYS_DISK:
case RKUSB_SDRAM_READ_10: