Skip to contentSkip to conversation

tm6000: Properly set alternate when preparing to stream

PATCH In review Mauro Carvalho Chehab 3 participants 3 messages Apr 26, 2010 – Apr 28, 2010

Subsystems (2)
lore
Share & tools
lore
#0 lore raw

PATCH 1/1 tm6000: Properly set alternate when preparing to stream

Although the code is getting the better alternates, it is not really using it. Get the interface/alternate numbers and use it where needed.

This patch implements also one small fix at the last_line set, as proposed by Bee Hock Goh <[email protected]>.

Signature · 2 lines
Cheers,
Mauro
drivers/staging/tm6000/tm6000-cards.c +29 -22
index f795a3e..a7e9556 100644
@@ -634,21 +634,24 @@ err:
 /* high bandwidth multiplier, as encoded in highspeed endpoint descriptors */
 #define hb_mult(wMaxPacketSize) (1 + (((wMaxPacketSize) >> 11) & 0x03))
 
-static void get_max_endpoint (  struct usb_device *usbdev,
-				char *msgtype,
-				struct usb_host_endpoint *curr_e,
-				unsigned int *maxsize,
-				struct usb_host_endpoint **ep  )
+static void get_max_endpoint(struct usb_device *udev,
+			     struct usb_host_interface *alt,
+			     char *msgtype,
+			     struct usb_host_endpoint *curr_e,
+			     struct tm6000_endpoint *tm_ep)
 {
 	u16 tmp = le16_to_cpu(curr_e->desc.wMaxPacketSize);
 	unsigned int size = tmp & 0x7ff;
 
-	if (usbdev->speed == USB_SPEED_HIGH)
+	if (udev->speed == USB_SPEED_HIGH)
 		size = size * hb_mult (tmp);
 
-	if (size>*maxsize) {
-		*ep = curr_e;
-		*maxsize = size;
+	if (size > tm_ep->maxsize) {
+		tm_ep->endp = curr_e;
+		tm_ep->maxsize = size;
+		tm_ep->bInterfaceNumber = alt->desc.bInterfaceNumber;
+		tm_ep->bAlternateSetting = alt->desc.bAlternateSetting;
+
 		printk("tm6000: %s endpoint: 0x%02x (max size=%u bytes)\n",
 					msgtype, curr_e->desc.bEndpointAddress,
 					size);
@@ -743,24 +746,28 @@ static int tm6000_usb_probe(struct usb_interface *interface,
 			switch (e->desc.bmAttributes) {
 			case USB_ENDPOINT_XFER_BULK:
 				if (!dir_out) {
-					get_max_endpoint (usbdev, "Bulk IN", e,
-							&dev->max_bulk_in,
-							&dev->bulk_in);
+					get_max_endpoint(usbdev,
+							 &interface->altsetting[i],
+							 "Bulk IN", e,
+							 &dev->bulk_in);
 				} else {
-					get_max_endpoint (usbdev, "Bulk OUT", e,
-							&dev->max_bulk_out,
-							&dev->bulk_out);
+					get_max_endpoint(usbdev,
+							 &interface->altsetting[i],
+							 "Bulk OUT", e,
+							 &dev->bulk_out);
 				}
 				break;
 			case USB_ENDPOINT_XFER_ISOC:
 				if (!dir_out) {
-					get_max_endpoint (usbdev, "ISOC IN", e,
-							&dev->max_isoc_in,
-							&dev->isoc_in);
+					get_max_endpoint(usbdev,
+							 &interface->altsetting[i],
+							 "ISOC IN", e,
+							 &dev->isoc_in);
 				} else {
-					get_max_endpoint (usbdev, "ISOC OUT", e,
-							&dev->max_isoc_out,
-							&dev->isoc_out);
+					get_max_endpoint(usbdev,
+							 &interface->altsetting[i],
+							 "ISOC OUT", e,
+							 &dev->isoc_out);
 				}
 				break;
 			}
@@ -775,7 +782,7 @@ static int tm6000_usb_probe(struct usb_interface *interface,
 		interface->altsetting->desc.bInterfaceNumber);
 
 /* check if the the device has the iso in endpoint at the correct place */
-	if (!dev->isoc_in) {
+	if (!dev->isoc_in.endp) {
 		printk("tm6000: probing error: no IN ISOC endpoint!\n");
 		rc= -ENODEV;
 
drivers/staging/tm6000/tm6000-video.c +13 -8
index c53de47..96358b2 100644
@@ -149,7 +149,8 @@ static inline void get_next_buf(struct tm6000_dmaqueue *dma_q,
 
 	/* Cleans up buffer - Usefull for testing for frame/URB loss */
 	outp = videobuf_to_vmalloc(&(*buf)->vb);
-	memset(outp, 0, (*buf)->vb.size);
+	if (outp)
+		memset(outp, 0, (*buf)->vb.size);
 
 	return;
 }
@@ -282,7 +283,8 @@ static int copy_packet(struct urb *urb, u32 header, u8 **ptr, u8 *endp,
 			start_line=line;
 			last_field=field;
 		}
-		last_line=line;
+		if (cmd == TM6000_URB_MSG_VIDEO)
+			last_line = line;
 
 		pktsize = TM6000_URB_MSG_LEN;
 	} else {
@@ -614,14 +616,18 @@ static int tm6000_prepare_isoc(struct tm6000_core *dev, unsigned int framesize)
 	/* De-allocates all pending stuff */
 	tm6000_uninit_isoc(dev);
 
+	usb_set_interface(dev->udev,
+			  dev->isoc_in.bInterfaceNumber,
+			  dev->isoc_in.bAlternateSetting);
+
 	pipe = usb_rcvisocpipe(dev->udev,
-			       dev->isoc_in->desc.bEndpointAddress &
+			       dev->isoc_in.endp->desc.bEndpointAddress &
 			       USB_ENDPOINT_NUMBER_MASK);
 
 	size = usb_maxpacket(dev->udev, pipe, usb_pipeout(pipe));
 
-	if (size > dev->max_isoc_in)
-		size = dev->max_isoc_in;
+	if (size > dev->isoc_in.maxsize)
+		size = dev->isoc_in.maxsize;
 
 	dev->isoc_ctl.max_pkt_size = size;
 
@@ -651,8 +657,7 @@ static int tm6000_prepare_isoc(struct tm6000_core *dev, unsigned int framesize)
 	dprintk(dev, V4L2_DEBUG_QUEUE, "Allocating %d x %d packets"
 		    " (%d bytes) of %d bytes each to handle %u size\n",
 		    max_packets, num_bufs, sb_size,
-		    dev->max_isoc_in, size);
-
+		    dev->isoc_in.maxsize, size);
 
 	/* allocate urbs and transfer buffers */
 	for (i = 0; i < dev->isoc_ctl.num_bufs; i++) {
@@ -680,7 +685,7 @@ static int tm6000_prepare_isoc(struct tm6000_core *dev, unsigned int framesize)
 		usb_fill_bulk_urb(urb, dev->udev, pipe,
 				  dev->isoc_ctl.transfer_buffer[i], sb_size,
 				  tm6000_irq_callback, dma_q);
-		urb->interval = dev->isoc_in->desc.bInterval;
+		urb->interval = dev->isoc_in.endp->desc.bInterval;
 		urb->number_of_packets = max_packets;
 		urb->transfer_flags = URB_ISO_ASAP | URB_NO_TRANSFER_DMA_MAP;
 
drivers/staging/tm6000/tm6000.h +8 -3
index 7aeded8..13d5a3e 100644
@@ -132,6 +132,13 @@ struct tm6000_dvb {
 	struct mutex		mutex;
 };
 
+struct tm6000_endpoint {
+	struct usb_host_endpoint	*endp;
+	__u8				bInterfaceNumber;
+	__u8				bAlternateSetting;
+	unsigned			maxsize;
+};
+
 struct tm6000_core {
 	/* generic device properties */
 	char				name[30];	/* name (including minor) of the device */
@@ -185,9 +192,7 @@ struct tm6000_core {
 	/* usb transfer */
 	struct usb_device		*udev;		/* the usb device */
 
-	struct usb_host_endpoint	*bulk_in, *bulk_out, *isoc_in, *isoc_out;
-	unsigned int			max_bulk_in, max_bulk_out;
-	unsigned int			max_isoc_in, max_isoc_out;
+	struct tm6000_endpoint		bulk_in, bulk_out, isoc_in, isoc_out;
 
 	/* scaler!=0 if scaler is active*/
 	int				scaler;
#1 lore raw

Am 26.04.2010 16:24, schrieb Mauro Carvalho Chehab:

Quoted 8 lines

Although the code is getting the better alternates, it is not really using it. Get the interface/alternate numbers and use it where needed.

This patch implements also one small fix at the last_line set, as proposed by Bee Hock Goh <[email protected]>.

Hi Mauro,

dvb doesn't build.

CC [M] /usr/src/src/tm6010/v4l-dvb/v4l/tm6000-dvb.o
/usr/src/src/tm6010/v4l-dvb/v4l/tm6000-dvb.c: In function 'tm6000_start_stream':
/usr/src/src/tm6010/v4l-dvb/v4l/tm6000-dvb.c:119:9: error: invalid type argument of '->' (have 'struct tm6000_endpoint')
make[5]: *** [/usr/src/src/tm6010/v4l-dvb/v4l/tm6000-dvb.o] Fehler 1 make[4]: *** [_module_/usr/src/src/tm6010/v4l-dvb/v4l] Fehler 2 make[3]: *** [sub-make] Error 2
make[2]: *** [all] Error 2
make[2]: Leaving directory `/usr/src/linux-2.6.34-rc4-16-obj/x86_64/desktop' make[1]: *** [default] Fehler 2
make[1]: Leaving directory `/usr/src/src/tm6010/v4l-dvb/v4l'
make: *** [all] Fehler 2

Signature · 1 line
Stefan Ringel <[email protected]>
#2 lore raw
In reply to Mauro Carvalho Chehab

patch seem work with no adverse effect or benefit? although the green screen is still an issue if the buffer is cleared.

maybe its just perception Will this patch give a better quality video?

Quoted 198 lines · Mauro Carvalho Chehab

Although the code is getting the better alternates, it is not really using it. Get the interface/alternate numbers and use it where needed.

This patch implements also one small fix at the last_line set, as proposed by Bee Hock Goh <[email protected]>.

--

Cheers,
Mauro

drivers/staging/tm6000/tm6000-cards.c +12 -9
index f795a3e..a7e9556 100644
@@ -634,21 +634,24 @@ err:
  /* high bandwidth multiplier, as encoded in highspeed endpoint descriptors */
  #define hb_mult(wMaxPacketSize) (1 + (((wMaxPacketSize) >> 11) & 0x03))
 
-static void get_max_endpoint (  struct usb_device *usbdev,
-                               char *msgtype,
-                               struct usb_host_endpoint *curr_e,
-                               unsigned int *maxsize,
-                               struct usb_host_endpoint **ep  )
+static void get_max_endpoint(struct usb_device *udev,
+                            struct usb_host_interface *alt,
+                            char *msgtype,
+                            struct usb_host_endpoint *curr_e,
+                            struct tm6000_endpoint *tm_ep)
  {
        u16 tmp = le16_to_cpu(curr_e->desc.wMaxPacketSize);
        unsigned int size = tmp & 0x7ff;
 
-       if (usbdev->speed == USB_SPEED_HIGH)
+       if (udev->speed == USB_SPEED_HIGH)
                size = size * hb_mult (tmp);
 
-       if (size>*maxsize) {
-               *ep = curr_e;
-               *maxsize = size;
+       if (size > tm_ep->maxsize) {
+               tm_ep->endp = curr_e;
+               tm_ep->maxsize = size;
+               tm_ep->bInterfaceNumber = alt->desc.bInterfaceNumber;
+               tm_ep->bAlternateSetting = alt->desc.bAlternateSetting;
+
                printk("tm6000: %s endpoint: 0x%02x (max size=%u bytes)\n",
                                        msgtype, curr_e->desc.bEndpointAddress,
                                        size);
@@ -743,24 +746,28 @@ static int tm6000_usb_probe(struct usb_interface *interface,
                        switch (e->desc.bmAttributes) {

                       case USB_ENDPOINT_XFER_BULK:
                               if (!dir_out) {
-                                       get_max_endpoint (usbdev, "Bulk IN", e,
-                                                       &dev->max_bulk_in,
-                                                       &dev->bulk_in);
+                                       get_max_endpoint(usbdev,
+                                                        &interface->altsetting[i],
+                                                        "Bulk IN", e,
+                                                        &dev->bulk_in); } else {
-                                       get_max_endpoint (usbdev, "Bulk OUT", e,
-                                                       &dev->max_bulk_out,
-                                                       &dev->bulk_out);
+                                       get_max_endpoint(usbdev,
+                                                        &interface->altsetting[i],
+                                                        "Bulk OUT", e,
+                                                        &dev->bulk_out); }
                               break;
                       case USB_ENDPOINT_XFER_ISOC:
                               if (!dir_out) {
-                                       get_max_endpoint (usbdev, "ISOC IN", e,
-                                                       &dev->max_isoc_in,
-                                                       &dev->isoc_in);
+                                       get_max_endpoint(usbdev,
+                                                        &interface->altsetting[i],
+                                                        "ISOC IN", e,
+                                                        &dev->isoc_in); } else {
-                                       get_max_endpoint (usbdev, "ISOC OUT", e,
-                                                       &dev->max_isoc_out,
-                                                       &dev->isoc_out);
+                                       get_max_endpoint(usbdev,
+                                                        &interface->altsetting[i],
+                                                        "ISOC OUT", e,
+                                                        &dev->isoc_out); }
                               break;
                       }

drivers/staging/tm6000/tm6000-cards.c +1 -1
@@ -775,7 +782,7 @@ static int tm6000_usb_probe(struct usb_interface *interface,
                interface->altsetting->desc.bInterfaceNumber);
 
  /* check if the the device has the iso in endpoint at the correct place */
-       if (!dev->isoc_in) {
+       if (!dev->isoc_in.endp) {
                printk("tm6000: probing error: no IN ISOC endpoint!\n");
                rc= -ENODEV;
 
drivers/staging/tm6000/tm6000-video.c +11 -5
index c53de47..96358b2 100644
@@ -149,7 +149,8 @@ static inline void get_next_buf(struct tm6000_dmaqueue *dma_q,
 
        /* Cleans up buffer - Usefull for testing for frame/URB loss */
        outp = videobuf_to_vmalloc(&(*buf)->vb);
-       memset(outp, 0, (*buf)->vb.size);
+       if (outp)
+               memset(outp, 0, (*buf)->vb.size);
 
        return;
  }
@@ -282,7 +283,8 @@ static int copy_packet(struct urb *urb, u32 header, u8 **ptr, u8 *endp,
                        start_line=line;
                        last_field=field;
                }
-               last_line=line;
+               if (cmd == TM6000_URB_MSG_VIDEO)
+                       last_line = line;
 
                pktsize = TM6000_URB_MSG_LEN;
        } else {
@@ -614,14 +616,18 @@ static int tm6000_prepare_isoc(struct tm6000_core *dev, unsigned int framesize)
        /* De-allocates all pending stuff */
        tm6000_uninit_isoc(dev);
 
+       usb_set_interface(dev->udev,
+                         dev->isoc_in.bInterfaceNumber,
+                         dev->isoc_in.bAlternateSetting);
+
        pipe = usb_rcvisocpipe(dev->udev,
-                              dev->isoc_in->desc.bEndpointAddress &
+                              dev->isoc_in.endp->desc.bEndpointAddress &
                               USB_ENDPOINT_NUMBER_MASK);
 
        size = usb_maxpacket(dev->udev, pipe, usb_pipeout(pipe));
 
-       if (size > dev->max_isoc_in)
-               size = dev->max_isoc_in;
+       if (size > dev->isoc_in.maxsize)
+               size = dev->isoc_in.maxsize;
 
        dev->isoc_ctl.max_pkt_size = size;
 
@@ -651,8 +657,7 @@ static int tm6000_prepare_isoc(struct tm6000_core *dev, unsigned int framesize)

       dprintk(dev, V4L2_DEBUG_QUEUE, "Allocating %d x %d packets" " (%d bytes) of %d bytes each to handle %u size\n", max_packets, num_bufs, sb_size,
-                   dev->max_isoc_in, size);
-
+                   dev->isoc_in.maxsize, size);

       /* allocate urbs and transfer buffers */ for (i = 0; i < dev->isoc_ctl.num_bufs; i++) {

drivers/staging/tm6000/tm6000-video.c +1 -1
@@ -680,7 +685,7 @@ static int tm6000_prepare_isoc(struct tm6000_core *dev, unsigned int framesize)
                usb_fill_bulk_urb(urb, dev->udev, pipe,
                                  dev->isoc_ctl.transfer_buffer[i], sb_size,
                                  tm6000_irq_callback, dma_q);
-               urb->interval = dev->isoc_in->desc.bInterval;
+               urb->interval = dev->isoc_in.endp->desc.bInterval;
                urb->number_of_packets = max_packets;
                urb->transfer_flags = URB_ISO_ASAP | URB_NO_TRANSFER_DMA_MAP;
 
drivers/staging/tm6000/tm6000.h +7 -0
index 7aeded8..13d5a3e 100644
@@ -132,6 +132,13 @@ struct tm6000_dvb {
        struct mutex            mutex;
  };
 
+struct tm6000_endpoint {
+       struct usb_host_endpoint        *endp;
+       __u8                            bInterfaceNumber;
+       __u8                            bAlternateSetting;
+       unsigned                        maxsize;
+};
+
  struct tm6000_core {
        /* generic device properties */

       char                            name[30];       /* name (including minor) of the device */

drivers/staging/tm6000/tm6000.h +0 -0
@@ -185,9 +192,7 @@ struct tm6000_core {
        /* usb transfer */

       struct usb_device               *udev;          /* the usb device */

-       struct usb_host_endpoint        *bulk_in, *bulk_out, *isoc_in, *isoc_out;
-       unsigned int                    max_bulk_in, max_bulk_out;
-       unsigned int                    max_isoc_in, max_isoc_out;
+       struct tm6000_endpoint          bulk_in, bulk_out, isoc_in, isoc_out;

       /* scaler!=0 if scaler is active*/
       int                             scaler;
--
To unsubscribe from this list: send the line "unsubscribe linux-media" in the body of a message to [email protected]
More majordomo info at  http://vger.kernel.org/majordomo-info.html