]> git.neil.brown.name Git - history.git/commitdiff
[PATCH] s390: channel subsystem docu.
authorMartin Schwidefsky <schwidefsky@de.ibm.com>
Fri, 6 Dec 2002 08:19:04 +0000 (00:19 -0800)
committerLinus Torvalds <torvalds@penguin.transmeta.com>
Fri, 6 Dec 2002 08:19:04 +0000 (00:19 -0800)
Documentation changes for common i/o.

Documentation/s390/cds.txt
Documentation/s390/chandev.8 [deleted file]
Documentation/s390/driver-model.txt [new file with mode: 0644]

index 38aeab5b50dfa7e3dbd261b66b545e7881be9a2a..ad3ffdb664e87f648841f6908ead559ca8cf40e9 100644 (file)
@@ -1,14 +1,13 @@
-Linux/390
+Linux for S/390 and zSeries
 
 Common Device Support (CDS)
 Device Driver I/O Support Routines
 
-Author : Ingo Adlung
+Authors : Ingo Adlung
+         Cornelia Huck
 
 Copyright, IBM Corp. 1999-2002
 
-ChangeLog: 02/01/2002   Cornelia Huck    brought up-to-date
-
 Introduction
 
 This document describes the common device support routines for Linux/390.
@@ -34,12 +33,24 @@ The common device support layer comprises the I/O support routines defined
 below. Some of them implement common Linux device driver interfaces, while 
 some of them are ESA/390 platform specific.
 
-get_dev_info_by_irq() / get_dev_info_by_devno()        
-   allow a device driver to determine the devices attached (visible) to the
-   system and their current status.
-
-get_irq_by_devno() / get_devno_by_irq()        
-   get irq (subchannel) from device number and vice versa.
+Note:
+In order to write a driver for S/390, you also need to look into the interface
+described in Documentation/s390/driver-model.txt.
+
+Note for porting drivers from 2.4:
+The major changes are:
+* The functions use a ccw_device instead of an irq (subchannel).
+* All drivers must define a ccw_driver (see driver-model.txt) and the associated
+  functions.
+* request_irq() and free_irq() are no longer done by the driver.
+* The oper_handler is (kindof) replaced by the probe() and set_online() functions
+  of the ccw_driver.
+* The not_oper_handler is (kindof) replaced by the remove() and set_offline()
+  functions of the ccw_driver.
+* The channel device layer is gone.
+* 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
@@ -47,29 +58,16 @@ read_dev_chars()
 read_conf_data()
    read configuration data.
 
-request_irq()  
-   obtain ownership for a specific device.
-
-s390_request_irq_special()
-   obtain ownership for a specific device. Similar to request_irq(), but
-   allows for device not operational notification too.
-
-free_irq()     
-   release ownership for a specific device.
+ccw_device_get_ciw()
+   get commands from extended sense data.
 
-disable_irq()  
-   disable a device from presenting interrupts.
-
-enable_irq()   
-   enable a device, allowing for I/O interrupts.
-
-do_IO()        
+ccw_device_start()     
    initiate an I/O request.
 
-resume_IO()
+ccw_device_resume()
    resume channel program execution.
 
-halt_IO()      
+ccw_device_halt()      
    terminate the current I/O request processed on the device.
 
 do_IRQ()       
@@ -133,258 +131,71 @@ 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.
+
 During its startup the Linux/390 system checks for peripheral devices. Each
 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 can not exceed 65535. The
-init_IRQ() routine gathers 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. Device drivers can retrieve this set of hardware
+Both subchannel number and device number can not exceed 65535. During driverfs
+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
 information during their initialization step to recognize the devices they
-support using get_dev_info_by_irq() or get_dev_info_by_devno() respectively.
+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.
 
-When a device driver has recognized a device it wants to claim ownership for,
-it calls request_irq() with the device's subchannel id serving as pseudo irq
-line. One of the required parameters it has to specify is dev_id, defining a
-device status block which the CDS layer will use to notify the device driver's
-interrupt handler about interrupt information observed. It depends on the
-device driver to properly handle those interrupts.
-
-In order to allow for easy I/O initiation the CDS layer provides a do_IO()
-interface that takes a device specific channel program (one or more CCWs) as
-input sets up the required architecture specific control blocks and initiates
-an I/O request on behalf of the device driver. The do_IO() routine allows for
-different I/O methods, synchronous and asynchronous, and allows to specify
-whether it expects the CDS layer to notify the device driver for every
-interrupt it observes, or with final status only. It also provides a scheme
-to allow for overlapped I/O processing. See do_IO() for more details. A device
-driver must never issue ESA/390 I/O commands itself, but must use the
-Linux/390 CDS interfaces instead.
+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
+or more CCWs) as input sets up the required architecture specific control blocks
+and initiates an I/O request on behalf of the device driver. The
+ccw_device_start() routine allows to specify whether it expects the CDS layer
+to notify the device driver for every interrupt it observes, or with final status
+only. See ccw_device_start() for more details. A device driver must never issue
+ESA/390 I/O commands itself, but must use the Linux/390 CDS interfaces instead.
 
 For long running I/O request to be canceled, the CDS layer provides the
-halt_IO() function. Some devices require to initially issue a HALT SUBCHANNEL
-(HSCH) command without having pending I/O requests. This function is also
-covered by halt_IO().
-
-When done with a device, the device driver calls free_irq() to release its
-ownership for the device. During free_irq() processing the CDS layer also
-disables the device from presenting further interrupts - the device driver
-doesn't need to assure it. The device will be reenabled for interrupts with
-the next call to request_irq().
-
-
-
-get_irq_first() / get_irq_next() - Retrieve Information about available IRQs 
-
-A device driver can use those interface routines to retrieve information for 
-those IRQs only that have valid device information available. As 
-Linux for S/390 supports a maximum of 65535 subchannels (devices), it might 
-be a waste of CPU to scan for the max number of  devices while a fraction is 
-available/usable only. get_irq_first() will retrieve the first usable IRQ. 
-Using this as input get_irq_next() will retrieve the next IRQ available, etc..
-
-int get_irq_first( void );
-int get_irq_next( int irq );
-
-irq - defines the subchannel to start scanning with. This must be
-      a valid subchannel or an error is returned. 
-
-The get_irq_first() / get_irq_next() functions return:
-
-non-negative value - next available IRQ
-          -ENODEV  - no more IRQs available
-
-Example : 
-
- irq = get_irq_first();
- while ( irq != -ENODEV) 
- {
-  get_dev_info_by_irq( irq, &dinfo);
-  if (    dinfo.devno == devno_to_look_for 
-       || dinfo.sid_data.cu_type == cu_type_to_look_for )
-  {
-   do_some_action( irq, &dinfo ); 
-  } /* endif */
-    
-  irq = get_irq_next(irq);
- }
-
-get_dev_info_by_irq() / get_dev_info_by_devno() - Retrieve Device Information
-
-During system startup - init_IRQ() processing - the generic I/O device support
-checks for the devices available. For all devices found it collects the
-SenseID information. For those devices supporting the command it also obtains
-extended SenseID information.
-
-int get_dev_info_by_irq( int             irq,
-                         s390_dev_info_t *pdi);
-
-int get_dev_info_by_devno( __u16           devno,
-                           s390_dev_info_t *pdi);
-
-irq     - defines the subchannel status information is to be
-          returned for.
-devno   - device number.
-pdi     - pointer to a user buffer of type s390_dev_info_t that should
-          be filled with device specific information.
-
-typedef struct {
-     int          irq;                  /* irq, aka. subchannel */
-     __u16        devno;                /* device number */
-     unsigned int status;               /* device status */
-     senseid_t    sid_data;             /* senseID data */
-} s390_dev_info_t;                     
-
-irq       - subchannel.
-devno     - device number as configured in the IOCDS.
-status    - device status
-sid_data  - data obtained by a SenseID call
-
-Possible status values are :
-
-DEVSTAT_NOT_OPER - device was found not-operational. In this case
-                   the caller should disregard the sid_data
-                   buffer content.
-
-//
-// sense-id response buffer layout
-//
-typedef struct {
-  /* common part */
-      __u8           reserved;     /* always 0x'FF' */
-      __u16          cu_type;      /* control unit type */
-      __u8           cu_model;     /* control unit model */
-      __u16          dev_type;     /* device type */
-      __u8           dev_model;    /* device model */
-      __u8           unused;       /* padding byte */
-  /* extended part */
-      ciw_t    ciw[MAX_CIWS];      /* variable # of CIWs */
-}  __attribute__ ((packed,aligned(4))) senseid_t;
-
-MAX_CIWS is currently defined as 8.
-
-The ESA/390 I/O architecture defines certain device specific I/O functions.
-The device returns the device specific command code together with the SenseID
-data in so called Command Information Words (CIW) :
-
-typedef struct _ciw {
-   __u32        et       :  2; // entry type
-   __u32        reserved :  2; // reserved
-   __u32        ct       :  4; // command type
-   __u32        cmd      :  8; // command
-   __u32        count    : 16; // count
-} __attribute__ ((packed)) ciw_t;
-
-Possible CIW entry types are :
-
-#define CIW_TYPE_RDC    0x0;      // read configuration data
-#define CIW_TYPE_SII    0x1;      // set interface identifier
-#define CIW_TYPE_RNI    0x2;      // read node identifier
-
-The device driver may use these commands as appropriate.
-
-The get_dev_info_by_irq() / get_dev_info_by_devno() functions return:
-
-      0 - successful completion
--ENODEV - irq or devno don't specify a known subchannel or device
-          number.
--EINVAL - invalid devinfo value.
-
-Usage Notes :
-
-In order to scan for known devices a device driver should scan all irqs by
-calling     get_dev_info() until it returns -ENODEV as there aren't any more
-available devices.
-
-If a device driver wants to request ownership for a specific device, it must
-call request_irq() prior to be able to issue any I/O request for it, including
-above mentioned   device dependent commands.
-
-Please see the "ESA/390 Common I/O-Commandss and Self Description" manual,
-with IBM form number SA22-7204 for more details on how to read the Sense-ID
-output, CIWs and device independent commands.
-
-
-
-get_irq_by_devno() / get_devno_by_irq() - Convert device identifiers
-
-While some device drivers act on the irq (subchannel) only, others take user
-defined device configurations on device number base, according to the device
-numbers configured in the IOCDS. The following routines serve the purpose to
-convert irq values into device numbers and vice versa.
-
-int get_irq_by_devno( __u16 devno );
-
-unsigned int get_devno_by_irq( int irq );
-
-The functions return :
-
-the requested irq/devno values
--1 if the requested conversion can't be accomplished.
-
-This could either be caused by irq/devno be outside the valid range
-( value > 0xffff or value < 0 ) or not identifying a known device.
+ccw_device_halt() function. Some devices require to initially issue a HALT
+SUBCHANNEL (HSCH) command without having pending I/O requests. This function is
+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 without an irq handler be in place.
-However, the irq for the requested device must not be locked or this will
-cause a deadlock situation ! Further, the driver must assure that nobody
-else has claimed ownership for the requested irq yet or the owning device
-driver's internal accounting may be affected.
+The function is meant to be called with an irq handler in place; that is,
+at earliest during set_online() processing.
 
