blob: 58b9cb0a1741cbdc19a9e4adb2e0bdae08c15e40 [file] [log] [blame]
// Copyright 2019 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "usb-spew.h"
#include <stdio.h>
#include <ddk/debug.h>
namespace mt_usb_hci {
void SpewUsbDeviceDescriptor(const usb_device_descriptor_t& d) {
// Here and below, used until std::string is fully available.
char buf[100];
// clang-format off
switch (d.bDeviceClass) {
case USB_CLASS_AUDIO: snprintf(buf, 100, "AUDIO"); break;
case USB_CLASS_COMM: snprintf(buf, 100, "COMM"); break;
case USB_CLASS_HID: snprintf(buf, 100, "HID"); break;
case USB_CLASS_PHYSICAL: snprintf(buf, 100, "PHYSICAL"); break;
case USB_CLASS_IMAGING: snprintf(buf, 100, "IMAGING"); break;
case USB_CLASS_PRINTER: snprintf(buf, 100, "PRINTER"); break;
case USB_CLASS_MSC: snprintf(buf, 100, "MSC"); break;
case USB_CLASS_HUB: snprintf(buf, 100, "HUB"); break;
case USB_CLASS_CDC: snprintf(buf, 100, "CDC"); break;
case USB_CLASS_CCID: snprintf(buf, 100, "CCID"); break;
case USB_CLASS_SECURITY: snprintf(buf, 100, "SECURITY"); break;
case USB_CLASS_VIDEO: snprintf(buf, 100, "VIDEO"); break;
case USB_CLASS_HEALTHCARE: snprintf(buf, 100, "HEALTHCARE"); break;
case USB_CLASS_DIAGNOSTIC: snprintf(buf, 100, "DIAGNOSTIC"); break;
case USB_CLASS_WIRELESS: snprintf(buf, 100, "WIRELESS"); break;
case USB_CLASS_MISC: snprintf(buf, 100, "MISC"); break;
case USB_CLASS_APPLICATION_SPECIFIC: snprintf(buf, 100, "APP-SPECIFIC"); break;
case USB_CLASS_VENDOR: snprintf(buf, 100, "VENDOR-SPECIFIC"); break;
default: snprintf(buf, 100, "???"); break;
}
zxlogf(TRACE, " === usb_device_descriptor_t ===");
zxlogf(TRACE, " .bLength = %d", d.bLength);
zxlogf(TRACE, " .bDescriptorType = <DEVICE_DESCRIPTOR>");
zxlogf(TRACE, " .bcdUSB = 0x%04x", d.bcdUSB);
zxlogf(TRACE, " .bDeviceClass = 0x%02x <%s>", d.bDeviceClass, buf);
zxlogf(TRACE, " .bDeviceSubClass = 0x%02x", d.bDeviceSubClass);
zxlogf(TRACE, " .bDeviceProtocol = 0x%02x", d.bDeviceProtocol);
zxlogf(TRACE, " .bMaxPacketSize0 = %d", d.bMaxPacketSize0);
zxlogf(TRACE, " .idVendor = 0x%04x", d.idVendor);
zxlogf(TRACE, " .idProduct = 0x%04x", d.idProduct);
zxlogf(TRACE, " .bcdDevice = 0x%04x", d.bcdDevice);
zxlogf(TRACE, " .iManufacturer = 0x%02x", d.iManufacturer);
zxlogf(TRACE, " .iProduct = 0x%02x", d.iProduct);
zxlogf(TRACE, " .iSerialNumber = 0x%02x", d.iSerialNumber);
zxlogf(TRACE, " .bNumConfigurations = %d", d.bNumConfigurations);
// clang-format on
}
void SpewUsbEndpointDescriptor(const usb_endpoint_descriptor_t& d) {
int off;
char addr_buf[100];
// Decode the endpoint address and direction.
off = snprintf(addr_buf, 100, "ep=%d,", usb_ep_num(&d));
off = snprintf(addr_buf + off, 100 - off, "%s", usb_ep_direction(&d) ? "IN" : "OUT");
// Decode the endpoint type.
char attr_buf[100];
// clang-format off
switch (static_cast<uint8_t>(usb_ep_type(&d))) {
case USB_ENDPOINT_CONTROL: snprintf(attr_buf, 100, "CONTROL"); break;
case USB_ENDPOINT_ISOCHRONOUS: snprintf(attr_buf, 100, "ISOCHRONOUS"); break;
case USB_ENDPOINT_BULK: snprintf(attr_buf, 100, "BULK"); break;
case USB_ENDPOINT_INTERRUPT: snprintf(attr_buf, 100, "INTERRUPT"); break;
default: snprintf(attr_buf, 100, "???"); break;
}
zxlogf(TRACE, " === usb_endpoint_descriptor_t ===");
zxlogf(TRACE, " .bLength = %d", d.bLength);
zxlogf(TRACE, " .bDescriptorType = <ENDPOINT_DESCRIPTOR>");
zxlogf(TRACE, " .bEndpointAddress = 0x%02x <%s>", d.bEndpointAddress, addr_buf);
zxlogf(TRACE, " .bmAttributes = 0x%02x <%s>", d.bmAttributes, attr_buf);
zxlogf(TRACE, " .wMaxPacketSize = 0x%04x", d.wMaxPacketSize);
zxlogf(TRACE, " .bInterval = %d", d.bInterval);
// clang-format on
}
void SpewUsbRequest(const usb_request_t& req) {
char buf[100];
// clang-format off
switch (req.setup.bRequest) {
case USB_REQ_GET_STATUS: snprintf(buf, 100, "GET_STATUS"); break;
case USB_REQ_CLEAR_FEATURE: snprintf(buf, 100, "CLEAR_FEATURE"); break;
case USB_REQ_SET_FEATURE: snprintf(buf, 100, "SET_FEATURE"); break;
case USB_REQ_SET_ADDRESS: snprintf(buf, 100, "SET_ADDRESS"); break;
case USB_REQ_GET_DESCRIPTOR: snprintf(buf, 100, "GET_DESCRIPTOR"); break;
case USB_REQ_SET_DESCRIPTOR: snprintf(buf, 100, "SET_DESCRIPTOR"); break;
case USB_REQ_GET_CONFIGURATION: snprintf(buf, 100, "GET_CONFIGURATION"); break;
case USB_REQ_SET_CONFIGURATION: snprintf(buf, 100, "SET_CONFIGURATION"); break;
case USB_REQ_GET_INTERFACE: snprintf(buf, 100, "GET_INTERFACE"); break;
case USB_REQ_SET_INTERFACE: snprintf(buf, 100, "SET_INTERFACE"); break;
case USB_REQ_SYNCH_FRAME: snprintf(buf, 100, "SYNCH_FRAME"); break;
default: snprintf(buf, 100, "???"); break;
}
zxlogf(TRACE, " === usb_header_t ===");
zxlogf(TRACE, " .frame = %ld", req.header.frame);
zxlogf(TRACE, " .device_id = %d", req.header.device_id);
zxlogf(TRACE, " .ep_address = %d", req.header.ep_address);
zxlogf(TRACE, " .length = %ld", req.header.length);
zxlogf(TRACE, " .send_zlp = %d", req.header.send_zlp);
zxlogf(TRACE, " === usb_setup_t ===");
zxlogf(TRACE, " .bmRequestType = 0x%02x", req.setup.bmRequestType);
zxlogf(TRACE, " .bRequest = %d <%s>", req.setup.bRequest, buf);
zxlogf(TRACE, " .wValue = 0x%04x", req.setup.wValue);
zxlogf(TRACE, " .wIndex = 0x%04x", req.setup.wIndex);
zxlogf(TRACE, " .wLength = %d", req.setup.wLength);
// clang-format on
}
} // namespace mt_usb_hci