static int diag_hsic_probe_dci(int pdev_id) { int err = 0; int index = hsic_map[pdev_id].struct_idx; int b_index = hsic_map[pdev_id].bridge_idx; if (!diag_bridge_dci || !diag_hsic_dci) return -ENOMEM; mutex_lock(&diag_bridge_dci[index].bridge_mutex); if (!diag_hsic_dci[index].hsic_inited) { diag_hsic_dci[index].data_buf = NULL; if (diag_hsic_dci[index].data == NULL) diag_hsic_dci[index].data = kzalloc(DIAG_MDM_BUF_SIZE, GFP_KERNEL); if (!diag_hsic_dci[index].data) { mutex_unlock(&diag_bridge_dci[index].bridge_mutex); return -ENOMEM; } diag_hsic_dci[index].id = index; diagmem_init(driver, POOL_TYPE_MDM_DCI + index); diagmem_init(driver, POOL_TYPE_MDM_DCI_WRITE + index); INIT_WORK(&(diag_hsic_dci[index].diag_read_hsic_work), diag_read_hsic_dci_work_fn); INIT_WORK(&(diag_hsic_dci[index].diag_process_hsic_work), diag_process_hsic_work_fn); diag_hsic_dci[index].hsic_inited = 1; } if (!diag_hsic_dci[index].hsic_device_opened) { hsic_diag_dci_bridge_ops[index].ctxt = (void *)(int)(index); err = diag_bridge_open(b_index, &hsic_diag_dci_bridge_ops[index]); if (err) { pr_err("diag: HSIC channel open error: %d\n", err); } else { pr_debug("diag: opened DCI HSIC channel at index %d\n", index); diag_hsic_dci[index].hsic_device_opened = 1; diag_hsic_dci[index].hsic_ch = 1; queue_work(diag_bridge_dci[index].wq, &diag_hsic_dci[index].diag_read_hsic_work); diag_send_dci_log_mask_remote(index + 1); diag_send_dci_event_mask_remote(index + 1); } } else { pr_debug("diag: HSIC DCI channel already open\n"); queue_work(diag_bridge_dci[index].wq, &diag_hsic_dci[index].diag_read_hsic_work); diag_send_dci_log_mask_remote(index + 1); diag_send_dci_event_mask_remote(index + 1); } diag_hsic_dci[index].hsic_device_enabled = 1; mutex_unlock(&diag_bridge_dci[index].bridge_mutex); return err; }
static int hsic_open(int id) { int err = 0; unsigned long flags; struct diag_hsic_info *ch = NULL; if (id < 0 || id >= NUM_HSIC_DEV) { pr_err("diag: Invalid index %d in %s\n", id, __func__); return -EINVAL; } ch = &diag_hsic[id]; if (!ch->enabled) return -ENODEV; if (ch->opened) { pr_debug("diag: HSIC channel %d is already opened\n", ch->id); return -ENODEV; } err = diag_bridge_open(ch->id, &diag_hsic_ops[ch->id]); if (err) { pr_err("diag: Unable to open HSIC channel %d, err: %d", ch->id, err); return err; } spin_lock_irqsave(&ch->lock, flags); ch->opened = 1; spin_unlock_irqrestore(&ch->lock, flags); diagmem_init(driver, ch->mempool); /* Notify the bridge that the channel is open */ diag_remote_dev_open(ch->dev_id); queue_work(ch->hsic_wq, &(ch->read_work)); return 0; }
static int diagchar_open(struct inode *inode, struct file *file) { int i = 0; char currtask_name[FIELD_SIZEOF(struct task_struct, comm) + 1]; if (driver) { mutex_lock(&driver->diagchar_mutex); for (i = 0; i < driver->num_clients; i++) if (driver->client_map[i].pid == 0) break; if (i < driver->num_clients) { driver->client_map[i].pid = current->tgid; strncpy(driver->client_map[i].name, get_task_comm( currtask_name, current), 20); driver->client_map[i].name[19] = '\0'; } else { if (i < threshold_client_limit) { driver->num_clients++; driver->client_map = krealloc(driver->client_map , (driver->num_clients) * sizeof(struct diag_client_map), GFP_KERNEL); driver->client_map[i].pid = current->tgid; strncpy(driver->client_map[i].name, get_task_comm(currtask_name, current), 20); driver->client_map[i].name[19] = '\0'; } else { mutex_unlock(&driver->diagchar_mutex); if (driver->alert_count == 0 || driver->alert_count == 10) { printk(KERN_ALERT "Max client limit for" "DIAG driver reached\n"); printk(KERN_INFO "Cannot open handle %s" " %d", get_task_comm(currtask_name, current), current->tgid); for (i = 0; i < driver->num_clients; i++) printk(KERN_INFO "%d) %s PID=%d" , i, driver->client_map[i].name, driver->client_map[i].pid); driver->alert_count = 0; } driver->alert_count++; return -ENOMEM; } } driver->data_ready[i] |= MSG_MASKS_TYPE; driver->data_ready[i] |= EVENT_MASKS_TYPE; driver->data_ready[i] |= LOG_MASKS_TYPE; if (driver->ref_count == 0) diagmem_init(driver); driver->ref_count++; mutex_unlock(&driver->diagchar_mutex); return 0; } return -ENOMEM; }
int diag_usb_register(int id, int ctxt, struct diag_mux_ops *ops) { struct diag_usb_info *ch = NULL; unsigned char wq_name[DIAG_USB_NAME_SZ + DIAG_USB_STRING_SZ]; if (id < 0 || id >= NUM_DIAG_USB_DEV) { pr_err("diag: Unable to register with USB, id: %d\n", id); return -EIO; } if (!ops) { pr_err("diag: Invalid operations for USB\n"); return -EIO; } ch = &diag_usb[id]; ch->ops = ops; ch->ctxt = ctxt; spin_lock_init(&ch->lock); ch->read_buf = kzalloc(USB_MAX_OUT_BUF, GFP_KERNEL); if (!ch->read_buf) goto err; ch->read_ptr = kzalloc(sizeof(struct diag_request), GFP_KERNEL); if (!ch->read_ptr) goto err; diagmem_init(driver, ch->mempool); INIT_WORK(&(ch->read_work), usb_read_work_fn); INIT_WORK(&(ch->read_done_work), usb_read_done_work_fn); INIT_WORK(&(ch->connect_work), usb_connect_work_fn); INIT_WORK(&(ch->disconnect_work), usb_disconnect_work_fn); strlcpy(wq_name, "DIAG_USB_", DIAG_USB_STRING_SZ); strlcat(wq_name, ch->name, sizeof(ch->name)); ch->usb_wq = create_singlethread_workqueue(wq_name); if (!ch->usb_wq) goto err; ch->hdl = usb_diag_open(ch->name, (void *)(uintptr_t)id, diag_usb_notifier); if (IS_ERR(ch->hdl)) { pr_err("diag: Unable to open USB channel %s\n", ch->name); goto err; } ch->enabled = 1; pr_debug("diag: Successfully registered USB %s\n", ch->name); return 0; err: if (ch->usb_wq) destroy_workqueue(ch->usb_wq); kfree(ch->read_ptr); kfree(ch->read_buf); return -ENOMEM; }
static int diagcharmdm_open(struct inode *inode, struct file *file) { int i = 0; #if defined(CONFIG_MACH_MECHA) if (!sdio_diag_initialized) { DIAG_INFO("sdio diag isn't in embedded mode \n"); return 0; } #endif DIAG_INFO("%s:%s(parent:%s): tgid=%d\n", __func__, current->comm, current->parent->comm, current->tgid); if (driver) { mutex_lock(&driver->diagcharmdm_mutex); for (i = 0; i < driver->num_mdmclients; i++) if (driver->mdmclient_map[i].pid == 0) break; if (i < driver->num_mdmclients) { driver->mdmclient_map[i].pid = current->tgid; strncpy(driver->mdmclient_map[i].name, current->comm, 20); driver->mdmclient_map[i].name[19] = '\0'; } else { mutex_unlock(&driver->diagcharmdm_mutex); DIAG_INFO("%s:reach max client count\n", __func__); for (i = 0; i < driver->num_mdmclients; i++) DIAG_WARNING("%d) %s PID=%d", i, driver-> mdmclient_map[i].name, driver->mdmclient_map[i].pid); return -ENOMEM; } driver->mdmdata_ready[i] |= MSG_MASKS_TYPE; driver->mdmdata_ready[i] |= EVENT_MASKS_TYPE; driver->mdmdata_ready[i] |= LOG_MASKS_TYPE; #if defined(CONFIG_ARCH_MSM8X60_LTE) if (driver->ref_count == 0) diagmem_init(driver); driver->ref_count++; #endif mutex_unlock(&driver->diagcharmdm_mutex); return 0; } return -ENOMEM; }
static int diagchar_open(struct inode *inode, struct file *file) { int i = 0; if (driver) { mutex_lock(&driver->diagchar_mutex); for (i = 0; i < driver->num_clients; i++) if (driver->client_map[i] == 0) break; if (i < driver->num_clients) driver->client_map[i] = current->tgid; else { if (i < threshold_client_limit) { driver->num_clients++; driver->client_map = krealloc( driver->client_map, (driver-> num_clients) * 4, GFP_KERNEL); driver->client_map[i] = current->tgid; } else { mutex_unlock(&driver->diagchar_mutex); printk(KERN_ALERT "Max client limit " "for DIAG driver reached\n"); printk(KERN_INFO "Cannot open handle for" " the new process %d\n", current->tgid); for (i = 0; i < driver->num_clients; i++) printk(KERN_INFO "Client%d has Process" " ID=%d", i, driver->client_map[i]); return -ENOMEM; } } driver->data_ready[i] |= MSG_MASKS_TYPE; driver->data_ready[i] |= EVENT_MASKS_TYPE; driver->data_ready[i] |= LOG_MASKS_TYPE; if (driver->ref_count == 0) diagmem_init(driver); driver->ref_count++; mutex_unlock(&driver->diagchar_mutex); return 0; } return -ENOMEM; }
static int diagcharmdm_open(struct inode *inode, struct file *file) { int i = 0; DIAG_INFO("%s:%s(parent:%s): tgid=%d\n", __func__, current->comm, current->parent->comm, current->tgid); if (driver) { mutex_lock(&driver->diagcharmdm_mutex); for (i = 0; i < driver->num_mdmclients; i++) if (driver->mdmclient_map[i].pid == 0) break; if (i < driver->num_mdmclients) { driver->mdmclient_map[i].pid = current->tgid; strncpy(driver->mdmclient_map[i].name, current->comm, 20); driver->mdmclient_map[i].name[19] = '\0'; } else { mutex_unlock(&driver->diagcharmdm_mutex); DIAG_INFO("%s:reach max client count\n", __func__); for (i = 0; i < driver->num_clients; i++) DIAG_WARNING("%d) %s PID=%d", i, driver-> mdmclient_map[i].name, driver->mdmclient_map[i].pid); return -ENOMEM; } driver->mdmdata_ready[i] |= MSG_MASKS_TYPE; driver->mdmdata_ready[i] |= EVENT_MASKS_TYPE; driver->mdmdata_ready[i] |= LOG_MASKS_TYPE; if (driver->ref_count == 0) diagmem_init(driver); driver->ref_count++; mutex_unlock(&driver->diagcharmdm_mutex); return 0; } return -ENOMEM; }
static int diagchar_open(struct inode *inode, struct file *file) { int i = 0; void *temp; if (driver) { mutex_lock(&driver->diagchar_mutex); for (i = 0; i < driver->num_clients; i++) if (driver->client_map[i].pid == 0) break; if (i < driver->num_clients) { diag_add_client(i, file); } else { if (i < threshold_client_limit) { driver->num_clients++; temp = krealloc(driver->client_map , (driver->num_clients) * sizeof(struct diag_client_map), GFP_KERNEL); if (!temp) goto fail; else driver->client_map = temp; temp = krealloc(driver->data_ready , (driver->num_clients) * sizeof(int), GFP_KERNEL); if (!temp) goto fail; else driver->data_ready = temp; diag_add_client(i, file); } else { mutex_unlock(&driver->diagchar_mutex); pr_alert("Max client limit for DIAG reached\n"); pr_info("Cannot open handle %s" " %d", current->comm, current->tgid); for (i = 0; i < driver->num_clients; i++) pr_debug("%d) %s PID=%d", i, driver-> client_map[i].name, driver->client_map[i].pid); return -ENOMEM; } } driver->data_ready[i] |= MSG_MASKS_TYPE; driver->data_ready[i] |= EVENT_MASKS_TYPE; driver->data_ready[i] |= LOG_MASKS_TYPE; if (driver->ref_count == 0) diagmem_init(driver); driver->ref_count++; mutex_unlock(&driver->diagchar_mutex); return 0; } return -ENOMEM; fail: mutex_unlock(&driver->diagchar_mutex); driver->num_clients--; pr_alert("diag: Insufficient memory for new client"); return -ENOMEM; }
static int diag_hsic_probe_data(int pdev_id) { int err = 0; int index = hsic_map[pdev_id].struct_idx; int b_index = hsic_map[pdev_id].bridge_idx; mutex_lock(&diag_bridge[index].bridge_mutex); if (!diag_hsic[index].hsic_inited) { spin_lock_init(&diag_hsic[index].hsic_spinlock); diag_hsic[index].num_hsic_buf_tbl_entries = 0; if (diag_hsic[index].hsic_buf_tbl == NULL) diag_hsic[index].hsic_buf_tbl = kzalloc(NUM_HSIC_BUF_TBL_ENTRIES * sizeof(struct diag_write_device), GFP_KERNEL); if (diag_hsic[index].hsic_buf_tbl == NULL) { mutex_unlock(&diag_bridge[index].bridge_mutex); return -ENOMEM; } diag_hsic[index].id = index; diag_hsic[index].poolsize_hsic_write = N_MDM_WRITE; diagmem_init(driver, POOL_TYPE_MDM + index); INIT_WORK(&(diag_hsic[index].diag_read_hsic_work), diag_read_hsic_work_fn); diag_hsic[index].hsic_data_requested = (driver->logging_mode == MEMORY_DEVICE_MODE) ? 0 : 1; diag_hsic[index].hsic_inited = 1; } /* * The probe function was called after the usb was connected * on the legacy channel OR ODL is turned on and hsic data is * requested. Communication over usb mdm and HSIC needs to be * turned on. */ if ((driver->logging_mode != MEMORY_DEVICE_MODE) || ((driver->logging_mode == MEMORY_DEVICE_MODE) && diag_hsic[index].hsic_data_requested)) { if (diag_hsic[index].hsic_device_opened) { /* should not happen. close it before re-opening */ pr_warn("diag: HSIC channel already opened in probe\n"); diag_bridge_close(hsic_data_bridge_map[index]); } hsic_diag_bridge_ops[index].ctxt = (void *)(index); err = diag_bridge_open(b_index, &hsic_diag_bridge_ops[index]); if (err) { pr_err("diag: could not open HSIC, err: %d\n", err); diag_hsic[index].hsic_device_opened = 0; mutex_unlock(&diag_bridge[index].bridge_mutex); return err; } pr_info("diag: opened HSIC bridge, ch = %d\n", index); diag_hsic[index].hsic_device_opened = 1; diag_hsic[index].hsic_ch = 1; diag_hsic[index].in_busy_hsic_read_on_device = 0; diag_hsic[index].in_busy_hsic_write = 0; diag_usb_queue_read(DIAG_USB_MDM + index); /* Poll HSIC channel to check for data */ queue_work(diag_bridge[index].wq, &diag_hsic[index].diag_read_hsic_work); } /* The HSIC (diag_bridge) platform device driver is enabled */ diag_hsic[index].hsic_device_enabled = 1; mutex_unlock(&diag_bridge[index].bridge_mutex); return err; }