Writing s390 channel device drivers

Author:

Cornelia Huck

Introduction

This document describes the interfaces available for device drivers thatdrive s390 based channel attached I/O devices. This includes interfacesfor interaction with the hardware and interfaces for interacting withthe common driver core. Those interfaces are provided by the s390 commonI/O layer.

The document assumes a familarity with the technical terms associatedwith the s390 channel I/O architecture. For a description of thisarchitecture, please refer to the “z/Architecture: Principles ofOperation”, IBM publication no. SA22-7832.

While most I/O devices on a s390 system are typically driven through thechannel I/O mechanism described here, there are various other methods(like the diag interface). These are out of the scope of this document.

The s390 common I/O layer also provides access to some devices that arenot strictly considered I/O devices. They are considered here as well,although they are not the focus of this document.

Some additional information can also be found in the kernel source underS/390 driver model interfaces.

The css bus

The css bus contains the subchannels available on the system. They fallinto several categories:

  • Standard I/O subchannels, for use by the system. They have a childdevice on the ccw bus and are described below.

  • I/O subchannels bound to the vfio-ccw driver. Seevfio-ccw: the basic infrastructure.

  • Message subchannels. No Linux driver currently exists.

  • CHSC subchannels (at most one). The chsc subchannel driver can be usedto send asynchronous chsc commands.

  • eADM subchannels. Used for talking to storage class memory.

The ccw bus

The ccw bus typically contains the majority of devices available to as390 system. Named after the channel command word (ccw), the basiccommand structure used to address its devices, the ccw bus containsso-called channel attached devices. They are addressed via I/Osubchannels, visible on the css bus. A device driver forchannel-attached devices, however, will never interact with thesubchannel directly, but only via the I/O device on the ccw bus, the ccwdevice.

I/O functions for channel-attached devices

Some hardware structures have been translated into C structures for useby the common I/O layer and device drivers. For more information on thehardware structures represented here, please consult the Principles ofOperation.

structccw1

channel command word

Definition:

struct ccw1 {    __u8 cmd_code;    __u8 flags;    __u16 count;    dma32_t cda;};

Members

cmd_code

command code

flags

flags, like IDA addressing, etc.

count

byte count

cda

data address

Description

The ccw is the basic structure to build channel programs that performoperations with the device or the control unit. Only Format-1 channelcommand words are supported.

structccw0

channel command word

Definition:

struct ccw0 {    __u8 cmd_code;    __u32 cda : 24;    __u8 flags;    __u8 reserved;    __u16 count;};

Members

cmd_code

command code

cda

data address

flags

flags, like IDA addressing, etc.

reserved

will be ignored

count

byte count

Description

The format-0 ccw structure.

structerw

extended report word

Definition:

struct erw {    __u32 res0  : 3;    __u32 auth  : 1;    __u32 pvrf  : 1;    __u32 cpt   : 1;    __u32 fsavf : 1;    __u32 cons  : 1;    __u32 scavf : 1;    __u32 fsaf  : 1;    __u32 scnt  : 6;    __u32 res16 : 16;};

Members

res0

reserved

auth

authorization check

pvrf

path-verification-required flag

cpt

channel-path timeout

fsavf

failing storage address validity flag

cons

concurrent sense

scavf

secondary ccw address validity flag

fsaf

failing storage address format

scnt

sense count, ifcons ==1

res16

reserved

structerw_eadm

EADM Subchannel extended report word

Definition:

struct erw_eadm {    __u32 : 16;    __u32 b : 1;    __u32 r : 1;    __u32 : 14;};

Members

b

aob error

r

arsb error

structsublog

subchannel logout area

Definition:

struct sublog {    __u32 res0  : 1;    __u32 esf   : 7;    __u32 lpum  : 8;    __u32 arep  : 1;    __u32 fvf   : 5;    __u32 sacc  : 2;    __u32 termc : 2;    __u32 devsc : 1;    __u32 serr  : 1;    __u32 ioerr : 1;    __u32 seqc  : 3;};

Members

res0

reserved

esf

extended status flags

lpum

last path used mask

arep

ancillary report

fvf

field-validity flags

sacc

storage access code

termc

termination code

devsc

device-status check

serr

secondary error

ioerr

i/o-error alert

seqc

sequence code

structesw0

Format 0 Extended Status Word (ESW)

Definition:

struct esw0 {    struct sublog sublog;    struct erw erw;    dma32_t faddr[2];    dma32_t saddr;};

Members

sublog

subchannel logout

erw

extended report word

faddr

failing storage address

saddr

secondary ccw address

structesw1

Format 1 Extended Status Word (ESW)

Definition:

struct esw1 {    __u8 zero0;    __u8 lpum;    __u16 zero16;    struct erw erw;    __u32 zeros[3];};

Members

zero0

reserved zeros

lpum

last path used mask

zero16

reserved zeros

erw

extended report word

zeros

three fullwords of zeros

structesw2

Format 2 Extended Status Word (ESW)

Definition:

struct esw2 {    __u8 zero0;    __u8 lpum;    __u16 dcti;    struct erw erw;    __u32 zeros[3];};

Members

zero0

reserved zeros

lpum

last path used mask

dcti

device-connect-time interval

erw

extended report word

zeros

three fullwords of zeros

structesw3

Format 3 Extended Status Word (ESW)

Definition:

struct esw3 {    __u8 zero0;    __u8 lpum;    __u16 res;    struct erw erw;    __u32 zeros[3];};

Members

zero0

reserved zeros

lpum

last path used mask

res

reserved

erw

extended report word

zeros

three fullwords of zeros

structesw_eadm

EADM Subchannel Extended Status Word (ESW)

Definition:

struct esw_eadm {    __u32 sublog;    struct erw_eadm erw;    __u32 : 32;    __u32 : 32;    __u32 : 32;};

Members

sublog

subchannel logout

erw

extended report word

structirb

interruption response block

Definition:

struct irb {    union scsw scsw;    union {        struct esw0 esw0;        struct esw1 esw1;        struct esw2 esw2;        struct esw3 esw3;        struct esw_eadm eadm;    } esw;    __u8 ecw[32];};

Members

scsw

subchannel status word

esw

extended status word

ecw

extended control word

Description

The irb that is handed to the device driver when an interrupt occurs. Forsolicited interrupts, the common I/O layer already performs checks whethera field is valid; a field not being valid is always passed as0.If a unit check occurred,ecw may contain sense data; this is retrievedby the common I/O layer itself if the device doesn’t support concurrentsense (so that the device driver never needs to perform basic sense itself).For unsolicited interrupts, the irb is passed as-is (expect for sense data,if applicable).

structciw

command information word (CIW) layout

Definition:

struct ciw {    __u32 et       :  2;    __u32 reserved :  2;    __u32 ct       :  4;    __u32 cmd      :  8;    __u32 count    : 16;};

Members

et

entry type

reserved

reserved bits

ct

command type

cmd

command code

count

command count

structccw_dev_id

unique identifier for ccw devices

Definition:

struct ccw_dev_id {    u8 ssid;    u16 devno;};

Members

ssid

subchannel set id

devno

device number

Description

This structure is not directly based on any hardware structure. Thehardware identifies a device by its device number and its subchannel,which is in turn identified by its id. In order to get a unique identifierfor ccw devices across subchannel sets,struct ccw_dev_id has beenintroduced.

intccw_dev_id_is_equal(structccw_dev_id*dev_id1,structccw_dev_id*dev_id2)

compare two ccw_dev_ids

Parameters

structccw_dev_id*dev_id1

a ccw_dev_id

structccw_dev_id*dev_id2

another ccw_dev_id

Return

1 if the two structures are equal field-by-field,0 if not.

Context

any

u8pathmask_to_pos(u8mask)

find the position of the left-most bit in a pathmask

Parameters

u8mask

pathmask with at least one bit set

ccw devices

Devices that want to initiate channel I/O need to attach to the ccw bus.Interaction with the driver core is done via the common I/O layer, whichprovides the abstractions of ccw devices and ccw device drivers.

The functions that initiate or terminate channel I/O all act upon a ccwdevice structure. Device drivers must not bypass those functions orstrange side effects may happen.

structccw_device

channel attached device

Definition:

struct ccw_device {    spinlock_t *ccwlock;    struct ccw_device_id id;    struct ccw_driver *drv;    struct device dev;    int online;    void (*handler) (struct ccw_device *, unsigned long, struct irb *);};

Members

ccwlock

pointer to device lock

id

id of this device

drv

ccw driver for this device

dev

embedded device structure

