code:
/*-
 * Copyright (c) 1990 The Regents of the University of California.
 * All rights reserved.
 *
 * This code is derived from software contributed to Berkeley by
 * William Jolitz.
 *
 * Copyright (c) 1997, 1999 Nicolas Souchu
 * 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.
 *
 * Distantly from :
 *	@(#)lptreg.h      1.1 (Berkeley) 12/19/90
 *	Id: lptreg.h,v 1.6 1997/02/22 09:36:52 peter Exp
 *	From Id: nlpt.h,v 1.3 1999/01/10 12:04:54 nsouch Exp
 *
 * $FreeBSD: release/9.0.0/sys/dev/ppbus/lpt.h 185003 2008-11-16 17:42:02Z jhb $
 */

/*
 * AT Parallel Port (for lineprinter)
 * Interface port and bit definitions
 * Written by William Jolitz 12/18/90
 * Copyright (C) William Jolitz 1990
 */

#ifndef __LPT_H
#define	__LPT_H

/* machine independent definitions, it shall only depend on the ppbus
 * parallel port model */

					/* PIN */
#define	LPS_NERR		0x08	/* 15  printer no error */
#define	LPS_SEL			0x10	/* 13  printer selected */
#define	LPS_OUT			0x20	/* 12  printer out of paper */
#define	LPS_NACK		0x40	/* 10  printer no ack of data */
#define	LPS_NBSY		0x80	/* 11  printer busy */

#define	LPC_STB			0x01	/*  1  strobe data to printer */
#define	LPC_AUTOL		0x02	/* 14  automatic linefeed */
#define	LPC_NINIT		0x04	/* 16  initialize printer */
#define	LPC_SEL			0x08	/* 17  printer selected */
#define	LPC_ENA			0x10	/*  -  enable IRQ */

#endif


code:
/*-
 *  Copyright (C) 1994 Geoffrey M. Rehmet
 *
 *  This program is free software; you may redistribute it and/or
 *  modify it, provided that it retain the above copyright notice
 *  and the following disclaimer.
 *
 *  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.
 *
 *	Geoff Rehmet, Rhodes University, South Africa <csgr@cs.ru.ac.za>
 *
 * $FreeBSD: release/9.0.0/sys/dev/ppbus/lptio.h 139749 2005-01-06 01:43:34Z imp $
 */

#ifndef	_DEV_PPBUS_LPT_H_
#define	_DEV_PPBUS_LPT_H_

#include <sys/ioccom.h>

#define	LPT_IRQ		_IOW('p', 1, long)	/* set interrupt status */

#endif /* !_DEV_PPBUS_LPT_H_ */

repo_name: veiledmerc/mira

license: mit


code:
/*-
 * Copyright (c) 1997 Nicolas Souchu
 * 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.
 *
 * $FreeBSD: release/9.0.0/sys/dev/ppbus/ppb_1284.h 55957 2000-01-14 08:03:15Z nsouch $
 *
 */
#ifndef __1284_H
#define __1284_H

/*
 * IEEE1284 signals
 */

/* host driven signals */

#define nHostClk	STROBE
#define Write		STROBE

#define nHostBusy	AUTOFEED
#define nHostAck	AUTOFEED
#define DStrb		AUTOFEED

#define nReveseRequest	nINIT

#define nActive1284	SELECTIN
#define AStrb		SELECTIN

/* peripheral driven signals */

#define nDataAvail	nFAULT
#define nPeriphRequest	nFAULT

#define Xflag		SELECT

#define AckDataReq	PERROR
#define nAckReverse	PERROR

#define nPtrBusy	nBUSY
#define nPeriphAck	nBUSY
#define Wait		nBUSY

#define PtrClk		nACK
#define PeriphClk	nACK
#define Intr		nACK

/* request mode values */
#define NIBBLE_1284_NORMAL	0x0
#define NIBBLE_1284_REQUEST_ID	0x4
#define BYTE_1284_NORMAL	0x1
#define BYTE_1284_REQUEST_ID	0x5
#define ECP_1284_NORMAL		0x10
#define ECP_1284_REQUEST_ID	0x14
#define ECP_1284_RLE		0x30
#define ECP_1284_RLE_REQUEST_ID	0x34
#define EPP_1284_NORMAL		0x40
#define EXT_LINK_1284_NORMAL	0x80

/* ieee1284 mode options */
#define PPB_REQUEST_ID		0x1
#define PPB_USE_RLE		0x2
#define PPB_EXTENSIBILITY_LINK	0x4

/* ieee1284 errors */
#define PPB_NO_ERROR		0
#define PPB_MODE_UNSUPPORTED	1	/* mode not supported by peripheral */
#define PPB_NOT_IEEE1284	2	/* not an IEEE1284 compliant periph. */
#define PPB_TIMEOUT		3	/* timeout */
#define PPB_INVALID_MODE	4	/* current mode is incorrect */

/* ieee1284 host side states */
#define PPB_ERROR			0
#define PPB_FORWARD_IDLE		1
#define PPB_NEGOCIATION			2
#define PPB_SETUP			3
#define PPB_ECP_FORWARD_IDLE		4
#define PPB_FWD_TO_REVERSE		5
#define PPB_REVERSE_IDLE		6
#define PPB_REVERSE_TRANSFER		7
#define PPB_REVERSE_TO_FWD		8
#define PPB_EPP_IDLE			9
#define PPB_TERMINATION			10

/* peripheral side states */
#define PPB_PERIPHERAL_NEGOCIATION	11
#define PPB_PERIPHERAL_IDLE		12
#define PPB_PERIPHERAL_TRANSFER		13
#define PPB_PERIPHERAL_TERMINATION	14

extern int nibble_1284_inbyte(device_t, char *);
extern int byte_1284_inbyte(device_t, char *);
extern int spp_1284_read(device_t, int, char *, int, int *);

extern int ppb_1284_negociate(device_t, int, int);
extern int ppb_1284_terminate(device_t);
extern int ppb_1284_read_id(device_t, int, char *, int, int *);
extern int ppb_1284_read(device_t, int, char *, int, int *);
extern int ppb_1284_get_state(device_t bus);
extern int ppb_1284_set_state(device_t bus, int state);

extern int ppb_peripheral_terminate(device_t, int);
extern int ppb_peripheral_negociate(device_t, int, int);
extern int byte_peripheral_write(device_t, char *, int, int *);

#endif


code:
/*-
 * Copyright (c) 1998 Nicolas Souchu
 * 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.
 *
 * $FreeBSD: release/9.0.0/sys/dev/ppbus/ppb_msq.h 106696 2002-11-09 12:55:07Z alfred $
 *
 */
#ifndef __PPB_MSQ_H
#define __PPB_MSQ_H

/*
 * Basic definitions
 */

/* microsequence parameter descriptor */
#define MS_INS_MASK	0x00ff	/* mask to retrieve the instruction position < 256	XXX */
#define MS_ARG_MASK	0x0f00	/* mask to retrieve the argument number */
#define MS_TYP_MASK	0xf000	/* mask to retrieve the type of the param */

/* offset of each mask (see above) */
#define MS_INS_OFFSET	0
#define MS_ARG_OFFSET	8
#define MS_TYP_OFFSET	12

/* list of parameter types */
#define MS_TYP_INT	0x0	/* integer */
#define MS_TYP_CHA	0x1	/* character */
#define MS_TYP_PTR	0x2	/* void pointer */
#define MS_TYP_FUN	0x3	/* function pointer */

#define MS_PARAM(ins,arg,typ) \
	(((ins<<MS_INS_OFFSET) & MS_INS_MASK) | \
	 ((arg<<MS_ARG_OFFSET) & MS_ARG_MASK) | \
	 ((typ<<MS_TYP_OFFSET) & MS_TYP_MASK))

#define MS_INS(param) ((param & MS_INS_MASK) >> MS_INS_OFFSET)
#define MS_ARG(param) ((param & MS_ARG_MASK) >> MS_ARG_OFFSET)
#define MS_TYP(param) ((param & MS_TYP_MASK) >> MS_TYP_OFFSET)

/* microsequence opcodes - do not change! */
#define MS_OP_GET       0	/* get <ptr>, <len>			*/
#define MS_OP_PUT       1	/* put <ptr>, <len>			*/

#define MS_OP_RFETCH	2	/* rfetch <reg>, <mask>, <ptr>		*/
#define MS_OP_RSET	3	/* rset <reg>, <mask>, <mask>		*/
#define MS_OP_RASSERT	4	/* rassert <reg>, <mask>		*/
#define MS_OP_DELAY     5	/* delay <val>				*/
#define MS_OP_SET       6	/* set <val>				*/
#define MS_OP_DBRA      7	/* dbra <offset>			*/
#define MS_OP_BRSET     8	/* brset <mask>, <offset>		*/
#define MS_OP_BRCLEAR   9	/* brclear <mask>, <offset>		*/
#define MS_OP_RET       10	/* ret <retcode>			*/
#define MS_OP_C_CALL	11	/* c_call <function>, <parameter>	*/
#define MS_OP_PTR	12	/* ptr <pointer>			*/
#define MS_OP_ADELAY	13	/* adelay <val>				*/
#define MS_OP_BRSTAT	14	/* brstat <mask>, <mask>, <offset>	*/
#define MS_OP_SUBRET	15	/* subret <code>			*/
#define MS_OP_CALL	16	/* call <microsequence>			*/
#define MS_OP_RASSERT_P	17	/* rassert_p <iter>, <reg>		*/
#define MS_OP_RFETCH_P	18	/* rfetch_p <iter>, <reg>, <mask>	*/
#define MS_OP_TRIG	19	/* trigger <reg>, <len>, <array>	*/

/* common masks */
#define MS_CLEAR_ALL	0x0
#define MS_ASSERT_NONE	0x0
#define MS_ASSERT_ALL	0xff
#define MS_FETCH_ALL	0xff

/* undefined parameter value */
#define MS_NULL		0
#define MS_UNKNOWN	MS_NULL

/* predifined parameters */
#define MS_ACCUM	-1	/* use accum previously set by MS_OP_SET */

/* these are register numbers according to our PC-like parallel port model */
#define MS_REG_DTR	0x0
#define MS_REG_STR	0x1
#define MS_REG_CTR	0x2
#define MS_REG_EPP_A	0x3
#define MS_REG_EPP_D	0x4

/*
 * Microsequence macro abstraction level
 */

/* register operations */
#define MS_RSET(reg,assert,clear) { MS_OP_RSET, {{ (reg) }, { (assert) }, { (clear) }}}
#define MS_RASSERT(reg,byte)	  { MS_OP_RASSERT, { { (reg) }, { (byte) }}}
#define MS_RCLR(reg,clear)	  { MS_OP_RSET, {{ (reg) }, { MS_ASSERT_NONE }, { (clear) }}}

#define MS_RFETCH(reg,mask,ptr) { MS_OP_RFETCH, {{ (reg) }, { (mask) }, { (ptr) }}}

/* trigger the port with array[char, delay,...] */
#define MS_TRIG(reg,len,array)	{ MS_OP_TRIG, {{ (reg) }, { (len) }, { (array) }}}

/* assert/fetch from/to ptr */
#define MS_RASSERT_P(n,reg)	  { MS_OP_RASSERT_P, {{ (n) }, { (reg) }}}
#define MS_RFETCH_P(n,reg,mask)	  { MS_OP_RFETCH_P, {{ (n) }, { (reg) }, { (mask) }}}

/* ptr manipulation */
#define MS_PTR(ptr)	{ MS_OP_PTR, {{ (ptr) }}}

#define MS_DASS(byte) MS_RASSERT(MS_REG_DTR,byte)
#define MS_SASS(byte) MS_RASSERT(MS_REG_STR,byte)
#define MS_CASS(byte) MS_RASSERT(MS_REG_CTR,byte)

#define MS_SET(accum)		{ MS_OP_SET, {{ (accum) }}}
#define MS_BRSET(mask,offset)	{ MS_OP_BRSET, {{ (mask) }, { (offset) }}}
#define MS_DBRA(offset)		{ MS_OP_DBRA, {{ (offset) }}}
#define MS_BRCLEAR(mask,offset)	{ MS_OP_BRCLEAR, {{ (mask) }, { (offset) }}}
#define MS_BRSTAT(mask_set,mask_clr,offset) \
		{ MS_OP_BRSTAT, {{ mask_set }, { mask_clr }, { (offset) }}}

/* C function or submicrosequence call */
#define MS_C_CALL(function,parameter) \
		{ MS_OP_C_CALL, {{ (function) }, { (parameter) }}}
#define MS_CALL(microseq) { MS_OP_CALL, {{ (microseq) }}}

/* mode dependent read/write operations
 * ppb_MS_xxx_init() call required otherwise default is
 * IEEE1284 operating mode */
#define MS_PUT(ptr,len) { MS_OP_PUT, {{ (ptr) }, { (len) }}}
#define MS_GET(ptr,len) { MS_OP_GET, {{ (ptr) }, { (len) }}}

