From d5562777511a3718d43a03eb86954d06acd012ce Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Sun, 18 Jul 2010 21:35:22 +0200 Subject: [PATCH] Add possibility of bulk reading with short timeout --- bus/usb/ohci.c | 4 ++-- bus/usb/uhci.c | 5 +++-- bus/usb/usbtrans.c | 19 ++++++++++++++----- include/grub/usb.h | 8 +++++++- 4 files changed, 26 insertions(+), 10 deletions(-) diff --git a/bus/usb/ohci.c b/bus/usb/ohci.c index 57ca24065..73e3e01e8 100644 --- a/bus/usb/ohci.c +++ b/bus/usb/ohci.c @@ -654,7 +654,7 @@ grub_ohci_transaction (grub_ohci_td_t td, static grub_usb_err_t grub_ohci_transfer (grub_usb_controller_t dev, - grub_usb_transfer_t transfer) + grub_usb_transfer_t transfer, int timeout) { struct grub_ohci *o = (struct grub_ohci *) dev->data; grub_ohci_ed_t ed_virt; @@ -832,7 +832,7 @@ grub_ohci_transfer (grub_usb_controller_t dev, } /* Safety measure to avoid a hang. */ - maxtime = grub_get_time_ms () + 1000; + maxtime = grub_get_time_ms () + timeout; /* Wait until the transfer is completed or STALLs. */ do diff --git a/bus/usb/uhci.c b/bus/usb/uhci.c index 5b4432018..d211de369 100644 --- a/bus/usb/uhci.c +++ b/bus/usb/uhci.c @@ -436,7 +436,8 @@ grub_uhci_transaction (struct grub_uhci *u, unsigned int endp, static grub_usb_err_t grub_uhci_transfer (grub_usb_controller_t dev, - grub_usb_transfer_t transfer) + grub_usb_transfer_t transfer, + int timeout) { struct grub_uhci *u = (struct grub_uhci *) dev->data; grub_uhci_qh_t qh; @@ -496,7 +497,7 @@ grub_uhci_transfer (grub_usb_controller_t dev, /* Wait until either the transaction completed or an error occurred. */ - endtime = grub_get_time_ms () + 1000; + endtime = grub_get_time_ms () + timeout; for (;;) { grub_uhci_td_t errtd; diff --git a/bus/usb/usbtrans.c b/bus/usb/usbtrans.c index 4a55cab11..9dfef509f 100644 --- a/bus/usb/usbtrans.c +++ b/bus/usb/usbtrans.c @@ -145,7 +145,7 @@ grub_usb_control_msg (grub_usb_device_t dev, transfer->transactions[datablocks + 1].toggle = 1; - err = dev->controller.dev->transfer (&dev->controller, transfer); + err = dev->controller.dev->transfer (&dev->controller, transfer, 1000); grub_dprintf ("usb", "control: err=%d\n", err); grub_free (transfer->transactions); @@ -162,7 +162,7 @@ grub_usb_control_msg (grub_usb_device_t dev, static grub_usb_err_t grub_usb_bulk_readwrite (grub_usb_device_t dev, int endpoint, grub_size_t size0, char *data_in, - grub_transfer_type_t type) + grub_transfer_type_t type, int timeout) { int i; grub_usb_transfer_t transfer; @@ -243,7 +243,7 @@ grub_usb_bulk_readwrite (grub_usb_device_t dev, size -= tr->size; } - err = dev->controller.dev->transfer (&dev->controller, transfer); + err = dev->controller.dev->transfer (&dev->controller, transfer, timeout); /* We must remember proper toggle value even if some transactions * were not processed - correct value should be inversion of last * processed transaction (TD). */ @@ -269,7 +269,7 @@ grub_usb_bulk_write (grub_usb_device_t dev, int endpoint, grub_size_t size, char *data) { return grub_usb_bulk_readwrite (dev, endpoint, size, data, - GRUB_USB_TRANSFER_TYPE_OUT); + GRUB_USB_TRANSFER_TYPE_OUT, 1000); } grub_usb_err_t @@ -277,5 +277,14 @@ grub_usb_bulk_read (grub_usb_device_t dev, int endpoint, grub_size_t size, char *data) { return grub_usb_bulk_readwrite (dev, endpoint, size, data, - GRUB_USB_TRANSFER_TYPE_IN); + GRUB_USB_TRANSFER_TYPE_IN, 1000); +} + +grub_usb_err_t +grub_usb_bulk_read_timeout (grub_usb_device_t dev, + int endpoint, grub_size_t size, char *data, + int timeout) +{ + return grub_usb_bulk_readwrite (dev, endpoint, size, data, + GRUB_USB_TRANSFER_TYPE_IN, timeout); } diff --git a/include/grub/usb.h b/include/grub/usb.h index 595cbd6d3..aba2fccc7 100644 --- a/include/grub/usb.h +++ b/include/grub/usb.h @@ -50,6 +50,7 @@ typedef enum enum { + GRUB_USB_REQTYPE_CLASS_INTERFACE_OUT = 0x21, GRUB_USB_REQTYPE_VENDOR_OUT = 0x40 }; @@ -103,7 +104,8 @@ struct grub_usb_controller_dev int (*iterate) (int (*hook) (grub_usb_controller_t dev)); grub_usb_err_t (*transfer) (grub_usb_controller_t dev, - grub_usb_transfer_t transfer); + grub_usb_transfer_t transfer, + int timeout); int (*hubports) (grub_usb_controller_t dev); @@ -235,5 +237,9 @@ void grub_usb_unregister_attach_hook_class (struct grub_usb_attach_desc *desc); void grub_usb_poll_devices (void); void grub_usb_device_attach (grub_usb_device_t dev); +grub_usb_err_t +grub_usb_bulk_read_timeout (grub_usb_device_t dev, + int endpoint, grub_size_t size, char *data, + int timeout); #endif /* GRUB_USB_H */