<!doctype linuxdoc system>

<article>

<title>ISAPnP-HOWTO
<author> 川嶋 勤<tt>&lt;kawawa@mail.interq.or.jp&gt;</tt>
<date>Ver 3.0 Mon Nov 31 19:00:00 JST 2002
<abstract>
本文書では Linux で ISAPnP を使う方法を説明しています。
本文書は 3 部構成になっていて、PnP(Plug and Play)の概略、Linux でサポート
されている三つの方法(kernel 2.4 の組み込み機能、isapnptools、サウンドカード
限定ですが ALSA)についての具体例、ISAPnP の技術情報について説明しています。
</abstract>
<toc>
<sect>改訂について
<p>
本文書は 2001 年 2 月に最初にリリースされました。 kernel 2.4 のバージョンアッ
プに伴い、設定の方法が少し変更されたため 2002 年 11 月に改訂しました。

<sect>はじめに
<p>
本文書は Linux で ISAPnP を使う方法を説明しています。本文書は大別すると 3 つの
部分に分かれ、それぞれ PnP の概略、ISAPnP の使い方、ISAPnP の技術情報について
説明しています。
<p>
本文書のご利用は<em>自己責任</em>にて、お願いいたします。

<!--
以下の章は JF の sgmlmemo.txt から、引用し使用しました。何か問題がある場合、
ご指摘ください。
-->
<sect>この文書の配布について
<p>
copyrighted (c) 2002 Tsutomu Kawashima

この文書は GNU パブリックライセンス (GPL) バージョン 2 かそれ以降の条件、
あるいは標準的な Linux ドキュメントプロジェクト (LDP) の条件に基づいた
配布ならば自由にしていただいてかまいません。これらのライセンスはこの
ドキュメントが入手できるようなサイトから入手できます。LDP の条件は
(翻訳をのぞく) いかなる修正も許可していません。修正されたバージョンは
GPL の基でのみ配布されるものとすることが可能です。

<sect>Plug and Play プラグアンドプレイとは<label id="what_is_pnp">
<p>
Plug and Play 略して PnP は人の手を何ら煩わすことなく、ハードウェアを
挿す (Plug) だけで、使用 (Play) できるようにする仕組みのことです。
PnP を実現するには、広い分野に渡る規格化、標準化が必要です。


<!-- HTML  出力のとき 表にする --> 
<#if output="html">
<sect1>PnP の実現条件<label id="pnp_imp_cond">
<p>
PnP (挿せば使える)を実現するためには、幾つかの条件を規定、規格化する
必要があります。その条件を下記に示します。
下記の項目で使用している記号について説明します。
<descrip>
<tag>HD</tag>ハードウェアで対応

<tag>HD/OS</tag>ハードウェア または OS で対応

<tag>HD+OS</tag> ハードウェアと OS が協調して対応

<tag>OS</tag> OS で対応 
</descrip>
<table loc="tbp">
<tabular ca="ccc">
対応するのに必要なもの | 条件 | 説明 @

HD |  機械的に接続できること | 
機械的な形状や、ピンの数、オスメスの区別等を規定しないと、挿す (Plug) ことが
できません。
@

HD | 電気的に接続できること | 
機械的に挿せても、電気的に接続できなければなりません。オプションとか、
ベンダデファイン(製造元が自由に定義できる部分)が含まれていても、いけません。
さらに、信号電位、タイミング、ハードウェア上のプロトコルも規定する必要があります。
@

HD/OS |  接続の有無が判別できること |
機械的な機構、電気的な方法、ソフトウェアによる方法等を使用し、接続の有無が
判別できなければなりません。
@

HD/OS | 分離(isolate)できること |
バス(Bus)接続ができる機器の場合、個々の機器が分離して、識別できる必要があります。
@

HD+OS | 何が接続されているか識別できること |
何が接続されているか識別できることが、必要です。多くの PnP の場合、
複数の識別子(種類、製造元、機器、改訂等)を使って、識別をしています。
識別子を識別する方法や、識別子の意味が規定されている必要があります。
別の機器と混同しないように、これらの識別子の幾つかは、その PnP の規格団体等で
一意に管理されています。
@

HD+OS | 必要な情報について規定されていること |
必要な情報とは、接続されている機種や PnP の規格に依存します。
例えば、PCIの場合、 I/O ポートアドレスや、IRQ 等です。ディスプレイ・モニタ
(DDC)の場合、解像度等です。必要な情報の取り出す方法(プロトコル)や、情報の内容
が規定されている必要があります。
@

OS | リソースの割り当てができること | 
接続される機器にリソース(I/O ポートアドレスや IRQ 等)の割り当てが必要な場合、
現在のリソースと衝突しないように、割り当てることが必要です。
@

OS | デバイスドライバの割り当てができること |
接続された、機器に対応したデバイスドライバを自動的に見つけ出せることが、
必要です。
人手により、設定する場合、ハードウェアの情報を、人にとって、わかりやすい
方法で、提示する必要があります。デバイスドライバと機器のリソースが
一致するように割り当てることと、デバイスドライバが割り当てられたリソースで
動作できなければ、なりません。
</tabular>
</table>

<sect1>PnP の実現方法<label id="pnp_imp_method">
<p>
<ref id="pnp_imp_cond" name="PnP の実現条件">を実際にどのように実現しているか、
概略を説明します。
<table loc="tbp">
<tabular ca="rrr">
実現に必要なもの | 条件 | 説明 @
HD |  機械的に接続できること・電気的に接続できること |
これらを実現するには、PnP 対応ハードウェアの供給元に規格を守ってもらうしか、
ありません。より効果的に、PnP に対応させるため、PnP 規格団体を設立する方法が
あります。この団体は、シンボルやマークの制定、ハードウェアの識別子の管理、
PnP 規格の情報(Know-How)の提供等を行います。ハードウェアの供給元はこの団体に
加盟し、PnP 規格を準拠したものに対して、シンボルの使用許可や、識別子の
割り当てを得ます。
一時期の USB のように、規格そのものを団体の加盟者以外には、秘密にすることも
あります(顰蹙を買い、現在 USB 規格は公開されています)。
尚、シンボルやマークは著作権の保護下に置くことで、勝手に使用できないように
できます。
@

HD/OS | 接続の有無が判別できること・分離(isolate)できること | 
これらは Bus 接続される ハードウェアに関連する項目です。当初から PnP を
目指した Bus 規格では、仕様に織り込み済みですので問題はありません。
後から、PnP 対応にした ISAPnP では、大きな問題があります。
@

HD+OS | 何が接続されているか識別できること・必要な情報について規定されていること |
これらは、PnP 対応ハードウェアに自己紹介させる、仕組みを用意することで、
実現します。実際には ハードウェアにコンフィグレーションレジスタ群を使用します。
このレジスタ群に、ハードウェアの ID(識別子)や、リソースの情報等を納めます。
@

OS | リソースの割り当てができること・デバイスドライバの割り当てができること |
これらは、OS がリソースとデバイスドライバを管理して、実現します。割り当てに
必要なリソースの情報はコンフィグレーションレジスタ群から読み取ります。OS は現在
管理しているリソース表から、未使用のリソースをコンフィグレーションレジスタ群に
書き込んで設定し、OS の管理しているリソース表を更新します。デバイスドライバの
割り当ては、デバイスドライバの特定と設定の二つの段階に分けられます。
デバイスドライバの特定には、コンフィグレーションレジスタ群から、ID(識別子)を
読み取ることで行います。この ID とデバイスドライバの対応表(データーベース)
から、デバイスドライバを特定します。または、ID を人にとって理解しやすい
方法で、表現し、人にデバイスドライバを選んでもらいます(PnP の目的(人手を
煩わすことなく)に反します)。
デバイスドライバが特定できたら、コンフィグレーションレジスタに書き込んだ
リソース情報と同じものを、デバイスドライバにも適応します。
</tabular>
</table>

</#if>

 <!-- HTML  出力では無いとき --> 
<#unless output="html">
<sect1>PnP の実現条件<label id="pnp_imp_cond">
<p>
PnP (挿せば使える)を実現するためには、幾つかの条件を規定、規格化する
必要があります。
下記の項目で使用している記号について説明します。
<descrip>
<tag>&lsqb; HD &rsqb;</tag>ハードウェアで対応

<tag>&lsqb; HD/OS &rsqb;</tag>ハードウェア または OS で対応

<tag>&lsqb; HD+OS &rsqb;</tag> ハードウェアと OS が協調して対応

<tag>&lsqb; OS &rsqb;</tag> OS で対応 
</descrip>
<p>
PnP (挿せば使える)の実現条件を下記に示します。
<descrip>
<tag>&lsqb; HD &rsqb; 機械的に接続できること</tag>
機械的な形状や、ピンの数、オスメスの区別等を規定しないと、挿す (Plug) ことが
できません。

<tag>&lsqb; HD &rsqb; 電気的に接続できること</tag>
機械的に挿せても、電気的に接続できなければなりません。オプションとか、
ベンダデファイン(製造元が自由に定義できる部分)が含まれていても、いけません。
さらに、信号電位、タイミング、ハードウェア上のプロトコルも規定する必要があります。

<tag>&lsqb; HD/OS &rsqb; 接続の有無が判別できること</tag>
機械的な機構、電気的な方法、ソフトウェアによる方法等を使用し、接続の有無が
判別できなければなりません。

<tag>&lsqb; HD/OS &rsqb; 分離(isolate)できること</tag>
バス(Bus)接続ができる機器の場合、個々の機器が分離して、識別できる必要があります。

<tag>&lsqb; HD+OS &rsqb; 何が接続されているか識別できること</tag>
何が接続されているか識別できることが、必要です。多くの PnP の場合、
複数の識別子(種類、製造元、機器、改訂等)を使って、識別をしています。
識別子を識別する方法や、識別子の意味が規定されている必要があります。
別の機器と混同しないように、これらの識別子の幾つかは、その PnP の規格団体等で
一意に管理されています。

<tag>&lsqb; HD+OS &rsqb; 必要な情報について規定されていること</tag>
必要な情報とは、接続されている機種や PnP の規格に依存します。
例えば、PCIの場合、 I/O ポートアドレスや、IRQ 等です。ディスプレイ・モニタ
(DDC)の場合、解像度等です。必要な情報の取り出す方法(プロトコル)や、情報の内容
が規定されている必要があります。

<tag>&lsqb; OS &rsqb; リソースの割り当てができること</tag>
接続される機器にリソース(I/O ポートアドレスや IRQ 等)の割り当てが必要な場合、
現在のリソースと衝突しないように、割り当てることが必要です。

<tag>&lsqb; OS &rsqb; デバイスドライバの割り当てができること</tag>
接続された、機器に対応したデバイスドライバを自動的に見つけ出せることが、
必要です。人手により、設定する場合、ハードウェアの情報を、人にとって、
わかりやすい方法で、提示する必要があります。デバイスドライバと機器の
リソースが一致するように割り当てることと、デバイスドライバが割り当てられた
リソースで動作できなければ、なりません。
</descrip>

<sect1>PnP の実現方法<label id="pnp_imp_method">
<p>
<ref id="pnp_imp_cond" name="PnP の実現条件">を実際にどのように実現しているか、
概略を説明します。
<descrip>
<tag>&lsqb; HD &rsqb; 機械的に接続できること・電気的に接続できること</tag>
これらを実現するには、PnP 対応ハードウェアの供給元に規格を守ってもらうしか、
ありません。より効果的に、PnP に対応させるため、PnP 規格団体を設立する方法が
あります。この団体は、シンボルやマークの制定、ハードウェアの識別子の管理、
PnP 規格の情報(Know-How)の提供等を行います。ハードウェアの供給元はこの団体に
加盟し、PnP 規格を準拠したものに対して、シンボルの使用許可や、識別子の割り
当てを得ます。
一時期の USB のように、規格そのものを団体の加盟者以外には、秘密にすることも
あります(顰蹙を買い、現在 USB 規格は公開されています)。
尚、シンボルやマークは著作権の保護下に置くことで、勝手に使用できないように
できます。

<tag>&lsqb; HD/OS &rsqb; 接続の有無が判別できること・分離(isolate)できること</tag>
これらは Bus 接続される ハードウェアに関連する項目です。当初から PnP を
目指した Bus 規格では、仕様に織り込み済みですので問題はありません。
後から、PnP 対応にした ISAPnP では、大きな問題があります。

<tag>&lsqb; HD+OS &rsqb; 何が接続されているか識別できること・必要な情報について規定されていること</tag>
これらは、PnP 対応ハードウェアに自己紹介させる、仕組みを用意することで、
実現します。実際には ハードウェアにコンフィグレーションレジスタ群を使用します。
このレジスタ群に、ハードウェアの ID(識別子)や、リソースの情報等を納めます。


<tag>&lsqb; OS &rsqb; リソースの割り当てができること・デバイスドライバの割り当てができること</tag>
これらは、OS がリソースとデバイスドライバを管理して、実現します。割り当てに
必要なリソースの情報はコンフィグレーションレジスタ群から読み取ります。OS は現在
管理しているリソース表から、未使用のリソースをコンフィグレーションレジスタ群に
書き込んで設定し、OS の管理しているリソース表を更新します。デバイスドライバの
割り当ては、デバイスドライバの特定と設定の二つの段階に分けられます。
デバイスドライバの特定には、コンフィグレーションレジスタ群から、ID(識別子)を
読み取ることで行います。この ID とデバイスドライバの対応表(データーベース)
から、デバイスドライバを特定します。または、ID を人にとって理解しやすい
方法で、表現し、人にデバイスドライバを選んでもらいます(PnP の目的(人手を
煩わすことなく)に反します)。
デバイスドライバが特定できたら、コンフィグレーションレジスタに書き込んだ
リソース情報と同じものを、デバイスドライバにも適応します。
</descrip>
</#if>

