EN JA
USBDI(9)
USBDI(9) FreeBSD Kernel Developer's Manual USBDI(9)

名称

usb_fifo_alloc_buffer, usb_fifo_attach, usb_fifo_detach, usb_fifo_free_buffer, usb_fifo_get_data, usb_fifo_get_data_buffer, usb_fifo_get_data_error, usb_fifo_get_data_linear, usb_fifo_put_bytes_max, usb_fifo_put_data, usb_fifo_put_data_buffer, usb_fifo_put_data_error, usb_fifo_put_data_linear, usb_fifo_reset, usb_fifo_softc, usb_fifo_wakeup, usbd_do_request, usbd_do_request_flags, usbd_errstr, usbd_lookup_id_by_info, usbd_lookup_id_by_uaa, usbd_transfer_clear_stall, usbd_transfer_drain, usbd_transfer_pending, usbd_transfer_poll, usbd_transfer_setup, usbd_transfer_start, usbd_transfer_stop, usbd_transfer_submit, usbd_transfer_unsetup, usbd_xfer_clr_flag, usbd_xfer_frame_data, usbd_xfer_frame_len, usbd_xfer_get_frame, usbd_xfer_get_priv, usbd_xfer_is_stalled, usbd_xfer_max_framelen, usbd_xfer_max_frames, usbd_xfer_max_len, usbd_xfer_set_flag, usbd_xfer_set_frame_data, usbd_xfer_set_frame_len, usbd_xfer_set_frame_offset, usbd_xfer_set_frames, usbd_xfer_set_interval, usbd_xfer_set_priv, usbd_xfer_set_stall, usbd_xfer_set_timeout, usbd_xfer_softc, usbd_xfer_state, usbd_xfer_statusユニバーサルシリアルバス (USB) ドライバプログラミングインタフェース

書式

#include < dev/usb/usb.h>
#include < dev/usb/usbdi.h>
#include < dev/usb/usbdi_util.h>

解説

ユニバーサルシリアルバス (USB) ドライバプログラミングインタフェースは、 USB 周辺機器で制御して通信するためのホストコントローラ独立の API がある USB 周辺機器ドライバを提供しています。 usb モジュールは、USB ホスト側のモードと USB デバイス側のモードの両方をサポートします。

USB カーネルプログラミング

ここに、一般的に使用される関数のリストがあります:

usb_error_t usbd_transfer_setup( udev, ifaces, pxfer, setup_start, n_setup, priv_sc, priv_mtx);

void usbd_transfer_unsetup( pxfer, n_setup);

void usbd_transfer_start( xfer);

void usbd_transfer_stop( xfer);

void usbd_transfer_drain( xfer);

USB 転送管理関数

USB 規格は、4 つのタイプの USB 転送を定義しています。制御転送、バルク (bulk) 転送、割り込み (interrupt) 転送、とアイソクロナス (isochronous) 転送です。すべての転送タイプは、次の 5 つの関数を使用して管理されます:

usbd_transfer_setup() この関数は、メモリを割り付け、USB 転送の配列とすべての要求された DMA メモリを初期化します。この関数は、リソースが利用可能となるまでスリープするか、ウェーティングをブロックすることができます。 udev は、"struct usb_device"へのポインタです。 ifaces は、使用するインタフェースインデックス番号の配列です。 "if_index"を参照してください。 pxfer は、 NULL に初期化される USB 転送のポインタの配列へのポインタであり、次に割り付けられた USB 転送へのポインタです。 setup_start は、USB 設定構造体の配列へのポインタです。 n_setup は、いくつの USB 転送がセットアップされるかを USB システムに伝える数です。 priv_sc は、"xfer->priv_sc"初期化するために使用される、プライベートな softc ポインタです。 priv_mtx は、転送構造体と softc を保護するプライベートなミューテックスです。このポインタは、 "xfer->priv_mtx"を初期化するために使用されます。この関数は、成功すれば、 0 を返します。 0 以外の返り値は、失敗を示します。

usbd_transfer_unsetup() この関数は、与えられた USB 転送と、これらの USB 転送に関連している、すべての割り付けられたリソースを解放します。 pxfer は、USB 転送ポインタの配列へのポインタで、NULL であるかもしれません、それは、USB システムによって解放されるべきです。 n_setup は、いくつの USB 転送がアンセットアップ (unsetup) されるべきであるかを USB システムに伝える数です。この関数は、USB 転送が完了するのをスリープして待つことができます。この関数は、USB 転送構造体のポインタに関して NULL セーフです。それは、USB 転送コールバックからこの関数を呼び出すことができません。

