mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2025-01-11 15:40:50 +00:00
Bluetooth: hidp: merge 'send' functions into hidp_send_message()
We handle skb buffers all over the place, even though we have hidp_send_*_message() helpers. This creates a more generic hidp_send_message() helper and uses it instead of dealing with transmit queues directly everywhere. Signed-off-by: David Herrmann <dh.herrmann@gmail.com> Acked-by: Marcel Holtmann <marcel@holtmann.org> Signed-off-by: Gustavo Padovan <gustavo.padovan@collabora.co.uk>
This commit is contained in:
parent
7350e6cf36
commit
41edc0c034
@ -68,15 +68,6 @@ static void hidp_session_remove(struct l2cap_conn *conn,
|
|||||||
static int hidp_session_thread(void *arg);
|
static int hidp_session_thread(void *arg);
|
||||||
static void hidp_session_terminate(struct hidp_session *s);
|
static void hidp_session_terminate(struct hidp_session *s);
|
||||||
|
|
||||||
static inline void hidp_schedule(struct hidp_session *session)
|
|
||||||
{
|
|
||||||
struct sock *ctrl_sk = session->ctrl_sock->sk;
|
|
||||||
struct sock *intr_sk = session->intr_sock->sk;
|
|
||||||
|
|
||||||
wake_up_interruptible(sk_sleep(ctrl_sk));
|
|
||||||
wake_up_interruptible(sk_sleep(intr_sk));
|
|
||||||
}
|
|
||||||
|
|
||||||
static void hidp_copy_session(struct hidp_session *session, struct hidp_conninfo *ci)
|
static void hidp_copy_session(struct hidp_session *session, struct hidp_conninfo *ci)
|
||||||
{
|
{
|
||||||
memset(ci, 0, sizeof(*ci));
|
memset(ci, 0, sizeof(*ci));
|
||||||
@ -107,11 +98,56 @@ static void hidp_copy_session(struct hidp_session *session, struct hidp_conninfo
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* assemble skb, queue message on @transmit and wake up the session thread */
|
||||||
|
static int hidp_send_message(struct hidp_session *session, struct socket *sock,
|
||||||
|
struct sk_buff_head *transmit, unsigned char hdr,
|
||||||
|
const unsigned char *data, int size)
|
||||||
|
{
|
||||||
|
struct sk_buff *skb;
|
||||||
|
struct sock *sk = sock->sk;
|
||||||
|
|
||||||
|
BT_DBG("session %p data %p size %d", session, data, size);
|
||||||
|
|
||||||
|
if (atomic_read(&session->terminate))
|
||||||
|
return -EIO;
|
||||||
|
|
||||||
|
skb = alloc_skb(size + 1, GFP_ATOMIC);
|
||||||
|
if (!skb) {
|
||||||
|
BT_ERR("Can't allocate memory for new frame");
|
||||||
|
return -ENOMEM;
|
||||||
|
}
|
||||||
|
|
||||||
|
*skb_put(skb, 1) = hdr;
|
||||||
|
if (data && size > 0)
|
||||||
|
memcpy(skb_put(skb, size), data, size);
|
||||||
|
|
||||||
|
skb_queue_tail(transmit, skb);
|
||||||
|
wake_up_interruptible(sk_sleep(sk));
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int hidp_send_ctrl_message(struct hidp_session *session,
|
||||||
|
unsigned char hdr, const unsigned char *data,
|
||||||
|
int size)
|
||||||
|
{
|
||||||
|
return hidp_send_message(session, session->ctrl_sock,
|
||||||
|
&session->ctrl_transmit, hdr, data, size);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int hidp_send_intr_message(struct hidp_session *session,
|
||||||
|
unsigned char hdr, const unsigned char *data,
|
||||||
|
int size)
|
||||||
|
{
|
||||||
|
return hidp_send_message(session, session->intr_sock,
|
||||||
|
&session->intr_transmit, hdr, data, size);
|
||||||
|
}
|
||||||
|
|
||||||
static int hidp_queue_event(struct hidp_session *session, struct input_dev *dev,
|
static int hidp_queue_event(struct hidp_session *session, struct input_dev *dev,
|
||||||
unsigned int type, unsigned int code, int value)
|
unsigned int type, unsigned int code, int value)
|
||||||
{
|
{
|
||||||
unsigned char newleds;
|
unsigned char newleds;
|
||||||
struct sk_buff *skb;
|
unsigned char hdr, data[2];
|
||||||
|
|
||||||
BT_DBG("session %p type %d code %d value %d", session, type, code, value);
|
BT_DBG("session %p type %d code %d value %d", session, type, code, value);
|
||||||
|
|
||||||
@ -129,21 +165,11 @@ static int hidp_queue_event(struct hidp_session *session, struct input_dev *dev,
|
|||||||
|
|
||||||
session->leds = newleds;
|
session->leds = newleds;
|
||||||
|
|
||||||
skb = alloc_skb(3, GFP_ATOMIC);
|
hdr = HIDP_TRANS_DATA | HIDP_DATA_RTYPE_OUPUT;
|
||||||
if (!skb) {
|
data[0] = 0x01;
|
||||||
BT_ERR("Can't allocate memory for new frame");
|
data[1] = newleds;
|
||||||
return -ENOMEM;
|
|
||||||
}
|
|
||||||
|
|
||||||
*skb_put(skb, 1) = HIDP_TRANS_DATA | HIDP_DATA_RTYPE_OUPUT;
|
return hidp_send_intr_message(session, hdr, data, 2);
|
||||||
*skb_put(skb, 1) = 0x01;
|
|
||||||
*skb_put(skb, 1) = newleds;
|
|
||||||
|
|
||||||
skb_queue_tail(&session->intr_transmit, skb);
|
|
||||||
|
|
||||||
hidp_schedule(session);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int hidp_hidinput_event(struct input_dev *dev, unsigned int type, unsigned int code, int value)
|
static int hidp_hidinput_event(struct input_dev *dev, unsigned int type, unsigned int code, int value)
|
||||||
@ -216,71 +242,9 @@ static void hidp_input_report(struct hidp_session *session, struct sk_buff *skb)
|
|||||||
input_sync(dev);
|
input_sync(dev);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int __hidp_send_ctrl_message(struct hidp_session *session,
|
|
||||||
unsigned char hdr, unsigned char *data,
|
|
||||||
int size)
|
|
||||||
{
|
|
||||||
struct sk_buff *skb;
|
|
||||||
|
|
||||||
BT_DBG("session %p data %p size %d", session, data, size);
|
|
||||||
|
|
||||||
if (atomic_read(&session->terminate))
|
|
||||||
return -EIO;
|
|
||||||
|
|
||||||
skb = alloc_skb(size + 1, GFP_ATOMIC);
|
|
||||||
if (!skb) {
|
|
||||||
BT_ERR("Can't allocate memory for new frame");
|
|
||||||
return -ENOMEM;
|
|
||||||
}
|
|
||||||
|
|
||||||
*skb_put(skb, 1) = hdr;
|
|
||||||
if (data && size > 0)
|
|
||||||
memcpy(skb_put(skb, size), data, size);
|
|
||||||
|
|
||||||
skb_queue_tail(&session->ctrl_transmit, skb);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int hidp_send_ctrl_message(struct hidp_session *session,
|
|
||||||
unsigned char hdr, unsigned char *data, int size)
|
|
||||||
{
|
|
||||||
int err;
|
|
||||||
|
|
||||||
err = __hidp_send_ctrl_message(session, hdr, data, size);
|
|
||||||
|
|
||||||
hidp_schedule(session);
|
|
||||||
|
|
||||||
return err;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int hidp_queue_report(struct hidp_session *session,
|
|
||||||
unsigned char *data, int size)
|
|
||||||
{
|
|
||||||
struct sk_buff *skb;
|
|
||||||
|
|
||||||
BT_DBG("session %p hid %p data %p size %d", session, session->hid, data, size);
|
|
||||||
|
|
||||||
skb = alloc_skb(size + 1, GFP_ATOMIC);
|
|
||||||
if (!skb) {
|
|
||||||
BT_ERR("Can't allocate memory for new frame");
|
|
||||||
return -ENOMEM;
|
|
||||||
}
|
|
||||||
|
|
||||||
*skb_put(skb, 1) = 0xa2;
|
|
||||||
if (size > 0)
|
|
||||||
memcpy(skb_put(skb, size), data, size);
|
|
||||||
|
|
||||||
skb_queue_tail(&session->intr_transmit, skb);
|
|
||||||
|
|
||||||
hidp_schedule(session);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int hidp_send_report(struct hidp_session *session, struct hid_report *report)
|
static int hidp_send_report(struct hidp_session *session, struct hid_report *report)
|
||||||
{
|
{
|
||||||
unsigned char buf[32];
|
unsigned char buf[32], hdr;
|
||||||
int rsize;
|
int rsize;
|
||||||
|
|
||||||
rsize = ((report->size - 1) >> 3) + 1 + (report->id > 0);
|
rsize = ((report->size - 1) >> 3) + 1 + (report->id > 0);
|
||||||
@ -288,8 +252,9 @@ static int hidp_send_report(struct hidp_session *session, struct hid_report *rep
|
|||||||
return -EIO;
|
return -EIO;
|
||||||
|
|
||||||
hid_output_report(report, buf);
|
hid_output_report(report, buf);
|
||||||
|
hdr = HIDP_TRANS_DATA | HIDP_DATA_RTYPE_OUPUT;
|
||||||
|
|
||||||
return hidp_queue_report(session, buf, rsize);
|
return hidp_send_intr_message(session, hdr, buf, rsize);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int hidp_get_raw_report(struct hid_device *hid,
|
static int hidp_get_raw_report(struct hid_device *hid,
|
||||||
@ -328,7 +293,7 @@ static int hidp_get_raw_report(struct hid_device *hid,
|
|||||||
session->waiting_report_number = numbered_reports ? report_number : -1;
|
session->waiting_report_number = numbered_reports ? report_number : -1;
|
||||||
set_bit(HIDP_WAITING_FOR_RETURN, &session->flags);
|
set_bit(HIDP_WAITING_FOR_RETURN, &session->flags);
|
||||||
data[0] = report_number;
|
data[0] = report_number;
|
||||||
ret = hidp_send_ctrl_message(hid->driver_data, report_type, data, 1);
|
ret = hidp_send_ctrl_message(session, report_type, data, 1);
|
||||||
if (ret)
|
if (ret)
|
||||||
goto err;
|
goto err;
|
||||||
|
|
||||||
@ -388,7 +353,7 @@ static int hidp_output_raw_report(struct hid_device *hid, unsigned char *data, s
|
|||||||
report_type = HIDP_TRANS_SET_REPORT | HIDP_DATA_RTYPE_FEATURE;
|
report_type = HIDP_TRANS_SET_REPORT | HIDP_DATA_RTYPE_FEATURE;
|
||||||
break;
|
break;
|
||||||
case HID_OUTPUT_REPORT:
|
case HID_OUTPUT_REPORT:
|
||||||
report_type = HIDP_TRANS_SET_REPORT | HIDP_DATA_RTYPE_OUPUT;
|
report_type = HIDP_TRANS_DATA | HIDP_DATA_RTYPE_OUPUT;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
@ -399,8 +364,7 @@ static int hidp_output_raw_report(struct hid_device *hid, unsigned char *data, s
|
|||||||
|
|
||||||
/* Set up our wait, and send the report request to the device. */
|
/* Set up our wait, and send the report request to the device. */
|
||||||
set_bit(HIDP_WAITING_FOR_SEND_ACK, &session->flags);
|
set_bit(HIDP_WAITING_FOR_SEND_ACK, &session->flags);
|
||||||
ret = hidp_send_ctrl_message(hid->driver_data, report_type, data,
|
ret = hidp_send_ctrl_message(session, report_type, data, count);
|
||||||
count);
|
|
||||||
if (ret)
|
if (ret)
|
||||||
goto err;
|
goto err;
|
||||||
|
|
||||||
@ -485,12 +449,12 @@ static void hidp_process_handshake(struct hidp_session *session,
|
|||||||
case HIDP_HSHK_ERR_FATAL:
|
case HIDP_HSHK_ERR_FATAL:
|
||||||
/* Device requests a reboot, as this is the only way this error
|
/* Device requests a reboot, as this is the only way this error
|
||||||
* can be recovered. */
|
* can be recovered. */
|
||||||
__hidp_send_ctrl_message(session,
|
hidp_send_ctrl_message(session,
|
||||||
HIDP_TRANS_HID_CONTROL | HIDP_CTRL_SOFT_RESET, NULL, 0);
|
HIDP_TRANS_HID_CONTROL | HIDP_CTRL_SOFT_RESET, NULL, 0);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
__hidp_send_ctrl_message(session,
|
hidp_send_ctrl_message(session,
|
||||||
HIDP_TRANS_HANDSHAKE | HIDP_HSHK_ERR_INVALID_PARAMETER, NULL, 0);
|
HIDP_TRANS_HANDSHAKE | HIDP_HSHK_ERR_INVALID_PARAMETER, NULL, 0);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -538,7 +502,7 @@ static int hidp_process_data(struct hidp_session *session, struct sk_buff *skb,
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
__hidp_send_ctrl_message(session,
|
hidp_send_ctrl_message(session,
|
||||||
HIDP_TRANS_HANDSHAKE | HIDP_HSHK_ERR_INVALID_PARAMETER, NULL, 0);
|
HIDP_TRANS_HANDSHAKE | HIDP_HSHK_ERR_INVALID_PARAMETER, NULL, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -585,7 +549,7 @@ static void hidp_recv_ctrl_frame(struct hidp_session *session,
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
__hidp_send_ctrl_message(session,
|
hidp_send_ctrl_message(session,
|
||||||
HIDP_TRANS_HANDSHAKE | HIDP_HSHK_ERR_UNSUPPORTED_REQUEST, NULL, 0);
|
HIDP_TRANS_HANDSHAKE | HIDP_HSHK_ERR_UNSUPPORTED_REQUEST, NULL, 0);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user