1b2441318SGreg Kroah-Hartman /* SPDX-License-Identifier: GPL-2.0 */
21da177e4SLinus Torvalds #ifndef S390_DEVICE_H
31da177e4SLinus Torvalds #define S390_DEVICE_H
41da177e4SLinus Torvalds
540154b82SPeter Oberparleiter #include <asm/ccwdev.h>
660063497SArun Sharma #include <linux/atomic.h>
7*846d0c6fSKees Cook #include <linux/timer.h>
840154b82SPeter Oberparleiter #include <linux/wait.h>
976e6fb4bSSebastian Ott #include <linux/notifier.h>
10de400d6bSPeter Oberparleiter #include <linux/kernel_stat.h>
11cd6b4f27SCornelia Huck #include "io_sch.h"
12cd6b4f27SCornelia Huck
131da177e4SLinus Torvalds /*
141da177e4SLinus Torvalds * states of the device statemachine
151da177e4SLinus Torvalds */
161da177e4SLinus Torvalds enum dev_state {
171da177e4SLinus Torvalds DEV_STATE_NOT_OPER,
181da177e4SLinus Torvalds DEV_STATE_SENSE_ID,
191da177e4SLinus Torvalds DEV_STATE_OFFLINE,
201da177e4SLinus Torvalds DEV_STATE_VERIFY,
211da177e4SLinus Torvalds DEV_STATE_ONLINE,
221da177e4SLinus Torvalds DEV_STATE_W4SENSE,
231da177e4SLinus Torvalds DEV_STATE_DISBAND_PGID,
241da177e4SLinus Torvalds DEV_STATE_BOXED,
251da177e4SLinus Torvalds /* states to wait for i/o completion before doing something */
261da177e4SLinus Torvalds DEV_STATE_TIMEOUT_KILL,
271da177e4SLinus Torvalds DEV_STATE_QUIESCE,
281da177e4SLinus Torvalds /* special states for devices gone not operational */
291da177e4SLinus Torvalds DEV_STATE_DISCONNECTED,
301da177e4SLinus Torvalds DEV_STATE_DISCONNECTED_SENSE_ID,
311da177e4SLinus Torvalds DEV_STATE_CMFCHANGE,
3294bb0633SCornelia Huck DEV_STATE_CMFUPDATE,
33d7d12ef2SPeter Oberparleiter DEV_STATE_STEAL_LOCK,
341da177e4SLinus Torvalds /* last element! */
351da177e4SLinus Torvalds NR_DEV_STATES
361da177e4SLinus Torvalds };
371da177e4SLinus Torvalds
381da177e4SLinus Torvalds /*
391da177e4SLinus Torvalds * asynchronous events of the device statemachine
401da177e4SLinus Torvalds */
411da177e4SLinus Torvalds enum dev_event {
421da177e4SLinus Torvalds DEV_EVENT_NOTOPER,
431da177e4SLinus Torvalds DEV_EVENT_INTERRUPT,
441da177e4SLinus Torvalds DEV_EVENT_TIMEOUT,
451da177e4SLinus Torvalds DEV_EVENT_VERIFY,
461da177e4SLinus Torvalds /* last element! */
471da177e4SLinus Torvalds NR_DEV_EVENTS
481da177e4SLinus Torvalds };
491da177e4SLinus Torvalds
501da177e4SLinus Torvalds struct ccw_device;
511da177e4SLinus Torvalds
521da177e4SLinus Torvalds /*
531da177e4SLinus Torvalds * action called through jumptable
541da177e4SLinus Torvalds */
551da177e4SLinus Torvalds typedef void (fsm_func_t)(struct ccw_device *, enum dev_event);
561da177e4SLinus Torvalds extern fsm_func_t *dev_jumptable[NR_DEV_STATES][NR_DEV_EVENTS];
571da177e4SLinus Torvalds
581da177e4SLinus Torvalds static inline void
dev_fsm_event(struct ccw_device * cdev,enum dev_event dev_event)591da177e4SLinus Torvalds dev_fsm_event(struct ccw_device *cdev, enum dev_event dev_event)
601da177e4SLinus Torvalds {
61de400d6bSPeter Oberparleiter int state = cdev->private->state;
62de400d6bSPeter Oberparleiter
63de400d6bSPeter Oberparleiter if (dev_event == DEV_EVENT_INTERRUPT) {
64de400d6bSPeter Oberparleiter if (state == DEV_STATE_ONLINE)
65420f42ecSHeiko Carstens inc_irq_stat(cdev->private->int_class);
66de400d6bSPeter Oberparleiter else if (state != DEV_STATE_CMFCHANGE &&
67de400d6bSPeter Oberparleiter state != DEV_STATE_CMFUPDATE)
68420f42ecSHeiko Carstens inc_irq_stat(IRQIO_CIO);
69de400d6bSPeter Oberparleiter }
70de400d6bSPeter Oberparleiter dev_jumptable[state][dev_event](cdev, dev_event);
711da177e4SLinus Torvalds }
721da177e4SLinus Torvalds
731da177e4SLinus Torvalds /*
741da177e4SLinus Torvalds * Delivers 1 if the device state is final.
751da177e4SLinus Torvalds */
761da177e4SLinus Torvalds static inline int
dev_fsm_final_state(struct ccw_device * cdev)771da177e4SLinus Torvalds dev_fsm_final_state(struct ccw_device *cdev)
781da177e4SLinus Torvalds {
791da177e4SLinus Torvalds return (cdev->private->state == DEV_STATE_NOT_OPER ||
801da177e4SLinus Torvalds cdev->private->state == DEV_STATE_OFFLINE ||
811da177e4SLinus Torvalds cdev->private->state == DEV_STATE_ONLINE ||
821da177e4SLinus Torvalds cdev->private->state == DEV_STATE_BOXED);
831da177e4SLinus Torvalds }
841da177e4SLinus Torvalds
852f17644dSSebastian Ott int __init io_subchannel_init(void);
861da177e4SLinus Torvalds
871da177e4SLinus Torvalds void io_subchannel_recog_done(struct ccw_device *cdev);
8813952ec1SSebastian Ott void io_subchannel_init_config(struct subchannel *sch);
891da177e4SLinus Torvalds
901da177e4SLinus Torvalds int ccw_device_cancel_halt_clear(struct ccw_device *);
911da177e4SLinus Torvalds
92d7b5a4c9SCornelia Huck int ccw_device_is_orphan(struct ccw_device *);
931da177e4SLinus Torvalds
94736b5db8SPeter Oberparleiter void ccw_device_recognition(struct ccw_device *);
951da177e4SLinus Torvalds int ccw_device_online(struct ccw_device *);
961da177e4SLinus Torvalds int ccw_device_offline(struct ccw_device *);
97823d494aSSebastian Ott void ccw_device_update_sense_data(struct ccw_device *);
98823d494aSSebastian Ott int ccw_device_test_sense_data(struct ccw_device *);
99ecf5d9efSPeter Oberparleiter int ccw_purge_blacklisted(void);
10037de53bbSPeter Oberparleiter void ccw_device_sched_todo(struct ccw_device *cdev, enum cdev_todo todo);
101b7a610f7SSebastian Ott struct ccw_device *get_ccwdev_by_dev_id(struct ccw_dev_id *dev_id);
1021da177e4SLinus Torvalds
1031da177e4SLinus Torvalds /* Function prototypes for device status and basic sense stuff. */
1041da177e4SLinus Torvalds void ccw_device_accumulate_irb(struct ccw_device *, struct irb *);
1051da177e4SLinus Torvalds void ccw_device_accumulate_basic_sense(struct ccw_device *, struct irb *);
1061da177e4SLinus Torvalds int ccw_device_accumulate_and_sense(struct ccw_device *, struct irb *);
1071da177e4SLinus Torvalds int ccw_device_do_sense(struct ccw_device *, struct irb *);
1081da177e4SLinus Torvalds
109e1f0fbd6SPeter Oberparleiter /* Function prototype for internal request handling. */
110e1f0fbd6SPeter Oberparleiter int lpm_adjust(int lpm, int mask);
111e1f0fbd6SPeter Oberparleiter void ccw_request_start(struct ccw_device *);
112e1f0fbd6SPeter Oberparleiter int ccw_request_cancel(struct ccw_device *cdev);
113e1f0fbd6SPeter Oberparleiter void ccw_request_handler(struct ccw_device *cdev);
114e1f0fbd6SPeter Oberparleiter void ccw_request_timeout(struct ccw_device *cdev);
115e1f0fbd6SPeter Oberparleiter void ccw_request_notoper(struct ccw_device *cdev);
116e1f0fbd6SPeter Oberparleiter
1171da177e4SLinus Torvalds /* Function prototypes for sense id stuff. */
1181da177e4SLinus Torvalds void ccw_device_sense_id_start(struct ccw_device *);
1191da177e4SLinus Torvalds void ccw_device_sense_id_done(struct ccw_device *, int);
1201da177e4SLinus Torvalds
1211da177e4SLinus Torvalds /* Function prototypes for path grouping stuff. */
1221da177e4SLinus Torvalds void ccw_device_verify_start(struct ccw_device *);
1231da177e4SLinus Torvalds void ccw_device_verify_done(struct ccw_device *, int);
1241da177e4SLinus Torvalds
1251da177e4SLinus Torvalds void ccw_device_disband_start(struct ccw_device *);
1261da177e4SLinus Torvalds void ccw_device_disband_done(struct ccw_device *, int);
1271da177e4SLinus Torvalds
1281da177e4SLinus Torvalds int ccw_device_stlck(struct ccw_device *);
1291da177e4SLinus Torvalds
130c820de39SCornelia Huck /* Helper function for machine check handling. */
131c820de39SCornelia Huck void ccw_device_trigger_reprobe(struct ccw_device *);
132c820de39SCornelia Huck void ccw_device_kill_io(struct ccw_device *);
133c820de39SCornelia Huck int ccw_device_notify(struct ccw_device *, int);
1346afcc775SPeter Oberparleiter void ccw_device_set_disconnected(struct ccw_device *cdev);
13591c36919SPeter Oberparleiter void ccw_device_set_notoper(struct ccw_device *cdev);
136c820de39SCornelia Huck
137*846d0c6fSKees Cook void ccw_device_timeout(struct timer_list *t);
1381da177e4SLinus Torvalds void ccw_device_set_timeout(struct ccw_device *, int);
13955fb7347SSebastian Ott void ccw_device_schedule_recovery(void);
1401da177e4SLinus Torvalds
14194bb0633SCornelia Huck /* Channel measurement facility related */
1421da177e4SLinus Torvalds void retry_set_schib(struct ccw_device *cdev);
14394bb0633SCornelia Huck void cmf_retry_copy_block(struct ccw_device *);
14494bb0633SCornelia Huck int cmf_reenable(struct ccw_device *);
145ab97d211SSebastian Ott void cmf_reactivate(void);
146a806170eSHeiko Carstens extern struct device_attribute dev_attr_cmb_enable;
1471da177e4SLinus Torvalds #endif
148