Merge branch 'acpi-ec'
authorRafael J. Wysocki <rafael.j.wysocki@intel.com>
Tue, 19 Nov 2013 00:06:06 +0000 (01:06 +0100)
committerRafael J. Wysocki <rafael.j.wysocki@intel.com>
Tue, 19 Nov 2013 00:06:06 +0000 (01:06 +0100)
* acpi-ec:
  ACPI / EC: Ensure lock is acquired before accessing ec struct members

1  2 
drivers/acpi/ec.c

diff --combined drivers/acpi/ec.c
index d5309fd494589b4d1596cb1c03576ed1e7ef252e,15986f32009ecf31f3d8e058c7a5d1170467c9db..ba5b56db9d27c7fafa3b19c6d1f5d2549308aea6
@@@ -28,7 -28,6 +28,7 @@@
  
  /* Uncomment next line to get verbose printout */
  /* #define DEBUG */
 +#define pr_fmt(fmt) "ACPI : EC: " fmt
  
  #include <linux/kernel.h>
  #include <linux/module.h>
@@@ -50,6 -49,9 +50,6 @@@
  #define ACPI_EC_DEVICE_NAME           "Embedded Controller"
  #define ACPI_EC_FILE_INFO             "info"
  
 -#undef PREFIX
 -#define PREFIX                                "ACPI: EC: "
 -
  /* EC status register */
  #define ACPI_EC_FLAG_OBF      0x01    /* Output buffer full */
  #define ACPI_EC_FLAG_IBF      0x02    /* Input buffer full */