/* delay in microseconds */
#define MS_DELAY(udelay) { MS_OP_DELAY, {{ (udelay) }}}

/* asynchroneous delay in ms */
#define MS_ADELAY(mdelay) { MS_OP_ADELAY, {{ (mdelay) }}}

/* return from submicrosequence execution or microseqence execution */
#define MS_SUBRET(code)	{ MS_OP_SUBRET,	{{ (code) }}}
#define MS_RET(code)	{ MS_OP_RET, {{ (code) }}}

/*
 * Function abstraction level
 */

#define ppb_MS_GET_init(bus,dev,body) ppb_MS_init(bus, dev, body, MS_OP_GET)

#define ppb_MS_PUT_init(bus,dev,body) ppb_MS_init(bus, dev, body, MS_OP_PUT)

extern int ppb_MS_init(
		device_t,			/* ppbus bus */
		device_t,			/* ppbus device */
		struct ppb_microseq *,		/* loop msq to assign */
		int opcode			/* MS_OP_GET, MS_OP_PUT */
		);

extern int ppb_MS_init_msq(
		struct ppb_microseq *,
		int,				/* number of parameters */
		...				/* descriptor, value, ... */
		);

extern int ppb_MS_exec(
		device_t,			/* ppbus bus */
		device_t,			/* ppbus device */
		int,				/* microseq opcode */
		union ppb_insarg,		/* param1 */
		union ppb_insarg,		/* param2 */
		union ppb_insarg,		/* param3 */
		int *				/* returned value */
		);

extern int ppb_MS_loop(
		device_t,			/* ppbus bus */
		device_t,			/* ppbus device */
		struct ppb_microseq *,		/* prologue msq of loop */
		struct ppb_microseq *,		/* body msq of loop */
		struct ppb_microseq *,		/* epilogue msq of loop */
		int,				/* number of iter */
		int *				/* returned value */
		);

extern int ppb_MS_microseq(
		device_t,			/* ppbus bus */
		device_t,			/* ppbus device */
		struct ppb_microseq *,		/* msq to execute */
		int *				/* returned value */
		);

#endif


code:
/*-
 * Copyright (c) 1997, 1998, 1999 Nicolas Souchu
 * 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.
 *
 * $FreeBSD: release/9.0.0/sys/dev/ppbus/ppbconf.h 188093 2009-02-03 19:49:21Z jhb $
 *
 */
#ifndef __PPBCONF_H
#define __PPBCONF_H

#define n(flags) (~(flags) & (flags))

/*
 * Parallel Port Chipset control bits.
 */
#define STROBE		0x01
#define AUTOFEED	0x02
#define nINIT		0x04
#define SELECTIN	0x08
#define IRQENABLE	0x10
#define PCD		0x20

#define nSTROBE		n(STROBE)
#define nAUTOFEED	n(AUTOFEED)
#define INIT		n(nINIT)
#define nSELECTIN	n(SELECTIN)
#define nPCD		n(PCD)

/*
 * Parallel Port Chipset status bits.
 */
#define TIMEOUT		0x01
#define nFAULT		0x08
#define SELECT		0x10
#define PERROR		0x20
#define nACK		0x40
#define nBUSY		0x80

#ifdef _KERNEL
#include <sys/queue.h>

/*
 * Parallel Port Bus sleep/wakeup queue.
 */
#define PPBPRI	(PZERO+8)

/*
 * Parallel Port Chipset mode masks.
 * NIBBLE mode is supposed to be available under each other modes.
 */
#define PPB_COMPATIBLE	0x0	/* Centronics compatible mode */

#define PPB_NIBBLE	0x1	/* reverse 4 bit mode */
#define PPB_PS2		0x2	/* PS/2 byte mode */
#define PPB_EPP		0x4	/* EPP mode, 32 bit */
#define PPB_ECP		0x8	/* ECP mode */

/* mode aliases */
#define PPB_SPP		PPB_NIBBLE|PPB_PS2
#define PPB_BYTE	PPB_PS2

#define PPB_MASK		0x0f
#define PPB_OPTIONS_MASK	0xf0

#define PPB_IS_EPP(mode) (mode & PPB_EPP)
#define PPB_IN_EPP_MODE(bus) (PPB_IS_EPP (ppb_get_mode (bus)))
#define PPB_IN_NIBBLE_MODE(bus) (ppb_get_mode (bus) & PPB_NIBBLE)
#define PPB_IN_PS2_MODE(bus) (ppb_get_mode (bus) & PPB_PS2)

/*
 * Structure to store status information.
 */
struct ppb_status {
	unsigned char status;

	unsigned int timeout:1;
	unsigned int error:1;
	unsigned int select:1;
	unsigned int paper_end:1;
	unsigned int ack:1;
	unsigned int busy:1;
};

/* Parallel port bus I/O opcodes */
#define PPB_OUTSB_EPP	1
#define PPB_OUTSW_EPP	2
#define PPB_OUTSL_EPP	3
#define PPB_INSB_EPP	4
#define PPB_INSW_EPP	5
#define PPB_INSL_EPP	6
#define PPB_RDTR	7
#define PPB_RSTR	8
#define PPB_RCTR	9
#define PPB_REPP_A	10
#define PPB_REPP_D	11
#define PPB_RECR	12
#define PPB_RFIFO	13
#define PPB_WDTR	14
#define PPB_WSTR	15
#define PPB_WCTR	16
#define PPB_WEPP_A	17
#define PPB_WEPP_D	18
#define PPB_WECR	19
#define PPB_WFIFO	20

/*
 * How tsleep() is called in ppb_request_bus().
 */
#define PPB_DONTWAIT	0
#define PPB_NOINTR	0
#define PPB_WAIT	0x1
#define PPB_INTR	0x2
#define PPB_POLL	0x4
#define PPB_FOREVER	-1

/*
 * Microsequence stuff.
 */
#define PPB_MS_MAXLEN	64		/* XXX according to MS_INS_MASK */
#define PPB_MS_MAXARGS	3		/* according to MS_ARG_MASK */

/* maximum number of mode dependent
 * submicrosequences for in/out operations
 */
#define PPB_MAX_XFER	6

union ppb_insarg {
	int	i;
	void	*p;
	char	*c;
	int	(* f)(void *, char *);
};

struct ppb_microseq {
	int			opcode;			/* microins. opcode */
	union ppb_insarg	arg[PPB_MS_MAXARGS];	/* arguments */
};

/* microseqences used for GET/PUT operations */
struct ppb_xfer {
	struct ppb_microseq *loop;		/* the loop microsequence */
};

/*
 * Parallel Port Bus Device structure.
 */
struct ppb_data;			/* see below */

struct ppb_context {
	int valid;			/* 1 if the struct is valid */
	int mode;			/* XXX chipset operating mode */

	struct microseq *curpc;		/* pc in curmsq */
	struct microseq *curmsq;	/* currently executed microseqence */
};

/*
 * List of IVARS available to ppb device drivers
 */
#define PPBUS_IVAR_MODE 0

/* other fields are reserved to the ppbus internals */

struct ppb_device {

	const char *name;		/* name of the device */

	u_int flags;			/* flags */

	struct ppb_context ctx;		/* context of the device */

					/* mode dependent get msq. If NULL,
					 * IEEE1284 code is used */
	struct ppb_xfer
		get_xfer[PPB_MAX_XFER];

					/* mode dependent put msq. If NULL,
					 * IEEE1284 code is used */
	struct ppb_xfer
		put_xfer[PPB_MAX_XFER];

	driver_intr_t *intr_hook;
	void *intr_arg;
};

/* EPP standards */
#define EPP_1_9		0x0			/* default */
#define EPP_1_7		0x1

/* Parallel Port Chipset IVARS */		/* elsewhere XXX */
#define PPC_IVAR_EPP_PROTO	0
#define PPC_IVAR_LOCK		1
#define PPC_IVAR_INTR_HANDLER	2

/*
 * Maximum size of the PnP info string
 */
#define PPB_PnP_STRING_SIZE	256			/* XXX */

/*
 * Parallel Port Bus structure.
 */
struct ppb_data {

#define PPB_PnP_PRINTER	0
#define PPB_PnP_MODEM	1
#define PPB_PnP_NET	2
#define PPB_PnP_HDC	3
#define PPB_PnP_PCMCIA	4
#define PPB_PnP_MEDIA	5
#define PPB_PnP_FDC	6
#define PPB_PnP_PORTS	7
#define PPB_PnP_SCANNER	8
#define PPB_PnP_DIGICAM	9
#define PPB_PnP_UNKNOWN	10
	int class_id;		/* not a PnP device if class_id < 0 */

	int state;		/* current IEEE1284 state */
	int error;		/* last IEEE1284 error */

	int mode;		/* IEEE 1284-1994 mode
				 * NIBBLE, PS2, EPP or ECP */

	device_t ppb_owner;	/* device which owns the bus */

	struct mtx *ppc_lock;	/* lock of parent device */
	struct resource *ppc_irq_res;
};

struct callout;

typedef int (*ppc_intr_handler)(void *);

extern int ppb_attach_device(device_t);
extern int ppb_request_bus(device_t, device_t, int);
extern int ppb_release_bus(device_t, device_t);

/* bus related functions */
extern void ppb_lock(device_t);
extern void ppb_unlock(device_t);
extern void _ppb_assert_locked(device_t, const char *, int);
extern void ppb_init_callout(device_t, struct callout *, int);
extern int ppb_sleep(device_t, void *, int, const char *, int);
extern int ppb_get_status(device_t, struct ppb_status *);
extern int ppb_poll_bus(device_t, int, char, char, int);
extern int ppb_reset_epp_timeout(device_t);
extern int ppb_ecp_sync(device_t);
extern int ppb_get_epp_protocol(device_t);
extern int ppb_set_mode(device_t, int);		/* returns old mode */
extern int ppb_get_mode(device_t);		/* returns current mode */
extern int ppb_write(device_t, char *, int, int);

#ifdef INVARIANTS
#define ppb_assert_locked(dev)	_ppb_assert_locked(dev, __FILE__, __LINE__)
#else
#define ppb_assert_locked(dev)
#endif
#endif /* _KERNEL */

#endif /* !__PPBCONF_H */


code:
/*-
 * Copyright (c) 1999 Nicolas Souchu
 * 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.
 *
 * $FreeBSD: release/9.0.0/sys/dev/ppbus/ppbio.h 55939 2000-01-14 00:18:06Z nsouch $
 *
 */

#ifndef __PPBIO_H
#define __PPBIO_H

/*
 * Set of ppbus i/o routines callable from ppbus device drivers
 */

#define ppb_outsb_epp(dev,buf,cnt)					    \
		(PPBUS_IO(device_get_parent(dev), PPB_OUTSB_EPP, buf, cnt, 0))
#define ppb_outsw_epp(dev,buf,cnt)					    \
		(PPBUS_IO(device_get_parent(dev), PPB_OUTSW_EPP, buf, cnt, 0))
#define ppb_outsl_epp(dev,buf,cnt)					    \
		(PPBUS_IO(device_get_parent(dev), PPB_OUTSL_EPP, buf, cnt, 0))

#define ppb_insb_epp(dev,buf,cnt)					    \
		(PPBUS_IO(device_get_parent(dev), PPB_INSB_EPP, buf, cnt, 0))
#define ppb_insw_epp(dev,buf,cnt)					    \
		(PPBUS_IO(device_get_parent(dev), PPB_INSW_EPP, buf, cnt, 0))
#define ppb_insl_epp(dev,buf,cnt)					    \
		(PPBUS_IO(device_get_parent(dev), PPB_INSL_EPP, buf, cnt, 0))

#define ppb_repp_A(dev) 						    \
		(PPBUS_IO(device_get_parent(dev), PPB_REPP_A, 0, 0, 0))
#define ppb_repp_D(dev) 						    \
		(PPBUS_IO(device_get_parent(dev), PPB_REPP_D, 0, 0, 0))
#define ppb_recr(dev)						    	    \
		(PPBUS_IO(device_get_parent(dev), PPB_RECR, 0, 0, 0))
#define ppb_rfifo(dev)							    \
		(PPBUS_IO(device_get_parent(dev), PPB_RFIFO, 0, 0, 0))

#define ppb_wepp_A(dev,byte)						    \
		(PPBUS_IO(device_get_parent(dev), PPB_WEPP_A, 0, 0, byte))
#define ppb_wepp_D(dev,byte)						    \
		(PPBUS_IO(device_get_parent(dev), PPB_WEPP_D, 0, 0, byte))
#define ppb_wecr(dev,byte)						    \
		(PPBUS_IO(device_get_parent(dev), PPB_WECR, 0, 0, byte))
#define ppb_wfifo(dev,byte)						    \
		(PPBUS_IO(device_get_parent(dev), PPB_WFIFO, 0, 0, byte))

#define ppb_rdtr(dev)							    \
		(PPBUS_IO(device_get_parent(dev), PPB_RDTR, 0, 0, 0))
#define ppb_rstr(dev)							    \
		(PPBUS_IO(device_get_parent(dev), PPB_RSTR, 0, 0, 0))
