code:
/* $FreeBSD: release/9.0.0/sys/dev/usb/usb_controller.h 215846 2010-11-25 22:56:26Z weongyo $ */
/*-
 * Copyright (c) 2008 Hans Petter Selasky. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 */

#ifndef _USB_CONTROLLER_H_
#define	_USB_CONTROLLER_H_

/* defines */

#define	USB_BUS_DMA_TAG_MAX 8

/* structure prototypes  */

struct usb_bus;
struct usb_page;
struct usb_endpoint;
struct usb_page_cache;
struct usb_setup_params;
struct usb_hw_ep_profile;
struct usb_fs_isoc_schedule;
struct usb_config_descriptor;
struct usb_endpoint_descriptor;

/* typedefs */

typedef void (usb_bus_mem_sub_cb_t)(struct usb_bus *bus, struct usb_page_cache *pc, struct usb_page *pg, usb_size_t size, usb_size_t align);
typedef void (usb_bus_mem_cb_t)(struct usb_bus *bus, usb_bus_mem_sub_cb_t *scb);

/*
 * The following structure is used to define all the USB BUS
 * callbacks.
 */
struct usb_bus_methods {

	/* USB Device and Host mode - Mandatory */

	usb_handle_req_t *roothub_exec;

	void    (*endpoint_init) (struct usb_device *,
		    struct usb_endpoint_descriptor *, struct usb_endpoint *);
	void    (*xfer_setup) (struct usb_setup_params *);
	void    (*xfer_unsetup) (struct usb_xfer *);
	void    (*get_dma_delay) (struct usb_device *, uint32_t *);
	void    (*device_suspend) (struct usb_device *);
	void    (*device_resume) (struct usb_device *);
	void    (*set_hw_power) (struct usb_bus *);

	/*
	 * The following flag is set if one or more control transfers are
	 * active:
	 */
#define	USB_HW_POWER_CONTROL	0x01
	/*
	 * The following flag is set if one or more bulk transfers are
	 * active:
	 */
#define	USB_HW_POWER_BULK	0x02
	/*
	 * The following flag is set if one or more interrupt transfers are
	 * active:
	 */
#define	USB_HW_POWER_INTERRUPT	0x04
	/*
	 * The following flag is set if one or more isochronous transfers
	 * are active:
	 */
#define	USB_HW_POWER_ISOC	0x08
	/*
	 * The following flag is set if one or more non-root-HUB devices
	 * are present on the given USB bus:
	 */
#define	USB_HW_POWER_NON_ROOT_HUB 0x10

	/* USB Device mode only - Mandatory */

	void    (*get_hw_ep_profile) (struct usb_device *udev, const struct usb_hw_ep_profile **ppf, uint8_t ep_addr);
	void    (*set_stall) (struct usb_device *udev, struct usb_xfer *xfer, struct usb_endpoint *ep, uint8_t *did_stall);

	/* USB Device mode mandatory. USB Host mode optional. */

	void    (*clear_stall) (struct usb_device *udev, struct usb_endpoint *ep);

	/* Optional transfer polling support */

	void	(*xfer_poll) (struct usb_bus *);

	/* Optional fixed power mode support */

	void	(*get_power_mode) (struct usb_device *udev, int8_t *pmode);

	/* Optional endpoint uninit */

	void    (*endpoint_uninit) (struct usb_device *, struct usb_endpoint *);

	/* Optional device init */

	usb_error_t	(*device_init) (struct usb_device *);

	/* Optional device uninit */

	void	(*device_uninit) (struct usb_device *);

	/* Optional for device and host mode */

	void	(*start_dma_delay) (struct usb_xfer *);

	void	(*device_state_change) (struct usb_device *);

	/* Optional for host mode */

	usb_error_t	(*set_address) (struct usb_device *, struct mtx *, uint16_t);
};

/*
 * The following structure is used to define all the USB pipe
 * callbacks.
 */
struct usb_pipe_methods {

	/* Mandatory USB Device and Host mode callbacks: */

	void	(*open)(struct usb_xfer *);
	void	(*close)(struct usb_xfer *);

	void	(*enter)(struct usb_xfer *);
	void	(*start)(struct usb_xfer *);

	/* Optional */

	void   *info;
};

/*
 * The following structure keeps information about what a hardware USB
 * endpoint supports.
 */
struct usb_hw_ep_profile {
	uint16_t max_in_frame_size;	/* IN-token direction */
	uint16_t max_out_frame_size;	/* OUT-token direction */
	uint8_t	is_simplex:1;
	uint8_t	support_multi_buffer:1;
	uint8_t	support_bulk:1;
	uint8_t	support_control:1;
	uint8_t	support_interrupt:1;
	uint8_t	support_isochronous:1;
	uint8_t	support_in:1;		/* IN-token is supported */
	uint8_t	support_out:1;		/* OUT-token is supported */
};

/*
 * The following structure is used when trying to allocate hardware
 * endpoints for an USB configuration in USB device side mode.
 */
struct usb_hw_ep_scratch_sub {
	const struct usb_hw_ep_profile *pf;
	uint16_t max_frame_size;
	uint8_t	hw_endpoint_out;
	uint8_t	hw_endpoint_in;
	uint8_t	needs_ep_type;
	uint8_t	needs_in:1;
	uint8_t	needs_out:1;
};

/*
 * The following structure is used when trying to allocate hardware
 * endpoints for an USB configuration in USB device side mode.
 */
struct usb_hw_ep_scratch {
	struct usb_hw_ep_scratch_sub ep[USB_EP_MAX];
	struct usb_hw_ep_scratch_sub *ep_max;
	struct usb_config_descriptor *cd;
	struct usb_device *udev;
	struct usb_bus_methods *methods;
	uint8_t	bmOutAlloc[(USB_EP_MAX + 15) / 16];
	uint8_t	bmInAlloc[(USB_EP_MAX + 15) / 16];
};

/*
 * The following structure is used when generating USB descriptors
 * from USB templates.
 */
struct usb_temp_setup {
	void   *buf;
	usb_size_t size;
	enum usb_dev_speed	usb_speed;
	uint8_t	self_powered;
	uint8_t	bNumEndpoints;
	uint8_t	bInterfaceNumber;
	uint8_t	bAlternateSetting;
	uint8_t	bConfigurationValue;
	usb_error_t err;
};

/* prototypes */

void	usb_bus_mem_flush_all(struct usb_bus *bus, usb_bus_mem_cb_t *cb);
uint8_t	usb_bus_mem_alloc_all(struct usb_bus *bus, bus_dma_tag_t dmat, usb_bus_mem_cb_t *cb);
void	usb_bus_mem_free_all(struct usb_bus *bus, usb_bus_mem_cb_t *cb);
uint16_t usb_isoc_time_expand(struct usb_bus *bus, uint16_t isoc_time_curr);
uint16_t usbd_fs_isoc_schedule_isoc_time_expand(struct usb_device *udev, struct usb_fs_isoc_schedule **pp_start, struct usb_fs_isoc_schedule **pp_end, uint16_t isoc_time);
uint8_t	usbd_fs_isoc_schedule_alloc(struct usb_fs_isoc_schedule *fss, uint8_t *pstart, uint16_t len);

#endif					/* _USB_CONTROLLER_H_ */


code:
/* $FreeBSD: release/9.0.0/sys/dev/usb/usb_core.h 199672 2009-11-22 21:16:43Z thompsa $ */
/*-
 * Copyright (c) 2008 Hans Petter Selasky. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 */

/*
 * Including this file is mandatory for all USB related c-files in the kernel.
 */

#ifndef _USB_CORE_H_
#define	_USB_CORE_H_

/*
 * The following macro will tell if an USB transfer is currently
 * receiving or transferring data.
 */
#define	USB_GET_DATA_ISREAD(xfer) ((xfer)->flags_int.usb_mode == \
	USB_MODE_DEVICE ? (((xfer)->endpointno & UE_DIR_IN) ? 0 : 1) : \
	(((xfer)->endpointno & UE_DIR_IN) ? 1 : 0))

/* macros */

#define	USB_BUS_LOCK(_b)		mtx_lock(&(_b)->bus_mtx)
#define	USB_BUS_UNLOCK(_b)		mtx_unlock(&(_b)->bus_mtx)
#define	USB_BUS_LOCK_ASSERT(_b, _t)	mtx_assert(&(_b)->bus_mtx, _t)
#define	USB_XFER_LOCK(_x)		mtx_lock((_x)->xroot->xfer_mtx)
#define	USB_XFER_UNLOCK(_x)		mtx_unlock((_x)->xroot->xfer_mtx)
#define	USB_XFER_LOCK_ASSERT(_x, _t)	mtx_assert((_x)->xroot->xfer_mtx, _t)

/* helper for converting pointers to integers */
#define	USB_P2U(ptr) \
  (((const uint8_t *)(ptr)) - ((const uint8_t *)0))

/* helper for computing offsets */
#define	USB_ADD_BYTES(ptr,size) \
  ((void *)(USB_P2U(ptr) + (size)))

/* debug macro */
#define	USB_ASSERT KASSERT

/* structure prototypes */

struct file;
struct usb_bus;
struct usb_device;
struct usb_device_request;
struct usb_page;
struct usb_page_cache;
struct usb_xfer;
struct usb_xfer_root;

/* typedefs */

/* structures */

/*
 * The following structure defines a set of internal USB transfer
 * flags.
 */
struct usb_xfer_flags_int {

	enum usb_hc_mode usb_mode;	/* shadow copy of "udev->usb_mode" */
	uint16_t control_rem;		/* remainder in bytes */

