Linux 即插即用文件

作者:

Adam Belay <ambx1@neo.rr.com>

上次更新時間:

2002 年 10 月 16 日

概述

即插即用提供了一種檢測和設定傳統裝置或無法配置的裝置的資源的方法。 Linux 即插即用層為相容的驅動程式提供這些服務。

使用者介面

Linux 即插即用使用者介面提供了一種為不支援 Linux 即插即用的傳統和使用者級驅動程式啟用 PnP 裝置的方法。 使用者介面整合到 sysfs 中。

除了標準的 sysfs 檔案外,以下檔案在每個裝置的目錄中建立:- id - 顯示支援的 EISA ID 列表 - options - 顯示可能的資源配置 - resources - 顯示當前分配的資源並允許資源更改

啟用裝置

# echo "auto" > resources

這將呼叫自動資源配置系統來啟用裝置

手動啟用裝置

# echo "manual <depnum> <mode>" > resources

<depnum> - the configuration number
<mode> - static or dynamic
         static = for next boot
         dynamic = now

停用裝置

# echo "disable" > resources

示例

假設您需要啟用軟盤驅動器控制器。

  1. 切換到正確的目錄,在我的例子中是 /driver/bus/pnp/devices/00:0f

    # cd /driver/bus/pnp/devices/00:0f
    # cat name
    PC standard floppy disk controller
    
  2. 檢查裝置是否已啟用

    # cat resources
    DISABLED
    
  • 注意字串“DISABLED”。 這意味著該裝置未啟用。

  1. 檢查裝置的可能配置(可選)

    # cat options
    Dependent: 01 - Priority acceptable
        port 0x3f0-0x3f0, align 0x7, size 0x6, 16-bit address decoding
        port 0x3f7-0x3f7, align 0x0, size 0x1, 16-bit address decoding
        irq 6
        dma 2 8-bit compatible
    Dependent: 02 - Priority acceptable
        port 0x370-0x370, align 0x7, size 0x6, 16-bit address decoding
        port 0x377-0x377, align 0x0, size 0x1, 16-bit address decoding
        irq 6
        dma 2 8-bit compatible
    
  2. 現在啟用裝置

    # echo "auto" > resources
    
  3. 最後檢查裝置是否已啟用

    # cat resources
    io 0x3f0-0x3f5
    io 0x3f7-0x3f7
    irq 6
    dma 2
    

還有一系列核心引數

pnp_reserve_irq=irq1[,irq2] ....
pnp_reserve_dma=dma1[,dma2] ....
pnp_reserve_io=io1,size1[,io2,size2] ....
pnp_reserve_mem=mem1,size1[,mem2,size2] ....

統一的即插即用層

所有即插即用驅動程式、協議和服務都彙集在一個名為即插即用層的中心位置。 該層負責 PnP 驅動程式和 PnP 協議之間的資訊交換。 因此,它會自動將命令轉發到正確的協議。 這使得編寫 PnP 驅動程式更加容易。

以下函式可從即插即用層獲得

pnp_get_protocol

將使用次數增加一

pnp_put_protocol

將使用次數減少一

pnp_register_protocol

使用此功能註冊新的 PnP 協議

pnp_register_driver

將 PnP 驅動程式新增到即插即用層

這包括驅動程式模型整合,成功返回零,失敗返回負錯誤號; 如果需要知道有多少裝置繫結到驅動程式,請計算對 .add() 方法的呼叫

pnp_unregister_driver

從即插即用層中刪除 PnP 驅動程式

即插即用協議

本節包含面向 PnP 協議開發人員的資訊。

以下協議目前在計算領域可用

  • PNPBIOS

    用於系統裝置,例如序列和並行埠。

  • ISAPNP

    為 ISA 匯流排提供 PnP 支援

  • ACPI

    在其眾多用途中,ACPI 提供有關係統級裝置的資訊。

它旨在取代 PNPBIOS。 Linux 即插即用目前不支援它,但計劃在不久的將來支援它。

Linux PnP 協議的要求:1. 該協議必須使用 EISA ID 2. 該協議必須將裝置的當前配置通知給 PnP 層

  • 設定資源的能力是可選的,但首選。

以下是 PnP 協議相關函式

pnp_add_device

使用此函式將 PnP 裝置新增到 PnP 層

僅當所有需要的值都設定在 pnp_dev 結構中時才呼叫此函式

pnp_init_device

呼叫此函式以初始化 PnP 結構

pnp_remove_device

呼叫此函式以從即插即用層中刪除裝置。 如果該裝置仍在被使用,它將失敗。 將自動釋放裝置和相關結構使用的記憶體

pnp_add_id

將 EISA ID 新增到指定裝置支援的 ID 列表

有關更多資訊,請查閱協議的原始碼,例如 /drivers/pnp/pnpbios/core.c。

Linux 即插即用驅動程式

本節包含面向 Linux PnP 驅動程式開發人員的資訊。

新方法

  1. 首先建立一個支援的 EISA ID 列表

    例如

    static const struct pnp_id pnp_dev_table[] = {
            /* Standard LPT Printer Port */
            {.id = "PNP0400", .driver_data = 0},
            /* ECP Printer Port */
            {.id = "PNP0401", .driver_data = 0},
            {.id = ""}
    };
    

    請注意,字元“X”可用作函式部分(最後四個字元)中的萬用字元。

    例如

    /* Unknown PnP modems */
    {       "PNPCXXX",              UNKNOWN_DEV     },
    

    可以選擇定義支援的 PnP 卡 ID。 例如

    static const struct pnp_id pnp_card_table[] = {
            {       "ANYDEVS",              0       },
            {       "",                     0       }
    };
    
  2. 可以選擇定義探測和刪除函式。 如果驅動程式已經有一種可靠的檢測資源的方法,例如 parport_pc 驅動程式,則不定義這些函式可能是有意義的。

    例如

    static int
    serial_pnp_probe(struct pnp_dev * dev, const struct pnp_id *card_id, const
                    struct pnp_id *dev_id)
    {
    . . .
    

    例如

    static void serial_pnp_remove(struct pnp_dev * dev)
    {
    . . .
    

    有關更多資訊,請查閱 /drivers/serial/8250_pnp.c。

  3. 建立一個驅動程式結構

    例如

    static struct pnp_driver serial_pnp_driver = {
            .name           = "serial",
            .card_id_table  = pnp_card_table,
            .id_table       = pnp_dev_table,
            .probe          = serial_pnp_probe,
            .remove         = serial_pnp_remove,
    };
    
    • 名稱和 id_table 不能為 NULL。

  4. 註冊驅動程式

    例如

    static int __init serial8250_pnp_init(void)
    {
            return pnp_register_driver(&serial_pnp_driver);
    }
    

舊方法

已建立一系列相容性函式,以便於轉換 ISAPNP 驅動程式。 它們應該僅作為臨時解決方案。

它們如下

struct pnp_dev *pnp_find_dev(struct pnp_card *card,
                             unsigned short vendor,
                             unsigned short function,
                             struct pnp_dev *from)