def _accept_responses(self, expected_header, info_cb, timeout_ms=None):
    """Accepts responses until the expected header or a FAIL.

    Arguments:
      expected_header: OKAY or DATA
      info_cb: Optional callback for text sent from the bootloader.
      timeout_ms: Timeout in milliseconds to wait for each response.

    Raises:
      FastbootStateMismatch: Fastboot responded with the wrong packet type.
      FastbootRemoteFailure: Fastboot reported failure.
      FastbootInvalidResponse: Fastboot responded with an unknown packet type.

    Returns:
      OKAY packet's message.
    """
    while True:
      response = self.usb.read(64, timeout_ms=timeout_ms)
      header = response[:4]
      remaining = response[4:]

      if header == 'INFO':
        info_cb(FastbootMessage(remaining, header))
      elif header in self.FINAL_HEADERS:
        if header != expected_header:
          raise usb_exceptions.FastbootStateMismatch(
              'Expected %s, got %s', expected_header, header)
        if header == 'OKAY':
          info_cb(FastbootMessage(remaining, header))
        return remaining
      elif header == 'FAIL':
        info_cb(FastbootMessage(remaining, header))
        raise usb_exceptions.FastbootRemoteFailure('FAIL: %s', remaining)
      else:
        raise usb_exceptions.FastbootInvalidResponse(
            'Got unknown header %s and response %s', header, remaining)