Lines Matching +full:vhub +full:- +full:generic +full:- +full:endpoints

1 // SPDX-License-Identifier: GPL-2.0+
3 * aspeed-vhub -- Driver for Aspeed SoC "vHub" USB gadget
5 * epn.c - Generic endpoints management
26 #include <linux/dma-mapping.h>
28 #include "vhub.h"
43 unsigned int act = req->req.actual; in ast_vhub_epn_kick()
44 unsigned int len = req->req.length; in ast_vhub_epn_kick()
48 WARN_ON(req->active); in ast_vhub_epn_kick()
51 chunk = len - act; in ast_vhub_epn_kick()
52 if (chunk > ep->ep.maxpacket) in ast_vhub_epn_kick()
53 chunk = ep->ep.maxpacket; in ast_vhub_epn_kick()
54 else if ((chunk < ep->ep.maxpacket) || !req->req.zero) in ast_vhub_epn_kick()
55 req->last_desc = 1; in ast_vhub_epn_kick()
58 req, act, len, chunk, req->last_desc); in ast_vhub_epn_kick()
61 if (!req->req.dma) { in ast_vhub_epn_kick()
64 if (ep->epn.is_in) { in ast_vhub_epn_kick()
65 memcpy(ep->buf, req->req.buf + act, chunk); in ast_vhub_epn_kick()
66 vhub_dma_workaround(ep->buf); in ast_vhub_epn_kick()
68 writel(ep->buf_dma, ep->epn.regs + AST_VHUB_EP_DESC_BASE); in ast_vhub_epn_kick()
70 if (ep->epn.is_in) in ast_vhub_epn_kick()
71 vhub_dma_workaround(req->req.buf); in ast_vhub_epn_kick()
72 writel(req->req.dma + act, ep->epn.regs + AST_VHUB_EP_DESC_BASE); in ast_vhub_epn_kick()
76 req->active = true; in ast_vhub_epn_kick()
78 ep->epn.regs + AST_VHUB_EP_DESC_STATUS); in ast_vhub_epn_kick()
80 ep->epn.regs + AST_VHUB_EP_DESC_STATUS); in ast_vhub_epn_kick()
90 stat = readl(ep->epn.regs + AST_VHUB_EP_DESC_STATUS); in ast_vhub_epn_handle_ack()
93 req = list_first_entry_or_null(&ep->queue, struct ast_vhub_req, queue); in ast_vhub_epn_handle_ack()
96 stat, ep->epn.is_in, req, req ? req->active : 0); in ast_vhub_epn_handle_ack()
106 if (!req->active) in ast_vhub_epn_handle_ack()
116 req->active = false; in ast_vhub_epn_handle_ack()
122 if (!req->req.dma && !ep->epn.is_in && len) in ast_vhub_epn_handle_ack()
123 memcpy(req->req.buf + req->req.actual, ep->buf, len); in ast_vhub_epn_handle_ack()
126 req->req.actual += len; in ast_vhub_epn_handle_ack()
129 if (len < ep->ep.maxpacket) in ast_vhub_epn_handle_ack()
130 req->last_desc = 1; in ast_vhub_epn_handle_ack()
133 if (req->last_desc >= 0) { in ast_vhub_epn_handle_ack()
135 req = list_first_entry_or_null(&ep->queue, struct ast_vhub_req, in ast_vhub_epn_handle_ack()
142 if (!req || req->active) in ast_vhub_epn_handle_ack()
154 * thus we can only have AST_VHUB_DESCS_COUNT-1 descriptors in ast_vhub_count_free_descs()
157 return (ep->epn.d_last + AST_VHUB_DESCS_COUNT - ep->epn.d_next - 1) & in ast_vhub_count_free_descs()
158 (AST_VHUB_DESCS_COUNT - 1); in ast_vhub_count_free_descs()
165 unsigned int act = req->act_count; in ast_vhub_epn_kick_desc()
166 unsigned int len = req->req.length; in ast_vhub_epn_kick_desc()
170 req->active = true; in ast_vhub_epn_kick_desc()
173 if (req->last_desc >= 0) in ast_vhub_epn_kick_desc()
177 act, len, ep->epn.chunk_max, ast_vhub_count_free_descs(ep)); in ast_vhub_epn_kick_desc()
180 while (ast_vhub_count_free_descs(ep) && req->last_desc < 0) { in ast_vhub_epn_kick_desc()
184 d_num = ep->epn.d_next; in ast_vhub_epn_kick_desc()
185 desc = &ep->epn.descs[d_num]; in ast_vhub_epn_kick_desc()
186 ep->epn.d_next = (d_num + 1) & (AST_VHUB_DESCS_COUNT - 1); in ast_vhub_epn_kick_desc()
189 chunk = len - act; in ast_vhub_epn_kick_desc()
190 if (chunk <= ep->epn.chunk_max) { in ast_vhub_epn_kick_desc()
199 if (!chunk || !req->req.zero || (chunk % ep->ep.maxpacket) != 0) in ast_vhub_epn_kick_desc()
200 req->last_desc = d_num; in ast_vhub_epn_kick_desc()
202 chunk = ep->epn.chunk_max; in ast_vhub_epn_kick_desc()
206 act, len, chunk, req->last_desc, d_num, in ast_vhub_epn_kick_desc()
210 desc->w0 = cpu_to_le32(req->req.dma + act); in ast_vhub_epn_kick_desc()
222 desc->w1 = cpu_to_le32(VHUB_DSC1_IN_SET_LEN(chunk)); in ast_vhub_epn_kick_desc()
223 if (req->last_desc >= 0 || !ast_vhub_count_free_descs(ep)) in ast_vhub_epn_kick_desc()
224 desc->w1 |= cpu_to_le32(VHUB_DSC1_IN_INTERRUPT); in ast_vhub_epn_kick_desc()
227 req->act_count = act = act + chunk; in ast_vhub_epn_kick_desc()
234 writel(VHUB_EP_DMA_SET_CPU_WPTR(ep->epn.d_next), in ast_vhub_epn_kick_desc()
235 ep->epn.regs + AST_VHUB_EP_DESC_STATUS); in ast_vhub_epn_kick_desc()
238 ep->epn.d_next, readl(ep->epn.regs + AST_VHUB_EP_DESC_STATUS)); in ast_vhub_epn_kick_desc()
249 stat = readl(ep->epn.regs + AST_VHUB_EP_DESC_STATUS); in ast_vhub_epn_handle_ack_desc()
250 stat1 = readl(ep->epn.regs + AST_VHUB_EP_DESC_STATUS); in ast_vhub_epn_handle_ack_desc()
257 req = list_first_entry_or_null(&ep->queue, struct ast_vhub_req, queue); in ast_vhub_epn_handle_ack_desc()
259 EPVDBG(ep, "ACK status=%08x is_in=%d ep->d_last=%d..%d\n", in ast_vhub_epn_handle_ack_desc()
260 stat, ep->epn.is_in, ep->epn.d_last, d_last); in ast_vhub_epn_handle_ack_desc()
263 while (ep->epn.d_last != d_last) { in ast_vhub_epn_handle_ack_desc()
269 d_num = ep->epn.d_last; in ast_vhub_epn_handle_ack_desc()
270 desc = &ep->epn.descs[d_num]; in ast_vhub_epn_handle_ack_desc()
271 ep->epn.d_last = (d_num + 1) & (AST_VHUB_DESCS_COUNT - 1); in ast_vhub_epn_handle_ack_desc()
274 len = VHUB_DSC1_IN_LEN(le32_to_cpu(desc->w1)); in ast_vhub_epn_handle_ack_desc()
277 d_num, len, req, req ? req->active : 0); in ast_vhub_epn_handle_ack_desc()
280 if (!req || !req->active) in ast_vhub_epn_handle_ack_desc()
284 req->req.actual += len; in ast_vhub_epn_handle_ack_desc()
287 is_last_desc = req->last_desc == d_num; in ast_vhub_epn_handle_ack_desc()
288 CHECK(ep, is_last_desc == (len < ep->ep.maxpacket || in ast_vhub_epn_handle_ack_desc()
289 (req->req.actual >= req->req.length && in ast_vhub_epn_handle_ack_desc()
290 !req->req.zero)), in ast_vhub_epn_handle_ack_desc()
293 is_last_desc, len, req->req.actual, req->req.length, in ast_vhub_epn_handle_ack_desc()
294 req->req.zero, ep->ep.maxpacket); in ast_vhub_epn_handle_ack_desc()
300 * d_last and ep->d_last should now be equal in ast_vhub_epn_handle_ack_desc()
302 CHECK(ep, d_last == ep->epn.d_last, in ast_vhub_epn_handle_ack_desc()
304 d_last, ep->epn.d_last); in ast_vhub_epn_handle_ack_desc()
306 /* Note: done will drop and re-acquire the lock */ in ast_vhub_epn_handle_ack_desc()
308 req = list_first_entry_or_null(&ep->queue, in ast_vhub_epn_handle_ack_desc()
322 if (ep->epn.desc_mode) in ast_vhub_epn_ack_irq()
333 struct ast_vhub *vhub = ep->vhub; in ast_vhub_epn_queue() local
339 if (!u_req || !u_req->complete || !u_req->buf) { in ast_vhub_epn_queue()
340 dev_warn(&vhub->pdev->dev, "Bogus EPn request ! u_req=%p\n", u_req); in ast_vhub_epn_queue()
342 dev_warn(&vhub->pdev->dev, "complete=%p internal=%d\n", in ast_vhub_epn_queue()
343 u_req->complete, req->internal); in ast_vhub_epn_queue()
345 return -EINVAL; in ast_vhub_epn_queue()
349 if (!ep->epn.enabled || !u_ep->desc || !ep->dev || !ep->d_idx || in ast_vhub_epn_queue()
350 !ep->dev->enabled) { in ast_vhub_epn_queue()
352 return -ESHUTDOWN; in ast_vhub_epn_queue()
360 * - The buffer is aligned to a 8 bytes boundary (HW requirement) in ast_vhub_epn_queue()
361 * - For a OUT endpoint, the request size is a multiple of the EP in ast_vhub_epn_queue()
371 if (ep->epn.desc_mode || in ast_vhub_epn_queue()
372 ((((unsigned long)u_req->buf & 7) == 0) && in ast_vhub_epn_queue()
373 (ep->epn.is_in || !(u_req->length & (u_ep->maxpacket - 1))))) { in ast_vhub_epn_queue()
374 rc = usb_gadget_map_request_by_dev(&vhub->pdev->dev, u_req, in ast_vhub_epn_queue()
375 ep->epn.is_in); in ast_vhub_epn_queue()
377 dev_warn(&vhub->pdev->dev, in ast_vhub_epn_queue()
382 u_req->dma = 0; in ast_vhub_epn_queue()
386 u_req->length, (u32)u_req->dma, u_req->zero, in ast_vhub_epn_queue()
387 u_req->short_not_ok, u_req->no_interrupt, in ast_vhub_epn_queue()
388 ep->epn.is_in); in ast_vhub_epn_queue()
391 u_req->status = -EINPROGRESS; in ast_vhub_epn_queue()
392 u_req->actual = 0; in ast_vhub_epn_queue()
393 req->act_count = 0; in ast_vhub_epn_queue()
394 req->active = false; in ast_vhub_epn_queue()
395 req->last_desc = -1; in ast_vhub_epn_queue()
396 spin_lock_irqsave(&vhub->lock, flags); in ast_vhub_epn_queue()
397 empty = list_empty(&ep->queue); in ast_vhub_epn_queue()
400 list_add_tail(&req->queue, &ep->queue); in ast_vhub_epn_queue()
402 if (ep->epn.desc_mode) in ast_vhub_epn_queue()
407 spin_unlock_irqrestore(&vhub->lock, flags); in ast_vhub_epn_queue()
418 if (ep->epn.desc_mode) in ast_vhub_stop_active_req()
419 writel(VHUB_EP_DMA_CTRL_RESET, ep->epn.regs + AST_VHUB_EP_DMA_CTLSTAT); in ast_vhub_stop_active_req()
421 writel(0, ep->epn.regs + AST_VHUB_EP_DMA_CTLSTAT); in ast_vhub_stop_active_req()
425 state = readl(ep->epn.regs + AST_VHUB_EP_DMA_CTLSTAT); in ast_vhub_stop_active_req()
433 dev_warn(&ep->vhub->pdev->dev, "Timeout waiting for DMA\n"); in ast_vhub_stop_active_req()
440 if (ep->epn.desc_mode) { in ast_vhub_stop_active_req()
451 reg = VHUB_EP_DMA_SET_RPTR(ep->epn.d_next) | in ast_vhub_stop_active_req()
452 VHUB_EP_DMA_SET_CPU_WPTR(ep->epn.d_next); in ast_vhub_stop_active_req()
453 writel(reg, ep->epn.regs + AST_VHUB_EP_DESC_STATUS); in ast_vhub_stop_active_req()
456 writel(ep->epn.dma_conf, in ast_vhub_stop_active_req()
457 ep->epn.regs + AST_VHUB_EP_DMA_CTLSTAT); in ast_vhub_stop_active_req()
460 writel(ep->epn.dma_conf, in ast_vhub_stop_active_req()
461 ep->epn.regs + AST_VHUB_EP_DMA_CTLSTAT); in ast_vhub_stop_active_req()
468 struct ast_vhub *vhub = ep->vhub; in ast_vhub_epn_dequeue() local
471 int rc = -EINVAL; in ast_vhub_epn_dequeue()
473 spin_lock_irqsave(&vhub->lock, flags); in ast_vhub_epn_dequeue()
476 list_for_each_entry (req, &ep->queue, queue) { in ast_vhub_epn_dequeue()
477 if (&req->req == u_req) in ast_vhub_epn_dequeue()
481 if (&req->req == u_req) { in ast_vhub_epn_dequeue()
483 req, req->active); in ast_vhub_epn_dequeue()
484 if (req->active) in ast_vhub_epn_dequeue()
486 ast_vhub_done(ep, req, -ECONNRESET); in ast_vhub_epn_dequeue()
490 spin_unlock_irqrestore(&vhub->lock, flags); in ast_vhub_epn_dequeue()
498 if (WARN_ON(ep->d_idx == 0)) in ast_vhub_update_epn_stall()
500 reg = readl(ep->epn.regs + AST_VHUB_EP_CONFIG); in ast_vhub_update_epn_stall()
501 if (ep->epn.stalled || ep->epn.wedged) in ast_vhub_update_epn_stall()
505 writel(reg, ep->epn.regs + AST_VHUB_EP_CONFIG); in ast_vhub_update_epn_stall()
507 if (!ep->epn.stalled && !ep->epn.wedged) in ast_vhub_update_epn_stall()
508 writel(VHUB_EP_TOGGLE_SET_EPNUM(ep->epn.g_idx), in ast_vhub_update_epn_stall()
509 ep->vhub->regs + AST_VHUB_EP_TOGGLE); in ast_vhub_update_epn_stall()
516 struct ast_vhub *vhub = ep->vhub; in ast_vhub_set_halt_and_wedge() local
521 if (!u_ep || !u_ep->desc) in ast_vhub_set_halt_and_wedge()
522 return -EINVAL; in ast_vhub_set_halt_and_wedge()
523 if (ep->d_idx == 0) in ast_vhub_set_halt_and_wedge()
525 if (ep->epn.is_iso) in ast_vhub_set_halt_and_wedge()
526 return -EOPNOTSUPP; in ast_vhub_set_halt_and_wedge()
528 spin_lock_irqsave(&vhub->lock, flags); in ast_vhub_set_halt_and_wedge()
530 /* Fail with still-busy IN endpoints */ in ast_vhub_set_halt_and_wedge()
531 if (halt && ep->epn.is_in && !list_empty(&ep->queue)) { in ast_vhub_set_halt_and_wedge()
532 spin_unlock_irqrestore(&vhub->lock, flags); in ast_vhub_set_halt_and_wedge()
533 return -EAGAIN; in ast_vhub_set_halt_and_wedge()
535 ep->epn.stalled = halt; in ast_vhub_set_halt_and_wedge()
536 ep->epn.wedged = wedge; in ast_vhub_set_halt_and_wedge()
539 spin_unlock_irqrestore(&vhub->lock, flags); in ast_vhub_set_halt_and_wedge()
557 struct ast_vhub *vhub = ep->vhub; in ast_vhub_epn_disable() local
563 spin_lock_irqsave(&vhub->lock, flags); in ast_vhub_epn_disable()
565 ep->epn.enabled = false; in ast_vhub_epn_disable()
571 writel(0, ep->epn.regs + AST_VHUB_EP_CONFIG); in ast_vhub_epn_disable()
574 imask = VHUB_EP_IRQ(ep->epn.g_idx); in ast_vhub_epn_disable()
575 ep_ier = readl(vhub->regs + AST_VHUB_EP_ACK_IER); in ast_vhub_epn_disable()
577 writel(ep_ier, vhub->regs + AST_VHUB_EP_ACK_IER); in ast_vhub_epn_disable()
578 writel(imask, vhub->regs + AST_VHUB_EP_ACK_ISR); in ast_vhub_epn_disable()
581 ast_vhub_nuke(ep, -ESHUTDOWN); in ast_vhub_epn_disable()
584 ep->ep.desc = NULL; in ast_vhub_epn_disable()
586 spin_unlock_irqrestore(&vhub->lock, flags); in ast_vhub_epn_disable()
596 struct ast_vhub *vhub; in ast_vhub_epn_enable() local
603 return -EINVAL; in ast_vhub_epn_enable()
606 if (!ep->d_idx || !ep->dev || in ast_vhub_epn_enable()
607 desc->bDescriptorType != USB_DT_ENDPOINT || in ast_vhub_epn_enable()
608 maxpacket == 0 || maxpacket > ep->ep.maxpacket) { in ast_vhub_epn_enable()
610 ep->d_idx, ep->dev, desc->bDescriptorType, in ast_vhub_epn_enable()
611 maxpacket, ep->ep.maxpacket); in ast_vhub_epn_enable()
612 return -EINVAL; in ast_vhub_epn_enable()
614 if (ep->d_idx != usb_endpoint_num(desc)) { in ast_vhub_epn_enable()
616 return -EINVAL; in ast_vhub_epn_enable()
619 if (ep->epn.enabled) { in ast_vhub_epn_enable()
621 return -EBUSY; in ast_vhub_epn_enable()
623 dev = ep->dev; in ast_vhub_epn_enable()
624 vhub = ep->vhub; in ast_vhub_epn_enable()
627 if (!dev->driver) { in ast_vhub_epn_enable()
629 dev->driver, dev->gadget.speed); in ast_vhub_epn_enable()
630 return -ESHUTDOWN; in ast_vhub_epn_enable()
634 ep->epn.is_in = usb_endpoint_dir_in(desc); in ast_vhub_epn_enable()
635 ep->ep.maxpacket = maxpacket; in ast_vhub_epn_enable()
637 ep->epn.d_next = ep->epn.d_last = 0; in ast_vhub_epn_enable()
638 ep->epn.is_iso = false; in ast_vhub_epn_enable()
639 ep->epn.stalled = false; in ast_vhub_epn_enable()
640 ep->epn.wedged = false; in ast_vhub_epn_enable()
643 ep->epn.is_in ? "in" : "out", usb_ep_type_string(type), in ast_vhub_epn_enable()
647 ep->epn.desc_mode = ep->epn.descs && ep->epn.is_in; in ast_vhub_epn_enable()
648 if (ep->epn.desc_mode) in ast_vhub_epn_enable()
649 memset(ep->epn.descs, 0, 8 * AST_VHUB_DESCS_COUNT); in ast_vhub_epn_enable()
655 ep->epn.chunk_max = ep->ep.maxpacket; in ast_vhub_epn_enable()
656 if (ep->epn.is_in) { in ast_vhub_epn_enable()
657 ep->epn.chunk_max <<= 3; in ast_vhub_epn_enable()
658 while (ep->epn.chunk_max > 4095) in ast_vhub_epn_enable()
659 ep->epn.chunk_max -= ep->ep.maxpacket; in ast_vhub_epn_enable()
665 return -EINVAL; in ast_vhub_epn_enable()
674 ep->epn.is_iso = true; in ast_vhub_epn_enable()
677 return -EINVAL; in ast_vhub_epn_enable()
683 if (!ep->epn.is_in) in ast_vhub_epn_enable()
687 ep_conf |= VHUB_EP_CFG_SET_DEV(dev->index + 1); in ast_vhub_epn_enable()
690 spin_lock_irqsave(&vhub->lock, flags); in ast_vhub_epn_enable()
693 writel(0, ep->epn.regs + AST_VHUB_EP_CONFIG); in ast_vhub_epn_enable()
695 ep->epn.regs + AST_VHUB_EP_DMA_CTLSTAT); in ast_vhub_epn_enable()
698 writel(ep_conf, ep->epn.regs + AST_VHUB_EP_CONFIG); in ast_vhub_epn_enable()
700 if (ep->epn.desc_mode) { in ast_vhub_epn_enable()
702 writel(0, ep->epn.regs + AST_VHUB_EP_DESC_STATUS); in ast_vhub_epn_enable()
705 writel(ep->epn.descs_dma, in ast_vhub_epn_enable()
706 ep->epn.regs + AST_VHUB_EP_DESC_BASE); in ast_vhub_epn_enable()
709 ep->epn.dma_conf = VHUB_EP_DMA_DESC_MODE; in ast_vhub_epn_enable()
710 if (ep->epn.is_in) in ast_vhub_epn_enable()
711 ep->epn.dma_conf |= VHUB_EP_DMA_IN_LONG_MODE; in ast_vhub_epn_enable()
714 writel(ep->epn.dma_conf | VHUB_EP_DMA_CTRL_RESET, in ast_vhub_epn_enable()
715 ep->epn.regs + AST_VHUB_EP_DMA_CTLSTAT); in ast_vhub_epn_enable()
718 writel(ep->epn.dma_conf, in ast_vhub_epn_enable()
719 ep->epn.regs + AST_VHUB_EP_DMA_CTLSTAT); in ast_vhub_epn_enable()
722 ep->epn.dma_conf = VHUB_EP_DMA_SINGLE_STAGE; in ast_vhub_epn_enable()
725 writel(ep->epn.dma_conf | VHUB_EP_DMA_CTRL_RESET, in ast_vhub_epn_enable()
726 ep->epn.regs + AST_VHUB_EP_DMA_CTLSTAT); in ast_vhub_epn_enable()
727 writel(ep->epn.dma_conf, in ast_vhub_epn_enable()
728 ep->epn.regs + AST_VHUB_EP_DMA_CTLSTAT); in ast_vhub_epn_enable()
729 writel(0, ep->epn.regs + AST_VHUB_EP_DESC_STATUS); in ast_vhub_epn_enable()
733 writel(VHUB_EP_TOGGLE_SET_EPNUM(ep->epn.g_idx), in ast_vhub_epn_enable()
734 vhub->regs + AST_VHUB_EP_TOGGLE); in ast_vhub_epn_enable()
737 imask = VHUB_EP_IRQ(ep->epn.g_idx); in ast_vhub_epn_enable()
738 writel(imask, vhub->regs + AST_VHUB_EP_ACK_ISR); in ast_vhub_epn_enable()
739 ep_ier = readl(vhub->regs + AST_VHUB_EP_ACK_IER); in ast_vhub_epn_enable()
741 writel(ep_ier, vhub->regs + AST_VHUB_EP_ACK_IER); in ast_vhub_epn_enable()
744 ep->epn.enabled = true; in ast_vhub_epn_enable()
746 spin_unlock_irqrestore(&vhub->lock, flags); in ast_vhub_epn_enable()
755 if (WARN_ON(!ep->dev || !ep->d_idx)) in ast_vhub_epn_dispose()
761 list_del_init(&ep->ep.ep_list); in ast_vhub_epn_dispose()
764 ep->dev->epns[ep->d_idx - 1] = NULL; in ast_vhub_epn_dispose()
767 kfree(ep->ep.name); in ast_vhub_epn_dispose()
768 ep->ep.name = NULL; in ast_vhub_epn_dispose()
769 dma_free_coherent(&ep->vhub->pdev->dev, in ast_vhub_epn_dispose()
772 ep->buf, ep->buf_dma); in ast_vhub_epn_dispose()
773 ep->buf = NULL; in ast_vhub_epn_dispose()
774 ep->epn.descs = NULL; in ast_vhub_epn_dispose()
777 ep->dev = NULL; in ast_vhub_epn_dispose()
794 struct ast_vhub *vhub = d->vhub; in ast_vhub_alloc_epn() local
800 spin_lock_irqsave(&vhub->lock, flags); in ast_vhub_alloc_epn()
801 for (i = 0; i < vhub->max_epns; i++) in ast_vhub_alloc_epn()
802 if (vhub->epns[i].dev == NULL) in ast_vhub_alloc_epn()
804 if (i >= vhub->max_epns) { in ast_vhub_alloc_epn()
805 spin_unlock_irqrestore(&vhub->lock, flags); in ast_vhub_alloc_epn()
810 ep = &vhub->epns[i]; in ast_vhub_alloc_epn()
811 ep->dev = d; in ast_vhub_alloc_epn()
812 spin_unlock_irqrestore(&vhub->lock, flags); in ast_vhub_alloc_epn()
815 INIT_LIST_HEAD(&ep->queue); in ast_vhub_alloc_epn()
816 ep->d_idx = addr; in ast_vhub_alloc_epn()
817 ep->vhub = vhub; in ast_vhub_alloc_epn()
818 ep->ep.ops = &ast_vhub_epn_ops; in ast_vhub_alloc_epn()
819 ep->ep.name = kasprintf(GFP_KERNEL, "ep%d", addr); in ast_vhub_alloc_epn()
820 d->epns[addr-1] = ep; in ast_vhub_alloc_epn()
821 ep->epn.g_idx = i; in ast_vhub_alloc_epn()
822 ep->epn.regs = vhub->regs + 0x200 + (i * 0x10); in ast_vhub_alloc_epn()
824 ep->buf = dma_alloc_coherent(&vhub->pdev->dev, in ast_vhub_alloc_epn()
827 &ep->buf_dma, GFP_KERNEL); in ast_vhub_alloc_epn()
828 if (!ep->buf) { in ast_vhub_alloc_epn()
829 kfree(ep->ep.name); in ast_vhub_alloc_epn()
830 ep->ep.name = NULL; in ast_vhub_alloc_epn()
833 ep->epn.descs = ep->buf + AST_VHUB_EPn_MAX_PACKET; in ast_vhub_alloc_epn()
834 ep->epn.descs_dma = ep->buf_dma + AST_VHUB_EPn_MAX_PACKET; in ast_vhub_alloc_epn()
836 usb_ep_set_maxpacket_limit(&ep->ep, AST_VHUB_EPn_MAX_PACKET); in ast_vhub_alloc_epn()
837 list_add_tail(&ep->ep.ep_list, &d->gadget.ep_list); in ast_vhub_alloc_epn()
838 ep->ep.caps.type_iso = true; in ast_vhub_alloc_epn()
839 ep->ep.caps.type_bulk = true; in ast_vhub_alloc_epn()
840 ep->ep.caps.type_int = true; in ast_vhub_alloc_epn()
841 ep->ep.caps.dir_in = true; in ast_vhub_alloc_epn()
842 ep->ep.caps.dir_out = true; in ast_vhub_alloc_epn()