https://bugzilla.kernel.org/show_bug.cgi?id=59911

           Summary: acpi ec write ec ram fail
           Product: ACPI
           Version: 2.5
    Kernel Version: 3.9.4
          Platform: All
        OS/Version: Linux
              Tree: Mainline
            Status: NEW
          Severity: normal
          Priority: P1
         Component: EC
        AssignedTo: acpi...@kernel-bugs.osdl.org
        ReportedBy: tank.xu...@gmail.com
        Regression: No


I run a long run test on ubuntu linux, this test will call ACPI method to write
EC RAM through ACPI EC write command(0x81). At the fail case, ACPI EC write
transaction is done, but the EC RAM data is no change.
Write EC Ram flow:
step 1. write 0x81 to port 66
step 2. write address byte to port 62
step 3. write data byte to port 62

The fail transaction cases can be grouped into 2 classes:
1. the time interval between step 1 and 2 is shorter than 10 us
2. the time interval between step 2 and 3 is shorter than 10 us

For the successful transaction cases, the time interval between 1 and 2 and 3
is longer than 100 us.

fail case 1:
Jun  6 15:55:10 barton-A24J kernel: [  377.863077] Barton EC write command
=0x81
Jun  6 15:55:10 barton-A24J kernel: [  377.863086] Barton EC write data = 0x1c
Jun  6 15:55:10 barton-A24J kernel: [  377.864948] Barton EC read status = 0x0
Jun  6 15:55:10 barton-A24J kernel: [  377.864951] Barton EC write data = 0x7
Jun  6 15:55:10 barton-A24J kernel: [  377.864982] Barton EC read status = 0x2
Jun  6 15:55:10 barton-A24J kernel: [  377.866706] Barton EC read status = 0x0

fail case 2:
Jun  7 13:44:35 barton-A24J kernel: [  166.878303] bxudbg EC write command
=0x81
Jun  7 13:44:35 barton-A24J kernel: [  166.878668] bxudbg EC read status = 0x8
Jun  7 13:44:35 barton-A24J kernel: [  166.878669] bxudbg EC write data = 0x1c
Jun  7 13:44:35 barton-A24J kernel: [  166.878671] bxudbg EC read status = 0x8
Jun  7 13:44:35 barton-A24J kernel: [  166.878676] bxudbg EC write data = 0x7
Jun  7 13:44:35 barton-A24J kernel: [  166.878697] bxudbg EC read status = 0x2
Jun  7 13:44:35 barton-A24J kernel: [  166.879172] bxudbg EC read status = 0x0

successful case:
Jun  6 12:30:36 barton-A24J kernel: [  275.360203] Barton EC write command
=0x81
Jun  6 12:30:36 barton-A24J kernel: [  275.360655] Barton EC read status = 0x8
Jun  6 12:30:36 barton-A24J kernel: [  275.360656] Barton EC write data = 0x1c
Jun  6 12:30:36 barton-A24J kernel: [  275.361494] Barton EC read status = 0x0
Jun  6 12:30:36 barton-A24J kernel: [  275.361495] Barton EC write data = 0x7
Jun  6 12:30:36 barton-A24J kernel: [  275.361524] Barton EC read status = 0x2
Jun  6 12:30:36 barton-A24J kernel: [  275.361985] Barton EC read status = 0x0

I had tried the below change in ec.c to make sure the time sequence for the
ACPI EC write transaction, and this workaround is OK for running my test.

static void advance_transaction(struct acpi_ec *ec, u8 status)
{
      unsigned long flags;
      struct transaction *t = ec->curr;
      u8 trusty_status;   //bxudbg

      spin_lock_irqsave(&ec->lock, flags);
      if (!t)
             goto unlock;
//bxudbg >>>
       udelay(100);
       trusty_status = acpi_ec_read_status(ec);
//bxudbg <<<

      if (t->wlen > t->wi) {
//bxudbg       if ((status & ACPI_EC_FLAG_IBF) == 0)
             if ((trusty_status & ACPI_EC_FLAG_IBF) == 0)   //bxudbg
                    acpi_ec_write_data(ec,
                           t->wdata[t->wi++]);
             else
                    goto err;
      } else if (t->rlen > t->ri) {
//bxudbg       if ((status & ACPI_EC_FLAG_OBF) == 1) {
             if ((trusty_status & ACPI_EC_FLAG_OBF) == 1) { //bxudbg
                    t->rdata[t->ri++] = acpi_ec_read_data(ec);
                    if (t->rlen == t->ri)
                           t->done = true;
             } else
                    goto err;
//bxudbg } else if (t->wlen == t->wi && (status & ACPI_EC_FLAG_IBF) == 0)
      } else if ((t->wlen == t->wi) && ((trusty_status & ACPI_EC_FLAG_IBF) ==
0)) //bxudbg
             t->done = true;
      goto unlock;
err:
      /*
       * If SCI bit is set, then don't think it's a false IRQ
       * otherwise will take a not handled IRQ as a false one.
       */
      if (in_interrupt() && !(status & ACPI_EC_FLAG_SCI))
             ++t->irq_count;

unlock:
      spin_unlock_irqrestore(&ec->lock, flags);
}

-- 
Configure bugmail: https://bugzilla.kernel.org/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
You are watching the assignee of the bug.

------------------------------------------------------------------------------
This SF.net email is sponsored by Windows:

Build for Windows Store.

http://p.sf.net/sfu/windows-dev2dev
_______________________________________________
acpi-bugzilla mailing list
acpi-bugzilla@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/acpi-bugzilla

Reply via email to