online

online status of device

handler

interrupt handler

Description

handler is a member of the device rather than the driver since a drivercan have different interrupt handlers for different ccw devices(multi-subchannel drivers).

structccw_driver

device driver for channel attached devices

Definition:

struct ccw_driver {    struct ccw_device_id *ids;    int (*probe) (struct ccw_device *);    void (*remove) (struct ccw_device *);    int (*set_online) (struct ccw_device *);    int (*set_offline) (struct ccw_device *);    int (*notify) (struct ccw_device *, int);    void (*path_event) (struct ccw_device *, int *);    void (*shutdown) (struct ccw_device *);    enum uc_todo (*uc_handler) (struct ccw_device *, struct irb *);    struct device_driver driver;    enum interruption_class int_class;};

Members

ids

ids supported by this driver

probe

function called on probe

remove

function called on remove

set_online

called when setting device online

set_offline

called when setting device offline

notify

notify driver of device state changes

path_event

notify driver of channel path events

shutdown

called at device shutdown

uc_handler

callback for unit check handler

driver

embedded device driver structure

int_class

interruption class to use for accounting interrupts

intccw_device_set_offline(structccw_device*cdev)

disable a ccw device for I/O

Parameters

structccw_device*cdev

target ccw device

Description

This function calls the driver’sset_offline() function forcdev, ifgiven, and then disablescdev.

Return

0 on success and a negative error value on failure.

Context

enabled, ccw device lock not held

intccw_device_set_online(structccw_device*cdev)

enable a ccw device for I/O

Parameters

structccw_device*cdev

target ccw device

Description

This function first enablescdev and then calls the driver’sset_online()function forcdev, if given. Ifset_online() returns an error,cdev isdisabled again.

Return

0 on success and a negative error value on failure.

Context

enabled, ccw device lock not held

structccw_device*get_ccwdev_by_dev_id(structccw_dev_id*dev_id)

obtain device from a ccw device id

Parameters

structccw_dev_id*dev_id

id of the device to be searched

Description

This function searches all devices attached to the ccw bus for a devicematchingdev_id.

Return

If a device is found its reference count is increased and returned;elseNULL is returned.

structccw_device*get_ccwdev_by_busid(structccw_driver*cdrv,constchar*bus_id)

obtain device from a bus id

Parameters

structccw_driver*cdrv

driver the device is owned by

constchar*bus_id

bus id of the device to be searched

Description

This function searches all devices owned bycdrv for a device with a busid matchingbus_id.

Return

If a match is found, its reference count of the found device is increasedand it is returned; elseNULL is returned.

intccw_driver_register(structccw_driver*cdriver)

register a ccw driver

Parameters

structccw_driver*cdriver

driver to be registered

Description

This function is mainly a wrapper arounddriver_register().

Return

0 on success and a negative error value on failure.

voidccw_driver_unregister(structccw_driver*cdriver)

deregister a ccw driver

Parameters

structccw_driver*cdriver

driver to be deregistered

Description

This function is mainly a wrapper arounddriver_unregister().

intccw_device_siosl(structccw_device*cdev)

initiate logging

Parameters

structccw_device*cdev

ccw device

Description

This function is used to invoke model-dependent logging within the channelsubsystem.

intccw_device_set_options_mask(structccw_device*cdev,unsignedlongflags)

set some options and unset the rest

Parameters

structccw_device*cdev

device for which the options are to be set

unsignedlongflags

options to be set

Description

All flags specified inflags are set, all flags not specified inflagsare cleared.

Return

0 on success, -EINVAL on an invalid flag combination.

intccw_device_set_options(structccw_device*cdev,unsignedlongflags)

set some options

Parameters

structccw_device*cdev

device for which the options are to be set

unsignedlongflags

options to be set

Description

All flags specified inflags are set, the remainder is left untouched.

Return

0 on success, -EINVAL if an invalid flag combination would ensue.

voidccw_device_clear_options(structccw_device*cdev,unsignedlongflags)

clear some options

Parameters

structccw_device*cdev

device for which the options are to be cleared

unsignedlongflags

options to be cleared

Description

All flags specified inflags are cleared, the remainder is left untouched.

intccw_device_is_pathgroup(structccw_device*cdev)

determine if paths to this device are grouped

Parameters

structccw_device*cdev

ccw device

Description

