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 underDocumentation/s390/driver-model.rst.
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. SeeDocumentation/s390/vfio-ccw.rst.
- 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.
- struct
ccw1¶ channel command word
Definition
struct ccw1 { __u8 cmd_code; __u8 flags; __u16 count; __u32 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.
- struct
ccw0¶ 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.
- struct
erw¶ 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
- struct
erw_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
- struct
sublog¶ 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
- struct
esw0¶ Format 0 Extended Status Word (ESW)
Definition
struct esw0 { struct sublog sublog; struct erw erw; __u32 faddr[2]; __u32 saddr;};Members
sublog- subchannel logout
erw- extended report word
faddr- failing storage address
saddr- secondary ccw address
- struct
esw1¶ 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
- struct
esw2¶ 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
- struct
esw3¶ 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
- struct
esw_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
- struct
irb¶ 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).
- struct
ciw¶ 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
- struct
ccw_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.
- int
ccw_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
1if the two structures are equal field-by-field,0if not.
Context
any
- u8
pathmask_to_pos(u8 mask)¶ 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.
- struct
ccw_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).
- struct
ccw_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 *); int (*prepare) (struct ccw_device *); void (*complete) (struct ccw_device *); int (*freeze)(struct ccw_device *); int (*thaw) (struct ccw_device *); int (*restore)(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
prepare- prepare for pm state transition
complete- undo work done inprepare
freeze- callback for freezing during hibernation snapshotting
thaw- undo work done infreeze
restore- callback for restoring after hibernation
uc_handler- callback for unit check handler
driver- embedded device driver structure
int_class- interruption class to use for accounting interrupts
- int
ccw_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’s set_offline() function forcdev, ifgiven, and then disablescdev.
Return
0on success and a negative error value on failure.
Context
enabled, ccw device lock not held
- int
ccw_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’s set_online()function forcdev, if given. If set_online() returns an error,cdev isdisabled again.
Return
0on 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;elseNULLis returned.
- structccw_device *
get_ccwdev_by_busid(structccw_driver * cdrv, const char * 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; elseNULLis returned.
- int
ccw_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
0on success and a negative error value on failure.
- void
ccw_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().
- int
ccw_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.
- int
ccw_device_set_options_mask(structccw_device * cdev, unsigned long flags)¶ 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
0on success, -EINVALon an invalid flag combination.
- int
ccw_device_set_options(structccw_device * cdev, unsigned long flags)¶ 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
0on success, -EINVALif an invalid flag combination would ensue.
- void
ccw_device_clear_options(structccw_device * cdev, unsigned long flags)¶ 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.
- int
ccw_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.
- int
ccw_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.
- int
ccw_device_clear(structccw_device * cdev, unsigned long intparm)¶ 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
0on success,-ENODEVon device not operational,-EINVALon invalid device state.
Context
Interrupts disabled, ccw device lock held
- int
ccw_device_start_timeout_key(structccw_device * cdev, structccw1 * cpa, unsigned long intparm, __u8 lpm, __u8 key, unsigned long flags, int expires)¶ 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
- int
ccw_device_start_key(structccw_device * cdev, structccw1 * cpa, unsigned long intparm, __u8 lpm, __u8 key, unsigned long flags)¶ 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
- int
ccw_device_start(structccw_device * cdev, structccw1 * cpa, unsigned long intparm, __u8 lpm, unsigned long flags)¶ 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
- int
ccw_device_start_timeout(structccw_device * cdev, structccw1 * cpa, unsigned long intparm, __u8 lpm, unsigned long flags, int expires)¶ 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
- int
ccw_device_halt(structccw_device * cdev, unsigned long intparm)¶ 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
0on success,-ENODEVon device not operational,-EINVALon invalid device state,-EBUSYon device busy or interrupt pending.
Context
Interrupts disabled, ccw device lock held
- int
ccw_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
0on success,-ENODEVon device not operational,-EINVALon invalid device state,-EBUSYon device busy or interrupt pending.
Context
Interrupts disabled, ccw device lock held
- structciw *
ccw_device_get_ciw(structccw_device * cdev, __u32 ct)¶ 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
NULLif 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.
- __u8
ccw_device_get_path_mask(structccw_device * cdev)¶ get currently available paths
Parameters
structccw_device*cdev- ccw device to be queried
Return
0if no subchannel for the device is available,else the mask of currently available paths for the ccw device’s subchannel.
- struct channel_path_desc_fmt0 *
ccw_device_get_chp_desc(structccw_device * cdev, int chp_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, int chp_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.
- void
ccw_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
- int
ccw_device_tm_start_timeout_key(structccw_device * cdev, struct tcw * tcw, unsigned long intparm, u8 lpm, u8 key, int expires)¶ 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.
- int
ccw_device_tm_start_key(structccw_device * cdev, struct tcw * tcw, unsigned long intparm, u8 lpm, u8 key)¶ 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.
- int
ccw_device_tm_start(structccw_device * cdev, struct tcw * tcw, unsigned long intparm, u8 lpm)¶ 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.
- int
ccw_device_tm_start_timeout(structccw_device * cdev, struct tcw * tcw, unsigned long intparm, u8 lpm, int expires)¶ 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.
- int
ccw_device_get_mdc(structccw_device * cdev, u8 mask)¶ 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.
- int
ccw_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.
- void
ccw_device_get_schid(structccw_device * cdev, struct subchannel_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
- int
ccw_device_pnso(structccw_device * cdev, struct chsc_pnso_area * pnso_area, struct chsc_pnso_resume_token resume_token, int cnc)¶ 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
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.
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.
- struct
cmbdata¶ 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.
- int
enable_cmf(structccw_device * cdev)¶ switch on the channel measurement for a specific device
Parameters
structccw_device*cdevThe ccw device to be enabled
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
- int
disable_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
- u64
cmf_read(structccw_device * cdev, int index)¶ 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
- int
cmf_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¶
- struct
ccwgroup_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[0];};Members
state- online/offline state
count- number of attached slave devices
dev- embedded device structure
ungroup_work- work to be done when a ccwgroup notifier has actiontype
BUS_NOTIFY_UNBIND_DRIVER cdev- variable number of slave devices, allocated as needed
- struct
ccwgroup_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)
- int
ccwgroup_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
0on success and a negative error value on failure.
- int
ccwgroup_set_offline(structccwgroup_device * gdev)¶ disable a ccwgroup device
Parameters
structccwgroup_device*gdev- target ccwgroup device
Description
This function attempts to put the ccwgroup device into the offline state.
Return
0on success and a negative error value on failure.
- int
ccwgroup_create_dev(structdevice * parent, structccwgroup_driver * gdrv, int num_devices, const char * 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
0on success and an error code on failure.
Context
non-atomic
- int
ccwgroup_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().
- void
ccwgroup_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().
- structccwgroup_device *
get_ccwgroupdev_by_busid(structccwgroup_driver * gdrv, char * bus_id)¶ obtain device from a bus id
Parameters
structccwgroup_driver*gdrv- driver the device is owned by
char*bus_id- bus id of the device to be searched
Description
This function searches all devices owned bygdrv 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; elseNULLis returned.
- int
ccwgroup_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
- void
ccwgroup_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.
- int
register_adapter_interrupt(struct airq_struct * airq)¶ register adapter interrupt handler
Parameters
structairq_struct*airq- pointer to adapter interrupt descriptor
Description
Returns 0 on success, or -EINVAL.
- void
unregister_adapter_interrupt(struct airq_struct * airq)¶ unregister adapter interrupt handler
Parameters
structairq_struct*airq- pointer to adapter interrupt descriptor
- struct airq_iv *
airq_iv_create(unsigned long bits, unsigned long flags)¶ create an interrupt vector
Parameters
unsignedlongbits- number of bits in the interrupt vector
unsignedlongflags- allocation flags
Description
Returns a pointer to an interrupt vector structure
- void
airq_iv_release(struct airq_iv * iv)¶ release an interrupt vector
Parameters
structairq_iv*iv- pointer to interrupt vector structure
- unsigned long
airq_iv_alloc(struct airq_iv * iv, unsigned long num)¶ 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
- void
airq_iv_free(struct airq_iv * iv, unsigned long bit, unsigned long num)¶ 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
- unsigned long
airq_iv_scan(struct airq_iv * iv, unsigned long start, unsigned long end)¶ 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.