#define ppb_rctr(dev)							    \
		(PPBUS_IO(device_get_parent(dev), PPB_RCTR, 0, 0, 0))

#define ppb_wdtr(dev,byte)						    \
		(PPBUS_IO(device_get_parent(dev), PPB_WDTR, 0, 0, byte))
#define ppb_wstr(dev,byte)						    \
		(PPBUS_IO(device_get_parent(dev), PPB_WSTR, 0, 0, byte))
#define ppb_wctr(dev,byte)						    \
		(PPBUS_IO(device_get_parent(dev), PPB_WCTR, 0, 0, byte))

#endif


code:
/*-
 * Copyright (c) 1997 Nicolas Souchu
 * 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.
 *
 * $FreeBSD: release/9.0.0/sys/dev/ppbus/ppi.h 185003 2008-11-16 17:42:02Z jhb $
 *
 */
#ifndef __PPI_H
#define	__PPI_H

#ifndef _KERNEL
# include <sys/types.h>
#endif
#include <sys/ioccom.h>

#define	PPIGDATA	_IOR('P', 10, u_int8_t)
#define	PPIGSTATUS	_IOR('P', 11, u_int8_t)
#define	PPIGCTRL	_IOR('P', 12, u_int8_t)
#define	PPIGEPPD	_IOR('P', 13, u_int8_t)
#define	PPIGECR		_IOR('P', 14, u_int8_t)
#define	PPIGFIFO	_IOR('P', 15, u_int8_t)

#define	PPISDATA	_IOW('P', 16, u_int8_t)
#define	PPISSTATUS	_IOW('P', 17, u_int8_t)
#define	PPISCTRL	_IOW('P', 18, u_int8_t)
#define	PPISEPPD	_IOW('P', 19, u_int8_t)
#define	PPISECR		_IOW('P', 20, u_int8_t)
#define	PPISFIFO	_IOW('P', 21, u_int8_t)

#define	PPIGEPPA	_IOR('P', 22, u_int8_t)
#define	PPISEPPA	_IOR('P', 23, u_int8_t)

#endif


code:
/*-
 * Copyright (c) 1998 Nicolas Souchu
 * 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.
 *
 * $FreeBSD: release/9.0.0/sys/dev/ppbus/vpoio.h 185003 2008-11-16 17:42:02Z jhb $
 *
 */
#ifndef __VP0IO_H
#define __VP0IO_H

/*
 * The ZIP drive cannot act as an initiator.
 */
#define VP0_INITIATOR	0x7

#define VP0_ESELECT_TIMEOUT	1
#define VP0_ECMD_TIMEOUT	2
#define VP0_ECONNECT		3
#define VP0_ESTATUS_TIMEOUT	4
#define VP0_EDATA_OVERFLOW	5
#define VP0_EDISCONNECT		6
#define VP0_EPPDATA_TIMEOUT	7
#define VP0_ENEGOCIATE		8
#define VP0_ENOPORT		9
#define VP0_EINITFAILED		10
#define VP0_EINTR		12

#define VP0_EOTHER		13

#define VP0_OPENNINGS	1

/*
 * Data structure used during microsequence execution
 * when characters are received in nibble mode
 */
struct vpo_nibble {
	char h;			/* most significant nibble */
	char l;			/* less significant nibble */
};

/* Mode found during initialisation */
#define VP0_MODE_UNDEFINED	0x0
#define VP0_MODE_NIBBLE		0x1
#define VP0_MODE_PS2		0x2
#define VP0_MODE_EPP		0x3

struct vpoio_data {
	int vpo_mode_found;		/* Mode found during init */

	struct vpo_nibble vpo_nibble;

	/* each device must have its own nibble inbyte microsequence */
	struct ppb_microseq *vpo_nibble_inbyte_msq;

	device_t vpo_dev;
};

int vpoio_probe(device_t dev, struct vpoio_data *vpo);

int vpoio_attach(struct vpoio_data *vpo);
int vpoio_reset_bus(struct vpoio_data *vpo);

int vpoio_do_scsi(struct vpoio_data *vpo, int host, int target, char *command,
		int clen, char *buffer, int blen, int *result, int *count,
		int *ret);

int imm_probe(device_t dev, struct vpoio_data *vpo);

int imm_attach(struct vpoio_data *vpo);
int imm_reset_bus(struct vpoio_data *vpo);

int imm_do_scsi(struct vpoio_data *vpo, int host, int target, char *command,
		int clen, char *buffer, int blen, int *result, int *count,
		int *ret);

#endif


code:
/*-
 * Copyright (c) 1998 Nicolas Souchu
 * 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.
 *
 * $FreeBSD: release/9.0.0/sys/dev/smbus/smb.h 162234 2006-09-11 20:52:41Z jhb $
 *
 */
#ifndef __SMB_H
#define __SMB_H

#include <sys/ioccom.h>

struct smbcmd {
	char cmd;
	int count;
	u_char slave;
	union {
		char byte;
		short word;

		char *byte_ptr;
		short *word_ptr;

		struct {
			short sdata;
			short *rdata;
		} process;
	} data;
};

/*
 * SMBus spec 2.0 says block transfers may be at most 32 bytes.
 */
#define SMB_MAXBLOCKSIZE	32

#define SMB_QUICK_WRITE	_IOW('i', 1, struct smbcmd)
#define SMB_QUICK_READ	_IOW('i', 2, struct smbcmd)
#define SMB_SENDB	_IOW('i', 3, struct smbcmd)
#define SMB_RECVB	_IOWR('i', 4, struct smbcmd)
#define SMB_WRITEB	_IOW('i', 5, struct smbcmd)
#define SMB_WRITEW	_IOW('i', 6, struct smbcmd)
#define SMB_READB	_IOW('i', 7, struct smbcmd)
#define SMB_READW	_IOW('i', 8, struct smbcmd)
#define SMB_PCALL	_IOW('i', 9, struct smbcmd)
#define SMB_BWRITE	_IOW('i', 10, struct smbcmd)
#define SMB_OLD_BREAD	_IOW('i', 11, struct smbcmd)
#define SMB_BREAD	_IOWR('i', 11, struct smbcmd)

#endif


code:
/*-
 * Copyright (c) 1998 Nicolas Souchu
 * 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.
 *
 * $FreeBSD: release/9.0.0/sys/dev/smbus/smbconf.h 162234 2006-09-11 20:52:41Z jhb $
 */
#ifndef __SMBONF_H
#define __SMBONF_H

#include <sys/queue.h>

#define SMBPRI (PZERO+8)		/* XXX sleep/wakeup queue priority */

#define n(flags) (~(flags) & (flags))

/*
 * How tsleep() is called in smb_request_bus().
 */
#define SMB_DONTWAIT	0
#define SMB_NOINTR	0
#define SMB_WAIT	0x1
#define SMB_INTR	0x2

/*
 * callback index
 */
#define SMB_REQUEST_BUS	0x1
#define SMB_RELEASE_BUS	0x2

/*
 * SMB bus errors
 */
#define SMB_ENOERR	0x0
#define SMB_EBUSERR	0x1
#define SMB_ENOTSUPP	0x2
#define SMB_ENOACK	0x4
#define SMB_ECOLLI	0x8
#define SMB_EABORT	0x10
#define SMB_ETIMEOUT	0x20
#define SMB_EBUSY	0x40
#define	SMB_EINVAL	0x100

/*
 * How Quick command is executed
 */
#define SMB_QWRITE	0x0
#define SMB_QREAD	0x1

/*
 * ivars codes
 */
#define SMBUS_IVAR_ADDR	0x1	/* slave address of the device */

int	smbus_request_bus(device_t, device_t, int);
int	smbus_release_bus(device_t, device_t);
device_t smbus_alloc_bus(device_t);
int	smbus_error(int error);

void	smbus_intr(device_t, u_char, char low, char high, int error);

u_char	smbus_get_addr(device_t);

extern driver_t smbus_driver;
extern devclass_t smbus_devclass;

#define smbus_quick(bus,slave,how) \
	(SMBUS_QUICK(device_get_parent(bus), slave, how))
#define smbus_sendb(bus,slave,byte) \
	(SMBUS_SENDB(device_get_parent(bus), slave, byte))
#define smbus_recvb(bus,slave,byte) \
	(SMBUS_RECVB(device_get_parent(bus), slave, byte))
#define smbus_writeb(bus,slave,cmd,byte) \
	(SMBUS_WRITEB(device_get_parent(bus), slave, cmd, byte))
#define smbus_writew(bus,slave,cmd,word) \
	(SMBUS_WRITEW(device_get_parent(bus), slave, cmd, word))
#define smbus_readb(bus,slave,cmd,byte) \
	(SMBUS_READB(device_get_parent(bus), slave, cmd, byte))
#define smbus_readw(bus,slave,cmd,word) \
	(SMBUS_READW(device_get_parent(bus), slave, cmd, word))
#define smbus_pcall(bus,slave,cmd,sdata,rdata) \
	(SMBUS_PCALL(device_get_parent(bus), slave, cmd, sdata, rdata))
#define smbus_bwrite(bus,slave,cmd,count,buf) \
	(SMBUS_BWRITE(device_get_parent(bus), slave, cmd, count, buf))
#define smbus_bread(bus,slave,cmd,count,buf) \
	(SMBUS_BREAD(device_get_parent(bus), slave, cmd, count, buf))

#define SMBUS_MODVER	1
#define SMBUS_MINVER	1
#define SMBUS_MAXVER	1
#define SMBUS_PREFVER	SMBUS_MODVER

#endif


code:
/*-
 * Copyright (c) 1998 Nicolas Souchu
 * 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.
 *
 * $FreeBSD: release/9.0.0/sys/dev/smbus/smbus.h 189580 2009-03-09 13:30:00Z imp $
 *
 */
#ifndef __SMBUS_H
#define __SMBUS_H

struct smbus_softc {
	device_t owner;		/* smbus owner device structure */
	struct mtx lock;
};

void smbus_generic_intr(device_t dev, u_char devaddr, char low, char high, int err);

#endif


code:
/*
 * speaker.h -- interface definitions for speaker ioctl()
 *
 * v1.4 by Eric S. Raymond (esr@snark.thyrsus.com) Aug 1993
 *      modified for FreeBSD by Andrew A. Chernov <ache@astral.msk.su>
 *
 * $FreeBSD: release/9.0.0/sys/dev/speaker/speaker.h 152306 2005-11-11 09:57:32Z ru $
 */

#ifndef	_DEV_SPEAKER_SPEAKER_H_
#define	_DEV_SPEAKER_SPEAKER_H_

#include <sys/ioccom.h>

#define SPKRTONE        _IOW('S', 1, tone_t)    /* emit tone */
#define SPKRTUNE        _IO('S', 2)             /* emit tone sequence*/

typedef struct
{
    int	frequency;	/* in hertz */
    int duration;	/* in 1/100ths of a second */
} tone_t;

/*
 * Strings written to the speaker device are interpreted as tunes and played;
 * see the spkr(4) man page for details.
 */

#endif /* !_DEV_SPEAKER_SPEAKER_H_ */


code:
/*-
 * Copyright (c) 2001 M. Warner Losh
 * 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 code is based on ugen.c and ulpt.c developed by Lennart Augustsson.
 * This code includes software developed by the NetBSD Foundation, Inc. and
 * its contributors.
 */

/*  $FreeBSD: release/9.0.0/sys/dev/usb/ufm_ioctl.h 196219 2009-08-14 20:03:53Z jhb $ */

#include <sys/ioccom.h>

#define	FM_SET_FREQ	_IOWR('U', 200, int)
#define	FM_GET_FREQ	_IOWR('U', 201, int)
#define	FM_START	_IOWR('U', 202, int)
#define	FM_STOP		_IOWR('U', 203, int)
#define	FM_GET_STAT	_IOWR('U', 204, int)


code:
/* $FreeBSD: release/9.0.0/sys/dev/usb/usb.h 226904 2011-10-29 12:39:05Z 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.
 */

/*
 * This file contains standard definitions for the following USB
 * protocol versions:
 *
 * USB v1.0
 * USB v1.1
 * USB v2.0
 * USB v3.0
 */

#ifndef _USB_STANDARD_H_
#define	_USB_STANDARD_H_

#if defined(_KERNEL)
#include "opt_usb.h"

/* Declare parent SYSCTL USB node. */
#ifdef SYSCTL_DECL
SYSCTL_DECL(_hw_usb);
#endif

#include <sys/malloc.h>

MALLOC_DECLARE(M_USB);
MALLOC_DECLARE(M_USBDEV);
MALLOC_DECLARE(M_USBHC);
#endif /* _KERNEL */

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

#define	USB_STACK_VERSION 2000		/* 2.0 */

/* Definition of some hardcoded USB constants. */

