Re: USB3 xHCI Error, unable to acces the disk
Hello, Thanks for your support, I don't know if the problem occur if the SSD is not connected as root partition and it will be difficult to test it as the internal SSD is windows7 type and I can't modify it (it's a professional laptop from my company). I will test with xhci debugging... Do I have to check the output of the debugging in journalctl or somewhere else? lesebas 2015-12-11 9:42 GMT+01:00 Mathias Nyman: > On 10.12.2015 18:18, Sébastien Deligny wrote: >> >> Hello I've report a bug on bug tracker but I've been advise to post it >> directly to th mailing list. Here is my problem : >> >> Connected on USB3 SSD as root partition, sometimes the system lags a >> lot and I'm not able to stop the system properly as the FS become >> readonly. Tested with 4.2 kernel. With testing version 4.3, the lags >> occur again but after few minutes it come back to a stable situation. >> >> Could you please CC'ed me in the answers of this post? >> >> Here is the extract of journalctl : >> >> >> Connected on USB3 SSD as root partition, sometimes the system lags a >> lot and I'm not able to stop the system properly as the FS become >> readonly. Tested with 4.2 kernel. With testing version 4.3, the lags >> occur again but after few minutes it come back to a stable situation. >> Here is the copy of journalctl : >> >> déc. 08 23:10:52 Vulpus kernel: xhci_hcd :00:14.0: ERROR Unknown >> event condition 10, HC probably busted >> déc. 08 23:10:52 Vulpus kernel: xhci_hcd :00:14.0: ERROR Transfer >> event for disabled endpoint or incorrect stream > > > Event condition 10 is a "Invalid Stream Type Error" related to uas and xhci > streams usage, > > xhci specs 4.12.2.1 list several occasions when this can happen, partly > depending on > if a Secondary stream array is in use. > I've managed to avoid streams until now. We should probably print out the > endpoint/stream context > on this error. > > Are you seeing this issue if the USB3 SSD is not connected as root > partition? > > Can you add xhci debugging and try to reproduce this issue: > echo -n 'module xhci_hcd =p' > /sys/kernel/debug/dynamic_debug/control > > -Mathias > > > > > -- S. Deligny -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v3 35/36] usb: gadget: f_uac2: conversion to new API
Generate descriptors in new format and attach them to USB function in prep_descs(). Implement prep_vendor_descs() to supply class specific descriptors. Change set_alt() implementation and implement clear_alt() operation. Remove boilerplate code. Signed-off-by: Robert Baldyga--- drivers/usb/gadget/function/f_uac2.c | 345 +-- 1 file changed, 122 insertions(+), 223 deletions(-) diff --git a/drivers/usb/gadget/function/f_uac2.c b/drivers/usb/gadget/function/f_uac2.c index 044ca79..713b452 100644 --- a/drivers/usb/gadget/function/f_uac2.c +++ b/drivers/usb/gadget/function/f_uac2.c @@ -119,10 +119,6 @@ static struct snd_pcm_hardware uac2_pcm_hardware = { }; struct audio_dev { - u8 ac_intf, ac_alt; - u8 as_out_intf, as_out_alt; - u8 as_in_intf, as_in_alt; - struct usb_ep *in_ep, *out_ep; struct usb_function func; @@ -880,65 +876,20 @@ static struct uac2_iso_endpoint_descriptor as_iso_in_desc = { .wLockDelay = 0, }; -static struct usb_descriptor_header *fs_audio_desc[] = { - (struct usb_descriptor_header *)_desc, - (struct usb_descriptor_header *)_ac_if_desc, - - (struct usb_descriptor_header *)_hdr_desc, - (struct usb_descriptor_header *)_clk_src_desc, - (struct usb_descriptor_header *)_clk_src_desc, - (struct usb_descriptor_header *)_out_it_desc, - (struct usb_descriptor_header *)_in_it_desc, - (struct usb_descriptor_header *)_in_ot_desc, - (struct usb_descriptor_header *)_out_ot_desc, - - (struct usb_descriptor_header *)_as_out_if0_desc, - (struct usb_descriptor_header *)_as_out_if1_desc, - - (struct usb_descriptor_header *)_out_hdr_desc, - (struct usb_descriptor_header *)_out_fmt1_desc, - (struct usb_descriptor_header *)_epout_desc, - (struct usb_descriptor_header *)_iso_out_desc, - - (struct usb_descriptor_header *)_as_in_if0_desc, - (struct usb_descriptor_header *)_as_in_if1_desc, - - (struct usb_descriptor_header *)_in_hdr_desc, - (struct usb_descriptor_header *)_in_fmt1_desc, - (struct usb_descriptor_header *)_epin_desc, - (struct usb_descriptor_header *)_iso_in_desc, - NULL, -}; +USB_COMPOSITE_ENDPOINT(ep_out, _epout_desc, _epout_desc, NULL, NULL); +USB_COMPOSITE_ENDPOINT(ep_in, _epin_desc, _epin_desc, NULL, NULL); -static struct usb_descriptor_header *hs_audio_desc[] = { - (struct usb_descriptor_header *)_desc, - (struct usb_descriptor_header *)_ac_if_desc, - - (struct usb_descriptor_header *)_hdr_desc, - (struct usb_descriptor_header *)_clk_src_desc, - (struct usb_descriptor_header *)_clk_src_desc, - (struct usb_descriptor_header *)_out_it_desc, - (struct usb_descriptor_header *)_in_it_desc, - (struct usb_descriptor_header *)_in_ot_desc, - (struct usb_descriptor_header *)_out_ot_desc, - - (struct usb_descriptor_header *)_as_out_if0_desc, - (struct usb_descriptor_header *)_as_out_if1_desc, - - (struct usb_descriptor_header *)_out_hdr_desc, - (struct usb_descriptor_header *)_out_fmt1_desc, - (struct usb_descriptor_header *)_epout_desc, - (struct usb_descriptor_header *)_iso_out_desc, - - (struct usb_descriptor_header *)_as_in_if0_desc, - (struct usb_descriptor_header *)_as_in_if1_desc, - - (struct usb_descriptor_header *)_in_hdr_desc, - (struct usb_descriptor_header *)_in_fmt1_desc, - (struct usb_descriptor_header *)_epin_desc, - (struct usb_descriptor_header *)_iso_in_desc, - NULL, -}; +USB_COMPOSITE_ALTSETTING(intf0alt0, _ac_if_desc); +USB_COMPOSITE_ALTSETTING(intf1alt0, _as_out_if0_desc); +USB_COMPOSITE_ALTSETTING(intf1alt1, _as_out_if1_desc, _out); +USB_COMPOSITE_ALTSETTING(intf2alt0, _as_in_if0_desc); +USB_COMPOSITE_ALTSETTING(intf2alt1, _as_in_if1_desc, _in); + +USB_COMPOSITE_INTERFACE(intf0, ); +USB_COMPOSITE_INTERFACE(intf1, , ); +USB_COMPOSITE_INTERFACE(intf2, , ); + +USB_COMPOSITE_DESCRIPTORS(uac2_descs, , , ); struct cntrl_cur_lay3 { __u32 dCUR; @@ -998,18 +949,13 @@ static void set_ep_max_packet_size(const struct f_uac2_opts *uac2_opts, le16_to_cpu(ep_desc->wMaxPacketSize))); } -static int -afunc_bind(struct usb_configuration *cfg, struct usb_function *fn) +static int afunc_prep_descs(struct usb_function *fn) { struct audio_dev *agdev = func_to_agdev(fn); - struct snd_uac2_chip *uac2 = >uac2; - struct usb_composite_dev *cdev = cfg->cdev; - struct usb_gadget *gadget = cdev->gadget; - struct device *dev = >pdev.dev; + struct usb_composite_dev *cdev = fn->config->cdev; struct uac2_rtd_params *prm; struct f_uac2_opts *uac2_opts; struct usb_string *us; - int ret; uac2_opts = container_of(fn->fi, struct f_uac2_opts, func_inst); @@ -1029,6 +975,28 @@ afunc_bind(struct usb_configuration *cfg, struct
[PATCH v3 34/36] usb: gadget: f_uac1: conversion to new API
Generate descriptors in new format and attach them to USB function in prep_descs(). Implement prep_vendor_descs() to supply class specific descriptors. Change set_alt() implementation and implement clear_alt() operation. Remove boilerplate code. Signed-off-by: Robert Baldyga--- drivers/usb/gadget/function/f_uac1.c | 134 +++ 1 file changed, 58 insertions(+), 76 deletions(-) diff --git a/drivers/usb/gadget/function/f_uac1.c b/drivers/usb/gadget/function/f_uac1.c index 6a2346b..2faf4e4 100644 --- a/drivers/usb/gadget/function/f_uac1.c +++ b/drivers/usb/gadget/function/f_uac1.c @@ -189,24 +189,17 @@ static struct uac_iso_endpoint_descriptor as_iso_out_desc = { .wLockDelay = __constant_cpu_to_le16(1), }; -static struct usb_descriptor_header *f_audio_desc[] = { - (struct usb_descriptor_header *)_interface_desc, - (struct usb_descriptor_header *)_header_desc, +USB_COMPOSITE_ENDPOINT(ep_out, _out_ep_desc, + _out_ep_desc, NULL, NULL); - (struct usb_descriptor_header *)_terminal_desc, - (struct usb_descriptor_header *)_terminal_desc, - (struct usb_descriptor_header *)_unit_desc, +USB_COMPOSITE_ALTSETTING(intf0alt0, _interface_desc); +USB_COMPOSITE_ALTSETTING(intf1alt0, _interface_alt_0_desc); +USB_COMPOSITE_ALTSETTING(intf1alt1, _interface_alt_1_desc, _out); - (struct usb_descriptor_header *)_interface_alt_0_desc, - (struct usb_descriptor_header *)_interface_alt_1_desc, - (struct usb_descriptor_header *)_header_desc, +USB_COMPOSITE_INTERFACE(intf0, ); +USB_COMPOSITE_INTERFACE(intf1, , ); - (struct usb_descriptor_header *)_type_i_desc, - - (struct usb_descriptor_header *)_out_ep_desc, - (struct usb_descriptor_header *)_iso_out_desc, - NULL, -}; +USB_COMPOSITE_DESCRIPTORS(uac1_descs, , ); enum { STR_AC_IF, @@ -573,7 +566,7 @@ static int f_audio_set_alt(struct usb_function *f, unsigned intf, unsigned alt) { struct f_audio *audio = func_to_audio(f); struct usb_composite_dev *cdev = f->config->cdev; - struct usb_ep *out_ep = audio->out_ep; + struct usb_ep *out_ep; struct usb_request *req; struct f_uac1_opts *opts; int req_buf_size, req_count, audio_buf_size; @@ -588,11 +581,12 @@ static int f_audio_set_alt(struct usb_function *f, unsigned intf, unsigned alt) if (intf == 1) { if (alt == 1) { - err = config_ep_by_speed(cdev->gadget, f, out_ep); - if (err) - return err; + out_ep = usb_function_get_ep(f, intf, 0); + if (!out_ep) + return -ENODEV; + + audio->out_ep = out_ep; - usb_ep_enable(out_ep); audio->copy_buf = f_audio_buffer_alloc(audio_buf_size); if (IS_ERR(audio->copy_buf)) return -ENOMEM; @@ -636,7 +630,8 @@ static int f_audio_set_alt(struct usb_function *f, unsigned intf, unsigned alt) return err; } -static void f_audio_disable(struct usb_function *f) +static void f_audio_clear_alt(struct usb_function *f, + unsigned intf, unsigned alt) { return; } @@ -664,25 +659,11 @@ static void f_audio_build_desc(struct f_audio *audio) } /* audio function driver setup/binding */ -static int -f_audio_bind(struct usb_configuration *c, struct usb_function *f) +static int f_audio_prep_descs(struct usb_function *f) { - struct usb_composite_dev *cdev = c->cdev; - struct f_audio *audio = func_to_audio(f); + struct usb_composite_dev *cdev = f->config->cdev; struct usb_string *us; - int status; - struct usb_ep *ep = NULL; - struct f_uac1_opts *audio_opts; - audio_opts = container_of(f->fi, struct f_uac1_opts, func_inst); - audio->card.gadget = c->cdev->gadget; - /* set up ASLA audio devices */ - if (!audio_opts->bound) { - status = gaudio_setup(>card); - if (status < 0) - return status; - audio_opts->bound = true; - } us = usb_gstrings_attach(cdev, uac1_strings, ARRAY_SIZE(strings_uac1)); if (IS_ERR(us)) return PTR_ERR(us); @@ -694,41 +675,47 @@ f_audio_bind(struct usb_configuration *c, struct usb_function *f) as_interface_alt_0_desc.iInterface = us[STR_AS_IF_ALT0].id; as_interface_alt_1_desc.iInterface = us[STR_AS_IF_ALT1].id; + return usb_function_set_descs(f, _descs); +} + +static int f_audio_prep_vendor_descs(struct usb_function *f) +{ + struct usb_composite_dev *cdev = f->config->cdev; + struct f_audio *audio = func_to_audio(f); + struct f_uac1_opts *audio_opts; + int
[PATCH v3 33/36] usb: gadget: f_subset: conversion to new API
Generate descriptors in new format and attach them to USB function in prep_descs(). Implement prep_vendor_descs() to supply class specific descriptors. Change set_alt() implementation and implement clear_alt() operation. Remove boilerplate code. Signed-off-by: Robert Baldyga--- drivers/usb/gadget/function/f_subset.c | 165 ++--- 1 file changed, 47 insertions(+), 118 deletions(-) diff --git a/drivers/usb/gadget/function/f_subset.c b/drivers/usb/gadget/function/f_subset.c index 829c78d..98324ca 100644 --- a/drivers/usb/gadget/function/f_subset.c +++ b/drivers/usb/gadget/function/f_subset.c @@ -154,17 +154,6 @@ static struct usb_endpoint_descriptor fs_subset_out_desc = { .bmAttributes = USB_ENDPOINT_XFER_BULK, }; -static struct usb_descriptor_header *fs_eth_function[] = { - (struct usb_descriptor_header *) _data_intf, - (struct usb_descriptor_header *) _header_desc, - (struct usb_descriptor_header *) _desc, - (struct usb_descriptor_header *) _detail_desc, - (struct usb_descriptor_header *) _desc, - (struct usb_descriptor_header *) _subset_in_desc, - (struct usb_descriptor_header *) _subset_out_desc, - NULL, -}; - /* high speed support: */ static struct usb_endpoint_descriptor hs_subset_in_desc = { @@ -183,17 +172,6 @@ static struct usb_endpoint_descriptor hs_subset_out_desc = { .wMaxPacketSize = cpu_to_le16(512), }; -static struct usb_descriptor_header *hs_eth_function[] = { - (struct usb_descriptor_header *) _data_intf, - (struct usb_descriptor_header *) _header_desc, - (struct usb_descriptor_header *) _desc, - (struct usb_descriptor_header *) _detail_desc, - (struct usb_descriptor_header *) _desc, - (struct usb_descriptor_header *) _subset_in_desc, - (struct usb_descriptor_header *) _subset_out_desc, - NULL, -}; - /* super speed support: */ static struct usb_endpoint_descriptor ss_subset_in_desc = { @@ -221,18 +199,16 @@ static struct usb_ss_ep_comp_descriptor ss_subset_bulk_comp_desc = { /* .bmAttributes = 0, */ }; -static struct usb_descriptor_header *ss_eth_function[] = { - (struct usb_descriptor_header *) _data_intf, - (struct usb_descriptor_header *) _header_desc, - (struct usb_descriptor_header *) _desc, - (struct usb_descriptor_header *) _detail_desc, - (struct usb_descriptor_header *) _desc, - (struct usb_descriptor_header *) _subset_in_desc, - (struct usb_descriptor_header *) _subset_bulk_comp_desc, - (struct usb_descriptor_header *) _subset_out_desc, - (struct usb_descriptor_header *) _subset_bulk_comp_desc, - NULL, -}; +USB_COMPOSITE_ENDPOINT(ep_in, _subset_in_desc, _subset_in_desc, + _subset_in_desc, _subset_bulk_comp_desc); +USB_COMPOSITE_ENDPOINT(ep_out, _subset_out_desc, _subset_out_desc, + _subset_out_desc, _subset_bulk_comp_desc); + +USB_COMPOSITE_ALTSETTING(intf0alt0, _data_intf, _in, _out); + +USB_COMPOSITE_INTERFACE(intf0, ); + +USB_COMPOSITE_DESCRIPTORS(subset_descs, ); /* string descriptors: */ @@ -260,26 +236,20 @@ static int geth_set_alt(struct usb_function *f, unsigned intf, unsigned alt) struct usb_composite_dev *cdev = f->config->cdev; struct net_device *net; - /* we know alt == 0, so this is an activation or a reset */ - - if (geth->port.in_ep->enabled) { - DBG(cdev, "reset cdc subset\n"); - gether_disconnect(>port); - } - DBG(cdev, "init + activate cdc subset\n"); - if (config_ep_by_speed(cdev->gadget, f, geth->port.in_ep) || - config_ep_by_speed(cdev->gadget, f, geth->port.out_ep)) { - geth->port.in_ep->desc = NULL; - geth->port.out_ep->desc = NULL; - return -EINVAL; - } + + geth->port.in_ep = usb_function_get_ep(f, intf, 0); + if (!geth->port.in_ep) + return -ENODEV; + geth->port.out_ep = usb_function_get_ep(f, intf, 1); + if (!geth->port.out_ep) + return -ENODEV; net = gether_connect(>port); return PTR_ERR_OR_ZERO(net); } -static void geth_disable(struct usb_function *f) +static void geth_clear_alt(struct usb_function *f, unsigned intf, unsigned alt) { struct f_gether *geth = func_to_geth(f); struct usb_composite_dev *cdev = f->config->cdev; @@ -292,14 +262,26 @@ static void geth_disable(struct usb_function *f) /* serial function driver setup/binding */ -static int -geth_bind(struct usb_configuration *c, struct usb_function *f) +static int geth_prep_descs(struct usb_function *f) { - struct usb_composite_dev *cdev = c->cdev; - struct f_gether *geth = func_to_geth(f); + struct usb_composite_dev *cdev = f->config->cdev; struct usb_string *us; + + us = usb_gstrings_attach(cdev, geth_strings, +
[PATCH v3 28/36] usb: gadget: f_ncm: conversion to new API
Generate descriptors in new format and attach them to USB function in prep_descs(). Implement prep_vendor_descs() to supply class specific descriptors. Change set_alt() implementation and implement clear_alt() operation. Remove boilerplate code. Signed-off-by: Robert Baldyga--- drivers/usb/gadget/function/f_ncm.c | 320 1 file changed, 105 insertions(+), 215 deletions(-) diff --git a/drivers/usb/gadget/function/f_ncm.c b/drivers/usb/gadget/function/f_ncm.c index 7ad798a..a681895 100644 --- a/drivers/usb/gadget/function/f_ncm.c +++ b/drivers/usb/gadget/function/f_ncm.c @@ -32,8 +32,7 @@ * NCM is intended to be used with high-speed network attachments. * * Note that NCM requires the use of "alternate settings" for its data - * interface. This means that the set_alt() method has real work to do, - * and also means that a get_alt() method is required. + * interface. */ /* to trigger crc/non-crc ndp signature */ @@ -270,23 +269,6 @@ static struct usb_endpoint_descriptor fs_ncm_out_desc = { .bmAttributes = USB_ENDPOINT_XFER_BULK, }; -static struct usb_descriptor_header *ncm_fs_function[] = { - (struct usb_descriptor_header *) _iad_desc, - /* CDC NCM control descriptors */ - (struct usb_descriptor_header *) _control_intf, - (struct usb_descriptor_header *) _header_desc, - (struct usb_descriptor_header *) _union_desc, - (struct usb_descriptor_header *) _desc, - (struct usb_descriptor_header *) _desc, - (struct usb_descriptor_header *) _ncm_notify_desc, - /* data interface, altsettings 0 and 1 */ - (struct usb_descriptor_header *) _data_nop_intf, - (struct usb_descriptor_header *) _data_intf, - (struct usb_descriptor_header *) _ncm_in_desc, - (struct usb_descriptor_header *) _ncm_out_desc, - NULL, -}; - /* high speed support: */ static struct usb_endpoint_descriptor hs_ncm_notify_desc = { @@ -316,22 +298,21 @@ static struct usb_endpoint_descriptor hs_ncm_out_desc = { .wMaxPacketSize = cpu_to_le16(512), }; -static struct usb_descriptor_header *ncm_hs_function[] = { - (struct usb_descriptor_header *) _iad_desc, - /* CDC NCM control descriptors */ - (struct usb_descriptor_header *) _control_intf, - (struct usb_descriptor_header *) _header_desc, - (struct usb_descriptor_header *) _union_desc, - (struct usb_descriptor_header *) _desc, - (struct usb_descriptor_header *) _desc, - (struct usb_descriptor_header *) _ncm_notify_desc, - /* data interface, altsettings 0 and 1 */ - (struct usb_descriptor_header *) _data_nop_intf, - (struct usb_descriptor_header *) _data_intf, - (struct usb_descriptor_header *) _ncm_in_desc, - (struct usb_descriptor_header *) _ncm_out_desc, - NULL, -}; +USB_COMPOSITE_ENDPOINT(ep_notify, _ncm_notify_desc, + _ncm_notify_desc, NULL, NULL); +USB_COMPOSITE_ENDPOINT(ep_in, _ncm_in_desc, + _ncm_in_desc, NULL, NULL); +USB_COMPOSITE_ENDPOINT(ep_out, _ncm_out_desc, + _ncm_out_desc, NULL, NULL); + +USB_COMPOSITE_ALTSETTING(intf0alt0, _control_intf, _notify); +USB_COMPOSITE_ALTSETTING(intf1alt0, _data_nop_intf); +USB_COMPOSITE_ALTSETTING(intf1alt1, _data_intf, _in, _out); + +USB_COMPOSITE_INTERFACE(intf0, ); +USB_COMPOSITE_INTERFACE(intf1, , ); + +USB_COMPOSITE_DESCRIPTORS(ncm_descs, , ); /* string descriptors: */ @@ -792,6 +773,8 @@ invalid: return value; } +static void ncm_tx_tasklet(unsigned long data); +static enum hrtimer_restart ncm_tx_timeout(struct hrtimer *data); static int ncm_set_alt(struct usb_function *f, unsigned intf, unsigned alt) { @@ -799,52 +782,44 @@ static int ncm_set_alt(struct usb_function *f, unsigned intf, unsigned alt) struct usb_composite_dev *cdev = f->config->cdev; /* Control interface has only altsetting 0 */ - if (intf == ncm->ctrl_id) { - if (alt != 0) - goto fail; - + if (intf == 0) { DBG(cdev, "reset ncm control %d\n", intf); - usb_ep_disable(ncm->notify); - if (!(ncm->notify->desc)) { - DBG(cdev, "init ncm ctrl %d\n", intf); - if (config_ep_by_speed(cdev->gadget, f, ncm->notify)) - goto fail; + ncm->notify = usb_function_get_ep(f, intf, 0); + if (!ncm->notify) + return -ENODEV; + + /* allocate notification request and buffer */ + ncm->notify_req = usb_ep_alloc_request(ncm->notify, GFP_KERNEL); + if (!ncm->notify_req) + return -ENOMEM; + ncm->notify_req->buf = kmalloc(NCM_STATUS_BYTECOUNT, GFP_KERNEL); + if (!ncm->notify_req->buf) { + usb_ep_free_request(ncm->notify, ncm->notify_req); +
Re: [PATCH 2/2] usb: serial: remove redundant condition
Hello. On 12/11/2015 12:46 PM, Geyslan G. Bem wrote: It's a bad idea to send 2 different patches with the same subject. I'd use "mos7840: " as a prefix in this case. This patch removes redundant condition. (length && length > 5) can be reduced to a single evaluation. Tested by compilation only. Caught by cppcheck. Signed-off-by: Geyslan G. Bem[...] MBR, Sergei -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v3 36/36] usb: gadget: f_mass_storage: conversion to new API
Generate descriptors in new format and attach them to USB function in prep_descs(). Change set_alt() implementation and implement clear_alt() operation. Remove boilerplate code. Signed-off-by: Robert Baldyga--- drivers/usb/gadget/function/f_mass_storage.c | 91 +--- drivers/usb/gadget/function/storage_common.c | 29 - drivers/usb/gadget/function/storage_common.h | 3 - 3 files changed, 29 insertions(+), 94 deletions(-) diff --git a/drivers/usb/gadget/function/f_mass_storage.c b/drivers/usb/gadget/function/f_mass_storage.c index 223ccf8..fa2326f 100644 --- a/drivers/usb/gadget/function/f_mass_storage.c +++ b/drivers/usb/gadget/function/f_mass_storage.c @@ -233,6 +233,17 @@ static const char fsg_string_interface[] = "Mass Storage"; #include "storage_common.h" #include "f_mass_storage.h" +USB_COMPOSITE_ENDPOINT(ep_in, _fs_bulk_in_desc, _hs_bulk_in_desc, +_ss_bulk_in_desc, _ss_bulk_in_comp_desc); +USB_COMPOSITE_ENDPOINT(ep_out, _fs_bulk_out_desc, _hs_bulk_out_desc, +_ss_bulk_out_desc, _ss_bulk_out_comp_desc); + +USB_COMPOSITE_ALTSETTING(intf0alt0, _intf_desc, _in, _out); + +USB_COMPOSITE_INTERFACE(intf0, ); + +USB_COMPOSITE_DESCRIPTORS(fsg_descs, ); + /* Static strings, in UTF-8 (for simplicity we use only ASCII characters) */ static struct usb_string fsg_strings[] = { {FSG_STRING_INTERFACE, fsg_string_interface}, @@ -325,8 +336,6 @@ struct fsg_dev { struct usb_gadget *gadget;/* Copy of cdev->gadget */ struct fsg_common *common; - u16 interface_number; - unsigned intbulk_in_enabled:1; unsigned intbulk_out_enabled:1; @@ -522,7 +531,7 @@ static int fsg_setup(struct usb_function *f, if (ctrl->bRequestType != (USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_INTERFACE)) break; - if (w_index != fsg->interface_number || w_value != 0 || + if (w_index != usb_get_interface_id(f, 0) || w_value != 0 || w_length != 0) return -EDOM; @@ -538,7 +547,7 @@ static int fsg_setup(struct usb_function *f, if (ctrl->bRequestType != (USB_DIR_IN | USB_TYPE_CLASS | USB_RECIP_INTERFACE)) break; - if (w_index != fsg->interface_number || w_value != 0 || + if (w_index != usb_get_interface_id(f, 0) || w_value != 0 || w_length != 1) return -EDOM; VDBG(fsg, "get max LUN\n"); @@ -2328,19 +2337,27 @@ reset: static int fsg_set_alt(struct usb_function *f, unsigned intf, unsigned alt) { struct fsg_dev *fsg = fsg_from_func(f); + + fsg->bulk_in = usb_function_get_ep(f, intf, 0); + if (!fsg->bulk_in) + return -ENODEV; + + fsg->bulk_out = usb_function_get_ep(f, intf, 1); + if (!fsg->bulk_out) + return -ENODEV; + fsg->common->new_fsg = fsg; raise_exception(fsg->common, FSG_STATE_CONFIG_CHANGE); return USB_GADGET_DELAYED_STATUS; } -static void fsg_disable(struct usb_function *f) +static void fsg_clear_alt(struct usb_function *f, unsigned intf, unsigned alt) { struct fsg_dev *fsg = fsg_from_func(f); fsg->common->new_fsg = NULL; raise_exception(fsg->common, FSG_STATE_CONFIG_CHANGE); } - /*-*/ static void handle_exception(struct fsg_common *common) @@ -3025,13 +3042,11 @@ static void fsg_common_release(struct kref *ref) /*-*/ -static int fsg_bind(struct usb_configuration *c, struct usb_function *f) +static int fsg_prep_descs(struct usb_function *f) { struct fsg_dev *fsg = fsg_from_func(f); struct fsg_common *common = fsg->common; - struct usb_gadget *gadget = c->cdev->gadget; - int i; - struct usb_ep *ep; + struct usb_gadget *gadget = f->config->cdev->gadget; unsignedmax_burst; int ret; struct fsg_opts *opts; @@ -3045,7 +3060,7 @@ static int fsg_bind(struct usb_configuration *c, struct usb_function *f) opts = fsg_opts_from_func_inst(f->fi); if (!opts->no_configfs) { - ret = fsg_common_set_cdev(fsg->common, c->cdev, + ret = fsg_common_set_cdev(fsg->common, f->config->cdev, fsg->common->can_stall); if (ret) return ret; @@ -3057,58 +3072,12 @@ static int fsg_bind(struct usb_configuration *c, struct usb_function *f) fsg->gadget = gadget; - /* New interface */ -
[PATCH v3 32/36] usb: gadget: f_phonet: conversion to new API
Generate descriptors in new format and attach them to USB function in prep_descs(). Implement prep_vendor_descs() to supply class specific descriptors. Change set_alt() implementation and implement clear_alt() operation. Remove boilerplate code. Signed-off-by: Robert Baldyga--- drivers/usb/gadget/function/f_phonet.c | 225 +++-- 1 file changed, 75 insertions(+), 150 deletions(-) diff --git a/drivers/usb/gadget/function/f_phonet.c b/drivers/usb/gadget/function/f_phonet.c index 157441d..da35b77 100644 --- a/drivers/usb/gadget/function/f_phonet.c +++ b/drivers/usb/gadget/function/f_phonet.c @@ -162,29 +162,19 @@ pn_hs_source_desc = { .wMaxPacketSize = cpu_to_le16(512), }; -static struct usb_descriptor_header *fs_pn_function[] = { - (struct usb_descriptor_header *) _control_intf_desc, - (struct usb_descriptor_header *) _header_desc, - (struct usb_descriptor_header *) _phonet_desc, - (struct usb_descriptor_header *) _union_desc, - (struct usb_descriptor_header *) _data_nop_intf_desc, - (struct usb_descriptor_header *) _data_intf_desc, - (struct usb_descriptor_header *) _fs_sink_desc, - (struct usb_descriptor_header *) _fs_source_desc, - NULL, -}; +USB_COMPOSITE_ENDPOINT(ep_sink, _fs_sink_desc, + _hs_sink_desc, NULL, NULL); +USB_COMPOSITE_ENDPOINT(ep_source, _fs_source_desc, + _hs_source_desc, NULL, NULL); -static struct usb_descriptor_header *hs_pn_function[] = { - (struct usb_descriptor_header *) _control_intf_desc, - (struct usb_descriptor_header *) _header_desc, - (struct usb_descriptor_header *) _phonet_desc, - (struct usb_descriptor_header *) _union_desc, - (struct usb_descriptor_header *) _data_nop_intf_desc, - (struct usb_descriptor_header *) _data_intf_desc, - (struct usb_descriptor_header *) _hs_sink_desc, - (struct usb_descriptor_header *) _hs_source_desc, - NULL, -}; +USB_COMPOSITE_ALTSETTING(intf0alt0, _control_intf_desc); +USB_COMPOSITE_ALTSETTING(intf1alt0, _data_nop_intf_desc); +USB_COMPOSITE_ALTSETTING(intf1alt1, _data_intf_desc, _sink, _source); + +USB_COMPOSITE_INTERFACE(intf0, ); +USB_COMPOSITE_INTERFACE(intf1, , ); + +USB_COMPOSITE_DESCRIPTORS(phonet_descs, , ); /*-*/ @@ -391,8 +381,6 @@ static void __pn_reset(struct usb_function *f) netif_carrier_off(dev); port->usb = NULL; - usb_ep_disable(fp->out_ep); - usb_ep_disable(fp->in_ep); if (fp->rx.skb) { dev_kfree_skb_irq(fp->rx.skb); fp->rx.skb = NULL; @@ -402,20 +390,13 @@ static void __pn_reset(struct usb_function *f) static int pn_set_alt(struct usb_function *f, unsigned intf, unsigned alt) { struct f_phonet *fp = func_to_pn(f); - struct usb_gadget *gadget = fp->function.config->cdev->gadget; - - if (intf == pn_control_intf_desc.bInterfaceNumber) - /* control interface, no altsetting */ - return (alt > 0) ? -EINVAL : 0; + int status, i; - if (intf == pn_data_intf_desc.bInterfaceNumber) { + if (intf == 0) { struct net_device *dev = fp->dev; struct phonet_port *port = netdev_priv(dev); /* data intf (0: inactive, 1: active) */ - if (alt > 1) - return -EINVAL; - spin_lock(>lock); if (fp->in_ep->enabled) @@ -424,72 +405,81 @@ static int pn_set_alt(struct usb_function *f, unsigned intf, unsigned alt) if (alt == 1) { int i; - if (config_ep_by_speed(gadget, f, fp->in_ep) || - config_ep_by_speed(gadget, f, fp->out_ep)) { - fp->in_ep->desc = NULL; - fp->out_ep->desc = NULL; - spin_unlock(>lock); - return -EINVAL; - } - usb_ep_enable(fp->out_ep); - usb_ep_enable(fp->in_ep); + fp->out_ep = usb_function_get_ep(f, intf, 0); + if (!fp->out_ep) + return -ENODEV; + fp->in_ep = usb_function_get_ep(f, intf, 1); + if (!fp->out_ep) + return -ENODEV; port->usb = fp; fp->out_ep->driver_data = fp; fp->in_ep->driver_data = fp; + /* Incoming USB requests */ + status = -ENOMEM; + for (i = 0; i < phonet_rxq_size; i++) { + struct usb_request *req; + + req = usb_ep_alloc_request(fp->out_ep, GFP_KERNEL); +
[PATCH 2/2] usb: serial: remove redundant condition
This patch removes redundant condition. (length && length > 5) can be reduced to a single evaluation. Tested by compilation only. Caught by cppcheck. Signed-off-by: Geyslan G. Bem--- drivers/usb/serial/mos7840.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/usb/serial/mos7840.c b/drivers/usb/serial/mos7840.c index 8ac9b55..2c69bfc 100644 --- a/drivers/usb/serial/mos7840.c +++ b/drivers/usb/serial/mos7840.c @@ -635,7 +635,7 @@ static void mos7840_interrupt_callback(struct urb *urb) * Byte 4 IIR Port 4 (port.number is 3) * Byte 5 FIFO status for both */ - if (length && length > 5) { + if (length > 5) { dev_dbg(>dev->dev, "%s", "Wrong data !!!\n"); return; } -- 2.6.3 -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v3 01/36] Documentation: usb: update usb-tools repository address
It seems that gitotious repository is no longer accessible, so we replace it with address to active repository. Signed-off-by: Robert Baldyga--- Documentation/usb/gadget-testing.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Documentation/usb/gadget-testing.txt b/Documentation/usb/gadget-testing.txt index 84b3d10..5819605 100644 --- a/Documentation/usb/gadget-testing.txt +++ b/Documentation/usb/gadget-testing.txt @@ -434,7 +434,7 @@ On host: serialc -v -p -i -a1 -s1024 \ where seriald and serialc are Felipe's utilities found here: -https://git.gitorious.org/usb/usb-tools.git master +https://github.com/felipebalbi/usb-tools.git master 12. PHONET function === -- 1.9.1 -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v3 00/36] usb: gadget: composite: introduce new function API
Hi Felipe, Here is my new patch series doing some changes in composite framework and modifying USB Function API. Some of concepts changed significantly, for example bind process is done automatically inside composite framework after collecting descriptors from all Functions. Hence bind() operation of USB Function has been replaced with prep_descs(). Besides the other benefits, such as simple implementation of gadget-level autoconfig solver, changes in API allowed to simplify code of USB Functions, which contain lots of boilerplate code. First five patches of this series are fixes or improvements, being preparation for further changes. Patches from 6 to 19 add implementation of new features. Some code allowing coexistence of both old and new API is added. This code will be removed after converting all USB Functions present in kernel to new API. Last 16 patches converts Functions: loopback, sourcesink, ecm, rndis, hid, acm, eem, ncm, printer, serial, obex, phonet, ECM subset, uac1, uac2 and mass_storage to new API. Conversion of another Functions will be provided soon. *** What has changed? *** The main changes are listed below: A. Introduce new descriptors format. It makes descriptors creation process simpler plus creates good place to contain additional information such as result of automatic bind or actually selected altsetting. B. Split descriptors creation process into two stages, implemented by two new operations: - prep_descs() provide entity descriptors (interfaces, altsettings and endpoints) - prep_vendor_descs() provide class and vendor specific descriptors. The first one is called before binding funciton to UDC and it's mandatory, because it provides information needed during bind process. The second one is optional and a Function can implement it if it wants to attach some class or vendor specific descriptors. It's called after bind process, so from it's context all information about interface numbers and endpoint addresses is accessible. C. Perform bind automatically inside composite framework after collecting descriptors from all USB Functions. Besides removing lots of repetitive code from USB Functions, it gives us two main advantages: - We can have gadget-level autoconfig solver providing better endpoint resources usage. We can choose best endpoint configuration for all Functions in all configurations. - We have composite driver structure creation process separated from bind process which allows to modify configfs to operate directly on composite driver state - both legacy gadgets and configfs can use common composite driver creation process. Function allowing to obtain endpoints after bind process is provided, and it should be called in set_alt(). D. Replace disable() operation with more powerful clear_alt(). It is called when Function is being disabled or when altsetting being selected on interface which already has active altsetting. It makes API more symmetric, which greatly simplifies resource management. E. Handle endpoint enable/disable automatically, which means, that in set_alt() we obtain set of already enabled endpoints for current altsetting. Likewise in clear_alt() endpoints are already disabled. F. Change meaning of second parameter of set_alt() operation. Now it contains index of interface within desctiptors array of given USB Function instead of bInterfaceNumber of this interface, which simplifies altsetting handling (so far it was necessary to compare this value with bInterfaceNumber of each interface to find out which altsetting of which interface is being selected). G. Handle get_alt() automatically. Currently selected altsetting number is stored for each interface. *** How did it work before? *** So far USB Functions had to handle bind process manually and deal with endpoints state explicitly, which has been making code lengthy and bug-prone. USB Functions contained lots of repetitive code which was usually copied while creating new USB Function module. This resulted with lots of boilerplate code scattered across all Functions present in Linux kernel. BIND: During bind process we had to obtain interface id manually and assign it to each interface descriptor (altsetting) of given interface. We also had to obtain endpoints manually using usb_ep_autoconfig(). Beside its verbosity, this solution resulted with suboptimal endpoints distribution, because autoconfig algorithm was aware of requirements of only single endpoint at a time. udc_bind_to_driver() { composite_bind() { configuration1->bind() { function1->bind() { intf1_id = usb_interface_id(); // Obtain intf id manually ep1 = usb_ep_autoconfig(); // Endpoint-level autoconfig ep2 = usb_ep_autoconfig(); intf2_id = usb_interface_id(); ep3 = usb_ep_autoconfig(); ep4 = usb_ep_autoconfig(); } function2->bind() { intf1_id =
[PATCH v3 03/36] usb: gadget: f_sourcesink: free requests in sourcesink_disable()
USB requests in SourceSink function are allocated in sourcesink_get_alt() function, so we prefer to free them rather in sourcesink_disable() than in source_sink_complete() when request is completed with error. It provides better symetry in resource management and improves code readability. Signed-off-by: Robert Baldyga--- drivers/usb/gadget/function/f_sourcesink.c | 63 -- 1 file changed, 51 insertions(+), 12 deletions(-) diff --git a/drivers/usb/gadget/function/f_sourcesink.c b/drivers/usb/gadget/function/f_sourcesink.c index e950031..6193b47 100644 --- a/drivers/usb/gadget/function/f_sourcesink.c +++ b/drivers/usb/gadget/function/f_sourcesink.c @@ -44,6 +44,11 @@ struct f_sourcesink { struct usb_ep *iso_out_ep; int cur_alt; + struct usb_request **in_reqs; + struct usb_request **out_reqs; + struct usb_request **iso_in_reqs; + struct usb_request **iso_out_reqs; + unsigned pattern; unsigned isoc_interval; unsigned isoc_maxpacket; @@ -550,7 +555,6 @@ static void source_sink_complete(struct usb_ep *ep, struct usb_request *req) req->actual, req->length); if (ep == ss->out_ep) check_read_data(ss, req); - free_ep_req(ep, req); return; case -EOVERFLOW:/* buffer overrun on read means that @@ -579,7 +583,7 @@ static int source_sink_start_ep(struct f_sourcesink *ss, bool is_in, bool is_iso, int speed) { struct usb_ep *ep; - struct usb_request *req; + struct usb_request **reqs; int i, size, qlen, status = 0; if (is_iso) { @@ -604,19 +608,23 @@ static int source_sink_start_ep(struct f_sourcesink *ss, bool is_in, qlen = ss->bulk_qlen; size = 0; } - + + reqs = kzalloc(qlen * sizeof(*reqs), GFP_ATOMIC); + for (i = 0; i < qlen; i++) { - req = ss_alloc_ep_req(ep, size); - if (!req) - return -ENOMEM; + reqs[i] = ss_alloc_ep_req(ep, size); + if (!reqs[i]) { + status = -ENOMEM; + goto err; + } - req->complete = source_sink_complete; + reqs[i]->complete = source_sink_complete; if (is_in) - reinit_write_data(ep, req); + reinit_write_data(ep, reqs[i]); else if (ss->pattern != 2) - memset(req->buf, 0x55, req->length); + memset(reqs[i]->buf, 0x55, reqs[i]->length); - status = usb_ep_queue(ep, req, GFP_ATOMIC); + status = usb_ep_queue(ep, reqs[i], GFP_ATOMIC); if (status) { struct usb_composite_dev*cdev; @@ -624,12 +632,30 @@ static int source_sink_start_ep(struct f_sourcesink *ss, bool is_in, ERROR(cdev, "start %s%s %s --> %d\n", is_iso ? "ISO-" : "", is_in ? "IN" : "OUT", ep->name, status); - free_ep_req(ep, req); - return status; + free_ep_req(ep, reqs[i]); + goto err; + } + + if (is_iso) { + if (is_in) + ss->iso_in_reqs = reqs; + else + ss->iso_out_reqs = reqs; + } else { + if (is_in) + ss->in_reqs = reqs; + else + ss->out_reqs = reqs; } } return status; + +err: + while (--i) + free_ep_req(ep, reqs[i]); + kfree(reqs); + return status; } static void disable_source_sink(struct f_sourcesink *ss) @@ -754,8 +780,21 @@ static int sourcesink_get_alt(struct usb_function *f, unsigned intf) static void sourcesink_disable(struct usb_function *f) { struct f_sourcesink *ss = func_to_ss(f); + int i; disable_source_sink(ss); + + for (i = 0; i < ss->bulk_qlen; ++i) { + free_ep_req(ss->in_ep, ss->in_reqs[i]); + free_ep_req(ss->out_ep, ss->out_reqs[i]); + } + + if (ss->iso_in_ep) { + for (i = 0; i < ss->iso_qlen; ++i) { + free_ep_req(ss->iso_in_ep, ss->iso_in_reqs[i]); + free_ep_req(ss->iso_out_ep, ss->iso_out_reqs[i]); + } + } } /*-*/ -- 1.9.1 -- To unsubscribe from this list: send the line "unsubscribe linux-usb"
Re: [PATCH 1/2] usb: serial: remove redundant conditions
2015-12-11 7:13 GMT-03:00 Johan Hovold: > On Fri, Dec 11, 2015 at 06:46:41AM -0300, Geyslan G. Bem wrote: >> This patch removes redundant conditions. >> >> (!A || (A && B)) is the same as (!A || B). >> >> Tested by compilation only. >> Caught by cppcheck. >> >> Signed-off-by: Geyslan G. Bem > > You forgot to update the commit summary (to include the driver name) > when splitting the original patch. I fixed that up and applied both for > next. Sorry. I got it: USB: mos7840: and USB: io_edgeport:. I'm still getting the hang of it. :-) Thank you for apply them. > > Thanks, > Johan -- Regards, Geyslan G. Bem hackingbits.com -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v3 29/36] usb: gadget: f_printer: conversion to new API
Generate descriptors in new format and attach them to USB function in prep_descs(). Implement prep_vendor_descs() to supply class specific descriptors. Change set_alt() implementation and implement clear_alt() operation. Remove boilerplate code. Signed-off-by: Robert Baldyga--- drivers/usb/gadget/function/f_printer.c | 300 ++-- 1 file changed, 88 insertions(+), 212 deletions(-) diff --git a/drivers/usb/gadget/function/f_printer.c b/drivers/usb/gadget/function/f_printer.c index 0fbfb2b..f5cfea3 100644 --- a/drivers/usb/gadget/function/f_printer.c +++ b/drivers/usb/gadget/function/f_printer.c @@ -135,13 +135,6 @@ static struct usb_endpoint_descriptor fs_ep_out_desc = { .bmAttributes = USB_ENDPOINT_XFER_BULK }; -static struct usb_descriptor_header *fs_printer_function[] = { - (struct usb_descriptor_header *) _desc, - (struct usb_descriptor_header *) _ep_in_desc, - (struct usb_descriptor_header *) _ep_out_desc, - NULL -}; - /* * usb 2.0 devices need to expose both high speed and full speed * descriptors, unless they only run at full speed. @@ -169,13 +162,6 @@ static struct usb_qualifier_descriptor dev_qualifier = { .bNumConfigurations = 1 }; -static struct usb_descriptor_header *hs_printer_function[] = { - (struct usb_descriptor_header *) _desc, - (struct usb_descriptor_header *) _ep_in_desc, - (struct usb_descriptor_header *) _ep_out_desc, - NULL -}; - /* * Added endpoint descriptors for 3.0 devices */ @@ -204,14 +190,16 @@ static struct usb_ss_ep_comp_descriptor ss_ep_out_comp_desc = { .bDescriptorType = USB_DT_SS_ENDPOINT_COMP, }; -static struct usb_descriptor_header *ss_printer_function[] = { - (struct usb_descriptor_header *) _desc, - (struct usb_descriptor_header *) _ep_in_desc, - (struct usb_descriptor_header *) _ep_in_comp_desc, - (struct usb_descriptor_header *) _ep_out_desc, - (struct usb_descriptor_header *) _ep_out_comp_desc, - NULL -}; +USB_COMPOSITE_ENDPOINT(ep_in, _ep_in_desc, _ep_in_desc, + _ep_in_desc, _ep_in_comp_desc); +USB_COMPOSITE_ENDPOINT(ep_out, _ep_out_desc, _ep_out_desc, + _ep_out_desc, _ep_out_comp_desc); + +USB_COMPOSITE_ALTSETTING(intf0alt0, _desc, _in, _out); + +USB_COMPOSITE_INTERFACE(intf0, ); + +USB_COMPOSITE_DESCRIPTORS(printer_descs, ); /* maxpacket and other transfer characteristics vary by speed. */ static inline struct usb_endpoint_descriptor *ep_desc(struct usb_gadget *gadget, @@ -764,86 +752,6 @@ static const struct file_operations printer_io_operations = { /*-*/ -static int -set_printer_interface(struct printer_dev *dev) -{ - int result = 0; - - dev->in_ep->desc = ep_desc(dev->gadget, _ep_in_desc, _ep_in_desc, - _ep_in_desc); - dev->in_ep->driver_data = dev; - - dev->out_ep->desc = ep_desc(dev->gadget, _ep_out_desc, - _ep_out_desc, _ep_out_desc); - dev->out_ep->driver_data = dev; - - result = usb_ep_enable(dev->in_ep); - if (result != 0) { - DBG(dev, "enable %s --> %d\n", dev->in_ep->name, result); - goto done; - } - - result = usb_ep_enable(dev->out_ep); - if (result != 0) { - DBG(dev, "enable %s --> %d\n", dev->in_ep->name, result); - goto done; - } - -done: - /* on error, disable any endpoints */ - if (result != 0) { - (void) usb_ep_disable(dev->in_ep); - (void) usb_ep_disable(dev->out_ep); - dev->in_ep->desc = NULL; - dev->out_ep->desc = NULL; - } - - /* caller is responsible for cleanup on error */ - return result; -} - -static void printer_reset_interface(struct printer_dev *dev) -{ - unsigned long flags; - - if (dev->interface < 0) - return; - - DBG(dev, "%s\n", __func__); - - if (dev->in_ep->desc) - usb_ep_disable(dev->in_ep); - - if (dev->out_ep->desc) - usb_ep_disable(dev->out_ep); - - spin_lock_irqsave(>lock, flags); - dev->in_ep->desc = NULL; - dev->out_ep->desc = NULL; - dev->interface = -1; - spin_unlock_irqrestore(>lock, flags); -} - -/* Change our operational Interface. */ -static int set_interface(struct printer_dev *dev, unsigned number) -{ - int result = 0; - - /* Free the current interface */ - printer_reset_interface(dev); - - result = set_printer_interface(dev); - if (result) - printer_reset_interface(dev); - else - dev->interface = number; - - if (!result) - INFO(dev, "Using interface %x\n", number); - - return result; -} - static void
[PATCH v3 25/36] usb: gadget: f_hid: conversion to new API
Generate descriptors in new format and attach them to USB function in prep_descs(). Implement prep_vendor_descs() to supply class specific descriptors. Change set_alt() implementation and implement clear_alt() operation. Move cdev initialization to hidg_alloc(). Remove boilerplate code. Signed-off-by: Robert Baldyga--- drivers/usb/gadget/function/f_hid.c | 305 ++-- 1 file changed, 119 insertions(+), 186 deletions(-) diff --git a/drivers/usb/gadget/function/f_hid.c b/drivers/usb/gadget/function/f_hid.c index 0456a53..8770289 100644 --- a/drivers/usb/gadget/function/f_hid.c +++ b/drivers/usb/gadget/function/f_hid.c @@ -125,14 +125,6 @@ static struct usb_endpoint_descriptor hidg_hs_out_ep_desc = { */ }; -static struct usb_descriptor_header *hidg_hs_descriptors[] = { - (struct usb_descriptor_header *)_interface_desc, - (struct usb_descriptor_header *)_desc, - (struct usb_descriptor_header *)_hs_in_ep_desc, - (struct usb_descriptor_header *)_hs_out_ep_desc, - NULL, -}; - /* Full-Speed Support */ static struct usb_endpoint_descriptor hidg_fs_in_ep_desc = { @@ -159,13 +151,16 @@ static struct usb_endpoint_descriptor hidg_fs_out_ep_desc = { */ }; -static struct usb_descriptor_header *hidg_fs_descriptors[] = { - (struct usb_descriptor_header *)_interface_desc, - (struct usb_descriptor_header *)_desc, - (struct usb_descriptor_header *)_fs_in_ep_desc, - (struct usb_descriptor_header *)_fs_out_ep_desc, - NULL, -}; +USB_COMPOSITE_ENDPOINT(ep_in, _fs_in_ep_desc, + _hs_in_ep_desc, NULL, NULL); +USB_COMPOSITE_ENDPOINT(ep_out, _fs_out_ep_desc, + _hs_out_ep_desc, NULL, NULL); + +USB_COMPOSITE_ALTSETTING(intf0alt0, _interface_desc, _in, _out); + +USB_COMPOSITE_INTERFACE(intf0, ); + +USB_COMPOSITE_DESCRIPTORS(hidg_descs, ); /*-*/ /* Strings */ @@ -487,27 +482,6 @@ respond: return status; } -static void hidg_disable(struct usb_function *f) -{ - struct f_hidg *hidg = func_to_hidg(f); - struct f_hidg_req_list *list, *next; - int i; - - usb_ep_disable(hidg->in_ep); - usb_ep_disable(hidg->out_ep); - - list_for_each_entry_safe(list, next, >completed_out_req, list) { - list_del(>list); - kfree(list); - } - - for (i = 0; i < hidg->qlen; ++i) { - kfree(hidg->out_reqs[i]->buf); - kfree(hidg->out_reqs[i]); - } - kfree(hidg->out_reqs); -} - static int hidg_set_alt(struct usb_function *f, unsigned intf, unsigned alt) { struct usb_composite_dev*cdev = f->config->cdev; @@ -516,65 +490,46 @@ static int hidg_set_alt(struct usb_function *f, unsigned intf, unsigned alt) VDBG(cdev, "hidg_set_alt intf:%d alt:%d\n", intf, alt); - if (hidg->in_ep != NULL) { - /* restart endpoint */ - usb_ep_disable(hidg->in_ep); + hidg->in_ep = usb_function_get_ep(f, intf, 0); + if (!hidg->in_ep) + return -ENODEV; + hidg->in_ep->driver_data = hidg; - status = config_ep_by_speed(f->config->cdev->gadget, f, - hidg->in_ep); - if (status) { - ERROR(cdev, "config_ep_by_speed FAILED!\n"); - goto fail; - } - status = usb_ep_enable(hidg->in_ep); - if (status < 0) { - ERROR(cdev, "Enable IN endpoint FAILED!\n"); - goto fail; - } - hidg->in_ep->driver_data = hidg; - } + hidg->out_ep = usb_function_get_ep(f, intf, 1); + if (!hidg->out_ep) + return -ENODEV; + hidg->out_ep->driver_data = hidg; + /* preallocate request and buffer */ + hidg->req = usb_ep_alloc_request(hidg->in_ep, GFP_KERNEL); + if (!hidg->req) + return -ENOMEM; - if (hidg->out_ep != NULL) { - /* restart endpoint */ - usb_ep_disable(hidg->out_ep); + hidg->req->buf = kmalloc(hidg->report_length, GFP_KERNEL); + if (!hidg->req->buf) + return -ENOMEM; - status = config_ep_by_speed(f->config->cdev->gadget, f, - hidg->out_ep); - if (status) { - ERROR(cdev, "config_ep_by_speed FAILED!\n"); - goto fail; - } - status = usb_ep_enable(hidg->out_ep); - if (status < 0) { - ERROR(cdev, "Enable IN endpoint FAILED!\n"); - goto fail; - } -
[PATCH v3 24/36] usb: gadget: f_hid: handle requests lifetime properly
So far USB requests allocated in hidg_set_alt() were not freed. Now we free them in case of hidg_set_alt() failure (when we are not able to allocate and enqueue all the requests) or in hidg_disable() function. Signed-off-by: Robert Baldyga--- drivers/usb/gadget/function/f_hid.c | 22 +- 1 file changed, 21 insertions(+), 1 deletion(-) diff --git a/drivers/usb/gadget/function/f_hid.c b/drivers/usb/gadget/function/f_hid.c index 99285b4..0456a53 100644 --- a/drivers/usb/gadget/function/f_hid.c +++ b/drivers/usb/gadget/function/f_hid.c @@ -59,6 +59,7 @@ struct f_hidg { boolwrite_pending; wait_queue_head_t write_queue; struct usb_request *req; + struct usb_request **out_reqs; int minor; struct cdev cdev; @@ -490,6 +491,7 @@ static void hidg_disable(struct usb_function *f) { struct f_hidg *hidg = func_to_hidg(f); struct f_hidg_req_list *list, *next; + int i; usb_ep_disable(hidg->in_ep); usb_ep_disable(hidg->out_ep); @@ -498,6 +500,12 @@ static void hidg_disable(struct usb_function *f) list_del(>list); kfree(list); } + + for (i = 0; i < hidg->qlen; ++i) { + kfree(hidg->out_reqs[i]->buf); + kfree(hidg->out_reqs[i]); + } + kfree(hidg->out_reqs); } static int hidg_set_alt(struct usb_function *f, unsigned intf, unsigned alt) @@ -547,11 +555,14 @@ static int hidg_set_alt(struct usb_function *f, unsigned intf, unsigned alt) /* * allocate a bunch of read buffers and queue them all at once. */ + hidg->out_reqs = kzalloc(hidg->qlen * + sizeof(*hidg->out_reqs), GFP_KERNEL); for (i = 0; i < hidg->qlen && status == 0; i++) { struct usb_request *req = hidg_alloc_ep_req(hidg->out_ep, hidg->report_length); if (req) { + hidg->out_reqs[i] = req; req->complete = hidg_set_report_complete; req->context = hidg; status = usb_ep_queue(hidg->out_ep, req, @@ -562,11 +573,20 @@ static int hidg_set_alt(struct usb_function *f, unsigned intf, unsigned alt) } else { usb_ep_disable(hidg->out_ep); status = -ENOMEM; - goto fail; + goto free_req; } } } +free_req: + if (status < 0) { + while (i--) { + kfree(hidg->out_reqs[i]->buf); + kfree(hidg->out_reqs[i]); + } + kfree(hidg->out_reqs); + } + fail: return status; } -- 1.9.1 -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v3 31/36] usb: gadget: f_obex: conversion to new API
Generate descriptors in new format and attach them to USB function in prep_descs(). Implement prep_vendor_descs() to supply class specific descriptors. Change set_alt() implementation and implement clear_alt() operation. Remove boilerplate code. Signed-off-by: Robert Baldyga--- drivers/usb/gadget/function/f_obex.c | 188 ++- 1 file changed, 50 insertions(+), 138 deletions(-) diff --git a/drivers/usb/gadget/function/f_obex.c b/drivers/usb/gadget/function/f_obex.c index d6396e0..0c4b1fd 100644 --- a/drivers/usb/gadget/function/f_obex.c +++ b/drivers/usb/gadget/function/f_obex.c @@ -34,7 +34,6 @@ struct f_obex { struct gserial port; u8 ctrl_id; u8 data_id; - u8 cur_alt; u8 port_num; }; @@ -144,19 +143,6 @@ static struct usb_endpoint_descriptor obex_hs_ep_in_desc = { .wMaxPacketSize = cpu_to_le16(512), }; -static struct usb_descriptor_header *hs_function[] = { - (struct usb_descriptor_header *) _control_intf, - (struct usb_descriptor_header *) _cdc_header_desc, - (struct usb_descriptor_header *) _desc, - (struct usb_descriptor_header *) _cdc_union_desc, - - (struct usb_descriptor_header *) _data_nop_intf, - (struct usb_descriptor_header *) _data_intf, - (struct usb_descriptor_header *) _hs_ep_in_desc, - (struct usb_descriptor_header *) _hs_ep_out_desc, - NULL, -}; - /* Full-Speed Support */ static struct usb_endpoint_descriptor obex_fs_ep_in_desc = { @@ -175,18 +161,19 @@ static struct usb_endpoint_descriptor obex_fs_ep_out_desc = { .bmAttributes = USB_ENDPOINT_XFER_BULK, }; -static struct usb_descriptor_header *fs_function[] = { - (struct usb_descriptor_header *) _control_intf, - (struct usb_descriptor_header *) _cdc_header_desc, - (struct usb_descriptor_header *) _desc, - (struct usb_descriptor_header *) _cdc_union_desc, +USB_COMPOSITE_ENDPOINT(ep_in, _fs_ep_in_desc, + _hs_ep_in_desc, NULL, NULL); +USB_COMPOSITE_ENDPOINT(ep_out, _fs_ep_out_desc, + _hs_ep_out_desc, NULL, NULL); - (struct usb_descriptor_header *) _data_nop_intf, - (struct usb_descriptor_header *) _data_intf, - (struct usb_descriptor_header *) _fs_ep_in_desc, - (struct usb_descriptor_header *) _fs_ep_out_desc, - NULL, -}; +USB_COMPOSITE_ALTSETTING(intf0alt0, _control_intf); +USB_COMPOSITE_ALTSETTING(intf1alt0, _data_nop_intf); +USB_COMPOSITE_ALTSETTING(intf1alt1, _data_intf, _in, _out); + +USB_COMPOSITE_INTERFACE(intf0, ); +USB_COMPOSITE_INTERFACE(intf1, , ); + +USB_COMPOSITE_DESCRIPTORS(obex_descs, , ); /*-*/ @@ -195,67 +182,33 @@ static int obex_set_alt(struct usb_function *f, unsigned intf, unsigned alt) struct f_obex *obex = func_to_obex(f); struct usb_composite_dev *cdev = f->config->cdev; - if (intf == obex->ctrl_id) { - if (alt != 0) - goto fail; + if (intf == 0) { /* NOP */ dev_dbg(>gadget->dev, "reset obex ttyGS%d control\n", obex->port_num); - - } else if (intf == obex->data_id) { - if (alt > 1) - goto fail; - - if (obex->port.in->enabled) { - dev_dbg(>gadget->dev, - "reset obex ttyGS%d\n", obex->port_num); - gserial_disconnect(>port); - } - - if (!obex->port.in->desc || !obex->port.out->desc) { - dev_dbg(>gadget->dev, - "init obex ttyGS%d\n", obex->port_num); - if (config_ep_by_speed(cdev->gadget, f, - obex->port.in) || - config_ep_by_speed(cdev->gadget, f, - obex->port.out)) { - obex->port.out->desc = NULL; - obex->port.in->desc = NULL; - goto fail; - } - } - - if (alt == 1) { - dev_dbg(>gadget->dev, + } else if (intf == 1 && alt == 1) { + dev_dbg(>gadget->dev, "activate obex ttyGS%d\n", obex->port_num); - gserial_connect(>port, obex->port_num); - } - } else - goto fail; + obex->port.in = usb_function_get_ep(f, intf, 0); + if (!obex->port.in) + return -ENODEV; + obex->port.out = usb_function_get_ep(f, intf, 1); + if
[PATCH v3 22/36] usb: gadget: f_ecm: conversion to new API
Generate descriptors in new format and attach them to USB function in prep_descs(). Implement prep_vendor_descs() to supply class specific descriptors. Change set_alt() implementation and implement clear_alt() operation. Get rid of get_alt() which now is handled automatically. Remove boilerplate code. Change USB request lifetime management - now it's allocated in set_alt() and freed in clear_alt(). Signed-off-by: Robert Baldyga--- drivers/usb/gadget/function/f_ecm.c | 321 +++- 1 file changed, 92 insertions(+), 229 deletions(-) diff --git a/drivers/usb/gadget/function/f_ecm.c b/drivers/usb/gadget/function/f_ecm.c index 7ad60ee..4627f20 100644 --- a/drivers/usb/gadget/function/f_ecm.c +++ b/drivers/usb/gadget/function/f_ecm.c @@ -214,25 +214,6 @@ static struct usb_endpoint_descriptor fs_ecm_out_desc = { .bmAttributes = USB_ENDPOINT_XFER_BULK, }; -static struct usb_descriptor_header *ecm_fs_function[] = { - /* CDC ECM control descriptors */ - (struct usb_descriptor_header *) _iad_descriptor, - (struct usb_descriptor_header *) _control_intf, - (struct usb_descriptor_header *) _header_desc, - (struct usb_descriptor_header *) _union_desc, - (struct usb_descriptor_header *) _desc, - - /* NOTE: status endpoint might need to be removed */ - (struct usb_descriptor_header *) _ecm_notify_desc, - - /* data interface, altsettings 0 and 1 */ - (struct usb_descriptor_header *) _data_nop_intf, - (struct usb_descriptor_header *) _data_intf, - (struct usb_descriptor_header *) _ecm_in_desc, - (struct usb_descriptor_header *) _ecm_out_desc, - NULL, -}; - /* high speed support: */ static struct usb_endpoint_descriptor hs_ecm_notify_desc = { @@ -263,25 +244,6 @@ static struct usb_endpoint_descriptor hs_ecm_out_desc = { .wMaxPacketSize = cpu_to_le16(512), }; -static struct usb_descriptor_header *ecm_hs_function[] = { - /* CDC ECM control descriptors */ - (struct usb_descriptor_header *) _iad_descriptor, - (struct usb_descriptor_header *) _control_intf, - (struct usb_descriptor_header *) _header_desc, - (struct usb_descriptor_header *) _union_desc, - (struct usb_descriptor_header *) _desc, - - /* NOTE: status endpoint might need to be removed */ - (struct usb_descriptor_header *) _ecm_notify_desc, - - /* data interface, altsettings 0 and 1 */ - (struct usb_descriptor_header *) _data_nop_intf, - (struct usb_descriptor_header *) _data_intf, - (struct usb_descriptor_header *) _ecm_in_desc, - (struct usb_descriptor_header *) _ecm_out_desc, - NULL, -}; - /* super speed support: */ static struct usb_endpoint_descriptor ss_ecm_notify_desc = { @@ -331,27 +293,21 @@ static struct usb_ss_ep_comp_descriptor ss_ecm_bulk_comp_desc = { /* .bmAttributes = 0, */ }; -static struct usb_descriptor_header *ecm_ss_function[] = { - /* CDC ECM control descriptors */ - (struct usb_descriptor_header *) _iad_descriptor, - (struct usb_descriptor_header *) _control_intf, - (struct usb_descriptor_header *) _header_desc, - (struct usb_descriptor_header *) _union_desc, - (struct usb_descriptor_header *) _desc, - - /* NOTE: status endpoint might need to be removed */ - (struct usb_descriptor_header *) _ecm_notify_desc, - (struct usb_descriptor_header *) _ecm_intr_comp_desc, - - /* data interface, altsettings 0 and 1 */ - (struct usb_descriptor_header *) _data_nop_intf, - (struct usb_descriptor_header *) _data_intf, - (struct usb_descriptor_header *) _ecm_in_desc, - (struct usb_descriptor_header *) _ecm_bulk_comp_desc, - (struct usb_descriptor_header *) _ecm_out_desc, - (struct usb_descriptor_header *) _ecm_bulk_comp_desc, - NULL, -}; +USB_COMPOSITE_ENDPOINT(ep_notify, _ecm_notify_desc, _ecm_notify_desc, + _ecm_notify_desc, _ecm_intr_comp_desc); +USB_COMPOSITE_ENDPOINT(ep_in, _ecm_in_desc, _ecm_in_desc, + _ecm_in_desc, _ecm_bulk_comp_desc); +USB_COMPOSITE_ENDPOINT(ep_out, _ecm_out_desc, _ecm_out_desc, + _ecm_out_desc, _ecm_bulk_comp_desc); + +USB_COMPOSITE_ALTSETTING(intf0alt0, _control_intf, _notify); +USB_COMPOSITE_ALTSETTING(intf1alt0, _data_nop_intf); +USB_COMPOSITE_ALTSETTING(intf1alt1, _data_intf, _in, _out); + +USB_COMPOSITE_INTERFACE(intf0, ); +USB_COMPOSITE_INTERFACE(intf1, , ); + +USB_COMPOSITE_DESCRIPTORS(ecm_descs, , ); /* string descriptors: */ @@ -537,47 +493,43 @@ static int ecm_set_alt(struct usb_function *f, unsigned intf, unsigned alt) struct usb_composite_dev *cdev = f->config->cdev; /* Control interface has only altsetting 0 */ - if (intf == ecm->ctrl_id) { - if (alt != 0) - goto fail; + if (intf == 0) { + /* NOTE: a
[PATCH v3 23/36] usb: gadget: f_rndis: conversion to new API
Generate descriptors in new format and attach them to USB function in prep_descs(). Implement prep_vendor_descs() to supply class specific descriptors. Change set_alt() implementation and implement clear_alt() operation. Remove boilerplate code. Change USB request lifetime management - now it's allocated in set_alt() and freed in clear_alt(). Signed-off-by: Robert Baldyga--- drivers/usb/gadget/function/f_rndis.c | 321 -- 1 file changed, 112 insertions(+), 209 deletions(-) diff --git a/drivers/usb/gadget/function/f_rndis.c b/drivers/usb/gadget/function/f_rndis.c index e587767..abe11a7 100644 --- a/drivers/usb/gadget/function/f_rndis.c +++ b/drivers/usb/gadget/function/f_rndis.c @@ -212,24 +212,6 @@ static struct usb_endpoint_descriptor fs_out_desc = { .bmAttributes = USB_ENDPOINT_XFER_BULK, }; -static struct usb_descriptor_header *eth_fs_function[] = { - (struct usb_descriptor_header *) _iad_descriptor, - - /* control interface matches ACM, not Ethernet */ - (struct usb_descriptor_header *) _control_intf, - (struct usb_descriptor_header *) _desc, - (struct usb_descriptor_header *) _mgmt_descriptor, - (struct usb_descriptor_header *) _acm_descriptor, - (struct usb_descriptor_header *) _union_desc, - (struct usb_descriptor_header *) _notify_desc, - - /* data interface has no altsetting */ - (struct usb_descriptor_header *) _data_intf, - (struct usb_descriptor_header *) _in_desc, - (struct usb_descriptor_header *) _out_desc, - NULL, -}; - /* high speed support: */ static struct usb_endpoint_descriptor hs_notify_desc = { @@ -260,24 +242,6 @@ static struct usb_endpoint_descriptor hs_out_desc = { .wMaxPacketSize = cpu_to_le16(512), }; -static struct usb_descriptor_header *eth_hs_function[] = { - (struct usb_descriptor_header *) _iad_descriptor, - - /* control interface matches ACM, not Ethernet */ - (struct usb_descriptor_header *) _control_intf, - (struct usb_descriptor_header *) _desc, - (struct usb_descriptor_header *) _mgmt_descriptor, - (struct usb_descriptor_header *) _acm_descriptor, - (struct usb_descriptor_header *) _union_desc, - (struct usb_descriptor_header *) _notify_desc, - - /* data interface has no altsetting */ - (struct usb_descriptor_header *) _data_intf, - (struct usb_descriptor_header *) _in_desc, - (struct usb_descriptor_header *) _out_desc, - NULL, -}; - /* super speed support: */ static struct usb_endpoint_descriptor ss_notify_desc = { @@ -327,26 +291,20 @@ static struct usb_ss_ep_comp_descriptor ss_bulk_comp_desc = { /* .bmAttributes = 0, */ }; -static struct usb_descriptor_header *eth_ss_function[] = { - (struct usb_descriptor_header *) _iad_descriptor, - - /* control interface matches ACM, not Ethernet */ - (struct usb_descriptor_header *) _control_intf, - (struct usb_descriptor_header *) _desc, - (struct usb_descriptor_header *) _mgmt_descriptor, - (struct usb_descriptor_header *) _acm_descriptor, - (struct usb_descriptor_header *) _union_desc, - (struct usb_descriptor_header *) _notify_desc, - (struct usb_descriptor_header *) _intr_comp_desc, - - /* data interface has no altsetting */ - (struct usb_descriptor_header *) _data_intf, - (struct usb_descriptor_header *) _in_desc, - (struct usb_descriptor_header *) _bulk_comp_desc, - (struct usb_descriptor_header *) _out_desc, - (struct usb_descriptor_header *) _bulk_comp_desc, - NULL, -}; +USB_COMPOSITE_ENDPOINT(ep_notify, _notify_desc, _notify_desc, + _notify_desc, _intr_comp_desc); +USB_COMPOSITE_ENDPOINT(ep_in, _in_desc, _in_desc, + _in_desc, _bulk_comp_desc); +USB_COMPOSITE_ENDPOINT(ep_out, _out_desc, _out_desc, + _out_desc, _bulk_comp_desc); + +USB_COMPOSITE_ALTSETTING(intf0alt0, _control_intf, _notify); +USB_COMPOSITE_ALTSETTING(intf1alt0, _data_intf, _in, _out); + +USB_COMPOSITE_INTERFACE(intf0, ); +USB_COMPOSITE_INTERFACE(intf1, ); + +USB_COMPOSITE_DESCRIPTORS(rndis_descs, , ); /* string descriptors: */ @@ -542,36 +500,35 @@ static int rndis_set_alt(struct usb_function *f, unsigned intf, unsigned alt) /* we know alt == 0 */ - if (intf == rndis->ctrl_id) { + if (intf == 0) { VDBG(cdev, "reset rndis control %d\n", intf); - usb_ep_disable(rndis->notify); - if (!rndis->notify->desc) { - VDBG(cdev, "init rndis ctrl %d\n", intf); - if (config_ep_by_speed(cdev->gadget, f, rndis->notify)) - goto fail; - } - usb_ep_enable(rndis->notify); - - } else if (intf == rndis->data_id) { - struct net_device *net; +
[PATCH v3 26/36] usb: gadget: f_acm: conversion to new API
Generate descriptors in new format and attach them to USB function in prep_descs(). Implement prep_vendor_descs() to supply class specific descriptors. Change set_alt() implementation and implement clear_alt() operation. Remove boilerplate code. Signed-off-by: Robert Baldyga--- drivers/usb/gadget/function/f_acm.c | 248 1 file changed, 78 insertions(+), 170 deletions(-) diff --git a/drivers/usb/gadget/function/f_acm.c b/drivers/usb/gadget/function/f_acm.c index 2fa1e80..0d3fe1a 100644 --- a/drivers/usb/gadget/function/f_acm.c +++ b/drivers/usb/gadget/function/f_acm.c @@ -185,20 +185,6 @@ static struct usb_endpoint_descriptor acm_fs_out_desc = { .bmAttributes = USB_ENDPOINT_XFER_BULK, }; -static struct usb_descriptor_header *acm_fs_function[] = { - (struct usb_descriptor_header *) _iad_descriptor, - (struct usb_descriptor_header *) _control_interface_desc, - (struct usb_descriptor_header *) _header_desc, - (struct usb_descriptor_header *) _call_mgmt_descriptor, - (struct usb_descriptor_header *) _descriptor, - (struct usb_descriptor_header *) _union_desc, - (struct usb_descriptor_header *) _fs_notify_desc, - (struct usb_descriptor_header *) _data_interface_desc, - (struct usb_descriptor_header *) _fs_in_desc, - (struct usb_descriptor_header *) _fs_out_desc, - NULL, -}; - /* high speed support: */ static struct usb_endpoint_descriptor acm_hs_notify_desc = { .bLength = USB_DT_ENDPOINT_SIZE, @@ -223,20 +209,6 @@ static struct usb_endpoint_descriptor acm_hs_out_desc = { .wMaxPacketSize = cpu_to_le16(512), }; -static struct usb_descriptor_header *acm_hs_function[] = { - (struct usb_descriptor_header *) _iad_descriptor, - (struct usb_descriptor_header *) _control_interface_desc, - (struct usb_descriptor_header *) _header_desc, - (struct usb_descriptor_header *) _call_mgmt_descriptor, - (struct usb_descriptor_header *) _descriptor, - (struct usb_descriptor_header *) _union_desc, - (struct usb_descriptor_header *) _hs_notify_desc, - (struct usb_descriptor_header *) _data_interface_desc, - (struct usb_descriptor_header *) _hs_in_desc, - (struct usb_descriptor_header *) _hs_out_desc, - NULL, -}; - static struct usb_endpoint_descriptor acm_ss_in_desc = { .bLength = USB_DT_ENDPOINT_SIZE, .bDescriptorType = USB_DT_ENDPOINT, @@ -256,22 +228,20 @@ static struct usb_ss_ep_comp_descriptor acm_ss_bulk_comp_desc = { .bDescriptorType = USB_DT_SS_ENDPOINT_COMP, }; -static struct usb_descriptor_header *acm_ss_function[] = { - (struct usb_descriptor_header *) _iad_descriptor, - (struct usb_descriptor_header *) _control_interface_desc, - (struct usb_descriptor_header *) _header_desc, - (struct usb_descriptor_header *) _call_mgmt_descriptor, - (struct usb_descriptor_header *) _descriptor, - (struct usb_descriptor_header *) _union_desc, - (struct usb_descriptor_header *) _hs_notify_desc, - (struct usb_descriptor_header *) _ss_bulk_comp_desc, - (struct usb_descriptor_header *) _data_interface_desc, - (struct usb_descriptor_header *) _ss_in_desc, - (struct usb_descriptor_header *) _ss_bulk_comp_desc, - (struct usb_descriptor_header *) _ss_out_desc, - (struct usb_descriptor_header *) _ss_bulk_comp_desc, - NULL, -}; +USB_COMPOSITE_ENDPOINT(ep_notify, _fs_notify_desc, _hs_notify_desc, + _hs_notify_desc, _ss_bulk_comp_desc); +USB_COMPOSITE_ENDPOINT(ep_in, _fs_in_desc, _hs_in_desc, + _ss_in_desc, _ss_bulk_comp_desc); +USB_COMPOSITE_ENDPOINT(ep_out, _fs_out_desc, _hs_out_desc, + _ss_out_desc, _ss_bulk_comp_desc); + +USB_COMPOSITE_ALTSETTING(intf0alt0, _control_interface_desc, _notify); +USB_COMPOSITE_ALTSETTING(intf1alt0, _data_interface_desc, _in, _out); + +USB_COMPOSITE_INTERFACE(intf0, ); +USB_COMPOSITE_INTERFACE(intf1, ); + +USB_COMPOSITE_DESCRIPTORS(acm_descs, , ); /* string descriptors: */ @@ -420,6 +390,8 @@ invalid: return value; } +static void acm_cdc_notify_complete(struct usb_ep *ep, struct usb_request *req); + static int acm_set_alt(struct usb_function *f, unsigned intf, unsigned alt) { struct f_acm*acm = func_to_acm(f); @@ -427,51 +399,49 @@ static int acm_set_alt(struct usb_function *f, unsigned intf, unsigned alt) /* we know alt == 0, so this is an activation or a reset */ - if (intf == acm->ctrl_id) { + if (intf == 0) { dev_vdbg(>gadget->dev, "reset acm control interface %d\n", intf); - usb_ep_disable(acm->notify); - - if (!acm->notify->desc) - if (config_ep_by_speed(cdev->gadget, f, acm->notify)) - return
[PATCH v3 30/36] usb: gadget: f_serial: conversion to new API
Generate descriptors in new format and attach them to USB function in prep_descs(). Change set_alt() implementation and implement clear_alt() operation. Remove boilerplate code. Signed-off-by: Robert Baldyga--- drivers/usb/gadget/function/f_serial.c | 122 +++-- 1 file changed, 25 insertions(+), 97 deletions(-) diff --git a/drivers/usb/gadget/function/f_serial.c b/drivers/usb/gadget/function/f_serial.c index 6bb44d61..526e664 100644 --- a/drivers/usb/gadget/function/f_serial.c +++ b/drivers/usb/gadget/function/f_serial.c @@ -69,13 +69,6 @@ static struct usb_endpoint_descriptor gser_fs_out_desc = { .bmAttributes = USB_ENDPOINT_XFER_BULK, }; -static struct usb_descriptor_header *gser_fs_function[] = { - (struct usb_descriptor_header *) _interface_desc, - (struct usb_descriptor_header *) _fs_in_desc, - (struct usb_descriptor_header *) _fs_out_desc, - NULL, -}; - /* high speed support: */ static struct usb_endpoint_descriptor gser_hs_in_desc = { @@ -92,13 +85,6 @@ static struct usb_endpoint_descriptor gser_hs_out_desc = { .wMaxPacketSize = cpu_to_le16(512), }; -static struct usb_descriptor_header *gser_hs_function[] = { - (struct usb_descriptor_header *) _interface_desc, - (struct usb_descriptor_header *) _hs_in_desc, - (struct usb_descriptor_header *) _hs_out_desc, - NULL, -}; - static struct usb_endpoint_descriptor gser_ss_in_desc = { .bLength = USB_DT_ENDPOINT_SIZE, .bDescriptorType = USB_DT_ENDPOINT, @@ -118,14 +104,16 @@ static struct usb_ss_ep_comp_descriptor gser_ss_bulk_comp_desc = { .bDescriptorType = USB_DT_SS_ENDPOINT_COMP, }; -static struct usb_descriptor_header *gser_ss_function[] = { - (struct usb_descriptor_header *) _interface_desc, - (struct usb_descriptor_header *) _ss_in_desc, - (struct usb_descriptor_header *) _ss_bulk_comp_desc, - (struct usb_descriptor_header *) _ss_out_desc, - (struct usb_descriptor_header *) _ss_bulk_comp_desc, - NULL, -}; +USB_COMPOSITE_ENDPOINT(ep_in, _fs_in_desc, _hs_in_desc, + _ss_in_desc, _ss_bulk_comp_desc); +USB_COMPOSITE_ENDPOINT(ep_out, _fs_out_desc, _hs_out_desc, + _ss_out_desc, _ss_bulk_comp_desc); + +USB_COMPOSITE_ALTSETTING(intf0alt0, _interface_desc, _in, _out); + +USB_COMPOSITE_INTERFACE(intf0, ); + +USB_COMPOSITE_DESCRIPTORS(serial_descs, ); /* string descriptors: */ @@ -151,28 +139,21 @@ static int gser_set_alt(struct usb_function *f, unsigned intf, unsigned alt) struct f_gser *gser = func_to_gser(f); struct usb_composite_dev *cdev = f->config->cdev; - /* we know alt == 0, so this is an activation or a reset */ - - if (gser->port.in->enabled) { - dev_dbg(>gadget->dev, - "reset generic ttyGS%d\n", gser->port_num); - gserial_disconnect(>port); - } - if (!gser->port.in->desc || !gser->port.out->desc) { - dev_dbg(>gadget->dev, + dev_dbg(>gadget->dev, "activate generic ttyGS%d\n", gser->port_num); - if (config_ep_by_speed(cdev->gadget, f, gser->port.in) || - config_ep_by_speed(cdev->gadget, f, gser->port.out)) { - gser->port.in->desc = NULL; - gser->port.out->desc = NULL; - return -EINVAL; - } - } + + gser->port.in = usb_function_get_ep(f, intf, 0); + if (!gser->port.in) + return -ENODEV; + gser->port.out = usb_function_get_ep(f, intf, 0); + if (!gser->port.out) + return -ENODEV; + gserial_connect(>port, gser->port_num); return 0; } -static void gser_disable(struct usb_function *f) +static void gser_clear_alt(struct usb_function *f, unsigned intf, unsigned alt) { struct f_gser *gser = func_to_gser(f); struct usb_composite_dev *cdev = f->config->cdev; @@ -186,12 +167,9 @@ static void gser_disable(struct usb_function *f) /* serial function driver setup/binding */ -static int gser_bind(struct usb_configuration *c, struct usb_function *f) +static int gser_prep_descs(struct usb_function *f) { - struct usb_composite_dev *cdev = c->cdev; - struct f_gser *gser = func_to_gser(f); int status; - struct usb_ep *ep; /* REVISIT might want instance-specific strings to help * distinguish instances ... @@ -199,57 +177,13 @@ static int gser_bind(struct usb_configuration *c, struct usb_function *f) /* maybe allocate device-global string ID */ if (gser_string_defs[0].id == 0) { - status = usb_string_id(c->cdev); + status = usb_string_id(f->config->cdev); if (status < 0) return status;
[PATCH v3 27/36] usb: gadget: f_eem: conversion to new API
Generate descriptors in new format and attach them to USB function in prep_descs(). Implement prep_vendor_descs() to supply class specific descriptors. Change set_alt() implementation and implement clear_alt() operation. Remove boilerplate code. Signed-off-by: Robert Baldyga--- drivers/usb/gadget/function/f_eem.c | 154 1 file changed, 33 insertions(+), 121 deletions(-) diff --git a/drivers/usb/gadget/function/f_eem.c b/drivers/usb/gadget/function/f_eem.c index cad35a5..8896419 100644 --- a/drivers/usb/gadget/function/f_eem.c +++ b/drivers/usb/gadget/function/f_eem.c @@ -73,14 +73,6 @@ static struct usb_endpoint_descriptor eem_fs_out_desc = { .bmAttributes = USB_ENDPOINT_XFER_BULK, }; -static struct usb_descriptor_header *eem_fs_function[] = { - /* CDC EEM control descriptors */ - (struct usb_descriptor_header *) _intf, - (struct usb_descriptor_header *) _fs_in_desc, - (struct usb_descriptor_header *) _fs_out_desc, - NULL, -}; - /* high speed support: */ static struct usb_endpoint_descriptor eem_hs_in_desc = { @@ -101,14 +93,6 @@ static struct usb_endpoint_descriptor eem_hs_out_desc = { .wMaxPacketSize = cpu_to_le16(512), }; -static struct usb_descriptor_header *eem_hs_function[] = { - /* CDC EEM control descriptors */ - (struct usb_descriptor_header *) _intf, - (struct usb_descriptor_header *) _hs_in_desc, - (struct usb_descriptor_header *) _hs_out_desc, - NULL, -}; - /* super speed support: */ static struct usb_endpoint_descriptor eem_ss_in_desc = { @@ -138,15 +122,16 @@ static struct usb_ss_ep_comp_descriptor eem_ss_bulk_comp_desc = { /* .bmAttributes = 0, */ }; -static struct usb_descriptor_header *eem_ss_function[] = { - /* CDC EEM control descriptors */ - (struct usb_descriptor_header *) _intf, - (struct usb_descriptor_header *) _ss_in_desc, - (struct usb_descriptor_header *) _ss_bulk_comp_desc, - (struct usb_descriptor_header *) _ss_out_desc, - (struct usb_descriptor_header *) _ss_bulk_comp_desc, - NULL, -}; +USB_COMPOSITE_ENDPOINT(ep_in, _fs_in_desc, _hs_in_desc, + _ss_in_desc, _ss_bulk_comp_desc); +USB_COMPOSITE_ENDPOINT(ep_out, _fs_out_desc, _hs_out_desc, + _ss_out_desc, _ss_bulk_comp_desc); + +USB_COMPOSITE_ALTSETTING(intf0alt0, _intf, _in, _out); + +USB_COMPOSITE_INTERFACE(intf0, ); + +USB_COMPOSITE_DESCRIPTORS(eem_descs, ); /* string descriptors: */ @@ -190,65 +175,46 @@ static int eem_set_alt(struct usb_function *f, unsigned intf, unsigned alt) struct usb_composite_dev *cdev = f->config->cdev; struct net_device *net; - /* we know alt == 0, so this is an activation or a reset */ - if (alt != 0) - goto fail; - - if (intf == eem->ctrl_id) { - DBG(cdev, "reset eem\n"); - gether_disconnect(>port); - - if (!eem->port.in_ep->desc || !eem->port.out_ep->desc) { - DBG(cdev, "init eem\n"); - if (config_ep_by_speed(cdev->gadget, f, - eem->port.in_ep) || - config_ep_by_speed(cdev->gadget, f, - eem->port.out_ep)) { - eem->port.in_ep->desc = NULL; - eem->port.out_ep->desc = NULL; - goto fail; - } - } + eem->port.in_ep = usb_function_get_ep(f, intf, 0); + if (!eem->port.in_ep) + return -ENODEV; - /* zlps should not occur because zero-length EEM packets -* will be inserted in those cases where they would occur -*/ - eem->port.is_zlp_ok = 1; - eem->port.cdc_filter = DEFAULT_FILTER; - DBG(cdev, "activate eem\n"); - net = gether_connect(>port); - if (IS_ERR(net)) - return PTR_ERR(net); - } else - goto fail; + eem->port.out_ep = usb_function_get_ep(f, intf, 1); + if (!eem->port.out_ep) + return -ENODEV; + + /* zlps should not occur because zero-length EEM packets +* will be inserted in those cases where they would occur +*/ + eem->port.is_zlp_ok = 1; + eem->port.cdc_filter = DEFAULT_FILTER; + DBG(cdev, "activate eem\n"); + net = gether_connect(>port); + if (IS_ERR(net)) + return PTR_ERR(net); return 0; -fail: - return -EINVAL; } -static void eem_disable(struct usb_function *f) +static void eem_clear_alt(struct usb_function *f, unsigned intf, unsigned alt) { struct f_eem*eem = func_to_eem(f); struct usb_composite_dev *cdev = f->config->cdev;
Re: [PATCH v2] usb: gadget: ether: Allow changing the MTU
Just a "ping" reminder, I'd like to inquire about the status of this patch... On 30-11-15 12:18, Mike Looijmans wrote: The gadget ethernet driver supports changing the MTU, but only allows this when the USB cable is removed. The comment indicates that this is because the "peer won't know". Even if the network link is still down and only the USB link is established, the driver won't allow the change. Other network interfaces allow changing the MTU any time, and don't force the link to be disabled. This makes perfect sense, because in order to be able to negotiate the MTU, the link needs to be up. Remove the restriction so that it is now actually possible to change the MTU (e.g. using "ifconfig usb0 mtu 15000") without having to manually pull the plug or change the driver's default setting. This is especially important after commit bba787a860fa ("usb: gadget: ether: Allow jumbo frames") Signed-off-by: Mike Looijmans--- v2: Fix commit reference (checkpatch) and unused variable 'dev' (kbuild test robot) drivers/usb/gadget/function/u_ether.c | 18 -- 1 file changed, 4 insertions(+), 14 deletions(-) diff --git a/drivers/usb/gadget/function/u_ether.c b/drivers/usb/gadget/function/u_ether.c index 6554322..637809e 100644 --- a/drivers/usb/gadget/function/u_ether.c +++ b/drivers/usb/gadget/function/u_ether.c @@ -143,21 +143,11 @@ static inline int qlen(struct usb_gadget *gadget, unsigned qmult) static int ueth_change_mtu(struct net_device *net, int new_mtu) { - struct eth_dev *dev = netdev_priv(net); - unsigned long flags; - int status = 0; + if (new_mtu <= ETH_HLEN || new_mtu > GETHER_MAX_ETH_FRAME_LEN) + return -ERANGE; + net->mtu = new_mtu; - /* don't change MTU on "live" link (peer won't know) */ - spin_lock_irqsave(>lock, flags); - if (dev->port_usb) - status = -EBUSY; - else if (new_mtu <= ETH_HLEN || new_mtu > GETHER_MAX_ETH_FRAME_LEN) - status = -ERANGE; - else - net->mtu = new_mtu; - spin_unlock_irqrestore(>lock, flags); - - return status; + return 0; } static void eth_get_drvinfo(struct net_device *net, struct ethtool_drvinfo *p) Kind regards, Mike Looijmans System Expert TOPIC Embedded Products Eindhovenseweg 32-C, NL-5683 KH Best Postbus 440, NL-5680 AK Best Telefoon: +31 (0) 499 33 69 79 Telefax: +31 (0) 499 33 69 70 E-mail: mike.looijm...@topicproducts.com Website: www.topicproducts.com Please consider the environment before printing this e-mail -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 1/2] usb: serial: remove redundant conditions
On Fri, Dec 11, 2015 at 06:46:41AM -0300, Geyslan G. Bem wrote: > This patch removes redundant conditions. > > (!A || (A && B)) is the same as (!A || B). > > Tested by compilation only. > Caught by cppcheck. > > Signed-off-by: Geyslan G. BemYou forgot to update the commit summary (to include the driver name) when splitting the original patch. I fixed that up and applied both for next. Thanks, Johan -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH] USB: serial: option: add support for Quectel UC20
Dan and Björn, On Thu, Dec 10, 2015 at 04:42:52PM +0100, yegorsli...@googlemail.com wrote: > From: Yegor Yefremov> > Signed-off-by: Yegor Yefremov > --- > drivers/usb/serial/option.c | 1 + > 1 file changed, 1 insertion(+) > > diff --git a/drivers/usb/serial/option.c b/drivers/usb/serial/option.c > index f228060..e0950bf 100644 > --- a/drivers/usb/serial/option.c > +++ b/drivers/usb/serial/option.c > @@ -1113,6 +1113,7 @@ static const struct usb_device_id option_ids[] = { > { USB_DEVICE(QUALCOMM_VENDOR_ID, 0x6613)}, /* Onda H600/ZTE MF330 */ > { USB_DEVICE(QUALCOMM_VENDOR_ID, 0x0023)}, /* ONYX 3G device */ > { USB_DEVICE(QUALCOMM_VENDOR_ID, 0x9000)}, /* SIMCom SIM5218 */ > + { USB_DEVICE(QUALCOMM_VENDOR_ID, 0x9003)}, /* Quectel UC20 */ Does this one belong in option or qcserial? I see that {DEVICE_G1K(0x05c6, 0x9001)}, /* Generic Gobi Modem device */ {DEVICE_G1K(0x05c6, 0x9002)}, /* Generic Gobi Modem device */ are already handled by the latter (while 0x9000 isn't). Thanks, Johan -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: USB3 xHCI Error, unable to acces the disk
On 11.12.2015 13:06, Sébastien Deligny wrote: Hello, Thanks for your support, I don't know if the problem occur if the SSD is not connected as root partition and it will be difficult to test it as the internal SSD is windows7 type and I can't modify it (it's a professional laptop from my company). I will test with xhci debugging... Do I have to check the output of the debugging in journalctl or somewhere else? after the issue is triggered type: dmesg > logfile -Mathias -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v3 17/36] usb: gadget: composite: add usb_get_interface_id() function
Introduce function returning id of interface at given index in function. The id value is equal bInterfaceNumber field in interface descriptor. This value can be useful during preparation of class or vendor specific descriptors in prep_vendor_descs() callback. It can be also necessary to handle some class or vendor specific setup requests. Signed-off-by: Robert Baldyga--- drivers/usb/gadget/composite.c | 19 +++ include/linux/usb/composite.h | 2 ++ 2 files changed, 21 insertions(+) diff --git a/drivers/usb/gadget/composite.c b/drivers/usb/gadget/composite.c index d7e7d0b..261023b 100644 --- a/drivers/usb/gadget/composite.c +++ b/drivers/usb/gadget/composite.c @@ -674,6 +674,25 @@ static int usb_interface_id_to_index(struct usb_function *f, u8 id) } /** + * usb_get_interface_id - get id number of interface at given index in + * USB function + * @f: USB function + * @i: index of interface in function + * + * Returns interface id on success, else negative errno. + */ +int usb_get_interface_id(struct usb_function *f, int i) +{ + if (!f->descs) + return -ENODEV; + if (f->descs->intfs_num <= i) + return -ENODEV; + + return f->descs->intfs[i]->id; +} +EXPORT_SYMBOL_GPL(usb_get_interface_id); + +/** * usb_function_get_ep - obtains endpoint of given index from active * altsetting of given interface * @f: USB function diff --git a/include/linux/usb/composite.h b/include/linux/usb/composite.h index e12921c..b6f5447 100644 --- a/include/linux/usb/composite.h +++ b/include/linux/usb/composite.h @@ -418,6 +418,8 @@ int usb_ep_add_vendor_desc(struct usb_function *f, int i, int a, int e, struct usb_descriptor_header *desc); +int usb_get_interface_id(struct usb_function *f, int i); + struct usb_ep *usb_function_get_ep(struct usb_function *f, int intf, int ep); int usb_interface_id(struct usb_configuration *, struct usb_function *); -- 1.9.1 -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v3 18/36] usb: gadget: composite: enable adding USB functions using new API
Enable adding USB functions which use new API. Check if all necessary function ops are supplied and call prep_descs() to allow function register it's entity descriptors. Notice that bind() function is not called for USB functions using new API, as now bind procedure is handled for them in composite framework. Signed-off-by: Robert Baldyga--- drivers/usb/gadget/composite.c | 40 +++- 1 file changed, 31 insertions(+), 9 deletions(-) diff --git a/drivers/usb/gadget/composite.c b/drivers/usb/gadget/composite.c index 261023b..bdd7a2c 100644 --- a/drivers/usb/gadget/composite.c +++ b/drivers/usb/gadget/composite.c @@ -181,6 +181,8 @@ ep_found: } EXPORT_SYMBOL_GPL(config_ep_by_speed); +static inline bool usb_function_is_new_api(struct usb_function *f); + /** * usb_add_function() - add a function to a configuration * @config: the configuration @@ -198,15 +200,12 @@ EXPORT_SYMBOL_GPL(config_ep_by_speed); int usb_add_function(struct usb_configuration *config, struct usb_function *function) { - int value = -EINVAL; + int value; DBG(config->cdev, "adding '%s'/%p to config '%s'/%p\n", function->name, function, config->label, config); - if (!function->set_alt || !function->disable) - goto done; - function->config = config; list_add_tail(>list, >functions); @@ -216,13 +215,22 @@ int usb_add_function(struct usb_configuration *config, goto done; } + value = -EINVAL; + + if (!function->set_alt) + goto done; + + if (usb_function_is_new_api(function)) + goto new_api; + + if (!function->disable) + goto done; + /* REVISIT *require* function->bind? */ if (function->bind) { value = function->bind(config, function); - if (value < 0) { - list_del(>list); - function->config = NULL; - } + if (value < 0) + goto done; } else value = 0; @@ -238,10 +246,24 @@ int usb_add_function(struct usb_configuration *config, if (!config->superspeed && function->ss_descriptors) config->superspeed = true; + goto done; + +new_api: + if (!function->prep_descs) + goto done; + + if (!function->clear_alt) + goto done; + + value = function->prep_descs(function); + done: - if (value) + if (value) { + list_del(>list); + function->config = NULL; DBG(config->cdev, "adding '%s'/%p --> %d\n", function->name, function, value); + } return value; } EXPORT_SYMBOL_GPL(usb_add_function); -- 1.9.1 -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v3 16/36] usb: gadget: composite: add usb_function_get_ep() function
Introduce function returning endpoint of given index in active altsetting of specified interface. It's intended to be used in set_alt() callback to obtain endpoints of currently selected altsetting. Signed-off-by: Robert Baldyga--- drivers/usb/gadget/composite.c | 33 + include/linux/usb/composite.h | 2 ++ 2 files changed, 35 insertions(+) diff --git a/drivers/usb/gadget/composite.c b/drivers/usb/gadget/composite.c index d78e63f..d7e7d0b 100644 --- a/drivers/usb/gadget/composite.c +++ b/drivers/usb/gadget/composite.c @@ -674,6 +674,39 @@ static int usb_interface_id_to_index(struct usb_function *f, u8 id) } /** + * usb_function_get_ep - obtains endpoint of given index from active + * altsetting of given interface + * @f: USB function + * @i: index of interface in given function + * @e: index of endpoint in active altsetting of given interface + * + * This function is designed to be used in set_alt() callback, when + * new altsetting is selected. It allows to obtain endpoints assigned + * to altsetting during autoconfig process. + * + * Returns pointer to endpoint on success or NULL on failure. + */ +struct usb_ep *usb_function_get_ep(struct usb_function *f, int i, int e) +{ + struct usb_composite_altset *altset; + int selected_altset; + + if (!f->descs) + return NULL; + if (i >= f->descs->intfs_num) + return NULL; + + selected_altset = f->descs->intfs[i]->cur_altset; + altset = f->descs->intfs[i]->altsets[selected_altset]; + + if (e >= altset->eps_num) + return NULL; + + return altset->eps[e]->ep; +} +EXPORT_SYMBOL_GPL(usb_function_get_ep); + +/** * usb_interface_id() - allocate an unused interface ID * @config: configuration associated with the interface * @function: function handling the interface diff --git a/include/linux/usb/composite.h b/include/linux/usb/composite.h index 3838eb6..e12921c 100644 --- a/include/linux/usb/composite.h +++ b/include/linux/usb/composite.h @@ -418,6 +418,8 @@ int usb_ep_add_vendor_desc(struct usb_function *f, int i, int a, int e, struct usb_descriptor_header *desc); +struct usb_ep *usb_function_get_ep(struct usb_function *f, int intf, int ep); + int usb_interface_id(struct usb_configuration *, struct usb_function *); int config_ep_by_speed(struct usb_gadget *g, struct usb_function *f, -- 1.9.1 -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v3 19/36] usb: gadget: configfs: add new composite API support
Handle functions using new API properly. Signed-off-by: Robert Baldyga--- drivers/usb/gadget/configfs.c | 22 ++ 1 file changed, 22 insertions(+) diff --git a/drivers/usb/gadget/configfs.c b/drivers/usb/gadget/configfs.c index 0557f80..153adf7 100644 --- a/drivers/usb/gadget/configfs.c +++ b/drivers/usb/gadget/configfs.c @@ -1355,6 +1355,11 @@ static int configfs_composite_bind(struct usb_gadget *gadget, goto err_purge_funcs; } } + + ret = usb_config_do_bind(c); + if (ret) + goto err_purge_funcs; + usb_ep_autoconfig_reset(cdev->gadget); } if (cdev->use_os_string) { @@ -1363,10 +1368,23 @@ static int configfs_composite_bind(struct usb_gadget *gadget, goto err_purge_funcs; } + ret = composite_prep_vendor_descs(cdev); + if (ret < 0) + goto err_free_vendor_descs; + + ret = composite_generate_old_descs(cdev); + if (ret < 0) + goto err_free_old_descs; + usb_ep_autoconfig_reset(cdev->gadget); return 0; +err_free_old_descs: + composite_free_old_descs(cdev); +err_free_vendor_descs: + composite_free_vendor_descs(cdev); err_purge_funcs: + composite_free_descs(cdev); purge_configs_funcs(gi); err_comp_cleanup: composite_dev_cleanup(cdev); @@ -1383,6 +1401,10 @@ static void configfs_composite_unbind(struct usb_gadget *gadget) cdev = get_gadget_data(gadget); gi = container_of(cdev, struct gadget_info, cdev); + composite_free_old_descs(cdev); + composite_free_vendor_descs(cdev); + composite_free_descs(cdev); + kfree(otg_desc[0]); otg_desc[0] = NULL; purge_configs_funcs(gi); -- 1.9.1 -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v3 15/36] usb: gadget: composite: handle get_alt() automatically
As now we store current altsetting number for each interface, we can handle USB_REQ_GET_INTERFACE automatically. Signed-off-by: Robert Baldyga--- drivers/usb/gadget/composite.c | 8 +++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/drivers/usb/gadget/composite.c b/drivers/usb/gadget/composite.c index 48af787..d78e63f 100644 --- a/drivers/usb/gadget/composite.c +++ b/drivers/usb/gadget/composite.c @@ -2078,7 +2078,13 @@ composite_setup(struct usb_gadget *gadget, const struct usb_ctrlrequest *ctrl) if (!f) break; /* lots of interfaces only need altsetting zero... */ - value = f->get_alt ? f->get_alt(f, w_index) : 0; + if (usb_function_is_new_api(f)) { + value = usb_interface_id_to_index(f, intf); + if (value >= 0) + value = f->descs->intfs[value]->cur_altset; + } else { + value = f->get_alt ? f->get_alt(f, w_index) : 0; + } if (value < 0) break; *((u8 *)req->buf) = value; -- 1.9.1 -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v3 21/36] usb: gadget: f_sourcesink: convert to new API
Generate descriptors in new format and attach them to USB function in prep_descs(). Change set_alt() implementation and implement clear_alt() operation. Get rid of get_alt() callback, as now USB_REQ_GET_INTERFACE is handled automatically by composite framwework. Remove unnecessary boilerplate code. Call usb_config_do_bind() in legacy gadget zero, because it uses usb_add_config_only() instead of usb_add_config() and prepares configuration manually. Signed-off-by: Robert Baldyga--- drivers/usb/gadget/function/f_sourcesink.c | 314 ++--- drivers/usb/gadget/function/g_zero.h | 3 - drivers/usb/gadget/legacy/zero.c | 3 + 3 files changed, 65 insertions(+), 255 deletions(-) diff --git a/drivers/usb/gadget/function/f_sourcesink.c b/drivers/usb/gadget/function/f_sourcesink.c index 6193b47..262dae8 100644 --- a/drivers/usb/gadget/function/f_sourcesink.c +++ b/drivers/usb/gadget/function/f_sourcesink.c @@ -42,7 +42,6 @@ struct f_sourcesink { struct usb_ep *out_ep; struct usb_ep *iso_in_ep; struct usb_ep *iso_out_ep; - int cur_alt; struct usb_request **in_reqs; struct usb_request **out_reqs; @@ -125,19 +124,6 @@ static struct usb_endpoint_descriptor fs_iso_sink_desc = { .bInterval =4, }; -static struct usb_descriptor_header *fs_source_sink_descs[] = { - (struct usb_descriptor_header *) _sink_intf_alt0, - (struct usb_descriptor_header *) _sink_desc, - (struct usb_descriptor_header *) _source_desc, - (struct usb_descriptor_header *) _sink_intf_alt1, -#define FS_ALT_IFC_1_OFFSET3 - (struct usb_descriptor_header *) _sink_desc, - (struct usb_descriptor_header *) _source_desc, - (struct usb_descriptor_header *) _iso_sink_desc, - (struct usb_descriptor_header *) _iso_source_desc, - NULL, -}; - /* high speed support: */ static struct usb_endpoint_descriptor hs_source_desc = { @@ -174,19 +160,6 @@ static struct usb_endpoint_descriptor hs_iso_sink_desc = { .bInterval =4, }; -static struct usb_descriptor_header *hs_source_sink_descs[] = { - (struct usb_descriptor_header *) _sink_intf_alt0, - (struct usb_descriptor_header *) _source_desc, - (struct usb_descriptor_header *) _sink_desc, - (struct usb_descriptor_header *) _sink_intf_alt1, -#define HS_ALT_IFC_1_OFFSET3 - (struct usb_descriptor_header *) _source_desc, - (struct usb_descriptor_header *) _sink_desc, - (struct usb_descriptor_header *) _iso_source_desc, - (struct usb_descriptor_header *) _iso_sink_desc, - NULL, -}; - /* super speed support: */ static struct usb_endpoint_descriptor ss_source_desc = { @@ -259,24 +232,24 @@ static struct usb_ss_ep_comp_descriptor ss_iso_sink_comp_desc = { .wBytesPerInterval =cpu_to_le16(1024), }; -static struct usb_descriptor_header *ss_source_sink_descs[] = { - (struct usb_descriptor_header *) _sink_intf_alt0, - (struct usb_descriptor_header *) _source_desc, - (struct usb_descriptor_header *) _source_comp_desc, - (struct usb_descriptor_header *) _sink_desc, - (struct usb_descriptor_header *) _sink_comp_desc, - (struct usb_descriptor_header *) _sink_intf_alt1, -#define SS_ALT_IFC_1_OFFSET5 - (struct usb_descriptor_header *) _source_desc, - (struct usb_descriptor_header *) _source_comp_desc, - (struct usb_descriptor_header *) _sink_desc, - (struct usb_descriptor_header *) _sink_comp_desc, - (struct usb_descriptor_header *) _iso_source_desc, - (struct usb_descriptor_header *) _iso_source_comp_desc, - (struct usb_descriptor_header *) _iso_sink_desc, - (struct usb_descriptor_header *) _iso_sink_comp_desc, - NULL, -}; +USB_COMPOSITE_ENDPOINT(ep_source, _source_desc, _source_desc, + _source_desc, _source_comp_desc); +USB_COMPOSITE_ENDPOINT(ep_sink, _sink_desc, _sink_desc, + _sink_desc, _sink_comp_desc); +USB_COMPOSITE_ENDPOINT(ep_iso_source, _iso_source_desc, _iso_source_desc, + _iso_source_desc, _iso_source_comp_desc); +USB_COMPOSITE_ENDPOINT(ep_iso_sink, _iso_sink_desc, _iso_sink_desc, + _iso_sink_desc, _iso_sink_comp_desc); + +USB_COMPOSITE_ALTSETTING(altset0, _sink_intf_alt0, _source, _sink); +USB_COMPOSITE_ALTSETTING(altset1, _sink_intf_alt1, _source, _sink, + _iso_source, _iso_sink); + +USB_COMPOSITE_INTERFACE(intf0, , ); +USB_COMPOSITE_INTERFACE(intf0_no_iso, ); + +USB_COMPOSITE_DESCRIPTORS(source_sink_descs, ); +USB_COMPOSITE_DESCRIPTORS(source_sink_descs_no_iso, _no_iso); /* function-specific strings: */ @@ -304,65 +277,12 @@ static inline struct usb_request *ss_alloc_ep_req(struct usb_ep *ep, int len) return alloc_ep_req(ep, len, ss->buflen); } -static void disable_ep(struct usb_composite_dev
[PATCH v3 20/36] usb: gadget: f_loopback: convert to new API
Generate descriptors in new format and attach them to USB function in prep_descs(). Change set_alt() implementation and implement clear_alt() operation. Remove unnecessary boilerplate code. Call usb_config_do_bind() in legacy gadget zero, because it uses usb_add_config_only() instead of usb_add_config() and prepares configuration manually. Signed-off-by: Robert Baldyga--- drivers/usb/gadget/function/f_loopback.c | 162 ++- drivers/usb/gadget/legacy/zero.c | 3 + 2 files changed, 33 insertions(+), 132 deletions(-) diff --git a/drivers/usb/gadget/function/f_loopback.c b/drivers/usb/gadget/function/f_loopback.c index f985107..f2aa056 100644 --- a/drivers/usb/gadget/function/f_loopback.c +++ b/drivers/usb/gadget/function/f_loopback.c @@ -76,13 +76,6 @@ static struct usb_endpoint_descriptor fs_loop_sink_desc = { .bmAttributes = USB_ENDPOINT_XFER_BULK, }; -static struct usb_descriptor_header *fs_loopback_descs[] = { - (struct usb_descriptor_header *) _intf, - (struct usb_descriptor_header *) _loop_sink_desc, - (struct usb_descriptor_header *) _loop_source_desc, - NULL, -}; - /* high speed support: */ static struct usb_endpoint_descriptor hs_loop_source_desc = { @@ -101,13 +94,6 @@ static struct usb_endpoint_descriptor hs_loop_sink_desc = { .wMaxPacketSize = cpu_to_le16(512), }; -static struct usb_descriptor_header *hs_loopback_descs[] = { - (struct usb_descriptor_header *) _intf, - (struct usb_descriptor_header *) _loop_source_desc, - (struct usb_descriptor_header *) _loop_sink_desc, - NULL, -}; - /* super speed support: */ static struct usb_endpoint_descriptor ss_loop_source_desc = { @@ -142,14 +128,17 @@ static struct usb_ss_ep_comp_descriptor ss_loop_sink_comp_desc = { .wBytesPerInterval =0, }; -static struct usb_descriptor_header *ss_loopback_descs[] = { - (struct usb_descriptor_header *) _intf, - (struct usb_descriptor_header *) _loop_source_desc, - (struct usb_descriptor_header *) _loop_source_comp_desc, - (struct usb_descriptor_header *) _loop_sink_desc, - (struct usb_descriptor_header *) _loop_sink_comp_desc, - NULL, -}; +USB_COMPOSITE_ENDPOINT(ep_source, _loop_source_desc, _loop_source_desc, + _loop_source_desc, _loop_source_comp_desc); +USB_COMPOSITE_ENDPOINT(ep_sink, _loop_sink_desc, _loop_sink_desc, + _loop_sink_desc, _loop_sink_comp_desc); + +USB_COMPOSITE_ALTSETTING(altset0, _intf, _source, _sink); + +USB_COMPOSITE_INTERFACE(intf0, ); + +USB_COMPOSITE_DESCRIPTORS(loopback_descs, ); + /* function-specific strings: */ @@ -170,18 +159,10 @@ static struct usb_gadget_strings *loopback_strings[] = { /*-*/ -static int loopback_bind(struct usb_configuration *c, struct usb_function *f) +static int loopback_prep_descs(struct usb_function *f) { - struct usb_composite_dev *cdev = c->cdev; - struct f_loopback *loop = func_to_loop(f); - int id; - int ret; - - /* allocate interface ID(s) */ - id = usb_interface_id(c, f); - if (id < 0) - return id; - loopback_intf.bInterfaceNumber = id; + struct usb_composite_dev *cdev = f->config->cdev; + int id; id = usb_string_id(cdev); if (id < 0) @@ -189,40 +170,7 @@ static int loopback_bind(struct usb_configuration *c, struct usb_function *f) strings_loopback[0].id = id; loopback_intf.iInterface = id; - /* allocate endpoints */ - - loop->in_ep = usb_ep_autoconfig(cdev->gadget, _loop_source_desc); - if (!loop->in_ep) { -autoconf_fail: - ERROR(cdev, "%s: can't autoconfigure on %s\n", - f->name, cdev->gadget->name); - return -ENODEV; - } - - loop->out_ep = usb_ep_autoconfig(cdev->gadget, _loop_sink_desc); - if (!loop->out_ep) - goto autoconf_fail; - - /* support high speed hardware */ - hs_loop_source_desc.bEndpointAddress = - fs_loop_source_desc.bEndpointAddress; - hs_loop_sink_desc.bEndpointAddress = fs_loop_sink_desc.bEndpointAddress; - - /* support super speed hardware */ - ss_loop_source_desc.bEndpointAddress = - fs_loop_source_desc.bEndpointAddress; - ss_loop_sink_desc.bEndpointAddress = fs_loop_sink_desc.bEndpointAddress; - - ret = usb_assign_descriptors(f, fs_loopback_descs, hs_loopback_descs, - ss_loopback_descs); - if (ret) - return ret; - - DBG(cdev, "%s speed %s: IN/%s, OUT/%s\n", - (gadget_is_superspeed(c->cdev->gadget) ? "super" : -(gadget_is_dualspeed(c->cdev->gadget) ? "dual" : "full")), - f->name, loop->in_ep->name, loop->out_ep->name); - return
[PATCH v3 14/36] usb: gadget: composite: introduce clear_alt() operation
Introduce clear_alt() callback, which is called when prevoiusly set altsetting is cleared. This can take place in two situations: - when another altsetting is selected, - during function disable. Thanks to symetry to set_alt(), clear_alt() simplifies managing of resources allocated in set_alt(). It also takes over the function of disable() opetarion, so it can be removed after converting all USB functions to new API. Signed-off-by: Robert Baldyga--- drivers/usb/gadget/composite.c | 12 include/linux/usb/composite.h | 4 2 files changed, 12 insertions(+), 4 deletions(-) diff --git a/drivers/usb/gadget/composite.c b/drivers/usb/gadget/composite.c index 34721ef..48af787 100644 --- a/drivers/usb/gadget/composite.c +++ b/drivers/usb/gadget/composite.c @@ -985,6 +985,9 @@ static void disable_interface(struct usb_function *f, unsigned i) for (e = 0; e < alt->eps_num; ++e) usb_ep_disable(alt->eps[e]->ep); + if (f->clear_alt) + f->clear_alt(f, i, intf->cur_altset); + intf->cur_altset = -1; } @@ -996,12 +999,13 @@ static void disable_function(struct usb_function *f) { int i; - if (usb_function_is_new_api(f)) + if (usb_function_is_new_api(f)) { for (i = 0; i < f->descs->intfs_num; ++i) disable_interface(f, i); - - if (f->disable) - f->disable(f); + } else { + if (f->disable) + f->disable(f); + } bitmap_zero(f->endpoints, 32); } diff --git a/include/linux/usb/composite.h b/include/linux/usb/composite.h index 7cef8c0..3838eb6 100644 --- a/include/linux/usb/composite.h +++ b/include/linux/usb/composite.h @@ -301,6 +301,8 @@ struct usb_os_desc_table { * initialize usb_ep.driver data at this time (when it is used). * Note that setting an interface to its current altsetting resets * interface state, and that all interfaces have a disabled state. + * @clear_alt: (REQUIRED) Clears altsetting, frees all ep requiests and other + * resources allocated by set_alt. * @get_alt: Returns the active altsetting. If this is not provided, * then only altsetting zero is supported. * @disable: (REQUIRED) Indicates the function should be disabled. Reasons @@ -373,6 +375,8 @@ struct usb_function { /* runtime state management */ int (*set_alt)(struct usb_function *, unsigned interface, unsigned alt); + void(*clear_alt)(struct usb_function *, + unsigned interface, unsigned alt); int (*get_alt)(struct usb_function *, unsigned interface); void(*disable)(struct usb_function *); -- 1.9.1 -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 1/2] usb: serial: remove redundant conditions
This patch removes redundant conditions. (!A || (A && B)) is the same as (!A || B). Tested by compilation only. Caught by cppcheck. Signed-off-by: Geyslan G. Bem--- drivers/usb/serial/io_edgeport.c | 35 ++- 1 file changed, 14 insertions(+), 21 deletions(-) diff --git a/drivers/usb/serial/io_edgeport.c b/drivers/usb/serial/io_edgeport.c index c086697..f49327d 100644 --- a/drivers/usb/serial/io_edgeport.c +++ b/drivers/usb/serial/io_edgeport.c @@ -1046,9 +1046,8 @@ static void edge_close(struct usb_serial_port *port) edge_port->closePending = true; - if ((!edge_serial->is_epic) || - ((edge_serial->is_epic) && -(edge_serial->epic_descriptor.Supports.IOSPChase))) { + if (!edge_serial->is_epic || + edge_serial->epic_descriptor.Supports.IOSPChase) { /* flush and chase */ edge_port->chaseResponsePending = true; @@ -1061,9 +1060,8 @@ static void edge_close(struct usb_serial_port *port) edge_port->chaseResponsePending = false; } - if ((!edge_serial->is_epic) || - ((edge_serial->is_epic) && -(edge_serial->epic_descriptor.Supports.IOSPClose))) { + if (!edge_serial->is_epic || + edge_serial->epic_descriptor.Supports.IOSPClose) { /* close the port */ dev_dbg(>dev, "%s - Sending IOSP_CMD_CLOSE_PORT\n", __func__); send_iosp_ext_cmd(edge_port, IOSP_CMD_CLOSE_PORT, 0); @@ -1612,9 +1610,8 @@ static void edge_break(struct tty_struct *tty, int break_state) struct edgeport_serial *edge_serial = usb_get_serial_data(port->serial); int status; - if ((!edge_serial->is_epic) || - ((edge_serial->is_epic) && -(edge_serial->epic_descriptor.Supports.IOSPChase))) { + if (!edge_serial->is_epic || + edge_serial->epic_descriptor.Supports.IOSPChase) { /* flush and chase */ edge_port->chaseResponsePending = true; @@ -1628,9 +1625,8 @@ static void edge_break(struct tty_struct *tty, int break_state) } } - if ((!edge_serial->is_epic) || - ((edge_serial->is_epic) && -(edge_serial->epic_descriptor.Supports.IOSPSetClrBreak))) { + if (!edge_serial->is_epic || + edge_serial->epic_descriptor.Supports.IOSPSetClrBreak) { if (break_state == -1) { dev_dbg(>dev, "%s - Sending IOSP_CMD_SET_BREAK\n", __func__); status = send_iosp_ext_cmd(edge_port, @@ -2465,9 +2461,8 @@ static void change_port_settings(struct tty_struct *tty, unsigned char stop_char = STOP_CHAR(tty); unsigned char start_char = START_CHAR(tty); - if ((!edge_serial->is_epic) || - ((edge_serial->is_epic) && -(edge_serial->epic_descriptor.Supports.IOSPSetXChar))) { + if (!edge_serial->is_epic || + edge_serial->epic_descriptor.Supports.IOSPSetXChar) { send_iosp_ext_cmd(edge_port, IOSP_CMD_SET_XON_CHAR, start_char); send_iosp_ext_cmd(edge_port, @@ -2494,13 +2489,11 @@ static void change_port_settings(struct tty_struct *tty, } /* Set flow control to the configured value */ - if ((!edge_serial->is_epic) || - ((edge_serial->is_epic) && -(edge_serial->epic_descriptor.Supports.IOSPSetRxFlow))) + if (!edge_serial->is_epic || + edge_serial->epic_descriptor.Supports.IOSPSetRxFlow) send_iosp_ext_cmd(edge_port, IOSP_CMD_SET_RX_FLOW, rxFlow); - if ((!edge_serial->is_epic) || - ((edge_serial->is_epic) && -(edge_serial->epic_descriptor.Supports.IOSPSetTxFlow))) + if (!edge_serial->is_epic || + edge_serial->epic_descriptor.Supports.IOSPSetTxFlow) send_iosp_ext_cmd(edge_port, IOSP_CMD_SET_TX_FLOW, txFlow); -- 2.6.3 -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 1/4] usb: serial: remove redundant conditions
2015-12-11 6:16 GMT-03:00 Johan Hovold: > On Thu, Dec 10, 2015 at 05:50:09PM -0300, Geyslan G. Bem wrote: >> This patch removes redundant conditions. >> >> (!A || (A && B)) is the same as (!A || B). >> (length && length > 5) can be reduced to a single evaluation. >> >> Tested by compilation only. >> Caught by cppcheck. >> >> Signed-off-by: Geyslan G. Bem >> --- >> drivers/usb/serial/io_edgeport.c | 35 ++- >> drivers/usb/serial/mos7840.c | 2 +- >> 2 files changed, 15 insertions(+), 22 deletions(-) > > Please split this up per driver as I (and Felipe) asked. Sorry. get_maintainer give same maintainers, but the question here is the different drivers. Ok, I'll send them splitted. > > You can send these two separate from the rest, and remember to CC > the USB list. Ok, tks. > > Thanks, > Johan -- Regards, Geyslan G. Bem hackingbits.com -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v3 02/36] usb: gadget: f_sourcesink: make ISO altset user-selectable
So far it was decided during the bind process whether is iso altsetting included to f_sourcesink function or not. This decision was based on availability of isochronous endpoints. Since we can assemble gadget driver using composite framework and configfs from many different functions, availability of given type of endpoint can depend on selected components or even on their order in given configuration. This can result with non-obvious behavior - even small, seemingly unrelated change in gadget configuration can decide if we have second altsetting with iso endpoints in given sourcesink function instance or not. Because of this it's way better to have additional parameter allowing user to decide if he/she wants to have iso altsetting, and if iso altsetting is included, and there are no iso endpoints available, function bind will fail instead of silently allowing to have non-complete function bound. Signed-off-by: Robert Baldyga--- drivers/usb/gadget/function/f_sourcesink.c | 98 -- drivers/usb/gadget/function/g_zero.h | 3 + drivers/usb/gadget/legacy/zero.c | 6 ++ 3 files changed, 76 insertions(+), 31 deletions(-) diff --git a/drivers/usb/gadget/function/f_sourcesink.c b/drivers/usb/gadget/function/f_sourcesink.c index 242ba5c..e950031 100644 --- a/drivers/usb/gadget/function/f_sourcesink.c +++ b/drivers/usb/gadget/function/f_sourcesink.c @@ -49,6 +49,7 @@ struct f_sourcesink { unsigned isoc_maxpacket; unsigned isoc_mult; unsigned isoc_maxburst; + unsigned isoc_enabled; unsigned buflen; unsigned bulk_qlen; unsigned iso_qlen; @@ -336,17 +337,28 @@ sourcesink_bind(struct usb_configuration *c, struct usb_function *f) /* allocate bulk endpoints */ ss->in_ep = usb_ep_autoconfig(cdev->gadget, _source_desc); - if (!ss->in_ep) { -autoconf_fail: - ERROR(cdev, "%s: can't autoconfigure on %s\n", - f->name, cdev->gadget->name); - return -ENODEV; - } + if (!ss->in_ep) + goto autoconf_fail; ss->out_ep = usb_ep_autoconfig(cdev->gadget, _sink_desc); if (!ss->out_ep) goto autoconf_fail; + /* support high speed hardware */ + hs_source_desc.bEndpointAddress = fs_source_desc.bEndpointAddress; + hs_sink_desc.bEndpointAddress = fs_sink_desc.bEndpointAddress; + + /* support super speed hardware */ + ss_source_desc.bEndpointAddress = fs_source_desc.bEndpointAddress; + ss_sink_desc.bEndpointAddress = fs_sink_desc.bEndpointAddress; + + if (!ss->isoc_enabled) { + fs_source_sink_descs[FS_ALT_IFC_1_OFFSET] = NULL; + hs_source_sink_descs[HS_ALT_IFC_1_OFFSET] = NULL; + ss_source_sink_descs[SS_ALT_IFC_1_OFFSET] = NULL; + goto no_iso; + } + /* sanity check the isoc module parameters */ if (ss->isoc_interval < 1) ss->isoc_interval = 1; @@ -368,30 +380,14 @@ autoconf_fail: /* allocate iso endpoints */ ss->iso_in_ep = usb_ep_autoconfig(cdev->gadget, _iso_source_desc); if (!ss->iso_in_ep) - goto no_iso; + goto autoconf_fail; ss->iso_out_ep = usb_ep_autoconfig(cdev->gadget, _iso_sink_desc); - if (!ss->iso_out_ep) { - usb_ep_autoconfig_release(ss->iso_in_ep); - ss->iso_in_ep = NULL; -no_iso: - /* -* We still want to work even if the UDC doesn't have isoc -* endpoints, so null out the alt interface that contains -* them and continue. -*/ - fs_source_sink_descs[FS_ALT_IFC_1_OFFSET] = NULL; - hs_source_sink_descs[HS_ALT_IFC_1_OFFSET] = NULL; - ss_source_sink_descs[SS_ALT_IFC_1_OFFSET] = NULL; - } + if (!ss->iso_out_ep) + goto autoconf_fail; if (ss->isoc_maxpacket > 1024) ss->isoc_maxpacket = 1024; - - /* support high speed hardware */ - hs_source_desc.bEndpointAddress = fs_source_desc.bEndpointAddress; - hs_sink_desc.bEndpointAddress = fs_sink_desc.bEndpointAddress; - /* * Fill in the HS isoc descriptors from the module parameters. * We assume that the user knows what they are doing and won't @@ -408,12 +404,6 @@ no_iso: hs_iso_sink_desc.bInterval = ss->isoc_interval; hs_iso_sink_desc.bEndpointAddress = fs_iso_sink_desc.bEndpointAddress; - /* support super speed hardware */ - ss_source_desc.bEndpointAddress = - fs_source_desc.bEndpointAddress; - ss_sink_desc.bEndpointAddress = - fs_sink_desc.bEndpointAddress; - /* * Fill in the SS isoc descriptors from the module parameters. * We assume that the user knows what they are doing and won't @@ -436,6 +426,7 @@
[PATCH v3 05/36] usb: gadget: configfs: fix error path
As usb_gstrings_attach() failure can happen when some USB functions are are already added to some configurations (in previous loop iterations), we should always call purge_configs_funcs() to be sure that failure is be handled properly. Signed-off-by: Robert Baldyga--- drivers/usb/gadget/configfs.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/usb/gadget/configfs.c b/drivers/usb/gadget/configfs.c index 163d305..0557f80 100644 --- a/drivers/usb/gadget/configfs.c +++ b/drivers/usb/gadget/configfs.c @@ -1342,7 +1342,7 @@ static int configfs_composite_bind(struct usb_gadget *gadget, s = usb_gstrings_attach(>cdev, cfg->gstrings, 1); if (IS_ERR(s)) { ret = PTR_ERR(s); - goto err_comp_cleanup; + goto err_purge_funcs; } c->iConfiguration = s[0].id; } -- 1.9.1 -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v3 08/36] usb: gadget: composite: introduce new USB function ops
Introduce two new USB function operations: 1. prep_descs() prepares and assigns entity (interface and endpoint) descriptors to USB function. It's mandatory, in the new function API, as each USB function should have at least minimalistic set of entity descriptors. The minimum is single inferface with one altsetting with no endpoins (ep0 only). Descriptors assigned to function in prep_descs() callback are used during bind procedure. 2. prep_vendor_descs() - prepares and assigns class and vendor specific descriptors to function. This function is called after binding function to UDC hardware, which means that interface numbers and endpoint addresses are already assigned so that function can use these values to prepare class or vendor specific descriptors and attach them to function. Signed-off-by: Robert Baldyga--- include/linux/usb/composite.h | 8 1 file changed, 8 insertions(+) diff --git a/include/linux/usb/composite.h b/include/linux/usb/composite.h index b778d4d..58d2929 100644 --- a/include/linux/usb/composite.h +++ b/include/linux/usb/composite.h @@ -286,6 +286,10 @@ struct usb_os_desc_table { * can expose more than one interface. If an interface is a member of * an IAD, only the first interface of IAD has its entry in the table. * @os_desc_n: Number of entries in os_desc_table + * @prep_descs: Returns standard function descriptors (interface and endpoint + * descritptors). + * @prep_vendor_descs: Attaches vendor or class specific descriptors to + * standard descriptors. * @bind: Before the gadget can register, all of its functions bind() to the * available resources including string and interface identifiers used * in interface or class descriptors; endpoints; I/O buffers; and so on. @@ -354,6 +358,10 @@ struct usb_function { * Related: unbind() may kfree() but bind() won't... */ + /* new function API*/ + int (*prep_descs)(struct usb_function *); + int (*prep_vendor_descs)(struct usb_function *); + /* configuration management: bind/unbind */ int (*bind)(struct usb_configuration *, struct usb_function *); -- 1.9.1 -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v3 10/36] usb: gadget: composite: handle vendor descs
After binding all configurations in gadget, call prep_vendor_descs() for each function which uses new API and implements this callback. Signed-off-by: Robert Baldyga--- drivers/usb/gadget/composite.c | 31 +++ include/linux/usb/composite.h | 2 ++ 2 files changed, 33 insertions(+) diff --git a/drivers/usb/gadget/composite.c b/drivers/usb/gadget/composite.c index 324bf81..1b8e204 100644 --- a/drivers/usb/gadget/composite.c +++ b/drivers/usb/gadget/composite.c @@ -2569,6 +2569,33 @@ int usb_config_do_bind(struct usb_configuration *c) } EXPORT_SYMBOL_GPL(usb_config_do_bind); +/** + * composite_prep_vendor_descs - for each function in each configuration call + * prep_vendor_descs() callback. + * @cdev: composite device + */ +int composite_prep_vendor_descs(struct usb_composite_dev *cdev) +{ + struct usb_configuration *c; + struct usb_function *f; + int ret; + + list_for_each_entry(c, >configs, list) + list_for_each_entry(f, >functions, list) { + if (!usb_function_is_new_api(f)) + continue; + if (f->prep_vendor_descs) { + ret = f->prep_vendor_descs(f); + if (ret) + return ret; + } + + } + + return 0; +} +EXPORT_SYMBOL_GPL(composite_prep_vendor_descs); + static int composite_bind(struct usb_gadget *gadget, struct usb_gadget_driver *gdriver) { @@ -2598,6 +2625,10 @@ static int composite_bind(struct usb_gadget *gadget, if (status < 0) goto fail; + status = composite_prep_vendor_descs(cdev); + if (status < 0) + goto fail; + if (cdev->use_os_string) { status = composite_os_desc_req_prepare(cdev, gadget->ep0); if (status) diff --git a/include/linux/usb/composite.h b/include/linux/usb/composite.h index a92da38..dc0ac28c 100644 --- a/include/linux/usb/composite.h +++ b/include/linux/usb/composite.h @@ -592,6 +592,8 @@ extern int composite_os_desc_req_prepare(struct usb_composite_dev *cdev, struct usb_ep *ep0); void composite_dev_cleanup(struct usb_composite_dev *cdev); +int composite_prep_vendor_descs(struct usb_composite_dev *cdev); + void composite_free_descs(struct usb_composite_dev *cdev); void composite_free_vendor_descs(struct usb_composite_dev *cdev); -- 1.9.1 -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v3 11/36] usb: gadget: composite: generate old descs for compatibility
For now we generate descriptor arrays for each speed as it is done by old API functions, to allow use mixed new and old API based functions in single configurations. This will be removed after complete switch to new API. Signed-off-by: Robert Baldyga--- drivers/usb/gadget/composite.c | 175 + include/linux/usb/composite.h | 2 + 2 files changed, 177 insertions(+) diff --git a/drivers/usb/gadget/composite.c b/drivers/usb/gadget/composite.c index 1b8e204..fdd0cbe 100644 --- a/drivers/usb/gadget/composite.c +++ b/drivers/usb/gadget/composite.c @@ -2258,6 +2258,30 @@ void composite_free_vendor_descs(struct usb_composite_dev *cdev) } EXPORT_SYMBOL_GPL(composite_free_vendor_descs); +/** + * composite_free_old_descs - for all functions implementing new API free old + * descriptors arrays. + * @cdev: composite device + */ +void composite_free_old_descs(struct usb_composite_dev *cdev) +{ + struct usb_configuration *c; + struct usb_function *f; + + list_for_each_entry(c, >configs, list) + list_for_each_entry(f, >functions, list) { + if (!usb_function_is_new_api(f)) + continue; + kfree(f->fs_descriptors); + kfree(f->hs_descriptors); + kfree(f->ss_descriptors); + f->fs_descriptors = NULL; + f->hs_descriptors = NULL; + f->ss_descriptors = NULL; + } +} +EXPORT_SYMBOL_GPL(composite_free_old_descs); + static void __composite_unbind(struct usb_gadget *gadget, bool unbind_driver) { struct usb_composite_dev*cdev = get_gadget_data(gadget); @@ -2269,6 +2293,7 @@ static void __composite_unbind(struct usb_gadget *gadget, bool unbind_driver) */ WARN_ON(cdev->config); + composite_free_old_descs(cdev); composite_free_vendor_descs(cdev); composite_free_descs(cdev); @@ -2596,6 +2621,152 @@ int composite_prep_vendor_descs(struct usb_composite_dev *cdev) } EXPORT_SYMBOL_GPL(composite_prep_vendor_descs); +/* + * function_add_desc() - Add given descriptor to descriptor arrays for + * each supported speed, in proper version for each speed. + * + * @f - USB function + * @idx - pointer to index of descriptor in fs and hs array + * @idx_ss - pointer to index of descriptor in ss array + * @fs - descriptor for FS + * @hs - descriptor for HS + * @ss - descriptor for SS + * + * Indexes are automatically incremented. + * + * This function will be removed after converting all USB functions + * in kernel to new API. + */ +static inline void function_add_desc(struct usb_function *f, + int *idx, int *idx_ss, + struct usb_descriptor_header *fs, + struct usb_descriptor_header *hs, + struct usb_descriptor_header *ss) { + if (f->config->fullspeed) + f->fs_descriptors[*idx] = fs; + if (f->config->highspeed) + f->hs_descriptors[*idx] = hs; + if (f->config->superspeed) + f->ss_descriptors[*idx_ss] = ss; + ++(*idx); + ++(*idx_ss); +} + +/* + * function_generate_old_descs() - generate descriptors array for each speed + * + * Allocate arrays of needed size and assign to them USB descriptors. + * + * This is temporary solution allowing coexistence to both old and new function + * API. It will be removed after converting all functions in kernel to new API. + */ +static int function_generate_old_descs(struct usb_function *f) +{ + struct usb_composite_intf *intf; + struct usb_composite_altset *alt; + struct usb_composite_ep *ep; + struct usb_composite_vendor_desc *vd; + int cnt, eps, i, a, e, idx, idx_ss; + + cnt = f->descs->vendor_descs_num; + eps = 0; + + for (i = 0; i < f->descs->intfs_num; ++i) { + intf = f->descs->intfs[i]; + for (a = 0; a < intf->altsets_num; ++a) { + alt = intf->altsets[a]; + cnt += alt->vendor_descs_num + 1; + eps += alt->eps_num; + for (e = 0; e < alt->eps_num; ++e) + cnt += alt->eps[e]->vendor_descs_num + 1; + } + } + + if (f->config->fullspeed) { + f->fs_descriptors = kzalloc((cnt + 1) * + sizeof(*f->fs_descriptors), GFP_KERNEL); + if (!f->fs_descriptors) + return -ENOMEM; + } + if (f->config->highspeed) { + f->hs_descriptors = kzalloc((cnt + 1) * + sizeof(*f->hs_descriptors), GFP_KERNEL); + if (!f->hs_descriptors) + goto err; + } + if (f->config->superspeed) { + f->ss_descriptors = kzalloc((cnt + eps + 1) * +
[PATCH v3 07/36] usb: gadget: composite: add functions for descriptors handling
Introduce functions and macros allowing to create and assign descriptors to function easily. Macros build structure hierarchy using pointers to USB descriptors, while functions assigning them to gadget make a deep copy. It allows for easy conversion of USB functions to make them using new descriptors format. Signed-off-by: Robert Baldyga--- drivers/usb/gadget/composite.c | 347 + include/linux/usb/composite.h | 52 ++ 2 files changed, 399 insertions(+) diff --git a/drivers/usb/gadget/composite.c b/drivers/usb/gadget/composite.c index 8b14c2a..35245fb 100644 --- a/drivers/usb/gadget/composite.c +++ b/drivers/usb/gadget/composite.c @@ -327,6 +327,318 @@ int usb_function_activate(struct usb_function *function) EXPORT_SYMBOL_GPL(usb_function_activate); /** + * usb_function_set_descs - assing descriptors to USB function + * @f: USB function + * @descs: USB descriptors to be assigned to function + * + * This function is to be called from prep_desc() callback to provide + * descriptors needed during bind process. It does a deep copy of + * descriptors hierarchy. + * + * Returns zero on success, else negative errno. + */ +int usb_function_set_descs(struct usb_function *f, + struct usb_composite_descs *descs) +{ + struct usb_composite_descs *descs_c; + struct usb_composite_intf *intf, *intf_c; + struct usb_composite_altset *altset, *altset_c; + struct usb_composite_ep *ep, *ep_c; + int i, a, e; + size_t size; + void *mem; + + size = sizeof(*descs); + + if (!descs->intfs_num) + return -EINVAL; + + if (!f->config) + return -ENODEV; + + size += descs->intfs_num * + (sizeof(*descs->intfs) + sizeof(**descs->intfs)); + for (i = 0; i < descs->intfs_num; ++i) { + intf = descs->intfs[i]; + if (!intf->altsets_num) + return -EINVAL; + size += intf->altsets_num * + (sizeof(*intf->altsets) + sizeof(**intf->altsets)); + for (a = 0; a < intf->altsets_num; ++a) { + altset = intf->altsets[a]; + size += sizeof(*altset->alt.desc); + size += altset->eps_num * + (sizeof(*altset->eps) + sizeof(**altset->eps)); + for (e = 0; e < altset->eps_num; ++e) { + ep = altset->eps[e]; + if (ep->fs.desc) { + size += sizeof(*ep->fs.desc); + f->config->fullspeed = true; + } + if (ep->hs.desc) { + size += sizeof(*ep->hs.desc); + f->config->highspeed = true; + } + if (ep->ss.desc) { + size += sizeof(*ep->ss.desc); + f->config->superspeed = true; + } + if (ep->ss_comp.desc) + size += sizeof(*ep->ss_comp.desc); + } + } + } + + mem = kzalloc(size, GFP_KERNEL); + if (!mem) + return -ENOMEM; + + f->descs = descs_c = mem; + mem += sizeof(*descs_c); + INIT_LIST_HEAD(_c->vendor_descs); + descs_c->intfs_num = descs->intfs_num; + descs_c->intfs = mem; + mem += descs_c->intfs_num * sizeof(*descs_c->intfs); + + for (i = 0; i < f->descs->intfs_num; ++i) { + intf = descs->intfs[i]; + descs_c->intfs[i] = intf_c = mem; + mem += sizeof(*intf_c); + intf_c->altsets_num = intf->altsets_num; + intf_c->altsets = mem; + mem += intf_c->altsets_num * sizeof(*intf_c->altsets); + + for (a = 0; a < intf->altsets_num; ++a) { + altset = intf->altsets[a]; + intf_c->altsets[a] = altset_c = mem; + mem += sizeof(*altset_c); + INIT_LIST_HEAD(_c->vendor_descs); + altset_c->alt.desc = mem; + mem += sizeof(*altset->alt.desc); + memcpy(altset_c->alt.desc, altset->alt.desc, + sizeof(*altset->alt.desc)); + altset_c->eps_num = altset->eps_num; + altset_c->eps = mem; + mem += altset_c->eps_num * sizeof(*altset_c->eps); + + for (e = 0; e < altset->eps_num; ++e) { + ep = altset->eps[e]; + altset_c->eps[e] = ep_c = mem; + mem
[PATCH v3 12/36] usb: gadget: composite: disable eps before calling disable() callback
Changes meaning of disable() operation for functions using new API. Before calling disable() callback composite automatically disables endpoints of active altsettings of given USB function. This reduces amount of boilerplate code in USB functions. Signed-off-by: Robert Baldyga--- drivers/usb/gadget/composite.c | 51 -- 1 file changed, 44 insertions(+), 7 deletions(-) diff --git a/drivers/usb/gadget/composite.c b/drivers/usb/gadget/composite.c index fdd0cbe..3695b75 100644 --- a/drivers/usb/gadget/composite.c +++ b/drivers/usb/gadget/composite.c @@ -246,12 +246,12 @@ done: } EXPORT_SYMBOL_GPL(usb_add_function); +static void disable_function(struct usb_function *f); + void usb_remove_function(struct usb_configuration *c, struct usb_function *f) { - if (f->disable) - f->disable(f); + disable_function(f); - bitmap_zero(f->endpoints, 32); list_del(>list); if (f->unbind) f->unbind(c, f); @@ -946,6 +946,46 @@ static void device_qual(struct usb_composite_dev *cdev) /*-*/ +/** + * disable_interface - disable all endpoints in given interface + * @f: USB function + * @i: interface index in function + */ +static void disable_interface(struct usb_function *f, unsigned i) +{ + struct usb_composite_intf *intf; + struct usb_composite_altset *alt; + int e; + + intf = f->descs->intfs[i]; + if (intf->cur_altset < 0) + return; + + alt = intf->altsets[intf->cur_altset]; + for (e = 0; e < alt->eps_num; ++e) + usb_ep_disable(alt->eps[e]->ep); + + intf->cur_altset = -1; +} + +/** + * disable_function - disable all endpoints in given function + * @f: USB function + */ +static void disable_function(struct usb_function *f) +{ + int i; + + if (usb_function_is_new_api(f)) + for (i = 0; i < f->descs->intfs_num; ++i) + disable_interface(f, i); + + if (f->disable) + f->disable(f); + + bitmap_zero(f->endpoints, 32); +} + static void reset_config(struct usb_composite_dev *cdev) { struct usb_function *f; @@ -953,10 +993,7 @@ static void reset_config(struct usb_composite_dev *cdev) DBG(cdev, "reset config\n"); list_for_each_entry(f, >config->functions, list) { - if (f->disable) - f->disable(f); - - bitmap_zero(f->endpoints, 32); + disable_function(f); } cdev->config = NULL; cdev->delayed_status = 0; -- 1.9.1 -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v3 06/36] usb: gadget: composite: introduce new descriptors format
Introduce new structures designed to contain information about descriptors. It splits descriptors in two categories: 1. Entity descs - interface and endpoint descriptors 2. Vendor descs - all other vendor and class specific descriptors Entity descriptors are embedded in hierarchy of structures while vendor descriptors are contained in linked lists. This distinction is caused by fact, that entity descriptors are needed during gadget bind procedure, while vendor descriptors can be supplied later, which is usually desired, as these descriptors may need to be filled with interface numbers and endpoint addresses which are assigned during gadget bind. In result we can split descriptors creation process in two steps - first collecs entity descriptors, perform the bind and then update and attach all other descriptors. This process can be done this way not only for each function separately, but also for entire gadget at once, which means we can first gather descriptors from all functions in gadget, next perform bind procedure, and then allow functions to supply additional descriptors. It allows us to have autoconfig solver capable to better distibute ep resources, and additionally, because we now store information about endpoints, allows us to handle endpoint state inside composite framework, and in result remove lots of boilerplate code from USB functions. Signed-off-by: Robert Baldyga--- include/linux/usb/composite.h | 119 ++ 1 file changed, 119 insertions(+) diff --git a/include/linux/usb/composite.h b/include/linux/usb/composite.h index 1074b89..686c5f7 100644 --- a/include/linux/usb/composite.h +++ b/include/linux/usb/composite.h @@ -57,6 +57,121 @@ struct usb_configuration; /** + * struct usb_composite_vendor_desc - vendor specific descriptor + * @desc: pointer to vendor specific descriptor + * @list: descriptor list element + * + * It's designed to be element of vendor specific descriptor list, + * which can be attached to function, interface (per altsetting) or + * endpoint. + */ +struct usb_composite_vendor_desc { + struct usb_descriptor_header *desc; + struct list_head list; +}; + +/** + * struct usb_composite_ep - representation of USB endpoint + * @fs.desc: FullSpeed descriptor + * @hs.desc: HighSpeed descriptor + * @ss.desc: SuperSpeed descriptor + * @ss_comp.desc: SuperSpeed Companion descriptor + * @vendor_descs: list of vendor specific descriptors + * @vendor_descs_num: count of vendor specific descriptors + * @ep: pointer to endpoint obtained during bind process + * + * We have pointer to each descriptor in union with pointer to descriptor + * header in order to avoid casting in many places in code, because in + * some situations we want to have access to fields of particular type + * of descriptor, while in other situations we want to treat all types + * of descriptors in the same way. + */ +struct usb_composite_ep { + union { + struct usb_descriptor_header *header; + struct usb_endpoint_descriptor *desc; + } fs; + + union { + struct usb_descriptor_header *header; + struct usb_endpoint_descriptor *desc; + } hs; + + union { + struct usb_descriptor_header *header; + struct usb_endpoint_descriptor *desc; + } ss; + + union { + struct usb_descriptor_header *header; + struct usb_ss_ep_comp_descriptor *desc; + } ss_comp; + + struct list_head vendor_descs; + int vendor_descs_num; + + struct usb_ep *ep; +}; + +/** + * struct usb_composite_altset - representation of USB altsetting + * @alt.desc: interface (altsetting) descriptor + * @eps: array of endpoints in altsetting + * @eps_num: number of endpoints + * @vendor_descs: list of vendor specific descriptors + * @vendor_descs_num: count of vendor specific descriptors + * + * We have pointer to alt descriptor in union with pointer to descriptor + * header in order to avoid casting in many places in code, because in + * some situations we want to have access to fields of particular type + * of descriptor, while in other situations we want to treat all types + * of descriptors in the same way. + */ +struct usb_composite_altset { + union { + struct usb_descriptor_header *header; + struct usb_interface_descriptor *desc; + } alt; + + struct usb_composite_ep **eps; + int eps_num; + + struct list_head vendor_descs; + int vendor_descs_num; +}; + +/** + * struct usb_composite_intf - representation of USB interface + * @altsets: array of altsettings in interface + * @altsets_num: number of altsettings + * @cur_altset: number of currently selected altsetting + * @id: id number of interface in configuraion (value of + * bInterfaceNumber in interface descriptor) + */ +struct usb_composite_intf { + struct usb_composite_altset **altsets;
[PATCH v3 13/36] usb: gadget: composite: enable eps before calling set_alt() callback
Change set_alt() behavior for functions using new API. Before we call set_alt() callback, we disable endpoints of previously selected altsetting, and enable endpoints of currently selected altsetting, which reduces amount of boilerplate code in USB functions. We also calculate index of interface in function and pass it to set_alt() callback instead of passing index of interface in configuration which has to be obtained from interface descriptor. This simplifies altsetting changes handling in code of USB functions. Signed-off-by: Robert Baldyga--- drivers/usb/gadget/composite.c | 80 -- 1 file changed, 78 insertions(+), 2 deletions(-) diff --git a/drivers/usb/gadget/composite.c b/drivers/usb/gadget/composite.c index 3695b75..34721ef 100644 --- a/drivers/usb/gadget/composite.c +++ b/drivers/usb/gadget/composite.c @@ -654,6 +654,26 @@ static void usb_function_free_vendor_descs(struct usb_function *f) } /** + * usb_interface_id_to_index - if interface with a specified id belongs + * to given USB function, return its index within descriptors array + * of this function + * @f: USB function + * @id: id number of interface + * + * Returns interface index on success, else negative errno. + */ +static int usb_interface_id_to_index(struct usb_function *f, u8 id) +{ + int i; + + for (i = 0; i < f->descs->intfs_num; ++i) + if (f->descs->intfs[i]->id == id) + return i; + + return -EINVAL; +} + +/** * usb_interface_id() - allocate an unused interface ID * @config: configuration associated with the interface * @function: function handling the interface @@ -999,6 +1019,62 @@ static void reset_config(struct usb_composite_dev *cdev) cdev->delayed_status = 0; } +/** + * set_alt() - select specified altsetting in given interface + * @f: USB function + * @i: interface id number + * @a: altsetting number + * + * This function has different behavior depending on which API is used by + * given USB function. For functions using old API behavior stays unchanged, + * while for functions using new API index of interface in function is + * calculated and endpoints are configured and enabled before calling + * set_alt() callback. + */ +static int set_alt(struct usb_function *f, unsigned i, unsigned a) +{ + struct usb_composite_dev *cdev = f->config->cdev; + struct usb_composite_altset *alt; + struct usb_composite_ep *ep; + int e, ret = -EINVAL; + + /* To be removed after switch to new API */ + if (!usb_function_is_new_api(f)) + return f->set_alt(f, i, a); + + i = usb_interface_id_to_index(f, i); + if (i < 0) + return i; + + disable_interface(f, i); + + if (a >= f->descs->intfs[i]->altsets_num) + return -EINVAL; + + alt = f->descs->intfs[i]->altsets[a]; + for (e = 0; e < alt->eps_num; ++e) { + ep = alt->eps[e]; + ret = config_ep_by_speed(cdev->gadget, f, ep->ep); + if (ret) + goto err; + ret = usb_ep_enable(ep->ep); + if (ret) + goto err; + } + + f->descs->intfs[i]->cur_altset = a; + ret = f->set_alt(f, i, a); + if (ret) + goto err; + + return 0; +err: + for (e = 0; e < alt->eps_num; ++e) + usb_ep_disable(alt->eps[e]->ep); + f->descs->intfs[i]->cur_altset = -1; + return ret; +} + static int set_config(struct usb_composite_dev *cdev, const struct usb_ctrlrequest *ctrl, unsigned number) { @@ -1078,7 +1154,7 @@ static int set_config(struct usb_composite_dev *cdev, set_bit(addr, f->endpoints); } - result = f->set_alt(f, tmp, 0); + result = set_alt(f, tmp, 0); if (result < 0) { DBG(cdev, "interface %d (%s/%p) alt 0 --> %d\n", tmp, f->name, f, result); @@ -1979,7 +2055,7 @@ composite_setup(struct usb_gadget *gadget, const struct usb_ctrlrequest *ctrl) break; if (w_value && !f->set_alt) break; - value = f->set_alt(f, w_index, w_value); + value = set_alt(f, w_index, w_value); if (value == USB_GADGET_DELAYED_STATUS) { DBG(cdev, "%s: interface %d (%s) requested delayed status\n", -- 1.9.1 -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v3 09/36] usb: gadget: composite: handle function bind
As now USB function supplies entity descriptors to composite in prep_descs() callback, we can perform bind inside composite framework without involving bind() callback (which now is unused and will be removed after converting all functions in kernel to new API). For now we bind each configuration when it's added, because we have to support functions based on old API, but after completing conversion of functions, we will be able to do bind after adding all configurations. Also more sophisticated autoconfig solver will be provided to improve utilization of available hardware endpoints. Signed-off-by: Robert Baldyga--- drivers/usb/gadget/composite.c | 162 + include/linux/usb/composite.h | 3 + 2 files changed, 165 insertions(+) diff --git a/drivers/usb/gadget/composite.c b/drivers/usb/gadget/composite.c index 35245fb..324bf81 100644 --- a/drivers/usb/gadget/composite.c +++ b/drivers/usb/gadget/composite.c @@ -327,6 +327,21 @@ int usb_function_activate(struct usb_function *function) EXPORT_SYMBOL_GPL(usb_function_activate); /** + * usb_function_is_new_api - checks if USB function uses new API + * @f: USB function + * + * This function is added temporarily to allow both old and new function API + * to coexist. It function will be removed after converting all USB functions + * in kernel to new API. + * + * Returns true if function uses new API. + */ +static inline bool usb_function_is_new_api(struct usb_function *f) +{ + return !!f->prep_descs; +} + +/** * usb_function_set_descs - assing descriptors to USB function * @f: USB function * @descs: USB descriptors to be assigned to function @@ -1112,6 +1127,12 @@ int usb_add_config(struct usb_composite_dev *cdev, goto done; status = bind(config); + if (status < 0) + goto out; + + status = usb_config_do_bind(config); + +out: if (status < 0) { while (!list_empty(>functions)) { struct usb_function *f; @@ -2407,6 +2428,147 @@ void composite_dev_cleanup(struct usb_composite_dev *cdev) device_remove_file(>gadget->dev, _attr_suspended); } +/** + * usb_cmp_ep_descs - compare descriptors of two endpoints + * + * As currently during autoconfig procedure we take into consideration only + * FullSpeed and SuperSpeed Companion descriptors, we need to compare only + * these descriptors. It they are the same, endpoints are identical from + * autoconfig point of view. + */ +static int usb_cmp_ep_descs(struct usb_composite_ep *ep1, + struct usb_composite_ep *ep2) +{ + if (ep1->fs.desc->bLength != ep2->fs.desc->bLength) + return 0; + if (usb_endpoint_dir_in(ep1->fs.desc) ^ + usb_endpoint_dir_in(ep2->fs.desc)) + return 0; + if (ep1->fs.desc->bmAttributes != ep2->fs.desc->bmAttributes) + return 0; + if (ep1->fs.desc->wMaxPacketSize != ep2->fs.desc->wMaxPacketSize) + return 0; + if (ep1->fs.desc->bInterval != ep2->fs.desc->bInterval) + return 0; + + if (ep1->fs.desc->bLength != USB_DT_ENDPOINT_AUDIO_SIZE) + goto ss_comp; + + if (ep1->fs.desc->bRefresh != ep2->fs.desc->bRefresh) + return 0; + if (ep1->fs.desc->bSynchAddress != ep2->fs.desc->bSynchAddress) + return 0; + +ss_comp: + if (!ep1->ss_comp.desc ^ !ep2->ss_comp.desc) + return 0; + if (!ep1->ss_comp.desc) + return 1; + + if (ep1->ss_comp.desc->bMaxBurst != ep2->ss_comp.desc->bMaxBurst) + return 0; + if (ep1->ss_comp.desc->bmAttributes != ep2->ss_comp.desc->bmAttributes) + return 0; + if (ep1->ss_comp.desc->wBytesPerInterval != + ep2->ss_comp.desc->wBytesPerInterval) + return 0; + + return 1; +} + +/** + * ep_update_address() - update endpoint address in descriptors + * @ep: composite endpoint with assigned hardware ep + * + * This function should be called after setting ep->ep to endpoint obtained + * from usb_ep_autoconfig_ss(), to update endpoint address in descriptors for + * all supported speeds. + */ +static inline void ep_update_address(struct usb_composite_ep *ep) +{ + if (ep->fs.desc) + ep->hs.desc->bEndpointAddress = ep->ep->address; + if (ep->hs.desc) + ep->hs.desc->bEndpointAddress = ep->ep->address; + if (ep->ss.desc) + ep->ss.desc->bEndpointAddress = ep->ep->address; +} + +/** + * interface_do_bind() - bind interface to UDC + * @c: USB configuration + * @f: USB function in configuration c + * @intf: USB interface in function f + * + * For now we use only simple interface-level ep aucoconfig solver. + * We share endpoints between altsettings where it's possible. + */ +static int interface_do_bind(struct usb_configuration *c, +
[PATCH v3 04/36] usb: gadget: f_loopback: free requests in loopback_disable()
USB requests in Loopback function are allocated in loopback_get_alt() function, so we prefer to free them rather in loopback_disable() than in loopback_complete() when request is completed with error. It provides better symetry in resource management and improves code readability. Signed-off-by: Robert Baldyga--- drivers/usb/gadget/function/f_loopback.c | 58 +--- 1 file changed, 23 insertions(+), 35 deletions(-) diff --git a/drivers/usb/gadget/function/f_loopback.c b/drivers/usb/gadget/function/f_loopback.c index ddc3aad..f985107 100644 --- a/drivers/usb/gadget/function/f_loopback.c +++ b/drivers/usb/gadget/function/f_loopback.c @@ -35,6 +35,9 @@ struct f_loopback { struct usb_ep *in_ep; struct usb_ep *out_ep; + struct usb_request *in_req; + struct usb_request *out_req; + unsignedqlen; unsignedbuflen; }; @@ -249,30 +252,25 @@ static void loopback_complete(struct usb_ep *ep, struct usb_request *req) * We received some data from the host so let's * queue it so host can read the from our in ep */ - struct usb_request *in_req = req->context; - - in_req->zero = (req->actual < req->length); - in_req->length = req->actual; + loop->in_req->zero = (req->actual < req->length); + loop->in_req->length = req->actual; + req = loop->in_req; ep = loop->in_ep; - req = in_req; } else { /* * We have just looped back a bunch of data * to host. Now let's wait for some more data. */ - req = req->context; + req = loop->out_req; ep = loop->out_ep; } /* queue the buffer back to host or for next bunch of data */ status = usb_ep_queue(ep, req, GFP_ATOMIC); - if (status == 0) { - return; - } else { + if (status < 0) ERROR(cdev, "Unable to loop back buffer to %s: %d\n", ep->name, status); - goto free_req; - } + break; /* "should never get here" */ default: @@ -280,20 +278,10 @@ static void loopback_complete(struct usb_ep *ep, struct usb_request *req) status, req->actual, req->length); /* FALLTHROUGH */ - /* NOTE: since this driver doesn't maintain an explicit record -* of requests it submitted (just maintains qlen count), we -* rely on the hardware driver to clean up on disconnect or -* endpoint disable. -*/ case -ECONNABORTED: /* hardware forced ep reset */ case -ECONNRESET: /* request dequeued */ case -ESHUTDOWN:/* disconnect from host */ -free_req: - usb_ep_free_request(ep == loop->in_ep ? - loop->out_ep : loop->in_ep, - req->context); - free_ep_req(ep, req); - return; + break; } } @@ -316,7 +304,6 @@ static inline struct usb_request *lb_alloc_ep_req(struct usb_ep *ep, int len) static int alloc_requests(struct usb_composite_dev *cdev, struct f_loopback *loop) { - struct usb_request *in_req, *out_req; int i; int result = 0; @@ -329,23 +316,21 @@ static int alloc_requests(struct usb_composite_dev *cdev, for (i = 0; i < loop->qlen && result == 0; i++) { result = -ENOMEM; - in_req = usb_ep_alloc_request(loop->in_ep, GFP_ATOMIC); - if (!in_req) + loop->in_req = usb_ep_alloc_request(loop->in_ep, GFP_ATOMIC); + if (!loop->in_req) goto fail; - out_req = lb_alloc_ep_req(loop->out_ep, 0); - if (!out_req) + loop->out_req = lb_alloc_ep_req(loop->out_ep, 0); + if (!loop->out_req) goto fail_in; - in_req->complete = loopback_complete; - out_req->complete = loopback_complete; + loop->in_req->complete = loopback_complete; + loop->out_req->complete = loopback_complete; - in_req->buf = out_req->buf; + loop->in_req->buf = loop->out_req->buf; /* length will be set in complete routine */ - in_req->context = out_req; - out_req->context = in_req; - result
Re: [PATCH v3 2/3] usb: renesas_usbhs: add fallback compatibility strings
Hello. On 12/11/2015 5:12 AM, Simon Horman wrote: Add fallback compatibility strings for R-Car Gen2 and Gen3. This is in keeping with the fallback scheme being adopted wherever appropriate for drivers for Renesas SoCs. Signed-off-by: Simon Horman--- v3 * Moved documentation of SoC names to a separate patch * Use correct fallback compatibility string in example v2 * Add R-Car Gen2 and Gen3 fallback compatibility strings rather than a single compatibility string for all of R-Car. --- Documentation/devicetree/bindings/usb/renesas_usbhs.txt | 10 +- drivers/usb/renesas_usbhs/common.c | 9 + 2 files changed, 18 insertions(+), 1 deletion(-) diff --git a/Documentation/devicetree/bindings/usb/renesas_usbhs.txt b/Documentation/devicetree/bindings/usb/renesas_usbhs.txt index a14c0bb561d5..c55cf77006d0 100644 --- a/Documentation/devicetree/bindings/usb/renesas_usbhs.txt +++ b/Documentation/devicetree/bindings/usb/renesas_usbhs.txt @@ -2,10 +2,18 @@ Renesas Electronics USBHS driver Required properties: - compatible: Must contain one of the following: Really? + - "renesas,usbhs-r8a7790" for r8a7790 (R-Car H2) compatible device - "renesas,usbhs-r8a7791" for r8a7791 (R-Car M2-W) compatible device - "renesas,usbhs-r8a7794" for r8a7794 (R-Car E2) compatible device - "renesas,usbhs-r8a7795" for r8a7795 (R-Car H3) compatible device + - "renesas,rcar-gen2-usbhs" for R-Car Gen2 compatible device + - "renesas,rcar-gen3-usbhs" for R-Car Gen3 compatible device + + When compatible with the generic version, nodes must list the + SoC-specific version corresponding to the platform first followed + by the generic version. + This kinda contradicts the above claim. [...] MBR, Sergei -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH v7 0/4] usb/gadget: independent registration of gadgets and gadget drivers
Hello, On 2015-12-10 18:13, Felipe Balbi wrote: Felipe Balbiwrites: Felipe Balbi writes: Marek Szyprowski writes: This is a resurrection of the patches initially submitted by Ruslan Bilovol in the following thread: https://lkml.org/lkml/2015/6/22/554 The changes since the original submission (v5) includes rebase onto latest linux-next branch, simplification of the code requested by Alan Stern and Felipe Balbi, removal of a patch, which deleted __init/__exit attributes (this change has been already merged) and fixes of the checkpatch issues. This feature is urgently needed, because it is not longer possible to use workaround to avoid deferred probe in UDC drivers due to not-yet-probed i2c regulator drivers (for more information see https://lkml.org/lkml/2015/10/30/374 ). This patchset has been successfully tested on Odroid XU3 boards with DWC3 UDC driver being deferred by missing regulator drivers. there is one problem with this patchset. If I try to statically link gadget drivers, only one can be chosen, even though I can enable both dwc3 and dummy_hcd just fine. And, actually, this brings another problem. How do we handle systems which have 2 USB peripheral controllers (say, 2 instances of dwc3) and choose which gadget driver will bind to which controller ? We also seem to have issues with Kconfig. If I try to make gadget driver built-in, when compiling I'll get asked again if I want gadget drivers built-in. Another one: I just tried dummy_hcd built-in, g_zero built-in, dwc3 as a module. I can never load anything to dwc3 ;-) In all fairness, none of these are regressions. Can we agree to look at these during v4.5-rc so maybe v4.6 has a final solution ? IMHO solving all the above issues requires reviving one of the previously abandoned gadget-bus patch series, i.e. http://thread.gmane.org/gmane.linux.usb.general/109745 Is this an approach You are interested in? Best regards -- Marek Szyprowski, PhD Samsung R Institute Poland -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 1/2] usb: serial: remove redundant conditions
On Fri, Dec 11, 2015 at 07:25:51AM -0300, Geyslan G. Bem wrote: > 2015-12-11 7:13 GMT-03:00 Johan Hovold: > > On Fri, Dec 11, 2015 at 06:46:41AM -0300, Geyslan G. Bem wrote: > >> This patch removes redundant conditions. > >> > >> (!A || (A && B)) is the same as (!A || B). > >> > >> Tested by compilation only. > >> Caught by cppcheck. > >> > >> Signed-off-by: Geyslan G. Bem > > > > You forgot to update the commit summary (to include the driver name) > > when splitting the original patch. I fixed that up and applied both for > > next. > Sorry. I got it: USB: mos7840: and USB: io_edgeport:. > > I'm still getting the hang of it. :-) Looks like you got it. :) > Thank you for apply them. Thanks again for the patches. Johan -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 2/2] usb: serial: remove redundant condition
2015-12-11 9:30 GMT-03:00 Sergei Shtylyov: > Hello. > > On 12/11/2015 12:46 PM, Geyslan G. Bem wrote: > >It's a bad idea to send 2 different patches with the same subject. I'd > use "mos7840: " as a prefix in this case. Sergei, tks for the advice. Johan already applied for next. > >> This patch removes redundant condition. >> >> (length && length > 5) can be reduced to a single evaluation. >> >> Tested by compilation only. >> Caught by cppcheck. >> >> Signed-off-by: Geyslan G. Bem > > [...] > > MBR, Sergei > -- Regards, Geyslan G. Bem hackingbits.com -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH v3 01/36] Documentation: usb: update usb-tools repository address
Hello. On 12/11/2015 2:24 PM, Robert Baldyga wrote: It seems that gitotious repository is no longer accessible, so we replace Gitorious. it with address to active repository. Signed-off-by: Robert Baldyga[...] MBR, Sergei -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH] USB: serial: option: add support for Quectel UC20
On Fri, Dec 11, 2015 at 2:46 PM, Bjørn Morkwrote: > Yegor Yefremov writes: > >> Let me know, if you need any additional info or if I should make specific >> tests. > > First of all: Does it work with qmi_wwan? There is already a device > entry there. You'll need to use qmicli (from libqmi) or similar to > verify the QMI support. The driver probing is too forgiving to be a > conclusive test. > > And if we're going to find out if qcserial is suitable, then we need to > know the rest of the descriptor layout too. "lsusb -vd 05c6:9003" would > be nice. Without the patch: usb 1-1.4: new high-speed USB device number 5 using musb-hdrc qmi_wwan 1-1.4:1.4: cdc-wdm0: USB WDM device qmi_wwan 1-1.4:1.4 wwan0: register 'qmi_wwan' at usb-musb-hdrc.0.auto-1.4, WWAN/QMI device, 56:c8:76:e3:9b:42 # mmcli -L Found 1 modems: /org/freedesktop/ModemManager1/Modem/0 [QUALCOMM INCORPORATED] 0 # mmcli -m 0 /org/freedesktop/ModemManager1/Modem/0 (device id '95f860898b89fc5948a8812343f271d3278657c7') - Hardware | manufacturer: 'QUALCOMM INCORPORATED' | model: '0' | revision: 'UC20GQAR03A04M1024 1 [2014/05/05 9:00:00]' | supported: 'gsm-umts' |current: 'gsm-umts' | equipment id: '861075020978979' - System | device: '/sys/devices/platform/ocp/4740.usb/47401400.usb/musb-hdrc.0.auto/usb1/1-1/1-1.4' |drivers: 'qmi_wwan' | plugin: 'Generic' | primary port: 'cdc-wdm0' | ports: 'cdc-wdm0 (qmi), wwan0 (net)' - Numbers | own : 'unknown' - Status | lock: 'unknown' | unlock retries: 'unknown' | state: 'failed' | failed reason: 'sim-missing' |power state: 'on' |access tech: 'unknown' | signal quality: '0' (cached) - Modes| supported: 'allowed: 2g; preferred: none | allowed: 3g; preferred: none | allowed: 2g, 3g; preferred: none | allowed: 2g, 3g; preferred: 2g | allowed: 2g, 3g; preferred: 3g' |current: 'allowed: any; preferred: none' - Bands| supported: 'cdma-bc15-aws, dcs, egsm, pcs, g850, u2100, u1900, u800, u850, u900' |current: 'unknown' - IP | supported: 'ipv4, ipv6, ipv4v6' - SIM | path: 'none' - Bearers | paths: 'none' # lsusb -vd 05c6:9003 Bus 001 Device 005: ID 05c6:9003 Device Descriptor: bLength18 bDescriptorType 1 bcdUSB 2.00 bDeviceClass0 bDeviceSubClass 0 bDeviceProtocol 0 bMaxPacketSize064 idVendor 0x05c6 idProduct 0x9003 bcdDevice0.00 iManufacturer 3 Quectel, Incorporated iProduct2 UMTS/HSPA Module iSerial 4 bNumConfigurations 1 Configuration Descriptor: bLength 9 bDescriptorType 2 wTotalLength 138 bNumInterfaces 5 bConfigurationValue 1 iConfiguration 1 Quectel Configuration bmAttributes 0xe0 Self Powered Remote Wakeup MaxPower 500mA Interface Descriptor: bLength 9 bDescriptorType 4 bInterfaceNumber0 bAlternateSetting 0 bNumEndpoints 2 bInterfaceClass 255 bInterfaceSubClass255 bInterfaceProtocol255 iInterface 0 Endpoint Descriptor: bLength 7 bDescriptorType 5 bEndpointAddress 0x81 EP 1 IN bmAttributes2 Transfer TypeBulk Synch Type None Usage Type Data wMaxPacketSize 0x0200 1x 512 bytes bInterval 32 Endpoint Descriptor: bLength 7 bDescriptorType 5 bEndpointAddress 0x01 EP 1 OUT bmAttributes2 Transfer TypeBulk Synch Type None Usage Type Data wMaxPacketSize 0x0200 1x 512 bytes bInterval 32 Interface Descriptor: bLength 9 bDescriptorType 4 bInterfaceNumber1 bAlternateSetting 0 bNumEndpoints 2 bInterfaceClass 255 bInterfaceSubClass255
Re: [PATCH] USB: serial: option: add support for Quectel UC20
Hi Bjørn, On Fri, Dec 11, 2015 at 1:50 PM, Bjørn Morkwrote: > Johan Hovold writes: > >> Dan and Björn, >> >> On Thu, Dec 10, 2015 at 04:42:52PM +0100, yegorsli...@googlemail.com wrote: >>> From: Yegor Yefremov >>> >>> Signed-off-by: Yegor Yefremov >>> --- >>> drivers/usb/serial/option.c | 1 + >>> 1 file changed, 1 insertion(+) >>> >>> diff --git a/drivers/usb/serial/option.c b/drivers/usb/serial/option.c >>> index f228060..e0950bf 100644 >>> --- a/drivers/usb/serial/option.c >>> +++ b/drivers/usb/serial/option.c >>> @@ -1113,6 +1113,7 @@ static const struct usb_device_id option_ids[] = { >>> { USB_DEVICE(QUALCOMM_VENDOR_ID, 0x6613)}, /* Onda H600/ZTE MF330 */ >>> { USB_DEVICE(QUALCOMM_VENDOR_ID, 0x0023)}, /* ONYX 3G device */ >>> { USB_DEVICE(QUALCOMM_VENDOR_ID, 0x9000)}, /* SIMCom SIM5218 */ >>> +{ USB_DEVICE(QUALCOMM_VENDOR_ID, 0x9003)}, /* Quectel UC20 */ >> >> Does this one belong in option or qcserial? I see that >> >> {DEVICE_G1K(0x05c6, 0x9001)}, /* Generic Gobi Modem device */ >> {DEVICE_G1K(0x05c6, 0x9002)}, /* Generic Gobi Modem device */ >> >> are already handled by the latter (while 0x9000 isn't). > > I don't have strong opionions about this, but it most certainly need to > avoid probing the QMI function so the above patch cannot be correct. > > I see that this ID was part of a batch addition I did a while ago based > on Windows drivers (and no testting whatsoever!). See > > 0470667caa82 ("net: qmi_wwan: add new Qualcomm devices") > > I guess this should have gone into some serial driver too, but it > appears it didn't. > > Based on the recent Quectel EC20 experiences, I wouldn't be surprised if > this device reuse a Qualcomm device ID with a different layout. Or > maybe we just were wrng in the first place... difficult to know without > any real tester/device. Let me know, if you need any additional info or if I should make specific tests. Yegor -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH] extcon-usb-gpio: add enable pin support
Hello. On 12/11/2015 07:05 AM, Chanwoo Choi wrote: Sometimes there's a real OTG chip behind the USB ID signal mapped to a GPIO pin: in my case it's Maxim Integrated MAX3355E which integrates Vbus charge pump and comparators and passes thru the ID signal from an OTG connector. s/thru/through ? "Thru" is valid English. This chip also has the SHDN# pin which should be driven high for the normal operation and low to save power; it is connected to a GPIO pin as well on, hence we'll have to teach the driver to parse the new optional device tree property, "enable-gpio"... This patch description includes the double space between words. Also, I think So what? you need to write the patch description again for formal style. Not sure I understand you. This patch adds the specific 'enable-gpio' pin to express the SHDN#pin for MAX3355E. I think it is not regular and standard case because maybe USB specification don't include the SHDN#pin information. Certainly, it's not a USB pin. I think it not appropriate way. Instead, you better to make the MAX3355 extcon driver to support this case. OK, just didn't want to duplicate most of this driver there... Thanks, Chanwoo MBR, Sergei -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH v6 0/3] USB MIDI Gadget improvements and bug fixes
Hi all, On 01/12/15 18:30, Felipe F. Tonello wrote: > Fixed all comments suggested by the linux-usb list. > > changes in v6: > - Removed patches already applied in Balbi's tree > - Cleanups on pre-allocation usb requrests patch > - Fixed indentention on patch 1 > - Added patch which fails set_alt if a failure happened while >allocating usb requests > > changes in v5: > - Use ep->enabled insetad of creating driver specific flag > - Save MIDIStreaming interface id in driver data > - define free_ep_req as static inline in header > > changes in v4: > - pre-alocation of in requests. > - more code clean up > - fix memory leak on out requests > - configure endpoints only when setting up MIDIStreaming interface > > Felipe F. Tonello (3): > usb: gadget: f_midi: set altsettings only for MIDIStreaming interface > usb: gadget: f_midi: fail if set_alt fails to allocate requests > usb: gadget: f_midi: pre-allocate IN requests > > drivers/usb/gadget/function/f_midi.c | 175 > +++ > drivers/usb/gadget/legacy/gmidi.c| 2 +- > 2 files changed, 135 insertions(+), 42 deletions(-) > Ping? -- Felipe 0x92698E6A.asc Description: application/pgp-keys
Re: [PATCH v2 2/3] ehci-platform: Add support for controllers with multiple reset lines
Am Freitag, den 11.12.2015, 16:41 +0100 schrieb Hans de Goede: > From: Reinder de Haan> > At least the EHCI/OHCI found on the Allwinnner H3 SoC needs multiple > reset lines, the controller will not initialize while the reset for > its companion is still asserted, which means we need to de-assert > 2 resets for the controller to work. > > Signed-off-by: Reinder de Haan > Signed-off-by: Hans de Goede > --- > Changes in v2: > -Use the new reset_control_[de]assert_shared reset-controller functions > --- > Documentation/devicetree/bindings/usb/usb-ehci.txt | 2 +- > drivers/usb/host/ehci-platform.c | 47 > +- > 2 files changed, 30 insertions(+), 19 deletions(-) > > diff --git a/Documentation/devicetree/bindings/usb/usb-ehci.txt > b/Documentation/devicetree/bindings/usb/usb-ehci.txt > index a12d601..0701812 100644 > --- a/Documentation/devicetree/bindings/usb/usb-ehci.txt > +++ b/Documentation/devicetree/bindings/usb/usb-ehci.txt > @@ -18,7 +18,7 @@ Optional properties: > - clocks : a list of phandle + clock specifier pairs > - phys : phandle + phy specifier pair > - phy-names : "usb" > - - resets : phandle + reset specifier pair > + - resets : a list of phandle + reset specifier pairs Are there documented names for these resets? Is the companion you mention the Port Control? regards Philipp -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH v2 1/3] reset: Add shared reset_control_[de]assert variants
Hi Hans, thanks for moving this forward. Am Freitag, den 11.12.2015, 16:41 +0100 schrieb Hans de Goede: > Add reset_control_deassert_shared / reset_control_assert_shared > functions which are intended for use by drivers for hw blocks which > (may) share a reset line with another driver / hw block. > > Unlike the regular reset_control_[de]assert functions these functions > keep track of how often deassert_shared / assert_shared have been called > and keep the line deasserted as long as deassert has been called more > times than assert. > > Signed-off-by: Hans de Goede> --- > Changes in v2: > -This is a new patch in v2 of this patch-set > --- > drivers/reset/core.c | 121 > --- > include/linux/reset-controller.h | 2 + > include/linux/reset.h| 2 + > 3 files changed, 116 insertions(+), 9 deletions(-) > > diff --git a/drivers/reset/core.c b/drivers/reset/core.c > index 9ab9290..8c3436c 100644 > --- a/drivers/reset/core.c > +++ b/drivers/reset/core.c > @@ -22,16 +22,29 @@ static DEFINE_MUTEX(reset_controller_list_mutex); > static LIST_HEAD(reset_controller_list); > > /** > + * struct reset_line - a reset line > + * @list: list entry for the reset controllers reset line list > + * @id: ID of the reset line in the reset controller device > + * @refcnt: Number of reset_control structs referencing this device > + * @deassert_cnt: Number of times this reset line has been deasserted > + */ > +struct reset_line { > + struct list_head list; > + unsigned int id; > + unsigned int refcnt; > + unsigned int deassert_cnt; > +}; I'd move rcdev into reset_line, too. That way the description is complete, and we don't duplicate rcdev when there are multiple reset_controls pointing here. > +/** > * struct reset_control - a reset control > * @rcdev: a pointer to the reset controller device > * this reset control belongs to > - * @id: ID of the reset controller in the reset > - * controller device > + * @line: reset line for this reset control > */ > struct reset_control { > struct reset_controller_dev *rcdev; > + struct reset_line *line; > struct device *dev; > - unsigned int id; > }; > > /** [...] > @@ -119,13 +134,55 @@ EXPORT_SYMBOL_GPL(reset_control_assert); > int reset_control_deassert(struct reset_control *rstc) > { Maybe WARN_ON(rstc->line->refcnt > 1) ? > if (rstc->rcdev->ops->deassert) > - return rstc->rcdev->ops->deassert(rstc->rcdev, rstc->id); > + return rstc->rcdev->ops->deassert(rstc->rcdev, rstc->line->id); > > return -ENOTSUPP; > } > EXPORT_SYMBOL_GPL(reset_control_deassert); > > /** > + * reset_control_assert_shared - asserts a shared reset line > + * @rstc: reset controller > + * > + * Assert a shared reset line, this functions decreases the deassert count > + * of the line by one and asserts it if, and only if, the deassert count > + * reaches 0. "After calling this function the shared reset line may be asserted, or it may still be deasserted, as long as other users keep it so." > + */ > +int reset_control_assert_shared(struct reset_control *rstc) > +{ > + if (!rstc->rcdev->ops->assert) > + return -ENOTSUPP; WARN_ON(rstc->line->deassert_cnt == 0) Actually, what to do in this case? Assume ops->assert was called, or do it again to be sure? Certainly we don't want to wrap deassert_cnt, or the next deassert_shared will do nothing. > + rstc->line->deassert_cnt--; > + if (rstc->line->deassert_cnt) deassert_cnt isn't protected by any lock. > + return 0; > + > + return rstc->rcdev->ops->assert(rstc->rcdev, rstc->line->id); > +} > +EXPORT_SYMBOL_GPL(reset_control_assert_shared); > + > +/** > + * reset_control_deassert_shared - deasserts a shared reset line > + * @rstc: reset controller > + * > + * Assert a shared reset line, this functions increases the deassert count Deassert > + * of the line by one and deasserts the reset line (if it was not already > + * deasserted). "After calling this function, the shared reset line is guaranteed to be deasserted." > + */ > +int reset_control_deassert_shared(struct reset_control *rstc) > +{ > + if (!rstc->rcdev->ops->deassert) > + return -ENOTSUPP; > + > + rstc->line->deassert_cnt++; > + if (rstc->line->deassert_cnt != 1) > + return 0; > + > + return rstc->rcdev->ops->deassert(rstc->rcdev, rstc->line->id); > +} > +EXPORT_SYMBOL_GPL(reset_control_deassert_shared); > + > +/** > * reset_control_status - returns a negative errno if not supported, a > * positive value if the reset line is asserted, or zero if the reset > * line is not asserted. > @@ -134,12 +191,47 @@ EXPORT_SYMBOL_GPL(reset_control_deassert); > int reset_control_status(struct reset_control *rstc) > { > if (rstc->rcdev->ops->status) > - return
[PATCHv5 01/18] fs: configfs: Drop unused parameter from configfs_undepend_item()
From: Krzysztof Opasiaksubsys parameter is never used by configfs_undepend_item() so there is no point in passing it to this function. Signed-off-by: Krzysztof Opasiak Cc: Joel Becker Cc: Christoph Hellwig Signed-off-by: Nicholas Bellinger --- drivers/target/target_core_configfs.c | 2 +- fs/configfs/dir.c | 3 +-- fs/ocfs2/cluster/nodemanager.c| 2 +- include/linux/configfs.h | 5 +++-- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/drivers/target/target_core_configfs.c b/drivers/target/target_core_configfs.c index b9b9ffd..2e47fe6 100644 --- a/drivers/target/target_core_configfs.c +++ b/drivers/target/target_core_configfs.c @@ -278,7 +278,7 @@ EXPORT_SYMBOL(target_depend_item); void target_undepend_item(struct config_item *item) { - return configfs_undepend_item(_core_fabrics, item); + return configfs_undepend_item(item); } EXPORT_SYMBOL(target_undepend_item); diff --git a/fs/configfs/dir.c b/fs/configfs/dir.c index a7a1b21..d390245 100644 --- a/fs/configfs/dir.c +++ b/fs/configfs/dir.c @@ -1128,8 +1128,7 @@ EXPORT_SYMBOL(configfs_depend_item); * configfs_depend_item() because we know that that the client driver is * pinned, thus the subsystem is pinned, and therefore configfs is pinned. */ -void configfs_undepend_item(struct configfs_subsystem *subsys, - struct config_item *target) +void configfs_undepend_item(struct config_item *target) { struct configfs_dirent *sd; diff --git a/fs/ocfs2/cluster/nodemanager.c b/fs/ocfs2/cluster/nodemanager.c index 72afdca..ebe5438 100644 --- a/fs/ocfs2/cluster/nodemanager.c +++ b/fs/ocfs2/cluster/nodemanager.c @@ -757,7 +757,7 @@ int o2nm_depend_item(struct config_item *item) void o2nm_undepend_item(struct config_item *item) { - configfs_undepend_item(_cluster_group.cs_subsys, item); + configfs_undepend_item(item); } int o2nm_depend_this_node(void) diff --git a/include/linux/configfs.h b/include/linux/configfs.h index 758a029..3b5c6d5 100644 --- a/include/linux/configfs.h +++ b/include/linux/configfs.h @@ -209,7 +209,8 @@ void configfs_unregister_default_group(struct config_group *group); /* These functions can sleep and can alloc with GFP_KERNEL */ /* WARNING: These cannot be called underneath configfs callbacks!! */ -int configfs_depend_item(struct configfs_subsystem *subsys, struct config_item *target); -void configfs_undepend_item(struct configfs_subsystem *subsys, struct config_item *target); +int configfs_depend_item(struct configfs_subsystem *subsys, +struct config_item *target); +void configfs_undepend_item(struct config_item *target); #endif /* _CONFIGFS_H_ */ -- 1.9.1 -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCHv5 07/18] tcm_usb_gadget: Fix enabled attribute failure
From: Nicholas BellingerFix up tcm_usbg_tpg_store_enable() return value to propagate usbg_attach() failure up to user-space if no HDC is found. Reported-by: Andrzej Pietrasiewicz Cc: Andrzej Pietrasiewicz Cc: Sebastian Andrzej Siewior Signed-off-by: Nicholas Bellinger [split unrelated changes into separate patches] Signed-off-by: Andrzej Pietrasiewicz --- drivers/usb/gadget/legacy/tcm_usb_gadget.c | 12 +--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/drivers/usb/gadget/legacy/tcm_usb_gadget.c b/drivers/usb/gadget/legacy/tcm_usb_gadget.c index e90d3c9..65e4950 100644 --- a/drivers/usb/gadget/legacy/tcm_usb_gadget.c +++ b/drivers/usb/gadget/legacy/tcm_usb_gadget.c @@ -1505,10 +1505,14 @@ static ssize_t tcm_usbg_tpg_enable_store(struct config_item *item, if (op > 1) return -EINVAL; - if (op && tpg->gadget_connect) + if (op && tpg->gadget_connect) { + ret = -EINVAL; goto out; - if (!op && !tpg->gadget_connect) + } + if (!op && !tpg->gadget_connect) { + ret = -EINVAL; goto out; + } if (op) { ret = usbg_attach(tpg); @@ -1518,8 +1522,10 @@ static ssize_t tcm_usbg_tpg_enable_store(struct config_item *item, usbg_detach(tpg); } tpg->gadget_connect = op; -out: + return count; +out: + return ret; } static ssize_t tcm_usbg_tpg_nexus_show(struct config_item *item, char *page) -- 1.9.1 -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCHv5 17/18] usb: gadget: f_tcm: use usb_gstrings_attach
Do not directly use file static strings definitions in instances of f_tcm. Instead use usb_gstrings_attach. Signed-off-by: Andrzej Pietrasiewicz--- drivers/usb/gadget/function/f_tcm.c | 18 +++--- 1 file changed, 7 insertions(+), 11 deletions(-) diff --git a/drivers/usb/gadget/function/f_tcm.c b/drivers/usb/gadget/function/f_tcm.c index b33738a..4a00463 100644 --- a/drivers/usb/gadget/function/f_tcm.c +++ b/drivers/usb/gadget/function/f_tcm.c @@ -2028,6 +2028,7 @@ static struct usb_gadget_strings *tcm_strings[] = { static int tcm_bind(struct usb_configuration *c, struct usb_function *f) { struct f_uas*fu = to_f_uas(f); + struct usb_string *us; struct usb_gadget *gadget = c->cdev->gadget; struct usb_ep *ep; struct f_tcm_opts *opts; @@ -2042,16 +2043,12 @@ static int tcm_bind(struct usb_configuration *c, struct usb_function *f) return -ENODEV; } mutex_unlock(>dep_lock); - - if (tcm_us_strings[0].id == 0) { - ret = usb_string_ids_tab(c->cdev, tcm_us_strings); - if (ret < 0) - return ret; - - bot_intf_desc.iInterface = tcm_us_strings[USB_G_STR_INT_BBB].id; - uasp_intf_desc.iInterface = - tcm_us_strings[USB_G_STR_INT_UAS].id; - } + us = usb_gstrings_attach(c->cdev, tcm_strings, + ARRAY_SIZE(tcm_us_strings)); + if (IS_ERR(us)) + return PTR_ERR(us); + bot_intf_desc.iInterface = us[USB_G_STR_INT_BBB].id; + uasp_intf_desc.iInterface = us[USB_G_STR_INT_UAS].id; iface = usb_interface_id(c, f); if (iface < 0) @@ -2300,7 +2297,6 @@ static struct usb_function *tcm_alloc(struct usb_function_instance *fi) fu->function.set_alt = tcm_set_alt; fu->function.setup = tcm_setup; fu->function.disable = tcm_disable; - fu->function.strings = tcm_strings; fu->function.free_func = tcm_free; fu->tpg = tpg_instances[i].tpg; mutex_unlock(_instances_lock); -- 1.9.1 -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCHv5 06/18] tcm_usb_gadget: Fix nexus leak
From: Nicholas BellingerThis patch adds the missing tcm_usbg_drop_nexus() to properly release tcm_usbg_nexus memory during typical ->fabric_drop_tpg() callback shutdown. Reported-by: Andrzej Pietrasiewicz Cc: Andrzej Pietrasiewicz Cc: Sebastian Andrzej Siewior Signed-off-by: Nicholas Bellinger [split unrelated changes into separate patches] Signed-off-by: Andrzej Pietrasiewicz --- drivers/usb/gadget/legacy/tcm_usb_gadget.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/usb/gadget/legacy/tcm_usb_gadget.c b/drivers/usb/gadget/legacy/tcm_usb_gadget.c index edc74d3..e90d3c9 100644 --- a/drivers/usb/gadget/legacy/tcm_usb_gadget.c +++ b/drivers/usb/gadget/legacy/tcm_usb_gadget.c @@ -1423,11 +1423,14 @@ static struct se_portal_group *usbg_make_tpg( return >se_tpg; } +static int tcm_usbg_drop_nexus(struct usbg_tpg *); + static void usbg_drop_tpg(struct se_portal_group *se_tpg) { struct usbg_tpg *tpg = container_of(se_tpg, struct usbg_tpg, se_tpg); + tcm_usbg_drop_nexus(tpg); core_tpg_deregister(se_tpg); destroy_workqueue(tpg->workqueue); kfree(tpg); -- 1.9.1 -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v2 2/3] ehci-platform: Add support for controllers with multiple reset lines
From: Reinder de HaanAt least the EHCI/OHCI found on the Allwinnner H3 SoC needs multiple reset lines, the controller will not initialize while the reset for its companion is still asserted, which means we need to de-assert 2 resets for the controller to work. Signed-off-by: Reinder de Haan Signed-off-by: Hans de Goede --- Changes in v2: -Use the new reset_control_[de]assert_shared reset-controller functions --- Documentation/devicetree/bindings/usb/usb-ehci.txt | 2 +- drivers/usb/host/ehci-platform.c | 47 +- 2 files changed, 30 insertions(+), 19 deletions(-) diff --git a/Documentation/devicetree/bindings/usb/usb-ehci.txt b/Documentation/devicetree/bindings/usb/usb-ehci.txt index a12d601..0701812 100644 --- a/Documentation/devicetree/bindings/usb/usb-ehci.txt +++ b/Documentation/devicetree/bindings/usb/usb-ehci.txt @@ -18,7 +18,7 @@ Optional properties: - clocks : a list of phandle + clock specifier pairs - phys : phandle + phy specifier pair - phy-names : "usb" - - resets : phandle + reset specifier pair + - resets : a list of phandle + reset specifier pairs Example (Sequoia 440EPx): ehci@e300 { diff --git a/drivers/usb/host/ehci-platform.c b/drivers/usb/host/ehci-platform.c index bd7082f2..6fbf32a 100644 --- a/drivers/usb/host/ehci-platform.c +++ b/drivers/usb/host/ehci-platform.c @@ -39,11 +39,12 @@ #define DRIVER_DESC "EHCI generic platform driver" #define EHCI_MAX_CLKS 3 +#define EHCI_MAX_RESETS 2 #define hcd_to_ehci_priv(h) ((struct ehci_platform_priv *)hcd_to_ehci(h)->priv) struct ehci_platform_priv { struct clk *clks[EHCI_MAX_CLKS]; - struct reset_control *rst; + struct reset_control *resets[EHCI_MAX_RESETS]; struct phy **phys; int num_phys; bool reset_on_resume; @@ -149,7 +150,7 @@ static int ehci_platform_probe(struct platform_device *dev) struct usb_ehci_pdata *pdata = dev_get_platdata(>dev); struct ehci_platform_priv *priv; struct ehci_hcd *ehci; - int err, irq, phy_num, clk = 0; + int err, irq, phy_num, clk = 0, rst = 0; if (usb_disabled()) return -ENODEV; @@ -232,18 +233,24 @@ static int ehci_platform_probe(struct platform_device *dev) break; } } - } - priv->rst = devm_reset_control_get_optional(>dev, NULL); - if (IS_ERR(priv->rst)) { - err = PTR_ERR(priv->rst); - if (err == -EPROBE_DEFER) - goto err_put_clks; - priv->rst = NULL; - } else { - err = reset_control_deassert(priv->rst); - if (err) - goto err_put_clks; + for (rst = 0; rst < EHCI_MAX_RESETS; rst++) { + priv->resets[rst] = + of_reset_control_get_by_index(dev->dev.of_node, + rst); + if (IS_ERR(priv->resets[rst])) { + err = PTR_ERR(priv->resets[rst]); + if (err == -EPROBE_DEFER) + goto err_reset; + priv->resets[rst] = NULL; + break; + } + err = reset_control_deassert_shared(priv->resets[rst]); + if (err) { + reset_control_put(priv->resets[rst]); + goto err_reset; + } + } } if (pdata->big_endian_desc) @@ -300,8 +307,10 @@ err_power: if (pdata->power_off) pdata->power_off(dev); err_reset: - if (priv->rst) - reset_control_assert(priv->rst); + while (--rst >= 0) { + reset_control_assert_shared(priv->resets[rst]); + reset_control_put(priv->resets[rst]); + } err_put_clks: while (--clk >= 0) clk_put(priv->clks[clk]); @@ -319,15 +328,17 @@ static int ehci_platform_remove(struct platform_device *dev) struct usb_hcd *hcd = platform_get_drvdata(dev); struct usb_ehci_pdata *pdata = dev_get_platdata(>dev); struct ehci_platform_priv *priv = hcd_to_ehci_priv(hcd); - int clk; + int clk, rst; usb_remove_hcd(hcd); if (pdata->power_off) pdata->power_off(dev); - if (priv->rst) - reset_control_assert(priv->rst); + for (rst = 0; rst < EHCI_MAX_RESETS && priv->resets[rst]; rst++) { + reset_control_assert_shared(priv->resets[rst]); + reset_control_put(priv->resets[rst]); + } for (clk = 0; clk < EHCI_MAX_CLKS && priv->clks[clk]; clk++) clk_put(priv->clks[clk]); --
[PATCH v4 2/2] phy-sun4i-usb: Add support for the host usb-phys found on the H3 SoC
From: Reinder de HaanNote this commit only adds support for phys 1-3, phy 0, the otg phy, is not yet (fully) supported after this commit. Signed-off-by: Reinder de Haan Signed-off-by: Hans de Goede --- Changes in v2: -Change break; after dev_err() to return, as intended, fixing a compiler warning (the dev_err case should never be reached) Changes in v3: -Use of_match_node to get model specific config data Changes in v4: -Adjust to v4 of "Use of_match_node to get model specific config data" patch --- .../devicetree/bindings/phy/sun4i-usb-phy.txt | 1 + drivers/phy/phy-sun4i-usb.c| 41 +- 2 files changed, 33 insertions(+), 9 deletions(-) diff --git a/Documentation/devicetree/bindings/phy/sun4i-usb-phy.txt b/Documentation/devicetree/bindings/phy/sun4i-usb-phy.txt index 0cebf74..95736d7 100644 --- a/Documentation/devicetree/bindings/phy/sun4i-usb-phy.txt +++ b/Documentation/devicetree/bindings/phy/sun4i-usb-phy.txt @@ -9,6 +9,7 @@ Required properties: * allwinner,sun7i-a20-usb-phy * allwinner,sun8i-a23-usb-phy * allwinner,sun8i-a33-usb-phy + * allwinner,sun8i-h3-usb-phy - reg : a list of offset + length pairs - reg-names : * "phy_ctrl" diff --git a/drivers/phy/phy-sun4i-usb.c b/drivers/phy/phy-sun4i-usb.c index 35b1fa3..bae54f7 100644 --- a/drivers/phy/phy-sun4i-usb.c +++ b/drivers/phy/phy-sun4i-usb.c @@ -47,6 +47,9 @@ #define REG_PHYBIST0x08 #define REG_PHYTUNE0x0c #define REG_PHYCTL_A33 0x10 +#define REG_PHY_UNK_H3 0x20 + +#define REG_PMU_UNK_H3 0x10 #define PHYCTL_DATABIT(7) @@ -80,7 +83,7 @@ #define PHY_DISCON_TH_SEL 0x2a #define PHY_SQUELCH_DETECT 0x3c -#define MAX_PHYS 3 +#define MAX_PHYS 4 /* * Note do not raise the debounce time, we must report Vusb high within 100ms @@ -92,6 +95,7 @@ enum sun4i_usb_phy_type { sun4i_a10_phy, sun8i_a33_phy, + sun8i_h3_phy, }; struct sun4i_usb_phy_cfg { @@ -239,6 +243,7 @@ static int sun4i_usb_phy_init(struct phy *_phy) struct sun4i_usb_phy *phy = phy_get_drvdata(_phy); struct sun4i_usb_phy_data *data = to_sun4i_usb_phy_data(phy); int ret; + u32 val; ret = clk_prepare_enable(phy->clk); if (ret) @@ -250,16 +255,26 @@ static int sun4i_usb_phy_init(struct phy *_phy) return ret; } - /* Enable USB 45 Ohm resistor calibration */ - if (phy->index == 0) - sun4i_usb_phy_write(phy, PHY_RES45_CAL_EN, 0x01, 1); + if (data->cfg->type == sun8i_h3_phy) { + if (phy->index == 0) { + val = readl(data->base + REG_PHY_UNK_H3); + writel(val & ~1, data->base + REG_PHY_UNK_H3); + } + + val = readl(phy->pmu + REG_PMU_UNK_H3); + writel(val & ~2, phy->pmu + REG_PMU_UNK_H3); + } else { + /* Enable USB 45 Ohm resistor calibration */ + if (phy->index == 0) + sun4i_usb_phy_write(phy, PHY_RES45_CAL_EN, 0x01, 1); - /* Adjust PHY's magnitude and rate */ - sun4i_usb_phy_write(phy, PHY_TX_AMPLITUDE_TUNE, 0x14, 5); + /* Adjust PHY's magnitude and rate */ + sun4i_usb_phy_write(phy, PHY_TX_AMPLITUDE_TUNE, 0x14, 5); - /* Disconnect threshold adjustment */ - sun4i_usb_phy_write(phy, PHY_DISCON_TH_SEL, - data->cfg->disc_thresh, 2); + /* Disconnect threshold adjustment */ + sun4i_usb_phy_write(phy, PHY_DISCON_TH_SEL, + data->cfg->disc_thresh, 2); + } sun4i_usb_phy_passby(phy, 1); @@ -726,6 +741,13 @@ static const struct sun4i_usb_phy_cfg sun8i_a33_cfg = { .dedicated_clocks = true, }; +static const struct sun4i_usb_phy_cfg sun8i_h3_cfg = { + .num_phys = 4, + .type = sun8i_h3_phy, + .disc_thresh = 3, + .dedicated_clocks = true, +}; + static const struct of_device_id sun4i_usb_phy_of_match[] = { { .compatible = "allwinner,sun4i-a10-usb-phy", .data = _a10_cfg }, { .compatible = "allwinner,sun5i-a13-usb-phy", .data = _a13_cfg }, @@ -733,6 +755,7 @@ static const struct of_device_id sun4i_usb_phy_of_match[] = { { .compatible = "allwinner,sun7i-a20-usb-phy", .data = _a20_cfg }, { .compatible = "allwinner,sun8i-a23-usb-phy", .data = _a23_cfg }, { .compatible = "allwinner,sun8i-a33-usb-phy", .data = _a33_cfg }, + { .compatible = "allwinner,sun8i-h3-usb-phy", .data = _h3_cfg }, { }, }; MODULE_DEVICE_TABLE(of, sun4i_usb_phy_of_match); -- 2.5.0 -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to
[PATCH v4 1/2] phy-sun4i-usb: Use of_match_node to get model specific config data
Use of_match_node instead of calling of_device_is_compatible a ton of times to get model specific config data. Signed-off-by: Hans de Goede--- Changes in v3: -New patch in v3 of this patch-set Changes in v4: -Use of_device_get_match_data() -Add phyctl_offset to sun4i_usb_phy_cfg, get rid of model specific code for phyctl-reg in sun4i_usb_phy_write() --- drivers/phy/phy-sun4i-usb.c | 121 +--- 1 file changed, 79 insertions(+), 42 deletions(-) diff --git a/drivers/phy/phy-sun4i-usb.c b/drivers/phy/phy-sun4i-usb.c index b12964b..35b1fa3 100644 --- a/drivers/phy/phy-sun4i-usb.c +++ b/drivers/phy/phy-sun4i-usb.c @@ -32,6 +32,7 @@ #include #include #include +#include #include #include #include @@ -88,12 +89,23 @@ #define DEBOUNCE_TIME msecs_to_jiffies(50) #define POLL_TIME msecs_to_jiffies(250) +enum sun4i_usb_phy_type { + sun4i_a10_phy, + sun8i_a33_phy, +}; + +struct sun4i_usb_phy_cfg { + int num_phys; + enum sun4i_usb_phy_type type; + u32 disc_thresh; + u8 phyctl_offset; + bool dedicated_clocks; +}; + struct sun4i_usb_phy_data { void __iomem *base; + const struct sun4i_usb_phy_cfg *cfg; struct mutex mutex; - int num_phys; - u32 disc_thresh; - bool has_a33_phyctl; struct sun4i_usb_phy { struct phy *phy; void __iomem *pmu; @@ -159,17 +171,14 @@ static void sun4i_usb_phy_write(struct sun4i_usb_phy *phy, u32 addr, u32 data, { struct sun4i_usb_phy_data *phy_data = to_sun4i_usb_phy_data(phy); u32 temp, usbc_bit = BIT(phy->index * 2); - void *phyctl; + void *phyctl = phy_data->base + phy_data->cfg->phyctl_offset; int i; mutex_lock(_data->mutex); - if (phy_data->has_a33_phyctl) { - phyctl = phy_data->base + REG_PHYCTL_A33; + if (phy_data->cfg->type == sun8i_a33_phy) { /* A33 needs us to set phyctl to 0 explicitly */ writel(0, phyctl); - } else { - phyctl = phy_data->base + REG_PHYCTL_A10; } for (i = 0; i < len; i++) { @@ -249,7 +258,8 @@ static int sun4i_usb_phy_init(struct phy *_phy) sun4i_usb_phy_write(phy, PHY_TX_AMPLITUDE_TUNE, 0x14, 5); /* Disconnect threshold adjustment */ - sun4i_usb_phy_write(phy, PHY_DISCON_TH_SEL, data->disc_thresh, 2); + sun4i_usb_phy_write(phy, PHY_DISCON_TH_SEL, + data->cfg->disc_thresh, 2); sun4i_usb_phy_passby(phy, 1); @@ -476,7 +486,7 @@ static struct phy *sun4i_usb_phy_xlate(struct device *dev, { struct sun4i_usb_phy_data *data = dev_get_drvdata(dev); - if (args->args[0] >= data->num_phys) + if (args->args[0] >= data->cfg->num_phys) return ERR_PTR(-ENODEV); return data->phys[args->args[0]].phy; @@ -511,7 +521,6 @@ static int sun4i_usb_phy_probe(struct platform_device *pdev) struct device *dev = >dev; struct device_node *np = dev->of_node; struct phy_provider *phy_provider; - bool dedicated_clocks; struct resource *res; int i, ret; @@ -522,29 +531,9 @@ static int sun4i_usb_phy_probe(struct platform_device *pdev) mutex_init(>mutex); INIT_DELAYED_WORK(>detect, sun4i_usb_phy0_id_vbus_det_scan); dev_set_drvdata(dev, data); - - if (of_device_is_compatible(np, "allwinner,sun5i-a13-usb-phy") || - of_device_is_compatible(np, "allwinner,sun8i-a23-usb-phy") || - of_device_is_compatible(np, "allwinner,sun8i-a33-usb-phy")) - data->num_phys = 2; - else - data->num_phys = 3; - - if (of_device_is_compatible(np, "allwinner,sun5i-a13-usb-phy") || - of_device_is_compatible(np, "allwinner,sun7i-a20-usb-phy")) - data->disc_thresh = 2; - else - data->disc_thresh = 3; - - if (of_device_is_compatible(np, "allwinner,sun6i-a31-usb-phy") || - of_device_is_compatible(np, "allwinner,sun8i-a23-usb-phy") || - of_device_is_compatible(np, "allwinner,sun8i-a33-usb-phy")) - dedicated_clocks = true; - else - dedicated_clocks = false; - - if (of_device_is_compatible(np, "allwinner,sun8i-a33-usb-phy")) - data->has_a33_phyctl = true; + data->cfg = of_device_get_match_data(dev); + if (!data->cfg) + return -EINVAL; res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "phy_ctrl"); data->base = devm_ioremap_resource(dev, res); @@ -590,7 +579,7 @@ static int sun4i_usb_phy_probe(struct platform_device *pdev) } } - for (i = 0; i < data->num_phys; i++) { + for (i = 0; i < data->cfg->num_phys; i++) { struct sun4i_usb_phy *phy = data->phys + i; char name[16];
[PATCHv5 05/18] tcm_usb_gadget: Don't strip off nexus WWPN prefix
From: Nicholas BellingerAvoid stripping off the 'naa.' I_T nexus prefix from configfs attribute store input, so that user-space will get back what it originaly wrote into ../usb_gadget/$WWPN/$TPGT/nexus. Note the SCSI initiator WWPN is purely symbolic for UAS + BOT, so it will not effect host side code. Reported-by: Andrzej Pietrasiewicz Cc: Andrzej Pietrasiewicz Cc: Sebastian Andrzej Siewior Signed-off-by: Nicholas Bellinger --- drivers/usb/gadget/legacy/tcm_usb_gadget.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/usb/gadget/legacy/tcm_usb_gadget.c b/drivers/usb/gadget/legacy/tcm_usb_gadget.c index 22e5615..edc74d3 100644 --- a/drivers/usb/gadget/legacy/tcm_usb_gadget.c +++ b/drivers/usb/gadget/legacy/tcm_usb_gadget.c @@ -1657,7 +1657,7 @@ static ssize_t tcm_usbg_tpg_nexus_store(struct config_item *item, if (i_port[strlen(i_port) - 1] == '\n') i_port[strlen(i_port) - 1] = '\0'; - ret = tcm_usbg_make_nexus(tpg, _port[4]); + ret = tcm_usbg_make_nexus(tpg, _port[0]); if (ret < 0) return ret; return count; -- 1.9.1 -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCHv5 12/18] usb: gadget: tcm: factor out f_tcm
Prepare for converting tcm to new function registration interface. Signed-off-by: Andrzej Pietrasiewicz--- drivers/usb/gadget/function/f_tcm.c| 2145 drivers/usb/gadget/function/tcm.h | 132 ++ drivers/usb/gadget/legacy/tcm_usb_gadget.c | 2132 +-- drivers/usb/gadget/legacy/tcm_usb_gadget.h | 132 -- 4 files changed, 2280 insertions(+), 2261 deletions(-) create mode 100644 drivers/usb/gadget/function/f_tcm.c create mode 100644 drivers/usb/gadget/function/tcm.h delete mode 100644 drivers/usb/gadget/legacy/tcm_usb_gadget.h diff --git a/drivers/usb/gadget/function/f_tcm.c b/drivers/usb/gadget/function/f_tcm.c new file mode 100644 index 000..ce246bc --- /dev/null +++ b/drivers/usb/gadget/function/f_tcm.c @@ -0,0 +1,2145 @@ +/* Target based USB-Gadget + * + * UAS protocol handling, target callbacks, configfs handling, + * BBB (USB Mass Storage Class Bulk-Only (BBB) and Transport protocol handling. + * + * Author: Sebastian Andrzej Siewior + * License: GPLv2 as published by FSF. + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "tcm.h" + +static inline struct f_uas *to_f_uas(struct usb_function *f) +{ + return container_of(f, struct f_uas, function); +} + +static void usbg_cmd_release(struct kref *); + +static inline void usbg_cleanup_cmd(struct usbg_cmd *cmd) +{ + kref_put(>ref, usbg_cmd_release); +} + +/* Start bot.c code */ + +static int bot_enqueue_cmd_cbw(struct f_uas *fu) +{ + int ret; + + if (fu->flags & USBG_BOT_CMD_PEND) + return 0; + + ret = usb_ep_queue(fu->ep_out, fu->cmd.req, GFP_ATOMIC); + if (!ret) + fu->flags |= USBG_BOT_CMD_PEND; + return ret; +} + +static void bot_status_complete(struct usb_ep *ep, struct usb_request *req) +{ + struct usbg_cmd *cmd = req->context; + struct f_uas *fu = cmd->fu; + + usbg_cleanup_cmd(cmd); + if (req->status < 0) { + pr_err("ERR %s(%d)\n", __func__, __LINE__); + return; + } + + /* CSW completed, wait for next CBW */ + bot_enqueue_cmd_cbw(fu); +} + +static void bot_enqueue_sense_code(struct f_uas *fu, struct usbg_cmd *cmd) +{ + struct bulk_cs_wrap *csw = >bot_status.csw; + int ret; + u8 *sense; + unsigned int csw_stat; + + csw_stat = cmd->csw_code; + + /* +* We can't send SENSE as a response. So we take ASC & ASCQ from our +* sense buffer and queue it and hope the host sends a REQUEST_SENSE +* command where it learns why we failed. +*/ + sense = cmd->sense_iu.sense; + + csw->Tag = cmd->bot_tag; + csw->Status = csw_stat; + fu->bot_status.req->context = cmd; + ret = usb_ep_queue(fu->ep_in, fu->bot_status.req, GFP_ATOMIC); + if (ret) + pr_err("%s(%d) ERR: %d\n", __func__, __LINE__, ret); +} + +static void bot_err_compl(struct usb_ep *ep, struct usb_request *req) +{ + struct usbg_cmd *cmd = req->context; + struct f_uas *fu = cmd->fu; + + if (req->status < 0) + pr_err("ERR %s(%d)\n", __func__, __LINE__); + + if (cmd->data_len) { + if (cmd->data_len > ep->maxpacket) { + req->length = ep->maxpacket; + cmd->data_len -= ep->maxpacket; + } else { + req->length = cmd->data_len; + cmd->data_len = 0; + } + + usb_ep_queue(ep, req, GFP_ATOMIC); + return; + } + bot_enqueue_sense_code(fu, cmd); +} + +static void bot_send_bad_status(struct usbg_cmd *cmd) +{ + struct f_uas *fu = cmd->fu; + struct bulk_cs_wrap *csw = >bot_status.csw; + struct usb_request *req; + struct usb_ep *ep; + + csw->Residue = cpu_to_le32(cmd->data_len); + + if (cmd->data_len) { + if (cmd->is_read) { + ep = fu->ep_in; + req = fu->bot_req_in; + } else { + ep = fu->ep_out; + req = fu->bot_req_out; + } + + if (cmd->data_len > fu->ep_in->maxpacket) { + req->length = ep->maxpacket; + cmd->data_len -= ep->maxpacket; + } else { + req->length = cmd->data_len; + cmd->data_len = 0; + } + req->complete = bot_err_compl; + req->context = cmd; + req->buf = fu->cmd.buf; + usb_ep_queue(ep, req, GFP_KERNEL); + } else { + bot_enqueue_sense_code(fu, cmd); + } +} + +static int bot_send_status(struct usbg_cmd *cmd, bool moved_data) +{ + struct f_uas *fu = cmd->fu; +
[PATCHv5 04/18] fs: configfs: Add unlocked version of configfs_depend_item()
From: Krzysztof OpasiakThis change is necessary for the SCSI target usb gadget composed with configfs. In this case configfs will be used for two different purposes: to compose a usb gadget and to configure the target part. If an instance of tcm function is created in $CONFIGFS_ROOT/usb_gadget//functions a tpg can be created in $CONFIGFS_ROOT/target/usb_gadget//, but after a tpg is created the tcm function must not be removed until its corresponding tpg is gone. While the configfs_depend/undepend_item() are meant exactly for creating this kind of dependencies, they are not suitable if the other kernel subsystem happens to be another subsystem in configfs, so this patch adds unlocked versions meant for configfs callbacks. Above description has been provided by: Andrzej Pietrasiewicz In configfs_depend_item() we have to consider two possible cases: 1) When we are called to depend another item in the same subsystem as caller In this case we should skip locking configfs root as we know that configfs is in valid state and our subsystem will not be unregistered during this call. 2) When we are called to depend item in different subsystem than our caller In this case we are also sure that configfs is in valid state but we have to lock root of configfs to avoid unregistration of target's subsystem. As it is other than caller's subsystem, there may be nothing what protects us against unregistration of that subsystem. Signed-off-by: Krzysztof Opasiak Cc: Joel Becker Cc: Christoph Hellwig Signed-off-by: Nicholas Bellinger --- fs/configfs/dir.c| 73 include/linux/configfs.h | 16 +++ 2 files changed, 89 insertions(+) diff --git a/fs/configfs/dir.c b/fs/configfs/dir.c index 3873ac1..8fd032a 100644 --- a/fs/configfs/dir.c +++ b/fs/configfs/dir.c @@ -1171,6 +1171,79 @@ void configfs_undepend_item(struct config_item *target) } EXPORT_SYMBOL(configfs_undepend_item); +/* + * caller_subsys is a caller's subsystem not target's. This is used to + * determine if we should lock root and check subsys or not. When we are + * in the same subsystem as our target there is no need to do locking as + * we know that subsys is valid and is not unregistered during this function + * as we are called from callback of one of his children and VFS holds a lock + * on some inode. Otherwise we have to lock our root to ensure that target's + * subsystem it is not unregistered during this function. + */ +int configfs_depend_item_unlocked(struct configfs_subsystem *caller_subsys, + struct config_item *target) +{ + struct configfs_subsystem *target_subsys; + struct config_group *root, *parent; + struct configfs_dirent *subsys_sd; + int ret = -ENOENT; + + /* Disallow this function for configfs root */ + if (configfs_is_root(target)) + return -EINVAL; + + parent = target->ci_group; + /* +* This may happen when someone is trying to depend root +* directory of some subsystem +*/ + if (configfs_is_root(>cg_item)) { + target_subsys = to_configfs_subsystem(to_config_group(target)); + root = parent; + } else { + target_subsys = parent->cg_subsys; + /* Find a cofnigfs root as we may need it for locking */ + for (root = parent; !configfs_is_root(>cg_item); +root = root->cg_item.ci_group) + ; + } + + if (target_subsys != caller_subsys) { + /* +* We are in other configfs subsystem, so we have to do +* additional locking to prevent other subsystem from being +* unregistered +*/ + mutex_lock(_inode(root->cg_item.ci_dentry)->i_mutex); + + /* +* As we are trying to depend item from other subsystem +* we have to check if this subsystem is still registered +*/ + subsys_sd = configfs_find_subsys_dentry( + root->cg_item.ci_dentry->d_fsdata, + _subsys->su_group.cg_item); + if (!subsys_sd) + goto out_root_unlock; + } else { + subsys_sd = target_subsys->su_group.cg_item.ci_dentry->d_fsdata; + } + + /* Now we can execute core of depend item */ + ret = configfs_do_depend_item(subsys_sd->s_dentry, target); + + if (target_subsys != caller_subsys) +out_root_unlock: + /* +* We were called from subsystem other than our target so we +* took some locks so now it's time to release them +*/ +
[PATCHv5 15/18] usb: gadget: f_tcm: remove compatibility layer
There are no old function interface users left. Signed-off-by: Andrzej Pietrasiewicz--- drivers/usb/gadget/function/f_tcm.c | 87 +++-- 1 file changed, 6 insertions(+), 81 deletions(-) diff --git a/drivers/usb/gadget/function/f_tcm.c b/drivers/usb/gadget/function/f_tcm.c index 3b1ba89..33afe6a 100644 --- a/drivers/usb/gadget/function/f_tcm.c +++ b/drivers/usb/gadget/function/f_tcm.c @@ -24,8 +24,6 @@ #include "tcm.h" #include "u_tcm.h" -#ifndef USBF_TCM_INCLUDED - #define TPG_INSTANCES 1 struct tpg_instance { @@ -36,7 +34,6 @@ struct tpg_instance { static struct tpg_instance tpg_instances[TPG_INSTANCES]; static DEFINE_MUTEX(tpg_instances_lock); -#endif static inline struct f_uas *to_f_uas(struct usb_function *f) { @@ -1386,10 +1383,8 @@ static struct se_portal_group *usbg_make_tpg( struct usbg_tpg *tpg; unsigned long tpgt; int ret; -#ifndef USBF_TCM_INCLUDED struct f_tcm_opts *opts; unsigned i; -#endif if (strstr(name, "tpgt_") != name) return ERR_PTR(-EINVAL); @@ -1400,7 +1395,6 @@ static struct se_portal_group *usbg_make_tpg( pr_err("gadgets, you can't do this here.\n"); return ERR_PTR(-EBUSY); } -#ifndef USBF_TCM_INCLUDED ret = -ENODEV; mutex_lock(_instances_lock); for (i = 0; i < TPG_INSTANCES; ++i) @@ -1417,26 +1411,16 @@ static struct se_portal_group *usbg_make_tpg( if (opts->has_dep && !try_module_get(opts->dependent)) goto unlock_dep; -#endif tpg = kzalloc(sizeof(struct usbg_tpg), GFP_KERNEL); ret = -ENOMEM; if (!tpg) -#ifdef USBF_TCM_INCLUDED - return ERR_PTR(-ENOMEM); -#else goto unref_dep; -#endif mutex_init(>tpg_mutex); atomic_set(>tpg_port_count, 0); tpg->workqueue = alloc_workqueue("tcm_usb_gadget", 0, 1); - if (!tpg->workqueue) { -#ifndef USBF_TCM_INCLUDED + if (!tpg->workqueue) goto free_tpg; -#endif - kfree(tpg); - return NULL; - } tpg->tport = tport; tpg->tport_tpgt = tpgt; @@ -1446,23 +1430,16 @@ static struct se_portal_group *usbg_make_tpg( * pretend to be SAS.. */ ret = core_tpg_register(wwn, >se_tpg, SCSI_PROTOCOL_SAS); - if (ret < 0) { -#ifndef USBF_TCM_INCLUDED + if (ret < 0) goto free_workqueue; -#endif - destroy_workqueue(tpg->workqueue); - kfree(tpg); - return NULL; - } -#ifndef USBF_TCM_INCLUDED + tpg_instances[i].tpg = tpg; tpg->fi = tpg_instances[i].func_inst; mutex_unlock(>dep_lock); mutex_unlock(_instances_lock); -#endif the_only_tpg_I_currently_have = tpg; return >se_tpg; -#ifndef USBF_TCM_INCLUDED + free_workqueue: destroy_workqueue(tpg->workqueue); free_tpg: @@ -1475,7 +1452,6 @@ unlock_inst: mutex_unlock(_instances_lock); return ERR_PTR(ret); -#endif } static int tcm_usbg_drop_nexus(struct usbg_tpg *); @@ -1484,16 +1460,13 @@ static void usbg_drop_tpg(struct se_portal_group *se_tpg) { struct usbg_tpg *tpg = container_of(se_tpg, struct usbg_tpg, se_tpg); -#ifndef USBF_TCM_INCLUDED unsigned i; struct f_tcm_opts *opts; -#endif tcm_usbg_drop_nexus(tpg); core_tpg_deregister(se_tpg); destroy_workqueue(tpg->workqueue); -#ifndef USBF_TCM_INCLUDED mutex_lock(_instances_lock); for (i = 0; i < TPG_INSTANCES; ++i) if (tpg_instances[i].tpg == tpg) @@ -1506,7 +1479,7 @@ static void usbg_drop_tpg(struct se_portal_group *se_tpg) module_put(opts->dependent); mutex_unlock(>dep_lock); mutex_unlock(_instances_lock); -#endif + kfree(tpg); the_only_tpg_I_currently_have = NULL; } @@ -2066,13 +2039,10 @@ static int tcm_bind(struct usb_configuration *c, struct usb_function *f) struct f_uas*fu = to_f_uas(f); struct usb_gadget *gadget = c->cdev->gadget; struct usb_ep *ep; -#ifndef USBF_TCM_INCLUDED struct f_tcm_opts *opts; -#endif int iface; int ret; -#ifndef USBF_TCM_INCLUDED opts = container_of(f->fi, struct f_tcm_opts, func_inst); mutex_lock(>dep_lock); @@ -2081,7 +2051,7 @@ static int tcm_bind(struct usb_configuration *c, struct usb_function *f) return -ENODEV; } mutex_unlock(>dep_lock); -#endif + if (tcm_us_strings[0].id == 0) { ret = usb_string_ids_tab(c->cdev, tcm_us_strings); if (ret < 0) @@ -2149,18 +2119,6 @@ ep_fail: return -ENOTSUPP; } -#ifdef USBF_TCM_INCLUDED - -static void tcm_old_unbind(struct usb_configuration *c, struct
[PATCHv5 11/18] usb: gadget: tcm: simplify attribute store function
Simplify function code. Signed-off-by: Andrzej Pietrasiewicz--- drivers/usb/gadget/legacy/tcm_usb_gadget.c | 22 +++--- 1 file changed, 7 insertions(+), 15 deletions(-) diff --git a/drivers/usb/gadget/legacy/tcm_usb_gadget.c b/drivers/usb/gadget/legacy/tcm_usb_gadget.c index 98064bb..96b5d54 100644 --- a/drivers/usb/gadget/legacy/tcm_usb_gadget.c +++ b/drivers/usb/gadget/legacy/tcm_usb_gadget.c @@ -1503,27 +1503,19 @@ static ssize_t tcm_usbg_tpg_enable_store(struct config_item *item, if (ret) return ret; - if (op && tpg->gadget_connect) { - ret = -EINVAL; - goto out; - } - if (!op && !tpg->gadget_connect) { - ret = -EINVAL; - goto out; - } + if ((op && tpg->gadget_connect) || (!op && !tpg->gadget_connect)) + return -EINVAL; - if (op) { + if (op) ret = usbg_attach(tpg); - if (ret) - goto out; - } else { + else usbg_detach(tpg); - } + if (ret) + return ret; + tpg->gadget_connect = op; return count; -out: - return ret; } static ssize_t tcm_usbg_tpg_nexus_show(struct config_item *item, char *page) -- 1.9.1 -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCHv5 14/18] usb: gadget: tcm: convert to use new function registration interface
Convert the only user of old tcm function interface so that the old interface can be removed. Signed-off-by: Andrzej Pietrasiewicz--- drivers/usb/gadget/legacy/Kconfig | 1 + drivers/usb/gadget/legacy/tcm_usb_gadget.c | 62 +- 2 files changed, 53 insertions(+), 10 deletions(-) diff --git a/drivers/usb/gadget/legacy/Kconfig b/drivers/usb/gadget/legacy/Kconfig index 4d682ad..a23d1b9 100644 --- a/drivers/usb/gadget/legacy/Kconfig +++ b/drivers/usb/gadget/legacy/Kconfig @@ -250,6 +250,7 @@ config USB_GADGET_TARGET tristate "USB Gadget Target Fabric Module" depends on TARGET_CORE select USB_LIBCOMPOSITE + select USB_F_TCM help This fabric is an USB gadget. Two USB protocols are supported that is BBB or BOT (Bulk Only Transport) and UAS (USB Attached SCSI). BOT is diff --git a/drivers/usb/gadget/legacy/tcm_usb_gadget.c b/drivers/usb/gadget/legacy/tcm_usb_gadget.c index f042df4..c209148 100644 --- a/drivers/usb/gadget/legacy/tcm_usb_gadget.c +++ b/drivers/usb/gadget/legacy/tcm_usb_gadget.c @@ -21,11 +21,9 @@ #include #include -USB_GADGET_COMPOSITE_OPTIONS(); +#include "u_tcm.h" -/* #include to be removed when new function registration interface is used */ -#define USBF_TCM_INCLUDED -#include "../function/f_tcm.c" +USB_GADGET_COMPOSITE_OPTIONS(); #define UAS_VENDOR_ID 0x0525 /* NetChip */ #define UAS_PRODUCT_ID 0xa4a5 /* Linux-USB File-backed Storage Gadget */ @@ -60,8 +58,31 @@ static struct usb_gadget_strings *usbg_strings[] = { NULL, }; +static struct usb_function_instance *fi_tcm; +static struct usb_function *f_tcm; + static int guas_unbind(struct usb_composite_dev *cdev) { + if (!IS_ERR_OR_NULL(f_tcm)) + usb_put_function(f_tcm); + + return 0; +} + +static int tcm_do_config(struct usb_configuration *c) +{ + int status; + + f_tcm = usb_get_function(fi_tcm); + if (IS_ERR(f_tcm)) + return PTR_ERR(f_tcm); + + status = usb_add_function(c, f_tcm); + if (status < 0) { + usb_put_function(f_tcm); + return status; + } + return 0; } @@ -71,6 +92,9 @@ static struct usb_configuration usbg_config_driver = { .bmAttributes = USB_CONFIG_ATT_SELFPOWER, }; +static int usbg_attach(struct usb_function_instance *f); +static void usbg_detach(struct usb_function_instance *f); + static int usb_target_bind(struct usb_composite_dev *cdev) { int ret; @@ -87,8 +111,7 @@ static int usb_target_bind(struct usb_composite_dev *cdev) usbg_config_driver.iConfiguration = usbg_us_strings[USB_G_STR_CONFIG].id; - ret = usb_add_config(cdev, _config_driver, - tcm_bind_config); + ret = usb_add_config(cdev, _config_driver, tcm_do_config); if (ret) return ret; usb_composite_overwrite_options(cdev, ); @@ -104,25 +127,44 @@ static struct usb_composite_driver usbg_driver = { .unbind = guas_unbind, }; -static int usbg_attach(struct usbg_tpg *tpg) +static int usbg_attach(struct usb_function_instance *f) { return usb_composite_probe(_driver); } -static void usbg_detach(struct usbg_tpg *tpg) +static void usbg_detach(struct usb_function_instance *f) { usb_composite_unregister(_driver); } static int __init usb_target_gadget_init(void) { - return target_register_template(_ops); + struct f_tcm_opts *tcm_opts; + + fi_tcm = usb_get_function_instance("tcm"); + if (IS_ERR(fi_tcm)) + return PTR_ERR(fi_tcm); + + tcm_opts = container_of(fi_tcm, struct f_tcm_opts, func_inst); + mutex_lock(_opts->dep_lock); + tcm_opts->tcm_register_callback = usbg_attach; + tcm_opts->tcm_unregister_callback = usbg_detach; + tcm_opts->dependent = THIS_MODULE; + tcm_opts->can_attach = true; + tcm_opts->has_dep = true; + mutex_unlock(_opts->dep_lock); + + fi_tcm->set_inst_name(fi_tcm, "tcm-legacy"); + + return 0; } module_init(usb_target_gadget_init); static void __exit usb_target_gadget_exit(void) { - target_unregister_template(_ops); + if (!IS_ERR_OR_NULL(fi_tcm)) + usb_put_function_instance(fi_tcm); + } module_exit(usb_target_gadget_exit); -- 1.9.1 -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCHv5 08/18] usb: gadget: tcm: split string definitions into function and device
Prepare for factoring out f_tcm from a legacy gadget. Signed-off-by: Andrzej Pietrasiewicz--- drivers/usb/gadget/legacy/tcm_usb_gadget.c | 25 + drivers/usb/gadget/legacy/tcm_usb_gadget.h | 3 +-- 2 files changed, 22 insertions(+), 6 deletions(-) diff --git a/drivers/usb/gadget/legacy/tcm_usb_gadget.c b/drivers/usb/gadget/legacy/tcm_usb_gadget.c index 65e4950..8278d3b 100644 --- a/drivers/usb/gadget/legacy/tcm_usb_gadget.c +++ b/drivers/usb/gadget/legacy/tcm_usb_gadget.c @@ -1990,13 +1990,13 @@ static struct usb_device_descriptor usbg_device_desc = { .bNumConfigurations = 1, }; +#define USB_G_STR_CONFIG USB_GADGET_FIRST_AVAIL_IDX + static struct usb_string usbg_us_strings[] = { [USB_GADGET_MANUFACTURER_IDX].s = "Target Manufactor", [USB_GADGET_PRODUCT_IDX].s = "Target Product", [USB_GADGET_SERIAL_IDX].s = "0001", [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", { }, }; @@ -2010,6 +2010,22 @@ static struct usb_gadget_strings *usbg_strings[] = { NULL, }; +static struct usb_string tcm_us_strings[] = { + [USB_G_STR_INT_UAS].s = "USB Attached SCSI", + [USB_G_STR_INT_BBB].s = "Bulk Only Transport", + { }, +}; + +static struct usb_gadget_strings tcm_stringtab = { + .language = 0x0409, + .strings = tcm_us_strings, +}; + +static struct usb_gadget_strings *tcm_strings[] = { + _stringtab, + NULL, +}; + static int guas_unbind(struct usb_composite_dev *cdev) { return 0; @@ -2174,10 +2190,11 @@ static int usbg_cfg_bind(struct usb_configuration *c) fu->function.set_alt = usbg_set_alt; fu->function.setup = usbg_setup; fu->function.disable = usbg_disable; + fu->function.strings = tcm_strings; 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; + bot_intf_desc.iInterface = tcm_us_strings[USB_G_STR_INT_BBB].id; + uasp_intf_desc.iInterface = tcm_us_strings[USB_G_STR_INT_UAS].id; ret = usb_add_function(c, >function); if (ret) diff --git a/drivers/usb/gadget/legacy/tcm_usb_gadget.h b/drivers/usb/gadget/legacy/tcm_usb_gadget.h index 0b749e1..f1b69e2 100644 --- a/drivers/usb/gadget/legacy/tcm_usb_gadget.h +++ b/drivers/usb/gadget/legacy/tcm_usb_gadget.h @@ -16,8 +16,7 @@ #define UASP_SS_EP_COMP_NUM_STREAMS (1 << UASP_SS_EP_COMP_LOG_STREAMS) enum { - USB_G_STR_CONFIG = USB_GADGET_FIRST_AVAIL_IDX, - USB_G_STR_INT_UAS, + USB_G_STR_INT_UAS = 0, USB_G_STR_INT_BBB, }; -- 1.9.1 -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCHv5 13/18] usb: gadget: f_tcm: convert to new function interface with backward compatibility
Converting tcm to the new function interface requires converting USB tcm's function code and its users. This patch converts the f_tcm.c to the new function interface. The file can be now compiled into a separate module usb_f_tcm.ko. The old function interface is provided by means of preprocessor conditional directives. After all users are converted, the old interface can be removed. Signed-off-by: Andrzej Pietrasiewicz--- drivers/usb/gadget/Kconfig | 3 + drivers/usb/gadget/function/Makefile | 2 + drivers/usb/gadget/function/f_tcm.c| 286 - drivers/usb/gadget/function/tcm.h | 2 + drivers/usb/gadget/function/u_tcm.h| 50 + drivers/usb/gadget/legacy/tcm_usb_gadget.c | 1 + 6 files changed, 339 insertions(+), 5 deletions(-) create mode 100644 drivers/usb/gadget/function/u_tcm.h diff --git a/drivers/usb/gadget/Kconfig b/drivers/usb/gadget/Kconfig index 33834aa..5bf50db 100644 --- a/drivers/usb/gadget/Kconfig +++ b/drivers/usb/gadget/Kconfig @@ -199,6 +199,9 @@ config USB_F_HID config USB_F_PRINTER tristate +config USB_F_TCM + tristate + choice tristate "USB Gadget Drivers" default USB_ETH diff --git a/drivers/usb/gadget/function/Makefile b/drivers/usb/gadget/function/Makefile index bd7def5..cb8c225 100644 --- a/drivers/usb/gadget/function/Makefile +++ b/drivers/usb/gadget/function/Makefile @@ -44,3 +44,5 @@ usb_f_hid-y := f_hid.o obj-$(CONFIG_USB_F_HID)+= usb_f_hid.o usb_f_printer-y:= f_printer.o obj-$(CONFIG_USB_F_PRINTER)+= usb_f_printer.o +usb_f_tcm-y:= f_tcm.o +obj-$(CONFIG_USB_F_TCM)+= usb_f_tcm.o diff --git a/drivers/usb/gadget/function/f_tcm.c b/drivers/usb/gadget/function/f_tcm.c index ce246bc..3b1ba89 100644 --- a/drivers/usb/gadget/function/f_tcm.c +++ b/drivers/usb/gadget/function/f_tcm.c @@ -22,6 +22,21 @@ #include #include "tcm.h" +#include "u_tcm.h" + +#ifndef USBF_TCM_INCLUDED + +#define TPG_INSTANCES 1 + +struct tpg_instance { + struct usb_function_instance*func_inst; + struct usbg_tpg *tpg; +}; + +static struct tpg_instance tpg_instances[TPG_INSTANCES]; + +static DEFINE_MUTEX(tpg_instances_lock); +#endif static inline struct f_uas *to_f_uas(struct usb_function *f) { @@ -1371,6 +1386,10 @@ static struct se_portal_group *usbg_make_tpg( struct usbg_tpg *tpg; unsigned long tpgt; int ret; +#ifndef USBF_TCM_INCLUDED + struct f_tcm_opts *opts; + unsigned i; +#endif if (strstr(name, "tpgt_") != name) return ERR_PTR(-EINVAL); @@ -1381,14 +1400,40 @@ static struct se_portal_group *usbg_make_tpg( pr_err("gadgets, you can't do this here.\n"); return ERR_PTR(-EBUSY); } +#ifndef USBF_TCM_INCLUDED + ret = -ENODEV; + mutex_lock(_instances_lock); + for (i = 0; i < TPG_INSTANCES; ++i) + if (tpg_instances[i].func_inst && !tpg_instances[i].tpg) + break; + if (i == TPG_INSTANCES) + goto unlock_inst; + + opts = container_of(tpg_instances[i].func_inst, struct f_tcm_opts, + func_inst); + mutex_lock(>dep_lock); + if (!opts->ready) + goto unlock_dep; + + if (opts->has_dep && !try_module_get(opts->dependent)) + goto unlock_dep; +#endif tpg = kzalloc(sizeof(struct usbg_tpg), GFP_KERNEL); + ret = -ENOMEM; if (!tpg) +#ifdef USBF_TCM_INCLUDED return ERR_PTR(-ENOMEM); +#else + goto unref_dep; +#endif mutex_init(>tpg_mutex); atomic_set(>tpg_port_count, 0); tpg->workqueue = alloc_workqueue("tcm_usb_gadget", 0, 1); if (!tpg->workqueue) { +#ifndef USBF_TCM_INCLUDED + goto free_tpg; +#endif kfree(tpg); return NULL; } @@ -1402,12 +1447,35 @@ static struct se_portal_group *usbg_make_tpg( */ ret = core_tpg_register(wwn, >se_tpg, SCSI_PROTOCOL_SAS); if (ret < 0) { +#ifndef USBF_TCM_INCLUDED + goto free_workqueue; +#endif destroy_workqueue(tpg->workqueue); kfree(tpg); return NULL; } +#ifndef USBF_TCM_INCLUDED + tpg_instances[i].tpg = tpg; + tpg->fi = tpg_instances[i].func_inst; + mutex_unlock(>dep_lock); + mutex_unlock(_instances_lock); +#endif the_only_tpg_I_currently_have = tpg; return >se_tpg; +#ifndef USBF_TCM_INCLUDED +free_workqueue: + destroy_workqueue(tpg->workqueue); +free_tpg: + kfree(tpg); +unref_dep: + module_put(opts->dependent); +unlock_dep: + mutex_unlock(>dep_lock); +unlock_inst: + mutex_unlock(_instances_lock); + + return ERR_PTR(ret); +#endif } static int
[PATCHv5 16/18] usb: gadget: f_tcm: remove redundant singleton
The only instance is guaranteed with TPG_INSTANCES defined to 1. Signed-off-by: Andrzej Pietrasiewicz--- drivers/usb/gadget/function/f_tcm.c | 9 - drivers/usb/gadget/function/tcm.h | 2 -- 2 files changed, 11 deletions(-) diff --git a/drivers/usb/gadget/function/f_tcm.c b/drivers/usb/gadget/function/f_tcm.c index 33afe6a..b33738a 100644 --- a/drivers/usb/gadget/function/f_tcm.c +++ b/drivers/usb/gadget/function/f_tcm.c @@ -1371,8 +1371,6 @@ static int usbg_init_nodeacl(struct se_node_acl *se_nacl, const char *name) return 0; } -struct usbg_tpg *the_only_tpg_I_currently_have; - static struct se_portal_group *usbg_make_tpg( struct se_wwn *wwn, struct config_group *group, @@ -1390,11 +1388,6 @@ static struct se_portal_group *usbg_make_tpg( return ERR_PTR(-EINVAL); if (kstrtoul(name + 5, 0, ) || tpgt > UINT_MAX) return ERR_PTR(-EINVAL); - if (the_only_tpg_I_currently_have) { - pr_err("Until the gadget framework can't handle multiple\n"); - pr_err("gadgets, you can't do this here.\n"); - return ERR_PTR(-EBUSY); - } ret = -ENODEV; mutex_lock(_instances_lock); for (i = 0; i < TPG_INSTANCES; ++i) @@ -1437,7 +1430,6 @@ static struct se_portal_group *usbg_make_tpg( tpg->fi = tpg_instances[i].func_inst; mutex_unlock(>dep_lock); mutex_unlock(_instances_lock); - the_only_tpg_I_currently_have = tpg; return >se_tpg; free_workqueue: @@ -1481,7 +1473,6 @@ static void usbg_drop_tpg(struct se_portal_group *se_tpg) mutex_unlock(_instances_lock); kfree(tpg); - the_only_tpg_I_currently_have = NULL; } static struct se_wwn *usbg_make_tport( diff --git a/drivers/usb/gadget/function/tcm.h b/drivers/usb/gadget/function/tcm.h index 0b8ff6d..b75c6f3 100644 --- a/drivers/usb/gadget/function/tcm.h +++ b/drivers/usb/gadget/function/tcm.h @@ -129,6 +129,4 @@ struct f_uas { struct usb_request *bot_req_out; }; -extern struct usbg_tpg *the_only_tpg_I_currently_have; - #endif /* __TARGET_USB_GADGET_H__ */ -- 1.9.1 -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCHv5 10/18] usb: gadget: tcm: use strtobool for a boolean value
Simplify the function. Signed-off-by: Andrzej Pietrasiewicz--- drivers/usb/gadget/legacy/tcm_usb_gadget.c | 10 -- 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/drivers/usb/gadget/legacy/tcm_usb_gadget.c b/drivers/usb/gadget/legacy/tcm_usb_gadget.c index b6e46a0..98064bb 100644 --- a/drivers/usb/gadget/legacy/tcm_usb_gadget.c +++ b/drivers/usb/gadget/legacy/tcm_usb_gadget.c @@ -1496,14 +1496,12 @@ static ssize_t tcm_usbg_tpg_enable_store(struct config_item *item, { struct se_portal_group *se_tpg = to_tpg(item); struct usbg_tpg *tpg = container_of(se_tpg, struct usbg_tpg, se_tpg); - unsigned long op; + bool op; ssize_t ret; - ret = kstrtoul(page, 0, ); - if (ret < 0) - return -EINVAL; - if (op > 1) - return -EINVAL; + ret = strtobool(page, ); + if (ret) + return ret; if (op && tpg->gadget_connect) { ret = -EINVAL; -- 1.9.1 -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCHv5 03/18] fs: configfs: Factor out configfs_find_subsys_dentry()
From: Krzysztof Opasiakconfigfs_depend_item() is quite complicated and should be split up into smaller functions. This also allow to share this code with other functions. Signed-off-by: Krzysztof Opasiak Cc: Joel Becker Cc: Christoph Hellwig Signed-off-by: Nicholas Bellinger --- fs/configfs/dir.c | 33 + 1 file changed, 21 insertions(+), 12 deletions(-) diff --git a/fs/configfs/dir.c b/fs/configfs/dir.c index 43decd2..3873ac1 100644 --- a/fs/configfs/dir.c +++ b/fs/configfs/dir.c @@ -1079,11 +1079,30 @@ out_unlock_dirent_lock: return ret; } +static inline struct configfs_dirent * +configfs_find_subsys_dentry(struct configfs_dirent *root_sd, + struct config_item *subsys_item) +{ + struct configfs_dirent *p; + struct configfs_dirent *ret = NULL; + + list_for_each_entry(p, _sd->s_children, s_sibling) { + if (p->s_type & CONFIGFS_DIR && + p->s_element == subsys_item) { + ret = p; + break; + } + } + + return ret; +} + + int configfs_depend_item(struct configfs_subsystem *subsys, struct config_item *target) { int ret; - struct configfs_dirent *p, *root_sd, *subsys_sd = NULL; + struct configfs_dirent *subsys_sd; struct config_item *s_item = >su_group.cg_item; struct dentry *root; @@ -1102,17 +1121,7 @@ int configfs_depend_item(struct configfs_subsystem *subsys, */ mutex_lock(_inode(root)->i_mutex); - root_sd = root->d_fsdata; - - list_for_each_entry(p, _sd->s_children, s_sibling) { - if (p->s_type & CONFIGFS_DIR) { - if (p->s_element == s_item) { - subsys_sd = p; - break; - } - } - } - + subsys_sd = configfs_find_subsys_dentry(root->d_fsdata, s_item); if (!subsys_sd) { ret = -ENOENT; goto out_unlock_fs; -- 1.9.1 -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCHv5 00/18] Equivalent of tcm_usb_gadget with configfs
Dear All, This series adds support to tcm usb gadget for composing it with configfs. @Felipe: The v4 series was rebased onto Nicholas' tree (target-pending). Consequently, the recent fixing patches were based against that tree. This (v5) series is rebased onto your tree in case you want to apply it, it includes the said recent fixing patches. @target-devel folks: You might be wondering why add configfs for something which already supports configfs. In tcm_usb_gadget configfs has beeen used for configuring the SCSI target part, but the usb gadget part is considered a legacy gadget. A legacy gadget is a composite usb gadget whose composition is defined statically at compilation time. Composite gadgets can consist of a number of "functions" and configurations. In legacy gadgets the selection is hardcoded in a dedicated kernel module. But with configfs the selection can be made at runtime without writing any kernel code. The conversion process started almost three years ago. The series aims at integrating configfs into tcm, the way it has been done with 19 of 20 usb functions. In other words this concludes the process of conversion to configfs in usb gadgets. The series depends on the series from Chrisoph: http://www.spinics.net/lists/target-devel/msg10730.html v4..v5: - rebased onto Felipe's next - included Krzysztof's patches adding unlocked versions of depend/undepend item - included changes proposed by Dan Carpenter, thanks Dan! v3..v4: - rebased onto current Nicholas' tree (1cc92aed7192caa8987bba0f88226f57e9b4ed73, tcm_usb_gadget: Fix enabled attribute failure) v2..v3: - dropped a patch adding unlocked versions of depend/undepend item, instead this series depends on a series from Krzysztof: http://www.spinics.net/lists/linux-usb/msg131720.html v1..v2: - added missing comments - used the next version of configfs_(un)depend_item_unlocked() - fixed bug: THIS_MODULE is NULL if a module is compiled-in, so we cannot rely on opts->dependent being non-NULL if a dependent module is present - added passing configfs subsystem to configfs_(un)depend_item_unlocked() BACKWARD COMPATIBILITY == Please note that the old tcm_usb_gadget.ko is still available and works. USING THE NEW "GADGET" == Please refer to this post: http://www.spinics.net/lists/linux-usb/msg76388.html for general information from Sebastian on how to use configfs-based gadgets (*). With configfs the procedure is as follows, compared to the information mentioned above (*): instead of mkdir functions/acm.ttyS1 do mkdir functions/tcm. e.g. mkdir functions/tcm.usb0. In the tcm.usb0 directory there are no attributes, because all the configuration is performed with the target subsystem in configfs. Below is a script which creates a tcm gadget on a board with dwc3: # mount -t configfs none /sys/kernel/config # modprobe usb_f_tcm # cd /sys/kernel/config/usb_gadget # mkdir tcm # cd tcm # mkdir functions/tcm.0 # cd /sys/kernel/config/target/ # mkdir usb_gadget # cd usb_gadget # mkdir naa.0123456789abcdef # cd naa.0123456789abcdef # mkdir tpgt_1 # cd tpgt_1 # echo naa.01234567890abcdef > nexus # echo 1 > enable # cd /sys/kernel/config/usb_gadget/tcm # mkdir configs/c.1 # ln -s functions/tcm.0 configs/c.1 # echo $VENDOR_ID > idVendor # echo $PRODUCT_ID > idProduct # echo 1240.dwc3 > UDC TESTING THE FUNCTION The most basic testing device: run the script above host: see the gadget enumerated Andrzej Pietrasiewicz (11): usb: gadget: tcm: split string definitions into function and device usb: gadget: tcm: follow naming conventions usb: gadget: tcm: use strtobool for a boolean value usb: gadget: tcm: simplify attribute store function usb: gadget: tcm: factor out f_tcm usb: gadget: f_tcm: convert to new function interface with backward compatibility usb: gadget: tcm: convert to use new function registration interface usb: gadget: f_tcm: remove compatibility layer usb: gadget: f_tcm: remove redundant singleton usb: gadget: f_tcm: use usb_gstrings_attach usb: gadget: f_tcm: add configfs support Krzysztof Opasiak (4): fs: configfs: Drop unused parameter from configfs_undepend_item() fs: configfs: Factor out configfs_do_depend_item() fs: configfs: Factor out configfs_find_subsys_dentry() fs: configfs: Add unlocked version of configfs_depend_item() Nicholas Bellinger (3): tcm_usb_gadget: Don't strip off nexus WWPN prefix tcm_usb_gadget: Fix nexus leak tcm_usb_gadget: Fix enabled attribute failure Documentation/ABI/testing/configfs-usb-gadget-tcm |6 + drivers/target/target_core_configfs.c |2 +- drivers/usb/gadget/Kconfig| 17 + drivers/usb/gadget/function/Makefile |2 + drivers/usb/gadget/function/f_tcm.c | 2397 + drivers/usb/gadget/function/tcm.h | 132 ++ drivers/usb/gadget/function/u_tcm.h | 50 +
[PATCHv5 09/18] usb: gadget: tcm: follow naming conventions
Prepare for splitting tcm_usb_gadget into legacy gadget proper and f_tcm. Signed-off-by: Andrzej Pietrasiewicz--- drivers/usb/gadget/legacy/tcm_usb_gadget.c | 28 ++-- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/drivers/usb/gadget/legacy/tcm_usb_gadget.c b/drivers/usb/gadget/legacy/tcm_usb_gadget.c index 8278d3b..b6e46a0 100644 --- a/drivers/usb/gadget/legacy/tcm_usb_gadget.c +++ b/drivers/usb/gadget/legacy/tcm_usb_gadget.c @@ -2037,7 +2037,7 @@ static struct usb_configuration usbg_config_driver = { .bmAttributes = USB_CONFIG_ATT_SELFPOWER, }; -static int usbg_bind(struct usb_configuration *c, struct usb_function *f) +static int tcm_bind(struct usb_configuration *c, struct usb_function *f) { struct f_uas*fu = to_f_uas(f); struct usb_gadget *gadget = c->cdev->gadget; @@ -2100,7 +2100,7 @@ ep_fail: return -ENOTSUPP; } -static void usbg_unbind(struct usb_configuration *c, struct usb_function *f) +static void tcm_unbind(struct usb_configuration *c, struct usb_function *f) { struct f_uas *fu = to_f_uas(f); @@ -2114,7 +2114,7 @@ struct guas_setup_wq { unsigned int alt; }; -static void usbg_delayed_set_alt(struct work_struct *wq) +static void tcm_delayed_set_alt(struct work_struct *wq) { struct guas_setup_wq *work = container_of(wq, struct guas_setup_wq, work); @@ -2135,7 +2135,7 @@ static void usbg_delayed_set_alt(struct work_struct *wq) usb_composite_setup_continue(fu->function.config->cdev); } -static int usbg_set_alt(struct usb_function *f, unsigned intf, unsigned alt) +static int tcm_set_alt(struct usb_function *f, unsigned intf, unsigned alt) { struct f_uas *fu = to_f_uas(f); @@ -2145,7 +2145,7 @@ static int usbg_set_alt(struct usb_function *f, unsigned intf, unsigned alt) work = kmalloc(sizeof(*work), GFP_ATOMIC); if (!work) return -ENOMEM; - INIT_WORK(>work, usbg_delayed_set_alt); + INIT_WORK(>work, tcm_delayed_set_alt); work->fu = fu; work->alt = alt; schedule_work(>work); @@ -2154,7 +2154,7 @@ static int usbg_set_alt(struct usb_function *f, unsigned intf, unsigned alt) return -EOPNOTSUPP; } -static void usbg_disable(struct usb_function *f) +static void tcm_disable(struct usb_function *f) { struct f_uas *fu = to_f_uas(f); @@ -2165,7 +2165,7 @@ static void usbg_disable(struct usb_function *f) fu->flags = 0; } -static int usbg_setup(struct usb_function *f, +static int tcm_setup(struct usb_function *f, const struct usb_ctrlrequest *ctrl) { struct f_uas *fu = to_f_uas(f); @@ -2176,7 +2176,7 @@ static int usbg_setup(struct usb_function *f, return usbg_bot_setup(f, ctrl); } -static int usbg_cfg_bind(struct usb_configuration *c) +static int tcm_bind_config(struct usb_configuration *c) { struct f_uas *fu; int ret; @@ -2185,11 +2185,11 @@ static int usbg_cfg_bind(struct usb_configuration *c) if (!fu) return -ENOMEM; fu->function.name = "Target Function"; - fu->function.bind = usbg_bind; - fu->function.unbind = usbg_unbind; - fu->function.set_alt = usbg_set_alt; - fu->function.setup = usbg_setup; - fu->function.disable = usbg_disable; + fu->function.bind = tcm_bind; + fu->function.unbind = tcm_unbind; + fu->function.set_alt = tcm_set_alt; + fu->function.setup = tcm_setup; + fu->function.disable = tcm_disable; fu->function.strings = tcm_strings; fu->tpg = the_only_tpg_I_currently_have; @@ -2223,7 +2223,7 @@ static int usb_target_bind(struct usb_composite_dev *cdev) usbg_us_strings[USB_G_STR_CONFIG].id; ret = usb_add_config(cdev, _config_driver, - usbg_cfg_bind); + tcm_bind_config); if (ret) return ret; usb_composite_overwrite_options(cdev, ); -- 1.9.1 -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCHv5 18/18] usb: gadget: f_tcm: add configfs support
Allow using the tcm function as a component of a gadget composed with ConfigFS. Signed-off-by: Andrzej Pietrasiewicz--- Documentation/ABI/testing/configfs-usb-gadget-tcm | 6 ++ drivers/usb/gadget/Kconfig| 14 + drivers/usb/gadget/function/f_tcm.c | 72 +-- 3 files changed, 88 insertions(+), 4 deletions(-) create mode 100644 Documentation/ABI/testing/configfs-usb-gadget-tcm diff --git a/Documentation/ABI/testing/configfs-usb-gadget-tcm b/Documentation/ABI/testing/configfs-usb-gadget-tcm new file mode 100644 index 000..a29ed2d --- /dev/null +++ b/Documentation/ABI/testing/configfs-usb-gadget-tcm @@ -0,0 +1,6 @@ +What: /config/usb-gadget/gadget/functions/tcm.name +Date: Dec 2015 +KernelVersion: 4.5 +Description: + There are no attributes because all the configuration + is performed in the "target" subsystem of configfs. diff --git a/drivers/usb/gadget/Kconfig b/drivers/usb/gadget/Kconfig index 5bf50db..0527308 100644 --- a/drivers/usb/gadget/Kconfig +++ b/drivers/usb/gadget/Kconfig @@ -454,6 +454,20 @@ config USB_CONFIGFS_F_PRINTER For more information, see Documentation/usb/gadget_printer.txt which includes sample code for accessing the device file. +config USB_CONFIGFS_F_TCM + bool "USB Gadget Target Fabric" + depends on TARGET_CORE + depends on USB_CONFIGFS + select USB_LIBCOMPOSITE + select USB_F_TCM + help + This fabric is a USB gadget component. Two USB protocols are + supported that is BBB or BOT (Bulk Only Transport) and UAS + (USB Attached SCSI). BOT is advertised on alternative + interface 0 (primary) and UAS is on alternative interface 1. + Both protocols can work on USB2.0 and USB3.0. + UAS utilizes the USB 3.0 feature called streams support. + source "drivers/usb/gadget/legacy/Kconfig" endchoice diff --git a/drivers/usb/gadget/function/f_tcm.c b/drivers/usb/gadget/function/f_tcm.c index 4a00463..ec8287a 100644 --- a/drivers/usb/gadget/function/f_tcm.c +++ b/drivers/usb/gadget/function/f_tcm.c @@ -23,6 +23,7 @@ #include "tcm.h" #include "u_tcm.h" +#include "configfs.h" #define TPG_INSTANCES 1 @@ -1402,8 +1403,16 @@ static struct se_portal_group *usbg_make_tpg( if (!opts->ready) goto unlock_dep; - if (opts->has_dep && !try_module_get(opts->dependent)) - goto unlock_dep; + if (opts->has_dep) { + if (!try_module_get(opts->dependent)) + goto unlock_dep; + } else { + ret = configfs_depend_item_unlocked( + group->cg_subsys, + >func_inst.group.cg_item); + if (ret) + goto unlock_dep; + } tpg = kzalloc(sizeof(struct usbg_tpg), GFP_KERNEL); ret = -ENOMEM; @@ -1437,7 +1446,10 @@ free_workqueue: free_tpg: kfree(tpg); unref_dep: - module_put(opts->dependent); + if (opts->has_dep) + module_put(opts->dependent); + else + configfs_undepend_item_unlocked(>func_inst.group.cg_item); unlock_dep: mutex_unlock(>dep_lock); unlock_inst: @@ -1468,7 +1480,10 @@ static void usbg_drop_tpg(struct se_portal_group *se_tpg) opts = container_of(tpg_instances[i].func_inst, struct f_tcm_opts, func_inst); mutex_lock(>dep_lock); - module_put(opts->dependent); + if (opts->has_dep) + module_put(opts->dependent); + else + configfs_undepend_item_unlocked(>func_inst.group.cg_item); mutex_unlock(>dep_lock); mutex_unlock(_instances_lock); @@ -2175,6 +2190,28 @@ static int tcm_setup(struct usb_function *f, return usbg_bot_setup(f, ctrl); } +static inline struct f_tcm_opts *to_f_tcm_opts(struct config_item *item) +{ + return container_of(to_config_group(item), struct f_tcm_opts, + func_inst.group); +} + +static void tcm_attr_release(struct config_item *item) +{ + struct f_tcm_opts *opts = to_f_tcm_opts(item); + + usb_put_function_instance(>func_inst); +} + +static struct configfs_item_operations tcm_item_ops = { + .release= tcm_attr_release, +}; + +static struct config_item_type tcm_func_type = { + .ct_item_ops= _item_ops, + .ct_owner = THIS_MODULE, +}; + static void tcm_free_inst(struct usb_function_instance *f) { struct f_tcm_opts *opts; @@ -2193,6 +2230,28 @@ static void tcm_free_inst(struct usb_function_instance *f) kfree(opts); } +static int tcm_register_callback(struct usb_function_instance *f) +{ + struct f_tcm_opts *opts = container_of(f, struct f_tcm_opts, func_inst); + + mutex_lock(>dep_lock); + opts->can_attach = true; + mutex_unlock(>dep_lock); + + return 0;
Re: [PATCH] USB: serial: option: add support for Quectel UC20
Seems it follows the layout given by the windows drivers, no special Quectel layout. MI_00 Qualcomm HS-USB Diagnostics 9003 MI_01 Qualcomm HS-USB NMEA 9003 MI_02 Qualcomm HS-USB AT Port 9003 MI_03 Qualcomm HS-USB Modem 9003 MI_04 Qualcomm Wireless HS-USB Ethernet Adapter 9003 wbr /Lars -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v2 1/3] reset: Add shared reset_control_[de]assert variants
Add reset_control_deassert_shared / reset_control_assert_shared functions which are intended for use by drivers for hw blocks which (may) share a reset line with another driver / hw block. Unlike the regular reset_control_[de]assert functions these functions keep track of how often deassert_shared / assert_shared have been called and keep the line deasserted as long as deassert has been called more times than assert. Signed-off-by: Hans de Goede--- Changes in v2: -This is a new patch in v2 of this patch-set --- drivers/reset/core.c | 121 --- include/linux/reset-controller.h | 2 + include/linux/reset.h| 2 + 3 files changed, 116 insertions(+), 9 deletions(-) diff --git a/drivers/reset/core.c b/drivers/reset/core.c index 9ab9290..8c3436c 100644 --- a/drivers/reset/core.c +++ b/drivers/reset/core.c @@ -22,16 +22,29 @@ static DEFINE_MUTEX(reset_controller_list_mutex); static LIST_HEAD(reset_controller_list); /** + * struct reset_line - a reset line + * @list: list entry for the reset controllers reset line list + * @id: ID of the reset line in the reset controller device + * @refcnt: Number of reset_control structs referencing this device + * @deassert_cnt: Number of times this reset line has been deasserted + */ +struct reset_line { + struct list_head list; + unsigned int id; + unsigned int refcnt; + unsigned int deassert_cnt; +}; + +/** * struct reset_control - a reset control * @rcdev: a pointer to the reset controller device * this reset control belongs to - * @id: ID of the reset controller in the reset - * controller device + * @line: reset line for this reset control */ struct reset_control { struct reset_controller_dev *rcdev; + struct reset_line *line; struct device *dev; - unsigned int id; }; /** @@ -66,6 +79,8 @@ int reset_controller_register(struct reset_controller_dev *rcdev) rcdev->of_xlate = of_reset_simple_xlate; } + INIT_LIST_HEAD(>reset_line_head); + mutex_lock(_controller_list_mutex); list_add(>list, _controller_list); mutex_unlock(_controller_list_mutex); @@ -93,7 +108,7 @@ EXPORT_SYMBOL_GPL(reset_controller_unregister); int reset_control_reset(struct reset_control *rstc) { if (rstc->rcdev->ops->reset) - return rstc->rcdev->ops->reset(rstc->rcdev, rstc->id); + return rstc->rcdev->ops->reset(rstc->rcdev, rstc->line->id); return -ENOTSUPP; } @@ -106,7 +121,7 @@ EXPORT_SYMBOL_GPL(reset_control_reset); int reset_control_assert(struct reset_control *rstc) { if (rstc->rcdev->ops->assert) - return rstc->rcdev->ops->assert(rstc->rcdev, rstc->id); + return rstc->rcdev->ops->assert(rstc->rcdev, rstc->line->id); return -ENOTSUPP; } @@ -119,13 +134,55 @@ EXPORT_SYMBOL_GPL(reset_control_assert); int reset_control_deassert(struct reset_control *rstc) { if (rstc->rcdev->ops->deassert) - return rstc->rcdev->ops->deassert(rstc->rcdev, rstc->id); + return rstc->rcdev->ops->deassert(rstc->rcdev, rstc->line->id); return -ENOTSUPP; } EXPORT_SYMBOL_GPL(reset_control_deassert); /** + * reset_control_assert_shared - asserts a shared reset line + * @rstc: reset controller + * + * Assert a shared reset line, this functions decreases the deassert count + * of the line by one and asserts it if, and only if, the deassert count + * reaches 0. + */ +int reset_control_assert_shared(struct reset_control *rstc) +{ + if (!rstc->rcdev->ops->assert) + return -ENOTSUPP; + + rstc->line->deassert_cnt--; + if (rstc->line->deassert_cnt) + return 0; + + return rstc->rcdev->ops->assert(rstc->rcdev, rstc->line->id); +} +EXPORT_SYMBOL_GPL(reset_control_assert_shared); + +/** + * reset_control_deassert_shared - deasserts a shared reset line + * @rstc: reset controller + * + * Assert a shared reset line, this functions increases the deassert count + * of the line by one and deasserts the reset line (if it was not already + * deasserted). + */ +int reset_control_deassert_shared(struct reset_control *rstc) +{ + if (!rstc->rcdev->ops->deassert) + return -ENOTSUPP; + + rstc->line->deassert_cnt++; + if (rstc->line->deassert_cnt != 1) + return 0; + + return rstc->rcdev->ops->deassert(rstc->rcdev, rstc->line->id); +} +EXPORT_SYMBOL_GPL(reset_control_deassert_shared); + +/** * reset_control_status - returns a negative errno if not supported, a * positive value if the reset line is asserted, or zero if the reset * line is not asserted. @@ -134,12 +191,47 @@ EXPORT_SYMBOL_GPL(reset_control_deassert); int reset_control_status(struct reset_control *rstc) { if (rstc->rcdev->ops->status) - return
[PATCH resend 6/9] usb: host: ehci.h: use space after comma
Put space after comma. This patch also changes QH_NEXT macro for better reading. Caught by checkpatch: "ERROR: space required after that ','" Signed-off-by: Geyslan G. Bem--- drivers/usb/host/ehci.h | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/drivers/usb/host/ehci.h b/drivers/usb/host/ehci.h index 1d2..e52a229 100644 --- a/drivers/usb/host/ehci.h +++ b/drivers/usb/host/ehci.h @@ -334,7 +334,7 @@ struct ehci_qtd { /*-*/ /* type tag from {qh,itd,sitd,fstn}->hw_next */ -#define Q_NEXT_TYPE(ehci,dma) ((dma) & cpu_to_hc32(ehci, 3 << 1)) +#define Q_NEXT_TYPE(ehci, dma) ((dma) & cpu_to_hc32(ehci, 3 << 1)) /* * Now the following defines are not converted using the @@ -350,7 +350,8 @@ struct ehci_qtd { #define Q_TYPE_FSTN(3 << 1) /* next async queue entry, or pointer to interrupt/periodic QH */ -#define QH_NEXT(ehci,dma) (cpu_to_hc32(ehci, (((u32)dma)&~0x01f)|Q_TYPE_QH)) +#define QH_NEXT(ehci, dma) \ + (cpu_to_hc32(ehci, (((u32) dma) & ~0x01f) | Q_TYPE_QH)) /* for periodic/async schedules and qtd lists, mark end of list */ #define EHCI_LIST_END(ehci)cpu_to_hc32(ehci, 1) /* "null pointer" to hw */ -- 2.6.3 -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH resend 7/9] usb: host: ehci.h: remove macros trailing semicolon
Removes trailing semicolon from macros. Caught by checkpatch: "WARNING: macros should not use a trailing semicolon" Signed-off-by: Geyslan G. Bem--- drivers/usb/host/ehci.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/usb/host/ehci.h b/drivers/usb/host/ehci.h index e52a229..3701471 100644 --- a/drivers/usb/host/ehci.h +++ b/drivers/usb/host/ehci.h @@ -635,10 +635,10 @@ struct ehci_tt { /* Prepare the PORTSC wakeup flags during controller suspend/resume */ #define ehci_prepare_ports_for_controller_suspend(ehci, do_wakeup) \ - ehci_adjust_port_wakeup_flags(ehci, true, do_wakeup); + ehci_adjust_port_wakeup_flags(ehci, true, do_wakeup) #define ehci_prepare_ports_for_controller_resume(ehci) \ - ehci_adjust_port_wakeup_flags(ehci, false, false); + ehci_adjust_port_wakeup_flags(ehci, false, false) /*-*/ -- 2.6.3 -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH resend 9/9] usb: host: ehci.h: move constant to right
This patch moves the constant 0x3ff to right and put spaces in the right shift. Caught by coccinelle: scripts/coccinelle/misc/compare_const_fl.cocci Signed-off-by: Geyslan G. Bem--- drivers/usb/host/ehci.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/usb/host/ehci.h b/drivers/usb/host/ehci.h index e974b63..7997b28 100644 --- a/drivers/usb/host/ehci.h +++ b/drivers/usb/host/ehci.h @@ -555,7 +555,7 @@ struct ehci_sitd { __hc32 hw_results; /* EHCI table 3-11 */ #defineSITD_IOC(1 << 31) /* interrupt on completion */ #defineSITD_PAGE (1 << 30) /* buffer 0/1 */ -#defineSITD_LENGTH(x) (0x3ff & ((x)>>16)) +#defineSITD_LENGTH(x) (((x) >> 16) & 0x3ff) #defineSITD_STS_ACTIVE (1 << 7)/* HC may execute this */ #defineSITD_STS_ERR(1 << 6)/* error from TT */ #defineSITD_STS_DBE(1 << 5)/* data buffer error (in HC) */ -- 2.6.3 -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH resend 8/9] usb: host: ehci.h: move pointer operator to name side
The pointer operator must be sticked to name. Caught by checkpatch: ERROR: "foo * bar" should be "foo *bar" Signed-off-by: Geyslan G. Bem--- drivers/usb/host/ehci.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/usb/host/ehci.h b/drivers/usb/host/ehci.h index 3701471..e974b63 100644 --- a/drivers/usb/host/ehci.h +++ b/drivers/usb/host/ehci.h @@ -732,7 +732,7 @@ ehci_port_speed(struct ehci_hcd *ehci, unsigned int portsc) #endif static inline unsigned int ehci_readl(const struct ehci_hcd *ehci, - __u32 __iomem * regs) + __u32 __iomem *regs) { #ifdef CONFIG_USB_EHCI_BIG_ENDIAN_MMIO return ehci_big_endian_mmio(ehci) ? -- 2.6.3 -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH resend 5/9] usb: host: ehci.h: remove direct use of __attribute__ keyword
Prefer to use __aligned(size) macro instead of __attribute__((aligned(size))). Caught by checkpatch. Signed-off-by: Geyslan G. Bem--- drivers/usb/host/ehci.h | 10 +- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/drivers/usb/host/ehci.h b/drivers/usb/host/ehci.h index c86194f..1d2 100644 --- a/drivers/usb/host/ehci.h +++ b/drivers/usb/host/ehci.h @@ -324,7 +324,7 @@ struct ehci_qtd { struct list_headqtd_list; /* sw qtd list */ struct urb *urb; /* qtd's urb */ size_t length; /* length of buffer */ -} __attribute__ ((aligned (32))); +} __aligned(32); /* mask NakCnt+T in qh->hw_alt_next */ #define QTD_MASK(ehci) cpu_to_hc32(ehci, ~0x1f) @@ -407,7 +407,7 @@ struct ehci_qh_hw { __hc32 hw_token; __hc32 hw_buf[5]; __hc32 hw_buf_hi[5]; -} __attribute__ ((aligned(32))); +} __aligned(32); struct ehci_qh { struct ehci_qh_hw *hw;/* Must come first */ @@ -535,7 +535,7 @@ struct ehci_itd { unsignedframe; /* where scheduled */ unsignedpg; unsignedindex[8]; /* in urb->iso_frame_desc */ -} __attribute__ ((aligned (32))); +} __aligned(32); /*-*/ @@ -578,7 +578,7 @@ struct ehci_sitd { struct list_headsitd_list; /* list of stream's sitds */ unsignedframe; unsignedindex; -} __attribute__ ((aligned (32))); +} __aligned(32); /*-*/ @@ -598,7 +598,7 @@ struct ehci_fstn { /* the rest is HCD-private */ dma_addr_t fstn_dma; union ehci_shadow fstn_next; /* ptr to periodic q entry */ -} __attribute__ ((aligned (32))); +} __aligned(32); /*-*/ -- 2.6.3 -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH resend 2/9] usb: host: ehci.h: remove space before function open parenthesis
Get rid of space between function name and open parenthesis. Caught by checkpatch: "WARNING: space prohibited between function name and open parenthesis '('" Signed-off-by: Geyslan G. Bem--- drivers/usb/host/ehci.h | 22 +++--- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/drivers/usb/host/ehci.h b/drivers/usb/host/ehci.h index 6a36ef4..46982df 100644 --- a/drivers/usb/host/ehci.h +++ b/drivers/usb/host/ehci.h @@ -268,13 +268,13 @@ struct ehci_hcd { /* one per controller */ }; /* convert between an HCD pointer and the corresponding EHCI_HCD */ -static inline struct ehci_hcd *hcd_to_ehci (struct usb_hcd *hcd) +static inline struct ehci_hcd *hcd_to_ehci(struct usb_hcd *hcd) { return (struct ehci_hcd *) (hcd->hcd_priv); } -static inline struct usb_hcd *ehci_to_hcd (struct ehci_hcd *ehci) +static inline struct usb_hcd *ehci_to_hcd(struct ehci_hcd *ehci) { - return container_of ((void *) ehci, struct usb_hcd, hcd_priv); + return container_of((void *) ehci, struct usb_hcd, hcd_priv); } /*-*/ @@ -327,9 +327,9 @@ struct ehci_qtd { } __attribute__ ((aligned (32))); /* mask NakCnt+T in qh->hw_alt_next */ -#define QTD_MASK(ehci) cpu_to_hc32 (ehci, ~0x1f) +#define QTD_MASK(ehci) cpu_to_hc32(ehci, ~0x1f) -#define IS_SHORT_READ(token) (QTD_LENGTH (token) != 0 && QTD_PID (token) == 1) +#define IS_SHORT_READ(token) (QTD_LENGTH(token) != 0 && QTD_PID(token) == 1) /*-*/ @@ -806,7 +806,7 @@ static inline void set_ohci_hcfs(struct ehci_hcd *ehci, int operational) #define ehci_big_endian_desc(e)((e)->big_endian_desc) /* cpu to ehci */ -static inline __hc32 cpu_to_hc32 (const struct ehci_hcd *ehci, const u32 x) +static inline __hc32 cpu_to_hc32(const struct ehci_hcd *ehci, const u32 x) { return ehci_big_endian_desc(ehci) ? (__force __hc32)cpu_to_be32(x) @@ -814,14 +814,14 @@ static inline __hc32 cpu_to_hc32 (const struct ehci_hcd *ehci, const u32 x) } /* ehci to cpu */ -static inline u32 hc32_to_cpu (const struct ehci_hcd *ehci, const __hc32 x) +static inline u32 hc32_to_cpu(const struct ehci_hcd *ehci, const __hc32 x) { return ehci_big_endian_desc(ehci) ? be32_to_cpu((__force __be32)x) : le32_to_cpu((__force __le32)x); } -static inline u32 hc32_to_cpup (const struct ehci_hcd *ehci, const __hc32 *x) +static inline u32 hc32_to_cpup(const struct ehci_hcd *ehci, const __hc32 *x) { return ehci_big_endian_desc(ehci) ? be32_to_cpup((__force __be32 *)x) @@ -831,18 +831,18 @@ static inline u32 hc32_to_cpup (const struct ehci_hcd *ehci, const __hc32 *x) #else /* cpu to ehci */ -static inline __hc32 cpu_to_hc32 (const struct ehci_hcd *ehci, const u32 x) +static inline __hc32 cpu_to_hc32(const struct ehci_hcd *ehci, const u32 x) { return cpu_to_le32(x); } /* ehci to cpu */ -static inline u32 hc32_to_cpu (const struct ehci_hcd *ehci, const __hc32 x) +static inline u32 hc32_to_cpu(const struct ehci_hcd *ehci, const __hc32 x) { return le32_to_cpu(x); } -static inline u32 hc32_to_cpup (const struct ehci_hcd *ehci, const __hc32 *x) +static inline u32 hc32_to_cpup(const struct ehci_hcd *ehci, const __hc32 *x) { return le32_to_cpup(x); } -- 2.6.3 -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 4/5] [v2] usb: host: ehci-msm: Fix register initialization
On Thu, Dec 10, 2015 at 06:28:56PM -0600, Timur Tabi wrote: > From: Jack Pham> > The default value for the 'transceiver select' field of > the PORTSC register may not always be correct. Previously > the phy-msm-usb driver would do this for us, but since > ehci-msm can now be instantiated standalone without any PHY > driver, the register needs to be explicitly initialized to > ULPI mode to properly communicate with the PHY. > > This is not readily apparent, as firmware or bootloader code > also happen to pre-initialize this for us. However, it can > manifest when performing a driver unbind/rebind as follows: > > cd /sys/bus/platform/drivers/msm_hsusb_host > echo QCOM8040:00 > unbind > echo QCOM8040:00 > bind > > The EHCI core executes a controller reset as part of this, > and as a result the register in question would revert to > its default state and must be re-initialized properly. > Furthermore this may be useful in the future when adding > PM suspend/resume support. > > Signed-off-by: Jack Pham > Signed-off-by: Timur Tabi Reviewed-by: Andy Gross -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v2] extcon: add Maxim MAX3355 driver
Maxim Integrated MAX3355E chip integrates a charge pump and comparators to enable a system with an integrated USB OTG dual-role transceiver to function as an USB OTG dual-role device. In addition to sensing/controlling Vbus, the chip also passes thru the ID signal from the USB OTG connector. On some Renesas boards, this signal is just fed into the SoC thru a GPIO pin -- there's no real OTG controller, only host and gadget USB controllers sharing the same USB bus; however, we'd like to allow host or gadget drivers to be loaded depending on the cable type, hence the need for the MAX3355 extcon driver. The Vbus status signals are also wired to GPIOs (however, we aren't currently interested in them), the OFFVBUS# signal is controlled by the host controllers, there's also the SHDN# signal wired to a GPIO, it should be driven high for the normal operation. Signed-off-by: Sergei Shtylyov--- The patch is against the 'extcon-next' branch of the 'extcon.git' repo. Changes in version 2: - added the USB gadget cable support; - added the remove() driver method which drives SHDN# GPIO low to save power; - dropped vendor prefix from the ID GPIO property name; - changed the GPIO property name suffix to "-gpios"; - switched to usign extcon_set_cable_state_() API; - switched to using the gpiod/sleeping 'gpiolib' APIs; - addded error messages to max3355_probe(); - added IRQF_NO_SUSPEND flasg to the devm_request_threaded_irq() call; - renamed 'ret' variable to 'err' in max3355_probe(); - expanded the Kconfig entry help text; - added vendor name to the patch summary, the bindings document, the Kconfig entry, the driver heading comment, the module description, and the change log; - fixed up and reformatted the change log. Documentation/devicetree/bindings/extcon/extcon-max3355.txt | 21 + drivers/extcon/Kconfig |8 drivers/extcon/Makefile |1 drivers/extcon/extcon-max3355.c | 153 4 files changed, 183 insertions(+) Index: extcon/Documentation/devicetree/bindings/extcon/extcon-max3355.txt === --- /dev/null +++ extcon/Documentation/devicetree/bindings/extcon/extcon-max3355.txt @@ -0,0 +1,21 @@ +Maxim Integrated MAX3355 USB OTG chip +- + +MAX3355 integrates a charge pump and comparators to enable a system with an +integrated USB OTG dual-role transceiver to function as a USB OTG dual-role +device. + +Required properties: +- compatible: should be "maxim,max3355"; +- maxim,shdn-gpios: should contain a phandle and GPIO specifier for the GPIO pin + connected to the MAX3355's SHDN# pin; +- id-gpios: should contain a phandle and GPIO specifier for the GPIO pin + connected to the MAX3355's ID_OUT pin. + +Example (Koelsch board): + + usb-otg { + compatible = "maxim,max3355"; + maxim,shdn-gpios = < 4 GPIO_ACTIVE_LOW>; + id-gpios = < 31 GPIO_ACTIVE_HIGH>; + }; Index: extcon/drivers/extcon/Kconfig === --- extcon.orig/drivers/extcon/Kconfig +++ extcon/drivers/extcon/Kconfig @@ -52,6 +52,14 @@ config EXTCON_MAX14577 Maxim MAX14577/77836. The MAX14577/77836 MUIC is a USB port accessory detector and switch. +config EXTCON_MAX3355 + tristate "Maxim MAX3355 USB OTG EXTCON Support" + help + If you say yes here you get support for the USB OTG role detection by + MAX3355. The MAX3355 chip integrates a charge pump and comparators to + enable a system with an integrated USB OTG dual-role transceiver to + function as an USB OTG dual-role device. + config EXTCON_MAX77693 tristate "Maxim MAX77693 EXTCON Support" depends on MFD_MAX77693 && INPUT Index: extcon/drivers/extcon/Makefile === --- extcon.orig/drivers/extcon/Makefile +++ extcon/drivers/extcon/Makefile @@ -8,6 +8,7 @@ obj-$(CONFIG_EXTCON_ARIZONA)+= extcon-a obj-$(CONFIG_EXTCON_AXP288)+= extcon-axp288.o obj-$(CONFIG_EXTCON_GPIO) += extcon-gpio.o obj-$(CONFIG_EXTCON_MAX14577) += extcon-max14577.o +obj-$(CONFIG_EXTCON_MAX3355) += extcon-max3355.o obj-$(CONFIG_EXTCON_MAX77693) += extcon-max77693.o obj-$(CONFIG_EXTCON_MAX77843) += extcon-max77843.o obj-$(CONFIG_EXTCON_MAX8997) += extcon-max8997.o Index: extcon/drivers/extcon/extcon-max3355.c === --- /dev/null +++ extcon/drivers/extcon/extcon-max3355.c @@ -0,0 +1,153 @@ +/* + * Maxim Integrated MAX3355 USB OTG chip extcon driver + * + * Copyright (C) 2014 Cogent Embedded, Inc. + * Author: Sergei Shtylyov + * + * This software is licensed under the terms of the GNU General Public
[PATCH resend 3/9] usb: host: ehci.h: remove space before open square bracket
Get rid of space before open square bracket. Caught by checkpatch: "ERROR: space prohibited before open square bracket '['" Signed-off-by: Geyslan G. Bem--- drivers/usb/host/ehci.h | 20 ++-- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/drivers/usb/host/ehci.h b/drivers/usb/host/ehci.h index 46982df..cfeebd8 100644 --- a/drivers/usb/host/ehci.h +++ b/drivers/usb/host/ehci.h @@ -185,7 +185,7 @@ struct ehci_hcd { /* one per controller */ struct ehci_sitd*last_sitd_to_free; /* per root hub port */ - unsigned long reset_done [EHCI_MAX_ROOT_PORTS]; + unsigned long reset_done[EHCI_MAX_ROOT_PORTS]; /* bit vectors (one bit per port) */ unsigned long bus_suspended; /* which ports were @@ -316,8 +316,8 @@ struct ehci_qtd { #define HALT_BIT(ehci) cpu_to_hc32(ehci, QTD_STS_HALT) #define STATUS_BIT(ehci) cpu_to_hc32(ehci, QTD_STS_STS) - __hc32 hw_buf [5];/* see EHCI 3.5.4 */ - __hc32 hw_buf_hi [5];/* Appendix B */ + __hc32 hw_buf[5];/* see EHCI 3.5.4 */ + __hc32 hw_buf_hi[5];/* Appendix B */ /* the rest is HCD-private */ dma_addr_t qtd_dma;/* qtd address */ @@ -405,8 +405,8 @@ struct ehci_qh_hw { __hc32 hw_qtd_next; __hc32 hw_alt_next; __hc32 hw_token; - __hc32 hw_buf [5]; - __hc32 hw_buf_hi [5]; + __hc32 hw_buf[5]; + __hc32 hw_buf_hi[5]; } __attribute__ ((aligned(32))); struct ehci_qh { @@ -510,7 +510,7 @@ struct ehci_iso_stream { struct ehci_itd { /* first part defined by EHCI spec */ __hc32 hw_next; /* see EHCI 3.3.1 */ - __hc32 hw_transaction [8]; /* see EHCI 3.3.2 */ + __hc32 hw_transaction[8]; /* see EHCI 3.3.2 */ #define EHCI_ISOC_ACTIVE(1<<31)/* activate transfer this slot */ #define EHCI_ISOC_BUF_ERR (1<<30)/* Data buffer error */ #define EHCI_ISOC_BABBLE(1<<29)/* babble detected */ @@ -520,8 +520,8 @@ struct ehci_itd { #define ITD_ACTIVE(ehci) cpu_to_hc32(ehci, EHCI_ISOC_ACTIVE) - __hc32 hw_bufp [7];/* see EHCI 3.3.3 */ - __hc32 hw_bufp_hi [7]; /* Appendix B */ + __hc32 hw_bufp[7]; /* see EHCI 3.3.3 */ + __hc32 hw_bufp_hi[7]; /* Appendix B */ /* the rest is HCD-private */ dma_addr_t itd_dma;/* for this itd */ @@ -565,9 +565,9 @@ struct ehci_sitd { #define SITD_ACTIVE(ehci) cpu_to_hc32(ehci, SITD_STS_ACTIVE) - __hc32 hw_buf [2]; /* EHCI table 3-12 */ + __hc32 hw_buf[2]; /* EHCI table 3-12 */ __hc32 hw_backpointer; /* EHCI table 3-13 */ - __hc32 hw_buf_hi [2]; /* Appendix B */ + __hc32 hw_buf_hi[2]; /* Appendix B */ /* the rest is HCD-private */ dma_addr_t sitd_dma; -- 2.6.3 -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH resend 4/9] usb: host: ehci.h: fix single statement macros
Don't use the 'do {} while (0)' wrapper in a single statement macro. Caught by checkpatch: "WARNING: Single statement macros should not use a do {} while (0) loop" Signed-off-by: Geyslan G. Bem--- drivers/usb/host/ehci.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/usb/host/ehci.h b/drivers/usb/host/ehci.h index cfeebd8..c86194f 100644 --- a/drivers/usb/host/ehci.h +++ b/drivers/usb/host/ehci.h @@ -244,9 +244,9 @@ struct ehci_hcd { /* one per controller */ /* irq statistics */ #ifdef EHCI_STATS struct ehci_stats stats; -# define COUNT(x) do { (x)++; } while (0) +# define COUNT(x) ((x)++) #else -# define COUNT(x) do {} while (0) +# define COUNT(x) #endif /* debug files */ -- 2.6.3 -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH resend 1/9] usb: host: ehci.h: remove space before comma
Get rid of spaces before comma. Caught by checkpatch: "ERROR: space prohibited before that ','" Signed-off-by: Geyslan G. Bem--- drivers/usb/host/ehci.h | 8 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/usb/host/ehci.h b/drivers/usb/host/ehci.h index ec61aed..6a36ef4 100644 --- a/drivers/usb/host/ehci.h +++ b/drivers/usb/host/ehci.h @@ -852,13 +852,13 @@ static inline u32 hc32_to_cpup (const struct ehci_hcd *ehci, const __hc32 *x) /*-*/ #define ehci_dbg(ehci, fmt, args...) \ - dev_dbg(ehci_to_hcd(ehci)->self.controller , fmt , ## args) + dev_dbg(ehci_to_hcd(ehci)->self.controller, fmt, ## args) #define ehci_err(ehci, fmt, args...) \ - dev_err(ehci_to_hcd(ehci)->self.controller , fmt , ## args) + dev_err(ehci_to_hcd(ehci)->self.controller, fmt, ## args) #define ehci_info(ehci, fmt, args...) \ - dev_info(ehci_to_hcd(ehci)->self.controller , fmt , ## args) + dev_info(ehci_to_hcd(ehci)->self.controller, fmt, ## args) #define ehci_warn(ehci, fmt, args...) \ - dev_warn(ehci_to_hcd(ehci)->self.controller , fmt , ## args) + dev_warn(ehci_to_hcd(ehci)->self.controller, fmt, ## args) #ifndef CONFIG_DYNAMIC_DEBUG -- 2.6.3 -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH resend 0/9] usb: host: ehci.h cleanup
This cleanup was done with the help of checkpatch and coccinelle tools. Geyslan G. Bem (9): usb: host: ehci.h: remove space before comma usb: host: ehci.h: remove space before function open parenthesis usb: host: ehci.h: remove space before open square bracket usb: host: ehci.h: fix single statement macros usb: host: ehci.h: remove direct use of __attribute__ keyword usb: host: ehci.h: use space after comma usb: host: ehci.h: remove macros trailing semicolon usb: host: ehci.h: move pointer operator to name side usb: host: ehci.h: move constant to right drivers/usb/host/ehci.h | 77 + 1 file changed, 39 insertions(+), 38 deletions(-) -- 2.6.3 -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 5/5] [v2] usb: host: ehci-msm: Register usb shutdown function
On Thu, Dec 10, 2015 at 06:28:57PM -0600, Timur Tabi wrote: > From: Azriel Samson> > Registering usb_hcd_platform_shutdown to be called during > shutdown. This is a generic function that performs the > generic host stack's shutdown. It ensures that USB > operations do not continue while kexec boots a new kernel. > > Signed-off-by: Azriel Samson > Signed-off-by: Timur Tabi Reviewed-by: Andy Gross -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH v3 4/9] usb: host: ehci.h: fix single statement macros
2015-12-11 17:55 GMT-03:00 Geyslan G. Bem: > 2015-12-11 13:30 GMT-03:00 Greg Kroah-Hartman : >> On Thu, Dec 10, 2015 at 03:18:19PM -0300, Geyslan G. Bem wrote: >>> Don't use the 'do {} while (0)' wrapper in a single statement macro. >>> >>> Caught by checkpatch: "WARNING: Single statement macros should not >>> use a do {} while (0) loop" >>> >>> Signed-off-by: Geyslan G. Bem >>> --- >>> Change in v3: >>> - There's no need to evaluate COUNT(x) in #ifdef EHCI_STATS >>>false branch. Thus an empty #define is the choice. >> >> Odd numbering scheme of patches, I can't figure this out... > Greg, > > I sent new versions only to modified ones. > 9 is v1. > 4 is v3. > rest is v2. > > Next time I'll send new versions for all. > >> >> Can you resend this whole series so I know I got it all correct? > I hope so. :-) Messing around with branches and merges here. I tell you soon. Greg, please, grab them. [PATCH resend 0/9] usb: host: ehci.h cleanup > >> >> thanks, >> >> greg k-h > > > > -- > Regards, > > Geyslan G. Bem > hackingbits.com -- Regards, Geyslan G. Bem hackingbits.com -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 3/5] [v2] usb: host: ehci-msm: Add support for ACPI probing
On Thu, Dec 10, 2015 at 06:28:55PM -0600, Timur Tabi wrote: > From: Jack Pham> > Allow the EHCI MSM driver to probe against an ACPI enumerated > device with ID QCOM8040. > > Signed-off-by: Jack Pham > Signed-off-by: Timur Tabi Reviewed-by: Andy Gross -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 2/5] [v2] usb: host: ehci-msm: Remove dependency on OTG PHY
On Thu, Dec 10, 2015 at 06:28:54PM -0600, Timur Tabi wrote: > From: Jack Pham> > Currently the EHCI MSM driver has a hard dependency to be created > by an OTG layer, namely the phy-msm-usb driver. In some cases or > board configurations we want to allow the EHCI host to be > instantiated without OTG capability. Instead, relax the dependency > on having an OTG PHY being present and call usb_add_hcd() directly. > > Signed-off-by: Jack Pham > Signed-off-by: Timur Tabi Reviewed-by: Andy Gross -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 1/1] USB: inode.c: fix unbalanced spin_lock in ep0_write
On Fri, Dec 11, 2015 at 9:11 PM, Al Virowrote: > > On Fri, Dec 11, 2015 at 08:56:26PM +0100, David Eccher wrote: > > Fix bad unlock balance: ep0_write enter with the locks locked from > > inode.c:1769, > > hence it must exit with spinlock held to avoid double unlock in dev_config. > > *Ugh* > > Just take that spinlock before the if (retval < 0) and don't drop it after > clear_req(), then... Oh, yeah good point, I'll send a v2...and test the patch thru checkpatch.pl, sorry -- David Eccher -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v2 1/1] USB: inode.c: fix unbalanced spin_lock in ep0_write
Fix bad unlock balance: ep0_write enter with the locks locked from inode.c:1769, hence it must exit with spinlock held to avoid double unlock in dev_config. Signed-off-by: David Eccher--- drivers/usb/gadget/legacy/inode.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/usb/gadget/legacy/inode.c b/drivers/usb/gadget/legacy/inode.c index f454c7a..365afd7 100644 --- a/drivers/usb/gadget/legacy/inode.c +++ b/drivers/usb/gadget/legacy/inode.c @@ -1137,10 +1137,9 @@ ep0_write (struct file *fd, const char __user *buf, size_t len, loff_t *ptr) dev->gadget->ep0, dev->req, GFP_KERNEL); } + spin_lock_irq(>lock); if (retval < 0) { - spin_lock_irq (>lock); clean_req (dev->gadget->ep0, dev->req); - spin_unlock_irq (>lock); } else retval = len; -- 1.8.1.2 -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[linux-usb-users] g_serial is not working in rx path (K3.14)
Hi We are trying to enable g_serial in Intel platform and facing issue with RX path. stable kernel version: K3.14 configuration enabled: USB_G_SERIAL testing details: writing from device side(ttyS0) to Windows Host(com 11-g_serial): working fine from ttyS0: echo test > /dev/ttyGS0 -- received in comm 11 Typing any character from windows host pc(com 11 using teraterm) to device side: not working from ttyS0: cat /dev/ttyGS0 issue details: In Device side(ttyS0): cat /dev/ttyGS0 In Windows Host PC (Com 11 -- g_serial - using teraterm) -- typing enter or any character is not sending bytes most of the time but sometimes typing character(e.g a) is sending the bytes and received in device side(cat /dev/ttyGS0) as per below log. logs added in u_serial: [ 94.912072] gs_write: ttyGS0 (a2471c00) writing 1 bytes -- not working case [ 94.916679] ttyGS0: tx len=1, 0x73 0x6c 0xa7 ... [ 94.921279] RAM: g_write_comp [ 95.006267] gs_rx_push:n 0 [ 95.007649] ttyGS0: rx block 1/1 do_push:1 [ 95.011831] gs_start_rx [ 95.015112] gs_write: ttyGS0 (a2471c00) writing 1 bytes [ 95.019591] ttyGS0: tx len=1, 0x64 0x6c 0xa7 ... [ 95.024496] RAM: g_write_comp [ 95.119200] gs_rx_push:n 0 [ 95.120618] ttyGS0: rx block 1/1 do_push:1 [ 95.124853] gs_start_rx a[ 95.190935] gs_rx_push:n 0 -- working case [ 95.192360] ttyGS0: rx block 1/1 do_push:1 [ 95.196500] gs_start_rx s[ 95.298273] gs_rx_push:n 0 [ 95.299678] ttyGS0: rx block 1/1 do_push:1 [ 95.303900] gs_start_rx we are observing "gs_rx_push" tasklet is triggered at every time if we press the character or by pressing enter key and the "do_push" flag is set. Kernel Log: pr_vdebug(PREFIX "%d: rx block %d/%d\n", port->port_num, count, req->actual); relative debug log with do_push print: ttyGS0: rx block 1/1 do_push:1 Please help on the same. Regards, Ramajayam S -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html