€•ŽÂŒsphinx.addnodes”Œdocument”“”)�”}”(Œ rawsource”Œ”Œchildren”]”(Œ translations”Œ LanguagesNode”“”)�”}”(hhh]”(hŒ pending_xref”“”)�”}”(hhh]”Œdocutils.nodes”ŒText”“”ŒChinese (Simplified)”…”�”}”Œparent”hsbaŒ attributes”}”(Œids”]”Œclasses”]”Œnames”]”Œdupnames”]”Œbackrefs”]”Œ refdomain”Œstd”Œreftype”Œdoc”Œ reftarget”Œ&/translations/zh_CN/driver-api/usb/URB”Œmodname”NŒ classname”NŒ refexplicit”ˆuŒtagname”hhh ubh)�”}”(hhh]”hŒChinese (Traditional)”…”�”}”hh2sbah}”(h]”h ]”h"]”h$]”h&]”Œ refdomain”h)Œreftype”h+Œ reftarget”Œ&/translations/zh_TW/driver-api/usb/URB”Œmodname”NŒ classname”NŒ refexplicit”ˆuh1hhh ubh)�”}”(hhh]”hŒItalian”…”�”}”hhFsbah}”(h]”h ]”h"]”h$]”h&]”Œ refdomain”h)Œreftype”h+Œ reftarget”Œ&/translations/it_IT/driver-api/usb/URB”Œmodname”NŒ classname”NŒ refexplicit”ˆuh1hhh ubh)�”}”(hhh]”hŒJapanese”…”�”}”hhZsbah}”(h]”h ]”h"]”h$]”h&]”Œ refdomain”h)Œreftype”h+Œ reftarget”Œ&/translations/ja_JP/driver-api/usb/URB”Œmodname”NŒ classname”NŒ refexplicit”ˆuh1hhh ubh)�”}”(hhh]”hŒKorean”…”�”}”hhnsbah}”(h]”h ]”h"]”h$]”h&]”Œ refdomain”h)Œreftype”h+Œ reftarget”Œ&/translations/ko_KR/driver-api/usb/URB”Œmodname”NŒ classname”NŒ refexplicit”ˆuh1hhh ubh)�”}”(hhh]”hŒPortuguese (Brazilian)”…”�”}”hh‚sbah}”(h]”h ]”h"]”h$]”h&]”Œ refdomain”h)Œreftype”h+Œ reftarget”Œ&/translations/pt_BR/driver-api/usb/URB”Œmodname”NŒ classname”NŒ refexplicit”ˆuh1hhh ubh)�”}”(hhh]”hŒSpanish”…”�”}”hh–sbah}”(h]”h ]”h"]”h$]”h&]”Œ refdomain”h)Œreftype”h+Œ reftarget”Œ&/translations/sp_SP/driver-api/usb/URB”Œmodname”NŒ classname”NŒ refexplicit”ˆuh1hhh ubeh}”(h]”h ]”h"]”h$]”h&]”Œcurrent_language”ŒEnglish”uh1h hhŒ _document”hŒsource”NŒline”NubhŒtarget”“”)�”}”(hŒ .. _usb-urb:”h]”h}”(h]”h ]”h"]”h$]”h&]”Œrefid”Œusb-urb”uh1hµh´Khhh²hh³Œ@/var/lib/git/docbuild/linux/Documentation/driver-api/usb/URB.rst”ubhŒsection”“”)�”}”(hhh]”(hŒtitle”“”)�”}”(hŒUSB Request Block (URB)”h]”hŒUSB Request Block (URB)”…”�”}”(hhËh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÉhhÆh²hh³hÃh´KubhŒ field_list”“”)�”}”(hhh]”(hŒfield”“”)�”}”(hhh]”(hŒ field_name”“”)�”}”(hŒRevised”h]”hŒRevised”…”�”}”(hhåh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hãhhàh³hÃh´KubhŒ field_body”“”)�”}”(hŒ 2000-Dec-05”h]”hŒ paragraph”“”)�”}”(hh÷h]”hŒ 2000-Dec-05”…”�”}”(hhûh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hùh³hÃh´Khhõubah}”(h]”h ]”h"]”h$]”h&]”uh1hóhhàubeh}”(h]”h ]”h"]”h$]”h&]”uh1hÞh³hÃh´KhhÛh²hubhß)�”}”(hhh]”(hä)�”}”(hŒAgain”h]”hŒAgain”…”�”}”(hjh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hãhjh³hÃh´Kubhô)�”}”(hŒ 2002-Jul-06”h]”hú)�”}”(hj'h]”hŒ 2002-Jul-06”…”�”}”(hj)h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hùh³hÃh´Khj%ubah}”(h]”h ]”h"]”h$]”h&]”uh1hóhjubeh}”(h]”h ]”h"]”h$]”h&]”uh1hÞh³hÃh´KhhÛh²hubhß)�”}”(hhh]”(hä)�”}”(hŒAgain”h]”hŒAgain”…”�”}”(hjEh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hãhjBh³hÃh´Kubhô)�”}”(hŒ 2005-Sep-19”h]”hú)�”}”(hjUh]”hŒ 2005-Sep-19”…”�”}”(hjWh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hùh³hÃh´KhjSubah}”(h]”h ]”h"]”h$]”h&]”uh1hóhjBubeh}”(h]”h ]”h"]”h$]”h&]”uh1hÞh³hÃh´KhhÛh²hubhß)�”}”(hhh]”(hä)�”}”(hŒAgain”h]”hŒAgain”…”�”}”(hjsh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hãhjph³hÃh´Kubhô)�”}”(hŒ 2017-Mar-29 ”h]”hú)�”}”(hŒ 2017-Mar-29”h]”hŒ 2017-Mar-29”…”�”}”(hj…h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hùh³hÃh´K hj�ubah}”(h]”h ]”h"]”h$]”h&]”uh1hóhjpubeh}”(h]”h ]”h"]”h$]”h&]”uh1hÞh³hÃh´K hhÛh²hubeh}”(h]”h ]”h"]”h$]”h&]”uh1hÙhhÆh²hh³hÃh´KubhŒnote”“”)�”}”(hXThe USB subsystem now has a substantial section at :ref:`usb-hostside-api` section, generated from the current source code. This particular documentation file isn't complete and may not be updated to the last version; don't rely on it except for a quick overview.”h]”hú)�”}”(hXThe USB subsystem now has a substantial section at :ref:`usb-hostside-api` section, generated from the current source code. This particular documentation file isn't complete and may not be updated to the last version; don't rely on it except for a quick overview.”h]”(hŒ3The USB subsystem now has a substantial section at ”…”�”}”(hj«h²hh³Nh´Nubh)�”}”(hŒ:ref:`usb-hostside-api`”h]”hŒinline”“”)�”}”(hjµh]”hŒusb-hostside-api”…”�”}”(hj¹h²hh³Nh´Nubah}”(h]”h ]”(Œxref”Œstd”Œstd-ref”eh"]”h$]”h&]”uh1j·hj³ubah}”(h]”h ]”h"]”h$]”h&]”Œrefdoc”Œdriver-api/usb/URB”Œ refdomain”jÄŒreftype”Œref”Œ refexplicit”‰Œrefwarn”ˆŒ reftarget”Œusb-hostside-api”uh1hh³hÃh´Khj«ubhŒÁ section, generated from the current source code. This particular documentation file isn’t complete and may not be updated to the last version; don’t rely on it except for a quick overview.”…”�”}”(hj«h²hh³Nh´Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1hùh³hÃh´Khj§ubah}”(h]”h ]”h"]”h$]”h&]”uh1j¥hhÆh²hh³hÃh´NubhÅ)�”}”(hhh]”(hÊ)�”}”(hŒ"Basic concept or 'What is an URB?'”h]”hŒ&Basic concept or ‘What is an URB?’”…”�”}”(hjëh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÉhjèh²hh³hÃh´Kubhú)�”}”(hŒvThe basic idea of the new driver is message passing, the message itself is called USB Request Block, or URB for short.”h]”hŒvThe basic idea of the new driver is message passing, the message itself is called USB Request Block, or URB for short.”…”�”}”(hjùh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hùh³hÃh´Khjèh²hubhŒ bullet_list”“”)�”}”(hhh]”(hŒ list_item”“”)�”}”(hŒqAn URB consists of all relevant information to execute any USB transaction and deliver the data and status back. ”h]”hú)�”}”(hŒpAn URB consists of all relevant information to execute any USB transaction and deliver the data and status back.”h]”hŒpAn URB consists of all relevant information to execute any USB transaction and deliver the data and status back.”…”�”}”(hjh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hùh³hÃh´Khjubah}”(h]”h ]”h"]”h$]”h&]”uh1j hj h²hh³hÃh´Nubj )�”}”(hŒ¯Execution of an URB is inherently an asynchronous operation, i.e. the :c:func:`usb_submit_urb` call returns immediately after it has successfully queued the requested action. ”h]”hú)�”}”(hŒ®Execution of an URB is inherently an asynchronous operation, i.e. the :c:func:`usb_submit_urb` call returns immediately after it has successfully queued the requested action.”h]”(hŒFExecution of an URB is inherently an asynchronous operation, i.e. the ”…”�”}”(hj*h²hh³Nh´Nubh)�”}”(hŒ:c:func:`usb_submit_urb`”h]”hŒliteral”“”)�”}”(hj4h]”hŒusb_submit_urb()”…”�”}”(hj8h²hh³Nh´Nubah}”(h]”h ]”(jÃŒc”Œc-func”eh"]”h$]”h&]”uh1j6hj2ubah}”(h]”h ]”h"]”h$]”h&]”Œrefdoc”jÐŒ refdomain”jBŒreftype”Œfunc”Œ refexplicit”‰Œrefwarn”‰jÖŒusb_submit_urb”uh1hh³hÃh´Khj*ubhŒP call returns immediately after it has successfully queued the requested action.”…”�”}”(hj*h²hh³Nh´Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1hùh³hÃh´Khj&ubah}”(h]”h ]”h"]”h$]”h&]”uh1j hj h²hh³hÃh´Nubj )�”}”(hŒQTransfers for one URB can be canceled with :c:func:`usb_unlink_urb` at any time. ”h]”hú)�”}”(hŒPTransfers for one URB can be canceled with :c:func:`usb_unlink_urb` at any time.”h]”(hŒ+Transfers for one URB can be canceled with ”…”�”}”(hjhh²hh³Nh´Nubh)�”}”(hŒ:c:func:`usb_unlink_urb`”h]”j7)�”}”(hjrh]”hŒusb_unlink_urb()”…”�”}”(hjth²hh³Nh´Nubah}”(h]”h ]”(jÃjBŒc-func”eh"]”h$]”h&]”uh1j6hjpubah}”(h]”h ]”h"]”h$]”h&]”Œrefdoc”jÐŒ refdomain”jBŒreftype”Œfunc”Œ refexplicit”‰Œrefwarn”‰jÖŒusb_unlink_urb”uh1hh³hÃh´K!hjhubhŒ at any time.”…”�”}”(hjhh²hh³Nh´Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1hùh³hÃh´K!hjdubah}”(h]”h ]”h"]”h$]”h&]”uh1j hj h²hh³hÃh´Nubj )�”}”(hŒÌEach URB has a completion handler, which is called after the action has been successfully completed or canceled. The URB also contains a context-pointer for passing information to the completion handler. ”h]”hú)�”}”(hŒËEach URB has a completion handler, which is called after the action has been successfully completed or canceled. The URB also contains a context-pointer for passing information to the completion handler.”h]”hŒËEach URB has a completion handler, which is called after the action has been successfully completed or canceled. The URB also contains a context-pointer for passing information to the completion handler.”…”�”}”(hj£h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hùh³hÃh´K$hjŸubah}”(h]”h ]”h"]”h$]”h&]”uh1j hj h²hh³hÃh´Nubj )�”}”(hXTEach endpoint for a device logically supports a queue of requests. You can fill that queue, so that the USB hardware can still transfer data to an endpoint while your driver handles completion of another. This maximizes use of USB bandwidth, and supports seamless streaming of data to (or from) devices when using periodic transfer modes. ”h]”hú)�”}”(hXREach endpoint for a device logically supports a queue of requests. You can fill that queue, so that the USB hardware can still transfer data to an endpoint while your driver handles completion of another. This maximizes use of USB bandwidth, and supports seamless streaming of data to (or from) devices when using periodic transfer modes.”h]”hXREach endpoint for a device logically supports a queue of requests. You can fill that queue, so that the USB hardware can still transfer data to an endpoint while your driver handles completion of another. This maximizes use of USB bandwidth, and supports seamless streaming of data to (or from) devices when using periodic transfer modes.”…”�”}”(hj»h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hùh³hÃh´K(hj·ubah}”(h]”h ]”h"]”h$]”h&]”uh1j hj h²hh³hÃh´Nubeh}”(h]”h ]”h"]”h$]”h&]”Œbullet”Œ-”uh1jh³hÃh´Khjèh²hubeh}”(h]”Œbasic-concept-or-what-is-an-urb”ah ]”h"]”Œ"basic concept or 'what is an urb?'”ah$]”h&]”uh1hÄhhÆh²hh³hÃh´KubhÅ)�”}”(hhh]”(hÊ)�”}”(hŒThe URB structure”h]”hŒThe URB structure”…”�”}”(hjâh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÉhjßh²hh³hÃh´K0ubhú)�”}”(hŒ&Some of the fields in struct urb are::”h]”hŒ%Some of the fields in struct urb are:”…”�”}”(hjðh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hùh³hÃh´K2hjßh²hubhŒ literal_block”“”)�”}”(hX½struct urb { // (IN) device and pipe specify the endpoint queue struct usb_device *dev; // pointer to associated USB device unsigned int pipe; // endpoint information unsigned int transfer_flags; // URB_ISO_ASAP, URB_SHORT_NOT_OK, etc. // (IN) all urbs need completion routines void *context; // context for completion routine usb_complete_t complete; // pointer to completion routine // (OUT) status after each completion int status; // returned status // (IN) buffer used for data transfers void *transfer_buffer; // associated data buffer u32 transfer_buffer_length; // data buffer length int number_of_packets; // size of iso_frame_desc // (OUT) sometimes only part of CTRL/BULK/INTR transfer_buffer is used u32 actual_length; // actual data buffer length // (IN) setup stage for CTRL (pass a struct usb_ctrlrequest) unsigned char *setup_packet; // setup packet (control only) // Only for PERIODIC transfers (ISO, INTERRUPT) // (IN/OUT) start_frame is set unless URB_ISO_ASAP isn't set int start_frame; // start frame int interval; // polling interval // ISO only: packets are only "best effort"; each can have errors int error_count; // number of errors struct usb_iso_packet_descriptor iso_frame_desc[0]; };”h]”hX½struct urb { // (IN) device and pipe specify the endpoint queue struct usb_device *dev; // pointer to associated USB device unsigned int pipe; // endpoint information unsigned int transfer_flags; // URB_ISO_ASAP, URB_SHORT_NOT_OK, etc. // (IN) all urbs need completion routines void *context; // context for completion routine usb_complete_t complete; // pointer to completion routine // (OUT) status after each completion int status; // returned status // (IN) buffer used for data transfers void *transfer_buffer; // associated data buffer u32 transfer_buffer_length; // data buffer length int number_of_packets; // size of iso_frame_desc // (OUT) sometimes only part of CTRL/BULK/INTR transfer_buffer is used u32 actual_length; // actual data buffer length // (IN) setup stage for CTRL (pass a struct usb_ctrlrequest) unsigned char *setup_packet; // setup packet (control only) // Only for PERIODIC transfers (ISO, INTERRUPT) // (IN/OUT) start_frame is set unless URB_ISO_ASAP isn't set int start_frame; // start frame int interval; // polling interval // ISO only: packets are only "best effort"; each can have errors int error_count; // number of errors struct usb_iso_packet_descriptor iso_frame_desc[0]; };”…”�”}”hjsbah}”(h]”h ]”h"]”h$]”h&]”Œ xml:space”Œpreserve”uh1jþh³hÃh´K4hjßh²hubhú)�”}”(hŒ�Your driver must create the "pipe" value using values from the appropriate endpoint descriptor in an interface that it's claimed.”h]”hŒ‡Your driver must create the “pipeâ€� value using values from the appropriate endpoint descriptor in an interface that it’s claimed.”…”�”}”(hjh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hùh³hÃh´KXhjßh²hubeh}”(h]”Œthe-urb-structure”ah ]”h"]”Œthe urb structure”ah$]”h&]”uh1hÄhhÆh²hh³hÃh´K0ubhÅ)�”}”(hhh]”(hÊ)�”}”(hŒHow to get an URB?”h]”hŒHow to get an URB?”…”�”}”(hj)h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÉhj&h²hh³hÃh´K]ubhú)�”}”(hŒ7URBs are allocated by calling :c:func:`usb_alloc_urb`::”h]”(hŒURBs are allocated by calling ”…”�”}”(hj7h²hh³Nh´Nubh)�”}”(hŒ:c:func:`usb_alloc_urb`”h]”j7)�”}”(hjAh]”hŒusb_alloc_urb()”…”�”}”(hjCh²hh³Nh´Nubah}”(h]”h ]”(jÃjBŒc-func”eh"]”h$]”h&]”uh1j6hj?ubah}”(h]”h ]”h"]”h$]”h&]”Œrefdoc”jÐŒ refdomain”jBŒreftype”Œfunc”Œ refexplicit”‰Œrefwarn”‰jÖŒ usb_alloc_urb”uh1hh³hÃh´K_hj7ubhŒ:”…”�”}”(hj7h²hh³Nh´Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1hùh³hÃh´K_hj&h²hubjÿ)�”}”(hŒ7struct urb *usb_alloc_urb(int isoframes, int mem_flags)”h]”hŒ7struct urb *usb_alloc_urb(int isoframes, int mem_flags)”…”�”}”hjhsbah}”(h]”h ]”h"]”h$]”h&]”jjuh1jþh³hÃh´Kahj&h²hubhú)�”}”(hX[Return value is a pointer to the allocated URB, 0 if allocation failed. The parameter isoframes specifies the number of isochronous transfer frames you want to schedule. For CTRL/BULK/INT, use 0. The mem_flags parameter holds standard memory allocation flags, letting you control (among other things) whether the underlying code may block or not.”h]”hX[Return value is a pointer to the allocated URB, 0 if allocation failed. The parameter isoframes specifies the number of isochronous transfer frames you want to schedule. For CTRL/BULK/INT, use 0. The mem_flags parameter holds standard memory allocation flags, letting you control (among other things) whether the underlying code may block or not.”…”�”}”(hjvh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hùh³hÃh´Kchj&h²hubhú)�”}”(hŒ,To free an URB, use :c:func:`usb_free_urb`::”h]”(hŒTo free an URB, use ”…”�”}”(hj„h²hh³Nh´Nubh)�”}”(hŒ:c:func:`usb_free_urb`”h]”j7)�”}”(hjŽh]”hŒusb_free_urb()”…”�”}”(hj�h²hh³Nh´Nubah}”(h]”h ]”(jÃjBŒc-func”eh"]”h$]”h&]”uh1j6hjŒubah}”(h]”h ]”h"]”h$]”h&]”Œrefdoc”jÐŒ refdomain”jBŒreftype”Œfunc”Œ refexplicit”‰Œrefwarn”‰jÖŒ usb_free_urb”uh1hh³hÃh´Kihj„ubhŒ:”…”�”}”(hj„h²hh³Nh´Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1hùh³hÃh´Kihj&h²hubjÿ)�”}”(hŒ"void usb_free_urb(struct urb *urb)”h]”hŒ"void usb_free_urb(struct urb *urb)”…”�”}”hjµsbah}”(h]”h ]”h"]”h$]”h&]”jjuh1jþh³hÃh´Kkhj&h²hubhú)�”}”(hŒ±You may free an urb that you've submitted, but which hasn't yet been returned to you in a completion callback. It will automatically be deallocated when it is no longer in use.”h]”hŒµYou may free an urb that you’ve submitted, but which hasn’t yet been returned to you in a completion callback. It will automatically be deallocated when it is no longer in use.”…”�”}”(hjÃh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hùh³hÃh´Kmhj&h²hubeh}”(h]”Œhow-to-get-an-urb”ah ]”h"]”Œhow to get an urb?”ah$]”h&]”uh1hÄhhÆh²hh³hÃh´K]ubhÅ)�”}”(hhh]”(hÊ)�”}”(hŒWhat has to be filled in?”h]”hŒWhat has to be filled in?”…”�”}”(hjÜh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÉhjÙh²hh³hÃh´Ksubhú)�”}”(hXÔDepending on the type of transaction, there are some inline functions defined in ``linux/usb.h`` to simplify the initialization, such as :c:func:`usb_fill_control_urb`, :c:func:`usb_fill_bulk_urb` and :c:func:`usb_fill_int_urb`. In general, they need the usb device pointer, the pipe (usual format from usb.h), the transfer buffer, the desired transfer length, the completion handler, and its context. Take a look at the some existing drivers to see how they're used.”h]”(hŒQDepending on the type of transaction, there are some inline functions defined in ”…”�”}”(hjêh²hh³Nh´Nubj7)�”}”(hŒ``linux/usb.h``”h]”hŒ linux/usb.h”…”�”}”(hjòh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j6hjêubhŒ) to simplify the initialization, such as ”…”�”}”(hjêh²hh³Nh´Nubh)�”}”(hŒ:c:func:`usb_fill_control_urb`”h]”j7)�”}”(hjh]”hŒusb_fill_control_urb()”…”�”}”(hjh²hh³Nh´Nubah}”(h]”h ]”(jÃjBŒc-func”eh"]”h$]”h&]”uh1j6hjubah}”(h]”h ]”h"]”h$]”h&]”Œrefdoc”jÐŒ refdomain”jBŒreftype”Œfunc”Œ refexplicit”‰Œrefwarn”‰jÖŒusb_fill_control_urb”uh1hh³hÃh´KuhjêubhŒ, ”…”�”}”(hjêh²hh³Nh´Nubh)�”}”(hŒ:c:func:`usb_fill_bulk_urb`”h]”j7)�”}”(hj)h]”hŒusb_fill_bulk_urb()”…”�”}”(hj+h²hh³Nh´Nubah}”(h]”h ]”(jÃjBŒc-func”eh"]”h$]”h&]”uh1j6hj'ubah}”(h]”h ]”h"]”h$]”h&]”Œrefdoc”jÐŒ refdomain”jBŒreftype”Œfunc”Œ refexplicit”‰Œrefwarn”‰jÖŒusb_fill_bulk_urb”uh1hh³hÃh´KuhjêubhŒ and ”…”�”}”(hjêh²hh³Nh´Nubh)�”}”(hŒ:c:func:`usb_fill_int_urb`”h]”j7)�”}”(hjLh]”hŒusb_fill_int_urb()”…”�”}”(hjNh²hh³Nh´Nubah}”(h]”h ]”(jÃjBŒc-func”eh"]”h$]”h&]”uh1j6hjJubah}”(h]”h ]”h"]”h$]”h&]”Œrefdoc”jÐŒ refdomain”jBŒreftype”Œfunc”Œ refexplicit”‰Œrefwarn”‰jÖŒusb_fill_int_urb”uh1hh³hÃh´KuhjêubhŒó. In general, they need the usb device pointer, the pipe (usual format from usb.h), the transfer buffer, the desired transfer length, the completion handler, and its context. Take a look at the some existing drivers to see how they’re used.”…”�”}”(hjêh²hh³Nh´Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1hùh³hÃh´KuhjÙh²hubhú)�”}”(hŒFlags:”h]”hŒFlags:”…”�”}”(hjsh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hùh³hÃh´K}hjÙh²hubj)�”}”(hhh]”(j )�”}”(hŒGFor ISO there are two startup behaviors: Specified start_frame or ASAP.”h]”hú)�”}”(hj†h]”hŒGFor ISO there are two startup behaviors: Specified start_frame or ASAP.”…”�”}”(hjˆh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hùh³hÃh´Khj„ubah}”(h]”h ]”h"]”h$]”h&]”uh1j hj�h²hh³hÃh´Nubj )�”}”(hŒ1For ASAP set ``URB_ISO_ASAP`` in transfer_flags. ”h]”hú)�”}”(hŒ0For ASAP set ``URB_ISO_ASAP`` in transfer_flags.”h]”(hŒ For ASAP set ”…”�”}”(hjŸh²hh³Nh´Nubj7)�”}”(hŒ``URB_ISO_ASAP``”h]”hŒ URB_ISO_ASAP”…”�”}”(hj§h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j6hjŸubhŒ in transfer_flags.”…”�”}”(hjŸh²hh³Nh´Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1hùh³hÃh´K€hj›ubah}”(h]”h ]”h"]”h$]”h&]”uh1j hj�h²hh³hÃh´Nubeh}”(h]”h ]”h"]”h$]”h&]”jÕjÖuh1jh³hÃh´KhjÙh²hubhú)�”}”(hŒUIf short packets should NOT be tolerated, set ``URB_SHORT_NOT_OK`` in transfer_flags.”h]”(hŒ.If short packets should NOT be tolerated, set ”…”�”}”(hjËh²hh³Nh´Nubj7)�”}”(hŒ``URB_SHORT_NOT_OK``”h]”hŒURB_SHORT_NOT_OK”…”�”}”(hjÓh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j6hjËubhŒ in transfer_flags.”…”�”}”(hjËh²hh³Nh´Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1hùh³hÃh´K‚hjÙh²hubeh}”(h]”Œwhat-has-to-be-filled-in”ah ]”h"]”Œwhat has to be filled in?”ah$]”h&]”uh1hÄhhÆh²hh³hÃh´KsubhÅ)�”}”(hhh]”(hÊ)�”}”(hŒHow to submit an URB?”h]”hŒHow to submit an URB?”…”�”}”(hjöh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÉhjóh²hh³hÃh´K‡ubhú)�”}”(hŒ$Just call :c:func:`usb_submit_urb`::”h]”(hŒ Just call ”…”�”}”(hjh²hh³Nh´Nubh)�”}”(hŒ:c:func:`usb_submit_urb`”h]”j7)�”}”(hjh]”hŒusb_submit_urb()”…”�”}”(hjh²hh³Nh´Nubah}”(h]”h ]”(jÃjBŒc-func”eh"]”h$]”h&]”uh1j6hj ubah}”(h]”h ]”h"]”h$]”h&]”Œrefdoc”jÐŒ refdomain”jBŒreftype”Œfunc”Œ refexplicit”‰Œrefwarn”‰jÖŒusb_submit_urb”uh1hh³hÃh´K‰hjubhŒ:”…”�”}”(hjh²hh³Nh´Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1hùh³hÃh´K‰hjóh²hubjÿ)�”}”(hŒ2int usb_submit_urb(struct urb *urb, int mem_flags)”h]”hŒ2int usb_submit_urb(struct urb *urb, int mem_flags)”…”�”}”hj5sbah}”(h]”h ]”h"]”h$]”h&]”jjuh1jþh³hÃh´K‹hjóh²hubhú)�”}”(hŒ‘The ``mem_flags`` parameter, such as ``GFP_ATOMIC``, controls memory allocation, such as whether the lower levels may block when memory is tight.”h]”(hŒThe ”…”�”}”(hjCh²hh³Nh´Nubj7)�”}”(hŒ ``mem_flags``”h]”hŒ mem_flags”…”�”}”(hjKh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j6hjCubhŒ parameter, such as ”…”�”}”(hjCh²hh³Nh´Nubj7)�”}”(hŒ``GFP_ATOMIC``”h]”hŒ GFP_ATOMIC”…”�”}”(hj]h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j6hjCubhŒ^, controls memory allocation, such as whether the lower levels may block when memory is tight.”…”�”}”(hjCh²hh³Nh´Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1hùh³hÃh´K�hjóh²hubhú)�”}”(hŒrIt immediately returns, either with status 0 (request queued) or some error code, usually caused by the following:”h]”hŒrIt immediately returns, either with status 0 (request queued) or some error code, usually caused by the following:”…”�”}”(hjuh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hùh³hÃh´K�hjóh²hubj)�”}”(hhh]”(j )�”}”(hŒOut of memory (``-ENOMEM``)”h]”hú)�”}”(hjˆh]”(hŒOut of memory (”…”�”}”(hjŠh²hh³Nh´Nubj7)�”}”(hŒ ``-ENOMEM``”h]”hŒ-ENOMEM”…”�”}”(hj‘h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j6hjŠubhŒ)”…”�”}”(hjŠh²hh³Nh´Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1hùh³hÃh´K“hj†ubah}”(h]”h ]”h"]”h$]”h&]”uh1j hjƒh²hh³hÃh´Nubj )�”}”(hŒUnplugged device (``-ENODEV``)”h]”hú)�”}”(hj±h]”(hŒUnplugged device (”…”�”}”(hj³h²hh³Nh´Nubj7)�”}”(hŒ ``-ENODEV``”h]”hŒ-ENODEV”…”�”}”(hjºh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j6hj³ubhŒ)”…”�”}”(hj³h²hh³Nh´Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1hùh³hÃh´K”hj¯ubah}”(h]”h ]”h"]”h$]”h&]”uh1j hjƒh²hh³hÃh´Nubj )�”}”(hŒStalled endpoint (``-EPIPE``)”h]”hú)�”}”(hjÚh]”(hŒStalled endpoint (”…”�”}”(hjÜh²hh³Nh´Nubj7)�”}”(hŒ ``-EPIPE``”h]”hŒ-EPIPE”…”�”}”(hjãh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j6hjÜubhŒ)”…”�”}”(hjÜh²hh³Nh´Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1hùh³hÃh´K•hjØubah}”(h]”h ]”h"]”h$]”h&]”uh1j hjƒh²hh³hÃh´Nubj )�”}”(hŒ+Too many queued ISO transfers (``-EAGAIN``)”h]”hú)�”}”(hjh]”(hŒToo many queued ISO transfers (”…”�”}”(hjh²hh³Nh´Nubj7)�”}”(hŒ ``-EAGAIN``”h]”hŒ-EAGAIN”…”�”}”(hj h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j6hjubhŒ)”…”�”}”(hjh²hh³Nh´Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1hùh³hÃh´K–hjubah}”(h]”h ]”h"]”h$]”h&]”uh1j hjƒh²hh³hÃh´Nubj )�”}”(hŒ*Too many requested ISO frames (``-EFBIG``)”h]”hú)�”}”(hj,h]”(hŒToo many requested ISO frames (”…”�”}”(hj.h²hh³Nh´Nubj7)�”}”(hŒ ``-EFBIG``”h]”hŒ-EFBIG”…”�”}”(hj5h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j6hj.ubhŒ)”…”�”}”(hj.h²hh³Nh´Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1hùh³hÃh´K—hj*ubah}”(h]”h ]”h"]”h$]”h&]”uh1j hjƒh²hh³hÃh´Nubj )�”}”(hŒ"Invalid INT interval (``-EINVAL``)”h]”hú)�”}”(hjUh]”(hŒInvalid INT interval (”…”�”}”(hjWh²hh³Nh´Nubj7)�”}”(hŒ ``-EINVAL``”h]”hŒ-EINVAL”…”�”}”(hj^h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j6hjWubhŒ)”…”�”}”(hjWh²hh³Nh´Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1hùh³hÃh´K˜hjSubah}”(h]”h ]”h"]”h$]”h&]”uh1j hjƒh²hh³hÃh´Nubj )�”}”(hŒ+More than one packet for INT (``-EINVAL``) ”h]”hú)�”}”(hŒ*More than one packet for INT (``-EINVAL``)”h]”(hŒMore than one packet for INT (”…”�”}”(hj€h²hh³Nh´Nubj7)�”}”(hŒ ``-EINVAL``”h]”hŒ-EINVAL”…”�”}”(hjˆh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j6hj€ubhŒ)”…”�”}”(hj€h²hh³Nh´Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1hùh³hÃh´K™hj|ubah}”(h]”h ]”h"]”h$]”h&]”uh1j hjƒh²hh³hÃh´Nubeh}”(h]”h ]”h"]”h$]”h&]”jÕjÖuh1jh³hÃh´K“hjóh²hubhú)�”}”(hŒ‡After submission, ``urb->status`` is ``-EINPROGRESS``; however, you should never look at that value except in your completion callback.”h]”(hŒAfter submission, ”…”�”}”(hj¬h²hh³Nh´Nubj7)�”}”(hŒ``urb->status``”h]”hŒ urb->status”…”�”}”(hj´h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j6hj¬ubhŒ is ”…”�”}”(hj¬h²hh³Nh´Nubj7)�”}”(hŒ``-EINPROGRESS``”h]”hŒ -EINPROGRESS”…”�”}”(hjÆh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j6hj¬ubhŒR; however, you should never look at that value except in your completion callback.”…”�”}”(hj¬h²hh³Nh´Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1hùh³hÃh´K›hjóh²hubhú)�”}”(hŒµFor isochronous endpoints, your completion handlers should (re)submit URBs to the same endpoint with the ``URB_ISO_ASAP`` flag, using multi-buffering, to get seamless ISO streaming.”h]”(hŒiFor isochronous endpoints, your completion handlers should (re)submit URBs to the same endpoint with the ”…”�”}”(hjÞh²hh³Nh´Nubj7)�”}”(hŒ``URB_ISO_ASAP``”h]”hŒ URB_ISO_ASAP”…”�”}”(hjæh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j6hjÞubhŒ< flag, using multi-buffering, to get seamless ISO streaming.”…”�”}”(hjÞh²hh³Nh´Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1hùh³hÃh´Kžhjóh²hubeh}”(h]”Œhow-to-submit-an-urb”ah ]”h"]”Œhow to submit an urb?”ah$]”h&]”uh1hÄhhÆh²hh³hÃh´K‡ubhÅ)�”}”(hhh]”(hÊ)�”}”(hŒ%How to cancel an already running URB?”h]”hŒ%How to cancel an already running URB?”…”�”}”(hj h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÉhjh²hh³hÃh´K¤ubhú)�”}”(hŒ¤There are two ways to cancel an URB you've submitted but which hasn't been returned to your driver yet. For an asynchronous cancel, call :c:func:`usb_unlink_urb`::”h]”(hŒŽThere are two ways to cancel an URB you’ve submitted but which hasn’t been returned to your driver yet. For an asynchronous cancel, call ”…”�”}”(hjh²hh³Nh´Nubh)�”}”(hŒ:c:func:`usb_unlink_urb`”h]”j7)�”}”(hj!h]”hŒusb_unlink_urb()”…”�”}”(hj#h²hh³Nh´Nubah}”(h]”h ]”(jÃjBŒc-func”eh"]”h$]”h&]”uh1j6hjubah}”(h]”h ]”h"]”h$]”h&]”Œrefdoc”jÐŒ refdomain”jBŒreftype”Œfunc”Œ refexplicit”‰Œrefwarn”‰jÖŒusb_unlink_urb”uh1hh³hÃh´K¦hjubhŒ:”…”�”}”(hjh²hh³Nh´Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1hùh³hÃh´K¦hjh²hubjÿ)�”}”(hŒ#int usb_unlink_urb(struct urb *urb)”h]”hŒ#int usb_unlink_urb(struct urb *urb)”…”�”}”hjHsbah}”(h]”h ]”h"]”h$]”h&]”jjuh1jþh³hÃh´Kªhjh²hubhú)�”}”(hXIt removes the urb from the internal list and frees all allocated HW descriptors. The status is changed to reflect unlinking. Note that the URB will not normally have finished when :c:func:`usb_unlink_urb` returns; you must still wait for the completion handler to be called.”h]”(hŒ¶It removes the urb from the internal list and frees all allocated HW descriptors. The status is changed to reflect unlinking. Note that the URB will not normally have finished when ”…”�”}”(hjVh²hh³Nh´Nubh)�”}”(hŒ:c:func:`usb_unlink_urb`”h]”j7)�”}”(hj`h]”hŒusb_unlink_urb()”…”�”}”(hjbh²hh³Nh´Nubah}”(h]”h ]”(jÃjBŒc-func”eh"]”h$]”h&]”uh1j6hj^ubah}”(h]”h ]”h"]”h$]”h&]”Œrefdoc”jÐŒ refdomain”jBŒreftype”Œfunc”Œ refexplicit”‰Œrefwarn”‰jÖŒusb_unlink_urb”uh1hh³hÃh´K¬hjVubhŒF returns; you must still wait for the completion handler to be called.”…”�”}”(hjVh²hh³Nh´Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1hùh³hÃh´K¬hjh²hubhú)�”}”(hŒ=To cancel an URB synchronously, call :c:func:`usb_kill_urb`::”h]”(hŒ%To cancel an URB synchronously, call ”…”�”}”(hj‡h²hh³Nh´Nubh)�”}”(hŒ:c:func:`usb_kill_urb`”h]”j7)�”}”(hj‘h]”hŒusb_kill_urb()”…”�”}”(hj“h²hh³Nh´Nubah}”(h]”h ]”(jÃjBŒc-func”eh"]”h$]”h&]”uh1j6hj�ubah}”(h]”h ]”h"]”h$]”h&]”Œrefdoc”jÐŒ refdomain”jBŒreftype”Œfunc”Œ refexplicit”‰Œrefwarn”‰jÖŒ usb_kill_urb”uh1hh³hÃh´K±hj‡ubhŒ:”…”�”}”(hj‡h²hh³Nh´Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1hùh³hÃh´K±hjh²hubjÿ)�”}”(hŒ"void usb_kill_urb(struct urb *urb)”h]”hŒ"void usb_kill_urb(struct urb *urb)”…”�”}”hj¸sbah}”(h]”h ]”h"]”h$]”h&]”jjuh1jþh³hÃh´K³hjh²hubhú)�”}”(hXŠIt does everything :c:func:`usb_unlink_urb` does, and in addition it waits until after the URB has been returned and the completion handler has finished. It also marks the URB as temporarily unusable, so that if the completion handler or anyone else tries to resubmit it they will get a ``-EPERM`` error. Thus you can be sure that when :c:func:`usb_kill_urb` returns, the URB is totally idle.”h]”(hŒIt does everything ”…”�”}”(hjÆh²hh³Nh´Nubh)�”}”(hŒ:c:func:`usb_unlink_urb`”h]”j7)�”}”(hjÐh]”hŒusb_unlink_urb()”…”�”}”(hjÒh²hh³Nh´Nubah}”(h]”h ]”(jÃjBŒc-func”eh"]”h$]”h&]”uh1j6hjÎubah}”(h]”h ]”h"]”h$]”h&]”Œrefdoc”jÐŒ refdomain”jBŒreftype”Œfunc”Œ refexplicit”‰Œrefwarn”‰jÖŒusb_unlink_urb”uh1hh³hÃh´KµhjÆubhŒõ does, and in addition it waits until after the URB has been returned and the completion handler has finished. It also marks the URB as temporarily unusable, so that if the completion handler or anyone else tries to resubmit it they will get a ”…”�”}”(hjÆh²hh³Nh´Nubj7)�”}”(hŒ ``-EPERM``”h]”hŒ-EPERM”…”�”}”(hjñh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j6hjÆubhŒ( error. Thus you can be sure that when ”…”�”}”(hjÆh²hh³Nh´Nubh)�”}”(hŒ:c:func:`usb_kill_urb`”h]”j7)�”}”(hjh]”hŒusb_kill_urb()”…”�”}”(hjh²hh³Nh´Nubah}”(h]”h ]”(jÃjBŒc-func”eh"]”h$]”h&]”uh1j6hjubah}”(h]”h ]”h"]”h$]”h&]”Œrefdoc”jÐŒ refdomain”jBŒreftype”Œfunc”Œ refexplicit”‰Œrefwarn”‰jÖŒ usb_kill_urb”uh1hh³hÃh´KµhjÆubhŒ" returns, the URB is totally idle.”…”�”}”(hjÆh²hh³Nh´Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1hùh³hÃh´Kµhjh²hubhú)�”}”(hX™There is a lifetime issue to consider. An URB may complete at any time, and the completion handler may free the URB. If this happens while :c:func:`usb_unlink_urb` or :c:func:`usb_kill_urb` is running, it will cause a memory-access violation. The driver is responsible for avoiding this, which often means some sort of lock will be needed to prevent the URB from being deallocated while it is still in use.”h]”(hŒ�There is a lifetime issue to consider. An URB may complete at any time, and the completion handler may free the URB. If this happens while ”…”�”}”(hj,h²hh³Nh´Nubh)�”}”(hŒ:c:func:`usb_unlink_urb`”h]”j7)�”}”(hj6h]”hŒusb_unlink_urb()”…”�”}”(hj8h²hh³Nh´Nubah}”(h]”h ]”(jÃjBŒc-func”eh"]”h$]”h&]”uh1j6hj4ubah}”(h]”h ]”h"]”h$]”h&]”Œrefdoc”jÐŒ refdomain”jBŒreftype”Œfunc”Œ refexplicit”‰Œrefwarn”‰jÖŒusb_unlink_urb”uh1hh³hÃh´K¼hj,ubhŒ or ”…”�”}”(hj,h²hh³Nh´Nubh)�”}”(hŒ:c:func:`usb_kill_urb`”h]”j7)�”}”(hjYh]”hŒusb_kill_urb()”…”�”}”(hj[h²hh³Nh´Nubah}”(h]”h ]”(jÃjBŒc-func”eh"]”h$]”h&]”uh1j6hjWubah}”(h]”h ]”h"]”h$]”h&]”Œrefdoc”jÐŒ refdomain”jBŒreftype”Œfunc”Œ refexplicit”‰Œrefwarn”‰jÖŒ usb_kill_urb”uh1hh³hÃh´K¼hj,ubhŒÚ is running, it will cause a memory-access violation. The driver is responsible for avoiding this, which often means some sort of lock will be needed to prevent the URB from being deallocated while it is still in use.”…”�”}”(hj,h²hh³Nh´Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1hùh³hÃh´K¼hjh²hubhú)�”}”(hX¹On the other hand, since usb_unlink_urb may end up calling the completion handler, the handler must not take any lock that is held when usb_unlink_urb is invoked. The general solution to this problem is to increment the URB's reference count while holding the lock, then drop the lock and call usb_unlink_urb or usb_kill_urb, and then decrement the URB's reference count. You increment the reference count by calling :c:func`usb_get_urb`::”h]”hX¼On the other hand, since usb_unlink_urb may end up calling the completion handler, the handler must not take any lock that is held when usb_unlink_urb is invoked. The general solution to this problem is to increment the URB’s reference count while holding the lock, then drop the lock and call usb_unlink_urb or usb_kill_urb, and then decrement the URB’s reference count. You increment the reference count by calling :c:func`usb_get_urb`:”…”�”}”(hj€h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hùh³hÃh´KÃhjh²hubjÿ)�”}”(hŒ(struct urb *usb_get_urb(struct urb *urb)”h]”hŒ(struct urb *usb_get_urb(struct urb *urb)”…”�”}”hjŽsbah}”(h]”h ]”h"]”h$]”h&]”jjuh1jþh³hÃh´KËhjh²hubhú)�”}”(hŒë(ignore the return value; it is the same as the argument) and decrement the reference count by calling :c:func:`usb_free_urb`. Of course, none of this is necessary if there's no danger of the URB being freed by the completion handler.”h]”(hŒg(ignore the return value; it is the same as the argument) and decrement the reference count by calling ”…”�”}”(hjœh²hh³Nh´Nubh)�”}”(hŒ:c:func:`usb_free_urb`”h]”j7)�”}”(hj¦h]”hŒusb_free_urb()”…”�”}”(hj¨h²hh³Nh´Nubah}”(h]”h ]”(jÃjBŒc-func”eh"]”h$]”h&]”uh1j6hj¤ubah}”(h]”h ]”h"]”h$]”h&]”Œrefdoc”jÐŒ refdomain”jBŒreftype”Œfunc”Œ refexplicit”‰Œrefwarn”‰jÖŒ usb_free_urb”uh1hh³hÃh´KÍhjœubhŒp. Of course, none of this is necessary if there’s no danger of the URB being freed by the completion handler.”…”�”}”(hjœh²hh³Nh´Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1hùh³hÃh´KÍhjh²hubeh}”(h]”Œ$how-to-cancel-an-already-running-urb”ah ]”h"]”Œ%how to cancel an already running urb?”ah$]”h&]”uh1hÄhhÆh²hh³hÃh´K¤ubhÅ)�”}”(hhh]”(hÊ)�”}”(hŒ"What about the completion handler?”h]”hŒ"What about the completion handler?”…”�”}”(hjØh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÉhjÕh²hh³hÃh´KÔubhú)�”}”(hŒ&The handler is of the following type::”h]”hŒ%The handler is of the following type:”…”�”}”(hjæh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hùh³hÃh´KÖhjÕh²hubjÿ)�”}”(hŒ,typedef void (*usb_complete_t)(struct urb *)”h]”hŒ,typedef void (*usb_complete_t)(struct urb *)”…”�”}”hjôsbah}”(h]”h ]”h"]”h$]”h&]”jjuh1jþh³hÃh´KØhjÕh²hubhú)�”}”(hŒýI.e., it gets the URB that caused the completion call. In the completion handler, you should have a look at ``urb->status`` to detect any USB errors. Since the context parameter is included in the URB, you can pass information to the completion handler.”h]”(hŒlI.e., it gets the URB that caused the completion call. In the completion handler, you should have a look at ”…”�”}”(hj h²hh³Nh´Nubj7)�”}”(hŒ``urb->status``”h]”hŒ urb->status”…”�”}”(hj h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j6hj ubhŒ‚ to detect any USB errors. Since the context parameter is included in the URB, you can pass information to the completion handler.”…”�”}”(hj h²hh³Nh´Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1hùh³hÃh´KÚhjÕh²hubhú)�”}”(hXNote that even when an error (or unlink) is reported, data may have been transferred. That's because USB transfers are packetized; it might take sixteen packets to transfer your 1KByte buffer, and ten of them might have transferred successfully before the completion was called.”h]”hXNote that even when an error (or unlink) is reported, data may have been transferred. That’s because USB transfers are packetized; it might take sixteen packets to transfer your 1KByte buffer, and ten of them might have transferred successfully before the completion was called.”…”�”}”(hj" h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hùh³hÃh´KßhjÕh²hubhŒwarning”“”)�”}”(hŒONEVER SLEEP IN A COMPLETION HANDLER. These are often called in atomic context.”h]”(hú)�”}”(hŒ$NEVER SLEEP IN A COMPLETION HANDLER.”h]”hŒ$NEVER SLEEP IN A COMPLETION HANDLER.”…”�”}”(hj6 h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hùh³hÃh´Kçhj2 ubhú)�”}”(hŒ)These are often called in atomic context.”h]”hŒ)These are often called in atomic context.”…”�”}”(hjD h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hùh³hÃh´Kéhj2 ubeh}”(h]”h ]”h"]”h$]”h&]”uh1j0 hjÕh²hh³hÃh´Nubhú)�”}”(hŒÆIn the current kernel, completion handlers run with local interrupts disabled, but in the future this will be changed, so don't assume that local IRQs are always disabled inside completion handlers.”h]”hŒÈIn the current kernel, completion handlers run with local interrupts disabled, but in the future this will be changed, so don’t assume that local IRQs are always disabled inside completion handlers.”…”�”}”(hjX h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hùh³hÃh´KëhjÕh²hubeh}”(h]”Œ!what-about-the-completion-handler”ah ]”h"]”Œ"what about the completion handler?”ah$]”h&]”uh1hÄhhÆh²hh³hÃh´KÔubhÅ)�”}”(hhh]”(hÊ)�”}”(hŒ&How to do isochronous (ISO) transfers?”h]”hŒ&How to do isochronous (ISO) transfers?”…”�”}”(hjq h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÉhjn h²hh³hÃh´Kðubhú)�”}”(hX~Besides the fields present on a bulk transfer, for ISO, you also have to set ``urb->interval`` to say how often to make transfers; it's often one per frame (which is once every microframe for highspeed devices). The actual interval used will be a power of two that's no bigger than what you specify. You can use the :c:func:`usb_fill_int_urb` macro to fill most ISO transfer fields.”h]”(hŒMBesides the fields present on a bulk transfer, for ISO, you also have to set ”…”�”}”(hj h²hh³Nh´Nubj7)�”}”(hŒ``urb->interval``”h]”hŒ urb->interval”…”�”}”(hj‡ h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j6hj ubhŒâ to say how often to make transfers; it’s often one per frame (which is once every microframe for highspeed devices). The actual interval used will be a power of two that’s no bigger than what you specify. You can use the ”…”�”}”(hj h²hh³Nh´Nubh)�”}”(hŒ:c:func:`usb_fill_int_urb`”h]”j7)�”}”(hj› h]”hŒusb_fill_int_urb()”…”�”}”(hj� h²hh³Nh´Nubah}”(h]”h ]”(jÃjBŒc-func”eh"]”h$]”h&]”uh1j6hj™ ubah}”(h]”h ]”h"]”h$]”h&]”Œrefdoc”jÐŒ refdomain”jBŒreftype”Œfunc”Œ refexplicit”‰Œrefwarn”‰jÖŒusb_fill_int_urb”uh1hh³hÃh´Kòhj ubhŒ( macro to fill most ISO transfer fields.”…”�”}”(hj h²hh³Nh´Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1hùh³hÃh´Kòhjn h²hubhú)�”}”(hŒºFor ISO transfers you also have to fill a :c:type:`usb_iso_packet_descriptor` structure, allocated at the end of the URB by :c:func:`usb_alloc_urb`, for each packet you want to schedule.”h]”(hŒ*For ISO transfers you also have to fill a ”…”�”}”(hj h²hh³Nh´Nubh)�”}”(hŒ#:c:type:`usb_iso_packet_descriptor`”h]”j7)�”}”(hjÌ h]”hŒusb_iso_packet_descriptor”…”�”}”(hjÎ h²hh³Nh´Nubah}”(h]”h ]”(jÃjBŒc-type”eh"]”h$]”h&]”uh1j6hjÊ ubah}”(h]”h ]”h"]”h$]”h&]”Œrefdoc”jÐŒ refdomain”jBŒreftype”Œtype”Œ refexplicit”‰Œrefwarn”‰jÖŒusb_iso_packet_descriptor”uh1hh³hÃh´Kùhj ubhŒ/ structure, allocated at the end of the URB by ”…”�”}”(hj h²hh³Nh´Nubh)�”}”(hŒ:c:func:`usb_alloc_urb`”h]”j7)�”}”(hjï h]”hŒusb_alloc_urb()”…”�”}”(hjñ h²hh³Nh´Nubah}”(h]”h ]”(jÃjBŒc-func”eh"]”h$]”h&]”uh1j6hjí ubah}”(h]”h ]”h"]”h$]”h&]”Œrefdoc”jÐŒ refdomain”jBŒreftype”Œfunc”Œ refexplicit”‰Œrefwarn”‰jÖŒ usb_alloc_urb”uh1hh³hÃh´Kùhj ubhŒ', for each packet you want to schedule.”…”�”}”(hj h²hh³Nh´Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1hùh³hÃh´Kùhjn h²hubhú)�”}”(hŒéThe :c:func:`usb_submit_urb` call modifies ``urb->interval`` to the implemented interval value that is less than or equal to the requested interval value. If ``URB_ISO_ASAP`` scheduling is used, ``urb->start_frame`` is also updated.”h]”(hŒThe ”…”�”}”(hj h²hh³Nh´Nubh)�”}”(hŒ:c:func:`usb_submit_urb`”h]”j7)�”}”(hj h]”hŒusb_submit_urb()”…”�”}”(hj" h²hh³Nh´Nubah}”(h]”h ]”(jÃjBŒc-func”eh"]”h$]”h&]”uh1j6hj ubah}”(h]”h ]”h"]”h$]”h&]”Œrefdoc”jÐŒ refdomain”jBŒreftype”Œfunc”Œ refexplicit”‰Œrefwarn”‰jÖŒusb_submit_urb”uh1hh³hÃh´Kýhj ubhŒ call modifies ”…”�”}”(hj h²hh³Nh´Nubj7)�”}”(hŒ``urb->interval``”h]”hŒ urb->interval”…”�”}”(hjA h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j6hj ubhŒc to the implemented interval value that is less than or equal to the requested interval value. If ”…”�”}”(hj h²hh³Nh´Nubj7)�”}”(hŒ``URB_ISO_ASAP``”h]”hŒ URB_ISO_ASAP”…”�”}”(hjS h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j6hj ubhŒ scheduling is used, ”…”�”}”(hj h²hh³Nh´Nubj7)�”}”(hŒ``urb->start_frame``”h]”hŒurb->start_frame”…”�”}”(hje h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j6hj ubhŒ is also updated.”…”�”}”(hj h²hh³Nh´Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1hùh³hÃh´Kýhjn h²hubhú)�”}”(hXßFor each entry you have to specify the data offset for this frame (base is transfer_buffer), and the length you want to write/expect to read. After completion, actual_length contains the actual transferred length and status contains the resulting status for the ISO transfer for this frame. It is allowed to specify a varying length from frame to frame (e.g. for audio synchronisation/adaptive transfer rates). You can also use the length 0 to omit one or more frames (striping).”h]”hXßFor each entry you have to specify the data offset for this frame (base is transfer_buffer), and the length you want to write/expect to read. After completion, actual_length contains the actual transferred length and status contains the resulting status for the ISO transfer for this frame. It is allowed to specify a varying length from frame to frame (e.g. for audio synchronisation/adaptive transfer rates). You can also use the length 0 to omit one or more frames (striping).”…”�”}”(hj} h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hùh³hÃh´Mhjn h²hubhú)�”}”(hXFor scheduling you can choose your own start frame or ``URB_ISO_ASAP``. As explained earlier, if you always keep at least one URB queued and your completion keeps (re)submitting a later URB, you'll get smooth ISO streaming (if usb bandwidth utilization allows).”h]”(hŒ6For scheduling you can choose your own start frame or ”…”�”}”(hj‹ h²hh³Nh´Nubj7)�”}”(hŒ``URB_ISO_ASAP``”h]”hŒ URB_ISO_ASAP”…”�”}”(hj“ h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j6hj‹ ubhŒÁ. As explained earlier, if you always keep at least one URB queued and your completion keeps (re)submitting a later URB, you’ll get smooth ISO streaming (if usb bandwidth utilization allows).”…”�”}”(hj‹ h²hh³Nh´Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1hùh³hÃh´M hjn h²hubhú)�”}”(hŒ½If you specify your own start frame, make sure it's several frames in advance of the current frame. You might want this model if you're synchronizing ISO data with some other event stream.”h]”hŒÁIf you specify your own start frame, make sure it’s several frames in advance of the current frame. You might want this model if you’re synchronizing ISO data with some other event stream.”…”�”}”(hj« h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hùh³hÃh´Mhjn h²hubeh}”(h]”Œ#how-to-do-isochronous-iso-transfers”ah ]”h"]”Œ&how to do isochronous (iso) transfers?”ah$]”h&]”uh1hÄhhÆh²hh³hÃh´KðubhÅ)�”}”(hhh]”(hÊ)�”}”(hŒ'How to start interrupt (INT) transfers?”h]”hŒ'How to start interrupt (INT) transfers?”…”�”}”(hjÄ h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÉhjÁ h²hh³hÃh´Mubhú)�”}”(hX'Interrupt transfers, like isochronous transfers, are periodic, and happen in intervals that are powers of two (1, 2, 4 etc) units. Units are frames for full and low speed devices, and microframes for high speed ones. You can use the :c:func:`usb_fill_int_urb` macro to fill INT transfer fields.”h]”(hŒêInterrupt transfers, like isochronous transfers, are periodic, and happen in intervals that are powers of two (1, 2, 4 etc) units. Units are frames for full and low speed devices, and microframes for high speed ones. You can use the ”…”�”}”(hjÒ h²hh³Nh´Nubh)�”}”(hŒ:c:func:`usb_fill_int_urb`”h]”j7)�”}”(hjÜ h]”hŒusb_fill_int_urb()”…”�”}”(hjÞ h²hh³Nh´Nubah}”(h]”h ]”(jÃjBŒc-func”eh"]”h$]”h&]”uh1j6hjÚ ubah}”(h]”h ]”h"]”h$]”h&]”Œrefdoc”jÐŒ refdomain”jBŒreftype”Œfunc”Œ refexplicit”‰Œrefwarn”‰jÖŒusb_fill_int_urb”uh1hh³hÃh´MhjÒ ubhŒ# macro to fill INT transfer fields.”…”�”}”(hjÒ h²hh³Nh´Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1hùh³hÃh´MhjÁ h²hubhú)�”}”(hŒšThe :c:func:`usb_submit_urb` call modifies ``urb->interval`` to the implemented interval value that is less than or equal to the requested interval value.”h]”(hŒThe ”…”�”}”(hj h²hh³Nh´Nubh)�”}”(hŒ:c:func:`usb_submit_urb`”h]”j7)�”}”(hj h]”hŒusb_submit_urb()”…”�”}”(hj h²hh³Nh´Nubah}”(h]”h ]”(jÃjBŒc-func”eh"]”h$]”h&]”uh1j6hj ubah}”(h]”h ]”h"]”h$]”h&]”Œrefdoc”jÐŒ refdomain”jBŒreftype”Œfunc”Œ refexplicit”‰Œrefwarn”‰jÖŒusb_submit_urb”uh1hh³hÃh´Mhj ubhŒ call modifies ”…”�”}”(hj h²hh³Nh´Nubj7)�”}”(hŒ``urb->interval``”h]”hŒ urb->interval”…”�”}”(hj. h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j6hj ubhŒ^ to the implemented interval value that is less than or equal to the requested interval value.”…”�”}”(hj h²hh³Nh´Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1hùh³hÃh´MhjÁ h²hubhú)�”}”(hX In Linux 2.6, unlike earlier versions, interrupt URBs are not automagically restarted when they complete. They end when the completion handler is called, just like other URBs. If you want an interrupt URB to be restarted, your completion handler must resubmit it. s”h]”hX In Linux 2.6, unlike earlier versions, interrupt URBs are not automagically restarted when they complete. They end when the completion handler is called, just like other URBs. If you want an interrupt URB to be restarted, your completion handler must resubmit it. s”…”�”}”(hjF h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hùh³hÃh´MhjÁ h²hubeh}”(h]”Œ$how-to-start-interrupt-int-transfers”ah ]”h"]”Œ'how to start interrupt (int) transfers?”ah$]”h&]”uh1hÄhhÆh²hh³hÃh´Mubeh}”(h]”(Œusb-request-block-urb”hÂeh ]”h"]”(Œusb request block (urb)”Œusb-urb”eh$]”h&]”uh1hÄhhh²hh³hÃh´KŒexpect_referenced_by_name”}”jb h·sŒexpect_referenced_by_id”}”hÂh·subeh}”(h]”h ]”h"]”h$]”h&]”Œsource”hÃuh1hŒcurrent_source”NŒ current_line”NŒsettings”Œdocutils.frontend”ŒValues”“”)�”}”(hÉNŒ generator”NŒ datestamp”NŒ source_link”NŒ source_url”NŒ toc_backlinks”Œentry”Œfootnote_backlinks”KŒ sectnum_xform”KŒstrip_comments”NŒstrip_elements_with_classes”NŒ strip_classes”NŒ report_level”KŒ halt_level”KŒexit_status_level”KŒdebug”NŒwarning_stream”NŒ traceback”ˆŒinput_encoding”Œ utf-8-sig”Œinput_encoding_error_handler”Œstrict”Œoutput_encoding”Œutf-8”Œoutput_encoding_error_handler”jŒ Œerror_encoding”Œutf-8”Œerror_encoding_error_handler”Œbackslashreplace”Œ language_code”Œen”Œrecord_dependencies”NŒconfig”NŒ id_prefix”hŒauto_id_prefix”Œid”Œ dump_settings”NŒdump_internals”NŒdump_transforms”NŒdump_pseudo_xml”NŒexpose_internals”NŒstrict_visitor”NŒ_disable_config”NŒ_source”hÃŒ _destination”NŒ _config_files”]”Œ7/var/lib/git/docbuild/linux/Documentation/docutils.conf”aŒfile_insertion_enabled”ˆŒ raw_enabled”KŒline_length_limit”M'Œpep_references”NŒ pep_base_url”Œhttps://peps.python.org/”Œpep_file_url_template”Œpep-%04d”Œrfc_references”NŒ rfc_base_url”Œ&https://datatracker.ietf.org/doc/html/”Œ tab_width”KŒtrim_footnote_reference_space”‰Œsyntax_highlight”Œlong”Œ smart_quotes”ˆŒsmartquotes_locales”]”Œcharacter_level_inline_markup”‰Œdoctitle_xform”‰Œ docinfo_xform”KŒsectsubtitle_xform”‰Œ image_loading”Œlink”Œembed_stylesheet”‰Œcloak_email_addresses”ˆŒsection_self_link”‰Œenv”NubŒreporter”NŒindirect_targets”]”Œsubstitution_defs”}”Œsubstitution_names”}”Œrefnames”}”Œrefids”}”hÂ]”h·asŒnameids”}”(jb hÂja j^ jÜjÙj#j jÖjÓjðjíjjjÒjÏjk jh j¾ j» jY jV uŒ nametypes”}”(jb ˆja ‰j܉j#‰jÖ‰jð‰j‰jÒ‰jk ‰j¾ ‰jY ‰uh}”(hÂhÆj^ hÆjÙjèj jßjÓj&jíjÙjjójÏjjh jÕj» jn jV jÁ uŒ footnote_refs”}”Œ citation_refs”}”Œ autofootnotes”]”Œautofootnote_refs”]”Œsymbol_footnotes”]”Œsymbol_footnote_refs”]”Œ footnotes”]”Œ citations”]”Œautofootnote_start”KŒsymbol_footnote_start”KŒ id_counter”Œ collections”ŒCounter”“”}”…”R”Œparse_messages”]”Œtransform_messages”]”hŒsystem_message”“”)�”}”(hhh]”hú)�”}”(hhh]”hŒ-Hyperlink target "usb-urb" is not referenced.”…”�”}”hjö sbah}”(h]”h ]”h"]”h$]”h&]”uh1hùhjó ubah}”(h]”h ]”h"]”h$]”h&]”Œlevel”KŒtype”ŒINFO”Œsource”hÃŒline”Kuh1jñ ubaŒ transformer”NŒ include_log”]”Œ decoration”Nh²hub.