S/390 驅動模型介面

1. CCW 裝置

所有可以透過 CCW 定址的裝置都被稱為“CCW 裝置” - 即使它們實際上不是由 CCW 驅動的。

所有 CCW 裝置都透過子通道訪問,這反映在 devices/ 下的結構中。

devices/
   - system/
   - css0/
         - 0.0.0000/0.0.0815/
         - 0.0.0001/0.0.4711/
         - 0.0.0002/
         - 0.1.0000/0.1.1234/
         ...
         - defunct/

在此示例中,裝置 0815 透過子通道集 0 中的子通道 0 訪問,裝置 4711 透過子通道集 0 中的子通道 1 訪問,子通道 2 是非 I/O 子通道。裝置 1234 透過子通道集 1 中的子通道 0 訪問。

名為“defunct”的子通道不代表系統上的任何真實子通道;它是一個偽子通道,如果斷開連線的 CCW 裝置被另一個在其先前子通道上執行的 CCW 裝置取代,則會將其移動到該偽子通道。如果 CCW 裝置再次在該子通道上執行,它們將被再次移動到適當的子通道。

您應該透過其匯流排 ID(例如 0.0.4711)定址 CCW 裝置;該裝置可以在 bus/ccw/devices/ 下找到。

所有 CCW 裝置都透過 sysfs 匯出一些資料。

cutype

控制單元型別/型號。

devtype

裝置型別/型號(如果適用)。

availability

可以是“good”或“boxed”;對於斷開連線的裝置,可以是“no path”或“no device”。

online

一個用於設定裝置上線和下線的介面。在裝置斷開連線的特殊情況下(參見 1.2 下的 notify 函式),將 0 管道到 online 將強制刪除該裝置。

裝置驅動程式可以新增條目以匯出每個裝置的資料和介面。

還有一些資料以每個子通道為基礎匯出(參見 bus/css/devices/ 下)。

chpids

裝置透過哪些 chpids 連線。

pimpampom

已安裝路徑、可用路徑和可操作路徑的掩碼。

可能還有其他資料,例如塊裝置的資料。

1.1 啟動 CCW 裝置

這分為幾個步驟完成。

  1. 每個驅動程式可以提供一個或多個引數介面,可以在其中指定引數。這些介面也由驅動程式負責。

  2. 如有必要,在執行 a. 之後,最終透過“online”介面啟動裝置。

1.2 為 CCW 裝置編寫驅動程式

基本的 struct ccw_devicestruct ccw_driver 資料結構可以在 include/asm/ccwdev.h 下找到

struct ccw_device {
      spinlock_t *ccwlock;
      struct ccw_device_private *private;
      struct ccw_device_id id;

      struct ccw_driver *drv;
      struct device dev;
      int online;

      void (*handler) (struct ccw_device *dev, unsigned long intparm,
                       struct irb *irb);
};

struct ccw_driver {
      struct module *owner;
      struct ccw_device_id *ids;
      int (*probe) (struct ccw_device *);
      int (*remove) (struct ccw_device *);
      int (*set_online) (struct ccw_device *);
      int (*set_offline) (struct ccw_device *);
      int (*notify) (struct ccw_device *, int);
      struct device_driver driver;
      char *name;
};

“private”欄位包含僅用於內部 I/O 操作的資料,並且裝置驅動程式不可用。

每個驅動程式都應該在 MODULE_DEVICE_TABLE 中宣告它感興趣的 CU 型別/型號和/或裝置型別/型號。此資訊稍後可以在 struct ccw_device_id 欄位中找到

struct ccw_device_id {
      __u16   match_flags;

      __u16   cu_type;
      __u16   dev_type;
      __u8    cu_model;
      __u8    dev_model;

      unsigned long driver_info;
};

ccw_driver 中的函式應以下列方式使用

probe

裝置層會為驅動程式感興趣的每個裝置呼叫此函式。驅動程式應僅分配私有結構以放入 dev->driver_data 並建立屬性(如果需要)。此外,應在此處設定中斷處理程式(見下文)。

int (*probe) (struct ccw_device *cdev);
引數
cdev
  • 要探測的裝置。

remove

驅動程式層在刪除驅動程式、裝置或模組時會呼叫此函式。驅動程式應在此處執行清理。

int (*remove) (struct ccw_device *cdev);
引數
cdev
  • 要刪除的裝置。

set_online

當裝置透過“online”屬性啟用時,公共 I/O 層會呼叫此函式。驅動程式應在此處最終設定並激活裝置。

int (*set_online) (struct ccw_device *);
引數
cdev
  • 要啟用的裝置。公共層已驗證該裝置尚未上線。

set_offline:當裝置

透過“online”屬性停用時,公共 I/O 層會呼叫此函式。驅動程式應關閉裝置,但不要取消分配其私有資料。

int (*set_offline) (struct ccw_device *);
引數
cdev
  • 要停用的裝置。公共層

    已驗證該裝置已上線。

notify

