#include <grub/list.h>
static grub_usb_controller_dev_t grub_usb_list;
+struct grub_usb_attach_desc *attach_hooks;
void
grub_usb_controller_dev_register (grub_usb_controller_dev_t usb)
}
}
+ /* XXX: Just check configuration 0 for now. */
+ for (i = 0; i < dev->config[0].descconf->numif; i++)
+ {
+ struct grub_usb_desc_if *interf;
+ struct grub_usb_attach_desc *desc;
+
+ interf = dev->config[0].interf[i].descif;
+
+ grub_dprintf ("usb", "iterate: interf=%d, class=%d, subclass=%d, protocol=%d\n",
+ i, interf->class, interf->subclass, interf->protocol);
+
+ if (dev->config[0].interf[i].attached)
+ continue;
+
+ for (desc = attach_hooks; desc; desc = desc->next)
+ if (interf->class == desc->class && desc->hook (dev, 0, i))
+ dev->config[0].interf[i].attached = 1;
+ }
+
return GRUB_USB_ERR_NONE;
fail:
return err;
}
-struct grub_usb_attach_desc *attach_hooks;
-
void
grub_usb_register_attach_hook_class (struct grub_usb_attach_desc *desc)
{
#include <grub/mm.h>
#include <grub/usb.h>
#include <grub/misc.h>
+#include <grub/time.h>
/* USB Supports 127 devices, with device 0 as special case. */
static struct grub_usb_device *grub_usb_devs[128];
+struct grub_usb_hub
+{
+ struct grub_usb_hub *next;
+ grub_usb_controller_t controller;
+ int nports;
+ grub_usb_speed_t *speed;
+ grub_usb_device_t dev;
+};
+
+struct grub_usb_hub *hubs;
+
/* Add a device that currently has device number 0 and resides on
CONTROLLER, the Hub reported that the device speed is SPEED. */
static grub_usb_device_t
return GRUB_ERR_NONE;
}
+static void
+attach_root_port (grub_usb_controller_t controller, int portno,
+ grub_usb_speed_t speed)
+{
+ grub_usb_device_t dev;
+ grub_err_t err;
+
+ /* Enable the port. */
+ err = controller->dev->portstatus (controller, portno, 0);
+ if (err)
+ return;
+
+ /* Enable the port. */
+ err = controller->dev->portstatus (controller, portno, 1);
+ if (err)
+ return;
+
+ /* Enable the port and create a device. */
+ dev = grub_usb_hub_add_dev (controller, speed);
+ if (! dev)
+ return;
+
+ /* If the device is a Hub, scan it for more devices. */
+ if (dev->descdev.class == 0x09)
+ grub_usb_add_hub (dev);
+}
+
grub_usb_err_t
grub_usb_root_hub (grub_usb_controller_t controller)
{
- grub_err_t err;
- int ports;
int i;
+ struct grub_usb_hub *hub;
+
+ hub = grub_malloc (sizeof (*hub));
+ if (!hub)
+ return GRUB_USB_ERR_INTERNAL;
+
+ hub->next = hubs;
+ hubs = hub;
+ hub->controller = grub_malloc (sizeof (*controller));
+ if (!hub->controller)
+ return GRUB_USB_ERR_INTERNAL;
+
+ grub_memcpy (hub->controller, controller, sizeof (*controller));
+ hub->dev = 0;
/* Query the number of ports the root Hub has. */
- ports = controller->dev->hubports (controller);
+ hub->nports = controller->dev->hubports (controller);
+ hub->speed = grub_malloc (sizeof (hub->speed[0]) * hub->nports);
+ if (!hub->speed)
+ {
+ grub_free (hub);
+ return GRUB_USB_ERR_INTERNAL;
+ }
- for (i = 0; i < ports; i++)
+ for (i = 0; i < hub->nports; i++)
{
- grub_usb_speed_t speed = controller->dev->detect_dev (controller, i);
+ hub->speed[i] = controller->dev->detect_dev (hub->controller, i);
+
+ if (hub->speed[i] != GRUB_USB_SPEED_NONE)
+ attach_root_port (hub->controller, i, hub->speed[i]);
+ }
+
+ return GRUB_USB_ERR_NONE;
+}
- if (speed != GRUB_USB_SPEED_NONE)
+void
+grub_usb_poll_devices (void)
+{
+ struct grub_usb_hub *hub;
+
+ for (hub = hubs; hub; hub = hub->next)
+ {
+ int i;
+ /* Do we have to recheck number of ports? */
+ for (i = 0; i < hub->nports; i++)
{
- grub_usb_device_t dev;
+ grub_usb_speed_t speed;
- /* Enable the port. */
- err = controller->dev->portstatus (controller, i, 1);
- if (err)
- continue;
+ speed = hub->controller->dev->detect_dev (hub->controller, i);
- /* Enable the port and create a device. */
- dev = grub_usb_hub_add_dev (controller, speed);
- if (! dev)
+ if (speed == hub->speed[i])
continue;
- /* If the device is a Hub, scan it for more devices. */
- if (dev->descdev.class == 0x09)
- grub_usb_add_hub (dev);
+ if (hub->speed[i] == GRUB_USB_SPEED_NONE
+ && speed != GRUB_USB_SPEED_NONE)
+ attach_root_port (hub->controller, i, speed);
+ hub->speed[i] = speed;
}
}
-
- return GRUB_USB_ERR_NONE;
}
int