#define	USB_MAX_IPACKET		8	/* initial USB packet size */
#define	USB_EP_MAX (2*16)		/* hardcoded */
#define	USB_ROOT_HUB_ADDR 1		/* index */
#define	USB_MIN_DEVICES 2		/* unused + root HUB */
#define	USB_UNCONFIG_INDEX 0xFF		/* internal use only */
#define	USB_IFACE_INDEX_ANY 0xFF	/* internal use only */
#define	USB_START_ADDR 0		/* default USB device BUS address
					 * after USB bus reset */
#define	USB_CONTROL_ENDPOINT 0		/* default control endpoint */

#define	USB_FRAMES_PER_SECOND_FS 1000	/* full speed */
#define	USB_FRAMES_PER_SECOND_HS 8000	/* high speed */

#define	USB_FS_BYTES_PER_HS_UFRAME 188	/* bytes */
#define	USB_HS_MICRO_FRAMES_MAX 8	/* units */

#define	USB_ISOC_TIME_MAX 128		/* ms */

/*
 * Minimum time a device needs to be powered down to go through a
 * power cycle. These values are not in the USB specification.
 */
#define	USB_POWER_DOWN_TIME	200	/* ms */
#define	USB_PORT_POWER_DOWN_TIME	100	/* ms */

/* Definition of software USB power modes */
#define	USB_POWER_MODE_OFF 0		/* turn off device */
#define	USB_POWER_MODE_ON 1		/* always on */
#define	USB_POWER_MODE_SAVE 2		/* automatic suspend and resume */
#define	USB_POWER_MODE_SUSPEND 3	/* force suspend */
#define	USB_POWER_MODE_RESUME 4		/* force resume */

#if 0
/* These are the values from the USB specification. */
#define	USB_PORT_RESET_DELAY	10	/* ms */
#define	USB_PORT_ROOT_RESET_DELAY 50	/* ms */
#define	USB_PORT_RESET_RECOVERY	10	/* ms */
#define	USB_PORT_POWERUP_DELAY	100	/* ms */
#define	USB_PORT_RESUME_DELAY	20	/* ms */
#define	USB_SET_ADDRESS_SETTLE	2	/* ms */
#define	USB_RESUME_DELAY	(20*5)	/* ms */
#define	USB_RESUME_WAIT		10	/* ms */
#define	USB_RESUME_RECOVERY	10	/* ms */
#define	USB_EXTRA_POWER_UP_TIME	0	/* ms */
#else
/* Allow for marginal and non-conforming devices. */
#define	USB_PORT_RESET_DELAY	50	/* ms */
#define	USB_PORT_ROOT_RESET_DELAY 250	/* ms */
#define	USB_PORT_RESET_RECOVERY	250	/* ms */
#define	USB_PORT_POWERUP_DELAY	300	/* ms */
#define	USB_PORT_RESUME_DELAY	(20*2)	/* ms */
#define	USB_SET_ADDRESS_SETTLE	10	/* ms */
#define	USB_RESUME_DELAY	(50*5)	/* ms */
#define	USB_RESUME_WAIT		50	/* ms */
#define	USB_RESUME_RECOVERY	50	/* ms */
#define	USB_EXTRA_POWER_UP_TIME	20	/* ms */
#endif

#define	USB_MIN_POWER		100	/* mA */
#define	USB_MAX_POWER		500	/* mA */

#define	USB_BUS_RESET_DELAY	100	/* ms */

/*
 * USB record layout in memory:
 *
 * - USB config 0
 *   - USB interfaces
 *     - USB alternative interfaces
 *       - USB endpoints
 *
 * - USB config 1
 *   - USB interfaces
 *     - USB alternative interfaces
 *       - USB endpoints
 */

/* Declaration of USB records */

struct usb_device_request {
	uByte	bmRequestType;
	uByte	bRequest;
	uWord	wValue;
	uWord	wIndex;
	uWord	wLength;
} __packed;
typedef struct usb_device_request usb_device_request_t;

#define	UT_WRITE		0x00
#define	UT_READ			0x80
#define	UT_STANDARD		0x00
#define	UT_CLASS		0x20
#define	UT_VENDOR		0x40
#define	UT_DEVICE		0x00
#define	UT_INTERFACE		0x01
#define	UT_ENDPOINT		0x02
#define	UT_OTHER		0x03

#define	UT_READ_DEVICE		(UT_READ  | UT_STANDARD | UT_DEVICE)
#define	UT_READ_INTERFACE	(UT_READ  | UT_STANDARD | UT_INTERFACE)
#define	UT_READ_ENDPOINT	(UT_READ  | UT_STANDARD | UT_ENDPOINT)
#define	UT_WRITE_DEVICE		(UT_WRITE | UT_STANDARD | UT_DEVICE)
#define	UT_WRITE_INTERFACE	(UT_WRITE | UT_STANDARD | UT_INTERFACE)
#define	UT_WRITE_ENDPOINT	(UT_WRITE | UT_STANDARD | UT_ENDPOINT)
#define	UT_READ_CLASS_DEVICE	(UT_READ  | UT_CLASS | UT_DEVICE)
#define	UT_READ_CLASS_INTERFACE	(UT_READ  | UT_CLASS | UT_INTERFACE)
#define	UT_READ_CLASS_OTHER	(UT_READ  | UT_CLASS | UT_OTHER)
#define	UT_READ_CLASS_ENDPOINT	(UT_READ  | UT_CLASS | UT_ENDPOINT)
#define	UT_WRITE_CLASS_DEVICE	(UT_WRITE | UT_CLASS | UT_DEVICE)
#define	UT_WRITE_CLASS_INTERFACE (UT_WRITE | UT_CLASS | UT_INTERFACE)
#define	UT_WRITE_CLASS_OTHER	(UT_WRITE | UT_CLASS | UT_OTHER)
#define	UT_WRITE_CLASS_ENDPOINT	(UT_WRITE | UT_CLASS | UT_ENDPOINT)
#define	UT_READ_VENDOR_DEVICE	(UT_READ  | UT_VENDOR | UT_DEVICE)
#define	UT_READ_VENDOR_INTERFACE (UT_READ  | UT_VENDOR | UT_INTERFACE)
#define	UT_READ_VENDOR_OTHER	(UT_READ  | UT_VENDOR | UT_OTHER)
#define	UT_READ_VENDOR_ENDPOINT	(UT_READ  | UT_VENDOR | UT_ENDPOINT)
#define	UT_WRITE_VENDOR_DEVICE	(UT_WRITE | UT_VENDOR | UT_DEVICE)
#define	UT_WRITE_VENDOR_INTERFACE (UT_WRITE | UT_VENDOR | UT_INTERFACE)
#define	UT_WRITE_VENDOR_OTHER	(UT_WRITE | UT_VENDOR | UT_OTHER)
#define	UT_WRITE_VENDOR_ENDPOINT (UT_WRITE | UT_VENDOR | UT_ENDPOINT)

/* Requests */
#define	UR_GET_STATUS		0x00
#define	UR_CLEAR_FEATURE	0x01
#define	UR_SET_FEATURE		0x03
#define	UR_SET_ADDRESS		0x05
#define	UR_GET_DESCRIPTOR	0x06
#define	UDESC_DEVICE		0x01
#define	UDESC_CONFIG		0x02
#define	UDESC_STRING		0x03
#define	USB_LANGUAGE_TABLE	0x00	/* language ID string index */
#define	UDESC_INTERFACE		0x04
#define	UDESC_ENDPOINT		0x05
#define	UDESC_DEVICE_QUALIFIER	0x06
#define	UDESC_OTHER_SPEED_CONFIGURATION 0x07
#define	UDESC_INTERFACE_POWER	0x08
#define	UDESC_OTG		0x09
#define	UDESC_DEBUG		0x0A
#define	UDESC_IFACE_ASSOC	0x0B	/* interface association */
#define	UDESC_BOS		0x0F	/* binary object store */
#define	UDESC_DEVICE_CAPABILITY	0x10
#define	UDESC_CS_DEVICE		0x21	/* class specific */
#define	UDESC_CS_CONFIG		0x22
#define	UDESC_CS_STRING		0x23
#define	UDESC_CS_INTERFACE	0x24
#define	UDESC_CS_ENDPOINT	0x25
#define	UDESC_HUB		0x29
#define	UDESC_SS_HUB		0x2A	/* super speed */
#define	UDESC_ENDPOINT_SS_COMP	0x30	/* super speed */
#define	UR_SET_DESCRIPTOR	0x07
#define	UR_GET_CONFIG		0x08
#define	UR_SET_CONFIG		0x09
#define	UR_GET_INTERFACE	0x0a
#define	UR_SET_INTERFACE	0x0b
#define	UR_SYNCH_FRAME		0x0c
#define	UR_SET_SEL		0x30
#define	UR_ISOCH_DELAY		0x31

/* HUB specific request */
#define	UR_GET_BUS_STATE	0x02
#define	UR_CLEAR_TT_BUFFER	0x08
#define	UR_RESET_TT		0x09
#define	UR_GET_TT_STATE		0x0a
#define	UR_STOP_TT		0x0b
#define	UR_SET_HUB_DEPTH	0x0c
#define	USB_SS_HUB_DEPTH_MAX	5
#define	UR_GET_PORT_ERR_COUNT	0x0d

/* Feature numbers */
#define	UF_ENDPOINT_HALT	0
#define	UF_DEVICE_REMOTE_WAKEUP	1
#define	UF_TEST_MODE		2
#define	UF_U1_ENABLE		0x30
#define	UF_U2_ENABLE		0x31
#define	UF_LTM_ENABLE		0x32

/* HUB specific features */
#define	UHF_C_HUB_LOCAL_POWER	0
#define	UHF_C_HUB_OVER_CURRENT	1
#define	UHF_PORT_CONNECTION	0
#define	UHF_PORT_ENABLE		1
#define	UHF_PORT_SUSPEND	2
#define	UHF_PORT_OVER_CURRENT	3
#define	UHF_PORT_RESET		4
#define	UHF_PORT_LINK_STATE	5
#define	UHF_PORT_POWER		8
#define	UHF_PORT_LOW_SPEED	9
#define	UHF_C_PORT_CONNECTION	16
#define	UHF_C_PORT_ENABLE	17
#define	UHF_C_PORT_SUSPEND	18
#define	UHF_C_PORT_OVER_CURRENT	19
#define	UHF_C_PORT_RESET	20
#define	UHF_PORT_TEST		21
#define	UHF_PORT_INDICATOR	22

/* SuperSpeed HUB specific features */
#define	UHF_PORT_U1_TIMEOUT	23
#define	UHF_PORT_U2_TIMEOUT	24
#define	UHF_C_PORT_LINK_STATE	25
#define	UHF_C_PORT_CONFIG_ERROR	26
#define	UHF_PORT_REMOTE_WAKE_MASK	27
#define	UHF_BH_PORT_RESET	28
#define	UHF_C_BH_PORT_RESET	29
#define	UHF_FORCE_LINKPM_ACCEPT	30

struct usb_descriptor {
	uByte	bLength;
	uByte	bDescriptorType;
	uByte	bDescriptorSubtype;
} __packed;
typedef struct usb_descriptor usb_descriptor_t;

struct usb_device_descriptor {
	uByte	bLength;
	uByte	bDescriptorType;
	uWord	bcdUSB;
#define	UD_USB_2_0		0x0200
#define	UD_USB_3_0		0x0300
#define	UD_IS_USB2(d) ((d)->bcdUSB[1] == 0x02)
#define	UD_IS_USB3(d) ((d)->bcdUSB[1] == 0x03)
	uByte	bDeviceClass;
	uByte	bDeviceSubClass;
	uByte	bDeviceProtocol;
	uByte	bMaxPacketSize;
	/* The fields below are not part of the initial descriptor. */
	uWord	idVendor;
	uWord	idProduct;
	uWord	bcdDevice;
	uByte	iManufacturer;
	uByte	iProduct;
	uByte	iSerialNumber;
	uByte	bNumConfigurations;
} __packed;
typedef struct usb_device_descriptor usb_device_descriptor_t;

/* Binary Device Object Store (BOS) */
struct usb_bos_descriptor {
	uByte	bLength;
	uByte	bDescriptorType;
	uWord	wTotalLength;
	uByte	bNumDeviceCaps;
} __packed;
typedef struct usb_bos_descriptor usb_bos_descriptor_t;

/* Binary Device Object Store Capability */
struct usb_bos_cap_descriptor {
	uByte	bLength;
	uByte	bDescriptorType;
	uByte	bDevCapabilityType;
#define	USB_DEVCAP_RESERVED	0x00
#define	USB_DEVCAP_WUSB		0x01
#define	USB_DEVCAP_USB2EXT	0x02
#define	USB_DEVCAP_SUPER_SPEED	0x03
#define	USB_DEVCAP_CONTAINER_ID	0x04
	/* data ... */
} __packed;
typedef struct usb_bos_cap_descriptor usb_bos_cap_descriptor_t;

struct usb_devcap_usb2ext_descriptor {
	uByte	bLength;
	uByte	bDescriptorType;
	uByte	bDevCapabilityType;
	uByte	bmAttributes;
#define	USB_V2EXT_LPM 0x02
} __packed;
typedef struct usb_devcap_usb2ext_descriptor usb_devcap_usb2ext_descriptor_t;

