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 string
usb::get_dev_string(int index
, int addr
) {
58 setup
.bmRequestType
= 0x80;
59 setup
.bRequest
= GET_DESCRIPTOR
;
60 setup
.wValue
= 3 << 8 | index
;
63 int size
= *(char*)host
->control_transfer(pid_setup
, &setup
, sizeof(usb_setup_data
), 1, addr
);
66 char *bytes
= (char*)host
->control_transfer(pid_setup
, &setup
, sizeof(usb_setup_data
), size
, addr
);
69 return string::from_utf16(bytes
);
72 void usb::device_connected(int port
) {
75 /* Get device descriptor */
77 setup
.bmRequestType
= 0x80;
78 setup
.bRequest
= GET_DESCRIPTOR
;
79 setup
.wValue
= 1 << 8;
83 device_descriptor
*dev
= (device_descriptor
*)host
->control_transfer(pid_setup
, &setup
, sizeof(usb_setup_data
), sizeof(device_descriptor
),0);
85 u8 addr
= host
->get_free_address();
87 /* Set device address */
88 setup
.bmRequestType
= 0;
89 setup
.bRequest
= SET_ADDRESS
;
94 host
->control_transfer(pid_setup
, &setup
, sizeof(usb_setup_data
), 0,0);
96 /* Get device descriptor */
97 setup
.bmRequestType
= 0x80;
98 setup
.bRequest
= GET_DESCRIPTOR
;
99 setup
.wValue
= 1 << 8;
103 dev
= (device_descriptor
*)host
->control_transfer(pid_setup
, &setup
, sizeof(usb_setup_data
), sizeof(device_descriptor
),addr
);
104 get_dev_string(dev
->iProduct
, addr
);
106 /* Get configuration descriptor */
107 setup
.bmRequestType
= 0x80;
108 setup
.bRequest
= GET_DESCRIPTOR
;
109 setup
.wValue
= 2 << 8;
111 setup
.wLength
= 0x20;
112 configuration_descriptor
*conf
= (configuration_descriptor
*)host
->control_transfer(pid_setup
, &setup
, sizeof(usb_setup_data
), 0x20/* sizeof(configuration_descriptor)*/, addr
);
114 p
<usb_did
> id
= new usb_did(this, addr
, (interface_descriptor
*)((unsigned int)conf
+ conf
->bLength
));
115 endpoint_descriptor
*endp
= (endpoint_descriptor
*)((unsigned int)conf
+ conf
->bLength
+ 9);
121 while (endp
->bDescriptorType
== 5) {
122 if (endp
->bmAttributes
!= 2)
125 if (endp
->bEndpointAddress
& 0x80)
126 read_ep
= endp
->bEndpointAddress
& ~0x80;
128 write_ep
= endp
->bEndpointAddress
;
133 id
->set_endps(control_ep
, read_ep
, write_ep
);
134 id
->set_conf(conf
->bConfigurationValue
);
136 __asm__
__volatile__("cli\nhlt"::"a"(conf
),"b"(write_ep
),"c"(read_ep
));
140 void usb::set_conf(int addr
, int conf
) {
141 usb_setup_data setup
;
142 setup
.bmRequestType
= 0;
143 setup
.bRequest
= SET_CONFIGURATION
;
148 host
->control_transfer(pid_setup
, &setup
, sizeof(usb_setup_data
), 0, addr
);
151 void usb::register_type() {
152 manes::manec::get()->register_type
<usb
>("usb", "pci");