<sect1>PnP の種類<label id="pnp_type">
<p>
もともと PnP とは、Intel 社と Microsoft 社により、1993年 3月に発表された、
&dquot;Plug and Play ISA Specification&dquot;に由来します。単に PnP と
いった場合、ISAPnP のことでした。現在は Plug and Play(挿せば使える)に、
対応したハードウェアや仕組みのことを、すべて PnP と呼んでいます。

PnP に対応したハードウェアはたくさんあります。
これらについて、簡単に説明します。

<descrip>
<tag>CPU</tag>
 x86 系の CPU には、CPU の特性が、特別なレジスタに書き込まれてい
ます。これを、CPU ID と呼んでいます。 Linux では CPU ID を CPU 内蔵
キャッシュメモリ容量の調査と設定、 MTRR の設定に利用しています。
CPU ID の情報は <tt>/proc/cpuinfo</tt> で調べることができます。

<tag>メモリ(SPD)</tag>
メモリの種類(EDO, SD, PROM)、容量、ECC やパリティの有無
を調べることと、タイミング(CAS, RAS のレイテンシー)の設定ができます。
 
<tag>ISAPnP</tag>
ISA Bus で PnP を実現したものです。<ref id="what_is_isapnp" name="ISAPnP について">で説明します。

<tag>PCI</tag>
すべての CPU で共通に使用できることを目指した高速 32bit Bus の
規格です。コネクタやカードの機械的な形状の規定と電気的な特性や
タイミングの規定と、識別子や、ハードウェアの情報を CPU 等から、読み書き
する方法の規定を含みます。PCI は拡張カードや周辺機器の接続だけではなく、
Bus そのものの拡張方法やコンピュータ同士の接続についても、規格化されていま
す。Linux では、問題なく認識できますが、拡張カードではデバイスドライバを
指定しないと、動作しません。

<tag>USB</tag>
電源を切ることなく、機器の取り外しや、取り付けができることが特徴
です。手軽に扱えるため、最近は様々な機器のインターフェースに採用されていま
す。しかし Linux では機器毎にプロトコルが存在するため、それに対応するのが
遅れています(ネットワークに当てはめていうと、パケットの送受はできてるが、
サービス ftp smtp pop 等に対応していない状況です)。

<tag>SCSI-2</tag>
 コネクタの機械的な形状、ケーブルの特性、電気的な特性やタイミ
ングの規定と、送受するコマンドの規定が規格されています。 
高速パラレルインターフェースとして、ハードディスクや様々な機器、さらに、
コンピュータまで接続できます。SCSI-2 以前の SCSI は送受するコマンドが
規定されていなかったため、機器の組み合わせの相性問題がありました。

<tag>ATA-3</tag>
もともと ATA は IDE ハードディスクの規格でしたが、SCSI コマンドに
似た ATAPI コマンドを規定したことで、CDROM, CDR, DVD, テープ、フロッピーディスク等、多くの機器が接続できるようになりました。

<tag>DDC</tag>
 ディスプレイやモニタの特性(解像度等)をビデオカード等から読める
ようにした規格です。XFree86 4.0 でサポートされるようになりました。
あの面倒くさい <tt>Modeline</tt> から、解放されるかもしれません。 

<tag>パラレルポート機器</tag>
 IBM PC/AT 互換機のパラレルポートが双方向だったこ
とから、発展し IEEE1284 になりました。そして、プリンタ以外にもフロッピーディ
スクドライブ等、比較的低速なパラレルインターフェースに使用できるようになり
ました。

<tag>PC Card</tag>
 主に、ノートパソコンの拡張用に使用されています。PC Card 規格
の起源は電子手帳に使用するメモリーカードから始まっています。
1986 年に、最初の規格が JEIDA からガイドラインとして公開されました。
その後 1989 年にアメリカで、PCMCIA が設立され、1993 年に JEIDA と
PCMCIA の規格を統一した PC Card 規格になりました。1997 年に CardBus 規格が
発行されました。PnP という言葉の前にできた、最初の PnP です。
Linux では pcmcia-cs として、サポートされてきました。kernel 2.4 では、
PC Card のサポートは kernel に組み込まれました。
<verb>
  略語説明 JEIDA  : 日本電子工業振興協会
           PCMCIA : Personal Computer Memory Card International Association
</verb>
</descrip>

<sect>ISAPnP について<label id="what_is_isapnp">
<p>
<sect1>ISAPnP の概要<label id="isapnp_brief_description">
<p>
ISAPnP とは ISA Bus に接続された各種 I/O 装置を、ソフトウェアだけで
設定できるようにする仕組みです。ISAPnP は、ISA カード、マザーボード、 BIOS の
全てが対応している必要があります。従って、古いマザーボードでは ISAPnP は
動作しません。

ISA Bus の I/O 装置を動作させるためには、I/O アドレスや IRQ 番号等、
ハードウェアの知識が必要でした。
さらに、I/O アドレスや IRQ 番号等を変更するためには、PC のケースを
開け、ISA カード上のジャンパーピン、スイッチの切り替え、パターンのカットや
半田付けが必要でした。
また、カード固有の設定ソフトウェアが必要なものもありました。
<p>
ISAPnP は以下の項目を実現することを目指したものです。
<itemize>
<item>PC のケースを開けなくても、I/O アドレスや IRQ 番号等が変更できること。

<item>カード固有の設定ソフトウェアを不要とすること。

<item>デバイスドライバが I/O アドレスや IRQ 番号等の変更に対応できること。
</itemize>
ただし、ISAPnP の単独では、自動的にどの I/O アドレスや IRQ 番号等が
使用できるか、判断することはできません。I/O アドレスや IRQ 番号等は、
マザーボード上の I/O 装置や、PCI デバイスも使用するからです。
また、ISAPnP カードは、BIOS でリソースの割り当てをすれば、
普通の ISA カードとして、使用できます。OS がリソースの設定をする必要は
無いのですが、BIOS の割り当てたリソースは OS の管理外になってしまいます。
<p>
ISAPnP カードは、コンフィグレーションレジスタを持っています。
BIOS や OS は このコンフィグレーションレジスタと情報のやり取りをして、
ISAPnP カードの種類や、識別子を読み込み、I/O アドレス や IRQ 番号等の
設定をします。この情報のやり取りをコンフィグレーションと呼びます。

ISAPnP カードはコンフィグレーションには、必ず応答しますが、リソースが
設定されていない場合、 I/O 装置としては反応しません。ISAPnP に対応していない
マザーボードのスロットに、ISAPnP カードを挿入した場合、 ISAPnP カードは
ただ、電力を消費するだけで、I/O 装置としては、使えません。

<sect1>ISAPnP カードの種類
<p>
ISAPnP カードはリソースの設定のされかたに、幾つかの種類があります。
<descrip>
<tag>起動時にデフォルトのリソースが設定されているもの</tag>
ISAPnP カード自身が起動時に、BIOS や OS の PnP の設定をしなくとも、
デフォルトのリソースを持つものがあります。デフォルトのリソースを
ジャンパーピンや特別なソフトウェアで変更できるものもあります。

<tag>起動時に以前のリソースが設定されるもの</tag>
ISAPnP カード自身が起動時に BIOS や OS が PnP の設定をしなくとも、
不揮発性メモリに記憶させた、以前のリソースを設定するものがあります。
一度も設定がされなかった場合、デフォルト値が設定される場合と、
何も設定されない場合があります。

<tag>リソースが固定されているもの</tag>
初期のISAPnP カードには、単にコンフィグレーションレジスタを追加しただけで、
PnP 対応としたものがあります。

<tag>リソースが指定できるもの</tag>
これが、普通のISAPnP カードです。BIOS や OS がリソースを指定します。
</descrip>

起動時に ISAPnP カード自身がリソースを独自に設定するものとして、
SCSI カードがあります。
Boot BIOS ROM 搭載の SCSI ISAPnP カードは、起動時に BIOS や OS の設定が
済む前に、稼働して SCSI bus に接続されたハードディスク等の情報を取得する
必要があるためです。このような ISAPnP カードは ISAPnP に対応していない、
ハードウェアや OS でも使用できます。

<sect1>デバイスドライバの種類
<p>
デバイスドライバはリソース設定方法により、3 種類あります。
<descrip>
<tag>I/O ポートアドレスや IRQ が固定されているもの</tag>
この種類のデバイスドライバは、ソースファイルを読むか、説明を読んで、固定さ
れた I/O ポートアドレスや IRQ を指定するように ISAPnP カードを設定します。

<tag>I/O ポートアドレスや IRQ が指定できるもの</tag>
デバイスドライバの I/O ポートアドレスや IRQ をカーネルコンパイル時や、
モジュール読み込み時に、指定できるものがあります。その時の設定と、
ISAPnP の設定を同一にします。

<tag>ISAPnP の自動設定に対応しているもの</tag>
kernel 2.4 の ISAPnP ルーチンが読み込まれたとき、自動的に ISAPnP カードを設定
します。これに対応したデバイスドライバもあります。しかし、正しく設定されない
場合もあります。そのときは、手動で設定する必要があります。
</descrip>

<sect1>Linux のリソース管理
<p>
Linux では、I/O ポートアドレス、IRQ と DMA は、kernel のサービスルーチンを
呼び出して、登録しないと使用できません。
特定のアドレスの I/O メモリも、kernel の許可がないと、アクセスできません。
<verb>
注意 --- I/O メモリとは、VRAM 等の I/O として使用しているメモリのことを指し、
         メインメモリの拡張用のメモリのことでは、ありません。
</verb>
ハードウェアをアクセスするときは、デバイスドライバがこれらのリソースの
登録と、使用許可申請をします。
Linux では、<em>/proc/</em> ディレクトリ以下の 特殊なファイルを読み出すことで、
現在、使用中のリソースを調べることができます。
<descrip>
<tag>/proc/ioports</tag>
現在使用中の I/O ポートアドレスを調べることができます。

<tag>/proc/interrupts</tag>
現在使用中の 割り込み IRQ を調べることができます。

<tag>/proc/dma</tag>
現在使用中の DMA を調べることができます。

<tag>/proc/iomem</tag>
kernel 2.4 は 現在使用中の I/O メモリを調べることができます。
kernel 2.2 では、現在使用中の I/O メモリを調べる簡単な方法はありません。
</descrip>
<p>
デバイスドライバがリソースの登録をするタイミングは二つあり、一つは、
デバイスドライバが kernel に組み込まれた時と、もう一つはデバイスの
アクセスが開始(open)された時です。デバイスドライバがリソースを手放す
タイミングも二つあり、一つはデバイスドライバが kernel から取り除かれた時と、
もう一つは、デバイスのアクセスが終了(close)した時です。
<p>
フロッピーディスク・ドライブデバイスドライバは、デバイスのアクセスが
開始(open)された時にリソースを登録し、デバイスのアクセスが終了(close)した時に
リソースを手放します。
したがって、フロッピーディスクドライブは I/O ポートアドレス 0x3f0-0x3f5,
0x3f7-0x3f7, IRQ 6, DMA 2 を使用しますが、フロッピーディスクドライブを
使用していない場合、これらは /proc/ 以下に出力されません。

<sect1>Linux での ISAPnP サポート
<p>
Linux では、以下の方法で ISAPnP をサポートします。
<descrip>
<tag>kernel 2.4</tag>
kernel 2.4 に組み込まれた機能を使用します。

<tag>isapnp tool</tag>
kernel 2.0 のころから、サポートされている方法です。kernel 2.4 でも使用でき
ます。

<tag>ALSA</tag>
サウンドカードだけですが、ALSA 自身も ISAPnP をサポートしてます。
</descrip>

<sect1>ISAPnP ツールを無効にする方法
<p>
ISAPnP ツールは互いに同時に使用することはできません。 例えば、kernel 2.4 の
ISAPnP を使用する場合、他の ISAPnP ツールを無効にしなければなりません。

<sect2>kernel 2.4 の ISAPnP を無効にする方法
<p>
kernel 再構築(recompile)のときに、ISAPnP サポートを無効にします。
<em>CONFIG_ISAPNP=n</em> を設定します。
モジュールにしている場合、<em>/etc/modules.conf</em> に下記の行を追加します。
<verb>
option isapnp isapnp_disable=1
</verb>

<sect2>isapnptools を無効にする方法
<p>
最も簡単な方法は、isapnptools をアンインストールしてしまうことです。
そうしたくない場合、/sbin/isapnp がどこで実行されているか調べるため、
<em>/etc/rc.d/rc.sysinit</em> 等の初期設定ファイルを解読する必要があります。
RedHat 系の場合、<em>/etc/isapnp.conf</em> のファイル名を変更する方法と、
kernel パラメータに <em>nopnp</em> を渡す方法があります。

<sect2>ALSA の ISAPnP を無効にする方法
<p>
ALSA の ISAPnP を無効にするには、alsa-driver-* のコンパイル時に、下記のよう
にオプションを指定します。ALSA のバージョンによって、少し違うかもしれません。

<verb>
$./configure --help
オプションの確認

$./configure --with-isapnp=no
</verb>

使用するサウンドカードによっては、alsa-driver-* のコンパイルオプションに
関わりなく、モジュール読み込みのときに ISAPnP を無効にできるかもしれません。
SoundBlaster16 ISAPnP では、<em>snd_isapnp=0</em> で無効にできます。
以下は、実際に私が使用している例です。

