hwahc_util.c revision 489b7c4ab76ae8df137fbfcc2214f7baa52883a0
/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* 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
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*/
/*
* Copyright 2009 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
/*
* The Data Transfer Interface driver for Host Wire Adapter device
*
* This file mainly contains the entries for HCDI interfaces.
*/
#define WUSB_GTK 1
#define WUSB_PTK 2
/* function prototypes */
extern void *hwahc_statep;
/* Check the Host controller state and return proper values */
static int
{
int rval;
return (USB_FAILURE);
}
switch (hwahcp->hwahc_hc_soft_state) {
case HWAHC_CTRL_INIT_STATE:
rval = USB_FAILURE;
break;
/* still need to check if channel is operational */
rval = USB_FAILURE;
} else {
rval = USB_SUCCESS;
}
break;
case HWAHC_CTRL_ERROR_STATE:
break;
default:
rval = USB_FAILURE;
break;
}
return (rval);
}
/* get soft state pointer */
{
return (hwahcp);
}
/*
* Do not support wusb bus PM now
*/
/* ARGSUSED */
static int
{
return (USB_FAILURE);
}
static void
/* ARGSUSED */
{
/* don't do anything now */
}
/* Wait for processing all completed transfers and to send results */
static void
{
return;
}
/* wait 3s */
"hwahc_wait_for_xfer_completion: no transfer completion "
"confirmation received");
}
}
/* remove all the unprocessed requests and do callback */
/* ARGSUSED */
static void
{
"hwahc_traverse_requests: pp = 0x%p, wr=%p", (void*)pp,
(void *)hdl->rp_curr_wr);
/*
* This CR is to tell USBA to mark this pipe as IDLE,
* so that do not queue client requests at USBA. Requests
*/
}
}
static void
{
"hwahc_do_client_periodic_in_req_callback: enter");
/*
* Check for Interrupt/Isochronous IN, whether we need to do
* callback for the original client's periodic IN request.
*/
if (pp->pp_client_periodic_in_reqp) {
if (WUSB_ISOC_ENDPOINT(eptd)) {
/* not supported */
"hwahc_do_client_periodic_in_req_callback: "
"ISOC xfer not support");
} else {
/*
* NULL wr to tell the function that we're done and
* should clear pipe's pp_client_periodic_in_reqp
*/
}
}
"hwahc_do_client_periodic_in_req_callback: end");
}
/*
* clean up the pipe, called by pipe_close/pipe_reset
* - Abort RPipe operation
* - Clean pending requests queueing on this pipe
*/
static void
{
int rval;
"hwahc_pipe_cleanup: ph = 0x%p, p_req_cnt, ep=0x%02x,"
/* abort rpipe */
/* if active, abort the requests */
}
/* wait for transfers to complete */
}
/* remove all unprocessed requests on this pipe and do callback */
case HWAHC_PIPE_STATE_CLOSE:
break;
case HWAHC_PIPE_STATE_RESET:
case HWAHC_PIPE_STATE_ERROR:
/*
* reset WA's RPipe.
* If this pipe is not bound to the default endpoint,
* also send a clear_feature request to that ep.
*/
"hwahc_pipe_cleanup: rp reset, rv=%d",
rval);
}
break;
break;
}
/*
* Do the callback for the original client
* periodic IN request.
*/
"hwahc_pipe_cleanup: end");
if ((WUSB_PERIODIC_ENDPOINT(eptd)) &&
USB_EP_DIR_IN)) {
}
}
/*
* set the pipe's parent device information
*/
static int
{
int i;
return (USB_FAILURE);
}
"hwahc_set_pipe_dev_info: pp(%p) device(%p) set",
break;
}
}
return (USB_SUCCESS);
} else {
return (USB_FAILURE);
}
}
/*
* HWA HCDI entry points
*
* The Host Controller Driver Interfaces (HCDI) are the software interfaces
* between the Universal Serial Bus Layer (USBA) and the Host Controller
* Driver (HCD). The HCDI interfaces or entry points are subject to change.
*/
/*
* hwahc_hcdi_pipe_open:
* Member of HCD Ops structure and called during client specific pipe open.
* Assign rpipe for wireless transaction to work.
* The rpipe is assigned to an endpoint until the endpoint is closed.
*/
static int
{
int rval;
int kmflag;
"hwahc_hcdi_pipe_open: hwahc=0x%p, ph=0x%p,"
if (ph->p_hcd_private) {
"hwahc_hcdi_pipe_open: Pipe is already opened");
return (USB_FAILURE);
}
"hwahc_hcdi_pipe_open: alloc pp failed");
return (USB_NO_RESOURCES);
}
"hwahc_hcdi_pipe_open: set pipe dev_info failed");
return (USB_FAILURE);
}
if (rval != USB_SUCCESS) {
"hwahc_hcdi_pipe_open: state error: %d", rval);
return (rval);
}
/* assign rpipe to the endpoint */
if (rval != USB_SUCCESS) {
"hwahc_hcdi_pipe_open: getting rpipe failed");
return (USB_NO_RESOURCES);
}
/* target the rpipe to the endpoint */
if (rval != USB_SUCCESS) {
"hwahc_hcdi_pipe_open: set target for rpipe failed");
return (USB_FAILURE);
}
return (USB_SUCCESS);
}
/*
* hwahc_hcdi_pipe_close:
* Member of HCD Ops structure and called during the client specific pipe
* close.
* Remove unprocessed transfers from the pipe and free rpipe resource.
*/
/* ARGSUSED */
static int
{
"hwahc_hcdi_pipe_close:ph=0x%p addr = 0x%x, ep = 0x%x",
"hwahc_hcdi_pipe_close: end");
return (USB_SUCCESS);
}
/*
* hwahc_hcdi_pipe_reset:
* - clean up this pipe and change its state
*/
/* ARGSUSED */
static int
{
"hwahc_hcdi_pipe_reset: ph = 0x%p, ep=0x%02x",
"hwahc_hcdi_pipe_reset: end");
return (USB_SUCCESS);
}
/*
* hwahc_hcdi_pipe_ctrl_xfer:
* - usba_hcdi_pipe_ctrl_xfer entry
* - check pipe state
* - call wa_xfer to do this request
*/
static int
{
int rval;
"hwahc_hcdi_pipe_ctrl_xfer: hwahcp=0x%p ph = 0x%p"
if (rval != USB_SUCCESS) {
return (rval);
}
/*
* if doing ctrl transfer on non-zero pipe and its state is error
* The default endpoint is critical for any other operations.
* We should not depend on upper layer to reset it.
*/
"hwahc_hcdi_pipe_ctrl_xfer: Pipe(%d) is in error"
" state, need pipe reset to continue", ep_addr);
if (ep_addr == 0) {
/*
* some error with the RPipe of EP 0,
* we need to reset this RPipe by ourself
*/
} else {
/* client driver should clear non-default endpoint's state */
return (USB_FAILURE);
}
return (USB_PIPE_ERROR);
}
if (rval != USB_SUCCESS) {
"hwahc_hcdi_pipe_ctrl_xfer failed, rval = %d", rval);
}
return (rval);
}
/*
* hwahc_hcdi_pipe_bulk_xfer:
* - usba_hcid_pipe_bulk_xfer entry
* - check the target pipe status first
* - process this request
*/
static int
{
int rval;
"hwahc_hcdi_pipe_bulk_xfer: hwahcp=0x%p ph = 0x%p reqp = 0x%p"
if (rval != USB_SUCCESS) {
return (rval);
}
"hwahc_hcdi_pipe_bulk_xfer: pp = 0x%p state= %x", (void *) pp,
"hwahc_hcdi_pipe_bulk_xfer: "
"Pipe is in error state, need pipe reset to continue");
return (USB_FAILURE);
}
if (rval != USB_SUCCESS) {
"hwahc_hcdi_pipe_bulk_xfer failed, rval = %d", rval);
}
return (rval);
}
/*
* hwahc_hcdi_pipe_intr_xfer:
* - usba_hcdi_pipe_intr_xfer entry
* - check pipe state
* - process this request
*/
static int
{
"hwahc_hcdi_pipe_intr_xfer: hwahcp=0x%p ph = 0x%p"
if (rval != USB_SUCCESS) {
return (rval);
}
"hwahc_hcdi_pipe_intr_xfer: pp = 0x%p state= %x", (void *) pp,
"hwahc_hcdi_pipe_intr_xfer: "
"Pipe is in error state, need pipe reset to continue");
return (USB_FAILURE);
}
if (rval != USB_SUCCESS) {
"hwahc_hcdi_pipe_intr_xfer failed, rval = %d", rval);
}
/*
* the request has been submitted successfully,
* save the original one; free this request when polling
* stopped
*/
}
return (rval);
}
/*
* hwahc_hcdi_pipe_isoc_xfer:
*/
/* ARGSUSED */
static int
{
return (USB_NOT_SUPPORTED);
}
/*
* hwahc_hcdi_bulk_transfer_size:
*
* Return maximum bulk transfer size
*/
/* ARGSUSED */
static int
{
int rval;
"hwahc_hcdi_bulk_transfer_size:");
if (rval != USB_SUCCESS) {
return (rval);
}
return (USB_SUCCESS);
}
/*
* hwahc_hcdi_pipe_stop_intr_polling()
*/
/* ARGSUSED */
static int
{
"hwahc_hcdi_pipe_stop_intr_polling: hwahcp=0x%p ph = 0x%p"
"hwahc_hcdi_pipe_stop_intr_polling: "
"Polling already stopped");
return (USB_SUCCESS);
}
return (USB_SUCCESS);
}
/*
* hwahc_hcdi_pipe_stop_isoc_polling()
*/
/*ARGSUSED*/
static int
{
return (USB_NOT_SUPPORTED);
}
/*
* hwahc_hcdi_get_current_frame_number:
*
* Get the current usb frame number.
* Return whether the request is handled successfully
*/
/* ARGSUSED */
static int
{
return (USB_NOT_SUPPORTED);
}
/*
* hwahc_hcdi_get_max_isoc_pkts:
*
* Get maximum isochronous packets per usb isochronous request.
* Return whether the request is handled successfully
*/
/* ARGSUSED */
static int
{
return (USB_NOT_SUPPORTED);
}
/*
* POLLED entry points
*
* These functions are entry points into the POLLED code.
*/
/*
* hwahc_hcdi_polled_input_init:
*
* This is the initialization routine for handling the USB keyboard
* in POLLED mode. This routine is not called from POLLED mode, so
* it is OK to acquire mutexes.
*/
/* ARGSUSED */
static int
{
return (USB_FAILURE);
}
/*
* hwahc_hcdi_polled_input_fini:
*/
/* ARGSUSED */
static int
{
return (USB_FAILURE);
}
/*
* hwahc_hcdi_polled_input_enter:
*
* This is where we enter into POLLED mode. This routine sets up
* everything so that calls to hwahc_hcdi_polled_read will return
* characters.
*/
/* ARGSUSED */
static int
{
return (USB_FAILURE);
}
/*
* hwahc_hcdi_polled_input_exit:
*
* This is where we exit POLLED mode. This routine restores
* everything that is needed to continue operation.
*/
/* ARGSUSED */
static int
{
return (USB_FAILURE);
}
/*
* hwahc_hcdi_polled_read:
*
* Get a key character
*/
/* ARGSUSED */
static int
{
return (USB_FAILURE);
}
/*
* hwahc_alloc_hcdi_ops:
*
* The HCDI interfaces or entry points are the software interfaces used by
* the Universal Serial Bus Driver (USBA) to access the services of the
* Host Controller Driver (HCD). During HCD initialization, inform USBA
* about all available HCDI interfaces or entry points.
*/
{
"hwahc_alloc_hcdi_ops:");
return (usba_hcdi_ops);
}
/*
* Set cluster ID.
* see 8.5.3.11
*/
int
{
int rval;
return (USB_INVALID_ARGS);
}
return (USB_INVALID_ARGS);
}
0,
NULL, 0,
&completion_reason, &cb_flags, 0);
if (rval != USB_SUCCESS) {
"Set_Cluster_ID fails: rval=%d cr=%d cb=0x%x",
}
return (rval);
}
/*
* Set WUSB Stream Index. see 8.5.3.13
*/
int
{
int rval;
return (USB_INVALID_ARGS);
}
return (USB_INVALID_ARGS);
}
0, NULL, 0, &completion_reason,
&cb_flags, 0);
if (rval != USB_SUCCESS) {
"Set_Stream_Idx fails: rval=%d cr=%d cb=0x%x",
}
return (rval);
}
/*
* 8.5.3.12 - Set WUSB MAS
* Caller must ensure the data is WUSB_SET_WUSB_MAS_LEN long.
*/
int
{
int rval, i;
return (USB_INVALID_ARGS);
}
return (USB_INVALID_ARGS);
}
for (i = 0; i < WUSB_SET_WUSB_MAS_LEN; i++) {
}
0,
&blk, 0,
&completion_reason, &cb_flags, 0);
if (rval != USB_SUCCESS) {
"Set_WUSB_MAS fails: rval=%d cr=%d cb=0x%x",
}
return (rval);
}
/* 8.5.3.1 - Add MMC IE */
int
{
int i, rval;
return (USB_INVALID_ARGS);
}
return (USB_INVALID_ARGS);
}
for (i = 0; i < len; i++) {
}
len,
&blk, 0,
&completion_reason, &cb_flags, 0);
if (rval != USB_SUCCESS) {
"Add_MMC_IE fails: rval=%d cr=%d cb=0x%x",
}
return (rval);
}
/* 8.5.3.5 - Remove MMC IE */
int
{
int rval;
return (USB_INVALID_ARGS);
}
return (USB_INVALID_ARGS);
}
0,
0,
NULL, 0,
&completion_reason, &cb_flags, 0);
if (rval != USB_SUCCESS) {
"Remove_MMC_IE fails: rval=%d cr=%d cb=0x%x",
}
return (rval);
}
/* 8.5.3.14 - WUSB Channel Stop */
int
{
int rval;
return (USB_INVALID_ARGS);
}
return (USB_INVALID_ARGS);
}
timeoff & 0x00ffffff,
0,
NULL, 0,
&completion_reason, &cb_flags, 0);
if (rval != USB_SUCCESS) {
"WUSB_Ch_Stop fails: rval=%d cr=%d cb=0x%x",
}
return (rval);
}
/* 8.5. 3.10 - Set Num DNTS Slots */
int
{
int rval;
return (USB_INVALID_ARGS);
}
return (USB_INVALID_ARGS);
}
0,
NULL, 0,
&completion_reason, &cb_flags, 0);
if (rval != USB_SUCCESS) {
"Set_Num_DNTS fails: rval=%d cr=%d cb=0x%x",
}
return (rval);
}
/* set encryptiion type for host */
int
{
int rval;
return (USB_INVALID_ARGS);
}
/* DEVICE INDEX */
if (rval != USB_SUCCESS) {
"hwahc_set_encrypt: set device encryption for port %d "
"failed", port);
}
return (rval);
}
/*
* Set Device Key for WUSB host, refer to WUSB 1.0/8.5.3.8
*
* devindex = actual port number - 1, so it is zero based
*
*/
{
int rval;
"hwahc_set_keys: klen = %d, devindex = %d", (int)klen,
devindex);
/* Table 7-21 and Errata 2005/07 */
if (devindex != 0) {
return (USB_FAILURE);
}
/* See 7.3.2.4 for key index format */
} else {
return (USB_FAILURE);
}
return (USB_FAILURE);
}
if (rval != USB_SUCCESS) {
cb_flags);
}
return (rval);
}
/* set PTK for host */
int
{
int rval;
return (USB_INVALID_ARGS);
}
/* DEVICE INDEX */
WUSB_PTK);
if (rval != USB_SUCCESS) {
"hwahc_set_ptk: set device key descr for port %d "
"failed", port);
}
return (rval);
}
/* set GTK for host */
int
{
int rval;
return (USB_INVALID_ARGS);
}
if (rval != USB_SUCCESS) {
"hwahc_set_gtk: set group key descr failed");
}
return (rval);
}
/*
* set device info for host
* Section 8.5.3.7.
*/
int
{
int rval;
return (USB_INVALID_ARGS);
}
/* the device can use all the host's reserved MASes to communicate */
/* To tell HWA device what data rates this child device supports */
/* bitmap, see7.4.1.1. Must support 53.3/106.7/200 Mbps */
} else {
}
info.bmDeviceAttribute = 0;
/* DEVICE INDEX */
return (USB_FAILURE);
}
return (rval);
}
/*
* 8.5.3.2 - 8.5.3.4 Get Time
* time_type:
* WUSB_TIME_ADJ - Get BPST Adjustment
* WUSB_TIME_BPST - Get BPST Time
* WUSB_TIME_WUSB - Get WUSB Time
*/
int
{
int rval;
return (USB_INVALID_ARGS);
}
return (USB_INVALID_ARGS);
}
/* according to WUSB 8.5.3, len is 1 or 3 */
return (USB_INVALID_ARGS);
}
if (rval != USB_SUCCESS) {
"Get_Time fails: rval=%d cr=%d cb=0x%x",
return (rval);
"Get_Time returns null data");
return (USB_FAILURE);
} else {
"Get_Time returns short length %d", length);
return (USB_FAILURE);
}
if (len == 1) {
} else {
}
return (USB_SUCCESS);
}
}