Linux-2.6.12-rc2

Initial git repository build. I'm not bothering with the full history,
even though we have it. We can create a separate "historical" git
archive of that later if we want to, and in the meantime it's about
3.2GB when imported into git - space that would just make the early
git days unnecessarily complicated, when we don't have a lot of good
infrastructure for it.

Let it rip!
diff --git a/drivers/media/dvb/dibusb/dvb-dibusb-usb.c b/drivers/media/dvb/dibusb/dvb-dibusb-usb.c
new file mode 100644
index 0000000..642f059
--- /dev/null
+++ b/drivers/media/dvb/dibusb/dvb-dibusb-usb.c
@@ -0,0 +1,303 @@
+/*
+ * dvb-dibusb-usb.c is part of the driver for mobile USB Budget DVB-T devices
+ * based on reference design made by DiBcom (http://www.dibcom.fr/)
+ *
+ * Copyright (C) 2004-5 Patrick Boettcher (patrick.boettcher@desy.de)
+ *
+ * see dvb-dibusb-core.c for more copyright details.
+ *
+ * This file contains functions for initializing and handling the
+ * usb specific stuff.
+ */
+#include "dvb-dibusb.h"
+
+#include <linux/version.h>
+#include <linux/pci.h>
+
+int dibusb_readwrite_usb(struct usb_dibusb *dib, u8 *wbuf, u16 wlen, u8 *rbuf,
+		u16 rlen)
+{
+	int actlen,ret = -ENOMEM;
+
+	if (wbuf == NULL || wlen == 0)
+		return -EINVAL;
+
+	if ((ret = down_interruptible(&dib->usb_sem)))
+		return ret;
+
+	debug_dump(wbuf,wlen);
+
+	ret = usb_bulk_msg(dib->udev,usb_sndbulkpipe(dib->udev,
+			dib->dibdev->dev_cl->pipe_cmd), wbuf,wlen,&actlen,
+			DIBUSB_I2C_TIMEOUT);
+
+	if (ret)
+		err("bulk message failed: %d (%d/%d)",ret,wlen,actlen);
+	else
+		ret = actlen != wlen ? -1 : 0;
+
+	/* an answer is expected, and no error before */
+	if (!ret && rbuf && rlen) {
+		ret = usb_bulk_msg(dib->udev,usb_rcvbulkpipe(dib->udev,
+				dib->dibdev->dev_cl->pipe_cmd),rbuf,rlen,&actlen,
+				DIBUSB_I2C_TIMEOUT);
+
+		if (ret)
+			err("recv bulk message failed: %d",ret);
+		else {
+			deb_alot("rlen: %d\n",rlen);
+			debug_dump(rbuf,actlen);
+		}
+	}
+
+	up(&dib->usb_sem);
+	return ret;
+}
+
+/*
+ * Cypress controls
+ */
+int dibusb_write_usb(struct usb_dibusb *dib, u8 *buf, u16 len)
+{
+	return dibusb_readwrite_usb(dib,buf,len,NULL,0);
+}
+
+#if 0
+/*
+ * #if 0'ing the following functions as they are not in use _now_,
+ * but probably will be sometime.
+ */
+/*
+ * do not use this, just a workaround for a bug,
+ * which will hopefully never occur :).
+ */
+int dibusb_interrupt_read_loop(struct usb_dibusb *dib)
+{
+	u8 b[1] = { DIBUSB_REQ_INTR_READ };
+	return dibusb_write_usb(dib,b,1);
+}
+#endif
+
+/*
+ * ioctl for the firmware
+ */
+static int dibusb_ioctl_cmd(struct usb_dibusb *dib, u8 cmd, u8 *param, int plen)
+{
+	u8 b[34];
+	int size = plen > 32 ? 32 : plen;
+	memset(b,0,34);
+	b[0] = DIBUSB_REQ_SET_IOCTL;
+	b[1] = cmd;
+
+	if (size > 0)
+		memcpy(&b[2],param,size);
+
+	return dibusb_write_usb(dib,b,34); //2+size);
+}
+
+/*
+ * ioctl for power control
+ */
+int dibusb_hw_wakeup(struct dvb_frontend *fe)
+{
+	struct usb_dibusb *dib = (struct usb_dibusb *) fe->dvb->priv;
+	u8 b[1] = { DIBUSB_IOCTL_POWER_WAKEUP };
+	deb_info("dibusb-device is getting up.\n");
+
+	switch (dib->dibdev->dev_cl->id) {
+		case DTT200U:
+			break;
+		default:
+			dibusb_ioctl_cmd(dib,DIBUSB_IOCTL_CMD_POWER_MODE, b,1);
+			break;
+	}
+
+	if (dib->fe_init)
+		return dib->fe_init(fe);
+
+	return 0;
+}
+
+int dibusb_hw_sleep(struct dvb_frontend *fe)
+{
+	struct usb_dibusb *dib = (struct usb_dibusb *) fe->dvb->priv;
+	u8 b[1] = { DIBUSB_IOCTL_POWER_SLEEP };
+	deb_info("dibusb-device is going to bed.\n");
+	/* workaround, something is wrong, when dibusb 1.1 device are going to bed too late */
+	switch (dib->dibdev->dev_cl->id) {
+		case DIBUSB1_1:
+		case NOVAT_USB2:
+		case DTT200U:
+			break;
+		default:
+			dibusb_ioctl_cmd(dib,DIBUSB_IOCTL_CMD_POWER_MODE, b,1);
+			break;
+	}
+	if (dib->fe_sleep)
+		return dib->fe_sleep(fe);
+
+	return 0;
+}
+
+int dibusb_set_streaming_mode(struct usb_dibusb *dib,u8 mode)
+{
+	u8 b[2] = { DIBUSB_REQ_SET_STREAMING_MODE, mode };
+	return dibusb_readwrite_usb(dib,b,2,NULL,0);
+}
+
+static int dibusb_urb_kill(struct usb_dibusb *dib)
+{
+	int i;
+deb_info("trying to kill urbs\n");
+	if (dib->init_state & DIBUSB_STATE_URB_SUBMIT) {
+		for (i = 0; i < dib->dibdev->dev_cl->urb_count; i++) {
+			deb_info("killing URB no. %d.\n",i);
+
+			/* stop the URB */
+			usb_kill_urb(dib->urb_list[i]);
+		}
+	} else
+	deb_info(" URBs not killed.\n");
+	dib->init_state &= ~DIBUSB_STATE_URB_SUBMIT;
+	return 0;
+}
+
+static int dibusb_urb_submit(struct usb_dibusb *dib)
+{
+	int i,ret;
+	if (dib->init_state & DIBUSB_STATE_URB_INIT) {
+		for (i = 0; i < dib->dibdev->dev_cl->urb_count; i++) {
+			deb_info("submitting URB no. %d\n",i);
+			if ((ret = usb_submit_urb(dib->urb_list[i],GFP_ATOMIC))) {
+				err("could not submit buffer urb no. %d - get them all back\n",i);
+				dibusb_urb_kill(dib);
+				return ret;
+			}
+			dib->init_state |= DIBUSB_STATE_URB_SUBMIT;
+		}
+	}
+	return 0;
+}
+
+int dibusb_streaming(struct usb_dibusb *dib,int onoff)
+{
+	if (onoff)
+		dibusb_urb_submit(dib);
+	else
+		dibusb_urb_kill(dib);
+
+	switch (dib->dibdev->dev_cl->id) {
+		case DIBUSB2_0:
+		case DIBUSB2_0B:
+		case NOVAT_USB2:
+		case UMT2_0:
+			if (onoff)
+				return dibusb_ioctl_cmd(dib,DIBUSB_IOCTL_CMD_ENABLE_STREAM,NULL,0);
+			else
+				return dibusb_ioctl_cmd(dib,DIBUSB_IOCTL_CMD_DISABLE_STREAM,NULL,0);
+			break;
+		default:
+			break;
+	}
+	return 0;
+}
+
+int dibusb_urb_init(struct usb_dibusb *dib)
+{
+	int i,bufsize,def_pid_parse = 1;
+
+	/*
+	 * when reloading the driver w/o replugging the device
+	 * a timeout occures, this helps
+	 */
+	usb_clear_halt(dib->udev,usb_sndbulkpipe(dib->udev,dib->dibdev->dev_cl->pipe_cmd));
+	usb_clear_halt(dib->udev,usb_rcvbulkpipe(dib->udev,dib->dibdev->dev_cl->pipe_cmd));
+	usb_clear_halt(dib->udev,usb_rcvbulkpipe(dib->udev,dib->dibdev->dev_cl->pipe_data));
+
+	/* allocate the array for the data transfer URBs */
+	dib->urb_list = kmalloc(dib->dibdev->dev_cl->urb_count*sizeof(struct urb *),GFP_KERNEL);
+	if (dib->urb_list == NULL)
+		return -ENOMEM;
+	memset(dib->urb_list,0,dib->dibdev->dev_cl->urb_count*sizeof(struct urb *));
+
+	dib->init_state |= DIBUSB_STATE_URB_LIST;
+
+	bufsize = dib->dibdev->dev_cl->urb_count*dib->dibdev->dev_cl->urb_buffer_size;
+	deb_info("allocate %d bytes as buffersize for all URBs\n",bufsize);
+	/* allocate the actual buffer for the URBs */
+	if ((dib->buffer = pci_alloc_consistent(NULL,bufsize,&dib->dma_handle)) == NULL) {
+		deb_info("not enough memory.\n");
+		return -ENOMEM;
+	}
+	deb_info("allocation complete\n");
+	memset(dib->buffer,0,bufsize);
+
+	dib->init_state |= DIBUSB_STATE_URB_BUF;
+
+	/* allocate and submit the URBs */
+	for (i = 0; i < dib->dibdev->dev_cl->urb_count; i++) {
+		if (!(dib->urb_list[i] = usb_alloc_urb(0,GFP_ATOMIC))) {
+			return -ENOMEM;
+		}
+
+		usb_fill_bulk_urb( dib->urb_list[i], dib->udev,
+				usb_rcvbulkpipe(dib->udev,dib->dibdev->dev_cl->pipe_data),
+				&dib->buffer[i*dib->dibdev->dev_cl->urb_buffer_size],
+				dib->dibdev->dev_cl->urb_buffer_size,
+				dibusb_urb_complete, dib);
+
+		dib->urb_list[i]->transfer_flags = 0;
+
+		dib->init_state |= DIBUSB_STATE_URB_INIT;
+	}
+
+	/* dib->pid_parse here contains the value of the module parameter */
+	/* decide if pid parsing can be deactivated:
+	 * is possible (by device type) and wanted (by user)
+	 */
+	switch (dib->dibdev->dev_cl->id) {
+		case DIBUSB2_0:
+		case DIBUSB2_0B:
+			if (dib->udev->speed == USB_SPEED_HIGH && !dib->pid_parse) {
+				def_pid_parse = 0;
+				info("running at HIGH speed, will deliver the complete TS.");
+			} else
+				info("will use pid_parsing.");
+			break;
+		default:
+			break;
+	}
+	/* from here on it contains the device and user decision */
+	dib->pid_parse = def_pid_parse;
+
+	return 0;
+}
+
+int dibusb_urb_exit(struct usb_dibusb *dib)
+{
+	int i;
+
+	dibusb_urb_kill(dib);
+
+	if (dib->init_state & DIBUSB_STATE_URB_LIST) {
+		for (i = 0; i < dib->dibdev->dev_cl->urb_count; i++) {
+			if (dib->urb_list[i] != NULL) {
+				deb_info("freeing URB no. %d.\n",i);
+				/* free the URBs */
+				usb_free_urb(dib->urb_list[i]);
+			}
+		}
+		/* free the urb array */
+		kfree(dib->urb_list);
+		dib->init_state &= ~DIBUSB_STATE_URB_LIST;
+	}
+
+	if (dib->init_state & DIBUSB_STATE_URB_BUF)
+		pci_free_consistent(NULL,
+			dib->dibdev->dev_cl->urb_buffer_size*dib->dibdev->dev_cl->urb_count,
+			dib->buffer,dib->dma_handle);
+
+	dib->init_state &= ~DIBUSB_STATE_URB_BUF;
+	dib->init_state &= ~DIBUSB_STATE_URB_INIT;
+	return 0;
+}