<verb>
$cat /etc/modules.conf
alias eth0 3c509
# --- BEGIN: Generated by ALSACONF, do not edit. ---
# --- ALSACONF verion 0.4.3b ---
alias char-major-116 snd
alias snd-card-0 snd-card-sb16
alias char-major-14 soundcore
alias sound-slot-0 snd-card-0
alias sound-service-0-0 snd-mixer-oss
alias sound-service-0-1 snd-seq-oss
alias sound-service-0-3 snd-pcm-oss
alias sound-service-0-8 snd-seq-oss
alias sound-service-0-12 snd-pcm-oss
options snd snd_major=116 snd_cards_limit=1 snd_device_mode=0666 snd_device_gid=
0 snd_device_uid=0
options snd-card-sb16 snd_isapnp=0 snd_index=0 snd_id=CARD_0 snd_port=0x220 snd_
mpu_port=0x330 snd_irq=5 snd_dma8=1 snd_dma8_size=64 snd_dma16=5 snd_dma16_size=
128 snd_mic_agc=0
# --- END: Generated by ALSACONF, do not edit. ---
</verb>

<sect>kernel 2.4 の ISAPnP
<p>
kernel 2.4 の ISAPnP の文書は <em>linux/Documentations/isapnp.txt</em>です。
ISAPnP のソースファイル群は <em>linux/drviers/pnp/</em>以下にあります。
kernel 2.4 で ISAPnP を有効にするには、 kernel 再構築の時に
<em>CONFIG_ISAPNP=y または m</em>を指定します。

<sect1>kernel 2.4 ISAPnP のパラメータ
<p>
kernel 2.4 ISAPnP のパラメータを下記に示します。通常は使う必要は無いと
思います。このパラメータは ISAPnP がモジュールの場合に使います。
<verb>
/etc/modules.confに下記のように、行を追加して使用します。
option isapnp isapnp_rdp=0x203,isapnp_reset=0
</verb>
<p>
凡例
<itemize>
<item>論理値 --- 偽は 0 、真は 0 以外の整数で 32bit です。

<item>I/O アドレス --- 0 から 0x3ff までの整数です。

<item>I/O リスト -- 上記 I/O アドレスを&dquot;,&dquot;で繋げたものです。
最大で 16 項目までです。例 100,0x210。

<item>IRQ 番号 --- 0,1,3,4,5,6,7,8,9,10,11,12,13,14,15です。

<item>IRQ リスト --- 上記 IRQ 番号を&dquot;,&dquot;で繋げたものです。
最大で 16 項目までです。例 9,10,11,12。

<item>DMA 番号 --- 0 から 7 までの整数です。

<item>DMA リスト --- 上記 DMA 番号を&dquot;,&dquot;で繋げたものです。
最大で 8 項目までです。例 1,5。

<item>メモリアドレスリスト --- 0 から 1048575 (0xfffff)のメモリアドレスを
&dquot;,&dquot;で繋げたものです。最大 16 項目までです。

<item>冗長モード --- 0,1,2のいずれかです。
</itemize>

<descrip>
<tag>isapnp_disable=論理値</tag>
論理値が真のとき、ISAPnP をサポートしません。論理値が偽のとき、ISAPnP を
サポートします。初期値は偽です。

<tag>isapnp_rdp= I/O アドレス</tag>
ISAPnP の'Read Data Port'を指定します。ISAPnP の規格を参考にしてください。

<tag>isapnp_reset=論理値</tag>
ISAPnP を設定するとき、すべての ISAPnP カードをリセット(バスから切り離す)する
か否か、指定します。論理値が真のとき、リセットします。初期値は真で、
ISAPnP カードをリセットします。

<tag>isapnp_skip_pci_scan=論理値</tag>
論理値が真のとき PCI のリソースを無視します。論理値が偽のとき、PCI と
ISAPnP で、リソースの競合が起きないように、ISAPnPを設定します。初期値は偽
です。

<tag>isapnp_verbose=冗長モード</tag>
ISAPnP サポートの出力するメッセージのモードを指定します。初期値は 1 です。

<tag>isapnp_reserve_irq=IRQ リスト</tag>
ISAPnP で使用しない IRQ 番号を指定します。初期値はすべての IRQ 番号を使います。

<tag>isapnp_reserve_dma=DMA リスト</tag>
ISAPnP で使用しない DMA 番号を指定します。初期値はすべての DMA 番号を使い
ます。

<tag>isapnp_reserve_io=I/O アドレスリスト</tag>
ISAPnP で使用しない I/O アドレスを指定します。 初期値はすべての I/O アドレ
スを使います。

<tag>isapnp_reseve_mem=メモリアドレスリスト</tag>
ISAPnP で使用しない メモリアドレスを指定します。初期値はすべてのメモリアドレスを使用します。
</descrip>

<sect1>/proc/isapnp
<p>
kernel 2.4 での ISAPnP サポートは /proc/isapnp を使用します。
/proc/isapnp を読み出して設定を調べ、適切な設定を /proc/isapnp へ書き込みます。
/proc 以下に isapnp が無い場合、kernel で isapnp が有効になっていません。

<sect2>/proc/isapnp の読み出し例
<p>
/proc/isapnp を読み出すと下記のような項目が出力されます。
下記の例では SoundBlaster16 と 33k アナログモデムと 3Com 3C509B の 3 枚
の ISAPnP カードがあります。これは ISAPnP のコンフィグレーションレジスタを
読み出したものです。
/proc/isapnp の読み出し例を簡単に説明します。
<verb>
Card 1 'CTL0080:Creative ViBRA16CL PnP' PnP version 1.0 Product version1.1
この ISAPnP カードのベンダ名は CTL0080 です。
  Logical device 0 'CTL0041:Audio'
論理デバイス 0 の名前は CTL0041 です。
    Device is active
この論理デバイスはすでに active 有効になっています。
    Active port 0x220,0x330,0x388
    Active IRQ 5 [0x2]
    Active DMA 1,5
現在の設定です。
    Resources 0
      Priority preferred
      Port 0x220-0x220, align 0x0, size 0x10, 16-bit address decoding
      Port 0x330-0x330, align 0x0, size 0x2, 16-bit address decoding
      Port 0x388-0x3f8, align 0x0, size 0x4, 16-bit address decoding
      IRQ 5 High-Edge
      DMA 1 8-bit byte-count compatible
      DMA 5 16-bit word-count compatible
使用可能なリソースです。I/O ポートアドレスは 0x220,0x330,0x388 の三つを
使います。IRQ は 5, DMA は 1 と 5 を使います。
      Alternate resources 0:1
        Priority acceptable
        Port 0x220-0x280, align 0x1f, size 0x10, 16-bit address decoding
        Port 0x300-0x330, align 0x2f, size 0x2, 16-bit address decoding
        Port 0x388-0x3f8, align 0x0, size 0x4, 16-bit address decoding
        IRQ 5,7,2/9,10 High-Edge
        DMA 1,3 8-bit byte-count compatible
        DMA 5,7 16-bit word-count compatible
代替えとなるリソースです。
1 番目の I/O ポートアドレスは 0x220,0x240,0x260,0x280 のうち一つが使えます。
2 番目の I/O ポートアドレスは 0x300,0x330 のどちらかが使えます。
3 番目の I/O ポートアドレスは 0x338 から 4 バイト置きに 0x3f8 まで内、一つ
が使えます。
IRQ は 5,7,2/9,10 の 四つの内、一つが使えます。 2/9 はカスケード接続された割り
込みであることを、示しています。
1 番目の DMA は 1 か 3 が使えます。
2 番目の DMA は 5 か 7 が使えます。

(中略)
  Logical device 1 'CTL7002:Game'
論理デバイス 1 の名前は CTL7002 です。
    Device is not active
この論理デバイスは not active 無効になっています。
    Resources 0
      Priority preferred
      Port 0x200-0x200, align 0x0, size 0x8, 16-bit address decoding
使用可能なリソースです。 I/O ポートアドレスは 0x200 を使います。
      Alternate resources 0:1
        Priority acceptable
        Port 0x200-0x208, align 0x7, size 0x8, 16-bit address decoding
代替えとなるリソースです。 I/O ポートアドレスは 0x200 と 0x208 のどちらかが使
えます。

Card 2 'FUJ0202:FUJITSU Modem 33600 PNP/I2' PnP version 1.0 Product version 0.5
この ISAPnP カードのベンダ名は FUJ0202 です。
  Logical device 0 'FUJ0000:Unknown'
論理デバイス名は FUJ0000 です。
    Supported registers 0x2
    Device is active
    Active port 0x2f8
    Active IRQ 3 [0x3]
    Active DMA 0,0
現在の設定です。
    Resources 0
      Priority acceptable
      Port 0x2f8-0x2f8, align 0x7, size 0x8, 16-bit address decoding
      IRQ 3 High-Edge
使用可能なリソースです。I/O ポートアドレスは 0x2f8, IRQ は 3 を使います。
      Alternate resources 0:1
        Priority acceptable
        Port 0x3f8-0x3f8, align 0x7, size 0x8, 16-bit address decoding
        IRQ 4 High-Edge
代替えとなるリソースです。I/O ポートアドレスは 0x3f8, IRQ は 4 を使います。
      Alternate resources 0:2
        Priority acceptable
        Port 0x3e8-0x3e8, align 0x7, size 0x8, 16-bit address decoding
        IRQ 4 High-Edge
(中略)
      Alternate resources 0:8
        Priority acceptable
        Port 0x100-0xfff8, align 0x7, size 0x8, 16-bit address decoding
        IRQ 3,4,5,7,2/9,10,11,12,15 High-Edge
代替えとなるリソースです。I/O ポートアドレスは 0x100 から 8 バイト置きに
0xfff8 までの内、一つが使えます。
IRQ は 3,4,5,7,2/9,10,11,12,15 の内、どれか一つが使えます。

Card 3 'TCM5098:3Com 3C509B EtherLink III' PnP version 1.0 Product version 1.0
この ISAPnP カードのベンダ名は TCM5098 です。
  Logical device 0 'TCM5098:Unknown'
論理デバイス名は TCM5098です。
    Supported registers 0x2
    Compatible device PNP80f7
論理デバイス名の別名です。
    Device is active
    Active port 0x300
    Active IRQ 10 [0x2]
現在の設定です。
    Resources 0
      Priority preferred
      Port 0x210-0x3e0, align 0xf, size 0x10, 16-bit address decoding
      IRQ 3,5,7,2/9,10,11,12,15 High-Edge
使用可能なリソースです。
I/O ポートアドレスは 0x210 から 16 バイト置きに0x3e0 までの内、一つが
使えます。
IRQ は 3,4,5,7,2/9,10,11,12,15 の内、どれか一つが使えます。

</verb>
リソースの内 Port と IRQ の表記について簡単に説明します。
<p>
Port 0x210-0x3e0, align 0xf, size 0x10, 16-bit address decoding<newline>
Port 最小アドレス - 最大アドレス, 境界、大きさ、アクセスモード<newline>
使用できるベースアドレスは 最小から最大アドレスの範囲にある値と
境界の論理積の結果、

 Port ベースアドレス = 最小アドレスから最大アドレスの範囲の値  &amp; 境界

になります。この場合、0x210,0x220,0x230...0x3d0,0x3e0 となります。
<p>
IRQ 3,5,7,2/9,10,11,12,15 High-Edge<newline>
IRQ 割り込みのリスト 割り込みトリガの方式<newline>
このリストの中から、ひとつを選んで使用できます。
リストの中で 2/9 となっているのはカスケードされた割り込みのことを示しています。

<sect2>/proc/isapnp への書き込み
<p>
/proc/isapnp への書き込みにより、ISAPnP を設定します。

<sect1>kernel 2.4 ISAPnP の設定項目
<p>
kernel 2.4 の文書 <em>linux/Documents/isapnp.txt</em>を参考にしてください。
/proc/isapnp を読み出した結果を基に、設定します。
/proc/isapnp へ書き込むコマンドは下記の通りです。

<p>
<descrip>
<tag>card 番号 ベンダ名</tag>
一番最初に ISAPnP カードを指定します。番号とベンダ名を指定します。通常、
番号は 0 です。ベンダ名は /proc/isapnp から <em>Card n 'ベンダ:....'</em>
のようにわかります。

<tag>dev 番号 論理デバイス名</tag>
ISAPnP カードの設定したい論理デバイスを指定します。番号と論理デバイス名
は /proc/isapnp から <em>Logical device 番号 '論理デバイス名:'</em>の
ようにわかります。

<tag>auto</tag>
指定した、論理デバイスを自動的に設定します。たぶん、あなたの
望んだような結果には、ならないでしょう。

<tag>port 番号 値</tag>
指定した論理デバイスの I/O ポートアドレスを設定します。
番号は /proc/isapnp での <em>Port</em> の順番を指定します。
最初の番号は 0 にします。
値は /proc/isapnp を読み出した結果と PC の現在使用している I/O ポートアドレス
を <em>/proc/ioports</em> から調べて、設定します。

<tag>irq 番号 値</tag>
指定した論理デバイスの IRQ を指定します。
番号は /proc/isapnp での <em>IRQ</em> の順番を指定します。
最初の番号は 0 にします。
値は /proc/isapnp を読み出した結果と PC の現在使用している IRQ を
 <em>/proc/interrupts</em> から調べて、設定します。

<tag>dma 番号 値</tag>
指定した論理デバイスの DMA を設定します。
番号は /proc/isapnp での <em>DMA</em> の順番を指定します。
最初の番号は 0 にします。
値は /proc/isapnp を読み出した結果と PC の現在使用している DMA を
 <em>/proc/dma</em> から調べて、設定します。

<tag>memory 番号 値</tag>
指定した論理デバイスのメモリアドレスを設定します。
番号は /proc/isapnp での <em>Memory</em> の順番を指定します。
最初の番号は 0 にします。
値は /proc/isapnp を読み出した結果から、設定します。
I/O が使用しているメモリは <em>/proc/iomem</em> や <em>/sbin/lspci コマンド</em>で調べられます。

<tag>poke|pokew|poked レジスタ 値</tag>
ISAPnP の論理デバイスのレジスタの値を変更します。特殊なコマンドです。

<tag>deactivate</tag>
指定した論理デバイスを無効にします。

