diff options
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/block/efi-block-io.c | 17 | ||||
-rw-r--r-- | drivers/efi/efi-device.c | 10 | ||||
-rw-r--r-- | drivers/hw_random/Kconfig | 6 | ||||
-rw-r--r-- | drivers/mfd/superio.c | 2 | ||||
-rw-r--r-- | drivers/of/of_gpio.c | 6 | ||||
-rw-r--r-- | drivers/of/of_path.c | 2 | ||||
-rw-r--r-- | drivers/serial/efi-stdio.c | 78 | ||||
-rw-r--r-- | drivers/serial/efi-stdio.h | 58 | ||||
-rw-r--r-- | drivers/serial/serial_cadence.c | 2 | ||||
-rw-r--r-- | drivers/usb/storage/usb.c | 7 |
10 files changed, 160 insertions, 28 deletions
diff --git a/drivers/block/efi-block-io.c b/drivers/block/efi-block-io.c index d167d814c2..39dbfb0f7a 100644 --- a/drivers/block/efi-block-io.c +++ b/drivers/block/efi-block-io.c @@ -14,6 +14,7 @@ #include <disks.h> #include <efi/efi.h> #include <efi/efi-device.h> +#include <bootsource.h> #define EFI_BLOCK_IO_PROTOCOL_REVISION2 0x00020001 #define EFI_BLOCK_IO_PROTOCOL_REVISION3 ((2<<16) | (31)) @@ -145,6 +146,7 @@ static int is_bio_usbdev(struct efi_device *efidev) static int efi_bio_probe(struct efi_device *efidev) { int ret; + int instance; struct efi_bio_priv *priv; struct efi_block_io_media *media; @@ -159,10 +161,14 @@ static int efi_bio_probe(struct efi_device *efidev) efi_bio_print_info(priv); priv->dev = &efidev->dev; - if (is_bio_usbdev(efidev)) - priv->blk.cdev.name = xasprintf("usbdisk%d", cdev_find_free_index("usbdisk")); - else - priv->blk.cdev.name = xasprintf("disk%d", cdev_find_free_index("disk")); + if (is_bio_usbdev(efidev)) { + instance = cdev_find_free_index("usbdisk"); + priv->blk.cdev.name = xasprintf("usbdisk%d", instance); + } else { + instance = cdev_find_free_index("disk"); + priv->blk.cdev.name = xasprintf("disk%d", instance); + } + priv->blk.blockbits = ffs(media->block_size) - 1; priv->blk.num_blocks = media->last_block + 1; priv->blk.ops = &efi_bio_ops; @@ -174,6 +180,9 @@ static int efi_bio_probe(struct efi_device *efidev) if (ret) return ret; + if (efi_get_bootsource() == efidev) + bootsource_set_instance(instance); + parse_partition_table(&priv->blk); return 0; diff --git a/drivers/efi/efi-device.c b/drivers/efi/efi-device.c index 305d337aab..a1aac2dd31 100644 --- a/drivers/efi/efi-device.c +++ b/drivers/efi/efi-device.c @@ -311,7 +311,7 @@ static int efi_bus_match(struct device_d *dev, struct driver_d *drv) int i; for (i = 0; i < efidev->num_guids; i++) { - if (!memcmp(&efidrv->guid, &efidev->guids[i], sizeof(efi_guid_t))) { + if (!efi_guidcmp(efidrv->guid, efidev->guids[i])) { BS->handle_protocol(efidev->handle, &efidev->guids[i], &efidev->protocol); return 0; @@ -398,13 +398,19 @@ static int is_bio_usbdev(struct efi_device *efidev) return 0; } +static struct efi_device *bootdev; + +struct efi_device *efi_get_bootsource(void) +{ + return bootdev; +} + static void efi_set_bootsource(void) { enum bootsource src = BOOTSOURCE_UNKNOWN; int instance = BOOTSOURCE_INSTANCE_UNKNOWN; efi_handle_t *efi_parent; - struct efi_device *bootdev; if (!efi_loaded_image->parent_handle) goto out; diff --git a/drivers/hw_random/Kconfig b/drivers/hw_random/Kconfig index c57928204d..242a7ef278 100644 --- a/drivers/hw_random/Kconfig +++ b/drivers/hw_random/Kconfig @@ -15,11 +15,11 @@ config HWRNG_MXC_RNGC Generator hardware found on some Freescale i.MX processors. config HWRNG_DEV_RANDOM - tristate "Linux /dev/random and /dev/urandom RNG" + tristate "Linux /dev/urandom RNG" depends on SANDBOX default y help - This driver allows use of the host provided /dev/random - and /dev/urandom as barebox HWRNGs. + This driver allows use of the host provided /dev/urandom + as barebox HWRNGs. endif diff --git a/drivers/mfd/superio.c b/drivers/mfd/superio.c index 0f08d56cb3..12d74b40f6 100644 --- a/drivers/mfd/superio.c +++ b/drivers/mfd/superio.c @@ -88,7 +88,7 @@ void superio_chip_add(struct superio_chip *siochip) &superio_regmap_config); if (IS_ERR(regmap)) pr_warn("creating %s regmap failed: %s\n", - chipname, strerror(-PTR_ERR(regmap))); + chipname, strerrorp(regmap)); ret = regmap_register_cdev(regmap, chipname); if (ret) diff --git a/drivers/of/of_gpio.c b/drivers/of/of_gpio.c index 9a8331ed18..7cbeeaf69e 100644 --- a/drivers/of/of_gpio.c +++ b/drivers/of/of_gpio.c @@ -19,18 +19,20 @@ static void of_gpio_flags_quirks(struct device_node *np, (!(strcmp(propname, "enable-gpio") && strcmp(propname, "enable-gpios")) && of_device_is_compatible(np, "regulator-gpio")))) { + bool active_low = !of_property_read_bool(np, + "enable-active-high"); /* * The regulator GPIO handles are specified such that the * presence or absence of "enable-active-high" solely controls * the polarity of the GPIO line. Any phandle flags must * be actively ignored. */ - if (*flags & OF_GPIO_ACTIVE_LOW) { + if ((*flags & OF_GPIO_ACTIVE_LOW) && !active_low) { pr_warn("%s GPIO handle specifies active low - ignored\n", np->full_name); *flags &= ~OF_GPIO_ACTIVE_LOW; } - if (!of_property_read_bool(np, "enable-active-high")) + if (active_low) *flags |= OF_GPIO_ACTIVE_LOW; } } diff --git a/drivers/of/of_path.c b/drivers/of/of_path.c index f8bbf2cba1..5c3a020345 100644 --- a/drivers/of/of_path.c +++ b/drivers/of/of_path.c @@ -83,7 +83,7 @@ static int __of_find_path(struct device_node *node, const char *part, char **out } if (dev->bus && !dev->driver) - return -ENODEV; + return -EPROBE_DEFER; device_detect(dev); diff --git a/drivers/serial/efi-stdio.c b/drivers/serial/efi-stdio.c index 2ca89fa4f8..9e825181e6 100644 --- a/drivers/serial/efi-stdio.c +++ b/drivers/serial/efi-stdio.c @@ -26,6 +26,8 @@ #include <readkey.h> #include <linux/ctype.h> #include <efi/efi.h> +#include <efi/efi-device.h> +#include "efi-stdio.h" #define EFI_SHIFT_STATE_VALID 0x80000000 #define EFI_RIGHT_CONTROL_PRESSED 0x00000004 @@ -71,6 +73,7 @@ struct efi_console_priv { struct efi_simple_text_output_protocol *out; struct efi_simple_input_interface *in; + struct efi_simple_text_input_ex_protocol *inex; struct console_device cdev; int lastkey; u16 efi_console_buffer[CONFIG_CBSIZE]; @@ -105,35 +108,72 @@ static struct efi_ctrlkey ctrlkeys[] = { { 0x17, 27 /* escape key */ }, }; +static int xlate_keypress(struct efi_input_key *k) +{ + int i; + + /* 32 bit modifier keys + 16 bit scan code + 16 bit unicode */ + for (i = 0; i < ARRAY_SIZE(ctrlkeys); i++) { + if (ctrlkeys[i].scan_code == k->scan_code) + return ctrlkeys[i].bb_key; + + } + + return k->unicode_char & 0xff; +} + static int efi_read_key(struct efi_console_priv *priv, bool wait) { unsigned long index; efi_status_t efiret; - struct efi_input_key k; - int i; + struct efi_key_data kd; /* wait until key is pressed */ if (wait) BS->wait_for_event(1, priv->in->wait_for_key, &index); - efiret = priv->in->read_key_stroke(efi_sys_table->con_in, &k); - if (EFI_ERROR(efiret)) - return -efi_errno(efiret); + if (priv->inex) { + efiret = priv->inex->read_key_stroke_ex(priv->inex, &kd); - /* 32 bit modifier keys + 16 bit scan code + 16 bit unicode */ - for (i = 0; i < ARRAY_SIZE(ctrlkeys); i++) { - if (ctrlkeys[i].scan_code == k.scan_code) - return ctrlkeys[i].bb_key; + if (efiret == EFI_NOT_READY) + return -EAGAIN; + + if (!EFI_ERROR(efiret)) { + if ((kd.state.shift_state & EFI_SHIFT_STATE_VALID) && + (kd.state.shift_state & EFI_CONTROL_PRESSED)) { + int ch = tolower(kd.key.unicode_char & 0xff); + + if (isalpha(ch)) + return CHAR_CTRL(ch); + if (ch == '\0') /* ctrl is pressed on its own */ + return -EAGAIN; + } + + if (kd.key.unicode_char || kd.key.scan_code) + return xlate_keypress(&kd.key); + /* Some broken firmwares offer simple_text_input_ex_protocol, + * but never handle any key. Treat those as if + * read_key_stroke_ex failed and fall through + * to the basic simple_text_input_protocol. + */ + dev_dbg(priv->cdev.dev, "Falling back to simple_text_input_protocol\n"); + } } - return k.unicode_char & 0xff; + efiret = priv->in->read_key_stroke(priv->in, &kd.key); + + if (EFI_ERROR(efiret)) + return -efi_errno(efiret); + + return xlate_keypress(&kd.key); } static void efi_console_putc(struct console_device *cdev, char c) { uint16_t str[2] = {}; - struct efi_simple_text_output_protocol *con_out = efi_sys_table->con_out; + struct efi_console_priv *priv = to_efi(cdev); + struct efi_simple_text_output_protocol *con_out = priv->out; str[0] = c; @@ -331,8 +371,12 @@ static void efi_set_mode(struct efi_console_priv *priv) static int efi_console_probe(struct device_d *dev) { + efi_guid_t inex_guid = EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL_GUID; + struct efi_simple_text_input_ex_protocol *inex; struct console_device *cdev; struct efi_console_priv *priv; + efi_status_t efiret; + int i; priv = xzalloc(sizeof(*priv)); @@ -340,6 +384,18 @@ static int efi_console_probe(struct device_d *dev) priv->out = efi_sys_table->con_out; priv->in = efi_sys_table->con_in; + efiret = BS->open_protocol((void *)efi_sys_table->con_in_handle, + &inex_guid, + (void **)&inex, + efi_parent_image, + 0, + EFI_OPEN_PROTOCOL_GET_PROTOCOL); + + if (!EFI_ERROR(efiret)) { + priv->inex = inex; + dev_dbg(dev, "Using simple_text_input_ex_protocol\n"); + } + priv->current_color = EFI_WHITE; efi_set_mode(priv); diff --git a/drivers/serial/efi-stdio.h b/drivers/serial/efi-stdio.h new file mode 100644 index 0000000000..1fa417c706 --- /dev/null +++ b/drivers/serial/efi-stdio.h @@ -0,0 +1,58 @@ +#ifndef EFI_STDIO_H_ +#define EFI_STDIO_H_ + +#include <efi.h> + +struct efi_simple_text_input_ex_protocol; + +typedef efi_status_t (EFIAPI *efi_input_reset_ex)( + struct efi_simple_text_input_ex_protocol *this, + efi_bool_t extended_verification +); + +struct efi_key_state { + u32 shift_state; + u8 toggle_state; +}; + +struct efi_key_data { + struct efi_input_key key; + struct efi_key_state state; +}; + +typedef efi_status_t (EFIAPI *efi_input_read_key_ex)( + struct efi_simple_text_input_ex_protocol *this, + struct efi_key_data *keydata +); + +typedef efi_status_t (EFIAPI *efi_set_state)( + struct efi_simple_text_input_ex_protocol *this, + u8 *key_toggle_state +); + +typedef efi_status_t (EFIAPI *efi_key_notify_function)( + struct efi_key_data *keydata +); + +typedef efi_status_t (EFIAPI *efi_register_keystroke_notify)( + struct efi_simple_text_input_ex_protocol *this, + struct efi_key_data keydata, + efi_key_notify_function key_notification_function, + void **notify_handle +); + +typedef efi_status_t (EFIAPI *efi_unregister_keystroke_notify)( + struct efi_simple_text_input_ex_protocol *this, + void *notification_handle +); + +struct efi_simple_text_input_ex_protocol { + efi_input_reset_ex reset; + efi_input_read_key_ex read_key_stroke_ex; + void *wait_for_key_ex; + efi_set_state set_state; + efi_register_keystroke_notify register_key_notify; + efi_unregister_keystroke_notify unregister_key_notify; +}; + +#endif diff --git a/drivers/serial/serial_cadence.c b/drivers/serial/serial_cadence.c index 0501c400b1..6454888e3c 100644 --- a/drivers/serial/serial_cadence.c +++ b/drivers/serial/serial_cadence.c @@ -199,7 +199,7 @@ static void cadence_serial_flush(struct console_device *cdev) struct cadence_serial_priv, cdev); while ((readl(priv->regs + CADENCE_UART_CHANNEL_STS) & - CADENCE_STS_TEMPTY) != 0) + CADENCE_STS_TEMPTY) == 0) ; } diff --git a/drivers/usb/storage/usb.c b/drivers/usb/storage/usb.c index 63d624e91b..e0ef4f5ef3 100644 --- a/drivers/usb/storage/usb.c +++ b/drivers/usb/storage/usb.c @@ -87,8 +87,7 @@ static int usb_stor_transport(struct us_blk_dev *usb_blkdev, struct device_d *dev = &us->pusb_dev->dev; int i, ret; - - for (i = 0; i < retries; i++) { + for (i = 0; i <= retries; i++) { dev_dbg(dev, "%s\n", usb_stor_opcode_name(cmd[0])); ret = us->transport(usb_blkdev, cmd, cmdlen, data, datalen); dev_dbg(dev, "%s returns %d\n", usb_stor_opcode_name(cmd[0]), @@ -105,6 +104,8 @@ static int usb_stor_transport(struct us_blk_dev *usb_blkdev, mdelay(request_sense_delay_ms); } + dev_dbg(dev, "Retried %s %d times, and failed.\n", usb_stor_opcode_name(cmd[0]), retries); + return -EIO; } @@ -194,7 +195,7 @@ static int usb_stor_io_10(struct us_blk_dev *usb_blkdev, u8 opcode, put_unaligned_be16(blocks, &cmd[7]); return usb_stor_transport(usb_blkdev, cmd, sizeof(cmd), data, - blocks * SECTOR_SIZE, 2, 0); + blocks * SECTOR_SIZE, 10, 0); } /*********************************************************************** |