-In case of a registered interrupt handler, the interrupt handler must be
-able to properly react on interrupts related to the read_dev_chars() I/O
-commands. While the request is procesed synchronously, the device interrupt
+While the request is procesed 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. If using the function with an existing device interrupt handler
-in place, the irq must be locked prior to call read_dev_chars().
+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( int irq, void **buffer, int length );
+int read_dev_chars(struct ccw_device *cdev, void **buffer, int length );
 
-irq    - specifies the subchannel the device characteristic
-         retrieval is requested for
+cdev   - the ccw_device the information is requested for.
 buffer - pointer to a buffer pointer. The buffer pointer itself
-         may be NULL to have the function allocate a buffer or
          must contain a valid buffer area.
-length - length of the buffer provided or to be allocated.
+length - length of the buffer provided.
 
 The read_dev_chars() function returns :
 
       0 - successful completion
--ENODEV - irq doesn't specify a valid subchannel number
--EINVAL - an invalid parameter was detected
+-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.
 
-Usage Notes :
-
-The function can be used in two ways :
-
-If the caller doesn't provide a data buffer, read_dev_chars() allocates a
-data buffer and provides the device characteristics together. It's the
-caller's responsability to release the kernel memory if not longer needed.
-This behaviour is triggered by specifying a NULL buffer area (*buffer == NULL).
-
-Alternatively, if the user specifies a buffer area himself, nothing is
-allocated.
-
-In either case the caller must provide the data area length - for the buffer
-he specifies, or the buffer he wants to be allocated.
-
 
 read_conf_data() - Read Configuration Data
 
@@ -392,16 +203,15 @@ 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. 
 
-The function is meant to be called without an irq handler be in place. However,
-the irq for the requested device must not be locked or this will cause a 
-deadlock situation ! 
+The function is meant to be called with an irq handler in place; that is,
+at earliest during set_online() processing.
 
-The function may be called enabled or disabled.
+The function may be called enabled or disabled, but the device must not be
+locked
 
-int read_conf_data( int irq, void **buffer, int *length, __u8 lpm);
+int read_conf_data(struct ccw_device, void **buffer, int *length, __u8 lpm);
 
-irq    - Specifies the subchannel the configuration data is to be
-         retrieved for.
+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 responsability to
@@ -412,8 +222,8 @@ lpm    - Logical path mask to be used for retrieving the data. If
 
 The read_conf_data() function returns :
           0 - Successful completion
--ENODEV     - irq doesn't specify a valid subchannel number
--EINVAL     - An invalid parameter was detected
+-ENODEV     - cdev invalid.
+-EINVAL     - An invalid parameter was detected, or the function was called early.
 -EIO        - An irrecoverable I/O error occured or the device is
               not operational.
 -ENOMEM     - The read_conf_data() routine couldn't obtain storage.
@@ -421,356 +231,65 @@ The read_conf_data() function returns :
               data command.
 
 