<tag>activate</tag>
指定した論理デバイスを有効にします。最後にこれを指定しないと、設定はすべて
無視されます。(isapnp_proc.c では先頭の 3 文字だけ検査しています)
</descrip>

<sect1>kernel 2.4 での設定例<label id="2.4_conf">
<p>
下記に設定例を示します。
<p>
SoundBlaster16 用の設定です。論理デバイス 1 CTL7002 は'dev 1 CTL7002'となるはず
ですが、'dev 0 CTL7002'にしないと、エラーになります。
<verb>
$cat SB16
card 0 CTL0080
dev 0 CTL0041
port 0 0x220
port 1 0x330
port 2 0x388
irq 0 5
dma 0 1
dma 1 5
active
dev 0 CTL7002
port 0 0x200
active
</verb>
<p>
3C509用の設定です。
<verb>
$cat 3c509
card 0 TCM5098
dev 0 TCM5098
port 0 0x300
irq  0 10
active
</verb>
<p>
33k アナログモデムは自動設定で、動作していますので、設定はしていません。

<sect1>kernel 2.4 での設定の注意
<p>
<itemize>
<item>設定は ISAPnP カード毎にしてください。

<item>設定に空行を含めないようにしてください。

<item>デバイスドライバが読み込まれる前に設定してください。

<item>他の ISAPnP 設定プログラムと併用しないでください。
</itemize>
<sect1>設定の試験
<p>
設定が正しいか試験してみましょう。
<verb>
#cat SB16 >/proc/isapnp
</verb>
設定に問題があれば、メッセージが表示されるか、<em>/var/log/messages</em>に
記録されます。以下にエラーメッセージの例を示します。
<verb>
Sep 29 21:55:09 localhost kernel: isapnp: device 'CTL7002' order 0 not found
Sep 29 21:55:35 localhost kernel: isapnp: wrong command 'logdev'
</verb>
設定に問題がなければ、とくにメッセージは表示されず、
<em>/var/log/messages</em>にも、なにも記録されません。
/proc/isapnp を読み出すと、設定したデバイスが <em>Device is active</em>に
なるはずです。
以下に設定が成功した場合の /proc/isapnp を示します。
<verb>
Card 1 'CTL0080:Creative ViBRA16CL PnP' PnP version 1.0 Product version 1.1
  Logical device 0 'CTL0041:Audio'
    Device is active
中略
  Logical device 1 'CTL7002:Game'
    Device is active
中略
Card 3 'TCM5098:3Com 3C509B EtherLink III' PnP version 1.0 Product version 1.0
  Logical device 0 'TCM5098:Unknown'
    Supported registers 0x2
    Compatible device PNP80f7
    Device is active
</verb>

