This file is indexed.

/usr/include/openusb.h is in libopenusb-dev 1.1.0-2.

This file is owned by root:root, with mode 0o644.

The actual contents of the file can be viewed below.

   1
   2
   3
   4
   5
   6
   7
   8
   9
  10
  11
  12
  13
  14
  15
  16
  17
  18
  19
  20
  21
  22
  23
  24
  25
  26
  27
  28
  29
  30
  31
  32
  33
  34
  35
  36
  37
  38
  39
  40
  41
  42
  43
  44
  45
  46
  47
  48
  49
  50
  51
  52
  53
  54
  55
  56
  57
  58
  59
  60
  61
  62
  63
  64
  65
  66
  67
  68
  69
  70
  71
  72
  73
  74
  75
  76
  77
  78
  79
  80
  81
  82
  83
  84
  85
  86
  87
  88
  89
  90
  91
  92
  93
  94
  95
  96
  97
  98
  99
 100
 101
 102
 103
 104
 105
 106
 107
 108
 109
 110
 111
 112
 113
 114
 115
 116
 117
 118
 119
 120
 121
 122
 123
 124
 125
 126
 127
 128
 129
 130
 131
 132
 133
 134
 135
 136
 137
 138
 139
 140
 141
 142
 143
 144
 145
 146
 147
 148
 149
 150
 151
 152
 153
 154
 155
 156
 157
 158
 159
 160
 161
 162
 163
 164
 165
 166
 167
 168
 169
 170
 171
 172
 173
 174
 175
 176
 177
 178
 179
 180
 181
 182
 183
 184
 185
 186
 187
 188
 189
 190
 191
 192
 193
 194
 195
 196
 197
 198
 199
 200
 201
 202
 203
 204
 205
 206
 207
 208
 209
 210
 211
 212
 213
 214
 215
 216
 217
 218
 219
 220
 221
 222
 223
 224
 225
 226
 227
 228
 229
 230
 231
 232
 233
 234
 235
 236
 237
 238
 239
 240
 241
 242
 243
 244
 245
 246
 247
 248
 249
 250
 251
 252
 253
 254
 255
 256
 257
 258
 259
 260
 261
 262
 263
 264
 265
 266
 267
 268
 269
 270
 271
 272
 273
 274
 275
 276
 277
 278
 279
 280
 281
 282
 283
 284
 285
 286
 287
 288
 289
 290
 291
 292
 293
 294
 295
 296
 297
 298
 299
 300
 301
 302
 303
 304
 305
 306
 307
 308
 309
 310
 311
 312
 313
 314
 315
 316
 317
 318
 319
 320
 321
 322
 323
 324
 325
 326
 327
 328
 329
 330
 331
 332
 333
 334
 335
 336
 337
 338
 339
 340
 341
 342
 343
 344
 345
 346
 347
 348
 349
 350
 351
 352
 353
 354
 355
 356
 357
 358
 359
 360
 361
 362
 363
 364
 365
 366
 367
 368
 369
 370
 371
 372
 373
 374
 375
 376
 377
 378
 379
 380
 381
 382
 383
 384
 385
 386
 387
 388
 389
 390
 391
 392
 393
 394
 395
 396
 397
 398
 399
 400
 401
 402
 403
 404
 405
 406
 407
 408
 409
 410
 411
 412
 413
 414
 415
 416
 417
 418
 419
 420
 421
 422
 423
 424
 425
 426
 427
 428
 429
 430
 431
 432
 433
 434
 435
 436
 437
 438
 439
 440
 441
 442
 443
 444
 445
 446
 447
 448
 449
 450
 451
 452
 453
 454
 455
 456
 457
 458
 459
 460
 461
 462
 463
 464
 465
 466
 467
 468
 469
 470
 471
 472
 473
 474
 475
 476
 477
 478
 479
 480
 481
 482
 483
 484
 485
 486
 487
 488
 489
 490
 491
 492
 493
 494
 495
 496
 497
 498
 499
 500
 501
 502
 503
 504
 505
 506
 507
 508
 509
 510
 511
 512
 513
 514
 515
 516
 517
 518
 519
 520
 521
 522
 523
 524
 525
 526
 527
 528
 529
 530
 531
 532
 533
 534
 535
 536
 537
 538
 539
 540
 541
 542
 543
 544
 545
 546
 547
 548
 549
 550
 551
 552
 553
 554
 555
 556
 557
 558
 559
 560
 561
 562
 563
 564
 565
 566
 567
 568
 569
 570
 571
 572
 573
 574
 575
 576
 577
 578
 579
 580
 581
 582
 583
 584
 585
 586
 587
 588
 589
 590
 591
 592
 593
 594
 595
 596
 597
 598
 599
 600
 601
 602
 603
 604
 605
 606
 607
 608
 609
 610
 611
 612
 613
 614
 615
 616
 617
 618
 619
 620
 621
 622
 623
 624
 625
 626
 627
 628
 629
 630
 631
 632
 633
 634
 635
 636
 637
 638
 639
 640
 641
 642
 643
 644
 645
 646
 647
 648
 649
 650
 651
 652
 653
 654
 655
 656
 657
 658
 659
 660
 661
 662
 663
 664
 665
 666
 667
 668
 669
 670
 671
 672
 673
 674
 675
 676
 677
 678
 679
 680
 681
 682
 683
 684
 685
 686
 687
 688
 689
 690
 691
 692
 693
 694
 695
 696
 697
 698
 699
 700
 701
 702
 703
 704
 705
 706
 707
 708
 709
 710
 711
 712
 713
 714
 715
 716
 717
 718
 719
 720
 721
 722
 723
 724
 725
 726
 727
 728
 729
 730
 731
 732
 733
 734
 735
 736
 737
 738
 739
 740
 741
 742
 743
 744
 745
 746
 747
 748
 749
 750
 751
 752
 753
 754
 755
 756
 757
 758
 759
 760
 761
 762
 763
 764
 765
 766
 767
 768
 769
 770
 771
 772
 773
 774
 775
 776
 777
 778
 779
 780
 781
 782
 783
 784
 785
 786
 787
 788
 789
 790
 791
 792
 793
 794
 795
 796
 797
 798
 799
 800
 801
 802
 803
 804
 805
 806
 807
 808
 809
 810
 811
 812
 813
 814
 815
 816
 817
 818
 819
 820
 821
 822
 823
 824
 825
 826
 827
 828
 829
 830
 831
 832
 833
 834
 835
 836
 837
 838
 839
 840
 841
 842
 843
 844
 845
 846
 847
 848
 849
 850
 851
 852
 853
 854
 855
 856
 857
 858
 859
 860
 861
 862
 863
 864
 865
 866
 867
 868
 869
 870
 871
 872
 873
 874
 875
 876
 877
 878
 879
 880
 881
 882
 883
 884
 885
 886
 887
 888
 889
 890
 891
 892
 893
 894
 895
 896
 897
 898
 899
 900
 901
 902
 903
 904
 905
 906
 907
 908
 909
 910
 911
 912
 913
 914
 915
 916
 917
 918
 919
 920
 921
 922
 923
 924
 925
 926
 927
 928
 929
 930
 931
 932
 933
 934
 935
 936
 937
 938
 939
 940
 941
 942
 943
 944
 945
 946
 947
 948
 949
 950
 951
 952
 953
 954
 955
 956
 957
 958
 959
 960
 961
 962
 963
 964
 965
 966
 967
 968
 969
 970
 971
 972
 973
 974
 975
 976
 977
 978
 979
 980
 981
 982
 983
 984
 985
 986
 987
 988
 989
 990
 991
 992
 993
 994
 995
 996
 997
 998
 999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
#ifndef __OPENUSB_H__
#define __OPENUSB_H__

/*
 * Prototypes, structure definitions and macros.
 *
 * Copyright 2000-2005 Johannes Erdfelt <johannes@erdfelt.com>
 *
 * Copyright 2004-2007 Sun Microsystems, Inc.  All rights reserved.
 * Use is subject to license terms.
 *
 * This file (and only this file) may alternatively be licensed under the
 * BSD license as well, read LICENSE for details.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 * 3. The name of the author may not be used to endorse or promote products
 *    derived from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#ifdef __cplusplus
extern "C" {
#endif

#include <inttypes.h>
#include <unistd.h>
#include <stdlib.h>
#include <limits.h>
#include <stdio.h>
#include <stdarg.h>

/*
 *********************************************************************
 * USB spec information
 *
 * This is all stuff grabbed from various USB specs and is pretty much
 * not subject to change
 *********************************************************************
 */

/*
 * Device and/or Interface Class codes
 */
#define	USB_CLASS_PER_INTERFACE		0	/* for DeviceClass */
#define	USB_CLASS_AUDIO			1
#define	USB_CLASS_COMM			2
#define	USB_CLASS_HID			3
#define	USB_CLASS_PHYSICAL		5
#define	USB_CLASS_STILL_IMAGE		6
#define	USB_CLASS_PRINTER		7
#define	USB_CLASS_MASS_STORAGE		8
#define	USB_CLASS_HUB			9
#define	USB_CLASS_CDC_DATA		10
#define	USB_CLASS_SMART_CARD		11
#define	USB_CLASS_CONT_SECURITY		13
#define	USB_CLASS_VIDEO			14
#define	USB_CLASS_DIAGNOSTIC		0xdc

#ifndef USB_CLASS_WIRELESS
#define	USB_CLASS_WIRELESS		0xe0
#endif

#ifndef USB_CLASS_MISC
#define	USB_CLASS_MISC			0xef
#endif

#define	USB_CLASS_APP_SPEC		0xfe

#ifndef USB_CLASS_VENDOR_SPEC
#define	USB_CLASS_VENDOR_SPEC		0xff
#endif

/*
 * Descriptor types
 */
#define	USB_DESC_TYPE_DEVICE			0x01
#define	USB_DESC_TYPE_CONFIG			0x02
#define	USB_DESC_TYPE_STRING			0x03
#define	USB_DESC_TYPE_INTERFACE			0x04
#define	USB_DESC_TYPE_ENDPOINT			0x05
#define	USB_DESC_TYPE_DEVICE_QUALIFIER		0x06
#define	USB_DESC_TYPE_OTHER_SPEED_CONFIG	0x07
#define	USB_DESC_TYPE_INTERFACE_POWER		0x08
#define	USB_DESC_TYPE_OTG			0x09
#define	USB_DESC_TYPE_DEBUG			0x0a
#define	USB_DESC_TYPE_INTERFACE_ASSOCIATION	0x0b

/* Device descriptor */
typedef struct usb_device_desc {
	uint8_t		bLength;
	uint8_t		bDescriptorType;
	uint16_t	bcdUSB;
	uint8_t		bDeviceClass;
	uint8_t		bDeviceSubClass;
	uint8_t		bDeviceProtocol;
	uint8_t		bMaxPacketSize0;
	uint16_t	idVendor;
	uint16_t	idProduct;
	uint16_t	bcdDevice;
	uint8_t		iManufacturer;
	uint8_t		iProduct;
	uint8_t		iSerialNumber;
	uint8_t		bNumConfigurations;
} usb_device_desc_t;

/* Configuration & other speed configuration descriptor */
typedef struct usb_config_desc {
	uint8_t		bLength;
	uint8_t		bDescriptorType;
	uint16_t	wTotalLength;
	uint8_t		bNumInterfaces;
	uint8_t		bConfigurationValue;
	uint8_t		iConfiguration;
	uint8_t		bmAttributes;
	uint8_t		bMaxPower;
} usb_config_desc_t;

/* bmAttributes for configuration desc */
#define	USB_CFG_ATTR_SELFPWR		0x40
#define	USB_CFG_ATTR_REMOTE_WAKEUP	0x20

/* Interface descriptor */
typedef struct usb_interface_desc {
	uint8_t		bLength;
	uint8_t		bDescriptorType;
	uint8_t		bInterfaceNumber;
	uint8_t		bAlternateSetting;
	uint8_t		bNumEndpoints;
	uint8_t		bInterfaceClass;
	uint8_t		bInterfaceSubClass;
	uint8_t		bInterfaceProtocol;
	uint8_t		iInterface;
} usb_interface_desc_t;

/* Endpoint descriptor */
typedef struct usb_endpoint_desc {
	uint8_t		bLength;
	uint8_t		bDescriptorType;
	uint8_t		bEndpointAddress;
	uint8_t		bmAttributes;
	uint16_t	wMaxPacketSize;
	uint8_t		bInterval;
	uint8_t		bRefresh; /* AC Int EP */
	uint8_t		bSynchAddress; /* AC Int EP */
} usb_endpoint_desc_t;

/* bEndpointAddress for endpoint desc */
#define	USB_ENDPOINT_NUM_MASK		0x0f	/* endpoint number mask */
#define	USB_ENDPOINT_DIR_MASK		0x80	/* direction mask */
#define	USB_ENDPOINT_IN			0x80	/* IN endpoint */
#define	USB_ENDPOINT_OUT		0x00	/* OUT endpoint */

/* bmAttributes for endpoint desc */
#define	USB_ENDPOINT_TYPE_MASK		0x03	/* transfer type mask */

#ifndef USB_ENDPOINT_TYPE_CONTROL

#define	USB_ENDPOINT_TYPE_CONTROL	0x00	/* control transfer */
#define	USB_ENDPOINT_TYPE_ISOCHRONOUS	0x01	/* isochronous transfer */
#define	USB_ENDPOINT_TYPE_BULK		0x02	/* bulk transfer */
#define	USB_ENDPOINT_TYPE_INTERRUPT	0x03	/* interrupt transfer */

#endif

#define	USB_ENDPOINT_SYNC_MASK		0x0c	/* synchronization mask */
#define	USB_ENDPOINT_SYNC_NONE		0x00	/* no synchronization */
#define	USB_ENDPOINT_SYNC_ASYNC		0x04	/* asynchronous */
#define	USB_ENDPOINT_SYNC_ADPT		0x08	/* adaptive */
#define	USB_ENDPOINT_SYNC_SYNC		0x0c	/* synchronous */

#define	USB_ENDPOINT_USAGE_MASK		0x30	/* sync feedback mask */
#define	USB_ENDPOINT_USAGE_DATA		0x00	/* data endpoint */
#define	USB_ENDPOINT_USAGE_FEED		0x10	/* feedback endpoint */
#define	USB_ENDPOINT_USAGE_IMPL_FEED	0x20	/* implicit feedback ep */

/* wMaxPacketSize for endpoint desc */
#define	USB_ENDPOINT_MAX_PKTSZ_MASK	0x03ff	/* Mask for packetsize bits */
#define	USB_ENDPOINT_MAX_XACTS_MASK	0x0c00	/* Max Transactns/microframe */
#define	USB_ENDPOINT_MAX_XACTS_SHIFT	11	/* 11 bits from end */

/* String descriptor of index zero */
typedef struct usb_string_desc_zero {
	uint8_t		bLength;
	uint8_t		bDescriptorType;
	uint16_t	wLANGID[];	/* flexible array member */
} usb_string_desc_zero_t;

/* UNICODE String descriptor */
typedef struct usb_string_desc {
	uint8_t		bLength;
	uint8_t		bDescriptorType;
	uint16_t	bString[];	/* flexible array member */
} usb_string_desc_t;

/* Device qualifier descriptor */
typedef struct usb_device_qualif_desc {
	uint8_t		bLength;
	uint8_t		bDescriptorType;
	uint16_t	bcdUSB;
	uint8_t		bDeviceClass;
	uint8_t		bDeviceSubClass;
	uint8_t		bDeviceProtocol;
	uint8_t		bMaxPacketSize0;
	uint8_t		bNumConfigurations;
	uint8_t		bReserved;
} usb_device_qualif_desc_t;

/* OTG descriptor */
typedef struct usb_otg_desc {
	uint8_t		bLength;
	uint8_t		bDescriptorType;
	uint8_t		bmAttributes;
} usb_otg_desc_t;

/* bmAttributes for OTG desc */
#define	USB_OTG_SRP			0x00
#define	USB_OTG_HNP			0x01

/* Debug descriptor */
typedef struct usb_debug_desc {
	uint8_t		bLength;
	uint8_t		bDescriptorType;
	uint8_t		bDebugInEndpoint;
	uint8_t		bDebugOutEndpoint;
} usb_debug_desc_t;

/* Interface association descriptor */
typedef struct usb_interface_association_desc {
	uint8_t		bLength;
	uint8_t		bDescriptorType;
	uint8_t		bFirstInterface;
	uint8_t		bInterfaceCount;
	uint8_t		bFunctionClass;
	uint8_t		bFunctionSubClass;
	uint8_t		bFunctionProtocol;
	uint8_t		iFunction;
} usb_interface_association_desc_t;

/*
 * Standard requests
 */
#define	USB_REQ_GET_STATUS		0x00
#define	USB_REQ_CLEAR_FEATURE		0x01
/* 0x02 is reserved */
#define	USB_REQ_SET_FEATURE		0x03
/* 0x04 is reserved */
#define	USB_REQ_SET_ADDRESS		0x05
#define	USB_REQ_GET_DESCRIPTOR		0x06
#define	USB_REQ_SET_DESCRIPTOR		0x07
#define	USB_REQ_GET_CONFIGURATION	0x08
#define	USB_REQ_SET_CONFIGURATION	0x09

#ifndef USB_REQ_GET_INTERFACE

#define	USB_REQ_GET_INTERFACE		0x0a
#define	USB_REQ_SET_INTERFACE		0x0b
#define	USB_REQ_SYNCH_FRAME		0x0c

#endif

/* Bitmaps for bmRequestType */
#define	USB_REQ_HOST_TO_DEV		0x00
#define	USB_REQ_DEV_TO_HOST		0x80
#define	USB_REQ_DIR_MASK		0x80

#define	USB_REQ_TYPE_STANDARD		(0x00 << 5)
#define	USB_REQ_TYPE_CLASS		(0x01 << 5)
#define	USB_REQ_TYPE_VENDOR		(0x02 << 5)
#define	USB_REQ_TYPE_RESERVED		(0x03 << 5)
#define	USB_REQ_TYPE_MASK		0x60

#define	USB_REQ_RECIP_DEVICE		0x00
#define	USB_REQ_RECIP_INTERFACE		0x01
#define	USB_REQ_RECIP_ENDPOINT		0x02
#define	USB_REQ_RECIP_OTHER		0x03
#define	USB_REQ_RECIP_MASK		0x1f

/* Feature selector */
#define	USB_FEATURE_EP_HALT		0
#define	USB_FEATURE_DEV_REMOTE_WAKEUP	1

/* Bits returned by GET_STATUS request */
#define	USB_DEVICE_STATUS_SELFPWR	0x0001
#define	USB_DEVICE_STATUS_REMOTE_WAKEUP	0x0002
#define	USB_ENDPOINT_STATUS_HALT	0x0001


/*
 ************************************************************
 * All openusb functions return an OS independent error code
 * (ie. no OS specific errno).
 * XXX more will be added during the implementation
 ************************************************************
 */
#define	OPENUSB_SUCCESS			0	/* Call success */
#define	OPENUSB_PLATFORM_FAILURE		-1	/* Unspecified kernel/driver failure */
#define	OPENUSB_NO_RESOURCES		-2	/* No resources available */
#define	OPENUSB_NO_BANDWIDTH		-3	/* No bandwidth available */
#define	OPENUSB_NOT_SUPPORTED		-4	/* Not supported by HCD */
#define	OPENUSB_HC_HARDWARE_ERROR	-5	/* USB host controller error */
#define	OPENUSB_INVALID_PERM		-6	/* Privileged operation */
#define	OPENUSB_BUSY			-7	/* Busy condition */
#define	OPENUSB_BADARG			-8	/* Invalid parameter */
#define	OPENUSB_NOACCESS			-9	/* Access to device denied */
#define	OPENUSB_PARSE_ERROR		-10	/* Data could not be parsed */
#define	OPENUSB_UNKNOWN_DEVICE		-11	/* Device id is stale or invalid */
#define	OPENUSB_INVALID_HANDLE		-12	/* Handle is invalid */
#define	OPENUSB_SYS_FUNC_FAILURE		-13	/* Call other system function failed */
#define	OPENUSB_NULL_LIST		-14	/* Can not find bus or device */

/* return values for asynchronous transfer callback function */
#define	OPENUSB_CB_CONTINUE		-20	/* Continue with next request */
#define	OPENUSB_CB_TERMINATE		-21	/* Stop doing next request */

#define	OPENUSB_IO_STALL			-50	/* Endpoint stalled */
#define	OPENUSB_IO_CRC_ERROR		-51	/* CRC error */
#define	OPENUSB_IO_DEVICE_HUNG		-52	/* Device hung */
#define	OPENUSB_IO_REQ_TOO_BIG		-53	/* Request too big */
#define	OPENUSB_IO_BIT_STUFFING		-54	/* Bit stuffing error */
#define	OPENUSB_IO_UNEXPECTED_PID	-55	/* Unexpected PID */
#define	OPENUSB_IO_DATA_OVERRUN		-56	/* Data overrun */
#define	OPENUSB_IO_DATA_UNDERRUN		-57	/* Data underrun */
#define	OPENUSB_IO_BUFFER_OVERRUN	-58	/* Buffer overrun */
#define	OPENUSB_IO_BUFFER_UNDERRUN	-59	/* Buffer underrun */
#define	OPENUSB_IO_PID_CHECK_FAILURE	-60	/* PID check failure */
#define	OPENUSB_IO_DATA_TOGGLE_MISMATCH	-61	/* Data toggle mismatch */
#define	OPENUSB_IO_TIMEOUT		-62	/* I/O timeout */
#define	OPENUSB_IO_CANCELED		-63 	/* I/O was canceled */


/*
 ********************************
 * Library specific data types
 ********************************
 */

typedef uint64_t openusb_devid_t; /* every devices in the USB bus has a devid */
typedef uint64_t openusb_busid_t; /* every bus in a USB host has a busid */
typedef uint64_t openusb_handle_t; /* every openusb instance has a lib handle */
typedef uint64_t openusb_dev_handle_t;/* every OPENED USB device has a handle */

typedef enum openusb_event {
	USB_ATTACH = 0,
	USB_REMOVE,
	USB_SUSPEND,
	USB_RESUME,
	USB_HC_ATTACH,
	USB_HC_REMOVE,
	USB_COLDPLUG_COMPLETED,
} openusb_event_t;

#define	OPENUSB_EVENT_TYPE_COUNT		7

typedef enum openusb_transfer_type {
	USB_TYPE_ALL = 0,
	USB_TYPE_CONTROL,
	USB_TYPE_INTERRUPT,
	USB_TYPE_BULK,
	USB_TYPE_ISOCHRONOUS,
	USB_TYPE_LAST
} openusb_transfer_type_t;

typedef void	(*openusb_event_callback_t)(openusb_handle_t handle,
	openusb_devid_t devid, openusb_event_t event, void *arg);

typedef void	(*openusb_debug_callback_t)(openusb_handle_t handle,
	const char *fmt, va_list args);

typedef struct openusb_dev_data {
	openusb_busid_t		busid;
	openusb_devid_t		devid;
	uint8_t			bus_address;

	/* parent device id, 0 for root-hub */
	openusb_devid_t		pdevid;

	/* parent port the device is connected to */
	uint8_t			pport;

	/* number of ports on the device, 0 for non-hub device */
	uint8_t			nports;

	/* descriptive path such as /dev/bus/usb/xxx */
	char			*sys_path;

	/* topological path such as 1.2.1 */
	char			*bus_path;

	usb_device_desc_t	dev_desc;
	usb_config_desc_t	cfg_desc;

	/* raw configuration desc cloud */
	uint8_t			*raw_cfg_desc;
  
	/* string descriptors with the first langid */
	usb_string_desc_t	*manufacturer;
	usb_string_desc_t	*product;
	usb_string_desc_t	*serialnumber;

	/* max transfer size for each request, 0 if not supported */
	uint32_t		ctrl_max_xfer_size;
	uint32_t		intr_max_xfer_size;
	uint32_t		bulk_max_xfer_size;
	uint32_t		isoc_max_xfer_size;
} openusb_dev_data_t;

/* Data types for I/O */

typedef struct openusb_request_result {
	int32_t			status;
	uint32_t		transferred_bytes;
} openusb_request_result_t;

typedef struct openusb_ctrl_request {
	struct openusb_ctrl_setup {
		uint8_t		bmRequestType;
		uint8_t		bRequest;
		uint16_t	wValue;
		uint16_t	wIndex;

		/* wLength set automatically based on length */
	} setup;

	uint8_t			*payload;
	uint32_t		length; /* platform endian */
	uint32_t		timeout;
	uint32_t		flags;
	openusb_request_result_t	result;
	struct openusb_ctrl_request	*next;
} openusb_ctrl_request_t;

typedef struct openusb_intr_request {
	uint16_t		interval;	/* may not work on some OS */
	uint8_t			*payload;
	uint32_t		length;
	uint32_t		timeout;
	uint32_t		flags;
	openusb_request_result_t	result;
	struct openusb_intr_request	*next;
} openusb_intr_request_t;

typedef struct openusb_bulk_request {
	uint8_t			*payload;
	uint32_t		length;
	uint32_t		timeout;
	uint32_t		flags;
	openusb_request_result_t	result;
	struct openusb_bulk_request	*next;
} openusb_bulk_request_t;

typedef struct openusb_isoc_pkts {
	uint32_t		num_packets;
	struct openusb_isoc_packet {
		uint8_t		*payload;
		uint32_t	length;
	} *packets;
} openusb_isoc_pkts_t;

typedef struct openusb_isoc_request {
	uint32_t		start_frame;
	uint32_t		flags;
	openusb_isoc_pkts_t	pkts;

	/* pointer to isoc result array */
	openusb_request_result_t	*isoc_results;

	/* overall isoc transfer completion status */
	int32_t			isoc_status;

	struct openusb_isoc_request	*next;
} openusb_isoc_request_t;

struct openusb_request_handle {
	openusb_dev_handle_t	dev;
	uint8_t			interface;	/* ignored for ep0 */
	uint8_t			endpoint;
	openusb_transfer_type_t	type;

	union openusb_request {
		openusb_ctrl_request_t	*ctrl;
		openusb_intr_request_t	*intr;
		openusb_bulk_request_t	*bulk;
		openusb_isoc_request_t	*isoc;
	} req;

	int32_t	(*cb)(struct openusb_request_handle *handle);
	void	*arg;	/* additional arg for callback */
};

typedef struct openusb_request_handle *openusb_request_handle_t;

/* flags for opening device and claiming interface */
typedef enum openusb_init_flag {
	USB_INIT_DEFAULT = 0,
	USB_INIT_FAIL_FAST,	 /* fail if not immediately available */
	USB_INIT_REVERSIBLE,	 /* try platform dependent things that are */
				 /* guaranteed to be reversed on close */
	USB_INIT_NON_REVERSIBLE, /* try advanced platform dependent */
				 /* things that may not be guaranteed */
				 /* to be reversible on close */
} openusb_init_flag_t;

/* Max length for device path of topological depiction */
#define	OPENUSB_BUS_PATH_MAX		28

/*
 ****************************************
 * Library function prototypes
 ****************************************
 */

/*
 *  openusb_init()
 *
 *   Arguments:
 *	flags           - TBD
 *	handle          - Libusb handle
 *   Return Values:
 *	OPENUSB_SUCCESS
 *	OPENUSB_PLATFORM_FAILURE - Unspecified kernel/driver failure
 *	OPENUSB_BADARG           - Invalid structure data
 *	OPENUSB_NO_RESOURCES     - Memory allocation failures
 *
 *   Notes:
 *	This function must be called before any other openusb function, and
 *	it returns one openusb handle upon each call
 */
int32_t openusb_init(uint32_t flags, openusb_handle_t *handle);

/*
 * Cleanup resources:
 *
 *  openusb_fini()
 *
 *   Arguments:
 *	handle          - Libusb handle
 *   Return Values:
 *	none
 *
 *   Notes:
 *	This function must be called at the end of each openusb application.
 *	Each call to openusb_init() needs a call to openusb_fini()
 */
void openusb_fini(openusb_handle_t handle);

/*
 * Register with openusb framework for event callbacks:
 *
 *  openusb_set_event_callback()  ........... Set event callback
 *
 *   Arguments:
 *	handle          - Libusb handle
 *	type            - Event type
 *	callback        - Pointer to event callback handler or NULL to unset
 *	arg             - User specified argument
 *
 *   Return Values:
 *	OPENUSB_SUCCESS
 *	OPENUSB_BADARG           - Invalid structure data
 *	OPENUSB_NO_RESOURCES     - Memory allocation failures
 */
int32_t openusb_set_event_callback(openusb_handle_t handle,
	openusb_event_t type,
	openusb_event_callback_t callback, void *arg);

/*
 * Block until end of coldplug events:
 *
 *  openusb_coldplug_callbacks_done()
 *
 *   Arguments:
 *	handle          - Libusb handle
 *
 *   Return Values:
 *	none
 *
 *   Notes:
 *	For MT applications that can handle coldplug events and need to
 *	know end of the events
 */
void openusb_coldplug_callbacks_done(openusb_handle_t handle);

/*
 *  openusb_set_debug() ............... Specify debug level
 *
 *   Arguments:
 *	handle          - Libusb handle
 *	level		- Debug level
 *	flags		- TBD
 *	callback	- Callback for user defined debug function
 *			  If NULL, the library embedded debug function is
 *			  is used and the messages will go to stderr
 *
 *   Return Values:
 *	none
 *
 * Notes:
 *	This function enables tracing of openusb with increasing level of detail
 */
void openusb_set_debug(openusb_handle_t handle, uint32_t level,
	uint32_t flags, openusb_debug_callback_t callback);

/*
 * Set default timeout:
 *
 *  openusb_set_default_timeout() .. Set default timeout for a request type
 *
 *   Arguments:
 *	handle          - Libusb handle
 *	type            - Type of transfer
 *	timeout         - Timeout in milliseconds (0 == infinite)
 *
 *   Return Values:
 *	OPENUSB_SUCCESS
 *	OPENUSB_UNKNOWN_DEVICE   - Bus id or device id is no longer valid
 *	OPENUSB_NO_RESOURCES     - Memory allocation failures
 *	OPENUSB_IO_*             - USB host controller errors
 */
int32_t openusb_set_default_timeout(openusb_handle_t handle,
	openusb_transfer_type_t type, uint32_t timeout);

/*
 * Endianness conversion functions:
 *
 *  openusb_le16_to_cpu() ..... Convert LE 16 bit quantity to CPU endianess
 *  openusb_le32_to_cpu() ..... Convert LE 32 bit quantity to CPU endianess
 *
 *   Arguments:
 *	data        - Data to be converted
 *
 *   Return Values  - Converted data
 */
inline uint16_t openusb_le16_to_cpu(uint16_t data);
inline uint32_t openusb_le32_to_cpu(uint32_t data);
#define	openusb_cpu_to_le16	openusb_le16_to_cpu
#define	openusb_cpu_to_le32	openusb_le32_to_cpu

/*
 *  openusb_strerror() ........ Return english text representation of error code
 *
 *   Arguments:
 *	error       - Error code
 *
 *   Return Values  - Pointer to english text representation
 */
const char *openusb_strerror(int32_t error);

/* 
 * Unpack arbitrary little endian data (ie. descriptors)
 *  
 *  openusb_parse_data() 
 *
 *   Arguments:
 *	format          - String indicating the format in b, w, d, eg. "2b4dw"
 *                        which describes 2 bytes, 4 dwords, one word.
 *                        A byte (b) is 8-bits, word (w) is 16-bits,
 *                        dword (w) is 32-bits. The character '.' skips one
 *                        byte in the source. The number prefix indicates
 *                        the number of items of the subsequent type.
 *	data            - Pointer to the LE data buffer
 *	datalen         - Length of the data
 *	structure       - Pointer to return structure where the unpacked data
 *                        will be written
 *	structlen       - Length of the return structure
 *	count           - Number of bytes parsed
 *
 *   Return Values:
 *	OPENUSB_SUCCESS
 *	OPENUSB_PARSE_ERROR      - Data could not be parsed successfully
 *
 *   Notes:
 *	for example to parse a descriptor such as:
 *	struct {
 *              uint8_t         a;
 *              uint16_t        b;
 *              uint8_t         c;
 *              uint32_t        d;
 *	};
 *
 * the application would call:
 *
 *	rv = openusb_parse_data("bwbd", buffer, sizeof (buffer),
 *              (void *)my_descr, sizeof (my_descr), &count);
 *
 * this would result in inserting some padding to align structure
 * members on natural boundaries (this is necessary on some processors such
 * as SPARC). If you would dump memory of this structure on SPARC, you would
 * see this:
 *              uint8_t         a;
 *              uint8_t         unused;
 *              uint16_t        b;
 *              uint8_t         c;
 *              uint8_t         unused[3];
 *              uint32_t        d;
 */
int32_t openusb_parse_data(char *format, uint8_t *data, uint32_t datalen,
	void *structure, uint32_t structlen, uint32_t *count);

/*
 * Functions for searching busses:
 *
 *  openusb_get_busid_list() ........... Return all busids in unordered list
 *  openusb_free_busid_list() .......... Free the returned buffer for busids
 *
 *   Arguments:
 *	handle           - Libusb handle
 *	busids           - Pointer to address of the busid list
 *	num_busids       - Number of bus ids in the list
 *
 *   Return Values:
 *	OPENUSB_SUCCESS
 *	OPENUSB_NO_RESOURCES     - Memory allocation failures
 */
int32_t openusb_get_busid_list(openusb_handle_t handle, openusb_busid_t **busids,
	uint32_t *num_busids);
void openusb_free_busid_list(openusb_busid_t *busids);

/*
 * Functions for searching devices:
 *
 *  openusb_get_devids_by_bus() .......... Return all devids on a bus, the
 *                                        first devid in the list is root-hub;
 *                                        or return all devids on all busses
 *                                        if busid equals 0
 *  openusb_get_devids_by_vendor() ....... Match on vid, pid
 *  openusb_get_devids_by_class() ........ Match on class, subclass, protocol
 *  openusb_free_devid_list() ............ Free the devid list returned above
 *   
 *   Arguments:
 *	handle           - Libusb handle
 *	busid            - Which bus (0 all busses)
 *	vendor           - Vendor id (0 - 0xffff, -1 for all)
 *	product          - Product id (0 - 0xffff, -1 for all)
 *	devclass         - Device class (0 - 0xff, -1 for all)
 *	subclass         - Subclass (0 - 0xff, -1 for all)
 *	protocol         - Protocol (0 - 0xff, -1 for all)
 *	devids           - Pointer to address of the devid list
 *	num_devids       - Number of device ids in the list
 *   
 *   Return Values:
 *	OPENUSB_SUCCESS
 *	OPENUSB_NO_RESOURCES     - Memory allocation failures
 */ 
int32_t openusb_get_devids_by_bus(openusb_handle_t handle, openusb_busid_t busid,
	openusb_devid_t **devids, uint32_t *num_devids);
int32_t openusb_get_devids_by_vendor(openusb_handle_t handle, int32_t vendor,
	int32_t product, openusb_devid_t **devids, uint32_t *num_devids);
int32_t openusb_get_devids_by_class(openusb_handle_t handle, int16_t devclass,
	int16_t subclass, int16_t protocol, openusb_devid_t **devids,
	uint32_t *num_devids);
void openusb_free_devid_list(openusb_devid_t *devids);

/*
 * Get device data:
 *
 *  openusb_get_device_data()
 *
 *   Arguments:
 *	handle           - Libusb handle
 *	devid            - Device id
 *	flags            - TBD
 *	data             - Pointer to device data
 *
 *   Return Values:
 *	OPENUSB_SUCCESS
 *	OPENUSB_UNKNOWN_DEVICE   - Device id is no longer valid
 *	OPENUSB_NO_RESOURCES     - Memory allocation failures
 *	OPENUSB_IO_*             - USB host controller errors
 *
 *   Notes:
 *	The data buffer is allocated by openusb
 */
int32_t openusb_get_device_data(openusb_handle_t handle, openusb_devid_t devid,
	uint32_t flags, openusb_dev_data_t **data);

/*
 * Free device data:
 *
 *  openusb_free_device_data()
 *
 *   Arguments:
 *	data             - Pointer to device data
 *
 *   Return Values:
 *	none
 */
void openusb_free_device_data(openusb_dev_data_t *data);

/*
 * Get child ID  (return ID of device at specified hub port):
 *
 *  openusb_get_child_devid()
 *
 *   Arguments:
 *	handle           - Libusb handle
int32_t openusb_get_child_devid(openusb_handle_t handle,
	openusb_devid_t hub_devid, uint8_t port,
	openusb_devid_t *child_devid);
*/

/*
 * Descriptor accessors:
 *
 * Getting standard descriptors from device
 *  openusb_get_raw_desc() ........ Return a buffer that contains raw desc.
 *  openusb_free_raw_desc() ....... Free the raw desc. buffer
 *
 * These are for parsing the raw descriptors getting above
 *  openusb_parse_device_desc() ......... Get cooked device desc.
 *  openusb_parse_config_desc() ......... Get cooked configuration desc.
 *  openusb_parse_interface_desc() ...... Get cooked interface desc.
 *  openusb_parse_endpoint_desc() ....... Get cooked endpoint desc.
 *
 *   Arguments:
 *	handle           - Libusb handle
 *	devid            - Device id
 *	type             - descriptor type
 *	descidx          - index for config/string desc., zero for others
 *	langid           - language ID for string desc., zero for others
 *	buffer           - Data buffer for raw desc.
 *	buflen           - Length of raw desc.
 *	devdesc          - Pointer to device desc.
 *	cfgidx           - Configuration index
 *	cfgdesc          - Pointer to configuration desc.
 *	ifcidx           - Interface index
 *	alt              - Alternate setting number
 *	ifcdesc          - Pointer to interface desc.
 *	eptidx           - Endpoint index
 *	eptdesc          - Pointer to endpoint desc.
 *
 *   Return Values:
 *	OPENUSB_SUCCESS
 *	OPENUSB_PLATFORM_FAILURE - Unspecified kernel/driver failure
 *	OPENUSB_UNKNOWN_DEVICE   - Bus id or device id is no longer valid
 *	OPENUSB_NO_RESOURCES     - Memory allocation failures
 *	OPENUSB_IO_*             - USB host controller errors
 *
 *   Notes:
 *	openusb_get_raw_desc() should be called before one can
 *	get cooked descriptors. And the raw data buffer and buflen
 *	are then passed to the parsing functions. The buffer passed
 *	for getting cooked interface desc and endpoint desc is the
 *	raw configuration desc buffer.
 *	The parsing functions also accept NULL buffer pointer, in which
 *	case user doesn't need to call openusb_get_raw_desc() beforehand,
 *	the parsing functions would do that internally.
 */
int32_t openusb_get_raw_desc(openusb_handle_t handle,
	openusb_devid_t devid, uint8_t type, uint8_t descidx,
	uint16_t langid, uint8_t **buffer, uint16_t *buflen);
void openusb_free_raw_desc(uint8_t *buffer);
int32_t openusb_parse_device_desc(openusb_handle_t handle,
	openusb_devid_t devid, uint8_t *buffer, uint16_t buflen,
	usb_device_desc_t *devdesc);
int32_t openusb_parse_config_desc(openusb_handle_t handle,
	openusb_devid_t devid, uint8_t *buffer, uint16_t buflen,
	uint8_t cfgidx, usb_config_desc_t *cfgdesc);
int32_t openusb_parse_interface_desc(openusb_handle_t handle,
	openusb_devid_t devid, uint8_t *buffer, uint16_t buflen,
	uint8_t cfgidx, uint8_t ifcidx, uint8_t alt,
	usb_interface_desc_t *ifcdesc);
int32_t openusb_parse_endpoint_desc(openusb_handle_t handle,
	openusb_devid_t devid, uint8_t *buffer, uint16_t buflen,
	uint8_t cfgidx, uint8_t ifcidx, uint8_t alt, uint8_t eptidx,
	usb_endpoint_desc_t *eptdesc);


/*
 * Gets the maximum data transfer size per request based on
 * the bus and type of transfer
 *
 * Arguments:
 *	handle		- LibUSB Handle
 *	bus				- Bus Id
 *	type			- Transfer type
 *	bytes			- Maximum data transfer size
 *
 * Return Values:
 *	OPENUSB_SUCCESS
 *	OPENUSB_INVALID_HANDLE	- Invalid LibUSB Handle
 *	OPENUSB_UNKNOWN_DEVICE	- Bus Id is not valid
 *	OPENUSB_NOT_SUPPORTED	- Operation not supported
 */
int32_t openusb_get_max_xfer_size(openusb_handle_t handle,
	openusb_busid_t bus, openusb_transfer_type_t type, uint32_t *bytes);



/*
 * Function for preparing device and making the default
 * endpoint accessible to openusb:
 *
 * openusb_open_device() .......... Prepare device for using by openusb
 * openusb_close_device() ......... Return device to original state
 *
 *  Arguments:
 *	handle            - Libusb handle
 *	devid             - Device id
 *	flags             - Initialization flag
 *      dev               - Device handle
 *
 *  Return Values:
 *	OPENUSB_SUCCESS
 *	OPENUSB_PLATFORM_FAILURE - Unspecified kernel/driver failure
 *	OPENUSB_UNKNOWN_DEVICE   - Bus id or device id is no longer valid
 *	OPENUSB_NO_RESOURCES     - Memory allocation failures
 *	OPENUSB_IO_*             - USB host controller errors
 *	More TBD
 *
 *  Notes:
 *	openusb_open_device() will
 *	- trigger some reconfiguration on some platforms
 *	- provide access to ep0
 *	- return a dev handle
 */
int32_t openusb_open_device(openusb_handle_t handle, openusb_devid_t devid,
	openusb_init_flag_t flags, openusb_dev_handle_t *dev);
int32_t openusb_close_device(openusb_dev_handle_t dev);

/*
 * Extract device ID from device handle:
 *
 *  openusb_get_devid()
 *
 *   Arguments:
 *	dev              - Device handle
 *	devid            - Pointer to device handle
 *
 *   Return Values:
 *	OPENUSB_SUCCESS
 *	OPENUSB_UNKNOWN_DEVICE - Device handle is no longer valid
 */
int32_t openusb_get_devid(openusb_dev_handle_t dev, openusb_devid_t *devid);

/*
 * Extract openusb handle from device handle:
 *
 *  openusb_get_lib_handle()
 *
 *   Arguments:
 *	dev              - Device handle
 *	lib_handle       - Pointer to openusb handle
 *
 *   Return Values:
 *	OPENUSB_SUCCESS
 *	OPENUSB_UNKNOWN_DEVICE - Device handle is no longer valid
 */
int32_t openusb_get_lib_handle(openusb_dev_handle_t dev,
	openusb_handle_t *lib_handle);

/*  
 * Configuration selection:
 *   
 *  openusb_get_configuration() .... Return bConfigurationValue
 *  openusb_set_configuration() .... Set the configuration
 *
 *   Arguments:
 *	dev             - Device handle
 *	cfg             - Configuration value
 *      
 *   Return Values:
 *	OPENUSB_SUCCESS
 *	OPENUSB_PLATFORM_FAILURE - Unspecified kernel/driver failure
 *	OPENUSB_UNKNOWN_DEVICE   - Bus id or device id is no longer valid
 *	OPENUSB_NO_RESOURCES     - Memory allocation failures
 *	OPENUSB_IO_*             - USB host controller errors
 *
 *   Notes:
 *	openusb_set_configuration() must be called before any interface
 *	on the device is claimed
 */
int32_t openusb_get_configuration(openusb_dev_handle_t dev, uint8_t *cfg);
int32_t openusb_set_configuration(openusb_dev_handle_t dev, uint8_t cfg);

/*
 * Interface claiming:
 *
 *  openusb_claim_interface() ........ Claim interface exclusively
 *  openusb_release_interface() ...... Release interface
 *  openusb_is_interface_claimed() ... Check if interface has been claimed
 *
 *   Arguments:
 *	dev              - Device handle
 *	ifc              - Interface number
 *	flags            - Claiming flag (0 - default to open flag)
 *
 *   Return Values:
 *	OPENUSB_SUCCESS
 *	OPENUSB_PLATFORM_FAILURE - Unspecified kernel/driver failure
 *	OPENUSB_UNKNOWN_DEVICE   - Bus id or device id is no longer valid
 *	OPENUSB_NO_RESOURCES     - Memory allocation failures
 *	OPENUSB_IO_*             - USB host controller errors
 *
 *   Notes:
 *	Need to reserve necessary bandwidth for periodic endpoints
 */
int32_t openusb_claim_interface(openusb_dev_handle_t dev, uint8_t ifc,
	openusb_init_flag_t flags);
int32_t openusb_release_interface(openusb_dev_handle_t dev, uint8_t ifc);
int32_t openusb_is_interface_claimed(openusb_dev_handle_t dev, uint8_t ifc);

/*
 * Alternate interface selection:
 *
 *  openusb_get_altsetting() ....... Get alternate setting number
 *  openusb_set_altsetting() ....... Set alternate setting
 *
 *   Arguments:
 *	dev              - Device handle
 *	ifc              - Interface number
 *	alt              - Alternate setting number
 *
 *   Return Values:
 *	OPENUSB_SUCCESS
 *	OPENUSB_PLATFORM_FAILURE - Unspecified kernel/driver failure
 *	OPENUSB_UNKNOWN_DEVICE   - Bus id or device id is no longer valid
 *	OPENUSB_NO_RESOURCES     - Memory allocation failures
 *	OPENUSB_IO_*             - USB host controller errors
 *
 *   Notes:
 *	May need to release old bandwidth reservation and make
 *	reservation again
 */
int32_t openusb_get_altsetting(openusb_dev_handle_t dev, uint8_t ifc, uint8_t *alt);
int32_t openusb_set_altsetting(openusb_dev_handle_t dev, uint8_t ifc, uint8_t alt);

/*
 * Intervention functions:
 *
 *  openusb_reset() ......... Reset device by resetting port
 *                           (Full reset not guaranteed)
 *   Arguments:
 *	dev              - Device handle
 *
 *   Return Values:
 *	OPENUSB_SUCCESS
 *	OPENUSB_PLATFORM_FAILURE - Unspecified kernel/driver failure
 *	OPENUSB_UNKNOWN_DEVICE   - Bus id or device id is no longer valid
 *	OPENUSB_IO_*             - USB host controller errors
 */
int32_t openusb_reset(openusb_dev_handle_t dev);

/*
 * I/O functions:
 *
 *  openusb_xfer_wait() .............. Issue synchronous I/O request
 *  openusb_xfer_aio()  .............. Issue asynchronous I/O request
 *
 *   Arguments:
 *	handle            - Pointer to request handle
 *
 *   Return Values:
 *	OPENUSB_SUCCESS
 *	OPENUSB_PLATFORM_FAILURE - Unspecified kernel/driver failure
 *	OPENUSB_UNKNOWN_DEVICE   - Bus id or device id is no longer valid
 *	OPENUSB_NO_RESOURCES     - Memory allocation failures
 *	OPENUSB_IO_*             - USB host controller errors
 */
int32_t openusb_xfer_wait(openusb_request_handle_t handle);
int32_t openusb_xfer_aio(openusb_request_handle_t handle);

/*
 * Wrapper functions for synchronous I/O:
 *
 *  openusb_ctrl_xfer() ............. Issue synchronous control request
 *  openusb_intr_xfer() ............. Issue synchronous interrupt request
 *  openusb_bulk_xfer() ............. Issue synchronous bulk request
 *  openusb_isoc_xfer() ............. Issue synchronous isochronous request
 *
 *   Arguments:
 *	dev               - Device handle
 *      ifc               - Interface number
 *      ept               - Endpoint number
 *	ctrl              - Pointer to USB control request
 *	intr              - Pointer to USB interrupt request
 *	bulk              - Pointer to USB bulk request
 *	isoc              - Pointer to USB isochronous request
 *
 *   Return Values:
 *	OPENUSB_SUCCESS
 *	OPENUSB_PLATFORM_FAILURE - Unspecified kernel/driver failure
 *	OPENUSB_UNKNOWN_DEVICE   - Bus id or device id is no longer valid
 *	OPENUSB_NO_RESOURCES     - Memory allocation failures
 *	OPENUSB_IO_*             - USB host controller errors
 *
 *   Notes:
 *	Please use openusb_xfer_wait() for synchronous I/O that needs
 *	to be aborted. The wrapper functions don't support abort.
 */
int32_t openusb_ctrl_xfer(openusb_dev_handle_t dev, uint8_t ifc, uint8_t ept,
	openusb_ctrl_request_t *ctrl);
int32_t openusb_intr_xfer(openusb_dev_handle_t dev, uint8_t ifc, uint8_t ept,
	openusb_intr_request_t *intr);
int32_t openusb_bulk_xfer(openusb_dev_handle_t dev, uint8_t ifc, uint8_t ept,
	openusb_bulk_request_t *bulk);
int32_t openusb_isoc_xfer(openusb_dev_handle_t dev, uint8_t ifc, uint8_t ept,
	openusb_isoc_request_t *isoc);

/*
 * Abort I/O request:
 *
 *  openusb_abort() ................ Abort previously submitted I/O request
 *
 *   Arguments:
 *	handle            - Pointer to request handle
 *
 *   Return Values:
 *	OPENUSB_SUCCESS
 *	OPENUSB_PLATFORM_FAILURE - Unspecified kernel/driver failure
 *	OPENUSB_UNKNOWN_DEVICE   - Bus id or device id is no longer valid
 *	OPENUSB_NO_RESOURCES     - Memory allocation failures
 *	OPENUSB_IO_*             - USB host controller errors
 */
int32_t openusb_abort(openusb_request_handle_t handle);

/*
 * I/O Support:
 *
 *  openusb_wait() ................. Wait for I/O request completion
 *  openusb_poll() ................. Poll I/O request completion status
 *
 *   Arguments:
 *	num_reqs          - Number of req handles in list
 *	handles           - Pointer to list of request handles
 *	handle            - Request handle that has completed
 *
 *   Return Values:
 *	OPENUSB_SUCCESS
 *	OPENUSB_PLATFORM_FAILURE - Unspecified kernel/driver failure
 *	OPENUSB_UNKNOWN_DEVICE   - Bus id or device id is no longer valid
 *	OPENUSB_NO_RESOURCES     - Memory allocation failures
 *	OPENUSB_IO_*             - USB host controller errors
 */
int32_t openusb_wait(uint32_t num_reqs, openusb_request_handle_t *handles,
	openusb_request_handle_t *handle);
int32_t openusb_poll(uint32_t num_reqs, openusb_request_handle_t *handles,
	openusb_request_handle_t *handle);


/*
 *********************************************************
 * The following data types and functions are to support
 * one request/multi-xfer mode
 *********************************************************
 */

typedef struct openusb_multi_intr_request {
	uint8_t		**payloads;	/* array of payload buffer pointers */
	uint32_t	*lengths;	/* array of payload buffer lengths */
	uint32_t	num_bufs;	/* buffer numbers */
	uint32_t	rp;		/* index of buffer to read */
	uint32_t	wp;		/* index of buffer to write */
	uint16_t	interval;
	uint32_t	timeout;
	uint32_t	flags;
} openusb_multi_intr_request_t;

typedef struct openusb_multi_bulk_request {
	uint8_t		**payloads;	/* array of payload buffer pointers */
	uint32_t	*lengths;	/* array of payload buffer lengths */
	uint32_t	num_bufs;	/* buffer numbers */
	uint32_t	rp;		/* index of buffer to read */
	uint32_t	wp;		/* index of buffer to write */
	uint32_t	timeout;
	uint32_t	flags;
} openusb_multi_bulk_request_t;

typedef struct openusb_multi_isoc_request {
	uint32_t	start_frame;
	uint32_t	flags;
	openusb_isoc_pkts_t	*pkts;	/* array of pkts pointers */
	uint32_t	num_pkts;	/* number of pkts pointers */
	uint32_t	rp;		/* index of pkts to read */
	uint32_t	wp;		/* index of pkts to write */
} openusb_multi_isoc_request_t;

struct openusb_multi_request_handle {
	openusb_dev_handle_t	dev;
	uint8_t			interface;
	uint8_t			endpoint;
	openusb_transfer_type_t	type;

	union openusb_multi_request {
		openusb_multi_intr_request_t	*intr;
		openusb_multi_bulk_request_t	*bulk;
		openusb_multi_isoc_request_t	*isoc;
	} req;

	/* callback function */
	int32_t	(*cb)(struct openusb_multi_request_handle *handle,
		uint32_t bufidx, openusb_request_result_t *result);

	void	*arg; /* additional arg for callback */
};

typedef struct openusb_multi_request_handle *openusb_multi_request_handle_t;

/*
 * one request/multi-xfer I/O functions:
 *
 *  openusb_start()               .... Start multi-xfer mode I/O
 *  openusb_stop()                .... Stop multi-xfer mode I/O
 *
 *   Arguments:
 *	handle            - Pointer to multi-xfer request handle
 *
 *   Return Values:
 *	OPENUSB_SUCCESS
 *	OPENUSB_PLATFORM_FAILURE - Unspecified kernel/driver failure
 *	OPENUSB_UNKNOWN_DEVICE - Bus id or device id is no longer valid
 *	OPENUSB_NO_RESOURCES   - Memory allocation failures
 *	OPENUSB_IO_*           - USB host controller errors
 */
int32_t openusb_start(openusb_multi_request_handle_t handle);
int32_t openusb_stop(openusb_multi_request_handle_t handle);

#ifdef __cplusplus
}
#endif

#endif /* __OPENUSB_H__ */