Return non-zero if there is a path group, zero otherwise.

intccw_device_is_multipath(structccw_device*cdev)

determine if device is operating in multipath mode

Parameters

structccw_device*cdev

ccw device

Description

Return non-zero if device is operating in multipath mode, zero otherwise.

intccw_device_clear(structccw_device*cdev,unsignedlongintparm)

terminate I/O request processing

Parameters

structccw_device*cdev

target ccw device

unsignedlongintparm

interruption parameter to be returned upon conclusion of csch

Description

ccw_device_clear() calls csch oncdev’s subchannel.

Return

0 on success,-ENODEV on device not operational,-EINVAL on invalid device state.

Context

Interrupts disabled, ccw device lock held

intccw_device_start_timeout_key(structccw_device*cdev,structccw1*cpa,unsignedlongintparm,__u8lpm,__u8key,unsignedlongflags,intexpires)

start a s390 channel program with timeout and key

Parameters

structccw_device*cdev

target ccw device

structccw1*cpa

logical start address of channel program

unsignedlongintparm

user specific interruption parameter; will be presented back tocdev’s interrupt handler. Allows a device driver to associatethe interrupt with a particular I/O request.

__u8lpm

defines the channel path to be used for a specific I/O request. Avalue of 0 will make cio use the opm.

__u8key

storage key to be used for the I/O

unsignedlongflags

additional flags; defines the action to be performed for I/Oprocessing.

intexpires

timeout value in jiffies

Description

Start a S/390 channel program. When the interrupt arrives, theIRQ handler is called, either immediately, delayed (dev-end missing,or sense required) or never (no IRQ handler registered).This function notifies the device driver if the channel program has notcompleted during the time specified byexpires. If a timeout occurs, thechannel program is terminated via xsch, hsch or csch, and the device’sinterrupt handler will be called with an irb containing ERR_PTR(-ETIMEDOUT).The interruption handler will echo back theintparm specified here, unlessanother interruption parameter is specified by a subsequent invocation ofccw_device_halt() orccw_device_clear().

Return

0, if the operation was successful;-EBUSY, if the device is busy, or status pending;-EACCES, if no path specified inlpm is operational;-ENODEV, if the device is not operational.

Context

Interrupts disabled, ccw device lock held

intccw_device_start_key(structccw_device*cdev,structccw1*cpa,unsignedlongintparm,__u8lpm,__u8key,unsignedlongflags)

start a s390 channel program with key

Parameters

structccw_device*cdev

target ccw device

structccw1*cpa

logical start address of channel program

unsignedlongintparm

user specific interruption parameter; will be presented back tocdev’s interrupt handler. Allows a device driver to associatethe interrupt with a particular I/O request.

__u8lpm

defines the channel path to be used for a specific I/O request. Avalue of 0 will make cio use the opm.

__u8key

storage key to be used for the I/O

unsignedlongflags

additional flags; defines the action to be performed for I/Oprocessing.

Description

Start a S/390 channel program. When the interrupt arrives, theIRQ handler is called, either immediately, delayed (dev-end missing,or sense required) or never (no IRQ handler registered).The interruption handler will echo back theintparm specified here, unlessanother interruption parameter is specified by a subsequent invocation ofccw_device_halt() orccw_device_clear().

Return

0, if the operation was successful;-EBUSY, if the device is busy, or status pending;-EACCES, if no path specified inlpm is operational;-ENODEV, if the device is not operational.

Context

Interrupts disabled, ccw device lock held

intccw_device_start(structccw_device*cdev,structccw1*cpa,unsignedlongintparm,__u8lpm,unsignedlongflags)

start a s390 channel program

Parameters

structccw_device*cdev

target ccw device

structccw1*cpa

logical start address of channel program

unsignedlongintparm

user specific interruption parameter; will be presented back tocdev’s interrupt handler. Allows a device driver to associatethe interrupt with a particular I/O request.

__u8lpm

defines the channel path to be used for a specific I/O request. Avalue of 0 will make cio use the opm.

unsignedlongflags

additional flags; defines the action to be performed for I/Oprocessing.

Description

Start a S/390 channel program. When the interrupt arrives, theIRQ handler is called, either immediately, delayed (dev-end missing,or sense required) or never (no IRQ handler registered).The interruption handler will echo back theintparm specified here, unlessanother interruption parameter is specified by a subsequent invocation ofccw_device_halt() orccw_device_clear().

