diff options
author | gc161489 <none@none> | 2006-06-26 02:48:11 -0700 |
---|---|---|
committer | gc161489 <none@none> | 2006-06-26 02:48:11 -0700 |
commit | 59c81845bc6374ff28873a51e05d627b5b027316 (patch) | |
tree | 005720029f2c573dbd1ca05c2e7faa8947fd134f /usr/src | |
parent | 12fbe00a8d6a6a4ef84260bb64ad420204f8d1e6 (diff) | |
download | illumos-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.c | 42 | ||||
-rw-r--r-- | usr/src/uts/common/io/usb/clients/usbkbm/usbkbm.c | 24 | ||||
-rw-r--r-- | usr/src/uts/common/sys/usb/clients/hid/hid.h | 14 |
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)) |