summaryrefslogtreecommitdiffstats
path: root/share/man/man9/usbdi.9
blob: 582754fa662273e4c698c13d02f81dce127c8715 (plain)
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
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
.\"
.\" Copyright (c) 2005 Ian Dowse <iedowse@FreeBSD.org>
.\" All rights reserved.
.\"
.\" 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.
.\"
.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
.\" ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
.\" SUCH DAMAGE.
.\"
.\"	$FreeBSD$
.Dd December 30, 2005
.Os
.Dt USBDI 9
.Sh NAME
.Nm usb_detach_wait ,
.Nm usb_detach_wakeup ,
.Nm usb_find_desc ,
.Nm usbd_abort_default_pipe ,
.Nm usbd_abort_pipe ,
.Nm usbd_alloc_buffer ,
.Nm usbd_alloc_xfer ,
.Nm usbd_bulk_transfer ,
.Nm usbd_clear_endpoint_stall ,
.Nm usbd_clear_endpoint_stall_async ,
.Nm usbd_clear_endpoint_toggle ,
.Nm usbd_close_pipe ,
.Nm usbd_device2interface_handle ,
.Nm usbd_devinfo ,
.Nm usbd_do_request ,
.Nm usbd_do_request_async ,
.Nm usbd_do_request_flags ,
.Nm usbd_do_request_flags_pipe ,
.Nm usbd_dopoll ,
.Nm usbd_endpoint_count ,
.Nm usbd_errstr ,
.Nm usbd_fill_deviceinfo ,
.Nm usbd_find_edesc ,
.Nm usbd_find_idesc ,
.Nm usbd_free_buffer ,
.Nm usbd_free_xfer ,
.Nm usbd_get_buffer ,
.Nm usbd_get_config ,
.Nm usbd_get_config_desc ,
.Nm usbd_get_config_desc_full ,
.Nm usbd_get_config_descriptor ,
.Nm usbd_get_device_descriptor ,
.Nm usbd_get_endpoint_descriptor ,
.Nm usbd_get_interface_altindex ,
.Nm usbd_get_interface_descriptor ,
.Nm usbd_get_no_alts ,
.Nm usbd_get_quirks ,
.Nm usbd_get_speed ,
.Nm usbd_get_string ,
.Nm usbd_get_string_desc ,
.Nm usbd_get_xfer_status ,
.Nm usbd_interface2device_handle ,
.Nm usbd_interface2endpoint_descriptor ,
.Nm usbd_interface_count ,
.Nm usbd_intr_transfer ,
.Nm usbd_open_pipe ,
.Nm usbd_open_pipe_intr ,
.Nm usbd_pipe2device_handle ,
.Nm usbd_ratecheck ,
.Nm usbd_set_config_index ,
.Nm usbd_set_config_no ,
.Nm usbd_set_interface ,
.Nm usbd_set_polling ,
.Nm usbd_setup_default_xfer ,
.Nm usbd_setup_isoc_xfer ,
.Nm usbd_setup_xfer ,
.Nm usbd_sync_transfer ,
.Nm usbd_transfer
.Nd Universal Serial Bus driver programming interface
.Sh SYNOPSIS
.In dev/usb/usb.h
.In dev/usb/usbdi.h
.In dev/usb/usbdi_util.h
.Pp
.Ft void
.Fn usb_detach_wait "device_ptr_t dv"
.Ft void
.Fn usb_detach_wakeup "device_ptr_t dv"
.Ft "const usb_descriptor_t *"
.Fn usb_find_desc "usbd_device_handle dev" "int type" "int subtype"
.Ft usbd_status
.Fn usbd_abort_default_pipe "usbd_device_handle dev"
.Ft usbd_status
.Fn usbd_abort_pipe "usbd_pipe_handle pipe"
.Ft "void *"
.Fn usbd_alloc_buffer "usbd_xfer_handle xfer" "u_int32_t size"
.Ft usbd_xfer_handle
.Fn usbd_alloc_xfer "usbd_device_handle dev"
.Ft usbd_status
.Fo usbd_bulk_transfer
.Fa "usbd_xfer_handle xfer"
.Fa "usbd_pipe_handle pipe"
.Fa "u_int16_t flags"
.Fa "u_int32_t timeout"
.Fa "void *buf"
.Fa "u_int32_t *size"
.Fa "char *lbl"
.Fc
.Ft usbd_status
.Fn usbd_clear_endpoint_stall "usbd_pipe_handle pipe"
.Ft usbd_status
.Fn usbd_clear_endpoint_stall_async "usbd_pipe_handle"
.Ft void
.Fn usbd_clear_endpoint_toggle "usbd_pipe_handle pipe"
.Ft usbd_status
.Fn usbd_close_pipe "usbd_pipe_handle pipe"
.Ft usbd_status
.Fo usbd_device2interface_handle
.Fa "usbd_device_handle dev"
.Fa "u_int8_t ifaceno"
.Fa "usbd_interface_handle *iface"
.Fc
.Ft void
.Fn usbd_devinfo "usbd_device_handle dev" "int showclass" "char *cp"
.Ft usbd_status
.Fo usbd_do_request
.Fa "usbd_device_handle dev"
.Fa "usb_device_request_t *req"
.Fa "void *data"
.Fc
.Ft usbd_status
.Fo usbd_do_request_async
.Fa "usbd_device_handle dev"
.Fa "usb_device_request_t *req"
.Fa "void *data"
.Fc
.Ft usbd_status
.Fo usbd_do_request_flags
.Fa "usbd_device_handle dev"
.Fa "usb_device_request_t *req"
.Fa "void *data"
.Fa "u_int16_t flags"
.Fa "int *actlen"
.Fa "u_int32_t timo"
.Fc
.Ft usbd_status
.Fo usbd_do_request_flags_pipe
.Fa "usbd_device_handle dev"
.Fa "usbd_pipe_handle pipe"
.Fa "usb_device_request_t *req"
.Fa "void *data"
.Fa "u_int16_t flags"
.Fa "int *actlen"
.Fa "u_int32_t timeout"
.Fc
.Ft void
.Fn usbd_dopoll "usbd_interface_handle iface"
.Ft usbd_status
.Fn usbd_endpoint_count "usbd_interface_handle iface" "u_int8_t *count"
.Ft "const char *"
.Fn usbd_errstr "usbd_status err"
.Ft void
.Fo usbd_fill_deviceinfo
.Fa "usbd_device_handle dev"
.Fa "struct usb_device_info *di"
.Fa "int usedev"
.Fc
.Ft "usb_endpoint_descriptor_t *"
.Fo usbd_find_edesc
.Fa "usb_config_descriptor_t *cd"
.Fa "int ifaceidx"
.Fa "int altidx"
.Fa "int endptidx"
.Fc
.Ft "usb_interface_descriptor_t *"
.Fn usbd_find_idesc "usb_config_descriptor_t *cd" "int ifaceidx" "int altidx"
.Ft void
.Fn usbd_free_buffer "usbd_xfer_handle xfer"
.Ft usbd_status
.Fn usbd_free_xfer "usbd_xfer_handle xfer"
.Ft "void *"
.Fn usbd_get_buffer "usbd_xfer_handle xfer"
.Ft usbd_status
.Fn usbd_get_config "usbd_device_handle dev" "u_int8_t *conf"
.Ft usbd_status
.Fo usbd_get_config_desc
.Fa "usbd_device_handle dev"
.Fa "int confidx"
.Fa "usb_config_descriptor_t *d"
.Fc
.Ft usbd_status
.Fo usbd_get_config_desc_full
.Fa "usbd_device_handle dev"
.Fa "int conf"
.Fa "void *d"
.Fa "int size"
.Fc
.Ft "usb_config_descriptor_t *"
.Fn usbd_get_config_descriptor "usbd_device_handle dev"
.Ft "usb_device_descriptor_t *"
.Fn usbd_get_device_descriptor "usbd_device_handle dev"
.Ft "usb_endpoint_descriptor_t *"
.Fo usbd_get_endpoint_descriptor
.Fa "usbd_interface_handle iface"
.Fa "u_int8_t address"
.Fc
.Ft int
.Fn usbd_get_interface_altindex "usbd_interface_handle iface"
.Ft "usb_interface_descriptor_t *"
.Fn usbd_get_interface_descriptor "usbd_interface_handle iface"
.Ft int
.Fn usbd_get_no_alts "usb_config_descriptor_t *cdesc" "int ifaceno"
.Ft "const struct usbd_quirks *"
.Fn usbd_get_quirks "usbd_device_handle dev"
.Ft int
.Fn usbd_get_speed "usbd_device_handle dev"
.Ft usbd_status
.Fn usbd_get_string "usbd_device_handle dev" "int si" "char *buf"
.Ft usbd_status
.Fo usbd_get_string_desc
.Fa "usbd_device_handle dev"
.Fa "int sindex"
.Fa "int langid"
.Fa "usb_string_descriptor_t *sdesc"
.Fa "int *sizep"
.Fc
.Ft void
.Fo usbd_get_xfer_status
.Fa "usbd_xfer_handle xfer"
.Fa "usbd_private_handle *priv"
.Fa "void **buffer"
.Fa "u_int32_t *count"
.Fa "usbd_status *status"
.Fc
.Ft void
.Fo usbd_interface2device_handle
.Fa "usbd_interface_handle iface"
.Fa "usbd_device_handle *dev"
.Fc
.Ft "usb_endpoint_descriptor_t *"
.Fo usbd_interface2endpoint_descriptor
.Fa "usbd_interface_handle iface"
.Fa "u_int8_t index"
.Fc
.Ft usbd_status
.Fn usbd_interface_count "usbd_device_handle dev" "u_int8_t *count"
.Ft usbd_status
.Fo usbd_intr_transfer
.Fa "usbd_xfer_handle xfer"
.Fa "usbd_pipe_handle pipe"
.Fa "u_int16_t flags"
.Fa "u_int32_t timeout"
.Fa "void *buf"
.Fa "u_int32_t *size"
.Fa "char *lbl"
.Fc
.Ft usbd_status
.Fo usbd_open_pipe
.Fa "usbd_interface_handle iface"
.Fa "u_int8_t address"
.Fa "u_int8_t flags"
.Fa "usbd_pipe_handle *pipe"
.Fc
.Ft usbd_status
.Fo usbd_open_pipe_intr
.Fa "usbd_interface_handle iface"
.Fa "u_int8_t address"
.Fa "u_int8_t flags"
.Fa "usbd_pipe_handle *pipe"
.Fa "usbd_private_handle priv"
.Fa "void *buffer"
.Fa "u_int32_t len"
.Fa "usbd_callback cb"
.Fa "int ival"
.Fc
.Ft usbd_device_handle
.Fn usbd_pipe2device_handle "usbd_pipe_handle pipe"
.Ft int
.Fn usbd_ratecheck "struct timeval *last"
.Ft usbd_status
.Fn usbd_set_config_index "usbd_device_handle dev" "int index" "int msg"
.Ft usbd_status
.Fn usbd_set_config_no "usbd_device_handle dev" "int no" "int msg"
.Ft usbd_status
.Fn usbd_set_interface "usbd_interface_handle iface" "int altidx"
.Ft void
.Fn usbd_set_polling "usbd_device_handle dev" "int on"
.Ft void
.Fo usbd_setup_default_xfer
.Fa "usbd_xfer_handle xfer"
.Fa "usbd_device_handle dev"
.Fa "usbd_private_handle priv"
.Fa "u_int32_t timeout"
.Fa "usb_device_request_t *req"
.Fa "void *buffer"
.Fa "u_int32_t length"
.Fa "u_int16_t flags"
.Fa "usbd_callback callback"
.Fc
.Ft void
.Fo usbd_setup_isoc_xfer
.Fa "usbd_xfer_handle xfer"
.Fa "usbd_pipe_handle pipe"
.Fa "usbd_private_handle priv"
.Fa "u_int16_t *frlengths"
.Fa "u_int32_t nframes"
.Fa "u_int16_t flags"
.Fa "usbd_callback callback"
.Fc
.Ft void
.Fo usbd_setup_xfer
.Fa "usbd_xfer_handle xfer"
.Fa "usbd_pipe_handle pipe"
.Fa "usbd_private_handle priv"
.Fa "void *buffer"
.Fa "u_int32_t length"
.Fa "u_int16_t flags"
.Fa "u_int32_t timeout"
.Fa "usbd_callback callback"
.Fc
.Ft usbd_status
.Fn usbd_sync_transfer "usbd_xfer_handle xfer"
.Ft usbd_status
.Fn usbd_transfer "usbd_xfer_handle xfer"
.Sh DESCRIPTION
The Universal Serial Bus (USB) driver programming interface provides
USB peripheral drivers with a host controller independent API for
controlling and communicating with USB peripherals.
.Pp
Typically, drivers will first use some combination of the functions
.Fn usbd_set_config_no ,
.Fn usbd_get_config_descriptor ,
.Fn usbd_set_interface ,
.Fn usbd_get_interface_descriptor ,
.Fn usbd_device2interface_handle ,
.Fn usbd_endpoint_count
and
.Fn usbd_interface2endpoint_descriptor
to query the device's properties and prepare it for use.
Drivers can then perform requests on the USB control pipe using
.Fn usbd_do_request ,
they can open pipes using the functions
.Fn usbd_open_pipe
and
.Fn usbd_open_pipe_intr ,
and perform transfers over these pipes using
.Fn usbd_alloc_xfer ,
.Fn usbd_setup_xfer
and
.Fn usbd_transfer .
Finally, the functions
.Fn usbd_abort_pipe ,
.Fn usbd_close_pipe
and
.Fn usbd_free_xfer
are used to cancel outstanding transfers, close open pipes and deallocate
transfer structures.
.Pp
The
.Fn usbd_get_device_descriptor
function returns a pointer to the USB device descriptor for
.Fa dev .
See
.Sx "USB Descriptors"
below for information about the USB device descriptor.
.Pp
The
.Fn usbd_get_config_desc
function retrieves the specified configuration descriptor from the device.
The
.Fa confidx
parameter specifies the configuration descriptor index, which must be less
than the
.Fa bNumConfigurations
value in the device descriptor.
The function
.Fn usbd_get_config_desc_full
retrieves a full configuration descriptor, which has all related interface
and endpoint descriptors appended to a normal configuration descriptor.
The parameter
.Fa d
should point to memory that is at least
.Fa size
bytes in length, and this should be at least as long as the
.Fa wTotalLength
value from the configuration descriptor.
See
.Sx "USB Descriptors"
below for information about the USB configuration descriptor.
.Pp
The
.Fn usbd_get_config
function retrieves the current configuration number from the device, i.e.\&
the
.Fa bConfigurationValue
value from the configuration that is active.
If the device is unconfigured then
.Dv USB_UNCONFIG_NO
is returned.
The current configuration can be changed by calling either
.Fn usbd_set_config_index
or
.Fn usbd_set_config_no .
The difference between these functions is that
.Fn usbd_set_config_index
accepts a configuration index number that is less than the
.Fa bNumConfigurations
value from the device descriptor, whereas
.Fn usbd_set_config_no
requires the
.Fa bConfigurationValue
value of the desired configuration to be provided instead.
To unconfigure the device, supply a configuration index of
.Dv USB_UNCONFIG_INDEX
to
.Fn usbd_set_config_index ,
or else specify a configuration number of
.Dv USB_UNCONFIG_NO
to
.Fn usbd_set_config_no .
.Pp
The
.Fn usbd_get_config_descriptor
function returns a pointer to an in-memory copy of the full configuration
descriptor of the configuration that is currently active.
The returned pointer remains valid until the device configuration
is changed using
.Fn usbd_set_config_index
or
.Fn usbd_set_config_no .
If the device is unconfigured then
.Dv NULL
is returned instead.
.Pp
The function
.Fn usbd_interface_count
returns the number of interfaces available in the current device
configuration.
The
.Fn usbd_get_no_alts
function determines the number of alternate interfaces in a full
configuration descriptor by counting the interface descriptors with
.Fa bInterfaceNumber
equal to
.Fa ifaceno
(the count includes alternate index zero).
The
.Fn usbd_find_idesc
function locates an interface descriptor within a full configuration
descriptor.
The
.Fa ifaceidx
parameter specifies the interface index number, which should be less than
the number of interfaces in the configuration descriptor (i.e.\& the value
returned by
.Fn usbd_interface_count
or the
.Fa bNumInterface
field from the configuration descriptor).
An alternate interface can be specified using a non-zero
.Fa altidx ,
which should be less than the value returned by
.Fn usbd_get_no_alts .
The return value is a pointer to the requested interface descriptor
within the full configuration descriptor, or
.Dv NULL
if the specified interface descriptor does not exist.
Note that the
.Fa altidx
parameter specifies the alternate setting by index number starting
at zero; it is not the alternate setting number defined in the
interface descriptor.
.Pp
The function
.Fn usbd_find_edesc
locates an endpoint descriptor within a full configuration descriptor.
The
.Fa ifaceidx
and
.Fa altidx
parameters are the same as described for
.Fn usbd_find_idesc ,
and the
.Fa endptidx
parameter is an endpoint index number that should be less than the
.Fa bNumEndpoints
field in the interface descriptor.
The return value is a pointer to the requested endpoint descriptor
within the full configuration descriptor, or
.Dv NULL
if the specified endpoint descriptor does not exist.
Note that the
.Fa altidx
and
.Fa endptidx
parameters are index numbers starting at zero; they are not the
alternate setting and endpoint address defined in the descriptors.
.Pp
The
.Fn usbd_get_speed
function returns the device speed.
This can be
.Dv USB_SPEED_LOW ,
.Dv USB_SPEED_FULL
or
.Dv USB_SPEED_HIGH .
.Pp
USB devices optionally support string descriptors, which can be
retrieved using the
.Fn usbd_get_string
or
.Fn usbd_get_string_desc
functions.
Device, configuration and interface descriptors reference strings by
an index number that can be supplied to these functions.
The
.Fn usbd_get_string
function should be used unless a non-default language is required.
It requires that
.Fa buf
points to a buffer of at least
.Dv USB_MAX_STRING_LEN
bytes in size.
The
.Fa si
parameter specified which string to retrieve.
.Pp
The
.Fn usb_find_desc
function searches through the in-memory full configuration descriptor
for the active configuration and finds the first descriptor that has a
.Fa bDescriptorType
equal to
.Fa type ,
and if
.Fa subtype
is not equal to
.Dv USBD_SUBTYPE_ANY ,
the descriptor must also have a
.Fa bDescriptorSubtype
equal to
.Fa subtype .
If found, then a pointer to the descriptor is returned.
Otherwise,
.Fn usb_find_desc
returns
.Dv NULL .
The returned pointer is valid until the device configuration is changed using
.Fn usbd_set_config_index
or
.Fn usbd_set_config_no .
.Pp
The USB driver interface uses opaque interface handles to refer to
configuration interfaces.
These handles remain valid until the device configuration is changed using
.Fn usbd_set_config_index
or
.Fn usbd_set_config_no .
The
.Fn usbd_device2interface_handle
function retrieves an interface handle.
The
.Fa ifaceno
parameter is an interface index number starting at zero.
If the device is configured and the specified interface exists, then
.Dv USBD_NORMAL_COMPLETION
is returned and the interface handle is stored in
.Fa *iface .
Otherwise an error code is returned and
.Fa *iface
is not changed.
The
.Fn usbd_interface2device_handle
function retrieves the device handle from an interface handle.
This is just for convenience to save passing around the device
handle as well as the interface handle.
The
.Fn usbd_set_interface
function changes the alternate setting number for an interface to
the alternate setting identified by the zero-based index number
.Fa altidx .
This operation invalidates any existing endpoints on this
interface and their descriptors.
The
.Fn usbd_get_interface_altindex
function returns the current alternative setting index as was
specified when calling
.Fn usbd_set_interface .
The
.Fn usbd_endpoint_count
function retrieves the number of endpoints associated with the
specified interface.
The
.Fn usbd_interface2endpoint_descriptor
function returns a pointer to an in-memory endpoint descriptor for
the endpoint that has an index number of
.Fa index .
This pointer remains valid until the configuration or alternate setting
number are changed.
The function
.Fn usbd_get_endpoint_descriptor
is like
.Fn usbd_interface2endpoint_descriptor
but it accepts a
.Fa bEndpointAddress
address value instead of an index.
.Pp
The
.Fn usbd_fill_deviceinfo
function fills out a
.Vt usb_device_info
structure with information about the device.
The vendor and product names come from the device itself, falling back to
a table lookup or just providing the IDs in hexadecimal.
If
.Fa usedev
is zero then
.Fn usbd_fill_deviceinfo
will not attempt to retrieve the vendor and product names from the
device.
The usb_device_info structure is defined in
.In dev/usb/usb.h
as follows:
.Bd -literal
struct usb_device_info {
	u_int8_t	udi_bus;
	u_int8_t	udi_addr;	/* device address */
	usb_event_cookie_t udi_cookie;
	char		udi_product[USB_MAX_STRING_LEN];
	char		udi_vendor[USB_MAX_STRING_LEN];
	char		udi_release[8];
	u_int16_t	udi_productNo;
	u_int16_t	udi_vendorNo;
	u_int16_t	udi_releaseNo;
	u_int8_t	udi_class;
	u_int8_t	udi_subclass;
	u_int8_t	udi_protocol;
	u_int8_t	udi_config;
	u_int8_t	udi_speed;
#define USB_SPEED_LOW  1
#define USB_SPEED_FULL 2
#define USB_SPEED_HIGH 3
	int		udi_power;	/* power consumption in mA */
	int		udi_nports;
	char		udi_devnames[USB_MAX_DEVNAMES][USB_MAX_DEVNAMELEN];
	/* hub only: addresses of devices on ports */
	u_int8_t	udi_ports[16];
#define USB_PORT_ENABLED 0xff
#define USB_PORT_SUSPENDED 0xfe
#define USB_PORT_POWERED 0xfd
}
.Ed
.Pp
The
.Fn usbd_devinfo
function generates a string description of the USB device.
The
.Fa cp
argument should point to a 1024-byte buffer (XXX the maximum length
is approximately 320 chars, but there is no sanity checking and everything uses
1024-character buffers).
Device class information is included if the
.Fa showclass
parameter is non-zero.
.Pp
The
.Fn usbd_get_quirks
function returns information from a table of devices that require
special workarounds in order to function correctly.
The returned structure is defined in
.In dev/usb/usb_quirks.h
as follows:
.Bd -literal
struct usbd_quirks {
	u_int32_t uq_flags;	/* Device problems */
};
.Ed
.Pp
See
.In dev/usb/usb_quirks.h
for a list of all currently defined quirks.
.Pp
USB control requests are performed via
.Vt usb_device_request_t
structures, defined in
.In dev/usb/usb.h
as follows:
.Bd -literal
typedef struct {
	uByte		bmRequestType;
	uByte		bRequest;
	uWord		wValue;
	uWord		wIndex;
	uWord		wLength;
} UPACKED usb_device_request_t;
.Ed
.Pp
The
.Fn usbd_do_request
function performs a single request synchronously.
The
.Fa req
parameter should point to a properly initialized
.Vt usb_device_request_t ,
and when the
.Fa wLength
field is non-zero,
.Fa data
should point at a buffer that is at least
.Fa wLength
bytes in length.
The request timeout is set to 5 seconds, so the operation will fail
with
.Er USBD_TIMEOUT
if the device does not respond within that time.
The
.Fn usbd_do_request_async
function is like
.Fn usbd_do_request ,
but it does not wait for the request to complete before returning.
This routine does not block so it can be used from contexts where
sleeping is not allowed.
Note that there is no notification mechanism to report when the
operation completed nor is there a way to determine whether the
request succeeded, so this function is of limited use.
See
.Fn usbd_setup_default_xfer
and
.Fn usbd_transfer
for a way to invoke an asynchronous callback upon completion of
a control request.
The
.Fn usbd_do_request_flags
function is like
.Fn usbd_do_request ,
but additional flags can be specified, the timeout is configurable,
and the actual number of bytes transferred is made available to the
caller.
The
.Fn usbd_do_request_flags_pipe
function uses a specified pipe instead of the default pipe.
.Pp
The function
.Fn usbd_open_pipe
creates a pipe connected to a specified endpoint on a specified interface.
The parameter
.Fa address
should be the
.Fa bEndpointAddress
value from one of this interface's endpoint descriptors.
If
.Fa flags
contains
.Dv USBD_EXCLUSIVE_USE
then the operation will only succeed if there are no open pipes
already connected to the specified endpoint.
The
.Fn usbd_open_pipe_intr
function creates an interrupt pipe connected to the specified endpoint.
The parameter
.Fa address
should be the
.Fa bEndpointAddress
value from one of this interface's endpoint descriptors.
The
.Fa flags
parameter is passed to
.Fn usbd_setup_xfer .
The
.Fa buffer
and
.Fa len
parameters define a buffer that is to be used for the interrupt transfers.
The callback to be invoked each time a transfer completes is specified by
.Fa cb ,
and
.Fa priv
is an argument to be passed to the callback function.
The
.Fa ival
parameter specifies the maximum acceptable interval between transfers;
in practice the transfers may occur more frequently.
The function
.Fn usbd_pipe2device_handle
returns the device associated with the specified
.Fa pipe .
.Pp
The
.Fn usbd_abort_pipe
function aborts all active or waiting transfers on the specified pipe.
Each transfer is aborted with a
.Dv USBD_CANCELLED
status; callback routines must detect this error code to ensure that
they do not attempt to initiate a new transfer in response to one being
aborted.
This routine blocks while it is waiting for the hardware to complete
processing of aborted transfers, so it is only safe to call it in
contexts where sleeping is allowed.
The function
.Fn usbd_abort_default_pipe
aborts all active or waiting transfers on the default pipe.
Like
.Fn usbd_abort_pipe ,
it blocks waiting for the hardware processing to complete.
.Pp
When a pipe has no active or waiting transfers, the pipe may be closed
using the
.Fn usbd_close_pipe
function.
Once a pipe is closed, its pipe handle becomes invalid and may no longer
be used.
.Pp
USB transfer handles are allocated using the function
.Fn usbd_alloc_xfer
and may be freed using
.Fn usbd_free_xfer .
.Pp
The function
.Fn usbd_setup_xfer
initializes a transfer handle with the details of a transfer to or from
a USB device.
The
.Fa xfer
parameter specifies the transfer handle to initialize,
.Fa pipe
specifies the pipe on which the transfer is to take place, and
.Fa priv
is an argument that will be passed to callback function.
The arguments
.Fa buffer
and
.Fa length
define the data buffer for the transfer.
If
.Fa length
is zero then the
.Fa buffer
may be
.Dv NULL .
The
.Fa flags
parameter may contain the following flags:
.Bl -tag -width ".Dv USBD_FORCE_SHORT_XFER"
.It Dv USBD_NO_COPY
This is used in association with
.Fn usbd_alloc_buffer
and
.Fn usbd_free_buffer
to use a dedicated DMA-capable buffer for the transfer.
.It Dv USBD_SYNCHRONOUS
Wait for the transfer to compete in
.Fn usbd_transfer .
.It Dv USBD_SHORT_XFER_OK
Permit transfers shorter than the requested data length.
.It Dv USBD_FORCE_SHORT_XFER
Force a short transfer at the end of a write operation to let the
device know that the transfer has ended.
.El
.Pp
The
.Fa timeout
parameter specifies a timeout for the transfer in milliseconds.
A value of
.Dv USBD_NO_TIMEOUT
indicates that no timeout should be configured.
The parameter
.Fa callback
specifies the function to call when the transfer completes.
Note that
.Fn usbd_setup_xfer
does not actually initiate the transfer.
The
.Fn usbd_setup_default_xfer
initializes a control transfer for the default pipe.
The
.Fa req
parameter should point at a completed
.Vt usb_device_request_t
structure.
The function
.Fa usbd_setup_isoc_xfer
initializes a transfer for an isochronous pipe.
.Pp
The function
.Fn usbd_transfer
initiates a transfer.
Normally it returns
.Dv USBD_IN_PROGRESS
to indicate that the transfer has been queued.
If the USB stack is operating in polling mode, or if the transfer
is synchronous, then
.Dv USBD_NORMAL_COMPLETION
may be returned.
Other return values indicate that the transfer could not be
initiated due to an error.
The
.Fn usbd_sync_transfer
function executes a transfer synchronously.
It will sleep waiting for the transfer to complete and then return
the transfer status.
Note that if the transfer has a callback routine, this will be
invoked before
.Fn usbd_sync_transfer
returns.
.Pp
The
.Fn usbd_intr_transfer
and
.Fn usbd_bulk_transfer
functions set up a transfer and wait synchronously for it to complete
but they allows signals to interrupt the wait.
They returns
.Dv USBD_INTERRUPTED
if the transfer was interrupted by a signal.
XXX these two functions are identical apart from their names.
.Pp
The function
.Fn usbd_get_xfer_status
retrieves various information from a completed transfer.
If the
.Fa priv
parameter is not NULL then the callback private argument is
stored in
.Fa *priv .
If
.Fa buffer
is not NULL then the transfer buffer pointer is stored in
.Fa *buffer .
The actual number of bytes transferred is stored in
.Fa *count
if
.Fa count is not NULL.
Finally, the transfer status is stored in
.Fa *status
if
.Fa status
is not NULL.
.Pp
The
.Fn usbd_clear_endpoint_stall
function clears an endpoint stall condition synchronously, i.e.\&
it sleeps waiting for the stall clear request to complete.
The function
.Fn usbd_clear_endpoint_stall_async
performs the same function asynchronously, but it provides no
way to determine when the request completed, or whether it was
successful.
The
.Fn usbd_clear_endpoint_toggle
function instructs the host controller driver to reset the toggle bit
on a pipe.
This is used when manually clearing an endpoint stall using a
control pipe request, in order to ensure that the host controller
driver and the USB device restart with the same toggle value.
.Pp
Normally the USB subsystem maps and copies data to and from
DMA-capable memory each time a transfer is performed.
The function
.Fn usbd_alloc_buffer
allocates a permanent DMA-capable buffer associated with the
transfer to avoid this overhead.
The return value is the virtual address of the buffer.
Any time that
.Fn usbd_setup_xfer
is called on the transfer with the
.Dv USBD_NO_COPY
flag enabled, the allocated buffer will be used directly and
the
.Fa buffer
argument passed to
.Fn usbd_setup_xfer
will be ignored.
The
.Fn usbd_get_buffer
function returns a pointer to the virtual address of a buffer previously
allocated by
.Fn usbd_alloc_buffer .
Finally,
.Fn usbd_free_buffer
deallocates the buffer.
.Pp
The
.Fn usbd_errstr
function converts a status code into a string for display.
.Pp
The function
.Fn usbd_set_polling
enables or disables polling mode.
In polling mode, all operations will busy-wait for the device to
respond, so its use is effectively limited to boot time and kernel
debuggers.
It is important to match up calls that enable and disable polling
mode, because the implementation just increments a polling reference
count when
.Fa on
is non-zero and decrements it when
.Fa on
is zero.
The
.Fn usbd_dopoll
causes the host controller driver to poll for any activity.
This should only be used when polling mode is enabled.
.Pp
The
.Fn usbd_ratecheck
function is used to limit the rate at which error messages are
printed to approximately once per second.
The
.Fa last
argument should point at a persistent
.Vt "struct timeval" .
A value of 1 will be returned if a message should be printed, but if
.Fn usbd_ratecheck
has already been called with the same
.Vt "struct timeval"
parameter in the last second then 0 is returned and the error message
should be suppressed.
.Pp
The functions
.Fn usb_detach_wait
and
.Fn usb_detach_wakeup
are used to wait for references to drain before completing the
detachment of a device.
The
.Fn usb_detach_wait
function will wait up to 60 seconds to receive a signal from
.Fn usb_detach_wait .
.Ss "USB Descriptors"
The USB specification defines a number of standard descriptors by
which USB devices report their attributes.
These descriptors are fixed-format structures that all USB devices
make available through USB control pipe requests.
.Pp
Every USB device has exactly one USB device descriptor.
The USB subsystem retrieves this automatically when a device is
attached, and a copy of the descriptor is kept in memory.
The
.Fn usbd_get_device_descriptor
function returns a pointer to the descriptor.
The device descriptor structure is defined in
.In dev/usb/usb.h
as follows:
.Bd -literal
typedef struct {
	uByte		bLength;
	uByte		bDescriptorType;
	uWord		bcdUSB;
#define UD_USB_2_0		0x0200
#define UD_IS_USB2(d) (UGETW((d)->bcdUSB) >= UD_USB_2_0)
	uByte		bDeviceClass;
	uByte		bDeviceSubClass;
	uByte		bDeviceProtocol;
	uByte		bMaxPacketSize;
	/* The fields below are not part of the initial descriptor. */
	uWord		idVendor;
	uWord		idProduct;
	uWord		bcdDevice;
	uByte		iManufacturer;
	uByte		iProduct;
	uByte		iSerialNumber;
	uByte		bNumConfigurations;
} UPACKED usb_device_descriptor_t;
#define USB_DEVICE_DESCRIPTOR_SIZE 18
.Ed
.Pp
USB devices have at least one configuration descriptor.
The
.Fa bNumConfigurations
field of the device descriptor specifies the number of configuration
descriptors that a device supports.
The
.Fn usbd_get_config_desc
function retrieves a particular configuration descriptor from the device
and the
.Fn usbd_get_config_desc_full
function retrieves a full
.Fa wTotalLength
length configuration descriptor, which includes all related interface
and endpoint descriptors.
Only one configuration may be active at a time.
The
.Fn usbd_set_config_index
function activates a specified configuration.
The configuration descriptor structure is defined in
.In dev/usb/usb.h
as follows:
.Bd -literal
typedef struct {
	uByte		bLength;
	uByte		bDescriptorType;
	uWord		wTotalLength;
	uByte		bNumInterface;
	uByte		bConfigurationValue;
	uByte		iConfiguration;
	uByte		bmAttributes;
#define UC_BUS_POWERED		0x80
#define UC_SELF_POWERED		0x40
#define UC_REMOTE_WAKEUP	0x20
	uByte		bMaxPower; /* max current in 2 mA units */
#define UC_POWER_FACTOR 2
} UPACKED usb_config_descriptor_t;
#define USB_CONFIG_DESCRIPTOR_SIZE 9
.Ed
.Pp
Each device configuration provides one or more interfaces.
The
.Fa bNumInterface
field of the configuration descriptor specifies the number of
interfaces associated with a device configuration.
Interfaces are described by an interface descriptor, which is defined in
.In dev/usb/usb.h
as follows:
.Bd -literal
typedef struct {
	uByte		bLength;
	uByte		bDescriptorType;
	uByte		bInterfaceNumber;
	uByte		bAlternateSetting;
	uByte		bNumEndpoints;
	uByte		bInterfaceClass;
	uByte		bInterfaceSubClass;
	uByte		bInterfaceProtocol;
	uByte		iInterface;
} UPACKED usb_interface_descriptor_t;
#define USB_INTERFACE_DESCRIPTOR_SIZE 9
.Ed
.Pp
Configurations may also have alternate interfaces with the same
.Fa bInterfaceNumber
but different
.Fa bAlternateSetting
values.
These alternate interface settings may be selected by passing a
non-zero
.Fa altidx
parameter to
.Fn usbd_set_interface .
.Pp
Interfaces have zero or more endpoints, and each endpoint has an
endpoint descriptor.
Note that endpoint zero, which is always present, does not have an
endpoint descriptor, and it is never included in the
.Fa bNumEndpoints
count of endpoints.
The endpoint descriptor is defined in
.In dev/usb/usb.h
as follows:
.Bd -literal
typedef struct {
	uByte		bLength;
	uByte		bDescriptorType;
	uByte		bEndpointAddress;
#define UE_GET_DIR(a)	((a) & 0x80)
#define UE_SET_DIR(a,d) ((a) | (((d)&1) << 7))
#define UE_DIR_IN	0x80
#define UE_DIR_OUT	0x00
#define UE_ADDR		0x0f
#define UE_GET_ADDR(a)	((a) & UE_ADDR)
	uByte		bmAttributes;
#define UE_XFERTYPE	0x03
#define	 UE_CONTROL	0x00
#define	 UE_ISOCHRONOUS 0x01
#define	 UE_BULK	0x02
#define	 UE_INTERRUPT	0x03
#define UE_GET_XFERTYPE(a)	((a) & UE_XFERTYPE)
#define UE_ISO_TYPE	0x0c
#define	 UE_ISO_ASYNC	0x04
#define	 UE_ISO_ADAPT	0x08
#define	 UE_ISO_SYNC	0x0c
#define UE_GET_ISO_TYPE(a)	((a) & UE_ISO_TYPE)
	uWord		wMaxPacketSize;
	uByte		bInterval;
} UPACKED usb_endpoint_descriptor_t;
#define USB_ENDPOINT_DESCRIPTOR_SIZE 7
.Ed
.Sh RETURN VALUES
Many functions return a
.Vt usbd_status
type to indicate the outcome of the operation.
If the operation completed successfully then
.Dv USBD_NORMAL_COMPLETION
is returned.
Operations that have been started but not yet completed will return
.Dv USBD_IN_PROGRESS .
Other errors usually indicate a problem.
Error codes can be converted to strings using
.Fn usbd_errstr .
.Sh ERRORS
.Bl -tag -width ".Er USBD_PENDING_REQUESTS"
.It Bq Er USBD_PENDING_REQUESTS
A pipe could not be closed because there are active requests.
.It Bq Er USBD_NOT_STARTED
The transfer has not yet been started.
.It Bq Er USBD_INVAL
An invalid value was supplied.
.It Bq Er USBD_NOMEM
An attempt to allocate memory failed.
.It Bq Er USBD_CANCELLED
The transfer was aborted.
.It Bq Er USBD_BAD_ADDRESS
The specified endpoint address was not found.
.It Bq Er USBD_IN_USE
The endpoint is already in use, or the configuration cannot be changed
because some of its endpoints are in use.
.It Bq Er USBD_NO_ADDR
No free USB devices addresses were found to assign to the device.
.It Bq Er USBD_SET_ADDR_FAILED
The device address could not be set.
.It Bq Er USBD_NO_POWER
Insufficient power was available for the device.
.It Bq Er USBD_TOO_DEEP
Too many levels of chained hubs were found.
.It Bq Er USBD_IOERROR
There was an error communicating with the device.
.It Bq Er USBD_NOT_CONFIGURED
An operation that requires an active configuration was attempted while
the device was in an unconfigured state.
.It Bq Er USBD_TIMEOUT
A transfer timed out.
.It Bq Er USBD_SHORT_XFER
A transfer that disallowed short data lengths completed with less than
the requested length transferred.
.It Bq Er USBD_STALLED
A transfer failed because the pipe is stalled.
.It Bq Er USBD_INTERRUPTED
An interruptible operation caught a signal.
.El
.Sh SEE ALSO
.Xr usb 4
.Sh HISTORY
The USB driver interface first appeared in
.Fx 3.0 .
.Sh AUTHORS
The USB driver was written by
.An Lennart Augustsson
for the
.Nx
project.
.Pp
.An -nosplit
This manual page was written by
.An Ian Dowse Aq iedowse@FreeBSD.org .
OpenPOWER on IntegriCloud