GRUB-1.98 changes
[grub2/jjazz.git] / bus / usb / usb.c
blob8289185da67da45cf6df8ddb6d561768d7247bc3
1 /* usb.c - Generic USB interfaces. */
2 /*
3 * GRUB -- GRand Unified Bootloader
4 * Copyright (C) 2008 Free Software Foundation, Inc.
6 * GRUB is free software: you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation, either version 3 of the License, or
9 * (at your option) any later version.
11 * GRUB is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with GRUB. If not, see <http://www.gnu.org/licenses/>.
20 #include <grub/dl.h>
21 #include <grub/mm.h>
22 #include <grub/usb.h>
23 #include <grub/misc.h>
25 static grub_usb_controller_dev_t grub_usb_list;
27 void
28 grub_usb_controller_dev_register (grub_usb_controller_dev_t usb)
30 auto int iterate_hook (grub_usb_controller_t dev);
32 /* Iterate over all controllers found by the driver. */
33 int iterate_hook (grub_usb_controller_t dev)
35 dev->dev = usb;
37 /* Enable the ports of the USB Root Hub. */
38 grub_usb_root_hub (dev);
40 return 0;
43 usb->next = grub_usb_list;
44 grub_usb_list = usb;
46 if (usb->iterate)
47 usb->iterate (iterate_hook);
50 void
51 grub_usb_controller_dev_unregister (grub_usb_controller_dev_t usb)
53 grub_usb_controller_dev_t *p, q;
55 for (p = &grub_usb_list, q = *p; q; p = &(q->next), q = q->next)
56 if (q == usb)
58 *p = q->next;
59 break;
63 #if 0
64 int
65 grub_usb_controller_iterate (int (*hook) (grub_usb_controller_t dev))
67 grub_usb_controller_dev_t p;
69 auto int iterate_hook (grub_usb_controller_t dev);
71 int iterate_hook (grub_usb_controller_t dev)
73 dev->dev = p;
74 if (hook (dev))
75 return 1;
76 return 0;
79 /* Iterate over all controller drivers. */
80 for (p = grub_usb_list; p; p = p->next)
82 /* Iterate over the busses of the controllers. XXX: Actually, a
83 hub driver should do this. */
84 if (p->iterate (iterate_hook))
85 return 1;
88 return 0;
90 #endif
93 grub_usb_err_t
94 grub_usb_clear_halt (grub_usb_device_t dev, int endpoint)
96 dev->toggle[endpoint] = 0;
97 return grub_usb_control_msg (dev, (GRUB_USB_REQTYPE_OUT
98 | GRUB_USB_REQTYPE_STANDARD
99 | GRUB_USB_REQTYPE_TARGET_ENDP),
100 GRUB_USB_REQ_CLEAR_FEATURE,
101 GRUB_USB_FEATURE_ENDP_HALT,
102 endpoint, 0, 0);
105 grub_usb_err_t
106 grub_usb_set_configuration (grub_usb_device_t dev, int configuration)
108 int i;
110 for (i = 0; i < 16; i++)
111 dev->toggle[i] = 0;
113 return grub_usb_control_msg (dev, (GRUB_USB_REQTYPE_OUT
114 | GRUB_USB_REQTYPE_STANDARD
115 | GRUB_USB_REQTYPE_TARGET_DEV),
116 GRUB_USB_REQ_SET_CONFIGURATION, configuration,
117 0, 0, NULL);
120 grub_usb_err_t
121 grub_usb_get_descriptor (grub_usb_device_t dev,
122 grub_uint8_t type, grub_uint8_t index,
123 grub_size_t size, char *data)
125 return grub_usb_control_msg (dev, (GRUB_USB_REQTYPE_IN
126 | GRUB_USB_REQTYPE_STANDARD
127 | GRUB_USB_REQTYPE_TARGET_DEV),
128 GRUB_USB_REQ_GET_DESCRIPTOR,
129 (type << 8) | index,
130 0, size, data);
133 struct grub_usb_desc_endp *
134 grub_usb_get_endpdescriptor (grub_usb_device_t usbdev, int addr)
136 int i;
138 for (i = 0; i < usbdev->config[0].descconf->numif; i++)
140 struct grub_usb_desc_if *interf;
141 int j;
143 interf = usbdev->config[0].interf[i].descif;
145 for (j = 0; j < interf->endpointcnt; j++)
147 struct grub_usb_desc_endp *endp;
148 endp = &usbdev->config[0].interf[i].descendp[j];
150 if (endp->endp_addr == addr)
151 return endp;
155 return NULL;
158 grub_usb_err_t
159 grub_usb_device_initialize (grub_usb_device_t dev)
161 struct grub_usb_desc_device *descdev;
162 struct grub_usb_desc_config config;
163 grub_usb_err_t err;
164 int i;
166 err = grub_usb_get_descriptor (dev, GRUB_USB_DESCRIPTOR_DEVICE,
167 0, sizeof (struct grub_usb_desc_device),
168 (char *) &dev->descdev);
169 if (err)
170 return err;
171 descdev = &dev->descdev;
173 for (i = 0; i < 8; i++)
174 dev->config[i].descconf = NULL;
176 for (i = 0; i < descdev->configcnt; i++)
178 int pos;
179 int currif;
180 char *data;
182 /* First just read the first 4 bytes of the configuration
183 descriptor, after that it is known how many bytes really have
184 to be read. */
185 err = grub_usb_get_descriptor (dev, GRUB_USB_DESCRIPTOR_CONFIG, i, 4,
186 (char *) &config);
188 data = grub_malloc (config.totallen);
189 if (! data)
191 err = GRUB_USB_ERR_INTERNAL;
192 goto fail;
195 dev->config[i].descconf = (struct grub_usb_desc_config *) data;
196 err = grub_usb_get_descriptor (dev, GRUB_USB_DESCRIPTOR_CONFIG, i,
197 config.totallen, data);
198 if (err)
199 goto fail;
201 /* Skip the configuration descriptor. */
202 pos = sizeof (struct grub_usb_desc_config);
204 /* Read all interfaces. */
205 for (currif = 0; currif < dev->config[i].descconf->numif; currif++)
207 dev->config[i].interf[currif].descif
208 = (struct grub_usb_desc_if *) &data[pos];
209 pos += sizeof (struct grub_usb_desc_if);
211 /* Point to the first endpoint. */
212 dev->config[i].interf[currif].descendp
213 = (struct grub_usb_desc_endp *) &data[pos];
214 pos += (sizeof (struct grub_usb_desc_endp)
215 * dev->config[i].interf[currif].descif->endpointcnt);
219 return GRUB_USB_ERR_NONE;
221 fail:
223 for (i = 0; i < 8; i++)
224 grub_free (dev->config[i].descconf);
226 return err;