RE: [PATCH 2/2] usb: dwc2: gadget reuse ahbcfg assigned from platform
-Original Message- From: Zhangfei Gao [mailto:zhangfei@linaro.org] Sent: Thursday, February 5, 2015 3:22 AM To: Kaukab, Yousaf Cc: ba...@ti.com; john.y...@synopsys.com; linux-usb@vger.kernel.org Subject: Re: [PATCH 2/2] usb: dwc2: gadget reuse ahbcfg assigned from platform Hi Yousaf On 4 February 2015 at 17:41, Kaukab, Yousaf yousaf.kau...@intel.com wrote: diff --git a/drivers/usb/dwc2/core.c b/drivers/usb/dwc2/core.c index d5197d4..8d388cc 100644 --- a/drivers/usb/dwc2/core.c +++ b/drivers/usb/dwc2/core.c @@ -2563,7 +2563,7 @@ void dwc2_set_param_reload_ctl(struct dwc2_hsotg *hsotg, int val) void dwc2_set_param_ahbcfg(struct dwc2_hsotg *hsotg, int val) { - if (val != -1) + if (val) hsotg-core_params-ahbcfg = val; else hsotg-core_params-ahbcfg = GAHBCFG_HBSTLEN_INCR4 diff --git a/drivers/usb/dwc2/gadget.c b/drivers/usb/dwc2/gadget.c index 15aa578..20085de 100644 --- a/drivers/usb/dwc2/gadget.c +++ b/drivers/usb/dwc2/gadget.c @@ -2314,9 +2314,13 @@ void s3c_hsotg_core_init_disconnected(struct dwc2_hsotg *hsotg, GINTSTS_USBSUSP | GINTSTS_WKUPINT, hsotg-regs + GINTMSK); + if ((hsotg-core_params) (hsotg-core_params-ahbcfg != - 1)) + val = hsotg-core_params-ahbcfg ~GAHBCFG_CTRL_MASK; + else + val = GAHBCFG_HBSTLEN_INCR4 GAHBCFG_HBSTLEN_SHIFT; + if (using_dma(hsotg)) - writel(GAHBCFG_GLBL_INTR_EN | GAHBCFG_DMA_EN | -(GAHBCFG_HBSTLEN_INCR4 GAHBCFG_HBSTLEN_SHIFT), + writel(GAHBCFG_GLBL_INTR_EN | GAHBCFG_DMA_EN | val, hsotg-regs + GAHBCFG); else writel(((hsotg-dedicated_fifos) ? (GAHBCFG_NP_TXF_EMP_LVL | There are other bits in GAHBCFG that can be set from platform. They will be preserved by your patch, as they are not part of GAHBCFG_CTRL_MASK, but only in case dma is enabled. Perhaps preserve them in non-dma case as well. Here may have issue if also set hsotg-core_params-ahbcfg for non-dma case, since GAHBCFG[4:1] may be set. You can mask off HBstLen in that case. However, I don't think setting burst length will be an issue in non DMA case as DWC2 will not act as a bus master. John, can you please confirm if setting burst length will be an issue in non-dma case? Though from drivers/usb/dwc2/core.h we can not see @ahbcfg is specifically used for dma case, most case in drivers/usb/dwc2/platform.c use ahbcfg is set hbstlen, GAHBCFG[4:1]. For example, our platform set GAHBCFG_HBSTLEN_INCR16. So I just assume @ahbcfg is used for dma case. What do you think. While you are fixing it, why not fix it for other bits, for example AHBSingle, InvDescEndianness etc., which are part of the same register and will be overwritten at the same place. Thanks BR, Yousaf
Re: [PATCH 2/2] usb: dwc2: gadget reuse ahbcfg assigned from platform
On 2/6/2015 6:02 AM, Zhangfei Gao wrote: On 6 February 2015 at 16:07, Kaukab, Yousaf yousaf.kau...@intel.com wrote: GAHBCFG_HBSTLEN_INCR4 diff --git a/drivers/usb/dwc2/gadget.c b/drivers/usb/dwc2/gadget.c index 15aa578..20085de 100644 --- a/drivers/usb/dwc2/gadget.c +++ b/drivers/usb/dwc2/gadget.c @@ -2314,9 +2314,13 @@ void s3c_hsotg_core_init_disconnected(struct dwc2_hsotg *hsotg, GINTSTS_USBSUSP | GINTSTS_WKUPINT, hsotg-regs + GINTMSK); + if ((hsotg-core_params) (hsotg-core_params-ahbcfg != - 1)) + val = hsotg-core_params-ahbcfg ~GAHBCFG_CTRL_MASK; + else + val = GAHBCFG_HBSTLEN_INCR4 GAHBCFG_HBSTLEN_SHIFT; + if (using_dma(hsotg)) - writel(GAHBCFG_GLBL_INTR_EN | GAHBCFG_DMA_EN | -(GAHBCFG_HBSTLEN_INCR4 GAHBCFG_HBSTLEN_SHIFT), + writel(GAHBCFG_GLBL_INTR_EN | GAHBCFG_DMA_EN | val, hsotg-regs + GAHBCFG); else writel(((hsotg-dedicated_fifos) ? (GAHBCFG_NP_TXF_EMP_LVL | There are other bits in GAHBCFG that can be set from platform. They will be preserved by your patch, as they are not part of GAHBCFG_CTRL_MASK, but only in case dma is enabled. Perhaps preserve them in non-dma case as well. Here may have issue if also set hsotg-core_params-ahbcfg for non-dma case, since GAHBCFG[4:1] may be set. You can mask off HBstLen in that case. However, I don't think setting burst length will be an issue in non DMA case as DWC2 will not act as a bus master. John, can you please confirm if setting burst length will be an issue in non-dma case? I don't think it hurts to preserve those bits, but I will check. diff --git a/drivers/usb/dwc2/core.c b/drivers/usb/dwc2/core.c index d5197d4..8d388cc 100644 --- a/drivers/usb/dwc2/core.c +++ b/drivers/usb/dwc2/core.c @@ -2563,7 +2563,7 @@ void dwc2_set_param_reload_ctl(struct dwc2_hsotg *hsotg, int val) void dwc2_set_param_ahbcfg(struct dwc2_hsotg *hsotg, int val) { - if (val != -1) + if (val) hsotg-core_params-ahbcfg = val; else hsotg-core_params-ahbcfg = Doesn't this already takes care of setting a default value if unset? So you can leave this unchanged and just use the value in gadget.c without any further checking. Regards, John -- 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 6/6] gadget: switch ep_io_operations to -read_iter/-write_iter
From: Al Viro v...@zeniv.linux.org.uk Signed-off-by: Al Viro v...@zeniv.linux.org.uk --- drivers/usb/gadget/legacy/inode.c | 355 +++--- 1 file changed, 141 insertions(+), 214 deletions(-) diff --git a/drivers/usb/gadget/legacy/inode.c b/drivers/usb/gadget/legacy/inode.c index 9fbbaa0..b825edc 100644 --- a/drivers/usb/gadget/legacy/inode.c +++ b/drivers/usb/gadget/legacy/inode.c @@ -363,97 +363,6 @@ ep_io (struct ep_data *epdata, void *buf, unsigned len) return value; } - -/* handle a synchronous OUT bulk/intr/iso transfer */ -static ssize_t -ep_read (struct file *fd, char __user *buf, size_t len, loff_t *ptr) -{ - struct ep_data *data = fd-private_data; - void*kbuf; - ssize_t value; - - if ((value = get_ready_ep (fd-f_flags, data)) 0) - return value; - - /* halt any endpoint by doing a wrong direction i/o call */ - if (usb_endpoint_dir_in(data-desc)) { - if (usb_endpoint_xfer_isoc(data-desc)) { - mutex_unlock(data-lock); - return -EINVAL; - } - DBG (data-dev, %s halt\n, data-name); - spin_lock_irq (data-dev-lock); - if (likely (data-ep != NULL)) - usb_ep_set_halt (data-ep); - spin_unlock_irq (data-dev-lock); - mutex_unlock(data-lock); - return -EBADMSG; - } - - /* FIXME readahead for O_NONBLOCK and poll(); careful with ZLPs */ - - value = -ENOMEM; - kbuf = kmalloc (len, GFP_KERNEL); - if (unlikely (!kbuf)) - goto free1; - - value = ep_io (data, kbuf, len); - VDEBUG (data-dev, %s read %zu OUT, status %d\n, - data-name, len, (int) value); - if (value = 0 copy_to_user (buf, kbuf, value)) - value = -EFAULT; - -free1: - mutex_unlock(data-lock); - kfree (kbuf); - return value; -} - -/* handle a synchronous IN bulk/intr/iso transfer */ -static ssize_t -ep_write (struct file *fd, const char __user *buf, size_t len, loff_t *ptr) -{ - struct ep_data *data = fd-private_data; - void*kbuf; - ssize_t value; - - if ((value = get_ready_ep (fd-f_flags, data)) 0) - return value; - - /* halt any endpoint by doing a wrong direction i/o call */ - if (!usb_endpoint_dir_in(data-desc)) { - if (usb_endpoint_xfer_isoc(data-desc)) { - mutex_unlock(data-lock); - return -EINVAL; - } - DBG (data-dev, %s halt\n, data-name); - spin_lock_irq (data-dev-lock); - if (likely (data-ep != NULL)) - usb_ep_set_halt (data-ep); - spin_unlock_irq (data-dev-lock); - mutex_unlock(data-lock); - return -EBADMSG; - } - - /* FIXME writebehind for O_NONBLOCK and poll(), qlen = 1 */ - - value = -ENOMEM; - kbuf = memdup_user(buf, len); - if (IS_ERR(kbuf)) { - value = PTR_ERR(kbuf); - kbuf = NULL; - goto free1; - } - - value = ep_io (data, kbuf, len); - VDEBUG (data-dev, %s write %zu IN, status %d\n, - data-name, len, (int) value); -free1: - mutex_unlock(data-lock); - kfree (kbuf); - return value; -} - static int ep_release (struct inode *inode, struct file *fd) { @@ -517,8 +426,8 @@ struct kiocb_priv { struct mm_struct*mm; struct work_struct work; void*buf; - const struct iovec *iv; - unsigned long nr_segs; + struct iov_iter to; + const void *to_free; unsignedactual; }; @@ -541,34 +450,6 @@ static int ep_aio_cancel(struct kiocb *iocb) return value; } -static ssize_t ep_copy_to_user(struct kiocb_priv *priv) -{ - ssize_t len, total; - void*to_copy; - int i; - - /* copy stuff into user buffers */ - total = priv-actual; - len = 0; - to_copy = priv-buf; - for (i=0; i priv-nr_segs; i++) { - ssize_t this = min((ssize_t)(priv-iv[i].iov_len), total); - - if (copy_to_user(priv-iv[i].iov_base, to_copy, this)) { - if (len == 0) - len = -EFAULT; - break; - } - - total -= this; - len += this; - to_copy += this; - if (total == 0) - break; - } - return len; -} - static void ep_user_copy_worker(struct work_struct *work) { struct kiocb_priv *priv = container_of(work, struct kiocb_priv, work);
[PATCH 2/6] gadget/function/f_fs.c: close leaks
From: Al Viro v...@zeniv.linux.org.uk If ffs_epfile_io() fails in AIO case, we end up leaking io_data (and iovec_copy in case of AIO read). Signed-off-by: Al Viro v...@zeniv.linux.org.uk --- drivers/usb/gadget/function/f_fs.c | 14 -- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/drivers/usb/gadget/function/f_fs.c b/drivers/usb/gadget/function/f_fs.c index 63314ed..0c120ad 100644 --- a/drivers/usb/gadget/function/f_fs.c +++ b/drivers/usb/gadget/function/f_fs.c @@ -962,6 +962,7 @@ static ssize_t ffs_epfile_aio_write(struct kiocb *kiocb, unsigned long nr_segs, loff_t loff) { struct ffs_io_data *io_data; + ssize_t res; ENTER(); @@ -981,7 +982,10 @@ static ssize_t ffs_epfile_aio_write(struct kiocb *kiocb, kiocb_set_cancel_fn(kiocb, ffs_aio_cancel); - return ffs_epfile_io(kiocb-ki_filp, io_data); + res = ffs_epfile_io(kiocb-ki_filp, io_data); + if (res != -EIOCBQUEUED) + kfree(io_data); + return res; } static ssize_t ffs_epfile_aio_read(struct kiocb *kiocb, @@ -990,6 +994,7 @@ static ssize_t ffs_epfile_aio_read(struct kiocb *kiocb, { struct ffs_io_data *io_data; struct iovec *iovec_copy; + ssize_t res; ENTER(); @@ -1017,7 +1022,12 @@ static ssize_t ffs_epfile_aio_read(struct kiocb *kiocb, kiocb_set_cancel_fn(kiocb, ffs_aio_cancel); - return ffs_epfile_io(kiocb-ki_filp, io_data); + res = ffs_epfile_io(kiocb-ki_filp, io_data); + if (res != -EIOCBQUEUED) { + kfree(io_data); + kfree(iovec_copy); + } + return res; } static int -- 2.1.4 -- 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 4/6] gadget/function/f_fs.c: switch to -{read,write}_iter()
From: Al Viro v...@zeniv.linux.org.uk Signed-off-by: Al Viro v...@zeniv.linux.org.uk --- drivers/usb/gadget/function/f_fs.c | 136 - 1 file changed, 58 insertions(+), 78 deletions(-) diff --git a/drivers/usb/gadget/function/f_fs.c b/drivers/usb/gadget/function/f_fs.c index 11704e7..04c6542 100644 --- a/drivers/usb/gadget/function/f_fs.c +++ b/drivers/usb/gadget/function/f_fs.c @@ -856,38 +856,6 @@ error: return ret; } -static ssize_t -ffs_epfile_write(struct file *file, const char __user *buf, size_t len, -loff_t *ptr) -{ - struct ffs_io_data io_data; - struct iovec iov = {.iov_base = buf, .iov_len = len}; - - ENTER(); - - io_data.aio = false; - io_data.read = false; - iov_iter_init(io_data.data, WRITE, iov, 1, len); - - return ffs_epfile_io(file, io_data); -} - -static ssize_t -ffs_epfile_read(struct file *file, char __user *buf, size_t len, loff_t *ptr) -{ - struct ffs_io_data io_data; - struct iovec iov = {.iov_base = buf, .iov_len = len}; - - ENTER(); - - io_data.aio = false; - io_data.read = true; - io_data.to_free = NULL; - iov_iter_init(io_data.data, READ, iov, 1, len); - - return ffs_epfile_io(file, io_data); -} - static int ffs_epfile_open(struct inode *inode, struct file *file) { @@ -924,72 +892,84 @@ static int ffs_aio_cancel(struct kiocb *kiocb) return value; } -static ssize_t ffs_epfile_aio_write(struct kiocb *kiocb, - const struct iovec *iovec, - unsigned long nr_segs, loff_t loff) +static ssize_t ffs_epfile_write_iter(struct kiocb *kiocb, struct iov_iter *from) { - struct ffs_io_data *io_data; + struct ffs_io_data io_data, *p = io_data; ssize_t res; ENTER(); - io_data = kmalloc(sizeof(*io_data), GFP_KERNEL); - if (unlikely(!io_data)) - return -ENOMEM; + if (!is_sync_kiocb(kiocb)) { + p = kmalloc(sizeof(io_data), GFP_KERNEL); + if (unlikely(!p)) + return -ENOMEM; + p-aio = true; + } else { + p-aio = false; + } - io_data-aio = true; - io_data-read = false; - io_data-kiocb = kiocb; - iov_iter_init(io_data-data, WRITE, iovec, nr_segs, kiocb-ki_nbytes); - io_data-mm = current-mm; + p-read = false; + p-kiocb = kiocb; + p-data = *from; + p-mm = current-mm; - kiocb-private = io_data; + kiocb-private = p; kiocb_set_cancel_fn(kiocb, ffs_aio_cancel); - res = ffs_epfile_io(kiocb-ki_filp, io_data); - if (res != -EIOCBQUEUED) - kfree(io_data); + res = ffs_epfile_io(kiocb-ki_filp, p); + if (res == -EIOCBQUEUED) + return res; + if (p-aio) + kfree(p); + else + *from = p-data; return res; } -static ssize_t ffs_epfile_aio_read(struct kiocb *kiocb, - const struct iovec *iovec, - unsigned long nr_segs, loff_t loff) +static ssize_t ffs_epfile_read_iter(struct kiocb *kiocb, struct iov_iter *to) { - struct ffs_io_data *io_data; - struct iovec *iovec_copy; + struct ffs_io_data io_data, *p = io_data; ssize_t res; ENTER(); - iovec_copy = kmalloc_array(nr_segs, sizeof(*iovec_copy), GFP_KERNEL); - if (unlikely(!iovec_copy)) - return -ENOMEM; - - memcpy(iovec_copy, iovec, sizeof(struct iovec)*nr_segs); - - io_data = kmalloc(sizeof(*io_data), GFP_KERNEL); - if (unlikely(!io_data)) { - kfree(iovec_copy); - return -ENOMEM; + if (!is_sync_kiocb(kiocb)) { + p = kmalloc(sizeof(io_data), GFP_KERNEL); + if (unlikely(!p)) + return -ENOMEM; + p-aio = true; + } else { + p-aio = false; } - io_data-aio = true; - io_data-read = true; - io_data-kiocb = kiocb; - io_data-to_free = iovec_copy; - iov_iter_init(io_data-data, READ, iovec_copy, nr_segs, kiocb-ki_nbytes); - io_data-mm = current-mm; + p-read = true; + p-kiocb = kiocb; + if (p-aio) { + p-to_free = dup_iter(p-data, to, GFP_KERNEL); + if (!p-to_free) { + kfree(p); + return -ENOMEM; + } + } else { + p-data = *to; + p-to_free = NULL; + } + p-mm = current-mm; - kiocb-private = io_data; + kiocb-private = p; kiocb_set_cancel_fn(kiocb, ffs_aio_cancel); - res = ffs_epfile_io(kiocb-ki_filp, io_data); - if (res != -EIOCBQUEUED) { - kfree(io_data-to_free); - kfree(io_data); + res =
[PATCH 3/6] gadget/function/f_fs.c: use put iov_iter into io_data
From: Al Viro v...@zeniv.linux.org.uk both on aio and non-aio sides Signed-off-by: Al Viro v...@zeniv.linux.org.uk --- drivers/usb/gadget/function/f_fs.c | 86 +++--- 1 file changed, 25 insertions(+), 61 deletions(-) diff --git a/drivers/usb/gadget/function/f_fs.c b/drivers/usb/gadget/function/f_fs.c index 0c120ad..11704e7 100644 --- a/drivers/usb/gadget/function/f_fs.c +++ b/drivers/usb/gadget/function/f_fs.c @@ -143,10 +143,9 @@ struct ffs_io_data { bool read; struct kiocb *kiocb; - const struct iovec *iovec; - unsigned long nr_segs; - char __user *buf; - size_t len; + struct iov_iter data; + const void *to_free; + char *buf; struct mm_struct *mm; struct work_struct work; @@ -645,29 +644,10 @@ static void ffs_user_copy_worker(struct work_struct *work) io_data-req-actual; if (io_data-read ret 0) { - int i; - size_t pos = 0; - - /* -* Since req-length may be bigger than io_data-len (after -* being rounded up to maxpacketsize), we may end up with more -* data then user space has space for. -*/ - ret = min_t(int, ret, io_data-len); - use_mm(io_data-mm); - for (i = 0; i io_data-nr_segs; i++) { - size_t len = min_t(size_t, ret - pos, - io_data-iovec[i].iov_len); - if (!len) - break; - if (unlikely(copy_to_user(io_data-iovec[i].iov_base, -io_data-buf[pos], len))) { - ret = -EFAULT; - break; - } - pos += len; - } + ret = copy_to_iter(io_data-buf, ret, io_data-data); + if (iov_iter_count(io_data-data)) + ret = -EFAULT; unuse_mm(io_data-mm); } @@ -677,7 +657,7 @@ static void ffs_user_copy_worker(struct work_struct *work) io_data-kiocb-private = NULL; if (io_data-read) - kfree(io_data-iovec); + kfree(io_data-to_free); kfree(io_data-buf); kfree(io_data); } @@ -736,6 +716,7 @@ static ssize_t ffs_epfile_io(struct file *file, struct ffs_io_data *io_data) * before the waiting completes, so do not assign to 'gadget' earlier */ struct usb_gadget *gadget = epfile-ffs-gadget; + size_t copied; spin_lock_irq(epfile-ffs-eps_lock); /* In the meantime, endpoint got disabled or changed. */ @@ -743,34 +724,21 @@ static ssize_t ffs_epfile_io(struct file *file, struct ffs_io_data *io_data) spin_unlock_irq(epfile-ffs-eps_lock); return -ESHUTDOWN; } + data_len = iov_iter_count(io_data-data); /* * Controller may require buffer size to be aligned to * maxpacketsize of an out endpoint. */ - data_len = io_data-read ? - usb_ep_align_maybe(gadget, ep-ep, io_data-len) : - io_data-len; + if (io_data-read) + data_len = usb_ep_align_maybe(gadget, ep-ep, data_len); spin_unlock_irq(epfile-ffs-eps_lock); data = kmalloc(data_len, GFP_KERNEL); if (unlikely(!data)) return -ENOMEM; - if (io_data-aio !io_data-read) { - int i; - size_t pos = 0; - for (i = 0; i io_data-nr_segs; i++) { - if (unlikely(copy_from_user(data[pos], -io_data-iovec[i].iov_base, -io_data-iovec[i].iov_len))) { - ret = -EFAULT; - goto error; - } - pos += io_data-iovec[i].iov_len; - } - } else { - if (!io_data-read - unlikely(__copy_from_user(data, io_data-buf, - io_data-len))) { + if (!io_data-read) { + copied = copy_from_iter(data, data_len, io_data-data); + if (copied != data_len) { ret = -EFAULT; goto error; } @@ -868,10 +836,8 @@ static ssize_t ffs_epfile_io(struct file *file, struct ffs_io_data *io_data)
[PATCH 5/6] gadgetfs: use-after-free in -aio_read()
From: Al Viro v...@zeniv.linux.org.uk AIO_PREAD requests call -aio_read() with iovec on caller's stack, so if we are going to access it asynchronously, we'd better get ourselves a copy - the one on kernel stack of aio_run_iocb() won't be there anymore. function/f_fs.c take care of doing that, legacy/inode.c doesn't... Cc: sta...@vger.kernel.org Signed-off-by: Al Viro v...@zeniv.linux.org.uk --- drivers/usb/gadget/legacy/inode.c | 15 --- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/drivers/usb/gadget/legacy/inode.c b/drivers/usb/gadget/legacy/inode.c index db49ec4..9fbbaa0 100644 --- a/drivers/usb/gadget/legacy/inode.c +++ b/drivers/usb/gadget/legacy/inode.c @@ -566,7 +566,6 @@ static ssize_t ep_copy_to_user(struct kiocb_priv *priv) if (total == 0) break; } - return len; } @@ -585,6 +584,7 @@ static void ep_user_copy_worker(struct work_struct *work) aio_complete(iocb, ret, ret); kfree(priv-buf); + kfree(priv-iv); kfree(priv); } @@ -605,6 +605,7 @@ static void ep_aio_complete(struct usb_ep *ep, struct usb_request *req) */ if (priv-iv == NULL || unlikely(req-actual == 0)) { kfree(req-buf); + kfree(priv-iv); kfree(priv); iocb-private = NULL; /* aio_complete() reports bytes-transferred _and_ faults */ @@ -640,7 +641,7 @@ ep_aio_rwtail( struct usb_request *req; ssize_t value; - priv = kmalloc(sizeof *priv, GFP_KERNEL); + priv = kzalloc(sizeof *priv, GFP_KERNEL); if (!priv) { value = -ENOMEM; fail: @@ -649,7 +650,14 @@ fail: } iocb-private = priv; priv-iocb = iocb; - priv-iv = iv; + if (iv) { + priv-iv = kmemdup(iv, nr_segs * sizeof(struct iovec), + GFP_KERNEL); + if (!priv-iv) { + kfree(priv); + goto fail; + } + } priv-nr_segs = nr_segs; INIT_WORK(priv-work, ep_user_copy_worker); @@ -689,6 +697,7 @@ fail: mutex_unlock(epdata-lock); if (unlikely(value)) { + kfree(priv-iv); kfree(priv); put_ep(epdata); } else -- 2.1.4 -- 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 4/4] usb: phy: add phy-hi6220-usb
Add usb phy controller for hi6220 platform Signed-off-by: Zhangfei Gao zhangfei@linaro.org --- drivers/usb/phy/Kconfig | 9 ++ drivers/usb/phy/Makefile | 1 + drivers/usb/phy/phy-hi6220-usb.c | 297 +++ 3 files changed, 307 insertions(+) create mode 100644 drivers/usb/phy/phy-hi6220-usb.c diff --git a/drivers/usb/phy/Kconfig b/drivers/usb/phy/Kconfig index c6d0c8e..405a3d0 100644 --- a/drivers/usb/phy/Kconfig +++ b/drivers/usb/phy/Kconfig @@ -173,6 +173,15 @@ config USB_MXS_PHY MXS Phy is used by some of the i.MX SoCs, for example imx23/28/6x. +config USB_HI6220_PHY + tristate hi6220 USB PHY support + select USB_PHY + select MFD_SYSCON + help + Enable this to support the HISILICON HI6220 USB PHY. + + To compile this driver as a module, choose M here. + config USB_RCAR_PHY tristate Renesas R-Car USB PHY support depends on USB || USB_GADGET diff --git a/drivers/usb/phy/Makefile b/drivers/usb/phy/Makefile index 75f2bba..00172d3 100644 --- a/drivers/usb/phy/Makefile +++ b/drivers/usb/phy/Makefile @@ -18,6 +18,7 @@ obj-$(CONFIG_SAMSUNG_USBPHY) += phy-samsung-usb.o obj-$(CONFIG_TWL6030_USB) += phy-twl6030-usb.o obj-$(CONFIG_USB_EHCI_TEGRA) += phy-tegra-usb.o obj-$(CONFIG_USB_GPIO_VBUS)+= phy-gpio-vbus-usb.o +obj-$(CONFIG_USB_HI6220_PHY) += phy-hi6220-usb.o obj-$(CONFIG_USB_ISP1301) += phy-isp1301.o obj-$(CONFIG_USB_MSM_OTG) += phy-msm-usb.o obj-$(CONFIG_USB_MV_OTG) += phy-mv-usb.o diff --git a/drivers/usb/phy/phy-hi6220-usb.c b/drivers/usb/phy/phy-hi6220-usb.c new file mode 100644 index 000..8092bca --- /dev/null +++ b/drivers/usb/phy/phy-hi6220-usb.c @@ -0,0 +1,297 @@ +/* + * Copyright (c) 2015 Linaro Ltd. + * Copyright (c) 2015 Hisilicon Limited. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + */ + +#include linux/clk.h +#include linux/mfd/syscon.h +#include linux/of_gpio.h +#include linux/platform_device.h +#include linux/regmap.h +#include linux/regulator/consumer.h +#include linux/usb/gadget.h +#include linux/usb/otg.h + +#define SC_PERIPH_CTRL40x00c + +#define CTRL4_PICO_SIDDQ BIT(6) +#define CTRL4_PICO_OGDISABLE BIT(8) +#define CTRL4_PICO_VBUSVLDEXT BIT(10) +#define CTRL4_PICO_VBUSVLDEXTSEL BIT(11) +#define CTRL4_OTG_PHY_SEL BIT(21) + +#define SC_PERIPH_CTRL50x010 + +#define CTRL5_USBOTG_RES_SEL BIT(3) +#define CTRL5_PICOPHY_ACAENB BIT(4) +#define CTRL5_PICOPHY_BC_MODE BIT(5) +#define CTRL5_PICOPHY_CHRGSEL BIT(6) +#define CTRL5_PICOPHY_VDATSRCEND BIT(7) +#define CTRL5_PICOPHY_VDATDETENB BIT(8) +#define CTRL5_PICOPHY_DCDENB BIT(9) +#define CTRL5_PICOPHY_IDDIGBIT(10) + +#define SC_PERIPH_CTRL80x018 +#define SC_PERIPH_RSTEN0 0x300 +#define SC_PERIPH_RSTDIS0 0x304 + +#define RST0_USBOTG_BUSBIT(4) +#define RST0_POR_PICOPHY BIT(5) +#define RST0_USBOTGBIT(6) +#define RST0_USBOTG_32KBIT(7) + +#define EYE_PATTERN_PARA 0x7053348c + +struct hi6220_priv { + struct usb_phy phy; + struct delayed_work work; + struct regmap *reg; + struct clk *clk; + struct regulator *vcc; + int gpio_vbus; + int gpio_id; + enum usb_otg_state state; +}; + +static void hi6220_start_periphrals(struct hi6220_priv *priv, bool on) +{ + struct usb_otg *otg = priv-phy.otg; + + if (!otg-gadget) + return; + + if (on) + usb_gadget_connect(otg-gadget); + else + usb_gadget_disconnect(otg-gadget); +} + +static void hi6220_detect_work(struct work_struct *work) +{ + struct hi6220_priv *priv = + container_of(work, struct hi6220_priv, work.work); + int gpio_id, gpio_vubs; + enum usb_otg_state state; + + if (!gpio_is_valid(priv-gpio_id) || !gpio_is_valid(priv-gpio_vbus)) + return; + + gpio_id = gpio_get_value_cansleep(priv-gpio_id); + gpio_vubs = gpio_get_value_cansleep(priv-gpio_vbus); + + if (gpio_vubs == 0) { + if (gpio_id == 1) + state = OTG_STATE_B_PERIPHERAL; + else + state = OTG_STATE_A_HOST; + } else { + state = OTG_STATE_A_HOST; + } + + if (priv-state != state) { + hi6220_start_periphrals(priv, state == OTG_STATE_B_PERIPHERAL); + priv-state = state; + } +} + +static
[PATCH v2 2/4] Documentation: dt-bindings: add dt binding info for hi6220
Signed-off-by: Zhangfei Gao zhangfei@linaro.org --- .../devicetree/bindings/usb/hi6220-usb.txt | 49 ++ 1 file changed, 49 insertions(+) create mode 100644 Documentation/devicetree/bindings/usb/hi6220-usb.txt diff --git a/Documentation/devicetree/bindings/usb/hi6220-usb.txt b/Documentation/devicetree/bindings/usb/hi6220-usb.txt new file mode 100644 index 000..b8278de --- /dev/null +++ b/Documentation/devicetree/bindings/usb/hi6220-usb.txt @@ -0,0 +1,49 @@ +Hisilicon hi6220 SoC USB controller +- + +usb controller is inherited from dwc2, refer dwc2.txt +- + +Required properties: +- compatible: hisilicon,hi6220-usb +Refer to dwc2.txt for dwc2 usb properties + + +PHY: +- + +Required properties: +- compatible: hisilicon,hi6220-usb-phy +- vcc-supply: phandle to the regulator that provides power to the PHY. +- clocks: phandle and clock specifier of the PHY clock. +- hisilicon,peripheral-syscon: phandle of syscon used to control peripheral. +- hisilicon,gpio-vbus: gpio of detecting vbus. +- hisilicon,gpio-id: gpio of detecting id. + +Example: + + peripheral_ctrl: syscon@f703 { + compatible = syscon; + reg = 0x0 0xf703 0x0 0x1000; + }; + + usb2_phy: usbphy { + compatible = hisilicon,hi6220-usb-phy; + vcc-supply = fixed_5v_hub; + hisilicon,gpio-vbus = gpio2 6 0; + hisilicon,gpio-id = gpio2 5 0; + hisilicon,peripheral-syscon = peripheral_ctrl; + clocks = clock_sys HI6220_USBOTG_HCLK; + }; + + usb: usb@f72c { + compatible = hisilicon,hi6220-usb; + reg = 0x0 0xf72c 0x0 0x4; + phys = usb2_phy; + dr_mode = otg; + g-use-dma; + g-rx-fifo-size = 512; + g-np-tx-fifo-size = 128; + g-tx-fifo-size = 128; + interrupts = 0 77 0x4; + }; -- 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 0/4] add usb support for hi6220
v2: address comments from Sergei and Peter add hi6220_phy_setup(false) code v1: hi6220 usb controller is inherited from dwc2 add phy accordingly support otg gadget/host Zhangfei Gao (4): Documentation: dt-bindings: add dt binding info for hi6220 dwc2 Documentation: dt-bindings: add dt binding info for hi6220 usb: dwc2: platform: add hi6220 support usb: phy: add phy-hi6220-usb Documentation/devicetree/bindings/usb/dwc2.txt | 1 + .../devicetree/bindings/usb/hi6220-usb.txt | 49 drivers/usb/dwc2/platform.c| 30 +++ drivers/usb/phy/Kconfig| 9 + drivers/usb/phy/Makefile | 1 + drivers/usb/phy/phy-hi6220-usb.c | 297 + 6 files changed, 387 insertions(+) create mode 100644 Documentation/devicetree/bindings/usb/hi6220-usb.txt create mode 100644 drivers/usb/phy/phy-hi6220-usb.c -- 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 1/4] Documentation: dt-bindings: add dt binding info for hi6220 dwc2
Add necessary dwc2 binding documentation for Hisilicon soc: hi6220 Signed-off-by: Zhangfei Gao zhangfei@linaro.org --- Documentation/devicetree/bindings/usb/dwc2.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/Documentation/devicetree/bindings/usb/dwc2.txt b/Documentation/devicetree/bindings/usb/dwc2.txt index fd132cb..2213682 100644 --- a/Documentation/devicetree/bindings/usb/dwc2.txt +++ b/Documentation/devicetree/bindings/usb/dwc2.txt @@ -4,6 +4,7 @@ Platform DesignWare HS OTG USB 2.0 controller Required properties: - compatible : One of: - brcm,bcm2835-usb: The DWC2 USB controller instance in the BCM2835 SoC. + - hisilicon,hi6220-usb: The DWC2 USB controller instance in the hi6220 SoC. - rockchip,rk3066-usb: The DWC2 USB controller instance in the rk3066 Soc; - rockchip,rk3188-usb, rockchip,rk3066-usb, snps,dwc2: for rk3188 Soc; - rockchip,rk3288-usb, rockchip,rk3066-usb, snps,dwc2: for rk3288 Soc; -- 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 3/4] usb: dwc2: platform: add hi6220 support
Signed-off-by: Zhangfei Gao zhangfei@linaro.org --- drivers/usb/dwc2/platform.c | 30 ++ 1 file changed, 30 insertions(+) diff --git a/drivers/usb/dwc2/platform.c b/drivers/usb/dwc2/platform.c index ae095f0..f7c67db 100644 --- a/drivers/usb/dwc2/platform.c +++ b/drivers/usb/dwc2/platform.c @@ -50,6 +50,35 @@ static const char dwc2_driver_name[] = dwc2; +static const struct dwc2_core_params params_hi6220 = { + .otg_cap= 2,/* No HNP/SRP capable */ + .otg_ver= 0,/* 1.3 */ + .dma_enable = 1, + .dma_desc_enable= 0, + .speed = 0,/* High Speed */ + .enable_dynamic_fifo= 1, + .en_multiple_tx_fifo= 1, + .host_rx_fifo_size = 512, + .host_nperio_tx_fifo_size = 512, + .host_perio_tx_fifo_size= 512, + .max_transfer_size = 65535, + .max_packet_count = 511, + .host_channels = 16, + .phy_type = 1,/* UTMI */ + .phy_utmi_width = 8, + .phy_ulpi_ddr = 0,/* Single */ + .phy_ulpi_ext_vbus = 0, + .i2c_enable = 0, + .ulpi_fs_ls = 0, + .host_support_fs_ls_low_power = 0, + .host_ls_low_power_phy_clk = 0,/* 48 MHz */ + .ts_dline = 0, + .reload_ctl = 0, + .ahbcfg = GAHBCFG_HBSTLEN_INCR16 + GAHBCFG_HBSTLEN_SHIFT, + .uframe_sched = 0, +}; + static const struct dwc2_core_params params_bcm2835 = { .otg_cap= 0,/* HNP/SRP capable */ .otg_ver= 0,/* 1.3 */ @@ -129,6 +158,7 @@ static int dwc2_driver_remove(struct platform_device *dev) static const struct of_device_id dwc2_of_match_table[] = { { .compatible = brcm,bcm2835-usb, .data = params_bcm2835 }, + { .compatible = hisilicon,hi6220-usb, .data = params_hi6220 }, { .compatible = rockchip,rk3066-usb, .data = params_rk3066 }, { .compatible = snps,dwc2, .data = NULL }, { .compatible = samsung,s3c6400-hsotg, .data = NULL}, -- 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
Re: [PATCH 3/5] fs: remove ki_nbytes
On Thu, Feb 05, 2015 at 10:29:42AM -0500, Alan Stern wrote: On Wed, 4 Feb 2015, Al Viro wrote: Um... readv() is also going through -aio_read(). Why does readv() do this but not read()? Wouldn't it make more sense to have all the read* calls use the same internal interface? Because there are two partially overlapping classes wrt vector IO semantics: ... Thanks for the detailed explanation. It appears to boil down to a series of historical accidents. In any case, feel free to copy the non-isochronous behavior of the synchronous routines in the async routines. It certainly won't hurt anything. OK, I've limited it to sync ones, actually. Preliminary series in followups. Those who prefer to read in git, see git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs.git #gadget WARNING: completely untested Al Viro (6): new helper: dup_iter() gadget/function/f_fs.c: close leaks gadget/function/f_fs.c: use put iov_iter into io_data gadget/function/f_fs.c: switch to -{read,write}_iter() gadgetfs: use-after-free in -aio_read() gadget: switch ep_io_operations to -read_iter/-write_iter drivers/usb/gadget/function/f_fs.c | 204 +- drivers/usb/gadget/legacy/inode.c | 346 +++-- include/linux/uio.h| 2 + mm/iov_iter.c | 15 ++ 4 files changed, 237 insertions(+), 330 deletions(-) -- 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 V5 8/8] USB: f81232: modify/add author
Add me to co-author and fix no '' in greg kh's email Signed-off-by: Peter Hung hpeter+linux_ker...@gmail.com --- drivers/usb/serial/f81232.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/usb/serial/f81232.c b/drivers/usb/serial/f81232.c index 07abf0c..8799b66 100644 --- a/drivers/usb/serial/f81232.c +++ b/drivers/usb/serial/f81232.c @@ -608,5 +608,6 @@ static struct usb_serial_driver * const serial_drivers[] = { module_usb_serial_driver(serial_drivers, id_table); MODULE_DESCRIPTION(Fintek F81232 USB to serial adaptor driver); -MODULE_AUTHOR(Greg Kroah-Hartman gre...@linuxfoundation.org); +MODULE_AUTHOR(Greg Kroah-Hartman gre...@linuxfoundation.org); +MODULE_AUTHOR(Peter Hong peter_h...@fintek.com.tw); MODULE_LICENSE(GPL v2); -- 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
Re: [PATCH 4/4] usb: phy: add phy-hi6220
On 6 February 2015 at 16:41, Peter Chen peter.c...@freescale.com wrote: On Thu, Feb 05, 2015 at 10:47:00PM +0800, Zhangfei Gao wrote: @@ -18,6 +18,7 @@ obj-$(CONFIG_SAMSUNG_USBPHY)+= phy-samsung-usb.o obj-$(CONFIG_TWL6030_USB)+= phy-twl6030-usb.o obj-$(CONFIG_USB_EHCI_TEGRA) += phy-tegra-usb.o obj-$(CONFIG_USB_GPIO_VBUS) += phy-gpio-vbus-usb.o +obj-$(CONFIG_USB_HI6220_PHY) += phy-hi6220.o To align the naming method, phy-hi6220-usb is better. Sure, +enum usb_mode { + USB_EMPTY, + GADGET_DEVICE, + OTG_HOST, +}; This usb_mode is a little strange, what state you would like to use? it is internal state machine, to distinguish otg gadget mode and host mode. There are two gpio, we use gpio_vbus interrupt as well as gpio_id status to distinguish gadget or host. +static irqreturn_t hiusb_gpio_intr(int irq, void *data) +{ + struct hi6220_priv *priv = (struct hi6220_priv *)data; + + /* add debounce time */ + schedule_delayed_work(priv-work, msecs_to_jiffies(100)); + return IRQ_HANDLED; +} + +static int mv_otg_set_peripheral(struct usb_otg *otg, mv? You may want to use hi Yes, my bad. +static void hi6220_phy_setup(struct hi6220_priv *priv) +{ + u32 val, mask; + int ret; + + if (priv-reg == NULL) + return; + + val = PERIPH_RSTDIS0_USBOTG_BUS | PERIPH_RSTDIS0_POR_PICOPHY | + PERIPH_RSTDIS0_USBOTG | PERIPH_RSTDIS0_USBOTG_32K; + mask = val; + ret = regmap_update_bits(priv-reg, SC_PERIPH_RSTDIS0, mask, val); + if (ret) + return; + + ret = regmap_read(priv-reg, SC_PERIPH_CTRL5, val); + val = PERIPH_CTRL5_USBOTG_RES_SEL | PERIPH_CTRL5_PICOPHY_ACAENB; + mask = val | PERIPH_CTRL5_PICOPHY_BC_MODE; + ret = regmap_update_bits(priv-reg, SC_PERIPH_CTRL5, mask, val); + if (ret) + return; + + val = PERIPH_CTRL4_PICO_VBUSVLDEXT | PERIPH_CTRL4_PICO_VBUSVLDEXTSEL | +PERIPH_CTRL4_OTG_PHY_SEL; + mask = val | PERIPH_CTRL4_PICO_SIDDQ | PERIPH_CTRL4_PICO_OGDISABLE; + ret = regmap_update_bits(priv-reg, SC_PERIPH_CTRL4, mask, val); + if (ret) + return; + + ret = regmap_write(priv-reg, SC_PERIPH_CTRL8, EYE_PATTERN_PARA); + if (ret) + return; +} + +static int hi6220_phy_probe(struct platform_device *pdev) +{ + struct hi6220_priv *priv; + struct usb_otg *otg; + struct device_node *np = pdev-dev.of_node; + int ret, irq; + + priv = devm_kzalloc(pdev-dev, sizeof(*priv), GFP_KERNEL); + if (!priv) + return -ENOMEM; + + otg = devm_kzalloc(pdev-dev, sizeof(*otg), GFP_KERNEL); + if (!otg) + return -ENOMEM; + + priv-phy.dev = pdev-dev; + priv-phy.otg = otg; + priv-phy.label = hi6220; + platform_set_drvdata(pdev, priv); + otg-set_peripheral = mv_otg_set_peripheral; + + priv-gpio_vbus_det = of_get_named_gpio(np, hisilicon,gpio_vbus_det, 0); + if (priv-gpio_vbus_det == -EPROBE_DEFER) + return -EPROBE_DEFER; + if (!gpio_is_valid(priv-gpio_vbus_det)) { + dev_err(pdev-dev, invalid gpio %d\n, priv-gpio_vbus_det); + return -ENODEV; + } + + priv-gpio_id_det = of_get_named_gpio(np, hisilicon,gpio_id_det, 0); + if (priv-gpio_id_det == -EPROBE_DEFER) + return -EPROBE_DEFER; + if (!gpio_is_valid(priv-gpio_id_det)) { + dev_err(pdev-dev, invalid gpio %d\n, priv-gpio_id_det); + return -ENODEV; + } + + priv-reg = syscon_regmap_lookup_by_phandle(pdev-dev.of_node, + hisilicon,peripheral-syscon); + if (IS_ERR(priv-reg)) + priv-reg = NULL; You may differentiate -ENODEV and other errors, for other errors, you can show an error, and return directly. Here I want to set this property as optional, in case other platform do not need this property. So phy_setup also add protection if (priv-reg == NULL) return; + + INIT_DELAYED_WORK(priv-work, hi6220_detect_work); + + ret = devm_gpio_request_one(pdev-dev, priv-gpio_vbus_det, + GPIOF_IN, gpio_vbus_det); + if (ret 0) { + dev_err(pdev-dev, gpio request failed for gpio_vbus_det\n); + return ret; + } + + ret = devm_gpio_request_one(pdev-dev, priv-gpio_id_det, + GPIOF_IN, gpio_id_det); + if (ret 0) { + dev_err(pdev-dev, gpio request failed for gpio_id_det\n); + return ret; + } + + priv-vcc = devm_regulator_get(pdev-dev, vcc); + if (!IS_ERR(priv-vcc)) { + ret = regulator_enable(priv-vcc); + if (ret) { + dev_err(pdev-dev, Failed to enable regulator\n); + return -ENODEV; + } + } + + priv-clk =
[PATCH V5 6/8] USB: f81232: clarify f81232_ioctl()
We extract TIOCGSERIAL section in f81232_ioctl() to f81232_get_serial_info() to make it clarify The f81232_set_mctrl() replace set_control_lines() to do MCR control so we clean-up the set_control_lines() function. Signed-off-by: Peter Hung hpeter+linux_ker...@gmail.com --- drivers/usb/serial/f81232.c | 34 +++--- 1 file changed, 23 insertions(+), 11 deletions(-) diff --git a/drivers/usb/serial/f81232.c b/drivers/usb/serial/f81232.c index e1cdf42..4dddb44 100644 --- a/drivers/usb/serial/f81232.c +++ b/drivers/usb/serial/f81232.c @@ -516,24 +516,36 @@ static int f81232_carrier_raised(struct usb_serial_port *port) return 0; } +static int f81232_get_serial_info(struct usb_serial_port *port, + unsigned long arg) +{ + struct serial_struct ser; + + memset(ser, 0, sizeof(ser)); + + ser.flags = ASYNC_SKIP_TEST | ASYNC_AUTO_IRQ; + ser.xmit_fifo_size = port-bulk_out_size; + ser.close_delay = 5 * HZ; + ser.closing_wait= 30 * HZ; + ser.type = PORT_16550A; + ser.line = port-minor; + ser.port = port-port_number; + ser.baud_base = 115200; + + if (copy_to_user((void __user *)arg, ser, sizeof(ser))) + return -EFAULT; + + return 0; +} + static int f81232_ioctl(struct tty_struct *tty, unsigned int cmd, unsigned long arg) { - struct serial_struct ser; struct usb_serial_port *port = tty-driver_data; switch (cmd) { case TIOCGSERIAL: - memset(ser, 0, sizeof ser); - ser.type = PORT_16654; - ser.line = port-minor; - ser.port = port-port_number; - ser.baud_base = 460800; - - if (copy_to_user((void __user *)arg, ser, sizeof ser)) - return -EFAULT; - - return 0; + return f81232_get_serial_info(port, arg); default: break; } -- 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] USB: legotower: use msecs_to_jiffies for time conversion
This is only an API consolidation and should make things more readable it replaces var * HZ / 1000 by msecs_to_jiffies(var). Signed-off-by: Nicholas Mc Guire hof...@osadl.org --- Patch was only compile tested with x86_64_defconfig + CONFIG_USB_LEGOTOWER=m Patch is against 3.19.0-rc7 (localversion-next is -next-20150204) drivers/usb/misc/legousbtower.c |6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/usb/misc/legousbtower.c b/drivers/usb/misc/legousbtower.c index 97cd9e2..7771be3 100644 --- a/drivers/usb/misc/legousbtower.c +++ b/drivers/usb/misc/legousbtower.c @@ -574,7 +574,7 @@ static ssize_t tower_read (struct file *file, char __user *buffer, size_t count, } if (read_timeout) { - timeout = jiffies + read_timeout * HZ / 1000; + timeout = jiffies + msecs_to_jiffies(read_timeout); } /* wait for data */ @@ -592,7 +592,7 @@ static ssize_t tower_read (struct file *file, char __user *buffer, size_t count, /* reset read timeout during read or write activity */ if (read_timeout (dev-read_buffer_length || dev-interrupt_out_busy)) { - timeout = jiffies + read_timeout * HZ / 1000; + timeout = jiffies + msecs_to_jiffies(read_timeout); } /* check for read timeout */ if (read_timeout time_after (jiffies, timeout)) { @@ -831,7 +831,7 @@ static int tower_probe (struct usb_interface *interface, const struct usb_device dev-read_buffer_length = 0; dev-read_packet_length = 0; spin_lock_init (dev-read_buffer_lock); - dev-packet_timeout_jiffies = packet_timeout * HZ / 1000; + dev-packet_timeout_jiffies = msecs_to_jiffies(packet_timeout); dev-read_last_arrival = jiffies; init_waitqueue_head (dev-read_wait); -- 1.7.10.4 -- 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] fs: remove ki_nbytes
On 02/06/2015 08:03 AM, Al Viro wrote: On Thu, Feb 05, 2015 at 10:29:42AM -0500, Alan Stern wrote: On Wed, 4 Feb 2015, Al Viro wrote: Um... readv() is also going through -aio_read(). Why does readv() do this but not read()? Wouldn't it make more sense to have all the read* calls use the same internal interface? Because there are two partially overlapping classes wrt vector IO semantics: ... Thanks for the detailed explanation. It appears to boil down to a series of historical accidents. In any case, feel free to copy the non-isochronous behavior of the synchronous routines in the async routines. It certainly won't hurt anything. Hmm... What happens if f_fs.c successfully queues struct usb_request, returns -EIOCBQUEUED and then gets hit by io_cancel(2)? AFAICS, you get ffs_aio_cancel() called, which dequeues usb_request and buggers off. The thing is, freeing io_data and stuff hanging off it would be done by ffs_user_copy_worker(), which would be scheduled via schedule_work() by ffs_epfile_async_io_complete(), i.e. usb_request -complete() callback. And usb_ep_dequeue() (aka. ep-ops-dequeue()) has tons of instances, but AFAICS some of them might not trigger usb_gadget_giveback_request(), which would normally call -complete()... Example: net2272_dequeue(struct usb_ep *_ep, struct usb_request *_req) { struct net2272_ep *ep; struct net2272_request *req; unsigned long flags; int stopped; ep = container_of(_ep, struct net2272_ep, ep); if (!_ep || (!ep-desc ep-num != 0) || !_req) return -EINVAL; spin_lock_irqsave(ep-dev-lock, flags); stopped = ep-stopped; ep-stopped = 1; /* make sure it's still queued on this endpoint */ list_for_each_entry(req, ep-queue, queue) { if (req-req == _req) break; } if (req-req != _req) { spin_unlock_irqrestore(ep-dev-lock, flags); return -EINVAL; } /* queue head may be partially complete */ if (ep-queue.next == req-queue) { dev_dbg(ep-dev-dev, unlink (%s) pio\n, _ep-name); net2272_done(ep, req, -ECONNRESET); } req = NULL; ep-stopped = stopped; spin_unlock_irqrestore(ep-dev-lock, flags); return 0; } Note that net2272_done(), which would call usb_gadget_giveback_request(), is only called if the victim happens to be queue head. Is that just a net2272.c bug, or am I missing something subtle here? Looks like at least on that hardware io_cancel() could leak io_data and everything that hangs off it... FWIW, net2272.c was the first one I looked at (happened to be on the last line of screen during git grep for \.dequeue in drivers/usb/gadget ;-) and after checking several more it seems that it's a Sod's Law in action - I'd checked about 5 of them and they seem to call usb_gadget_giveback_request() as long as they find the sucker in queue, head or no head. OTOH, there's a lot more of those guys, so that observation is not worth much... IOW, is that a net2272.c bug, or a f_fs.c one? AFAIK usb request should be completed in all cases, and many gadget drivers make assumptions that complete() of each request will be called, so it's definitely bug in net2272 driver. Robert Baldyga -- 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] USB: image: use msecs_to_jiffies for time conversion
This is only an API consolidation and should make things more readable it replaces var * HZ / 1000 by msecs_to_jiffies(var). Signed-off-by: Nicholas Mc Guire hof...@osadl.org --- Note that the indentation is not aligned with the correct ( here due to lines going over 80 char - not sure if this is the right way to resolve this (this file has quite a few coding style issues). Patch was only compile tested with x86_64_defconfig + CONFIG_USB_MDC800=m Patch is against 3.19.0-rc7 (localversion-next is -next-20150204) drivers/usb/image/mdc800.c | 11 +++ 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/drivers/usb/image/mdc800.c b/drivers/usb/image/mdc800.c index a62865a..3a72e8f 100644 --- a/drivers/usb/image/mdc800.c +++ b/drivers/usb/image/mdc800.c @@ -347,7 +347,8 @@ static int mdc800_usb_waitForIRQ (int mode, int msec) { mdc800-camera_request_ready=1+mode; - wait_event_timeout(mdc800-irq_wait, mdc800-irq_woken, msec*HZ/1000); + wait_event_timeout(mdc800-irq_wait, mdc800-irq_woken, + msecs_to_jiffies(msec)); mdc800-irq_woken = 0; if (mdc800-camera_request_ready0) @@ -743,8 +744,9 @@ static ssize_t mdc800_device_read (struct file *file, char __user *buf, size_t l mutex_unlock(mdc800-io_lock); return len-left; } - wait_event_timeout(mdc800-download_wait, mdc800-downloaded, - TO_DOWNLOAD_GET_READY*HZ/1000); + wait_event_timeout(mdc800-download_wait, +mdc800-downloaded, +msecs_to_jiffies(TO_DOWNLOAD_GET_READY)); mdc800-downloaded = 0; if (mdc800-download_urb-status != 0) { @@ -867,7 +869,8 @@ static ssize_t mdc800_device_write (struct file *file, const char __user *buf, s mutex_unlock(mdc800-io_lock); return -EIO; } - wait_event_timeout(mdc800-write_wait, mdc800-written, TO_WRITE_GET_READY*HZ/1000); + wait_event_timeout(mdc800-write_wait, mdc800-written, + msecs_to_jiffies(TO_WRITE_GET_READY)); mdc800-written = 0; if (mdc800-state == WORKING) { -- 1.7.10.4 -- 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
[RFC PATCH 2/2] usb: dwc3: Add chained TRB support for ep0
dwc3 can do only max packet aligned transfers. So in case request length is not max packet aligned and is bigger than DWC3_EP0_BOUNCE_SIZE two chained TRBs is required to handle the transfer. Signed-off-by: Kishon Vijay Abraham I kis...@ti.com --- *) Did eumeration testing with g_zero in kernel *) Similar patch was added in u-boot. With DFU, was able to create a scenario where the request length is not max packet aligned and is bigger than DWC3_EP0_BOUNCE_SIZE (512 bytes). In that case, 2 chained TRBs will be used. drivers/usb/dwc3/ep0.c| 65 + drivers/usb/dwc3/gadget.c |2 +- 2 files changed, 49 insertions(+), 18 deletions(-) diff --git a/drivers/usb/dwc3/ep0.c b/drivers/usb/dwc3/ep0.c index 24b7925..3b728b8 100644 --- a/drivers/usb/dwc3/ep0.c +++ b/drivers/usb/dwc3/ep0.c @@ -56,7 +56,7 @@ static const char *dwc3_ep0_state_string(enum dwc3_ep0_state state) } static int dwc3_ep0_start_trans(struct dwc3 *dwc, u8 epnum, dma_addr_t buf_dma, - u32 len, u32 type) + u32 len, u32 type, unsigned chain) { struct dwc3_gadget_ep_cmd_params params; struct dwc3_trb *trb; @@ -70,7 +70,10 @@ static int dwc3_ep0_start_trans(struct dwc3 *dwc, u8 epnum, dma_addr_t buf_dma, return 0; } - trb = dwc-ep0_trb; + trb = dwc-ep0_trb[dep-free_slot]; + + if (chain) + dep-free_slot++; trb-bpl = lower_32_bits(buf_dma); trb-bph = upper_32_bits(buf_dma); @@ -78,10 +81,17 @@ static int dwc3_ep0_start_trans(struct dwc3 *dwc, u8 epnum, dma_addr_t buf_dma, trb-ctrl = type; trb-ctrl |= (DWC3_TRB_CTRL_HWO - | DWC3_TRB_CTRL_LST - | DWC3_TRB_CTRL_IOC | DWC3_TRB_CTRL_ISP_IMI); + if (chain) + trb-ctrl |= DWC3_TRB_CTRL_CHN; + else + trb-ctrl |= (DWC3_TRB_CTRL_IOC + | DWC3_TRB_CTRL_LST); + + if (chain) + return 0; + memset(params, 0, sizeof(params)); params.param0 = upper_32_bits(dwc-ep0_trb_addr); params.param1 = lower_32_bits(dwc-ep0_trb_addr); @@ -302,7 +312,7 @@ void dwc3_ep0_out_start(struct dwc3 *dwc) int ret; ret = dwc3_ep0_start_trans(dwc, 0, dwc-ctrl_req_addr, 8, - DWC3_TRBCTL_CONTROL_SETUP); + DWC3_TRBCTL_CONTROL_SETUP, false); WARN_ON(ret 0); } @@ -817,6 +827,22 @@ static void dwc3_ep0_complete_data(struct dwc3 *dwc, maxp = ep0-endpoint.maxpacket; + /* Handle the first TRB before handling the bounce buffer if the request +* length is greater than the bounce buffer size +*/ + if (!IS_ALIGNED(ur-length, maxp) + ur-length DWC3_EP0_BOUNCE_SIZE) { + transfer_size = (ur-length / maxp) * maxp; + transferred = transfer_size - length; + buf = (u8 *)buf + transferred; + ur-actual += transferred; + + trb++; + length = trb-size DWC3_TRB_SIZE_MASK; + + ep0-free_slot = 0; + } + if (dwc-ep0_bounced) { transfer_size = roundup((ur-length - transfer_size), maxp); @@ -844,7 +870,7 @@ static void dwc3_ep0_complete_data(struct dwc3 *dwc, ret = dwc3_ep0_start_trans(dwc, epnum, dwc-ctrl_req_addr, 0, - DWC3_TRBCTL_CONTROL_DATA); + DWC3_TRBCTL_CONTROL_DATA, false); WARN_ON(ret 0); } } @@ -928,7 +954,7 @@ static void __dwc3_ep0_do_control_data(struct dwc3 *dwc, if (req-request.length == 0) { ret = dwc3_ep0_start_trans(dwc, dep-number, dwc-ctrl_req_addr, 0, - DWC3_TRBCTL_CONTROL_DATA); + DWC3_TRBCTL_CONTROL_DATA, false); } else if (!IS_ALIGNED(req-request.length, dep-endpoint.maxpacket) (dep-number == 0)) { u32 transfer_size = 0; @@ -941,22 +967,26 @@ static void __dwc3_ep0_do_control_data(struct dwc3 *dwc, return; } - WARN_ON(req-request.length DWC3_EP0_BOUNCE_SIZE); - maxpacket = dep-endpoint.maxpacket; + + if (req-request.length DWC3_EP0_BOUNCE_SIZE) { + transfer_size = (req-request.length / maxpacket) * + maxpacket; + ret = dwc3_ep0_start_trans(dwc, dep-number, + req-request.dma, + transfer_size, +
[PATCH V5 3/8] USB: f81232: implement RX bulk-in ep
The F81232 bulk-in is RX data + LSR channel, data format is [LSR+Data][LSR+Data]. , We had reimplemented in this patch. Signed-off-by: Peter Hung hpeter+linux_ker...@gmail.com --- drivers/usb/serial/f81232.c | 68 +++-- 1 file changed, 35 insertions(+), 33 deletions(-) diff --git a/drivers/usb/serial/f81232.c b/drivers/usb/serial/f81232.c index ec4609d..9ea498a 100644 --- a/drivers/usb/serial/f81232.c +++ b/drivers/usb/serial/f81232.c @@ -185,44 +185,46 @@ exit: static void f81232_process_read_urb(struct urb *urb) { struct usb_serial_port *port = urb-context; - struct f81232_private *priv = usb_get_serial_port_data(port); unsigned char *data = urb-transfer_buffer; - char tty_flag = TTY_NORMAL; - unsigned long flags; - u8 line_status; + char tty_flag; int i; - /* update line status */ - spin_lock_irqsave(priv-lock, flags); - line_status = priv-modem_status; - priv-modem_status = ~UART_STATE_TRANSIENT_MASK; - spin_unlock_irqrestore(priv-lock, flags); - - if (!urb-actual_length) + if (urb-actual_length 2) return; - /* break takes precedence over parity, */ - /* which takes precedence over framing errors */ - if (line_status UART_BREAK_ERROR) - tty_flag = TTY_BREAK; - else if (line_status UART_PARITY_ERROR) - tty_flag = TTY_PARITY; - else if (line_status UART_FRAME_ERROR) - tty_flag = TTY_FRAME; - dev_dbg(port-dev, %s - tty_flag = %d\n, __func__, tty_flag); - - /* overrun is special, not associated with a char */ - if (line_status UART_OVERRUN_ERROR) - tty_insert_flip_char(port-port, 0, TTY_OVERRUN); - - if (port-port.console port-sysrq) { - for (i = 0; i urb-actual_length; ++i) - if (!usb_serial_handle_sysrq_char(port, data[i])) - tty_insert_flip_char(port-port, data[i], - tty_flag); - } else { - tty_insert_flip_string_fixed_flag(port-port, data, tty_flag, - urb-actual_length); + /* bulk-in data: [LSR(1Byte)+DATA(1Byte)][LSR(1Byte)+DATA(1Byte)]... */ + + for (i = 0 ; i urb-actual_length ; i += 2) { + tty_flag = TTY_NORMAL; + + if (unlikely(data[i+0] UART_LSR_BRK_ERROR_BITS)) { + if (data[i+0] UART_LSR_BI) { + tty_flag = TTY_BREAK; + port-icount.brk++; + usb_serial_handle_break(port); + } else if (data[i+0] UART_LSR_PE) { + tty_flag = TTY_PARITY; + port-icount.parity++; + } else if (data[i+0] UART_LSR_FE) { + tty_flag = TTY_FRAME; + port-icount.frame++; + } + + if (data[0] UART_LSR_OE) { + port-icount.overrun++; + tty_insert_flip_char(port-port, 0, + TTY_OVERRUN); + } + } + + if (port-port.console port-sysrq) { + if (!usb_serial_handle_sysrq_char(port, data[i+1])) + tty_insert_flip_char(port-port, data[i+1], + tty_flag); + } else { + tty_insert_flip_string_fixed_flag(port-port, + data[i+1], tty_flag, 1); + } } tty_flip_buffer_push(port-port); -- 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 V5 4/8] USB: f81232: implement set_termios
The original driver had do not any h/w change in driver. This patch implements with configure H/W for baud/parity/word length/stop bits functional. Some init step extract to f81232_port_init(), called once with open(). And refine baudrate setting to f81232_set_baudrate() Signed-off-by: Peter Hung hpeter+linux_ker...@gmail.com --- drivers/usb/serial/f81232.c | 145 +--- 1 file changed, 138 insertions(+), 7 deletions(-) diff --git a/drivers/usb/serial/f81232.c b/drivers/usb/serial/f81232.c index 9ea498a..06d1eb0 100644 --- a/drivers/usb/serial/f81232.c +++ b/drivers/usb/serial/f81232.c @@ -31,11 +31,19 @@ static const struct usb_device_id id_table[] = { }; MODULE_DEVICE_TABLE(usb, id_table); +/* Maximum baudrate for F81232 */ +#define F81232_MAX_BAUDRATE 115200L + /* USB Control EP parameter */ #define F81232_REGISTER_REQUEST 0xA0 #define F81232_GET_REGISTER 0xc0 +#define F81232_SET_REGISTER 0x40 #define SERIAL_BASE_ADDRESS 0x0120 +#define RECEIVE_BUFFER_REGISTER(0x00 + SERIAL_BASE_ADDRESS) +#define INTERRUPT_ENABLE_REGISTER (0x01 + SERIAL_BASE_ADDRESS) +#define FIFO_CONTROL_REGISTER (0x02 + SERIAL_BASE_ADDRESS) +#define LINE_CONTROL_REGISTER (0x03 + SERIAL_BASE_ADDRESS) #define MODEM_STATUS_REGISTER (0x06 + SERIAL_BASE_ADDRESS) #define CONTROL_DTR0x01 @@ -61,6 +69,14 @@ struct f81232_private { struct usb_serial_port *port; }; +static int calc_baud_divisor(u32 baudrate) +{ + if (!baudrate) + return 0; + else + return DIV_ROUND_CLOSEST(F81232_MAX_BAUDRATE, baudrate); +} + static int f81232_get_register(struct usb_serial_port *port, u16 reg, u8 *data) { @@ -82,6 +98,27 @@ static int f81232_get_register(struct usb_serial_port *port, return status; } +static int f81232_set_register(struct usb_serial_port *port, + u16 reg, u8 data) +{ + int status; + struct usb_device *dev = port-serial-dev; + + status = usb_control_msg(dev, + usb_sndctrlpipe(dev, 0), + F81232_REGISTER_REQUEST, + F81232_SET_REGISTER, + reg, + 0, + data, + sizeof(data), + USB_CTRL_SET_TIMEOUT); + if (status 0) + dev_err(port-dev, %s status: %d\n, __func__, status); + + return status; +} + static void f81232_read_msr(struct usb_serial_port *port) { int status; @@ -247,18 +284,106 @@ static void f81232_break_ctl(struct tty_struct *tty, int break_state) */ } +static void f81232_set_baudrate(struct usb_serial_port *port, int baudrate) +{ + u8 divisor; + int status = 0; + + divisor = calc_baud_divisor(baudrate); + + status = f81232_set_register(port, LINE_CONTROL_REGISTER, +UART_LCR_DLAB); /* DLAB */ + if (status 0) { + dev_err(port-dev, %s status: %d line:%d\n, + __func__, status, __LINE__); + } + + status = f81232_set_register(port, RECEIVE_BUFFER_REGISTER, +divisor 0x00ff); /* low */ + if (status 0) { + dev_err(port-dev, %s status: %d line:%d\n, + __func__, status, __LINE__); + } + + status = f81232_set_register(port, INTERRUPT_ENABLE_REGISTER, +(divisor 0xff00) 8); /* high */ + if (status 0) { + dev_err(port-dev, %s status: %d line:%d\n, __func__, + status, __LINE__); + } + + status = f81232_set_register(port, LINE_CONTROL_REGISTER, 0x00); + if (status 0) { + dev_err(port-dev, %s status: %d line:%d\n, __func__, + status, __LINE__); + } +} + +static int f81232_port_init(struct usb_serial_port *port) +{ + u8 data; + int status = 0; + + /* fifo on, trigger8, clear TX/RX*/ + data = UART_FCR_TRIGGER_8 | UART_FCR_ENABLE_FIFO | UART_FCR_CLEAR_RCVR + | UART_FCR_CLEAR_XMIT; + + status |= f81232_set_register(port, FIFO_CONTROL_REGISTER, data); + + /* MSR Interrupt only, LSR will read from Bulk-in odd byte */ + data = UART_IER_MSI; + + /* IER */ + status |= f81232_set_register(port, INTERRUPT_ENABLE_REGISTER, data); + if (status 0) { + dev_err(port-dev, %s set error: %d\n, __func__, status); + return status; + } + + return 0; +} + static void f81232_set_termios(struct tty_struct *tty, struct usb_serial_port *port, struct ktermios *old_termios) { - /* FIXME - Stubbed out for now */ + u8 new_lcr = 0; + int status = 0; - /* Don't change anything if nothing has changed */ -
[PATCH V5 2/8] USB: f81232: implement read IIR/MSR with endpoint
The interrupt Endpoint will report current IIR. If we got IIR with MSR Changed , We will do read MSR with interrupt_work worker to do f81232_read_msr() func. Signed-off-by: Peter Hung hpeter+linux_ker...@gmail.com --- drivers/usb/serial/f81232.c | 109 1 file changed, 100 insertions(+), 9 deletions(-) diff --git a/drivers/usb/serial/f81232.c b/drivers/usb/serial/f81232.c index 669a2f2..ec4609d 100644 --- a/drivers/usb/serial/f81232.c +++ b/drivers/usb/serial/f81232.c @@ -23,6 +23,7 @@ #include linux/uaccess.h #include linux/usb.h #include linux/usb/serial.h +#include linux/serial_reg.h static const struct usb_device_id id_table[] = { { USB_DEVICE(0x1934, 0x0706) }, @@ -30,6 +31,13 @@ static const struct usb_device_id id_table[] = { }; MODULE_DEVICE_TABLE(usb, id_table); +/* USB Control EP parameter */ +#define F81232_REGISTER_REQUEST 0xA0 +#define F81232_GET_REGISTER 0xc0 + +#define SERIAL_BASE_ADDRESS 0x0120 +#define MODEM_STATUS_REGISTER (0x06 + SERIAL_BASE_ADDRESS) + #define CONTROL_DTR0x01 #define CONTROL_RTS0x02 @@ -48,19 +56,92 @@ struct f81232_private { spinlock_t lock; u8 line_control; u8 modem_status; + + struct work_struct interrupt_work; + struct usb_serial_port *port; }; -static void f81232_update_line_status(struct usb_serial_port *port, +static int f81232_get_register(struct usb_serial_port *port, + u16 reg, u8 *data) +{ + int status; + struct usb_device *dev = port-serial-dev; + + status = usb_control_msg(dev, +usb_rcvctrlpipe(dev, 0), +F81232_REGISTER_REQUEST, +F81232_GET_REGISTER, +reg, +0, +data, +sizeof(*data), +USB_CTRL_GET_TIMEOUT); + if (status 0) + dev_err(port-dev, %s status: %d\n, __func__, status); + + return status; +} + +static void f81232_read_msr(struct usb_serial_port *port) +{ + int status; + unsigned long flags; + u8 current_msr; + struct tty_struct *tty; + struct f81232_private *priv = usb_get_serial_port_data(port); + + status = f81232_get_register(port, MODEM_STATUS_REGISTER, + current_msr); + if (status 0) { + /* Retain the error even reported in f81232_get_register() +to make debug easily :D */ + dev_err(port-dev, %s fail, status: %d\n, __func__, status); + return; + } + + if (!(current_msr UART_MSR_ANY_DELTA)) + return; + + tty = tty_port_tty_get(port-port); + if (tty) { + if (current_msr UART_MSR_DDCD) { + usb_serial_handle_dcd_change(port, tty, + current_msr UART_MSR_DCD); + } + + tty_kref_put(tty); + } + + spin_lock_irqsave(priv-lock, flags); + priv-modem_status = current_msr; + spin_unlock_irqrestore(priv-lock, flags); + + wake_up_interruptible(port-port.delta_msr_wait); +} + +static void f81232_update_modem_status(struct usb_serial_port *port, unsigned char *data, unsigned int actual_length) { - /* -* FIXME: Update port-icount, and call -* -* wake_up_interruptible(port-port.delta_msr_wait); -* -*on MSR changes. -*/ + struct f81232_private *priv = usb_get_serial_port_data(port); + + if (!actual_length) + return; + + switch (data[0] 0x07) { + case 0x00: /* msr change */ + dev_dbg(port-dev, IIR: MSR Change: %x\n, data[0]); + schedule_work(priv-interrupt_work); + break; + case 0x02: /* tx-empty */ + break; + case 0x04: /* rx data available */ + break; + case 0x06: /* lsr change */ + /* we can forget it. the LSR will read from bulk-in */ + dev_dbg(port-dev, IIR: LSR Change: %x\n, data[0]); + break; + } } static void f81232_read_int_callback(struct urb *urb) @@ -91,7 +172,7 @@ static void f81232_read_int_callback(struct urb *urb) usb_serial_debug_data(port-dev, __func__, urb-actual_length, urb-transfer_buffer); - f81232_update_line_status(port, data, actual_length); + f81232_update_modem_status(port, data, actual_length); exit: retval = usb_submit_urb(urb, GFP_ATOMIC); @@ -270,6 +351,14 @@ static int f81232_ioctl(struct tty_struct *tty, return -ENOIOCTLCMD; } +static void f81232_interrupt_work(struct work_struct *work) +{ + struct
[PATCH V5 7/8] USB: f81232: fix error in f81232_carrier_raised()
It's should compared with UART_MSR_DCD, not UART_DCD. also we clean-up some non-used define to avoid impropriety use. Signed-off-by: Peter Hung hpeter+linux_ker...@gmail.com --- drivers/usb/serial/f81232.c | 16 +--- 1 file changed, 1 insertion(+), 15 deletions(-) diff --git a/drivers/usb/serial/f81232.c b/drivers/usb/serial/f81232.c index 4dddb44..07abf0c 100644 --- a/drivers/usb/serial/f81232.c +++ b/drivers/usb/serial/f81232.c @@ -47,20 +47,6 @@ MODULE_DEVICE_TABLE(usb, id_table); #define MODEM_CONTROL_REGISTER (0x04 + SERIAL_BASE_ADDRESS) #define MODEM_STATUS_REGISTER (0x06 + SERIAL_BASE_ADDRESS) -#define CONTROL_DTR0x01 -#define CONTROL_RTS0x02 - -#define UART_STATE 0x08 -#define UART_STATE_TRANSIENT_MASK 0x74 -#define UART_DCD 0x01 -#define UART_DSR 0x02 -#define UART_BREAK_ERROR 0x04 -#define UART_RING 0x08 -#define UART_FRAME_ERROR 0x10 -#define UART_PARITY_ERROR 0x20 -#define UART_OVERRUN_ERROR 0x40 -#define UART_CTS 0x80 - struct f81232_private { spinlock_t lock; u8 line_control; @@ -511,7 +497,7 @@ static void f81232_dtr_rts(struct usb_serial_port *port, int on) static int f81232_carrier_raised(struct usb_serial_port *port) { struct f81232_private *priv = usb_get_serial_port_data(port); - if (priv-modem_status UART_DCD) + if (priv-modem_status UART_MSR_DCD) return 1; return 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 V5 5/8] USB: f81232: implement MCR/MSR function
This patch implement relative MCR/MSR function, such like tiocmget()/tiocmset()/dtr_rts(). The f81232_set_mctrl() replace set_control_lines() to do MCR control so we clean-up the set_control_lines() function. Signed-off-by: Peter Hung hpeter+linux_ker...@gmail.com --- drivers/usb/serial/f81232.c | 98 +++-- 1 file changed, 77 insertions(+), 21 deletions(-) diff --git a/drivers/usb/serial/f81232.c b/drivers/usb/serial/f81232.c index 06d1eb0..e1cdf42 100644 --- a/drivers/usb/serial/f81232.c +++ b/drivers/usb/serial/f81232.c @@ -44,6 +44,7 @@ MODULE_DEVICE_TABLE(usb, id_table); #define INTERRUPT_ENABLE_REGISTER (0x01 + SERIAL_BASE_ADDRESS) #define FIFO_CONTROL_REGISTER (0x02 + SERIAL_BASE_ADDRESS) #define LINE_CONTROL_REGISTER (0x03 + SERIAL_BASE_ADDRESS) +#define MODEM_CONTROL_REGISTER (0x04 + SERIAL_BASE_ADDRESS) #define MODEM_STATUS_REGISTER (0x06 + SERIAL_BASE_ADDRESS) #define CONTROL_DTR0x01 @@ -156,6 +157,50 @@ static void f81232_read_msr(struct usb_serial_port *port) wake_up_interruptible(port-port.delta_msr_wait); } +static int f81232_set_mctrl(struct usb_serial_port *port, + unsigned int set, unsigned int clear) +{ + u8 urb_value; + int status; + unsigned long flags; + struct f81232_private *priv = usb_get_serial_port_data(port); + + if (((set | clear) (TIOCM_DTR | TIOCM_RTS)) == 0) + return 0; /* no change */ + + /* 'set' takes precedence over 'clear' */ + clear = ~set; + + /* force enable interrupt with OUT2 */ + urb_value = UART_MCR_OUT2 | priv-line_control; + + if (clear TIOCM_DTR) + urb_value = ~UART_MCR_DTR; + + if (clear TIOCM_RTS) + urb_value = ~UART_MCR_RTS; + + if (set TIOCM_DTR) + urb_value |= UART_MCR_DTR; + + if (set TIOCM_RTS) + urb_value |= UART_MCR_RTS; + + dev_dbg(port-dev, %s new:%02x old:%02x\n, __func__, + urb_value, priv-line_control); + + status = f81232_set_register(port, MODEM_CONTROL_REGISTER, urb_value); + if (status 0) { + dev_err(port-dev, %s set MCR status 0\n, __func__); + } else { + spin_lock_irqsave(priv-lock, flags); + priv-line_control = urb_value; + spin_unlock_irqrestore(priv-lock, flags); + } + + return status; +} + static void f81232_update_modem_status(struct usb_serial_port *port, unsigned char *data, unsigned int actual_length) @@ -267,12 +312,6 @@ static void f81232_process_read_urb(struct urb *urb) tty_flip_buffer_push(port-port); } -static int set_control_lines(struct usb_device *dev, u8 value) -{ - /* FIXME - Stubbed out for now */ - return 0; -} - static void f81232_break_ctl(struct tty_struct *tty, int break_state) { /* FIXME - Stubbed out for now */ @@ -388,15 +427,41 @@ static void f81232_set_termios(struct tty_struct *tty, static int f81232_tiocmget(struct tty_struct *tty) { - /* FIXME - Stubbed out for now */ - return 0; + int r; + struct usb_serial_port *port = tty-driver_data; + struct f81232_private *port_priv = usb_get_serial_port_data(port); + unsigned long flags; + u8 mcr, msr; + + /* force get current MSR changed state */ + f81232_read_msr(port); + + spin_lock_irqsave(port_priv-lock, flags); + mcr = port_priv-line_control; + msr = port_priv-modem_status; + spin_unlock_irqrestore(port_priv-lock, flags); + + r = (mcr UART_MCR_DTR ? TIOCM_DTR : 0) | + (mcr UART_MCR_RTS ? TIOCM_RTS : 0) | + (msr UART_MSR_CTS ? TIOCM_CTS : 0) | + (msr UART_MSR_DCD ? TIOCM_CAR : 0) | + (msr UART_MSR_RI ? TIOCM_RI : 0) | + (msr UART_MSR_DSR ? TIOCM_DSR : 0); + + return r; } static int f81232_tiocmset(struct tty_struct *tty, unsigned int set, unsigned int clear) { - /* FIXME - Stubbed out for now */ - return 0; + int status; + struct usb_serial_port *port = tty-driver_data; + + status = f81232_set_mctrl(port, set, clear); + if (status 0) + return usb_translate_errors(status); + else + return 0; } static int f81232_open(struct tty_struct *tty, struct usb_serial_port *port) @@ -437,19 +502,10 @@ static void f81232_close(struct usb_serial_port *port) static void f81232_dtr_rts(struct usb_serial_port *port, int on) { - struct f81232_private *priv = usb_get_serial_port_data(port); - unsigned long flags; - u8 control; - - spin_lock_irqsave(priv-lock, flags); - /* Change DTR and RTS */ if (on) - priv-line_control |= (CONTROL_DTR |
Re: [PATCH 4/4] usb: phy: add phy-hi6220
On Thu, Feb 05, 2015 at 10:47:00PM +0800, Zhangfei Gao wrote: Add usb phy controller for hi6220 platform Signed-off-by: Zhangfei Gao zhangfei@linaro.org --- drivers/usb/phy/Kconfig | 9 ++ drivers/usb/phy/Makefile | 1 + drivers/usb/phy/phy-hi6220.c | 290 +++ 3 files changed, 300 insertions(+) create mode 100644 drivers/usb/phy/phy-hi6220.c diff --git a/drivers/usb/phy/Kconfig b/drivers/usb/phy/Kconfig index c6d0c8e..405a3d0 100644 --- a/drivers/usb/phy/Kconfig +++ b/drivers/usb/phy/Kconfig @@ -173,6 +173,15 @@ config USB_MXS_PHY MXS Phy is used by some of the i.MX SoCs, for example imx23/28/6x. +config USB_HI6220_PHY + tristate hi6220 USB PHY support + select USB_PHY + select MFD_SYSCON + help + Enable this to support the HISILICON HI6220 USB PHY. + + To compile this driver as a module, choose M here. + config USB_RCAR_PHY tristate Renesas R-Car USB PHY support depends on USB || USB_GADGET diff --git a/drivers/usb/phy/Makefile b/drivers/usb/phy/Makefile index 75f2bba..819283c 100644 --- a/drivers/usb/phy/Makefile +++ b/drivers/usb/phy/Makefile @@ -18,6 +18,7 @@ obj-$(CONFIG_SAMSUNG_USBPHY)+= phy-samsung-usb.o obj-$(CONFIG_TWL6030_USB)+= phy-twl6030-usb.o obj-$(CONFIG_USB_EHCI_TEGRA) += phy-tegra-usb.o obj-$(CONFIG_USB_GPIO_VBUS) += phy-gpio-vbus-usb.o +obj-$(CONFIG_USB_HI6220_PHY) += phy-hi6220.o To align the naming method, phy-hi6220-usb is better. obj-$(CONFIG_USB_ISP1301)+= phy-isp1301.o obj-$(CONFIG_USB_MSM_OTG)+= phy-msm-usb.o obj-$(CONFIG_USB_MV_OTG) += phy-mv-usb.o diff --git a/drivers/usb/phy/phy-hi6220.c b/drivers/usb/phy/phy-hi6220.c new file mode 100644 index 000..87b1f0e --- /dev/null +++ b/drivers/usb/phy/phy-hi6220.c @@ -0,0 +1,290 @@ +/* + * Copyright (c) 2015 Linaro Ltd. + * Copyright (c) 2015 Hisilicon Limited. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + */ + +#include linux/clk.h +#include linux/mfd/syscon.h +#include linux/of_gpio.h +#include linux/platform_device.h +#include linux/regmap.h +#include linux/regulator/consumer.h +#include linux/usb/gadget.h +#include linux/usb/otg.h + +#define SC_PERIPH_CTRL4 0x00c + +#define PERIPH_CTRL4_PICO_SIDDQ BIT(6) +#define PERIPH_CTRL4_PICO_OGDISABLE BIT(8) +#define PERIPH_CTRL4_PICO_VBUSVLDEXT BIT(10) +#define PERIPH_CTRL4_PICO_VBUSVLDEXTSEL BIT(11) +#define PERIPH_CTRL4_OTG_PHY_SEL BIT(21) + +#define SC_PERIPH_CTRL5 0x010 + +#define PERIPH_CTRL5_USBOTG_RES_SEL BIT(3) +#define PERIPH_CTRL5_PICOPHY_ACAENB BIT(4) +#define PERIPH_CTRL5_PICOPHY_BC_MODE BIT(5) +#define PERIPH_CTRL5_PICOPHY_CHRGSEL BIT(6) +#define PERIPH_CTRL5_PICOPHY_VDATSRCEND BIT(7) +#define PERIPH_CTRL5_PICOPHY_VDATDETENB BIT(8) +#define PERIPH_CTRL5_PICOPHY_DCDENB BIT(9) +#define PERIPH_CTRL5_PICOPHY_IDDIG BIT(10) + +#define SC_PERIPH_CTRL8 0x018 + +#define EYE_PATTERN_PARA 0x7053348c + +#define SC_PERIPH_RSTDIS00x304 + +#define PERIPH_RSTDIS0_USBOTG_BUSBIT(4) +#define PERIPH_RSTDIS0_POR_PICOPHY BIT(5) +#define PERIPH_RSTDIS0_USBOTGBIT(6) +#define PERIPH_RSTDIS0_USBOTG_32KBIT(7) + +enum usb_mode { + USB_EMPTY, + GADGET_DEVICE, + OTG_HOST, +}; This usb_mode is a little strange, what state you would like to use? + +struct hi6220_priv { + struct usb_phy phy; + struct delayed_work work; + struct regmap *reg; + struct clk *clk; + struct regulator *vcc; + int gpio_vbus_det; + int gpio_id_det; + enum usb_mode mode; +}; + +static void hi6220_start_periphrals(struct hi6220_priv *priv, bool on) +{ + struct usb_otg *otg = priv-phy.otg; + + if (!otg-gadget) + return; + + if (on) + usb_gadget_connect(otg-gadget); + else + usb_gadget_disconnect(otg-gadget); +} + +static void hi6220_detect_work(struct work_struct *work) +{ + struct hi6220_priv *priv = + container_of(work, struct hi6220_priv, work.work); + int id_det, vbus_det; + enum usb_mode mode; + + if (!gpio_is_valid(priv-gpio_id_det) || + !gpio_is_valid(priv-gpio_vbus_det)) + return; + + id_det = gpio_get_value_cansleep(priv-gpio_id_det); + vbus_det = gpio_get_value_cansleep(priv-gpio_vbus_det); + + if (vbus_det == 0) { + if (id_det == 1) + mode = GADGET_DEVICE; + else + mode = OTG_HOST; + }
[PATCH] usb: isp1760: use msecs_to_jiffies for time conversion
This is only an API consolidation and should make things more readable it replaces var * HZ / 1000 by msecs_to_jiffies(var). Signed-off-by: Nicholas Mc Guire hof...@osadl.org --- Patch was only compile tested with x86_64_defconfig + CONFIG_USB_ISP1760=m Patch is against 3.19.0-rc7 (localversion-next is -next-20150204) drivers/usb/isp1760/isp1760-hcd.c |6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/usb/isp1760/isp1760-hcd.c b/drivers/usb/isp1760/isp1760-hcd.c index eba9b82..3cb98b1 100644 --- a/drivers/usb/isp1760/isp1760-hcd.c +++ b/drivers/usb/isp1760/isp1760-hcd.c @@ -1274,7 +1274,7 @@ static void errata2_function(unsigned long data) for (slot = 0; slot 32; slot++) if (priv-atl_slots[slot].qh time_after(jiffies, priv-atl_slots[slot].timestamp + - SLOT_TIMEOUT * HZ / 1000)) { + msecs_to_jiffies(SLOT_TIMEOUT))) { ptd_read(hcd-regs, ATL_PTD_OFFSET, slot, ptd); if (!FROM_DW0_VALID(ptd.dw0) !FROM_DW3_ACTIVE(ptd.dw3)) @@ -1286,7 +1286,7 @@ static void errata2_function(unsigned long data) spin_unlock_irqrestore(priv-lock, spinflags); - errata2_timer.expires = jiffies + SLOT_CHECK_PERIOD * HZ / 1000; + errata2_timer.expires = jiffies + msecs_to_jiffies(SLOT_CHECK_PERIOD); add_timer(errata2_timer); } @@ -1336,7 +1336,7 @@ static int isp1760_run(struct usb_hcd *hcd) return retval; setup_timer(errata2_timer, errata2_function, (unsigned long)hcd); - errata2_timer.expires = jiffies + SLOT_CHECK_PERIOD * HZ / 1000; + errata2_timer.expires = jiffies + msecs_to_jiffies(SLOT_CHECK_PERIOD); add_timer(errata2_timer); chipid = reg_read32(hcd-regs, HC_CHIP_ID_REG); -- 1.7.10.4 -- 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: dwc2: gadget reuse ahbcfg assigned from platform
On 6 February 2015 at 16:07, Kaukab, Yousaf yousaf.kau...@intel.com wrote: GAHBCFG_HBSTLEN_INCR4 diff --git a/drivers/usb/dwc2/gadget.c b/drivers/usb/dwc2/gadget.c index 15aa578..20085de 100644 --- a/drivers/usb/dwc2/gadget.c +++ b/drivers/usb/dwc2/gadget.c @@ -2314,9 +2314,13 @@ void s3c_hsotg_core_init_disconnected(struct dwc2_hsotg *hsotg, GINTSTS_USBSUSP | GINTSTS_WKUPINT, hsotg-regs + GINTMSK); + if ((hsotg-core_params) (hsotg-core_params-ahbcfg != - 1)) + val = hsotg-core_params-ahbcfg ~GAHBCFG_CTRL_MASK; + else + val = GAHBCFG_HBSTLEN_INCR4 GAHBCFG_HBSTLEN_SHIFT; + if (using_dma(hsotg)) - writel(GAHBCFG_GLBL_INTR_EN | GAHBCFG_DMA_EN | -(GAHBCFG_HBSTLEN_INCR4 GAHBCFG_HBSTLEN_SHIFT), + writel(GAHBCFG_GLBL_INTR_EN | GAHBCFG_DMA_EN | val, hsotg-regs + GAHBCFG); else writel(((hsotg-dedicated_fifos) ? (GAHBCFG_NP_TXF_EMP_LVL | There are other bits in GAHBCFG that can be set from platform. They will be preserved by your patch, as they are not part of GAHBCFG_CTRL_MASK, but only in case dma is enabled. Perhaps preserve them in non-dma case as well. Here may have issue if also set hsotg-core_params-ahbcfg for non-dma case, since GAHBCFG[4:1] may be set. You can mask off HBstLen in that case. However, I don't think setting burst length will be an issue in non DMA case as DWC2 will not act as a bus master. John, can you please confirm if setting burst length will be an issue in non-dma case? It would be great if John has some input. I am not sure, just doubt ahbcfg is specifically used for dma mode. static int dwc2_gahbcfg_init(struct dwc2_hsotg *hsotg) { case GHWCFG2_INT_DMA_ARCH: dev_dbg(hsotg-dev, Internal DMA Mode\n); if (hsotg-core_params-ahbcfg != -1) { ahbcfg = GAHBCFG_CTRL_MASK; ahbcfg |= hsotg-core_params-ahbcfg ~GAHBCFG_CTRL_MASK; } break; } Looks like only GHWCFG2_INT_DMA_ARCH case cares the value of ahbcfg. Though from drivers/usb/dwc2/core.h we can not see @ahbcfg is specifically used for dma case, most case in drivers/usb/dwc2/platform.c use ahbcfg is set hbstlen, GAHBCFG[4:1]. For example, our platform set GAHBCFG_HBSTLEN_INCR16. So I just assume @ahbcfg is used for dma case. What do you think. While you are fixing it, why not fix it for other bits, for example AHBSingle, InvDescEndianness etc., which are part of the same register and will be overwritten at the same place. Yes, understand. Not sure other value need to be overwirtten, if only GAHBCFG[4:1], burst len, maybe we can add another property? Will update accordingly after John give some info. Thanks Yousaf -- 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 V5 1/8] USB: f81232: Rename private struct member name
Change private struct member name from line_status to modem_status. It will store MSR for some functions used Signed-off-by: Peter Hung hpeter+linux_ker...@gmail.com --- drivers/usb/serial/f81232.c | 8 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/usb/serial/f81232.c b/drivers/usb/serial/f81232.c index c5dc233..669a2f2 100644 --- a/drivers/usb/serial/f81232.c +++ b/drivers/usb/serial/f81232.c @@ -47,7 +47,7 @@ MODULE_DEVICE_TABLE(usb, id_table); struct f81232_private { spinlock_t lock; u8 line_control; - u8 line_status; + u8 modem_status; }; static void f81232_update_line_status(struct usb_serial_port *port, @@ -113,8 +113,8 @@ static void f81232_process_read_urb(struct urb *urb) /* update line status */ spin_lock_irqsave(priv-lock, flags); - line_status = priv-line_status; - priv-line_status = ~UART_STATE_TRANSIENT_MASK; + line_status = priv-modem_status; + priv-modem_status = ~UART_STATE_TRANSIENT_MASK; spin_unlock_irqrestore(priv-lock, flags); if (!urb-actual_length) @@ -241,7 +241,7 @@ static void f81232_dtr_rts(struct usb_serial_port *port, int on) static int f81232_carrier_raised(struct usb_serial_port *port) { struct f81232_private *priv = usb_get_serial_port_data(port); - if (priv-line_status UART_DCD) + if (priv-modem_status UART_DCD) return 1; return 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 V5 0/8] USB: f81534: v5 patch
This series patch V5 is improvement from V4 as following: 1. transform all function not to use private data as parameter, using usb_serial_port instead. 2. Some init step we extract it from set_term() to f81232_port_init() and run it when open port only. 3. We'll force re-read msr in tiocmget() because the IIR with MSR change maybe delay received. 4. process_read_urb() add process of Break/FrameError/ParityError. 5. clarify a lot of code about Johan suggested. Peter Hung (8): USB: f81232: Rename private struct member name USB: f81232: implement read IIR/MSR with endpoint USB: f81232: implement RX bulk-in ep USB: f81232: implement set_termios USB: f81232: implement MCR/MSR function USB: f81232: clarify f81232_ioctl() USB: f81232: fix error in f81232_carrier_raised() USB: f81232: modify/add author drivers/usb/serial/f81232.c | 471 +++- 1 file changed, 375 insertions(+), 96 deletions(-) -- 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
[RFC PATCH 1/2] usb: dwc3: ep0: preparation for implementing chained TRB
No functional change. Modified few things so that there are no code duplication while implementing chained TRB. Signed-off-by: Kishon Vijay Abraham I kis...@ti.com --- drivers/usb/dwc3/ep0.c | 23 ++- 1 file changed, 14 insertions(+), 9 deletions(-) diff --git a/drivers/usb/dwc3/ep0.c b/drivers/usb/dwc3/ep0.c index 2ef3c8d..24b7925 100644 --- a/drivers/usb/dwc3/ep0.c +++ b/drivers/usb/dwc3/ep0.c @@ -779,7 +779,10 @@ static void dwc3_ep0_complete_data(struct dwc3 *dwc, struct usb_request *ur; struct dwc3_trb *trb; struct dwc3_ep *ep0; - u32 transferred; + unsignedtransfer_size = 0; + unsignedmaxp; + void*buf; + u32 transferred = 0; u32 status; u32 length; u8 epnum; @@ -808,16 +811,17 @@ static void dwc3_ep0_complete_data(struct dwc3 *dwc, } ur = r-request; + buf = ur-buf; length = trb-size DWC3_TRB_SIZE_MASK; - if (dwc-ep0_bounced) { - unsigned transfer_size = ur-length; - unsigned maxp = ep0-endpoint.maxpacket; + maxp = ep0-endpoint.maxpacket; - transfer_size += (maxp - (transfer_size % maxp)); - transferred = min_t(u32, ur-length, - transfer_size - length); + if (dwc-ep0_bounced) { + transfer_size = roundup((ur-length - transfer_size), + maxp); + transferred = min_t(u32, ur-length - transferred, + transfer_size - length); memcpy(ur-buf, dwc-ep0_bounce, transferred); } else { transferred = ur-length - length; @@ -927,7 +931,7 @@ static void __dwc3_ep0_do_control_data(struct dwc3 *dwc, DWC3_TRBCTL_CONTROL_DATA); } else if (!IS_ALIGNED(req-request.length, dep-endpoint.maxpacket) (dep-number == 0)) { - u32 transfer_size; + u32 transfer_size = 0; u32 maxpacket; ret = usb_gadget_map_request(dwc-gadget, req-request, @@ -940,7 +944,8 @@ static void __dwc3_ep0_do_control_data(struct dwc3 *dwc, WARN_ON(req-request.length DWC3_EP0_BOUNCE_SIZE); maxpacket = dep-endpoint.maxpacket; - transfer_size = roundup(req-request.length, maxpacket); + transfer_size = roundup((req-request.length - transfer_size), + maxpacket); dwc-ep0_bounced = true; -- 1.7.9.5 -- 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] xhci: Fix the lack of support for the Handle Port Configure Error
From: Shimmer Huang shimm...@marvell.com Linux xHCI driver does not check the CEC bit in register PORTSC when handling port status events. If Port Configure Error for root hub port occurs, CEC bit in PORTSC would be set by xHC and remains 1. This happends when the root port fails to configure its link partner, e.g. the port fails to exchange port capabilities information using Port Capability LMPs. Then the Port Status Change Events will be blocked until all status change bits(CEC is one of the change bits) are cleared('0') (refer to xHCI spec 4.19.2). Otherwise, the port status change event for this root port will not be generated anymore, then root port would look like “dead” for user and can’t be recovered until a Host Controller Reset(HCRST) This patch is to check CEC bit and clear the CEC bit if it's set to 1 in function handle_port_status(). [gregory.clem...@free-electrons.com: ported from 3.10 and added more explanations(from Shimmer) in the commit log] Signed-off-by: Guang Shen gs...@marvell.com Signed-off-by: Shimmer Huang shimm...@marvell.com Signed-off-by: Nadav Haklai nad...@marvell.com Reviewed-by: Yehuda Yitschak yehu...@marvell.com Signed-off-by: Gregory CLEMENT gregory.clem...@free-electrons.com Cc: sta...@vger.kernel.org --- Hi, usually I tried to add a kernel version for the stable team, but for this patch I don't know since when it makes sens to apply it. Gregory drivers/usb/host/xhci-ring.c | 7 +++ 1 file changed, 7 insertions(+) diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c index e692e769c50c..45d8dd7e07f3 100644 --- a/drivers/usb/host/xhci-ring.c +++ b/drivers/usb/host/xhci-ring.c @@ -1541,6 +1541,13 @@ static void handle_port_status(struct xhci_hcd *xhci, port_id); temp = readl(port_array[faked_port_index]); + + if (temp PORT_CEC) { + xhci_dbg(xhci, port failed to configure its link partner.\n); + xhci_test_and_clear_bit(xhci, port_array, + faked_port_index, PORT_CEC); + } + if (hcd-state == HC_STATE_SUSPENDED) { xhci_dbg(xhci, resume root hub\n); usb_hcd_resume_root_hub(hcd); -- 2.1.0 -- 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] usb: dwc2: Register interrupt handler only once gadget is correctly initialized
Don't register interrupt handler before usb gadget is correctly initialized. For some embedded platforms which don't have a usb-phy, it crashes the driver because an interrupt is emitted with non-initialized hardware. According to devm_request_irq documentation, an interrupt can be emitted at any time once the interrupt is registered, so we have to care about driver and hardware initialization. Signed-off-by: Romain Perier romain.per...@gmail.com --- Changes for v2: fix typos in commit log drivers/usb/dwc2/platform.c | 17 + 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/drivers/usb/dwc2/platform.c b/drivers/usb/dwc2/platform.c index ae095f0..b26cf8c 100644 --- a/drivers/usb/dwc2/platform.c +++ b/drivers/usb/dwc2/platform.c @@ -196,14 +196,6 @@ static int dwc2_driver_probe(struct platform_device *dev) return irq; } - dev_dbg(hsotg-dev, registering common handler for irq%d\n, - irq); - retval = devm_request_irq(hsotg-dev, irq, - dwc2_handle_common_intr, IRQF_SHARED, - dev_name(hsotg-dev), hsotg); - if (retval) - return retval; - res = platform_get_resource(dev, IORESOURCE_MEM, 0); hsotg-regs = devm_ioremap_resource(dev-dev, res); if (IS_ERR(hsotg-regs)) @@ -237,6 +229,15 @@ static int dwc2_driver_probe(struct platform_device *dev) retval = dwc2_gadget_init(hsotg, irq); if (retval) return retval; + +dev_dbg(hsotg-dev, registering common handler for irq%d\n, +irq); +retval = devm_request_irq(hsotg-dev, irq, +dwc2_handle_common_intr, IRQF_SHARED, +dev_name(hsotg-dev), hsotg); +if (retval) +return retval; + retval = dwc2_hcd_init(hsotg, irq, params); if (retval) return retval; -- 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
Re: [PATCH 2/2] usb: musb: Fix getting a generic phy for musb_dsps
Hi Tony, You also need to add similar things in dsps_musb_reset(); Otherwise you might not recover from a BABBLE condition. On 02/05/2015 10:05 PM, Tony Lindgren wrote: We still have a combination of legacy phys and generic phys in use so we need to support both types of phy for musb_dsps.c. Cc: Brian Hutchinson b.hutch...@gmail.com Signed-off-by: Tony Lindgren t...@atomide.com --- drivers/usb/musb/musb_dsps.c | 17 + 1 file changed, 17 insertions(+) --- a/drivers/usb/musb/musb_dsps.c +++ b/drivers/usb/musb/musb_dsps.c @@ -457,12 +457,25 @@ static int dsps_musb_init(struct musb *musb) if (IS_ERR(musb-xceiv)) return PTR_ERR(musb-xceiv); + musb-phy = devm_phy_get(dev-parent, usb2-phy); + /* Returns zero if e.g. not clocked */ rev = dsps_readl(reg_base, wrp-revision); if (!rev) return -ENODEV; usb_phy_init(musb-xceiv); + if (IS_ERR(musb-phy)) { + musb-phy = NULL; + } else { + ret = phy_init(musb-phy); + if (ret 0) + return ret; + ret = phy_power_on(musb-phy); + if (ret) + return ret; + } + setup_timer(glue-timer, otg_timer, (unsigned long) musb); /* Reset the musb */ @@ -502,6 +515,10 @@ static int dsps_musb_exit(struct musb *musb) del_timer_sync(glue-timer); usb_phy_shutdown(musb-xceiv); + if (musb-phy) { + phy_power_off(musb-phy); + phy_exit(musb-phy); + } debugfs_remove_recursive(glue-dbgfs_root); return 0; -George -- 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: image: use msecs_to_jiffies for time conversion
On Fri, 06 Feb 2015, Sergei Shtylyov wrote: Hello. On 2/6/2015 12:50 PM, Nicholas Mc Guire wrote: This is only an API consolidation and should make things more readable it replaces var * HZ / 1000 by msecs_to_jiffies(var). Signed-off-by: Nicholas Mc Guire hof...@osadl.org --- Note that the indentation is not aligned with the correct ( here due to lines going over 80 char - not sure if this is the right way to resolve this (this file has quite a few coding style issues). Patch was only compile tested with x86_64_defconfig + CONFIG_USB_MDC800=m Patch is against 3.19.0-rc7 (localversion-next is -next-20150204) drivers/usb/image/mdc800.c | 11 +++ 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/drivers/usb/image/mdc800.c b/drivers/usb/image/mdc800.c index a62865a..3a72e8f 100644 --- a/drivers/usb/image/mdc800.c +++ b/drivers/usb/image/mdc800.c [...] @@ -743,8 +744,9 @@ static ssize_t mdc800_device_read (struct file *file, char __user *buf, size_t l mutex_unlock(mdc800-io_lock); return len-left; } -wait_event_timeout(mdc800-download_wait, mdc800-downloaded, - TO_DOWNLOAD_GET_READY*HZ/1000); +wait_event_timeout(mdc800-download_wait, + mdc800-downloaded, + msecs_to_jiffies(TO_DOWNLOAD_GET_READY)); Don't indent with spaces (you're not aligning to open paren anyway), use the final tab instead, please. thanks ! In the diff output that problem is actually not well visible. was not really clear on how to do this properly - the problem with using the last tab stop is that you then get the following code wait_event_timeout(mdc800-download_wait, mdc800-downloaded, msecs_to_jiffies(TO_DOWNLOAD_GET_READY)); mdc800-downloaded = 0; which semed really bad and wait_event_timeout(mdc800-download_wait, mdc800-downloaded, msecs_to_jiffies(TO_DOWNLOAD_GET_READY)); mdc800-downloaded = 0; makes it atleast somewhat readable. If I indent a full tab ghen it goes over 80 char. So in this case - should one use the last tab-stop anyway ? thx! hofrat -- 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: image: use msecs_to_jiffies for time conversion
On 2/6/2015 4:36 PM, Nicholas Mc Guire wrote: This is only an API consolidation and should make things more readable it replaces var * HZ / 1000 by msecs_to_jiffies(var). Signed-off-by: Nicholas Mc Guire hof...@osadl.org --- Note that the indentation is not aligned with the correct ( here due to lines going over 80 char - not sure if this is the right way to resolve this (this file has quite a few coding style issues). Patch was only compile tested with x86_64_defconfig + CONFIG_USB_MDC800=m Patch is against 3.19.0-rc7 (localversion-next is -next-20150204) drivers/usb/image/mdc800.c | 11 +++ 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/drivers/usb/image/mdc800.c b/drivers/usb/image/mdc800.c index a62865a..3a72e8f 100644 --- a/drivers/usb/image/mdc800.c +++ b/drivers/usb/image/mdc800.c [...] @@ -743,8 +744,9 @@ static ssize_t mdc800_device_read (struct file *file, char __user *buf, size_t l mutex_unlock(mdc800-io_lock); return len-left; } - wait_event_timeout(mdc800-download_wait, mdc800-downloaded, - TO_DOWNLOAD_GET_READY*HZ/1000); + wait_event_timeout(mdc800-download_wait, +mdc800-downloaded, +msecs_to_jiffies(TO_DOWNLOAD_GET_READY)); Don't indent with spaces (you're not aligning to open paren anyway), use the final tab instead, please. thanks ! In the diff output that problem is actually not well visible. was not really clear on how to do this properly - the problem with using the last tab stop is that you then get the following code wait_event_timeout(mdc800-download_wait, mdc800-downloaded, msecs_to_jiffies(TO_DOWNLOAD_GET_READY)); mdc800-downloaded = 0; which semed really bad and Yes, it's horrible. wait_event_timeout(mdc800-download_wait, mdc800-downloaded, msecs_to_jiffies(TO_DOWNLOAD_GET_READY)); mdc800-downloaded = 0; makes it atleast somewhat readable. If I indent a full tab ghen it goes over 80 char. Ah, I didn't realize that, sorry. So in this case - should one use the last tab-stop anyway ? Probably not. thx! hofrat WBR, 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: image: use msecs_to_jiffies for time conversion
Hello. On 2/6/2015 12:50 PM, Nicholas Mc Guire wrote: This is only an API consolidation and should make things more readable it replaces var * HZ / 1000 by msecs_to_jiffies(var). Signed-off-by: Nicholas Mc Guire hof...@osadl.org --- Note that the indentation is not aligned with the correct ( here due to lines going over 80 char - not sure if this is the right way to resolve this (this file has quite a few coding style issues). Patch was only compile tested with x86_64_defconfig + CONFIG_USB_MDC800=m Patch is against 3.19.0-rc7 (localversion-next is -next-20150204) drivers/usb/image/mdc800.c | 11 +++ 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/drivers/usb/image/mdc800.c b/drivers/usb/image/mdc800.c index a62865a..3a72e8f 100644 --- a/drivers/usb/image/mdc800.c +++ b/drivers/usb/image/mdc800.c [...] @@ -743,8 +744,9 @@ static ssize_t mdc800_device_read (struct file *file, char __user *buf, size_t l mutex_unlock(mdc800-io_lock); return len-left; } - wait_event_timeout(mdc800-download_wait, mdc800-downloaded, - TO_DOWNLOAD_GET_READY*HZ/1000); + wait_event_timeout(mdc800-download_wait, +mdc800-downloaded, +msecs_to_jiffies(TO_DOWNLOAD_GET_READY)); Don't indent with spaces (you're not aligning to open paren anyway), use the final tab instead, please. WBR, 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 1/3] usb: gadget: rndis: use rndis_params instead of configNr
RNDIS function has a limitation on the number of allowed instances. So far it has been RNDIS_MAX_CONFIGS, which happens to be one. In order to eliminate this kind of arbitrary limitation we should not preallocate a predefined (RNDIS_MAX_CONFIGS) array of struct rndis_params instances but instead allow allocating them on demand. This patch prepares the elimination of the said limit by converting all the functions which accept rndis config number to accept a pointer to the actual struct rndis_params. Consequently, rndis_register() returns a pointer to a corresponding struct rndis_params instance. The pointer is then always used by f_rndis.c instead of config number when it talks to rndis.c API. A nice side-effect of the changes is that many lines of code in rndis.c become shorter and fit in 80 columns. If a function prototype changes in rndis.h a style cleanup is made at the same time, otherwise checkpatch complains that the patch has style problems. Signed-off-by: Andrzej Pietrasiewicz andrze...@samsung.com --- drivers/usb/gadget/function/f_rndis.c | 38 +++--- drivers/usb/gadget/function/rndis.c | 213 +++--- drivers/usb/gadget/function/rndis.h | 29 ++--- 3 files changed, 129 insertions(+), 151 deletions(-) diff --git a/drivers/usb/gadget/function/f_rndis.c b/drivers/usb/gadget/function/f_rndis.c index 829edf8..2dafe72 100644 --- a/drivers/usb/gadget/function/f_rndis.c +++ b/drivers/usb/gadget/function/f_rndis.c @@ -76,7 +76,7 @@ struct f_rndis { u8 ethaddr[ETH_ALEN]; u32 vendorID; const char *manufacturer; - int config; + struct rndis_params *params; struct usb_ep *notify; struct usb_request *notify_req; @@ -453,7 +453,7 @@ static void rndis_command_complete(struct usb_ep *ep, struct usb_request *req) /* received RNDIS command from USB_CDC_SEND_ENCAPSULATED_COMMAND */ // spin_lock(dev-lock); - status = rndis_msg_parser(rndis-config, (u8 *) req-buf); + status = rndis_msg_parser(rndis-params, (u8 *) req-buf); if (status 0) pr_err(RNDIS command error %d, %d/%d\n, status, req-actual, req-length); @@ -499,12 +499,12 @@ rndis_setup(struct usb_function *f, const struct usb_ctrlrequest *ctrl) u32 n; /* return the result */ - buf = rndis_get_next_response(rndis-config, n); + buf = rndis_get_next_response(rndis-params, n); if (buf) { memcpy(req-buf, buf, n); req-complete = rndis_response_complete; req-context = rndis; - rndis_free_response(rndis-config, buf); + rndis_free_response(rndis-params, buf); value = n; } /* else stalls ... spec says to avoid that */ @@ -597,7 +597,7 @@ static int rndis_set_alt(struct usb_function *f, unsigned intf, unsigned alt) if (IS_ERR(net)) return PTR_ERR(net); - rndis_set_param_dev(rndis-config, net, + rndis_set_param_dev(rndis-params, net, rndis-port.cdc_filter); } else goto fail; @@ -617,7 +617,7 @@ static void rndis_disable(struct usb_function *f) DBG(cdev, rndis deactivated\n); - rndis_uninit(rndis-config); + rndis_uninit(rndis-params); gether_disconnect(rndis-port); usb_ep_disable(rndis-notify); @@ -640,9 +640,9 @@ static void rndis_open(struct gether *geth) DBG(cdev, %s\n, __func__); - rndis_set_param_medium(rndis-config, RNDIS_MEDIUM_802_3, + rndis_set_param_medium(rndis-params, RNDIS_MEDIUM_802_3, bitrate(cdev-gadget) / 100); - rndis_signal_connect(rndis-config); + rndis_signal_connect(rndis-params); } static void rndis_close(struct gether *geth) @@ -651,8 +651,8 @@ static void rndis_close(struct gether *geth) DBG(geth-func.config-cdev, %s\n, __func__); - rndis_set_param_medium(rndis-config, RNDIS_MEDIUM_802_3, 0); - rndis_signal_disconnect(rndis-config); + rndis_set_param_medium(rndis-params, RNDIS_MEDIUM_802_3, 0); + rndis_signal_disconnect(rndis-params); } /*-*/ @@ -796,11 +796,11 @@ rndis_bind(struct usb_configuration *c, struct usb_function *f) rndis-port.open = rndis_open; rndis-port.close = rndis_close; - rndis_set_param_medium(rndis-config, RNDIS_MEDIUM_802_3, 0); - rndis_set_host_mac(rndis-config, rndis-ethaddr); +
[PATCH 2/3] usb: gadget: rndis: style correction
Don't use a space between function name and parameter list opening bracket. All other functions in this file comply wich checkpatch rules. Signed-off-by: Andrzej Pietrasiewicz andrze...@samsung.com --- drivers/usb/gadget/function/rndis.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/usb/gadget/function/rndis.h b/drivers/usb/gadget/function/rndis.h index 338deb7..1cddd99 100644 --- a/drivers/usb/gadget/function/rndis.h +++ b/drivers/usb/gadget/function/rndis.h @@ -206,7 +206,7 @@ int rndis_set_param_vendor(struct rndis_params *params, u32 vendorID, const char *vendorDescr); int rndis_set_param_medium(struct rndis_params *params, u32 medium, u32 speed); -void rndis_add_hdr (struct sk_buff *skb); +void rndis_add_hdr(struct sk_buff *skb); int rndis_rm_hdr(struct gether *port, struct sk_buff *skb, struct sk_buff_head *list); u8 *rndis_get_next_response(struct rndis_params *params, u32 *length); -- 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 3/3] usb: gadget: rndis: remove the limit of available rndis connections
RNDIS function has a limitation on the number of allowed instances. So far it has been RNDIS_MAX_CONFIGS, which happens to be one. In order to eliminate this kind of arbitrary limitation we should not preallocate a predefined (RNDIS_MAX_CONFIGS) array of struct rndis_params instances but instead allow allocating them on demand. This patch allocates struct rndis_params on demand in rndis_register(). Coversly, the structure is free()'d in rndis_deregister(). If CONFIG_USB_GADGET_DEBUG_FILES is set, the proc files are created which is the same behaviour as before, but the moment of creation is delayed until struct rndis_params is actually allocated. rnids_init() and rndis_exit() have nothing to do, so they are eliminated. Signed-off-by: Andrzej Pietrasiewicz andrze...@samsung.com --- Documentation/usb/gadget-testing.txt | 2 - drivers/usb/gadget/function/f_rndis.c | 22 +- drivers/usb/gadget/function/rndis.c | 140 +++--- drivers/usb/gadget/function/u_rndis.h | 2 - 4 files changed, 78 insertions(+), 88 deletions(-) diff --git a/Documentation/usb/gadget-testing.txt b/Documentation/usb/gadget-testing.txt index 076ac7b..339b612 100644 --- a/Documentation/usb/gadget-testing.txt +++ b/Documentation/usb/gadget-testing.txt @@ -525,8 +525,6 @@ Except for ifname they can be written to until the function is linked to a configuration. The ifname is read-only and contains the name of the interface which was assigned by the net core, e. g. usb0. -By default there can be only 1 RNDIS interface in the system. - Testing the RNDIS function -- diff --git a/drivers/usb/gadget/function/f_rndis.c b/drivers/usb/gadget/function/f_rndis.c index 2dafe72..32985da 100644 --- a/drivers/usb/gadget/function/f_rndis.c +++ b/drivers/usb/gadget/function/f_rndis.c @@ -1012,26 +1012,6 @@ static struct usb_function *rndis_alloc(struct usb_function_instance *fi) return rndis-port.func; } -DECLARE_USB_FUNCTION(rndis, rndis_alloc_inst, rndis_alloc); - -static int __init rndis_mod_init(void) -{ - int ret; - - ret = rndis_init(); - if (ret) - return ret; - - return usb_function_register(rndisusb_func); -} -module_init(rndis_mod_init); - -static void __exit rndis_mod_exit(void) -{ - usb_function_unregister(rndisusb_func); - rndis_exit(); -} -module_exit(rndis_mod_exit); - +DECLARE_USB_FUNCTION_INIT(rndis, rndis_alloc_inst, rndis_alloc); MODULE_LICENSE(GPL); MODULE_AUTHOR(David Brownell); diff --git a/drivers/usb/gadget/function/rndis.c b/drivers/usb/gadget/function/rndis.c index 01a3b58..dd68000 100644 --- a/drivers/usb/gadget/function/rndis.c +++ b/drivers/usb/gadget/function/rndis.c @@ -25,6 +25,7 @@ #include linux/moduleparam.h #include linux/kernel.h #include linux/errno.h +#include linux/idr.h #include linux/list.h #include linux/proc_fs.h #include linux/slab.h @@ -57,10 +58,13 @@ MODULE_PARM_DESC (rndis_debug, enable debugging); #define rndis_debug0 #endif -#define RNDIS_MAX_CONFIGS 1 +#ifdef CONFIG_USB_GADGET_DEBUG_FILES +#defineNAME_TEMPLATE driver/rndis-%03d -static rndis_params rndis_per_dev_params[RNDIS_MAX_CONFIGS]; +#endif /* CONFIG_USB_GADGET_DEBUG_FILES */ + +static DEFINE_IDA(rndis_ida); /* Driver Version */ static const __le32 rndis_driver_version = cpu_to_le32(1); @@ -69,6 +73,11 @@ static const __le32 rndis_driver_version = cpu_to_le32(1); static rndis_resp_t *rndis_add_response(struct rndis_params *params, u32 length); +#ifdef CONFIG_USB_GADGET_DEBUG_FILES + +static const struct file_operations rndis_proc_fops; + +#endif /* CONFIG_USB_GADGET_DEBUG_FILES */ /* supported OIDs */ static const u32 oid_supported_list[] = @@ -850,38 +859,93 @@ int rndis_msg_parser(struct rndis_params *params, u8 *buf) } EXPORT_SYMBOL_GPL(rndis_msg_parser); +static inline int rndis_get_nr(void) +{ + return ida_simple_get(rndis_ida, 0, 0, GFP_KERNEL); +} + +static inline void rndis_put_nr(int nr) +{ + ida_simple_remove(rndis_ida, nr); +} + struct rndis_params *rndis_register(void (*resp_avail)(void *v), void *v) { + struct rndis_params *params; u8 i; if (!resp_avail) return ERR_PTR(-EINVAL); - for (i = 0; i RNDIS_MAX_CONFIGS; i++) { - if (!rndis_per_dev_params[i].used) { - rndis_per_dev_params[i].used = 1; - rndis_per_dev_params[i].resp_avail = resp_avail; - rndis_per_dev_params[i].v = v; - pr_debug(%s: configNr = %d\n, __func__, i); - return rndis_per_dev_params[i]; + i = rndis_get_nr(); + if (i 0) { + pr_debug(failed\n); + + return ERR_PTR(-ENODEV); + } + + params = kzalloc(sizeof(*params), GFP_KERNEL); + if (!params) { + rndis_put_nr(i); + +
[PATCH 0/3] Eliminate limitation on the number of RNDIS instances
This is meant for 3.21. RNDIS function has a limitation on the number of allowed instances. So far it has been RNDIS_MAX_CONFIGS, which happens to be one. In order to eliminate this kind of arbitrary limitation we should not preallocate a predefined (RNDIS_MAX_CONFIGS) array of struct rndis_params instances but instead allow allocating them on demand. This short series eliminates the limit. The first patch prepares the conversion proper by changing the way each struct rndis_params instance is referenced throughout the API: instead of an index into some array a pointer to actual instance is passed around. The second patch is a small style correction and the third does the conversion proper by changing the way instances of struct rndis_params are allocated: instead of a predefined array they are now allocated on demand. Rebased onto Felipe's testing/next. Andrzej Pietrasiewicz (3): usb: gadget: rndis: use rndis_params instead of configNr usb: gadget: rndis: style correction usb: gadget: rndis: remove the limit of available rndis connections Documentation/usb/gadget-testing.txt | 2 - drivers/usb/gadget/function/f_rndis.c | 60 ++ drivers/usb/gadget/function/rndis.c | 347 +- drivers/usb/gadget/function/rndis.h | 31 +-- drivers/usb/gadget/function/u_rndis.h | 2 - 5 files changed, 205 insertions(+), 237 deletions(-) -- 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
Re: [PATCH V5 6/8] USB: f81232: clarify f81232_ioctl()
Hello. On 2/6/2015 12:46 PM, Peter Hung wrote: We extract TIOCGSERIAL section in f81232_ioctl() to f81232_get_serial_info() to make it clarify You're also changing 'ser.baud_rate' from 460800 to 115200. And explicitly overriding some previously initialized to 0 fields. The f81232_set_mctrl() replace set_control_lines() to do MCR control so we clean-up the set_control_lines() function. I don't see where are you doing this... Signed-off-by: Peter Hung hpeter+linux_ker...@gmail.com --- drivers/usb/serial/f81232.c | 34 +++--- 1 file changed, 23 insertions(+), 11 deletions(-) diff --git a/drivers/usb/serial/f81232.c b/drivers/usb/serial/f81232.c index e1cdf42..4dddb44 100644 --- a/drivers/usb/serial/f81232.c +++ b/drivers/usb/serial/f81232.c @@ -516,24 +516,36 @@ static int f81232_carrier_raised(struct usb_serial_port *port) return 0; } +static int f81232_get_serial_info(struct usb_serial_port *port, + unsigned long arg) +{ + struct serial_struct ser; + + memset(ser, 0, sizeof(ser)); + + ser.flags = ASYNC_SKIP_TEST | ASYNC_AUTO_IRQ; + ser.xmit_fifo_size = port-bulk_out_size; + ser.close_delay = 5 * HZ; + ser.closing_wait= 30 * HZ; + ser.type = PORT_16550A; + ser.line = port-minor; + ser.port = port-port_number; + ser.baud_base = 115200; + + if (copy_to_user((void __user *)arg, ser, sizeof(ser))) + return -EFAULT; + + return 0; +} + static int f81232_ioctl(struct tty_struct *tty, unsigned int cmd, unsigned long arg) { - struct serial_struct ser; struct usb_serial_port *port = tty-driver_data; switch (cmd) { case TIOCGSERIAL: - memset(ser, 0, sizeof ser); - ser.type = PORT_16654; - ser.line = port-minor; - ser.port = port-port_number; - ser.baud_base = 460800; - - if (copy_to_user((void __user *)arg, ser, sizeof ser)) - return -EFAULT; - - return 0; + return f81232_get_serial_info(port, arg); default: break; } WBR, 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: [RFC PATCH 2/2] usb: dwc3: Add chained TRB support for ep0
Hi, On Fri, Feb 06, 2015 at 05:25:35PM +0530, Kishon Vijay Abraham I wrote: dwc3 can do only max packet aligned transfers. So in case request length is not max packet aligned and is bigger than DWC3_EP0_BOUNCE_SIZE two chained TRBs is required to handle the transfer. Signed-off-by: Kishon Vijay Abraham I kis...@ti.com --- *) Did eumeration testing with g_zero in kernel *) Similar patch was added in u-boot. With DFU, was able to create a scenario where the request length is not max packet aligned and is bigger than DWC3_EP0_BOUNCE_SIZE (512 bytes). In that case, 2 chained TRBs will be used. I really need a test case for this. If you have to patch g_zero to have a configuration descriptor so large that it's over 512, so be it, but I really need to have a test case exposing the problem. I also need you to run full USB30CV (for USB2 and USB3 device), together with Link Layer Tests (on USB3-only, clearly) using USB30CV and LeCroy's compliance suite (there's a slight difference from USB30CV and LeCroy's compliance, we must work with both because both are accepted test vectors per USB-IF). diff --git a/drivers/usb/dwc3/ep0.c b/drivers/usb/dwc3/ep0.c index 24b7925..3b728b8 100644 --- a/drivers/usb/dwc3/ep0.c +++ b/drivers/usb/dwc3/ep0.c @@ -56,7 +56,7 @@ static const char *dwc3_ep0_state_string(enum dwc3_ep0_state state) } static int dwc3_ep0_start_trans(struct dwc3 *dwc, u8 epnum, dma_addr_t buf_dma, - u32 len, u32 type) + u32 len, u32 type, unsigned chain) { struct dwc3_gadget_ep_cmd_params params; struct dwc3_trb *trb; @@ -70,7 +70,10 @@ static int dwc3_ep0_start_trans(struct dwc3 *dwc, u8 epnum, dma_addr_t buf_dma, return 0; } - trb = dwc-ep0_trb; + trb = dwc-ep0_trb[dep-free_slot]; + + if (chain) + dep-free_slot++; trb-bpl = lower_32_bits(buf_dma); trb-bph = upper_32_bits(buf_dma); @@ -78,10 +81,17 @@ static int dwc3_ep0_start_trans(struct dwc3 *dwc, u8 epnum, dma_addr_t buf_dma, trb-ctrl = type; trb-ctrl |= (DWC3_TRB_CTRL_HWO - | DWC3_TRB_CTRL_LST - | DWC3_TRB_CTRL_IOC | DWC3_TRB_CTRL_ISP_IMI); + if (chain) + trb-ctrl |= DWC3_TRB_CTRL_CHN; + else + trb-ctrl |= (DWC3_TRB_CTRL_IOC + | DWC3_TRB_CTRL_LST); + + if (chain) + return 0; + memset(params, 0, sizeof(params)); params.param0 = upper_32_bits(dwc-ep0_trb_addr); params.param1 = lower_32_bits(dwc-ep0_trb_addr); @@ -302,7 +312,7 @@ void dwc3_ep0_out_start(struct dwc3 *dwc) int ret; ret = dwc3_ep0_start_trans(dwc, 0, dwc-ctrl_req_addr, 8, - DWC3_TRBCTL_CONTROL_SETUP); + DWC3_TRBCTL_CONTROL_SETUP, false); WARN_ON(ret 0); } @@ -817,6 +827,22 @@ static void dwc3_ep0_complete_data(struct dwc3 *dwc, maxp = ep0-endpoint.maxpacket; + /* Handle the first TRB before handling the bounce buffer if the request + * length is greater than the bounce buffer size + */ + if (!IS_ALIGNED(ur-length, maxp) + ur-length DWC3_EP0_BOUNCE_SIZE) { + transfer_size = (ur-length / maxp) * maxp; you can use ALIGN() for this which is more efficient. Note however that this is not safe, see below. + transferred = transfer_size - length; + buf = (u8 *)buf + transferred; + ur-actual += transferred; this is dangerous. The extra size is because you *must* align OUT to wMaxPacketSize, so you cannot allow more than the original req-length to be copied into buf. That bounce buffer, is really supposed to be a throw-away buffer and should never have data in it. You should really add a big fat WARN() if transferred req-length. The thing is that if host sends more data than we were expecting, this could be someone trying to use our driver as an exploit vector, trying to send more data than it should. We must be robust against that. + + trb++; + length = trb-size DWC3_TRB_SIZE_MASK; + + ep0-free_slot = 0; + } + if (dwc-ep0_bounced) { transfer_size = roundup((ur-length - transfer_size), maxp); @@ -844,7 +870,7 @@ static void dwc3_ep0_complete_data(struct dwc3 *dwc, ret = dwc3_ep0_start_trans(dwc, epnum, dwc-ctrl_req_addr, 0, - DWC3_TRBCTL_CONTROL_DATA); + DWC3_TRBCTL_CONTROL_DATA, false); WARN_ON(ret 0); } } @@ -928,7 +954,7 @@ static void __dwc3_ep0_do_control_data(struct dwc3 *dwc, if (req-request.length == 0) { ret =
Re: [PATCH 2/2] usb: musb: Fix getting a generic phy for musb_dsps
Tony, On Fri, Feb 6, 2015 at 11:23 AM, Tony Lindgren t...@atomide.com wrote: * George Cherian george.cher...@ti.com [150206 05:05]: Hi Tony, You also need to add similar things in dsps_musb_reset(); Otherwise you might not recover from a BABBLE condition. Thank I totally missed that, updated patch below. Do you have some testcase that easily triggers BABBLE on MUSB? I normally just shorten DP or DM to VBUS to trigger babble. No device is connected to the port, if I remembered correctly. Regards, -Bin. Regards, Tony 8 -- From: Tony Lindgren t...@atomide.com Date: Wed, 4 Feb 2015 06:28:49 -0800 Subject: [PATCH] usb: musb: Fix getting a generic phy for musb_dsps We still have a combination of legacy phys and generic phys in use so we need to support both types of phy for musb_dsps.c. Cc: Brian Hutchinson b.hutch...@gmail.com Signed-off-by: Tony Lindgren t...@atomide.com --- a/drivers/usb/musb/musb_dsps.c +++ b/drivers/usb/musb/musb_dsps.c @@ -457,12 +457,27 @@ static int dsps_musb_init(struct musb *musb) if (IS_ERR(musb-xceiv)) return PTR_ERR(musb-xceiv); + musb-phy = devm_phy_get(dev-parent, usb2-phy); + /* Returns zero if e.g. not clocked */ rev = dsps_readl(reg_base, wrp-revision); if (!rev) return -ENODEV; usb_phy_init(musb-xceiv); + if (IS_ERR(musb-phy)) { + musb-phy = NULL; + } else { + ret = phy_init(musb-phy); + if (ret 0) + return ret; + ret = phy_power_on(musb-phy); + if (ret) { + phy_exit(musb-phy); + return ret; + } + } + setup_timer(glue-timer, otg_timer, (unsigned long) musb); /* Reset the musb */ @@ -502,6 +517,8 @@ static int dsps_musb_exit(struct musb *musb) del_timer_sync(glue-timer); usb_phy_shutdown(musb-xceiv); + phy_power_off(musb-phy); + phy_exit(musb-phy); debugfs_remove_recursive(glue-dbgfs_root); return 0; @@ -610,7 +627,7 @@ static int dsps_musb_reset(struct musb *musb) struct device *dev = musb-controller; struct dsps_glue *glue = dev_get_drvdata(dev-parent); const struct dsps_musb_wrapper *wrp = glue-wrp; - int session_restart = 0; + int session_restart = 0, error; if (glue-sw_babble_enabled) session_restart = sw_babble_control(musb); @@ -624,8 +641,14 @@ static int dsps_musb_reset(struct musb *musb) dsps_writel(musb-ctrl_base, wrp-control, (1 wrp-reset)); usleep_range(100, 200); usb_phy_shutdown(musb-xceiv); + error = phy_power_off(musb-phy); + if (error) + dev_err(dev, phy shutdown failed: %i\n, error); usleep_range(100, 200); usb_phy_init(musb-xceiv); + error = phy_power_on(musb-phy); + if (error) + dev_err(dev, phy powerup failed: %i\n, error); session_restart = 1; } -- To unsubscribe from this list: send the line unsubscribe linux-omap in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html -- 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: musb: Fix getting a generic phy for musb_dsps
* George Cherian george.cher...@ti.com [150206 05:05]: Hi Tony, You also need to add similar things in dsps_musb_reset(); Otherwise you might not recover from a BABBLE condition. Thank I totally missed that, updated patch below. Do you have some testcase that easily triggers BABBLE on MUSB? Regards, Tony 8 -- From: Tony Lindgren t...@atomide.com Date: Wed, 4 Feb 2015 06:28:49 -0800 Subject: [PATCH] usb: musb: Fix getting a generic phy for musb_dsps We still have a combination of legacy phys and generic phys in use so we need to support both types of phy for musb_dsps.c. Cc: Brian Hutchinson b.hutch...@gmail.com Signed-off-by: Tony Lindgren t...@atomide.com --- a/drivers/usb/musb/musb_dsps.c +++ b/drivers/usb/musb/musb_dsps.c @@ -457,12 +457,27 @@ static int dsps_musb_init(struct musb *musb) if (IS_ERR(musb-xceiv)) return PTR_ERR(musb-xceiv); + musb-phy = devm_phy_get(dev-parent, usb2-phy); + /* Returns zero if e.g. not clocked */ rev = dsps_readl(reg_base, wrp-revision); if (!rev) return -ENODEV; usb_phy_init(musb-xceiv); + if (IS_ERR(musb-phy)) { + musb-phy = NULL; + } else { + ret = phy_init(musb-phy); + if (ret 0) + return ret; + ret = phy_power_on(musb-phy); + if (ret) { + phy_exit(musb-phy); + return ret; + } + } + setup_timer(glue-timer, otg_timer, (unsigned long) musb); /* Reset the musb */ @@ -502,6 +517,8 @@ static int dsps_musb_exit(struct musb *musb) del_timer_sync(glue-timer); usb_phy_shutdown(musb-xceiv); + phy_power_off(musb-phy); + phy_exit(musb-phy); debugfs_remove_recursive(glue-dbgfs_root); return 0; @@ -610,7 +627,7 @@ static int dsps_musb_reset(struct musb *musb) struct device *dev = musb-controller; struct dsps_glue *glue = dev_get_drvdata(dev-parent); const struct dsps_musb_wrapper *wrp = glue-wrp; - int session_restart = 0; + int session_restart = 0, error; if (glue-sw_babble_enabled) session_restart = sw_babble_control(musb); @@ -624,8 +641,14 @@ static int dsps_musb_reset(struct musb *musb) dsps_writel(musb-ctrl_base, wrp-control, (1 wrp-reset)); usleep_range(100, 200); usb_phy_shutdown(musb-xceiv); + error = phy_power_off(musb-phy); + if (error) + dev_err(dev, phy shutdown failed: %i\n, error); usleep_range(100, 200); usb_phy_init(musb-xceiv); + error = phy_power_on(musb-phy); + if (error) + dev_err(dev, phy powerup failed: %i\n, error); session_restart = 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