Return

0, if the operation was successful;-EBUSY, if the device is busy, or status pending;-EACCES, if no path specified inlpm is operational;-ENODEV, if the device is not operational.

Context

Interrupts disabled, ccw device lock held

intccw_device_start_timeout(structccw_device*cdev,structccw1*cpa,unsignedlongintparm,__u8lpm,unsignedlongflags,intexpires)

start a s390 channel program with timeout

Parameters

structccw_device*cdev

target ccw device

structccw1*cpa

logical start address of channel program

unsignedlongintparm

user specific interruption parameter; will be presented back tocdev’s interrupt handler. Allows a device driver to associatethe interrupt with a particular I/O request.

__u8lpm

defines the channel path to be used for a specific I/O request. Avalue of 0 will make cio use the opm.

unsignedlongflags

additional flags; defines the action to be performed for I/Oprocessing.

intexpires

timeout value in jiffies

Description

Start a S/390 channel program. When the interrupt arrives, theIRQ handler is called, either immediately, delayed (dev-end missing,or sense required) or never (no IRQ handler registered).This function notifies the device driver if the channel program has notcompleted during the time specified byexpires. If a timeout occurs, thechannel program is terminated via xsch, hsch or csch, and the device’sinterrupt handler will be called with an irb containing ERR_PTR(-ETIMEDOUT).The interruption handler will echo back theintparm specified here, unlessanother interruption parameter is specified by a subsequent invocation ofccw_device_halt() orccw_device_clear().

Return

0, if the operation was successful;-EBUSY, if the device is busy, or status pending;-EACCES, if no path specified inlpm is operational;-ENODEV, if the device is not operational.

Context

Interrupts disabled, ccw device lock held

intccw_device_halt(structccw_device*cdev,unsignedlongintparm)

halt I/O request processing

Parameters

structccw_device*cdev

target ccw device

unsignedlongintparm

interruption parameter to be returned upon conclusion of hsch

Description

ccw_device_halt() calls hsch oncdev’s subchannel.The interruption handler will echo back theintparm specified here, unlessanother interruption parameter is specified by a subsequent invocation ofccw_device_clear().

Return

0 on success,-ENODEV on device not operational,-EINVAL on invalid device state,-EBUSY on device busy or interrupt pending.

Context

Interrupts disabled, ccw device lock held

intccw_device_resume(structccw_device*cdev)

resume channel program execution

Parameters

structccw_device*cdev

target ccw device

Description

ccw_device_resume() calls rsch oncdev’s subchannel.

Return

0 on success,-ENODEV on device not operational,-EINVAL on invalid device state,-EBUSY on device busy or interrupt pending.

Context

Interrupts disabled, ccw device lock held

structciw*ccw_device_get_ciw(structccw_device*cdev,__u32ct)

Search for CIW command in extended sense data.

Parameters

structccw_device*cdev

ccw device to inspect

__u32ct

command type to look for

Description

During SenseID, command information words (CIWs) describing specialcommands available to the device may have been stored in the extendedsense data. This function searches for CIWs of a specified commandtype in the extended sense data.

Return

NULL if no extended sense data has been stored or if no CIW of thespecified command type could be found,else a pointer to the CIW of the specified command type.

__u8ccw_device_get_path_mask(structccw_device*cdev)

get currently available paths

Parameters

structccw_device*cdev

ccw device to be queried

Return

0 if no subchannel for the device is available,else the mask of currently available paths for the ccw device’s subchannel.

structchannel_path_desc_fmt0*ccw_device_get_chp_desc(structccw_device*cdev,intchp_idx)

return newly allocated channel-path descriptor

Parameters

structccw_device*cdev

device to obtain the descriptor for

intchp_idx

index of the channel path

Description

On success return a newly allocated copy of the channel-path descriptiondata associated with the given channel path. ReturnNULL on error.

u8*ccw_device_get_util_str(structccw_device*cdev,intchp_idx)

return newly allocated utility strings

Parameters

structccw_device*cdev

device to obtain the utility strings for

intchp_idx

index of the channel path

Description

On success return a newly allocated copy of the utility stringsassociated with the given channel path. ReturnNULL on error.

voidccw_device_get_id(structccw_device*cdev,structccw_dev_id*dev_id)

obtain a ccw device id

