예제 #1
0
static inline int dvb_isoc_copy(struct em28xx *dev, struct urb *urb)
{
	int i;

	if (!dev)
		return 0;

	if ((dev->state & DEV_DISCONNECTED) || (dev->state & DEV_MISCONFIGURED))
		return 0;

	if (urb->status < 0) {
		print_err_status(dev, -1, urb->status);
		if (urb->status == -ENOENT)
			return 0;
	}

	for (i = 0; i < urb->number_of_packets; i++) {
		int status = urb->iso_frame_desc[i].status;

		if (status < 0) {
			print_err_status(dev, i, status);
			if (urb->iso_frame_desc[i].status != -EPROTO)
				continue;
		}

		dvb_dmx_swfilter(&dev->dvb->demux, urb->transfer_buffer +
				 urb->iso_frame_desc[i].offset,
				 urb->iso_frame_desc[i].actual_length);
	}

	return 0;
}
예제 #2
0
static inline int em28xx_dvb_urb_data_copy(struct em28xx *dev, struct urb *urb)
{
	int xfer_bulk, num_packets, i;

	if (!dev)
		return 0;

	if (dev->disconnected)
		return 0;

	if (urb->status < 0)
		print_err_status(dev, -1, urb->status);

	xfer_bulk = usb_pipebulk(urb->pipe);

	if (xfer_bulk) /* bulk */
		num_packets = 1;
	else /* isoc */
		num_packets = urb->number_of_packets;

	for (i = 0; i < num_packets; i++) {
		if (xfer_bulk) {
			if (urb->status < 0) {
				print_err_status(dev, i, urb->status);
				if (urb->status != -EPROTO)
					continue;
			}
			if (!urb->actual_length)
				continue;
			dvb_dmx_swfilter(&dev->dvb->demux, urb->transfer_buffer,
					urb->actual_length);
		} else {
			if (urb->iso_frame_desc[i].status < 0) {
				print_err_status(dev, i,
						 urb->iso_frame_desc[i].status);
				if (urb->iso_frame_desc[i].status != -EPROTO)
					continue;
			}
			if (!urb->iso_frame_desc[i].actual_length)
				continue;
			dvb_dmx_swfilter(&dev->dvb->demux,
					 urb->transfer_buffer +
					 urb->iso_frame_desc[i].offset,
					 urb->iso_frame_desc[i].actual_length);
		}
	}

	return 0;
}
예제 #3
0
파일: tm6000-dvb.c 프로젝트: 020gzh/linux
static void tm6000_urb_received(struct urb *urb)
{
	int ret;
	struct tm6000_core *dev = urb->context;

	switch (urb->status) {
	case 0:
	case -ETIMEDOUT:
		break;
	case -ENOENT:
	case -ECONNRESET:
	case -ESHUTDOWN:
		return;
	default:
		print_err_status(dev, 0, urb->status);
	}

	if (urb->actual_length > 0)
		dvb_dmx_swfilter(&dev->dvb->demux, urb->transfer_buffer,
						   urb->actual_length);

	if (dev->dvb->streams > 0) {
		ret = usb_submit_urb(urb, GFP_ATOMIC);
		if (ret < 0) {
			printk(KERN_ERR "tm6000:  error %s\n", __func__);
			kfree(urb->transfer_buffer);
			usb_free_urb(urb);
		}
	}
}
예제 #4
0
static void tm6000_urb_received(struct urb *urb)
{
	int ret;
	struct tm6000_core *dev = urb->context;

	if (urb->status != 0)
		print_err_status(dev, 0, urb->status);
	else if (urb->actual_length > 0)
		dvb_dmx_swfilter(&dev->dvb->demux, urb->transfer_buffer,
						   urb->actual_length);

	if (dev->dvb->streams > 0) {
		ret = usb_submit_urb(urb, GFP_ATOMIC);
		if (ret < 0) {
			printk(KERN_ERR "tm6000:  error %s\n", __func__);
			kfree(urb->transfer_buffer);
			usb_free_urb(urb);
		}
	}
}
예제 #5
0
/*
 * Controls the isoc copy of each urb packet
 */
static inline int cx231xx_isoc_vbi_copy(struct cx231xx *dev, struct urb *urb)
{
	struct cx231xx_dmaqueue *dma_q = urb->context;
	int rc = 1;
	unsigned char *p_buffer;
	u32 bytes_parsed = 0, buffer_size = 0;
	u8 sav_eav = 0;

	if (!dev)
		return 0;

	if (dev->state & DEV_DISCONNECTED)
		return 0;

	if (urb->status < 0) {
		print_err_status(dev, -1, urb->status);
		if (urb->status == -ENOENT)
			return 0;
	}

	/* get buffer pointer and length */
	p_buffer = urb->transfer_buffer;
	buffer_size = urb->actual_length;

	if (buffer_size > 0) {
		bytes_parsed = 0;

		if (dma_q->is_partial_line) {
			/* Handle the case where we were working on a partial
			   line */
			sav_eav = dma_q->last_sav;
		} else {
			/* Check for a SAV/EAV overlapping the
			   buffer boundary */

			sav_eav = cx231xx_find_boundary_SAV_EAV(p_buffer,
							  dma_q->partial_buf,
							  &bytes_parsed);
		}

		sav_eav &= 0xF0;
		/* Get the first line if we have some portion of an SAV/EAV from
		   the last buffer or a partial line */
		if (sav_eav) {
			bytes_parsed += cx231xx_get_vbi_line(dev, dma_q,
				sav_eav,		       /* SAV/EAV */
				p_buffer + bytes_parsed,       /* p_buffer */
				buffer_size - bytes_parsed);   /* buffer size */
		}

		/* Now parse data that is completely in this buffer */
		dma_q->is_partial_line = 0;

		while (bytes_parsed < buffer_size) {
			u32 bytes_used = 0;

			sav_eav = cx231xx_find_next_SAV_EAV(
				p_buffer + bytes_parsed,	/* p_buffer */
				buffer_size - bytes_parsed, /* buffer size */
				&bytes_used);	/* bytes used to get SAV/EAV */

			bytes_parsed += bytes_used;

			sav_eav &= 0xF0;
			if (sav_eav && (bytes_parsed < buffer_size)) {
				bytes_parsed += cx231xx_get_vbi_line(dev,
					dma_q, sav_eav,	/* SAV/EAV */
					p_buffer+bytes_parsed, /* p_buffer */
					buffer_size-bytes_parsed);/*buf size*/
			}
		}

		/* Save the last four bytes of the buffer so we can
		check the buffer boundary condition next time */
		memcpy(dma_q->partial_buf, p_buffer + buffer_size - 4, 4);
		bytes_parsed = 0;
	}

	return rc;
}