[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