usb: Update the test to cover reading and writing
Add test coverage for blk_write() as well. The blk_erase() is not tested for now as the USB stor interface does not support erase. Signed-off-by: Simon Glass <sjg@chromium.org>
This commit is contained in:
parent
606b926f9d
commit
2ff3db3a1c
@ -62,6 +62,15 @@ int sb_scsi_emul_command(struct scsi_emul_info *info,
|
|||||||
ret = SCSI_EMUL_DO_READ;
|
ret = SCSI_EMUL_DO_READ;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case SCSI_WRITE10: {
|
||||||
|
const struct scsi_write10_req *write_req = (void *)req;
|
||||||
|
|
||||||
|
info->seek_block = be32_to_cpu(write_req->lba);
|
||||||
|
info->write_len = be16_to_cpu(write_req->xfer_len);
|
||||||
|
info->buff_used = info->write_len * info->block_size;
|
||||||
|
ret = SCSI_EMUL_DO_WRITE;
|
||||||
|
break;
|
||||||
|
}
|
||||||
default:
|
default:
|
||||||
debug("Command not supported: %x\n", req->cmd[0]);
|
debug("Command not supported: %x\n", req->cmd[0]);
|
||||||
ret = -EPROTONOSUPPORT;
|
ret = -EPROTONOSUPPORT;
|
||||||
|
@ -4,6 +4,8 @@
|
|||||||
* Written by Simon Glass <sjg@chromium.org>
|
* Written by Simon Glass <sjg@chromium.org>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#define LOG_CATEGORY UCLASS_USB
|
||||||
|
|
||||||
#include <common.h>
|
#include <common.h>
|
||||||
#include <dm.h>
|
#include <dm.h>
|
||||||
#include <log.h>
|
#include <log.h>
|
||||||
@ -190,7 +192,8 @@ static int handle_ufi_command(struct sandbox_flash_priv *priv, const void *buff,
|
|||||||
ret = sb_scsi_emul_command(info, req, len);
|
ret = sb_scsi_emul_command(info, req, len);
|
||||||
if (!ret) {
|
if (!ret) {
|
||||||
setup_response(priv);
|
setup_response(priv);
|
||||||
} else if (ret == SCSI_EMUL_DO_READ && priv->fd != -1) {
|
} else if ((ret == SCSI_EMUL_DO_READ || ret == SCSI_EMUL_DO_WRITE) &&
|
||||||
|
priv->fd != -1) {
|
||||||
os_lseek(priv->fd, info->seek_block * info->block_size,
|
os_lseek(priv->fd, info->seek_block * info->block_size,
|
||||||
OS_SEEK_SET);
|
OS_SEEK_SET);
|
||||||
setup_response(priv);
|
setup_response(priv);
|
||||||
@ -217,6 +220,7 @@ static int sandbox_flash_bulk(struct udevice *dev, struct usb_device *udev,
|
|||||||
case SCSIPH_START:
|
case SCSIPH_START:
|
||||||
info->alloc_len = 0;
|
info->alloc_len = 0;
|
||||||
info->read_len = 0;
|
info->read_len = 0;
|
||||||
|
info->write_len = 0;
|
||||||
if (priv->error || len != UMASS_BBB_CBW_SIZE ||
|
if (priv->error || len != UMASS_BBB_CBW_SIZE ||
|
||||||
cbw->dCBWSignature != CBWSIGNATURE)
|
cbw->dCBWSignature != CBWSIGNATURE)
|
||||||
goto err;
|
goto err;
|
||||||
@ -230,8 +234,31 @@ static int sandbox_flash_bulk(struct udevice *dev, struct usb_device *udev,
|
|||||||
return handle_ufi_command(priv, cbw->CBWCDB,
|
return handle_ufi_command(priv, cbw->CBWCDB,
|
||||||
cbw->bCDBLength);
|
cbw->bCDBLength);
|
||||||
case SCSIPH_DATA:
|
case SCSIPH_DATA:
|
||||||
debug("data out\n");
|
log_debug("data out, len=%x, info->write_len=%x\n", len,
|
||||||
break;
|
info->write_len);
|
||||||
|
info->transfer_len = cbw->dCBWDataTransferLength;
|
||||||
|
priv->tag = cbw->dCBWTag;
|
||||||
|
if (!info->write_len)
|
||||||
|
return 0;
|
||||||
|
if (priv->fd != -1) {
|
||||||
|
ulong bytes_written;
|
||||||
|
|
||||||
|
bytes_written = os_write(priv->fd, buff, len);
|
||||||
|
log_debug("bytes_written=%lx", bytes_written);
|
||||||
|
if (bytes_written != len)
|
||||||
|
return -EIO;
|
||||||
|
info->write_len -= len / info->block_size;
|
||||||
|
if (!info->write_len)
|
||||||
|
info->phase = SCSIPH_STATUS;
|
||||||
|
} else {
|
||||||
|
if (info->alloc_len && len > info->alloc_len)
|
||||||
|
len = info->alloc_len;
|
||||||
|
if (len > SANDBOX_FLASH_BUF_SIZE)
|
||||||
|
len = SANDBOX_FLASH_BUF_SIZE;
|
||||||
|
memcpy(info->buff, buff, len);
|
||||||
|
info->phase = SCSIPH_STATUS;
|
||||||
|
}
|
||||||
|
return len;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -310,7 +337,7 @@ static int sandbox_flash_probe(struct udevice *dev)
|
|||||||
struct scsi_emul_info *info = &priv->eminfo;
|
struct scsi_emul_info *info = &priv->eminfo;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
priv->fd = os_open(plat->pathname, OS_O_RDONLY);
|
priv->fd = os_open(plat->pathname, OS_O_RDWR);
|
||||||
if (priv->fd != -1) {
|
if (priv->fd != -1) {
|
||||||
ret = os_get_filesize(plat->pathname, &info->file_size);
|
ret = os_get_filesize(plat->pathname, &info->file_size);
|
||||||
if (ret)
|
if (ret)
|
||||||
|
@ -255,6 +255,16 @@ struct __packed scsi_read10_req {
|
|||||||
u8 spare2[3];
|
u8 spare2[3];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/** struct scsi_write10_req - data for the write10 command */
|
||||||
|
struct __packed scsi_write10_req {
|
||||||
|
u8 cmd;
|
||||||
|
u8 lun_flags;
|
||||||
|
u32 lba;
|
||||||
|
u8 spare;
|
||||||
|
u16 xfer_len;
|
||||||
|
u8 spare2[3];
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* struct scsi_plat - stores information about SCSI controller
|
* struct scsi_plat - stores information about SCSI controller
|
||||||
*
|
*
|
||||||
|
@ -41,13 +41,20 @@ struct scsi_emul_info {
|
|||||||
enum scsi_cmd_phase phase;
|
enum scsi_cmd_phase phase;
|
||||||
int buff_used;
|
int buff_used;
|
||||||
int read_len;
|
int read_len;
|
||||||
|
int write_len;
|
||||||
uint seek_pos;
|
uint seek_pos;
|
||||||
int alloc_len;
|
int alloc_len;
|
||||||
uint transfer_len;
|
uint transfer_len;
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Indicates that a read is being started */
|
/**
|
||||||
#define SCSI_EMUL_DO_READ 1
|
* Return value from sb_scsi_emul_command() indicates that a read or write is
|
||||||
|
* being started
|
||||||
|
*/
|
||||||
|
enum {
|
||||||
|
SCSI_EMUL_DO_READ = 1,
|
||||||
|
SCSI_EMUL_DO_WRITE = 2,
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* sb_scsi_emul_command() - Process a SCSI command
|
* sb_scsi_emul_command() - Process a SCSI command
|
||||||
@ -61,8 +68,9 @@ struct scsi_emul_info {
|
|||||||
* @info: Emulation information
|
* @info: Emulation information
|
||||||
* @req: Request to process
|
* @req: Request to process
|
||||||
* @len: Length of request in bytes
|
* @len: Length of request in bytes
|
||||||
* @return SCSI_EMUL_DO_READ if a read has started, 0 if some other operation
|
* @return SCSI_EMUL_DO_READ if a read has started, SCSI_EMUL_DO_WRITE if a
|
||||||
* has started, -ve if there was an error
|
* write has started, 0 if some other operation has started, -ve if there
|
||||||
|
* was an error
|
||||||
*/
|
*/
|
||||||
int sb_scsi_emul_command(struct scsi_emul_info *info,
|
int sb_scsi_emul_command(struct scsi_emul_info *info,
|
||||||
const struct scsi_cmd *req, int len);
|
const struct scsi_cmd *req, int len);
|
||||||
|
@ -61,7 +61,24 @@ static int dm_test_usb_flash(struct unit_test_state *uts)
|
|||||||
ut_asserteq(512, dev_desc->blksz);
|
ut_asserteq(512, dev_desc->blksz);
|
||||||
memset(cmp, '\0', sizeof(cmp));
|
memset(cmp, '\0', sizeof(cmp));
|
||||||
ut_asserteq(2, blk_read(blk, 0, 2, cmp));
|
ut_asserteq(2, blk_read(blk, 0, 2, cmp));
|
||||||
ut_assertok(strcmp(cmp, "this is a test"));
|
ut_asserteq_str("this is a test", cmp);
|
||||||
|
|
||||||
|
strcpy(cmp, "another test");
|
||||||
|
ut_asserteq(1, blk_write(blk, 1, 1, cmp));
|
||||||
|
|
||||||
|
memset(cmp, '\0', sizeof(cmp));
|
||||||
|
ut_asserteq(2, blk_read(blk, 0, 2, cmp));
|
||||||
|
ut_asserteq_str("this is a test", cmp);
|
||||||
|
ut_asserteq_str("another test", cmp + 512);
|
||||||
|
|
||||||
|
memset(cmp, '\0', sizeof(cmp));
|
||||||
|
ut_asserteq(1, blk_write(blk, 1, 1, cmp));
|
||||||
|
|
||||||
|
memset(cmp, '\0', sizeof(cmp));
|
||||||
|
ut_asserteq(2, blk_read(blk, 0, 2, cmp));
|
||||||
|
ut_asserteq_str("this is a test", cmp);
|
||||||
|
ut_asserteq_str("", cmp + 512);
|
||||||
|
|
||||||
ut_assertok(usb_stop());
|
ut_assertok(usb_stop());
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
Loading…
Reference in New Issue
Block a user