aboutsummaryrefslogtreecommitdiff
path: root/drivers/usb/gadget/tcm_usb_gadget.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/usb/gadget/tcm_usb_gadget.c')
-rw-r--r--drivers/usb/gadget/tcm_usb_gadget.c183
1 files changed, 88 insertions, 95 deletions
diff --git a/drivers/usb/gadget/tcm_usb_gadget.c b/drivers/usb/gadget/tcm_usb_gadget.c
index c46439c8dd7..6cdb7a534f2 100644
--- a/drivers/usb/gadget/tcm_usb_gadget.c
+++ b/drivers/usb/gadget/tcm_usb_gadget.c
@@ -25,13 +25,10 @@
#include <target/configfs_macros.h>
#include <asm/unaligned.h>
-#include "usbstring.c"
-#include "epautoconf.c"
-#include "config.c"
-#include "composite.c"
-
#include "tcm_usb_gadget.h"
+USB_GADGET_COMPOSITE_OPTIONS();
+
static struct target_fabric_configfs *usbg_fabric_configfs;
static inline struct f_uas *to_f_uas(struct usb_function *f)
@@ -294,7 +291,7 @@ static int bot_send_write_request(struct usbg_cmd *cmd)
pr_err("%s(%d)\n", __func__, __LINE__);
wait_for_completion(&cmd->write_complete);
- transport_generic_process_write(se_cmd);
+ target_execute_cmd(se_cmd);
cleanup:
return ret;
}
@@ -373,7 +370,7 @@ err:
return -ENOMEM;
}
-void bot_cleanup_old_alt(struct f_uas *fu)
+static void bot_cleanup_old_alt(struct f_uas *fu)
{
if (!(fu->flags & USBG_ENABLED))
return;
@@ -475,7 +472,7 @@ static int usbg_bot_setup(struct usb_function *f,
bot_enqueue_cmd_cbw(fu);
return 0;
break;
- };
+ }
return -ENOTSUPP;
}
@@ -620,7 +617,7 @@ static void uasp_status_data_cmpl(struct usb_ep *ep, struct usb_request *req)
default:
BUG();
- };
+ }
return;
cleanup:
@@ -725,7 +722,7 @@ static int uasp_send_write_request(struct usbg_cmd *cmd)
}
wait_for_completion(&cmd->write_complete);
- transport_generic_process_write(se_cmd);
+ target_execute_cmd(se_cmd);
cleanup:
return ret;
}
@@ -1065,16 +1062,20 @@ static void usbg_cmd_work(struct work_struct *work)
tv_nexus->tvn_se_sess->se_tpg->se_tpg_tfo,
tv_nexus->tvn_se_sess, cmd->data_len, DMA_NONE,
cmd->prio_attr, cmd->sense_iu.sense);
-
- transport_send_check_condition_and_sense(se_cmd,
- TCM_UNSUPPORTED_SCSI_OPCODE, 1);
- usbg_cleanup_cmd(cmd);
- return;
+ goto out;
}
- target_submit_cmd(se_cmd, tv_nexus->tvn_se_sess,
+ if (target_submit_cmd(se_cmd, tv_nexus->tvn_se_sess,
cmd->cmd_buf, cmd->sense_iu.sense, cmd->unpacked_lun,
- 0, cmd->prio_attr, dir, TARGET_SCF_UNKNOWN_SIZE);
+ 0, cmd->prio_attr, dir, TARGET_SCF_UNKNOWN_SIZE) < 0)
+ goto out;
+
+ return;
+
+out:
+ transport_send_check_condition_and_sense(se_cmd,
+ TCM_UNSUPPORTED_SCSI_OPCODE, 1);
+ usbg_cleanup_cmd(cmd);
}
static int usbg_submit_command(struct f_uas *fu,
@@ -1177,16 +1178,20 @@ static void bot_cmd_work(struct work_struct *work)
tv_nexus->tvn_se_sess->se_tpg->se_tpg_tfo,
tv_nexus->tvn_se_sess, cmd->data_len, DMA_NONE,
cmd->prio_attr, cmd->sense_iu.sense);
-
- transport_send_check_condition_and_sense(se_cmd,
- TCM_UNSUPPORTED_SCSI_OPCODE, 1);
- usbg_cleanup_cmd(cmd);
- return;
+ goto out;
}
- target_submit_cmd(se_cmd, tv_nexus->tvn_se_sess,
+ if (target_submit_cmd(se_cmd, tv_nexus->tvn_se_sess,
cmd->cmd_buf, cmd->sense_iu.sense, cmd->unpacked_lun,
- cmd->data_len, cmd->prio_attr, dir, 0);
+ cmd->data_len, cmd->prio_attr, dir, 0) < 0)
+ goto out;
+
+ return;
+
+out:
+ transport_send_check_condition_and_sense(se_cmd,
+ TCM_UNSUPPORTED_SCSI_OPCODE, 1);
+ usbg_cleanup_cmd(cmd);
}
static int bot_submit_command(struct f_uas *fu,
@@ -1378,10 +1383,8 @@ static struct se_node_acl *usbg_alloc_fabric_acl(struct se_portal_group *se_tpg)
struct usbg_nacl *nacl;
nacl = kzalloc(sizeof(struct usbg_nacl), GFP_KERNEL);
- if (!nacl) {
- printk(KERN_ERR "Unable to alocate struct usbg_nacl\n");
+ if (!nacl)
return NULL;
- }
return &nacl->se_node_acl;
}
@@ -1400,19 +1403,6 @@ static u32 usbg_tpg_get_inst_index(struct se_portal_group *se_tpg)
return 1;
}
-static int usbg_new_cmd(struct se_cmd *se_cmd)
-{
- struct usbg_cmd *cmd = container_of(se_cmd, struct usbg_cmd,
- se_cmd);
- int ret;
-
- ret = target_setup_cmd_from_cdb(se_cmd, cmd->cmd_buf);
- if (ret)
- return ret;
-
- return transport_generic_map_mem_to_cmd(se_cmd, NULL, 0, NULL, 0);
-}
-
static void usbg_cmd_release(struct kref *ref)
{
struct usbg_cmd *cmd = container_of(ref, struct usbg_cmd,
@@ -1475,19 +1465,13 @@ static int usbg_get_cmd_state(struct se_cmd *se_cmd)
return 0;
}
-static int usbg_queue_tm_rsp(struct se_cmd *se_cmd)
-{
- return 0;
-}
-
-static u16 usbg_set_fabric_sense_len(struct se_cmd *se_cmd, u32 sense_length)
+static void usbg_queue_tm_rsp(struct se_cmd *se_cmd)
{
- return 0;
}
-static u16 usbg_get_fabric_sense_len(void)
+static void usbg_aborted_task(struct se_cmd *se_cmd)
{
- return 0;
+ return;
}
static const char *usbg_check_wwn(const char *name)
@@ -1575,10 +1559,8 @@ static struct se_portal_group *usbg_make_tpg(
}
tpg = kzalloc(sizeof(struct usbg_tpg), GFP_KERNEL);
- if (!tpg) {
- printk(KERN_ERR "Unable to allocate struct usbg_tpg");
+ if (!tpg)
return ERR_PTR(-ENOMEM);
- }
mutex_init(&tpg->tpg_mutex);
atomic_set(&tpg->tpg_port_count, 0);
tpg->workqueue = alloc_workqueue("tcm_usb_gadget", 0, 1);
@@ -1627,12 +1609,10 @@ static struct se_wwn *usbg_make_tport(
return ERR_PTR(-EINVAL);
tport = kzalloc(sizeof(struct usbg_tport), GFP_KERNEL);
- if (!(tport)) {
- printk(KERN_ERR "Unable to allocate struct usbg_tport");
+ if (!(tport))
return ERR_PTR(-ENOMEM);
- }
tport->tport_wwpn = wwpn;
- snprintf(tport->tport_name, sizeof(tport->tport_name), wnn_name);
+ snprintf(tport->tport_name, sizeof(tport->tport_name), "%s", wnn_name);
return &tport->tport_wwn;
}
@@ -1741,11 +1721,9 @@ static int tcm_usbg_make_nexus(struct usbg_tpg *tpg, char *name)
ret = -ENOMEM;
tv_nexus = kzalloc(sizeof(*tv_nexus), GFP_KERNEL);
- if (!tv_nexus) {
- pr_err("Unable to allocate struct tcm_vhost_nexus\n");
+ if (!tv_nexus)
goto err_unlock;
- }
- tv_nexus->tvn_se_sess = transport_init_session();
+ tv_nexus->tvn_se_sess = transport_init_session(TARGET_PROT_NORMAL);
if (IS_ERR(tv_nexus->tvn_se_sess))
goto err_free;
@@ -1812,9 +1790,10 @@ static int tcm_usbg_drop_nexus(struct usbg_tpg *tpg)
tpg->tpg_nexus = NULL;
kfree(tv_nexus);
+ ret = 0;
out:
mutex_unlock(&tpg->tpg_mutex);
- return 0;
+ return ret;
}
static ssize_t tcm_usbg_tpg_store_nexus(
@@ -1830,7 +1809,7 @@ static ssize_t tcm_usbg_tpg_store_nexus(
ret = tcm_usbg_drop_nexus(tpg);
return (!ret) ? count : ret;
}
- if (strlen(page) > USBG_NAMELEN) {
+ if (strlen(page) >= USBG_NAMELEN) {
pr_err("Emulated NAA Sas Address: %s, exceeds"
" max: %d\n", page, USBG_NAMELEN);
return -EINVAL;
@@ -1864,7 +1843,7 @@ static int usbg_port_link(struct se_portal_group *se_tpg, struct se_lun *lun)
struct usbg_tpg *tpg = container_of(se_tpg, struct usbg_tpg, se_tpg);
atomic_inc(&tpg->tpg_port_count);
- smp_mb__after_atomic_inc();
+ smp_mb__after_atomic();
return 0;
}
@@ -1874,7 +1853,7 @@ static void usbg_port_unlink(struct se_portal_group *se_tpg,
struct usbg_tpg *tpg = container_of(se_tpg, struct usbg_tpg, se_tpg);
atomic_dec(&tpg->tpg_port_count);
- smp_mb__after_atomic_dec();
+ smp_mb__after_atomic();
}
static int usbg_check_stop_free(struct se_cmd *se_cmd)
@@ -1902,7 +1881,6 @@ static struct target_core_fabric_ops usbg_ops = {
.tpg_alloc_fabric_acl = usbg_alloc_fabric_acl,
.tpg_release_fabric_acl = usbg_release_fabric_acl,
.tpg_get_inst_index = usbg_tpg_get_inst_index,
- .new_cmd_map = usbg_new_cmd,
.release_cmd = usbg_release_cmd,
.shutdown_session = usbg_shutdown_session,
.close_session = usbg_close_session,
@@ -1916,8 +1894,7 @@ static struct target_core_fabric_ops usbg_ops = {
.queue_data_in = usbg_send_read_response,
.queue_status = usbg_send_status_response,
.queue_tm_rsp = usbg_queue_tm_rsp,
- .get_fabric_sense_len = usbg_get_fabric_sense_len,
- .set_fabric_sense_len = usbg_set_fabric_sense_len,
+ .aborted_task = usbg_aborted_task,
.check_stop_free = usbg_check_stop_free,
.fabric_make_wwn = usbg_make_tport,
@@ -1944,15 +1921,15 @@ static int usbg_register_configfs(void)
}
fabric->tf_ops = usbg_ops;
- TF_CIT_TMPL(fabric)->tfc_wwn_cit.ct_attrs = usbg_wwn_attrs;
- TF_CIT_TMPL(fabric)->tfc_tpg_base_cit.ct_attrs = usbg_base_attrs;
- TF_CIT_TMPL(fabric)->tfc_tpg_attrib_cit.ct_attrs = NULL;
- TF_CIT_TMPL(fabric)->tfc_tpg_param_cit.ct_attrs = NULL;
- TF_CIT_TMPL(fabric)->tfc_tpg_np_base_cit.ct_attrs = NULL;
- TF_CIT_TMPL(fabric)->tfc_tpg_nacl_base_cit.ct_attrs = NULL;
- TF_CIT_TMPL(fabric)->tfc_tpg_nacl_attrib_cit.ct_attrs = NULL;
- TF_CIT_TMPL(fabric)->tfc_tpg_nacl_auth_cit.ct_attrs = NULL;
- TF_CIT_TMPL(fabric)->tfc_tpg_nacl_param_cit.ct_attrs = NULL;
+ fabric->tf_cit_tmpl.tfc_wwn_cit.ct_attrs = usbg_wwn_attrs;
+ fabric->tf_cit_tmpl.tfc_tpg_base_cit.ct_attrs = usbg_base_attrs;
+ fabric->tf_cit_tmpl.tfc_tpg_attrib_cit.ct_attrs = NULL;
+ fabric->tf_cit_tmpl.tfc_tpg_param_cit.ct_attrs = NULL;
+ fabric->tf_cit_tmpl.tfc_tpg_np_base_cit.ct_attrs = NULL;
+ fabric->tf_cit_tmpl.tfc_tpg_nacl_base_cit.ct_attrs = NULL;
+ fabric->tf_cit_tmpl.tfc_tpg_nacl_attrib_cit.ct_attrs = NULL;
+ fabric->tf_cit_tmpl.tfc_tpg_nacl_auth_cit.ct_attrs = NULL;
+ fabric->tf_cit_tmpl.tfc_tpg_nacl_param_cit.ct_attrs = NULL;
ret = target_fabric_configfs_register(fabric);
if (ret < 0) {
printk(KERN_ERR "target_fabric_configfs_register() failed"
@@ -1977,13 +1954,11 @@ static void usbg_deregister_configfs(void)
static struct usb_interface_descriptor bot_intf_desc = {
.bLength = sizeof(bot_intf_desc),
.bDescriptorType = USB_DT_INTERFACE,
- .bAlternateSetting = 0,
.bNumEndpoints = 2,
.bAlternateSetting = USB_G_ALT_INT_BBB,
.bInterfaceClass = USB_CLASS_MASS_STORAGE,
.bInterfaceSubClass = USB_SC_SCSI,
.bInterfaceProtocol = USB_PR_BULK,
- .iInterface = USB_G_STR_INT_UAS,
};
static struct usb_interface_descriptor uasp_intf_desc = {
@@ -1994,7 +1969,6 @@ static struct usb_interface_descriptor uasp_intf_desc = {
.bInterfaceClass = USB_CLASS_MASS_STORAGE,
.bInterfaceSubClass = USB_SC_SCSI,
.bInterfaceProtocol = USB_PR_UAS,
- .iInterface = USB_G_STR_INT_BBB,
};
static struct usb_endpoint_descriptor uasp_bi_desc = {
@@ -2163,6 +2137,7 @@ static struct usb_descriptor_header *uasp_fs_function_desc[] = {
(struct usb_descriptor_header *) &uasp_status_pipe_desc,
(struct usb_descriptor_header *) &uasp_fs_cmd_desc,
(struct usb_descriptor_header *) &uasp_cmd_pipe_desc,
+ NULL,
};
static struct usb_descriptor_header *uasp_hs_function_desc[] = {
@@ -2215,20 +2190,16 @@ static struct usb_device_descriptor usbg_device_desc = {
.bDeviceClass = USB_CLASS_PER_INTERFACE,
.idVendor = cpu_to_le16(UAS_VENDOR_ID),
.idProduct = cpu_to_le16(UAS_PRODUCT_ID),
- .iManufacturer = USB_G_STR_MANUFACTOR,
- .iProduct = USB_G_STR_PRODUCT,
- .iSerialNumber = USB_G_STR_SERIAL,
-
.bNumConfigurations = 1,
};
static struct usb_string usbg_us_strings[] = {
- { USB_G_STR_MANUFACTOR, "Target Manufactor"},
- { USB_G_STR_PRODUCT, "Target Product"},
- { USB_G_STR_SERIAL, "000000000001"},
- { USB_G_STR_CONFIG, "default config"},
- { USB_G_STR_INT_UAS, "USB Attached SCSI"},
- { USB_G_STR_INT_BBB, "Bulk Only Transport"},
+ [USB_GADGET_MANUFACTURER_IDX].s = "Target Manufactor",
+ [USB_GADGET_PRODUCT_IDX].s = "Target Product",
+ [USB_GADGET_SERIAL_IDX].s = "000000000001",
+ [USB_G_STR_CONFIG].s = "default config",
+ [USB_G_STR_INT_UAS].s = "USB Attached SCSI",
+ [USB_G_STR_INT_BBB].s = "Bulk Only Transport",
{ },
};
@@ -2250,7 +2221,6 @@ static int guas_unbind(struct usb_composite_dev *cdev)
static struct usb_configuration usbg_config_driver = {
.label = "Linux Target",
.bConfigurationValue = 1,
- .iConfiguration = USB_G_STR_CONFIG,
.bmAttributes = USB_CONFIG_ATT_SELFPOWER,
};
@@ -2268,6 +2238,7 @@ static int usbg_bind(struct usb_configuration *c, struct usb_function *f)
struct usb_gadget *gadget = c->cdev->gadget;
struct usb_ep *ep;
int iface;
+ int ret;
iface = usb_interface_id(c, f);
if (iface < 0)
@@ -2318,6 +2289,11 @@ static int usbg_bind(struct usb_configuration *c, struct usb_function *f)
uasp_ss_status_desc.bEndpointAddress;
uasp_fs_cmd_desc.bEndpointAddress = uasp_ss_cmd_desc.bEndpointAddress;
+ ret = usb_assign_descriptors(f, uasp_fs_function_desc,
+ uasp_hs_function_desc, uasp_ss_function_desc);
+ if (ret)
+ goto ep_fail;
+
return 0;
ep_fail:
pr_err("Can't claim all required eps\n");
@@ -2333,6 +2309,7 @@ static void usbg_unbind(struct usb_configuration *c, struct usb_function *f)
{
struct f_uas *fu = to_f_uas(f);
+ usb_free_all_descriptors(f);
kfree(fu);
}
@@ -2413,9 +2390,6 @@ static int usbg_cfg_bind(struct usb_configuration *c)
if (!fu)
return -ENOMEM;
fu->function.name = "Target Function";
- fu->function.descriptors = uasp_fs_function_desc;
- fu->function.hs_descriptors = uasp_hs_function_desc;
- fu->function.ss_descriptors = uasp_ss_function_desc;
fu->function.bind = usbg_bind;
fu->function.unbind = usbg_unbind;
fu->function.set_alt = usbg_set_alt;
@@ -2423,6 +2397,9 @@ static int usbg_cfg_bind(struct usb_configuration *c)
fu->function.disable = usbg_disable;
fu->tpg = the_only_tpg_I_currently_have;
+ bot_intf_desc.iInterface = usbg_us_strings[USB_G_STR_INT_BBB].id;
+ uasp_intf_desc.iInterface = usbg_us_strings[USB_G_STR_INT_UAS].id;
+
ret = usb_add_function(c, &fu->function);
if (ret)
goto err;
@@ -2437,22 +2414,38 @@ static int usb_target_bind(struct usb_composite_dev *cdev)
{
int ret;
+ ret = usb_string_ids_tab(cdev, usbg_us_strings);
+ if (ret)
+ return ret;
+
+ usbg_device_desc.iManufacturer =
+ usbg_us_strings[USB_GADGET_MANUFACTURER_IDX].id;
+ usbg_device_desc.iProduct = usbg_us_strings[USB_GADGET_PRODUCT_IDX].id;
+ usbg_device_desc.iSerialNumber =
+ usbg_us_strings[USB_GADGET_SERIAL_IDX].id;
+ usbg_config_driver.iConfiguration =
+ usbg_us_strings[USB_G_STR_CONFIG].id;
+
ret = usb_add_config(cdev, &usbg_config_driver,
usbg_cfg_bind);
+ if (ret)
+ return ret;
+ usb_composite_overwrite_options(cdev, &coverwrite);
return 0;
}
-static struct usb_composite_driver usbg_driver = {
+static __refdata struct usb_composite_driver usbg_driver = {
.name = "g_target",
.dev = &usbg_device_desc,
.strings = usbg_strings,
.max_speed = USB_SPEED_SUPER,
+ .bind = usb_target_bind,
.unbind = guas_unbind,
};
static int usbg_attach(struct usbg_tpg *tpg)
{
- return usb_composite_probe(&usbg_driver, usb_target_bind);
+ return usb_composite_probe(&usbg_driver);
}
static void usbg_detach(struct usbg_tpg *tpg)