diff options
-rw-r--r-- | drivers/usb/serial/keyspan.c | 49 |
1 files changed, 45 insertions, 4 deletions
diff --git a/drivers/usb/serial/keyspan.c b/drivers/usb/serial/keyspan.c index 9d2fdfd6865f..e6966f12ed5a 100644 --- a/drivers/usb/serial/keyspan.c +++ b/drivers/usb/serial/keyspan.c | |||
@@ -1275,11 +1275,31 @@ static int keyspan_fake_startup (struct usb_serial *serial) | |||
1275 | } | 1275 | } |
1276 | 1276 | ||
1277 | /* Helper functions used by keyspan_setup_urbs */ | 1277 | /* Helper functions used by keyspan_setup_urbs */ |
1278 | static struct usb_endpoint_descriptor const *find_ep(struct usb_serial const *serial, | ||
1279 | int endpoint) | ||
1280 | { | ||
1281 | struct usb_host_interface *iface_desc; | ||
1282 | struct usb_endpoint_descriptor *ep; | ||
1283 | int i; | ||
1284 | |||
1285 | iface_desc = serial->interface->cur_altsetting; | ||
1286 | for (i = 0; i < iface_desc->desc.bNumEndpoints; ++i) { | ||
1287 | ep = &iface_desc->endpoint[i].desc; | ||
1288 | if (ep->bEndpointAddress == endpoint) | ||
1289 | return ep; | ||
1290 | } | ||
1291 | dev_warn(&serial->interface->dev, "found no endpoint descriptor for " | ||
1292 | "endpoint %x\n", endpoint); | ||
1293 | return NULL; | ||
1294 | } | ||
1295 | |||
1278 | static struct urb *keyspan_setup_urb (struct usb_serial *serial, int endpoint, | 1296 | static struct urb *keyspan_setup_urb (struct usb_serial *serial, int endpoint, |
1279 | int dir, void *ctx, char *buf, int len, | 1297 | int dir, void *ctx, char *buf, int len, |
1280 | void (*callback)(struct urb *)) | 1298 | void (*callback)(struct urb *)) |
1281 | { | 1299 | { |
1282 | struct urb *urb; | 1300 | struct urb *urb; |
1301 | struct usb_endpoint_descriptor const *ep_desc; | ||
1302 | char const *ep_type_name; | ||
1283 | 1303 | ||
1284 | if (endpoint == -1) | 1304 | if (endpoint == -1) |
1285 | return NULL; /* endpoint not needed */ | 1305 | return NULL; /* endpoint not needed */ |
@@ -1291,11 +1311,32 @@ static struct urb *keyspan_setup_urb (struct usb_serial *serial, int endpoint, | |||
1291 | return NULL; | 1311 | return NULL; |
1292 | } | 1312 | } |
1293 | 1313 | ||
1294 | /* Fill URB using supplied data. */ | 1314 | ep_desc = find_ep(serial, endpoint); |
1295 | usb_fill_bulk_urb(urb, serial->dev, | 1315 | if (!ep_desc) { |
1296 | usb_sndbulkpipe(serial->dev, endpoint) | dir, | 1316 | /* leak the urb, something's wrong and the callers don't care */ |
1297 | buf, len, callback, ctx); | 1317 | return urb; |
1318 | } | ||
1319 | if (usb_endpoint_xfer_int(ep_desc)) { | ||
1320 | ep_type_name = "INT"; | ||
1321 | usb_fill_int_urb(urb, serial->dev, | ||
1322 | usb_sndintpipe(serial->dev, endpoint) | dir, | ||
1323 | buf, len, callback, ctx, | ||
1324 | ep_desc->bInterval); | ||
1325 | } else if (usb_endpoint_xfer_bulk(ep_desc)) { | ||
1326 | ep_type_name = "BULK"; | ||
1327 | usb_fill_bulk_urb(urb, serial->dev, | ||
1328 | usb_sndbulkpipe(serial->dev, endpoint) | dir, | ||
1329 | buf, len, callback, ctx); | ||
1330 | } else { | ||
1331 | dev_warn(&serial->interface->dev, | ||
1332 | "unsupported endpoint type %x\n", | ||
1333 | ep_desc->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK); | ||
1334 | usb_free_urb(urb); | ||
1335 | return NULL; | ||
1336 | } | ||
1298 | 1337 | ||
1338 | dbg("%s - using urb %p for %s endpoint %x", | ||
1339 | __func__, urb, ep_type_name, endpoint); | ||
1299 | return urb; | 1340 | return urb; |
1300 | } | 1341 | } |
1301 | 1342 | ||