Exemplo n.º 1
0
static int btqcomsmd_send(struct hci_dev *hdev, struct sk_buff *skb)
{
	struct btqcomsmd *btq = hci_get_drvdata(hdev);
	int ret;

	switch (bt_cb(skb)->pkt_type) {
	case HCI_ACLDATA_PKT:
	case HCI_SCODATA_PKT:
		ret = qcom_smd_send(btq->acl_channel, skb->data, skb->len);
		break;
	case HCI_COMMAND_PKT:
		ret = qcom_smd_send(btq->cmd_channel, skb->data, skb->len);
		break;
	default:
		ret = -ENODEV;
		break;
	}

	return ret;
}
Exemplo n.º 2
0
/**
 * qcom_rpm_smd_write - write @buf to @type:@id
 * @rpm:	rpm handle
 * @type:	resource type
 * @id:		resource identifier
 * @buf:	the data to be written
 * @count:	number of bytes in @buf
 */
int qcom_rpm_smd_write(struct qcom_smd_rpm *rpm,
		       int state,
		       u32 type, u32 id,
		       void *buf,
		       size_t count)
{
	static unsigned msg_id = 1;
	int left;
	int ret;
	struct {
		struct qcom_rpm_header hdr;
		struct qcom_rpm_request req;
		u8 payload[];
	} *pkt;
	size_t size = sizeof(*pkt) + count;

	/* SMD packets to the RPM may not exceed 256 bytes */
	if (WARN_ON(size >= 256))
		return -EINVAL;

	pkt = kmalloc(size, GFP_KERNEL);
	if (!pkt)
		return -ENOMEM;

	mutex_lock(&rpm->lock);

	pkt->hdr.service_type = cpu_to_le32(RPM_SERVICE_TYPE_REQUEST);
	pkt->hdr.length = cpu_to_le32(sizeof(struct qcom_rpm_request) + count);

	pkt->req.msg_id = cpu_to_le32(msg_id++);
	pkt->req.flags = cpu_to_le32(state);
	pkt->req.type = cpu_to_le32(type);
	pkt->req.id = cpu_to_le32(id);
	pkt->req.data_len = cpu_to_le32(count);
	memcpy(pkt->payload, buf, count);

	ret = qcom_smd_send(rpm->rpm_channel, pkt, size);
	if (ret)
		goto out;

	left = wait_for_completion_timeout(&rpm->ack, RPM_REQUEST_TIMEOUT);
	if (!left)
		ret = -ETIMEDOUT;
	else
		ret = rpm->ack_status;

out:
	kfree(pkt);
	mutex_unlock(&rpm->lock);
	return ret;
}
Exemplo n.º 3
0
/**
 * qcom_rpm_smd_write - write @buf to @type:@id
 * @rpm:	rpm handle
 * @type:	resource type
 * @id:		resource identifier
 * @buf:	the data to be written
 * @count:	number of bytes in @buf
 */
int qcom_rpm_smd_write(struct qcom_smd_rpm *rpm,
		       int state,
		       u32 type, u32 id,
		       void *buf,
		       size_t count)
{
	static unsigned msg_id = 1;
	int left;
	int ret;

	struct {
		struct qcom_rpm_header hdr;
		struct qcom_rpm_request req;
		u8 payload[count];
	} pkt;

	/* SMD packets to the RPM may not exceed 256 bytes */
	if (WARN_ON(sizeof(pkt) >= 256))
		return -EINVAL;

	mutex_lock(&rpm->lock);

	pkt.hdr.service_type = RPM_SERVICE_TYPE_REQUEST;
	pkt.hdr.length = sizeof(struct qcom_rpm_request) + count;

	pkt.req.msg_id = msg_id++;
	pkt.req.flags = BIT(state);
	pkt.req.type = type;
	pkt.req.id = id;
	pkt.req.data_len = count;
	memcpy(pkt.payload, buf, count);

	ret = qcom_smd_send(rpm->rpm_channel, &pkt, sizeof(pkt));
	if (ret)
		goto out;

	left = wait_for_completion_timeout(&rpm->ack, RPM_REQUEST_TIMEOUT);
	if (!left)
		ret = -ETIMEDOUT;
	else
		ret = rpm->ack_status;

out:
	mutex_unlock(&rpm->lock);
	return ret;
}