static int acpi_aml_write_user(const char __user *buf, int len) { int ret; struct circ_buf *crc = &acpi_aml_io.in_crc; int n; char *p; ret = acpi_aml_lock_write(crc, ACPI_AML_IN_USER); if (ret < 0) return ret; /* sync tail before inserting cmds */ smp_mb(); p = &crc->buf[crc->head]; n = min(len, circ_space_to_end(crc)); if (copy_from_user(p, buf, n)) { ret = -EFAULT; goto out; } /* sync head after inserting cmds */ smp_wmb(); crc->head = (crc->head + n) & (ACPI_AML_BUF_SIZE - 1); ret = n; out: acpi_aml_unlock_fifo(ACPI_AML_IN_USER, !ret); return n; }
static int acpi_aml_read(int fd, struct circ_buf *crc) { char *p; int len; p = &crc->buf[crc->head]; len = circ_space_to_end(crc); len = read(fd, p, len); if (len < 0) perror("read"); else if (len > 0) crc->head = (crc->head + len) & (ACPI_AML_BUF_SIZE - 1); return len; }
static int acpi_aml_read_batch_cmd(int unused, struct circ_buf *crc) { char *p; int len; int remained = strlen(acpi_aml_batch_pos); p = &crc->buf[crc->head]; len = circ_space_to_end(crc); if (len > remained) { memcpy(p, acpi_aml_batch_pos, remained); acpi_aml_batch_pos += remained; len = remained; } else { memcpy(p, acpi_aml_batch_pos, len); acpi_aml_batch_pos += len; } if (len > 0) crc->head = (crc->head + len) & (ACPI_AML_BUF_SIZE - 1); return len; }
static void rd_write(struct msm_rd_state *rd, const void *buf, int sz) { struct circ_buf *fifo = &rd->fifo; const char *ptr = buf; while (sz > 0) { char *fptr = &fifo->buf[fifo->head]; int n; wait_event(rd->fifo_event, circ_space(&rd->fifo) > 0); n = min(sz, circ_space_to_end(&rd->fifo)); memcpy(fptr, ptr, n); fifo->head = (fifo->head + n) & (BUF_SZ - 1); sz -= n; ptr += n; wake_up_all(&rd->fifo_event); } }
static int acpi_aml_write_kern(const char *buf, int len) { int ret; struct circ_buf *crc = &acpi_aml_io.out_crc; int n; char *p; ret = acpi_aml_lock_write(crc, ACPI_AML_OUT_KERN); if (ret < 0) return ret; /* sync tail before inserting logs */ smp_mb(); p = &crc->buf[crc->head]; n = min(len, circ_space_to_end(crc)); memcpy(p, buf, n); /* sync head after inserting logs */ smp_wmb(); crc->head = (crc->head + n) & (ACPI_AML_BUF_SIZE - 1); acpi_aml_unlock_fifo(ACPI_AML_OUT_KERN, true); return n; }
static int acpi_aml_read_batch_log(int fd, struct circ_buf *crc) { char *p; int len; int ret = 0; p = &crc->buf[crc->head]; len = circ_space_to_end(crc); while (ret < len && acpi_aml_log_state != ACPI_AML_LOG_STOP) { if (acpi_aml_log_state == ACPI_AML_PROMPT_ROLL) { *p = acpi_aml_batch_roll; len = 1; crc->head = (crc->head + 1) & (ACPI_AML_BUF_SIZE - 1); ret += 1; acpi_aml_log_state = ACPI_AML_LOG_START; } else { len = read(fd, p, 1); if (len <= 0) { if (len < 0) perror("read"); ret = len; break; } } switch (acpi_aml_log_state) { case ACPI_AML_LOG_START: if (*p == '\n') acpi_aml_log_state = ACPI_AML_PROMPT_START; crc->head = (crc->head + 1) & (ACPI_AML_BUF_SIZE - 1); ret += 1; break; case ACPI_AML_PROMPT_START: if (*p == ACPI_DEBUGGER_COMMAND_PROMPT || *p == ACPI_DEBUGGER_EXECUTE_PROMPT) { acpi_aml_batch_prompt = *p; acpi_aml_log_state = ACPI_AML_PROMPT_STOP; } else { if (*p != '\n') acpi_aml_log_state = ACPI_AML_LOG_START; crc->head = (crc->head + 1) & (ACPI_AML_BUF_SIZE - 1); ret += 1; } break; case ACPI_AML_PROMPT_STOP: if (*p == ' ') { acpi_aml_log_state = ACPI_AML_LOG_STOP; acpi_aml_exit = true; } else { /* Roll back */ acpi_aml_log_state = ACPI_AML_PROMPT_ROLL; acpi_aml_batch_roll = *p; *p = acpi_aml_batch_prompt; crc->head = (crc->head + 1) & (ACPI_AML_BUF_SIZE - 1); ret += 1; } break; default: assert(0); break; } } return ret; }