@@@ -129,26 -131,26 +129,26 @@@ static int EC_FLAGS_SKIP_DSDT_SCAN; /* 
  static inline u8 acpi_ec_read_status(struct acpi_ec *ec)
  {
        u8 x = inb(ec->command_addr);
 -      pr_debug(PREFIX "---> status = 0x%2.2x\n", x);
 +      pr_debug("---> status = 0x%2.2x\n", x);
        return x;
  }
  
  static inline u8 acpi_ec_read_data(struct acpi_ec *ec)
  {
        u8 x = inb(ec->data_addr);
 -      pr_debug(PREFIX "---> data = 0x%2.2x\n", x);
 +      pr_debug("---> data = 0x%2.2x\n", x);
        return x;
  }
  
  static inline void acpi_ec_write_cmd(struct acpi_ec *ec, u8 command)
  {
 -      pr_debug(PREFIX "<--- command = 0x%2.2x\n", command);
 +      pr_debug("<--- command = 0x%2.2x\n", command);
        outb(command, ec->command_addr);
  }
  
  static inline void acpi_ec_write_data(struct acpi_ec *ec, u8 data)
  {
 -      pr_debug(PREFIX "<--- data = 0x%2.2x\n", data);
 +      pr_debug("<--- data = 0x%2.2x\n", data);
        outb(data, ec->data_addr);
  }
  
@@@ -173,9 -175,10 +173,10 @@@ static void start_transaction(struct ac
  static void advance_transaction(struct acpi_ec *ec, u8 status)
  {
        unsigned long flags;
-       struct transaction *t = ec->curr;
+       struct transaction *t;
  
        spin_lock_irqsave(&ec->lock, flags);
+       t = ec->curr;
        if (!t)
                goto unlock;
        if (t->wlen > t->wi) {
@@@ -239,7 -242,7 +240,7 @@@ static int ec_poll(struct acpi_ec *ec
                        }
                        advance_transaction(ec, acpi_ec_read_status(ec));
                } while (time_before(jiffies, delay));
 -              pr_debug(PREFIX "controller reset, restart transaction\n");
 +              pr_debug("controller reset, restart transaction\n");
                spin_lock_irqsave(&ec->lock, flags);
                start_transaction(ec);
                spin_unlock_irqrestore(&ec->lock, flags);
@@@ -307,12 -310,12 +308,12 @@@ static int acpi_ec_transaction(struct a
                }
        }
        if (ec_wait_ibf0(ec)) {
 -              pr_err(PREFIX "input buffer is not empty, "
 +              pr_err("input buffer is not empty, "
                                "aborting transaction\n");
                status = -ETIME;
                goto end;
        }
 -      pr_debug(PREFIX "transaction start (cmd=0x%02x, addr=0x%02x)\n",
 +      pr_debug("transaction start (cmd=0x%02x, addr=0x%02x)\n",
                        t->command, t->wdata ? t->wdata[0] : 0);
        /* disable GPE during transaction if storm is detected */
        if (test_bit(EC_FLAGS_GPE_STORM, &ec->flags)) {
                /* It is safe to enable the GPE outside of the transaction. */
                acpi_enable_gpe(NULL, ec->gpe);
        } else if (t->irq_count > ec_storm_threshold) {
 -              pr_info(PREFIX "GPE storm detected(%d GPEs), "
 +              pr_info("GPE storm detected(%d GPEs), "
                        "transactions will use polling mode\n",
                        t->irq_count);
                set_bit(EC_FLAGS_GPE_STORM, &ec->flags);
        }
 -      pr_debug(PREFIX "transaction end\n");
 +      pr_debug("transaction end\n");
  end:
        if (ec->global_lock)
                acpi_release_global_lock(glk);
@@@ -568,12 -571,12 +569,12 @@@ static void acpi_ec_run(void *cxt
        struct acpi_ec_query_handler *handler = cxt;
        if (!handler)
                return;
 -      pr_debug(PREFIX "start query execution\n");
 +      pr_debug("start query execution\n");
        if (handler->func)
                handler->func(handler->data);
        else if (handler->handle)
                acpi_evaluate_object(handler->handle, NULL, NULL, NULL);
 -      pr_debug(PREFIX "stop query execution\n");
 +      pr_debug("stop query execution\n");
        kfree(handler);
  }
  
@@@ -591,8 -594,7 +592,8 @@@ static int acpi_ec_sync_query(struct ac
                        if (!copy)
                                return -ENOMEM;
                        memcpy(copy, handler, sizeof(*copy));
 -                      pr_debug(PREFIX "push query execution (0x%2x) on queue\n", value);
 +                      pr_debug("push query execution (0x%2x) on queue\n",
 +                              value);
                        return acpi_os_execute((copy->func) ?
                                OSL_NOTIFY_HANDLER : OSL_GPE_HANDLER,
                                acpi_ec_run, copy);
@@@ -615,7 -617,7 +616,7 @@@ static int ec_check_sci(struct acpi_ec 
  {
        if (state & ACPI_EC_FLAG_SCI) {
                if (!test_and_set_bit(EC_FLAGS_QUERY_PENDING, &ec->flags)) {
 -                      pr_debug(PREFIX "push gpe query to the queue\n");
 +                      pr_debug("push gpe query to the queue\n");
                        return acpi_os_execute(OSL_NOTIFY_HANDLER,
                                acpi_ec_gpe_query, ec);
                }
@@@ -629,7 -631,7 +630,7 @@@ static u32 acpi_ec_gpe_handler(acpi_han
        struct acpi_ec *ec = data;
        u8 status = acpi_ec_read_status(ec);
  
 -      pr_debug(PREFIX "~~~> interrupt, status:0x%02x\n", status);
 +      pr_debug("~~~> interrupt, status:0x%02x\n", status);
  
        advance_transaction(ec, status);
        if (ec_transaction_done(ec) &&
@@@ -775,7 -777,7 +776,7 @@@ static int ec_install_handlers(struct a
                         * The AE_NOT_FOUND error will be ignored and OS
                         * continue to initialize EC.
                         */
 -                      printk(KERN_ERR "Fail in evaluating the _REG object"
 +                      pr_err("Fail in evaluating the _REG object"
                                " of EC device. Broken bios is suspected.\n");
                } else {
                        acpi_remove_gpe_handler(NULL, ec->gpe,
@@@ -794,10 -796,10 +795,10 @@@ static void ec_remove_handlers(struct a
        acpi_disable_gpe(NULL, ec->gpe);
        if (ACPI_FAILURE(acpi_remove_address_space_handler(ec->handle,
                                ACPI_ADR_SPACE_EC, &acpi_ec_space_handler)))
 -              pr_err(PREFIX "failed to remove space handler\n");
 +              pr_err("failed to remove space handler\n");
        if (ACPI_FAILURE(acpi_remove_gpe_handler(NULL, ec->gpe,
                                &acpi_ec_gpe_handler)))
 -              pr_err(PREFIX "failed to remove gpe handler\n");
 +              pr_err("failed to remove gpe handler\n");
        clear_bit(EC_FLAGS_HANDLERS_INSTALLED, &ec->flags);
  }
  
@@@ -839,7 -841,7 +840,7 @@@ static int acpi_ec_add(struct acpi_devi
        ret = !!request_region(ec->command_addr, 1, "EC cmd");
        WARN(!ret, "Could not request EC cmd io port 0x%lx", ec->command_addr);
  
 -      pr_info(PREFIX "GPE = 0x%lx, I/O: command/status = 0x%lx, data = 0x%lx\n",
 +      pr_info("GPE = 0x%lx, I/O: command/status = 0x%lx, data = 0x%lx\n",
                          ec->gpe, ec->command_addr, ec->data_addr);
  
        ret = ec_install_handlers(ec);
@@@ -930,7 -932,7 +931,7 @@@ static int ec_validate_ecdt(const struc
  /* MSI EC needs special treatment, enable it */
  static int ec_flag_msi(const struct dmi_system_id *id)
  {
 -      printk(KERN_DEBUG PREFIX "Detected MSI hardware, enabling workarounds.\n");
 +      pr_debug("Detected MSI hardware, enabling workarounds.\n");
        EC_FLAGS_MSI = 1;
        EC_FLAGS_VALIDATE_ECDT = 1;
        return 0;
@@@ -1009,7 -1011,7 +1010,7 @@@ int __init acpi_ec_ecdt_probe(void
        status = acpi_get_table(ACPI_SIG_ECDT, 1,
                                (struct acpi_table_header **)&ecdt_ptr);
        if (ACPI_SUCCESS(status)) {
 -              pr_info(PREFIX "EC description table is found, configuring boot EC\n");
 +              pr_info("EC description table is found, configuring boot EC\n");
                boot_ec->command_addr = ecdt_ptr->control.address;
                boot_ec->data_addr = ecdt_ptr->data.address;
                boot_ec->gpe = ecdt_ptr->gpe;
  
        /* This workaround is needed only on some broken machines,
         * which require early EC, but fail to provide ECDT */
 -      printk(KERN_DEBUG PREFIX "Look up EC in DSDT\n");
 +      pr_debug("Look up EC in DSDT\n");
        status = acpi_get_devices(ec_device_ids[0].id, ec_parse_device,
                                        boot_ec, NULL);
        /* Check that acpi_get_devices actually find something */
                    saved_ec->data_addr != boot_ec->data_addr ||
                    saved_ec->gpe != boot_ec->gpe ||
                    saved_ec->handle != boot_ec->handle)
 -                      pr_info(PREFIX "ASUSTek keeps feeding us with broken "
 +                      pr_info("ASUSTek keeps feeding us with broken "
                        "ECDT tables, which are very hard to workaround. "
                        "Trying to use DSDT EC info instead. Please send "
                        "output of acpidump to linux-acpi@vger.kernel.org\n");