struct usb_devcap_ss_descriptor {
	uByte	bLength;
	uByte	bDescriptorType;
	uByte	bDevCapabilityType;
	uByte	bmAttributes;
	uWord	wSpeedsSupported;
	uByte	bFunctionalitySupport;
	uByte	bU1DevExitLat;
	uByte	bU2DevExitLat;
} __packed;
typedef struct usb_devcap_ss_descriptor usb_devcap_ss_descriptor_t;

struct usb_devcap_container_id_descriptor {
	uByte	bLength;
	uByte	bDescriptorType;
	uByte	bDevCapabilityType;
	uByte	bReserved;
	uByte	bContainerID;
} __packed;
typedef struct usb_devcap_container_id_descriptor
		usb_devcap_container_id_descriptor_t;

/* Device class codes */
#define	UDCLASS_IN_INTERFACE	0x00
#define	UDCLASS_COMM		0x02
#define	UDCLASS_HUB		0x09
#define	UDSUBCLASS_HUB		0x00
#define	UDPROTO_FSHUB		0x00
#define	UDPROTO_HSHUBSTT	0x01
#define	UDPROTO_HSHUBMTT	0x02
#define	UDPROTO_SSHUB		0x03
#define	UDCLASS_DIAGNOSTIC	0xdc
#define	UDCLASS_WIRELESS	0xe0
#define	UDSUBCLASS_RF		0x01
#define	UDPROTO_BLUETOOTH	0x01
#define	UDCLASS_VENDOR		0xff

struct usb_config_descriptor {
	uByte	bLength;
	uByte	bDescriptorType;
	uWord	wTotalLength;
	uByte	bNumInterface;
	uByte	bConfigurationValue;
#define	USB_UNCONFIG_NO 0
	uByte	iConfiguration;
	uByte	bmAttributes;
#define	UC_BUS_POWERED		0x80
#define	UC_SELF_POWERED		0x40
#define	UC_REMOTE_WAKEUP	0x20
	uByte	bMaxPower;		/* max current in 2 mA units */
#define	UC_POWER_FACTOR 2
} __packed;
typedef struct usb_config_descriptor usb_config_descriptor_t;

struct usb_interface_descriptor {
	uByte	bLength;
	uByte	bDescriptorType;
	uByte	bInterfaceNumber;
	uByte	bAlternateSetting;
	uByte	bNumEndpoints;
	uByte	bInterfaceClass;
	uByte	bInterfaceSubClass;
	uByte	bInterfaceProtocol;
	uByte	iInterface;
} __packed;
typedef struct usb_interface_descriptor usb_interface_descriptor_t;

struct usb_interface_assoc_descriptor {
	uByte	bLength;
	uByte	bDescriptorType;
	uByte	bFirstInterface;
	uByte	bInterfaceCount;
	uByte	bFunctionClass;
	uByte	bFunctionSubClass;
	uByte	bFunctionProtocol;
	uByte	iFunction;
} __packed;
typedef struct usb_interface_assoc_descriptor usb_interface_assoc_descriptor_t;

/* Interface class codes */
#define	UICLASS_UNSPEC		0x00
#define	UICLASS_AUDIO		0x01	/* audio */
#define	UISUBCLASS_AUDIOCONTROL	1
#define	UISUBCLASS_AUDIOSTREAM		2
#define	UISUBCLASS_MIDISTREAM		3

#define	UICLASS_CDC		0x02	/* communication */
#define	UISUBCLASS_DIRECT_LINE_CONTROL_MODEL	1
#define	UISUBCLASS_ABSTRACT_CONTROL_MODEL	2
#define	UISUBCLASS_TELEPHONE_CONTROL_MODEL	3
#define	UISUBCLASS_MULTICHANNEL_CONTROL_MODEL	4
#define	UISUBCLASS_CAPI_CONTROLMODEL		5
#define	UISUBCLASS_ETHERNET_NETWORKING_CONTROL_MODEL 6
#define	UISUBCLASS_ATM_NETWORKING_CONTROL_MODEL 7
#define	UISUBCLASS_WIRELESS_HANDSET_CM 8
#define	UISUBCLASS_DEVICE_MGMT 9
#define	UISUBCLASS_MOBILE_DIRECT_LINE_MODEL 10
#define	UISUBCLASS_OBEX 11
#define	UISUBCLASS_ETHERNET_EMULATION_MODEL 12
#define	UISUBCLASS_NETWORK_CONTROL_MODEL 13

#define	UIPROTO_CDC_AT			1

#define	UICLASS_HID		0x03
#define	UISUBCLASS_BOOT		1
#define	UIPROTO_BOOT_KEYBOARD	1
#define	UIPROTO_MOUSE		2

#define	UICLASS_PHYSICAL	0x05
#define	UICLASS_IMAGE		0x06
#define	UISUBCLASS_SIC		1	/* still image class */
#define	UICLASS_PRINTER		0x07
#define	UISUBCLASS_PRINTER	1
#define	UIPROTO_PRINTER_UNI	1
#define	UIPROTO_PRINTER_BI	2
#define	UIPROTO_PRINTER_1284	3

#define	UICLASS_MASS		0x08
#define	UISUBCLASS_RBC		1
#define	UISUBCLASS_SFF8020I	2
#define	UISUBCLASS_QIC157	3
#define	UISUBCLASS_UFI		4
#define	UISUBCLASS_SFF8070I	5
#define	UISUBCLASS_SCSI		6
#define	UIPROTO_MASS_CBI_I	0
#define	UIPROTO_MASS_CBI	1
#define	UIPROTO_MASS_BBB_OLD	2	/* Not in the spec anymore */
#define	UIPROTO_MASS_BBB	80	/* 'P' for the Iomega Zip drive */

#define	UICLASS_HUB		0x09
#define	UISUBCLASS_HUB		0
#define	UIPROTO_FSHUB		0
#define	UIPROTO_HSHUBSTT	0	/* Yes, same as previous */
#define	UIPROTO_HSHUBMTT	1

#define	UICLASS_CDC_DATA	0x0a
#define	UISUBCLASS_DATA		0x00
#define	UIPROTO_DATA_ISDNBRI		0x30	/* Physical iface */
#define	UIPROTO_DATA_HDLC		0x31	/* HDLC */
#define	UIPROTO_DATA_TRANSPARENT	0x32	/* Transparent */
#define	UIPROTO_DATA_Q921M		0x50	/* Management for Q921 */
#define	UIPROTO_DATA_Q921		0x51	/* Data for Q921 */
#define	UIPROTO_DATA_Q921TM		0x52	/* TEI multiplexer for Q921 */
#define	UIPROTO_DATA_V42BIS		0x90	/* Data compression */
#define	UIPROTO_DATA_Q931		0x91	/* Euro-ISDN */
#define	UIPROTO_DATA_V120		0x92	/* V.24 rate adaption */
#define	UIPROTO_DATA_CAPI		0x93	/* CAPI 2.0 commands */
#define	UIPROTO_DATA_HOST_BASED		0xfd	/* Host based driver */
#define	UIPROTO_DATA_PUF		0xfe	/* see Prot. Unit Func. Desc. */
#define	UIPROTO_DATA_VENDOR		0xff	/* Vendor specific */
#define	UIPROTO_DATA_NCM		0x01	/* Network Control Model */

#define	UICLASS_SMARTCARD	0x0b
#define	UICLASS_FIRM_UPD	0x0c
#define	UICLASS_SECURITY	0x0d
#define	UICLASS_DIAGNOSTIC	0xdc
#define	UICLASS_WIRELESS	0xe0
#define	UISUBCLASS_RF			0x01
#define	UIPROTO_BLUETOOTH		0x01

#define	UICLASS_IAD		0xEF	/* Interface Association Descriptor */

#define	UICLASS_APPL_SPEC	0xfe
#define	UISUBCLASS_FIRMWARE_DOWNLOAD	1
#define	UISUBCLASS_IRDA			2
#define	UIPROTO_IRDA			0

#define	UICLASS_VENDOR		0xff
#define	UISUBCLASS_XBOX360_CONTROLLER	0x5d
#define	UIPROTO_XBOX360_GAMEPAD	0x01

struct usb_endpoint_descriptor {
	uByte	bLength;
	uByte	bDescriptorType;
	uByte	bEndpointAddress;
#define	UE_GET_DIR(a)	((a) & 0x80)
#define	UE_SET_DIR(a,d)	((a) | (((d)&1) << 7))
#define	UE_DIR_IN	0x80		/* IN-token endpoint, fixed */
#define	UE_DIR_OUT	0x00		/* OUT-token endpoint, fixed */
#define	UE_DIR_RX	0xfd		/* for internal use only! */
#define	UE_DIR_TX	0xfe		/* for internal use only! */
#define	UE_DIR_ANY	0xff		/* for internal use only! */
#define	UE_ADDR		0x0f
#define	UE_ADDR_ANY	0xff		/* for internal use only! */
#define	UE_GET_ADDR(a)	((a) & UE_ADDR)
	uByte	bmAttributes;
#define	UE_XFERTYPE	0x03
#define	UE_CONTROL	0x00
#define	UE_ISOCHRONOUS	0x01
#define	UE_BULK	0x02
#define	UE_INTERRUPT	0x03
#define	UE_BULK_INTR	0xfe		/* for internal use only! */
#define	UE_TYPE_ANY	0xff		/* for internal use only! */
#define	UE_GET_XFERTYPE(a)	((a) & UE_XFERTYPE)
#define	UE_ISO_TYPE	0x0c
#define	UE_ISO_ASYNC	0x04
#define	UE_ISO_ADAPT	0x08
#define	UE_ISO_SYNC	0x0c
#define	UE_GET_ISO_TYPE(a)	((a) & UE_ISO_TYPE)
	uWord	wMaxPacketSize;
#define	UE_ZERO_MPS 0xFFFF		/* for internal use only */
	uByte	bInterval;
} __packed;
typedef struct usb_endpoint_descriptor usb_endpoint_descriptor_t;

struct usb_endpoint_ss_comp_descriptor {
	uByte	bLength;
	uByte	bDescriptorType;
	uByte	bMaxBurst;
	uByte	bmAttributes;
	uWord	wBytesPerInterval;
} __packed;
typedef struct usb_endpoint_ss_comp_descriptor
		usb_endpoint_ss_comp_descriptor_t;

struct usb_string_descriptor {
	uByte	bLength;
	uByte	bDescriptorType;
	uWord	bString[126];
	uByte	bUnused;
} __packed;
typedef struct usb_string_descriptor usb_string_descriptor_t;

#define	USB_MAKE_STRING_DESC(m,name)	\
struct name {				\
  uByte bLength;			\
  uByte bDescriptorType;		\
  uByte bData[sizeof((uint8_t []){m})];	\
} __packed;				\
static const struct name name = {	\
  .bLength = sizeof(struct name),	\
  .bDescriptorType = UDESC_STRING,	\
  .bData = { m },			\
}

struct usb_hub_descriptor {
	uByte	bDescLength;
	uByte	bDescriptorType;
	uByte	bNbrPorts;
	uWord	wHubCharacteristics;
#define	UHD_PWR			0x0003
#define	UHD_PWR_GANGED		0x0000
#define	UHD_PWR_INDIVIDUAL	0x0001
#define	UHD_PWR_NO_SWITCH	0x0002
#define	UHD_COMPOUND		0x0004
#define	UHD_OC			0x0018
#define	UHD_OC_GLOBAL		0x0000
#define	UHD_OC_INDIVIDUAL	0x0008
#define	UHD_OC_NONE		0x0010
#define	UHD_TT_THINK		0x0060
#define	UHD_TT_THINK_8		0x0000
#define	UHD_TT_THINK_16		0x0020
#define	UHD_TT_THINK_24		0x0040
#define	UHD_TT_THINK_32		0x0060
#define	UHD_PORT_IND		0x0080
	uByte	bPwrOn2PwrGood;		/* delay in 2 ms units */
#define	UHD_PWRON_FACTOR 2
	uByte	bHubContrCurrent;
	uByte	DeviceRemovable[32];	/* max 255 ports */
#define	UHD_NOT_REMOV(desc, i) \
    (((desc)->DeviceRemovable[(i)/8] >> ((i) % 8)) & 1)
	uByte	PortPowerCtrlMask[1];	/* deprecated */
} __packed;
typedef struct usb_hub_descriptor usb_hub_descriptor_t;

struct usb_hub_ss_descriptor {
	uByte	bLength;
	uByte	bDescriptorType;
	uByte	bNbrPorts;
	uWord	wHubCharacteristics;
	uByte	bPwrOn2PwrGood;		/* delay in 2 ms units */
	uByte	bHubContrCurrent;
	uByte	bHubHdrDecLat;
	uWord	wHubDelay;
	uByte	DeviceRemovable[32];	/* max 255 ports */
} __packed;
typedef struct usb_hub_ss_descriptor usb_hub_ss_descriptor_t;

