From: Vladimir 'phcoder' Serbinenko Date: Wed, 1 Feb 2012 13:30:40 +0000 (+0100) Subject: merge mainline into cbi X-Git-Tag: 2.00~725^2 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=d68538e928c11110a867db0da33bbead76b95513;p=thirdparty%2Fgrub.git merge mainline into cbi --- d68538e928c11110a867db0da33bbead76b95513 diff --cc grub-core/disk/usbms.c index 2bff40117,e264c464c..52cc33e93 --- a/grub-core/disk/usbms.c +++ b/grub-core/disk/usbms.c @@@ -24,14 -24,10 +24,16 @@@ #include #include + GRUB_MOD_LICENSE ("GPLv3+"); + #define GRUB_USBMS_DIRECTION_BIT 7 +/* Length of CBI command should be always 12 bytes */ +#define GRUB_USBMS_CBI_CMD_SIZE 12 +/* CBI class-specific USB request ADSC - it sends CBI (scsi) command to + * device in DATA stage */ +#define GRUB_USBMS_CBI_ADSC_REQ 0x00 + /* The USB Mass Storage Command Block Wrapper. */ struct grub_usbms_cbw { @@@ -75,52 -70,15 +77,56 @@@ static grub_usbms_dev_t grub_usbms_devi static int first_available_slot = 0; static grub_err_t -grub_usbms_reset (grub_usb_device_t dev, int interface) +grub_usbms_cbi_cmd (grub_usb_device_t dev, int interface, + grub_uint8_t *cbicb) +{ + return grub_usb_control_msg (dev, + GRUB_USB_REQTYPE_CLASS_INTERFACE_OUT, + GRUB_USBMS_CBI_ADSC_REQ, 0, interface, + GRUB_USBMS_CBI_CMD_SIZE, (char*)cbicb); +} + +static grub_err_t +grub_usbms_cbi_reset (grub_usb_device_t dev, int interface) +{ + /* Prepare array with Command Block Reset (=CBR) */ + /* CBI specific communication reset command should be send to device + * via CBI USB class specific request ADCS */ + struct grub_cbi_reset + { + grub_uint8_t opcode; /* 0x1d = SEND DIAGNOSTIC */ + grub_uint8_t lun; /* 7-5 LUN, 4-0 flags - for CBR always = 0x04 */ + grub_uint8_t pad[10]; + /* XXX: There is collision between CBI and UFI specifications: + * CBI says 0xff, UFI says 0x00 ... probably it does + * not matter ... (?) */ + } cbicb = { 0x1d, 0x04, + { 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff } + }; + + return grub_usbms_cbi_cmd (dev, interface, (grub_uint8_t *)&cbicb); +} + +static grub_err_t +grub_usbms_bo_reset (grub_usb_device_t dev, int interface) { - return grub_usb_control_msg (dev, 0x21, 255, 0, interface, 0, 0); + grub_usb_err_t u; + u = grub_usb_control_msg (dev, 0x21, 255, 0, interface, 0, 0); + if (u) + return grub_error (GRUB_ERR_IO, "USB error %d", u); + return GRUB_ERR_NONE; } +static grub_err_t +grub_usbms_reset (grub_usbms_dev_t dev) +{ + if (dev->protocol == GRUB_USBMS_PROTOCOL_BULK) + return grub_usbms_bo_reset (dev->dev, dev->interface); + else + return grub_usbms_cbi_reset (dev->dev, dev->interface); +} + static void grub_usbms_detach (grub_usb_device_t usbdev, int config, int interface) {