2 * Originally released under the Be Sample Code License.
3 * Copyright 2000, Be Incorporated. All rights reserved.
5 * Modified for Haiku by François Revol and Michael Lotz.
6 * Copyright 2007-2008, Haiku Inc. All rights reserved.
14 #include <usb/USB_audio.h>
15 #include <usb/USB_video.h>
17 #include "usbspec_private.h"
18 #include "usb-utils.h"
24 ClassName(int classNumber
) {
25 switch (classNumber
) {
27 return "Per-interface classes";
28 case USB_AUDIO_DEVICE_CLASS
:
31 return "Communication";
41 return "Mass storage";
49 return "Content security";
50 case USB_VIDEO_DEVICE_CLASS
:
53 return "Personal Healthcare";
55 return "Diagnostic device";
57 return "Wireless controller";
59 return "Miscellaneous";
61 return "Application specific";
63 return "Vendor specific";
71 SubclassName(int classNumber
, int subclass
)
73 if (classNumber
== 0xEF) {
78 if (classNumber
== USB_VIDEO_DEVICE_CLASS
) {
80 case USB_VIDEO_INTERFACE_UNDEFINED_SUBCLASS
:
81 return " (Undefined)";
82 case USB_VIDEO_INTERFACE_VIDEOCONTROL_SUBCLASS
:
84 case USB_VIDEO_INTERFACE_VIDEOSTREAMING_SUBCLASS
:
85 return " (Streaming)";
86 case USB_VIDEO_INTERFACE_COLLECTION_SUBCLASS
:
87 return " (Collection)";
95 ProtocolName(int classNumber
, int subclass
, int protocol
)
97 switch (classNumber
) {
103 return " (Full speed)";
105 return " (Hi-speed, single TT)";
107 return " (Hi-speed, multiple TT)";
109 return " (Super speed)";
113 if (subclass
== 0x01 && protocol
== 0x01)
114 return " (Bluetooth)";
116 if (subclass
== 0x02 && protocol
== 0x01)
117 return " (Interface Association)";
125 DumpDescriptorData(const usb_generic_descriptor
* descriptor
)
127 printf(" Type ............. 0x%02x\n",
128 descriptor
->descriptor_type
);
130 printf(" Data ............. ");
131 // len includes len and descriptor_type field
132 for (int32 i
= 0; i
< descriptor
->length
- 2; i
++)
133 printf("%02x ", descriptor
->data
[i
]);
139 DumpDescriptor(const usb_generic_descriptor
* descriptor
,
140 int classNum
, int subclass
)
143 case USB_AUDIO_DEVICE_CLASS
:
144 DumpAudioDescriptor(descriptor
, subclass
);
146 case USB_VIDEO_DEVICE_CLASS
:
147 DumpVideoDescriptor(descriptor
, subclass
);
150 DumpDescriptorData(descriptor
);
157 DumpInterface(const BUSBInterface
* interface
)
162 printf(" Class .............. 0x%02x (%s)\n",
163 interface
->Class(), ClassName(interface
->Class()));
164 printf(" Subclass ........... 0x%02x%s\n",
165 interface
->Subclass(),
166 SubclassName(interface
->Class(), interface
->Subclass()));
167 printf(" Protocol ........... 0x%02x%s\n",
168 interface
->Protocol(), ProtocolName(interface
->Class(),
169 interface
->Subclass(), interface
->Protocol()));
170 printf(" Interface String ... \"%s\"\n",
171 interface
->InterfaceString());
173 for (uint32 i
= 0; i
< interface
->CountEndpoints(); i
++) {
174 const BUSBEndpoint
* endpoint
= interface
->EndpointAt(i
);
178 printf(" [Endpoint %" B_PRIu32
"]\n", i
);
179 printf(" MaxPacketSize .... %d\n",
180 endpoint
->MaxPacketSize());
181 printf(" Interval ......... %d\n",
182 endpoint
->Interval());
184 if (endpoint
->IsControl())
185 printf(" Type ............. Control\n");
186 else if (endpoint
->IsBulk())
187 printf(" Type ............. Bulk\n");
188 else if (endpoint
->IsIsochronous())
189 printf(" Type ............. Isochronous\n");
190 else if (endpoint
->IsInterrupt())
191 printf(" Type ............. Interrupt\n");
193 if (endpoint
->IsInput())
194 printf(" Direction ........ Input\n");
196 printf(" Direction ........ Output\n");
200 usb_descriptor
* generic
= (usb_descriptor
*)buffer
;
202 interface
->OtherDescriptorAt(i
, generic
, 256) == B_OK
; i
++) {
203 printf(" [Descriptor %" B_PRIu32
"]\n", i
);
204 DumpDescriptor(&generic
->generic
, interface
->Class(), interface
->Subclass());
210 DumpConfiguration(const BUSBConfiguration
* configuration
)
215 printf(" Configuration String . \"%s\"\n",
216 configuration
->ConfigurationString());
217 for (uint32 i
= 0; i
< configuration
->CountInterfaces(); i
++) {
218 printf(" [Interface %" B_PRIu32
"]\n", i
);
219 const BUSBInterface
* interface
= configuration
->InterfaceAt(i
);
221 for (uint32 j
= 0; j
< interface
->CountAlternates(); j
++) {
222 const BUSBInterface
* alternate
= interface
->AlternateAt(j
);
223 printf(" [Alternate %" B_PRIu32
"%s]\n", j
,
224 j
== interface
->AlternateIndex() ? " active" : "");
225 DumpInterface(alternate
);
232 DumpInfo(BUSBDevice
& device
, bool verbose
)
234 const char* vendorName
= NULL
;
235 const char* deviceName
= NULL
;
236 usb_get_vendor_info(device
.VendorID(), &vendorName
);
237 usb_get_device_info(device
.VendorID(), device
.ProductID(), &deviceName
);
240 printf("%04x:%04x /dev/bus/usb%s \"%s\" \"%s\" ver. %04x\n",
241 device
.VendorID(), device
.ProductID(), device
.Location(),
242 vendorName
? vendorName
: device
.ManufacturerString(),
243 deviceName
? deviceName
: device
.ProductString(),
248 printf("[Device /dev/bus/usb%s]\n", device
.Location());
249 printf(" Class .................. 0x%02x (%s)\n", device
.Class(),
250 ClassName(device
.Class()));
251 printf(" Subclass ............... 0x%02x%s\n", device
.Subclass(),
252 SubclassName(device
.Class(), device
.Subclass()));
253 printf(" Protocol ............... 0x%02x%s\n", device
.Protocol(),
254 ProtocolName(device
.Class(), device
.Subclass(), device
.Protocol()));
255 printf(" Max Endpoint 0 Packet .. %d\n", device
.MaxEndpoint0PacketSize());
256 uint32_t version
= device
.USBVersion();
257 printf(" USB Version ............ %d.%d\n", version
>> 8, version
& 0xFF);
258 printf(" Vendor ID .............. 0x%04x", device
.VendorID());
259 if (vendorName
!= NULL
)
260 printf(" (%s)", vendorName
);
261 printf("\n Product ID ............. 0x%04x", device
.ProductID());
262 if (deviceName
!= NULL
)
263 printf(" (%s)", deviceName
);
264 printf("\n Product Version ........ 0x%04x\n", device
.Version());
265 printf(" Manufacturer String .... \"%s\"\n", device
.ManufacturerString());
266 printf(" Product String ......... \"%s\"\n", device
.ProductString());
267 printf(" Serial Number .......... \"%s\"\n", device
.SerialNumberString());
269 for (uint32 i
= 0; i
< device
.CountConfigurations(); i
++) {
270 printf(" [Configuration %" B_PRIu32
"]\n", i
);
271 DumpConfiguration(device
.ConfigurationAt(i
));
274 if (device
.Class() != 0x09)
277 usb_hub_descriptor hubDescriptor
;
278 size_t size
= device
.GetDescriptor(USB_DESCRIPTOR_HUB
, 0, 0,
279 (void*)&hubDescriptor
, sizeof(usb_hub_descriptor
));
280 if (size
== sizeof(usb_hub_descriptor
)) {
281 printf(" Hub ports count......... %d\n", hubDescriptor
.num_ports
);
282 printf(" Hub Controller Current.. %dmA\n", hubDescriptor
.max_power
);
284 for (int index
= 1; index
<= hubDescriptor
.num_ports
; index
++) {
285 usb_port_status portStatus
;
286 size_t actualLength
= device
.ControlTransfer(USB_REQTYPE_CLASS
287 | USB_REQTYPE_OTHER_IN
, USB_REQUEST_GET_STATUS
, 0,
288 index
, sizeof(portStatus
), (void*)&portStatus
);
289 if (actualLength
!= sizeof(portStatus
))
291 printf(" Port %d status....... %04x.%04x%s%s%s%s%s%s%s%s%s\n",
292 index
, portStatus
.status
, portStatus
.change
,
293 portStatus
.status
& PORT_STATUS_CONNECTION
? " Connect": "",
294 portStatus
.status
& PORT_STATUS_ENABLE
? " Enable": "",
295 portStatus
.status
& PORT_STATUS_SUSPEND
? " Suspend": "",
296 portStatus
.status
& PORT_STATUS_OVER_CURRENT
? " Overcurrent": "",
297 portStatus
.status
& PORT_STATUS_RESET
? " Reset": "",
298 portStatus
.status
& PORT_STATUS_POWER
? " Power": "",
299 portStatus
.status
& PORT_STATUS_CONNECTION
300 ? (portStatus
.status
& PORT_STATUS_LOW_SPEED
? " Lowspeed"
301 : (portStatus
.status
& PORT_STATUS_HIGH_SPEED
? " Highspeed"
302 : " Fullspeed")) : "",
303 portStatus
.status
& PORT_STATUS_TEST
? " Test": "",
304 portStatus
.status
& PORT_STATUS_INDICATOR
? " Indicator": "");
310 class DumpRoster
: public BUSBRoster
{
312 DumpRoster(bool verbose
)
318 virtual status_t
DeviceAdded(BUSBDevice
* device
)
320 DumpInfo(*device
, fVerbose
);
325 virtual void DeviceRemoved(BUSBDevice
* device
)
336 main(int argc
, char* argv
[])
338 bool verbose
= false;
339 BString devname
= "";
340 for (int i
= 1; i
< argc
; i
++) {
341 if (argv
[i
][0] == '-') {
342 if (argv
[i
][1] == 'v')
345 printf("Usage: listusb [-v] [device]\n\n");
346 printf("-v: Show more detailed information including "
347 "interfaces, configurations, etc.\n\n");
348 printf("If a device is not specified, "
349 "all devices found on the bus will be listed\n");
356 if (devname
.Length() > 0) {
357 BUSBDevice
device(devname
.String());
358 if (device
.InitCheck() < B_OK
) {
359 printf("Cannot open USB device: %s\n", devname
.String());
362 DumpInfo(device
, verbose
);
366 DumpRoster
roster(verbose
);