usb: gadget: f_tcm: Enhance UASP driver
Get series with b4
b4 am [email protected]Versions newest first
- v3 Latest28 patches 7 repliesIn review
Patches in v3 No applies recorded yet
| # | Subject and files | Size | Replies | Applied |
|---|---|---|---|---|
| 1/28 | usb: gadget: f_tcm: Don't free command immediatelydrivers/ | +0 | 0 replies | |
| 2/28 | usb: gadget: f_tcm: Translate error to sensedrivers/ | +2 | 0 replies | |
| 3/28 | usb: gadget: f_tcm: Decrement command ref count on cleanupdrivers/ | +1 | 0 replies | |
| 4/28 | usb: gadget: f_tcm: Fix Get/SetInterface return valuedrivers/ | +10 | 0 replies | |
| 5/28 | usb: gadget: f_tcm: ep_autoconfig with fullspeed endpointdrivers/ | +14 | 0 replies | |
| 6/28 | usb: gadget: f_tcm: Don't prepare BOT write request twicedrivers/ | +0 | 0 replies | |
| 7/28 | usb: gadget: f_tcm: Increase stream countdrivers/ | +1 | 0 replies | |
| 8/28 | usb: gadget: f_tcm: Increase bMaxBurstdrivers/ | +4 | 0 replies | |
| 9/28 | usb: gadget: f_tcm: Limit number of sessionsdrivers/ | +1 | 0 replies | |
| 10/28 | usb: gadget: f_tcm: Get stream by sbitmap numberdrivers/ drivers/ | +6 | 0 replies | |
| 11/28 | usb: gadget: f_tcm: Don't set static stream_iddrivers/ | +3 | 0 replies | |
| 12/28 | usb: gadget: f_tcm: Allocate matching number of commands to streamsdrivers/ drivers/ | +61 | 0 replies | |
| 13/28 | usb: gadget: f_tcm: Handle multiple commands in paralleldrivers/ | +8 | 0 replies | |
| 14/28 | usb: gadget: f_tcm: Use extra number of commandsdrivers/ | +1 | 0 replies | |
| 15/28 | usb: gadget: f_tcm: Return ATA cmd directiondrivers/ | +2 | 0 replies | |
| 16/28 | usb: gadget: f_tcm: Execute command on write completiondrivers/ drivers/ | +34 | 0 replies | |
| 17/28 | usb: gadget: f_tcm: Minor cleanup redundant codedrivers/ | +0 | 0 replies | |
| 18/28 | usb: gadget: f_tcm: Handle abort commanddrivers/ | +18 | 0 replies | |
| 19/28 | usb: gadget: f_tcm: Cleanup requests on ep disabledrivers/ | +13 | 0 replies | |
| 20/28 | usb: gadget: f_tcm: Stop proceeding further on -ESHUTDOWNdrivers/ | +7 | 0 replies | |
| 21/28 | usb: gadget: f_tcm: Save CPU ID per commanddrivers/ | +1 | 0 replies | |
| 22/28 | usb: gadget: f_tcm: Send sense on cancelled transferdrivers/ | +2 | 0 replies | |
| 23/28 | usb: gadget: f_tcm: Handle TASK_MANAGEMENT commandsdrivers/ drivers/ | +206 | 0 replies | |
| 24/28 | usb: gadget: f_tcm: Check overlapped commanddrivers/ drivers/ | +127 | 3 replies | |
| 25/28 | usb: gadget: f_tcm: Stall on invalid CBWdrivers/ drivers/ | +16 | 0 replies | |
| 26/28 | usb: gadget: f_tcm: Requeue command request on errordrivers/ | +6 | 0 replies | |
| 27/28 | usb: gadget: f_tcm: Track BOT command krefdrivers/ | +2 | 0 replies | |
| 28/28 | usb: gadget: f_tcm: Refactor goto check_conditiondrivers/ | +12 | 0 replies |
Reviews trailers per patch
No Reviewed-by, Acked-by or Tested-by trailers for v3 yet.
Cover letter [PATCH v3 00/28] usb: gadget: f_tcm: Enhance UASP driver
Apologies for the delay; after two years and multiple requests to resume this series, I squeezed some time to push an update. This series applies on top of Greg's usb-testing branch.
If possible, please help test this series and get this merged as my resources are nil for this work.
Example Bringup Steps
=====================
To test UASP, here's an example perl script snippet to bring it up.
Note: the script was cut down and quickly rewritten, so sorry if I make mistakes.
my $MY_UAS_VID = xxxx;
my $MY_UAS_PID = yyyy;
my $SERIAL = "1234";
my $VENDOR = "VENDOR";
my $MY_VER = "VER";
my $vendor_id = "my_vid";
my $product_id = "my_pid";
my $revision = "my_rev";
# Must update:
my $backing_storage = "/tmp/some_file";
my $backing_storage_size = 1024*1024*16;
my $use_ramdisk = 0;
my $g = "/sys/kernel/config/usb_gadget/g1";
system("modprobe libcomposite");
system("modprobe usb_f_tcm");
system("mkdir -p $g");
system("mkdir -p $g/configs/c.1");
system("mkdir -p $g/functions/tcm.0");
system("mkdir -p $g/strings/0x409");
system("mkdir -p $g/configs/c.1/strings/0x409");
my $tp = "/sys/kernel/config/target/usb_gadget/naa.0/tpgt_1";
my $tf;
my $ctrl;
if ($use_ramdisk) {
$tf = "/sys/kernel/config/target/core/rd_mcp_0/ramdisk";
$ctrl = 'rd_pages=524288';
} else {
$tf = "/sys/kernel/config/target/core/fileio_0/fileio";
$ctrl = 'fd_dev_name=$backing_storage,fd_dev_size=$backing_storage_size,fd_async_io=1';
}
system("mkdir -p /etc/target");
system("mkdir -p $tp");
system("mkdir -p $tf");
system("mkdir -p $tp/lun/lun_0");
system("echo naa.0 > $tp/nexus");
system("echo $ctrl > $tf/control");
system("echo 1 > $tf/attrib/emulate_ua_intlck_ctrl");
system("echo 123 > $tf/wwn/vpd_unit_serial");
system("echo $vendor_id > $tf/wwn/vendor_id");
system("echo $product_id > $tf/wwn/product_id");
system("echo $revision > $tf/wwn/revision");
system("echo 1 > $tf/enable");
system("ln -s $tf $tp/lun/lun_0/virtual_scsi_port");
system("echo 1 > $tp/enable");
system("echo $MY_UAS_PID > $g/idProduct");
system("ln -s $g/functions/tcm.0 $g/configs/c.1");
system("echo $MY_UAS_VID > $g/idVendor");
system("echo $SERIAL > $g/strings/0x409/serialnumber");
system("echo $VENDOR > $g/strings/0x409/manufacturer");
system("echo \"$MY_VER\" > $g/strings/0x409/product");
system("echo \"Conf 1\" > $g/configs/c.1/strings/0x409/configuration");
system("echo super-speed-plus > $g/max_speed");
# Make sure the UDC is available
system("echo $my_udc > $g/UDC");Target Subsystem Fixes
======================
I have eliminated unnecessary changes related to the Target subsystem and reworked f_tcm to minimize the modifications required in the Target subsystem. There are unimplemented Task Management Requests in the Target subsystem, but the basic flow should still work.
Regardless, you should still need to apply at least these 2 fixes:
1) Fix Data Corruption
----------------------
Properly increment the "len" base on the command requested length instead of the SG entry length.
If you're using File backend, then you need to fix target_core_file. If you're using other backend such as Ramdisk, then you need a similar fix there.
--- drivers/target/target_core_file.c | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-)
drivers/target/target_core_file.c +12 -2
@@ -283,7 +283,12 @@ fd_execute_rw_aio(struct se_cmd *cmd, struct scatterlist *sgl, u32 sgl_nents,for_each_sg (sgl, sg, sgl_nents, i) {bvec_set_page (&aio_cmd->bvecs[i],sg_page (sg), sg->length, sg->offset); - len += sg->length; +if (len + sg->length >= cmd->data_length) { + len = cmd->data_length; +break ; + }else { + len += sg->length; + } }iov_iter_bvec (&iter, is_write, aio_cmd->bvecs, sgl_nents, len);
@@ -328,7 +333,12 @@ static int fd_do_rw(struct se_cmd *cmd, struct file *fd,for_each_sg (sgl, sg, sgl_nents, i) {bvec_set_page (&bvec[i],sg_page (sg), sg->length, sg->offset); - len += sg->length; +if (len + sg->length >= data_length) { + len = data_length; +break ; + }else { + len += sg->length; + } }iov_iter_bvec (&iter, is_write, bvec, sgl_nents, len);
Signature · 13 lines
2) Fix Sense Data Length ------------------------ The transport_get_sense_buffer() and transport_copy_sense_to_cmd() take sense data length to be the allocated sense buffer length TRANSPORT_SENSE_BUFFER. However, the sense data length is depending on the sense data description. Check the sense data to set the proper cmd->scsi_sense_length. See SPC4-r37 section 4.5.2.1. --- drivers/target/target_core_transport.c | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-)
drivers/target/target_core_transport.c +15 -4
@@ -804,8 +804,6 @@ static unsigned char *transport_get_sense_buffer(struct se_cmd *cmd)if (cmd->se_cmd_flags &SCF_SENT_CHECK_CONDITION )return NULL ; - cmd->scsi_sense_length =TRANSPORT_SENSE_BUFFER ; -pr_debug ("HBA_[%u]_PLUG[%s]: Requesting sense for SAM STATUS: 0x%02x\n" , dev->se_hba->hba_id, dev->transport->name, cmd->scsi_status);return cmd->sense_buffer;
@@ -824,7 +822,13 @@ void transport_copy_sense_to_cmd(struct se_cmd *cmd, unsigned char *sense) } cmd->se_cmd_flags |=SCF_TRANSPORT_TASK_SENSE ; + +/* Sense data length = min sense data + additional sense data length */ + cmd->scsi_sense_length =min_t (u16, cmd_sense_buf[7 ] +8 , +TRANSPORT_SENSE_BUFFER ); +memcpy (cmd_sense_buf, sense, cmd->scsi_sense_length); +spin_unlock_irqrestore (&cmd->t_state_lock, flags); }EXPORT_SYMBOL (transport_copy_sense_to_cmd);
@@ -3521,12 +3525,19 @@ static void translate_sense_reason(struct se_cmd *cmd, sense_reason_t reason) cmd->se_cmd_flags |=SCF_EMULATED_TASK_SENSE ; cmd->scsi_status =SAM_STAT_CHECK_CONDITION ; - cmd->scsi_sense_length =TRANSPORT_SENSE_BUFFER ; +scsi_build_sense_buffer (desc_format, buffer, key, asc, ascq);if (sd->add_sense_info)WARN_ON_ONCE (scsi_set_sense_information (buffer, - cmd->scsi_sense_length, +TRANSPORT_SENSE_BUFFER , cmd->sense_info) <0 ); +/* +* CHECK CONDITION returns sense data, and sense data is minimum 8 +* bytes long plus additional Sense Data Length. +* See SPC4-r37 section 4.5.2.1. +*/ + cmd->scsi_sense_length =min_t (u16, buffer[7 ] +8 , +TRANSPORT_SENSE_BUFFER ); }int
Signature · 47 lines
Changes in v3: - v2: https://lore.kernel.org/linux-usb/[email protected]/ - Moved patches around so fixes patches go first - Use hashtable to map tag to uas stream - Move target_execute_cmd() out of interrupt context - Various cleanup - Additional fixes over the 2 years Thinh Nguyen (28): usb: gadget: f_tcm: Don't free command immediately usb: gadget: f_tcm: Translate error to sense usb: gadget: f_tcm: Decrement command ref count on cleanup usb: gadget: f_tcm: Fix Get/SetInterface return value usb: gadget: f_tcm: ep_autoconfig with fullspeed endpoint usb: gadget: f_tcm: Don't prepare BOT write request twice usb: gadget: f_tcm: Increase stream count usb: gadget: f_tcm: Increase bMaxBurst usb: gadget: f_tcm: Limit number of sessions usb: gadget: f_tcm: Get stream by sbitmap number usb: gadget: f_tcm: Don't set static stream_id usb: gadget: f_tcm: Allocate matching number of commands to streams usb: gadget: f_tcm: Handle multiple commands in parallel usb: gadget: f_tcm: Use extra number of commands usb: gadget: f_tcm: Return ATA cmd direction usb: gadget: f_tcm: Execute command on write completion usb: gadget: f_tcm: Minor cleanup redundant code usb: gadget: f_tcm: Handle abort command usb: gadget: f_tcm: Cleanup requests on ep disable usb: gadget: f_tcm: Stop proceeding further on -ESHUTDOWN usb: gadget: f_tcm: Save CPU ID per command usb: gadget: f_tcm: Send sense on cancelled transfer usb: gadget: f_tcm: Handle TASK_MANAGEMENT commands usb: gadget: f_tcm: Check overlapped command usb: gadget: f_tcm: Stall on invalid CBW usb: gadget: f_tcm: Requeue command request on error usb: gadget: f_tcm: Track BOT command kref usb: gadget: f_tcm: Refactor goto check_condition drivers/usb/gadget/function/f_tcm.c | 711 ++++++++++++++++++++-------- drivers/usb/gadget/function/tcm.h | 28 +- 2 files changed, 547 insertions(+), 192 deletions(-) base-commit: d8d936c51388442f769a81e512b505dcf87c6a51 -- 2.28.0