Commit 05f0ffbc authored by Mauro Carvalho Chehab's avatar Mauro Carvalho Chehab

[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: default avatarMauro Carvalho Chehab <mchehab@redhat.com>
parent db30567a
...@@ -35,16 +35,23 @@ module_param_named(debug, sms_dbg, int, 0644); ...@@ -35,16 +35,23 @@ module_param_named(debug, sms_dbg, int, 0644);
MODULE_PARM_DESC(debug, "set debug level (info=1, adv=2 (or-able))"); MODULE_PARM_DESC(debug, "set debug level (info=1, adv=2 (or-able))");
#define USB1_BUFFER_SIZE 0x1000 #define USB1_BUFFER_SIZE 0x1000
#define USB2_BUFFER_SIZE 0x4000 #define USB2_BUFFER_SIZE 0x2000
#define MAX_BUFFERS 50 #define MAX_BUFFERS 50
#define MAX_URBS 10 #define MAX_URBS 10
struct smsusb_device_t; struct smsusb_device_t;
enum smsusb_state {
SMSUSB_DISCONNECTED,
SMSUSB_SUSPENDED,
SMSUSB_ACTIVE
};
struct smsusb_urb_t { struct smsusb_urb_t {
struct list_head entry;
struct smscore_buffer_t *cb; struct smscore_buffer_t *cb;
struct smsusb_device_t *dev; struct smsusb_device_t *dev;
struct urb urb; struct urb urb;
}; };
...@@ -57,11 +64,23 @@ struct smsusb_device_t { ...@@ -57,11 +64,23 @@ struct smsusb_device_t {
int response_alignment; int response_alignment;
int buffer_size; int buffer_size;
unsigned char in_ep;
unsigned char out_ep;
enum smsusb_state state;
}; };
static int smsusb_submit_urb(struct smsusb_device_t *dev, static int smsusb_submit_urb(struct smsusb_device_t *dev,
struct smsusb_urb_t *surb); struct smsusb_urb_t *surb);
/**
* Completing URB's callback handler - top half (interrupt context)
* adds completing sms urb to the global surbs list and activtes the worker
* thread the surb
* IMPORTANT - blocking functions must not be called from here !!!
* @param urb pointer to a completing urb object
*/
static void smsusb_onresponse(struct urb *urb) static void smsusb_onresponse(struct urb *urb)
{ {
struct smsusb_urb_t *surb = (struct smsusb_urb_t *) urb->context; 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,7 +159,7 @@ static int smsusb_submit_urb(struct smsusb_device_t *dev,
usb_fill_bulk_urb( usb_fill_bulk_urb(
&surb->urb, &surb->urb,
dev->udev, dev->udev,
usb_rcvbulkpipe(dev->udev, 0x81), usb_rcvbulkpipe(dev->udev, dev->in_ep),
surb->cb->p, surb->cb->p,
dev->buffer_size, dev->buffer_size,
smsusb_onresponse, smsusb_onresponse,
...@@ -192,6 +211,9 @@ static int smsusb_sendrequest(void *context, void *buffer, size_t size) ...@@ -192,6 +211,9 @@ static int smsusb_sendrequest(void *context, void *buffer, size_t size)
smscore_translate_msg(phdr->msgType), phdr->msgType, smscore_translate_msg(phdr->msgType), phdr->msgType,
phdr->msgLength); phdr->msgLength);
if (dev->state != SMSUSB_ACTIVE)
return -ENOENT;
smsendian_handle_message_header((struct SmsMsgHdr_ST *)buffer); smsendian_handle_message_header((struct SmsMsgHdr_ST *)buffer);
return usb_bulk_msg(dev->udev, usb_sndbulkpipe(dev->udev, 2), return usb_bulk_msg(dev->udev, usb_sndbulkpipe(dev->udev, 2),
buffer, size, &dummy, 1000); buffer, size, &dummy, 1000);
...@@ -301,13 +323,15 @@ static void smsusb_term_device(struct usb_interface *intf) ...@@ -301,13 +323,15 @@ static void smsusb_term_device(struct usb_interface *intf)
struct smsusb_device_t *dev = usb_get_intfdata(intf); struct smsusb_device_t *dev = usb_get_intfdata(intf);
if (dev) { if (dev) {
dev->state = SMSUSB_DISCONNECTED;
smsusb_stop_streaming(dev); smsusb_stop_streaming(dev);
/* unregister from smscore */ /* unregister from smscore */
if (dev->coredev) if (dev->coredev)
smscore_unregister_device(dev->coredev); smscore_unregister_device(dev->coredev);
sms_info("device %p destroyed", dev); sms_info("device 0x%p destroyed", dev);
kfree(dev); kfree(dev);
} }
...@@ -330,6 +354,7 @@ static int smsusb_init_device(struct usb_interface *intf, int board_id) ...@@ -330,6 +354,7 @@ static int smsusb_init_device(struct usb_interface *intf, int board_id)
memset(&params, 0, sizeof(params)); memset(&params, 0, sizeof(params));
usb_set_intfdata(intf, dev); usb_set_intfdata(intf, dev);
dev->udev = interface_to_usbdev(intf); dev->udev = interface_to_usbdev(intf);
dev->state = SMSUSB_DISCONNECTED;
params.device_type = sms_get_board(board_id)->type; params.device_type = sms_get_board(board_id)->type;
...@@ -346,6 +371,8 @@ static int smsusb_init_device(struct usb_interface *intf, int board_id) ...@@ -346,6 +371,8 @@ static int smsusb_init_device(struct usb_interface *intf, int board_id)
case SMS_NOVA_A0: case SMS_NOVA_A0:
case SMS_NOVA_B0: case SMS_NOVA_B0:
case SMS_VEGA: case SMS_VEGA:
case SMS_VENICE:
case SMS_DENVER_1530:
dev->buffer_size = USB2_BUFFER_SIZE; dev->buffer_size = USB2_BUFFER_SIZE;
dev->response_alignment = dev->response_alignment =
le16_to_cpu(dev->udev->ep_in[1]->desc.wMaxPacketSize) - 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,6 +382,16 @@ static int smsusb_init_device(struct usb_interface *intf, int board_id)
break; break;
} }
for (i = 0; i < intf->cur_altsetting->desc.bNumEndpoints; i++) {
if (intf->cur_altsetting->endpoint[i].desc. bEndpointAddress & USB_DIR_IN)
dev->in_ep = intf->cur_altsetting->endpoint[i].desc.bEndpointAddress;
else
dev->out_ep = intf->cur_altsetting->endpoint[i].desc.bEndpointAddress;
}
sms_info("in_ep = %02x, out_ep = %02x",
dev->in_ep, dev->out_ep);
params.device = &dev->udev->dev; params.device = &dev->udev->dev;
params.buffer_size = dev->buffer_size; params.buffer_size = dev->buffer_size;
params.num_buffers = MAX_BUFFERS; params.num_buffers = MAX_BUFFERS;
...@@ -386,6 +423,8 @@ static int smsusb_init_device(struct usb_interface *intf, int board_id) ...@@ -386,6 +423,8 @@ static int smsusb_init_device(struct usb_interface *intf, int board_id)
return rc; return rc;
} }
dev->state = SMSUSB_ACTIVE;
rc = smscore_start_device(dev->coredev); rc = smscore_start_device(dev->coredev);
if (rc < 0) { if (rc < 0) {
sms_err("smscore_start_device(...) failed"); sms_err("smscore_start_device(...) failed");
...@@ -393,7 +432,7 @@ static int smsusb_init_device(struct usb_interface *intf, int board_id) ...@@ -393,7 +432,7 @@ static int smsusb_init_device(struct usb_interface *intf, int board_id)
return rc; return rc;
} }
sms_info("device %p created", dev); sms_info("device 0x%p created", dev);
return rc; return rc;
} }
...@@ -402,15 +441,23 @@ static int smsusb_probe(struct usb_interface *intf, ...@@ -402,15 +441,23 @@ static int smsusb_probe(struct usb_interface *intf,
const struct usb_device_id *id) const struct usb_device_id *id)
{ {
struct usb_device *udev = interface_to_usbdev(intf); struct usb_device *udev = interface_to_usbdev(intf);
char devpath[32];
int i, rc; int i, rc;
rc = usb_clear_halt(udev, usb_rcvbulkpipe(udev, 0x81)); sms_info("interface number %d",
rc = usb_clear_halt(udev, usb_rcvbulkpipe(udev, 0x02)); intf->cur_altsetting->desc.bInterfaceNumber);
if (intf->num_altsetting > 0) { if (sms_get_board(id->driver_info)->intf_num !=
rc = usb_set_interface( intf->cur_altsetting->desc.bInterfaceNumber) {
udev, intf->cur_altsetting->desc.bInterfaceNumber, 0); sms_err("interface number is %d expecting %d",
sms_get_board(id->driver_info)->intf_num,
intf->cur_altsetting->desc.bInterfaceNumber);
return -ENODEV;
}
if (intf->num_altsetting > 1) {
rc = usb_set_interface(udev,
intf->cur_altsetting->desc.bInterfaceNumber,
0);
if (rc < 0) { if (rc < 0) {
sms_err("usb_set_interface failed, rc %d", rc); sms_err("usb_set_interface failed, rc %d", rc);
return rc; return rc;
...@@ -419,27 +466,25 @@ static int smsusb_probe(struct usb_interface *intf, ...@@ -419,27 +466,25 @@ static int smsusb_probe(struct usb_interface *intf,
sms_info("smsusb_probe %d", sms_info("smsusb_probe %d",
intf->cur_altsetting->desc.bInterfaceNumber); intf->cur_altsetting->desc.bInterfaceNumber);
for (i = 0; i < intf->cur_altsetting->desc.bNumEndpoints; i++) for (i = 0; i < intf->cur_altsetting->desc.bNumEndpoints; i++) {
sms_info("endpoint %d %02x %02x %d", i, sms_info("endpoint %d %02x %02x %d", i,
intf->cur_altsetting->endpoint[i].desc.bEndpointAddress, intf->cur_altsetting->endpoint[i].desc.bEndpointAddress,
intf->cur_altsetting->endpoint[i].desc.bmAttributes, intf->cur_altsetting->endpoint[i].desc.bmAttributes,
intf->cur_altsetting->endpoint[i].desc.wMaxPacketSize); intf->cur_altsetting->endpoint[i].desc.wMaxPacketSize);
if (intf->cur_altsetting->endpoint[i].desc.bEndpointAddress &
USB_DIR_IN)
rc = usb_clear_halt(udev, usb_rcvbulkpipe(udev,
intf->cur_altsetting->endpoint[i].desc.bEndpointAddress));
else
rc = usb_clear_halt(udev, usb_sndbulkpipe(udev,
intf->cur_altsetting->endpoint[i].desc.bEndpointAddress));
}
if ((udev->actconfig->desc.bNumInterfaces == 2) && if ((udev->actconfig->desc.bNumInterfaces == 2) &&
(intf->cur_altsetting->desc.bInterfaceNumber == 0)) { (intf->cur_altsetting->desc.bInterfaceNumber == 0)) {
sms_err("rom interface 0 is not used"); sms_err("rom interface 0 is not used");
return -ENODEV; return -ENODEV;
} }
if (intf->cur_altsetting->desc.bInterfaceNumber == 1) {
snprintf(devpath, sizeof(devpath), "usb\\%d-%s",
udev->bus->busnum, udev->devpath);
sms_info("stellar device was found.");
return smsusb1_load_firmware(
udev, smscore_registry_getmode(devpath),
id->driver_info);
}
rc = smsusb_init_device(intf, id->driver_info); rc = smsusb_init_device(intf, id->driver_info);
sms_info("rc %d", rc); sms_info("rc %d", rc);
sms_board_load_modules(id->driver_info); sms_board_load_modules(id->driver_info);
...@@ -454,7 +499,9 @@ static void smsusb_disconnect(struct usb_interface *intf) ...@@ -454,7 +499,9 @@ static void smsusb_disconnect(struct usb_interface *intf)
static int smsusb_suspend(struct usb_interface *intf, pm_message_t msg) static int smsusb_suspend(struct usb_interface *intf, pm_message_t msg)
{ {
struct smsusb_device_t *dev = usb_get_intfdata(intf); struct smsusb_device_t *dev = usb_get_intfdata(intf);
printk(KERN_INFO "%s: Entering status %d.\n", __func__, msg.event); printk(KERN_INFO "%s Entering status %d.\n", __func__, msg.event);
dev->state = SMSUSB_SUSPENDED;
/*smscore_set_power_mode(dev, SMS_POWER_MODE_SUSPENDED);*/
smsusb_stop_streaming(dev); smsusb_stop_streaming(dev);
return 0; return 0;
} }
...@@ -465,9 +512,9 @@ static int smsusb_resume(struct usb_interface *intf) ...@@ -465,9 +512,9 @@ static int smsusb_resume(struct usb_interface *intf)
struct smsusb_device_t *dev = usb_get_intfdata(intf); struct smsusb_device_t *dev = usb_get_intfdata(intf);
struct usb_device *udev = interface_to_usbdev(intf); struct usb_device *udev = interface_to_usbdev(intf);
printk(KERN_INFO "%s: Entering.\n", __func__); printk(KERN_INFO "%s Entering.\n", __func__);
usb_clear_halt(udev, usb_rcvbulkpipe(udev, 0x81)); usb_clear_halt(udev, usb_rcvbulkpipe(udev, dev->in_ep));
usb_clear_halt(udev, usb_rcvbulkpipe(udev, 0x02)); usb_clear_halt(udev, usb_sndbulkpipe(udev, dev->out_ep));
for (i = 0; i < intf->cur_altsetting->desc.bNumEndpoints; i++) for (i = 0; i < intf->cur_altsetting->desc.bNumEndpoints; i++)
printk(KERN_INFO "endpoint %d %02x %02x %d\n", i, printk(KERN_INFO "endpoint %d %02x %02x %d\n", i,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment