cds.txt
来自「Linux Kernel 2.6.9 for OMAP1710」· 文本 代码 · 共 514 行 · 第 1/2 页
TXT
514 行
driver's interrupt handler as this is related to the rules (flags) definedwith 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);cdev : ccw_device the I/O is destined forcpa : logical start address of channel programuser_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.flag : defines the action to be performed for I/O processingPossible flag values are :DOIO_ALLOW_SUSPEND - channel program may become suspendedDOIO_DENY_PREFETCH - don't allow for CCW prefetch; usually this implies the channel program might become modifiedDOIO_SUPPRESS_INTER - don't call the handler on intermediate statusThe 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 chainingCCW_FLAG_CC - command chainingCCW_FLAG_SLI - suppress incorrct lengthCCW_FLAG_SKIP - skipCCW_FLAG_PCI - PCICCW_FLAG_IDA - indirect addressingCCW_FLAG_SUSPEND - suspendVia ccw_device_set_options(), the device driver may specify the followingoptions for the device:DOIO_EARLY_NOTIFICATION - allow for early interrupt notificationDOIO_REPORT_ALL - report all interrupt conditionsThe ccw_device_start() function returns : 0 - successful completion or request successfully initiated-EBUSY - The device is currently processing a previous I/O request, or ther is 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 willaccumalate 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 delayedby an alert status notification. In any case this status is not related to thecurrent (last) I/O request. In case of a delayed status notification no specialinterrupt will be presented to indicate I/O completion as the I/O request wasnever 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, thefield irb->scsw.count describes the numer of device specific sense bytesavailable in the extended control word irb->scsw.ecw[0]. No device sensing bythe device driver itself is required.The device interrupt handler can use the following definitions to investigatethe primary unit check source coded in sense byte 0 :SNS0_CMD_REJECT 0x80SNS0_INTERVENTION_REQ 0x40SNS0_BUS_OUT_CHECK 0x20SNS0_EQUIPMENT_CHECK 0x10SNS0_DATA_CHECK 0x08SNS0_OVERRUN 0x04SNS0_INCOMPL_DOMAIN 0x01Depending 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 interruptSCHN_STAT_INCORR_LEN - incorrect lengthSCHN_STAT_PROG_CHECK - program checkSCHN_STAT_PROT_CHECK - protection checkSCHN_STAT_CHN_DATA_CHK - channel data checkSCHN_STAT_CHN_CTRL_CHK - channel control checkSCHN_STAT_INTF_CTRL_CHK - interface control checkSCHN_STAT_CHAIN_CHECK - chaining checkThe irb->scsw.dstat field provides the (accumulated) device status :DEV_STAT_ATTENTION - attentionDEV_STAT_STAT_MOD - status modifierDEV_STAT_CU_END - control unit endDEV_STAT_BUSY - busyDEV_STAT_CHN_END - channel endDEV_STAT_DEV_END - device endDEV_STAT_UNIT_CHECK - unit checkDEV_STAT_UNIT_EXCEP - unit exceptionPlease see the ESA/390 Principles of Operation manual for details on theindividual flag meanings.Usage Notes :Prior to call ccw_device_start() the device driver must assure disabled state,i.e. the I/O mask value in the PSW must be disabled. This can be accomplishedby calling local_save_flags( flags). The current PSW flags are preserved andcan be restored by local_irq_restore( flags) at a later time.If the device driver violates this rule while running in a uni-processorenvironment 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 adeadlock situation as the interrupt handler will try to obtain the irqlock the device driver still owns (see below) !The driver must assure to hold the device specific lock. This can beaccomplished by(i) spin_lock(get_ccwdev_lock(cdev)), or(ii) spin_lock_irqsave(get_ccwdev_lock(cdev), flags)Option (i) should be used if the calling routine is running disabled forI/O interrupts (see above) already. Option (ii) obtains the device gate undputs the CPU into I/O disabled state by preserving the current PSW flags.The device driver is allowed to issue the next ccw_device_start() call fromwithin its interrupt handler already. It is not required to schedule abottom-half, unless an non deterministicly long running error recovery procedureor similar needs to be scheduled. During I/O processing the Linux/390 genericI/O device driver support has already obtained the IRQ lock, i.e. the handlermust not try to obtain it again when calling ccw_device_start() or we end in adeadlock situation!If a device driver relies on an I/O request to be completed prior to start thenext it can reduce I/O processing overhead by chaining a NoOp I/O commandCCW_CMD_NOOP to the end of the submitted CCW chain. This will force Channel-Endand Device-End status to be presented together, with a single interrupt.However, this should be used with care as it implies the channel will remainbusy, not being able to process I/O requests for other devices on the samechannel. Therefore e.g. read commands should never use this technique, as theresult will be presented by a single interrupt anyway.In order to minimize I/O overhead, a device driver should use theDOIO_REPORT_ALL only if the device can report intermediate interruptinformation prior to device-end the device driver urgently relies on. In thiscase all I/O interruptions are presented to the device driver until finalstatus is recognized.If a device is able to recover from asynchronosly presented I/O errors, it canperform overlapping I/O using the DOIO_EARLY_NOTIFICATION flag. While somedevices always report channel-end and device-end together, with a singleinterrupt, others present primary status (channel-end) when the channel isready for the next I/O request and secondary status (device-end) when the datatransmission has been completed at the device.Above flag allows to exploit this feature, e.g. for communication devices thatcan 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 bepresented to the device driver while overlapping I/O is performed. When asecondary status without error (alert status) is presented, this indicatessuccessful completion for all overlapping ccw_device_start() requests that havebeen 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 forThe resume_IO() 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 onsuspended channel programs.ccw_device_halt() - Halt I/O Request ProcessingSometimes a device driver might need a possibility to stop the processing ofa long-running channel program or the device might require to initially issuea halt subchannel (HSCH) I/O command. For those purposes the ccw_device_halt()command is provided.int ccw_device_halt(struct ccw_device *cdev, unsigned long intparm);cdev : ccw_device the halt operation is requested forintparm : interruption parameter; value is only used if no I/O is outstanding, otherwise the intparm associated with the I/O request is returnedThe ccw_device_halt() function returns : 0 - successful completion or 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 channelprogram that at its end loops back to its beginning by means of a transfer inchannel (TIC) command (CCW_CMD_TIC). Usually this is performed by networkdevice drivers by setting the PCI CCW flag (CCW_FLAG_PCI). Once this CCW isexecuted a program controlled interrupt (PCI) is generated. The device drivercan then perform an appropriate action. Prior to interrupt of an outstandingread to a network device (with or without PCI flag) a ccw_device_halt()is required to end the pending operation.Miscellaneous Support RoutinesThis chapter describes various routines to be used in a Linux/390 devicedriver programming environment.get_ccwdev_lock()Get the address of the device specific lock. This is then used inspin_lock() / spin_unlock() calls.__u8 ccw_device_get_path_mask(struct ccw_device *cdev);Get the mask of the path currently available for cdev.
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?