Parameters

structccw_device*cdev

device to obtain the id for

structccw_dev_id*dev_id

where to fill in the values

intccw_device_tm_start_timeout_key(structccw_device*cdev,structtcw*tcw,unsignedlongintparm,u8lpm,u8key,intexpires)

perform start function

Parameters

structccw_device*cdev

ccw device on which to perform the start function

structtcw*tcw

transport-command word to be started

unsignedlongintparm

user defined parameter to be passed to the interrupt handler

u8lpm

mask of paths to use

u8key

storage key to use for storage access

intexpires

time span in jiffies after which to abort request

Description

Start the tcw on the given ccw device. Return zero on success, non-zerootherwise.

intccw_device_tm_start_key(structccw_device*cdev,structtcw*tcw,unsignedlongintparm,u8lpm,u8key)

perform start function

Parameters

structccw_device*cdev

ccw device on which to perform the start function

structtcw*tcw

transport-command word to be started

unsignedlongintparm

user defined parameter to be passed to the interrupt handler

u8lpm

mask of paths to use

u8key

storage key to use for storage access

Description

Start the tcw on the given ccw device. Return zero on success, non-zerootherwise.

intccw_device_tm_start(structccw_device*cdev,structtcw*tcw,unsignedlongintparm,u8lpm)

perform start function

Parameters

structccw_device*cdev

ccw device on which to perform the start function

structtcw*tcw

transport-command word to be started

unsignedlongintparm

user defined parameter to be passed to the interrupt handler

u8lpm

mask of paths to use

Description

Start the tcw on the given ccw device. Return zero on success, non-zerootherwise.

intccw_device_tm_start_timeout(structccw_device*cdev,structtcw*tcw,unsignedlongintparm,u8lpm,intexpires)

perform start function

Parameters

structccw_device*cdev

ccw device on which to perform the start function

structtcw*tcw

transport-command word to be started

unsignedlongintparm

user defined parameter to be passed to the interrupt handler

u8lpm

mask of paths to use

intexpires

time span in jiffies after which to abort request

Description

Start the tcw on the given ccw device. Return zero on success, non-zerootherwise.

intccw_device_get_mdc(structccw_device*cdev,u8mask)

accumulate max data count

Parameters

structccw_device*cdev

ccw device for which the max data count is accumulated

u8mask

mask of paths to use

Description

Return the number of 64K-bytes blocks all paths at least supportfor a transport command. Return value 0 indicates failure.

intccw_device_tm_intrg(structccw_device*cdev)

perform interrogate function

Parameters

structccw_device*cdev

ccw device on which to perform the interrogate function

Description

Perform an interrogate function on the given ccw device. Return zero onsuccess, non-zero otherwise.

voidccw_device_get_schid(structccw_device*cdev,structsubchannel_id*schid)

obtain a subchannel id

Parameters

structccw_device*cdev

device to obtain the id for

structsubchannel_id*schid

where to fill in the values

intccw_device_pnso(structccw_device*cdev,structchsc_pnso_area*pnso_area,u8oc,structchsc_pnso_resume_tokenresume_token,intcnc)

Perform Network-Subchannel Operation

Parameters

structccw_device*cdev

device on which PNSO is performed

structchsc_pnso_area*pnso_area

request and response block for the operation

u8oc

Operation Code

structchsc_pnso_resume_tokenresume_token

resume token for multiblock response

intcnc

Boolean change-notification control

Description

pnso_area must be allocated by the caller with get_zeroed_page(GFP_KERNEL)

Returns 0 on success.

intccw_device_get_cssid(structccw_device*cdev,u8*cssid)

obtain Channel Subsystem ID

Parameters

structccw_device*cdev

device to obtain the CSSID for

u8*cssid

The resulting Channel Subsystem ID

intccw_device_get_iid(structccw_device*cdev,u8*iid)

obtain MIF-image ID

Parameters

structccw_device*cdev

device to obtain the MIF-image ID for

u8*iid

The resulting MIF-image ID

intccw_device_get_chpid(structccw_device*cdev,intchp_idx,u8*chpid)

obtain Channel Path ID

Parameters

structccw_device*cdev

device to obtain the Channel Path ID for

intchp_idx

Index of the channel path

u8*chpid

The resulting Channel Path ID

intccw_device_get_chid(structccw_device*cdev,intchp_idx,u16*chid)

