* The interrupt handlers must be adapted to use a ccw_device as argument.
Moreover, they don't return a devstat, but an irb.
* Before initiating an io, the options must be set via ccw_device_set_options().
-
-read_dev_chars()
- read device characteristics
-
-read_conf_data()
-read_conf_data_lpm()
- read configuration data.
+* Instead of calling read_dev_chars()/read_conf_data(), the driver issues
+ the channel program and handles the interrupt itself.
ccw_device_get_ciw()
get commands from extended sense data.
Linux/390 common device support (CDS) provides to allow for device specific
driver implementations on the IBM ESA/390 hardware platform. Those interfaces
intend to provide the functionality required by every device driver
-implementaion to allow to drive a specific hardware device on the ESA/390
+implementation to allow to drive a specific hardware device on the ESA/390
platform. Some of the interface routines are specific to Linux/390 and some
of them can be found on other Linux platforms implementations too.
Miscellaneous function prototypes, data declarations, and macro definitions
can be found in the architecture specific C header file
-linux/include/asm-s390/irq.h.
+linux/arch/s390/include/asm/irq.h.
Overview of CDS interface concepts
provides a unified view of the devices physically attached to the systems.
Though the ESA/390 hardware platform knows about a huge variety of different
peripheral attachments like disk devices (aka. DASDs), tapes, communication
-controllers, etc. they can all by accessed by a well defined access method and
+controllers, etc. they can all be accessed by a well defined access method and
they are presenting I/O completion a unified way : I/O interruptions. Every
single device is uniquely identified to the system by a so called subchannel,
where the ESA/390 architecture allows for 64k devices be attached.
has to call every single device driver registered on this IRQ in order to
determine the device driver owning the device that raised the interrupt.
-In order not to introduce a new I/O concept to the common Linux code,
-Linux/390 preserves the IRQ concept and semantically maps the ESA/390
-subchannels to Linux as IRQs. This allows Linux/390 to support up to 64k
-different IRQs, uniquely representig a single device each.
-
Up to kernel 2.4, Linux/390 used to provide interfaces via the IRQ (subchannel).
For internal use of the common I/O layer, these are still there. However,
device drivers should use the new calling interface via the ccw_device only.
of those devices is uniquely defined by a so called subchannel by the ESA/390
channel subsystem. While the subchannel numbers are system generated, each
subchannel also takes a user defined attribute, the so called device number.
-Both subchannel number and device number cannot exceed 65535. During driverfs
+Both subchannel number and device number cannot exceed 65535. During sysfs
initialisation, the information about control unit type and device types that
imply specific I/O commands (channel command words - CCWs) in order to operate
the device are gathered. Device drivers can retrieve this set of hardware
support using the information saved in the struct ccw_device given to them.
This methods implies that Linux/390 doesn't require to probe for free (not
armed) interrupt request lines (IRQs) to drive its devices with. Where
-applicable, the device drivers can use the read_dev_chars() to retrieve device
-characteristics. This can be done without having to request device ownership
-previously.
+applicable, the device drivers can use issue the READ DEVICE CHARACTERISTICS
+ccw to retrieve device characteristics in its online routine.
In order to allow for easy I/O initiation the CDS layer provides a
ccw_device_start() interface that takes a device specific channel program (one
also covered by ccw_device_halt().
-read_dev_chars() - Read Device Characteristics
-
-This routine returns the characteristics for the device specified.
-
-The function is meant to be called with an irq handler in place; that is,
-at earliest during set_online() processing.
-
-While the request is processed synchronously, the device interrupt
-handler is called for final ending status. In case of error situations the
-interrupt handler may recover appropriately. The device irq handler can
-recognize the corresponding interrupts by the interruption parameter be
-0x00524443. The ccw_device must not be locked prior to calling read_dev_chars().
-
-The function may be called enabled or disabled.
-
-int read_dev_chars(struct ccw_device *cdev, void **buffer, int length );
-
-cdev - the ccw_device the information is requested for.
-buffer - pointer to a buffer pointer. The buffer pointer itself
- must contain a valid buffer area.
-length - length of the buffer provided.
-
-The read_dev_chars() function returns :
-
- 0 - successful completion
--ENODEV - cdev invalid
--EINVAL - an invalid parameter was detected, or the function was called early.
--EBUSY - an irrecoverable I/O error occurred or the device is not
- operational.
-
-
-read_conf_data(), read_conf_data_lpm() - Read Configuration Data
-
-Retrieve the device dependent configuration data. Please have a look at your
-device dependent I/O commands for the device specific layout of the node
-descriptor elements. read_conf_data_lpm() will retrieve the configuration data
-for a specific path.
-
-The function is meant to be called with the device already enabled; that is,
-at earliest during set_online() processing.
-
-The function may be called enabled or disabled, but the device must not be
-locked
-
-int read_conf_data(struct ccw_device, void **buffer, int *length);
-int read_conf_data_lpm(struct ccw_device, void **buffer, int *length, __u8 lpm);
-
-cdev - the ccw_device the data is requested for.
-buffer - Pointer to a buffer pointer. The read_conf_data() routine
- will allocate a buffer and initialize the buffer pointer
- accordingly. It's the device driver's responsibility to
- release the kernel memory if no longer needed.
-length - Length of the buffer allocated and retrieved.
-lpm - Logical path mask to be used for retrieving the data. If
- zero the data is retrieved on the next path available.
-
-The read_conf_data() function returns :
- 0 - Successful completion
--ENODEV - cdev invalid.
--EINVAL - An invalid parameter was detected, or the function was called early.
--EIO - An irrecoverable I/O error occurred or the device is
- not operational.
--ENOMEM - The read_conf_data() routine couldn't obtain storage.
--EOPNOTSUPP - The device doesn't support the read configuration
- data command.
-
-
get_ciw() - get command information word
This call enables a device driver to get information about supported commands
The ccw_device_start() function returns :
0 - successful completion or request successfully initiated
--EBUSY - The device is currently processing a previous I/O request, or ther is
+-EBUSY - The device is currently processing a previous I/O request, or there is
a status pending at the device.
-ENODEV - cdev is invalid, the device is not operational or the ccw_device is
not online.
timeout value
-EIO: the common I/O layer terminated the request due to an error state
-If the concurrent sense flag in the extended status word in the irb is set, the
-field irb->scsw.count describes the numer of device specific sense bytes
-available in the extended control word irb->scsw.ecw[0]. No device sensing by
-the device driver itself is required.
+If the concurrent sense flag in the extended status word (esw) in the irb is
+set, the field erw.scnt in the esw describes the number of device specific
+sense bytes available in the extended control word irb->scsw.ecw[]. No device
+sensing by the device driver itself is required.
The device interrupt handler can use the following definitions to investigate
the primary unit check source coded in sense byte 0 :
Usage Notes :
-Prior to call ccw_device_start() the device driver must assure disabled state,
-i.e. the I/O mask value in the PSW must be disabled. This can be accomplished
-by calling local_save_flags( flags). The current PSW flags are preserved and
-can be restored by local_irq_restore( flags) at a later time.
-
-If the device driver violates this rule while running in a uni-processor
-environment an interrupt might be presented prior to the ccw_device_start()
-routine returning to the device driver main path. In this case we will end in a
-deadlock situation as the interrupt handler will try to obtain the irq
-lock the device driver still owns (see below) !
-
-The driver must assure to hold the device specific lock. This can be
-accomplished by
-
-(i) spin_lock(get_ccwdev_lock(cdev)), or
-(ii) spin_lock_irqsave(get_ccwdev_lock(cdev), flags)
-
-Option (i) should be used if the calling routine is running disabled for
-I/O interrupts (see above) already. Option (ii) obtains the device gate und
-puts the CPU into I/O disabled state by preserving the current PSW flags.
+ccw_device_start() must be called disabled and with the ccw device lock held.
The device driver is allowed to issue the next ccw_device_start() call from
within its interrupt handler already. It is not required to schedule a
-bottom-half, unless an non deterministically long running error recovery procedure
+bottom-half, unless a non deterministically long running error recovery procedure
or similar needs to be scheduled. During I/O processing the Linux/390 generic
I/O device driver support has already obtained the IRQ lock, i.e. the handler
must not try to obtain it again when calling ccw_device_start() or we end in a
case all I/O interruptions are presented to the device driver until final
status is recognized.
-If a device is able to recover from asynchronosly presented I/O errors, it can
+If a device is able to recover from asynchronously presented I/O errors, it can
perform overlapping I/O using the DOIO_EARLY_NOTIFICATION flag. While some
devices always report channel-end and device-end together, with a single
interrupt, others present primary status (channel-end) when the channel is
cdev - ccw_device the resume operation is requested for
-The resume_IO() function returns:
+The ccw_device_resume() function returns:
0 - suspended channel program is resumed
-EBUSY - status pending
a halt subchannel (HSCH) I/O command. For those purposes the ccw_device_halt()
command is provided.
+ccw_device_halt() must be called disabled and with the ccw device lock held.
+
int ccw_device_halt(struct ccw_device *cdev,
unsigned long intparm);
The ccw_device_halt() function returns :
- 0 - successful completion or request successfully initiated
+ 0 - request successfully initiated
-EBUSY - the device is currently busy, or status pending.
-ENODEV - cdev invalid.
-EINVAL - The device is not operational or the ccw device is not online.
read to a network device (with or without PCI flag) a ccw_device_halt()
is required to end the pending operation.
+ccw_device_clear() - Terminage I/O Request Processing
+
+In order to terminate all I/O processing at the subchannel, the clear subchannel
+(CSCH) command is used. It can be issued via ccw_device_clear().
+
+ccw_device_clear() must be called disabled and with the ccw device lock held.
+
+int ccw_device_clear(struct ccw_device *cdev, unsigned long intparm);
+
+cdev: ccw_device the clear operation is requested for
+intparm: interruption parameter (see ccw_device_halt())
+
+The ccw_device_clear() function returns:
+
+ 0 - request successfully initiated
+-ENODEV - cdev invalid
+-EINVAL - The device is not operational or the ccw device is not online.
Miscellaneous Support Routines