-request_irq() - Request Device Ownership
-
-As previously discussed a device driver will scan for the devices its supports
-by calling get_dev_info(). Once it has found a device it will call
-request_irq() to request ownership for it. This call causes the subchannel to
-be enabled for interrupts if it was found operational.
-
-Note: This function is obsolete and provided for compatibility purposes only. 
-Device drivers should use s390_request_irq_special() instead. 
-
-int request_irq( unsigned int   irq,
-                 int          (*handler)( int,
-                                          void *,
-                                          struct pt_regs *),
-                 unsigned long  irqflags,
-                 const char    *devname,
-                 void          *dev_id);
-
-irq      : specifies the subchannel the ownership is requested for
-handler  : specifies the device driver's interrupt handler to be
-           called for interrupt processing
-irqflags : IRQ flags, currently ignored
-devname  : device name
-dev_id   : required pointer to a device specific buffer of type
-           devstat_t
-
-typedef struct {
-     __u16         devno;    /* device number, aka. "cuu" from irb */
-     unsigned long intparm;  /* interrupt parameter */
-     __u8          cstat;    /* channel status - accumulated */
-     __u8          dstat;    /* device status - accumulated */
-     __u8          lpum;     /* last path used mask from irb */
-     __u8          unused;   /* not used - reserved */
-     unsigned int  flag;     /* flag : see below */
-     __u32         cpa;      /* CCW address from irb at primary status */
-     __u32         rescnt;   /* res. count from irb at primary status */
-     __u32         scnt;     /* sense count, if DEVSTAT_FLAG_SENSE_AVAIL */
-     union {
-        irb_t   irb;         /* interruption response block */
-        sense_t sense;       /* sense information */
-     } ii;                /* interrupt information */
-} devstat_t;
-
-
-During request_irq() processing, the devstat_t layout does not matter as it
-won't be used during request_irq() processing. See do_IO() for a functional
-description of its usage.
-
-The request_irq() function returns :
-
-      0 - successful completion
--EINVAL - an invalid parameter was detected
--EBUSY  - device (subchannel) already owned
--ENODEV - the device is not-operational
--ENOMEM - not enough kernel memory to process request
-
-Usage Notes :
-
-While Linux for Intel defines dev_id as a unique identifier for shared
-interrupt lines it has a totally different purpose on Linux/390. Here it
-serves as a shared interrupt status area between the generic device support
-layer, and the device specific driver. The value passed to request_irq()
-must therefore point to a valid devstat_t type buffer area the device driver
-must preserve for later usage. I.e. it must not be released prior to a call
-to free_irq().
-
-Irqflags are currently ignored by the cds layer.
-The Linux/390 kernel does neither know about "fast" interrupt handlers, nor
-does it allow for interrupt sharing. Remember, the term interrupt level (irq),
-device, and subchannel are used interchangeably in Linux/390.
-
-If request_irq() was called in enabled state, or if multiple CPUs are present,
-the device may present an interrupt to the specified handler prior to
-request_irq() return to the caller  already ! This includes the possibility
-of unsolicited interrupts or a pending interrupt status from an earlier
-solicited I/O request. The device driver must be able to handle this situation
-properly or the device may become unoperational otherwise !
-
-Although the interrupt handler is defined to be called with a pointer to a
-struct pt_regs buffer area, this is not implemented by the Linux/390 generic
-I/O device driver support layer. The device driver's interrupt handler must
-therefore not rely on this parameter on function entry.
-
-
-s390_request_irq_special() - Request Device Ownership 
-
-As previously discussed a device driver will scan for the devices its supports 
-by calling get_dev_info(). Once it has found a device it will call 
-request_irq() to request ownership.
-
-Note:  This function replaces request_irq() described previously.
-
-int s390_request_irq_special( 
-                     int                      irq,
-                     io_handler_func_t        io_handler,
-                     not_oper_handler_func_t  not_oper_handler,
-                     unsigned long            irqflags,
-                     const char              *devname,
-                     void                    *dev_id);
-
-irq              : specifies the subchannel the ownership is
-                    requested for
-io_handler       : specifies the device driver's interrupt handler
-                    to be called for interrupt processing
-not_oper_handler : specifies a device driver "not operational" handler
-irqflags         : IRQ flags, currently ignored
-devname          : device name
-dev_id           : required pointer to a device specific buffer of
-                    type devstat_t
-
-
-typedef struct {
-     __u16         devno;    /* device number, aka. "cuu" from irb */
-     unsigned long intparm;  /* interrupt parameter */
-     __u8          cstat;    /* channel status - accumulated */
-     __u8          dstat;    /* device status - accumulated */
-     __u8          lpum;     /* last path used mask from irb */
-     __u8          unused;   /* not used - reserved */
-     unsigned int  flag;     /* flag : see below */
-     __u32         cpa;      /* CCW address from irb at primary status */
-     __u32         rescnt;   /* res. count from irb at primary status */
-     __u32         scnt;     /* sense count, if DEVSTAT_FLAG_SENSE_AVAIL */
-     union {
-        irb_t   irb;         /* interruption response block */
-        sense_t sense;       /* sense information */
-     } ii;                   /* interrupt information */
-} devstat_t;
-
-During request_irq() processing, the devstat_t layout does not matter as it 
-won't be used during request_irq() processing. See do_IO() for a functional 
-description of its usage.
-
-typedef  void (* io_handler_func_t) ( int             irq,
-                                      void           *devstat,
-                                      struct pt_regs *rgs);
-
-irq     : IRQ the interrupt handler is called for
-devstat : device status block
-rgs     : obsolete
-
-typedef (void)(* not_oper_handler_func_t)( int irq, 
-                                           int status );
-
-irq    : IRQ the not operational status has been encountered for
-status : device status
-         DEVSTAT_NOT_OPER    - device is not operational
-         DEVSTAT_REVALIDATE  - revalidate device number
-         DEVSTAT_DEVICE_GONE - no such device (irq)  
-
-Note: Revalidate indicates that running under VM the device number has been 
-modified by means of a DEFINE xxxx [as] yyyy command. Therewith device number 
-xxxx was altered to yyyy. It's the device drivers responsibility to decide 
-whether device ownership can be retained.
-
-Gone indicates that the device was detached under VM, or the device number 
-became invalid (native, LPAR). In order to prevent further I/O the IRQ was 
-implicitly freed on behalf of the device driver. The driver must not call 
-free_irq itself.
-
-Not Oper indicates the device became not operational. It's the device driver's 
-responsibility whether it wants to maintain ownership for the IRQ, or not. 
-
-The s390_request_irq_special() function returns :
-      0 - successful completion
--EINVAL - an invalid parameter was detected
--EBUSY  - device (subchannel) already owned 
--ENODEV - the device is not-operational
--ENOMEM - not enough kernel memory to process request
-
-Usage Notes :
-While Linux for Intel defines dev_id as a unique identifier for shared 
-interrupt lines, it has a totally different purpose on Linux for S/390. Here 
-it serves as a shared interrupt status area between the generic device support 
-layer and the device specific driver. The value passed to request_irq() must 
-therefore point to a valid devstat_t type buffer area the device driver must 
-preserve for later usage. I.e. it must not be released prior to a call to 
-free_irq().
-Currently, the value of irqflags is ignored. The Linux for S/390 kernel does 
-neither know about "fast" interrupt handlers, nor does it allow for interrupt 
-sharing. Remember, the term interrupt level (irq), device, and subchannel are 
-used interchangeably in Linux for S/390.
-Other than request_irq(), this function does allow for a not operational 
-handler to be defined. This handler is called when a device either became not 
-operational, the last path to a device became not operational, or the device 
-was detached from the system. A detach could be a "detach" under VM or that 
-the device became unassigned by the Support Element (SE) or Hardware Management 
-Console (HMC). 
-If s390_request_irq_special() was called in enabled state, or if multiple CPUs 
-are present, the device may present an interrupt to the specified handler prior 
-to request_irq() return to the caller already ! This includes the possibility 
-of unsolicited interrupts or a pending interrupt status from an earlier 
-solicited I/O request. The device driver must be able to handle this situation 
-properly or the device may become unoperational otherwise !
-
-Although the interrupt handler is defined to be called with a pointer to a 
-struct pt_regs buffer area, this is not implemented by the Linux for S/390 
-platform specific common I/O support layer. The device driver's interrupt 
-handler must therefore not rely on this parameter on function entry.
-
-
-free_irq() - Release Device Ownership
-
-A device driver may call free_irq() to release ownership of a previously
-acquired device.
-
-void free_irq( unsigned int  irq,
-               void         *dev_id);
-
-irq      : specifies the subchannel the ownership is requested for
-dev_id   : required pointer to a device specific buffer of type
-           devstat_t. This must be the same as the one specified
-           during a previous call to request_irq().
-
-Usage Notes :
-
-Unfortunately the free_irq() is defined not to return error codes. I.e. if
-called with wrong  parameters a device may still be operational although there
-is no device driver available to handle its interrupts. Further, during
-free_irq() processing we may possibly find pending interrupt conditions. As
-those need to be processed, we have to delay free_irq() returning until a
-clean device status is found by synchronously handling them.
-
-The call to free_irq() will also cause the device (subchannel) be disabled for
-interrupts. The device driver must not release any data areas required for
-interrupt processing prior to free_irq() return to the caller as interrupts
-can occur prior to free_irq() returning. This is also true when called in
-disabled state if either multiple CPUs are presents or a pending interrupt
-status was found during free_irq() processing.
-
-
-disable_irq() - Disable Interrupts for a given Device
-
-This function may be called at any time to disable interrupt processing for
-the specified irq. However, as Linux/390 maps irqs to the device (subchannel)
-one-to-one, this may require more extensive I/O processing than anticipated,
-especially if an interrupt status is found pending on the subchannel that
-requires synchronous error processing.
-
-int disable_irq( unsigned int irq );
-
-irq : specifies the subchannel to be disabled
-
-The disable-irq() routine may return :
-
-      0 - successful completion
--EBUSY  - device (subchannel) is currently processing an I/O
-          request
--ENODEV - the device is not-operational or irq doesn't specify a
-          valid subchannel
-
-Usage Notes :
-
-Unlike the Intel based hardware architecture the ESA/390 architecture does
-not have a programmable interrupt controller (PIC) where a specific interrupt
-line can be disabled. Instead the subchannel logically representing the device
-in the channel subsystem must be disabled for interrupts. However, if there
-are still inetrrupt conditions pending they must   be processed first in order
-to allow for proper processing after reenabling the device at a later time.
-This may lead to delayed disable processing.
-
-As described above the disable processing may require extensive processing.
-Therefore    disabling and re-enabling the device using disable_irq() /
-enable_irq() should be avoided and is not suitable for high frequency
-operations.
-
-Linux for Intel defines this function
-
-void disable_irq( int irq);
+get_ciw() - get command information word
 