	uint8_t	open:1;			/* set if USB pipe has been opened */
	uint8_t	transferring:1;		/* set if an USB transfer is in
					 * progress */
	uint8_t	did_dma_delay:1;	/* set if we waited for HW DMA */
	uint8_t	did_close:1;		/* set if we closed the USB transfer */
	uint8_t	draining:1;		/* set if we are draining an USB
					 * transfer */
	uint8_t	started:1;		/* keeps track of started or stopped */
	uint8_t	bandwidth_reclaimed:1;
	uint8_t	control_xfr:1;		/* set if control transfer */
	uint8_t	control_hdr:1;		/* set if control header should be
					 * sent */
	uint8_t	control_act:1;		/* set if control transfer is active */
	uint8_t	control_stall:1;	/* set if control transfer should be stalled */

	uint8_t	short_frames_ok:1;	/* filtered version */
	uint8_t	short_xfer_ok:1;	/* filtered version */
#if USB_HAVE_BUSDMA
	uint8_t	bdma_enable:1;		/* filtered version (only set if
					 * hardware supports DMA) */
	uint8_t	bdma_no_post_sync:1;	/* set if the USB callback wrapper
					 * should not do the BUS-DMA post sync
					 * operation */
	uint8_t	bdma_setup:1;		/* set if BUS-DMA has been setup */
#endif
	uint8_t	isochronous_xfr:1;	/* set if isochronous transfer */
	uint8_t	curr_dma_set:1;		/* used by USB HC/DC driver */
	uint8_t	can_cancel_immed:1;	/* set if USB transfer can be
					 * cancelled immediately */
	uint8_t	doing_callback:1;	/* set if executing the callback */
};

/*
 * The following structure defines an USB transfer.
 */
struct usb_xfer {
	struct usb_callout timeout_handle;
	TAILQ_ENTRY(usb_xfer) wait_entry;	/* used at various places */

	struct usb_page_cache *buf_fixup;	/* fixup buffer(s) */
	struct usb_xfer_queue *wait_queue;	/* pointer to queue that we
						 * are waiting on */
	struct usb_page *dma_page_ptr;
	struct usb_endpoint *endpoint;	/* our USB endpoint */
	struct usb_xfer_root *xroot;	/* used by HC driver */
	void   *qh_start[2];		/* used by HC driver */
	void   *td_start[2];		/* used by HC driver */
	void   *td_transfer_first;	/* used by HC driver */
	void   *td_transfer_last;	/* used by HC driver */
	void   *td_transfer_cache;	/* used by HC driver */
	void   *priv_sc;		/* device driver data pointer 1 */
	void   *priv_fifo;		/* device driver data pointer 2 */
	void   *local_buffer;
	usb_frlength_t *frlengths;
	struct usb_page_cache *frbuffers;
	usb_callback_t *callback;

	usb_frlength_t max_hc_frame_size;
	usb_frlength_t max_data_length;
	usb_frlength_t sumlen;		/* sum of all lengths in bytes */
	usb_frlength_t actlen;		/* actual length in bytes */
	usb_timeout_t timeout;		/* milliseconds */

	usb_frcount_t max_frame_count;	/* initial value of "nframes" after
					 * setup */
	usb_frcount_t nframes;		/* number of USB frames to transfer */
	usb_frcount_t aframes;		/* actual number of USB frames
					 * transferred */

	uint16_t max_packet_size;
	uint16_t max_frame_size;
	uint16_t qh_pos;
	uint16_t isoc_time_complete;	/* in ms */
	usb_timeout_t interval;	/* milliseconds */

	uint8_t	address;		/* physical USB address */
	uint8_t	endpointno;		/* physical USB endpoint */
	uint8_t	max_packet_count;
	uint8_t	usb_state;
	uint8_t fps_shift;		/* down shift of FPS, 0..3 */

	usb_error_t error;

	struct usb_xfer_flags flags;
	struct usb_xfer_flags_int flags_int;
};

/* external variables */

extern struct mtx usb_ref_lock;

/* typedefs */

typedef struct malloc_type *usb_malloc_type;

/* prototypes */

#endif					/* _USB_CORE_H_ */

repo_name: veiledmerc/mira

license: mit


code:
/* $FreeBSD: release/9.0.0/sys/dev/usb/usb_debug.h 207077 2010-04-22 21:31:34Z thompsa $ */
/*-
 * Copyright (c) 2008 Hans Petter Selasky. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 */

/* This file contains various factored out debug macros. */

#ifndef _USB_DEBUG_H_
#define	_USB_DEBUG_H_

/* Declare global USB debug variable. */
extern int usb_debug;

/* Check if USB debugging is enabled. */
#ifdef USB_DEBUG_VAR
#ifdef USB_DEBUG
#define	DPRINTFN(n,fmt,...) do {		\
  if ((USB_DEBUG_VAR) >= (n)) {			\
    printf("%s: " fmt,				\
	   __FUNCTION__,## __VA_ARGS__);	\
  }						\
} while (0)
#define	DPRINTF(...)	DPRINTFN(1, __VA_ARGS__)
#else
#define	DPRINTF(...) do { } while (0)
#define	DPRINTFN(...) do { } while (0)
#endif
#endif

struct usb_interface;
struct usb_device;
struct usb_endpoint;
struct usb_xfer;

void	usb_dump_iface(struct usb_interface *iface);
void	usb_dump_device(struct usb_device *udev);
void	usb_dump_queue(struct usb_endpoint *ep);
void	usb_dump_endpoint(struct usb_endpoint *ep);
void	usb_dump_xfer(struct usb_xfer *xfer);

#endif					/* _USB_DEBUG_H_ */


code:
/* $FreeBSD: release/9.0.0/sys/dev/usb/usb_dev.h 196219 2009-08-14 20:03:53Z jhb $ */
/*-
 * Copyright (c) 2008 Hans Petter Selasky. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 */

#ifndef _USB_DEV_H_
#define	_USB_DEV_H_

#include <sys/file.h>
#include <sys/selinfo.h>
#include <sys/poll.h>
#include <sys/signalvar.h>
#include <sys/proc.h>

struct usb_fifo;
struct usb_mbuf;

struct usb_symlink {
	TAILQ_ENTRY(usb_symlink) sym_entry;
	char	src_path[32];		/* Source path - including terminating
					 * zero */
	char	dst_path[32];		/* Destination path - including
					 * terminating zero */
	uint8_t	src_len;		/* String length */
	uint8_t	dst_len;		/* String length */
};

/*
 * Private per-device information.
 */
struct usb_cdev_privdata {
	struct usb_bus		*bus;
	struct usb_device	*udev;
	struct usb_interface	*iface;
	int			bus_index;	/* bus index */
	int			dev_index;	/* device index */
	int			ep_addr;	/* endpoint address */
	int			fflags;
	uint8_t			fifo_index;	/* FIFO index */
};

/*
 * The following structure defines a minimum re-implementation of the
 * ifqueue structure in the kernel.
 */
struct usb_ifqueue {
	struct usb_mbuf *ifq_head;
	struct usb_mbuf *ifq_tail;

	usb_size_t ifq_len;
	usb_size_t ifq_maxlen;
};

/*
 * Private per-device and per-thread reference information
 */
struct usb_cdev_refdata {
	struct usb_fifo		*rxfifo;
	struct usb_fifo		*txfifo;
	uint8_t			is_read;	/* location has read access */
	uint8_t			is_write;	/* location has write access */
	uint8_t			is_uref;	/* USB refcount decr. needed */
	uint8_t			is_usbfs;	/* USB-FS is active */
};

struct usb_fs_privdata {
	int bus_index;
	int dev_index;
	int ep_addr;
	int mode;
	int fifo_index;
	struct cdev *cdev;

	LIST_ENTRY(usb_fs_privdata) pd_next;
};

/*
 * Most of the fields in the "usb_fifo" structure are used by the
 * generic USB access layer.
 */
struct usb_fifo {
	struct usb_ifqueue free_q;
	struct usb_ifqueue used_q;
	struct selinfo selinfo;
	struct cv cv_io;
	struct cv cv_drain;
	struct usb_fifo_methods *methods;
	struct usb_symlink *symlink[2];/* our symlinks */
	struct proc *async_p;		/* process that wants SIGIO */
	struct usb_fs_endpoint *fs_ep_ptr;
	struct usb_device *udev;
	struct usb_xfer *xfer[2];
	struct usb_xfer **fs_xfer;
	struct mtx *priv_mtx;		/* client data */
	/* set if FIFO is opened by a FILE: */
	struct usb_cdev_privdata *curr_cpd;
	void   *priv_sc0;		/* client data */
	void   *priv_sc1;		/* client data */
	void   *queue_data;
	usb_timeout_t timeout;		/* timeout in milliseconds */
	usb_frlength_t bufsize;		/* BULK and INTERRUPT buffer size */
	usb_frcount_t nframes;		/* for isochronous mode */
	uint16_t dev_ep_index;		/* our device endpoint index */
	uint8_t	flag_sleeping;		/* set if FIFO is sleeping */
	uint8_t	flag_iscomplete;	/* set if a USB transfer is complete */
	uint8_t	flag_iserror;		/* set if FIFO error happened */
	uint8_t	flag_isselect;		/* set if FIFO is selected */
	uint8_t	flag_flushing;		/* set if FIFO is flushing data */
	uint8_t	flag_short;		/* set if short_ok or force_short
					 * transfer flags should be set */
	uint8_t	flag_stall;		/* set if clear stall should be run */
	uint8_t	flag_write_defrag;	/* set to defrag written data */
	uint8_t	flag_have_fragment;	/* set if defragging */
	uint8_t	iface_index;		/* set to the interface we belong to */
	uint8_t	fifo_index;		/* set to the FIFO index in "struct
					 * usb_device" */
	uint8_t	fs_ep_max;
	uint8_t	fifo_zlp;		/* zero length packet count */
	uint8_t	refcount;
#define	USB_FIFO_REF_MAX 0xFF
};

