Commit ee1fc07c authored by Mauro Carvalho Chehab's avatar Mauro Carvalho Chehab
Browse files

V4L/DVB (12829): tm6000: several changes on usb preparation trying to avoid -EPROTO errors

parent c4acf48c
Loading
Loading
Loading
Loading
+49 −47
Original line number Diff line number Diff line
@@ -47,6 +47,8 @@
#define TM6000_MIN_BUF 4
#define TM6000_DEF_BUF 8

#define TM6000_MAX_ISO_PACKETS	40	/* Max number of ISO packets */

/* Declare static vars that will be used as parameters */
static unsigned int vid_limit = 16;	/* Video memory limit, in Mb */
static int video_nr = -1;		/* /dev/videoN, -1 for autodetect */
@@ -532,7 +534,7 @@ static void tm6000_irq_callback(struct urb *urb)
	struct tm6000_buffer    *buf;
	struct tm6000_dmaqueue  *dma_q = urb->context;
	struct tm6000_core *dev = container_of(dma_q, struct tm6000_core, vidq);
	int rc, i;
	int rc;
	unsigned long flags;

	spin_lock_irqsave(&dev->slock, flags);
@@ -550,11 +552,6 @@ static void tm6000_irq_callback(struct urb *urb)

	dev->isoc_ctl.buf = buf;
ret:
	/* Reset urb buffers */
	for (i = 0; i < urb->number_of_packets; i++) {
		urb->iso_frame_desc[i].status = 0;
		urb->iso_frame_desc[i].actual_length = 0;
	}

	urb->status = usb_submit_urb(urb, GFP_ATOMIC);
	if (urb->status)
@@ -613,28 +610,37 @@ static void tm6000_stop_thread(struct tm6000_dmaqueue *dma_q)
	tm6000_uninit_isoc(dev);
}


/*
 * Allocate URBs and start IRQ
 */
static int tm6000_prepare_isoc(struct tm6000_core *dev,
		     int max_packets, int num_bufs)
static int tm6000_prepare_isoc(struct tm6000_core *dev, unsigned int framesize)
{
	struct tm6000_dmaqueue *dma_q = &dev->vidq;
	int i;
	int sb_size, pipe;
	int i, j, sb_size, pipe, size, max_packets, num_bufs = 5;
	struct urb *urb;
	int j, k;

	dprintk(dev, V4L2_DEBUG_QUEUE, "Allocating %dx%d packets"
		    " of %d bytes each to handle %u size\n",
		    max_packets, num_bufs,
		    dev->max_isoc_in, dev->isoc_ctl.max_pkt_size);


	/* De-allocates all pending stuff */
	tm6000_uninit_isoc(dev);


	pipe = usb_rcvisocpipe(dev->udev,
			       dev->isoc_in->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;

	dev->isoc_ctl.max_pkt_size = size;

	max_packets = ( framesize + size - 1) / size;

	if (max_packets > TM6000_MAX_ISO_PACKETS)
		max_packets = TM6000_MAX_ISO_PACKETS;

	sb_size = max_packets * size;

	dev->isoc_ctl.num_bufs = num_bufs;

	dev->isoc_ctl.urb = kmalloc(sizeof(void *)*num_bufs,
@@ -652,9 +658,10 @@ static int tm6000_prepare_isoc(struct tm6000_core *dev,
		return -ENOMEM;
	}

	dev->isoc_ctl.max_pkt_size=dev->max_isoc_in;

	sb_size = max_packets * dev->isoc_ctl.max_pkt_size;
	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);


	/* allocate urbs and transfer buffers */
@@ -680,23 +687,17 @@ static int tm6000_prepare_isoc(struct tm6000_core *dev,
		}
		memset(dev->isoc_ctl.transfer_buffer[i], 0, sb_size);

		pipe=usb_rcvisocpipe(dev->udev,
					dev->isoc_in->desc.bEndpointAddress &
					USB_ENDPOINT_NUMBER_MASK);
		usb_fill_int_urb(urb, dev->udev, pipe,
		usb_fill_bulk_urb(urb, dev->udev, pipe,
				  dev->isoc_ctl.transfer_buffer[i], sb_size,
					tm6000_irq_callback, dma_q,
					dev->isoc_in->desc.bInterval);

				  tm6000_irq_callback, dma_q);
//		urb->interval = dev->isoc_in->desc.bInterval;
		urb->interval = 2;
		urb->number_of_packets = max_packets;
		urb->transfer_flags = URB_ISO_ASAP;
		urb->transfer_flags = URB_ISO_ASAP | URB_NO_TRANSFER_DMA_MAP;

		k = 0;
		for (j = 0; j < max_packets; j++) {
			urb->iso_frame_desc[j].offset = k;
			urb->iso_frame_desc[j].length =
						dev->isoc_ctl.max_pkt_size;
			k += dev->isoc_ctl.max_pkt_size;
			urb->iso_frame_desc[j].offset = size * j;
			urb->iso_frame_desc[j].length = size;
		}
	}

@@ -890,7 +891,8 @@ buffer_prepare(struct videobuf_queue *vq, struct videobuf_buffer *vb,
		urb_init = 1;

	if (urb_init) {
		rc = tm6000_prepare_isoc(dev, 128, 1);
		rc = tm6000_prepare_isoc(dev, buf->vb.size);

		if (rc < 0)
			goto fail;
	}