summaryrefslogtreecommitdiff
path: root/usr/src
diff options
context:
space:
mode:
authorgc161489 <none@none>2006-06-26 02:48:11 -0700
committergc161489 <none@none>2006-06-26 02:48:11 -0700
commit59c81845bc6374ff28873a51e05d627b5b027316 (patch)
tree005720029f2c573dbd1ca05c2e7faa8947fd134f /usr/src
parent12fbe00a8d6a6a4ef84260bb64ad420204f8d1e6 (diff)
downloadillumos-gate-59c81845bc6374ff28873a51e05d627b5b027316.tar.gz
6414967 hid_qreply_error calls freemsg on non-mblk
Diffstat (limited to 'usr/src')
-rw-r--r--usr/src/uts/common/io/usb/clients/hid/hid.c42
-rw-r--r--usr/src/uts/common/io/usb/clients/usbkbm/usbkbm.c24
-rw-r--r--usr/src/uts/common/sys/usb/clients/hid/hid.h14
3 files changed, 32 insertions, 48 deletions
diff --git a/usr/src/uts/common/io/usb/clients/hid/hid.c b/usr/src/uts/common/io/usb/clients/hid/hid.c
index 72965b5e43..897ce3188b 100644
--- a/usr/src/uts/common/io/usb/clients/hid/hid.c
+++ b/usr/src/uts/common/io/usb/clients/hid/hid.c
@@ -2275,7 +2275,7 @@ hid_mctl_receive(register queue_t *q, register mblk_t *mp)
} else {
hid_req_data = (hid_req_t *)mp->b_cont->b_rptr;
if ((iocp->ioc_cmd == HID_SET_REPORT) &&
- (hid_req_data->hid_req_data == NULL)) {
+ (hid_req_data->hid_req_wLength == 0)) {
hid_qreply_merror(q, mp, EINVAL);
return (error);
@@ -2431,9 +2431,13 @@ hid_send_async_ctrl_request(hid_state_t *hidp, hid_req_t *hid_request,
* non-zero wLength value but ctrl_data would be allocated by
* client for them.
*/
- if (request_type & USB_DEV_REQ_DEV_TO_HOST) {
- length = hid_request->hid_req_data ?
- 0 : hid_request->hid_req_wLength;
+ if (hid_request->hid_req_wLength >= MAX_REPORT_DATA) {
+ USB_DPRINTF_L2(PRINT_MASK_ALL, hidp->hid_log_handle,
+ "hid_req_wLength is exceeded");
+ return (USB_FAILURE);
+ }
+ if ((request_type & USB_DEV_REQ_DIR_MASK) == USB_DEV_REQ_DEV_TO_HOST) {
+ length = hid_request->hid_req_wLength;
}
if ((ctrl_req = usb_alloc_ctrl_req(hidp->hid_dip, length, 0)) == NULL) {
@@ -2444,17 +2448,10 @@ hid_send_async_ctrl_request(hid_state_t *hidp, hid_req_t *hid_request,
ASSERT(hidp->hid_default_pipe_req >= 0);
mutex_exit(&hidp->hid_mutex);
- /*
- * Some SET M_CTLs will have non-null
- * hid_req_data, free hid_req_data
- */
- freemsg((mblk_t *)hid_request->hid_req_data);
- hid_request->hid_req_data = NULL;
-
return (USB_FAILURE);
}
- if (request_type & USB_DEV_REQ_HOST_TO_DEV) {
+ if ((request_type & USB_DEV_REQ_DIR_MASK) == USB_DEV_REQ_HOST_TO_DEV) {
ASSERT((length == 0) && (ctrl_req->ctrl_data == NULL));
}
@@ -2463,9 +2460,18 @@ hid_send_async_ctrl_request(hid_state_t *hidp, hid_req_t *hid_request,
ctrl_req->ctrl_wValue = hid_request->hid_req_wValue;
ctrl_req->ctrl_wIndex = request_index;
ctrl_req->ctrl_wLength = hid_request->hid_req_wLength;
- ctrl_req->ctrl_data = ctrl_req->ctrl_data ?
- ctrl_req->ctrl_data :
- hid_request->hid_req_data;
+ /* host to device: create a msg from hid_req_data */
+ if ((request_type & USB_DEV_REQ_DIR_MASK) == USB_DEV_REQ_HOST_TO_DEV) {
+ mblk_t *pblk = allocb(hid_request->hid_req_wLength, BPRI_HI);
+ if (pblk == NULL) {
+ usb_free_ctrl_req(ctrl_req);
+ return (USB_FAILURE);
+ }
+ bcopy(hid_request->hid_req_data, pblk->b_wptr,
+ hid_request->hid_req_wLength);
+ pblk->b_wptr += hid_request->hid_req_wLength;
+ ctrl_req->ctrl_data = pblk;
+ }
ctrl_req->ctrl_attributes = USB_ATTRS_AUTOCLEARING;
ctrl_req->ctrl_client_private = (usb_opaque_t)hid_default_pipe_arg;
ctrl_req->ctrl_cb = hid_default_pipe_callback;
@@ -2478,8 +2484,6 @@ hid_send_async_ctrl_request(hid_state_t *hidp, hid_req_t *hid_request,
ASSERT(hidp->hid_default_pipe_req >= 0);
mutex_exit(&hidp->hid_mutex);
- /* caller will free hid_req_data in case of failure */
- ctrl_req->ctrl_data = NULL;
usb_free_ctrl_req(ctrl_req);
USB_DPRINTF_L2(PRINT_MASK_ALL, hidp->hid_log_handle,
"usb_pipe_ctrl_xfer() failed. rval = %d", rval);
@@ -2792,12 +2796,8 @@ hid_restore_device_state(dev_info_t *dip, hid_state_t *hidp)
static void
hid_qreply_merror(queue_t *q, mblk_t *mp, uchar_t errval)
{
- hid_req_t *hid_req = NULL;
-
mp->b_datap->db_type = M_ERROR;
if (mp->b_cont) {
- hid_req = (hid_req_t *)mp->b_cont->b_rptr;
- freemsg((mblk_t *)hid_req->hid_req_data);
freemsg(mp->b_cont);
mp->b_cont = NULL;
}
diff --git a/usr/src/uts/common/io/usb/clients/usbkbm/usbkbm.c b/usr/src/uts/common/io/usb/clients/usbkbm/usbkbm.c
index e1470dae58..d631bae3e5 100644
--- a/usr/src/uts/common/io/usb/clients/usbkbm/usbkbm.c
+++ b/usr/src/uts/common/io/usb/clients/usbkbm/usbkbm.c
@@ -1231,7 +1231,6 @@ usbkbm_mctl_receive(register queue_t *q, register mblk_t *mp)
buf.hid_req_version_no = HID_VERSION_V_0;
buf.hid_req_wValue = SET_BOOT_PROTOCOL;
buf.hid_req_wLength = 0;
- buf.hid_req_data = NULL;
mctl_ptr = usba_mk_mctl(mctlmsg, &buf, len);
if (mctl_ptr == NULL) {
USB_DPRINTF_L2(PRINT_MASK_ALL, usbkbm_log_handle,
@@ -1270,7 +1269,7 @@ static void
usbkbm_streams_setled(struct kbtrans_hardware *kbtrans_hw, int state)
{
struct iocblk mctlmsg;
- mblk_t *LED_message, *mctl_ptr;
+ mblk_t *mctl_ptr;
hid_req_t *LED_report;
usbkbm_state_t *usbkbmd;
uchar_t led_state;
@@ -1289,14 +1288,6 @@ usbkbm_streams_setled(struct kbtrans_hardware *kbtrans_hw, int state)
* Send the request to the hid driver to set LED.
*/
- /* Create an mblk_t */
- LED_message = allocb(sizeof (uchar_t), BPRI_HI);
- if (LED_message == NULL) {
- kmem_free(LED_report, sizeof (hid_req_t));
-
- return;
- }
-
led_state = 0;
/*
@@ -1322,26 +1313,16 @@ usbkbm_streams_setled(struct kbtrans_hardware *kbtrans_hw, int state)
led_state |= USB_LED_KANA;
}
- bcopy((void *)&led_state, (void *)LED_message->b_wptr, 1);
-
- LED_message->b_wptr = LED_message->b_wptr + 1;
-
- USB_DPRINTF_L3(PRINT_MASK_ALL, usbkbm_log_handle,
- "usbkbm: Send Ctrl Request. Data is 0x%x",
- (uchar_t)*LED_message->b_rptr);
-
LED_report->hid_req_version_no = HID_VERSION_V_0;
LED_report->hid_req_wValue = REPORT_TYPE_OUTPUT;
LED_report->hid_req_wLength = sizeof (uchar_t);
- LED_report->hid_req_data = LED_message;
+ LED_report->hid_req_data[0] = led_state;
mctlmsg.ioc_cmd = HID_SET_REPORT;
mctlmsg.ioc_count = sizeof (LED_report);
mctl_ptr = usba_mk_mctl(mctlmsg, LED_report, sizeof (hid_req_t));
if (mctl_ptr != NULL) {
putnext(usbkbmd->usbkbm_writeq, mctl_ptr);
- } else {
- freemsg(LED_message);
}
/*
@@ -1903,7 +1884,6 @@ usbkbm_set_protocol(usbkbm_state_t *usbkbmd, uint16_t protocol)
buf.hid_req_version_no = HID_VERSION_V_0;
buf.hid_req_wValue = protocol;
buf.hid_req_wLength = 0;
- buf.hid_req_data = NULL;
mctl_ptr = usba_mk_mctl(mctlmsg, &buf, len);
if (mctl_ptr == NULL) {
usbkbmd->usbkbm_flags = 0;
diff --git a/usr/src/uts/common/sys/usb/clients/hid/hid.h b/usr/src/uts/common/sys/usb/clients/hid/hid.h
index 5d9e0b265a..b73a970352 100644
--- a/usr/src/uts/common/sys/usb/clients/hid/hid.h
+++ b/usr/src/uts/common/sys/usb/clients/hid/hid.h
@@ -2,9 +2,8 @@
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License"). You may not use this file except in compliance
- * with the License.
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
@@ -20,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -78,12 +77,17 @@ typedef struct hid_vid_pid {
* Hid will turn the M_CTL request into a request control request on the
* default pipe. Hid needs the following information in the hid_req_t
* structure. See the details below for specific values for each command.
+ * hid_req_data is a 256-byte buffer, which is used to transfer input, output
+ * and feature report(hid specification 6.2.2.3 long items).
*/
+
+#define MAX_REPORT_DATA 256
+
typedef struct hid_req_struct {
uint16_t hid_req_version_no; /* Version number */
uint16_t hid_req_wValue; /* wValue field of request */
uint16_t hid_req_wLength; /* wLength of request */
- mblk_t *hid_req_data; /* data for send case */
+ uchar_t hid_req_data[MAX_REPORT_DATA]; /* data for send case */
} hid_req_t;
_NOTE(SCHEME_PROTECTS_DATA("unique per call", hid_req_t))