aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/usb/siano
diff options
context:
space:
mode:
authorMauro Carvalho Chehab <mchehab@redhat.com>2013-03-06 07:53:50 -0500
committerMauro Carvalho Chehab <mchehab@redhat.com>2013-03-21 06:38:02 -0400
commit05f0ffbc487517a529c00119d0bfde33df509b52 (patch)
tree34f79acb84832fd5f59ac426d972533be6ee3f7a /drivers/media/usb/siano
parentdb30567a63db0094e03338462939031edf558cc8 (diff)
[media] siano: use USB endpoint descriptors for in/out endp
Instead of using hardcoded descriptors, detect them from the USB descriptors. This patch is rebased form Doron Cohen's patch: http://patchwork.linuxtv.org/patch/7883/ Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
Diffstat (limited to 'drivers/media/usb/siano')
-rw-r--r--drivers/media/usb/siano/smsusb.c99
1 files changed, 73 insertions, 26 deletions
diff --git a/drivers/media/usb/siano/smsusb.c b/drivers/media/usb/siano/smsusb.c
index 2050e4c415b1..a31bf74a5957 100644
--- a/drivers/media/usb/siano/smsusb.c
+++ b/drivers/media/usb/siano/smsusb.c
@@ -35,16 +35,23 @@ module_param_named(debug, sms_dbg, int, 0644);
35MODULE_PARM_DESC(debug, "set debug level (info=1, adv=2 (or-able))"); 35MODULE_PARM_DESC(debug, "set debug level (info=1, adv=2 (or-able))");
36 36
37#define USB1_BUFFER_SIZE 0x1000 37#define USB1_BUFFER_SIZE 0x1000
38#define USB2_BUFFER_SIZE 0x4000 38#define USB2_BUFFER_SIZE 0x2000
39 39
40#define MAX_BUFFERS 50 40#define MAX_BUFFERS 50
41#define MAX_URBS 10 41#define MAX_URBS 10
42 42
43struct smsusb_device_t; 43struct smsusb_device_t;
44 44
45enum smsusb_state {
46 SMSUSB_DISCONNECTED,
47 SMSUSB_SUSPENDED,
48 SMSUSB_ACTIVE
49};
50
45struct smsusb_urb_t { 51struct smsusb_urb_t {
52 struct list_head entry;
46 struct smscore_buffer_t *cb; 53 struct smscore_buffer_t *cb;
47 struct smsusb_device_t *dev; 54 struct smsusb_device_t *dev;
48 55
49 struct urb urb; 56 struct urb urb;
50}; 57};
@@ -57,11 +64,23 @@ struct smsusb_device_t {
57 64
58 int response_alignment; 65 int response_alignment;
59 int buffer_size; 66 int buffer_size;
67
68 unsigned char in_ep;
69 unsigned char out_ep;
70 enum smsusb_state state;
60}; 71};
61 72
62static int smsusb_submit_urb(struct smsusb_device_t *dev, 73static int smsusb_submit_urb(struct smsusb_device_t *dev,
63 struct smsusb_urb_t *surb); 74 struct smsusb_urb_t *surb);
64 75
76/**
77 * Completing URB's callback handler - top half (interrupt context)
78 * adds completing sms urb to the global surbs list and activtes the worker
79 * thread the surb
80 * IMPORTANT - blocking functions must not be called from here !!!
81
82 * @param urb pointer to a completing urb object
83 */
65static void smsusb_onresponse(struct urb *urb) 84static void smsusb_onresponse(struct urb *urb)
66{ 85{
67 struct smsusb_urb_t *surb = (struct smsusb_urb_t *) urb->context; 86 struct smsusb_urb_t *surb = (struct smsusb_urb_t *) urb->context;
@@ -140,7 +159,7 @@ static int smsusb_submit_urb(struct smsusb_device_t *dev,
140 usb_fill_bulk_urb( 159 usb_fill_bulk_urb(
141 &surb->urb, 160 &surb->urb,
142 dev->udev, 161 dev->udev,
143 usb_rcvbulkpipe(dev->udev, 0x81), 162 usb_rcvbulkpipe(dev->udev, dev->in_ep),
144 surb->cb->p, 163 surb->cb->p,
145 dev->buffer_size, 164 dev->buffer_size,
146 smsusb_onresponse, 165 smsusb_onresponse,
@@ -192,6 +211,9 @@ static int smsusb_sendrequest(void *context, void *buffer, size_t size)
192 smscore_translate_msg(phdr->msgType), phdr->msgType, 211 smscore_translate_msg(phdr->msgType), phdr->msgType,
193 phdr->msgLength); 212 phdr->msgLength);
194 213
214 if (dev->state != SMSUSB_ACTIVE)
215 return -ENOENT;
216
195 smsendian_handle_message_header((struct SmsMsgHdr_ST *)buffer); 217 smsendian_handle_message_header((struct SmsMsgHdr_ST *)buffer);
196 return usb_bulk_msg(dev->udev, usb_sndbulkpipe(dev->udev, 2), 218 return usb_bulk_msg(dev->udev, usb_sndbulkpipe(dev->udev, 2),
197 buffer, size, &dummy, 1000); 219 buffer, size, &dummy, 1000);
@@ -301,13 +323,15 @@ static void smsusb_term_device(struct usb_interface *intf)
301 struct smsusb_device_t *dev = usb_get_intfdata(intf); 323 struct smsusb_device_t *dev = usb_get_intfdata(intf);
302 324
303 if (dev) { 325 if (dev) {
326 dev->state = SMSUSB_DISCONNECTED;
327
304 smsusb_stop_streaming(dev); 328 smsusb_stop_streaming(dev);
305 329
306 /* unregister from smscore */ 330 /* unregister from smscore */
307 if (dev->coredev) 331 if (dev->coredev)
308 smscore_unregister_device(dev->coredev); 332 smscore_unregister_device(dev->coredev);
309 333
310 sms_info("device %p destroyed", dev); 334 sms_info("device 0x%p destroyed", dev);
311 kfree(dev); 335 kfree(dev);
312 } 336 }
313 337
@@ -330,6 +354,7 @@ static int smsusb_init_device(struct usb_interface *intf, int board_id)
330 memset(&params, 0, sizeof(params)); 354 memset(&params, 0, sizeof(params));
331 usb_set_intfdata(intf, dev); 355 usb_set_intfdata(intf, dev);
332 dev->udev = interface_to_usbdev(intf); 356 dev->udev = interface_to_usbdev(intf);
357 dev->state = SMSUSB_DISCONNECTED;
333 358
334 params.device_type = sms_get_board(board_id)->type; 359 params.device_type = sms_get_board(board_id)->type;
335 360
@@ -346,6 +371,8 @@ static int smsusb_init_device(struct usb_interface *intf, int board_id)
346 case SMS_NOVA_A0: 371 case SMS_NOVA_A0:
347 case SMS_NOVA_B0: 372 case SMS_NOVA_B0:
348 case SMS_VEGA: 373 case SMS_VEGA:
374 case SMS_VENICE:
375 case SMS_DENVER_1530:
349 dev->buffer_size = USB2_BUFFER_SIZE; 376 dev->buffer_size = USB2_BUFFER_SIZE;
350 dev->response_alignment = 377 dev->response_alignment =
351 le16_to_cpu(dev->udev->ep_in[1]->desc.wMaxPacketSize) - 378 le16_to_cpu(dev->udev->ep_in[1]->desc.wMaxPacketSize) -
@@ -355,6 +382,16 @@ static int smsusb_init_device(struct usb_interface *intf, int board_id)
355 break; 382 break;
356 } 383 }
357 384
385 for (i = 0; i < intf->cur_altsetting->desc.bNumEndpoints; i++) {
386 if (intf->cur_altsetting->endpoint[i].desc. bEndpointAddress & USB_DIR_IN)
387 dev->in_ep = intf->cur_altsetting->endpoint[i].desc.bEndpointAddress;
388 else
389 dev->out_ep = intf->cur_altsetting->endpoint[i].desc.bEndpointAddress;
390 }
391
392 sms_info("in_ep = %02x, out_ep = %02x",
393 dev->in_ep, dev->out_ep);
394
358 params.device = &dev->udev->dev; 395 params.device = &dev->udev->dev;
359 params.buffer_size = dev->buffer_size; 396 params.buffer_size = dev->buffer_size;
360 params.num_buffers = MAX_BUFFERS; 397 params.num_buffers = MAX_BUFFERS;
@@ -386,6 +423,8 @@ static int smsusb_init_device(struct usb_interface *intf, int board_id)
386 return rc; 423 return rc;
387 } 424 }
388 425
426 dev->state = SMSUSB_ACTIVE;
427
389 rc = smscore_start_device(dev->coredev); 428 rc = smscore_start_device(dev->coredev);
390 if (rc < 0) { 429 if (rc < 0) {
391 sms_err("smscore_start_device(...) failed"); 430 sms_err("smscore_start_device(...) failed");
@@ -393,7 +432,7 @@ static int smsusb_init_device(struct usb_interface *intf, int board_id)
393 return rc; 432 return rc;
394 } 433 }
395 434
396 sms_info("device %p created", dev); 435 sms_info("device 0x%p created", dev);
397 436
398 return rc; 437 return rc;
399} 438}
@@ -402,15 +441,23 @@ static int smsusb_probe(struct usb_interface *intf,
402 const struct usb_device_id *id) 441 const struct usb_device_id *id)
403{ 442{
404 struct usb_device *udev = interface_to_usbdev(intf); 443 struct usb_device *udev = interface_to_usbdev(intf);
405 char devpath[32];
406 int i, rc; 444 int i, rc;
407 445
408 rc = usb_clear_halt(udev, usb_rcvbulkpipe(udev, 0x81)); 446 sms_info("interface number %d",
409 rc = usb_clear_halt(udev, usb_rcvbulkpipe(udev, 0x02)); 447 intf->cur_altsetting->desc.bInterfaceNumber);
410 448
411 if (intf->num_altsetting > 0) { 449 if (sms_get_board(id->driver_info)->intf_num !=
412 rc = usb_set_interface( 450 intf->cur_altsetting->desc.bInterfaceNumber) {
413 udev, intf->cur_altsetting->desc.bInterfaceNumber, 0); 451 sms_err("interface number is %d expecting %d",
452 sms_get_board(id->driver_info)->intf_num,
453 intf->cur_altsetting->desc.bInterfaceNumber);
454 return -ENODEV;
455 }
456
457 if (intf->num_altsetting > 1) {
458 rc = usb_set_interface(udev,
459 intf->cur_altsetting->desc.bInterfaceNumber,
460 0);
414 if (rc < 0) { 461 if (rc < 0) {
415 sms_err("usb_set_interface failed, rc %d", rc); 462 sms_err("usb_set_interface failed, rc %d", rc);
416 return rc; 463 return rc;
@@ -419,27 +466,25 @@ static int smsusb_probe(struct usb_interface *intf,
419 466
420 sms_info("smsusb_probe %d", 467 sms_info("smsusb_probe %d",
421 intf->cur_altsetting->desc.bInterfaceNumber); 468 intf->cur_altsetting->desc.bInterfaceNumber);
422 for (i = 0; i < intf->cur_altsetting->desc.bNumEndpoints; i++) 469 for (i = 0; i < intf->cur_altsetting->desc.bNumEndpoints; i++) {
423 sms_info("endpoint %d %02x %02x %d", i, 470 sms_info("endpoint %d %02x %02x %d", i,
424 intf->cur_altsetting->endpoint[i].desc.bEndpointAddress, 471 intf->cur_altsetting->endpoint[i].desc.bEndpointAddress,
425 intf->cur_altsetting->endpoint[i].desc.bmAttributes, 472 intf->cur_altsetting->endpoint[i].desc.bmAttributes,
426 intf->cur_altsetting->endpoint[i].desc.wMaxPacketSize); 473 intf->cur_altsetting->endpoint[i].desc.wMaxPacketSize);
427 474 if (intf->cur_altsetting->endpoint[i].desc.bEndpointAddress &
475 USB_DIR_IN)
476 rc = usb_clear_halt(udev, usb_rcvbulkpipe(udev,
477 intf->cur_altsetting->endpoint[i].desc.bEndpointAddress));
478 else
479 rc = usb_clear_halt(udev, usb_sndbulkpipe(udev,
480 intf->cur_altsetting->endpoint[i].desc.bEndpointAddress));
481 }
428 if ((udev->actconfig->desc.bNumInterfaces == 2) && 482 if ((udev->actconfig->desc.bNumInterfaces == 2) &&
429 (intf->cur_altsetting->desc.bInterfaceNumber == 0)) { 483 (intf->cur_altsetting->desc.bInterfaceNumber == 0)) {
430 sms_err("rom interface 0 is not used"); 484 sms_err("rom interface 0 is not used");
431 return -ENODEV; 485 return -ENODEV;
432 } 486 }
433 487
434 if (intf->cur_altsetting->desc.bInterfaceNumber == 1) {
435 snprintf(devpath, sizeof(devpath), "usb\\%d-%s",
436 udev->bus->busnum, udev->devpath);
437 sms_info("stellar device was found.");
438 return smsusb1_load_firmware(
439 udev, smscore_registry_getmode(devpath),
440 id->driver_info);
441 }
442
443 rc = smsusb_init_device(intf, id->driver_info); 488 rc = smsusb_init_device(intf, id->driver_info);
444 sms_info("rc %d", rc); 489 sms_info("rc %d", rc);
445 sms_board_load_modules(id->driver_info); 490 sms_board_load_modules(id->driver_info);
@@ -454,7 +499,9 @@ static void smsusb_disconnect(struct usb_interface *intf)
454static int smsusb_suspend(struct usb_interface *intf, pm_message_t msg) 499static int smsusb_suspend(struct usb_interface *intf, pm_message_t msg)
455{ 500{
456 struct smsusb_device_t *dev = usb_get_intfdata(intf); 501 struct smsusb_device_t *dev = usb_get_intfdata(intf);
457 printk(KERN_INFO "%s: Entering status %d.\n", __func__, msg.event); 502 printk(KERN_INFO "%s Entering status %d.\n", __func__, msg.event);
503 dev->state = SMSUSB_SUSPENDED;
504 /*smscore_set_power_mode(dev, SMS_POWER_MODE_SUSPENDED);*/
458 smsusb_stop_streaming(dev); 505 smsusb_stop_streaming(dev);
459 return 0; 506 return 0;
460} 507}
@@ -465,9 +512,9 @@ static int smsusb_resume(struct usb_interface *intf)
465 struct smsusb_device_t *dev = usb_get_intfdata(intf); 512 struct smsusb_device_t *dev = usb_get_intfdata(intf);
466 struct usb_device *udev = interface_to_usbdev(intf); 513 struct usb_device *udev = interface_to_usbdev(intf);
467 514
468 printk(KERN_INFO "%s: Entering.\n", __func__); 515 printk(KERN_INFO "%s Entering.\n", __func__);
469 usb_clear_halt(udev, usb_rcvbulkpipe(udev, 0x81)); 516 usb_clear_halt(udev, usb_rcvbulkpipe(udev, dev->in_ep));
470 usb_clear_halt(udev, usb_rcvbulkpipe(udev, 0x02)); 517 usb_clear_halt(udev, usb_sndbulkpipe(udev, dev->out_ep));
471 518
472 for (i = 0; i < intf->cur_altsetting->desc.bNumEndpoints; i++) 519 for (i = 0; i < intf->cur_altsetting->desc.bNumEndpoints; i++)
473 printk(KERN_INFO "endpoint %d %02x %02x %d\n", i, 520 printk(KERN_INFO "endpoint %d %02x %02x %d\n", i,