summaryrefslogtreecommitdiffstats
path: root/cfe/cfe/usb/usbd.h
blob: 73fde869aa4f96a7da8f33404327e7b055a3f958 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
/*  *********************************************************************
    *  Broadcom Common Firmware Environment (CFE)
    *  
    *  USB Device Layer definitions		File: usbd.h
    *  
    *  Definitions for the USB device layer.
    *  
    *  Author:  Mitch Lichtenberg (mpl@broadcom.com)
    *  
    *********************************************************************  
    *
    *  Copyright 2000,2001,2002,2003
    *  Broadcom Corporation. All rights reserved.
    *  
    *  This software is furnished under license and may be used and 
    *  copied only in accordance with the following terms and 
    *  conditions.  Subject to these conditions, you may download, 
    *  copy, install, use, modify and distribute modified or unmodified 
    *  copies of this software in source and/or binary form.  No title 
    *  or ownership is transferred hereby.
    *  
    *  1) Any source code used, modified or distributed must reproduce 
    *     and retain this copyright notice and list of conditions 
    *     as they appear in the source file.
    *  
    *  2) No right is granted to use any trade name, trademark, or 
    *     logo of Broadcom Corporation.  The "Broadcom Corporation" 
    *     name may not be used to endorse or promote products derived 
    *     from this software without the prior written permission of 
    *     Broadcom Corporation.
    *  
    *  3) THIS SOFTWARE IS PROVIDED "AS-IS" AND ANY EXPRESS OR
    *     IMPLIED WARRANTIES, INCLUDING BUT NOT LIMITED TO, ANY IMPLIED
    *     WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR 
    *     PURPOSE, OR NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT 
    *     SHALL BROADCOM BE LIABLE FOR ANY DAMAGES WHATSOEVER, AND IN 
    *     PARTICULAR, BROADCOM SHALL NOT BE LIABLE FOR 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), EVEN IF ADVISED OF 
    *     THE POSSIBILITY OF SUCH DAMAGE.
    ********************************************************************* */

#ifndef _PHYSADDR_T_DEFINED_
#include "lib_physio.h"
#endif

#include "usbchap9.h"


/*  *********************************************************************
    *  Forward declarations and opaque types
    ********************************************************************* */

typedef struct usb_hc_s usb_hc_t;
typedef struct usb_ept_s usb_ept_t;
typedef struct usb_hcdrv_s usb_hcdrv_t;
typedef struct usbdev_s usbdev_t;
typedef struct usb_driver_s usb_driver_t;

/*  *********************************************************************
    *  USB Bus structure - one of these per host controller
    ********************************************************************* */

#define USB_MAX_DEVICES	128

typedef struct usbbus_s {
    struct usbbus_s *ub_next;		/* link to other buses */
    usb_hc_t *ub_hwsoftc;		/* bus driver softc */
    usb_hcdrv_t *ub_hwdisp;		/* bus driver dispatch */
    usbdev_t *ub_roothub;		/* root hub device */
    usbdev_t *ub_devices[USB_MAX_DEVICES]; /* pointers to each device, idx by address */
    unsigned int ub_flags;		/* flag bits */
    int ub_num;				/* bus number */
} usbbus_t;

#define UB_FLG_NEEDSCAN	1		/* some device on bus needs scanning */

/*  *********************************************************************
    *  USB Pipe structure - one of these per unidirectional channel
    *  to an endpoint on a USB device
    ********************************************************************* */

#define UP_TYPE_CONTROL	1
#define UP_TYPE_BULK	2
#define UP_TYPE_INTR	4
#define UP_TYPE_ISOC	8

#define UP_TYPE_IN	128
#define UP_TYPE_OUT	256

#define UP_TYPE_LOWSPEED 16

typedef struct usbpipe_s {
    usb_ept_t *up_hwendpoint;		/* OHCI-specific endpoint pointer */
    usbdev_t *up_dev;			/* our device info */
    int up_num;				/* pipe number */
    int up_mps;				/* max packet size */
    int up_flags;
} usbpipe_t;

/*  *********************************************************************
    *  USB device structure - one per device attached to the USB
    *  This is the basic structure applications will use to
    *  refer to a device.
    ********************************************************************* */

#define UD_FLAG_HUB	0x0001		/* this is a hub device */
#define UD_FLAG_ROOTHUB	0x0002		/* this is a root hub device */
#define UD_FLAG_LOWSPEED 0x0008		/* this is a lowspeed device */

#define UD_MAX_PIPES	32
#define USB_EPADDR_TO_IDX(addr) ((((addr)&0x80) >> 3) | ((addr) & 0x0F))
//#define USB_EPADDR_TO_IDX(addr) USB_ENDPOINT_ADDRESS(addr)
//#define UD_MAX_PIPES	16

