diff --git a/motors/usb/usb.cc b/motors/usb/usb.cc
new file mode 100644
index 0000000..3067695
--- /dev/null
+++ b/motors/usb/usb.cc
@@ -0,0 +1,812 @@
+#include "motors/usb/usb.h"
+
+#include <string.h>
+
+#include "motors/util.h"
+
+namespace frc971 {
+namespace teensy {
+namespace {
+
+// The mask of interrupts we care about.
+constexpr uint32_t usb_enabled_interrupts() {
+  // Deliberately not turning the sleep interrupt on here because we just
+  // want to ignore that anyways.
+  return USB_INTEN_TOKDNEEN | USB_INTEN_SOFTOKEN | USB_INTEN_ERROREN |
+         USB_INTEN_USBRSTEN;
+}
+
+// The names of all the standard setup requests which come in on endpoint 0.
+namespace standard_setup_requests {
+constexpr int kGetStatus = 0;
+constexpr int kClearFeature = 1;
+constexpr int kSetFeature = 3;
+constexpr int kSetAddress = 5;
+constexpr int kGetDescriptor = 6;
+constexpr int kSetDescriptor = 7;
+constexpr int kGetConfiguration = 8;
+constexpr int kSetConfiguration = 9;
+constexpr int kGetInterface = 10;
+constexpr int kSetInterface = 11;
+constexpr int kSynchFrame = 12;
+}  // namespace standard_setup_requests
+
+// The names of the standard feature selectors.
+namespace standard_feature_selectors {
+constexpr int kDeviceRemoteWakeup = 1;
+constexpr int kEndpointHalt = 0;
+constexpr int kTestMode = 2;
+}  // namespace standard_feature_selectors
+
+// The names of all the PIDs (Packet IDs) from the USB standard. Note that this
+// USB hardware doesn't expose most of them, especially in device mode.
+enum class UsbPid {
+  kOut = 0x1,
+  kIn = 0x9,
+  kSof = 0x5,
+  kSetup = 0xD,
+  kData0 = 0x3,
+  kData1 = 0xB,
+  kData2 = 0x7,
+  kMData = 0xF,
+  kAck = 0x2,
+  kNak = 0xA,
+  kStall = 0xE,
+  kNYet = 0x6,
+  kPre = 0xC,
+  kErr = 0xC,
+  kSplit = 0x8,
+  kPing = 0x4,
+  kReserved = 0x0,
+};
+
+// The device class for using IADs.
+constexpr uint8_t iad_device_class() { return 0xEF; }
+// The device subclass for using IADs.
+constexpr uint8_t iad_device_subclass() { return 0x02; }
+// The device protocol for using IADs.
+constexpr uint8_t iad_device_protocol() { return 0x01; }
+
+// The total number of endpoints supported by this hardware.
+constexpr int number_endpoints() { return 16; }
+
+__attribute__((aligned(512))) BdtEntry
+    usb0_buffer_descriptor_table[number_endpoints() * 2 /* rx/tx */ *
+                                 2 /* even/odd */];
+
+// Returns the specified BDT entry.
+BdtEntry *MutableBdtEntry(int endpoint, Direction direction, EvenOdd odd) {
+  return &usb0_buffer_descriptor_table[static_cast<uint32_t>(endpoint << 2) |
+                                       static_cast<uint32_t>(direction) |
+                                       static_cast<uint32_t>(odd)];
+}
+
+// Returns the BDT entry corresponding to a USBx_STAT value.
+BdtEntry *MutableBdtEntryFromStat(uint8_t stat) {
+  return &usb0_buffer_descriptor_table[static_cast<uint32_t>(stat) >> 2];
+}
+
+// A pointer to the object we're going to ask to handle interrupts.
+UsbDevice *volatile global_usb0_device = nullptr;
+
+}  // namespace
+
+UsbDevice::UsbDevice(int index, uint16_t vendor_id, uint16_t product_id)
+    : index_(index) {
+  // TODO(Brian): Pass index_ into all the register access macros. Also sort out
+  // how to deal with it for the interrupts.
+  assert(index == 0);
+
+  assert(global_usb0_device == nullptr);
+  global_usb0_device = this;
+
+  // Endpoint 0 isn't a normal endpoint, so it doesn't show up in here.
+  endpoint_mapping_.push_back(nullptr);
+
+  // Set up the "String Descriptor Zero, Specifying Languages Supported by the
+  // Device" (aka english_us_code() only).
+  strings_.emplace_back(4, '\0');
+  strings_.back()[0] = 4;
+  strings_.back()[1] = static_cast<uint8_t>(UsbDescriptorType::kString);
+  strings_.back()[2] = english_us_code() & 0xFF;
+  strings_.back()[3] = (english_us_code() >> 8) & 0xFF;
+
+  device_descriptor_ =
+      device_descriptor_list_.CreateDescriptor(18, UsbDescriptorType::kDevice);
+  device_descriptor_->AddUint16(0x0200);  // bcdUSB
+  device_descriptor_->AddByte(iad_device_class());  // bDeviceClass
+  device_descriptor_->AddByte(iad_device_subclass());  // bDeviceSubClass
+  device_descriptor_->AddByte(iad_device_protocol());  // bDeviceProtocol
+  device_descriptor_->AddByte(kEndpoint0MaxSize);  // bMaxPacketSize0
+  device_descriptor_->AddUint16(vendor_id);  // idVendor
+  device_descriptor_->AddUint16(product_id);  // idProduct
+  device_descriptor_->AddUint16(0);  // bcdDevice
+  // We might overwrite these string descriptor indices later if we get strings
+  // to put there.
+  device_descriptor_->AddByte(0);  // iManufacturer
+  device_descriptor_->AddByte(0);  // iProduct
+  device_descriptor_->AddByte(0);  // iSerialNumber
+  device_descriptor_->AddByte(1);  // bNumConfigurations
+
+  config_descriptor_ = config_descriptor_list_.CreateDescriptor(
+      9, UsbDescriptorType::kConfiguration);
+}
+
+UsbDevice::~UsbDevice() {
+  NVIC_DISABLE_IRQ(IRQ_USBOTG);
+  dma_memory_barrier();
+  assert(global_usb0_device == this);
+  global_usb0_device = nullptr;
+}
+
+void UsbDevice::Initialize() {
+  assert(!is_set_up_);
+
+  for (UsbFunction *function : functions_) {
+    function->Initialize();
+  }
+
+  config_descriptor_->AddUint16(
+      config_descriptor_list_.CurrentSize());              // wTotalLength
+  config_descriptor_->AddByte(interface_mapping_.size());  // bNumInterfaces
+  config_descriptor_->AddByte(1);  // bConfigurationValue
+  // Doesn't seem to be much point naming our one and only configuration.
+  config_descriptor_->AddByte(0);  // iConfiguration
+  config_descriptor_->AddByte((1 << 7) /* Reserved */ |
+                              (1 << 6) /* Self-powered */);  // bmAttribute
+  config_descriptor_->AddByte(2 /* 4mA */);  // bMaxPower
+
+  device_descriptor_.reset();
+  config_descriptor_.reset();
+  device_descriptor_list_.CheckFinished();
+  config_descriptor_list_.CheckFinished();
+  is_set_up_ = true;
+
+  // Make sure all the buffer descriptors are clear.
+  for (int i = 0; i < number_endpoints(); ++i) {
+    for (Direction direction : {Direction::kTx, Direction::kRx}) {
+      for (EvenOdd odd : {EvenOdd::kOdd, EvenOdd::kEven}) {
+        MutableBdtEntry(i, direction, odd)->buffer_descriptor = 0;
+        MutableBdtEntry(i, direction, odd)->address = nullptr;
+      }
+    }
+  }
+  dma_memory_barrier();
+
+  // The other startup code handles getting the incoming 48MHz clock running.
+  SIM_SCGC4 |= SIM_SCGC4_USBOTG;
+  MPU_RGDAAC0 |= 0x03000000;
+
+  // Reset it.
+  USB0_USBTRC0 = USB_USBTRC_USBRESET;
+  // TRM says to wait "two USB clock cycles", so assume that's at 48MHz and then
+  // round up, being pessimistic in assuming each read from the peripheral is
+  // only a single core clock. This wildly overapproximates how long we need to
+  // wait, but whatever.
+  for (int i = 0; i < ((F_CPU / 48000000) + 1) * 2; ++i) {
+    while ((USB0_USBTRC0 & USB_USBTRC_USBRESET) != 0) {
+    }
+  }
+
+  USB0_BDTPAGE1 =
+      reinterpret_cast<uintptr_t>(&usb0_buffer_descriptor_table[0]) >> 8;
+  USB0_BDTPAGE2 =
+      reinterpret_cast<uintptr_t>(&usb0_buffer_descriptor_table[0]) >> 16;
+  USB0_BDTPAGE3 =
+      reinterpret_cast<uintptr_t>(&usb0_buffer_descriptor_table[0]) >> 24;
+
+  // The Quick Reference User Guide says to clear all the interrupts.
+  ClearInterrupts();
+  USB0_OTGISTAT = USB_OTGISTAT_ONEMSEC | USB_OTGISTAT_LINE_STATE_CHG;
+
+  // Now enable the module.
+  USB0_CTL = USB_CTL_USBENSOFEN;
+
+  // Un-suspend the transceiver and disable weak pulldowns.
+  USB0_USBCTRL = 0;
+  // And enable the D+ pullup which indicates we're a full-speed device.
+  USB0_CONTROL = USB_CONTROL_DPPULLUPNONOTG;
+
+  // Enable the reset interrupt (which is the first one we care about).
+  USB0_INTEN = USB_INTEN_USBRSTEN;
+
+  dma_memory_barrier();
+  NVIC_ENABLE_IRQ(IRQ_USBOTG);
+}
+
+void usb_isr(void) {
+  UsbDevice *const usb0_device = global_usb0_device;
+  if (usb0_device == nullptr) {
+    NVIC_DISABLE_IRQ(IRQ_USBOTG);
+  } else {
+    usb0_device->HandleInterrupt();
+  }
+}
+
+void UsbDevice::ClearInterrupts() {
+  USB0_ISTAT = USB_ISTAT_ATTACH | USB_ISTAT_RESUME | USB_ISTAT_SLEEP |
+               USB_ISTAT_TOKDNE | USB_ISTAT_SOFTOK | USB_ISTAT_ERROR |
+               USB_ISTAT_USBRST;
+  USB0_ERRSTAT = USB_ERRSTAT_BTSERR | USB_ERRSTAT_DMAERR | USB_ERRSTAT_BTOERR |
+                 USB_ERRSTAT_DFN8 | USB_ERRSTAT_CRC16 | USB_ERRSTAT_CRC5EOF |
+                 USB_ERRSTAT_PIDERR;
+}
+
+void UsbDevice::HandleInterrupt() {
+  while (true) {
+    const uint32_t status = USB0_ISTAT;
+    if ((status & usb_enabled_interrupts()) == 0) {
+      return;
+    }
+
+    // If we just got a start-of-frame token, then ask all the functions what to
+    // do.
+    if (status & USB_ISTAT_SOFTOK) {
+      // TODO(Brian): Actually ask the functions, maybe only if we're
+      // configured.
+      USB0_ISTAT = USB_ISTAT_SOFTOK;
+    }
+
+    // If we just finished processing a token.
+    if (status & USB_ISTAT_TOKDNE) {
+      const uint8_t stat = USB0_STAT;
+      const int endpoint = G_USB_STAT_ENDP(stat);
+
+      if (endpoint == 0) {
+        HandleEndpoint0Token(stat);
+      } else {
+        BdtEntry *const bdt_entry = MutableBdtEntryFromStat(stat);
+        const UsbPid pid = G_USB_BD_PID(bdt_entry->buffer_descriptor);
+        UsbFunction *const function = endpoint_mapping_[endpoint];
+        if (function == nullptr) {
+          // Should never happen, so stall if we do get here somehow.
+          StallEndpoint(endpoint);
+        } else {
+          switch (pid) {
+            case UsbPid::kOut:
+              function->HandleOutFinished(endpoint, bdt_entry);
+              break;
+
+            case UsbPid::kIn:
+              function->HandleInFinished(
+                  endpoint, bdt_entry,
+                  (stat & M_USB_STAT_ODD) ? EvenOdd::kOdd : EvenOdd::kEven);
+              break;
+
+            case UsbPid::kSetup:
+            default:
+              // Should never happen, so stall if we do get here somehow.
+              StallEndpoint(endpoint);
+              break;
+          }
+        }
+      }
+
+      USB0_ISTAT = USB_ISTAT_TOKDNE;
+    }
+
+    if (status & USB_ISTAT_USBRST) {
+      // Use DATA0 for all endpoints.
+      USB0_CTL = USB_CTL_ODDRST;
+      endpoint0_tx_odd_ = EvenOdd::kEven;
+      endpoint0_tx_toggle_ = Data01::kData0;
+
+      for (UsbFunction *function : functions_) {
+        function->HandleReset();
+      }
+
+      MutableBdtEntry(0, Direction::kRx, EvenOdd::kEven)->buffer_descriptor =
+          M_USB_BD_OWN | M_USB_BD_DTS | V_USB_BD_BC(kEndpoint0MaxSize);
+      MutableBdtEntry(0, Direction::kRx, EvenOdd::kEven)->address =
+          &endpoint0_receive_buffer_[0][0];
+
+      MutableBdtEntry(0, Direction::kRx, EvenOdd::kOdd)->buffer_descriptor =
+          M_USB_BD_OWN | M_USB_BD_DTS | V_USB_BD_BC(kEndpoint0MaxSize);
+      MutableBdtEntry(0, Direction::kRx, EvenOdd::kOdd)->address =
+          &endpoint0_receive_buffer_[1][0];
+
+      MutableBdtEntry(0, Direction::kTx, EvenOdd::kEven)->buffer_descriptor = 0;
+      MutableBdtEntry(0, Direction::kTx, EvenOdd::kOdd)->buffer_descriptor = 0;
+
+      USB0_ENDPT0 = USB_ENDPT_EPRXEN | USB_ENDPT_EPTXEN | USB_ENDPT_EPHSHK;
+
+      ClearInterrupts();
+
+      // Set the address to 0 for enumeration.
+      USB0_ADDR = 0;
+      new_address_ = 0;
+
+      endpoint0_data_ = nullptr;
+      endpoint0_data_left_ = 0;
+
+      USB0_INTEN = usb_enabled_interrupts();
+      USB0_ERREN = USB_ERREN_BTSERREN | USB_ERREN_DMAERREN |
+                   USB_ERREN_BTOERREN | USB_ERREN_DFN8EN | USB_ERREN_CRC16EN |
+                   USB_ERREN_CRC5EOFEN | USB_ERREN_PIDERREN;
+
+      // Start the peripheral going.
+      dma_memory_barrier();
+      USB0_CTL = USB_CTL_USBENSOFEN;
+
+      continue;
+    }
+
+    // TODO(Brian): Handle errors more intelligently.
+    if (status & USB_ISTAT_ERROR) {
+      const uint8_t error = USB0_ERRSTAT;
+      USB0_ERRSTAT = error;
+      USB0_ISTAT = USB_ISTAT_ERROR;
+    }
+  }
+}
+
+void UsbDevice::HandleEndpoint0Token(const uint8_t stat) {
+  BdtEntry *const bdt_entry = MutableBdtEntryFromStat(stat);
+  const UsbPid pid = G_USB_BD_PID(bdt_entry->buffer_descriptor);
+  switch (pid) {
+    case UsbPid::kSetup:
+      // Unstall it if it was previously stalled.
+      USB0_ENDPT0 = USB_ENDPT_EPRXEN | USB_ENDPT_EPTXEN | USB_ENDPT_EPHSHK;
+
+      SetupPacket setup_packet;
+      memcpy(&setup_packet, bdt_entry->address, sizeof(setup_packet));
+
+      // Give the buffer back now.
+      dma_memory_barrier();
+      // Next IN and OUT packet for this endpoint (data stage/status stage)
+      // should both be DATA1.
+      // TODO(Brian): Does this actually deal with received toggles correctly?
+      bdt_entry->buffer_descriptor =
+          M_USB_BD_OWN | M_USB_BD_DTS | V_USB_BD_BC(kEndpoint0MaxSize);
+      MutableBdtEntryFromStat(stat ^ M_USB_STAT_ODD)->buffer_descriptor =
+          M_USB_BD_OWN | M_USB_BD_DTS | V_USB_BD_BC(kEndpoint0MaxSize) |
+          M_USB_BD_DATA1;
+      endpoint0_tx_toggle_ = Data01::kData1;
+
+      // TODO(Brian): Tell the functions a new setup packet is starting.
+      // CdcTty: next_endpoint0_out_ = NextEndpoint0Out::kNone;
+
+      // Forget about any pending transactions on this endpoint. There shouldn't
+      // be any, so if we think there are something's out of sync and we should
+      // just drop it. Important to do this before clearing TXD_SUSPEND in
+      // USBx_CTL. Standard says "If a Setup transaction is received by an
+      // endpoint before a previously initiated control transfer is completed,
+      // the device must abort the current transfer/operation".
+      endpoint0_data_ = nullptr;
+      endpoint0_data_left_ = 0;
+      MutableBdtEntry(0, Direction::kTx, EvenOdd::kEven)->buffer_descriptor = 0;
+      MutableBdtEntry(0, Direction::kTx, EvenOdd::kOdd)->buffer_descriptor = 0;
+
+      HandleEndpoint0SetupPacket(setup_packet);
+
+      break;
+
+    case UsbPid::kOut:
+     for (UsbFunction *function : functions_) {
+       switch (function->HandleEndpoint0OutPacket(
+           bdt_entry->address, G_USB_BD_BC(bdt_entry->buffer_descriptor))) {
+          case SetupResponse::kIgnored:
+            break;
+          case SetupResponse::kHandled:
+            dma_memory_barrier();
+            bdt_entry->buffer_descriptor =
+                M_USB_BD_OWN | M_USB_BD_DTS | V_USB_BD_BC(kEndpoint0MaxSize);
+            return;
+          case SetupResponse::kStall:
+            bdt_entry->buffer_descriptor =
+                M_USB_BD_OWN | M_USB_BD_DTS | V_USB_BD_BC(kEndpoint0MaxSize);
+            StallEndpoint0();
+            return;
+        }
+      }
+      bdt_entry->buffer_descriptor =
+          M_USB_BD_OWN | M_USB_BD_DTS | V_USB_BD_BC(kEndpoint0MaxSize);
+      StallEndpoint0();
+      return;
+
+    case UsbPid::kIn:
+      // The functions are allowed to queue data in {endpoint0_data_,
+      // endpoint0_data_left_}, so this case deals with sending their data too.
+
+      // An IN transaction completed, so set up for the next one if appropriate.
+      if (!BufferEndpoint0TxPacket()) {
+        // After we're done, any further requests from the host should result in
+        // stalls (until the next setup token).
+        // TODO(Brian): Keep track of which direction it is and how much we've
+        // finished so we actually know when to stall it, both here and for
+        // kOut tokens.
+        //StallEndpoint0();
+      }
+
+      // If we have a new address, there is nothing left in the setup request
+      // besides a single IN packet forming the status stage, so we know the
+      // changes must be done now.
+      if (new_address_ != 0) {
+        USB0_ADDR = new_address_;
+        new_address_ = 0;
+      }
+
+      break;
+
+    default:
+      // Should never happen, but give the buffer back anyways if necessary.
+      if (!(bdt_entry->buffer_descriptor & M_USB_BD_OWN)) {
+        bdt_entry->buffer_descriptor =
+            M_USB_BD_OWN | M_USB_BD_DTS | V_USB_BD_BC(kEndpoint0MaxSize);
+      }
+      break;
+  }
+
+  // Clear the TXD_SUSPEND flag.
+  dma_memory_barrier();
+  USB0_CTL = USB_CTL_USBENSOFEN;
+}
+
+void UsbDevice::HandleEndpoint0SetupPacket(const SetupPacket &setup_packet) {
+  const bool in = setup_packet.request_type & M_SETUP_REQUEST_TYPE_IN;
+  const uint8_t recipient =
+      G_SETUP_REQUEST_TYPE_RECIPIENT(setup_packet.request_type);
+  switch (G_SETUP_REQUEST_TYPE_TYPE(setup_packet.request_type)) {
+    case SetupRequestType::kStandard:
+      switch (setup_packet.request) {
+        case standard_setup_requests::kSetAddress:
+          if (in || recipient != standard_setup_recipients::kDevice ||
+              setup_packet.index != 0 || setup_packet.length != 0) {
+            break;
+          }
+          new_address_ = setup_packet.value;
+          SendEmptyEndpoint0Packet();
+          return;
+
+        case standard_setup_requests::kSetConfiguration:
+          if (in || recipient != standard_setup_recipients::kDevice ||
+              setup_packet.index != 0 || setup_packet.length != 0) {
+            break;
+          }
+          configuration_ = setup_packet.value;
+
+          // No need to mess with endpoint0_tx_toggle_ because we reset it with
+          // each setup packet anyways.
+
+          for (int endpoint = 0;
+               endpoint < static_cast<int>(endpoint_mapping_.size());
+               ++endpoint) {
+            if (endpoint_mapping_[endpoint]) {
+              endpoint_mapping_[endpoint]->HandleConfigured(endpoint);
+            }
+          }
+
+          SendEmptyEndpoint0Packet();
+          return;
+
+        case standard_setup_requests::kClearFeature:
+          if (in || setup_packet.length != 0) {
+            break;
+          }
+          if (recipient == standard_setup_recipients::kEndpoint &&
+              setup_packet.value == standard_feature_selectors::kEndpointHalt) {
+            const int endpoint =
+                G_SETUP_REQUEST_INDEX_ENDPOINT(setup_packet.index);
+            // Our endpoint 0 doesn't support the halt feature because that's
+            // weird and not recommended by the standard.
+            if (endpoint == 0) {
+              break;
+            }
+            if (endpoint >= number_endpoints()) {
+              break;
+            }
+            USB0_ENDPTn(endpoint) &= ~USB_ENDPT_EPSTALL;
+            if (endpoint_mapping_[endpoint] != nullptr) {
+              endpoint_mapping_[endpoint]->HandleConfigured(endpoint);
+            }
+            SendEmptyEndpoint0Packet();
+            return;
+          }
+          // We should never get kDeviceRemoteWakeup because we don't advertise
+          // support for it in our configuration descriptors.
+          // We should never get kTestMode because we're not high-speed.
+          break;
+
+        case standard_setup_requests::kSetFeature:
+          if (in || setup_packet.length != 0) {
+            break;
+          }
+          if (recipient == standard_setup_recipients::kEndpoint &&
+              setup_packet.value == standard_feature_selectors::kEndpointHalt) {
+            const int endpoint =
+                G_SETUP_REQUEST_INDEX_ENDPOINT(setup_packet.index);
+            // Our endpoint 0 doesn't support the halt feature because that's
+            // weird and not recommended by the standard.
+            if (endpoint == 0) {
+              break;
+            }
+            if (endpoint >= number_endpoints()) {
+              break;
+            }
+            StallEndpoint(endpoint);
+            // TODO(Brian): Tell the appropriate function it's now stalled.
+            SendEmptyEndpoint0Packet();
+            return;
+          }
+          // We should never get kDeviceRemoteWakeup because we don't advertise
+          // support for it in our configuration descriptors.
+          // We should never get kTestMode because we're not high-speed.
+          break;
+
+        case standard_setup_requests::kGetConfiguration:
+          if (!in || recipient != standard_setup_recipients::kDevice ||
+              setup_packet.index != 0 || setup_packet.length != 1) {
+            break;
+          }
+          endpoint0_transmit_buffer_[0] = configuration_;
+          QueueEndpoint0Data(endpoint0_transmit_buffer_, 1);
+          return;
+
+        case standard_setup_requests::kGetInterface:
+          if (!in || recipient != standard_setup_recipients::kInterface ||
+              setup_packet.value != 0 || setup_packet.length != 1) {
+            break;
+          }
+          // Standard says it's unspecified in the default state and must
+          // respond with an error in the address state, so just do an error for
+          // both of them.
+          if (configuration_ == 0) {
+            break;
+          }
+          // TODO(Brian): Ask the appropriate function what alternate setting
+          // the interface has, and stall if there isn't one.
+          endpoint0_transmit_buffer_[0] = 0;
+          QueueEndpoint0Data(endpoint0_transmit_buffer_, 1);
+          return;
+
+        case standard_setup_requests::kSetInterface:
+          if (in || recipient != standard_setup_recipients::kInterface ||
+              setup_packet.length != 0) {
+            break;
+          }
+          // Standard says it's unspecified in the default state and must
+          // respond with an error in the address state, so just do an error for
+          // both of them.
+          if (configuration_ == 0) {
+            break;
+          }
+
+          // TODO(Brian): Pass to the appropriate function instead.
+          if (setup_packet.value != 0) {
+            break;
+          }
+          SendEmptyEndpoint0Packet();
+          return;
+
+        case standard_setup_requests::kGetStatus:
+          if (!in || setup_packet.value != 0 || setup_packet.length != 2) {
+            break;
+          }
+          if (recipient == standard_setup_recipients::kDevice) {
+            if (setup_packet.index != 0) {
+              break;
+            }
+            // Say that we're currently self powered.
+            endpoint0_transmit_buffer_[0] = 1;
+            endpoint0_transmit_buffer_[1] = 0;
+            QueueEndpoint0Data(endpoint0_transmit_buffer_, 2);
+            return;
+          }
+          if ((recipient == standard_setup_recipients::kInterface &&
+               setup_packet.index == 0) ||
+              (recipient == standard_setup_recipients::kEndpoint &&
+               G_SETUP_REQUEST_INDEX_ENDPOINT(setup_packet.index) == 0)) {
+            endpoint0_transmit_buffer_[0] = 0;
+            endpoint0_transmit_buffer_[1] = 0;
+            QueueEndpoint0Data(endpoint0_transmit_buffer_, 2);
+            return;
+          }
+          // Standard says it's unspecified in the default state and must
+          // respond with an error in the address state, so just do an error
+          // for both of them.
+          if (configuration_ == 0) {
+            break;
+          }
+
+          if (recipient == standard_setup_recipients::kInterface) {
+            // TODO(Brian): Check if it's actually an interface we have?
+            endpoint0_transmit_buffer_[0] = 0;
+            endpoint0_transmit_buffer_[1] = 0;
+            QueueEndpoint0Data(endpoint0_transmit_buffer_, 2);
+            return;
+          }
+
+          if (recipient == standard_setup_recipients::kEndpoint) {
+            const int endpoint =
+                G_SETUP_REQUEST_INDEX_ENDPOINT(setup_packet.index);
+            // TODO(Brian): Check if it's actually an endpoint we have?
+            if (USB0_ENDPTn(endpoint) & USB_ENDPT_EPSTALL) {
+              endpoint0_transmit_buffer_[0] = 1;
+            } else {
+              endpoint0_transmit_buffer_[0] = 0;
+            }
+            endpoint0_transmit_buffer_[1] = 0;
+            QueueEndpoint0Data(endpoint0_transmit_buffer_, 2);
+            return;
+          }
+          break;
+
+        case standard_setup_requests::kSetDescriptor:
+          // Not implementing anything for this.
+          break;
+
+        case standard_setup_requests::kSynchFrame:
+          // We don't implement any classes which use this.
+          break;
+
+        case standard_setup_requests::kGetDescriptor:
+          if (!in || recipient != standard_setup_recipients::kDevice) {
+            break;
+          }
+          const uint8_t descriptor_type_byte = (setup_packet.value >> 8) & 0xFF;
+          if (descriptor_type_byte < kUsbDescriptorTypeMin ||
+              descriptor_type_byte > kUsbDescriptorTypeMax) {
+            break;
+          }
+          const UsbDescriptorType descriptor_type =
+              static_cast<UsbDescriptorType>(descriptor_type_byte);
+          const uint8_t descriptor_index = setup_packet.value & 0xFF;
+          switch (descriptor_type) {
+            case UsbDescriptorType::kDevice:
+              if (setup_packet.index != 0 || descriptor_index != 0) {
+                break;
+              }
+              QueueEndpoint0Data(
+                  device_descriptor_list_.data_.data(),
+                  ::std::min<int>(setup_packet.length,
+                                  device_descriptor_list_.data_.size()));
+              return;
+
+            case UsbDescriptorType::kConfiguration:
+              if (setup_packet.index != 0 || descriptor_index != 0) {
+                break;
+              }
+              QueueEndpoint0Data(
+                  config_descriptor_list_.data_.data(),
+                  ::std::min<int>(setup_packet.length,
+                                  config_descriptor_list_.data_.size()));
+              return;
+
+            case UsbDescriptorType::kString:
+              if (descriptor_index != 0 && setup_packet.index != english_us_code()) {
+                break;
+              }
+              if (descriptor_index >= strings_.size()) {
+                break;
+              }
+              QueueEndpoint0Data(
+                  strings_[descriptor_index].data(),
+                  ::std::min<int>(setup_packet.length,
+                                  strings_[descriptor_index].size()));
+              return;
+
+            default:
+              // TODO(Brian): Handle other types of descriptor too.
+              break;
+          }
+      }
+      break;
+
+    default:
+      for (UsbFunction *function : functions_) {
+        switch (function->HandleEndpoint0SetupPacket(setup_packet)) {
+          case SetupResponse::kIgnored:
+            continue;
+          case SetupResponse::kHandled:
+            return;
+          case SetupResponse::kStall:
+            break;
+        }
+        break;
+      }
+      break;
+  }
+
+  StallEndpoint0();
+}
+
+// We're supposed to continue returning stalls until the next kSetup packet.
+// Code might continue putting stuff in the TX buffers, but the hardware won't
+// actually send it as long as the EPSTALL bit is set.
+void UsbDevice::StallEndpoint0() {
+  USB0_ENDPT0 = USB_ENDPT_EPSTALL | USB_ENDPT_EPRXEN | USB_ENDPT_EPTXEN |
+                USB_ENDPT_EPHSHK;
+}
+
+bool UsbDevice::BufferEndpoint0TxPacket() {
+  if (endpoint0_data_ == nullptr) {
+    return false;
+  }
+
+  const int to_transmit = ::std::min(endpoint0_data_left_, kEndpoint0MaxSize);
+  BdtEntry *const tx_bdt_entry =
+      MutableBdtEntry(0, Direction::kTx, endpoint0_tx_odd_);
+  // const_cast is safe because the hardware is only going to read from
+  // this, not write.
+  tx_bdt_entry->address =
+      const_cast<void *>(static_cast<const void *>(endpoint0_data_));
+  dma_memory_barrier();
+  tx_bdt_entry->buffer_descriptor =
+      V_USB_BD_BC(to_transmit) | static_cast<uint32_t>(endpoint0_tx_toggle_) |
+      M_USB_BD_OWN | M_USB_BD_DTS;
+
+  endpoint0_tx_odd_ = EvenOddInverse(endpoint0_tx_odd_);
+  endpoint0_tx_toggle_ = Data01Inverse(endpoint0_tx_toggle_);
+
+  endpoint0_data_ += to_transmit;
+  endpoint0_data_left_ -= to_transmit;
+  if (to_transmit < kEndpoint0MaxSize) {
+    endpoint0_data_ = nullptr;
+  }
+
+  return true;
+}
+
+void UsbDevice::SendEmptyEndpoint0Packet() {
+  // Really doesn't matter what we put here as long as it's not nullptr.
+  endpoint0_data_ = reinterpret_cast<char *>(this);
+  endpoint0_data_left_ = 0;
+  BufferEndpoint0TxPacket();
+}
+
+void UsbDevice::QueueEndpoint0Data(const char *data, int size) {
+  endpoint0_data_ = data;
+  endpoint0_data_left_ = size;
+  // There are 2 TX buffers, so fill them both up.
+  BufferEndpoint0TxPacket();
+  BufferEndpoint0TxPacket();
+}
+
+void UsbDevice::StallEndpoint(int endpoint) {
+  for (Direction direction : {Direction::kTx, Direction::kRx}) {
+    for (EvenOdd odd : {EvenOdd::kOdd, EvenOdd::kEven}) {
+      MutableBdtEntry(endpoint, direction, odd)->buffer_descriptor = 0;
+      dma_memory_barrier();
+      MutableBdtEntry(endpoint, direction, odd)->address = nullptr;
+    }
+  }
+  USB0_ENDPTn(endpoint) |= USB_ENDPT_EPSTALL;
+}
+
+void UsbDevice::ConfigureEndpointFor(int endpoint, bool rx, bool tx,
+                                     bool handshake) {
+  uint8_t control = 0;
+  if (rx) {
+    control |= USB_ENDPT_EPRXEN;
+  }
+  if (tx) {
+    control |= USB_ENDPT_EPTXEN;
+  }
+  if (handshake) {
+    control |= USB_ENDPT_EPHSHK;
+  }
+  USB0_ENDPTn(endpoint) = control;
+}
+
+int UsbFunction::AddEndpoint() {
+  const int r = device_->endpoint_mapping_.size();
+  assert(r < number_endpoints());
+  device_->endpoint_mapping_.push_back(this);
+  return r;
+}
+
+int UsbFunction::AddInterface() {
+  const int r = device_->interface_mapping_.size();
+  // bInterfaceNumber is only one byte.
+  assert(r < 255);
+  device_->interface_mapping_.push_back(this);
+  return r;
+}
+
+void UsbDevice::SetBdtEntry(int endpoint, Direction direction, EvenOdd odd,
+                            BdtEntry bdt_entry) {
+  *MutableBdtEntry(endpoint, direction, odd) = bdt_entry;
+}
+
+}  // namespace teensy
+}  // namespace frc971
