Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
L
linux
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
nexedi
linux
Commits
43c9d459
Commit
43c9d459
authored
Jun 08, 2002
by
Martin Schwidefsky
Committed by
Linus Torvalds
Jun 08, 2002
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
[PATCH] s/390 patches for 2.5.20 (4 of 4).
Fourth and last part of the s/390 update. Docu stuff.
parent
10e294df
Changes
3
Show whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
394 additions
and
123 deletions
+394
-123
Documentation/s390/CommonIO
Documentation/s390/CommonIO
+38
-32
Documentation/s390/Debugging390.txt
Documentation/s390/Debugging390.txt
+16
-3
Documentation/s390/cds.txt
Documentation/s390/cds.txt
+340
-88
No files found.
Documentation/s390/CommonIO
View file @
43c9d459
...
...
@@ -21,7 +21,8 @@ Command line parameters
Default is on.
* cio_ignore = <range of device numbers>, <range of device numbers>, ...
* cio_ignore = <device number> | <range of device numbers>,
<device number> | <range of device numbers>, ...
The given device numbers will be ignored by the common I/O-layer; no detection
and device sensing will be done on any of those devices. The subchannel to
...
...
@@ -41,45 +42,27 @@ Command line parameters
By default, no devices are ignored.
* cio_proc_devinfo = yes | no
Determines whether the entries under /proc/deviceinfo/ (see below) should be
created. Since there are problems with systems with many devices attached, I
made it configurable.
Until the problems are dealt with, default is off.
/proc entries
-------------
* /proc/subchannels
Shows for each subchannel
This entry shows information on a per-subchannel basis.
The data is ordered in the following way:
- device number
- device type/model and if applicable control unit type/model
- whether the device is in use
- path installed mask, path available mask, path operational mask and last
path used mask
- the channel path IDs (chpids)
* /proc/deviceinfo/
Shows in subdirectories for each device some characteristics:
- /proc/deviceinfo/<devno>/chpids:
the channel path IDs
- /proc/deviceinfo/<devno>/in_use:
whether the device is in use
- /proc/deviceinfo/<devno>/sensedata:
the device type/model and if applicable control unit type/model of the
device
NOTE: Since the number of inodes which can be dynamically allocated by procfs
is limited, device entries will only be created up to a magic number of
devices. The kernel will utter a warning that not all entries can be
created. In this case, you shouldn't use "cio_proc_devinfo=yes" (see
above).
- subchannel number
- device type/model (if applicable; if not, this is empty) and control unit
type/model
- whether the device is in use (i. e. a device driver has requested ownership
and registered an interrupt handler)
- path installed mask (PIM), as reflected by last store subchannel
- path available mask (PAM), as reflected by last store subchannel
- path operational mask (POM), as reflected by last store subchannel
- the channel path IDs (CHPIDs)
All fields are separated by spaces, the chpids are in blocks of four chpids.
* /proc/cio_ignore
...
...
@@ -137,3 +120,26 @@ Command line parameters
This entry counts how many times s390_process_IRQ has been called for each
CPU. This info is in /proc/interrupts on other architectures.
* /proc/chpids
This entry will only show up if you specified CONFIG_CHSC=y during kernel
config.
This entry serves a dual purpose:
- show which chpids are currently known to Linux and their status (online,
logically offline),
- toggling known chpids logically online/offline.
To toggle a known chpid logically offline, do an
echo off <chpid> > /proc/chpids
<chpid> is interpreted as hex, even if you omit the '0x'.
The chpid will be treated by Linux as if it were not online, which can mean
some devices will become unavailable.
You can toggle a logically offline chpid online again by
echo on <chpid> > /proc/chpids
If devices became unavailable by toggling the chpid logically offline, they
will become available again after you toggle the chpid online again.
Documentation/s390/Debugging390.txt
View file @
43c9d459
...
...
@@ -237,9 +237,10 @@ they go to 64 Bit.
On 390 our limitations & strengths make us slightly different.
For backward compatibility we are only allowed use 31 bits (2GB)
of our 32 bit addresses,however, we use entirely separate address
spaces for the user & kernel.
For backward compatibility ( because of the psw address hi bit which
indicates whether we are in 31 or 24 bit mode ) we are only allowed
use 31 bits (2GB) of our 32 bit addresses. However,
we use entirely separate address spaces for the user & kernel.
This means we can support 2GB of non Extended RAM on s/390, & more
with the Extended memory managment swap device &
...
...
@@ -1474,6 +1475,12 @@ Now display what gpr2 is pointing to
D 00014CB4.20
V00014CB4 2F646576 2F636F6E 736F6C65 00001BF5
V00014CC4 FC00014C B4001001 E0001000 B8070707
Alternatively you can do the more elegant
D 0.20;BASE2
BASE2 telling VM to use GPR2 as the base register.
Now copy the text till the first 00 hex ( which is the end of the string
to an xterm & do hex2ascii on it.
hex2ascii 2F646576 2F636F6E 736F6C65 00
...
...
@@ -2124,6 +2131,12 @@ now do
p/x (*(**$sp+56))&0x7fffffff
& so on.
Another good trick to look at addresses on the stack if you've somehow lost
the backchain is.
x/500xa $sp
This displays anything the name of any known functions above the stack pointer
for 500 bytes.
Disassembling instructions without debug info
---------------------------------------------
gdb typically compains if there is a lack of debugging
...
...
Documentation/s390/cds.txt
View file @
43c9d459
...
...
@@ -5,12 +5,14 @@ Device Driver I/O Support Routines
Author : Ingo Adlung
Copyright, IBM Corp. 1999
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.
Different than other hardware architectures, ESA/390 hasdefined a unified
Different than other hardware architectures, ESA/390 has
defined a unified
I/O access method. This gives relief to the device drivers as they don't
have to deal with different bus types, polling versus interrupt
processing, shared versus non-shared interrupt processing, DMA versus port
...
...
@@ -26,14 +28,11 @@ Operation manual (IBM Form. No. SA22-7201).
In order to build common device support for ESA/390 I/O interfaces, a
functional layer was introduced that provides generic I/O access methods to
the hardware. The following figure shows the usage of the common device support
of Linux/390 using a TbCP/IP driven device access an example. Similar figures
could be drawn for other access methods, e.g. file system access to disk
devices.
the hardware.
The common device support layer
shown above 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.
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
...
...
@@ -45,9 +44,16 @@ get_irq_by_devno() / get_devno_by_irq()
read_dev_chars()
read device characteristics
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.
...
...
@@ -60,6 +66,9 @@ enable_irq()
do_IO()
initiate an I/O request.
resume_IO()
resume channel program execution.
halt_IO()
terminate the current I/O request processed on the device.
...
...
@@ -70,12 +79,14 @@ do_IRQ()
interrupt handler according to the rules (flags) defined during I/O request
initiation with do_IO().
The next chapters describe the functions
,
other than do_IRQ() in more details.
The next chapters describe the functions other than do_IRQ() in more details.
The do_IRQ() interface is not described, as it is called from the Linux/390
first level interrupt handler only and does not comprise a device driver
callable interface. Instead, the functional description of do_IO() also
describes the input to the device specific interrupt handler.
Note: All explanations apply also to the 64 bit architecture s390x.
Common Device Support (CDS) for Linux/390 Device Drivers
...
...
@@ -90,7 +101,7 @@ 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/
arch/s390/kernel
/irq.h.
linux/
include/asm-s390
/irq.h.
Overview of CDS interface concepts
...
...
@@ -106,7 +117,7 @@ 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.
Linux, however was first built on the Intel PC architecture, with its two
Linux, however
,
was first built on the Intel PC architecture, with its two
cascaded 8259 programmable interrupt controllers (PICs), that allow for a
maximum of 15 different interrupt lines. All devices attached to such a system
share those 15 interrupt levels. Devices attached to the ISA bus system must
...
...
@@ -117,7 +128,7 @@ present their hardware status by the same (shared) IRQ, the operating system
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
to not
introduce a new I/O concept to the common Linux code,
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.
...
...
@@ -126,7 +137,7 @@ 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
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
...
...
@@ -141,7 +152,7 @@ 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
,
the CDS layer will use to notify the device driver's
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.
...
...
@@ -169,6 +180,41 @@ 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
...
...
@@ -177,23 +223,25 @@ SenseID information. For those devices supporting the command it also obtains
extended SenseID information.
int get_dev_info_by_irq( int irq,
dev_info_t *devinfo
);
s390_dev_info_t *pdi
);
int get_dev_info_by_devno(
unsigned int irq
,
dev_info_t *devinfo
);
int get_dev_info_by_devno(
__u16 devno
,
s390_dev_info_t *pdi
);
irq - defines the subchannel
,
status information is to be
irq - defines the subchannel status information is to be
returned for.
devno - device number.
devinfo - pointer to a user buffer of type
dev_info_t that should
pdi - pointer to a user buffer of type s390_
dev_info_t that should
be filled with device specific information.
typedef struct {
unsigned int devno; /* device number */
int irq; /* irq, aka. subchannel */
__u16 devno; /* device number */
unsigned int status; /* device status */
senseid_t sid_data; /* senseID data */
}
dev_info_t;
}
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
...
...
@@ -205,31 +253,33 @@ DEVSTAT_NOT_OPER - device was found not-operational. In this case
buffer content.
//
//
SenseID
response buffer layout
//
sense-id
response buffer layout
//
typedef struct {
/* common part */
unsigned char
reserved; /* always 0x'FF' */
unsigned short
cu_type; /* control unit type */
unsigned char
cu_model; /* control unit model */
unsigned short
dev_type; /* device type */
unsigned char
dev_model; /* device model */
unsigned char
unused; /* padding byte */
__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[62]; /* variable # of CIWs */
} senseid_t;
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 {
unsigned int et : 2;
// entry type
unsigned int reserved : 2;
// reserved
unsigned int ct : 4;
// command type
unsigned int cmd : 8;
// command
unsigned int count : 16;
// count
} ciw_t;
__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 :
...
...
@@ -252,7 +302,7 @@ 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
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.
...
...
@@ -269,7 +319,7 @@ 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(
unsigned int
devno );
int get_irq_by_devno(
__u16
devno );
unsigned int get_devno_by_irq( int irq );
...
...
@@ -336,6 +386,41 @@ 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
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 may be called enabled or disabled.
int read_conf_data( int irq, void **buffer, int *length, __u8 lpm);
irq - Specifies the subchannel the configuration data is to be
retrieved 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
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 - irq doesn't specify a valid subchannel number
-EINVAL - An invalid parameter was detected
-EIO - An irrecoverable I/O error occured 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.
request_irq() - Request Device Ownership
As previously discussed a device driver will scan for the devices its supports
...
...
@@ -343,6 +428,9 @@ 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 *,
...
...
@@ -354,27 +442,28 @@ int request_irq( unsigned int irq,
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,
must be 0 (zero) or SA_SAMPLE_RANDOM
irqflags : IRQ flags,
currently ignored
devname : device name
dev_id : required pointer to a device specific buffer of type
devstat_t
typedef struct {
unsigned int devno; /* device number
from irb */
unsigned
int intparm;
/* interrupt parameter */
unsigned char cstat;
/* channel status - accumulated */
unsigned char dstat;
/* device status - accumulated */
unsigned char lpum;
/* last path used mask from irb */
unsigned char unused;
/* not used - reserved */
__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 */
unsigned long cpa; /* CCW addr from irb at prim.
status */
unsigned int rescnt; /*
count from irb at primary status */
unsigned int scnt; /* sense count, if available
*/
__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;
} 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
...
...
@@ -396,9 +485,9 @@ 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()
to free_irq()
.
The only value parameter irqflags supports is SA_SAMPLE_RANDOM if appropriate
.
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.
...
...
@@ -416,6 +505,126 @@ 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
...
...
@@ -523,13 +732,13 @@ with the associated I/O request when calling do_IO().
int do_IO( int irq,
ccw1_t *cpa,
unsigned long intparm,
unsigned long
user_
intparm,
unsigned int lpm,
unsigned long flag);
irq : irq (subchannel) the I/O request is destined for
cpa : logical start address of channel program
intparm : user specific interrupt information; will be presented
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.
...
...
@@ -543,16 +752,25 @@ 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)
The cpa parameter points to the first format 1 CCW of a channel program :
typedef struct {
char cmd_code;
/* command code */
char flags; /* flags, like IDA ad
dressing, etc. */
unsigned short count;
/* byte count */
void *cda;
/* data address */
}
ccw1_t __attribute__ ((aligned(8)))
;
__u8 cmd_code;
/* command code */
__u8 flags; /* flags, like IDA a
dressing, etc. */
__u16 count;
/* byte count */
__u32 cda;
/* data address */
}
__attribute__ ((packed,aligned(8))) ccw1_t
;
with the following CCW flags values defined :
...
...
@@ -605,6 +823,9 @@ DEVSTAT_STATUS_PENDING - a pending status was found. The I/O
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
...
...
@@ -612,9 +833,9 @@ available in the sense area dev_id->ii.sense. No device sensing by the device
driver itself is required.
typedef struct {
unsigned char res[32];
/* reserved */
unsigned char data[32];
/* sense data */
}
sense_t;
__u8 res[32];
/* reserved */
__u8 data[32];
/* sense data */
} __attribute__ ((packed))
sense_t;
The device interrupt handler can use the following definitions to investigate
the primary unit check source coded in sense byte 0 :
...
...
@@ -625,6 +846,7 @@ SNS0_BUS_OUT_CHECK 0x20
SNS0_EQUIPMENT_CHECK 0x10
SNS0_DATA_CHECK 0x08
SNS0_OVERRUN 0x04
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.
...
...
@@ -661,12 +883,10 @@ 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 __save_flags( flags). The current PSW
flags are preserved and can be restored by __restore_flags( flags) at a
later time.
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
__save_flags( flags). The current PSW flags are preserved and can be restored
by __restore_flags( 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
...
...
@@ -674,7 +894,7 @@ 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) !
t
he driver must assure to hold the device specific lock. This can be
T
he driver must assure to hold the device specific lock. This can be
accomplished by
(i) s390irq_spin_lock( irq), or
...
...
@@ -705,6 +925,10 @@ 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
...
...
@@ -757,6 +981,34 @@ 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.
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
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
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.
int resume_IO( int irq);
irq : irq (subchannel) the halt operation is requested for
The resume_IO() function returns:
0 - suspended channel program is resumed
-EBUSY - status pending
-ENODEV - 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.
halt_IO() - Halt I/O Request Processing
...
...
@@ -766,8 +1018,8 @@ a halt subchannel (HSCH) I/O command. For those purposes the halt_IO() command
is provided.
int halt_IO( int irq, /* subchannel number */
int
intparm, /* dummy intparm */
unsigned
int
flag); /* operation mode */
unsigned long
intparm, /* dummy intparm */
unsigned
long
flag); /* operation mode */
irq : irq (subchannel) the halt operation is requested for
intparm : interruption parameter; value is only used if no I/O
...
...
@@ -867,7 +1119,7 @@ The set_cons_dev() function returns
reset_cons_dev - Reset Console Device
This routine allows for resetting the console device specification. See
se
t_cons_dev() for details.
wai
t_cons_dev() for details.
int reset_cons_dev( int irq);
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment