1/*  *********************************************************************
2    *  Broadcom Common Firmware Environment (CFE)
3    *
4    *  USB Device Layer definitions		File: usbd.h
5    *
6    *  Definitions for the USB device layer.
7    *
8    *  Author:  Mitch Lichtenberg
9    *
10    *********************************************************************
11    *
12    *  Copyright 2000,2001,2002,2003
13    *  Broadcom Corporation. All rights reserved.
14    *
15    *  This software is furnished under license and may be used and
16    *  copied only in accordance with the following terms and
17    *  conditions.  Subject to these conditions, you may download,
18    *  copy, install, use, modify and distribute modified or unmodified
19    *  copies of this software in source and/or binary form.  No title
20    *  or ownership is transferred hereby.
21    *
22    *  1) Any source code used, modified or distributed must reproduce
23    *     and retain this copyright notice and list of conditions
24    *     as they appear in the source file.
25    *
26    *  2) No right is granted to use any trade name, trademark, or
27    *     logo of Broadcom Corporation.  The "Broadcom Corporation"
28    *     name may not be used to endorse or promote products derived
29    *     from this software without the prior written permission of
30    *     Broadcom Corporation.
31    *
32    *  3) THIS SOFTWARE IS PROVIDED "AS-IS" AND ANY EXPRESS OR
33    *     IMPLIED WARRANTIES, INCLUDING BUT NOT LIMITED TO, ANY IMPLIED
34    *     WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
35    *     PURPOSE, OR NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT
36    *     SHALL BROADCOM BE LIABLE FOR ANY DAMAGES WHATSOEVER, AND IN
37    *     PARTICULAR, BROADCOM SHALL NOT BE LIABLE FOR DIRECT, INDIRECT,
38    *     INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
39    *     (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
40    *     GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
41    *     BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
42    *     OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
43    *     TORT (INCLUDING NEGLIGENCE OR OTHERWISE), EVEN IF ADVISED OF
44    *     THE POSSIBILITY OF SUCH DAMAGE.
45    ********************************************************************* */
46
47#ifndef _USBD_H_
48#define _USBD_H_
49
50#ifndef _PHYSADDR_T_DEFINED_
51#include "lib_physio.h"
52#endif
53
54#include "usbchap9.h"
55
56
57/*  *********************************************************************
58    *  Forward declarations and opaque types
59    ********************************************************************* */
60
61typedef struct usb_hc_s usb_hc_t;
62typedef struct usb_ept_s usb_ept_t;
63typedef struct usb_hcdrv_s usb_hcdrv_t;
64typedef struct usbdev_s usbdev_t;
65typedef struct usb_driver_s usb_driver_t;
66
67/*  *********************************************************************
68    *  USB Request error codes
69    *
70    *  Note: these error codes exactly match the OHCI errors, so they
71    *  should be kept in sync.  It is expected that other controllers
72    *  will either use these same codes or can be mapped into them.
73    ********************************************************************* */
74
75#define UR_ERR_NOERROR			0
76#define UR_ERR_CRC			1
77#define UR_ERR_BITSTUFFING		2
78#define UR_ERR_DATATOGGLEMISMATCH	3
79#define UR_ERR_STALL			4
80#define UR_ERR_DEVICENOTRESPONDING	5
81#define UR_ERR_PIDCHECKFAILURE		6
82#define UR_ERR_UNEXPECTEDPID		7
83#define UR_ERR_DATAOVERRUN		8
84#define UR_ERR_DATAUNDERRUN		9
85#define UR_ERR_BUFFEROVERRUN		12
86#define UR_ERR_BUFFERUNDERRUN		13
87#define UR_ERR_NOTACCESSED		15
88#define UR_ERR_CANCELLED		0xFF
89
90/*  *********************************************************************
91    *  USB Bus structure - one of these per host controller
92    ********************************************************************* */
93
94#define USB_MAX_DEVICES	128
95
96typedef struct usbbus_s {
97    struct usbbus_s *ub_next;		/* link to other buses */
98    usb_hc_t *ub_hwsoftc;		/* bus driver softc */
99    usb_hcdrv_t *ub_hwdisp;		/* bus driver dispatch */
100    usbdev_t *ub_roothub;		/* root hub device */
101    usbdev_t *ub_devices[USB_MAX_DEVICES]; /* pointers to each device, idx by address */
102    unsigned int ub_flags;		/* flag bits */
103    int ub_num;				/* bus number */
104} usbbus_t;
105
106#define UB_FLG_NEEDSCAN	1		/* some device on bus needs scanning */
107
108/*  *********************************************************************
109    *  USB Pipe structure - one of these per unidirectional channel
110    *  to an endpoint on a USB device
111    ********************************************************************* */
112
113#define UP_TYPE_CONTROL	1
114#define UP_TYPE_BULK	2
115#define UP_TYPE_INTR	4
116#define UP_TYPE_ISOC	8
117
118#define UP_TYPE_IN	128
119#define UP_TYPE_OUT	256
120
121#define UP_TYPE_LOWSPEED 16
122
123typedef struct usbpipe_s {
124    usb_ept_t *up_hwendpoint;		/* OHCI-specific endpoint pointer */
125    usbdev_t *up_dev;			/* our device info */
126    int up_num;				/* pipe number */
127    int up_mps;				/* max packet size */
128    int up_flags;
129} usbpipe_t;
130
131/*  *********************************************************************
132    *  USB device structure - one per device attached to the USB
133    *  This is the basic structure applications will use to
134    *  refer to a device.
135    ********************************************************************* */
136
137#define UD_FLAG_HUB	0x0001		/* this is a hub device */
138#define UD_FLAG_ROOTHUB	0x0002		/* this is a root hub device */
139#define UD_FLAG_LOWSPEED 0x0008		/* this is a lowspeed device */
140#define UD_FLAG_REMOVING 0x0010		/* device is being removed */
141
142#define UD_MAX_PIPES	32
143#define USB_EPADDR_TO_IDX(addr) ((((addr)&0x80) >> 3) | ((addr) & 0x0F))
144
145struct usbdev_s {
146    usb_driver_t *ud_drv;		/* Driver's methods */
147    usbbus_t *ud_bus;			/* owning bus */
148    int ud_address;			/* USB address */
149    usbpipe_t *ud_pipes[UD_MAX_PIPES];	/* pipes, 0 is the control pipe */
150    struct usbdev_s *ud_parent;		/* used for hubs */
151    int ud_flags;
152    void *ud_private;			/* private data for device driver */
153    usb_device_descr_t ud_devdescr;	/* device descriptor */
154    usb_config_descr_t *ud_cfgdescr;	/* config, interface, and ep descrs */
155};
156
157
158/*  *********************************************************************
159    *  USB Request - basic structure to describe an in-progress
160    *  I/O request.  It associates buses, pipes, and buffers
161    *  together.
162    ********************************************************************* */
163
164
165#define UR_FLAG_SYNC		0x8000
166
167#define UR_FLAG_SETUP		0x0001
168#define UR_FLAG_IN		0x0002
169#define UR_FLAG_OUT		0x0004
170#define UR_FLAG_STATUS_IN	0x0008		/* status phase of a control WRITE */
171#define UR_FLAG_STATUS_OUT	0x0010		/* status phase of a control READ */
172#define UR_FLAG_SHORTOK		0x0020		/* short transfers are ok */
173
174
175typedef struct usbreq_s {
176    queue_t ur_qblock;
177
178    /*
179     * pointers to our device and pipe
180     */
181
182    usbdev_t *ur_dev;
183    usbpipe_t *ur_pipe;
184
185    /*
186     * stuff to keep track of the data we transfer
187     */
188
189    uint8_t *ur_buffer;
190    int ur_length;
191    int ur_xferred;
192    int ur_status;
193    int ur_flags;
194
195    /*
196     * Stuff needed for the callback
197     */
198    void *ur_ref;
199    int ur_inprogress;
200    int (*ur_callback)(struct usbreq_s *req);
201
202    /*
203     * For use inside the ohci driver
204     */
205    void *ur_tdqueue;
206    int ur_tdcount;
207} usbreq_t;
208
209
210/*  *********************************************************************
211    *  Prototypes
212    ********************************************************************* */
213
214int usb_create_pipe(usbdev_t *dev,int pipenum,int mps,int flags);
215void usb_destroy_pipe(usbdev_t *dev,int pipenum);
216int usb_set_address(usbdev_t *dev,int addr);
217usbdev_t *usb_create_device(usbbus_t *bus,int lowspeed);
218void usb_destroy_device(usbdev_t *dev);
219void usb_destroy_all_pipes(usbdev_t *dev);
220usbreq_t *usb_make_request(usbdev_t *dev,int pipenum,uint8_t *buf,int length,int flags);
221void usb_poll(usbbus_t *bus);
222void usb_daemon(usbbus_t *bus);
223int usb_cancel_request(usbreq_t *ur);
224void usb_free_request(usbreq_t *ur);
225int usb_queue_request(usbreq_t *ur);
226int usb_wait_request(usbreq_t *ur);
227int usb_sync_request(usbreq_t *ur);
228int usb_make_sync_request(usbdev_t *dev,int pipenum,uint8_t *buf,int length,int flags);
229int usb_get_descriptor(usbdev_t *dev,uint8_t reqtype,int dsctype,int dscidx,uint8_t *buffer,int buflen);
230int usb_get_config_descriptor(usbdev_t *dev,usb_config_descr_t *dscr,int idx,int maxlen);
231int usb_get_device_status(usbdev_t *dev,usb_device_status_t *status);
232int usb_set_configuration(usbdev_t *dev,int config);
233int usb_open_pipe(usbdev_t *dev,usb_endpoint_descr_t *epdesc);
234int usb_simple_request(usbdev_t *dev,uint8_t reqtype,int bRequest,int wValue,int wIndex);
235void usb_complete_request(usbreq_t *ur,int status);
236int usb_get_device_descriptor(usbdev_t *dev,usb_device_descr_t *dscr,int smallflg);
237int usb_set_ep0mps(usbdev_t *dev,int mps);
238int usb_new_address(usbbus_t *bus);
239int usb_get_string(usbdev_t *dev,int id,char *buf,int maxlen);
240int usb_std_request(usbdev_t *dev,uint8_t bmRequestType,
241			   uint8_t bRequest,uint16_t wValue,
242		    uint16_t wIndex,uint8_t *buffer,int length);
243void *usb_find_cfg_descr(usbdev_t *dev,int dtype,int idx);
244void usb_delay_ms(usbbus_t *bus,int ms);
245int usb_clear_stall(usbdev_t *dev,int pipe);
246
247void usb_scan(usbbus_t *bus);
248void usbhub_map_tree(usbbus_t *bus,int (*func)(usbdev_t *dev,void *arg),void *arg);
249void usbhub_map_from_device(usbdev_t *dev,int (*func)(usbdev_t *dev,void *arg),void *arg);
250void usbhub_dumpbus(usbbus_t *bus,uint32_t verbose);
251
252void usb_initroot(usbbus_t *bus);
253
254
255/*  *********************************************************************
256    *  Host Controller Driver
257    *  Methods for abstracting the USB host controller from the
258    *  rest of the goop.
259    ********************************************************************* */
260
261struct usb_hcdrv_s {
262    usbbus_t * (*hcdrv_create)(physaddr_t regaddr);
263    void (*hcdrv_delete)(usbbus_t *);
264    int (*hcdrv_start)(usbbus_t *);
265    void (*hcdrv_stop)(usbbus_t *);
266    int (*hcdrv_intr)(usbbus_t *);
267    usb_ept_t * (*hcdrv_ept_create)(usbbus_t *,int usbaddr,int eptnum,int mps,int flags);
268    void (*hcdrv_ept_delete)(usbbus_t *,usb_ept_t *);
269    void (*hcdrv_ept_setmps)(usbbus_t *,usb_ept_t *,int mps);
270    void (*hcdrv_ept_setaddr)(usbbus_t *,usb_ept_t *,int addr);
271    void (*hcdrv_ept_cleartoggle)(usbbus_t *,usb_ept_t *);
272    int (*hcdrv_xfer)(usbbus_t *,usb_ept_t *uept,usbreq_t *ur);
273};
274
275#define UBCREATE(driver,addr) (*((driver)->hcdrv_create))(addr)
276#define UBDELETE(bus) (*((bus)->ub_hwdisp->hcdrv_delete))(bus)
277#define UBSTART(bus) (*((bus)->ub_hwdisp->hcdrv_start))(bus)
278#define UBSTOP(bus) (*((bus)->ub_hwdisp->hcdrv_stop))(bus)
279#define UBINTR(bus) (*((bus)->ub_hwdisp->hcdrv_intr))(bus)
280#define UBEPTCREATE(bus,addr,num,mps,flags) (*((bus)->ub_hwdisp->hcdrv_ept_create))(bus,addr,num,mps,flags)
281#define UBEPTDELETE(bus,ept) (*((bus)->ub_hwdisp->hcdrv_ept_delete))(bus,ept)
282#define UBEPTSETMPS(bus,ept,mps) (*((bus)->ub_hwdisp->hcdrv_ept_setmps))(bus,ept,mps)
283#define UBEPTSETADDR(bus,ept,addr) (*((bus)->ub_hwdisp->hcdrv_ept_setaddr))(bus,ept,addr)
284#define UBEPTCLEARTOGGLE(bus,ept) (*((bus)->ub_hwdisp->hcdrv_ept_cleartoggle))(bus,ept)
285#define UBXFER(bus,ept,xfer) (*((bus)->ub_hwdisp->hcdrv_xfer))(bus,ept,xfer)
286
287/*  *********************************************************************
288    *  Devices - methods for abstracting things that _use_ USB
289    *  (devices you can plug into the USB) - the entry points
290    *  here are basically just for device discovery, since the top half
291    *  of the actual driver will be device-specific.
292    ********************************************************************* */
293
294struct usb_driver_s {
295    char *udrv_name;
296    int (*udrv_attach)(usbdev_t *,usb_driver_t *);
297    int (*udrv_detach)(usbdev_t *);
298};
299
300typedef struct usb_drvlist_s {
301    int udl_class;
302    int udl_vendor;
303    int udl_product;
304    usb_driver_t *udl_disp;
305} usb_drvlist_t;
306
307extern usb_driver_t *usb_find_driver(usbdev_t *dev);
308
309#define CLASS_ANY	-1
310#define VENDOR_ANY	-1
311#define PRODUCT_ANY	-1
312
313void mydelay(int x);
314
315#define IS_HUB(dev) ((dev)->ud_devdescr.bDeviceClass == USB_DEVICE_CLASS_HUB)
316
317/*  *********************************************************************
318    *  Error codes
319    ********************************************************************* */
320
321#define USBD_ERR_OK		0		/* Request ok */
322#define USBD_ERR_STALLED	-1		/* Endpoint is stalled */
323#define USBD_ERR_IOERROR	-2		/* I/O error */
324#define USBD_ERR_HWERROR	-3		/* Hardware failure */
325#define USBD_ERR_CANCELED	-4		/* Request canceled */
326#define USBD_ERR_NOMEM		-5		/* Out of memory */
327#define USBD_ERR_TIMEOUT	-6		/* Request timeout */
328
329/*  *********************************************************************
330    *  Debug routines
331    ********************************************************************* */
332
333void usb_dbg_dumpportstatus(int port,usb_port_status_t *portstatus,int level);
334void usb_dbg_dumpdescriptors(usbdev_t *dev,uint8_t *ptr,int len);
335void usb_dbg_dumpcfgdescr(usbdev_t *dev,unsigned int index);
336void usb_dbg_dumpeptdescr(usb_endpoint_descr_t * epdscr);
337void usb_dbg_dumpdevice(usbdev_t *dev);
338void usb_dbg_showdevice(usbdev_t *dev);
339
340#endif /* _USBD_H_ */
341