18c2ecf20Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0 */ 28c2ecf20Sopenharmony_ci#ifndef S390_IO_SCH_H 38c2ecf20Sopenharmony_ci#define S390_IO_SCH_H 48c2ecf20Sopenharmony_ci 58c2ecf20Sopenharmony_ci#include <linux/types.h> 68c2ecf20Sopenharmony_ci#include <asm/schid.h> 78c2ecf20Sopenharmony_ci#include <asm/ccwdev.h> 88c2ecf20Sopenharmony_ci#include <asm/irq.h> 98c2ecf20Sopenharmony_ci#include "css.h" 108c2ecf20Sopenharmony_ci#include "orb.h" 118c2ecf20Sopenharmony_ci 128c2ecf20Sopenharmony_cistruct io_subchannel_dma_area { 138c2ecf20Sopenharmony_ci struct ccw1 sense_ccw; /* static ccw for sense command */ 148c2ecf20Sopenharmony_ci}; 158c2ecf20Sopenharmony_ci 168c2ecf20Sopenharmony_cistruct io_subchannel_private { 178c2ecf20Sopenharmony_ci union orb orb; /* operation request block */ 188c2ecf20Sopenharmony_ci struct ccw_device *cdev;/* pointer to the child ccw device */ 198c2ecf20Sopenharmony_ci struct { 208c2ecf20Sopenharmony_ci unsigned int suspend:1; /* allow suspend */ 218c2ecf20Sopenharmony_ci unsigned int prefetch:1;/* deny prefetch */ 228c2ecf20Sopenharmony_ci unsigned int inter:1; /* suppress intermediate interrupts */ 238c2ecf20Sopenharmony_ci } __packed options; 248c2ecf20Sopenharmony_ci struct io_subchannel_dma_area *dma_area; 258c2ecf20Sopenharmony_ci dma_addr_t dma_area_dma; 268c2ecf20Sopenharmony_ci} __aligned(8); 278c2ecf20Sopenharmony_ci 288c2ecf20Sopenharmony_ci#define to_io_private(n) ((struct io_subchannel_private *) \ 298c2ecf20Sopenharmony_ci dev_get_drvdata(&(n)->dev)) 308c2ecf20Sopenharmony_ci#define set_io_private(n, p) (dev_set_drvdata(&(n)->dev, p)) 318c2ecf20Sopenharmony_ci 328c2ecf20Sopenharmony_cistatic inline struct ccw_device *sch_get_cdev(struct subchannel *sch) 338c2ecf20Sopenharmony_ci{ 348c2ecf20Sopenharmony_ci struct io_subchannel_private *priv = to_io_private(sch); 358c2ecf20Sopenharmony_ci return priv ? priv->cdev : NULL; 368c2ecf20Sopenharmony_ci} 378c2ecf20Sopenharmony_ci 388c2ecf20Sopenharmony_cistatic inline void sch_set_cdev(struct subchannel *sch, 398c2ecf20Sopenharmony_ci struct ccw_device *cdev) 408c2ecf20Sopenharmony_ci{ 418c2ecf20Sopenharmony_ci struct io_subchannel_private *priv = to_io_private(sch); 428c2ecf20Sopenharmony_ci if (priv) 438c2ecf20Sopenharmony_ci priv->cdev = cdev; 448c2ecf20Sopenharmony_ci} 458c2ecf20Sopenharmony_ci 468c2ecf20Sopenharmony_ci#define MAX_CIWS 8 478c2ecf20Sopenharmony_ci 488c2ecf20Sopenharmony_ci/* 498c2ecf20Sopenharmony_ci * Possible status values for a CCW request's I/O. 508c2ecf20Sopenharmony_ci */ 518c2ecf20Sopenharmony_cienum io_status { 528c2ecf20Sopenharmony_ci IO_DONE, 538c2ecf20Sopenharmony_ci IO_RUNNING, 548c2ecf20Sopenharmony_ci IO_STATUS_ERROR, 558c2ecf20Sopenharmony_ci IO_PATH_ERROR, 568c2ecf20Sopenharmony_ci IO_REJECTED, 578c2ecf20Sopenharmony_ci IO_KILLED 588c2ecf20Sopenharmony_ci}; 598c2ecf20Sopenharmony_ci 608c2ecf20Sopenharmony_ci/** 618c2ecf20Sopenharmony_ci * ccw_request - Internal CCW request. 628c2ecf20Sopenharmony_ci * @cp: channel program to start 638c2ecf20Sopenharmony_ci * @timeout: maximum allowable time in jiffies between start I/O and interrupt 648c2ecf20Sopenharmony_ci * @maxretries: number of retries per I/O operation and path 658c2ecf20Sopenharmony_ci * @lpm: mask of paths to use 668c2ecf20Sopenharmony_ci * @check: optional callback that determines if results are final 678c2ecf20Sopenharmony_ci * @filter: optional callback to adjust request status based on IRB data 688c2ecf20Sopenharmony_ci * @callback: final callback 698c2ecf20Sopenharmony_ci * @data: user-defined pointer passed to all callbacks 708c2ecf20Sopenharmony_ci * @singlepath: if set, use only one path from @lpm per start I/O 718c2ecf20Sopenharmony_ci * @cancel: non-zero if request was cancelled 728c2ecf20Sopenharmony_ci * @done: non-zero if request was finished 738c2ecf20Sopenharmony_ci * @mask: current path mask 748c2ecf20Sopenharmony_ci * @retries: current number of retries 758c2ecf20Sopenharmony_ci * @drc: delayed return code 768c2ecf20Sopenharmony_ci */ 778c2ecf20Sopenharmony_cistruct ccw_request { 788c2ecf20Sopenharmony_ci struct ccw1 *cp; 798c2ecf20Sopenharmony_ci unsigned long timeout; 808c2ecf20Sopenharmony_ci u16 maxretries; 818c2ecf20Sopenharmony_ci u8 lpm; 828c2ecf20Sopenharmony_ci int (*check)(struct ccw_device *, void *); 838c2ecf20Sopenharmony_ci enum io_status (*filter)(struct ccw_device *, void *, struct irb *, 848c2ecf20Sopenharmony_ci enum io_status); 858c2ecf20Sopenharmony_ci void (*callback)(struct ccw_device *, void *, int); 868c2ecf20Sopenharmony_ci void *data; 878c2ecf20Sopenharmony_ci unsigned int singlepath:1; 888c2ecf20Sopenharmony_ci /* These fields are used internally. */ 898c2ecf20Sopenharmony_ci unsigned int cancel:1; 908c2ecf20Sopenharmony_ci unsigned int done:1; 918c2ecf20Sopenharmony_ci u16 mask; 928c2ecf20Sopenharmony_ci u16 retries; 938c2ecf20Sopenharmony_ci int drc; 948c2ecf20Sopenharmony_ci} __attribute__((packed)); 958c2ecf20Sopenharmony_ci 968c2ecf20Sopenharmony_ci/* 978c2ecf20Sopenharmony_ci * sense-id response buffer layout 988c2ecf20Sopenharmony_ci */ 998c2ecf20Sopenharmony_cistruct senseid { 1008c2ecf20Sopenharmony_ci /* common part */ 1018c2ecf20Sopenharmony_ci u8 reserved; /* always 0x'FF' */ 1028c2ecf20Sopenharmony_ci u16 cu_type; /* control unit type */ 1038c2ecf20Sopenharmony_ci u8 cu_model; /* control unit model */ 1048c2ecf20Sopenharmony_ci u16 dev_type; /* device type */ 1058c2ecf20Sopenharmony_ci u8 dev_model; /* device model */ 1068c2ecf20Sopenharmony_ci u8 unused; /* padding byte */ 1078c2ecf20Sopenharmony_ci /* extended part */ 1088c2ecf20Sopenharmony_ci struct ciw ciw[MAX_CIWS]; /* variable # of CIWs */ 1098c2ecf20Sopenharmony_ci} __attribute__ ((packed, aligned(4))); 1108c2ecf20Sopenharmony_ci 1118c2ecf20Sopenharmony_cienum cdev_todo { 1128c2ecf20Sopenharmony_ci CDEV_TODO_NOTHING, 1138c2ecf20Sopenharmony_ci CDEV_TODO_ENABLE_CMF, 1148c2ecf20Sopenharmony_ci CDEV_TODO_REBIND, 1158c2ecf20Sopenharmony_ci CDEV_TODO_REGISTER, 1168c2ecf20Sopenharmony_ci CDEV_TODO_UNREG, 1178c2ecf20Sopenharmony_ci CDEV_TODO_UNREG_EVAL, 1188c2ecf20Sopenharmony_ci}; 1198c2ecf20Sopenharmony_ci 1208c2ecf20Sopenharmony_ci#define FAKE_CMD_IRB 1 1218c2ecf20Sopenharmony_ci#define FAKE_TM_IRB 2 1228c2ecf20Sopenharmony_ci 1238c2ecf20Sopenharmony_cistruct ccw_device_dma_area { 1248c2ecf20Sopenharmony_ci struct senseid senseid; /* SenseID info */ 1258c2ecf20Sopenharmony_ci struct ccw1 iccws[2]; /* ccws for SNID/SID/SPGID commands */ 1268c2ecf20Sopenharmony_ci struct irb irb; /* device status */ 1278c2ecf20Sopenharmony_ci struct pgid pgid[8]; /* path group IDs per chpid*/ 1288c2ecf20Sopenharmony_ci}; 1298c2ecf20Sopenharmony_ci 1308c2ecf20Sopenharmony_cistruct ccw_device_private { 1318c2ecf20Sopenharmony_ci struct ccw_device *cdev; 1328c2ecf20Sopenharmony_ci struct subchannel *sch; 1338c2ecf20Sopenharmony_ci int state; /* device state */ 1348c2ecf20Sopenharmony_ci atomic_t onoff; 1358c2ecf20Sopenharmony_ci struct ccw_dev_id dev_id; /* device id */ 1368c2ecf20Sopenharmony_ci struct ccw_request req; /* internal I/O request */ 1378c2ecf20Sopenharmony_ci int iretry; 1388c2ecf20Sopenharmony_ci u8 pgid_valid_mask; /* mask of valid PGIDs */ 1398c2ecf20Sopenharmony_ci u8 pgid_todo_mask; /* mask of PGIDs to be adjusted */ 1408c2ecf20Sopenharmony_ci u8 pgid_reset_mask; /* mask of PGIDs which were reset */ 1418c2ecf20Sopenharmony_ci u8 path_noirq_mask; /* mask of paths for which no irq was 1428c2ecf20Sopenharmony_ci received */ 1438c2ecf20Sopenharmony_ci u8 path_notoper_mask; /* mask of paths which were found 1448c2ecf20Sopenharmony_ci not operable */ 1458c2ecf20Sopenharmony_ci u8 path_gone_mask; /* mask of paths, that became unavailable */ 1468c2ecf20Sopenharmony_ci u8 path_new_mask; /* mask of paths, that became available */ 1478c2ecf20Sopenharmony_ci u8 path_broken_mask; /* mask of paths, which were found to be 1488c2ecf20Sopenharmony_ci unusable */ 1498c2ecf20Sopenharmony_ci struct { 1508c2ecf20Sopenharmony_ci unsigned int fast:1; /* post with "channel end" */ 1518c2ecf20Sopenharmony_ci unsigned int repall:1; /* report every interrupt status */ 1528c2ecf20Sopenharmony_ci unsigned int pgroup:1; /* do path grouping */ 1538c2ecf20Sopenharmony_ci unsigned int force:1; /* allow forced online */ 1548c2ecf20Sopenharmony_ci unsigned int mpath:1; /* do multipathing */ 1558c2ecf20Sopenharmony_ci } __attribute__ ((packed)) options; 1568c2ecf20Sopenharmony_ci struct { 1578c2ecf20Sopenharmony_ci unsigned int esid:1; /* Ext. SenseID supported by HW */ 1588c2ecf20Sopenharmony_ci unsigned int dosense:1; /* delayed SENSE required */ 1598c2ecf20Sopenharmony_ci unsigned int doverify:1; /* delayed path verification */ 1608c2ecf20Sopenharmony_ci unsigned int donotify:1; /* call notify function */ 1618c2ecf20Sopenharmony_ci unsigned int recog_done:1; /* dev. recog. complete */ 1628c2ecf20Sopenharmony_ci unsigned int fake_irb:2; /* deliver faked irb */ 1638c2ecf20Sopenharmony_ci unsigned int resuming:1; /* recognition while resume */ 1648c2ecf20Sopenharmony_ci unsigned int pgroup:1; /* pathgroup is set up */ 1658c2ecf20Sopenharmony_ci unsigned int mpath:1; /* multipathing is set up */ 1668c2ecf20Sopenharmony_ci unsigned int pgid_unknown:1;/* unknown pgid state */ 1678c2ecf20Sopenharmony_ci unsigned int initialized:1; /* set if initial reference held */ 1688c2ecf20Sopenharmony_ci } __attribute__((packed)) flags; 1698c2ecf20Sopenharmony_ci unsigned long intparm; /* user interruption parameter */ 1708c2ecf20Sopenharmony_ci struct qdio_irq *qdio_data; 1718c2ecf20Sopenharmony_ci int async_kill_io_rc; 1728c2ecf20Sopenharmony_ci struct work_struct todo_work; 1738c2ecf20Sopenharmony_ci enum cdev_todo todo; 1748c2ecf20Sopenharmony_ci wait_queue_head_t wait_q; 1758c2ecf20Sopenharmony_ci struct timer_list timer; 1768c2ecf20Sopenharmony_ci void *cmb; /* measurement information */ 1778c2ecf20Sopenharmony_ci struct list_head cmb_list; /* list of measured devices */ 1788c2ecf20Sopenharmony_ci u64 cmb_start_time; /* clock value of cmb reset */ 1798c2ecf20Sopenharmony_ci void *cmb_wait; /* deferred cmb enable/disable */ 1808c2ecf20Sopenharmony_ci struct gen_pool *dma_pool; 1818c2ecf20Sopenharmony_ci struct ccw_device_dma_area *dma_area; 1828c2ecf20Sopenharmony_ci enum interruption_class int_class; 1838c2ecf20Sopenharmony_ci}; 1848c2ecf20Sopenharmony_ci 1858c2ecf20Sopenharmony_ci#endif 186