extern struct cdevsw usb_devsw;

int	usb_fifo_wait(struct usb_fifo *fifo);
void	usb_fifo_signal(struct usb_fifo *fifo);
uint8_t	usb_fifo_opened(struct usb_fifo *fifo);
struct usb_symlink *usb_alloc_symlink(const char *target);
void	usb_free_symlink(struct usb_symlink *ps);
int	usb_read_symlink(uint8_t *user_ptr, uint32_t startentry,
	    uint32_t user_len);

#endif					/* _USB_DEV_H_ */


code:
/* $FreeBSD: release/9.0.0/sys/dev/usb/usb_device.h 225350 2011-09-02 18:50:44Z hselasky $ */
/*-
 * Copyright (c) 2008 Hans Petter Selasky. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 */

#ifndef _USB_DEVICE_H_
#define	_USB_DEVICE_H_

struct usb_symlink;		/* UGEN */
struct usb_device;		/* linux compat */
struct usb_fs_privdata;

#define	USB_CTRL_XFER_MAX 2

/* "usb_parse_config()" commands */

#define	USB_CFG_ALLOC 0
#define	USB_CFG_FREE 1
#define	USB_CFG_INIT 2

/* "usb_unconfigure()" flags */

#define	USB_UNCFG_FLAG_NONE 0x00
#define	USB_UNCFG_FLAG_FREE_EP0	0x02		/* endpoint zero is freed */

struct usb_clear_stall_msg {
	struct usb_proc_msg hdr;
	struct usb_device *udev;
};

/* The following four structures makes up a tree, where we have the
 * leaf structure, "usb_host_endpoint", first, and the root structure,
 * "usb_device", last. The four structures below mirror the structure
 * of the USB descriptors belonging to an USB configuration. Please
 * refer to the USB specification for a definition of "endpoints" and
 * "interfaces".
 */
struct usb_host_endpoint {
	struct usb_endpoint_descriptor desc;
	TAILQ_HEAD(, urb) bsd_urb_list;
	struct usb_xfer *bsd_xfer[2];
	uint8_t *extra;			/* Extra descriptors */
	usb_frlength_t fbsd_buf_size;
	uint16_t extralen;
	uint8_t	bsd_iface_index;
} __aligned(USB_HOST_ALIGN);

struct usb_host_interface {
	struct usb_interface_descriptor desc;
	/* the following array has size "desc.bNumEndpoint" */
	struct usb_host_endpoint *endpoint;
	const char *string;		/* iInterface string, if present */
	uint8_t *extra;			/* Extra descriptors */
	uint16_t extralen;
	uint8_t	bsd_iface_index;
} __aligned(USB_HOST_ALIGN);

/*
 * The following structure defines the USB device flags.
 */
struct usb_device_flags {
	enum usb_hc_mode usb_mode;	/* host or device mode */
	uint8_t	self_powered:1;		/* set if USB device is self powered */
	uint8_t	no_strings:1;		/* set if USB device does not support
					 * strings */
	uint8_t	remote_wakeup:1;	/* set if remote wakeup is enabled */
	uint8_t	uq_bus_powered:1;	/* set if BUS powered quirk is present */

	/*
	 * NOTE: Although the flags below will reach the same value
	 * over time, but the instant values may differ, and
	 * consequently the flags cannot be merged into one!
	 */
	uint8_t peer_suspended:1;	/* set if peer is suspended */
	uint8_t self_suspended:1;	/* set if self is suspended */
};

/*
 * The following structure is used for power-save purposes. The data
 * in this structure is protected by the USB BUS lock.
 */
struct usb_power_save {
	usb_ticks_t last_xfer_time;	/* copy of "ticks" */
	usb_size_t type_refs[4];	/* transfer reference count */
	usb_size_t read_refs;		/* data read references */
	usb_size_t write_refs;		/* data write references */
};

/*
 * The following structure defines an USB device. There exists one of
 * these structures for every USB device.
 */
struct usb_device {
	struct usb_clear_stall_msg cs_msg[2];	/* generic clear stall
						 * messages */
	struct sx ctrl_sx;
	struct sx enum_sx;
	struct sx sr_sx;
	struct mtx device_mtx;
	struct cv ctrlreq_cv;
	struct cv ref_cv;
	struct usb_interface *ifaces;
	struct usb_endpoint ctrl_ep;	/* Control Endpoint 0 */
	struct usb_endpoint *endpoints;
	struct usb_power_save pwr_save;/* power save data */
	struct usb_bus *bus;		/* our USB BUS */
	device_t parent_dev;		/* parent device */
	struct usb_device *parent_hub;
	struct usb_device *parent_hs_hub;	/* high-speed parent HUB */
	struct usb_config_descriptor *cdesc;	/* full config descr */
	struct usb_hub *hub;		/* only if this is a hub */
	struct usb_xfer *ctrl_xfer[USB_CTRL_XFER_MAX];
	struct usb_temp_data *usb_template_ptr;
	struct usb_endpoint *ep_curr;	/* current clear stall endpoint */
#if USB_HAVE_UGEN
	struct usb_fifo *fifo[USB_FIFO_MAX];
	struct usb_symlink *ugen_symlink;	/* our generic symlink */
	struct usb_fs_privdata *ctrl_dev;	/* Control Endpoint 0 device node */
	LIST_HEAD(,usb_fs_privdata) pd_list;
	char	ugen_name[20];		/* name of ugenX.X device */
#endif
	usb_ticks_t plugtime;		/* copy of "ticks" */

	enum usb_dev_state state;
	enum usb_dev_speed speed;
	uint16_t refcount;
#define	USB_DEV_REF_MAX 0xffff

	uint16_t power;			/* mA the device uses */
	uint16_t langid;		/* language for strings */
	uint16_t autoQuirk[USB_MAX_AUTO_QUIRK];		/* dynamic quirks */

	uint8_t	address;		/* device addess */
	uint8_t	device_index;		/* device index in "bus->devices" */
	uint8_t	controller_slot_id;	/* controller specific value */
	uint8_t	curr_config_index;	/* current configuration index */
	uint8_t	curr_config_no;		/* current configuration number */
	uint8_t	depth;			/* distance from root HUB */
	uint8_t	port_index;		/* parent HUB port index */
	uint8_t	port_no;		/* parent HUB port number */
	uint8_t	hs_hub_addr;		/* high-speed HUB address */
	uint8_t	hs_port_no;		/* high-speed HUB port number */
	uint8_t	driver_added_refcount;	/* our driver added generation count */
	uint8_t	power_mode;		/* see USB_POWER_XXX */
	uint8_t re_enumerate_wait;	/* set if re-enum. is in progress */
	uint8_t ifaces_max;		/* number of interfaces present */
	uint8_t endpoints_max;		/* number of endpoints present */

	/* the "flags" field is write-protected by "bus->mtx" */

	struct usb_device_flags flags;

	struct usb_endpoint_descriptor ctrl_ep_desc;	/* for endpoint 0 */
	struct usb_endpoint_ss_comp_descriptor ctrl_ep_comp_desc;	/* for endpoint 0 */
	struct usb_device_descriptor ddesc;	/* device descriptor */

	char	*serial;		/* serial number, can be NULL */
	char	*manufacturer;		/* manufacturer string, can be NULL */
	char	*product;		/* product string, can be NULL */

#if USB_HAVE_COMPAT_LINUX
	/* Linux compat */
	struct usb_device_descriptor descriptor;
	struct usb_host_endpoint ep0;
	struct usb_interface *linux_iface_start;
	struct usb_interface *linux_iface_end;
	struct usb_host_endpoint *linux_endpoint_start;
	struct usb_host_endpoint *linux_endpoint_end;
	uint16_t devnum;
#endif

	uint32_t clear_stall_errors;	/* number of clear-stall failures */
};

/* globals */

extern int usb_template;

/* function prototypes */

const char *usb_statestr(enum usb_dev_state state);
struct usb_device *usb_alloc_device(device_t parent_dev, struct usb_bus *bus,
		    struct usb_device *parent_hub, uint8_t depth,
		    uint8_t port_index, uint8_t port_no,
		    enum usb_dev_speed speed, enum usb_hc_mode mode);
#if USB_HAVE_UGEN
struct usb_fs_privdata *usb_make_dev(struct usb_device *, const char *,
		    int, int, int, uid_t, gid_t, int);
void	usb_destroy_dev(struct usb_fs_privdata *);
#endif
usb_error_t	usb_probe_and_attach(struct usb_device *udev,
		    uint8_t iface_index);
void		usb_detach_device(struct usb_device *, uint8_t, uint8_t);
usb_error_t	usb_reset_iface_endpoints(struct usb_device *udev,
		    uint8_t iface_index);
usb_error_t	usbd_set_config_index(struct usb_device *udev, uint8_t index);
usb_error_t	usbd_set_endpoint_stall(struct usb_device *udev,
		    struct usb_endpoint *ep, uint8_t do_stall);
