|
@@ -836,10 +836,9 @@ static void xpad_irq_out(struct urb *urb)
|
|
spin_unlock_irqrestore(&xpad->odata_lock, flags);
|
|
spin_unlock_irqrestore(&xpad->odata_lock, flags);
|
|
}
|
|
}
|
|
|
|
|
|
-static int xpad_init_output(struct usb_interface *intf, struct usb_xpad *xpad)
|
|
|
|
|
|
+static int xpad_init_output(struct usb_interface *intf, struct usb_xpad *xpad,
|
|
|
|
+ struct usb_endpoint_descriptor *ep_irq_out)
|
|
{
|
|
{
|
|
- struct usb_endpoint_descriptor *ep_irq_out;
|
|
|
|
- int ep_irq_out_idx;
|
|
|
|
int error;
|
|
int error;
|
|
|
|
|
|
if (xpad->xtype == XTYPE_UNKNOWN)
|
|
if (xpad->xtype == XTYPE_UNKNOWN)
|
|
@@ -860,10 +859,6 @@ static int xpad_init_output(struct usb_interface *intf, struct usb_xpad *xpad)
|
|
goto err_free_coherent;
|
|
goto err_free_coherent;
|
|
}
|
|
}
|
|
|
|
|
|
- /* Xbox One controller has in/out endpoints swapped. */
|
|
|
|
- ep_irq_out_idx = xpad->xtype == XTYPE_XBOXONE ? 0 : 1;
|
|
|
|
- ep_irq_out = &intf->cur_altsetting->endpoint[ep_irq_out_idx].desc;
|
|
|
|
-
|
|
|
|
usb_fill_int_urb(xpad->irq_out, xpad->udev,
|
|
usb_fill_int_urb(xpad->irq_out, xpad->udev,
|
|
usb_sndintpipe(xpad->udev, ep_irq_out->bEndpointAddress),
|
|
usb_sndintpipe(xpad->udev, ep_irq_out->bEndpointAddress),
|
|
xpad->odata, XPAD_PKT_LEN,
|
|
xpad->odata, XPAD_PKT_LEN,
|
|
@@ -1447,8 +1442,7 @@ static int xpad_probe(struct usb_interface *intf, const struct usb_device_id *id
|
|
{
|
|
{
|
|
struct usb_device *udev = interface_to_usbdev(intf);
|
|
struct usb_device *udev = interface_to_usbdev(intf);
|
|
struct usb_xpad *xpad;
|
|
struct usb_xpad *xpad;
|
|
- struct usb_endpoint_descriptor *ep_irq_in;
|
|
|
|
- int ep_irq_in_idx;
|
|
|
|
|
|
+ struct usb_endpoint_descriptor *ep_irq_in, *ep_irq_out;
|
|
int i, error;
|
|
int i, error;
|
|
|
|
|
|
if (intf->cur_altsetting->desc.bNumEndpoints != 2)
|
|
if (intf->cur_altsetting->desc.bNumEndpoints != 2)
|
|
@@ -1518,13 +1512,26 @@ static int xpad_probe(struct usb_interface *intf, const struct usb_device_id *id
|
|
goto err_free_in_urb;
|
|
goto err_free_in_urb;
|
|
}
|
|
}
|
|
|
|
|
|
- error = xpad_init_output(intf, xpad);
|
|
|
|
- if (error)
|
|
|
|
|
|
+ ep_irq_in = ep_irq_out = NULL;
|
|
|
|
+
|
|
|
|
+ for (i = 0; i < 2; i++) {
|
|
|
|
+ struct usb_endpoint_descriptor *ep =
|
|
|
|
+ &intf->cur_altsetting->endpoint[i].desc;
|
|
|
|
+
|
|
|
|
+ if (usb_endpoint_dir_in(ep))
|
|
|
|
+ ep_irq_in = ep;
|
|
|
|
+ else
|
|
|
|
+ ep_irq_out = ep;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if (!ep_irq_in || !ep_irq_out) {
|
|
|
|
+ error = -ENODEV;
|
|
goto err_free_in_urb;
|
|
goto err_free_in_urb;
|
|
|
|
+ }
|
|
|
|
|
|
- /* Xbox One controller has in/out endpoints swapped. */
|
|
|
|
- ep_irq_in_idx = xpad->xtype == XTYPE_XBOXONE ? 1 : 0;
|
|
|
|
- ep_irq_in = &intf->cur_altsetting->endpoint[ep_irq_in_idx].desc;
|
|
|
|
|
|
+ error = xpad_init_output(intf, xpad, ep_irq_out);
|
|
|
|
+ if (error)
|
|
|
|
+ goto err_free_in_urb;
|
|
|
|
|
|
usb_fill_int_urb(xpad->irq_in, udev,
|
|
usb_fill_int_urb(xpad->irq_in, udev,
|
|
usb_rcvintpipe(udev, ep_irq_in->bEndpointAddress),
|
|
usb_rcvintpipe(udev, ep_irq_in->bEndpointAddress),
|