usbd_transfer_start() この関数は、まだ開始されていいなら、 xfer によって指された USB 転送を開始します。この関数は、常に非ブロッキングであり、いわゆるプライベートなロックされた USB ミューテックスで、呼び出されなければなりません。この関数は、USB 転送構造体のポインタに関して NULL セーフです。

usbd_transfer_stop() この関数は、まだ停止されていいなら、 xfer によって指された USB 転送を停止します。この関数は、常に非ブロッキングであり、いわゆるプライベートなロックされた USB ミューテックスで、呼び出されなければなりません。この関数は、USB コールバックが呼び出される前に、返ることができます。この関数は、USB 転送構造体のポインタに関して NULL セーフです。転送が進行していたなら、コールバックは、"USB_ST_ERROR"と "error = USB_ERR_CANCELLED"で呼び出されます。

usbd_transfer_drain() この関数は、まだ停止されれていないなら、USB 転送を停止して、終了する任意の追加の USB ハードウェア操作を待ちます。この関数が戻った後に、"usbd_xfer_set_frame_data()"を使用して DMA にロードされたバッファを安全にを解放することができます。この関数は、呼び出し側をブロックすることができ、USB コールバックが呼び出される前に返りません。この関数は、USB 転送構造体のポインタに関して NULL セーフです。

USB 転送コールバック

USB コールバックには、3 つの状態があります。 USB_ST_SETUP、USB_ST_TRANSFERRED と USB_ST_ERROR です。 USB_ST_SETUP は、初期状態です。コールバックがこの状態で呼び出された後に、他の 2 つの状態の 1 つの後の段階で常にコールバックされます。 USB コールバックは、エラーの原因が USB_ERR_CANCELLED であった場合に USB 転送を再開するべきではありません。 USB コールバックは、再帰から保護されます。それは、1 つの要求を別の転送のコールバックから転送するのは何でも開始して停止することができることを意味します。また、現在のコールバックされる転送もです。再帰は、繰り返し戻りたいコールバックであるなら、もう一度、呼び出されるように扱われます。

usbd_transfer_submit() この関数は、USB コールバックからのみ呼び出されるべきであり、 USB ハードウェアを開始するするために使用されます。 USB 転送には、すべての USB 転送タイプのために I/O ベクトルを構成する 1 つ以上の USB パケットから成る複数のフレームがあります。

void 
usb_default_callback(struct usb_xfer *xfer, usb_error_t error) 
{ 
 int actlen; 
 
 usbd_xfer_status(xfer, &actlen, NULL, NULL, NULL); 
 
 switch (USB_GET_STATE(xfer)) { 
 case USB_ST_SETUP: 
  /* 
   * xfer フレーム長/カウントとデータをセットアップ 
   */ 
  usbd_transfer_submit(xfer); 
  break; 
 
 case USB_ST_TRANSFERRED: 
  /* 
   * もしあれば, usb フレームデータを読み込む. 
   * "actlen"には, 転送されたすべてのフレームの 
   * 合計長があります. 
   */ 
  break; 
 
 default: /* Error */ 
  /* 
   * 例えば, エラーメッセージを印刷し, ストール 
   * (stall) をクリアする. 
   */ 
  break; 
 } 
 /* 
  * ここで, プライベートな USB ミューテックスロックなしで, 
  * 何かを行うことは安全です. 
  */ 
 return; 
}

USB 制御転送

USB 制御転送には、3 つの部分があります。最初に、SETUP パケット、次に (複数の) DATA パケット、とそして、STATUS パケットです。 SETUP パケットは、常にフレーム 0 によって指され、また任意の SETUP パケットを送信するべきでないなら、長さは、 usbd_xfer_frame_len() によって設定されます! USB 制御転送に DATA ステージがないなら、フレームの数は、1 に設定されるべきです。そうでなければ、フレームのデフォルト数は、2 です。

 
例1: SETUP + STATUS 
 usbd_xfer_set_frames(xfer, 1); 
 usbd_xfer_set_frame_len(xfer, 0, 8); 
 usbd_transfer_submit(xfer); 
 
例2: SETUP + DATA + STATUS 
 usbd_xfer_set_frames(xfer, 2); 
 usbd_xfer_set_frame_len(xfer, 0, 8); 
 usbd_xfer_set_frame_len(xfer, 1, 1); 
 usbd_transfer_submit(xfer); 
 
例3: SETUP + DATA + STATUS - split 
最初のコールバック: 
 usbd_xfer_set_frames(xfer, 1); 
 usbd_xfer_set_frame_len(xfer, 0, 8); 
 usbd_transfer_submit(xfer); 
 