-This is suitable for the Intel PC architecture as this only causes to mask
-the requested irq line in the PIC which is not applicable for the ESA/390
-architecture. Therefore we allow   for returning error codes.
+This call enables a device driver to get information about supported commands
+from the extended SenseID data.
 
+struct ciw *
+ccw_device_get_ciw(struct ccw_device *cdev, __u32 cmd);
 
-enable_irq() - Enable Interrupts for a given Device
+cdev - The ccw_device for which the command is to be retrieved.
+cmd  - The command type to be retrieved.
 
-This function is used to enable a previously disabled device (subchannel).
-See disable_irq() for more details.
+ccw_device_get_ciw() returns:
+NULL    - No extended data available, invalid device or command not found.
+!NULL   - The command requested.
 
-int enable_irq( unsigned int irq );
 
-irq : specifies the subchannel to be enabled
-
-The enable-irq() routine may return :
-
-      0 - successful completion
--EBUSY  - device (subchannel) is currently processing an I/O
-          request. This implies the device is already in enabled
-          state
--ENODEV - the device is not-operational or irq doesn't specify a
-          valid subchannel
+ccw_device_start() - Initiate I/O Request
 
-
-
-do_IO() - Initiate I/O Request
-
-The do_IO() routines is the I/O request front-end processor. All device driver
-I/O requests must be issued using this routine. A device driver must not issue
-ESA/390 I/O commands itself. Instead the do_IO() routine provides all
-interfaces required to drive arbitrary devices.
+The ccw_device_start() routines is the I/O request front-end processor. All
+device driver I/O requests must be issued using this routine. A device driver
+must not issue ESA/390 I/O commands itself. Instead the ccw_device_start()
+routine provides all interfaces required to drive arbitrary devices.
 
 This description also covers the status information passed to the device
 driver's interrupt handler as this is related to the rules (flags) defined
-with the associated I/O request when calling do_IO().
+with the associated I/O request when calling ccw_device_start().
 
-int do_IO( int            irq,
-           ccw1_t        *cpa,
-           unsigned long  user_intparm,
-           unsigned int   lpm,
-           unsigned long  flag);
+int ccw_device_start(struct ccw_device *cdev,
+                    struct ccw1 *cpa,
+                    unsigned long intparm,
+                    __u8 lpm,
+                    unsigned long flags);
 
-irq          : irq (subchannel) the I/O request is destined for
+cdev         : ccw_device the I/O is destined for
 cpa          : logical start address of channel program
 user_intparm : user specific interrupt information; will be presented
               back to the device driver's interrupt handler. Allows a
                device driver to associate the interrupt with a
                particular I/O request.
 lpm          : defines the channel path to be used for a specific I/O
-               request. Valid with flag value DOIO_VALID_LPM only.
-flag         : defines the action to e parformed for I/O processing
+               request. A value of 0 will make cio use the opm.
+flag         : defines the action to be performed for I/O processing
 
 Possible flag values are :
 
-DOIO_EARLY_NOTIFICATION  - allow for early interrupt notification
-DOIO_VALID_LPM           - LPM input parameter is valid (see usage
-                           notes below for details)
-DOIO_WAIT_FOR_INTERRUPT  - wait synchronously for final status
-DOIO_TIMEOUT             - perform a loop while waiting for final status
-                          and fail after a timeout
-DOIO_REPORT_ALL          - report all interrupt conditions
 DOIO_ALLOW_SUSPEND       - channel program may become suspended
 DOIO_DENY_PREFETCH       - don't allow for CCW prefetch; usually
                            this implies the channel program might
-                           become modified 
-DOIO_CANCEL_ON_TIMEOUT   - do a cancel_IO if there is a timeout waiting
-                          for the channel program to finish (see usage
-                           notes below for details)
+                           become modified
+DOIO_SUPPRESS_INTER     - don't call the handler on intermediate status
 
 The cpa parameter points to the first format 1 CCW of a channel program :
 
-typedef struct {
+struct ccw1 {
       __u8  cmd_code;/* command code */
       __u8  flags;   /* flags, like IDA adressing, etc. */
       __u16 count;   /* byte count */
       __u32 cda;     /* data address */
-} __attribute__ ((packed,aligned(8))) ccw1_t;
+} __attribute__ ((packed,aligned(8)));
 
 with the following CCW flags values defined :
 
@@ -783,59 +302,35 @@ CCW_FLAG_IDA       - indirect addressing
 CCW_FLAG_SUSPEND   - suspend
 
 
+Via ccw_device_set_options(), the device driver may specify the following
+options for the device:
+
+DOIO_EARLY_NOTIFICATION  - allow for early interrupt notification
+DOIO_REPORT_ALL          - report all interrupt conditions
 
-The do_IO() function returns :
+
+The ccw_device_start() function returns :
 
       0 - successful completion or request successfully initiated
--EBUSY  - the do_io() function was caled out of sequence. The
-          device is currently processing a previous I/O request
--ENODEV - irq doesn't specify a valid subchannel, the device is
-          not operational (check dev_id.flags) or the irq is not
-          owned.
--EINVAL - both, DOIO_EARLY_NOTIFICATION and DOIO_REORT_ALL flags
-          have been specified. The usage of those flags is mutual
-          exclusive.
+-EBUSY  - The device is currently processing a previous I/O request, or ther is
+          a status pending at the device.
+-ENODEV - cdev is invalid, the device is not operational or the ccw_device is
+          not online.
 
 When the I/O request completes, the CDS first level interrupt handler will
-setup the dev_id buffer of type devstat_t defined during request_irq()
-processing. See request_irq() for the devstat_t data layout. The
-dev_id->intparm field in the device status area will contain the value the
-device driver has associated with a particular I/O request. If a pending
-device status was recognized dev_id->intparm will be set to 0 (zero). This
-may happen during I/O initiation or delayed by an alert status notification.
-In any case this status is not related to the current (last) I/O request. In
-case of a delayed status notification no special interrupt will be presented
-to indicate I/O completion as the I/O request was never started, even though
-do_IO() returned with successful completion.
-
-Possible dev_id->flag values are :
-
-DEVSTAT_FLAG_SENSE_AVAIL - sense data is available
-DEVSTAT_NOT_OPER         - device is not-operational
-DEVSTAT_START_FUNCTION   - interrupt is presented as result of a
-                           call to do_IO()
-DEVSTAT_HALT_FUNCTION    - interrupt is presented as result of a
-                           call to halt_IO()
-DEVSTAT_STATUS_PENDING   - a pending status was found. The I/O
-                           resquest (if any) was not initiated.
-                           This status might have been presented
-                           delayed, after do_IO() or halt_IO() have
-                           successfully be started previously.
-DEVSTAT_FINAL_STATUS     - This is a final interrupt status for the
-                           I/O requst identified by intparm.
-DEVSTAT_PCI              - A PCI was received. 
-DEVSTAT_SUSPENDED        - A "suspended" intermediate status was
-                           received.  
-
-If device status DEVSTAT_FLAG_SENSE_AVAIL is indicated in field dev_id->flag,
-field dev_id->scnt describes the numer of device specific sense bytes
-available in the sense area dev_id->ii.sense. No device sensing by the device
-driver itself is required.
-
-typedef struct {
-      __u8          res[32];   /* reserved   */
-      __u8          data[32];  /* sense data */
-   } __attribute__ ((packed)) sense_t;
+accumalate the status in a struct irb and then call the device interrupt handler.
+The intparm field will contain the value the device driver has associated with a 
+particular I/O request. If a pending device status was recognized, 
+intparm will be set to 0 (zero). This may happen during I/O initiation or delayed
+by an alert status notification. In any case this status is not related to the
+current (last) I/O request. In case of a delayed status notification no special
+interrupt will be presented to indicate I/O completion as the I/O request was
+never started, even though ccw_device_start() returned with successful completion.
+
+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.
 
 The device interrupt handler can use the following definitions to investigate
 the primary unit check source coded in sense byte 0 :
