1 // SPDX-License-Identifier: GPL-2.0-or-later 2 /* 3 * Copyright (c) 2000-2002 Vojtech Pavlik <vojtech@ucw.cz> 4 * Copyright (c) 2001-2002, 2007 Johann Deneux <johann.deneux@gmail.com> 5 * 6 * USB/RS232 I-Force joysticks and wheels. 7 */ 8 9 #include <linux/usb.h> 10 #include "iforce.h" 11 12 struct iforce_usb { 13 struct iforce iforce; 14 15 struct usb_device *usbdev; 16 struct usb_interface *intf; 17 struct urb *irq, *out; 18 19 u8 data_in[IFORCE_MAX_LENGTH] ____cacheline_aligned; 20 u8 data_out[IFORCE_MAX_LENGTH] ____cacheline_aligned; 21 }; 22 23 static void __iforce_usb_xmit(struct iforce *iforce) 24 { 25 struct iforce_usb *iforce_usb = container_of(iforce, struct iforce_usb, 26 iforce); 27 int n, c; 28 29 guard(spinlock_irqsave)(&iforce->xmit_lock); 30 31 if (iforce->xmit.head == iforce->xmit.tail) { 32 iforce_clear_xmit_and_wake(iforce); 33 return; 34 } 35 36 ((char *)iforce_usb->out->transfer_buffer)[0] = iforce->xmit.buf[iforce->xmit.tail]; 37 XMIT_INC(iforce->xmit.tail, 1); 38 n = iforce->xmit.buf[iforce->xmit.tail]; 39 XMIT_INC(iforce->xmit.tail, 1); 40 41 iforce_usb->out->transfer_buffer_length = n + 1; 42 iforce_usb->out->dev = iforce_usb->usbdev; 43 44 /* Copy rest of data then */ 45 c = CIRC_CNT_TO_END(iforce->xmit.head, iforce->xmit.tail, XMIT_SIZE); 46 if (n < c) 47 c = n; 48 49 memcpy(iforce_usb->out->transfer_buffer + 1, 50 &iforce->xmit.buf[iforce->xmit.tail], 51 c); 52 if (n != c) { 53 memcpy(iforce_usb->out->transfer_buffer + 1 + c, 54 &iforce->xmit.buf[0], 55 n - c); 56 } 57 XMIT_INC(iforce->xmit.tail, n); 58 59 n=usb_submit_urb(iforce_usb->out, GFP_ATOMIC); 60 if (n) { 61 dev_warn(&iforce_usb->intf->dev, 62 "usb_submit_urb failed %d\n", n); 63 iforce_clear_xmit_and_wake(iforce); 64 } 65 66 /* The IFORCE_XMIT_RUNNING bit is not cleared here. That's intended. 67 * As long as the urb completion handler is not called, the transmiting 68 * is considered to be running */ 69 } 70 71 static void iforce_usb_xmit(struct iforce *iforce) 72 { 73 if (!test_and_set_bit(IFORCE_XMIT_RUNNING, iforce->xmit_flags)) 74 __iforce_usb_xmit(iforce); 75 } 76 77 static int iforce_usb_get_id(struct iforce *iforce, u8 id, 78 u8 *response_data, size_t *response_len) 79 { 80 struct iforce_usb *iforce_usb = container_of(iforce, struct iforce_usb, 81 iforce); 82 u8 *buf; 83 int status; 84 85 buf = kmalloc(IFORCE_MAX_LENGTH, GFP_KERNEL); 86 if (!buf) 87 return -ENOMEM; 88 89 status = usb_control_msg(iforce_usb->usbdev, 90 usb_rcvctrlpipe(iforce_usb->usbdev, 0), 91 id, 92 USB_TYPE_VENDOR | USB_DIR_IN | 93 USB_RECIP_INTERFACE, 94 0, 0, buf, IFORCE_MAX_LENGTH, 1000); 95 if (status < 0) { 96 dev_err(&iforce_usb->intf->dev, 97 "usb_submit_urb failed: %d\n", status); 98 } else if (buf[0] != id) { 99 status = -EIO; 100 } else { 101 memcpy(response_data, buf, status); 102 *response_len = status; 103 status = 0; 104 } 105 106 kfree(buf); 107 return status; 108 } 109 110 static int iforce_usb_start_io(struct iforce *iforce) 111 { 112 struct iforce_usb *iforce_usb = container_of(iforce, struct iforce_usb, 113 iforce); 114 115 if (usb_submit_urb(iforce_usb->irq, GFP_KERNEL)) 116 return -EIO; 117 118 return 0; 119 } 120 121 static void iforce_usb_stop_io(struct iforce *iforce) 122 { 123 struct iforce_usb *iforce_usb = container_of(iforce, struct iforce_usb, 124 iforce); 125 126 usb_kill_urb(iforce_usb->irq); 127 usb_kill_urb(iforce_usb->out); 128 } 129 130 static const struct iforce_xport_ops iforce_usb_xport_ops = { 131 .xmit = iforce_usb_xmit, 132 .get_id = iforce_usb_get_id, 133 .start_io = iforce_usb_start_io, 134 .stop_io = iforce_usb_stop_io, 135 }; 136 137 static void iforce_usb_irq(struct urb *urb) 138 { 139 struct iforce_usb *iforce_usb = urb->context; 140 struct iforce *iforce = &iforce_usb->iforce; 141 struct device *dev = &iforce_usb->intf->dev; 142 int status; 143 144 switch (urb->status) { 145 case 0: 146 /* success */ 147 break; 148 case -ECONNRESET: 149 case -ENOENT: 150 case -ESHUTDOWN: 151 /* this urb is terminated, clean up */ 152 dev_dbg(dev, "%s - urb shutting down with status: %d\n", 153 __func__, urb->status); 154 return; 155 default: 156 dev_dbg(dev, "%s - urb has status of: %d\n", 157 __func__, urb->status); 158 goto exit; 159 } 160 161 iforce_process_packet(iforce, iforce_usb->data_in[0], 162 iforce_usb->data_in + 1, urb->actual_length - 1); 163 164 exit: 165 status = usb_submit_urb(urb, GFP_ATOMIC); 166 if (status) 167 dev_err(dev, "%s - usb_submit_urb failed with result %d\n", 168 __func__, status); 169 } 170 171 static void iforce_usb_out(struct urb *urb) 172 { 173 struct iforce_usb *iforce_usb = urb->context; 174 struct iforce *iforce = &iforce_usb->iforce; 175 176 if (urb->status) { 177 dev_dbg(&iforce_usb->intf->dev, "urb->status %d, exiting\n", 178 urb->status); 179 iforce_clear_xmit_and_wake(iforce); 180 return; 181 } 182 183 __iforce_usb_xmit(iforce); 184 185 wake_up_all(&iforce->wait); 186 } 187 188 static int iforce_usb_probe(struct usb_interface *intf, 189 const struct usb_device_id *id) 190 { 191 struct usb_device *dev = interface_to_usbdev(intf); 192 struct usb_host_interface *interface; 193 struct usb_endpoint_descriptor *epirq, *epout; 194 struct iforce_usb *iforce_usb; 195 int err = -ENOMEM; 196 197 interface = intf->cur_altsetting; 198 199 if (interface->desc.bNumEndpoints < 2) 200 return -ENODEV; 201 202 epirq = &interface->endpoint[0].desc; 203 if (!usb_endpoint_is_int_in(epirq)) 204 return -ENODEV; 205 206 epout = &interface->endpoint[1].desc; 207 if (!usb_endpoint_is_int_out(epout)) 208 return -ENODEV; 209 210 iforce_usb = kzalloc(sizeof(*iforce_usb), GFP_KERNEL); 211 if (!iforce_usb) 212 goto fail; 213 214 iforce_usb->irq = usb_alloc_urb(0, GFP_KERNEL); 215 if (!iforce_usb->irq) 216 goto fail; 217 218 iforce_usb->out = usb_alloc_urb(0, GFP_KERNEL); 219 if (!iforce_usb->out) 220 goto fail; 221 222 iforce_usb->iforce.xport_ops = &iforce_usb_xport_ops; 223 224 iforce_usb->usbdev = dev; 225 iforce_usb->intf = intf; 226 227 usb_fill_int_urb(iforce_usb->irq, dev, 228 usb_rcvintpipe(dev, epirq->bEndpointAddress), 229 iforce_usb->data_in, sizeof(iforce_usb->data_in), 230 iforce_usb_irq, iforce_usb, epirq->bInterval); 231 232 usb_fill_int_urb(iforce_usb->out, dev, 233 usb_sndintpipe(dev, epout->bEndpointAddress), 234 iforce_usb->data_out, sizeof(iforce_usb->data_out), 235 iforce_usb_out, iforce_usb, epout->bInterval); 236 237 err = iforce_init_device(&intf->dev, BUS_USB, &iforce_usb->iforce); 238 if (err) 239 goto fail; 240 241 usb_set_intfdata(intf, iforce_usb); 242 return 0; 243 244 fail: 245 if (iforce_usb) { 246 usb_free_urb(iforce_usb->irq); 247 usb_free_urb(iforce_usb->out); 248 kfree(iforce_usb); 249 } 250 251 return err; 252 } 253 254 static void iforce_usb_disconnect(struct usb_interface *intf) 255 { 256 struct iforce_usb *iforce_usb = usb_get_intfdata(intf); 257 258 usb_set_intfdata(intf, NULL); 259 260 input_unregister_device(iforce_usb->iforce.dev); 261 262 usb_free_urb(iforce_usb->irq); 263 usb_free_urb(iforce_usb->out); 264 265 kfree(iforce_usb); 266 } 267 268 static const struct usb_device_id iforce_usb_ids[] = { 269 { USB_DEVICE(0x044f, 0xa01c) }, /* Thrustmaster Motor Sport GT */ 270 { USB_DEVICE(0x046d, 0xc281) }, /* Logitech WingMan Force */ 271 { USB_DEVICE(0x046d, 0xc291) }, /* Logitech WingMan Formula Force */ 272 { USB_DEVICE(0x05ef, 0x020a) }, /* AVB Top Shot Pegasus */ 273 { USB_DEVICE(0x05ef, 0x8884) }, /* AVB Mag Turbo Force */ 274 { USB_DEVICE(0x05ef, 0x8888) }, /* AVB Top Shot FFB Racing Wheel */ 275 { USB_DEVICE(0x061c, 0xc0a4) }, /* ACT LABS Force RS */ 276 { USB_DEVICE(0x061c, 0xc084) }, /* ACT LABS Force RS */ 277 { USB_DEVICE(0x06a3, 0xff04) }, /* Saitek R440 Force Wheel */ 278 { USB_DEVICE(0x06f8, 0x0001) }, /* Guillemot Race Leader Force Feedback */ 279 { USB_DEVICE(0x06f8, 0x0003) }, /* Guillemot Jet Leader Force Feedback */ 280 { USB_DEVICE(0x06f8, 0x0004) }, /* Guillemot Force Feedback Racing Wheel */ 281 { USB_DEVICE(0x06f8, 0xa302) }, /* Guillemot Jet Leader 3D */ 282 { } /* Terminating entry */ 283 }; 284 285 MODULE_DEVICE_TABLE (usb, iforce_usb_ids); 286 287 struct usb_driver iforce_usb_driver = { 288 .name = "iforce", 289 .probe = iforce_usb_probe, 290 .disconnect = iforce_usb_disconnect, 291 .id_table = iforce_usb_ids, 292 }; 293 294 module_usb_driver(iforce_usb_driver); 295 296 MODULE_AUTHOR("Vojtech Pavlik <vojtech@ucw.cz>, Johann Deneux <johann.deneux@gmail.com>"); 297 MODULE_DESCRIPTION("USB I-Force joysticks and wheels driver"); 298 MODULE_LICENSE("GPL"); 299