usb_error_t	usb_suspend_resume(struct usb_device *udev,
		    uint8_t do_suspend);
void	usb_devinfo(struct usb_device *udev, char *dst_ptr, uint16_t dst_len);
void	usb_free_device(struct usb_device *, uint8_t);
void	usb_linux_free_device(struct usb_device *dev);
uint8_t	usb_peer_can_wakeup(struct usb_device *udev);
struct usb_endpoint *usb_endpoint_foreach(struct usb_device *udev, struct usb_endpoint *ep);
void	usb_set_device_state(struct usb_device *, enum usb_dev_state);
enum usb_dev_state usb_get_device_state(struct usb_device *);

void	usbd_enum_lock(struct usb_device *);
void	usbd_enum_unlock(struct usb_device *);
void	usbd_sr_lock(struct usb_device *);
void	usbd_sr_unlock(struct usb_device *);
uint8_t usbd_enum_is_locked(struct usb_device *);

#endif					/* _USB_DEVICE_H_ */


code:
/* $FreeBSD: release/9.0.0/sys/dev/usb/usb_dynamic.h 225469 2011-09-10 15:55:36Z hselasky $ */
/*-
 * Copyright (c) 2008 Hans Petter Selasky. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 */

#ifndef _USB_DYNAMIC_H_
#define	_USB_DYNAMIC_H_

/* prototypes */

struct usb_device;
struct usbd_lookup_info;
struct usb_device_request;

/* typedefs */

typedef usb_error_t	(usb_temp_setup_by_index_t)(struct usb_device *udev,
			    uint16_t index);
typedef uint8_t		(usb_test_quirk_t)(const struct usbd_lookup_info *info,
			    uint16_t quirk);
typedef int		(usb_quirk_ioctl_t)(unsigned long cmd, caddr_t data,
			    int fflag, struct thread *td);
typedef void		(usb_temp_unsetup_t)(struct usb_device *udev);

/* global function pointers */

extern usb_handle_req_t *usb_temp_get_desc_p;
extern usb_temp_setup_by_index_t *usb_temp_setup_by_index_p;
extern usb_temp_unsetup_t *usb_temp_unsetup_p;
extern usb_test_quirk_t *usb_test_quirk_p;
extern usb_quirk_ioctl_t *usb_quirk_ioctl_p;
extern devclass_t usb_devclass_ptr;

/* function prototypes */

void	usb_temp_unload(void *);
void	usb_quirk_unload(void *);
void	usb_bus_unload(void *);

#endif					/* _USB_DYNAMIC_H_ */


code:
/* $FreeBSD: release/9.0.0/sys/dev/usb/usb_endian.h 196219 2009-08-14 20:03:53Z jhb $ */
/*
 * Copyright (c) 2008 Hans Petter Selasky. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 */

#ifndef _USB_ENDIAN_H_
#define	_USB_ENDIAN_H_

#include <sys/stdint.h>
#include <sys/endian.h>

/*
 * Declare the basic USB record types. USB records have an alignment
 * of 1 byte and are always packed.
 */
typedef uint8_t uByte;
typedef uint8_t uWord[2];
typedef uint8_t uDWord[4];
typedef uint8_t uQWord[8];

/*
 * Define a set of macros that can get and set data independent of
 * CPU endianness and CPU alignment requirements:
 */
#define	UGETB(w)			\
  ((w)[0])

#define	UGETW(w)			\
  ((w)[0] |				\
  (((uint16_t)((w)[1])) << 8))

#define	UGETDW(w)			\
  ((w)[0] |				\
  (((uint16_t)((w)[1])) << 8) |		\
  (((uint32_t)((w)[2])) << 16) |	\
  (((uint32_t)((w)[3])) << 24))

#define	UGETQW(w)			\
  ((w)[0] |				\
  (((uint16_t)((w)[1])) << 8) |		\
  (((uint32_t)((w)[2])) << 16) |	\
  (((uint32_t)((w)[3])) << 24) |	\
  (((uint64_t)((w)[4])) << 32) |	\
  (((uint64_t)((w)[5])) << 40) |	\
  (((uint64_t)((w)[6])) << 48) |	\
  (((uint64_t)((w)[7])) << 56))

#define	USETB(w,v) do {			\
  (w)[0] = (uint8_t)(v);		\
} while (0)

#define	USETW(w,v) do {			\
  (w)[0] = (uint8_t)(v);		\
  (w)[1] = (uint8_t)((v) >> 8);		\
} while (0)

#define	USETDW(w,v) do {		\
  (w)[0] = (uint8_t)(v);		\
  (w)[1] = (uint8_t)((v) >> 8);		\
  (w)[2] = (uint8_t)((v) >> 16);	\
  (w)[3] = (uint8_t)((v) >> 24);	\
} while (0)

#define	USETQW(w,v) do {		\
  (w)[0] = (uint8_t)(v);		\
  (w)[1] = (uint8_t)((v) >> 8);		\
  (w)[2] = (uint8_t)((v) >> 16);	\
  (w)[3] = (uint8_t)((v) >> 24);	\
  (w)[4] = (uint8_t)((v) >> 32);	\
  (w)[5] = (uint8_t)((v) >> 40);	\
  (w)[6] = (uint8_t)((v) >> 48);	\
  (w)[7] = (uint8_t)((v) >> 56);	\
} while (0)

#define	USETW2(w,b1,b0) do {		\
  (w)[0] = (uint8_t)(b0);		\
  (w)[1] = (uint8_t)(b1);		\
} while (0)

#define	USETW4(w,b3,b2,b1,b0) do {	\
  (w)[0] = (uint8_t)(b0);		\
  (w)[1] = (uint8_t)(b1);		\
  (w)[2] = (uint8_t)(b2);		\
  (w)[3] = (uint8_t)(b3);		\
} while (0)

#define	USETW8(w,b7,b6,b5,b4,b3,b2,b1,b0) do {	\
  (w)[0] = (uint8_t)(b0);		\
  (w)[1] = (uint8_t)(b1);		\
  (w)[2] = (uint8_t)(b2);		\
  (w)[3] = (uint8_t)(b3);		\
  (w)[4] = (uint8_t)(b4);		\
  (w)[5] = (uint8_t)(b5);		\
  (w)[6] = (uint8_t)(b6);		\
  (w)[7] = (uint8_t)(b7);		\
} while (0)

#endif					/* _USB_ENDIAN_H_ */


code:
/* $FreeBSD: release/9.0.0/sys/dev/usb/usb_freebsd.h 225350 2011-09-02 18:50:44Z hselasky $ */
/*-
 * Copyright (c) 2008 Hans Petter Selasky. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 */

/*
 * Including this file is mandatory for all USB related c-files in the kernel.
 */

#ifndef _USB_FREEBSD_H_
#define	_USB_FREEBSD_H_

/* Default USB configuration */
#define	USB_HAVE_UGEN 1
#define	USB_HAVE_DEVCTL 1
#define	USB_HAVE_BUSDMA 1
#define	USB_HAVE_COMPAT_LINUX 1
#define	USB_HAVE_USER_IO 1
#define	USB_HAVE_MBUF 1
#define	USB_HAVE_TT_SUPPORT 1
#define	USB_HAVE_POWERD 1
#define	USB_HAVE_MSCTEST 1
#define	USB_HAVE_PF 1

#define	USB_TD_GET_PROC(td) (td)->td_proc
#define	USB_PROC_GET_GID(td) (td)->p_pgid

#if (!defined(USB_HOST_ALIGN)) || (USB_HOST_ALIGN <= 0)
/* Use default value. */
#undef USB_HOST_ALIGN
#define	USB_HOST_ALIGN    8		/* bytes, must be power of two */
#endif
/* Sanity check for USB_HOST_ALIGN: Verify power of two. */
#if ((-USB_HOST_ALIGN) & USB_HOST_ALIGN) != USB_HOST_ALIGN
#error "USB_HOST_ALIGN is not power of two."
#endif
#define	USB_FS_ISOC_UFRAME_MAX 4	/* exclusive unit */
#define	USB_BUS_MAX 256			/* units */
#define	USB_MAX_DEVICES 128		/* units */
#define	USB_IFACE_MAX 32		/* units */
#define	USB_FIFO_MAX 128		/* units */

#define	USB_MAX_FS_ISOC_FRAMES_PER_XFER (120)	/* units */
#define	USB_MAX_HS_ISOC_FRAMES_PER_XFER (8*120)	/* units */

#define	USB_HUB_MAX_DEPTH	5
#define	USB_EP0_BUFSIZE		1024	/* bytes */
#define	USB_CS_RESET_LIMIT	20	/* failures = 20 * 50 ms = 1sec */

#define	USB_MAX_AUTO_QUIRK	4	/* maximum number of dynamic quirks */

typedef uint32_t usb_timeout_t;		/* milliseconds */
typedef uint32_t usb_frlength_t;	/* bytes */
typedef uint32_t usb_frcount_t;		/* units */
typedef uint32_t usb_size_t;		/* bytes */
typedef uint32_t usb_ticks_t;		/* system defined */
typedef uint16_t usb_power_mask_t;	/* see "USB_HW_POWER_XXX" */

#endif	/* _USB_FREEBSD_H_ */


code:
/* $FreeBSD: release/9.0.0/sys/dev/usb/usb_generic.h 196219 2009-08-14 20:03:53Z jhb $ */
/*-
 * Copyright (c) 2008 Hans Petter Selasky. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 */

#ifndef _USB_GENERIC_H_
#define	_USB_GENERIC_H_

