static void hsic_read_work_fn(struct work_struct *work) { int err = 0; unsigned char *buf = NULL; struct diag_hsic_info *ch = container_of(work, struct diag_hsic_info, read_work); if (!ch || !ch->enabled || !ch->opened) return; do { buf = diagmem_alloc(driver, DIAG_MDM_BUF_SIZE, ch->mempool); if (!buf) { err = -ENOMEM; break; } err = diag_bridge_read(ch->id, buf, DIAG_MDM_BUF_SIZE); if (err) { diagmem_free(driver, buf, ch->mempool); pr_err_ratelimited("diag: Unable to read from HSIC channel %d, err: %d\n", ch->id, err); break; } } while (buf); /* Read from the HSIC channel continously if the channel is present */ if (!err) queue_work(ch->hsic_wq, &ch->read_work); }
static void diag_read_hsic_work_fn(struct work_struct *work) { unsigned char *buf_in_hsic = NULL; int num_reads_submitted = 0; int err = 0; int write_ptrs_available; if (!driver->hsic_ch) { pr_err("DIAG in %s: driver->hsic_ch == 0\n", __func__); return; } if (driver->logging_mode == MEMORY_DEVICE_MODE) write_ptrs_available = driver->poolsize_hsic_write - driver->num_hsic_buf_tbl_entries; else write_ptrs_available = driver->poolsize_hsic_write - driver->count_hsic_write_pool; do { if (write_ptrs_available <= 0) break; write_ptrs_available--; if (!driver->hsic_ch) break; buf_in_hsic = diagmem_alloc(driver, READ_HSIC_BUF_SIZE, POOL_TYPE_HSIC); if (buf_in_hsic) { pr_debug("diag: read from HSIC\n"); num_reads_submitted++; err = diag_bridge_read((char *)buf_in_hsic, READ_HSIC_BUF_SIZE); if (err) { num_reads_submitted--; diagmem_free(driver, buf_in_hsic, POOL_TYPE_HSIC); pr_err_ratelimited("diag: Error initiating HSIC read, err: %d\n", err); break; } } } while (buf_in_hsic); if ((driver->count_hsic_pool < driver->poolsize_hsic) && (num_reads_submitted == 0) && (err != -ENODEV) && (driver->hsic_ch != 0)) queue_work(diag_bridge[HSIC].wq, &driver->diag_read_hsic_work); }
/* Work function used to send zero cfg packet and receive ack */ static void diag_zero_cfg_hsic_work_fn(struct work_struct *work) { int index = driver->zero_cfg_packet_lens_index; if (index >= ZERO_CFG_SUBPACKET_MAX) return; if (!driver->in_busy_hsic_write && !driver->in_busy_hsic_read) { driver->in_busy_hsic_write = 1; diag_bridge_write(&zero_cfg_buf[driver->zero_cfg_index], zero_cfg_packet_lens[index]); driver->in_busy_hsic_read = 1; diag_bridge_read((char *)driver->buf_in_hsic, IN_BUF_SIZE); } }
static void diag_read_hsic_work_fn(struct work_struct *work) { if (!driver->hsic_ch) { pr_err("DIAG in %s: driver->hsic_ch == 0\n", __func__); return; } /* * If there is no hsic data being read from the hsic and there * is no hsic data being written to the usb mdm channel */ if (!driver->in_busy_hsic_read && (!driver->in_busy_hsic_write_on_mdm || driver->logging_mode == MEMORY_DEVICE_MODE)) { /* * Initiate the read from the hsic. The hsic read is * asynchronous. Once the read is complete the read * callback function will be called. */ int err; driver->in_busy_hsic_read = 1; APPEND_DEBUG('i'); err = diag_bridge_read((char *)driver->buf_in_hsic, IN_BUF_SIZE); if (err) { pr_err("DIAG: Error initiating HSIC read, err: %d\n", err); /* * If the error is recoverable, then clear * the read flag, so we will resubmit a * read on the next frame. Otherwise, don't * resubmit a read on the next frame. */ if ((-ESHUTDOWN) != err) driver->in_busy_hsic_read = 0; if (err == -EBUSY) return; } } /* * If for some reason there was no hsic data, set up * the next read */ if (!driver->in_busy_hsic_read) queue_work(driver->diag_hsic_wq, &driver->diag_read_hsic_work); }
static void diag_read_hsic_work_fn(struct work_struct *work) { if (!driver->hsic_ch) { pr_err("DIAG in %s: driver->hsic_ch == 0\n", __func__); return; } /* If there is no hsic data being read from the hsic and there * is no hsic data being written to the device */ if (!driver->in_busy_hsic_read && !driver->in_busy_hsic_write_on_device) { /* * Initiate the read from the hsic. The hsic read is * asynchronous. Once the read is complete the read * callback function will be called. */ int err; driver->in_busy_hsic_read = 1; APPEND_DEBUG('i'); pr_debug("diag: read from HSIC\n"); err = diag_bridge_read((char *)driver->buf_in_hsic, IN_BUF_SIZE); if (err) { pr_err_ratelimited("DIAG: Error initiating HSIC read, err: %d\n", err); /* * If the error is recoverable, then clear * the read flag, so we will resubmit a * read on the next frame. Otherwise, don't * resubmit a read on the next frame. */ if ((-ENODEV) != err) driver->in_busy_hsic_read = 0; } } /* * If for some reason there was no hsic data, set up * the next read */ if (!driver->in_busy_hsic_read) queue_work(driver->diag_bridge_wq, &driver->diag_read_hsic_work); }
static void diag_read_hsic_work_fn(struct work_struct *work) { unsigned char *buf_in_hsic = NULL; int num_reads_submitted = 0; int err = 0; int write_ptrs_available; struct diag_hsic_dev *hsic_struct = container_of(work, struct diag_hsic_dev, diag_read_hsic_work); int index = hsic_struct->id; static DEFINE_RATELIMIT_STATE(rl, 10*HZ, 1); if (!diag_hsic[index].hsic_ch) { pr_err("DIAG in %s: diag_hsic[index].hsic_ch == 0\n", __func__); return; } /* * Determine the current number of available buffers for writing after * reading from the HSIC has completed. */ if (driver->logging_mode == MEMORY_DEVICE_MODE) write_ptrs_available = diag_hsic[index].poolsize_hsic_write - diag_hsic[index]. num_hsic_buf_tbl_entries; else write_ptrs_available = diag_hsic[index].poolsize_hsic_write - diag_hsic[index].count_hsic_write_pool; /* * Queue up a read on the HSIC for all available buffers in the * pool, exhausting the pool. */ do { /* * If no more write buffers are available, * stop queuing reads */ if (write_ptrs_available <= 0) break; write_ptrs_available--; /* * No sense queuing a read if the HSIC bridge was * closed in another thread */ if (!diag_hsic[index].hsic_ch) break; buf_in_hsic = diagmem_alloc(driver, READ_HSIC_BUF_SIZE, index+POOL_TYPE_HSIC); if (buf_in_hsic) { /* * Initiate the read from the HSIC. The HSIC read is * asynchronous. Once the read is complete the read * callback function will be called. */ pr_debug("diag: read from HSIC\n"); num_reads_submitted++; err = diag_bridge_read(hsic_data_bridge_map[index], (char *)buf_in_hsic, READ_HSIC_BUF_SIZE); if (err) { num_reads_submitted--; /* Return the buffer to the pool */ diagmem_free(driver, buf_in_hsic, index+POOL_TYPE_HSIC); if (__ratelimit(&rl)) pr_err("diag: Error initiating HSIC read, err: %d\n", err); /* * An error occurred, discontinue queuing * reads */ break; } } } while (buf_in_hsic); /* * If there are read buffers available and for some reason the * read was not queued, and if no unrecoverable error occurred * (-ENODEV is an unrecoverable error), then set up the next read */ if ((diag_hsic[index].count_hsic_pool < diag_hsic[index].poolsize_hsic) && (num_reads_submitted == 0) && (err != -ENODEV) && (diag_hsic[index].hsic_ch != 0)) queue_work(diag_bridge[index].wq, &diag_hsic[index].diag_read_hsic_work); }
static void diag_read_hsic_dci_work_fn(struct work_struct *work) { unsigned char *buf_in_hsic = NULL; int num_reads_submitted = 0; int err = 0; struct diag_hsic_dci_dev *hsic_struct = container_of(work, struct diag_hsic_dci_dev, diag_read_hsic_work); int index = hsic_struct->id; if (!diag_hsic_dci[index].hsic_ch) { pr_err("diag: Invalid HSIC channel in %s\n", __func__); return; } /* * Queue up a read on the HSIC for all available buffers in the * pool, exhausting the pool. */ do { /* * No sense queuing a read if the HSIC bridge was * closed in another thread */ if (!diag_hsic_dci[index].hsic_ch) break; buf_in_hsic = diagmem_alloc(driver, READ_HSIC_BUF_SIZE_DCI, POOL_TYPE_HSIC_DCI + index); if (buf_in_hsic) { /* * Initiate the read from the HSIC. The HSIC read is * asynchronous. Once the read is complete the read * callback function will be called. */ num_reads_submitted++; err = diag_bridge_read(hsic_dci_bridge_map[index], (char *)buf_in_hsic, READ_HSIC_BUF_SIZE_DCI); if (err) { num_reads_submitted--; /* Return the buffer to the pool */ diagmem_free(driver, buf_in_hsic, POOL_TYPE_HSIC_DCI + index); pr_err_ratelimited("diag: Error initiating HSIC read, err: %d\n", err); /* * An error occurred, discontinue queuing * reads */ break; } } } while (buf_in_hsic); /* * If there are read buffers available and for some reason the * read was not queued, and if no unrecoverable error occurred * (-ENODEV is an unrecoverable error), then set up the next read */ if ((diag_hsic_dci[index].count_hsic_pool < diag_hsic_dci[index].poolsize_hsic) && (num_reads_submitted == 0) && (err != -ENODEV) && (diag_hsic_dci[index].hsic_ch != 0)) queue_work(diag_bridge_dci[index].wq, &diag_hsic_dci[index].diag_read_hsic_work); }
static void diag_read_hsic_work_fn(struct work_struct *work) { unsigned char *buf_in_hsic = NULL; int num_reads_submitted = 0; int err = 0; int write_ptrs_available; if (!driver->hsic_ch) { pr_err("DIAG in %s: driver->hsic_ch == 0\n", __func__); return; } /* * Determine the current number of available buffers for writing after * reading from the HSIC has completed. */ if (driver->logging_mode == MEMORY_DEVICE_MODE) write_ptrs_available = driver->poolsize_hsic_write - driver->num_hsic_buf_tbl_entries; else write_ptrs_available = driver->poolsize_hsic_write - driver->count_hsic_write_pool; /* * Queue up a read on the HSIC for all available buffers in the * pool, exhausting the pool. */ do { /* * If no more write buffers are available, * stop queuing reads */ if (write_ptrs_available <= 0) break; write_ptrs_available--; buf_in_hsic = diagmem_alloc(driver, READ_HSIC_BUF_SIZE, POOL_TYPE_HSIC); if (buf_in_hsic) { /* * Initiate the read from the hsic. The hsic read is * asynchronous. Once the read is complete the read * callback function will be called. */ pr_debug("diag: read from HSIC\n"); num_reads_submitted++; err = diag_bridge_read((char *)buf_in_hsic, READ_HSIC_BUF_SIZE); if (err) { num_reads_submitted--; /* Return the buffer to the pool */ diagmem_free(driver, buf_in_hsic, POOL_TYPE_HSIC); pr_err_ratelimited("diag: Error initiating HSIC read, err: %d\n", err); /* * An error occurred, discontinue queuing * reads */ break; } } } while (buf_in_hsic); /* * If there are no buffers available or for some reason there * was no hsic data, and if no unrecoverable error occurred * (-ENODEV is an unrecoverable error), then set up the next read */ if ((num_reads_submitted == 0) && (err != -ENODEV)) queue_work(driver->diag_bridge_wq, &driver->diag_read_hsic_work); }
static void diag_read_hsic_work_fn(struct work_struct *work) { unsigned char *buf_in_hsic = NULL; int err = 0; struct diag_hsic_dev *hsic_struct = container_of(work, struct diag_hsic_dev, diag_read_hsic_work); int index = hsic_struct->id; static DEFINE_RATELIMIT_STATE(rl, 10*HZ, 1); if (!diag_hsic[index].hsic_ch) { pr_err("DIAG in %s: diag_hsic[index].hsic_ch == 0\n", __func__); return; } /* * Queue up a read on the HSIC for all available buffers in the * pool, exhausting the pool. */ do { /* * No sense queuing a read if the HSIC bridge was * closed in another thread */ if (!diag_hsic[index].hsic_ch) break; buf_in_hsic = diagmem_alloc(driver, DIAG_MDM_BUF_SIZE, index+POOL_TYPE_MDM); if (buf_in_hsic) { /* * Initiate the read from the HSIC. The HSIC read is * asynchronous. Once the read is complete the read * callback function will be called. */ pr_debug("diag: read from HSIC\n"); err = diag_bridge_read(hsic_data_bridge_map[index], (char *)buf_in_hsic, DIAG_MDM_BUF_SIZE); if (err) { /* Return the buffer to the pool */ diagmem_free(driver, buf_in_hsic, index+POOL_TYPE_MDM); if (__ratelimit(&rl)) pr_err("diag: Error initiating HSIC read, err: %d\n", err); /* * An error occurred, discontinue queuing * reads */ break; } } } while (buf_in_hsic); /* * If no unrecoverable error occurred (-ENODEV is an * unrecoverable error), then set up the next read */ if ((err != -ENODEV) && (diag_hsic[index].hsic_ch != 0)) queue_work(diag_bridge[index].wq, &diag_hsic[index].diag_read_hsic_work); }