obtain Channel ID associated with specified CHPID

Parameters

structccw_device*cdev

device to obtain the Channel ID for

intchp_idx

Index of the channel path

u16*chid

The resulting Channel ID

The channel-measurement facility

The channel-measurement facility provides a means to collect measurementdata which is made available by the channel subsystem for each channelattached device.

structcmbdata

channel measurement block data for user space

Definition:

struct cmbdata {    __u64 size;    __u64 elapsed_time;    __u64 ssch_rsch_count;    __u64 sample_count;    __u64 device_connect_time;    __u64 function_pending_time;    __u64 device_disconnect_time;    __u64 control_unit_queuing_time;    __u64 device_active_only_time;    __u64 device_busy_time;    __u64 initial_command_response_time;};

Members

size

size of the stored data

elapsed_time

time since last sampling

ssch_rsch_count

number of ssch and rsch

sample_count

number of samples

device_connect_time

time of device connect

function_pending_time

time of function pending

device_disconnect_time

time of device disconnect

control_unit_queuing_time

time of control unit queuing

device_active_only_time

time of device active only

device_busy_time

time of device busy (ext. format)

initial_command_response_time

initial command response time (ext. format)

Description

All values are stored as 64 bit for simplicity, especiallyin 32 bit emulation mode. All time values are normalized tonanoseconds.Currently, two formats are known, which differ by the size ofthis structure, i.e. the last two members are only set whenthe extended channel measurement facility (first shipped inz990 machines) is activated.Potentially, more fields could be added, which would result in anew ioctl number.

intenable_cmf(structccw_device*cdev)

switch on the channel measurement for a specific device

Parameters

structccw_device*cdev

The ccw device to be enabled

Description

Enable channel measurements forcdev. If this is called on a devicefor which channel measurement is already enabled a reset of themeasurement data is triggered.

Return

0 for success or a negative error value.

Context

non-atomic

intdisable_cmf(structccw_device*cdev)

switch off the channel measurement for a specific device

Parameters

structccw_device*cdev

The ccw device to be disabled

Return

0 for success or a negative error value.

Context

non-atomic

u64cmf_read(structccw_device*cdev,intindex)

read one value from the current channel measurement block

Parameters

structccw_device*cdev

the channel to be read

intindex

the index of the value to be read

Return

The value read or0 if the value cannot be read.

Context

any

intcmf_readall(structccw_device*cdev,structcmbdata*data)

read the current channel measurement block

Parameters

structccw_device*cdev

the channel to be read

structcmbdata*data

a pointer to a data block that will be filled

Return

0 on success, a negative error value otherwise.

Context

any

The ccwgroup bus

The ccwgroup bus only contains artificial devices, created by the user.Many networking devices (e.g. qeth) are in fact composed of several ccwdevices (like read, write and data channel for qeth). The ccwgroup busprovides a mechanism to create a meta-device which contains those ccwdevices as slave devices and can be associated with the netdevice.

ccw group devices

structccwgroup_device

ccw group device

Definition:

struct ccwgroup_device {    enum {        CCWGROUP_OFFLINE,        CCWGROUP_ONLINE,    } state;    unsigned int count;    struct device   dev;    struct work_struct ungroup_work;    struct ccw_device *cdev[];};

Members

state

online/offline state

count

number of attached slave devices

dev

embedded device structure

ungroup_work

used to ungroup the ccwgroup device

cdev

variable number of slave devices, allocated as needed

structccwgroup_driver

driver for ccw group devices

Definition:

struct ccwgroup_driver {    int (*setup) (struct ccwgroup_device *);    void (*remove) (struct ccwgroup_device *);    int (*set_online) (struct ccwgroup_device *);    int (*set_offline) (struct ccwgroup_device *);    void (*shutdown)(struct ccwgroup_device *);    struct device_driver driver;    struct ccw_driver *ccw_driver;};

Members

setup

function called during device creation to setup the device

remove

function called on remove

set_online

function called when device is set online

set_offline

function called when device is set offline

shutdown

function called when device is shut down

driver

embedded driver structure

ccw_driver

supported ccw_driver (optional)

intccwgroup_set_online(structccwgroup_device*gdev)

enable a ccwgroup device

Parameters

structccwgroup_device*gdev

target ccwgroup device

Description