/* minimum HUB descriptor (8-ports maximum) */
struct usb_hub_descriptor_min {
	uByte	bDescLength;
	uByte	bDescriptorType;
	uByte	bNbrPorts;
	uWord	wHubCharacteristics;
	uByte	bPwrOn2PwrGood;
	uByte	bHubContrCurrent;
	uByte	DeviceRemovable[1];
	uByte	PortPowerCtrlMask[1];
} __packed;
typedef struct usb_hub_descriptor_min usb_hub_descriptor_min_t;

struct usb_device_qualifier {
	uByte	bLength;
	uByte	bDescriptorType;
	uWord	bcdUSB;
	uByte	bDeviceClass;
	uByte	bDeviceSubClass;
	uByte	bDeviceProtocol;
	uByte	bMaxPacketSize0;
	uByte	bNumConfigurations;
	uByte	bReserved;
} __packed;
typedef struct usb_device_qualifier usb_device_qualifier_t;

struct usb_otg_descriptor {
	uByte	bLength;
	uByte	bDescriptorType;
	uByte	bmAttributes;
#define	UOTG_SRP	0x01
#define	UOTG_HNP	0x02
} __packed;
typedef struct usb_otg_descriptor usb_otg_descriptor_t;

/* OTG feature selectors */
#define	UOTG_B_HNP_ENABLE	3
#define	UOTG_A_HNP_SUPPORT	4
#define	UOTG_A_ALT_HNP_SUPPORT	5

struct usb_status {
	uWord	wStatus;
/* Device status flags */
#define	UDS_SELF_POWERED		0x0001
#define	UDS_REMOTE_WAKEUP		0x0002
/* Endpoint status flags */
#define	UES_HALT			0x0001
} __packed;
typedef struct usb_status usb_status_t;

struct usb_hub_status {
	uWord	wHubStatus;
#define	UHS_LOCAL_POWER			0x0001
#define	UHS_OVER_CURRENT		0x0002
	uWord	wHubChange;
} __packed;
typedef struct usb_hub_status usb_hub_status_t;

struct usb_port_status {
	uWord	wPortStatus;
#define	UPS_CURRENT_CONNECT_STATUS	0x0001
#define	UPS_PORT_ENABLED		0x0002
#define	UPS_SUSPEND			0x0004
#define	UPS_OVERCURRENT_INDICATOR	0x0008
#define	UPS_RESET			0x0010
/* The link-state bits are valid for Super-Speed USB HUBs */
#define	UPS_PORT_LINK_STATE_GET(x)	(((x) >> 5) & 0xF)
#define	UPS_PORT_LINK_STATE_SET(x)	(((x) & 0xF) << 5)
#define	UPS_PORT_LS_U0		0x00
#define	UPS_PORT_LS_U1		0x01
#define	UPS_PORT_LS_U2		0x02
#define	UPS_PORT_LS_U3		0x03
#define	UPS_PORT_LS_SS_DIS	0x04
#define	UPS_PORT_LS_RX_DET	0x05
#define	UPS_PORT_LS_SS_INA	0x06
#define	UPS_PORT_LS_POLL	0x07
#define	UPS_PORT_LS_RECOVER	0x08
#define	UPS_PORT_LS_HOT_RST	0x09
#define	UPS_PORT_LS_COMP_MODE	0x0A
#define	UPS_PORT_LS_LOOPBACK	0x0B
#define	UPS_PORT_LS_RESUME	0x0F
#define	UPS_PORT_POWER			0x0100
#define	UPS_LOW_SPEED			0x0200
#define	UPS_HIGH_SPEED			0x0400
#define	UPS_OTHER_SPEED			0x0600	/* currently FreeBSD specific */
#define	UPS_PORT_TEST			0x0800
#define	UPS_PORT_INDICATOR		0x1000
#define	UPS_PORT_MODE_DEVICE		0x8000	/* currently FreeBSD specific */
	uWord	wPortChange;
#define	UPS_C_CONNECT_STATUS		0x0001
#define	UPS_C_PORT_ENABLED		0x0002
#define	UPS_C_SUSPEND			0x0004
#define	UPS_C_OVERCURRENT_INDICATOR	0x0008
#define	UPS_C_PORT_RESET		0x0010
#define	UPS_C_BH_PORT_RESET		0x0020
#define	UPS_C_PORT_LINK_STATE		0x0040
#define	UPS_C_PORT_CONFIG_ERROR		0x0080
} __packed;
typedef struct usb_port_status usb_port_status_t;

/*
 * The "USB_SPEED" macros defines all the supported USB speeds.
 */
enum usb_dev_speed {
	USB_SPEED_VARIABLE,
	USB_SPEED_LOW,
	USB_SPEED_FULL,
	USB_SPEED_HIGH,
	USB_SPEED_SUPER,
};
#define	USB_SPEED_MAX	(USB_SPEED_SUPER+1)

/*
 * The "USB_REV" macros defines all the supported USB revisions.
 */
enum usb_revision {
	USB_REV_UNKNOWN,
	USB_REV_PRE_1_0,
	USB_REV_1_0,
	USB_REV_1_1,
	USB_REV_2_0,
	USB_REV_2_5,
	USB_REV_3_0
};
#define	USB_REV_MAX	(USB_REV_3_0+1)

/*
 * Supported host contoller modes.
 */
enum usb_hc_mode {
	USB_MODE_HOST,		/* initiates transfers */
	USB_MODE_DEVICE,	/* bus transfer target */
	USB_MODE_DUAL		/* can be host or device */
};
#define	USB_MODE_MAX	(USB_MODE_DUAL+1)

/*
 * The "USB_MODE" macros defines all the supported device states.
 */
enum usb_dev_state {
	USB_STATE_DETACHED,
	USB_STATE_ATTACHED,
	USB_STATE_POWERED,
	USB_STATE_ADDRESSED,
	USB_STATE_CONFIGURED,
};
#define	USB_STATE_MAX	(USB_STATE_CONFIGURED+1)
#endif					/* _USB_STANDARD_H_ */


code:
/* $FreeBSD: release/9.0.0/sys/dev/usb/usb_bus.h 215802 2010-11-24 19:11:32Z 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_BUS_H_
#define	_USB_BUS_H_

/*
 * The following structure defines the USB explore message sent to the USB
 * explore process.
 */

struct usb_bus_msg {
	struct usb_proc_msg hdr;
	struct usb_bus *bus;
};

/*
 * The following structure defines the USB statistics structure.
 */
struct usb_bus_stat {
	uint32_t uds_requests[4];
};

/*
 * The following structure defines an USB BUS. There is one USB BUS
 * for every Host or Device controller.
 */
struct usb_bus {
	struct usb_bus_stat stats_err;
	struct usb_bus_stat stats_ok;
	struct root_hold_token *bus_roothold;
	/*
	 * There are two callback processes. One for Giant locked
	 * callbacks. One for non-Giant locked callbacks. This should
	 * avoid congestion and reduce response time in most cases.
	 */
	struct usb_process giant_callback_proc;
	struct usb_process non_giant_callback_proc;

	/* Explore process */
	struct usb_process explore_proc;

	/* Control request process */
	struct usb_process control_xfer_proc;

	struct usb_bus_msg explore_msg[2];
	struct usb_bus_msg detach_msg[2];
	struct usb_bus_msg attach_msg[2];
	/*
	 * This mutex protects the USB hardware:
	 */
	struct mtx bus_mtx;
	struct usb_xfer_queue intr_q;
	struct usb_callout power_wdog;	/* power management */

	device_t parent;
	device_t bdev;			/* filled by HC driver */

#if USB_HAVE_BUSDMA
	struct usb_dma_parent_tag dma_parent_tag[1];
	struct usb_dma_tag dma_tags[USB_BUS_DMA_TAG_MAX];
#endif
	struct usb_bus_methods *methods;	/* filled by HC driver */
	struct usb_device **devices;

	struct ifnet *ifp;	/* only for USB Packet Filter */

	usb_power_mask_t hw_power_state;	/* see USB_HW_POWER_XXX */
	usb_size_t uframe_usage[USB_HS_MICRO_FRAMES_MAX];

	uint16_t isoc_time_last;	/* in milliseconds */

	uint8_t	alloc_failed;		/* Set if memory allocation failed. */
	uint8_t	driver_added_refcount;	/* Current driver generation count */
	enum usb_revision usbrev;	/* USB revision. See "USB_REV_XXX". */

	uint8_t	devices_max;		/* maximum number of USB devices */
	uint8_t	do_probe;		/* set if USB BUS should be re-probed */

	/*
	 * The scratch area can only be used inside the explore thread
	 * belonging to the give serial bus.
	 */
	union {
		struct usb_hw_ep_scratch hw_ep_scratch[1];
		struct usb_temp_setup temp_setup[1];
		uint8_t	data[255];
	}	scratch[1];
};

#endif					/* _USB_BUS_H_ */


code:
/* $FreeBSD: release/9.0.0/sys/dev/usb/usb_busdma.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_BUSDMA_H_
#define	_USB_BUSDMA_H_

#include <sys/uio.h>
#include <sys/mbuf.h>

#include <machine/bus.h>

/* defines */

#define	USB_PAGE_SIZE PAGE_SIZE		/* use system PAGE_SIZE */

#if (__FreeBSD_version >= 700020)
#define	USB_GET_DMA_TAG(dev) bus_get_dma_tag(dev)
#else
#define	USB_GET_DMA_TAG(dev) NULL	/* XXX */
#endif

/* structure prototypes */

struct usb_xfer_root;
struct usb_dma_parent_tag;
struct usb_dma_tag;

/*
 * The following typedef defines the USB DMA load done callback.
 */

typedef void (usb_dma_callback_t)(struct usb_dma_parent_tag *udpt);

/*
 * The following structure defines physical and non kernel virtual
 * address of a memory page having size USB_PAGE_SIZE.
 */
struct usb_page {
#if USB_HAVE_BUSDMA
	bus_size_t physaddr;
	void   *buffer;			/* non Kernel Virtual Address */
#endif
};

/*
 * The following structure is used when needing the kernel virtual
 * pointer and the physical address belonging to an offset in an USB
 * page cache.
 */
struct usb_page_search {
	void   *buffer;
#if USB_HAVE_BUSDMA
	bus_size_t physaddr;
#endif
	usb_size_t length;
};

/*
 * The following structure is used to keep information about a DMA
 * memory allocation.
 */
struct usb_page_cache {

#if USB_HAVE_BUSDMA
	bus_dma_tag_t tag;
	bus_dmamap_t map;
	struct usb_page *page_start;
#endif
	struct usb_dma_parent_tag *tag_parent;	/* always set */
	void   *buffer;			/* virtual buffer pointer */
#if USB_HAVE_BUSDMA
	usb_size_t page_offset_buf;
	usb_size_t page_offset_end;
	uint8_t	isread:1;		/* set if we are currently reading
					 * from the memory. Else write. */
	uint8_t	ismultiseg:1;		/* set if we can have multiple
					 * segments */
#endif
};

/*
 * The following structure describes the parent USB DMA tag.
 */
#if USB_HAVE_BUSDMA
struct usb_dma_parent_tag {
	struct cv cv[1];		/* internal condition variable */
	bus_dma_tag_t tag;		/* always set */

	struct mtx *mtx;		/* private mutex, always set */
	usb_dma_callback_t *func;	/* load complete callback function */
	struct usb_dma_tag *utag_first;/* pointer to first USB DMA tag */
	uint8_t	dma_error;		/* set if DMA load operation failed */
	uint8_t	dma_bits;		/* number of DMA address lines */
	uint8_t	utag_max;		/* number of USB DMA tags */
};
#else
struct usb_dma_parent_tag {};		/* empty struct */
#endif

/*
 * The following structure describes an USB DMA tag.
 */
#if USB_HAVE_BUSDMA
struct usb_dma_tag {
	struct usb_dma_parent_tag *tag_parent;
	bus_dma_tag_t tag;
	usb_size_t align;
	usb_size_t size;
};
#else
struct usb_dma_tag {};			/* empty struct */
#endif

/* function prototypes */

int	usb_uiomove(struct usb_page_cache *pc, struct uio *uio,
	    usb_frlength_t pc_offset, usb_frlength_t len);
struct usb_dma_tag *usb_dma_tag_find(struct usb_dma_parent_tag *udpt,
	    usb_size_t size, usb_size_t align);
uint8_t	usb_pc_alloc_mem(struct usb_page_cache *pc, struct usb_page *pg,
	    usb_size_t size, usb_size_t align);
uint8_t	usb_pc_dmamap_create(struct usb_page_cache *pc, usb_size_t size);
uint8_t	usb_pc_load_mem(struct usb_page_cache *pc, usb_size_t size,
	    uint8_t sync);
