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