This function attempts to put the ccwgroup device into the online state.

Return

0 on success and a negative error value on failure.

intccwgroup_set_offline(structccwgroup_device*gdev,boolcall_gdrv)

disable a ccwgroup device

Parameters

structccwgroup_device*gdev

target ccwgroup device

boolcall_gdrv

Call the registered gdrv set_offline function

Description

This function attempts to put the ccwgroup device into the offline state.

Return

0 on success and a negative error value on failure.

intccwgroup_create_dev(structdevice*parent,structccwgroup_driver*gdrv,intnum_devices,constchar*buf)

create and register a ccw group device

Parameters

structdevice*parent

parent device for the new device

structccwgroup_driver*gdrv

driver for the new group device

intnum_devices

number of slave devices

constchar*buf

buffer containing comma separated bus ids of slave devices

Description

Create and register a new ccw group device as a child ofparent. Slavedevices are obtained from the list of bus ids given inbuf.

Return

0 on success and an error code on failure.

Context

non-atomic

intccwgroup_driver_register(structccwgroup_driver*cdriver)

register a ccw group driver

Parameters

structccwgroup_driver*cdriver

driver to be registered

Description

This function is mainly a wrapper arounddriver_register().

voidccwgroup_driver_unregister(structccwgroup_driver*cdriver)

deregister a ccw group driver

Parameters

structccwgroup_driver*cdriver

driver to be deregistered

Description

This function is mainly a wrapper arounddriver_unregister().

intccwgroup_probe_ccwdev(structccw_device*cdev)

probe function for slave devices

Parameters

structccw_device*cdev

ccw device to be probed

Description

This is a dummy probe function for ccw devices that are slave devices ina ccw group device.

Return

always0

voidccwgroup_remove_ccwdev(structccw_device*cdev)

remove function for slave devices

Parameters

structccw_device*cdev

ccw device to be removed

Description

This is a remove function for ccw devices that are slave devices in a ccwgroup device. It sets the ccw device offline and also deregisters theembedding ccw group device.

Generic interfaces

The following section contains interfaces in use not only by driversdealing with ccw devices, but drivers for various other s390 hardwareas well.

Adapter interrupts

The common I/O layer provides helper functions for dealing with adapterinterrupts and interrupt vectors.

intregister_adapter_interrupt(structairq_struct*airq)

register adapter interrupt handler

Parameters

structairq_struct*airq

pointer to adapter interrupt descriptor

Description

Returns 0 on success, or -EINVAL.

voidunregister_adapter_interrupt(structairq_struct*airq)

unregister adapter interrupt handler

Parameters

structairq_struct*airq

pointer to adapter interrupt descriptor

structairq_iv*airq_iv_create(unsignedlongbits,unsignedlongflags,unsignedlong*vec)

create an interrupt vector

Parameters

unsignedlongbits

number of bits in the interrupt vector

unsignedlongflags

allocation flags

unsignedlong*vec

pointer to pinned guest memory if AIRQ_IV_GUESTVEC

Description

Returns a pointer to an interrupt vector structure

voidairq_iv_release(structairq_iv*iv)

release an interrupt vector

Parameters

structairq_iv*iv

pointer to interrupt vector structure

unsignedlongairq_iv_alloc(structairq_iv*iv,unsignedlongnum)

allocate irq bits from an interrupt vector

Parameters

structairq_iv*iv

pointer to an interrupt vector structure

unsignedlongnum

number of consecutive irq bits to allocate

Description

Returns the bit number of the first irq in the allocated block of irqs,or -1UL if no bit is available or the AIRQ_IV_ALLOC flag has not beenspecified

voidairq_iv_free(structairq_iv*iv,unsignedlongbit,unsignedlongnum)

free irq bits of an interrupt vector

Parameters

structairq_iv*iv

pointer to interrupt vector structure

unsignedlongbit

number of the first irq bit to free

unsignedlongnum

number of consecutive irq bits to free

unsignedlongairq_iv_scan(structairq_iv*iv,unsignedlongstart,unsignedlongend)

scan interrupt vector for non-zero bits

Parameters

structairq_iv*iv

pointer to interrupt vector structure

unsignedlongstart

bit number to start the search

unsignedlongend

bit number to end the search

Description

Returns the bit number of the next non-zero interrupt bit, or-1UL if the scan completed without finding any more any non-zero bits.