[SLOF] [PATCH v2 8/8] usb-xhci: add keyboard support
Nikunj A Dadhania
nikunj at linux.vnet.ibm.com
Mon Oct 5 15:27:54 AEDT 2015
Alexey Kardashevskiy <aik at ozlabs.ru> writes:
> On 09/18/2015 07:54 PM, Nikunj A Dadhania wrote:
>>
>> Missed a hunk in code re-org:
>>
>> @@ -616,6 +617,7 @@ static void xhci_free_dev(struct xhci_dev *xdev)
>> {
>> xhci_free_seg(&xdev->bulk_in, XHCI_DATA_TRBS_SIZE);
>> xhci_free_seg(&xdev->bulk_out, XHCI_DATA_TRBS_SIZE);
>> + xhci_free_seg(&xdev->intr, XHCI_INTR_TRBS_SIZE);
>> xhci_free_seg(&xdev->control, XHCI_CONTROL_TRBS_SIZE);
>> xhci_free_ctx(&xdev->in_ctx, XHCI_CTX_BUF_SIZE);
>> xhci_free_ctx(&xdev->out_ctx, XHCI_CTX_BUF_SIZE);
>>
>> And added following in pipe cleanup path:
>>
>> @@ -1404,6 +1405,10 @@ static void xhci_put_pipe(struct usb_pipe *pipe)
>> if (pipe->type == USB_EP_TYPE_BULK) {
>> xpipe = xhci_pipe_get_xpipe(pipe);
>> xpipe->seg = NULL;
>> + } else if (pipe->type == USB_EP_TYPE_INTR) {
>> + xpipe = xhci_pipe_get_xpipe(pipe);
>> + SLOF_dma_map_out(xpipe->buf_phys, xpipe->buf, xpipe->buflen);
>> + xpipe->seg = NULL;
>> }
>> if (xhcd->end)
>> xhcd->end->next = pipe;
>
>
> So you'll repost, right? You can repost just this patch and I'll take the
> rest from this series.
I will repost just this patch. As nothing got changed in the previous
patches.
>
>
>
>> Nikunj A Dadhania <nikunj at linux.vnet.ibm.com> writes:
>>
>>> Add support for xhci interrupt pipes needed for keyboard handling
>>>
>>> Signed-off-by: Nikunj A Dadhania <nikunj at linux.vnet.ibm.com>
>>> ---
>>> lib/libusb/usb-xhci.c | 110 +++++++++++++++++++++++++++++++++++++++++++++++++-
>>> lib/libusb/usb-xhci.h | 5 +++
>>> 2 files changed, 114 insertions(+), 1 deletion(-)
>>
>> From: Nikunj A Dadhania <nikunj at linux.vnet.ibm.com>
>> Subject: usb-xhci: add keyboard support
>>
>> Add support for xhci interrupt pipes needed for keyboard handling
>>
>> Signed-off-by: Nikunj A Dadhania <nikunj at linux.vnet.ibm.com>
>> ---
>> lib/libusb/usb-xhci.c | 115 +++++++++++++++++++++++++++++++++++++++++++++++++-
>> lib/libusb/usb-xhci.h | 5 +++
>> 2 files changed, 119 insertions(+), 1 deletion(-)
>>
>> diff --git a/lib/libusb/usb-xhci.c b/lib/libusb/usb-xhci.c
>> index c4fe7ca..04d32c9 100644
>> --- a/lib/libusb/usb-xhci.c
>> +++ b/lib/libusb/usb-xhci.c
>> @@ -623,6 +623,7 @@ static void xhci_free_dev(struct xhci_dev *xdev)
>> {
>> xhci_free_seg(&xdev->bulk_in, XHCI_DATA_TRBS_SIZE);
>> xhci_free_seg(&xdev->bulk_out, XHCI_DATA_TRBS_SIZE);
>> + xhci_free_seg(&xdev->intr, XHCI_INTR_TRBS_SIZE);
>> xhci_free_seg(&xdev->control, XHCI_CONTROL_TRBS_SIZE);
>> xhci_free_ctx(&xdev->in_ctx, XHCI_CTX_BUF_SIZE);
>> xhci_free_ctx(&xdev->out_ctx, XHCI_CTX_BUF_SIZE);
>> @@ -1149,6 +1150,7 @@ static uint64_t xhci_get_trb_phys(struct xhci_seg *seg, uint64_t trb)
>> return seg->trbs_dma + (trb - (uint64_t)seg->trbs);
>> }
>>
>> +static int usb_kb = false;
>> static int xhci_transfer_bulk(struct usb_pipe *pipe, void *td, void *td_phys,
>> void *data, int datalen)
>> {
>> @@ -1198,7 +1200,8 @@ static int xhci_transfer_bulk(struct usb_pipe *pipe, void *td, void *td_phys,
>> } else if (event_phys == 0) { /* polling timed out */
>> ret = false;
>> break;
>> - }
>> + } else
>> + usb_kb = true;
>>
>> /* transfer timed out */
>> if (time < SLOF_GetTimer())
>> @@ -1293,6 +1296,61 @@ static void xhci_init_bulk_ep(struct usb_dev *dev, struct usb_pipe *pipe)
>> xpipe->seg = seg;
>> }
>>
>> +static int xhci_get_pipe_intr(struct usb_pipe *pipe,
>> + struct xhci_hcd *xhcd,
>> + char *buf, size_t len)
>> +{
>> + struct xhci_dev *xdev;
>> + struct xhci_seg *seg;
>> + struct xhci_pipe *xpipe;
>> + struct xhci_control_ctx *ctrl;
>> + struct xhci_ep_ctx *ep;
>> + uint32_t x_epno, val, type;
>> + struct usb_dev *dev;
>> + struct xhci_transfer_trb *trb;
>> +
>> + dev = pipe->dev;
>> + if (dev->class != DEV_HID_KEYB)
>> + return false;
>> +
>> + xdev = dev->priv;
>> + pipe->mps = 8;
>> + seg = xhci_pipe_get_seg(pipe);
>> + xpipe = xhci_pipe_get_xpipe(pipe);
>> + type = EP_INT_IN;
>> + seg = &xdev->intr;
>> +
>> + if (!seg->trbs) {
>> + if (!xhci_alloc_seg(seg, XHCI_INTR_TRBS_SIZE, TYPE_BULK)) {
>> + printf("usb-xhci: allocation failed for interrupt endpoint\n");
>> + return false;
>> + }
>> + } else {
>> + xhci_init_seg(seg, XHCI_EVENT_TRBS_SIZE, TYPE_BULK);
>> + }
>> +
>> + xpipe->buf = buf;
>> + xpipe->buf_phys = SLOF_dma_map_in(buf, len, false);
>> + xpipe->buflen = len;
>> +
>> + ctrl = xhci_get_control_ctx(&xdev->in_ctx);
>> + x_epno = xhci_get_epno(pipe);
>> + ep = xhci_get_ep_ctx(&xdev->in_ctx, xdev->ctx_size, x_epno);
>> + val = EP_TYPE(type) | MAX_BURST(0) | ERROR_COUNT(3) |
>> + MAX_PACKET_SIZE(pipe->mps);
>> + ep->field2 = cpu_to_le32(val);
>> + ep->deq_addr = cpu_to_le64(seg->trbs_dma | seg->cycle_state);
>> + ep->field4 = cpu_to_le32(8);
>> + ctrl->a_flags = cpu_to_le32(BIT(x_epno) | 0x1);
>> + ctrl->d_flags = 0;
>> + xhci_configure_ep(xhcd, xdev->slot_id, xdev->in_ctx.dma_addr);
>> + xpipe->seg = seg;
>> +
>> + trb = xhci_get_trb(seg);
>> + fill_normal_trb(trb, (void *)xpipe->buf_phys, pipe->mps);
>> + return true;
>> +}
>> +
>> static struct usb_pipe* xhci_get_pipe(struct usb_dev *dev, struct usb_ep_descr *ep, char *buf, size_t len)
>> {
>> struct xhci_hcd *xhcd;
>> @@ -1322,6 +1380,11 @@ static struct usb_pipe* xhci_get_pipe(struct usb_dev *dev, struct usb_ep_descr *
>> new->dir = (ep->bEndpointAddress & 0x80) >> 7;
>> new->epno = ep->bEndpointAddress & 0x0f;
>>
>> + if (new->type == USB_EP_TYPE_INTR)
>> + if (!xhci_get_pipe_intr(new, xhcd, buf, len)) {
>> + printf("usb-xhci: %s alloc_intr failed %p\n",
>> + __func__, new);
>> + }
>
>
> Some consistency would not hurt, add {} for the outer if().
Sure, will add that.
Nikunj
More information about the SLOF
mailing list