@@ -851,7 +346,7 @@ SNS0_INCOMPL_DOMAIN     0x01
 Depending on the device status, multiple of those values may be set together.
 Please refer to the device specific documentation for details.
 
-The devi_id->cstat field provides the (accumulated) subchannel status :
+The irb->scsw.cstat field provides the (accumulated) subchannel status :
 
 SCHN_STAT_PCI            - program controlled interrupt
 SCHN_STAT_INCORR_LEN     - incorrect length
@@ -862,7 +357,7 @@ SCHN_STAT_CHN_CTRL_CHK   - channel control check
 SCHN_STAT_INTF_CTRL_CHK  - interface control check
 SCHN_STAT_CHAIN_CHECK    - chaining check
 
-The dev_id->dstat field provides the (accumulated) device status :
+The irb->scsw.dstat field provides the (accumulated) device status :
 
 DEV_STAT_ATTENTION   - attention
 DEV_STAT_STAT_MOD    - status modifier
@@ -876,67 +371,36 @@ DEV_STAT_UNIT_EXCEP  - unit exception
 Please see the ESA/390 Principles of Operation manual for details on the
 individual flag meanings.
 
-In rare error situations the device driver may require access to the original
-hardware interrupt data beyond the scope of above mentioned infromation. For
-those situations the Linux/390 common device support provides the interrupt
-response block (IRB) as part of the device status block in dev_id->ii.irb.
-
 Usage Notes :
 