公共 I/O 層會為裝置的某些狀態更改呼叫此函式。

傳送到驅動程式的訊號是

  • 在線上狀態下,裝置已分離 (CIO_GONE) 或最後一個路徑已消失 (CIO_NO_PATH)。驅動程式必須返回 !0 以保留該裝置;對於返回程式碼 0,裝置將像往常一樣被刪除(即使未註冊任何 notify 函式)。如果驅動程式想要保留該裝置,則會將其移動到斷開連線狀態。

  • 在斷開連線狀態下,裝置再次執行 (CIO_OPER)。公共 I/O 層對裝置編號和裝置/CU 執行一些健全性檢查,以合理確定它是否仍然是同一裝置。如果不是,則刪除舊裝置並註冊一個新裝置。透過 notify 函式的返回程式碼,裝置驅動程式發出訊號,表明它是否希望將裝置取回:!0 表示保留,0 表示使裝置被刪除並重新註冊。

int (*notify) (struct ccw_device *, int);
引數
cdev
  • 其狀態已更改的裝置。

event
  • 發生的事件。這可以是 CIO_GONE、CIO_NO_PATH 或 CIO_OPER 之一。

struct ccw_device 的 handler 欄位旨在設定為裝置的中斷處理程式。為了適應使用多個不同處理程式的驅動程式(例如多子通道裝置),這是 ccw_device 的成員,而不是 ccw_driver 的成員。該處理程式在驅動程式被呼叫之前,在 set_online() 處理期間向公共層註冊,並在驅動程式被呼叫之後,在 set_offline() 期間登出。此外,在註冊/登出之前,會執行路徑分組或解散路徑組(如果適用)。

void (*handler) (struct ccw_device *dev, unsigned long intparm, struct irb *irb);
引數:dev - 呼叫處理程式的裝置
intparm - intparm 允許裝置驅動程式識別

中斷與之關聯的 i/o,或將中斷識別為未經請求的。

irb - 中斷響應塊,其中包含累積的

狀態。

裝置驅動程式從公共 ccw_device 層呼叫,並且可以從 irb 引數中檢索有關中斷的資訊。

1.3 ccwgroup 裝置

ccwgroup 機制旨在處理由多個 ccw 裝置組成的裝置,如 qeth 或 ctc。

ccw 驅動程式提供了一個“group”屬性。將 ccw 裝置的匯流排 ID 管道到此屬性會建立一個由這些 ccw 裝置組成的 ccwgroup 裝置(如果可能)。此 ccwgroup 裝置可以像普通 ccw 裝置一樣設定為上線或下線。

每個 ccwgroup 裝置還提供一個“ungroup”屬性,用於再次銷燬該裝置(僅在離線時)。這是一個通用的 ccwgroup 機制(驅動程式不需要實現任何超出正常刪除例程的內容)。

作為 ccwgroup 裝置成員的 ccw 裝置在其裝置結構的 driver_data 中攜帶一個指向 ccwgroup 裝置的指標。驅動程式不得觸及此欄位 - 它應該使用 ccwgroup 裝置的 driver_data 作為其私有資料。

要實現 ccwgroup 驅動程式,請參閱 include/asm/ccwgroup.h。請記住,大多數驅動程式都需要同時實現 ccwgroup 和 ccw 驅動程式。

2. 通道路徑

通道路徑像子通道一樣出現在通道子系統根目錄 (css0) 下,稱為“chp0.<chpid>”。它們沒有驅動程式,也不屬於任何匯流排。請注意,與 2.4 中的 /proc/chpids 不同,通道路徑物件僅反映邏輯狀態,而不反映物理狀態,因為由於缺少機器支援,我們無法始終如一地跟蹤後者(無論如何我們不需要了解它)。

status
  • 可以是“online”或“offline”。管道“on”或“off”將 chpid 邏輯上設定為上線/下線。將“on”管道到線上 chpid 會觸發 chpid 連線到的所有裝置的路徑重新探測。這可用於強制核心重新使用使用者知道線上的通道路徑,但機器尚未為其建立機器檢查。

type
  • 通道路徑的物理型別。

shared
  • 通道路徑是否共享。

cmg
  • 通道測量組。

3. 系統裝置

3.1 xpram

xpram 顯示在 devices/system/ 下,作為“xpram”。

3.2 cpus

對於每個 cpu,會在 devices/system/cpu/ 下建立一個目錄。每個 cpu 都有一個屬性“online”,可以是 0 或 1。

4. 其他裝置

4.1 Netiucv

netiucv 驅動程式在 bus/iucv/drivers/netiucv 下建立一個屬性“connection”。管道到此屬性會建立一個到指定主機的新的 netiucv 連線。

Netiucv 連線顯示在 devices/iucv/ 下,作為“netiucv<ifnum>”。介面編號按順序分配給透過“connection”屬性定義的連線。

user
  • 顯示連線夥伴。

buffer
  • 最大緩衝區大小。管道到它可以更改緩衝區大小。