struct usbdev_s {
    usb_driver_t *ud_drv;		/* Driver's methods */
    usbbus_t *ud_bus;			/* owning bus */
    int ud_address;			/* USB address */
    usbpipe_t *ud_pipes[UD_MAX_PIPES];	/* pipes, 0 is the control pipe */
    struct usbdev_s *ud_parent;		/* used for hubs */
    int ud_flags;
    void *ud_private;			/* private data for device driver */
    usb_device_descr_t ud_devdescr;	/* device descriptor */
    usb_config_descr_t *ud_cfgdescr;	/* config, interface, and ep descrs */
};


/*  *********************************************************************
    *  USB Request - basic structure to describe an in-progress 
    *  I/O request.  It associates buses, pipes, and buffers 
    *  together.
    ********************************************************************* */


#define UR_FLAG_SYNC		0x8000

#define UR_FLAG_SETUP		0x0001
#define UR_FLAG_IN		0x0002
#define UR_FLAG_OUT		0x0004
#define UR_FLAG_STATUS_IN	0x0008		/* status phase of a control WRITE */
#define UR_FLAG_STATUS_OUT	0x0010		/* status phase of a control READ */
#define UR_FLAG_SHORTOK		0x0020		/* short transfers are ok */


typedef struct usbreq_s {
    queue_t ur_qblock;

    /*
     * pointers to our device and pipe 
     */

    usbdev_t *ur_dev;
    usbpipe_t *ur_pipe;

    /*
     * stuff to keep track of the data we transfer
     */

    uint8_t *ur_buffer;
    int ur_length;
    int ur_xferred;
    int ur_status;
    int ur_flags;

    /*
     * Stuff needed for the callback
     */
    void *ur_ref;
    int ur_inprogress;
    int (*ur_callback)(struct usbreq_s *req);

    /*
     * For use inside the ohci driver
     */
    void *ur_tdqueue;	
    int ur_tdcount;
} usbreq_t;


/*  *********************************************************************
    *  Prototypes
    ********************************************************************* */

int usb_create_pipe(usbdev_t *dev,int pipenum,int mps,int flags);
void usb_destroy_pipe(usbdev_t *dev,int pipenum);
int usb_set_address(usbdev_t *dev,int addr);
usbdev_t *usb_create_device(usbbus_t *bus,int lowspeed);
void usb_destroy_device(usbdev_t *dev);
usbreq_t *usb_make_request(usbdev_t *dev,int pipenum,uint8_t *buf,int length,int flags);
void usb_poll(usbbus_t *bus);
void usb_daemon(usbbus_t *bus);
int usb_cancel_request(usbreq_t *ur);
void usb_free_request(usbreq_t *ur);
int usb_queue_request(usbreq_t *ur);
int usb_wait_request(usbreq_t *ur);
int usb_sync_request(usbreq_t *ur);
int usb_get_descriptor(usbdev_t *dev,uint8_t reqtype,int dsctype,int dscidx,uint8_t *buffer,int buflen);
int usb_get_config_descriptor(usbdev_t *dev,usb_config_descr_t *dscr,int idx,int maxlen);
int usb_get_device_status(usbdev_t *dev,usb_device_status_t *status);
int usb_set_configuration(usbdev_t *dev,int config);
int usb_open_pipe(usbdev_t *dev,usb_endpoint_descr_t *epdesc);
int usb_simple_request(usbdev_t *dev,uint8_t reqtype,int bRequest,int wValue,int wIndex);
void usb_complete_request(usbreq_t *ur,int status);
int usb_get_device_descriptor(usbdev_t *dev,usb_device_descr_t *dscr,int smallflg);
int usb_set_ep0mps(usbdev_t *dev,int mps);
int usb_new_address(usbbus_t *bus);
int usb_get_string(usbdev_t *dev,int id,char *buf,int maxlen);
int usb_std_request(usbdev_t *dev,uint8_t bmRequestType,
			   uint8_t bRequest,uint16_t wValue,
		    uint16_t wIndex,uint8_t *buffer,int length);
void *usb_find_cfg_descr(usbdev_t *dev,int dtype,int idx);
void usb_delay_ms(usbbus_t *bus,int ms);
int usb_clear_stall(usbdev_t *dev,int pipe);

void usb_scan(usbbus_t *bus);
void usbhub_map_tree(usbbus_t *bus,int (*func)(usbdev_t *dev,void *arg),void *arg);
void usbhub_dumpbus(usbbus_t *bus,uint32_t verbose);