-Prior to call do_IO() 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.
+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 do_IO() routine
-returning to the device driver main path. In this case we will end in a
+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)  s390irq_spin_lock( irq), or
-(ii) s390irq_spin_lock_irqsave(irq, flags)
+(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.
-See the descriptions of s390irq_spin_lock() or s390irq_spin_lock_irqsave()
-for more details.
 
-The device driver is allowed to issue the next do_IO() call from within its
-interrupt handler already. It is not required to schedule a bottom-half,
-unless an non deterministicly long running error recovery procedure or
-similar needs to be scheduled. During I/O processing the Linux/390 generic
+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 deterministicly 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 do_IO() or we end in a deadlock
-situation ! Anyway, the device driver's interrupt handler must only call
-do_IO() if the handler itself can be entered recursively if do_IO() e.g. finds
-a status pending and needs to all the interrupt handler itself.
-
-Device drivers shouldn't heavily rely on DOIO_WAIT_FOR_INTERRUPT synchronous
-I/O request processing. All I/O devices, but the console device are driven
-using a single shared interrupt subclass (ISC). For sync. processing the
-device is temporarily mapped to a special ISC while the calling CPU waits for
-I/O completion. As this special ISC is gated, all sync. requests in a SMP
-environment are serialized which may cause other CPUs to spin. This service
-is therewith primarily meant to be used during device driver initialization
-for ease of device setup.
-
-If the device driver is using the DOIO_TIMEOUT parameter, it is a good idea
-also to specify DOIO_CANCEL_ON_TIMEOUT. Otherwise, the failing channel program
-may prevent the execution of any other channel program at the subchannel.
-
-The lpm input parameter might be used for multipath devices shared among
-multiple systems as the Linux/390 CDS isn't grouping channel paths. Therefore
-its use might be required if multiple access paths to a device are available
-and the device was reserved by means of a reserve device command (for devices
-supporting this technique). When issuing this command the device driver needs
-needs to extract the dev_id->lpum value and restrict all subsequent channel
-programs to this channel path until the device is released by a device release
-command. Otherwise a deadlock may occur.
+must not try to obtain it again when calling ccw_device_start() or we end in a
+deadlock situation!
 
 If a device driver relies on an I/O request to be completed prior to start the
 next it can reduce I/O processing overhead by chaining a NoOp I/O command
@@ -967,19 +431,8 @@ Unless the channel subsystem at any time presents a secondary status interrupt,
 exploiting this feature will cause only primary status interrups to be
 presented to the device driver while overlapping I/O is performed. When a
 secondary status without error (alert status) is presented, this indicates
-successful completion for all overlapping do_IO() requests that have been
-issued since the last secondary (final) status.
-
-During interrupt processing the device specific interrupt handler should avoid
-basing its processing decisions on the interruption response block (IRB) that
-is part of the dev_id buffer area. The IRB area represents the interruption
-parameters from the last interrupt received. Unless the device driver has
-specified DOIO_REPORT_ALL or is called with a pending status
-(DEVSTAT_STATUS_PENDING), the IRB information may or may not show the complete
-interruption status, but the last interrupt only. Therefore the device driver
-should usually base its processing decisions on the values of dev_id->cstat
-and dev_id->dstat that represent the accumulated subchannel and device status
-information gathered since do_IO() request initiation.
+successful completion for all overlapping ccw_device_start() requests that have
+been issued since the last secondary (final) status.
 
 Channel programs that intend to set the suspend flag on a channel command word 
 (CCW)  must start the I/O operation with the DOIO_ALLOW_SUSPEND option or the 
@@ -987,56 +440,50 @@ suspend flag will cause a channel program check. At the time the channel program
 becomes suspended an intermediate interrupt will be generated by the channel 
 subsystem.
 
-resume_IO() - Resume Channel Program Execution 
+ccw_device_resume() - Resume Channel Program Execution 
 
 If a device driver chooses to suspend the current channel program execution by 
 setting the CCW suspend flag on a particular CCW, the channel program execution 
 is suspended. In order to resume channel program execution the CIO layer 
-provides the resume_IO() routine. 
+provides the ccw_device_resume() routine. 
 
-int resume_IO( int irq);
+int ccw_device_resume(struct ccw_device *cdev);
 
-irq     : irq (subchannel) the halt operation is requested for
+cdev - ccw_device the resume operation is requested for
 
 The resume_IO() function returns:
 
         0  - suspended channel program is resumed
 -EBUSY     - status pending
--ENODEV    - invalid or not-operational subchannel 
+-ENODEV    - cdev invalid or not-operational subchannel 
 -EINVAL    - resume function not applicable  
 -ENOTCONN  - there is no I/O request pending for completion 
 
 Usage Notes:
-Please have a look at the do_IO()  usage notes for more details on suspended 
-channel programs.
+Please have a look at the ccw_device_start() usage notes for more details on
+suspended channel programs.
 
-halt_IO() - Halt I/O Request Processing
+ccw_device_halt() - Halt I/O Request Processing
 
 Sometimes a device driver might need a possibility to stop the processing of
 a long-running channel program or the device might require to initially issue
-a halt subchannel (HSCH) I/O command. For those purposes the halt_IO() command
-is provided.
+a halt subchannel (HSCH) I/O command. For those purposes the ccw_device_halt()
+command is provided.
 
-int halt_IO( int           irq,     /* subchannel number */
-             unsigned long intparm, /* dummy intparm */
-             unsigned long flag);   /* operation mode */
+int ccw_device_halt(struct ccw_device *cdev,
+                    unsigned long intparm);
 
-irq     : irq (subchannel) the halt operation is requested for
+cdev    : ccw_device the halt operation is requested for
 intparm : interruption parameter; value is only used if no I/O
           is outstanding, otherwise the intparm associated with
           the I/O request is returned
-flag    : 0 (zero) or DOIO_WAIT_FOR_INTERRUPT
 
-The halt_IO() function returns :
+The ccw_device_halt() function returns :
 
       0 - successful completion or request successfully initiated
--EBUSY  - the device is currently performing a synchronous I/O
-          operation : do_IO() with flag DOIO_WAIT_FOR_INTERRUPT
-          or an error was encountered and the device is currently
-          be sensed
--ENODEV - the irq specified doesn't specify a valid subchannel, the
-          device is not operational (check dev_id.flags) or the irq
-          is not owned.
+-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.
 
 Usage Notes :
 
@@ -1046,11 +493,8 @@ channel (TIC)   command (CCW_CMD_TIC). Usually this is performed by network
 device drivers by setting the PCI CCW flag (CCW_FLAG_PCI). Once this CCW is
 executed a program controlled interrupt (PCI) is generated. The device driver
 can then perform an appropriate action. Prior to interrupt of an outstanding
-read to a network device (with or   without PCI flag) a halt_IO() is required
-to end the pending operation.
-
-We don't allow to stop sync. I/O requests by means of a halt_IO() call. The
-function will return -EBUSY instead.
+read to a network device (with or without PCI flag) a ccw_device_halt()
+is required to end the pending operation.
 
 
 Miscellaneous Support Routines
@@ -1058,107 +502,12 @@ Miscellaneous Support Routines
 This chapter describes various routines to be used in a Linux/390 device
 driver programming environment.
 
-s390irq_spin_lock() / s390irq_spin_unlock()
-
-Those two macro definitions are required to obtain the device specific IRQ
-lock. The lock needs to be obtained if the device driver intends to call
-do_IO() or halt_IO() from anywhere but the device interrupt handler (where
-the lock is already owned). Those routines must only be used if running
-disabled for interrupts already. Otherwise use s390irq_spin_lock_irqsave()
-and the corresponding unlock routine instead (see below).
-
-s390irq_spin_lock( int irq);
-s390irq_spin_unlock( int irq);
-
-
-s390irq_spin_lock_irqsave() / s390_irq_spin_unlock_irqrestore()
-
-Those two macro definitions are required to obtain the device specific IRQ
-lock. The lock needs to be obtained if the device driver intends to call
-do_IO() or halt_IO() from anywhere but the device interrupt handler (where
-the lock is already owned). Those routines should only be used if running
-enabled for interrupts. If running disabled already, the driver should use
-s390irq_spin_lock() and the corresponding unlock routine instead (see above).
-
-s390irq_spin_lock_irqsave( int irq, unsigned long flags);
-s390irq_spin_unlock_irqrestore( int irq, unsigned long flags);
-
-
-
-
-Special Console Interface Routines
-
-This chapter describes the special interface routines required for system
-console processing. Though they are an extension to the Linux/390 device
-driver interface concept, they base on the same principles. It was necessary
-to build those extensions to assure a deterministic behaviour in critical
-situations e.g. printk() messages by other device drivers running disabled
-for interrupts during I/O interrupt handling or in case of a panic() message
-being raised.
-
-set_cons_dev - Set Console Device
-
-This routine allows to specify the system console device. This is necessary
-as the console isn't driven by the same ESA/390 interrupt subclass as are
-other devices, but it is assigned ist own interrupt subclass. Only one device
-can act as system console. See wait_cons_dev() for details.
-
-int set_cons_dev( int irq);
-
-irq : subchannel identifying the system console device
-
-The set_cons_dev() function returns
-
-      0 - successful completion
--EIO    - an unhandled interrupt condition is pending for the
-          specified subchannel (irq) - status pending
--ENODEV - irq doesn't specify a valid subchannel or the devive is
-          not operational
--EBUSY  - the console device is already defined
-
-reset_cons_dev - Reset Console Device
-
-This routine allows for resetting the console device specification. See
-wait_cons_dev() for details.
-
-int reset_cons_dev( int irq);
-
-irq : subchannel identifying the system console device
-
-The reset_cons_dev() function returns
-
-      0 - successful completion
--EIO    - an unhandled interrupt condition is pending for the
-          specified subchannel (irq) - status pending
--ENODEV - irq doesn't specify a valid subchannel or the devive is
-          not operational
-
-wait_cons_dev - Synchronously Wait for Console Processing
-
-The wait_cons_dev() routine is used by the console device driver when its
-buffer pool for intermediate request queuing is exhausted and a new output
-request is received. In this case the console driver uses the wait_cons_dev()
-routine to synchronously wait until enough buffer space is gained to enqueue
-the current request. Any pending interrupt condition for the console device
-found during wait_cons_dev() processing causes its interrupt handler to be
-called.
-
-int wait_cons_dev( int irq);
-
-irq : subchannel identifying the system console device
-
-The wait_cons_dev() function  returns :
-
-      0 - successful completion
--EINVAL - the irq specified doesn't match the irq configured for
-          the console device by set_cons_dev()
-
-Usage Notes :
+get_ccwdev_lock()
 
-The function should be used carefully. Especially in a SMP environment the
-wait_cons_dev() processing requires that all but the special console ISC are
-disabled. In a SMP system this requires the other CPUs to be signaled to
-disable/enable those ISCs.
+Get the address of the device specific lock. This is then used in
+spin_lock() / spin_unlock() calls.
 
 
+__u8 ccw_device_get_path_mask(struct ccw_device *cdev);
 
+Get the mask of the path currently available for cdev.
diff --git a/Documentation/s390/chandev.8 b/Documentation/s390/chandev.8
deleted file mode 100644 (file)
index bdd96fd..0000000
+++ /dev/null
@@ -1,430 +0,0 @@
-.TH chandev 8
-.SH NAME
-channel device layer
-.Dd December 6, 2000
-.Os Linux for Zseries
-
-.SH SYNOPSIS
-The channel device layer is a layer to provide a consistent interface for
-configuration & default machine check (devices appearing & disappearing )
-handling on Linux for s/390 & z/Series channel devices.
-
-
-s/390 & z/Series channel devices include among others
-
-.Bl -item
-.It
-lcs ( the most common ethernet/token ring/fddi standard on zSeries )
-.It
-ctc/escon hi speed like serial link standard on s/390 & z/Series.
-.It
-claw used to talk to cisco routers.
-.It
-qeth gigabit ethernet.
-.It
-osad used by osa/sf to configure osa devices, e.g. to share a osa card between 2 or more vm guests. osad is just added to the channel device layer for completeness, there are no plans at the current time to write a driver to exploit this under linux.
-.It
-These devices use two channels one read & one write for configuration &
-or communication ( & a third channel the data channel in the case of gigabit ethernet ).
-The motivation behind developing this layer was that there was a lot of
-duplicate code among the channel device drivers for configuration. 
-Also the lcs & ctc drivers tended to fight over 3088/08's & 3088/1F's which could 
-be either 2216/3172 channel attached lcs compatible devices or escon/ctc pipes 
-between guests & to resolve this fight both device drivers had to be configured 
-separately,  this is now simplified by doing the configuration in a single place
-( the channel device layer ).
-
-This layer isn't invasive & it is quite okay to use channel drivers
-which don't use the channel device layer in conjunction with
-drivers which do.
-.El
-
-.SH DESCRIPTION
-The current setup can be read from /proc/chandev
-arguments can be entered by...
-.Bl -enum
-.It
-Piping to /proc/chandev.
-e.g. echo reprobe >/proc/chandev
-will cause uninitialised channel devices to be probed.
-.It
-Entering them into /etc/chandev.conf comments are prefixed with #.
-.It
-Or from the boot command line using the 'chandev=' keyword
-e.g. chandev=noauto,0x0,0x480d;noauto,0x4810,0xffff
-will allow only devno's 0x480e & 0x480f to be autodetected.
-.El
-.Bl -item
-.It
-Multiple options can be passed separated by semicolons, no spaces or newlines are allowed between parameters on the kernel parameter line as it complicates parsing, spaces are allowed in /proc/chandev & chandev.conf, newlines are allowed in chandev.conf only. To be consistent with other hotpluggable architectures the script pointed to /proc/sys/kernel/hotplug (normally /sbin/hotplug) will be called automatically on startup or a machine check of a device as follows.
-/sbin/hotplug chandev <start starting_devnames> <machine_check (devname last/pre_recovery_status) (current/post_recovery_status)>.
-The chandev layer doesn't open stdin stdout or stderr so it is advisable that you add the following lines to the start of your script, here is a sample script which starts devices as they become available.
-.It
-#!/bin/bash
-.It
-exec >/dev/console 2>&1 0>&1
-.It
-# Uncomment line below for debugging.
-.It
-# echo $*
-.It
-if [ "$1" = "chandev" ] && [ "$2" = "start" ]
-.It
-then
-.It
-    shift 2
-.It
-    while [ "$1" != "" ]  && [ "$1" != "machine_check" ]
-.It
-    do
-.It
-        isup=`ifconfig $1 2>/dev/null | grep UP`
-.It
-       if [ "$isup" = "" ]
-.It
-       then
-.It
-            ifup $1
-.It
-       fi
-.It
-       shift
-.It
-    done
-.It
-fi
-.It
-.It
-e.g. if tr0 & ctc0 were starting up & eth0 & eth1 devices disappeared & eth2 got a revalidate machine check ( which is normally fully recoverable ) nearly simultainously the parameters would be.
-.It
-/sbin/hotplug chandev start tr0 ctc0 machine_check eth0 gone gone eth1 gone gone eth2 revalidate good
-.It
-This can be used for example to call /etc/rc.d/init.d/network start when a device appears & make the ipldelay kernel boot parameter obselete on native machines or recover from bad machine checks where the default machine check handling isn't adequete. The machine checks that can be presented as parameters are good not_operational no_path revalidate device_gone. Normally you wouldn't want to do anything like stop networking when a device disappears as this is hopefully temporary, I just added it to be complete. The chandev layer waits a few seconds for machine checks to settle before running /sbin/hotplug because several machine checks usually happen at once & the forked scripts would possibly race against each other to shutdown & start resources at the same time & behave rather stupidly.
-.El
-
-
-
-valid chandev arguments are <> indicate optional parameters, | indicate a choice.
-
-.B glossary
-.Bl -item
-.It
-devno: is a 16 bit unsigned number used to uniquely identify a subchannel to a device.
-.It
-force list: is a term specific to channel device layer describing a range of devno's to be forced to configure in a particular manner as opposed to autodetect
-.El
-
-.B commonly used options
-
-.Bl -item
-.It
-
-.Bl -item
-.It
-.B (ctc|escon|lcs|osad|qeth)<devif_num>, 
-read_devno,write_devno,<data_devno,memory_usage_in_k,port_no/protocol_no,checksum_received_ip_pkts,use_hw_stats>
-.It
-devif_num of -1 indicates you don't care what device interface number is chosen, omitting it indicates this is a range of devices for which you want to force to be detected as a particular type, qeth devices can't be forced as a range as it makes no sense for them.
-The data_devno field is only valid for qeth devices, all parameters including & after memory_usage_in_k can be set optionally, if not set they
-go to default values. memory_usage_in_k ( 0 the default ) means let the driver choose,checksum_received_ip_pkts & use_hw_stats are set to false
-.It
-e.g. ctc0,0x7c00,0x7c01
-.It
-Tells the channel layer to force ctc0 if detected to use cuu's 7c00 & 7c01 port,port_no is the relative adapter no on lcs, on ctc/escon this field is the ctc/escon protocol number ( default 0 ), don't do checksumming on received ip packets & as ctc doesn't have hardware stats so it ignores this parameter. This can be used for instance to force a device if it presents bad sense data to the IO layer & thus autodetection fails.
-.It
-lcs,0x7c00,0x7d00,4096,-1
-All devices between 0x7c00 & 7d00 should be detected as lcs, let the driver use 4096k for each instance, don't care what port relative adapter number is chosen, don't checksum received ip packets & use hw stats .
-.It
-qeth1,0x7c00,0x7c01,0x7c02
-.It
-devif_num=1,read=0x7c00,write=0x7c01,data=0x7c02, don't checksum received ip packets & use hw stats.
-.El
-.It
-.Bl -item
-.B claw devif_num, 
-read_devno,write_devno<,memory_usage_in_k,checksum_received_ip_pkts,use_hw_stats,>
-host_name,adapter_name,api_type
-.It
-CLAW currently is not autodetected as the host_name,adapter_name & api_type
-need to be set up, possibly some convention for setting these automatically
-may be contrived in the future & auto detection may be done but currently there isn't any.
-The names host_name,adapter_name,api_type may be 8 upto characters in length,
-host_name is the name of this host, adapter_name is the name of the adjacent host,
-api_type may be name 1 to 8 chars in length API & TCPIP are common values.
-The remainder of the parameters are the same as the description for other ctc escon etc. 
-.It
-A typical setup may be
-.It
-claw0,0xe00,0xe01,linuxa,rs6k,TCPIP
-.It
-.El
-.Bl -item
-.It
-.B add_parms
-,chan_type,<lo_devno,hi_devno,>string
-.It
-chan_type bitfield 
-.It
-ctc=0x1, escon=0x2, lcs=0x4, osad=0x8, qeth=0x10, claw=0x20.
-.It
-This is for device driver specific options passed as a string to the driver
-not dealt with by the channel device layer it can't contain spaces.
-low_devno & hi_devno are optional parameters to specify a range.
-The channel device layer doesn't concatenate strings if device ranges overlap,
-before passing to a device driver.
-.El
-.It
-
-.Bl -item
-.It
-.B del_parms
-<,chan_type,exact_match,lo_devno>
-.It
-This deletes some or all device driver specific options not specifying chan_type causes it to delete all the strings. exact_match=1 specifies only to remove driver parms where chan_type is exactly equal exact_match=0 specifies to remove parms where any bit matches chan_type.
-lo_devno is an optional parameter the delete to only happen if lo_devno matches a lo_devno in one of the ranges.
-.El
-.It
-
-.Bl -item
-.It
-.B noauto
-<,lo_devno,hi_devno>
-.It
-Don't probe a range of device numbers for channel devices.
-.El
-.It
-
-.Bl -item
-.It
-.B use_devno_names
-.It
-Tells the channel layer to assign device names based on the read channel cuu number.
-.It
-e.g. a token ring read channel 0x7c00 would have an interface called tr0x7c00 this avoids name collisions on devices.
-.El
-
-
-.B power user options
-
-
-.Bl -item
-
-.It
-.Bl -item
-.It
-.B del_noauto
-,<devno>
-.It
- Delete a range or all noauto ranges when devno is within a range.
-.El
-
-.It
-.Bl -item
-.It
-.B del_force
-,read_devno
-.It
-Delete a forced channel device from force list.
-.El
-
-.It
-.Bl -item
-.It
-.B dont_use_devno_names
-.It
-Opposite to use_devno_names described above.
-.El
-
-
-.It
-.Bl -item
-.It
-.B add_model
-,chan_type, cu_type, cu_model, dev_type, dev_model, max_port_no, automatic_machine_check_handling
-.It
-Tells the channel layer to probe for the device described, -1 for any of the parameters other than chan_type & automatic_machine_check_handling is a wildcard.
-Set max_port_no to 0 for non lcs devices.
-.It
-auto machine check recovery bitfield
-.It
-not_operational=0x1, no_path=0x2, revalidate=0x4, gone=0x8
-.It
-chan_type bitfield
-.It
-ctc=0x1, escon=0x2, lcs=0x4, osad=0x8, qeth=0x10, claw=0x20
-.El
-.Bl -item
-.It
-.B del_model
-,cu_type,cu_model,dev_type,dev_model
-.It
--1 for any parameter is a wildcard.
-.El
-
-.Bl -item
-.It
-.B del_all_models
-.It 
-should be obvious.
-.El
-.Bl -item
-.It
-.B  non_cautious_auto_detect
-.It
-Tells the channel device layer to attempt to auto detect devices even if their type/model pairs don't unambigously identify the device, e.g. 3088/1F's can either be escon CTC's or channel attached 3172 lcs compatible devices. If the wrong device driver attempts to probe these channels there may be big delays on startup or even a kernel lockup, use this option with caution.
-.El
-.Bl -item
-.It
-.B cautious_auto_detect
-.It
- See non_cautious_auto_detect this is the default.
-.El
-.Bl -item
-.It
-.B auto_msck
-<,lo_devno>,<hi_devno>,auto_msck_recovery
-.It
-This is used to specify the kind of machine check recovery that occurs over a device range.
-.El
-.It
-.Bl -item
-.It
-.B del_auto_msck
-<,devno>
-.It
-Delete a range or all machine check recovery ranges when devno is within a range.
-.El
-.It
-.Bl -item
-.It
-.B reset_clean
-.It
-Resets all model info, forced devices & noauto lists to null.
-.El
-.It
-.Bl -item
-.It
-.B reset_conf
-.It
-Resets all model info, forced devices & noauto lists back to default settings.
-.El
-.It
-.Bl -item
-.It
-.B reset_conf_clean
-.It
-Resets all model info, forced devices & noauto lists to empty.
-.El
-.It
-.Bl -item
-.It
-.B shutdown
-<device name|read devno>
-.It
-Shuts down a particular device by device name or read devno,
-deregisters it & releases its interrupts
-or shuts down all devices if no parameter is used.
-.El
-.It
-.Bl -item
-.It
-.B reprobe
-.It
-Calls probe method for channels whose interrupts are not owned.
-.El
-.It
-.Bl -item
-.It
-.B unregister_probe <probefunc_addr>
-.It
-unregisters a single probe function or all of them.
-.El
-.Bl -item
-.It
-.B unregister_probe_by_chan_type
-.It
-unregisters all probe functions which match the chan_type bitfield exactly,
-useful if you want a configuration to survice a kernel upgrade.
-.El
-.Bl -item
-.It
-.B read_conf
-.It
-Read instructions from /etc/chandev.conf.
-.El
-.It
-.Bl -item
-.It
-.B dont_read_conf
-.It
-Don't automatically read /etc/chandev.conf on boot.
-.El
-.Bl -item
-.It
-.B persist 
-,chan_type
-.It
-Force drivers modules to stay loaded even if no device is found,
-this is useful for debugging & one wishes to examine debug entries in 
-/proc/s390dbf/ to find out why a module failed to load.
-.It
-e.g.
-.It
-persist,-1 forces all devices to persist.
-.It
-persist,0 forces all channel devices to be non persistent.
-.El
-
-.It
-e.g the following sequence of commands should be roughly equivalent
-to rebooting for channel devices.
-.Bl -item
-.It
-shutdown
-.It
-reset_conf
-.It
-read_conf
-.It
-reprobe
-.El
-.El
-
-.SH SEE ALSO
-.Bl -item
-.It
-If you wish to write a driver channel device layer compatible
-.It
-/linux/include/asm-s390/chandev.h for the apis which are commented.
-.It
-/linux/drivers/s390/misc/chandev.c for the code.
-.El
-
-.SH FILES
-.Bl -item
-.It
-.B /proc/chandev
-.It
-cat /proc/chandev to see current options chosen.
-.It
-echo <command> >/proc/chandev to enter a new command
-.It
-.B /etc/chandev.conf 
-.It
-A file which can be used to configure the channel 
-device layer.
-.It
-kernel parameters with the 
-.B 'chandev=' 
-keyword.
-.It
-.B /sbin/hotplug
-.It 
-A user script/executable which is run when devices come online "appear"
-or go offline "disappear".
-.El
-
-
-.SH AUTHORS
-DJ Barrow (djbarrow@de.ibm.com,barrow_dj@yahoo.com)
-
diff --git a/Documentation/s390/driver-model.txt b/Documentation/s390/driver-model.txt
new file mode 100644 (file)
index 0000000..7d56d4b
--- /dev/null
@@ -0,0 +1,209 @@
+S/390 driver model interfaces
+-----------------------------
+
+1. CCW devices
+--------------
+
+All devices which can be addressed by means of ccws are called 'CCW devices' -
+even if they aren't actually driven by ccws.
+
+All ccw devices are accessed via a subchannel, this is reflected in the 
+structures under root/:
+
+root/
+     - sys
+     - legacy
+     - css0/
+           - 0:0000/0:0815/
+          - 0:0001/0:4711/
+          - 0:0002/
+          ...
+
+In this example, device 0815 is accessed via subchannel 0, device 4711 via 
+subchannel 1, and subchannel 2 is a non-I/O subchannel.
+
+You should address a ccw device via its bus id (e.g. 0:4711); the device can
+be found under bus/ccw/devices/.
+
+All ccw devices export some data via sysfs additional to the standard 'name'
+and 'power' entries.
+
+cutype:            The control unit type / model.
+
+devtype:    The device type / model, if applicable.
+
+online:     An interface to set the device online and offline.
+
+The device drivers can add entries to export per-device data and interfaces.
+
+There is also some data exported on a per-subchannel basis (see under
+bus/css/devices/):
+
+chpids:            Via which chpids the device is connected.
+
+pimpampom:  The path installed, path available and path operational masks.
+
+There also might be additional data, for example for block devices.
+
+
+1.1 Bringing up a ccw device
+----------------------------
+
+This is done in several steps.
+
+a. Some drivers need several ccw devices to make up one device. This drivers
+   provide a 'chaining' interface (driver dependend) which allows to specify
+   which ccw devices form a device.
+b. Each driver provides one or more parameter interfaces where parameters can
+   be specified. These interfaces are also in the driver's responsibility.
+c. After a. and b. have been performed, if neccessary, the device is finally
+   brought up via the 'online' interface.
+
+
+1.2 Writing a driver for ccw devices
+------------------------------------
+
+The basic struct ccw_device and struct ccw_driver data structures can be found
+under 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 *);
+       void (*release) (struct ccw_driver *); 
+       int (*set_online) (struct ccw_device *);
+       int (*set_offline) (struct ccw_device *);
+       struct device_driver driver;
+       char *name;
+};
+
+The 'private' field contains data needed for internal i/o operation only, and
+is not available to the device driver.
+
+Each driver should declare in a MODULE_DEVICE_TABLE into which CU types/models
+and/or device types/models it is interested. This information can later be found
+found in the struct ccw_device_id fields:
+
+struct ccw_device_id {
+       __u16   match_flags;    
+
+       __u16   cu_type;        
+       __u16   dev_type;       
+       __u8    cu_model;       
+       __u8    dev_model;      
+
+       unsigned long driver_info;
+};
+
+The functions in ccw_driver should be used in the following way:
+probe:   This function is called by the device layer for each device the driver
+        is interested in. The driver should only allocate private structures
+        to put in dev->driver_data and create attributes (if needed). Also,
+        the interrupt handler (see below) should be set here.
+
+int (*probe) (struct ccw_device *cdev); 
+
+Parameters:  cdev     - the device to be probed.
+
+
+remove:  This function is called by the device layer upon removal of the driver,
+        the device or the module. The driver should perform cleanups here.
+
+int (*remove) (struct ccw_device *cdev);
+
+Parameters:   cdev    - the device to be removed.
+
+
+set_online: This function is called by the common I/O layer when the device is
+           activated via the 'online' attribute. The driver should finally
+           setup and activate the device here.
+
+int (*set_online) (struct ccw_device *);
+
+Parameters:   cdev     - the device to be activated. The common layer has
+                         verified that the device is not already online.
+
+
+set_offline: This function is called by the common I/O layer when the device is
+            de-activated via the 'online' attribute. The driver should shut
+            down the device, but not de-allocate its private data.
+
+int (*set_offline) (struct ccw_device *);
+
+Parameters:   cdev       - the device to be deactivated. The common layer has
+                          verified that the device is online.
+
+
+The handler field of the struct ccw_device is meant to be set to the interrupt
+handler for the device. In order to accomodate drivers which use several 
+distinct handlers (e.g. multi subchannel devices), this is a member of ccw_device
+instead of ccw_driver.
+The handler is registered with the common layer during set_online() processing
+before the driver is called, and is deregistered during set_offline() after the
+driver has been called. Also, after registering / before deregistering, path 
+grouping resp. disbanding of the path group (if applicable) are performed.
+
+void (*handler) (struct ccw_device *dev, unsigned long intparm, struct irb *irb);
+
+Parameters:    dev     - the device the handler is called for
+               intparm - the intparm which allows the device driver to identify
+                          the i/o the interrupt is associated with, or to recognize
+                          the interrupt as unsolicited.
+                irb     - interruption response block which contains the accumulated
+                          status.
+
+The device driver is called from the common ccw_device layer and can retrieve 
+information about the interrupt from the irb parameter.
+
+
+2. System devices
+-----------------
+
+2.1 Channel paths
+-----------------
+
+Every channel path is represented under sys/ as channel_path<nr>. (Unfortunately,
+<nr> is in decimal, which may look unfamiliar.)
+
+status - Can be 'online', 'logically offline' or 'n/a'.
+        Piping 'on' or 'off' sets the chpid logically online/offline.
+
+
+2.2 xpram 
+---------
+
+xpram shows up under sys/ as 'xpram'.
+
+
+3. 'Legacy' devices
+-------------------
+
+The 'legacy' bus is for devices not detected, but specified by the user.
+
+
+3.1 Netiucv
+-----------
+
+Netiucv connections show up under legacy/ as "netiucv<ifnum>". The interface
+number is assigned sequentially at module load.
+
+user                     - the user the connection goes to.
+
+buffer                   - maximum buffer size.
+                           Pipe to it to change buffer size.
+
+