この章の目次にもどる
前頁:第14章 ネットワークデバイスにもどる
USBマネージャは、USBホストコントローラに対応したドライバであり、
USBデバイスを対象とするデバイスドライバに対し、
デバイスとの通信手段を提供するものである。
USBマネージャは以下に示す機能を持つ。
- デバイスの接続と解除の通知
- デバイスの接続もしくは解除を検出し、
対応するドライバに対してランデブ呼び出しにより通知する。
- デバイスに対する共通処理の実行
- デバイスの接続時には、対応するドライバからのアクセスを可能とするために
リセット処理、アドレスの設定、各種ディスクリプタの取得、
(必要がある場合のみ)コンフィギュレーションの設定を行う。
デバイスの解除時には、
デバイスへのアクセスを禁止するために必要な処理を行う。
- デバイスとドライバの対応付け
- デバイスが接続された場合、登録済みの複数のドライバに対して
接続されたデバイスが対象とするデバイスあるいはインターフェースかどうかを
問い合わせ、ドライバとの対応付けを行う。
- デバイスとの通信機能
- コントロール・バルク・インタラプト転送を行うための関数が用意されている。
- ドライバへの各種サービス機能の提供
-
- 各種ディスクリプタの取り出し
- デバイス接続情報の取得
- その他
USBデバイスを対象とするデバイスドライバは、
通常のドライバ機能に加えて以下の機能が必要となる。
- デバイスの接続・解除に伴う機能
- USBデバイスは任意の時点で接続・解除が行われる。
どのような場合でも、
これらに対する処理を確実に行うことができなければならない。
- 対象とするデバイスかどうかを判断する機能
- 接続されたデバイスあるいはインターフェースが自分が対象とするものかどうかを
デバイス・インターフェースディスクリプタ等を読み出して判断する機能。
- 対象とするデバイスの初期化機能
- デバイスそのものの初期化はUSBマネージャが行うが、
ドライバが必要とするUSBデバイスの機能を利用できるようにするための設定は
各ドライバで行う必要がある。
- デバイスとの通信機能
- デバイスおよびインターフェースのクラスに応じ、
ディスクリプタの内容に従ってUSBデバイスとの通信を行う。
USBマネージャの制限事項は以下の通りである。
- アイソクロナス転送はサポートしない。
- デバイスに複数のコンフィギュレーションが存在する場合、最初(=コンフィギュレーションインデックスが0)のコンフィギュレーションしか使用できない。
- 使用可能なデバイスの総数は31個、インターフェースおよびエンドポイントの数はそれぞれ64個である。ただし、USBホストコントローラも1個のデバイスとして扱う。
/* イベント種別(USBマネージャ) */
#define USB_MOUNT 1 /* デバイス接続 */
#define USB_UNMOUNT 2 /* デバイス切断 */
/* 応答コード(USBマネージャ) */
#define USB_NONE 0 /* 対象デバイスでない */
#define USB_OWN 1 /* 対象デバイス */
/* USBデバイスリクエスト(USB規格) */
typedef struct {
UB bmRequestType; /* 要求する対象の設定 */
UB bRequest; /* 要求コード */
UH wValue; /* 設定する値 */
UH wIndex; /* 文字列index等の指定 */
UH wLength; /* 転送長 */
} usbDeviceRequest;
/* bRequest:標準要求コード(USB規格) */
#define USB_GET_STATUS 0
#define USB_CLEAR_FEATURE 1
#define USB_SET_FEATURE 3
#define USB_SET_ADDRESS 5
#define USB_GET_DESCRIPTOR 6
#define USB_SET_DESCRIPTOR 7
#define USB_GET_CONFIGURATION 8
#define USB_SET_CONFIGURATION 9
#define USB_GET_INTERFACE 10
#define USB_SET_INTERFACE 11
#define USB_SYNCH_FRAME 12
/* bmRequestType(USB規格) */
#define bmR_DEVICE 0x00
#define bmR_INTERFACE 0x01
#define bmR_ENDPOINT 0x02
#define bmR_OTHER 0x03
#define bmR_STANDARD 0x00
#define bmR_CLASS 0x20
#define bmR_VENDOR 0x40
#define bmR_OUT 0x00
#define bmR_IN 0x80
/* bDescriptorType:ディスクリプタ種別(USB規格) */
#define USB_DEVICE 1
#define USB_CONFIGURATION 2
#define USB_STRING 3
#define USB_INTERFACE 4
#define USB_ENDPOINT 5
/* USB デバイスディスクリプタ(USB規格) */
typedef struct {
UB bLength; /* ディスクリプタ長 */
UB bDescriptorType; /* Device Descriptor(1) */
UH bcdUSB; /* USB規格のバージョン */
UB bDeviceClass; /* Device Class */
UB bDeviceSubClass; /* Device SubClass */
UB bDeviceProtocol; /* Device Protocol */
UB bMaxPacketSize0; /* pipe#0のPacketSize */
UH idVendor; /* 製造元ID(USB-IF) */
UH idProduct; /* 製品ID */
UH bcdDevice; /* 製品のバージョン */
UB iManufacturer; /* 文字列index (Mfg.) */
UB iProduct; /* 文字列index (Prod.) */
UB iSerialNumber; /* 文字列index (Ser#) */
UB bNumConfigurations; /* Configurationの数 */
} usbDeviceDescriptor;
/* USB コンフィギュレーションディスクリプタ(USB規格) */
typedef struct {
UB bLength; /* ディスクリプタ長 */
UB bDescriptorType; /* Cfg. Descriptor(2) */
UH wTotalLength; /* Cfg+other desc size */
UB bNumInterfaces; /* Interfaceの数 */
UB bConfigurationValue; /* このCfg.のID */
UB iConfiguration; /* 文字列index (Cfg.) */
UB bmAttributes; /* 電源などに関する属性 */
UB MaxPower; /* 消費電流(×2 mA) */
} usbConfigurationDescriptor;
/* USB インタフェースディスクリプタ(USB規格) */
typedef struct {
UB bLength; /* ディスクリプタ長 */
UB bDescriptorType; /* I/F Descriptor(4) */
UB bInterfaceNumber; /* このInterfaceのID */
UB bAlternateSetting; /* 代替設定のID */
UB bNumEndpoints; /* エンドポイントの数 */
UB bInterfaceClass; /* Interface Class */
UB bInterfaceSubClass; /* Interface SubClass */
UB bInterfaceProtocol; /* Interface Protocol */
UB iInterface; /* 文字列index (I/F) */
} usbInterfaceDescriptor;
/* USB エンドポイントディスクリプタ(USB規格) */
typedef struct {
UB bLength; /* ディスクリプタ長 */
UB bDescriptorType; /* E/P Descriptor(5) */
UB bEndpointAddress; /* endpoint address */
UB bmAttributes; /* 転送形式(Ctrl/Iso..) */
UH wMaxPacketSize; /* パケットサイズ */
UB bInterval; /* Iso/Int 転送周期(ms) */
} usbEndpointDescriptor;
/* エンドポイントディスクリプタのbmAttributesの定義(USB規格) */
#define USB_CONTROL 0
#define USB_ISOCHRONOUS 1
#define USB_BULK 2
#define USB_INTERRUPT 3
/* USB ストリングディスクリプタ(USB規格) */
typedef struct {
UB bLength; /* ディスクリプタ長 */
UB bDescriptorType; /* Str. Descriptor(3) */
UH bString[1]; /* 文字列 (Unicode) */
} usbStringDescriptor;
/* USBイベント指定用構造体(USBマネージャ) */
typedef struct {
UB bClass; /* Device/Interface Class */
UB bSubClass; /* Device/Interface SubClass */
UB bProtocol; /* Device/Interface Protocol */
UB mask; /* bClass/bSubClass/bProtocol/devidの選択 */
} usbEventPattern;
/* nowaitモード時の応答メッセージ(USBマネージャ) */
typedef struct {
W pid; /* pipe ID */
W datacnt; /* データ数 */
W error; /* エラーコード */
} usbMsg;
/* maskの値(USBマネージャ) */
#define EVENT_CLASS 0x01
#define EVENT_SUBCLASS 0x02
#define EVENT_PROTOCOL 0x04
#define EVENT_ANY 0x08
/* エラーコード (USBマネージャ) */
#define USB_OK (EC_OK << 16)
#define USB_ERR_BUSY ((EC_BUSY << 16) | 0)
#define USB_ERR_PAR ((EC_PAR << 16) | 0)
#define USB_ERR_DEVICE ((EC_PAR << 16) | 1)
#define USB_ERR_INTERFACE ((EC_PAR << 16) | 2)
#define USB_ERR_ENDPOINT ((EC_PAR << 16) | 3)
#define USB_ERR_POWER ((EC_LIMIT << 16) | 0)
#define USB_ERR_REQUEST ((EC_DEV << 16) | 0)
#define USB_ERR_SYSTEM ((EC_SYS << 16) | 0)
#define USB_ERR_NOMEM ((EC_NOMEM << 16) | 0)
#define USB_ERR_STALL ((EC_IO << 16) | 2)
#define USB_ERR_ABORT ((EC_IO << 16) | 3)
#define USB_ERR_IO_NAK ((EC_IO << 16) | 6)
#define USB_ERR_IO_SHORT ((EC_IO << 16) | 7)
#define USB_ERR_IO_BUFERR ((EC_IO << 16) | 9)
#define USB_ERR_IO_BABBLE ((EC_IO << 16) | 10)
#define USB_ERR_IO_CRC ((EC_IO << 16) | 11)
#define USB_ERR_IO_BITSTUFF ((EC_IO << 16) | 12)
#define USB_ERR_IO_NORESP ((EC_IO << 16) | 13)
/* usbIoPipe()での指定用(USBマネージャ) */
#define USB_WAIT 0x00
#define USB_SHORTNG 0x00
#define USB_NOWAIT 0x01
#define USB_SHORTOK 0x02
/* usbGetHubInfo()で使用する構造体(USBマネージャ) */
/* hub status構造体(USBマネージャ) */
typedef union {
struct {
UH level:3; /* hubの段数 */
UH self_power:1; /* self powered hubなら1 */
UH reserved:12;
} bmStatus;
UH status;
} usbHubStatus;
/* device status (USBマネージャ) */
#define PS_PORT_CONNECTION 0x0001
#define PS_PORT_ENABLE 0x0002
#define PS_PORT_SUSPEND 0x0004
#define PS_PORT_OVER_CURRENT 0x0008
#define PS_PORT_RESET 0x0010
#define PS_PORT_POWER 0x0100
#define PS_PORT_LOW_SPEED 0x0200
登録したデバイスドライバに対しては、
デバイスドライバへの要求受け付けランデブポートに対して
USBイベントの呼び出しが行われる。
このイベントは、デバイス単位あるいはインターフェース単位で得ることができる。
デバイスドライバは、
どのような時点でもUSBイベント呼び出しを速やかに受け付け、
対応した処理を行った後応答を戻さなくてはならない。
USBイベント呼び出しは、呼び出しが行われてから
30秒以内に受け付けられなければならない。受け付けられなかった場合は、
そのデバイスドライバはデバイスを使用しないものとみなす。
USBイベント呼び出し・応答は、
通常のデバイス要求・応答のデータ形式を使用して以下の内容で行われる。
- 呼び出し(デバイス接続時の要求):
-
DevReq: devid (bit 6〜 0) 接続されたデバイスのアドレス
(bit 7) 0
cmd.cmd = DC_USBEVENT
datano = USB_MOUNT
datacnt (bit 7〜 0) bDeviceClassの値
(bit 8〜15) bDeviceSubClassの値
(bit16〜23) bDeviceProtocolの値
taskid 予約(0)
memptr 予約(0)
- 応答(デバイス接続時の要求)
-
DevRsp: devid (bit 6〜 0) 接続されたデバイスのアドレス
(bit 7) 0
cmd.cmd = DC_USBEVENT
datano 予約
datacnt 予約
error 応答コード(USB_OWN/USB_NONE)
- 呼び出し(デバイス解除時の要求):
-
DevReq: devid (bit 6〜 0) 接続されたデバイスのアドレス
(bit 7) 0
cmd.cmd = DC_USBEVENT
datano = USB_UNMOUNT
datacnt 予約(0)
taskid 予約(0)
memptr 予約(0)
- 応答(デバイス解除時の要求)
-
DevRspに設定すべき値は無い。rpl_rdv()で応答するだけで良い。
- 呼び出し(インターフェース接続時の要求)
-
DevReq: devid (bit 6〜 0) 接続されたデバイスのアドレス
(bit 7) 1
(bit 8〜15) インターフェースディスクリプタのbInterfaceNumber
cmd.cmd = DC_USBEVENT
datano = USB_MOUNT
datacnt (bit 7〜 0) bInterfaceClassの値
(bit 8〜15) bInterfaceSubClassの値
(bit16〜23) bInterfaceProtocolの値
taskid 予約(0)
memptr 予約(0)
- 応答(インターフェース接続時の要求)
-
DevRsp: devid (bit 6〜 0) 接続されたデバイスのアドレス
(bit 7) 1
(bit 8〜15) インターフェースディスクリプタのbInterfaceNumber
cmd.cmd = DC_USBEVENT
datano 予約
datacnt 予約
error 応答コード(USB_OWN/USB_NONE)
- 呼び出し(インターフェース解除時の要求):
-
DevReq: devid (bit 6〜 0) 接続されたデバイスのアドレス
(bit 7) 1
(bit 8〜15) インターフェースディスクリプタのbInterfaceNumber
cmd.cmd = DC_USBEVENT
datano = USB_UNMOUNT
datacnt 予約(0)
taskid 予約(0)
memptr 予約(0)
- 応答(インターフェース解除時の要求)
-
DevRspに設定すべき値は無い。rpl_rdv()で応答するだけで良い。
USB_MOUNT
イベント(デバイス・インターフェース接続)
USBデバイスが接続された時点で登録されているデバイスドライバのうち、
以下の条件を満たすドライバに対して順番に発行される。
ドライバからの応答コードとしてUSB_OWN
が得られた場合、
そのドライバがデバイスに対応付けられて、イベントの発行が終了する。
- まだデバイスあるいはインターフェースとの対応付けがされていない。
- デバイスあるいはインターフェースクラスが
ドライバ登録時に宣言したクラスと一致している。
デバイスに対応付けられるドライバが存在しない場合、
USBマネージャはコンフィギュレーションインデックスが0の内容で
デバイスのコンフィギュレーションを行う。
そしてデバイスに対応付けられるドライバの検索を行うのと同様に
インターフェースに対応するドライバの検索を行う。
デバイス・インターフェース接続イベントを発行する順番は
ドライバを登録した順番と逆順に発行される。
つまり、一番最近に登録されたドライバが最初にイベントを受け取ることになる。
デバイスドライバの登録時点で既にデバイスが接続されており、
そのデバイスがまだドライバに対応付けられていない場合も
USB_MOUNT
イベントが発生する。
USB_MOUNT
イベントを受け取ったドライバは、
そのデバイスあるいはインターフェースが自分が対象としているものかどうかを
イベント呼び出しで得られるデバイス・インターフェースクラスや
usbDescriptorDevice()
等で得られるディスクリプタを使用して
チェックする。
チェックの結果、対象とするデバイスでない場合は
USB_NONE
の応答コードを戻し、これ以降は
そのデバイスに対するアクセスを行わないこと。
チェックの結果、対象とするデバイスである場合はUSB_OWN
の
応答コードを戻す。
応答コードを戻すまでの間に、デバイスのコンフィギュレーション
(これはデバイスに対応付けられるドライバの場合のみ必要となる)や、
ディスクリプタの解釈を行い、デバイスとの通信準備を行っても良い。
USB_UNMOUNT
イベント(デバイス・インターフェース解除)
USBデバイスが解除された時点で、そのデバイスおよびインターフェースに
対応付けられたドライバに対してUSB_UNMOUNT
イベントが発行される。
USB_UNMOUNT
イベントを受けたドライバは
対象とするデバイスあるいはインターフェースが解除されたことに対応する
処理を行い、応答を戻す。
このイベントに対する応答コードは意味を持たない。
デバイスが解除されるとデバイスとドライバとの対応付けは解除され、
ドライバのデバイスに対する操作が禁止される。
サスペンド・レジューム処理
サスペンドに移行する際は、USBマネージャはデバイスの接続を解除する。
よってこの時は、USBデバイスを使用しているデバイスドライバに対して
デバイス・インターフェース解除イベントが発生し、
サスペンド中はデバイスが存在しない状態となる。
逆にレジュームが行われる際は、USBマネージャはデバイスの接続を行う。
よって、USBデバイスを使用しているデバイスドライバに対しては
デバイス・インターフェース接続イベントが発生する。
USBマネージャは、デバイスドライバに対して
以下のサービスを拡張システムコールとして提供する。
エラーコードの説明の中にあるUSB_ERR_IO_*
は、
USBデバイスとの通信中に発生するエラーである。
このエラーに関する説明は次項で行っている。
usbRequestDevice |
|
デバイスリクエストを発行 |
|
【形式】
ERR usbRequestDevice(W did, UB *request, UB *data, W len, W *rlen)
【パラメータ】
did | デバイスのアドレス |
request | デバイスに対して送信するデバイスリクエストのポインタ |
data | 送受信するデータを格納するメモリ領域の先頭ポインタ |
len | 送受信するデータの大きさ |
rlen | 実際に送受信を行ったデータの大きさを格納する領域のポインタ |
【リターン値】
= 0 (USB_OK) | デバイスリクエストの発行に成功した |
< 0 | エラー(エラーコード) |
【解説】
デバイスに対して、各種デバイスリクエストを発行する。
ただし、デバイスに対してデータを送信するような標準デバイスリクエスト
(bmRequestTypeのbit5, 6, 7が全て0であるもの)は発行できない。
この関数は、デバイスのオープン・クローズに関係なく使用可能である。
同一デバイスに対するリクエストを複数のタスクから発行することが
できるが、デバイスに対して送られるリクエストの順番は先着順である。
なお、複数のインターフェースを持つようなデバイスの場合、
複数のドライバが同一デバイスに対してリクエストを行うことがあるので
リクエストの内容や順番に注意する必要がある。
ショートパケット(要求したデータ長より短いデータを受信した場合)
による中断はエラーとならない。
よって、実際に転送を行ったデータ長を確認するのが望ましい。
デバイスリクエストの発行中は待ち状態となる。
dataにはNULLを指定することができるが,その際のlenは0を指定すること。
dataにNULLを指定した状態でlenが0以外の場合の動作は保証しない。
lenに指定できる値は,4088(4096 - デバイスリクエストの大きさ(8))
バイトが上限となる。
なお、マネージャ内部でlenで指定した値をwLengthとして設定するため、
デバイスリクエストのwLengthを指定する必要は無い。
【エラーコード】
USB_ERR_DEVICE | didが不正(デバイスが存在しない) |
USB_ERR_STALL | STALLが発生した |
USB_ERR_ABORT | 通信がキャンセルされた |
USB_ERR_IO_* | 入出力エラーが発生した |
USB_ERR_REQUEST | 発行できないデバイスリクエストを発行しようとした |
USB_ERR_PAR | requestがNULLである |
usbDescriptorDevice |
usbDescriptorInterface |
usbDescriptorEndpoint |
|
デバイス/インターフェース/エンドポイントディスクリプタの取得 |
|
【形式】
ERR usbDescriptorDevice(W did, UB *data, W len, W *rlen)
ERR usbDescriptorInterface(W iid, UB *data, W len, W *rlen)
ERR usbDescriptorEndpoint(W pid, UB *data, W len, W *rlen)
【パラメータ】
did | デバイスのアドレス(usbDescriptorDevice()) |
iid | インターフェースID(usbDescriptorInterface()) |
pid | パイプID(usbDescriptorPipe()) |
data | 取得するデータを格納するメモリ領域の先頭ポインタ |
len | 取得するデータの大きさ |
rlen | ディスクリプタの大きさを格納する領域のポインタ |
【リターン値】
= 0 (USB_OK) | ディスクリプタの取得に成功した |
< 0 | エラー(エラーコード) |
【解説】
(usbDescriptorDevice())
didで指定したデバイスに含まれる、デバイスディスクリプタと
コンフィギュレーションディスクリプタ
(これにはインターフェースディスクリプタや
エンドポイントディスクリプタ、各種クラスディスクリプタが含まれる)
およびデバイスディスクリプタのiProductで示される
ストリングディスクリプタを取得する。
(usbDescriptorInterface(), usbDescriptorEndpoint())
iidもしくはpidで指定したインターフェースもしくは
エンドポイント(パイプ)のディスクリプタを取得する。
クラスディスクリプタが後に続いている場合は、それも一緒に取得できる。
この関数は、オープン・クローズに関係なく使用することができる。
usbRequestDevice()でインターフェース番号やエンドポイントアドレスが
必要になった場合、この関数で取得したディスクリプタの情報を
使用すれば良い。
この関数はデバイスに対する通信を行わず、USBマネージャ側が
デバイス接続時に取得した情報をコピーするだけである。
使用する際は、data=NULL, len=0として呼び出し、rlenに得られた
ディスクリプタサイズを使って十分な量のメモリを確保してから
再度呼び出すことになるだろう。
USB規格に定められた各種ディスクリプタを、
include/driver/usb.h中に定義している。
詳細については、USB 1.1の規格書を参照すること。
【エラーコード】
USB_ERR_DEVICE | didが不正(didで指定したデバイスは存在しない) |
USB_ERR_INTERFACE | iidが不正(iidで指定したインターフェースは存在しない) |
USB_ERR_ENDPOINT | pidが不正(pidで指定したエンドポイントは存在しない) |
usbConfigDevice |
|
デバイスのコンフィギュレーションの設定・取得 |
|
【形式】
WERR usbConfigDevice(W did, W cfg)
【パラメータ】
did | | デバイスのアドレス |
cfg | 0〜255 | コンフィギュレーションの選択(標準デバイスリクエストのSET_CONFIGURATIONを発行する) |
| -1 | 現在設定されているコンフィギュレーションの取得(標準デバイスリクエストのGET_CONFIGURATIONを発行する) |
【リターン値】
0〜255 | コンフィギュレーションの設定に成功した(cfgが0〜255の場合) |
| 現在設定されているコンフィギュレーション(cfgが-1の場合) |
< 0 | エラー(エラーコード) |
【解説】
デバイスに対するコンフィギュレーションを行い、
使用するインターフェースを決定する。
また、現在設定されているコンフィギュレーションを
デバイスから取り出すこともできる。
デバイスに属している全てのインターフェースが
クローズの状態でないと実行できない。
cfg=0の場合、デバイスはコンフィギュレーションされていない状態になる。
usbOpenDeivce()
でオープンしたばかりのデバイスは
アドレスが割り振られただけの状態なので、
必ずこの関数でコンフィギュレーションを選択し、
使用するインターフェースを決定する必要がある。
使用するインターフェースが決定しても、
usbRegistInterface()
で登録を行ったドライバに対して
イベントが起こることはない。
【エラーコード】
USB_ERR_DEVICE | didが不正(デバイスが存在しない) |
USB_ERR_STALL | STALLが発生した |
USB_ERR_ABORT | 通信がキャンセルされた |
USB_ERR_IO_* | 入出力エラーが発生した |
USB_ERR_BUSY | クローズしていないインターフェースが存在している |
USB_ERR_INTERFACE | 指定したコンフィギュレーションは存在しない |
USB_ERR_POWER | ハブの電流容量不足のため、コンフィギュレーションが設定できない |
USB_ERR_PAR | cfgの値が-1〜255以外である |
usbConfigInterface |
|
インターフェースの代替設定(alternate setting)の設定・取得 |
|
【形式】
WERR usbConfigInterface(W iid, W alt)
【パラメータ】
iid | | インターフェースID |
alt | 0〜255 | インターフェースの代替設定を選択する(SET_INTERFACEを発行する) |
| -1 | 現在選択されている代替設定を取得する(GET_INTERFACEを発行する) |
【リターン値】
0〜255 | 代替設定を行った(altが0〜255の場合) |
| 現在設定されている代替設定(altが-1の場合) |
< 0 | エラー(エラーコード) |
【解説】
デバイスのインターフェースに対し、
代替設定(alternate setting)を設定する。
また、インターフェースがどの設定を現在使用しているかという情報を
取り出すこともできる。
全てのパイプがクローズの状態でないと実行できない。
オープンしたばかりのデバイスは代替設定に0が指定された状態になっている。
主にプリンタデバイスのような、複数の代替設定を持つデバイスで使用する。
【エラーコード】
USB_ERR_DEVICE | デバイスへの操作が禁止されている(デバイスがクローズされている) |
USB_ERR_INTERFACE | iidが不正(インターフェースが存在しない) |
USB_ERR_STALL | STALLが発生した |
USB_ERR_ABORT | 通信がキャンセルされた |
USB_ERR_IO_* | 入出力エラーが発生した |
USB_ERR_BUSY | クローズしていないパイプが存在している |
USB_ERR_ENDPOINT | 指定した代替設定は存在しない |
USB_ERR_PAR | altの値が-1〜255以外である |
usbStallPipe |
|
エンドポイントのストールの設定・解除 |
|
【形式】
WERR usbStallPipe(W pid, W stl)
【パラメータ】
pid | | パイプID(usbOpenPipe()で得る) |
stl | 1 | SET_FEATURE(ENDPOINT_STALL)を発行する |
| 0 | CLEAR_FEATURE(ENDPOINT_STALL)を発行する |
| -1 | GET_STATUS(ENDPOINT)を発行する |
| 2 | SET_FEATURE(ENDPOINT_STALL)を発行した後、CLEAR_FEATURE(ENDPOINT_STALL)を発行する |
【リターン値】
> 0 | エンドポイントの設定に成功した(stlが0, 1, 2の場合) |
| エンドポイントのステータス(stlが-1の場合) |
< 0 | エラー(エラーコード) |
【解説】
エンドポイントに対し、STALLの状態を設定・取得する。
USBではデータ転送を行う際、データの順番をトグルビット(toggle bit)
という0と1の値を使用して決めている。
この値がデバイス側とホスト側で異なっている場合、
データの転送は正常に行われない。
このビットを初期化する目的でCLEAR_FEATURE(ENDPOINT_STALL)を
発行することがある。
【エラーコード】
USB_ERR_DEVICE | デバイスへの操作が禁止されている |
USB_ERR_INTERFACE | インターフェースへの操作が禁止されている |
USB_ERR_ENDPOINT | pidが不正(パイプが存在しない) |
USB_ERR_STALL | STALLが発生した |
USB_ERR_ABORT | 通信がキャンセルされた |
USB_ERR_IO_* | 入出力エラーが発生した |
USB_ERR_PAR | stlが -1, 0, 1, 2 以外である |
【形式】
WERR usbSyncPipe(W pid)
【パラメータ】
pid | パイプID(usbOpenPipe()で得る) |
【リターン値】
>= 0 | デバイスが返してくるフレーム番号 |
< 0 | エラー(エラーコード) |
【解説】
エンドポイントに対し、USB標準デバイスリクエストのSYNCH_FRAMEを
発行する。主にアイソクロナス転送を使用するパイプで使用する。
【エラーコード】
USB_ERR_DEVICE | デバイスへの操作が禁止されている |
USB_ERR_INTERFACE | インターフェースへの操作が禁止されている |
USB_ERR_ENDPOINT | pidが不正(パイプが存在しない) |
USB_ERR_STALL | STALLが発生した |
USB_ERR_ABORT | 通信がキャンセルされた |
USB_ERR_IO_* | 入出力エラーが発生した |
【形式】
ERR usbOpenDevice(W did)
【パラメータ】
did | デバイスのアドレス(デバイス接続時のイベントで取得できる) |
【リターン値】
> 0 | デバイスのアドレス |
< 0 | エラー(エラーコード) |
【解説】
デバイスに対する操作の開始を宣言する。
デバイスの多重オープンはできない。
【エラーコード】
USB_ERR_DEVICE | didが不正(デバイスが存在しない) |
USB_ERR_BUSY | デバイスは既にオープンされている |
【形式】
ERR usbCloseDevice(W did)
【パラメータ】
【リターン値】
= 0 (USB_OK) | デバイスをクローズした |
< 0 | エラー(エラーコード) |
【解説】
デバイスに対する操作の終了を宣言する。
デバイスをクローズすると、そのデバイスに属しているインターフェースや
パイプなどもクローズされる。
オープンしたタスク以外からのタスクからもクローズを行うことができる。
よって、didに誤った値を指定しないように注意すること。
【エラーコード】
USB_ERR_DEVICE | didが不正(デバイスが存在しない) |
usbOpenInterface |
|
インターフェースのオープン |
|
【形式】
WERR usbOpenInterface(W did, W ifno)
【パラメータ】
did | デバイスのアドレス(イベントから取得できる) |
ifno | インターフェース番号(インターフェースディスクリプタのbInterfaceNumber) |
【リターン値】
>= 0 | インターフェースID(iid) |
< 0 | エラー(エラーコード) |
【解説】
インターフェースに対する操作の開始を宣言する。
インターフェースに対する多重オープンはできない。
【エラーコード】
USB_ERR_DEVICE | didが不正(デバイスが存在しないか、操作が禁止されている) |
USB_ERR_INTERFACE | ifnoが不正(指定した番号のインターフェースは存在しない) |
USB_ERR_BUSY | インターフェースは既にオープンされている |
USB_ERR_NOMEM | これ以上インターフェースをオープンすることができない |
USB_ERR_SYSTEM | USBマネージャの内部エラー |
usbCloseInterface |
|
インターフェースのクローズ |
|
【形式】
ERR usbCloseInterface(W iid)
【パラメータ】
【リターン値】
= 0 (USB_OK) | インターフェースをクローズした |
< 0 | エラー(エラーコード) |
【解説】
インターフェースに対する操作の終了を宣言する。
インターフェースをクローズすると、そのインターフェースに属している
エンドポイントは全てクローズされる。
オープンしたタスク以外からのタスクからもクローズを行うことができる。
よって、iidに誤った値を指定しないように注意すること。
【エラーコード】
USB_ERR_INTERFACE | iidが不正(iidで指定したインターフェースは存在しない) |
usbOpenPipe |
|
エンドポイントのオープン(パイプの作成) |
|
【形式】
WERR usbOpenPipe(W iid, W epadr, usbIoMode mode, W mbfid)
【パラメータ】
iid | | インターフェースID(usbOpenInterface()で得る) |
epadr | | 操作の対象となるエンドポイントアドレス(エンドポイントディスクリプタのbEndpointAddress) |
mode | | 動作モード [USB_NOWAIT] | [USB_SHORTOK] |
| USB_NOWAIT | pipeへのread/write中、転送の完結を待たない(nowait mode)。指定しない場合はpipeへのread/writeの完結を待つ (wait mode)。 |
| USB_SHORTOK | usbIoPipe() での転送中、ショートパケット(要求したデータ長よりも短いデータ長で転送が終了した場合)を検出してもエラーとしない。指定しない場合はショートパケットを検出した場合にUSB_ERR_SHORTのエラーを返すようになる。 |
mbfid | | nowaitモード使用時に、ステータスを受け取るためのメッセージバッファID(負の値を指定した場合はステータスの受け取りを行わない) |
【リターン値】
>= 0 | パイプをオープンした(パイプID) |
< 0 | エラー(エラーコード) |
【解説】
パイプ(エンドポイントに対する通信路)を作成し、
指定したエンドポイントに対する操作の開始を宣言する。
エンドポイントに対する多重オープンはできない。
nowaitモードを使用できるのはインタラプト転送を使用する
エンドポイントに対してのみである。
それ以外の転送モードを使用するパイプでは指定しないこと。
waitモードを指定した場合、mbfidの値は無視される。
【エラーコード】
USB_ERR_DEVICE | デバイスへの操作が禁止されている |
USB_ERR_INTERFACE | iidが不正(インターフェースが存在しない) |
USB_ERR_ENDPOINT | epadrが不正(指定したアドレスのエンドポイントは存在しない) |
USB_ERR_BUSY | パイプは既にオープンされている |
USB_ERR_NOMEM | これ以上パイプをオープンすることができない |
usbClosePipe |
|
エンドポイントのクローズ(パイプの消去) |
|
【形式】
ERR usbClosePipe(W pid)
【パラメータ】
【リターン値】
= 0 (USB_OK) | パイプをクローズした |
< 0 | エラー(エラーコード) |
【解説】
エンドポイントに対する操作の終了を宣言する。
パイプを使用して行われている通信は全てキャンセルされる。
内部でusbCancelPipe()
を発行するため、キャンセルが完了するまで待つ。
オープンしたタスク以外からのタスクからもクローズを行うことができる。
よって、pidに誤った値を指定しないように注意すること。
【エラーコード】
USB_ERR_ENDPOINT | pidが不正(そのパイプは存在しない) |
usbIoPipe |
|
エンドポイントに対するデータの送受信 |
|
【形式】
ERR usbIoPipe(W pid, UB *buf, W len, W *rlen)
【パラメータ】
pid | パイプID |
buf | 転送するデータの先頭ポインタ |
len | 転送するデータの大きさ |
rlen | 実際に転送を行ったデータ長を格納する領域のポインタ |
【リターン値】
= 0 (USB_OK) | 転送は成功した |
< 0 | エラー(エラーコード) |
【解説】
パイプIDで指定したパイプに、
usbOpenPipe()
で指定した転送方向でデータを流す。
usbOpenPipe()
でnowaitモードを指定した場合を除き、
動作が完了するまでこの関数は終了しない。
nowaitモードの場合、rlenには0が格納される。
また、以下の点に注意する必要がある。
- 転送終了の通知およびそのステータスは
usbOpenPipe()で指定したメッセージバッファに格納される
(メッセージバッファに空きが無い場合はこの通知が行えないので、
メッセージバッファの空きには注意すること)。
- 転送するデータを格納する領域は
転送が終了する時点まで確保されていなければならない。
転送終了前にデータを格納する領域が解放された場合の動作は
保証しない。
エンドポイントからデータを受信する際、datにNULLを指定するとlenで
指定したバイト数だけデータを読み捨てることができる。ただし、
この場合はlenをエンドポイントのwMaxPacketSizeの倍数にしないと
読み捨てた後のデータ転送が行えなくなってしまう。
送信する場合はdatにNULLを指定してはならない。
【エラーコード】
USB_ERR_DEVICE | デバイスへの操作が禁止されている |
USB_ERR_INTERFACE | インターフェースへの操作が禁止されている |
USB_ERR_ENDPOINT | pidが不正(パイプが存在しない) |
USB_ERR_STALL | STALLが発生した |
USB_ERR_ABORT | 通信がキャンセルされた |
USB_ERR_IO_* | 入出力エラーが発生した |
USB_ERR_BUSY | 送信要求を受け付けることができない(帯域が不足した) |
usbCancelDevice |
usbCancelInterface |
usbCancelPipe |
|
通信のキャンセル(デバイス・インターフェース・エンドポイント単位) |
|
【形式】
ERR usbCancelDevice(W did)
ERR usbCancelInterface(W iid)
ERR usbCancelPipe(W pid)
【パラメータ】
did | デバイスのアドレス(usbCancelDevice()の場合) |
iid | インターフェースID(usbCancelInterface()の場合) |
pid | パイプID(usbCancelPipe()の場合) |
【リターン値】
= 0 (USB_OK) | キャンセルに成功した |
< 0 | エラー(エラーコード) |
【解説】
usbCancelPipe()
は、pidで指定したパイプを使用して行われている通信をキャンセルする。
usbCancelInterface()
はiidで指定した
インターフェースに含まれる全てのパイプの通信をキャンセルする。
usbCancelDevice()
はdidで指定したデバイスに含まれる
全てのパイプの通信をキャンセルする。
waitモードのusbIoPipe()で通信を行っているタスクでは、
USB_ERR_ABORTのエラーコードが返る。
nowaitモードの場合、usbOpenPipe()で指定したメッセージバッファに
メッセージが格納され、そのエラーコードはUSB_ERR_ABORTとなる。
また、対象とするパイプのwait/nowaitモードに関わらず、この関数は
パイプの通信が中断されるまで待ち状態となる。
【エラーコード】
USB_ERR_DEVICE | didが不正(デバイスが存在しない) |
USB_ERR_INTERFACE | iidが不正(インターフェースが存在しない) |
USB_ERR_ENDPOINT | pidが不正(パイプが存在しない) |
usbAlivePipe |
|
パイプが使用できるかをチェック |
|
【形式】
ERR usbAlivePipe(W pid)
【パラメータ】
【リターン値】
= 0 (USB_OK) | パイプは使用可能である |
< 0 | エラー(エラーコード) |
【解説】
pidで指定したパイプが使用可能であるかどうかをチェックする。
通信が中断された際などで、それ以降のアクセスを行うことが
できるかどうかを知る目的で使用される。
【エラーコード】
USB_ERR_DEVICE | デバイスは存在しない |
USB_ERR_INTERFACE | インターフェースは存在しない |
USB_ERR_ENDPOINT | パイプは存在しない |
usbRegistDevice |
|
デバイス接続・解除イベントの通知先を登録 |
|
【形式】
ERR usbRegistDevice(ID portid, usbEventPattern *pattern)
【パラメータ】
portid | デバイスイベント受付用ランデブポートID |
pattern | イベント通知条件のポインタ(pattern = NULLの場合は登録の解除になり、これ以降は指定したポートに対するイベントの通知を行わなくなる) |
【リターン値】
= 0 (USB_OK) | 登録に成功した |
< 0 | エラー(エラーコード) |
【解説】
USBデバイスの接続・解除時に発生するイベント(デバイスイベント)の
送り先を指定する。デバイスイベントの受信条件はpatternで指定する。
一つのポートに複数の条件を登録することが可能だが、
消去する場合はポートに関連付けられた全ての条件が消去される。
通常は、後述のusbRegistInterface()
を使用して
インターフェース単位のドライバを作成する方が簡単だと思われる。
usbEventPattern構造体は以下の形をとる。この構造体は、後述の
usbRegistInterface()
でも使用する。
typedef struct {
UB bClass;
UB bSubClass;
UB bProtocol;
UB mask;
} usbEventPattern;
usbRegistDevice()
を使用する場合、
bClass, bSubClass, bProtocolの値はデバイスディスクリプタの
bDeviceClass, bDeviceSubClass, bDeviceProtocolに対応する。
usbRegistInterface()
を使用する場合、
bClass, bSubClass, bProtocolの値はインターフェースディスクリプタの
bInterfaceClass, bInterfaceSubClass, bInterfaceProcotolに対応する。
maskは以下の4種類がある。EVENT_ANYを指定するか、または
EVENT_CLASS, EVENT_SUBCLASS, EVENT_PROTOCOLの3つの組み合せで
対象とするデバイスに対するイベントを発生させる
(ただし、maskに0は指定できない)。
EVENT_ANY | デバイス・インターフェースの種類は問わない |
EVENT_CLASS | bClassを比較対象とする |
EVENT_SUBCLASS | bSubClassを比較対象とする |
EVENT_PROTOCOL | bProtocolを比較対象とする |
【エラーコード】
USB_ERR_DEVICE | 指定したポートに対するデバイス接続イベントの登録が行われていない(pattern = NULLの時に発生) |
USB_ERR_NOMEM | これ以上デバイスイベントを登録できない |
USB_ERR_PAR | pattern.maskが0である |
usbRegistInterface |
|
インターフェース接続・解除イベントの通知先を登録 |
|
【形式】
ERR usbRegistInterface(ID portid, usbEventPattern *pattern)
【パラメータ】
portid | デバイスイベント受付用ランデブポートID |
pattern | イベント通知条件のポインタ(pattern = NULLの場合は登録の解除になり、これ以降は指定したポートに対するイベントの通知を行わなくなる) |
【リターン値】
= 0 (USB_OK) | 登録に成功した |
< 0 | エラー(エラーコード) |
【解説】
USBデバイスの接続が行われたものの、デバイスに対応するドライバが
存在しない場合はUSBマネージャ側でコンフィギュレーションを行う。
この際に使用されるコンフィギュレーションは、一番最初に読み出せる
(コンフィギュレーションインデックスが0の)
コンフィギュレーションディスクリプタを使用する。
USBマネージャによるコンフィギュレーションが終了し、
使用可能なインターフェースが決定した時に発生するイベント
(インターフェースイベント)の送り先を指定する。
インターフェースイベントの受信条件はpatternで指定する。
なお、インターフェースクラスが合致していても、
bAlternateSettingが0でない場合はイベントの発生対象とはならない。
usbEventPattern構造体に関する説明は、
usbRegistDevice()
の項にある。
【エラーコード】
USB_ERR_INTERFACE | 指定したポートに対するインターフェース接続イベントの登録が行われていない(pattern = NULLの時に発生) |
USB_ERR_NOMEM | これ以上インターフェースイベントを登録できない |
USB_ERR_PAR | pattern.maskが0である |
usbSuspend |
usbResume |
|
USBマネージャのサスペンド・レジューム制御 |
|
【形式】
VOID usbSuspend(Bool start)
VOID usbResume(Bool start)
【パラメータ】
start | True | サスペンド移行処理を開始する(usbSuspend() ) |
| | 何もしない(usbResume() ) |
| False | 何もしない(usbSuspend() ) |
| | レジューム移行処理を開始する(usbResume() ) |
【リターン値】
【解説】
システムのサスペンド・レジューム処理をUSBマネージャに通知する。
サスペンド中はデバイス接続・解除を検出することができなくなるため
サスペンド中はデバイスを解除し、レジューム時にデバイスを接続する
処理を行っている。
よって、サスペンド処理中にデバイス・インターフェース解除イベントが、
レジューム処理中にデバイス・インターフェース接続イベントが発生する。
(デバイスドライバは、これらのイベントを受信できるよう、また
受信した後に然るべき措置をとれるようにしておく必要がある)
usbSuspend()
もしくはusbResume()
の
どちらかの処理が終了するまでもう片方の処理を行った場合の動作は
保証しない。
usbResetDevice |
|
デバイスのリセット(ソフトウェアによるデバイスの切り離し・再接続) |
|
【形式】
ERR usbResetDevice(W did)
【パラメータ】
【リターン値】
= 0 (USB_OK) | デバイスをリセットした |
< 0 | エラー |
【解説】
didで指定したデバイスをリセットする。
デバイスを一旦解除し、再度接続したの同じ効果があり、
リセットの対象になったデバイスに対応付けられているドライバには
デバイス解除イベント→デバイス接続イベントの順にイベントが
送られる。
リセットを行った後のデバイスのアドレスはリセットを行う前と
同じとは限らない。
また、デバイスのリセットが完了するまでこの関数が待つことは無い。
【エラーコード】
USB_ERR_DEVICE | didが不正(デバイスが存在しない) |
usbGetHubInfo |
|
デバイス接続情報の取得 |
|
【形式】
WERR usbGetHubInfo(W *report, W size)
【パラメータ】
report | 接続情報を格納する領域のポインタ |
size | 接続情報を格納する領域の大きさ |
【リターン値】
【解説】
USBハブデバイスの接続情報を取得する。
reportのフォーマットは以下の通りである。
bit 31 16 15 0
+0 [[ hub deviceのアドレス ][ hub deviceのステータス ]]
bit 31 8 7 0
+4 [[ 未使用(0) ][hub deviceのポート数]]
+8〜 (portの数だけ繰り返し)
bit 31 16 15 0
[[ 接続されているdeviceのaddr. ][ deviceのステータス ]]
hub deviceのステータスは以下の構造体で表される。
typedef union {
struct {
UH level:3; /* hubの段数 */
UH self_power:1; /* self powered hubなら1 */
UH reserved:12;
} bmStatus;
UH status;
} usbHubStatus;
- hub deviceに接続されているデバイスが存在しない場合、deviceのアドレスは-1となる。
- deviceのステータスは以下の通りである。
PS_PORT_CONNECTION | 0x0001 | デバイスが接続されている場合に設定される |
PS_PORT_ENABLE | 0x0002 | デバイスがオープンされている場合に設定されている |
PS_PORT_SUSPEND | 0x0004 | デバイスがサスペンド状態の場合に設定される(通常、この値が設定されることはない) |
PS_PORT_OVER_CURRENT | 0x0008 | デバイスが過電流状態にある場合(bus-powered hubが2つ連続で接続された場合はホストから遠い側のhubに設定される)
|
PS_PORT_RESET | 0x0010 | デバイスはリセットを行っている(通常、この値が設定されることはない) |
PS_PORT_POWER | 0x0100 | deviceに対して電源が供給されている場合に設定される(通常はこの値が設定されているが、ハブもしくはデバイスに何らかの異常が起こっている場合は設定されていないことがある) |
PS_PORT_LOW_SPEED | 0x0200 | low speed device(キーボードやマウス等が挙げられる)が接続された場合に設定される |
【エラーコード】
USB_ERR_NOMEM | reportを格納するだけの領域が確保されていない |
本項目では、USBマネージャシステムコールの説明で
USB_ERR_IO_*
のように書かれているエラー
(USBデバイスとの通信中に発生するエラー)に関しての説明を行う。
USB_ERR_IO_NAK
-
デバイスからのNAK応答が一定時間(10秒)以上続いた場合に発生する。
ただし、インタラプト転送を使用するパイプではこのエラーは発生しない。
USB_ERR_IO_SHORT
-
usbOpenPipe()
でUSB_SHORTOKを指定しない状態で
usbIoPipe()
でデータをやり取りした際に、
指定したデータ長より短いサイズでデータのやり取りが終了した場合に
発生する。
USB_ERR_IO_BABBLE
-
バブル(babble)が発生した場合にこのエラーコードが返される。
USB_ERR_IO_CRC
-
CRCエラーが発生した場合にこのエラーコードが返される。
USB_ERR_IO_BITSTUFF
-
ビットスタッフ(bit stuff)エラーが発生した場合に
このエラーコードが返される。
USB_ERR_IO_BABBLE, USB_ERR_IO_CRC, USB_ERR_IO_BITSTUFF
が
頻繁に発生する場合、USBデバイスに問題がある可能性が考えられる。
USB_ERR_IO_BUFERR
-
USBホストコントローラとメインメモリとの間の転送で
問題が発生した場合に起こるエラーである。
通常は発生しないが、
ホストコントローラの種類によっては発生することがある。
USB_ERR_IO_NORESP
-
デバイスが解除されてからUSBマネージャがデバイスの解除を検知する
までの間には多少のタイムラグがあり、その間にデバイスに対して
通信を行った際に発生するエラーである。
このエラーが発生した場合、それ以降はデバイスに対する操作を
行うのを避けるべきである。
この章の目次にもどる
前頁:第14章 ネットワークデバイスにもどる