extern struct usb_fifo_methods usb_ugen_methods;
int	ugen_do_request(struct usb_fifo *f, struct usb_ctl_request *ur);

#endif					/* _USB_GENERIC_H_ */


code:
/* $FreeBSD: release/9.0.0/sys/dev/usb/usb_hub.h 213435 2010-10-04 23:18:05Z hselasky $ */
/*-
 * Copyright (c) 2008 Hans Petter Selasky. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 */

#ifndef _USB_HUB_H_
#define	_USB_HUB_H_

/*
 * The following structure defines an USB port.
 */
struct usb_port {
	uint8_t	restartcnt;
#define	USB_RESTART_MAX 5
	uint8_t	device_index;		/* zero means not valid */
	enum usb_hc_mode usb_mode;	/* host or device mode */
};

/*
 * The following structure defines how many bytes are
 * left in an 1ms USB time slot.
 */
struct usb_fs_isoc_schedule {
	uint16_t total_bytes;
	uint8_t	frame_bytes;
	uint8_t	frame_slot;
};

/*
 * The following structure defines an USB HUB.
 */
struct usb_hub {
#if USB_HAVE_TT_SUPPORT
	struct usb_fs_isoc_schedule fs_isoc_schedule[USB_ISOC_TIME_MAX];
#endif
	struct usb_device *hubudev;	/* the HUB device */
	usb_error_t (*explore) (struct usb_device *hub);
	void   *hubsoftc;
	usb_size_t uframe_usage[USB_HS_MICRO_FRAMES_MAX];
	uint16_t portpower;		/* mA per USB port */
	uint8_t	isoc_last_time;
	uint8_t	nports;
	struct usb_port ports[0];
};

/* function prototypes */

void	usb_hs_bandwidth_alloc(struct usb_xfer *xfer);
void	usb_hs_bandwidth_free(struct usb_xfer *xfer);
void	usbd_fs_isoc_schedule_init_all(struct usb_fs_isoc_schedule *fss);
void	usb_bus_port_set_device(struct usb_bus *bus, struct usb_port *up,
	    struct usb_device *udev, uint8_t device_index);
struct usb_device *usb_bus_port_get_device(struct usb_bus *bus,
	    struct usb_port *up);
void	usb_needs_explore(struct usb_bus *bus, uint8_t do_probe);
void	usb_needs_explore_all(void);
void	usb_bus_power_update(struct usb_bus *bus);
void	usb_bus_powerd(struct usb_bus *bus);
void	uhub_root_intr(struct usb_bus *, const uint8_t *, uint8_t);
usb_error_t uhub_query_info(struct usb_device *, uint8_t *, uint8_t *);

#endif					/* _USB_HUB_H_ */


code:
/* $FreeBSD: release/9.0.0/sys/dev/usb/usb_ioctl.h 223467 2011-06-23 07:54:03Z hselasky $ */
/*-
 * Copyright (c) 2008 Hans Petter Selasky. All rights reserved.
 * Copyright (c) 1998 The NetBSD Foundation, Inc. All rights reserved.
 * Copyright (c) 1998 Lennart Augustsson. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 */

#ifndef _USB_IOCTL_H_
#define	_USB_IOCTL_H_

#include <sys/ioccom.h>

/* Building "kdump" depends on these includes */

#include <dev/usb/usb_endian.h>
#include <dev/usb/usb.h>

#define	USB_DEVICE_NAME "usbctl"
#define	USB_DEVICE_DIR "usb"
#define	USB_GENERIC_NAME "ugen"
#define	USB_TEMPLATE_SYSCTL "hw.usb.template"	/* integer type */

/* Definition of valid template sysctl values */

enum {
	USB_TEMP_MSC,		/* USB Mass Storage */
	USB_TEMP_CDCE,		/* USB CDC Ethernet */
	USB_TEMP_MTP,		/* Message Transfer Protocol */
	USB_TEMP_MODEM,		/* USB CDC Modem */
	USB_TEMP_AUDIO,		/* USB Audio */
	USB_TEMP_KBD,		/* USB Keyboard */
	USB_TEMP_MOUSE,		/* USB Mouse */
	USB_TEMP_MAX,
};

struct usb_read_dir {
#ifdef COMPAT_32BIT
	uint64_t urd_data;
#else
	void   *urd_data;
#endif
	uint32_t urd_startentry;
	uint32_t urd_maxlen;
};

struct usb_ctl_request {
#ifdef COMPAT_32BIT
	uint64_t ucr_data;
#else
	void   *ucr_data;
#endif
	uint16_t ucr_flags;
	uint16_t ucr_actlen;		/* actual length transferred */
	uint8_t	ucr_addr;		/* zero - currently not used */
	struct usb_device_request ucr_request;
};

struct usb_alt_interface {
	uint8_t	uai_interface_index;
	uint8_t	uai_alt_index;
};

struct usb_gen_descriptor {
#ifdef COMPAT_32BIT
	uint64_t ugd_data;
#else
	void   *ugd_data;
#endif
	uint16_t ugd_lang_id;
	uint16_t ugd_maxlen;
	uint16_t ugd_actlen;
	uint16_t ugd_offset;
	uint8_t	ugd_config_index;
	uint8_t	ugd_string_index;
	uint8_t	ugd_iface_index;
	uint8_t	ugd_altif_index;
	uint8_t	ugd_endpt_index;
	uint8_t	ugd_report_type;
	uint8_t	reserved[8];
};

struct usb_device_info {
	uint16_t udi_productNo;
	uint16_t udi_vendorNo;
	uint16_t udi_releaseNo;
	uint16_t udi_power;		/* power consumption in mA, 0 if
					 * selfpowered */
	uint8_t	udi_bus;
	uint8_t	udi_addr;		/* device address */
	uint8_t	udi_index;		/* device index */
	uint8_t	udi_class;
	uint8_t	udi_subclass;
	uint8_t	udi_protocol;
	uint8_t	udi_config_no;		/* current config number */
	uint8_t	udi_config_index;	/* current config index */
	uint8_t	udi_speed;		/* see "USB_SPEED_XXX" */
	uint8_t	udi_mode;		/* see "USB_MODE_XXX" */
	uint8_t	udi_nports;
	uint8_t	udi_hubaddr;		/* parent HUB address */
	uint8_t	udi_hubindex;		/* parent HUB device index */
	uint8_t	udi_hubport;		/* parent HUB port */
	uint8_t	udi_power_mode;		/* see "USB_POWER_MODE_XXX" */
	uint8_t	udi_suspended;		/* set if device is suspended */
	uint8_t	udi_reserved[16];	/* leave space for the future */
	char	udi_product[128];
	char	udi_vendor[128];
	char	udi_serial[64];
	char	udi_release[8];
};

struct usb_device_stats {
	uint32_t uds_requests_ok[4];	/* Indexed by transfer type UE_XXX */
	uint32_t uds_requests_fail[4];	/* Indexed by transfer type UE_XXX */
};

struct usb_fs_start {
	uint8_t	ep_index;
};

struct usb_fs_stop {
	uint8_t	ep_index;
};

struct usb_fs_complete {
	uint8_t	ep_index;
};

/* This structure is used for all endpoint types */
struct usb_fs_endpoint {
	/*
	 * NOTE: isochronous USB transfer only use one buffer, but can have
	 * multiple frame lengths !
	 */
#ifdef COMPAT_32BIT
	uint64_t ppBuffer;
	uint64_t pLength;
#else
	void  **ppBuffer;		/* pointer to userland buffers */
	uint32_t *pLength;		/* pointer to frame lengths, updated
					 * to actual length */
#endif
	uint32_t nFrames;		/* number of frames */
	uint32_t aFrames;		/* actual number of frames */
	uint16_t flags;
	/* a single short frame will terminate */
#define	USB_FS_FLAG_SINGLE_SHORT_OK 0x0001
	/* multiple short frames are allowed */
#define	USB_FS_FLAG_MULTI_SHORT_OK 0x0002
	/* all frame(s) transmitted are short terminated */
#define	USB_FS_FLAG_FORCE_SHORT 0x0004
	/* will do a clear-stall before xfer */
#define	USB_FS_FLAG_CLEAR_STALL 0x0008
	uint16_t timeout;		/* in milliseconds */
	/* isocronous completion time in milliseconds - used for echo cancel */
	uint16_t isoc_time_complete;
	/* timeout value for no timeout */
#define	USB_FS_TIMEOUT_NONE 0
	int	status;			/* see USB_ERR_XXX */
};

struct usb_fs_init {
	/* userland pointer to endpoints structure */
#ifdef COMPAT_32BIT
	uint64_t pEndpoints;
#else
	struct usb_fs_endpoint *pEndpoints;
#endif
	/* maximum number of endpoints */
	uint8_t	ep_index_max;
};

struct usb_fs_uninit {
	uint8_t	dummy;			/* zero */
};

struct usb_fs_open {
#define	USB_FS_MAX_BUFSIZE (1 << 18)
	uint32_t max_bufsize;
#define	USB_FS_MAX_FRAMES		(1U << 12)
#define	USB_FS_MAX_FRAMES_PRE_SCALE	(1U << 31)	/* for ISOCHRONOUS transfers */
	uint32_t max_frames;		/* read and write */
	uint16_t max_packet_length;	/* read only */
	uint8_t	dev_index;		/* currently unused */
	uint8_t	ep_index;
	uint8_t	ep_no;			/* bEndpointNumber */
};

struct usb_fs_close {
	uint8_t	ep_index;
};

struct usb_fs_clear_stall_sync {
	uint8_t	ep_index;
};

