diff options
Diffstat (limited to 'drivers/usb/gadget/tcm_usb_gadget.c')
| -rw-r--r-- | drivers/usb/gadget/tcm_usb_gadget.c | 183 |
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) |
