1 /* usb.c - Generic USB interfaces. */
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/>.
23 #include <grub/misc.h>
25 static grub_usb_controller_dev_t grub_usb_list
;
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
)
37 /* Enable the ports of the USB Root Hub. */
38 grub_usb_root_hub (dev
);
43 usb
->next
= grub_usb_list
;
47 usb
->iterate (iterate_hook
);
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
)
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
)
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
))
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
,
106 grub_usb_set_configuration (grub_usb_device_t dev
, int configuration
)
110 for (i
= 0; i
< 16; i
++)
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
,
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
,
133 struct grub_usb_desc_endp
*
134 grub_usb_get_endpdescriptor (grub_usb_device_t usbdev
, int addr
)
138 for (i
= 0; i
< usbdev
->config
[0].descconf
->numif
; i
++)
140 struct grub_usb_desc_if
*interf
;
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
)
159 grub_usb_device_initialize (grub_usb_device_t dev
)
161 struct grub_usb_desc_device
*descdev
;
162 struct grub_usb_desc_config config
;
166 err
= grub_usb_get_descriptor (dev
, GRUB_USB_DESCRIPTOR_DEVICE
,
167 0, sizeof (struct grub_usb_desc_device
),
168 (char *) &dev
->descdev
);
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
++)
182 /* First just read the first 4 bytes of the configuration
183 descriptor, after that it is known how many bytes really have
185 err
= grub_usb_get_descriptor (dev
, GRUB_USB_DESCRIPTOR_CONFIG
, i
, 4,
188 data
= grub_malloc (config
.totallen
);
191 err
= GRUB_USB_ERR_INTERNAL
;
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
);
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
;
223 for (i
= 0; i
< 8; i
++)
224 grub_free (dev
->config
[i
].descconf
);