struct usb_gen_quirk {
	uint16_t index;			/* Quirk Index */
	uint16_t vid;			/* Vendor ID */
	uint16_t pid;			/* Product ID */
	uint16_t bcdDeviceLow;		/* Low Device Revision */
	uint16_t bcdDeviceHigh;		/* High Device Revision */
	uint16_t reserved[2];
	/*
	 * String version of quirk including terminating zero. See UQ_XXX in
	 * "usb_quirk.h".
	 */
	char	quirkname[64 - 14];
};

/* USB controller */
#define	USB_REQUEST		_IOWR('U', 1, struct usb_ctl_request)
#define	USB_SETDEBUG		_IOW ('U', 2, int)
#define	USB_DISCOVER		_IO  ('U', 3)
#define	USB_DEVICEINFO		_IOWR('U', 4, struct usb_device_info)
#define	USB_DEVICESTATS		_IOR ('U', 5, struct usb_device_stats)
#define	USB_DEVICEENUMERATE	_IOW ('U', 6, int)

/* Generic HID device */
#define	USB_GET_REPORT_DESC	_IOWR('U', 21, struct usb_gen_descriptor)
#define	USB_SET_IMMED		_IOW ('U', 22, int)
#define	USB_GET_REPORT		_IOWR('U', 23, struct usb_gen_descriptor)
#define	USB_SET_REPORT		_IOW ('U', 24, struct usb_gen_descriptor)
#define	USB_GET_REPORT_ID	_IOR ('U', 25, int)

/* Generic USB device */
#define	USB_GET_CONFIG		_IOR ('U', 100, int)
#define	USB_SET_CONFIG		_IOW ('U', 101, int)
#define	USB_GET_ALTINTERFACE	_IOWR('U', 102, struct usb_alt_interface)
#define	USB_SET_ALTINTERFACE	_IOWR('U', 103, struct usb_alt_interface)
#define	USB_GET_DEVICE_DESC	_IOR ('U', 105, struct usb_device_descriptor)
#define	USB_GET_CONFIG_DESC	_IOR ('U', 106, struct usb_config_descriptor)
#define	USB_GET_RX_INTERFACE_DESC _IOR ('U', 107, struct usb_interface_descriptor)
#define	USB_GET_RX_ENDPOINT_DESC _IOR ('U', 108, struct usb_endpoint_descriptor)
#define	USB_GET_FULL_DESC	_IOWR('U', 109, struct usb_gen_descriptor)
#define	USB_GET_STRING_DESC	_IOWR('U', 110, struct usb_gen_descriptor)
#define	USB_DO_REQUEST		_IOWR('U', 111, struct usb_ctl_request)
#define	USB_GET_DEVICEINFO	_IOR ('U', 112, struct usb_device_info)
#define	USB_SET_RX_SHORT_XFER	_IOW ('U', 113, int)
#define	USB_SET_RX_TIMEOUT	_IOW ('U', 114, int)
#define	USB_GET_RX_FRAME_SIZE	_IOR ('U', 115, int)
#define	USB_GET_RX_BUFFER_SIZE	_IOR ('U', 117, int)
#define	USB_SET_RX_BUFFER_SIZE	_IOW ('U', 118, int)
#define	USB_SET_RX_STALL_FLAG	_IOW ('U', 119, int)
#define	USB_SET_TX_STALL_FLAG	_IOW ('U', 120, int)
#define	USB_GET_IFACE_DRIVER	_IOWR('U', 121, struct usb_gen_descriptor)
#define	USB_CLAIM_INTERFACE	_IOW ('U', 122, int)
#define	USB_RELEASE_INTERFACE	_IOW ('U', 123, int)
#define	USB_IFACE_DRIVER_ACTIVE	_IOW ('U', 124, int)
#define	USB_IFACE_DRIVER_DETACH	_IOW ('U', 125, int)
#define	USB_GET_PLUGTIME	_IOR ('U', 126, uint32_t)
#define	USB_READ_DIR		_IOW ('U', 127, struct usb_read_dir)
/* 128 - 135 unused */
#define	USB_SET_TX_FORCE_SHORT	_IOW ('U', 136, int)
#define	USB_SET_TX_TIMEOUT	_IOW ('U', 137, int)
#define	USB_GET_TX_FRAME_SIZE	_IOR ('U', 138, int)
#define	USB_GET_TX_BUFFER_SIZE	_IOR ('U', 139, int)
#define	USB_SET_TX_BUFFER_SIZE	_IOW ('U', 140, int)
#define	USB_GET_TX_INTERFACE_DESC _IOR ('U', 141, struct usb_interface_descriptor)
#define	USB_GET_TX_ENDPOINT_DESC _IOR ('U', 142, struct usb_endpoint_descriptor)
#define	USB_SET_PORT_ENABLE	_IOW ('U', 143, int)
#define	USB_SET_PORT_DISABLE	_IOW ('U', 144, int)
#define	USB_SET_POWER_MODE	_IOW ('U', 145, int)
#define	USB_GET_POWER_MODE	_IOR ('U', 146, int)
#define	USB_SET_TEMPLATE	_IOW ('U', 147, int)
#define	USB_GET_TEMPLATE	_IOR ('U', 148, int)

/* Modem device */
#define	USB_GET_CM_OVER_DATA	_IOR ('U', 180, int)
#define	USB_SET_CM_OVER_DATA	_IOW ('U', 181, int)

/* USB file system interface */
#define	USB_FS_START		_IOW ('U', 192, struct usb_fs_start)
#define	USB_FS_STOP		_IOW ('U', 193, struct usb_fs_stop)
#define	USB_FS_COMPLETE		_IOR ('U', 194, struct usb_fs_complete)
#define	USB_FS_INIT		_IOW ('U', 195, struct usb_fs_init)
#define	USB_FS_UNINIT		_IOW ('U', 196, struct usb_fs_uninit)
#define	USB_FS_OPEN		_IOWR('U', 197, struct usb_fs_open)
#define	USB_FS_CLOSE		_IOW ('U', 198, struct usb_fs_close)
#define	USB_FS_CLEAR_STALL_SYNC _IOW ('U', 199, struct usb_fs_clear_stall_sync)

/* USB quirk system interface */
#define	USB_DEV_QUIRK_GET	_IOWR('Q', 0, struct usb_gen_quirk)
#define	USB_QUIRK_NAME_GET	_IOWR('Q', 1, struct usb_gen_quirk)
#define	USB_DEV_QUIRK_ADD	_IOW ('Q', 2, struct usb_gen_quirk)
#define	USB_DEV_QUIRK_REMOVE	_IOW ('Q', 3, struct usb_gen_quirk)

#endif					/* _USB_IOCTL_H_ */


code:
/* $FreeBSD: release/9.0.0/sys/dev/usb/usb_mbuf.h 196219 2009-08-14 20:03:53Z jhb $ */
/*-
 * Copyright (c) 2008 Hans Petter Selasky. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 */

#ifndef _USB_MBUF_H_
#define	_USB_MBUF_H_

/*
 * The following structure defines a minimum re-implementation of the
 * mbuf system in the kernel.
 */
struct usb_mbuf {
	uint8_t *cur_data_ptr;
	uint8_t *min_data_ptr;
	struct usb_mbuf *usb_nextpkt;
	struct usb_mbuf *usb_next;

	usb_size_t cur_data_len;
	usb_size_t max_data_len;
	uint8_t last_packet:1;
	uint8_t unused:7;
};

#define	USB_IF_ENQUEUE(ifq, m) do {		\
    (m)->usb_nextpkt = NULL;			\
    if ((ifq)->ifq_tail == NULL)		\
        (ifq)->ifq_head = (m);			\
    else					\
        (ifq)->ifq_tail->usb_nextpkt = (m);	\
    (ifq)->ifq_tail = (m);			\
    (ifq)->ifq_len++;				\
  } while (0)

#define	USB_IF_DEQUEUE(ifq, m) do {				\
    (m) = (ifq)->ifq_head;					\
    if (m) {							\
        if (((ifq)->ifq_head = (m)->usb_nextpkt) == NULL) {	\
	     (ifq)->ifq_tail = NULL;				\
	}							\
	(m)->usb_nextpkt = NULL;				\
	(ifq)->ifq_len--;					\
    }								\
  } while (0)

#define	USB_IF_PREPEND(ifq, m) do {		\
      (m)->usb_nextpkt = (ifq)->ifq_head;	\
      if ((ifq)->ifq_tail == NULL) {		\
	  (ifq)->ifq_tail = (m);		\
      }						\
      (ifq)->ifq_head = (m);			\
      (ifq)->ifq_len++;				\
  } while (0)

#define	USB_IF_QFULL(ifq)   ((ifq)->ifq_len >= (ifq)->ifq_maxlen)
#define	USB_IF_QLEN(ifq)    ((ifq)->ifq_len)
#define	USB_IF_POLL(ifq, m) ((m) = (ifq)->ifq_head)

#define	USB_MBUF_RESET(m) do {			\
    (m)->cur_data_ptr = (m)->min_data_ptr;	\
    (m)->cur_data_len = (m)->max_data_len;	\
    (m)->last_packet = 0;			\
  } while (0)

/* prototypes */
void   *usb_alloc_mbufs(struct malloc_type *type, struct usb_ifqueue *ifq,
	    usb_size_t block_size, uint16_t nblocks);

#endif					/* _USB_MBUF_H_ */


