Re: [PATCH] [media] dabusb: Move it to staging to be deprecated

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Wait!

It supports the DRBox1 DAB sold by Terratec:
http://www.baycom.de/wiki/index.php/Products::dabusbhw

I've been working on a free firmware for this device:
http://libreplanet.org/wiki/LinuxLibre:USB_DABUSB

Felipe Sanches

On Mon, Dec 27, 2010 at 7:22 PM, Mauro Carvalho Chehab
<mchehab@xxxxxxxxxx> wrote:
> From cd1b06628baa2cc4780e70922623aac310d890e1 Mon Sep 17 00:00:00 2001
> From: Mauro Carvalho Chehab <mchehab@xxxxxxxxxx>
> Date: Mon, 27 Dec 2010 19:17:12 -0200
> Subject: [PATCH] [media] dabusb: Move it to staging to be deprecated
>
> dabusb driver were conceived as an experimental driver for a test
> device. The driver never supported any shipped product, and, while
> there were some updates on it in 2003, for an ancient product,
> those changes were never submitted upstream.
>
> Also, there's no DocBook for its API, nor any upstream discussion.
>
> So, better to remove it, on .39. If later needed, we may rescue it
> from git logs. For now, let's move it to staging.
>
> Acked-by: Deti Fliegl <deti@xxxxxxxxx>
> gned-off-by: Mauro Carvalho Chehab <mchehab@xxxxxxxxxx>
>
> diff --git a/drivers/media/Kconfig b/drivers/media/Kconfig
> index 147c92b..81b3ba8 100644
> --- a/drivers/media/Kconfig
> +++ b/drivers/media/Kconfig
> @@ -92,26 +92,4 @@ source "drivers/media/radio/Kconfig"
>
>  source "drivers/media/dvb/Kconfig"
>
> -config DAB
> -       boolean "DAB adapters"
> -       ---help---
> -         Allow selecting support for Digital Audio Broadcasting (DAB)
> -         Receiver adapters.
> -
> -if DAB
> -config USB_DABUSB
> -       tristate "DABUSB driver"
> -       depends on USB
> -       ---help---
> -         A Digital Audio Broadcasting (DAB) Receiver for USB and Linux
> -         brought to you by the DAB-Team
> -         <http://wwwbode.cs.tum.edu/Par/arch/dab/>.  This driver can be taken
> -         as an example for URB-based bulk, control, and isochronous
> -         transactions. URB's are explained in
> -         <Documentation/usb/URB.txt>.
> -
> -         To compile this driver as a module, choose M here: the
> -         module will be called dabusb.
> -endif # DAB
> -
>  endif # MEDIA_SUPPORT
> diff --git a/drivers/media/video/Makefile b/drivers/media/video/Makefile
> index fd684dd..98825e7 100644
> --- a/drivers/media/video/Makefile
> +++ b/drivers/media/video/Makefile
> @@ -121,7 +121,6 @@ obj-$(CONFIG_VIDEO_CAFE_CCIC) += cafe_ccic.o
>
>  obj-$(CONFIG_VIDEO_VIA_CAMERA) += via-camera.o
>
> -obj-$(CONFIG_USB_DABUSB)        += dabusb.o
>  obj-$(CONFIG_USB_ZR364XX)       += zr364xx.o
>  obj-$(CONFIG_USB_STKWEBCAM)     += stkwebcam.o
>
> diff --git a/drivers/media/video/dabusb.c b/drivers/media/video/dabusb.c
> deleted file mode 100644
> index f3e25e9..0000000
> --- a/drivers/media/video/dabusb.c
> +++ /dev/null
> @@ -1,914 +0,0 @@
> -/*****************************************************************************/
> -
> -/*
> - *      dabusb.c  --  dab usb driver.
> - *
> - *      Copyright (C) 1999  Deti Fliegl (deti@xxxxxxxxx)
> - *
> - *      This program is free software; you can redistribute it and/or modify
> - *      it under the terms of the GNU General Public License as published by
> - *      the Free Software Foundation; either version 2 of the License, or
> - *      (at your option) any later version.
> - *
> - *      This program is distributed in the hope that it will be useful,
> - *      but WITHOUT ANY WARRANTY; without even the implied warranty of
> - *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> - *      GNU General Public License for more details.
> - *
> - *      You should have received a copy of the GNU General Public License
> - *      along with this program; if not, write to the Free Software
> - *      Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
> - *
> - *
> - *
> - *  $Id: dabusb.c,v 1.54 2000/07/24 21:39:39 deti Exp $
> - *
> - */
> -
> -/*****************************************************************************/
> -
> -#include <linux/module.h>
> -#include <linux/socket.h>
> -#include <linux/list.h>
> -#include <linux/vmalloc.h>
> -#include <linux/slab.h>
> -#include <linux/init.h>
> -#include <asm/uaccess.h>
> -#include <asm/atomic.h>
> -#include <linux/delay.h>
> -#include <linux/usb.h>
> -#include <linux/mutex.h>
> -#include <linux/firmware.h>
> -#include <linux/ihex.h>
> -
> -#include "dabusb.h"
> -
> -/*
> - * Version Information
> - */
> -#define DRIVER_VERSION "v1.54"
> -#define DRIVER_AUTHOR "Deti Fliegl, deti@xxxxxxxxx"
> -#define DRIVER_DESC "DAB-USB Interface Driver for Linux (c)1999"
> -
> -/* --------------------------------------------------------------------- */
> -
> -#ifdef CONFIG_USB_DYNAMIC_MINORS
> -#define NRDABUSB 256
> -#else
> -#define NRDABUSB 4
> -#endif
> -
> -/*-------------------------------------------------------------------*/
> -
> -static dabusb_t dabusb[NRDABUSB];
> -static int buffers = 256;
> -static struct usb_driver dabusb_driver;
> -
> -/*-------------------------------------------------------------------*/
> -
> -static int dabusb_add_buf_tail (pdabusb_t s, struct list_head *dst, struct list_head *src)
> -{
> -       unsigned long flags;
> -       struct list_head *tmp;
> -       int ret = 0;
> -
> -       spin_lock_irqsave (&s->lock, flags);
> -
> -       if (list_empty (src)) {
> -               // no elements in source buffer
> -               ret = -1;
> -               goto err;
> -       }
> -       tmp = src->next;
> -       list_move_tail (tmp, dst);
> -
> -  err: spin_unlock_irqrestore (&s->lock, flags);
> -       return ret;
> -}
> -/*-------------------------------------------------------------------*/
> -#ifdef DEBUG
> -static void dump_urb (struct urb *urb)
> -{
> -       dbg("urb                   :%p", urb);
> -       dbg("dev                   :%p", urb->dev);
> -       dbg("pipe                  :%08X", urb->pipe);
> -       dbg("status                :%d", urb->status);
> -       dbg("transfer_flags        :%08X", urb->transfer_flags);
> -       dbg("transfer_buffer       :%p", urb->transfer_buffer);
> -       dbg("transfer_buffer_length:%d", urb->transfer_buffer_length);
> -       dbg("actual_length         :%d", urb->actual_length);
> -       dbg("setup_packet          :%p", urb->setup_packet);
> -       dbg("start_frame           :%d", urb->start_frame);
> -       dbg("number_of_packets     :%d", urb->number_of_packets);
> -       dbg("interval              :%d", urb->interval);
> -       dbg("error_count           :%d", urb->error_count);
> -       dbg("context               :%p", urb->context);
> -       dbg("complete              :%p", urb->complete);
> -}
> -#endif
> -/*-------------------------------------------------------------------*/
> -static int dabusb_cancel_queue (pdabusb_t s, struct list_head *q)
> -{
> -       unsigned long flags;
> -       pbuff_t b;
> -
> -       dbg("dabusb_cancel_queue");
> -
> -       spin_lock_irqsave (&s->lock, flags);
> -
> -       list_for_each_entry(b, q, buff_list) {
> -#ifdef DEBUG
> -               dump_urb(b->purb);
> -#endif
> -               usb_unlink_urb (b->purb);
> -       }
> -       spin_unlock_irqrestore (&s->lock, flags);
> -       return 0;
> -}
> -/*-------------------------------------------------------------------*/
> -static int dabusb_free_queue (struct list_head *q)
> -{
> -       struct list_head *tmp;
> -       struct list_head *p;
> -       pbuff_t b;
> -
> -       dbg("dabusb_free_queue");
> -       for (p = q->next; p != q;) {
> -               b = list_entry (p, buff_t, buff_list);
> -
> -#ifdef DEBUG
> -               dump_urb(b->purb);
> -#endif
> -               kfree(b->purb->transfer_buffer);
> -               usb_free_urb(b->purb);
> -               tmp = p->next;
> -               list_del (p);
> -               kfree (b);
> -               p = tmp;
> -       }
> -
> -       return 0;
> -}
> -/*-------------------------------------------------------------------*/
> -static int dabusb_free_buffers (pdabusb_t s)
> -{
> -       unsigned long flags;
> -       dbg("dabusb_free_buffers");
> -
> -       spin_lock_irqsave(&s->lock, flags);
> -
> -       dabusb_free_queue (&s->free_buff_list);
> -       dabusb_free_queue (&s->rec_buff_list);
> -
> -       spin_unlock_irqrestore(&s->lock, flags);
> -
> -       s->got_mem = 0;
> -       return 0;
> -}
> -/*-------------------------------------------------------------------*/
> -static void dabusb_iso_complete (struct urb *purb)
> -{
> -       pbuff_t b = purb->context;
> -       pdabusb_t s = b->s;
> -       int i;
> -       int len;
> -       int dst = 0;
> -       void *buf = purb->transfer_buffer;
> -
> -       dbg("dabusb_iso_complete");
> -
> -       // process if URB was not killed
> -       if (purb->status != -ENOENT) {
> -               unsigned int pipe = usb_rcvisocpipe (purb->dev, _DABUSB_ISOPIPE);
> -               int pipesize = usb_maxpacket (purb->dev, pipe, usb_pipeout (pipe));
> -               for (i = 0; i < purb->number_of_packets; i++)
> -                       if (!purb->iso_frame_desc[i].status) {
> -                               len = purb->iso_frame_desc[i].actual_length;
> -                               if (len <= pipesize) {
> -                                       memcpy (buf + dst, buf + purb->iso_frame_desc[i].offset, len);
> -                                       dst += len;
> -                               }
> -                               else
> -                                       dev_err(&purb->dev->dev,
> -                                               "dabusb_iso_complete: invalid len %d\n", len);
> -                       }
> -                       else
> -                               dev_warn(&purb->dev->dev, "dabusb_iso_complete: corrupted packet status: %d\n", purb->iso_frame_desc[i].status);
> -               if (dst != purb->actual_length)
> -                       dev_err(&purb->dev->dev,
> -                               "dst!=purb->actual_length:%d!=%d\n",
> -                                       dst, purb->actual_length);
> -       }
> -
> -       if (atomic_dec_and_test (&s->pending_io) && !s->remove_pending && s->state != _stopped) {
> -               s->overruns++;
> -               dev_err(&purb->dev->dev, "overrun (%d)\n", s->overruns);
> -       }
> -       wake_up (&s->wait);
> -}
> -/*-------------------------------------------------------------------*/
> -static int dabusb_alloc_buffers (pdabusb_t s)
> -{
> -       int transfer_len = 0;
> -       pbuff_t b;
> -       unsigned int pipe = usb_rcvisocpipe (s->usbdev, _DABUSB_ISOPIPE);
> -       int pipesize = usb_maxpacket (s->usbdev, pipe, usb_pipeout (pipe));
> -       int packets = _ISOPIPESIZE / pipesize;
> -       int transfer_buffer_length = packets * pipesize;
> -       int i;
> -
> -       dbg("dabusb_alloc_buffers pipesize:%d packets:%d transfer_buffer_len:%d",
> -                pipesize, packets, transfer_buffer_length);
> -
> -       while (transfer_len < (s->total_buffer_size << 10)) {
> -               b = kzalloc(sizeof (buff_t), GFP_KERNEL);
> -               if (!b) {
> -                       dev_err(&s->usbdev->dev,
> -                               "kzalloc(sizeof(buff_t))==NULL\n");
> -                       goto err;
> -               }
> -               b->s = s;
> -               b->purb = usb_alloc_urb(packets, GFP_KERNEL);
> -               if (!b->purb) {
> -                       dev_err(&s->usbdev->dev, "usb_alloc_urb == NULL\n");
> -                       kfree (b);
> -                       goto err;
> -               }
> -
> -               b->purb->transfer_buffer = kmalloc (transfer_buffer_length, GFP_KERNEL);
> -               if (!b->purb->transfer_buffer) {
> -                       kfree (b->purb);
> -                       kfree (b);
> -                       dev_err(&s->usbdev->dev,
> -                               "kmalloc(%d)==NULL\n", transfer_buffer_length);
> -                       goto err;
> -               }
> -
> -               b->purb->transfer_buffer_length = transfer_buffer_length;
> -               b->purb->number_of_packets = packets;
> -               b->purb->complete = dabusb_iso_complete;
> -               b->purb->context = b;
> -               b->purb->dev = s->usbdev;
> -               b->purb->pipe = pipe;
> -               b->purb->transfer_flags = URB_ISO_ASAP;
> -
> -               for (i = 0; i < packets; i++) {
> -                       b->purb->iso_frame_desc[i].offset = i * pipesize;
> -                       b->purb->iso_frame_desc[i].length = pipesize;
> -               }
> -
> -               transfer_len += transfer_buffer_length;
> -               list_add_tail (&b->buff_list, &s->free_buff_list);
> -       }
> -       s->got_mem = transfer_len;
> -
> -       return 0;
> -
> -       err:
> -       dabusb_free_buffers (s);
> -       return -ENOMEM;
> -}
> -/*-------------------------------------------------------------------*/
> -static int dabusb_bulk (pdabusb_t s, pbulk_transfer_t pb)
> -{
> -       int ret;
> -       unsigned int pipe;
> -       int actual_length;
> -
> -       dbg("dabusb_bulk");
> -
> -       if (!pb->pipe)
> -               pipe = usb_rcvbulkpipe (s->usbdev, 2);
> -       else
> -               pipe = usb_sndbulkpipe (s->usbdev, 2);
> -
> -       ret=usb_bulk_msg(s->usbdev, pipe, pb->data, pb->size, &actual_length, 100);
> -       if(ret<0) {
> -               dev_err(&s->usbdev->dev,
> -                       "usb_bulk_msg failed(%d)\n", ret);
> -
> -               if (usb_set_interface (s->usbdev, _DABUSB_IF, 1) < 0) {
> -                       dev_err(&s->usbdev->dev, "set_interface failed\n");
> -                       return -EINVAL;
> -               }
> -
> -       }
> -
> -       if( ret == -EPIPE ) {
> -               dev_warn(&s->usbdev->dev, "CLEAR_FEATURE request to remove STALL condition.\n");
> -               if(usb_clear_halt(s->usbdev, usb_pipeendpoint(pipe)))
> -                       dev_err(&s->usbdev->dev, "request failed\n");
> -       }
> -
> -       pb->size = actual_length;
> -       return ret;
> -}
> -/* --------------------------------------------------------------------- */
> -static int dabusb_writemem (pdabusb_t s, int pos, const unsigned char *data,
> -                           int len)
> -{
> -       int ret;
> -       unsigned char *transfer_buffer =  kmalloc (len, GFP_KERNEL);
> -
> -       if (!transfer_buffer) {
> -               dev_err(&s->usbdev->dev,
> -                       "dabusb_writemem: kmalloc(%d) failed.\n", len);
> -               return -ENOMEM;
> -       }
> -
> -       memcpy (transfer_buffer, data, len);
> -
> -       ret=usb_control_msg(s->usbdev, usb_sndctrlpipe( s->usbdev, 0 ), 0xa0, 0x40, pos, 0, transfer_buffer, len, 300);
> -
> -       kfree (transfer_buffer);
> -       return ret;
> -}
> -/* --------------------------------------------------------------------- */
> -static int dabusb_8051_reset (pdabusb_t s, unsigned char reset_bit)
> -{
> -       dbg("dabusb_8051_reset: %d",reset_bit);
> -       return dabusb_writemem (s, CPUCS_REG, &reset_bit, 1);
> -}
> -/* --------------------------------------------------------------------- */
> -static int dabusb_loadmem (pdabusb_t s, const char *fname)
> -{
> -       int ret;
> -       const struct ihex_binrec *rec;
> -       const struct firmware *uninitialized_var(fw);
> -
> -       dbg("Enter dabusb_loadmem (internal)");
> -
> -       ret = request_ihex_firmware(&fw, "dabusb/firmware.fw", &s->usbdev->dev);
> -       if (ret) {
> -               dev_err(&s->usbdev->dev,
> -                       "Failed to load \"dabusb/firmware.fw\": %d\n", ret);
> -               goto out;
> -       }
> -       ret = dabusb_8051_reset (s, 1);
> -
> -       for (rec = (const struct ihex_binrec *)fw->data; rec;
> -            rec = ihex_next_binrec(rec)) {
> -               dbg("dabusb_writemem: %04X %p %d)", be32_to_cpu(rec->addr),
> -                   rec->data, be16_to_cpu(rec->len));
> -
> -               ret = dabusb_writemem(s, be32_to_cpu(rec->addr), rec->data,
> -                                      be16_to_cpu(rec->len));
> -               if (ret < 0) {
> -                       dev_err(&s->usbdev->dev,
> -                               "dabusb_writemem failed (%d %04X %p %d)\n",
> -                               ret, be32_to_cpu(rec->addr),
> -                               rec->data, be16_to_cpu(rec->len));
> -                       break;
> -               }
> -       }
> -       ret = dabusb_8051_reset (s, 0);
> -       release_firmware(fw);
> - out:
> -       dbg("dabusb_loadmem: exit");
> -
> -       return ret;
> -}
> -/* --------------------------------------------------------------------- */
> -static int dabusb_fpga_clear (pdabusb_t s, pbulk_transfer_t b)
> -{
> -       b->size = 4;
> -       b->data[0] = 0x2a;
> -       b->data[1] = 0;
> -       b->data[2] = 0;
> -       b->data[3] = 0;
> -
> -       dbg("dabusb_fpga_clear");
> -
> -       return dabusb_bulk (s, b);
> -}
> -/* --------------------------------------------------------------------- */
> -static int dabusb_fpga_init (pdabusb_t s, pbulk_transfer_t b)
> -{
> -       b->size = 4;
> -       b->data[0] = 0x2c;
> -       b->data[1] = 0;
> -       b->data[2] = 0;
> -       b->data[3] = 0;
> -
> -       dbg("dabusb_fpga_init");
> -
> -       return dabusb_bulk (s, b);
> -}
> -/* --------------------------------------------------------------------- */
> -static int dabusb_fpga_download (pdabusb_t s, const char *fname)
> -{
> -       pbulk_transfer_t b = kmalloc (sizeof (bulk_transfer_t), GFP_KERNEL);
> -       const struct firmware *fw;
> -       unsigned int blen, n;
> -       int ret;
> -
> -       dbg("Enter dabusb_fpga_download (internal)");
> -
> -       if (!b) {
> -               dev_err(&s->usbdev->dev,
> -                       "kmalloc(sizeof(bulk_transfer_t))==NULL\n");
> -               return -ENOMEM;
> -       }
> -
> -       ret = request_firmware(&fw, "dabusb/bitstream.bin", &s->usbdev->dev);
> -       if (ret) {
> -               dev_err(&s->usbdev->dev,
> -                       "Failed to load \"dabusb/bitstream.bin\": %d\n", ret);
> -               kfree(b);
> -               return ret;
> -       }
> -
> -       b->pipe = 1;
> -       ret = dabusb_fpga_clear (s, b);
> -       mdelay (10);
> -       blen = fw->data[73] + (fw->data[72] << 8);
> -
> -       dbg("Bitstream len: %i", blen);
> -
> -       b->data[0] = 0x2b;
> -       b->data[1] = 0;
> -       b->data[2] = 0;
> -       b->data[3] = 60;
> -
> -       for (n = 0; n <= blen + 60; n += 60) {
> -               // some cclks for startup
> -               b->size = 64;
> -               memcpy (b->data + 4, fw->data + 74 + n, 60);
> -               ret = dabusb_bulk (s, b);
> -               if (ret < 0) {
> -                       dev_err(&s->usbdev->dev, "dabusb_bulk failed.\n");
> -                       break;
> -               }
> -               mdelay (1);
> -       }
> -
> -       ret = dabusb_fpga_init (s, b);
> -       kfree (b);
> -       release_firmware(fw);
> -
> -       dbg("exit dabusb_fpga_download");
> -
> -       return ret;
> -}
> -
> -static int dabusb_stop (pdabusb_t s)
> -{
> -       dbg("dabusb_stop");
> -
> -       s->state = _stopped;
> -       dabusb_cancel_queue (s, &s->rec_buff_list);
> -
> -       dbg("pending_io: %d", s->pending_io.counter);
> -
> -       s->pending_io.counter = 0;
> -       return 0;
> -}
> -
> -static int dabusb_startrek (pdabusb_t s)
> -{
> -       if (!s->got_mem && s->state != _started) {
> -
> -               dbg("dabusb_startrek");
> -
> -               if (dabusb_alloc_buffers (s) < 0)
> -                       return -ENOMEM;
> -               dabusb_stop (s);
> -               s->state = _started;
> -               s->readptr = 0;
> -       }
> -
> -       if (!list_empty (&s->free_buff_list)) {
> -               pbuff_t end;
> -               int ret;
> -
> -       while (!dabusb_add_buf_tail (s, &s->rec_buff_list, &s->free_buff_list)) {
> -
> -                       dbg("submitting: end:%p s->rec_buff_list:%p", s->rec_buff_list.prev, &s->rec_buff_list);
> -
> -                       end = list_entry (s->rec_buff_list.prev, buff_t, buff_list);
> -
> -                       ret = usb_submit_urb (end->purb, GFP_KERNEL);
> -                       if (ret) {
> -                               dev_err(&s->usbdev->dev,
> -                                       "usb_submit_urb returned:%d\n", ret);
> -                               if (dabusb_add_buf_tail (s, &s->free_buff_list, &s->rec_buff_list))
> -                                       dev_err(&s->usbdev->dev,
> -                                               "startrek: dabusb_add_buf_tail failed\n");
> -                               break;
> -                       }
> -                       else
> -                               atomic_inc (&s->pending_io);
> -               }
> -               dbg("pending_io: %d",s->pending_io.counter);
> -       }
> -
> -       return 0;
> -}
> -
> -static ssize_t dabusb_read (struct file *file, char __user *buf, size_t count, loff_t * ppos)
> -{
> -       pdabusb_t s = (pdabusb_t) file->private_data;
> -       unsigned long flags;
> -       unsigned ret = 0;
> -       int rem;
> -       int cnt;
> -       pbuff_t b;
> -       struct urb *purb = NULL;
> -
> -       dbg("dabusb_read");
> -
> -       if (*ppos)
> -               return -ESPIPE;
> -
> -       if (s->remove_pending)
> -               return -EIO;
> -
> -
> -       if (!s->usbdev)
> -               return -EIO;
> -
> -       while (count > 0) {
> -               dabusb_startrek (s);
> -
> -               spin_lock_irqsave (&s->lock, flags);
> -
> -               if (list_empty (&s->rec_buff_list)) {
> -
> -                       spin_unlock_irqrestore(&s->lock, flags);
> -
> -                       dev_err(&s->usbdev->dev,
> -                               "error: rec_buf_list is empty\n");
> -                       goto err;
> -               }
> -
> -               b = list_entry (s->rec_buff_list.next, buff_t, buff_list);
> -               purb = b->purb;
> -
> -               spin_unlock_irqrestore(&s->lock, flags);
> -
> -               if (purb->status == -EINPROGRESS) {
> -                       if (file->f_flags & O_NONBLOCK)         // return nonblocking
> -                        {
> -                               if (!ret)
> -                                       ret = -EAGAIN;
> -                               goto err;
> -                       }
> -
> -                       interruptible_sleep_on (&s->wait);
> -
> -                       if (signal_pending (current)) {
> -                               if (!ret)
> -                                       ret = -ERESTARTSYS;
> -                               goto err;
> -                       }
> -
> -                       spin_lock_irqsave (&s->lock, flags);
> -
> -                       if (list_empty (&s->rec_buff_list)) {
> -                               spin_unlock_irqrestore(&s->lock, flags);
> -                               dev_err(&s->usbdev->dev,
> -                                       "error: still no buffer available.\n");
> -                               goto err;
> -                       }
> -                       spin_unlock_irqrestore(&s->lock, flags);
> -                       s->readptr = 0;
> -               }
> -               if (s->remove_pending) {
> -                       ret = -EIO;
> -                       goto err;
> -               }
> -
> -               rem = purb->actual_length - s->readptr;         // set remaining bytes to copy
> -
> -               if (count >= rem)
> -                       cnt = rem;
> -               else
> -                       cnt = count;
> -
> -               dbg("copy_to_user:%p %p %d",buf, purb->transfer_buffer + s->readptr, cnt);
> -
> -               if (copy_to_user (buf, purb->transfer_buffer + s->readptr, cnt)) {
> -                       dev_err(&s->usbdev->dev, "read: copy_to_user failed\n");
> -                       if (!ret)
> -                               ret = -EFAULT;
> -                       goto err;
> -               }
> -
> -               s->readptr += cnt;
> -               count -= cnt;
> -               buf += cnt;
> -               ret += cnt;
> -
> -               if (s->readptr == purb->actual_length) {
> -                       // finished, take next buffer
> -                       if (dabusb_add_buf_tail (s, &s->free_buff_list, &s->rec_buff_list))
> -                               dev_err(&s->usbdev->dev,
> -                                       "read: dabusb_add_buf_tail failed\n");
> -                       s->readptr = 0;
> -               }
> -       }
> -      err:                     //mutex_unlock(&s->mutex);
> -       return ret;
> -}
> -
> -static int dabusb_open (struct inode *inode, struct file *file)
> -{
> -       int devnum = iminor(inode);
> -       pdabusb_t s;
> -       int r;
> -
> -       if (devnum < DABUSB_MINOR || devnum >= (DABUSB_MINOR + NRDABUSB))
> -               return -EIO;
> -
> -       s = &dabusb[devnum - DABUSB_MINOR];
> -
> -       dbg("dabusb_open");
> -       mutex_lock(&s->mutex);
> -
> -       while (!s->usbdev || s->opened) {
> -               mutex_unlock(&s->mutex);
> -
> -               if (file->f_flags & O_NONBLOCK)
> -                       return -EBUSY;
> -               msleep_interruptible(500);
> -
> -               if (signal_pending (current))
> -                       return -EAGAIN;
> -               mutex_lock(&s->mutex);
> -       }
> -       if (usb_set_interface (s->usbdev, _DABUSB_IF, 1) < 0) {
> -               mutex_unlock(&s->mutex);
> -               dev_err(&s->usbdev->dev, "set_interface failed\n");
> -               return -EINVAL;
> -       }
> -       s->opened = 1;
> -       mutex_unlock(&s->mutex);
> -
> -       file->f_pos = 0;
> -       file->private_data = s;
> -
> -       r = nonseekable_open(inode, file);
> -       return r;
> -}
> -
> -static int dabusb_release (struct inode *inode, struct file *file)
> -{
> -       pdabusb_t s = (pdabusb_t) file->private_data;
> -
> -       dbg("dabusb_release");
> -
> -       mutex_lock(&s->mutex);
> -       dabusb_stop (s);
> -       dabusb_free_buffers (s);
> -       mutex_unlock(&s->mutex);
> -
> -       if (!s->remove_pending) {
> -               if (usb_set_interface (s->usbdev, _DABUSB_IF, 0) < 0)
> -                       dev_err(&s->usbdev->dev, "set_interface failed\n");
> -       }
> -       else
> -               wake_up (&s->remove_ok);
> -
> -       s->opened = 0;
> -       return 0;
> -}
> -
> -static long dabusb_ioctl (struct file *file, unsigned int cmd, unsigned long arg)
> -{
> -       pdabusb_t s = (pdabusb_t) file->private_data;
> -       pbulk_transfer_t pbulk;
> -       int ret = 0;
> -       int version = DABUSB_VERSION;
> -
> -       dbg("dabusb_ioctl");
> -
> -       if (s->remove_pending)
> -               return -EIO;
> -
> -       mutex_lock(&s->mutex);
> -
> -       if (!s->usbdev) {
> -               mutex_unlock(&s->mutex);
> -               return -EIO;
> -       }
> -
> -       switch (cmd) {
> -
> -       case IOCTL_DAB_BULK:
> -               pbulk = memdup_user((void __user *)arg,
> -                                   sizeof(bulk_transfer_t));
> -
> -               if (IS_ERR(pbulk)) {
> -                       ret = PTR_ERR(pbulk);
> -                       break;
> -               }
> -
> -               ret=dabusb_bulk (s, pbulk);
> -               if(ret==0)
> -                       if (copy_to_user((void __user *)arg, pbulk,
> -                                        sizeof(bulk_transfer_t)))
> -                               ret = -EFAULT;
> -               kfree (pbulk);
> -               break;
> -
> -       case IOCTL_DAB_OVERRUNS:
> -               ret = put_user (s->overruns, (unsigned int __user *) arg);
> -               break;
> -
> -       case IOCTL_DAB_VERSION:
> -               ret = put_user (version, (unsigned int __user *) arg);
> -               break;
> -
> -       default:
> -               ret = -ENOIOCTLCMD;
> -               break;
> -       }
> -       mutex_unlock(&s->mutex);
> -       return ret;
> -}
> -
> -static const struct file_operations dabusb_fops =
> -{
> -       .owner =        THIS_MODULE,
> -       .llseek =       no_llseek,
> -       .read =         dabusb_read,
> -       .unlocked_ioctl =       dabusb_ioctl,
> -       .open =         dabusb_open,
> -       .release =      dabusb_release,
> -};
> -
> -static char *dabusb_devnode(struct device *dev, mode_t *mode)
> -{
> -       return kasprintf(GFP_KERNEL, "usb/%s", dev_name(dev));
> -}
> -
> -static struct usb_class_driver dabusb_class = {
> -       .name =         "dabusb%d",
> -       .devnode =      dabusb_devnode,
> -       .fops =         &dabusb_fops,
> -       .minor_base =   DABUSB_MINOR,
> -};
> -
> -
> -/* --------------------------------------------------------------------- */
> -static int dabusb_probe (struct usb_interface *intf,
> -                        const struct usb_device_id *id)
> -{
> -       struct usb_device *usbdev = interface_to_usbdev(intf);
> -       int retval;
> -       pdabusb_t s;
> -
> -       dbg("dabusb: probe: vendor id 0x%x, device id 0x%x ifnum:%d",
> -           le16_to_cpu(usbdev->descriptor.idVendor),
> -           le16_to_cpu(usbdev->descriptor.idProduct),
> -           intf->altsetting->desc.bInterfaceNumber);
> -
> -       /* We don't handle multiple configurations */
> -       if (usbdev->descriptor.bNumConfigurations != 1)
> -               return -ENODEV;
> -
> -       if (intf->altsetting->desc.bInterfaceNumber != _DABUSB_IF &&
> -           le16_to_cpu(usbdev->descriptor.idProduct) == 0x9999)
> -               return -ENODEV;
> -
> -
> -
> -       s = &dabusb[intf->minor];
> -
> -       mutex_lock(&s->mutex);
> -       s->remove_pending = 0;
> -       s->usbdev = usbdev;
> -       s->devnum = intf->minor;
> -
> -       if (usb_reset_configuration (usbdev) < 0) {
> -               dev_err(&intf->dev, "reset_configuration failed\n");
> -               goto reject;
> -       }
> -       if (le16_to_cpu(usbdev->descriptor.idProduct) == 0x2131) {
> -               dabusb_loadmem (s, NULL);
> -               goto reject;
> -       }
> -       else {
> -               dabusb_fpga_download (s, NULL);
> -
> -               if (usb_set_interface (s->usbdev, _DABUSB_IF, 0) < 0) {
> -                       dev_err(&intf->dev, "set_interface failed\n");
> -                       goto reject;
> -               }
> -       }
> -       dbg("bound to interface: %d", intf->altsetting->desc.bInterfaceNumber);
> -       usb_set_intfdata (intf, s);
> -       mutex_unlock(&s->mutex);
> -
> -       retval = usb_register_dev(intf, &dabusb_class);
> -       if (retval) {
> -               usb_set_intfdata (intf, NULL);
> -               return -ENOMEM;
> -       }
> -
> -       return 0;
> -
> -      reject:
> -       mutex_unlock(&s->mutex);
> -       s->usbdev = NULL;
> -       return -ENODEV;
> -}
> -
> -static void dabusb_disconnect (struct usb_interface *intf)
> -{
> -       wait_queue_t __wait;
> -       pdabusb_t s = usb_get_intfdata (intf);
> -
> -       dbg("dabusb_disconnect");
> -
> -       init_waitqueue_entry(&__wait, current);
> -
> -       usb_set_intfdata (intf, NULL);
> -       if (s) {
> -               usb_deregister_dev (intf, &dabusb_class);
> -               s->remove_pending = 1;
> -               wake_up (&s->wait);
> -               add_wait_queue(&s->remove_ok, &__wait);
> -               set_current_state(TASK_UNINTERRUPTIBLE);
> -               if (s->state == _started)
> -                       schedule();
> -               current->state = TASK_RUNNING;
> -               remove_wait_queue(&s->remove_ok, &__wait);
> -
> -               s->usbdev = NULL;
> -               s->overruns = 0;
> -       }
> -}
> -
> -static struct usb_device_id dabusb_ids [] = {
> -       // { USB_DEVICE(0x0547, 0x2131) },      /* An2131 chip, no boot ROM */
> -       { USB_DEVICE(0x0547, 0x9999) },
> -       { }                                             /* Terminating entry */
> -};
> -
> -MODULE_DEVICE_TABLE (usb, dabusb_ids);
> -
> -static struct usb_driver dabusb_driver = {
> -       .name =         "dabusb",
> -       .probe =        dabusb_probe,
> -       .disconnect =   dabusb_disconnect,
> -       .id_table =     dabusb_ids,
> -};
> -
> -/* --------------------------------------------------------------------- */
> -
> -static int __init dabusb_init (void)
> -{
> -       int retval;
> -       unsigned u;
> -
> -       /* initialize struct */
> -       for (u = 0; u < NRDABUSB; u++) {
> -               pdabusb_t s = &dabusb[u];
> -               memset (s, 0, sizeof (dabusb_t));
> -               mutex_init (&s->mutex);
> -               s->usbdev = NULL;
> -               s->total_buffer_size = buffers;
> -               init_waitqueue_head (&s->wait);
> -               init_waitqueue_head (&s->remove_ok);
> -               spin_lock_init (&s->lock);
> -               INIT_LIST_HEAD (&s->free_buff_list);
> -               INIT_LIST_HEAD (&s->rec_buff_list);
> -       }
> -
> -       /* register misc device */
> -       retval = usb_register(&dabusb_driver);
> -       if (retval)
> -               goto out;
> -
> -       dbg("dabusb_init: driver registered");
> -
> -       printk(KERN_INFO KBUILD_MODNAME ": " DRIVER_VERSION ":"
> -              DRIVER_DESC "\n");
> -
> -out:
> -       return retval;
> -}
> -
> -static void __exit dabusb_cleanup (void)
> -{
> -       dbg("dabusb_cleanup");
> -
> -       usb_deregister (&dabusb_driver);
> -}
> -
> -/* --------------------------------------------------------------------- */
> -
> -MODULE_AUTHOR( DRIVER_AUTHOR );
> -MODULE_DESCRIPTION( DRIVER_DESC );
> -MODULE_LICENSE("GPL");
> -MODULE_FIRMWARE("dabusb/firmware.fw");
> -MODULE_FIRMWARE("dabusb/bitstream.bin");
> -
> -module_param(buffers, int, 0);
> -MODULE_PARM_DESC (buffers, "Number of buffers (default=256)");
> -
> -module_init (dabusb_init);
> -module_exit (dabusb_cleanup);
> -
> -/* --------------------------------------------------------------------- */
> diff --git a/drivers/media/video/dabusb.h b/drivers/media/video/dabusb.h
> deleted file mode 100644
> index 00eb34c..0000000
> --- a/drivers/media/video/dabusb.h
> +++ /dev/null
> @@ -1,85 +0,0 @@
> -#define _BULK_DATA_LEN 64
> -typedef struct
> -{
> -       unsigned char data[_BULK_DATA_LEN];
> -       unsigned int size;
> -       unsigned int pipe;
> -}bulk_transfer_t,*pbulk_transfer_t;
> -
> -#define DABUSB_MINOR 240               /* some unassigned USB minor */
> -#define DABUSB_VERSION 0x1000
> -#define IOCTL_DAB_BULK              _IOWR('d', 0x30, bulk_transfer_t)
> -#define IOCTL_DAB_OVERRUNS         _IOR('d',  0x15, int)
> -#define IOCTL_DAB_VERSION           _IOR('d', 0x3f, int)
> -
> -#ifdef __KERNEL__
> -
> -typedef enum { _stopped=0, _started } driver_state_t;
> -
> -typedef struct
> -{
> -       struct mutex mutex;
> -       struct usb_device *usbdev;
> -       wait_queue_head_t wait;
> -       wait_queue_head_t remove_ok;
> -       spinlock_t lock;
> -       atomic_t pending_io;
> -       driver_state_t state;
> -       int remove_pending;
> -       int got_mem;
> -       int total_buffer_size;
> -       unsigned int overruns;
> -       int readptr;
> -       int opened;
> -       int devnum;
> -       struct list_head free_buff_list;
> -       struct list_head rec_buff_list;
> -} dabusb_t,*pdabusb_t;
> -
> -typedef struct
> -{
> -       pdabusb_t s;
> -       struct urb *purb;
> -       struct list_head buff_list;
> -} buff_t,*pbuff_t;
> -
> -typedef struct
> -{
> -       wait_queue_head_t wait;
> -} bulk_completion_context_t, *pbulk_completion_context_t;
> -
> -
> -#define _DABUSB_IF 2
> -#define _DABUSB_ISOPIPE 0x09
> -#define _ISOPIPESIZE   16384
> -
> -#define _BULK_DATA_LEN 64
> -// Vendor specific request code for Anchor Upload/Download
> -// This one is implemented in the core
> -#define ANCHOR_LOAD_INTERNAL  0xA0
> -
> -// EZ-USB Control and Status Register.  Bit 0 controls 8051 reset
> -#define CPUCS_REG    0x7F92
> -#define _TOTAL_BUFFERS 384
> -
> -#define MAX_INTEL_HEX_RECORD_LENGTH 16
> -
> -#ifndef _BYTE_DEFINED
> -#define _BYTE_DEFINED
> -typedef unsigned char BYTE;
> -#endif // !_BYTE_DEFINED
> -
> -#ifndef _WORD_DEFINED
> -#define _WORD_DEFINED
> -typedef unsigned short WORD;
> -#endif // !_WORD_DEFINED
> -
> -typedef struct _INTEL_HEX_RECORD
> -{
> -   BYTE  Length;
> -   WORD  Address;
> -   BYTE  Type;
> -   BYTE  Data[MAX_INTEL_HEX_RECORD_LENGTH];
> -} INTEL_HEX_RECORD, *PINTEL_HEX_RECORD;
> -
> -#endif
> diff --git a/drivers/staging/Kconfig b/drivers/staging/Kconfig
> index 7e7b27b..648142e 100644
> --- a/drivers/staging/Kconfig
> +++ b/drivers/staging/Kconfig
> @@ -51,6 +51,8 @@ source "drivers/staging/cx25821/Kconfig"
>
>  source "drivers/staging/tm6000/Kconfig"
>
> +source "drivers/staging/dabusb/Kconfig"
> +
>  source "drivers/staging/se401/Kconfig"
>
>  source "drivers/staging/usbvideo/Kconfig"
> diff --git a/drivers/staging/Makefile b/drivers/staging/Makefile
> index 72e0c83..8185c00 100644
> --- a/drivers/staging/Makefile
> +++ b/drivers/staging/Makefile
> @@ -8,6 +8,7 @@ obj-$(CONFIG_SLICOSS)           += slicoss/
>  obj-$(CONFIG_VIDEO_GO7007)     += go7007/
>  obj-$(CONFIG_VIDEO_CX25821)    += cx25821/
>  obj-$(CONFIG_VIDEO_TM6000)     += tm6000/
> +obj-$(CONFIG_USB_DABUSB)        += dabusb/
>  obj-$(CONFIG_USB_VICAM)         += usbvideo/
>  obj-$(CONFIG_USB_SE401)         += se401/
>  obj-$(CONFIG_LIRC_STAGING)     += lirc/
> diff --git a/drivers/staging/dabusb/Kconfig b/drivers/staging/dabusb/Kconfig
> new file mode 100644
> index 0000000..87bdc42
> --- /dev/null
> +++ b/drivers/staging/dabusb/Kconfig
> @@ -0,0 +1,14 @@
> +config USB_DABUSB
> +       tristate "DABUSB driver"
> +       depends on USB
> +       ---help---
> +         A Digital Audio Broadcasting (DAB) Receiver for USB and Linux
> +         brought to you by the DAB-Team
> +         <http://wwwbode.cs.tum.edu/Par/arch/dab/>.  This driver can be taken
> +         as an example for URB-based bulk, control, and isochronous
> +         transactions. URB's are explained in
> +         <Documentation/usb/URB.txt>.
> +
> +         To compile this driver as a module, choose M here: the
> +         module will be called dabusb.
> +
> diff --git a/drivers/staging/dabusb/Makefile b/drivers/staging/dabusb/Makefile
> new file mode 100644
> index 0000000..2ff2f22
> --- /dev/null
> +++ b/drivers/staging/dabusb/Makefile
> @@ -0,0 +1,2 @@
> +obj-$(CONFIG_USB_DABUSB)        += dabusb.o
> +
> diff --git a/drivers/staging/dabusb/TODO b/drivers/staging/dabusb/TODO
> new file mode 100644
> index 0000000..f9c0314
> --- /dev/null
> +++ b/drivers/staging/dabusb/TODO
> @@ -0,0 +1,5 @@
> +This is a driver for an experimental sample developed in 2003. The driver
> +never supported any commercial product, nor had any known user.
> +If nobody takes care on it, the driver will be removed for 2.6.39.
> +
> +Please send patches to linux-media@xxxxxxxxxxxxxxx
> diff --git a/drivers/staging/dabusb/dabusb.c b/drivers/staging/dabusb/dabusb.c
> new file mode 100644
> index 0000000..f3e25e9
> --- /dev/null
> +++ b/drivers/staging/dabusb/dabusb.c
> @@ -0,0 +1,914 @@
> +/*****************************************************************************/
> +
> +/*
> + *      dabusb.c  --  dab usb driver.
> + *
> + *      Copyright (C) 1999  Deti Fliegl (deti@xxxxxxxxx)
> + *
> + *      This program is free software; you can redistribute it and/or modify
> + *      it under the terms of the GNU General Public License as published by
> + *      the Free Software Foundation; either version 2 of the License, or
> + *      (at your option) any later version.
> + *
> + *      This program is distributed in the hope that it will be useful,
> + *      but WITHOUT ANY WARRANTY; without even the implied warranty of
> + *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> + *      GNU General Public License for more details.
> + *
> + *      You should have received a copy of the GNU General Public License
> + *      along with this program; if not, write to the Free Software
> + *      Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
> + *
> + *
> + *
> + *  $Id: dabusb.c,v 1.54 2000/07/24 21:39:39 deti Exp $
> + *
> + */
> +
> +/*****************************************************************************/
> +
> +#include <linux/module.h>
> +#include <linux/socket.h>
> +#include <linux/list.h>
> +#include <linux/vmalloc.h>
> +#include <linux/slab.h>
> +#include <linux/init.h>
> +#include <asm/uaccess.h>
> +#include <asm/atomic.h>
> +#include <linux/delay.h>
> +#include <linux/usb.h>
> +#include <linux/mutex.h>
> +#include <linux/firmware.h>
> +#include <linux/ihex.h>
> +
> +#include "dabusb.h"
> +
> +/*
> + * Version Information
> + */
> +#define DRIVER_VERSION "v1.54"
> +#define DRIVER_AUTHOR "Deti Fliegl, deti@xxxxxxxxx"
> +#define DRIVER_DESC "DAB-USB Interface Driver for Linux (c)1999"
> +
> +/* --------------------------------------------------------------------- */
> +
> +#ifdef CONFIG_USB_DYNAMIC_MINORS
> +#define NRDABUSB 256
> +#else
> +#define NRDABUSB 4
> +#endif
> +
> +/*-------------------------------------------------------------------*/
> +
> +static dabusb_t dabusb[NRDABUSB];
> +static int buffers = 256;
> +static struct usb_driver dabusb_driver;
> +
> +/*-------------------------------------------------------------------*/
> +
> +static int dabusb_add_buf_tail (pdabusb_t s, struct list_head *dst, struct list_head *src)
> +{
> +       unsigned long flags;
> +       struct list_head *tmp;
> +       int ret = 0;
> +
> +       spin_lock_irqsave (&s->lock, flags);
> +
> +       if (list_empty (src)) {
> +               // no elements in source buffer
> +               ret = -1;
> +               goto err;
> +       }
> +       tmp = src->next;
> +       list_move_tail (tmp, dst);
> +
> +  err: spin_unlock_irqrestore (&s->lock, flags);
> +       return ret;
> +}
> +/*-------------------------------------------------------------------*/
> +#ifdef DEBUG
> +static void dump_urb (struct urb *urb)
> +{
> +       dbg("urb                   :%p", urb);
> +       dbg("dev                   :%p", urb->dev);
> +       dbg("pipe                  :%08X", urb->pipe);
> +       dbg("status                :%d", urb->status);
> +       dbg("transfer_flags        :%08X", urb->transfer_flags);
> +       dbg("transfer_buffer       :%p", urb->transfer_buffer);
> +       dbg("transfer_buffer_length:%d", urb->transfer_buffer_length);
> +       dbg("actual_length         :%d", urb->actual_length);
> +       dbg("setup_packet          :%p", urb->setup_packet);
> +       dbg("start_frame           :%d", urb->start_frame);
> +       dbg("number_of_packets     :%d", urb->number_of_packets);
> +       dbg("interval              :%d", urb->interval);
> +       dbg("error_count           :%d", urb->error_count);
> +       dbg("context               :%p", urb->context);
> +       dbg("complete              :%p", urb->complete);
> +}
> +#endif
> +/*-------------------------------------------------------------------*/
> +static int dabusb_cancel_queue (pdabusb_t s, struct list_head *q)
> +{
> +       unsigned long flags;
> +       pbuff_t b;
> +
> +       dbg("dabusb_cancel_queue");
> +
> +       spin_lock_irqsave (&s->lock, flags);
> +
> +       list_for_each_entry(b, q, buff_list) {
> +#ifdef DEBUG
> +               dump_urb(b->purb);
> +#endif
> +               usb_unlink_urb (b->purb);
> +       }
> +       spin_unlock_irqrestore (&s->lock, flags);
> +       return 0;
> +}
> +/*-------------------------------------------------------------------*/
> +static int dabusb_free_queue (struct list_head *q)
> +{
> +       struct list_head *tmp;
> +       struct list_head *p;
> +       pbuff_t b;
> +
> +       dbg("dabusb_free_queue");
> +       for (p = q->next; p != q;) {
> +               b = list_entry (p, buff_t, buff_list);
> +
> +#ifdef DEBUG
> +               dump_urb(b->purb);
> +#endif
> +               kfree(b->purb->transfer_buffer);
> +               usb_free_urb(b->purb);
> +               tmp = p->next;
> +               list_del (p);
> +               kfree (b);
> +               p = tmp;
> +       }
> +
> +       return 0;
> +}
> +/*-------------------------------------------------------------------*/
> +static int dabusb_free_buffers (pdabusb_t s)
> +{
> +       unsigned long flags;
> +       dbg("dabusb_free_buffers");
> +
> +       spin_lock_irqsave(&s->lock, flags);
> +
> +       dabusb_free_queue (&s->free_buff_list);
> +       dabusb_free_queue (&s->rec_buff_list);
> +
> +       spin_unlock_irqrestore(&s->lock, flags);
> +
> +       s->got_mem = 0;
> +       return 0;
> +}
> +/*-------------------------------------------------------------------*/
> +static void dabusb_iso_complete (struct urb *purb)
> +{
> +       pbuff_t b = purb->context;
> +       pdabusb_t s = b->s;
> +       int i;
> +       int len;
> +       int dst = 0;
> +       void *buf = purb->transfer_buffer;
> +
> +       dbg("dabusb_iso_complete");
> +
> +       // process if URB was not killed
> +       if (purb->status != -ENOENT) {
> +               unsigned int pipe = usb_rcvisocpipe (purb->dev, _DABUSB_ISOPIPE);
> +               int pipesize = usb_maxpacket (purb->dev, pipe, usb_pipeout (pipe));
> +               for (i = 0; i < purb->number_of_packets; i++)
> +                       if (!purb->iso_frame_desc[i].status) {
> +                               len = purb->iso_frame_desc[i].actual_length;
> +                               if (len <= pipesize) {
> +                                       memcpy (buf + dst, buf + purb->iso_frame_desc[i].offset, len);
> +                                       dst += len;
> +                               }
> +                               else
> +                                       dev_err(&purb->dev->dev,
> +                                               "dabusb_iso_complete: invalid len %d\n", len);
> +                       }
> +                       else
> +                               dev_warn(&purb->dev->dev, "dabusb_iso_complete: corrupted packet status: %d\n", purb->iso_frame_desc[i].status);
> +               if (dst != purb->actual_length)
> +                       dev_err(&purb->dev->dev,
> +                               "dst!=purb->actual_length:%d!=%d\n",
> +                                       dst, purb->actual_length);
> +       }
> +
> +       if (atomic_dec_and_test (&s->pending_io) && !s->remove_pending && s->state != _stopped) {
> +               s->overruns++;
> +               dev_err(&purb->dev->dev, "overrun (%d)\n", s->overruns);
> +       }
> +       wake_up (&s->wait);
> +}
> +/*-------------------------------------------------------------------*/
> +static int dabusb_alloc_buffers (pdabusb_t s)
> +{
> +       int transfer_len = 0;
> +       pbuff_t b;
> +       unsigned int pipe = usb_rcvisocpipe (s->usbdev, _DABUSB_ISOPIPE);
> +       int pipesize = usb_maxpacket (s->usbdev, pipe, usb_pipeout (pipe));
> +       int packets = _ISOPIPESIZE / pipesize;
> +       int transfer_buffer_length = packets * pipesize;
> +       int i;
> +
> +       dbg("dabusb_alloc_buffers pipesize:%d packets:%d transfer_buffer_len:%d",
> +                pipesize, packets, transfer_buffer_length);
> +
> +       while (transfer_len < (s->total_buffer_size << 10)) {
> +               b = kzalloc(sizeof (buff_t), GFP_KERNEL);
> +               if (!b) {
> +                       dev_err(&s->usbdev->dev,
> +                               "kzalloc(sizeof(buff_t))==NULL\n");
> +                       goto err;
> +               }
> +               b->s = s;
> +               b->purb = usb_alloc_urb(packets, GFP_KERNEL);
> +               if (!b->purb) {
> +                       dev_err(&s->usbdev->dev, "usb_alloc_urb == NULL\n");
> +                       kfree (b);
> +                       goto err;
> +               }
> +
> +               b->purb->transfer_buffer = kmalloc (transfer_buffer_length, GFP_KERNEL);
> +               if (!b->purb->transfer_buffer) {
> +                       kfree (b->purb);
> +                       kfree (b);
> +                       dev_err(&s->usbdev->dev,
> +                               "kmalloc(%d)==NULL\n", transfer_buffer_length);
> +                       goto err;
> +               }
> +
> +               b->purb->transfer_buffer_length = transfer_buffer_length;
> +               b->purb->number_of_packets = packets;
> +               b->purb->complete = dabusb_iso_complete;
> +               b->purb->context = b;
> +               b->purb->dev = s->usbdev;
> +               b->purb->pipe = pipe;
> +               b->purb->transfer_flags = URB_ISO_ASAP;
> +
> +               for (i = 0; i < packets; i++) {
> +                       b->purb->iso_frame_desc[i].offset = i * pipesize;
> +                       b->purb->iso_frame_desc[i].length = pipesize;
> +               }
> +
> +               transfer_len += transfer_buffer_length;
> +               list_add_tail (&b->buff_list, &s->free_buff_list);
> +       }
> +       s->got_mem = transfer_len;
> +
> +       return 0;
> +
> +       err:
> +       dabusb_free_buffers (s);
> +       return -ENOMEM;
> +}
> +/*-------------------------------------------------------------------*/
> +static int dabusb_bulk (pdabusb_t s, pbulk_transfer_t pb)
> +{
> +       int ret;
> +       unsigned int pipe;
> +       int actual_length;
> +
> +       dbg("dabusb_bulk");
> +
> +       if (!pb->pipe)
> +               pipe = usb_rcvbulkpipe (s->usbdev, 2);
> +       else
> +               pipe = usb_sndbulkpipe (s->usbdev, 2);
> +
> +       ret=usb_bulk_msg(s->usbdev, pipe, pb->data, pb->size, &actual_length, 100);
> +       if(ret<0) {
> +               dev_err(&s->usbdev->dev,
> +                       "usb_bulk_msg failed(%d)\n", ret);
> +
> +               if (usb_set_interface (s->usbdev, _DABUSB_IF, 1) < 0) {
> +                       dev_err(&s->usbdev->dev, "set_interface failed\n");
> +                       return -EINVAL;
> +               }
> +
> +       }
> +
> +       if( ret == -EPIPE ) {
> +               dev_warn(&s->usbdev->dev, "CLEAR_FEATURE request to remove STALL condition.\n");
> +               if(usb_clear_halt(s->usbdev, usb_pipeendpoint(pipe)))
> +                       dev_err(&s->usbdev->dev, "request failed\n");
> +       }
> +
> +       pb->size = actual_length;
> +       return ret;
> +}
> +/* --------------------------------------------------------------------- */
> +static int dabusb_writemem (pdabusb_t s, int pos, const unsigned char *data,
> +                           int len)
> +{
> +       int ret;
> +       unsigned char *transfer_buffer =  kmalloc (len, GFP_KERNEL);
> +
> +       if (!transfer_buffer) {
> +               dev_err(&s->usbdev->dev,
> +                       "dabusb_writemem: kmalloc(%d) failed.\n", len);
> +               return -ENOMEM;
> +       }
> +
> +       memcpy (transfer_buffer, data, len);
> +
> +       ret=usb_control_msg(s->usbdev, usb_sndctrlpipe( s->usbdev, 0 ), 0xa0, 0x40, pos, 0, transfer_buffer, len, 300);
> +
> +       kfree (transfer_buffer);
> +       return ret;
> +}
> +/* --------------------------------------------------------------------- */
> +static int dabusb_8051_reset (pdabusb_t s, unsigned char reset_bit)
> +{
> +       dbg("dabusb_8051_reset: %d",reset_bit);
> +       return dabusb_writemem (s, CPUCS_REG, &reset_bit, 1);
> +}
> +/* --------------------------------------------------------------------- */
> +static int dabusb_loadmem (pdabusb_t s, const char *fname)
> +{
> +       int ret;
> +       const struct ihex_binrec *rec;
> +       const struct firmware *uninitialized_var(fw);
> +
> +       dbg("Enter dabusb_loadmem (internal)");
> +
> +       ret = request_ihex_firmware(&fw, "dabusb/firmware.fw", &s->usbdev->dev);
> +       if (ret) {
> +               dev_err(&s->usbdev->dev,
> +                       "Failed to load \"dabusb/firmware.fw\": %d\n", ret);
> +               goto out;
> +       }
> +       ret = dabusb_8051_reset (s, 1);
> +
> +       for (rec = (const struct ihex_binrec *)fw->data; rec;
> +            rec = ihex_next_binrec(rec)) {
> +               dbg("dabusb_writemem: %04X %p %d)", be32_to_cpu(rec->addr),
> +                   rec->data, be16_to_cpu(rec->len));
> +
> +               ret = dabusb_writemem(s, be32_to_cpu(rec->addr), rec->data,
> +                                      be16_to_cpu(rec->len));
> +               if (ret < 0) {
> +                       dev_err(&s->usbdev->dev,
> +                               "dabusb_writemem failed (%d %04X %p %d)\n",
> +                               ret, be32_to_cpu(rec->addr),
> +                               rec->data, be16_to_cpu(rec->len));
> +                       break;
> +               }
> +       }
> +       ret = dabusb_8051_reset (s, 0);
> +       release_firmware(fw);
> + out:
> +       dbg("dabusb_loadmem: exit");
> +
> +       return ret;
> +}
> +/* --------------------------------------------------------------------- */
> +static int dabusb_fpga_clear (pdabusb_t s, pbulk_transfer_t b)
> +{
> +       b->size = 4;
> +       b->data[0] = 0x2a;
> +       b->data[1] = 0;
> +       b->data[2] = 0;
> +       b->data[3] = 0;
> +
> +       dbg("dabusb_fpga_clear");
> +
> +       return dabusb_bulk (s, b);
> +}
> +/* --------------------------------------------------------------------- */
> +static int dabusb_fpga_init (pdabusb_t s, pbulk_transfer_t b)
> +{
> +       b->size = 4;
> +       b->data[0] = 0x2c;
> +       b->data[1] = 0;
> +       b->data[2] = 0;
> +       b->data[3] = 0;
> +
> +       dbg("dabusb_fpga_init");
> +
> +       return dabusb_bulk (s, b);
> +}
> +/* --------------------------------------------------------------------- */
> +static int dabusb_fpga_download (pdabusb_t s, const char *fname)
> +{
> +       pbulk_transfer_t b = kmalloc (sizeof (bulk_transfer_t), GFP_KERNEL);
> +       const struct firmware *fw;
> +       unsigned int blen, n;
> +       int ret;
> +
> +       dbg("Enter dabusb_fpga_download (internal)");
> +
> +       if (!b) {
> +               dev_err(&s->usbdev->dev,
> +                       "kmalloc(sizeof(bulk_transfer_t))==NULL\n");
> +               return -ENOMEM;
> +       }
> +
> +       ret = request_firmware(&fw, "dabusb/bitstream.bin", &s->usbdev->dev);
> +       if (ret) {
> +               dev_err(&s->usbdev->dev,
> +                       "Failed to load \"dabusb/bitstream.bin\": %d\n", ret);
> +               kfree(b);
> +               return ret;
> +       }
> +
> +       b->pipe = 1;
> +       ret = dabusb_fpga_clear (s, b);
> +       mdelay (10);
> +       blen = fw->data[73] + (fw->data[72] << 8);
> +
> +       dbg("Bitstream len: %i", blen);
> +
> +       b->data[0] = 0x2b;
> +       b->data[1] = 0;
> +       b->data[2] = 0;
> +       b->data[3] = 60;
> +
> +       for (n = 0; n <= blen + 60; n += 60) {
> +               // some cclks for startup
> +               b->size = 64;
> +               memcpy (b->data + 4, fw->data + 74 + n, 60);
> +               ret = dabusb_bulk (s, b);
> +               if (ret < 0) {
> +                       dev_err(&s->usbdev->dev, "dabusb_bulk failed.\n");
> +                       break;
> +               }
> +               mdelay (1);
> +       }
> +
> +       ret = dabusb_fpga_init (s, b);
> +       kfree (b);
> +       release_firmware(fw);
> +
> +       dbg("exit dabusb_fpga_download");
> +
> +       return ret;
> +}
> +
> +static int dabusb_stop (pdabusb_t s)
> +{
> +       dbg("dabusb_stop");
> +
> +       s->state = _stopped;
> +       dabusb_cancel_queue (s, &s->rec_buff_list);
> +
> +       dbg("pending_io: %d", s->pending_io.counter);
> +
> +       s->pending_io.counter = 0;
> +       return 0;
> +}
> +
> +static int dabusb_startrek (pdabusb_t s)
> +{
> +       if (!s->got_mem && s->state != _started) {
> +
> +               dbg("dabusb_startrek");
> +
> +               if (dabusb_alloc_buffers (s) < 0)
> +                       return -ENOMEM;
> +               dabusb_stop (s);
> +               s->state = _started;
> +               s->readptr = 0;
> +       }
> +
> +       if (!list_empty (&s->free_buff_list)) {
> +               pbuff_t end;
> +               int ret;
> +
> +       while (!dabusb_add_buf_tail (s, &s->rec_buff_list, &s->free_buff_list)) {
> +
> +                       dbg("submitting: end:%p s->rec_buff_list:%p", s->rec_buff_list.prev, &s->rec_buff_list);
> +
> +                       end = list_entry (s->rec_buff_list.prev, buff_t, buff_list);
> +
> +                       ret = usb_submit_urb (end->purb, GFP_KERNEL);
> +                       if (ret) {
> +                               dev_err(&s->usbdev->dev,
> +                                       "usb_submit_urb returned:%d\n", ret);
> +                               if (dabusb_add_buf_tail (s, &s->free_buff_list, &s->rec_buff_list))
> +                                       dev_err(&s->usbdev->dev,
> +                                               "startrek: dabusb_add_buf_tail failed\n");
> +                               break;
> +                       }
> +                       else
> +                               atomic_inc (&s->pending_io);
> +               }
> +               dbg("pending_io: %d",s->pending_io.counter);
> +       }
> +
> +       return 0;
> +}
> +
> +static ssize_t dabusb_read (struct file *file, char __user *buf, size_t count, loff_t * ppos)
> +{
> +       pdabusb_t s = (pdabusb_t) file->private_data;
> +       unsigned long flags;
> +       unsigned ret = 0;
> +       int rem;
> +       int cnt;
> +       pbuff_t b;
> +       struct urb *purb = NULL;
> +
> +       dbg("dabusb_read");
> +
> +       if (*ppos)
> +               return -ESPIPE;
> +
> +       if (s->remove_pending)
> +               return -EIO;
> +
> +
> +       if (!s->usbdev)
> +               return -EIO;
> +
> +       while (count > 0) {
> +               dabusb_startrek (s);
> +
> +               spin_lock_irqsave (&s->lock, flags);
> +
> +               if (list_empty (&s->rec_buff_list)) {
> +
> +                       spin_unlock_irqrestore(&s->lock, flags);
> +
> +                       dev_err(&s->usbdev->dev,
> +                               "error: rec_buf_list is empty\n");
> +                       goto err;
> +               }
> +
> +               b = list_entry (s->rec_buff_list.next, buff_t, buff_list);
> +               purb = b->purb;
> +
> +               spin_unlock_irqrestore(&s->lock, flags);
> +
> +               if (purb->status == -EINPROGRESS) {
> +                       if (file->f_flags & O_NONBLOCK)         // return nonblocking
> +                        {
> +                               if (!ret)
> +                                       ret = -EAGAIN;
> +                               goto err;
> +                       }
> +
> +                       interruptible_sleep_on (&s->wait);
> +
> +                       if (signal_pending (current)) {
> +                               if (!ret)
> +                                       ret = -ERESTARTSYS;
> +                               goto err;
> +                       }
> +
> +                       spin_lock_irqsave (&s->lock, flags);
> +
> +                       if (list_empty (&s->rec_buff_list)) {
> +                               spin_unlock_irqrestore(&s->lock, flags);
> +                               dev_err(&s->usbdev->dev,
> +                                       "error: still no buffer available.\n");
> +                               goto err;
> +                       }
> +                       spin_unlock_irqrestore(&s->lock, flags);
> +                       s->readptr = 0;
> +               }
> +               if (s->remove_pending) {
> +                       ret = -EIO;
> +                       goto err;
> +               }
> +
> +               rem = purb->actual_length - s->readptr;         // set remaining bytes to copy
> +
> +               if (count >= rem)
> +                       cnt = rem;
> +               else
> +                       cnt = count;
> +
> +               dbg("copy_to_user:%p %p %d",buf, purb->transfer_buffer + s->readptr, cnt);
> +
> +               if (copy_to_user (buf, purb->transfer_buffer + s->readptr, cnt)) {
> +                       dev_err(&s->usbdev->dev, "read: copy_to_user failed\n");
> +                       if (!ret)
> +                               ret = -EFAULT;
> +                       goto err;
> +               }
> +
> +               s->readptr += cnt;
> +               count -= cnt;
> +               buf += cnt;
> +               ret += cnt;
> +
> +               if (s->readptr == purb->actual_length) {
> +                       // finished, take next buffer
> +                       if (dabusb_add_buf_tail (s, &s->free_buff_list, &s->rec_buff_list))
> +                               dev_err(&s->usbdev->dev,
> +                                       "read: dabusb_add_buf_tail failed\n");
> +                       s->readptr = 0;
> +               }
> +       }
> +      err:                     //mutex_unlock(&s->mutex);
> +       return ret;
> +}
> +
> +static int dabusb_open (struct inode *inode, struct file *file)
> +{
> +       int devnum = iminor(inode);
> +       pdabusb_t s;
> +       int r;
> +
> +       if (devnum < DABUSB_MINOR || devnum >= (DABUSB_MINOR + NRDABUSB))
> +               return -EIO;
> +
> +       s = &dabusb[devnum - DABUSB_MINOR];
> +
> +       dbg("dabusb_open");
> +       mutex_lock(&s->mutex);
> +
> +       while (!s->usbdev || s->opened) {
> +               mutex_unlock(&s->mutex);
> +
> +               if (file->f_flags & O_NONBLOCK)
> +                       return -EBUSY;
> +               msleep_interruptible(500);
> +
> +               if (signal_pending (current))
> +                       return -EAGAIN;
> +               mutex_lock(&s->mutex);
> +       }
> +       if (usb_set_interface (s->usbdev, _DABUSB_IF, 1) < 0) {
> +               mutex_unlock(&s->mutex);
> +               dev_err(&s->usbdev->dev, "set_interface failed\n");
> +               return -EINVAL;
> +       }
> +       s->opened = 1;
> +       mutex_unlock(&s->mutex);
> +
> +       file->f_pos = 0;
> +       file->private_data = s;
> +
> +       r = nonseekable_open(inode, file);
> +       return r;
> +}
> +
> +static int dabusb_release (struct inode *inode, struct file *file)
> +{
> +       pdabusb_t s = (pdabusb_t) file->private_data;
> +
> +       dbg("dabusb_release");
> +
> +       mutex_lock(&s->mutex);
> +       dabusb_stop (s);
> +       dabusb_free_buffers (s);
> +       mutex_unlock(&s->mutex);
> +
> +       if (!s->remove_pending) {
> +               if (usb_set_interface (s->usbdev, _DABUSB_IF, 0) < 0)
> +                       dev_err(&s->usbdev->dev, "set_interface failed\n");
> +       }
> +       else
> +               wake_up (&s->remove_ok);
> +
> +       s->opened = 0;
> +       return 0;
> +}
> +
> +static long dabusb_ioctl (struct file *file, unsigned int cmd, unsigned long arg)
> +{
> +       pdabusb_t s = (pdabusb_t) file->private_data;
> +       pbulk_transfer_t pbulk;
> +       int ret = 0;
> +       int version = DABUSB_VERSION;
> +
> +       dbg("dabusb_ioctl");
> +
> +       if (s->remove_pending)
> +               return -EIO;
> +
> +       mutex_lock(&s->mutex);
> +
> +       if (!s->usbdev) {
> +               mutex_unlock(&s->mutex);
> +               return -EIO;
> +       }
> +
> +       switch (cmd) {
> +
> +       case IOCTL_DAB_BULK:
> +               pbulk = memdup_user((void __user *)arg,
> +                                   sizeof(bulk_transfer_t));
> +
> +               if (IS_ERR(pbulk)) {
> +                       ret = PTR_ERR(pbulk);
> +                       break;
> +               }
> +
> +               ret=dabusb_bulk (s, pbulk);
> +               if(ret==0)
> +                       if (copy_to_user((void __user *)arg, pbulk,
> +                                        sizeof(bulk_transfer_t)))
> +                               ret = -EFAULT;
> +               kfree (pbulk);
> +               break;
> +
> +       case IOCTL_DAB_OVERRUNS:
> +               ret = put_user (s->overruns, (unsigned int __user *) arg);
> +               break;
> +
> +       case IOCTL_DAB_VERSION:
> +               ret = put_user (version, (unsigned int __user *) arg);
> +               break;
> +
> +       default:
> +               ret = -ENOIOCTLCMD;
> +               break;
> +       }
> +       mutex_unlock(&s->mutex);
> +       return ret;
> +}
> +
> +static const struct file_operations dabusb_fops =
> +{
> +       .owner =        THIS_MODULE,
> +       .llseek =       no_llseek,
> +       .read =         dabusb_read,
> +       .unlocked_ioctl =       dabusb_ioctl,
> +       .open =         dabusb_open,
> +       .release =      dabusb_release,
> +};
> +
> +static char *dabusb_devnode(struct device *dev, mode_t *mode)
> +{
> +       return kasprintf(GFP_KERNEL, "usb/%s", dev_name(dev));
> +}
> +
> +static struct usb_class_driver dabusb_class = {
> +       .name =         "dabusb%d",
> +       .devnode =      dabusb_devnode,
> +       .fops =         &dabusb_fops,
> +       .minor_base =   DABUSB_MINOR,
> +};
> +
> +
> +/* --------------------------------------------------------------------- */
> +static int dabusb_probe (struct usb_interface *intf,
> +                        const struct usb_device_id *id)
> +{
> +       struct usb_device *usbdev = interface_to_usbdev(intf);
> +       int retval;
> +       pdabusb_t s;
> +
> +       dbg("dabusb: probe: vendor id 0x%x, device id 0x%x ifnum:%d",
> +           le16_to_cpu(usbdev->descriptor.idVendor),
> +           le16_to_cpu(usbdev->descriptor.idProduct),
> +           intf->altsetting->desc.bInterfaceNumber);
> +
> +       /* We don't handle multiple configurations */
> +       if (usbdev->descriptor.bNumConfigurations != 1)
> +               return -ENODEV;
> +
> +       if (intf->altsetting->desc.bInterfaceNumber != _DABUSB_IF &&
> +           le16_to_cpu(usbdev->descriptor.idProduct) == 0x9999)
> +               return -ENODEV;
> +
> +
> +
> +       s = &dabusb[intf->minor];
> +
> +       mutex_lock(&s->mutex);
> +       s->remove_pending = 0;
> +       s->usbdev = usbdev;
> +       s->devnum = intf->minor;
> +
> +       if (usb_reset_configuration (usbdev) < 0) {
> +               dev_err(&intf->dev, "reset_configuration failed\n");
> +               goto reject;
> +       }
> +       if (le16_to_cpu(usbdev->descriptor.idProduct) == 0x2131) {
> +               dabusb_loadmem (s, NULL);
> +               goto reject;
> +       }
> +       else {
> +               dabusb_fpga_download (s, NULL);
> +
> +               if (usb_set_interface (s->usbdev, _DABUSB_IF, 0) < 0) {
> +                       dev_err(&intf->dev, "set_interface failed\n");
> +                       goto reject;
> +               }
> +       }
> +       dbg("bound to interface: %d", intf->altsetting->desc.bInterfaceNumber);
> +       usb_set_intfdata (intf, s);
> +       mutex_unlock(&s->mutex);
> +
> +       retval = usb_register_dev(intf, &dabusb_class);
> +       if (retval) {
> +               usb_set_intfdata (intf, NULL);
> +               return -ENOMEM;
> +       }
> +
> +       return 0;
> +
> +      reject:
> +       mutex_unlock(&s->mutex);
> +       s->usbdev = NULL;
> +       return -ENODEV;
> +}
> +
> +static void dabusb_disconnect (struct usb_interface *intf)
> +{
> +       wait_queue_t __wait;
> +       pdabusb_t s = usb_get_intfdata (intf);
> +
> +       dbg("dabusb_disconnect");
> +
> +       init_waitqueue_entry(&__wait, current);
> +
> +       usb_set_intfdata (intf, NULL);
> +       if (s) {
> +               usb_deregister_dev (intf, &dabusb_class);
> +               s->remove_pending = 1;
> +               wake_up (&s->wait);
> +               add_wait_queue(&s->remove_ok, &__wait);
> +               set_current_state(TASK_UNINTERRUPTIBLE);
> +               if (s->state == _started)
> +                       schedule();
> +               current->state = TASK_RUNNING;
> +               remove_wait_queue(&s->remove_ok, &__wait);
> +
> +               s->usbdev = NULL;
> +               s->overruns = 0;
> +       }
> +}
> +
> +static struct usb_device_id dabusb_ids [] = {
> +       // { USB_DEVICE(0x0547, 0x2131) },      /* An2131 chip, no boot ROM */
> +       { USB_DEVICE(0x0547, 0x9999) },
> +       { }                                             /* Terminating entry */
> +};
> +
> +MODULE_DEVICE_TABLE (usb, dabusb_ids);
> +
> +static struct usb_driver dabusb_driver = {
> +       .name =         "dabusb",
> +       .probe =        dabusb_probe,
> +       .disconnect =   dabusb_disconnect,
> +       .id_table =     dabusb_ids,
> +};
> +
> +/* --------------------------------------------------------------------- */
> +
> +static int __init dabusb_init (void)
> +{
> +       int retval;
> +       unsigned u;
> +
> +       /* initialize struct */
> +       for (u = 0; u < NRDABUSB; u++) {
> +               pdabusb_t s = &dabusb[u];
> +               memset (s, 0, sizeof (dabusb_t));
> +               mutex_init (&s->mutex);
> +               s->usbdev = NULL;
> +               s->total_buffer_size = buffers;
> +               init_waitqueue_head (&s->wait);
> +               init_waitqueue_head (&s->remove_ok);
> +               spin_lock_init (&s->lock);
> +               INIT_LIST_HEAD (&s->free_buff_list);
> +               INIT_LIST_HEAD (&s->rec_buff_list);
> +       }
> +
> +       /* register misc device */
> +       retval = usb_register(&dabusb_driver);
> +       if (retval)
> +               goto out;
> +
> +       dbg("dabusb_init: driver registered");
> +
> +       printk(KERN_INFO KBUILD_MODNAME ": " DRIVER_VERSION ":"
> +              DRIVER_DESC "\n");
> +
> +out:
> +       return retval;
> +}
> +
> +static void __exit dabusb_cleanup (void)
> +{
> +       dbg("dabusb_cleanup");
> +
> +       usb_deregister (&dabusb_driver);
> +}
> +
> +/* --------------------------------------------------------------------- */
> +
> +MODULE_AUTHOR( DRIVER_AUTHOR );
> +MODULE_DESCRIPTION( DRIVER_DESC );
> +MODULE_LICENSE("GPL");
> +MODULE_FIRMWARE("dabusb/firmware.fw");
> +MODULE_FIRMWARE("dabusb/bitstream.bin");
> +
> +module_param(buffers, int, 0);
> +MODULE_PARM_DESC (buffers, "Number of buffers (default=256)");
> +
> +module_init (dabusb_init);
> +module_exit (dabusb_cleanup);
> +
> +/* --------------------------------------------------------------------- */
> diff --git a/drivers/staging/dabusb/dabusb.h b/drivers/staging/dabusb/dabusb.h
> new file mode 100644
> index 0000000..00eb34c
> --- /dev/null
> +++ b/drivers/staging/dabusb/dabusb.h
> @@ -0,0 +1,85 @@
> +#define _BULK_DATA_LEN 64
> +typedef struct
> +{
> +       unsigned char data[_BULK_DATA_LEN];
> +       unsigned int size;
> +       unsigned int pipe;
> +}bulk_transfer_t,*pbulk_transfer_t;
> +
> +#define DABUSB_MINOR 240               /* some unassigned USB minor */
> +#define DABUSB_VERSION 0x1000
> +#define IOCTL_DAB_BULK              _IOWR('d', 0x30, bulk_transfer_t)
> +#define IOCTL_DAB_OVERRUNS         _IOR('d',  0x15, int)
> +#define IOCTL_DAB_VERSION           _IOR('d', 0x3f, int)
> +
> +#ifdef __KERNEL__
> +
> +typedef enum { _stopped=0, _started } driver_state_t;
> +
> +typedef struct
> +{
> +       struct mutex mutex;
> +       struct usb_device *usbdev;
> +       wait_queue_head_t wait;
> +       wait_queue_head_t remove_ok;
> +       spinlock_t lock;
> +       atomic_t pending_io;
> +       driver_state_t state;
> +       int remove_pending;
> +       int got_mem;
> +       int total_buffer_size;
> +       unsigned int overruns;
> +       int readptr;
> +       int opened;
> +       int devnum;
> +       struct list_head free_buff_list;
> +       struct list_head rec_buff_list;
> +} dabusb_t,*pdabusb_t;
> +
> +typedef struct
> +{
> +       pdabusb_t s;
> +       struct urb *purb;
> +       struct list_head buff_list;
> +} buff_t,*pbuff_t;
> +
> +typedef struct
> +{
> +       wait_queue_head_t wait;
> +} bulk_completion_context_t, *pbulk_completion_context_t;
> +
> +
> +#define _DABUSB_IF 2
> +#define _DABUSB_ISOPIPE 0x09
> +#define _ISOPIPESIZE   16384
> +
> +#define _BULK_DATA_LEN 64
> +// Vendor specific request code for Anchor Upload/Download
> +// This one is implemented in the core
> +#define ANCHOR_LOAD_INTERNAL  0xA0
> +
> +// EZ-USB Control and Status Register.  Bit 0 controls 8051 reset
> +#define CPUCS_REG    0x7F92
> +#define _TOTAL_BUFFERS 384
> +
> +#define MAX_INTEL_HEX_RECORD_LENGTH 16
> +
> +#ifndef _BYTE_DEFINED
> +#define _BYTE_DEFINED
> +typedef unsigned char BYTE;
> +#endif // !_BYTE_DEFINED
> +
> +#ifndef _WORD_DEFINED
> +#define _WORD_DEFINED
> +typedef unsigned short WORD;
> +#endif // !_WORD_DEFINED
> +
> +typedef struct _INTEL_HEX_RECORD
> +{
> +   BYTE  Length;
> +   WORD  Address;
> +   BYTE  Type;
> +   BYTE  Data[MAX_INTEL_HEX_RECORD_LENGTH];
> +} INTEL_HEX_RECORD, *PINTEL_HEX_RECORD;
> +
> +#endif
> --
> To unsubscribe from this list: send the line "unsubscribe linux-media" in
> the body of a message to majordomo@xxxxxxxxxxxxxxx
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
>
--
To unsubscribe from this list: send the line "unsubscribe linux-media" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[Index of Archives]     [Linux Input]     [Video for Linux]     [Gstreamer Embedded]     [Mplayer Users]     [Linux USB Devel]     [Linux Audio Users]     [Linux Kernel]     [Linux SCSI]     [Yosemite Backpacking]
  Powered by Linux