void usb_initroot(usbbus_t *bus);


/*  *********************************************************************
    *  Host Controller Driver
    *  Methods for abstracting the USB host controller from the 
    *  rest of the goop.
    ********************************************************************* */

struct usb_hcdrv_s {
    usbbus_t * (*hcdrv_create)(physaddr_t regaddr);
    void (*hcdrv_delete)(usbbus_t *);
    int (*hcdrv_start)(usbbus_t *);
    void (*hcdrv_stop)(usbbus_t *);
    int (*hcdrv_intr)(usbbus_t *);
    usb_ept_t * (*hcdrv_ept_create)(usbbus_t *,int usbaddr,int eptnum,int mps,int flags);
    void (*hcdrv_ept_delete)(usbbus_t *,usb_ept_t *);
    void (*hcdrv_ept_setmps)(usbbus_t *,usb_ept_t *,int mps);
    void (*hcdrv_ept_setaddr)(usbbus_t *,usb_ept_t *,int addr);
    void (*hcdrv_ept_cleartoggle)(usbbus_t *,usb_ept_t *);
    int (*hcdrv_xfer)(usbbus_t *,usb_ept_t *uept,usbreq_t *ur);
};

#define UBCREATE(driver,addr) (*((driver)->hcdrv_create))(addr)
#define UBDELETE(bus) (*((bus)->ub_hwdisp->hcdrv_delete))(bus)
#define UBSTART(bus) (*((bus)->ub_hwdisp->hcdrv_start))(bus)
#define UBSTOP(bus) (*((bus)->ub_hwdisp->hcdrv_stop))(bus)
#define UBINTR(bus) (*((bus)->ub_hwdisp->hcdrv_intr))(bus)
#define UBEPTCREATE(bus,addr,num,mps,flags) (*((bus)->ub_hwdisp->hcdrv_ept_create))(bus,addr,num,mps,flags)
#define UBEPTDELETE(bus,ept) (*((bus)->ub_hwdisp->hcdrv_ept_delete))(bus,ept)
#define UBEPTSETMPS(bus,ept,mps) (*((bus)->ub_hwdisp->hcdrv_ept_setmps))(bus,ept,mps)
#define UBEPTSETADDR(bus,ept,addr) (*((bus)->ub_hwdisp->hcdrv_ept_setaddr))(bus,ept,addr)
#define UBEPTCLEARTOGGLE(bus,ept) (*((bus)->ub_hwdisp->hcdrv_ept_cleartoggle))(bus,ept)
#define UBXFER(bus,ept,xfer) (*((bus)->ub_hwdisp->hcdrv_xfer))(bus,ept,xfer)

/*  *********************************************************************
    *  Devices - methods for abstracting things that _use_ USB
    *  (devices you can plug into the USB) - the entry points
    *  here are basically just for device discovery, since the top half
    *  of the actual driver will be device-specific.
    ********************************************************************* */

struct usb_driver_s {
    char *udrv_name;
    int (*udrv_attach)(usbdev_t *,usb_driver_t *);
    int (*udrv_detach)(usbdev_t *);
};

typedef struct usb_drvlist_s {
    int udl_class;
    int udl_vendor;
    int udl_product;
    usb_driver_t *udl_disp;
} usb_drvlist_t;

extern usb_driver_t *usb_find_driver(usbdev_t *dev);

#define CLASS_ANY	-1
#define VENDOR_ANY	-1
#define PRODUCT_ANY	-1

void mydelay(int x);

#define IS_HUB(dev) ((dev)->ud_devdescr.bDeviceClass == USB_DEVICE_CLASS_HUB)

/*  *********************************************************************
    *  Error codes
    ********************************************************************* */

#define USBD_ERR_OK		0		/* Request ok */
#define USBD_ERR_STALLED	-1		/* Endpoint is stalled */
#define USBD_ERR_IOERROR	-2		/* I/O error */
#define USBD_ERR_HWERROR	-3		/* Hardware failure */
#define USBD_ERR_CANCELED	-4		/* Request canceled */
#define USBD_ERR_NOMEM		-5		/* Out of memory */
#define USBD_ERR_TIMEOUT	-6		/* Request timeout */

/*  *********************************************************************
    *  Debug routines
    ********************************************************************* */

void usb_dbg_dumpportstatus(int port,usb_port_status_t *portstatus,int level);
void usb_dbg_dumpdescriptors(usbdev_t *dev,uint8_t *ptr,int len);
void usb_dbg_dumpcfgdescr(usbdev_t *dev);
void usb_dbg_dumpeptdescr(usb_endpoint_descr_t * epdscr);