code:
/* $FreeBSD: release/9.0.0/sys/dev/usb/usb_msctest.h 225350 2011-09-02 18:50:44Z hselasky $ */
/*-
 * Copyright (c) 2008 Hans Petter Selasky. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 */

#ifndef _USB_MSCTEST_H_
#define	_USB_MSCTEST_H_

enum {
	MSC_EJECT_STOPUNIT,
	MSC_EJECT_REZERO,
	MSC_EJECT_ZTESTOR,
	MSC_EJECT_CMOTECH,
	MSC_EJECT_HUAWEI,
	MSC_EJECT_TCT,
};

int usb_iface_is_cdrom(struct usb_device *udev,
	    uint8_t iface_index);
usb_error_t usb_msc_eject(struct usb_device *udev,
	    uint8_t iface_index, int method);
usb_error_t usb_msc_auto_quirk(struct usb_device *udev,
	    uint8_t iface_index);

#endif					/* _USB_MSCTEST_H_ */


code:
/* $FreeBSD: release/9.0.0/sys/dev/usb/usb_pci.h 196219 2009-08-14 20:03:53Z jhb $ */
/*-
 * Copyright (c) 2008 Hans Petter Selasky. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 */

#ifndef _USB_PCI_H_
#define	_USB_PCI_H_

/*
 * We don't want the following files included everywhere, that's why
 * they are in a separate file.
 */
#include <dev/pci/pcireg.h>
#include <dev/pci/pcivar.h>

#include <sys/rman.h>

#endif					/* _USB_PCI_H_ */


code:
/*-
 * Copyright (c) 1990, 1991, 1993
 *	The Regents of the University of California.  All rights reserved.
 *
 * This code is derived from the Stanford/CMU enet packet filter,
 * (net/enet.c) distributed as part of 4.3BSD, and code contributed
 * to Berkeley by Steven McCanne and Van Jacobson both of Lawrence
 * Berkeley Laboratory.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 * 4. Neither the name of the University nor the names of its contributors
 *    may be used to endorse or promote products derived from this software
 *    without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 *
 * $FreeBSD: release/9.0.0/sys/dev/usb/usb_pf.h 220301 2011-04-03 20:03:45Z hselasky $
 */

#ifndef _DEV_USB_PF_H
#define	_DEV_USB_PF_H

struct usbpf_pkthdr {
	uint32_t	up_totlen;	/* Total length including all headers */
	uint32_t	up_busunit;	/* Host controller unit number */
	uint8_t		up_address;	/* USB device index */
	uint8_t		up_mode;	/* Mode of transfer */
#define	USBPF_MODE_HOST		0
#define	USBPF_MODE_DEVICE	1
	uint8_t		up_type;	/* points SUBMIT / DONE */
	uint8_t		up_xfertype;	/* Transfer type, see USB2.0 spec. */
	uint32_t	up_flags;	/* Transfer flags */
#define	USBPF_FLAG_FORCE_SHORT_XFER	(1 << 0)
#define	USBPF_FLAG_SHORT_XFER_OK	(1 << 1)
#define	USBPF_FLAG_SHORT_FRAMES_OK	(1 << 2)
#define	USBPF_FLAG_PIPE_BOF		(1 << 3)
#define	USBPF_FLAG_PROXY_BUFFER		(1 << 4)
#define	USBPF_FLAG_EXT_BUFFER		(1 << 5)
#define	USBPF_FLAG_MANUAL_STATUS	(1 << 6)
#define	USBPF_FLAG_NO_PIPE_OK		(1 << 7)
#define	USBPF_FLAG_STALL_PIPE		(1 << 8)
	uint32_t	up_status;	/* Transfer status */
#define	USBPF_STATUS_OPEN		(1 << 0)
#define	USBPF_STATUS_TRANSFERRING	(1 << 1)
#define	USBPF_STATUS_DID_DMA_DELAY	(1 << 2)
#define	USBPF_STATUS_DID_CLOSE		(1 << 3)
#define	USBPF_STATUS_DRAINING		(1 << 4)
#define	USBPF_STATUS_STARTED		(1 << 5)
#define	USBPF_STATUS_BW_RECLAIMED	(1 << 6)
#define	USBPF_STATUS_CONTROL_XFR	(1 << 7)
#define	USBPF_STATUS_CONTROL_HDR	(1 << 8)
#define	USBPF_STATUS_CONTROL_ACT	(1 << 9)
#define	USBPF_STATUS_CONTROL_STALL	(1 << 10)
#define	USBPF_STATUS_SHORT_FRAMES_OK	(1 << 11)
#define	USBPF_STATUS_SHORT_XFER_OK	(1 << 12)
#define	USBPF_STATUS_BDMA_ENABLE	(1 << 13)
#define	USBPF_STATUS_BDMA_NO_POST_SYNC	(1 << 14)
#define	USBPF_STATUS_BDMA_SETUP		(1 << 15)
#define	USBPF_STATUS_ISOCHRONOUS_XFR	(1 << 16)
#define	USBPF_STATUS_CURR_DMA_SET	(1 << 17)
#define	USBPF_STATUS_CAN_CANCEL_IMMED	(1 << 18)
#define	USBPF_STATUS_DOING_CALLBACK	(1 << 19)
	uint32_t	up_error;	/* USB error, see USB_ERR_XXX */
	uint32_t	up_interval;	/* For interrupt and isoc (ms) */
	uint32_t	up_frames;	/* Number of following frames */
	uint32_t	up_packet_size;	/* Packet size used */
	uint32_t	up_packet_count;	/* Packet count used */
	uint32_t	up_endpoint;	/* USB endpoint / stream ID */
	uint8_t		up_speed;	/* USB speed, see USB_SPEED_XXX */
	/* sizeof(struct usbpf_pkthdr) == 128 bytes */
	uint8_t		up_reserved[83];
};

struct usbpf_framehdr {
	/*
	 * The frame length field excludes length of frame header and
	 * any alignment.
	 */
	uint32_t length;
#define	USBPF_FRAME_ALIGN(x)		(((x) + 3) & ~3)
	uint32_t flags;
#define	USBPF_FRAMEFLAG_READ		(1 << 0)
#define	USBPF_FRAMEFLAG_DATA_FOLLOWS	(1 << 1)
};

#define	USBPF_HDR_LEN		128	/* bytes */
#define	USBPF_FRAME_HDR_LEN	8	/* bytes */

extern uint8_t usbpf_pkthdr_size_ok[
    (sizeof(struct usbpf_pkthdr) == USBPF_HDR_LEN) ? 1 : -1];
extern uint8_t usbpf_framehdr_size_ok[
    (sizeof(struct usbpf_framehdr) == USBPF_FRAME_HDR_LEN) ? 1 : -1];

#define	USBPF_XFERTAP_SUBMIT	0
#define	USBPF_XFERTAP_DONE	1

#ifdef _KERNEL
void	usbpf_attach(struct usb_bus *);
void	usbpf_detach(struct usb_bus *);
void	usbpf_xfertap(struct usb_xfer *, int);
#endif

#endif


code:
/* $FreeBSD: release/9.0.0/sys/dev/usb/usb_process.h 217350 2011-01-13 14:15:36Z jhb $ */
/*-
 * Copyright (c) 2008 Hans Petter Selasky. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 */

#ifndef _USB_PROCESS_H_
#define	_USB_PROCESS_H_

#include <sys/interrupt.h>
#include <sys/priority.h>
#include <sys/runq.h>

/* defines */
#define	USB_PRI_HIGH	PI_SWI(SWI_NET)
#define	USB_PRI_MED	PI_SWI(SWI_CAMBIO)

#define	USB_PROC_WAIT_TIMEOUT 2
#define	USB_PROC_WAIT_DRAIN   1
#define	USB_PROC_WAIT_NORMAL  0

/* structure prototypes */

struct usb_proc_msg;

/*
 * The following structure defines the USB process.
 */
struct usb_process {
	TAILQ_HEAD(, usb_proc_msg) up_qhead;
	struct cv up_cv;
	struct cv up_drain;

#if (__FreeBSD_version >= 800000)
	struct thread *up_ptr;
#else
	struct proc *up_ptr;
#endif
	struct thread *up_curtd;
	struct mtx *up_mtx;

	usb_size_t up_msg_num;

	uint8_t	up_prio;
	uint8_t	up_gone;
	uint8_t	up_msleep;
	uint8_t	up_csleep;
	uint8_t	up_dsleep;
};

/* prototypes */

uint8_t	usb_proc_is_gone(struct usb_process *up);
int	usb_proc_create(struct usb_process *up, struct mtx *p_mtx,
	    const char *pmesg, uint8_t prio);
void	usb_proc_drain(struct usb_process *up);
void	usb_proc_mwait(struct usb_process *up, void *pm0, void *pm1);
void	usb_proc_free(struct usb_process *up);
void   *usb_proc_msignal(struct usb_process *up, void *pm0, void *pm1);
void	usb_proc_rewakeup(struct usb_process *up);

#endif					/* _USB_PROCESS_H_ */


code:
/* $FreeBSD: release/9.0.0/sys/dev/usb/usb_request.h 222786 2011-06-06 21:45:09Z hselasky $ */
/*-
 * Copyright (c) 2008 Hans Petter Selasky. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 */

#ifndef _USB_REQUEST_H_
#define	_USB_REQUEST_H_

struct usb_process;

usb_error_t usbd_req_clear_hub_feature(struct usb_device *udev,
		    struct mtx *mtx, uint16_t sel);
usb_error_t usbd_req_clear_port_feature(struct usb_device *udev,
		    struct mtx *mtx, uint8_t port, uint16_t sel);