<sect1>kernel 2.4 起動時の設定<label id="2.4_boot">
<p>
ISAPnP の設定は、kernel 起動後、できるだけ早く行う必要があります。
ISAPnP の設定には /proc を使用するので、/proc がマウントされた直後に行う
のが良いでしょう。
ディストリビューションによっても違いますが、ここでは、RedHat 系の
<em>/etc/rc.d/rc.sysinit</em>スクリプトを使う場合を説明します。
/etc/rc.d/rc.sysinit の /proc のマウント直後に下記のように追加します。
<p>
<verb>
mount -t proc /proc /proc
#isapnp in kernel
if [ -d /etc/isapnp.d ]; then
    for i in /etc/isapnp.d/*; do
         echo "ISA PnP setup :$i"
         cat $i >/proc/isapnp
    done
fi
</verb>
<p>
そして、<em>/etc/isapnp.d</em> ディレクトリを作成し、その中に ISAPnP の設
定ファイルを置きます。設定ファイルの内容は<ref id="2.4_conf" name
="kernel 2.4 での設定例">を参照してください。
<verb>
$ls /etc/isapnp.d
3c509  SB16
</verb>

<sect>isapnptools<label id="isapnptools">
<p>
isapnptools は Linux で比較的古くから、サポートされている ISAPnP 設定ツール
です。isapnptools はコンフィグレーションレジスタを読み出して、標準出力する
 <em>pnpdump</em>コマンドと ISAPnP カードを設定する <em>isapnp</em> コマンド
のふたつのコマンドから、構成されています。
pnpdump の標準出力をファイルにしたものを編集して、isapnp の設定に使います。
下記では、この設定ファイルを <em>isapnp.conf</em> と呼びます。

たぶん、isapnptools は 既にご使用中の Linux にインストールされている
でしょう。ここでは、念のためインストールから説明します。

<sect1>isapnptools のインストール<label id="isapnptools_install">
<p>
isapnptools の最新版は<url url="http://www.roestock.demon.co.uk/isapnptools/"
 name="isapnptoolsのウェブサイト">から入手できます。
2002 年 10 月現在の最新版は (09-May-201 にリリースされた) 
<em>isapnptools-1.26.tgz</em>です。
適当なディレクトリ(ここでは&tilde;/Src)に <em>isapnptools-1.26.tgz</em> を
ダウンロードしたら、展開し、コンパイル、インストールします。

下記の文で、&num;&num;はコメントです。
<verb>
$ tar tvzf isapnptools-1.26.tgz  ##中身を確認します。
$ tar xzf isapnptools-1.26.tgz   ##展開します。
$ cd isapnptools-1.26
$ less README                    ##README は必ず読みましょう
$ less doc/*                     ##文書に 一通り目を通しましょう。
$ ./configure --help             ##どんなオプションがあるか確認します。
$ ./configure                    ##オプションなしで、良いみたいです。
$ make                           ## コンパイルエラーが出たら、下記を参照。
$ su
# make install                   ##インストールします。
# exit
$
尚、標準では、オブジェクトや man ページは /usr/local/ にインストールされます
(configure のオプションで変更できます)。 ディストリビュータの isapnptools で
は、/sbin/isapnp, /sbin/pnpdump, /usr/share/man/man5/isapnp.conf.5.gz と
インストールされることが多いようです。
</verb>

古い isapnptools-1.23 には、残念なこと
バグがありますので、<em>isapnptools-1.23/src/pnpdump_main.c</em> の 87 行目を
下記のように変更します。
<verb>
 static FILE* o_file = NULL;
</verb>

<sect1>isapnptools の使い方<label id="isapnptools_usage">
<p>
isapnptools では、<em>pnpdump</em> で ISAPnP カードの設定を読み出し、それを
編集し、 <em>isapnp</em> コマンドで設定する方法を取ります。例えば下記のように
します。
<verb>
$ su
# /usr/local/sbin/pnpdump >isapnp.conf
# vi isapnp.conf
# /usr/local/sbin/isapnp -c isapnp.conf
# exit
</verb>

<sect1>pnpdump の出力 isapnp.conf の例
<p>
pnpdump は下記のような項目を出力します。kernel 2.4 の /proc/isapnp よりも、
解りやすいのでしょう。これを適切に編集し、<em>isapnp</em> コマンドの
設定ファイルにします。

下記の例では SoundBlaster16 と 33k アナログモデムと 3Com 3C509B の 3 枚
の ISAPnP カードがあります。
これは ISAPnP のコンフィグレーションレジスタを読み出したものですから、
kernel 2.4 の /proc/isapnp と同一の内容を表しています。
ここでは、下記の出力 isapnp.conf の例を簡単に説明します。
&num;以降はコメントで、<em>isapnp</em> コマンドは無視します。

<verb>
# $Id: ISAPnP-HOWTO.sgml,v 1.3 2002/11/30 11:14:44 mdk Exp $
# Release isapnptools-1.24
# 
# This is free software, see the sources for details.
# This software has NO WARRANTY, use at your OWN RISK
# 
# For details of the output file format, see isapnp.conf(5)
# 
# For latest information and FAQ on isapnp and pnpdump see:
# http://www.roestock.demon.co.uk/isapnptools/
# 
isapnptools そのものの説明です。

# Compiler flags:  -DREALTIME -DHAVE_PROC -DENABLE_PCI -DHAVE_SCHED_SETSCHEDULER -DHAVE_NANOSLEEP -DWANT_TO_VALIDATE
isapnptools をコンパイルしたときのフラグです。

# 
# Trying port address 0273
# Board 1 has serial identifier 9a ff ff ff ff 80 00 8c 0e
# Board 2 has serial identifier 50 30 80 03 e5 02 02 aa 1a
# Board 3 has serial identifier 08 97 19 38 e6 98 50 6d 50


# (DEBUG)
(READPORT 0x0273)
(ISOLATE PRESERVE)
(IDENTIFY *)
(VERBOSITY 2)
(CONFLICT (IO FATAL)(IRQ FATAL)(DMA FATAL)(MEM FATAL)) # or WARNING
これらは、isapnp コマンドへの指示です。

# Card 1: (serial identifier 9a ff ff ff ff 80 00 8c 0e)
# Vendor Id CTL0080, No Serial Number (-1), checksum 0x9A.
# Version 1.0, Vendor version 1.1
# ANSI string -->Creative ViBRA16CL PnP<--
#
# Logical device id CTL0041
#     Device supports vendor reserved register @ 0x39
#     Device supports vendor reserved register @ 0x3c
#     Device supports vendor reserved register @ 0x3d
#     Device supports vendor reserved register @ 0x3f
1 枚目のカードの説明です。

#
# Edit the entries below to uncomment out the configuration required.
# Note that only the first value of any range is given, this may be changed if required
# Don't forget to uncomment the activate (ACT Y) when happy

(CONFIGURE CTL0080/-1 (LD 0
#     ANSI string -->Audio<--
1つめの論理デバイスの設定です。

# Multiple choice time, choose one only !
選択候補はたくさんあるけれど、ひとつだけ選んでね。

#     Start dependent functions: priority preferred
選択候補その 1 です。

#       IRQ 5.
#             High true, edge sensitive interrupt (by default)
# (INT 0 (IRQ 5 (MODE +E)))
IRQ 5 を使います。

#       First DMA channel 1.
#             8 bit DMA only
#             Logical device is a bus master
#             DMA may execute in count by byte mode
#             DMA may not execute in count by word mode
#             DMA channel speed in compatible mode
# (DMA 0 (CHANNEL 1))
1 番目の DMA の設定です。DMA 1 を使います。

#       Next DMA channel 5.
#             16 bit DMA only
#             Logical device is a bus master
#             DMA may not execute in count by byte mode
#             DMA may execute in count by word mode
#             DMA channel speed in compatible mode
# (DMA 1 (CHANNEL 5))
2 番目の DMA の設定です。DMA 5 を使います。

#       Logical device decodes 16 bit IO address lines
#             Minimum IO base address 0x0220
#             Maximum IO base address 0x0220
#             IO base alignment 1 bytes
#             Number of IO addresses required: 16
# (IO 0 (SIZE 16) (BASE 0x0220))
1 番目の I/O ポートアドレスの設定で、16 バイト分、0x220 から使います。

#       Logical device decodes 16 bit IO address lines
#             Minimum IO base address 0x0330
#             Maximum IO base address 0x0330
#             IO base alignment 1 bytes
#             Number of IO addresses required: 2
# (IO 1 (SIZE 2) (BASE 0x0330))
2 番目の I/O ポートアドレスの設定で、2 バイト分、0x330 から使います。

#       Logical device decodes 16 bit IO address lines
#             Minimum IO base address 0x0388
#             Maximum IO base address 0x0388
#             IO base alignment 1 bytes
#             Number of IO addresses required: 4
# (IO 2 (SIZE 4) (BASE 0x0388))
3 番目の I/O ポートアドレスの設定で、4 バイト分、0x388 から使います。

#       Start dependent functions: priority acceptable
代替えとなるリソースの設定です。

#       IRQ 5, 7, 9 or 10.
#             High true, edge sensitive interrupt (by default)
# (INT 0 (IRQ 5 (MODE +E)))
IRQ は 5,7,9,10 の四つの内、一つが使えます。

#       First DMA channel 1 or 3.
#             8 bit DMA only
#             Logical device is a bus master
#             DMA may execute in count by byte mode
#             DMA may not execute in count by word mode
#             DMA channel speed in compatible mode
# (DMA 0 (CHANNEL 1))
1 番目の DMA は 1 か 3 が使えます。

#       Next DMA channel 5 or 7.
#             16 bit DMA only
#             Logical device is a bus master
#             DMA may not execute in count by byte mode
#             DMA may execute in count by word mode
#             DMA channel speed in compatible mode
# (DMA 1 (CHANNEL 5))
2 番目の DMA は 5 か 7 が使えます。

#       Logical device decodes 16 bit IO address lines
#             Minimum IO base address 0x0220
#             Maximum IO base address 0x0280
#             IO base alignment 32 bytes
#             Number of IO addresses required: 16
# (IO 0 (SIZE 16) (BASE 0x0220))
1 番目の I/O ポートアドレスは 0x220,0x240,0x260,0x280 のうち一つが使えます。

#       Logical device decodes 16 bit IO address lines
#             Minimum IO base address 0x0300
#             Maximum IO base address 0x0330
#             IO base alignment 48 bytes
#             Number of IO addresses required: 2
# (IO 1 (SIZE 2) (BASE 0x0300))
2 番目の I/O ポートアドレスは 0x300,0x330 のどちらかが使えます

#       Logical device decodes 16 bit IO address lines
#             Minimum IO base address 0x0388
#             Maximum IO base address 0x0388
#             IO base alignment 1 bytes
#             Number of IO addresses required: 4
# (IO 2 (SIZE 4) (BASE 0x0388))
3 番目の I/O ポートアドレスは 0x338 から 4 バイト置きに 0x3f8 までの内、一つ
が使えます。

中略

#     End dependent functions
 (NAME "CTL0080/-1[0]{Audio               }")
# (ACT Y)
設定を有効にするときに、# をはずします。

))
1 番目の論理デバイスの設定の終わりです。

# Logical device id CTL7002
#     Device supports vendor reserved register @ 0x38
#     Device supports vendor reserved register @ 0x39
#     Device supports vendor reserved register @ 0x3c
#     Device supports vendor reserved register @ 0x3d
#     Device supports vendor reserved register @ 0x3f
#
# Edit the entries below to uncomment out the configuration required.
# Note that only the first value of any range is given, this may be changed if required
# Don't forget to uncomment the activate (ACT Y) when happy

(CONFIGURE CTL0080/-1 (LD 1
#     ANSI string -->Game<--
2 番目の論理デバイスの設定です。

# Multiple choice time, choose one only !

#     Start dependent functions: priority preferred
#       Logical device decodes 16 bit IO address lines
#             Minimum IO base address 0x0200
#             Maximum IO base address 0x0200
#             IO base alignment 1 bytes
#             Number of IO addresses required: 8
# (IO 0 (SIZE 8) (BASE 0x0200))
I/O ポートアドレスは 0x200 を使います。

#       Start dependent functions: priority acceptable
#       Logical device decodes 16 bit IO address lines
#             Minimum IO base address 0x0200
#             Maximum IO base address 0x0208
#             IO base alignment 8 bytes
#             Number of IO addresses required: 8
# (IO 0 (SIZE 8) (BASE 0x0200))
代替えとなるリソースです。I/O ポートアドレスは 0x200 と 0x208 のどちらかが
使えます。

#     End dependent functions
 (NAME "CTL0080/-1[1]{Game                }")
# (ACT Y)
設定を有効にするときに、# をはずします。

))
2 番目の論理デバイスの設定の終わりです。


# End tag... Checksum 0x00 (OK)

# Card 2: (serial identifier 50 30 80 03 e5 02 02 aa 1a)
# Vendor Id FUJ0202, Serial Number 813695973, checksum 0x50.
#     Version 1.0, Vendor version 0.5
#     ANSI string -->FUJITSU Modem 33600 PNP/I2<--
#
# Logical device id FUJ0000
#     Device supports I/O range check register
#     Device supports vendor reserved register @ 0x38
#     Device supports vendor reserved register @ 0x3c
#     Device supports vendor reserved register @ 0x3d
#     Device supports vendor reserved register @ 0x3f
#
# Edit the entries below to uncomment out the configuration required.
# Note that only the first value of any range is given, this may be changed if required
# Don't forget to uncomment the activate (ACT Y) when happy
2 枚目の カードの説明です。

(CONFIGURE FUJ0202/813695973 (LD 0
一つ目の論理デバイスの設定です。

# Multiple choice time, choose one only !

#     Start dependent functions: priority acceptable
#       Logical device decodes 16 bit IO address lines
#             Minimum IO base address 0x02f8
#             Maximum IO base address 0x02f8
#             IO base alignment 8 bytes
#             Number of IO addresses required: 8
# (IO 0 (SIZE 8) (BASE 0x02f8) (CHECK))
I/O ポートアドレスは 0x2f8 を使います。

#       IRQ 3.
#             High true, edge sensitive interrupt (by default)
# (INT 0 (IRQ 3 (MODE +E)))
IRQ は 3 を使います。

#       Start dependent functions: priority acceptable
代替えとなるリソースです。
#       Logical device decodes 16 bit IO address lines
#             Minimum IO base address 0x03f8
#             Maximum IO base address 0x03f8
#             IO base alignment 8 bytes
#             Number of IO addresses required: 8
# (IO 0 (SIZE 8) (BASE 0x03f8) (CHECK))
I/O ポートアドレスは 0x3f8 を使います。

#       IRQ 4.
#             High true, edge sensitive interrupt (by default)
# (INT 0 (IRQ 4 (MODE +E)))
IRQ は 4 を使います。

中略

#     End dependent functions
 (NAME "FUJ0202/813695973[0]{FUJITSU Modem 33600 PNP/I2}")
# (ACT Y)
設定を有効にするときに、# をはずします。

))
# End tag... Checksum 0x00 (OK)
2 番目のカードの設定の終わりです。


# Card 3: (serial identifier 08 97 19 38 e6 98 50 6d 50)
# Vendor Id TCM5098, Serial Number 2535012582, checksum 0x08.
#     Version 1.0, Vendor version 1.0
#     ANSI string -->3Com 3C509B EtherLink III<--
#
# Logical device id TCM5098
#     Device supports I/O range check register
#     Device supports vendor reserved register @ 0x38
#     Device supports vendor reserved register @ 0x3c
#     Device supports vendor reserved register @ 0x3d
#     Device supports vendor reserved register @ 0x3f
#
# Edit the entries below to uncomment out the configuration required.
# Note that only the first value of any range is given, this may be changed if required
# Don't forget to uncomment the activate (ACT Y) when happy
3 枚目のカードの説明です。

(CONFIGURE TCM5098/2535012582 (LD 0
#     Compatible device id PNP80f7
#     IRQ 3, 5, 7, 9, 10, 11, 12 or 15.
#         High true, edge sensitive interrupt (by default)
# (INT 0 (IRQ 3 (MODE +E)))
IRQ は 3,5,7,9,19,11,12,15 の内 一つが使えます。

#     Logical device decodes 16 bit IO address lines
#         Minimum IO base address 0x0210
#         Maximum IO base address 0x03e0
#         IO base alignment 16 bytes
#         Number of IO addresses required: 16
# (IO 0 (SIZE 16) (BASE 0x0210) (CHECK))
I/O ポートアドレスは 16 バイト分を 0x210 から 16 バイト置きに 0x3e0 までの内、
一つが使えます。

 (NAME "TCM5098/2535012582[0]{3Com 3C509B EtherLink III}")
# (ACT Y)
設定を有効にするときに、# をはずします。

))
# End tag... Checksum 0x00 (OK)
3 枚目のカードの設定の終わりです。

# Returns all cards to the "Wait for Key" state
(WAITFORKEY)
すべてのカードの設定の終わりです。
</verb>

<sect1>isapnptools の設定<label id="isapnptools_conf">
<p>
isapnptools の設定は、pnpdump の標準出力をファイルにしたものを編集して、
isapnp の設定に使います。この設定ファイルを <em>isapnp.conf</em> と呼びます。
isapnp.conf の設定は かっこの中に書きます。

isapnp.conf には、ISAPnP カードが使用できるリソースが列記されていますので、
必要なリソースに対応した行の先頭にある<em>&num;</em>を取り去り、
リソースを有効にします。または、リソースの行を適切に編集します。
具体的には下記のようにします。尚、行番号を説明のために付加しています。
<verb>
 1: (CONFIGURE FUJ0202/813695973 (LD 0
 2:
 3: # Multiple choice time, choose one only !
 4:
 5: #     Start dependent functions: priority acceptable
 6: #       Logical device decodes 16 bit IO address lines
 7: #             Minimum IO base address 0x02f8
 8: #             Maximum IO base address 0x02f8
 9: #             IO base alignment 8 bytes
10: #             Number of IO addresses required: 8
2 行目から 10 行目までは、削除してかまいません。

11: # (IO 0 (SIZE 8) (BASE 0x02f8) (CHECK))
(IO 0 (SIZE 8) (BASE 0x02f8)) "#"を取り有効にします。(CHECK) をはずしました。

12: #       IRQ 3.
13: #             High true, edge sensitive interrupt (by default)
14: # (INT 0 (IRQ 3 (MODE +E)))
(INT 0 (IRQ 3 (MODE +E))) "#"を取り有効にします。

15:
16: #       Start dependent functions: priority acceptable

17: #     End dependent functions
18:  (NAME "FUJ0202/813695973[0]{FUJITSU Modem 33600 PNP/I2}")
19: # (ACT Y)
(ACT Y) "#"を取り有効にします。これを忘れると、設定が反映されません。

20: ))

21: (CONFIGURE TCM5098/2535012582 (LD 0
22: #     Compatible device id PNP80f7
23: #     IRQ 3, 5, 7, 9, 10, 11, 12 or 15.
IRQ は 3,5,7,9,10,11,12,15のどれかを選択します。

24: #         High true, edge sensitive interrupt (by default)
25: # (INT 0 (IRQ 3 (MODE +E)))
(INT 0 (IRQ 10 (MODE +E)))  "#"を取り有効にします。IRQ は 10 にしました。

26: #     Logical device decodes 16 bit IO address lines
27: #         Minimum IO base address 0x0210
28: #         Maximum IO base address 0x03e0
29: #         IO base alignment 16 bytes
30: #         Number of IO addresses required: 16
I/O ポートアドレスは 0x210 から 16 バイト置きに 0x3e0 の範囲から選択します。

31: # (IO 0 (SIZE 16) (BASE 0x0210) (CHECK))
(IO 0 (SIZE 16) (BASE 0x0300) (CHECK)) "#"を取り有効にします。
                                       I/O ポートアドレスは 0x300 にしました。

32:  (NAME "TCM5098/2535012582[0]{3Com 3C509B EtherLink III}")
33: # (ACT Y)
(ACT Y) "#"を取り有効にします。これを忘れると、設定が反映されません。

34: ))
25: (WAITFORKEY)
</verb>
これを整理すると、下記のようになります。
<verb>
(CONFIGURE FUJ0202/813695973 (LD 0
 (IO 0 (SIZE 8) (BASE 0x02f8) )
 (INT 0 (IRQ 3 (MODE +E)))
 (NAME "FUJ0202/813695973[0]{FUJITSU Modem 33600 PNP/I2}")
 (ACT Y)
))

(CONFIGURE TCM5098/2535012582 (LD 0
 (INT 0 (IRQ 10 (MODE +E)))
 (IO 0 (SIZE 16) (BASE 0x0300) (CHECK) )
 (NAME "TCM5098/2535012582[0]{3Com 3C509B EtherLink III}")
 (ACT Y)
))
(WAITFORKEY)
</verb>

<sect1>isapnptools とリソースの衝突
<p>
isapnptolls はリソースの衝突に敏感です。
<ref id="isapnptools_conf" name="isapnptools の設定">の中で、33k アナログ
モデムの設定で、<em>(CHECK)</em> をはずした行があります(下記に転記します)。
<verb>
(IO 0 (SIZE 8) (BASE 0x02f8) )
</verb>
この I/O ポートアドレス 0x2f8 はマザーボード上の標準シリアルポートです。
この 33k アナログモデムでは、標準のシリアルポートと同じ I/O ポートアドレス
を使います。BIOS でマザーボード上の標準シリアルポートは無効にしていますが、
kernel によって、自動的にリソースが登録されてしまいます。そのため、
リソースが衝突しているように、見えます。isapnp は <em>(CHECK)</em> が
指定してあると、リソースの衝突を発見したとき、その時点で、中断(abort)して
しまいますが、<em>(CHECK)</em> を外すと、エラーは報告しますが、
リソースの設定も実行し、処理も続行します。

isapnp の設定(pnpdump の出力)でリソースの衝突に関係する部分について、
説明します。
<descrip>
<tag>&num; Compiler flags: </tag>
isapnptools コンパイル時に &dquot;--enable-onreserr&dquot; を付けると、
<em>-DABORT_ONRESERR</em> が出力されます。このオプションフラグを付けて、
isapnptools をコンパイルすると、isapnp コマンドは設定とリソースが衝突した
場合、処理を中断するようになります。

<tag>(CONFLICT (IO FATAL)(IRQ FATAL)(DMA FATAL)(MEM FATAL))</tag>
リソースが衝突したときの動作を指定します。<em>FATAL</em>の場合、
致命的(fatal)なエラーとして、isapnp コマンドは処理を中断します。
<em>WARNING</em>の 場合、警告(warning)を出力し、処理を続行します。

<tag>(IO x (SIZE y) (BASE z) (CHECK))</tag>
I/O ポートアドレスの設定に <em>(CHECK)</em>が指定されていた場合、
isapnp コマンドはリソースの衝突を検査(check)します。衝突が発見された場合、
isapnp コマンドは処理を中断します。
</descrip>
<p>
また、isapnp コマンドに、使用禁止のリソースを知らせるファイル
<em>/etc/isapnp.gone</em> があります。<em>/etc/isapnp.gone</em> の書式を
下記に示します。
<descrip>
<tag>IO ベースアドレス , 使用する I/O ポートアドレスの大きさ</tag>
使用禁止にする I/O ポートアドレスのベースアドレスとその大きさを指定します。
大きさを省略すると、大きさは 8 バイトになります。

<tag>IRQ 番号</tag>
使用禁止にする IRQ 番号を指定します。

<tag>DMA 番号</tag>
使用禁止にする DMA 番号を指定します。

<tag>MEM ベースアドレス , 使用するメモリの大きさ</tag>
使用禁止にするメモリのベースアドレスと大きさを指定します。
</descrip>

<em>/etc/isapnp.gone</em>の例を下記に示します。
<verb>
IO 0x3f8,8
IRQ 4
DMA 1
DMA 5
IO 0x378,2
IRQ 7
</verb>
<p>
上記のように、isapnp コマンドはリソースの衝突に敏感です。これは動作としては、
正しいのですが、使い勝手が悪くなります。その理由は下記の通りです。

ISAPnP を一度設定すると、設定したリソースは当然、使用中になります。
二つある I/O ポートアドレスの内、一つ目は変更せず、二つ目の I/O ポートアドレス
を変更しようとした場合、一つ目のI/O ポートアドレスが使用中のリソースと衝突
してしまいます。
ISAPnP カードの設定は、電源投入時にのみ、初期化されます。Linux や Windows 系
の OS の再起動では、設定は初期化されません。

これを回避するには、isapnp コマンドの設定(pnpdump の出力)を下記のようにします。
<verb>
(CONFLICT (IO FATAL)(IRQ FATAL)(DMA FATAL)(MEM FATAL))を
(CONFLICT (IO WARNING)(IRQ FATAL)(DMA FATAL)(MEM FATAL))と
FATAL を WARNING に変更する。

(IO x (SIZE y) (BASE z) (CHECK))を
(IO x (SIZE y) (BASE z) )と、(CHECK)を削除する。
</verb>
しかし isapnptools のコンパイル時に <em>--enable-onreserr</em> を指定した場合、
isapnp コマンドの設定(pnpdump の出力)で変更することはできません。
<em>--enable-onreserr</em>を付けずに、isapnptoolsを再コンパイルする必要が
あります。

<sect1>isapnptools による設定例<label id="isapnptool_setup">
<p>
下記に設定例を示します。この設定を<em>/etc/isapnp.conf</em>というファイル名
で作成します。
<verb>
(READPORT 0x0273)
(ISOLATE PRESERVE)
(IDENTIFY *)
(VERBOSITY 2)
(CONFLICT (IO WARNING)(IRQ WARNING)(DMA WARNING)(MEM WARNING))

(CONFIGURE CTL0080/-1 (LD 0
 (INT 0 (IRQ 5 (MODE +E)))
 (DMA 0 (CHANNEL 1))
 (DMA 1 (CHANNEL 5))
 (IO 0 (SIZE 16) (BASE 0x0220))
 (IO 1 (SIZE 2) (BASE 0x0330))
 (IO 2 (SIZE 4) (BASE 0x0388))
 (NAME "CTL0080/-1[0]{Audio               }")
 (ACT Y)
))

(CONFIGURE CTL0080/-1 (LD 1
# (IO 0 (SIZE 8) (BASE 0x0200))
 (NAME "CTL0080/-1[1]{Game                }")
# (ACT Y)
))

(CONFIGURE FUJ0202/813695973 (LD 0
 (IO 0 (SIZE 8) (BASE 0x02f8) )
 (INT 0 (IRQ 3 (MODE +E)))
 (NAME "FUJ0202/813695973[0]{FUJITSU Modem 33600 PNP/I2}")
 (ACT Y)
))

(CONFIGURE TCM5098/2535012582 (LD 0
 (INT 0 (IRQ 10 (MODE +E)))
 (IO 0 (SIZE 16) (BASE 0x0300) )
 (NAME "TCM5098/2535012582[0]{3Com 3C509B EtherLink III}")
 (ACT Y)
))

(WAITFORKEY)
</verb>
何故、33k アナログモデムの設定が kernel 2.4 の設定例には無くて、
isapnptoolsの設定にはあるのかといいますと、kernel 2.4 の標準シリアルポート
デバイスドライバは、ISAPnP に対応しており自動設定で済みますが、
kernel 2.2 の標準シリアルポートデバイスドライバは、ISAPnP に対応していない
ので、設定する必要があるためです。

<sect1>isapnptools 起動時の設定
<p>
現在、ご使用の Linux に isapnptools がインストール済みであれば、
起動時の設定もされているはずです。
ディストリビューションによっても違いますが、ここでは、RedHat 系の
<em>/etc/rc.d/rc.sysinit</em>スクリプトを使う場合を説明します。
/etc/rc.d/rc.sysinit の /proc のマウント直後に下記のように追加します。
<verb>
mount -t proc /proc /proc
if [ -x /usr/local/sbin/isapnp -a -f /etc/isapnp.conf ]; then
      /usr/local/sbin/isapnp /etc/isapnp.conf
fi
</verb>

<sect>ALSA の ISAPnP サポート
<p>
サウンドドライバ ALSA は独自に ISAPnP のサウンドカードをサポートしています。
ALSA は <url url="http://www.alsa-project.org/" name="Advanced Linux Sound
Architecture">から入手できます。
本書ではALSA のインストールについては説明しません。

ALSA の ISAPnP を有効にするには、alsa-driver-*のコンパイル時に、下記のよう
にオプションを指定します。ALSAのバージョンによって、少し違うかもしれません。
<verb>
$./configure --help
オプションの確認

$./configure --with-isapnp=yes
</verb>

<sect1>ALSA の設定
<p>
ALSA の設定は、<em>alsaconf</em> を使用すると、簡単に設定できます。
alsaconf を使用しない場合、ALSA driver 附属の文書 README を参考に、
<em>/etc/modules.conf</em> に設定を記載します。
ISAPnP に固有の設定はサウンドカード毎に異なりますが、
SoundBlaster16 ISAPnP では、<em>snd_isapnp=1</em> がデフォルトで有効に
なっています。
下記に設定例を示します。
<verb>
$cat /etc/modules.conf
alias eth0 3c509
# --- BEGIN: Generated by ALSACONF, do not edit. ---
# --- ALSACONF verion 0.4.3b ---
alias char-major-116 snd
alias snd-card-0 snd-card-sb16
alias char-major-14 soundcore
alias sound-slot-0 snd-card-0
alias sound-service-0-0 snd-mixer-oss
alias sound-service-0-1 snd-seq-oss
alias sound-service-0-3 snd-pcm-oss
alias sound-service-0-8 snd-seq-oss
alias sound-service-0-12 snd-pcm-oss
options snd snd_major=116 snd_cards_limit=1 snd_device_mode=0666 snd_device_gid=0 snd_device_uid=0
options snd-card-sb16 snd_isapnp=1 snd_index=0 snd_id=CARD_0 snd_port=0x220 snd_mpu_port=0x330 snd_irq=5 snd_dma8=1 snd_dma8_size=64 snd_dma16=5 snd_dma16_size=128 snd_mic_agc=0
# --- END: Generated by ALSACONF, do not edit. ---
</verb>

<sect>参考文献<label id="reference">
<p>
<itemize>
<item>ISAPnP 規格 
<url url="http://www.microsoft.com/hwdev/respec/PNPSPECS.HTM" 
name="Plug and Play ISA Specification Version 1.0a May 5,1994">
<em>pnpisa.zip</em> RTFの文書が入手できます。

<item>JFの文書 <url url="http://www.linux.or.jp/JF/JFdocs/Plug-and-Play-HOWTO.html"
name="Plug-and-Play-HOWTO">。

<item><url url="http://www.microsoft.com/hwdev/pc98.htm" name="PC98 System
Design Guide">

<item><url url="http://www.microsoft.com/hwdev/pc99.htm" name="PC99 System Design Guide">

<item>kernel 2.4 ソース linux/drivers/pnp

<item>isapnptools ソース isapnptools-version/doc/
</itemize>

<!--
お名前はメールのご署名より、転記させていただきました。
問題がございましたら、ご指摘ください。
 --> 
<sect>謝辞
<p>
本文書の作成にあたり、下記の方々に大変お世話になりました。
<verb>
瀬藤 誠 さん    <setoh@cwa.bai.ne.jp>
千旦裕司 さん   <ysenda@pop01.odn.ne.jp>
武井伸光 さん   <takei@webmasters.gr.jp>
佐野武俊 さん   <kgh12351@nifty.ne.jp>
</verb>

 <appendix>
<sect>ISA Bus について
<p>
本文書のこの項以降は技術文書です。ISAPnP について、より深く、理解したい人向けに
書いてありますが、ハードウェア、C 言語、kernel の基礎知識があることを
前提にしています。

<sect1>ISA Bus の歴史と特徴
<p>
ISA Bus は 1983 年に IBM 社が発売した、8088 CPUを搭載した PC/XT の I/O チャ
ネルがもとになっています。この I/O チャネルは 62 ピンのコネクタを使用しています。
1984 年 に IBM社 は 80286 CPU を搭載した PC/AT を発売します。これに、伴っ
て I/O チャネルも拡張され、PC/XT のものに 36 ピンのコネクタを追加しました。
PC/AT は多数の互換機が作成され、その互換機メーカたちにより、PC/AT の
I/O チャネルは ISA(Industry Standard Architecture) Busと呼ばれるように
なりました。多くの PC/AT 互換機には 6 本の 62 + 36 ピンのスロットと、
2 本の 62 ピンのスロットの合計、8 本の ISA Bus スロットがありました。

ISA Bus は PC/XT 由来の 62 ピンのスロットには、アドレスバス 20bit、
データバス 8bit、割り込み 6 本、DMA 3 組があります。
PC/AT で追加された 36 ピンのスロットには、アドレスバス 上位 7bit、データ
バス 上位 8bit、割り込み 5 本、DMA 4 組があります(80286 CPU のアドレス
は 24bit なので、4bit の追加で足りるはずですが、何故か 7bit 増えています)。

これら以外に、CPU との制御線、クロック、リセット、電源があります。
Bus クロックは CPU のクロックに依存し、6MHz,8MHz,10MHz 等がありました。
ISA Bus の信号線は、80286 CPU, DMA コントローラ 8237A、割り込み
コントローラ 8259A に接続されていて、これらのデバイス固有のタイミングで
制御されています。ISA Bus は 80286 CPU 専用のバスだったといってもよいでしょう。
<p>
x86 系の CPU は I/O アドレス空間をメモリ空間とは別に持っています。
I/O アドレス空間は 16bit 長ですが、80286 時代の PC/AT 用拡張カードの
中には下位 12bit しか見ていないカードや、1 個の I/O アドレスしか
使用していないのに、8 個の I/O アドレスを浪費するカードがありました。

PC/AT とその互換機のマザーボード上の I/O 装置には、キーボートコントローラ、
タイマ、リアルタイムクロック(RTC 時計)しか搭載されていません。
ビデオ、シリアルポート、プリンタポート、ハードディスク・フロッピーディスク
コントローラ、拡張メモリ等は ISA Bus にアタプタ(拡張カード)を挿して、
使用しました。これではスロットが足らないため、シリアル、パラレル、ハード
ディスク・フロッピーディスクコントローラカードを 1 枚にまとめた
マルチ I/O カードや、サウンド、SCSI、CDROM コントローラ、ジョイ
スティック・マウス コントローラを 1 枚にまとめたお楽しみカードというような
カードが登場しました。
<p>
80386 CPU が出現したとき、ISA Bus は 80386 CPU に対応できませんでした。
また、高速なメモリは ISA Bus に置くと誤動作するので、CPU のすぐそばに
置くようになりました。その後、80486 や Pentium が出現し EISA や、
高速ビデオカードに対応した VL Bus が採用されたこともありました。
そして、高速で、CPU に依存しない PCI Bus 規格が登場し、PC/AT 互換機の
標準 Bus は ISA Bus から PCI Bus に移りました。

新しい Bus が PC/AT 互換機に採用される度に ISA Bus は消えて無くなるだろう
といわれてきました。しかし、今のところ ISA Bus は生き残っています。
その理由として、下記に幾つか挙げておきます。
<itemize>
<item>ISA Bus と周辺機器のインターフェースが簡単な回路で実現できること。

<item>自作のカードや、安価なカードが多数存在したこと。

<item>ISA PnP により、拡張カードの取り扱いが楽になったこと。

<item>PCI が ISA Bus リソースと重ならないように実装されたこと。

<item>ISA Busで十分な性能が得られる用途があること。
</itemize>

しかし、Microsoft 社と Intel 社の提唱する PC のハードウェア標準規格、
<ref id="reference" name="PC 98 Hardware Design Guide">では、
ISA Bus の搭載は<em>不可</em>となってしまいました。
今後、自作する人に対し PCI Bus インターフェース用 LSI が安価で提供され、
PCI Bus が ISA Bus のように簡単に使えるようになったとき、ISA Bus は無くなる
だろうと思います。

<sect1>現在の ISA Bus
<p>
2000 年現在の ISA Bus と CPU Pentium III とは下図 1 のように接続されています。
<verb>
                          DRAM   AGP                   USB    Super I/O chip
                           |      |                     |              |
Pentium III -- GTL Bus -- North Bridge -- PCI Bus -- South Bridge -- ISA Bus
    |                                                   |              |
    +------- IO APIC (interrupt) -----------------------+--------------+

                    図 1 Pentium III と 440BX Chip セット
</verb>
<label id="fig_1">図 1 を説明します。
<descrip>
<tag>Pentium III</tag>
現在の最新 CPU です。

<tag>GTL Bus</tag>
最新の CPU (Pentium II や Celeron等を含む)の Bus の名称です。Bus クロック
は 100MHz です。

<tag>North Bridge</tag>
CPU と DRAM,AGP,PCI Bus インターフェース機能が受け持ちます。
型番は 82443BX です。

<tag>South Bridge</tag>
昔の PC/AT のマザーボードに搭載されていた機能、割り込み、DMA,RTC 等、
PCI Bus 接続の ATA(IDE)インターフェースや USB と PCI-ISA Bus Bridge 機能
を持ちます。型番は 82371EB です。

<tag>Super I/O chip</tag>
フロッピディスク、パラレル・シリアルポート、キーボード、マウス
インターフェースを持ちます。 ISA Bus に接続されています。各社から提供され
ています。

<tag>IO APIC</tag>
新しい、割り込みコントローラです。PC/AT の割り込みを拡張し、16 個以上の
割り込みが使え、PCI Bus とISA Bus の割り込みを別にできます。
型番は 82093AA です。
</descrip>

もともと 8088/80286 CPU のそばにあった ISA Bus は、何段ものインタフェースを
経由して、Pentium III と接続されています。
ISA Bus のタイミングは クロック 8MHz の、80286 時代のタイミングとほぼ、
同じです。

<sect1>ISA Bus と PC/AT の問題点<label id="isa_problem">
<p>
ISA Bus の問題点は、PC/AT 互換機の問題と言い換えることができます。

<descrip>
<tag>リセットの問題</tag>
x86 系の CPU で 8086(8088)と同じ動作をリアルモードといいます。
x86 系の CPU は 最新の Pentium III も含めて、CPU を リセットすると、
このリアルモードになります。プロテクトモードは様々な保護機能や、仮想メモリ
機能を持つモードのことです。
80286 CPU は機械語命令で、リアルモードから、プロテクトモードに移行できます
が、プロテクトモードから、リアルモードに戻る機械語命令を持っていませんでし
た。80286 CPU 時代の幾つかのプログラムはリアルモードで無いと動作しないもの
があるため、リアルモードに戻るため、CPU をリセットするハードウェア
を PC/AT 互換機に追加しました。キーボードコントローラの出力ポート
(I/O アドレス 0x64) の bit 0 に 0 を書き込むと、リセットできるので、
キーボードリセットと呼ばれています。
この、キーボードリセットでは ISA Bus はリセットされません。
ISA Bus がリセットされるのは、電源投入時だけです。

<tag>I/O アドレスの問題</tag>
x86 系の CPU は 16 bit の I/O アドレスを持っています。PC/AT では、アドレ
ス 0x0000 から 0x00FF までを、マザーボード上で使用し、
拡張カードは 0x0100 から 0x03FF までを使用します(合わせて 10bit 1024バイト
になります)。
ところが、どちらも I/O アドレス 16bit を完全デコードせず、手を抜いています。
マザーボードでは、I/O アドレス の bit15 から 10 を無視し、
しかも、bit9 と bit8 がともに 0 の時、選択されてしまいます。
拡張カードは I/O アドレスの bit15 から 10 を無視しています。
そのため、I/O アドレス空間は イメージ(ゴースト)だらけになっています。
つまり、マザーボードでは 0x0000,0x1000,0x2000... は全て同じ I/O が反応し、
拡張カードでは 0x0100,0x0400,0x0800... は全て同じ I/O が反応してしまいま
す。
さらに、1 個の I/O アドレスしか必要が無くとも、マザーボード上では、
最低単位でも 16 個、多くの拡張カードでは 8 個の I/O アドレスを浪費しています。
この手抜きは デコーダ回路を簡素化するために行われましたが、
I/O アドレスに連続した広い領域を取ることができません。

<tag>DMA の問題</tag>
PC/AT の DMA コントローラは (大昔の) 8080 用の 8237A を使用しています。
8237A はアドレス空間 16bit 、データ幅 8bit なので、64kbyte までしか転送でき
ません。PC/AT では、かなり複雑な方法で 8237A を 2 個使用し、
データ幅 16bit の転送ができます。また 8bit のレジスタを使用し、
アドレス空間 24bit に拡大されています。ただし、一度に転送できるデータ長は、
16bit までに、制限されています。
さらに、DMA の転送速度は現在の CPU のプログラム転送速度に劣ります。

<tag>割り込みの問題</tag>
x86 CPU 自体は 2 本の割り込み線があります。NMI と INT です。
NMI は 割り込み禁止にすることができないもので、主に致命的なエラー(メモリの
異常や、電源が落ちた等)の時に使用します。
INT は 割り込み禁止にできることと、割り込み発生時 8bit の割り込みベクタを
読み込むことで、256 個の割り込みに対応できます。
PC/AT では 割り込みコントローラ 8259A を 2 個使用し、15 個の割り込みが
使用できます。8259A は 8本 の IRQ 端子を持っていて、IRQ 端子毎に別々の
割り込みベクタを設定(プログラム)できます。8259A を 2 個使うためには、
一方の IRQ 端子を他方の 8259Aの端子のために使うため、16 個ではなく 1 つ足り
ない、15 個の割り込みになります。
これらの割り込みをハードウェア割り込みといいます。
<p>
また、x86 系 CPU にはソフトウェア割り込み機械語命令(ニーモニックは INT です)が
ありますが、ハードウェア割り込みと同じように動作します。
8259A が 割り込みベクタ 8 を出力し、CPU の INT 端子を有効にしたことと、
ソフトウェア割り込み機械語命令 INT 8 の動作は全く同じで、CPU には区別が
付きません。8259A のレジスタを調べたり、IRQ 端子を有効にした、ハードウェア
に問い合わせて、ハードウェアかソフトウェアの割り込みを区別します。
これは、欠点とも利点とも考えられます。 欠点として、ハードウェアかソフトウェ
アか区別するプログラムが必要になることです。利点としては、ハードウェアが
動作していない(bugっていたり、まだ完成していない)ときに、ソフトウェアで
試験ができることです。

x86 系 CPU はベクタ番号から計算した、メモリ内容(勿論あらかじめ、値を設定
しておきます)をもとにしたアドレスへサブルーチンコールします。

PC/AT 発売当初は割り込みが 15 個もあれば、十分と考えられていましたが、
現在では、不足しています。

<tag>Bus 速度の問題</tag>
ISA Bus の転送速度はピークでも、8Mbyte/sec 以下です。8bit 幅の I/O 命令で
ISA Bus をアクセスした場合 1Mbyte/sec を下回ります。 

<tag>分離の問題</tag>
ISA Bus には、すべてのスロットに信号線が共通に配線されています。そのため、
ISA カード毎にアクセスする方法がありません。
同じ Bus 接続でも、SCSI は装置毎に、ID 番号を人手で重複しないように設定し、
その ID 番号を使い、装置を区別しアクセスしています。
PCI では装置(スロット)と PCI Bus コントローラを 1 対 1 に接続している
制御線があります。PCI では、この制御線を有効にすると、対応したひとつだけの
装置(スロット)が反応し、同じ Bus 上にある他の装置(スロット)は反応しません。

</descrip>

<sect1>I/O アドレス空間について
<p>
ISA Bus は I/O アドレス空間を使用し、ハードウェアを制御します。
I/O アドレス空間へのアクセスに関係する問題を下記に示します。

<sect2>I/O アドレス空間の問題
<p>
x86 系 CPU は I/O アドレス空間をメモリアドレス空間と別に持っていますが、
I/O アドレス空間を持つ CPU は少数派なのです。何故、少数派かといえば、I/O アドレ
ス空間を別に持つ、必要は必ずしも無かったからです。
I/O のハードウェアがメモリと同じように、アクセスして、動作するように設計されてい
れば、問題は無いからです。I/O アドレス空間をアクセスする機械語命令や、
CPU の信号線やアクセスタイミングに I/O アドレス空間専用のものを用意する必要も無い
ので、I/O アドレス空間を持たない方が有利でした。
しかし、キャシュメモリの搭載、命令のスケジューラ、保護機能、CPU の高速化等により、
I/O アドレス空間を持つ方が有利となってきました。
その理由を下記に示します。
<descrip>
<tag>キャシュメモリの搭載</tag>
メモリは CPU の管理下にあり、メモリ内容を変更するのは、原則として CPU だけです
が、ハードウェアは独自にメモリ内容を変更します。
メモリアドレス空間にハードウェアを割り当てる場合、その領域をキャシュ不可にする
必要があります。x86 系の MTRR はメモリアドレス空間にハードウェアを割り当てるとき
に使用されます。

<tag>命令のスケジュール</tag>
現在の CPU は複数機械語命令を同時に取り込み、並列に実行できるようになっていま
す。そのため、命令の実行順序や、メモリアドレス空間へのアクセス順序を変更すること
があります。ハードウェアに対し、実行順序やアクセス順序が変更された場合、誤動作す
る可能性があります。

<tag>保護機能</tag>
ハードウェアが割り当てられたアドレス空間では、メモリアドレス空間とは、異なる保護
機能が必要です。メモリアドレス空間では、読み出し不可、書き込み専用は意味のない、
保護ですが、ハードウェアでは有効な保護になります。また、読み出し不可、書き込み不
可、しかしアクセスは可能という保護もハードウェアではあり得ます。
さらに、これらの保護機能はビット単位で行う必要があります。

<tag>CPU の高速化</tag>
CPU が高速化すれば、メモリへも高速にアクセス可能で、アクセスタイムは同一である方
が、有利でしょう。しかし、ハードウェアのアクセス速度は様々で、超低速のものもあり
ます。ハードウェアを同じ空間に割り当てるよりも、別の空間に割り当てた方が、
CPU Bus や メモリ Bus の設計が容易になります。
</descrip>

<sect2>ハードウェアへのアクセス
<p>
ハードウェアへのアクセスに関連する話題を下記に示します。
<descrip>
<tag>ハードウェアへのアクセスの特殊性</tag>
ハードウェアへのアクセスはメモリのアクセスとは、同じではありません。
下記にいつかの機械語命令のコードの例を示し、I/O とメモリとの違いを説明します。
<verb>
コード 1
load io     # io アドレスのデータを読み込む
load io
store io
store io    # io アドレスへデータを書き込む

コード 2-1
load io
ioにアクセスしない処理

コード 2-2
ioにアクセスしない処理
load io

コード 3-1
load32 io   # 32bit 単位でアクセス
and 0xff    # 8bit 分を取り出す。

コード 3-2
load8 io    # 8bit 単位でアクセス
</verb>
コード 1 がメモリへのアクセスであれば、読み込んだデータを書き戻すだけですから、
無意味なコードでしょう。CPU によっては、機械語命令を実行しないかもしれません。
しかし、コード 1 がハードウェアへのアクセスの場合、この通りに、2 回読んで、2 回
書くように(&dquot;読 読 書 書&dquot; と)実行する必要があります。
&dquot;読 書 読 書&dquot; や、&dquot;読 書 書 読&dquot; で
は動作しないように、設計されたハードウェアかもしれません。
<p>
コード 2 は最初にハードウェアにアクセスするか、後でハードウェアにアクセスするか
の違いですが、時間が経過すると、ハードウェアは別のデータを返すかもしれません。
<p>
コード 3 はアクセスするときのデータバス幅の違いです。読み込んだデータはともに
8bit の同じデータでしょう。しかし、32bit 幅のアクセスでは、24bit 分よけいな
アクセスをしています。そのため、ハードウェアの動作は全く異なるものになるでしょう。
<p>
また、同じ I/O アドレスへのアクセスでも、読み込みと書き込みの動作が異なることも、
ありますし、アクセスさえあれば、読み込み書き込みを問わないこともあります。

<tag>I/O アクセスプログラムの問題</tag>
x86 系 CPU が I/O アドレス空間にアクセスする機械語命令を I/O 命令と
呼んでいます。I/O 命令のアドレッシングモードは、ふたつしかありません。
絶対アドレスと DX レジスタ間接です。
絶対アドレスアドレッシングモードは、I/O アドレスを直に指定するので、
機械語命令が ROM に書き込まれた場合や、プロテクトモードでは、
I/O アドレスを書き換えることはできません。また、アドレスは 0 から 255 の範囲に
限られます。
DX レジスタ間接アドレッシングモードは、DX レジスタに I/O アドレスを、
渡せば良いので、I/O アドレスを書き換えることができます。
ところが、x86 系 CPU は CPU レジスタの役割が固定されている上、レジスタが
少ないため、DX レジスタを他の用途に使用していることや、
プログラマが 8080 CPU 機械語に慣れていることから、
DX レジスタ間接アドレッシングモードはあまり使われませんでした。
Busが ISAPnP になっても、絶対アドレッシングモードを使用しているデバイス
ドライバがあり、リソースが衝突して、せっかくの PnP 機能が生かせないものが
あります(そう、いまでも) 。ただし、IBM PC/AT互換機では I/O アドレス 0 から 255
は システム I/O に使用しますので、ISAPnP カードには割り当てることはありません。

<tag>バイトオーダの問題</tag>
エンディアンの問題とも、いいます。16bit 以上の整数値が 8bit 単位でどのように
メモリに格納されるかということです。x86 系の CPU では、最下位から、格納され、
その他の CPU (例えば 68k や Alpha)では、最上位から格納されます。
例えば、0x123456AB は x86 系では、&dquot;AB 56 34 12&dquot; の順に、 68k
では&dquot;12 34 56 AB&dquot; の
順に格納されます。それぞれに、利点があって、x86 系では、ビット数の拡張に
向いていて、68k では、可読性に富んでいます。
ビット数の拡張とは、現在 16bit のデータを格納するとき、将来を見越して、64bit の
領域を用意し、xx yy 00 00 ... のように、未使用領域を 0 にしておくと、
32bit でも、64bit でも、同じ先頭アドレスでアクセスできます。
<p>
ISAPnP (実は PCI も) コンフィグレーションレジスタは x86 系のバイトオーダに
なっています。
また、同種の問題として、最上位ビットの位置の問題があります。x86 系では、
32bit の場合、 bit31 が最上位ビットですが、ある CPU では bit0 が
最上位ビットになっています。
</descrip>

<sect>ISAPnP の仕組み
<p>
ISAPnP の仕組みについて説明します。より詳しい ISAPnP の仕組みについては、
<ref id="reference" name="参考文献">を参照してください。

<sect1>ISAPnP カードの用語とハードウェア
<p>
本書で使用している ISAPnP カードの用語と、ISAPnP 固有のハードウェアについて、
説明します。

<sect2>論理デバイス
<p>
ISAPnP カードは一つのカードに複数の機能を搭載しているものがあります。
この複数の機能を論理デバイスと呼びます。
例えば、サウンドカードは、サウンド機能と、ジョイスティック機能の二つの
論理デバイスを持ちます。
単機能のカードの場合、論理デバイスが一つあるということになります。
論理デバイスは 256 個まで持てます。
一つの論理デバイスは、最大で、 8 つの I/O アドレス空間、4 つのメモリアドレス
空間、2 つの割り込み、2 つの DMA チャンネルを持つことができます。

<sect2>コンフィグレーションレジスタ
<p>
OS と ISAPnP カードとは、ISAPnP カードの持つコンフィグレーションレジスタを
介して、8bit 単位で情報のやり取りをします。
コンフィグレーションレジスタは 0 から 0xff まで、アドレス番号が割り当てられ
ています。アドレス番号 0 から 0x2f までは ISAPnP カードに 一つだけあり、
カードレベルレジスタと呼びます。
アドレス番号 0x3f から 0xff までは、ISAPnP カード上の論理デバイスの数だけ
何組かあり、デバイスレベルレジスタと呼びます。
ひとつのアドレス番号に対し、複数のデータを持ったものがあります。その意味では、
アドレス番号というよりもコマンド番号と考えた方が解りやすいかもしれません。

<sect2>分離
<p>
複数枚ある ISAPnP カードから、1 枚を特定することです。

<sect2>CSN
<p>
CSN(Card Select Number) は ISAPnP カードを特定するための 1byte の数値です。
OS は CSN を ユニークに管理する必要があります。
無事 ISAPnP カードの分離に成功すると、OS は ISAPnP カードに CSN を割り当て
ます。
OS が CSN を出力すると、ISAPnP カードは自分に割り当てられた CSN の時だけ
反応します。CSN が 0 の場合、特別に全ての ISAPnP カードが反応します。
CSN 0 はISAPnP カードを全てリセットするときや、分離の時に使います。

<sect2>ISAPnP カードのステート
<p>
ISAPnP カードは幾つかのステート(状態 state)があります。
<descrip>
<tag>Wait</tag> 電源投入直後のOS による初期化を待っているか、
コンフィグレーション終了後の正常な動作中の状態です。

<tag>Sleep</tag> OS からの &dquot;Wake&dquot; コマンドを待っている状態です。
Wake コマンドを受け取ると、Wait ステートに移行します。 

<tag>Isolation</tag> 分離シーケンス実行中の状態です。分離に失敗すると、Sleep ス
テートに移行します。成功すると、CSN コマンドを待ち、CSN コマンドを受け取ると、
Config ステートに移行します。

<tag>Config</tag> コンフィグレーション実行中の状態です。
</descrip>
OS がコマンドを出力し、ステートを移行させます。

<sect2>コンフィグレーション時のデータバスドライブ方法
<p>
ISAPnP カードの分離が済むまでは、複数のカードが反応してしまいます。
そこで、ISAPnP カードのコンフィグレーションレジスタからの読み出しの場合、
ISAPnP カードは データバスに 論理値 0(Low)のビットのみを駆動し、
論理値 1(High) のビットは駆動せず、ハイインピーダンスにします。
ハイインピーダンスにするとは、電気的に切り離したのと同じ状態にすることです。
ISAPnP 対応のマザーボードのデータバスはハイインピーダンスの場合、
論理値 1(High)になるように、細工(電気抵抗でプルアップ)されていますので、
論理値 1(High)のビットも正しく読み出せます。
<p>
もし、データバスの同じビットに対し、あるカードが論理値 1 を駆動し、別の
カードが論理値 0 を駆動した場合、論理値 1 を出したカードはビットが 0 に
ならないようにがんばり、論理値 0 を出したカードはビットを 0 にしようと
がんばってしまいます。その結果、両者のカードの間に大電流が流れ、
両方のカードが壊れてしまいます。
論理値 1(High) を駆動せず、ハイインピーダンスにすれば、
プルアップしている電気抵抗によって電流が制限されていますので、
カードは壊れません。
また、論理値 0 同士の場合は、どちらかのカードも、論理値 0 になれば、
それ以上電流は流れないので、両カードは壊れません。 

<sect2>ISAPnP コンフィグレーション時の アクセス方法
<p>
ISAPnP はコンフィグレーションのとき、三つの I/O アドレスを使います。
<descrip>
<tag>アドレスポート 0x279</tag>
アドレスポートは プリンタポートの読み取り専用のステイタスポートと
同じ I/O アドレスを書き込み用に変更して、使用しています。
OS はアドレスポートに ISAPnP のコンフィグレーションレジスタのアドレス番号を
書き込みます。

<tag>ライトデータポート 0xa79</tag>
ライト(write)データポートはプリンタポートの読み取り専用のステイタスポートの
イメージと同じ I/O アドレスを使用します。ISAPnP 対応マザーボードでは、
I/O アドレスのフルデコードが義務づけられているので、実際にはイメージでは
ありません。
OS はライトデータポートへ、コンフィグレーションレジスタに設定したいデータを
書き込みます。

<tag>リードデータポート 0x203 + 4*n から 0x3ffまでの内 一つ</tag>
リードデータポートの I/O アドレスは 0x203,0x207,0x20b,0x20f...0x3ffの中から、
未使用の I/O アドレスを一つ使用します。OS はリードデータポートから、コンフィグ
レーションレジスタのデータを読み出します。実際の I/O アドレスは、分離中に
調べます。
</descrip>

ISAPnP 対応ハードウェアのコンフィグレーションレジスタのアクセス方法は
下記の通りです。
<descrip>
<tag>書き込み</tag>
アドレスポートに、コンフィグレーションレジスタのアドレス番号を書き込みます。
次に、書き込むべきデータ数の分だけ、ライトデータポートに、データを
書き込みます。

<tag>読み込み</tag>
アドレスポートに コンフィグレーションレジスタのアドレス番号を書き込みます。
次に、読み込むべきデータ数の分だけ、リードデータポートから、データを
読み込みます。
</descrip>

<sect1>ISAPnP のコンフィグレーション
<p>
ISAPnP のコンフィグレーションについて、説明します。

<sect2>分離の仕組み<label id="isolation">
<p>
ISAPnP カードの仕組みで最も難しいものが、<em>分離(isolation)</em>です。
分離とは ISA Bus 上にある複数枚のカードから、一枚だけを識別し、番号を
付けることです。
ISAPnP カードは 32bit のベンダーID と 32bit のシリアルID の合計 64bit の ID を
持っています。この ID は他の全ての ISAPnP カードと異なるように
付けられています。この ID と ID のチェックサム 8bit の合計 72bit を使って、
ISAPnP カードを分離します。
<p>
分離のアルゴリズムの基本的な考えは勝ち抜き戦のようなものです。
勝ち抜き戦は、ID を LSB から順に 1 ビットづつ調べて行います。
勝敗は下記のように決めます。
<descrip>
<tag>勝ち組</tag>  ID の調査中のビットが 1 のカード。勝ち組は手を挙げて、勝利を
他のカードに知らせる。

<tag>負け組</tag>  ID の調査中のビットが 0 のカード。負け組は、手を挙げているカードが無いか、調べる。

<tag>敗者復活</tag> 誰も勝者がいなければ(手が挙がらないとき)、次の勝負に進める。
</descrip>
負け組は敗者復活のときにしか、次の勝負に進めません。
そして、優勝したカードには、番号(CSN:Card Select Number)を付けて、勝負から
降りて(勝ち抜けて)もらいます。
敗者たちは、次の勝ち抜き戦に出場します。
この勝ち抜き戦を繰り返し、カードが全て無くなるまで勝負を続けます。
<p>
例として、カード A は 101、カード B は 011、カード C は 001 の 2 進数 3bit 
の ID を持っているとします。勝負は最下位ビットから始めます。
<verb>
勝負 |   A   |   B   |   C   | 手 |   判定
=====+=======+=======+=======+====+===========
1-1  | A = 1 | B = 1 | C = 1 | 挙 | みんな勝ち
1-2  | A = 0 | B = 1 | C = 0 | 挙 | B の勝ち
1-3  | xxxxx | B = 0 | xxxxx |    | B の優勝
-----+-------+-------+-------+----+-----------
2-1  | A = 1 | I am  | C = 1 | 挙 | 両方勝ち
2-2  | A = 0 |  NO.  | C = 0 |    | 敗者復活
2-3  | A = 1 |  one! | C = 0 | 挙 | A の優勝
-----+-------+-------+-------+----+-----------
3-1  | I am  |       | C = 1 | 挙 | C の勝ち
3-2  |  NO.  |       | C = 0 |    | 敗者復活
3-3  |  two. |       | C = 0 |    | C の優勝
-----+-------+-------+-------+----+-----------
4-1  |       |       |       |    |カード無し
=====+=======+=======+=======+====+===========
CSN  |   2   |   1   |   3   |     
</verb>
こうして、全てのカードには CSN が付けられたので、今後カードとは、
CSN を使用し、コンフィグレーションを続けます。
<p>
勿論、実際の ISAPnP の分離のアルゴリズム(シーケンス)はもう少し複雑です。
基本となるアルゴリズムは下記の通りです。
<p>
OS がデータリードポートアドレスからデータを 2 回読み込みます。
ISAPnP カードは ID の 調査中のビットが 1 の場合、データを 0x55, 0xAA の順で
出力します(勝ち組)。ID の調査中のビットが 0 の ISAPnP カードは、データバスを 2
回読み込み、最初のデータの下位 2ビットが 01 で、次のデータの下位 2 ビット
が 10 の場合、Sleep ステートに移行します(負け組)が、データの下位 2 ビットが、
01,10 で無かった場合、Isolate ステートを続行します(敗者復活)。
OS は読み込んだ最初のデータが 0x55、 次のデータが 0xAA だった場合、
ID は 1 、そうでない場合、 0 と判断します。
<p>
このアルゴリズムを仮に Iso 操作と呼びます。この操作を ID のチェックサムを
求める為に、64 回繰り返し、ISAPnP カードが出力するチェックサムを取得する
ために、8 回繰り返します。最後に両者のチェックサムを比較し、ISAPnPカード の
有無を判断します。実際の ISAPnP 分離のアルゴリズムは下記のようになります。
<enum>
<item>OS は CSN を 0x01に初期化し、データリードポートアドレスを 0x203 に
します。

<item>データリードポートアドレスが 0x3ff を越えた場合、9. へ行き終了します。

<item>OSは 現在のデータリードポートアドレスを ISAPnP カードに設定し、
 ISAPnP カードを Isolate ステートに移行させます。

<item>OS の チェックサムを初期化し、Iso 操作を 64 回 繰り返しチェックサムを
計算します。

<item>Iso 操作を 8 回 繰り返し、ISAPnP カードのチェックサムと OS のチェック
サムを比較します。一致したら、6．へ、一致しなかったら 8. へ行きます。

<item>チェックサムが一致した場合、ISAPnP カードに CSN を割り当てます。

<item>CSN を更新し、次の ISAPnP カードのため、3. へ行きます。

<item>チェックサムが一致しなかった場合、データリードポートアドレス
を更新(4 を加算)し、2．へ行きます。

<item>ISAPnP カードが無かったとして、終了します。
</enum>
尚、チェックサムの計算方法により、チェックサムは 0 で無いことが、保証されて
います。従って、ISAPnP カードがあれば、必ず 0x55,0xAA が読み出せるので、
リードデータポートアドレスは確定できますし、ISAPnP カードの分離もできます。


<sect2>チェックサムの計算
<p>
チェックサムの計算は LFSR(linear feedback shift register) を使います。
LFSR は 8bit 長で、bit0 と bit1 と ISAPnP の ID ビットの排他的論理和が
bit7 にフィードバックされています。LFSR は OS から 0x6a に初期化され、
ID ビットが更新されるときに、シフトされます。
ISAPnP の ID は 64bit ですから、LFSR を 64 回シフトした結果がチェックサムに
なります。この計算法により、チェックサムは 0 でないことが、保証されます。

尚、このチェックサムの計算は CRC チェックサムの一種です。

<sect2>リソースの読み込み
<p>
リソースの読み込みには二つの方法があります。一つは、ISAPnP カードの分離後、
続けて ISAPnP カードにアクセスする方法です。
ISAPnP カードは分離後、リソースデータを連続して、出力します。OS は コンフィグ
レーションレジスタを調べてリソースデータの終了を調べます。
もう一つは、下記の手順を使い、OS が ISAPnP カードのリソースを読み込む方法
です。
<enum>
<item>OS は CSN を出力します。

<item>OS は ISAPnP カードの論理デバイスを指定します。

<item>OS は ISAPnP のリソースの種類を指定します。

<item>ISAPnP カードは指定された論理デバイスのリソースを出力します。

<item>OS はリソースを読み込みます。
</enum>
 
<sect2>リソースの書き込み
<p>
下記の手順で OS は ISAPnP カードのリソースを書き込みます。
<enum>
<item>OS は CSN を出力します。

<item>OS は ISAPnP カードの論理デバイスを指定します。

<item>OS は ISAPnP のリソースの種類を指定します。

<item>OS は指定した論理デバイスのリソースを書き込みます。

<item>ISAPnP カードはリソースを設定します。
</enum>

<sect2>リソースの種類
<p>
リソースの種類は、下記の通りです。種類ごとにフィールドがあり、さらに、それ毎
に、サブフィールドがあります。
<descrip>
<tag>メモリ</tag>
メモリのフィールドは 四つあります。
メモリのサブフィールドはベースアドレス、コントロール、制限値の 三つがあります。
ベースアドレスはメモリアドレスの上位 16bit です。
コントロールは メモリのアクセスが 8bit か 16bitの指定と、制限値の種類です。
制限値は 16bit 幅で、コントロールの指定により、メモリの長さか、メモリアドレスの
上限値になります。

<tag>I/O アドレス</tag>
I/O アドレスのフィールドは八つあります。
I/O アドレスのサブフィールドはベースアドレス、最大アドレス、アライメント境界、アドレス長の四つがあります。ベースアドレスと最大アドレスは 10bit です。
アライメント境界とアドレス長は 8bit です。

<tag>IRQ</tag>
IRQ のフィールドは一つだけです。
IRQ のサブフィールドは IRQ マスクとトリガ方式の二つあります。
IRQ マスクは 16bit で、ビット位置で IRQ 番号が指定されます。トリガ方式は 4 種
類ありますが、 ISA で使用するのは立ち上がりエッジ方式だけです。

<tag>DMA</tag>
DMA のフィールドは一つだけです。
DMA のサブフィールドは DMA マスクと転送方式の二つあります。
DMA マスクは 8bit で、ビット位置で DMA番号が指定されます。
転送方式は データバス幅、連続転送・断続転送等が指定されます。 
</descrip>

 <!-- おしまい -->
</article>