2 番目のコールバック: 
 /* 重要: frbuffers[0] は, まだセットアップパケットを指して 
    いなければなりません! */ 
 usbd_xfer_set_frames(xfer, 2); 
 usbd_xfer_set_frame_len(xfer, 0, 0); 
 usbd_xfer_set_frame_len(xfer, 1, 1); 
 usbd_transfer_submit(xfer); 
 
例4: SETUP + STATUS - split 
最初のコールバック: 
 usbd_xfer_set_frames(xfer, 1); 
 usbd_xfer_set_frame_len(xfer, 0, 8); 
 usbd_xfer_set_flag(xfer, USB_MANUAL_STATUS); 
 usbd_transfer_submit(xfer); 
 
2 番目のコールバック: 
 usbd_xfer_set_frames(xfer, 1); 
 usbd_xfer_set_frame_len(xfer, 0, 0); 
 usbd_xfer_clr_flag(xfer, USB_MANUAL_STATUS); 
 usbd_transfer_submit(xfer); 

USB 転送設定

単に終点を検索するためには、 usb モジュールは、希望の終点の特性を指定することができる USB 設定構造体を定義します。

 
struct usb_config { 
 bufsize, 
 callback 
 direction, 
 endpoint, 
 frames, 
 index flags, 
 interval, 
 timeout, 
 type, 
}; 

type フィールドは、USB パイプタイプを選択します。有効な値は、次の通りです: UE_INTERRUPT, UE_CONTROL, UE_BULK, UE_ISOCHRONOUS です。特別な値 UE_BULK_INTR は、BULK と INTERRUPT パイプを選択します。このフィールドは、強制的です。

endpoint フィールドは、USB 終点番号を選択します。 0xFF、"-1"または "UE_ADDR_ANY"の値は、最初のマッチする終点を選択します。このフィールドは、強制的です。

direction フィールドは、USB 終点方向を選択します。 "UE_DIR_ANY"の値は、最初にマッチする終点を選択します。ほかの有効な値は、次の通りです: "UE_DIR_IN"と "UE_DIR_OUT"。方向が USB_MODE_DEVICE の場合にスワップされることを意味する "UE_DIR_SID"によって "UE_DIR_IN"と "UE_DIR_OUT"をバイナリ OR することができます。 "UE_DIR_IN"が、"IN"トークンのデータ転送方向を参照して、 "UE_DIR_OUT"が、"OUT"トークンのデータ転送方向を参照することに注意してください。このフィールドは、強制的です。

interval フィールドは、割り込み間隔を選択します。このフィールドの値は、ミリ秒単位で与えられ、デバイスの速度から独立しています。終点のタイプに従って、このフィールドには、異なった意味があります:

UE_INTERRUPT
"0"、終点の記述子に基づくデフォルト割り込み間隔を使用します。 "Else"、ポーリングのための与えられた値を使用します。
UE_ISOCHRONOUS
"0"、デフォルトを使用します。 "Else"は、値が無視されます。
UE_BULK
UE_CONTROL
"0"、転送プレ遅延なし、 "Else"、ミリ秒単位でこのフィールドによって与えられる遅延は、 "usbd_transfer_submit()"が呼び出されるとき、ハードウェアが開始される前に、挿入されます。

注: 転送タイムアウトは、もしあれば、プレ遅延が経過した後に開始されます!

timeout フィールドは、0 以外であるなら、ミリ秒単位で転送タイムアウトを設定します。 "timeout"フィールドが 0 でであり、転送タイプが ISOCHRONOUS であるなら、 250ms のタイムアウトが使用されます。

frames フィールドは、フレームの最大数を設定します。 0 が指定されるなら、次の結果をもたらします:

UE_BULK
xfer->nframes = 1;
UE_INTERRUPT
xfer->nframes = 1;
UE_CONTROL
xfer->nframes = 2;
UE_ISOCHRONOUS
許可されていません。エラーを引き起こすでしょう。

ep_index フィールドによって、利用者は、マッチしている "ep_index"が使用されるべきであるかを選択する、より多くの終点が記述にマッチする場合、番号を与えることができます。

if_index フィールドによって、利用者は、与えられた USB 転送をセットアップするとき、使用されるべきである "usbd_transfer_setup"へ渡される "ifaces"配列パラメータのインタフェース番号を選択できます。

flags フィールドには、タイプ "struct usb_xfer_flags"があり、 USB 転送の初期フラグを設定することができます。有効なフラグは、次の通りです:

force_short_xfer
このフラグは、最後に転送された USB パケットを強制的に短くします。短いパケットには、"wMaxPacketSize"に由来している "xfer->max_packet_size"未満の長さがあります。操作の間に、このフラグを変更することができます。
short_xfer_ok
このフラグは、転送の完了時に、受信された転送の長さ、 "xfer->actlen"を "xfer->sumlen"未満とできます。操作の間に、このフラグを変更することができます。
short_frames_ok
このフラグは、複数の短い USB フレームの受信を許可します。受信されたフレームの数が、1 以上であるなら、このフラグだけに、BULK と INTERRUPT 終点に対して効果があります。操作の間に、このフラグを変更することができます。
pipe_bof
このフラグによって、失敗した USB 転送は、"xfer->error"が "USB_ERR_CANCELLED"に等しい場合を除いて、PIPE キューの最初に残っています。影響された PIPE キューの他の USB 転送は、次のいずれかまで、開始されません:
1
失敗した USB 転送は、"usbd_transfer_stop()"を使用して停止されます。
2
失敗した USB 転送は、転送の実行に成功しました。
このフラグの目的は、複数の転送が USB 終点で実行のためにキューに入れられるとき、例えば、最初に実行された転送が、ストール (stall) のクリアのために必要とされるローディングに失敗するときに、競合を避けることです。この場合、このフラグは、クリアストール (clear-stall) コマンドが USB 制御終点で実行されると同時に、続く USB 転送が、実行されることを防ぐためにに使用されます。操作の間に、このフラグを変更することができます。

"BOF"は、"Block On Failure"を短くしたものです。

注: このフラグは、ユーザランドとカーネルの間で共有できる終点を使用する、すべての BULK と INTERRUPT USB 転送で設定されるべきです。

proxy_buffer
このフラグを設定することによって、合計バッファサイズは、最も近い不可分なハードウェア転送サイズまで丸められます。任意の USB 転送の最大のデータの長さは、常に "xfer->max_data_length"に格納されます。制御転送のために、 USB カーネルは、SETUP ヘッダの 8 バイトのための追加空間を割り付けます。これらの 8 バイトは、"xfer->max_data_length"変数によってカウントされません。操作の間に、このフラグを変更することができません。
ext_buffer
このフラグを設定することによって、データバッファは、割り付けられません。代わりに、USB クライアントは、データバッファを提供しなければなりません。操作の間に、このフラグを変更することができません。
manual_status
このフラグを設定することは、USB STATUS ステージを、 USB 制御転送の終わりに追加することを防ぎます。制御データが転送されないなら、このフラグは、クリアされなければなりません。そうでなければ、エラーは、USB コールバックに返されます。このフラグは、ほとんど USB デバイス側で役に立ちます。操作の間に、このフラグを変更することができます。
no_pipe_ok
このフラグを設定することによって、USB_ERR_NO_PIPE エラーは、無視されます。操作の間に、このフラグを変更することができません。
stall_pipe
Device Side Mode
このフラグを設定することによって、STALL pid は、転送が開始される前に、この転送に属する終点に送信されます。ホストが STALL した終点でクリアストール (clear-stall) コマンドを発行した瞬間に、転送は始められます。操作の間に、このフラグを変更することができます。
Host Side Mode
このフラグを設定することによって、クリアストール (clear-stall) 制御要求は、 USB 転送が開始される前に、終点で実行されます。

このフラグが、USB コールバック関数の外で変更されるなら、利用者は、"usbd_xfer_set_stall()"と "usbd_transfer_clear_stall()"関数を使用しなければなりません! このフラグは、ストール (stall)、または、クリアストール (clear-stall) が実行された後に、自動的にクリアされます。

pre_scale_frames
このフラグが設定されるなら、指定されたフレームの数は、フレームの代わりにミリ秒単位でバッファリング時間を与えると見なされます。転送の間に、フレームフィールドのセットアップは、終点のための対応する値で前もってスケーリングされ、 0 より大きいフレームの最も近い数に丸められます。このオプションだけが ISOCHRONOUS 転送に対して効果があります。

bufsize フィールドは、バイト単位の合計バッファサイズを設定します。このフィールドが 0 であるなら、"wMaxPacketSize"が使用され、転送タイプが ISOCHRONOUS であるなら、"frames"フィールドによって掛けられます。これは、割り込みパイプをセットアップするために役に立ちます。このフィールドは、強制的です。

注: 転送を制御するために、"bufsize"は、要求された構造体の長さを含んでいます。

callback ポインタは、USB コールバックを設定します。このフィールドは、強制的です。

USB LINUX 互換レイヤ (層)

usb モジュールは、Linux USB API をサポートしています。

関連項目

libusb(3), usb(4), usbconfig(8)

規格

usb モジュールは、USB 2.0 規格に準拠しています。

歴史

usb モジュールは、最初に Lennart Augustsson によって書かれた NetBSD USB スタックから発想を得ています。 usb モジュールは、 Hans Petter Selasky <hselasky@FreeBSD.org>によって書かれました。
June 24, 2009 FreeBSD