요약·해설과 원문, 전문 번역을 서로 분리했습니다. API 이름, symbol, source path는 원문 표기를 사용합니다.
1. 요약·해설
원문의 핵심 논리와 kernel programming 관점의 보충 설명입니다. 아래의 전문 번역과는 별도로 작성했습니다.
2. 영어 원문 전체
번역 기준이 된 Linux v6.18.37 원문입니다. 줄 번호는 이 버전의 파일 좌표입니다.
원문 전체 펼치기
.. _usb-error-codes:
USB Error codes
~~~~~~~~~~~~~~~
:Revised: 2004-Oct-21
This is the documentation of (hopefully) all possible error codes (and
their interpretation) that can be returned from usbcore.
Some of them are returned by the Host Controller Drivers (HCDs), which
device drivers only see through usbcore. As a rule, all the HCDs should
behave the same except for transfer speed dependent behaviors and the
way certain faults are reported.
Error codes returned by :c:func:`usb_submit_urb`
================================================
Non-USB-specific:
=============== ===============================================
0 URB submission went fine
``-ENOMEM`` no memory for allocation of internal structures
=============== ===============================================
USB-specific:
======================= =======================================================
``-EBUSY`` The URB is already active.
``-ENODEV`` specified USB-device or bus doesn't exist
``-ENOENT`` specified interface or endpoint does not exist or
is not enabled
``-ENXIO`` host controller driver does not support queuing of
this type of urb. (treat as a host controller bug.)
``-EINVAL`` a) Invalid transfer type specified (or not supported)
b) Invalid or unsupported periodic transfer interval
c) ISO: attempted to change transfer interval
d) ISO: ``number_of_packets`` is < 0
e) various other cases
``-EXDEV`` ISO: ``URB_ISO_ASAP`` wasn't specified and all the
frames the URB would be scheduled in have already
expired.
``-EFBIG`` Host controller driver can't schedule that many ISO
frames.
``-EPIPE`` The pipe type specified in the URB doesn't match the
endpoint's actual type.
``-EMSGSIZE`` (a) endpoint maxpacket size is zero; it is not usable
in the current interface altsetting.
(b) ISO packet is larger than the endpoint maxpacket.
(c) requested data transfer length is invalid: negative
or too large for the host controller.
``-EBADR`` The wLength value in a control URB's setup packet does
not match the URB's transfer_buffer_length.
``-ENOSPC`` This request would overcommit the usb bandwidth reserved
for periodic transfers (interrupt, isochronous).
``-ESHUTDOWN`` The device or host controller has been disabled due to
some problem that could not be worked around.
``-EPERM`` Submission failed because ``urb->reject`` was set.
``-EHOSTUNREACH`` URB was rejected because the device is suspended.
``-ENOEXEC`` A control URB doesn't contain a Setup packet.
======================= =======================================================
Error codes returned by ``in urb->status`` or in ``iso_frame_desc[n].status`` (for ISO)
=======================================================================================
USB device drivers may only test urb status values in completion handlers.
This is because otherwise there would be a race between HCDs updating
these values on one CPU, and device drivers testing them on another CPU.
A transfer's actual_length may be positive even when an error has been
reported. That's because transfers often involve several packets, so that
one or more packets could finish before an error stops further endpoint I/O.
For isochronous URBs, the urb status value is non-zero only if the URB is
unlinked, the device is removed, the host controller is disabled, or the total
transferred length is less than the requested length and the
``URB_SHORT_NOT_OK`` flag is set. Completion handlers for isochronous URBs
should only see ``urb->status`` set to zero, ``-ENOENT``, ``-ECONNRESET``,
``-ESHUTDOWN``, or ``-EREMOTEIO``. Individual frame descriptor status fields
may report more status codes.
=============================== ===============================================
0 Transfer completed successfully
``-ENOENT`` URB was synchronously unlinked by
:c:func:`usb_unlink_urb`
``-EINPROGRESS`` URB still pending, no results yet
(That is, if drivers see this it's a bug.)
``-EPROTO`` [#f1]_, [#f2]_ a) bitstuff error
b) no response packet received within the
prescribed bus turn-around time
c) unknown USB error
``-EILSEQ`` [#f1]_, [#f2]_ a) CRC mismatch
b) no response packet received within the
prescribed bus turn-around time
c) unknown USB error
Note that often the controller hardware does
not distinguish among cases a), b), and c), so
a driver cannot tell whether there was a
protocol error, a failure to respond (often
caused by device disconnect), or some other
fault.
``-ETIME`` [#f2]_ No response packet received within the
prescribed bus turn-around time. This error
may instead be reported as
``-EPROTO`` or ``-EILSEQ``.
``-ETIMEDOUT`` Synchronous USB message functions use this code
to indicate timeout expired before the transfer
completed, and no other error was reported
by HC.
``-EPIPE`` [#f2]_ Endpoint stalled. For non-control endpoints,
reset this status with
:c:func:`usb_clear_halt`.
``-ECOMM`` During an IN transfer, the host controller
received data from an endpoint faster than it
could be written to system memory
``-ENOSR`` During an OUT transfer, the host controller
could not retrieve data from system memory fast
enough to keep up with the USB data rate
``-EOVERFLOW`` [#f1]_ The amount of data returned by the endpoint was
greater than either the max packet size of the
endpoint or the remaining buffer size.
"Babble".
``-EREMOTEIO`` The data read from the endpoint did not fill
the specified buffer, and ``URB_SHORT_NOT_OK``
was set in ``urb->transfer_flags``.
``-ENODEV`` Device was removed. Often preceded by a burst
of other errors, since the hub driver doesn't
detect device removal events immediately.
``-EXDEV`` ISO transfer only partially completed
(only set in ``iso_frame_desc[n].status``,
not ``urb->status``)
``-EINVAL`` ISO madness, if this happens: Log off and
go home
``-ECONNRESET`` URB was asynchronously unlinked by
:c:func:`usb_unlink_urb`
``-ESHUTDOWN`` The device or host controller has been
disabled due to some problem that could not
be worked around, such as a physical
disconnect.
=============================== ===============================================
.. [#f1]
Error codes like ``-EPROTO``, ``-EILSEQ`` and ``-EOVERFLOW`` normally
indicate hardware problems such as bad devices (including firmware)
or cables.
.. [#f2]
This is also one of several codes that different kinds of host
controller use to indicate a transfer has failed because of device
disconnect. In the interval before the hub driver starts disconnect
processing, devices may receive such fault reports for every request.
Error codes returned by usbcore-functions
=========================================
.. note:: expect also other submit and transfer status codes
:c:func:`usb_register`:
======================= ===================================
``-EINVAL`` error during registering new driver
======================= ===================================
``usb_get_*/usb_set_*()``,
:c:func:`usb_control_msg`,
:c:func:`usb_bulk_msg()`:
======================= ==============================================
``-ETIMEDOUT`` Timeout expired before the transfer completed.
======================= ==============================================
3. 한국어 전문 번역
영어 원문의 문단 순서와 의미를 유지한 전체 번역입니다. 코드, 함수명, symbol과 URL은 원문 표기를 유지합니다.
USB 오류 코드 개요
1-16이 문서는 usbcore가 반환할 수 있는 모든 오류 코드와 그 해석을 정리합니다. 2004년 10월 21일에 개정되었습니다.
일부 오류는 Host Controller Driver(HCD)가 생성하고 device driver는 usbcore를 통해서만 봅니다. 원칙적으로 모든 HCD는 전송 속도에 따른 동작과 특정 fault를 보고하는 방식만 제외하면 같은 의미로 동작해야 합니다.
.. _usb-error-codes:
USB Error codes
~~~~~~~~~~~~~~~
:Revised: 2004-Oct-21
This is the documentation of (hopefully) all possible error codes (and
their interpretation) that can be returned from usbcore.
Some of them are returned by the Host Controller Drivers (HCDs), which
device drivers only see through usbcore. As a rule, all the HCDs should
behave the same except for transfer speed dependent behaviors and the
way certain faults are reported.
usb_submit_urb() 반환 코드
17-79`usb_submit_urb()`의 일반 반환값에서 `0`은 URB 제출 성공을 뜻하고 `-ENOMEM`은 내부 구조체를 할당할 메모리가 없음을 뜻합니다.
USB 전용 제출 오류는 URB의 활성 상태, device·interface·endpoint 존재 여부, HCD 기능, 전송 유형과 주기, ISO frame 예약, pipe 유형, packet·buffer 크기, control setup packet, bandwidth, controller 상태와 suspend 상태를 검사하는 단계에서 발생합니다.
Error codes returned by :c:func:`usb_submit_urb`
================================================
Non-USB-specific:
=============== ===============================================
0 URB submission went fine
``-ENOMEM`` no memory for allocation of internal structures
=============== ===============================================
USB-specific:
======================= =======================================================
``-EBUSY`` The URB is already active.
``-ENODEV`` specified USB-device or bus doesn't exist
``-ENOENT`` specified interface or endpoint does not exist or
is not enabled
``-ENXIO`` host controller driver does not support queuing of
this type of urb. (treat as a host controller bug.)
``-EINVAL`` a) Invalid transfer type specified (or not supported)
b) Invalid or unsupported periodic transfer interval
c) ISO: attempted to change transfer interval
d) ISO: ``number_of_packets`` is < 0
e) various other cases
``-EXDEV`` ISO: ``URB_ISO_ASAP`` wasn't specified and all the
frames the URB would be scheduled in have already
expired.
``-EFBIG`` Host controller driver can't schedule that many ISO
frames.
``-EPIPE`` The pipe type specified in the URB doesn't match the
endpoint's actual type.
``-EMSGSIZE`` (a) endpoint maxpacket size is zero; it is not usable
in the current interface altsetting.
(b) ISO packet is larger than the endpoint maxpacket.
(c) requested data transfer length is invalid: negative
or too large for the host controller.
``-EBADR`` The wLength value in a control URB's setup packet does
not match the URB's transfer_buffer_length.
``-ENOSPC`` This request would overcommit the usb bandwidth reserved
for periodic transfers (interrupt, isochronous).
``-ESHUTDOWN`` The device or host controller has been disabled due to
some problem that could not be worked around.
``-EPERM`` Submission failed because ``urb->reject`` was set.
``-EHOSTUNREACH`` URB was rejected because the device is suspended.
``-ENOEXEC`` A control URB doesn't contain a Setup packet.
======================= =======================================================
URB와 ISO frame status 판독 규칙
80-99`urb->status`와 ISO의 `iso_frame_desc[n].status`는 completion handler 안에서만 검사해야 합니다. 다른 위치에서 읽으면 한 CPU에서 HCD가 값을 갱신하는 동안 다른 CPU에서 device driver가 검사하는 race가 생길 수 있습니다.
오류가 보고되어도 `actual_length`는 양수일 수 있습니다. 전송은 흔히 여러 packet으로 구성되므로 오류가 이후 endpoint I/O를 중단하기 전에 일부 packet이 완료될 수 있기 때문입니다.
Isochronous URB의 `urb->status`는 URB가 unlink됐거나, device가 제거됐거나, host controller가 disable됐거나, 전체 전송 길이가 요청보다 짧고 `URB_SHORT_NOT_OK`가 설정된 경우에만 0이 아닙니다.
따라서 ISO completion handler의 `urb->status`에는 `0`, `-ENOENT`, `-ECONNRESET`, `-ESHUTDOWN`, `-EREMOTEIO`만 나타나야 합니다. 개별 frame descriptor의 status에는 더 다양한 코드가 올 수 있습니다.
동시성과 부분 전송을 고려한 판독 흐름입니다.
Error codes returned by ``in urb->status`` or in ``iso_frame_desc[n].status`` (for ISO)
=======================================================================================
USB device drivers may only test urb status values in completion handlers.
This is because otherwise there would be a race between HCDs updating
these values on one CPU, and device drivers testing them on another CPU.
A transfer's actual_length may be positive even when an error has been
reported. That's because transfers often involve several packets, so that
one or more packets could finish before an error stops further endpoint I/O.
For isochronous URBs, the urb status value is non-zero only if the URB is
unlinked, the device is removed, the host controller is disabled, or the total
transferred length is less than the requested length and the
``URB_SHORT_NOT_OK`` flag is set. Completion handlers for isochronous URBs
should only see ``urb->status`` set to zero, ``-ENOENT``, ``-ECONNRESET``,
``-ESHUTDOWN``, or ``-EREMOTEIO``. Individual frame descriptor status fields
may report more status codes.
전송 완료 status 코드
100-177완료 status의 `0`은 성공입니다. unlink 방식에 따라 동기식 `usb_unlink_urb()`는 `-ENOENT`, 비동기식 unlink는 `-ECONNRESET`을 남깁니다. `-EINPROGRESS`는 아직 결과가 없는 pending 상태이므로 completion handler에서 driver가 보게 되면 bug입니다.
`-EPROTO`, `-EILSEQ`, `-ETIME`은 bitstuff, CRC, 응답 시간 초과 또는 알 수 없는 USB 오류를 표현할 수 있습니다. controller hardware가 원인을 구별하지 못하는 경우가 많아 protocol 오류, device disconnect에 따른 무응답, 다른 fault를 driver가 확정할 수 없을 수 있습니다.
전송 오류가 있더라도 endpoint에서 반환한 data가 max packet 또는 남은 buffer를 넘으면 `-EOVERFLOW`, 짧은 read와 `URB_SHORT_NOT_OK` 조합이면 `-EREMOTEIO`가 됩니다. IN·OUT 방향에서 system memory 처리 속도가 USB data rate를 따라가지 못하는 경우에는 각각 `-ECOMM`, `-ENOSR`을 사용합니다.
=============================== ===============================================
0 Transfer completed successfully
``-ENOENT`` URB was synchronously unlinked by
:c:func:`usb_unlink_urb`
``-EINPROGRESS`` URB still pending, no results yet
(That is, if drivers see this it's a bug.)
``-EPROTO`` [#f1]_, [#f2]_ a) bitstuff error
b) no response packet received within the
prescribed bus turn-around time
c) unknown USB error
``-EILSEQ`` [#f1]_, [#f2]_ a) CRC mismatch
b) no response packet received within the
prescribed bus turn-around time
c) unknown USB error
Note that often the controller hardware does
not distinguish among cases a), b), and c), so
a driver cannot tell whether there was a
protocol error, a failure to respond (often
caused by device disconnect), or some other
fault.
``-ETIME`` [#f2]_ No response packet received within the
prescribed bus turn-around time. This error
may instead be reported as
``-EPROTO`` or ``-EILSEQ``.
``-ETIMEDOUT`` Synchronous USB message functions use this code
to indicate timeout expired before the transfer
completed, and no other error was reported
by HC.
``-EPIPE`` [#f2]_ Endpoint stalled. For non-control endpoints,
reset this status with
:c:func:`usb_clear_halt`.
``-ECOMM`` During an IN transfer, the host controller
received data from an endpoint faster than it
could be written to system memory
``-ENOSR`` During an OUT transfer, the host controller
could not retrieve data from system memory fast
enough to keep up with the USB data rate
``-EOVERFLOW`` [#f1]_ The amount of data returned by the endpoint was
greater than either the max packet size of the
endpoint or the remaining buffer size.
"Babble".
``-EREMOTEIO`` The data read from the endpoint did not fill
the specified buffer, and ``URB_SHORT_NOT_OK``
was set in ``urb->transfer_flags``.
``-ENODEV`` Device was removed. Often preceded by a burst
of other errors, since the hub driver doesn't
detect device removal events immediately.
``-EXDEV`` ISO transfer only partially completed
(only set in ``iso_frame_desc[n].status``,
not ``urb->status``)
``-EINVAL`` ISO madness, if this happens: Log off and
go home
``-ECONNRESET`` URB was asynchronously unlinked by
:c:func:`usb_unlink_urb`
``-ESHUTDOWN`` The device or host controller has been
disabled due to some problem that could not
be worked around, such as a physical
disconnect.
=============================== ===============================================
하드웨어 fault 각주와 usbcore 함수
178-210`-EPROTO`, `-EILSEQ`, `-EOVERFLOW` 같은 코드는 보통 device·firmware 불량이나 cable 문제 같은 hardware fault를 나타냅니다.
`-EPROTO`, `-EILSEQ`, `-ETIME`, `-EPIPE` 등은 host controller 종류에 따라 device disconnect 때문에 전송이 실패했음을 나타내는 코드로도 사용됩니다. Hub driver가 disconnect 처리를 시작하기 전까지 device의 모든 request에 이런 fault가 보고될 수 있습니다.
usbcore 함수는 아래 값 외에도 앞에서 설명한 제출 오류와 전송 status를 반환할 수 있습니다. `usb_register()`의 `-EINVAL`은 새 driver 등록 중 오류를 뜻합니다.
`usb_get_*()`·`usb_set_*()`, `usb_control_msg()`, `usb_bulk_msg()`의 `-ETIMEDOUT`은 전송이 완료되기 전에 timeout이 만료됐음을 뜻합니다.
.. [#f1]
Error codes like ``-EPROTO``, ``-EILSEQ`` and ``-EOVERFLOW`` normally
indicate hardware problems such as bad devices (including firmware)
or cables.
.. [#f2]
This is also one of several codes that different kinds of host
controller use to indicate a transfer has failed because of device
disconnect. In the interval before the hub driver starts disconnect
processing, devices may receive such fault reports for every request.
Error codes returned by usbcore-functions
=========================================
.. note:: expect also other submit and transfer status codes
:c:func:`usb_register`:
======================= ===================================
``-EINVAL`` error during registering new driver
======================= ===================================
``usb_get_*/usb_set_*()``,
:c:func:`usb_control_msg`,
:c:func:`usb_bulk_msg()`:
======================= ==============================================
``-ETIMEDOUT`` Timeout expired before the transfer completed.
======================= ==============================================
요약·해설
error-codes.rst:1-210USB 오류는 제출 단계, HCD 전송 완료, ISO frame, device disconnect와 usbcore 동기 helper에서 서로 다른 의미로 나타납니다. Status는 completion handler에서만 읽고 부분 전송 길이와 controller별 fault 표현 차이를 함께 해석해야 합니다.