void	usb_bdma_done_event(struct usb_dma_parent_tag *udpt);
void	usb_bdma_post_sync(struct usb_xfer *xfer);
void	usb_bdma_pre_sync(struct usb_xfer *xfer);
void	usb_bdma_work_loop(struct usb_xfer_queue *pq);
void	usb_dma_tag_setup(struct usb_dma_parent_tag *udpt,
	    struct usb_dma_tag *udt, bus_dma_tag_t dmat, struct mtx *mtx,
	    usb_dma_callback_t *func, uint8_t ndmabits, uint8_t nudt);
void	usb_dma_tag_unsetup(struct usb_dma_parent_tag *udpt);
void	usb_pc_cpu_flush(struct usb_page_cache *pc);
void	usb_pc_cpu_invalidate(struct usb_page_cache *pc);
void	usb_pc_dmamap_destroy(struct usb_page_cache *pc);
void	usb_pc_free_mem(struct usb_page_cache *pc);

#endif					/* _USB_BUSDMA_H_ */


code:
/*	$NetBSD: usbcdc.h,v 1.9 2004/10/23 13:24:24 augustss Exp $	*/
/*	$FreeBSD: release/9.0.0/sys/dev/usb/usb_cdc.h 213809 2010-10-13 22:04:55Z hselasky $	*/

/*-
 * Copyright (c) 1998 The NetBSD Foundation, Inc.
 * All rights reserved.
 *
 * This code is derived from software contributed to The NetBSD Foundation
 * by Lennart Augustsson (lennart@augustsson.net) at
 * Carlstedt Research & Technology.
 *
 * 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 NETBSD FOUNDATION, INC. 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 FOUNDATION 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_CDC_H_
#define	_USB_CDC_H_

#define	UDESCSUB_CDC_HEADER	0
#define	UDESCSUB_CDC_CM		1	/* Call Management */
#define	UDESCSUB_CDC_ACM	2	/* Abstract Control Model */
#define	UDESCSUB_CDC_DLM	3	/* Direct Line Management */
#define	UDESCSUB_CDC_TRF	4	/* Telephone Ringer */
#define	UDESCSUB_CDC_TCLSR	5	/* Telephone Call */
#define	UDESCSUB_CDC_UNION	6
#define	UDESCSUB_CDC_CS		7	/* Country Selection */
#define	UDESCSUB_CDC_TOM	8	/* Telephone Operational Modes */
#define	UDESCSUB_CDC_USBT	9	/* USB Terminal */
#define	UDESCSUB_CDC_NCT	10
#define	UDESCSUB_CDC_PUF	11
#define	UDESCSUB_CDC_EUF	12
#define	UDESCSUB_CDC_MCMF	13
#define	UDESCSUB_CDC_CCMF	14
#define	UDESCSUB_CDC_ENF	15
#define	UDESCSUB_CDC_ANF	16

struct usb_cdc_header_descriptor {
	uByte	bLength;
	uByte	bDescriptorType;
	uByte	bDescriptorSubtype;
	uWord	bcdCDC;
} __packed;

struct usb_cdc_cm_descriptor {
	uByte	bLength;
	uByte	bDescriptorType;
	uByte	bDescriptorSubtype;
	uByte	bmCapabilities;
#define	USB_CDC_CM_DOES_CM		0x01
#define	USB_CDC_CM_OVER_DATA		0x02
	uByte	bDataInterface;
} __packed;

struct usb_cdc_acm_descriptor {
	uByte	bLength;
	uByte	bDescriptorType;
	uByte	bDescriptorSubtype;
	uByte	bmCapabilities;
#define	USB_CDC_ACM_HAS_FEATURE		0x01
#define	USB_CDC_ACM_HAS_LINE		0x02
#define	USB_CDC_ACM_HAS_BREAK		0x04
#define	USB_CDC_ACM_HAS_NETWORK_CONN	0x08
} __packed;

struct usb_cdc_union_descriptor {
	uByte	bLength;
	uByte	bDescriptorType;
	uByte	bDescriptorSubtype;
	uByte	bMasterInterface;
	uByte	bSlaveInterface[1];
} __packed;

struct usb_cdc_ethernet_descriptor {
	uByte	bLength;
	uByte	bDescriptorType;
	uByte	bDescriptorSubtype;
	uByte	iMacAddress;
	uDWord	bmEthernetStatistics;
	uWord	wMaxSegmentSize;
	uWord	wNumberMCFilters;
	uByte	bNumberPowerFilters;
} __packed;

#define	UCDC_SEND_ENCAPSULATED_COMMAND	0x00
#define	UCDC_GET_ENCAPSULATED_RESPONSE	0x01
#define	UCDC_SET_COMM_FEATURE		0x02
#define	UCDC_GET_COMM_FEATURE		0x03
#define	UCDC_ABSTRACT_STATE		0x01
#define	UCDC_COUNTRY_SETTING		0x02
#define	UCDC_CLEAR_COMM_FEATURE		0x04
#define	UCDC_SET_LINE_CODING		0x20
#define	UCDC_GET_LINE_CODING		0x21
#define	UCDC_SET_CONTROL_LINE_STATE	0x22
#define	UCDC_LINE_DTR			0x0001
#define	UCDC_LINE_RTS			0x0002
#define	UCDC_SEND_BREAK			0x23
#define	UCDC_BREAK_ON			0xffff
#define	UCDC_BREAK_OFF			0x0000

struct usb_cdc_abstract_state {
	uWord	wState;
#define	UCDC_IDLE_SETTING		0x0001
#define	UCDC_DATA_MULTIPLEXED		0x0002
} __packed;

#define	UCDC_ABSTRACT_STATE_LENGTH	2

struct usb_cdc_line_state {
	uDWord	dwDTERate;
	uByte	bCharFormat;
#define	UCDC_STOP_BIT_1			0
#define	UCDC_STOP_BIT_1_5		1
#define	UCDC_STOP_BIT_2			2
	uByte	bParityType;
#define	UCDC_PARITY_NONE		0
#define	UCDC_PARITY_ODD			1
#define	UCDC_PARITY_EVEN		2
#define	UCDC_PARITY_MARK		3
#define	UCDC_PARITY_SPACE		4
	uByte	bDataBits;
} __packed;

#define	UCDC_LINE_STATE_LENGTH		7

struct usb_cdc_notification {
	uByte	bmRequestType;
#define	UCDC_NOTIFICATION		0xa1
	uByte	bNotification;
#define	UCDC_N_NETWORK_CONNECTION	0x00
#define	UCDC_N_RESPONSE_AVAILABLE	0x01
#define	UCDC_N_AUX_JACK_HOOK_STATE	0x08
#define	UCDC_N_RING_DETECT		0x09
#define	UCDC_N_SERIAL_STATE		0x20
#define	UCDC_N_CALL_STATE_CHANGED	0x28
#define	UCDC_N_LINE_STATE_CHANGED	0x29
#define	UCDC_N_CONNECTION_SPEED_CHANGE	0x2a
	uWord	wValue;
	uWord	wIndex;
	uWord	wLength;
	uByte	data[16];
} __packed;

#define	UCDC_NOTIFICATION_LENGTH	8

/*
 * Bits set in the SERIAL STATE notifcation (first byte of data)
 */

#define	UCDC_N_SERIAL_OVERRUN		0x40
#define	UCDC_N_SERIAL_PARITY		0x20
#define	UCDC_N_SERIAL_FRAMING		0x10
#define	UCDC_N_SERIAL_RI		0x08
#define	UCDC_N_SERIAL_BREAK		0x04
#define	UCDC_N_SERIAL_DSR		0x02
#define	UCDC_N_SERIAL_DCD		0x01

/* Serial state bit masks */
#define	UCDC_MDM_RXCARRIER		0x01
#define	UCDC_MDM_TXCARRIER		0x02
#define	UCDC_MDM_BREAK			0x04
#define	UCDC_MDM_RING			0x08
#define	UCDC_MDM_FRAMING_ERR		0x10
#define	UCDC_MDM_PARITY_ERR		0x20
#define	UCDC_MDM_OVERRUN_ERR		0x40

/*
 * Network Control Model, NCM16 + NCM32, protocol definitions
 */
struct usb_ncm16_hdr {
	uDWord	dwSignature;
	uWord	wHeaderLength;
	uWord	wSequence;
	uWord	wBlockLength;
	uWord	wDptIndex;
} __packed;

struct usb_ncm16_dp {
	uWord	wFrameIndex;
	uWord	wFrameLength;
} __packed;

struct usb_ncm16_dpt {
	uDWord	dwSignature;
	uWord	wLength;
	uWord	wNextNdpIndex;
	struct usb_ncm16_dp dp[0];
} __packed;

struct usb_ncm32_hdr {
	uDWord	dwSignature;
	uWord	wHeaderLength;
	uWord	wSequence;
	uDWord	dwBlockLength;
	uDWord	dwDptIndex;
} __packed;

struct usb_ncm32_dp {
	uDWord	dwFrameIndex;
	uDWord	dwFrameLength;
} __packed;

struct usb_ncm32_dpt {
	uDWord	dwSignature;
	uWord	wLength;
	uWord	wReserved6;
	uDWord	dwNextNdpIndex;
	uDWord	dwReserved12;
	struct usb_ncm32_dp dp[0];
} __packed;

/* Communications interface class specific descriptors */

#define	UCDC_NCM_FUNC_DESC_SUBTYPE	0x1A

struct usb_ncm_func_descriptor {
	uByte	bLength;
	uByte	bDescriptorType;
	uByte	bDescriptorSubtype;
	uByte	bcdNcmVersion[2];
	uByte	bmNetworkCapabilities;
#define	UCDC_NCM_CAP_FILTER	0x01
#define	UCDC_NCM_CAP_MAC_ADDR	0x02
#define	UCDC_NCM_CAP_ENCAP	0x04
#define	UCDC_NCM_CAP_MAX_DATA	0x08
#define	UCDC_NCM_CAP_CRCMODE	0x10
#define	UCDC_NCM_CAP_MAX_DGRAM	0x20
} __packed;

/* Communications interface specific class request codes */

#define	UCDC_NCM_SET_ETHERNET_MULTICAST_FILTERS			0x40
#define	UCDC_NCM_SET_ETHERNET_POWER_MGMT_PATTERN_FILTER		0x41
#define	UCDC_NCM_GET_ETHERNET_POWER_MGMT_PATTERN_FILTER		0x42
#define	UCDC_NCM_SET_ETHERNET_PACKET_FILTER			0x43
#define	UCDC_NCM_GET_ETHERNET_STATISTIC				0x44
#define	UCDC_NCM_GET_NTB_PARAMETERS				0x80
#define	UCDC_NCM_GET_NET_ADDRESS				0x81
#define	UCDC_NCM_SET_NET_ADDRESS				0x82
#define	UCDC_NCM_GET_NTB_FORMAT					0x83
#define	UCDC_NCM_SET_NTB_FORMAT					0x84
#define	UCDC_NCM_GET_NTB_INPUT_SIZE				0x85
#define	UCDC_NCM_SET_NTB_INPUT_SIZE				0x86
#define	UCDC_NCM_GET_MAX_DATAGRAM_SIZE				0x87
#define	UCDC_NCM_SET_MAX_DATAGRAM_SIZE				0x88
#define	UCDC_NCM_GET_CRC_MODE					0x89
#define	UCDC_NCM_SET_CRC_MODE					0x8A

struct usb_ncm_parameters {
	uWord	wLength;
	uWord	bmNtbFormatsSupported;
#define	UCDC_NCM_FORMAT_NTB16	0x0001
#define	UCDC_NCM_FORMAT_NTB32	0x0002
	uDWord	dwNtbInMaxSize;
	uWord	wNdpInDivisor;
	uWord	wNdpInPayloadRemainder;
	uWord	wNdpInAlignment;
	uWord	wReserved14;
	uDWord	dwNtbOutMaxSize;
	uWord	wNdpOutDivisor;
	uWord	wNdpOutPayloadRemainder;
	uWord	wNdpOutAlignment;
	uWord	wNtbOutMaxDatagrams;
} __packed;

/* Communications interface specific class notification codes */
#define	UCDC_NCM_NOTIF_NETWORK_CONNECTION	0x00
#define	UCDC_NCM_NOTIF_RESPONSE_AVAILABLE	0x01
#define	UCDC_NCM_NOTIF_CONNECTION_SPEED_CHANGE	0x2A

#endif					/* _USB_CDC_H_ */


code:
/* $FreeBSD: release/9.0.0/sys/dev/usb/usb_compat_linux.h 198776 2009-11-01 21:48:18Z thompsa $ */
/*-
 * Copyright (c) 2007 Luigi Rizzo - Universita` di Pisa. All rights reserved.
 * Copyright (c) 2007 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_COMPAT_LINUX_H
#define	_USB_COMPAT_LINUX_H

struct usb_device;
struct usb_interface;
struct usb_driver;
struct urb;

typedef void *pm_message_t;
typedef void (usb_complete_t)(struct urb *);

#define	USB_MAX_FULL_SPEED_ISOC_FRAMES (60 * 1)
#define	USB_MAX_HIGH_SPEED_ISOC_FRAMES (60 * 8)

#define	USB_DEVICE_ID_MATCH_DEVICE \
	(USB_DEVICE_ID_MATCH_VENDOR | USB_DEVICE_ID_MATCH_PRODUCT)

#define	USB_DEVICE(vend,prod) \
	.match_flags = USB_DEVICE_ID_MATCH_DEVICE, .idVendor = (vend), \
	.idProduct = (prod)

/* The "usb_driver" structure holds the Linux USB device driver
 * callbacks, and a pointer to device ID's which this entry should
 * match against. Usually this entry is exposed to the USB emulation
 * layer using the "USB_DRIVER_EXPORT()" macro, which is defined
 * below.
 */
