Back to home page

OSCL-LXR

 
 

    


0001 /* SPDX-License-Identifier: GPL-2.0 */
0002 #ifndef S390_IO_SCH_H
0003 #define S390_IO_SCH_H
0004 
0005 #include <linux/types.h>
0006 #include <asm/schid.h>
0007 #include <asm/ccwdev.h>
0008 #include <asm/irq.h>
0009 #include "css.h"
0010 #include "orb.h"
0011 
0012 struct io_subchannel_dma_area {
0013     struct ccw1 sense_ccw;  /* static ccw for sense command */
0014 };
0015 
0016 struct io_subchannel_private {
0017     union orb orb;      /* operation request block */
0018     struct ccw_device *cdev;/* pointer to the child ccw device */
0019     struct {
0020         unsigned int suspend:1; /* allow suspend */
0021         unsigned int prefetch:1;/* deny prefetch */
0022         unsigned int inter:1;   /* suppress intermediate interrupts */
0023     } __packed options;
0024     struct io_subchannel_dma_area *dma_area;
0025     dma_addr_t dma_area_dma;
0026 } __aligned(8);
0027 
0028 #define to_io_private(n) ((struct io_subchannel_private *) \
0029               dev_get_drvdata(&(n)->dev))
0030 #define set_io_private(n, p) (dev_set_drvdata(&(n)->dev, p))
0031 
0032 static inline struct ccw_device *sch_get_cdev(struct subchannel *sch)
0033 {
0034     struct io_subchannel_private *priv = to_io_private(sch);
0035     return priv ? priv->cdev : NULL;
0036 }
0037 
0038 static inline void sch_set_cdev(struct subchannel *sch,
0039                 struct ccw_device *cdev)
0040 {
0041     struct io_subchannel_private *priv = to_io_private(sch);
0042     if (priv)
0043         priv->cdev = cdev;
0044 }
0045 
0046 #define MAX_CIWS 8
0047 
0048 /*
0049  * Possible status values for a CCW request's I/O.
0050  */
0051 enum io_status {
0052     IO_DONE,
0053     IO_RUNNING,
0054     IO_STATUS_ERROR,
0055     IO_PATH_ERROR,
0056     IO_REJECTED,
0057     IO_KILLED
0058 };
0059 
0060 /**
0061  * ccw_request - Internal CCW request.
0062  * @cp: channel program to start
0063  * @timeout: maximum allowable time in jiffies between start I/O and interrupt
0064  * @maxretries: number of retries per I/O operation and path
0065  * @lpm: mask of paths to use
0066  * @check: optional callback that determines if results are final
0067  * @filter: optional callback to adjust request status based on IRB data
0068  * @callback: final callback
0069  * @data: user-defined pointer passed to all callbacks
0070  * @singlepath: if set, use only one path from @lpm per start I/O
0071  * @cancel: non-zero if request was cancelled
0072  * @done: non-zero if request was finished
0073  * @mask: current path mask
0074  * @retries: current number of retries
0075  * @drc: delayed return code
0076  */
0077 struct ccw_request {
0078     struct ccw1 *cp;
0079     unsigned long timeout;
0080     u16 maxretries;
0081     u8 lpm;
0082     int (*check)(struct ccw_device *, void *);
0083     enum io_status (*filter)(struct ccw_device *, void *, struct irb *,
0084                  enum io_status);
0085     void (*callback)(struct ccw_device *, void *, int);
0086     void *data;
0087     unsigned int singlepath:1;
0088     /* These fields are used internally. */
0089     unsigned int cancel:1;
0090     unsigned int done:1;
0091     u16 mask;
0092     u16 retries;
0093     int drc;
0094 } __attribute__((packed));
0095 
0096 /*
0097  * sense-id response buffer layout
0098  */
0099 struct senseid {
0100     /* common part */
0101     u8  reserved;   /* always 0x'FF' */
0102     u16 cu_type;    /* control unit type */
0103     u8  cu_model;   /* control unit model */
0104     u16 dev_type;   /* device type */
0105     u8  dev_model;  /* device model */
0106     u8  unused; /* padding byte */
0107     /* extended part */
0108     struct ciw ciw[MAX_CIWS];   /* variable # of CIWs */
0109 }  __attribute__ ((packed, aligned(4)));
0110 
0111 enum cdev_todo {
0112     CDEV_TODO_NOTHING,
0113     CDEV_TODO_ENABLE_CMF,
0114     CDEV_TODO_REBIND,
0115     CDEV_TODO_REGISTER,
0116     CDEV_TODO_UNREG,
0117     CDEV_TODO_UNREG_EVAL,
0118 };
0119 
0120 #define FAKE_CMD_IRB    1
0121 #define FAKE_TM_IRB 2
0122 
0123 struct ccw_device_dma_area {
0124     struct senseid senseid; /* SenseID info */
0125     struct ccw1 iccws[2];   /* ccws for SNID/SID/SPGID commands */
0126     struct irb irb;     /* device status */
0127     struct pgid pgid[8];    /* path group IDs per chpid*/
0128 };
0129 
0130 struct ccw_device_private {
0131     struct ccw_device *cdev;
0132     struct subchannel *sch;
0133     int state;      /* device state */
0134     atomic_t onoff;
0135     struct ccw_dev_id dev_id;   /* device id */
0136     struct ccw_request req;     /* internal I/O request */
0137     int iretry;
0138     u8 pgid_valid_mask; /* mask of valid PGIDs */
0139     u8 pgid_todo_mask;  /* mask of PGIDs to be adjusted */
0140     u8 pgid_reset_mask; /* mask of PGIDs which were reset */
0141     u8 path_noirq_mask; /* mask of paths for which no irq was
0142                    received */
0143     u8 path_notoper_mask;   /* mask of paths which were found
0144                    not operable */
0145     u8 path_gone_mask;  /* mask of paths, that became unavailable */
0146     u8 path_new_mask;   /* mask of paths, that became available */
0147     u8 path_broken_mask;    /* mask of paths, which were found to be
0148                    unusable */
0149     struct {
0150         unsigned int fast:1;    /* post with "channel end" */
0151         unsigned int repall:1;  /* report every interrupt status */
0152         unsigned int pgroup:1;  /* do path grouping */
0153         unsigned int force:1;   /* allow forced online */
0154         unsigned int mpath:1;   /* do multipathing */
0155     } __attribute__ ((packed)) options;
0156     struct {
0157         unsigned int esid:1;        /* Ext. SenseID supported by HW */
0158         unsigned int dosense:1;     /* delayed SENSE required */
0159         unsigned int doverify:1;    /* delayed path verification */
0160         unsigned int donotify:1;    /* call notify function */
0161         unsigned int recog_done:1;  /* dev. recog. complete */
0162         unsigned int fake_irb:2;    /* deliver faked irb */
0163         unsigned int pgroup:1;      /* pathgroup is set up */
0164         unsigned int mpath:1;       /* multipathing is set up */
0165         unsigned int pgid_unknown:1;/* unknown pgid state */
0166         unsigned int initialized:1; /* set if initial reference held */
0167     } __attribute__((packed)) flags;
0168     unsigned long intparm;  /* user interruption parameter */
0169     struct qdio_irq *qdio_data;
0170     int async_kill_io_rc;
0171     struct work_struct todo_work;
0172     enum cdev_todo todo;
0173     wait_queue_head_t wait_q;
0174     struct timer_list timer;
0175     void *cmb;          /* measurement information */
0176     struct list_head cmb_list;  /* list of measured devices */
0177     u64 cmb_start_time;     /* clock value of cmb reset */
0178     void *cmb_wait;         /* deferred cmb enable/disable */
0179     struct gen_pool *dma_pool;
0180     struct ccw_device_dma_area *dma_area;
0181     enum interruption_class int_class;
0182 };
0183 
0184 #endif