Some hotplug support (buggy)
This commit is contained in:
parent
5434f8bf3a
commit
f5db3949e7
4 changed files with 117 additions and 25 deletions
|
@ -24,6 +24,7 @@
|
||||||
#include <grub/list.h>
|
#include <grub/list.h>
|
||||||
|
|
||||||
static grub_usb_controller_dev_t grub_usb_list;
|
static grub_usb_controller_dev_t grub_usb_list;
|
||||||
|
struct grub_usb_attach_desc *attach_hooks;
|
||||||
|
|
||||||
void
|
void
|
||||||
grub_usb_controller_dev_register (grub_usb_controller_dev_t usb)
|
grub_usb_controller_dev_register (grub_usb_controller_dev_t usb)
|
||||||
|
@ -224,6 +225,25 @@ grub_usb_device_initialize (grub_usb_device_t dev)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* 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;
|
return GRUB_USB_ERR_NONE;
|
||||||
|
|
||||||
fail:
|
fail:
|
||||||
|
@ -234,8 +254,6 @@ grub_usb_device_initialize (grub_usb_device_t dev)
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct grub_usb_attach_desc *attach_hooks;
|
|
||||||
|
|
||||||
void
|
void
|
||||||
grub_usb_register_attach_hook_class (struct grub_usb_attach_desc *desc)
|
grub_usb_register_attach_hook_class (struct grub_usb_attach_desc *desc)
|
||||||
{
|
{
|
||||||
|
|
113
bus/usb/usbhub.c
113
bus/usb/usbhub.c
|
@ -21,10 +21,22 @@
|
||||||
#include <grub/mm.h>
|
#include <grub/mm.h>
|
||||||
#include <grub/usb.h>
|
#include <grub/usb.h>
|
||||||
#include <grub/misc.h>
|
#include <grub/misc.h>
|
||||||
|
#include <grub/time.h>
|
||||||
|
|
||||||
/* USB Supports 127 devices, with device 0 as special case. */
|
/* USB Supports 127 devices, with device 0 as special case. */
|
||||||
static struct grub_usb_device *grub_usb_devs[128];
|
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
|
/* Add a device that currently has device number 0 and resides on
|
||||||
CONTROLLER, the Hub reported that the device speed is SPEED. */
|
CONTROLLER, the Hub reported that the device speed is SPEED. */
|
||||||
static grub_usb_device_t
|
static grub_usb_device_t
|
||||||
|
@ -137,43 +149,98 @@ grub_usb_add_hub (grub_usb_device_t dev)
|
||||||
return GRUB_ERR_NONE;
|
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_err_t
|
||||||
grub_usb_root_hub (grub_usb_controller_t controller)
|
grub_usb_root_hub (grub_usb_controller_t controller)
|
||||||
{
|
{
|
||||||
grub_err_t err;
|
|
||||||
int ports;
|
|
||||||
int i;
|
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. */
|
/* 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);
|
||||||
for (i = 0; i < ports; i++)
|
if (!hub->speed)
|
||||||
{
|
{
|
||||||
grub_usb_speed_t speed = controller->dev->detect_dev (controller, i);
|
grub_free (hub);
|
||||||
|
return GRUB_USB_ERR_INTERNAL;
|
||||||
|
}
|
||||||
|
|
||||||
if (speed != GRUB_USB_SPEED_NONE)
|
for (i = 0; i < hub->nports; i++)
|
||||||
{
|
{
|
||||||
grub_usb_device_t dev;
|
hub->speed[i] = controller->dev->detect_dev (hub->controller, i);
|
||||||
|
|
||||||
/* Enable the port. */
|
if (hub->speed[i] != GRUB_USB_SPEED_NONE)
|
||||||
err = controller->dev->portstatus (controller, i, 1);
|
attach_root_port (hub->controller, i, hub->speed[i]);
|
||||||
if (err)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
/* Enable the port and create a device. */
|
|
||||||
dev = grub_usb_hub_add_dev (controller, speed);
|
|
||||||
if (! dev)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
/* If the device is a Hub, scan it for more devices. */
|
|
||||||
if (dev->descdev.class == 0x09)
|
|
||||||
grub_usb_add_hub (dev);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return GRUB_USB_ERR_NONE;
|
return GRUB_USB_ERR_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_speed_t speed;
|
||||||
|
|
||||||
|
speed = hub->controller->dev->detect_dev (hub->controller, i);
|
||||||
|
|
||||||
|
if (speed == hub->speed[i])
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (hub->speed[i] == GRUB_USB_SPEED_NONE
|
||||||
|
&& speed != GRUB_USB_SPEED_NONE)
|
||||||
|
attach_root_port (hub->controller, i, speed);
|
||||||
|
hub->speed[i] = speed;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
grub_usb_iterate (int (*hook) (grub_usb_device_t dev))
|
grub_usb_iterate (int (*hook) (grub_usb_device_t dev))
|
||||||
{
|
{
|
||||||
|
|
|
@ -209,6 +209,8 @@ grub_usbms_iterate (int (*hook) (const char *name, int luns))
|
||||||
{
|
{
|
||||||
unsigned i;
|
unsigned i;
|
||||||
|
|
||||||
|
grub_usb_poll_devices ();
|
||||||
|
|
||||||
for (i = 0; i < ARRAY_SIZE (grub_usbms_devices); i++)
|
for (i = 0; i < ARRAY_SIZE (grub_usbms_devices); i++)
|
||||||
if (grub_usbms_devices[i])
|
if (grub_usbms_devices[i])
|
||||||
{
|
{
|
||||||
|
@ -389,6 +391,9 @@ grub_usbms_open (const char *name, struct grub_scsi *scsi)
|
||||||
"not a USB Mass Storage device");
|
"not a USB Mass Storage device");
|
||||||
|
|
||||||
devnum = grub_strtoul (name + 3, NULL, 10);
|
devnum = grub_strtoul (name + 3, NULL, 10);
|
||||||
|
|
||||||
|
grub_usb_poll_devices ();
|
||||||
|
|
||||||
if (!grub_usbms_devices[devnum])
|
if (!grub_usbms_devices[devnum])
|
||||||
return grub_error (GRUB_ERR_UNKNOWN_DEVICE,
|
return grub_error (GRUB_ERR_UNKNOWN_DEVICE,
|
||||||
"not a USB Mass Storage device");
|
"not a USB Mass Storage device");
|
||||||
|
|
|
@ -227,4 +227,6 @@ struct grub_usb_attach_desc
|
||||||
void grub_usb_register_attach_hook_class (struct grub_usb_attach_desc *desc);
|
void grub_usb_register_attach_hook_class (struct grub_usb_attach_desc *desc);
|
||||||
void grub_usb_unregister_attach_hook_class (struct grub_usb_attach_desc *desc);
|
void grub_usb_unregister_attach_hook_class (struct grub_usb_attach_desc *desc);
|
||||||
|
|
||||||
|
void grub_usb_poll_devices (void);
|
||||||
|
|
||||||
#endif /* GRUB_USB_H */
|
#endif /* GRUB_USB_H */
|
||||||
|
|
Loading…
Reference in a new issue