Beispiel #1
0
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;
}
Beispiel #3
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;
}
Beispiel #4
0
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;
}
Beispiel #9
0
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;
}