struct usb_driver {
	const char *name;

	int     (*probe) (struct usb_interface *intf,
	    	const	struct usb_device_id *id);

	void    (*disconnect) (struct usb_interface *intf);

	int     (*ioctl) (struct usb_interface *intf, unsigned int code,
	    	void  *buf);

	int     (*suspend) (struct usb_interface *intf, pm_message_t message);
	int     (*resume) (struct usb_interface *intf);

	const struct usb_device_id *id_table;

	void    (*shutdown) (struct usb_interface *intf);

	LIST_ENTRY(usb_driver) linux_driver_list;
};

#define	USB_DRIVER_EXPORT(id,p_usb_drv) \
  SYSINIT(id,SI_SUB_KLD,SI_ORDER_FIRST,usb_linux_register,p_usb_drv); \
  SYSUNINIT(id,SI_SUB_KLD,SI_ORDER_ANY,usb_linux_deregister,p_usb_drv)

#define	USB_DT_ENDPOINT_SIZE		7
#define	USB_DT_ENDPOINT_AUDIO_SIZE	9

/*
 * Endpoints
 */
#define	USB_ENDPOINT_NUMBER_MASK	0x0f	/* in bEndpointAddress */
#define	USB_ENDPOINT_DIR_MASK		0x80

#define	USB_ENDPOINT_XFERTYPE_MASK	0x03	/* in bmAttributes */
#define	USB_ENDPOINT_XFER_CONTROL	0
#define	USB_ENDPOINT_XFER_ISOC		1
#define	USB_ENDPOINT_XFER_BULK		2
#define	USB_ENDPOINT_XFER_INT		3
#define	USB_ENDPOINT_MAX_ADJUSTABLE	0x80

/* CONTROL REQUEST SUPPORT */

/*
 * Definition of direction mask for
 * "bEndpointAddress" and "bmRequestType":
 */
#define	USB_DIR_MASK			0x80
#define	USB_DIR_OUT			0x00	/* write to USB device */
#define	USB_DIR_IN			0x80	/* read from USB device */

/*
 * Definition of type mask for
 * "bmRequestType":
 */
#define	USB_TYPE_MASK			(0x03 << 5)
#define	USB_TYPE_STANDARD		(0x00 << 5)
#define	USB_TYPE_CLASS			(0x01 << 5)
#define	USB_TYPE_VENDOR			(0x02 << 5)
#define	USB_TYPE_RESERVED		(0x03 << 5)

/*
 * Definition of receiver mask for
 * "bmRequestType":
 */
#define	USB_RECIP_MASK			0x1f
#define	USB_RECIP_DEVICE		0x00
#define	USB_RECIP_INTERFACE		0x01
#define	USB_RECIP_ENDPOINT		0x02
#define	USB_RECIP_OTHER			0x03

/*
 * Definition of standard request values for
 * "bRequest":
 */
#define	USB_REQ_GET_STATUS		0x00
#define	USB_REQ_CLEAR_FEATURE		0x01
#define	USB_REQ_SET_FEATURE		0x03
#define	USB_REQ_SET_ADDRESS		0x05
#define	USB_REQ_GET_DESCRIPTOR		0x06
#define	USB_REQ_SET_DESCRIPTOR		0x07
#define	USB_REQ_GET_CONFIGURATION	0x08
#define	USB_REQ_SET_CONFIGURATION	0x09
#define	USB_REQ_GET_INTERFACE		0x0A
#define	USB_REQ_SET_INTERFACE		0x0B
#define	USB_REQ_SYNCH_FRAME		0x0C

#define	USB_REQ_SET_ENCRYPTION		0x0D	/* Wireless USB */
#define	USB_REQ_GET_ENCRYPTION		0x0E
#define	USB_REQ_SET_HANDSHAKE		0x0F
#define	USB_REQ_GET_HANDSHAKE		0x10
#define	USB_REQ_SET_CONNECTION		0x11
#define	USB_REQ_SET_SECURITY_DATA	0x12
#define	USB_REQ_GET_SECURITY_DATA	0x13
#define	USB_REQ_SET_WUSB_DATA		0x14
#define	USB_REQ_LOOPBACK_DATA_WRITE	0x15
#define	USB_REQ_LOOPBACK_DATA_READ	0x16
#define	USB_REQ_SET_INTERFACE_DS	0x17

/*
 * USB feature flags are written using USB_REQ_{CLEAR,SET}_FEATURE, and
 * are read as a bit array returned by USB_REQ_GET_STATUS.  (So there
 * are at most sixteen features of each type.)
 */
#define	USB_DEVICE_SELF_POWERED		0	/* (read only) */
#define	USB_DEVICE_REMOTE_WAKEUP	1	/* dev may initiate wakeup */
#define	USB_DEVICE_TEST_MODE		2	/* (wired high speed only) */
#define	USB_DEVICE_BATTERY		2	/* (wireless) */
#define	USB_DEVICE_B_HNP_ENABLE		3	/* (otg) dev may initiate HNP */
#define	USB_DEVICE_WUSB_DEVICE		3	/* (wireless) */
#define	USB_DEVICE_A_HNP_SUPPORT	4	/* (otg) RH port supports HNP */
#define	USB_DEVICE_A_ALT_HNP_SUPPORT	5	/* (otg) other RH port does */
#define	USB_DEVICE_DEBUG_MODE		6	/* (special devices only) */

#define	USB_ENDPOINT_HALT		0	/* IN/OUT will STALL */

#define	PIPE_ISOCHRONOUS		0x01	/* UE_ISOCHRONOUS */
#define	PIPE_INTERRUPT			0x03	/* UE_INTERRUPT */
#define	PIPE_CONTROL			0x00	/* UE_CONTROL */
#define	PIPE_BULK			0x02	/* UE_BULK */

/* Whenever Linux references an USB endpoint:
 * a) to initialize "urb->endpoint"
 * b) second argument passed to "usb_control_msg()"
 *
 * Then it uses one of the following macros. The "endpoint" argument
 * is the physical endpoint value masked by 0xF. The "dev" argument
 * is a pointer to "struct usb_device".
 */
#define	usb_sndctrlpipe(dev,endpoint) \
  usb_find_host_endpoint(dev, PIPE_CONTROL, (endpoint) | USB_DIR_OUT)

#define	usb_rcvctrlpipe(dev,endpoint) \
  usb_find_host_endpoint(dev, PIPE_CONTROL, (endpoint) | USB_DIR_IN)

#define	usb_sndisocpipe(dev,endpoint) \
  usb_find_host_endpoint(dev, PIPE_ISOCHRONOUS, (endpoint) | USB_DIR_OUT)

#define	usb_rcvisocpipe(dev,endpoint) \
  usb_find_host_endpoint(dev, PIPE_ISOCHRONOUS, (endpoint) | USB_DIR_IN)

#define	usb_sndbulkpipe(dev,endpoint) \
  usb_find_host_endpoint(dev, PIPE_BULK, (endpoint) | USB_DIR_OUT)

#define	usb_rcvbulkpipe(dev,endpoint) \
  usb_find_host_endpoint(dev, PIPE_BULK, (endpoint) | USB_DIR_IN)

#define	usb_sndintpipe(dev,endpoint) \
  usb_find_host_endpoint(dev, PIPE_INTERRUPT, (endpoint) | USB_DIR_OUT)

#define	usb_rcvintpipe(dev,endpoint) \
  usb_find_host_endpoint(dev, PIPE_INTERRUPT, (endpoint) | USB_DIR_IN)

/*
 * The following structure is used to extend "struct urb" when we are
 * dealing with an isochronous endpoint. It contains information about
 * the data offset and data length of an isochronous packet.
 * The "actual_length" field is updated before the "complete"
 * callback in the "urb" structure is called.
 */
struct usb_iso_packet_descriptor {
	uint32_t offset;		/* depreciated buffer offset (the
					 * packets are usually back to back) */
	uint16_t length;		/* expected length */
	uint16_t actual_length;
	 int16_t status;		/* transfer status */
};

/*
 * The following structure holds various information about an USB
 * transfer. This structure is used for all kinds of USB transfers.
 *
 * URB is short for USB Request Block.
 */
struct urb {
	TAILQ_ENTRY(urb) bsd_urb_list;
	struct cv cv_wait;

	struct usb_device *dev;		/* (in) pointer to associated device */
	struct usb_host_endpoint *endpoint;	/* (in) pipe pointer */
	uint8_t *setup_packet;		/* (in) setup packet (control only) */
	uint8_t *bsd_data_ptr;
	void   *transfer_buffer;	/* (in) associated data buffer */
	void   *context;		/* (in) context for completion */
	usb_complete_t *complete;	/* (in) completion routine */

	usb_size_t transfer_buffer_length;/* (in) data buffer length */
	usb_size_t bsd_length_rem;
	usb_size_t actual_length;	/* (return) actual transfer length */
	usb_timeout_t timeout;		/* FreeBSD specific */

	uint16_t transfer_flags;	/* (in) */
#define	URB_SHORT_NOT_OK	0x0001	/* report short transfers like errors */
#define	URB_ISO_ASAP		0x0002	/* ignore "start_frame" field */
#define	URB_ZERO_PACKET		0x0004	/* the USB transfer ends with a short
					 * packet */
#define	URB_NO_TRANSFER_DMA_MAP 0x0008	/* "transfer_dma" is valid on submit */
#define	URB_WAIT_WAKEUP		0x0010	/* custom flags */
#define	URB_IS_SLEEPING		0x0020	/* custom flags */

	usb_frcount_t start_frame;	/* (modify) start frame (ISO) */
	usb_frcount_t number_of_packets;	/* (in) number of ISO packets */
	uint16_t interval;		/* (modify) transfer interval
					 * (INT/ISO) */
	uint16_t error_count;		/* (return) number of ISO errors */
	int16_t	status;			/* (return) status */

	uint8_t	setup_dma;		/* (in) not used on FreeBSD */
	uint8_t	transfer_dma;		/* (in) not used on FreeBSD */
	uint8_t	bsd_isread;
	uint8_t kill_count;		/* FreeBSD specific */

	struct usb_iso_packet_descriptor iso_frame_desc[];	/* (in) ISO ONLY */
};

/* various prototypes */

int	usb_submit_urb(struct urb *urb, uint16_t mem_flags);
int	usb_unlink_urb(struct urb *urb);
int	usb_clear_halt(struct usb_device *dev, struct usb_host_endpoint *uhe);
int	usb_control_msg(struct usb_device *dev, struct usb_host_endpoint *ep,
	    uint8_t request, uint8_t requesttype, uint16_t value,
	    uint16_t index, void *data, uint16_t size, usb_timeout_t timeout);
int	usb_set_interface(struct usb_device *dev, uint8_t ifnum,
	    uint8_t alternate);
int	usb_setup_endpoint(struct usb_device *dev,
	    struct usb_host_endpoint *uhe, usb_frlength_t bufsize);

struct usb_host_endpoint *usb_find_host_endpoint(struct usb_device *dev,
	    uint8_t type, uint8_t ep);
struct urb *usb_alloc_urb(uint16_t iso_packets, uint16_t mem_flags);
struct usb_host_interface *usb_altnum_to_altsetting(
	    const struct usb_interface *intf, uint8_t alt_index);
struct usb_interface *usb_ifnum_to_if(struct usb_device *dev, uint8_t iface_no);

void   *usb_buffer_alloc(struct usb_device *dev, usb_size_t size,
	    uint16_t mem_flags, uint8_t *dma_addr);
void   *usbd_get_intfdata(struct usb_interface *intf);

void	usb_buffer_free(struct usb_device *dev, usb_size_t size, void *addr, uint8_t dma_addr);
void	usb_free_urb(struct urb *urb);
void	usb_init_urb(struct urb *urb);
void	usb_kill_urb(struct urb *urb);
void	usb_set_intfdata(struct usb_interface *intf, void *data);
void	usb_linux_register(void *arg);
void	usb_linux_deregister(void *arg);

void	usb_fill_bulk_urb(struct urb *, struct usb_device *,
	    struct usb_host_endpoint *, void *, int, usb_complete_t, void *);
int	usb_bulk_msg(struct usb_device *, struct usb_host_endpoint *,
	    void *, int, uint16_t *, usb_timeout_t);

#define	interface_to_usbdev(intf) (intf)->linux_udev
#define	interface_to_bsddev(intf) (intf)->linux_udev

#endif					/* _USB_COMPAT_LINUX_H */