diff options
author | Garrett D'Amore <garrett@damore.org> | 2014-08-17 17:50:24 -0700 |
---|---|---|
committer | Garrett D'Amore <garrett@damore.org> | 2015-04-12 19:12:39 -0700 |
commit | e2c88f0c2610f16de7b639746b40dea5f3e2256e (patch) | |
tree | 9ce9ee8b93dbe4cd9d2e309bfd41c37ba7b78e4b | |
parent | eba03e8e19855a13cb54c87ad0767659a673b834 (diff) | |
download | illumos-joyent-e2c88f0c2610f16de7b639746b40dea5f3e2256e.tar.gz |
5832 EOF wireless usb (aka UWB)
Reviewed by: Dan McDonald <danmcd@omniti.com>
Reviewed by: Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
Reviewed by: "Joshua M. Clulow" <josh@sysmgr.org>
Approved by: Gordon Ross <gordon.w.ross@gmail.com>
110 files changed, 97 insertions, 32541 deletions
diff --git a/exception_lists/closed-bins b/exception_lists/closed-bins index 672e21f568..3b54696fa2 100644 --- a/exception_lists/closed-bins +++ b/exception_lists/closed-bins @@ -41,6 +41,9 @@ ./usr/has/bin ./usr/has/bin/patch ./usr/include/sys/pcmcia +./usr/include/sys/usb/clients/hwarc +./usr/include/sys/uwb +./usr/include/sys/uwb/uwba ./usr/kernel ./usr/kernel/strmod ./usr/kernel/strmod/amd64 diff --git a/usr/src/Makefile.lint b/usr/src/Makefile.lint index dd5d1edc72..465c40d3a6 100644 --- a/usr/src/Makefile.lint +++ b/usr/src/Makefile.lint @@ -23,6 +23,7 @@ # Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved. # Copyright (c) 2012 by Delphix. All rights reserved. # Copyright 2015 Nexenta Systems, Inc. All rights reserved. +# Copyright 2015 Garrett D'Amore <garrett@damore.org> # include global definitions include Makefile.master @@ -315,7 +316,6 @@ COMMON_SUBDIRS = \ cmd/who \ cmd/whodo \ cmd/wracct \ - cmd/wusbadm \ cmd/xargs \ cmd/xstr \ cmd/yes \ diff --git a/usr/src/cmd/Makefile b/usr/src/cmd/Makefile index 16750703b5..f54e0f9c4b 100644 --- a/usr/src/cmd/Makefile +++ b/usr/src/cmd/Makefile @@ -447,7 +447,6 @@ COMMON_SUBDIRS= \ whodo \ wracct \ write \ - wusbadm \ xargs \ xstr \ yes \ @@ -723,7 +722,6 @@ MSGSUBDIRS= \ whodo \ wracct \ write \ - wusbadm \ xargs \ yppasswd \ zdump \ diff --git a/usr/src/cmd/wusbadm/Makefile b/usr/src/cmd/wusbadm/Makefile deleted file mode 100644 index b01e042b12..0000000000 --- a/usr/src/cmd/wusbadm/Makefile +++ /dev/null @@ -1,70 +0,0 @@ -# -# 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 -# or http://www.opensolaris.org/os/licensing. -# 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. -# -# - -PROG= wusbadm -MANIFEST= wusb.xml -SVCMETHOD= svc-wusb - -include ../Makefile.cmd - -ROOTMANIFESTDIR= $(ROOTSVCSYSTEM) - -OBJS= wusbadm.o wusbd.o crypto_util.o -SRCS= $(OBJS:%.o=%.c) -POFILE= wusbadm_all.po -POFILES=$(OBJS:%.o=%.po) - - -CPPFLAGS += -I$(SRC)/uts/common -LDLIBS += -lpkcs11 -lkmf -lsysevent -lnvpair -lsecdb - -.KEEP_STATE: - -all: $(PROG) - -$(PROG): $(OBJS) - $(LINK.c) -o $@ $(OBJS) $(LDLIBS) - $(POST_PROCESS) - -install: all $(ROOTSBINPROG) $(ROOTMANIFEST) $(ROOTSVCMETHOD) - $(RM) $(ROOTUSRSBINPROG) - -$(SYMLINK) ../../sbin/$(PROG) $(ROOTUSRSBINPROG) - $(RM) $(ROOTLIB)/wusbd - -$(SYMLINK) ../../sbin/$(PROG) $(ROOTLIB)/wusbd - -check: $(PROG).c $(CHKMANIFEST) - $(CSTYLE) -pP $(SRCS:%=%) - -$(POFILE): $(POFILES) - $(RM) $@ - $(CAT) $(POFILES) > $@ - -clean: - $(RM) $(PROG) $(OBJS) $(POFILES) - -lint: lint_SRCS - -include ../Makefile.targ diff --git a/usr/src/cmd/wusbadm/crypto_util.c b/usr/src/cmd/wusbadm/crypto_util.c deleted file mode 100644 index 5bf42a73b8..0000000000 --- a/usr/src/cmd/wusbadm/crypto_util.c +++ /dev/null @@ -1,175 +0,0 @@ -/* - * 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 - * or http://www.opensolaris.org/os/licensing. - * 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. - */ - - -#include <stdlib.h> -#include <stdio.h> -#include <string.h> -#include <strings.h> -#include <sys/param.h> -#include <pwd.h> -#include <nss_dbdefs.h> -#include <auth_attr.h> -#include "crypto_util.h" - -/* init kmf handle and pkcs11 handle, for cc creation */ -int -wusb_crypto_init( - KMF_HANDLE_T *kmfhandle, - CK_SESSION_HANDLE *pkhandle, - const char *pktoken, - const char *tokendir) -{ - KMF_KEYSTORE_TYPE kstype = KMF_KEYSTORE_PK11TOKEN; - boolean_t bfalse = FALSE; - KMF_ATTRIBUTE attrlist[20]; - int numattr; - - /* change default softtoken directory */ - if (setenv("SOFTTOKEN_DIR", tokendir, 1) != 0) { - - return (-1); - } - - /* init kmf */ - if (kmf_initialize(kmfhandle, NULL, NULL) != KMF_OK) { - - return (-1); - } - - numattr = 0; - kmf_set_attr_at_index(attrlist, numattr++, - KMF_KEYSTORE_TYPE_ATTR, &kstype, sizeof (kstype)); - kmf_set_attr_at_index(attrlist, numattr++, - KMF_TOKEN_LABEL_ATTR, (void *)pktoken, strlen(pktoken) + 1); - kmf_set_attr_at_index(attrlist, numattr++, - KMF_READONLY_ATTR, &bfalse, sizeof (bfalse)); - - if (kmf_configure_keystore(*kmfhandle, numattr, attrlist) != KMF_OK) { - - return (-1); - } - - /* get pkcs11 handle from kmf */ - *pkhandle = kmf_get_pk11_handle(*kmfhandle); - if (*pkhandle == NULL) { - - return (-1); - } - - return (0); -} - -void -wusb_crypto_fini(KMF_HANDLE_T kmfhandle) -{ - (void) kmf_finalize(kmfhandle); -} - -/* random generation, for cc creation */ -int -wusb_random( - CK_SESSION_HANDLE hSession, - CK_BYTE *seed, size_t slen, - CK_BYTE *rand, size_t rlen) -{ - hrtime_t hrt; - - if (seed == NULL) { - hrt = gethrtime() + gethrvtime(); - if (C_SeedRandom(hSession, (CK_BYTE *)&hrt, - sizeof (hrt)) != CKR_OK) { - - return (-1); - } - } else { - if (C_SeedRandom(hSession, seed, slen) != CKR_OK) { - - return (-1); - } - } - - if (C_GenerateRandom(hSession, rand, rlen) != CKR_OK) { - - return (-1); - } - - return (0); -} - - -/* conver mac address to label string */ -void -mac_to_label(uint8_t *mac, char *label) -{ - int i; - - bzero(label, WUSB_CC_LABEL_LENGTH); - for (i = 0; i < WUSB_DEV_MAC_LENGTH; i++) { - (void) snprintf(label, WUSB_CC_LABEL_LENGTH, - "%s%02x", label, mac[i]); - } -} - -/* ARGSUSED */ -/* For debug only, print an array of byte */ -void -print_array(const char *label, CK_BYTE *array, size_t len) -{ -#ifdef DEBUG - int i; - - fprintf(stdout, "%s :\n", label); - for (i = 0; i < len; i++) { - fprintf(stdout, "%02x ", array[i]); - if ((i & 15) == 15) fprintf(stdout, "\n"); - } -#endif -} - -/* Check if a uid has auths */ -int -chk_auths(uid_t uid, const char *auths) -{ - struct passwd pwd; - char buf[NSS_LINELEN_PASSWD]; - - - if (uid == (uid_t)-1) { - return (-1); - } - - /* get user name */ - if (getpwuid_r(uid, &pwd, buf, sizeof (buf)) == NULL) { - return (-1); - } - - /* check the auths */ - if (chkauthattr(auths, pwd.pw_name) != 1) { - return (-1); - } - return (0); - -} diff --git a/usr/src/cmd/wusbadm/crypto_util.h b/usr/src/cmd/wusbadm/crypto_util.h deleted file mode 100644 index 065130d9a8..0000000000 --- a/usr/src/cmd/wusbadm/crypto_util.h +++ /dev/null @@ -1,96 +0,0 @@ -/* - * 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 - * or http://www.opensolaris.org/os/licensing. - * 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. - */ - -#ifndef _CRYPTO_UTIL_H -#define _CRYPTO_UTIL_H - - -#ifdef __cplusplus -extern "C" { -#endif - -#include <limits.h> -#include <security/cryptoki.h> -#include <security/pkcs11.h> -#include <kmfapi.h> - -#include <sys/usb/usba/wusba_io.h> - - -#define WUSB_DEV_MAC_LENGTH 6 -#define WUSB_CC_LABEL_LENGTH (WUSB_DEV_MAC_LENGTH * 2 + 1) -#define WUSB_TYPE_LEN 16 - -/* - * wusb_cc_info. - * Record the association information and it is - * saved at /etc/usb/wusbcc - */ -typedef struct wusb_cc_info { - uint8_t mac[WUSB_DEV_MAC_LENGTH]; - wusb_cc_t cc; /* cc info */ - char type[WUSB_TYPE_LEN]; /* device/host path */ - uint8_t host; /* Host id */ - uint16_t dev; /* Device id */ - char flag; /* Onetime/Always */ -} wusb_cc_info_t; - - -/* Device state definition */ -#define DEV_STAT_DISCONN 0x00 -#define DEV_STAT_CONNECT 0x01 - -/* wusbadm list structure */ -typedef struct wusb_cc_list { - struct wusb_cc_list *next; - wusb_cc_info_t info; /* cc info */ - uint8_t stat; /* host or device state */ -} wusb_cc_list_t; - -typedef struct wusb_device_info { - char type[WUSB_TYPE_LEN]; - uint8_t host; /* host id */ - uint16_t dev; /* device id */ - uint8_t stat; /* state */ -} wusb_device_info_t; - -/* cc generation functions */ -int wusb_crypto_init(KMF_HANDLE_T *, CK_SESSION_HANDLE *, - const char *, const char *); -void wusb_crypto_fini(KMF_HANDLE_T); - -int wusb_random(CK_SESSION_HANDLE, CK_BYTE *, size_t, CK_BYTE *, size_t); - - -void mac_to_label(uint8_t *, char *); - -void print_array(const char *, CK_BYTE *, size_t); - -int chk_auths(uid_t, const char *); -#ifdef __cplusplus -} -#endif - -#endif /* _CRYPTO_UTIL_H */ diff --git a/usr/src/cmd/wusbadm/svc-wusb b/usr/src/cmd/wusbadm/svc-wusb deleted file mode 100644 index 8b35144980..0000000000 --- a/usr/src/cmd/wusbadm/svc-wusb +++ /dev/null @@ -1,73 +0,0 @@ -#!/sbin/sh -# -# 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 -# or http://www.opensolaris.org/os/licensing. -# 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. -# -# - -. /lib/svc/share/smf_include.sh - -RUN_OK=0 -CONFIG_ERROR=1 -FATAL_ERROR=2 - -PID_FILE=/var/run/wusbd/wusb.pid -DOOR_FILE=/var/run/wusbd/wusb_door - -case "$1" in -'start') - if smf_is_nonglobalzone; then - /usr/sbin/svcadm disable $SMF_FMRI - echo "$SMF_FMRI is not supported in a local zone" - sleep 5 & - exit $SMF_EXIT_OK - fi - - - [ ! -d /var/run/wusbd ] && /usr/bin/mkdir -m 755 /var/run/wusbd - - /usr/lib/wusbd --daemon - - if [ $? -eq $CONFIG_ERROR ]; then - exit $SMF_EXIT_ERR_CONFIG - fi - - if [ $? -eq $FATAL_ERROR ]; then - exit $SMF_EXIT_ERR_FATAL - fi - ;; - -'stop') - - [ -f $PID_FILE ] && kill `cat $PID_FILE` - - rm -f $PID_FILE - rm -f $DOOR_FILE - ;; - - *) - echo "Usage: $0 start" - ;; -esac - -exit $SMF_EXIT_OK diff --git a/usr/src/cmd/wusbadm/wusb.xml b/usr/src/cmd/wusbadm/wusb.xml deleted file mode 100644 index fe35688ac9..0000000000 --- a/usr/src/cmd/wusbadm/wusb.xml +++ /dev/null @@ -1,107 +0,0 @@ -<?xml version="1.0"?> -<!DOCTYPE service_bundle SYSTEM "/usr/share/lib/xml/dtd/service_bundle.dtd.1"> -<!-- - Copyright 2009 Sun Microsystems, Inc. All rights reserved. - Use is subject to license terms. - - 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 - or http://www.opensolaris.org/os/licensing. - 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 - - NOTE: This service manifest is not editable; its contents will - be overwritten by package or patch operations, including - operating system upgrade. Make customizations in a different - file. - - Service manifest for wusbd. ---> - -<service_bundle type='manifest' name='SUNWwusb:wusbd'> - -<service - name='system/wusbd' - type='service' - version='1'> - - <create_default_instance enabled='false' /> - - <single_instance /> - - <dependency name='usr' - type='service' - grouping='require_all' - restart_on='none'> - <service_fmri value='svc:/system/filesystem/local' /> - </dependency> - - <dependency name='devices' - type='service' - grouping='require_all' - restart_on='none'> - <service_fmri value='svc:/system/device/local' /> - </dependency> - - <exec_method - type='method' - name='start' - exec='/lib/svc/method/svc-wusb start' - timeout_seconds='30' /> - - <exec_method - type='method' - name='stop' - exec='/lib/svc/method/svc-wusb stop' - timeout_seconds='30' /> - - <exec_method - type='method' - name='refresh' - exec=':kill -HUP' - timeout_seconds='30' /> - - <property_group name='config' type='application'> - </property_group> - <property_group name='general' type='framework'> - <propval name='action_authorization' type='astring' - value='solaris.smf.manage.wusb' /> - <propval name='value_authorization' type='astring' - value='solaris.smf.manage.wusb' /> - </property_group> - - <property_group name='startd' type='framework'> - <!-- sub-process core dumps shouldn't restart session --> - <propval name='ignore_error' type='astring' - value='core,signal' /> - </property_group> - - <stability value='Unstable' /> - - <template> - <common_name> - <loctext xml:lang='C'> - Wireless USB management daemon - </loctext> - </common_name> - <documentation> - <manpage title='wusbd' section='1M' manpath='/usr/man' /> - </documentation> - </template> - -</service> - -</service_bundle> diff --git a/usr/src/cmd/wusbadm/wusbadm.c b/usr/src/cmd/wusbadm/wusbadm.c deleted file mode 100644 index 94635e1ab5..0000000000 --- a/usr/src/cmd/wusbadm/wusbadm.c +++ /dev/null @@ -1,1481 +0,0 @@ -/* - * 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 - * or http://www.opensolaris.org/os/licensing. - * 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. - */ - - -#include <stdio.h> -#include <stdarg.h> -#include <sys/param.h> -#include <locale.h> -#include <dirent.h> -#include <fcntl.h> -#include <door.h> -#include <errno.h> -#include <sys/mman.h> -#include <getopt.h> -#include <assert.h> -#include <sys/stat.h> -#include <sys/usb/usba/wusba_io.h> -#include <sys/usb/clients/wusb_ca/wusb_ca.h> -#include "crypto_util.h" -#include "wusbd.h" - -/* - * EXIT STATUS - * The following exit values are returned: - * 0 Successful operation - * 1 Error: the operation failed. - * 2 Usage error. - */ -#define WUSB_EXIT_SUCCESS 0 -#define WUSB_EXIT_FAILURE 1 -#define WUSB_EXIT_USAGE 2 - - - -#define ASSO_CABLE_NAME "wusb_ca" - -#define WUSB_MAX_LEN 255 - -#define WUSB_HOSTID_LEN 2 -#define WUSB_DEVID_LEN 6 - -/* wusba admin list options */ -#define WUSB_FIELD_WIDTH 20 - -#define WUSB_LIST_HOST 0x01 -#define WUSB_LIST_DEV 0x02 -#define WUSB_LIST_HD (WUSB_LIST_HOST | WUSB_LIST_DEV) -#define WUSB_LIST_ID 0x04 -#define WUSB_LIST_TYPE 0x08 -#define WUSB_LIST_STATE 0x10 -#define WUSB_LIST_ALL (WUSB_LIST_ID | WUSB_LIST_TYPE | WUSB_LIST_STATE) - -/* cable device list */ -typedef struct dev_list { - char path[MAXPATHLEN]; - struct dev_list *next; -} dev_list_t; - -static wusb_device_info_t *dev_lists = NULL; -static uint32_t cnt = 0; - -/* log and debug helpers */ -static void wusb_prt(const char *, ...); -static void wusb_usage(const char *, ...); -static void wusb_fail(const char *, ...); -static void wusb_opterr(int, int); - - - -/* load host/dev list helpers */ -static void wusb_load_list(wusb_device_info_t **, uint32_t *cnt); -static void wusb_free_list(wusb_device_info_t *); - -/* door call helpers */ -static int wusb_door_req(int, door_arg_t *, char *, int); -static void wusb_door_free(door_arg_t *); -static uint16_t wusb_door_result(door_arg_t *da); - -/* check auths */ -static void wusb_check_auth(const char *); -/* usr input funcs */ -static void user_confirm(char *); -static void user_input(char *, char *, int); - -/* string translation helpers */ -static uint32_t str2id(char *); -static void usage(); - -/* list */ -static const struct option wusb_list_opts[] = { - { "host", no_argument, NULL, 'h'}, - { "device", no_argument, NULL, 'd'}, - { "output", required_argument, NULL, 'o'}, - {0, 0, 0, 0} -}; -static const char *WUSB_LIST_HEADER[] = { - "ID", /* host-id or dev-id */ - "STATE", /* host or device states */ - "TYPE", /* host or deivce types */ - NULL -}; - -static void do_list(int, char **); -static void do_list_args(int, char **, char *); - -static void parse_subopts(char *, const char *); -static int parse_option(char *, const char *); - -static void wusb_prt_titles(char); -static void wusb_prt_lists(char, wusb_device_info_t *); - - -static int find_dev_id(uint8_t, uint16_t); -static void parse_dev_id(const char *, wusb_dev_ctrl_t *); -static void parse_host_id(char *, uint8_t *); - -/* associate */ -static struct option wusb_asso_opts[] = { - { "host", required_argument, NULL, 'h'}, - { "cable", no_argument, NULL, 'c'}, - { "numeric", required_argument, NULL, 'n'}, - { "force", no_argument, NULL, 'f'}, - { "onetime", no_argument, NULL, 'o'}, - { 0, 0, 0, 0} -}; -static void do_associate(int, char **); -static void do_asso_args(int, char **, wusb_asso_ctrl_t *); - -static int input_host_id(uint8_t *); -static void input_dev_id(wusb_dev_ctrl_t *); -#ifdef NUMERIC_ENABLED -static int input_asso_type(uint8_t *); -#endif -static int select_cable_device(char *); - -/* remove dev */ -static struct option wusb_rmdev_opts[] = { - { "host", required_argument, NULL, 'h'}, - { "device", required_argument, NULL, 'd'}, - { "force", no_argument, NULL, 'f'}, - { 0, 0, 0, 0} -}; - -/* remove/enable/disable host */ -static struct option wusb_host_opts[] = { - { "host", required_argument, NULL, 'h'}, - { "force", no_argument, NULL, 'f'}, - { 0, 0, 0, 0} -}; - -static void do_host(int, char **, int); -static void do_host_args(int, char **, int, wusb_dev_ctrl_t *); -static void do_remove_host(int, char **); -static void do_enable_host(int, char **); -static void do_disable_host(int, char **); - -static void do_remove_dev(int, char **); -static void do_remove_dev_args(int, char **, wusb_dev_ctrl_t *); - - - -/* error message maps */ -struct errormsgs { - int code; - char *errmsg; -} wusb_errors[] = { - { WUSBADM_OK, "success" }, - { WUSBADM_AUTH_FAILURE, "permisson denied" }, - { WUSBADM_NO_HOST, "host does not exist" }, - { WUSBADM_NO_DEVICE, "device does not exist" }, - { WUSBADM_CCSTORE_ACC, "fail to access CC store" }, - { WUSBADM_NO_SUPPORT, "command not supported" }, - { WUSBADM_INVAL_HOSTID, "invalid host id" }, - { WUSBADM_INVAL_DEVID, "invalid device id" }, - { WUSBADM_HOST_NOT_ATTACH, "host not attached" }, - { WUSBADM_FAILURE, "unknown error"} -}; - -char * -wusb_strerror(int err) -{ - if (err < 0 || err > WUSBADM_FAILURE) { - - return (wusb_errors[WUSBADM_FAILURE].errmsg); - } - - return (wusb_errors[err].errmsg); -} - - -/* - * wusbadm cmd line tool is used for used to administrate the wireless usb - * host and wireless usb devices. - * list - List the device and host status - * associated - Setup assocaition between host and devices. - * remove-dev - Remove the assocation of device - * remove-host - Remove the host information and all the devices assocaiton to - * the host - * enable-host - Enable a host to be ready to accept wireless devices - * disable-host - Disable a host, host will not accpet connections - */ - -int -main(int argc, char **argv) -{ - int i; - static struct { - const char *cmd; - void (*func)(int, char **); - const char *auth; - } cmd_list[] = { - { "list", do_list, WUSB_AUTH_READ}, - { "associate", do_associate, WUSB_AUTH_MODIFY}, - { "remove-dev", do_remove_dev, WUSB_AUTH_MODIFY}, - { "remove-host", do_remove_host, WUSB_AUTH_HOST}, - { "enable-host", do_enable_host, WUSB_AUTH_HOST}, - { "disable-host", do_disable_host, WUSB_AUTH_HOST}, - { NULL, NULL} - }; - - - (void) setlocale(LC_ALL, ""); - -#ifndef TEXT_DOMAIN -#define TEXT_DOMAIN "SYS_TEST" -#endif - (void) textdomain(TEXT_DOMAIN); - - if (argc <= 1) { - usage(); - exit(WUSB_EXIT_USAGE); - } - - /* start wusb damemon */ - if (strcmp(argv[1], "--daemon") == 0) { - (void) daemonize(); - exit(WUSB_EXIT_SUCCESS); - } - - - /* wusbadm entry */ - for (i = 0; cmd_list[i].cmd; i++) { - if (strcmp(cmd_list[i].cmd, argv[1]) == 0) { - break; - } - } - if (!cmd_list[i].cmd) { - wusb_usage("unknown option %s", argv[1]); - } - wusb_check_auth(cmd_list[i].auth); - - wusb_load_list(&dev_lists, &cnt); - - cmd_list[i].func(argc - 1, &argv[1]); - - wusb_free_list(dev_lists); - return (WUSB_EXIT_SUCCESS); -} - -static void -usage() -{ - wusb_prt("\nUsage:\twusbadm sub-command args ...\n\n"); - wusb_prt("\tlist [-h | -d] [-o field[,...]]\n"); - wusb_prt("\tassociate [-h host-id] [[-c [-f]] | -n] [-o]\n"); - wusb_prt("\tremove-dev [[-d dev-id] | [-h host-id]] [-f]\n"); - wusb_prt("\tremove-host [-h host-id] [-f]\n"); - wusb_prt("\tenable-host [-h host-id]\n"); - wusb_prt("\tdisable-host [-h host-id] [-f]\n"); - wusb_prt("\n"); -} - -/* - * list command routine. - * wusbadmin list [-h | -d] [-o field[,...]] - * 1. parse the options - * 2. load host/deivce info from daemon - * 3. print titles accoding to list options - * 4. print host/deivce list one by one - */ -static void -do_list(int argc, char **argv) -{ - char fields = 0x0; - int i; - - /* parse the list options */ - do_list_args(argc, argv, &fields); - - - /* print list title */ - wusb_prt_titles(fields); - - /* print out the result */ - for (i = 0; i < cnt; i++) { - wusb_prt_lists(fields, &dev_lists[i]); - } - - -} - -/* - * associate command routine - * wusbadmin associate [-h host-id] [[-c [-f] | -n] [-o] - * 1. Parse the options and get user input - * 2. Send the asso infor the daemon - */ -static void -do_associate(int argc, char **argv) -{ - door_arg_t da; - wusb_asso_ctrl_t asso_ctrl; - uint16_t rval = 0; - - /* Get association options */ - bzero(&asso_ctrl, sizeof (wusb_asso_ctrl_t)); - do_asso_args(argc, argv, &asso_ctrl); - - /* open door file */ - (void) wusb_door_req(WUSB_DCMD_ASSOCIATE, &da, - (char *)&asso_ctrl, sizeof (wusb_asso_ctrl_t)); - - /* association result */ - rval = wusb_door_result(&da); - - wusb_door_free(&da); - - if (rval != WUSBADM_OK) { - wusb_fail("%s", wusb_strerror(rval)); - } - -} -/* - * remove-dev command routine - * remove-dev [[-d dev-id] | [-h host-id]] [-f] - * 1. parse options/user input - * 2. send message to daemon. - * dev-id != 0 means remove one dev - * dev-id == 0 means remove all dev with a host - */ -static void -do_remove_dev(int argc, char **argv) -{ - wusb_dev_ctrl_t devctrl; - door_arg_t da; - - uint16_t rval = WUSBADM_OK; - - /* parse options */ - bzero(&devctrl, sizeof (wusb_dev_ctrl_t)); - do_remove_dev_args(argc, argv, &devctrl); - - /* send command to daemon */ - (void) wusb_door_req(WUSB_DCMD_REMOVE_DEV, &da, - (char *)&devctrl, sizeof (wusb_dev_ctrl_t)); - - - rval = wusb_door_result(&da); - - wusb_door_free(&da); - - if (rval != WUSBADM_OK) { - wusb_fail("%s", wusb_strerror(rval)); - } - - -} - -/* - * Send the LOAD_CC request to daemon. Daemon will allocate memory and put - * all CCs in that block of memory. We need to free the memory here. - * CCs are in data array format. - */ -static void -wusb_load_list(wusb_device_info_t **cc_list, uint32_t *cnt) -{ - door_arg_t da; - - size_t buflen = 0; - uint32_t num = 0; - uint16_t rval = WUSBADM_OK; - - /* send command to daemon */ - (void) wusb_door_req(WUSB_DCMD_LIST_DATA, &da, 0, 0); - - rval = wusb_door_result(&da); - if (rval != WUSBADM_OK) { - wusb_door_free(&da); - - wusb_fail("%s", wusb_strerror(rval)); - } - - /* number of the devinfo list */ - (void) memcpy(&num, da.data_ptr+sizeof (uint16_t), sizeof (uint32_t)); - - if (num) { - - buflen = (num) * sizeof (wusb_device_info_t); - if ((*cc_list = malloc(buflen)) == NULL) { - wusb_door_free(&da); - - wusb_fail("list: malloc buffer failed"); - } - - (void) memcpy(*cc_list, - da.data_ptr + sizeof (uint32_t) + sizeof (uint16_t), - buflen); - } - *cnt = num; - - /* unmap the buffer */ - wusb_door_free(&da); -} -static void -wusb_free_list(wusb_device_info_t *cc_list) -{ - if (cc_list) { - free(cc_list); - } - cnt = 0; -} - -/* - * This is a wrapper of door call for wusb adm tool. - * Mandatory: - * cmd - wusb admin command (WUSB_DCMD_*). - * da - door call arg. - * Optional: - * databuf - data send to daemon. - * size - data buf size. - */ -static int -wusb_door_req(int cmd, door_arg_t *da, char *databuf, int size) -{ - wusb_door_call_t dcall; - int fd = -1; - - bzero(&dcall, sizeof (wusb_door_call_t)); - dcall.cmdss = cmd; - - /* copy data buffer */ - if (databuf) { - (void) memcpy(dcall.buf, databuf, size); - } - - /* set rbuf to 0, unmap the data buf later */ - bzero(da, sizeof (door_arg_t)); - da->data_ptr = (char *)&dcall; - da->data_size = sizeof (wusb_door_call_t); - da->rbuf = 0; - da->rsize = 0; - - /* open door file */ - if ((fd = open(DOOR_FILE, O_RDONLY)) < 0) { - - wusb_fail("daemon not started"); - } - - /* make door call */ - if (door_call(fd, da) != 0) { - (void) close(fd); - - wusb_fail("daemon out of service:%s", strerror(errno)); - } - - (void) close(fd); - - if (da->data_size == 0) { - - wusb_fail("no data from daemon"); - } - - return (WUSBA_SUCCESS); -} - -/* - * After each door call return, the first 2 bytes of the data - * returned is encoded as the door call result from daemon. - * This is a wrapper to get the door call result - */ -uint16_t -wusb_door_result(door_arg_t *da) { - uint16_t rval = 0; - (void) memcpy(&rval, da->data_ptr, sizeof (uint16_t)); - - return (rval); -} - -/* - * Unmap the buffer after door call. - * It is mandatory after any wusb_door_call since we set the rbuf to NULL - * in the wusb_door_call. So any buffer returned is from the client proces. - * See door_call(3C) for more infor - */ -static void -wusb_door_free(door_arg_t *da) -{ - (void) munmap(da->rbuf, da->rsize); -} - -/* - * wusbadmin remove-host routine - * remove-host [-h host-id] [-f] - */ -static void -do_remove_host(int argc, char **argv) -{ - do_host(argc, argv, WUSB_DCMD_REMOVE_HOST); -} - -/* - * wusbadmin enable-host routine - * enable-host [-h host-id] - */ -static void -do_enable_host(int argc, char **argv) -{ - do_host(argc, argv, WUSB_DCMD_ENABLE_HOST); -} - -/* - * wusbadmin disable-host routine - * disable-host [-h host-id] [-f] - */ -static void -do_disable_host(int argc, char **argv) -{ - do_host(argc, argv, WUSB_DCMD_DISABLE_HOST); -} - -/* - * wusb do host routine. The wrapper for all host related - * subcommand (enable-host, disable-host, remove-host). - * 1. parser options/user input - * 2. send wusb command to daemon - */ -static void -do_host(int argc, char **argv, int cmd) -{ - wusb_dev_ctrl_t hostctrl; - door_arg_t da; - - uint16_t rval = 0; - - /* parse options */ - bzero(&hostctrl, sizeof (wusb_dev_ctrl_t)); - do_host_args(argc, argv, cmd, &hostctrl); - - /* door call to daemon */ - (void) wusb_door_req(cmd, &da, - (char *)&hostctrl, sizeof (wusb_dev_ctrl_t)); - - rval = wusb_door_result(&da); - wusb_door_free(&da); - - if (rval != WUSBADM_OK) { - wusb_fail("%s", wusb_strerror(rval)); - } -} - -/* - * wusb list option parser - * wusbadmin list [-h | -d] [-o field[,...]] - */ -static void -do_list_args(int argc, char **argv, char *option) -{ - char fields = 0x0; - int c; - - while ((c = getopt_long(argc, argv, ":hdo:", - wusb_list_opts, NULL)) != -1) { - switch (c) { - case 'h': - if (fields & WUSB_LIST_HOST) { - wusb_usage("too many -h specified"); - } - if (fields & WUSB_LIST_DEV) { - wusb_usage("-h and -d used together"); - } - fields |= WUSB_LIST_HOST; - break; - case 'd': - if (fields & WUSB_LIST_HOST) { - wusb_usage("-h and -d used together"); - } - if (fields & WUSB_LIST_DEV) { - wusb_usage("too many -d specified"); - } - fields |= WUSB_LIST_DEV; - break; - case 'o': - if (strlen(optarg) > 63) { - wusb_usage("options too long"); - } - (void) parse_option(&fields, optarg); - break; - default: - wusb_opterr(optopt, c); - break; - } - } - - if (optind < argc) { - wusb_usage("unrecognized options:%s", argv[optind++]); - } - - /* if no option specified,print out all fields */ - fields |= (fields & WUSB_LIST_HD)? 0x00:WUSB_LIST_HD; - fields |= (fields & WUSB_LIST_ALL)? 0x00:WUSB_LIST_ALL; - - *option = fields; - - -} -/* - * Print the header for list subcommand. - * Each title is right aligned with length of WUSB_FIELD_WIDTH - * The following titles will be printed if the relative tags - * marked in the fields option. - * ID STATE TYPE - */ -static void -wusb_prt_titles(char fields) -{ - int i = 0; - char option; - for (option = WUSB_LIST_ID; - option <= WUSB_LIST_STATE; - option <<= 1, i++) { - if (fields & option) { - wusb_prt("%-*s", WUSB_FIELD_WIDTH, - WUSB_LIST_HEADER[i]); - } - } - - (void) putchar('\n'); - -} -/* - * Append the host-id / dev-id to the output buf. - * host-id - 2 digits number (XX) - * dev-id - 5 digits number (XX.XXX) - * See wusbadm (1M) for more - */ -static void -append_id(char *buf, wusb_device_info_t *devinfo) -{ - char tmp[WUSB_MAX_LEN] = {'\0'}; - - if (devinfo->dev) { - (void) snprintf(tmp, WUSB_MAX_LEN, "%02d.%03d", - devinfo->host, devinfo->dev); - } else { - (void) snprintf(tmp, WUSB_MAX_LEN, "%02d", devinfo->host); - } - (void) snprintf(buf, WUSB_MAX_LEN, "%s%-*s", - buf, WUSB_FIELD_WIDTH, tmp); -} -/* - * Append state to the output buf. - * host - enabled/disabled - * device - connected/disconnected - * See wusbadm (1M) for more - */ -static void -append_state(char *buf, wusb_device_info_t *devinfo) -{ - const char *WUSB_DEV_STATE_MSG[] = { - "disconnected", /* WUSB_STATE_UNCONNTED */ - "connected", /* WUSB_STATE_CONNTING */ - "connected", /* WUSB_STATE_UNAUTHENTICATED */ - "connected", /* WUSB_STATE_DEFAULT */ - "connected", /* WUSB_STATE_ADDRESSED */ - "connected", /* WUSB_STATE_CONFIGURED */ - "connected", /* WUSB_STATE_SLEEPING */ - "connected", /* WUSB_STATE_RECONNTING */ - NULL - }; - const char *WUSB_HOST_STATE_MSG[] = { - "disconnected", /* WUSB_HC_DISCONNTED */ - "disabled", /* WUSB_HC_STOPPED */ - "enabled", /* WUSB_HC_STARTED */ - "disabled", /* WUSB_HC_CH_STOPPED */ - NULL - }; - char tmp[WUSB_MAX_LEN] = {'\0'}; - - if (devinfo->dev) { - - /* append the state for device */ - if (devinfo->stat > WUSB_STATE_RECONNTING) { - (void) snprintf(tmp, WUSB_MAX_LEN, "%s", "unknown"); - } else { - (void) snprintf(tmp, WUSB_MAX_LEN, "%s", - WUSB_DEV_STATE_MSG[devinfo->stat]); - } - } else { - /* append the state for host */ - if (devinfo->stat > WUSB_HC_CH_STOPPED) { - (void) snprintf(tmp, WUSB_MAX_LEN, "%s", "unknown"); - } else { - (void) snprintf(tmp, WUSB_MAX_LEN, "%s", - WUSB_HOST_STATE_MSG[devinfo->stat]); - } - } - (void) snprintf(buf, WUSB_MAX_LEN, "%s%-*s", - buf, WUSB_FIELD_WIDTH, tmp); -} - - -/* - * Appenend host/dev type to the ouput buf string - * Currently map the file name to specific types - * TODO: how to define the type - */ -static void -append_type(char *buf, wusb_device_info_t *devinfo) -{ - (void) snprintf(buf, WUSB_MAX_LEN, "%s%-*s", buf, WUSB_FIELD_WIDTH, - devinfo->type); -} - - -/* - * This is core func to print wireless device list on systems. - * Print the devinfo list entry with option field - */ -static void -wusb_prt_lists(char fields, wusb_device_info_t *devinfo) -{ - char buf[WUSB_MAX_LEN+1] = {'\0'}; - int i = 0; - char opt = 0; - void (*append_funcs[])(char *, wusb_device_info_t *) = { - append_id, - append_state, - append_type, - NULL - }; - - /* check if dev or host need to be print out */ - if ((devinfo->dev && !(fields & WUSB_LIST_DEV)) || - (!devinfo->dev && !(fields & WUSB_LIST_HOST))) { - return; - } - - /* Append all the enabled fields to the output buf */ - for (i = 0, opt = WUSB_LIST_ID; - opt <= WUSB_LIST_STATE; - opt <<= 1, i++) { - if (fields & opt) { - append_funcs[i](buf, devinfo); - } - } - - wusb_prt("%s\n", buf); -} - -/* - * wusb association option parser - * wusbadmin association [-h host-id] [[-c [-f] | -n] [-o] - * Note:Only cable association is supported now - */ -static void -do_asso_args(int argc, char **argv, wusb_asso_ctrl_t *asso_ctrl) -{ - int c; - int force = 0; - - while ((c = getopt_long(argc, argv, ":h:cfno", wusb_asso_opts, 0)) - != -1) { - switch (c) { - case 'h': - parse_host_id(optarg, &(asso_ctrl->host)); - break; - case 'c': - asso_ctrl->type |= ASSO_TYPE_CABLE; - break; - case 'n': - asso_ctrl->type |= ASSO_TYPE_NUMERIC; - break; - case 'f': - force = 1; - break; - case 'o': - asso_ctrl->onetime = 1; - break; - default: - wusb_opterr(optopt, c); - break; - } - } - - if (optind < argc) { - wusb_usage("unrecognized options:%s", argv[optind++]); - } - - /* TODO: support cable association */ - if (asso_ctrl->type & ASSO_TYPE_NUMERIC) { - - wusb_fail("Numeric association not supported"); - } - - /* get user input host id */ - if (!asso_ctrl->host) { - (void) input_host_id(&asso_ctrl->host); - } - - /* get user input association type */ - if (!asso_ctrl->type) { - asso_ctrl->type |= ASSO_TYPE_CABLE; - /* Todo: Will be enabled after Numberic Assocation support */ - -#ifdef NUMERIC_ENABLED - (void) input_asso_type(&asso_ctrl->type); -#endif - } - - /* get user input cable device to associate */ - if (asso_ctrl->type == ASSO_TYPE_CABLE) { - (void) select_cable_device(asso_ctrl->path); - } - - /* confirm with user to continue or not */ - if (!force) { - wusb_prt("Associate device (%s) with host (%02d) via cable\n", - asso_ctrl->path, asso_ctrl->host); - user_confirm("Continue "); - } - -} -/* - * Convert a string to an id (host-id/dev-id/cable-dev-id) - * Fail if 0 returned, since each id is indexed from 1. - * Widely used to handle user input ids. - */ -static uint32_t -str2id(char *arg) -{ - uint32_t id = 0; - - /* check the string and generate int result */ - while (*arg) { - if (*arg < '0' || *arg > '9') { - - return (0); - } - id = id*10+(*arg-'0'); - arg++; - } - - return (id); -} - -static void -parse_host_id(char *arg, uint8_t *host) { - int len = strlen(arg); - - if ((len > WUSB_HOSTID_LEN) || (len == 0)) { - wusb_fail("host-id should be 2 digits"); - } - if ((*host = str2id(arg)) == 0) { - wusb_fail("invalid host id:%s", arg); - } - if (find_dev_id(*host, 0) < 0) { - wusb_fail("host-id does not exist: %02d ", *host); - } - - return; - -} -/* - * Get the host from user input. - * 1. list all the host id from the daemon - * 2. Ask user to input the host id - * 3. Check host id and return - */ -static int -input_host_id(uint8_t *host) -{ - - char fields = WUSB_LIST_HOST | WUSB_LIST_ALL; - char buf[WUSB_MAX_LEN] = {'\0'}; - int i = 0; - - - - /* show avaialbe host id to usr */ - wusb_prt_titles(fields); - for (i = 0; i < cnt; i++) { - wusb_prt_lists(fields, &dev_lists[i]); - } - - /* get user input of host id */ - user_input("Please select 2 digits host-id:", buf, WUSB_MAX_LEN-1); - parse_host_id(buf, host); - - return (WUSBA_SUCCESS); -} -static void -input_dev_id(wusb_dev_ctrl_t *devctrl) -{ - - char fields = WUSB_LIST_DEV | WUSB_LIST_ALL; - char buf[WUSB_MAX_LEN] = {'\0'}; - int i = 0; - - - - /* show avaialbe host id to usr */ - wusb_prt_titles(fields); - for (i = 0; i < cnt; i++) { - wusb_prt_lists(fields, &dev_lists[i]); - } - - /* get user input of host id */ - user_input("Please select dev-id:", buf, WUSB_MAX_LEN-1); - - parse_dev_id(buf, devctrl); -} -static int -find_dev_id(uint8_t host, uint16_t dev) -{ - int rval = WUSBA_FAILURE; - int i; - - for (i = 0; i < cnt; i++) { - if ((dev_lists[i].dev == dev) && - (dev_lists[i].host == host)) { - rval = WUSBA_SUCCESS; - - break; - } - } - - return (rval); -} - -/* - * Select assocation type. - * - Cable - * - Numeric Not supported - */ -#ifdef NUMERIC_ENABLED -static int -input_asso_type(uint8_t *asso_type) -{ - char buf[15] = {'\0'}; - - user_input("Select association type (c/n) :", buf, 14); - if (strcasecmp(buf, "c") == 0) { - *asso_type = ASSO_TYPE_CABLE; - - } else if (strcasecmp(buf, "n") == 0) { - *asso_type = ASSO_TYPE_NUMERIC; - - } else { - - wusb_usage("invalid association type"); - } - return (WUSBA_SUCCESS); -} -#endif - -/* - * Create a list contains all the cable devices on the system - */ -static void -init_cable_devices(dev_list_t **dev_lists, int *num) -{ - struct dirent *entry = NULL; - dev_list_t *_devlist = NULL; - - DIR *dirp = opendir(WUSB_HOST_PATH); - char filename[MAXPATHLEN] = {'\0'}; - - *num = 0; - /* - * walk on all the filename in the /dev/usb, check the filename - * to see if it is a cable asso filename and add it to the devinfo - * list if so - */ - if (!dirp) { - wusb_fail("cable device not available"); - } - while ((entry = readdir(dirp)) != NULL) { - /* searching for cable node */ - if (strstr(entry->d_name, ASSO_CABLE_NAME) == NULL) { - continue; - } - (void) snprintf(filename, MAXPATHLEN, "%s/%s", - WUSB_HOST_PATH, entry->d_name); - - /* add the filename to the dev list */ - if (_devlist == NULL) { - _devlist = malloc(sizeof (dev_list_t)); - *dev_lists = _devlist; - } else { - _devlist->next = malloc(sizeof (dev_list_t)); - _devlist = _devlist->next; - } - /* this need to be freed */ - (void) snprintf(_devlist->path, MAXPATHLEN, - "%s", filename); - - _devlist->next = NULL; - - /* increase the list number */ - (*num)++; - } - (void) closedir(dirp); -} -/* Free the devlist created for cable device */ -static void -free_devlist(dev_list_t *dev_list) -{ - dev_list_t *head = dev_list; - while (head) { - head = dev_list->next; - free(dev_list); - dev_list = head; - } -} - -/* find the cable dev with the user-inputed index */ -static dev_list_t * -get_cable_dev(dev_list_t *dev_list, int index) -{ - int i = 1; - while ((i != index) && dev_list) { - dev_list = dev_list->next; - i++; - } - - return (dev_list); -} -/* print the cable devlist with index */ -static void -show_devlist(dev_list_t *dev_list) -{ - /* show all the cable devices to user */ - int index = 1; - wusb_prt("Cable devices on the system:\n"); - while (dev_list) { - wusb_prt("%03d. %s\n", index, dev_list->path); - dev_list = dev_list->next; - index++; - } - -} -/* - * when doing association, all the cable devices on the system - * should be print out to the user - */ -static int -select_cable_device(char *device) -{ - /* cable association */ - char buf[32]; - int cableid = 1; - - dev_list_t *head = NULL; - dev_list_t *tmp = NULL; - int devnum = 0; - - /* get all the cable dev on the system */ - init_cable_devices(&head, &devnum); - - /* Get the device name as user input */ - if (!head) { - wusb_fail("no cable devices found "); - } - - if (devnum != 1) { - show_devlist(head); - - /* get the user input of the cable dev index */ - user_input("Select cable device to associate:", buf, 19); - if (strlen(buf) != 3) { - wusb_fail("cable device id should be 3 digits"); - } - cableid = str2id(buf); - - /* check user iput */ - if ((cableid <= 0) || (cableid > devnum)) { - free_devlist(head); - - wusb_fail("invalid cable device "); - } - - } else { - /* if only one dev exist, use it without asking user */ - cableid = 1; - } - - /* find the device to associate */ - tmp = get_cable_dev(head, cableid); - (void) snprintf(device, MAXPATHLEN, "%s", tmp->path); - - /* free the list */ - free_devlist(head); - - return (WUSBA_SUCCESS); - -} -/* - * Parse the -o option for wusbadm list - */ -static int -parse_option(char *fields, const char *optarg) -{ - - char *lasts = NULL, *token = NULL; - char buf[64] = { '\0' }; - - (void) snprintf(buf, 64, "%s", optarg); - if ((token = strtok_r(buf, ",", &lasts)) != 0) { - parse_subopts(fields, token); - while ((token = strtok_r(NULL, ",", &lasts))) { - parse_subopts(fields, token); - } - } - - return (WUSBA_SUCCESS); - -} - -/* - * wusbadmin list - * parse the sub option extracted from -o options - */ -static void -parse_subopts(char *fields, const char *str) -{ - int i; - char opt; - for (i = 0, opt = WUSB_LIST_ID; opt <= WUSB_LIST_STATE; i++) { - if (strcasecmp(str, WUSB_LIST_HEADER[i]) == 0) { - *fields |= opt; - break; - } - opt = opt << 1; - } - - if (opt > WUSB_LIST_STATE) { - - wusb_usage("unrecognized options:%s", str); - } - -} - -/* - * Device id parser for remove-dev - * dev id is 5 digits with format XX.XXX - */ -void -parse_dev_id(const char *arg, wusb_dev_ctrl_t *devctrl) -{ - char buf[WUSB_DEVID_LEN+1] = {'\0'}; - char *tmp = NULL; - - if (strlen(arg) > WUSB_DEVID_LEN) goto fail; - - (void) snprintf(buf, WUSB_DEVID_LEN+1, "%s", arg); - - if ((tmp = strchr(buf, '.')) == NULL) goto fail; - /* get host id */ - *tmp = '\0'; - if ((devctrl->host = str2id(buf)) == 0) { - goto fail; - } - - /* get device id */ - if ((devctrl->dev = str2id(tmp+1)) == 0) { - goto fail; - } - - if (find_dev_id(devctrl->host, devctrl->dev) < 0) { - wusb_fail("dev-id does not exist: %02d.%03d ", - devctrl->host, devctrl->dev); - } - - return; -fail: - wusb_fail("unknown device id:%s", arg); - -} -/* - * remove-dev options parser - * remove-dev [[-d dev-id] | [-h host-id]] [-f] - */ -static void -do_remove_dev_args(int argc, char **argv, wusb_dev_ctrl_t *devctrl) -{ - int c; - int force = 0; - bzero(devctrl, sizeof (wusb_dev_ctrl_t)); - - while ((c = getopt_long(argc, argv, ":h:d:f", - wusb_rmdev_opts, NULL)) != -1) { - switch (c) { - case 'h': - if (devctrl->dev) { - wusb_usage("-h -d can not be" - "used together"); - } - if (devctrl->host) { - wusb_usage("multi -h is not allowed"); - } - - /* get 2 digit host id */ - parse_host_id(optarg, &(devctrl->host)); - - break; - - case 'd': - if (devctrl->dev) { - wusb_usage("multi -d is not allowed"); - } - if (devctrl->host) { - wusb_usage("-h -d can not be" - "used together"); - } - /* parse devid */ - (void) parse_dev_id(optarg, devctrl); - break; - case 'f': - force = 1; - break; - default: - wusb_opterr(optopt, c); - break; - - } - } - - if (optind < argc) { - wusb_usage("unrecognized options:%s", argv[optind++]); - } - if ((devctrl->host == 0) && (devctrl->dev == 0)) { - input_dev_id(devctrl); - } - - /* confirm with user to continue or not */ - if (!force) { - if (devctrl->dev) { - wusb_prt("Remove the device's association information" - " of device (%02d.%03d) from system.\nThis device" - " can not be connected with the host until it is" - " associated again.\n", - devctrl->host, devctrl->dev); - } else { - wusb_prt("Remove the information of all the devices " - "associated with host (%02d) from the system\n" - "All the devices asociated with the host can not" - " be connected with it until they are associated" - " again.\n", devctrl->host); - } - user_confirm("Continue "); - } -} -/* - * Confirm with user continue or not - * info: the information shown to user before input - */ -static void -user_confirm(char *info) -{ - char yesorno[20]; - - wusb_prt(info); - user_input("(yes/no): ", yesorno, 19); - if (strcasecmp(yesorno, "no") == 0) { - wusb_fail(""); - } - if (strcasecmp(yesorno, "n") == 0) { - wusb_fail(""); - } - if (strcasecmp(yesorno, "yes") == 0) { - return; - } - if (strcasecmp(yesorno, "y") == 0) { - return; - } - wusb_fail("illegal input: %s", yesorno); -} -/* - * Get user input - * msg(in): infor shown to user before input - * length(in): buf size to save uer input - * buf(out): user input saved in buffer - */ -static void -user_input(char *msg, char *buf, int length) -{ - int i = 0, b; - - wusb_prt(msg); - /*CONSTCOND*/ - while (1) { - b = getc(stdin); - if (b == '\n' || b == '\0' || b == EOF) { - if (i < length) - buf[i] = 0; - break; - } - if (i < length) - buf[i] = b; - i++; - } - if (i >= length) { - buf[length] = 0; - } - -} -/* - * do host options parser - * remove-host [-h host-id] [-f] - * enable-host [-h host-id] - * disable-host [-h host-id] [-f] - */ -static void -do_host_args(int argc, char **argv, int cmd, wusb_dev_ctrl_t *hostctrl) -{ - int c; - int force = 0; - - while ((c = getopt_long(argc, argv, ":h:f", - wusb_host_opts, NULL)) != -1) { - switch (c) { - case 'h': - if (hostctrl->host) { - wusb_usage("multi -h is not allowed"); - } - /* 2 digits host id */ - parse_host_id(optarg, &(hostctrl->host)); - - break; - - case 'f': - /* enable host does not need -f */ - if (cmd == WUSB_DCMD_ENABLE_HOST) { - wusb_opterr(optopt, c); - } - force = 1; - break; - default: - wusb_opterr(optopt, c); - break; - - } - } - if (optind < argc) { - wusb_usage("unrecognized options:%s", argv[optind++]); - } - /* - * all the host related command can be used without a specific - * host-id, so list all the hosts avalable to users for selection - */ - if (hostctrl->host == 0) { - (void) input_host_id(&(hostctrl->host)); - } - - - /* confirm with user to continue or not */ - if (!force && (cmd != WUSB_DCMD_ENABLE_HOST)) { - switch (cmd) { - case WUSB_DCMD_DISABLE_HOST: - wusb_prt("Disable host (%02d).\nAll the" - " devices connected with the host will be" - " disconnected\n", hostctrl->host); - break; - - case WUSB_DCMD_REMOVE_HOST: - wusb_prt("Remove host (%02d).\nAll the" - " association with the host will be" - " removed\n", hostctrl->host); - break; - default: - break; - } - user_confirm("Continue"); - } - -} - -static void -wusb_check_auth(const char *auth) { - - uid_t uid = geteuid(); - if (chk_auths(uid, auth) < 0) { - wusb_fail("%s", wusb_strerror(WUSBADM_AUTH_FAILURE)); - } - -} -/* - * wusb exit helper funcstion - * wusb_fail or wusb_usage - */ -static void -wusb_fail(const char *format, ...) -{ - va_list alist; - - format = gettext(format); - (void) fprintf(stderr, gettext("wusbadm: ")); - va_start(alist, format); - (void) vfprintf(stderr, format, alist); - va_end(alist); - (void) fprintf(stderr, "\n"); - - wusb_free_list(dev_lists); - exit(WUSB_EXIT_FAILURE); -} -static void -wusb_usage(const char *format, ...) -{ - va_list alist; - - format = gettext(format); - (void) fprintf(stderr, gettext("wusbadm: ")); - va_start(alist, format); - (void) vfprintf(stderr, format, alist); - va_end(alist); - (void) fprintf(stderr, "\n"); - usage(); - - wusb_free_list(dev_lists); - exit(WUSB_EXIT_USAGE); -} - - -/* wusb print helper func */ -static void -wusb_prt(const char *format, ...) -{ - va_list alist; - - format = gettext(format); - va_start(alist, format); - (void) vfprintf(stdout, format, alist); - va_end(alist); -} - -/* wusb option failuer func */ -static void -wusb_opterr(int opt, int opterr) -{ - switch (opterr) { - case ':': - wusb_usage("option '-%c' requires a value", opt); - break; - case '?': - default: - wusb_usage("unrecognized option '-%c'", opt); - break; - } -} diff --git a/usr/src/cmd/wusbadm/wusbd.c b/usr/src/cmd/wusbadm/wusbd.c deleted file mode 100644 index b661eee394..0000000000 --- a/usr/src/cmd/wusbadm/wusbd.c +++ /dev/null @@ -1,2578 +0,0 @@ -/* - * 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 - * or http://www.opensolaris.org/os/licensing. - * 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. - */ - -#include <unistd.h> -#include <stdarg.h> -#include <sys/stat.h> -#include <stdio.h> -#include <signal.h> -#include <door.h> -#include <libsysevent.h> -#include <sys/sunddi.h> -#include <sys/wait.h> -#include <fcntl.h> -#include <syslog.h> -#include <pthread.h> -#include <dirent.h> -#include <locale.h> -#include <alloca.h> /* alloca */ -#include <errno.h> -#include <pwd.h> - -#include <priv_utils.h> -#include <priv.h> - -#include <sys/usb/usba/wusba_io.h> -#include <sys/usb/clients/wusb_ca/wusb_ca.h> -#include "crypto_util.h" -#include "wusbd.h" - - -/* deamon exit status code */ -#define CONFIG_ERROR 1 -#define FATAL_ERROR 2 - -#define PKTOKEN "Sun Software PKCS#11 softtoken " -#define TOKENDIR "/etc/usb" - -/* Restrict the max number association for one host to 200 */ -#define HOST_MAX 100 -#define DEV_MAX 200 - -/* global mutext for door service */ -static pthread_mutex_t mutex_cclock = PTHREAD_MUTEX_INITIALIZER; -static void wusbd_daemon_enter(); -static void wusbd_daemon_leave(char *, int); - - -static wusb_cc_list_t *global_cclist = NULL; -static uint32_t cc_cnt = 0; -static wusb_cc_list_t *devids[HOST_MAX][DEV_MAX]; - - -/* cc utility funcs */ -static int save_cc(const wusb_cc_info_t *); -static int save_cc_to_list(const wusb_cc_info_t *); -static int save_cc_to_store(const wusb_cc_info_t *); - - -static void refresh(int); -static void event_handler(sysevent_t *); - -/* daemon init functions */ -static int wusbd_daemonize_init(void); -static void wusbd_daemonize_fini(int, int); -static int init_daemon_pid(); -static int init_sys_evnt(); -static int init_door_srv(); -static int init_global_cc_list(); -static void print_prv(); - -static void exit_clean(int); - -/* walk on all hosts in system */ -typedef void (* host_func)(const char *); -static void all_hosts_iterate(host_func); - - -/* walk on all cc list */ -typedef int (* cc_list_func)(wusb_cc_list_t *, void *); -static void global_list_iterate(cc_list_func, void *); -static void add_to_global_list(wusb_cc_list_t *); -static void remove_from_global_list(wusb_cc_list_t *); - -/* update cc list device status */ -static void clean_all_cc_list(); -static void update_cc_list(const char *); -static void update_all_cc_list(); -static int update_cc_file(); - -static int add_all_cc_to_host(const char *, uint8_t); -static int remove_cc_from_host(uint8_t, uint16_t); -static int remove_all_cc_from_host(uint8_t); - -static int create_host_cc(const char *); -static void check_host(const char *); -static void check_all_host(); -static void stop_all_host(); - -/* cc list entry funcs */ -static int clean_cc_list(wusb_cc_list_t *, void *); -static int print_cc_list(wusb_cc_list_t *, void *); -static int copy_cc_list(wusb_cc_list_t *, void *); -static int write_cc_list(wusb_cc_list_t *, void *); - -/* door service utility funcs */ -static void door_srv(void *, char *, size_t, door_desc_t *, uint_t); -static int wusbd_check_auth(const char *); - - -/* daemon log utilities */ -static void wusbd_info(const char *, ...); -static void wusbd_warn(const char *, ...); -static void wusbd_log(const char *, ...); - -/* host-id / dev-id util funcs */ -static uint8_t assign_host_id(void); -static uint16_t assign_dev_id(uint8_t); -static void free_dev_id(uint8_t, uint16_t); - -static int get_host_path(int, char *); - -static int load_host_mac(const char *, uint8_t *); - -/* searching helper funcs */ -static int find_host_id(uint8_t *); -static wusb_cc_info_t *find_dev_cc(uint8_t, uint8_t *); -static wusb_cc_info_t *find_host_cc(uint8_t); -static void copy_list_back(char *); - - -/* enable/disable host funcs */ -static int start_host(const char *); -static int stop_host(const char *); - - -/* remove dev funcs */ -static int remove_one_dev(uint8_t, uint16_t); -static int remove_all_dev(uint8_t); - -/* dev_ctrl check funcs */ -static uint16_t check_dev_ctrl(wusb_dev_ctrl_t *); -static uint16_t check_host_ctrl(wusb_dev_ctrl_t *); - -static int wusbd_do_ca(const char *, const char *, wusb_cc_info_t *, char); -static int wusbd_do_host(char *, size_t, door_desc_t *, uint_t, int); - -/* cc generation methods */ -static int generate_wusb_CDID(CK_SESSION_HANDLE, wusb_cc_t *); -static int generate_wusb_CK(CK_SESSION_HANDLE, wusb_cc_t *); -static int generate_wusb_CC(wusb_cc_t *); -static int generate_wusb_CHID(wusb_cc_t *, uint8_t *); - -static int wusbd_do_list(char *, size_t, door_desc_t *, uint_t); -static int wusbd_do_association(char *, size_t, door_desc_t *, uint_t); -static int wusbd_do_remove_host(char *, size_t, door_desc_t *, uint_t); -static int wusbd_do_remove_dev(char *, size_t, door_desc_t *, uint_t); -static int wusbd_do_enable_host(char *, size_t, door_desc_t *, uint_t); -static int wusbd_do_disable_host(char *, size_t, door_desc_t *, uint_t); - -typedef struct { - const char *auth; - int (* dfunc)(char *, size_t, door_desc_t *, uint_t); -} wusbd_door_func_t; -static wusbd_door_func_t dfuncs[] = -{ - { WUSB_AUTH_READ, wusbd_do_list }, - { WUSB_AUTH_MODIFY, wusbd_do_association }, - { WUSB_AUTH_MODIFY, wusbd_do_remove_dev }, - { WUSB_AUTH_HOST, wusbd_do_remove_host }, - { WUSB_AUTH_HOST, wusbd_do_enable_host }, - { WUSB_AUTH_HOST, wusbd_do_disable_host }, -}; - - -static void -wusbd_sig_handler(int sigval) -{ - wusbd_info("received signal %d\n", sigval); - switch (sigval) { - case 0: - case SIGPIPE: - wusbd_info("SIG PIPE received"); - break; - - case SIGHUP: - wusbd_info("Refreshing dameon"); - /* Refresh config was triggered */ - refresh(sigval); - break; - - default: - (void) pthread_mutex_lock(&mutex_cclock); - wusbd_info("Stop all host before exit"); - stop_all_host(); - (void) pthread_mutex_unlock(&mutex_cclock); - exit_clean(0); - break; - } - -} - - -/* - * Daemon. - * use "--daemon" to start daemon - */ -void -daemonize() { - - int pfd = -1; - - struct sigaction act; - sigset_t set; - - openlog("wusbd", LOG_PID | LOG_NDELAY, LOG_DAEMON); - - (void) sigfillset(&set); - (void) sigdelset(&set, SIGABRT); - - (void) sigfillset(&act.sa_mask); - act.sa_handler = wusbd_sig_handler; - act.sa_flags = 0; - - (void) sigaction(SIGTERM, &act, NULL); - (void) sigaction(SIGHUP, &act, NULL); - (void) sigaction(SIGINT, &act, NULL); - (void) sigaction(SIGPIPE, &act, NULL); - - (void) sigdelset(&set, SIGTERM); - (void) sigdelset(&set, SIGHUP); - (void) sigdelset(&set, SIGINT); - (void) sigdelset(&set, SIGPIPE); - - pfd = wusbd_daemonize_init(); - - wusbd_info("daemonize: start daemon "); - if (pthread_mutex_init(&mutex_cclock, NULL) != 0) { - wusbd_log("daemonize: mutext cclock init failed!"); - exit(FATAL_ERROR); - } - if (init_daemon_pid() < 0) { - wusbd_log("daemonize: init daemon pid fail"); - goto fail; - } - if (init_global_cc_list() < 0) { - wusbd_log("daemonize: init global cc fail"); - goto fail; - } - - check_all_host(); - - if (init_sys_evnt() < 0) { - wusbd_log("daemonize: init sys evnt fail"); - goto fail; - } - - if (init_door_srv() < 0) { - wusbd_log("daemonize: init door serv fail"); - goto fail; - } - - wusbd_daemonize_fini(pfd, 0); - - /*CONSTCOND*/ - while (1) { - (void) pause(); - } -fail: - - exit_clean(FATAL_ERROR); -} - -/* Respond client's list request. */ -/*ARGSUSED*/ -static int -wusbd_do_list(char *argp, size_t arg_size, - door_desc_t *dp, uint_t n_desc) -{ - - char *buf = NULL; - size_t buflen = 0; - - uint16_t rval = WUSBADM_OK; - wusbd_daemon_enter(); - - /* update CC status */ - clean_all_cc_list(); - update_all_cc_list(); - - /* 2 bytes command result */ - buflen += sizeof (uint16_t); - - /* 4 bytes cc list number */ - buflen += sizeof (uint32_t); - - /* length of all clists */ - buflen += sizeof (wusb_device_info_t) * cc_cnt; - - /* use alloca here */ - if ((buf = (char *)alloca(buflen)) == NULL) { - wusbd_warn("wusb_do_list: alloca buffer failed"); - - rval = WUSBADM_FAILURE; - wusbd_daemon_leave((char *)&rval, sizeof (uint16_t)); - - return (WUSBA_FAILURE); - } - bzero(buf, buflen); - - /* command result */ - (void) memcpy(buf, &rval, sizeof (uint16_t)); - - /* cc number */ - (void) memcpy(buf + sizeof (uint16_t), &cc_cnt, sizeof (uint32_t)); - - /* wusb_device_info_t * cc_cnt */ - copy_list_back(buf + sizeof (uint16_t) + sizeof (uint32_t)); - - /* debug only */ - global_list_iterate(print_cc_list, NULL); - - /* - * Update the cc file because we may get the device type if - * device is connected - */ - (void) update_cc_file(); - - wusbd_daemon_leave(buf, buflen); - - return (WUSBA_SUCCESS); - -} - -/* Respond client's associate request. */ -/* ARGSUSED */ -static int -wusbd_do_association(char *argp, size_t arg_size, - door_desc_t *dp, uint_t n_desc) -{ - uint16_t rval = WUSBADM_OK; - wusb_cc_info_t *host_cc = NULL; - wusb_door_call_t *dcall; - wusb_asso_ctrl_t *asso_ctrl; - char host_path[MAXPATHLEN]; - - /* get associate request */ - /* LINTED E_BAD_PTR_CAST_ALIGN */ - dcall = (wusb_door_call_t *)argp; - asso_ctrl = (wusb_asso_ctrl_t *)dcall->buf; - - wusbd_daemon_enter(); - - /* check if host id exist */ - if ((host_cc = find_host_cc(asso_ctrl->host)) == NULL) { - wusbd_warn("wusbd_do_association:asso_ctrl.host = %d err = %s", - asso_ctrl->host, strerror(errno)); - rval = WUSBADM_INVAL_HOSTID; - goto done; - } - if (get_host_path(asso_ctrl->host, host_path) < 0) { - wusbd_warn("wusbd_do_association:host = %d not attached", - asso_ctrl->host); - rval = WUSBADM_HOST_NOT_ATTACH; - goto done; - } - - /* check if it is cable device */ - if (asso_ctrl->type != ASSO_TYPE_CABLE) { - wusbd_warn("wusbd_do_association: asso_ctrl.type = %d", - asso_ctrl->type); - rval = WUSBADM_NO_SUPPORT; - goto done; - } - /* do assocation now */ - if (wusbd_do_ca(host_path, asso_ctrl->path, - host_cc, asso_ctrl->onetime) < 0) { - wusbd_warn("wusbd_do_association: wusbd_do_ca failed"); - rval = WUSBADM_FAILURE; - goto done; - } - -done: - wusbd_daemon_leave((char *)&rval, sizeof (uint16_t)); - - return (rval); -} - -/* Respond client's remove-dev request. */ -/* ARGSUSED */ -static int -wusbd_do_remove_dev(char *argp, size_t arg_size, - door_desc_t *dp, uint_t n_desc) -{ - wusb_door_call_t *dcall; - wusb_dev_ctrl_t *rmctrl; - uint16_t rval = WUSBADM_OK; - - /* LINTED E_BAD_PTR_CAST_ALIGN */ - dcall = (wusb_door_call_t *)argp; - /* LINTED E_BAD_PTR_CAST_ALIGN */ - rmctrl = (wusb_dev_ctrl_t *)dcall->buf; - - wusbd_daemon_enter(); - - if ((rval = check_dev_ctrl(rmctrl)) != WUSBADM_OK) { - wusbd_warn("wusbd_do_remove_dev: dev-id = %d.%d failed", - rmctrl->host, rmctrl->dev); - goto done; - } - - if (rmctrl->dev) { - /* remove only one device */ - if (remove_one_dev(rmctrl->host, rmctrl->dev) < 0) { - wusbd_warn("wusbd_do_remove_dev: dev-id = %d.%d failed", - rmctrl->host, rmctrl->dev); - rval = WUSBADM_FAILURE; - goto done; - } - } else { - /* remove all the device associated to the host */ - if (remove_all_dev(rmctrl->host) < 0) { - wusbd_warn("wusbd_do_remove_dev: host-id = %d failed", - rmctrl->host); - rval = WUSBADM_FAILURE; - goto done; - } - } - - if (update_cc_file() < 0) { - wusbd_warn("wusbd_do_remove_dev: update cc file failed"); - rval = WUSBADM_CCSTORE_ACC; - goto done; - } - - -done: - wusbd_daemon_leave((char *)&rval, sizeof (uint16_t)); - - return (rval); -} - -/* Respond client's remove-host request. */ -/* ARGSUSED */ -static int -wusbd_do_remove_host(char *argp, size_t arg_size, - door_desc_t *dp, uint_t n_desc) -{ - wusb_door_call_t *dcall; - wusb_dev_ctrl_t *host_ctrl; - uint16_t rval = WUSBADM_OK; - - char host_path[MAXPATHLEN]; - - wusbd_daemon_enter(); - /* LINTED E_BAD_PTR_CAST_ALIGN */ - dcall = (wusb_door_call_t *)argp; - /* LINTED E_BAD_PTR_CAST_ALIGN */ - host_ctrl = (wusb_dev_ctrl_t *)dcall->buf; - wusbd_info("wusbd_do_remove_host start: hostid = %d", host_ctrl->host); - - if ((rval = check_host_ctrl(host_ctrl)) != WUSBADM_OK) { - wusbd_warn("wusbd_do_remove_host :host_ctrl->host = %d failed", - host_ctrl->host); - goto done; - } - - if (remove_all_dev(host_ctrl->host) < 0) { - wusbd_warn("wusbd_do_remove_host :host_ctrl->host = %d failed", - host_ctrl->host); - rval = WUSBADM_FAILURE; - goto done; - } - - if (get_host_path(host_ctrl->host, host_path) < 0) { - wusbd_warn("wusbd_do_host:host_ctrl->host = %d not attached", - host_ctrl->host); - } else { - - /* - * Stop host if possible, if the host can not - * be stoped we just remove the host cc from - * system, this means the host should be re-plugged - * before any new association since the CHID info is - * gone. - */ - if (stop_host(host_path) < 0) { - wusbd_warn("wusbd_do_remove_host: host_path = %s", - host_path); - } - } - - /* remove the last CC for host */ - remove_from_global_list(devids[host_ctrl->host][0]); - free_dev_id(host_ctrl->host, 0); - - if (update_cc_file() < 0) { - wusbd_warn("wusbd_do_remove_host: update cc failed"); - rval = WUSBADM_CCSTORE_ACC; - goto done; - } - wusbd_info("wusbd_do_remove_host complete "); - -done: - wusbd_daemon_leave((char *)&rval, sizeof (uint16_t)); - - return (rval); - - -} - -/* Respond client's enable-host request. */ -static int -wusbd_do_enable_host(char *argp, size_t arg_size, - door_desc_t *dp, uint_t n_desc) -{ - (void) wusbd_do_host(argp, arg_size, dp, n_desc, 1); - - return (WUSBA_SUCCESS); -} - -/* Respond client's disable-host request. */ -static int -wusbd_do_disable_host(char *argp, size_t arg_size, - door_desc_t *dp, uint_t n_desc) -{ - (void) wusbd_do_host(argp, arg_size, dp, n_desc, 0); - - return (WUSBA_SUCCESS); -} - -/* - * wusbd_do_host is the only wrapper for any host related cmds. - * It will call door_return, so it will - * not return and its return val should be omitted by callers - */ -/* ARGSUSED */ -static int -wusbd_do_host(char *argp, size_t arg_size, - door_desc_t *dp, uint_t n_desc, int flag) -{ - wusb_door_call_t *dcall; - wusb_dev_ctrl_t *host_ctrl; - uint16_t rval = WUSBADM_OK; - - char host_path[MAXPATHLEN]; - - /* LINTED E_BAD_PTR_CAST_ALIGN */ - dcall = (wusb_door_call_t *)argp; - /* LINTED E_BAD_PTR_CAST_ALIGN */ - host_ctrl = (wusb_dev_ctrl_t *)dcall->buf; - - wusbd_daemon_enter(); - if ((rval = check_host_ctrl(host_ctrl)) != WUSBADM_OK) { - wusbd_warn("wusbd_do_host: host-id = %d failed", - host_ctrl->host); - goto done; - } - - if (get_host_path(host_ctrl->host, host_path) < 0) { - wusbd_warn("wusbd_do_host:host_ctrl->host = %d not attached", - host_ctrl->host); - rval = WUSBADM_HOST_NOT_ATTACH; - goto done; - } - - wusbd_info("wusbd_do_host: host = %s flag = %d", host_path, flag); - if (!flag) { - if (stop_host(host_path) < 0) { - wusbd_warn("wusbd_do_host: host_path = %s stop failed", - host_path); - rval = WUSBADM_HOST_NOT_ATTACH; - goto done; - } - } else { - (void) add_all_cc_to_host(host_path, host_ctrl->host); - /* start the host */ - if (start_host(host_path) < 0) { - wusbd_warn("wusbd_do_host: host = %s start failed", - host_path); - rval = WUSBADM_HOST_NOT_ATTACH; - goto done; - } - - } - -done: - wusbd_daemon_leave((char *)&rval, sizeof (uint16_t)); - - return (rval); - - -} -/* - * door server handler - * Do not allocate memory dynamically in this function. Upon - * door_return(), the server is blocked in the kernel context. No - * place to free that memory. see - * http://blogs.sun.com/tucker/entry/door_api_details - */ -/* ARGSUSED */ -static void -door_srv(void *cookie, char *argp, size_t arg_size, - door_desc_t *dp, uint_t n_desc) -{ - wusb_door_call_t *dcall; - - uint16_t rval = WUSBADM_FAILURE; - - /* check if it is an valid wusb door call */ - if (argp == NULL || arg_size != sizeof (wusb_door_call_t)) { - - wusbd_warn("door_srv: argp = 0x%p arg_size = %d", - argp, arg_size); - rval = WUSBADM_FAILURE; - goto fail; - } - - /* LINTED E_BAD_PTR_CAST_ALIGN */ - dcall = (wusb_door_call_t *)argp; - - if (dcall->cmdss >= (sizeof (dfuncs)/sizeof (wusbd_door_func_t))) { - wusbd_warn("door_srv: dcall->cmdss = %d", - dcall->cmdss); - rval = WUSBADM_NO_SUPPORT; - - goto fail; - } - - /* chk auths should be done first for any cmd */ - if (wusbd_check_auth(dfuncs[dcall->cmdss].auth) < 0) { - wusbd_warn("door_srv: cmdss = %d, auth = %s", - dcall->cmdss, dfuncs[dcall->cmdss].auth); - rval = WUSBADM_AUTH_FAILURE; - - goto fail; - } - - - /* - * Any wusbd_do_xx will return the door service - */ - dfuncs[dcall->cmdss].dfunc(argp, arg_size, dp, n_desc); - - return; - -fail: - (void) door_return((char *)&rval, sizeof (uint16_t), NULL, 0); - -} - -/* - * Check the status of every CC. And update it in the list so that - * client can know if it's connected/disconnected. - */ -static void -update_cc_list(const char *host) -{ - uint8_t mac[WUSB_DEV_MAC_LENGTH]; - wusb_hc_get_dstate_t dstate; - wusb_cc_list_t *list = NULL; - int hostid = 0; - int hstate = -1; - int fd = -1; - int i; - - wusbd_info("update_cc_list: host = %s", host); - if (load_host_mac(host, mac) < 0) { - wusbd_warn("update_cc_list: host = %s failed", host); - - return; - } - - if ((hostid = find_host_id(mac)) == 0) { - - return; - } - - if ((fd = open(host, O_RDONLY)) == -1) { - wusbd_warn("update_cc_list: host = %s, err = %s", - host, strerror(errno)); - - return; - } - - /* update host states */ - if (ioctl(fd, WUSB_HC_GET_HSTATE, &hstate) < 0) { - wusbd_warn("update_cc_list: WUSB_HC_GET_HSTATE, err = %s", - strerror(errno)); - (void) close(fd); - - return; - } - - list = devids[hostid][0]; - list->stat = hstate; - - bzero(&dstate, sizeof (wusb_hc_get_dstate_t)); - - for (i = 1; i < DEV_MAX; i++) { - if ((list = devids[hostid][i]) == NULL) { - continue; - } - (void) memcpy(dstate.cdid, list->info.cc.CDID, 16); - if (ioctl(fd, WUSB_HC_GET_DSTATE, &dstate) == 0) { - list = devids[hostid][i]; - list->stat = dstate.state; - if (dstate.state == WUSB_STATE_CONFIGURED) { - (void) snprintf(list->info.type, WUSB_TYPE_LEN, - "%s", dstate.nodename); - } - wusbd_info("update_cc_list: type = %s, state = %d", - dstate.nodename, dstate.state); - } - - } - - (void) close(fd); -} -/* find the host cc infor with host id */ -static wusb_cc_info_t * -find_host_cc(uint8_t host_id) -{ - wusb_cc_list_t *list = NULL; - - if (host_id == 0 || host_id >= HOST_MAX) { - - return (NULL); - } - - list = devids[host_id][0]; - - return (list? &(list->info):NULL); -} - -/* find the device CDID with host id */ -static wusb_cc_info_t * -find_dev_cc(uint8_t host_id, uint8_t *CDID) -{ - wusb_cc_list_t *list = NULL; - int j = 0; - - for (j = 1; j < DEV_MAX; j++) { - list = devids[host_id][j]; - if (list && (memcmp(list->info.cc.CDID, CDID, 16) == 0)) { - - return (&list->info); - } - } - return (NULL); -} - -/* find the host id with mac address */ -static int -find_host_id(uint8_t *mac) -{ - wusb_cc_list_t *list = NULL; - int i = 0; - - for (i = 1; i < HOST_MAX; i++) { - list = devids[i][0]; - if (list && memcmp(mac, - list->info.mac, WUSB_DEV_MAC_LENGTH) == 0) { - return (i); - } - } - - return (0); -} - -/* Save the cc infor from dame to /etc/usb/wusbcc */ -static int -update_cc_file() -{ - int ccfd = -1; - - if ((ccfd = open(WUSB_CC, O_RDWR|O_TRUNC)) < 0) { - wusbd_warn("update_cc_file: CC store file = %s, %s", - WUSB_CC, strerror(errno)); - - return (WUSBA_FAILURE); - } - - global_list_iterate(write_cc_list, &ccfd); - (void) close(ccfd); - - return (WUSBA_SUCCESS); - -} -/* - * ca_****: Cable Assocation helpers - * to setup an association for host and device - */ -static int -ca_get_info(int fd, wusb_cbaf_asso_info_t *first) -{ - bzero(first, sizeof (wusb_cbaf_asso_info_t)); - if (0 != ioctl(fd, CBAF_IOCTL_GET_ASSO_INFO, first)) { - wusbd_warn("ca_get_info: CBAF_IOCTL_GET_ASSO_INFO: err = %s", - strerror(errno)); - - return (WUSBA_FAILURE); - } - - return (WUSBA_SUCCESS); -} - -static int -ca_set_host(int fd, wusb_cc_info_t *info) -{ - wusb_cbaf_host_info_t host_info; - - host_info.AssociationTypeId = 1; - host_info.AssociationSubTypeId = 0; - host_info.LangID = 0; - - (void) memcpy(host_info.CHID, info->cc.CHID, 16); - (void) memset(host_info.HostFriendlyName, 0, 64); - - mac_to_label(info->mac, host_info.HostFriendlyName); - - if (0 != ioctl(fd, CBAF_IOCTL_SET_HOST_INFO, &host_info)) { - wusbd_warn("ca_set_host: CBAF_IOCTL_SET_HOST_INFO: err = %s", - strerror(errno)); - - return (WUSBA_FAILURE); - } - - return (WUSBA_SUCCESS); -} - -static int -ca_get_req(int fd, wusb_cbaf_asso_info_t *first) -{ - void *ca_buf; - wusb_cbaf_asso_info_t *ca_info; - - wusbd_info("ca_get_req: NumAssociates = %d", - first->NumAssociationRequests); - - ca_buf = malloc(sizeof (wusb_cbaf_asso_info_t) + - first->NumAssociationRequests * sizeof (wusb_cbaf_asso_req_t)); - - if (ca_buf == NULL) { - wusbd_warn("ca_get_req: ca_buf = NULL"); - - return (WUSBA_FAILURE); - } - - ca_info = (wusb_cbaf_asso_info_t *)ca_buf; - (void) memcpy(ca_info, first, sizeof (wusb_cbaf_asso_info_t)); - - if (0 != ioctl(fd, CBAF_IOCTL_GET_ASSO_REQS, ca_buf)) { - wusbd_warn("ca_get_req: CBAF_IOCTL_GET_ASSO_REQS: err = %s", - strerror(errno)); - free(ca_info); - - return (WUSBA_FAILURE); - } - /* currently not used */ - free(ca_buf); - - return (WUSBA_SUCCESS); - -} - -static int -ca_get_devinfo(int fd, wusb_cbaf_device_info_t *device_info) -{ - bzero(device_info, sizeof (wusb_cbaf_device_info_t)); - if (0 != ioctl(fd, CBAF_IOCTL_GET_DEVICE_INFO, device_info)) { - wusbd_warn("ca_get_dev failed"); - - return (WUSBA_FAILURE); - } - wusbd_info("ca_get_devinfo: DeviceFriendlyName = %s", - device_info->DeviceFriendlyName); - wusbd_info("ca_get_devinfo: bandgroup = %d", - device_info->BandGroups); - wusbd_info("ca_get_devinfo: LangID = %d", - device_info->LangID); - - print_array("CDID from device", device_info->CDID, 16); - - return (WUSBA_SUCCESS); -} - -static int -ca_connect_cc(int fd, wusb_cc_info_t *newinfo, - wusb_cbaf_device_info_t *device_info) -{ - wusb_cbaf_cc_data_t cc_data; - - cc_data.AssociationTypeId = 1; - cc_data.AssociationSubTypeId = 1; - cc_data.Length = WUSB_CC_DATA_SIZE; - cc_data.BandGroups = device_info->BandGroups; - (void) memcpy(&(cc_data.CC), &(newinfo->cc), sizeof (wusb_cc_t)); - - - if (0 != ioctl(fd, CBAF_IOCTL_SET_CONNECTION, &cc_data)) { - wusbd_warn("ca_connect_cc: CBAF_IOCTL_SET_CONNECTION: err = %s", - strerror(errno)); - - return (WUSBA_FAILURE); - } - print_array("New CC to device", cc_data.CC.CHID, 48); - - return (WUSBA_SUCCESS); -} - -static int -ca_create_cc(wusb_cc_info_t *newinfo, wusb_cc_info_t *host_cc) -{ - (void) memcpy(newinfo->cc.CHID, host_cc->cc.CHID, 16); - - if (generate_wusb_CC(&(newinfo->cc)) < 0) { - wusbd_warn("ca_create_cc: generate cc failed!"); - - return (WUSBA_FAILURE); - } - - return (WUSBA_SUCCESS); -} - -static int -ca_add_cc(wusb_cc_info_t *newinfo, const char *filename) -{ - int fd = -1; - int hstate = -1; - - wusbd_info("ca_add_cc: filename = %s start", filename); - - if ((fd = open(filename, O_RDONLY)) == -1) { - wusbd_warn("ca_add_cc: filename = %s, err = %s", - filename, strerror(errno)); - - return (WUSBA_FAILURE); - } - if (ioctl(fd, WUSB_HC_ADD_CC, &(newinfo->cc)) != 0) { - wusbd_warn("ca_add_cc: ioctl = WUSB_HC_ADD_CC, err = %s", - strerror(errno)); - goto fail; - } - if (ioctl(fd, WUSB_HC_GET_HSTATE, &hstate) < 0) { - wusbd_warn("ca_add_cc: ioctl = WUSB_HC_GET_HSTATE, err = %s", - strerror(errno)); - goto fail; - } - if (hstate != WUSB_HC_STARTED) { - if (ioctl(fd, WUSB_HC_START, WUSB_HC_INITIAL_START) == -1) { - wusbd_warn("ca_add_cc: ioctl = WUSB_HC_START, err = %s", - strerror(errno)); - goto fail; - } - } - - (void) close(fd); - - print_array("New CC to host", newinfo->cc.CHID, 48); - - return (WUSBA_SUCCESS); - -fail: - (void) close(fd); - - return (WUSBA_FAILURE); -} - -static int -ca_save_cc(wusb_cc_info_t *newinfo, wusb_cc_info_t *hostinfo) -{ - newinfo->host = hostinfo->host; - if ((newinfo->dev = assign_dev_id(newinfo->host)) == 0) { - wusbd_warn("ca_save_cc: host-id:%d", newinfo->host); - - return (WUSBA_FAILURE); - } - - if (save_cc(newinfo) < 0) { - wusbd_warn("ca_save_cc: save cc failed"); - - return (WUSBA_FAILURE); - } - - return (WUSBA_SUCCESS); -} - -static int -wusbd_do_ca(const char *host_path, const char *ca_dev, - wusb_cc_info_t *host_cc, char onetime) -{ - wusb_cbaf_asso_info_t first; - wusb_cbaf_device_info_t device_info; - wusb_cc_info_t newinfo; - int fd; - wusb_cc_info_t *old_cc = NULL; - - wusbd_info("wusbd_do_ca start\n"); - /* IMPORTANT: Do NOT open it with O_RDWR */ - fd = open(ca_dev, O_RDONLY); - if (fd == -1) { - wusbd_warn("wusbd_do_ca: ca_dev = %s err = %s", ca_dev, - strerror(errno)); - - return (WUSBA_FAILURE); - } - /* - * The first parts to set up a cable associaiton. - * Refer to: [Association Models Supplement to the - * Certified Wireless Universal Serial Bus Specification] - * chapter 4. - * - * 1. Send GET_ASSOCIATION_INFORMATION to the cable device - * and get the number of association requests. - * - * 2. Send GET_ASSOCIATION_INFORMATION again to get the - * all the association requests. - * - * 3. Send SET_ASSOCIATION_RESPONSE with the host CHID - * - * 4. Send GET_ASSOCIATION_REQUEST to get the exisiting CC - * infor from the device. - * - */ - if (ca_get_info(fd, &first) < 0) { - wusbd_warn("wusbd_do_ca: get asso info failed!"); - goto cleanup; - } - if (ca_get_req(fd, &first) < 0) { - wusbd_warn("wusbd_do_ca: get asso req failed!"); - goto cleanup; - } - if (ca_set_host(fd, host_cc)) { - wusbd_warn("wusbd_do_ca: set host info failred"); - goto cleanup; - } - if (ca_get_devinfo(fd, &device_info)) { - wusbd_warn("wusbd_do_ca: get device infor failed"); - goto cleanup; - } - - - (void) snprintf(newinfo.type, WUSB_TYPE_LEN, "unknown"); - newinfo.flag = onetime; - - /* - * The second part to setup cable association. - * - * 1. Create a CC from exsiting host_cc for the devices - * - * 2. Send new cc to the cable device to save in its hardware - * - * 3. Add new cc to the host controller - * - * 4. Save the cc to the cc list and cc store file - * - * Done! - */ - if (ca_create_cc(&newinfo, host_cc) < 0) { - wusbd_warn("wusbd_do_ca: ca create cc failed!"); - goto cleanup; - } - /* - * Check if CDID exist in the host cc list, if so, We need to update - * the exisiting cc infor with a new ck, do the association with the - * updated cc. - * See "Association Models Supplement to the WUSB Specification" - * Chapter 4 - */ - old_cc = find_dev_cc(host_cc->host, device_info.CDID); - if (old_cc) { - wusbd_warn("wusbd_do_ca: Association exist, use old CDID"); - (void) remove_cc_from_host(old_cc->host, old_cc->dev); - - /* update old cc with the new ck and copy back */ - (void) memcpy(old_cc->cc.CK, newinfo.cc.CK, 16); - (void) memcpy(&(newinfo.cc), &(old_cc->cc), sizeof (wusb_cc_t)); - } - if (ca_connect_cc(fd, &newinfo, &device_info) < 0) { - wusbd_warn("wusbd_do_ca: ca connect cc failed!"); - goto cleanup; - } - - (void) close(fd); - - if (ca_add_cc(&newinfo, host_path) < 0) { - wusbd_warn("wusbd_do_ca: ca add cc failed!"); - - return (WUSBA_FAILURE); - } - - if (!old_cc) { - /* a new cc save to file */ - if (ca_save_cc(&newinfo, host_cc) < 0) { - wusbd_warn("wusbd_do_ca: ca save cc failed!"); - - return (WUSBA_FAILURE); - } - } else { - /* Just update the cc file */ - if (update_cc_file() < 0) { - wusbd_warn("wusbd_do_ca: update old cc failed"); - - return (WUSBA_FAILURE); - } - } - - wusbd_info("wusbd_do_ca: Set cable connection complete!"); - - return (WUSBA_SUCCESS); - -cleanup: - (void) close(fd); - - return (WUSBA_FAILURE); -} -/* - * wusb cc infor generation helpers - * generate_wusb_CC: Generate CC infor for a device and host - * generate_wusb_CHID: Generate CHID for a host - * generate_wusb_CDID: Generate CDID for a device - * generate_wusb_CK : Generate CK for an assocation - */ - -static int -generate_wusb_CC(wusb_cc_t *cc) -{ - CK_SESSION_HANDLE pkhandle; - KMF_HANDLE_T kmfhandle; - int rval = WUSBA_SUCCESS; - wusbd_info("generate_wusb_CC: start"); - - if (wusb_crypto_init(&kmfhandle, &pkhandle, PKTOKEN, TOKENDIR) != 0) { - wusbd_warn("generate_wusb_CC: Crypto init failed"); - - return (WUSBA_FAILURE); - } - if (generate_wusb_CDID(pkhandle, cc) < 0) { - wusbd_warn("generate_wusb_CC: crate cdid failed"); - rval = WUSBA_FAILURE; - - goto done; - } - if (generate_wusb_CK(pkhandle, cc) < 0) { - wusbd_warn("generate_wusb_CC: crate ck failed"); - rval = WUSBA_FAILURE; - - goto done; - } -done: - wusb_crypto_fini(kmfhandle); - - wusbd_info("generate_wusb_CC: complete"); - - return (rval); -} - - -static int -generate_wusb_CHID(wusb_cc_t *cc, uint8_t *mac) -{ - /* - * CHID construction : - * 0 - 5 : MAC serial - * 6 - 7 : arbitrary - * 8 - 15 : random from seed = (MAC..) || (hostid||time)) || hrtime - */ - uint8_t *p = cc->CHID; - uint8_t seed[24]; - time_t tt; - uint64_t prod, hrtime; - int rval = WUSBA_SUCCESS; - - KMF_HANDLE_T kmfhandle; - CK_SESSION_HANDLE pkhandle; - - wusbd_info("generate_wusb_CHID: start"); - if (wusb_crypto_init(&kmfhandle, &pkhandle, PKTOKEN, TOKENDIR) != 0) { - wusbd_warn("generate_wusb_CHID: Crypto init failed"); - rval = WUSBA_FAILURE; - goto done; - } - - (void) memcpy(p, mac, WUSB_DEV_MAC_LENGTH); - p += 8; - - (void) time(&tt); - prod = gethostid(); - prod = (prod << 32) | tt; - hrtime = gethrtime(); - - (void) memcpy(seed, cc->CHID, 8); - (void) memcpy(seed + 8, &prod, 8); - (void) memcpy(seed + 16, &hrtime, 8); - - if (wusb_random(pkhandle, seed, 24, p, 8) < 0) { - wusbd_warn("generate_wusb_CHID: random failed"); - rval = WUSBA_FAILURE; - } - wusb_crypto_fini(kmfhandle); - wusbd_info("generate_wusb_CHID complete"); -done: - - return (rval); -} - -static int -generate_wusb_CDID(CK_SESSION_HANDLE pkhandle, wusb_cc_t *cc) -{ - /* TODO : need better generation mechanism */ - return (wusb_random(pkhandle, NULL, 0, cc->CDID, 16)); - -} - -static int -generate_wusb_CK(CK_SESSION_HANDLE pkhandle, wusb_cc_t *cc) -{ - /* TODO : need better generation mechanism */ - return (wusb_random(pkhandle, NULL, 0, cc->CK, 16)); -} - -/* Log to dmesg and smf log */ -static void -wusbd_warn(const char *format, ...) -{ - va_list alist; - - format = gettext(format); - va_start(alist, format); - (void) fprintf(stderr, gettext("[WUSBD]")); - (void) vfprintf(stderr, format, alist); - (void) fputc('\n', stderr); - va_end(alist); -} -static void -wusbd_log(const char *format, ...) -{ - va_list alist; - - format = gettext(format); - va_start(alist, format); - (void) vsyslog(LOG_WARNING, format, alist); - va_end(alist); -} - - -/* Log to smf log in DEBUG version */ -/* ARGSUSED */ -static void -wusbd_info(const char *format, ...) -{ -#ifdef DEBUG - va_list alist; - - format = gettext(format); - va_start(alist, format); - (void) fprintf(stderr, gettext("[WUSBD]")); - (void) vfprintf(stderr, format, alist); - (void) fputc('\n', stderr); - va_end(alist); -#endif -} - -/* - * Find an unused host id and return it. - * The wusbadm use two digits to represent a host. This means - * hostid can't be greater than 99. - */ -static uint8_t -assign_host_id(void) -{ - uint8_t i; - for (i = 1; i < HOST_MAX; i++) { - if (devids[i][0] == 0) { - wusbd_info("assign_host_id: rval = %d", i); - - return (i); - } - } - - return (0); /* illegal value */ -} - -/* - * traverse the CC store, search in the specified host, - * find an unused device id, return it. - * The wusbadm use 3 digits to represent a device. This means - * devid can't be greater than 999. - */ -static uint16_t -assign_dev_id(uint8_t hostid) -{ - uint16_t i; - if (hostid >= HOST_MAX) { - - return (0); - } - for (i = 1; i < DEV_MAX; i++) { - if (devids[hostid][i] == 0) { - wusbd_info("assign_dev_id: devid = %d.%d", hostid, i); - - return (i); - } - } - - return (0); /* illegal value */ -} - -/* Release a dev id, eg: remove dev */ -static void -free_dev_id(uint8_t hostid, uint16_t devid) -{ - if (hostid >= HOST_MAX || devid >= DEV_MAX) { - - return; - } - devids[hostid][devid] = 0; -} - -/* - * init_door_srv. - * Create the door file and attach door service - * to the door file - */ -static int -init_door_srv() -{ - int fd, dd; - - (void) fdetach(DOOR_FILE); - (void) unlink(DOOR_FILE); - - if ((dd = door_create(door_srv, 0, 0)) < 0) { - wusbd_warn("init_door_srv: door_creat: err = %s", - strerror(errno)); - - goto fail; - } - if ((fd = creat(DOOR_FILE, S_IRUSR | S_IRGRP | S_IROTH)) < 0) { - wusbd_warn("init_door_srv: creat: err = %s", - strerror(errno)); - - goto fail; - } - - (void) close(fd); - - wusbd_info("init_door_srv: file = %s created", DOOR_FILE); - - if (fattach(dd, DOOR_FILE) < 0) { - wusbd_warn("init_door_srv: fattach err = %s", - strerror(errno)); - - goto fail; - } - - return (WUSBA_SUCCESS); -fail: - - return (WUSBA_FAILURE); -} - - -/* Print a cc list entry */ -/* ARGSUSED */ -static int -print_cc_list(wusb_cc_list_t *list, void *data) -{ - wusbd_info("list:%x", list); - wusbd_info("\thostid:%x", list->info.host); - wusbd_info("\tdevid:%x", list->info.dev); - - return (WUSBA_SUCCESS); -} - -/* write a cc list entry back to file fd */ -static int -write_cc_list(wusb_cc_list_t *list, void *data) -{ - int ccfd = *((int *)data); - wusbd_info("write_cc_list: host-id = %d dev-id = %d", - list->info.host, list->info.dev); - - if (list->info.flag) { - - return (WUSBA_SUCCESS); - } - if (write(ccfd, &(list->info), sizeof (wusb_cc_info_t)) != - sizeof (wusb_cc_info_t)) { - wusbd_warn("write_cc_list: write err = %s ", - strerror(errno)); - - return (WUSBA_FAILURE); - } - - return (WUSBA_SUCCESS); -} - -/* clean up the status of the cc list entry */ -/* ARGSUSED */ -static int -clean_cc_list(wusb_cc_list_t *list, void *data) -{ - list->stat = list->info.dev? DEV_STAT_DISCONN:WUSB_HC_DISCONNTED; - - return (WUSBA_SUCCESS); -} - -/* copy a cc list entry to a device info buffer */ -static int -copy_cc_list(wusb_cc_list_t *list, void *data) -{ - char **buf = (char **)data; - - wusb_device_info_t devinfo; - devinfo.dev = list->info.dev; - devinfo.host = list->info.host; - devinfo.stat = list->stat; - - (void) snprintf(devinfo.type, WUSB_TYPE_LEN, "%s", list->info.type); - (void) memcpy(*buf, &devinfo, sizeof (wusb_device_info_t)); - - *buf += sizeof (wusb_device_info_t); - - return (WUSBA_SUCCESS); - -} - -/* save cc to list and file */ -static int -save_cc(const wusb_cc_info_t *ccinfo) -{ - /* save CC to file */ - if (save_cc_to_store(ccinfo) < 0) { - wusbd_warn("save_cc: Failed to save CC to file"); - - return (WUSBA_FAILURE); - } - - /* save cc to global list */ - if (save_cc_to_list(ccinfo) < 0) { - wusbd_warn("save_cc: Failed to save CC to list"); - - return (WUSBA_FAILURE); - - } - - return (WUSBA_SUCCESS); -} - -/* create cc list entry and add to global list */ -static int -save_cc_to_list(const wusb_cc_info_t *ccinfo) -{ - wusb_cc_list_t *newlist = - (wusb_cc_list_t *)malloc(sizeof (wusb_cc_list_t)); - if (newlist == NULL) { - wusbd_warn("save_cc_to_list: newlist = NULL"); - - return (WUSBA_FAILURE); - } - bzero(newlist, sizeof (wusb_cc_list_t)); - (void) memcpy(&(newlist->info), ccinfo, sizeof (wusb_cc_info_t)); - devids[ccinfo->host][ccinfo->dev] = newlist; - - add_to_global_list(newlist); - - return (WUSBA_SUCCESS); - -} - -/* save cc info to the host */ -static int -save_cc_to_store(const wusb_cc_info_t *ccinfo) -{ - int rval = WUSBA_FAILURE; - int ccfd = -1; - - /* - * If a device association is just used for one time - * we will not save it to the store file. See wusbadm(1) - */ - if (ccinfo->flag) { - - return (WUSBA_SUCCESS); - } - - /* open cc file */ - if ((ccfd = open(WUSB_CC, O_RDWR)) < 0) { - wusbd_warn("save_cc_to_store:CC file = %s, err = %s", - WUSB_CC, strerror(errno)); - goto done; - } - - /* seek to the end of the file */ - if ((rval = lseek(ccfd, 0, SEEK_END)) == (offset_t)-1) { - wusbd_warn("save_cc_to_store: seek fail err = %s", - strerror(errno)); - (void) close(ccfd); - goto done; - } - - /* save ccinfo to cc file */ - if ((rval = write(ccfd, ccinfo, sizeof (wusb_cc_info_t))) != - sizeof (wusb_cc_info_t)) { - wusbd_warn("write to store fail: %s - %d", - strerror(errno), rval); - (void) close(ccfd); - goto done; - } - - (void) close(ccfd); - rval = WUSBA_SUCCESS; - -done: - wusbd_info("save_cc_to_store: complete"); - - return (rval); - -} -/* - * load all the cc to the host controller - * 1. walk thru the cc list and find the device cc info - * related to this host. - * 2. add the cc to the host controller - * 3. start the host controller - */ -static int -add_all_cc_to_host(const char *host_path, uint8_t hostid) -{ - wusb_cc_list_t *list = NULL; - int fd = -1; - int j = 0; - wusbd_warn("add_all_cc_to_host: host = %s", host_path); - /* open host file */ - if ((fd = open(host_path, O_RDONLY)) == -1) { - wusbd_warn("add_all_cc_to_host: host = %s err = %s", - host_path, strerror(errno)); - - return (WUSBA_FAILURE); - } - - /* Find all the device cc and add cc to host controler */ - for (j = 0; j < DEV_MAX; j++) { - if ((list = devids[hostid][j]) == NULL) { - continue; - } - if (ioctl(fd, WUSB_HC_ADD_CC, &list->info.cc) == -1) { - wusbd_warn(" add_all_cc_to_host: ioctl = WUSB_HC_ADD_CC" - "hostid = %d, fail ", hostid); - (void) close(fd); - - return (WUSBA_FAILURE); - } - } - - (void) close(fd); - - wusbd_info("add_all_cc_to_host complete"); - - return (WUSBA_SUCCESS); -} - -/* Remove all the cc infor from a host device */ -static int -remove_all_cc_from_host(uint8_t hostid) -{ - int fd = -1; - int rval = 0; - char host_path[MAXPATHLEN]; - - if (get_host_path(hostid, host_path) < 0) { - wusbd_warn("remove_all_cc_from_host:hostid = %d not attached", - hostid); - - return (WUSBA_FAILURE); - } - - - if ((fd = open(host_path, O_RDONLY)) == -1) { - wusbd_warn("remove_all_cc_from host: host = %s err = %s", - host_path, strerror(errno)); - - return (WUSBA_FAILURE); - } - rval = ioctl(fd, WUSB_HC_STOP, WUSB_HC_REM_ALL_CC | WUSB_HC_FINAL_STOP); - - if (rval < 0) { - wusbd_warn("remove_all_cc_from_host: WUSB_HC_STOP: err = %s", - strerror(errno)); - (void) close(fd); - - return (WUSBA_FAILURE); - } - (void) close(fd); - - return (WUSBA_SUCCESS); -} -/* - * Initialize the global cc list from the store file - * "/etc/usb/wusbcc", the hostid/devid would also be - * set in the global devids - */ -static int -init_global_cc_list(void) -{ - wusb_cc_list_t *list = NULL; - char buf[sizeof (wusb_cc_list_t) + 1]; - int ccfd = -1; - - bzero(devids, HOST_MAX * DEV_MAX * sizeof (wusb_cc_list_t *)); - - /* - * open the cc file. when daemon starts for the first time - * cc file will be created in /etc/usb, all the wusb host - * and device Conection Context informaion is stored in this - * file. global cc list is the map in the dameon for the - * file. - */ - wusbd_info("init_global_cc_list: load cc from %s", WUSB_CC); - if ((ccfd = open(WUSB_CC, O_RDWR|O_CREAT, S_IRUSR | S_IWUSR)) < 0) { - wusbd_warn("init_global_cc_list: CC store file = %s, err = %s", - WUSB_CC, strerror(errno)); - - goto fail; - } - - (void) lseek(ccfd, 0, SEEK_SET); - - /* initialize globle cc list from cc file */ - while ((read(ccfd, buf, sizeof (wusb_cc_info_t))) > 0) { - - list = (wusb_cc_list_t *)calloc(sizeof (wusb_cc_list_t), 1); - - if (list == NULL) { - wusbd_warn("init_global_cc_list: list = NULL"); - (void) close(ccfd); - goto fail; - } - - (void) memcpy(&(list->info), buf, sizeof (wusb_cc_info_t)); - - /* set devids */ - devids[list->info.host][list->info.dev] = list; - - /* add the list to the global cc list */ - add_to_global_list(list); - } - (void) close(ccfd); - - return (WUSBA_SUCCESS); -fail: - - return (WUSBA_FAILURE); -} - -/* destroy the global CC list */ -static void -destroy_global_cc_list(void) -{ - wusb_cc_list_t *list = NULL; - wusb_cc_list_t *next = NULL; - - for (list = global_cclist; list; list = next) { - next = list->next; - free(list); - cc_cnt--; - } - global_cclist = NULL; - wusbd_info("destroy_global_cc_list: cc_cnt = %d", cc_cnt); - cc_cnt = 0; - bzero(devids, HOST_MAX * DEV_MAX * sizeof (wusb_cc_list_t *)); -} - -/* - * Add a new list to the global cc list. - * The new cc list will be inserted in an hostid/devid - * incremental order. - */ -static void -add_to_global_list(wusb_cc_list_t *list) -{ - - wusb_cc_list_t *tmp; - wusb_cc_list_t *next; - - - wusbd_info("add_to_global_list: start"); - wusbd_info("host-id = %d, dev-id = %d, type = %s", - list->info.host, list->info.dev, list->info.type); - - /* first cc list */ - if (global_cclist == NULL) { - global_cclist = list; - list->next = NULL; - - goto done; - } - - /* new cc list header */ - tmp = global_cclist; - if (tmp->info.host > list->info.host) { - list->next = tmp; - global_cclist = list; - goto done; - } - - /* find where to insert the new cc */ - for (tmp = global_cclist; tmp->next; tmp = tmp->next) { - next = tmp->next; - if (next->info.host < list->info.host) { - continue; - } - if (next->info.host == list->info.host) { - if (next->info.dev < list->info.dev) - continue; - } - break; - } - list->next = tmp->next; - tmp->next = list; - -done: - cc_cnt++; - wusbd_info("add_to_global_list: complete"); -} - -/* Remove a list from the global cc list */ -static void -remove_from_global_list(wusb_cc_list_t *list) -{ - - wusb_cc_list_t *tmp = NULL; - - wusbd_info("remove_from_global_list: host-id:%d, dev-id:%d, path:%s", - list->info.host, list->info.dev, list->info.type); - - /* first list */ - if (global_cclist == list) { - global_cclist = list->next; - goto found; - } - - for (tmp = global_cclist; tmp; tmp = tmp->next) { - if (tmp->next == list) { - tmp->next = list->next; - goto found; - } - } - - wusbd_warn("remove_from_global_list: cc not found "); - return; -found: - free(list); - cc_cnt--; - wusbd_info("remove_from_global_list: complete"); -} - -/* - * It is useful make a wrapper to work thru each entry in the global - * lists. it is used widely for to travers the whole list - */ -static void -global_list_iterate(cc_list_func func, void *data) -{ - wusb_cc_list_t *list = global_cclist; - while (list) { - if (func(list, (void*)data) < 0) - break; - list = list->next; - } -} - -/* Set all the device/host state to be disabled or disconnected */ -static void -clean_all_cc_list() -{ - wusbd_info("clean_all_cc_list: start"); - global_list_iterate(clean_cc_list, NULL); - wusbd_info("clean_all_cc_list: complete"); -} - -/* Copy the cc list to buffer */ -static void -copy_list_back(char *buf) -{ - global_list_iterate(copy_cc_list, &buf); -} - -/* work on each entry in the /dev/usb/whost */ -static void -all_hosts_iterate(host_func func) -{ - struct dirent *entry; - char filename[MAXPATHLEN]; - DIR *dirp = NULL; - - if ((dirp = opendir(WUSB_HOST_PATH)) == NULL) { - wusbd_warn("all_hosts_iterate: dir = %s, err = %s", - WUSB_HOST_PATH, strerror(errno)); - - return; - } - while ((entry = readdir(dirp)) != NULL) { - if (strstr(entry->d_name, WUSB_HOST_NAME)) { - - (void) snprintf(filename, MAXPATHLEN, "%s/%s", - WUSB_HOST_PATH, entry->d_name); - func(filename); - } - } - (void) closedir(dirp); -} - -/* Get the host file path in /dev/usb from a host id */ -static int -get_host_path(int hostid, char *path) -{ - struct dirent *entry; - char filename[MAXPATHLEN]; - DIR *dirp = NULL; - uint8_t mac[WUSB_DEV_MAC_LENGTH]; - int rval = WUSBA_FAILURE; - - wusbd_info("get_host_path :host = %d", hostid); - if ((dirp = opendir(WUSB_HOST_PATH)) == NULL) { - wusbd_warn("all_hosts_iterate: dir = %s, err = %s", - WUSB_HOST_PATH, strerror(errno)); - - return (rval); - } - while ((entry = readdir(dirp)) != NULL) { - if (strstr(entry->d_name, WUSB_HOST_NAME)) { - (void) snprintf(filename, MAXPATHLEN, "%s/%s", - WUSB_HOST_PATH, entry->d_name); - if (load_host_mac(filename, mac) < 0) { - wusbd_warn("get_host_path: host = %s failed", - filename); - - continue; - } - - if (hostid == find_host_id(mac)) { - (void) snprintf(path, MAXPATHLEN, "%s", - filename); - rval = WUSBA_SUCCESS; - - - break; - } - - - } - } - (void) closedir(dirp); - - return (rval); -} - -/* Check all the host device */ -static void -check_all_host() -{ - wusbd_info("check_all_host :start"); - all_hosts_iterate(check_host); - wusbd_info("check_all_host :finished"); -} - -/* Stop the host device */ -static void -stop_all_host() -{ - wusbd_info("stop_all_host :start"); - all_hosts_iterate((host_func)stop_host); - wusbd_info("stop_all_host :finished"); -} - -/* - * update the cc list information - * stat of the device and host, device nodename - */ -static void -update_all_cc_list() -{ - wusbd_info("update_all_cc_list :start"); - if (global_cclist) { - all_hosts_iterate(update_cc_list); - } else { - wusbd_info("update_all_cc_list :global_cclist = NULL"); - } - wusbd_info("update_all_cc_list :complete"); -} - -/* - * Get credential of the door_call client and check - * authorizations of caller's uid/euid - */ -static int -wusbd_check_auth(const char *auth_str) -{ - uid_t uid; - ucred_t *pcred = NULL; - if (door_ucred(&pcred) < 0) { - wusbd_warn("chk_auths: door_ucred: err = %s ", strerror(errno)); - - return (WUSBA_FAILURE); - } - - uid = ucred_geteuid(pcred); - - /* remember to do this */ - ucred_free(pcred); - - if (chk_auths(uid, auth_str) < 0) { - - return (WUSBA_FAILURE); - } - - return (WUSBA_SUCCESS); -} - -static int -load_host_mac(const char *filename, uint8_t *mac) -{ - int fd = -1; - int rval = WUSBA_FAILURE; - - wusbd_info("load_host_mac: host = %s\n", filename); - /* open host/dev file */ - if ((fd = open(filename, O_RDONLY)) == -1) { - wusbd_warn("load_host_mac: filename = %s , err = %s", filename, - strerror(errno)); - goto done; - } - - /* Get the mac address of the host */ - if (ioctl(fd, WUSB_HC_GET_MAC_ADDR, mac) == -1) { - wusbd_warn("load_host_mac: WUSB_HC_GET_MAC_ADDR: err = %s", - strerror(errno)); - (void) close(fd); - goto done; - } - - (void) close(fd); - - - rval = WUSBA_SUCCESS; -done: - wusbd_info("load_host_mac complete"); - - return (rval); -} - -/* - * create host cc - * 1. create the cc for host - * 2. save the cc to list & cc store file - */ -static int -create_host_cc(const char *filename) -{ - wusb_cc_info_t ccinfo; - uint8_t mac[WUSB_DEV_MAC_LENGTH]; - wusbd_info("create host cc for :%s", filename); - - if (load_host_mac(filename, mac) < 0) { - wusbd_warn("create_host_cc: host = %s, load mac failed", - filename); - - return (WUSBA_FAILURE); - } - - bzero(&ccinfo, sizeof (wusb_cc_info_t)); - - /* assign CHID */ - if (generate_wusb_CHID(&(ccinfo.cc), mac) < 0) { - - wusbd_warn("create_host_cc: host = %s, reate chid failed", - filename); - - return (WUSBA_FAILURE); - } - - print_array("New CC for host:", ccinfo.cc.CHID, 48); - - (void) memcpy(ccinfo.mac, mac, WUSB_DEV_MAC_LENGTH); - - /* Todo: only support hwa */ - (void) snprintf(ccinfo.type, WUSB_TYPE_LEN, "hwa"); - - /* don't allocate dev id here , for host, dev id set to 0 */ - if ((ccinfo.host = assign_host_id()) == 0) { - wusbd_warn("create_host_cc: assign_host_id = 0"); - - return (WUSBA_FAILURE); - } - ccinfo.dev = 0; - - /* save cc infor to host and cc file */ - if (save_cc(&ccinfo) < 0) { - wusbd_warn("create_host_cc: save_cc failed"); - - return (WUSBA_FAILURE); - } - - return (WUSBA_SUCCESS); - -} - -/* - * Add CCs to hosts upon startup - * OR add CCs to the host which is newly hotplugged in - */ -static void -check_host(const char *host) -{ - int hostid = 0; - - uint8_t mac[WUSB_DEV_MAC_LENGTH]; - - wusbd_info("check_host: host = %s", host); - if (load_host_mac(host, mac) < 0) { - wusbd_warn("check_host: host = %s load mac fail", host); - - return; - } - if ((hostid = find_host_id(mac)) != 0) { - wusbd_info("check_host: host = %s host-id = %d found", - host, hostid); - (void) add_all_cc_to_host(host, hostid); - /* start the host */ - (void) start_host(host); - - } else { - wusbd_info("check_host: newhost = %s found", host); - if (WUSBA_SUCCESS == create_host_cc(host)) { - /* check host again */ - (void) check_host(host); - } - } -} - -/* - * Remove one cc from host - * Args: - * hostid - hostid for the cc - * devid - devid for the cc - */ -static int -remove_cc_from_host(uint8_t hostid, uint16_t devid) -{ - int fd = -1; - wusb_cc_list_t *list = devids[hostid][0]; - char host_path[MAXPATHLEN]; - - if (get_host_path(hostid, host_path) < 0) { - wusbd_warn("remove_cc_from_host:hostid = %d not attached", - hostid); - - return (WUSBA_FAILURE); - } - - if ((fd = open(host_path, O_RDWR)) == -1) { - wusbd_warn("remove_cc_from_host: host = %s err = %s", - host_path, strerror(errno)); - - return (WUSBA_FAILURE); - } - - list = devids[hostid][devid]; - if (ioctl(fd, WUSB_HC_REM_CC, &(list->info.cc)) != 0) { - wusbd_warn("remove_cc_from_host: WUSB_HC_REM_CC err = %s", - strerror(errno)); - (void) close(fd); - - return (WUSBA_FAILURE); - } - (void) close(fd); - - return (WUSBA_SUCCESS); -} - -/* Stop/disable a host device */ -static int -stop_host(const char *host) -{ - int fd = -1; - int hstate = -1; - wusbd_info("stop_host: host = %s", host); - if ((fd = open(host, O_RDONLY)) == -1) { - wusbd_warn("stop_host:host = %s err = %s", host, - strerror(errno)); - - return (WUSBA_FAILURE); - } - /* - * We'll only send the cmd to stop host while host has already - * been startd. start/stop host takes time becasue host controller - * need to reset hardware or may cause issue while it it is stopping. - * So just do it at the right time. - */ - if (ioctl(fd, WUSB_HC_GET_HSTATE, &hstate) < 0) { - wusbd_warn("stop_host: WUSB_HC_GET_HSTATE: err = %s", - strerror(errno)); - goto fail; - } - - if (hstate == WUSB_HC_STARTED) { - if (ioctl(fd, WUSB_HC_STOP, WUSB_HC_FINAL_STOP) != 0) { - wusbd_warn("stop_host: WUSB_HC_STOP: err = %s", - strerror(errno)); - goto fail; - } - } - (void) close(fd); - - return (WUSBA_SUCCESS); -fail: - (void) close(fd); - - return (WUSBA_FAILURE); -} - -/* start/enable a host device */ -static int -start_host(const char *host) -{ - int fd = -1; - int hstate = -1; - wusbd_warn("start_host : host = %s", host); - if ((fd = open(host, O_RDONLY)) == -1) { - wusbd_warn("start_host: host = %s err = %s", host, - strerror(errno)); - - return (WUSBA_FAILURE); - } - /* - * Check if the host is already start. if the host has been started. - * it is not proper to send the start command to the host controller, - * because it may cause some issue for host contoller reset the - * hardware - */ - if (ioctl(fd, WUSB_HC_GET_HSTATE, &hstate) < 0) { - wusbd_warn("start_host: ioctl = WUSB_HC_GET_HSTATE err = %s", - strerror(errno)); - goto fail; - } - - if (hstate != WUSB_HC_STARTED) { - if (ioctl(fd, WUSB_HC_START, WUSB_HC_INITIAL_START) == -1) { - wusbd_warn("start_host: WUSB_HC_START: err = %s", - strerror(errno)); - goto fail; - } - } - (void) close(fd); - wusbd_info("start_host: complete"); - - return (WUSBA_SUCCESS); -fail: - (void) close(fd); - - return (WUSBA_FAILURE); -} - -/* Check the args of a dev ctrl door call request */ -static uint16_t -check_dev_ctrl(wusb_dev_ctrl_t *dev_ctrl) -{ - if ((dev_ctrl->host == 0) || (dev_ctrl->host >= HOST_MAX)) { - wusbd_warn("check_dev_ctrl: host-id = %02d", dev_ctrl->host); - - return (WUSBADM_INVAL_HOSTID); - } - if (!devids[dev_ctrl->host][0]) { - wusbd_warn("check_dev_ctrl: host-id = %02d cc = NULL", - dev_ctrl->host); - - return (WUSBADM_NO_HOST); - } - if (dev_ctrl->dev >= DEV_MAX) { - wusbd_warn("check_dev_ctrl: dev-id = %03d, max: %d", - dev_ctrl->dev, DEV_MAX); - - return (WUSBADM_INVAL_DEVID); - - } - if (!devids[dev_ctrl->host][dev_ctrl->dev]) { - wusbd_warn("check_dev_ctl: dev-id = %02d.%03d, cc = NULL", - dev_ctrl->host, dev_ctrl->dev); - - return (WUSBADM_NO_DEVICE); - } - - return (WUSBADM_OK); -} - -/* Check the args of a host ctrl door call request */ -static uint16_t -check_host_ctrl(wusb_dev_ctrl_t *dev_ctrl) -{ - if ((dev_ctrl->host == 0) || (dev_ctrl->host >= HOST_MAX)) { - wusbd_warn("check_host_ctrl: host-id = %02d", dev_ctrl->host); - - return (WUSBADM_INVAL_HOSTID); - } - if (!devids[dev_ctrl->host][0]) { - wusbd_warn("check_host_ctrl: host-id = %02d, cc = NULL", - dev_ctrl->host); - - return (WUSBADM_NO_HOST); - } - if (dev_ctrl->dev != 0) { - wusbd_warn("check_host_ctrl: dev-id = %03d no zero", - dev_ctrl->dev); - - return (WUSBADM_INVAL_DEVID); - } - - return (WUSBADM_OK); -} - -/* Remove one dev from the cc list */ -static int -remove_one_dev(uint8_t hostid, uint16_t devid) -{ - wusb_cc_list_t *list = NULL; - if (remove_cc_from_host(hostid, devid) < 0) { - wusbd_warn("remove_one_dev: hostid = %d, devid = %d" - "remove cc from host failed", hostid, devid); - } - list = devids[hostid][devid]; - remove_from_global_list(list); - - free_dev_id(hostid, devid); - - return (WUSBA_SUCCESS); - -} - -/* Remove all dev from the cc list */ -static int -remove_all_dev(uint8_t hostid) -{ - int i = 0; - wusbd_warn("remove_all_dev enter, hostid = %d", hostid); - if (remove_all_cc_from_host(hostid) < 0) { - wusbd_warn("remove_all_dev: hostid = %d. remove all cc failed", - hostid); - } - for (i = 1; i < DEV_MAX; i++) { - wusb_cc_list_t *list = devids[hostid][i]; - if (list) { - remove_from_global_list(list); - free_dev_id(hostid, i); - } - } - wusbd_warn("remove_all_dev complete"); - - return (WUSBA_SUCCESS); -} - -/* register device add/remove event to update the cc list */ -static int -init_sys_evnt() -{ - sysevent_handle_t *shp; - const char *subclass_list[] = { - ESC_DEVFS_DEVI_ADD, - 0 - }; - if ((shp = sysevent_bind_handle(event_handler)) == NULL) { - wusbd_warn("init_sys_evnt: sysevent bind handle: err = %s", - strerror(errno)); - goto fail; - } - if (sysevent_subscribe_event(shp, EC_DEVFS, subclass_list, 1) != 0) { - wusbd_warn("init_sys_evnt: sysevent subscribe: err = %s", - strerror(errno)); - sysevent_unbind_handle(shp); - goto fail; - } - - return (WUSBA_SUCCESS); -fail: - - return (WUSBA_FAILURE); -} - -/* - * Only one daemon is running in the system - * Create pid file to save the pid of the daemon - * process, the pid file is also used by svcadm to - * stop the daemon - */ -static int -init_daemon_pid() -{ - int fd; - char pid[20]; - - if ((fd = open(PID_FILE, O_RDWR|O_CREAT|O_EXCL, S_IRUSR | S_IWUSR)) - == -1) { - wusbd_warn("dameon is already running! "); - - return (WUSBA_FAILURE); - } - - /* save pid to the file */ - (void) snprintf(pid, 19, "%d", getpid()); - - if (write(fd, pid, strlen(pid)) != strlen(pid)) { - wusbd_warn("write pid file failed! "); - (void) close(fd); - - return (WUSBA_FAILURE); - - } - (void) close(fd); - - return (WUSBA_SUCCESS); - -} - -static void -exit_clean(int ret) -{ - wusbd_warn("Remove door file, pid file"); - (void) fdetach(DOOR_FILE); - (void) unlink(DOOR_FILE); - (void) unlink(PID_FILE); - - (void) pthread_mutex_destroy(&mutex_cclock); - - closelog(); - - exit(ret); -} - -/* - * Refresh daemon. svcadm restart will send a SIGHUP to the daemon - * destroy the cc list and reload it from cc now. Update the status - * of each cc list by checking all the hosts in the system. - */ -/* ARGSUSED */ -static void -refresh(int signo) -{ - wusbd_info("refresh: daemon is restarting.."); - - (void) pthread_mutex_lock(&mutex_cclock); - - destroy_global_cc_list(); - (void) init_global_cc_list(); - check_all_host(); - - (void) pthread_mutex_unlock(&mutex_cclock); - - wusbd_info("refresh: daemon is ok now"); -} - -/* update host CC when a wireless host is plugged */ -static void -event_handler(sysevent_t *ev) -{ - nvlist_t *attr_list = NULL; - char *path = NULL; - - if (sysevent_get_attr_list(ev, &attr_list) != 0) { - wusbd_warn("event_handler: can not get attr list"); - - return; - } - - (void) nvlist_lookup_string(attr_list, DEVFS_PATHNAME, &path); - - wusbd_info("event_handler: device path %s", path); - - - /* check if the device is host device and update cc list */ - if (path && strstr(path, WUSB_HWA_HOST_NODE)) { - char filename[MAXPATHLEN]; - (void) snprintf(filename, MAXPATHLEN, "/devices%s:hwahc", path); - - (void) pthread_mutex_lock(&mutex_cclock); - check_host(filename); - (void) pthread_mutex_unlock(&mutex_cclock); - } - - nvlist_free(attr_list); -} - - -/* For debug only */ -void -print_prv() -{ -#ifdef DEBUG - priv_set_t *tt = priv_allocset(); - if (getppriv(PRIV_PERMITTED, tt) == 0) { - wusbd_info("PRIV_PERMITTED:\n"); - wusbd_info("\t%s\n", - priv_set_to_str(tt, ',', PRIV_STR_SHORT)); - } - if (getppriv(PRIV_EFFECTIVE, tt) == 0) { - wusbd_info("PRIV_EFFECTIVE:\n"); - wusbd_info("\t%s\n", - priv_set_to_str(tt, ',', PRIV_STR_SHORT)); - } - if (getppriv(PRIV_INHERITABLE, tt) == 0) { - wusbd_info("PRIV_INHERITABLE:\n"); - wusbd_info("\t%s\n", - priv_set_to_str(tt, ',', PRIV_STR_SHORT)); - } - if (getppriv(PRIV_LIMIT, tt) == 0) { - wusbd_info("PRIV_LIMIT:\n"); - wusbd_info("\t%s\n", - priv_set_to_str(tt, ',', PRIV_STR_SHORT)); - } - priv_freeset(tt); -#endif -} - -/* wusb daemon init */ -static int -wusbd_daemonize_init() -{ - int status, pfds[2]; - sigset_t set, oset; - pid_t pid; - int rc; - - /* - * Remove all the privs not needed for the daemon. - * PRIV_SYS_MOUNT: requred by starting door serv. - * PRIV_FILE_DAC_WRITE: requred by attach door file. - * PRIV_SYS_CONFIG, required by register sys event. - * PRIV_SYS_DEVICES, required by driver ioctl. - */ - rc = __init_daemon_priv(PU_RESETGROUPS | PU_CLEARLIMITSET, - 0, 0, - PRIV_SYS_MOUNT, - PRIV_FILE_DAC_WRITE, - PRIV_SYS_CONFIG, - PRIV_SYS_DEVICES, - NULL); - - if (rc != 0) { - wusbd_warn("insufficient privileges"); - exit(FATAL_ERROR); - } - - /* - * Block all signals prior to the fork and leave them blocked in the - * parent so we don't get in a situation where the parent gets SIGINT - * and returns non-zero exit status and the child is actually running. - * In the child, restore the signal mask once we've done our setsid(). - */ - (void) sigfillset(&set); - (void) sigdelset(&set, SIGABRT); - (void) sigprocmask(SIG_BLOCK, &set, &oset); - - if (pipe(pfds) == -1) { - wusbd_warn("unable to create pipe"); - closelog(); - exit(FATAL_ERROR); - } - - closelog(); - - - if ((pid = fork()) == -1) { - openlog("wusbd", LOG_PID | LOG_NDELAY, LOG_DAEMON); - wusbd_warn("unable to fork"); - closelog(); - exit(FATAL_ERROR); - } - - /* - * If we're the parent process, wait for either the child to send us - * the appropriate exit status over the pipe or for the read to fail - * (presumably with 0 for EOF if our child terminated abnormally). - * If the read fails, exit with either the child's exit status if it - * exited or with SMF_EXIT_ERR_FATAL if it died from a fatal signal. - */ - if (pid != 0) { - (void) close(pfds[1]); - - if (read(pfds[0], &status, sizeof (status)) == sizeof (status)) - _exit(status); - - if (waitpid(pid, &status, 0) == pid && WIFEXITED(status)) - _exit(WEXITSTATUS(status)); - - _exit(FATAL_ERROR); - } - openlog("wusbd", LOG_PID | LOG_NDELAY, LOG_DAEMON); - (void) setsid(); - (void) sigprocmask(SIG_SETMASK, &oset, NULL); - (void) chdir("/"); - (void) umask(022); - (void) close(pfds[0]); - - return (pfds[1]); -} - -/* wusb daemon fini */ -static void -wusbd_daemonize_fini(int fd, int exit_status) -{ - /* - * Now that we're running, if a pipe fd was specified, write an exit - * status to it to indicate that our parent process can safely detach. - * Then proceed to loading the remaining non-built-in modules. - */ - if (fd >= 0) { - (void) write(fd, &exit_status, sizeof (exit_status)); - } - - (void) close(fd); - if ((fd = open("/dev/null", O_RDWR)) >= 0) { - (void) fcntl(fd, F_DUP2FD, STDIN_FILENO); - (void) fcntl(fd, F_DUP2FD, STDOUT_FILENO); -#if 0 - /* Leave the stderr for smf log */ - (void) fcntl(fd, F_DUP2FD, STDERR_FILENO); -#endif - (void) close(fd); - } - /* Remove all the privs not needed. leave SYS_DEVICE only */ - __fini_daemon_priv(PRIV_PROC_FORK, PRIV_PROC_EXEC, PRIV_PROC_SESSION, - PRIV_FILE_LINK_ANY, - PRIV_PROC_INFO, - PRIV_FILE_DAC_WRITE, - PRIV_SYS_MOUNT, - PRIV_SYS_CONFIG, - (char *)NULL); - - - print_prv(); -} -/* Each door call handler should get the lock */ -static void -wusbd_daemon_enter() -{ - wusbd_info("wusbd_daemon_enter: enter"); - (void) pthread_mutex_lock(&mutex_cclock); -} -/* Each door call handler should release the lock */ -static void -wusbd_daemon_leave(char *buf, int len) -{ - wusbd_info("wusbd_daemon_leave"); - (void) pthread_mutex_unlock(&mutex_cclock); - (void) door_return(buf, len, NULL, 0); -} diff --git a/usr/src/cmd/wusbadm/wusbd.h b/usr/src/cmd/wusbadm/wusbd.h deleted file mode 100644 index c215d2b772..0000000000 --- a/usr/src/cmd/wusbadm/wusbd.h +++ /dev/null @@ -1,105 +0,0 @@ -/* - * 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 - * or http://www.opensolaris.org/os/licensing. - * 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. - */ - -#ifndef _WUSBD_H -#define _WUSBD_H - - -#ifdef __cplusplus -extern "C" { -#endif - -#define WUSB_HOST_PATH "/dev/usb" -#define WUSB_HOST_NAME "whost" -#define WUSB_HWA_HOST_NODE "hwa-host" - -#define DOOR_FILE "/var/run/wusbd/wusb_door" -#define PID_FILE "/var/run/wusbd/wusb.pid" -#define WUSB_CC "/etc/usb/wusbcc" - -/* door server commands */ -enum { - WUSB_DCMD_LIST_DATA = 0, - WUSB_DCMD_ASSOCIATE, - WUSB_DCMD_REMOVE_DEV, - WUSB_DCMD_REMOVE_HOST, - WUSB_DCMD_ENABLE_HOST, - WUSB_DCMD_DISABLE_HOST -}; - -enum { - WUSBADM_OK = 0, - WUSBADM_AUTH_FAILURE, /* authorization check failure */ - WUSBADM_NO_HOST, /* host id does not exist */ - WUSBADM_NO_DEVICE, /* failure */ - WUSBADM_CCSTORE_ACC, /* fail to access CC store */ - WUSBADM_NO_SUPPORT, /* failure */ - WUSBADM_INVAL_HOSTID, /* host-id not exist */ - WUSBADM_INVAL_DEVID, /* dev-id not exist */ - WUSBADM_HOST_NOT_ATTACH, /* the device file not exist */ - WUSBADM_FAILURE /* other kind of failure */ -}; - -#define WUSB_AUTH_READ "solaris.admin.wusb.read" -#define WUSB_AUTH_MODIFY "solaris.admin.wusb.modify" -#define WUSB_AUTH_HOST "solaris.admin.wusb.host" - -#define WUSB_BUF_LEN 1024 - - -/* return values */ -#define WUSBA_SUCCESS 0 -#define WUSBA_FAILURE -1 - -typedef struct wusbd_door_call { - uint16_t cmdss; /* cmd/status */ - char buf[WUSB_BUF_LEN]; /* args/return */ -} wusb_door_call_t; - -/* association type */ -#define ASSO_TYPE_NUMERIC 0x01 -#define ASSO_TYPE_CABLE 0x02 - -/* assocation data */ -typedef struct wusb_asso_ctrl { - uint8_t host; /* host id */ - uint8_t type; /* c/n */ - uint8_t onetime; /* onetime/always */ - char path[MAXPATHLEN]; /* device path */ -} wusb_asso_ctrl_t; - -/* host/dev contrl data */ -typedef struct wusb_dev_ctrl { - uint8_t host; /* host id */ - uint16_t dev; /* device id */ -} wusb_dev_ctrl_t; - -void daemonize(); - -#ifdef __cplusplus -} -#endif - -#endif /* _WUSBD_H */ diff --git a/usr/src/man/man1m/Makefile b/usr/src/man/man1m/Makefile index 133bd112f1..ddeddbafd5 100644 --- a/usr/src/man/man1m/Makefile +++ b/usr/src/man/man1m/Makefile @@ -565,7 +565,6 @@ _MANFILES= 6to4relay.1m \ wificonfig.1m \ wpad.1m \ wracct.1m \ - wusbadm.1m \ ypbind.1m \ ypinit.1m \ ypmake.1m \ diff --git a/usr/src/man/man1m/wusbadm.1m b/usr/src/man/man1m/wusbadm.1m deleted file mode 100644 index b209317acc..0000000000 --- a/usr/src/man/man1m/wusbadm.1m +++ /dev/null @@ -1,665 +0,0 @@ -'\" te -.\" Copyright (c) 2009, Sun Microsystems, Inc. All Rights Reserved -.\" 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 or http://www.opensolaris.org/os/licensing. -.\" 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] -.TH WUSBADM 1M "Apr 22, 2009" -.SH NAME -wusbadm \- administer wireless USB hosts and devices -.SH SYNOPSIS -.LP -.nf -\fBwusbadm\fR list [\fB-h\fR | \fB-d\fR] [\fB-o\fR \fIfield\fR[,...]] -.fi - -.LP -.nf -\fBwusbadm\fR associate [\fB-h\fR \fIhost-id\fR] [[\fB-c\fR [\fB-f\fR]] | \fB-n\fR] [\fB-o\fR] -.fi - -.LP -.nf -\fBwusbadm\fR remove-dev [[\fB-d\fR \fIdev-id\fR] | [\fB-h\fR \fIhost-id\fR]] [\fB-f\fR] -.fi - -.LP -.nf -\fBwusbadm\fR remove-host [\fB-h\fR \fIhost-id\fR] [\fB-f\fR] -.fi - -.LP -.nf -\fBwusbadm\fR enable-host [\fB-h\fR \fIhost-id\fR] -.fi - -.LP -.nf -\fBwusbadm\fR disable-host [\fB-h\fR \fIhost-id\fR] -.fi - -.SH DESCRIPTION -.sp -.LP -The \fBwusbadm\fR command provides a command line interface to administer -wireless USB hosts and devices, including listing hosts and devices -information, associating the host with the device, removing host or device -information from the system, and enabling or disabling hosts. -.sp -.LP -Before connecting a wireless USB device to a host for the first time, a user -needs to set up the association information between them by running the wusbadm -associate subcommand. Following this, the user can connect or disconnect the -device by simply turning on or off the device radio (perhaps a button on the -device, depending on the manufacturer). The device radio's turning on and off -are analogous to the hotplugging of wired USB devices. -.sp -.LP -The association information created by the \fBassociate\fR subcommand is -maintained in the non-volatile memory of the device and the host. On the host, -it can be removed by the \fBremove-dev\fR or \fBremove-host\fR subcommands. On -the device, it can be overwritten by another association. For a device is -associated with multiple hosts, the way that the device prioritizes or updates -its multiple records of association depends on the manufacturer. -.sp -.LP -Each \fBwusbadm\fR subcommand operates on one of the following objects: -.sp -.ne 2 -.na -\fB\fIhost-id\fR\fR -.ad -.sp .6 -.RS 4n -A two-digit number (in the range from 01 to 99) that uniquely identifies a -wireless USB host on a system. It is generated when the \fBwusb\fR service (see -\fBNOTES\fR section) is successfully enabled and finds the host instance for -the first time. The number is maintained until removed by \fBremove-host\fR -subcommand. -.RE - -.sp -.ne 2 -.na -\fB\fIdev-id\fR\fR -.ad -.sp .6 -.RS 4n -A five-digit number that uniquely identifies a wireless USB device associated -with a wireless USB host. The first two digits are the host-id of the wireless -USB host with which the device is associated. The last three-digit number (in -the range from 001 to 999) is used to differentiate devices associated with the -same host. In the five-digit number, the first two digits and the last three -are separated by a dot. -.sp -\fIdev-id\fR is generated during the device association process. It is -maintained for the device until removed by the \fBremove-dev\fR subcommand or -until updated by another association between the same host and device. -.RE - -.SH SUB-COMMANDS -.sp -.LP -The following subcommands are supported. Except for the \fBlist\fR subcommand, -each subcommand displays subcommand-specific usage information if you run it -without any options or operands. -.sp -.ne 2 -.na -\fB\fBlist\fR [\fB-h\fR | \fB-d\fR] [\fB-o\fR \fIfield\fR[,...]]\fR -.ad -.sp .6 -.RS 4n -List wireless USB hosts and devices on a system, displaying the ID, state, and -type for all hosts and devices. By default, \fBlist\fR will list all hosts and -devices and all fields. Each host and its devices will be displayed as a group. -This subcommand supports the following options. -.sp -.ne 2 -.na -\fB\fB-o\fR \fIfield\fR[,...], \fB--output\fR=\fIfield\fR[,...]\fR -.ad -.sp .6 -.RS 4n -A case-insensitive, comma-separated list of output fields to display. The field -name must be one of the fields listed below, or the special value \fBall\fR to -display all fields. By default (without \fB-o\fR), \fBlist\fR displays all -fields. -.sp -.ne 2 -.na -\fB\fBID\fR\fR -.ad -.sp .6 -.RS 4n -The \fIhost-id\fR or \fIdev-id\fR. -.RE - -.sp -.ne 2 -.na -\fB\fBTYPE\fR\fR -.ad -.sp .6 -.RS 4n -The \fBhost\fR or \fBdevice\fR types. -.sp -For \fBhost\fR, the types include \fBwhci\fR (on-board host) and \fBhwa\fR -(hot-pluggable host). -.sp -For \fBdevice\fR, the types include \fBkbd\fR, \fBmouse\fR, \fBstorage\fR, -\fBprinter\fR, \fBdwa\fR (wireless USB hub), \fBaudio\fR, \fBvideo\fR, and so -forth. -.RE - -.sp -.ne 2 -.na -\fB\fBSTATE\fR\fR -.ad -.sp .6 -.RS 4n -There are the following states for the host: -.sp -.ne 2 -.na -\fB\fBenabled\fR\fR -.ad -.sp .6 -.RS 4n -The host is ready to work or is already working, including performing -association, connecting devices, performing data communication, and so forth. -.RE - -.sp -.ne 2 -.na -\fB\fBdisabled\fR\fR -.ad -.sp .6 -.RS 4n -The host is not ready to work with any devices and no devices are connected to -the host. It might be stopped by a \fBdisable-host\fR subcommand, or the host -might not be available because it is physically unplugged or because of a -driver detach. -.RE - -.sp -.ne 2 -.na -\fB\fBdisconnected\fR\fR -.ad -.sp .6 -.RS 4n -The host is not attached to the system. An \fBhwa\fR device is in this state -after it is unplugged from the USB port on the system. -.RE - -There are the folllowing states for the device: -.sp -.ne 2 -.na -\fB\fBconnected\fR\fR -.ad -.sp .6 -.RS 4n -The device is connected with a host and ready to be opened, or it is already -opened and working. By default, the device tries to get into this state after -the association is complete and its radio is turned on. -.RE - -.sp -.ne 2 -.na -\fB\fBdisconnected\fR\fR -.ad -.sp .6 -.RS 4n -The device is not connected to a host or not ready to be opened yet. The device -might be in this state because its radio is out of range, power is off, -hardware problems, and so forth. -.RE - -.RE - -.RE - -.sp -.ne 2 -.na -\fB\fB-h\fR, \fB--host\fR\fR -.ad -.sp .6 -.RS 4n -List the wireless USB hosts only. -.RE - -.sp -.ne 2 -.na -\fB\fB-d\fR, \fB--device\fR\fR -.ad -.sp .6 -.RS 4n -List the wireless USB devices only. -.RE - -.RE - -.sp -.ne 2 -.na -\fB\fBassociate\fR [\fB-h\fR \fIhost-id\fR] [[\fB-c\fR [\fB-f\fR]] | \fB-n\fR] -[\fB-o\fR]\fR -.ad -.sp .6 -.RS 4n -Designate the host to start an association process. Association is the initial -step before a wireless USB device can be connected with a wireless USB host. -.sp -There are two association models: -.sp -.ne 2 -.na -\fBCable association\fR -.ad -.sp .6 -.RS 4n -A user connects the device and host with a USB cable first, and then run this -subcommand to designate the host to setup the association information with the -device. After the association is in effect, the cable is no longer needed in -the subsequent connections between the same host and the device. -.RE - -.sp -.ne 2 -.na -\fBNumeric association\fR -.ad -.sp .6 -.RS 4n -A user turns on the device radio and runs this subcommand to designate the host -to talk to the device. A short number is then displayed on both host and -device. The user compares the values of the numbers and confirms on both the -host and the device. -.RE - -Following a successful association, the associated USB host and device are able -to proceed with the wireless connection process. By default, the association -information will be kept both on the host and the device until it is removed or -overwritten. -.sp -If there are multiple devices available for association, this subcommand will -list all of them, enabling a user to choose among them. This subcommand has the -following options. -.sp -.ne 2 -.na -\fB\fB-h\fR \fIhost-id\fR, \fB--host\fR \fIhost-id\fR\fR -.ad -.sp .6 -.RS 4n -Specify the host for which the association will be done. If this option is not -specified, this subcommand lists all enabled hosts for users to choose. -.RE - -.sp -.ne 2 -.na -\fB\fB-c\fR, \fB--cable\fR\fR -.ad -.sp .6 -.RS 4n -Start the cable association process. A user plugs the wireless USB device to -the host and runs the associate subcommand with this option. -.RE - -.sp -.ne 2 -.na -\fB\fB-n\fR, \fB--numeric\fR\fR -.ad -.sp .6 -.RS 4n -Start the numeric association process. This subcommand prompts the user to -compare the number displayed on the host and the device. -.RE - -If neither of the preceding two association model options (\fB-n\fR or -\fB-c\fR) is specified, this subcommand prompts the user to specify one of the -following association model options. -.sp -.ne 2 -.na -\fB\fB-f\fR, \fB--force\fR\fR -.ad -.sp .6 -.RS 4n -Start the cable association process. A user plugs the wireless USB device to -the host and runs the associate subcommand with this option. -.RE - -.sp -.ne 2 -.na -\fB\fB-o\fR, \fB--onetime\fR\fR -.ad -.sp .6 -.RS 4n -Indicate that this association is for a one-time connection. That is, after the -association, if the device is connected and then disconnected, the association -information for this device will be removed from the host system. A user would -need to perform another association for the next connection. -.RE - -.RE - -.sp -.ne 2 -.na -\fB\fBremove-dev\fR [[\fB-d\fR \fIdev-id\fR] | [\fB-h\fR -\fIhost-id\fR]][\fB-f\fR]\fR -.ad -.sp .6 -.RS 4n -Remove the association information of the wireless USB device from the system. -After the removal, the device cannot be connected with the host until the user -runs the \fBassociate\fR subcommand again, for the host and device. This -subcommand has the following options. -.sp -.ne 2 -.na -\fB\fB-d\fR, \fB--device\fR=\fIdev-id\fR\fR -.ad -.sp .6 -.RS 4n -Remove the association information of the wireless USB device specified by -\fIdev-id\fR. -.RE - -.sp -.ne 2 -.na -\fB\fB-h\fR \fIhost-id\fR, \fB--host\fR=\fIhost-id\fR\fR -.ad -.sp .6 -.RS 4n -Remove the association information of all the wireless USB devices associated -with the host specified by \fIhost-id\fR. -.RE - -.sp -.ne 2 -.na -\fB\fB-f\fR, \fB--force\fR\fR -.ad -.sp .6 -.RS 4n -Perform the removal without asking for confirmation. If the device is being -connected with the host, then this subcommand will force it to disconnect. -.RE - -.RE - -.sp -.ne 2 -.na -\fB\fBremove-host\fR [\fB-h\fR \fIhost-id\fR] [\fB-f\fR]\fR -.ad -.sp .6 -.RS 4n -Remove the host information from the system, including \fIhost-id\fR and the -association information of all the devices associated with the host. This -subcommand is used most often for removing the temporarily used hot-pluggable -wireless USB host, for example, a \fBhwa\fR dongle. The host can be brought -back by being re-enumerated, for example, physically hot-plugging a \fBhwa\fR -dongle. The host-id will then be updated and no device association information -can be restored. It is not recommended to remove a on-board host. This -subcommand has the following options. -.sp -.ne 2 -.na -\fB\fB-h\fR \fIhost-id\fR, \fB--host\fR=\fIhost-id\fR\fR -.ad -.sp .6 -.RS 4n -Specifies the \fIhost-id\fR to be removed. -.RE - -.sp -.ne 2 -.na -\fB\fB-f\fR, \fB--force\fR\fR -.ad -.sp .6 -.RS 4n -Perform the removal without asking for confirmation. If there are one or more -devices connected with the host, then force them to disconnect. -.RE - -.RE - -.sp -.ne 2 -.na -\fB\fBenable-host\fR [\fB-h\fR \fIhost-id\fR]\fR -.ad -.sp .6 -.RS 4n -Take the host to the enabled state. By default, the host is in the enabled -state. This subcommand has the following option. -.sp -.ne 2 -.na -\fB\fB-h\fR \fIhost-id\fR, \fB--host\fR=\fIhost-id\fR\fR -.ad -.sp .6 -.RS 4n -Specifies the \fIhost-id\fR to be enabled. -.RE - -.RE - -.sp -.ne 2 -.na -\fB\fBdisable-host\fR [\fB-h\fR \fIhost-id\fR] [\fB-f\fR]\fR -.ad -.sp .6 -.RS 4n -Take the host to the disabled state. The \fIhost-id\fR and all the association -information of the host are maintained. Issuing an \fBenable-host\fR subcommand -brings the host back to the enabled state. This subcommand has the following -options. -.sp -.ne 2 -.na -\fB\fB-h\fR \fIhost-id\fR, \fB--host\fR=\fIhost-id\fR\fR -.ad -.sp .6 -.RS 4n -Specifies the \fIhost-id\fR to be disabled. -.RE - -.sp -.ne 2 -.na -\fB\fB-f\fR, \fB--force\fR\fR -.ad -.sp .6 -.RS 4n -Perform the disable operation without asking for confirmation. If there are one -or more devices connected with the host, this option forces them to disconnect. -.RE - -.RE - -.SH EXAMPLES -.LP -\fBExample 1 \fRListing All Hosts and Devices -.sp -.LP -The following command lists all wireless USB hosts and devices. - -.sp -.in +2 -.nf -# \fBwusbadm list\fR -01 enabled hwa -01.001 connected mouse -01.002 connected kbd -02 enabled whci -02.001 connected printer -02.002 disconnected storage -03 disabled hwa -03.001 disconnected storage -03.002 disconnected dwa -.fi -.in -2 -.sp - -.LP -\fBExample 2 \fRAssociating to a Device Using Cable -.sp -.LP -The following command associates a device to a specific host (host-id -\fB01\fR), using the cable association approach. - -.sp -.in +2 -.nf -# \fBwusbadm associate -h 01 -c\fR -Associate a device with host (01) via cable. -Continue (yes/no)? -.fi -.in -2 -.sp - -.LP -\fBExample 3 \fRRemoving a Device's Association -.sp -.LP -The following command removes a device's association information from the host -system. - -.sp -.in +2 -.nf -# \fBwusbadm remove-dev -d 01.002\fR -Remove the information of device (01.002) from system. -This device can not be connected with the host until it is associated -again. Continue (yes/no)? -.fi -.in -2 -.sp - -.LP -\fBExample 4 \fRRemoving Associations for All Devices -.sp -.LP -The following command removes the association information for all devices -associated with a specific host. - -.sp -.in +2 -.nf -# \fBwusbadm remove-dev -h 02\fR -Remove the information of all the devices associated with host (02) -from the system. -All the devices associated with the host cannot be connected with it -until they are associated again. Continue (yes/no)? -.fi -.in -2 -.sp - -.SH EXIT STATUS -.sp -.LP -The following exit values are returned: -.sp -.ne 2 -.na -\fB\fB0\fR\fR -.ad -.sp .6 -.RS 4n -Successful operation. -.RE - -.sp -.ne 2 -.na -\fB\fB1\fR\fR -.ad -.sp .6 -.RS 4n -Error: the operation failed. For example, a device failed to associate with a -host. -.RE - -.sp -.ne 2 -.na -\fB\fB2\fR\fR -.ad -.sp .6 -.RS 4n -Usage error. -.RE - -.SH ATTRIBUTES -.sp -.LP -See \fBattributes\fR(5) for descriptions of the following attributes: -.sp -.LP -\fB/usr/sbin\fR -.sp - -.sp -.TS -box; -c | c -l | l . -ATTRIBUTE TYPE ATTRIBUTE VALUE -_ -Interface Stability Committed -.TE - -.SH SEE ALSO -.sp -.LP -\fBattributes\fR(5), \fBhwahc\fR(7D), \fBusba\fR(7D) -.SH NOTES -.sp -.LP -The \fBwusb\fR (wireless USB administration) service is managed by the service -management facility, \fBsmf\fR(5), under the service identifier: -.sp -.in +2 -.nf -svc:/system/wusb:default -.fi -.in -2 -.sp - -.sp -.LP -Administrative actions on this service, such as enabling, disabling, or -requesting restart, can be performed using \fBsvcadm\fR(1M). The service's -status can be queried using the \fBsvcs\fR(1) command. -.sp -.LP -The \fBwusb\fR service is implemented by the \fBwusbd\fR daemon, a private -interface. As with the \fBwusb\fR service, the daemon is started by the SMF. -Specify the daemon with the service instance: -.sp -.in +2 -.nf -svc:/system/wusbd:default -.fi -.in -2 -.sp - -.sp -.LP -The \fBwusbd\fR daemon should not be invoked directly. diff --git a/usr/src/man/man7d/Makefile b/usr/src/man/man7d/Makefile index 9ab694f75b..5b5210e985 100644 --- a/usr/src/man/man7d/Makefile +++ b/usr/src/man/man7d/Makefile @@ -58,8 +58,6 @@ _MANFILES= aac.7d \ hid.7d \ hme.7d \ hubd.7d \ - hwahc.7d \ - hwarc.7d \ hxge.7d \ ib.7d \ ibcm.7d \ @@ -141,13 +139,10 @@ _MANFILES= aac.7d \ usbsksp.7d \ usbsprl.7d \ usbvc.7d \ - uwba.7d \ virtualkm.7d \ vni.7d \ vr.7d \ wscons.7d \ - wusb_ca.7d \ - wusb_df.7d \ xge.7d \ yge.7d \ zcons.7d \ @@ -247,15 +242,13 @@ _MANLINKS= 1394.7d \ bscbus.7d \ fdc.7d \ firewire.7d \ - hwa1480_fw.7d \ i2bsc.7d \ kmem.7d \ lo0.7d \ ticots.7d \ ticotsord.7d \ urandom.7d \ - usb.7d \ - uwb.7d + usb.7d sparc_MANLINKS= drmach.7d \ ngdr.7d \ @@ -288,10 +281,6 @@ ticotsord.7d := LINKSRC = ticlts.7d usb.7d := LINKSRC = usba.7d -uwb.7d := LINKSRC = uwba.7d - -hwa1480_fw.7d := LINKSRC = wusb_df.7d - .KEEP_STATE: include $(SRC)/man/Makefile.man diff --git a/usr/src/man/man7d/hwahc.7d b/usr/src/man/man7d/hwahc.7d deleted file mode 100644 index 1d139f2267..0000000000 --- a/usr/src/man/man7d/hwahc.7d +++ /dev/null @@ -1,109 +0,0 @@ -'\" te -.\" Copyright (c) 2009, Sun Microsystems, Inc. All Rights Reserved -.\" 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 or http://www.opensolaris.org/os/licensing. -.\" 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] -.TH HWAHC 7D "Apr 17, 2009" -.SH NAME -hwahc \- Host Wire Adapter Host Controller Driver -.SH DESCRIPTION -.sp -.LP -The \fBhwahc\fR driver is a USBA (Solaris USB Architecture) compliant nexus -driver that supports the Wireless USB 1.0 Host Wire Adapter Host Controller, an -industry standard developed by USB-IF. -.sp -.LP -A Host Wire Adapter (HWA) is a USB device whose upstream connection is a USB -2.0 wired interface. The HWA operates as a host to a cluster of downstream -Wireless USB devices. -.sp -.LP -The \fBhwahc\fR driver supports bulk, interrupt and control transfers. -.SH FILES -.sp -.ne 2 -.na -\fB\fB/kernel/drv/hwahc\fR\fR -.ad -.RS 29n -32-bit ELF 86 kernel module -.RE - -.sp -.ne 2 -.na -\fB\fB/kernel/drv/sparcv9/hwahc\fR\fR -.ad -.RS 29n -64-bit SPARC ELF kernel module -.RE - -.sp -.ne 2 -.na -\fB\fB/kernel/drv/amd64/hwahc\fR\fR -.ad -.RS 29n -64-bit x86 ELF kernel module -.RE - -.SH ATTRIBUTES -.sp -.LP -See \fBattributes\fR(5) for a description of the following attributes: -.sp - -.sp -.TS -box; -l | l -l | l . -ATTRIBUTE TYPE ATTRIBUTE VALUE -_ -Architecture SPARC, x86 -.TE - -.SH SEE ALSO -.sp -.LP -\fBadd_drv\fR(1M), \fBprtconf\fR(1M), \fBrem_drv\fR(1M), \fBupdate_drv\fR(1M), -\fBattributes\fR(5), \fBehci\fR(7D), \fBhubd\fR(7D), \fBusba\fR(7D) -.sp -.LP -\fIWriting Device Drivers\fR -.sp -.LP -\fISystem Administration Guide: Basic Administration\fR -.sp -.LP -\fIUniversal Serial Bus Specification 2.0\fR -.sp -.LP -\fIWireless Universal Serial Bus Specification 1.0\fR -.sp -.LP -http://www.usb.org -.sp -.LP -http://www.sun.com -.SH DIAGNOSTICS -.sp -.LP -All host controller errors are passed to the client drivers. In addition to -being logged, the following messages can appear on the system console. All -messages are formatted in the following way: -.sp -.in +2 -.nf -WARNING: \fIdevice_path hwahc instance_number\fR: Message ... - -Connection device on WUSB port \fIport_number\fR fails -.fi -.in -2 -.sp - -.sp -.LP -The connecting device fails to connect to the HWA. Make sure the device has -been associated with the host. diff --git a/usr/src/man/man7d/hwarc.7d b/usr/src/man/man7d/hwarc.7d deleted file mode 100644 index e1ed89c1ab..0000000000 --- a/usr/src/man/man7d/hwarc.7d +++ /dev/null @@ -1,89 +0,0 @@ -'\" te -.\" Copyright (c) 2009, Sun Microsystems, Inc. All Rights Reserved -.\" 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 or http://www.opensolaris.org/os/licensing. -.\" 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] -.TH HWARC 7D "Apr 17, 2009" -.SH NAME -hwarc \- HWA Radio Controller Driver -.SH SYNOPSIS -.LP -.nf -hwa-radio@unit-address -.fi - -.SH DESCRIPTION -.sp -.LP -The \fBhwarc\fR driver is a USBA (Solaris USB Architecture) compliant client -driver that supports Host Wire Adapter Radio Controller, specified in Wireless -Universal Serial Bus Specification, Version 1.0. -.sp -.LP -The \fBhwarc\fR driver handles the Radio Controller Interface of an HWA device -and properly controls the UWB (Ultra Wideband) Radio in the device. The driver -controls an HWA device to Scan, Start/Stop Beacon, Get IE, and so forth. -.SH FILES -.sp -.ne 2 -.na -\fB\fB/kernel/drv/hwarc\fR\fR -.ad -.RS 29n -32-bit ELF 86 kernel module -.RE - -.sp -.ne 2 -.na -\fB\fB/kernel/drv/sparcv9/hwarc\fR\fR -.ad -.RS 29n -64-bit SPARC ELF kernel module -.RE - -.sp -.ne 2 -.na -\fB\fB/kernel/drv/amd64/hwarc\fR\fR -.ad -.RS 29n -64-bit x86 ELF kernel module -.RE - -.SH ATTRIBUTES -.sp -.LP -See \fBattributes\fR(5) for a description of the following attributes: -.sp - -.sp -.TS -box; -l | l -l | l . -ATTRIBUTE TYPE ATTRIBUTE VALUE -_ -Architecture SPARC, x86 -.TE - -.SH SEE ALSO -.sp -.LP -\fBadd_drv\fR(1M), \fBprtconf\fR(1M), \fBrem_drv\fR(1M), \fBupdate_drv\fR(1M), -\fBattributes\fR(5), \fBhwahc\fR(7D), \fBusba\fR(7D), \fBuwba\fR(7D), -.sp -.LP -\fIWriting Device Drivers\fR -.sp -.LP -\fIUniversal Serial Bus Specification 1.0, 1.1 and 2.0 - 1996, 1998, 2000\fR -.sp -.LP -\fIWireless Universal Serial Bus Specification 1.0\fR -.sp -.LP -http://www.usb.org -.sp -.LP -http://www.sun.com diff --git a/usr/src/man/man7d/uwba.7d b/usr/src/man/man7d/uwba.7d deleted file mode 100644 index ad0dc57bc9..0000000000 --- a/usr/src/man/man7d/uwba.7d +++ /dev/null @@ -1,86 +0,0 @@ -'\" te -.\" Copyright (c) 2009, Sun Microsystems, Inc. All Rights Reserved -.\" 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 or http://www.opensolaris.org/os/licensing. -.\" 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] -.TH UWBA 7D "Apr 17, 2009" -.SH NAME -uwba, uwb \- Solaris UWB Architecture (UWBA) -.SH DESCRIPTION -.sp -.LP -Ultra-WideBand (UWB) radio technology supports high bandwidth for wireless -devices. UWBA is a miscellaneous module and it supports radio controller -drivers for UWB based devices like HWA (Host Wire Adapter), WHCI (Wireless Host -Controller Interface) and so forth. For example, both HWA radio controller -driver (\fBhwarc\fR) and \fBwhci\fR driver register to \fBuwba\fR during -attach. -.sp -.LP -UWBA provides a series of common interfaces for drivers that support UWB radio -technology. Each radio controller driver register itself as a UWB dev to the -uwba model in the attach entry, then other driver or module can control this -device to perform the UWB functions through a list of common interface. For -example, a \fBhwahc\fR driver can control the \fBhwarc\fR driver to scan in a -specific channel, start/stop beacon, manage device/MAC address, and so forth. -.SH FILES -.sp -.ne 2 -.na -\fB\fB/kernel/misc/uwba\fR\fR -.ad -.RS 29n -32-bit ELF 86 kernel module -.RE - -.sp -.ne 2 -.na -\fB\fB/kernel/misc/amd64/uwba\fR\fR -.ad -.RS 29n -64-bit x86 ELF kernel module -.RE - -.sp -.ne 2 -.na -\fB\fB/kernel/misc/sparcv9/uwba\fR\fR -.ad -.RS 29n -64-bit SPARC ELF kernel module -.RE - -.SH ATTRIBUTES -.sp -.LP -See \fBattributes\fR(5) for a description of the following attributes: -.sp - -.sp -.TS -box; -l | l -l | l . -ATTRIBUTE TYPE ATTRIBUTE VALUE -_ -Architecture PCI-based systems -.TE - -.SH SEE ALSO -.sp -.LP -\fBattributes\fR(5), \fBhwahc\fR(7D), \fBhwarc\fR(7D), \fBusba\fR(7D) -.sp -.LP -\fIWriting Device Drivers\fR -.sp -.LP -\fIECMA-368 High Rate Ultra Wideband PHY and MAC Standard, 1st Edition\fR -.sp -.LP -\fIWireless Host Controller Interface Specification for Certified Wireless -Universal Serial Bus, Version 0.95\fR -.sp -.LP -\fIWireless Universal Serial Bus Specification 1.0\fR diff --git a/usr/src/man/man7d/wusb_ca.7d b/usr/src/man/man7d/wusb_ca.7d deleted file mode 100644 index 2af68c2a0e..0000000000 --- a/usr/src/man/man7d/wusb_ca.7d +++ /dev/null @@ -1,92 +0,0 @@ -'\" te -.\" Copyright (c) 2009, Sun Microsystems, Inc. All Rights Reserved -.\" 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 or http://www.opensolaris.org/os/licensing. -.\" 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] -.TH WUSB_CA 7D "Apr 17, 2009" -.SH NAME -wusb_ca \- WUSB Cable Association Driver -.SH DESCRIPTION -.sp -.LP -The \fBwusb_ca\fR driver is a USBA (Solaris USB Architecture) compliant client -driver that supports the cable association model which is defined in -Association Models Supplement to the Certified WUSB specification. -.sp -.LP -The wireless USB cable association driver is a USB class driver that provides -interfaces for establishing a first-time connection between Wireless USB hosts -and devices. This process of establishing a first-time connection is called -\fIassociation\fR in WUSB standard. It is a prerequisite process that must be -completed by hosts and devices prior to implementing the security requirements -outlined in \fIWireless Universal Serial Bus Specification 1.0\fR. -.sp -.LP -Users should use \fBwusbadm\fR(1M) to do cable association for WUSB devices. -.SH FILES -.sp -.ne 2 -.na -\fB\fB/kernel/drv/wusb_ca\fR\fR -.ad -.sp .6 -.RS 4n -32-bit ELF 86 kernel module -.RE - -.sp -.ne 2 -.na -\fB\fB/kernel/drv/amd64/wusb_ca\fR\fR -.ad -.sp .6 -.RS 4n -64-bit x86 ELF kernel module -.RE - -.sp -.ne 2 -.na -\fB\fB/kernel/drv/sparcv9/wusb_ca\fR\fR -.ad -.sp .6 -.RS 4n -64-bit SPARC ELF kernel module -.RE - -.SH ATTRIBUTES -.sp -.LP -See \fBattributes\fR(5) for a description of the following attributes: -.sp - -.sp -.TS -box; -l | l -l | l . -ATTRIBUTE TYPE ATTRIBUTE VALUE -_ -Architecture SPARC, x86, PCI-based systems -.TE - -.SH SEE ALSO -.sp -.LP -\fBwusbadm\fR(1M), \fBattributes\fR(5), \fBhwahc\fR(7D), \fBhwarc\fR(7D), -\fBusba\fR(7D) -.sp -.LP -\fIWriting Device Drivers\fR -.sp -.LP -\fISystem Administration Guide: Basic Administration\fR -.sp -.LP -\fIWireless Universal Serial Bus Specification 1.0\fR -.sp -.LP -http://www.usb.org -.sp -.LP -http://www.sun.com diff --git a/usr/src/man/man7d/wusb_df.7d b/usr/src/man/man7d/wusb_df.7d deleted file mode 100644 index 8993e3a058..0000000000 --- a/usr/src/man/man7d/wusb_df.7d +++ /dev/null @@ -1,124 +0,0 @@ -'\" te -.\" Copyright (c) 2009, Sun Microsystems, Inc. All Rights Reserved -.\" 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 or http://www.opensolaris.org/os/licensing. -.\" 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] -.TH WUSB_DF 7D "Sep 18, 2009" -.SH NAME -wusb_df, hwa1480_fw \- WUSB firmware download driver and firmware module for -Intel i1480 chipset -.SH DESCRIPTION -.sp -.LP -The \fBwusb_df\fR driver is a Solaris USB Architecture (USBA) compliant client -driver that is used to download firmware for Host Wire Adapter (HWA) dongles -that use Intel i1480 chipsets. -.sp -.LP -Currently, the \fBwusb_df\fR driver can only download driver for Intel i1480 -based HWA dongles. The \fBhwa1480_fw\fR is a miscellaneous module which is -transformed from Intel's firmware binary version RC1.3PA2-20070828. -\fBwusb_df\fR reads firmware data from \fBhwa1480_fw\fR module and downloads it -to HWA hardware. -.sp -.LP -Users can use \fBelfwrap\fR(1) to transform new firmware binary. Users must use -the same name as \fBhwa1480_fw\fR, since \fBwusb_df\fR only recognizes this -symbol. -.SH FILES -.sp -.ne 2 -.na -\fB\fB/kernel/drv/wusb_df\fR\fR -.ad -.sp .6 -.RS 4n -32-bit ELF 86 kernel module -.RE - -.sp -.ne 2 -.na -\fB\fB/kernel/drv/sparcv9/wusb_df\fR\fR -.ad -.sp .6 -.RS 4n -64-bit SPARC ELF kernel module -.RE - -.sp -.ne 2 -.na -\fB\fB/kernel/drv/amd64/wusb_df\fR\fR -.ad -.sp .6 -.RS 4n -64-bit x86 ELF kernel module -.RE - -.sp -.ne 2 -.na -\fB\fB/kernel/misc/hwa_1480\fR\fR -.ad -.sp .6 -.RS 4n -32-bit ELF 86 kernel module -.RE - -.sp -.ne 2 -.na -\fB\fB/kernel/misc/sparcv9/hwa_1480\fR\fR -.ad -.sp .6 -.RS 4n -64-bit SPARC ELF kernel module -.RE - -.sp -.ne 2 -.na -\fB\fB/kernel/drv/amd64/hwa_1480\fR\fR -.ad -.sp .6 -.RS 4n -64-bit x86 ELF kernel module -.RE - -.SH ATTRIBUTES -.sp -.LP -See \fBattributes\fR(5) for a description of the following attributes: -.sp - -.sp -.TS -box; -l | l -l | l . -ATTRIBUTE TYPE ATTRIBUTE VALUE -_ -Architecture SPARC, x86, PCI-based systems -.TE - -.SH SEE ALSO -.sp -.LP -\fBelfwrap\fR(1)\fBadd_drv\fR(1M), \fBrem_drv\fR(1M), \fBupdate_drv\fR(1M), -\fBattributes\fR(5) -.sp -.LP -\fIWriting Device Drivers\fR -.sp -.LP -\fISystem Administration Guide: Basic Administration\fR -.sp -.LP -\fIWireless Universal Serial Bus Specification 1.0\fR -.sp -.LP -http://www.usb.org -.sp -.LP -http://www.sun.com diff --git a/usr/src/pkg/manifests/SUNWcs.man1m.inc b/usr/src/pkg/manifests/SUNWcs.man1m.inc index 0f9d620d02..3bba753ce6 100644 --- a/usr/src/pkg/manifests/SUNWcs.man1m.inc +++ b/usr/src/pkg/manifests/SUNWcs.man1m.inc @@ -276,7 +276,6 @@ file path=usr/share/man/man1m/volcopy_ufs.1m file path=usr/share/man/man1m/wall.1m file path=usr/share/man/man1m/whodo.1m file path=usr/share/man/man1m/wracct.1m -file path=usr/share/man/man1m/wusbadm.1m file path=usr/share/man/man1m/zdump.1m file path=usr/share/man/man1m/zic.1m link path=usr/share/man/man1m/dcopy.1m target=clri.1m diff --git a/usr/src/pkg/manifests/SUNWcs.mf b/usr/src/pkg/manifests/SUNWcs.mf index 3acb0aff2d..a0f5abd72c 100644 --- a/usr/src/pkg/manifests/SUNWcs.mf +++ b/usr/src/pkg/manifests/SUNWcs.mf @@ -23,6 +23,7 @@ # Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved. # Copyright 2015 Nexenta Systems, Inc. All rights reserved. # Copyright (c) 2013 Gary Mills +# Copyright 2014 Garrett D'Amore <garrett@damore.org> # <include SUNWcs.man1.inc> @@ -664,7 +665,6 @@ file path=sbin/uadmin group=sys mode=0555 file path=sbin/umount mode=0555 file path=sbin/umountall group=sys mode=0555 file path=sbin/uname mode=0555 -file path=sbin/wusbadm mode=0555 file path=sbin/zonename mode=0555 $(i386_ONLY)file path=usr/bin/$(ARCH32)/amt mode=0555 file path=usr/bin/$(ARCH32)/decrypt mode=0555 @@ -1785,7 +1785,6 @@ link path=usr/lib/locale/POSIX target=./C link path=usr/lib/rsh target=../bin/ksh93 link path=usr/lib/secure/32 target=. link path=usr/lib/secure/64 target=$(ARCH64) -link path=usr/lib/wusbd target=../../sbin/wusbadm link path=usr/mail target=../var/mail link path=usr/net/nls/listen target=../../lib/saf/listen link path=usr/net/nls/nlps_server target=../../lib/saf/nlps_server @@ -1838,7 +1837,6 @@ link path=usr/sbin/uadmin target=../../sbin/uadmin link path=usr/sbin/ufsdump target=../lib/fs/ufs/ufsdump link path=usr/sbin/ufsrestore target=../lib/fs/ufs/ufsrestore link path=usr/sbin/umount target=../../sbin/umount -link path=usr/sbin/wusbadm target=../../sbin/wusbadm link path=usr/spool target=../var/spool link path=usr/src target=./share/src link path=usr/tmp target=../var/tmp diff --git a/usr/src/pkg/manifests/driver-usb.mf b/usr/src/pkg/manifests/driver-usb.mf index fbcbda090e..b9ac3d016d 100644 --- a/usr/src/pkg/manifests/driver-usb.mf +++ b/usr/src/pkg/manifests/driver-usb.mf @@ -22,6 +22,7 @@ # # Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved. # Copyright 2012 Nexenta Systems, Inc. All rights reserved. +# Copyright 2014 Garrett D'Amore <garrett@damore.org> # # @@ -61,8 +62,6 @@ dir path=usr/share/man/man9s driver name=ehci alias=pciclass,0c0320 perms="* 0644 root sys" driver name=hid alias=usbif,class3 perms="* 0600 root sys" driver name=hubd alias=usbif,class9 perms="* 0644 root sys" -driver name=hwahc alias=usbif,classe0.2.1 perms="* 0644 root sys" -driver name=hwarc alias=usbif,classe0.1.2 perms="* 0644 root sys" driver name=ohci alias=pciclass,0c0310 perms="* 0644 root sys" driver name=scsa2usb \ alias=usb584,222 \ @@ -73,17 +72,11 @@ driver name=usb_as alias=usbif,class1.2 perms="* 0600 root sys" driver name=usb_ia alias=usb,ia driver name=usb_mid alias=usb,device driver name=usbprn alias=usbif,class7.1 perms="* 0666 root sys" -driver name=wusb_ca alias=usbif,classef.3.1 perms="* 0666 root sys" -driver name=wusb_df perms="* 0666 root sys" \ - alias=usb15a9,5 \ - alias=usb3495,3007 file path=etc/usb/config_map.conf group=sys \ original_name=SUNWusb:etc/usb/config_map.conf preserve=true file path=kernel/drv/$(ARCH64)/ehci group=sys file path=kernel/drv/$(ARCH64)/hid group=sys file path=kernel/drv/$(ARCH64)/hubd group=sys -file path=kernel/drv/$(ARCH64)/hwahc group=sys -file path=kernel/drv/$(ARCH64)/hwarc group=sys file path=kernel/drv/$(ARCH64)/ohci group=sys file path=kernel/drv/$(ARCH64)/scsa2usb group=sys file path=kernel/drv/$(ARCH64)/uhci group=sys @@ -92,14 +85,10 @@ file path=kernel/drv/$(ARCH64)/usb_as group=sys file path=kernel/drv/$(ARCH64)/usb_ia group=sys file path=kernel/drv/$(ARCH64)/usb_mid group=sys file path=kernel/drv/$(ARCH64)/usbprn group=sys -file path=kernel/drv/$(ARCH64)/wusb_ca group=sys -file path=kernel/drv/$(ARCH64)/wusb_df group=sys $(i386_ONLY)file path=kernel/drv/ehci group=sys file path=kernel/drv/ehci.conf group=sys $(i386_ONLY)file path=kernel/drv/hid group=sys $(i386_ONLY)file path=kernel/drv/hubd group=sys -$(i386_ONLY)file path=kernel/drv/hwahc group=sys -$(i386_ONLY)file path=kernel/drv/hwarc group=sys $(i386_ONLY)file path=kernel/drv/ohci group=sys file path=kernel/drv/ohci.conf group=sys $(i386_ONLY)file path=kernel/drv/scsa2usb group=sys @@ -113,14 +102,10 @@ $(i386_ONLY)file path=kernel/drv/usb_as group=sys $(i386_ONLY)file path=kernel/drv/usb_ia group=sys $(i386_ONLY)file path=kernel/drv/usb_mid group=sys $(i386_ONLY)file path=kernel/drv/usbprn group=sys -$(i386_ONLY)file path=kernel/drv/wusb_ca group=sys -$(i386_ONLY)file path=kernel/drv/wusb_df group=sys file path=kernel/misc/$(ARCH64)/hidparser group=sys mode=0755 -file path=kernel/misc/$(ARCH64)/hwa1480_fw group=sys mode=0755 file path=kernel/misc/$(ARCH64)/usba group=sys mode=0755 file path=kernel/misc/$(ARCH64)/usba10 group=sys mode=0755 $(i386_ONLY)file path=kernel/misc/hidparser group=sys mode=0755 -$(i386_ONLY)file path=kernel/misc/hwa1480_fw group=sys mode=0755 $(i386_ONLY)file path=kernel/misc/usba group=sys mode=0755 $(i386_ONLY)file path=kernel/misc/usba10 group=sys mode=0755 file path=kernel/strmod/$(ARCH64)/usb_ah group=sys mode=0755 @@ -131,13 +116,9 @@ $(i386_ONLY)file path=kernel/strmod/usb_ah group=sys mode=0755 $(i386_ONLY)file path=kernel/strmod/usbkbm group=sys mode=0755 $(i386_ONLY)file path=kernel/strmod/usbms group=sys mode=0755 $(i386_ONLY)file path=kernel/strmod/usbwcm group=sys mode=0755 -file path=lib/svc/manifest/system/wusb.xml group=sys mode=0444 -file path=lib/svc/method/svc-wusb mode=0555 file path=usr/share/man/man7d/ehci.7d file path=usr/share/man/man7d/hid.7d file path=usr/share/man/man7d/hubd.7d -file path=usr/share/man/man7d/hwahc.7d -file path=usr/share/man/man7d/hwarc.7d file path=usr/share/man/man7d/ohci.7d file path=usr/share/man/man7d/scsa2usb.7d file path=usr/share/man/man7d/uhci.7d @@ -147,8 +128,6 @@ file path=usr/share/man/man7d/usb_ia.7d file path=usr/share/man/man7d/usb_mid.7d file path=usr/share/man/man7d/usba.7d file path=usr/share/man/man7d/usbprn.7d -file path=usr/share/man/man7d/wusb_ca.7d -file path=usr/share/man/man7d/wusb_df.7d file path=usr/share/man/man7m/usb_ah.7m file path=usr/share/man/man7m/usbkbm.7m file path=usr/share/man/man7m/usbms.7m @@ -200,9 +179,6 @@ legacy pkg=SUNWusb desc="USBA (USB framework) and USB Device Drivers" \ license cr_Sun license=cr_Sun license lic_CDDL license=lic_CDDL license license_in_headers license=license_in_headers -license usr/src/uts/common/io/usb/clients/hwa1480_fw/i1480/LICENSE \ - license=usr/src/uts/common/io/usb/clients/hwa1480_fw/i1480/LICENSE -link path=usr/share/man/man7d/hwa1480_fw.7d target=wusb_df.7d link path=usr/share/man/man7d/usb.7d target=usba.7d link path=usr/share/man/man9f/usb_alloc_bulk_req.9f \ target=usb_alloc_request.9f diff --git a/usr/src/pkg/manifests/system-header-header-usb.mf b/usr/src/pkg/manifests/system-header-header-usb.mf index d9c8b49b57..85c19361ff 100644 --- a/usr/src/pkg/manifests/system-header-header-usb.mf +++ b/usr/src/pkg/manifests/system-header-header-usb.mf @@ -21,6 +21,7 @@ # # Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved. +# Copyright 2014 Garrett D'Amore <garrett@damore.org> # set name=pkg.fmri value=pkg:/system/header/header-usb@$(PKGVERS) @@ -36,7 +37,6 @@ dir path=usr/include/sys/usb dir path=usr/include/sys/usb/clients dir path=usr/include/sys/usb/clients/audio dir path=usr/include/sys/usb/clients/hid -dir path=usr/include/sys/usb/clients/hwarc dir path=usr/include/sys/usb/clients/mass_storage dir path=usr/include/sys/usb/clients/printer dir path=usr/include/sys/usb/clients/usbcdc @@ -45,11 +45,8 @@ dir path=usr/include/sys/usb/clients/usbinput/usbwcm dir path=usr/include/sys/usb/clients/video dir path=usr/include/sys/usb/clients/video/usbvc dir path=usr/include/sys/usb/hubd -dir path=usr/include/sys/uwb -dir path=usr/include/sys/uwb/uwba file path=usr/include/sys/usb/clients/audio/usb_audio.h file path=usr/include/sys/usb/clients/hid/hid.h -file path=usr/include/sys/usb/clients/hwarc/hwarc.h file path=usr/include/sys/usb/clients/mass_storage/usb_bulkonly.h file path=usr/include/sys/usb/clients/mass_storage/usb_cbi.h file path=usr/include/sys/usb/clients/printer/usb_printer.h @@ -60,9 +57,6 @@ file path=usr/include/sys/usb/hubd/hub.h file path=usr/include/sys/usb/usba.h file path=usr/include/sys/usb/usbai.h file path=usr/include/sys/usb/usbdevs.h -file path=usr/include/sys/uwb/uwb.h -file path=usr/include/sys/uwb/uwba/uwba.h -file path=usr/include/sys/uwb/uwbai.h legacy pkg=SUNWusbu desc="USB Headers" name="USB Headers" license cr_Sun license=cr_Sun license lic_CDDL license=lic_CDDL diff --git a/usr/src/pkg/manifests/system-kernel-ultra-wideband.mf b/usr/src/pkg/manifests/system-kernel-ultra-wideband.mf index be309e6075..76c1b7cb8f 100644 --- a/usr/src/pkg/manifests/system-kernel-ultra-wideband.mf +++ b/usr/src/pkg/manifests/system-kernel-ultra-wideband.mf @@ -22,6 +22,7 @@ # # Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved. # Copyright 2012 Nexenta Systems, Inc. All rights reserved. +# Copyright 2014 Garrett D'Amore <garrett@damore.org> # # @@ -31,21 +32,5 @@ # <include global_zone_only_component> set name=pkg.fmri value=pkg:/system/kernel/ultra-wideband@$(PKGVERS) -set name=pkg.description value="Common framework for UWB device drivers" -set name=pkg.summary value="Ultra Wideband (UWB) support modules" -set name=info.classification \ - value=org.opensolaris.category.2008:System/Hardware +set name=pkg.obsolete value=true set name=variant.arch value=$(ARCH) -dir path=kernel group=sys -dir path=kernel/misc group=sys -dir path=kernel/misc/$(ARCH64) group=sys -dir path=usr/share/man -dir path=usr/share/man/man7d -file path=kernel/misc/$(ARCH64)/uwba group=sys mode=0755 -$(i386_ONLY)file path=kernel/misc/uwba group=sys mode=0755 -file path=usr/share/man/man7d/uwba.7d -legacy pkg=SUNWuwb desc="Common framework for UWB device drivers" \ - name="Ultra Wideband (UWB) support modules" -license cr_Sun license=cr_Sun -license lic_CDDL license=lic_CDDL -link path=usr/share/man/man7d/uwb.7d target=uwba.7d diff --git a/usr/src/uts/common/Makefile.files b/usr/src/uts/common/Makefile.files index d7dc276f69..0b6309a8a8 100644 --- a/usr/src/uts/common/Makefile.files +++ b/usr/src/uts/common/Makefile.files @@ -757,8 +757,6 @@ BOFI_OBJS += bofi.o HID_OBJS += hid.o -HWA_RC_OBJS += hwarc.o - USBSKEL_OBJS += usbskel.o USBVC_OBJS += usbvc.o usbvc_v4l2.o @@ -787,8 +785,6 @@ USBS49_FW_OBJS += keyspan_49fw.o USBSPRL_OBJS += usbser_pl2303.o pl2303_dsd.o -WUSB_CA_OBJS += wusb_ca.o - USBFTDI_OBJS += usbser_uftdi.o uftdi_dsd.o USBECM_OBJS += usbecm.o @@ -824,9 +820,6 @@ SATA_OBJS += sata.o USBA_OBJS += hcdi.o usba.o usbai.o hubdi.o parser.o genconsole.o \ usbai_pipe_mgmt.o usbai_req.o usbai_util.o usbai_register.o \ - usba_devdb.o usba10_calls.o usba_ugen.o whcdi.o wa.o -USBA_WITHOUT_WUSB_OBJS += hcdi.o usba.o usbai.o hubdi.o parser.o genconsole.o \ - usbai_pipe_mgmt.o usbai_req.o usbai_util.o usbai_register.o \ usba_devdb.o usba10_calls.o usba_ugen.o USBA10_OBJS += usba10.o @@ -1742,15 +1735,8 @@ USB_MID_OBJS += usb_mid.o USB_IA_OBJS += usb_ia.o -UWBA_OBJS += uwba.o uwbai.o - SCSA2USB_OBJS += scsa2usb.o usb_ms_bulkonly.o usb_ms_cbi.o -HWAHC_OBJS += hwahc.o hwahc_util.o - -WUSB_DF_OBJS += wusb_df.o -WUSB_FWMOD_OBJS += wusb_fwmod.o - IPF_OBJS += ip_fil_solaris.o fil.o solaris.o ip_state.o ip_frag.o ip_nat.o \ ip_proxy.o ip_auth.o ip_pool.o ip_htable.o ip_lookup.o \ ip_log.o misc.o ip_compat.o ip_nat6.o drand48.o diff --git a/usr/src/uts/common/Makefile.rules b/usr/src/uts/common/Makefile.rules index fe48d43775..c5e728fdff 100644 --- a/usr/src/uts/common/Makefile.rules +++ b/usr/src/uts/common/Makefile.rules @@ -1185,10 +1185,6 @@ $(OBJS_DIR)/%.o: $(UTSBASE)/common/io/usb/clients/video/usbvc/%.c $(COMPILE.c) -o $@ $< $(CTFCONVERT_O) -$(OBJS_DIR)/%.o: $(UTSBASE)/common/io/usb/clients/hwarc/%.c - $(COMPILE.c) -o $@ $< - $(CTFCONVERT_O) - $(OBJS_DIR)/%.o: $(UTSBASE)/common/io/usb/clients/hid/%.c $(COMPILE.c) -o $@ $< $(CTFCONVERT_O) @@ -1237,18 +1233,6 @@ $(OBJS_DIR)/%.o: $(UTSBASE)/common/io/usb/clients/usbser/usbsprl/%.c $(COMPILE.c) -o $@ $< $(CTFCONVERT_O) -$(OBJS_DIR)/%.o: $(UTSBASE)/common/io/usb/clients/wusb_df/%.c - $(COMPILE.c) -o $@ $< - $(CTFCONVERT_O) - -$(OBJS_DIR)/%.o: $(UTSBASE)/common/io/usb/clients/hwa1480_fw/%.c - $(COMPILE.c) -o $@ $< - $(CTFCONVERT_O) - -$(OBJS_DIR)/%.o: $(UTSBASE)/common/io/usb/clients/wusb_ca/%.c - $(COMPILE.c) -o $@ $< - $(CTFCONVERT_O) - $(OBJS_DIR)/%.o: $(UTSBASE)/common/io/usb/clients/usbecm/%.c $(COMPILE.c) -o $@ $< $(CTFCONVERT_O) @@ -1289,14 +1273,6 @@ $(OBJS_DIR)/%.o: $(UTSBASE)/common/io/usb/usba10/%.c $(COMPILE.c) -o $@ $< $(CTFCONVERT_O) -$(OBJS_DIR)/%.o: $(UTSBASE)/common/io/usb/hwa/hwahc/%.c - $(COMPILE.c) -o $@ $< - $(CTFCONVERT_O) - -$(OBJS_DIR)/%.o: $(UTSBASE)/common/io/uwb/uwba/%.c - $(COMPILE.c) -o $@ $< - $(CTFCONVERT_O) - $(OBJS_DIR)/%.o: $(UTSBASE)/common/io/vuidmice/%.c $(COMPILE.c) -o $@ $< $(CTFCONVERT_O) @@ -2459,9 +2435,6 @@ $(LINTS_DIR)/%.ln: $(UTSBASE)/common/io/usb/clients/usbskel/%.c $(LINTS_DIR)/%.ln: $(UTSBASE)/common/io/usb/clients/video/usbvc/%.c @($(LHEAD) $(LINT.c) $< $(LTAIL)) -$(LINTS_DIR)/%.ln: $(UTSBASE)/common/io/usb/clients/hwarc/%.c - @($(LHEAD) $(LINT.c) $< $(LTAIL)) - $(LINTS_DIR)/%.ln: $(UTSBASE)/common/io/usb/clients/hid/%.c @($(LHEAD) $(LINT.c) $< $(LTAIL)) @@ -2498,15 +2471,6 @@ $(LINTS_DIR)/%.ln: $(UTSBASE)/common/io/usb/clients/usbser/usbser_keyspan/%.c $(LINTS_DIR)/%.ln: $(UTSBASE)/common/io/usb/clients/usbser/usbsprl/%.c @($(LHEAD) $(LINT.c) $< $(LTAIL)) -$(LINTS_DIR)/%.ln: $(UTSBASE)/common/io/usb/clients/wusb_df/%.c - @($(LHEAD) $(LINT.c) $< $(LTAIL)) - -$(LINTS_DIR)/%.ln: $(UTSBASE)/common/io/usb/clients/hwa1480_fw/%.c - @($(LHEAD) $(LINT.c) $< $(LTAIL)) - -$(LINTS_DIR)/%.ln: $(UTSBASE)/common/io/usb/clients/wusb_ca/%.c - @($(LHEAD) $(LINT.c) $< $(LTAIL)) - $(LINTS_DIR)/%.ln: $(UTSBASE)/common/io/usb/clients/usbecm/%.c @($(LHEAD) $(LINT.c) $< $(LTAIL)) @@ -2537,12 +2501,6 @@ $(LINTS_DIR)/%.ln: $(UTSBASE)/common/io/usb/usba/%.c $(LINTS_DIR)/%.ln: $(UTSBASE)/common/io/usb/usba10/%.c @($(LHEAD) $(LINT.c) $< $(LTAIL)) -$(LINTS_DIR)/%.ln: $(UTSBASE)/common/io/uwb/uwba/%.c - @($(LHEAD) $(LINT.c) $< $(LTAIL)) - -$(LINTS_DIR)/%.ln: $(UTSBASE)/common/io/usb/hwa/hwahc/%.c - @($(LHEAD) $(LINT.c) $< $(LTAIL)) - $(LINTS_DIR)/%.ln: $(UTSBASE)/common/io/vuidmice/%.c @($(LHEAD) $(LINT.c) $< $(LTAIL)) diff --git a/usr/src/uts/common/io/usb/clients/hwa1480_fw/i1480/LICENSE b/usr/src/uts/common/io/usb/clients/hwa1480_fw/i1480/LICENSE deleted file mode 100644 index c554213283..0000000000 --- a/usr/src/uts/common/io/usb/clients/hwa1480_fw/i1480/LICENSE +++ /dev/null @@ -1,40 +0,0 @@ -Copyright (c) 2007, Intel Corporation. All rights reserved. - -Redistribution. Redistribution and use in binary form, without -modification, are permitted provided that the following conditions are -met: - -* Redistributions must reproduce the above copyright notice and the - following disclaimer in the documentation and/or other materials - provided with the distribution. - -* Neither the name of Intel Corporation nor the names of its suppliers - may be used to endorse or promote products derived from this - software without specific prior written permission. - -* No reverse engineering, decompilation, or disassembly of this - software is permitted. - -Limited patent license. Intel Corporation grants a world-wide, -royalty-free, non-exclusive license under patents it now or hereafter -owns or controls to make, have made, use, import, offer to sell and -sell ("Utilize") this software, but solely to the extent that any such -patent is necessary to Utilize the software alone, or in combination -with an operating system licensed under an approved Open Source -license as listed by the Open Source Initiative at -http://opensource.org/licenses. The patent license shall not apply to -any other combinations which include this software. No hardware per -se is licensed hereunder. - -DISCLAIMER. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND -CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, -BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND -FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE -COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, -INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, -BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS -OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR -TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE -USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH -DAMAGE. diff --git a/usr/src/uts/common/io/usb/clients/hwa1480_fw/i1480/LICENSE.descrip b/usr/src/uts/common/io/usb/clients/hwa1480_fw/i1480/LICENSE.descrip deleted file mode 100644 index dd45859383..0000000000 --- a/usr/src/uts/common/io/usb/clients/hwa1480_fw/i1480/LICENSE.descrip +++ /dev/null @@ -1 +0,0 @@ -INTEL I1480 USB FIRMWARE diff --git a/usr/src/uts/common/io/usb/clients/hwa1480_fw/i1480/i1480-usb-0.0.bin b/usr/src/uts/common/io/usb/clients/hwa1480_fw/i1480/i1480-usb-0.0.bin Binary files differdeleted file mode 100644 index 82fc7d7278..0000000000 --- a/usr/src/uts/common/io/usb/clients/hwa1480_fw/i1480/i1480-usb-0.0.bin +++ /dev/null diff --git a/usr/src/uts/common/io/usb/clients/hwa1480_fw/wusb_fwmod.c b/usr/src/uts/common/io/usb/clients/hwa1480_fw/wusb_fwmod.c deleted file mode 100644 index 762245bb24..0000000000 --- a/usr/src/uts/common/io/usb/clients/hwa1480_fw/wusb_fwmod.c +++ /dev/null @@ -1,67 +0,0 @@ -/* - * 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 - * or http://www.opensolaris.org/os/licensing. - * 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. - */ - -/* - * misc module wrapper for a WUSB firmware module - * User must use elfwrap(1) to convert raw firmware data file to - * ELF object file. Then use ld(1) to link the ELF object file and - * this module to produce a kernel loadable module. - */ - -#include <sys/types.h> -#include <sys/param.h> -#include <sys/errno.h> -#include <sys/modctl.h> - - -extern struct mod_ops mod_miscops; -static struct modlmisc modlmisc = { - &mod_miscops, - "WUSB firmware wrapper module 1.1" -}; -static struct modlinkage modlinkage = { - MODREV_1, - &modlmisc, - 0 -}; - -int -_init(void) -{ - return (mod_install(&modlinkage)); -} - -int -_fini(void) -{ - return (mod_remove(&modlinkage)); -} - -int -_info(struct modinfo *modinfop) -{ - return (mod_info(&modlinkage, modinfop)); -} diff --git a/usr/src/uts/common/io/usb/clients/hwarc/hwarc.c b/usr/src/uts/common/io/usb/clients/hwarc/hwarc.c deleted file mode 100644 index d6bccedb89..0000000000 --- a/usr/src/uts/common/io/usb/clients/hwarc/hwarc.c +++ /dev/null @@ -1,1613 +0,0 @@ -/* - * 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 - * or http://www.opensolaris.org/os/licensing. - * 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. - */ - - -/* - * UWB HWA Radio Controller driver. - * - * - * The device has four states (refer to usbai.h): - * USB_DEV_ONLINE: In action or ready for action. - * USB_DEV_DISCONNECTED: Hotplug removed, or device not present/correct on - * resume (CPR). - * USB_DEV_SUSPENDED: Device has been suspended along with the system. - * USB_DEV_PWRED_DOWN: Device has been powered down. (Note that this - * driver supports only two power states, powered down and - * full power.) - * - * In order to avoid race conditions between driver entry points, - * access to the device is serialized. Race conditions are an issue in - * particular between disconnect event callbacks, detach, power, open - * and data transfer callbacks. The functions hwarc_serialize/release_access - * are implemented for this purpose. - * - * Mutexes should never be held when making calls into USBA or when - * sleeping. - * - * pm_busy_component and pm_idle_component mark the device as busy or idle to - * the system. These functions are paired, and are called only from code - * bracketed by hwarc_serialize_access and hwarc_release_access. - * - */ - -#define USBDRV_MAJOR_VER 2 -#define USBDRV_MINOR_VER 0 - -#include <sys/strsun.h> -#include <sys/usb/usba.h> -#include <sys/usb/clients/hwarc/hwarc.h> - - - -uint_t hwarc_errlevel = 4; -static uint_t hwarc_errmask = (uint_t)PRINT_MASK_ALL; -static uint_t hwarc_instance_debug = (uint_t)-1; - -static char *name = "hwarc"; /* Driver name, used all over */ - - -/* Function Prototypes */ -static int hwarc_attach(dev_info_t *, ddi_attach_cmd_t); -static int hwarc_detach(dev_info_t *, ddi_detach_cmd_t); -static int hwarc_info(dev_info_t *, ddi_info_cmd_t, void *, void **); -static int hwarc_cleanup(dev_info_t *, hwarc_state_t *); -static int hwarc_open(dev_t *, int, int, cred_t *); -static int hwarc_close(dev_t, int, int, cred_t *); -static int hwarc_send_cmd(uwb_dev_handle_t, mblk_t *, uint16_t); -static int hwarc_ioctl(dev_t, int, intptr_t, int, cred_t *, int *); -static int hwarc_disconnect_callback(dev_info_t *); -static int hwarc_reconnect_callback(dev_info_t *); -static void hwarc_restore_device_state(dev_info_t *, hwarc_state_t *); -static int hwarc_cpr_suspend(dev_info_t *); -static void hwarc_cpr_resume(dev_info_t *); -static int hwarc_open_intr_pipe(hwarc_state_t *); -static void hwarc_close_intr_pipe(hwarc_state_t *); -static void hwarc_pm_busy_component(hwarc_state_t *); -static void hwarc_pm_idle_component(hwarc_state_t *); -static int hwarc_power(dev_info_t *, int, int); -static int hwarc_serialize_access(hwarc_state_t *, boolean_t); -static void hwarc_release_access(hwarc_state_t *); -static int hwarc_reset_device(hwarc_state_t *); -static int hwarc_init_phy(hwarc_state_t *); - - -static int hwarc_start_polling(hwarc_state_t *, usb_pipe_handle_t); - - -_NOTE(SCHEME_PROTECTS_DATA("unique per call", usb_ctrl_req)) -_NOTE(SCHEME_PROTECTS_DATA("unique per call", usb_intr_req)) -_NOTE(SCHEME_PROTECTS_DATA("unique per call", buf)) - -/* module loading stuff */ -struct cb_ops hwarc_cb_ops = { - hwarc_open, /* open */ - hwarc_close, /* close */ - nodev, /* strategy */ - nulldev, /* print */ - nulldev, /* dump */ - nodev, /* read */ - nodev, /* write */ - hwarc_ioctl, /* ioctl */ - nulldev, /* devmap */ - nodev, /* mmap */ - nodev, /* segmap */ - nochpoll, /* poll */ - ddi_prop_op, /* cb_prop_op */ - NULL, /* streamtab */ - D_MP -}; - -static struct dev_ops hwarc_ops = { - DEVO_REV, /* devo_rev, */ - 0, /* refcnt */ - hwarc_info, /* info */ - nulldev, /* identify */ - nulldev, /* probe */ - hwarc_attach, /* attach */ - hwarc_detach, /* detach */ - nodev, /* reset */ - &hwarc_cb_ops, /* driver operations */ - NULL, /* bus operations */ - hwarc_power, /* power */ - ddi_quiesce_not_needed, /* devo_quiesce */ -}; - -static struct modldrv hwarc_modldrv = { - &mod_driverops, - "USB HWA Radio Controller driver", - &hwarc_ops -}; - -static struct modlinkage modlinkage = { - MODREV_1, - &hwarc_modldrv, - NULL -}; - -/* Soft state structures */ -#define HWARC_INITIAL_SOFT_SPACE 1 -static void *hwarc_statep; - - -/* Module-wide initialization routine */ -int -_init(void) -{ - int rval; - - if ((rval = ddi_soft_state_init(&hwarc_statep, - sizeof (hwarc_state_t), HWARC_INITIAL_SOFT_SPACE)) != 0) { - - return (rval); - } - - if ((rval = mod_install(&modlinkage)) != 0) { - ddi_soft_state_fini(&hwarc_statep); - } - - return (rval); -} - - -/* Module-wide tear-down routine */ -int -_fini(void) -{ - int rval; - - if ((rval = mod_remove(&modlinkage)) != 0) { - - return (rval); - } - - ddi_soft_state_fini(&hwarc_statep); - - return (rval); -} - - -int -_info(struct modinfo *modinfop) -{ - return (mod_info(&modlinkage, modinfop)); -} - - -/* - * hwarc_info: - * Get minor number, soft state structure, etc. - */ -/*ARGSUSED*/ -static int -hwarc_info(dev_info_t *dip, ddi_info_cmd_t infocmd, - void *arg, void **result) -{ - hwarc_state_t *hrcp; - int error = DDI_FAILURE; - - switch (infocmd) { - case DDI_INFO_DEVT2DEVINFO: - *result = NULL; - if ((hrcp = ddi_get_soft_state(hwarc_statep, - getminor((dev_t)arg))) != NULL) { - *result = hrcp->hrc_dip; - } - error = (*result)? DDI_SUCCESS:DDI_FAILURE; - - break; - case DDI_INFO_DEVT2INSTANCE: - *result = (void *)(uintptr_t)getminor((dev_t)arg); - error = DDI_SUCCESS; - break; - default: - break; - } - - return (error); -} - - - -/* - * hwarc_init_power_mgmt: - * Initialize power management and remote wakeup functionality. - * No mutex is necessary in this function as it's called only by attach. - */ -static void -hwarc_init_power_mgmt(hwarc_state_t *hrcp) -{ - hwarc_power_t *hrcpm = NULL; - uint_t pwr_states; - - USB_DPRINTF_L4(PRINT_MASK_PM, hrcp->hrc_log_hdl, - "init_power_mgmt enter"); - - /* Put online before PM init as can get power managed afterward. */ - hrcp->hrc_dev_state = USB_DEV_ONLINE; - - /* Allocate the state structure */ - hrcpm = kmem_zalloc(sizeof (hwarc_power_t), KM_SLEEP); - - hrcpm->hrc_state = hrcp; - hrcpm->hrc_pm_capabilities = 0; - hrcpm->hrc_current_power = USB_DEV_OS_FULL_PWR; - - - if (usb_create_pm_components(hrcp->hrc_dip, &pwr_states) == - USB_SUCCESS) { - hrcpm->hrc_pwr_states = (uint8_t)pwr_states; - - if (usb_handle_remote_wakeup(hrcp->hrc_dip, - USB_REMOTE_WAKEUP_ENABLE) == USB_SUCCESS) { - hrcpm->hrc_wakeup_enabled = 1; - } else { - USB_DPRINTF_L2(PRINT_MASK_PM, - hrcp->hrc_log_hdl, "hwarc_init_power_mgmt:" - " remote wakeup not supported"); - } - - } else { - USB_DPRINTF_L2(PRINT_MASK_PM, hrcp->hrc_log_hdl, - "hwarc_init_power_mgmt:created PM components failed"); - } - mutex_enter(&hrcp->hrc_mutex); - hrcp->hrc_pm = hrcpm; - hwarc_pm_busy_component(hrcp); - mutex_exit(&hrcp->hrc_mutex); - - (void) pm_raise_power( - hrcp->hrc_dip, 0, USB_DEV_OS_FULL_PWR); - - USB_DPRINTF_L4(PRINT_MASK_PM, hrcp->hrc_log_hdl, - "hwarc_init_power_mgmt: end"); -} - - -/* - * hwarc_destroy_power_mgmt: - * Shut down and destroy power management and remote wakeup functionality. - */ -static void -hwarc_destroy_power_mgmt(hwarc_state_t *hrcp) -{ - hwarc_power_t *pm; - - USB_DPRINTF_L4(PRINT_MASK_PM, hrcp->hrc_log_hdl, - "destroy_power_mgmt enter"); - - mutex_enter(&hrcp->hrc_mutex); - - if ((pm = hrcp->hrc_pm) == NULL) { - USB_DPRINTF_L3(PRINT_MASK_PM, hrcp->hrc_log_hdl, - "hwarc_destroy_power_mgmt:pm not supported"); - goto done; - } - - if (hrcp->hrc_dev_state == USB_DEV_DISCONNECTED) { - USB_DPRINTF_L3(PRINT_MASK_PM, hrcp->hrc_log_hdl, - "hwarc_destroy_power_mgmt:device disconnected"); - goto done; - } - - hwarc_pm_busy_component(hrcp); - - mutex_exit(&hrcp->hrc_mutex); - - if (pm->hrc_wakeup_enabled) { - - /* First bring the device to full power */ - (void) pm_raise_power(hrcp->hrc_dip, 0, USB_DEV_OS_FULL_PWR); - if (usb_handle_remote_wakeup(hrcp->hrc_dip, - USB_REMOTE_WAKEUP_DISABLE) != USB_SUCCESS) { - USB_DPRINTF_L2(PRINT_MASK_PM, - hrcp->hrc_log_hdl, "hwarc_destroy_power_mgmt: " - "Error disabling rmt wakeup"); - } - - } - - /* - * Since remote wakeup is disabled now, - * no one can raise power - * and get to device once power is lowered here. - */ - (void) pm_lower_power(hrcp->hrc_dip, 0, USB_DEV_OS_PWR_OFF); - - mutex_enter(&hrcp->hrc_mutex); - - hwarc_pm_idle_component(hrcp); - -done: - if (pm) { - kmem_free(pm, sizeof (hwarc_power_t)); - - hrcp->hrc_pm = NULL; - } - mutex_exit(&hrcp->hrc_mutex); -} - - -static void -hwarc_pm_busy_component(hwarc_state_t *hrcp) -{ - ASSERT(mutex_owned(&hrcp->hrc_mutex)); - - USB_DPRINTF_L4(PRINT_MASK_PM, hrcp->hrc_log_hdl, - "hwarc_pm_busy_component: enter"); - if (hrcp->hrc_pm == NULL) { - USB_DPRINTF_L4(PRINT_MASK_PM, hrcp->hrc_log_hdl, - "hwarc_pm_busy_component: pm not supported, return"); - - return; - } - - hrcp->hrc_pm->hrc_pm_busy++; - - mutex_exit(&hrcp->hrc_mutex); - if (pm_busy_component(hrcp->hrc_dip, 0) != - DDI_SUCCESS) { - mutex_enter(&hrcp->hrc_mutex); - USB_DPRINTF_L3(PRINT_MASK_PM, hrcp->hrc_log_hdl, - "hwarc_pm_busy_component: pm busy fail, hrc_pm_busy=%d", - hrcp->hrc_pm->hrc_pm_busy); - - hrcp->hrc_pm->hrc_pm_busy--; - mutex_exit(&hrcp->hrc_mutex); - } - mutex_enter(&hrcp->hrc_mutex); - - USB_DPRINTF_L4(PRINT_MASK_PM, hrcp->hrc_log_hdl, - "hwarc_pm_busy_component: exit"); -} - - -static void -hwarc_pm_idle_component(hwarc_state_t *hrcp) -{ - ASSERT(mutex_owned(&hrcp->hrc_mutex)); - USB_DPRINTF_L4(PRINT_MASK_PM, hrcp->hrc_log_hdl, - "hwarc_pm_idle_component: enter"); - - if (hrcp->hrc_pm == NULL) { - USB_DPRINTF_L4(PRINT_MASK_PM, hrcp->hrc_log_hdl, - "hwarc_pm_idle_component: pm not supported"); - - return; - } - - mutex_exit(&hrcp->hrc_mutex); - if (pm_idle_component(hrcp->hrc_dip, 0) == DDI_SUCCESS) { - mutex_enter(&hrcp->hrc_mutex); - ASSERT(hrcp->hrc_pm->hrc_pm_busy > 0); - hrcp->hrc_pm->hrc_pm_busy--; - mutex_exit(&hrcp->hrc_mutex); - } - mutex_enter(&hrcp->hrc_mutex); - - USB_DPRINTF_L3(PRINT_MASK_PM, hrcp->hrc_log_hdl, - "hwarc_pm_idle_component: %d", hrcp->hrc_pm->hrc_pm_busy); - -} - - -/* - * hwarc_pwrlvl0: - * Functions to handle power transition for OS levels 0 -> 3 - */ -static int -hwarc_pwrlvl0(hwarc_state_t *hrcp) -{ - int rval; - - USB_DPRINTF_L3(PRINT_MASK_PM, hrcp->hrc_log_hdl, - "hwarc_pwrlvl0, dev_state: %x", hrcp->hrc_dev_state); - - switch (hrcp->hrc_dev_state) { - case USB_DEV_ONLINE: - /* Deny the powerdown request if the device is busy */ - if (hrcp->hrc_pm->hrc_pm_busy != 0) { - USB_DPRINTF_L2(PRINT_MASK_PM, hrcp->hrc_log_hdl, - "hwarc_pwrlvl0: hrc_pm_busy"); - - return (USB_FAILURE); - } - - /* Close the interrupt pipe */ - mutex_exit(&hrcp->hrc_mutex); - hwarc_close_intr_pipe(hrcp); - mutex_enter(&hrcp->hrc_mutex); - - /* Issue USB D3 command to the device here */ - rval = usb_set_device_pwrlvl3(hrcp->hrc_dip); - ASSERT(rval == USB_SUCCESS); - - hrcp->hrc_dev_state = USB_DEV_PWRED_DOWN; - hrcp->hrc_pm->hrc_current_power = USB_DEV_OS_PWR_OFF; - - /* FALLTHRU */ - case USB_DEV_DISCONNECTED: - case USB_DEV_SUSPENDED: - - return (USB_SUCCESS); - - case USB_DEV_PWRED_DOWN: - default: - USB_DPRINTF_L2(PRINT_MASK_PM, hrcp->hrc_log_hdl, - "hwarc_pwrlvl0: illegal dev state"); - - return (USB_FAILURE); - } -} - - -/* - * hwarc_pwrlvl1: - * Functions to handle power transition to OS levels -> 2 - */ -static int -hwarc_pwrlvl1(hwarc_state_t *hrcp) -{ - int rval; - - USB_DPRINTF_L4(PRINT_MASK_PM, hrcp->hrc_log_hdl, "hwarc_pwrlvl1"); - - /* Issue USB D2 command to the device here */ - rval = usb_set_device_pwrlvl2(hrcp->hrc_dip); - ASSERT(rval == USB_SUCCESS); - - return (USB_FAILURE); -} - - -/* - * hwarc_pwrlvl2: - * Functions to handle power transition to OS levels -> 1 - */ -static int -hwarc_pwrlvl2(hwarc_state_t *hrcp) -{ - int rval; - - USB_DPRINTF_L3(PRINT_MASK_PM, hrcp->hrc_log_hdl, - "hwarc_pwrlvl2, dev_stat=%d", hrcp->hrc_dev_state); - - /* Issue USB D1 command to the device here */ - rval = usb_set_device_pwrlvl1(hrcp->hrc_dip); - ASSERT(rval == USB_SUCCESS); - - return (USB_FAILURE); -} - - -/* - * hwarc_pwrlvl3: - * Functions to handle power transition to OS level -> 0 - */ -static int -hwarc_pwrlvl3(hwarc_state_t *hrcp) -{ - - USB_DPRINTF_L3(PRINT_MASK_PM, hrcp->hrc_log_hdl, - "hwarc_pwrlvl3, dev_stat=%d", hrcp->hrc_dev_state); - - switch (hrcp->hrc_dev_state) { - case USB_DEV_PWRED_DOWN: - /* Issue USB D0 command to the device here */ - (void) usb_set_device_pwrlvl0(hrcp->hrc_dip); - - mutex_exit(&hrcp->hrc_mutex); - if (hwarc_open_intr_pipe(hrcp) != USB_SUCCESS) { - mutex_enter(&hrcp->hrc_mutex); - - return (USB_FAILURE); - } - mutex_enter(&hrcp->hrc_mutex); - - /* Todo: Reset device or not */ - hrcp->hrc_dev_state = USB_DEV_ONLINE; - hrcp->hrc_pm->hrc_current_power = USB_DEV_OS_FULL_PWR; - - /* FALLTHRU */ - case USB_DEV_ONLINE: - /* we are already in full power */ - /* FALLTHRU */ - case USB_DEV_DISCONNECTED: - case USB_DEV_SUSPENDED: - /* - * PM framework tries to put us in full power - * during system shutdown. If we are disconnected/cpr'ed - * return success anyways - */ - - return (USB_SUCCESS); - - default: - USB_DPRINTF_L2(PRINT_MASK_PM, hrcp->hrc_log_hdl, - "hwarc_pwrlvl3: illegal dev state"); - - return (USB_FAILURE); - } -} - -/* Init dev inst */ -static void -hwarc_init_devinst(dev_info_t *dip, hwarc_state_t *hrcp) -{ - char *devinst; - int devinstlen; - - hrcp->hrc_dip = dip; - hrcp->hrc_log_hdl = usb_alloc_log_hdl(dip, - "hwarc", &hwarc_errlevel, - &hwarc_errmask, &hwarc_instance_debug, 0); - - devinst = kmem_zalloc(USB_MAXSTRINGLEN, KM_SLEEP); - devinstlen = snprintf(devinst, USB_MAXSTRINGLEN, "%s%d: ", - ddi_driver_name(dip), ddi_get_instance(dip)); - - hrcp->hrc_devinst = kmem_zalloc(devinstlen + 1, KM_SLEEP); - (void) strncpy(hrcp->hrc_devinst, devinst, devinstlen); - - kmem_free(devinst, USB_MAXSTRINGLEN); -} - -/* init endpoints */ -static int -hwarc_init_ep(dev_info_t *dip, hwarc_state_t *hrcp) -{ - int status = USB_SUCCESS; - usb_ep_data_t *ep_datap; - if ((status = usb_client_attach(dip, USBDRV_VERSION, 0)) != - USB_SUCCESS) { - USB_DPRINTF_L2(PRINT_MASK_ATTA, hrcp->hrc_log_hdl, - "hwarc_init_ep: usb_client_attach failed" - " error code = %d", status); - goto done; - } - - if ((status = usb_get_dev_data(dip, &hrcp->hrc_reg, USB_PARSE_LVL_ALL, - 0)) != USB_SUCCESS) { - USB_DPRINTF_L2(PRINT_MASK_ATTA, hrcp->hrc_log_hdl, - "hwarc_init_ep: usb_get_dev_data failed" - "error code = %d", status); - goto done; - } - hrcp->hrc_if_descr = - &hrcp->hrc_reg->dev_curr_cfg->cfg_if[hrcp->hrc_reg->dev_curr_if]; - hrcp->hrc_default_ph = hrcp->hrc_reg->dev_default_ph; - - /* - * Get the descriptor for an intr pipe at alt 0 of current interface. - * This will be used later to open the pipe. - */ - if ((ep_datap = usb_lookup_ep_data(dip, hrcp->hrc_reg, - hrcp->hrc_reg->dev_curr_if, 0, 0, - USB_EP_ATTR_INTR, USB_EP_DIR_IN)) == NULL) { - USB_DPRINTF_L2(PRINT_MASK_ATTA, hrcp->hrc_log_hdl, - "hwarc_init_ep: Error getting intr endpoint descriptor"); - status = USB_FAILURE; - goto done; - } - hrcp->hrc_intr_ep_descr = ep_datap->ep_descr; - -done: - - return (status); -} -/* init mutex */ -static void -hwarc_init_mutex(hwarc_state_t *hrcp) { - mutex_init(&hrcp->hrc_mutex, NULL, MUTEX_DRIVER, - hrcp->hrc_reg->dev_iblock_cookie); - - cv_init(&hrcp->hrc_serial_cv, NULL, CV_DRIVER, NULL); - hrcp->hrc_serial_inuse = B_FALSE; - - hrcp->hrc_locks_initialized = B_TRUE; -} -/* - * hwarc_attach: - * Attach or resume. - * - * For attach, initialize state and device, including: - * state variables, locks, device node - * device registration with system - * power management, hotplugging - * For resume, restore device and state - */ -static int -hwarc_attach(dev_info_t *dip, ddi_attach_cmd_t cmd) -{ - int instance = ddi_get_instance(dip); - hwarc_state_t *hrcp = NULL; - - switch (cmd) { - case DDI_ATTACH: - break; - - case DDI_RESUME: - hwarc_cpr_resume(dip); - /* - * Always return success to work around enumeration - * failures.This works around an issue where devices - * which are present before a suspend and absent upon - * resume could cause a system panic on resume. - */ - - return (DDI_SUCCESS); - default: - return (DDI_FAILURE); - } - - if (ddi_soft_state_zalloc(hwarc_statep, instance) == DDI_SUCCESS) { - hrcp = ddi_get_soft_state(hwarc_statep, instance); - } - if (hrcp == NULL) { - USB_DPRINTF_L2(PRINT_MASK_ATTA, NULL, - "hwarc_attach: get soft state failed for instance %d", - instance); - - return (DDI_FAILURE); - } - - (void) hwarc_init_devinst(dip, hrcp); - - if (hwarc_init_ep(dip, hrcp) != USB_SUCCESS) { - USB_DPRINTF_L2(PRINT_MASK_ATTA, hrcp->hrc_log_hdl, - "attach: Error init usb data"); - goto fail; - } - hwarc_init_mutex(hrcp); - - /* create minor node */ - if (ddi_create_minor_node(dip, name, S_IFCHR, instance, - NULL, 0) != DDI_SUCCESS) { - USB_DPRINTF_L2(PRINT_MASK_ATTA, hrcp->hrc_log_hdl, - "attach: Error creating minor node"); - goto fail; - } - - /* initialize power management */ - hwarc_init_power_mgmt(hrcp); - - if (usb_register_hotplug_cbs(dip, hwarc_disconnect_callback, - hwarc_reconnect_callback) != USB_SUCCESS) { - USB_DPRINTF_L2(PRINT_MASK_ATTA, hrcp->hrc_log_hdl, - "attach: Error register hotplug cbs"); - - goto fail; - } - - /* register this device to uwba */ - uwb_dev_attach(dip, &hrcp->hrc_dev_hdl, 0, hwarc_send_cmd); - - if (hwarc_open_intr_pipe(hrcp) != USB_SUCCESS) { - USB_DPRINTF_L2(PRINT_MASK_ATTA, hrcp->hrc_log_hdl, - "attach: Error open intr pipe"); - - goto fail; - } - - /* reset device */ - if (hwarc_reset_device(hrcp) != USB_SUCCESS) { - USB_DPRINTF_L2(PRINT_MASK_ATTA, hrcp->hrc_log_hdl, - "attach: Error reset deivce"); - goto fail; - } - /* init phy capabilities */ - if (hwarc_init_phy(hrcp) != USB_SUCCESS) { - USB_DPRINTF_L2(PRINT_MASK_ATTA, hrcp->hrc_log_hdl, - "attach: Error get phy ie"); - - goto fail; - } - /* Report device */ - ddi_report_dev(dip); - - mutex_enter(&hrcp->hrc_mutex); - hwarc_pm_idle_component(hrcp); - mutex_exit(&hrcp->hrc_mutex); - - return (DDI_SUCCESS); - -fail: - (void) hwarc_cleanup(dip, hrcp); - - return (DDI_FAILURE); -} - - -/* - * hwarc_detach: - * detach or suspend driver instance - * - * Note: in detach, only contention threads is from pm and disconnnect. - */ -static int -hwarc_detach(dev_info_t *dip, ddi_detach_cmd_t cmd) -{ - int rval = USB_SUCCESS; - hwarc_state_t *hrcp = - ddi_get_soft_state(hwarc_statep, ddi_get_instance(dip)); - - USB_DPRINTF_L3(PRINT_MASK_ATTA, hrcp->hrc_log_hdl, - "hwarc_detach: enter for detach, cmd = %d", cmd); - - - switch (cmd) { - case DDI_DETACH: - - rval = hwarc_cleanup(dip, hrcp); - - break; - case DDI_SUSPEND: - - rval = hwarc_cpr_suspend(dip); - default: - - break; - } - - return ((rval == USB_SUCCESS) ? DDI_SUCCESS : DDI_FAILURE); -} - - -/* - * hwarc_cleanup: - * clean up the driver state for detach - */ -static int -hwarc_cleanup(dev_info_t *dip, hwarc_state_t *hrcp) -{ - USB_DPRINTF_L2(PRINT_MASK_ATTA, hrcp->hrc_log_hdl, "Cleanup: enter"); - - if (hrcp->hrc_locks_initialized) { - - (void) uwb_stop_beacon(dip); - /* This must be done 1st to prevent more events from coming. */ - usb_unregister_hotplug_cbs(dip); - - hwarc_close_intr_pipe(hrcp); - - /* - * At this point, no new activity can be initiated. The driver - * has disabled hotplug callbacks. The Solaris framework has - * disabled new opens on a device being detached, and does not - * allow detaching an open device. - * - * The following ensures that all driver activity has drained. - */ - mutex_enter(&hrcp->hrc_mutex); - (void) hwarc_serialize_access(hrcp, HWARC_SER_NOSIG); - hwarc_release_access(hrcp); - mutex_exit(&hrcp->hrc_mutex); - - /* All device activity has died down. */ - hwarc_destroy_power_mgmt(hrcp); - - /* start dismantling */ - ddi_remove_minor_node(dip, NULL); - cv_destroy(&hrcp->hrc_serial_cv); - mutex_destroy(&hrcp->hrc_mutex); - } - - usb_client_detach(dip, hrcp->hrc_reg); - - USB_DPRINTF_L4(PRINT_MASK_ATTA, hrcp->hrc_log_hdl, "Cleanup: end"); - - usb_free_log_hdl(hrcp->hrc_log_hdl); - - uwb_dev_detach(hrcp->hrc_dev_hdl); - - kmem_free(hrcp->hrc_devinst, strlen(hrcp->hrc_devinst) + 1); - - ddi_soft_state_free(hwarc_statep, ddi_get_instance(dip)); - ddi_prop_remove_all(dip); - - return (USB_SUCCESS); -} - - - -/*ARGSUSED*/ -static int -hwarc_open(dev_t *devp, int flag, int otyp, cred_t *cred_p) -{ - hwarc_state_t *hrcp = NULL; - int rval = 0; - - hrcp = ddi_get_soft_state(hwarc_statep, getminor(*devp)); - - ASSERT(hrcp != NULL); - - USB_DPRINTF_L4(PRINT_MASK_OPEN, hrcp->hrc_log_hdl, "hwarc_open: enter"); - - /* - * Keep it simple: one client at a time. - * Exclusive open only - */ - mutex_enter(&hrcp->hrc_mutex); - /* exclusive open */ - if ((flag & FEXCL) && (hrcp->hrc_open_count > 0)) { - USB_DPRINTF_L2(PRINT_MASK_OPEN, hrcp->hrc_log_hdl, - "hwarc_open failed, open count=%d", hrcp->hrc_open_count); - mutex_exit(&hrcp->hrc_mutex); - - return (EBUSY); - } - - if ((hrcp->hrc_dev_state == USB_DEV_DISCONNECTED) || - (hrcp->hrc_dev_state == USB_DEV_SUSPENDED)) { - - USB_DPRINTF_L2(PRINT_MASK_OPEN, hrcp->hrc_log_hdl, - "hwarc_open failed, dev_stat=%d", hrcp->hrc_dev_state); - mutex_exit(&hrcp->hrc_mutex); - - return (EIO); - } - - hrcp->hrc_open_count++; - - USB_DPRINTF_L3(PRINT_MASK_OPEN, hrcp->hrc_log_hdl, - "hwarc_open, open count=%d", hrcp->hrc_open_count); - if (hwarc_serialize_access(hrcp, HWARC_SER_SIG) == 0) { - hrcp->hrc_open_count--; - hwarc_release_access(hrcp); - mutex_exit(&hrcp->hrc_mutex); - - return (EINTR); - } - - hwarc_pm_busy_component(hrcp); - - mutex_exit(&hrcp->hrc_mutex); - (void) pm_raise_power(hrcp->hrc_dip, 0, USB_DEV_OS_FULL_PWR); - - mutex_enter(&hrcp->hrc_mutex); - /* Fail if device is no longer ready. */ - if (hrcp->hrc_dev_state != USB_DEV_ONLINE) { - USB_DPRINTF_L2(PRINT_MASK_OPEN, hrcp->hrc_log_hdl, - "hwarc_open failed, dev_stat=%d", hrcp->hrc_dev_state); - rval = EIO; - } - hwarc_release_access(hrcp); - /* Device specific initialization goes here. */ - if (rval != 0) { - hrcp->hrc_open_count--; - hwarc_pm_idle_component(hrcp); - } - mutex_exit(&hrcp->hrc_mutex); - - USB_DPRINTF_L4(PRINT_MASK_OPEN, hrcp->hrc_log_hdl, "hwarc_open: leave"); - - return (0); -} - - -/*ARGSUSED*/ -static int -hwarc_close(dev_t dev, int flag, int otyp, cred_t *cred_p) -{ - hwarc_state_t *hrcp = - ddi_get_soft_state(hwarc_statep, getminor(dev)); - - USB_DPRINTF_L4(PRINT_MASK_CLOSE, hrcp->hrc_log_hdl, - "hwarc_close: enter"); - - mutex_enter(&hrcp->hrc_mutex); - (void) hwarc_serialize_access(hrcp, HWARC_SER_NOSIG); - - hrcp->hrc_open_count--; - USB_DPRINTF_L3(PRINT_MASK_CLOSE, hrcp->hrc_log_hdl, - "hwarc_close: open count=%d", hrcp->hrc_open_count); - - hwarc_release_access(hrcp); - hwarc_pm_idle_component(hrcp); - - mutex_exit(&hrcp->hrc_mutex); - - USB_DPRINTF_L4(PRINT_MASK_CLOSE, hrcp->hrc_log_hdl, - "hwarc_close: leave"); - - return (0); -} - -/* Send cmd to hwarc device */ -int -hwarc_send_cmd(uwb_dev_handle_t uwb_dev_hdl, mblk_t *data, uint16_t data_len) -{ - usb_cb_flags_t cb_flags; - usb_cr_t cr; - usb_ctrl_setup_t setup; - int rval; - hwarc_state_t *hrcp = NULL; - dev_info_t *dip = uwb_get_dip(uwb_dev_hdl); - - hrcp = ddi_get_soft_state(hwarc_statep, ddi_get_instance(dip)); - - ASSERT((hrcp != NULL) && (data != NULL)); - - setup.bmRequestType = HWARC_SET_IF; - setup.bRequest = HWA_EXEC_RC_CMD; - - setup.wValue = 0; - setup.wIndex = hrcp->hrc_if_descr->if_alt->altif_descr.bInterfaceNumber; - - setup.wLength = data_len; - setup.attrs = 0; - - USB_DPRINTF_L3(PRINT_MASK_DEVCTRL, hrcp->hrc_log_hdl, - "hwarc_send_cmd: wLength=%d, data[0], [1], [2], [3]=%d, %d, %d, %d", - setup.wLength, data->b_rptr[0], data->b_rptr[1], data->b_rptr[2], - data->b_rptr[3]); - - if ((rval = usb_pipe_ctrl_xfer_wait(hrcp->hrc_default_ph, &setup, - &data, &cr, &cb_flags, 0)) != USB_SUCCESS) { - USB_DPRINTF_L2(PRINT_MASK_DEVCTRL, hrcp->hrc_log_hdl, - "hwarc_send_cmd: fail, rval=%d, cr=%d, " - "cb_flags=%x", rval, cr, cb_flags); - - } - - freemsg(data); - - return (rval); -} - -/* ioctl, call uwb ioctl */ -/*ARGSUSED*/ -static int -hwarc_ioctl(dev_t dev, int cmd, intptr_t arg, - int mode, cred_t *cred_p, int *rval_p) -{ - int rv = 0; - - hwarc_state_t *hrcp = - ddi_get_soft_state(hwarc_statep, getminor(dev)); - if (hrcp == NULL) { - - return (ENXIO); - } - - if (drv_priv(cred_p) != 0) { - USB_DPRINTF_L3(PRINT_MASK_ALL, hrcp->hrc_log_hdl, - "hwahc_wusb_ioctl: user must have SYS_DEVICE privilege," - "cmd=%x", cmd); - - return (EPERM); - } - - - - USB_DPRINTF_L4(PRINT_MASK_ALL, hrcp->hrc_log_hdl, "hwarc_ioctl: enter"); - - mutex_enter(&hrcp->hrc_mutex); - if (hrcp->hrc_dev_state != USB_DEV_ONLINE) { - USB_DPRINTF_L2(PRINT_MASK_ALL, hrcp->hrc_log_hdl, - "ioctl: Device is not online," - " dev_stat=%d", hrcp->hrc_dev_state); - mutex_exit(&hrcp->hrc_mutex); - - return (EFAULT); - } - mutex_exit(&hrcp->hrc_mutex); - - rv = uwb_do_ioctl(hrcp->hrc_dev_hdl, cmd, arg, mode); - - return (rv); -} - - -/* - * hwarc_disconnect_callback: - * Called when device hotplug-removed. - * Close pipes. (This does not attempt to contact device.) - * Set state to DISCONNECTED - */ -static int -hwarc_disconnect_callback(dev_info_t *dip) -{ - hwarc_state_t *hrcp = - ddi_get_soft_state(hwarc_statep, ddi_get_instance(dip)); - - USB_DPRINTF_L4(PRINT_MASK_CB, hrcp->hrc_log_hdl, "disconnect: enter"); - - /* Disconnect the uwb device will stop beacon and save state */ - (void) uwb_dev_disconnect(dip); - hwarc_close_intr_pipe(hrcp); - - mutex_enter(&hrcp->hrc_mutex); - (void) hwarc_serialize_access(hrcp, HWARC_SER_NOSIG); - - /* - * Save any state of device or IO in progress required by - * hwarc_restore_device_state for proper device "thawing" later. - */ - hrcp->hrc_dev_state = USB_DEV_DISCONNECTED; - - hwarc_release_access(hrcp); - mutex_exit(&hrcp->hrc_mutex); - - return (USB_SUCCESS); -} - - -/* - * hwarc_reconnect_callback: - * Called with device hotplug-inserted - * Restore state - */ -static int -hwarc_reconnect_callback(dev_info_t *dip) -{ - int instance = ddi_get_instance(dip); - hwarc_state_t *hrcp = - ddi_get_soft_state(hwarc_statep, instance); - - USB_DPRINTF_L4(PRINT_MASK_CB, hrcp->hrc_log_hdl, "reconnect: enter"); - - mutex_enter(&hrcp->hrc_mutex); - (void) hwarc_serialize_access(hrcp, HWARC_SER_NOSIG); - hwarc_restore_device_state(dip, hrcp); - hwarc_release_access(hrcp); - mutex_exit(&hrcp->hrc_mutex); - - /* Reconnect the uwb device will restore uwb device state */ - (void) uwb_dev_reconnect(dip); - return (USB_SUCCESS); -} - - -/* - * hwarc_restore_device_state: - * Called during hotplug-reconnect and resume. - * reenable power management - * Verify the device is the same as before the disconnect/suspend. - * Restore device state - * Thaw any IO which was frozen. - * Quiesce device. (Other routines will activate if thawed IO.) - * Set device online. - * Leave device disconnected if there are problems. - */ -static void -hwarc_restore_device_state(dev_info_t *dip, hwarc_state_t *hrcp) -{ - - USB_DPRINTF_L4(PRINT_MASK_ATTA, hrcp->hrc_log_hdl, - "hwarc_restore_device_state: enter"); - - ASSERT(mutex_owned(&hrcp->hrc_mutex)); - - ASSERT((hrcp->hrc_dev_state == USB_DEV_DISCONNECTED) || - (hrcp->hrc_dev_state == USB_DEV_SUSPENDED)); - - hwarc_pm_busy_component(hrcp); - - mutex_exit(&hrcp->hrc_mutex); - - (void) pm_raise_power(hrcp->hrc_dip, 0, USB_DEV_OS_FULL_PWR); - - if (usb_check_same_device(dip, hrcp->hrc_log_hdl, USB_LOG_L2, - PRINT_MASK_ALL, USB_CHK_BASIC|USB_CHK_CFG, NULL) != USB_SUCCESS) { - USB_DPRINTF_L2(PRINT_MASK_ATTA, hrcp->hrc_log_hdl, - "hwarc_restore_device_state: check same device failed"); - - goto fail; - - } - if (hwarc_open_intr_pipe(hrcp) != USB_SUCCESS) { - - goto fail; - } - mutex_enter(&hrcp->hrc_mutex); - - hrcp->hrc_dev_state = USB_DEV_ONLINE; - - if (hrcp->hrc_pm && hrcp->hrc_pm->hrc_wakeup_enabled) { - - mutex_exit(&hrcp->hrc_mutex); - if (usb_handle_remote_wakeup(dip, USB_REMOTE_WAKEUP_ENABLE) != - USB_SUCCESS) { - USB_DPRINTF_L2(PRINT_MASK_ATTA, hrcp->hrc_log_hdl, - "hwarc_restore_device_state: " - "fail to enable device remote wakeup"); - } - mutex_enter(&hrcp->hrc_mutex); - - } - - hwarc_pm_idle_component(hrcp); - - USB_DPRINTF_L3(PRINT_MASK_ATTA, hrcp->hrc_log_hdl, - "hwarc_restore_device_state: end"); - - return; - -fail: - /* change the device state from suspended to disconnected */ - mutex_enter(&hrcp->hrc_mutex); - hrcp->hrc_dev_state = USB_DEV_DISCONNECTED; - hwarc_pm_idle_component(hrcp); -} - - -/* - * hwarc_cpr_suspend: - * Clean up device. - * Wait for any IO to finish, then close pipes. - * Quiesce device. - */ -static int -hwarc_cpr_suspend(dev_info_t *dip) -{ - hwarc_state_t *hrcp = ddi_get_soft_state(hwarc_statep, - ddi_get_instance(dip)); - - USB_DPRINTF_L3(PRINT_MASK_PM, hrcp->hrc_log_hdl, - "hwarc_cpr_suspend, dev_stat=%d", hrcp->hrc_dev_state); - - /* Disconnect the uwb device will stop beacon and save state */ - (void) uwb_dev_disconnect(dip); - - /* Serialize to prevent races with detach, open, device access. */ - mutex_enter(&hrcp->hrc_mutex); - (void) hwarc_serialize_access(hrcp, HWARC_SER_NOSIG); - - hwarc_pm_busy_component(hrcp); - - /* - * Set dev_state to suspended so other driver threads don't start any - * new I/O. In a real driver, there may be draining of requests done - * afterwards, and we don't want the draining to compete with new - * requests being queued. - */ - - /* Don't suspend if the device is open. */ - if (hrcp->hrc_open_count != 0) { - USB_DPRINTF_L3(PRINT_MASK_PM, hrcp->hrc_log_hdl, - "suspend: Device is open. Can't suspend"); - - hwarc_release_access(hrcp); - hwarc_pm_idle_component(hrcp); - mutex_exit(&hrcp->hrc_mutex); - - return (USB_FAILURE); - } - - /* Access device here to clean it up. */ - mutex_exit(&hrcp->hrc_mutex); - hwarc_close_intr_pipe(hrcp); - mutex_enter(&hrcp->hrc_mutex); - - hrcp->hrc_dev_state = USB_DEV_SUSPENDED; - - /* - * Save any state of device required by hwarc_restore_device_state - * for proper device "thawing" later. - */ - hwarc_release_access(hrcp); - hwarc_pm_idle_component(hrcp); - mutex_exit(&hrcp->hrc_mutex); - - USB_DPRINTF_L3(PRINT_MASK_PM, hrcp->hrc_log_hdl, "suspend: success"); - - return (USB_SUCCESS); -} - - -/* - * hwarc_cpr_resume: - * - * hwarc_restore_device_state marks success by putting device back online - */ -static void -hwarc_cpr_resume(dev_info_t *dip) -{ - int instance = ddi_get_instance(dip); - hwarc_state_t *hrcp = ddi_get_soft_state(hwarc_statep, - instance); - - USB_DPRINTF_L3(PRINT_MASK_PM, hrcp->hrc_log_hdl, - "hwarc_cpr_resume, dev_stat=%d", hrcp->hrc_dev_state); - - /* - * NOTE: A pm_raise_power in hwarc_restore_device_state will bring - * the power-up state of device into synch with the system. - */ - mutex_enter(&hrcp->hrc_mutex); - hwarc_restore_device_state(dip, hrcp); - mutex_exit(&hrcp->hrc_mutex); - - /* Reconnect the uwb device will restore uwb device state */ - (void) uwb_dev_reconnect(dip); -} - -/* - * pipe callbacks - * -------------- - * - * intr in callback for event receiving for hwarc device - */ -/*ARGSUSED*/ -void -hwarc_intr_cb(usb_pipe_handle_t pipe, usb_intr_req_t *req) -{ - hwarc_state_t *hrcp = (hwarc_state_t *)req->intr_client_private; - uwb_dev_handle_t uwb_dev_hd; - mblk_t *data = req->intr_data; - int data_len, parse_err; - - uwb_dev_hd = hrcp->hrc_dev_hdl; - data_len = (data) ? MBLKL(data) : 0; - - if (data_len == 0) { - - return; - } - - /* - * Parse the event/notifications from the device, and cv_signal the - * waiting cmd - */ - parse_err = uwb_parse_evt_notif((uint8_t *)data->b_rptr, - data_len, uwb_dev_hd); - if (parse_err != UWB_SUCCESS) { - USB_DPRINTF_L2(PRINT_MASK_CB, hrcp->hrc_log_hdl, - "hwarc_intr_cb: parse failed, no cmd result or " - "notifs delivered. parse_err= %d", parse_err); - if (data_len >= 5) { - USB_DPRINTF_L2(PRINT_MASK_CB, hrcp->hrc_log_hdl, - "hwarc_intr_cb: erro evt len=%d" - " evtcode=%d %d,evt_context=%d, result-code=%d", - data_len, data->b_rptr[1], data->b_rptr[2], - data->b_rptr[3], data->b_rptr[4]); - } - } - - usb_free_intr_req(req); -} - -/* - * pipe callbacks - * -------------- - * - * intr in exception callback - */ -void -hwarc_intr_ex_cb(usb_pipe_handle_t pipe, usb_intr_req_t *req) -{ - hwarc_state_t *hrcp = (hwarc_state_t *)req->intr_client_private; - usb_cr_t cr = req->intr_completion_reason; - - USB_DPRINTF_L4(PRINT_MASK_CB, hrcp->hrc_log_hdl, - "hwarc_intr_ex_cb: ph = 0x%p req = 0x%p cr=%d flags=%x", - (void *)pipe, (void *)req, cr, req->intr_cb_flags); - - usb_free_intr_req(req); - - /* restart polling */ - if ((cr != USB_CR_PIPE_CLOSING) && (cr != USB_CR_STOPPED_POLLING) && - (cr != USB_CR_FLUSHED) && (cr != USB_CR_DEV_NOT_RESP) && - (cr != USB_CR_PIPE_RESET) && - (hrcp->hrc_dev_state == USB_DEV_ONLINE)) { - if (hwarc_start_polling(hrcp, hrcp->hrc_intr_ph) != - USB_SUCCESS) { - USB_DPRINTF_L2(PRINT_MASK_CB, hrcp->hrc_log_hdl, - "hwarc_intr_ex_cb:" - "Restart pollling failed."); - } - } else { - USB_DPRINTF_L2(PRINT_MASK_CB, hrcp->hrc_log_hdl, - "hwarc_intr_ex_cb:" - "get events failed: cr=%d", cr); - } -} - -/* - * start polling on the interrupt pipe for events - */ -int -hwarc_start_polling(hwarc_state_t *hrcp, usb_pipe_handle_t intr_ph) -{ - usb_intr_req_t *br; - int rval = USB_SUCCESS; - - USB_DPRINTF_L3(PRINT_MASK_OPEN, hrcp->hrc_log_hdl, - "hwarc_start_polling"); - - br = usb_alloc_intr_req(hrcp->hrc_dip, 0, USB_FLAGS_SLEEP); - - if (!br) { - USB_DPRINTF_L2(PRINT_MASK_OPEN, hrcp->hrc_log_hdl, - "hwarc_start_polling: alloc req failed."); - - return (USB_FAILURE); - } - br->intr_attributes = USB_ATTRS_SHORT_XFER_OK | USB_ATTRS_AUTOCLEARING; - br->intr_len = hrcp->hrc_intr_ep_descr.wMaxPacketSize; - br->intr_client_private = (void *)hrcp; - - br->intr_cb = hwarc_intr_cb; - br->intr_exc_cb = hwarc_intr_ex_cb; - - rval = usb_pipe_intr_xfer(intr_ph, br, USB_FLAGS_SLEEP); - - if (rval != USB_SUCCESS) { - usb_free_intr_req(br); - - USB_DPRINTF_L2(PRINT_MASK_OPEN, hrcp->hrc_log_hdl, - "hwarc_start_polling: failed (%d)", rval); - } - - return (rval); -} - -/* - * hwarc_open_intr_pipe: - * Open any pipes other than default pipe. - * Mutex is assumed to be held. - */ -static int -hwarc_open_intr_pipe(hwarc_state_t *hrcp) -{ - - int rval = USB_SUCCESS; - usb_pipe_policy_t pipe_policy; - usb_pipe_handle_t pipe_handle; - - USB_DPRINTF_L3(PRINT_MASK_ATTA, hrcp->hrc_log_hdl, "open_pipes enter"); - - bzero(&pipe_policy, sizeof (pipe_policy)); - - /* - * Allow that pipes can support at least two asynchronous operations - * going on simultaneously. Operations include asynchronous callbacks, - * resets, closures. - */ - pipe_policy.pp_max_async_reqs = 2; - - if ((rval = usb_pipe_open(hrcp->hrc_dip, - &hrcp->hrc_intr_ep_descr, &pipe_policy, - USB_FLAGS_SLEEP, &pipe_handle)) != USB_SUCCESS) { - USB_DPRINTF_L2(PRINT_MASK_ATTA, hrcp->hrc_log_hdl, - "hwarc_open_intr_pipe:Error opening intr pipe: status = %d", - rval); - goto done; - } - - mutex_enter(&hrcp->hrc_mutex); - hrcp->hrc_intr_ph = pipe_handle; - mutex_exit(&hrcp->hrc_mutex); - - /* - * At this point, polling could be started on the pipe by making an - * asynchronous input request on the pipe. Allocate a request by - * calling usb_alloc_intr_req(9F) with a zero length, initialize - * attributes with USB_ATTRS_SHORT_XFER_OK | USB_ATTRS_AUTOCLEARING, - * initialize length to be packetsize of the endpoint, specify the - * callbacks. Pass this request to usb_pipe_intr_xfer to start polling. - * Call usb_pipe_stop_intr_poling(9F) to stop polling. - */ - rval = hwarc_start_polling(hrcp, hrcp->hrc_intr_ph); - if (rval != USB_SUCCESS) { - hwarc_close_intr_pipe(hrcp); - - USB_DPRINTF_L3(PRINT_MASK_ATTA, hrcp->hrc_log_hdl, - "hwarc_open_intr_pipe: Error start " - "polling intr pipe: rval = %d", rval); - } - -done: - - return (rval); -} - - -/* - * hwarc_close_intr_pipe: - * Close pipes. Mutex is assumed to be held. - */ -static void -hwarc_close_intr_pipe(hwarc_state_t *hrcp) -{ - usb_pipe_handle_t pipe_handle = NULL; - USB_DPRINTF_L3(PRINT_MASK_ATTA, hrcp->hrc_log_hdl, "close_pipes enter"); - - mutex_enter(&hrcp->hrc_mutex); - if (!hrcp->hrc_intr_ph) { - USB_DPRINTF_L2(PRINT_MASK_ATTA, hrcp->hrc_log_hdl, - "hwarc intr pipe not exist"); - mutex_exit(&hrcp->hrc_mutex); - return; - } - - pipe_handle = hrcp->hrc_intr_ph; - hrcp->hrc_intr_ph = NULL; - mutex_exit(&hrcp->hrc_mutex); - - /* Stop polling */ - usb_pipe_stop_intr_polling(pipe_handle, USB_FLAGS_SLEEP); - - /* Close Pipe */ - usb_pipe_close(hrcp->hrc_dip, pipe_handle, USB_FLAGS_SLEEP, NULL, 0); -} - -/* - * hwarc_power : - * Power entry point, the workhorse behind pm_raise_power, pm_lower_power, - * usb_req_raise_power and usb_req_lower_power. - */ -/*ARGSUSED*/ -static int -hwarc_power(dev_info_t *dip, int comp, int level) -{ - hwarc_state_t *hrcp; - int rval = USB_FAILURE; - - hrcp = ddi_get_soft_state(hwarc_statep, ddi_get_instance(dip)); - - USB_DPRINTF_L3(PRINT_MASK_PM, hrcp->hrc_log_hdl, - "hwarc_power: level = %d", level); - - mutex_enter(&hrcp->hrc_mutex); - - ASSERT(hrcp->hrc_pm != NULL); - - (void) hwarc_serialize_access(hrcp, HWARC_SER_NOSIG); - - /* - * If we are disconnected/suspended, return success. Note that if we - * return failure, bringing down the system will hang when - * PM tries to power up all devices - */ - if ((hrcp->hrc_dev_state == USB_DEV_DISCONNECTED) || - (hrcp->hrc_dev_state == USB_DEV_SUSPENDED)) { - - USB_DPRINTF_L3(PRINT_MASK_PM, hrcp->hrc_log_hdl, - "hwarc_power: disconnected/suspended " - "dev_state=%d", hrcp->hrc_dev_state); - rval = USB_SUCCESS; - - goto done; - } - - - /* Check if we are transitioning to a legal power level */ - if (USB_DEV_PWRSTATE_OK(hrcp->hrc_pm->hrc_pwr_states, level)) { - USB_DPRINTF_L2(PRINT_MASK_PM, hrcp->hrc_log_hdl, - "hwarc_power: illegal power level = %d " - "pwr_states: %x", level, hrcp->hrc_pm->hrc_pwr_states); - - goto done; - } - - switch (level) { - case USB_DEV_OS_PWR_OFF : - rval = hwarc_pwrlvl0(hrcp); - - break; - case USB_DEV_OS_PWR_1: - rval = hwarc_pwrlvl1(hrcp); - - break; - case USB_DEV_OS_PWR_2: - rval = hwarc_pwrlvl2(hrcp); - - break; - case USB_DEV_OS_FULL_PWR : - rval = hwarc_pwrlvl3(hrcp); - - break; - } - -done: - hwarc_release_access(hrcp); - mutex_exit(&hrcp->hrc_mutex); - - return ((rval == USB_SUCCESS) ? DDI_SUCCESS : DDI_FAILURE); -} - - -/* - * hwarc_serialize_access: - * Get the serial synchronization object before returning. - * - * Arguments: - * hrcp - Pointer to hwarc state structure - * waitsig - Set to: - * HWARC_SER_SIG - to wait such that a signal can interrupt - * HWARC_SER_NOSIG - to wait such that a signal cannot interrupt - */ -static int -hwarc_serialize_access(hwarc_state_t *hrcp, boolean_t waitsig) -{ - int rval = 1; - - ASSERT(mutex_owned(&hrcp->hrc_mutex)); - - while (hrcp->hrc_serial_inuse) { - if (waitsig == HWARC_SER_SIG) { - rval = cv_wait_sig(&hrcp->hrc_serial_cv, - &hrcp->hrc_mutex); - } else { - cv_wait(&hrcp->hrc_serial_cv, - &hrcp->hrc_mutex); - } - } - hrcp->hrc_serial_inuse = B_TRUE; - - return (rval); -} - - -/* - * hwarc_release_access: - * Release the serial synchronization object. - */ -static void -hwarc_release_access(hwarc_state_t *hrcp) -{ - ASSERT(mutex_owned(&hrcp->hrc_mutex)); - hrcp->hrc_serial_inuse = B_FALSE; - cv_broadcast(&hrcp->hrc_serial_cv); -} - - -/* - * hwarc_reset_device: - * Reset the readio controller with uwb interfaces. - * if the device is different. Can block. - */ -static int -hwarc_reset_device(hwarc_state_t *hrcp) -{ - if (uwb_reset_dev(hrcp->hrc_dip) != UWB_SUCCESS) { - USB_DPRINTF_L2(PRINT_MASK_ATTA, hrcp->hrc_log_hdl, - "hwarc_reset_device: uwb_reset_dev failed"); - - return (USB_FAILURE); - } - - return (USB_SUCCESS); -} - -/* - * hwarc_init_phy - * init the physical capabilities of the radio controller. - * the band groups and phy rates will be initialized in the - * uwb devices. - */ -static int -hwarc_init_phy(hwarc_state_t *hrcp) -{ - if (uwb_init_phy(hrcp->hrc_dip) != UWB_SUCCESS) { - USB_DPRINTF_L2(PRINT_MASK_ATTA, hrcp->hrc_log_hdl, - "hwarc_init_phy: uwb_init_phy failed"); - - return (USB_FAILURE); - } - - return (USB_SUCCESS); -} diff --git a/usr/src/uts/common/io/usb/clients/wusb_ca/wusb_ca.c b/usr/src/uts/common/io/usb/clients/wusb_ca/wusb_ca.c deleted file mode 100644 index 92f9acdc35..0000000000 --- a/usr/src/uts/common/io/usb/clients/wusb_ca/wusb_ca.c +++ /dev/null @@ -1,1806 +0,0 @@ -/* - * 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 - * or http://www.opensolaris.org/os/licensing. - * 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. - */ - -/* - * WUSB cable association driver - * - * This driver implements the cable association mechanism defined in - * "Association Models Supplement to the Certified Wireless Universal - * Serial Bus Specification 1.0". Cable association compliant devices, - * i.e. with bInterfaceClass=0xEF, bInterfaceSubClass=0x03 and - * bInterfaceProtocol=0x01(compatible names: "usbif,classef.3.1") will - * be supported by this driver. - * - * The Cable Association Model uses the USB Cable-Based Association - * Framework (CBAF). The basic operation under this framework is: - * - * - The user connects the device to the host using a USB cable. - * - * - The host detects that the device supports the CBAF and it is capable - * of configuring WUSB CC(Connection Context). - * - * - The host sends its CHID to the device, along with other information - * - * - If the device has a valid CC with a matching CHID, the device will - * respond to the host with the CDID from the CC. - * - * - As of this driver implementation, no matter if the CDID returned - * from the device matches the CDID in the host's copy of CC, we choose - * to skip further explicit user conditioning, generate a new CC and send - * it to the device. - * - * - Upon receiving the CC, the device must store the CC in non-volatile - * memory, replacing any existing CC with a matching CHID if it exists. - * - * - First time association is complete: Host has securely transferred the CC - * to the device - * - * CBAF requires device to use the default control endpoint to exchange - * requests and data with host. Three control requests are defined by spec - * and supported by this driver: - * - GET_ASSOCIATION_INFORMATION - * - GET_ASSOCIATION_REQUEST - * - SET_ASSOCIATION_RESPONSE - * - */ - -#if defined(lint) && !defined(DEBUG) -#define DEBUG -#endif - -#define USBDRV_MAJOR_VER 2 -#define USBDRV_MINOR_VER 0 - -#include <sys/usb/usba.h> -#include <sys/stream.h> -#include <sys/strsun.h> -#include <sys/usb/clients/wusb_ca/wusb_ca_priv.h> -#include <sys/usb/clients/wusb_ca/wusb_ca.h> - - -uint_t wusb_ca_errlevel = USB_LOG_L4; -uint_t wusb_ca_errmask = (uint_t)PRINT_MASK_ALL; -uint_t wusb_ca_instance_debug = (uint_t)-1; - -/* - * Function Prototypes - */ -static int wusb_ca_attach(dev_info_t *, ddi_attach_cmd_t); -static int wusb_ca_detach(dev_info_t *, ddi_detach_cmd_t); -static int wusb_ca_info(dev_info_t *, ddi_info_cmd_t, void *, void **); -static int wusb_ca_cleanup(dev_info_t *, wusb_ca_state_t *); -static int wusb_ca_open(dev_t *, int, int, cred_t *); -static int wusb_ca_close(dev_t, int, int, cred_t *); -static int wusb_ca_ioctl(dev_t, int, intptr_t, int, cred_t *, int *); -static int wusb_ca_disconnect_callback(dev_info_t *); -static int wusb_ca_reconnect_callback(dev_info_t *); -static void wusb_ca_restore_device_state(dev_info_t *, wusb_ca_state_t *); - -static int wusb_ca_cpr_suspend(dev_info_t *); -static void wusb_ca_cpr_resume(dev_info_t *); -static int wusb_ca_pm_busy_component(wusb_ca_state_t *); -static void wusb_ca_pm_idle_component(wusb_ca_state_t *); -static int wusb_ca_power(dev_info_t *, int, int); -static void wusb_ca_init_power_mgmt(wusb_ca_state_t *); -static void wusb_ca_destroy_power_mgmt(wusb_ca_state_t *); - -static int wusb_ca_serialize_access(wusb_ca_state_t *, boolean_t); -static void wusb_ca_release_access(wusb_ca_state_t *); -static int wusb_ca_check_same_device(wusb_ca_state_t *); - -static mblk_t *trans_from_host_info(wusb_cbaf_host_info_t *); -static mblk_t *trans_from_cc_data(wusb_cbaf_cc_data_t *); -static mblk_t *trans_from_cc_fail(wusb_cbaf_cc_fail_t *); -static int trans_to_device_info(wusb_ca_state_t *, mblk_t *, - wusb_cbaf_device_info_t *); - -/* _NOTE is an advice for locklint. Locklint checks lock use for deadlocks. */ -_NOTE(SCHEME_PROTECTS_DATA("unique per call", usb_ctrl_req)) -_NOTE(SCHEME_PROTECTS_DATA("unique per call", buf)) -_NOTE(SCHEME_PROTECTS_DATA("unique per call", msgb)) -/* module loading stuff */ -struct cb_ops wusb_ca_cb_ops = { - wusb_ca_open, /* open */ - wusb_ca_close, /* close */ - nulldev, /* strategy */ - nulldev, /* print */ - nulldev, /* dump */ - nodev, /* read */ - nodev, /* write */ - wusb_ca_ioctl, /* ioctl */ - nulldev, /* devmap */ - nodev, /* mmap */ - nodev, /* segmap */ - nochpoll, /* poll */ - ddi_prop_op, /* cb_prop_op */ - NULL, /* streamtab */ - D_MP -}; - -static struct dev_ops wusb_ca_ops = { - DEVO_REV, /* devo_rev, */ - 0, /* refcnt */ - wusb_ca_info, /* info */ - nulldev, /* identify */ - nulldev, /* probe */ - wusb_ca_attach, /* attach */ - wusb_ca_detach, /* detach */ - nodev, /* reset */ - &wusb_ca_cb_ops, /* driver operations */ - NULL, /* bus operations */ - wusb_ca_power, /* power */ - ddi_quiesce_not_needed, /* quiesce */ -}; - -static struct modldrv wusb_ca_modldrv = { - &mod_driverops, - "WUSB Cable Association driver", - &wusb_ca_ops -}; - -static struct modlinkage modlinkage = { - MODREV_1, - &wusb_ca_modldrv, - NULL -}; - -/* local variables */ - -/* Soft state structures */ -#define WUSB_CA_INITIAL_SOFT_SPACE 1 -static void *wusb_ca_statep; - - -/* - * Module-wide initialization routine. - */ -int -_init(void) -{ - int rval; - - if ((rval = ddi_soft_state_init(&wusb_ca_statep, - sizeof (wusb_ca_state_t), WUSB_CA_INITIAL_SOFT_SPACE)) != 0) { - - return (rval); - } - - if ((rval = mod_install(&modlinkage)) != 0) { - ddi_soft_state_fini(&wusb_ca_statep); - } - - return (rval); -} - - -/* - * Module-wide tear-down routine. - */ -int -_fini(void) -{ - int rval; - - if ((rval = mod_remove(&modlinkage)) != 0) { - - return (rval); - } - - ddi_soft_state_fini(&wusb_ca_statep); - - return (rval); -} - - -int -_info(struct modinfo *modinfop) -{ - return (mod_info(&modlinkage, modinfop)); -} - - -/* - * wusb_ca_info: - * Get minor number, soft state structure, etc. - */ -/*ARGSUSED*/ -static int -wusb_ca_info(dev_info_t *dip, ddi_info_cmd_t infocmd, - void *arg, void **result) -{ - wusb_ca_state_t *wusb_cap; - int error = DDI_FAILURE; - - switch (infocmd) { - case DDI_INFO_DEVT2DEVINFO: - if ((wusb_cap = ddi_get_soft_state(wusb_ca_statep, - getminor((dev_t)arg))) != NULL) { - *result = wusb_cap->wusb_ca_dip; - if (*result != NULL) { - error = DDI_SUCCESS; - } - } else { - *result = NULL; - } - break; - case DDI_INFO_DEVT2INSTANCE: - *result = (void *)(uintptr_t)getminor((dev_t)arg); - error = DDI_SUCCESS; - break; - default: - break; - } - - return (error); -} - - -/* - * wusb_ca_attach: - * Attach or resume. - * - * For attach, initialize state and device, including: - * state variables, locks, device node - * device registration with system - * power management, hotplugging - * For resume, restore device and state - */ -static int -wusb_ca_attach(dev_info_t *dip, ddi_attach_cmd_t cmd) -{ - int instance = ddi_get_instance(dip); - char *devinst; - int devinstlen; - wusb_ca_state_t *wusb_cap = NULL; - int status; - - switch (cmd) { - case DDI_ATTACH: - break; - - case DDI_RESUME: - wusb_ca_cpr_resume(dip); - - /* - * Always return success to work around enumeration failures. - * This works around an issue where devices which are present - * before a suspend and absent upon resume could cause a system - * panic on resume. - */ - return (DDI_SUCCESS); - default: - return (DDI_FAILURE); - } - - if (ddi_soft_state_zalloc(wusb_ca_statep, instance) == DDI_SUCCESS) { - wusb_cap = ddi_get_soft_state(wusb_ca_statep, instance); - } - if (wusb_cap == NULL) { - - return (DDI_FAILURE); - } - - wusb_cap->wusb_ca_dip = dip; - - devinst = kmem_zalloc(USB_MAXSTRINGLEN, KM_SLEEP); - devinstlen = snprintf(devinst, USB_MAXSTRINGLEN, "%s%d: ", - ddi_driver_name(dip), instance); - - wusb_cap->wusb_ca_devinst = kmem_zalloc(devinstlen + 1, KM_SLEEP); - (void) strncpy(wusb_cap->wusb_ca_devinst, devinst, devinstlen); - kmem_free(devinst, USB_MAXSTRINGLEN); - - wusb_cap->wusb_ca_log_hdl = usb_alloc_log_hdl(dip, "wusb_ca", - &wusb_ca_errlevel, &wusb_ca_errmask, &wusb_ca_instance_debug, 0); - - USB_DPRINTF_L4(PRINT_MASK_ATTA, wusb_cap->wusb_ca_log_hdl, - "Attach: enter for attach"); - - - - if ((status = usb_client_attach(dip, USBDRV_VERSION, 0)) != - USB_SUCCESS) { - USB_DPRINTF_L2(PRINT_MASK_ATTA, wusb_cap->wusb_ca_log_hdl, - "attach: usb_client_attach failed, error code:%d", status); - goto fail; - } - - if ((status = usb_get_dev_data(dip, &wusb_cap->wusb_ca_reg, - USB_PARSE_LVL_ALL, 0)) != USB_SUCCESS) { - USB_DPRINTF_L2(PRINT_MASK_ATTA, wusb_cap->wusb_ca_log_hdl, - "attach: usb_get_dev_data failed, error code:%d", status); - goto fail; - } - - usb_free_descr_tree(dip, wusb_cap->wusb_ca_reg); - - mutex_init(&wusb_cap->wusb_ca_mutex, NULL, MUTEX_DRIVER, - wusb_cap->wusb_ca_reg->dev_iblock_cookie); - - cv_init(&wusb_cap->wusb_ca_serial_cv, NULL, CV_DRIVER, NULL); - wusb_cap->wusb_ca_serial_inuse = B_FALSE; - - wusb_cap->wusb_ca_locks_initialized = B_TRUE; - - /* create minor node */ - if (ddi_create_minor_node(dip, "wusb_ca", S_IFCHR, instance, - "wusb_ca", 0) != DDI_SUCCESS) { - USB_DPRINTF_L2(PRINT_MASK_ATTA, wusb_cap->wusb_ca_log_hdl, - "attach: Error creating minor node"); - - goto fail; - } - - /* Put online before PM init as can get power managed afterward. */ - wusb_cap->wusb_ca_dev_state = USB_DEV_ONLINE; - - /* initialize power management */ - wusb_ca_init_power_mgmt(wusb_cap); - - if (usb_register_hotplug_cbs(dip, wusb_ca_disconnect_callback, - wusb_ca_reconnect_callback) != USB_SUCCESS) { - - goto fail; - } - - /* Report device */ - ddi_report_dev(dip); - - return (DDI_SUCCESS); - -fail: - if (wusb_cap) { - (void) wusb_ca_cleanup(dip, wusb_cap); - } - - return (DDI_FAILURE); -} - - -/* - * wusb_ca_detach: - * detach or suspend driver instance - * - * Note: in detach, only contention threads is from pm and disconnnect. - */ -static int -wusb_ca_detach(dev_info_t *dip, ddi_detach_cmd_t cmd) -{ - int instance = ddi_get_instance(dip); - int rval = DDI_FAILURE; - wusb_ca_state_t *wusb_cap; - - wusb_cap = ddi_get_soft_state(wusb_ca_statep, instance); - switch (cmd) { - case DDI_DETACH: - mutex_enter(&wusb_cap->wusb_ca_mutex); - ASSERT((wusb_cap->wusb_ca_drv_state & WUSB_CA_OPEN) == 0); - mutex_exit(&wusb_cap->wusb_ca_mutex); - - USB_DPRINTF_L4(PRINT_MASK_ATTA, wusb_cap->wusb_ca_log_hdl, - "Detach: enter for detach"); - - rval = wusb_ca_cleanup(dip, wusb_cap); - - break; - case DDI_SUSPEND: - USB_DPRINTF_L4(PRINT_MASK_ATTA, wusb_cap->wusb_ca_log_hdl, - "Detach: enter for suspend"); - - rval = wusb_ca_cpr_suspend(dip); - default: - - break; - } - - return ((rval == USB_SUCCESS) ? DDI_SUCCESS : DDI_FAILURE); -} - - -/* - * wusb_ca_cleanup: - * clean up the driver state for detach - */ -static int -wusb_ca_cleanup(dev_info_t *dip, wusb_ca_state_t *wusb_cap) -{ - USB_DPRINTF_L4(PRINT_MASK_ATTA, wusb_cap->wusb_ca_log_hdl, - "Cleanup: enter"); - - if (wusb_cap->wusb_ca_locks_initialized) { - - /* This must be done 1st to prevent more events from coming. */ - usb_unregister_hotplug_cbs(dip); - - /* - * At this point, no new activity can be initiated. The driver - * has disabled hotplug callbacks. The Solaris framework has - * disabled new opens on a device being detached, and does not - * allow detaching an open device. - * - * The following ensures that all driver activity has drained. - */ - mutex_enter(&wusb_cap->wusb_ca_mutex); - (void) wusb_ca_serialize_access(wusb_cap, WUSB_CA_SER_NOSIG); - wusb_ca_release_access(wusb_cap); - mutex_exit(&wusb_cap->wusb_ca_mutex); - - /* All device activity has died down. */ - wusb_ca_destroy_power_mgmt(wusb_cap); - - /* start dismantling */ - ddi_remove_minor_node(dip, NULL); - - cv_destroy(&wusb_cap->wusb_ca_serial_cv); - mutex_destroy(&wusb_cap->wusb_ca_mutex); - } - - usb_client_detach(dip, wusb_cap->wusb_ca_reg); - - usb_free_log_hdl(wusb_cap->wusb_ca_log_hdl); - - if (wusb_cap->wusb_ca_devinst != NULL) { - kmem_free(wusb_cap->wusb_ca_devinst, - strlen(wusb_cap->wusb_ca_devinst) + 1); - } - - ddi_soft_state_free(wusb_ca_statep, ddi_get_instance(dip)); - ddi_prop_remove_all(dip); - - return (USB_SUCCESS); -} - - -/*ARGSUSED*/ -static int -wusb_ca_open(dev_t *devp, int flag, int otyp, cred_t *cred_p) -{ - wusb_ca_state_t *wusb_cap = - ddi_get_soft_state(wusb_ca_statep, getminor(*devp)); - int rval = 0; - - if (wusb_cap == NULL) { - - return (ENXIO); - } - - USB_DPRINTF_L4(PRINT_MASK_OPEN, wusb_cap->wusb_ca_log_hdl, - "open: enter"); - - /* - * Keep it simple: one client at a time. - * Exclusive open only - */ - mutex_enter(&wusb_cap->wusb_ca_mutex); - if ((wusb_cap->wusb_ca_drv_state & WUSB_CA_OPEN) != 0) { - mutex_exit(&wusb_cap->wusb_ca_mutex); - - return (EBUSY); - } - wusb_cap->wusb_ca_drv_state |= WUSB_CA_OPEN; - - /* - * This is in place so that a disconnect or CPR doesn't interfere with - * pipe opens. - */ - if (wusb_ca_serialize_access(wusb_cap, WUSB_CA_SER_SIG) == 0) { - wusb_cap->wusb_ca_drv_state &= ~WUSB_CA_OPEN; - mutex_exit(&wusb_cap->wusb_ca_mutex); - - return (EINTR); - } - - mutex_exit(&wusb_cap->wusb_ca_mutex); - if (wusb_ca_pm_busy_component(wusb_cap) != DDI_SUCCESS) { - USB_DPRINTF_L2(PRINT_MASK_OPEN, wusb_cap->wusb_ca_log_hdl, - "open: Error raising power"); - rval = EIO; - goto done; - } - mutex_enter(&wusb_cap->wusb_ca_mutex); - - /* Fail if device is no longer ready. */ - if (wusb_cap->wusb_ca_dev_state != USB_DEV_ONLINE) { - mutex_exit(&wusb_cap->wusb_ca_mutex); - rval = EIO; - goto done; - } - - mutex_exit(&wusb_cap->wusb_ca_mutex); - -done: - if (rval != 0) { - mutex_enter(&wusb_cap->wusb_ca_mutex); - wusb_cap->wusb_ca_drv_state &= ~WUSB_CA_OPEN; - - wusb_ca_release_access(wusb_cap); - mutex_exit(&wusb_cap->wusb_ca_mutex); - - wusb_ca_pm_idle_component(wusb_cap); - } else { - - /* Device is idle until it is used. */ - mutex_enter(&wusb_cap->wusb_ca_mutex); - wusb_ca_release_access(wusb_cap); - mutex_exit(&wusb_cap->wusb_ca_mutex); - } - - return (rval); -} - - -/*ARGSUSED*/ -static int -wusb_ca_close(dev_t dev, int flag, int otyp, cred_t *cred_p) -{ - wusb_ca_state_t *wusb_cap = - ddi_get_soft_state(wusb_ca_statep, getminor(dev)); - - USB_DPRINTF_L4(PRINT_MASK_CLOSE, wusb_cap->wusb_ca_log_hdl, - "close: enter"); - - mutex_enter(&wusb_cap->wusb_ca_mutex); - (void) wusb_ca_serialize_access(wusb_cap, WUSB_CA_SER_NOSIG); - mutex_exit(&wusb_cap->wusb_ca_mutex); - - /* Perform device session cleanup here. */ - - USB_DPRINTF_L4(PRINT_MASK_CLOSE, wusb_cap->wusb_ca_log_hdl, - "close: cleaning up..."); - - /* - * USBA automatically flushes/resets active non-default pipes - * when they are closed. We can't reset default pipe, but we - * can wait for all requests on it from this dip to drain. - */ - (void) usb_pipe_drain_reqs(wusb_cap->wusb_ca_dip, - wusb_cap->wusb_ca_reg->dev_default_ph, 0, - USB_FLAGS_SLEEP, NULL, 0); - - mutex_enter(&wusb_cap->wusb_ca_mutex); - - wusb_cap->wusb_ca_drv_state &= ~WUSB_CA_OPEN; - - wusb_ca_release_access(wusb_cap); - mutex_exit(&wusb_cap->wusb_ca_mutex); - - wusb_ca_pm_idle_component(wusb_cap); - - return (0); -} - - -/* - * ioctl for cable association operations. - */ -/*ARGSUSED*/ -static int -wusb_ca_ioctl(dev_t dev, int cmd, intptr_t arg, - int mode, cred_t *cred_p, int *rval_p) -{ - wusb_ca_state_t *wusb_cap = - ddi_get_soft_state(wusb_ca_statep, getminor(dev)); - - USB_DPRINTF_L4(PRINT_MASK_ALL, wusb_cap->wusb_ca_log_hdl, - "ioctl enter"); - - mutex_enter(&wusb_cap->wusb_ca_mutex); - - switch (cmd) { - case CBAF_IOCTL_GET_ASSO_INFO: - *rval_p = wusb_cbaf_get_asso_info(wusb_cap, arg, mode); - - break; - case CBAF_IOCTL_GET_ASSO_REQS: - *rval_p = wusb_cbaf_get_asso_reqs(wusb_cap, arg, mode); - - break; - case CBAF_IOCTL_SET_HOST_INFO: - *rval_p = wusb_cbaf_set_host_info(wusb_cap, arg, mode); - - break; - case CBAF_IOCTL_GET_DEVICE_INFO: - *rval_p = wusb_cbaf_get_device_info(wusb_cap, arg, mode); - - break; - case CBAF_IOCTL_SET_CONNECTION: - *rval_p = wusb_cbaf_set_connection(wusb_cap, arg, mode); - - break; - case CBAF_IOCTL_SET_FAILURE: - *rval_p = wusb_cbaf_set_failure(wusb_cap, arg, mode); - - break; - default: - - *rval_p = EINVAL; - } - - mutex_exit(&wusb_cap->wusb_ca_mutex); - - return (*rval_p); -} - - -/* - * wusb_ca_disconnect_callback: - * Called when device hotplug-removed. - * Close pipes. (This does not attempt to contact device.) - * Set state to DISCONNECTED - */ -static int -wusb_ca_disconnect_callback(dev_info_t *dip) -{ - int instance = ddi_get_instance(dip); - wusb_ca_state_t *wusb_cap; - - wusb_cap = ddi_get_soft_state(wusb_ca_statep, instance); - - USB_DPRINTF_L4(PRINT_MASK_CB, wusb_cap->wusb_ca_log_hdl, - "disconnect: enter"); - - mutex_enter(&wusb_cap->wusb_ca_mutex); - (void) wusb_ca_serialize_access(wusb_cap, WUSB_CA_SER_NOSIG); - - /* - * Save any state of device or IO in progress required by - * wusb_ca_restore_device_state for proper device "thawing" later. - */ - wusb_cap->wusb_ca_dev_state = USB_DEV_DISCONNECTED; - - wusb_ca_release_access(wusb_cap); - mutex_exit(&wusb_cap->wusb_ca_mutex); - - return (USB_SUCCESS); -} - - -/* - * wusb_ca_reconnect_callback: - * Called with device hotplug-inserted - * Restore state - */ -static int -wusb_ca_reconnect_callback(dev_info_t *dip) -{ - int instance = ddi_get_instance(dip); - wusb_ca_state_t *wusb_cap; - - wusb_cap = ddi_get_soft_state(wusb_ca_statep, instance); - - USB_DPRINTF_L4(PRINT_MASK_CB, wusb_cap->wusb_ca_log_hdl, - "reconnect: enter"); - - mutex_enter(&wusb_cap->wusb_ca_mutex); - (void) wusb_ca_serialize_access(wusb_cap, WUSB_CA_SER_NOSIG); - wusb_ca_restore_device_state(dip, wusb_cap); - wusb_ca_release_access(wusb_cap); - mutex_exit(&wusb_cap->wusb_ca_mutex); - - return (USB_SUCCESS); -} - - -/* - * wusb_ca_restore_device_state: - * Called during hotplug-reconnect and resume. - * reenable power management - * Verify the device is the same as before the disconnect/suspend. - * Restore device state - * Thaw any IO which was frozen. - * Quiesce device. (Other routines will activate if thawed IO.) - * Set device online. - * Leave device disconnected if there are problems. - */ -static void -wusb_ca_restore_device_state(dev_info_t *dip, wusb_ca_state_t *wusb_cap) -{ - USB_DPRINTF_L4(PRINT_MASK_CPR, wusb_cap->wusb_ca_log_hdl, - "wusb_ca_restore_device_state: enter"); - - ASSERT(mutex_owned(&wusb_cap->wusb_ca_mutex)); - - ASSERT((wusb_cap->wusb_ca_dev_state == USB_DEV_DISCONNECTED) || - (wusb_cap->wusb_ca_dev_state == USB_DEV_SUSPENDED)); - - mutex_exit(&wusb_cap->wusb_ca_mutex); - - if (wusb_ca_pm_busy_component(wusb_cap) != DDI_SUCCESS) { - USB_DPRINTF_L2(PRINT_MASK_CPR, wusb_cap->wusb_ca_log_hdl, - "wusb_ca_restore_device_state: Error raising power"); - - goto fail; - } - - /* Check if we are talking to the same device */ - if (wusb_ca_check_same_device(wusb_cap) != USB_SUCCESS) { - wusb_ca_pm_idle_component(wusb_cap); - - goto fail; - } - - mutex_enter(&wusb_cap->wusb_ca_mutex); - wusb_cap->wusb_ca_dev_state = USB_DEV_ONLINE; - - if ((wusb_cap->wusb_ca_pm) && - (wusb_cap->wusb_ca_pm->wusb_ca_remote_wakeup)) { - mutex_exit(&wusb_cap->wusb_ca_mutex); - - /* Failure here means device disappeared again. */ - if (usb_handle_remote_wakeup(dip, USB_REMOTE_WAKEUP_ENABLE) != - USB_SUCCESS) { - USB_DPRINTF_L2(PRINT_MASK_CPR, - wusb_cap->wusb_ca_log_hdl, - "device may or may not be accessible. " - "Please verify reconnection"); - } - - mutex_enter(&wusb_cap->wusb_ca_mutex); - } - - mutex_exit(&wusb_cap->wusb_ca_mutex); - wusb_ca_pm_idle_component(wusb_cap); - mutex_enter(&wusb_cap->wusb_ca_mutex); - - USB_DPRINTF_L4(PRINT_MASK_CPR, wusb_cap->wusb_ca_log_hdl, - "wusb_ca_restore_device_state: end"); - - return; - -fail: - /* change the device state from suspended to disconnected */ - mutex_enter(&wusb_cap->wusb_ca_mutex); - wusb_cap->wusb_ca_dev_state = USB_DEV_DISCONNECTED; -} - - -/* - * wusb_ca_cpr_suspend: - * Clean up device. - * Wait for any IO to finish, then close pipes. - * Quiesce device. - */ -static int -wusb_ca_cpr_suspend(dev_info_t *dip) -{ - int instance = ddi_get_instance(dip); - wusb_ca_state_t *wusb_cap; - - wusb_cap = ddi_get_soft_state(wusb_ca_statep, instance); - - USB_DPRINTF_L4(PRINT_MASK_CPR, wusb_cap->wusb_ca_log_hdl, - "suspend enter"); - - /* Serialize to prevent races with detach, open, device access. */ - mutex_enter(&wusb_cap->wusb_ca_mutex); - (void) wusb_ca_serialize_access(wusb_cap, WUSB_CA_SER_NOSIG); - mutex_exit(&wusb_cap->wusb_ca_mutex); - - if (wusb_ca_pm_busy_component(wusb_cap) != DDI_SUCCESS) { - USB_DPRINTF_L2(PRINT_MASK_CPR, wusb_cap->wusb_ca_log_hdl, - "suspend: Error raising power"); - wusb_ca_pm_idle_component(wusb_cap); - - return (USB_FAILURE); - } - - mutex_enter(&wusb_cap->wusb_ca_mutex); - - /* - * Set dev_state to suspended so other driver threads don't start any - * new I/O. - */ - - /* Don't suspend if the device is open. */ - if ((wusb_cap->wusb_ca_drv_state & WUSB_CA_OPEN) != 0) { - USB_DPRINTF_L2(PRINT_MASK_CPR, wusb_cap->wusb_ca_log_hdl, - "suspend: Device is open. Can't suspend"); - - wusb_ca_release_access(wusb_cap); - mutex_exit(&wusb_cap->wusb_ca_mutex); - - wusb_ca_pm_idle_component(wusb_cap); - - return (USB_FAILURE); - } - - wusb_cap->wusb_ca_dev_state = USB_DEV_SUSPENDED; - - wusb_ca_release_access(wusb_cap); - mutex_exit(&wusb_cap->wusb_ca_mutex); - - wusb_ca_pm_idle_component(wusb_cap); - - USB_DPRINTF_L4(PRINT_MASK_CPR, wusb_cap->wusb_ca_log_hdl, - "suspend: success"); - - return (USB_SUCCESS); -} - - -/* - * wusb_ca_cpr_resume: - * - * wusb_ca_restore_device_state marks success by putting device back online - */ -static void -wusb_ca_cpr_resume(dev_info_t *dip) -{ - int instance = ddi_get_instance(dip); - wusb_ca_state_t *wusb_cap; - - wusb_cap = ddi_get_soft_state(wusb_ca_statep, instance); - - USB_DPRINTF_L4(PRINT_MASK_CPR, wusb_cap->wusb_ca_log_hdl, - "resume: enter"); - - /* - * A pm_raise_power in wusb_ca_restore_device_state will bring - * the power-up state of device into synch with the system. - */ - mutex_enter(&wusb_cap->wusb_ca_mutex); - wusb_ca_restore_device_state(dip, wusb_cap); - mutex_exit(&wusb_cap->wusb_ca_mutex); -} - - -static int -wusb_ca_pm_busy_component(wusb_ca_state_t *wusb_cap) -{ - int rval = DDI_SUCCESS; - - mutex_enter(&wusb_cap->wusb_ca_mutex); - if (wusb_cap->wusb_ca_pm != NULL) { - wusb_cap->wusb_ca_pm->wusb_ca_pm_busy++; - mutex_exit(&wusb_cap->wusb_ca_mutex); - if (pm_busy_component(wusb_cap->wusb_ca_dip, 0) == - DDI_SUCCESS) { - (void) pm_raise_power( - wusb_cap->wusb_ca_dip, 0, USB_DEV_OS_FULL_PWR); - mutex_enter(&wusb_cap->wusb_ca_mutex); - } else { - mutex_enter(&wusb_cap->wusb_ca_mutex); - wusb_cap->wusb_ca_pm->wusb_ca_pm_busy--; - } - } - mutex_exit(&wusb_cap->wusb_ca_mutex); - - return (rval); -} - -static void -wusb_ca_pm_idle_component(wusb_ca_state_t *wusb_cap) -{ - mutex_enter(&wusb_cap->wusb_ca_mutex); - if (wusb_cap->wusb_ca_pm != NULL) { - mutex_exit(&wusb_cap->wusb_ca_mutex); - if (pm_idle_component(wusb_cap->wusb_ca_dip, 0) == - DDI_SUCCESS) { - mutex_enter(&wusb_cap->wusb_ca_mutex); - ASSERT(wusb_cap->wusb_ca_pm->wusb_ca_pm_busy > 0); - wusb_cap->wusb_ca_pm->wusb_ca_pm_busy--; - mutex_exit(&wusb_cap->wusb_ca_mutex); - } - mutex_enter(&wusb_cap->wusb_ca_mutex); - USB_DPRINTF_L3(PRINT_MASK_PM, wusb_cap->wusb_ca_log_hdl, - "wusb_ca_pm_idle_component: %d", - wusb_cap->wusb_ca_pm->wusb_ca_pm_busy); - } - mutex_exit(&wusb_cap->wusb_ca_mutex); -} - -/* - * wusb_ca_power : - * Power entry point, the workhorse behind pm_raise_power, pm_lower_power, - * usb_req_raise_power and usb_req_lower_power. - */ -/* ARGSUSED */ -static int -wusb_ca_power(dev_info_t *dip, int comp, int level) -{ - wusb_ca_state_t *wusb_cap; - wusb_ca_power_t *pm; - int rval = USB_SUCCESS; - - wusb_cap = ddi_get_soft_state(wusb_ca_statep, ddi_get_instance(dip)); - - USB_DPRINTF_L4(PRINT_MASK_PM, wusb_cap->wusb_ca_log_hdl, - "wusb_ca_power: enter: level = %d", level); - - mutex_enter(&wusb_cap->wusb_ca_mutex); - (void) wusb_ca_serialize_access(wusb_cap, WUSB_CA_SER_NOSIG); - - /* - * If we are disconnected/suspended, return success. Note that if we - * return failure, bringing down the system will hang when PM tries - * to power up all devices - */ - if ((wusb_cap->wusb_ca_dev_state == USB_DEV_DISCONNECTED) || - (wusb_cap->wusb_ca_dev_state == USB_DEV_SUSPENDED)) { - - USB_DPRINTF_L3(PRINT_MASK_PM, wusb_cap->wusb_ca_log_hdl, - "wusb_ca_power: disconnected/suspended " - "dev_state=%d", wusb_cap->wusb_ca_dev_state); - rval = USB_SUCCESS; - - goto done; - } - - if (wusb_cap->wusb_ca_pm == NULL) { - - goto done; - } - - pm = wusb_cap->wusb_ca_pm; - - /* Check if we are transitioning to a legal power level */ - if (USB_DEV_PWRSTATE_OK(pm->wusb_ca_pwr_states, level)) { - USB_DPRINTF_L3(PRINT_MASK_PM, wusb_cap->wusb_ca_log_hdl, - "wusb_ca_power: illegal power level = %d " - "pwr_states: %x", level, pm->wusb_ca_pwr_states); - - goto done; - } - - switch (level) { - case USB_DEV_OS_PWR_OFF : - /* fail attempt to go to low power if busy */ - if (pm->wusb_ca_pm_busy) { - - goto done; - } - if (wusb_cap->wusb_ca_dev_state == USB_DEV_ONLINE) { - (void) usb_set_device_pwrlvl3(wusb_cap->wusb_ca_dip); - - wusb_cap->wusb_ca_dev_state = USB_DEV_PWRED_DOWN; - wusb_cap->wusb_ca_pm->wusb_ca_current_power = - USB_DEV_OS_PWR_OFF; - } - - break; - - case USB_DEV_OS_FULL_PWR : - /* - * PM framework tries to put us in full power during system - * shutdown. Handle USB_DEV_PWRED_DOWN only. - */ - if (wusb_cap->wusb_ca_dev_state == USB_DEV_PWRED_DOWN) { - (void) usb_set_device_pwrlvl0(wusb_cap->wusb_ca_dip); - wusb_cap->wusb_ca_dev_state = USB_DEV_ONLINE; - wusb_cap->wusb_ca_pm->wusb_ca_current_power = - USB_DEV_OS_FULL_PWR; - } - - break; - - /* Levels 1 and 2 are not supported by this driver to keep it simple. */ - default: - USB_DPRINTF_L3(PRINT_MASK_PM, wusb_cap->wusb_ca_log_hdl, - "wusb_ca_power: power level %d not supported", level); - break; - } -done: - wusb_ca_release_access(wusb_cap); - mutex_exit(&wusb_cap->wusb_ca_mutex); - - /* Generally return success to make PM succeed */ - return ((rval == USB_SUCCESS) ? DDI_SUCCESS : DDI_FAILURE); -} - - -/* - * wusb_ca_init_power_mgmt: - * Initialize power management and remote wakeup functionality. - * No mutex is necessary in this function as it's called only by attach. - */ -static void -wusb_ca_init_power_mgmt(wusb_ca_state_t *wusb_cap) -{ - wusb_ca_power_t *wusb_capm; - uint_t pwr_states; - - USB_DPRINTF_L4(PRINT_MASK_PM, wusb_cap->wusb_ca_log_hdl, - "init_power_mgmt enter"); - - /* Allocate the state structure */ - wusb_capm = kmem_zalloc(sizeof (wusb_ca_power_t), KM_SLEEP); - wusb_cap->wusb_ca_pm = wusb_capm; - wusb_capm->wusb_ca_state = wusb_cap; - wusb_capm->wusb_ca_pm_capabilities = 0; - wusb_capm->wusb_ca_current_power = USB_DEV_OS_FULL_PWR; - - if (usb_create_pm_components(wusb_cap->wusb_ca_dip, - &pwr_states) == USB_SUCCESS) { - USB_DPRINTF_L3(PRINT_MASK_PM, wusb_cap->wusb_ca_log_hdl, - "wusb_ca_init_power_mgmt: created PM components"); - - wusb_capm->wusb_ca_pwr_states = (uint8_t)pwr_states; - (void) pm_raise_power(wusb_cap->wusb_ca_dip, 0, - USB_DEV_OS_FULL_PWR); - } else { - USB_DPRINTF_L3(PRINT_MASK_PM, wusb_cap->wusb_ca_log_hdl, - "wusb_ca_init_power_mgmt: create_pm_compts failed"); - } - - /* - * If remote wakeup is not available you may not want to do - * power management. - */ - if (usb_handle_remote_wakeup(wusb_cap->wusb_ca_dip, - USB_REMOTE_WAKEUP_ENABLE) == USB_SUCCESS) { - wusb_capm->wusb_ca_remote_wakeup = 1; - } else { - USB_DPRINTF_L3(PRINT_MASK_PM, wusb_cap->wusb_ca_log_hdl, - "wusb_ca_init_power_mgmt: failure enabling remote wakeup"); - } - - USB_DPRINTF_L4(PRINT_MASK_PM, wusb_cap->wusb_ca_log_hdl, - "wusb_ca_init_power_mgmt: end"); -} - - -/* - * wusb_ca_destroy_power_mgmt: - * Shut down and destroy power management and remote wakeup functionality. - */ -static void -wusb_ca_destroy_power_mgmt(wusb_ca_state_t *wusb_cap) -{ - wusb_ca_power_t *wusb_capm; - - USB_DPRINTF_L4(PRINT_MASK_PM, wusb_cap->wusb_ca_log_hdl, - "destroy_power_mgmt enter"); - - ASSERT(!mutex_owned(&wusb_cap->wusb_ca_mutex)); - - mutex_enter(&wusb_cap->wusb_ca_mutex); - - wusb_capm = wusb_cap->wusb_ca_pm; - if (!wusb_capm) { - mutex_exit(&wusb_cap->wusb_ca_mutex); - - return; - } - - mutex_exit(&wusb_cap->wusb_ca_mutex); - - (void) wusb_ca_pm_busy_component(wusb_cap); - - mutex_enter(&wusb_cap->wusb_ca_mutex); - if (wusb_cap->wusb_ca_dev_state != USB_DEV_DISCONNECTED) { - int rval; - - if (wusb_capm->wusb_ca_remote_wakeup) { - mutex_exit(&wusb_cap->wusb_ca_mutex); - - (void) pm_raise_power(wusb_cap->wusb_ca_dip, 0, - USB_DEV_OS_FULL_PWR); - - rval = usb_handle_remote_wakeup( - wusb_cap->wusb_ca_dip, - USB_REMOTE_WAKEUP_DISABLE); - - USB_DPRINTF_L2(PRINT_MASK_PM, - wusb_cap->wusb_ca_log_hdl, - "wusb_ca_destroy_power_mgmt: " - "Error disabling rmt wakeup: rval = %d", - rval); - - mutex_enter(&wusb_cap->wusb_ca_mutex); - } - } - - mutex_exit(&wusb_cap->wusb_ca_mutex); - - /* - * Since remote wakeup is disabled now, - * no one can raise power - * and get to device once power is lowered here. - */ - (void) pm_lower_power(wusb_cap->wusb_ca_dip, 0, USB_DEV_OS_PWR_OFF); - wusb_ca_pm_idle_component(wusb_cap); - - mutex_enter(&wusb_cap->wusb_ca_mutex); - kmem_free(wusb_cap->wusb_ca_pm, sizeof (wusb_ca_power_t)); - wusb_cap->wusb_ca_pm = NULL; - mutex_exit(&wusb_cap->wusb_ca_mutex); -} - - -/* - * wusb_ca_serialize_access: - * Get the serial synchronization object before returning. - * - * Arguments: - * wusb_cap - Pointer to wusb_ca state structure - * waitsig - Set to: - * WUSB_CA_SER_SIG - to wait such that a signal can interrupt - * WUSB_CA_SER_NOSIG - to wait such that a signal cannot interrupt - */ -static int -wusb_ca_serialize_access(wusb_ca_state_t *wusb_cap, boolean_t waitsig) -{ - int rval = 1; - - ASSERT(mutex_owned(&wusb_cap->wusb_ca_mutex)); - - while (wusb_cap->wusb_ca_serial_inuse) { - if (waitsig == WUSB_CA_SER_SIG) { - rval = cv_wait_sig(&wusb_cap->wusb_ca_serial_cv, - &wusb_cap->wusb_ca_mutex); - } else { - cv_wait(&wusb_cap->wusb_ca_serial_cv, - &wusb_cap->wusb_ca_mutex); - } - } - wusb_cap->wusb_ca_serial_inuse = B_TRUE; - - return (rval); -} - - -/* - * wusb_ca_release_access: - * Release the serial synchronization object. - */ -static void -wusb_ca_release_access(wusb_ca_state_t *wusb_cap) -{ - ASSERT(mutex_owned(&wusb_cap->wusb_ca_mutex)); - wusb_cap->wusb_ca_serial_inuse = B_FALSE; - cv_broadcast(&wusb_cap->wusb_ca_serial_cv); -} - - -/* - * wusb_ca_check_same_device: - * Check if the device connected to the port is the same as - * the previous device that was in the port. The previous device is - * represented by the dip on record for the port. Print a message - * if the device is different. Can block. - * - * return values: - * USB_SUCCESS: same device - * USB_INVALID_VERSION not same device - * USB_FAILURE: Failure processing request - */ -static int -wusb_ca_check_same_device(wusb_ca_state_t *wusb_cap) -{ - usb_dev_descr_t *orig_usb_dev_descr; - usb_dev_descr_t usb_dev_descr; - mblk_t *pdata = NULL; - int rval; - char *buf; - usb_cr_t completion_reason; - usb_cb_flags_t cb_flags; - boolean_t match = B_TRUE; - - usb_ctrl_setup_t setup = { - USB_DEV_REQ_DEV_TO_HOST | USB_DEV_REQ_TYPE_STANDARD | - USB_DEV_REQ_RCPT_DEV, - USB_REQ_GET_DESCR, /* bRequest */ - USB_DESCR_TYPE_SETUP_DEV, /* wValue */ - 0, /* wIndex */ - USB_DEV_DESCR_SIZE, /* wLength */ - 0 /* request attributes */ - }; - - ASSERT(!mutex_owned(&wusb_cap->wusb_ca_mutex)); - - orig_usb_dev_descr = wusb_cap->wusb_ca_reg->dev_descr; - - /* get the "new" device descriptor */ - rval = usb_pipe_ctrl_xfer_wait(wusb_cap->wusb_ca_reg->dev_default_ph, - &setup, &pdata, &completion_reason, &cb_flags, USB_FLAGS_SLEEP); - - if (rval != USB_SUCCESS) { - USB_DPRINTF_L2(PRINT_MASK_ALL, wusb_cap->wusb_ca_log_hdl, - "wusb_ca_check_same_device: " - "getting device descriptor failed " - "rval=%d, cr=%d, cb=0x%x\n", - rval, completion_reason, cb_flags); - freemsg(pdata); - - return (USB_FAILURE); - } - - ASSERT(pdata != NULL); - - (void) usb_parse_data("2cs4c3s4c", pdata->b_rptr, - (intptr_t)pdata->b_wptr - (intptr_t)pdata->b_rptr, &usb_dev_descr, - sizeof (usb_dev_descr_t)); - - freemsg(pdata); - pdata = NULL; - - /* Always check the device descriptor length. */ - if (usb_dev_descr.bLength != USB_DEV_DESCR_SIZE) { - match = B_FALSE; - - /* Always check the device descriptor. */ - } else if (bcmp(orig_usb_dev_descr, - (char *)&usb_dev_descr, USB_DEV_DESCR_SIZE) != 0) { - match = B_FALSE; - } - - /* if requested & this device has a serial number check and compare */ - if ((match == B_TRUE) && - (wusb_cap->wusb_ca_reg->dev_serial != NULL)) { - buf = kmem_alloc(USB_MAXSTRINGLEN, KM_SLEEP); - if (usb_get_string_descr(wusb_cap->wusb_ca_dip, USB_LANG_ID, - usb_dev_descr.iSerialNumber, buf, - USB_MAXSTRINGLEN) == USB_SUCCESS) { - match = - (strcmp(buf, - wusb_cap->wusb_ca_reg->dev_serial) == 0); - } - kmem_free(buf, USB_MAXSTRINGLEN); - } - - if (match == B_FALSE) { - USB_DPRINTF_L2(PRINT_MASK_ALL, wusb_cap->wusb_ca_log_hdl, - "Device is not identical to the " - "previous one this port.\n" - "Please disconnect and reconnect"); - - return (USB_INVALID_VERSION); - } - - return (USB_SUCCESS); -} - - -/* get association info */ -int -wusb_cbaf_get_asso_info(wusb_ca_state_t *wusb_cap, intptr_t arg, int flag) -{ - usb_pipe_handle_t pipe = wusb_cap->wusb_ca_reg->dev_default_ph; - usb_ctrl_setup_t setup; - usb_cr_t completion_reason; - usb_cb_flags_t cb_flags; - wusb_cbaf_asso_info_t ca_info; - mblk_t *pdata = NULL; - int rval; - - setup.bmRequestType = USB_DEV_REQ_DEV_TO_HOST | - USB_DEV_REQ_TYPE_CLASS | USB_DEV_REQ_RCPT_IF; - setup.bRequest = WUSB_CBAF_GET_ASSOCIATION_INFORMATION; - setup.wValue = 0; - setup.wIndex = 0; - setup.wLength = WUSB_ASSO_INFO_SIZE; - setup.attrs = USB_ATTRS_NONE; - - rval = usb_pipe_ctrl_xfer_wait(pipe, &setup, &pdata, - &completion_reason, &cb_flags, USB_FLAGS_SLEEP); - - if (rval != USB_SUCCESS) { - USB_DPRINTF_L2(PRINT_MASK_ALL, wusb_cap->wusb_ca_log_hdl, - "cr = %d cb_flags = %d", completion_reason, cb_flags); - - return (EIO); - } - if (pdata == NULL || msgsize(pdata) == 0) { - USB_DPRINTF_L2(PRINT_MASK_ALL, wusb_cap->wusb_ca_log_hdl, - "empty pdata"); - - return (EIO); - } - - rval = usb_parse_data("scs", pdata->b_rptr, WUSB_ASSO_INFO_SIZE, - &ca_info, sizeof (ca_info)); - if (rval <= 0) { - USB_DPRINTF_L2(PRINT_MASK_ALL, wusb_cap->wusb_ca_log_hdl, - "parse data"); - - return (EIO); - } - - rval = ddi_copyout(&ca_info, (void *)arg, sizeof (ca_info), flag); - if (rval != 0) { - USB_DPRINTF_L2(PRINT_MASK_ALL, wusb_cap->wusb_ca_log_hdl, - "ddi_copyout"); - - return (EIO); - } - - freemsg(pdata); - - return (0); -} - -/* get request array */ -int -wusb_cbaf_get_asso_reqs(wusb_ca_state_t *wusb_cap, intptr_t arg, int flag) -{ - usb_pipe_handle_t pipe = wusb_cap->wusb_ca_reg->dev_default_ph; - usb_ctrl_setup_t setup; - usb_cr_t completion_reason; - usb_cb_flags_t cb_flags; - wusb_cbaf_asso_info_t ca_info; - wusb_cbaf_asso_req_t *ca_reqs; - mblk_t *pdata = NULL; - uchar_t *data; - int rval, reqs_size, i; - - rval = ddi_copyin((void *)arg, &ca_info, sizeof (ca_info), flag); - if (rval != 0) { - USB_DPRINTF_L2(PRINT_MASK_ALL, wusb_cap->wusb_ca_log_hdl, - "ddi_copyin"); - - return (EIO); - } - - setup.bmRequestType = USB_DEV_REQ_DEV_TO_HOST | - USB_DEV_REQ_TYPE_CLASS | USB_DEV_REQ_RCPT_IF; - setup.bRequest = WUSB_CBAF_GET_ASSOCIATION_INFORMATION; - setup.wValue = 0; - setup.wIndex = 0; - setup.wLength = ca_info.Length; - setup.attrs = USB_ATTRS_NONE; - - rval = usb_pipe_ctrl_xfer_wait(pipe, &setup, &pdata, - &completion_reason, &cb_flags, USB_FLAGS_SLEEP); - - if (rval != USB_SUCCESS) { - USB_DPRINTF_L2(PRINT_MASK_ALL, wusb_cap->wusb_ca_log_hdl, - "cr = %d cb_flags = %d", completion_reason, cb_flags); - - return (EIO); - } - if (pdata == NULL || msgsize(pdata) == 0) { - USB_DPRINTF_L2(PRINT_MASK_ALL, wusb_cap->wusb_ca_log_hdl, - "empty pdata"); - - return (EIO); - } - - reqs_size = sizeof (wusb_cbaf_asso_req_t) * - ca_info.NumAssociationRequests; - ca_reqs = (wusb_cbaf_asso_req_t *)kmem_zalloc(reqs_size, KM_SLEEP); - - data = pdata->b_rptr + WUSB_ASSO_INFO_SIZE; - for (i = 0; i < ca_info.NumAssociationRequests; i++) { - rval = usb_parse_data("ccssl", data, WUSB_ASSO_REQUEST_SIZE, - &(ca_reqs[i]), sizeof (wusb_cbaf_asso_req_t)); - if (rval <= 0) { - USB_DPRINTF_L2(PRINT_MASK_ALL, - wusb_cap->wusb_ca_log_hdl, - "parse data"); - - return (EIO); - } - data += WUSB_ASSO_REQUEST_SIZE; - } - - rval = ddi_copyout(ca_reqs, (void *)(arg + sizeof (ca_info)), - reqs_size, flag); - if (rval != 0) { - USB_DPRINTF_L2(PRINT_MASK_ALL, wusb_cap->wusb_ca_log_hdl, - "ddi_copyout"); - - return (EIO); - } - - freemsg(pdata); - kmem_free(ca_reqs, reqs_size); - - return (0); -} - -/* set host info */ -int -wusb_cbaf_set_host_info(wusb_ca_state_t *wusb_cap, intptr_t arg, int flag) -{ - usb_pipe_handle_t pipe = wusb_cap->wusb_ca_reg->dev_default_ph; - usb_ctrl_setup_t setup; - usb_cr_t completion_reason; - usb_cb_flags_t cb_flags; - wusb_cbaf_host_info_t host_info; - mblk_t *pdata; - int rval; - - rval = ddi_copyin((void *)arg, &host_info, sizeof (host_info), flag); - if (rval != 0) { - USB_DPRINTF_L2(PRINT_MASK_ALL, wusb_cap->wusb_ca_log_hdl, - "ddi_copyin"); - - return (EIO); - } - - if ((pdata = trans_from_host_info(&host_info)) == NULL) { - USB_DPRINTF_L2(PRINT_MASK_ALL, wusb_cap->wusb_ca_log_hdl, - "trans host info"); - - return (EIO); - } - - setup.bmRequestType = USB_DEV_REQ_TYPE_CLASS | USB_DEV_REQ_RCPT_IF; - setup.bRequest = WUSB_CBAF_SET_ASSOCIATION_RESPONSE; - setup.wValue = 0x101; - setup.wIndex = 0; - setup.wLength = WUSB_HOST_INFO_SIZE; - setup.attrs = USB_ATTRS_NONE; - - rval = usb_pipe_ctrl_xfer_wait(pipe, &setup, &pdata, - &completion_reason, &cb_flags, USB_FLAGS_SLEEP); - - freemsg(pdata); - - if (rval != USB_SUCCESS) { - USB_DPRINTF_L2(PRINT_MASK_ALL, wusb_cap->wusb_ca_log_hdl, - "cr = %d cb_flags = 0x%03x", completion_reason, cb_flags); - - return (EIO); - } - - return (0); -} - -/* get device info */ -int -wusb_cbaf_get_device_info(wusb_ca_state_t *wusb_cap, intptr_t arg, int flag) -{ - usb_pipe_handle_t pipe = wusb_cap->wusb_ca_reg->dev_default_ph; - usb_ctrl_setup_t setup; - usb_cr_t completion_reason; - usb_cb_flags_t cb_flags; - wusb_cbaf_device_info_t device_info; - mblk_t *pdata = NULL; - int rval; - - setup.bmRequestType = USB_DEV_REQ_DEV_TO_HOST | - USB_DEV_REQ_TYPE_CLASS | USB_DEV_REQ_RCPT_IF; - setup.bRequest = WUSB_CBAF_GET_ASSOCIATION_REQUEST; - setup.wValue = 0x200; - setup.wIndex = 0; - setup.wLength = WUSB_DEVICE_INFO_SIZE; - setup.attrs = USB_ATTRS_NONE; - - rval = usb_pipe_ctrl_xfer_wait(pipe, &setup, &pdata, - &completion_reason, &cb_flags, USB_FLAGS_SLEEP); - - if (rval != USB_SUCCESS) { - USB_DPRINTF_L2(PRINT_MASK_ALL, wusb_cap->wusb_ca_log_hdl, - "cr = %d cb_flags = %d", completion_reason, cb_flags); - - return (EIO); - } - if (pdata == NULL || msgsize(pdata) == 0) { - USB_DPRINTF_L2(PRINT_MASK_ALL, wusb_cap->wusb_ca_log_hdl, - "empty pdata"); - - return (EIO); - } - - if (trans_to_device_info(wusb_cap, pdata, &device_info) != 0) { - USB_DPRINTF_L2(PRINT_MASK_ALL, wusb_cap->wusb_ca_log_hdl, - "trans to device_info"); - - return (EIO); - } - - rval = ddi_copyout(&device_info, (void *)arg, - sizeof (device_info), flag); - if (rval != 0) { - USB_DPRINTF_L2(PRINT_MASK_ALL, wusb_cap->wusb_ca_log_hdl, - "ddi_copyout"); - - return (EIO); - } - - freemsg(pdata); - - return (0); -} - -/* set connection to device */ -int -wusb_cbaf_set_connection(wusb_ca_state_t *wusb_cap, intptr_t arg, int flag) -{ - usb_pipe_handle_t pipe = wusb_cap->wusb_ca_reg->dev_default_ph; - usb_ctrl_setup_t setup; - usb_cr_t completion_reason; - usb_cb_flags_t cb_flags; - wusb_cbaf_cc_data_t cc_data; - mblk_t *pdata = NULL; - int rval; - - rval = ddi_copyin((void *)arg, &cc_data, sizeof (cc_data), flag); - if (rval != 0) { - USB_DPRINTF_L2(PRINT_MASK_ALL, wusb_cap->wusb_ca_log_hdl, - "ddi_copyin"); - - return (EIO); - } - - if ((pdata = trans_from_cc_data(&cc_data)) == NULL) { - USB_DPRINTF_L2(PRINT_MASK_ALL, wusb_cap->wusb_ca_log_hdl, - "trans cc data"); - - return (EIO); - } - - setup.bmRequestType = USB_DEV_REQ_TYPE_CLASS | USB_DEV_REQ_RCPT_IF; - setup.bRequest = WUSB_CBAF_SET_ASSOCIATION_RESPONSE; - setup.wValue = 0x201; - setup.wIndex = 0; - setup.wLength = WUSB_CC_DATA_SIZE; - setup.attrs = USB_ATTRS_NONE; - - rval = usb_pipe_ctrl_xfer_wait(pipe, &setup, &pdata, - &completion_reason, &cb_flags, USB_FLAGS_SLEEP); - - freemsg(pdata); - - if (rval != USB_SUCCESS) { - USB_DPRINTF_L2(PRINT_MASK_ALL, wusb_cap->wusb_ca_log_hdl, - "cr = %d cb_flags = %d", completion_reason, cb_flags); - - return (EIO); - } - - return (0); -} - -/* set failure */ -int -wusb_cbaf_set_failure(wusb_ca_state_t *wusb_cap, intptr_t arg, int flag) -{ - usb_pipe_handle_t pipe = wusb_cap->wusb_ca_reg->dev_default_ph; - usb_ctrl_setup_t setup; - usb_cr_t completion_reason; - usb_cb_flags_t cb_flags; - wusb_cbaf_cc_fail_t cc_fail; - mblk_t *pdata = NULL; - int rval; - - rval = ddi_copyin((void *)arg, &cc_fail, sizeof (cc_fail), flag); - if (rval != 0) { - USB_DPRINTF_L2(PRINT_MASK_ALL, wusb_cap->wusb_ca_log_hdl, - "ddi_copyin"); - - return (EIO); - } - - if ((pdata = trans_from_cc_fail(&cc_fail)) == NULL) { - USB_DPRINTF_L2(PRINT_MASK_ALL, wusb_cap->wusb_ca_log_hdl, - "trans cc fail"); - - return (EIO); - } - - setup.bmRequestType = USB_DEV_REQ_TYPE_CLASS | USB_DEV_REQ_RCPT_IF; - setup.bRequest = WUSB_CBAF_SET_ASSOCIATION_RESPONSE; - setup.wValue = 0x201; - setup.wIndex = 0; - setup.wLength = WUSB_CC_DATA_SIZE; - setup.attrs = USB_ATTRS_NONE; - - rval = usb_pipe_ctrl_xfer_wait(pipe, &setup, &pdata, - &completion_reason, &cb_flags, USB_FLAGS_SLEEP); - - freemsg(pdata); - - if (rval != USB_SUCCESS) { - USB_DPRINTF_L2(PRINT_MASK_ALL, wusb_cap->wusb_ca_log_hdl, - "cr = %d cb_flags = %d", completion_reason, cb_flags); - - return (EIO); - } - - return (0); -} - -#define DRAW_BYTE(x, sh) (((x) >> (sh * 8)) & 0xff) - -static mblk_t * -trans_from_host_info(wusb_cbaf_host_info_t *host_info) -{ - mblk_t *pdata; - - if ((pdata = allocb(WUSB_HOST_INFO_SIZE, BPRI_HI)) == NULL) { - - return (NULL); - } - - bcopy(fieldAssociationTypeId, pdata->b_wptr, 4); - pdata->b_wptr += 4; - *pdata->b_wptr++ = DRAW_BYTE(host_info->AssociationTypeId, 0); - *pdata->b_wptr++ = DRAW_BYTE(host_info->AssociationTypeId, 1); - - bcopy(fieldAssociationSubTypeId, pdata->b_wptr, 4); - pdata->b_wptr += 4; - *pdata->b_wptr++ = DRAW_BYTE(host_info->AssociationSubTypeId, 0); - *pdata->b_wptr++ = DRAW_BYTE(host_info->AssociationSubTypeId, 1); - - bcopy(fieldCHID, pdata->b_wptr, 4); - pdata->b_wptr += 4; - bcopy(host_info->CHID, pdata->b_wptr, 16); - pdata->b_wptr += 16; - - bcopy(fieldLangID, pdata->b_wptr, 4); - pdata->b_wptr += 4; - *pdata->b_wptr++ = DRAW_BYTE(host_info->LangID, 0); - *pdata->b_wptr++ = DRAW_BYTE(host_info->LangID, 1); - - bcopy(fieldHostFriendlyName, pdata->b_wptr, 4); - pdata->b_wptr += 4; - bcopy(host_info->HostFriendlyName, pdata->b_wptr, 64); - pdata->b_wptr += 64; - - return (pdata); -} - -static mblk_t * -trans_from_cc_data(wusb_cbaf_cc_data_t *cc_data) -{ - mblk_t *pdata; - - if ((pdata = allocb(WUSB_CC_DATA_SIZE, BPRI_HI)) == NULL) { - - return (NULL); - } - - bcopy(fieldAssociationTypeId, pdata->b_wptr, 4); - pdata->b_wptr += 4; - *pdata->b_wptr++ = DRAW_BYTE(cc_data->AssociationTypeId, 0); - *pdata->b_wptr++ = DRAW_BYTE(cc_data->AssociationTypeId, 1); - - bcopy(fieldAssociationSubTypeId, pdata->b_wptr, 4); - pdata->b_wptr += 4; - *pdata->b_wptr++ = DRAW_BYTE(cc_data->AssociationSubTypeId, 0); - *pdata->b_wptr++ = DRAW_BYTE(cc_data->AssociationSubTypeId, 1); - - bcopy(fieldLength, pdata->b_wptr, 4); - pdata->b_wptr += 4; - *pdata->b_wptr++ = DRAW_BYTE(cc_data->Length, 0); - *pdata->b_wptr++ = DRAW_BYTE(cc_data->Length, 1); - *pdata->b_wptr++ = DRAW_BYTE(cc_data->Length, 2); - *pdata->b_wptr++ = DRAW_BYTE(cc_data->Length, 3); - - bcopy(fieldConnectionContext, pdata->b_wptr, 4); - pdata->b_wptr += 4; - bcopy(&(cc_data->CC), pdata->b_wptr, 48); - pdata->b_wptr += 48; - - bcopy(fieldBandGroups, pdata->b_wptr, 4); - pdata->b_wptr += 4; - *pdata->b_wptr++ = DRAW_BYTE(cc_data->BandGroups, 0); - *pdata->b_wptr++ = DRAW_BYTE(cc_data->BandGroups, 1); - - return (pdata); -} - -static mblk_t * -trans_from_cc_fail(wusb_cbaf_cc_fail_t *cc_fail) -{ - mblk_t *pdata; - - if ((pdata = allocb(WUSB_CC_FAILURE_SIZE, BPRI_HI)) == NULL) { - - return (NULL); - } - - bcopy(fieldAssociationTypeId, pdata->b_wptr, 4); - pdata->b_wptr += 4; - *pdata->b_wptr++ = DRAW_BYTE(cc_fail->AssociationTypeId, 0); - *pdata->b_wptr++ = DRAW_BYTE(cc_fail->AssociationTypeId, 1); - - bcopy(fieldAssociationSubTypeId, pdata->b_wptr, 4); - pdata->b_wptr += 4; - *pdata->b_wptr++ = DRAW_BYTE(cc_fail->AssociationSubTypeId, 0); - *pdata->b_wptr++ = DRAW_BYTE(cc_fail->AssociationSubTypeId, 1); - - bcopy(fieldLength, pdata->b_wptr, 4); - pdata->b_wptr += 4; - *pdata->b_wptr++ = DRAW_BYTE(cc_fail->Length, 0); - *pdata->b_wptr++ = DRAW_BYTE(cc_fail->Length, 1); - *pdata->b_wptr++ = DRAW_BYTE(cc_fail->Length, 2); - *pdata->b_wptr++ = DRAW_BYTE(cc_fail->Length, 3); - - bcopy(fieldAssociationStatus, pdata->b_wptr, 4); - pdata->b_wptr += 4; - *pdata->b_wptr++ = DRAW_BYTE(cc_fail->AssociationStatus, 0); - *pdata->b_wptr++ = DRAW_BYTE(cc_fail->AssociationStatus, 1); - *pdata->b_wptr++ = DRAW_BYTE(cc_fail->AssociationStatus, 2); - *pdata->b_wptr++ = DRAW_BYTE(cc_fail->AssociationStatus, 3); - - return (pdata); -} - -static int -trans_to_device_info(wusb_ca_state_t *wusb_cap, - mblk_t *pdata, wusb_cbaf_device_info_t *device_info) -{ - int i, plen; - void *paddr; - char *mode; - uchar_t *ptr = (uchar_t *)pdata->b_rptr; - wusb_cbaf_info_item_t item; - - for (i = 0; i < 5; i++) { - if (((int)usb_parse_data("ss", ptr, 4, &item, - sizeof (item))) <= 0) { - USB_DPRINTF_L2(PRINT_MASK_ALL, - wusb_cap->wusb_ca_log_hdl, - "parse item[%d] failed", i); - - return (-1); - } - ptr += 4; - - switch (item.typeID) { - case attrLength: - mode = "l"; - paddr = &(device_info->Length); - plen = sizeof (uint32_t); - - break; - case attrCDID: - mode = "16c"; - paddr = &(device_info->CDID); - plen = 16 * sizeof (uint8_t); - - break; - case attrBandGroups: - mode = "s"; - paddr = &(device_info->BandGroups); - plen = sizeof (uint16_t); - - break; - case attrLangID: - mode = "s"; - paddr = &(device_info->LangID); - plen = sizeof (uint16_t); - - break; - case attrDeviceFriendlyName: - mode = "l"; - paddr = &(device_info->DeviceFriendlyName); - plen = 64 * sizeof (char); - - break; - default: - USB_DPRINTF_L2(PRINT_MASK_ALL, - wusb_cap->wusb_ca_log_hdl, - "item[%d]: 0x%04x", i, item.typeID); - - return (-1); - } - - if (((int)usb_parse_data(mode, ptr, item.length, - paddr, plen)) <= 0) { - USB_DPRINTF_L2(PRINT_MASK_ALL, - wusb_cap->wusb_ca_log_hdl, - "item[%d]: 0x%04x", i, item.typeID); - - return (-1); - } - ptr += item.length; - } - - return (0); -} diff --git a/usr/src/uts/common/io/usb/clients/wusb_df/wusb_df.c b/usr/src/uts/common/io/usb/clients/wusb_df/wusb_df.c deleted file mode 100644 index 8dc8448f6a..0000000000 --- a/usr/src/uts/common/io/usb/clients/wusb_df/wusb_df.c +++ /dev/null @@ -1,1269 +0,0 @@ -/* - * 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 - * or http://www.opensolaris.org/os/licensing. - * 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. - */ - - -/* - * This driver is to be used for download firmware for devices. - */ - -#if defined(lint) && !defined(DEBUG) -#define DEBUG -#endif - -#define USBDRV_MAJOR_VER 2 -#define USBDRV_MINOR_VER 0 - -#include <sys/kobj.h> -#include <sys/usb/usba.h> -#include <sys/usb/usba/usbai_private.h> -#include <sys/usb/clients/wusb_df/wusb_df.h> - -#define WUSB_DF_INITIAL_SOFT_SPACE 1 -#define MAX_DAT_FILE_SIZE (512 * 1024) - -uint_t wusb_df_errlevel = USB_LOG_L4; -uint_t wusb_df_errmask = (uint_t)PRINT_MASK_ALL; -uint_t wusb_df_instance_debug = (uint_t)-1; -static char *name = "wusb_df"; /* Driver name, used all over. */ -static char wusb_fwmod[] = "hwa1480_fw"; -static char wusb_fwsym1[] = "hwa1480_fw"; - -/* Soft state structures */ -static void *wusb_df_statep; - -/* - * Function Prototypes - */ -static int wusb_df_attach(dev_info_t *, ddi_attach_cmd_t); -static int wusb_df_detach(dev_info_t *, ddi_detach_cmd_t); -static int wusb_df_info(dev_info_t *, ddi_info_cmd_t, void *, void **); -static int wusb_df_cleanup(dev_info_t *, wusb_df_state_t *); -static int wusb_df_disconnect_callback(dev_info_t *); -static int wusb_df_reconnect_callback(dev_info_t *); -static void wusb_df_restore_device_state(dev_info_t *, wusb_df_state_t *); -static int wusb_df_cpr_suspend(dev_info_t *); -static void wusb_df_cpr_resume(dev_info_t *); -static void wusb_df_pm_busy_component(wusb_df_state_t *); -static void wusb_df_pm_idle_component(wusb_df_state_t *); -static int wusb_df_power(dev_info_t *, int, int); -static void wusb_df_init_power_mgmt(wusb_df_state_t *); -static void wusb_df_destroy_power_mgmt(wusb_df_state_t *); -static int wusb_df_serialize_access(wusb_df_state_t *, boolean_t); -static void wusb_df_release_access(wusb_df_state_t *); -static int wusb_df_firmware_download(wusb_df_state_t *wusbp); - - -/* _NOTE is an advice for locklint. Locklint checks lock use for deadlocks. */ -_NOTE(SCHEME_PROTECTS_DATA("unique per call", usb_ctrl_req)) -_NOTE(SCHEME_PROTECTS_DATA("unique per call", buf)) - -/* module loading stuff */ -struct cb_ops wusb_df_cb_ops = { - nodev, /* open */ - nodev, /* close */ - nodev, /* strategy */ - nulldev, /* print */ - nulldev, /* dump */ - nodev, /* read */ - nodev, /* write */ - nodev, /* ioctl */ - nulldev, /* devmap */ - nodev, /* mmap */ - nodev, /* segmap */ - nochpoll, /* poll */ - ddi_prop_op, /* cb_prop_op */ - NULL, /* streamtab */ - D_MP -}; - -static struct dev_ops wusb_df_ops = { - DEVO_REV, /* devo_rev, */ - 0, /* refcnt */ - wusb_df_info, /* info */ - nulldev, /* identify */ - nulldev, /* probe */ - wusb_df_attach, /* attach */ - wusb_df_detach, /* detach */ - nodev, /* reset */ - &wusb_df_cb_ops, /* driver operations */ - NULL, /* bus operations */ - wusb_df_power /* power */ -}; - -static struct modldrv wusb_df_modldrv = { - &mod_driverops, - "WUSB firmware download", - &wusb_df_ops -}; - -static struct modlinkage modlinkage = { - MODREV_1, - &wusb_df_modldrv, - NULL -}; - -/* - * Descriptor for a record of firmware - */ -typedef struct fw_dsc { - uint32_t addr; - size_t size; - uint8_t *data; - struct fw_dsc *next; -} fw_dsc_t; - - -/* - * Module-wide initialization routine. - */ -int -_init(void) -{ - int rval; - - - if ((rval = ddi_soft_state_init(&wusb_df_statep, - sizeof (wusb_df_state_t), WUSB_DF_INITIAL_SOFT_SPACE)) != 0) { - - return (rval); - } - - if ((rval = mod_install(&modlinkage)) != 0) { - ddi_soft_state_fini(&wusb_df_statep); - } - - - return (rval); -} - - -/* - * Module-wide tear-down routine. - */ -int -_fini(void) -{ - int rval; - - if ((rval = mod_remove(&modlinkage)) != 0) { - - return (rval); - } - - ddi_soft_state_fini(&wusb_df_statep); - - return (rval); -} - - -int -_info(struct modinfo *modinfop) -{ - return (mod_info(&modlinkage, modinfop)); -} - -/* - * wusb_df_attach: - * Attach or resume. - * - * For attach, initialize state and device, including: - * state variables, locks, device node - * device registration with system - * power management, hotplugging - * For resume, restore device and state - */ -static int -wusb_df_attach(dev_info_t *dip, ddi_attach_cmd_t cmd) -{ - int instance = ddi_get_instance(dip); - char *devinst; - int devinstlen; - wusb_df_state_t *wusb_dfp = NULL; - usb_ep_data_t *ep_datap; - int status; - - switch (cmd) { - case DDI_ATTACH: - break; - - case DDI_RESUME: - wusb_df_cpr_resume(dip); - - /* - * Always return success to work around enumeration failures. - * This works around an issue where devices which are present - * before a suspend and absent upon resume could cause a system - * panic on resume. - */ - return (DDI_SUCCESS); - default: - return (DDI_FAILURE); - } - - if (ddi_soft_state_zalloc(wusb_df_statep, instance) == DDI_SUCCESS) { - wusb_dfp = ddi_get_soft_state(wusb_df_statep, instance); - } - if (wusb_dfp == NULL) { - - return (DDI_FAILURE); - } - - wusb_dfp->wusb_df_dip = dip; - - devinst = kmem_zalloc(USB_MAXSTRINGLEN, KM_SLEEP); - devinstlen = snprintf(devinst, USB_MAXSTRINGLEN, "%s%d: ", - ddi_driver_name(dip), instance); - - wusb_dfp->wusb_df_devinst = kmem_zalloc(devinstlen + 1, KM_SLEEP); - (void) strncpy(wusb_dfp->wusb_df_devinst, devinst, devinstlen); - kmem_free(devinst, USB_MAXSTRINGLEN); - - wusb_dfp->wusb_df_log_hdl = usb_alloc_log_hdl(dip, "wusb_df", - &wusb_df_errlevel, &wusb_df_errmask, &wusb_df_instance_debug, 0); - - USB_DPRINTF_L4(PRINT_MASK_ATTA, wusb_dfp->wusb_df_log_hdl, - "Attach: enter for attach"); - - if ((status = usb_client_attach(dip, USBDRV_VERSION, 0)) != - USB_SUCCESS) { - USB_DPRINTF_L2(PRINT_MASK_ATTA, wusb_dfp->wusb_df_log_hdl, - "attach: usb_client_attach failed, error code:%d", status); - goto fail; - } - - if ((status = usb_get_dev_data(dip, &wusb_dfp->wusb_df_reg, - USB_PARSE_LVL_ALL, 0)) != USB_SUCCESS) { - USB_DPRINTF_L2(PRINT_MASK_ATTA, wusb_dfp->wusb_df_log_hdl, - "attach: usb_get_dev_data failed, error code:%d", status); - goto fail; - } - - - /* - * Get the descriptor for an intr pipe at alt 0 of current interface. - * This will be used later to open the pipe. - */ - if ((ep_datap = usb_lookup_ep_data(dip, wusb_dfp->wusb_df_reg, - wusb_dfp->wusb_df_reg->dev_curr_if, 0, 0, - USB_EP_ATTR_INTR, USB_EP_DIR_IN)) == NULL) { - USB_DPRINTF_L2(PRINT_MASK_ATTA, wusb_dfp->wusb_df_log_hdl, - "attach: Error getting intr endpoint descriptor"); - goto fail; - } - wusb_dfp->wusb_df_intr_ep_descr = ep_datap->ep_descr; - - usb_free_descr_tree(dip, wusb_dfp->wusb_df_reg); - - mutex_init(&wusb_dfp->wusb_df_mutex, NULL, MUTEX_DRIVER, - wusb_dfp->wusb_df_reg->dev_iblock_cookie); - - cv_init(&wusb_dfp->wusb_df_serial_cv, NULL, CV_DRIVER, NULL); - wusb_dfp->wusb_df_serial_inuse = B_FALSE; - - wusb_dfp->wusb_df_locks_initialized = B_TRUE; - - /* create minor node */ - if (ddi_create_minor_node(dip, name, S_IFCHR, instance, - "wusb_df", 0) != DDI_SUCCESS) { - USB_DPRINTF_L2(PRINT_MASK_ATTA, wusb_dfp->wusb_df_log_hdl, - "attach: Error creating minor node"); - goto fail; - } - - /* Put online before PM init as can get power managed afterward. */ - wusb_dfp->wusb_df_dev_state = USB_DEV_ONLINE; - - /* initialize power management */ - wusb_df_init_power_mgmt(wusb_dfp); - - if (usb_register_hotplug_cbs(dip, wusb_df_disconnect_callback, - wusb_df_reconnect_callback) != USB_SUCCESS) { - - goto fail; - } - - /* Report device */ - ddi_report_dev(dip); - - (void) wusb_df_firmware_download(wusb_dfp); - - if (usb_reset_device(dip, USB_RESET_LVL_REATTACH) != USB_SUCCESS) { - USB_DPRINTF_L2(PRINT_MASK_PM, wusb_dfp->wusb_df_log_hdl, - "reset device failed"); - - return (USB_FAILURE); - } - - return (DDI_SUCCESS); - -fail: - if (wusb_dfp) { - (void) wusb_df_cleanup(dip, wusb_dfp); - } - - return (DDI_FAILURE); -} - - -/* - * wusb_df_detach: - * detach or suspend driver instance - * - * Note: in detach, only contention threads is from pm and disconnnect. - */ -static int -wusb_df_detach(dev_info_t *dip, ddi_detach_cmd_t cmd) -{ - int instance = ddi_get_instance(dip); - wusb_df_state_t *wusb_dfp = - ddi_get_soft_state(wusb_df_statep, instance); - int rval = DDI_FAILURE; - - switch (cmd) { - case DDI_DETACH: - - USB_DPRINTF_L4(PRINT_MASK_ATTA, wusb_dfp->wusb_df_log_hdl, - "Detach: enter for detach"); - - rval = wusb_df_cleanup(dip, wusb_dfp); - - break; - case DDI_SUSPEND: - USB_DPRINTF_L4(PRINT_MASK_ATTA, wusb_dfp->wusb_df_log_hdl, - "Detach: enter for suspend"); - - rval = wusb_df_cpr_suspend(dip); - default: - - break; - } - - return ((rval == USB_SUCCESS) ? DDI_SUCCESS : DDI_FAILURE); -} - - -/* - * wusb_df_cleanup: - * clean up the driver state for detach - */ -static int -wusb_df_cleanup(dev_info_t *dip, wusb_df_state_t *wusb_dfp) -{ - - USB_DPRINTF_L3(PRINT_MASK_ATTA, wusb_dfp->wusb_df_log_hdl, - "Cleanup: enter"); - - if (wusb_dfp->wusb_df_locks_initialized) { - - /* This must be done 1st to prevent more events from coming. */ - usb_unregister_hotplug_cbs(dip); - - /* - * At this point, no new activity can be initiated. The driver - * has disabled hotplug callbacks. The Solaris framework has - * disabled new opens on a device being detached, and does not - * allow detaching an open device. - * - * The following ensures that all driver activity has drained. - */ - mutex_enter(&wusb_dfp->wusb_df_mutex); - (void) wusb_df_serialize_access(wusb_dfp, WUSB_DF_SER_NOSIG); - wusb_df_release_access(wusb_dfp); - mutex_exit(&wusb_dfp->wusb_df_mutex); - - /* All device activity has died down. */ - wusb_df_destroy_power_mgmt(wusb_dfp); - - /* start dismantling */ - ddi_remove_minor_node(dip, NULL); - - cv_destroy(&wusb_dfp->wusb_df_serial_cv); - mutex_destroy(&wusb_dfp->wusb_df_mutex); - } - - usb_client_detach(dip, wusb_dfp->wusb_df_reg); - - usb_free_log_hdl(wusb_dfp->wusb_df_log_hdl); - - if (wusb_dfp->wusb_df_devinst != NULL) { - kmem_free(wusb_dfp->wusb_df_devinst, - strlen(wusb_dfp->wusb_df_devinst) + 1); - } - - ddi_soft_state_free(wusb_df_statep, ddi_get_instance(dip)); - ddi_prop_remove_all(dip); - - return (USB_SUCCESS); -} - - -/* - * wusb_df_disconnect_callback: - * Called when device hotplug-removed. - * Close pipes. (This does not attempt to contact device.) - * Set state to DISCONNECTED - */ -static int -wusb_df_disconnect_callback(dev_info_t *dip) -{ - int instance = ddi_get_instance(dip); - wusb_df_state_t *wusb_dfp = - ddi_get_soft_state(wusb_df_statep, instance); - - - USB_DPRINTF_L4(PRINT_MASK_CB, wusb_dfp->wusb_df_log_hdl, - "disconnect: enter"); - - mutex_enter(&wusb_dfp->wusb_df_mutex); - (void) wusb_df_serialize_access(wusb_dfp, WUSB_DF_SER_NOSIG); - - /* - * Save any state of device or IO in progress required by - * wusb_df_restore_device_state for proper device "thawing" later. - */ - wusb_dfp->wusb_df_dev_state = USB_DEV_DISCONNECTED; - - wusb_df_release_access(wusb_dfp); - mutex_exit(&wusb_dfp->wusb_df_mutex); - - return (USB_SUCCESS); -} - - -/* - * wusb_df_reconnect_callback: - * Called with device hotplug-inserted - * Restore state - */ -static int -wusb_df_reconnect_callback(dev_info_t *dip) -{ - int instance = ddi_get_instance(dip); - wusb_df_state_t *wusb_dfp = - ddi_get_soft_state(wusb_df_statep, instance); - - USB_DPRINTF_L4(PRINT_MASK_ATTA, wusb_dfp->wusb_df_log_hdl, - "reconnect: enter"); - - wusb_df_pm_busy_component(wusb_dfp); - (void) pm_raise_power(wusb_dfp->wusb_df_dip, 0, USB_DEV_OS_FULL_PWR); - - mutex_enter(&wusb_dfp->wusb_df_mutex); - (void) wusb_df_serialize_access(wusb_dfp, WUSB_DF_SER_NOSIG); - wusb_df_restore_device_state(dip, wusb_dfp); - wusb_df_release_access(wusb_dfp); - mutex_exit(&wusb_dfp->wusb_df_mutex); - - wusb_df_pm_idle_component(wusb_dfp); - - return (USB_SUCCESS); -} - - -/* - * wusb_df_restore_device_state: - * Called during hotplug-reconnect and resume. - * reenable power management - * Verify the device is the same as before the disconnect/suspend. - * Restore device state - * Thaw any IO which was frozen. - * Quiesce device. (Other routines will activate if thawed IO.) - * Set device online. - * Leave device disconnected if there are problems. - */ -static void -wusb_df_restore_device_state(dev_info_t *dip, wusb_df_state_t *wusb_dfp) -{ - USB_DPRINTF_L2(PRINT_MASK_PM, wusb_dfp->wusb_df_log_hdl, - "wusb_df_restore_device_state: enter"); - - ASSERT(mutex_owned(&wusb_dfp->wusb_df_mutex)); - - ASSERT((wusb_dfp->wusb_df_dev_state == USB_DEV_DISCONNECTED) || - (wusb_dfp->wusb_df_dev_state == USB_DEV_SUSPENDED)); - - mutex_exit(&wusb_dfp->wusb_df_mutex); - - - /* Check if we are talking to the same device */ - if (usb_check_same_device(dip, wusb_dfp->wusb_df_log_hdl, - USB_LOG_L0, PRINT_MASK_ALL, - USB_CHK_ALL, NULL) != USB_SUCCESS) { - - /* change the device state from suspended to disconnected */ - mutex_enter(&wusb_dfp->wusb_df_mutex); - wusb_dfp->wusb_df_dev_state = USB_DEV_SUSPENDED; - USB_DPRINTF_L2(PRINT_MASK_PM, wusb_dfp->wusb_df_log_hdl, - "wusb_df_restore_device_state: check same device failed"); - return; - } - - mutex_enter(&wusb_dfp->wusb_df_mutex); - wusb_dfp->wusb_df_dev_state = USB_DEV_ONLINE; - - if (wusb_dfp->wusb_df_pm && - wusb_dfp->wusb_df_pm->wusb_df_wakeup_enabled) { - - /* Failure here means device disappeared again. */ - mutex_exit(&wusb_dfp->wusb_df_mutex); - if (usb_handle_remote_wakeup(dip, USB_REMOTE_WAKEUP_ENABLE) != - USB_SUCCESS) { - USB_DPRINTF_L2(PRINT_MASK_PM, wusb_dfp->wusb_df_log_hdl, - "device may or may not be accessible. " - "Please verify reconnection"); - } - mutex_enter(&wusb_dfp->wusb_df_mutex); - } - - - USB_DPRINTF_L4(PRINT_MASK_PM, wusb_dfp->wusb_df_log_hdl, - "wusb_df_restore_device_state: end"); - -} - - -/* - * wusb_df_cpr_suspend: - * Clean up device. - * Wait for any IO to finish, then close pipes. - * Quiesce device. - */ -static int -wusb_df_cpr_suspend(dev_info_t *dip) -{ - int instance = ddi_get_instance(dip); - wusb_df_state_t *wusb_dfp = - ddi_get_soft_state(wusb_df_statep, instance); - - USB_DPRINTF_L4(PRINT_MASK_ATTA, wusb_dfp->wusb_df_log_hdl, - "suspend enter"); - - /* Serialize to prevent races with detach, open, device access. */ - mutex_enter(&wusb_dfp->wusb_df_mutex); - (void) wusb_df_serialize_access(wusb_dfp, WUSB_DF_SER_NOSIG); - mutex_exit(&wusb_dfp->wusb_df_mutex); - - wusb_df_pm_busy_component(wusb_dfp); - - mutex_enter(&wusb_dfp->wusb_df_mutex); - - /* Access device here to clean it up. */ - - wusb_dfp->wusb_df_dev_state = USB_DEV_SUSPENDED; - - /* - * Save any state of device required by wusb_df_restore_device_state - * for proper device "thawing" later. - */ - - wusb_df_release_access(wusb_dfp); - mutex_exit(&wusb_dfp->wusb_df_mutex); - - wusb_df_pm_idle_component(wusb_dfp); - - USB_DPRINTF_L4(PRINT_MASK_ATTA, wusb_dfp->wusb_df_log_hdl, - "suspend: success"); - - return (USB_SUCCESS); -} - - -/* - * wusb_df_cpr_resume: - * - * wusb_df_restore_device_state marks success by putting device back online - */ -static void -wusb_df_cpr_resume(dev_info_t *dip) -{ - int instance = ddi_get_instance(dip); - wusb_df_state_t *wusb_dfp = - ddi_get_soft_state(wusb_df_statep, instance); - - USB_DPRINTF_L4(PRINT_MASK_CPR, wusb_dfp->wusb_df_log_hdl, - "resume: enter"); - - /* - * NOTE: A pm_raise_power in wusb_df_restore_device_state will bring - * the power-up state of device into synch with the system. - */ - wusb_df_pm_busy_component(wusb_dfp); - (void) pm_raise_power(wusb_dfp->wusb_df_dip, 0, USB_DEV_OS_FULL_PWR); - mutex_enter(&wusb_dfp->wusb_df_mutex); - wusb_df_restore_device_state(dip, wusb_dfp); - mutex_exit(&wusb_dfp->wusb_df_mutex); - wusb_df_pm_idle_component(wusb_dfp); -} - -static void -wusb_df_pm_busy_component(wusb_df_state_t *wusb_dfp) -{ - ASSERT(!mutex_owned(&wusb_dfp->wusb_df_mutex)); - - mutex_enter(&wusb_dfp->wusb_df_mutex); - if (wusb_dfp->wusb_df_pm == NULL) { - USB_DPRINTF_L4(PRINT_MASK_PM, wusb_dfp->wusb_df_log_hdl, - "wusb_df_pm_busy_component: pm = NULL"); - goto done; - } - - wusb_dfp->wusb_df_pm->wusb_df_pm_busy++; - USB_DPRINTF_L4(PRINT_MASK_PM, wusb_dfp->wusb_df_log_hdl, - "wusb_df_pm_busy_component: %d", - wusb_dfp->wusb_df_pm->wusb_df_pm_busy); - - mutex_exit(&wusb_dfp->wusb_df_mutex); - - if (pm_busy_component(wusb_dfp->wusb_df_dip, 0) != DDI_SUCCESS) { - mutex_enter(&wusb_dfp->wusb_df_mutex); - wusb_dfp->wusb_df_pm->wusb_df_pm_busy--; - - USB_DPRINTF_L4(PRINT_MASK_PM, wusb_dfp->wusb_df_log_hdl, - "wusb_df_pm_busy_component: %d", - wusb_dfp->wusb_df_pm->wusb_df_pm_busy); - mutex_exit(&wusb_dfp->wusb_df_mutex); - - - } - return; -done: - mutex_exit(&wusb_dfp->wusb_df_mutex); - -} - -static void -wusb_df_pm_idle_component(wusb_df_state_t *wusb_dfp) -{ - ASSERT(!mutex_owned(&wusb_dfp->wusb_df_mutex)); - mutex_enter(&wusb_dfp->wusb_df_mutex); - if (wusb_dfp->wusb_df_pm == NULL) { - mutex_exit(&wusb_dfp->wusb_df_mutex); - return; - } - mutex_exit(&wusb_dfp->wusb_df_mutex); - - - if (pm_idle_component(wusb_dfp->wusb_df_dip, 0) == DDI_SUCCESS) { - mutex_enter(&wusb_dfp->wusb_df_mutex); - ASSERT(wusb_dfp->wusb_df_pm->wusb_df_pm_busy > 0); - wusb_dfp->wusb_df_pm->wusb_df_pm_busy--; - - USB_DPRINTF_L4(PRINT_MASK_PM, wusb_dfp->wusb_df_log_hdl, - "wusb_df_pm_idle_component: %d", - wusb_dfp->wusb_df_pm->wusb_df_pm_busy); - - mutex_exit(&wusb_dfp->wusb_df_mutex); - } -} - -/* - * wusb_df_power : - * Power entry point, the workhorse behind pm_raise_power, pm_lower_power, - * usb_req_raise_power and usb_req_lower_power. - */ -/* ARGSUSED */ -static int -wusb_df_power(dev_info_t *dip, int comp, int level) -{ - wusb_df_state_t *wusb_dfp; - wusb_df_power_t *pm; - int rval = USB_SUCCESS; - - wusb_dfp = ddi_get_soft_state(wusb_df_statep, ddi_get_instance(dip)); - - USB_DPRINTF_L3(PRINT_MASK_PM, wusb_dfp->wusb_df_log_hdl, - "wusb_df_power: enter: level = %d", level); - - mutex_enter(&wusb_dfp->wusb_df_mutex); - (void) wusb_df_serialize_access(wusb_dfp, WUSB_DF_SER_NOSIG); - - - /* - * If we are disconnected/suspended, return success. Note that if we - * return failure, bringing down the system will hang when - * PM tries to power up all devices - */ - if ((wusb_dfp->wusb_df_dev_state == USB_DEV_DISCONNECTED) || - (wusb_dfp->wusb_df_dev_state == USB_DEV_SUSPENDED)) { - - USB_DPRINTF_L3(PRINT_MASK_PM, wusb_dfp->wusb_df_log_hdl, - "wusb_df_power: disconnected/suspended " - "dev_state=%d", wusb_dfp->wusb_df_dev_state); - rval = USB_SUCCESS; - - goto done; - } - - if (wusb_dfp->wusb_df_pm == NULL) { - - goto done; - } - - pm = wusb_dfp->wusb_df_pm; - - /* Check if we are transitioning to a legal power level */ - if (USB_DEV_PWRSTATE_OK(pm->wusb_df_pwr_states, level)) { - USB_DPRINTF_L3(PRINT_MASK_PM, wusb_dfp->wusb_df_log_hdl, - "wusb_df_power: illegal power level = %d " - "pwr_states: %x", level, pm->wusb_df_pwr_states); - - goto done; - } - - switch (level) { - case USB_DEV_OS_PWR_OFF : - /* fail attempt to go to low power if busy */ - if (pm->wusb_df_pm_busy) { - - goto done; - } - if (wusb_dfp->wusb_df_dev_state == USB_DEV_ONLINE) { - wusb_dfp->wusb_df_dev_state = USB_DEV_PWRED_DOWN; - wusb_dfp->wusb_df_pm->wusb_df_current_power = - USB_DEV_OS_PWR_OFF; - } else { - rval = USB_SUCCESS; - } - break; - - case USB_DEV_OS_FULL_PWR : - /* - * PM framework tries to put us in full power during system - * shutdown. - */ - wusb_dfp->wusb_df_dev_state = USB_DEV_ONLINE; - wusb_dfp->wusb_df_pm->wusb_df_current_power = - USB_DEV_OS_FULL_PWR; - break; - - /* Levels 1 and 2 are not supported by this driver to keep it simple. */ - default: - USB_DPRINTF_L3(PRINT_MASK_PM, wusb_dfp->wusb_df_log_hdl, - "wusb_df_power: power level %d not supported", level); - break; - } -done: - wusb_df_release_access(wusb_dfp); - mutex_exit(&wusb_dfp->wusb_df_mutex); - - return ((rval == USB_SUCCESS) ? DDI_SUCCESS : DDI_FAILURE); -} - - -/* - * wusb_df_init_power_mgmt: - * Initialize power management and remote wakeup functionality. - * No mutex is necessary in this function as it's called only by attach. - */ -static void -wusb_df_init_power_mgmt(wusb_df_state_t *wusb_dfp) -{ - wusb_df_power_t *wusb_dfpm; - uint_t pwr_states; - - USB_DPRINTF_L4(PRINT_MASK_PM, wusb_dfp->wusb_df_log_hdl, - "init_power_mgmt enter"); - - /* - * If remote wakeup is not available you may not want to do - * power management. - */ - /* Allocate the state structure */ - wusb_dfpm = kmem_zalloc(sizeof (wusb_df_power_t), KM_SLEEP); - wusb_dfp->wusb_df_pm = wusb_dfpm; - wusb_dfpm->wusb_df_state = wusb_dfp; - wusb_dfpm->wusb_df_pm_capabilities = 0; - wusb_dfpm->wusb_df_current_power = USB_DEV_OS_FULL_PWR; - - if (usb_create_pm_components(wusb_dfp->wusb_df_dip, &pwr_states) == - USB_SUCCESS) { - - USB_DPRINTF_L4(PRINT_MASK_PM, wusb_dfp->wusb_df_log_hdl, - "wusb_df_init_power_mgmt: created PM components"); - - wusb_dfpm->wusb_df_pwr_states = (uint8_t)pwr_states; - (void) pm_raise_power(wusb_dfp->wusb_df_dip, 0, - USB_DEV_OS_FULL_PWR); - - if (usb_handle_remote_wakeup(wusb_dfp->wusb_df_dip, - USB_REMOTE_WAKEUP_ENABLE) == USB_SUCCESS) { - wusb_dfpm->wusb_df_wakeup_enabled = 1; - } else { - USB_DPRINTF_L2(PRINT_MASK_PM, wusb_dfp->wusb_df_log_hdl, - "wusb_df_init_power_mgmt:" - "fail to enable remote wakeup"); - } - - } else { - USB_DPRINTF_L2(PRINT_MASK_PM, wusb_dfp->wusb_df_log_hdl, - "wusb_df_init_power_mgmt: create_pm_compts failed"); - } - USB_DPRINTF_L4(PRINT_MASK_PM, wusb_dfp->wusb_df_log_hdl, - "wusb_df_init_power_mgmt: end"); - -} - - -/* - * wusb_df_destroy_power_mgmt: - * Shut down and destroy power management and remote wakeup functionality. - */ -static void -wusb_df_destroy_power_mgmt(wusb_df_state_t *wusb_dfp) -{ - USB_DPRINTF_L4(PRINT_MASK_PM, wusb_dfp->wusb_df_log_hdl, - "destroy_power_mgmt enter"); - - ASSERT(!mutex_owned(&wusb_dfp->wusb_df_mutex)); - - mutex_enter(&wusb_dfp->wusb_df_mutex); - if (!wusb_dfp->wusb_df_pm) { - mutex_exit(&wusb_dfp->wusb_df_mutex); - return; - } - mutex_exit(&wusb_dfp->wusb_df_mutex); - - (void) wusb_df_pm_busy_component(wusb_dfp); - - mutex_enter(&wusb_dfp->wusb_df_mutex); - if (wusb_dfp->wusb_df_dev_state != USB_DEV_DISCONNECTED) { - - if (wusb_dfp->wusb_df_pm->wusb_df_wakeup_enabled) { - mutex_exit(&wusb_dfp->wusb_df_mutex); - - (void) pm_raise_power(wusb_dfp->wusb_df_dip, 0, - USB_DEV_OS_FULL_PWR); - if (usb_handle_remote_wakeup(wusb_dfp->wusb_df_dip, - USB_REMOTE_WAKEUP_DISABLE) != USB_SUCCESS) { - USB_DPRINTF_L2(PRINT_MASK_PM, - wusb_dfp->wusb_df_log_hdl, - "wusb_df_destroy_power_mgmt: " - "Error disabling rmt wakeup"); - } - mutex_enter(&wusb_dfp->wusb_df_mutex); - - } - } - mutex_exit(&wusb_dfp->wusb_df_mutex); - - /* - * Since remote wakeup is disabled now, - * no one can raise power - * and get to device once power is lowered here. - */ - (void) pm_lower_power(wusb_dfp->wusb_df_dip, 0, USB_DEV_OS_PWR_OFF); - wusb_df_pm_idle_component(wusb_dfp); - - mutex_enter(&wusb_dfp->wusb_df_mutex); - kmem_free(wusb_dfp->wusb_df_pm, sizeof (wusb_df_power_t)); - wusb_dfp->wusb_df_pm = NULL; - mutex_exit(&wusb_dfp->wusb_df_mutex); -} - - -/* - * wusb_df_serialize_access: - * Get the serial synchronization object before returning. - * - * Arguments: - * wusb_dfp - Pointer to wusb_df state structure - * waitsig - Set to: - * WUSB_DF_SER_SIG - to wait such that a signal can interrupt - * WUSB_DF_SER_NOSIG - to wait such that a signal cannot interrupt - */ -static int -wusb_df_serialize_access(wusb_df_state_t *wusb_dfp, boolean_t waitsig) -{ - int rval = 1; - - ASSERT(mutex_owned(&wusb_dfp->wusb_df_mutex)); - - while (wusb_dfp->wusb_df_serial_inuse) { - if (waitsig == WUSB_DF_SER_SIG) { - rval = cv_wait_sig(&wusb_dfp->wusb_df_serial_cv, - &wusb_dfp->wusb_df_mutex); - } else { - cv_wait(&wusb_dfp->wusb_df_serial_cv, - &wusb_dfp->wusb_df_mutex); - } - } - wusb_dfp->wusb_df_serial_inuse = B_TRUE; - - return (rval); -} - - -/* - * wusb_df_release_access: - * Release the serial synchronization object. - */ -static void -wusb_df_release_access(wusb_df_state_t *wusb_dfp) -{ - ASSERT(mutex_owned(&wusb_dfp->wusb_df_mutex)); - wusb_dfp->wusb_df_serial_inuse = B_FALSE; - cv_broadcast(&wusb_dfp->wusb_df_serial_cv); -} - -/* - * wusb_df_info: - * Get minor number, soft state structure, etc. - */ -/*ARGSUSED*/ -static int -wusb_df_info(dev_info_t *dip, ddi_info_cmd_t infocmd, - void *arg, void **result) -{ - wusb_df_state_t *wusb_dfp; - int error = DDI_FAILURE; - - switch (infocmd) { - case DDI_INFO_DEVT2DEVINFO: - if ((wusb_dfp = ddi_get_soft_state(wusb_df_statep, - getminor((dev_t)arg))) != NULL) { - *result = wusb_dfp->wusb_df_dip; - if (*result != NULL) { - error = DDI_SUCCESS; - } - } else { - *result = NULL; - } - break; - case DDI_INFO_DEVT2INSTANCE: - *result = (void *)(uintptr_t)getminor((dev_t)arg); - error = DDI_SUCCESS; - break; - default: - break; - } - - return (error); -} - -/* Free a chain of firmware headers */ -static void -free_fw_dscs(struct fw_dsc *head) -{ - struct fw_dsc *next; - - while (head) { - next = head->next; - kmem_free(head, sizeof (fw_dsc_t)); - head = next; - } -} - -static unsigned int -char2int32(unsigned char *input) -{ - return ((*input) | - (*(input + 1) << 8) | - (*(input + 2) << 16) | - (*(input + 3) << 24)); -} - -/* - * download firmware or command by control pipe - */ -static int -wusb_df_send_data(wusb_df_state_t *wusbp, - unsigned int address, - const unsigned char *buffer, - unsigned int size) -{ - int error = DDI_FAILURE; - usb_ctrl_setup_t setup; - usb_cb_flags_t cb_flags; - usb_cr_t cr; - mblk_t *data = NULL; /* data for USBA */ - uint16_t data_len; /* # of bytes want to write */ - uint_t cnt; /* # of xfered bytes */ - - setup.bmRequestType = USB_DEV_REQ_TYPE_VENDOR | - USB_DEV_REQ_HOST_TO_DEV | USB_DEV_REQ_RCPT_DEV; - setup.bRequest = 0xf0; - setup.attrs = 0; - - for (cnt = 0; cnt < size; cnt += data_len) { - data_len = min(size - cnt, 512); - - /* reuse previous mblk if possible */ - if ((data = reallocb(data, data_len, 0)) == NULL) { - - return (USB_FAILURE); - } - bcopy(buffer + cnt, data->b_rptr, data_len); - data->b_wptr += data_len; - - setup.wValue = (address + cnt) & 0xffff; - setup.wIndex = ((address + cnt) >> 16) & 0xffff; - setup.wLength = data_len; - error = usb_pipe_ctrl_xfer_wait( - wusbp->wusb_df_reg->dev_default_ph, &setup, &data, - &cr, &cb_flags, 0); - if (error != USB_SUCCESS) { - USB_DPRINTF_L2(PRINT_MASK_ATTA, wusbp->wusb_df_log_hdl, - "wusb_df_send_data: " - "send failed rval=%d, cr=%d, cb=0x%x\n", - error, cr, cb_flags); - - break; - } - } - - if (data) { - freemsg(data); - } - - return (error); -} - -/* - * find the firmware module's "_start", "_end" symbols - * and get the size of firmware. - */ -static int -wusbdf_mod_loadsym(wusb_df_state_t *dfp, ddi_modhandle_t modp, char *mod, - char *sym, char **start, size_t *len) -{ - char start_sym[256]; - char end_sym[256]; - char *p, *end; - int rv; - size_t n; - - (void) snprintf(start_sym, sizeof (start_sym), "%s_start", sym); - (void) snprintf(end_sym, sizeof (end_sym), "%s_end", sym); - - p = (char *)ddi_modsym(modp, start_sym, &rv); - if (p == NULL || rv != 0) { - USB_DPRINTF_L2(PRINT_MASK_ATTA, dfp->wusb_df_log_hdl, - "mod %s: symbol %s not found\n", mod, start_sym); - return (-1); - } - end = (char *)ddi_modsym(modp, end_sym, &rv); - if (end == NULL || rv != 0) { - USB_DPRINTF_L2(PRINT_MASK_ATTA, dfp->wusb_df_log_hdl, - "mod %s: symbol %s not found\n", mod, end_sym); - return (-1); - } - n = end - p; - - *start = p; - *len = n; - - return (0); -} - -/* write firmware segments into device through control endpoint */ -static int -wusb_df_fw_download(wusb_df_state_t *wusb_dfp) -{ - int error = USB_SUCCESS; - size_t size = 0, record_cnt = 0; - unsigned char *pdata, *data_end; - unsigned char *firmware_image; - fw_dsc_t *pdsc = NULL, *rcd_head = NULL, *tmpr = NULL; - unsigned int remaining_size; - int rv = 0; - ddi_modhandle_t modp; - char *firm_start; - - USB_DPRINTF_L3(PRINT_MASK_ATTA, wusb_dfp->wusb_df_log_hdl, - "Download firmware: %s", wusb_fwmod); - - /* allow user specify firmware in .conf? */ - - /* see elfwrap(1) for how to turn firmware into loadable module */ - modp = ddi_modopen(wusb_fwmod, KRTLD_MODE_FIRST, &rv); - if (modp == NULL) { - USB_DPRINTF_L2(PRINT_MASK_ATTA, wusb_dfp->wusb_df_log_hdl, - "module %s not found", wusb_fwmod); - - error = USB_FAILURE; - goto checkstatus; - } - - rv = wusbdf_mod_loadsym(wusb_dfp, modp, wusb_fwmod, wusb_fwsym1, - &firm_start, &size); - if (rv != 0) { - USB_DPRINTF_L2(PRINT_MASK_ATTA, wusb_dfp->wusb_df_log_hdl, - "module(%s) loadsym error", wusb_fwmod); - - error = USB_FAILURE; - goto checkstatus; - } - - if (size >= MAX_DAT_FILE_SIZE) { - USB_DPRINTF_L2(PRINT_MASK_ATTA, wusb_dfp->wusb_df_log_hdl, - "file size too big"); - - error = USB_FAILURE; - goto checkstatus; - } else { - firmware_image = (unsigned char *)kmem_alloc(size, KM_SLEEP); - - if (!firmware_image) { - USB_DPRINTF_L2(PRINT_MASK_ATTA, - wusb_dfp->wusb_df_log_hdl, "malloc failed"); - - error = USB_FAILURE; - goto checkstatus; - } - - (void) memcpy(firmware_image, firm_start, size); - } - - USB_DPRINTF_L3(PRINT_MASK_ATTA, wusb_dfp->wusb_df_log_hdl, - "file size = %d", (int)size); - - /* - * close the module, return if 1) fail to close or 2) encounter error - * when getting above symbol - */ -checkstatus: - if (modp != NULL) - rv = ddi_modclose(modp); - - if ((rv != 0) || (error != USB_SUCCESS)) { - USB_DPRINTF_L2(PRINT_MASK_ATTA, wusb_dfp->wusb_df_log_hdl, - "modclose(%s) error", wusb_fwmod); - - return (USB_FAILURE); - } - - /* - * BIN firmware has this format: - * address(4B) + length(4B) + data(Length Bytes) ... repeat - */ - pdata = firmware_image; - data_end = firmware_image + size; - while (pdata < data_end) { - error = USB_FAILURE; - pdsc = (fw_dsc_t *)kmem_zalloc(sizeof (fw_dsc_t), KM_SLEEP); - - /* hdr_offset = pdata - firmware_image; */ - remaining_size = data_end - pdata; - - if ((pdata + 8) > data_end) { - kmem_free(pdsc, sizeof (fw_dsc_t)); - free_fw_dscs(rcd_head); - break; - } - - pdsc->next = NULL; - pdsc->addr = char2int32(pdata); - pdsc->size = 4 * char2int32(pdata + 4); - pdsc->data = pdata + 8; - if (pdsc->size > remaining_size) { - kmem_free(pdsc, sizeof (fw_dsc_t)); - free_fw_dscs(rcd_head); - break; - } - USB_DPRINTF_L3(PRINT_MASK_ATTA, wusb_dfp->wusb_df_log_hdl, - "address = 0x%x, length = 0x%x, " - "first 4 byte is : 0x%02x 0x%02x 0x%02x 0x%02x", - pdsc->addr, (int)pdsc->size, pdsc->data[0], pdsc->data[1], - pdsc->data[2], pdsc->data[3]); - - pdata += 8 + pdsc->size; - if (rcd_head == NULL) { - rcd_head = pdsc; - } else { - tmpr->next = pdsc; - } - - tmpr = pdsc; /* tmp record */ - record_cnt ++; - error = USB_SUCCESS; - } - - USB_DPRINTF_L3(PRINT_MASK_ATTA, wusb_dfp->wusb_df_log_hdl, - "Start download firmware ..."); - for (pdsc = rcd_head; pdsc != NULL; pdsc = pdsc->next) { - error = wusb_df_send_data(wusb_dfp, pdsc->addr, - pdsc->data, pdsc->size); - if (error != USB_SUCCESS) { - - USB_DPRINTF_L2(PRINT_MASK_ATTA, - wusb_dfp->wusb_df_log_hdl, "Download failure!"); - break; - } - - delay(drv_usectohz(1000)); - } - - USB_DPRINTF_L2(PRINT_MASK_ATTA, wusb_dfp->wusb_df_log_hdl, - "Download firmware end."); - - free_fw_dscs(rcd_head); - kmem_free(firmware_image, size); - - return (error); -} - - -/* - * Firmware download. Program device special registers and then call - * wusb_df_fw_download() to download the true data. - */ -static int -wusb_df_firmware_download(wusb_df_state_t *wusbp) -{ - int error = USB_FAILURE; - unsigned char buf[4]; - - (void) memset(buf, 0, 4); - /* program the device register to make it ready to accept fw */ - error = wusb_df_send_data(wusbp, 0x800000c0, buf, 4); - if (error != USB_SUCCESS) { - USB_DPRINTF_L2(PRINT_MASK_ATTA, wusbp->wusb_df_log_hdl, - "Fail init"); - return (error); - } - - error = wusb_df_fw_download(wusbp); - if (error != USB_SUCCESS) { - USB_DPRINTF_L2(PRINT_MASK_ATTA, wusbp->wusb_df_log_hdl, - "Fail to download firmware"); - return (error); - } - - buf[0] = 0x48; - buf[1] = 0x56; - buf[2] = 0x2c; - buf[3] = 0x00; - error = wusb_df_send_data(wusbp, 0x80008060, buf, 4); - if (error != USB_SUCCESS) { - return (error); - } - - (void) memset(buf, 0, 4); - buf[0] = 0x18; - /* firmware download finished, program the device to lock fw */ - error = wusb_df_send_data(wusbp, 0x800000c0, buf, 4); - - return (error); -} diff --git a/usr/src/uts/common/io/usb/hwa/hwahc/hwahc.c b/usr/src/uts/common/io/usb/hwa/hwahc/hwahc.c deleted file mode 100644 index 9ca1fa0f54..0000000000 --- a/usr/src/uts/common/io/usb/hwa/hwahc/hwahc.c +++ /dev/null @@ -1,6183 +0,0 @@ -/* - * 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 - * or http://www.opensolaris.org/os/licensing. - * 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. - */ -/* - * Copyright 2012 Garrett D'Amore <garrett@damore.org>. All rights reserved. - */ - -/* - * The Data Transfer Interface driver for Host Wire Adapter device - * - * HWA device has two interfaces, one is the data transfer interface, - * another is the radio control interface. This driver (hwahc) is only - * for data transfer interface support, but it depends on the radio - * control interface driver (hwarc) to work. That means the hwarc - * driver must be loaded while the hwahc is working. This is now - * ensured by holding hwarc open until hwahc detaches or powers down. - * - * The data transfer interface has three endpoints besides the default - * control endpoint which is shared between the two interfaces. The - * three endpoints are: - * - * - notification endpoint (intr in type, for asynchronous event - * notifications and transfer status notifications) - * - * - data transfer OUT endpoint (bulk out type, for sending transfer - * requests and transfer data from the host to the HWA device) - * - * - data transfer IN endpoint (bulk in type, for returning transfer - * status and transfer data from the HWA device to the host) - * - * The HWA device is a USB 2.0 device, so it supports the standard USB - * requests defined in chapter 9 of USB 2.0 specification as other USB - * client devices. But its most important functionality is to work as - * a wireless USB host. This means the hwahc driver needs to supply - * host controller functionalities, which include children hotplug - * support and data transfer support to children device endpoints. - * - * So hwahc driver is implemented as a nexus driver and it follows the - * event mechanism in existing USBA framework to support children - * hotplug events. - * - * The hwahc driver works as the root-hub on wireless USB bus. And it - * relays data transfers to/from wireless bus to the USB bus where ehci/ - * ohci/uhci works as the root-hub. This makes a bus cascading topology. - * - * The data transfer to/from wireless device endpoints is implemented by - * remote pipe (rpipe) mechanism. The rpipe descriptor on the HWA defines - * the attributes of a wireless USB transfer, such as the transfer type, - * the target device address, the target endpoint address and the max - * packet size. And the transfer requests through data transfer OUT - * endpoint will take a certain rpipe as the transfer target, thus - * fulfills the data transfer across buses. Refer to chapter 8 of WUSB - * 1.0 specification for details of this. - */ - -#define USBDRV_MAJOR_VER 2 -#define USBDRV_MINOR_VER 0 - -#include <sys/usb/hwa/hwahc/hwahc.h> -#include <sys/usb/hwa/hwahc/hwahc_util.h> -#include <sys/usb/usba/wa.h> -#include <sys/usb/usba/wusba.h> -#include <sys/usb/usba/whcdi.h> -#include <sys/usb/usba.h> -#include <sys/usb/usba/usba_impl.h> -#include <sys/usb/usba/usba_devdb.h> /* for usba_devdb_refresh */ -#include <sys/usb/hubd/hubdvar.h> -#include <sys/usb/hubd/hubd_impl.h> /* for hubd_ioctl_data_t */ -#include <sys/strsubr.h> /* for allocb_wait */ -#include <sys/strsun.h> /* for MBLKL macro */ -#include <sys/fs/dv_node.h> /* for devfs_clean */ -#include <sys/uwb/uwbai.h> /* for uwb ioctls */ -#include <sys/random.h> - -void *hwahc_statep; - -/* number of instances */ -#define HWAHC_INSTS 1 - -/* default value for set number DNTS slots request */ -#define HWAHC_DEFAULT_DNTS_INTERVAL 2 /* ms */ -#define HWAHC_DEFAULT_DNTS_SLOT_NUM 4 - - -/* debug support */ -uint_t hwahc_errmask = (uint_t)PRINT_MASK_ALL; -uint_t hwahc_errlevel = USB_LOG_L4; -uint_t hwahc_instance_debug = (uint_t)-1; - -/* bus config debug flag */ -uint_t hwahc_bus_config_debug = 0; -uint8_t hwahc_enable_trust_timeout = 1; - - -/* - * Use the default GTK for the whole life of HWA driver. - * Not so compatible with WUSB spec. - */ -static uint8_t dft_gtk[16]; -static uint8_t dft_gtkid[3]; - -extern usb_log_handle_t whcdi_log_handle; - -/* - * Function Prototypes - */ -/* driver operations (dev_ops) entry points */ -static int hwahc_open(dev_t *, int, int, cred_t *); -static int hwahc_close(dev_t, int, int, cred_t *); -static int hwahc_ioctl(dev_t, int, intptr_t, int, cred_t *, int *); - -static int hwahc_info(dev_info_t *, ddi_info_cmd_t, void *, void **); -static int hwahc_attach(dev_info_t *, ddi_attach_cmd_t); -static int hwahc_detach(dev_info_t *, ddi_detach_cmd_t); -static int hwahc_power(dev_info_t *, int, int); - -/* bus_ops entry points */ -static int hwahc_bus_ctl(dev_info_t *, dev_info_t *, ddi_ctl_enum_t, - void *, void *); -static int hwahc_busop_get_eventcookie(dev_info_t *, dev_info_t *, - char *, ddi_eventcookie_t *); -static int hwahc_busop_add_eventcall( - dev_info_t *, dev_info_t *, ddi_eventcookie_t, - void (*)(dev_info_t *, ddi_eventcookie_t, void *, void *), - void *, ddi_callback_id_t *); -static int hwahc_busop_remove_eventcall(dev_info_t *, ddi_callback_id_t); -static int hwahc_bus_config(dev_info_t *, uint_t, ddi_bus_config_op_t, - void *, dev_info_t **); -static int hwahc_bus_unconfig(dev_info_t *, uint_t, ddi_bus_config_op_t, - void *); - -/* hotplug and power management supporting functions */ -static int hwahc_disconnect_event_cb(dev_info_t *dip); -static int hwahc_reconnect_event_cb(dev_info_t *dip); -static int hwahc_pre_suspend_event_cb(dev_info_t *dip); -static int hwahc_post_resume_event_cb(dev_info_t *dip); -static int hwahc_cpr_suspend(dev_info_t *); -static int hwahc_cpr_resume(dev_info_t *); -static void hwahc_restore_device_state(dev_info_t *, hwahc_state_t *); -static void hwahc_run_callbacks(hwahc_state_t *, usba_event_t); -static void hwahc_post_event(hwahc_state_t *, usb_port_t, usba_event_t); - -static int hwahc_cleanup(dev_info_t *, hwahc_state_t *); -static void hwahc_create_pm_components(dev_info_t *, hwahc_state_t *); -static void hwahc_destroy_pm_components(hwahc_state_t *); -static void hwahc_pm_busy_component(hwahc_state_t *); -static void hwahc_pm_idle_component(hwahc_state_t *); -static int hwahc_pwrlvl0(hwahc_state_t *); -static int hwahc_pwrlvl1(hwahc_state_t *); -static int hwahc_pwrlvl2(hwahc_state_t *); -static int hwahc_pwrlvl3(hwahc_state_t *); -static int hwahc_hc_channel_suspend(hwahc_state_t *); - -/* hardware initialization and deinitialization functions */ -static int hwahc_parse_security_data(wusb_secrt_data_t *, - usb_cfg_data_t *); -static void hwahc_print_secrt_data(hwahc_state_t *); - -static int hwahc_hub_attach(hwahc_state_t *); -static int hwahc_hub_detach(hwahc_state_t *); - -static int hwahc_hc_initial_start(hwahc_state_t *); -static int hwahc_hc_final_stop(hwahc_state_t *); -static int hwahc_wa_start(hwahc_state_t *); -static void hwahc_wa_stop(hwahc_state_t *); -static int hwahc_hc_channel_start(hwahc_state_t *); -static int hwahc_hc_channel_stop(hwahc_state_t *); -static void hwahc_hc_data_init(hwahc_state_t *); -static void hwahc_hc_data_fini(hwahc_state_t *); - -/* ioctl support */ -static int hwahc_cfgadm_ioctl(hwahc_state_t *, int, intptr_t, int, - cred_t *, int *); -static int hwahc_wusb_ioctl(hwahc_state_t *, int, intptr_t, int, - cred_t *, int *); - -/* callbacks registered to USBA */ -static void hwahc_disconnect_dev(dev_info_t *, usb_port_t); -static void hwahc_reconnect_dev(dev_info_t *, usb_port_t); -static int hwahc_create_child(dev_info_t *, usb_port_t); -static int hwahc_destroy_child(dev_info_t *, usb_port_t); -static int hwahc_cleanup_child(dev_info_t *); -static int hwahc_delete_child(dev_info_t *, usb_port_t, uint_t, boolean_t); - -/* data transfer and notification handling */ -static void hwahc_intr_cb(usb_pipe_handle_t, struct usb_intr_req *); -static void hwahc_intr_exc_cb(usb_pipe_handle_t, struct usb_intr_req *); -static void hwahc_handle_notif(hwahc_state_t *, mblk_t *); -static void hwahc_handle_xfer_result(hwahc_state_t *, uint8_t); -static void hwahc_stop_result_thread(hwahc_state_t *); -static void hwahc_result_thread(void *); -static void hwahc_handle_dn_notif(hwahc_state_t *, hwa_notif_dn_recvd_t *); -static void hwahc_notif_thread(void *); -static void hwahc_handle_dn(hwahc_state_t *, hwa_notif_dn_recvd_t *); -static void hwahc_drain_notif_queue(hwahc_state_t *); -static void hwahc_rpipe_xfer_cb(dev_info_t *, usba_pipe_handle_data_t *, - wusb_wa_trans_wrapper_t *, usb_cr_t); - -static void hwahc_trust_timeout_handler(void *arg); -static void hwahc_stop_trust_timer(wusb_dev_info_t *dev); - -static int hwahc_pipe_submit_periodic_req(wusb_wa_data_t *wa_data, - usba_pipe_handle_data_t *ph); - -/* hwa specific requests */ -static int hwahc_set_chid(hwahc_state_t *, uint8_t *); - -/* helper functions */ -static usb_port_t hwahc_get_port_num(hwahc_state_t *, struct devctl_iocdata *); -static dev_info_t *hwahc_get_child_dip(hwahc_state_t *, usb_port_t); - -static struct cb_ops hwahc_cb_ops = { - hwahc_open, /* Open */ - hwahc_close, /* Close */ - nodev, /* Strategy */ - nodev, /* Print */ - nodev, /* Dump */ - nodev, /* Read */ - nodev, /* Write */ - hwahc_ioctl, /* Ioctl */ - nodev, /* Devmap */ - nodev, /* Mmap */ - nodev, /* Segmap */ - nochpoll, /* Poll */ - ddi_prop_op, /* cb_prop_op */ - NULL, /* Streamtab */ - D_MP /* Driver compatibility flag */ -}; - -static struct bus_ops hwahc_busops = { - BUSO_REV, - nullbusmap, /* bus_map */ - NULL, /* bus_get_intrspec */ - NULL, /* bus_add_intrspec */ - NULL, /* bus_remove_intrspec */ - NULL, /* bus_map_fault */ - NULL, /* bus_dma_map */ - ddi_dma_allochdl, - ddi_dma_freehdl, - ddi_dma_bindhdl, - ddi_dma_unbindhdl, - ddi_dma_flush, - ddi_dma_win, - ddi_dma_mctl, /* bus_dma_ctl */ - hwahc_bus_ctl, /* bus_ctl */ - ddi_bus_prop_op, /* bus_prop_op */ - hwahc_busop_get_eventcookie, /* bus_get_eventcookie */ - hwahc_busop_add_eventcall, /* bus_add_eventcall */ - hwahc_busop_remove_eventcall, /* bus_remove_eventcall */ - NULL, /* bus_post_event */ - NULL, /* bus_intr_ctl */ - hwahc_bus_config, /* bus_config */ - hwahc_bus_unconfig, /* bus_unconfig */ - NULL, /* bus_fm_init */ - NULL, /* bus_fm_fini */ - NULL, /* bus_fm_access_enter */ - NULL, /* bus_fm_access_exit */ - NULL, /* bus_power */ -}; - -static struct dev_ops hwahc_ops = { - DEVO_REV, /* Devo_rev */ - 0, /* Refcnt */ - hwahc_info, /* Info */ - nulldev, /* Identify */ - nulldev, /* Probe */ - hwahc_attach, /* Attach */ - hwahc_detach, /* Detach */ - nodev, /* Reset */ - &hwahc_cb_ops, /* Driver operations */ - &hwahc_busops, /* Bus operations */ - hwahc_power, /* Power */ - ddi_quiesce_not_needed, /* devo_quiesce */ -}; - -static struct modldrv hwahc_modldrv = { - &mod_driverops, - "WUSB hwa-hc driver", - &hwahc_ops -}; - -static struct modlinkage modlinkage = { - MODREV_1, - &hwahc_modldrv, - NULL -}; - -/* events from parent */ -static usb_event_t hwahc_events = { - hwahc_disconnect_event_cb, - hwahc_reconnect_event_cb, - hwahc_pre_suspend_event_cb, - hwahc_post_resume_event_cb -}; - -/* - * events support for children - * A map tween USBA_EVENTs and DDI_EVENTs. - */ -static ndi_event_definition_t hwahc_ndi_event_defs[] = { - {USBA_EVENT_TAG_HOT_REMOVAL, DDI_DEVI_REMOVE_EVENT, EPL_KERNEL, - NDI_EVENT_POST_TO_ALL}, - {USBA_EVENT_TAG_HOT_INSERTION, DDI_DEVI_INSERT_EVENT, EPL_KERNEL, - NDI_EVENT_POST_TO_ALL}, - {USBA_EVENT_TAG_POST_RESUME, USBA_POST_RESUME_EVENT, EPL_KERNEL, - NDI_EVENT_POST_TO_ALL}, - {USBA_EVENT_TAG_PRE_SUSPEND, USBA_PRE_SUSPEND_EVENT, EPL_KERNEL, - NDI_EVENT_POST_TO_ALL} -}; - -#define HWAHC_N_NDI_EVENTS \ - (sizeof (hwahc_ndi_event_defs) / sizeof (ndi_event_definition_t)) - -static ndi_event_set_t hwahc_ndi_events = { - NDI_EVENTS_REV1, HWAHC_N_NDI_EVENTS, hwahc_ndi_event_defs}; - -/* transfer callbacks */ -static wusb_wa_cb_t hwahc_cbs = { - hwahc_pipe_submit_periodic_req, - hwahc_intr_cb, - hwahc_intr_exc_cb, - hwahc_rpipe_xfer_cb -}; - - -/* - * Module-wide initialization routine. - */ -int -_init(void) -{ - int rval; - - if ((rval = ddi_soft_state_init(&hwahc_statep, sizeof (hwahc_state_t), - HWAHC_INSTS)) != 0) { - - return (rval); - } - - if ((rval = mod_install(&modlinkage)) != 0) { - ddi_soft_state_fini(&hwahc_statep); - } - - return (rval); -} - - -/* - * Module-wide tear-down routine. - */ -int -_fini(void) -{ - int rval; - - if ((rval = mod_remove(&modlinkage)) == 0) { - /* Release per module resources */ - ddi_soft_state_fini(&hwahc_statep); - } - - return (rval); -} - - -int -_info(struct modinfo *modinfop) -{ - return (mod_info(&modlinkage, modinfop)); -} - - -/* - * hwahc_info: - * Get minor number, instance number, etc. - */ -/*ARGSUSED*/ -static int -hwahc_info(dev_info_t *dip, ddi_info_cmd_t infocmd, - void *arg, void **result) -{ - hwahc_state_t *hwahcp; - int error = DDI_FAILURE; - int instance = HWAHC_MINOR_TO_INSTANCE(getminor((dev_t)arg)); - - switch (infocmd) { - case DDI_INFO_DEVT2DEVINFO: - if ((hwahcp = ddi_get_soft_state(hwahc_statep, - instance)) != NULL) { - *result = hwahcp->hwahc_dip; - if (*result != NULL) { - error = DDI_SUCCESS; - } - } else { - *result = NULL; - } - break; - case DDI_INFO_DEVT2INSTANCE: - *result = (void *)(uintptr_t)instance; - error = DDI_SUCCESS; - break; - default: - break; - } - - return (error); -} - - -/* - * hwahc_attach: - * Attach or resume. - * - * For attach, initialize state and device, including: - * state variables, locks, device node, - * resource initialization, event registration, - * device registration with system - * power management, hotplugging - * For resume, restore device and state - */ -static int -hwahc_attach(dev_info_t *dip, ddi_attach_cmd_t cmd) -{ - int instance = ddi_get_instance(dip); - hwahc_state_t *hwahcp = NULL; - usb_client_dev_data_t *dev_data; - struct usb_cfg_data *cfg_data; - usba_hcdi_register_args_t hcdi_args; - int rval; - char *pathname; - - USB_DPRINTF_L3(PRINT_MASK_ATTA, NULL, "hwahc_attach: cmd=%d", cmd); - - switch (cmd) { - case DDI_ATTACH: - break; - case DDI_RESUME: - (void) hwahc_cpr_resume(dip); - - return (DDI_SUCCESS); - default: - USB_DPRINTF_L2(PRINT_MASK_ATTA, NULL, - "hwahc_attach: failed"); - - return (DDI_FAILURE); - } - - /* - * Allocate soft state information. - */ - rval = ddi_soft_state_zalloc(hwahc_statep, instance); - if (rval != DDI_SUCCESS) { - USB_DPRINTF_L2(PRINT_MASK_ATTA, NULL, - "hwahc_attach: cannot allocate soft state for instance %d", - instance); - - return (USB_FAILURE); - } - - hwahcp = ddi_get_soft_state(hwahc_statep, instance); - if (hwahcp == NULL) { - USB_DPRINTF_L2(PRINT_MASK_ATTA, NULL, - "hwahc_attach: get soft state failed for instance %d", - instance); - - return (USB_FAILURE); - } - - hwahcp->hwahc_log_handle = usb_alloc_log_hdl(dip, "hwahc", - &hwahc_errlevel, &hwahc_errmask, &hwahc_instance_debug, 0); - - /* initialize hc state */ - hwahcp->hwahc_hc_soft_state = HWAHC_CTRL_INIT_STATE; - hwahcp->hwahc_dip = dip; - hwahcp->hwahc_instance = instance; - - /* register with USBA as client driver */ - if (usb_client_attach(dip, USBDRV_VERSION, 0) != USB_SUCCESS) { - USB_DPRINTF_L2(PRINT_MASK_ATTA, hwahcp->hwahc_log_handle, - "hwahc_attach: client attach failed"); - - goto fail; - } - - if (usb_get_dev_data(dip, &dev_data, USB_PARSE_LVL_IF, 0) != - USB_SUCCESS) { - USB_DPRINTF_L2(PRINT_MASK_ATTA, hwahcp->hwahc_log_handle, - "hwahc_attach: cannot get dev_data"); - - goto fail; - } - - /* initialize mutex and cv */ - mutex_init(&hwahcp->hwahc_mutex, NULL, MUTEX_DRIVER, - dev_data->dev_iblock_cookie); - cv_init(&hwahcp->hwahc_result_thread_cv, NULL, CV_DRIVER, NULL); - - hwahcp->hwahc_flags |= HWAHC_LOCK_INITED; - hwahcp->hwahc_dev_data = dev_data; - - /* initialize data transfer function related structure */ - if (wusb_wa_data_init(dip, &hwahcp->hwahc_wa_data, &hwahc_cbs, - dev_data, PRINT_MASK_ATTA, - hwahcp->hwahc_log_handle) != USB_SUCCESS) { - USB_DPRINTF_L2(PRINT_MASK_ATTA, hwahcp->hwahc_log_handle, - "hwahc_attach: init wa data failed"); - - goto fail; - } - - hwahcp->hwahc_flags |= HWAHC_WA_INITED; - cfg_data = dev_data->dev_curr_cfg; - - /* parse the security descrs from the configuration descr cloud */ - if (hwahc_parse_security_data(&hwahcp->hwahc_secrt_data, cfg_data) != - USB_SUCCESS) { - USB_DPRINTF_L2(PRINT_MASK_ATTA, hwahcp->hwahc_log_handle, - "hwahc_attach: parse security descrs failed"); - - goto fail; - } - - hwahcp->hwahc_default_pipe = dev_data->dev_default_ph; - hwahcp->hwahc_wa_data.wa_private_data = (void *)hwahcp; - hwahcp->hwahc_wa_data.wa_default_pipe = hwahcp->hwahc_default_pipe; - - usb_free_descr_tree(dip, dev_data); - - hwahcp->hwahc_dev_state = USB_DEV_ONLINE; - - /* now create components to power manage this device */ - hwahc_create_pm_components(dip, hwahcp); - - /* - * Event definition and registration - * - * allocate a new NDI event handle as a nexus driver - */ - (void) ndi_event_alloc_hdl(dip, 0, &hwahcp->hwahc_ndi_event_hdl, - NDI_SLEEP); - - /* - * bind our NDI events with the event handle, - * i.e. Define the events set we're to support as a nexus driver. - * - * These events will be used by bus_ops functions to register callbacks. - */ - if (ndi_event_bind_set(hwahcp->hwahc_ndi_event_hdl, &hwahc_ndi_events, - NDI_SLEEP)) { - USB_DPRINTF_L2(PRINT_MASK_ATTA, hwahcp->hwahc_log_handle, - "hwahc_attach: binding event set failed"); - - goto fail; - } - - - /* - * Register USB events to USBA(the parent) to get callbacks as a - * child of (root) hub - */ - if (usb_register_event_cbs(dip, &hwahc_events, 0) != USB_SUCCESS) { - USB_DPRINTF_L2(PRINT_MASK_ATTA, hwahcp->hwahc_log_handle, - "hwahc_attach: register_events failed"); - - goto fail; - } - - hwahcp->hwahc_flags |= HWAHC_EVENTS_REGISTERED; - - /* create minor nodes */ - if (ddi_create_minor_node(dip, "hwahc", S_IFCHR, - instance << HWAHC_MINOR_INSTANCE_SHIFT, - DDI_NT_NEXUS, 0) != DDI_SUCCESS) { - - USB_DPRINTF_L2(PRINT_MASK_ATTA, hwahcp->hwahc_log_handle, - "hwahc_attach: cannot create minor node"); - - goto fail; - } - - hwahcp->hwahc_flags |= HWAHC_MINOR_NODE_CREATED; - - hwahcp->hwahc_hcdi_ops = hwahc_alloc_hcdi_ops(hwahcp); - - /* register this hc instance with usba HCD interface */ - hcdi_args.usba_hcdi_register_version = HCDI_REGISTER_VERSION; - hcdi_args.usba_hcdi_register_dip = dip; - hcdi_args.usba_hcdi_register_ops = hwahcp->hwahc_hcdi_ops; - - /* use parent dma attr here */ - hcdi_args.usba_hcdi_register_dma_attr = usba_get_hc_dma_attr(dip); - hcdi_args.usba_hcdi_register_iblock_cookie = NULL; - - if (usba_hcdi_register(&hcdi_args, 0) != USB_SUCCESS) { - USB_DPRINTF_L2(PRINT_MASK_ATTA, hwahcp->hwahc_log_handle, - "hwahc_attach: usba_hcdi_register failed"); - - goto fail; - } - - hwahcp->hwahc_flags |= HWAHC_HCDI_REGISTERED; - - /* create hub minor node and register to usba HUBD interface */ - if (hwahc_hub_attach(hwahcp) != USB_SUCCESS) { - USB_DPRINTF_L2(PRINT_MASK_ATTA, hwahcp->hwahc_log_handle, - "hwahc_attach: hub attach failed"); - - goto fail; - } - hwahcp->hwahc_flags |= HWAHC_HUBREG; - - /* intialize WUSB host function related structure */ - hwahc_hc_data_init(hwahcp); - hwahcp->hwahc_flags |= HWAHC_HC_INITED; - - /* can be combined with wusb_wa_data_init() */ - if (hwahc_wa_start(hwahcp) != USB_SUCCESS) { - - goto fail; - } - - hwahcp->hwahc_flags |= HWAHC_WA_STARTED; - - /* report this dev */ - ddi_report_dev(dip); - - hwahc_pm_idle_component(hwahcp); - - mutex_enter(&(hwahcp->hwahc_mutex)); - hwahc_print_secrt_data(hwahcp); - mutex_exit(&(hwahcp->hwahc_mutex)); - - if (uwb_dev_online(dip) != USB_SUCCESS) { - goto fail; - } - - return (DDI_SUCCESS); - -fail: - pathname = kmem_alloc(MAXPATHLEN, KM_SLEEP); - - /* log this message to usba_debug_buf */ - USB_DPRINTF_L2(PRINT_MASK_ATTA, hwahcp->hwahc_log_handle, - "cannot attach %s", ddi_pathname(dip, pathname)); - - kmem_free(pathname, MAXPATHLEN); - - if (hwahcp) { - hwahc_pm_idle_component(hwahcp); - - rval = hwahc_cleanup(dip, hwahcp); - if (rval != USB_SUCCESS) { - USB_DPRINTF_L2(PRINT_MASK_ATTA, - hwahcp->hwahc_log_handle, - "failure to complete cleanup after attach failure"); - } - } - - return (DDI_FAILURE); -} - - -/* - * hwahc_detach: - * detach or suspend driver instance - * - * Note: in detach, only contention threads is from pm and disconnnect. - */ -static int -hwahc_detach(dev_info_t *dip, ddi_detach_cmd_t cmd) -{ - int instance = ddi_get_instance(dip); - hwahc_state_t *hwahcp = ddi_get_soft_state(hwahc_statep, instance); - int rval = DDI_FAILURE; - - - USB_DPRINTF_L3(PRINT_MASK_ATTA, hwahcp->hwahc_log_handle, - "hwahc_detach: cmd = %d", cmd); - - switch (cmd) { - case DDI_DETACH: - USB_DPRINTF_L3(PRINT_MASK_ATTA, hwahcp->hwahc_log_handle, - "offline uwb device for dip: 0x%p", (void *)dip); - /* offline the hwarc interface */ - (void) uwb_dev_offline(dip); - if (hwahcp) { - rval = hwahc_cleanup(dip, hwahcp); - } - - break; - case DDI_SUSPEND: - rval = hwahc_cpr_suspend(dip); - - break; - default: - - break; - } - - return ((rval == USB_SUCCESS) ? DDI_SUCCESS : DDI_FAILURE); -} - - -/* - * hwahc_cleanup: - * clean up on attach failure or detach - */ -static int -hwahc_cleanup(dev_info_t *dip, hwahc_state_t *hwahcp) -{ - USB_DPRINTF_L4(PRINT_MASK_ATTA, hwahcp->hwahc_log_handle, - "hwahc_cleanup: start"); - - if ((hwahcp->hwahc_flags & HWAHC_LOCK_INITED) == 0) { - - goto done; - } - - /* - * deallocate events, if events are still registered - * (ie. children still attached) then we have to fail the detach - */ - if (hwahcp->hwahc_ndi_event_hdl && - (ndi_event_free_hdl(hwahcp->hwahc_ndi_event_hdl) != NDI_SUCCESS)) { - - USB_DPRINTF_L2(PRINT_MASK_ATTA, hwahcp->hwahc_log_handle, - "hwahc_cleanup: ndi_event_free_hdl failed"); - - return (USB_FAILURE); - } - - if (hwahcp->hwahc_flags & HWAHC_EVENTS_REGISTERED) { - /* unregister events */ - usb_unregister_event_cbs(dip, &hwahc_events); - } - - if (hwahcp->hwahc_flags & HWAHC_HCDI_REGISTERED) { - /* unregister the instance with usba HCD interface */ - usba_hcdi_unregister(hwahcp->hwahc_dip); - } - - mutex_enter(&hwahcp->hwahc_mutex); - - if (hwahcp->hwahc_hw_state != HWAHC_HW_STOPPED) { - /* stop the hw if it is enabled */ - (void) hwahc_hc_final_stop(hwahcp); - } - - if (hwahcp->hwahc_flags & HWAHC_WA_STARTED) { - /* can be combined with wusb_wa_data_fini() */ - mutex_exit(&hwahcp->hwahc_mutex); - hwahc_wa_stop(hwahcp); - mutex_enter(&hwahcp->hwahc_mutex); - } - - if (hwahcp->hwahc_flags & HWAHC_HC_INITED) { - /* deinitialize the WUSB host function related structure */ - hwahc_hc_data_fini(hwahcp); - } - - mutex_exit(&hwahcp->hwahc_mutex); - - if (hwahcp->hwahc_pm) { - /* destroy power management components */ - hwahc_destroy_pm_components(hwahcp); - } - - if (hwahcp->hwahc_flags & HWAHC_HUBREG) { - /* unregister the instance from usba HUBD interface */ - if (hwahc_hub_detach(hwahcp) != USB_SUCCESS) { - - return (USB_FAILURE); - } - } - - if (hwahcp->hwahc_hcdi_ops) { - usba_free_hcdi_ops(hwahcp->hwahc_hcdi_ops); - } - - mutex_enter(&hwahcp->hwahc_mutex); - if (hwahcp->hwahc_secrt_data.secrt_encry_descr) { - /* free security descrs */ - kmem_free(hwahcp->hwahc_secrt_data.secrt_encry_descr, - sizeof (usb_encryption_descr_t) * - hwahcp->hwahc_secrt_data.secrt_n_encry); - } - - if (hwahcp->hwahc_flags & HWAHC_WA_INITED) { - /* deinitialize data transfer function related structure */ - wusb_wa_data_fini(&hwahcp->hwahc_wa_data); - } - mutex_exit(&hwahcp->hwahc_mutex); - - if (hwahcp->hwahc_flags & HWAHC_MINOR_NODE_CREATED) { - /* remove all the minor nodes */ - ddi_remove_minor_node(dip, NULL); - } - - /* destroy mutex and cv */ - mutex_destroy(&hwahcp->hwahc_mutex); - cv_destroy(&hwahcp->hwahc_result_thread_cv); - -done: - /* unregister the client driver from usba */ - usb_client_detach(dip, hwahcp->hwahc_dev_data); - - USB_DPRINTF_L4(PRINT_MASK_ATTA, hwahcp->hwahc_log_handle, - "hwahc_cleanup: end"); - - usb_free_log_hdl(hwahcp->hwahc_log_handle); - - /* remove all properties created */ - ddi_prop_remove_all(dip); - - /* free the soft state information */ - ddi_soft_state_free(hwahc_statep, ddi_get_instance(dip)); - - return (USB_SUCCESS); -} - - -/*ARGSUSED*/ -static int -hwahc_open(dev_t *devp, int flag, int otyp, cred_t *cred_p) -{ - hwahc_state_t *hwahcp; - - if ((hwahcp = ddi_get_soft_state(hwahc_statep, - HWAHC_MINOR_TO_INSTANCE(getminor(*devp)))) == NULL) { - - return (ENXIO); - } - - USB_DPRINTF_L4(PRINT_MASK_OPEN, hwahcp->hwahc_log_handle, - "hwahc_open: start"); - - mutex_enter(&hwahcp->hwahc_mutex); - /* exclusive open */ - if ((flag & FEXCL) && (hwahcp->hwahc_open_count > 0)) { - mutex_exit(&hwahcp->hwahc_mutex); - - return (EBUSY); - } - - if ((hwahcp->hwahc_dev_state == USB_DEV_DISCONNECTED) || - (hwahcp->hwahc_dev_state == USB_DEV_SUSPENDED)) { - mutex_exit(&hwahcp->hwahc_mutex); - - return (EIO); - } - - hwahcp->hwahc_open_count++; - - mutex_exit(&hwahcp->hwahc_mutex); - - /* raise to full power and keep it until close */ - hwahc_pm_busy_component(hwahcp); - (void) pm_raise_power(hwahcp->hwahc_dip, 0, USB_DEV_OS_FULL_PWR); - - USB_DPRINTF_L4(PRINT_MASK_OPEN, hwahcp->hwahc_log_handle, - "hwahc_open: end"); - - return (0); -} - - -/*ARGSUSED*/ -static int -hwahc_close(dev_t dev, int flag, int otyp, cred_t *cred_p) -{ - hwahc_state_t *hwahcp; - - if ((hwahcp = ddi_get_soft_state(hwahc_statep, - HWAHC_MINOR_TO_INSTANCE(getminor(dev)))) == NULL) { - - return (ENXIO); - } - - USB_DPRINTF_L4(PRINT_MASK_CLOSE, hwahcp->hwahc_log_handle, - "hwahc_close: start"); - - mutex_enter(&hwahcp->hwahc_mutex); - if (hwahcp->hwahc_open_count == 0) { - USB_DPRINTF_L2(PRINT_MASK_CLOSE, hwahcp->hwahc_log_handle, - "hwahc_close: already closed"); - mutex_exit(&hwahcp->hwahc_mutex); - - return (EINVAL); - } - - hwahcp->hwahc_open_count--; - mutex_exit(&hwahcp->hwahc_mutex); - - hwahc_pm_idle_component(hwahcp); - - USB_DPRINTF_L4(PRINT_MASK_CLOSE, hwahcp->hwahc_log_handle, - "hwahc_close: end"); - - return (0); -} - -/* retrieve port number from devctl data */ -static usb_port_t -hwahc_get_port_num(hwahc_state_t *hwahcp, struct devctl_iocdata *dcp) -{ - int32_t port; - - ASSERT(mutex_owned(&hwahcp->hwahc_mutex)); - - /* Get which port to operate on. */ - if (nvlist_lookup_int32(ndi_dc_get_ap_data(dcp), "port", &port) != 0) { - USB_DPRINTF_L2(PRINT_MASK_CBOPS, hwahcp->hwahc_log_handle, - "hwahc_get_port_num: port lookup failed"); - port = 0; - } - - USB_DPRINTF_L4(PRINT_MASK_CBOPS, hwahcp->hwahc_log_handle, - "hwahc_get_port_num: hwahcp=0x%p, port=%d", (void *)hwahcp, - port); - - return ((usb_port_t)port); -} - -/* return the child dip on a certain port */ -static dev_info_t * -hwahc_get_child_dip(hwahc_state_t *hwahcp, usb_port_t port) -{ - wusb_hc_data_t *hc_data; - dev_info_t *child_dip; - - hc_data = &hwahcp->hwahc_hc_data; - - /* check port range to prevent an illegal number */ - if (port > hc_data->hc_num_ports) { - return (NULL); - } - - mutex_enter(&hc_data->hc_mutex); - child_dip = hc_data->hc_children_dips[port]; - mutex_exit(&hc_data->hc_mutex); - - return (child_dip); -} - -/* - * hwahc_cfgadm_state: - * - * child_dip list child_state cfgadm_state - * -------------- ---------- ------------ - * != NULL connected configured or - * unconfigured - * != NULL not connected disconnect but - * busy/still referenced - * NULL connected logically disconnected - * NULL not connected empty - */ -static uint_t -hwahc_cfgadm_state(hwahc_state_t *hwahcp, usb_port_t port) -{ - uint_t state; - dev_info_t *child_dip = hwahc_get_child_dip(hwahcp, port); - wusb_hc_data_t *hc_data = &hwahcp->hwahc_hc_data; - wusb_dev_info_t *dev_info; - - if (child_dip == NULL) { - - return (HWAHC_CFGADM_INVALID); - } - - mutex_enter(&hc_data->hc_mutex); - dev_info = hc_data->hc_dev_infos[port]; - if (dev_info) { - if (dev_info->wdev_state == WUSB_STATE_CONFIGURED) { - if (child_dip && - (DEVI_IS_DEVICE_OFFLINE(child_dip) || - !i_ddi_devi_attached(child_dip))) { - state = HWAHC_CFGADM_UNCONFIGURED; - } else if (!child_dip) { - state = HWAHC_CFGADM_UNCONFIGURED; - } else { - state = HWAHC_CFGADM_CONFIGURED; - } - } else if (dev_info->wdev_state == WUSB_STATE_UNCONNTED) { - if (child_dip) { - state = HWAHC_CFGADM_STILL_REFERENCED; - } else { - state = HWAHC_CFGADM_DISCONNECTED; - } - } else { - if (child_dip) { - state = HWAHC_CFGADM_STILL_REFERENCED; - } else { - state = HWAHC_CFGADM_UNCONFIGURED; - } - } - } else { - state = HWAHC_CFGADM_EMPTY; - } - mutex_exit(&hc_data->hc_mutex); - - USB_DPRINTF_L4(PRINT_MASK_CBOPS, hwahcp->hwahc_log_handle, - "hwahc_cfgadm_state: hwahcp=0x%p, port=%d state=0x%x", - (void *) hwahcp, port, state); - - return (state); -} - -/* cfgadm ioctl support, now only implements list function */ -/* ARGSUSED */ -static int -hwahc_cfgadm_ioctl(hwahc_state_t *hwahcp, int cmd, intptr_t arg, - int mode, cred_t *credp, int *rvalp) -{ - dev_info_t *rh_dip; - dev_info_t *child_dip; - struct devctl_iocdata *dcp = NULL; - usb_port_t port = 0; - devctl_ap_state_t ap_state; - int circ, rh_circ, prh_circ; - int rv = 0; - char *msg; - - /* read devctl ioctl data */ - if ((cmd != DEVCTL_AP_CONTROL) && - (ndi_dc_allochdl((void *)arg, &dcp) != NDI_SUCCESS)) { - - return (EFAULT); - } - - mutex_enter(&hwahcp->hwahc_mutex); - - rh_dip = hwahcp->hwahc_hubd->h_usba_device->usb_root_hub_dip; - - switch (cmd) { - case DEVCTL_AP_DISCONNECT: - case DEVCTL_AP_UNCONFIGURE: - case DEVCTL_AP_CONFIGURE: - if (hwahcp->hwahc_dev_state == USB_DEV_DISCONNECTED) { - USB_DPRINTF_L2(PRINT_MASK_ATTA, - hwahcp->hwahc_log_handle, - "hwahc_cfgadm_ioctl: dev already gone"); - mutex_exit(&hwahcp->hwahc_mutex); - if (dcp) { - ndi_dc_freehdl(dcp); - } - - return (EIO); - } - /* FALLTHROUGH */ - case DEVCTL_AP_GETSTATE: - if ((port = hwahc_get_port_num(hwahcp, dcp)) == 0) { - USB_DPRINTF_L2(PRINT_MASK_ATTA, - hwahcp->hwahc_log_handle, - "hwahc_cfgadm_ioctl: bad port"); - mutex_exit(&hwahcp->hwahc_mutex); - if (dcp) { - ndi_dc_freehdl(dcp); - } - - return (EINVAL); - } - break; - case DEVCTL_AP_CONTROL: - - break; - default: - mutex_exit(&hwahcp->hwahc_mutex); - if (dcp) { - ndi_dc_freehdl(dcp); - } - - return (ENOTTY); - } - - /* should not happen, just in case */ - if (hwahcp->hwahc_dev_state == USB_DEV_SUSPENDED) { - mutex_exit(&hwahcp->hwahc_mutex); - if (dcp) { - ndi_dc_freehdl(dcp); - } - - return (EIO); - } - - mutex_exit(&hwahcp->hwahc_mutex); - - ndi_devi_enter(ddi_get_parent(rh_dip), &prh_circ); - ndi_devi_enter(rh_dip, &rh_circ); - ndi_devi_enter(hwahcp->hwahc_dip, &circ); - - mutex_enter(&hwahcp->hwahc_mutex); - - switch (cmd) { - case DEVCTL_AP_DISCONNECT: - /* TODO: not supported now */ - rv = EIO; - break; - case DEVCTL_AP_UNCONFIGURE: - /* TODO: not supported now */ - rv = EIO; - break; - case DEVCTL_AP_CONFIGURE: - /* TODO: not supported now */ - rv = EIO; - break; - case DEVCTL_AP_GETSTATE: - switch (hwahc_cfgadm_state(hwahcp, port)) { - case HWAHC_CFGADM_DISCONNECTED: - /* port previously 'disconnected' by cfgadm */ - ap_state.ap_rstate = AP_RSTATE_DISCONNECTED; - ap_state.ap_ostate = AP_OSTATE_UNCONFIGURED; - ap_state.ap_condition = AP_COND_OK; - - break; - case HWAHC_CFGADM_UNCONFIGURED: - ap_state.ap_rstate = AP_RSTATE_CONNECTED; - ap_state.ap_ostate = AP_OSTATE_UNCONFIGURED; - ap_state.ap_condition = AP_COND_OK; - - break; - case HWAHC_CFGADM_CONFIGURED: - ap_state.ap_rstate = AP_RSTATE_CONNECTED; - ap_state.ap_ostate = AP_OSTATE_CONFIGURED; - ap_state.ap_condition = AP_COND_OK; - - break; - case HWAHC_CFGADM_STILL_REFERENCED: - ap_state.ap_rstate = AP_RSTATE_EMPTY; - ap_state.ap_ostate = AP_OSTATE_CONFIGURED; - ap_state.ap_condition = AP_COND_UNUSABLE; - - break; - case HWAHC_CFGADM_EMPTY: - default: - ap_state.ap_rstate = AP_RSTATE_EMPTY; - ap_state.ap_ostate = AP_OSTATE_UNCONFIGURED; - ap_state.ap_condition = AP_COND_OK; - - break; - } - - ap_state.ap_last_change = (time_t)-1; - ap_state.ap_error_code = 0; - ap_state.ap_in_transition = 0; - - USB_DPRINTF_L4(PRINT_MASK_CBOPS, hwahcp->hwahc_log_handle, - "DEVCTL_AP_GETSTATE: " - "ostate=0x%x, rstate=0x%x, condition=0x%x", - ap_state.ap_ostate, - ap_state.ap_rstate, ap_state.ap_condition); - - /* copy the return-AP-state information to the user space */ - if (ndi_dc_return_ap_state(&ap_state, dcp) != NDI_SUCCESS) { - rv = EFAULT; - } - - break; - case DEVCTL_AP_CONTROL: - { - /* - * Generic devctl for hardware-specific functionality. - * For list of sub-commands see hubd_impl.h - */ - hubd_ioctl_data_t ioc; /* for 64 byte copies */ - - /* copy user ioctl data in first */ -#ifdef _MULTI_DATAMODEL - if (ddi_model_convert_from(mode & FMODELS) == DDI_MODEL_ILP32) { - hubd_ioctl_data_32_t ioc32; - - if (ddi_copyin((void *)arg, (void *)&ioc32, - sizeof (ioc32), mode) != 0) { - rv = EFAULT; - - break; - } - ioc.cmd = (uint_t)ioc32.cmd; - ioc.port = (uint_t)ioc32.port; - ioc.get_size = (uint_t)ioc32.get_size; - ioc.buf = (caddr_t)(uintptr_t)ioc32.buf; - ioc.bufsiz = (uint_t)ioc32.bufsiz; - ioc.misc_arg = (uint_t)ioc32.misc_arg; - } else -#endif /* _MULTI_DATAMODEL */ - if (ddi_copyin((void *)arg, (void *)&ioc, sizeof (ioc), - mode) != 0) { - rv = EFAULT; - - break; - } - - USB_DPRINTF_L3(PRINT_MASK_CBOPS, hwahcp->hwahc_log_handle, - "DEVCTL_AP_CONTROL: ioc: cmd=0x%x port=%d get_size=%d" - "\n\tbuf=0x%p, bufsiz=%d, misc_arg=%d", ioc.cmd, - ioc.port, ioc.get_size, (void *) ioc.buf, ioc.bufsiz, - ioc.misc_arg); - - /* - * To avoid BE/LE and 32/64 issues, a get_size always - * returns a 32-bit number. - */ - if (ioc.get_size != 0 && ioc.bufsiz != (sizeof (uint32_t))) { - rv = EINVAL; - - break; - } - - switch (ioc.cmd) { - case USB_DESCR_TYPE_DEV: - msg = "DEVCTL_AP_CONTROL: GET_DEVICE_DESC"; - if (ioc.get_size) { - /* uint32 so this works 32/64 */ - uint32_t size = sizeof (usb_dev_descr_t); - - if (ddi_copyout((void *)&size, ioc.buf, - ioc.bufsiz, mode) != 0) { - USB_DPRINTF_L2(PRINT_MASK_CBOPS, - hwahcp->hwahc_log_handle, - "%s: get_size copyout failed", msg); - rv = EIO; - - break; - } - } else { /* send out the actual descr */ - usb_dev_descr_t *dev_descrp; - - /* check child_dip */ - if ((child_dip = hwahc_get_child_dip(hwahcp, - ioc.port)) == NULL) { - rv = EINVAL; - - break; - } - - dev_descrp = usb_get_dev_descr(child_dip); - if (ioc.bufsiz != sizeof (*dev_descrp)) { - USB_DPRINTF_L2(PRINT_MASK_CBOPS, - hwahcp->hwahc_log_handle, - "%s: bufsize passed (%d) != sizeof " - "usba_device_descr_t (%d)", msg, - ioc.bufsiz, dev_descrp->bLength); - rv = EINVAL; - - break; - } - - if (ddi_copyout((void *)dev_descrp, - ioc.buf, ioc.bufsiz, mode) != 0) { - USB_DPRINTF_L2(PRINT_MASK_CBOPS, - hwahcp->hwahc_log_handle, - "%s: copyout failed.", msg); - rv = EIO; - - break; - } - } - break; - case USB_DESCR_TYPE_CFG: - { - usba_device_t *child_ud = NULL; - uint32_t idx = ioc.misc_arg; - uint32_t cfg_len = 0; - - if ((child_dip = - hwahc_get_child_dip(hwahcp, ioc.port)) == NULL) { - rv = EINVAL; - - break; - } - child_ud = usba_get_usba_device(child_dip); - cfg_len = (uint32_t)child_ud->usb_cfg_array_len[idx]; - - msg = "DEVCTL_AP_CONTROL: GET_CONFIG_DESC"; - if (ioc.get_size) { - if (ddi_copyout((void *)&cfg_len, ioc.buf, - ioc.bufsiz, mode) != 0) { - USB_DPRINTF_L2(PRINT_MASK_CBOPS, - hwahcp->hwahc_log_handle, - "%s: get_size copyout failed", msg); - rv = EIO; - - break; - } - } else { /* send out the actual descr */ - uchar_t *cfg_descr = - child_ud->usb_cfg_array[idx]; - - if (ioc.bufsiz != cfg_len) { - USB_DPRINTF_L2(PRINT_MASK_CBOPS, - hwahcp->hwahc_log_handle, - "%s: bufsize passed (%d) != size " - "of cfg_descr (%d)", msg, - ioc.bufsiz, cfg_len); - rv = EINVAL; - - break; - } - - if (ddi_copyout((void *)cfg_descr, - ioc.buf, ioc.bufsiz, mode) != 0) { - USB_DPRINTF_L2(PRINT_MASK_CBOPS, - hwahcp->hwahc_log_handle, - "%s: copyout failed.", msg); - rv = EIO; - - break; - } - } - break; - } - case USB_DESCR_TYPE_STRING: - { - char *str; - uint32_t size; - usba_device_t *usba_device; - - msg = "DEVCTL_AP_CONTROL: GET_STRING_DESCR"; - USB_DPRINTF_L4(PRINT_MASK_CBOPS, - hwahcp->hwahc_log_handle, - "%s: string request: %d", msg, ioc.misc_arg); - - /* recheck */ - if ((child_dip = - hwahc_get_child_dip(hwahcp, ioc.port)) == NULL) { - rv = EINVAL; - - break; - } - usba_device = usba_get_usba_device(child_dip); - - switch (ioc.misc_arg) { - case HUBD_MFG_STR: - str = usba_device->usb_mfg_str; - - break; - case HUBD_PRODUCT_STR: - str = usba_device->usb_product_str; - - break; - case HUBD_SERIALNO_STR: - str = usba_device->usb_serialno_str; - - break; - case HUBD_CFG_DESCR_STR: - mutex_enter(&usba_device->usb_mutex); - str = usba_device->usb_cfg_str_descr[ - usba_device->usb_active_cfg_ndx]; - mutex_exit(&usba_device->usb_mutex); - - break; - default: - USB_DPRINTF_L2(PRINT_MASK_CBOPS, - hwahcp->hwahc_log_handle, - "%s: Invalid string request", msg); - rv = EINVAL; - - break; - } /* end of switch */ - - if (rv != 0) { - - break; - } - - size = (str != NULL) ? strlen(str) + 1 : 0; - if (ioc.get_size) { - if (ddi_copyout((void *)&size, ioc.buf, - ioc.bufsiz, mode) != 0) { - USB_DPRINTF_L2(PRINT_MASK_CBOPS, - hwahcp->hwahc_log_handle, - "%s: copyout of size failed.", msg); - rv = EIO; - - break; - } - } else { - if (size == 0) { - USB_DPRINTF_L2(PRINT_MASK_CBOPS, - hwahcp->hwahc_log_handle, - "%s: String is NULL", msg); - rv = EINVAL; - - break; - } - - if (ioc.bufsiz != size) { - USB_DPRINTF_L2(PRINT_MASK_CBOPS, - hwahcp->hwahc_log_handle, - "%s: string buf size wrong", msg); - rv = EINVAL; - - break; - } - - if (ddi_copyout((void *)str, ioc.buf, - ioc.bufsiz, mode) != 0) { - USB_DPRINTF_L2(PRINT_MASK_CBOPS, - hwahcp->hwahc_log_handle, - "%s: copyout failed.", msg); - rv = EIO; - - break; - } - } - break; - } - case HUBD_GET_CFGADM_NAME: - { - uint32_t name_len; - const char *name; - - /* recheck */ - if ((child_dip = - hwahc_get_child_dip(hwahcp, ioc.port)) == NULL) { - rv = EINVAL; - - break; - } - name = ddi_node_name(child_dip); - if (name == NULL) { - name = "unsupported"; - } - name_len = strlen(name) + 1; - - msg = "DEVCTL_AP_CONTROL: HUBD_GET_CFGADM_NAME"; - USB_DPRINTF_L4(PRINT_MASK_CBOPS, - hwahcp->hwahc_log_handle, - "%s: name=%s name_len=%d", msg, name, name_len); - - if (ioc.get_size) { - if (ddi_copyout((void *)&name_len, - ioc.buf, ioc.bufsiz, mode) != 0) { - USB_DPRINTF_L2(PRINT_MASK_CBOPS, - hwahcp->hwahc_log_handle, - "%s: copyout of size failed", msg); - rv = EIO; - - break; - } - } else { - if (ioc.bufsiz != name_len) { - USB_DPRINTF_L2(PRINT_MASK_CBOPS, - hwahcp->hwahc_log_handle, - "%s: string buf length wrong", msg); - rv = EINVAL; - - break; - } - - if (ddi_copyout((void *)name, ioc.buf, - ioc.bufsiz, mode) != 0) { - USB_DPRINTF_L2(PRINT_MASK_CBOPS, - hwahcp->hwahc_log_handle, - "%s: copyout failed.", msg); - rv = EIO; - - break; - } - } - - break; - } - - /* - * Return the config index for the currently-configured - * configuration. - */ - case HUBD_GET_CURRENT_CONFIG: - { - uint_t config_index; - uint32_t size = sizeof (config_index); - usba_device_t *usba_device; - - msg = "DEVCTL_AP_CONTROL: GET_CURRENT_CONFIG"; - USB_DPRINTF_L4(PRINT_MASK_CBOPS, - hwahcp->hwahc_log_handle, "%s", msg); - - /* - * Return the config index for the configuration - * currently in use. - * Recheck if child_dip exists - */ - if ((child_dip = - hwahc_get_child_dip(hwahcp, ioc.port)) == NULL) { - rv = EINVAL; - - break; - } - - usba_device = usba_get_usba_device(child_dip); - mutex_enter(&usba_device->usb_mutex); - config_index = usba_device->usb_active_cfg_ndx; - mutex_exit(&usba_device->usb_mutex); - - if (ioc.get_size) { - if (ddi_copyout((void *)&size, - ioc.buf, ioc.bufsiz, mode) != 0) { - USB_DPRINTF_L2(PRINT_MASK_CBOPS, - hwahcp->hwahc_log_handle, - "%s: copyout of size failed.", msg); - rv = EIO; - - break; - } - } else { - if (ioc.bufsiz != size) { - USB_DPRINTF_L2(PRINT_MASK_CBOPS, - hwahcp->hwahc_log_handle, - "%s: buffer size wrong", msg); - rv = EINVAL; - - break; - } - if (ddi_copyout((void *)&config_index, - ioc.buf, ioc.bufsiz, mode) != 0) { - USB_DPRINTF_L2(PRINT_MASK_CBOPS, - hwahcp->hwahc_log_handle, - "%s: copyout failed", msg); - rv = EIO; - } - } - - break; - } - case HUBD_GET_DEVICE_PATH: - { - char *path; - uint32_t size; - - msg = "DEVCTL_AP_CONTROL: GET_DEVICE_PATH"; - USB_DPRINTF_L4(PRINT_MASK_CBOPS, - hwahcp->hwahc_log_handle, "%s", msg); - - /* Recheck if child_dip exists */ - if ((child_dip = - hwahc_get_child_dip(hwahcp, ioc.port)) == NULL) { - rv = EINVAL; - - break; - } - - /* ddi_pathname doesn't supply /devices, so we do. */ - path = kmem_alloc(MAXPATHLEN, KM_SLEEP); - (void) strcpy(path, "/devices"); - (void) ddi_pathname(child_dip, path + strlen(path)); - size = strlen(path) + 1; - - USB_DPRINTF_L4(PRINT_MASK_CBOPS, - hwahcp->hwahc_log_handle, - "%s: device path=%s size=%d", msg, path, size); - - if (ioc.get_size) { - if (ddi_copyout((void *)&size, - ioc.buf, ioc.bufsiz, mode) != 0) { - - USB_DPRINTF_L2(PRINT_MASK_CBOPS, - hwahcp->hwahc_log_handle, - "%s: copyout of size failed.", msg); - rv = EIO; - } - } else { - if (ioc.bufsiz != size) { - USB_DPRINTF_L2(PRINT_MASK_CBOPS, - hwahcp->hwahc_log_handle, - "%s: buffer wrong size.", msg); - rv = EINVAL; - } else if (ddi_copyout((void *)path, - ioc.buf, ioc.bufsiz, mode) != 0) { - USB_DPRINTF_L2(PRINT_MASK_CBOPS, - hwahcp->hwahc_log_handle, - "%s: copyout failed.", msg); - rv = EIO; - } - } - kmem_free(path, MAXPATHLEN); - - break; - } - case HUBD_REFRESH_DEVDB: - msg = "DEVCTL_AP_CONTROL: HUBD_REFRESH_DEVDB"; - USB_DPRINTF_L4(PRINT_MASK_CBOPS, - hwahcp->hwahc_log_handle, "%s", msg); - - if ((rv = usba_devdb_refresh()) != USB_SUCCESS) { - USB_DPRINTF_L2(PRINT_MASK_CBOPS, - hwahcp->hwahc_log_handle, - "%s: Failed: %d", msg, rv); - rv = EIO; - } - - break; - default: - rv = ENOTSUP; - } /* end switch */ - - break; - } - - default: - rv = ENOTTY; - } - - if (dcp) { - ndi_dc_freehdl(dcp); - } - - mutex_exit(&hwahcp->hwahc_mutex); - - ndi_devi_exit(hwahcp->hwahc_dip, circ); - ndi_devi_exit(rh_dip, rh_circ); - ndi_devi_exit(ddi_get_parent(rh_dip), prh_circ); - - return (rv); -} - -/* update CHID for the hc driver, return 0 on success */ -static int -hwahc_set_chid(hwahc_state_t *hwahcp, uint8_t *chid) -{ - wusb_hc_data_t *hc_data = &hwahcp->hwahc_hc_data; - - ASSERT(!mutex_owned(&hc_data->hc_mutex)); - - /* same as the old CHID, return success */ - if (memcmp(chid, hc_data->hc_chid, 16) == 0) { - - return (0); - } - - /* - * stop hw from working before updating CHID - * this may not be necessary but so far we don't know - * other ways to do it safely - */ - if (hwahcp->hwahc_hw_state == HWAHC_HW_STARTED) { - /* use final_stop to fully stop the hwa */ - if (hwahc_hc_final_stop(hwahcp) != USB_SUCCESS) { - - return (EIO); - } - - mutex_enter(&hc_data->hc_mutex); - (void) memcpy(hc_data->hc_chid, chid, 16); - mutex_exit(&hc_data->hc_mutex); - - /* restart the host */ - if (hwahc_hc_initial_start(hwahcp) != USB_SUCCESS) { - - return (EIO); - } - - return (0); - } - - /* hc is stopped or partially stopped, simply update */ - mutex_enter(&hc_data->hc_mutex); - (void) memcpy(hc_data->hc_chid, chid, 16); - mutex_exit(&hc_data->hc_mutex); - - return (0); -} - -/* - * wusbadm ioctl support - */ -/* ARGSUSED */ -static int -hwahc_wusb_ioctl(hwahc_state_t *hwahcp, int cmd, intptr_t arg, - int mode, cred_t *credp, int *rvalp) -{ - int rv = 0; - wusb_hc_data_t *hc_data = &hwahcp->hwahc_hc_data; - - if (drv_priv(credp) != 0) { - USB_DPRINTF_L3(PRINT_MASK_CBOPS, hwahcp->hwahc_log_handle, - "hwahc_wusb_ioctl: user must have SYS_DEVICE privilege," - "cmd=%x", cmd); - - return (EPERM); - } - - mutex_enter(&hwahcp->hwahc_mutex); - - switch (cmd) { - case WUSB_HC_GET_DSTATE: /* Get device state: wusbadm list */ - { - wusb_hc_get_dstate_t state; - usb_port_t port = 0; - - if (ddi_copyin((void *)arg, (void *)&state, sizeof (state), - mode) != 0) { - rv = EFAULT; - - break; - } - - mutex_enter(&hc_data->hc_mutex); - - if (wusb_hc_is_dev_connected(hc_data, &state.cdid[0], &port)) { - state.state = hc_data->hc_dev_infos[port]->wdev_state; - } else { - /* cdid not found */ - state.state = WUSB_STATE_UNCONNTED; - } - - USB_DPRINTF_L3(PRINT_MASK_CBOPS, hwahcp->hwahc_log_handle, - "hwahc_wusb_ioctl: hc_data=%p, port = %d, state=%d", - (void *) hc_data, port, state.state); - - mutex_exit(&hc_data->hc_mutex); - - if (state.state == WUSB_STATE_CONFIGURED) { - /* Get the bind device node name of this child */ - (void) memset(state.nodename, 0, MAX_USB_NODENAME); - (void) snprintf(state.nodename, MAX_USB_NODENAME, "%s", - ddi_node_name(hwahc_get_child_dip(hwahcp, port))); - - USB_DPRINTF_L3(PRINT_MASK_CBOPS, - hwahcp->hwahc_log_handle, - "WUSB_HC_GET_DSTATE: nodename %s", state.nodename); - } - - if (ddi_copyout((void *)&state, (void *)arg, - sizeof (state), mode) != 0) { - USB_DPRINTF_L2(PRINT_MASK_CBOPS, - hwahcp->hwahc_log_handle, - "WUSB_HC_GET_DSTATE: copyout failed"); - rv = EIO; - } - - break; - } - - case WUSB_HC_GET_MAC_ADDR: /* Get host MAC addr */ - { - uint8_t mac_addr[6]; - - bzero(mac_addr, 6); - - /* - * get UWB 48-bit mac address - * Section 8.6.2.2. - */ - if (uwb_get_mac_addr(hwahcp->hwahc_dip, mac_addr) != - USB_SUCCESS) { - USB_DPRINTF_L2(PRINT_MASK_CBOPS, - hwahcp->hwahc_log_handle, - "WUSB_HC_GET_MAC_ADDR: get mac failed"); - rv = EIO; - - break; - } - - if (ddi_copyout((void *)mac_addr, (void *)arg, - 6, mode) != 0) { - USB_DPRINTF_L2(PRINT_MASK_CBOPS, - hwahcp->hwahc_log_handle, - "WUSB_HC_GET_MAC_ADDR: copyout failed"); - rv = EIO; - } - - break; - } - case WUSB_HC_ADD_CC: - { - /* - * add a new device CC to host's list: wusbadm associate - * Or, the application can pass in a fake CC with only CHID set - * to set the host's CHID. - */ - wusb_hc_cc_list_t *cc_list; - - cc_list = kmem_zalloc(sizeof (wusb_hc_cc_list_t), KM_SLEEP); - - if (ddi_copyin((void *)arg, (void *)&cc_list->cc, - sizeof (wusb_cc_t), mode) != 0) { - rv = EFAULT; - kmem_free(cc_list, sizeof (wusb_hc_cc_list_t)); - - break; - } - - /* update CHID only when cc list is empty */ - mutex_enter(&hc_data->hc_mutex); - if (hc_data->hc_cc_list == NULL) { - mutex_exit(&hc_data->hc_mutex); - - if ((rv = hwahc_set_chid(hwahcp, - cc_list->cc.CHID)) != 0) { - kmem_free(cc_list, sizeof (wusb_hc_cc_list_t)); - - break; - } - - mutex_enter(&hc_data->hc_mutex); - } else { - /* fail if the CHID in the new CC does not match */ - if (memcmp(cc_list->cc.CHID, hc_data->hc_chid, - 16) != 0) { - rv = EINVAL; - kmem_free(cc_list, sizeof (wusb_hc_cc_list_t)); - - mutex_exit(&hc_data->hc_mutex); - break; - } - } - cc_list->next = NULL; - - wusb_hc_add_cc(&hc_data->hc_cc_list, cc_list); - mutex_exit(&hc_data->hc_mutex); - - break; - } - case WUSB_HC_REM_CC: - { - wusb_cc_t cc; - usb_port_t port; - - if (ddi_copyin((void *)arg, (void *)&cc, sizeof (wusb_cc_t), - mode) != 0) { - rv = EFAULT; - - break; - } - - /* check if the CHID in the CC matches */ - if (memcmp(cc.CHID, hc_data->hc_chid, 16) != 0) { - rv = EINVAL; - - break; - } - - /* if the device is connected, disconnect it first */ - mutex_enter(&hc_data->hc_mutex); - if (wusb_hc_is_dev_connected(hc_data, cc.CDID, &port)) { - mutex_exit(&hc_data->hc_mutex); - mutex_exit(&hwahcp->hwahc_mutex); - /* - * clean up host side state, device not - * really disconnected. But user can safely remove - * the device now. - */ - (void) hwahc_destroy_child(hc_data->hc_dip, port); - mutex_enter(&hwahcp->hwahc_mutex); - mutex_enter(&hc_data->hc_mutex); - } - - wusb_hc_rem_cc(&hc_data->hc_cc_list, &cc); - mutex_exit(&hc_data->hc_mutex); - - break; - } - case WUSB_HC_SET_CHANNEL: /* for debug purpose */ - { - uint8_t channel; - - channel = (uint8_t)arg; - - if (hwahcp->hwahc_hc_data.hc_channel == channel) { - USB_DPRINTF_L2(PRINT_MASK_CBOPS, - hwahcp->hwahc_log_handle, - "WUSB_HC_SET_CHANNEL ioctl: same as existing"); - - break; - } - - if (hwahcp->hwahc_hw_state != HWAHC_HW_STOPPED) { - /* beacon is already started, stop it first */ - if (uwb_stop_beacon(hwahcp->hwahc_dip) != USB_SUCCESS) { - USB_DPRINTF_L2(PRINT_MASK_CBOPS, - hwahcp->hwahc_log_handle, - "WUSB_HC_SET_CHANNEL ioctl: " - "stop beacon failed"); - rv = EIO; - - break; - } - /* update channel number */ - hwahcp->hwahc_hc_data.hc_channel = channel; - /* restart beacon on the new channel */ - if (uwb_start_beacon(hwahcp->hwahc_dip, - channel) != USB_SUCCESS) { - USB_DPRINTF_L2(PRINT_MASK_CBOPS, - hwahcp->hwahc_log_handle, - "WUSB_HC_SET_CHANNEL ioctl: " - "restart beacon failed"); - rv = EIO; - } - - break; - } - - /* beacon is not started, simply update channel number */ - hwahcp->hwahc_hc_data.hc_channel = channel; - - break; - } - case WUSB_HC_START: - { - int flag; - - - flag = (int)arg; - - if (hwahcp->hwahc_hw_state == HWAHC_HW_STARTED) { - USB_DPRINTF_L2(PRINT_MASK_CBOPS, - hwahcp->hwahc_log_handle, - "WUSB_HC_START ioctl: already started"); - - break; - } - - /* - * now we start hc only when the cc list is not NULL - * this limitation may be removed if we support - * numeric association, but CHID needs to be set - * in advance for the hc to work - */ - mutex_enter(&hc_data->hc_mutex); - if (hc_data->hc_cc_list == NULL) { - USB_DPRINTF_L2(PRINT_MASK_CBOPS, - hwahcp->hwahc_log_handle, - "WUSB_HC_START ioctl: cc list not inited"); - rv = EINVAL; - - mutex_exit(&hc_data->hc_mutex); - - break; - } - mutex_exit(&hc_data->hc_mutex); - - /* cannot be both */ - if ((flag & WUSB_HC_INITIAL_START) && (flag & - WUSB_HC_CHANNEL_START)) { - USB_DPRINTF_L2(PRINT_MASK_CBOPS, - hwahcp->hwahc_log_handle, - "WUSB_HC_START ioctl: flag cannot coexist"); - rv = EINVAL; - - break; - } - - /* - * init Mac layer 16-bit dev addr. it is important for - * authentication. It'd be better to let UWB provide - * this address. - */ - mutex_enter(&hc_data->hc_mutex); - if (hc_data->hc_addr == 0) { - uint16_t dev_addr = HWAHC_DEV_ADDR_BASE + - ddi_get_instance(hwahcp->hwahc_dip); - - mutex_exit(&hc_data->hc_mutex); - /* set UWB 16-bit dev address */ - if (uwb_set_dev_addr(hwahcp->hwahc_dip, - dev_addr) != USB_SUCCESS) { - USB_DPRINTF_L2(PRINT_MASK_CBOPS, - hwahcp->hwahc_log_handle, - "WUSB_HC_START ioctl: set dev addr failed"); - rv = EIO; - - break; - } - - /* verify the dev addr is set correctly */ - if (uwb_get_dev_addr(hwahcp->hwahc_dip, - &dev_addr) != USB_SUCCESS) { - USB_DPRINTF_L2(PRINT_MASK_CBOPS, - hwahcp->hwahc_log_handle, - "WUSB_HC_START ioctl: get dev addr failed"); - rv = EIO; - - break; - } - - mutex_enter(&hc_data->hc_mutex); - hc_data->hc_addr = dev_addr; - USB_DPRINTF_L2(PRINT_MASK_CBOPS, - hwahcp->hwahc_log_handle, - "host dev addr = 0x%x", dev_addr); - } - mutex_exit(&hc_data->hc_mutex); - - /* start functions of wusb host */ - if ((flag & WUSB_HC_INITIAL_START) && - (hwahcp->hwahc_hw_state == HWAHC_HW_STOPPED)) { - if (hwahc_hc_initial_start(hwahcp) != USB_SUCCESS) { - rv = EIO; - } - } else if ((flag & WUSB_HC_CHANNEL_START) && - (hwahcp->hwahc_hw_state == HWAHC_HW_CH_STOPPED)) { - if (hwahc_hc_channel_start(hwahcp) != USB_SUCCESS) { - rv = EIO; - } - } else { - USB_DPRINTF_L2(PRINT_MASK_CBOPS, - hwahcp->hwahc_log_handle, - "WUSB_HC_START ioctl: unknown flag (%d) or " - "state (%d)", flag, hwahcp->hwahc_hw_state); - rv = EINVAL; - } - - break; - } - case WUSB_HC_STOP: - { - int flag; - - flag = (int)arg; - - /* cannot be both */ - if ((flag & WUSB_HC_FINAL_STOP) && (flag & - WUSB_HC_CHANNEL_STOP)) { - USB_DPRINTF_L2(PRINT_MASK_CBOPS, - hwahcp->hwahc_log_handle, - "WUSB_HC_STOP ioctl: flag cannot coexist"); - rv = EINVAL; - - break; - } - - if (flag & WUSB_HC_FINAL_STOP) { - if (hwahc_hc_final_stop(hwahcp) != USB_SUCCESS) { - rv = EIO; - } - } else if (flag & WUSB_HC_CHANNEL_STOP) { - if (hwahc_hc_channel_stop(hwahcp) != USB_SUCCESS) { - rv = EIO; - } - } else { - /* must be one of the STOP flag */ - USB_DPRINTF_L2(PRINT_MASK_CBOPS, - hwahcp->hwahc_log_handle, - "WUSB_HC_STOP ioctl: invalid flag = %d", flag); - rv = EINVAL; - } - - /* REM_ALL_CC flag is optional */ - if ((rv == 0) && (flag & WUSB_HC_REM_ALL_CC)) { - mutex_enter(&hc_data->hc_mutex); - if (hc_data->hc_cc_list) { - wusb_hc_free_cc_list(hc_data->hc_cc_list); - hc_data->hc_cc_list = NULL; - } - mutex_exit(&hc_data->hc_mutex); - } - - break; - } - case WUSB_HC_GET_HSTATE: - { - int state; - - if (hwahcp->hwahc_dev_state == USB_DEV_DISCONNECTED) { - state = WUSB_HC_DISCONNTED; - } else { - switch (hwahcp->hwahc_hw_state) { - case HWAHC_HW_STOPPED: - state = WUSB_HC_STOPPED; - break; - case HWAHC_HW_STARTED: - state = WUSB_HC_STARTED; - break; - case HWAHC_HW_CH_STOPPED: - /* - * app can mark the hwa as disabled - * for this state - */ - state = WUSB_HC_CH_STOPPED; - break; - } - } - - if (ddi_copyout((void *)&state, (void *)arg, - sizeof (int), mode) != 0) { - USB_DPRINTF_L2(PRINT_MASK_CBOPS, - hwahcp->hwahc_log_handle, - "WUSB_HC_GET_HSTATE: copyout failed"); - rv = EIO; - } - - break; - } - default: - USB_DPRINTF_L2(PRINT_MASK_CBOPS, hwahcp->hwahc_log_handle, - "hwahc_ioctl: unsupported command"); - - rv = ENOTSUP; - } - mutex_exit(&hwahcp->hwahc_mutex); - - return (rv); -} - -static int -hwahc_ioctl(dev_t dev, int cmd, intptr_t arg, - int mode, cred_t *credp, int *rvalp) -{ - hwahc_state_t *hwahcp; - int rval; - - if ((hwahcp = ddi_get_soft_state(hwahc_statep, - HWAHC_MINOR_TO_INSTANCE(getminor(dev)))) == NULL) { - - return (ENXIO); - } - - USB_DPRINTF_L4(PRINT_MASK_CBOPS, hwahcp->hwahc_log_handle, - "hwahc_ioctl: cmd=%x, arg=%lx, mode=%x, cred=%p, rval=%p dev=0x%lx", - cmd, arg, mode, (void *) credp, (void *) rvalp, dev); - - if (IS_DEVCTL(cmd)) { - /* for cfgadm cmd support */ - rval = hwahc_cfgadm_ioctl(hwahcp, cmd, arg, mode, credp, rvalp); - } else { - /* for wusbadm cmd support */ - rval = hwahc_wusb_ioctl(hwahcp, cmd, arg, mode, credp, rvalp); - } - - return (rval); -} - -/* return the port number corresponding the child dip */ -static usb_port_t -hwahc_child_dip2port(hwahc_state_t *hwahcp, dev_info_t *dip) -{ - usb_port_t port; - wusb_hc_data_t *hc_data = &hwahcp->hwahc_hc_data; - - mutex_enter(&hc_data->hc_mutex); - for (port = 1; port <= hc_data->hc_num_ports; port++) { - if (hc_data->hc_children_dips[port] == dip) { - - break; - } - } - ASSERT(port <= hc_data->hc_num_ports); - mutex_exit(&hc_data->hc_mutex); - - return (port); -} - -/* - * child post attach/detach notification - */ -static void -hwahc_post_attach(hwahc_state_t *hwahcp, dev_info_t *rdip, - struct attachspec *as) -{ - /* we don't need additional process for post-attach now */ - USB_DPRINTF_L3(PRINT_MASK_EVENTS, hwahcp->hwahc_log_handle, - "hwahc_post_attach: rdip = 0x%p result = %d", (void *) rdip, - as->result); -} - -static void -hwahc_post_detach(hwahc_state_t *hwahcp, dev_info_t *rdip, - struct detachspec *as) -{ - /* we don't need additional process for post-detach now */ - USB_DPRINTF_L3(PRINT_MASK_EVENTS, hwahcp->hwahc_log_handle, - "hwahc_post_detach: rdip = 0x%p result = %d", (void *) rdip, - as->result); -} - -/* - * bus ctl support. - * To support different operations, such as a PreAttach preparation, - * PostAttach operations. HWA only process the interested operations. - * Other general ones are processed by usba_bus_ctl(). - */ -static int -hwahc_bus_ctl(dev_info_t *dip, /* dip could be the parent */ - dev_info_t *rdip, /* rdip is the dev node to be operated */ - ddi_ctl_enum_t op, - void *arg, - void *result) -{ - usba_device_t *usba_device = usba_get_usba_device(rdip); - dev_info_t *hubdip = usba_device->usb_root_hub_dip; - hwahc_state_t *hwahcp; - struct attachspec *as; - struct detachspec *ds; - - if ((hwahcp = ddi_get_soft_state(hwahc_statep, - ddi_get_instance(dip))) == NULL) { - - return (DDI_FAILURE); - } - - USB_DPRINTF_L2(PRINT_MASK_EVENTS, hwahcp->hwahc_log_handle, - "hwahc_bus_ctl:\n\t" - "dip = 0x%p, rdip = 0x%p, op = 0x%x, arg = 0x%p", - (void *) dip, (void *) rdip, op, (void *) arg); - - switch (op) { - case DDI_CTLOPS_ATTACH: - as = (struct attachspec *)arg; - - switch (as->when) { - case DDI_PRE : - /* nothing to do basically */ - USB_DPRINTF_L2(PRINT_MASK_EVENTS, - hwahcp->hwahc_log_handle, - "DDI_PRE DDI_CTLOPS_ATTACH"); - break; - case DDI_POST : - hwahc_post_attach(hwahcp, rdip, - (struct attachspec *)arg); - break; - } - - break; - case DDI_CTLOPS_DETACH: - ds = (struct detachspec *)arg; - - switch (ds->when) { - case DDI_PRE : - /* nothing to do basically */ - USB_DPRINTF_L2(PRINT_MASK_EVENTS, - hwahcp->hwahc_log_handle, - "DDI_PRE DDI_CTLOPS_DETACH"); - break; - case DDI_POST : - hwahc_post_detach(hwahcp, rdip, - (struct detachspec *)arg); - break; - } - - break; - case DDI_CTLOPS_REPORTDEV: /* the workhorse behind ddi_report_dev */ - { - char *name, compat_name[64]; - - if (usb_owns_device(rdip)) { - (void) snprintf(compat_name, - sizeof (compat_name), - "usb%x,%x", - usba_device->usb_dev_descr->idVendor, - usba_device->usb_dev_descr->idProduct); - } else if (usba_owns_ia(rdip)) { - (void) snprintf(compat_name, - sizeof (compat_name), - "usbia%x,%x.config%x.%x", - usba_device->usb_dev_descr->idVendor, - usba_device->usb_dev_descr->idProduct, - usba_device->usb_cfg_value, - usb_get_if_number(rdip)); - } else { - (void) snprintf(compat_name, - sizeof (compat_name), - "usbif%x,%x.config%x.%x", - usba_device->usb_dev_descr->idVendor, - usba_device->usb_dev_descr->idProduct, - usba_device->usb_cfg_value, - usb_get_if_number(rdip)); - } - - cmn_err(CE_CONT, - "?USB %x.%x %s (%s) operating wirelessly with " - "HWA device: " - "%s@%s, %s%d at bus address %d\n", - (usba_device->usb_dev_descr->bcdUSB & 0xff00) >> 8, - usba_device->usb_dev_descr->bcdUSB & 0xff, - (usb_owns_device(rdip) ? "device" : - ((usba_owns_ia(rdip) ? "interface-association" : - "interface"))), - compat_name, - ddi_node_name(rdip), ddi_get_name_addr(rdip), - ddi_driver_name(rdip), - ddi_get_instance(rdip), usba_device->usb_addr); - - name = kmem_alloc(MAXNAMELEN, KM_SLEEP); - (void) usba_get_mfg_prod_sn_str(rdip, name, MAXNAMELEN); - if (name[0] != '\0') { - cmn_err(CE_CONT, "?\t%s\n", name); - } - kmem_free(name, MAXNAMELEN); - - break; - } - default: - /* pass to usba to handle */ - return (usba_bus_ctl(hubdip, rdip, op, arg, result)); - } - - return (DDI_SUCCESS); -} - -/* - * bus enumeration entry points - * Configures the named device(BUS_CONFIG_ONE) or all devices under - * the nexus(BUS_CONFIG_ALL). Drives devinfo state to DS_READY,i.e.device - * is fully operational. - * - * This operation is driven from devfs(reading /devices), devctl, libdevinfo; - * or from within the kernel to attach a boot device or layered underlying - * driver. - */ -static int -hwahc_bus_config(dev_info_t *dip, uint_t flag, ddi_bus_config_op_t op, - void *arg, dev_info_t **child) -{ - hwahc_state_t *hwahcp; - int rval, circ; - - if ((hwahcp = ddi_get_soft_state(hwahc_statep, - ddi_get_instance(dip))) == NULL) { - - return (NDI_FAILURE); - } - - USB_DPRINTF_L3(PRINT_MASK_EVENTS, hwahcp->hwahc_log_handle, - "hwahc_bus_config: op=%d", op); - - if (hwahc_bus_config_debug) { - flag |= NDI_DEVI_DEBUG; - } - - ndi_devi_enter(dip, &circ); - rval = ndi_busop_bus_config(dip, flag, op, arg, child, 0); - ndi_devi_exit(dip, circ); - - return (rval); -} - -/* - * Unconfigures the named device or all devices under the nexus. The - * devinfo state is not DS_READY anymore. - * This operations is driven by modunload, devctl or DR branch removal or - * rem_drv(1M). - */ -static int -hwahc_bus_unconfig(dev_info_t *dip, uint_t flag, ddi_bus_config_op_t op, - void *arg) -{ - hwahc_state_t *hwahcp; - wusb_hc_data_t *hc_data; - dev_info_t *cdip; - usb_port_t port; - int rval, circ; - - if ((hwahcp = ddi_get_soft_state(hwahc_statep, - ddi_get_instance(dip))) == NULL) { - - return (NDI_FAILURE); - } - - USB_DPRINTF_L3(PRINT_MASK_EVENTS, hwahcp->hwahc_log_handle, - "hwahc_bus_unconfig: op=%d", op); - - if (hwahc_bus_config_debug) { - flag |= NDI_DEVI_DEBUG; - } - - if ((op == BUS_UNCONFIG_ALL) && (flag & NDI_AUTODETACH) == 0) { - flag |= NDI_DEVI_REMOVE; - } - - /* serialize access */ - ndi_devi_enter(dip, &circ); - - /* unconfig children, detach them */ - rval = ndi_busop_bus_unconfig(dip, flag, op, arg); - - /* logically zap children's list */ - hc_data = &hwahcp->hwahc_hc_data; - - mutex_enter(&hc_data->hc_mutex); - for (port = 1; port <= hc_data->hc_num_ports; port++) { - hc_data->hc_children_state[port] |= WUSB_CHILD_ZAP; - } - mutex_exit(&hc_data->hc_mutex); - - /* fill in what's left */ - for (cdip = ddi_get_child(dip); cdip; - cdip = ddi_get_next_sibling(cdip)) { - usba_device_t *usba_device = usba_get_usba_device(cdip); - - if (usba_device == NULL) { - - continue; - } - mutex_enter(&hc_data->hc_mutex); - port = usba_device->usb_port; - hc_data->hc_children_dips[port] = cdip; - hc_data->hc_children_state[port] &= ~WUSB_CHILD_ZAP; - mutex_exit(&hc_data->hc_mutex); - } - - /* physically zap the children we didn't find */ - mutex_enter(&hc_data->hc_mutex); - for (port = 1; port <= hc_data->hc_num_ports; port++) { - if (hc_data->hc_children_state[port] & WUSB_CHILD_ZAP) { - wusb_dev_info_t *dev_info; - wusb_secrt_data_t *csecrt_data; - usba_device_t *child_ud; - - USB_DPRINTF_L3(PRINT_MASK_EVENTS, - hwahcp->hwahc_log_handle, - "hwahc_bus_unconfig: physically zap port %d", port); - - child_ud = hc_data->hc_usba_devices[port]; - mutex_exit(&hc_data->hc_mutex); - /* zap the dip and usba_device structure as well */ - usba_free_usba_device(child_ud); - mutex_enter(&hc_data->hc_mutex); - hc_data->hc_usba_devices[port] = NULL; - - /* dip freed in usba_destroy_child_devi */ - hc_data->hc_children_dips[port] = NULL; - hc_data->hc_children_state[port] &= ~WUSB_CHILD_ZAP; - - /* free hc_dev_infos[port] */ - dev_info = hc_data->hc_dev_infos[port]; - if (dev_info == NULL) { - - continue; - } - - /* stop the device's trust timer before deallocate it */ - hwahc_stop_trust_timer(dev_info); - - if (dev_info->wdev_secrt_data.secrt_encry_descr) { - csecrt_data = &dev_info->wdev_secrt_data; - kmem_free(csecrt_data->secrt_encry_descr, - sizeof (usb_encryption_descr_t) * - csecrt_data->secrt_n_encry); - } - if (dev_info->wdev_uwb_descr) { - kmem_free(dev_info->wdev_uwb_descr, - sizeof (usb_uwb_cap_descr_t)); - } - kmem_free(dev_info, sizeof (wusb_dev_info_t)); - hc_data->hc_dev_infos[port] = NULL; - } - } - mutex_exit(&hc_data->hc_mutex); - - ndi_devi_exit(dip, circ); - - USB_DPRINTF_L3(PRINT_MASK_EVENTS, hwahcp->hwahc_log_handle, - "hwahc_bus_unconfig: rval=%d", rval); - - return (rval); -} - -/* - * busctl event support - * - * Called by ndi_busop_get_eventcookie(). Return a event cookie - * associated with one event name. - * The eventname should be the one we defined in hwahc_ndi_event_defs - */ -static int -hwahc_busop_get_eventcookie(dev_info_t *dip, - dev_info_t *rdip, - char *eventname, - ddi_eventcookie_t *cookie) -{ - hwahc_state_t *hwahcp; - - if ((hwahcp = ddi_get_soft_state(hwahc_statep, - ddi_get_instance(dip))) == NULL) { - - return (NDI_FAILURE); - } - - USB_DPRINTF_L3(PRINT_MASK_EVENTS, hwahcp->hwahc_log_handle, - "hwahc_busop_get_eventcookie: dip=0x%p, rdip=0x%p, " - "event=%s", (void *)dip, (void *)rdip, eventname); - USB_DPRINTF_L3(PRINT_MASK_EVENTS, hwahcp->hwahc_log_handle, - "(dip=%s%d, rdip=%s%d)", - ddi_driver_name(dip), ddi_get_instance(dip), - ddi_driver_name(rdip), ddi_get_instance(rdip)); - - /* return event cookie, iblock cookie, and level */ - return (ndi_event_retrieve_cookie(hwahcp->hwahc_ndi_event_hdl, - rdip, eventname, cookie, NDI_EVENT_NOPASS)); -} - -/* - * Add event handler for a given event cookie - */ -static int -hwahc_busop_add_eventcall(dev_info_t *dip, - dev_info_t *rdip, - ddi_eventcookie_t cookie, - void (*callback)(dev_info_t *dip, - ddi_eventcookie_t cookie, void *arg, - void *bus_impldata), - void *arg, ddi_callback_id_t *cb_id) -{ - hwahc_state_t *hwahcp; - usb_port_t port; - - if ((hwahcp = ddi_get_soft_state(hwahc_statep, - ddi_get_instance(dip))) == NULL) { - - return (NDI_FAILURE); - } - - port = hwahc_child_dip2port(hwahcp, rdip); - - mutex_enter(&hwahcp->hwahc_mutex); - - USB_DPRINTF_L3(PRINT_MASK_EVENTS, hwahcp->hwahc_log_handle, - "hwahc_busop_add_eventcall: dip=0x%p, rdip=0x%p " - "cookie=0x%p, cb=0x%p, arg=0x%p", - (void *)dip, (void *)rdip, (void *)cookie, (void *)callback, arg); - USB_DPRINTF_L3(PRINT_MASK_EVENTS, hwahcp->hwahc_log_handle, - "(dip=%s%d, rdip=%s%d, event=%s)", - ddi_driver_name(dip), ddi_get_instance(dip), - ddi_driver_name(rdip), ddi_get_instance(rdip), - ndi_event_cookie_to_name(hwahcp->hwahc_ndi_event_hdl, cookie)); - - /* Set flag on children registering events */ - switch (ndi_event_cookie_to_tag(hwahcp->hwahc_ndi_event_hdl, cookie)) { - case USBA_EVENT_TAG_HOT_REMOVAL: - hwahcp->hwahc_child_events[port] |= - HWAHC_CHILD_EVENT_DISCONNECT; - - break; - case USBA_EVENT_TAG_PRE_SUSPEND: - hwahcp->hwahc_child_events[port] |= - HWAHC_CHILD_EVENT_PRESUSPEND; - - break; - default: - - break; - } - - mutex_exit(&hwahcp->hwahc_mutex); - - /* add callback to our event set */ - return (ndi_event_add_callback(hwahcp->hwahc_ndi_event_hdl, - rdip, cookie, callback, arg, NDI_SLEEP, cb_id)); - -} - - -/* - * Remove a callback previously added by bus_add_eventcall() - */ -static int -hwahc_busop_remove_eventcall(dev_info_t *dip, ddi_callback_id_t cb_id) -{ - hwahc_state_t *hwahcp; - ndi_event_callbacks_t *id = (ndi_event_callbacks_t *)cb_id; - - if ((hwahcp = ddi_get_soft_state(hwahc_statep, - ddi_get_instance(dip))) == NULL) { - - return (NDI_FAILURE); - } - - USB_DPRINTF_L3(PRINT_MASK_EVENTS, hwahcp->hwahc_log_handle, - "hwahc_busop_remove_eventcall: dip=0x%p, rdip=0x%p " - "cookie=0x%p", (void *)dip, (void *) id->ndi_evtcb_dip, - (void *)id->ndi_evtcb_cookie); - USB_DPRINTF_L3(PRINT_MASK_EVENTS, hwahcp->hwahc_log_handle, - "(dip=%s%d, rdip=%s%d, event=%s)", - ddi_driver_name(dip), ddi_get_instance(dip), - ddi_driver_name(id->ndi_evtcb_dip), - ddi_get_instance(id->ndi_evtcb_dip), - ndi_event_cookie_to_name(hwahcp->hwahc_ndi_event_hdl, - id->ndi_evtcb_cookie)); - - /* remove event registration from our event set */ - return (ndi_event_remove_callback(hwahcp->hwahc_ndi_event_hdl, cb_id)); -} - -/* - * hwahc_post_event - * post event to a single child on the port depending on the type, i.e. - * to invoke the child's registered callback. - */ -static void -hwahc_post_event(hwahc_state_t *hwahcp, usb_port_t port, usba_event_t type) -{ - int rval; - dev_info_t *dip; - usba_device_t *usba_device; - ddi_eventcookie_t cookie, rm_cookie, suspend_cookie; - wusb_hc_data_t *hc_data = &hwahcp->hwahc_hc_data; - - USB_DPRINTF_L4(PRINT_MASK_EVENTS, hwahcp->hwahc_log_handle, - "hwahc_post_event: port=%d event=%s", port, - ndi_event_tag_to_name(hwahcp->hwahc_ndi_event_hdl, type)); - - cookie = ndi_event_tag_to_cookie(hwahcp->hwahc_ndi_event_hdl, type); - rm_cookie = ndi_event_tag_to_cookie(hwahcp->hwahc_ndi_event_hdl, - USBA_EVENT_TAG_HOT_REMOVAL); - suspend_cookie = ndi_event_tag_to_cookie(hwahcp->hwahc_ndi_event_hdl, - USBA_EVENT_TAG_PRE_SUSPEND); - - /* - * Hotplug daemon may be attaching a driver that may be registering - * event callbacks. So it already has got the device tree lock and - * event handle mutex. So to prevent a deadlock while posting events, - * we grab and release the locks in the same order. - */ - mutex_enter(&hwahcp->hwahc_mutex); - dip = hwahcp->hwahc_hc_data.hc_children_dips[port]; - usba_device = hwahcp->hwahc_hc_data.hc_usba_devices[port]; - mutex_exit((&hwahcp->hwahc_mutex)); - - switch (type) { - case USBA_EVENT_TAG_HOT_REMOVAL: - /* stop this device's timer to prevent its further process */ - mutex_enter(&hc_data->hc_mutex); - - hwahc_stop_trust_timer(hc_data->hc_dev_infos[port]); - mutex_exit(&hc_data->hc_mutex); - - /* Clear the registered event flag */ - mutex_enter(&hwahcp->hwahc_mutex); - hwahcp->hwahc_child_events[port] &= - ~HWAHC_CHILD_EVENT_DISCONNECT; - mutex_exit(&hwahcp->hwahc_mutex); - - (void) ndi_event_do_callback(hwahcp->hwahc_ndi_event_hdl, - dip, cookie, NULL); - usba_persistent_pipe_close(usba_device); - - /* - * Mark the dip for deletion only after the driver has - * seen the disconnect event to prevent cleanup thread - * from stepping in between. - */ -#ifndef __lock_lint - mutex_enter(&DEVI(dip)->devi_lock); - DEVI_SET_DEVICE_REMOVED(dip); - mutex_exit(&DEVI(dip)->devi_lock); -#endif - - break; - case USBA_EVENT_TAG_PRE_SUSPEND: - mutex_enter(&hwahcp->hwahc_mutex); - hwahcp->hwahc_child_events[port] &= - ~HWAHC_CHILD_EVENT_PRESUSPEND; - mutex_exit(&hwahcp->hwahc_mutex); - - (void) ndi_event_do_callback(hwahcp->hwahc_ndi_event_hdl, - dip, cookie, NULL); - /* - * persistent pipe close for this event is taken care by the - * caller after verfying that all children can suspend - */ - - break; - case USBA_EVENT_TAG_HOT_INSERTION: - /* - * Check if this child has missed the disconnect event before - * it registered for event callbacks - */ - mutex_enter(&hwahcp->hwahc_mutex); - if (hwahcp->hwahc_child_events[port] & - HWAHC_CHILD_EVENT_DISCONNECT) { - /* clear the flag and post disconnect event */ - hwahcp->hwahc_child_events[port] &= - ~HWAHC_CHILD_EVENT_DISCONNECT; - mutex_exit(&hwahcp->hwahc_mutex); - - (void) ndi_event_do_callback( - hwahcp->hwahc_ndi_event_hdl, - dip, rm_cookie, NULL); - usba_persistent_pipe_close(usba_device); - mutex_enter(&hwahcp->hwahc_mutex); - } - mutex_exit(&hwahcp->hwahc_mutex); - - /* - * Mark the dip as reinserted to prevent cleanup thread - * from stepping in. - */ -#ifndef __lock_lint - mutex_enter(&(DEVI(dip)->devi_lock)); - DEVI_SET_DEVICE_REINSERTED(dip); - mutex_exit(&(DEVI(dip)->devi_lock)); -#endif - - rval = usba_persistent_pipe_open(usba_device); - if (rval != USB_SUCCESS) { - USB_DPRINTF_L2(PRINT_MASK_EVENTS, - hwahcp->hwahc_log_handle, - "failed to reopen all pipes on reconnect"); - } - - (void) ndi_event_do_callback(hwahcp->hwahc_ndi_event_hdl, - dip, cookie, NULL); - - /* - * We might see a connect event only if hotplug thread for - * disconnect event don't run in time. - * Set the flag again, so we don't miss posting a - * disconnect event. - */ - mutex_enter(&hwahcp->hwahc_mutex); - hwahcp->hwahc_child_events[port] |= - HWAHC_CHILD_EVENT_DISCONNECT; - mutex_exit(&hwahcp->hwahc_mutex); - - break; - case USBA_EVENT_TAG_POST_RESUME: - /* - * Check if this child has missed the pre-suspend event before - * it registered for event callbacks - */ - mutex_enter(&hwahcp->hwahc_mutex); - if (hwahcp->hwahc_child_events[port] & - HWAHC_CHILD_EVENT_PRESUSPEND) { - /* clear the flag and post pre_suspend event */ - hwahcp->hwahc_child_events[port] &= - ~HWAHC_CHILD_EVENT_PRESUSPEND; - mutex_exit(&hwahcp->hwahc_mutex); - (void) ndi_event_do_callback( - hwahcp->hwahc_ndi_event_hdl, - dip, suspend_cookie, NULL); - mutex_enter(&hwahcp->hwahc_mutex); - } - mutex_exit(&hwahcp->hwahc_mutex); - - mutex_enter(&usba_device->usb_mutex); - usba_device->usb_no_cpr = 0; - mutex_exit(&usba_device->usb_mutex); - - /* - * Since the pipe has already been opened by whub - * at DDI_RESUME time, there is no need for a - * persistent pipe open - */ - (void) ndi_event_do_callback(hwahcp->hwahc_ndi_event_hdl, - dip, cookie, NULL); - - /* - * Set the flag again, so we don't miss posting a - * pre-suspend event. This enforces a tighter - * dev_state model. - */ - mutex_enter(&hwahcp->hwahc_mutex); - hwahcp->hwahc_child_events[port] |= - HWAHC_CHILD_EVENT_PRESUSPEND; - mutex_exit(&hwahcp->hwahc_mutex); - break; - } -} - -/* - * hwahc_run_callbacks: - * Send an event to all children - */ -static void -hwahc_run_callbacks(hwahc_state_t *hwahcp, usba_event_t type) -{ - usb_port_t port; - wusb_hc_data_t *hc_data = &hwahcp->hwahc_hc_data; - - USB_DPRINTF_L4(PRINT_MASK_EVENTS, hwahcp->hwahc_log_handle, - "hwahc_run_callbacks:"); - - mutex_enter(&hc_data->hc_mutex); - for (port = 1; port <= hc_data->hc_num_ports; port++) { - if (hc_data->hc_children_dips[port]) { - mutex_exit(&hc_data->hc_mutex); - hwahc_post_event(hwahcp, port, type); - mutex_enter(&hc_data->hc_mutex); - } - } - mutex_exit(&hc_data->hc_mutex); -} - -/* - * hwahc_disconnect_event_cb: - * Called when hwa device hotplug-removed. - * Close pipes - * Post event to child - * Set state to DISCONNECTED - */ -static int -hwahc_disconnect_event_cb(dev_info_t *dip) -{ - int instance = ddi_get_instance(dip); - hwahc_state_t *hwahcp; - int circ; - - if ((hwahcp = ddi_get_soft_state(hwahc_statep, instance)) == NULL) { - - return (USB_FAILURE); - } - - USB_DPRINTF_L4(PRINT_MASK_EVENTS, hwahcp->hwahc_log_handle, - "hwahc_disconnect_event_cb: dip = 0x%p", (void *)dip); - - ndi_devi_enter(dip, &circ); - - mutex_enter(&hwahcp->hwahc_mutex); - - USB_DPRINTF_L4(PRINT_MASK_EVENTS, hwahcp->hwahc_log_handle, - "hwahc_disconnect_event_cb: devstate= %d hw-state=%d", - hwahcp->hwahc_dev_state, hwahcp->hwahc_hw_state); - switch (hwahcp->hwahc_dev_state) { - case USB_DEV_ONLINE: - case USB_DEV_PWRED_DOWN: - hwahcp->hwahc_dev_state = USB_DEV_DISCONNECTED; - - if (hwahcp->hwahc_hw_state != HWAHC_HW_STOPPED) { - mutex_exit(&hwahcp->hwahc_mutex); - wusb_wa_stop_nep(&hwahcp->hwahc_wa_data); - mutex_enter(&hwahcp->hwahc_mutex); - hwahc_stop_result_thread(hwahcp); - hwahc_drain_notif_queue(hwahcp); - } - /* FALLTHROUGH */ - case USB_DEV_SUSPENDED: - /* remain in this state */ - mutex_exit(&hwahcp->hwahc_mutex); - hwahc_run_callbacks(hwahcp, USBA_EVENT_TAG_HOT_REMOVAL); - mutex_enter(&hwahcp->hwahc_mutex); - - hwahcp->hwahc_hc_soft_state = HWAHC_CTRL_INIT_STATE; - - break; - case USB_DEV_DISCONNECTED: - USB_DPRINTF_L2(PRINT_MASK_EVENTS, hwahcp->hwahc_log_handle, - "hwahc_disconnect_event_cb: already disconnected"); - - break; - default: - USB_DPRINTF_L2(PRINT_MASK_EVENTS, hwahcp->hwahc_log_handle, - "hwahc_disconnect_event_cb: illegal devstate=%d", - hwahcp->hwahc_dev_state); - - break; - } - mutex_exit(&hwahcp->hwahc_mutex); - - ndi_devi_exit(dip, circ); - - return (USB_SUCCESS); -} - - -/* - * hwahc_reconnect_event_cb: - * Called with device hotplug-inserted - * Restore state - */ -static int -hwahc_reconnect_event_cb(dev_info_t *dip) -{ - int instance = ddi_get_instance(dip); - hwahc_state_t *hwahcp; - int circ; - - - if ((hwahcp = ddi_get_soft_state(hwahc_statep, instance)) == NULL) { - - return (USB_FAILURE); - } - - USB_DPRINTF_L4(PRINT_MASK_CBOPS, hwahcp->hwahc_log_handle, - "hwahc_reconnect_event_cb: dip = 0x%p", (void *)dip); - - ndi_devi_enter(dip, &circ); - hwahc_restore_device_state(dip, hwahcp); - ndi_devi_exit(dip, circ); - - return (USB_SUCCESS); -} - - -/* - * hwahc_pre_suspend_event_cb: - * Called before HWA device suspend - */ -static int -hwahc_pre_suspend_event_cb(dev_info_t *dip) -{ - int instance = ddi_get_instance(dip); - hwahc_state_t *hwahcp; - int circ; - - if ((hwahcp = ddi_get_soft_state(hwahc_statep, instance)) == NULL) { - - return (USB_FAILURE); - } - - USB_DPRINTF_L4(PRINT_MASK_EVENTS, hwahcp->hwahc_log_handle, - "hwahc_pre_suspend_event_cb: dip = 0x%p", (void *)dip); - - mutex_enter(&hwahcp->hwahc_mutex); - USB_DPRINTF_L4(PRINT_MASK_PM, hwahcp->hwahc_log_handle, - "hwahc_pre_suspend_event_cb: start, hw state = %d, softstate = %d", - hwahcp->hwahc_hw_state, hwahcp->hwahc_hc_soft_state); - mutex_exit(&hwahcp->hwahc_mutex); - - /* keep PM out till we see a cpr resume */ - (void) hwahc_pm_busy_component(hwahcp); - (void) pm_raise_power(hwahcp->hwahc_dip, 0, USB_DEV_OS_FULL_PWR); - - ndi_devi_enter(dip, &circ); - hwahc_run_callbacks(hwahcp, USBA_EVENT_TAG_PRE_SUSPEND); - ndi_devi_exit(dip, circ); - - /* - * rc driver is always suspended first, that fails the hc suspend. - * need to suspend hc before rc is suspended, so move the suspend - * operations here - */ - mutex_enter(&hwahcp->hwahc_mutex); - if (hwahcp->hwahc_dev_state != USB_DEV_ONLINE) { - USB_DPRINTF_L3(PRINT_MASK_EVENTS, hwahcp->hwahc_log_handle, - "hwahc_pre_suspend_event_cb: dev_state = %d", - hwahcp->hwahc_dev_state); - mutex_exit(&hwahcp->hwahc_mutex); - - return (USB_SUCCESS); - } - - if (hwahcp->hwahc_hw_state == HWAHC_HW_STARTED) { - /* - * notify children the host is going to stop - */ - (void) hwahc_hc_channel_suspend(hwahcp); - } - - /* stop the hc from functioning */ - if (hwahcp->hwahc_hw_state != HWAHC_HW_STOPPED) { - mutex_exit(&hwahcp->hwahc_mutex); - wusb_wa_stop_nep(&hwahcp->hwahc_wa_data); - - mutex_enter(&hwahcp->hwahc_mutex); - hwahc_stop_result_thread(hwahcp); - hwahc_drain_notif_queue(hwahcp); - - mutex_exit(&hwahcp->hwahc_mutex); - (void) wusb_wa_disable(&hwahcp->hwahc_wa_data, - hwahcp->hwahc_default_pipe); - mutex_enter(&hwahcp->hwahc_mutex); - - } - - USB_DPRINTF_L4(PRINT_MASK_PM, hwahcp->hwahc_log_handle, - "hwahc_pre_suspend_event_cb: end, devstate=%d " - "hwstate=%d softstate = %d", - hwahcp->hwahc_dev_state, hwahcp->hwahc_hw_state, - hwahcp->hwahc_hc_soft_state); - - mutex_exit(&hwahcp->hwahc_mutex); - - return (USB_SUCCESS); -} - - -/* - * hwahc_post_resume_event_cb: - * Call after HWA device resume - */ -static int -hwahc_post_resume_event_cb(dev_info_t *dip) -{ - int instance = ddi_get_instance(dip); - hwahc_state_t *hwahcp; - int circ; - - if ((hwahcp = ddi_get_soft_state(hwahc_statep, instance)) == NULL) { - - return (USB_FAILURE); - } - - USB_DPRINTF_L4(PRINT_MASK_EVENTS, hwahcp->hwahc_log_handle, - "hwahc_post_resume_event_cb: dip = 0x%p", (void *)dip); - - mutex_enter(&hwahcp->hwahc_mutex); - - USB_DPRINTF_L4(PRINT_MASK_PM, hwahcp->hwahc_log_handle, - "hwahc_post_resume_event_cb: start, hw state = %d, softstate = %d", - hwahcp->hwahc_hw_state, hwahcp->hwahc_hc_soft_state); - mutex_exit(&hwahcp->hwahc_mutex); - - ndi_devi_enter(dip, &circ); - - /* need to place hc restore here to make sure rc has resumed */ - hwahc_restore_device_state(dip, hwahcp); - - hwahc_run_callbacks(hwahcp, USBA_EVENT_TAG_POST_RESUME); - - ndi_devi_exit(dip, circ); - - /* enable PM */ - (void) hwahc_pm_idle_component(hwahcp); - - return (USB_SUCCESS); -} - - -/* - * hwahc_restore_device_state: - * Called during hotplug-reconnect and resume. - * re-enable power management - * Verify the device is the same as before the disconnect/suspend. - * Restore device state - * Thaw any IO which was frozen. - * Quiesce device. (Other routines will activate if thawed IO.) - * Set device online. - * Leave device disconnected if there are problems. - */ -static void -hwahc_restore_device_state(dev_info_t *dip, hwahc_state_t *hwahcp) -{ - int rval; - int old_hw_state; - - USB_DPRINTF_L4(PRINT_MASK_ATTA, hwahcp->hwahc_log_handle, - "hwahc_restore_device_state: dip = 0x%p", (void *)dip); - - mutex_enter(&hwahcp->hwahc_mutex); - - ASSERT((hwahcp->hwahc_dev_state == USB_DEV_DISCONNECTED) || - (hwahcp->hwahc_dev_state == USB_DEV_SUSPENDED)); - - /* raise power */ - mutex_exit(&hwahcp->hwahc_mutex); - hwahc_pm_busy_component(hwahcp); - (void) pm_raise_power(hwahcp->hwahc_dip, 0, USB_DEV_OS_FULL_PWR); - - /* - * Check if we are talking to the same device - * Some host controllers may see all devices disconnected - * when they just resume. This may be a cause of not - * finding the same device. - * - * Some HWA devices need to download firmware when it is - * powered on. Before the firmware is downloaded, the device - * will look differently. - */ - if (usb_check_same_device(dip, hwahcp->hwahc_log_handle, - USB_LOG_L0, PRINT_MASK_ALL, - USB_CHK_BASIC | USB_CHK_SERIAL | USB_CHK_VIDPID, NULL) != - USB_SUCCESS) { - USB_DPRINTF_L2(PRINT_MASK_ATTA, hwahcp->hwahc_log_handle, - "hwahc_restore_device_state: not the same device"); - /* change the device state from suspended to disconnected */ - mutex_enter(&hwahcp->hwahc_mutex); - hwahcp->hwahc_dev_state = USB_DEV_DISCONNECTED; - hwahcp->hwahc_hc_soft_state = HWAHC_CTRL_ERROR_STATE; - mutex_exit(&hwahcp->hwahc_mutex); - hwahc_pm_idle_component(hwahcp); - - return; - } - - USB_DPRINTF_L3(PRINT_MASK_ATTA, hwahcp->hwahc_log_handle, - "hwahc_restore_device_state: Hwahc has been reconnected but" - " data may have been lost"); - - mutex_enter(&hwahcp->hwahc_mutex); - - /* reinitialize the hw */ - hwahcp->hwahc_dev_state = USB_DEV_ONLINE; - hwahcp->hwahc_hc_soft_state = HWAHC_CTRL_INIT_STATE; - - if (hwahcp->hwahc_hw_state == HWAHC_HW_STOPPED) { - mutex_exit(&hwahcp->hwahc_mutex); - /* no need to start hc */ - hwahc_pm_idle_component(hwahcp); - USB_DPRINTF_L3(PRINT_MASK_ATTA, hwahcp->hwahc_log_handle, - "hwahc_restore_device_state: stopped hwa"); - - return; - } - - - rval = wusb_hc_set_cluster_id(&hwahcp->hwahc_hc_data, - hwahcp->hwahc_hc_data.hc_cluster_id); - - if (rval != USB_SUCCESS) { - USB_DPRINTF_L2(PRINT_MASK_ATTA, hwahcp->hwahc_log_handle, - "hwahc_restore_device_state: set cluster id fails"); - - goto err; - } - - if (hwahcp->hwahc_hw_state == HWAHC_HW_STARTED) { - old_hw_state = hwahcp->hwahc_hw_state; - hwahcp->hwahc_hw_state = HWAHC_HW_CH_STOPPED; - rval = hwahc_hc_channel_start(hwahcp); - if (rval != USB_SUCCESS) { - USB_DPRINTF_L2(PRINT_MASK_ATTA, - hwahcp->hwahc_log_handle, - "hwahc_restore_device_state: start hc fails"); - hwahcp->hwahc_hw_state = old_hw_state; - - goto err; - } - hwahcp->hwahc_hw_state = old_hw_state; - } - - rval = wusb_hc_set_num_dnts(&hwahcp->hwahc_hc_data, - HWAHC_DEFAULT_DNTS_INTERVAL, HWAHC_DEFAULT_DNTS_SLOT_NUM); - if (rval != USB_SUCCESS) { - USB_DPRINTF_L2(PRINT_MASK_ATTA, hwahcp->hwahc_log_handle, - "hwahc_restore_device_state: set num dnts fails"); - - goto err; - } - - /* set default GTK */ - rval = wusb_hc_set_gtk(&hwahcp->hwahc_hc_data, dft_gtk, dft_gtkid); - if (rval != USB_SUCCESS) { - USB_DPRINTF_L2(PRINT_MASK_ATTA, hwahcp->hwahc_log_handle, - "hwahc_restore_device_state: set gtk fails"); - - goto err; - } - - mutex_exit(&hwahcp->hwahc_mutex); - - rval = wusb_wa_enable(&hwahcp->hwahc_wa_data, - hwahcp->hwahc_default_pipe); - mutex_enter(&hwahcp->hwahc_mutex); - if (rval != USB_SUCCESS) { - USB_DPRINTF_L2(PRINT_MASK_ATTA, hwahcp->hwahc_log_handle, - "hwahc_restore_device_state: enable wa fails"); - - goto err; - } - - /* - * This is a workaround, sometimes the ioctl and reconnect will - * happen at the sametime, so the ioctl will start nep which makes - * the below sart nep fail. Need more work to do to avoid such - * issues - */ - (void) wusb_wa_stop_nep(&hwahcp->hwahc_wa_data); - - rval = wusb_wa_start_nep(&hwahcp->hwahc_wa_data, USB_FLAGS_SLEEP); - if (rval != USB_SUCCESS) { - USB_DPRINTF_L2(PRINT_MASK_ATTA, hwahcp->hwahc_log_handle, - "hwahc_restore_device_state: start notifep fails rval =%d", - rval); - mutex_exit(&hwahcp->hwahc_mutex); - (void) wusb_wa_disable(&hwahcp->hwahc_wa_data, - hwahcp->hwahc_default_pipe); - mutex_enter(&hwahcp->hwahc_mutex); - - goto err; - } - - /* Handle transfer results on bulk-in ep */ - rval = hwahc_start_result_thread(hwahcp); - if (rval != USB_SUCCESS) { - USB_DPRINTF_L2(PRINT_MASK_ATTA, hwahcp->hwahc_log_handle, - "hwahc_restore_device_state: start result thread fails"); - mutex_exit(&hwahcp->hwahc_mutex); - wusb_wa_stop_nep(&hwahcp->hwahc_wa_data); - (void) wusb_wa_disable(&hwahcp->hwahc_wa_data, - hwahcp->hwahc_default_pipe); - mutex_enter(&hwahcp->hwahc_mutex); - - goto err; - } - - /* if the device had remote wakeup earlier, enable it again */ - if (hwahcp->hwahc_pm && hwahcp->hwahc_pm->hwahc_wakeup_enabled) { - mutex_exit(&hwahcp->hwahc_mutex); - (void) usb_handle_remote_wakeup(hwahcp->hwahc_dip, - USB_REMOTE_WAKEUP_ENABLE); - mutex_enter(&hwahcp->hwahc_mutex); - } - - hwahcp->hwahc_hw_state = HWAHC_HW_STARTED; - hwahcp->hwahc_hc_soft_state = HWAHC_CTRL_OPERATIONAL_STATE; - mutex_exit(&hwahcp->hwahc_mutex); - hwahc_pm_idle_component(hwahcp); - - return; - -err: - hwahcp->hwahc_hw_state = HWAHC_HW_STOPPED; - mutex_exit(&hwahcp->hwahc_mutex); - hwahc_pm_idle_component(hwahcp); -} - - -/* - * hwahc_cpr_suspend: - * Clean up device. - * Wait for any IO to finish, then close pipes. - * Quiesce device. - * due to the dependency on hwarc, the actual suspend operations are - * moved to hwahc_pre_suspend_event_cb function. - */ -static int -hwahc_cpr_suspend(dev_info_t *dip) -{ - int instance = ddi_get_instance(dip); - hwahc_state_t *hwahcp = ddi_get_soft_state(hwahc_statep, instance); - - if (hwahcp == NULL) { - - return (USB_FAILURE); - } - - USB_DPRINTF_L4(PRINT_MASK_PM, hwahcp->hwahc_log_handle, - "hwahc_cpr_suspend: start"); - - mutex_enter(&hwahcp->hwahc_mutex); - - /* Don't suspend if the device is open. */ - if (hwahcp->hwahc_open_count > 0) { - USB_DPRINTF_L2(PRINT_MASK_PM, hwahcp->hwahc_log_handle, - "hwahc_cpr_suspend: Device is open, cannot suspend"); - mutex_exit(&hwahcp->hwahc_mutex); - - return (USB_FAILURE); - } - - mutex_exit(&hwahcp->hwahc_mutex); - /* raise power */ - hwahc_pm_busy_component(hwahcp); - (void) pm_raise_power(hwahcp->hwahc_dip, 0, USB_DEV_OS_FULL_PWR); - - mutex_enter(&hwahcp->hwahc_mutex); - switch (hwahcp->hwahc_dev_state) { - case USB_DEV_ONLINE: - /* real suspend operations put in pre_suspend function */ - /* FALLTHRU */ - case USB_DEV_DISCONNECTED: - case USB_DEV_PWRED_DOWN: - hwahcp->hwahc_dev_state = USB_DEV_SUSPENDED; - hwahcp->hwahc_hw_state = HWAHC_HW_CH_SUSPEND; - - break; - case USB_DEV_SUSPENDED: - default: - USB_DPRINTF_L2(PRINT_MASK_PM, hwahcp->hwahc_log_handle, - "hwahc_cpr_suspend: illegal dev state=%d", - hwahcp->hwahc_dev_state); - - break; - } - - mutex_exit(&hwahcp->hwahc_mutex); - hwahc_pm_idle_component(hwahcp); - - USB_DPRINTF_L4(PRINT_MASK_PM, hwahcp->hwahc_log_handle, - "hwahc_cpr_suspend: end"); - - return (USB_SUCCESS); -} - - -/* - * hwahc_cpr_resume: - * - * hwahc_restore_device_state marks success by putting device back online - */ -static int -hwahc_cpr_resume(dev_info_t *dip) -{ - int instance = ddi_get_instance(dip); - hwahc_state_t *hwahcp = ddi_get_soft_state(hwahc_statep, instance); - - if (hwahcp == NULL) { - - return (USB_FAILURE); - } - - USB_DPRINTF_L4(PRINT_MASK_PM, hwahcp->hwahc_log_handle, - "hwahc_cpr_resume: hw state = %d, softstate = %d", - hwahcp->hwahc_hw_state, hwahcp->hwahc_hc_soft_state); - - /* - * rc is always resumed after hc. restoring hc before rc would fail. - * move the restoring operations to hwahc_post_resume_event_cb. - */ - - return (USB_SUCCESS); -} - -/* - * hwahc_create_pm_components: - * Create power managements components - */ -static void -hwahc_create_pm_components(dev_info_t *dip, hwahc_state_t *hwahcp) -{ - hwahc_power_t *hwahcpm; - uint_t pwr_states; - - USB_DPRINTF_L4(PRINT_MASK_PM, hwahcp->hwahc_log_handle, - "hwahc_create_pm_components: Begin"); - - /* Allocate the state structure */ - hwahcpm = kmem_zalloc(sizeof (hwahc_power_t), KM_SLEEP); - hwahcp->hwahc_pm = hwahcpm; - hwahcpm->hwahc_state = hwahcp; - hwahcpm->hwahc_pm_capabilities = 0; - hwahcpm->hwahc_current_power = USB_DEV_OS_FULL_PWR; - - if (usb_create_pm_components(dip, &pwr_states) == USB_SUCCESS) { - USB_DPRINTF_L3(PRINT_MASK_PM, hwahcp->hwahc_log_handle, - "hwahc_create_pm_components: created PM components"); - - if (usb_handle_remote_wakeup(dip, - USB_REMOTE_WAKEUP_ENABLE) == USB_SUCCESS) { - hwahcpm->hwahc_wakeup_enabled = 1; - } - hwahcpm->hwahc_pwr_states = (uint8_t)pwr_states; - /* make device busy till end of attach */ - hwahc_pm_busy_component(hwahcp); - (void) pm_raise_power(hwahcp->hwahc_dip, 0, - USB_DEV_OS_FULL_PWR); - } else { - USB_DPRINTF_L3(PRINT_MASK_PM, hwahcp->hwahc_log_handle, - "hwahc_create_pm_components: failed"); - } - - USB_DPRINTF_L4(PRINT_MASK_PM, hwahcp->hwahc_log_handle, - "hwahc_create_pm_components: End"); -} - -/* - * hwahc_destroy_pm_components: - * Shut down and destroy power management and remote wakeup functionality - */ -static void -hwahc_destroy_pm_components(hwahc_state_t *hwahcp) -{ - USB_DPRINTF_L4(PRINT_MASK_PM, hwahcp->hwahc_log_handle, - "hwahc_destroy_pm_components: Begin"); - - ASSERT(!mutex_owned(&hwahcp->hwahc_mutex)); - - mutex_enter(&hwahcp->hwahc_mutex); - if (hwahcp->hwahc_pm && (hwahcp->hwahc_dev_state != - USB_DEV_DISCONNECTED)) { - mutex_exit(&hwahcp->hwahc_mutex); - hwahc_pm_busy_component(hwahcp); - mutex_enter(&hwahcp->hwahc_mutex); - - if (hwahcp->hwahc_pm->hwahc_wakeup_enabled) { - int rval; - - mutex_exit(&hwahcp->hwahc_mutex); - (void) pm_raise_power(hwahcp->hwahc_dip, 0, - USB_DEV_OS_FULL_PWR); - - if ((rval = usb_handle_remote_wakeup( - hwahcp->hwahc_dip, - USB_REMOTE_WAKEUP_DISABLE)) != - USB_SUCCESS) { - USB_DPRINTF_L3(PRINT_MASK_PM, - hwahcp->hwahc_log_handle, - "hwahc_destroy_pm_components: " - "Error disabling rmt wakeup: rval = %d", - rval); - } - } else { - mutex_exit(&hwahcp->hwahc_mutex); - } - - /* - * Since remote wakeup is disabled now, - * no one can raise power and get to device - * once power is lowered here. - */ - (void) pm_lower_power(hwahcp->hwahc_dip, 0, USB_DEV_OS_PWR_OFF); - - hwahc_pm_idle_component(hwahcp); - mutex_enter(&hwahcp->hwahc_mutex); - } - - if (hwahcp->hwahc_pm) { - kmem_free(hwahcp->hwahc_pm, sizeof (hwahc_power_t)); - hwahcp->hwahc_pm = NULL; - } - mutex_exit(&hwahcp->hwahc_mutex); - - USB_DPRINTF_L4(PRINT_MASK_PM, hwahcp->hwahc_log_handle, - "hwahc_destroy_pm_components: End"); -} - -/* mark component busy */ -static void -hwahc_pm_busy_component(hwahc_state_t *hwahcp) -{ - ASSERT(!mutex_owned(&hwahcp->hwahc_mutex)); - - if (hwahcp->hwahc_pm != NULL) { - mutex_enter(&hwahcp->hwahc_mutex); - hwahcp->hwahc_pm->hwahc_pm_busy++; - USB_DPRINTF_L4(PRINT_MASK_PM, hwahcp->hwahc_log_handle, - "hwahc_pm_busy_component: %d", - hwahcp->hwahc_pm->hwahc_pm_busy); - mutex_exit(&hwahcp->hwahc_mutex); - - if (pm_busy_component(hwahcp->hwahc_dip, 0) != - DDI_SUCCESS) { - mutex_enter(&hwahcp->hwahc_mutex); - hwahcp->hwahc_pm->hwahc_pm_busy--; - USB_DPRINTF_L2(PRINT_MASK_PM, - hwahcp->hwahc_log_handle, - "hwahc_pm_busy_component failed: %d", - hwahcp->hwahc_pm->hwahc_pm_busy); - mutex_exit(&hwahcp->hwahc_mutex); - } - } -} - -/* mark component idle */ -static void -hwahc_pm_idle_component(hwahc_state_t *hwahcp) -{ - ASSERT(!mutex_owned(&hwahcp->hwahc_mutex)); - - if (hwahcp->hwahc_pm != NULL) { - - if (pm_idle_component(hwahcp->hwahc_dip, 0) == - DDI_SUCCESS) { - mutex_enter(&hwahcp->hwahc_mutex); - ASSERT(hwahcp->hwahc_pm->hwahc_pm_busy > 0); - hwahcp->hwahc_pm->hwahc_pm_busy--; - USB_DPRINTF_L4(PRINT_MASK_PM, - hwahcp->hwahc_log_handle, - "hwahc_pm_idle_component: %d", - hwahcp->hwahc_pm->hwahc_pm_busy); - mutex_exit(&hwahcp->hwahc_mutex); - } - } -} - -/* - * hwahc_power : - * Power entry point, the workhorse behind pm_raise_power, pm_lower_power, - * usb_req_raise_power and usb_req_lower_power. - */ -/* ARGSUSED */ -static int -hwahc_power(dev_info_t *dip, int comp, int level) -{ - hwahc_state_t *hwahcp; - hwahc_power_t *pm; - int rval = USB_FAILURE; - - hwahcp = ddi_get_soft_state(hwahc_statep, ddi_get_instance(dip)); - - if (hwahcp == NULL) { - - return (DDI_FAILURE); - } - - USB_DPRINTF_L4(PRINT_MASK_PM, hwahcp->hwahc_log_handle, - "hwahc_power: dip = 0x%p", (void *)dip); - - mutex_enter(&hwahcp->hwahc_mutex); - - if (hwahcp->hwahc_pm == NULL) { - - goto done; - } - - pm = hwahcp->hwahc_pm; - - /* Check if we are transitioning to a legal power level */ - if (USB_DEV_PWRSTATE_OK(pm->hwahc_pwr_states, level)) { - USB_DPRINTF_L2(PRINT_MASK_PM, hwahcp->hwahc_log_handle, - "hwahc_power: illegal power level = %d " - "pwr_states: %x", level, pm->hwahc_pwr_states); - - goto done; - } - - switch (level) { - case USB_DEV_OS_PWR_OFF : - rval = hwahc_pwrlvl0(hwahcp); - - break; - case USB_DEV_OS_PWR_1: - rval = hwahc_pwrlvl1(hwahcp); - - break; - case USB_DEV_OS_PWR_2: - rval = hwahc_pwrlvl2(hwahcp); - - break; - case USB_DEV_OS_FULL_PWR : - rval = hwahc_pwrlvl3(hwahcp); - - break; - } -done: - mutex_exit(&hwahcp->hwahc_mutex); - - return ((rval == USB_SUCCESS) ? DDI_SUCCESS : DDI_FAILURE); -} - -/* - * hwahc_pwrlvl0: - * Functions to handle power transition for OS levels 0 -> 3 - * OS 0 <--> USB D3, no or minimal power - */ -static int -hwahc_pwrlvl0(hwahc_state_t *hwahcp) -{ - int rval; - - USB_DPRINTF_L4(PRINT_MASK_PM, hwahcp->hwahc_log_handle, - "hwahc_pwrlvl0: %d", hwahcp->hwahc_pm->hwahc_pm_busy); - - switch (hwahcp->hwahc_dev_state) { - case USB_DEV_ONLINE: - /* Deny the powerdown request if the device is busy */ - if (hwahcp->hwahc_pm->hwahc_pm_busy != 0) { - USB_DPRINTF_L2(PRINT_MASK_PM, - hwahcp->hwahc_log_handle, - "hwahc_pwrlvl0: hwahc_pm is busy"); - - return (USB_FAILURE); - } - /* - * only when final_stop gets called, we allow the system - * to do PM on us. At this moment, we don't need to do - * more operations other than those in final_stop. - */ - - /* Issue USB D3 command to the device here */ - rval = usb_set_device_pwrlvl3(hwahcp->hwahc_dip); - ASSERT(rval == USB_SUCCESS); - - hwahcp->hwahc_dev_state = USB_DEV_PWRED_DOWN; - - hwahcp->hwahc_pm->hwahc_current_power = USB_DEV_OS_PWR_OFF; - - break; - case USB_DEV_DISCONNECTED: - case USB_DEV_SUSPENDED: - case USB_DEV_PWRED_DOWN: - default: - break; - } - - return (USB_SUCCESS); -} - -/* - * hwahc_pwrlvl1: - * Functions to handle power transition to OS levels -> 2 - * OS level 1 <--> D2 - */ -static int -hwahc_pwrlvl1(hwahc_state_t *hwahcp) -{ - int rval; - - USB_DPRINTF_L4(PRINT_MASK_PM, hwahcp->hwahc_log_handle, - "hwahc_pwrlvl1:"); - - /* Issue USB D2 command to the device here */ - rval = usb_set_device_pwrlvl2(hwahcp->hwahc_dip); - ASSERT(rval == USB_SUCCESS); - - return (USB_FAILURE); -} - -/* - * hwahc_pwrlvl2: - * Functions to handle power transition to OS levels -> 1 - * OS leve 2 <--> D1 - */ -static int -hwahc_pwrlvl2(hwahc_state_t *hwahcp) -{ - int rval; - - USB_DPRINTF_L4(PRINT_MASK_PM, hwahcp->hwahc_log_handle, - "hwahc_pwrlvl2:"); - - /* Issue USB D1 command to the device here */ - rval = usb_set_device_pwrlvl1(hwahcp->hwahc_dip); - ASSERT(rval == USB_SUCCESS); - - return (USB_FAILURE); -} - - -/* - * hwahc_pwrlvl3: - * Functions to handle power transition to OS level -> 0 - * OS level 3 <--> D0 (full power) - */ -static int -hwahc_pwrlvl3(hwahc_state_t *hwahcp) -{ - USB_DPRINTF_L4(PRINT_MASK_PM, hwahcp->hwahc_log_handle, - "hwahc_pwrlvl3: %d", hwahcp->hwahc_pm->hwahc_pm_busy); - - ASSERT(mutex_owned(&hwahcp->hwahc_mutex)); - - switch (hwahcp->hwahc_dev_state) { - case USB_DEV_PWRED_DOWN: - /* Issue USB D0 command to the device here */ - (void) usb_set_device_pwrlvl0(hwahcp->hwahc_dip); - - /* - * Due to our current PM policy, it's not possible - * for hwa to be in USB_DEV_PWRED_DOWN between - * initial_start and final_stop. If it's PWRED_DOWN, - * it should not start. We don't need to resume - * soft or hardware state in this case. - */ - if (hwahcp->hwahc_hw_state == HWAHC_HW_STOPPED) { - /* no need to start hc */ - hwahcp->hwahc_dev_state = USB_DEV_ONLINE; - hwahcp->hwahc_pm->hwahc_current_power = - USB_DEV_OS_FULL_PWR; - - return (USB_SUCCESS); - } - - hwahcp->hwahc_pm->hwahc_current_power = USB_DEV_OS_FULL_PWR; - - /* FALLTHRU */ - case USB_DEV_ONLINE: - /* we are already in full power */ - /* FALLTHRU */ - case USB_DEV_DISCONNECTED: - case USB_DEV_SUSPENDED: - /* - * PM framework tries to put you in full power - * during system shutdown. If we are disconnected - * return success. Also, we should not change state - * when we are disconnected or suspended or about to - * transition to that state - */ - - return (USB_SUCCESS); - default: - USB_DPRINTF_L4(PRINT_MASK_PM, hwahcp->hwahc_log_handle, - "hwahc_pwrlvl3: illegal dev_state=%d", - hwahcp->hwahc_dev_state); - - - return (USB_FAILURE); - } -} - -/* - * Host power management: stop channel - * See Section 4.16.2.1 for details - * See Section 8.1.0 for HWA suspend/resume - */ -static int -hwahc_hc_channel_suspend(hwahc_state_t *hwahcp) -{ - int rval; - - USB_DPRINTF_L4(PRINT_MASK_PM, hwahcp->hwahc_log_handle, - "hwahc_hc_channel_suspend:"); - - ASSERT(mutex_owned(&hwahcp->hwahc_mutex)); - - /* no need to suspend if host hw was not started */ - if (hwahcp->hwahc_hw_state != HWAHC_HW_STARTED) { - USB_DPRINTF_L3(PRINT_MASK_PM, hwahcp->hwahc_log_handle, - "hwahc_hc_channel_suspend: hw already stopped"); - - return (USB_SUCCESS); - } - - if (hwahcp->hwahc_hw_state == HWAHC_HW_CH_SUSPEND) { - USB_DPRINTF_L3(PRINT_MASK_PM, hwahcp->hwahc_log_handle, - "hwahc_hc_channel_suspend: already suspended"); - - return (USB_SUCCESS); - } - - mutex_exit(&hwahcp->hwahc_mutex); - /* suspend host, refer to WUSB 1.0 spec 8.5.3.14 */ - rval = wusb_hc_stop_ch(&hwahcp->hwahc_hc_data, 10000); /* 10ms */ - mutex_enter(&hwahcp->hwahc_mutex); - if (rval != USB_SUCCESS) { - USB_DPRINTF_L2(PRINT_MASK_PM, hwahcp->hwahc_log_handle, - "hwahc_hc_channel_suspend: wusb channel stop fails"); - - return (rval); - } - - hwahcp->hwahc_hw_state = HWAHC_HW_CH_SUSPEND; - - return (USB_SUCCESS); -} - -/* - * Parse security descriptors, see T.8-43 - * put result in secrt_data - */ -static int -hwahc_parse_security_data(wusb_secrt_data_t *secrt_data, - usb_cfg_data_t *cfg_data) -{ - int i, j; - usb_cvs_data_t *cvs_data; - size_t count, len; - - if ((secrt_data == NULL) || (cfg_data == NULL)) { - return (USB_INVALID_ARGS); - } - - for (i = 0; i < cfg_data->cfg_n_cvs; i++) { - cvs_data = &cfg_data->cfg_cvs[i]; - if (cvs_data == NULL) { - continue; - } - if (cvs_data->cvs_buf[1] == USB_DESCR_TYPE_SECURITY) { - count = usb_parse_data("ccsc", - cvs_data->cvs_buf, cvs_data->cvs_buf_len, - (void *)&secrt_data->secrt_descr, - (size_t)USB_SECURITY_DESCR_SIZE); - if (count != USB_SECURITY_DESCR_SIZE) { - - return (USB_FAILURE); - } else { - secrt_data->secrt_n_encry = - secrt_data->secrt_descr.bNumEncryptionTypes; - len = sizeof (usb_encryption_descr_t) * - secrt_data->secrt_n_encry; - - secrt_data->secrt_encry_descr = - (usb_encryption_descr_t *)kmem_alloc(len, - KM_SLEEP); - - for (j = 0; j < secrt_data->secrt_n_encry; - j++) { - cvs_data = - &cfg_data->cfg_cvs[i + j + 1]; - if (cvs_data->cvs_buf[1] != - USB_DESCR_TYPE_ENCRYPTION) { - kmem_free(secrt_data-> - secrt_encry_descr, len); - - return (USB_FAILURE); - } - - /* Table 7-34 */ - count = usb_parse_data("ccccc", - cvs_data->cvs_buf, - cvs_data->cvs_buf_len, - (void *)&secrt_data-> - secrt_encry_descr[j], - USB_ENCRYPTION_DESCR_SIZE); - if (count != - USB_ENCRYPTION_DESCR_SIZE) { - kmem_free(secrt_data-> - secrt_encry_descr, len); - - return (USB_FAILURE); - - } - } - return (USB_SUCCESS); - } - } - } - - return (USB_FAILURE); -} - -/* initialize wusb_hc_data_t structure */ -static void -hwahc_hc_data_init(hwahc_state_t *hwahcp) -{ - wusb_hc_data_t *hc_data = &hwahcp->hwahc_hc_data; - - hc_data->hc_dip = hwahcp->hwahc_dip; - hc_data->hc_private_data = (void *)hwahcp; - - (void) memset(hc_data->hc_chid, 0, sizeof (hc_data->hc_chid)); - - hc_data->hc_num_mmcies = hwahcp->hwahc_wa_data.wa_descr.bNumMMCIEs; - - ASSERT(hc_data->hc_num_mmcies != 0); - - hc_data->hc_mmcie_list = kmem_zalloc((hc_data->hc_num_mmcies * - sizeof (wusb_ie_header_t *)), KM_SLEEP); - - /* initialize frequently used IE */ - hc_data->hc_alive_ie.bIEIdentifier = WUSB_IE_DEV_KEEPALIVE; - - /* register callbacks */ - hc_data->disconnect_dev = hwahc_disconnect_dev; - hc_data->reconnect_dev = hwahc_reconnect_dev; - hc_data->create_child = hwahc_create_child; - hc_data->destroy_child = hwahc_destroy_child; - - /* HWA HC operation functions */ - hc_data->set_encrypt = hwahc_set_encrypt; - hc_data->set_ptk = hwahc_set_ptk; - hc_data->set_gtk = hwahc_set_gtk; - hc_data->set_device_info = hwahc_set_device_info; - hc_data->set_cluster_id = hwahc_set_cluster_id; - hc_data->set_stream_idx = hwahc_set_stream_idx; - hc_data->set_wusb_mas = hwahc_set_wusb_mas; - hc_data->add_mmc_ie = hwahc_add_mmc_ie; - hc_data->rem_mmc_ie = hwahc_remove_mmc_ie; - hc_data->stop_ch = hwahc_stop_ch; - hc_data->set_num_dnts = hwahc_set_num_dnts; - hc_data->get_time = hwahc_get_time; - - hc_data->hc_num_ports = hwahcp->hwahc_wa_data.wa_descr.bNumPorts; - - hc_data->hc_cd_list_length = (sizeof (dev_info_t **)) * - (hc_data->hc_num_ports + 1); - - hc_data->hc_children_dips = (dev_info_t **)kmem_zalloc( - hc_data->hc_cd_list_length, KM_SLEEP); - hc_data->hc_usba_devices = (usba_device_t **)kmem_zalloc( - hc_data->hc_cd_list_length, KM_SLEEP); - hc_data->hc_dev_infos = (wusb_dev_info_t **)kmem_zalloc( - hc_data->hc_cd_list_length, KM_SLEEP); - - mutex_init(&hc_data->hc_mutex, NULL, MUTEX_DRIVER, NULL); -} - -/* deinitialize wusb_hc_data_t structure */ -static void -hwahc_hc_data_fini(hwahc_state_t *hwahcp) -{ - int i; - wusb_hc_data_t *hc_data = &hwahcp->hwahc_hc_data; - wusb_ie_header_t *hdr; - -#ifdef DEBUG - usb_port_t port; -#endif - - if (hc_data->hc_mmcie_list) { - /* Free all recorded IEs except statically allocated IEs */ - for (i = 0; i < hc_data->hc_num_mmcies; i++) { - if (hc_data->hc_mmcie_list[i] != NULL) { - hdr = hc_data->hc_mmcie_list[i]; - if ((hdr->bIEIdentifier != - WUSB_IE_DEV_KEEPALIVE)) { - kmem_free(hdr, hdr->bLength); - } - hc_data->hc_mmcie_list[i] = NULL; - } - } - - kmem_free(hc_data->hc_mmcie_list, - hc_data->hc_num_mmcies * sizeof (wusb_ie_header_t *)); - } - - if (hc_data->hc_cluster_id) { - wusb_hc_free_cluster_id(hc_data->hc_cluster_id); - } - - if (hc_data->hc_cc_list) { - wusb_hc_free_cc_list(hc_data->hc_cc_list); - } - -#ifdef DEBUG - for (port = 1; port <= hc_data->hc_num_ports; port++) { - ASSERT(hc_data->hc_usba_devices[port] == NULL); - ASSERT(hc_data->hc_children_dips[port] == NULL); - ASSERT(hc_data->hc_dev_infos[port] == NULL); - } -#endif - - kmem_free(hc_data->hc_children_dips, hc_data->hc_cd_list_length); - kmem_free(hc_data->hc_usba_devices, hc_data->hc_cd_list_length); - kmem_free(hc_data->hc_dev_infos, hc_data->hc_cd_list_length); - - mutex_destroy(&hc_data->hc_mutex); -} - -/* fully start the HWA hw */ -static int -hwahc_hc_initial_start(hwahc_state_t *hwahcp) -{ - uint8_t stream_idx; - uint8_t mas[WUSB_SET_WUSB_MAS_LEN]; - int rval; - uint8_t cluster_id = 0; - - USB_DPRINTF_L4(PRINT_MASK_ATTA, hwahcp->hwahc_log_handle, - "hwahc_hc_initial_start:"); - - ASSERT(mutex_owned(&hwahcp->hwahc_mutex)); - - if (hwahcp->hwahc_dev_state != USB_DEV_ONLINE) { - USB_DPRINTF_L2(PRINT_MASK_ATTA, hwahcp->hwahc_log_handle, - "hwahc_hc_initial_start: invalid dev state = %d", - hwahcp->hwahc_dev_state); - - return (USB_INVALID_REQUEST); - } - - if (hwahcp->hwahc_hw_state != HWAHC_HW_STOPPED) { - USB_DPRINTF_L2(PRINT_MASK_ATTA, hwahcp->hwahc_log_handle, - "hwahc_hc_initial_start: invalid hw state"); - - return (USB_INVALID_REQUEST); - } - - /* - * start beacon of radio layer - * We're not sure if previouse channel is occupied or not. So, let - * UWB allocates a free channel for this hwa. Then we can start - * beacon. - */ - hwahcp->hwahc_hc_data.hc_channel = - uwb_allocate_channel(hwahcp->hwahc_dip); - if (hwahcp->hwahc_hc_data.hc_channel == 0) { - USB_DPRINTF_L2(PRINT_MASK_ATTA, - hwahcp->hwahc_log_handle, - "wusb_hc_initial_start: channel = %d", - hwahcp->hwahc_hc_data.hc_channel); - return (USB_FAILURE); - } - - if ((rval = uwb_start_beacon(hwahcp->hwahc_dip, - hwahcp->hwahc_hc_data.hc_channel)) != USB_SUCCESS) { - USB_DPRINTF_L2(PRINT_MASK_ATTA, - hwahcp->hwahc_log_handle, - "wusb_hc_initial_start: start uwb beacon failed"); - - return (rval); - } - - mutex_exit(&hwahcp->hwahc_mutex); - /* reset wire adapter */ - rval = wusb_wa_reset(&hwahcp->hwahc_wa_data, - hwahcp->hwahc_default_pipe); - mutex_enter(&hwahcp->hwahc_mutex); - if (rval != SUCCESS) { - USB_DPRINTF_L2(PRINT_MASK_ATTA, hwahcp->hwahc_log_handle, - "hwahc_hc_initial_start: reset wa fails"); - - goto err; - } - - /* reuse the old cluster id or assign one */ - if (hwahcp->hwahc_hc_data.hc_cluster_id) { - cluster_id = hwahcp->hwahc_hc_data.hc_cluster_id; - } else { - cluster_id = wusb_hc_get_cluster_id(); - if (cluster_id == 0) { - USB_DPRINTF_L2(PRINT_MASK_ATTA, - hwahcp->hwahc_log_handle, - "hwahc_hc_initial_start: cannot get cluster id"); - rval = USB_NO_RESOURCES; - - goto err; - } - } - - mutex_exit(&hwahcp->hwahc_mutex); - /* set cluster id for the wusb channel */ - rval = wusb_hc_set_cluster_id(&hwahcp->hwahc_hc_data, cluster_id); - if (rval != USB_SUCCESS) { - USB_DPRINTF_L2(PRINT_MASK_ATTA, hwahcp->hwahc_log_handle, - "hwahc_hc_initial_start: set cluster id %d fails", - cluster_id); - mutex_enter(&hwahcp->hwahc_mutex); - - goto err; - } - - /* UWB should be responsible for assigning stream index */ - stream_idx = 1; - - rval = wusb_hc_set_stream_idx(&hwahcp->hwahc_hc_data, stream_idx); - if (rval != USB_SUCCESS) { - USB_DPRINTF_L2(PRINT_MASK_ATTA, hwahcp->hwahc_log_handle, - "hwahc_hc_initial_start: set stream idx %d fails", - stream_idx); - mutex_enter(&hwahcp->hwahc_mutex); - - goto err; - } - - /* set dnts slot */ - rval = wusb_hc_set_num_dnts(&hwahcp->hwahc_hc_data, - HWAHC_DEFAULT_DNTS_INTERVAL, HWAHC_DEFAULT_DNTS_SLOT_NUM); - - if (rval != USB_SUCCESS) { - USB_DPRINTF_L2(PRINT_MASK_ATTA, hwahcp->hwahc_log_handle, - "hwahc_hc_initial_start: set num dnts fails"); - mutex_enter(&hwahcp->hwahc_mutex); - - goto err; - } - - /* set host info IE */ - rval = wusb_hc_add_host_info(&hwahcp->hwahc_hc_data, stream_idx); - if (rval != USB_SUCCESS) { - USB_DPRINTF_L2(PRINT_MASK_ATTA, hwahcp->hwahc_log_handle, - "hwahc_hc_initial_start: add hostinfo ie fails"); - mutex_enter(&hwahcp->hwahc_mutex); - - goto err; - } - - /* reserve MAS slots for the host, need a way to assign */ - (void) memset(mas, 0xff, WUSB_SET_WUSB_MAS_LEN); - mas[0] = 0xf0; /* the first 4 slots are for beacons */ - rval = wusb_hc_set_wusb_mas(&hwahcp->hwahc_hc_data, mas); - mutex_enter(&hwahcp->hwahc_mutex); - if (rval != USB_SUCCESS) { - USB_DPRINTF_L2(PRINT_MASK_ATTA, hwahcp->hwahc_log_handle, - "hwahc_hc_initial_start: set wusb mas fails"); - - goto err; - } - - /* record the available MAS slots */ - (void) memcpy(hwahcp->hwahc_hc_data.hc_mas, mas, WUSB_SET_WUSB_MAS_LEN); - - /* Set initial GTK/TKID to random values */ - (void) random_get_pseudo_bytes(dft_gtk, 16); - (void) random_get_pseudo_bytes(dft_gtkid, 3); - - /* set default GTK, need a way to dynamically compute it */ - mutex_exit(&hwahcp->hwahc_mutex); - rval = wusb_hc_set_gtk(&hwahcp->hwahc_hc_data, dft_gtk, dft_gtkid); - if (rval != USB_SUCCESS) { - USB_DPRINTF_L2(PRINT_MASK_ATTA, hwahcp->hwahc_log_handle, - "hwahc_hc_initial_start: set gtk fails"); - mutex_enter(&hwahcp->hwahc_mutex); - - goto err; - } - - /* enable wire adapter */ - rval = wusb_wa_enable(&hwahcp->hwahc_wa_data, - hwahcp->hwahc_default_pipe); - if (rval != USB_SUCCESS) { - USB_DPRINTF_L2(PRINT_MASK_ATTA, hwahcp->hwahc_log_handle, - "hwahc_hc_initial_start: enable wa fails"); - mutex_enter(&hwahcp->hwahc_mutex); - - goto err; - } - - /* Start Notification endpoint */ - rval = wusb_wa_start_nep(&hwahcp->hwahc_wa_data, USB_FLAGS_SLEEP); - - if (rval != USB_SUCCESS) { - USB_DPRINTF_L2(PRINT_MASK_ATTA, hwahcp->hwahc_log_handle, - "hwahc_hc_initial_start: start notification ep fails"); - (void) wusb_wa_disable(&hwahcp->hwahc_wa_data, - hwahcp->hwahc_default_pipe); - - mutex_enter(&hwahcp->hwahc_mutex); - - goto err; - } - - mutex_enter(&hwahcp->hwahc_mutex); - - /* - * Handle transfer results on bulk-in ep - * The bulk-in ep needs to be polled no matter the completion - * notification is received or not to avoid miss result. - */ - rval = hwahc_start_result_thread(hwahcp); - if (rval != USB_SUCCESS) { - USB_DPRINTF_L2(PRINT_MASK_ATTA, hwahcp->hwahc_log_handle, - "hwahc_hc_initial_start: start result thread fails, " - "rval = %d", rval); - mutex_exit(&hwahcp->hwahc_mutex); - wusb_wa_stop_nep(&hwahcp->hwahc_wa_data); - (void) wusb_wa_disable(&hwahcp->hwahc_wa_data, - hwahcp->hwahc_default_pipe); - mutex_enter(&hwahcp->hwahc_mutex); - - goto err; - } - USB_DPRINTF_L2(PRINT_MASK_ATTA, hwahcp->hwahc_log_handle, - "hwahc_hc_initial_start: start result thread success"); - - hwahcp->hwahc_hw_state = HWAHC_HW_STARTED; - hwahcp->hwahc_hc_soft_state = HWAHC_CTRL_OPERATIONAL_STATE; - - /* Don't do PM on an active beacon hwa until explicitly stopped */ - mutex_exit(&hwahcp->hwahc_mutex); - hwahc_pm_busy_component(hwahcp); - mutex_enter(&hwahcp->hwahc_mutex); - - return (USB_SUCCESS); - -err: - if (cluster_id != 0) { - wusb_hc_free_cluster_id(cluster_id); - } - - mutex_exit(&hwahcp->hwahc_mutex); - (void) uwb_stop_beacon(hwahcp->hwahc_dip); - mutex_enter(&hwahcp->hwahc_mutex); - - return (rval); -} - -/* entirely stop the HWA from working */ -static int -hwahc_hc_final_stop(hwahc_state_t *hwahcp) -{ - USB_DPRINTF_L4(PRINT_MASK_ATTA, hwahcp->hwahc_log_handle, - "hwahc_hc_final_stop:"); - - ASSERT(mutex_owned(&hwahcp->hwahc_mutex)); - - if (hwahcp->hwahc_hw_state == HWAHC_HW_STOPPED) { - USB_DPRINTF_L2(PRINT_MASK_ATTA, hwahcp->hwahc_log_handle, - "hwahc_hc_final_stop: already stopped"); - - return (USB_SUCCESS); - } - - if (hwahcp->hwahc_dev_state == USB_DEV_SUSPENDED) { - USB_DPRINTF_L2(PRINT_MASK_ATTA, hwahcp->hwahc_log_handle, - "hwahc_hc_final_stop: invalid dev state = %d", - hwahcp->hwahc_dev_state); - - return (USB_INVALID_REQUEST); - } - - /* might have been powered down before detaching */ - mutex_exit(&hwahcp->hwahc_mutex); - (void) pm_raise_power(hwahcp->hwahc_dip, 0, USB_DEV_OS_FULL_PWR); - mutex_enter(&hwahcp->hwahc_mutex); - - if (hwahcp->hwahc_dev_state != USB_DEV_DISCONNECTED) { - /* notify children the host is going to stop */ - (void) hwahc_hc_channel_suspend(hwahcp); - - /* release mutex here to avoid deadlock with exc_cb */ - mutex_exit(&hwahcp->hwahc_mutex); - - /* stop notification endpoint */ - wusb_wa_stop_nep(&hwahcp->hwahc_wa_data); - mutex_enter(&hwahcp->hwahc_mutex); - - /* stop bulk-in ept from listening result */ - hwahc_stop_result_thread(hwahcp); - - /* drain the device notifications */ - hwahc_drain_notif_queue(hwahcp); - - /* disable wire adapter */ - mutex_exit(&hwahcp->hwahc_mutex); - (void) wusb_wa_disable(&hwahcp->hwahc_wa_data, - hwahcp->hwahc_default_pipe); - - /* stop beaconing. Not necessary to unreserve mas */ - (void) uwb_stop_beacon(hwahcp->hwahc_dip); - - wusb_hc_rem_host_info(&hwahcp->hwahc_hc_data); - - /* Manually remove all connected children */ - hwahc_run_callbacks(hwahcp, USBA_EVENT_TAG_HOT_REMOVAL); - - /* delete all the children */ - (void) hwahc_cleanup_child(hwahcp->hwahc_dip); - mutex_enter(&hwahcp->hwahc_mutex); - } - - /* - * we make it busy at hwahc_hc_initial_start(). This idle operation - * is to match that busy operation. - * All other busy/idle operations should have been matched. - */ - if ((hwahcp->hwahc_hw_state == HWAHC_HW_STARTED) && - (hwahcp->hwahc_hc_soft_state == HWAHC_CTRL_OPERATIONAL_STATE)) { - USB_DPRINTF_L2(PRINT_MASK_ATTA, hwahcp->hwahc_log_handle, - "hwahc_hc_final_stop: pm_busy=%d", - hwahcp->hwahc_pm->hwahc_pm_busy); - mutex_exit(&hwahcp->hwahc_mutex); - hwahc_pm_idle_component(hwahcp); - mutex_enter(&hwahcp->hwahc_mutex); - } - - hwahcp->hwahc_hw_state = HWAHC_HW_STOPPED; - if (hwahcp->hwahc_hc_soft_state == HWAHC_CTRL_OPERATIONAL_STATE) { - hwahcp->hwahc_hc_soft_state = HWAHC_CTRL_INIT_STATE; - } - - return (USB_SUCCESS); -} - -/* - * init WUSB channel, this is only part of the full hw start operations - * including setting wusb channel stream idx, wusb MAS slots reservation - * and adding host info IE - */ -static int -hwahc_hc_channel_start(hwahc_state_t *hwahcp) -{ - uint8_t stream_idx; - uint8_t mas[WUSB_SET_WUSB_MAS_LEN]; - int rval; - - USB_DPRINTF_L4(PRINT_MASK_ATTA, hwahcp->hwahc_log_handle, - "hwahc_hc_channel_start:"); - - ASSERT(mutex_owned(&hwahcp->hwahc_mutex)); - - if (hwahcp->hwahc_dev_state != USB_DEV_ONLINE) { - USB_DPRINTF_L2(PRINT_MASK_ATTA, hwahcp->hwahc_log_handle, - "hwahc_hc_channel_start: invalid dev_state = %d", - hwahcp->hwahc_dev_state); - - return (USB_INVALID_REQUEST); - } - - if (hwahcp->hwahc_hw_state != HWAHC_HW_CH_STOPPED) { - USB_DPRINTF_L2(PRINT_MASK_ATTA, hwahcp->hwahc_log_handle, - "hwahc_hc_channel_start: invalid hw state"); - - return (USB_INVALID_REQUEST); - } - - /* set stream idx */ - stream_idx = 1; - - mutex_exit(&hwahcp->hwahc_mutex); - rval = wusb_hc_set_stream_idx(&hwahcp->hwahc_hc_data, stream_idx); - if (rval != USB_SUCCESS) { - USB_DPRINTF_L2(PRINT_MASK_ATTA, hwahcp->hwahc_log_handle, - "hwahc_hc_channel_start: set stream idx %d fails", - stream_idx); - mutex_enter(&hwahcp->hwahc_mutex); - - return (rval); - } - - /* reserve MAS slots for the host. Should be allocated by UWB */ - (void) memset(mas, 0xff, WUSB_SET_WUSB_MAS_LEN); - mas[0] = 0xf0; /* for beacons */ - rval = wusb_hc_set_wusb_mas(&hwahcp->hwahc_hc_data, mas); - - if (rval != USB_SUCCESS) { - USB_DPRINTF_L2(PRINT_MASK_ATTA, hwahcp->hwahc_log_handle, - "hwahc_hc_channel_start: set wusb mas fails"); - mutex_enter(&hwahcp->hwahc_mutex); - - return (rval); - } - (void) memcpy(hwahcp->hwahc_hc_data.hc_mas, mas, WUSB_SET_WUSB_MAS_LEN); - - /* set host info IE */ - rval = wusb_hc_add_host_info(&hwahcp->hwahc_hc_data, stream_idx); - - if (rval != USB_SUCCESS) { - USB_DPRINTF_L2(PRINT_MASK_ATTA, hwahcp->hwahc_log_handle, - "hwahc_hc_channel_start: add hostinfo ie fails"); - mutex_enter(&hwahcp->hwahc_mutex); - - return (rval); - } - - mutex_enter(&hwahcp->hwahc_mutex); - hwahcp->hwahc_hw_state = HWAHC_HW_STARTED; - hwahcp->hwahc_hc_soft_state = HWAHC_CTRL_OPERATIONAL_STATE; - - /* do not PM this device, once we're ready to accept DN */ - mutex_exit(&hwahcp->hwahc_mutex); - hwahc_pm_busy_component(hwahcp); - mutex_enter(&hwahcp->hwahc_mutex); - - return (USB_SUCCESS); -} - -/* - * stop WUSB channel, this only stops part of the hw function - * it mainly unreserve the MAS slots and remove the host info IE - */ -static int -hwahc_hc_channel_stop(hwahc_state_t *hwahcp) -{ - uint8_t stream_idx; - uint8_t mas[WUSB_SET_WUSB_MAS_LEN]; - int rval; - - USB_DPRINTF_L4(PRINT_MASK_ATTA, hwahcp->hwahc_log_handle, - "hwahc_hc_channel_stop:"); - - ASSERT(mutex_owned(&hwahcp->hwahc_mutex)); - - if (hwahcp->hwahc_dev_state != USB_DEV_ONLINE) { - USB_DPRINTF_L2(PRINT_MASK_ATTA, hwahcp->hwahc_log_handle, - "hwahc_hc_channel_stop: invalid dev state %d", - hwahcp->hwahc_dev_state); - - return (USB_INVALID_REQUEST); - } - - if (hwahcp->hwahc_hw_state == HWAHC_HW_CH_STOPPED) { - USB_DPRINTF_L2(PRINT_MASK_ATTA, hwahcp->hwahc_log_handle, - "hwahc_hc_channel_stop: already partially stopped"); - - return (USB_SUCCESS); - } - - if (hwahcp->hwahc_hw_state == HWAHC_HW_STOPPED) { - USB_DPRINTF_L2(PRINT_MASK_ATTA, hwahcp->hwahc_log_handle, - "hwahc_hc_channel_stop: already stopped, invalid state"); - - return (USB_INVALID_REQUEST); - } - - /* send host disconect IE so that the children know to disconnect */ - mutex_exit(&hwahcp->hwahc_mutex); - rval = wusb_hc_send_host_disconnect(&hwahcp->hwahc_hc_data); - if (rval != USB_SUCCESS) { - USB_DPRINTF_L2(PRINT_MASK_ATTA, hwahcp->hwahc_log_handle, - "hwahc_hc_channel_stop: send host disconnect ie fails"); - - mutex_enter(&hwahcp->hwahc_mutex); - - return (rval); - } - - /* remove host info IE */ - wusb_hc_rem_host_info(&hwahcp->hwahc_hc_data); - - /* unset stream idx */ - stream_idx = 0; - - rval = wusb_hc_set_stream_idx(&hwahcp->hwahc_hc_data, stream_idx); - if (rval != USB_SUCCESS) { - USB_DPRINTF_L2(PRINT_MASK_ATTA, hwahcp->hwahc_log_handle, - "hwahc_hc_channel_stop: set stream idx 0 fails"); - mutex_enter(&hwahcp->hwahc_mutex); - - return (rval); - } - - /* unreserve MAS slots */ - (void) memset(mas, 0, WUSB_SET_WUSB_MAS_LEN); - rval = wusb_hc_set_wusb_mas(&hwahcp->hwahc_hc_data, mas); - - if (rval != USB_SUCCESS) { - USB_DPRINTF_L2(PRINT_MASK_ATTA, hwahcp->hwahc_log_handle, - "hwahc_hc_channel_stop: set null wusb mas fails"); - mutex_enter(&hwahcp->hwahc_mutex); - - return (rval); - } - - mutex_enter(&hwahcp->hwahc_mutex); - (void) memcpy(hwahcp->hwahc_hc_data.hc_mas, mas, WUSB_SET_WUSB_MAS_LEN); - - hwahcp->hwahc_hw_state = HWAHC_HW_CH_STOPPED; - - /* Channel is stopped, can be PM'ed */ - mutex_exit(&hwahcp->hwahc_mutex); - hwahc_pm_idle_component(hwahcp); - mutex_enter(&hwahcp->hwahc_mutex); - - return (USB_SUCCESS); -} - -/* initialize data transfer related resources */ -static int -hwahc_wa_start(hwahc_state_t *hwahcp) -{ - int rval; - - USB_DPRINTF_L4(PRINT_MASK_ATTA, hwahcp->hwahc_log_handle, - "hwahc_wa_start:"); - - /* get all rpipe descrs */ - if ((rval = wusb_wa_get_rpipe_descrs(&hwahcp->hwahc_wa_data, - hwahcp->hwahc_default_pipe, PRINT_MASK_ATTA, - hwahcp->hwahc_log_handle)) != USB_SUCCESS) { - USB_DPRINTF_L2(PRINT_MASK_ATTA, hwahcp->hwahc_log_handle, - "hwahc_wa_start: get rpipe descrs fails, rval=%d", rval); - - return (rval); - } - - /* open all data transfer epts */ - if ((rval = wusb_wa_open_pipes(&hwahcp->hwahc_wa_data)) != - USB_SUCCESS) { - USB_DPRINTF_L2(PRINT_MASK_ATTA, hwahcp->hwahc_log_handle, - "hwahc_wa_start: open pipes fails, rval=%d", rval); - (void) wusb_wa_disable(&hwahcp->hwahc_wa_data, - hwahcp->hwahc_default_pipe); - - return (rval); - } - - /* init notification list */ - usba_init_list(&hwahcp->hwahc_dn_notif_queue, NULL, - hwahcp->hwahc_dev_data->dev_iblock_cookie); - - return (USB_SUCCESS); -} - -/* deinitialize data transfer related resources */ -static void -hwahc_wa_stop(hwahc_state_t *hwahcp) -{ - USB_DPRINTF_L4(PRINT_MASK_ATTA, hwahcp->hwahc_log_handle, - "hwahc_wa_stop:"); - - usba_destroy_list(&hwahcp->hwahc_dn_notif_queue); - wusb_wa_close_pipes(&hwahcp->hwahc_wa_data); -} - -/* - * HUBD related initialization - * To mimic standard hub attach process to create a fake "root hub" - * for HWA - */ -static int -hwahc_hub_attach(hwahc_state_t *hwahcp) -{ - hubd_t *hubd = NULL; - dev_info_t *dip = hwahcp->hwahc_dip; - int instance = ddi_get_instance(dip); - int i; - int rval; - - USB_DPRINTF_L4(PRINT_MASK_ATTA, hwahcp->hwahc_log_handle, - "hwahc_hub_attach:"); - - if (ndi_prop_create_boolean(DDI_DEV_T_NONE, dip, - "wire-adapter") != NDI_SUCCESS) { - - return (USB_FAILURE); - } - - /* allocate hubd structure */ - hubd = hwahcp->hwahc_hubd = kmem_zalloc(sizeof (hubd_t), KM_SLEEP); - - hubd->h_log_handle = usb_alloc_log_hdl(dip, "husb", &hubd_errlevel, - &hubd_errmask, &hubd_instance_debug, 0); - hubd->h_usba_device = usba_get_usba_device(dip); - hubd->h_usba_device->usb_is_wa = TRUE; - hubd->h_dip = dip; - hubd->h_instance = instance; - hubd->h_ignore_pwr_budget = B_TRUE; - hubd->h_cleanup_child = hwahc_cleanup_child; - - mutex_enter(&hubd->h_usba_device->usb_mutex); - hubd->h_usba_device->usb_root_hubd = hubd; - mutex_exit(&hubd->h_usba_device->usb_mutex); - - if (usb_get_dev_data(dip, &hubd->h_dev_data, - USB_PARSE_LVL_IF, 0) != USB_SUCCESS) { - USB_DPRINTF_L2(DPRINT_MASK_ATTA, hubd->h_log_handle, - "cannot get dev_data"); - - goto fail; - } - - /* init hubd mutex */ - mutex_init(HUBD_MUTEX(hubd), NULL, MUTEX_DRIVER, - hubd->h_dev_data->dev_iblock_cookie); - - usb_free_descr_tree(dip, hubd->h_dev_data); - - hubd->h_init_state |= HUBD_LOCKS_DONE; - - /* register the instance to usba HUBDI */ - rval = usba_hubdi_register(dip, 0); - if (rval != USB_SUCCESS) { - USB_DPRINTF_L2(DPRINT_MASK_ATTA, hubd->h_log_handle, - "usba_hubdi_register failed"); - - goto fail; - } - - mutex_enter(HUBD_MUTEX(hubd)); - hubd->h_init_state |= HUBD_HUBDI_REGISTERED; - - hubd->h_ancestry_str = (char *)kmem_zalloc(HUBD_APID_NAMELEN, - KM_SLEEP); - hubd_get_ancestry_str(hubd); - - /* create cfgadm minor nodes */ - for (i = 1; i <= hwahcp->hwahc_wa_data.wa_descr.bNumPorts; i++) { - char ap_name[HUBD_APID_NAMELEN]; - - (void) snprintf(ap_name, HUBD_APID_NAMELEN, "%s%d", - hubd->h_ancestry_str, i); - USB_DPRINTF_L3(DPRINT_MASK_ATTA, hwahcp->hwahc_log_handle, - "ap_name=%s", ap_name); - - if (ddi_create_minor_node(dip, ap_name, S_IFCHR, - (instance << HWAHC_MINOR_INSTANCE_SHIFT) | i, - DDI_NT_USB_ATTACHMENT_POINT, 0) != DDI_SUCCESS) { - USB_DPRINTF_L2(DPRINT_MASK_ATTA, hubd->h_log_handle, - "cannot create attachment point node (%d)", - instance); - mutex_exit(HUBD_MUTEX(hubd)); - - goto fail; - } - } - i = hwahcp->hwahc_wa_data.wa_descr.bNumPorts; - mutex_exit(HUBD_MUTEX(hubd)); - - /* create hubd minor node */ - if (ddi_create_minor_node(dip, "hubd", S_IFCHR, - instance << HWAHC_MINOR_INSTANCE_SHIFT, - DDI_NT_NEXUS, 0) != DDI_SUCCESS) { - USB_DPRINTF_L2(DPRINT_MASK_ATTA, hubd->h_log_handle, - "cannot create devctl minor node (%d)", instance); - - goto fail; - } - - mutex_enter(HUBD_MUTEX(hubd)); - hubd->h_init_state |= HUBD_MINOR_NODE_CREATED; - mutex_exit(HUBD_MUTEX(hubd)); - - if (ndi_prop_update_int(DDI_DEV_T_NONE, dip, - "usb-port-count", i) != DDI_PROP_SUCCESS) { - USB_DPRINTF_L2(DPRINT_MASK_ATTA, hubd->h_log_handle, - "usb-port-count update failed"); - } - - return (USB_SUCCESS); - -fail: - if (hwahc_hub_detach(hwahcp) != USB_SUCCESS) { - USB_DPRINTF_L2(PRINT_MASK_ATTA, hwahcp->hwahc_log_handle, - "fail to cleanup after hub attach failure"); - } - - return (USB_FAILURE); -} - -/* HUBD related deinitialization */ -static int -hwahc_hub_detach(hwahc_state_t *hwahcp) -{ - hubd_t *hubd = hwahcp->hwahc_hubd; - dev_info_t *dip = hwahcp->hwahc_dip; - - USB_DPRINTF_L4(PRINT_MASK_ATTA, hwahcp->hwahc_log_handle, - "hwahc_hub_detach:"); - - if ((hubd->h_init_state & HUBD_LOCKS_DONE) == 0) { - goto done; - } - - if (hubd->h_init_state & HUBD_MINOR_NODE_CREATED) { - /* remove minor nodes */ - ddi_remove_minor_node(dip, NULL); - } - - if (hubd->h_init_state & HUBD_HUBDI_REGISTERED) { - /* unregister with usba HUBDI */ - (void) usba_hubdi_unregister(dip); - } - - if (hubd->h_init_state & HUBD_LOCKS_DONE) { - mutex_destroy(HUBD_MUTEX(hubd)); - } - - if (hubd->h_ancestry_str) { - kmem_free(hubd->h_ancestry_str, HUBD_APID_NAMELEN); - } - -done: - if (hubd->h_dev_data) { - /* unregister client from usba */ - usb_client_detach(dip, hubd->h_dev_data); - } - - usb_free_log_hdl(hubd->h_log_handle); - kmem_free(hubd, sizeof (hubd_t)); - ddi_prop_remove_all(dip); - - return (USB_SUCCESS); -} - -/* print security descrs */ -static void -hwahc_print_secrt_data(hwahc_state_t *hwahcp) -{ - int i; - wusb_secrt_data_t *secrt_data = &hwahcp->hwahc_secrt_data; - - USB_DPRINTF_L3(PRINT_MASK_ATTA, hwahcp->hwahc_log_handle, - "The Host Wire Adapter security descriptor:"); - USB_DPRINTF_L3(PRINT_MASK_ATTA, hwahcp->hwahc_log_handle, - "bLength = 0x%x\t\t bDescriptorType = 0x%x", - secrt_data->secrt_descr.bLength, - secrt_data->secrt_descr.bDescriptorType); - USB_DPRINTF_L3(PRINT_MASK_ATTA, hwahcp->hwahc_log_handle, - "wTotalLength = 0x%x\t bNumEncryptionTypes = 0x%x", - secrt_data->secrt_descr.wTotalLength, - secrt_data->secrt_descr.bNumEncryptionTypes); - - for (i = 0; i < secrt_data->secrt_n_encry; i++) { - USB_DPRINTF_L3(PRINT_MASK_ATTA, hwahcp->hwahc_log_handle, - "The Host Wire Adapter encryption descriptor %d:", i + 1); - USB_DPRINTF_L3(PRINT_MASK_ATTA, hwahcp->hwahc_log_handle, - "bLength = 0x%x\t\t bDescriptorType = 0x%x", - secrt_data->secrt_encry_descr[i].bLength, - secrt_data->secrt_encry_descr[i].bDescriptorType); - USB_DPRINTF_L3(PRINT_MASK_ATTA, hwahcp->hwahc_log_handle, - "bEncryptionType = 0x%x\t bEncryptionValue = 0x%x", - secrt_data->secrt_encry_descr[i].bEncryptionType, - secrt_data->secrt_encry_descr[i].bEncryptionValue); - USB_DPRINTF_L3(PRINT_MASK_ATTA, hwahcp->hwahc_log_handle, - "bAuthKeyIndex = 0x%x", - secrt_data->secrt_encry_descr[i].bAuthKeyIndex); - } -} - -/* drain device notifications */ -static void -hwahc_drain_notif_queue(hwahc_state_t *hwahcp) -{ - int i; - - ASSERT(mutex_owned(&hwahcp->hwahc_mutex)); - - USB_DPRINTF_L4(PRINT_MASK_CBOPS, hwahcp->hwahc_log_handle, - "hwahc_drain_notif_queue: started"); - - if ((hwahcp->hwahc_notif_thread_id == NULL) && - (usba_list_entry_count(&hwahcp->hwahc_dn_notif_queue) != 0)) { - /* kick off a notif thread to drain the queue */ - if (usb_async_req(hwahcp->hwahc_dip, hwahc_notif_thread, - (void *)hwahcp, 0) != USB_SUCCESS) { - USB_DPRINTF_L2(PRINT_MASK_CBOPS, - hwahcp->hwahc_log_handle, - "hwahc_drain_notif_queue: no notif thread started"); - } else { - hwahcp->hwahc_notif_thread_id = (kthread_t *)1; - } - } - - for (i = 0; i < HWAHC_NOTIF_DRAIN_TIMEOUT; i++) { - /* loop until the queue is completed or it timeouts */ - if ((hwahcp->hwahc_notif_thread_id == NULL) && - (usba_list_entry_count(&hwahcp->hwahc_dn_notif_queue) == - 0)) { - - break; - } - mutex_exit(&hwahcp->hwahc_mutex); - delay(drv_usectohz(1000000)); - mutex_enter(&hwahcp->hwahc_mutex); - } - - /* cleanup the queue if not completed */ - while (usba_list_entry_count(&hwahcp->hwahc_dn_notif_queue) != 0) { - hwahc_dn_notif_list_t *nlist; - - nlist = (hwahc_dn_notif_list_t *)usba_rm_first_pvt_from_list( - &hwahcp->hwahc_dn_notif_queue); - ASSERT(nlist != NULL); - ASSERT(nlist->dn_notif != NULL); - usba_destroy_list(&nlist->notif_list); - kmem_free(nlist->dn_notif, nlist->dn_notif->bLength); - kmem_free(nlist, sizeof (hwahc_dn_notif_list_t)); - } - - USB_DPRINTF_L4(PRINT_MASK_CBOPS, hwahcp->hwahc_log_handle, - "hwahc_drain_notif_queue: ended"); -} - - -/* normal callback for notification ept */ -static void -hwahc_intr_cb(usb_pipe_handle_t ph, struct usb_intr_req *reqp) -{ - dev_info_t *dip = (USBA_REQ2WRP(reqp))->wr_dip; - hwahc_state_t *hwahcp; - mblk_t *data = reqp->intr_data; - - ASSERT(dip != NULL); - hwahcp = ddi_get_soft_state(hwahc_statep, ddi_get_instance(dip)); - ASSERT(hwahcp != NULL); - - USB_DPRINTF_L4(PRINT_MASK_CBOPS, hwahcp->hwahc_log_handle, - "hwahc_intr_cb: ph = 0x%p reqp = 0x%p", (void *)ph, - (void *)reqp); - - ASSERT((reqp->intr_cb_flags & USB_CB_INTR_CONTEXT) == 0); - - if (data == NULL) { - usb_free_intr_req(reqp); - - return; - } - - /* handle the notification */ - hwahc_handle_notif(hwahcp, data); - - usb_free_intr_req(reqp); -} - -/* - * See Section 8.3.3.3 for Transfer Notification format and - * Section 8.5.4 for HWA specific notifications. - * Three kinds of Notifications: - * - Transfer Completion - * - DN Received - * - BPST ADJ - */ -/* handle the notification according to notification type */ -static void -hwahc_handle_notif(hwahc_state_t *hwahcp, mblk_t *data) -{ - int len; - uint8_t *p; - wa_notif_header_t *hdr; - - if (data == NULL) { - - return; - } - - len = MBLKL(data); - p = data->b_rptr; - USB_DPRINTF_L3(PRINT_MASK_CBOPS, hwahcp->hwahc_log_handle, - "hwahc_handle_notif: data len = %d", len); - - /* - * according to WUSB 1.0/8.1.2, multiple notifications might be sent - * at a time, need to parse one by one - */ - while (len > 0) { - if (len < 2) { - USB_DPRINTF_L2(PRINT_MASK_CBOPS, - hwahcp->hwahc_log_handle, - "hwahc_handle_notif: short packet len = %d", - len); - - break; - } - - hdr = (wa_notif_header_t *)p; - if (len < hdr->bLength) { - USB_DPRINTF_L2(PRINT_MASK_CBOPS, - hwahcp->hwahc_log_handle, - "hwahc_handle_notif: length not match, " - "hdr length = %d, actual length = %d", - hdr->bLength, len); - - break; - } - - switch (hdr->bNotifyType) { - case WA_NOTIF_TYPE_TRANSFER: - { - uint8_t ept = p[2]; - - /* deal with transfer completion notification */ - hwahc_handle_xfer_result(hwahcp, ept); - - break; - } - case HWA_NOTIF_TYPE_DN_RECEIVED: - { - hwa_notif_dn_recvd_t *dn_notif; - - dn_notif = kmem_alloc(hdr->bLength, KM_NOSLEEP); - (void) memcpy(dn_notif, p, hdr->bLength); - - /* deal with device notification */ - hwahc_handle_dn_notif(hwahcp, dn_notif); - - break; - } - case HWA_NOTIF_TYPE_BPST_ADJ: - USB_DPRINTF_L3(PRINT_MASK_CBOPS, - hwahcp->hwahc_log_handle, - "hwahc_handle_notif: received BPST adjust " - "notification, bAdjustment = %d", p[2]); - - break; - default: - USB_DPRINTF_L2(PRINT_MASK_CBOPS, - hwahcp->hwahc_log_handle, - "hwahc_handle_notif: unknown notification 0x%x", - hdr->bNotifyType); - - break; - } - p += hdr->bLength; - len -= hdr->bLength; - } -} - -/* - * start listening on bulk-in ept for transfer result - * - * Dispatches a task to read the BULK IN endpoint to get the result of - * last request. usb_async_req() will have system_taskq to process the tasks. - */ -int -hwahc_start_result_thread(hwahc_state_t *hwahcp) -{ - wusb_wa_data_t *wa_data; - - USB_DPRINTF_L4(PRINT_MASK_ATTA, hwahcp->hwahc_log_handle, - "hwahc_start_result_thread:"); - - ASSERT(mutex_owned(&hwahcp->hwahc_mutex)); - - if (hwahcp->hwahc_result_thread_id != 0) { - USB_DPRINTF_L2(PRINT_MASK_ATTA, hwahcp->hwahc_log_handle, - "hwahc_start_result_thread: already started"); - - return (USB_SUCCESS); - } - - wa_data = &hwahcp->hwahc_wa_data; - - mutex_enter(&wa_data->wa_mutex); - if ((wa_data->wa_bulkin_ph != NULL) && - (wa_data->wa_bulkin_pipe_state != WA_PIPE_STOPPED)) { - mutex_exit(&wa_data->wa_mutex); - - return (USB_INVALID_PIPE); - } - mutex_exit(&wa_data->wa_mutex); - - if (wa_data->wa_bulkin_ph == NULL) { - mutex_exit(&hwahcp->hwahc_mutex); - if (usb_pipe_open(wa_data->wa_dip, &wa_data->wa_bulkin_ept, - &wa_data->wa_pipe_policy, USB_FLAGS_SLEEP, - &wa_data->wa_bulkin_ph) != USB_SUCCESS) { - USB_DPRINTF_L2(PRINT_MASK_ATTA, - hwahcp->hwahc_log_handle, - "hwahc_start_result_thread: open pipe failed"); - - - mutex_enter(&hwahcp->hwahc_mutex); - return (USB_FAILURE); - } - mutex_enter(&hwahcp->hwahc_mutex); - - mutex_enter(&wa_data->wa_mutex); - wa_data->wa_bulkin_pipe_state = WA_PIPE_STOPPED; - mutex_exit(&wa_data->wa_mutex); - } - - /* kick off an asynchronous thread to handle transfer result */ - if (usb_async_req(hwahcp->hwahc_dip, hwahc_result_thread, - (void *)hwahcp, 0) != USB_SUCCESS) { - USB_DPRINTF_L2(PRINT_MASK_ATTA, hwahcp->hwahc_log_handle, - "hwahc_start_result_thread: failed to start result thread"); - - return (USB_FAILURE); - } - hwahcp->hwahc_result_thread_id = (kthread_t *)1; - - /* pipe state is active while the result thread is on */ - mutex_enter(&wa_data->wa_mutex); - wa_data->wa_bulkin_pipe_state = WA_PIPE_ACTIVE; - mutex_exit(&wa_data->wa_mutex); - - return (USB_SUCCESS); -} - -/* stop the bulk-in ept from listening */ -static void -hwahc_stop_result_thread(hwahc_state_t *hwahcp) -{ - wusb_wa_data_t *wa_data; - - ASSERT(mutex_owned(&hwahcp->hwahc_mutex)); - - USB_DPRINTF_L4(PRINT_MASK_ATTA, hwahcp->hwahc_log_handle, - "hwahc_stop_result_thread:"); - - if (hwahcp->hwahc_result_thread_id == 0) { - USB_DPRINTF_L2(PRINT_MASK_ATTA, hwahcp->hwahc_log_handle, - "hwahc_stop_result_thread: already stopped"); - - return; - } - - wa_data = &hwahcp->hwahc_wa_data; - mutex_enter(&wa_data->wa_mutex); - if ((wa_data->wa_bulkin_ph == NULL) || - (wa_data->wa_bulkin_pipe_state != WA_PIPE_ACTIVE)) { - USB_DPRINTF_L2(PRINT_MASK_ATTA, hwahcp->hwahc_log_handle, - "hwahc_stop_result_thread: invalid pipe state"); - - mutex_exit(&wa_data->wa_mutex); - - return; - } - mutex_exit(&wa_data->wa_mutex); - - USB_DPRINTF_L4(PRINT_MASK_ATTA, hwahcp->hwahc_log_handle, - "hwahc_stop_result_thread: reset hwa bulk-in pipe"); - mutex_exit(&hwahcp->hwahc_mutex); - usb_pipe_reset(wa_data->wa_dip, wa_data->wa_bulkin_ph, - USB_FLAGS_SLEEP, NULL, NULL); - - /* - * have to close pipe here to fail the bulk-in transfer - * that never timeouts - */ - USB_DPRINTF_L4(PRINT_MASK_ATTA, hwahcp->hwahc_log_handle, - "hwahc_stop_result_thread: close hwa bulk-in pipe"); - usb_pipe_close(wa_data->wa_dip, wa_data->wa_bulkin_ph, - USB_FLAGS_SLEEP, NULL, NULL); - mutex_enter(&hwahcp->hwahc_mutex); - - mutex_enter(&wa_data->wa_mutex); - wa_data->wa_bulkin_ph = NULL; - wa_data->wa_bulkin_pipe_state = WA_PIPE_STOPPED; - mutex_exit(&wa_data->wa_mutex); - - while (hwahcp->hwahc_result_thread_id != 0) { - /* wait the result thread to exit */ - cv_wait(&hwahcp->hwahc_result_thread_cv, &hwahcp->hwahc_mutex); - } -} - -/* - * keep listening for transfer result by setting timeout to 0 while the - * bulk-in pipe is active - * the thread would be stopped by closing bulk-in pipe or encountering - * transaction error, eg, hot-removal of hwa device - */ -static void -hwahc_result_thread(void *arg) -{ - hwahc_state_t *hwahcp = (hwahc_state_t *)arg; - wusb_wa_data_t *wa_data = &hwahcp->hwahc_wa_data; - int rval; - uint8_t retry = 0; - - mutex_enter(&hwahcp->hwahc_mutex); - ASSERT(hwahcp->hwahc_result_thread_id == (kthread_t *)1); - hwahcp->hwahc_result_thread_id = curthread; - USB_DPRINTF_L4(PRINT_MASK_ATTA, hwahcp->hwahc_log_handle, - "hwahc_result_thread: started, thread_id=0x%p", - (void *)hwahcp->hwahc_result_thread_id); - - /* keep polling the bulk IN endpoint to get the result */ - mutex_enter(&wa_data->wa_mutex); - while (wa_data->wa_bulkin_pipe_state == WA_PIPE_ACTIVE) { - mutex_exit(&wa_data->wa_mutex); - mutex_exit(&hwahcp->hwahc_mutex); - - if ((rval = wusb_wa_get_xfer_result(wa_data)) != USB_SUCCESS) { - retry++; - USB_DPRINTF_L2(PRINT_MASK_ATTA, - hwahcp->hwahc_log_handle, - "hwahc_result_thread: get xfer result failed, " - "rval = %d, retry = %d", rval, retry); - - /* retry 3 times upon failure */ - if (retry >= 3) { - mutex_enter(&hwahcp->hwahc_mutex); - mutex_enter(&wa_data->wa_mutex); - - break; - } - } - - mutex_enter(&hwahcp->hwahc_mutex); - mutex_enter(&wa_data->wa_mutex); - } - - hwahcp->hwahc_result_thread_id = 0; - wa_data->wa_bulkin_pipe_state = WA_PIPE_STOPPED; - mutex_exit(&wa_data->wa_mutex); - - /* signal to the thread requesting stopping if any */ - cv_signal(&hwahcp->hwahc_result_thread_cv); - - USB_DPRINTF_L4(PRINT_MASK_ATTA, hwahcp->hwahc_log_handle, - "hwahc_result_thread: ended"); - - mutex_exit(&hwahcp->hwahc_mutex); -} - -/* - * nothing to do here, just check if the ept number in the transfer - * completion notification is valid - * the actual handling of transfer result is performed by the result thread - */ -static void -hwahc_handle_xfer_result(hwahc_state_t *hwahcp, uint8_t ept) -{ - usb_ep_descr_t *epdt; - - USB_DPRINTF_L4(PRINT_MASK_CBOPS, hwahcp->hwahc_log_handle, - "hwahc_handle_xfer_result: result on ept %d", ept); - - epdt = &hwahcp->hwahc_wa_data.wa_bulkin_ept; - - /* the result should be on the bulk-in ept */ - if ((epdt->bEndpointAddress & USB_EP_NUM_MASK) != ept) { - USB_DPRINTF_L2(PRINT_MASK_CBOPS, hwahcp->hwahc_log_handle, - "hwahc_handle_xfer_result: ept number not match"); - - return; - } -} - - -/* - * Section 8.5.4.2. - * Copy the DN Notification and add it to the instance's global - * nofication list. If the worker thread is not started yet, start - * it. - */ -static void -hwahc_handle_dn_notif(hwahc_state_t *hwahcp, hwa_notif_dn_recvd_t *dn_notif) -{ - hwahc_dn_notif_list_t *nlist; - - USB_DPRINTF_L4(PRINT_MASK_CBOPS, hwahcp->hwahc_log_handle, - "hwahc_handle_dn_notif: notif = 0x%p", (void *)dn_notif); - - nlist = kmem_zalloc(sizeof (hwahc_dn_notif_list_t), KM_NOSLEEP); - - mutex_enter(&hwahcp->hwahc_mutex); - nlist->dn_notif = dn_notif; - - usba_init_list(&nlist->notif_list, (usb_opaque_t)nlist, - hwahcp->hwahc_dev_data->dev_iblock_cookie); - - /* queue the new notification to the list */ - usba_add_to_list(&hwahcp->hwahc_dn_notif_queue, &nlist->notif_list); - - /* handle the notification queue with an asynchronous thread */ - if (hwahcp->hwahc_notif_thread_id == 0) { - if (usb_async_req(hwahcp->hwahc_dip, hwahc_notif_thread, - (void *)hwahcp, 0) != USB_SUCCESS) { - USB_DPRINTF_L2(PRINT_MASK_CBOPS, - hwahcp->hwahc_log_handle, - "hwahc_handle_dn_notif: no notif thread started"); - mutex_exit(&hwahcp->hwahc_mutex); - - return; - } - hwahcp->hwahc_notif_thread_id = (kthread_t *)1; - } - - mutex_exit(&hwahcp->hwahc_mutex); -} - -/* handle the notifications in the notification queue in sequence */ -static void -hwahc_notif_thread(void *arg) -{ - hwahc_state_t *hwahcp = (hwahc_state_t *)arg; - hwahc_dn_notif_list_t *nlist; - hwa_notif_dn_recvd_t *dn_notif; - - mutex_enter(&hwahcp->hwahc_mutex); - ASSERT(hwahcp->hwahc_notif_thread_id == (kthread_t *)1); - hwahcp->hwahc_notif_thread_id = curthread; - - USB_DPRINTF_L4(PRINT_MASK_CBOPS, hwahcp->hwahc_log_handle, - "hwahc_notif_thread: started, thread_id=0x%p", - (void *)hwahcp->hwahc_notif_thread_id); - - while (usba_list_entry_count(&hwahcp->hwahc_dn_notif_queue) != 0) { - /* - * first in first out, only one notification will be handled - * at a time, so it assures no racing in attach or detach - */ - if ((nlist = - (hwahc_dn_notif_list_t *)usba_rm_first_pvt_from_list( - &hwahcp->hwahc_dn_notif_queue)) == NULL) { - - continue; - } - dn_notif = nlist->dn_notif; - mutex_exit(&hwahcp->hwahc_mutex); - hwahc_handle_dn(hwahcp, dn_notif); - usba_destroy_list(&nlist->notif_list); - kmem_free(nlist, sizeof (hwahc_dn_notif_list_t)); - mutex_enter(&hwahcp->hwahc_mutex); - } - - hwahcp->hwahc_notif_thread_id = 0; - - USB_DPRINTF_L4(PRINT_MASK_CBOPS, hwahcp->hwahc_log_handle, - "hwahc_notif_thread: ended"); - - mutex_exit(&hwahcp->hwahc_mutex); -} - -/* Set the child device's active bit to 1 */ -static void -hwahc_set_device_active(hwahc_state_t *hwahcp, uint8_t devaddr) -{ - wusb_dev_info_t *dev_info; - wusb_hc_data_t *hc_data = &hwahcp->hwahc_hc_data; - int i; - - mutex_enter(&hc_data->hc_mutex); - for (i = 1; i <= hc_data->hc_num_ports; i++) { - dev_info = hc_data->hc_dev_infos[i]; - if ((dev_info != NULL) && (dev_info->wdev_addr == devaddr)) { - dev_info->wdev_active = 1; - USB_DPRINTF_L3(DPRINT_MASK_EVENTS, - hwahcp->hwahc_log_handle, - "hwahc_set_device_active:device(%p) updated ", - (void *)dev_info); - - break; - } - } - mutex_exit(&hc_data->hc_mutex); -} - -/* - * handle a specific device notification - * assuming the raw data in HWA DN_RECEIVED notification pkt includes - * no more than one dn pkt - */ -static void -hwahc_handle_dn(hwahc_state_t *hwahcp, hwa_notif_dn_recvd_t *dn_notif) -{ - uint8_t *p; - size_t len; - uint8_t dntype; - int circ; - wusb_hc_data_t *hc_data = &hwahcp->hwahc_hc_data; - - if (dn_notif->bLength < 4) { - USB_DPRINTF_L2(PRINT_MASK_CBOPS, hwahcp->hwahc_log_handle, - "hwahc_handle_dn: bLength too short %d", dn_notif->bLength); - kmem_free(dn_notif, dn_notif->bLength); - - return; - } - - p = dn_notif->notifdata; - len = dn_notif->bLength - 4; - - /* - * WUSB Errata 06.12 specifies that the raw data in the DN_RECEIVED - * notification must not include the WUSB header, but only the bType - * and Notification specific data - */ - if (len == 0) { - USB_DPRINTF_L2(PRINT_MASK_CBOPS, hwahcp->hwahc_log_handle, - "hwahc_handle_dn: no raw data"); - kmem_free(dn_notif, dn_notif->bLength); - - return; - } - dntype = *p; - - /* update the device's status bit, no matter what the DN is */ - hwahc_set_device_active(hwahcp, dn_notif->bSourceDeviceAddr); - - ndi_devi_enter(hwahcp->hwahc_dip, &circ); - switch (dntype) { - case WUSB_DN_CONNECT: - /* DN_Connect */ - wusb_hc_handle_dn_connect( - hc_data, hwahcp->hwahc_default_pipe, - hwahcp->hwahc_wa_data.wa_ifno, p, len, - &hwahcp->hwahc_secrt_data); - - break; - case WUSB_DN_DISCONNECT: - /* DN_Disconnect */ - wusb_hc_handle_dn_disconnect( - hc_data, dn_notif->bSourceDeviceAddr, - p, len); - - break; - case WUSB_DN_ALIVE: - /* We only send KeepAlive IE to one device at a comment */ - mutex_enter(&hc_data->hc_mutex); - if (dn_notif->bSourceDeviceAddr == - hc_data->hc_alive_ie.bDeviceAddress[0]) { - mutex_exit(&hc_data->hc_mutex); - wusb_hc_rem_ie(hc_data, - (wusb_ie_header_t *)&hc_data->hc_alive_ie); - mutex_enter(&hc_data->hc_mutex); - } - mutex_exit(&hc_data->hc_mutex); - - break; - case WUSB_DN_EPRDY: - case WUSB_DN_MASAVAILCHANGED: - case WUSB_DN_REMOTEWAKEUP: - case WUSB_DN_SLEEP: - default: - USB_DPRINTF_L4(PRINT_MASK_CBOPS, hwahcp->hwahc_log_handle, - "hwahc_handle_dn: dn type 0x%x not supported yet", - dntype); - - break; - } - - kmem_free(dn_notif, dn_notif->bLength); - ndi_devi_exit(hwahcp->hwahc_dip, circ); -} - -/* exceptional callback for notification ept */ -/* ARGSUSED */ -static void -hwahc_intr_exc_cb(usb_pipe_handle_t ph, struct usb_intr_req *reqp) -{ - dev_info_t *dip = (USBA_REQ2WRP(reqp))->wr_dip; - hwahc_state_t *hwahcp; - - ASSERT(dip != NULL); - hwahcp = ddi_get_soft_state(hwahc_statep, ddi_get_instance(dip)); - ASSERT(hwahcp != NULL); - - USB_DPRINTF_L2(PRINT_MASK_CBOPS, hwahcp->hwahc_log_handle, - "hwahc_intr_exc_cb: receive intr exception cb, cr=%d", - reqp->intr_completion_reason); - - ASSERT((reqp->intr_cb_flags & USB_CB_INTR_CONTEXT) == 0); - - mutex_enter(&hwahcp->hwahc_mutex); - - switch (reqp->intr_completion_reason) { - case USB_CR_PIPE_RESET: - /* only restart nep after autoclearing */ - if (hwahcp->hwahc_dev_state == USB_DEV_ONLINE) { - hwahcp->hwahc_wa_data.wa_intr_pipe_state = - WA_PIPE_STOPPED; - mutex_exit(&hwahcp->hwahc_mutex); - (void) wusb_wa_start_nep(&hwahcp->hwahc_wa_data, - USB_FLAGS_NOSLEEP); - mutex_enter(&hwahcp->hwahc_mutex); - } - - break; - case USB_CR_DEV_NOT_RESP: - case USB_CR_STOPPED_POLLING: - case USB_CR_PIPE_CLOSING: - case USB_CR_UNSPECIFIED_ERR: - /* never restart nep on these conditions */ - default: - /* for all others, wait for the autoclearing PIPE_RESET cb */ - - break; - } - - usb_free_intr_req(reqp); - mutex_exit(&hwahcp->hwahc_mutex); -} - -/* - * callback function called by WA to resubmit a periodic request for - * interrupt polling or isochronous transfer. - */ -static int -hwahc_pipe_submit_periodic_req(wusb_wa_data_t *wa_data, - usba_pipe_handle_data_t *ph) -{ - hwahc_state_t *hwahcp = wa_data->wa_private_data; - hwahc_pipe_private_t *pp = (hwahc_pipe_private_t *)ph->p_hcd_private; - int rval; - - mutex_enter(&hwahcp->hwahc_mutex); - - USB_DPRINTF_L4(PRINT_MASK_CBOPS, hwahcp->hwahc_log_handle, - "hwahc_pipe_submit_periodic_req: hwahcp=0x%p, pp=0x%p," - " pipe state = %d", (void *)hwahcp, (void *)pp, pp->pp_state); - - if (pp->pp_state != HWAHC_PIPE_STATE_ACTIVE) { - /* pipe error or pipe closing, don't resubmit any more */ - USB_DPRINTF_L4(PRINT_MASK_CBOPS, hwahcp->hwahc_log_handle, - "hwahc_pipe_submit_periodic_req: pipe not active = %d", - pp->pp_state); - - mutex_exit(&hwahcp->hwahc_mutex); - - return (USB_PIPE_ERROR); - } - - mutex_exit(&hwahcp->hwahc_mutex); - - /* re-submit the original request */ - rval = wusb_wa_intr_xfer(wa_data, pp->pp_rp, ph, - (usb_intr_req_t *)pp->pp_client_periodic_in_reqp, 0); - - return (rval); -} - -/* call HCD callback for completion handling */ -static void -hwahc_rpipe_xfer_cb(dev_info_t *dip, usba_pipe_handle_data_t *ph, - wusb_wa_trans_wrapper_t *wr, usb_cr_t cr) -{ - hwahc_state_t *hwahcp; - hwahc_pipe_private_t *pp; - usb_opaque_t req; - wusb_hc_data_t *hc_data; - - hwahcp = ddi_get_soft_state(hwahc_statep, ddi_get_instance(dip)); - if (hwahcp == NULL) { - - return; - } - - hc_data = &hwahcp->hwahc_hc_data; - - mutex_enter(&hwahcp->hwahc_mutex); - USB_DPRINTF_L3(PRINT_MASK_CBOPS, hwahcp->hwahc_log_handle, - "hwahc_rpipe_xfer_cb: ph = 0x%p, wr = 0x%p cr = 0x%x", - (void *)ph, (void *)wr, cr); - - pp = (hwahc_pipe_private_t *)ph->p_hcd_private; - - mutex_enter(&hc_data->hc_mutex); - pp->pp_wdev->wdev_active = 1; /* this device is active on xfer */ - mutex_exit(&hc_data->hc_mutex); - - switch (cr) { - case USB_CR_OK: - break; - case USB_CR_NOT_SUPPORTED: - case USB_CR_NO_RESOURCES: - case USB_CR_PIPE_RESET: - case USB_CR_STOPPED_POLLING: - pp->pp_state = HWAHC_PIPE_STATE_IDLE; - break; - case USB_CR_PIPE_CLOSING: - break; - default: - pp->pp_state = HWAHC_PIPE_STATE_ERROR; - - break; - } - - if (wr && wr->wr_reqp) { - req = wr->wr_reqp; - - mutex_enter(&wr->wr_rp->rp_mutex); - wr->wr_reqp = NULL; - mutex_exit(&wr->wr_rp->rp_mutex); - - } else { /* periodic pipe cleanup */ - - /* the original request is cleared and returned to client */ - req = pp->pp_client_periodic_in_reqp; - pp->pp_client_periodic_in_reqp = NULL; - } - - mutex_exit(&hwahcp->hwahc_mutex); - - USB_DPRINTF_L3(PRINT_MASK_CBOPS, hwahcp->hwahc_log_handle, - "hwahc_rpipe_xfer_cb: call usba_hcdi_cb for req= 0x%p", - (void *)req); - - usba_hcdi_cb(ph, req, cr); -} - -/* post disconnect event to child on a certain port */ -static void -hwahc_disconnect_dev(dev_info_t *dip, usb_port_t port) -{ - hwahc_state_t *hwahcp; - int circ; - dev_info_t *child_dip; - - if ((hwahcp = ddi_get_soft_state(hwahc_statep, - ddi_get_instance(dip))) == NULL) { - - return; - } - - ndi_devi_enter(dip, &circ); - mutex_enter(&hwahcp->hwahc_mutex); - - child_dip = hwahcp->hwahc_hc_data.hc_children_dips[port]; - if ((hwahcp->hwahc_dev_state == USB_DEV_ONLINE) && child_dip) { - mutex_exit(&hwahcp->hwahc_mutex); - - /* if the child driver remains attached */ - if (i_ddi_devi_attached(child_dip)) { - hwahc_post_event(hwahcp, port, - USBA_EVENT_TAG_HOT_REMOVAL); - } - mutex_enter(&hwahcp->hwahc_mutex); - } - - mutex_exit(&hwahcp->hwahc_mutex); - ndi_devi_exit(dip, circ); -} - -/* post reconect event to child on a certain port */ -static void -hwahc_reconnect_dev(dev_info_t *dip, usb_port_t port) -{ - hwahc_state_t *hwahcp; - int circ; - - if ((hwahcp = ddi_get_soft_state(hwahc_statep, - ddi_get_instance(dip))) == NULL) { - - return; - } - ndi_devi_enter(dip, &circ); - mutex_enter(&hwahcp->hwahc_mutex); - - if ((hwahcp->hwahc_dev_state == USB_DEV_ONLINE) && - (hwahcp->hwahc_hc_data.hc_children_dips[port])) { - mutex_exit(&hwahcp->hwahc_mutex); - hwahc_post_event(hwahcp, port, USBA_EVENT_TAG_HOT_INSERTION); - mutex_enter(&hwahcp->hwahc_mutex); - } - - mutex_exit(&hwahcp->hwahc_mutex); - ndi_devi_exit(dip, circ); -} - - -/* - * Device TrustTimeout timer operations: - * hwahc_start_trust_timer: start the trust timer for a newly connected device - * hwahc_trust_timeout_handler: timer handler - * hwahc_stop_trust_timer: stop a device's trust timer - */ -static void -hwahc_start_trust_timer(wusb_dev_info_t *dev) -{ - if (hwahc_enable_trust_timeout == 0) { - - return; - } - - if (dev->wdev_trust_timer == NULL) { - dev->wdev_trust_timer = timeout(hwahc_trust_timeout_handler, - (void *)dev, drv_usectohz(WUSB_TRUST_TIMEOUT_US)); - } -} - -/* timeout handler for device TrustTimeout. See section 4.14 */ -static void -hwahc_trust_timeout_handler(void *arg) -{ - wusb_dev_info_t *dev = (wusb_dev_info_t *)arg; - usb_port_t port; - uint16_t dev_addr; - wusb_hc_data_t *hc_data = dev->wdev_hc; - uint8_t retry = 3; - int rval; - - mutex_enter(&hc_data->hc_mutex); - - dev->wdev_trust_timer = 0; - dev_addr = dev->wdev_addr; - - if (dev->wdev_active == 1) { - /* device is active during the past period. Restart the timer */ - dev->wdev_active = 0; /* expect device DN set it to 1 */ - } else { - /* send a KeepAlive IE to query the device */ - for (retry = 0; retry < 3; retry++) { - mutex_exit(&hc_data->hc_mutex); - rval = wusb_hc_send_keepalive_ie(hc_data, - dev_addr); - mutex_enter(&hc_data->hc_mutex); - - if (rval == USB_SUCCESS) { - break; - } - /* retry 3 times if fail to send KeepAlive IE */ - } - - if (dev->wdev_active == 0) { - /* still no activity! Delete this device */ - if (wusb_hc_is_dev_connected(hc_data, dev->wdev_cdid, - &port)) { - mutex_exit(&hc_data->hc_mutex); - (void) hwahc_destroy_child(hc_data->hc_dip, - port); - - /* the device comes to the end of its life */ - return; - } - } - } - - /* active or we received DN during query */ - hwahc_start_trust_timer(dev); - - mutex_exit(&hc_data->hc_mutex); -} - -/* stop a child device's trust timeout handler */ -void -hwahc_stop_trust_timer(wusb_dev_info_t *dev) -{ - timeout_id_t tid; - wusb_hc_data_t *hc_data = dev->wdev_hc; - - ASSERT(mutex_owned(&hc_data->hc_mutex)); - - if (hwahc_enable_trust_timeout == 0) { - return; - } - - tid = dev->wdev_trust_timer; - - dev->wdev_trust_timer = NULL; - mutex_exit(&hc_data->hc_mutex); - - if (tid != NULL) { - (void) untimeout(tid); - } - - mutex_enter(&hc_data->hc_mutex); -} - -/* configure child device and attach child on a certain port */ -static int -hwahc_create_child(dev_info_t *dip, usb_port_t port) -{ - hwahc_state_t *hwahcp; - wusb_hc_data_t *hc_data; - wusb_dev_info_t *dev_info; - usb_pipe_handle_t ph; - int rval; - dev_info_t *child_dip; - usba_device_t *child_ud = NULL; - mblk_t *pdata = NULL; - usb_cr_t completion_reason; - usb_cb_flags_t cb_flags; - size_t size; - uint8_t address; - int user_conf_index; - uint_t config_index; - int prh_circ, rh_circ, circ; - dev_info_t *rh_dip; - usb_dev_descr_t usb_dev_descr; - - if ((hwahcp = ddi_get_soft_state(hwahc_statep, - ddi_get_instance(dip))) == NULL) { - - return (USB_INVALID_ARGS); - } - - rh_dip = hwahcp->hwahc_hubd->h_usba_device->usb_root_hub_dip; - ndi_hold_devi(dip); /* avoid racing with dev detach */ - /* exclude other threads */ - ndi_devi_enter(ddi_get_parent(rh_dip), &prh_circ); - ndi_devi_enter(rh_dip, &rh_circ); - ndi_devi_enter(dip, &circ); - - _NOTE(NOW_INVISIBLE_TO_OTHER_THREADS(*dev_info)); - - hc_data = &hwahcp->hwahc_hc_data; - mutex_enter(&hc_data->hc_mutex); - dev_info = hc_data->hc_dev_infos[port]; - - /* Created in whcdi.c before authed */ - child_dip = hc_data->hc_children_dips[port]; - - child_ud = usba_get_usba_device(child_dip); - ph = dev_info->wdev_ph; - - mutex_exit(&hc_data->hc_mutex); - /* - * HWA maintains the address space as a separate bus and - * will not occupy parent's address space - */ - address = child_ud->usb_addr; - if (address < 0x80) { - USB_DPRINTF_L3(PRINT_MASK_CBOPS, hwahcp->hwahc_log_handle, - "hwahc_create_child: reconnecting, address = %d", - address); - - } else { - /* SetAddress(0) */ - if ((rval = usb_pipe_sync_ctrl_xfer(child_dip, ph, - USB_DEV_REQ_HOST_TO_DEV, - USB_REQ_SET_ADDRESS, /* bRequest */ - 0, /* wValue */ - 0, /* wIndex */ - 0, /* wLength */ - NULL, 0, - &completion_reason, &cb_flags, 0)) != USB_SUCCESS) { - char buffer[64]; - USB_DPRINTF_L2(PRINT_MASK_CBOPS, - hwahcp->hwahc_log_handle, - "setting address failed (cr=%s cb_flags=%s " - "rval=%d)", usb_str_cr(completion_reason), - usb_str_cb_flags(cb_flags, buffer, sizeof (buffer)), - rval); - - goto done; - } - - USB_DPRINTF_L3(PRINT_MASK_CBOPS, hwahcp->hwahc_log_handle, - "set address 0 done"); - - usb_pipe_close(child_dip, ph, - USB_FLAGS_SLEEP | USBA_FLAGS_PRIVILEGED, NULL, NULL); - - child_ud->usb_addr = 0; - dev_info->wdev_addr = 0; - dev_info->wdev_ph = NULL; - - /* need to be called each time dev addr is changed */ - if ((rval = wusb_hc_set_device_info(&hwahcp->hwahc_hc_data, - port)) != USB_SUCCESS) { - USB_DPRINTF_L2(PRINT_MASK_CBOPS, - hwahcp->hwahc_log_handle, - "update device info failed, rval = %d", rval); - - goto done; - } - - /* new ph is stored in usba_device */ - if ((rval = usb_pipe_open(child_dip, NULL, NULL, - USB_FLAGS_SLEEP | USBA_FLAGS_PRIVILEGED, &ph)) != - USB_SUCCESS) { - USB_DPRINTF_L2(PRINT_MASK_CBOPS, - hwahcp->hwahc_log_handle, - "usb_pipe_open failed (%d)", rval); - - goto done; - } - - /* provide at least 2ms time for address change, 7.3.1.3 */ - delay(drv_usectohz(2000)); - - /* start normal enumeration process */ - /* - * wusb bus address has 1:1 relationship with port number - * and wusb bus address starts from 2, so as to follow - * the convention that USB bus address 1 is reserved for - * host controller device. As such, only 126 WUSB devices - * are supported on a WUSB host - */ - address = port + 1; - if (address >= 0x80) { - USB_DPRINTF_L3(PRINT_MASK_CBOPS, - hwahcp->hwahc_log_handle, - "hwahc_create_child: address for port %d exceeds " - "0x80", port); - rval = USB_FAILURE; - - goto done; - } - /* Set the address of the device */ - if ((rval = usb_pipe_sync_ctrl_xfer(child_dip, ph, - USB_DEV_REQ_HOST_TO_DEV, - USB_REQ_SET_ADDRESS, /* bRequest */ - address, /* wValue */ - 0, /* wIndex */ - 0, /* wLength */ - NULL, 0, - &completion_reason, &cb_flags, 0)) != USB_SUCCESS) { - char buffer[64]; - USB_DPRINTF_L2(PRINT_MASK_CBOPS, - hwahcp->hwahc_log_handle, - "setting address failed (cr=%s cb_flags=%s " - "rval=%d)", usb_str_cr(completion_reason), - usb_str_cb_flags(cb_flags, buffer, sizeof (buffer)), - rval); - - goto done; - } - - USB_DPRINTF_L3(PRINT_MASK_CBOPS, hwahcp->hwahc_log_handle, - "set address 0x%x done", address); - - usb_pipe_close(child_dip, ph, - USB_FLAGS_SLEEP | USBA_FLAGS_PRIVILEGED, NULL, NULL); - - child_ud->usb_addr = address; - dev_info->wdev_addr = address; - dev_info->wdev_ph = NULL; - - if ((rval = wusb_hc_set_device_info(&hwahcp->hwahc_hc_data, - port)) != USB_SUCCESS) { - USB_DPRINTF_L2(PRINT_MASK_CBOPS, - hwahcp->hwahc_log_handle, - "update device info failed, rval = %d", rval); - - goto done; - } - - /* new ph is stored in usba_device */ - if ((rval = usb_pipe_open(child_dip, NULL, NULL, - USB_FLAGS_SLEEP | USBA_FLAGS_PRIVILEGED, &ph)) != - USB_SUCCESS) { - USB_DPRINTF_L2(PRINT_MASK_CBOPS, - hwahcp->hwahc_log_handle, - "usb_pipe_open failed (%d)", rval); - - goto done; - } - - /* provide at least 2ms time for address change, 7.3.1.3 */ - delay(drv_usectohz(2000)); - } - - /* get device descriptor ignoring device reconnection */ - rval = usb_pipe_sync_ctrl_xfer(child_dip, ph, - USB_DEV_REQ_DEV_TO_HOST | USB_DEV_REQ_TYPE_STANDARD, - USB_REQ_GET_DESCR, /* bRequest */ - USB_DESCR_TYPE_SETUP_DEV, /* wValue */ - 0, /* wIndex */ - 512, /* wLength */ - &pdata, USB_ATTRS_SHORT_XFER_OK, - &completion_reason, &cb_flags, 0); - - if (rval != USB_SUCCESS) { - if (pdata) { - freemsg(pdata); - pdata = NULL; - } - - USB_DPRINTF_L2(PRINT_MASK_CBOPS, hwahcp->hwahc_log_handle, - "hwahc_create_child: get device descriptor failed " - "(%s 0x%x %d)", usb_str_cr(completion_reason), - cb_flags, rval); - - goto done; - } - - ASSERT(pdata != NULL); - size = usb_parse_dev_descr( - pdata->b_rptr, - MBLKL(pdata), - &usb_dev_descr, - sizeof (usb_dev_descr_t)); - freemsg(pdata); - - if (size < USB_DEV_DESCR_SIZE) { - USB_DPRINTF_L2(PRINT_MASK_CBOPS, hwahcp->hwahc_log_handle, - "hwahc_create_child: get device descriptor size = %lu " - "expected size = %u", size, USB_DEV_DESCR_SIZE); - rval = USB_FAILURE; - - goto done; - } - - bcopy(&usb_dev_descr, child_ud->usb_dev_descr, - sizeof (usb_dev_descr_t)); - child_ud->usb_n_cfgs = usb_dev_descr.bNumConfigurations; - - if (usb_dev_descr.bNumConfigurations == 0) { - USB_DPRINTF_L2(PRINT_MASK_CBOPS, hwahcp->hwahc_log_handle, - "device descriptor:\n\t" - "l=0x%x type=0x%x USB=0x%x class=0x%x subclass=0x%x\n\t" - "protocol=0x%x maxpktsize=0x%x " - "Vid=0x%x Pid=0x%x rel=0x%x\n\t" - "Mfg=0x%x P=0x%x sn=0x%x #config=0x%x", - usb_dev_descr.bLength, usb_dev_descr.bDescriptorType, - usb_dev_descr.bcdUSB, usb_dev_descr.bDeviceClass, - usb_dev_descr.bDeviceSubClass, - usb_dev_descr.bDeviceProtocol, - usb_dev_descr.bMaxPacketSize0, - usb_dev_descr.idVendor, - usb_dev_descr.idProduct, usb_dev_descr.bcdDevice, - usb_dev_descr.iManufacturer, usb_dev_descr.iProduct, - usb_dev_descr.iSerialNumber, - usb_dev_descr.bNumConfigurations); - - rval = USB_FAILURE; - - goto done; - } - - /* get the device string descriptor(s) */ - usba_get_dev_string_descrs(child_dip, child_ud); - - /* retrieve config cloud for all configurations */ - rval = hubd_get_all_device_config_cloud(hwahcp->hwahc_hubd, - child_dip, child_ud); - if (rval != USB_SUCCESS) { - USB_DPRINTF_L2(PRINT_MASK_CBOPS, hwahcp->hwahc_log_handle, - "failed to get configuration descriptor(s)"); - - goto done; - } - - /* get the preferred configuration for this device */ - user_conf_index = hubd_select_device_configuration(hwahcp->hwahc_hubd, - port, child_dip, child_ud); - - /* Check if the user selected configuration index is in range */ - if ((user_conf_index >= usb_dev_descr.bNumConfigurations) || - (user_conf_index < 0)) { - USB_DPRINTF_L2(PRINT_MASK_CBOPS, hwahcp->hwahc_log_handle, - "Configuration index for device idVendor=%d " - "idProduct=%d is=%d, and is out of range[0..%d]", - usb_dev_descr.idVendor, usb_dev_descr.idProduct, - user_conf_index, usb_dev_descr.bNumConfigurations - 1); - - /* treat this as user didn't specify configuration */ - user_conf_index = USBA_DEV_CONFIG_INDEX_UNDEFINED; - } - - if (user_conf_index == USBA_DEV_CONFIG_INDEX_UNDEFINED) { - if (child_ud->usb_preferred_driver) { - /* - * It is the job of the "preferred driver" to put the - * device in the desired configuration. Till then - * put the device in config index 0. - */ - /* h_ignore_pwr_budget = TRUE, not care the power */ - if ((rval = usba_hubdi_check_power_budget(dip, child_ud, - USB_DEV_DEFAULT_CONFIG_INDEX)) != USB_SUCCESS) { - - goto done; - } - - child_dip = hubd_ready_device(hwahcp->hwahc_hubd, - child_dip, child_ud, USB_DEV_DEFAULT_CONFIG_INDEX); - - /* - * Assign the dip before onlining to avoid race - * with busctl - */ - mutex_enter(&hc_data->hc_mutex); - hc_data->hc_children_dips[port] = child_dip; - mutex_exit(&hc_data->hc_mutex); - - (void) usba_bind_driver(child_dip); - } else { - /* - * loop through all the configurations to see if we - * can find a driver for any one config. If not, set - * the device in config_index 0 - */ - rval = USB_FAILURE; - for (config_index = 0; - (config_index < usb_dev_descr.bNumConfigurations) && - (rval != USB_SUCCESS); config_index++) { - - child_dip = hubd_ready_device( - hwahcp->hwahc_hubd, - child_dip, child_ud, config_index); - - /* - * Assign the dip before onlining to avoid race - * with busctl - */ - mutex_enter(&hc_data->hc_mutex); - hc_data->hc_children_dips[port] = child_dip; - mutex_exit(&hc_data->hc_mutex); - - rval = usba_bind_driver(child_dip); - - if (rval == USB_SUCCESS) { - /* always succeed for WUSB device */ - if ((usba_hubdi_check_power_budget(dip, - child_ud, config_index)) != - USB_SUCCESS) { - rval = USB_FAILURE; - - goto done; - } - } - } - - if (rval != USB_SUCCESS) { - if ((usba_hubdi_check_power_budget(dip, - child_ud, 0)) != USB_SUCCESS) { - - goto done; - } - - child_dip = hubd_ready_device( - hwahcp->hwahc_hubd, - child_dip, child_ud, 0); - mutex_enter(&hc_data->hc_mutex); - hc_data->hc_children_dips[port] = child_dip; - mutex_exit(&hc_data->hc_mutex); - } - } /* end else loop all configs */ - } else { - if ((usba_hubdi_check_power_budget(dip, child_ud, - (uint_t)user_conf_index)) != USB_SUCCESS) { - rval = USB_FAILURE; - - goto done; - } - - child_dip = hubd_ready_device(hwahcp->hwahc_hubd, child_dip, - child_ud, (uint_t)user_conf_index); - - /* - * Assign the dip before onlining to avoid race - * with busctl - */ - mutex_enter(&hc_data->hc_mutex); - hc_data->hc_children_dips[port] = child_dip; - mutex_exit(&hc_data->hc_mutex); - - (void) usba_bind_driver(child_dip); - - rval = USB_SUCCESS; - } - - /* workaround for non response after ctrl write */ - usb_pipe_close(child_dip, ph, - USB_FLAGS_SLEEP | USBA_FLAGS_PRIVILEGED, NULL, NULL); - - if ((rval = usb_pipe_open(child_dip, NULL, NULL, - USB_FLAGS_SLEEP | USBA_FLAGS_PRIVILEGED, &ph)) != - USB_SUCCESS) { - USB_DPRINTF_L2(PRINT_MASK_CBOPS, - hwahcp->hwahc_log_handle, - "usb_pipe_open failed (%d)", rval); - - goto done; - } - -done: - _NOTE(NOW_VISIBLE_TO_OTHER_THREADS(*dev_info)); - - ndi_devi_exit(dip, circ); - ndi_devi_exit(rh_dip, rh_circ); - ndi_devi_exit(ddi_get_parent(rh_dip), prh_circ); - - (void) devfs_clean(rh_dip, NULL, 0); - - if (rval == USB_SUCCESS) { - (void) ndi_devi_online(child_dip, 0); - - USB_DPRINTF_L2(PRINT_MASK_CBOPS, hwahcp->hwahc_log_handle, - "hwahc_create_child: create timer for child %p", - (void *)dev_info); - - mutex_enter(&hc_data->hc_mutex); - hwahc_start_trust_timer(dev_info); - mutex_exit(&hc_data->hc_mutex); - } - - ndi_rele_devi(dip); - - return (rval); -} - -/* offline child on a certain port */ -static int -hwahc_destroy_child(dev_info_t *dip, usb_port_t port) -{ - hwahc_state_t *hwahcp; - - if ((hwahcp = ddi_get_soft_state(hwahc_statep, - ddi_get_instance(dip))) == NULL) { - - return (USB_INVALID_ARGS); - } - - hwahc_post_event(hwahcp, port, USBA_EVENT_TAG_HOT_REMOVAL); - - USB_DPRINTF_L3(PRINT_MASK_CBOPS, hwahcp->hwahc_log_handle, - "hwahc_destroy_child: scheduling cleanup"); - - /* schedule cleanup thread */ - hubd_schedule_cleanup(hwahcp->hwahc_hubd->h_usba_device-> - usb_root_hub_dip); - - return (USB_SUCCESS); -} - -/* - * called by cleanup thread to offline child and cleanup child resources - * Child's callback functions have been called before calling this routine. - * dip - hwahc's dip - */ -static int -hwahc_cleanup_child(dev_info_t *dip) -{ - hwahc_state_t *hwahcp; - wusb_hc_data_t *hc_data; - usb_port_t port; - - if ((hwahcp = ddi_get_soft_state(hwahc_statep, - ddi_get_instance(dip))) == NULL) { - - return (USB_INVALID_ARGS); - } - - hc_data = &hwahcp->hwahc_hc_data; - mutex_enter(&hc_data->hc_mutex); - for (port = 1; port <= hc_data->hc_num_ports; port++) { - dev_info_t *cdip = hc_data->hc_children_dips[port]; - - if (cdip == NULL || DEVI_IS_DEVICE_REMOVED(cdip) == 0) { - - continue; - } - - /* - * child's callback has been called and its dip has been - * marked REMOVED. Do further cleanup in hwa driver for - * this child. - */ - mutex_exit(&hc_data->hc_mutex); - (void) hwahc_delete_child(dip, port, NDI_DEVI_REMOVE, B_TRUE); - mutex_enter(&hc_data->hc_mutex); - } - mutex_exit(&hc_data->hc_mutex); - - return (USB_SUCCESS); -} - -/* offline child and cleanup child resources */ -static int -hwahc_delete_child(dev_info_t *dip, usb_port_t port, uint_t flag, - boolean_t retry) -{ - hwahc_state_t *hwahcp; - dev_info_t *child_dip; - usba_device_t *usba_device; - wusb_hc_data_t *hc_data; - int rval; - - if ((hwahcp = ddi_get_soft_state(hwahc_statep, - ddi_get_instance(dip))) == NULL) { - - return (USB_INVALID_ARGS); - } - - child_dip = hwahc_get_child_dip(hwahcp, port); - if (child_dip == NULL) { - - return (USB_SUCCESS); - } - - usba_device = usba_get_usba_device(child_dip); - hc_data = &hwahcp->hwahc_hc_data; - - USB_DPRINTF_L4(PRINT_MASK_CBOPS, hwahcp->hwahc_log_handle, - "hwahc_delete_child: port=%d, dip=0x%p usba_device=0x%p", - port, (void *)child_dip, (void *)usba_device); - - if (usba_device) { - usba_hubdi_incr_power_budget(dip, usba_device); - } - - /* remove this child's dip. If it's <DS_INITIALIZED, free it */ - rval = usba_destroy_child_devi(child_dip, flag); - - if ((rval == USB_SUCCESS) && (flag & NDI_DEVI_REMOVE)) { - /* - * if the child was still < DS_INITIALIZED - * then our bus_unconfig was not called and - * we have to zap the child here - */ - mutex_enter(&hc_data->hc_mutex); - if (hc_data->hc_children_dips[port] == child_dip) { - usba_device_t *ud = hc_data->hc_usba_devices[port]; - wusb_dev_info_t *dev_info = hc_data->hc_dev_infos[port]; - - hc_data->hc_children_dips[port] = NULL; - if (ud) { - mutex_exit(&hc_data->hc_mutex); - - mutex_enter(&ud->usb_mutex); - ud->usb_ref_count = 0; - mutex_exit(&ud->usb_mutex); - - usba_free_usba_device(ud); - mutex_enter(&hc_data->hc_mutex); - hc_data->hc_usba_devices[port] = NULL; - } - - /* free the child's wusb_dev_info data */ - if (dev_info) { - wusb_secrt_data_t *secrt_data; - - if (dev_info-> - wdev_secrt_data.secrt_encry_descr) { - secrt_data = &dev_info->wdev_secrt_data; - kmem_free(secrt_data->secrt_encry_descr, - sizeof (usb_encryption_descr_t) * - secrt_data->secrt_n_encry); - } - if (dev_info->wdev_uwb_descr) { - kmem_free(dev_info->wdev_uwb_descr, - sizeof (usb_uwb_cap_descr_t)); - } - kmem_free(dev_info, sizeof (wusb_dev_info_t)); - hc_data->hc_dev_infos[port] = NULL; - } - } - mutex_exit(&hc_data->hc_mutex); - } - - if ((rval != USB_SUCCESS) && retry) { - - hubd_schedule_cleanup(usba_device->usb_root_hub_dip); - } - - return (rval); -} - -/* - * Set encryption type for WUSB host, refer to WUSB 1.0/8.5.3.6 - * index = port number - 1 - */ -int -hwahc_set_dev_encrypt(usb_pipe_handle_t ph, uint8_t ifc, - usb_port_t index, wusb_secrt_data_t *secrt_data, uint8_t type) -{ - int16_t value; - usb_ctrl_setup_t setup; - usb_cr_t cr; - usb_cb_flags_t cb_flags; - - USB_DPRINTF_L4(DPRINT_MASK_WHCDI, whcdi_log_handle, - "hwahc_set_dev_encrypt: device index = %d", index); - - if (type == USB_ENC_TYPE_UNSECURE) { - value = 0; - } else if (type == USB_ENC_TYPE_CCM_1) { - if (secrt_data == NULL) { - - return (USB_INVALID_ARGS); - } - - value = wusb_get_ccm_encryption_value(secrt_data); - if (value == -1) { - USB_DPRINTF_L2(DPRINT_MASK_WHCDI, whcdi_log_handle, - "hwahc_set_dev_encrypt: cannot find ccm " - "encryption type"); - - return (USB_FAILURE); - } - USB_DPRINTF_L2(DPRINT_MASK_WHCDI, whcdi_log_handle, - "hwahc_set_dev_encrypt: ccm encryption value is %d", - value); - } else { - USB_DPRINTF_L2(DPRINT_MASK_WHCDI, whcdi_log_handle, - "hwahc_set_dev_encrypt: unsupported encryption type %d", - type); - - return (USB_INVALID_ARGS); - } - - setup.bmRequestType = USB_DEV_REQ_HOST_TO_DEV | - USB_DEV_REQ_TYPE_CLASS | USB_DEV_REQ_RCPT_IF; - setup.bRequest = USB_REQ_SET_ENCRYPTION; - setup.wValue = (uint16_t)value; - setup.wIndex = (index << 8) | ifc; - setup.wLength = 0; - setup.attrs = USB_ATTRS_NONE; - - USB_DPRINTF_L2(DPRINT_MASK_WHCDI, whcdi_log_handle, - "bmRequestType=0x%x, bRequest=0x%x, wValue=0x%x, wIndex=0x%x", - setup.bmRequestType, setup.bRequest, setup.wValue, setup.wIndex); - - return (usb_pipe_ctrl_xfer_wait(ph, &setup, NULL, - &cr, &cb_flags, USB_FLAGS_SLEEP)); -} diff --git a/usr/src/uts/common/io/usb/hwa/hwahc/hwahc_util.c b/usr/src/uts/common/io/usb/hwa/hwahc/hwahc_util.c deleted file mode 100644 index 65d828afeb..0000000000 --- a/usr/src/uts/common/io/usb/hwa/hwahc/hwahc_util.c +++ /dev/null @@ -1,1679 +0,0 @@ -/* - * 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 - * or http://www.opensolaris.org/os/licensing. - * 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. - */ -#include <sys/usb/usba/usba_impl.h> /* usba_get_dip */ -#include <sys/usb/hwa/hwahc/hwahc.h> -#include <sys/usb/hwa/hwahc/hwahc_util.h> -#include <sys/strsubr.h> -#include <sys/strsun.h> /* MBLKL */ - -#define WUSB_GTK 1 -#define WUSB_PTK 2 - -/* function prototypes */ -static int hwahc_state_is_operational(hwahc_state_t *hwahcp); -static hwahc_state_t *hwahc_obtain_state(dev_info_t *dip); -static void hwahc_wait_for_xfer_completion(hwahc_state_t *hwahcp, - hwahc_pipe_private_t *pp); -static void hwahc_traverse_requests(hwahc_state_t *hwahcp, - hwahc_pipe_private_t *pp); -static void hwahc_pipe_cleanup(hwahc_state_t *hwahcp, - usba_pipe_handle_data_t *ph); -int hwahc_set_dev_encrypt(usb_pipe_handle_t ph, uint8_t ifc, - usb_port_t index, wusb_secrt_data_t *secrt_data, uint8_t type); - -static int hwahc_hcdi_pm_support(dev_info_t *dip); -static int hwahc_hcdi_pipe_open(usba_pipe_handle_data_t *ph, - usb_flags_t flags); -static int hwahc_hcdi_pipe_close(usba_pipe_handle_data_t *ph, - usb_flags_t flags); -static int hwahc_hcdi_pipe_reset(usba_pipe_handle_data_t *ph, - usb_flags_t flags); -static void hwahc_hcdi_pipe_reset_data_toggle(usba_pipe_handle_data_t *ph); -static int hwahc_hcdi_pipe_ctrl_xfer(usba_pipe_handle_data_t *ph, - usb_ctrl_req_t *ctrl_reqp, usb_flags_t usb_flags); -static int hwahc_hcdi_pipe_bulk_xfer(usba_pipe_handle_data_t *ph, - usb_bulk_req_t *bulk_reqp, usb_flags_t usb_flags); -static int hwahc_hcdi_pipe_intr_xfer(usba_pipe_handle_data_t *ph, - usb_intr_req_t *intr_reqp, usb_flags_t usb_flags); -static int hwahc_hcdi_pipe_isoc_xfer(usba_pipe_handle_data_t *ph, - usb_isoc_req_t *isoc_reqp, usb_flags_t usb_flags); -static int hwahc_hcdi_bulk_transfer_size(usba_device_t *usba_device, - size_t *size); -static int hwahc_hcdi_pipe_stop_intr_polling(usba_pipe_handle_data_t *ph, - usb_flags_t flags); -static int hwahc_hcdi_pipe_stop_isoc_polling(usba_pipe_handle_data_t *ph, - usb_flags_t flags); -static int hwahc_hcdi_get_current_frame_number(usba_device_t *usba_device, - usb_frame_number_t *frame_number); -static int hwahc_hcdi_get_max_isoc_pkts(usba_device_t *usba_device, - uint_t *max_pkts); -static int hwahc_hcdi_polled_input_init(usba_pipe_handle_data_t *ph, - uchar_t **polled_buf, usb_console_info_impl_t *console_input_info); -static int hwahc_hcdi_polled_input_fini(usb_console_info_impl_t *info); -static int hwahc_hcdi_polled_input_enter(usb_console_info_impl_t *info); -static int hwahc_hcdi_polled_input_exit(usb_console_info_impl_t *info); -static int hwahc_hcdi_polled_read(usb_console_info_impl_t *info, - uint_t *num_characters); -usba_hcdi_ops_t *hwahc_alloc_hcdi_ops(hwahc_state_t *hwahcp); - -extern void *hwahc_statep; - -/* Check the Host controller state and return proper values */ -static int -hwahc_state_is_operational(hwahc_state_t *hwahcp) -{ - int rval; - - ASSERT(mutex_owned(&hwahcp->hwahc_mutex)); - - if (hwahcp->hwahc_dev_state != USB_DEV_ONLINE) { - - return (USB_FAILURE); - } - - switch (hwahcp->hwahc_hc_soft_state) { - case HWAHC_CTRL_INIT_STATE: - rval = USB_FAILURE; - break; - case HWAHC_CTRL_OPERATIONAL_STATE: - /* still need to check if channel is operational */ - if (hwahcp->hwahc_hw_state != HWAHC_HW_STARTED) { - rval = USB_FAILURE; - } else { - rval = USB_SUCCESS; - } - - break; - case HWAHC_CTRL_ERROR_STATE: - rval = USB_HC_HARDWARE_ERROR; - break; - default: - rval = USB_FAILURE; - break; - } - - return (rval); -} - -/* get soft state pointer */ -hwahc_state_t * -hwahc_obtain_state(dev_info_t *dip) -{ - int instance = ddi_get_instance(dip); - - hwahc_state_t *hwahcp = ddi_get_soft_state(hwahc_statep, instance); - - ASSERT(hwahcp != NULL); - - return (hwahcp); -} - - -/* - * Do not support wusb bus PM now - */ -/* ARGSUSED */ -static int -hwahc_hcdi_pm_support(dev_info_t *dip) -{ - return (USB_FAILURE); -} - -static void -/* ARGSUSED */ -hwahc_hcdi_pipe_reset_data_toggle(usba_pipe_handle_data_t *ph) -{ - /* don't do anything now */ -} - -/* Wait for processing all completed transfers and to send results */ -static void -hwahc_wait_for_xfer_completion(hwahc_state_t *hwahcp, hwahc_pipe_private_t *pp) -{ - wusb_wa_rpipe_hdl_t *hdl = pp->pp_rp; - - mutex_enter(&hdl->rp_mutex); - if (hdl->rp_state != WA_RPIPE_STATE_ACTIVE) { - mutex_exit(&hdl->rp_mutex); - - return; - } - mutex_exit(&hdl->rp_mutex); - - /* wait 3s */ - (void) cv_reltimedwait(&pp->pp_xfer_cmpl_cv, &hwahcp->hwahc_mutex, - drv_usectohz(3000000), TR_CLOCK_TICK); - - mutex_enter(&hdl->rp_mutex); - if (hdl->rp_state == WA_RPIPE_STATE_ACTIVE) { - USB_DPRINTF_L2(PRINT_MASK_HCDI, hwahcp->hwahc_log_handle, - "hwahc_wait_for_xfer_completion: no transfer completion " - "confirmation received"); - } - mutex_exit(&hdl->rp_mutex); -} - -/* remove all the unprocessed requests and do callback */ -/* ARGSUSED */ -static void -hwahc_traverse_requests(hwahc_state_t *hwahcp, hwahc_pipe_private_t *pp) -{ - wusb_wa_rpipe_hdl_t *hdl = pp->pp_rp; - wusb_wa_trans_wrapper_t *wr; - - mutex_enter(&hdl->rp_mutex); - - USB_DPRINTF_L4(PRINT_MASK_HCDI, hwahcp->hwahc_log_handle, - "hwahc_traverse_requests: pp = 0x%p, wr=%p", (void*)pp, - (void *)hdl->rp_curr_wr); - - wr = hdl->rp_curr_wr; - if (wr != NULL) { - wusb_wa_stop_xfer_timer(wr); - hdl->rp_state = WA_RPIPE_STATE_IDLE; - hdl->rp_curr_wr = NULL; - wr->wr_state = WR_ABORTED; - mutex_exit(&hdl->rp_mutex); - - mutex_exit(&hwahcp->hwahc_mutex); - - /* - * This CR is to tell USBA to mark this pipe as IDLE, - * so that do not queue client requests at USBA. Requests - * sent after pipe close/reset will be handled by hwahc. - */ - wr->wr_cb(wr->wr_wa_data, wr, USB_CR_NOT_SUPPORTED, 0); - - mutex_enter(&hwahcp->hwahc_mutex); - mutex_enter(&hdl->rp_mutex); - } - mutex_exit(&hdl->rp_mutex); -} - -/* process periodic(INTR/ISOC) requests */ -static void -hwahc_do_client_periodic_in_req_callback(hwahc_state_t *hwahcp, - hwahc_pipe_private_t *pp, usb_cr_t completion_reason) -{ - usb_ep_descr_t *eptd; - - USB_DPRINTF_L4(PRINT_MASK_HCDI, hwahcp->hwahc_log_handle, - "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. - */ - eptd = &(pp->pp_pipe_handle->p_ep); - if (pp->pp_client_periodic_in_reqp) { - if (WUSB_ISOC_ENDPOINT(eptd)) { - /* not supported */ - USB_DPRINTF_L4(PRINT_MASK_HCDI, - hwahcp->hwahc_log_handle, - "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 - */ - wusb_wa_callback(&hwahcp->hwahc_wa_data, - pp->pp_pipe_handle, NULL, completion_reason); - } - } - - USB_DPRINTF_L4(PRINT_MASK_HCDI, hwahcp->hwahc_log_handle, - "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 -hwahc_pipe_cleanup(hwahc_state_t *hwahcp, usba_pipe_handle_data_t *ph) -{ - hwahc_pipe_private_t *pp; - wusb_wa_rpipe_hdl_t *hdl; - int rval; - usb_ep_descr_t *eptd; - usb_cr_t completion_reason; - - pp = (hwahc_pipe_private_t *)ph->p_hcd_private; - - USB_DPRINTF_L4(PRINT_MASK_HCDI, hwahcp->hwahc_log_handle, - "hwahc_pipe_cleanup: ph = 0x%p, p_req_cnt, ep=0x%02x," - " state=%d", (void *) ph, ph->p_ep.bEndpointAddress, - pp->pp_state); - - ASSERT(mutex_owned(&hwahcp->hwahc_mutex)); - ASSERT(!servicing_interrupt()); - - hdl = pp->pp_rp; - - if (hwahcp->hwahc_dev_state == USB_DEV_ONLINE) { - /* abort rpipe */ - mutex_enter(&hdl->rp_mutex); - - /* if active, abort the requests */ - if (hdl->rp_state == WA_RPIPE_STATE_ACTIVE) { - mutex_exit(&hdl->rp_mutex); - mutex_exit(&hwahcp->hwahc_mutex); - rval = wusb_wa_rpipe_abort(hwahcp->hwahc_dip, - hwahcp->hwahc_default_pipe, hdl); - mutex_enter(&hwahcp->hwahc_mutex); - mutex_enter(&hdl->rp_mutex); - } - mutex_exit(&hdl->rp_mutex); - - /* wait for transfers to complete */ - hwahc_wait_for_xfer_completion(hwahcp, pp); - } - - /* remove all unprocessed requests on this pipe and do callback */ - hwahc_traverse_requests(hwahcp, pp); - - switch (pp->pp_state) { - case HWAHC_PIPE_STATE_CLOSE: - completion_reason = USB_CR_PIPE_CLOSING; - - mutex_exit(&hwahcp->hwahc_mutex); - (void) wusb_wa_rpipe_reset(hwahcp->hwahc_dip, ph, hdl, 0); - mutex_enter(&hwahcp->hwahc_mutex); - - break; - case HWAHC_PIPE_STATE_RESET: - case HWAHC_PIPE_STATE_ERROR: - completion_reason = USB_CR_PIPE_RESET; - if (hwahcp->hwahc_dev_state == USB_DEV_ONLINE) { - mutex_exit(&hwahcp->hwahc_mutex); - /* - * reset WA's RPipe. - * If this pipe is not bound to the default endpoint, - * also send a clear_feature request to that ep. - */ - rval = wusb_wa_rpipe_reset(hwahcp->hwahc_dip, - ph, hdl, 1); - mutex_enter(&hwahcp->hwahc_mutex); - - USB_DPRINTF_L4(PRINT_MASK_HCDI, - hwahcp->hwahc_log_handle, - "hwahc_pipe_cleanup: rp reset, rv=%d", - rval); - - pp->pp_state = HWAHC_PIPE_STATE_IDLE; - } - - break; - case HWAHC_PIPE_STATE_STOP_POLLING: - completion_reason = USB_CR_STOPPED_POLLING; - pp->pp_state = HWAHC_PIPE_STATE_IDLE; - - break; - } - - /* - * Do the callback for the original client - * periodic IN request. - */ - eptd = &ph->p_ep; - - USB_DPRINTF_L4(PRINT_MASK_HCDI, hwahcp->hwahc_log_handle, - "hwahc_pipe_cleanup: end"); - - if ((WUSB_PERIODIC_ENDPOINT(eptd)) && - ((ph->p_ep.bEndpointAddress & USB_EP_DIR_MASK) == - USB_EP_DIR_IN)) { - mutex_exit(&hwahcp->hwahc_mutex); - - hwahc_do_client_periodic_in_req_callback( - hwahcp, pp, completion_reason); - - mutex_enter(&hwahcp->hwahc_mutex); - } -} - -/* - * set the pipe's parent device information - */ -static int -hwahc_set_pipe_dev_info(hwahc_state_t *hwahcp, - usba_pipe_handle_data_t *ph, hwahc_pipe_private_t *pp) -{ - dev_info_t *dip = NULL; - wusb_hc_data_t *hc_data; - int i; - - dip = usba_get_dip((usb_pipe_handle_t)ph->p_ph_impl); - if (dip == NULL) { - - return (USB_FAILURE); - } - - hc_data = &hwahcp->hwahc_hc_data; - - mutex_enter(&hc_data->hc_mutex); - for (i = 1; i <= hc_data->hc_num_ports; i++) { - if ((dip == hc_data->hc_children_dips[i])) { - pp->pp_wdev = hc_data->hc_dev_infos[i]; - - USB_DPRINTF_L3(DPRINT_MASK_HCDI, - hwahcp->hwahc_log_handle, - "hwahc_set_pipe_dev_info: pp(%p) device(%p) set", - (void *) pp, (void *) pp->pp_wdev); - - break; - } - } - - mutex_exit(&hc_data->hc_mutex); - - if (pp->pp_wdev) { - 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 -hwahc_hcdi_pipe_open( - usba_pipe_handle_data_t *ph, - usb_flags_t flags) -{ - int rval; - hwahc_state_t *hwahcp; - int kmflag; - hwahc_pipe_private_t *pp; - usb_ep_descr_t *epdt = &ph->p_ep; - uint8_t type; - wusb_wa_data_t *wa; - - hwahcp = hwahc_obtain_state(ph->p_usba_device->usb_root_hub_dip); - wa = &hwahcp->hwahc_wa_data; - - USB_DPRINTF_L4(PRINT_MASK_HCDI, hwahcp->hwahc_log_handle, - "hwahc_hcdi_pipe_open: hwahc=0x%p, ph=0x%p," - " addr = 0x%x, ep=0x%02X", (void *) hwahcp, (void *) ph, - ph->p_usba_device->usb_addr, epdt->bEndpointAddress); - - kmflag = (flags & USB_FLAGS_SLEEP) ? KM_SLEEP : KM_NOSLEEP; - - if (ph->p_hcd_private) { - USB_DPRINTF_L2(PRINT_MASK_HCDI, hwahcp->hwahc_log_handle, - "hwahc_hcdi_pipe_open: Pipe is already opened"); - - return (USB_FAILURE); - } - - pp = kmem_zalloc(sizeof (hwahc_pipe_private_t), kmflag); - if (pp == NULL) { - USB_DPRINTF_L2(PRINT_MASK_HCDI, hwahcp->hwahc_log_handle, - "hwahc_hcdi_pipe_open: alloc pp failed"); - - return (USB_NO_RESOURCES); - } - - mutex_enter(&hwahcp->hwahc_mutex); - - if (hwahc_set_pipe_dev_info(hwahcp, ph, pp) < 0) { - USB_DPRINTF_L2(PRINT_MASK_HCDI, hwahcp->hwahc_log_handle, - "hwahc_hcdi_pipe_open: set pipe dev_info failed"); - mutex_exit(&hwahcp->hwahc_mutex); - - return (USB_FAILURE); - } - - rval = hwahc_state_is_operational(hwahcp); - if (rval != USB_SUCCESS) { - USB_DPRINTF_L2(PRINT_MASK_HCDI, hwahcp->hwahc_log_handle, - "hwahc_hcdi_pipe_open: state error: %d", rval); - kmem_free(pp, sizeof (hwahc_pipe_private_t)); - mutex_exit(&hwahcp->hwahc_mutex); - - return (rval); - } - - /* assign rpipe to the endpoint */ - type = epdt->bmAttributes & USB_EP_ATTR_MASK; - rval = wusb_wa_get_rpipe(&hwahcp->hwahc_wa_data, - hwahcp->hwahc_default_pipe, type, &pp->pp_rp, - PRINT_MASK_HCDI, hwahcp->hwahc_log_handle); - if (rval != USB_SUCCESS) { - USB_DPRINTF_L2(PRINT_MASK_HCDI, hwahcp->hwahc_log_handle, - "hwahc_hcdi_pipe_open: getting rpipe failed"); - kmem_free(pp, sizeof (hwahc_pipe_private_t)); - mutex_exit(&hwahcp->hwahc_mutex); - - return (USB_NO_RESOURCES); - } - - mutex_exit(&hwahcp->hwahc_mutex); - /* target the rpipe to the endpoint */ - rval = wusb_wa_set_rpipe_target(hwahcp->hwahc_dip, wa, - hwahcp->hwahc_default_pipe, ph, pp->pp_rp); - mutex_enter(&hwahcp->hwahc_mutex); - - if (rval != USB_SUCCESS) { - USB_DPRINTF_L2(PRINT_MASK_HCDI, hwahcp->hwahc_log_handle, - "hwahc_hcdi_pipe_open: set target for rpipe failed"); - (void) wusb_wa_release_rpipe(wa, pp->pp_rp); - kmem_free(pp, sizeof (hwahc_pipe_private_t)); - mutex_exit(&hwahcp->hwahc_mutex); - - return (USB_FAILURE); - } - - pp->pp_pipe_handle = ph; - cv_init(&pp->pp_xfer_cmpl_cv, NULL, CV_DRIVER, NULL); - - mutex_enter(&ph->p_mutex); - ph->p_hcd_private = (usb_opaque_t)pp; - bcopy(&ph->p_policy, &pp->pp_policy, sizeof (usb_pipe_policy_t)); - mutex_exit(&ph->p_mutex); - - pp->pp_state = HWAHC_PIPE_STATE_IDLE; - hwahcp->hwahc_open_pipe_count++; - mutex_exit(&hwahcp->hwahc_mutex); - - 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( - usba_pipe_handle_data_t *ph, - usb_flags_t flags) -{ - hwahc_state_t *hwahcp; - hwahc_pipe_private_t *pp; - usb_ep_descr_t *epdt = &ph->p_ep; - - hwahcp = hwahc_obtain_state(ph->p_usba_device->usb_root_hub_dip); - - USB_DPRINTF_L4(PRINT_MASK_HCDI, hwahcp->hwahc_log_handle, - "hwahc_hcdi_pipe_close:ph=0x%p addr = 0x%x, ep = 0x%x", - (void *) ph, ph->p_usba_device->usb_addr, - epdt->bEndpointAddress); - - ASSERT(ph->p_hcd_private != NULL); - pp = (hwahc_pipe_private_t *)ph->p_hcd_private; - - mutex_enter(&hwahcp->hwahc_mutex); - - pp->pp_state = HWAHC_PIPE_STATE_CLOSE; - - hwahc_pipe_cleanup(hwahcp, ph); - - mutex_exit(&hwahcp->hwahc_mutex); - - wusb_wa_clear_dev_ep(ph); /* clear the remote dev's endpoint */ - mutex_enter(&hwahcp->hwahc_mutex); - - (void) wusb_wa_release_rpipe(&hwahcp->hwahc_wa_data, pp->pp_rp); - - mutex_enter(&ph->p_mutex); - cv_destroy(&pp->pp_xfer_cmpl_cv); - kmem_free(pp, sizeof (hwahc_pipe_private_t)); - ph->p_hcd_private = NULL; - mutex_exit(&ph->p_mutex); - hwahcp->hwahc_open_pipe_count--; - mutex_exit(&hwahcp->hwahc_mutex); - - USB_DPRINTF_L4(PRINT_MASK_HCDI, hwahcp->hwahc_log_handle, - "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( - usba_pipe_handle_data_t *ph, - usb_flags_t flags) -{ - hwahc_state_t *hwahcp; - hwahc_pipe_private_t *pp; - - hwahcp = hwahc_obtain_state(ph->p_usba_device->usb_root_hub_dip); - - USB_DPRINTF_L4(PRINT_MASK_HCDI, hwahcp->hwahc_log_handle, - "hwahc_hcdi_pipe_reset: ph = 0x%p, ep=0x%02x", - (void *) ph, ph->p_ep.bEndpointAddress); - - ASSERT(ph->p_hcd_private != NULL); - pp = (hwahc_pipe_private_t *)ph->p_hcd_private; - - mutex_enter(&hwahcp->hwahc_mutex); - pp->pp_state = HWAHC_PIPE_STATE_RESET; - hwahc_pipe_cleanup(hwahcp, ph); - mutex_exit(&hwahcp->hwahc_mutex); - - USB_DPRINTF_L4(PRINT_MASK_HCDI, hwahcp->hwahc_log_handle, - "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 -hwahc_hcdi_pipe_ctrl_xfer( - usba_pipe_handle_data_t *ph, - usb_ctrl_req_t *ctrl_reqp, - usb_flags_t usb_flags) -{ - hwahc_state_t *hwahcp; - hwahc_pipe_private_t *pp; - int rval; - uint8_t ep_addr = ph->p_ep.bEndpointAddress; - - hwahcp = hwahc_obtain_state(ph->p_usba_device->usb_root_hub_dip); - - USB_DPRINTF_L4(PRINT_MASK_HCDI, hwahcp->hwahc_log_handle, - "hwahc_hcdi_pipe_ctrl_xfer: hwahcp=0x%p ph = 0x%p" - " reqp = 0x%p flags = %x", (void *) hwahcp, (void *) ph, - (void *) ctrl_reqp, usb_flags); - - ASSERT(ph->p_hcd_private != NULL); - pp = (hwahc_pipe_private_t *)ph->p_hcd_private; - - mutex_enter(&hwahcp->hwahc_mutex); - rval = hwahc_state_is_operational(hwahcp); - if (rval != USB_SUCCESS) { - mutex_exit(&hwahcp->hwahc_mutex); - - 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. - */ - if ((pp->pp_state == HWAHC_PIPE_STATE_ERROR)) { - USB_DPRINTF_L2(PRINT_MASK_HCDI, hwahcp->hwahc_log_handle, - "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 - */ - mutex_exit(&hwahcp->hwahc_mutex); - (void) wusb_wa_rpipe_reset(hwahcp->hwahc_dip, ph, - pp->pp_rp, 1); - mutex_enter(&hwahcp->hwahc_mutex); - pp->pp_state = 0; - } else { - /* client driver should clear non-default endpoint's state */ - mutex_exit(&hwahcp->hwahc_mutex); - - return (USB_FAILURE); - } - } else if ((pp->pp_state != HWAHC_PIPE_STATE_IDLE) && - (pp->pp_state != HWAHC_PIPE_STATE_ERROR)) { - mutex_exit(&hwahcp->hwahc_mutex); - - return (USB_PIPE_ERROR); - } - - mutex_exit(&hwahcp->hwahc_mutex); - - rval = wusb_wa_ctrl_xfer(&hwahcp->hwahc_wa_data, pp->pp_rp, ph, - ctrl_reqp, usb_flags); - if (rval != USB_SUCCESS) { - USB_DPRINTF_L2(PRINT_MASK_HCDI, hwahcp->hwahc_log_handle, - "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 -hwahc_hcdi_pipe_bulk_xfer( - usba_pipe_handle_data_t *ph, - usb_bulk_req_t *bulk_reqp, - usb_flags_t usb_flags) -{ - hwahc_state_t *hwahcp; - hwahc_pipe_private_t *pp; - int rval; - - hwahcp = hwahc_obtain_state(ph->p_usba_device->usb_root_hub_dip); - - USB_DPRINTF_L4(PRINT_MASK_HCDI, hwahcp->hwahc_log_handle, - "hwahc_hcdi_pipe_bulk_xfer: hwahcp=0x%p ph = 0x%p reqp = 0x%p" - " flags = %x", (void *) hwahcp, (void *) ph, - (void *) bulk_reqp, usb_flags); - - ASSERT(ph->p_hcd_private != NULL); - - pp = (hwahc_pipe_private_t *)ph->p_hcd_private; - - mutex_enter(&hwahcp->hwahc_mutex); - rval = hwahc_state_is_operational(hwahcp); - if (rval != USB_SUCCESS) { - mutex_exit(&hwahcp->hwahc_mutex); - - return (rval); - } - - USB_DPRINTF_L4(PRINT_MASK_HCDI, hwahcp->hwahc_log_handle, - "hwahc_hcdi_pipe_bulk_xfer: pp = 0x%p state= %x", (void *) pp, - pp->pp_state); - - if (pp->pp_state == HWAHC_PIPE_STATE_ERROR) { - USB_DPRINTF_L2(PRINT_MASK_HCDI, hwahcp->hwahc_log_handle, - "hwahc_hcdi_pipe_bulk_xfer: " - "Pipe is in error state, need pipe reset to continue"); - - mutex_exit(&hwahcp->hwahc_mutex); - - return (USB_FAILURE); - } - - mutex_exit(&hwahcp->hwahc_mutex); - rval = wusb_wa_bulk_xfer(&hwahcp->hwahc_wa_data, pp->pp_rp, ph, - bulk_reqp, usb_flags); - mutex_enter(&hwahcp->hwahc_mutex); - if (rval != USB_SUCCESS) { - USB_DPRINTF_L2(PRINT_MASK_HCDI, hwahcp->hwahc_log_handle, - "hwahc_hcdi_pipe_bulk_xfer failed, rval = %d", rval); - } - mutex_exit(&hwahcp->hwahc_mutex); - - 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( - usba_pipe_handle_data_t *ph, - usb_intr_req_t *intr_reqp, - usb_flags_t usb_flags) -{ - hwahc_state_t *hwahcp; - hwahc_pipe_private_t *pp; - int rval, pipe_dir; - - hwahcp = hwahc_obtain_state(ph->p_usba_device->usb_root_hub_dip); - - USB_DPRINTF_L4(PRINT_MASK_HCDI, hwahcp->hwahc_log_handle, - "hwahc_hcdi_pipe_intr_xfer: hwahcp=0x%p ph = 0x%p" - " reqp = 0x%p flags = %x", (void *) hwahcp, (void *) ph, - (void *) intr_reqp, usb_flags); - - ASSERT(ph->p_hcd_private != NULL); - pp = (hwahc_pipe_private_t *)ph->p_hcd_private; - - mutex_enter(&hwahcp->hwahc_mutex); - rval = hwahc_state_is_operational(hwahcp); - if (rval != USB_SUCCESS) { - mutex_exit(&hwahcp->hwahc_mutex); - - return (rval); - } - - USB_DPRINTF_L4(PRINT_MASK_HCDI, hwahcp->hwahc_log_handle, - "hwahc_hcdi_pipe_intr_xfer: pp = 0x%p state= %x", (void *) pp, - pp->pp_state); - - if (pp->pp_state == HWAHC_PIPE_STATE_ERROR) { - USB_DPRINTF_L2(PRINT_MASK_HCDI, hwahcp->hwahc_log_handle, - "hwahc_hcdi_pipe_intr_xfer: " - "Pipe is in error state, need pipe reset to continue"); - - mutex_exit(&hwahcp->hwahc_mutex); - - return (USB_FAILURE); - } - - pipe_dir = ph->p_ep.bEndpointAddress & USB_EP_DIR_MASK; - - - mutex_exit(&hwahcp->hwahc_mutex); - rval = wusb_wa_intr_xfer(&hwahcp->hwahc_wa_data, pp->pp_rp, ph, - intr_reqp, usb_flags); - mutex_enter(&hwahcp->hwahc_mutex); - if (rval != USB_SUCCESS) { - USB_DPRINTF_L2(PRINT_MASK_HCDI, hwahcp->hwahc_log_handle, - "hwahc_hcdi_pipe_intr_xfer failed, rval = %d", rval); - } - - if ((pipe_dir == USB_EP_DIR_IN) &&(rval == USB_SUCCESS)) { - /* - * the request has been submitted successfully, - * save the original one; free this request when polling - * stopped - */ - pp->pp_client_periodic_in_reqp = (usb_opaque_t)intr_reqp; - pp->pp_state = HWAHC_PIPE_STATE_ACTIVE; - } - - mutex_exit(&hwahcp->hwahc_mutex); - - return (rval); -} - -/* - * hwahc_hcdi_pipe_isoc_xfer: - */ -/* ARGSUSED */ -static int -hwahc_hcdi_pipe_isoc_xfer( - usba_pipe_handle_data_t *ph, - usb_isoc_req_t *isoc_reqp, - usb_flags_t usb_flags) -{ - return (USB_NOT_SUPPORTED); -} - - -/* - * hwahc_hcdi_bulk_transfer_size: - * - * Return maximum bulk transfer size - */ -/* ARGSUSED */ -static int -hwahc_hcdi_bulk_transfer_size( - usba_device_t *usba_device, - size_t *size) -{ - hwahc_state_t *hwahcp; - int rval; - - hwahcp = hwahc_obtain_state(usba_device->usb_root_hub_dip); - - USB_DPRINTF_L4(PRINT_MASK_HCDI, hwahcp->hwahc_log_handle, - "hwahc_hcdi_bulk_transfer_size:"); - - mutex_enter(&hwahcp->hwahc_mutex); - rval = hwahc_state_is_operational(hwahcp); - mutex_exit(&hwahcp->hwahc_mutex); - - if (rval != USB_SUCCESS) { - - return (rval); - } - - *size = WA_MAX_SEG_COUNT * 1024; - - return (USB_SUCCESS); -} - -/* - * hwahc_hcdi_pipe_stop_intr_polling() - */ -/* ARGSUSED */ -static int -hwahc_hcdi_pipe_stop_intr_polling( - usba_pipe_handle_data_t *ph, - usb_flags_t flags) -{ - hwahc_state_t *hwahcp; - hwahc_pipe_private_t *pp; - - hwahcp = hwahc_obtain_state(ph->p_usba_device->usb_root_hub_dip); - - USB_DPRINTF_L4(PRINT_MASK_HCDI, hwahcp->hwahc_log_handle, - "hwahc_hcdi_pipe_stop_intr_polling: hwahcp=0x%p ph = 0x%p" - " flags = %x", (void *) hwahcp, (void *) ph, flags); - - ASSERT(ph->p_hcd_private != NULL); - - mutex_enter(&hwahcp->hwahc_mutex); - pp = (hwahc_pipe_private_t *)ph->p_hcd_private; - - if (pp->pp_state != HWAHC_PIPE_STATE_ACTIVE) { - USB_DPRINTF_L2(PRINT_MASK_HCDI, hwahcp->hwahc_log_handle, - "hwahc_hcdi_pipe_stop_intr_polling: " - "Polling already stopped"); - mutex_exit(&hwahcp->hwahc_mutex); - - return (USB_SUCCESS); - } - - pp->pp_state = HWAHC_PIPE_STATE_STOP_POLLING; - - hwahc_pipe_cleanup(hwahcp, ph); - - mutex_exit(&hwahcp->hwahc_mutex); - - return (USB_SUCCESS); -} - - -/* - * hwahc_hcdi_pipe_stop_isoc_polling() - */ -/*ARGSUSED*/ -static int -hwahc_hcdi_pipe_stop_isoc_polling( - usba_pipe_handle_data_t *ph, - usb_flags_t flags) -{ - 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 -hwahc_hcdi_get_current_frame_number( - usba_device_t *usba_device, - usb_frame_number_t *frame_number) -{ - 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 -hwahc_hcdi_get_max_isoc_pkts( - usba_device_t *usba_device, - uint_t *max_pkts) -{ - 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 -hwahc_hcdi_polled_input_init( - usba_pipe_handle_data_t *ph, - uchar_t **polled_buf, - usb_console_info_impl_t *console_input_info) -{ - return (USB_FAILURE); -} - - -/* - * hwahc_hcdi_polled_input_fini: - */ -/* ARGSUSED */ -static int -hwahc_hcdi_polled_input_fini(usb_console_info_impl_t *info) -{ - 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 -hwahc_hcdi_polled_input_enter(usb_console_info_impl_t *info) -{ - 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 -hwahc_hcdi_polled_input_exit(usb_console_info_impl_t *info) -{ - return (USB_FAILURE); -} - - -/* - * hwahc_hcdi_polled_read: - * - * Get a key character - */ -/* ARGSUSED */ -static int -hwahc_hcdi_polled_read( - usb_console_info_impl_t *info, - uint_t *num_characters) -{ - 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. - */ -usba_hcdi_ops_t * -hwahc_alloc_hcdi_ops(hwahc_state_t *hwahcp) -{ - usba_hcdi_ops_t *usba_hcdi_ops; - - USB_DPRINTF_L2(PRINT_MASK_ATTA, hwahcp->hwahc_log_handle, - "hwahc_alloc_hcdi_ops:"); - - usba_hcdi_ops = usba_alloc_hcdi_ops(); - - usba_hcdi_ops->usba_hcdi_ops_version = HCDI_OPS_VERSION; - - usba_hcdi_ops->usba_hcdi_pm_support = hwahc_hcdi_pm_support; - usba_hcdi_ops->usba_hcdi_pipe_open = hwahc_hcdi_pipe_open; - usba_hcdi_ops->usba_hcdi_pipe_close = hwahc_hcdi_pipe_close; - - usba_hcdi_ops->usba_hcdi_pipe_reset = hwahc_hcdi_pipe_reset; - usba_hcdi_ops->usba_hcdi_pipe_reset_data_toggle = - hwahc_hcdi_pipe_reset_data_toggle; - - usba_hcdi_ops->usba_hcdi_pipe_ctrl_xfer = hwahc_hcdi_pipe_ctrl_xfer; - usba_hcdi_ops->usba_hcdi_pipe_bulk_xfer = hwahc_hcdi_pipe_bulk_xfer; - usba_hcdi_ops->usba_hcdi_pipe_intr_xfer = hwahc_hcdi_pipe_intr_xfer; - usba_hcdi_ops->usba_hcdi_pipe_isoc_xfer = hwahc_hcdi_pipe_isoc_xfer; - - usba_hcdi_ops->usba_hcdi_bulk_transfer_size = - hwahc_hcdi_bulk_transfer_size; - - usba_hcdi_ops->usba_hcdi_pipe_stop_intr_polling = - hwahc_hcdi_pipe_stop_intr_polling; - usba_hcdi_ops->usba_hcdi_pipe_stop_isoc_polling = - hwahc_hcdi_pipe_stop_isoc_polling; - - usba_hcdi_ops->usba_hcdi_get_current_frame_number = - hwahc_hcdi_get_current_frame_number; - usba_hcdi_ops->usba_hcdi_get_max_isoc_pkts = - hwahc_hcdi_get_max_isoc_pkts; - - usba_hcdi_ops->usba_hcdi_console_input_init = - hwahc_hcdi_polled_input_init; - usba_hcdi_ops->usba_hcdi_console_input_enter = - hwahc_hcdi_polled_input_enter; - usba_hcdi_ops->usba_hcdi_console_read = - hwahc_hcdi_polled_read; - usba_hcdi_ops->usba_hcdi_console_input_exit = - hwahc_hcdi_polled_input_exit; - usba_hcdi_ops->usba_hcdi_console_input_fini = - hwahc_hcdi_polled_input_fini; - - return (usba_hcdi_ops); -} - - -/* - * Set cluster ID. - * see 8.5.3.11 - */ -int -hwahc_set_cluster_id(dev_info_t *dip, uint8_t cluster_id) -{ - usb_cr_t completion_reason; - usb_cb_flags_t cb_flags; - int rval; - hwahc_state_t *hwahcp; - - if (dip == NULL) { - - return (USB_INVALID_ARGS); - } - - hwahcp = ddi_get_soft_state(hwahc_statep, ddi_get_instance(dip)); - if (hwahcp == NULL) { - - return (USB_INVALID_ARGS); - } - - rval = usb_pipe_sync_ctrl_xfer(dip, hwahcp->hwahc_default_pipe, - WUSB_CLASS_IF_REQ_OUT_TYPE, - HWA_REQ_SET_CLUSTER_ID, - cluster_id, - hwahcp->hwahc_wa_data.wa_ifno, - 0, - NULL, 0, - &completion_reason, &cb_flags, 0); - - if (rval != USB_SUCCESS) { - USB_DPRINTF_L2(PRINT_MASK_HCDI, hwahcp->hwahc_log_handle, - "Set_Cluster_ID fails: rval=%d cr=%d cb=0x%x", - rval, completion_reason, cb_flags); - } - - return (rval); -} - -/* - * Set WUSB Stream Index. see 8.5.3.13 - */ -int -hwahc_set_stream_idx(dev_info_t *dip, uint8_t stream_idx) -{ - usb_cr_t completion_reason; - usb_cb_flags_t cb_flags; - int rval; - hwahc_state_t *hwahcp; - - if ((dip == NULL)) { - - return (USB_INVALID_ARGS); - } - - hwahcp = ddi_get_soft_state(hwahc_statep, ddi_get_instance(dip)); - if (hwahcp == NULL) { - - return (USB_INVALID_ARGS); - } - - rval = usb_pipe_sync_ctrl_xfer(dip, hwahcp->hwahc_default_pipe, - WUSB_CLASS_IF_REQ_OUT_TYPE, - HWA_REQ_SET_STREAM_IDX, - stream_idx, - hwahcp->hwahc_wa_data.wa_ifno, - 0, NULL, 0, &completion_reason, - &cb_flags, 0); - - if (rval != USB_SUCCESS) { - USB_DPRINTF_L2(PRINT_MASK_HCDI, hwahcp->hwahc_log_handle, - "Set_Stream_Idx fails: rval=%d cr=%d cb=0x%x", - rval, completion_reason, cb_flags); - } - - return (rval); -} - -/* - * 8.5.3.12 - Set WUSB MAS - * Caller must ensure the data is WUSB_SET_WUSB_MAS_LEN long. - */ -int -hwahc_set_wusb_mas(dev_info_t *dip, uint8_t *data) -{ - usb_cr_t completion_reason; - usb_cb_flags_t cb_flags; - mblk_t *blk; - int rval, i; - hwahc_state_t *hwahcp; - - if ((dip == NULL)) { - - return (USB_INVALID_ARGS); - } - - hwahcp = ddi_get_soft_state(hwahc_statep, ddi_get_instance(dip)); - if (hwahcp == NULL) { - - return (USB_INVALID_ARGS); - } - - blk = allocb_wait(WUSB_SET_WUSB_MAS_LEN, BPRI_LO, STR_NOSIG, NULL); - - for (i = 0; i < WUSB_SET_WUSB_MAS_LEN; i++) { - *blk->b_wptr++ = data[i]; - } - - rval = usb_pipe_sync_ctrl_xfer(dip, hwahcp->hwahc_default_pipe, - WUSB_CLASS_IF_REQ_OUT_TYPE, - HWA_REQ_SET_WUSB_MAS, - 0, - hwahcp->hwahc_wa_data.wa_ifno, - WUSB_SET_WUSB_MAS_LEN, - &blk, 0, - &completion_reason, &cb_flags, 0); - - if (rval != USB_SUCCESS) { - USB_DPRINTF_L2(PRINT_MASK_HCDI, hwahcp->hwahc_log_handle, - "Set_WUSB_MAS fails: rval=%d cr=%d cb=0x%x", - rval, completion_reason, cb_flags); - } - freemsg(blk); - - return (rval); -} - -/* 8.5.3.1 - Add MMC IE */ -int -hwahc_add_mmc_ie(dev_info_t *dip, uint8_t interval, uint8_t rcnt, - uint8_t iehdl, uint16_t len, uint8_t *data) -{ - usb_cr_t completion_reason; - usb_cb_flags_t cb_flags; - mblk_t *blk; - int i, rval; - hwahc_state_t *hwahcp; - - if (dip == NULL) { - - return (USB_INVALID_ARGS); - } - - hwahcp = ddi_get_soft_state(hwahc_statep, ddi_get_instance(dip)); - if (hwahcp == NULL) { - - return (USB_INVALID_ARGS); - } - - blk = allocb_wait(len, BPRI_LO, STR_NOSIG, NULL); - - for (i = 0; i < len; i++) { - *blk->b_wptr++ = data[i]; - } - - rval = usb_pipe_sync_ctrl_xfer(dip, hwahcp->hwahc_default_pipe, - WUSB_CLASS_IF_REQ_OUT_TYPE, - HWA_REQ_ADD_MMC_IE, - (interval << 8) | rcnt, - (iehdl << 8) | hwahcp->hwahc_wa_data.wa_ifno, - len, - &blk, 0, - &completion_reason, &cb_flags, 0); - - if (rval != USB_SUCCESS) { - USB_DPRINTF_L2(PRINT_MASK_HCDI, hwahcp->hwahc_log_handle, - "Add_MMC_IE fails: rval=%d cr=%d cb=0x%x", - rval, completion_reason, cb_flags); - } - - freemsg(blk); - - return (rval); -} - -/* 8.5.3.5 - Remove MMC IE */ -int -hwahc_remove_mmc_ie(dev_info_t *dip, uint8_t iehdl) -{ - usb_cr_t completion_reason; - usb_cb_flags_t cb_flags; - int rval; - hwahc_state_t *hwahcp; - - if (dip == NULL) { - - return (USB_INVALID_ARGS); - } - - hwahcp = ddi_get_soft_state(hwahc_statep, ddi_get_instance(dip)); - if (hwahcp == NULL) { - return (USB_INVALID_ARGS); - } - - rval = usb_pipe_sync_ctrl_xfer(dip, hwahcp->hwahc_default_pipe, - WUSB_CLASS_IF_REQ_OUT_TYPE, - HWA_REQ_REMOVE_MMC_IE, - 0, - (iehdl << 8) | hwahcp->hwahc_wa_data.wa_ifno, - 0, - NULL, 0, - &completion_reason, &cb_flags, 0); - - if (rval != USB_SUCCESS) { - USB_DPRINTF_L2(PRINT_MASK_HCDI, hwahcp->hwahc_log_handle, - "Remove_MMC_IE fails: rval=%d cr=%d cb=0x%x", - rval, completion_reason, cb_flags); - } - - return (rval); -} - -/* 8.5.3.14 - WUSB Channel Stop */ -int -hwahc_stop_ch(dev_info_t *dip, uint32_t timeoff) -{ - int rval; - usb_cr_t completion_reason; - usb_cb_flags_t cb_flags; - hwahc_state_t *hwahcp; - - if (dip == NULL) { - - return (USB_INVALID_ARGS); - } - - hwahcp = ddi_get_soft_state(hwahc_statep, ddi_get_instance(dip)); - if (hwahcp == NULL) { - - return (USB_INVALID_ARGS); - } - - rval = usb_pipe_sync_ctrl_xfer(dip, hwahcp->hwahc_default_pipe, - WUSB_CLASS_IF_REQ_OUT_TYPE, - HWA_REQ_CH_STOP, - timeoff & 0x00ffffff, - hwahcp->hwahc_wa_data.wa_ifno, - 0, - NULL, 0, - &completion_reason, &cb_flags, 0); - - if (rval != USB_SUCCESS) { - USB_DPRINTF_L2(PRINT_MASK_HCDI, hwahcp->hwahc_log_handle, - "WUSB_Ch_Stop fails: rval=%d cr=%d cb=0x%x", - rval, completion_reason, cb_flags); - } - - return (rval); -} - -/* 8.5. 3.10 - Set Num DNTS Slots */ -int -hwahc_set_num_dnts(dev_info_t *dip, uint8_t interval, uint8_t nslots) -{ - usb_cr_t completion_reason; - usb_cb_flags_t cb_flags; - int rval; - hwahc_state_t *hwahcp; - - if (dip == NULL) { - - return (USB_INVALID_ARGS); - } - - hwahcp = ddi_get_soft_state(hwahc_statep, ddi_get_instance(dip)); - if (hwahcp == NULL) { - - return (USB_INVALID_ARGS); - } - - rval = usb_pipe_sync_ctrl_xfer(dip, hwahcp->hwahc_default_pipe, - WUSB_CLASS_IF_REQ_OUT_TYPE, - HWA_REQ_SET_NUM_DNTS, - (interval << 8) | nslots, - hwahcp->hwahc_wa_data.wa_ifno, - 0, - NULL, 0, - &completion_reason, &cb_flags, 0); - - if (rval != USB_SUCCESS) { - USB_DPRINTF_L2(PRINT_MASK_HCDI, hwahcp->hwahc_log_handle, - "Set_Num_DNTS fails: rval=%d cr=%d cb=0x%x", - rval, completion_reason, cb_flags); - } - - return (rval); -} - -/* set encryptiion type for host */ -int -hwahc_set_encrypt(dev_info_t *dip, usb_port_t port, uint8_t type) -{ - hwahc_state_t *hwahcp; - int rval; - - if ((hwahcp = ddi_get_soft_state(hwahc_statep, - ddi_get_instance(dip))) == NULL) { - - return (USB_INVALID_ARGS); - } - /* DEVICE INDEX */ - rval = hwahc_set_dev_encrypt(hwahcp->hwahc_default_pipe, - hwahcp->hwahc_wa_data.wa_ifno, port - 1, - &hwahcp->hwahc_secrt_data, type); - if (rval != USB_SUCCESS) { - USB_DPRINTF_L2(PRINT_MASK_CBOPS, hwahcp->hwahc_log_handle, - "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 - * - * Set group/device key: - * devindex = actual port number - 1, so it is zero based - * - */ -int hwahc_set_keys(hwahc_state_t *hwahcp, usb_key_descr_t *key_descr, - size_t klen, uint8_t devindex, uint8_t keydex, uint8_t flag) -{ - usb_ctrl_setup_t setup; - usb_cr_t cr; - usb_cb_flags_t cb_flags; - mblk_t *pdata; - int rval; - uint8_t keyindex; - - USB_DPRINTF_L4(PRINT_MASK_HCDI, hwahcp->hwahc_log_handle, - "hwahc_set_keys: klen = %d, devindex = %d", (int)klen, - devindex); - - /* Table 7-21 and Errata 2005/07 */ - if (flag == WUSB_GTK) { - if (devindex != 0) { - return (USB_FAILURE); - } - - /* See 7.3.2.4 for key index format */ - keyindex = (1 << 5) | keydex; - } else if (flag == WUSB_PTK) { - - keyindex = keydex; - } else { - - return (USB_FAILURE); - } - - setup.bmRequestType = USB_DEV_REQ_HOST_TO_DEV | - USB_DEV_REQ_TYPE_CLASS | USB_DEV_REQ_RCPT_IF; - setup.bRequest = USB_REQ_SET_DESCR; - setup.wValue = (USB_DESCR_TYPE_KEY << 8) | keyindex; - setup.wIndex = devindex << 8 | hwahcp->hwahc_wa_data.wa_ifno; - setup.wLength = (uint16_t)klen; - setup.attrs = USB_ATTRS_NONE; - - if ((pdata = allocb(klen, BPRI_HI)) == NULL) { - - return (USB_FAILURE); - } - bcopy(key_descr, pdata->b_wptr, klen); - pdata->b_wptr += klen; - - rval = usb_pipe_ctrl_xfer_wait(hwahcp->hwahc_default_pipe, &setup, - &pdata, &cr, &cb_flags, USB_FLAGS_SLEEP); - - if (rval != USB_SUCCESS) { - USB_DPRINTF_L4(PRINT_MASK_HCDI, hwahcp->hwahc_log_handle, - "hwahc_set_keys:fail, rv=%d,cr=%d,cb=%d", rval, cr, - cb_flags); - } - - freemsg(pdata); - - return (rval); -} - -/* set PTK for host */ -int -hwahc_set_ptk(dev_info_t *dip, usb_key_descr_t *key_descr, size_t klen, - usb_port_t port) -{ - hwahc_state_t *hwahcp; - int rval; - uint8_t keyindex = 1; - - if ((hwahcp = ddi_get_soft_state(hwahc_statep, - ddi_get_instance(dip))) == NULL) { - - return (USB_INVALID_ARGS); - } - /* DEVICE INDEX */ - rval = hwahc_set_keys(hwahcp, key_descr, klen, port - 1, keyindex, - WUSB_PTK); - if (rval != USB_SUCCESS) { - USB_DPRINTF_L2(PRINT_MASK_CBOPS, hwahcp->hwahc_log_handle, - "hwahc_set_ptk: set device key descr for port %d " - "failed", port); - } - - return (rval); -} - -/* set GTK for host */ -int -hwahc_set_gtk(dev_info_t *dip, usb_key_descr_t *key_descr, size_t klen) -{ - hwahc_state_t *hwahcp; - int rval; - - if ((hwahcp = ddi_get_soft_state(hwahc_statep, - ddi_get_instance(dip))) == NULL) { - - return (USB_INVALID_ARGS); - } - - rval = hwahc_set_keys(hwahcp, key_descr, klen, 0, 0, WUSB_GTK); - if (rval != USB_SUCCESS) { - USB_DPRINTF_L2(PRINT_MASK_CBOPS, hwahcp->hwahc_log_handle, - "hwahc_set_gtk: set group key descr failed"); - } - - return (rval); -} - -/* - * set device info for host - * Section 8.5.3.7. - */ -int -hwahc_set_device_info(dev_info_t *dip, wusb_dev_info_t *dev_info, - usb_port_t port) -{ - hwahc_state_t *hwahcp; - int rval; - hwa_dev_info_t info; - usb_ctrl_setup_t setup; - usb_cr_t cr; - usb_cb_flags_t cb_flags; - mblk_t *pdata; - - if ((hwahcp = ddi_get_soft_state(hwahc_statep, - ddi_get_instance(dip))) == NULL) { - - return (USB_INVALID_ARGS); - } - - /* the device can use all the host's reserved MASes to communicate */ - (void) memcpy(info.bmDeviceAvailablilityInfo, - hwahcp->hwahc_hc_data.hc_mas, WUSB_SET_WUSB_MAS_LEN); - - info.bDeviceAddress = dev_info->wdev_addr; - - /* To tell HWA device what data rates this child device supports */ - if (dev_info->wdev_uwb_descr == NULL) { - /* bitmap, see7.4.1.1. Must support 53.3/106.7/200 Mbps */ - info.wPHYRates[0] = WUSB_DATA_RATE_BIT_53 | - WUSB_DATA_RATE_BIT_106 | WUSB_DATA_RATE_BIT_200; - info.wPHYRates[1] = 0; - } else { - info.wPHYRates[0] = - dev_info->wdev_uwb_descr->wPHYRates && 0xff; - info.wPHYRates[1] = - (dev_info->wdev_uwb_descr->wPHYRates >> 8) && 0xff; - } - info.bmDeviceAttribute = 0; - - setup.bmRequestType = USB_DEV_REQ_HOST_TO_DEV | - USB_DEV_REQ_TYPE_CLASS | USB_DEV_REQ_RCPT_IF; - setup.bRequest = HWA_REQ_SET_DEVICE_INFO; - setup.wValue = 0; - - /* DEVICE INDEX */ - setup.wIndex = (port - 1) << 8 | hwahcp->hwahc_wa_data.wa_ifno; - setup.wLength = WUSB_SET_DEV_INFO_LEN; - setup.attrs = USB_ATTRS_NONE; - - if ((pdata = allocb(WUSB_SET_DEV_INFO_LEN, BPRI_HI)) == NULL) { - - return (USB_FAILURE); - } - bcopy(&info, pdata->b_wptr, WUSB_SET_DEV_INFO_LEN); - pdata->b_wptr += WUSB_SET_DEV_INFO_LEN; - - rval = usb_pipe_ctrl_xfer_wait(hwahcp->hwahc_default_pipe, &setup, - &pdata, &cr, &cb_flags, USB_FLAGS_SLEEP); - - freemsg(pdata); - - 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 -hwahc_get_time(dev_info_t *dip, uint8_t time_type, - uint16_t len, uint32_t *time) -{ - usb_cr_t completion_reason; - usb_cb_flags_t cb_flags; - mblk_t *blk = NULL; - int rval; - uint8_t *data; - uint16_t length; - hwahc_state_t *hwahcp = NULL; - - if (dip == NULL) { - - return (USB_INVALID_ARGS); - } - - hwahcp = ddi_get_soft_state(hwahc_statep, ddi_get_instance(dip)); - if (hwahcp == NULL) { - - return (USB_INVALID_ARGS); - } - - /* according to WUSB 8.5.3, len is 1 or 3 */ - if ((len != 1) && (len != 3)) { - - return (USB_INVALID_ARGS); - } - - rval = usb_pipe_sync_ctrl_xfer(dip, hwahcp->hwahc_default_pipe, - WUSB_CLASS_IF_REQ_OUT_TYPE, HWA_REQ_GET_TIME, - time_type, hwahcp->hwahc_wa_data.wa_ifno, - len, &blk, 0, &completion_reason, &cb_flags, 0); - - if (rval != USB_SUCCESS) { - freemsg(blk); - - USB_DPRINTF_L2(PRINT_MASK_HCDI, hwahcp->hwahc_log_handle, - "Get_Time fails: rval=%d cr=%d cb=0x%x", - rval, completion_reason, cb_flags); - - return (rval); - } else if (blk == NULL) { - USB_DPRINTF_L2(PRINT_MASK_HCDI, hwahcp->hwahc_log_handle, - "Get_Time returns null data"); - - return (USB_FAILURE); - } else { - length = MBLKL(blk); - - if (length < len) { - freemsg(blk); - - USB_DPRINTF_L2(PRINT_MASK_HCDI, - hwahcp->hwahc_log_handle, - "Get_Time returns short length %d", length); - - return (USB_FAILURE); - } - - data = blk->b_rptr; - if (len == 1) { - *time = *data; - } else { - *time = (data[2] << 16) | (data[1] << 8) | data[0]; - } - freemsg(blk); - - return (USB_SUCCESS); - } -} diff --git a/usr/src/uts/common/io/usb/usba/hubdi.c b/usr/src/uts/common/io/usb/usba/hubdi.c index 132b27bb16..b9c72d0fe0 100644 --- a/usr/src/uts/common/io/usb/usba/hubdi.c +++ b/usr/src/uts/common/io/usb/usba/hubdi.c @@ -597,11 +597,6 @@ static usb_event_t hubd_events = { /* * hubd_get_soft_state() returns the hubd soft state - * - * WUSB support extends this function to support wire adapter class - * devices. The hubd soft state for the wire adapter class device - * would be stored in usb_root_hubd field of the usba_device structure, - * just as the USB host controller drivers do. */ hubd_t * hubd_get_soft_state(dev_info_t *dip) @@ -611,7 +606,7 @@ hubd_get_soft_state(dev_info_t *dip) return (NULL); } - if (usba_is_root_hub(dip) || usba_is_wa(dip)) { + if (usba_is_root_hub(dip)) { usba_device_t *usba_device = usba_get_usba_device(dip); return (usba_device->usb_root_hubd); @@ -6466,19 +6461,6 @@ hubd_delete_child(hubd_t *hubd, usb_port_t port, uint_t flag, boolean_t retry) rval = usba_destroy_child_devi(child_dip, flag); - if ((rval != USB_SUCCESS) && usba_is_hwa(child_dip)) { - /* - * This is only useful for HWA device node. - * Since hwahc interface must hold hwarc interface - * open until hwahc is detached, the first call to - * ndi_devi_unconfig_one() can only offline hwahc - * driver but not hwarc driver. Need to make a second - * call to ndi_devi_unconfig_one() to make the hwarc - * driver detach. - */ - rval = usba_destroy_child_devi(child_dip, flag); - } - if ((rval == USB_SUCCESS) && (flag & NDI_DEVI_REMOVE)) { /* * if the child was still < DS_INITIALIZED diff --git a/usr/src/uts/common/io/usb/usba/parser.c b/usr/src/uts/common/io/usb/usba/parser.c index 3ca8ba81f7..965113374c 100644 --- a/usr/src/uts/common/io/usb/usba/parser.c +++ b/usr/src/uts/common/io/usb/usba/parser.c @@ -21,6 +21,8 @@ /* * Copyright 2009 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. + * + * Copyright 2014 Garrett D'Amore <garrett@damore.org> */ @@ -621,62 +623,3 @@ usb_parse_CV_ep_descr(uchar_t *buf, /* from GET_DESCRIPTOR(CONFIGURATION) */ return (USB_PARSE_ERROR); } - -size_t -usb_parse_bos_descr(uchar_t *buf, /* from GET_DESCRIPTOR(BOS) */ - size_t buflen, - usb_bos_descr_t *ret_descr, - size_t ret_buf_len) -{ - if ((buf == NULL) || (ret_descr == NULL) || - (buflen < 2) || (buf[1] != USB_DESCR_TYPE_BOS)) { - - return (USB_PARSE_ERROR); - } - - return (usb_parse_data("ccsc", - buf, buflen, ret_descr, ret_buf_len)); -} - -size_t -usb_parse_uwb_bos_descr(uchar_t *buf, /* from GET_DESCRIPTOR(BOS) */ - size_t buflen, - usb_uwb_cap_descr_t *ret_descr, - size_t ret_buf_len) -{ - uchar_t *bufend = buf + buflen; - - if ((buf == NULL) || (ret_descr == NULL)) { - - return (USB_PARSE_ERROR); - } - - while (buf + 3 <= bufend) { - if ((buf[1] == USB_DESCR_TYPE_DEV_CAPABILITY) && - (buf[2] == USB_CAP_TYPE_WUSB)) { - - return (usb_parse_data("ccccsccsc", - buf, _PTRDIFF(bufend, buf), ret_descr, - ret_buf_len)); - } - - INCREMENT_BUF(buf); - } - - return (USB_PARSE_ERROR); -} - -size_t -usb_parse_comp_ep_descr(uchar_t *buf, /* from GET_DESCRIPTOR(CONFIGURATION) */ - size_t buflen, - uint_t if_number, - uint_t alt_if_setting, - uint_t ep_index, - usb_ep_comp_descr_t *ret_descr, - size_t ret_buf_len) -{ - return (usb_parse_CV_ep_descr(buf, buflen, "ccccsscc", - if_number, alt_if_setting, ep_index, - USB_DESCR_TYPE_WIRELESS_EP_COMP, 0, - ret_descr, ret_buf_len)); -} diff --git a/usr/src/uts/common/io/usb/usba/usba.c b/usr/src/uts/common/io/usb/usba/usba.c index 2f2c7e834f..898243abb6 100644 --- a/usr/src/uts/common/io/usb/usba/usba.c +++ b/usr/src/uts/common/io/usb/usba/usba.c @@ -21,6 +21,8 @@ /* * Copyright 2009 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. + * + * Copyright 2014 Garrett D'Amore <garrett@damore.org> */ @@ -119,12 +121,10 @@ _init(void) usba_usbai_register_initialization(); usba_hcdi_initialization(); usba_hubdi_initialization(); - usba_whcdi_initialization(); usba_devdb_initialization(); if ((rval = mod_install(&modlinkage)) != 0) { usba_devdb_destroy(); - usba_whcdi_destroy(); usba_hubdi_destroy(); usba_hcdi_destroy(); usba_usbai_register_destroy(); @@ -142,7 +142,6 @@ _fini() if ((rval = mod_remove(&modlinkage)) == 0) { usba_devdb_destroy(); - usba_whcdi_destroy(); usba_hubdi_destroy(); usba_hcdi_destroy(); usba_usbai_register_destroy(); @@ -641,26 +640,6 @@ usba_free_evdata(usba_evdata_t *evdata) /* - * free wireless usb specific structure - */ -void -usba_free_wireless_data(usba_wireless_data_t *wireless_data) -{ - if (wireless_data == NULL) { - - return; - } - - if (wireless_data->wusb_bos) { - kmem_free(wireless_data->wusb_bos, - wireless_data->wusb_bos_length); - } - - kmem_free(wireless_data, sizeof (usba_wireless_data_t)); -} - - -/* * free usb device structure */ void @@ -788,22 +767,7 @@ usba_free_usba_device(usba_device_t *usba_device) strlen(usba_device->usb_serialno_str) + 1); } - if (usba_device->usb_wireless_data) { - mutex_enter(&usba_device->usb_mutex); - usba_free_wireless_data( - usba_device->usb_wireless_data); - mutex_exit(&usba_device->usb_mutex); - } - - /* - * The device address on the wireless bus is assigned - * by the wireless host controller driver(whci or hwahc), - * not by USBA framework, so skip this for wireless - * USB devices. - */ - if (!usba_device->usb_is_wireless) { - usba_unset_usb_address(usba_device); - } + usba_unset_usb_address(usba_device); } #ifndef __lock_lint @@ -1432,52 +1396,6 @@ usba_is_root_hub(dev_info_t *dip) } /* - * check whether this dip is a wire adapter device - */ -int -usba_is_wa(dev_info_t *dip) -{ - if (dip) { - usba_device_t *usba_device; - - usba_device = usba_get_usba_device(dip); - - return (usba_device->usb_is_wa? 1:0); - } - - return (0); -} - -/* - * check whether this dip is a host wire adapter device node - */ -int -usba_is_hwa(dev_info_t *dip) -{ - dev_info_t *cdip; - - if (dip == NULL) { - - return (0); - } - - if (strcmp(ddi_driver_name(dip), "usb_mid") != 0) { - - return (0); - } - - for (cdip = ddi_get_child(dip); cdip; - cdip = ddi_get_next_sibling(cdip)) { - if (strcmp(ddi_driver_name(cdip), "hwarc") == 0) { - - return (1); - } - } - - return (0); -} - -/* * get and store usba_device pointer in the devi */ usba_device_t * diff --git a/usr/src/uts/common/io/usb/usba/usbai_pipe_mgmt.c b/usr/src/uts/common/io/usb/usba/usbai_pipe_mgmt.c index e4d9c2bac8..9d6f2e1ef9 100644 --- a/usr/src/uts/common/io/usb/usba/usbai_pipe_mgmt.c +++ b/usr/src/uts/common/io/usb/usba/usbai_pipe_mgmt.c @@ -21,6 +21,8 @@ /* * Copyright 2009 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. + * + * Copyright 2014 Garrett D'Amore <garrett@damore.org> */ @@ -523,14 +525,6 @@ usba_init_pipe_handle(dev_info_t *dip, uint16_t maxpktsize; maxpktsize = usba_device->usb_dev_descr->bMaxPacketSize0; - if (usba_device->usb_is_wireless) { - /* - * according to wusb 1.0 spec 4.8.1, the host must - * assume a wMaxPacketSize of 512 for the default - * control pipe of a wusb device - */ - maxpktsize = 0x200; - } USB_DPRINTF_L3(DPRINT_MASK_USBAI, usbai_log_handle, "adjusting max packet size from %d to %d", ph_data->p_ep.wMaxPacketSize, maxpktsize); diff --git a/usr/src/uts/common/io/usb/usba/usbai_register.c b/usr/src/uts/common/io/usb/usba/usbai_register.c index 74a461821e..cc034e0210 100644 --- a/usr/src/uts/common/io/usb/usba/usbai_register.c +++ b/usr/src/uts/common/io/usb/usba/usbai_register.c @@ -21,6 +21,8 @@ /* * Copyright 2009 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. + * + * Copyright 2014 Garrett D'Amore <garrett@damore.org> */ /* @@ -112,14 +114,12 @@ uint_t usbai_register_dump_errlevel = USB_LOG_L2; uint_t usbai_register_errmask = (uint_t)-1; /* Function prototypes */ -static int usba_build_bos(usba_device_t *, usb_client_dev_data_t *); static int usba_build_descr_tree(dev_info_t *, usba_device_t *, usb_client_dev_data_t *); static void usba_process_cfg_descr(usba_reg_state_t *); static int usba_process_if_descr(usba_reg_state_t *, boolean_t *); static int usba_process_ep_descr(usba_reg_state_t *); static int usba_process_cv_descr(usba_reg_state_t *); -static int usba_process_ep_comp_descr(usba_reg_state_t *); static int usba_set_parse_values(dev_info_t *dip, usba_device_t *usba_device, usba_reg_state_t *state); static void* usba_kmem_realloc(void *, int, int); @@ -427,16 +427,6 @@ usb_get_dev_data(dev_info_t *dip, return (USB_FAILURE); } - /* get parsed bos for wusb device */ - if (usba_device->usb_is_wireless) { - if ((rval = usba_build_bos(usba_device, usb_reg)) != - USB_SUCCESS) { - kmem_free(usb_reg, sizeof (usb_client_dev_data_t)); - - return (rval); - } - } - usb_reg->dev_iblock_cookie = usba_hcdi_get_hcdi( usba_device->usb_root_hub_dip)->hcdi_soft_iblock_cookie; @@ -595,10 +585,6 @@ usb_free_dev_data(dev_info_t *dip, usb_client_dev_data_t *reg) usb_free_descr_tree(dip, reg); } - if (reg->dev_bos != NULL) { - kmem_free(reg->dev_bos, sizeof (usb_bos_data_t)); - } - mutex_enter(&usba_device->usb_mutex); prev = &usba_device->usb_client_dev_data_list; entry = usba_device->usb_client_dev_data_list.cddl_next; @@ -647,40 +633,6 @@ usb_free_dev_data(dev_info_t *dip, usb_client_dev_data_t *reg) } /* - * This builds the BOS descriptors for WUSB device - */ -static int -usba_build_bos(usba_device_t *usba_device, usb_client_dev_data_t *usb_reg) -{ - uint8_t *buf; - size_t size, buflen; - - buf = usba_device->usb_wireless_data->wusb_bos; - buflen = usba_device->usb_wireless_data->wusb_bos_length; - - usb_reg->dev_bos = kmem_zalloc(sizeof (usb_bos_data_t), - KM_SLEEP); - size = usb_parse_bos_descr(buf, buflen, &usb_reg->dev_bos->bos_descr, - sizeof (usb_bos_descr_t)); - if (size != USB_BOS_DESCR_SIZE) { - kmem_free(usb_reg->dev_bos, sizeof (usb_bos_data_t)); - - return (USB_FAILURE); - } - - size = usb_parse_uwb_bos_descr(buf, buflen, - &usb_reg->dev_bos->bos_uwb_cap, sizeof (usb_uwb_cap_descr_t)); - if (size != USB_UWB_CAP_DESCR_SIZE) { - kmem_free(usb_reg->dev_bos, sizeof (usb_bos_data_t)); - - return (USB_FAILURE); - } - - return (USB_SUCCESS); -} - - -/* * usba_build_descr_tree: * This builds the descriptor tree. See module header comment for tree * description. @@ -847,18 +799,6 @@ usba_build_descr_tree(dev_info_t *dip, usba_device_t *usba_device, } break; - case USB_DESCR_TYPE_WIRELESS_EP_COMP: - /* for WUSB devices */ - if (process_this_if_tree && - state.st_build_ep_comp) { - if (usba_process_ep_comp_descr( - &state) != USB_SUCCESS) { - - return (USB_FAILURE); - } - } - - break; case USB_DESCR_TYPE_STRING: USB_DPRINTF_L2(DPRINT_MASK_ALL, usbai_reg_log_handle, @@ -1107,30 +1047,6 @@ usba_process_ep_descr(usba_reg_state_t *state) } -static int -usba_process_ep_comp_descr(usba_reg_state_t *state) -{ - USB_DPRINTF_L4(DPRINT_MASK_REGISTER, usbai_reg_log_handle, - "usba_process_ep_comp_descr starting"); - - /* No endpoint descr preceeds this descr */ - if (state->st_curr_ep == NULL) { - USB_DPRINTF_L2(DPRINT_MASK_REGISTER, usbai_reg_log_handle, - "usba_process_ep_comp_descr: no endpt before the descr"); - - return (USB_FAILURE); - } - - (void) usb_parse_data("ccccsscc", state->st_curr_raw_descr, - state->st_curr_raw_descr_len, - &state->st_curr_ep->ep_comp_descr, - sizeof (usb_ep_comp_descr_t)); - USB_DPRINTF_L4(DPRINT_MASK_REGISTER, usbai_reg_log_handle, - "usba_process_ep_comp_descr done"); - - return (USB_SUCCESS); -} - /* * usba_process_cv_descr: * This processes a raw endpoint descriptor, and sets up an analogous @@ -1227,7 +1143,6 @@ usba_set_parse_values(dev_info_t *dip, usba_device_t *usba_device, /* Default to *all* in case configuration# prop not set. */ mutex_enter(&usba_device->usb_mutex); state->st_cfg_to_build = usba_device->usb_active_cfg_ndx; - state->st_build_ep_comp = usba_device->usb_is_wireless; mutex_exit(&usba_device->usb_mutex); if (state->st_cfg_to_build == USBA_DEV_CONFIG_INDEX_UNDEFINED) { state->st_cfg_to_build = USBA_ALL; diff --git a/usr/src/uts/common/io/usb/usba/wa.c b/usr/src/uts/common/io/usb/usba/wa.c deleted file mode 100644 index 24da7f7ced..0000000000 --- a/usr/src/uts/common/io/usb/usba/wa.c +++ /dev/null @@ -1,3684 +0,0 @@ -/* - * 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 - * or http://www.opensolaris.org/os/licensing. - * 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. - */ - -/* - * Wire Adapter Operations - * Both DWA and HWA have the same kind of functional components, the - * Wire Adapter. Functions defined in this file are to handle WA's - * class specific Descriptors, Requests, Notifications and Transfers. - * DWA or HWA specific descriptors, requests are not handled here. - */ - -#include <sys/usb/hwa/hwahc/hwahc.h> -#include <sys/usb/hwa/hwahc/hwahc_util.h> -#include <sys/usb/usba/wa.h> -#include <sys/usb/usba/wusba.h> -#include <sys/usb/usba/whcdi.h> -#include <sys/usb/usba.h> -#include <sys/usb/usba/usba_impl.h> -#include <sys/usb/usba/usba_devdb.h> /* usba_devdb_refresh */ -#include <sys/usb/hubd/hubdvar.h> -#include <sys/usb/hubd/hubd_impl.h> /* hubd_ioctl_data_t */ -#include <sys/strsubr.h> /* allocb_wait */ -#include <sys/strsun.h> /* MBLKL macro */ - -extern usb_log_handle_t whcdi_log_handle; - -/* default rpipe PHY transfer speed */ -static uint8_t rp_default_speed = WUSB_PHY_TX_RATE_106; - -/* function prototypes */ -static void wusb_wa_remove_wr_from_timeout_list(wusb_wa_rpipe_hdl_t *hdl, - wusb_wa_trans_wrapper_t *tw); -static void wusb_wa_handle_error(wusb_wa_data_t *wa_data, - wusb_wa_trans_wrapper_t *wr, usb_cr_t cr); - -/* - * Parse Wire Adapter class desriptor. - * - see 8.4.3.7 & 8.5.2.7 - * - * wa_descr - the parsed descriptors. - * altif_data - the passed in raw descriptor data. - */ -int -wusb_parse_wa_descr(usb_wa_descr_t *wa_descr, usb_alt_if_data_t *altif_data) -{ - usb_cvs_data_t *cvs_data; - int i; - size_t count; - - if ((wa_descr == NULL) || (altif_data == NULL)) { - return (USB_INVALID_ARGS); - } - - for (i = 0; i < altif_data->altif_n_cvs; i++) { - cvs_data = &altif_data->altif_cvs[i]; - if (cvs_data->cvs_buf == NULL) { - continue; - } - if (cvs_data->cvs_buf[1] == USB_DESCR_TYPE_WA) { - count = usb_parse_data("ccsccsscccc", - cvs_data->cvs_buf, cvs_data->cvs_buf_len, - (void *)wa_descr, - (size_t)USB_WA_DESCR_SIZE); - if (count != USB_WA_DESCR_SIZE) { - return (USB_FAILURE); - } else { - return (USB_SUCCESS); - } - } - } - - return (USB_FAILURE); -} - -/* initialize rpipe structures */ -void -wusb_wa_rpipes_init(wusb_wa_data_t *wa_data) -{ - int i; - wusb_wa_rpipe_hdl_t *hdl; - - for (i = 0; i < wa_data->wa_num_rpipes; i++) { - hdl = &wa_data->wa_rpipe_hdl[i]; - mutex_init(&hdl->rp_mutex, NULL, MUTEX_DRIVER, NULL); - cv_init(&hdl->rp_cv, NULL, CV_DRIVER, NULL); - - _NOTE(NOW_INVISIBLE_TO_OTHER_THREADS(*hdl)); - hdl->rp_state = WA_RPIPE_STATE_FREE; - hdl->rp_refcnt = 0; - hdl->rp_timeout_list = NULL; - _NOTE(NOW_VISIBLE_TO_OTHER_THREADS(*hdl)); - } -} - -/* deinitialize rpipe structures */ -void -wusb_wa_rpipes_fini(wusb_wa_data_t *wa_data) -{ - int i; - wusb_wa_rpipe_hdl_t *hdl; - - for (i = 0; i < wa_data->wa_num_rpipes; i++) { - hdl = &wa_data->wa_rpipe_hdl[i]; - mutex_destroy(&hdl->rp_mutex); - cv_destroy(&hdl->rp_cv); - } -} - - -/* - * wusb_wa_data_init: - * WA interface validation - * Parse WA class descriptors - * Set up RPipes - * Set up callbacks - */ -int -wusb_wa_data_init(dev_info_t *dip, wusb_wa_data_t *wa_data, wusb_wa_cb_t *cbs, - usb_client_dev_data_t *dev_data, - uint_t mask, usb_log_handle_t handle) -{ - usb_alt_if_data_t *altif_data; - usb_ep_data_t *ep_data; - int ifno; - int rval; - - if ((wa_data == NULL) || (dev_data == NULL)) { - - return (USB_INVALID_ARGS); - } - - _NOTE(NOW_INVISIBLE_TO_OTHER_THREADS(*wa_data)); - - /* get inf descr and ept descrs from altif data */ - altif_data = &dev_data->dev_curr_cfg-> - cfg_if[dev_data->dev_curr_if].if_alt[0]; - - /* T.8-44. Wire Adapter */ - if (altif_data->altif_descr.bInterfaceSubClass != - USB_SUBCLS_WUSB_2) { - USB_DPRINTF_L2(mask, handle, - "wusb_init_wa_data: invalid interface subclass (0x%x)", - altif_data->altif_descr.bInterfaceSubClass); - - return (USB_FAILURE); - } - - /* at least 3 EPs, INTR IN + BULK IN + BULK OUT */ - if (altif_data->altif_n_ep < 3) { - USB_DPRINTF_L2(mask, handle, - "wusb_init_wa_data: invalid alt 0 for interface %d", - dev_data->dev_curr_if); - - return (USB_FAILURE); - } - - wa_data->wa_ifno = ifno = dev_data->dev_curr_if; - wa_data->wa_if_descr = altif_data->altif_descr; - - if ((ep_data = usb_lookup_ep_data(dip, dev_data, ifno, 0, 0, - USB_EP_ATTR_BULK, USB_EP_DIR_OUT)) != NULL) { - wa_data->wa_bulkout_ept = ep_data->ep_descr; - } - if ((ep_data = usb_lookup_ep_data(dip, dev_data, ifno, 0, 0, - USB_EP_ATTR_BULK, USB_EP_DIR_IN)) != NULL) { - wa_data->wa_bulkin_ept = ep_data->ep_descr; - } - if ((ep_data = usb_lookup_ep_data(dip, dev_data, ifno, 0, 0, - USB_EP_ATTR_INTR, USB_EP_DIR_IN)) != NULL) { - wa_data->wa_intr_ept = ep_data->ep_descr; - } - - if ((wa_data->wa_bulkout_ept.bLength == 0) || - (wa_data->wa_bulkin_ept.bLength == 0) || - (wa_data->wa_intr_ept.bLength == 0)) { - USB_DPRINTF_L2(mask, handle, - "wusb_init_wa_data: the minimum endpoint set is not " - "supported"); - - return (USB_FAILURE); - } - - /* parse the WA descriptor */ - if ((rval = wusb_parse_wa_descr(&wa_data->wa_descr, altif_data)) != - USB_SUCCESS) { - USB_DPRINTF_L2(mask, handle, - "wusb_init_wa_data: parse wire adapter class descr failed"); - - return (rval); - } - wa_data->wa_avail_blocks = wa_data->wa_descr.wRPipeMaxBlock; - - wa_data->wa_dip = dip; - - /* initialize rpipe handlers */ - wa_data->wa_num_rpipes = wa_data->wa_descr.wNumRPipes; - - wa_data->wa_rpipe_hdl = kmem_zalloc((wa_data->wa_num_rpipes * - sizeof (wusb_wa_rpipe_hdl_t)), KM_SLEEP); - - /* init rpipes */ - wusb_wa_rpipes_init(wa_data); - - /* register callbacks */ - wa_data->pipe_periodic_req = cbs->pipe_periodic_req; - wa_data->intr_cb = cbs->intr_cb; - wa_data->intr_exc_cb = cbs->intr_exc_cb; - wa_data->rpipe_xfer_cb = cbs->rpipe_xfer_cb; - - mutex_init(&wa_data->wa_mutex, NULL, MUTEX_DRIVER, NULL); - - _NOTE(NOW_VISIBLE_TO_OTHER_THREADS(*wa_data)); - - return (USB_SUCCESS); -} - -/* deinitialize data transfer related resources */ -void -wusb_wa_data_fini(wusb_wa_data_t *wa_data) -{ - mutex_enter(&wa_data->wa_mutex); - if (wa_data->wa_rpipe_hdl) { - wusb_wa_rpipes_fini(wa_data); - kmem_free(wa_data->wa_rpipe_hdl, wa_data->wa_num_rpipes * - sizeof (wusb_wa_rpipe_hdl_t)); - } - mutex_exit(&wa_data->wa_mutex); - mutex_destroy(&wa_data->wa_mutex); -} - -void wusb_wa_dump_rpipe_descr(usb_wa_rpipe_descr_t *pd, uint_t mask, - usb_log_handle_t handle) -{ - USB_DPRINTF_L4(mask, handle, "RPipe Descriptor:\n" - "\tWRPipeIndex=%d wRequests=%d wBlocks=%d\n" - "\twMaxPacketSize=%d bHSHubAddress=%d\n" - "\tbHSHubPort=%d bSpeed=%d bDeviceAddress=%d\n" - "\tbEndpointAddress=0x%02x bDataSequence=%d\n" - "\tdwCurrentWindow=0x%08x bMaxDataSequence=%d", - pd->wRPipeIndex, pd->wRequests, pd->wBlocks, pd->wMaxPacketSize, - pd->wa_value.hwa_value.bMaxBurst, - pd->wa_value.hwa_value.bDeviceInfoIndex, - pd->bSpeed, pd->bDeviceAddress, - pd->bEndpointAddress, pd->bDataSequence, pd->dwCurrentWindow, - pd->bMaxDataSequence); - - USB_DPRINTF_L4(mask, handle, - "(cont'ed)bInterval=%d bOverTheAirInterval=%d\n" - "\tbmAttribute=0x%02x bmCharacter=0x%02x\n" - "\tbmRetryOptions=0x%02x wNumTransactionErrors=%d\n", - pd->bInterval, pd->bOverTheAirInterval, - pd->bmAttribute, pd->bmCharacteristics, pd->bmRetryOptions, - pd->wNumTransactionErrors); - -} - -/* get rpipe descr of a certain index, refer to WUSB 1.0/8.3.1.4 */ -int -wusb_wa_get_rpipe_descr(dev_info_t *dip, usb_pipe_handle_t ph, - uint16_t idx, usb_wa_rpipe_descr_t *descr, - uint_t mask, usb_log_handle_t handle) -{ - mblk_t *data = NULL; - usb_cr_t completion_reason; - usb_cb_flags_t cb_flags; - size_t count; - int rval; - - /* - * This descriptor is critical for later operations to succeed. - * So, we must wait here. - */ - rval = usb_pipe_sync_ctrl_xfer(dip, ph, - WA_CLASS_RPIPE_REQ_IN_TYPE, - USB_REQ_GET_DESCR, - USB_DESCR_TYPE_RPIPE << 8, - idx, - USB_RPIPE_DESCR_SIZE, - &data, 0, - &completion_reason, &cb_flags, 0); - - if (rval != USB_SUCCESS) { - USB_DPRINTF_L2(mask, handle, - "wusb_wa_get_rpipe_descr: rval=%d, cr=%d, " - "cb=0x%x", rval, completion_reason, cb_flags); - - goto done; - } - - if (MBLKL(data) != USB_RPIPE_DESCR_SIZE) { - USB_DPRINTF_L2(mask, handle, - "wusb_wa_get_rpipe_descr: return size %d", - (int)MBLKL(data)); - rval = USB_FAILURE; - - goto done; - } - - count = usb_parse_data("2c4s6cl6cs", data->b_rptr, - USB_RPIPE_DESCR_SIZE, descr, sizeof (usb_wa_rpipe_descr_t)); - - if (count == USB_PARSE_ERROR) { - USB_DPRINTF_L2(mask, handle, - "wusb_wa_get_rpipe_descr: parse error"); - rval = USB_FAILURE; - - goto done; - } - - wusb_wa_dump_rpipe_descr(descr, mask, handle); - - freemsg(data); - data = NULL; - - return (USB_SUCCESS); - -done: - if (data) { - freemsg(data); - } - - return (rval); -} - -/* - * Get All the RPipes' descriptors of an HWA - * - WA RPipe descriptor are not returned as part of the - * cofiguration descriptor. We have to get it separately. - * - See section 8.4.3.19 and 8.5.2.11 - */ -int -wusb_wa_get_rpipe_descrs(wusb_wa_data_t *wa_data, usb_pipe_handle_t ph, - uint_t mask, usb_log_handle_t handle) -{ - dev_info_t *dip = wa_data->wa_dip; - int i, rval; - - if ((dip == NULL) || (ph == NULL)) { - - return (USB_INVALID_ARGS); - } - - /* called at initialization, no other threads yet */ - _NOTE(NOW_INVISIBLE_TO_OTHER_THREADS(*wa_data)); - - for (i = 0; i < wa_data->wa_num_rpipes; i++) { - rval = wusb_wa_get_rpipe_descr(dip, ph, i, - &wa_data->wa_rpipe_hdl[i].rp_descr, mask, handle); - - if (rval != USB_SUCCESS) { - USB_DPRINTF_L2(mask, handle, - "wusb_wa_get_rpipe_descrs: fail to get rpipe " - "descr for idx %d", i); - - return (rval); - } - } - _NOTE(NOW_VISIBLE_TO_OTHER_THREADS(*wa_data)); - - return (USB_SUCCESS); -} - -/* - * Get Wire Adapter's Status - * See section 8.3.1.6 - */ -int -wusb_get_wa_status(wusb_wa_data_t *wa_data, usb_pipe_handle_t ph, - uint32_t *status) -{ - dev_info_t *dip = wa_data->wa_dip; - int rval = USB_SUCCESS; - mblk_t *data = NULL; - usb_cr_t completion_reason; - usb_cb_flags_t cb_flags; - - if ((dip == NULL) || (ph == NULL)) { - - return (USB_INVALID_ARGS); - } - - rval = usb_pipe_sync_ctrl_xfer(dip, ph, - WUSB_CLASS_IF_REQ_IN_TYPE, - USB_REQ_GET_STATUS, - 0, - wa_data->wa_ifno, - WA_GET_WA_STATUS_LEN, - &data, 0, - &completion_reason, &cb_flags, 0); - - if (rval != USB_SUCCESS) { - USB_DPRINTF_L4(DPRINT_MASK_WHCDI, whcdi_log_handle, - "wusb_get_wa_status: can't retrieve status"); - - goto done; - } - - *status = (*(data->b_rptr + 3) << 24) | (*(data->b_rptr + 2) << 16) | - (*(data->b_rptr + 1) << 8) | *(data->b_rptr); - -done: - if (data) { - freemsg(data); - } - - return (rval); -} - -/* - * Reset WA - * See 8.3.1.9 - */ -int -wusb_wa_reset(wusb_wa_data_t *wa_data, usb_pipe_handle_t ph) -{ - dev_info_t *dip = wa_data->wa_dip; - usb_cr_t completion_reason; - usb_cb_flags_t cb_flags; - int rval, i; - uint32_t status; - - if ((dip == NULL) || (ph == NULL)) { - - return (USB_INVALID_ARGS); - } - - rval = usb_pipe_sync_ctrl_xfer(dip, ph, - WUSB_CLASS_IF_REQ_OUT_TYPE, - USB_REQ_SET_FEATURE, - WA_DEV_RESET, - wa_data->wa_ifno, - 0, - NULL, 0, - &completion_reason, &cb_flags, 0); - - if (rval != USB_SUCCESS) { - USB_DPRINTF_L4(DPRINT_MASK_WHCDI, whcdi_log_handle, - "wusb_wa_reset: can't reset wa, rval = %d, cr=%d", rval, - completion_reason); - - return (rval); - } - - for (i = 0; i < 10; i++) { - delay(drv_usectohz(50000)); - - rval = wusb_get_wa_status(wa_data, ph, &status); - if (rval != USB_SUCCESS) { - USB_DPRINTF_L4(DPRINT_MASK_WHCDI, whcdi_log_handle, - "wusb_wa_reset: can't get status, rval = %d", - rval); - - return (rval); - } - - if (!(status & WA_HC_RESET_IN_PROGRESS)) { - - return (USB_SUCCESS); - } - } - - return (USB_FAILURE); -} - -/* - * Enable wire adapter. - * See 8.3.1.9 - */ -int -wusb_wa_enable(wusb_wa_data_t *wa_data, usb_pipe_handle_t ph) -{ - dev_info_t *dip = wa_data->wa_dip; - usb_cr_t completion_reason; - usb_cb_flags_t cb_flags; - int rval, i; - uint32_t status; - - if ((dip == NULL) || (ph == NULL)) { - - return (USB_INVALID_ARGS); - } - - rval = usb_pipe_sync_ctrl_xfer(dip, ph, - WUSB_CLASS_IF_REQ_OUT_TYPE, - USB_REQ_SET_FEATURE, - WA_DEV_ENABLE, - wa_data->wa_ifno, - 0, - NULL, 0, - &completion_reason, &cb_flags, 0); - - if (rval != USB_SUCCESS) { - USB_DPRINTF_L4(DPRINT_MASK_WHCDI, whcdi_log_handle, - "wusb_wa_enable: can't enable WA, rval = %d, cr=%d", - rval, completion_reason); - - return (rval); - } - - for (i = 0; i < 10; i++) { - delay(drv_usectohz(50000)); - - rval = wusb_get_wa_status(wa_data, ph, &status); - if (rval != USB_SUCCESS) { - USB_DPRINTF_L4(DPRINT_MASK_WHCDI, whcdi_log_handle, - "wusb_wa_enable: can't get status, rval = %d", - rval); - - return (rval); - } - - if (status & WA_HC_ENABLED) { - - return (USB_SUCCESS); - } - } - - return (USB_FAILURE); -} - -/* - * Disable WA. Clear a fearture. - * See Section 8.3.1.3 - */ -int -wusb_wa_disable(wusb_wa_data_t *wa_data, usb_pipe_handle_t ph) -{ - dev_info_t *dip = wa_data->wa_dip; - usb_cr_t completion_reason; - usb_cb_flags_t cb_flags; - int rval, i; - uint32_t status; - - if ((dip == NULL) || (ph == NULL)) { - - return (USB_INVALID_ARGS); - } - - rval = usb_pipe_sync_ctrl_xfer(dip, ph, - WUSB_CLASS_IF_REQ_OUT_TYPE, - USB_REQ_CLEAR_FEATURE, - WA_DEV_ENABLE, - wa_data->wa_ifno, - 0, - NULL, 0, - &completion_reason, &cb_flags, 0); - - if (rval != USB_SUCCESS) { - USB_DPRINTF_L4(DPRINT_MASK_WHCDI, whcdi_log_handle, - "wusb_wa_disable: can't disable wa, rval = %d, cr = %d", - rval, completion_reason); - - return (rval); - } - - for (i = 0; i < 10; i++) { - delay(drv_usectohz(50000)); - - rval = wusb_get_wa_status(wa_data, ph, &status); - if (rval != USB_SUCCESS) { - USB_DPRINTF_L4(DPRINT_MASK_WHCDI, whcdi_log_handle, - "wusb_wa_disable: can't get status, rval = %d", - rval); - - return (rval); - } - - if (!(status & WA_HC_ENABLED)) { - - return (USB_SUCCESS); - } - } - - return (USB_FAILURE); -} - -/* - * Open the two bulk endpoints and one interrupt IN endpoint, defined in - * a WA's data transfer interface. See 8.1.2 - */ -int -wusb_wa_open_pipes(wusb_wa_data_t *wa_data) -{ - int rval; - - mutex_enter(&wa_data->wa_mutex); - if (wa_data->wa_state & WA_PIPES_OPENED) { - mutex_exit(&wa_data->wa_mutex); - - return (USB_SUCCESS); - } - wa_data->wa_pipe_policy.pp_max_async_reqs = 1; - mutex_exit(&wa_data->wa_mutex); - - rval = usb_pipe_open(wa_data->wa_dip, &wa_data->wa_intr_ept, - &wa_data->wa_pipe_policy, USB_FLAGS_SLEEP, - &wa_data->wa_intr_ph); - if (rval != USB_SUCCESS) { - USB_DPRINTF_L2(DPRINT_MASK_WHCDI, whcdi_log_handle, - "wusb_wa_open_pipes: can't open intr pipe, rval = %d", - rval); - - return (rval); - } - - rval = usb_pipe_open(wa_data->wa_dip, &wa_data->wa_bulkin_ept, - &wa_data->wa_pipe_policy, USB_FLAGS_SLEEP, - &wa_data->wa_bulkin_ph); - if (rval != USB_SUCCESS) { - USB_DPRINTF_L2(DPRINT_MASK_WHCDI, whcdi_log_handle, - "wusb_wa_open_pipes: can't open bulkin pipe, rval = %d", - rval); - - usb_pipe_close(wa_data->wa_dip, wa_data->wa_intr_ph, - USB_FLAGS_SLEEP, NULL, NULL); - mutex_enter(&wa_data->wa_mutex); - wa_data->wa_intr_ph = NULL; - mutex_exit(&wa_data->wa_mutex); - - return (rval); - } - - rval = usb_pipe_open(wa_data->wa_dip, &wa_data->wa_bulkout_ept, - &wa_data->wa_pipe_policy, USB_FLAGS_SLEEP, - &wa_data->wa_bulkout_ph); - - if (rval != USB_SUCCESS) { - USB_DPRINTF_L2(DPRINT_MASK_WHCDI, whcdi_log_handle, - "wusb_wa_open_pipes: can't open bulkout pipe, rval = %d", - rval); - - usb_pipe_close(wa_data->wa_dip, wa_data->wa_intr_ph, - USB_FLAGS_SLEEP, NULL, NULL); - usb_pipe_close(wa_data->wa_dip, wa_data->wa_bulkin_ph, - USB_FLAGS_SLEEP, NULL, NULL); - mutex_enter(&wa_data->wa_mutex); - wa_data->wa_intr_ph = NULL; - wa_data->wa_bulkin_ph = NULL; - mutex_exit(&wa_data->wa_mutex); - - return (rval); - } - - mutex_enter(&wa_data->wa_mutex); - /* mark the state stopped until listening is started on the pipes */ - wa_data->wa_intr_pipe_state = WA_PIPE_STOPPED; - wa_data->wa_bulkin_pipe_state = WA_PIPE_STOPPED; - /* no listening on this pipe, just mark it active */ - wa_data->wa_bulkout_pipe_state = WA_PIPE_ACTIVE; - wa_data->wa_state |= WA_PIPES_OPENED; - mutex_exit(&wa_data->wa_mutex); - - return (USB_SUCCESS); -} - -/* - * Close WA's pipes. - */ -void -wusb_wa_close_pipes(wusb_wa_data_t *wa_data) -{ - mutex_enter(&wa_data->wa_mutex); - if ((wa_data->wa_state & WA_PIPES_OPENED) == 0) { - mutex_exit(&wa_data->wa_mutex); - - return; - } - - mutex_exit(&wa_data->wa_mutex); - - usb_pipe_close(wa_data->wa_dip, wa_data->wa_intr_ph, - USB_FLAGS_SLEEP, NULL, NULL); - - if (wa_data->wa_bulkin_ph != NULL) { - usb_pipe_close(wa_data->wa_dip, wa_data->wa_bulkin_ph, - USB_FLAGS_SLEEP, NULL, NULL); - } - - usb_pipe_close(wa_data->wa_dip, wa_data->wa_bulkout_ph, - USB_FLAGS_SLEEP, NULL, NULL); - - mutex_enter(&wa_data->wa_mutex); - wa_data->wa_intr_ph = NULL; - wa_data->wa_bulkin_ph = NULL; - wa_data->wa_bulkout_ph = NULL; - wa_data->wa_intr_pipe_state = WA_PIPE_CLOSED; - wa_data->wa_bulkin_pipe_state = WA_PIPE_CLOSED; - wa_data->wa_bulkout_pipe_state = WA_PIPE_CLOSED; - wa_data->wa_state &= ~WA_PIPES_OPENED; - mutex_exit(&wa_data->wa_mutex); -} - -/* - * start listening for transfer completion notifications or device - * notifications on the notification ept - */ -int -wusb_wa_start_nep(wusb_wa_data_t *wa_data, usb_flags_t flag) -{ - int rval; - usb_intr_req_t *reqp; - - mutex_enter(&wa_data->wa_mutex); - if ((wa_data->wa_intr_ph == NULL) || - (wa_data->wa_intr_pipe_state != WA_PIPE_STOPPED)) { - mutex_exit(&wa_data->wa_mutex); - - return (USB_INVALID_PIPE); - } - - reqp = usb_alloc_intr_req(wa_data->wa_dip, 0, flag); - if (!reqp) { - mutex_exit(&wa_data->wa_mutex); - - return (USB_NO_RESOURCES); - } - - reqp->intr_client_private = (usb_opaque_t)wa_data; - reqp->intr_attributes = USB_ATTRS_SHORT_XFER_OK | - USB_ATTRS_AUTOCLEARING; - reqp->intr_len = wa_data->wa_intr_ept.wMaxPacketSize; - reqp->intr_cb = wa_data->intr_cb; - reqp->intr_exc_cb = wa_data->intr_exc_cb; - mutex_exit(&wa_data->wa_mutex); - - if ((rval = usb_pipe_intr_xfer(wa_data->wa_intr_ph, reqp, - flag)) != USB_SUCCESS) { - USB_DPRINTF_L2(DPRINT_MASK_WHCDI, whcdi_log_handle, - "wusb_wa_start_nep: intr xfer fail, rval = %d", - rval); - - usb_free_intr_req(reqp); - - return (rval); - } - - mutex_enter(&wa_data->wa_mutex); - /* pipe state is active while the listening is on */ - wa_data->wa_intr_pipe_state = WA_PIPE_ACTIVE; - mutex_exit(&wa_data->wa_mutex); - - return (USB_SUCCESS); -} - -/* - * stop the notification ept from listening - */ -void -wusb_wa_stop_nep(wusb_wa_data_t *wa_data) -{ - mutex_enter(&wa_data->wa_mutex); - if ((wa_data->wa_intr_ph == NULL) || - (wa_data->wa_intr_pipe_state != WA_PIPE_ACTIVE)) { - mutex_exit(&wa_data->wa_mutex); - - return; - } - wa_data->wa_intr_pipe_state = WA_PIPE_STOPPED; - mutex_exit(&wa_data->wa_mutex); - /* stop intr in without closing the pipe */ - usb_pipe_stop_intr_polling(wa_data->wa_intr_ph, USB_FLAGS_SLEEP); -} - -/* - * allocate a rpipe for transfers on a pipe - * - Find a free RPipe - * - * For now, one rpipe is associated with only one usba pipe once - * the pipe is opened. In the future, the rpipe needs to be - * multiplexed between asynchronous endpoints - * input: - * type: 0 - ctrl, 1 - isoc, 2 - bulk, 3 - intr - * - */ -/* ARGSUSED */ -int -wusb_wa_get_rpipe(wusb_wa_data_t *wa_data, usb_pipe_handle_t ph, - uint8_t type, wusb_wa_rpipe_hdl_t **hdl, - uint_t mask, usb_log_handle_t handle) -{ - int i; - wusb_wa_rpipe_hdl_t *thdl; - uint8_t rp_type; - uint8_t ep_type = 1 << type; - - *hdl = NULL; - - mutex_enter(&wa_data->wa_mutex); - for (i = 0; i < wa_data->wa_num_rpipes; i++) { - /* find the first unused rpipe */ - thdl = &wa_data->wa_rpipe_hdl[i]; - mutex_enter(&thdl->rp_mutex); - if (thdl->rp_state != WA_RPIPE_STATE_FREE) { - mutex_exit(&thdl->rp_mutex); - - continue; - } - - /* check if the rpipe supports the ept transfer type */ - rp_type = (thdl->rp_descr.bmCharacteristics & - USB_RPIPE_CHA_MASK); - if (rp_type & ep_type) { - thdl->rp_refcnt++; - thdl->rp_state = WA_RPIPE_STATE_IDLE; - thdl->rp_avail_reqs = thdl->rp_descr.wRequests; - *hdl = thdl; - mutex_exit(&thdl->rp_mutex); - mutex_exit(&wa_data->wa_mutex); - - return (USB_SUCCESS); - } - mutex_exit(&thdl->rp_mutex); - } - - USB_DPRINTF_L2(mask, handle, - "wusb_wa_get_rpipe: no matching rpipe is found"); - mutex_exit(&wa_data->wa_mutex); - - return (USB_FAILURE); -} - -/* - * Decrease a RPipe's reference count. - * - if count == 0, mark it as free RPipe. - */ -int -wusb_wa_release_rpipe(wusb_wa_data_t *wa, wusb_wa_rpipe_hdl_t *hdl) -{ - if (hdl == NULL) { - - return (USB_FAILURE); - } - - mutex_enter(&wa->wa_mutex); - mutex_enter(&hdl->rp_mutex); - if (hdl->rp_refcnt == 0) { - mutex_exit(&hdl->rp_mutex); - mutex_exit(&wa->wa_mutex); - - return (USB_FAILURE); - } - - if (--hdl->rp_refcnt == 0) { - hdl->rp_state = WA_RPIPE_STATE_FREE; - } - - if (hdl->rp_block_chg == 1) { - wa->wa_avail_blocks += hdl->rp_descr.wBlocks; - hdl->rp_descr.wBlocks = 0; /* to prevent misadd upon re-call */ - hdl->rp_block_chg = 0; - } - - mutex_exit(&hdl->rp_mutex); - mutex_exit(&wa->wa_mutex); - - return (USB_SUCCESS); -} - -/* - * Set a RPipe's Descriptor and make the rpipe configured - * See section 8.3.1.7 - */ -int -wusb_wa_set_rpipe_descr(dev_info_t *dip, usb_pipe_handle_t ph, - usb_wa_rpipe_descr_t *rp_descr) -{ - mblk_t *data = NULL; - usb_cr_t completion_reason; - usb_cb_flags_t cb_flags; - int rval; - uint8_t *p; - - data = allocb_wait(USB_RPIPE_DESCR_SIZE, BPRI_LO, STR_NOSIG, NULL); - p = data->b_wptr; - p[0] = rp_descr->bLength; - p[1] = rp_descr->bDescriptorType; - p[2] = rp_descr->wRPipeIndex; - p[3] = rp_descr->wRPipeIndex >> 8; - p[4] = rp_descr->wRequests; - p[5] = rp_descr->wRequests >> 8; - p[6] = rp_descr->wBlocks; - p[7] = rp_descr->wBlocks >> 8; - p[8] = rp_descr->wMaxPacketSize; - p[9] = rp_descr->wMaxPacketSize >> 8; - p[10] = rp_descr->wa_value.hwa_value.bMaxBurst; - p[11] = rp_descr->wa_value.hwa_value.bDeviceInfoIndex; - p[12] = rp_descr->bSpeed; - p[13] = rp_descr->bDeviceAddress; - p[14] = rp_descr->bEndpointAddress; - p[15] = rp_descr->bDataSequence; - p[16] = rp_descr->dwCurrentWindow; - p[17] = rp_descr->dwCurrentWindow >> 8; - p[18] = rp_descr->dwCurrentWindow >> 16; - p[19] = rp_descr->dwCurrentWindow >> 24; - p[20] = rp_descr->bMaxDataSequence; - p[21] = rp_descr->bInterval; - p[22] = rp_descr->bOverTheAirInterval; - p[23] = rp_descr->bmAttribute; - p[24] = rp_descr->bmCharacteristics; - p[25] = rp_descr->bmRetryOptions; - p[26] = rp_descr->wNumTransactionErrors; - p[27] = rp_descr->wNumTransactionErrors >> 8; - - USB_DPRINTF_L4(DPRINT_MASK_WHCDI, whcdi_log_handle, - "wusb_wa_set_rpipe_descr: RPipe Descriptors"); - wusb_wa_dump_rpipe_descr(rp_descr, DPRINT_MASK_WHCDI, whcdi_log_handle); - - rval = usb_pipe_sync_ctrl_xfer(dip, ph, - WA_CLASS_RPIPE_REQ_OUT_TYPE, - USB_REQ_SET_DESCR, - USB_DESCR_TYPE_RPIPE << 8, - rp_descr->wRPipeIndex, - USB_RPIPE_DESCR_SIZE, - &data, 0, - &completion_reason, &cb_flags, 0); - - freemsg(data); - - USB_DPRINTF_L4(DPRINT_MASK_WHCDI, whcdi_log_handle, - "wusb_wa_set_rpipe_descr: rval = %d", rval); - - return (rval); -} - -/* ept companion descr for the default ctrl pipe, refer to WUSB 1.0/4.8.1 */ -usb_ep_comp_descr_t ep_comp0 = { - sizeof (usb_ep_comp_descr_t), USB_DESCR_TYPE_WIRELESS_EP_COMP, - 1, 2, -}; - -/* - * Get the Endpoint Companion Descriptor for the pipe - * ph_data - the specified pipe - * ep_comp - the companion descriptor returned - */ -int -wusb_wa_get_ep_comp_descr(usba_pipe_handle_data_t *ph_data, - usb_ep_comp_descr_t *ep_comp) -{ - usb_ep_descr_t *ep = &ph_data->p_ep; - usb_client_dev_data_t *dev_data; - usb_if_data_t *if_data; - usb_alt_if_data_t *altif_data; - usb_ep_data_t *ep_data; - int i, j; - - /* default ctrl endpoint */ - if (ep->bEndpointAddress == 0) { - *ep_comp = ep_comp0; - - return (USB_SUCCESS); - } - - if (usb_get_dev_data(ph_data->p_dip, &dev_data, - USB_PARSE_LVL_IF, 0) != USB_SUCCESS) { - - return (USB_FAILURE); - } - - /* retrieve ept companion descr from the dev data */ - if_data = &dev_data->dev_curr_cfg->cfg_if[dev_data->dev_curr_if]; - for (i = 0; i < if_data->if_n_alt; i++) { - altif_data = &if_data->if_alt[i]; - for (j = 0; j < altif_data->altif_n_ep; j++) { - ep_data = &altif_data->altif_ep[j]; - if (memcmp(&ep_data->ep_descr, ep, - sizeof (usb_ep_descr_t)) == 0) { - *ep_comp = ep_data->ep_comp_descr; - usb_free_dev_data(ph_data->p_dip, dev_data); - - return (USB_SUCCESS); - } - } - } - usb_free_dev_data(ph_data->p_dip, dev_data); - - return (USB_FAILURE); -} - -/* to check if the specified PHY speed is supported by the device */ -int -wusb_wa_is_speed_valid(usba_device_t *ud, uint8_t speed) -{ - usb_uwb_cap_descr_t *uwb_descr = ud->usb_wireless_data->uwb_descr; - uint8_t valid_spd[WUSB_PHY_TX_RATE_RES] = { - WUSB_DATA_RATE_BIT_53, WUSB_DATA_RATE_BIT_106, - WUSB_DATA_RATE_BIT_160, WUSB_DATA_RATE_BIT_200, - WUSB_DATA_RATE_BIT_320, WUSB_DATA_RATE_BIT_400, - WUSB_DATA_RATE_BIT_480, 0 - }; - - if (speed >= WUSB_PHY_TX_RATE_RES) { - - return (0); - } - - /* this speed is not supported by the device */ - if (valid_spd[speed] != (uwb_descr->wPHYRates & valid_spd[speed])) { - - return (0); - } - - return (1); -} - -/* - * Set up a RPipe - * - Associate a RPipe and a pipe handle. Hence, an endpoint has - * RPipe to transfer data. - * - Set this RPipe to bDeviceAddress:bEndpointAddress - * - * wa - wa data - * ph - wa's default control pipe - * ph_data - client driver's usba pipe to be opened - * hdl - RPipe handle - */ -int -wusb_wa_set_rpipe_target(dev_info_t *dip, wusb_wa_data_t *wa, - usb_pipe_handle_t ph, usba_pipe_handle_data_t *ph_data, - wusb_wa_rpipe_hdl_t *hdl) -{ - int rval; - usb_ep_comp_descr_t ep_comp; - usb_ep_descr_t *ep = &ph_data->p_ep; - usba_device_t *usba_device; - uint8_t rp_status; - usb_wa_descr_t *wa_desc = &wa->wa_descr; - uint16_t blockcnt; - uint16_t maxsize; - uint16_t seg_len; - - - USB_DPRINTF_L4(DPRINT_MASK_WHCDI, whcdi_log_handle, - "wusb_wa_set_rpipe_target: ph_data = 0x%p rp_hdl = 0x%p", - (void*)ph_data, (void*)hdl); - - /* Get client device's Endpoint companion descriptor */ - if ((rval = wusb_wa_get_ep_comp_descr(ph_data, &ep_comp)) != - USB_SUCCESS) { - USB_DPRINTF_L2(DPRINT_MASK_WHCDI, whcdi_log_handle, - "wusb_wa_set_rpipe_target: get companion ep descr failed," - " rval = %d", rval); - - return (rval); - } - - /* set the rpipe to unconfigured state */ - if ((rval = wusb_wa_rpipe_reset(dip, ph_data, hdl, 0)) != USB_SUCCESS) { - USB_DPRINTF_L2(DPRINT_MASK_WHCDI, whcdi_log_handle, - "wusb_wa_set_rpipe_target: reset rpipe failed, rval = %d", - rval); - - return (rval); - } - - if ((rval = wusb_wa_get_rpipe_status(dip, ph, - hdl->rp_descr.wRPipeIndex, &rp_status)) != USB_SUCCESS) { - USB_DPRINTF_L2(DPRINT_MASK_WHCDI, whcdi_log_handle, - "wusb_wa_set_rpipe_target: get rpipe status failed, " - "rval = %d", rval); - - return (rval); - } - - if (rp_status & WA_RPIPE_CONFIGURED) { - USB_DPRINTF_L2(DPRINT_MASK_WHCDI, whcdi_log_handle, - "wusb_wa_set_rpipe_target: reset rpipe unsuccessful"); - - return (USB_FAILURE); - } - - mutex_enter(&wa->wa_mutex); - usba_device = usba_get_usba_device(ph_data->p_dip); - - mutex_enter(&hdl->rp_mutex); - - /* should be 0x200 for default ctrl pipe, refer to wusb 1.0/4.8.1 */ - hdl->rp_descr.wMaxPacketSize = ep->wMaxPacketSize; - - /* - * set rpipe descr values - * - * Try to use an average block value first. If it's too small, - * then try to allocate the minimum block size to accomodate one - * packet. If the required number of block is not available, return - * failure. - */ - if (hdl->rp_descr.wBlocks == 0) { - blockcnt = wa_desc->wRPipeMaxBlock/wa_desc->wNumRPipes; - maxsize = 1 << (wa_desc->bRPipeBlockSize - 1); - seg_len = blockcnt * maxsize; - - /* alloc enough blocks to accomodate one packet */ - if (ep->wMaxPacketSize > seg_len) { - blockcnt = (ep->wMaxPacketSize + maxsize -1)/maxsize; - } - - /* WA don't have so many blocks to fulfill this reqirement */ - if (wa->wa_avail_blocks < blockcnt) { - mutex_exit(&hdl->rp_mutex); - mutex_exit(&wa->wa_mutex); - - return (USB_FAILURE); - } - - /* we're satisfied */ - hdl->rp_descr.wBlocks = blockcnt; - hdl->rp_block_chg = 1; /* the wBlocks is changed */ - wa->wa_avail_blocks -= blockcnt; - } - USB_DPRINTF_L4(DPRINT_MASK_WHCDI, whcdi_log_handle, - "wusb_wa_set_rpipe_target: wBlocks=%d, maxblock=%d, numR=%d, av=%d", - hdl->rp_descr.wBlocks, wa_desc->wRPipeMaxBlock, wa_desc->wNumRPipes, - wa->wa_avail_blocks); - - hdl->rp_descr.wa_value.hwa_value.bMaxBurst = ep_comp.bMaxBurst; - - /* - * DEVICE INDEX - * device info index should be zero based, refer - * to WUSB 1.0/8.5.3.7 - */ - hdl->rp_descr.wa_value.hwa_value.bDeviceInfoIndex = - usba_device->usb_port - 1; - - /* - * default ctrl pipe uses PHY base signaling rate - * refer to wusb 1.0/4.8.1 - */ - if (ep->bEndpointAddress == 0) { - hdl->rp_descr.bSpeed = WUSB_PHY_TX_RATE_53; - } else { - if (wusb_wa_is_speed_valid(usba_device, rp_default_speed)) { - hdl->rp_descr.bSpeed = rp_default_speed; - } else { - /* use a must-supported speed */ - hdl->rp_descr.bSpeed = WUSB_PHY_TX_RATE_106; - } - } - hdl->rp_descr.bDeviceAddress = usba_device->usb_addr; - hdl->rp_descr.bEndpointAddress = ep->bEndpointAddress; - hdl->rp_descr.bDataSequence = 0; - hdl->rp_descr.dwCurrentWindow = 1; - hdl->rp_descr.bMaxDataSequence = ep_comp.bMaxSequence - 1; - hdl->rp_descr.bInterval = ep->bInterval; - hdl->rp_descr.bOverTheAirInterval = ep_comp.bOverTheAirInterval; - hdl->rp_descr.bmAttribute = ep->bmAttributes & 0x03; - hdl->rp_descr.bmRetryOptions = 0; /* keep retrying */ - hdl->rp_descr.wNumTransactionErrors = 0; - mutex_exit(&hdl->rp_mutex); - - mutex_exit(&wa->wa_mutex); - - /* set rpipe descr */ - rval = wusb_wa_set_rpipe_descr(dip, ph, &hdl->rp_descr); - if (rval != USB_SUCCESS) { - USB_DPRINTF_L2(DPRINT_MASK_WHCDI, whcdi_log_handle, - "wusb_wa_set_rpipe_target: set rpipe descr failed, " - "rval = %d", rval); - - return (rval); - } - - /* check rpipe status, must be configured and idle */ - if ((rval = wusb_wa_get_rpipe_status(dip, ph, - hdl->rp_descr.wRPipeIndex, &rp_status)) != USB_SUCCESS) { - USB_DPRINTF_L2(DPRINT_MASK_WHCDI, whcdi_log_handle, - "wusb_wa_set_rpipe_target: get rpipe status failed, " - "rval = %d", rval); - - return (rval); - } - - if (rp_status != (WA_RPIPE_CONFIGURED | WA_RPIPE_IDLE)) { - USB_DPRINTF_L2(DPRINT_MASK_WHCDI, whcdi_log_handle, - "wusb_wa_set_rpipe_target: set rpipe descr unsuccessful"); - - return (USB_FAILURE); - } - - return (rval); -} - -/* - * Abort a RPipe - * - See Section 8.3.1.1 - * - Aborts all transfers pending on the given pipe - */ -int -wusb_wa_rpipe_abort(dev_info_t *dip, usb_pipe_handle_t ph, - wusb_wa_rpipe_hdl_t *hdl) -{ - usb_cr_t completion_reason; - usb_cb_flags_t cb_flags; - int rval; - - mutex_enter(&hdl->rp_mutex); - - USB_DPRINTF_L4(DPRINT_MASK_WHCDI, whcdi_log_handle, - "wusb_wa_rpipe_abort: rp_hdl = 0x%p", (void *)hdl); - - /* only abort when there is active transfer */ - if (hdl->rp_state != WA_RPIPE_STATE_ACTIVE) { - mutex_exit(&hdl->rp_mutex); - - return (USB_SUCCESS); - } - - mutex_exit(&hdl->rp_mutex); - rval = usb_pipe_sync_ctrl_xfer(dip, ph, - WA_CLASS_RPIPE_REQ_OUT_TYPE, - WA_REQ_ABORT_RPIPE, - 0, - hdl->rp_descr.wRPipeIndex, - 0, - NULL, 0, - &completion_reason, &cb_flags, 0); - - if (rval != USB_SUCCESS) { - USB_DPRINTF_L2(DPRINT_MASK_WHCDI, whcdi_log_handle, - "wusb_wa_rpipe_abort: abort failed, rval = %d", rval); - - return (rval); - } - - return (USB_SUCCESS); -} - -/* - * Clear status on the remote device's endpoint, specifically clear the - * RPipe's target endpoint sequence number. See 4.5.3, 4.6.4 and Tab.8-49 - * for reference of data sequence. - * - * NOTE AGAIN: - * The device endpoint will not respond to host request if the RPipe is - * reset or re-targeted, while device endpoint is not reset! - */ -void -wusb_wa_clear_dev_ep(usba_pipe_handle_data_t *ph) -{ - uint8_t ept_addr; - - if (ph == NULL) { - return; - } - - ept_addr = ph->p_ep.bEndpointAddress; - - USB_DPRINTF_L4(PRINT_MASK_HCDI, whcdi_log_handle, - "wusb_wa_clear_dev_ep:clear endpoint = 0x%02x", ept_addr); - if (ept_addr != 0) { - /* only clear non-default endpoints */ - (void) usb_clr_feature(ph->p_dip, USB_DEV_REQ_RCPT_EP, 0, - ept_addr, USB_FLAGS_SLEEP, NULL, NULL); - } -} - -/* - * Reset a RPipe - * - Reset a RPipe to a known state - * - Pending transfers must be drained or aborted before this - * operation. - * - See Section 8.3.1.10 - * - * dip - the WA's devinfo - * ph - RPipe's targeted remote device's endpoint pipe. - * hdl - RPipe's handle - * - * flag = 1, reset the RPipe descriptor to its initial state and - * also clear remote device endpoint - * = 0, not reset the RPipe descriptor. Caller should use 0 flag - * if it's the first time to open a pipe, because we don't have - * a valid ph yet before successfully opening a pipe by using - * usb_pipe_open(). - */ -int -wusb_wa_rpipe_reset(dev_info_t *dip, usba_pipe_handle_data_t *ph, - wusb_wa_rpipe_hdl_t *hdl, int flag) -{ - int rval = 0; - usb_cr_t completion_reason; - usb_cb_flags_t cb_flags = 0; - usb_pipe_handle_t default_ph; - - USB_DPRINTF_L4(DPRINT_MASK_WHCDI, whcdi_log_handle, - "wusb_wa_rpipe_reset: rp_hdl = 0x%p, ep=0x%02x, flag = %d", - (void *)hdl, ph->p_ep.bEndpointAddress, flag); - - /* get WA's default pipe */ - default_ph = usba_get_dflt_pipe_handle(dip); - - rval = usb_pipe_sync_ctrl_xfer(dip, default_ph, - WA_CLASS_RPIPE_REQ_OUT_TYPE, - WA_REQ_RESET_RPIPE, - 0, - hdl->rp_descr.wRPipeIndex, - 0, - NULL, 0, - &completion_reason, &cb_flags, 0); - - if (rval != USB_SUCCESS) { - USB_DPRINTF_L2(DPRINT_MASK_WHCDI, whcdi_log_handle, - "wusb_wa_rpipe_reset: reset failed, rval=%d" - " cr=%d cb=0x%02x", - rval, (int)completion_reason, (int)cb_flags); - - return (rval); - } - - if (flag == 0) { - /* do nothing else, just return, the rpipe is unconfigured */ - return (USB_SUCCESS); - } - - USB_DPRINTF_L4(DPRINT_MASK_WHCDI, whcdi_log_handle, - "wusb_wa_rpipe_reset: need to clear dev pipe and reset RP descr"); - - /* set rpipe descr and make the rpipe configured */ - rval = wusb_wa_set_rpipe_descr(dip, default_ph, &hdl->rp_descr); - if (rval != USB_SUCCESS) { - USB_DPRINTF_L2(DPRINT_MASK_WHCDI, whcdi_log_handle, - "wusb_wa_rpipe_reset: set descr failed, rval = %d", rval); - - return (rval); - } - - mutex_enter(&hdl->rp_mutex); - hdl->rp_avail_reqs = hdl->rp_descr.wRequests; - if (hdl->rp_state == WA_RPIPE_STATE_ERROR) { - hdl->rp_state = WA_RPIPE_STATE_IDLE; - } - mutex_exit(&hdl->rp_mutex); - - USB_DPRINTF_L4(DPRINT_MASK_WHCDI, whcdi_log_handle, - "wusb_wa_rpipe_reset: end"); - - return (USB_SUCCESS); -} - -/* get rpipe status, refer to WUSB 1.0/8.3.1.5 */ -int -wusb_wa_get_rpipe_status(dev_info_t *dip, usb_pipe_handle_t ph, uint16_t idx, - uint8_t *status) -{ - mblk_t *data = NULL; - usb_cr_t completion_reason; - usb_cb_flags_t cb_flags; - int rval; - - rval = usb_pipe_sync_ctrl_xfer(dip, ph, - WA_CLASS_RPIPE_REQ_IN_TYPE, - USB_REQ_GET_STATUS, - 0, - idx, - 1, - &data, 0, - &completion_reason, &cb_flags, 0); - - if (rval != USB_SUCCESS) { - USB_DPRINTF_L2(DPRINT_MASK_WHCDI, whcdi_log_handle, - "wusb_wa_get_rpipe_status: fail, rval=%d, cr=%d, " - "cb=0x%x", rval, completion_reason, cb_flags); - } else { - *status = *data->b_rptr; - USB_DPRINTF_L2(DPRINT_MASK_WHCDI, whcdi_log_handle, - "wusb_wa_get_rpipe_status: status = %x", *status); - freemsg(data); - } - - return (rval); -} - -/* - * WA specific operations end - */ - -/* Transfer related routines */ -wusb_wa_trans_wrapper_t * -wusb_wa_alloc_tw(wusb_wa_data_t *wa_data, wusb_wa_rpipe_hdl_t *hdl, - usba_pipe_handle_data_t *ph, uint32_t datalen, usb_flags_t usb_flags) -{ - uint_t seg_count; - uint32_t seg_len, maxpktsize; - wusb_wa_trans_wrapper_t *wr; - - USB_DPRINTF_L4(DPRINT_MASK_WHCDI, whcdi_log_handle, - "wusb_wa_alloc_tw: ph = 0x%p rp_hdl = 0x%p ", - (void*)ph, (void*)hdl); - - mutex_enter(&hdl->rp_mutex); - - /* compute the rpipe buffer size */ - seg_len = hdl->rp_descr.wBlocks * - (1 << (wa_data->wa_descr.bRPipeBlockSize - 1)); - maxpktsize = hdl->rp_descr.wMaxPacketSize; - mutex_exit(&hdl->rp_mutex); - - if (seg_len < maxpktsize) { - USB_DPRINTF_L2(DPRINT_MASK_WHCDI, whcdi_log_handle, - "wusb_wa_alloc_tw: fail, segment len(%d) " - "< wMaxPacketSize(%d) ", seg_len, maxpktsize); - - return (NULL); - } - - /* - * the transfer length for each segment is a multiple of the - * wMaxPacketSize except the last segment, and the length - * cannot exceed the rpipe buffer size - */ - seg_len = (seg_len / maxpktsize) * maxpktsize; - if (datalen) { - seg_count = (datalen + seg_len - 1) / seg_len; - } else { - seg_count = 1; - } - - if (seg_count > WA_MAX_SEG_COUNT) { - USB_DPRINTF_L2(DPRINT_MASK_WHCDI, whcdi_log_handle, - "wusb_wa_alloc_tw: fail, seg count(%d)" - " > Max allowed number(%d) ", seg_count, WA_MAX_SEG_COUNT); - - return (NULL); - } - - if ((wr = kmem_zalloc(sizeof (wusb_wa_trans_wrapper_t), - KM_NOSLEEP)) == NULL) { - - return (NULL); - } - - /* allocation, not visible to other threads */ - _NOTE(NOW_INVISIBLE_TO_OTHER_THREADS(*wr)); - - if ((wr->wr_seg_array = kmem_zalloc(sizeof (wusb_wa_seg_t) * seg_count, - KM_NOSLEEP)) == NULL) { - kmem_free(wr, sizeof (wusb_wa_trans_wrapper_t)); - - return (NULL); - } - - /* assign a unique ID for each transfer */ - wr->wr_id = WA_GET_ID(wr); - if (wr->wr_id == 0) { - kmem_free(wr->wr_seg_array, sizeof (wusb_wa_seg_t) * - seg_count); - kmem_free(wr, sizeof (wusb_wa_trans_wrapper_t)); - - return (NULL); - } - - wr->wr_ph = ph; - wr->wr_rp = hdl; - wr->wr_wa_data = wa_data; - wr->wr_flags = usb_flags; - wr->wr_nsegs = (uint8_t)seg_count; - wr->wr_max_seglen = seg_len; - wr->wr_has_aborted = 0; - - cv_init(&wr->wr_cv, NULL, CV_DRIVER, NULL); - - USB_DPRINTF_L4(DPRINT_MASK_WHCDI, whcdi_log_handle, - "wusb_wa_alloc_tw: wr = 0x%p id = %x nseg = %d", (void*)wr, - wr->wr_id, wr->wr_nsegs); - - return (wr); -} - -/* create transfer wrapper for a ctrl request, return NULL on failure */ -wusb_wa_trans_wrapper_t * -wusb_wa_create_ctrl_wrapper(wusb_wa_data_t *wa_data, wusb_wa_rpipe_hdl_t *hdl, - usba_pipe_handle_data_t *ph, usb_ctrl_req_t *ctrl_reqp, - usb_flags_t usb_flags) -{ - wusb_wa_trans_wrapper_t *wr = NULL; - - USB_DPRINTF_L4(DPRINT_MASK_WHCDI, whcdi_log_handle, - "wusb_wa_create_ctrl_wrapper: ph = 0x%p rp_hdl = 0x%p reqp = 0x%p", - (void *)ph, (void*)hdl, (void *)ctrl_reqp); - - wr = wusb_wa_alloc_tw(wa_data, hdl, ph, ctrl_reqp->ctrl_wLength, - usb_flags); - if (wr == NULL) { - USB_DPRINTF_L2(DPRINT_MASK_WHCDI, whcdi_log_handle, - "wusb_wa_create_ctrl_wrapper: fail to create tw for %p", - (void *)ctrl_reqp); - - return (NULL); - } - - /* not visible to other threads yet */ - _NOTE(NOW_INVISIBLE_TO_OTHER_THREADS(*wr)); - - if (ctrl_reqp->ctrl_bmRequestType & USB_DEV_REQ_DEV_TO_HOST) { - wr->wr_dir = WA_DIR_IN; - } else { - wr->wr_dir = WA_DIR_OUT; - } - - wr->wr_type = WA_XFER_REQ_TYPE_CTRL; - wr->wr_reqp = (usb_opaque_t)ctrl_reqp; - wr->wr_timeout = (ctrl_reqp->ctrl_timeout == 0) ? - WA_RPIPE_DEFAULT_TIMEOUT : ctrl_reqp->ctrl_timeout; - wr->wr_cb = wusb_wa_handle_ctrl; - - USB_DPRINTF_L4(DPRINT_MASK_WHCDI, whcdi_log_handle, - "wusb_wa_create_ctrl_wrapper: wr = 0x%p nseg = %d", (void *)wr, - wr->wr_nsegs); - - _NOTE(NOW_VISIBLE_TO_OTHER_THREADS(*wr)); - - return (wr); -} - -/* - * create transfer wrapper for a bulk request, return NULL on failure - * - split the request into multiple segments - * - every segment is N * wMaxPacketSize - * - segment length <= bRPipeBlockSize * wBlocks - */ -wusb_wa_trans_wrapper_t * -wusb_wa_create_bulk_wrapper(wusb_wa_data_t *wa_data, wusb_wa_rpipe_hdl_t *hdl, - usba_pipe_handle_data_t *ph, usb_bulk_req_t *bulk_reqp, - usb_flags_t usb_flags) -{ - wusb_wa_trans_wrapper_t *wr = NULL; - usb_ep_descr_t *epdt = &ph->p_ep; - - USB_DPRINTF_L4(DPRINT_MASK_WHCDI, whcdi_log_handle, - "wusb_wa_create_bulk_wrapper: ph = 0x%p rp_hdl = 0x%p reqp = 0x%p", - (void *)ph, (void *)hdl, (void *)bulk_reqp); - - wr = wusb_wa_alloc_tw(wa_data, hdl, ph, bulk_reqp->bulk_len, - usb_flags); - if (wr == NULL) { - USB_DPRINTF_L2(DPRINT_MASK_WHCDI, whcdi_log_handle, - "wusb_wa_create_bulk_wrapper: fail to create tw for %p", - (void *)bulk_reqp); - - return (NULL); - } - - /* no locking needed */ - _NOTE(NOW_INVISIBLE_TO_OTHER_THREADS(*wr)); - - if ((epdt->bEndpointAddress & USB_EP_DIR_MASK) == USB_EP_DIR_IN) { - wr->wr_dir = WA_DIR_IN; - } else { - wr->wr_dir = WA_DIR_OUT; - } - - wr->wr_type = WA_XFER_REQ_TYPE_BULK_INTR; - wr->wr_reqp = (usb_opaque_t)bulk_reqp; - wr->wr_timeout = (bulk_reqp->bulk_timeout == 0) ? - WA_RPIPE_DEFAULT_TIMEOUT : bulk_reqp->bulk_timeout; - wr->wr_cb = wusb_wa_handle_bulk; - - USB_DPRINTF_L4(DPRINT_MASK_WHCDI, whcdi_log_handle, - "wusb_wa_create_bulk_wrapper: wr = 0x%p nseg = %d", (void *)wr, - wr->wr_nsegs); - - _NOTE(NOW_VISIBLE_TO_OTHER_THREADS(*wr)); - - return (wr); -} - -/* - * create transfer wrapper for a intr request, return NULL on failure - * - split the request into multiple segments - * - every segment is N * wMaxPacketSize - * - segment length <= bRPipeBlockSize * wBlocks - */ -wusb_wa_trans_wrapper_t * -wusb_wa_create_intr_wrapper(wusb_wa_data_t *wa_data, wusb_wa_rpipe_hdl_t *hdl, - usba_pipe_handle_data_t *ph, usb_intr_req_t *intr_reqp, - usb_flags_t usb_flags) -{ - wusb_wa_trans_wrapper_t *wr; - usb_ep_descr_t *epdt = &ph->p_ep; - uint32_t tw_len; - usb_intr_req_t *curr_intr_reqp; - - USB_DPRINTF_L4(DPRINT_MASK_WHCDI, whcdi_log_handle, - "wusb_wa_create_intr_wrapper: ph = 0x%p rp_hdl = 0x%p reqp = 0x%p", - (void *)ph, (void *)hdl, (void *)intr_reqp); - - if ((ph->p_ep.bEndpointAddress & USB_EP_DIR_MASK) == USB_EP_DIR_IN) { - tw_len = (intr_reqp->intr_len) ? intr_reqp->intr_len : - ph->p_ep.wMaxPacketSize; - - /* duplicate client's intr request */ - curr_intr_reqp = usba_hcdi_dup_intr_req(ph->p_dip, - (usb_intr_req_t *)intr_reqp, tw_len, usb_flags); - if (curr_intr_reqp == NULL) { - USB_DPRINTF_L2(DPRINT_MASK_WHCDI, whcdi_log_handle, - "wusb_wa_create_intr_wrapper: fail to create reqp"); - - return (NULL); - } - - } else { /* OUT */ - tw_len = intr_reqp->intr_len; - curr_intr_reqp = intr_reqp; - } - - wr = wusb_wa_alloc_tw(wa_data, hdl, ph, tw_len, usb_flags); - if (wr == NULL) { - USB_DPRINTF_L2(DPRINT_MASK_WHCDI, whcdi_log_handle, - "wusb_wa_create_bulk_wrapper: fail to create tw for %p", - (void *)intr_reqp); - - return (NULL); - } - - /* no locking needed */ - _NOTE(NOW_INVISIBLE_TO_OTHER_THREADS(*wr)); - - if ((epdt->bEndpointAddress & USB_EP_DIR_MASK) == USB_EP_DIR_IN) { - wr->wr_dir = WA_DIR_IN; - } else { - wr->wr_dir = WA_DIR_OUT; - } - - wr->wr_type = WA_XFER_REQ_TYPE_BULK_INTR; - - wr->wr_reqp = (usb_opaque_t)curr_intr_reqp; - - wr->wr_timeout = (intr_reqp->intr_timeout == 0) ? - WA_RPIPE_DEFAULT_TIMEOUT : intr_reqp->intr_timeout; - wr->wr_cb = wusb_wa_handle_intr; - - USB_DPRINTF_L4(DPRINT_MASK_WHCDI, whcdi_log_handle, - "wusb_wa_create_intr_wrapper: wr = 0x%p nseg = %d", (void *)wr, - wr->wr_nsegs); - - _NOTE(NOW_VISIBLE_TO_OTHER_THREADS(*wr)); - - return (wr); -} - -/* - * Setup the transfer request structure for a segment - * len = transfer request structure length - * - see section 8.3.3.1 and 8.3.3.2 - */ -void -wusb_wa_setup_trans_req(wusb_wa_trans_wrapper_t *wr, wusb_wa_seg_t *seg, - uint8_t len) -{ - mblk_t *data = seg->seg_trans_reqp->bulk_data; - uint8_t *trans_req = data->b_wptr; - - USB_DPRINTF_L4(DPRINT_MASK_WHCDI, whcdi_log_handle, - "wusb_wa_setup_trans_req: wr = 0x%p len = %d segnum = 0x%x", - (void*)wr, len, seg->seg_num); - - bzero(trans_req, len); - trans_req[0] = len; - trans_req[1] = wr->wr_type; - trans_req[2] = wr->wr_rp->rp_descr.wRPipeIndex; - trans_req[3] = wr->wr_rp->rp_descr.wRPipeIndex >> 8; - trans_req[4] = seg->seg_id; /* dwTransferID */ - trans_req[5] = seg->seg_id >> 8; - trans_req[6] = seg->seg_id >> 16; - trans_req[7] = seg->seg_id >> 24; - trans_req[8] = seg->seg_len; - trans_req[9] = seg->seg_len >> 8; - trans_req[10] = seg->seg_len >> 16; - trans_req[11] = seg->seg_len >> 24; - trans_req[12] = seg->seg_num; - - /* - * 8-byte setupdata only for the first segment of a ctrl - * transfer request - */ - if (wr->wr_type == WA_XFER_REQ_TYPE_CTRL) { - usb_ctrl_req_t *ctrl_req = (usb_ctrl_req_t *)wr->wr_reqp; - - /* what is the unsecured flag for ? */ - trans_req[13] = wr->wr_dir | WA_CTRL_SECRT_REGULAR; - if ((seg->seg_num & 0x7f) == 0) { - /* only send baSetupDate on the first segment */ - trans_req[16] = ctrl_req->ctrl_bmRequestType; - trans_req[17] = ctrl_req->ctrl_bRequest; - trans_req[18] = ctrl_req->ctrl_wValue; - trans_req[19] = ctrl_req->ctrl_wValue >> 8; - trans_req[20] = ctrl_req->ctrl_wIndex; - trans_req[21] = ctrl_req->ctrl_wIndex >> 8; - trans_req[22] = ctrl_req->ctrl_wLength; - trans_req[23] = ctrl_req->ctrl_wLength >> 8; - - } - USB_DPRINTF_L4(DPRINT_MASK_WHCDI, whcdi_log_handle, - "wusb_wa_setup_trans_req: Ctrl segment = %02x", - seg->seg_num); - - USB_DPRINTF_L4(DPRINT_MASK_WHCDI, whcdi_log_handle, - "wusb_wa_setup_trans_req: Ctrl Setup Data: " - "%02x %02x %02x %02x %02x %02x %02x %02x", - trans_req[16], trans_req[17], trans_req[18], - trans_req[19], trans_req[20], trans_req[21], - trans_req[22], trans_req[23]); - } - data->b_wptr += len; -} - -/* - * WA bulk pipe callbacks - * wusb_wa_trans_bulk_cb: transfer request stage normal callback - * wusb_wa_trans_bulk_exc_cb: transfer request stage exceptional callback - * - * wusb_wa_data_bulk_cb: transfer data stage normal callback - * wusb_wa_data_bulk_exc_cb: transfer data stage exceptional callback - * - * see WUSB1.0 8.3.3 for details - */ -void -wusb_wa_trans_bulk_cb(usb_pipe_handle_t ph, struct usb_bulk_req *req) -{ - wusb_wa_seg_t *seg = (wusb_wa_seg_t *)req->bulk_client_private; - wusb_wa_trans_wrapper_t *wr = (wusb_wa_trans_wrapper_t *)seg->seg_wr; - - USB_DPRINTF_L4(DPRINT_MASK_WHCDI, whcdi_log_handle, - "wusb_wa_trans_bulk_cb: ph=%p req=0x%p cr=%d", (void*)ph, - (void*)req, req->bulk_completion_reason); - - mutex_enter(&wr->wr_rp->rp_mutex); - - /* callback returned, this seg can be freed */ - seg->seg_trans_req_state = 0; - - cv_signal(&seg->seg_trans_cv); - mutex_exit(&wr->wr_rp->rp_mutex); -} - -void -wusb_wa_trans_bulk_exc_cb(usb_pipe_handle_t ph, struct usb_bulk_req *req) -{ - wusb_wa_seg_t *seg = (wusb_wa_seg_t *)req->bulk_client_private; - wusb_wa_trans_wrapper_t *wr = (wusb_wa_trans_wrapper_t *)seg->seg_wr; - - USB_DPRINTF_L4(DPRINT_MASK_WHCDI, whcdi_log_handle, - "wusb_wa_trans_bulk_exc_cb: ph=%p req=0x%p cr=%d", (void *)ph, - (void *)req, req->bulk_completion_reason); - - mutex_enter(&wr->wr_rp->rp_mutex); - - /* callback returned, this seg can be freed */ - seg->seg_trans_req_state = 0; - - cv_signal(&seg->seg_trans_cv); - mutex_exit(&wr->wr_rp->rp_mutex); -} - -void -wusb_wa_data_bulk_cb(usb_pipe_handle_t ph, struct usb_bulk_req *req) -{ - wusb_wa_seg_t *seg = (wusb_wa_seg_t *)req->bulk_client_private; - wusb_wa_trans_wrapper_t *wr = (wusb_wa_trans_wrapper_t *)seg->seg_wr; - - USB_DPRINTF_L4(DPRINT_MASK_WHCDI, whcdi_log_handle, - "wusb_wa_data_bulk_cb: ph=%p req=0x%p cr=%d", (void *)ph, - (void *)req, req->bulk_completion_reason); - - mutex_enter(&wr->wr_rp->rp_mutex); - - /* callback returned, this seg can be freed */ - seg->seg_data_req_state = 0; - - cv_signal(&seg->seg_data_cv); - mutex_exit(&wr->wr_rp->rp_mutex); -} - -void -wusb_wa_data_bulk_exc_cb(usb_pipe_handle_t ph, struct usb_bulk_req *req) -{ - wusb_wa_seg_t *seg = (wusb_wa_seg_t *)req->bulk_client_private; - wusb_wa_trans_wrapper_t *wr = (wusb_wa_trans_wrapper_t *)seg->seg_wr; - - USB_DPRINTF_L4(DPRINT_MASK_WHCDI, whcdi_log_handle, - "wusb_wa_data_bulk_exc_cb: ph=%p req=0x%p cr=%d", (void *)ph, - (void *)req, req->bulk_completion_reason); - - mutex_enter(&wr->wr_rp->rp_mutex); - - /* callback returned, this seg can be freed */ - seg->seg_data_req_state = 0; - - cv_signal(&seg->seg_data_cv); - mutex_exit(&wr->wr_rp->rp_mutex); -} - -/* - * Setup all the transfer request segments, including the transfer request - * stage and data stage for out transfer. - * len = total size of payload data to transfer - * - for every segment, allocate a new bulk request for Transfer - * Request. Fill the request with the segment and wrapper data. - * - for every segment, allocate a new bulk request for data stage. - * - */ -int -wusb_wa_setup_segs(wusb_wa_data_t *wa_data, wusb_wa_trans_wrapper_t *wr, - uint32_t len, mblk_t *data) -{ - int i, rval; - wusb_wa_seg_t *seg; - usb_bulk_req_t *trans_req, *data_req; - uint8_t trans_req_len; - uint8_t *p; - wusb_wa_rpipe_hdl_t *hdl = NULL; - - USB_DPRINTF_L4(DPRINT_MASK_WHCDI, whcdi_log_handle, - "wusb_wa_setup_segs: wr = 0x%p len = %d data = 0x%p", (void *)wr, - len, (void *)data); - - _NOTE(NOW_INVISIBLE_TO_OTHER_THREADS(*wr)); - - if (wr == NULL) { - USB_DPRINTF_L4(DPRINT_MASK_WHCDI, whcdi_log_handle, - "wusb_wa_setup_segs: invalid wr"); - - return (USB_INVALID_ARGS); - } - - if ((len != 0) && (data != NULL)) { - p = data->b_rptr; - } - - for (i = 0; i < wr->wr_nsegs; i++) { - _NOTE(NOW_INVISIBLE_TO_OTHER_THREADS(*seg)); - - seg = &wr->wr_seg_array[i]; - cv_init(&seg->seg_trans_cv, NULL, CV_DRIVER, NULL); - cv_init(&seg->seg_data_cv, NULL, CV_DRIVER, NULL); - seg->seg_wr = wr; - seg->seg_num = (uint8_t)i; /* 0-based */ - seg->seg_len = wr->wr_max_seglen; - if (i == (wr->wr_nsegs - 1)) { - seg->seg_num |= 0x80; /* last segment */ - seg->seg_len = len; - } else { - len -= seg->seg_len; - } - - /* - * set seg_id, all segs are the same or unique ?? - * now make all segs share the same id - */ - seg->seg_id = wr->wr_id; - - /* alloc transfer request and set values */ - switch (wr->wr_type) { - case WA_XFER_REQ_TYPE_CTRL: - trans_req_len = WA_CTRL_REQ_LEN; - break; - case WA_XFER_REQ_TYPE_BULK_INTR: - trans_req_len = WA_BULK_INTR_REQ_LEN; - - break; - default: - trans_req_len = 0; - break; - } - - if (trans_req_len == 0) { - rval = USB_NOT_SUPPORTED; - USB_DPRINTF_L2(DPRINT_MASK_WHCDI, whcdi_log_handle, - "wusb_wa_setup_segs: trans len error"); - - goto error; - } - - /* alloc transfer request for the ith seg */ - trans_req = usb_alloc_bulk_req(wa_data->wa_dip, - trans_req_len, USB_FLAGS_NOSLEEP); - if (trans_req == NULL) { - rval = USB_NO_RESOURCES; - USB_DPRINTF_L2(DPRINT_MASK_WHCDI, whcdi_log_handle, - "wusb_wa_setup_segs: can't alloc_bulk_req"); - - goto error; - } - - /* setup the ith transfer request */ - trans_req->bulk_len = trans_req_len; - trans_req->bulk_timeout = WA_RPIPE_DEFAULT_TIMEOUT; - trans_req->bulk_attributes = USB_ATTRS_AUTOCLEARING; - trans_req->bulk_cb = wusb_wa_trans_bulk_cb; - trans_req->bulk_exc_cb = wusb_wa_trans_bulk_exc_cb; - trans_req->bulk_client_private = (usb_opaque_t)seg; - - seg->seg_trans_reqp = trans_req; - wusb_wa_setup_trans_req(wr, seg, trans_req_len); - - if (seg->seg_len != 0) { - /* alloc request for data stage */ - data_req = usb_alloc_bulk_req(wa_data->wa_dip, - seg->seg_len, USB_FLAGS_NOSLEEP); - if (data_req == NULL) { - rval = USB_NO_RESOURCES; - USB_DPRINTF_L2(DPRINT_MASK_WHCDI, - whcdi_log_handle, - "wusb_wa_setup_segs: can't alloc_bulk_req" - " for data"); - - goto error; - } - - /* setup the ith data transfer */ - data_req->bulk_len = seg->seg_len; - data_req->bulk_timeout = WA_RPIPE_DEFAULT_TIMEOUT; - data_req->bulk_attributes = USB_ATTRS_AUTOCLEARING; - - data_req->bulk_cb = wusb_wa_data_bulk_cb; - data_req->bulk_exc_cb = wusb_wa_data_bulk_exc_cb; - data_req->bulk_client_private = (usb_opaque_t)seg; - - seg->seg_data_reqp = data_req; - - /* - * Copy data from client driver to bulk request for - * an OUT endpoint. - */ - if (wr->wr_dir == WA_DIR_OUT) { - ASSERT(data != NULL); - /* - * cannot increase data->b_rptr, - * or scsa2usb panic at bulk out - */ - ASSERT((intptr_t)((uintptr_t)data->b_wptr - - (uintptr_t)p) >= seg->seg_len); - bcopy(p, - data_req->bulk_data->b_wptr, - seg->seg_len); - p += seg->seg_len; - - data_req->bulk_data->b_wptr += seg->seg_len; - } - } - - _NOTE(NOW_VISIBLE_TO_OTHER_THREADS(*seg)); - } - - /* zero timeout means to wait infinitely */ - /* - * if this is the first time this WR to be transfered, - * we'll add it to its rpipe handle's timeout queue - */ - if (wr->wr_timeout > 0) { - hdl = wr->wr_rp; - - USB_DPRINTF_L4(DPRINT_MASK_WHCDI, whcdi_log_handle, - "wusb_wa_setup_segs: timeout=%d", wr->wr_timeout); - - mutex_enter(&hdl->rp_mutex); - - /* Add this new wrapper to the head of RPipe's timeout list */ - if (hdl->rp_timeout_list) { - wr->wr_timeout_next = hdl->rp_timeout_list; - } - - hdl->rp_timeout_list = wr; - - _NOTE(NOW_VISIBLE_TO_OTHER_THREADS(*wr)); - - mutex_exit(&hdl->rp_mutex); - } - - return (USB_SUCCESS); - -error: - USB_DPRINTF_L2(DPRINT_MASK_WHCDI, whcdi_log_handle, - "wusb_wa_setup_segs: fail, rval = %d", rval); - - _NOTE(NOW_VISIBLE_TO_OTHER_THREADS(*wr)); - - mutex_enter(&hdl->rp_mutex); - wusb_wa_free_segs(wr); - mutex_exit(&hdl->rp_mutex); - - return (rval); -} - -/* allocate transfer wrapper and setup all transfer segments */ -wusb_wa_trans_wrapper_t * -wusb_wa_alloc_ctrl_resources(wusb_wa_data_t *wa_data, wusb_wa_rpipe_hdl_t *hdl, - usba_pipe_handle_data_t *ph, usb_ctrl_req_t *ctrl_reqp, - usb_flags_t usb_flags) -{ - wusb_wa_trans_wrapper_t *wr; - - wr = wusb_wa_create_ctrl_wrapper(wa_data, hdl, ph, ctrl_reqp, - usb_flags); - - if (wr == NULL) { - USB_DPRINTF_L2(DPRINT_MASK_WHCDI, whcdi_log_handle, - "wusb_wa_alloc_ctrl_resources failed"); - - return (NULL); - } - - if (wusb_wa_setup_segs(wa_data, wr, ctrl_reqp->ctrl_wLength, - ctrl_reqp->ctrl_data) != USB_SUCCESS) { - wusb_wa_free_trans_wrapper(wr); - - USB_DPRINTF_L2(DPRINT_MASK_WHCDI, whcdi_log_handle, - "wusb_wa_alloc_ctrl_resources failed to setup segs"); - - return (NULL); - } - - return (wr); -} - -/* allocate transfer wrapper and setup all transfer segments */ -wusb_wa_trans_wrapper_t * -wusb_wa_alloc_bulk_resources(wusb_wa_data_t *wa_data, wusb_wa_rpipe_hdl_t *hdl, - usba_pipe_handle_data_t *ph, usb_bulk_req_t *bulk_reqp, - usb_flags_t usb_flags) -{ - wusb_wa_trans_wrapper_t *wr; - - wr = wusb_wa_create_bulk_wrapper(wa_data, hdl, ph, bulk_reqp, - usb_flags); - - if (wr == NULL) { - - USB_DPRINTF_L2(DPRINT_MASK_WHCDI, whcdi_log_handle, - "wusb_wa_alloc_bulk_resources: failed to create wr"); - - return (NULL); - } - - if (wusb_wa_setup_segs(wa_data, wr, bulk_reqp->bulk_len, - bulk_reqp->bulk_data) != USB_SUCCESS) { - wusb_wa_free_trans_wrapper(wr); - - USB_DPRINTF_L2(DPRINT_MASK_WHCDI, whcdi_log_handle, - "wusb_wa_alloc_bulk_resources:failed to setup segs"); - return (NULL); - } - - return (wr); -} - -/* - * allocate transfer wrapper and setup all transfer segments - * if it's an IN request, duplicate it. - */ -wusb_wa_trans_wrapper_t * -wusb_wa_alloc_intr_resources(wusb_wa_data_t *wa_data, wusb_wa_rpipe_hdl_t *hdl, - usba_pipe_handle_data_t *ph, usb_intr_req_t *intr_reqp, - usb_flags_t usb_flags) -{ - wusb_wa_trans_wrapper_t *wr; - - wr = wusb_wa_create_intr_wrapper(wa_data, hdl, ph, intr_reqp, - usb_flags); - - if (wr == NULL) { - USB_DPRINTF_L2(DPRINT_MASK_WHCDI, whcdi_log_handle, - "wusb_wa_alloc_intr_resources: failed to create wr"); - - return (NULL); - } - - if (wusb_wa_setup_segs(wa_data, wr, intr_reqp->intr_len, - intr_reqp->intr_data) != USB_SUCCESS) { - wusb_wa_free_trans_wrapper(wr); - - USB_DPRINTF_L2(DPRINT_MASK_WHCDI, whcdi_log_handle, - "wusb_wa_alloc_intr_resources: failed to setup segs"); - - return (NULL); - } - - return (wr); -} - -/* free the bulk request structures for all segments */ -void -wusb_wa_free_segs(wusb_wa_trans_wrapper_t *wr) -{ - int i; - wusb_wa_seg_t *seg; - - ASSERT(mutex_owned(&wr->wr_rp->rp_mutex)); - - USB_DPRINTF_L4(DPRINT_MASK_WHCDI, whcdi_log_handle, - "wusb_wa_free_segs: wr = 0x%p, segs=%p", (void *)wr, - (void *)wr->wr_seg_array); - - if (wr->wr_seg_array == NULL) { - return; - } - - - for (i = 0; i < wr->wr_nsegs; i++) { - seg = &wr->wr_seg_array[i]; - - if (seg->seg_trans_reqp != NULL) { - while (seg->seg_trans_req_state == 1) { - cv_wait(&seg->seg_trans_cv, - &wr->wr_rp->rp_mutex); - } - /* free the bulk req for transfer request */ - usb_free_bulk_req(seg->seg_trans_reqp); - seg->seg_trans_reqp = NULL; - } - - if (seg->seg_data_reqp != NULL) { - while (seg->seg_data_req_state == 1) { - cv_wait(&seg->seg_data_cv, - &wr->wr_rp->rp_mutex); - } - /* free the bulk req for data transfer */ - usb_free_bulk_req(seg->seg_data_reqp); - seg->seg_data_reqp = NULL; - } - - cv_destroy(&seg->seg_trans_cv); - cv_destroy(&seg->seg_data_cv); - } - - kmem_free(wr->wr_seg_array, sizeof (wusb_wa_seg_t) * wr->wr_nsegs); - - wr->wr_seg_array = NULL; - wr->wr_nsegs = 0; -} - -/* free transfer wrapper */ -void -wusb_wa_free_trans_wrapper(wusb_wa_trans_wrapper_t *wr) -{ - wusb_wa_rpipe_hdl_t *hdl = NULL; - - USB_DPRINTF_L4(DPRINT_MASK_WHCDI, whcdi_log_handle, - "wusb_wa_free_trans_wrapper: wr = 0x%p", (void *)wr); - - if (wr == NULL) { - USB_DPRINTF_L4(DPRINT_MASK_WHCDI, whcdi_log_handle, - "wusb_wa_free_trans_wrapper: NULL wrapper"); - return; - } - - hdl = wr->wr_rp; - - mutex_enter(&hdl->rp_mutex); - - wusb_wa_remove_wr_from_timeout_list(hdl, wr); - - if (wr->wr_seg_array != NULL) { - wusb_wa_free_segs(wr); - kmem_free(wr->wr_seg_array, - sizeof (wusb_wa_seg_t) * wr->wr_nsegs); - } - - if (wr->wr_id != 0) { - WA_FREE_ID(wr->wr_id); - } - - cv_destroy(&wr->wr_cv); - - kmem_free(wr, sizeof (wusb_wa_trans_wrapper_t)); - - mutex_exit(&hdl->rp_mutex); -} - -/* abort a transfer, refer to WUSB 1.0/8.3.3.5 */ -void -wusb_wa_abort_req(wusb_wa_data_t *wa_data, wusb_wa_trans_wrapper_t *wr, - uint32_t id) -{ - usb_bulk_req_t *req; - uint8_t *p; - int rval; - - USB_DPRINTF_L4(DPRINT_MASK_WHCDI, whcdi_log_handle, - "wusb_wa_abort_req: wr = 0x%p", (void *)wr); - - req = usb_alloc_bulk_req(wa_data->wa_dip, WA_ABORT_REQ_LEN, - USB_FLAGS_NOSLEEP); - if (req == NULL) { - USB_DPRINTF_L2(DPRINT_MASK_WHCDI, whcdi_log_handle, - "wusb_wa_abort_req: alloc bulk req failed"); - - return; - } - - req->bulk_len = WA_ABORT_REQ_LEN; - req->bulk_timeout = WA_RPIPE_DEFAULT_TIMEOUT; - req->bulk_attributes = USB_ATTRS_AUTOCLEARING; - p = req->bulk_data->b_wptr; - p[0] = WA_ABORT_REQ_LEN; - p[1] = WA_XFER_REQ_TYPE_ABORT; - p[2] = wr->wr_rp->rp_descr.wRPipeIndex; - p[3] = wr->wr_rp->rp_descr.wRPipeIndex >> 8; - p[4] = (uint8_t)id; - p[5] = (uint8_t)(id >> 8); - p[6] = (uint8_t)(id >> 16); - p[7] = (uint8_t)(id >> 24); - req->bulk_data->b_wptr += WA_ABORT_REQ_LEN; - - mutex_exit(&wr->wr_rp->rp_mutex); - rval = usb_pipe_bulk_xfer(wa_data->wa_bulkout_ph, req, - USB_FLAGS_SLEEP); - mutex_enter(&wr->wr_rp->rp_mutex); - if (rval != USB_SUCCESS) { - USB_DPRINTF_L2(DPRINT_MASK_WHCDI, whcdi_log_handle, - "wusb_wa_abort_req: send abort req failed, rval = %d", - rval); - } - usb_free_bulk_req(req); -} - -static void -wusb_wa_remove_wr_from_timeout_list(wusb_wa_rpipe_hdl_t *hdl, - wusb_wa_trans_wrapper_t *tw) -{ - wusb_wa_trans_wrapper_t *prev, *next; - int ret = 0; /* debug only */ - - USB_DPRINTF_L2(DPRINT_MASK_WHCDI, whcdi_log_handle, - "remove_wr_from_timeout_list: %p", (void *)tw); - - if (hdl->rp_timeout_list) { - if (hdl->rp_timeout_list == tw) { - hdl->rp_timeout_list = tw->wr_timeout_next; - tw->wr_timeout_next = NULL; - ret = 1; - } else { - prev = hdl->rp_timeout_list; - next = prev->wr_timeout_next; - - while (next && (next != tw)) { - prev = next; - next = next->wr_timeout_next; - } - - if (next == tw) { - prev->wr_timeout_next = next->wr_timeout_next; - tw->wr_timeout_next = NULL; - ret = 1; - } - } - } - - /* debug only */ - USB_DPRINTF_L4(DPRINT_MASK_WHCDI, whcdi_log_handle, - "remove_wr_from_timeout_list: %p, on the list:%d", - (void *)tw, ret); -} - -/* start timer on a rpipe */ -void -wusb_wa_start_xfer_timer(wusb_wa_rpipe_hdl_t *hdl) -{ - USB_DPRINTF_L4(DPRINT_MASK_WHCDI, whcdi_log_handle, - "wusb_wa_start_xfer_timer: rpipe hdl = 0x%p", (void *)hdl); - - ASSERT(mutex_owned(&hdl->rp_mutex)); - - /* - * wr_timeout is in Seconds - */ - /* - * Start the rpipe's timer only if currently timer is not - * running and if there are transfers on the rpipe. - * The timer will be per rpipe. - * - * The RPipe's timer expires every 1s. When this timer expires, the - * handler gets called and will decrease every pending transfer - * wrapper's timeout value. - */ - if ((!hdl->rp_timer_id) && (hdl->rp_timeout_list)) { - hdl->rp_timer_id = timeout(wusb_wa_xfer_timeout_handler, - (void *)hdl, drv_usectohz(1000000)); - } -} - -/* transfer timeout handler */ -void -wusb_wa_xfer_timeout_handler(void *arg) -{ - wusb_wa_rpipe_hdl_t *hdl = (wusb_wa_rpipe_hdl_t *)arg; - wusb_wa_trans_wrapper_t *wr = NULL; - wusb_wa_trans_wrapper_t *next = NULL; - wusb_wa_data_t *wa_data = NULL; - int rval; - uint8_t rp_status; - wusb_wa_trans_wrapper_t *expire_list = NULL; - - USB_DPRINTF_L4(DPRINT_MASK_WHCDI, whcdi_log_handle, - "wusb_wa_xfer_timeout_handler: rphdl = 0x%p ", (void *)hdl); - - mutex_enter(&hdl->rp_mutex); - - /* - * Check whether still timeout handler is valid. - */ - if (hdl->rp_timer_id != 0) { - - /* Reset the timer id to zero */ - hdl->rp_timer_id = 0; - } else { - mutex_exit(&hdl->rp_mutex); - - return; - } - - /* - * Check each transfer wrapper on this RPipe's timeout queue - * Actually, due to USBA's limitation and queueing, there's only one - * usba_request submitted to HCD at a specific pipe. Hence, only one - * WR can be on this RPipe's list at any moment. - */ - wr = hdl->rp_timeout_list; - while (wr) { - next = wr->wr_timeout_next; - - USB_DPRINTF_L3(DPRINT_MASK_WHCDI, whcdi_log_handle, - "wusb_wa_xfer_timeout_handler: rhdl=0x%p" - " wr=0x%p(to=%d) nxt=0x%p", (void *)hdl, (void *)wr, - wr->wr_timeout, (void *)next); - - /* - * 1 second passed. Decrease every transfer wrapper's - * timeout value. If the timeout < 0 (expired), remove this - * wrapper from the timeout list and put it on the - * expire_list. - */ - wr->wr_timeout--; - if (wr->wr_timeout <= 0) { - USB_DPRINTF_L3(DPRINT_MASK_WHCDI, whcdi_log_handle, - "wusb_wa_xfer_timeout_handler: 0x%p time out", - (void *)wr); - - /* remove it from the rpipe's timeout list */ - wusb_wa_remove_wr_from_timeout_list(hdl, wr); - - /* put it on the expired list */ - wr->wr_timeout_next = expire_list; - expire_list = wr; - - } - - wr = next; - } - - /* Restart this RPipe's timer */ - wusb_wa_start_xfer_timer(hdl); - - /* timeout handling */ - wr = expire_list; - while (wr) { - next = wr->wr_timeout_next; - - /* other thread shouldn't continue processing it */ - wr->wr_state = WR_TIMEOUT; - - wa_data = wr->wr_wa_data; - - mutex_exit(&hdl->rp_mutex); - rval = wusb_wa_get_rpipe_status(wa_data->wa_dip, - wa_data->wa_default_pipe, hdl->rp_descr.wRPipeIndex, - &rp_status); - mutex_enter(&hdl->rp_mutex); - - if (rval != USB_SUCCESS) { - /* reset WA perhaps? */ - hdl->rp_state = WA_RPIPE_STATE_ERROR; - hdl->rp_curr_wr = NULL; - mutex_exit(&hdl->rp_mutex); - wr->wr_cb(wa_data, wr, USB_CR_TIMEOUT, 1); - mutex_enter(&hdl->rp_mutex); - - USB_DPRINTF_L3(DPRINT_MASK_WHCDI, whcdi_log_handle, - "wusb_wa_xfer_timeout_handler: fail to get" - " rpipe status, rval = %d", rval); - - goto continuing; - } - USB_DPRINTF_L3(DPRINT_MASK_WHCDI, whcdi_log_handle, - "wusb_wa_xfer_timeout_handler: rpstat=0x%02x, wr=0x%p," - " wr_state=%d", rp_status, (void *)wr, wr->wr_state); - - if (!(rp_status & WA_RPIPE_IDLE)) { - /* - * If RP is not idle, then it must be processing this WR. - * Abort this request to make the RPipe idle. - */ - USB_DPRINTF_L3(DPRINT_MASK_WHCDI, whcdi_log_handle, - "wusb_wa_xfer_timeout_handler: rp not idle"); - - mutex_exit(&hdl->rp_mutex); - rval = wusb_wa_rpipe_abort(wa_data->wa_dip, - wa_data->wa_default_pipe, hdl); - mutex_enter(&hdl->rp_mutex); - - USB_DPRINTF_L3(DPRINT_MASK_WHCDI, - whcdi_log_handle, - "wusb_wa_xfer_timeout_handler: abort rpipe" - " fail rval = %d", rval); - - if (rval == 0) { - /* - * wait for the result thread to get - * Aborted result. If this wr hasn't been - * aborted, wait it. - */ - if ((wr->wr_has_aborted == 0) && - (cv_reltimedwait(&wr->wr_cv, &hdl->rp_mutex, - drv_usectohz(100 * 1000), TR_CLOCK_TICK) - >= 0)) { - /* 100ms, random number, long enough? */ - - /* the result thread has processed it */ - goto continuing; - } - - USB_DPRINTF_L3(DPRINT_MASK_WHCDI, - whcdi_log_handle, - "wusb_wa_xfer_timeout_handler: result" - " thread can't get the aborted request"); - } - } - - /* - * 1)The Rpipe is idle, OR, - * 2)rpipe_abort fails, OR, - * 3)The result thread hasn't got an aborted result in 100ms, - * most likely the result is lost. We can not depend on WA to - * return result for this aborted request. The WA seems not - * always returning such result. This will cause some hcdi - * ops hang. - */ - hdl->rp_state = WA_RPIPE_STATE_IDLE; - hdl->rp_curr_wr = NULL; - - /* release this WR's occupied req */ - hdl->rp_avail_reqs += (wr->wr_curr_seg - wr->wr_seg_done); - cv_signal(&hdl->rp_cv); - - mutex_exit(&hdl->rp_mutex); - - wr->wr_cb(wa_data, wr, USB_CR_TIMEOUT, 0); - mutex_enter(&hdl->rp_mutex); - -continuing: - wr = next; - } - - mutex_exit(&hdl->rp_mutex); -} - -/* stop timer */ -void -wusb_wa_stop_xfer_timer(wusb_wa_trans_wrapper_t *wr) -{ - wusb_wa_rpipe_hdl_t *hdl = wr->wr_rp; - timeout_id_t timer_id; - - USB_DPRINTF_L4(DPRINT_MASK_WHCDI, whcdi_log_handle, - "wusb_wa_stop_xfer_timer: wr = 0x%p", (void *)wr); - - ASSERT(mutex_owned(&hdl->rp_mutex)); - - if (hdl->rp_timer_id == 0) { - - return; - } - - timer_id = hdl->rp_timer_id; - hdl->rp_timer_id = 0; - mutex_exit(&hdl->rp_mutex); - - (void) untimeout(timer_id); - - mutex_enter(&hdl->rp_mutex); -} - - -/* - * send transfer request and data to the bulk out pipe - * - * General transfer function for WA transfer, see Section 8.3.3. - */ -/* ARGSUSED */ -int -wusb_wa_wr_xfer(wusb_wa_data_t *wa_data, wusb_wa_rpipe_hdl_t *hdl, - wusb_wa_trans_wrapper_t *wr, usb_flags_t usb_flags) -{ - int i, rval; - uint8_t curr_seg; - usb_bulk_req_t *req; - - USB_DPRINTF_L4(DPRINT_MASK_WHCDI, whcdi_log_handle, - "wusb_wa_wr_xfer: wr = 0x%p", (void *)wr); - - ASSERT(wr->wr_seg_array != NULL); - - ASSERT(mutex_owned(&hdl->rp_mutex)); - - if (hdl->rp_state == WA_RPIPE_STATE_IDLE) { - hdl->rp_state = WA_RPIPE_STATE_ACTIVE; - hdl->rp_curr_wr = wr; - } - curr_seg = wr->wr_curr_seg; - - USB_DPRINTF_L3(DPRINT_MASK_WHCDI, whcdi_log_handle, - "wusb_wa_wr_xfer: curr_seg = %d, avail_req = %d", curr_seg, - hdl->rp_avail_reqs); - - /* - * For every segment, - * Step 1: contruct a bulk req containing Transfer - * Request(T8-12 and T8-10) - * Step 2: alloc another bulk req if there's any data - * for OUT endpoints. - * - * For IN endpoints, the data is returned in the - * GetResult thread. - * Just throw as many as maximum available requests to the RPipe. - * If the avail_req is zero, wait! - * - * When a request is finished, the avail_req will be increased - * in the result thread. - */ - for (i = curr_seg; i < wr->wr_nsegs; i++) { - USB_DPRINTF_L3(DPRINT_MASK_WHCDI, whcdi_log_handle, - "wusb_wa_wr_xfer: wr=%p curr_seg = %d, avail_req = %d," - " dir=%s", (void *)wr, curr_seg, hdl->rp_avail_reqs, - (wr->wr_dir == WA_DIR_IN)?"IN":"OUT"); - - /* waiting for available requests if wr is still good */ - while ((hdl->rp_avail_reqs == 0) && (wr->wr_state == 0)) { - rval = cv_wait_sig(&hdl->rp_cv, &hdl->rp_mutex); - } - - if ((wr->wr_curr_seg - wr->wr_seg_done) >= 1) { - /* send only one segment */ - - break; - } - - if (wr->wr_state != 0) { - /* wr transfer error, don't continue */ - USB_DPRINTF_L3(DPRINT_MASK_WHCDI, whcdi_log_handle, - "wusb_wa_wr_xfer: wr_state!=0(%d)", wr->wr_state); - - break; - } - - req = wr->wr_seg_array[i].seg_trans_reqp; - ASSERT(req != NULL); - - mutex_exit(&hdl->rp_mutex); - /* send ith transfer request */ - rval = usb_pipe_bulk_xfer(wa_data->wa_bulkout_ph, req, 0); - mutex_enter(&hdl->rp_mutex); - if (rval != USB_SUCCESS) { - USB_DPRINTF_L2(DPRINT_MASK_WHCDI, whcdi_log_handle, - "wusb_wa_wr_xfer: send transfer request %d failed," - "rv=%d", i, rval); - - wr->wr_seg_array[i].seg_trans_req_state = 0; /* clear */ - - if (i == 0) { - /* no xfer in processing */ - hdl->rp_state = WA_RPIPE_STATE_IDLE; - hdl->rp_curr_wr = NULL; - - return (rval); - } - wusb_wa_abort_req(wa_data, wr, wr->wr_id); - wr->wr_state = WR_SEG_REQ_ERR; /* sending tr error */ - - break; - } - wr->wr_seg_array[i].seg_trans_req_state = 1; /* submitted */ - - USB_DPRINTF_L3(DPRINT_MASK_WHCDI, whcdi_log_handle, - "wusb_wa_wr_xfer: seg(%d) request(0x%p) sent," - " avail_req = %d", i, (void*)req, hdl->rp_avail_reqs); - - hdl->rp_avail_reqs--; - - /* Get data in the GetResult thread for IN eps */ - if (wr->wr_dir == WA_DIR_IN) { - wr->wr_curr_seg++; - - /* only send data for out request */ - continue; - } - - req = wr->wr_seg_array[i].seg_data_reqp; - if (req == NULL) { - /* no data stage */ - wr->wr_curr_seg++; - - continue; - } - - wr->wr_seg_array[i].seg_data_req_state = 1; /* submitted */ - mutex_exit(&hdl->rp_mutex); - /* send ith data asynchronously */ - rval = usb_pipe_bulk_xfer(wa_data->wa_bulkout_ph, req, 0); - mutex_enter(&hdl->rp_mutex); - if (rval != USB_SUCCESS) { - USB_DPRINTF_L2(DPRINT_MASK_WHCDI, whcdi_log_handle, - "wusb_wa_wr_xfer: send transfer data %d failed", - i); - - wr->wr_seg_array[i].seg_data_req_state = 0; /* clear */ - - wusb_wa_abort_req(wa_data, wr, wr->wr_id); - wr->wr_state = WR_SEG_DAT_ERR; /* sending data error */ - - /* not inc rp_avail_reqs until callback */ - - break; - } - - USB_DPRINTF_L3(DPRINT_MASK_WHCDI, whcdi_log_handle, - "wusb_wa_wr_xfer: seg(%d) data(0x%p) sent, avail_req = %d", - i, (void*)req, hdl->rp_avail_reqs); - - wr->wr_curr_seg++; - } - - /* start timer */ - wusb_wa_start_xfer_timer(hdl); - /* - * return success even if the xfer is not complete, the callback - * will only continue sending segs when (wr_error_state = 0 && - * wr_curr_seg < wr_nsegs) - */ - return (USB_SUCCESS); -} - -/* - * submit wr according to rpipe status - * - check RPipe state - * - call general WA transfer function to do transfer - * - * usba only submits one transfer to the host controller per pipe at a time - * and starts next when the previous one completed. So the hwahc now - * assumes one transfer per rpipe at a time. This won't be necessary to - * change unless the usba scheme is changed. - */ -int -wusb_wa_submit_ctrl_wr(wusb_wa_data_t *wa_data, wusb_wa_rpipe_hdl_t *hdl, - wusb_wa_trans_wrapper_t *wr, usb_ctrl_req_t *ctrl_reqp, - usb_flags_t usb_flags) -{ - int rval; - - mutex_enter(&hdl->rp_mutex); - switch (hdl->rp_state) { - case WA_RPIPE_STATE_IDLE: - rval = wusb_wa_wr_xfer(wa_data, hdl, wr, usb_flags); - break; - case WA_RPIPE_STATE_ACTIVE: - /* only allow one req at a time, this should not happen */ - default: - rval = USB_PIPE_ERROR; - break; - } - mutex_exit(&hdl->rp_mutex); - - if (rval != USB_SUCCESS) { - if (ctrl_reqp->ctrl_completion_reason == USB_CR_OK) { - ctrl_reqp->ctrl_completion_reason = usba_rval2cr(rval); - } - mutex_enter(&hdl->rp_mutex); - USB_DPRINTF_L4(DPRINT_MASK_WHCDI, whcdi_log_handle, - "wusb_wa_submit_ctrl_wr:fail, reqp=0x%p, rpstat=%d, rv=%d", - (void*)ctrl_reqp, hdl->rp_state, rval); - - mutex_exit(&hdl->rp_mutex); - - wusb_wa_free_trans_wrapper(wr); - } - - /* In other cases, wr will be freed in callback */ - return (rval); -} - -/* - * Transfer a control request: - * - allocate a transfer wrapper(TW) for this request - * - submit this TW - */ -int -wusb_wa_ctrl_xfer(wusb_wa_data_t *wa_data, wusb_wa_rpipe_hdl_t *hdl, - usba_pipe_handle_data_t *ph, usb_ctrl_req_t *ctrl_reqp, - usb_flags_t usb_flags) -{ - int rval; - wusb_wa_trans_wrapper_t *wr; - - USB_DPRINTF_L4(DPRINT_MASK_WHCDI, whcdi_log_handle, - "wusb_wa_ctrl_xfer: ph = 0x%p reqp = 0x%p", - (void*)ph, (void*)ctrl_reqp); - - wr = wusb_wa_alloc_ctrl_resources(wa_data, hdl, ph, ctrl_reqp, - usb_flags); - if (wr == NULL) { - USB_DPRINTF_L2(DPRINT_MASK_WHCDI, whcdi_log_handle, - "wusb_wa_ctrl_req: alloc ctrl resource failed"); - - return (USB_NO_RESOURCES); - } - - rval = wusb_wa_submit_ctrl_wr(wa_data, hdl, wr, ctrl_reqp, usb_flags); - if (rval != USB_SUCCESS) { - USB_DPRINTF_L2(DPRINT_MASK_WHCDI, whcdi_log_handle, - "wusb_wa_submit_ctrl_wr: submit ctrl req failed, rval = %d", - rval); - } - - return (rval); -} - -/* - * submit wr according to rpipe status - * - * usba only submits one transfer to the host controller per pipe at a time - * and starts next when the previous one completed. So the hwahc now - * assumes one transfer per rpipe at a time. This won't be necessary to - * change unless the usba scheme is changed. - */ -int -wusb_wa_submit_bulk_wr(wusb_wa_data_t *wa_data, wusb_wa_rpipe_hdl_t *hdl, - wusb_wa_trans_wrapper_t *wr, usb_bulk_req_t *bulk_reqp, - usb_flags_t usb_flags) -{ - int rval; - - mutex_enter(&hdl->rp_mutex); - switch (hdl->rp_state) { - case WA_RPIPE_STATE_IDLE: - rval = wusb_wa_wr_xfer(wa_data, hdl, wr, usb_flags); - break; - case WA_RPIPE_STATE_ACTIVE: - /* only allow one req at a time, this should not happen */ - default: - rval = USB_PIPE_ERROR; - break; - } - mutex_exit(&hdl->rp_mutex); - - if (rval != USB_SUCCESS) { - if (bulk_reqp->bulk_completion_reason == USB_CR_OK) { - bulk_reqp->bulk_completion_reason = usba_rval2cr(rval); - } - wusb_wa_free_trans_wrapper(wr); - } - - /* In other cases, wr will be freed in callback */ - return (rval); -} - -/* - * WA general bulk transfer - * - allocate bulk resources - * - submit the bulk request - */ -int -wusb_wa_bulk_xfer(wusb_wa_data_t *wa_data, wusb_wa_rpipe_hdl_t *hdl, - usba_pipe_handle_data_t *ph, usb_bulk_req_t *bulk_reqp, - usb_flags_t usb_flags) -{ - int rval; - wusb_wa_trans_wrapper_t *wr; - - USB_DPRINTF_L4(DPRINT_MASK_WHCDI, whcdi_log_handle, - "wusb_wa_bulk_xfer: ph = 0x%p reqp = 0x%p", - (void *)ph, (void *)bulk_reqp); - - wr = wusb_wa_alloc_bulk_resources(wa_data, hdl, ph, bulk_reqp, - usb_flags); - if (wr == NULL) { - USB_DPRINTF_L2(DPRINT_MASK_WHCDI, whcdi_log_handle, - "wusb_wa_bulk_xfer: alloc bulk resource failed"); - - return (USB_NO_RESOURCES); - } - - rval = wusb_wa_submit_bulk_wr(wa_data, hdl, wr, bulk_reqp, - usb_flags); - if (rval != USB_SUCCESS) { - USB_DPRINTF_L2(DPRINT_MASK_WHCDI, whcdi_log_handle, - "wusb_wa_bulk_req: submit bulk req failed, rval = %d", - rval); - } - - return (rval); -} - -/* - * submit wr according to rpipe status - * - * usba only submits one transfer to the host controller per pipe at a time - * and starts next when the previous one completed. So the hwahc now - * assumes one transfer per rpipe at a time. This won't be necessary to - * change unless the usba scheme is changed. - */ -int -wusb_wa_submit_intr_wr(wusb_wa_data_t *wa_data, wusb_wa_rpipe_hdl_t *hdl, - wusb_wa_trans_wrapper_t *wr, usb_intr_req_t *intr_reqp, - usb_flags_t usb_flags) -{ - int rval; - - mutex_enter(&hdl->rp_mutex); - switch (hdl->rp_state) { - case WA_RPIPE_STATE_IDLE: - rval = wusb_wa_wr_xfer(wa_data, hdl, wr, usb_flags); - break; - case WA_RPIPE_STATE_ACTIVE: - /* only allow one req at a time, this should not happen */ - default: - rval = USB_PIPE_ERROR; - break; - } - mutex_exit(&hdl->rp_mutex); - - if (rval != USB_SUCCESS) { - if (intr_reqp->intr_completion_reason == USB_CR_OK) { - intr_reqp->intr_completion_reason = usba_rval2cr(rval); - } - wusb_wa_free_trans_wrapper(wr); - } - - USB_DPRINTF_L4(DPRINT_MASK_WHCDI, whcdi_log_handle, - "wusb_wa_submit_intr_wr: submit intr req, rval = %d", rval); - - /* In other cases, wr will be freed in callback */ - return (rval); -} - -/* - * do intr xfer - * - * Now only one time intr transfer is supported. intr polling is not - * supported. - */ -int -wusb_wa_intr_xfer(wusb_wa_data_t *wa_data, wusb_wa_rpipe_hdl_t *hdl, - usba_pipe_handle_data_t *ph, usb_intr_req_t *intr_reqp, - usb_flags_t usb_flags) -{ - int rval; - wusb_wa_trans_wrapper_t *wr; - - USB_DPRINTF_L4(DPRINT_MASK_WHCDI, whcdi_log_handle, - "wusb_wa_intr_xfer: ph = 0x%p reqp = 0x%p", - (void *)ph, (void *)intr_reqp); - - wr = wusb_wa_alloc_intr_resources(wa_data, hdl, ph, intr_reqp, - usb_flags); - if (wr == NULL) { - USB_DPRINTF_L2(DPRINT_MASK_WHCDI, whcdi_log_handle, - "wusb_wa_intr_req: alloc intr resource failed"); - - return (USB_NO_RESOURCES); - } - - rval = wusb_wa_submit_intr_wr(wa_data, hdl, wr, intr_reqp, - usb_flags); - if (rval != USB_SUCCESS) { - USB_DPRINTF_L2(DPRINT_MASK_WHCDI, whcdi_log_handle, - "wusb_wa_intr_req: submit intr req failed, rval = %d", - rval); - - return (rval); - } - - /* - * have successfully duplicate and queue one more request on - * the pipe. Increase the pipe request count. - */ - if ((ph->p_ep.bEndpointAddress & USB_EP_DIR_MASK) == USB_EP_DIR_IN) { - mutex_enter(&ph->p_mutex); - - /* - * this count will be decremented by usba_req_normal_cb - * or usba_req_exc_cb (called by hcdi_do_cb <-- usba_hcdi_cb) - */ - ph->p_req_count++; - - USB_DPRINTF_L2(DPRINT_MASK_WHCDI, whcdi_log_handle, - "wusb_wa_intr_req: p_req_cnt = %d", ph->p_req_count); - - mutex_exit(&ph->p_mutex); - } - - return (rval); -} - -/* - * For an IN transfer request, receive transfer data on bulk-in ept - * The bulk_req has been allocated when allocating transfer resources - */ -int -wusb_wa_get_data(wusb_wa_data_t *wa_data, wusb_wa_seg_t *seg, uint32_t len) -{ - usb_bulk_req_t *req; - int rval; - - if (len == 0) { - - return (USB_SUCCESS); - } - - USB_DPRINTF_L2(DPRINT_MASK_WHCDI, whcdi_log_handle, - "wusb_wa_get_data: get data for wr: 0x%p", (void *)seg->seg_wr); - - req = seg->seg_data_reqp; - ASSERT(req != NULL); - - /* adjust bulk in length to actual length */ - req->bulk_len = len; - rval = usb_pipe_bulk_xfer(wa_data->wa_bulkin_ph, req, - USB_FLAGS_SLEEP); - - return (rval); -} - -/* - * to retrieve a transfer_wrapper by dwTransferID - * - * Though to search a list looks not so efficient, we have to give up - * id32_lookup(). When a transfer segment is throwed to HWA device, we - * can't anticipate when the result will be returned, even if we try to - * abort it. If we have freed the transfer wrapper due to timeout, then - * after a moment, that TW's segment is accomplished by hardware. If - * id32_lookup() is used to look up corresponding TW, we'll get an invalid - * address. Unfortunately, id32_lookup() can't judge validity of its - * returned address. - */ -wusb_wa_trans_wrapper_t * -wusb_wa_retrieve_wr(wusb_wa_data_t *wa_data, uint32_t id) -{ - wusb_wa_rpipe_hdl_t *rph; - uint16_t i; - wusb_wa_trans_wrapper_t *tw; - - for (i = 0; i < wa_data->wa_num_rpipes; i++) { - rph = &wa_data->wa_rpipe_hdl[i]; - - mutex_enter(&rph->rp_mutex); - /* all outstanding TWs are put on the timeout list */ - tw = rph->rp_timeout_list; - - while (tw) { - if (tw->wr_id == id) { - mutex_exit(&rph->rp_mutex); - return (tw); - } - tw = tw->wr_timeout_next; - } - mutex_exit(&rph->rp_mutex); - } - - return (NULL); -} - -/* endlessly wait for transfer result on bulk-in ept and handle the result */ -int -wusb_wa_get_xfer_result(wusb_wa_data_t *wa_data) -{ - usb_bulk_req_t *req; - int rval; - mblk_t *data; - uint8_t *p; - wa_xfer_result_t result; - wusb_wa_trans_wrapper_t *wr; - wusb_wa_seg_t *seg; - uint8_t status; - uint_t len; - uint8_t lastseg = 0; - usb_cr_t cr; - uint32_t act_len; - wusb_wa_rpipe_hdl_t *hdl; - - USB_DPRINTF_L4(DPRINT_MASK_WHCDI, whcdi_log_handle, - "wusb_wa_get_xfer_result: started, wa=0x%p", (void*)wa_data); - - /* grab lock before accessing wa_data */ - mutex_enter(&wa_data->wa_mutex); - - len = wa_data->wa_bulkin_ept.wMaxPacketSize; - - req = usb_alloc_bulk_req(wa_data->wa_dip, len, - USB_FLAGS_NOSLEEP); - if (req == NULL) { - USB_DPRINTF_L2(DPRINT_MASK_WHCDI, whcdi_log_handle, - "wusb_wa_get_xfer_result: alloc bulk req failed"); - - mutex_exit(&wa_data->wa_mutex); - - return (USB_NO_RESOURCES); - } - - req->bulk_len = len; - req->bulk_timeout = 0; - req->bulk_attributes = USB_ATTRS_SHORT_XFER_OK | - USB_ATTRS_AUTOCLEARING; - - mutex_exit(&wa_data->wa_mutex); - - /* Get the Transfer Result head, see Table 8-14 */ - rval = usb_pipe_bulk_xfer(wa_data->wa_bulkin_ph, req, - USB_FLAGS_SLEEP); - if ((rval != USB_SUCCESS) || (req->bulk_data == NULL)) { - USB_DPRINTF_L2(DPRINT_MASK_WHCDI, whcdi_log_handle, - "wusb_wa_get_xfer_result: bulk xfer failed or " - "null data returned, rval=%d, req->bulk_data = %p", - rval, (void*)req->bulk_data); - usb_free_bulk_req(req); - - return (rval); - } - - data = req->bulk_data; - p = data->b_rptr; - - USB_DPRINTF_L3(DPRINT_MASK_WHCDI, whcdi_log_handle, - "wusb_wa_get_xfer_result: received data len = %d", - (int)MBLKL(data)); - - if ((MBLKL(data) != WA_XFER_RESULT_LEN) || - (p[1] != WA_RESULT_TYPE_TRANSFER)) { - USB_DPRINTF_L2(DPRINT_MASK_WHCDI, whcdi_log_handle, - "wusb_wa_get_xfer_result: invalid xfer result, " - "len = %d, p0 = 0x%x, p1 = 0x%x, p6 = 0x%x", - (int)MBLKL(data), p[0], p[1], p[6]); - - usb_free_bulk_req(req); - - return (USB_SUCCESS); /* don't stop this thread */ - } - - /* Transfer result. Section 8.3.3.4 */ - (void) usb_parse_data("ccllccl", p, WA_XFER_RESULT_LEN, &result, - sizeof (wa_xfer_result_t)); - - - USB_DPRINTF_L3(DPRINT_MASK_WHCDI, whcdi_log_handle, - "wusb_wa_get_xfer_result: id = 0x%x len = 0x%x nseg = 0x%02x" - " status = 0x%02x(0x%02x)", result.dwTransferID, - result.dwTransferLength, result.bTransferSegment, - result.bTransferStatus, p[11]&0x0f); - - req->bulk_data = NULL; /* don't free it. we still need it */ - usb_free_bulk_req(req); - - status = result.bTransferStatus; - if ((status & 0x3f) == WA_STS_NOT_FOUND) { - freemsg(data); - /* - * The result is just ignored since the transfer request - * has completed - */ - USB_DPRINTF_L2(DPRINT_MASK_WHCDI, whcdi_log_handle, - "wusb_wa_get_xfer_result: TransferID not found"); - - return (USB_SUCCESS); - } - - mutex_enter(&wa_data->wa_mutex); - wr = wusb_wa_retrieve_wr(wa_data, result.dwTransferID); - if ((wr == NULL)) { - /* this id's corresponding WR may have been freed by timeout handler */ - USB_DPRINTF_L2(DPRINT_MASK_WHCDI, whcdi_log_handle, - "wusb_wa_get_xfer_result: wr == deadbeef or NULL"); - - mutex_exit(&wa_data->wa_mutex); - freemsg(data); - - return (USB_SUCCESS); - } - - /* bit 7 is last segment flag */ - if ((result.bTransferSegment & 0x7f) >= wr->wr_nsegs) { - USB_DPRINTF_L3(DPRINT_MASK_WHCDI, whcdi_log_handle, - "wusb_wa_get_xfer_result: error - " - " bTransferSegment(%d) > segment coutnts(%d)", - (result.bTransferSegment & 0x7f), wr->wr_nsegs); - - goto err; - } - - lastseg = result.bTransferSegment & 0x80; - hdl = wr->wr_rp; - - mutex_enter(&hdl->rp_mutex); - seg = &wr->wr_seg_array[result.bTransferSegment & 0x7f]; - seg->seg_status = result.bTransferStatus; - act_len = seg->seg_actual_len = result.dwTransferLength; - - /* - * if this is the last segment, we should not continue. - * IMPT: we expect the WA deliver result sequentially. - */ - seg->seg_done = (result.bTransferSegment) & 0x80; - - wr->wr_seg_done++; - hdl->rp_avail_reqs++; - USB_DPRINTF_L2(DPRINT_MASK_WHCDI, whcdi_log_handle, - "wusb_wa_get_xfer_result: wr = %p, rp=%p, avail_req=%d", (void*)wr, - (void*)wr->wr_rp, hdl->rp_avail_reqs); - - cv_broadcast(&hdl->rp_cv); - - if (status & 0x40) { - status = 0; /* ignore warning, see Tab8-15 */ - } - seg->seg_status = status; - - /* Error bit set */ - if (status & 0x80) { - /* don't change timeout error */ - if (wr->wr_state != WR_TIMEOUT) { - wr->wr_state = WR_XFER_ERR; - } - - /* - * The timeout handler is waiting, but the result thread will - * process this wr. - */ - if ((wr->wr_state == WR_TIMEOUT) && - (status & 0x3F) == WA_STS_ABORTED) { - wr->wr_has_aborted = 1; - cv_signal(&wr->wr_cv); /* to inform timeout hdler */ - } - - mutex_exit(&hdl->rp_mutex); - /* seg error, don't proceed with this WR */ - goto err; - } - - USB_DPRINTF_L3(DPRINT_MASK_WHCDI, whcdi_log_handle, - "wusb_wa_get_xfer_result: status = 0x%02x dir=%s", - status, (wr->wr_dir == WA_DIR_IN)?"IN":"OUT"); - - /* - * for an IN endpoint and data length > 0 and no error, read in - * the real data. Otherwise, for OUT EP, or data length = 0, or - * segment error, don't read. - */ - if ((wr->wr_dir == WA_DIR_IN) && - (act_len > 0) && - ((status & 0x3F) == 0)) { /* if segment error, don't read */ - /* receive data */ - mutex_exit(&hdl->rp_mutex); - mutex_exit(&wa_data->wa_mutex); - rval = wusb_wa_get_data(wa_data, seg, act_len); - mutex_enter(&wa_data->wa_mutex); - mutex_enter(&hdl->rp_mutex); - if (rval != USB_SUCCESS) { - USB_DPRINTF_L3(DPRINT_MASK_WHCDI, whcdi_log_handle, - "wusb_wa_get_xfer_result: can't get seg data:%d", - rval); - - mutex_exit(&hdl->rp_mutex); - - goto err; - } - - USB_DPRINTF_L3(DPRINT_MASK_WHCDI, whcdi_log_handle, - "wusb_wa_get_xfer_result: get (%dB) data for IN ep", - act_len); - } - - mutex_exit(&hdl->rp_mutex); - - mutex_exit(&wa_data->wa_mutex); - - /* check if the whole transfer has completed */ - wusb_wa_check_req_done(wa_data, wr, lastseg); - - USB_DPRINTF_L4(DPRINT_MASK_WHCDI, whcdi_log_handle, - "wusb_wa_get_xfer_result: ended"); - - freemsg(data); - - return (USB_SUCCESS); - -err: - mutex_exit(&wa_data->wa_mutex); - - mutex_enter(&hdl->rp_mutex); - USB_DPRINTF_L4(DPRINT_MASK_WHCDI, whcdi_log_handle, - "wusb_wa_get_xfer_result: segment(%02x) error, abort wr 0x%p," - "wr_state=%d", result.bTransferSegment, (void*)wr, wr->wr_state); - - /* if it's timeout, just return the TIMEOUT error */ - if (wr->wr_state == WR_TIMEOUT) { - cr = USB_CR_TIMEOUT; - } else { - cr = wusb_wa_sts2cr(status); - } - - mutex_exit(&hdl->rp_mutex); - - wusb_wa_handle_error(wa_data, wr, cr); - - USB_DPRINTF_L4(DPRINT_MASK_WHCDI, whcdi_log_handle, - "wusb_wa_get_xfer_result: error end, cr=%d", - cr); - - freemsg(data); - - return (USB_SUCCESS); -} - - -static void -wusb_wa_handle_error(wusb_wa_data_t *wa_data, wusb_wa_trans_wrapper_t *wr, - usb_cr_t cr) -{ - USB_DPRINTF_L4(DPRINT_MASK_WHCDI, whcdi_log_handle, - "wusb_wa_handle_error: start"); - - mutex_enter(&wr->wr_rp->rp_mutex); - if (wr->wr_seg_done != wr->wr_curr_seg) { - /* still segments pending, abort them */ - USB_DPRINTF_L3(DPRINT_MASK_WHCDI, whcdi_log_handle, - "wusb_wa_handle_error: segment err, abort other segs"); - - wusb_wa_abort_req(wa_data, wr, wr->wr_id); - } - - wusb_wa_stop_xfer_timer(wr); - wr->wr_rp->rp_state = WA_RPIPE_STATE_IDLE; - wr->wr_rp->rp_curr_wr = NULL; - mutex_exit(&wr->wr_rp->rp_mutex); - - wr->wr_cb(wa_data, wr, cr, 1); - - USB_DPRINTF_L4(DPRINT_MASK_WHCDI, whcdi_log_handle, - "wusb_wa_handle_error: error end, cr=%d", - cr); -} - -/* - * Check if current request is done, if yes, do callback and move on to - * next request; if there is any uncleared error, do callback to cleanup - * the pipe - */ -void -wusb_wa_check_req_done(wusb_wa_data_t *wa_data, - wusb_wa_trans_wrapper_t *wr, uint8_t lastseg) -{ - wusb_wa_rpipe_hdl_t *hdl = wr->wr_rp; - wusb_wa_seg_t *seg; - int i, rval; - usb_cr_t cr; - - USB_DPRINTF_L4(DPRINT_MASK_WHCDI, whcdi_log_handle, - "wusb_wa_check_req_done: wr = 0x%p, lastseg=%02x", - (void*)wr, lastseg); - - mutex_enter(&hdl->rp_mutex); - /* not done: submitted segs not finished and lastseg not set */ - if ((wr->wr_seg_done != wr->wr_curr_seg) && (!lastseg)) { - mutex_exit(&hdl->rp_mutex); - - return; - } - - if (wr->wr_state != 0) { /* abort somewhere */ - USB_DPRINTF_L4(DPRINT_MASK_WHCDI, whcdi_log_handle, - "wusb_wa_check_req_done: tw(%p) aborted somewhere", - (void*)wr); - cr = USB_CR_UNSPECIFIED_ERR; - - goto reset; - } - - /* check if there is any error */ - for (i = 0; i < wr->wr_curr_seg; i++) { - seg = &wr->wr_seg_array[i]; - if (seg->seg_status != WA_STS_SUCCESS) { - /* what about short xfer? need to fix */ - cr = wusb_wa_sts2cr(seg->seg_status); - USB_DPRINTF_L4(DPRINT_MASK_WHCDI, whcdi_log_handle, - "wusb_wa_check_req_done: seg fail, status=%02x", - seg->seg_status); - - goto reset; - } - - if (seg->seg_done == 0x80) { - /* device has told this is the last segment, we're done */ - USB_DPRINTF_L4(DPRINT_MASK_WHCDI, whcdi_log_handle, - "wusb_wa_check_req_done: last seg"); - - goto done; - } - } - - /* check if current request has completed */ - /* - * Transfer another segment. - * - */ - if (wr->wr_curr_seg < wr->wr_nsegs) { - /* send the remained segments */ - USB_DPRINTF_L4(DPRINT_MASK_WHCDI, whcdi_log_handle, - "wusb_wa_check_req_done: req not completed, restart"); - - rval = wusb_wa_wr_xfer(wa_data, hdl, wr, wr->wr_flags); - if (rval != USB_SUCCESS) { - cr = usba_rval2cr(rval); - - goto reset; - } - - mutex_exit(&hdl->rp_mutex); - - return; - } - -done: - wusb_wa_stop_xfer_timer(wr); - - /* release the occupied requests */ - hdl->rp_avail_reqs += (wr->wr_curr_seg - wr->wr_seg_done); - cv_signal(&hdl->rp_cv); - - hdl->rp_state = WA_RPIPE_STATE_IDLE; - hdl->rp_curr_wr = NULL; - wr->wr_state = WR_FINISHED; - mutex_exit(&hdl->rp_mutex); - - wr->wr_cb(wa_data, wr, USB_CR_OK, 0); - - /* Need to move on to next request? usba will do this */ - USB_DPRINTF_L4(DPRINT_MASK_WHCDI, whcdi_log_handle, - "wusb_wa_check_req_done: ended"); - - return; - -reset: - wusb_wa_stop_xfer_timer(wr); - - /* not necessary to reset the RPipe */ - hdl->rp_state = WA_RPIPE_STATE_IDLE; - hdl->rp_curr_wr = NULL; - - hdl->rp_avail_reqs += (wr->wr_curr_seg - wr->wr_seg_done); - cv_signal(&hdl->rp_cv); - - /* if it's timeout, just return the TIMEOUT error */ - if (wr->wr_state == WR_TIMEOUT) - cr = USB_CR_TIMEOUT; - - mutex_exit(&hdl->rp_mutex); - - wr->wr_cb(wa_data, wr, cr, 1); - USB_DPRINTF_L4(DPRINT_MASK_WHCDI, whcdi_log_handle, - "wusb_wa_check_req_done: reset end"); -} - -/* - * callback for ctrl transfer - * - * reset_flag: not support yet - */ -void -wusb_wa_handle_ctrl(wusb_wa_data_t *wa_data, wusb_wa_trans_wrapper_t *wr, - usb_cr_t cr, uint_t reset_flag) -{ - usb_ctrl_req_t *req; - usb_bulk_req_t *bulk_req; - mblk_t *data, *bulk_data; - int i; - size_t len; - wusb_wa_seg_t *seg; - - USB_DPRINTF_L4(DPRINT_MASK_WHCDI, whcdi_log_handle, - "wusb_wa_handle_ctrl: wr = 0x%p, cr = 0x%x, flag=%d", - (void*)wr, cr, reset_flag); - - req = (usb_ctrl_req_t *)wr->wr_reqp; - - if ((wr->wr_dir == WA_DIR_OUT) || (cr != USB_CR_OK)) { - - /* do callback */ - wusb_wa_callback(wa_data, wr->wr_ph, wr, cr); - - return; - } - - mutex_enter(&wr->wr_rp->rp_mutex); - data = req->ctrl_data; - for (i = 0; i < wr->wr_nsegs; i++) { - seg = &wr->wr_seg_array[i]; - /* copy received data to original req buffer */ - bulk_req = (usb_bulk_req_t *) - wr->wr_seg_array[i].seg_data_reqp; - bulk_data = bulk_req->bulk_data; - len = MBLKL(bulk_data); - bcopy(bulk_data->b_rptr, data->b_wptr, len); - data->b_wptr += len; - if (len < wr->wr_seg_array[i].seg_len) { - /* short xfer */ - break; - } - - if (seg->seg_done == 0x80) { - /* last segment, finish */ - break; - } - } - - mutex_exit(&wr->wr_rp->rp_mutex); - /* do callback */ - wusb_wa_callback(wa_data, wr->wr_ph, wr, cr); -} - -/* - * callback for bulk transfer - * - * reset_flag: not support yet - */ -void -wusb_wa_handle_bulk(wusb_wa_data_t *wa_data, wusb_wa_trans_wrapper_t *wr, - usb_cr_t cr, uint_t reset_flag) -{ - usb_bulk_req_t *req; - usb_bulk_req_t *bulk_req; - mblk_t *data, *bulk_data; - int i; - size_t len; - wusb_wa_seg_t *seg; - - USB_DPRINTF_L4(DPRINT_MASK_WHCDI, whcdi_log_handle, - "wusb_wa_handle_bulk: wr = 0x%p, cr = 0x%x, flag=%d", - (void*)wr, cr, reset_flag); - - req = (usb_bulk_req_t *)wr->wr_reqp; - - if ((wr->wr_dir == WA_DIR_OUT) || (cr != USB_CR_OK)) { - /* do callback */ - wusb_wa_callback(wa_data, wr->wr_ph, wr, cr); - - return; - } - - mutex_enter(&wr->wr_rp->rp_mutex); - data = req->bulk_data; - for (i = 0; i < wr->wr_nsegs; i++) { - seg = &wr->wr_seg_array[i]; - /* copy received data to original req buffer */ - bulk_req = (usb_bulk_req_t *) - wr->wr_seg_array[i].seg_data_reqp; - bulk_data = bulk_req->bulk_data; - len = MBLKL(bulk_data); - bcopy(bulk_data->b_rptr, data->b_wptr, len); - data->b_wptr += len; - if (len < wr->wr_seg_array[i].seg_len) { - /* short xfer */ - break; - } - - if (seg->seg_done == 0x80) { - /* last segment, finish */ - break; - } - } - - mutex_exit(&wr->wr_rp->rp_mutex); - /* do callback */ - wusb_wa_callback(wa_data, wr->wr_ph, wr, cr); -} - -int -wa_submit_periodic_req(wusb_wa_data_t *wa_data, usba_pipe_handle_data_t *ph) -{ - USB_DPRINTF_L4(DPRINT_MASK_WHCDI, whcdi_log_handle, - "wa_submit_periodic_req: wa_data=0x%p, ph=0x%p", - (void*)wa_data, (void*)ph); - - return (wa_data->pipe_periodic_req(wa_data, ph)); -} - -/* - * callback for intr transfer - * - * reset_flag: not support yet - */ -void -wusb_wa_handle_intr(wusb_wa_data_t *wa_data, wusb_wa_trans_wrapper_t *wr, - usb_cr_t cr, uint_t reset_flag) -{ - usb_intr_req_t *req; - usb_req_attrs_t attrs; - usba_pipe_handle_data_t *ph = wr->wr_ph; - usb_bulk_req_t *bulk_req; - mblk_t *data, *bulk_data; - int i; - size_t len; - int rval; - wusb_wa_seg_t *seg; - - USB_DPRINTF_L4(DPRINT_MASK_WHCDI, whcdi_log_handle, - "wusb_wa_handle_intr: wr = 0x%p, cr = 0x%x, flag=%d", - (void*)wr, cr, reset_flag); - - req = (usb_intr_req_t *)wr->wr_reqp; - attrs = req->intr_attributes; - - if ((wr->wr_dir == WA_DIR_OUT) || (cr != USB_CR_OK)) { - /* do callback */ - wusb_wa_callback(wa_data, wr->wr_ph, wr, cr); - - return; - } - - mutex_enter(&wr->wr_rp->rp_mutex); - /* copy data to client's buffer */ - data = req->intr_data; - for (i = 0; i < wr->wr_nsegs; i++) { - seg = &wr->wr_seg_array[i]; - /* copy received data to original req buffer */ - bulk_req = (usb_bulk_req_t *) - wr->wr_seg_array[i].seg_data_reqp; - bulk_data = bulk_req->bulk_data; - len = MBLKL(bulk_data); - bcopy(bulk_data->b_rptr, data->b_wptr, len); - data->b_wptr += len; - if (len < wr->wr_seg_array[i].seg_len) { - /* short xfer */ - break; - } - - if (seg->seg_done & 0x80) { - - break; - } - } - - if (attrs & USB_ATTRS_ONE_XFER) { - /* client requires ONE_XFER request, return */ - USB_DPRINTF_L4(DPRINT_MASK_WHCDI, whcdi_log_handle, - "wusb_wa_handle_intr: ONE_XFER set"); - - mutex_exit(&wr->wr_rp->rp_mutex); - goto finish; - } - - /* polling mode */ - mutex_exit(&wr->wr_rp->rp_mutex); - rval = wa_submit_periodic_req(wa_data, ph); - if (rval != USB_SUCCESS) { - USB_DPRINTF_L4(DPRINT_MASK_WHCDI, whcdi_log_handle, - "wusb_wa_handle_intr: polling, fail to resubmit req"); - - goto finish; - } - - USB_DPRINTF_L4(DPRINT_MASK_WHCDI, whcdi_log_handle, - "wusb_wa_handle_intr: polling, resubmit request, rv=%d", rval); - -finish: - /* do callback */ - wusb_wa_callback(wa_data, wr->wr_ph, wr, cr); - - USB_DPRINTF_L4(DPRINT_MASK_WHCDI, whcdi_log_handle, - "wusb_wa_handle_intr: end"); -} - -/* - * free transfer wrapper - * call host controller driver callback for completion handling - * - * This callback will call WA's specific callback function. - * The callback functions should call usba_hcdi_cb() to pass request - * back to client driver. - */ -void -wusb_wa_callback(wusb_wa_data_t *wa_data, usba_pipe_handle_data_t *ph, - wusb_wa_trans_wrapper_t *wr, usb_cr_t cr) -{ - USB_DPRINTF_L4(DPRINT_MASK_WHCDI, whcdi_log_handle, - "wusb_wa_callback: wr=0x%p, cr=0x%x, ph=0x%p, req = 0x%p", - (void*)wr, cr, (void*)ph, (void*)((wr == NULL)?0:wr->wr_reqp)); - - if (cr == USB_CR_FLUSHED) { - /* - * the wr is aborted. mark the rpipe as error, - * so that the periodic xfer callbacks will not submit - * further requests. - */ - mutex_enter(&wr->wr_rp->rp_mutex); - wr->wr_rp->rp_state = WA_RPIPE_STATE_ERROR; - mutex_exit(&wr->wr_rp->rp_mutex); - } - - wa_data->rpipe_xfer_cb(wa_data->wa_dip, ph, wr, cr); - - /* - * need to consider carefully when to free wrapper - * if the rpipe is reset, what to do with current wr in processing? - */ - USB_DPRINTF_L4(DPRINT_MASK_WHCDI, whcdi_log_handle, - "wusb_wa_callback: hwahc callback finish for wr= 0x%p, free it", - (void*)wr); - - wusb_wa_free_trans_wrapper(wr); -} - -static struct { - uint8_t status; - usb_cr_t cr; -} sts2cr[] = { - {WA_STS_SUCCESS, USB_CR_OK}, - {WA_STS_HALTED, USB_CR_STALL}, - {WA_STS_DATA_BUFFER_ERROR, USB_CR_DATA_OVERRUN}, - {WA_STS_BABBLE, USB_CR_DATA_UNDERRUN}, - {WA_STS_NOT_FOUND, USB_CR_NOT_ACCESSED}, - {WA_STS_INSUFFICIENT_RESOURCE, USB_CR_NO_RESOURCES}, - {0x80 | WA_STS_TRANSACTION_ERROR, USB_CR_STALL}, - {0x40 | WA_STS_TRANSACTION_ERROR, USB_CR_OK}, - {WA_STS_ABORTED, USB_CR_FLUSHED}, - {WA_STS_RPIPE_NOT_READY, USB_CR_DEV_NOT_RESP}, - {WA_STS_INVALID_REQ_FORMAT, USB_CR_CRC}, - {WA_STS_UNEXPECTED_SEGMENT_NUM, USB_CR_UNEXP_PID}, - {WA_STS_RPIPE_TYPE_MISMATCH, USB_CR_NOT_SUPPORTED}, - {WA_STS_PACKET_DISCARDED, USB_CR_PID_CHECKFAILURE}, - {0xff, 0} /* end */ -}; - -/* translate transfer status to USB completion reason */ -usb_cr_t -wusb_wa_sts2cr(uint8_t rawstatus) -{ - int i; - uint8_t status; - - /* cares about bits5:0 in WUSB 1.0 */ - if ((rawstatus & 0x1f) == WA_STS_TRANSACTION_ERROR) { - status = rawstatus; - } else { - status = rawstatus & 0x1f; - } - - for (i = 0; sts2cr[i].status != 0xff; i++) { - if (sts2cr[i].status == status) { - - return (sts2cr[i].cr); - } - } - - return (USB_CR_UNSPECIFIED_ERR); -} diff --git a/usr/src/uts/common/io/usb/usba/whcdi.c b/usr/src/uts/common/io/usb/usba/whcdi.c deleted file mode 100644 index 13a9a01f75..0000000000 --- a/usr/src/uts/common/io/usb/usba/whcdi.c +++ /dev/null @@ -1,2884 +0,0 @@ -/* - * 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 - * or http://www.opensolaris.org/os/licensing. - * 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. - */ - - -/* - * USBA: Solaris USB Architecture support - * - * whcdi.c is part of the WUSB extension to the USBA framework. - * - * It mainly contains functions that can be shared by whci and hwahc - * drivers to enable WUSB host functionality, such as WUSB channel - * resource management, MMC IE handling, WUSB HC specific requests, - * WUSB device authentication, child connection/disconnection, etc. - */ -#define USBA_FRAMEWORK -#include <sys/usb/usba.h> -#include <sys/usb/usba/usba_impl.h> -#include <sys/usb/usba/usba_types.h> -#include <sys/usb/usba/hcdi_impl.h> /* for usba_hcdi_t */ -#include <sys/usb/usba/whcdi.h> -#include <sys/usb/usba/wa.h> -#include <sys/strsubr.h> -#include <sys/crypto/api.h> -#include <sys/strsun.h> -#include <sys/random.h> - -/* - * local variables - */ -static kmutex_t whcdi_mutex; - -/* use 0-30 bit as wusb cluster_id bitmaps */ -static uint32_t cluster_id_mask = 0; - -_NOTE(MUTEX_PROTECTS_DATA(whcdi_mutex, cluster_id_mask)) - -usb_log_handle_t whcdi_log_handle; -uint_t whcdi_errlevel = USB_LOG_L4; -uint_t whcdi_errmask = (uint_t)-1; - -/* - * initialize private data - */ -void -usba_whcdi_initialization() -{ - whcdi_log_handle = usb_alloc_log_hdl(NULL, "whcdi", &whcdi_errlevel, - &whcdi_errmask, NULL, 0); - - USB_DPRINTF_L4(DPRINT_MASK_WHCDI, whcdi_log_handle, - "whcdi_initialization"); - - mutex_init(&whcdi_mutex, NULL, MUTEX_DRIVER, NULL); -} - -void -usba_whcdi_destroy() -{ - USB_DPRINTF_L4(DPRINT_MASK_WHCDI, whcdi_log_handle, - "whcdi_destroy"); - - mutex_destroy(&whcdi_mutex); - - usb_free_log_hdl(whcdi_log_handle); -} - -/* - * Assign a cluster id for a WUSB channel - * return 0 if no free cluster id is available - */ -uint8_t -wusb_hc_get_cluster_id() -{ - int i; - uint8_t id; - - mutex_enter(&whcdi_mutex); - for (i = 0; i < WUSB_CLUSTER_ID_COUNT; i++) { - /* find the first unused slot */ - if (cluster_id_mask & (1 << i)) { - continue; - } - - /* set the bitmask */ - cluster_id_mask |= (1 << i); - id = WUSB_MIN_CLUSTER_ID + i; - USB_DPRINTF_L3(DPRINT_MASK_WHCDI, whcdi_log_handle, - "new cluster id %d, mask %d", id, cluster_id_mask); - mutex_exit(&whcdi_mutex); - - return (id); - } - - mutex_exit(&whcdi_mutex); - - USB_DPRINTF_L2(DPRINT_MASK_WHCDI, whcdi_log_handle, - "no cluster id available"); - - return (0); -} - -/* Free the cluster id */ -void -wusb_hc_free_cluster_id(uint8_t id) -{ - int i = id - WUSB_MIN_CLUSTER_ID; - - if ((i < 0) || (i >= WUSB_CLUSTER_ID_COUNT)) { - - return; - } - - mutex_enter(&whcdi_mutex); - if (cluster_id_mask & (1 << i)) { - /* unset the bitmask */ - cluster_id_mask &= ~(1 << i); - } else { - USB_DPRINTF_L2(DPRINT_MASK_WHCDI, whcdi_log_handle, - "cluster id already freed"); - } - mutex_exit(&whcdi_mutex); -} - -/* - * Allocate iehdl according to the order specified in WUSB 1.0/7.5 - * WUSB Errata 06.12 requires iehdl to be zero based - */ -int -wusb_hc_get_iehdl(wusb_hc_data_t *hc_data, wusb_ie_header_t *hdr, - uint8_t *iehdl) -{ - int i, rval = USB_SUCCESS; - uint8_t hdl = 0xFF; - - switch (hdr->bIEIdentifier) { - case WUSB_IE_HOSTINFO: - /* - * 7.5.2(and 7.5 under Table 7-38) says this IE should be located - * in an MMC afte all WCTA_IEs. This mean its handle should - * be the last one. See also whci r0.95 page 105 top. HC sends - * IE blocks in ascending IE_HANDLE order. - */ - hdl = hc_data->hc_num_mmcies - 1; - hc_data->hc_mmcie_list[hdl] = hdr; - break; - case WUSB_IE_ISOC_DISCARD: - /* - * 7.5.10 says this IE must be included before any WxCTAs. - */ - USB_DPRINTF_L2(DPRINT_MASK_WHCDI, whcdi_log_handle, - "IE type 0x%x unimplemented\n", hdr->bIEIdentifier); - rval = USB_NOT_SUPPORTED; - break; - default: - /* - * search for existing slot or find the last empty slot - * so that the other IEs would always set after WCTA_IEs - */ - for (i = hc_data->hc_num_mmcies - 2; i >= 0; i--) { - if ((hc_data->hc_mmcie_list[i] == hdr) || - (hc_data->hc_mmcie_list[i] == NULL)) { - hdl = (uint8_t)i; - hc_data->hc_mmcie_list[i] = hdr; - break; - } - } - if (hdl == 0xFF) { - USB_DPRINTF_L2(DPRINT_MASK_WHCDI, whcdi_log_handle, - "no IE handle available\n"); - rval = USB_NO_RESOURCES; - } - break; - } - - if (rval == USB_SUCCESS) { - *iehdl = hdl; - } - - return (rval); -} - -/* Deallocate iehdl */ -void -wusb_hc_free_iehdl(wusb_hc_data_t *hc_data, uint8_t iehdl) -{ - ASSERT(mutex_owned(&hc_data->hc_mutex)); - - if (iehdl >= hc_data->hc_num_mmcies) { - - return; - } - - if (hc_data->hc_mmcie_list[iehdl] != NULL) { - hc_data->hc_mmcie_list[iehdl] = NULL; - } -} - - -/* - * ****************************************************************** - * WUSB host controller specific requests, refer to WUSB 1.0/8.5.3 - * - * WHCI driver needs to translate the requests to register operations - * ****************************************************************** - */ - -/* For HWA, see WUSB 8.5.3.11 - Set WUSB Cluster ID */ -int -wusb_hc_set_cluster_id(wusb_hc_data_t *hc_data, uint8_t cluster_id) -{ - dev_info_t *dip = hc_data->hc_dip; - int rval; - - if (dip == NULL) { - - return (USB_INVALID_ARGS); - } - - if ((rval = hc_data->set_cluster_id(dip, cluster_id)) - != USB_SUCCESS) { - - USB_DPRINTF_L2(DPRINT_MASK_WHCDI, whcdi_log_handle, - "Set_Cluster_ID fails: rval=%d ", rval); - } else { - mutex_enter(&hc_data->hc_mutex); - hc_data->hc_cluster_id = cluster_id; - mutex_exit(&hc_data->hc_mutex); - } - - return (rval); -} - -/* - * WUSB 8.5.3.13 - Set WUSB Stream Index - * From 7.7, stream index should be 3bits and less than 8. - */ -int -wusb_hc_set_stream_idx(wusb_hc_data_t *hc_data, uint8_t stream_idx) -{ - dev_info_t *dip = hc_data->hc_dip; - int rval; - - if (stream_idx > 7) { - USB_DPRINTF_L2(DPRINT_MASK_WHCDI, whcdi_log_handle, - "Set_Stream_Idx fails: invalid idx = %d", - stream_idx); - - return (USB_INVALID_ARGS); - } - - rval = hc_data->set_stream_idx(dip, stream_idx); - if (rval != USB_SUCCESS) { - USB_DPRINTF_L2(DPRINT_MASK_WHCDI, whcdi_log_handle, - "Set_Stream_Idx fails: rval=%d", - rval); - } - - return (rval); -} - -/* For HWA, see WUSB 8.5.3.12 - Set WUSB MAS */ -int -wusb_hc_set_wusb_mas(wusb_hc_data_t *hc_data, uint8_t *data) -{ - dev_info_t *dip = hc_data->hc_dip; - int rval; - - rval = hc_data->set_wusb_mas(dip, data); - if (rval != USB_SUCCESS) { - USB_DPRINTF_L2(DPRINT_MASK_WHCDI, whcdi_log_handle, - "Set_WUSB_MAS fails: rval=%d", rval); - } - - return (rval); - -} - -/* For HWA, see WUSB 8.5.3.1 - Add MMC IE */ -int -wusb_hc_add_mmc_ie(wusb_hc_data_t *hc_data, uint8_t interval, - uint8_t rcnt, uint8_t iehdl, uint16_t len, uint8_t *data) -{ - dev_info_t *dip = hc_data->hc_dip; - int rval; - - rval = hc_data->add_mmc_ie(dip, interval, rcnt, iehdl, len, data); - - if (rval != USB_SUCCESS) { - USB_DPRINTF_L2(DPRINT_MASK_WHCDI, whcdi_log_handle, - "Add_MMC_IE fails: rval=%d ", - rval); - } - - return (rval); -} - -/* For HWA, see WUSB 8.5.3.5 - Remove MMC IE */ -int -wusb_hc_remove_mmc_ie(wusb_hc_data_t *hc_data, uint8_t iehdl) -{ - dev_info_t *dip = hc_data->hc_dip; - int rval; - - ASSERT(mutex_owned(&hc_data->hc_mutex)); - - if ((iehdl >= hc_data->hc_num_mmcies) || - (hc_data->hc_mmcie_list[iehdl] == NULL)) { - - return (USB_FAILURE); - } - - mutex_exit(&hc_data->hc_mutex); - rval = hc_data->rem_mmc_ie(dip, iehdl); - mutex_enter(&hc_data->hc_mutex); - if (rval != USB_SUCCESS) { - USB_DPRINTF_L2(DPRINT_MASK_WHCDI, whcdi_log_handle, - "Remove_MMC_IE fails: rval=%d ", rval); - } - - return (rval); -} - -/* For HWA, see WUSB 8.5.3.14 - WUSB Channel Stop */ -int -wusb_hc_stop_ch(wusb_hc_data_t *hc_data, uint32_t timeoff) -{ - dev_info_t *dip = hc_data->hc_dip; - int rval; - - rval = hc_data->stop_ch(dip, timeoff); - if (rval != USB_SUCCESS) { - USB_DPRINTF_L2(DPRINT_MASK_WHCDI, whcdi_log_handle, - "WUSB_Ch_Stop fails: rval=%d ", rval); - } - - return (rval); -} - -/* For HWA, see WUSB 8.5. 3.10 - Set Num DNTS Slots */ -int -wusb_hc_set_num_dnts(wusb_hc_data_t *hc_data, uint8_t interval, - uint8_t nslots) -{ - dev_info_t *dip = hc_data->hc_dip; - int rval; - - rval = hc_data->set_num_dnts(dip, interval, nslots); - if (rval != USB_SUCCESS) { - USB_DPRINTF_L2(DPRINT_MASK_WHCDI, whcdi_log_handle, - "Set_Num_DNTS fails: rval=%d ", rval); - } - - return (rval); -} - -/* - * For HWA, see WUSB 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 -wusb_hc_get_time(wusb_hc_data_t *hc_data, uint8_t time_type, - uint16_t len, uint32_t *time) -{ - dev_info_t *dip = hc_data->hc_dip; - int rval; - - /* call the HC's specific get_time function */ - rval = hc_data->get_time(dip, time_type, len, time); - if (rval != USB_SUCCESS) { - USB_DPRINTF_L2(DPRINT_MASK_WHCDI, whcdi_log_handle, - "Set_Num_DNTS fails: rval=%d ", rval); - } - - return (rval); -} - -/* - * Remove the specified IE from host MMC and release the related IE handle - */ -void -wusb_hc_rem_ie(wusb_hc_data_t *hc_data, wusb_ie_header_t *ieh) -{ - int i; - int16_t iehdl = -1; - - mutex_enter(&hc_data->hc_mutex); - for (i = 0; i < hc_data->hc_num_mmcies; i++) { - if (hc_data->hc_mmcie_list[i] == ieh) { - iehdl = (int16_t)i; - - break; - } - } - - if (iehdl == -1) { - USB_DPRINTF_L2(DPRINT_MASK_WHCDI, whcdi_log_handle, - "wusb_hc_rem_ie: IE(%p) iehdl not found", (void *)ieh); - mutex_exit(&hc_data->hc_mutex); - - return; - } - - (void) wusb_hc_remove_mmc_ie(hc_data, (uint8_t)iehdl); - - wusb_hc_free_iehdl(hc_data, (uint8_t)iehdl); - mutex_exit(&hc_data->hc_mutex); -} - -/* Add Host Info IE */ -int -wusb_hc_add_host_info(wusb_hc_data_t *hc_data, uint8_t stream_idx) -{ - wusb_ie_host_info_t *hinfo; - uint8_t iehdl; - int rval; - - hinfo = kmem_zalloc(sizeof (wusb_ie_host_info_t), KM_SLEEP); - - mutex_enter(&hc_data->hc_mutex); - - hinfo->bIEIdentifier = WUSB_IE_HOSTINFO; - hinfo->bLength = sizeof (wusb_ie_host_info_t); - if (hc_data->hc_newcon_enabled) { - hinfo->bmAttributes[0] = (stream_idx << WUSB_HI_STRIDX_SHIFT) | - WUSB_HI_CONN_ALL; - } else { - hinfo->bmAttributes[0] = (stream_idx << WUSB_HI_STRIDX_SHIFT) | - WUSB_HI_CONN_LMTED; - } - (void) memcpy(hinfo->CHID, hc_data->hc_chid, sizeof (hinfo->CHID)); - - rval = wusb_hc_get_iehdl(hc_data, (wusb_ie_header_t *)hinfo, &iehdl); - if (rval != USB_SUCCESS) { - USB_DPRINTF_L2(DPRINT_MASK_WHCDI, whcdi_log_handle, - "wusb_hc_add_host_info: get ie handle fails"); - mutex_exit(&hc_data->hc_mutex); - - return (rval); - } - - USB_DPRINTF_L3(DPRINT_MASK_WHCDI, whcdi_log_handle, - "wusb_hc_add_host_info: iehdl=%d", iehdl); - - mutex_exit(&hc_data->hc_mutex); - rval = wusb_hc_add_mmc_ie(hc_data, 10, 1, iehdl, - sizeof (wusb_ie_host_info_t), (uint8_t *)hinfo); - if (rval != USB_SUCCESS) { - USB_DPRINTF_L2(DPRINT_MASK_WHCDI, whcdi_log_handle, - "wusb_hc_add_host_info: add host info mmc ie fails"); - mutex_enter(&hc_data->hc_mutex); - wusb_hc_free_iehdl(hc_data, iehdl); - mutex_exit(&hc_data->hc_mutex); - - return (rval); - } - - - return (USB_SUCCESS); -} - -/* Remove Host Info IE */ -void -wusb_hc_rem_host_info(wusb_hc_data_t *hc_data) -{ - int16_t iehdl = -1; - wusb_ie_header_t *iehead; - - mutex_enter(&hc_data->hc_mutex); - /* host info IE is always the last one */ - iehdl = hc_data->hc_num_mmcies - 1; - iehead = hc_data->hc_mmcie_list[iehdl]; - - /* something wrong */ - if ((iehead == NULL) || (iehead->bIEIdentifier != WUSB_IE_HOSTINFO)) { - mutex_exit(&hc_data->hc_mutex); - return; - } - - (void) wusb_hc_remove_mmc_ie(hc_data, (uint8_t)iehdl); - wusb_hc_free_iehdl(hc_data, (uint8_t)iehdl); - kmem_free(iehead, sizeof (wusb_ie_host_info_t)); - - mutex_exit(&hc_data->hc_mutex); -} - -/* - * Check if a device with certain CDID is connected - * return 1 if a device with the same CDID is found; - * return 0 if not - */ -uint_t -wusb_hc_is_dev_connected(wusb_hc_data_t *hc_data, uint8_t *cdid, - usb_port_t *port) -{ - int i; - wusb_dev_info_t *dev_info; - - ASSERT(mutex_owned(&hc_data->hc_mutex)); - - for (i = 1; i <= hc_data->hc_num_ports; i++) { - dev_info = hc_data->hc_dev_infos[i]; - if ((dev_info != NULL) && - (memcmp(cdid, dev_info->wdev_cdid, 16) == 0)) { - *port = (usb_port_t)i; - USB_DPRINTF_L3(DPRINT_MASK_WHCDI, whcdi_log_handle, - "wusb_hc_is_dev_connected: find dev at port " - "%d", *port); - - return (1); - } - } - - return (0); -} - -/* - * Check if a device with certain address is connected - * return 1 if a device with the same address is found; - * return 0 if not - */ -uint_t -wusb_hc_is_addr_valid(wusb_hc_data_t *hc_data, uint8_t addr, - usb_port_t *port) -{ - int i; - wusb_dev_info_t *dev_info; - - for (i = 1; i <= hc_data->hc_num_ports; i++) { - dev_info = hc_data->hc_dev_infos[i]; - if ((dev_info != NULL) && (dev_info->wdev_addr == addr)) { - *port = (usb_port_t)i; - USB_DPRINTF_L3(DPRINT_MASK_WHCDI, whcdi_log_handle, - "wusb_hc_is_addr_valid: find addr at port " - "%d", *port); - - return (1); - } - } - - return (0); -} - - -/* - * Assign port number for a newly connected device - * return the first free port number if any, or 0 if none - */ -usb_port_t -wusb_hc_get_free_port(wusb_hc_data_t *hc_data) -{ - int i; - usb_port_t port; - - for (i = 1; i <= hc_data->hc_num_ports; i++) { - if (hc_data->hc_dev_infos[i] == NULL) { - port = (usb_port_t)i; - USB_DPRINTF_L3(DPRINT_MASK_WHCDI, whcdi_log_handle, - "wusb_hc_get_free_port: find free port %d", port); - - return (port); - } - } - - return (0); -} - -/* Add Connect Acknowledge IE */ -int -wusb_hc_ack_conn(wusb_hc_data_t *hc_data, usb_port_t port) -{ - wusb_dev_info_t *dev_info; - wusb_ie_connect_ack_t *ack_ie; - wusb_connectack_block_t *ack_block; - uint8_t iehdl; - int rval; - - ASSERT(mutex_owned(&hc_data->hc_mutex)); - - dev_info = hc_data->hc_dev_infos[port]; - ASSERT(dev_info != NULL); - - ack_ie = kmem_zalloc(sizeof (wusb_ie_connect_ack_t), KM_SLEEP); - - ack_ie->bIEIdentifier = WUSB_IE_CONNECTACK; - ack_block = (wusb_connectack_block_t *)ack_ie->bAckBlock; - (void) memcpy(ack_block->CDID, dev_info->wdev_cdid, 16); - ack_block->bDeviceAddress = dev_info->wdev_addr; - ack_ie->bLength = 20; - - rval = wusb_hc_get_iehdl(hc_data, (wusb_ie_header_t *)ack_ie, &iehdl); - if (rval != USB_SUCCESS) { - USB_DPRINTF_L2(DPRINT_MASK_WHCDI, whcdi_log_handle, - "wusb_hc_ack_conn: get ie handle fails"); - kmem_free(ack_ie, sizeof (wusb_ie_connect_ack_t)); - - return (rval); - } - - rval = wusb_hc_add_mmc_ie(hc_data, 0, 3, iehdl, - ack_ie->bLength, (uint8_t *)ack_ie); - if (rval != USB_SUCCESS) { - USB_DPRINTF_L2(DPRINT_MASK_WHCDI, whcdi_log_handle, - "wusb_hc_ack_conn: add connect ack ie fails"); - wusb_hc_free_iehdl(hc_data, iehdl); - kmem_free(ack_ie, sizeof (wusb_ie_connect_ack_t)); - - return (rval); - } - - mutex_exit(&hc_data->hc_mutex); - /* - * WUSB 1.0/7.5.1 requires at least 2ms delay between ConnectAck - * and WUSB transactions, wait for 2ms here - */ - delay(drv_usectohz(2000)); - mutex_enter(&hc_data->hc_mutex); - - return (USB_SUCCESS); -} - -/* Remove Connect Acknowledge IE */ -void -wusb_hc_rm_ack(wusb_hc_data_t *hc_data) -{ - int i; - int16_t iehdl = -1; - wusb_ie_header_t *ieh; - - for (i = 0; i < hc_data->hc_num_mmcies; i++) { - ieh = hc_data->hc_mmcie_list[i]; - if ((ieh != NULL) && - (ieh->bIEIdentifier == WUSB_IE_CONNECTACK)) { - iehdl = (int16_t)i; - - break; - } - } - - if (iehdl == -1) { - USB_DPRINTF_L2(DPRINT_MASK_WHCDI, whcdi_log_handle, - "wusb_hc_rm_ack: ack iehdl not found"); - - return; - } - - /* remove mmc ie and free handle & memory */ - (void) wusb_hc_remove_mmc_ie(hc_data, (uint8_t)iehdl); - wusb_hc_free_iehdl(hc_data, iehdl); - kmem_free(ieh, sizeof (wusb_ie_connect_ack_t)); -} - -/* - * Send a KeepAlive IE to the device. See WUSB 1.0 section 7.5.9 - */ -int -wusb_hc_send_keepalive_ie(wusb_hc_data_t *hc_data, uint8_t addr) -{ - wusb_ie_keepalive_t *alive_ie; - uint8_t iehdl; - int rval; - - mutex_enter(&hc_data->hc_mutex); - /* - * the scheme ensures each time only one device addr - * is set each time - */ - alive_ie = &hc_data->hc_alive_ie; - alive_ie->bDeviceAddress[0] = addr; - /* padding, no active wusb device addr will be 1 */ - alive_ie->bDeviceAddress[1] = 1; - alive_ie->bLength = 4; - - rval = wusb_hc_get_iehdl(hc_data, (wusb_ie_header_t *)alive_ie, - &iehdl); - if (rval != USB_SUCCESS) { - USB_DPRINTF_L2(DPRINT_MASK_WHCDI, whcdi_log_handle, - "wusb_hc_send_keepalive_ie: get ie handle fails"); - mutex_exit(&hc_data->hc_mutex); - - return (rval); - } - - USB_DPRINTF_L2(DPRINT_MASK_WHCDI, whcdi_log_handle, - "wusb_hc_send_keepalive_ie: get ie handle = %d", iehdl); - /* - * we must release the lock so that the DN notification - * thread can update the device active bit - */ - mutex_exit(&hc_data->hc_mutex); - - rval = wusb_hc_add_mmc_ie(hc_data, 0, 0, iehdl, - alive_ie->bLength, (uint8_t *)alive_ie); - if (rval != USB_SUCCESS) { - USB_DPRINTF_L2(DPRINT_MASK_WHCDI, whcdi_log_handle, - "wusb_hc_send_keepalive_ie: add keepalive ie fails"); - - /* no need to free the ack iehdl since it is reused */ - return (rval); - } - - /* - * wait 400ms for the device to reply a DN_Alive notification - */ - delay(drv_usectohz(400000)); - - /* - * cease transmitting the IE and release the IE handle, - * no matter we receive a response or not. - */ - mutex_enter(&hc_data->hc_mutex); - (void) wusb_hc_remove_mmc_ie(hc_data, iehdl); - wusb_hc_free_iehdl(hc_data, iehdl); - mutex_exit(&hc_data->hc_mutex); - - return (USB_SUCCESS); -} - -/* - * Check the hc_cc_list for matching CDID and return the pointer - * to the matched cc. Return NULL if no matching cc is found. - */ -wusb_cc_t * -wusb_hc_cc_matched(wusb_hc_cc_list_t *cc_list, uint8_t *cdid) -{ - wusb_cc_t *cc = NULL, *tcc; - - while (cc_list != NULL) { - tcc = &cc_list->cc; - if (memcmp(tcc->CDID, cdid, 16) == 0) { - cc = tcc; - - break; - } - cc_list = cc_list->next; - } - - return (cc); -} - -/* - * *************************************************************** - * WUSB specific standard device requests, refer to WUSB 1.0/7.3.1 - * *************************************************************** - */ -/* Get WUSB device BOS descr and UWB capability descr */ -int -wusb_get_dev_uwb_descr(wusb_hc_data_t *hc_data, usb_port_t port) -{ - dev_info_t *child_dip; - usba_device_t *child_ud; - wusb_dev_info_t *dev_info; - int rval; - uint8_t *buf; - size_t size, buflen; - - ASSERT(mutex_owned(&hc_data->hc_mutex)); - - USB_DPRINTF_L4(DPRINT_MASK_WHCDI, whcdi_log_handle, - "wusb_get_dev_uwb_descr: port = %d", port); - - dev_info = hc_data->hc_dev_infos[port]; - child_dip = hc_data->hc_children_dips[port]; - if (child_dip == NULL) { - - return (USB_FAILURE); - } - - child_ud = usba_get_usba_device(child_dip); - if (child_ud == NULL) { - - return (USB_FAILURE); - } - - /* only get bos descr the first time */ - if (dev_info->wdev_uwb_descr == NULL) { - mutex_exit(&hc_data->hc_mutex); - rval = wusb_get_bos_cloud(child_dip, child_ud); - if (rval != USB_SUCCESS) { - USB_DPRINTF_L2(DPRINT_MASK_WHCDI, whcdi_log_handle, - "wusb_get_dev_uwb_descr: failed to " - "get bos descriptor"); - - mutex_enter(&hc_data->hc_mutex); - - return (rval); - } - mutex_enter(&hc_data->hc_mutex); - - buf = child_ud->usb_wireless_data->wusb_bos; - buflen = child_ud->usb_wireless_data->wusb_bos_length; - - dev_info->wdev_uwb_descr = kmem_zalloc( - sizeof (usb_uwb_cap_descr_t), KM_SLEEP); - - size = usb_parse_uwb_bos_descr(buf, buflen, - dev_info->wdev_uwb_descr, sizeof (usb_uwb_cap_descr_t)); - - USB_DPRINTF_L4(DPRINT_MASK_WHCDI, whcdi_log_handle, - "wusb_get_dev_uwb_descr: parsed uwb descr size is %d", - (int)size); - if (size < USB_UWB_CAP_DESCR_SIZE) { - kmem_free(dev_info->wdev_uwb_descr, - sizeof (usb_uwb_cap_descr_t)); - dev_info->wdev_uwb_descr = NULL; - - return (USB_FAILURE); - } - - /* store a parsed uwb descriptor */ - child_ud->usb_wireless_data->uwb_descr = - dev_info->wdev_uwb_descr; - } else { - USB_DPRINTF_L3(DPRINT_MASK_WHCDI, whcdi_log_handle, - "wusb_get_dev_uwb_descr: already done"); - } - - return (USB_SUCCESS); -} - -/* Get WUSB device BOS descr cloud, refer to WUSB 1.0/7.4.1 */ -int -wusb_get_bos_cloud(dev_info_t *child_dip, usba_device_t *child_ud) -{ - usb_bos_descr_t *bos_descr; - mblk_t *pdata = NULL; - int rval; - size_t size; - usb_cr_t completion_reason; - usb_cb_flags_t cb_flags; - usb_pipe_handle_t def_ph; - usba_wireless_data_t *wireless_data; - - USB_DPRINTF_L4(DPRINT_MASK_WHCDI, whcdi_log_handle, - "wusb_get_bos_cloud: "); - - bos_descr = (usb_bos_descr_t *)kmem_zalloc(sizeof (usb_bos_descr_t), - KM_SLEEP); - - def_ph = usba_get_dflt_pipe_handle(child_dip); - - if ((rval = usb_pipe_sync_ctrl_xfer(child_dip, def_ph, - USB_DEV_REQ_DEV_TO_HOST | USB_DEV_REQ_TYPE_STANDARD, - USB_REQ_GET_DESCR, - USB_DESCR_TYPE_BOS << 8, - 0, - USB_BOS_DESCR_SIZE, - &pdata, - 0, - &completion_reason, - &cb_flags, - 0)) == USB_SUCCESS) { - - /* this must be true since we didn't allow data underruns */ - if (MBLKL(pdata) != USB_BOS_DESCR_SIZE) { - USB_DPRINTF_L2(DPRINT_MASK_WHCDI, whcdi_log_handle, - "device returned incorrect bos " - "descriptor size."); - - rval = USB_FAILURE; - goto done; - } - - /* - * Parse the bos descriptor - */ - size = usb_parse_bos_descr(pdata->b_rptr, - MBLKL(pdata), bos_descr, - sizeof (usb_bos_descr_t)); - - /* if parse bos descr error, it should return failure */ - if (size == USB_PARSE_ERROR) { - - if (pdata->b_rptr[1] != USB_DESCR_TYPE_BOS) { - USB_DPRINTF_L2(DPRINT_MASK_WHCDI, - whcdi_log_handle, - "device returned incorrect " - "bos descriptor type."); - } - rval = USB_FAILURE; - goto done; - } - - if (bos_descr->wTotalLength < USB_BOS_DESCR_SIZE) { - USB_DPRINTF_L2(DPRINT_MASK_WHCDI, whcdi_log_handle, - "device returned incorrect " - "bos descriptor size."); - - rval = USB_FAILURE; - goto done; - } - - freemsg(pdata); - pdata = NULL; - - /* Now fetch the complete bos cloud */ - if ((rval = usb_pipe_sync_ctrl_xfer(child_dip, def_ph, - USB_DEV_REQ_DEV_TO_HOST | USB_DEV_REQ_TYPE_STANDARD, - USB_REQ_GET_DESCR, - USB_DESCR_TYPE_BOS << 8, - 0, - bos_descr->wTotalLength, - &pdata, - 0, - &completion_reason, - &cb_flags, - 0)) == USB_SUCCESS) { - - if (MBLKL(pdata) != bos_descr->wTotalLength) { - - USB_DPRINTF_L2(DPRINT_MASK_WHCDI, - whcdi_log_handle, - "device returned incorrect " - "bos descriptor cloud."); - - rval = USB_FAILURE; - goto done; - } - - /* - * copy bos descriptor into usba_device - */ - mutex_enter(&child_ud->usb_mutex); - wireless_data = child_ud->usb_wireless_data; - wireless_data->wusb_bos = - kmem_zalloc(bos_descr->wTotalLength, KM_SLEEP); - wireless_data->wusb_bos_length = - bos_descr->wTotalLength; - bcopy((caddr_t)pdata->b_rptr, - (caddr_t)wireless_data->wusb_bos, - bos_descr->wTotalLength); - USB_DPRINTF_L3(DPRINT_MASK_WHCDI, whcdi_log_handle, - "bos_length = %d", - wireless_data->wusb_bos_length); - mutex_exit(&child_ud->usb_mutex); - } - } - -done: - if (rval != USB_SUCCESS) { - USB_DPRINTF_L2(DPRINT_MASK_WHCDI, whcdi_log_handle, - "wusb_get_bos_cloud: " - "error in retrieving bos descriptor, rval=%d cr=%d", - rval, completion_reason); - } - - if (pdata) { - freemsg(pdata); - pdata = NULL; - } - - kmem_free(bos_descr, sizeof (usb_bos_descr_t)); - - return (rval); -} - -/* Get WUSB device security descriptors, refer to WUSB 1.0/7.4.5 */ -int -wusb_get_dev_security_descr(usb_pipe_handle_t ph, - wusb_secrt_data_t *secrt_data) -{ - usb_ctrl_setup_t setup; - mblk_t *pdata = NULL; - usb_cr_t cr; - usb_cb_flags_t cb_flags; - int i, rval; - size_t size, len; - uint8_t *p; - - setup.bmRequestType = USB_DEV_REQ_DEV_TO_HOST; - setup.bRequest = USB_REQ_GET_DESCR; - setup.wValue = USB_DESCR_TYPE_SECURITY << 8; - setup.wIndex = 0; - setup.wLength = USB_SECURITY_DESCR_SIZE; - setup.attrs = USB_ATTRS_NONE; - - rval = usb_pipe_ctrl_xfer_wait(ph, &setup, &pdata, &cr, &cb_flags, - USB_FLAGS_SLEEP); - if (rval != USB_SUCCESS) { - USB_DPRINTF_L2(DPRINT_MASK_WHCDI, whcdi_log_handle, - "wusb_get_dev_security_descr " - "failed, rval = %d, cr = %d", rval, cr); - - return (rval); - } - - if (MBLKL(pdata) != USB_SECURITY_DESCR_SIZE) { - USB_DPRINTF_L2(DPRINT_MASK_WHCDI, whcdi_log_handle, - "received incorrect security descriptor size"); - rval = USB_FAILURE; - - goto done; - } - - /* Parse the security descriptor */ - size = usb_parse_data("ccsc", pdata->b_rptr, - MBLKL(pdata), &secrt_data->secrt_descr, - sizeof (usb_security_descr_t)); - - /* check if the parsed descr is good */ - if (size < USB_SECURITY_DESCR_SIZE) { - rval = USB_FAILURE; - - goto done; - } - - if (secrt_data->secrt_descr.wTotalLength < USB_SECURITY_DESCR_SIZE) { - USB_DPRINTF_L2(DPRINT_MASK_WHCDI, whcdi_log_handle, - "device returned incorrect security descriptor size"); - rval = USB_FAILURE; - - goto done; - } - - freemsg(pdata); - pdata = NULL; - - secrt_data->secrt_n_encry = - secrt_data->secrt_descr.bNumEncryptionTypes; - len = sizeof (usb_encryption_descr_t) * secrt_data->secrt_n_encry; - secrt_data->secrt_encry_descr = - (usb_encryption_descr_t *)kmem_zalloc(len, KM_SLEEP); - - /* Now fetch the complete security descr cloud */ - setup.wLength = secrt_data->secrt_descr.wTotalLength; - rval = usb_pipe_ctrl_xfer_wait(ph, &setup, &pdata, &cr, &cb_flags, - USB_FLAGS_SLEEP); - if (rval != USB_SUCCESS) { - USB_DPRINTF_L2(DPRINT_MASK_WHCDI, whcdi_log_handle, - "wusb_get_dev_security_descr " - "for total cloud failed, rval = %d, cr = %d", rval, cr); - - goto done; - } - - if (MBLKL(pdata) != secrt_data->secrt_descr.wTotalLength) { - USB_DPRINTF_L2(DPRINT_MASK_WHCDI, whcdi_log_handle, - "received incorrect security descriptor cloud size"); - rval = USB_FAILURE; - - goto done; - } - - p = pdata->b_rptr + USB_SECURITY_DESCR_SIZE; - for (i = 0; i < secrt_data->secrt_n_encry; i++) { - size = usb_parse_data("ccccc", p, _PTRDIFF(pdata->b_wptr, p), - &secrt_data->secrt_encry_descr[i], - sizeof (usb_encryption_descr_t)); - if (size < USB_ENCRYPTION_DESCR_SIZE) { - USB_DPRINTF_L2(DPRINT_MASK_WHCDI, whcdi_log_handle, - "parse %dth encryption descr failed", i); - rval = USB_FAILURE; - - goto done; - } - p += USB_ENCRYPTION_DESCR_SIZE; - } - -done: - if (rval != USB_SUCCESS) { - USB_DPRINTF_L2(DPRINT_MASK_WHCDI, whcdi_log_handle, - "wusb_get_dev_security_descr: " - "error in retrieving security descriptors"); - if (secrt_data->secrt_encry_descr) { - kmem_free(secrt_data->secrt_encry_descr, len); - secrt_data->secrt_encry_descr = NULL; - } - } - - if (pdata) { - freemsg(pdata); - pdata = NULL; - } - - return (rval); -} - -/* Get WUSB device status, refer to WUSB 1.0/7.3.1.2 */ -int -wusb_get_dev_status(usb_pipe_handle_t ph, uint16_t selector, - uint16_t len, uint8_t *status) -{ - usb_ctrl_setup_t setup; - mblk_t *pdata = NULL; - usb_cr_t cr; - usb_cb_flags_t cb_flags; - int rval; - - USB_DPRINTF_L4(DPRINT_MASK_WHCDI, whcdi_log_handle, - "wusb_get_dev_status: selector = %d, len = %d", selector, len); - - setup.bmRequestType = USB_DEV_REQ_DEV_TO_HOST; - setup.bRequest = USB_REQ_GET_STATUS; - setup.wValue = 0; - setup.wIndex = selector; - setup.wLength = len; - setup.attrs = USB_ATTRS_NONE; - - rval = usb_pipe_ctrl_xfer_wait(ph, &setup, &pdata, &cr, &cb_flags, - USB_FLAGS_SLEEP); - if (rval != USB_SUCCESS) { - USB_DPRINTF_L2(DPRINT_MASK_WHCDI, whcdi_log_handle, - "wusb_get_dev_status failed, rval = %d, cr = %d", rval, cr); - - return (rval); - } - if (pdata == NULL) { - return (USB_FAILURE); - } - if (MBLKL(pdata) != len) { - USB_DPRINTF_L2(DPRINT_MASK_WHCDI, whcdi_log_handle, - "received incorrect dev status size"); - freemsg(pdata); - - return (USB_FAILURE); - } - - bcopy(pdata->b_rptr, status, len); - freemsg(pdata); - - if ((selector == WUSB_STS_TYPE_MAS_AVAIL) && - (len == WUSB_SET_WUSB_MAS_LEN)) { - uint8_t *p = status; - - USB_DPRINTF_L4(DPRINT_MASK_WHCDI, whcdi_log_handle, - "mas_avail: %x %x %x %x %x %x %x %x %x %x %x %x " - "%x %x %x %x %x %x %x %x %x %x %x %x %x %x %x %x " - "%x %x %x %x", p[0], p[1], p[2], p[3], p[4], p[5], p[6], - p[7], p[8], p[9], p[10], p[11], p[12], p[13], p[14], p[15], - p[16], p[17], p[18], p[19], p[20], p[21], p[22], p[23], - p[24], p[25], p[26], p[27], p[28], p[29], p[30], p[31]); - } - - return (USB_SUCCESS); -} - -/* test function, can be removed */ -void -wusb_test_ctrlreq(usb_pipe_handle_t ph) -{ - int i, rval; - uint8_t mas[WUSB_SET_WUSB_MAS_LEN]; - - for (i = 0; i < 10; i++) { - USB_DPRINTF_L2(DPRINT_MASK_WHCDI, whcdi_log_handle, - "wusb_test_ctrlreq %d started:", i); - rval = wusb_get_dev_status(ph, - WUSB_STS_TYPE_MAS_AVAIL, WUSB_SET_WUSB_MAS_LEN, mas); - if (rval != USB_SUCCESS) { - USB_DPRINTF_L2(DPRINT_MASK_WHCDI, whcdi_log_handle, - "get mas availability status %d failed, " - "rval = %d", i, rval); - - continue; - } - } -} - -/* test function, can be removed */ -void -wusb_test_loopback(usb_pipe_handle_t ph) -{ - usb_ctrl_setup_t setup; - mblk_t *pdata; - usb_cr_t cr; - usb_cb_flags_t cb_flags; - int i, j, rval; - uint16_t len = 20; - - for (j = 0; j < 10; j++) { - pdata = allocb_wait(len, BPRI_LO, STR_NOSIG, NULL); - for (i = 0; i < len; i++) { - *pdata->b_wptr++ = (uint8_t)j; - } - - setup.bmRequestType = USB_DEV_REQ_HOST_TO_DEV; - setup.bRequest = USB_REQ_LOOPBACK_DATA_WRITE; - setup.wValue = 0; - setup.wIndex = 0; - setup.wLength = len; - setup.attrs = USB_ATTRS_NONE; - - USB_DPRINTF_L4(DPRINT_MASK_WHCDI, whcdi_log_handle, - "wusb_test_loopback_write %d start:", j); - - rval = usb_pipe_ctrl_xfer_wait(ph, &setup, &pdata, &cr, - &cb_flags, USB_FLAGS_SLEEP); - if (rval != USB_SUCCESS) { - USB_DPRINTF_L2(DPRINT_MASK_WHCDI, whcdi_log_handle, - "wusb_test_loopback_write %d failed, " - "rval = %d, cr = %d", j, rval, cr); - freemsg(pdata); - - return; - } - - freemsg(pdata); - pdata = NULL; - } -} - -/* test function, can be removed */ -void -wusb_test_write(wusb_dev_info_t *dev_info) -{ - int16_t value; - int i, rval; - usb_pipe_handle_t dev_ph; - - value = wusb_get_ccm_encryption_value(&dev_info->wdev_secrt_data); - if (value == -1) { - USB_DPRINTF_L2(DPRINT_MASK_WHCDI, whcdi_log_handle, - "wusb_test_write: cannot find ccm encryption type"); - - return; - } - /* failed at 2nd write */ - for (i = 0; i < 1; i++) { - USB_DPRINTF_L4(DPRINT_MASK_WHCDI, whcdi_log_handle, - "wusb_test_write %d start:", i); - mutex_enter(&dev_info->wdev_hc->hc_mutex); - dev_ph = dev_info->wdev_ph; - mutex_exit(&dev_info->wdev_hc->hc_mutex); - - rval = wusb_dev_set_encrypt(dev_ph, (uint8_t)value); - if (rval != USB_SUCCESS) { - USB_DPRINTF_L2(DPRINT_MASK_WHCDI, whcdi_log_handle, - "wusb_test_write: %dth set encryption failed", i); - - continue; - } - } -} - - -/* enable CCM encryption on the device */ -int -wusb_enable_dev_encrypt(wusb_hc_data_t *hc_data, wusb_dev_info_t *dev_info) -{ - int16_t value; - int rval; - usb_pipe_handle_t ph; - - USB_DPRINTF_L3(DPRINT_MASK_WHCDI, whcdi_log_handle, - "wusb_enable_dev_encrypt:enter"); - - value = wusb_get_ccm_encryption_value(&dev_info->wdev_secrt_data); - if (value == -1) { - USB_DPRINTF_L2(DPRINT_MASK_WHCDI, whcdi_log_handle, - "wusb_enable_dev_encrypt: cannot find ccm encryption type"); - - return (USB_FAILURE); - } - - mutex_enter(&hc_data->hc_mutex); - ph = dev_info->wdev_ph; - mutex_exit(&hc_data->hc_mutex); - - rval = wusb_dev_set_encrypt(ph, (uint8_t)value); - if (rval != USB_SUCCESS) { - USB_DPRINTF_L2(DPRINT_MASK_WHCDI, whcdi_log_handle, - "wusb_enable_dev_encrypt: set encryption failed"); - } - USB_DPRINTF_L3(DPRINT_MASK_WHCDI, whcdi_log_handle, - "wusb_enable_dev_encrypti:exit"); - - return (rval); -} - -/* - * Perform the authentication process, refer to WUSB 1.0/7.1.2. - * host secrt_data will be used for 4-way handshake - */ -/* ARGSUSED */ -int -wusb_hc_auth_dev(wusb_hc_data_t *hc_data, usb_port_t port, - usb_pipe_handle_t ph, uint8_t ifc, - wusb_secrt_data_t *secrt_data) -{ - wusb_dev_info_t *dev_info; - usb_pipe_handle_t child_ph; - dev_info_t *child_dip; - - ASSERT(mutex_owned(&hc_data->hc_mutex)); - - dev_info = hc_data->hc_dev_infos[port]; - USB_DPRINTF_L2(DPRINT_MASK_WHCDI, whcdi_log_handle, - "wusb_hc_auth_dev: dev addr = %d", dev_info->wdev_addr); - if (dev_info == NULL) { - USB_DPRINTF_L2(DPRINT_MASK_WHCDI, whcdi_log_handle, - "wusb_hc_auth_dev: port %d invalid", port); - - return (USB_INVALID_ARGS); - } - child_ph = dev_info->wdev_ph; - child_dip = hc_data->hc_children_dips[port]; - - mutex_exit(&hc_data->hc_mutex); - /* get device security descrs */ - if (wusb_get_dev_security_descr(child_ph, - &dev_info->wdev_secrt_data) != USB_SUCCESS) { - USB_DPRINTF_L2(DPRINT_MASK_WHCDI, whcdi_log_handle, - "wusb_hc_auth_dev: failed to get device security descrs"); - mutex_enter(&hc_data->hc_mutex); - - return (USB_FAILURE); - } - - /* - * enable CCM encryption on the device, this needs to be done - * before 4-way handshake. [WUSB 1.0/7.3.2.5] - */ - if (wusb_enable_dev_encrypt(hc_data, dev_info) != USB_SUCCESS) { - USB_DPRINTF_L2(DPRINT_MASK_WHCDI, whcdi_log_handle, - "wusb_hc_auth_dev: set encryption failed"); - - mutex_enter(&hc_data->hc_mutex); - return (USB_FAILURE); - } - - - /* this seems to relieve the non-response issue somehow */ - usb_pipe_close(child_dip, child_ph, - USB_FLAGS_SLEEP | USBA_FLAGS_PRIVILEGED, NULL, NULL); - - mutex_enter(&hc_data->hc_mutex); - dev_info->wdev_ph = NULL; - - /* unauthenticated state */ - /* check cc_list for existing cc with the same CDID */ - if ((dev_info->wdev_cc = wusb_hc_cc_matched(hc_data->hc_cc_list, - dev_info->wdev_cdid)) == NULL) { - USB_DPRINTF_L2(DPRINT_MASK_WHCDI, whcdi_log_handle, - "wusb_hc_auth_dev: no matching cc found"); - - if (dev_info->wdev_is_newconn == 0) { - USB_DPRINTF_L2(DPRINT_MASK_WHCDI, whcdi_log_handle, - "wusb_hc_auth_dev: not new connection, " - "just fail"); - - return (USB_FAILURE); - } - - /* now we simply return not supported */ - USB_DPRINTF_L2(DPRINT_MASK_WHCDI, whcdi_log_handle, - "wusb_hc_auth_dev: numeric association not supported"); - - return (USB_NOT_SUPPORTED); - } - - USB_DPRINTF_L3(DPRINT_MASK_WHCDI, whcdi_log_handle, - "wusb_hc_auth_dev: matching cc found 0x%p", - (void *)dev_info->wdev_cc); - - mutex_exit(&hc_data->hc_mutex); - if (usb_pipe_open(child_dip, NULL, NULL, - USB_FLAGS_SLEEP | USBA_FLAGS_PRIVILEGED, &child_ph) != - USB_SUCCESS) { - USB_DPRINTF_L2(DPRINT_MASK_WHCDI, whcdi_log_handle, - "usb_pipe_open failed"); - - mutex_enter(&hc_data->hc_mutex); - - return (USB_FAILURE); - } - - mutex_enter(&hc_data->hc_mutex); - /* recording the default pipe */ - dev_info->wdev_ph = child_ph; - - mutex_exit(&hc_data->hc_mutex); - /* perform 4-way handshake */ - if (wusb_4way_handshake(hc_data, port, ph, ifc) != 0) { - USB_DPRINTF_L2(DPRINT_MASK_WHCDI, whcdi_log_handle, - "port(%d) 4-way handshake authentication failed!", - port); - - /* perhaps resetting the device is better */ - usb_pipe_reset(child_dip, child_ph, - USB_FLAGS_SLEEP | USBA_FLAGS_PRIVILEGED, - NULL, NULL); - (void) wusb_dev_set_encrypt(child_ph, 0); - - mutex_enter(&hc_data->hc_mutex); - - return (USB_FAILURE); - } - - mutex_enter(&hc_data->hc_mutex); - - return (USB_SUCCESS); -} - -/* Acknowledge WUSB Device Disconnect notification, refer to WUSB 1.0/7.6.2 */ -int -wusb_hc_ack_disconn(wusb_hc_data_t *hc_data, uint8_t addr) -{ - wusb_ie_dev_disconnect_t *disconn_ie; - uint8_t iehdl; - int rval; - - ASSERT(mutex_owned(&hc_data->hc_mutex)); - - /* - * the scheme ensures each time only one device addr - * is set each time - */ - disconn_ie = kmem_zalloc(sizeof (wusb_ie_dev_disconnect_t), KM_SLEEP); - if (!disconn_ie) { - return (USB_NO_RESOURCES); - } - - disconn_ie->bIEIdentifier = WUSB_IE_DEV_DISCONNECT; - disconn_ie->bDeviceAddress[0] = addr; - /* padding, no active wusb device addr will be 1 */ - disconn_ie->bDeviceAddress[1] = 1; - disconn_ie->bLength = 4; - - rval = wusb_hc_get_iehdl(hc_data, (wusb_ie_header_t *)disconn_ie, - &iehdl); - if (rval != USB_SUCCESS) { - USB_DPRINTF_L2(DPRINT_MASK_WHCDI, whcdi_log_handle, - "wusb_hc_ack_disconn: get ie handle fails"); - kmem_free(disconn_ie, sizeof (wusb_ie_dev_disconnect_t)); - - return (rval); - } - - rval = wusb_hc_add_mmc_ie(hc_data, 0, 0, iehdl, - disconn_ie->bLength, (uint8_t *)disconn_ie); - if (rval != USB_SUCCESS) { - USB_DPRINTF_L2(DPRINT_MASK_WHCDI, whcdi_log_handle, - "wusb_hc_ack_disconn: add dev disconnect ie fails"); - wusb_hc_free_iehdl(hc_data, iehdl); - kmem_free(disconn_ie, sizeof (wusb_ie_dev_disconnect_t)); - - return (rval); - } - - mutex_exit(&hc_data->hc_mutex); - /* - * WUSB 1.0/7.5.4 requires the IE to be transmitted at least - * 100ms before ceasing, wait for 150ms here - */ - delay(drv_usectohz(150000)); - mutex_enter(&hc_data->hc_mutex); - - /* cease transmitting the IE */ - (void) wusb_hc_remove_mmc_ie(hc_data, (uint8_t)iehdl); - wusb_hc_free_iehdl(hc_data, iehdl); - kmem_free(disconn_ie, sizeof (wusb_ie_dev_disconnect_t)); - - return (USB_SUCCESS); -} - -/* create child devinfo node and usba_device structure */ -int -wusb_create_child_devi(dev_info_t *dip, char *node_name, - usba_hcdi_ops_t *usba_hcdi_ops, dev_info_t *usb_root_hub_dip, - usb_port_status_t port_status, usba_device_t *usba_device, - dev_info_t **child_dip) -{ - ndi_devi_alloc_sleep(dip, node_name, (pnode_t)DEVI_SID_NODEID, - child_dip); - - usba_device = usba_alloc_usba_device(usb_root_hub_dip); - - /* grab the mutex to keep warlock happy */ - mutex_enter(&usba_device->usb_mutex); - usba_device->usb_hcdi_ops = usba_hcdi_ops; - usba_device->usb_port_status = port_status; - usba_device->usb_is_wireless = B_TRUE; - mutex_exit(&usba_device->usb_mutex); - - /* store the usba_device point in the dip */ - usba_set_usba_device(*child_dip, usba_device); - - return (USB_SUCCESS); -} - -/* - * Handle WUSB child device connection, including creating child devinfo - * and usba strutures, authentication, configuration and attach. - */ -int -wusb_hc_handle_port_connect(wusb_hc_data_t *hc_data, usb_port_t port, - usb_pipe_handle_t ph, uint8_t ifc, wusb_secrt_data_t *secrt_data) -{ - dev_info_t *dip = hc_data->hc_dip; - dev_info_t *child_dip = NULL; - usba_device_t *child_ud = NULL; - usba_device_t *parent_ud; - usba_hcdi_t *hcdi = usba_hcdi_get_hcdi(dip); - usb_pipe_handle_t child_ph = NULL; - int rval; - int child_created = 0; - wusb_dev_info_t *dev_info; - usb_dev_descr_t usb_dev_descr; - int ackie_removed = 0; - - USB_DPRINTF_L4(DPRINT_MASK_WHCDI, whcdi_log_handle, - "wusb_hc_handle_port_connect: hc_data=0x%p, port=%d", - (void *)hc_data, port); - - ASSERT(mutex_owned(&hc_data->hc_mutex)); - dev_info = hc_data->hc_dev_infos[port]; - if (dev_info == NULL) { - USB_DPRINTF_L2(DPRINT_MASK_WHCDI, whcdi_log_handle, - "wusb_hc_handle_port_connect: port %d invalid", port); - wusb_hc_rm_ack(hc_data); - - return (USB_INVALID_ARGS); - } - - dev_info->wdev_hc = hc_data; - - /* prepare child devinfo and usba structures */ - if (hc_data->hc_children_dips[port]) { - child_dip = hc_data->hc_children_dips[port]; - child_ud = hc_data->hc_usba_devices[port]; - child_ph = usba_get_dflt_pipe_handle(child_dip); - mutex_exit(&hc_data->hc_mutex); - usb_pipe_close(child_dip, child_ph, - USB_FLAGS_SLEEP | USBA_FLAGS_PRIVILEGED, NULL, NULL); - mutex_enter(&hc_data->hc_mutex); - } else { - rval = wusb_create_child_devi(dip, - "device", - hcdi->hcdi_ops, - dip, - USBA_HIGH_SPEED_DEV, - child_ud, - &child_dip); - if (rval != USB_SUCCESS) { - wusb_hc_rm_ack(hc_data); // , ph, ifc); - - return (rval); - } - child_ud = usba_get_usba_device(child_dip); - ASSERT(child_ud != NULL); - - mutex_enter(&child_ud->usb_mutex); - child_ud->usb_dev_descr = kmem_zalloc(sizeof (usb_dev_descr_t), - KM_SLEEP); - child_ud->usb_wireless_data = - kmem_zalloc(sizeof (usba_wireless_data_t), KM_SLEEP); - mutex_exit(&child_ud->usb_mutex); - child_created = 1; - hc_data->hc_children_dips[port] = child_dip; - hc_data->hc_usba_devices[port] = child_ud; - } - - /* do necessary setup */ - parent_ud = usba_get_usba_device(dip); - mutex_enter(&child_ud->usb_mutex); - child_ud->usb_addr = dev_info->wdev_addr; - child_ud->usb_port = port; - - /* - * TODO: now only consider the situation that HWA is high - * speed dev for the children. The situation that HWA is - * connected to the USB 1.1 port is not considered. The - * available HWA devices can't work behind USB1.1 port. - */ - child_ud->usb_hs_hub_usba_dev = parent_ud; - child_ud->usb_hs_hub_addr = parent_ud->usb_addr; - child_ud->usb_hs_hub_port = port; - bzero(&usb_dev_descr, sizeof (usb_dev_descr_t)); - - /* - * 255 for WUSB devices, refer to WUSB 1.0/4.8.1. - * default ctrl pipe will ignore this value - */ - usb_dev_descr.bMaxPacketSize0 = 255; - bcopy(&usb_dev_descr, child_ud->usb_dev_descr, - sizeof (usb_dev_descr_t)); - mutex_exit(&child_ud->usb_mutex); - - dev_info->wdev_ph = NULL; - - /* - * set device info and encryption mode for the host so that - * open child pipe can work later - */ - rval = wusb_hc_set_device_info(hc_data, port); - if (rval != USB_SUCCESS) { - USB_DPRINTF_L2(DPRINT_MASK_WHCDI, whcdi_log_handle, - "wusb_hc_handle_port_connect: set device info for" - " host failed, rval = %d", rval); - - goto error; - } - - /* set the host to unsecure mode before authentication starts */ - rval = wusb_hc_set_encrypt(hc_data, port, WUSB_ENCRYP_TYPE_UNSECURE); - if (rval != USB_SUCCESS) { - USB_DPRINTF_L2(DPRINT_MASK_WHCDI, whcdi_log_handle, - "wusb_hc_handle_port_connect:set unsecure encryption" - " for host failed, rval = %d", rval); - - goto error; - } - - /* - * Open the default pipe for the child device - * the MaxPacketSize for the default ctrl pipe is - * set in usba_init_pipe_handle(). - */ - mutex_exit(&hc_data->hc_mutex); - if ((rval = usb_pipe_open(child_dip, NULL, NULL, - USB_FLAGS_SLEEP | USBA_FLAGS_PRIVILEGED, &child_ph)) != - USB_SUCCESS) { - USB_DPRINTF_L2(DPRINT_MASK_WHCDI, whcdi_log_handle, - "wusb_hc_handle_port_connect:open default pipe failed (%d)", - rval); - mutex_enter(&hc_data->hc_mutex); - - goto error; - } - mutex_enter(&hc_data->hc_mutex); - - /* recording the default pipe */ - dev_info->wdev_ph = child_ph; - - /* verify the default child pipe works */ - if (wusb_get_dev_uwb_descr(hc_data, port) != USB_SUCCESS) { - USB_DPRINTF_L2(DPRINT_MASK_WHCDI, whcdi_log_handle, - "wusb_hc_handle_port_connect: failed to get" - " device uwb descr"); - - goto error; - } - - /* remove connect acknowledge IE */ - wusb_hc_rm_ack(hc_data); - ackie_removed = 1; - - /* do authentication */ - if (wusb_hc_auth_dev(hc_data, port, ph, ifc, secrt_data) != - USB_SUCCESS) { - USB_DPRINTF_L2(DPRINT_MASK_WHCDI, whcdi_log_handle, - "wusb_hc_handle_port_connect: " - "device authentication fails"); - - goto error; - } - - /* online child */ - if (dev_info->wdev_state == WUSB_STATE_RECONNTING) { - dev_info->wdev_state = WUSB_STATE_CONFIGURED; - /* post reconnect event to child */ - wusb_hc_reconnect_dev(hc_data, port); - } else { - if (wusb_hc_create_child(hc_data, port) != USB_SUCCESS) { - USB_DPRINTF_L2(DPRINT_MASK_WHCDI, whcdi_log_handle, - "wusb_hc_handle_port_connect: create child fails"); - - goto error; - } - dev_info->wdev_state = WUSB_STATE_CONFIGURED; - } - - return (USB_SUCCESS); - -error: - if (dev_info->wdev_ph != NULL) { - mutex_exit(&hc_data->hc_mutex); - usb_pipe_close(child_dip, child_ph, - USB_FLAGS_SLEEP | USBA_FLAGS_PRIVILEGED, NULL, NULL); - mutex_enter(&hc_data->hc_mutex); - - dev_info->wdev_ph = NULL; - } - - if (child_created) { - - rval = usba_destroy_child_devi(child_dip, - NDI_DEVI_REMOVE); - - if (rval != USB_SUCCESS) { - USB_DPRINTF_L2(DPRINT_MASK_WHCDI, whcdi_log_handle, - "wusb_hc_handle_port_connect: " - "failure to remove child node"); - } - - mutex_exit(&hc_data->hc_mutex); - usba_free_usba_device(child_ud); - mutex_enter(&hc_data->hc_mutex); - - hc_data->hc_children_dips[port] = NULL; - hc_data->hc_usba_devices[port] = NULL; - } - - if (ackie_removed == 0) { - wusb_hc_rm_ack(hc_data); - } - - return (USB_FAILURE); -} - -/* - * Handle device connect notification: assign port number, acknowledge - * device connection, and online child - * Refer to WUSB 1.0 4.13, 6.10, 7.1 for connection process handling - * and device state diagram - */ -void -wusb_hc_handle_dn_connect(wusb_hc_data_t *hc_data, usb_pipe_handle_t ph, - uint8_t ifc, uint8_t *data, size_t len, - wusb_secrt_data_t *secrt_data) -{ - wusb_dn_connect_t *dn_con; - uint8_t addr; - wusb_dev_info_t *dev_info = NULL; - usb_port_t port = 0; - uint_t new_alloc = 0; - wusb_secrt_data_t *csecrt_data; - - if (len < WUSB_DN_CONN_PKT_LEN) { - USB_DPRINTF_L2(DPRINT_MASK_WHCDI, whcdi_log_handle, - "wusb_hc_handle_dn_connect: short pkt len %d", (int)len); - - return; - } - - dn_con = (wusb_dn_connect_t *)data; - ASSERT(dn_con->bType == WUSB_DN_CONNECT); - addr = dn_con->bmConnAttributes[0]; - - mutex_enter(&hc_data->hc_mutex); - - /* - * check if the device requesting to connect was ever connected - * and decide connect request type - */ - if (wusb_hc_is_dev_connected(hc_data, dn_con->CDID, &port) == 0) { - /* - * the device with the CDID was not connected. - * It should be a connect or new connect request - */ - if (addr) { - /* - * the device may have been disconnected by the host - * the host expects to see a connect request instead - * of a reconnect request. The reconnect request is - * ignored. - */ - USB_DPRINTF_L2(DPRINT_MASK_WHCDI, whcdi_log_handle, - "wusb_hc_handle_dn_connect: device has " - "disconnected, need to connect again"); - mutex_exit(&hc_data->hc_mutex); - - return; - } - - /* assign port number */ - port = wusb_hc_get_free_port(hc_data); - if (port == 0) { - USB_DPRINTF_L2(DPRINT_MASK_WHCDI, whcdi_log_handle, - "wusb_hc_handle_dn_connect: cannot find " - "a free port for the device connecting"); - mutex_exit(&hc_data->hc_mutex); - - return; - } - - /* initialize dev_info structure */ - dev_info = kmem_zalloc(sizeof (wusb_dev_info_t), KM_SLEEP); - /* unconnected dev addr is 0xff, refer to WUSB 1.0/7.6.1 */ - dev_info->wdev_addr = 0xff; - (void) memcpy(dev_info->wdev_cdid, dn_con->CDID, 16); - dev_info->wdev_state = WUSB_STATE_CONNTING; - hc_data->hc_dev_infos[port] = dev_info; - new_alloc = 1; - } else { - /* - * the device with the CDID was found connected. - * It should be a reconnect or connect request. - */ - dev_info = hc_data->hc_dev_infos[port]; - if ((addr != 0) && (addr == dev_info->wdev_addr)) { - dev_info->wdev_state = WUSB_STATE_RECONNTING; - } else if (addr == 0) { - dev_info->wdev_state = WUSB_STATE_CONNTING; - dev_info->wdev_addr = 0xff; - } else { - USB_DPRINTF_L2(DPRINT_MASK_WHCDI, whcdi_log_handle, - "wusb_hc_handle_dn_connect: reconnecting, but " - "device addr doesn't match"); - mutex_exit(&hc_data->hc_mutex); - - return; - } - - /* - * post removal event to child device before - * reconnecting it - */ - wusb_hc_disconnect_dev(hc_data, port); - } - - dev_info->wdev_beacon_attr = dn_con->bmConnAttributes[1] & - WUSB_DN_CONN_BEACON_MASK; - - /* refer to WUSB 1.0/7.6.1/4.13 for how New Connection bit works */ - if (addr == 0) { - dev_info->wdev_is_newconn = dn_con->bmConnAttributes[1] & - WUSB_DN_CONN_NEW; - } else { - dev_info->wdev_is_newconn = 0; - } - - /* - * state=connting means new dev addr needs to be assigned - * new_alloc=1 means newly allocated dev_info structure needs to - * be freed later if the connection process fails - * To simplify, the assigned address corresponds to the faked - * port number. - */ - if (dev_info->wdev_addr == 0xff) { - dev_info->wdev_addr = port + 0x7f; - } - - /* - * Acknowledge dn connect notification. - * The notif queue scheme will ensure only one ack_ie exists - * at one time. Don't deal with multiple ack_ie elements now - */ - if (wusb_hc_ack_conn(hc_data, port) != USB_SUCCESS) { - USB_DPRINTF_L2(DPRINT_MASK_WHCDI, whcdi_log_handle, - "wusb_hc_handle_dn_connect: acknowledge " - "connection fails"); - - if (new_alloc == 1) { - kmem_free(dev_info, sizeof (wusb_dev_info_t)); - hc_data->hc_dev_infos[port] = NULL; - } else { - dev_info->wdev_state = WUSB_STATE_UNCONNTED; - } - mutex_exit(&hc_data->hc_mutex); - - return; - } - - /* - * Handle device connection according to connect request type - * Connect Acknowledge IE is removed inside the function - */ - if (wusb_hc_handle_port_connect(hc_data, port, ph, ifc, secrt_data) != - USB_SUCCESS) { - char *pathname = kmem_alloc(MAXPATHLEN, KM_NOSLEEP); - - USB_DPRINTF_L2(DPRINT_MASK_WHCDI, whcdi_log_handle, - "wusb_hc_handle_dn_connect: connect port %d fails", port); - - if (new_alloc == 1) { - if (dev_info->wdev_secrt_data.secrt_encry_descr) { - csecrt_data = &dev_info->wdev_secrt_data; - kmem_free(csecrt_data->secrt_encry_descr, - sizeof (usb_encryption_descr_t) * - csecrt_data->secrt_n_encry); - } - if (dev_info->wdev_uwb_descr) { - kmem_free(dev_info->wdev_uwb_descr, - sizeof (usb_uwb_cap_descr_t)); - } - kmem_free(dev_info, sizeof (wusb_dev_info_t)); - hc_data->hc_dev_infos[port] = NULL; - } else { - dev_info->wdev_state = WUSB_STATE_UNCONNTED; - } - mutex_exit(&hc_data->hc_mutex); - - if (pathname) { - /* output error message to syslog */ - cmn_err(CE_WARN, "%s %s%d: Connecting device" - " on WUSB port %d fails", - ddi_pathname(hc_data->hc_dip, pathname), - ddi_driver_name(hc_data->hc_dip), - ddi_get_instance(hc_data->hc_dip), - port); - - kmem_free(pathname, MAXPATHLEN); - } - - return; - } - - mutex_exit(&hc_data->hc_mutex); -} - -/* Handle device disconnect notification, refer to WUSB 1.0/7.6.2 */ -void -wusb_hc_handle_dn_disconnect(wusb_hc_data_t *hc_data, uint8_t addr, - uint8_t *data, size_t len) -{ - wusb_dn_disconnect_t *dn_discon; - usb_port_t port; - - if (len < WUSB_DN_DISCONN_PKT_LEN) { - USB_DPRINTF_L2(DPRINT_MASK_WHCDI, whcdi_log_handle, - "wusb_hc_handle_dn_disconnect: short pkt len %d", - (int)len); - - return; - } - - dn_discon = (wusb_dn_disconnect_t *)data; - ASSERT(dn_discon->bType == WUSB_DN_DISCONNECT); - - mutex_enter(&hc_data->hc_mutex); - - /* send WDEV_DISCONNECT_IE to acknowledge the notification */ - if (wusb_hc_ack_disconn(hc_data, addr) != USB_SUCCESS) { - USB_DPRINTF_L2(DPRINT_MASK_WHCDI, whcdi_log_handle, - "wusb_hc_handle_dn_disconnect: send disconnect ie fails"); - mutex_exit(&hc_data->hc_mutex); - - return; - } - - /* offline the device requesting disconnection */ - if (wusb_hc_is_addr_valid(hc_data, addr, &port)) { - (void) wusb_hc_destroy_child(hc_data, port); - } else { - USB_DPRINTF_L2(DPRINT_MASK_WHCDI, whcdi_log_handle, - "wusb_hc_handle_dn_disconnect: device with addr " - "0x%x not found", addr); - } - - mutex_exit(&hc_data->hc_mutex); -} - -/* post disconnect event to the device driver */ -void -wusb_hc_disconnect_dev(wusb_hc_data_t *hc_data, usb_port_t port) -{ - dev_info_t *dip = hc_data->hc_dip; - - ASSERT(dip != NULL); - - mutex_exit(&hc_data->hc_mutex); - - hc_data->disconnect_dev(dip, port); - - mutex_enter(&hc_data->hc_mutex); -} - -/* post reconnect event to the device driver */ -void -wusb_hc_reconnect_dev(wusb_hc_data_t *hc_data, usb_port_t port) -{ - dev_info_t *dip = hc_data->hc_dip; - - ASSERT(dip != NULL); - - mutex_exit(&hc_data->hc_mutex); - - hc_data->reconnect_dev(dip, port); - - mutex_enter(&hc_data->hc_mutex); -} - -/* configure child device and online it */ -int -wusb_hc_create_child(wusb_hc_data_t *hc_data, usb_port_t port) -{ - dev_info_t *dip = hc_data->hc_dip; - int rval; - - ASSERT(dip != NULL); - - mutex_exit(&hc_data->hc_mutex); - - rval = hc_data->create_child(dip, port); - - mutex_enter(&hc_data->hc_mutex); - - return (rval); -} - -/* offline child device */ -int -wusb_hc_destroy_child(wusb_hc_data_t *hc_data, usb_port_t port) -{ - dev_info_t *dip = hc_data->hc_dip; - int rval; - - ASSERT(dip != NULL); - - mutex_exit(&hc_data->hc_mutex); - - rval = hc_data->destroy_child(dip, port); - - mutex_enter(&hc_data->hc_mutex); - - return (rval); -} - - -/* - * *********************** - * CC management functions - * *********************** - */ - -/* add a CC to the CC list */ -void -wusb_hc_add_cc(wusb_hc_cc_list_t **cc_list, wusb_hc_cc_list_t *new_cc) -{ - wusb_hc_cc_list_t *head; - - USB_DPRINTF_L4(DPRINT_MASK_WHCDI, whcdi_log_handle, - "wusb_hc_add_cc: cc_list = 0x%p, new_cc = 0x%p", - (void *)cc_list, (void *)new_cc); - - if (new_cc == NULL) { - - return; - } - - if (*cc_list == NULL) { - *cc_list = new_cc; - - return; - } - - head = *cc_list; - while (head != NULL) { - /* update an existing CC */ - if (memcmp(head->cc.CDID, new_cc->cc.CDID, 16) == 0) { - (void) memcpy(head->cc.CK, new_cc->cc.CK, 16); - kmem_free(new_cc, sizeof (wusb_hc_cc_list_t)); - - return; - } - - /* add a new CC */ - if (head->next == NULL) { - head->next = new_cc; - - return; - } - - head = head->next; - } -} - -/* remove a CC from the CC list */ -void -wusb_hc_rem_cc(wusb_hc_cc_list_t **cc_list, wusb_cc_t *old_cc) -{ - wusb_cc_t *cc; - wusb_hc_cc_list_t *prev, *next; - - if (*cc_list == NULL || old_cc == NULL) { - - return; - } - - prev = *cc_list; - cc = &prev->cc; - if (memcmp(cc, old_cc, sizeof (wusb_cc_t)) == 0) { - *cc_list = prev->next; - kmem_free(prev, sizeof (wusb_hc_cc_list_t)); - - return; - } - next = prev->next; - while (next != NULL) { - cc = &next->cc; - if (memcmp(cc, old_cc, sizeof (wusb_cc_t)) == 0) { - prev->next = next->next; - kmem_free(next, sizeof (wusb_hc_cc_list_t)); - - return; - } - prev = next; - next = prev->next; - } -} - -/* remove all CCs from the list */ -void -wusb_hc_free_cc_list(wusb_hc_cc_list_t *cc_list) -{ - wusb_hc_cc_list_t *list, *next; - - list = cc_list; - while (list != NULL) { - next = list->next; - kmem_free(list, sizeof (wusb_hc_cc_list_t)); - list = next; - } -} - -/* Send Host Disconnect notification */ -int -wusb_hc_send_host_disconnect(wusb_hc_data_t *hc_data) -{ - wusb_ie_host_disconnect_t *disconn_ie; - uint8_t iehdl; - int rval; - - disconn_ie = kmem_zalloc(sizeof (wusb_ie_host_disconnect_t), KM_SLEEP); - disconn_ie->bIEIdentifier = WUSB_IE_HOST_DISCONNECT; - disconn_ie->bLength = sizeof (wusb_ie_host_disconnect_t); - - mutex_enter(&hc_data->hc_mutex); - rval = wusb_hc_get_iehdl(hc_data, (wusb_ie_header_t *)disconn_ie, - &iehdl); - mutex_exit(&hc_data->hc_mutex); - if (rval != USB_SUCCESS) { - USB_DPRINTF_L2(DPRINT_MASK_WHCDI, whcdi_log_handle, - "wusb_hc_send_host_disconnect: get ie handle fails"); - kmem_free(disconn_ie, sizeof (wusb_ie_host_disconnect_t)); - - return (rval); - } - - rval = wusb_hc_add_mmc_ie(hc_data, 0, 0, iehdl, - disconn_ie->bLength, (uint8_t *)disconn_ie); - if (rval != USB_SUCCESS) { - USB_DPRINTF_L2(DPRINT_MASK_WHCDI, whcdi_log_handle, - "wusb_hc_send_host_disconnect: add host " - "disconnect ie fails"); - mutex_enter(&hc_data->hc_mutex); - wusb_hc_free_iehdl(hc_data, iehdl); - mutex_exit(&hc_data->hc_mutex); - kmem_free(disconn_ie, sizeof (wusb_ie_host_disconnect_t)); - - return (rval); - } - - delay(drv_usectohz(100000)); /* WUSB 1.0/7.5.5 */ - - mutex_enter(&hc_data->hc_mutex); - (void) wusb_hc_remove_mmc_ie(hc_data, iehdl); - wusb_hc_free_iehdl(hc_data, iehdl); - mutex_exit(&hc_data->hc_mutex); - - kmem_free(disconn_ie, sizeof (wusb_ie_host_disconnect_t)); - - return (USB_SUCCESS); -} - -/* Get RC dev_t by HC dip */ -int -wusb_get_rc_dev_by_hc(dev_info_t *dip, dev_t *dev) -{ - dev_info_t *pdip = ddi_get_parent(dip); - dev_info_t *rcdip; - int found = 0; - major_t major; - minor_t minor; - int inst; - - if (strcmp(ddi_driver_name(dip), "whci") == 0) { - /* For WHCI, RC and HC share the same dip */ - rcdip = dip; - inst = ddi_get_instance(rcdip); - /* need to change when whci driver is ready */ - minor = inst; - found = 1; - } else { - /* For HWA, RC and HC share the same parent dip */ - rcdip = ddi_get_child(pdip); - while (rcdip != NULL) { - if (strcmp(ddi_driver_name(rcdip), "hwarc") == 0) { - found = 1; - inst = ddi_get_instance(rcdip); - // minor = HWAHC_CONSTRUCT_MINOR(inst); - /* - * now hwarc driver uses inst# as minor#. - * this may change - */ - minor = inst; - - break; - } - rcdip = ddi_get_next_sibling(rcdip); - } - } - - if (found == 0) { - *dev = 0; - - return (USB_FAILURE); - } - - major = ddi_driver_major(rcdip); - *dev = makedevice(major, minor); - - USB_DPRINTF_L3(DPRINT_MASK_WHCDI, whcdi_log_handle, - "wusb_get_rc_dev_by_hc: rc device(%s%d) major = %d, minor = %d", - ddi_driver_name(rcdip), inst, major, minor); - - return (USB_SUCCESS); -} - -/* format nonce to a buffer according to WUSB Table 6-3 */ -static void -nonce_to_buf(wusb_ccm_nonce_t *nonce, uchar_t *nbuf, int sfn_only) -{ - int i, offset; - uchar_t *p = nbuf; - - for (i = 0, offset = 0; i < 6; i++, offset += 8) { - *p++ = (nonce->sfn >> offset) & 0xff; - } - - if (sfn_only) { - - return; - } - - *p++ = (nonce->tkid) & 0xff; - *p++ = (nonce->tkid >> 8) & 0xff; - *p++ = (nonce->tkid >> 16) & 0xff; - - *p++ = (nonce->daddr) & 0xff; - *p++ = (nonce->daddr >> 8) & 0xff; - - *p++ = (nonce->saddr) & 0xff; - *p++ = (nonce->saddr >> 8) & 0xff; -} - -/* Call the crypto framework to compute CCM MAC data */ -static int -wusb_ccm_mac( - CK_AES_CCM_PARAMS *ccm_params, - const uchar_t *key, size_t klen, - uchar_t *out, int olen) -{ - crypto_mechanism_t mech; - crypto_key_t crkey; - crypto_context_t ctx; - crypto_data_t dmac; - int ret; - - bzero(&crkey, sizeof (crkey)); - crkey.ck_format = CRYPTO_KEY_RAW; - crkey.ck_data = (char *)key; - crkey.ck_length = klen * 8; - - mech.cm_type = crypto_mech2id(SUN_CKM_AES_CCM); - mech.cm_param = (caddr_t)ccm_params; - mech.cm_param_len = sizeof (CK_AES_CCM_PARAMS); - - if ((ret = crypto_encrypt_init(&mech, &crkey, NULL, &ctx, NULL)) != - CRYPTO_SUCCESS) { - - return (ret); - } - - /* - * Since we've known the encrypted data is none (l(m) = 0), - * the middle procedure crypto_encrypt_update() is ignored. - * The last 8-byte MAC is calculated directly. - */ - - bzero(&dmac, sizeof (dmac)); - dmac.cd_format = CRYPTO_DATA_RAW; - dmac.cd_offset = 0; - dmac.cd_length = olen; - dmac.cd_raw.iov_base = (char *)out; - dmac.cd_raw.iov_len = olen; - - if ((ret = crypto_encrypt_final(ctx, &dmac, NULL)) != CRYPTO_SUCCESS) { - - return (ret); - } - - return (CRYPTO_SUCCESS); -} - -/* Pseudo-Random Function according to WUSB 1.0/6.5 */ -int -PRF(const uchar_t *key, size_t klen, - wusb_ccm_nonce_t *nonce, - const uchar_t *adata, size_t alen, - const uchar_t *bdata, size_t blen, - uchar_t *out, - size_t bitlen) -{ - CK_AES_CCM_PARAMS ccm_params; - uchar_t *ab; - uchar_t nbuf[CCM_NONCE_LEN]; - size_t lm, la; - int i, offset, ret; - - /* from WUSB 6.4 */ - lm = 0; - la = alen + blen; - ab = (uchar_t *)kmem_alloc(la, KM_SLEEP); - bcopy(adata, ab, alen); - bcopy(bdata, ab + alen, blen); - - nonce_to_buf(nonce, nbuf, 0); - - ccm_params.ulMACSize = CCM_MAC_LEN; - ccm_params.ulNonceSize = CCM_NONCE_LEN; - ccm_params.nonce = nbuf; - ccm_params.ulAuthDataSize = la; /* l(a) */ - ccm_params.authData = ab; - ccm_params.ulDataSize = lm; /* l(m) */ - - offset = 0; - for (i = 0; i < (bitlen + 63)/64; i++) { - ret = wusb_ccm_mac(&ccm_params, key, klen, - out + offset, CCM_MAC_LEN); - - if (ret != CRYPTO_SUCCESS) { - kmem_free(ab, la); - - return (ret); - }; - - offset += CCM_MAC_LEN; - nonce->sfn++; - nonce_to_buf(nonce, nbuf, 1); - } - - kmem_free(ab, la); - - return (CRYPTO_SUCCESS); -} - -/* rbuf is a 16-byte buffer to store the random nonce */ -int -wusb_gen_random_nonce(wusb_hc_data_t *hc_data, - wusb_dev_info_t *dev_info, uchar_t *rbuf) -{ - usba_device_t *udev = usba_get_usba_device(hc_data->hc_dip); - wusb_ccm_nonce_t n; - uint16_t vid, pid; - uint64_t ht; - uint8_t kbuf[16], *p; - uchar_t a[] = "Random Numbers"; - - n.sfn = 0; - n.tkid = dev_info->wdev_tkid[0] | (dev_info->wdev_tkid[1] << 8) | - (dev_info->wdev_tkid[2] << 16); - n.daddr = hc_data->hc_addr; - n.saddr = dev_info->wdev_addr; - - vid = udev->usb_dev_descr->idVendor; - pid = udev->usb_dev_descr->idProduct; - ht = gethrtime(); - - p = kbuf; - bcopy((uint8_t *)&vid, p, sizeof (uint16_t)); - p += sizeof (uint16_t); - - bcopy((uint8_t *)&pid, p, sizeof (uint16_t)); - p += sizeof (uint16_t); - - bcopy((uint8_t *)&p, p, sizeof (uint32_t)); - p += sizeof (uint32_t); - - bcopy((uint8_t *)&ht, p, sizeof (uint64_t)); - - return (PRF_128(kbuf, 16, &n, a, sizeof (a), - (uchar_t *)hc_data, sizeof (wusb_hc_data_t), rbuf)); -} - -/* Set WUSB device encryption type, refer to WUSB 1.0/7.3.2.2 */ -int -wusb_dev_set_encrypt(usb_pipe_handle_t ph, uint8_t value) -{ - usb_ctrl_setup_t setup; - usb_cr_t cr; - usb_cb_flags_t cb_flags; - - setup.bmRequestType = USB_DEV_REQ_HOST_TO_DEV; - setup.bRequest = USB_REQ_SET_ENCRYPTION; - setup.wValue = value; - setup.wIndex = 0; - setup.wLength = 0; - setup.attrs = USB_ATTRS_NONE; - - return (usb_pipe_ctrl_xfer_wait(ph, &setup, NULL, - &cr, &cb_flags, USB_FLAGS_SLEEP)); -} - -/* - * Set WUSB device key descriptor, refer to WUSB 1.0/7.3.2.4 - * ph - Device's default control pipe - * key_index - Key Index - */ -int -wusb_dev_set_key(usb_pipe_handle_t ph, uint8_t key_index, - usb_key_descr_t *key, size_t klen) -{ - usb_ctrl_setup_t setup; - usb_cr_t cr; - usb_cb_flags_t cb_flags; - mblk_t *pdata; - int rval; - - setup.bmRequestType = USB_DEV_REQ_HOST_TO_DEV; - setup.bRequest = USB_REQ_SET_DESCR; - setup.wValue = (USB_DESCR_TYPE_KEY << 8) | key_index; - setup.wIndex = 0; - setup.wLength = (uint16_t)klen; - setup.attrs = USB_ATTRS_NONE; - - if ((pdata = allocb(klen, BPRI_HI)) == NULL) { - - return (USB_FAILURE); - } - bcopy(key, pdata->b_wptr, klen); - pdata->b_wptr += klen; - - rval = usb_pipe_ctrl_xfer_wait(ph, &setup, &pdata, - &cr, &cb_flags, USB_FLAGS_SLEEP); - - freemsg(pdata); - - return (rval); -} - -/* - * Set encryption type for the specified device. - */ -int -wusb_hc_set_encrypt(wusb_hc_data_t *hc_data, usb_port_t port, uint8_t type) -{ - dev_info_t *dip = hc_data->hc_dip; - int rval; - - if ((rval = hc_data->set_encrypt(dip, port, type)) != USB_SUCCESS) { - USB_DPRINTF_L2(DPRINT_MASK_WHCDI, whcdi_log_handle, - "wusb_hc_set_encrypt: set encryption type %d " - "for port %d failed, rval = %d", type, port, rval); - } - - return (rval); -} - -/* - * Set Device Key for WUSB host, refer to WUSB 1.0/8.5.3.8 - * Call the HC's specific set_ptk function to set PTK for a device - * len: length of key_data - */ -int -wusb_hc_set_ptk(wusb_hc_data_t *hc_data, uint8_t *key_data, usb_port_t port) -{ - dev_info_t *dip = hc_data->hc_dip; - wusb_dev_info_t *dev_info = hc_data->hc_dev_infos[port]; - usb_key_descr_t *key_descr; - size_t klen; - int rval; - uint8_t *p; - - ASSERT(mutex_owned(&hc_data->hc_mutex)); - - if ((key_data == NULL) || (dev_info == NULL)) { - - return (USB_INVALID_ARGS); - } - - klen = sizeof (usb_key_descr_t) + 15; - key_descr = kmem_zalloc(klen, KM_SLEEP); - - key_descr->bLength = (uint16_t)klen; - key_descr->bDescriptorType = USB_DESCR_TYPE_KEY; - (void) memcpy(key_descr->tTKID, dev_info->wdev_tkid, 3); - p = &key_descr->KeyData[0]; - (void) memcpy(p, key_data, 16); - - mutex_exit(&hc_data->hc_mutex); - - if ((rval = hc_data->set_ptk(dip, key_descr, klen, port)) != - USB_SUCCESS) { - USB_DPRINTF_L2(DPRINT_MASK_WHCDI, whcdi_log_handle, - "wusb_hc_set_pkt: set ptk for port %d failed", port); - } - - kmem_free(key_descr, klen); - mutex_enter(&hc_data->hc_mutex); - - return (rval); -} - -/* - * Set GTK for a host - * Call HC's specific set_gtk function - * - * Default gtk is set at hc_initial_start, and to be changed whenever - * a device leaves the current group (refer to WUSB spec 6.2.11.2) - */ -int -wusb_hc_set_gtk(wusb_hc_data_t *hc_data, uint8_t *key_data, uint8_t *tkid) -{ - dev_info_t *dip = hc_data->hc_dip; - usb_key_descr_t *key_descr; - size_t klen; - int rval; - uint8_t *p; - - if ((key_data == NULL) || (tkid == NULL)) { - - return (USB_INVALID_ARGS); - } - - klen = sizeof (usb_key_descr_t) + 15; - key_descr = kmem_zalloc(klen, KM_SLEEP); - - key_descr->bLength = (uint16_t)klen; - key_descr->bDescriptorType = USB_DESCR_TYPE_KEY; - (void) memcpy(key_descr->tTKID, tkid, 3); - p = &key_descr->KeyData[0]; - (void) memcpy(p, key_data, 16); - - if ((rval = hc_data->set_gtk(dip, key_descr, klen)) != - USB_SUCCESS) { - USB_DPRINTF_L2(DPRINT_MASK_WHCDI, whcdi_log_handle, - "wusb_hc_set_gkt: set gtk failed"); - } - - (void) memcpy(&hc_data->hc_gtk, key_descr, klen); - kmem_free(key_descr, klen); - - return (rval); -} - -/* Set Device Info for WUSB host, refer to WUSB 1.0/8.5.3.7 */ -int -wusb_hc_set_device_info(wusb_hc_data_t *hc_data, usb_port_t port) -{ - wusb_dev_info_t *dev_info; - int rval; - - USB_DPRINTF_L4(DPRINT_MASK_WHCDI, whcdi_log_handle, - "wusb_hc_set_device_info: port = %d", port); - - dev_info = hc_data->hc_dev_infos[port]; - rval = hc_data->set_device_info(hc_data->hc_dip, dev_info, port); - if (rval != USB_SUCCESS) { - USB_DPRINTF_L2(DPRINT_MASK_WHCDI, whcdi_log_handle, - "wusb_hc_set_device_info: the host failed to set " - "device info, rval = %d", rval); - } - - return (rval); -} - -/* - * Set/Get Handshake Data to/from WUSB device, refer to WUSB 1.0/7.3.2.5 - * step = 1, 2, 3 - */ -int -wusb_handshake(usb_pipe_handle_t pipe, wusb_hndshk_data_t *hs, int step) -{ - usb_ctrl_setup_t setup; - mblk_t *pdata; - usb_cr_t cr; - usb_cb_flags_t cb_flags; - int rval; - - if (step == 2) { - /* get handshake */ - setup.bmRequestType = USB_DEV_REQ_DEV_TO_HOST; - setup.bRequest = USB_REQ_GET_HANDSHAKE; - pdata = NULL; - } else if ((step == 1) || (step == 3)) { - /* set handshake */ - setup.bmRequestType = USB_DEV_REQ_HOST_TO_DEV; - setup.bRequest = USB_REQ_SET_HANDSHAKE; - - if ((pdata = allocb(WUSB_HNDSHK_DATA_LEN, BPRI_HI)) == NULL) { - - return (USB_NO_RESOURCES); - } - bcopy(hs, pdata->b_wptr, WUSB_HNDSHK_DATA_LEN); - pdata->b_wptr += WUSB_HNDSHK_DATA_LEN; - } else { - /* step value is invalid */ - return (USB_INVALID_ARGS); - } - - setup.wValue = (uint16_t)step; - setup.wIndex = 0; - setup.wLength = WUSB_HNDSHK_DATA_LEN; - setup.attrs = USB_ATTRS_NONE; - - rval = usb_pipe_ctrl_xfer_wait(pipe, &setup, &pdata, - &cr, &cb_flags, USB_FLAGS_SLEEP); - - if (step == 2) { - if (pdata) { - bcopy(pdata->b_rptr, hs, msgsize(pdata)); - freemsg(pdata); - } - } else { - freemsg(pdata); - } - - return (rval); -} - -/* search the security descrs for CCM encryption type descr */ -int16_t -wusb_get_ccm_encryption_value(wusb_secrt_data_t *secrt_data) -{ - usb_encryption_descr_t *encry_descr; - int i; - int16_t value = -1; - - for (i = 0; i < secrt_data->secrt_n_encry; i++) { - encry_descr = &secrt_data->secrt_encry_descr[i]; - if (encry_descr->bEncryptionType == USB_ENC_TYPE_CCM_1) { - value = encry_descr->bEncryptionValue; - USB_DPRINTF_L3(DPRINT_MASK_WHCDI, whcdi_log_handle, - "ccm encryption value is %d", value); - - break; - } - } - - return (value); -} - -static void -wusb_print_handshake_data(wusb_hndshk_data_t *hs, int step) -{ - uint8_t *p; - - USB_DPRINTF_L3(DPRINT_MASK_WHCDI, whcdi_log_handle, - "handshake %d data:", step); - USB_DPRINTF_L3(DPRINT_MASK_WHCDI, whcdi_log_handle, - "%x %x (TKID)%x %x %x %x", hs->bMessageNumber, hs->bStatus, - hs->tTKID[0], hs->tTKID[1], hs->tTKID[2], hs->bReserved); - - p = hs->CDID; - - USB_DPRINTF_L3(DPRINT_MASK_WHCDI, whcdi_log_handle, - "(CDID)%x %x %x %x %x %x %x %x %x %x %x %x %x %x %x %x", - p[0], p[1], p[2], p[3], p[4], p[5], p[6], p[7], p[8], p[9], - p[10], p[11], p[12], p[13], p[14], p[15]); - - p = hs->Nonce; - USB_DPRINTF_L3(DPRINT_MASK_WHCDI, whcdi_log_handle, - "(Nonce)%x %x %x %x %x %x %x %x %x %x %x %x %x %x %x %x", - p[0], p[1], p[2], p[3], p[4], p[5], p[6], p[7], p[8], p[9], - p[10], p[11], p[12], p[13], p[14], p[15]); - - p = hs->MIC; - USB_DPRINTF_L3(DPRINT_MASK_WHCDI, whcdi_log_handle, - "(MIC)%x %x %x %x %x %x %x %x", - p[0], p[1], p[2], p[3], p[4], p[5], p[6], p[7]); -} - -/* ARGSUSED */ -/* - * Do 4way handshake and other necessary control operations to - * transit the device to authenticated state - * refer to WUSB 1.0 [7.3.2.5, 6.2.10.9.1, 7.1.2] - * ph - pipe handle of the host controller - */ -int -wusb_4way_handshake(wusb_hc_data_t *hc_data, usb_port_t port, - usb_pipe_handle_t ph, uint8_t ifc) -{ - uint8_t tkid[3]; - wusb_ccm_nonce_t n; - wusb_hndshk_data_t *hs; - wusb_dev_info_t *dev_info; - wusb_cc_t *cc; - uchar_t adata1[] = "Pair-wise keys"; - uchar_t adata2[] = "out-of-bandMIC"; - uchar_t bdata[32], keyout[32], mic[8]; - int rval; - usb_pipe_handle_t w_ph; - - USB_DPRINTF_L4(DPRINT_MASK_WHCDI, whcdi_log_handle, - "wusb_4way_handshake: port = %d", port); - - mutex_enter(&hc_data->hc_mutex); - dev_info = hc_data->hc_dev_infos[port]; - if (dev_info == NULL) { - mutex_exit(&hc_data->hc_mutex); - - return (USB_FAILURE); - } - cc = dev_info->wdev_cc; - if (dev_info->wdev_ph == NULL || cc == NULL) { - mutex_exit(&hc_data->hc_mutex); - - return (USB_FAILURE); - } - - w_ph = dev_info->wdev_ph; - - hs = (wusb_hndshk_data_t *)kmem_zalloc( - 3 * sizeof (wusb_hndshk_data_t), KM_SLEEP); - - /* tkid is generated dynamically and saved in dev_info */ - (void) random_get_pseudo_bytes(tkid, 3); - - (void) memcpy(dev_info->wdev_tkid, tkid, 3); - - /* handshake 1 */ - hs[0].bMessageNumber = 1; - hs[0].bStatus = 0; - (void) memcpy(hs[0].tTKID, tkid, 3); - hs[0].bReserved = 0; - bcopy(cc->CDID, hs[0].CDID, WUSB_CDID_LEN); - - if ((rval = wusb_gen_random_nonce(hc_data, dev_info, hs[0].Nonce)) - != USB_SUCCESS) { - USB_DPRINTF_L2(DPRINT_MASK_WHCDI, whcdi_log_handle, - "Nonce generation failed: %d", rval); - mutex_exit(&hc_data->hc_mutex); - - goto done; - } - - wusb_print_handshake_data(&hs[0], 1); - USB_DPRINTF_L4(DPRINT_MASK_WHCDI, whcdi_log_handle, - "wusb_4way_handshake: shake 1............."); - - mutex_exit(&hc_data->hc_mutex); - rval = wusb_handshake(w_ph, &(hs[0]), 1); - if (rval != USB_SUCCESS) { - USB_DPRINTF_L2(DPRINT_MASK_WHCDI, whcdi_log_handle, - "handshake 1 failed, rval = %d", rval); - - goto done; - } - - /* handshake 2 */ - USB_DPRINTF_L4(DPRINT_MASK_WHCDI, whcdi_log_handle, - "wusb_4way_handshake: shake 2............."); - rval = wusb_handshake(w_ph, &(hs[1]), 2); - if (rval != USB_SUCCESS) { - USB_DPRINTF_L2(DPRINT_MASK_WHCDI, whcdi_log_handle, - "handshake 2 failed, rval = %d", rval); - - goto done; - } - - if (hs[1].bMessageNumber != 2 || hs[1].bStatus != 0) { - rval = USB_FAILURE; - - goto done; - } - - wusb_print_handshake_data(&hs[1], 2); - - /* derived session keys, refer to WUSB 1.0/6.5.1 */ - n.sfn = 0; - n.tkid = tkid[0] | (tkid[1]<<8) | (tkid[2] << 16); - - mutex_enter(&hc_data->hc_mutex); - n.daddr = dev_info->wdev_addr; - - n.saddr = hc_data->hc_addr; - bcopy(hs[0].Nonce, bdata, 16); - bcopy(hs[1].Nonce, bdata + 16, 16); - mutex_exit(&hc_data->hc_mutex); - - rval = PRF_256(cc->CK, 16, &n, adata1, 14, bdata, 32, keyout); - if (rval != 0) { - USB_DPRINTF_L2(DPRINT_MASK_WHCDI, whcdi_log_handle, - "compute keys failed, rval = %d", rval); - - goto done; - } - - /* sfn was changed in PRF(). Need to reset it to 0 */ - n.sfn = 0; - - /* used the derived KCK to verify received MIC (WUSB 1.0/6.5.2] */ - rval = PRF_64(keyout, 16, &n, adata2, 14, (uchar_t *)(&hs[1]), - WUSB_HNDSHK_DATA_LEN - 8, mic); - if (rval != 0) { - USB_DPRINTF_L2(DPRINT_MASK_WHCDI, whcdi_log_handle, - "compute MIC failed, rval = %d", rval); - - goto done; - } - - if (memcmp(hs[1].MIC, mic, 8) != 0) { - USB_DPRINTF_L2(DPRINT_MASK_WHCDI, whcdi_log_handle, - "verify mic failed"); - rval = USB_FAILURE; - - goto done; - } - - /* handshake 3 */ - bcopy(&hs[0], &hs[2], WUSB_HNDSHK_DATA_LEN - 8); - hs[2].bMessageNumber = 3; - n.sfn = 0; - rval = PRF_64(keyout, 16, &n, adata2, 14, (uchar_t *)(&hs[2]), - WUSB_HNDSHK_DATA_LEN - 8, hs[2].MIC); - if (rval != 0) { - goto done; - } - - wusb_print_handshake_data(&hs[2], 3); - - USB_DPRINTF_L4(DPRINT_MASK_WHCDI, whcdi_log_handle, - "wusb_4way_handshake: shake 3............."); - rval = wusb_handshake(w_ph, &(hs[2]), 3); - if (rval != USB_SUCCESS) { - USB_DPRINTF_L2(DPRINT_MASK_WHCDI, whcdi_log_handle, - "handshake 3 failed, rval = %d", rval); - - goto done; - } - - mutex_enter(&hc_data->hc_mutex); - /* set PTK for host */ - (void) memcpy(dev_info->wdev_ptk, keyout + 16, 16); - - USB_DPRINTF_L4(DPRINT_MASK_WHCDI, whcdi_log_handle, - "wusb_4way_handshake: set ptk ............."); - rval = wusb_hc_set_ptk(hc_data, dev_info->wdev_ptk, port); - mutex_exit(&hc_data->hc_mutex); - if (rval != USB_SUCCESS) { - USB_DPRINTF_L2(DPRINT_MASK_WHCDI, whcdi_log_handle, - "set ptk for host failed, rval = %d", rval); - - goto done; - } - - /* - * enable CCM encryption on the host - * according to WUSB 1.0/7.1.2, the encryption mode must be - * enabled before setting GTK onto device - */ - USB_DPRINTF_L4(DPRINT_MASK_WHCDI, whcdi_log_handle, - "wusb_4way_handshake: hc set encrypt ............."); - rval = wusb_hc_set_encrypt(hc_data, port, WUSB_ENCRYP_TYPE_CCM_1); - if (rval != USB_SUCCESS) { - USB_DPRINTF_L2(DPRINT_MASK_WHCDI, whcdi_log_handle, - "set encryption for host failed, rval = %d", rval); - - goto done; - } - - /* - * set GTK for device - * GTK is initialized when hc_data is inited - */ - rval = wusb_dev_set_key(w_ph, 2 << 4, - &hc_data->hc_gtk, hc_data->hc_gtk.bLength); -done: - kmem_free(hs, 3 * sizeof (wusb_hndshk_data_t)); - if (rval != USB_SUCCESS) { - /* restore the host to unsecure mode */ - (void) wusb_hc_set_encrypt(hc_data, port, - WUSB_ENCRYP_TYPE_UNSECURE); - } - - return (rval); -} diff --git a/usr/src/uts/common/io/uwb/uwba/uwba.c b/usr/src/uts/common/io/uwb/uwba/uwba.c deleted file mode 100644 index 81c6d50347..0000000000 --- a/usr/src/uts/common/io/uwb/uwba/uwba.c +++ /dev/null @@ -1,1374 +0,0 @@ -/* - * 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 - * or http://www.opensolaris.org/os/licensing. - * 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. - */ - -/* - * This file is for uwba private functions - */ - -#include <sys/uwb/uwba/uwba.h> - -uint_t uwba_errlevel = UWBA_LOG_CONSOLE; - -static kmutex_t uwba_mutex; - -/* list for uwba_dev, the radio host devices */ -static list_t uwba_dev_list; - -/* modload support */ -extern struct mod_ops mod_miscops; - -static struct modlmisc modlmisc = { - &mod_miscops, /* Type of module */ - "UWBA: UWB Architecture" -}; - -static struct modlinkage modlinkage = { - MODREV_1, (void *)&modlmisc, NULL -}; - -_NOTE(SCHEME_PROTECTS_DATA("unique per call", uwba_client_dev)) -_NOTE(SCHEME_PROTECTS_DATA("unique per call", uwb_notif_wrapper)) -/* This table is for data decode */ -uwba_evt_size_t uwba_evt_size_table[] = { - [UWB_NOTIF_IE_RECEIVED] = { - .struct_len = UWB_RESULT_CODE_SIZE, - .buf_len_offset = 6 - }, - [UWB_NOTIF_BEACON_RECEIVED] = { - .struct_len = sizeof (uwb_rceb_beacon_t), - .buf_len_offset = UWB_BEACONINFOLEN_OFFSET - }, - [UWB_NOTIF_BEACON_SIZE_CHANGE] = { - .struct_len = sizeof (uwb_rceb_beacon_size_change_t), - .buf_len_offset = UWB_EVT_NO_BUF_LEN_OFFSET - }, - [UWB_NOTIF_BPOIE_CHANGE] = { - .struct_len = sizeof (uwb_rceb_bpoie_change_t), - .buf_len_offset = UWB_EVT_NO_BUF_LEN_OFFSET - }, - [UWB_NOTIF_BP_SLOT_CHANGE] = { - .struct_len = sizeof (uwb_rceb_bp_slot_change_t), - .buf_len_offset = UWB_EVT_NO_BUF_LEN_OFFSET - }, - [UWB_NOTIF_BP_SWITCH_IE_RECEIVED] = { - .struct_len = UWB_RESULT_CODE_SIZE, - .buf_len_offset = UWB_EVT_NO_BUF_LEN_OFFSET - }, - [UWB_NOTIF_DEV_ADDR_CONFLICT] = { - .struct_len = UWB_RESULT_CODE_SIZE, - .buf_len_offset = UWB_EVT_NO_BUF_LEN_OFFSET - }, - [UWB_NOTIF_DRP_AVAILABILITY_CHANGE] = { - .struct_len = sizeof (uwb_rceb_drp_availability_t), - .buf_len_offset = UWB_EVT_NO_BUF_LEN_OFFSET - }, - [UWB_NOTIF_DRP] = { - .struct_len = sizeof (uwb_rceb_drp_t), - .buf_len_offset = 8 - }, - [UWB_NOTIF_BP_SWITCH_STATUS] = { - .struct_len = UWB_RESULT_CODE_SIZE, - .buf_len_offset = UWB_EVT_NO_BUF_LEN_OFFSET - }, - [UWB_NOTIF_CMD_FRAME_RCV] = { - .struct_len = UWB_RESULT_CODE_SIZE, - .buf_len_offset = UWB_EVT_NO_BUF_LEN_OFFSET - }, - [UWB_NOTIF_CHANNEL_CHANGE_IE_RCV] = { - .struct_len = UWB_RESULT_CODE_SIZE, - .buf_len_offset = UWB_EVT_NO_BUF_LEN_OFFSET - }, - [UWB_NOTIF_RESERVED] = { - .struct_len = UWB_RESULT_CODE_SIZE, - .buf_len_offset = UWB_EVT_NO_BUF_LEN_OFFSET - }, - [UWB_NOTIF_RESERVED + 1] = { - .struct_len = UWB_RESULT_CODE_SIZE, - .buf_len_offset = UWB_EVT_NO_BUF_LEN_OFFSET - }, - [UWB_NOTIF_RESERVED + 2] = { - .struct_len = UWB_RESULT_CODE_SIZE, - .buf_len_offset = UWB_EVT_NO_BUF_LEN_OFFSET - }, - [UWB_NOTIF_RESERVED + 3] = { - .struct_len = UWB_RESULT_CODE_SIZE, - .buf_len_offset = UWB_EVT_NO_BUF_LEN_OFFSET - }, - [UWB_CE_CHANNEL_CHANGE] = { - .struct_len = sizeof (uwb_rceb_head_t), - .buf_len_offset = UWB_EVT_NO_BUF_LEN_OFFSET - }, - [UWB_CE_DEV_ADDR_MGMT] = { - .struct_len = sizeof (uwb_rceb_dev_addr_mgmt_t), - .buf_len_offset = UWB_EVT_NO_BUF_LEN_OFFSET - }, - [UWB_CE_GET_IE] = { - .struct_len = sizeof (uwb_rceb_get_ie_t), - .buf_len_offset = 4 - }, - [UWB_CE_RESET] = { - .struct_len = UWB_RESULT_CODE_SIZE, - .buf_len_offset = UWB_EVT_NO_BUF_LEN_OFFSET - }, - [UWB_CE_SCAN] = { - .struct_len = UWB_RESULT_CODE_SIZE, - .buf_len_offset = UWB_EVT_NO_BUF_LEN_OFFSET - }, - [UWB_CE_SET_BEACON_FILTER] = { - .struct_len = UWB_RESULT_CODE_SIZE, - .buf_len_offset = UWB_EVT_NO_BUF_LEN_OFFSET - }, - [UWB_CE_SET_DRP_IE] = { - .struct_len = sizeof (uwb_rceb_set_drp_ie_t), - .buf_len_offset = UWB_EVT_NO_BUF_LEN_OFFSET - }, - [UWB_CE_SET_IE] = { - .struct_len = sizeof (uwb_rceb_set_ie_t), - .buf_len_offset = UWB_EVT_NO_BUF_LEN_OFFSET - }, - [UWB_CE_SET_NOTIFICATION_FILTER] = { - .struct_len = UWB_RESULT_CODE_SIZE, - .buf_len_offset = UWB_EVT_NO_BUF_LEN_OFFSET - }, - [UWB_CE_SET_TX_POWER] = { - .struct_len = UWB_RESULT_CODE_SIZE, - .buf_len_offset = UWB_EVT_NO_BUF_LEN_OFFSET - }, - [UWB_CE_SLEEP] = { - .struct_len = UWB_RESULT_CODE_SIZE, - .buf_len_offset = UWB_EVT_NO_BUF_LEN_OFFSET - }, - [UWB_CE_START_BEACON] = { - .struct_len = UWB_RESULT_CODE_SIZE, - .buf_len_offset = UWB_EVT_NO_BUF_LEN_OFFSET - }, - [UWB_CE_STOP_BEACON] = { - .struct_len = UWB_RESULT_CODE_SIZE, - .buf_len_offset = UWB_EVT_NO_BUF_LEN_OFFSET - }, - [UWB_CE_BP_MERGE] = { - .struct_len = UWB_RESULT_CODE_SIZE, - .buf_len_offset = UWB_EVT_NO_BUF_LEN_OFFSET - }, - [UWB_CE_SEND_COMMAND_FRAME] = { - .struct_len = UWB_RESULT_CODE_SIZE, - .buf_len_offset = UWB_EVT_NO_BUF_LEN_OFFSET - }, - [UWB_CE_SET_ASIE_NOTIFICATION] = { - .struct_len = UWB_RESULT_CODE_SIZE, - .buf_len_offset = UWB_EVT_NO_BUF_LEN_OFFSET - }, -}; -/* This table is used for debug only */ -const char *uwba_evt_msg_table[] = { - [UWB_NOTIF_IE_RECEIVED] = "UWB_NOTIF_IE_RECEIVED", - [UWB_NOTIF_BEACON_RECEIVED] = "UWB_NOTIF_BEACON_RECEIVED", - [UWB_NOTIF_BEACON_SIZE_CHANGE] = "UWB_NOTIF_BEACON_SIZE_CHANGE", - [UWB_NOTIF_BPOIE_CHANGE] = "UWB_NOTIF_BPOIE_CHANGE", - [UWB_NOTIF_BP_SLOT_CHANGE] = "UWB_NOTIF_BP_SLOT_CHANGE", - [UWB_NOTIF_BP_SWITCH_IE_RECEIVED] = "UWB_NOTIF_BP_SWITCH_IE_RECEIVED", - [UWB_NOTIF_DEV_ADDR_CONFLICT] = "UWB_NOTIF_DEV_ADDR_CONFLICT", - [UWB_NOTIF_DRP_AVAILABILITY_CHANGE] = - "UWB_NOTIF_DRP_AVAILABILITY_CHANGE", - [UWB_NOTIF_DRP] = "UWB_NOTIF_DRP", - [UWB_NOTIF_BP_SWITCH_STATUS] = "UWB_NOTIF_BP_SWITCH_STATUS", - [UWB_NOTIF_CMD_FRAME_RCV] = "UWB_NOTIF_CMD_FRAME_RCV", - [UWB_NOTIF_CHANNEL_CHANGE_IE_RCV] = "UWB_NOTIF_CHANNEL_CHANGE_IE_RCV", - [UWB_NOTIF_RESERVED] = "UWB_NOTIF_RESERVED", - [UWB_NOTIF_RESERVED + 1] = "UWB_NOTIF_RESERVED + 1", - [UWB_NOTIF_RESERVED + 2] = "UWB_NOTIF_RESERVED + 2", - [UWB_NOTIF_RESERVED + 3] = "UWB_NOTIF_RESERVED + 2", - [UWB_CE_CHANNEL_CHANGE] = "UWB_CE_CHANNEL_CHANGE", - [UWB_CE_DEV_ADDR_MGMT] = "UWB_CE_DEV_ADDR_MGMT", - [UWB_CE_GET_IE] = "UWB_CE_GET_IE", - [UWB_CE_RESET] = "UWB_CE_RESET", - [UWB_CE_SCAN] = "UWB_CE_SCAN", - [UWB_CE_SET_BEACON_FILTER] = "UWB_CE_SET_BEACON_FILTER", - [UWB_CE_SET_DRP_IE] = "UWB_CE_SET_DRP_IE", - [UWB_CE_SET_IE] = "UWB_CE_SET_IE", - [UWB_CE_SET_NOTIFICATION_FILTER] = "UWB_CE_SET_NOTIFICATION_FILTER", - [UWB_CE_SET_TX_POWER] = "UWB_CE_SET_TX_POWER", - [UWB_CE_SLEEP] = "UWB_CE_SLEEP", - [UWB_CE_START_BEACON] = "UWB_CE_START_BEACON", - [UWB_CE_STOP_BEACON] = "UWB_CE_STOP_BEACON", - [UWB_CE_BP_MERGE] = "UWB_CE_BP_MERGE", - [UWB_CE_SEND_COMMAND_FRAME] = "UWB_CE_SEND_COMMAND_FRAME", - [UWB_CE_SET_ASIE_NOTIFICATION] = "UWB_CE_SET_ASIE_NOTIFICATION", -}; - - -static void uwba_init_lists(void); -static void uwba_fini_lists(void); -static void uwba_remove_cdev_list(uwba_dev_t *); - -static void uwba_list_phy_rates(uwb_dev_handle_t); -static void uwba_list_phy_bandgroups(uwb_dev_handle_t); -static void uwba_get_phy_cap(uwb_dev_handle_t, uint8_t *, uint16_t); -static void uwba_save_phy_cap_bm(uwb_dev_handle_t, uint8_t *); -int -_init(void) -{ - int rval; - /* - * uwba providing uwb device list support needs to be init'ed first - * and destroyed last - */ - uwba_init_lists(); - mutex_init(&uwba_mutex, NULL, MUTEX_DRIVER, NULL); - if ((rval = mod_install(&modlinkage)) != 0) { - uwba_fini_lists(); - mutex_destroy(&uwba_mutex); - } - - return (rval); -} - -int -_fini() -{ - int rval; - - if ((rval = mod_remove(&modlinkage)) == 0) { - mutex_destroy(&uwba_mutex); - uwba_fini_lists(); - } - - return (rval); -} - -int -_info(struct modinfo *modinfop) -{ - return (mod_info(&modlinkage, modinfop)); -} - -/* Create the global uwb dev list */ -static void -uwba_init_lists(void) -{ - list_create(&(uwba_dev_list), sizeof (uwba_dev_t), - offsetof(uwba_dev_t, uwba_dev_node)); -} - -/* Destroy the global uwb dev list */ -static void -uwba_fini_lists(void) -{ - uwba_dev_t *dev; - - /* Free all uwb dev node from dev_list */ - while (!list_is_empty(&uwba_dev_list)) { - dev = list_head(&uwba_dev_list); - if (dev != NULL) { - list_remove(&uwba_dev_list, dev); - kmem_free(dev, sizeof (uwba_dev_t)); - } - } -} -/* Search the uwb handle with a hwarc/hwahc dip */ -uwb_dev_handle_t -uwba_dev_search(dev_info_t *dip) -{ - mutex_enter(&uwba_mutex); - uwba_dev_t *uwba_dev = list_head(&uwba_dev_list); - - while (uwba_dev != NULL) { - if (ddi_get_parent(uwba_dev->dip) == ddi_get_parent(dip)) { - - goto done; - } - uwba_dev = list_next(&uwba_dev_list, uwba_dev); - } -done: - mutex_exit(&uwba_mutex); - - return (uwb_dev_handle_t)(uwba_dev); -} - -/* Add a uwb device (hwarc/whci) to the uwb dev list */ -void -uwba_dev_add_to_list(uwba_dev_t *uwba_dev) -{ - mutex_enter(&uwba_mutex); - uwba_log(uwba_dev, UWBA_LOG_DEBUG, - "add uwba_dev = %x", uwba_dev); - list_insert_tail(&uwba_dev_list, uwba_dev); - mutex_exit(&uwba_mutex); -} - -/* Remove a uwb device (hwarc/whci) from the uwb dev list */ -void -uwba_dev_rm_from_list(uwba_dev_t *uwba_dev) -{ - mutex_enter(&uwba_mutex); - if (list_is_empty(&uwba_dev_list)) { - mutex_exit(&uwba_mutex); - - return; - } - - uwba_log(uwba_dev, UWBA_LOG_DEBUG, - "remove uwba_dev = %x", uwba_dev); - - list_remove(&uwba_dev_list, uwba_dev); - mutex_exit(&uwba_mutex); -} - -/* Init context bitset for a radio device (hwarc/whci) */ -void -uwba_init_ctxt_id(uwba_dev_t *uwba_dev) -{ - bitset_init(&uwba_dev->ctxt_bits); /* this bzero sizeof(bitset_t) */ - bitset_resize(&uwba_dev->ctxt_bits, 256); /* alloc mem */ - bitset_add(&uwba_dev->ctxt_bits, 0); - bitset_add(&uwba_dev->ctxt_bits, 255); -} - -/* Free context bitset for a radio device (hwarc/whci) */ -void -uwba_fini_ctxt_id(uwba_dev_t *uwba_dev) -{ - /* bitset_fini will free the mem allocated by bitset_resize. */ - bitset_fini(&uwba_dev->ctxt_bits); -} - -/* Get a free context id from bitset */ -uint8_t -uwba_get_ctxt_id(uwba_dev_t *uwba_dev) -{ - uint8_t ctxt_id; - - /* if reaches the top, turn around */ - if (uwba_dev->ctxt_id >= UWB_CTXT_ID_TOP) { - uwba_dev->ctxt_id = UWB_CTXT_ID_BOTTOM -1; - } - ctxt_id = uwba_dev->ctxt_id; - - /* Search ctxt_id+1 to UWB_CTXT_ID_UNVALID */ - do { - ctxt_id++; - - /* test bit and returen if it is not set */ - if (!bitset_in_set(&uwba_dev->ctxt_bits, ctxt_id)) { - bitset_add(&uwba_dev->ctxt_bits, ctxt_id); - uwba_dev->ctxt_id = ctxt_id; - - return (ctxt_id); - } - - } while (ctxt_id < UWB_CTXT_ID_UNVALID); - - /* Search 1 to ctxt_id */ - if (uwba_dev->ctxt_id != 0) { - ctxt_id = UWB_CTXT_ID_BOTTOM; - do { - ctxt_id++; - - /* test bit and returen if it is not set */ - if (!bitset_in_set(&uwba_dev->ctxt_bits, ctxt_id)) { - bitset_add(&uwba_dev->ctxt_bits, ctxt_id); - uwba_dev->ctxt_id = ctxt_id; - - return (ctxt_id); - } - } while (ctxt_id < uwba_dev->ctxt_id); - } - - /* All ids are in use, just force to re-use one. */ - uwba_dev->ctxt_id++; - - return (uwba_dev->ctxt_id); -} - -/* Reset the bit (offset at ctxt_id) to zero */ -void -uwba_free_ctxt_id(uwba_dev_t *dev, uint8_t ctxt_id) -{ - bitset_del(&dev->ctxt_bits, ctxt_id); - -} - -/* Fill the rccb to ctrl req's data block */ -void -uwba_fill_rccb_head(uwba_dev_t *uwba_dev, uint16_t cmd, mblk_t *data) -{ - data->b_rptr[0] = UWB_CE_TYPE_GENERAL; - UINT16_TO_LE(cmd, 1, data->b_rptr); - data->b_rptr[3] = uwba_get_ctxt_id(uwba_dev); - uwba_log(uwba_dev, UWBA_LOG_DEBUG, - "the new ctxt_id is %d", data->b_rptr[3]); -} - -/* - * Allocate uwb_dev_t for a radio controller device. Arg rcd_intr_pri is the - * interrupt priority of the interrupt handler of the radio controller driver. - * If there is no interrupt handler in the driver, then pass 0 to this arg. - */ -void -uwba_alloc_uwb_dev(dev_info_t *dip, uwba_dev_t **uwba_dev, uint_t rcd_intr_pri) -{ - char *devinst; - int devinstlen; - int instance = ddi_get_instance(dip); - - *uwba_dev = (uwba_dev_t *)kmem_zalloc(sizeof (uwba_dev_t), KM_SLEEP); - - /* - * HWA radio controller will not call uwb_* functions in interrupt - * level, while WHCI radio controller will. - */ - if (rcd_intr_pri == 0) { - mutex_init(&(*uwba_dev)->dev_mutex, NULL, MUTEX_DRIVER, NULL); - } else { - mutex_init(&(*uwba_dev)->dev_mutex, NULL, MUTEX_DRIVER, - DDI_INTR_PRI(rcd_intr_pri)); - } - mutex_enter(&(*uwba_dev)->dev_mutex); - - (*uwba_dev)->dip = dip; - (*uwba_dev)->dev_state = UWB_STATE_IDLE; - - /* create a string for driver name and instance number */ - devinst = kmem_zalloc(UWB_MAXSTRINGLEN, KM_SLEEP); - devinstlen = snprintf(devinst, UWB_MAXSTRINGLEN, "%s%d: ", - ddi_driver_name(dip), instance); - (*uwba_dev)->devinst = kmem_zalloc(devinstlen + 1, KM_SLEEP); - (void) strncpy((*uwba_dev)->devinst, devinst, devinstlen); - kmem_free(devinst, UWB_MAXSTRINGLEN); - - /* list to cache the notifications from radio controller device */ - list_create(&(*uwba_dev)->notif_list, sizeof (uwb_notif_wrapper_t), - offsetof(uwb_notif_wrapper_t, notif_node)); - (*uwba_dev)->notif_cnt = 0; - - /* list to record the client devices according to beacons received */ - list_create(&(*uwba_dev)->client_dev_list, sizeof (uwba_client_dev_t), - offsetof(uwba_client_dev_t, dev_node)); - (*uwba_dev)->client_dev_cnt = 0; - - cv_init(&(*uwba_dev)->cmd_result_cv, NULL, CV_DRIVER, NULL); - cv_init(&(*uwba_dev)->cmd_handler_cv, NULL, CV_DRIVER, NULL); - - mutex_exit(&(*uwba_dev)->dev_mutex); - -} - -/* Free a uwb dev for a radio device (hwarc/whci) */ -void -uwba_free_uwb_dev(uwba_dev_t *uwba_dev) -{ - uwb_notif_wrapper_t *nw; - - mutex_enter(&(uwba_dev)->dev_mutex); - cv_destroy(&uwba_dev->cmd_result_cv); - cv_destroy(&uwba_dev->cmd_handler_cv); - - /* - * remove all the notifications in this device's list, and then destroy - * the list - */ - while (!list_is_empty(&uwba_dev->notif_list)) { - - nw = list_head(&uwba_dev->notif_list); - if (nw != NULL) { - list_remove(&(uwba_dev->notif_list), nw); - } else { - break; - } - - /* Free notification struct */ - if (nw->notif) { - kmem_free(nw->notif, nw->length); - } - kmem_free(nw, sizeof (uwb_notif_wrapper_t)); - } - uwba_dev->notif_cnt = 0; - list_destroy(&uwba_dev->notif_list); - - uwba_remove_cdev_list(uwba_dev); - if (uwba_dev->devinst != NULL) { - kmem_free(uwba_dev->devinst, - strlen(uwba_dev->devinst) + 1); - } - mutex_exit(&(uwba_dev)->dev_mutex); - - /* Destroy mutex and dev structure */ - mutex_destroy(&uwba_dev->dev_mutex); - kmem_free(uwba_dev, sizeof (uwba_dev_t)); -} - - -/* Get a event or notification code from the data stream */ -uint16_t -uwba_get_evt_code(uint8_t *data, int data_len) -{ - uint16_t evt_code; - - /* - * UWB_RAW_RESULT_CODE_SIZE is the minimum size for any events or - * notifications. - */ - if (data_len < UWB_RAW_RESULT_CODE_SIZE) { - - uwba_log(NULL, UWBA_LOG_LOG, - "uwba_get_evt_code: invalid data_len=%d", - data_len); - return (UWB_INVALID_EVT_CODE); - } - - LE_TO_UINT16(data, UWB_RAW_WEVENT_OFFSET, evt_code); - - /* if out of range */ - if (evt_code > UWB_CE_SET_ASIE_NOTIFICATION) { - uwba_log(NULL, UWBA_LOG_LOG, - "uwba_get_evt_code: invalid evt_code=%d", - evt_code); - return (UWB_INVALID_EVT_CODE); - } - - /* if fall into the reserved range */ - if (evt_code >= UWB_NOTIF_RESERVED && - evt_code < UWB_CE_CHANNEL_CHANGE) { - uwba_log(NULL, UWBA_LOG_LOG, - "uwba_get_evt_code: reserved evt_code=%d", evt_code); - - return (UWB_INVALID_EVT_CODE); - } - - return (evt_code); -} - -/* Get the size of notif/evt struct */ -uint16_t -uwba_get_evt_size(uint8_t *data, int data_len, uint16_t evt_code) -{ - uint16_t buf_len_off, buf_len, evt_size; - - evt_size = uwba_evt_size_table[evt_code].struct_len; - buf_len_off = uwba_evt_size_table[evt_code].buf_len_offset; - - /* If the offset of the variable data length is out of range. */ - if (buf_len_off >= data_len) { - - return (UWB_INVALID_EVT_SIZE); - } - - /* If this event has variable length data, add up the length. */ - if (buf_len_off) { - LE_TO_UINT16(data, buf_len_off, buf_len); - - /* in case buf_len is not a reasonable value. */ - if ((buf_len_off + 2 + buf_len) > data_len) { - uwba_log(NULL, UWBA_LOG_DEBUG, - "uwba_get_evt_size: data_len=%d, buf_len_off=%d," - " buf_len=%d", data_len, buf_len_off, buf_len); - - return (UWB_INVALID_EVT_SIZE); - } - - /* - * after add up, the evt size may be a couple of bytes greater - * (depends on the structure alignment) than we actually need, - * but it does not matter. - */ - evt_size += buf_len; - } - - /* - * TODO: check if data_len is less than expected raw event data, for the - * fixed length events/notifs. - */ - - return (evt_size); -} - -/* - * hook the new event to uwb device handle, replace the old one if there is. - * Signal the cmd thread which is waiting this cmd result. - */ -void -uwba_put_cmd_result(uwba_dev_t *uwba_dev, void *evt_struct, - uint16_t evt_size) -{ - uwb_cmd_result_t *cmd_rlt = (uwb_cmd_result_t *)evt_struct; - - mutex_enter(&uwba_dev->dev_mutex); - if (uwba_dev->cmd_result_wrap.cmd_result) { - uwba_log(uwba_dev, UWBA_LOG_LOG, - "previous command result not processed " - "bEventType = %d, wEvent = %d, ctxt_id = %d", - uwba_dev->cmd_result_wrap.cmd_result->rceb.bEventType, - uwba_dev->cmd_result_wrap.cmd_result->rceb.wEvent, - uwba_dev->cmd_result_wrap.cmd_result->rceb.bEventContext); - - kmem_free(uwba_dev->cmd_result_wrap.cmd_result, - uwba_dev->cmd_result_wrap.length); - } - - uwba_log(uwba_dev, UWBA_LOG_DEBUG, - "uwba_put_cmd_result: wEvent= %d, msg= %s", - cmd_rlt->rceb.wEvent, uwba_event_msg(cmd_rlt->rceb.wEvent)); - uwba_dev->cmd_result_wrap.length = evt_size; - uwba_dev->cmd_result_wrap.cmd_result = cmd_rlt; - if (cmd_rlt->rceb.bEventContext == uwba_dev->ctxt_id) { - cv_signal(&uwba_dev->cmd_result_cv); - } else { - uwba_log(uwba_dev, UWBA_LOG_LOG, - "the cmd result ctxt_id %d is not matching the" - "current cmd ctxt_id %d", - cmd_rlt->rceb.bEventContext, uwba_dev->ctxt_id); - } - mutex_exit(&uwba_dev->dev_mutex); -} - -/* add the notification to the tail of uwba_dev->notif_list */ -int -uwba_add_notif_to_list(uwba_dev_t *uwba_dev, void *evt_struct, - uint16_t evt_size) -{ - uwb_notif_wrapper_t *nw, *ow; - - nw = (uwb_notif_wrapper_t *)kmem_alloc(sizeof (uwb_notif_wrapper_t), - KM_NOSLEEP); - if (nw == NULL) { - uwba_log(uwba_dev, UWBA_LOG_LOG, - "uwba_add_notif_to_list: allocate notif wrapper failed"); - - return (UWB_NO_RESOURCES); - } - nw->length = evt_size; - nw->notif = (uwb_rceb_notif_t *)evt_struct; - - mutex_enter(&uwba_dev->dev_mutex); - - list_insert_tail(&uwba_dev->notif_list, nw); - uwba_dev->notif_cnt++; - - if (uwba_dev->notif_cnt >= UWB_MAX_NOTIF_NUMBER) { - /* remove oldest one */ - ow = list_head(&uwba_dev->notif_list); - list_remove(&uwba_dev->notif_list, ow); - uwba_dev->notif_cnt--; - - /* Free it */ - if (ow->notif) { - kmem_free(ow->notif, ow->length); - } - kmem_free(ow, sizeof (uwb_notif_wrapper_t)); - } - - uwba_log(uwba_dev, UWBA_LOG_DEBUG, - "uwba_add_notif_to_list: notification code=%d, notif_cnt=%d", - nw->notif->rceb.wEvent, uwba_dev->notif_cnt); - - mutex_exit(&uwba_dev->dev_mutex); - - return (UWB_SUCCESS); -} - -/* - * find the specific client device in the client_dev_list by comparing the MAC - * address - */ -uwba_client_dev_t * -uwba_find_cdev_by_mac(uwba_dev_t *uwba_dev, uwb_mac_addr_t *mac) -{ - uwba_client_dev_t *cdev = NULL; - - cdev = list_head(&uwba_dev->client_dev_list); - while (cdev != NULL) { - if (memcmp(mac, cdev->beacon_frame.Device_Identifier.addr, - sizeof (uwb_mac_addr_t)) == 0) { - - return (cdev); - } - cdev = list_next(&uwba_dev->client_dev_list, cdev); - } - - return (cdev); -} -/* find the client device beconing in a specific channel */ -uwba_client_dev_t * -uwba_find_cdev_by_channel(uwba_dev_t *uwba_dev, uint8_t channel) -{ - uwba_client_dev_t *cdev = NULL; - - cdev = list_head(&uwba_dev->client_dev_list); - while (cdev != NULL) { - if (cdev->bChannelNumber == channel) { - - return (cdev); - } - cdev = list_next(&uwba_dev->client_dev_list, cdev); - } - - return (cdev); -} - -/* remove all cdev list for uwb dev */ -static void -uwba_remove_cdev_list(uwba_dev_t *uwba_dev) -{ - uwba_client_dev_t *cdev = NULL; - - while (!list_is_empty(&uwba_dev->client_dev_list)) { - - cdev = list_head(&uwba_dev->client_dev_list); - if (cdev != NULL) { - - list_remove(&(uwba_dev->client_dev_list), cdev); - } else { - - break; - } - - kmem_free(cdev, sizeof (uwba_client_dev_t)); - } -} - -/* add a client radio device to the tail of uwba_dev->client_dev_list */ -int -uwba_add_cdev_to_list(uwba_dev_t *uwba_dev, uwb_beacon_frame_t *bc_frm) -{ - uwb_mac_addr_t *mac; - uwba_client_dev_t *cdev; - int rval = UWB_SUCCESS; - - mutex_enter(&uwba_dev->dev_mutex); - - if (uwba_dev->client_dev_cnt >= UWB_MAX_CDEV_NUMBER) { - uwba_log(uwba_dev, UWBA_LOG_LOG, - "uwba_add_cdev_to_list: can not add this dev," - "client dev number reached max, client_dev_cnt=%d", - uwba_dev->client_dev_cnt); - rval = UWB_FAILURE; - goto done; - } - - mac = &bc_frm->Device_Identifier; - if (uwba_find_cdev_by_mac(uwba_dev, mac) != NULL) { - uwba_log(uwba_dev, UWBA_LOG_DEBUG, - "uwba_add_cdev_to_list: this client dev is added before"); - - rval = UWB_SUCCESS; - goto done; - } - cdev = (uwba_client_dev_t *)kmem_alloc(sizeof (uwba_client_dev_t), - KM_NOSLEEP); - if (cdev == NULL) { - uwba_log(uwba_dev, UWBA_LOG_LOG, - "uwba_add_client_device: allocate " - "uwba_client_dev_t failed"); - - rval = UWB_NO_RESOURCES; - goto done; - } - (void) memcpy(&cdev->beacon_frame, bc_frm, sizeof (uwb_beacon_frame_t)); - - list_insert_tail(&uwba_dev->client_dev_list, cdev); - uwba_dev->client_dev_cnt++; - - uwba_log(uwba_dev, UWBA_LOG_DEBUG, - "uwba_add_cdev_to_list: a new client dev added. MAC: " - "%x %x %x %x %x %x, client_dev_cnt=%d", - cdev->beacon_frame.Device_Identifier.addr[0], - cdev->beacon_frame.Device_Identifier.addr[1], - cdev->beacon_frame.Device_Identifier.addr[2], - cdev->beacon_frame.Device_Identifier.addr[3], - cdev->beacon_frame.Device_Identifier.addr[4], - cdev->beacon_frame.Device_Identifier.addr[5], - uwba_dev->client_dev_cnt); -done: - - mutex_exit(&uwba_dev->dev_mutex); - - return (rval); -} - -/* - * Return the actual parsed raw data length. Stop parse if datalen or structlen - * is out of range, and then return UWB_PARSE_ERROR. - */ -int -uwba_parse_data(char *format, - uchar_t *data, - size_t datalen, - void *structure, - size_t structlen) -{ - int fmt; - int counter = 1; - int multiplier = 0; - uchar_t *datastart = data; - uchar_t *dataend = data + datalen; - void *structend = (void *)((intptr_t)structure + structlen); - - if ((format == NULL) || (data == NULL) || (structure == NULL)) { - - return (UWB_PARSE_ERROR); - } - - while ((fmt = *format) != '\0') { - - /* - * Could some one pass a "format" that is greater than - * the structlen? Conversely, one could pass a ret_buf_len - * that is less than the "format" length. - * If so, we need to protect against writing over memory. - */ - if (counter++ > structlen) { - return (UWB_PARSE_ERROR); - } - - if (fmt == 'c') { - uint8_t *cp = (uint8_t *)structure; - - cp = (uint8_t *)(((uintptr_t)cp + _CHAR_ALIGNMENT - 1) & - ~(_CHAR_ALIGNMENT - 1)); - - /* - * If data or structure is out of range, stop parse. - */ - if (((data + 1) > dataend) || - ((cp + 1) > (uint8_t *)structend)) - return (UWB_PARSE_ERROR); - - *cp++ = *data++; - structure = (void *)cp; - if (multiplier) { - multiplier--; - } - if (multiplier == 0) { - format++; - } - } else if (fmt == 's') { - uint16_t *sp = (uint16_t *)structure; - - sp = (uint16_t *) - (((uintptr_t)sp + _SHORT_ALIGNMENT - 1) & - ~(_SHORT_ALIGNMENT - 1)); - if (((data + 2) > dataend) || - ((sp + 1) > (uint16_t *)structend)) - return (UWB_PARSE_ERROR); - - *sp++ = (data[1] << 8) + data[0]; - data += 2; - structure = (void *)sp; - if (multiplier) { - multiplier--; - } - if (multiplier == 0) { - format++; - } - } else if (isdigit(fmt)) { - multiplier = (multiplier * 10) + (fmt - '0'); - format++; - counter--; - } else { - multiplier = 0; - - return (UWB_PARSE_ERROR); - } - } - - return ((intptr_t)data - (intptr_t)datastart); -} - - -/* - * parse rceb, check if the context id is in the reasonable range (0x0 - 0xfe). - * If success, return the offset just after the rceb struct. - */ -int -uwba_parse_rceb(uint8_t *data, - size_t datalen, - void *structure, - size_t structlen) -{ - int parsed_len; - uwb_rceb_head_t *rceb; - - parsed_len = uwba_parse_data("csc", data, datalen, - structure, structlen); - if (parsed_len == UWB_PARSE_ERROR) { - - return (UWB_PARSE_ERROR); - } - rceb = (uwb_rceb_head_t *)structure; - if (rceb->bEventContext > UWB_CTXT_ID_TOP) { - - return (UWB_PARSE_ERROR); - } - - return (parsed_len); -} - -int -uwba_parse_dev_addr_mgmt(uint8_t *spec_data, int spec_data_len, - uwb_rceb_dev_addr_mgmt_t *evt_struct) -{ - /* 6 bytes for address, 1 for result code. */ - if (uwba_parse_data("7c", spec_data, - spec_data_len, evt_struct->baAddr, 7) == UWB_PARSE_ERROR) { - - return (UWB_PARSE_ERROR); - } - - return (UWB_SUCCESS); -} - -/* Parse UWB IEs that got by get_ie radio controller command */ -int -uwba_parse_get_ie(uwb_dev_handle_t uwb_dev_hdl, uint8_t *spec_data, - int spec_data_len, uwb_rceb_get_ie_t *evt_struct) -{ - int i; - uwba_dev_t *uwba_dev = (uwba_dev_t *)uwb_dev_hdl; - - /* At least, it should have wIELength. */ - if (spec_data_len < 2) { - - return (UWB_PARSE_ERROR); - } - LE_TO_UINT16(spec_data, 0, evt_struct->wIELength); - - /* - * Except wIELength, it should have the number of bytes of indicated by - * wIELength. - */ - if (spec_data_len < (evt_struct->wIELength + 2)) { - - return (UWB_PARSE_ERROR); - } - - /* - * Proper memory for evt_struct is already allocated for evt_struct in - * uwb_parse_evt_notif() - */ - bcopy(spec_data + 2, evt_struct->IEData, evt_struct->wIELength); - - uwba_log(uwba_dev, UWBA_LOG_DEBUG, - "uwba_parse_get_ie: wIELength=%d", evt_struct->wIELength); - - for (i = 0; i < evt_struct->wIELength; i++) { - uwba_log(uwba_dev, UWBA_LOG_DEBUG, - "0x%x ", evt_struct->IEData[i]); - } - - /* Todo: continue to parse other IE Data? */ - uwba_get_phy_cap(uwb_dev_hdl, evt_struct->IEData, - evt_struct->wIELength); - uwba_list_phy_rates(uwb_dev_hdl); - uwba_list_phy_bandgroups(uwb_dev_hdl); - - return (UWB_SUCCESS); -} - - -/* - * Parse the beacon frame and add the client radio device to the dev_list in - * uwb_dev_handle - */ -void -uwba_parse_beacon_info(uwba_dev_t *uwba_dev, uint8_t *bc_info) -{ - uwb_beacon_frame_t *bc_frm; - - bc_frm = (uwb_beacon_frame_t *)bc_info; - - /* - * add the uwb device to list if it is a newly found device according to - * its MAC addr in the beacon - */ - if (uwba_add_cdev_to_list(uwba_dev, bc_frm) == UWB_SUCCESS) { - - /* TODO: log messages */ - - return; - } -} - -int -uwba_parse_bpoie_chg(uwb_dev_handle_t uwb_dev_hdl, - uint8_t *spec_data, int spec_data_len, - uwb_rceb_bpoie_change_t *evt_struct) { - int parsed_len; - uwba_dev_t *uwba_dev = (uwba_dev_t *)uwb_dev_hdl; - parsed_len = uwba_parse_data("s", spec_data, - spec_data_len, &(evt_struct->wBPOIELength), 2); - - if (parsed_len == UWB_PARSE_ERROR) { - uwba_log(uwba_dev, UWBA_LOG_LOG, - "uwba_parse_bpoie_chg: parse error, parsed_len=%d", - parsed_len); - - return (UWB_PARSE_ERROR); - } - /* Todo: not supported now */ - return (UWB_SUCCESS); -} -/* Parse the beacon_receive notif */ -int -uwba_parse_beacon_rcv(uwb_dev_handle_t uwb_dev_hdl, - uint8_t *spec_data, int spec_data_len, - uwb_rceb_beacon_t *evt_struct) -{ - int parsed_len; - uwba_dev_t *uwba_dev = (uwba_dev_t *)uwb_dev_hdl; - uwb_beacon_frame_t *bc_frm = NULL; - uwba_client_dev_t *client_dev = NULL; - - /* parse the elements except BeaconInfo */ - parsed_len = uwba_parse_data("ccsccs", spec_data, - spec_data_len, &(evt_struct->bChannelNumber), 8); - if (parsed_len == UWB_PARSE_ERROR) { - uwba_log(uwba_dev, UWBA_LOG_LOG, - "uwba_parse_beacon_rcv: parse error, parsed_len=%d", - parsed_len); - - return (UWB_PARSE_ERROR); - } - - /* - * Except the elements before BeaconInfo, it should have the number of - * bytes of indicated by wBeaconInfoLength. - */ - if ((spec_data_len -UWB_BEACONINFO_OFFSET) < - evt_struct->wBeaconInfoLength) { - uwba_log(uwba_dev, UWBA_LOG_LOG, - "uwba_parse_beacon_rcv: parse error: spec_data_len=%d," - "evt_struct->wBeaconInfoLength=%d, bc_info_offset=%d", - spec_data_len, evt_struct->wBeaconInfoLength, - UWB_BEACONINFO_OFFSET); - - return (UWB_PARSE_ERROR); - } - if (evt_struct->wBeaconInfoLength < sizeof (uwb_beacon_frame_t)) { - uwba_log(uwba_dev, UWBA_LOG_LOG, - "uwba_parse_beacon_rcv: too small size, " - "wBeaconInfoLength=%d, data[0]=%d, data[1]=%d, data[4]=%d," - " data[5]=%d, data[6]=%d, data[7]=%d, spec_data_len=%d", - evt_struct->wBeaconInfoLength, spec_data[0], spec_data[1], - spec_data[4], spec_data[5], spec_data[6], spec_data[7], - spec_data_len); - - return (UWB_PARSE_ERROR); - } - uwba_log(uwba_dev, UWBA_LOG_DEBUG, "uwba_parse_beacon_rcv:" - "bChannelNumber = %d bBeaconType = %d " - "wBPSTOffset = %d bLQI = %d bRSSI = %d " - "wBeaconInfoLength = %d", - evt_struct->bChannelNumber, evt_struct->bBeaconType, - evt_struct->wBPSTOffset, evt_struct->bLQI, evt_struct->bRSSI, - evt_struct->wBeaconInfoLength); - - /* - * Proper memory for evt_struct is already allocated for evt_struct in - * uwb_parse_evt_notif() - */ - bcopy(spec_data + UWB_BEACONINFO_OFFSET, - evt_struct->BeaconInfo, evt_struct->wBeaconInfoLength); - - /* - * Parse the beacon frame and add the client radio device - * to the dev_list in uwb_dev_handle - */ - uwba_parse_beacon_info(uwba_dev, evt_struct->BeaconInfo); - - bc_frm = (uwb_beacon_frame_t *)evt_struct->BeaconInfo; - - client_dev = uwba_find_cdev_by_mac(uwba_dev, - &(bc_frm->Device_Identifier)); - - /* Update the client device's beconing information */ - client_dev->bChannelNumber = evt_struct->bChannelNumber; - client_dev->bBeaconType = evt_struct->bBeaconType; - client_dev->wBPSTOffset = evt_struct->wBPSTOffset; - return (UWB_SUCCESS); -} - - -/* - * find the phy capability ie from ie_data, then save the capability bitmap to - * uwb_dev_hdl - */ -static void -uwba_get_phy_cap(uwb_dev_handle_t uwb_dev_hdl, - uint8_t *ie_data, uint16_t ie_len) -{ - uint8_t *phy_ie; - - /* traverse ie_data to find PHY Capabilities IE */ - phy_ie = uwba_find_ie(uwb_dev_hdl, - UWB_IE_PHY_CAP, ie_data, ie_len); - - if (phy_ie == NULL) { - - return; - } - /* copy the phy capabilities bitmap to uwba_dev->phy_cap_bm */ - uwba_save_phy_cap_bm(uwb_dev_hdl, phy_ie); -} - -/* Copy the PHY capability bitmap from phy_ie to uwb device handle */ -static void -uwba_save_phy_cap_bm(uwb_dev_handle_t uwb_dev_hdl, uint8_t *phy_ie) -{ - uwba_dev_t *uwba_dev = (uwba_dev_t *)uwb_dev_hdl; - - mutex_enter(&uwba_dev->dev_mutex); - uwba_dev->phy_cap_bm = 0; - - uwba_dev->phy_cap_bm = phy_ie[4]; - uwba_dev->phy_cap_bm = phy_ie[3] | uwba_dev->phy_cap_bm << 8; - uwba_dev->phy_cap_bm = phy_ie[2] | uwba_dev->phy_cap_bm << 8; - mutex_exit(&uwba_dev->dev_mutex); -} - -/* List all supported PHY data rates by checking the PHY capability bitmap */ -static void -uwba_list_phy_rates(uwb_dev_handle_t uwb_dev_hdl) -{ - uwba_dev_t *uwba_dev = (uwba_dev_t *)uwb_dev_hdl; - int i; - const char *uwb_phy_rate_table[] = { - [UWB_RATE_OFFSET_53 - UWB_RATE_OFFSET_BASE] = "53.3", - [UWB_RATE_OFFSET_80 - UWB_RATE_OFFSET_BASE] = "80", - [UWB_RATE_OFFSET_106 - UWB_RATE_OFFSET_BASE] = "106.7", - [UWB_RATE_OFFSET_160 - UWB_RATE_OFFSET_BASE] = "160", - [UWB_RATE_OFFSET_200 - UWB_RATE_OFFSET_BASE] = "200", - [UWB_RATE_OFFSET_320 - UWB_RATE_OFFSET_BASE] = "320", - [UWB_RATE_OFFSET_400 - UWB_RATE_OFFSET_BASE] = "400", - [UWB_RATE_OFFSET_480 - UWB_RATE_OFFSET_BASE] = "480", - }; - - for (i = UWB_RATE_OFFSET_BASE; i <= UWB_RATE_OFFSET_480; i++) { - if (BT_TEST(&uwba_dev->phy_cap_bm, i)) { - uwba_log(uwba_dev, UWBA_LOG_DEBUG, - "uwba_list_phy_rates: Rate supported=%s", - uwb_phy_rate_table[i - UWB_RATE_OFFSET_BASE]); - } - } - uwba_log(uwba_dev, UWBA_LOG_DEBUG, - "uwba_list_phy_rates: phy_cap_bm=%u", - uwba_dev->phy_cap_bm); -} - -/* List all supported PHY band groups by checking the PHY capability bitmap */ -static void -uwba_list_phy_bandgroups(uwb_dev_handle_t uwb_dev_hdl) -{ - uwba_dev_t *uwba_dev = (uwba_dev_t *)uwb_dev_hdl; - int i; - - /* group 1 to 4 [ECMA, Table 112] */ - for (i = 0; i <= 7; i++) { - if (BT_TEST(&uwba_dev->phy_cap_bm, i)) { - uwba_log(uwba_dev, UWBA_LOG_DEBUG, - "uwba_list_phy_bandgroups: band groups " - "supported=%d", i); - } - } - - /* group 5 [ECMA, Table 112] */ - if (BT_TEST(&uwba_dev->phy_cap_bm, 9)) { - uwba_log(uwba_dev, UWBA_LOG_DEBUG, - "uwba_list_phy_bandgroups: band groups supported=%d", i); - } -} - - - -/* - * Allocate a channel for the HC. Scan every channel supported, - * if beacon information from the channel received, scan the next - * channel, or else, stop. - * Return: - * first channel with no beacon recieved - * last channel if every channel is busy - * 0 if scan failure - * uwba_channel_table is used to decode the PHY capability IE. - * The array index is the bit in the PHY IE. base is the first - * TFC code.offset is the length from the first TFC code. - * Refer to: - * [ECM-368]. CHAP 11.2. Table 25-30. - * [ECM-368]. CHAP 16.8.16. Table 112 - * - */ -uint8_t -uwba_allocate_channel(uwb_dev_handle_t uwb_dev_hdl) { - uwba_dev_t *uwba_dev = (uwba_dev_t *)uwb_dev_hdl; - int i, j; - uwba_channel_range_t uwba_channel_table[] = { - { .base = 9, .offset = 4 }, /* Band group 1 TFI */ - { .base = 13, .offset = 3 }, /* Band group 1 FFI */ - { .base = 17, .offset = 4 }, /* Band group 2 TFI */ - { .base = 21, .offset = 3 }, /* Band group 2 FFI */ - { .base = 25, .offset = 4 }, /* Band group 3 TFI */ - { .base = 29, .offset = 3 }, /* Band group 3 FFI */ - { .base = 33, .offset = 4 }, /* Band group 4 TFI */ - { .base = 37, .offset = 3 }, /* Band group 4 FFI */ - { .base = 0, .offset = 0 }, /* Bit reserved */ - { .base = 45, .offset = 2 } /* Band group 5 FFI */ - }; - int tbl_size = sizeof (uwba_channel_table) / - sizeof (uwba_channel_range_t); - - uint8_t channel = 0; - for (i = 0; i < tbl_size; i++) { - if ((uwba_dev->phy_cap_bm & (0x01<<i)) == 0x0) continue; - - for (j = 0; j < uwba_channel_table[i].offset; j++) { - - channel = uwba_channel_table[i].base + j; - if (uwb_scan_channel(uwb_dev_hdl, channel) - != UWB_SUCCESS) { - uwba_log(uwba_dev, UWBA_LOG_LOG, - "uwba_allocate_channel: scan chanel" - " %d failed", channel); - - return (0); - } - /* No beacon recevied in this channel, return */ - if (!uwba_find_cdev_by_channel(uwba_dev, channel)) { - - return (channel); - } - uwba_log(uwba_dev, UWBA_LOG_DEBUG, - "uwba_allocate_channel: exsting device becaoning" - "in channel = %d ", channel); - } - - } - - /* - * when we reach here, it means all the channel has beconning device, - * return the last channel - */ -done: - uwba_log(uwba_dev, UWBA_LOG_DEBUG, - "uwba_allocate_channel: return channel = %d", - channel); - - return (channel); -} -/* - * Find a IE with a specific ID in ie_data. Return the pointer to the IE head if - * found, else return NULL. - */ -uint8_t * -uwba_find_ie(uwb_dev_handle_t uwb_dev_hdl, uint_t ie_id, - uint8_t *ie_data, uint16_t ie_len) -{ - int i = 0; - uint8_t curr_ie_len; - boolean_t matched = B_FALSE; - uwba_dev_t *uwba_dev = (uwba_dev_t *)uwb_dev_hdl; - - while (i < (ie_len - 1)) { - if (ie_data[i] == ie_id) { - matched = B_TRUE; - - break; - } - i++; /* move to the length item of the current IE */ - curr_ie_len = ie_data[i]; - i = i + curr_ie_len + 1; /* move to the next IE's head */ - } - if (matched) { - curr_ie_len = ie_data[i + 1]; - - /* - * if the rest ie data are less than that indicated in the - * matched IE's length, then this is not valid IE - */ - if ((ie_len - i -1) < curr_ie_len) { - uwba_log(uwba_dev, UWBA_LOG_LOG, - "the matched IE is not valid. " - "curr_ie_len=%d, i=%d", curr_ie_len, i); - - return (NULL); - } - - return (&ie_data[i]); - } - - return (NULL); -} - -void -uwba_copy_rccb(uwb_rccb_cmd_t *src_rccb, uwb_rccb_cmd_t *des_rccb) -{ - bcopy(src_rccb, des_rccb, sizeof (uwb_rccb_cmd_t)); -} - -/* uwba_log, log the message output to dmesg according to err level */ -void -uwba_log(uwba_dev_t *uwba_dev, uint_t msglevel, char *formatarg, ...) -{ - va_list ap; - const char *devinst = NULL; - - if (msglevel <= uwba_errlevel) { - char *format; - int formatlen = strlen(formatarg) + 2; /* '!' and NULL char */ - int devinst_start = 0; - if (uwba_dev) { - devinst = uwba_dev->devinst; - } else { - devinst = "uwba: "; - } - ASSERT(devinst != NULL); - - /* Allocate extra room if driver name and instance is present */ - formatlen += strlen(devinst); - - format = kmem_zalloc(formatlen, KM_SLEEP); - - if (msglevel >= UWBA_LOG_LOG) { - format[0] = '!'; - devinst_start = 1; - } - - (void) strcpy(&format[devinst_start], devinst); - - va_start(ap, formatarg); - (void) strcat(format, formatarg); - vcmn_err(CE_CONT, format, ap); - va_end(ap); - - kmem_free(format, formatlen); - } -} - -/* Get a msg string of a event or notfication */ -const char * -uwba_event_msg(uint16_t wEvent) { - if (wEvent > UWB_CE_SET_ASIE_NOTIFICATION) { - return ("Unknown Message"); - } else { - return (uwba_evt_msg_table[wEvent]); - } -} diff --git a/usr/src/uts/common/io/uwb/uwba/uwbai.c b/usr/src/uts/common/io/uwb/uwba/uwbai.c deleted file mode 100644 index 17aa53556e..0000000000 --- a/usr/src/uts/common/io/uwb/uwba/uwbai.c +++ /dev/null @@ -1,1571 +0,0 @@ -/* - * 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 - * or http://www.opensolaris.org/os/licensing. - * 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. - */ - -/* - * UWB radio controller driver interfaces - */ -#include <sys/uwb/uwba/uwba.h> -#include <sys/sunndi.h> -#include <sys/ddi.h> - - -/* - * The following is a list of functions which handles the rccb command - * for uwb model, each rccb command has a related handler. Not all the - * rccb command is supportted, the below uwb_rccb_handler_tbl lists - * the supported handler - */ -static int uwb_do_cmd_rccb(uwb_dev_handle_t, uwb_rccb_cmd_t *); -static int uwb_do_cmd_scan(uwb_dev_handle_t, uwb_rccb_cmd_t *); -static int uwb_do_cmd_start_beacon(uwb_dev_handle_t, - uwb_rccb_cmd_t *); -static int uwb_do_cmd_dev_addr_mgmt(uwb_dev_handle_t, uwb_rccb_cmd_t *); - - -static int uwb_process_rccb_cmd_private(uwb_dev_handle_t, - uwb_rccb_cmd_t *, uwb_cmd_result_t *); - -static int uwb_send_rccb_cmd(uwb_dev_handle_t, uwb_rccb_cmd_t *); -static int uwb_check_rccb_cmd(uwb_dev_handle_t, uwb_rccb_cmd_t *); -static int uwb_check_dev_state(uwba_dev_t *, uwb_rccb_cmd_t *); -static void uwb_set_dev_state(uwba_dev_t *, uwb_rccb_cmd_t *); - -static int uwb_wait_cmd_result(uwb_dev_handle_t); -static void uwb_free_cmd_result(uwb_dev_handle_t); - -static int uwb_rccb_cmd_enter(uwba_dev_t *); -static void uwb_rccb_cmd_leave(uwba_dev_t *); - -static int uwb_do_ioctl_rccb_cmd(uwb_dev_handle_t, - uint16_t, intptr_t, int); - -static uwb_notif_wrapper_t *uwb_get_notification(uwb_dev_handle_t, - intptr_t, int); -static void uwb_free_notification(uwb_notif_wrapper_t *); -/* - * - * This is all the rccb command handler supported and not supported in - * current version. rccb handler table map - */ -static uwb_rccb_handler_t uwb_rccb_handler_tbl [] = { - UWB_RCCB_NULL_HANDLER, /* CHANNEL_CHANGE */ - uwb_do_cmd_dev_addr_mgmt, /* DEV_ADDR_MGMT */ - uwb_do_cmd_rccb, /* GET_IE */ - uwb_do_cmd_rccb, /* RESET */ - uwb_do_cmd_scan, /* SCAN */ - UWB_RCCB_NULL_HANDLER, /* SET_BEACON_FILTER */ - UWB_RCCB_NULL_HANDLER, /* SET_DRP_IE */ - UWB_RCCB_NULL_HANDLER, /* SET_IE */ - UWB_RCCB_NULL_HANDLER, /* SET_NOTIFICATION_FILTER */ - UWB_RCCB_NULL_HANDLER, /* SET_TX_POWER */ - UWB_RCCB_NULL_HANDLER, /* SLEEP */ - uwb_do_cmd_start_beacon, /* START_BEACON */ - uwb_do_cmd_rccb, /* STOP_BEACON */ - UWB_RCCB_NULL_HANDLER, /* BP_MERGE */ - UWB_RCCB_NULL_HANDLER /* SEND_COMMAND_FRAME */ -}; - -/* - * This table recode different size of the rccb command data block - * For those rccb command not supported, it is zero - */ -static uint8_t uwb_rccb_size_tbl [] = { - 0, /* CHANNEL_CHANGE */ - sizeof (uwb_rccb_dev_addr_mgmt_t), /* DEV_ADDR_MGMT */ - sizeof (uwb_rccb_cmd_t), /* GET_IE */ - sizeof (uwb_rccb_cmd_t), /* RESET */ - sizeof (uwb_rccb_scan_t), /* SCAN */ - 0, /* SET_BEACON_FILTER */ - 0, /* SET_DRP_IE */ - 0, /* SET_IE */ - 0, /* SET_NOTIFICATION_FILTER */ - 0, /* SET_TX_POWER */ - 0, /* SLEEP */ - sizeof (uwb_rccb_start_beacon_t), /* START_BEACON */ - sizeof (uwb_rccb_cmd_t), /* STOP_BEACON */ - 0, /* BP_MERGE */ - 0 /* SEND_COMMAND_FRAME */ -}; -_NOTE(SCHEME_PROTECTS_DATA("unique per call", uwba_dev::send_cmd)) -_NOTE(SCHEME_PROTECTS_DATA("unique per call", uwb_rceb_get_ie)) -_NOTE(SCHEME_PROTECTS_DATA("unique per call", uwb_rceb_result_code)) - -/* - * Called by radio controller driver's attach() to register the device to uwba. - * Including alloc and init the uwb_dev_handle - */ -void -uwb_dev_attach(dev_info_t *dip, uwb_dev_handle_t *uwb_dev_handle, - uint_t rcd_intr_pri, int (*send_cmd)(uwb_dev_handle_t uwb_dev_hdl, - mblk_t *data, uint16_t data_len)) -{ - uwba_dev_t *uwba_dev; - - uwba_alloc_uwb_dev(dip, &uwba_dev, rcd_intr_pri); - - uwba_init_ctxt_id(uwba_dev); - uwba_dev->send_cmd = send_cmd; - - uwba_dev_add_to_list(uwba_dev); - - *uwb_dev_handle = (uwb_dev_handle_t)uwba_dev; - -} - -/* - * Called by radio controller driver's dettach() to unregister the device from - * uwba. Including dealloc and fnit the uwb_dev_handle - */ -void -uwb_dev_detach(uwb_dev_handle_t uwb_dev_hdl) -{ - uwba_dev_t *uwba_dev = (uwba_dev_t *)uwb_dev_hdl; - - uwba_dev_rm_from_list(uwba_dev); - uwba_fini_ctxt_id(uwba_dev); - uwba_free_uwb_dev(uwba_dev); -} - -/* - * Called by the radio controler to the dip from a uwb_dev_handle - */ -dev_info_t * -uwb_get_dip(uwb_dev_handle_t uwb_dev_hdl) -{ - if (uwb_dev_hdl) { - - return (((uwba_dev_t *)uwb_dev_hdl)->dip); - } - - return (NULL); -} - -/* - * Called by host controller or radio controller, this function set the - * ddi_no_autodetach to for the hwarc dip. Radio controller interface - * should alway be detached after the host controller detachment. - * So it should be called while the hwahc is attaching - * dip- a hwahc dip or a hwarc dip - */ -int -uwb_dev_online(dev_info_t *dip) -{ - dev_info_t *pdip, *child_dip; - int rval = UWB_FAILURE; - uwba_dev_t *uwba_dev = NULL; - uwb_dev_handle_t uwb_dev_hdl = uwba_dev_search(dip); - uwba_dev = (uwba_dev_t *)uwb_dev_hdl; - if (uwb_dev_hdl != NULL) { - (void) ddi_prop_update_int(DDI_DEV_T_NONE, uwba_dev->dip, - DDI_NO_AUTODETACH, 1); - - return (UWB_SUCCESS); - } - - pdip = ddi_get_parent(dip); - child_dip = ddi_get_child(pdip); - while (child_dip != NULL) { - if (child_dip != dip) { - /* Force the dip online */ - if (ndi_devi_online(child_dip, NDI_ONLINE_ATTACH) != - NDI_SUCCESS) { - uwba_log(uwba_dev, UWBA_LOG_LOG, - "fail to online dip = %p, node_name = %s", - dip, ddi_node_name(child_dip)); - } - - /* - * Update the dip properties if it is a radio - * controller node - */ - if (strcmp(ddi_node_name(child_dip), "hwa-radio") == - 0) { - (void) ddi_prop_update_int(DDI_DEV_T_NONE, - child_dip, DDI_NO_AUTODETACH, 1); - rval = UWB_SUCCESS; - break; - } - } - - child_dip = ddi_get_next_sibling(child_dip); - } - - return (rval); - -} - -/* - * Called by hwahc when detaching. - * The hwarc should be detached after the hwahc. So it should only be - * called when hwahc is detaching. - */ -int -uwb_dev_offline(dev_info_t *dip) -{ - uwba_dev_t *uwba_dev = NULL; - uwb_dev_handle_t uwb_dev_hdl = uwba_dev_search(dip); - if (uwb_dev_hdl == NULL) { - uwba_log(NULL, UWBA_LOG_LOG, - "uwb_dev_offline::no dev for dip:0x%p", dip); - - return (UWB_FAILURE); - } - uwba_dev = (uwba_dev_t *)uwb_dev_hdl; - uwba_log(uwba_dev, UWBA_LOG_LOG, - " uwb_dev_offline dip = 0x%p", dip); - (void) ddi_prop_update_int(DDI_DEV_T_NONE, uwba_dev->dip, - DDI_NO_AUTODETACH, 0); - - return (UWB_SUCCESS); - -} -/* - * Called by hwarc when disconnect or suspend. - * Stop beacon. In addition, uwb will save the current channel - * and dev state. - */ -int -uwb_dev_disconnect(dev_info_t *dip) -{ - uwba_dev_t *uwba_dev = NULL; - uwb_dev_handle_t uwb_dev_hdl = uwba_dev_search(dip); - if (uwb_dev_hdl == NULL) { - uwba_log(NULL, UWBA_LOG_LOG, - "uwb_dev_offline::no dev for dip:0x%p", dip); - - return (UWB_FAILURE); - } - uwba_dev = (uwba_dev_t *)uwb_dev_hdl; - - mutex_enter(&uwba_dev->dev_mutex); - uint8_t channel = uwba_dev->channel; - uint8_t state = uwba_dev->dev_state; - mutex_exit(&uwba_dev->dev_mutex); - - - uwba_log(uwba_dev, UWBA_LOG_LOG, - " uwb_dev_disconnect dip = 0x%p, channel=%d, state=%d", - dip, channel, state); - - if (state == UWB_STATE_BEACON) { - (void) uwb_stop_beacon(dip); - } - - mutex_enter(&uwba_dev->dev_mutex); - uwba_dev->channel = channel; - uwba_dev->dev_state = state; - mutex_exit(&uwba_dev->dev_mutex); - - - return (UWB_SUCCESS); - -} - -/* - * Called by hwarc when reconnect or resume. - * Start beacon and set the dev address whchi is saved - * in disconnect or suspend. - */ -int -uwb_dev_reconnect(dev_info_t *dip) -{ - uwba_dev_t *uwba_dev = NULL; - uwb_dev_handle_t uwb_dev_hdl = uwba_dev_search(dip); - if (uwb_dev_hdl == NULL) { - uwba_log(NULL, UWBA_LOG_LOG, - "uwb_dev_offline::no dev for dip:0x%p", dip); - - return (UWB_FAILURE); - } - uwba_dev = (uwba_dev_t *)uwb_dev_hdl; - - mutex_enter(&uwba_dev->dev_mutex); - uint8_t channel = uwba_dev->channel; - uint8_t state = uwba_dev->dev_state; - uwba_dev->dev_state = UWB_STATE_IDLE; - mutex_exit(&uwba_dev->dev_mutex); - - uwba_log(uwba_dev, UWBA_LOG_LOG, - " uwb_dev_reconnect dip = 0x%p, channel= %d, state = %d", - dip, channel, state); - - - (void) uwb_set_dev_addr(dip, uwba_dev->dev_addr); - - if (state == UWB_STATE_BEACON) { - (void) uwb_start_beacon(dip, uwba_dev->channel); - } - - - return (UWB_SUCCESS); - -} - - - -/* - * This is a common interface for other models to send a - * rccb command to the radio controller - */ -int -uwb_process_rccb_cmd(dev_info_t *dip, uwb_rccb_cmd_t *rccb_cmd, - uwb_cmd_result_t *cmd_result) -{ - int rval = UWB_SUCCESS; - uwb_dev_handle_t uwb_dev_hdl = uwba_dev_search(dip); - if (uwb_dev_hdl == NULL) { - uwba_log(NULL, UWBA_LOG_LOG, - "uwb_process_rccb_cmd::no dev for dip:0x%p", dip); - - return (UWB_FAILURE); - } - - /* check if it is a valid rccb command */ - if (uwb_check_rccb_cmd(uwb_dev_hdl, rccb_cmd) != UWB_SUCCESS) { - - return (UWB_FAILURE); - } - - rval = uwb_process_rccb_cmd_private(uwb_dev_hdl, rccb_cmd, cmd_result); - - return (rval); -} - -/* - * Find a free chanel by scaning the supported channels - */ -uint8_t -uwb_allocate_channel(dev_info_t *dip) -{ - uwb_dev_handle_t uwb_dev_hdl = uwba_dev_search(dip); - uint8_t channel = 0; - if (!uwb_dev_hdl) { - uwba_log(NULL, UWBA_LOG_LOG, - "uwb_send_rccb_cmd: uwba dev not found"); - goto done; - } - uwba_log((uwba_dev_t *)uwb_dev_hdl, UWBA_LOG_DEBUG, - "uwb_allocate_channel: enter"); - channel = uwba_allocate_channel(uwb_dev_hdl); -done: - return (channel); -} -/* scan a channel and wait for a while to get beacon info */ -int -uwb_scan_channel(uwb_dev_handle_t uwb_dev_hdl, uint8_t channel) -{ - - uwb_rccb_scan_t rccb_cmd; - - bzero(&rccb_cmd, sizeof (rccb_cmd)); - rccb_cmd.rccb.bCommandType = UWB_CE_TYPE_GENERAL; - - rccb_cmd.rccb.wCommand = UWB_CE_SCAN; - rccb_cmd.bScanState = UWB_RC_SCAN_ONLY; - rccb_cmd.wStartTime = 0; - rccb_cmd.bChannelNumber = channel; - - uwba_log((uwba_dev_t *)uwb_dev_hdl, UWBA_LOG_DEBUG, - "uwb_scan_channel: channel = %d", channel); - /* Scan a specific channel */ - - if (uwb_process_rccb_cmd_private(uwb_dev_hdl, - (uwb_rccb_cmd_t *)&rccb_cmd, NULL) != 0) { - uwba_log((uwba_dev_t *)uwb_dev_hdl, UWBA_LOG_LOG, - "uwb_scan_channel: process cmd failed"); - - return (UWB_FAILURE); - } - - /* wait for beacon info */ - delay(drv_usectohz(300000)); - - /* stop scan in the channel */ - rccb_cmd.bScanState = UWB_RC_SCAN_DISABLED; - - if (uwb_process_rccb_cmd_private(uwb_dev_hdl, - (uwb_rccb_cmd_t *)&rccb_cmd, (uwb_cmd_result_t *)NULL) != 0) { - uwba_log((uwba_dev_t *)uwb_dev_hdl, UWBA_LOG_LOG, - "uwb_scan_channel: process cmd failed, channel = %d", - channel); - - return (UWB_FAILURE); - } - - return (UWB_SUCCESS); -} - -/* Stop beacon common interface */ -int -uwb_stop_beacon(dev_info_t *dip) -{ - uwb_rccb_cmd_t rccb_cmd; - uwb_rceb_result_code_t ret; - - uwb_dev_handle_t uwb_dev_hdl = uwba_dev_search(dip); - if (uwb_dev_hdl == NULL) { - uwba_log(NULL, UWBA_LOG_LOG, - "uwb_stop_beacon::no dev for dip:0x%p", dip); - - return (UWB_FAILURE); - } - - uwba_log((uwba_dev_t *)uwb_dev_hdl, UWBA_LOG_DEBUG, - "uwb_stop_beacon: enter"); - - bzero(&rccb_cmd, sizeof (rccb_cmd)); - rccb_cmd.rccb.bCommandType = UWB_CE_TYPE_GENERAL; - - rccb_cmd.rccb.wCommand = UWB_CE_STOP_BEACON; - - if (uwb_process_rccb_cmd_private(uwb_dev_hdl, - (uwb_rccb_cmd_t *)&rccb_cmd, (uwb_cmd_result_t *)&ret) != 0) { - uwba_log((uwba_dev_t *)uwb_dev_hdl, UWBA_LOG_LOG, - "uwb_stop_beacon: process cmd failed"); - - return (UWB_FAILURE); - } - - if (ret.bResultCode != 0) { - uwba_log((uwba_dev_t *)uwb_dev_hdl, UWBA_LOG_LOG, - "uwb_stop_beacon: bResultCode =%d", ret.bResultCode); - - return (UWB_FAILURE); - } - - return (UWB_SUCCESS); -} - -/* - * Start beacon common interface - * start beaconing on specified channel - */ -int -uwb_start_beacon(dev_info_t *dip, uint8_t channel) -{ - uwb_rccb_start_beacon_t rccb_cmd; - uwb_rceb_result_code_t ret; - uwb_dev_handle_t uwb_dev_hdl = uwba_dev_search(dip); - - if (uwb_dev_hdl == NULL) { - uwba_log(NULL, UWBA_LOG_LOG, - "uwb_start_beacon::no dev for dip:0x%p, channel = %d", - dip, channel); - - return (UWB_FAILURE); - } - - uwba_log((uwba_dev_t *)uwb_dev_hdl, UWBA_LOG_DEBUG, - "uwb_start_beacon: channel = %d", channel); - bzero(&rccb_cmd, sizeof (rccb_cmd)); - rccb_cmd.rccb.bCommandType = UWB_CE_TYPE_GENERAL; - - - rccb_cmd.rccb.wCommand = UWB_CE_START_BEACON; - /* todo: this needs to be fixed later */ - rccb_cmd.wBPSTOffset = 0; - rccb_cmd.bChannelNumber = channel; - - if (uwb_process_rccb_cmd_private(uwb_dev_hdl, - (uwb_rccb_cmd_t *)&rccb_cmd, (uwb_cmd_result_t *)&ret) != 0) { - uwba_log((uwba_dev_t *)uwb_dev_hdl, UWBA_LOG_LOG, - "uwb_start_beacon: process cmd failed" - "channel = %d", channel); - - return (UWB_FAILURE); - } - - - if (ret.bResultCode != 0) { - uwba_log((uwba_dev_t *)uwb_dev_hdl, UWBA_LOG_LOG, - "uwb_start_beacon: bResultCode =%d", ret.bResultCode); - - return (UWB_FAILURE); - } - - return (UWB_SUCCESS); -} - -/* Get the mac address of the radion controller */ -int -uwb_get_mac_addr(dev_info_t *dip, uint8_t *mac_addr) -{ - uwb_rccb_dev_addr_mgmt_t rccb_cmd; - uwb_rceb_dev_addr_mgmt_t ret; - - uwb_dev_handle_t uwb_dev_hdl = uwba_dev_search(dip); - if (uwb_dev_hdl == NULL) { - uwba_log(NULL, UWBA_LOG_LOG, - "uwb_get_mac_addr::no dev for dip:0x%p", dip); - - return (UWB_FAILURE); - } - - uwba_log((uwba_dev_t *)uwb_dev_hdl, UWBA_LOG_DEBUG, - "uwb_get_mac_addr: enter"); - - bzero(&rccb_cmd, sizeof (rccb_cmd)); - rccb_cmd.rccb.bCommandType = UWB_CE_TYPE_GENERAL; - - rccb_cmd.rccb.wCommand = UWB_CE_DEV_ADDR_MGMT; - rccb_cmd.bmOperationType = 2; /* get MAC. XXX: should use Macro */ - - if (uwb_process_rccb_cmd_private(uwb_dev_hdl, - (uwb_rccb_cmd_t *)&rccb_cmd, (uwb_cmd_result_t *)&ret) != 0) { - uwba_log((uwba_dev_t *)uwb_dev_hdl, UWBA_LOG_LOG, - "uwb_get_mac_addr: process cmd failed"); - - return (UWB_FAILURE); - } - - - if (ret.bResultCode != 0) { - uwba_log((uwba_dev_t *)uwb_dev_hdl, UWBA_LOG_LOG, - "uwb_get_mac_addr: bResultCode =%d", ret.bResultCode); - - return (UWB_FAILURE); - } - (void) memcpy(mac_addr, ret.baAddr, 6); - - return (UWB_SUCCESS); -} - -/* Get the device address of the radion controller */ -int -uwb_get_dev_addr(dev_info_t *dip, uint16_t *dev_addr) -{ - uwb_rccb_dev_addr_mgmt_t rccb_cmd; - uwb_rceb_dev_addr_mgmt_t ret; - - uwb_dev_handle_t uwb_dev_hdl = uwba_dev_search(dip); - if (uwb_dev_hdl == NULL) { - uwba_log(NULL, UWBA_LOG_LOG, - "uwb_get_dev_addr::no dev for dip:0x%p", dip); - - return (UWB_FAILURE); - } - - uwba_log((uwba_dev_t *)uwb_dev_hdl, UWBA_LOG_DEBUG, - "uwb_get_dev_addr: enter"); - - bzero(&rccb_cmd, sizeof (rccb_cmd)); - rccb_cmd.rccb.bCommandType = UWB_CE_TYPE_GENERAL; - - rccb_cmd.rccb.wCommand = UWB_CE_DEV_ADDR_MGMT; - rccb_cmd.bmOperationType = 0; /* get 16-bit dev addr */ - - if (uwb_process_rccb_cmd_private(uwb_dev_hdl, - (uwb_rccb_cmd_t *)&rccb_cmd, (uwb_cmd_result_t *)&ret) != 0) { - uwba_log((uwba_dev_t *)uwb_dev_hdl, UWBA_LOG_LOG, - "uwb_get_dev_addr: process cmd failed"); - - return (UWB_FAILURE); - } - if (ret.bResultCode != 0) { - uwba_log((uwba_dev_t *)uwb_dev_hdl, UWBA_LOG_LOG, - "uwb_get_dev_addr: bResultCode =%d", ret.bResultCode); - - return (UWB_FAILURE); - } - *dev_addr = ret.baAddr[0] | (ret.baAddr[1] << 8); - - return (UWB_SUCCESS); -} - -/* Set the device address of the radion controller */ -int -uwb_set_dev_addr(dev_info_t *dip, uint16_t dev_addr) -{ - uwb_rccb_dev_addr_mgmt_t rccb_cmd; - uwb_rceb_dev_addr_mgmt_t ret; - - uwb_dev_handle_t uwb_dev_hdl = uwba_dev_search(dip); - if (uwb_dev_hdl == NULL) { - uwba_log(NULL, UWBA_LOG_LOG, - "uwb_set_dev_addr::no dev for dip:0x%p, dev_addr=%d", - dip, dev_addr); - - return (UWB_FAILURE); - } - - uwba_log((uwba_dev_t *)uwb_dev_hdl, UWBA_LOG_DEBUG, - "uwb_set_dev_addr: dev_addr = %d", dev_addr); - - bzero(&rccb_cmd, sizeof (rccb_cmd)); - rccb_cmd.rccb.bCommandType = UWB_CE_TYPE_GENERAL; - - rccb_cmd.rccb.wCommand = UWB_CE_DEV_ADDR_MGMT; - rccb_cmd.bmOperationType = 1; /* set 16-bit dev addr */ - rccb_cmd.baAddr[0] = dev_addr & 0xff; - rccb_cmd.baAddr[1] = (dev_addr >> 8) & 0xff; - - if (uwb_process_rccb_cmd_private(uwb_dev_hdl, - (uwb_rccb_cmd_t *)&rccb_cmd, (uwb_cmd_result_t *)&ret) != 0) { - uwba_log((uwba_dev_t *)uwb_dev_hdl, UWBA_LOG_LOG, - "uwb_set_dev_addr: process cmd failed" - "dev_addr=%d", dev_addr); - - return (UWB_FAILURE); - } - - - if (ret.bResultCode != 0) { - uwba_log((uwba_dev_t *)uwb_dev_hdl, UWBA_LOG_LOG, - "uwb_set_dev_addr: bResultCode =%d", ret.bResultCode); - - return (UWB_FAILURE); - } - - return (UWB_SUCCESS); -} - -/* - * Reset the radio controller. - * This is called when the radio controller is attached. - * Notice:Radio controller should not be reset when it - * is beaconing or scaning. - */ -int -uwb_reset_dev(dev_info_t *dip) -{ - uwb_rccb_cmd_t rccb_cmd; - uwb_rceb_result_code_t ret; - - uwb_dev_handle_t uwb_dev_hdl = uwba_dev_search(dip); - if (uwb_dev_hdl == NULL) { - uwba_log(NULL, UWBA_LOG_LOG, - "uwb_reset_dev:no dev for dip:0x%p", dip); - - return (UWB_FAILURE); - } - - uwba_log((uwba_dev_t *)uwb_dev_hdl, UWBA_LOG_DEBUG, - "uwb_reset_dev: enter"); - bzero(&rccb_cmd, sizeof (rccb_cmd)); - rccb_cmd.rccb.bCommandType = UWB_CE_TYPE_GENERAL; - rccb_cmd.rccb.wCommand = UWB_CE_RESET; - - if (uwb_process_rccb_cmd_private(uwb_dev_hdl, - (uwb_rccb_cmd_t *)&rccb_cmd, (uwb_cmd_result_t *)&ret) != 0) { - uwba_log((uwba_dev_t *)uwb_dev_hdl, UWBA_LOG_LOG, - "uwb_reset_dev: process cmd failed"); - - return (UWB_FAILURE); - } - if (ret.bResultCode != 0) { - uwba_log((uwba_dev_t *)uwb_dev_hdl, UWBA_LOG_LOG, - "uwb_reset_dev: bResultCode =%d", ret.bResultCode); - - return (UWB_FAILURE); - } - - return (UWB_SUCCESS); -} - -/* - * Called while attaching. - * The physical capabilities is initialized. - * Only the supported channels is used in current version - */ -int -uwb_init_phy(dev_info_t *dip) -{ - uwb_rccb_cmd_t rccb_cmd; - - uwb_dev_handle_t uwb_dev_hdl = uwba_dev_search(dip); - if (uwb_dev_hdl == NULL) { - uwba_log(NULL, UWBA_LOG_LOG, - "uwb_init_phy::no dev for dip:0x%p", dip); - - return (UWB_FAILURE); - } - - uwba_log((uwba_dev_t *)uwb_dev_hdl, UWBA_LOG_DEBUG, - "uwb_init_phy: enter"); - bzero(&rccb_cmd, sizeof (rccb_cmd)); - rccb_cmd.rccb.bCommandType = UWB_CE_TYPE_GENERAL; - rccb_cmd.rccb.wCommand = UWB_CE_GET_IE; - - if (uwb_process_rccb_cmd_private(uwb_dev_hdl, - (uwb_rccb_cmd_t *)&rccb_cmd, (uwb_cmd_result_t *)NULL) != 0) { - uwba_log((uwba_dev_t *)uwb_dev_hdl, UWBA_LOG_LOG, - "uwb_init_phy: process cmd failed"); - - return (UWB_FAILURE); - } - /* todo: rceb result is handled in event notification */ - - return (UWB_SUCCESS); -} - - -/* Get a notif from the list head. That notif is dis-linked from the list. */ -static uwb_notif_wrapper_t * -uwb_get_notif_head(uwb_dev_handle_t uwb_dev_hdl) -{ - uwb_notif_wrapper_t *nw = NULL; - uwba_dev_t *uwba_dev = (uwba_dev_t *)uwb_dev_hdl; - - mutex_enter(&uwba_dev->dev_mutex); - - if (!list_is_empty(&uwba_dev->notif_list)) { - nw = list_head(&uwba_dev->notif_list); - if (nw != NULL) { - - /* - * unlink a notification wrapper's structure from the - * list - */ - list_remove(&(uwba_dev->notif_list), nw); - } - } - mutex_exit(&uwba_dev->dev_mutex); - - return (nw); -} - -/* - * UWB ioctls - * UWB_COMMAND --- Send a rccb command to the radio controller - * UWB_GET_NOTIFICATION -- Get the uwb notifications. Not used - */ -int -uwb_do_ioctl(uwb_dev_handle_t uwb_dev_hdl, - int cmd, intptr_t arg, int mode) -{ - uwba_dev_t *uwba_dev = (uwba_dev_t *)uwb_dev_hdl; - int rv = 0; - - switch (cmd) { - case UWB_COMMAND: /* Issue commands to UWB Radio Controller */ - { - uwb_rccb_cmd_t rccb_cmd; - if (ddi_copyin((caddr_t)arg, &rccb_cmd, - sizeof (rccb_cmd), mode)) { - uwba_log(uwba_dev, UWBA_LOG_LOG, - "uwb_do_ioctl: ddi_copyin fail"); - - rv = EFAULT; - break; - } - if (uwb_check_rccb_cmd(uwb_dev_hdl, &rccb_cmd) != UWB_SUCCESS) { - - rv = EINVAL; - break; - } - if (uwb_do_ioctl_rccb_cmd(uwb_dev_hdl, rccb_cmd.rccb.wCommand, - arg, mode) - != UWB_SUCCESS) { - - uwba_log(uwba_dev, UWBA_LOG_LOG, - "uwb_do_ioctl: uwb_do_ioctl_rccb_cmd failed"); - rv = EIO; - } - - break; - } - case UWB_GET_NOTIFICATION: - { - uwb_notif_wrapper_t *nw; - - nw = uwb_get_notification(uwb_dev_hdl, arg, mode); - - if (nw && nw->notif) { - /* Copy the notification to userland application */ - if (ddi_copyout(nw->notif, - (caddr_t)&(((uwb_notif_get_t *)arg)->notif), - nw->length, mode)) { /* todo: 32bit/64bit */ - - rv = EFAULT; - } - /* release the notif and the wrapper. */ - uwb_free_notification(nw); - } else { - rv = EIO; - } - - break; - } - default: - uwba_log(uwba_dev, UWBA_LOG_LOG, - "uwb_do_ioctl: not a valid cmd value, cmd=%x", cmd); - rv = EINVAL; - } - - uwba_log(uwba_dev, UWBA_LOG_DEBUG, - "uwb_do_ioctl: exit, rv=%d", rv); - - return (rv); -} - - -/* - * Parse all the standard events, including command results and notifications. - * If a unknown event, return UWB_NOT_SUPPORTED. The specific client radio - * controllers might has the knowledge to parse the vendor specific - * events/notifications. - */ -int -uwb_parse_evt_notif(uint8_t *data, int data_len, - uwb_dev_handle_t uwb_dev_hdl) -{ - uint16_t evt_code, evt_size; - void *evt_struct; - uwb_rceb_head_t *rceb; - uwba_dev_t *uwba_dev; - uint8_t *spec_data; /* the raw event data excluding rceb. */ - int spec_data_len, offset; - int rval = UWB_SUCCESS; - - uwba_dev = (uwba_dev_t *)uwb_dev_hdl; - - /* Get evt/notif code */ - if ((evt_code = uwba_get_evt_code(data, data_len)) == - UWB_INVALID_EVT_CODE) { - uwba_log(uwba_dev, UWBA_LOG_LOG, - "uwb_parse_evt_notif: invalid evt_code"); - - return (UWB_INVALID_EVT_CODE); - } - - if ((evt_size = uwba_get_evt_size(data, data_len, evt_code)) == - UWB_INVALID_EVT_SIZE) { - uwba_log(uwba_dev, UWBA_LOG_LOG, - "uwb_parse_evt_notif: invalid evt_size. evt_code=%d", - evt_code); - - return (UWB_INVALID_EVT_SIZE); - } - evt_struct = kmem_alloc(evt_size, KM_NOSLEEP); - if (evt_struct == NULL) { - - return (UWB_NO_RESOURCES); - } - - /* parse rceb and get the data offset just after the rceb struct. */ - if ((offset = uwba_parse_rceb(data, data_len, evt_struct, evt_size)) - == UWB_PARSE_ERROR) { - uwba_log(uwba_dev, UWBA_LOG_LOG, - "uwb_parse_evt_notif: uwba_parse_rceb failed"); - kmem_free(evt_struct, evt_size); - - return (UWB_PARSE_ERROR); - } - rceb = (uwb_rceb_head_t *)evt_struct; - if (rceb->bEventContext > 0 && - rceb->bEventContext != uwba_dev->ctxt_id) { - uwba_log(uwba_dev, UWBA_LOG_LOG, - "uwb_parse_evt_notif: cmd result's ctxt_id is " - "not matching cmd's ctxt_id," - " result ctxt_id=%d, cmd ctxt_id=%d", - rceb->bEventContext, uwba_dev->ctxt_id); - } - - /* the data after rceb head are evt specific data */ - spec_data = data + offset; - spec_data_len = data_len - offset; - - switch (evt_code) { - case UWB_CE_CHANNEL_CHANGE: - case UWB_CE_RESET: - case UWB_CE_SCAN: - case UWB_CE_SET_BEACON_FILTER: - case UWB_CE_SET_NOTIFICATION_FILTER: - case UWB_CE_SET_TX_POWER: - case UWB_CE_SLEEP: - case UWB_CE_START_BEACON: - case UWB_CE_STOP_BEACON: - case UWB_CE_BP_MERGE: - case UWB_CE_SEND_COMMAND_FRAME: - case UWB_CE_SET_ASIE_NOTIFICATION: - /* All the above cmd results have only result code. */ - ((uwb_rceb_result_code_t *)evt_struct)->bResultCode = - *spec_data; - uwba_log(uwba_dev, UWBA_LOG_DEBUG, - "uwb_parse_evt_notif: msg = %s, bResultCode = %d ", - uwba_event_msg(evt_code), *spec_data); - - break; - case UWB_CE_DEV_ADDR_MGMT: - rval = uwba_parse_dev_addr_mgmt(spec_data, spec_data_len, - (uwb_rceb_dev_addr_mgmt_t *)evt_struct); - - break; - case UWB_CE_GET_IE: - rval = uwba_parse_get_ie(uwb_dev_hdl, spec_data, spec_data_len, - (uwb_rceb_get_ie_t *)evt_struct); - - break; - case UWB_NOTIF_BEACON_RECEIVED: - rval = uwba_parse_beacon_rcv(uwb_dev_hdl, spec_data, - spec_data_len, (uwb_rceb_beacon_t *)evt_struct); - break; - case UWB_NOTIF_BPOIE_CHANGE: - rval = uwba_parse_bpoie_chg(uwb_dev_hdl, spec_data, - spec_data_len, (uwb_rceb_bpoie_change_t *)evt_struct); - break; - - case UWB_NOTIF_BEACON_SIZE_CHANGE: - case UWB_CE_SET_DRP_IE: - case UWB_CE_SET_IE: - case UWB_NOTIF_IE_RECEIVED: - case UWB_NOTIF_BP_SLOT_CHANGE: - case UWB_NOTIF_BP_SWITCH_IE_RECEIVED: - case UWB_NOTIF_DEV_ADDR_CONFLICT: - case UWB_NOTIF_DRP_AVAILABILITY_CHANGE: - case UWB_NOTIF_DRP: - case UWB_NOTIF_BP_SWITCH_STATUS: - case UWB_NOTIF_CMD_FRAME_RCV: - case UWB_NOTIF_CHANNEL_CHANGE_IE_RCV: - uwba_log(uwba_dev, UWBA_LOG_DEBUG, - "uwb_parse_evt_notif: %s not supported", - uwba_event_msg(evt_code)); - break; - - default: /* unkonwn events or notifications */ - uwba_log(uwba_dev, UWBA_LOG_LOG, - "uwb_parse_evt_notif: unkonwn events or notifications," - " evt_code=%d", evt_code); - break; - } - - if (rval != UWB_SUCCESS) { - uwba_log(uwba_dev, UWBA_LOG_LOG, - "uwb_parse_evt_notif: fail, rval = %d", rval); - - kmem_free(evt_struct, evt_size); - - return (rval); - } - - /* - * By now, parse complete. Go on notify the waiting cmd thread or add - * notification to list - */ - if (evt_code > UWB_NOTIF_RESERVED) { - /* If this event is a cmd result */ - uwba_put_cmd_result(uwba_dev, evt_struct, evt_size); - } else { - - /* If this event is a notification */ - rval = uwba_add_notif_to_list(uwba_dev, evt_struct, evt_size); - } - - return (rval); -} - - -/* - * Send command to device. This function is shared by those commands whose cmd - * data have rccb only. - */ -static int -uwb_do_cmd_rccb(uwb_dev_handle_t uwb_dev_hdl, uwb_rccb_cmd_t *rccb_cmd) -{ - /* reset cmd has no extra bytes, just rccb */ - mblk_t *data; - uint16_t data_len; - uwba_dev_t *uwba_dev; - int rval = UWB_SUCCESS; - - uwba_dev = (uwba_dev_t *)uwb_dev_hdl; - - /* size of rccb. Reset cmd has no data other than rccb head */ - data_len = UWB_RAW_RCCB_HEAD_SIZE; - - uwba_log(uwba_dev, UWBA_LOG_DEBUG, - "uwb_do_cmd_rccb: wLength=%d", data_len); - - /* Data block */ - if ((data = allocb(data_len, BPRI_HI)) == NULL) { - uwba_log(uwba_dev, UWBA_LOG_LOG, - "uwb_do_cmd_rccb: allocb failed"); - - return (UWB_FAILURE); - } - - uwba_fill_rccb_head(uwba_dev, rccb_cmd->rccb.wCommand, data); - data->b_wptr += data_len; - - /* record the current cmd rccb to the uwb dev handle. */ - uwba_copy_rccb(rccb_cmd, &(uwba_dev->curr_rccb)); - uwba_dev->curr_rccb.rccb.bCommandContext = data->b_rptr[3]; - - /* - * data will be freed by radio client driver after the cmd is sent to - * device - */ - rval = uwba_dev->send_cmd(uwb_dev_hdl, data, data_len); - if (rval != UWB_SUCCESS) { - uwba_log(uwba_dev, UWBA_LOG_LOG, - "uwb_do_cmd_rccb: send cmd fail "); - - return (rval); - } - - return (rval); -} - -/* Dev addr management rccb cmd handler */ -static int -uwb_do_cmd_dev_addr_mgmt(uwb_dev_handle_t uwb_dev_hdl, - uwb_rccb_cmd_t *rccb_cmd) -{ - mblk_t *data; - uint16_t data_len; - uwba_dev_t *uwba_dev; - int i, rval = UWB_SUCCESS; - uwb_rccb_dev_addr_mgmt_t *rccb_dev_addr = - (uwb_rccb_dev_addr_mgmt_t *)rccb_cmd; - - uwba_dev = (uwba_dev_t *)uwb_dev_hdl; - /* size of device address mgmt RCCB */ - data_len = UWB_RAW_RCCB_HEAD_SIZE + 7; - - uwba_log(uwba_dev, UWBA_LOG_DEBUG, - "uwb_do_cmd_dev_addr_mgmt: wLength=%d, type=%x", - data_len, rccb_dev_addr->bmOperationType); - - /* Data block */ - if ((data = allocb(data_len, BPRI_HI)) == NULL) { - uwba_log(uwba_dev, UWBA_LOG_LOG, - "uwb_do_cmd_dev_addr_mgmt: allocb failed"); - - return (UWB_NO_RESOURCES); - } - - uwba_fill_rccb_head(uwba_dev, rccb_dev_addr->rccb.wCommand, data); - data->b_rptr[4] = rccb_dev_addr->bmOperationType; - for (i = 0; i < 6; i++) { - data->b_rptr[5 + i] = rccb_dev_addr->baAddr[i]; - } - data->b_wptr += data_len; - - /* record the current cmd rccb to the uwb dev handle. */ - uwba_copy_rccb((uwb_rccb_cmd_t *)rccb_dev_addr, &(uwba_dev->curr_rccb)); - uwba_dev->curr_rccb.rccb.bCommandContext = data->b_rptr[3]; - - if ((rval = uwba_dev->send_cmd(uwb_dev_hdl, data, data_len)) - != UWB_SUCCESS) { - uwba_log(uwba_dev, UWBA_LOG_LOG, - "uwb_do_cmd_dev_addr_mgmt: fail "); - - return (rval); - } - - uwba_log(uwba_dev, UWBA_LOG_DEBUG, - "uwb_do_cmd_dev_addr_mgmt: success."); - - return (rval); -} - -/* Scan rccb cmd handler */ -static int -uwb_do_cmd_scan(uwb_dev_handle_t uwb_dev_hdl, uwb_rccb_cmd_t *rccb_cmd) -{ - mblk_t *data; - uint16_t data_len; - uwba_dev_t *uwba_dev; - int rval = UWB_SUCCESS; - uwb_rccb_scan_t *rccb_scan = (uwb_rccb_scan_t *)rccb_cmd; - - uwba_dev = (uwba_dev_t *)uwb_dev_hdl; - data_len = UWB_RAW_RCCB_HEAD_SIZE + 4; /* size of scan RCCB */ - - uwba_log(uwba_dev, UWBA_LOG_DEBUG, - "uwb_do_cmd_scan: wLength=%d", data_len); - - /* Data block */ - if ((data = allocb(data_len, BPRI_HI)) == NULL) { - uwba_log(uwba_dev, UWBA_LOG_LOG, - "uwb_do_cmd_scan: allocb failed"); - - return (UWB_NO_RESOURCES); - } - - uwba_fill_rccb_head(uwba_dev, rccb_scan->rccb.wCommand, data); - data->b_rptr[4] = rccb_scan->bChannelNumber; - data->b_rptr[5] = rccb_scan->bScanState; - UINT16_TO_LE(rccb_scan->wStartTime, 6, data->b_rptr); - data->b_wptr += data_len; - - /* record the current cmd rccb to the uwb dev handle. */ - uwba_copy_rccb((uwb_rccb_cmd_t *)rccb_scan, &(uwba_dev->curr_rccb)); - uwba_dev->curr_rccb.rccb.bCommandContext = data->b_rptr[3]; - - if ((rval = uwba_dev->send_cmd(uwb_dev_hdl, data, data_len)) - != UWB_SUCCESS) { - uwba_log(uwba_dev, UWBA_LOG_LOG, - "uwb_send_rccb_cmd: fail "); - - return (rval); - } - - uwba_log(uwba_dev, UWBA_LOG_DEBUG, - "uwb_do_cmd_scan: success."); - - return (rval); -} - -/* Start beacon rccb handler */ -static int -uwb_do_cmd_start_beacon(uwb_dev_handle_t uwb_dev_hdl, - uwb_rccb_cmd_t *rccb_cmd) -{ - mblk_t *data; - uint16_t data_len; - uwba_dev_t *uwba_dev = (uwba_dev_t *)uwb_dev_hdl; - int rval = UWB_SUCCESS; - uwba_client_dev_t *client = NULL; - uwb_rccb_start_beacon_t *rccb_startbc = - (uwb_rccb_start_beacon_t *)rccb_cmd; - - if (client = uwba_find_cdev_by_channel(uwba_dev, - rccb_startbc->bChannelNumber)) { - rccb_startbc->wBPSTOffset = client->wBPSTOffset; - } - - data_len = UWB_RAW_RCCB_HEAD_SIZE + 3; /* size of start beacon RCCB */ - - uwba_log(uwba_dev, UWBA_LOG_DEBUG, - "uwb_do_cmd_start_beacon: channel= %d , BPSTOffset = %d", - rccb_startbc->bChannelNumber, rccb_startbc->wBPSTOffset); - /* Data block */ - if ((data = allocb(data_len, BPRI_HI)) == NULL) { - uwba_log(uwba_dev, UWBA_LOG_LOG, - "uwb_do_cmd_start_beacon: allocb failed"); - - return (UWB_FAILURE); - } - - uwba_fill_rccb_head(uwba_dev, rccb_startbc->rccb.wCommand, data); - UINT16_TO_LE(rccb_startbc->wBPSTOffset, 4, data->b_rptr); - data->b_rptr[6] = rccb_startbc->bChannelNumber; - data->b_wptr += data_len; - - /* record the current cmd rccb to the uwb dev handle. */ - uwba_copy_rccb((uwb_rccb_cmd_t *)rccb_startbc, &(uwba_dev->curr_rccb)); - uwba_dev->curr_rccb.rccb.bCommandContext = data->b_rptr[3]; - if ((rval = uwba_dev->send_cmd(uwb_dev_hdl, data, data_len)) - != UWB_SUCCESS) { - uwba_log(uwba_dev, UWBA_LOG_LOG, - "uwb_do_cmd_start_beacon: send_cmd failed, channel = %d," - "wBPSTOffset = %d", rccb_startbc->bChannelNumber, - rccb_startbc->wBPSTOffset); - - return (rval); - } - - return (rval); -} - -/* Send rccb cmd and get the rceb result */ -static int -uwb_process_rccb_cmd_private(uwb_dev_handle_t uwb_dev_hdl, - uwb_rccb_cmd_t *rccb_cmd, uwb_cmd_result_t *cmd_result) -{ - uwba_dev_t *uwba_dev = (uwba_dev_t *)uwb_dev_hdl; - int rval = UWB_SUCCESS; - - if (uwb_check_dev_state(uwba_dev, rccb_cmd) != UWB_SUCCESS) { - - uwba_log(uwba_dev, UWBA_LOG_LOG, - "uwb_process_rccb_cmd_private: illegal dev_state:%d", - uwba_dev->dev_state); - - return (UWB_FAILURE); - } - - - - if (uwb_rccb_cmd_enter(uwba_dev) != UWB_SUCCESS) { - uwba_log(uwba_dev, UWBA_LOG_LOG, - "uwb_process_rccb_cmd_private: fail to enter" - "wCommand = %d, %s ", rccb_cmd->rccb.wCommand, - uwba_event_msg(rccb_cmd->rccb.wCommand)); - - return (UWB_FAILURE); - } - - if ((rval = uwb_send_rccb_cmd(uwb_dev_hdl, rccb_cmd)) != UWB_SUCCESS) { - uwba_log(uwba_dev, UWBA_LOG_LOG, - "uwb_process_rccb_cmd_private: fail to send" - "wCommand = %d, %s ", rccb_cmd->rccb.wCommand, - uwba_event_msg(rccb_cmd->rccb.wCommand)); - goto cleanup; - } - - mutex_enter(&uwba_dev->dev_mutex); - /* Copy the command result to application */ - if (cmd_result) { - bcopy(uwba_dev->cmd_result_wrap.cmd_result, cmd_result, - uwba_dev->cmd_result_wrap.length); - } - /* release the command result (event) block. */ - uwb_free_cmd_result(uwb_dev_hdl); - - uwb_set_dev_state(uwba_dev, rccb_cmd); - - mutex_exit(&uwba_dev->dev_mutex); - -cleanup: - uwb_rccb_cmd_leave(uwba_dev); - - return (rval); -} - -/* Call rccb handler to send a rccb cmd */ -static int -uwb_send_rccb_cmd(uwb_dev_handle_t uwb_dev_hdl, uwb_rccb_cmd_t *rccb_cmd) -{ - int rccb_index = rccb_cmd->rccb.wCommand - UWB_CE_CHANNEL_CHANGE; - uwba_dev_t *uwba_dev = (uwba_dev_t *)uwb_dev_hdl; - ASSERT(rccb_cmd->rccb.bCommandType == UWB_CE_TYPE_GENERAL); - - mutex_enter(&uwba_dev->dev_mutex); - if (uwb_rccb_handler_tbl[rccb_index](uwb_dev_hdl, rccb_cmd) - != UWB_SUCCESS) { - uwba_log(uwba_dev, UWBA_LOG_LOG, - "uwb_send_rccb_cmd: uwb_send_rccb_cmd failed"); - goto failure; - - } - if (uwb_wait_cmd_result(uwb_dev_hdl) != UWB_SUCCESS) { - uwba_log(uwba_dev, UWBA_LOG_LOG, - "uwb_send_rccb_cmd: fail to get cmd result "); - goto failure; - } - - mutex_exit(&uwba_dev->dev_mutex); - - return (UWB_SUCCESS); -failure: - mutex_exit(&uwba_dev->dev_mutex); - - return (UWB_FAILURE); - -} -/* Check a rccb cmd */ -static int -uwb_check_rccb_cmd(uwb_dev_handle_t uwb_dev_hdl, uwb_rccb_cmd_t *rccb_cmd) -{ - uwba_dev_t *uwba_dev = (uwba_dev_t *)uwb_dev_hdl; - int rccb_index = rccb_cmd->rccb.wCommand - UWB_CE_CHANNEL_CHANGE; - - if (rccb_cmd->rccb.bCommandType != UWB_CE_TYPE_GENERAL) { - uwba_log(uwba_dev, UWBA_LOG_LOG, - "uwb_check_rccb_cmd: invalid bCommandType = %d", - rccb_cmd->rccb.bCommandType); - - return (UWB_FAILURE); - } - if ((rccb_cmd->rccb.wCommand < UWB_CE_CHANNEL_CHANGE) || - (rccb_cmd->rccb.wCommand > UWB_CE_SET_ASIE_NOTIFICATION)) { - uwba_log(uwba_dev, UWBA_LOG_LOG, - "uwb_check_rccb_cmd: invalid wCommand = %d", - rccb_cmd->rccb.wCommand); - - return (UWB_FAILURE); - } - if (uwb_rccb_handler_tbl[rccb_index] == UWB_RCCB_NULL_HANDLER) { - uwba_log(uwba_dev, UWBA_LOG_LOG, - "uwb_send_rccb_cmd: unsupportted wCommand = %d", - rccb_cmd->rccb.wCommand); - - return (UWB_FAILURE); - } - - return (UWB_SUCCESS); -} - -/* Check the current dev state */ -static int -uwb_check_dev_state(uwba_dev_t *uwba_dev, uwb_rccb_cmd_t *rccb_cmd) { - uint8_t state = uwba_dev->dev_state; - - switch (rccb_cmd->rccb.wCommand) { - case UWB_CE_SCAN: - if (((uwb_rccb_scan_t *)rccb_cmd)->bScanState - == UWB_RC_SCAN_DISABLED) { - if (state == UWB_STATE_SCAN) { - - return (UWB_SUCCESS); - } - } else { - - if (state == UWB_STATE_IDLE) { - - return (UWB_SUCCESS); - } - } - break; - - case UWB_CE_START_BEACON: - case UWB_CE_RESET: - if (state == UWB_STATE_IDLE) { - - return (UWB_SUCCESS); - } - break; - - case UWB_CE_STOP_BEACON: - if (state == UWB_STATE_BEACON) { - - return (UWB_SUCCESS); - } - break; - - default: - return (UWB_SUCCESS); - } - - return (UWB_FAILURE); -} -/* Set the uwb dev state */ -static void -uwb_set_dev_state(uwba_dev_t *uwba_dev, uwb_rccb_cmd_t *rccb_cmd) { - switch (rccb_cmd->rccb.wCommand) { - case UWB_CE_SCAN: - { - uwb_rccb_scan_t *cmd = - (uwb_rccb_scan_t *)rccb_cmd; - if (cmd->bScanState == UWB_RC_SCAN_DISABLED) { - - uwba_dev->dev_state = UWB_STATE_IDLE; - } else { - - uwba_dev->dev_state = UWB_STATE_SCAN; - uwba_dev->channel = cmd->bChannelNumber; - } - } - break; - - case UWB_CE_START_BEACON: - { - uwb_rccb_start_beacon_t *cmd = - (uwb_rccb_start_beacon_t *)rccb_cmd; - uwba_dev->dev_state = UWB_STATE_BEACON; - uwba_dev->channel = cmd->bChannelNumber; - } - break; - - case UWB_CE_STOP_BEACON: - case UWB_CE_RESET: - - uwba_dev->dev_state = UWB_STATE_IDLE; - break; - case UWB_CE_DEV_ADDR_MGMT: - { - uwb_rccb_dev_addr_mgmt_t *cmd = - (uwb_rccb_dev_addr_mgmt_t *)rccb_cmd; - if (cmd->bmOperationType == 1) - { - uwba_dev->dev_addr = cmd->baAddr[1]; - uwba_dev->dev_addr = - uwba_dev->dev_addr <<8; - uwba_dev->dev_addr = - uwba_dev->dev_addr | cmd->baAddr[0]; - } - } - break; - - default: - break; - } - -} - -/* Handle rccb cmd for ioctl */ -static int -uwb_do_ioctl_rccb_cmd(uwb_dev_handle_t uwb_dev_hdl, uint16_t wCommand, - intptr_t arg, int mode) -{ - uwba_dev_t *uwba_dev = (uwba_dev_t *)uwb_dev_hdl; - int rv = UWB_FAILURE; - - int rccb_size = uwb_rccb_size_tbl[wCommand - UWB_CE_CHANNEL_CHANGE]; - uwb_rccb_cmd_t *rccb_cmd = NULL; - - if (uwb_rccb_cmd_enter(uwba_dev) != UWB_SUCCESS) { - uwba_log(uwba_dev, UWBA_LOG_LOG, - "uwb_do_ioctl_rccb_cmd: enter cmd fail"); - - return (UWB_FAILURE); - } - rccb_cmd = kmem_alloc(rccb_size, KM_NOSLEEP); - if (ddi_copyin((caddr_t)arg, rccb_cmd, rccb_size, mode)) { - - uwba_log(uwba_dev, UWBA_LOG_LOG, - "uwb_do_ioctl_rccb_cmd: ddi_copyin fail"); - - goto cleanup; - } - - if (uwb_check_dev_state(uwba_dev, rccb_cmd) != UWB_SUCCESS) { - - uwba_log(uwba_dev, UWBA_LOG_LOG, - "uwb_check_dev_state: illegal dev_state:%d", - uwba_dev->dev_state); - - goto cleanup; - } - - - if ((uwb_send_rccb_cmd(uwb_dev_hdl, rccb_cmd)) != UWB_SUCCESS) { - uwba_log(uwba_dev, UWBA_LOG_LOG, - "uwb_do_ioctl_rccb_cmd: fail to send wCommand = %d ", - rccb_cmd->rccb.wCommand); - - goto cleanup; - } - - /* Copy the command result to application */ - mutex_enter(&uwba_dev->dev_mutex); - if (ddi_copyout(uwba_dev->cmd_result_wrap.cmd_result, (caddr_t)arg, - uwba_dev->cmd_result_wrap.length, mode)) { - - uwba_log(uwba_dev, UWBA_LOG_LOG, - "uwb_do_ioctl_rccb_cmd: ddi_copyout fail"); - } else { - rv = UWB_SUCCESS; - } - - /* release the command result (event) block. */ - uwb_free_cmd_result(uwb_dev_hdl); - - uwb_set_dev_state(uwba_dev, rccb_cmd); - mutex_exit(&uwba_dev->dev_mutex); - -cleanup: - uwb_rccb_cmd_leave(uwba_dev); - kmem_free(rccb_cmd, rccb_size); - - return (rv); -} - -/* - * alloc evt block according to cmd code; alloc context id; - * link the evt block to uwb_dev_hdl - */ -static int -uwb_wait_cmd_result(uwb_dev_handle_t uwb_dev_hdl) -{ - int rval = UWB_SUCCESS; - uwba_dev_t *uwba_dev = (uwba_dev_t *)uwb_dev_hdl; - - ASSERT(mutex_owned(&uwba_dev->dev_mutex)); - - while (uwba_dev->cmd_result_wrap.cmd_result == NULL) { - - if (cv_timedwait_sig(&uwba_dev->cmd_result_cv, - &uwba_dev->dev_mutex, UWB_CMD_TIMEOUT) <= 0) { - - /* no cmd result is received and cv is signaled */ - rval = UWB_FAILURE; - - return (rval); - } - uwba_log(uwba_dev, UWBA_LOG_DEBUG, - "uwb_wait_cmd_result: wait for cmd complete end, " - "cv_signal received."); - } - ASSERT(uwba_dev->cmd_result_wrap.cmd_result != NULL); - - return (rval); -} - -static void -uwb_free_cmd_result(uwb_dev_handle_t uwb_dev_hdl) -{ - uwba_dev_t *uwba_dev = (uwba_dev_t *)uwb_dev_hdl; - - - ASSERT(mutex_owned(&uwba_dev->dev_mutex)); - - kmem_free(uwba_dev->cmd_result_wrap.cmd_result, - uwba_dev->cmd_result_wrap.length); - uwba_dev->cmd_result_wrap.cmd_result = NULL; - uwba_dev->cmd_result_wrap.length = 0; - uwba_free_ctxt_id(uwba_dev, uwba_dev->ctxt_id); -} - -/* Get notif for ioctl */ -static uwb_notif_wrapper_t * -uwb_get_notification(uwb_dev_handle_t uwb_dev_hdl, - intptr_t arg, int mode) -{ - uwb_notif_wrapper_t *notif; - uwb_notif_get_t ng; - - - if (ddi_copyin((caddr_t)arg, &ng, sizeof (ng), mode)) { - - return (NULL); - } - if (ng.notif.rceb.bEventType != UWB_CE_TYPE_GENERAL) { - - return (NULL); - } - - notif = uwb_get_notif_head(uwb_dev_hdl); - - return (notif); -} -/* Free a notif from notificatin list */ -static void -uwb_free_notification(uwb_notif_wrapper_t *nw) -{ - ASSERT(nw->notif); - - kmem_free(nw->notif, nw->length); - kmem_free(nw, sizeof (uwb_notif_wrapper_t)); -} -/* uwb rccb cmd handler lock */ -static int -uwb_rccb_cmd_enter(uwba_dev_t *uwba_dev) -{ - mutex_enter(&uwba_dev->dev_mutex); - while (uwba_dev->cmd_busy == B_TRUE) { - if (cv_wait_sig(&uwba_dev->cmd_handler_cv, - &uwba_dev->dev_mutex) <= 0) { - mutex_exit(&uwba_dev->dev_mutex); - - return (UWB_FAILURE); - } - } - uwba_dev->cmd_busy = B_TRUE; - mutex_exit(&uwba_dev->dev_mutex); - - return (UWB_SUCCESS); -} -/* uwb rccb cmd handler unlock */ -static void -uwb_rccb_cmd_leave(uwba_dev_t *uwba_dev) -{ - mutex_enter(&uwba_dev->dev_mutex); - uwba_dev->cmd_busy = B_FALSE; - cv_signal(&uwba_dev->cmd_handler_cv); - mutex_exit(&uwba_dev->dev_mutex); -} diff --git a/usr/src/uts/common/io/warlock/hwahc.wlcmd b/usr/src/uts/common/io/warlock/hwahc.wlcmd deleted file mode 100644 index 3cdd87bc6f..0000000000 --- a/usr/src/uts/common/io/warlock/hwahc.wlcmd +++ /dev/null @@ -1,114 +0,0 @@ -# -# 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 -# or http://www.opensolaris.org/os/licensing. -# 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. -# - -one hwahc_state -one usba_device -one usba_pipe_handle_data -one usba_ph_impl - -### specify the root functions - -### hcdi entry points -root hwahc_hcdi_bulk_transfer_size -root hwahc_hcdi_get_current_frame_number -root hwahc_hcdi_get_max_isoc_pkts -root hwahc_hcdi_pipe_bulk_xfer -root hwahc_hcdi_pipe_close -root hwahc_hcdi_pipe_ctrl_xfer -root hwahc_hcdi_pipe_intr_xfer -root hwahc_hcdi_pipe_isoc_xfer -root hwahc_hcdi_pipe_open -root hwahc_hcdi_pipe_reset -root hwahc_hcdi_pipe_stop_intr_polling -root hwahc_hcdi_pipe_stop_isoc_polling -root hwahc_hcdi_pm_support -root hwahc_hcdi_polled_input_enter -root hwahc_hcdi_polled_input_exit -root hwahc_hcdi_polled_input_fini -root hwahc_hcdi_polled_input_init -root hwahc_hcdi_polled_read -root hwahc_hcdi_pipe_reset_data_toggle - -root hwahc_add_mmc_ie -root hwahc_get_time -root hwahc_remove_mmc_ie -root hwahc_set_cluster_id -root hwahc_set_dev_encrypt -root hwahc_set_keys -root hwahc_set_num_dnts -root hwahc_set_stream_idx -root hwahc_set_wusb_mas -root hwahc_stop_ch - -root hwahc_cleanup_child -root hwahc_create_child -root hwahc_destroy_child -root hwahc_disconnect_dev -root hwahc_reconnect_dev -root hwahc_set_device_info -root hwahc_set_encrypt -root hwahc_set_gtk -root hwahc_set_ptk - -root hwahc_notif_thread -root hwahc_intr_cb -root hwahc_intr_exc_cb -root hwahc_disconnect_event_cb -root hwahc_post_resume_event_cb -root hwahc_pre_suspend_event_cb -root hwahc_reconnect_event_cb -root hwahc_result_thread -root hwahc_pipe_submit_periodic_req -root hwahc_rpipe_xfer_cb - -root ndi_devi_online - -### POLLED entry points -root hwahc_hcdi_polled_input_init -root hwahc_hcdi_polled_input_fini -root hwahc_hcdi_polled_input_enter -root hwahc_hcdi_polled_input_exit -root hwahc_hcdi_polled_read - -add wusb_wa_trans_wrapper::wr_cb targets warlock_dummy - -add usba_hcdi_ops::usba_hcdi_console_input_init targets \ - hwahc_hcdi_polled_input_init -add usba_hcdi_ops::usba_hcdi_console_input_fini targets \ - hwahc_hcdi_polled_input_fini - -add bus_ops::bus_add_eventcall targets warlock_dummy -add bus_ops::bus_get_eventcookie targets warlock_dummy -add bus_ops::bus_post_event targets warlock_dummy -add bus_ops::bus_remove_eventcall targets warlock_dummy -add bus_ops::bus_intr_ctl targets warlock_dummy -add bus_ops::bus_config targets warlock_dummy -add bus_ops::bus_unconfig targets warlock_dummy - -add wusb_hc_data::set_device_info targets hwahc_set_device_info - -add hubd::h_cleanup_child target hwahc_cleanup_child - -ignore msgb::b_wptr diff --git a/usr/src/uts/common/io/warlock/hwahc_with_usba.wlcmd b/usr/src/uts/common/io/warlock/hwahc_with_usba.wlcmd deleted file mode 100644 index f5f1073f36..0000000000 --- a/usr/src/uts/common/io/warlock/hwahc_with_usba.wlcmd +++ /dev/null @@ -1,142 +0,0 @@ -# -# 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 -# or http://www.opensolaris.org/os/licensing. -# 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. -# - -one hwahc_state -one usba_device -one usba_pipe_handle_data -one usba_ph_impl -one hubd - - -### specify the root functions -### hcdi entry points -root hwahc_notif_thread -root hwahc_result_thread -root hwahc_hcdi_pipe_open -root hwahc_hcdi_pipe_close -root hwahc_hcdi_pipe_stop_intr_polling -root hwahc_hcdi_pipe_stop_isoc_polling -root hwahc_hcdi_pipe_reset -root hwahc_hcdi_bulk_transfer_size -root hwahc_hcdi_get_current_frame_number -root hwahc_hcdi_get_max_isoc_pkts -root hwahc_hcdi_pipe_ctrl_xfer -root hwahc_hcdi_pipe_bulk_xfer -root hwahc_hcdi_pipe_intr_xfer -root hwahc_hcdi_pipe_isoc_xfer -root hwahc_hcdi_pm_support -root hwahc_hcdi_pipe_reset_data_toggle -root usb_get_if_number -root usba_free_hcdi_ops -root usb_set_device_pwrlvl0 -root usb_set_device_pwrlvl1 -root usb_set_device_pwrlvl2 -root usb_set_device_pwrlvl3 -root usb_async_req -root usb_pipe_ctrl_xfer_wait -root usb_pipe_reset -root hubd_ready_device -root hubd_schedule_cleanup -root hubd_select_device_configuration -root hubd_disconnect_event_cb -root hubd_post_resume_event_cb -root hubd_pre_suspend_event_cb -root hubd_reconnect_event_cb -root hubd_bus_power - -root hwahc_add_mmc_ie -root hwahc_get_time -root hwahc_remove_mmc_ie -root hwahc_set_cluster_id -root hwahc_set_dev_encrypt -root hwahc_set_device_info -root hwahc_set_encrypt -root hwahc_set_gtk -root hwahc_set_keys -root hwahc_set_num_dnts -root hwahc_set_ptk -root hwahc_set_stream_idx -root hwahc_set_wusb_mas -root hwahc_stop_ch -root hwahc_create_child -root hwahc_disconnect_dev -root hwahc_disconnect_event_cb -root hwahc_handle_notif -root hwahc_handle_xfer_result -root hwahc_intr_cb -root hwahc_intr_exc_cb -root hwahc_pipe_submit_periodic_req -root hwahc_post_resume_event_cb -root hwahc_pre_suspend_event_cb -root hwahc_reconnect_dev -root hwahc_reconnect_event_cb -root hwahc_restore_device_state -root hwahc_rpipe_xfer_cb - -root usb_check_same_device -root usba_bind_driver -root usba_destroy_child_devi -root usba_get_dev_string_descrs -root usba_hubdi_check_power_budget -root usba_hubdi_incr_power_budget -root usba_persistent_pipe_close -root usba_persistent_pipe_open - -### POLLED entry points -root hwahc_hcdi_polled_input_init -root hwahc_hcdi_polled_input_fini -root hwahc_hcdi_polled_input_enter -root hwahc_hcdi_polled_input_exit -root hwahc_hcdi_polled_read - -root hubd_restore_state_cb - -### currently unused functions - -add wusb_wa_trans_wrapper::wr_cb targets warlock_dummy - -add usba_hcdi_ops::usba_hcdi_console_input_init targets \ - hwahc_hcdi_polled_input_init -add usba_hcdi_ops::usba_hcdi_console_input_fini targets \ - hwahc_hcdi_polled_input_fini - -add wusb_hc_data::add_mmc_ie targets hwahc_add_mmc_ie -add wusb_hc_data::create_child targets hwahc_create_child - -add wusb_hc_data::destroy_child targets warlock_dummy -add wusb_hc_data::disconnect_dev targets warlock_dummy -add wusb_hc_data::get_time targets warlock_dummy -add wusb_hc_data::reconnect_dev targets warlock_dummy -add wusb_hc_data::rem_mmc_ie targets warlock_dummy -add wusb_hc_data::set_cluster_id targets warlock_dummy -add wusb_hc_data::set_device_info targets warlock_dummy -add wusb_hc_data::set_encrypt targets warlock_dummy -add wusb_hc_data::set_gtk targets warlock_dummy -add wusb_hc_data::set_num_dnts targets warlock_dummy -add wusb_hc_data::set_ptk targets warlock_dummy -add wusb_hc_data::set_stream_idx targets warlock_dummy -add wusb_hc_data::set_wusb_mas targets warlock_dummy -add wusb_hc_data::stop_ch targets warlock_dummy - diff --git a/usr/src/uts/common/io/warlock/hwarc.wlcmd b/usr/src/uts/common/io/warlock/hwarc.wlcmd deleted file mode 100644 index c6154f2d81..0000000000 --- a/usr/src/uts/common/io/warlock/hwarc.wlcmd +++ /dev/null @@ -1,46 +0,0 @@ -# -# 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 -# or http://www.opensolaris.org/os/licensing. -# 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. -# - -one hwarc_state - -### specify the root functions - -root hwarc_open -root hwarc_close -root hwarc_ioctl -root hwarc_disconnect_callback -root hwarc_reconnect_callback -root hwarc_intr_cb -root hwarc_intr_ex_cb -root hwarc_send_cmd - -### currently unused functions -add bus_ops::bus_add_eventcall targets warlock_dummy -add bus_ops::bus_get_eventcookie targets warlock_dummy -add bus_ops::bus_post_event targets warlock_dummy -add bus_ops::bus_remove_eventcall targets warlock_dummy -add bus_ops::bus_intr_ctl targets warlock_dummy -add bus_ops::bus_config targets warlock_dummy -add bus_ops::bus_unconfig targets warlock_dummy diff --git a/usr/src/uts/common/io/warlock/hwarc_with_usba.wlcmd b/usr/src/uts/common/io/warlock/hwarc_with_usba.wlcmd deleted file mode 100644 index 90aa870c42..0000000000 --- a/usr/src/uts/common/io/warlock/hwarc_with_usba.wlcmd +++ /dev/null @@ -1,49 +0,0 @@ -# -# 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 -# or http://www.opensolaris.org/os/licensing. -# 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. -# - -one hwarc_state -one usba_device -one usba_pipe_handle_data -one usba_ph_impl -one hubd -### specify the root functions - -root hwarc_open -root hwarc_close -root hwarc_ioctl -root hwarc_disconnect_callback -root hwarc_reconnect_callback -root hwarc_intr_cb -root hwarc_intr_ex_cb -root hwarc_send_cmd - - -root hubd_disconnect_event_cb -root hubd_post_resume_event_cb -root hubd_pre_suspend_event_cb -root hubd_reconnect_event_cb -root hubd_bus_power -root usba_persistent_pipe_close -root hubd_restore_state_cb diff --git a/usr/src/uts/common/io/warlock/uwba.wlcmd b/usr/src/uts/common/io/warlock/uwba.wlcmd deleted file mode 100644 index 0cb23b7da9..0000000000 --- a/usr/src/uts/common/io/warlock/uwba.wlcmd +++ /dev/null @@ -1,59 +0,0 @@ -# -# 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 -# or http://www.opensolaris.org/os/licensing. -# 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. -# - -one uwba_dev - -### specify the root functions - -root uwb_allocate_channel -root uwb_dev_attach -root uwb_dev_detach -root uwb_dev_offline -root uwb_dev_online -root uwb_do_ioctl -root uwb_get_dev_addr -root uwb_get_dip -root uwb_get_mac_addr -root uwb_init_phy -root uwb_parse_evt_notif -root uwb_process_rccb_cmd -root uwb_reset_dev -root uwb_set_dev_addr -root uwb_start_beacon -root uwb_stop_beacon -root uwb_dev_disconnect -root uwb_dev_reconnect - - -### currently unused functions - -add bus_ops::bus_add_eventcall targets warlock_dummy -add bus_ops::bus_config targets warlock_dummy -add bus_ops::bus_get_eventcookie targets warlock_dummy -add bus_ops::bus_intr_ctl targets warlock_dummy -add bus_ops::bus_post_event targets warlock_dummy -add bus_ops::bus_remove_eventcall targets warlock_dummy -add bus_ops::bus_unconfig targets warlock_dummy -add uwba_dev::send_cmd targets warlock_dummy diff --git a/usr/src/uts/common/io/warlock/wusb_ca.wlcmd b/usr/src/uts/common/io/warlock/wusb_ca.wlcmd deleted file mode 100644 index 29a22b8af9..0000000000 --- a/usr/src/uts/common/io/warlock/wusb_ca.wlcmd +++ /dev/null @@ -1,42 +0,0 @@ -# -# 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 -# or http://www.opensolaris.org/os/licensing. -# 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. -# - -one wusb_ca_state - -### specify the root functions - -root wusb_ca_open -root wusb_ca_close -root wusb_ca_ioctl -root wusb_ca_disconnect_callback -root wusb_ca_reconnect_callback -### currently unused functions -add bus_ops::bus_add_eventcall targets warlock_dummy -add bus_ops::bus_get_eventcookie targets warlock_dummy -add bus_ops::bus_post_event targets warlock_dummy -add bus_ops::bus_remove_eventcall targets warlock_dummy -add bus_ops::bus_intr_ctl targets warlock_dummy -add bus_ops::bus_config targets warlock_dummy -add bus_ops::bus_unconfig targets warlock_dummy diff --git a/usr/src/uts/common/io/warlock/wusb_ca_with_usba.wlcmd b/usr/src/uts/common/io/warlock/wusb_ca_with_usba.wlcmd deleted file mode 100644 index e0a26fb05d..0000000000 --- a/usr/src/uts/common/io/warlock/wusb_ca_with_usba.wlcmd +++ /dev/null @@ -1,46 +0,0 @@ -# -# 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 -# or http://www.opensolaris.org/os/licensing. -# 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. -# - -one wusb_ca_state -one usba_device -one usba_pipe_handle_data -one usba_ph_impl -one hubd -### specify the root functions - -root wusb_ca_open -root wusb_ca_close -root wusb_ca_ioctl -root wusb_ca_disconnect_callback -root wusb_ca_reconnect_callback - - -root hubd_disconnect_event_cb -root hubd_post_resume_event_cb -root hubd_pre_suspend_event_cb -root hubd_reconnect_event_cb -root hubd_bus_power -root usba_persistent_pipe_close -root hubd_restore_state_cb diff --git a/usr/src/uts/common/io/warlock/wusb_df.wlcmd b/usr/src/uts/common/io/warlock/wusb_df.wlcmd deleted file mode 100644 index 3d3c95a942..0000000000 --- a/usr/src/uts/common/io/warlock/wusb_df.wlcmd +++ /dev/null @@ -1,40 +0,0 @@ -# -# 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 -# or http://www.opensolaris.org/os/licensing. -# 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. -# - -one wusb_df_state - -### specify the root functions - -root wusb_df_disconnect_callback -root wusb_df_reconnect_callback - -### currently unused functions -add bus_ops::bus_add_eventcall targets warlock_dummy -add bus_ops::bus_get_eventcookie targets warlock_dummy -add bus_ops::bus_post_event targets warlock_dummy -add bus_ops::bus_remove_eventcall targets warlock_dummy -add bus_ops::bus_intr_ctl targets warlock_dummy -add bus_ops::bus_config targets warlock_dummy -add bus_ops::bus_unconfig targets warlock_dummy diff --git a/usr/src/uts/common/io/warlock/wusb_df_with_usba.wlcmd b/usr/src/uts/common/io/warlock/wusb_df_with_usba.wlcmd deleted file mode 100644 index 4cfa892b8b..0000000000 --- a/usr/src/uts/common/io/warlock/wusb_df_with_usba.wlcmd +++ /dev/null @@ -1,43 +0,0 @@ -# -# 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 -# or http://www.opensolaris.org/os/licensing. -# 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. -# - -one wusb_df_state -one usba_device -one usba_pipe_handle_data -one usba_ph_impl -one hubd -### specify the root functions - -root wusb_df_disconnect_callback -root wusb_df_reconnect_callback - - -root hubd_disconnect_event_cb -root hubd_post_resume_event_cb -root hubd_pre_suspend_event_cb -root hubd_reconnect_event_cb -root hubd_bus_power -root usba_persistent_pipe_close -root hubd_restore_state_cb diff --git a/usr/src/uts/common/sys/Makefile b/usr/src/uts/common/sys/Makefile index 656494c228..c99ef8accb 100644 --- a/usr/src/uts/common/sys/Makefile +++ b/usr/src/uts/common/sys/Makefile @@ -1011,13 +1011,6 @@ USBHDRS= \ usba.h \ usbai.h -UWBHDRS= \ - uwb.h \ - uwbai.h - -UWBAHDRS= \ - uwba.h - USBAUDHDRS= \ usb_audio.h @@ -1028,9 +1021,6 @@ USBHUBDHDRS= \ USBHIDHDRS= \ hid.h -USBHWARCHDRS= \ - hwarc.h - USBMSHDRS= \ usb_bulkonly.h \ usb_cbi.h @@ -1199,7 +1189,6 @@ CHECKHDRS= \ $(USBAUDHDRS:%.h=usb/clients/audio/%.check) \ $(USBHUBDHDRS:%.h=usb/hubd/%.check) \ $(USBHIDHDRS:%.h=usb/clients/hid/%.check) \ - $(USBHWARCHDRS:%.h=usb/clients/hwarc/%.check) \ $(USBMSHDRS:%.h=usb/clients/mass_storage/%.check) \ $(USBPRNHDRS:%.h=usb/clients/printer/%.check) \ $(USBCDCHDRS:%.h=usb/clients/usbcdc/%.check) \ @@ -1207,8 +1196,6 @@ CHECKHDRS= \ $(USBWCMHDRS:%.h=usb/clients/usbinput/usbwcm/%.check) \ $(UGENHDRS:%.h=usb/clients/ugen/%.check) \ $(USBHDRS:%.h=usb/%.check) \ - $(UWBHDRS:%.h=uwb/%.check) \ - $(UWBAHDRS:%.h=uwb/uwba/%.check) \ $(I1394HDRS:%.h=1394/%.check) \ $(RSMHDRS:%.h=rsm/%.check) \ $(TSOLHDRS:%.h=tsol/%.check) \ diff --git a/usr/src/uts/common/sys/Makefile.syshdrs b/usr/src/uts/common/sys/Makefile.syshdrs index 1871c019f1..578177f529 100644 --- a/usr/src/uts/common/sys/Makefile.syshdrs +++ b/usr/src/uts/common/sys/Makefile.syshdrs @@ -19,7 +19,7 @@ # CDDL HEADER END # # Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved. -# Copyright 2013 Garrett D'Amore <garrett@damore.org> +# Copyright 2014 Garrett D'Amore <garrett@damore.org> # # Common definitions for open and closed headers. @@ -143,9 +143,6 @@ usb/hubd/%.check: usb/hubd/%.h usb/clients/hid/%.check: usb/clients/hid/%.h $(DOT_H_CHECK) -usb/clients/hwarc/%.check: usb/clients/hwarc/%.h - $(DOT_H_CHECK) - usb/clients/mass_storage/%.check: usb/clients/mass_storage/%.h $(DOT_H_CHECK) @@ -229,15 +226,12 @@ ROOTDIRS= \ $(ROOTDIR)/usb/clients \ $(ROOTDIR)/usb/clients/audio \ $(ROOTDIR)/usb/clients/hid \ - $(ROOTDIR)/usb/clients/hwarc \ $(ROOTDIR)/usb/clients/mass_storage \ $(ROOTDIR)/usb/clients/printer \ $(ROOTDIR)/usb/clients/usbcdc \ $(ROOTDIR)/usb/clients/video/usbvc \ $(ROOTDIR)/usb/clients/usbinput/usbwcm \ $(ROOTDIR)/usb/clients/ugen \ - $(ROOTDIR)/uwb \ - $(ROOTDIR)/uwb/uwba \ $(ROOTDIR)/1394 \ $(ROOTDIR)/rsm \ $(ROOTDIR)/tsol \ @@ -311,12 +305,9 @@ ROOTCONTRACTHDRS= $(CONTRACTHDRS:%=$(ROOTDIR)/contract/%) ROOTXHDRS= $(XHDRS:%=$(ROOTDIR)/%) ROOTUSBHDRS= $(USBHDRS:%=$(ROOTDIR)/usb/%) -ROOTUWBHDRS= $(UWBHDRS:%=$(ROOTDIR)/uwb/%) -ROOTUWBAHDRS= $(UWBAHDRS:%=$(ROOTDIR)/uwb/uwba/%) ROOTUSBAUDHDRS= $(USBAUDHDRS:%=$(ROOTDIR)/usb/clients/audio/%) ROOTUSBHUBDHDRS= $(USBHUBDHDRS:%=$(ROOTDIR)/usb/hubd/%) ROOTUSBHIDHDRS = $(USBHIDHDRS:%=$(ROOTDIR)/usb/clients/hid/%) -ROOTUSBHWARCHDRS = $(USBHWARCHDRS:%=$(ROOTDIR)/usb/clients/hwarc/%) ROOTUSBMSHDRS= $(USBMSHDRS:%=$(ROOTDIR)/usb/clients/mass_storage/%) ROOTUSBPRNHDRS= $(USBPRNHDRS:%=$(ROOTDIR)/usb/clients/printer/%) ROOTUSBCDCHDRS= $(USBCDCHDRS:%=$(ROOTDIR)/usb/clients/usbcdc/%) @@ -339,13 +330,11 @@ ROOTTSOLHDRS= $(TSOLHDRS:%=$(ROOTDIR)/tsol/%) sparc_ROOTHDRS= $(ROOTSDKTPHDRS) $(ROOTSCSICADHDRS) $(ROOTSCSITARGETSHDRS) \ $(ROOTUSBHDRS) $(ROOTUSBHUBDHDRS) \ $(ROOTUSBAUDHDRS) $(ROOTUSBHIDHDRS) $(ROOTUSBMSHDRS) \ - $(ROOTUSBPRNHDRS) $(ROOTUGENHDRS) $(ROOTUSBVIDHDRS) \ - $(ROOTUWBHDRS) $(ROOTUWBAHDRS) $(ROOTUSBHWARCHDRS) + $(ROOTUSBPRNHDRS) $(ROOTUGENHDRS) $(ROOTUSBVIDHDRS) i386_ROOTHDRS= $(ROOTDKTPHDRS) $(ROOTPCHDRS) $(ROOTSCSITARGETSHDRS) \ $(ROOTSCSIVHCIHDRS) $(ROOTHOTPLUGHDRS) \ - $(ROOTHOTPLUGPCIHDRS) $(ROOTSATAGENHDRS) \ - $(ROOTUWBHDRS) $(ROOTUWBAHDRS) $(ROOTUSBHWARCHDRS) + $(ROOTHOTPLUGPCIHDRS) $(ROOTSATAGENHDRS) # install rules $(ROOTDIR)/%: % diff --git a/usr/src/uts/common/sys/usb/clients/hwarc/hwarc.h b/usr/src/uts/common/sys/usb/clients/hwarc/hwarc.h deleted file mode 100644 index b804822255..0000000000 --- a/usr/src/uts/common/sys/usb/clients/hwarc/hwarc.h +++ /dev/null @@ -1,122 +0,0 @@ -/* - * 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 - * or http://www.opensolaris.org/os/licensing. - * 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. - */ - -#ifndef _SYS_USB_HWARC_H -#define _SYS_USB_HWARC_H - -#ifdef __cplusplus -extern "C" { -#endif - -#include <sys/usb/usba/usbai_private.h> -#include <sys/uwb/uwbai.h> - -/* Power Management support */ -typedef struct hwarc_power { - - void *hrc_state; /* Hwarc state */ - uint8_t hrc_pwr_states; /* Hwarc power state */ - int hrc_pm_busy; /* Hwarc busy counter */ - - uint8_t hrc_pm_capabilities; /* PM capabilities */ - uint8_t hrc_current_power; /* Hwarc power value */ - - uint8_t hrc_wakeup_enabled; /* Remote Wakeup */ -} hwarc_power_t; - -/* Hwarc State structure */ -typedef struct hwarc_state { - dev_info_t *hrc_dip; /* Dip of Hwarc */ - - usb_client_dev_data_t *hrc_reg; /* Usb dev data */ - usb_if_data_t *hrc_if_descr; /* Interface descr */ - - usb_pipe_handle_t hrc_default_ph; /* Default pipe */ - usb_ep_descr_t hrc_intr_ep_descr; /* Inter ep descr */ - usb_pipe_handle_t hrc_intr_ph; /* Inter pipe hdl */ - char *hrc_devinst; /* Device instance */ - - int hrc_dev_state; /* USB device state */ - uint_t hrc_open_count; - - kmutex_t hrc_mutex; /* Global hwarc mutex */ - - kcondvar_t hrc_serial_cv; /* Serial access cond */ - boolean_t hrc_serial_inuse; /* Serial access flag */ - - - boolean_t hrc_locks_initialized; /* Init status flag */ - - hwarc_power_t *hrc_pm; /* PM state of hwarc */ - - usb_log_handle_t hrc_log_hdl; /* Hwarc log handle */ - uwb_dev_handle_t hrc_dev_hdl; /* Uwb dev handle */ -} hwarc_state_t; - -_NOTE(MUTEX_PROTECTS_DATA(hwarc_state_t::hrc_mutex, hwarc_state_t)) -_NOTE(DATA_READABLE_WITHOUT_LOCK(hwarc_state_t::{ - hrc_dev_hdl - hrc_dev_state - hrc_intr_ep_descr - hrc_default_ph - hrc_reg - hrc_intr_ph - hrc_log_hdl - hrc_dip - hrc_if_descr - -})) - - -#define USB_DEV_DESCR_SIZE 18 /* Hwarc device descr size */ - - -#define HWA_EXEC_RC_CMD 40 /* UWB Radio cmd request code */ - -#define HWARC_SER_NOSIG B_FALSE /* Hwarc serialization */ -#define HWARC_SER_SIG B_TRUE - -#define HWARC_SET_IF 0x21 /* Hwarc bmRequestType */ -#define HWARC_GET_IF 0xA1 - - -/* HWARC masks for debug printing */ -#define PRINT_MASK_ATTA 0x00000001 -#define PRINT_MASK_OPEN 0x00000002 -#define PRINT_MASK_CLOSE 0x00000004 -#define PRINT_MASK_READ 0x00000008 -#define PRINT_MASK_IOCTL 0x00000010 -#define PRINT_MASK_PM 0x00000020 -#define PRINT_MASK_CB 0x00000040 -#define PRINT_MASK_HOTPLUG 0x00000080 -#define PRINT_MASK_DEVCTRL 0x00000100 -#define PRINT_MASK_DEVMAP 0x00000200 -#define PRINT_MASK_ALL 0xFFFFFFFF - -#ifdef __cplusplus -} -#endif - -#endif /* _SYS_USB_HWARC_H */ diff --git a/usr/src/uts/common/sys/usb/clients/wusb_ca/wusb_ca.h b/usr/src/uts/common/sys/usb/clients/wusb_ca/wusb_ca.h deleted file mode 100644 index c5f1ca5dac..0000000000 --- a/usr/src/uts/common/sys/usb/clients/wusb_ca/wusb_ca.h +++ /dev/null @@ -1,121 +0,0 @@ -/* - * 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 - * or http://www.opensolaris.org/os/licensing. - * 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. - */ - -/* - * Definitions and data structures for application to exchange request - * with driver - */ -#ifndef _SYS_USB_WUSB_CA_H -#define _SYS_USB_WUSB_CA_H - -#ifdef __cplusplus -extern "C" { -#endif - -#include <sys/usb/usba/wusba_io.h> -#include <sys/usb/usba/wusba.h> - -/* Refer to WUSB AM Spec 4.3 */ -#define WUSB_CBAF_GET_ASSOCIATION_INFORMATION 0x01 -#define WUSB_CBAF_GET_ASSOCIATION_REQUEST 0x02 -#define WUSB_CBAF_SET_ASSOCIATION_RESPONSE 0x03 - -#define WUSB_CBAF_DEFAULT_STATE 0x01 -#define WUSB_CBAF_ADDRESS_STATE 0x02 -#define WUSB_CBAF_CONFIG_STATE 0x03 - -#define WUSB_CBAF_RETRIEVE_HOST_INFO 0x0000 -#define WUSB_CBAF_ASSOCIATE_WUSB 0x0001 - -#define WUSB_ASSO_INFO_SIZE 5 -#define WUSB_ASSO_REQUEST_SIZE 10 -#define WUSB_HOST_INFO_SIZE 106 -#define WUSB_DEVICE_INFO_SIZE 108 -#define WUSB_CC_DATA_SIZE 78 -#define WUSB_CC_FAILURE_SIZE 28 - -typedef struct __association_information { - uint16_t Length; - uint8_t NumAssociationRequests; - uint16_t Flag; -} wusb_cbaf_asso_info_t; - -typedef struct __association_request { - uint8_t AssociationDataIndex; - uint8_t Reserved; - uint16_t AssociationTypeId; - uint16_t AssociationSubTypeId; - uint32_t AssociationTypeInfoSize; -} wusb_cbaf_asso_req_t; - -typedef struct __host_info { - uint16_t AssociationTypeId; - uint16_t AssociationSubTypeId; - uint8_t CHID[16]; - uint16_t LangID; - char HostFriendlyName[64]; -} wusb_cbaf_host_info_t; - -typedef struct __device_info { - uint32_t Length; - uint8_t CDID[16]; - uint16_t BandGroups; - uint16_t LangID; - char DeviceFriendlyName[64]; -} wusb_cbaf_device_info_t; - -typedef struct __cc_data { - uint16_t AssociationTypeId; - uint16_t AssociationSubTypeId; - uint32_t Length; - wusb_cc_t CC; - uint16_t BandGroups; -} wusb_cbaf_cc_data_t; - -typedef struct __cc_fail { - uint16_t AssociationTypeId; - uint16_t AssociationSubTypeId; - uint32_t Length; - uint32_t AssociationStatus; -} wusb_cbaf_cc_fail_t; - - -/* WUSB CBAF ioctl command */ -#define CBAF_IOCTL_GET_ASSO_INFO 0x0001 -#define CBAF_IOCTL_GET_ASSO_REQS 0x0002 -#define CBAF_IOCTL_SET_HOST_INFO 0x0003 -#define CBAF_IOCTL_GET_DEVICE_INFO 0x0004 -#define CBAF_IOCTL_SET_CONNECTION 0x0005 -#define CBAF_IOCTL_SET_FAILURE 0x0006 - -#define CBAF_ASSO_FAILURE_DEFAULT 0x0001 -#define CBAF_ASSO_FAILURE_MALFORMED_REQUEST 0x0002 -#define CBAF_ASSO_FAILURE_TYPE_NOT_SUPPORTED 0x0003 - -#ifdef __cplusplus -} -#endif - -#endif /* _SYS_USB_WUSB_CA_H */ diff --git a/usr/src/uts/common/sys/usb/clients/wusb_ca/wusb_ca_priv.h b/usr/src/uts/common/sys/usb/clients/wusb_ca/wusb_ca_priv.h deleted file mode 100644 index f44f6a308f..0000000000 --- a/usr/src/uts/common/sys/usb/clients/wusb_ca/wusb_ca_priv.h +++ /dev/null @@ -1,121 +0,0 @@ -/* - * 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 - * or http://www.opensolaris.org/os/licensing. - * 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. - */ - -/* - * WUSB cable association driver private data structures and definitions. - */ -#ifndef _SYS_USB_WUSB_CA_PRIV_H -#define _SYS_USB_WUSB_CA_PRIV_H - - -#ifdef __cplusplus -extern "C" { -#endif - -#include <sys/usb/usba/usbai_private.h> - -/* - * Power Management support - */ -typedef struct wusb_ca_power { - - void *wusb_ca_state; /* points back to wusb_ca_state */ - uint8_t wusb_ca_pwr_states; /* bit mask of device pwr states */ - int wusb_ca_pm_busy; - - /* wakeup and power transistion capabilites of an interface */ - uint8_t wusb_ca_pm_capabilities; - - /* flag to indicate if driver is about to raise power level */ - boolean_t wusb_ca_raise_power; - - uint8_t wusb_ca_current_power; - uint8_t wusb_ca_remote_wakeup; -} wusb_ca_power_t; - - -/* - * State structure - */ -typedef struct wusb_ca_state { - dev_info_t *wusb_ca_dip; /* per-device info handle */ - usb_client_dev_data_t *wusb_ca_reg; /* registration data */ - char *wusb_ca_devinst; /* Dev and instance */ - int wusb_ca_dev_state; /* USB device states. */ - int wusb_ca_drv_state; /* driver states. */ - kmutex_t wusb_ca_mutex; - kcondvar_t wusb_ca_serial_cv; - boolean_t wusb_ca_serial_inuse; - boolean_t wusb_ca_locks_initialized; - wusb_ca_power_t *wusb_ca_pm; - usb_log_handle_t wusb_ca_log_hdl; -} wusb_ca_state_t; - -_NOTE(MUTEX_PROTECTS_DATA(wusb_ca_state::wusb_ca_mutex, wusb_ca_state)) - -_NOTE(DATA_READABLE_WITHOUT_LOCK(wusb_ca_state_t::{ - wusb_ca_log_hdl - wusb_ca_dip - wusb_ca_reg -})) -/* Macros */ -#define WUSB_CA_OPEN 0x00000001 - -#define WUSB_CA_REQUEST_SIZE 65535 /* Read request size maximum */ -#define USB_DEV_DESCR_SIZE 18 /* device descr size */ - -/* Other */ -#define WUSB_CA_DRAIN_TMO 15 - -/* For serialization. */ -#define WUSB_CA_SER_NOSIG B_FALSE -#define WUSB_CA_SER_SIG B_TRUE - -/* For logging. */ -#define WUSB_CA_LOG_LOG 1 -#define WUSB_CA_LOG_CONSOLE 0 - -#define PRINT_MASK_ALL 0xFFFFFFFF -#define PRINT_MASK_ATTA 0x00000001 -#define PRINT_MASK_CLOSE 0x00000002 -#define PRINT_MASK_OPEN 0x00000004 -#define PRINT_MASK_EVENTS 0x00000008 -#define PRINT_MASK_PM 0x00000010 -#define PRINT_MASK_CB 0x00000020 -#define PRINT_MASK_CPR 0x00000040 - -int wusb_cbaf_get_asso_info(wusb_ca_state_t *, intptr_t, int); -int wusb_cbaf_get_asso_reqs(wusb_ca_state_t *, intptr_t, int); -int wusb_cbaf_set_host_info(wusb_ca_state_t *, intptr_t, int); -int wusb_cbaf_get_device_info(wusb_ca_state_t *, intptr_t, int); -int wusb_cbaf_set_connection(wusb_ca_state_t *, intptr_t, int); -int wusb_cbaf_set_failure(wusb_ca_state_t *, intptr_t, int); - - -#ifdef __cplusplus -} -#endif - -#endif /* _SYS_USB_WUSB_CA_PRIV_H */ diff --git a/usr/src/uts/common/sys/usb/clients/wusb_df/wusb_df.h b/usr/src/uts/common/sys/usb/clients/wusb_df/wusb_df.h deleted file mode 100644 index 803fda4dae..0000000000 --- a/usr/src/uts/common/sys/usb/clients/wusb_df/wusb_df.h +++ /dev/null @@ -1,102 +0,0 @@ -/* - * 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 - * or http://www.opensolaris.org/os/licensing. - * 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. - */ - -#ifndef _SYS_USB_WUSB_DF_H -#define _SYS_USB_WUSB_DF_H - - -#ifdef __cplusplus -extern "C" { -#endif - -#include <sys/usb/usba/usbai_private.h> - -/* - * Power Management support - */ -typedef struct wusb_df_power { - - void *wusb_df_state; /* points back to wusb_df_state */ - uint8_t wusb_df_pwr_states; /* bit mask of device pwr states */ - int wusb_df_pm_busy; - uint8_t wusb_df_wakeup_enabled; - - /* wakeup and power transistion capabilites of an interface */ - uint8_t wusb_df_pm_capabilities; - - - uint8_t wusb_df_current_power; -} wusb_df_power_t; - - -/* - * State structure - */ -typedef struct wusb_df_state { - dev_info_t *wusb_df_dip; /* per-device info handle */ - usb_client_dev_data_t *wusb_df_reg; /* registration data */ - usb_ep_descr_t wusb_df_intr_ep_descr; /* Intr ep descr */ - usb_pipe_handle_t wusb_df_intr_ph; /* Intr pipe handle. */ - char *wusb_df_devinst; /* Dev and instance */ - int wusb_df_dev_state; /* USB device states. */ - kmutex_t wusb_df_mutex; - kcondvar_t wusb_df_serial_cv; - boolean_t wusb_df_serial_inuse; - boolean_t wusb_df_locks_initialized; - wusb_df_power_t *wusb_df_pm; - usb_log_handle_t wusb_df_log_hdl; -} wusb_df_state_t; - -_NOTE(MUTEX_PROTECTS_DATA(wusb_df_state::wusb_df_mutex, wusb_df_state)) - -_NOTE(DATA_READABLE_WITHOUT_LOCK(wusb_df_state_t::{ - wusb_df_log_hdl - wusb_df_intr_ph - wusb_df_dip - wusb_df_reg -})) -/* Macros */ - -#define WUSB_DF_REQUEST_SIZE 65535 /* Read request size maximum */ -#define USB_DEV_DESCR_SIZE 18 /* device descr size */ - - -/* For serialization. */ -#define WUSB_DF_SER_NOSIG B_FALSE -#define WUSB_DF_SER_SIG B_TRUE - -/* For logging. */ - -#define PRINT_MASK_ALL 0xFFFFFFFF -#define PRINT_MASK_ATTA 0x00000001 -#define PRINT_MASK_PM 0x00000010 -#define PRINT_MASK_CB 0x00000020 -#define PRINT_MASK_CPR 0x00000040 - -#ifdef __cplusplus -} -#endif - -#endif /* _SYS_USB_WUSB_DF_H */ diff --git a/usr/src/uts/common/sys/usb/hwa/hwahc/hwahc.h b/usr/src/uts/common/sys/usb/hwa/hwahc/hwahc.h deleted file mode 100644 index 9c7e9e35da..0000000000 --- a/usr/src/uts/common/sys/usb/hwa/hwahc/hwahc.h +++ /dev/null @@ -1,244 +0,0 @@ -/* - * 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 - * or http://www.opensolaris.org/os/licensing. - * 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. - */ - -#ifndef _SYS_USB_HWAHC_H -#define _SYS_USB_HWAHC_H - -#ifdef __cplusplus -extern "C" { -#endif - - -#include <sys/usb/usba/wa.h> -#include <sys/usb/hubd/hub.h> -#include <sys/usb/hubd/hubdvar.h> -#include <sys/usb/usba/hcdi.h> -#include <sys/usb/usba/whcdi.h> -#include <sys/disp.h> -#include <sys/sunldi.h> - -/* - * Power Management support - */ -typedef struct hwahc_power { - void *hwahc_state; /* points back to hwahc_state */ - uint8_t hwahc_pwr_states; /* bit mask of device pwr states */ - int hwahc_pm_busy; /* device busy counting */ - uint8_t hwahc_wakeup_enabled; - - /* wakeup and power transistion capabilites of an interface */ - uint8_t hwahc_pm_capabilities; - - /* current power level the device is in */ - uint8_t hwahc_current_power; -} hwahc_power_t; - -_NOTE(DATA_READABLE_WITHOUT_LOCK(hwahc_power_t::hwahc_wakeup_enabled)) - -/* softstate init state */ -#define HWAHC_LOCK_INITED 0x0001 -#define HWAHC_HUBDI_REGISTERED 0x0002 -#define HWAHC_MINOR_NODE_CREATED 0x0004 -#define HWAHC_EVENTS_REGISTERED 0x0010 -#define HWAHC_HUBREG 0x0020 -#define HWAHC_WA_INITED 0x0040 -#define HWAHC_HCDI_REGISTERED 0x0080 -#define HWAHC_HC_INITED 0x0400 -#define HWAHC_WA_STARTED 0x0800 - -/* hardware operation state */ -#define HWAHC_HW_STOPPED 0 -#define HWAHC_HW_STARTED 1 -#define HWAHC_HW_CH_STOPPED 2 -#define HWAHC_HW_CH_SUSPEND 3 - -/* Tracking events registered by children */ -#define HWAHC_CHILD_EVENT_DISCONNECT 0x01 -#define HWAHC_CHILD_EVENT_PRESUSPEND 0x02 - -/* Host controller software states */ -#define HWAHC_CTRL_INIT_STATE 0 /* Initialization state */ -#define HWAHC_CTRL_SUSPEND_STATE 1 /* Suspend state */ -#define HWAHC_CTRL_OPERATIONAL_STATE 2 /* Operational state */ -#define HWAHC_CTRL_ERROR_STATE 3 /* Error state */ - -/* Host controller pipe states */ -#define HWAHC_PIPE_STATE_IDLE 1 /* Pipe is in ready state */ -#define HWAHC_PIPE_STATE_ACTIVE 2 /* Pipe is in busy state */ -#define HWAHC_PIPE_STATE_ERROR 3 /* Pipe is in error state */ - -/* Additional pipe states for the hwahc_pipe_cleanup */ -#define HWAHC_PIPE_STATE_CLOSE 4 /* Pipe close */ -#define HWAHC_PIPE_STATE_RESET 5 /* Pipe reset */ -#define HWAHC_PIPE_STATE_STOP_POLLING 6 /* Pipe stop polling */ - -typedef struct hwahc_pipe_private { - usba_pipe_handle_data_t *pp_pipe_handle; - uint_t pp_state; - usb_pipe_policy_t pp_policy; - wusb_wa_rpipe_hdl_t *pp_rp; - wusb_dev_info_t *pp_wdev; /* parent device */ - - /* - * To support Intr/Isoc IN polling. - * Save the original client's request - */ - usb_opaque_t pp_client_periodic_in_reqp; - kcondvar_t pp_xfer_cmpl_cv; -} hwahc_pipe_private_t; - -_NOTE(DATA_READABLE_WITHOUT_LOCK(hwahc_pipe_private_t::pp_pipe_handle)) -_NOTE(DATA_READABLE_WITHOUT_LOCK(hwahc_pipe_private_t::pp_rp)) -_NOTE(DATA_READABLE_WITHOUT_LOCK( - hwahc_pipe_private_t::pp_client_periodic_in_reqp)) - -/* - * Softstate structure - */ -typedef struct hwahc_state { - int hwahc_instance; - uint_t hwahc_flags; - uint_t hwahc_dev_state; /* USB device states */ - usb_log_handle_t hwahc_log_handle; - - hwahc_power_t *hwahc_pm; - dev_info_t *hwahc_dip; /* device info handle */ - - /* mutex to protect softstate and hw regs */ - kmutex_t hwahc_mutex; - - hubd_t *hwahc_hubd; - int hwahc_hw_state; /* hc start flag */ - uint_t hwahc_open_count; - - int hwahc_hc_soft_state; /* driver states. */ - - /* default pipe handle as a usba client device */ - usb_pipe_handle_t hwahc_default_pipe; - - uint_t hwahc_open_pipe_count; - - /* wire adapter common data */ - wusb_wa_data_t hwahc_wa_data; - wusb_secrt_data_t hwahc_secrt_data; - - /* WUSB HC common data. hold HC and children info */ - wusb_hc_data_t hwahc_hc_data; - - /* for DN notification */ - usba_list_entry_t hwahc_dn_notif_queue; - kthread_t *hwahc_notif_thread_id; - - /* for transfer result notification */ - kthread_t *hwahc_result_thread_id; - kcondvar_t hwahc_result_thread_cv; - - int8_t hwahc_bus_pwr; /* bus power event count */ - - /* track event registration of children */ - uint8_t hwahc_child_events[128]; - - ndi_event_hdl_t hwahc_ndi_event_hdl; - - usb_client_dev_data_t *hwahc_dev_data; /* registration data */ - usba_hcdi_ops_t *hwahc_hcdi_ops; /* HCDI structure */ - -} hwahc_state_t; - -/* warlock directives */ -_NOTE(MUTEX_PROTECTS_DATA(hwahc_state_t::hwahc_mutex, hwahc_state_t)) -_NOTE(MUTEX_PROTECTS_DATA(hwahc_state_t::hwahc_mutex, hwahc_pipe_private_t)) -_NOTE(MUTEX_PROTECTS_DATA(hwahc_state_t::hwahc_mutex, - hwahc_pipe_private_t::pp_state)) -_NOTE(MUTEX_PROTECTS_DATA(hwahc_state_t::hwahc_mutex, hwahc_power_t)) - -_NOTE(DATA_READABLE_WITHOUT_LOCK(hwahc_state_t::hwahc_log_handle)) -_NOTE(DATA_READABLE_WITHOUT_LOCK(hwahc_state_t::hwahc_wa_data)) -_NOTE(DATA_READABLE_WITHOUT_LOCK(hwahc_state_t::hwahc_dip)) -_NOTE(DATA_READABLE_WITHOUT_LOCK(hwahc_state_t::hwahc_default_pipe)) -_NOTE(DATA_READABLE_WITHOUT_LOCK(hwahc_state_t::hwahc_ndi_event_hdl)) -_NOTE(DATA_READABLE_WITHOUT_LOCK(hwahc_state_t::hwahc_pm - hwahc_state_t::hwahc_hubd)) - -_NOTE(SCHEME_PROTECTS_DATA("stable data", usb_ep_comp_descr)) -_NOTE(SCHEME_PROTECTS_DATA("stable data", usba_device_t)) - -/* Debug masks */ -#define PRINT_MASK_ATTA 0x00000001 /* Attach time */ -#define PRINT_MASK_RPIPES 0x00000002 /* Rpipe management */ -#define PRINT_MASK_HUB 0x00000004 /* Hub related stuff */ -#define PRINT_MASK_EVENTS 0x00000008 /* Intr notification */ -#define PRINT_MASK_SECURITY 0x00000020 /* Security info */ -#define PRINT_MASK_CBOPS 0x00000040 /* CB-OPS */ -#define PRINT_MASK_HCDI 0x00000080 /* HCDI entry points */ -#define PRINT_MASK_DUMPING 0x00000100 /* Dump hwa info */ -#define PRINT_MASK_OPEN 0x00000200 /* Open time */ -#define PRINT_MASK_CLOSE 0x00000400 /* Close time */ -#define PRINT_MASK_PM 0x00000800 /* For pwr mgmt */ -#define PRINT_MASK_ALL 0xFFFFFFFF - -#define HWAHC_MINOR_HUB_BITS_MASK 0xff -#define HWAHC_MINOR_INSTANCE_MASK ~HWAHC_MINOR_HUB_BITS_MASK -#define HWAHC_MINOR_INSTANCE_SHIFT 8 - -#define HWAHC_MINOR_TO_INSTANCE(minor) \ - (((minor) & HWAHC_MINOR_INSTANCE_MASK) >> \ - HWAHC_MINOR_INSTANCE_SHIFT) - -#define HWAHC_CONSTRUCT_MINOR(inst) \ - (inst << HWAHC_MINOR_INSTANCE_SHIFT) - -/* base of MAC layer dev address for HWA class device */ -#define HWAHC_DEV_ADDR_BASE 0xA100 - -typedef struct hwahc_dn_notif_list { - hwa_notif_dn_recvd_t *dn_notif; - usba_list_entry_t notif_list; -} hwahc_dn_notif_list_t; - -_NOTE(MUTEX_PROTECTS_DATA(hwahc_state_t::hwahc_mutex, hwahc_dn_notif_list_t)) - -/* max elements in notification queue */ -#define HWAHC_MAX_NOTIF 100 - -/* notification queue drain timeout - 60sec */ -#define HWAHC_NOTIF_DRAIN_TIMEOUT 60 - -/* - * cfgadm state values - */ -#define HWAHC_CFGADM_NORMAL 0 /* normal state */ -#define HWAHC_CFGADM_DISCONNECTED 1 /* logically disconnected */ -#define HWAHC_CFGADM_UNCONFIGURED 2 /* port is unconfigured */ -#define HWAHC_CFGADM_EMPTY 3 /* port is empty */ -#define HWAHC_CFGADM_STILL_REFERENCED 4 /* ndi_devi_offline failed */ -#define HWAHC_CFGADM_CONFIGURED 5 /* port is configured */ -#define HWAHC_CFGADM_INVALID 0xFF /* invalid state */ - -#ifdef __cplusplus -} -#endif - -#endif /* _SYS_USB_HWAHC_H */ diff --git a/usr/src/uts/common/sys/usb/hwa/hwahc/hwahc_util.h b/usr/src/uts/common/sys/usb/hwa/hwahc/hwahc_util.h deleted file mode 100644 index 7873310b12..0000000000 --- a/usr/src/uts/common/sys/usb/hwa/hwahc/hwahc_util.h +++ /dev/null @@ -1,54 +0,0 @@ -/* - * 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 - * or http://www.opensolaris.org/os/licensing. - * 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. - */ - -#ifndef _SYS_USB_HWAHC_UTIL_H -#define _SYS_USB_HWAHC_UTIL_H - -#ifdef __cplusplus -extern "C" { -#endif - -usba_hcdi_ops_t *hwahc_alloc_hcdi_ops(hwahc_state_t *hwahcp); -int hwahc_start_result_thread(hwahc_state_t *hwahcp); -int hwahc_set_encrypt(dev_info_t *, usb_port_t, uint8_t type); -int hwahc_set_ptk(dev_info_t *, usb_key_descr_t *, size_t, usb_port_t); -int hwahc_set_gtk(dev_info_t *, usb_key_descr_t *, size_t); -int hwahc_set_device_info(dev_info_t *, wusb_dev_info_t *, usb_port_t); -int hwahc_set_cluster_id(dev_info_t *, uint8_t); -int hwahc_set_stream_idx(dev_info_t *, uint8_t); -int hwahc_set_wusb_mas(dev_info_t *, uint8_t *); -int hwahc_add_mmc_ie(dev_info_t *dip, uint8_t interval, uint8_t rcnt, - uint8_t iehdl, uint16_t len, uint8_t *data); -int hwahc_remove_mmc_ie(dev_info_t *dip, uint8_t iehdl); -int hwahc_stop_ch(dev_info_t *dip, uint32_t time); -int hwahc_set_num_dnts(dev_info_t *dip, uint8_t interval, uint8_t nslot); -int hwahc_get_time(dev_info_t *dip, uint8_t time_type, uint16_t len, - uint32_t *time); - -#ifdef __cplusplus -} -#endif - -#endif /* _SYS_USB_HWAHC_UTIL_H */ diff --git a/usr/src/uts/common/sys/usb/usba/usba_impl.h b/usr/src/uts/common/sys/usb/usba/usba_impl.h index 73b5cd9556..06e1744dc4 100644 --- a/usr/src/uts/common/sys/usb/usba/usba_impl.h +++ b/usr/src/uts/common/sys/usb/usba/usba_impl.h @@ -21,6 +21,8 @@ /* * Copyright 2009 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. + * + * Copyright 2014 Garrett D'Amore <garrett@damore.org> */ #ifndef _SYS_USB_USBA_USBA_IMPL_H @@ -265,15 +267,9 @@ void usba_devdb_destroy(); int usba_hubdi_register(dev_info_t *, uint_t); int usba_hubdi_unregister(dev_info_t *); -void usba_whcdi_initialization(); -void usba_whcdi_destroy(); - int usba_is_root_hub(dev_info_t *dip); -int usba_is_wa(dev_info_t *dip); -int usba_is_hwa(dev_info_t *dip); usba_device_t *usba_alloc_usba_device(dev_info_t *); -void usba_free_wireless_data(usba_wireless_data_t *wireless_data); void usba_free_usba_device(usba_device_t *usba_device_t); void usba_clear_data_toggle(usba_device_t *usba_device); diff --git a/usr/src/uts/common/sys/usb/usba/usba_private.h b/usr/src/uts/common/sys/usb/usba/usba_private.h index 7cf9addf42..4e56e4aa47 100644 --- a/usr/src/uts/common/sys/usb/usba/usba_private.h +++ b/usr/src/uts/common/sys/usb/usba/usba_private.h @@ -21,6 +21,8 @@ /* * Copyright 2009 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. + * + * Copyright 2014 Garrett D'Amore <garrett@damore.org> */ #ifndef _SYS_USB_USBA_USBA_PRIVATE_H @@ -203,30 +205,6 @@ size_t usb_parse_CV_descr( size_t structlen); /* - * For WUSB extended descriptors - */ -size_t -usb_parse_bos_descr(uchar_t *buf, /* from GET_DESCRIPTOR(BOS) */ - size_t buflen, - usb_bos_descr_t *ret_descr, - size_t ret_buf_len); - -size_t -usb_parse_uwb_bos_descr(uchar_t *buf, /* from GET_DESCRIPTOR(BOS) */ - size_t buflen, - usb_uwb_cap_descr_t *ret_descr, - size_t ret_buf_len); - -size_t -usb_parse_comp_ep_descr(uchar_t *buf, /* from GET_DESCRIPTOR(CONFIGURATION) */ - size_t buflen, - uint_t if_number, - uint_t alt_if_setting, - uint_t ep_index, - usb_ep_comp_descr_t *ret_descr, - size_t ret_buf_len); - -/* * Returns pointer to the raw config cloud. The client should * not free this space. */ diff --git a/usr/src/uts/common/sys/usb/usba/usba_types.h b/usr/src/uts/common/sys/usb/usba/usba_types.h index e007d5d3c0..7937a42c52 100644 --- a/usr/src/uts/common/sys/usb/usba/usba_types.h +++ b/usr/src/uts/common/sys/usb/usba/usba_types.h @@ -20,6 +20,8 @@ * * Copyright 2009 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. + * + * Copyright 2014 Garrett D'Amore <garrett@damore.org> */ #ifndef _SYS_USB_USBA_USBA_TYPES_H @@ -226,16 +228,6 @@ typedef struct usb_client_dev_data_list { } usb_client_dev_data_list_t; /* - * wireless usb specific data - */ -typedef struct usba_wireless_data { - uint8_t *wusb_bos; /* raw bos descr */ - uint_t wusb_bos_length; /* length of bos descr */ - usb_uwb_cap_descr_t *uwb_descr; /* UWB capability descr */ -} usba_wireless_data_t; - - -/* * This structure uniquely identifies a USB device * with all interfaces, or just one interface of a USB device. * usba_device is associated with a devinfo node @@ -303,11 +295,6 @@ typedef struct usba_device { uchar_t usb_n_cfgs; uchar_t usb_n_ifs; - /* To support WUSB */ - boolean_t usb_is_wa; - boolean_t usb_is_wireless; - usba_wireless_data_t *usb_wireless_data; - /* * power drawn from hub, if > 0, the power has been * subtracted from the parent hub's power budget @@ -356,7 +343,6 @@ typedef struct usba_device { _NOTE(MUTEX_PROTECTS_DATA(usba_device::usb_mutex, usba_device)) _NOTE(MUTEX_PROTECTS_DATA(usba_device::usb_mutex, usba_evdata)) -_NOTE(MUTEX_PROTECTS_DATA(usba_device::usb_mutex, usba_wireless_data)) _NOTE(SCHEME_PROTECTS_DATA("chg at attach only", usba_evdata::ev_rm_cb_id)) @@ -367,13 +353,6 @@ _NOTE(SCHEME_PROTECTS_DATA("chg at attach only", _NOTE(SCHEME_PROTECTS_DATA("chg at attach only", usba_evdata::ev_resume_cb_id)) -_NOTE(SCHEME_PROTECTS_DATA("chg at attach only", - usba_wireless_data::wusb_bos)) -_NOTE(SCHEME_PROTECTS_DATA("chg at attach only", - usba_wireless_data::wusb_bos_length)) -_NOTE(SCHEME_PROTECTS_DATA("chg at attach only", - usba_wireless_data::uwb_descr)) - /* this should be really stable data */ _NOTE(DATA_READABLE_WITHOUT_LOCK(usba_device::usb_serialno_str)) _NOTE(DATA_READABLE_WITHOUT_LOCK(usba_device::usb_root_hub_dip)) @@ -405,9 +384,6 @@ _NOTE(DATA_READABLE_WITHOUT_LOCK(usba_device::usb_client_flags)) _NOTE(DATA_READABLE_WITHOUT_LOCK(usba_device::usb_client_attach_list)) _NOTE(DATA_READABLE_WITHOUT_LOCK(usba_device::usb_client_ev_cb_list)) _NOTE(DATA_READABLE_WITHOUT_LOCK(usba_device::usb_dip)) -_NOTE(DATA_READABLE_WITHOUT_LOCK(usba_device::usb_is_wireless)) -_NOTE(DATA_READABLE_WITHOUT_LOCK(usba_device::usb_wireless_data)) -_NOTE(DATA_READABLE_WITHOUT_LOCK(usba_device::usb_is_wa)) _NOTE(SCHEME_PROTECTS_DATA("set at device creation", usba_device::usb_shared_taskq)) diff --git a/usr/src/uts/common/sys/usb/usbai.h b/usr/src/uts/common/sys/usb/usbai.h index 499d8777e1..407c98a926 100644 --- a/usr/src/uts/common/sys/usb/usbai.h +++ b/usr/src/uts/common/sys/usb/usbai.h @@ -21,6 +21,8 @@ /* * Copyright 2009 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. + * + * Copyright 2014 Garrett D'Amore <garrett@damore.org> */ #ifndef _SYS_USB_USBAI_H @@ -445,113 +447,6 @@ typedef struct usb_string_descr { #define USB_MAXSTRINGLEN 255 /* max string descr length */ - -/* - * usb_bos_descr: - * usb BOS descriptor, refer to WUSB 1.0/7.4.1 - */ -typedef struct usb_bos_descr { - uint8_t bLength; - uint8_t bDescriptorType; - uint16_t wTotalLength; - uint8_t bNumDeviceCaps; -} usb_bos_descr_t; - -/* - * usb_dev_cap_header: - * usb device capability descriptor header, refer to WUSB 1.0/7.4.1 - */ -typedef struct usb_cap_descr_header { - uint8_t bLength; - uint8_t bDescriptorType; - uint8_t bDevCapabilityType; -} usb_cap_descr_header_t; - -typedef struct usb_cap_descr { - uint8_t bLength; - uint8_t bDescriptorType; /* set to DEVICE CAPABILITY */ - uint8_t bDevCapabilityType; - uint8_t bCapValue[1]; /* variable length data */ -} usb_cap_descr_t; - -#define USB_CAP_TYPE_WUSB 1 - -/* Wireless USB device capability descriptor - UWB descriptor */ -typedef struct usb_uwb_cap_descr { - uint8_t bLength; - uint8_t bDescriptorType; - uint8_t bDevCapabilityType; - uint8_t bmAttributes; - uint16_t wPHYRates; - uint8_t bmTFITXPowerInfo; - uint8_t bmFFITXPowerInfo; - uint16_t bmBandGroup; - uint8_t bReserved; -} usb_uwb_cap_descr_t; - -/* - * usb_ep_comp_descr: - * usb endpoint companion descriptor, refer to WUSB 1.0/7.4.4 - */ -typedef struct usb_ep_comp_descr { - uint8_t bLength; - uint8_t bDescriptorType; - uint8_t bMaxBurst; - uint8_t bMaxSequence; - uint16_t wMaxStreamDelay; - uint16_t wOverTheAirPacketSize; - uint8_t bOverTheAirInterval; - uint8_t bmCompAttributes; -} usb_ep_comp_descr_t; - -/* - * usb_security_descr: - * usb security descriptor, refer to WUSB 1.0/7.4.5 - */ -typedef struct usb_security_descr { - uint8_t bLength; - uint8_t bDescriptorType; - uint16_t wTotalLength; - uint8_t bNumEncryptionTypes; -} usb_security_descr_t; - -/* - * usb_encryption_descr: - * usb encryption descriptor, refer to WUSB 1.0/7.4.5 - */ -typedef struct usb_encryption_descr { - uint8_t bLength; - uint8_t bDescriptorType; - uint8_t bEncryptionType; - uint8_t bEncryptionValue; - uint8_t bAuthKeyIndex; -} usb_encryption_descr_t; - -#define USB_ENC_TYPE_UNSECURE 0x00 -#define USB_ENC_TYPE_WIRED 0x01 -#define USB_ENC_TYPE_CCM_1 0x02 -#define USB_ENC_TYPE_RSA_1 0x03 - -/* - * usb_key_descr: - * usb key descriptor, refer to WUSB 1.0/7.4.5 - */ -typedef struct usb_key_descr { - uint8_t bLength; - uint8_t bDescriptorType; - uint8_t tTKID[3]; - uint8_t bReserved; - uint8_t KeyData[1]; /* variable length */ -} usb_key_descr_t; - -#define USB_EP_COMP_DESCR_SIZE 10 -#define USB_BOS_DESCR_SIZE 5 -#define USB_CAP_DESCR_HEADER_SIZE 3 -#define USB_UWB_CAP_DESCR_SIZE 11 -#define USB_SECURITY_DESCR_SIZE 5 -#define USB_ENCRYPTION_DESCR_SIZE 5 - - /* * *************************************************************************** * Client driver registration with USBA @@ -622,7 +517,6 @@ typedef struct usb_alt_if_data { */ typedef struct usb_ep_data { usb_ep_descr_t ep_descr; /* endpoint descriptor */ - usb_ep_comp_descr_t ep_comp_descr; /* endpoint companion descr */ struct usb_cvs_data *ep_cvs; /* cv mod/extending this ep */ uint_t ep_n_cvs; /* #elements in ep_cvs[] */ } usb_ep_data_t; @@ -638,15 +532,6 @@ typedef struct usb_cvs_data { /* - * Data structure for wireless USB specific descriptor - */ -typedef struct usb_bos_data { - usb_bos_descr_t bos_descr; /* parsed bos descr */ - usb_uwb_cap_descr_t bos_uwb_cap; /* uwb cap descr */ -} usb_bos_data_t; - - -/* * Parse_level determines the extent to which the tree is built, the amount * of parsing usb_client_attach() is to do. It has the following values: * @@ -691,7 +576,6 @@ typedef struct usb_client_dev_data { uint_t dev_n_cfg; /* #elements in dev_cfg[] */ struct usb_cfg_data *dev_curr_cfg; /* current cfg */ int dev_curr_if; /* current interface number */ - struct usb_bos_data *dev_bos; /* bos for this device */ } usb_client_dev_data_t; diff --git a/usr/src/uts/common/sys/uwb/uwb.h b/usr/src/uts/common/sys/uwb/uwb.h deleted file mode 100644 index 56ae2d492c..0000000000 --- a/usr/src/uts/common/sys/uwb/uwb.h +++ /dev/null @@ -1,371 +0,0 @@ -/* - * 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 - * or http://www.opensolaris.org/os/licensing. - * 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. - */ - -#ifndef _SYS_UWB_UWB_H -#define _SYS_UWB_UWB_H - - -#ifdef __cplusplus -extern "C" { -#endif - -/* - * IOCTLs and related data structures for UWB Radio Controller drivers. - */ - -/* IOCTLs */ -#define UWB_IOCTL_BASE 0x1000 -#define UWB_COMMAND (UWB_IOCTL_BASE + 0x1) -#define UWB_GET_NOTIFICATION (UWB_IOCTL_BASE + 0x2) - -#define UWB_CE_TYPE_GENERAL 0 /* General Command/Event type */ - -/* - * UWB Radio Controller Commands and Events: - * - * See WUSB spec 1.0 [Table 8-68] - * See WHCI 0.95 [Table 3-2],[Table 3-5] - */ -/* Commands */ -#define UWB_CE_CHANNEL_CHANGE 16 -#define UWB_CE_DEV_ADDR_MGMT 17 -#define UWB_CE_GET_IE 18 -#define UWB_CE_RESET 19 -#define UWB_CE_SCAN 20 -#define UWB_CE_SET_BEACON_FILTER 21 -#define UWB_CE_SET_DRP_IE 22 -#define UWB_CE_SET_IE 23 -#define UWB_CE_SET_NOTIFICATION_FILTER 24 -#define UWB_CE_SET_TX_POWER 25 -#define UWB_CE_SLEEP 26 -#define UWB_CE_START_BEACON 27 -#define UWB_CE_STOP_BEACON 28 -#define UWB_CE_BP_MERGE 29 -#define UWB_CE_SEND_COMMAND_FRAME 30 -#define UWB_CE_SET_ASIE_NOTIFICATION 31 - -/* Notifications */ -#define UWB_NOTIF_IE_RECEIVED 0 -#define UWB_NOTIF_BEACON_RECEIVED 1 -#define UWB_NOTIF_BEACON_SIZE_CHANGE 2 -#define UWB_NOTIF_BPOIE_CHANGE 3 -#define UWB_NOTIF_BP_SLOT_CHANGE 4 -#define UWB_NOTIF_BP_SWITCH_IE_RECEIVED 5 -#define UWB_NOTIF_DEV_ADDR_CONFLICT 6 -#define UWB_NOTIF_DRP_AVAILABILITY_CHANGE 7 -#define UWB_NOTIF_DRP 8 -#define UWB_NOTIF_BP_SWITCH_STATUS 9 -#define UWB_NOTIF_CMD_FRAME_RCV 10 -#define UWB_NOTIF_CHANNEL_CHANGE_IE_RCV 11 -#define UWB_NOTIF_RESERVED 12 - -/* - * Scan types. - * WUSB spec 1.0 [Table 8-78. Scan RCCB] - * WHCI 0.95 [Table 3-14. Scan RCCB Format] - */ -#define UWB_RC_SCAN_ONLY 0 -#define UWB_RC_SCAN_OUTSIDE_BP 1 -#define UWB_RC_SCAN_WHILE_INACTIVE 2 -#define UWB_RC_SCAN_DISABLED 3 -#define UWB_RC_SCAN_ONLY_STARTTIME 4 - -/* - * See ECMA-368 [7.2.2 Device address] - * Individual MAC sublayers are addressed via an EUI-48 [I3] - * DevAddrs are 16-bit values - */ -typedef struct uwb_mac_addr { - uint8_t addr[6]; -} uwb_mac_addr_t; - -typedef struct uwb_dev_addr { - uint8_t addr[2]; -} uwb_dev_addr_t; - -/* - * See ECMA-368 [16.8.6] - * One superframe has 256 Medium Access Slots. - * One superframe has 16 zones. - */ -#define UWB_MAS_NUM 256 -#define UWB_ZONE_NUM 16 - -/* Type of DRP reservation. ECMA-368 [table 106] */ -#define UWB_DRP_TP_ALIEN 0 -#define UWB_DRP_TP_HARD 1 -#define UWB_DRP_TP_SOFT 2 -#define UWB_DRP_TP_PRVT 3 -#define UWB_DRP_TP_PCA 4 -#define UWB_DRP_TP_RESVD 5 - -/* DRP Reasons. ECMA-368 [table 107] */ -#define UWB_DRP_RS_ACCEP 0 -#define UWB_DRP_RS_CNFLCT 1 -#define UWB_DRP_RS_PNDNG 2 -#define UWB_DRP_RS_DENI 3 -#define UWB_DRP_RS_MODIF 4 -#define UWB_DRP_RS_RSEVD 5 - -/* Allocation of MAS slots in a DRP request. ECMA-368 */ -typedef struct uwb_drp_bm_alloc { - uint16_t zone; - uint16_t mas; -} uwb_drp_bm_alloc_t; - -/* Information elements. ECMA-368 [Table 104] */ -#define UWB_IE_TIM 0 -#define UWB_IE_BPO 1 -#define UWB_IE_PCA_AVAIL 2 -#define UWB_IE_DRP_AVAIL 8 -#define UWB_IE_DRP 9 -#define UWB_IE_HIB_MODE 10 -#define UWB_IE_BP_SWITCH 11 -#define UWB_IE_MAC_CAP 12 -#define UWB_IE_PHY_CAP 13 -#define UWB_IE_PROBE 14 -#define UWB_IE_APPSPEC_PROBE 15 -#define UWB_IE_LINK_FB 16 -#define UWB_IE_HIB_ANCHOR 17 -#define UWB_IE_CHNL_CHG 18 -#define UWB_IE_IDENT 19 -#define UWB_IE_MASTER_KEY_ID 20 -#define UWB_IE_RELQ_REQ 21 -#define UWB_IE_MAB 22 -#define UWB_IE_APP_SPEC 255 - -/* UWB Information Element header. ECMA-368 [16.8] */ -typedef struct uwb_ie_head { - uint8_t id; /* Element ID */ - uint8_t len; /* Length */ -} uwb_ie_head_t; - -/* Dynamic Reservation Protocol IE. ECMA-368 [16.8.6] */ -typedef struct uwb_drp_ie { - uwb_ie_head_t head; - uint16_t drp_ctrl; - uwb_dev_addr_t dev_addr; - uwb_drp_bm_alloc_t allocs[1]; -} uwb_drp_ie_t; - -/* Dynamic Reservation Protocol IE. ECMA-368 [16.8.7] */ -typedef struct uwb_drp_avail_ie { - uwb_ie_head_t head; - ulong_t bitmap[8]; -} uwb_drp_avail_ie_t; - - -/* Data structures for UWB commands */ - -/* WUSB spec 1.0 [Table 8-65] Radio Control Command Block (RCCB) */ -typedef struct uwb_rccb_head { - uint8_t bCommandType; /* Command Type */ - uint16_t wCommand; /* Command code */ - uint8_t bCommandContext; /* Context ID */ -} uwb_rccb_head_t; - -/* Generic RCCB Command */ -typedef struct uwb_rccb_cmd { - uwb_rccb_head_t rccb; - uint8_t buf[1]; -} uwb_rccb_cmd_t; - -/* WUSB spec 1.0. Table 8-78. Scan RCCB */ -typedef struct uwb_rccb_scan { - uwb_rccb_head_t rccb; - uint8_t bChannelNumber; - uint8_t bScanState; - uint16_t wStartTime; -} uwb_rccb_scan_t; - -/* WUSB spec 1.0 Table 8-93. Start Beaconing RCCB */ -typedef struct uwb_rccb_start_beacon { - uwb_rccb_head_t rccb; - uint16_t wBPSTOffset; - uint8_t bChannelNumber; -} uwb_rccb_start_beacon_t; - -/* WUSB spec 1.0 Table 8-82. Set DRP IE RCCB */ -typedef struct uwb_rccb_set_drp_ie { - uwb_rccb_head_t rccb; - uint16_t wIELength; - uint8_t IEData[1]; -} uwb_rccb_set_drp_ie_t; - -/* WUSB spec 1.0 Table 8-84. Set IE RCCB */ -typedef struct uwb_rccb_set_ie { - uwb_rccb_head_t rccb; - uint16_t wIELength; - uint8_t IEData[1]; -}uwb_rccb_set_ie_t; - -/* WUSB spec 1.0 Table 8-72. Device Address Management RCCB */ -typedef struct uwb_rccb_dev_addr_mgmt { - uwb_rccb_head_t rccb; - uint8_t bmOperationType; - uint8_t baAddr[6]; -} uwb_rccb_dev_addr_mgmt_t; - -/* Data structures for UWB Command results (Events) */ - -/* WUSB spec 1.0 Table 8-66. Radio Control Event Block (RCEB) */ -typedef struct uwb_rceb_head { - uint8_t bEventType; - uint16_t wEvent; - uint8_t bEventContext; -} uwb_rceb_head_t; - -/* - * Generic RCEB for commands that returns result code only. - * Including channel change, scan, reset, etc. - */ -typedef struct uwb_rceb_result_code { - uwb_rceb_head_t rceb; - uint8_t bResultCode; -} uwb_rceb_result_code_t; - -/* - * WUSB 1.0 Table 8-73. Device Address Management RCEB - * baAddr should be ignored if the Set bit in the associated - * RCCB is set to 1. The spec is fixed in Errata. - */ -typedef struct uwb_rceb_dev_addr_mgmt { - uwb_rceb_head_t rceb; - uint8_t baAddr[6]; - uint8_t bResultCode; -} uwb_rceb_dev_addr_mgmt_t; - -/* WUSB 1.0 Table 8-75. Get IE RCEB */ -typedef struct uwb_rceb_get_ie { - uwb_rceb_head_t rceb; - uint16_t wIELength; - uint8_t IEData[1]; -} uwb_rceb_get_ie_t; - -/* WUSB 1.0 Table 8-86. Set IE RCEB */ -typedef struct uwb_rceb_set_ie { - uwb_rceb_head_t rceb; - uint16_t RemainingSpace; - uint8_t bResultCode; -} uwb_rceb_set_ie_t; - -/* WUSB 1.0 Table 8-83. Set DRP IE RCEB */ -typedef struct uwb_rceb_set_drp_ie { - uwb_rceb_head_t rceb; - uint16_t wRemainingSpace; - uint8_t bResultCode; -} uwb_rceb_set_drp_ie_t; - - -/* Data structures for UWB Notifications */ - -/* Notification from device */ -typedef struct uwb_rceb_notif { - uwb_rceb_head_t rceb; - uint8_t buf[1]; -} uwb_rceb_notif_t; - -typedef struct uwb_notif_get { - /* wait for milliseconds untile get a notification */ - uint_t timeout; - uwb_rceb_notif_t notif; -} uwb_notif_get_t; - -/* - * UWB_NOTIF_BEACON_RECEIVED, Beacon received notification - * WHCI [3.1.4.2]. - * NOTICE:In WUSB Spec, Table 8-98. No bBeaconType. Below follow - * WHCI spec - */ -typedef struct uwb_rceb_beacon { - uwb_rceb_head_t rceb; - uint8_t bChannelNumber; - uint8_t bBeaconType; - uint16_t wBPSTOffset; - uint8_t bLQI; - uint8_t bRSSI; - uint16_t wBeaconInfoLength; - uint8_t BeaconInfo[1]; -} uwb_rceb_beacon_t; - -/* MAC Header field values for beacon frames. ECMA 368 [table 96] */ -typedef struct uwb_bcfrm_mac_hdr { - uint16_t Frame_Control; - uwb_dev_addr_t DestAddr; - uwb_dev_addr_t SrcAddr; - uint16_t Sequence_Control; - uint16_t Access_Information; -} uwb_bcfrm_mac_hdr_t; - -/* Beacon Frame [ECMA-368] page 151 */ -typedef struct uwb_beacon_frame { - uwb_bcfrm_mac_hdr_t hdr; - uwb_mac_addr_t Device_Identifier; - uint8_t Beacon_Slot_Number; - uint8_t Device_Control; - uint8_t IEData[1]; -} uwb_beacon_frame_t; - -/* WUSB 1.0. Table 8-99. Beacon Size Change Notification RCEB */ -typedef struct uwb_rceb_beacon_size_change { - uwb_rceb_head_t rceb; - uint16_t wNewBeaconSize; -} uwb_rceb_beacon_size_change_t; - -/* WUSB 1.0. Table 8-100. BPOIE Change Notification RCEB */ -typedef struct uwb_rceb_bpoie_change { - uwb_rceb_head_t rceb; - uint16_t wBPOIELength; - uint8_t BPOIE[1]; -} uwb_rceb_bpoie_change_t; - -/* WHCI 0.95 Table 3-42. BP Slot Change Notification RCEB Format */ -typedef struct uwb_rceb_bp_slot_change { - uwb_rceb_head_t rceb; - uint8_t bNewSlotNumber; -} uwb_rceb_bp_slot_change_t; - -/* WHCI 0.95 Table 3-45. DRP Availability Changed Notification RCEB Format */ -typedef struct uwb_rceb_drp_availability { - uwb_rceb_head_t rceb; - uint8_t DRPAvailability[32]; /* 256 bit bitmap */ -} uwb_rceb_drp_availability_t; - -/* WHCI 0.95 [3.1.4.9] * Table 3-46. DRP Notification RCEB Format */ -typedef struct uwb_rceb_drp { - uwb_rceb_head_t rceb; - uint16_t wSrcAddr; - uint8_t bReason; - uint8_t bBeaconSlotNumber; - uint16_t wIELength; - uint8_t IEData[1]; -} uwb_rceb_drp_t; - - -#ifdef __cplusplus -} -#endif - -#endif /* _SYS_UWB_UWB_H */ diff --git a/usr/src/uts/common/sys/uwb/uwba/uwba.h b/usr/src/uts/common/sys/uwb/uwba/uwba.h deleted file mode 100644 index ff5e2103b4..0000000000 --- a/usr/src/uts/common/sys/uwb/uwba/uwba.h +++ /dev/null @@ -1,343 +0,0 @@ -/* - * 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 - * or http://www.opensolaris.org/os/licensing. - * 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. - */ - -#ifndef _SYS_UWB_UWBA_H -#define _SYS_UWB_UWBA_H - -#ifdef __cplusplus -extern "C" { -#endif - - -/* - * UWBA private header file. - */ - -#include <sys/note.h> -#include <sys/sunddi.h> -#include <sys/types.h> -#include <sys/list.h> -#include <sys/bitset.h> -#include <sys/bitmap.h> - -#include <sys/uwb/uwb.h> -#include <sys/uwb/uwbai.h> - -/* For logging. */ -#define UWBA_LOG_DEBUG 2 -#define UWBA_LOG_LOG 1 -#define UWBA_LOG_CONSOLE 0 - -#define offsetof(s, m) ((size_t)(&(((s *)0)->m))) -#define isdigit(ch) ((ch >= '0') && (ch <= '9')) - -#define UWB_RAW_RESULT_CODE_SIZE 5 /* size of RCEB + bResultCode */ -#define UWB_RAW_RCCB_HEAD_SIZE 4 /* size of RCCB */ - -#define UWB_RAW_BEVENTTYPE_OFFSET 0 /* offset of bEventType */ -#define UWB_RAW_WEVENT_OFFSET 1 /* offset of wEvent */ -#define UWB_RAW_BEVENTCONTEXT_OFFSET 3 /* offset of bEventContext */ -#define UWB_RAW_BRESULTCODE_OFFSET 4 /* offset of bResultCode */ - - - -#define UWB_CTXT_ID_TOP 0xfe /* top context id */ -#define UWB_CTXT_ID_BOTTOM 0x1 /* bottom context id */ -#define UWB_CTXT_ID_NOTIF 0x0 /* notification context id */ -#define UWB_CTXT_ID_UNVALID 0xff /* invalid context id */ - - -#define UWB_INVALID_EVT_CODE 0x7ffe /* invalid evt/notif code */ -#define UWB_INVALID_EVT_SIZE 0x7fff /* invalid evt length */ - -#define UWB_MAX_NOTIF_NUMBER 10 /* Max notifications in a notif_list */ - -#define UWB_MAX_CDEV_NUMBER 32 /* Max client radio device */ - -/* - * Offset of data rates Bits in PHY Capability Bitmap. - * [ECMA, 16.8.16, table 112] - */ -#define UWB_RATE_OFFSET_BASE 16 -/* the offset of data rate 53.3Mbps in PHY capability bitmap */ -#define UWB_RATE_OFFSET_53 UWB_RATE_OFFSET_BASE -#define UWB_RATE_OFFSET_80 (UWB_RATE_OFFSET_BASE + 1) /* 80Mbps */ -#define UWB_RATE_OFFSET_106 (UWB_RATE_OFFSET_BASE + 2) -#define UWB_RATE_OFFSET_160 (UWB_RATE_OFFSET_BASE + 3) -#define UWB_RATE_OFFSET_200 (UWB_RATE_OFFSET_BASE + 4) -#define UWB_RATE_OFFSET_320 (UWB_RATE_OFFSET_BASE + 5) -#define UWB_RATE_OFFSET_400 (UWB_RATE_OFFSET_BASE + 6) -#define UWB_RATE_OFFSET_480 (UWB_RATE_OFFSET_BASE + 7) - -typedef int (*uwb_rccb_handler_t)(uwb_dev_handle_t, uwb_rccb_cmd_t *); -#define UWB_RCCB_NULL_HANDLER ((uwb_rccb_handler_t)0) - -#define UWB_STATE_IDLE 0 -#define UWB_STATE_BEACON 1 -#define UWB_STATE_SCAN 2 - -/* radio client device */ -typedef struct uwba_client_dev { - uint8_t bChannelNumber; - uint8_t bBeaconType; - uint16_t wBPSTOffset; - uwb_beacon_frame_t beacon_frame; - list_node_t dev_node; -} uwba_client_dev_t; - -/* Command result from the radio controller */ -typedef struct uwb_cmd_result { - uwb_rceb_head_t rceb; - - /* Cmd result data from device when cmd is finished. */ - uint8_t buf[1]; -} uwb_cmd_result_t; - - -typedef struct uwb_cmd_result_wrapper { - /* Length of a uwb cmd_result */ - int length; - - uwb_cmd_result_t *cmd_result; -} uwb_cmd_result_wrapper_t; - -typedef struct uwb_notif_wrapper { - /* Length of uwb notifcation */ - int length; - uwb_rceb_notif_t *notif; - - list_node_t notif_node; -} uwb_notif_wrapper_t; - - - -typedef struct uwba_dev { - /* dip of the uwb radio controller device */ - dev_info_t *dip; - - /* Dev and instance */ - char *devinst; - - kmutex_t dev_mutex; - - /* send cmd to the device */ - int (*send_cmd)(uwb_dev_handle_t, mblk_t *, uint16_t); - - /* current command block */ - uwb_rccb_cmd_t curr_rccb; - - /* wait for cmd complete and the cmd result available */ - kcondvar_t cmd_result_cv; - kcondvar_t cmd_handler_cv; - - /* filled by uwb_fill_cmd_result in rc driver's cmd call back */ - uwb_cmd_result_wrapper_t cmd_result_wrap; - - /* - * set to TRUE when start to do cmd ioctl; - * set to FALSE when put_cmd and exit cmd ioctl - */ - boolean_t cmd_busy; - - /* Device state */ - uint8_t dev_state; - - /* Beacon or scan channel */ - uint8_t channel; - - /* Device address */ - uint16_t dev_addr; - - /* notifications from radio controller device */ - list_t notif_list; - - /* the current number of notifications in the notif_list */ - int notif_cnt; - - /* client radio devices found through beacons by this radio host */ - list_t client_dev_list; - - /* the current number of devices in dev_list */ - int client_dev_cnt; - - /* context id is maintained by uwba */ - uint8_t ctxt_id; /* current command context id */ - bitset_t ctxt_bits; /* command context bit map */ - - /* PHY capability bitmap, saved from PHY capability IE */ - ulong_t phy_cap_bm; - - /* list node of a uwb radio host device */ - list_node_t uwba_dev_node; -} uwba_dev_t; - -_NOTE(MUTEX_PROTECTS_DATA(uwba_dev_t::dev_mutex, uwba_dev_t)) -_NOTE(DATA_READABLE_WITHOUT_LOCK(uwba_dev_t::{ - dip - devinst - send_cmd - phy_cap_bm - notif_cnt - dev_state - dip - ctxt_id - ctxt_bits - notif_list - cmd_result_wrap - client_dev_cnt - channel - dev_addr -})) - - -typedef struct uwba_evt_size { - /* length of a evt/notif structure, impact by alignment */ - uint8_t struct_len; - - /* - * offset of the length member of an event/notif struct. - * if zero, means there is no variable buf length member - * in this struct - */ - uint16_t buf_len_offset; -} uwba_evt_size_t; -typedef struct uwba_channel_range { - /* First channel in the specific bandgroup */ - uint8_t base; - - /* Length since this first channel in the bandgroup */ - uint8_t offset; -} uwba_channel_range_t; - -#define UWB_RESULT_CODE_SIZE (sizeof (uwb_rceb_result_code_t)) - -/* str_t is the struct type of the notif/evt */ -#define UWB_EVT_RCEB_SZ (sizeof (uwb_rceb_t)) - -/* the size after excluded the rceb head */ -#define UWB_EVT_END_SZ(stru_t) (sizeof (stru_t) - sizeof (uwb_rceb_t)) - -#define UWB_EVT_NO_BUF_LEN_OFFSET 0 - -/* Offset of wBeaconInfoLength in uwb_rceb_beacon_t */ -#define UWB_BEACONINFOLEN_OFFSET 10 - -/* Offset of BeaconInfo from bChannelNumber in uwb_rceb_beacon_t */ -#define UWB_BEACONINFO_OFFSET 8 - -/* - * UWB radio controller device list - */ -void uwba_dev_add_to_list(uwba_dev_t *); -void uwba_dev_rm_from_list(uwba_dev_t *); -void uwba_alloc_uwb_dev(dev_info_t *, uwba_dev_t **, uint_t); -void uwba_free_uwb_dev(uwba_dev_t *); -uwb_dev_handle_t uwba_dev_search(dev_info_t *); - -/* - * Context ID operations - */ -void uwba_init_ctxt_id(uwba_dev_t *); -void uwba_fini_ctxt_id(uwba_dev_t *); -uint8_t uwba_get_ctxt_id(uwba_dev_t *); -void uwba_free_ctxt_id(uwba_dev_t *, uint8_t); - -void uwba_fill_rccb_head(uwba_dev_t *, uint16_t, mblk_t *); -uint16_t uwba_get_evt_code(uint8_t *, int); -uint16_t uwba_get_evt_size(uint8_t *, int, uint16_t); - -void uwba_put_cmd_result(uwba_dev_t *, void *, uint16_t); -int uwba_add_notif_to_list(uwba_dev_t *, void *, uint16_t); - -/* - * Parse events/notifications from radio controller device - */ -int uwba_parse_data(char *, uchar_t *, size_t, void *, size_t); -int uwba_parse_rceb(uint8_t *, size_t, void *, size_t); -int uwba_parse_dev_addr_mgmt(uint8_t *, int, uwb_rceb_dev_addr_mgmt_t *); -int uwba_parse_get_ie(uwb_dev_handle_t, uint8_t *, - int, uwb_rceb_get_ie_t *); -int uwba_parse_beacon_rcv(uwb_dev_handle_t, uint8_t *, - int, uwb_rceb_beacon_t *); -int uwba_parse_bpoie_chg(uwb_dev_handle_t, uint8_t *, - int, uwb_rceb_bpoie_change_t *); -uint8_t uwba_allocate_channel(uwb_dev_handle_t); -uint8_t *uwba_find_ie(uwb_dev_handle_t, uint_t, uint8_t *, uint16_t); - -void uwba_copy_rccb(uwb_rccb_cmd_t *, uwb_rccb_cmd_t *); - -uwba_client_dev_t *uwba_find_cdev_by_channel(uwba_dev_t *, uint8_t); - -/* Debug/message log */ -void uwba_log(uwba_dev_t *, uint_t, char *, ...); -const char *uwba_event_msg(uint16_t); - -/* Turn a little endian byte array to a uint32_t */ -#define LE_TO_UINT32(src, off, des) \ -{ \ - uint32_t tmp; \ - des = src[off + 3]; \ - des = des << 24; \ - tmp = src[off + 2]; \ - des |= tmp << 16; \ - tmp = src[off + 1]; \ - des |= tmp << 8; \ - des |= src[off]; \ -} - -/* Turn a uint32_t to a little endian byte array */ -#define UINT32_TO_LE(src, off, des) \ -{ \ - des[off + 0] = 0xff & src; \ - des[off + 1] = 0xff & (src >> 8); \ - des[off + 2] = 0xff & (src >> 16); \ - des[off + 3] = 0xff & (src >> 24); \ -} - -/* Turn a little endian byte array to a uint16_t */ -#define LE_TO_UINT16(src, off, des) \ -{ \ - des = src[off + 1]; \ - des = des << 8; \ - des |= src[off]; \ -} - -/* Turn a uint16_t to alittle endian byte array */ -#define UINT16_TO_LE(src, off, des) \ -{ \ - des[off + 0] = 0xff & src; \ - des[off + 1] = 0xff & (src >> 8); \ -} - - -/* Max string length for the driver name and instance number. */ -#define UWB_MAXSTRINGLEN 255 - - -#ifdef __cplusplus -} -#endif - -#endif /* _SYS_UWB_UWBA_H */ diff --git a/usr/src/uts/common/sys/uwb/uwbai.h b/usr/src/uts/common/sys/uwb/uwbai.h deleted file mode 100644 index b9594d5cd6..0000000000 --- a/usr/src/uts/common/sys/uwb/uwbai.h +++ /dev/null @@ -1,105 +0,0 @@ -/* - * 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 - * or http://www.opensolaris.org/os/licensing. - * 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. - */ - -#ifndef _SYS_UWB_UWBAI_H -#define _SYS_UWB_UWBAI_H - - -#ifdef __cplusplus -extern "C" { -#endif - -/* - * This header file includes interfaces for UWB radio controller drivers. - */ - -/* - * A uwb device handle is returned by uwb_device_attach() on success. The - * handle is opaque to the client uwba driver. The implimentation structure is - * uwba_dev - */ -typedef struct uwb_dev_handle *uwb_dev_handle_t; - - -/* - * UWBA function return values - */ -#define UWB_SUCCESS 0 /* call success */ -#define UWB_FAILURE -1 /* unspecified UWBA or HCD error */ -#define UWB_NO_RESOURCES -2 /* no resources available */ -#define UWB_NO_BANDWIDTH -3 /* no bandwidth available */ -#define UWB_NOT_SUPPORTED -4 /* function not supported by HCD */ -#define UWB_PIPE_ERROR -5 /* error occured on the pipe */ -#define UWB_INVALID_PIPE -6 /* pipe handle passed is invalid */ -#define UWB_NO_FRAME_NUMBER -7 /* frame No or ASAP not specified */ -#define UWB_INVALID_START_FRAME -8 /* starting UWB frame not valid */ -#define UWB_HC_HARDWARE_ERROR -9 /* UWB host controller error */ -#define UWB_INVALID_REQUEST -10 /* request had invalid values */ -#define UWB_INVALID_CONTEXT -11 /* sleep flag in interrupt context */ -#define UWB_INVALID_VERSION -12 /* invalid version specified */ -#define UWB_INVALID_ARGS -13 /* invalid func args specified */ -#define UWB_INVALID_PERM -14 /* privileged operation */ -#define UWB_BUSY -15 /* busy condition */ -#define UWB_PARSE_ERROR -18 - - - -/* Max wait time for each uwb cmd */ -#define UWB_CMD_TIMEOUT (ddi_get_lbolt() + drv_usectohz(10000000)) - - -/* - * Radio controller driver registion - */ -void uwb_dev_attach(dev_info_t *, uwb_dev_handle_t *, uint_t, - int (*)(uwb_dev_handle_t, mblk_t *, uint16_t)); -void uwb_dev_detach(uwb_dev_handle_t); - -/* UWB COMMON INTERFACES */ -int uwb_do_ioctl(uwb_dev_handle_t, int, intptr_t, int); -int uwb_parse_evt_notif(uint8_t *, int, uwb_dev_handle_t); -int uwb_scan_channel(uwb_dev_handle_t, uint8_t); -int uwb_reset_dev(dev_info_t *); -int uwb_init_phy(dev_info_t *); -int uwb_stop_beacon(dev_info_t *); -int uwb_start_beacon(dev_info_t *, uint8_t); -int uwb_get_mac_addr(dev_info_t *, uint8_t *); -int uwb_get_dev_addr(dev_info_t *, uint16_t *); -int uwb_set_dev_addr(dev_info_t *, uint16_t); -uint8_t uwb_allocate_channel(dev_info_t *); - -int uwb_dev_disconnect(dev_info_t *); -int uwb_dev_reconnect(dev_info_t *); - -int uwb_dev_online(dev_info_t *); -int uwb_dev_offline(dev_info_t *); - -dev_info_t *uwb_get_dip(uwb_dev_handle_t); - -#ifdef __cplusplus -} -#endif - -#endif /* _SYS_UWB_UWBAI_H */ diff --git a/usr/src/uts/intel/Makefile.intel b/usr/src/uts/intel/Makefile.intel index acdedaf5ca..bd346b5dab 100644 --- a/usr/src/uts/intel/Makefile.intel +++ b/usr/src/uts/intel/Makefile.intel @@ -456,7 +456,6 @@ DRV_KMODS += ses # USB specific modules # DRV_KMODS += hid -DRV_KMODS += hwarc hwahc DRV_KMODS += hubd DRV_KMODS += uhci DRV_KMODS += ehci @@ -475,8 +474,6 @@ DRV_KMODS += usb_as DRV_KMODS += usbskel DRV_KMODS += usbvc DRV_KMODS += usbftdi -DRV_KMODS += wusb_df -DRV_KMODS += wusb_ca DRV_KMODS += usbecm # @@ -637,9 +634,7 @@ MISC_KMODS += qlc_fw_2400 MISC_KMODS += qlc_fw_2500 MISC_KMODS += qlc_fw_6322 MISC_KMODS += qlc_fw_8100 -MISC_KMODS += hwa1480_fw MISC_KMODS += uathfw -MISC_KMODS += uwba MISC_KMODS += klmmod klmops diff --git a/usr/src/uts/intel/hid/Makefile b/usr/src/uts/intel/hid/Makefile index 98ab745af4..ad070dfb6d 100644 --- a/usr/src/uts/intel/hid/Makefile +++ b/usr/src/uts/intel/hid/Makefile @@ -23,6 +23,7 @@ # Copyright 2009 Sun Microsystems, Inc. All rights reserved. # Use is subject to license terms. # +# Copyright 2014 Garrett D'Amore <garrett@damore.org> # # This makefile drives the production of the hid driver kernel module. # @@ -114,7 +115,7 @@ TEST = test # # lock_lint rules # -USBA_FILES = $(USBA_WITHOUT_WUSB_OBJS:%.o=../usba/%.ll) +USBA_FILES = $(USBA_OBJS:%.o=../usba/%.ll) OHCI_FILES = $(OHCI_OBJS:%.o=../ohci/%.ll) UHCI_FILES = $(UHCI_OBJS:%.o=../uhci/%.ll) EHCI_FILES = $(EHCI_OBJS:%.o=../ehci/%.ll) diff --git a/usr/src/uts/intel/hwa1480_fw/Makefile b/usr/src/uts/intel/hwa1480_fw/Makefile deleted file mode 100644 index ace371f7a6..0000000000 --- a/usr/src/uts/intel/hwa1480_fw/Makefile +++ /dev/null @@ -1,132 +0,0 @@ -# -# 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 -# or http://www.opensolaris.org/os/licensing. -# 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 -# -# -# uts/intel/hwa1480_fw/Makefile -# Copyright 2009 Sun Microsystems, Inc. All rights reserved. -# Use is subject to license terms. -# -# -# This makefile drives the production of the hwa1480_fw kernel module. -# -# -# Path to the base of the uts directory tree (usually /usr/src/uts). -# -UTSBASE = ../.. - -# -# Define the module and object file sets. -# -MODULE = hwa1480_fw -OBJECTS = $(WUSB_FWMOD_OBJS:%=$(OBJS_DIR)/%) -LINTS = $(WUSB_FWMOD_OBJS:%.o=$(LINTS_DIR)/%.ln) -ROOTMODULE = $(ROOT_MISC_DIR)/$(MODULE) -WARLOCK_OUT = $(WUSB_FWMOD_OBJS:%.o=%.ll) -WARLOCK_OK = $(MODULE).ok - -FWOBJ = $(OBJS_DIR)/$(MODULE).o - -OBJECTS += $(FWOBJ) - -# -# Include common rules. -# -include $(UTSBASE)/intel/Makefile.intel - -LDFLAGS = -# -# Define targets -# -ALL_TARGET = $(BINARY) -LINT_TARGET = $(MODULE).lint -INSTALL_TARGET = $(BINARY) $(ROOTMODULE) - -# -# For now, disable these lint checks; maintainers should endeavor -# to investigate and remove these for maximum lint coverage. -# Please do not carry these forward to new Makefiles. -# -LINTTAGS += -erroff=E_BAD_PTR_CAST_ALIGN -LINTTAGS += -erroff=E_PTRDIFF_OVERFLOW -LINTTAGS += -erroff=E_ASSIGN_NARROW_CONV -LINTTAGS += -erroff=E_STATIC_UNUSED - -CLEANFILES += $(WARLOCK_OUT) $(WARLOCK_OK) -CLOBBERFILES += $(BINSRC)/$(MODULE) - -# -# Default build targets. -# -.KEEP_STATE: - -def: $(DEF_DEPS) $(FWOBJ) - -all: $(ALL_DEPS) - -clean: $(CLEAN_DEPS) - -clobber: $(CLOBBER_DEPS) - -lint: $(LINT_DEPS) - -modlintlib: $(MODLINTLIB_DEPS) - -clean.lint: $(CLEAN_LINT_DEPS) - -install: $(INSTALL_DEPS) - - -# customized section for transforming firmware binary -ELFWRAP = elfwrap -BINSRC = $(UTSBASE)/common/io/usb/clients/hwa1480_fw/i1480 -ORIGIN_SRC = i1480-usb-0.0.bin - -#get build type, 32/64 -WRAPTYPE = $(CLASS:%=-%) - -#set elfwrap option -WRAPOPT = $(WRAPTYPE:-32=) - -$(FWOBJ): - cp $(BINSRC)/$(ORIGIN_SRC) $(BINSRC)/$(MODULE) - $(ELFWRAP) $(WRAPOPT) -o $@ $(BINSRC)/$(MODULE) - -# -# Include common targets. -# -include $(UTSBASE)/intel/Makefile.targ - -# -# Defines for local commands. -# -WLCC = wlcc -TOUCH = touch -WARLOCK = warlock - -# -# Warlock targets -# -warlock: $(WARLOCK_OK) - -$(WARLOCK_OK): $(WARLOCK_OUT) - $(TOUCH) $@ - -%.ll: $(UTSBASE)/common/io/usb/clients/hwa1480_fw/%.c - $(WLCC) $(CPPFLAGS) -DDEBUG -o $@ $< diff --git a/usr/src/uts/intel/hwahc/Makefile b/usr/src/uts/intel/hwahc/Makefile deleted file mode 100644 index 60346ffd44..0000000000 --- a/usr/src/uts/intel/hwahc/Makefile +++ /dev/null @@ -1,149 +0,0 @@ -# -# 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 -# or http://www.opensolaris.org/os/licensing. -# 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 -# -# -# uts/intel/hwahc/Makefile -# Copyright 2009 Sun Microsystems, Inc. All rights reserved. -# Use is subject to license terms. -# -# -# This makefile drives the production of the hwahc driver kernel module. -# - -# -# Path to the base of the uts directory tree (usually /usr/src/uts). -# -UTSBASE = ../.. - -# -# Define the module and object file sets. -# -MODULE = hwahc -OBJECTS = $(HWAHC_OBJS:%=$(OBJS_DIR)/%) -LINTS = $(HWAHC_OBJS:%.o=$(LINTS_DIR)/%.ln) -ROOTMODULE = $(ROOT_DRV_DIR)/$(MODULE) -WARLOCK_OUT = $(HWAHC_OBJS:%.o=%.ll) -WARLOCK_OK = $(MODULE).ok -WLCMD_DIR = $(UTSBASE)/common/io/warlock - -# -# Include common rules. -# -include $(UTSBASE)/intel/Makefile.intel - -CERRWARN += -_gcc=-Wno-uninitialized -CERRWARN += -_gcc=-Wno-switch - -# -# Define targets -# -ALL_TARGET = $(BINARY) -LINT_TARGET = $(MODULE).lint -INSTALL_TARGET = $(BINARY) $(ROOTMODULE) - -# -# Override defaults to build a unique, local modstubs.o. -# -MODSTUBS_DIR = $(OBJS_DIR) -CLEANFILES += $(MODSTUBS_O) - -# -# depends on misc/usba -# -LDFLAGS += -dy -Nmisc/usba -Nmisc/uwba - -# -# Default build targets. -# -.KEEP_STATE: - -def: $(DEF_DEPS) - -all: $(ALL_DEPS) - -clean: $(CLEAN_DEPS) - $(RM) $(WARLOCK_OUT) $(WARLOCK_OK) - -clobber: $(CLOBBER_DEPS) - $(RM) $(WARLOCK_OUT) $(WARLOCK_OK) - -lint: $(LINT_DEPS) - -modlintlib: $(MODLINTLIB_DEPS) - -clean.lint: $(CLEAN_LINT_DEPS) - -install: $(INSTALL_DEPS) - -# -# Include common targets. -# -include $(UTSBASE)/intel/Makefile.targ - -# -# Defines for local commands. -# -WARLOCK = warlock -WLCC = wlcc -TOUCH = touch -SCCS = sccs -TEST = test - -# -# Warlock targets -# -USBA_FILES = $(USBA_OBJS:%.o= -l ../usba/%.ll) -UHCI_FILES = $(UHCI_OBJS:%.o=../uhci/%.ll) -OHCI_FILES = $(OHCI_OBJS:%.o=../ohci/%.ll) -EHCI_FILES = $(EHCI_OBJS:%.o=../ehci/%.ll) - -warlock: $(WARLOCK_OK) warlock_with_usba - -$(WARLOCK_OK): $(WARLOCK_OUT) $(WLCMD_DIR)/hwahc.wlcmd warlock_ddi.files \ - usba_files - $(WARLOCK) -c $(WLCMD_DIR)/hwahc.wlcmd $(WARLOCK_OUT) \ - -l ../warlock/ddi_dki_impl.ll - $(TOUCH) $@ - -%.ll: $(UTSBASE)/common/io/usb/hwa/hwahc/%.c \ - $(UTSBASE)/common/sys/usb/hwa/hwahc/hwahc.h \ - $(UTSBASE)/common/sys/usb/hwa/hwahc/hwahc_util.h - $(WLCC) $(CPPFLAGS) -DDEBUG -o $@ $< - -warlock_with_usba: $(WLCMD_DIR)/hwahc_with_usba.wlcmd $(WARLOCK_OUT) usba_files \ - warlock_ddi.files - $(WARLOCK) -c $(WLCMD_DIR)/hwahc_with_usba.wlcmd \ - $(USBA_FILES) $(WARLOCK_OUT) \ - -l ../warlock/ddi_dki_impl.ll - -usba_files: - @cd ../usba; pwd; $(MAKE) warlock - -uhci_files: - @cd ../uhci; pwd; $(MAKE) warlock - -ohci_files: - @cd ../ohci; pwd; $(MAKE) warlock - -ehci_files: - @cd ../ehci; pwd; $(MAKE) warlock - -warlock_ddi.files: - @cd ../warlock; pwd; $(MAKE) warlock diff --git a/usr/src/uts/intel/hwarc/Makefile b/usr/src/uts/intel/hwarc/Makefile deleted file mode 100644 index 390fa2785b..0000000000 --- a/usr/src/uts/intel/hwarc/Makefile +++ /dev/null @@ -1,154 +0,0 @@ -# -# 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 -# or http://www.opensolaris.org/os/licensing. -# 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 -# -# -# uts/intel/hwarc/Makefile -# Copyright 2009 Sun Microsystems, Inc. All rights reserved. -# Use is subject to license terms. -# -# -# This makefile drives the production of the hwarc driver kernel module. -# - -# -# Path to the base of the uts directory tree (usually /usr/src/uts). -# -UTSBASE = ../.. - -# -# Define the module and object file sets. -# -MODULE = hwarc -OBJECTS = $(HWA_RC_OBJS:%=$(OBJS_DIR)/%) -LINTS = $(HWA_RC_OBJS:%.o=$(LINTS_DIR)/%.ln) -ROOTMODULE = $(ROOT_DRV_DIR)/$(MODULE) -WARLOCK_OUT = $(HWA_RC_OBJS:%.o=%.ll) -WARLOCK_OK = $(MODULE).ok -WLCMD_DIR = $(UTSBASE)/common/io/warlock - -# -# Include common rules. -# -include $(UTSBASE)/intel/Makefile.intel - -# -# Define targets -# -ALL_TARGET = $(BINARY) -LINT_TARGET = $(MODULE).lint -INSTALL_TARGET = $(BINARY) $(ROOTMODULE) - -# -# Override defaults to build a unique, local modstubs.o. -# -MODSTUBS_DIR = $(OBJS_DIR) -CLEANFILES += $(MODSTUBS_O) - -# -# depends on misc/usba -# -LDFLAGS += -dy -Nmisc/usba -Nmisc/uwba - -# -# For now, disable these lint checks; maintainers should endeavor -# to investigate and remove these for maximum lint coverage. -# Please do not carry these forward to new Makefiles. -# -LINTTAGS += -erroff=E_PTRDIFF_OVERFLOW - -# -# Default build targets. -# -.KEEP_STATE: - -def: $(DEF_DEPS) - -all: $(ALL_DEPS) - -clean: $(CLEAN_DEPS) - $(RM) $(WARLOCK_OUT) $(WARLOCK_OK) - -clobber: $(CLOBBER_DEPS) - $(RM) $(WARLOCK_OUT) $(WARLOCK_OK) - -lint: $(LINT_DEPS) - -modlintlib: $(MODLINTLIB_DEPS) - -clean.lint: $(CLEAN_LINT_DEPS) - -install: $(INSTALL_DEPS) - -# -# Include common targets. -# -include $(UTSBASE)/intel/Makefile.targ - -# -# Defines for local commands. -# -WARLOCK = warlock -WLCC = wlcc -TOUCH = touch -SCCS = sccs -TEST = test - -# -# lock_lint rules -# -USBA_FILES = $(USBA_OBJS:%.o= -l ../usba/%.ll) -UHCI_FILES = $(UHCI_OBJS:%.o=../uhci/%.ll) -OHCI_FILES = $(OHCI_OBJS:%.o=../ohci/%.ll) -EHCI_FILES = $(EHCI_OBJS:%.o=../ehci/%.ll) - -warlock: $(WARLOCK_OK) warlock_with_usba - -%.wlcmd: - cd $(WLCMD_DIR); $(TEST) -f $@ || $(SCCS) get $@ - -$(WARLOCK_OK): $(WARLOCK_OUT) hwarc.wlcmd warlock_ddi.files usba_files - $(WARLOCK) -c $(WLCMD_DIR)/hwarc.wlcmd $(WARLOCK_OUT) \ - -l ../warlock/ddi_dki_impl.ll - $(TOUCH) $@ - -%.ll: $(UTSBASE)/common/io/usb/clients/hwarc/%.c \ - $(UTSBASE)/common/sys/usb/clients/hwarc/hwarc.h - $(WLCC) $(CPPFLAGS) -DDEBUG -o $@ $< - -warlock_with_usba: hwarc_with_usba.wlcmd $(WARLOCK_OUT) usba_files \ - warlock_ddi.files - $(WARLOCK) -c $(WLCMD_DIR)/hwarc_with_usba.wlcmd \ - $(USBA_FILES) $(WARLOCK_OUT) \ - -l ../warlock/ddi_dki_impl.ll - -usba_files: - @cd ../usba;pwd; $(MAKE) warlock - -uhci_files: - @cd ../uhci;pwd; $(MAKE) warlock - -ohci_files: - @cd ../ohci;pwd; $(MAKE) warlock - -ehci_files: - @cd ../ehci;pwd; $(MAKE) warlock - -warlock_ddi.files: - cd ../warlock; pwd; $(MAKE) warlock diff --git a/usr/src/uts/intel/scsa2usb/Makefile b/usr/src/uts/intel/scsa2usb/Makefile index 9da60a6d6a..8562d9231e 100644 --- a/usr/src/uts/intel/scsa2usb/Makefile +++ b/usr/src/uts/intel/scsa2usb/Makefile @@ -23,6 +23,7 @@ # Copyright 2009 Sun Microsystems, Inc. All rights reserved. # Use is subject to license terms. # +# Copyright 2014 Garrett D'Amore <garrett@damore.org> # # This makefile drives the production of the scsa2usb driver # kernel module. intel architecture dependent @@ -117,7 +118,7 @@ TEST = test # # lock_lint rules # -USBA_FILES = $(USBA_WITHOUT_WUSB_OBJS:%.o=../usba/%.ll) +USBA_FILES = $(USBA_OBJS:%.o=../usba/%.ll) UHCI_FILES = $(UHCI_OBJS:%.o=../uhci/%.ll) OHCI_FILES = $(OHCI_OBJS:%.o=../ohci/%.ll) EHCI_FILES = $(EHCI_OBJS:%.o=../ehci/%.ll) diff --git a/usr/src/uts/intel/ugen/Makefile b/usr/src/uts/intel/ugen/Makefile index 32b475b6fd..a56d9c759e 100644 --- a/usr/src/uts/intel/ugen/Makefile +++ b/usr/src/uts/intel/ugen/Makefile @@ -22,6 +22,7 @@ # Copyright 2009 Sun Microsystems, Inc. All rights reserved. # Use is subject to license terms. # +# Copyright 2014 Garrett D'Amore <garrett@damore.org> # # This makefile drives the production of the ugen driver @@ -102,7 +103,7 @@ TEST = test # # lock_lint rules # -USBA_FILES = $(USBA_WITHOUT_WUSB_OBJS:%.o=../usba/%.ll) +USBA_FILES = $(USBA_OBJS:%.o=../usba/%.ll) UHCI_FILES = $(UHCI_OBJS:%.o=../uhci/%.ll) OHCI_FILES = $(OHCI_OBJS:%.o=../ohci/%.ll) EHCI_FILES = $(EHCI_OBJS:%.o=../ehci/%.ll) diff --git a/usr/src/uts/intel/usb_ac/Makefile b/usr/src/uts/intel/usb_ac/Makefile index 072d676d98..c35c2daa99 100644 --- a/usr/src/uts/intel/usb_ac/Makefile +++ b/usr/src/uts/intel/usb_ac/Makefile @@ -22,6 +22,8 @@ # Copyright 2009 Sun Microsystems, Inc. All rights reserved. # Use is subject to license terms. # +# Copyright 2014 Garrett D'Amore <garrett@damore.org> +# # uts/intel/usb_ac/Makefile # # This makefile drives the production of the usb_ac driver @@ -113,7 +115,7 @@ TEST = test # # lock_lint rules # -USBA_FILES = $(USBA_WITHOUT_WUSB_OBJS:%.o=../usba/%.ll) +USBA_FILES = $(USBA_OBJS:%.o=../usba/%.ll) UHCI_FILES = $(UHCI_OBJS:%.o=../uhci/%.ll) OHCI_FILES = $(OHCI_OBJS:%.o=../ohci/%.ll) EHCI_FILES = $(EHCI_OBJS:%.o=../ehci/%.ll) diff --git a/usr/src/uts/intel/usb_as/Makefile b/usr/src/uts/intel/usb_as/Makefile index 38542942d7..3973a5b4df 100644 --- a/usr/src/uts/intel/usb_as/Makefile +++ b/usr/src/uts/intel/usb_as/Makefile @@ -22,6 +22,8 @@ # Copyright 2009 Sun Microsystems, Inc. All rights reserved. # Use is subject to license terms. # +# Copyright 2014 Garrett D'Amore <garrett@damore.org> +# # uts/sparc/usb_as/Makefile # # This makefile drives the production of the usb_as driver @@ -114,7 +116,7 @@ TEST = test # lock_lint rules # USB_AS_FILES = $(MODULE).ll -USBA_FILES = $(USBA_WITHOUT_WUSB_OBJS:%.o=../usba/%.ll) +USBA_FILES = $(USBA_OBJS:%.o=../usba/%.ll) UHCI_FILES = $(UHCI_OBJS:%.o=../uhci/%.ll) OHCI_FILES = $(OHCI_OBJS:%.o=../ohci/%.ll) EHCI_FILES = $(EHCI_OBJS:%.o=../ehci/%.ll) diff --git a/usr/src/uts/intel/usb_ia/Makefile b/usr/src/uts/intel/usb_ia/Makefile index daac68d010..97c37f7e3e 100644 --- a/usr/src/uts/intel/usb_ia/Makefile +++ b/usr/src/uts/intel/usb_ia/Makefile @@ -23,6 +23,7 @@ # Copyright 2009 Sun Microsystems, Inc. All rights reserved. # Use is subject to license terms. # +# Copyright 2014 Garrett D'Amore <garrett@damore.org> # # This makefile drives the production of the usb_ia driver kernel module. # @@ -105,7 +106,7 @@ TEST = test # # lock_lint rules # -USBA_FILES = $(USBA_WITHOUT_WUSB_OBJS:%.o=../usba/%.ll) +USBA_FILES = $(USBA_OBJS:%.o=../usba/%.ll) UHCI_FILES = $(UHCI_OBJS:%.o=../uhci/%.ll) OHCI_FILES = $(OHCI_OBJS:%.o=../ohci/%.ll) EHCI_FILES = $(EHCI_OBJS:%.o=../ehci/%.ll) diff --git a/usr/src/uts/intel/usb_mid/Makefile b/usr/src/uts/intel/usb_mid/Makefile index 6f5d3df456..ff5fe23bab 100644 --- a/usr/src/uts/intel/usb_mid/Makefile +++ b/usr/src/uts/intel/usb_mid/Makefile @@ -23,6 +23,7 @@ # Copyright 2009 Sun Microsystems, Inc. All rights reserved. # Use is subject to license terms. # +# Copyright 2014 Garrett D'Amore <garrett@damore.org> # # This makefile drives the production of the usb_mid driver kernel module. # @@ -105,7 +106,7 @@ TEST = test # # lock_lint rules # -USBA_FILES = $(USBA_WITHOUT_WUSB_OBJS:%.o=../usba/%.ll) +USBA_FILES = $(USBA_OBJS:%.o=../usba/%.ll) UHCI_FILES = $(UHCI_OBJS:%.o=../uhci/%.ll) OHCI_FILES = $(OHCI_OBJS:%.o=../ohci/%.ll) EHCI_FILES = $(EHCI_OBJS:%.o=../ehci/%.ll) diff --git a/usr/src/uts/intel/usbecm/Makefile b/usr/src/uts/intel/usbecm/Makefile index c30224b2c0..b1f761dfa6 100644 --- a/usr/src/uts/intel/usbecm/Makefile +++ b/usr/src/uts/intel/usbecm/Makefile @@ -23,6 +23,7 @@ # Copyright 2010 Sun Microsystems, Inc. All rights reserved. # Use is subject to license terms. # +# Copyright 2014 Garrett D'Amore <garrett@damore.org> # # This makefile drives the production of Abstract Control Model of # USB Communication Devices Class dirver. @@ -94,7 +95,7 @@ TEST = test # WARLOCK_CMD = $(WLCMD_DIR)/$(MODULE).wlcmd -USBA_FILES = $(USBA_WITHOUT_WUSB_OBJS:%.o=../usba/%.ll) +USBA_FILES = $(USBA_OBJS:%.o=../usba/%.ll) UHCI_FILES = $(UHCI_OBJS:%.o=../uhci/%.ll) OHCI_FILES = $(OHCI_OBJS:%.o=../ohci/%.ll) EHCI_FILES = $(EHCI_OBJS:%.o=../ehci/%.ll) diff --git a/usr/src/uts/intel/usbftdi/Makefile b/usr/src/uts/intel/usbftdi/Makefile index 43a6aa9976..c4521f48f4 100644 --- a/usr/src/uts/intel/usbftdi/Makefile +++ b/usr/src/uts/intel/usbftdi/Makefile @@ -23,6 +23,7 @@ # Copyright 2009 Sun Microsystems, Inc. All rights reserved. # Use is subject to license terms. # +# Copyright 2014 Garrett D'Amore <garrett@damore.org> # # This makefile drives the production of the FT232R USB Serial # Adapter driver. @@ -97,7 +98,7 @@ TEST = test # WARLOCK_CMD = $(WLCMD_DIR)/$(MODULE).wlcmd USBSER_FILES = $(USBSER_OBJS:%.o=../usbser/%.ll) -USBA_FILES = $(USBA_WITHOUT_WUSB_OBJS:%.o=../usba/%.ll) +USBA_FILES = $(USBA_OBJS:%.o=../usba/%.ll) UHCI_FILES = $(UHCI_OBJS:%.o=../uhci/%.ll) OHCI_FILES = $(OHCI_OBJS:%.o=../ohci/%.ll) EHCI_FILES = $(EHCI_OBJS:%.o=../ehci/%.ll) diff --git a/usr/src/uts/intel/usbprn/Makefile b/usr/src/uts/intel/usbprn/Makefile index 8dbb7d0823..dd4bdc7ede 100644 --- a/usr/src/uts/intel/usbprn/Makefile +++ b/usr/src/uts/intel/usbprn/Makefile @@ -23,6 +23,7 @@ # Copyright 2009 Sun Microsystems, Inc. All rights reserved. # Use is subject to license terms. # +# Copyright 2014 Garrett D'Amore <garrett@damore.org> # # This makefile drives the production of the usbprn driver kernel module. # @@ -105,8 +106,7 @@ TEST = test # # lock_lint rules # -#USBA_FILES = $(USBA_OBJS:%.o=../usba/%.ll) -USBA_FILES = $(USBA_WITHOUT_WUSB_OBJS:%.o=../usba/%.ll) +USBA_FILES = $(USBA_OBJS:%.o=../usba/%.ll) UHCI_FILES = $(UHCI_OBJS:%.o=../uhci/%.ll) OHCI_FILES = $(OHCI_OBJS:%.o=../ohci/%.ll) EHCI_FILES = $(EHCI_OBJS:%.o=../ehci/%.ll) diff --git a/usr/src/uts/intel/usbskel/Makefile b/usr/src/uts/intel/usbskel/Makefile index 57efcd878d..f020121884 100644 --- a/usr/src/uts/intel/usbskel/Makefile +++ b/usr/src/uts/intel/usbskel/Makefile @@ -23,6 +23,7 @@ # Copyright 2009 Sun Microsystems, Inc. All rights reserved. # Use is subject to license terms. # +# Copyright 2014 Garrett D'Amore <garrett@damore.org> # # This makefile drives the production of the usbskel driver kernel module. # @@ -106,7 +107,7 @@ TEST = test # # lock_lint rules # -USBA_FILES = $(USBA_WITHOUT_WUSB_OBJS:%.o=../usba/%.ll) +USBA_FILES = $(USBA_OBJS:%.o=../usba/%.ll) UHCI_FILES = $(UHCI_OBJS:%.o=../uhci/%.ll) OHCI_FILES = $(OHCI_OBJS:%.o=../ohci/%.ll) EHCI_FILES = $(EHCI_OBJS:%.o=../ehci/%.ll) diff --git a/usr/src/uts/intel/usbsksp/Makefile b/usr/src/uts/intel/usbsksp/Makefile index 9ac78dc7e0..9fce0550b4 100644 --- a/usr/src/uts/intel/usbsksp/Makefile +++ b/usr/src/uts/intel/usbsksp/Makefile @@ -23,6 +23,8 @@ # Copyright 2009 Sun Microsystems, Inc. All rights reserved. # Use is subject to license terms. # +# Copyright 2014 Garrett D'Amore <garrett@damore.org> +# # uts/intel/usbsksp/Makefile # @@ -99,7 +101,7 @@ TEST = test WARLOCK_CMD = $(WLCMD_DIR)/usbser_keyspan.wlcmd USBSER_FILES = $(USBSER_OBJS:%.o=../usbser/%.ll) -USBA_FILES = $(USBA_WITHOUT_WUSB_OBJS:%.o=../usba/%.ll) +USBA_FILES = $(USBA_OBJS:%.o=../usba/%.ll) UHCI_FILES = $(UHCI_OBJS:%.o=../uhci/%.ll) OHCI_FILES = $(OHCI_OBJS:%.o=../ohci/%.ll) EHCI_FILES = $(EHCI_OBJS:%.o=../ehci/%.ll) diff --git a/usr/src/uts/intel/usbsprl/Makefile b/usr/src/uts/intel/usbsprl/Makefile index 3b76265082..3a896a7a4e 100644 --- a/usr/src/uts/intel/usbsprl/Makefile +++ b/usr/src/uts/intel/usbsprl/Makefile @@ -23,6 +23,7 @@ # Copyright 2009 Sun Microsystems, Inc. All rights reserved. # Use is subject to license terms. # +# Copyright 2014 Garrett D'Amore <garrett@damore.org> # # This makefile drives the production of the Prolific USB Serial # Adapter driver. @@ -96,7 +97,7 @@ TEST = test # WARLOCK_CMD = $(WLCMD_DIR)/$(MODULE).wlcmd USBSER_FILES = $(USBSER_OBJS:%.o=../usbser/%.ll) -USBA_FILES = $(USBA_WITHOUT_WUSB_OBJS:%.o=../usba/%.ll) +USBA_FILES = $(USBA_OBJS:%.o=../usba/%.ll) UHCI_FILES = $(UHCI_OBJS:%.o=../uhci/%.ll) OHCI_FILES = $(OHCI_OBJS:%.o=../ohci/%.ll) EHCI_FILES = $(EHCI_OBJS:%.o=../ehci/%.ll) diff --git a/usr/src/uts/intel/usbvc/Makefile b/usr/src/uts/intel/usbvc/Makefile index 66c96b9a5c..a447b0f875 100644 --- a/usr/src/uts/intel/usbvc/Makefile +++ b/usr/src/uts/intel/usbvc/Makefile @@ -23,6 +23,8 @@ # Copyright 2009 Sun Microsystems, Inc. All rights reserved. # Use is subject to license terms. # +# Copyright 2014 Garrett D'Amore <garrett@damore.org> +# # # This makefile drives the production of the usbvc driver kernel module. @@ -114,7 +116,7 @@ TEST = test # # lock_lint rules # -USBA_FILES = $(USBA_WITHOUT_WUSB_OBJS:%.o=../usba/%.ll) +USBA_FILES = $(USBA_OBJS:%.o=../usba/%.ll) UHCI_FILES = $(UHCI_OBJS:%.o=../uhci/%.ll) OHCI_FILES = $(OHCI_OBJS:%.o=../ohci/%.ll) EHCI_FILES = $(EHCI_OBJS:%.o=../ehci/%.ll) diff --git a/usr/src/uts/intel/uwba/Makefile b/usr/src/uts/intel/uwba/Makefile deleted file mode 100644 index 20fe0f1775..0000000000 --- a/usr/src/uts/intel/uwba/Makefile +++ /dev/null @@ -1,119 +0,0 @@ -# -# 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 -# or http://www.opensolaris.org/os/licensing. -# 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 -# -# -# uts/intel/uwba/Makefile -# Copyright 2009 Sun Microsystems, Inc. All rights reserved. -# Use is subject to license terms. -# -# -# This makefile drives the production of the uwba kernel module. -# - -# -# Path to the base of the uts directory tree (usually /usr/src/uts). -# -UTSBASE = ../.. - -# -# Define the module and object file sets. -# -MODULE = uwba -OBJECTS = $(UWBA_OBJS:%=$(OBJS_DIR)/%) -LINTS = $(UWBA_OBJS:%.o=$(LINTS_DIR)/%.ln) -ROOTMODULE = $(ROOT_MISC_DIR)/$(MODULE) -WARLOCK_OUT = $(UWBA_OBJS:%.o=%.ll) -WARLOCK_OK = $(MODULE).ok -WLCMD_DIR = $(UTSBASE)/common/io/warlock - -# -# Include common rules. -# -include $(UTSBASE)/intel/Makefile.intel - -# -# Define targets -# -ALL_TARGET = $(BINARY) -LINT_TARGET = $(MODULE).lint -INSTALL_TARGET = $(BINARY) $(ROOTMODULE) - -# -# For now, disable these lint checks; maintainers should endeavor -# to investigate and remove these for maximum lint coverage. -# Please do not carry these forward to new Makefiles. -# -LINTTAGS += -erroff=E_BAD_PTR_CAST_ALIGN -LINTTAGS += -erroff=E_PTRDIFF_OVERFLOW -LINTTAGS += -erroff=E_ASSIGN_NARROW_CONV -LINTTAGS += -erroff=E_STATIC_UNUSED - -CERRWARN += -_gcc=-Wno-unused-label -CERRWARN += -_gcc=-Wno-parentheses - -# -# Default build targets. -# -.KEEP_STATE: - -def: $(DEF_DEPS) - -all: $(ALL_DEPS) - -clean: $(CLEAN_DEPS) - $(RM) $(WARLOCK_OUT) $(WARLOCK_OK) - -clobber: $(CLOBBER_DEPS) - $(RM) $(WARLOCK_OUT) $(WARLOCK_OK) - -lint: $(LINT_DEPS) - -modlintlib: $(MODLINTLIB_DEPS) - -clean.lint: $(CLEAN_LINT_DEPS) - -install: $(INSTALL_DEPS) - -# -# Include common targets. -# -include $(UTSBASE)/intel/Makefile.targ - -# -# Defines for local commands. -# -WLCC = wlcc -TOUCH = touch -WARLOCK = warlock - -# -# Warlock targets -# -warlock: $(WARLOCK_OK) - -$(WARLOCK_OK): $(WARLOCK_OUT) - $(WARLOCK) -c $(WLCMD_DIR)/uwba.wlcmd $(WARLOCK_OUT) \ - -l ../warlock/ddi_dki_impl.ll - $(TOUCH) $@ - -%.ll: $(UTSBASE)/common/io/uwb/uwba/%.c \ - $(UTSBASE)/common/sys/uwb/uwba/uwba.h \ - $(UTSBASE)/common/sys/uwb/uwbai.h - $(WLCC) $(CPPFLAGS) -DDEBUG -o $@ $< diff --git a/usr/src/uts/intel/wusb_ca/Makefile b/usr/src/uts/intel/wusb_ca/Makefile deleted file mode 100644 index 79d71bdf3f..0000000000 --- a/usr/src/uts/intel/wusb_ca/Makefile +++ /dev/null @@ -1,157 +0,0 @@ -# -# 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 -# or http://www.opensolaris.org/os/licensing. -# 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 -# -# -# uts/intel/wusb_ca/Makefile -# Copyright 2009 Sun Microsystems, Inc. All rights reserved. -# Use is subject to license terms. -# -# -# This makefile drives the production of the wusb_ca driver kernel module. -# - -# -# Path to the base of the uts directory tree (usually /usr/src/uts). -# -UTSBASE = ../.. - -# -# Define the module and object file sets. -# -MODULE = wusb_ca -OBJECTS = $(WUSB_CA_OBJS:%=$(OBJS_DIR)/%) -LINTS = $(WUSB_CA_OBJS:%.o=$(LINTS_DIR)/%.ln) -ROOTMODULE = $(ROOT_DRV_DIR)/$(MODULE) -WARLOCK_OUT = $(WUSB_CA_OBJS:%.o=%.ll) -WARLOCK_OK = $(MODULE).ok -WLCMD_DIR = $(UTSBASE)/common/io/warlock - -# -# Include common rules. -# -include $(UTSBASE)/intel/Makefile.intel - -# -# Define targets -# -ALL_TARGET = $(BINARY) -LINT_TARGET = $(MODULE).lint -INSTALL_TARGET = $(BINARY) $(ROOTMODULE) - -# -# Override defaults to build a unique, local modstubs.o. -# -MODSTUBS_DIR = $(OBJS_DIR) -CLEANFILES += $(MODSTUBS_O) - -# -# depends on misc/usba -# -LDFLAGS += -dy -Nmisc/usba - -# -# For now, disable these lint checks; maintainers should endeavor -# to investigate and remove these for maximum lint coverage. -# Please do not carry these forward to new Makefiles. -# -LINTTAGS += -erroff=E_SUPPRESSION_DIRECTIVE_UNUSED -LINTTAGS += -erroff=E_BAD_PTR_CAST_ALIGN -LINTTAGS += -erroff=E_ASSIGN_NARROW_CONV - -# -# Default build targets. -# -.KEEP_STATE: - -def: $(DEF_DEPS) - -all: $(ALL_DEPS) - -clean: $(CLEAN_DEPS) - $(RM) $(WARLOCK_OUT) $(WARLOCK_OK) - -clobber: $(CLOBBER_DEPS) - $(RM) $(WARLOCK_OUT) $(WARLOCK_OK) - -lint: $(LINT_DEPS) - -modlintlib: $(MODLINTLIB_DEPS) - -clean.lint: $(CLEAN_LINT_DEPS) - -install: $(INSTALL_DEPS) - -# -# Include common targets. -# -include $(UTSBASE)/intel/Makefile.targ - -# -# Defines for local commands. -# -WARLOCK = warlock -WLCC = wlcc -TOUCH = touch -SCCS = sccs -TEST = test - -# -# lock_lint rules -# -USBA_FILES = $(USBA_OBJS:%.o= -l ../usba/%.ll) -OHCI_FILES = $(OHCI_OBJS:%.o=../ohci/%.ll) -UHCI_FILES = $(UHCI_OBJS:%.o=../uhci/%.ll) -EHCI_FILES = $(EHCI_OBJS:%.o=../ehci/%.ll) - -warlock: $(WARLOCK_OK) warlock_with_usba - -%.wlcmd: - cd $(WLCMD_DIR); $(TEST) -f $@ || $(SCCS) get $@ - -$(WARLOCK_OK): $(WARLOCK_OUT) wusb_ca.wlcmd warlock_ddi.files - $(WARLOCK) -c $(WLCMD_DIR)/wusb_ca.wlcmd $(WARLOCK_OUT) \ - -l ../warlock/ddi_dki_impl.ll - $(TOUCH) $@ - -%.ll: $(UTSBASE)/common/io/usb/clients/wusb_ca/%.c \ - $(UTSBASE)/common/sys/usb/clients/wusb_ca/wusb_ca_priv.h - $(WLCC) $(CPPFLAGS) -DDEBUG -o $@ $< - -warlock_with_usba: wusb_ca.wlcmd $(WARLOCK_OUT) usba_files \ - warlock_ddi.files - $(WARLOCK) -c $(WLCMD_DIR)/wusb_ca_with_usba.wlcmd \ - $(USBA_FILES) $(WARLOCK_OUT) \ - -l ../warlock/ddi_dki_impl.ll - -usba_files: - @cd ../usba;pwd; $(MAKE) warlock - -ohci_files: - @cd ../ohci;pwd; $(MAKE) warlock - -uhci_files: - @cd ../uhci;pwd; $(MAKE) warlock - -ehci_files: - @cd ../ehci;pwd; $(MAKE) warlock - -warlock_ddi.files: - cd ../warlock; pwd; $(MAKE) warlock - diff --git a/usr/src/uts/intel/wusb_df/Makefile b/usr/src/uts/intel/wusb_df/Makefile deleted file mode 100644 index 0b76177028..0000000000 --- a/usr/src/uts/intel/wusb_df/Makefile +++ /dev/null @@ -1,157 +0,0 @@ -# -# 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 -# or http://www.opensolaris.org/os/licensing. -# 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 -# -# -# uts/intel/wusb_df/Makefile -# Copyright 2009 Sun Microsystems, Inc. All rights reserved. -# Use is subject to license terms. -# -# -# This makefile drives the production of the wusb_df driver kernel module. -# - -# -# Path to the base of the uts directory tree (usually /usr/src/uts). -# -UTSBASE = ../.. - -# -# Define the module and object file sets. -# -MODULE = wusb_df -OBJECTS = $(WUSB_DF_OBJS:%=$(OBJS_DIR)/%) -LINTS = $(WUSB_DF_OBJS:%.o=$(LINTS_DIR)/%.ln) -ROOTMODULE = $(ROOT_DRV_DIR)/$(MODULE) -WARLOCK_OUT = $(WUSB_DF_OBJS:%.o=%.ll) -WARLOCK_OK = $(MODULE).ok -WLCMD_DIR = $(UTSBASE)/common/io/warlock - -# -# Include common rules. -# -include $(UTSBASE)/intel/Makefile.intel - -# -# Define targets -# -ALL_TARGET = $(BINARY) -LINT_TARGET = $(MODULE).lint -INSTALL_TARGET = $(BINARY) $(ROOTMODULE) - -# -# Override defaults to build a unique, local modstubs.o. -# -MODSTUBS_DIR = $(OBJS_DIR) -CLEANFILES += $(MODSTUBS_O) - -# -# depends on misc/usba -# -LDFLAGS += -dy -Nmisc/usba - -# -# For now, disable these lint checks; maintainers should endeavor -# to investigate and remove these for maximum lint coverage. -# Please do not carry these forward to new Makefiles. -# -LINTTAGS += -erroff=E_PTRDIFF_OVERFLOW - -CERRWARN += -_gcc=-Wno-uninitialized - -# -# Default build targets. -# -.KEEP_STATE: - -def: $(DEF_DEPS) - -all: $(ALL_DEPS) - -clean: $(CLEAN_DEPS) - $(RM) $(WARLOCK_OUT) $(WARLOCK_OK) - -clobber: $(CLOBBER_DEPS) - $(RM) $(WARLOCK_OUT) $(WARLOCK_OK) - -lint: $(LINT_DEPS) - -modlintlib: $(MODLINTLIB_DEPS) - -clean.lint: $(CLEAN_LINT_DEPS) - -install: $(INSTALL_DEPS) - -# -# Include common targets. -# -include $(UTSBASE)/intel/Makefile.targ - -# -# Defines for local commands. -# -WARLOCK = warlock -WLCC = wlcc -TOUCH = touch -SCCS = sccs -TEST = test - -# -# lock_lint rules -# -USBA_FILES = $(USBA_OBJS:%.o= -l ../usba/%.ll) -UHCI_FILES = $(UHCI_OBJS:%.o=../uhci/%.ll) -OHCI_FILES = $(OHCI_OBJS:%.o=../ohci/%.ll) -EHCI_FILES = $(EHCI_OBJS:%.o=../ehci/%.ll) - -warlock: $(WARLOCK_OK) warlock_with_usba - -%.wlcmd: - cd $(WLCMD_DIR); $(TEST) -f $@ || $(SCCS) get $@ - -$(WARLOCK_OK): $(WARLOCK_OUT) wusb_df.wlcmd warlock_ddi.files - $(WARLOCK) -c $(WLCMD_DIR)/wusb_df.wlcmd $(WARLOCK_OUT) \ - -l ../warlock/ddi_dki_impl.ll - $(TOUCH) $@ - -%.ll: $(UTSBASE)/common/io/usb/clients/wusb_df/%.c \ - $(UTSBASE)/common/sys/usb/clients/wusb_df/wusb_df.h - $(WLCC) $(CPPFLAGS) -DDEBUG -DWUSB_DF_PM -DWUSB_DF_CPR -o $@ $< - -warlock_with_usba: wusb_df_with_usba.wlcmd $(WARLOCK_OUT) usba_files \ - warlock_ddi.files - $(WARLOCK) -c $(WLCMD_DIR)/wusb_df_with_usba.wlcmd \ - $(USBA_FILES) $(WARLOCK_OUT) \ - -l ../warlock/ddi_dki_impl.ll - -usba_files: - @cd ../usba;pwd; $(MAKE) warlock - -uhci_files: - @cd ../uhci;pwd; $(MAKE) warlock - -ohci_files: - @cd ../ohci;pwd; $(MAKE) warlock - -ehci_files: - @cd ../ehci;pwd; $(MAKE) warlock - -warlock_ddi.files: - cd ../warlock; pwd; $(MAKE) warlock - diff --git a/usr/src/uts/sparc/Makefile.sparc b/usr/src/uts/sparc/Makefile.sparc index 1a16a109f9..e0913ce81f 100644 --- a/usr/src/uts/sparc/Makefile.sparc +++ b/usr/src/uts/sparc/Makefile.sparc @@ -277,7 +277,6 @@ DRV_KMODS += usb_as usb_ac DRV_KMODS += usbskel DRV_KMODS += usbvc DRV_KMODS += usbftdi -DRV_KMODS += wusb_df hwahc hwarc wusb_ca DRV_KMODS += usbecm DRV_KMODS += hci1394 av1394 scsa1394 dcam1394 DRV_KMODS += sbp2 @@ -418,7 +417,6 @@ MISC_KMODS += qlc_fw_2500 MISC_KMODS += qlc_fw_6322 MISC_KMODS += qlc_fw_8100 MISC_KMODS += spuni -MISC_KMODS += hwa1480_fw uwba MISC_KMODS += mii MISC_KMODS += klmmod klmops diff --git a/usr/src/uts/sparc/hid/Makefile b/usr/src/uts/sparc/hid/Makefile index 5a855d5800..c4295a87ce 100644 --- a/usr/src/uts/sparc/hid/Makefile +++ b/usr/src/uts/sparc/hid/Makefile @@ -24,6 +24,7 @@ # Copyright 2009 Sun Microsystems, Inc. All rights reserved. # Use is subject to license terms. # +# Copyright 2014 Garrett D'Amore <garrett@damore.org> # # This makefile drives the production of the hid kernel driver. # @@ -113,7 +114,7 @@ TEST = test # # lock_lint rules # -USBA_FILES = $(USBA_WITHOUT_WUSB_OBJS:%.o=../usba/%.ll) +USBA_FILES = $(USBA_OBJS:%.o=../usba/%.ll) OHCI_FILES = $(OHCI_OBJS:%.o=../ohci/%.ll) UHCI_FILES = $(UHCI_OBJS:%.o=../uhci/%.ll) EHCI_FILES = $(EHCI_OBJS:%.o=../ehci/%.ll) diff --git a/usr/src/uts/sparc/hwa1480_fw/Makefile b/usr/src/uts/sparc/hwa1480_fw/Makefile deleted file mode 100644 index a23b4ceb2a..0000000000 --- a/usr/src/uts/sparc/hwa1480_fw/Makefile +++ /dev/null @@ -1,133 +0,0 @@ -# -# 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 -# or http://www.opensolaris.org/os/licensing. -# 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 -# -# -# uts/sparc/hwa1480_fw/Makefile -# Copyright 2009 Sun Microsystems, Inc. All rights reserved. -# Use is subject to license terms. -# -# -# This makefile drives the production of the hwa1480_fw driver kernel module. -# sparc architecture dependent -# - -# -# Path to the base of the uts directory tree (usually /usr/src/uts). -# -UTSBASE = ../.. - -# -# Define the module and object file sets. -# -MODULE = hwa1480_fw -OBJECTS = $(WUSB_FWMOD_OBJS:%=$(OBJS_DIR)/%) -LINTS = $(WUSB_FWMOD_OBJS:%.o=$(LINTS_DIR)/%.ln) -ROOTMODULE = $(ROOT_MISC_DIR)/$(MODULE) -WARLOCK_OUT = $(WUSB_FWMOD_OBJS:%.o=%.ll) -WARLOCK_OK = $(MODULE).ok - -FWOBJ = $(OBJS_DIR)/$(MODULE).o -OBJECTS += $(FWOBJ) - -# -# Include common rules. -# -include $(UTSBASE)/sparc/Makefile.sparc - -LDFLAGS = -# -# Define targets -# -ALL_TARGET = $(BINARY) -LINT_TARGET = $(MODULE).lint -INSTALL_TARGET = $(BINARY) $(ROOTMODULE) - -# -# For now, disable these lint checks; maintainers should endeavor -# to investigate and remove these for maximum lint coverage. -# Please do not carry these forward to new Makefiles. -# -LINTTAGS += -erroff=E_BAD_PTR_CAST_ALIGN -LINTTAGS += -erroff=E_PTRDIFF_OVERFLOW -LINTTAGS += -erroff=E_ASSIGN_NARROW_CONV -LINTTAGS += -erroff=E_STATIC_UNUSED - -# -# Default build targets. -# -.KEEP_STATE: - -def: $(DEF_DEPS) - -all: $(ALL_DEPS) - -clean: $(CLEAN_DEPS) - $(RM) $(WARLOCK_OUT) $(WARLOCK_OK) - -clobber: $(CLOBBER_DEPS) - $(RM) $(WARLOCK_OUT) $(WARLOCK_OK) - -lint: $(LINT_DEPS) - -modlintlib: $(MODLINTLIB_DEPS) - -clean.lint: $(CLEAN_LINT_DEPS) - -install: $(INSTALL_DEPS) - - -# -# Include common targets. -# -include $(UTSBASE)/sparc/Makefile.targ - - -# customized section for transforming firmware binary -ELFWRAP = elfwrap -BINSRC = $(UTSBASE)/common/io/usb/clients/hwa1480_fw/i1480 -ORIGIN_SRC = i1480-usb-0.0.bin - -# get build type, 32/64 -WRAPTYPE = $(CLASS:%=-%) - -# set elfwrap option -WRAPOPT = $(WRAPTYPE:-32=) - -$(FWOBJ): - cp $(BINSRC)/$(ORIGIN_SRC) $(BINSRC)/$(MODULE) - $(ELFWRAP) $(WRAPOPT) -o $@ $(BINSRC)/$(MODULE) - -# -# Defines for local commands. -# -WLCC = wlcc -TOUCH = touch -WARLOCK = warlock - -# -# Warlock targets -# -warlock: $(WARLOCK_OK) - -$(WARLOCK_OK): $(WARLOCK_OUT) - $(TOUCH) $@ - -%.ll: $(UTSBASE)/common/io/usb/clients/wusb_fwmod/%.c - $(WLCC) $(CPPFLAGS) -DDEBUG -o $@ $< diff --git a/usr/src/uts/sparc/hwahc/Makefile b/usr/src/uts/sparc/hwahc/Makefile deleted file mode 100644 index d6f810d2a4..0000000000 --- a/usr/src/uts/sparc/hwahc/Makefile +++ /dev/null @@ -1,144 +0,0 @@ -# -# 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 -# or http://www.opensolaris.org/os/licensing. -# 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 -# -# -# uts/sparc/hwahc/Makefile -# Copyright 2009 Sun Microsystems, Inc. All rights reserved. -# Use is subject to license terms. -# -# -# This makefile drives the production of the hwahc driver kernel module. -# sparc architecture dependent -# - -# -# Path to the base of the uts directory tree (usually /usr/src/uts). -# -UTSBASE = ../.. - -# -# Define the module and object file sets. -# -MODULE = hwahc -OBJECTS = $(HWAHC_OBJS:%=$(OBJS_DIR)/%) -LINTS = $(HWAHC_OBJS:%.o=$(LINTS_DIR)/%.ln) -ROOTMODULE = $(ROOT_DRV_DIR)/$(MODULE) -WARLOCK_OUT = $(HWAHC_OBJS:%.o=%.ll) -WARLOCK_OK = $(MODULE).ok -WLCMD_DIR = $(UTSBASE)/common/io/warlock - -# -# Include common rules. -# -include $(UTSBASE)/sparc/Makefile.sparc - -# -# lint pass one enforcement -# -CFLAGS += $(CCVERBOSE) -CERRWARN += -_gcc=-Wno-uninitialized -CERRWARN += -_gcc=-Wno-switch - -# -# depends on misc/usba -# -LDFLAGS += -dy -Nmisc/usba -Nmisc/uwba - -# -# Define targets -# -ALL_TARGET = $(BINARY) -LINT_TARGET = $(MODULE).lint -INSTALL_TARGET = $(BINARY) $(ROOTMODULE) - -.KEEP_STATE: - -def: $(DEF_DEPS) - -all: $(ALL_DEPS) - -clean: $(CLEAN_DEPS) - $(RM) $(WARLOCK_OUT) $(WARLOCK_OK) - -clobber: $(CLOBBER_DEPS) - $(RM) $(WARLOCK_OUT) $(WARLOCK_OK) - -lint: $(LINT_DEPS) - -modlintlib: $(MODLINTLIB_DEPS) - -clean.lint: $(CLEAN_LINT_DEPS) - -install: $(INSTALL_DEPS) - -# -# Include common targets. -# -include $(UTSBASE)/sparc/Makefile.targ - -# -# Defines for local commands. -# -WARLOCK = warlock -WLCC = wlcc -TOUCH = touch -SCCS = sccs -TEST = test - -# -# Warlock targets -# -USBA_FILES = $(USBA_OBJS:%.o=../usba/%.ll) -UHCI_FILES = $(UHCI_OBJS:%.o=../uhci/%.ll) -OHCI_FILES = $(OHCI_OBJS:%.o=../ohci/%.ll) -EHCI_FILES = $(EHCI_OBJS:%.o=../ehci/%.ll) - -warlock: $(WARLOCK_OK) warlock_with_usba - -$(WARLOCK_OK): $(WARLOCK_OUT) $(WLCMD_DIR)/hwahc.wlcmd warlock_ddi.files - $(WARLOCK) -c $(WLCMD_DIR)/hwahc.wlcmd $(WARLOCK_OUT) \ - -l ../warlock/ddi_dki_impl.ll - $(TOUCH) $@ - -%.ll: $(UTSBASE)/common/io/usb/hwa/hwahc/%.c \ - $(UTSBASE)/common/sys/usb/hwa/hwahc/hwahc.h \ - $(UTSBASE)/common/sys/usb/hwa/hwahc/hwahc_util.h - $(WLCC) $(CPPFLAGS) -DDEBUG -o $@ $< - -warlock_with_usba: $(WLCMD_DIR)/hwahc_with_usba.wlcmd $(WARLOCK_OUT) usba_files \ - ohci_files ehci_files uhci_files warlock_ddi.files - $(WARLOCK) -c $(WLCMD_DIR)/hwahc_with_usba.wlcmd \ - $(USBA_FILES) $(OHCI_FILES) $(EHCI_FILES) $(UHCI_FILES) \ - $(WARLOCK_OUT) -l ../warlock/ddi_dki_impl.ll - -usba_files: - @cd ../usba; pwd; $(MAKE) warlock - -uhci_files: - @cd ../uhci; pwd; $(MAKE) warlock - -ohci_files: - @cd ../ohci; pwd; $(MAKE) warlock - -ehci_files: - @cd ../ehci; pwd; $(MAKE) warlock - -warlock_ddi.files: - @cd ../warlock; pwd; $(MAKE) warlock diff --git a/usr/src/uts/sparc/hwarc/Makefile b/usr/src/uts/sparc/hwarc/Makefile deleted file mode 100644 index 2e72c6f2b5..0000000000 --- a/usr/src/uts/sparc/hwarc/Makefile +++ /dev/null @@ -1,156 +0,0 @@ -# -# 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 -# or http://www.opensolaris.org/os/licensing. -# 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 -# -# -# uts/sparc/hwarc/Makefile -# Copyright 2009 Sun Microsystems, Inc. All rights reserved. -# Use is subject to license terms. -# -# -# This makefile drives the production of the hwarc driver kernel module. -# sparc architecture dependent -# - -# -# Path to the base of the uts directory tree (usually /usr/src/uts). -# -UTSBASE = ../.. - -# -# Define the module and object file sets. -# -MODULE = hwarc -OBJECTS = $(HWA_RC_OBJS:%=$(OBJS_DIR)/%) -LINTS = $(HWA_RC_OBJS:%.o=$(LINTS_DIR)/%.ln) -ROOTMODULE = $(ROOT_DRV_DIR)/$(MODULE) -WARLOCK_OUT = $(HWA_RC_OBJS:%.o=%.ll) -WARLOCK_OK = $(MODULE).ok -WLCMD_DIR = $(UTSBASE)/common/io/warlock - -# -# Include common rules. -# -include $(UTSBASE)/sparc/Makefile.sparc - -# -# lint pass one enforcement -# -CFLAGS += $(CCVERBOSE) - - -# -# depends on misc/usba -# -LDFLAGS += -dy -Nmisc/usba -Nmisc/uwba - - -# -# Define targets -# -ALL_TARGET = $(BINARY) -LINT_TARGET = $(MODULE).lint -INSTALL_TARGET = $(BINARY) $(ROOTMODULE) - - -# -# For now, disable these lint checks; maintainers should endeavor -# to investigate and remove these for maximum lint coverage. -# Please do not carry these forward to new Makefiles. -# -LINTTAGS += -erroff=E_PTRDIFF_OVERFLOW - -# -# Default build targets. -# -.KEEP_STATE: - -def: $(DEF_DEPS) - -all: $(ALL_DEPS) - -clean: $(CLEAN_DEPS) - $(RM) $(WARLOCK_OUT) $(WARLOCK_OK) - -clobber: $(CLOBBER_DEPS) - $(RM) $(WARLOCK_OUT) $(WARLOCK_OK) - -lint: $(LINT_DEPS) - -modlintlib: $(MODLINTLIB_DEPS) - -clean.lint: $(CLEAN_LINT_DEPS) - -install: $(INSTALL_DEPS) - -# -# Include common targets. -# -include $(UTSBASE)/sparc/Makefile.targ - -# -# Defines for local commands. -# -WARLOCK = warlock -WLCC = wlcc -TOUCH = touch -SCCS = sccs -TEST = test - -# -# lock_lint rules -# -USBA_FILES = $(USBA_OBJS:%.o=../usba/%.ll) -UHCI_FILES = $(UHCI_OBJS:%.o=../uhci/%.ll) -OHCI_FILES = $(OHCI_OBJS:%.o=../ohci/%.ll) -EHCI_FILES = $(EHCI_OBJS:%.o=../ehci/%.ll) - -warlock: $(WARLOCK_OK) warlock_with_usba - -$(WARLOCK_OK): $(WARLOCK_OUT) $(WLCMD_DIR)/hwarc.wlcmd warlock_ddi.files - $(WARLOCK) -c $(WLCMD_DIR)/hwarc.wlcmd $(WARLOCK_OUT) \ - -l ../warlock/ddi_dki_impl.ll - $(TOUCH) $@ - -%.ll: $(UTSBASE)/common/io/usb/clients/hwarc/%.c \ - $(UTSBASE)/common/sys/usb/clients/hwarc/hwarc.h - $(WLCC) $(CPPFLAGS) -DDEBUG -o $@ $< - -warlock_with_usba: $(WLCMD_DIR)/hwarc_with_usba.wlcmd $(WARLOCK_OUT) usba_files \ - ohci_files ehci_files uhci_files warlock_ddi.files - $(WARLOCK) -c $(WLCMD_DIR)/hwarc_with_usba.wlcmd \ - $(USBA_FILES) $(OHCI_FILES) $(EHCI_FILES) $(UHCI_FILES) \ - $(WARLOCK_OUT) \ - -l ../warlock/ddi_dki_impl.ll - -usba_files: - @cd ../usba; pwd; $(MAKE) warlock - -uhci_files: - @cd ../uhci; pwd; $(MAKE) warlock - -ohci_files: - @cd ../ohci; pwd; $(MAKE) warlock - -ehci_files: - @cd ../ehci; pwd; $(MAKE) warlock - -warlock_ddi.files: - @cd ../warlock; pwd; $(MAKE) warlock - diff --git a/usr/src/uts/sparc/scsa2usb/Makefile b/usr/src/uts/sparc/scsa2usb/Makefile index a939a5042b..3886f470ef 100644 --- a/usr/src/uts/sparc/scsa2usb/Makefile +++ b/usr/src/uts/sparc/scsa2usb/Makefile @@ -22,6 +22,8 @@ # Copyright 2009 Sun Microsystems, Inc. All rights reserved. # Use is subject to license terms. # +# Copyright 2014 Garrett D'Amore <garrett@damore.org> +# # uts/sparc/scsa2usb/Makefile # # This makefile drives the production of the scsa2usb driver @@ -113,7 +115,7 @@ TEST = test # # lock_lint rules # -USBA_FILES = $(USBA_WITHOUT_WUSB_OBJS:%.o=../usba/%.ll) +USBA_FILES = $(USBA_OBJS:%.o=../usba/%.ll) UHCI_FILES = $(UHCI_OBJS:%.o=../uhci/%.ll) OHCI_FILES = $(OHCI_OBJS:%.o=../ohci/%.ll) EHCI_FILES = $(EHCI_OBJS:%.o=../ehci/%.ll) diff --git a/usr/src/uts/sparc/ugen/Makefile b/usr/src/uts/sparc/ugen/Makefile index cd88eac467..f8988fea49 100644 --- a/usr/src/uts/sparc/ugen/Makefile +++ b/usr/src/uts/sparc/ugen/Makefile @@ -24,6 +24,7 @@ # Copyright 2009 Sun Microsystems, Inc. All rights reserved. # Use is subject to license terms. # +# Copyright 2014 Garrett D'Amore <garrett@damore.org> # # This makefile drives the production of the ugen kernel driver. # @@ -105,7 +106,7 @@ TEST = test # # lock_lint rules # -USBA_FILES = $(USBA_WITHOUT_WUSB_OBJS:%.o=../usba/%.ll) +USBA_FILES = $(USBA_OBJS:%.o=../usba/%.ll) UHCI_FILES = $(UHCI_OBJS:%.o=../uhci/%.ll) OHCI_FILES = $(OHCI_OBJS:%.o=../ohci/%.ll) EHCI_FILES = $(EHCI_OBJS:%.o=../ehci/%.ll) diff --git a/usr/src/uts/sparc/usb_ac/Makefile b/usr/src/uts/sparc/usb_ac/Makefile index e1088a3ace..3aee852b0e 100644 --- a/usr/src/uts/sparc/usb_ac/Makefile +++ b/usr/src/uts/sparc/usb_ac/Makefile @@ -22,6 +22,8 @@ # Copyright 2009 Sun Microsystems, Inc. All rights reserved. # Use is subject to license terms. # +# Copyright 2014 Garrett D'Amore <garrett@damore.org> +# # uts/sparc/usb_ac/Makefile # # This makefile drives the production of the usb_ac driver @@ -112,7 +114,7 @@ TEST = test # # lock_lint rules # -USBA_FILES = $(USBA_WITHOUT_WUSB_OBJS:%.o=../usba/%.ll) +USBA_FILES = $(USBA_OBJS:%.o=../usba/%.ll) UHCI_FILES = $(UHCI_OBJS:%.o=../uhci/%.ll) OHCI_FILES = $(OHCI_OBJS:%.o=../ohci/%.ll) EHCI_FILES = $(EHCI_OBJS:%.o=../ehci/%.ll) diff --git a/usr/src/uts/sparc/usb_as/Makefile b/usr/src/uts/sparc/usb_as/Makefile index 870534bd2c..4261e3a0ea 100644 --- a/usr/src/uts/sparc/usb_as/Makefile +++ b/usr/src/uts/sparc/usb_as/Makefile @@ -22,6 +22,8 @@ # Copyright 2009 Sun Microsystems, Inc. All rights reserved. # Use is subject to license terms. # +# Copyright 2014 Garrett D'Amore <garrett@damore.org> +# # uts/sparc/usb_as/Makefile # # This makefile drives the production of the usb_audio driver @@ -110,7 +112,7 @@ TEST = test # # lock_lint rules # -USBA_FILES = $(USBA_WITHOUT_WUSB_OBJS:%.o=../usba/%.ll) +USBA_FILES = $(USBA_OBJS:%.o=../usba/%.ll) UHCI_FILES = $(UHCI_OBJS:%.o=../uhci/%.ll) OHCI_FILES = $(OHCI_OBJS:%.o=../ohci/%.ll) EHCI_FILES = $(EHCI_OBJS:%.o=../ehci/%.ll) diff --git a/usr/src/uts/sparc/usb_ia/Makefile b/usr/src/uts/sparc/usb_ia/Makefile index 71356e1d4f..2d39cf236d 100644 --- a/usr/src/uts/sparc/usb_ia/Makefile +++ b/usr/src/uts/sparc/usb_ia/Makefile @@ -24,6 +24,8 @@ # Copyright 2009 Sun Microsystems, Inc. All rights reserved. # Use is subject to license terms. # +# Copyright 2014 Garrett D'Amore <garrett@damore.org> +# # This makefile drives the production of the usb_ia driver kernel module. # sparc architecture dependent # @@ -103,7 +105,7 @@ TEST = test # # lock_lint rules # -USBA_FILES = $(USBA_WITHOUT_WUSB_OBJS:%.o=../usba/%.ll) +USBA_FILES = $(USBA_OBJS:%.o=../usba/%.ll) UHCI_FILES = $(UHCI_OBJS:%.o=../uhci/%.ll) OHCI_FILES = $(OHCI_OBJS:%.o=../ohci/%.ll) EHCI_FILES = $(EHCI_OBJS:%.o=../ehci/%.ll) diff --git a/usr/src/uts/sparc/usb_mid/Makefile b/usr/src/uts/sparc/usb_mid/Makefile index 61ea14e1b3..954e558785 100644 --- a/usr/src/uts/sparc/usb_mid/Makefile +++ b/usr/src/uts/sparc/usb_mid/Makefile @@ -24,6 +24,8 @@ # Copyright 2009 Sun Microsystems, Inc. All rights reserved. # Use is subject to license terms. # +# Copyright 2014 Garrett D'Amore <garrett@damore.org> +# # This makefile drives the production of the usb_mid driver kernel module. # sparc architecture dependent # @@ -103,7 +105,7 @@ TEST = test # # lock_lint rules # -USBA_FILES = $(USBA_WITHOUT_WUSB_OBJS:%.o=../usba/%.ll) +USBA_FILES = $(USBA_OBJS:%.o=../usba/%.ll) UHCI_FILES = $(UHCI_OBJS:%.o=../uhci/%.ll) OHCI_FILES = $(OHCI_OBJS:%.o=../ohci/%.ll) EHCI_FILES = $(EHCI_OBJS:%.o=../ehci/%.ll) diff --git a/usr/src/uts/sparc/usbecm/Makefile b/usr/src/uts/sparc/usbecm/Makefile index e5c1f61dec..4762360a0a 100644 --- a/usr/src/uts/sparc/usbecm/Makefile +++ b/usr/src/uts/sparc/usbecm/Makefile @@ -23,6 +23,7 @@ # Copyright 2010 Sun Microsystems, Inc. All rights reserved. # Use is subject to license terms. # +# Copyright 2014 Garrett D'Amore <garrett@damore.org> # # This makefile drives the production of Abstract Control Model of # USB Communication Devices Class dirver. @@ -99,7 +100,6 @@ TEST = test # WARLOCK_CMD = $(WLCMD_DIR)/$(MODULE).wlcmd -USBA_FILES = $(USBA_WITHOUT_WUSB_OBJS:%.o=../usba/%.ll) UHCI_FILES = $(UHCI_OBJS:%.o=../uhci/%.ll) OHCI_FILES = $(OHCI_OBJS:%.o=../ohci/%.ll) EHCI_FILES = $(EHCI_OBJS:%.o=../ehci/%.ll) diff --git a/usr/src/uts/sparc/usbftdi/Makefile b/usr/src/uts/sparc/usbftdi/Makefile index b120699874..54b0fcc5b9 100644 --- a/usr/src/uts/sparc/usbftdi/Makefile +++ b/usr/src/uts/sparc/usbftdi/Makefile @@ -23,6 +23,7 @@ # Copyright 2009 Sun Microsystems, Inc. All rights reserved. # Use is subject to license terms. # +# Copyright 2014 Garrett D'Amore <garrett@damore.org> # # This makefile drives the production of the FT232R USB Serial # Adapter driver. @@ -97,7 +98,7 @@ TEST = test # WARLOCK_CMD = $(WLCMD_DIR)/$(MODULE).wlcmd USBSER_FILES = $(USBSER_OBJS:%.o=../usbser/%.ll) -USBA_FILES = $(USBA_WITHOUT_WUSB_OBJS:%.o=../usba/%.ll) +USBA_FILES = $(USBA_OBJS:%.o=../usba/%.ll) UHCI_FILES = $(UHCI_OBJS:%.o=../uhci/%.ll) OHCI_FILES = $(OHCI_OBJS:%.o=../ohci/%.ll) EHCI_FILES = $(EHCI_OBJS:%.o=../ehci/%.ll) diff --git a/usr/src/uts/sparc/usbprn/Makefile b/usr/src/uts/sparc/usbprn/Makefile index 64011303d3..0fa8ce7e0c 100644 --- a/usr/src/uts/sparc/usbprn/Makefile +++ b/usr/src/uts/sparc/usbprn/Makefile @@ -22,6 +22,7 @@ # Copyright 2009 Sun Microsystems, Inc. All rights reserved. # Use is subject to license terms. # +# Copyright 2014 Garrett D'Amore <garrett@damore.org> # # This makefile drives the production of the usbprn kernel driver. # @@ -101,7 +102,7 @@ TEST = test # # lock_lint rules # -USBA_FILES = $(USBA_WITHOUT_WUSB_OBJS:%.o=../usba/%.ll) +USBA_FILES = $(USBA_OBJS:%.o=../usba/%.ll) UHCI_FILES = $(UHCI_OBJS:%.o=../uhci/%.ll) OHCI_FILES = $(OHCI_OBJS:%.o=../ohci/%.ll) EHCI_FILES = $(EHCI_OBJS:%.o=../ehci/%.ll) diff --git a/usr/src/uts/sparc/usbskel/Makefile b/usr/src/uts/sparc/usbskel/Makefile index f2b6289f9a..664cf2fa17 100644 --- a/usr/src/uts/sparc/usbskel/Makefile +++ b/usr/src/uts/sparc/usbskel/Makefile @@ -24,6 +24,7 @@ # Copyright 2009 Sun Microsystems, Inc. All rights reserved. # Use is subject to license terms. # +# Copyright 2014 Garrett D'Amore <garrett@damore.org> # # This makefile drives the production of the usbskel kernel driver. # @@ -105,7 +106,7 @@ TEST = test # # lock_lint rules # -USBA_FILES = $(USBA_WITHOUT_WUSB_OBJS:%.o=../usba/%.ll) +USBA_FILES = $(USBA_OBJS:%.o=../usba/%.ll) UHCI_FILES = $(UHCI_OBJS:%.o=../uhci/%.ll) OHCI_FILES = $(OHCI_OBJS:%.o=../ohci/%.ll) EHCI_FILES = $(EHCI_OBJS:%.o=../ehci/%.ll) diff --git a/usr/src/uts/sparc/usbsksp/Makefile b/usr/src/uts/sparc/usbsksp/Makefile index cc0932b37d..28c036c0bc 100644 --- a/usr/src/uts/sparc/usbsksp/Makefile +++ b/usr/src/uts/sparc/usbsksp/Makefile @@ -19,10 +19,11 @@ # CDDL HEADER END # # -# # Copyright 2009 Sun Microsystems, Inc. All rights reserved. # Use is subject to license terms. # +# Copyright 2014 Garrett D'Amore <garrett@damore.org> +# # uts/sparc/usbsksp/Makefile @@ -104,7 +105,7 @@ TEST = test # WARLOCK_CMD = $(WLCMD_DIR)/usbser_keyspan.wlcmd USBSER_FILES = $(USBSER_OBJS:%.o=../usbser/%.ll) -USBA_FILES = $(USBA_WITHOUT_WUSB_OBJS:%.o=../usba/%.ll) +USBA_FILES = $(USBA_OBJS:%.o=../usba/%.ll) UHCI_FILES = $(UHCI_OBJS:%.o=../uhci/%.ll) OHCI_FILES = $(OHCI_OBJS:%.o=../ohci/%.ll) EHCI_FILES = $(EHCI_OBJS:%.o=../ehci/%.ll) diff --git a/usr/src/uts/sparc/usbsprl/Makefile b/usr/src/uts/sparc/usbsprl/Makefile index 6d15b200dd..e359afcab0 100644 --- a/usr/src/uts/sparc/usbsprl/Makefile +++ b/usr/src/uts/sparc/usbsprl/Makefile @@ -24,6 +24,7 @@ # Copyright 2009 Sun Microsystems, Inc. All rights reserved. # Use is subject to license terms. # +# Copyright 2014 Garrett D'Amore <garrett@damore.org> # # This makefile drives the production of the Prolific USB Serial # Adapter driver. @@ -102,7 +103,7 @@ TEST = test # WARLOCK_CMD = $(WLCMD_DIR)/$(MODULE).wlcmd USBSER_FILES = $(USBSER_OBJS:%.o=../usbser/%.ll) -USBA_FILES = $(USBA_WITHOUT_WUSB_OBJS:%.o=../usba/%.ll) +USBA_FILES = $(USBA_OBJS:%.o=../usba/%.ll) UHCI_FILES = $(UHCI_OBJS:%.o=../uhci/%.ll) OHCI_FILES = $(OHCI_OBJS:%.o=../ohci/%.ll) EHCI_FILES = $(EHCI_OBJS:%.o=../ehci/%.ll) diff --git a/usr/src/uts/sparc/usbvc/Makefile b/usr/src/uts/sparc/usbvc/Makefile index dc6a2bade5..42f280d785 100644 --- a/usr/src/uts/sparc/usbvc/Makefile +++ b/usr/src/uts/sparc/usbvc/Makefile @@ -23,6 +23,8 @@ # Copyright 2009 Sun Microsystems, Inc. All rights reserved. # Use is subject to license terms. # +# Copyright 2014 Garrett D'Amore <garrett@damore.org> +# # # uts/sparc/usbvc/Makefile @@ -112,7 +114,7 @@ TEST = test # # lock_lint rules # -USBA_FILES = $(USBA_WITHOUT_WUSB_OBJS:%.o=../usba/%.ll) +USBA_FILES = $(USBA_OBJS:%.o=../usba/%.ll) UHCI_FILES = $(UHCI_OBJS:%.o=../uhci/%.ll) OHCI_FILES = $(OHCI_OBJS:%.o=../ohci/%.ll) EHCI_FILES = $(EHCI_OBJS:%.o=../ehci/%.ll) diff --git a/usr/src/uts/sparc/uwba/Makefile b/usr/src/uts/sparc/uwba/Makefile deleted file mode 100644 index 46b7434db3..0000000000 --- a/usr/src/uts/sparc/uwba/Makefile +++ /dev/null @@ -1,120 +0,0 @@ -# -# 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 -# or http://www.opensolaris.org/os/licensing. -# 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 -# -# -# uts/sparc/uwba/Makefile -# Copyright 2009 Sun Microsystems, Inc. All rights reserved. -# Use is subject to license terms. -# -# -# This makefile drives the production of the uwba kernel module. -# sparc architecture dependent -# - -# -# Path to the base of the uts directory tree (usually /usr/src/uts). -# -UTSBASE = ../.. - -# -# Define the module and object file sets. -# -MODULE = uwba -OBJECTS = $(UWBA_OBJS:%=$(OBJS_DIR)/%) -LINTS = $(UWBA_OBJS:%.o=$(LINTS_DIR)/%.ln) -ROOTMODULE = $(ROOT_MISC_DIR)/$(MODULE) -WARLOCK_OUT = $(UWBA_OBJS:%.o=%.ll) -WARLOCK_OK = $(MODULE).ok - -# -# Include common rules. -# -include $(UTSBASE)/sparc/Makefile.sparc - -# -# lint pass one enforcement -# -CFLAGS += $(CCVERBOSE) - -# -# Define targets -# -ALL_TARGET = $(BINARY) -LINT_TARGET = $(MODULE).lint -INSTALL_TARGET = $(BINARY) $(ROOTMODULE) - -# -# For now, disable these lint checks; maintainers should endeavor -# to investigate and remove these for maximum lint coverage. -# Please do not carry these forward to new Makefiles. -# -LINTTAGS += -erroff=E_BAD_PTR_CAST_ALIGN -LINTTAGS += -erroff=E_PTRDIFF_OVERFLOW -LINTTAGS += -erroff=E_ASSIGN_NARROW_CONV -LINTTAGS += -erroff=E_STATIC_UNUSED - -CERRWARN += -_gcc=-Wno-unused-label -CERRWARN += -_gcc=-Wno-parentheses - -# -# Default build targets. -# -.KEEP_STATE: - -def: $(DEF_DEPS) - -all: $(ALL_DEPS) - -clean: $(CLEAN_DEPS) - $(RM) $(WARLOCK_OUT) $(WARLOCK_OK) - -clobber: $(CLOBBER_DEPS) - $(RM) $(WARLOCK_OUT) $(WARLOCK_OK) - -lint: $(LINT_DEPS) - -modlintlib: $(MODLINTLIB_DEPS) - -clean.lint: $(CLEAN_LINT_DEPS) - -install: $(INSTALL_DEPS) - -# -# Include common targets. -# -include $(UTSBASE)/sparc/Makefile.targ - -# -# Defines for local commands. -# -WLCC = wlcc -TOUCH = touch -WARLOCK = warlock - -# -# Warlock targets -# -warlock: $(WARLOCK_OK) - -$(WARLOCK_OK): $(WARLOCK_OUT) - $(TOUCH) $@ - -%.ll: $(UTSBASE)/common/io/uwb/uwba/%.c - $(WLCC) $(CPPFLAGS) -DDEBUG -o $@ $< diff --git a/usr/src/uts/sparc/wusb_ca/Makefile b/usr/src/uts/sparc/wusb_ca/Makefile deleted file mode 100644 index 2222a94dc4..0000000000 --- a/usr/src/uts/sparc/wusb_ca/Makefile +++ /dev/null @@ -1,156 +0,0 @@ -# -# 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 -# or http://www.opensolaris.org/os/licensing. -# 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 -# -# -# uts/sparc/wusb_ca/Makefile - -# Copyright 2009 Sun Microsystems, Inc. All rights reserved. -# Use is subject to license terms. -# -# -#This makefile drives the production of the wusb_ca kernel driver. -# -#sparc architecture dependent -# - -# -# Path to the base of the uts directory tree (usually /usr/src/uts). -# -UTSBASE = ../.. - -# -# Define the module and object file sets. -# -MODULE = wusb_ca -OBJECTS = $(WUSB_CA_OBJS:%=$(OBJS_DIR)/%) -LINTS = $(WUSB_CA_OBJS:%.o=$(LINTS_DIR)/%.ln) -ROOTMODULE = $(ROOT_DRV_DIR)/$(MODULE) -WARLOCK_OUT = $(WUSB_CA_OBJS:%.o=%.ll) -WARLOCK_OK = $(MODULE).ok -WLCMD_DIR = $(UTSBASE)/common/io/warlock - -# -# Include common rules. -# -include $(UTSBASE)/sparc/Makefile.sparc - -# -# lint pass one enforcement -# -CFLAGS += $(CCVERBOSE) - -# -# depends on misc/usba -# -LDFLAGS += -dy -Nmisc/usba - -# -# Define targets -# -ALL_TARGET = $(BINARY) -LINT_TARGET = $(MODULE).lint -INSTALL_TARGET = $(BINARY) $(ROOTMODULE) - -# -# For now, disable these lint checks; maintainers should endeavor -# to investigate and remove these for maximum lint coverage. -# Please do not carry these forward to new Makefiles. -# -LINTTAGS += -erroff=E_BAD_PTR_CAST_ALIGN -LINTTAGS += -erroff=E_PTRDIFF_OVERFLOW -LINTTAGS += -erroff=E_ASSIGN_NARROW_CONV -LINTTAGS += -erroff=E_SUPPRESSION_DIRECTIVE_UNUSED - -.KEEP_STATE: - -all: $(ALL_DEPS) - -def: $(DEF_DEPS) - -clean: $(CLEAN_DEPS) - $(RM) $(WARLOCK_OUT) $(WARLOCK_OK) - -clobber: $(CLOBBER_DEPS) - $(RM) $(WARLOCK_OUT) $(WARLOCK_OK) - -lint: $(LINT_DEPS) - -modlintlib: $(MODLINTLIB_DEPS) - -clean.lint: $(CLEAN_LINT_DEPS) - -install: $(INSTALL_DEPS) - -# -# Include common targets. -# -include $(UTSBASE)/sparc/Makefile.targ - -# -# Defines for local commands. -# -WARLOCK = warlock -WLCC = wlcc -TOUCH = touch -TEST = test - -# -# lock_lint rules -# -USBA_FILES = $(USBA_OBJS:%.o= -l ../usba/%.ll) -OHCI_FILES = $(OHCI_OBJS:%.o=../ohci/%.ll) -UHCI_FILES = $(UHCI_OBJS:%.o=../uhci/%.ll) -EHCI_FILES = $(EHCI_OBJS:%.o=../ehci/%.ll) - -warlock: $(WARLOCK_OK) warlock_with_usba - -%.wlcmd: - cd $(WLCMD_DIR); $(TEST) -f $@ || $(SCCS) get $@ - -$(WARLOCK_OK): $(WARLOCK_OUT) wusb_ca.wlcmd warlock_ddi.files - $(WARLOCK) -c $(WLCMD_DIR)/wusb_ca.wlcmd $(WARLOCK_OUT) \ - -l ../warlock/ddi_dki_impl.ll - $(TOUCH) $@ - -%.ll: $(UTSBASE)/common/io/usb/clients/wusb_ca/%.c \ - $(UTSBASE)/common/sys/usb/clients/wusb_ca/wusb_ca_priv.h - $(WLCC) $(CPPFLAGS) -DDEBUG -o $@ $< - -warlock_with_usba: wusb_ca.wlcmd $(WARLOCK_OUT) usba_files \ - warlock_ddi.files - $(WARLOCK) -c $(WLCMD_DIR)/wusb_ca_with_usba.wlcmd \ - $(USBA_FILES) $(WARLOCK_OUT) \ - -l ../warlock/ddi_dki_impl.ll - -usba_files: - @cd ../usba;pwd; $(MAKE) warlock - -ohci_files: - @cd ../ohci;pwd; $(MAKE) warlock - -uhci_files: - @cd ../uhci;pwd; $(MAKE) warlock - -ehci_files: - @cd ../ehci;pwd; $(MAKE) warlock - -warlock_ddi.files: - cd ../warlock; pwd; $(MAKE) warlock - diff --git a/usr/src/uts/sparc/wusb_df/Makefile b/usr/src/uts/sparc/wusb_df/Makefile deleted file mode 100644 index da4c27e4aa..0000000000 --- a/usr/src/uts/sparc/wusb_df/Makefile +++ /dev/null @@ -1,158 +0,0 @@ -# -# 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 -# or http://www.opensolaris.org/os/licensing. -# 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 -# -# -# uts/sparc/wusb_df/Makefile -# Copyright 2009 Sun Microsystems, Inc. All rights reserved. -# Use is subject to license terms. -# -# -# This makefile drives the production of the wusb_df driver kernel module. -# sparc architecture dependent -# - -# -# Path to the base of the uts directory tree (usually /usr/src/uts). -# -UTSBASE = ../.. - -# -# Define the module and object file sets. -# -MODULE = wusb_df -OBJECTS = $(WUSB_DF_OBJS:%=$(OBJS_DIR)/%) -LINTS = $(WUSB_DF_OBJS:%.o=$(LINTS_DIR)/%.ln) -ROOTMODULE = $(ROOT_DRV_DIR)/$(MODULE) -WARLOCK_OUT = $(WUSB_DF_OBJS:%.o=%.ll) -WARLOCK_OK = $(MODULE).ok -WLCMD_DIR = $(UTSBASE)/common/io/warlock - -# -# Include common rules. -# -include $(UTSBASE)/sparc/Makefile.sparc - -# -# lint pass one enforcement -# -CFLAGS += $(CCVERBOSE) - -# -# depends on misc/usba -# -LDFLAGS += -dy -Nmisc/usba - -# -# Define targets -# -ALL_TARGET = $(BINARY) -LINT_TARGET = $(MODULE).lint -INSTALL_TARGET = $(BINARY) $(ROOTMODULE) - - -# -# For now, disable these lint checks; maintainers should endeavor -# to investigate and remove these for maximum lint coverage. -# Please do not carry these forward to new Makefiles. -# -LINTTAGS += -erroff=E_PTRDIFF_OVERFLOW - -CERRWARN += -_gcc=-Wno-uninitialized - -# -# Default build targets. -# -.KEEP_STATE: - -def: $(DEF_DEPS) - -all: $(ALL_DEPS) - -clean: $(CLEAN_DEPS) - $(RM) $(WARLOCK_OUT) $(WARLOCK_OK) - -clobber: $(CLOBBER_DEPS) - $(RM) $(WARLOCK_OUT) $(WARLOCK_OK) - -lint: $(LINT_DEPS) - -modlintlib: $(MODLINTLIB_DEPS) - -clean.lint: $(CLEAN_LINT_DEPS) - -install: $(INSTALL_DEPS) - -# -# Include common targets. -# -include $(UTSBASE)/sparc/Makefile.targ - -# -# Defines for local commands. -# -WARLOCK = warlock -WLCC = wlcc -TOUCH = touch -SCCS = sccs -TEST = test - -# -# lock_lint rules -# -USBA_FILES = $(USBA_OBJS:%.o= -l ../usba/%.ll) -UHCI_FILES = $(UHCI_OBJS:%.o=../uhci/%.ll) -OHCI_FILES = $(OHCI_OBJS:%.o=../ohci/%.ll) -EHCI_FILES = $(EHCI_OBJS:%.o=../ehci/%.ll) - -warlock: $(WARLOCK_OK) warlock_with_usba - -%.wlcmd: - cd $(WLCMD_DIR); $(TEST) -f $@ || $(SCCS) get $@ - -$(WARLOCK_OK): $(WARLOCK_OUT) wusb_df.wlcmd warlock_ddi.files - $(WARLOCK) -c $(WLCMD_DIR)/wusb_df.wlcmd $(WARLOCK_OUT) \ - -l ../warlock/ddi_dki_impl.ll - $(TOUCH) $@ - -%.ll: $(UTSBASE)/common/io/usb/clients/wusb_df/%.c \ - $(UTSBASE)/common/sys/usb/clients/wusb_df/wusb_df.h - $(WLCC) $(CPPFLAGS) -DDEBUG -DWUSB_DF_PM -DWUSB_DF_CPR -o $@ $< - -warlock_with_usba: wusb_df_with_usba.wlcmd $(WARLOCK_OUT) usba_files \ - warlock_ddi.files - $(WARLOCK) -c $(WLCMD_DIR)/wusb_df_with_usba.wlcmd \ - $(USBA_FILES) $(WARLOCK_OUT) \ - -l ../warlock/ddi_dki_impl.ll - -usba_files: - @cd ../usba; pwd; $(MAKE) warlock - -uhci_files: - @cd ../uhci; pwd; $(MAKE) warlock - -ohci_files: - @cd ../ohci; pwd; $(MAKE) warlock - -ehci_files: - @cd ../ehci; pwd; $(MAKE) warlock - -warlock_ddi.files: - @cd ../warlock; pwd; $(MAKE) warlock - |