mirror of
https://github.com/AetherDroid/android_kernel_samsung_on5xelte.git
synced 2025-09-06 16:28:04 -04:00
Fixed MTP to work with TWRP
This commit is contained in:
commit
f6dfaef42e
50820 changed files with 20846062 additions and 0 deletions
472
Documentation/s390/cds.txt
Normal file
472
Documentation/s390/cds.txt
Normal file
|
@ -0,0 +1,472 @@
|
|||
Linux for S/390 and zSeries
|
||||
|
||||
Common Device Support (CDS)
|
||||
Device Driver I/O Support Routines
|
||||
|
||||
Authors : Ingo Adlung
|
||||
Cornelia Huck
|
||||
|
||||
Copyright, IBM Corp. 1999-2002
|
||||
|
||||
Introduction
|
||||
|
||||
This document describes the common device support routines for Linux/390.
|
||||
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
|
||||
I/O (PIO), and other hardware features more. However, this implies that
|
||||
either every single device driver needs to implement the hardware I/O
|
||||
attachment functionality itself, or the operating system provides for a
|
||||
unified method to access the hardware, providing all the functionality that
|
||||
every single device driver would have to provide itself.
|
||||
|
||||
The document does not intend to explain the ESA/390 hardware architecture in
|
||||
every detail.This information can be obtained from the ESA/390 Principles of
|
||||
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 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.
|
||||
|
||||
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().
|
||||
* Instead of calling read_dev_chars()/read_conf_data(), the driver issues
|
||||
the channel program and handles the interrupt itself.
|
||||
|
||||
ccw_device_get_ciw()
|
||||
get commands from extended sense data.
|
||||
|
||||
ccw_device_start()
|
||||
ccw_device_start_timeout()
|
||||
ccw_device_start_key()
|
||||
ccw_device_start_key_timeout()
|
||||
initiate an I/O request.
|
||||
|
||||
ccw_device_resume()
|
||||
resume channel program execution.
|
||||
|
||||
ccw_device_halt()
|
||||
terminate the current I/O request processed on the device.
|
||||
|
||||
do_IRQ()
|
||||
generic interrupt routine. This function is called by the interrupt entry
|
||||
routine whenever an I/O interrupt is presented to the system. The do_IRQ()
|
||||
routine determines the interrupt status and calls the device specific
|
||||
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 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
|
||||
|
||||
General Information
|
||||
|
||||
The following chapters describe the I/O related interface routines the
|
||||
Linux/390 common device support (CDS) provides to allow for device specific
|
||||
driver implementations on the IBM ESA/390 hardware platform. Those interfaces
|
||||
intend to provide the functionality required by every device driver
|
||||
implementation to allow to drive a specific hardware device on the ESA/390
|
||||
platform. Some of the interface routines are specific to Linux/390 and some
|
||||
of them can be found on other Linux platforms implementations too.
|
||||
Miscellaneous function prototypes, data declarations, and macro definitions
|
||||
can be found in the architecture specific C header file
|
||||
linux/arch/s390/include/asm/irq.h.
|
||||
|
||||
Overview of CDS interface concepts
|
||||
|
||||
Different to other hardware platforms, the ESA/390 architecture doesn't define
|
||||
interrupt lines managed by a specific interrupt controller and bus systems
|
||||
that may or may not allow for shared interrupts, DMA processing, etc.. Instead,
|
||||
the ESA/390 architecture has implemented a so called channel subsystem, that
|
||||
provides a unified view of the devices physically attached to the systems.
|
||||
Though the ESA/390 hardware platform knows about a huge variety of different
|
||||
peripheral attachments like disk devices (aka. DASDs), tapes, communication
|
||||
controllers, etc. they can all be accessed by a well defined access method and
|
||||
they are presenting I/O completion a unified way : I/O interruptions. Every
|
||||
single device is uniquely identified to the system by a so called subchannel,
|
||||
where the ESA/390 architecture allows for 64k devices be attached.
|
||||
|
||||
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
|
||||
not share interrupt levels (aka. IRQs), as the ISA bus bases on edge triggered
|
||||
interrupts. MCA, EISA, PCI and other bus systems base on level triggered
|
||||
interrupts, and therewith allow for shared IRQs. However, if multiple devices
|
||||
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.
|
||||
|
||||
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 cannot exceed 65535. During sysfs
|
||||
initialisation, the information about control unit type and device types that
|
||||
imply specific I/O commands (channel command words - CCWs) in order to operate
|
||||
the device are gathered. Device drivers can retrieve this set of hardware
|
||||
information during their initialization step to recognize the devices they
|
||||
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 issue the READ DEVICE CHARACTERISTICS
|
||||
ccw to retrieve device characteristics in its online routine.
|
||||
|
||||
In order to allow for easy I/O initiation the CDS layer provides a
|
||||
ccw_device_start() interface that takes a device specific channel program (one
|
||||
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
|
||||
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().
|
||||
|
||||
|
||||
get_ciw() - get command information word
|
||||
|
||||
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);
|
||||
|
||||
cdev - The ccw_device for which the command is to be retrieved.
|
||||
cmd - The command type to be retrieved.
|
||||
|
||||
ccw_device_get_ciw() returns:
|
||||
NULL - No extended data available, invalid device or command not found.
|
||||
!NULL - The command requested.
|
||||
|
||||
|
||||
ccw_device_start() - Initiate I/O Request
|
||||
|
||||
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 ccw_device_start().
|
||||
|
||||
int ccw_device_start(struct ccw_device *cdev,
|
||||
struct ccw1 *cpa,
|
||||
unsigned long intparm,
|
||||
__u8 lpm,
|
||||
unsigned long flags);
|
||||
int ccw_device_start_timeout(struct ccw_device *cdev,
|
||||
struct ccw1 *cpa,
|
||||
unsigned long intparm,
|
||||
__u8 lpm,
|
||||
unsigned long flags,
|
||||
int expires);
|
||||
int ccw_device_start_key(struct ccw_device *cdev,
|
||||
struct ccw1 *cpa,
|
||||
unsigned long intparm,
|
||||
__u8 lpm,
|
||||
__u8 key,
|
||||
unsigned long flags);
|
||||
int ccw_device_start_key_timeout(struct ccw_device *cdev,
|
||||
struct ccw1 *cpa,
|
||||
unsigned long intparm,
|
||||
__u8 lpm,
|
||||
__u8 key,
|
||||
unsigned long flags,
|
||||
int expires);
|
||||
|
||||
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. A value of 0 will make cio use the opm.
|
||||
key : the storage key to use for the I/O (useful for operating on a
|
||||
storage with a storage key != default key)
|
||||
flag : defines the action to be performed for I/O processing
|
||||
expires : timeout value in jiffies. The common I/O layer will terminate
|
||||
the running program after this and call the interrupt handler
|
||||
with ERR_PTR(-ETIMEDOUT) as irb.
|
||||
|
||||
Possible flag values are :
|
||||
|
||||
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_SUPPRESS_INTER - don't call the handler on intermediate status
|
||||
|
||||
The cpa parameter points to the first format 1 CCW of a channel program :
|
||||
|
||||
struct ccw1 {
|
||||
__u8 cmd_code;/* command code */
|
||||
__u8 flags; /* flags, like IDA addressing, etc. */
|
||||
__u16 count; /* byte count */
|
||||
__u32 cda; /* data address */
|
||||
} __attribute__ ((packed,aligned(8)));
|
||||
|
||||
with the following CCW flags values defined :
|
||||
|
||||
CCW_FLAG_DC - data chaining
|
||||
CCW_FLAG_CC - command chaining
|
||||
CCW_FLAG_SLI - suppress incorrect length
|
||||
CCW_FLAG_SKIP - skip
|
||||
CCW_FLAG_PCI - PCI
|
||||
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 ccw_device_start() function returns :
|
||||
|
||||
0 - successful completion or request successfully initiated
|
||||
-EBUSY - The device is currently processing a previous I/O request, or there is
|
||||
a status pending at the device.
|
||||
-ENODEV - cdev is invalid, the device is not operational or the ccw_device is
|
||||
not online.
|
||||
|
||||
When the I/O request completes, the CDS first level interrupt handler will
|
||||
accumulate 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.
|
||||
|
||||
The irb may contain an error value, and the device driver should check for this
|
||||
first:
|
||||
|
||||
-ETIMEDOUT: the common I/O layer terminated the request after the specified
|
||||
timeout value
|
||||
-EIO: the common I/O layer terminated the request due to an error state
|
||||
|
||||
If the concurrent sense flag in the extended status word (esw) in the irb is
|
||||
set, the field erw.scnt in the esw describes the number of device specific
|
||||
sense bytes available in the extended control word irb->scsw.ecw[]. No device
|
||||
sensing by the device driver itself is required.
|
||||
|
||||
The device interrupt handler can use the following definitions to investigate
|
||||
the primary unit check source coded in sense byte 0 :
|
||||
|
||||
SNS0_CMD_REJECT 0x80
|
||||
SNS0_INTERVENTION_REQ 0x40
|
||||
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.
|
||||
|
||||
The irb->scsw.cstat field provides the (accumulated) subchannel status :
|
||||
|
||||
SCHN_STAT_PCI - program controlled interrupt
|
||||
SCHN_STAT_INCORR_LEN - incorrect length
|
||||
SCHN_STAT_PROG_CHECK - program check
|
||||
SCHN_STAT_PROT_CHECK - protection check
|
||||
SCHN_STAT_CHN_DATA_CHK - channel data check
|
||||
SCHN_STAT_CHN_CTRL_CHK - channel control check
|
||||
SCHN_STAT_INTF_CTRL_CHK - interface control check
|
||||
SCHN_STAT_CHAIN_CHECK - chaining check
|
||||
|
||||
The irb->scsw.dstat field provides the (accumulated) device status :
|
||||
|
||||
DEV_STAT_ATTENTION - attention
|
||||
DEV_STAT_STAT_MOD - status modifier
|
||||
DEV_STAT_CU_END - control unit end
|
||||
DEV_STAT_BUSY - busy
|
||||
DEV_STAT_CHN_END - channel end
|
||||
DEV_STAT_DEV_END - device end
|
||||
DEV_STAT_UNIT_CHECK - unit check
|
||||
DEV_STAT_UNIT_EXCEP - unit exception
|
||||
|
||||
Please see the ESA/390 Principles of Operation manual for details on the
|
||||
individual flag meanings.
|
||||
|
||||
Usage Notes :
|
||||
|
||||
ccw_device_start() must be called disabled and with the ccw device lock held.
|
||||
|
||||
The device driver is allowed to issue the next ccw_device_start() call from
|
||||
within its interrupt handler already. It is not required to schedule a
|
||||
bottom-half, unless a non deterministically long running error recovery procedure
|
||||
or similar needs to be scheduled. During I/O processing the Linux/390 generic
|
||||
I/O device driver support has already obtained the IRQ lock, i.e. the handler
|
||||
must not try to obtain it again when calling ccw_device_start() or we end in a
|
||||
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
|
||||
CCW_CMD_NOOP to the end of the submitted CCW chain. This will force Channel-End
|
||||
and Device-End status to be presented together, with a single interrupt.
|
||||
However, this should be used with care as it implies the channel will remain
|
||||
busy, not being able to process I/O requests for other devices on the same
|
||||
channel. Therefore e.g. read commands should never use this technique, as the
|
||||
result will be presented by a single interrupt anyway.
|
||||
|
||||
In order to minimize I/O overhead, a device driver should use the
|
||||
DOIO_REPORT_ALL only if the device can report intermediate interrupt
|
||||
information prior to device-end the device driver urgently relies on. In this
|
||||
case all I/O interruptions are presented to the device driver until final
|
||||
status is recognized.
|
||||
|
||||
If a device is able to recover from asynchronously presented I/O errors, it can
|
||||
perform overlapping I/O using the DOIO_EARLY_NOTIFICATION flag. While some
|
||||
devices always report channel-end and device-end together, with a single
|
||||
interrupt, others present primary status (channel-end) when the channel is
|
||||
ready for the next I/O request and secondary status (device-end) when the data
|
||||
transmission has been completed at the device.
|
||||
|
||||
Above flag allows to exploit this feature, e.g. for communication devices that
|
||||
can handle lost data on the network to allow for enhanced I/O processing.
|
||||
|
||||
Unless the channel subsystem at any time presents a secondary status interrupt,
|
||||
exploiting this feature will cause only primary status interrupts 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 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
|
||||
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.
|
||||
|
||||
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 ccw_device_resume() routine.
|
||||
|
||||
int ccw_device_resume(struct ccw_device *cdev);
|
||||
|
||||
cdev - ccw_device the resume operation is requested for
|
||||
|
||||
The ccw_device_resume() function returns:
|
||||
|
||||
0 - suspended channel program is resumed
|
||||
-EBUSY - status pending
|
||||
-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 ccw_device_start() usage notes for more details on
|
||||
suspended channel programs.
|
||||
|
||||
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 ccw_device_halt()
|
||||
command is provided.
|
||||
|
||||
ccw_device_halt() must be called disabled and with the ccw device lock held.
|
||||
|
||||
int ccw_device_halt(struct ccw_device *cdev,
|
||||
unsigned long intparm);
|
||||
|
||||
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
|
||||
|
||||
The ccw_device_halt() function returns :
|
||||
|
||||
0 - request successfully initiated
|
||||
-EBUSY - the device is currently busy, or status pending.
|
||||
-ENODEV - cdev invalid.
|
||||
-EINVAL - The device is not operational or the ccw device is not online.
|
||||
|
||||
Usage Notes :
|
||||
|
||||
A device driver may write a never-ending channel program by writing a channel
|
||||
program that at its end loops back to its beginning by means of a transfer in
|
||||
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 ccw_device_halt()
|
||||
is required to end the pending operation.
|
||||
|
||||
ccw_device_clear() - Terminage I/O Request Processing
|
||||
|
||||
In order to terminate all I/O processing at the subchannel, the clear subchannel
|
||||
(CSCH) command is used. It can be issued via ccw_device_clear().
|
||||
|
||||
ccw_device_clear() must be called disabled and with the ccw device lock held.
|
||||
|
||||
int ccw_device_clear(struct ccw_device *cdev, unsigned long intparm);
|
||||
|
||||
cdev: ccw_device the clear operation is requested for
|
||||
intparm: interruption parameter (see ccw_device_halt())
|
||||
|
||||
The ccw_device_clear() function returns:
|
||||
|
||||
0 - request successfully initiated
|
||||
-ENODEV - cdev invalid
|
||||
-EINVAL - The device is not operational or the ccw device is not online.
|
||||
|
||||
Miscellaneous Support Routines
|
||||
|
||||
This chapter describes various routines to be used in a Linux/390 device
|
||||
driver programming environment.
|
||||
|
||||
get_ccwdev_lock()
|
||||
|
||||
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.
|
Loading…
Add table
Add a link
Reference in a new issue