|
|
1.1 root 1: // Main code for handling USB controllers and devices.
2: //
3: // Copyright (C) 2009 Kevin O'Connor <[email protected]>
4: //
5: // This file may be distributed under the terms of the GNU LGPLv3 license.
6:
7: #include "util.h" // dprintf
8: #include "pci.h" // foreachpci
9: #include "config.h" // CONFIG_*
10: #include "pci_regs.h" // PCI_CLASS_REVISION
11: #include "pci_ids.h" // PCI_CLASS_SERIAL_USB_UHCI
12: #include "usb-uhci.h" // uhci_init
13: #include "usb-ohci.h" // ohci_init
14: #include "usb-hid.h" // usb_keyboard_setup
15: #include "usb.h" // struct usb_s
16: #include "biosvar.h" // GET_GLOBAL
17:
18: struct usb_s USBControllers[16] VAR16VISIBLE;
19:
20: static int
21: send_control(u32 endp, int dir, const void *cmd, int cmdsize
22: , void *data, int datasize)
23: {
24: struct usb_s *cntl = endp2cntl(endp);
25: switch (cntl->type) {
26: default:
27: case USB_TYPE_UHCI:
28: return uhci_control(endp, dir, cmd, cmdsize, data, datasize);
29: case USB_TYPE_OHCI:
30: return ohci_control(endp, dir, cmd, cmdsize, data, datasize);
31: }
32: }
33:
34: struct usb_pipe *
35: alloc_intr_pipe(u32 endp, int period)
36: {
37: struct usb_s *cntl = endp2cntl(endp);
38: switch (cntl->type) {
39: default:
40: case USB_TYPE_UHCI:
41: return uhci_alloc_intr_pipe(endp, period);
42: case USB_TYPE_OHCI:
43: return ohci_alloc_intr_pipe(endp, period);
44: }
45: }
46:
47: int
48: usb_poll_intr(struct usb_pipe *pipe, void *data)
49: {
50: u32 endp = GET_FLATPTR(pipe->endp);
51: struct usb_s *cntl = endp2cntl(endp);
52: switch (GET_GLOBAL(cntl->type)) {
53: default:
54: case USB_TYPE_UHCI:
55: return uhci_poll_intr(pipe, data);
56: case USB_TYPE_OHCI:
57: return ohci_poll_intr(pipe, data);
58: }
59: }
60:
61: int
62: send_default_control(u32 endp, const struct usb_ctrlrequest *req, void *data)
63: {
64: return send_control(endp, req->bRequestType & USB_DIR_IN
65: , req, sizeof(*req), data, req->wLength);
66: }
67:
68: // Get the first 8 bytes of the device descriptor.
69: static int
70: get_device_info8(struct usb_device_descriptor *dinfo, u32 endp)
71: {
72: struct usb_ctrlrequest req;
73: req.bRequestType = USB_DIR_IN | USB_TYPE_STANDARD | USB_RECIP_DEVICE;
74: req.bRequest = USB_REQ_GET_DESCRIPTOR;
75: req.wValue = USB_DT_DEVICE<<8;
76: req.wIndex = 0;
77: req.wLength = 8;
78: return send_default_control(endp, &req, dinfo);
79: }
80:
81: static struct usb_config_descriptor *
82: get_device_config(u32 endp)
83: {
84: struct usb_config_descriptor cfg;
85:
86: struct usb_ctrlrequest req;
87: req.bRequestType = USB_DIR_IN | USB_TYPE_STANDARD | USB_RECIP_DEVICE;
88: req.bRequest = USB_REQ_GET_DESCRIPTOR;
89: req.wValue = USB_DT_CONFIG<<8;
90: req.wIndex = 0;
91: req.wLength = sizeof(cfg);
92: int ret = send_default_control(endp, &req, &cfg);
93: if (ret)
94: return NULL;
95:
96: void *config = malloc_tmphigh(cfg.wTotalLength);
97: if (!config)
98: return NULL;
99: req.wLength = cfg.wTotalLength;
100: ret = send_default_control(endp, &req, config);
101: if (ret)
102: return NULL;
103: //hexdump(config, cfg.wTotalLength);
104: return config;
105: }
106:
107: static u32
108: set_address(u32 endp)
109: {
110: dprintf(3, "set_address %x\n", endp);
111: struct usb_s *cntl = endp2cntl(endp);
112: if (cntl->maxaddr >= USB_MAXADDR)
113: return 0;
114:
115: struct usb_ctrlrequest req;
116: req.bRequestType = USB_DIR_OUT | USB_TYPE_STANDARD | USB_RECIP_DEVICE;
117: req.bRequest = USB_REQ_SET_ADDRESS;
118: req.wValue = cntl->maxaddr + 1;
119: req.wIndex = 0;
120: req.wLength = 0;
121: int ret = send_default_control(endp, &req, NULL);
122: if (ret)
123: return 0;
124: msleep(2);
125:
126: cntl->maxaddr++;
127: return mkendp(cntl, cntl->maxaddr, 0, endp2speed(endp), endp2maxsize(endp));
128: }
129:
130: static int
131: set_configuration(u32 endp, u16 val)
132: {
133: struct usb_ctrlrequest req;
134: req.bRequestType = USB_DIR_OUT | USB_TYPE_STANDARD | USB_RECIP_DEVICE;
135: req.bRequest = USB_REQ_SET_CONFIGURATION;
136: req.wValue = val;
137: req.wIndex = 0;
138: req.wLength = 0;
139: return send_default_control(endp, &req, NULL);
140: }
141:
142: // Called for every found device - see if a driver is available for
143: // this device and do setup if so.
144: int
145: configure_usb_device(struct usb_s *cntl, int lowspeed)
146: {
147: dprintf(1, "config_usb: %p %d\n", cntl, lowspeed);
148:
149: // Get device info
150: u32 endp = mkendp(cntl, 0, 0, lowspeed, 8);
151: struct usb_device_descriptor dinfo;
152: int ret = get_device_info8(&dinfo, endp);
153: if (ret)
154: return 0;
155: dprintf(3, "device rev=%04x cls=%02x sub=%02x proto=%02x size=%02x\n"
156: , dinfo.bcdUSB, dinfo.bDeviceClass, dinfo.bDeviceSubClass
157: , dinfo.bDeviceProtocol, dinfo.bMaxPacketSize0);
158: if (dinfo.bMaxPacketSize0 < 8 || dinfo.bMaxPacketSize0 > 64)
159: return 0;
160: endp = mkendp(cntl, 0, 0, lowspeed, dinfo.bMaxPacketSize0);
161:
162: // Get configuration
163: struct usb_config_descriptor *config = get_device_config(endp);
164: if (!config)
165: return 0;
166:
167: // Determine if a driver exists for this device - only look at the
168: // first interface of the first configuration.
169: struct usb_interface_descriptor *iface = (void*)(&config[1]);
170: if (iface->bInterfaceClass != USB_CLASS_HID
171: || iface->bInterfaceSubClass != USB_INTERFACE_SUBCLASS_BOOT
172: || iface->bInterfaceProtocol != USB_INTERFACE_PROTOCOL_KEYBOARD)
173: // Not a "boot" keyboard
174: goto fail;
175:
176: // Set the address and configure device.
177: endp = set_address(endp);
178: if (!endp)
179: goto fail;
180: ret = set_configuration(endp, config->bConfigurationValue);
181: if (ret)
182: goto fail;
183:
184: // Configure driver.
185: ret = usb_keyboard_init(endp, iface, ((void*)config + config->wTotalLength
186: - (void*)iface));
187: if (ret)
188: goto fail;
189:
190: free(config);
191: return 1;
192: fail:
193: free(config);
194: return 0;
195: }
196:
197: void
198: usb_setup()
199: {
200: if (! CONFIG_USB)
201: return;
202:
203: dprintf(3, "init usb\n");
204:
205: usb_keyboard_setup();
206:
207: // Look for USB controllers
208: int count = 0;
209: int bdf, max;
210: foreachpci(bdf, max) {
211: u32 code = pci_config_readl(bdf, PCI_CLASS_REVISION) >> 8;
212:
213: if (code >> 8 != PCI_CLASS_SERIAL_USB)
214: continue;
215:
216: struct usb_s *cntl = &USBControllers[count];
217: cntl->bdf = bdf;
218:
219: if (code == PCI_CLASS_SERIAL_USB_UHCI)
220: run_thread(uhci_init, cntl);
221: else if (code == PCI_CLASS_SERIAL_USB_OHCI)
222: run_thread(ohci_init, cntl);
223: else
224: continue;
225:
226: count++;
227: if (count >= ARRAY_SIZE(USBControllers))
228: break;
229: }
230: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.