components/libusb/ugen/src/libusbugen.c
author Mike Sullivan <Mike.Sullivan@Oracle.COM>
Wed, 29 Aug 2012 11:05:56 -0700
changeset 957 255465c5756f
parent 229 1fd565334dfc
permissions -rw-r--r--
Close of build 04.
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
229
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
     1
/*
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
     2
 * CDDL HEADER START
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
     3
 *
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
     4
 * The contents of this file are subject to the terms of the
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
     5
 * Common Development and Distribution License (the "License").
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
     6
 * You may not use this file except in compliance with the License.
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
     7
 *
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
     8
 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
     9
 * or http://www.opensolaris.org/os/licensing.
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
    10
 * See the License for the specific language governing permissions
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
    11
 * and limitations under the License.
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
    12
 *
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
    13
 * When distributing Covered Code, include this CDDL HEADER in each
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
    14
 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
    15
 * If applicable, add the following below this CDDL HEADER, with the
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
    16
 * fields enclosed by brackets "[]" replaced with your own identifying
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
    17
 * information: Portions Copyright [yyyy] [name of copyright owner]
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
    18
 *
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
    19
 * CDDL HEADER END
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
    20
 */
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
    21
/*
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
    22
 * Copyright (c) 2004, 2011, Oracle and/or its affiliates. All rights reserved.
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
    23
 */
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
    24
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
    25
/*
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
    26
 * This library can either be used stand-alone or as plugin
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
    27
 * to the libusb wrapper library.
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
    28
 * The libusb API 0.1.0.10 has been implemented using all original code
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
    29
 * which was not derived from opensource.
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
    30
 *
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
    31
 * XXX issues:
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
    32
 *	- timeout thru signal
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
    33
 *	- usb_interrupt/bulk_write/read should have common code
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
    34
 */
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
    35
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
    36
#include <stdlib.h>
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
    37
#include <stdio.h>
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
    38
#include <errno.h>
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
    39
#include <unistd.h>
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
    40
#include <string.h>
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
    41
#include <fcntl.h>
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
    42
#include <sys/time.h>
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
    43
#include <dirent.h>
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
    44
#include <stdarg.h>
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
    45
#include <strings.h>
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
    46
#include <sys/stat.h>
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
    47
#include <regex.h>
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
    48
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
    49
#include <sys/usb/clients/ugen/usb_ugen.h>
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
    50
#include "usb.h"
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
    51
#include "libusbugen_impl.h"
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
    52
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
    53
/* global variables */
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
    54
usb_bus_t *usb_busses = NULL;
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
    55
const char *libusb_version = "1.1";
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
    56
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
    57
/* error handling */
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
    58
static	char usb_error_string[1024];
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
    59
static	int usb_error_errno;
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
    60
static	usb_error_type_t usb_error_type = USB_ERROR_TYPE_NONE;
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
    61
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
    62
/* debugging */
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
    63
static	int libusb_debug = DEBUG_NONE;
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
    64
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
    65
/* api binding */
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
    66
static	int libusb_api = API_RELAXED;
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
    67
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
    68
/* internal function prototypes */
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
    69
static	void usb_error_str(int x, char *format, ...);
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
    70
static	int usb_error(int x);
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
    71
static	void usb_dprintf(int level, char *format, ...);
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
    72
static	void usb_dump_data(char *data, int size);
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
    73
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
    74
static	int usb_open_ep0(usb_dev_handle_impl_t *hdl);
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
    75
static	void usb_close_ep0(usb_dev_handle_impl_t *hdl);
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
    76
static	int usb_check_access(usb_dev_handle *dev);
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
    77
static	int usb_search_dev_usb(usb_device_t **new_devices);
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
    78
static	int usb_do_io(int fd, int stat_fd, char *data, size_t size, int flag);
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
    79
static	int usb_send_msg(int fd, int stat_fd, int requesttype, int request,
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
    80
	int value, int index, char *data, int size);
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
    81
static	int usb_check_device_and_status_open(usb_dev_handle *dev,
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
    82
	int ep, int ep_type, int mode);
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
    83
static	int usb_get_status(int fd);
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
    84
static	void usb_set_ep_iface_alts(usb_dev_handle_impl_t *hdl,
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
    85
	usb_dev_handle_info_t *info, int index, int interface, int alternate);
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
    86
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
    87
static	int usb_setup_all_configs(usb_dev_handle_impl_t *hdl);
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
    88
static	void usb_free_all_configs(usb_device_t *device);
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
    89
static	int usb_parse_config(usb_dev_handle_impl_t *hdl, uint_t index);
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
    90
static	void usb_free_config(usb_device_t *device, uint_t index);
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
    91
static	int usb_parse_interface(usb_dev_handle_impl_t *hdl, uint_t index,
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
    92
	uint_t iface, char *cloud);
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
    93
static	void usb_free_interface(usb_device_t *device, uint_t index,
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
    94
	uint_t iface);
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
    95
static	int usb_parse_alternate(usb_dev_handle_impl_t *hdl, uint_t index,
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
    96
	uint_t iface, uint_t alt, char *cloud);
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
    97
static	void usb_free_alternate(usb_device_t *device, uint_t index,
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
    98
	uint_t iface, uint_t alt);
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
    99
