static void advance_transaction(struct acpi_ec *ec, u8 status) { unsigned long flags; spin_lock_irqsave(&ec->curr_lock, flags); if (!ec->curr) goto unlock; if (ec->curr->wlen > ec->curr->wi) { if ((status & ACPI_EC_FLAG_IBF) == 0) acpi_ec_write_data(ec, ec->curr->wdata[ec->curr->wi++]); else goto err; } else if (ec->curr->rlen > ec->curr->ri) { if ((status & ACPI_EC_FLAG_OBF) == 1) { ec->curr->rdata[ec->curr->ri++] = acpi_ec_read_data(ec); if (ec->curr->rlen == ec->curr->ri) ec->curr->done = true; } else goto err; } else if (ec->curr->wlen == ec->curr->wi && (status & ACPI_EC_FLAG_IBF) == 0) ec->curr->done = true; goto unlock; err: /* false interrupt, state didn't change */ if (in_interrupt()) ++ec->curr->irq_count; unlock: spin_unlock_irqrestore(&ec->curr_lock, flags); }
static int acpi_ec_transaction_unlocked(struct acpi_ec *ec, u8 command, const u8 * wdata, unsigned wdata_len, u8 * rdata, unsigned rdata_len) { int result = 0; unsigned count = atomic_read(&ec->event_count); acpi_ec_write_cmd(ec, command); for (; wdata_len > 0; --wdata_len) { result = acpi_ec_wait(ec, ACPI_EC_EVENT_IBF_0, count); if (result) { printk(KERN_ERR PREFIX "write_cmd timeout, command = %d\n", command); goto end; } count = atomic_read(&ec->event_count); acpi_ec_write_data(ec, *(wdata++)); } if (!rdata_len) { result = acpi_ec_wait(ec, ACPI_EC_EVENT_IBF_0, count); if (result) { printk(KERN_ERR PREFIX "finish-write timeout, command = %d\n", command); goto end; } } else if (command == ACPI_EC_COMMAND_QUERY) { atomic_set(&ec->query_pending, 0); } for (; rdata_len > 0; --rdata_len) { result = acpi_ec_wait(ec, ACPI_EC_EVENT_OBF_1, count); if (result) { printk(KERN_ERR PREFIX "read timeout, command = %d\n", command); goto end; } count = atomic_read(&ec->event_count); *(rdata++) = acpi_ec_read_data(ec); } end: return result; }