usb_error_t usbd_req_get_alt_interface_no(struct usb_device *udev,
		    struct mtx *mtx, uint8_t *alt_iface_no,
		    uint8_t iface_index);
usb_error_t usbd_req_get_config(struct usb_device *udev, struct mtx *mtx,
		    uint8_t *pconf);
usb_error_t usbd_req_get_descriptor_ptr(struct usb_device *udev,
		    struct usb_config_descriptor **ppcd, uint16_t wValue);
usb_error_t usbd_req_get_config_desc(struct usb_device *udev, struct mtx *mtx,
		    struct usb_config_descriptor *d, uint8_t conf_index);
usb_error_t usbd_req_get_config_desc_full(struct usb_device *udev,
		    struct mtx *mtx, struct usb_config_descriptor **ppcd,
		    struct malloc_type *mtype, uint8_t conf_index);
usb_error_t usbd_req_get_desc(struct usb_device *udev, struct mtx *mtx,
		    uint16_t *actlen, void *desc, uint16_t min_len,
		    uint16_t max_len, uint16_t id, uint8_t type,
		    uint8_t index, uint8_t retries);
usb_error_t usbd_req_get_device_desc(struct usb_device *udev, struct mtx *mtx,
		    struct usb_device_descriptor *d);
usb_error_t usbd_req_get_device_status(struct usb_device *udev,
		    struct mtx *mtx, struct usb_status *st);
usb_error_t usbd_req_get_hub_descriptor(struct usb_device *udev,
		    struct mtx *mtx, struct usb_hub_descriptor *hd,
		    uint8_t nports);
usb_error_t usbd_req_get_ss_hub_descriptor(struct usb_device *udev,
		    struct mtx *mtx, struct usb_hub_ss_descriptor *hd,
		    uint8_t nports);
usb_error_t usbd_req_get_hub_status(struct usb_device *udev, struct mtx *mtx,
		    struct usb_hub_status *st);
usb_error_t usbd_req_get_port_status(struct usb_device *udev, struct mtx *mtx,
		    struct usb_port_status *ps, uint8_t port);
usb_error_t usbd_req_reset_port(struct usb_device *udev, struct mtx *mtx,
		    uint8_t port);
usb_error_t usbd_req_warm_reset_port(struct usb_device *udev,
		    struct mtx *mtx, uint8_t port);
usb_error_t usbd_req_set_address(struct usb_device *udev, struct mtx *mtx,
		    uint16_t addr);
usb_error_t usbd_req_set_hub_feature(struct usb_device *udev, struct mtx *mtx,
		    uint16_t sel);
usb_error_t usbd_req_set_port_feature(struct usb_device *udev,
		    struct mtx *mtx, uint8_t port, uint16_t sel);
usb_error_t usbd_setup_device_desc(struct usb_device *udev, struct mtx *mtx);
usb_error_t usbd_req_re_enumerate(struct usb_device *udev, struct mtx *mtx);
usb_error_t usbd_req_clear_device_feature(struct usb_device *udev,
		    struct mtx *mtx, uint16_t sel);
usb_error_t usbd_req_set_device_feature(struct usb_device *udev,
		    struct mtx *mtx, uint16_t sel);
usb_error_t usbd_req_set_hub_u1_timeout(struct usb_device *udev,
		    struct mtx *mtx, uint8_t port, uint8_t timeout);
usb_error_t usbd_req_set_hub_u2_timeout(struct usb_device *udev,
		    struct mtx *mtx, uint8_t port, uint8_t timeout);
usb_error_t usbd_req_set_hub_depth(struct usb_device *udev,
		    struct mtx *mtx, uint16_t depth);
usb_error_t usbd_req_reset_tt(struct usb_device *udev, struct mtx *mtx,
		    uint8_t port);
usb_error_t usbd_req_clear_tt_buffer(struct usb_device *udev, struct mtx *mtx,
		    uint8_t port, uint8_t addr, uint8_t type, uint8_t endpoint);

#endif					/* _USB_REQUEST_H_ */


code:
/* $FreeBSD: release/9.0.0/sys/dev/usb/usb_transfer.h 213435 2010-10-04 23:18:05Z hselasky $ */
/*-
 * Copyright (c) 2008 Hans Petter Selasky. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 */

#ifndef _USB_TRANSFER_H_
#define	_USB_TRANSFER_H_

/*
 * The following structure defines the messages that is used to signal
 * the "done_p" USB process.
 */
struct usb_done_msg {
	struct usb_proc_msg hdr;
	struct usb_xfer_root *xroot;
};

#define	USB_DMATAG_TO_XROOT(dpt)				\
  ((struct usb_xfer_root *)(					\
   ((uint8_t *)(dpt)) -						\
   ((uint8_t *)&((struct usb_xfer_root *)0)->dma_parent_tag)))

/*
 * The following structure is used to keep information about memory
 * that should be automatically freed at the moment all USB transfers
 * have been freed.
 */
struct usb_xfer_root {
	struct usb_dma_parent_tag dma_parent_tag;
#if USB_HAVE_BUSDMA
	struct usb_xfer_queue dma_q;
#endif
	struct usb_xfer_queue done_q;
	struct usb_done_msg done_m[2];
	struct cv cv_drain;

	struct usb_process *done_p;	/* pointer to callback process */
	void   *memory_base;
	struct mtx *xfer_mtx;	/* cannot be changed during operation */
#if USB_HAVE_BUSDMA
	struct usb_page_cache *dma_page_cache_start;
	struct usb_page_cache *dma_page_cache_end;
#endif
	struct usb_page_cache *xfer_page_cache_start;
	struct usb_page_cache *xfer_page_cache_end;
	struct usb_bus *bus;		/* pointer to USB bus (cached) */
	struct usb_device *udev;	/* pointer to USB device */

	usb_size_t memory_size;
	usb_size_t setup_refcount;
#if USB_HAVE_BUSDMA
	usb_frcount_t dma_nframes;	/* number of page caches to load */
	usb_frcount_t dma_currframe;	/* currect page cache number */
	usb_frlength_t dma_frlength_0;	/* length of page cache zero */
	uint8_t	dma_error;		/* set if virtual memory could not be
					 * loaded */
#endif
	uint8_t	done_sleep;		/* set if done thread is sleeping */
};

/*
 * The following structure is used when setting up an array of USB
 * transfers.
 */
struct usb_setup_params {
	struct usb_dma_tag *dma_tag_p;
	struct usb_page *dma_page_ptr;
	struct usb_page_cache *dma_page_cache_ptr;	/* these will be
							 * auto-freed */
	struct usb_page_cache *xfer_page_cache_ptr;	/* these will not be
							 * auto-freed */
	struct usb_device *udev;
	struct usb_xfer *curr_xfer;
	const struct usb_config *curr_setup;
	const struct usb_pipe_methods *methods;
	void   *buf;
	usb_frlength_t *xfer_length_ptr;

	usb_size_t size[7];
	usb_frlength_t bufsize;
	usb_frlength_t bufsize_max;

	uint32_t hc_max_frame_size;
	uint16_t hc_max_packet_size;
	uint8_t	hc_max_packet_count;
	enum usb_dev_speed speed;
	uint8_t	dma_tag_max;
	usb_error_t err;
};

/* function prototypes */

uint8_t	usbd_transfer_setup_sub_malloc(struct usb_setup_params *parm,
	    struct usb_page_cache **ppc, usb_size_t size, usb_size_t align,
	    usb_size_t count);
void	usb_dma_delay_done_cb(struct usb_xfer *);
void	usb_command_wrapper(struct usb_xfer_queue *pq,
	    struct usb_xfer *xfer);
void	usbd_pipe_enter(struct usb_xfer *xfer);
void	usbd_pipe_start(struct usb_xfer_queue *pq);
void	usbd_transfer_dequeue(struct usb_xfer *xfer);
void	usbd_transfer_done(struct usb_xfer *xfer, usb_error_t error);
void	usbd_transfer_enqueue(struct usb_xfer_queue *pq,
	    struct usb_xfer *xfer);
void	usbd_transfer_setup_sub(struct usb_setup_params *parm);
void	usbd_ctrl_transfer_setup(struct usb_device *udev);
void	usbd_clear_stall_locked(struct usb_device *udev,
	    struct usb_endpoint *ep);
void	usbd_clear_data_toggle(struct usb_device *udev,
	    struct usb_endpoint *ep);
usb_callback_t usbd_do_request_callback;
usb_callback_t usb_handle_request_callback;
usb_callback_t usb_do_clear_stall_callback;
void	usbd_transfer_timeout_ms(struct usb_xfer *xfer,
	    void (*cb) (void *arg), usb_timeout_t ms);
usb_timeout_t usbd_get_dma_delay(struct usb_device *udev);
void	usbd_transfer_power_ref(struct usb_xfer *xfer, int val);

#endif					/* _USB_TRANSFER_H_ */


code:
/* $FreeBSD: release/9.0.0/sys/dev/usb/usb_util.h 196219 2009-08-14 20:03:53Z jhb $ */
/*-
 * Copyright (c) 2008 Hans Petter Selasky. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 */

#ifndef _USB_UTIL_H_
#define	_USB_UTIL_H_

int	device_delete_all_children(device_t dev);
uint8_t	usb_make_str_desc(void *ptr, uint16_t max_len, const char *s);
void	usb_printbcd(char *p, uint16_t p_len, uint16_t bcd);
void	usb_trim_spaces(char *p);

#endif					/* _USB_UTIL_H_ */