5 * Copyright (C) 2009 Pawel Dziepak
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License along
18 * with this program; if not, write to the Free Software Foundation, Inc.,
19 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
27 #include "manes/manec.h"
29 using namespace resources
;
33 bool usb::init_bus(p
<device
> dev
) {
34 host
= dev
.cast
<usb_hc
>();
39 host
->scan_bus(delegate
<void, int>::method(this, &usb::device_connected
));
44 int usb::get_count() {
49 #define GET_DESCRIPTOR 6
50 #define GET_CONFIGURATION 8
51 #define SET_CONFIGURATION 9
53 void usb::device_connected(int port
) {
56 /* Get device descriptor */
58 setup
.bmRequestType
= 0x80;
59 setup
.bRequest
= GET_DESCRIPTOR
;
60 setup
.wValue
= 1 << 8;
64 device_descriptor
*dev
= (device_descriptor
*)host
->control_transfer(pid_setup
, &setup
, sizeof(usb_setup_data
), sizeof(device_descriptor
),0);
66 u8 addr
= host
->get_free_address();
68 /* Set device address */
69 setup
.bmRequestType
= 0;
70 setup
.bRequest
= SET_ADDRESS
;
75 host
->control_transfer(pid_setup
, &setup
, sizeof(usb_setup_data
), 0,0);
77 /* Get device descriptor */
78 setup
.bmRequestType
= 0x80;
79 setup
.bRequest
= GET_DESCRIPTOR
;
80 setup
.wValue
= 1 << 8;
84 dev
= (device_descriptor
*)host
->control_transfer(pid_setup
, &setup
, sizeof(usb_setup_data
), sizeof(device_descriptor
),addr
);
86 /* Get configuration descriptor */
87 setup
.bmRequestType
= 0x80;
88 setup
.bRequest
= GET_DESCRIPTOR
;
89 setup
.wValue
= 2 << 8;
92 configuration_descriptor
*conf
= (configuration_descriptor
*)host
->control_transfer(pid_setup
, &setup
, sizeof(usb_setup_data
), 0x20/* sizeof(configuration_descriptor)*/, addr
);
94 p
<usb_did
> id
= new usb_did(this, addr
, (interface_descriptor
*)((unsigned int)conf
+ conf
->bLength
));
95 endpoint_descriptor
*endp
= (endpoint_descriptor
*)((unsigned int)conf
+ conf
->bLength
+ 9);
101 while (endp
->bDescriptorType
== 5) {
102 if (endp
->bmAttributes
!= 2)
105 if (endp
->bEndpointAddress
& 0x80)
106 read_ep
= endp
->bEndpointAddress
& ~0x80;
108 write_ep
= endp
->bEndpointAddress
;
113 id
->set_endps(control_ep
, read_ep
, write_ep
);
115 __asm__
__volatile__("cli\nhlt"::"a"(conf
),"b"(write_ep
),"c"(read_ep
));
119 void usb::set_conf(int addr
) {
120 usb_setup_data setup
;
121 setup
.bmRequestType
= 0;
122 setup
.bRequest
= SET_CONFIGURATION
;
127 host
->control_transfer(pid_setup
, &setup
, sizeof(usb_setup_data
), 0, addr
);
130 void usb::register_type() {
131 manes::manec::get()->register_type
<usb
>("usb", "pci");