^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) /* SPDX-License-Identifier: GPL-2.0 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) #ifndef S390_IO_SCH_H
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) #define S390_IO_SCH_H
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) #include <linux/types.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) #include <asm/schid.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) #include <asm/ccwdev.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) #include <asm/irq.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) #include "css.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) #include "orb.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) struct io_subchannel_dma_area {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) struct ccw1 sense_ccw; /* static ccw for sense command */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) struct io_subchannel_private {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) union orb orb; /* operation request block */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) struct ccw_device *cdev;/* pointer to the child ccw device */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) struct {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) unsigned int suspend:1; /* allow suspend */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) unsigned int prefetch:1;/* deny prefetch */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) unsigned int inter:1; /* suppress intermediate interrupts */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) } __packed options;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) struct io_subchannel_dma_area *dma_area;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) dma_addr_t dma_area_dma;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) } __aligned(8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) #define to_io_private(n) ((struct io_subchannel_private *) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) dev_get_drvdata(&(n)->dev))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) #define set_io_private(n, p) (dev_set_drvdata(&(n)->dev, p))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) static inline struct ccw_device *sch_get_cdev(struct subchannel *sch)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) struct io_subchannel_private *priv = to_io_private(sch);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) return priv ? priv->cdev : NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) static inline void sch_set_cdev(struct subchannel *sch,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) struct ccw_device *cdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) struct io_subchannel_private *priv = to_io_private(sch);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) if (priv)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) priv->cdev = cdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) #define MAX_CIWS 8
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) * Possible status values for a CCW request's I/O.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) enum io_status {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) IO_DONE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) IO_RUNNING,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) IO_STATUS_ERROR,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) IO_PATH_ERROR,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) IO_REJECTED,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) IO_KILLED
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) * ccw_request - Internal CCW request.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) * @cp: channel program to start
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) * @timeout: maximum allowable time in jiffies between start I/O and interrupt
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) * @maxretries: number of retries per I/O operation and path
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) * @lpm: mask of paths to use
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) * @check: optional callback that determines if results are final
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) * @filter: optional callback to adjust request status based on IRB data
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) * @callback: final callback
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) * @data: user-defined pointer passed to all callbacks
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) * @singlepath: if set, use only one path from @lpm per start I/O
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) * @cancel: non-zero if request was cancelled
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) * @done: non-zero if request was finished
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) * @mask: current path mask
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) * @retries: current number of retries
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) * @drc: delayed return code
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) struct ccw_request {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) struct ccw1 *cp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) unsigned long timeout;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) u16 maxretries;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) u8 lpm;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) int (*check)(struct ccw_device *, void *);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) enum io_status (*filter)(struct ccw_device *, void *, struct irb *,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) enum io_status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) void (*callback)(struct ccw_device *, void *, int);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) void *data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) unsigned int singlepath:1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) /* These fields are used internally. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) unsigned int cancel:1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) unsigned int done:1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) u16 mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) u16 retries;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) int drc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) } __attribute__((packed));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) * sense-id response buffer layout
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) struct senseid {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) /* common part */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) u8 reserved; /* always 0x'FF' */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) u16 cu_type; /* control unit type */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) u8 cu_model; /* control unit model */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) u16 dev_type; /* device type */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) u8 dev_model; /* device model */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) u8 unused; /* padding byte */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) /* extended part */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) struct ciw ciw[MAX_CIWS]; /* variable # of CIWs */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) } __attribute__ ((packed, aligned(4)));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) enum cdev_todo {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) CDEV_TODO_NOTHING,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) CDEV_TODO_ENABLE_CMF,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) CDEV_TODO_REBIND,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) CDEV_TODO_REGISTER,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) CDEV_TODO_UNREG,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) CDEV_TODO_UNREG_EVAL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) #define FAKE_CMD_IRB 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) #define FAKE_TM_IRB 2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) struct ccw_device_dma_area {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) struct senseid senseid; /* SenseID info */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) struct ccw1 iccws[2]; /* ccws for SNID/SID/SPGID commands */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) struct irb irb; /* device status */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) struct pgid pgid[8]; /* path group IDs per chpid*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) struct ccw_device_private {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) struct ccw_device *cdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) struct subchannel *sch;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) int state; /* device state */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) atomic_t onoff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) struct ccw_dev_id dev_id; /* device id */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) struct ccw_request req; /* internal I/O request */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) int iretry;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) u8 pgid_valid_mask; /* mask of valid PGIDs */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) u8 pgid_todo_mask; /* mask of PGIDs to be adjusted */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) u8 pgid_reset_mask; /* mask of PGIDs which were reset */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) u8 path_noirq_mask; /* mask of paths for which no irq was
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) received */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) u8 path_notoper_mask; /* mask of paths which were found
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) not operable */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) u8 path_gone_mask; /* mask of paths, that became unavailable */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) u8 path_new_mask; /* mask of paths, that became available */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) u8 path_broken_mask; /* mask of paths, which were found to be
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) unusable */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) struct {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) unsigned int fast:1; /* post with "channel end" */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) unsigned int repall:1; /* report every interrupt status */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) unsigned int pgroup:1; /* do path grouping */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) unsigned int force:1; /* allow forced online */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) unsigned int mpath:1; /* do multipathing */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) } __attribute__ ((packed)) options;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) struct {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) unsigned int esid:1; /* Ext. SenseID supported by HW */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) unsigned int dosense:1; /* delayed SENSE required */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) unsigned int doverify:1; /* delayed path verification */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) unsigned int donotify:1; /* call notify function */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) unsigned int recog_done:1; /* dev. recog. complete */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) unsigned int fake_irb:2; /* deliver faked irb */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) unsigned int resuming:1; /* recognition while resume */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) unsigned int pgroup:1; /* pathgroup is set up */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) unsigned int mpath:1; /* multipathing is set up */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) unsigned int pgid_unknown:1;/* unknown pgid state */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) unsigned int initialized:1; /* set if initial reference held */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) } __attribute__((packed)) flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) unsigned long intparm; /* user interruption parameter */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) struct qdio_irq *qdio_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) int async_kill_io_rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) struct work_struct todo_work;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) enum cdev_todo todo;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) wait_queue_head_t wait_q;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) struct timer_list timer;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) void *cmb; /* measurement information */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) struct list_head cmb_list; /* list of measured devices */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) u64 cmb_start_time; /* clock value of cmb reset */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) void *cmb_wait; /* deferred cmb enable/disable */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) struct gen_pool *dma_pool;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) struct ccw_device_dma_area *dma_area;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) enum interruption_class int_class;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) #endif