static	int usb_parse_endpoint(usb_dev_handle_impl_t *hdl, int index,
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   100
	int iface, int alt, int ep, char *cloud);
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   101
static	void usb_find_extra(uchar_t *buf, size_t buflen,
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   102
	unsigned char **extra, int *extralen);
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   103
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   104
static	void usb_close_all_eps(usb_dev_handle_impl_t *hdl);
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   105
static	void usb_add_device(usb_device_t **list, usb_device_t *dev);
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   106
static	void usb_remove_device(usb_device_t **list, usb_device_t *dev);
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   107
static	int usb_check_device_in_list(usb_device_t *list, usb_device_t *dev);
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   108
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   109
static	void usb_free_dev(usb_device_t *dev);
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   110
static	void usb_free_bus(usb_bus_t *bus);
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   111
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   112
static size_t usb_parse_dev_descr(uchar_t *buf, size_t buflen,
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   113
	struct usb_device_descriptor *ret_descr, size_t	ret_buf_len);
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   114
static size_t usb_parse_cfg_descr(uchar_t *buf, size_t buflen,
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   115
	usb_cfg_descr_t	*ret_descr, size_t ret_buf_len,
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   116
	unsigned char **extra, int *extralen);
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   117
static size_t usb_parse_if_descr(uchar_t *buf, size_t buflen,
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   118
	uint_t if_number, uint_t alt_if_setting,
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   119
	usb_if_descr_t *ret_descr, size_t ret_buf_len,
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   120
	unsigned char **extra, int *extralen);
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   121
static size_t usb_parse_ep_descr(uchar_t *buf, size_t buflen,
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   122
	uint_t if_number, uint_t alt_if_setting, uint_t ep_index,
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   123
	usb_ep_descr_t *ret_descr, size_t ret_buf_len,
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   124
	unsigned char **extra, int *extralen);
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   125
static uchar_t usb_ep_index(uint8_t ep_addr);
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   126
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   127
/*
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   128
 * libusb_init:
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   129
 *
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   130
 * Returns: 0 or ENOSUP if we cannot support any bus
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   131
 */
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   132
int
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   133
libusb_init(void)
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   134
{
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   135
	return (0);
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   136
}
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   137
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   138
/*
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   139
 * libusb_fini:
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   140
 *
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   141
 * Returns: always returns 0
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   142
 */
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   143
int
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   144
libusb_fini(void)
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   145
{
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   146
	return (0);
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   147
}
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   148
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   149
/*
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   150
 * Entry points:
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   151
 *
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   152
 * usb_set_debug:
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   153
 *	sets debug level for tracing
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   154
 */
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   155
void
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   156
usb_set_debug(int level)
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   157
{
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   158
	if (getenv("SUN_LIBUSBUGEN_DEBUG")) {
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   159
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   160
		level =	atoi(getenv("SUN_LIBUSBUGEN_DEBUG"));
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   161
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   162
	} else if (getenv("SUN_LIBUSB_DEBUG")) {
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   163
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   164
		level = atoi(getenv("SUN_LIBUSB_DEBUG"));
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   165
	}
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   166
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   167
	if (level < 0)
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   168
		return;
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   169
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   170
	libusb_debug = level;
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   171
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   172
	usb_dprintf(DEBUG_FUNCTIONS, "usb_set_debug(): "
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   173
	    "Setting debugging level to %d (%s)\n",
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   174
	    level, level ? "on" : "off");
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   175
}
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   176
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   177
/*
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   178
 * usb_init:
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   179
 *	not much to initialize. just set debug level
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   180
 */
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   181
void
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   182
usb_init(void)
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   183
{
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   184
	if (getenv("LIBUSB_API_STRICT")) {
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   185
		libusb_api = API_STRICT;
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   186
	}
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   187
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   188
	usb_set_debug(libusb_debug);
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   189
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   190
	usb_dprintf(DEBUG_FUNCTIONS, "usb_init(): "
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   191
	    "libusb version=%s\n", libusb_version);
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   192
}
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   193
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   194
/*
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   195
 * usb_get_busses:
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   196
 * Returns: usb_busses pointer
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   197
 */
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   198
usb_bus_t *
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   199
usb_get_busses(void)
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   200
{
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   201
	return (usb_busses);
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   202
}
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   203
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   204
/*
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   205
 * usb_find_busses:
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   206
 *	finds all busses in the system. On solaris we have
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   207
 *	only one flat name space, /dev/usb
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   208
 *
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   209
 * Returns: change in number of busses or negative errno
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   210
 */
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   211
int
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   212
usb_find_busses(void)
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   213
{
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   214
	usb_bus_t *bus;
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   215
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   216
	/* we only have one name space for all USB busses */
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   217
	if (usb_busses == NULL) {
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   218
		/* never freed */
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   219
		if ((bus = calloc(sizeof (*bus), 1)) == NULL) {
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   220
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   221
			return (usb_error(ENOMEM));
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   222
		}
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   223
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   224
		(void) strncpy(bus->dirname, "/dev/usb",
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   225
		    sizeof (bus->dirname));
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   226
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   227
		usb_dprintf(DEBUG_FUNCTIONS, "usb_find_busses(): "
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   228
		    "found %s\n", bus->dirname);
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   229
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   230
		usb_busses = bus;
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   231
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   232
		return (1);
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   233
	}
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   234
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   235
	return (0);
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   236
}
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   237
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   238
/*
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   239
 * usb_find_devices:
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   240
 *	finds all devices that have appeared and removes devices
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   241
 *	from the list that are no longer there
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   242
 *
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   243
 * Returns: change in number of devices or a negative errno
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   244
 */
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   245
int
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   246
usb_find_devices(void)
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   247
{
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   248
	int i, rval, found;
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   249
	int changes = 0;
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   250
	usb_device_t *new_devices;
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   251
	usb_device_t *dev, *next_dev, *new, *next_new;
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   252
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   253
	new_devices = NULL;
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   254
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   255
	rval = usb_search_dev_usb(&new_devices);
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   256
	if (rval != 0) {
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   257
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   258
		return (usb_error(rval));
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   259
	}
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   260
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   261
	/* is any of devices on the new list also on the old list? */
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   262
	for (dev = usb_busses->devices; dev != NULL; dev = next_dev) {
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   263
		next_dev = dev->next;
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   264
		found = 0;
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   265
		for (new = new_devices; new != NULL; new = next_new) {
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   266
			next_new = new->next;
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   267
			if (strncmp(dev->filename, new->filename,
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   268
			    sizeof (dev->filename)) == 0) {
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   269
				usb_remove_device(&new_devices, new);
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   270
				usb_free_dev(new);
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   271
				found++;
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   272
				break;
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   273
			}
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   274
		}
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   275
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   276
		/* the device must have been hot removed */
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   277
		if (!found) {
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   278
			usb_remove_device(&usb_busses->devices, dev);
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   279
			usb_free_dev(dev);
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   280
		}
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   281
	}
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   282
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   283
	/* add all new_devices to the old_devices list */
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   284
	usb_dprintf(DEBUG_DETAILED, "moving new to old\n");
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   285
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   286
	for (new = new_devices; new != NULL; new = next_new) {
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   287
		next_new = new->next;
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   288
		usb_remove_device(&new_devices, new);
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   289
		usb_add_device(&usb_busses->devices, new);
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   290
		(void) usb_close(usb_open(new));
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   291
		changes++;
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   292
	}
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   293
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   294
	usb_dprintf(DEBUG_DETAILED, "usb_devices list:\n");
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   295
	for (i = 0, dev = usb_busses->devices; dev != NULL;
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   296
	    i++, dev = next_dev) {
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   297
		next_dev = dev->next;
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   298
		usb_dprintf(DEBUG_DETAILED, "%d: %s\n", i, dev->filename);
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   299
	}
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   300
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   301
	return (changes);
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   302
}
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   303
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   304
/*
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   305
 * usb_device:
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   306
 *	 included because sane uses this
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   307
 * Returns: usb_device structure associated with handle
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   308
 */
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   309
struct usb_device *
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   310
usb_device(usb_dev_handle *dev)
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   311
{
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   312
	usb_dev_handle_impl_t *hdl = (usb_dev_handle_impl_t *)dev;
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   313
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   314
	return ((hdl != NULL) ? hdl->device : NULL);
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   315
}
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   316
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   317
/*
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   318
 * usb_open:
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   319
 *	opens the device for access
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   320
 *
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   321
 * Returns: a usb device handle or NULL
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   322
 */
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   323
usb_dev_handle *
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   324
usb_open(usb_device_t *dev)
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   325
{
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   326
	usb_dev_handle_impl_t	*hdl;
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   327
	usb_dev_handle_info_t	*info;
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   328
	int			i, rval;
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   329
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   330
	usb_dprintf(DEBUG_FUNCTIONS, "usb_open():\n");
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   331
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   332
	if (usb_check_device_in_list(usb_busses->devices,
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   333
	    dev) == 0) {
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   334
		usb_dprintf(DEBUG_ERRORS, "usb_open(): "
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   335
		    "illegal usb_device pointer\n");
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   336
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   337
		return (NULL);
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   338
	}
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   339
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   340
	/* create a handle and info structure */
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   341
	if ((hdl = calloc(sizeof (*hdl), 1)) == NULL) {
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   342
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   343
		return (NULL);
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   344
	}
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   345
	hdl->device = dev;
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   346
	if ((info = calloc(sizeof (*info), 1)) == NULL) {
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   347
		free(hdl);
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   348
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   349
		return (NULL);
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   350
	}
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   351
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   352
	hdl->info = info;
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   353
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   354
	/* set all file descriptors to "closed" */
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   355
	for (i = 0; i < USB_MAXENDPOINTS; i++) {
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   356
		hdl->info->ep_fd[i] = -1;
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   357
		hdl->info->ep_status_fd[i] = -1;
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   358
		if (i > 0) {
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   359
			hdl->info->ep_interface[i] = -1;
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   360
		}
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   361
	}
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   362
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   363
	/* open default control ep and keep it open */
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   364
	if ((rval = usb_open_ep0(hdl)) != 0) {
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   365
		usb_dprintf(DEBUG_ERRORS, "usb_open_ep0 failed: %d\n", rval);
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   366
		free(info);
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   367
		free(hdl);
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   368
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   369
		return (NULL);
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   370
	}
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   371
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   372
	/*
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   373
	 * setup config info: trees of configs, interfaces, alternates
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   374
	 * and endpoints structures
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   375
	 */
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   376
	if (usb_setup_all_configs(hdl) != 0) {
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   377
		usb_free_all_configs(hdl->device);
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   378
		usb_close_ep0(hdl);
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   379
		free(info);
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   380
		free(hdl);
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   381
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   382
		return (NULL);
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   383
	}
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   384
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   385
	/* set when the app claims an interface */
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   386
	info->configuration_value =
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   387
	    info->claimed_interface = info->alternate = -1;
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   388
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   389
	usb_dprintf(DEBUG_FUNCTIONS, "usb_open(): hdl=0x%x\n", (int)hdl);
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   390
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   391
	return ((usb_dev_handle *)hdl);
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   392
}
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   393
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   394
/*
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   395
 * usb_close:
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   396
 *	closes the device and free resources
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   397
 *
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   398
 * Returns: 0
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   399
 */
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   400
int
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   401
usb_close(usb_dev_handle *dev)
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   402
{
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   403
	usb_dev_handle_impl_t *hdl = (usb_dev_handle_impl_t *)dev;
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   404
	usb_dev_handle_info_t *info;
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   405
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   406
	usb_dprintf(DEBUG_FUNCTIONS, "usb_close(): hdl=0x%x\n", hdl);
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   407
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   408
	if (hdl) {
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   409
		info = hdl->info;
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   410
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   411
		usb_dprintf(DEBUG_DETAILED,
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   412
		    "usb_close(): claimed %d\n",
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   413
		    info->claimed_interface);
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   414
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   415
		if (info->claimed_interface != -1) {
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   416
			(void) usb_release_interface(dev,
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   417
			    info->claimed_interface);
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   418
		}
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   419
		usb_close_all_eps(hdl);
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   420
		usb_close_ep0(hdl);
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   421
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   422
		free(info);
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   423
		free(hdl);
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   424
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   425
		return (0);
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   426
	}
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   427
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   428
	return (usb_error(EINVAL));
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   429
}
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   430
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   431
/*
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   432
 * usb_control_msg:
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   433
 *	sends a control message
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   434
 *
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   435
 * Returns: actual number of data bytes transferred or
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   436
 *	    a negative errno
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   437
 */
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   438
/*ARGSUSED*/
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   439
int
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   440
usb_control_msg(usb_dev_handle *dev, int requesttype, int request,
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   441
    int value, int index, char *data, int size, int timeout)
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   442
{
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   443
	usb_dev_handle_impl_t *hdl = (usb_dev_handle_impl_t *)dev;
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   444
	usb_dev_handle_info_t *info;
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   445
	int additional;
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   446
	int rval;
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   447
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   448
	usb_dprintf(DEBUG_FUNCTIONS, "usb_control_msg():\n");
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   449
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   450
	if ((hdl == NULL) || (size < 0)) {
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   451
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   452
		return (usb_error(EINVAL));
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   453
	}
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   454
	info = hdl->info;
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   455
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   456
	/*
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   457
	 * no need to do validation since ep0 is always open and
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   458
	 * we do not need to claim an interface first
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   459
	 *
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   460
	 * usb_send_msg returns #bytes xferred or negative errno
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   461
	 */
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   462
	rval = usb_send_msg(info->ep_fd[0], info->ep_status_fd[0],
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   463
	    requesttype, request, value, index, data, size);
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   464
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   465
	/* less than setup bytes transferred? */
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   466
	if (rval < 8) {
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   467
		usb_error_str(errno,
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   468
		    "error sending control message: %d", rval);
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   469
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   470
		return ((rval >= 0) ?
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   471
		    usb_error(EIO) : usb_error(-rval));
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   472
	}
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   473
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   474
	rval -= 8; /* substract setup length */
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   475
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   476
	/* for IN requests, now transfer the remaining bytes */
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   477
	if ((size) && (requesttype & USB_DEV_REQ_DEV_TO_HOST)) {
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   478
		additional = usb_do_io(info->ep_fd[0],
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   479
		    info->ep_status_fd[0], data, size, READ);
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   480
	} else {
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   481
		additional = rval;
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   482
	}
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   483
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   484
	usb_dprintf(DEBUG_FUNCTIONS,
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   485
	    "usb_control_msg(): additional 0x%x bytes\n", additional);
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   486
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   487
	return (additional);
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   488
}
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   489
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   490
/*
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   491
 * usb_bulk_write:
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   492
 *	writes to a bulk endpoint
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   493
 *
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   494
 * Returns: actual number of data bytes transferred or negative errno
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   495
 */
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   496
/* ARGSUSED */
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   497
int
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   498
usb_bulk_write(usb_dev_handle *dev, int ep, char *data, int size,
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   499
    int timeout)
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   500
{
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   501
	usb_dev_handle_impl_t *hdl = (usb_dev_handle_impl_t *)dev;
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   502
	usb_dev_handle_info_t *info;
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   503
	int sent, rval;
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   504
	int ep_index = usb_ep_index(ep);
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   505
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   506
	usb_dprintf(DEBUG_FUNCTIONS, "usb_bulk_write(): ep=0x%x\n", ep);
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   507
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   508
	if ((hdl == NULL) || (data == NULL) || (size <= 0)) {
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   509
		usb_dprintf(DEBUG_ERRORS,
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   510
		    "usb_bulk_write(): NULL handle or data\n");
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   511
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   512
		return (usb_error(EINVAL));
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   513
	}
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   514
	info = hdl->info;
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   515
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   516
	/* do some validation first */
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   517
	if ((rval = usb_check_device_and_status_open(dev, ep,
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   518
	    USB_ENDPOINT_TYPE_BULK, O_WRONLY)) != 0) {
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   519
		usb_dprintf(DEBUG_ERRORS,
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   520
		    "usb_check_device_and_status_open() failed\n");
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   521
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   522
		return (usb_error(rval));
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   523
	}
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   524
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   525
	/* now write out the bytes */
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   526
	sent = usb_do_io(info->ep_fd[ep_index], info->ep_status_fd[ep_index],
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   527
	    data, size, WRITE);
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   528
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   529
	return (sent);
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   530
}
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   531
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   532
/*
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   533
 * usb_bulk_read:
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   534
 *	reads from a bulk endpoint
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   535
 *
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   536
 * Returns: actual number of data bytes transferred or negative errno
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   537
 */
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   538
/* ARGSUSED */
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   539
int
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   540
usb_bulk_read(usb_dev_handle *dev, int ep, char *data, int size,
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   541
    int timeout)
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   542
{
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   543
	usb_dev_handle_impl_t *hdl = (usb_dev_handle_impl_t *)dev;
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   544
	usb_dev_handle_info_t *info;
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   545
	int ep_index, received, rval;
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   546
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   547
	ep |= USB_ENDPOINT_IN;
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   548
	ep_index = usb_ep_index(ep);
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   549
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   550
	usb_dprintf(DEBUG_FUNCTIONS, "usb_bulk_read(): ep=0x%x\n", ep);
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   551
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   552
	if ((hdl == NULL) || (data == NULL) || (size <= 0)) {
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   553
		usb_dprintf(DEBUG_ERRORS,
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   554
		    "usb_bulk_read(): NULL handle or data\n");
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   555
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   556
		return (usb_error(EINVAL));
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   557
	}
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   558
	info = hdl->info;
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   559
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   560
	/* do some validation first */
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   561
	if ((rval = usb_check_device_and_status_open(dev, ep,
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   562
	    USB_ENDPOINT_TYPE_BULK, O_RDONLY)) != 0) {
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   563
		usb_dprintf(DEBUG_ERRORS,
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   564
		    "usb_check_device_and_status_open() failed\n");
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   565
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   566
		return (usb_error(rval));
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   567
	}
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   568
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   569
	/* now read in the bytes */
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   570
	received = usb_do_io(info->ep_fd[ep_index],
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   571
	    info->ep_status_fd[ep_index],
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   572
	    data, size, READ);
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   573
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   574
	return (received);
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   575
}
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   576
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   577
/*
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   578
 * usb_interrupt_write:
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   579
 *	writes data to an interrupt endpoint
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   580
 *
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   581
 * Returns: actual number of data bytes transferred or negative errno
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   582
 */
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   583
/* ARGSUSED */
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   584
int
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   585
usb_interrupt_write(usb_dev_handle *dev, int ep, char *data, int size,
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   586
    int timeout)
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   587
{
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   588
	usb_dev_handle_impl_t *hdl = (usb_dev_handle_impl_t *)dev;
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   589
	usb_dev_handle_info_t *info;
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   590
	int sent, rval;
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   591
	int ep_index = usb_ep_index(ep);
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   592
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   593
	usb_dprintf(DEBUG_FUNCTIONS, "usb_interrupt_write(): ep=0x%x\n", ep);
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   594
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   595
	if ((hdl == NULL) || (data == NULL) || (size <= 0)) {
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   596
		usb_dprintf(DEBUG_ERRORS,
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   597
		    "usb_interrupt_write(): NULL handle or data\n");
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   598
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   599
		return (usb_error(EINVAL));
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   600
	}
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   601
	info = hdl->info;
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   602
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   603
	/* do some validation first */
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   604
	if ((rval = usb_check_device_and_status_open(dev, ep,
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   605
	    USB_ENDPOINT_TYPE_INTERRUPT, O_WRONLY)) != 0) {
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   606
		usb_dprintf(DEBUG_ERRORS,
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   607
		    "usb_check_device_and_status_open() failed\n");
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   608
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   609
		return (usb_error(rval));
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   610
	}
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   611
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   612
	/* now transfer the bytes */
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   613
	sent = usb_do_io(info->ep_fd[ep_index],
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   614
	    info->ep_status_fd[ep_index],
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   615
	    data, size, WRITE);
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   616
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   617
	return (sent);
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   618
}
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   619
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   620
/*
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   621
 * usb_interrupt_read:
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   622
 *	reads data from an interrupt endpoint
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   623
 *
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   624
 * Returns: actual number of data bytes transferred or negative errno
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   625
 */
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   626
/* ARGSUSED */
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   627
int
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   628
usb_interrupt_read(usb_dev_handle *dev, int ep, char *data, int size,
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   629
    int timeout)
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   630
{
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   631
	usb_dev_handle_impl_t *hdl = (usb_dev_handle_impl_t *)dev;
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   632
	usb_dev_handle_info_t *info;
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   633
	int ep_index, received, rval;
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   634
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   635
	ep |= USB_ENDPOINT_IN;
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   636
	ep_index = usb_ep_index(ep);
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   637
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   638
	usb_dprintf(DEBUG_FUNCTIONS, "usb_interrrupt_read(): ep=0x%x\n", ep);
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   639
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   640
	if ((hdl == NULL) || (data == NULL) || (size <= 0)) {
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   641
		usb_dprintf(DEBUG_ERRORS,
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   642
		    "usb_interrupt_read(): NULL handle or data\n");
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   643
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   644
		return (usb_error(EINVAL));
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   645
	}
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   646
	info = hdl->info;
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   647
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   648
	/* do some validation first */
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   649
	if ((rval = usb_check_device_and_status_open(dev, ep,
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   650
	    USB_ENDPOINT_TYPE_INTERRUPT, O_RDONLY)) != 0) {
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   651
		usb_dprintf(DEBUG_ERRORS,
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   652
		    "usb_check_device_and_status_open() failed\n");
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   653
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   654
		return (usb_error(rval));
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   655
	}
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   656
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   657
	/* now transfer the bytes */
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   658
	received = usb_do_io(info->ep_fd[ep_index],
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   659
	    info->ep_status_fd[ep_index],
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   660
	    data, size, READ);
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   661
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   662
	/* close the endpoint so we stop polling the endpoint now */
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   663
	(void) close(info->ep_fd[ep_index]);
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   664
	(void) close(info->ep_status_fd[ep_index]);
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   665
	info->ep_fd[ep_index] = -1;
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   666
	info->ep_status_fd[ep_index] = -1;
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   667
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   668
	return (received);
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   669
}
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   670
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   671
/*
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   672
 * usb_get_string:
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   673
 *	gets a raw unicode string
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   674
 *
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   675
 * Returns: number of bytes transferred or negative errno
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   676
 */
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   677
int
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   678
usb_get_string(usb_dev_handle *dev, int index, int langid, char *buf,
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   679
    size_t buflen)
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   680
{
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   681
	/*
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   682
	 * We can't use usb_get_descriptor() because it's lacking the index
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   683
	 * parameter. This will be fixed in libusb 1.0
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   684
	 */
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   685
	usb_dprintf(DEBUG_FUNCTIONS,
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   686
	    "usb_get_string(): index=%d langid=0x%x len=%d\n",
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   687
	    index, langid, buflen);
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   688
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   689
	if ((dev == NULL) || (buf == NULL) || (buflen == 0)) {
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   690
		usb_dprintf(DEBUG_ERRORS,
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   691
		    "usb_get_string(): NULL handle or data\n");
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   692
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   693
		return (usb_error(EINVAL));
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   694
	}
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   695
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   696
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   697
	return (usb_control_msg(dev, USB_DEV_REQ_DEV_TO_HOST,
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   698
	    USB_REQ_GET_DESCRIPTOR, (USB_DT_STRING << 8) + index,
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   699
	    langid, buf, (int)buflen, 1000));
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   700
}
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   701
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   702
/*
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   703
 * usb_get_string_simple:
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   704
 *	gets a cooked ascii string
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   705
 *
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   706
 * Returns:  number of bytes transferred or negative errno
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   707
 */
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   708
int
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   709
usb_get_string_simple(usb_dev_handle *dev, int index, char *buf,
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   710
    size_t buflen)
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   711
{
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   712
	char tbuf[256];
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   713
	int ret, langid, si, di;
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   714
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   715
	usb_dprintf(DEBUG_FUNCTIONS, "usb_get_string_simple(): index=%d\n",
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   716
	    index);
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   717
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   718
	if ((dev == NULL) || (buf == NULL) || (buflen == 0)) {
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   719
		usb_dprintf(DEBUG_ERRORS,
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   720
		    "usb_get_string_simple(): NULL handle or data\n");
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   721
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   722
		return (usb_error(EINVAL));
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   723
	}
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   724
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   725
	(void) memset(buf, 0, buflen);
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   726
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   727
	/*
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   728
	 * Asking for the zero'th index is special - it returns a string
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   729
	 * descriptor that contains all the language IDs supported by the
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   730
	 * device. Typically there aren't many - often only one. The
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   731
	 * language IDs are 16 bit numbers, and they start at the third byte
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   732
	 * in the descriptor. See USB 2.0 specification, section 9.6.7, for
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   733
	 * more information on this.
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   734
	 */
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   735
	ret = usb_get_string(dev, index, 0, tbuf, sizeof (tbuf));
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   736
	usb_dprintf(DEBUG_DETAILED, "usb_get_string() returned %d\n", ret);
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   737
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   738
	if (ret < 4) {
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   739
		langid = 0x409;
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   740
	} else {
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   741
		langid = tbuf[2] | (tbuf[3] << 8);
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   742
	}
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   743
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   744
	usb_dprintf(DEBUG_DETAILED, "using langid=0x%x\n", langid);
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   745
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   746
	ret = usb_get_string(dev, index, langid, tbuf, sizeof (tbuf));
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   747
	if (ret < 0) {
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   748
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   749
		return (ret);
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   750
	}
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   751
	if (tbuf[1] != USB_DT_STRING) {
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   752
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   753
		return (-EIO);
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   754
	}
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   755
	if (tbuf[0] > ret) {
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   756
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   757
		return (-EFBIG);
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   758
	}
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   759
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   760
	for (di = 0, si = 2; si < tbuf[0]; si += 2) {
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   761
		if (di >= ((int)buflen - 1)) {
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   762
			break;
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   763
		}
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   764
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   765
		if (tbuf[si + 1]) {  /* high byte */
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   766
			buf[di++] = '?';
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   767
		} else {
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   768
			buf[di++] = tbuf[si];
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   769
		}
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   770
	}
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   771
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   772
	buf[di] = 0;
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   773
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   774
	return (di);
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   775
}
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   776
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   777
/*
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   778
 * usb_get_descriptor_by_endpoint:
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   779
 * usb_get_descriptor:
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   780
 *	get a descriptor. by_endpoint does not appear to make
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   781
 *	much sense.
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   782
 *
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   783
 * Returns: number of bytes transferred or negative errno
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   784
 */
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   785
int
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   786
usb_get_descriptor_by_endpoint(usb_dev_handle *udev, int ep,
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   787
    uchar_t type, uchar_t index, void *buf, int size)
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   788
{
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   789
	if ((udev == NULL) || (buf == NULL) || (size <= 0)) {
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   790
		usb_dprintf(DEBUG_ERRORS,
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   791
		    "usb_get_descriptor_by_endpoint(): "
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   792
		    "NULL handle or data\n");
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   793
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   794
		return (usb_error(EINVAL));
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   795
	}
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   796
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   797
	(void) memset(buf, 0, size);
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   798
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   799
	return (usb_control_msg(udev,
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   800
	    ep | USB_ENDPOINT_IN, USB_REQ_GET_DESCRIPTOR,
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   801
	    (type << 8) + index, 0, buf, size, 1000));
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   802
}
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   803
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   804
int
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   805
usb_get_descriptor(usb_dev_handle *udev, uchar_t type,
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   806
    uchar_t index, void *buf, int size)
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   807
{
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   808
	if ((udev == NULL) || (buf == NULL) || (size <= 0)) {
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   809
		usb_dprintf(DEBUG_ERRORS,
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   810
		    "usb_get_string_simple(): NULL handle or data\n");
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   811
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   812
		return (usb_error(EINVAL));
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   813
	}
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   814
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   815
	(void) memset(buf, 0, size);
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   816
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   817
	return (usb_control_msg(udev,
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   818
	    USB_ENDPOINT_IN, USB_REQ_GET_DESCRIPTOR,
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   819
	    (type << 8) + index, 0, buf, size, 1000));
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   820
}
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   821
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   822
/*
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   823
 * usb_set_altinterface:
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   824
 *	switches to the alternate interface for the device
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   825
 *	Note that ugen does not really need this. It does implicit
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   826
 *	cfg and alt switches when the endpoint is opened.
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   827
 *
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   828
 * Returns: 0 or negative errno
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   829
 */
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   830
/* ARGSUSED */
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   831
int
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   832
usb_set_altinterface(usb_dev_handle *dev, int alt)
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   833
{
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   834
	usb_dev_handle_impl_t *hdl = (usb_dev_handle_impl_t *)dev;
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   835
	usb_dev_handle_info_t *info;
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   836
	usb_device_specific_t *dev_specific;
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   837
	int index, iface, err;
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   838
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   839
	usb_dprintf(DEBUG_FUNCTIONS, "usb_set_altinterface(): "
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   840
	    "hdl=0x%x alt=%d\n", hdl, alt);
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   841
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   842
	if (hdl == NULL) {
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   843
		usb_dprintf(DEBUG_ERRORS,
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   844
		    "usb_set_altinterface(): NULL handle\n");
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   845
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   846
		return (usb_error(EINVAL));
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   847
	}
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   848
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   849
	info = hdl->info;
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   850
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   851
	if (libusb_api == API_RELAXED) {
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   852
		if (info->claimed_interface == -1) {
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   853
			/*
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   854
			 * usb_claim_interface() should always be called
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   855
			 * prior usb_set_altinterface(), but some apps
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   856
			 * do not do this, hence we call it here assuming
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   857
			 * the default interface.
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   858
			 */
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   859
			if ((err = usb_claim_interface(dev, 0))) {
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   860
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   861
				return (err);
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   862
			}
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   863
		}
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   864
	}
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   865
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   866
	iface = info->claimed_interface;
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   867
	dev_specific = (usb_device_specific_t *)(hdl->device->dev);
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   868
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   869
	usb_dprintf(DEBUG_DETAILED, "claimed=%d, cfgvalue=%d, hdl=0x%x\n",
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   870
	    info->claimed_interface, info->configuration_value,
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   871
	    dev_specific->claimed_interfaces[iface], hdl);
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   872
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   873
	if ((info->claimed_interface == -1) ||
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   874
	    (info->configuration_value == -1) ||
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   875
	    (hdl != dev_specific->claimed_interfaces[iface])) {
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   876
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   877
		return (usb_error(EACCES));
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   878
	}
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   879
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   880
	usb_close_all_eps(hdl);
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   881
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   882
	/* find the conf index */
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   883
	for (index = 0; index < hdl->device->descriptor.bNumConfigurations;
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   884
	    index++) {
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   885
		if (info->configuration_value ==
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   886
		    hdl->device->config[index].bConfigurationValue) {
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   887
			break;
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   888
		}
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   889
	}
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   890
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   891
	usb_dprintf(DEBUG_DETAILED,
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   892
	    "cfg value=%d index=%d, iface=%d, alt=%d #alts=%d\n",
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   893
	    info->configuration_value, index, iface, alt,
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   894
	    hdl->device->config[index].interface[iface].num_altsetting);
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   895
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   896
	if ((alt < 0) || (alt >= hdl->device->
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   897
	    config[index].interface[iface].num_altsetting)) {
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   898
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   899
		return (usb_error(EINVAL));
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   900
	}
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   901
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   902
	info->alternate = alt;
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   903
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   904
	usb_set_ep_iface_alts(hdl, info, index, iface, alt);
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   905
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   906
	return (0);
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   907
}
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   908
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   909
/*
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   910
 * usb_set_configuration:
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   911
 *	sets the configuration for the device.
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   912
 *	ugen implicitly switches configuration and rejects
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   913
 *	set configuration requests
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   914
 *
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   915
 * Returns: 0
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   916
 */
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   917
/* ARGSUSED */
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   918
int
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   919
usb_set_configuration(usb_dev_handle *dev, int configuration)
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   920
{
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   921
	usb_dev_handle_impl_t *hdl = (usb_dev_handle_impl_t *)dev;
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   922
	usb_dev_handle_info_t *info;
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   923
	int index, i;
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   924
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   925
	usb_dprintf(DEBUG_FUNCTIONS,
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   926
	    "usb_set_configuration(): config = %d\n", configuration);
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   927
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   928
	if (hdl == NULL) {
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   929
		usb_dprintf(DEBUG_ERRORS,
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   930
		    "usb_set_configuration(): NULL handle\n");
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   931
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   932
		return (usb_error(EINVAL));
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   933
	}
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   934
	info = hdl->info;
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   935
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   936
	/* find the conf index */
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   937
	for (index = 0; index < hdl->device->descriptor.bNumConfigurations;
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   938
	    index++) {
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   939
		if (configuration ==
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   940
		    hdl->device->config[index].bConfigurationValue) {
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   941
			break;
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   942
		}
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   943
	}
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   944
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   945
	if (index >= hdl->device->descriptor.bNumConfigurations) {
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   946
		usb_dprintf(DEBUG_ERRORS,
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   947
		    "usb_set_configuration(): invalid\n");
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   948
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   949
		return (usb_error(EINVAL));
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   950
	}
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   951
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   952
	usb_close_all_eps(hdl);
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   953
	info->configuration_value = configuration;
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   954
	info->configuration_index = index;
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   955
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   956
	/* reset ep arrays */
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   957
	for (i = 0; i < USB_MAXENDPOINTS; i++) {
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   958
		info->ep_interface[i] = -1;
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   959
	}
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   960
	if (info->claimed_interface != -1) {
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   961
		(void) usb_release_interface(dev, info->claimed_interface);
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   962
	}
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   963
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   964
	return (0);
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   965
}
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   966
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   967
/*
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   968
 * usb_clear_halt:
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   969
 *	clears a halted endpoint
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   970
 *	ugen has auto clearing but we send the request anyways
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   971
 *
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   972
 * Returns: 0 or negative errno
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   973
 */
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   974
/* ARGSUSED */
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   975
int
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   976
usb_clear_halt(usb_dev_handle *dev, unsigned int ep)
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   977
{
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   978
	int rval;
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   979
	int index = usb_ep_index(ep);
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   980
	usb_dev_handle_impl_t *hdl = (usb_dev_handle_impl_t *)dev;
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   981
	usb_dev_handle_info_t *info;
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   982
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   983
	usb_dprintf(DEBUG_FUNCTIONS, "usb_clear_halt(): ep=0x%x\n", ep);
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   984
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   985
	if (dev == NULL) {
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   986
		usb_dprintf(DEBUG_ERRORS,
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   987
		    "usb_clear_halt(): NULL handle\n");
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   988
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   989
		return (usb_error(EINVAL));
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   990
	}
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   991
	info = hdl->info;
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   992
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   993
	usb_dprintf(DEBUG_DETAILED, "index=0x%x, ep_intf=%d\n",
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   994
	    index, info->ep_interface[index]);
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   995
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   996
	if (info->ep_interface[index] == -1) {
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   997
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   998
		return (usb_error(EINVAL));
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
   999
	}
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1000
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1001
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1002
	/* only check for ep > 0 */
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1003
	if (ep && ((rval = usb_check_access(dev) != 0))) {
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1004
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1005
		return (usb_error(rval));
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1006
	}
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1007
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1008
	rval = usb_control_msg(dev,
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1009
	    USB_DEV_REQ_HOST_TO_DEV | USB_RECIP_ENDPOINT,
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1010
	    USB_REQ_CLEAR_FEATURE, 0, ep, NULL, 0, 0);
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1011
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1012
	if (rval < 0) {
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1013
		usb_error_str(errno, "could not clear feature on ep=0x%x", ep);
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1014
	}
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1015
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1016
	return (rval);
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1017
}
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1018
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1019
/*
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1020
 * usb_claim_interface:
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1021
 *	ugen does not have a claim interface concept but all endpoints
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1022
 *	are opened exclusively. This provides some exclusion. However,
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1023
 *	the interrupt IN endpoint is closed after the read
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1024
 *
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1025
 * Returns: 0 or negative errno
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1026
 */
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1027
int
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1028
usb_claim_interface(usb_dev_handle *dev, int interface)
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1029
{
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1030
	usb_dev_handle_impl_t *hdl = (usb_dev_handle_impl_t *)dev;
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1031
	usb_dev_handle_info_t *info;
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1032
	usb_device_specific_t *dev_specific;
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1033
	int index;
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1034
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1035
	if (hdl == NULL) {
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1036
		usb_dprintf(DEBUG_ERRORS,
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1037
		    "usb_claim_interface(): NULL handle\n");
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1038
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1039
		return (usb_error(EINVAL));
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1040
	}
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1041
	info = hdl->info;
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1042
	dev_specific = (usb_device_specific_t *)(hdl->device->dev);
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1043
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1044
	usb_dprintf(DEBUG_FUNCTIONS, "usb_claim_interface(): hdl=0x%x: "
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1045
	    "interface = %d\n", hdl, interface);
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1046
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1047
	if (info->configuration_value == -1) {
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1048
		index = 0;
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1049
	} else {
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1050
		/* find the conf index */
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1051
		for (index = 0;
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1052
		    index < hdl->device->descriptor.bNumConfigurations;
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1053
		    index++) {
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1054
			if (info->configuration_value ==
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1055
			    hdl->device->config[index].bConfigurationValue) {
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1056
				break;
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1057
			}
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1058
		}
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1059
	}
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1060
	info->configuration_value =
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1061
	    hdl->device->config[index].bConfigurationValue;
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1062
	info->configuration_index = index;
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1063
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1064
	usb_dprintf(DEBUG_DETAILED, "configuration_value=%d, index=%d\n",
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1065
	    info->configuration_value, index);
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1066
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1067
	/* is this a valid interface? */
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1068
	if ((interface < 0) || (interface > 255) ||
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1069
	    (interface >= hdl->device->config[index].bNumInterfaces)) {
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1070
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1071
		return (usb_error(EINVAL));
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1072
	}
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1073
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1074
	/* already claimed? */
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1075
	if (dev_specific->claimed_interfaces[interface] == hdl) {
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1076
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1077
		return (0);
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1078
	}
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1079
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1080
	if (info->claimed_interface != -1) {
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1081
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1082
		return (usb_error(EBUSY));
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1083
	}
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1084
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1085
	if (dev_specific->claimed_interfaces[interface] != 0) {
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1086
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1087
		return (usb_error(EBUSY));
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1088
	}
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1089
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1090
	usb_dprintf(DEBUG_DETAILED, "usb_claim_interface(): hdl=0x%x: "
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1091
	    "interface = %d, claimed by this udev=%d, by hdl=0x%x\n",
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1092
	    hdl, interface, info->claimed_interface,
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1093
	    dev_specific->claimed_interfaces[interface]);
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1094
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1095
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1096
	info->claimed_interface = interface;
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1097
	info->alternate = 0;
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1098
	dev_specific->claimed_interfaces[interface] = hdl;
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1099
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1100
	usb_set_ep_iface_alts(hdl, info, index, interface, 0);
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1101
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1102
	return (0);
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1103
}
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1104
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1105
/*
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1106
 * usb_release_interface:
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1107
 *	releases the acquired interface
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1108
 *
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1109
 * Returns: 0 or negative errno
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1110
 */
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1111
/* ARGSUSED */
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1112
int
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1113
usb_release_interface(usb_dev_handle *dev, int interface)
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1114
{
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1115
	usb_dev_handle_impl_t *hdl = (usb_dev_handle_impl_t *)dev;
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1116
	usb_dev_handle_info_t *info;
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1117
	usb_device_specific_t *dev_specific;
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1118
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1119
	if (hdl == NULL) {
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1120
		usb_dprintf(DEBUG_ERRORS,
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1121
		    "usb_release_interface(): NULL handle\n");
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1122
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1123
		return (usb_error(EINVAL));
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1124
	}
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1125
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1126
	info = hdl->info;
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1127
	dev_specific = (usb_device_specific_t *)(hdl->device->dev);
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1128
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1129
	usb_dprintf(DEBUG_FUNCTIONS, "usb_release_interface(): hdl=0x%x: "
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1130
	    "interface = %d\n", hdl, interface);
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1131
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1132
	if ((info->claimed_interface == -1) ||
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1133
	    (info->claimed_interface != interface)) {
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1134
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1135
		return (usb_error(EINVAL));
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1136
	}
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1137
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1138
	usb_dprintf(DEBUG_DETAILED, "usb_release_interface(): hdl=0x%x: "
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1139
	    "interface = %d, claimed by this udev=%d, by hdl=0x%x\n",
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1140
	    hdl, interface, info->claimed_interface,
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1141
	    dev_specific->claimed_interfaces[interface]);
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1142
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1143
	dev_specific->claimed_interfaces[interface] = 0;
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1144
	info->claimed_interface = -1;
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1145
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1146
	return (0);
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1147
}
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1148
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1149
/*
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1150
 * usb_resetep
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1151
 *	resets the endpoint
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1152
 *
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1153
 * Returns: 0 or negative errno
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1154
 */
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1155
int
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1156
usb_resetep(usb_dev_handle *dev, unsigned int ep)
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1157
{
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1158
	usb_dprintf(DEBUG_FUNCTIONS, "usb_resetep(): ep=0x%x\n", ep);
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1159
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1160
	return (usb_clear_halt(dev, ep));
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1161
}
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1162
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1163
/*
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1164
 * usb_reset:
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1165
 *	resets the device
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1166
 * Returns: -ENOTSUP
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1167
 */
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1168
/* ARGSUSED */
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1169
int
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1170
usb_reset(usb_dev_handle * dev)
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1171
{
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1172
	int rval;
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1173
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1174
	usb_dprintf(DEBUG_FUNCTIONS, "usb_reset():\n");
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1175
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1176
	if (dev == NULL) {
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1177
		usb_dprintf(DEBUG_ERRORS,
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1178
		    "usb_reset(): NULL handle\n");
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1179
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1180
		return (usb_error(EINVAL));
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1181
	}
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1182
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1183
	if ((rval = usb_check_access(dev)) != 0) {
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1184
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1185
		return (usb_error(rval));
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1186
	}
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1187
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1188
	return (usb_error(ENOTSUP));
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1189
}
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1190
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1191
/*
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1192
 * Helper functions
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1193
 *
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1194
 * usb_send_msg:
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1195
 *	creates setup data and send it
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1196
 *
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1197
 * Returns: number of bytes transferred or negative errno
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1198
 */
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1199
static int
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1200
usb_send_msg(int fd, int stat_fd, int requesttype, int request, int value,
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1201
    int index, char *data, int size)
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1202
{
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1203
	uint8_t req[8];
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1204
	int rval;
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1205
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1206
	usb_dprintf(DEBUG_DETAILED, "usb_send_msg():\n"
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1207
	    "\trequesttype 0x%x\n"
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1208
	    "\trequest	   0x%x\n"
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1209
	    "\tvalue	   0x%x\n"
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1210
	    "\tindex	   0x%x\n"
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1211
	    "\tsize	   0x%x\n",
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1212
	    requesttype, request, value, index, size);
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1213
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1214
	req[0] = (uint8_t)requesttype;
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1215
	req[1] = (uint8_t)request;
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1216
	req[2] = (uint8_t)value;
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1217
	req[3] = (uint8_t)(value >> 8);
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1218
	req[4] = (uint8_t)index;
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1219
	req[5] = (uint8_t)(index >> 8);
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1220
	req[6] = (uint8_t)size;
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1221
	req[7] = (uint8_t)(size >> 8);
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1222
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1223
	if (requesttype & USB_DEV_REQ_DEV_TO_HOST) {
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1224
		rval = usb_do_io(fd, stat_fd, (char *)&req,
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1225
		    sizeof (req), WRITE);
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1226
	} else {
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1227
		/* append the write data */
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1228
		char *buffer;
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1229
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1230
		if ((buffer = malloc(size + 8)) == NULL) {
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1231
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1232
			return (usb_error(ENOMEM));
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1233
		}
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1234
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1235
		(void) memcpy(buffer, &req, 8);
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1236
		(void) memcpy(&buffer[8], data, size);
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1237
		rval = usb_do_io(fd, stat_fd, buffer,
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1238
		    (uint_t)sizeof (req) + size, WRITE);
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1239
		free(buffer);
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1240
	}
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1241
	usb_dprintf(DEBUG_FUNCTIONS, "usb_send_msg(): rval=%d\n", rval);
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1242
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1243
	return (rval);
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1244
}
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1245
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1246
/*
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1247
 * usb_do_io:
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1248
 *	performs i/o to/from an endpoint and check the
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1249
 *	status of the device if error or short xfer.
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1250
 *
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1251
 * Returns: bytes transferred or negative errno
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1252
 */
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1253
static int
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1254
usb_do_io(int fd, int stat_fd, char *data, size_t size, int flag)
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1255
{
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1256
	int error;
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1257
	ssize_t ret;
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1258
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1259
	usb_dprintf(DEBUG_FUNCTIONS, "usb_do_io(): size=0x%x flag=%d\n",
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1260
	    size, flag);
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1261
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1262
	if (size == 0) {
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1263
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1264
		return (0);
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1265
	}
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1266
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1267
	switch (flag) {
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1268
	case READ:
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1269
		ret = read(fd, data, size);
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1270
		usb_dump_data(data, (int)size);
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1271
		break;
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1272
	case WRITE:
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1273
		usb_dump_data(data, (int)size);
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1274
		ret = write(fd, data, size);
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1275
		break;
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1276
	}
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1277
	if (ret < 0) {
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1278
		int save_errno = errno;
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1279
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1280
		/* usb_get_status will do a read and overwrite errno */
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1281
		error = usb_get_status(stat_fd);
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1282
		usb_error_str(save_errno, "error %d doing io: errno=%d",
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1283
		    error, save_errno);
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1284
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1285
		return (-save_errno);
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1286
	}
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1287
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1288
	usb_dprintf(DEBUG_FUNCTIONS, "usb_do_io(): amount=%d\n", ret);
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1289
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1290
	return ((int)ret);
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1291
}
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1292
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1293
/*
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1294
 * usb_check_access:
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1295
 *	basically checks if the interface has been claimed
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1296
 *
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1297
 * Returns: 0 or EACCES/EINVAL
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1298
 */
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1299
static int
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1300
usb_check_access(usb_dev_handle *dev)
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1301
{
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1302
	usb_dev_handle_impl_t *hdl = (usb_dev_handle_impl_t *)dev;
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1303
	usb_dev_handle_info_t *info = hdl->info;
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1304
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1305
	if (hdl == NULL) {
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1306
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1307
		return (EINVAL);
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1308
	}
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1309
	info = hdl->info;
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1310
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1311
	usb_dprintf(DEBUG_FUNCTIONS, "usb_check_access(): "
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1312
	    "hdl=0x%x conf=%d claimed=%d alternate=%d\n",
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1313
	    (int)hdl, info->configuration_value,
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1314
	    info->claimed_interface, info->alternate);
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1315
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1316
	if ((info->configuration_value == -1) ||
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1317
	    (info->claimed_interface == -1) ||
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1318
	    (info->alternate == -1)) {
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1319
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1320
		return (EACCES);
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1321
	}
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1322
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1323
	return (0);
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1324
}
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1325
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1326
/*
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1327
 * usb_set_ep_iface_alts:
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1328
 *	initialize ep_interface arrays
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1329
 */
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1330
static void
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1331
usb_set_ep_iface_alts(usb_dev_handle_impl_t *hdl, usb_dev_handle_info_t *info,
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1332
    int index, int interface, int alternate)
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1333
{
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1334
	struct usb_interface_descriptor *if_descr;
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1335
	struct usb_endpoint_descriptor *ep_descr;
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1336
	int i;
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1337
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1338
	/* reinitialize endpoint arrays */
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1339
	for (i = 0; i < USB_MAXENDPOINTS; i++) {
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1340
		info->ep_interface[i] = -1;
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1341
	}
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1342
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1343
	/*
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1344
	 * for the current config, this interface and alt,
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1345
	 * which endpoints are available
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1346
	 */
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1347
	if_descr = &hdl->device->config[index].interface[interface].
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1348
	    altsetting[alternate];
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1349
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1350
	usb_dprintf(DEBUG_DETAILED, "cfg%d.%d.%d has %d endpoints\n",
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1351
	    info->configuration_value, interface, alternate,
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1352
	    if_descr->bNumEndpoints);
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1353
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1354
	for (i = 0; i < if_descr->bNumEndpoints; i++)  {
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1355
		ep_descr = &hdl->device->config[index].interface[interface].
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1356
		    altsetting[alternate].endpoint[i];
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1357
		info->ep_interface[usb_ep_index(
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1358
		    ep_descr->bEndpointAddress)] = interface;
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1359
	}
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1360
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1361
	usb_dprintf(DEBUG_DETAILED, "ep_interface:\n");
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1362
	for (i = 0; i < USB_MAXENDPOINTS; i++) {
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1363
		usb_dprintf(DEBUG_DETAILED, "%d ",
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1364
		    info->ep_interface[i]);
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1365
	}
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1366
	usb_dprintf(DEBUG_DETAILED, "\n");
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1367
}
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1368
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1369
/*
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1370
 * usb_check_device_and_status_open:
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1371
 *	Make sure that the endpoint and status device for the endpoint
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1372
 *	can be opened, or have already been opened.
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1373
 *
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1374
 * Returns: errno
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1375
 */
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1376
static int
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1377
usb_check_device_and_status_open(usb_dev_handle *dev, int ep, int ep_type,
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1378
    int mode)
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1379
{
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1380
	usb_dev_handle_impl_t *hdl = (usb_dev_handle_impl_t *)dev;
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1381
	usb_dev_handle_info_t *info = hdl->info;
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1382
	char *filename, *statfilename, cfg_num[16], alt_num[16];
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1383
	int fd, fdstat, index, rval;
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1384
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1385
	index = usb_ep_index(ep);
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1386
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1387
	usb_dprintf(DEBUG_FUNCTIONS,
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1388
	    "usb_check_device_and_status_open(): "
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1389
	    "ep=0x%x mode=%d index=%d\n", ep, mode, index);
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1390
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1391
	if ((rval = usb_check_access(dev)) != 0) {
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1392
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1393
		return (rval);
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1394
	}
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1395
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1396
	if ((index < 0) || (index > 31)) {
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1397
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1398
		return (EINVAL);
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1399
	}
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1400
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1401
	usb_dprintf(DEBUG_DETAILED, "claimed=%d ep_interface=%d\n",
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1402
	    info->claimed_interface, info->ep_interface[index]);
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1403
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1404
	if (info->claimed_interface != info->ep_interface[index]) {
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1405
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1406
		return (EINVAL);
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1407
	}
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1408
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1409
	if ((info->ep_fd[index] > 0) && (info->ep_status_fd[index] > 0)) {
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1410
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1411
		return (0);
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1412
	}
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1413
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1414
	if (ep == 0) {
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1415
		/* should already be open */
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1416
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1417
		return (0);
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1418
	}
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1419
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1420
	if ((filename = malloc(PATH_MAX+1)) == NULL) {
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1421
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1422
		return (ENOMEM);
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1423
	}
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1424
	if ((statfilename = malloc(PATH_MAX+1)) == NULL) {
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1425
		free(filename);
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1426
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1427
		return (ENOMEM);
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1428
	}
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1429
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1430
	usb_dprintf(DEBUG_DETAILED, "cfgvalue=%d\n",
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1431
	    info->configuration_value);
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1432
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1433
	/* create filename */
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1434
	if (info->configuration_index > 0) {
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1435
		(void) snprintf(cfg_num, sizeof (cfg_num), "cfg%d",
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1436
		    info->configuration_value);
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1437
	} else {
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1438
		(void) memset(cfg_num, 0, sizeof (cfg_num));
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1439
	}
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1440
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1441
	if (info->alternate > 0) {
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1442
		(void) snprintf(alt_num, sizeof (alt_num), ".%d",
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1443
		    info->alternate);
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1444
	} else {
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1445
		(void) memset(alt_num, 0, sizeof (alt_num));
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1446
	}
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1447
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1448
	(void) snprintf(filename, PATH_MAX, "%s/%s/%sif%d%s%s%d",
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1449
	    hdl->device->bus->dirname, hdl->device->filename,
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1450
	    cfg_num, info->ep_interface[index],
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1451
	    alt_num, (ep & USB_EP_DIR_MASK) ? "in" :
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1452
	    "out", (ep & USB_EP_NUM_MASK));
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1453
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1454
	usb_dprintf(DEBUG_DETAILED,
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1455
	    "usb_check_device_and_status_open: %s\n", filename);
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1456
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1457
	/*
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1458
	 * for interrupt IN endpoints, we need to enable one xfer
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1459
	 * mode before opening the endpoint
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1460
	 */
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1461
	(void) snprintf(statfilename, PATH_MAX, "%sstat", filename);
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1462
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1463
	if ((ep_type == USB_ENDPOINT_TYPE_INTERRUPT) &&
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1464
	    (ep & USB_ENDPOINT_IN)) {
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1465
		char control = USB_EP_INTR_ONE_XFER;
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1466
		ssize_t count;
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1467
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1468
		/* open the status device node for the ep first RDWR */
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1469
		if ((fdstat = open(statfilename, O_RDWR)) == -1) {
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1470
			usb_error_str(errno, "can't open %s RDWR: %d",
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1471
			    statfilename, errno);
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1472
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1473
			/* might be an older ugen version, try RDONLY */
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1474
			if ((fdstat = open(statfilename,
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1475
			    O_RDONLY)) == -1) {
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1476
				usb_error_str(errno,
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1477
				    "can't open %s RDONLY: %d",
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1478
				    filename, errno);
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1479
				free(filename);
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1480
				free(statfilename);
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1481
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1482
				return (errno);
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1483
			}
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1484
		} else {
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1485
			count = write(fdstat, &control, sizeof (control));
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1486
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1487
			if (count != 1) {
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1488
				/* this should have worked */
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1489
				usb_error_str(errno, "can't write to %s: %d",
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1490
				    filename, errno);
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1491
				free(filename);
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1492
				free(statfilename);
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1493
				(void) close(fdstat);
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1494
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1495
				return (errno);
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1496
			}
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1497
		}
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1498
	} else {
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1499
		if ((fdstat = open(statfilename, O_RDONLY)) == -1) {
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1500
			usb_error_str(errno, "can't open %s: %d",
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1501
			    statfilename, errno);
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1502
			free(filename);
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1503
			free(statfilename);
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1504
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1505
			return (errno);
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1506
		}
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1507
	}
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1508
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1509
	/* open the ep */
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1510
	if ((fd = open(filename, mode)) == -1) {
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1511
		usb_error_str(errno, "can't open %s: %d",
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1512
		    filename, errno);
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1513
		(void) close(fdstat);
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1514
		free(filename);
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1515
		free(statfilename);
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1516
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1517
		return (errno);
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1518
	}
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1519
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1520
	free(filename);
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1521
	free(statfilename);
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1522
	info->ep_fd[index] = fd;
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1523
	info->ep_status_fd[index] = fdstat;
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1524
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1525
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1526
	return (0);
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1527
}
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1528
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1529
/*
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1530
 * usb_ep_index:
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1531
 *	creates an index from endpoint address that can
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1532
 *	be used to index into endpoint lists
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1533
 *
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1534
 * Returns: ep index (a number between 0 and 31)
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1535
 */
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1536
static uchar_t
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1537
usb_ep_index(uint8_t ep_addr)
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1538
{
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1539
	return ((ep_addr & USB_EP_NUM_MASK) +
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1540
	    ((ep_addr & USB_EP_DIR_MASK) ? 16 : 0));
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1541
}
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1542
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1543
/*
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1544
 * usb_open_ep0:
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1545
 *	opens default pipe
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1546
 *
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1547
 * Returns: errno
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1548
 */
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1549
static int
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1550
usb_open_ep0(usb_dev_handle_impl_t *hdl)
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1551
{
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1552
	char *filename;
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1553
	usb_device_specific_t *dev_specific =
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1554
	    (usb_device_specific_t *)(hdl->device->dev);
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1555
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1556
	usb_dprintf(DEBUG_FUNCTIONS, "usb_open_ep0():\n");
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1557
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1558
	if (dev_specific->ep0_fd) {
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1559
		dev_specific->ref_count++;
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1560
		hdl->info->ep_fd[0] = dev_specific->ep0_fd;
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1561
		hdl->info->ep_status_fd[0] = dev_specific->ep0_fd_stat;
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1562
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1563
		usb_dprintf(DEBUG_DETAILED,
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1564
		    "usb_open_ep0(): already open, ref=%d\n",
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1565
		    dev_specific->ref_count);
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1566
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1567
		return (0);
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1568
	}
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1569
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1570
	if ((filename = malloc(PATH_MAX+1)) == NULL) {
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1571
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1572
		return (ENOMEM);
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1573
	}
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1574
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1575
	(void) snprintf(filename, PATH_MAX, "%s/%s/cntrl0",
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1576
	    hdl->device->bus->dirname, hdl->device->filename);
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1577
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1578
	usb_dprintf(DEBUG_DETAILED, "opening %s\n", filename);
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1579
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1580
	hdl->info->ep_fd[0] = open(filename, O_RDWR);
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1581
	if (hdl->info->ep_fd[0] < 0) {
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1582
		usb_dprintf(DEBUG_ERRORS, "opening ep0 failed, %d\n",
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1583
		    hdl->info->ep_fd[0]);
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1584
		free(filename);
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1585
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1586
		return (errno);
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1587
	}
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1588
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1589
	(void) snprintf(filename, PATH_MAX, "%s/%s/cntrl0stat",
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1590
	    hdl->device->bus->dirname, hdl->device->filename);
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1591
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1592
	usb_dprintf(DEBUG_DETAILED, "opening %s\n", filename);
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1593
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1594
	hdl->info->ep_status_fd[0] = open(filename, O_RDONLY);
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1595
	if (hdl->info->ep_status_fd[0] < 0) {
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1596
		free(filename);
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1597
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1598
		return (errno);
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1599
	}
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1600
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1601
	/* allow sharing between multiple opens */
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1602
	dev_specific->ep0_fd = hdl->info->ep_fd[0];
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1603
	dev_specific->ep0_fd_stat = hdl->info->ep_status_fd[0];
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1604
	dev_specific->ref_count++;
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1605
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1606
	usb_dprintf(DEBUG_DETAILED, "ep0 opened\n");
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1607
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1608
	free(filename);
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1609
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1610
	return (0);
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1611
}
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1612
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1613
/*
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1614
 * usb_close_ep0:
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1615
 *	closes default ep0
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1616
 */
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1617
static void
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1618
usb_close_ep0(usb_dev_handle_impl_t *hdl)
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1619
{
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1620
	usb_device_specific_t *dev_specific =
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1621
	    (usb_device_specific_t *)(hdl->device->dev);
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1622
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1623
	usb_dprintf(DEBUG_FUNCTIONS, "usb_close_ep0():\n");
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1624
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1625
	if (dev_specific->ep0_fd) {
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1626
		if (--(dev_specific->ref_count) > 0) {
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1627
			usb_dprintf(DEBUG_DETAILED,
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1628
			    "usb_close_ep0(): ref_count=%d\n",
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1629
			    dev_specific->ref_count);
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1630
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1631
			return;
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1632
		}
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1633
	}
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1634
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1635
	if (hdl->info->ep_fd[0] != -1) {
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1636
		(void) close(hdl->info->ep_fd[0]);
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1637
		hdl->info->ep_fd[0] = -1;
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1638
	}
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1639
	if (hdl->info->ep_status_fd[0] != -1) {
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1640
		(void) close(hdl->info->ep_status_fd[0]);
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1641
		hdl->info->ep_status_fd[0] = -1;
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1642
	}
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1643
	dev_specific->ep0_fd = 0;
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1644
	dev_specific->ep0_fd_stat = 0;
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1645
}
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1646
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1647
/*
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1648
 * usb_close_all_eps:
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1649
 *	closes all open endpoints except 0
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1650
 */
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1651
static void
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1652
usb_close_all_eps(usb_dev_handle_impl_t *hdl)
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1653
{
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1654
	int i;
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1655
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1656
	usb_dprintf(DEBUG_FUNCTIONS, "usb_close_all_eps():\n");
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1657
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1658
	for (i = 1; i < USB_MAXENDPOINTS; i++) {
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1659
		if (hdl->info->ep_fd[i] != -1) {
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1660
			(void) close(hdl->info->ep_fd[i]);
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1661
			hdl->info->ep_fd[i] = -1;
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1662
		}
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1663
		if (hdl->info->ep_status_fd[i] != -1) {
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1664
			(void) close(hdl->info->ep_status_fd[i]);
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1665
			hdl->info->ep_status_fd[i] = -1;
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1666
		}
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1667
	}
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1668
}
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1669
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1670
/*
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1671
 * usb_setup_all_configs:
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1672
 *	parses config cloud for each config
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1673
 *
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1674
 * Returns: errno
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1675
 */
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1676
static int
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1677
usb_setup_all_configs(usb_dev_handle_impl_t *hdl)
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1678
{
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1679
	char buffer[USB_DEV_DESCR_SIZE];
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1680
	int rval, len;
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1681
	uint_t index;
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1682
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1683
	if (hdl->device->config) {
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1684
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1685
		return (0);
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1686
	}
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1687
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1688
	usb_dprintf(DEBUG_FUNCTIONS, "usb_setup_all_configs():\n");
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1689
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1690
	/* get device descriptor */
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1691
	rval = usb_control_msg((usb_dev_handle *)hdl,
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1692
	    USB_DEV_REQ_DEV_TO_HOST | USB_TYPE_STANDARD,
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1693
	    USB_REQ_GET_DESCRIPTOR, USB_DESCR_TYPE_SETUP_DEV,
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1694
	    0, buffer, USB_DEV_DESCR_SIZE, 0);
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1695
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1696
	usb_dprintf(DEBUG_DETAILED, "dev descr rval=%d\n", rval);
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1697
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1698
	if (rval != USB_DEV_DESCR_SIZE) {
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1699
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1700
		return (EIO);
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1701
	}
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1702
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1703
	/* parse device descriptor */
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1704
	rval = (int)usb_parse_dev_descr((uchar_t *)buffer, sizeof (buffer),
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1705
	    (struct usb_device_descriptor *)&hdl->device->descriptor,
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1706
	    sizeof (struct usb_device_descriptor));
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1707
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1708
	usb_dprintf(DEBUG_DETAILED, "parse dev descr rval=%d\n", rval);
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1709
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1710
	if (rval != (int)sizeof (struct usb_device_descriptor)) {
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1711
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1712
		return (EIO);
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1713
	}
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1714
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1715
	/* allocate config array */
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1716
	len = (int) sizeof (struct usb_config_descriptor) *
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1717
	    hdl->device->descriptor.bNumConfigurations;
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1718
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1719
	if ((hdl->device->config = calloc(len, 1)) == NULL) {
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1720
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1721
		return (ENOMEM);
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1722
	}
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1723
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1724
	/* parse each config cloud */
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1725
	for (index = 0; index < hdl->device->descriptor.bNumConfigurations;
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1726
	    index++) {
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1727
		if ((rval = usb_parse_config(hdl, index)) != 0) {
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1728
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1729
			return (rval);
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1730
		}
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1731
	}
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1732
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1733
	return (0);
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1734
}
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1735
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1736
/*
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1737
 * usb_free_all_configs:
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1738
 *	frees all allocated resources
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1739
 */
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1740
static void
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1741
usb_free_all_configs(usb_device_t *dev)
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1742
{
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1743
	uint_t index;
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1744
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1745
	usb_dprintf(DEBUG_FUNCTIONS, "usb_free_all_configs(): "
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1746
	    "dev=0x%x config=0x%x #conf=%d\n",
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1747
	    dev, dev->config, dev->descriptor.bNumConfigurations);
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1748
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1749
	if (dev->config) {
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1750
		for (index = 0; index < dev->descriptor.bNumConfigurations;
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1751
		    index++) {
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1752
			usb_free_config(dev, index);
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1753
		}
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1754
		free(dev->config);
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1755
		dev->config = NULL;
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1756
	}
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1757
}
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1758
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1759
/*
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1760
 * usb_parse_config:
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1761
 *	parse config descriptor and get cloud
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1762
 *
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1763
 * Returns: errno
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1764
 */
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1765
static int
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1766
usb_parse_config(usb_dev_handle_impl_t *hdl, uint_t index)
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1767
{
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1768
	int rval;
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1769
	uint_t iface, len;
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1770
	char buffer[USB_CFG_DESCR_SIZE];
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1771
	char *cloud;
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1772
	unsigned char *extra;
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1773
	int extralen;
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1774
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1775
	usb_dprintf(DEBUG_FUNCTIONS, "usb_parse_config(): index=%d\n",
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1776
	    index);
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1777
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1778
	rval = usb_control_msg((usb_dev_handle *)hdl,
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1779
	    USB_DEV_REQ_DEV_TO_HOST | USB_TYPE_STANDARD,
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1780
	    USB_REQ_GET_DESCRIPTOR, USB_DESCR_TYPE_SETUP_CFG | index,
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1781
	    0, buffer, USB_CFG_DESCR_SIZE, 0);
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1782
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1783
	usb_dprintf(DEBUG_DETAILED, "config descr rval=%d expecting %d\n",
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1784
	    rval, USB_CFG_DESCR_SIZE);
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1785
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1786
	if (rval < USB_CFG_DESCR_SIZE) {
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1787
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1788
		return (EIO);
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1789
	}
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1790
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1791
	rval = (int)usb_parse_cfg_descr((uchar_t *)buffer, sizeof (buffer),
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1792
	    (usb_cfg_descr_t *)&hdl->device->config[index],
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1793
	    sizeof (usb_cfg_descr_t), &extra, &extralen);
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1794
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1795
	usb_dprintf(DEBUG_DETAILED, "config descr rval=%d expecting %d\n",
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1796
	    rval, sizeof (usb_cfg_descr_t));
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1797
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1798
	if (rval < USB_CFG_DESCR_SIZE) {
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1799
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1800
		return (EIO);
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1801
	}
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1802
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1803
	usb_dprintf(DEBUG_DETAILED,
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1804
	    "cfg%d: len=%d type=%d total=%d #if=%d cf=%d\n", index,
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1805
	    hdl->device->config[index].bLength,
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1806
	    hdl->device->config[index].bDescriptorType,
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1807
	    hdl->device->config[index].wTotalLength,
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1808
	    hdl->device->config[index].bNumInterfaces,
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1809
	    hdl->device->config[index].bConfigurationValue);
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1810
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1811
	if ((cloud = malloc(hdl->device->config[index].wTotalLength)) ==
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1812
	    NULL) {
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1813
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1814
		return (ENOMEM);
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1815
	}
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1816
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1817
	/* get complete cloud */
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1818
	rval = usb_control_msg((usb_dev_handle *)hdl,
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1819
	    USB_DEV_REQ_DEV_TO_HOST | USB_TYPE_STANDARD,
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1820
	    USB_REQ_GET_DESCRIPTOR, USB_DESCR_TYPE_SETUP_CFG | index,
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1821
	    0, (char *)cloud,
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1822
	    hdl->device->config[index].wTotalLength, 0);
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1823
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1824
	if (rval != hdl->device->config[index].wTotalLength) {
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1825
		free(cloud);
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1826
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1827
		return (EIO);
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1828
	}
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1829
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1830
	/* parse descriptor again to get extra descriptors */
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1831
	rval = (int)usb_parse_cfg_descr((uchar_t *)cloud,
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1832
	    hdl->device->config[index].wTotalLength,
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1833
	    (usb_cfg_descr_t *)&hdl->device->config[index],
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1834
	    sizeof (usb_cfg_descr_t), &extra, &extralen);
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1835
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1836
	if (extralen) {
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1837
		usb_dprintf(DEBUG_DETAILED,
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1838
		    "cfg%d: extra descriptors length=%d:\n",
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1839
		    index, extralen);
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1840
		usb_dump_data((char *)extra, extralen);
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1841
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1842
		if ((hdl->device->config[index].extra =
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1843
		    calloc(extralen, 1)) == NULL) {
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1844
			free(cloud);
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1845
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1846
			return (ENOMEM);
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1847
		}
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1848
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1849
		(void) memcpy(hdl->device->config[index].extra, extra,
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1850
		    extralen);
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1851
		hdl->device->config[index].extralen = extralen;
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1852
	}
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1853
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1854
	/* allocate interface array */
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1855
	len = hdl->device->config[index].bNumInterfaces *
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1856
	    (int)sizeof (struct usb_interface);
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1857
	if ((hdl->device->config[index].interface = calloc(len, 1)) ==
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1858
	    NULL) {
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1859
		free(cloud);
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1860
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1861
		return (ENOMEM);
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1862
	}
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1863
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1864
	for (iface = 0; iface < hdl->device->config[index].bNumInterfaces;
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1865
	    iface++) {
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1866
		rval = usb_parse_interface(hdl, index, iface, cloud);
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1867
		if (rval != 0) {
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1868
			free(cloud);
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1869
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1870
			return (rval);
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1871
		}
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1872
	}
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1873
	free(cloud);
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1874
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1875
	return (0);
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1876
}
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1877
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1878
/*
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1879
 * usb_free_config:
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1880
 *	frees all allocated config resources
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1881
 */
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1882
static void
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1883
usb_free_config(usb_device_t *device, uint_t index)
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1884
{
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1885
	uint_t iface;
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1886
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1887
	usb_dprintf(DEBUG_FUNCTIONS, "usb_free_config(): index=%d\n",
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1888
	    index);
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1889
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1890
	if (device->config[index].interface) {
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1891
		for (iface = 0; iface < device->config[index].bNumInterfaces;
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1892
		    iface++) {
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1893
			usb_free_interface(device, index, iface);
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1894
		}
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1895
		if (device->config[index].extralen) {
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1896
			free(device->config[index].extra);
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1897
		}
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1898
		free(device->config[index].interface);
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1899
	}
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1900
}
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1901
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1902
/*
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1903
 * usb_parse_interface:
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1904
 *	parse an interface descriptor
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1905
 *
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1906
 * Returns: errno
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1907
 */
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1908
static int
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1909
usb_parse_interface(usb_dev_handle_impl_t *hdl, uint_t index, uint_t iface,
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1910
    char *cloud)
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1911
{
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1912
	usb_if_descr_t if_descr;
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1913
	int rval;
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1914
	uint_t alt, max_alt, len;
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1915
	unsigned char *extra;
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1916
	int extralen;
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1917
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1918
	usb_dprintf(DEBUG_FUNCTIONS, "usb_parse_interface(): "
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1919
	    "index=%d, iface=%d\n", index, iface);
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1920
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1921
	/* count the number of alternates for this interface */
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1922
	for (max_alt = alt = 0; alt < USB_MAXALTSETTING; alt++) {
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1923
		rval = (int)usb_parse_if_descr((uchar_t *)cloud,
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1924
		    hdl->device->config[index].wTotalLength,
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1925
		    iface, alt, &if_descr, sizeof (if_descr),
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1926
		    &extra, &extralen);
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1927
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1928
		usb_dprintf(DEBUG_DETAILED, "usb_parse_interface: "
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1929
		    "alt %d: rval=%d expecting %d\n",
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1930
		    alt, rval, sizeof (if_descr));
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1931
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1932
		if (rval != (int)sizeof (if_descr)) {
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1933
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1934
			break;
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1935
		}
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1936
		max_alt = alt;
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1937
	}
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1938
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1939
	usb_dprintf(DEBUG_DETAILED,
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1940
	    "usb_parse_interface: max_alt=%d\n", max_alt);
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1941
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1942
	/* allocate alt interface setting array */
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1943
	len = ++max_alt * (int)sizeof (struct usb_interface_descriptor);
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1944
	if ((hdl->device->config[index].interface[iface].altsetting =
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1945
	    calloc(len, 1)) == NULL) {
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1946
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1947
		return (ENOMEM);
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1948
	}
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1949
	hdl->device->config[index].interface[iface].num_altsetting =
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1950
	    max_alt;
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1951
	for (alt = 0; alt < max_alt; alt++) {
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1952
		rval = usb_parse_alternate(hdl, index, iface, alt, cloud);
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1953
		if (rval != 0) {
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1954
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1955
			return (rval);
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1956
		}
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1957
	}
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1958
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1959
	return (0);
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1960
}
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1961
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1962
/*
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1963
 * usb_free_interface:
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1964
 *	frees interface resources
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1965
 *
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1966
 * Returns: errno
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1967
 */
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1968
static void
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1969
usb_free_interface(usb_device_t *device, uint_t index, uint_t iface)
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1970
{
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1971
	uint_t alt, max_alt;
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1972
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1973
	usb_dprintf(DEBUG_FUNCTIONS, "usb_free_interface(): "
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1974
	    "index=%d, iface=%d\n", index, iface);
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1975
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1976
	if (device->config[index].interface[iface].altsetting) {
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1977
		max_alt = device->config[index].interface[iface].
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1978
		    num_altsetting;
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1979
		for (alt = 0; alt < max_alt; alt++) {
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1980
			usb_free_alternate(device, index, iface, alt);
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1981
		}
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1982
		free(device->config[index].interface[iface].altsetting);
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1983
	}
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1984
}
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1985
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1986
/*
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1987
 * usb_parse_alternate:
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1988
 *	parses each alternate descriptor
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1989
 *
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1990
 * Returns: errno
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1991
 */
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1992
static int
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1993
usb_parse_alternate(usb_dev_handle_impl_t *hdl, uint_t index, uint_t iface,
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1994
    uint_t alt, char *cloud)
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1995
{
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1996
	uint_t ep, len;
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1997
	usb_if_descr_t if_descr;
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1998
	int rval;
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  1999
	unsigned char *extra;
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2000
	int extralen;
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2001
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2002
	usb_dprintf(DEBUG_FUNCTIONS, "usb_parse_alternate(): "
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2003
	    "index=%d, iface=%d, alt=%d\n", index, iface, alt);
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2004
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2005
	rval = (int)usb_parse_if_descr((uchar_t *)cloud,
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2006
	    hdl->device->config[index].wTotalLength,
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2007
	    iface, alt, &if_descr, sizeof (if_descr), &extra, &extralen);
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2008
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2009
	if (rval != (int)sizeof (if_descr)) {
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2010
		usb_dprintf(DEBUG_ERRORS, "usb_parse_alternate: rval=%d\n",
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2011
		    rval);
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2012
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2013
		return (EIO);
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2014
	}
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2015
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2016
	usb_dprintf(DEBUG_DETAILED,
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2017
	    "cfg%d.if%d.%d: len=%d type=%d num=%d alt=%d #ep=%d c=%d"
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2018
	    " sc=%d p=%d i=%d\n", index, iface, alt,
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2019
	    if_descr.bLength,
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2020
	    if_descr.bDescriptorType,
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2021
	    if_descr.bInterfaceNumber,
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2022
	    if_descr.bAlternateSetting,
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2023
	    if_descr.bNumEndpoints,
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2024
	    if_descr.bInterfaceClass,
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2025
	    if_descr.bInterfaceSubClass,
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2026
	    if_descr.bInterfaceProtocol,
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2027
	    if_descr.iInterface);
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2028
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2029
	(void) memcpy(
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2030
	    &hdl->device->config[index].interface[iface].altsetting[alt],
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2031
	    &if_descr, sizeof (if_descr));
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2032
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2033
	if (extralen) {
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2034
		usb_dprintf(DEBUG_DETAILED,
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2035
		    "cfg%d.if%d.%d: extralen=%d:\n", index, iface, alt,
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2036
		    extralen);
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2037
		usb_dump_data((char *)extra, extralen);
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2038
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2039
		if ((hdl->device->config[index].interface[iface].
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2040
		    altsetting[alt].extra = calloc(extralen, 1)) == NULL) {
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2041
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2042
			return (ENOMEM);
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2043
		}
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2044
		(void) memcpy(
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2045
		    hdl->device->config[index].interface[iface].
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2046
		    altsetting[alt].extra, extra, extralen);
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2047
		hdl->device->config[index].interface[iface].
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2048
		    altsetting[alt].extralen = extralen;
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2049
	}
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2050
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2051
	if (if_descr.bNumEndpoints == 0) {
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2052
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2053
		return (0);
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2054
	}
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2055
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2056
	/* allocate endpoint array for this alternate */
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2057
	len = if_descr.bNumEndpoints *
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2058
	    (int)sizeof (struct usb_endpoint_descriptor);
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2059
	if ((hdl->device->config[index].interface[iface].altsetting[alt].
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2060
	    endpoint = calloc(len, 1)) == NULL) {
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2061
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2062
		return (ENOMEM);
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2063
	}
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2064
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2065
	for (ep = 0; ep < if_descr.bNumEndpoints; ep++) {
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2066
		rval = usb_parse_endpoint(hdl, index, iface, alt, ep, cloud);
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2067
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2068
		if (rval != 0) {
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2069
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2070
			return (rval);
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2071
		}
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2072
	}
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2073
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2074
	return (0);
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2075
}
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2076
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2077
/*
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2078
 * usb_free_alternate:
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2079
 *	frees all alternate resources
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2080
 */
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2081
static void
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2082
usb_free_alternate(usb_device_t *device, uint_t index, uint_t iface,
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2083
	uint_t alt)
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2084
{
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2085
	usb_dprintf(DEBUG_FUNCTIONS, "usb_free_alternate(): "
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2086
	    "index=%d, iface=%d, alt=%d\n", index, iface, alt);
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2087
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2088
	if (device->config[index].interface[iface].altsetting[alt].
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2089
	    endpoint) {
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2090
		uint_t ep;
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2091
		struct usb_interface_descriptor *if_descr =
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2092
		    &device->config[index].
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2093
		    interface[iface].altsetting[alt];
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2094
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2095
		for (ep = 0; ep < if_descr->bNumEndpoints; ep++) {
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2096
			if (if_descr->extralen) {
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2097
				free(if_descr->extra);
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2098
			}
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2099
		}
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2100
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2101
		if (device->config[index].interface[iface].altsetting[alt].
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2102
		    extralen) {
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2103
			free(device->config[index].interface[iface].
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2104
			    altsetting[alt].extra);
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2105
		}
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2106
		free(device->config[index].interface[iface].altsetting[alt].
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2107
		    endpoint);
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2108
	}
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2109
}
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2110
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2111
/*
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2112
 * usb_parse_endpoint:
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2113
 *	 parses an endpoint descriptor
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2114
 *
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2115
 * Returns: errno
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2116
 */
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2117
static int
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2118
usb_parse_endpoint(usb_dev_handle_impl_t *hdl, int index, int iface,
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2119
    int alt, int ep, char *cloud)
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2120
{
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2121
	usb_ep_descr_t ep_descr;
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2122
	int rval;
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2123
	unsigned char *extra;
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2124
	int extralen;
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2125
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2126
	usb_dprintf(DEBUG_FUNCTIONS, "usb_parse_endpoint(): "
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2127
	    "index=%d, iface=%d, alt=%d, ep=0x%x\n",
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2128
	    index, iface, alt, ep);
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2129
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2130
	rval = (int)usb_parse_ep_descr((uchar_t *)cloud,
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2131
	    hdl->device->config[index].wTotalLength,
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2132
	    iface, alt, ep, &ep_descr, sizeof (ep_descr),
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2133
	    &extra, &extralen);
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2134
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2135
	if (rval < USB_EP_DESCR_SIZE) {
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2136
		usb_dprintf(DEBUG_ERRORS, "usb_parse_endpoint: rval=%d, "
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2137
		    "expecting %d\n", rval, USB_EP_DESCR_SIZE);
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2138
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2139
		return (rval);
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2140
	}
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2141
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2142
	usb_dprintf(DEBUG_DETAILED,
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2143
	    "\tl=%d t=%d a=0x%x attr=0x%x max=%d int=%d\n",
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2144
	    ep_descr.bLength, ep_descr.bDescriptorType,
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2145
	    ep_descr.bEndpointAddress, ep_descr.bmAttributes,
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2146
	    ep_descr.wMaxPacketSize, ep_descr.bInterval);
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2147
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2148
	(void) memcpy(&hdl->device->
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2149
	    config[index].interface[iface].altsetting[alt].endpoint[ep],
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2150
	    &ep_descr, sizeof (ep_descr));
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2151
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2152
	if (extralen) {
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2153
		usb_dprintf(DEBUG_DETAILED,
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2154
		    "cfg%d.if%d.%d.ep%d: extralen=%d:\n",
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2155
		    index, iface, alt, ep, extralen);
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2156
		usb_dump_data((char *)extra, extralen);
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2157
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2158
		if ((hdl->device->config[index].interface[iface].
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2159
		    altsetting[alt].endpoint[ep].extra =
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2160
		    calloc(extralen, 1)) == NULL) {
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2161
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2162
			return (ENOMEM);
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2163
		}
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2164
		(void) memcpy(hdl->device->config[index].interface[iface].
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2165
		    altsetting[alt].endpoint[ep].extra, extra, extralen);
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2166
		hdl->device->config[index].interface[iface].
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2167
		    altsetting[alt].endpoint[ep].extralen = extralen;
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2168
	}
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2169
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2170
	return (0);
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2171
}
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2172
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2173
/*
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2174
 * usb_add_device:
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2175
 *	adds dev to the beginning of the list
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2176
 */
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2177
static void
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2178
usb_add_device(usb_device_t **list, usb_device_t *dev)
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2179
{
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2180
	if (*list) {
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2181
		dev->next = *list;
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2182
		dev->next->prev = dev;
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2183
	} else {
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2184
		dev->next = NULL;
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2185
	}
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2186
	dev->prev = NULL;
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2187
	*list = dev;
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2188
}
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2189
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2190
/*
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2191
 * usb_remove_device:
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2192
 *	removes dev from a list
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2193
 */
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2194
static void
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2195
usb_remove_device(usb_device_t **list, usb_device_t *dev)
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2196
{
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2197
	if (dev->prev) {
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2198
		dev->prev->next = dev->next;
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2199
	} else {
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2200
		*list = dev->next;
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2201
	}
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2202
	if (dev->next) {
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2203
		dev->next->prev = dev->prev;
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2204
	}
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2205
	dev->prev = dev->next = NULL;
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2206
}
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2207
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2208
/*
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2209
 * usb_check_device_in_list:
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2210
 *	checks if dev is in list
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2211
 *
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2212
 * Returns: 1 (yes), 0 (no)
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2213
 */
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2214
static int
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2215
usb_check_device_in_list(usb_device_t *list, usb_device_t *dev)
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2216
{
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2217
	usb_device_t *d = list;
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2218
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2219
	while (d != NULL) {
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2220
		if (d == dev) {
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2221
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2222
			return (1);
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2223
		}
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2224
		d = d->next;
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2225
	}
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2226
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2227
	return (0);
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2228
}
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2229
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2230
/*
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2231
 * usb_free_bus:
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2232
 *	frees the entire bus structure, not used, just for
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2233
 *	completeness
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2234
 */
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2235
static void
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2236
usb_free_bus(usb_bus_t *bus)
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2237
{
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2238
	free(bus);
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2239
}
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2240
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2241
/*
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2242
 * usb_free_dev:
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2243
 *	frees all configs and then the device structure itself
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2244
 */
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2245
static void
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2246
usb_free_dev(usb_device_t *dev)
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2247
{
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2248
	usb_dprintf(DEBUG_FUNCTIONS, "usb_free_dev(): 0x%x\n", (int)dev);
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2249
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2250
	usb_free_all_configs(dev);
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2251
	free(dev->dev);
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2252
	free(dev);
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2253
}
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2254
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2255
/*
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2256
 * usb_get_device_status:
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2257
 *	gets status of device
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2258
 *
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2259
 * Returns: ugen dev status values
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2260
 */
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2261
static int
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2262
usb_get_device_status(int fd)
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2263
{
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2264
	int status, error;
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2265
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2266
	usb_dprintf(DEBUG_FUNCTIONS, "usb_get_device_status():\n");
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2267
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2268
	error = (int)read(fd, &status, (size_t)sizeof (status));
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2269
	if (error != (int)sizeof (status)) {
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2270
		usb_error_str(errno, "Could not read device status: %d",
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2271
		    error);
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2272
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2273
		return (USB_DEV_STAT_UNAVAILABLE);
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2274
	} else {
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2275
		switch (status) {
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2276
		case USB_DEV_STAT_ONLINE:
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2277
			usb_dprintf(DEBUG_DETAILED, "Device is available\n");
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2278
			break;
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2279
		case USB_DEV_STAT_DISCONNECTED:
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2280
			usb_dprintf(DEBUG_DETAILED, "Device has been "
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2281
			    "disconnected\n");
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2282
			break;
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2283
		case USB_DEV_STAT_RESUMED:
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2284
			usb_dprintf(DEBUG_DETAILED,
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2285
			    "Device has been resumed\n");
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2286
			break;
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2287
		case USB_DEV_STAT_UNAVAILABLE:
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2288
			usb_dprintf(DEBUG_DETAILED,
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2289
			    "Device is powered down\n");
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2290
			break;
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2291
		default:
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2292
			usb_dprintf(DEBUG_DETAILED,
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2293
			    "Device status=%d\n", status);
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2294
		}
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2295
	}
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2296
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2297
	return (status);
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2298
}
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2299
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2300
/*
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2301
 * usb_search_dev_usb:
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2302
 *	finds all names of devices in the /usb/dev tree
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2303
 *	this will be the VID/PID and instance no
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2304
 *
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2305
 * Returns: errno
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2306
 */
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2307
static int
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2308
usb_search_dev_usb(usb_device_t **new_devices)
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2309
{
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2310
	DIR			*dir, *subdir;
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2311
	struct dirent		*dir_entry, *subdir_entry;
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2312
	char			*device, *filename;
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2313
	usb_bus_t		*bus = usb_busses;
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2314
	struct stat		statbuf;
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2315
	regex_t			regex;
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2316
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2317
	usb_dprintf(DEBUG_FUNCTIONS, "usb_search_dev_usb():\n");
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2318
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2319
	if ((device = malloc(PATH_MAX+1)) == NULL) {
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2320
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2321
		return (ENOMEM);
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2322
	}
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2323
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2324
	if ((filename = malloc(PATH_MAX+1)) == NULL) {
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2325
		free(device);
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2326
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2327
		return (ENOMEM);
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2328
	}
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2329
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2330
	if (!(dir = opendir(bus->dirname))) {
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2331
		free(device);
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2332
		free(filename);
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2333
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2334
		usb_error_str(errno,
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2335
		    "couldn't opendir %s: %d", bus->dirname, errno);
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2336
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2337
		return (errno);
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2338
	}
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2339
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2340
	/* make sure we only open ugen directories */
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2341
	if ((regcomp(&regex, "/dev/usb/[0-9a-f]+[.][0-9a-f]+",
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2342
	    REG_EXTENDED) != 0)) {
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2343
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2344
		return (EINVAL);
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2345
	}
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2346
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2347
	/* search for devices */
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2348
	while ((dir_entry = readdir(dir)) != NULL) {
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2349
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2350
		usb_dprintf(DEBUG_FUNCTIONS, "usb_search_dev_usb(): dir=%s\n",
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2351
		    dir_entry->d_name);
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2352
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2353
		if (dir_entry->d_name[0] == '.') {
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2354
			continue;
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2355
		}
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2356
		(void) snprintf(device, PATH_MAX, "%s/%s", bus->dirname,
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2357
		    dir_entry->d_name);
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2358
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2359
		/*
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2360
		 * make sure we don't accidentily open /dev/usb/hid* nodes
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2361
		 * which will get them unlinked from the virtual console
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2362
		 */
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2363
		if (lstat(device, &statbuf) == -1) {
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2364
			continue;
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2365
		}
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2366
		if (!S_ISDIR(statbuf.st_mode)) {
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2367
			continue;
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2368
		}
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2369
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2370
		if (regexec(&regex, device, 0, NULL, 0) != 0) {
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2371
			continue;
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2372
		}
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2373
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2374
		usb_dprintf(DEBUG_FUNCTIONS, "checking %s\n", device);
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2375
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2376
		/* need to search instances */
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2377
		if (!(subdir = opendir(device))) {
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2378
			continue;
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2379
		}
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2380
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2381
		while ((subdir_entry = readdir(subdir)) != NULL) {
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2382
			usb_device_t *dev;
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2383
			usb_device_specific_t *dev_specific;
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2384
			int fd;
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2385
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2386
			if (subdir_entry->d_name[0] == '.') {
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2387
				continue;
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2388
			}
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2389
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2390
			if ((dev = calloc(sizeof (*dev), 1)) == NULL) {
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2391
				free(device);
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2392
				free(filename);
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2393
				regfree(&regex);
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2394
				(void) closedir(subdir);
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2395
				(void) closedir(dir);
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2396
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2397
				return (ENOMEM);
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2398
			}
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2399
			if ((dev_specific = calloc(sizeof (*dev_specific),
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2400
			    1)) == NULL) {
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2401
				free(device);
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2402
				free(filename);
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2403
				free(dev);
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2404
				regfree(&regex);
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2405
				(void) closedir(subdir);
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2406
				(void) closedir(dir);
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2407
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2408
				return (ENOMEM);
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2409
			}
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2410
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2411
			dev->dev = (void *)dev_specific;
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2412
			dev->bus = bus;
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2413
			(void) snprintf(dev->filename, PATH_MAX, "%s/%s",
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2414
			    dir_entry->d_name, subdir_entry->d_name);
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2415
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2416
			/* See if the device is online */
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2417
			(void) snprintf(filename, PATH_MAX, "%s/%s/devstat",
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2418
			    bus->dirname, dev->filename);
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2419
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2420
			usb_dprintf(DEBUG_DETAILED, "filename %s\n", filename);
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2421
			usb_dprintf(DEBUG_DETAILED, "dev filename %s\n",
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2422
			    dev->filename);
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2423
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2424
			if ((fd = open(filename, O_RDONLY|O_EXCL)) < 0) {
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2425
				usb_dprintf(DEBUG_ERRORS,
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2426
				    "usb_search_dev_usb: Couldn't open %s\n",
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2427
				    filename);
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2428
				free(dev_specific);
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2429
				free(dev);
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2430
				continue;
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2431
			}
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2432
			if (usb_get_device_status(fd) != USB_DEV_STAT_ONLINE) {
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2433
				(void) close(fd);
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2434
				usb_error_str(EIO, "Device %s is not online",
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2435
				    dev->filename);
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2436
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2437
				free(dev_specific);
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2438
				free(dev);
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2439
				continue;
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2440
			}
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2441
			(void) close(fd);
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2442
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2443
			usb_add_device(new_devices, dev);
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2444
		}
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2445
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2446
		(void) closedir(subdir);
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2447
	}
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2448
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2449
	regfree(&regex);
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2450
	free(filename);
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2451
	free(device);
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2452
	(void) closedir(dir);
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2453
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2454
	return (0);
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2455
}
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2456
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2457
/*
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2458
 * usb_get_status:
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2459
 *	gets status of endpoint
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2460
 *
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2461
 * Returns: ugen's last cmd status
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2462
 */
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2463
static int
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2464
usb_get_status(int fd)
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2465
{
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2466
	int status, error;
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2467
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2468
	usb_dprintf(DEBUG_FUNCTIONS, "usb_get_status(): fd=%d\n", fd);
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2469
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2470
	error = (int)read(fd, &status, sizeof (status));
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2471
	if (error == (int)sizeof (status)) {
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2472
		switch (status) {
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2473
		case USB_LC_STAT_NOERROR:
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2474
			usb_dprintf(DEBUG_DETAILED, "No Error\n");
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2475
			break;
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2476
		case USB_LC_STAT_CRC:
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2477
			usb_dprintf(DEBUG_ERRORS, "CRC Timeout Detected\n");
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2478
			break;
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2479
		case USB_LC_STAT_BITSTUFFING:
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2480
			usb_dprintf(DEBUG_ERRORS, "Bit Stuffing Violation\n");
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2481
			break;
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2482
		case USB_LC_STAT_DATA_TOGGLE_MM:
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2483
			usb_dprintf(DEBUG_ERRORS, "Data Toggle Mismatch\n");
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2484
			break;
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2485
		case USB_LC_STAT_STALL:
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2486
			usb_dprintf(DEBUG_ERRORS, "End Point Stalled\n");
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2487
			break;
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2488
		case USB_LC_STAT_DEV_NOT_RESP:
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2489
			usb_dprintf(DEBUG_ERRORS, "Device is Not Responding\n");
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2490
			break;
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2491
		case USB_LC_STAT_PID_CHECKFAILURE:
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2492
			usb_dprintf(DEBUG_ERRORS, "PID Check Failure\n");
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2493
			break;
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2494
		case USB_LC_STAT_UNEXP_PID:
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2495
			usb_dprintf(DEBUG_ERRORS, "Unexpected PID\n");
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2496
			break;
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2497
		case USB_LC_STAT_DATA_OVERRUN:
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2498
			usb_dprintf(DEBUG_ERRORS, "Data Exceeded Size\n");
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2499
			break;
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2500
		case USB_LC_STAT_DATA_UNDERRUN:
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2501
			usb_dprintf(DEBUG_ERRORS, "Less data received\n");
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2502
			break;
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2503
		case USB_LC_STAT_BUFFER_OVERRUN:
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2504
			usb_dprintf(DEBUG_ERRORS, "Buffer Size Exceeded\n");
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2505
			break;
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2506
		case USB_LC_STAT_BUFFER_UNDERRUN:
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2507
			usb_dprintf(DEBUG_ERRORS, "Buffer Underrun\n");
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2508
			break;
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2509
		case USB_LC_STAT_TIMEOUT:
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2510
			usb_dprintf(DEBUG_ERRORS, "Command Timed Out\n");
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2511
			break;
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2512
		case USB_LC_STAT_NOT_ACCESSED:
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2513
			usb_dprintf(DEBUG_ERRORS, "Not Accessed by h/w\n");
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2514
			break;
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2515
		case USB_LC_STAT_UNSPECIFIED_ERR:
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2516
			usb_dprintf(DEBUG_ERRORS, "Unspecified Error\n");
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2517
			break;
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2518
		case USB_LC_STAT_NO_BANDWIDTH:
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2519
			usb_dprintf(DEBUG_ERRORS, "No Bandwidth\n");
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2520
			break;
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2521
		case USB_LC_STAT_HW_ERR:
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2522
			usb_dprintf(DEBUG_ERRORS,
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2523
			    "Host Controller h/w Error\n");
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2524
			break;
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2525
		case USB_LC_STAT_SUSPENDED:
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2526
			usb_dprintf(DEBUG_ERRORS, "Device was Suspended\n");
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2527
			break;
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2528
		case USB_LC_STAT_DISCONNECTED:
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2529
			usb_dprintf(DEBUG_ERRORS, "Device was Disconnected\n");
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2530
			break;
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2531
		case USB_LC_STAT_INTR_BUF_FULL:
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2532
			usb_dprintf(DEBUG_ERRORS,
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2533
			    "Interrupt buffer was full\n");
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2534
			break;
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2535
		case USB_LC_STAT_INVALID_REQ:
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2536
			usb_dprintf(DEBUG_ERRORS, "Request was Invalid\n");
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2537
			break;
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2538
		case USB_LC_STAT_INTERRUPTED:
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2539
			usb_dprintf(DEBUG_ERRORS, "Request was Interrupted\n");
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2540
			break;
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2541
		case USB_LC_STAT_NO_RESOURCES:
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2542
			usb_dprintf(DEBUG_ERRORS, "No resources available for "
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2543
			    "request\n");
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2544
			break;
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2545
		case USB_LC_STAT_INTR_POLLING_FAILED:
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2546
			usb_dprintf(DEBUG_ERRORS, "Failed to Restart Poll");
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2547
			break;
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2548
		default:
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2549
			usb_dprintf(DEBUG_ERRORS, "Error Not Determined %d\n",
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2550
			    status);
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2551
			break;
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2552
		}
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2553
	}
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2554
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2555
	return (status);
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2556
}
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2557
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2558
/*
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2559
 * Descriptor parsing functions, taken from USBA code
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2560
 *
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2561
 * usb_parse_data:
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2562
 *	take a raw buffer and pads it according to format
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2563
 *
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2564
 * Returns: USB_PARSE_ERROR or length parsed
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2565
 */
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2566
static size_t
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2567
usb_parse_data(char *format, uchar_t *data, size_t datalen,
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2568
    void *structure, size_t structlen)
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2569
{
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2570
	int	fmt;
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2571
	size_t	counter = 1;
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2572
	int	multiplier = 0;
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2573
	uchar_t	*dataend = data + datalen;
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2574
	char	*structstart = (char *)structure;
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2575
	void	*structend = (void *)((intptr_t)structstart + structlen);
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2576
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2577
	if ((format == NULL) || (data == NULL) || (structure == NULL)) {
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2578
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2579
		return (USB_PARSE_ERROR);
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2580
	}
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2581
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2582
	while ((fmt = *format) != '\0') {
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2583
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2584
		/*
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2585
		 * Could some one pass a "format" that is greater than
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2586
		 * the structlen? Conversely, one could pass a ret_buf_len
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2587
		 * that is less than the "format" length.
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2588
		 * If so, we need to protect against writing over memory.
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2589
		 */
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2590
		if (counter++ > structlen) {
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2591
			break;
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2592
		}
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2593
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2594
		if (fmt == 'c') {
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2595
			uint8_t	*cp = (uint8_t *)structure;
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2596
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2597
			cp = (uint8_t *)(((uintptr_t)cp + _CHAR_ALIGNMENT - 1) &
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2598
			    ~(_CHAR_ALIGNMENT - 1));
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2599
			if (((data + 1) > dataend) ||
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2600
			    ((cp + 1) > (uint8_t *)structend))
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2601
				break;
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2602
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2603
			*cp++ = *data++;
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2604
			structure = (void *)cp;
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2605
			if (multiplier) {
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2606
				multiplier--;
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2607
			}
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2608
			if (multiplier == 0) {
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2609
				format++;
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2610
			}
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2611
		} else if (fmt == 's') {
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2612
			uint16_t	*sp = (uint16_t *)structure;
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2613
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2614
			sp = (uint16_t *)
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2615
			    (((uintptr_t)sp + _SHORT_ALIGNMENT - 1) &
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2616
			    ~(_SHORT_ALIGNMENT - 1));
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2617
			if (((data + 2) > dataend) ||
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2618
			    ((sp + 1) > (uint16_t *)structend))
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2619
				break;
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2620
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2621
			*sp++ = (data[1] << 8) + data[0];
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2622
			data += 2;
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2623
			structure = (void *)sp;
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2624
			if (multiplier) {
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2625
				multiplier--;
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2626
			}
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2627
			if (multiplier == 0) {
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2628
				format++;
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2629
			}
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2630
		} else if (fmt == 'l') {
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2631
			uint32_t	*lp = (uint32_t *)structure;
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2632
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2633
			lp = (uint32_t *)
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2634
			    (((uintptr_t)lp + _INT_ALIGNMENT - 1) &
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2635
			    ~(_INT_ALIGNMENT - 1));
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2636
			if (((data + 4) > dataend) ||
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2637
			    ((lp + 1) > (uint32_t *)structend))
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2638
				break;
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2639
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2640
			*lp++ = (((((
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2641
			    (uint32_t)data[3] << 8) | data[2]) << 8) |
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2642
			    data[1]) << 8) | data[0];
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2643
			data += 4;
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2644
			structure = (void *)lp;
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2645
			if (multiplier) {
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2646
				multiplier--;
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2647
			}
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2648
			if (multiplier == 0) {
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2649
				format++;
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2650
			}
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2651
		} else if (fmt == 'L') {
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2652
			uint64_t	*llp = (uint64_t *)structure;
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2653
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2654
			llp = (uint64_t *)
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2655
			    (((uintptr_t)llp + _LONG_LONG_ALIGNMENT - 1) &
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2656
			    ~(_LONG_LONG_ALIGNMENT - 1));
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2657
			if (((data + 8) > dataend) ||
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2658
			    ((llp + 1) >= (uint64_t *)structend))
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2659
				break;
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2660
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2661
			*llp++ = (((((((((((((data[7] << 8) |
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2662
			    data[6]) << 8) | data[5]) << 8) |
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2663
			    data[4]) << 8) | data[3]) << 8) |
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2664
			    data[2]) << 8) | data[1]) << 8) |
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2665
			    data[0];
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2666
			data += 8;
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2667
			structure = (void *)llp;
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2668
			if (multiplier) {
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2669
				multiplier--;
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2670
			}
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2671
			if (multiplier == 0) {
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2672
				format++;
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2673
			}
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2674
		} else if (isdigit(fmt)) {
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2675
			multiplier = (multiplier * 10) + (fmt - '0');
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2676
			counter--;
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2677
			format++;
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2678
		} else {
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2679
			multiplier = 0;
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2680
			break;
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2681
		}
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2682
	}
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2683
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2684
	return ((intptr_t)structure - (intptr_t)structstart);
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2685
}
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2686
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2687
/*
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2688
 * usb_nth_descr:
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2689
 *	finds pointer to n-th descriptor of
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2690
 *	type descr_type, unless the end of the buffer or a descriptor
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2691
 *	of type	stop_descr_type1 or stop_descr_type2 is encountered first.
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2692
 *
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2693
 * Returns: returns pointer to n-th descriptor
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2694
 */
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2695
static uchar_t *
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2696
usb_nth_descr(uchar_t *buf, size_t buflen, int descr_type, uint_t n,
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2697
    int	stop_descr_type1, int stop_descr_type2)
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2698
{
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2699
	uchar_t	*bufstart = buf;
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2700
	uchar_t *bufend = buf + buflen;
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2701
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2702
	if (buf == NULL) {
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2703
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2704
		return (NULL);
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2705
	}
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2706
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2707
	while (buf + 2 <= bufend) {
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2708
		if ((buf != bufstart) && ((buf[1] == stop_descr_type1) ||
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2709
		    (buf[1] == stop_descr_type2))) {
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2710
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2711
			return (NULL);
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2712
		}
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2713
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2714
		if ((descr_type == USB_DESCR_TYPE_ANY) ||
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2715
		    (buf[1] == descr_type)) {
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2716
			if (n-- == 0) {
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2717
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2718
				return (buf);
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2719
			}
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2720
		}
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2721
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2722
		/*
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2723
		 * Check for a bad buffer.
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2724
		 * If buf[0] is 0, then this will be an infite loop
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2725
		 */
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2726
		INCREMENT_BUF(buf);
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2727
	}
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2728
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2729
	return (NULL);
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2730
}
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2731
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2732
/*
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2733
 * usb_parse_dev_descr:
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2734
 *	parse device descriptor
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2735
 *
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2736
 * Returns: #bytes parsed
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2737
 */
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2738
static size_t
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2739
usb_parse_dev_descr(uchar_t *buf, size_t buflen,
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2740
    struct usb_device_descriptor *ret_descr, size_t ret_buf_len)
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2741
{
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2742
	if ((buf == NULL) || (ret_descr == NULL) ||
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2743
	    (buflen < 2) || (buf[1] != USB_DESCR_TYPE_DEV)) {
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2744
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2745
		return (USB_PARSE_ERROR);
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2746
	}
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2747
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2748
	return (usb_parse_data("ccsccccssscccc",
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2749
	    buf, buflen, ret_descr, ret_buf_len));
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2750
}
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2751
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2752
/*
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2753
 * usb_parse_cfg_descr:
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2754
 *	parse config descriptor
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2755
 *
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2756
 * Returns: #bytes parsed
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2757
 */
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2758
static size_t
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2759
usb_parse_cfg_descr(uchar_t *buf, size_t buflen, usb_cfg_descr_t *ret_descr,
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2760
    size_t ret_buf_len, unsigned char **extra, int *extralen)
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2761
{
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2762
	size_t rval;
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2763
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2764
	if ((buf == NULL) || (ret_descr == NULL) ||
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2765
	    (buflen < 2) || (buf[1] != USB_DESCR_TYPE_CFG)) {
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2766
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2767
		return (USB_PARSE_ERROR);
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2768
	}
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2769
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2770
	rval = usb_parse_data("ccsccccc",
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2771
	    buf, buflen, ret_descr, ret_buf_len);
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2772
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2773
	usb_find_extra(buf, buflen, extra, extralen);
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2774
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2775
	return (rval);
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2776
}
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2777
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2778
/*
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2779
 * usb_parse_if_descr:
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2780
 *	parse interface descriptor
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2781
 *
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2782
 * Returns: #bytes parsed
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2783
 */
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2784
static size_t
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2785
usb_parse_if_descr(uchar_t *buf, size_t	buflen, uint_t if_number,
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2786
    uint_t alt_if_setting, usb_if_descr_t *ret_descr, size_t ret_buf_len,
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2787
    unsigned char **extra, int *extralen)
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2788
{
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2789
	uchar_t *bufend = buf + buflen;
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2790
	size_t rval;
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2791
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2792
	if ((buf == NULL) || (ret_descr == NULL)) {
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2793
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2794
		return (USB_PARSE_ERROR);
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2795
	}
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2796
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2797
	while (buf + 4 <= bufend) {
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2798
		if ((buf[1] == USB_DESCR_TYPE_IF) &&
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2799
		    (buf[2] == if_number) &&
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2800
		    (buf[3] == alt_if_setting)) {
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2801
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2802
			rval = usb_parse_data("ccccccccc",
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2803
			    buf, ((uintptr_t)bufend - (uintptr_t)buf),
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2804
			    ret_descr, ret_buf_len);
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2805
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2806
			usb_find_extra(buf,
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2807
			    ((uintptr_t)bufend - (uintptr_t)buf),
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2808
			    extra, extralen);
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2809
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2810
			return (rval);
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2811
		}
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2812
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2813
		/*
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2814
		 * Check for a bad buffer.
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2815
		 * If buf[0] is 0, then this will be an infinite loop
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2816
		 */
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2817
		INCREMENT_BUF(buf);
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2818
	}
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2819
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2820
	return (USB_PARSE_ERROR);
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2821
}
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2822
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2823
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2824
/*
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2825
 * usb_parse_ep_descr:
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2826
 *	parse config descriptor
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2827
 *	the endpoint index is relative to the interface. index 0 is
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2828
 *	the first endpoint
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2829
 *
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2830
 * Returns: #bytes parsed
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2831
 */
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2832
size_t
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2833
usb_parse_ep_descr(uchar_t *buf, size_t buflen, uint_t if_number,
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2834
    uint_t alt_if_setting, uint_t ep_index, usb_ep_descr_t *ret_descr,
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2835
    size_t ret_buf_len, unsigned char **extra, int *extralen)
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2836
{
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2837
	uchar_t *bufend = buf + buflen;
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2838
	size_t rval;
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2839
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2840
	if ((buf == NULL) || (ret_descr == NULL)) {
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2841
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2842
		return (USB_PARSE_ERROR);
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2843
	}
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2844
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2845
	while ((buf + 4) <= bufend) {
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2846
		if (buf[1] == USB_DESCR_TYPE_IF &&
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2847
		    buf[2] == if_number &&
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2848
		    buf[3] == alt_if_setting) {
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2849
			if ((buf = usb_nth_descr(buf,
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2850
			    (uintptr_t)bufend - (uintptr_t)buf,
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2851
			    USB_DESCR_TYPE_EP, ep_index,
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2852
			    USB_DESCR_TYPE_IF, -1)) == NULL) {
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2853
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2854
				break;
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2855
			}
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2856
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2857
			rval = usb_parse_data("ccccsccc", buf,
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2858
			    (uintptr_t)bufend - (uintptr_t)buf,
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2859
			    ret_descr, ret_buf_len);
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2860
			usb_find_extra(buf, (uintptr_t)bufend - (uintptr_t)buf,
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2861
			    extra, extralen);
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2862
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2863
			return (rval);
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2864
		}
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2865
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2866
		/*
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2867
		 * Check for a bad buffer.
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2868
		 * If buf[0] is 0, then this will be an infinite loop
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2869
		 */
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2870
		INCREMENT_BUF(buf);
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2871
	}
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2872
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2873
	return (USB_PARSE_ERROR);
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2874
}
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2875
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2876
/*
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2877
 * extra descriptor handling
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2878
 *
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2879
 * usb_find_extra:
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2880
 *	finds any non-standard descriptor after the current
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2881
 *	standard descriptor and puts a pointer in extra argument
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2882
 *	and the length in extralen
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2883
 */
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2884
static	void
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2885
usb_find_extra(uchar_t *buf, size_t buflen,
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2886
    unsigned char **extra, int *extralen)
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2887
{
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2888
	uchar_t *next = buf + buf[0];
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2889
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2890
	*extralen = 0;
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2891
	*extra = next;
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2892
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2893
	while (((uintptr_t)next - (uintptr_t)buf + 1) < buflen) {
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2894
		if ((next[1] == USB_DT_CONFIG) ||
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2895
		    (next[1] == USB_DT_INTERFACE) ||
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2896
		    (next[1] == USB_DT_ENDPOINT)) {
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2897
			*extralen = (int)((uintptr_t)next -
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2898
			    (uintptr_t)buf - buf[0]);
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2899
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2900
			return;
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2901
		}
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2902
		next += next[0];
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2903
	}
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2904
}
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2905
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2906
/*
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2907
 * error handling
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2908
 *
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2909
 * usb_strerror:
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2910
 *	lookup error string
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2911
 *
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2912
 * Returns: error string
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2913
 */
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2914
char *
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2915
usb_strerror(void)
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2916
{
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2917
	usb_dprintf(DEBUG_FUNCTIONS, "usb_strerror(): "
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2918
	    "usb_error_type=%d, errno=%d\n", usb_error_type, usb_error_errno);
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2919
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2920
	switch (usb_error_type) {
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2921
	case USB_ERROR_TYPE_NONE:
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2922
		return ("No error");
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2923
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2924
	case USB_ERROR_TYPE_STRING:
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2925
		return (usb_error_string);
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2926
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2927
	case USB_ERROR_TYPE_ERRNO:
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2928
		if (usb_error_errno > 0) {
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2929
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2930
			return (strerror(usb_error_errno));
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2931
		}
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2932
	default:
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2933
		break;
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2934
	}
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2935
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2936
	return ("Unknown error");
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2937
}
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2938
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2939
/*
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2940
 * usb_error:
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2941
 *	stores the error number in the global usb_error_errno
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2942
 *
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2943
 * Returns: negative error number
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2944
 */
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2945
static int
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2946
usb_error(int x)
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2947
{
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2948
	usb_dprintf(DEBUG_FUNCTIONS, "usb_error(): error=%d\n", x);
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2949
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2950
	usb_error_type = USB_ERROR_TYPE_ERRNO;
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2951
	usb_error_errno = x;
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2952
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2953
	return (-x);
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2954
}
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2955
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2956
/*
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2957
 * usb_error_str:
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2958
 *	creates error string
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2959
 */
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2960
static void
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2961
usb_error_str(int x, char *format, ...)
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2962
{
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2963
	va_list ap;
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2964
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2965
	va_start(ap, format);
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2966
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2967
	usb_error_type = USB_ERROR_TYPE_ERRNO;
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2968
	usb_error_errno = x;
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2969
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2970
	(void) vsnprintf(usb_error_string, sizeof (usb_error_string),
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2971
	    format, ap);
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2972
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2973
	usb_dprintf(DEBUG_ERRORS, "USB error (%d): %s\n", x, usb_error_string);
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2974
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2975
	va_end(ap);
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2976
}
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2977
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2978
/*
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2979
 * usb_dprintf:
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2980
 *	prints out tracing messages according to level
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2981
 */
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2982
static void
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2983
usb_dprintf(int level, char *format, ...)
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2984
{
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2985
	va_list ap;
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2986
	char buf[512];
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2987
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2988
	va_start(ap, format);
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2989
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2990
	(void) vsnprintf(buf, sizeof (buf), format, ap);
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2991
	if (libusb_debug >= level) {
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2992
		(void) fprintf(stderr, buf);
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2993
	}
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2994
	va_end(ap);
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2995
}
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2996
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2997
/*
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2998
 * usb_dump_data:
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  2999
 *	print data buffer
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  3000
 */
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  3001
static void
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  3002
usb_dump_data(char *data, int size)
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  3003
{
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  3004
	int i;
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  3005
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  3006
	if (libusb_debug >= DEBUG_DATA_DUMP) {
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  3007
		(void) fprintf(stderr, "data dump:");
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  3008
		for (i = 0; i < size; i++) {
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  3009
			if (i % 16 == 0) {
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  3010
				(void) fprintf(stderr, "\n%08x	", i);
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  3011
			}
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  3012
			(void) fprintf(stderr, "%02x ", (uchar_t)data[i]);
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  3013
		}
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  3014
		(void) fprintf(stderr, "\n");
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  3015
	}
1fd565334dfc 7043696 libusb should move to userland
Norm Jacobs <Norm.Jacobs@Oracle.COM>
parents:
diff changeset
  3016
}