4 * Copyright (c) 2005 Fabrice Bellard
6 * Permission is hereby granted, free of charge, to any person obtaining a copy
7 * of this software and associated documentation files (the "Software"), to deal
8 * in the Software without restriction, including without limitation the rights
9 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 * copies of the Software, and to permit persons to whom the Software is
11 * furnished to do so, subject to the following conditions:
13 * The above copyright notice and this permission notice shall be included in
14 * all copies or substantial portions of the Software.
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
26 void usb_attach(USBPort
*port
, USBDevice
*dev
)
28 port
->attach(port
, dev
);
31 /**********************/
32 /* generic USB device helpers (you are not forced to use them when
33 writing your USB device driver, but they help handling the
37 #define SETUP_STATE_IDLE 0
38 #define SETUP_STATE_DATA 1
39 #define SETUP_STATE_ACK 2
41 int usb_generic_handle_packet(USBDevice
*s
, USBPacket
*p
)
45 uint8_t *data
= p
->data
;
49 s
->state
= USB_STATE_ATTACHED
;
52 s
->state
= USB_STATE_NOTATTACHED
;
57 s
->state
= USB_STATE_DEFAULT
;
61 if (s
->state
< USB_STATE_DEFAULT
|| p
->devaddr
!= s
->addr
)
65 memcpy(s
->setup_buf
, data
, 8);
66 s
->setup_len
= (s
->setup_buf
[7] << 8) | s
->setup_buf
[6];
68 if (s
->setup_buf
[0] & USB_DIR_IN
) {
69 ret
= s
->handle_control(s
,
70 (s
->setup_buf
[0] << 8) | s
->setup_buf
[1],
71 (s
->setup_buf
[3] << 8) | s
->setup_buf
[2],
72 (s
->setup_buf
[5] << 8) | s
->setup_buf
[4],
77 if (ret
< s
->setup_len
)
79 s
->setup_state
= SETUP_STATE_DATA
;
81 if (s
->setup_len
== 0)
82 s
->setup_state
= SETUP_STATE_ACK
;
84 s
->setup_state
= SETUP_STATE_DATA
;
88 if (s
->state
< USB_STATE_DEFAULT
|| p
->devaddr
!= s
->addr
)
92 switch(s
->setup_state
) {
94 if (!(s
->setup_buf
[0] & USB_DIR_IN
)) {
95 s
->setup_state
= SETUP_STATE_IDLE
;
96 ret
= s
->handle_control(s
,
97 (s
->setup_buf
[0] << 8) | s
->setup_buf
[1],
98 (s
->setup_buf
[3] << 8) | s
->setup_buf
[2],
99 (s
->setup_buf
[5] << 8) | s
->setup_buf
[4],
108 case SETUP_STATE_DATA
:
109 if (s
->setup_buf
[0] & USB_DIR_IN
) {
110 l
= s
->setup_len
- s
->setup_index
;
113 memcpy(data
, s
->data_buf
+ s
->setup_index
, l
);
115 if (s
->setup_index
>= s
->setup_len
)
116 s
->setup_state
= SETUP_STATE_ACK
;
119 s
->setup_state
= SETUP_STATE_IDLE
;
128 ret
= s
->handle_data(s
, p
);
133 if (s
->state
< USB_STATE_DEFAULT
|| p
->devaddr
!= s
->addr
)
134 return USB_RET_NODEV
;
137 switch(s
->setup_state
) {
138 case SETUP_STATE_ACK
:
139 if (s
->setup_buf
[0] & USB_DIR_IN
) {
140 s
->setup_state
= SETUP_STATE_IDLE
;
143 /* ignore additional output */
146 case SETUP_STATE_DATA
:
147 if (!(s
->setup_buf
[0] & USB_DIR_IN
)) {
148 l
= s
->setup_len
- s
->setup_index
;
151 memcpy(s
->data_buf
+ s
->setup_index
, data
, l
);
153 if (s
->setup_index
>= s
->setup_len
)
154 s
->setup_state
= SETUP_STATE_ACK
;
157 s
->setup_state
= SETUP_STATE_IDLE
;
166 ret
= s
->handle_data(s
, p
);
178 /* XXX: fix overflow */
179 int set_usb_string(uint8_t *buf
, const char *str
)
188 for(i
= 0; i
< len
; i
++) {
195 /* Send an internal message to a USB device. */
196 void usb_send_msg(USBDevice
*dev
, int msg
)
199 memset(&p
, 0, sizeof(p
));
201 dev
->handle_packet(dev
, &p
);