/*****************************************************************************/

/*
 *	usbdrv.h  --  Linux USB driver interface.
 *
 *	Copyright (C) 1999-2001
 *          Thomas Sailer (t.sailer@alumni.ethz.ch)
 *
 *	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.
 *
 *  Please note that the GPL allows you to use the driver, NOT the radio.
 *  In order to use the radio, you need a license from the communications
 *  authority of your country.
 *
 *  $Id: usbdrv.h,v 1.3 2000/01/11 11:07:50 tom Exp $	 
 *
 *  History:
 *   0.1  07.01.2000  Created
 *
 */

/*****************************************************************************/

#ifndef _USBDRV_H
#define _USBDRV_H

/* --------------------------------------------------------------------- */

#ifdef HAVE_CONFIG_H
#include "config.h"
#endif

#define _GNU_SOURCE
#include <sys/types.h>
#include <stdio.h>

/*
 * needed for the URB definition
 */

#ifdef WIN32

struct usbdevfs_iso_packet_desc {
        unsigned int length;
        unsigned int actual_length;
        unsigned int status;
};

struct usbdevfs_urb {
        unsigned char type;
        unsigned char endpoint;
        int status;
        unsigned int flags;
        void *buffer;
        int buffer_length;
        int actual_length;
        int start_frame;
        int number_of_packets;
        int error_count;
        unsigned int signr;  /* signal to be sent on error, -1 if none should be sent */
        void *usercontext;
        struct usbdevfs_iso_packet_desc iso_frame_desc[0];
};

#define USBDEVFS_URB_DISABLE_SPD         0x0001
#define USBDEVFS_URB_ISO_ASAP            0x0002
#define USBDEVFS_URB_QUEUE_BULK          0x0010
#define USBDEVFS_URB_NO_FSBR             0x0020
#define USBDEVFS_URB_ZERO_PACKET         0x0040

#define USBDEVFS_URB_TYPE_ISO              0
#define USBDEVFS_URB_TYPE_INTERRUPT        1
#define USBDEVFS_URB_TYPE_CONTROL          2
#define USBDEVFS_URB_TYPE_BULK             3

#else

#ifdef HAVE_LINUX_USBDEVICE_FS_H
#include <linux/types.h>
#include <linux/usbdevice_fs.h>
#else
#include "usbdevice_fs.h"
#endif

#ifndef USBDEVFS_URB_ZERO_PACKET
#define USBDEVFS_URB_ZERO_PACKET         0x0040
#endif

#endif

/* --------------------------------------------------------------------- */

/*
 * provided externally!
 */

extern int lprintf(unsigned vl, const char *format, ...) __attribute__ ((format (printf, 2, 3)));

/* --------------------------------------------------------------------- */

struct usb_device_descriptor {
        u_int8_t  bLength;
        u_int8_t  bDescriptorType;
        u_int8_t  bcdUSB[2];
        u_int8_t  bDeviceClass;
        u_int8_t  bDeviceSubClass;
        u_int8_t  bDeviceProtocol;
        u_int8_t  bMaxPacketSize0;
        u_int8_t  idVendor[2];
        u_int8_t  idProduct[2];
        u_int8_t  bcdDevice[2];
        u_int8_t  iManufacturer;
        u_int8_t  iProduct;
        u_int8_t  iSerialNumber;
        u_int8_t  bNumConfigurations;
};

#define USB_DT_DEVICE_SIZE sizeof(struct usb_device_descriptor)

struct usb_control_request {
        u_int8_t  requesttype;
        u_int8_t  request;
	u_int8_t  value[2];
	u_int8_t  index[2];
	u_int8_t  length[2];
} __attribute__ ((packed));

#define USB_CONTROL_REQUEST_SIZE sizeof(struct usb_control_request)

/* --------------------------------------------------------------------- */

struct usbdevice;

extern void usb_setmountpoint(const char *mnt);
extern const char *usb_getmountpoint(void);
extern void usb_show_device_descriptor(FILE *f, struct usb_device_descriptor *desc);
extern void usb_close(struct usbdevice *dev);
extern struct usbdevice *usb_open_bynumber(unsigned int busnum, unsigned int devnum, int vendorid, int productid);
extern struct usbdevice *usb_open(int vendorid, int productid, unsigned int timeout, unsigned int index);
extern int usb_control_msg(struct usbdevice *dev, unsigned char requesttype, unsigned char request,
			  unsigned short value, unsigned short index, unsigned short length, void *data, unsigned int timeout);
extern int usb_bulk_msg(struct usbdevice *dev, unsigned int ep, unsigned int dlen, void *data, unsigned int timeout);
extern int usb_resetep(struct usbdevice *dev, unsigned int ep);
extern int usb_setconfiguration(struct usbdevice *dev, unsigned int configuration);
extern int usb_setinterface(struct usbdevice *dev, unsigned int intf, unsigned int altsetting);
extern int usb_getdevicedescriptor(struct usbdevice *dev, struct usb_device_descriptor *desc);
extern int usb_claiminterface(struct usbdevice *dev, unsigned int intf);
extern int usb_releaseinterface(struct usbdevice *dev, unsigned int intf);
extern int usb_discsignal(struct usbdevice *dev, unsigned int signr, void *context);
extern int usb_submiturb(struct usbdevice *dev, struct usbdevfs_urb *urb);
extern int usb_discardurb(struct usbdevice *dev, struct usbdevfs_urb *urb);
extern struct usbdevfs_urb *usb_reapurb(struct usbdevice *dev, int timeout); /* timeout: -1 infinity, 0 nonblocking, otherwise ms */

#if defined(WIN32)
extern HANDLE usb_getfd(struct usbdevice *dev);
#else
extern int usb_getfd(struct usbdevice *dev);
#endif

/* ---------------------------------------------------------------------- */
#endif /* _USBDRV_H */
