/* usb.c -- libusb USB support for GRUB. */ /* * GRUB -- GRand Unified Bootloader * Copyright (C) 2008 Free Software Foundation, Inc. * * GRUB is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * GRUB is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with GRUB. If not, see . */ #include #include #include #include #include #include static struct grub_usb_controller_dev usb_controller = { .name = "libusb" }; static struct grub_usb_device *grub_usb_devs[128]; struct usb_bus *busses; static grub_err_t grub_libusb_devices (void) { struct usb_bus *bus; int last = 0; busses = usb_get_busses(); for (bus = busses; bus; bus = bus->next) { struct usb_device *usbdev; struct grub_usb_device *dev; for (usbdev = bus->devices; usbdev; usbdev = usbdev->next) { struct usb_device_descriptor *desc = &usbdev->descriptor; grub_err_t err; if (! desc->bcdUSB) continue; dev = grub_malloc (sizeof (*dev)); if (! dev) return grub_errno; dev->data = usbdev; /* Fill in all descriptors. */ err = grub_usb_device_initialize (dev); if (err) { grub_errno = GRUB_ERR_NONE; continue; } /* Register the device. */ grub_usb_devs[last++] = dev; } } return GRUB_USB_ERR_NONE; } int grub_usb_iterate (int (*hook) (grub_usb_device_t dev)) { int i; for (i = 0; i < 128; i++) { if (grub_usb_devs[i]) { if (hook (grub_usb_devs[i])) return 1; } } return 0; } grub_usb_err_t grub_usb_root_hub (grub_usb_controller_t controller __attribute__((unused))) { return GRUB_USB_ERR_NONE; } grub_usb_err_t grub_usb_control_msg (grub_usb_device_t dev, grub_uint8_t reqtype, grub_uint8_t request, grub_uint16_t value, grub_uint16_t index, grub_size_t size, char *data) { usb_dev_handle *devh; struct usb_device *d = dev->data; devh = usb_open (d); if (usb_control_msg (devh, reqtype, request, value, index, data, size, 20) < 0) { usb_close (devh); return GRUB_USB_ERR_STALL; } usb_close (devh); return GRUB_USB_ERR_NONE; } grub_usb_err_t grub_usb_bulk_read (grub_usb_device_t dev, int endpoint, grub_size_t size, char *data) { usb_dev_handle *devh; struct usb_device *d = dev->data; devh = usb_open (d); if (usb_claim_interface (devh, 0) < 1) { usb_close (devh); return GRUB_USB_ERR_STALL; } if (usb_bulk_read (devh, endpoint, data, size, 20) < 1) { usb_close (devh); return GRUB_USB_ERR_STALL; } usb_release_interface (devh, 0); usb_close (devh); return GRUB_USB_ERR_NONE; } grub_usb_err_t grub_usb_bulk_write (grub_usb_device_t dev, int endpoint, grub_size_t size, char *data) { usb_dev_handle *devh; struct usb_device *d = dev->data; devh = usb_open (d); if (usb_claim_interface (devh, 0) < 0) goto fail; if (usb_bulk_write (devh, endpoint, data, size, 20) < 0) goto fail; if (usb_release_interface (devh, 0) < 0) goto fail; usb_close (devh); return GRUB_USB_ERR_NONE; fail: usb_close (devh); return GRUB_USB_ERR_STALL; } GRUB_MOD_INIT (libusb) { usb_init(); usb_find_busses(); usb_find_devices(); if (grub_libusb_devices ()) return; grub_usb_controller_dev_register (&usb_controller); return; } GRUB_MOD_FINI (libusb) { return; }