41
55
dev->controller = *controller;
42
56
dev->speed = speed;
44
grub_usb_device_initialize (dev);
58
err = grub_usb_device_initialize (dev);
46
65
/* Assign a new address to the device. */
47
for (i = 1; i < 128; i++)
66
for (i = 1; i < GRUB_USBHUB_MAX_DEVICES; i++)
49
68
if (! grub_usb_devs[i])
71
if (i == GRUB_USBHUB_MAX_DEVICES)
54
73
grub_error (GRUB_ERR_IO, "can't assign address to USB device");
74
for (i = 0; i < 8; i++)
75
grub_free (dev->config[i].descconf);
58
grub_usb_control_msg (dev,
60
| GRUB_USB_REQTYPE_STANDARD
61
| GRUB_USB_REQTYPE_TARGET_DEV),
62
GRUB_USB_REQ_SET_ADDRESS,
80
err = grub_usb_control_msg (dev,
82
| GRUB_USB_REQTYPE_STANDARD
83
| GRUB_USB_REQTYPE_TARGET_DEV),
84
GRUB_USB_REQ_SET_ADDRESS,
88
for (i = 0; i < 8; i++)
89
grub_free (dev->config[i].descconf);
66
95
dev->initialized = 1;
67
96
grub_usb_devs[i] = dev;
98
/* Wait "recovery interval", spec. says 2ms */
101
grub_usb_device_attach (dev);
196
245
return GRUB_ERR_NONE;
249
attach_root_port (grub_usb_controller_t controller, int portno,
250
grub_usb_speed_t speed)
252
grub_usb_device_t dev;
255
/* Disable the port. XXX: Why? */
256
err = controller->dev->portstatus (controller, portno, 0);
260
/* Enable the port. */
261
err = controller->dev->portstatus (controller, portno, 1);
265
/* Enable the port and create a device. */
266
dev = grub_usb_hub_add_dev (controller, speed);
270
/* If the device is a Hub, scan it for more devices. */
271
if (dev->descdev.class == 0x09)
272
grub_usb_add_hub (dev);
200
276
grub_usb_root_hub (grub_usb_controller_t controller)
279
struct grub_usb_hub *hub;
282
hub = grub_malloc (sizeof (*hub));
284
return GRUB_USB_ERR_INTERNAL;
288
hub->controller = grub_malloc (sizeof (*controller));
289
if (!hub->controller)
292
return GRUB_USB_ERR_INTERNAL;
295
grub_memcpy (hub->controller, controller, sizeof (*controller));
206
298
/* Query the number of ports the root Hub has. */
207
ports = controller->dev->hubports (controller);
209
for (i = 0; i < ports; i++)
211
grub_usb_speed_t speed = controller->dev->detect_dev (controller, i);
213
if (speed != GRUB_USB_SPEED_NONE)
215
grub_usb_device_t dev;
217
/* Enable the port. */
218
err = controller->dev->portstatus (controller, i, 1);
222
/* Enable the port and create a device. */
223
dev = grub_usb_hub_add_dev (controller, speed);
227
/* If the device is a Hub, scan it for more devices. */
228
if (dev->descdev.class == 0x09)
229
grub_usb_add_hub (dev);
299
hub->nports = controller->dev->hubports (controller);
300
hub->speed = grub_malloc (sizeof (hub->speed[0]) * hub->nports);
303
grub_free (hub->controller);
305
return GRUB_USB_ERR_INTERNAL;
308
for (i = 0; i < hub->nports; i++)
310
hub->speed[i] = controller->dev->detect_dev (hub->controller, i,
313
if (hub->speed[i] != GRUB_USB_SPEED_NONE)
314
attach_root_port (hub->controller, i, hub->speed[i]);
233
317
return GRUB_USB_ERR_NONE;
321
poll_nonroot_hub (grub_usb_device_t dev)
323
struct grub_usb_usb_hubdesc hubdesc;
326
grub_uint64_t timeout;
327
grub_usb_device_t next_dev;
329
err = grub_usb_control_msg (dev, (GRUB_USB_REQTYPE_IN
330
| GRUB_USB_REQTYPE_CLASS
331
| GRUB_USB_REQTYPE_TARGET_DEV),
332
GRUB_USB_REQ_GET_DESCRIPTOR,
333
(GRUB_USB_DESCRIPTOR_HUB << 8) | 0,
334
0, sizeof (hubdesc), (char *) &hubdesc);
338
/* Iterate over the Hub ports. */
339
for (i = 1; i <= hubdesc.portcnt; i++)
341
grub_uint32_t status;
343
/* Get the port status. */
344
err = grub_usb_control_msg (dev, (GRUB_USB_REQTYPE_IN
345
| GRUB_USB_REQTYPE_CLASS
346
| GRUB_USB_REQTYPE_TARGET_OTHER),
347
GRUB_USB_REQ_GET_STATUS,
348
0, i, sizeof (status), (char *) &status);
349
/* Just ignore the device if the Hub does not report the
354
/* Connected and status of connection changed ? */
355
if ((status & GRUB_USB_HUB_STATUS_CONNECTED)
356
&& (status & GRUB_USB_HUB_STATUS_C_CONNECTED))
358
grub_usb_speed_t speed;
360
/* Determine the device speed. */
361
if (status & GRUB_USB_HUB_STATUS_LOWSPEED)
362
speed = GRUB_USB_SPEED_LOW;
365
if (status & GRUB_USB_HUB_STATUS_HIGHSPEED)
366
speed = GRUB_USB_SPEED_HIGH;
368
speed = GRUB_USB_SPEED_FULL;
371
/* A device is actually connected to this port.
372
* Now do reset of port. */
373
err = grub_usb_control_msg (dev, (GRUB_USB_REQTYPE_OUT
374
| GRUB_USB_REQTYPE_CLASS
375
| GRUB_USB_REQTYPE_TARGET_OTHER),
376
GRUB_USB_REQ_SET_FEATURE,
377
GRUB_USB_HUB_FEATURE_PORT_RESET,
379
/* If the Hub does not cooperate for this port, just skip
384
/* Wait for reset procedure done */
385
timeout = grub_get_time_ms () + 1000;
388
/* Get the port status. */
389
err = grub_usb_control_msg (dev, (GRUB_USB_REQTYPE_IN
390
| GRUB_USB_REQTYPE_CLASS
391
| GRUB_USB_REQTYPE_TARGET_OTHER),
392
GRUB_USB_REQ_GET_STATUS,
393
0, i, sizeof (status), (char *) &status);
396
!(status & GRUB_USB_HUB_STATUS_C_PORT_RESET) &&
397
(grub_get_time_ms() < timeout) );
398
if (err || !(status & GRUB_USB_HUB_STATUS_C_PORT_RESET) )
401
/* Wait a recovery time after reset, spec. says 10ms */
402
grub_millisleep (10);
404
/* Do reset of connection change bit */
405
err = grub_usb_control_msg (dev, (GRUB_USB_REQTYPE_OUT
406
| GRUB_USB_REQTYPE_CLASS
407
| GRUB_USB_REQTYPE_TARGET_OTHER),
408
GRUB_USB_REQ_CLEAR_FEATURE,
409
GRUB_USB_HUB_FEATURE_C_CONNECTED,
411
/* Just ignore the device if the Hub reports some error */
415
/* Add the device and assign a device address to it. */
416
next_dev = grub_usb_hub_add_dev (&dev->controller, speed);
420
/* If the device is a Hub, scan it for more devices. */
421
if (next_dev->descdev.class == 0x09)
422
grub_usb_add_hub (next_dev);
430
grub_usb_poll_devices (void)
432
struct grub_usb_hub *hub;
435
for (hub = hubs; hub; hub = hub->next)
438
/* Do we have to recheck number of ports? */
439
/* No, it should be never changed, it should be constant. */
440
for (i = 0; i < hub->nports; i++)
442
grub_usb_speed_t speed;
444
speed = hub->controller->dev->detect_dev (hub->controller, i,
447
if (speed != GRUB_USB_SPEED_NONE)
450
attach_root_port (hub->controller, i, speed);
453
/* XXX: There should be also handling
454
* of disconnected devices. */
456
hub->speed[i] = speed;
460
/* We should check changes of non-root hubs too. */
461
for (i = 0; i < GRUB_USBHUB_MAX_DEVICES; i++)
463
grub_usb_device_t dev = grub_usb_devs[i];
465
if (dev && dev->descdev.class == 0x09)
467
poll_nonroot_hub (dev);
237
474
grub_usb_iterate (int (*hook) (grub_usb_device_t dev))
241
for (i = 0; i < 128; i++)
478
for (i = 0; i < GRUB_USBHUB_MAX_DEVICES; i++)
243
480
if (grub_usb_devs[i])