1 #ifndef S390_IO_SCH_H 2 #define S390_IO_SCH_H 3 4 #include "schid.h" 5 6 /* 7 * operation request block 8 */ 9 struct orb { 10 u32 intparm; /* interruption parameter */ 11 u32 key : 4; /* flags, like key, suspend control, etc. */ 12 u32 spnd : 1; /* suspend control */ 13 u32 res1 : 1; /* reserved */ 14 u32 mod : 1; /* modification control */ 15 u32 sync : 1; /* synchronize control */ 16 u32 fmt : 1; /* format control */ 17 u32 pfch : 1; /* prefetch control */ 18 u32 isic : 1; /* initial-status-interruption control */ 19 u32 alcc : 1; /* address-limit-checking control */ 20 u32 ssic : 1; /* suppress-suspended-interr. control */ 21 u32 res2 : 1; /* reserved */ 22 u32 c64 : 1; /* IDAW/QDIO 64 bit control */ 23 u32 i2k : 1; /* IDAW 2/4kB block size control */ 24 u32 lpm : 8; /* logical path mask */ 25 u32 ils : 1; /* incorrect length */ 26 u32 zero : 6; /* reserved zeros */ 27 u32 orbx : 1; /* ORB extension control */ 28 u32 cpa; /* channel program address */ 29 } __attribute__ ((packed, aligned(4))); 30 31 struct io_subchannel_private { 32 struct orb orb; /* operation request block */ 33 struct ccw1 sense_ccw; /* static ccw for sense command */ 34 } __attribute__ ((aligned(8))); 35 36 #define to_io_private(n) ((struct io_subchannel_private *)n->private) 37 #define sch_get_cdev(n) (dev_get_drvdata(&n->dev)) 38 #define sch_set_cdev(n, c) (dev_set_drvdata(&n->dev, c)) 39 40 #define MAX_CIWS 8 41 42 /* 43 * sense-id response buffer layout 44 */ 45 struct senseid { 46 /* common part */ 47 u8 reserved; /* always 0x'FF' */ 48 u16 cu_type; /* control unit type */ 49 u8 cu_model; /* control unit model */ 50 u16 dev_type; /* device type */ 51 u8 dev_model; /* device model */ 52 u8 unused; /* padding byte */ 53 /* extended part */ 54 struct ciw ciw[MAX_CIWS]; /* variable # of CIWs */ 55 } __attribute__ ((packed, aligned(4))); 56 57 struct ccw_device_private { 58 struct ccw_device *cdev; 59 struct subchannel *sch; 60 int state; /* device state */ 61 atomic_t onoff; 62 unsigned long registered; 63 struct ccw_dev_id dev_id; /* device id */ 64 struct subchannel_id schid; /* subchannel number */ 65 u8 imask; /* lpm mask for SNID/SID/SPGID */ 66 int iretry; /* retry counter SNID/SID/SPGID */ 67 struct { 68 unsigned int fast:1; /* post with "channel end" */ 69 unsigned int repall:1; /* report every interrupt status */ 70 unsigned int pgroup:1; /* do path grouping */ 71 unsigned int force:1; /* allow forced online */ 72 } __attribute__ ((packed)) options; 73 struct { 74 unsigned int pgid_single:1; /* use single path for Set PGID */ 75 unsigned int esid:1; /* Ext. SenseID supported by HW */ 76 unsigned int dosense:1; /* delayed SENSE required */ 77 unsigned int doverify:1; /* delayed path verification */ 78 unsigned int donotify:1; /* call notify function */ 79 unsigned int recog_done:1; /* dev. recog. complete */ 80 unsigned int fake_irb:1; /* deliver faked irb */ 81 unsigned int intretry:1; /* retry internal operation */ 82 } __attribute__((packed)) flags; 83 unsigned long intparm; /* user interruption parameter */ 84 struct qdio_irq *qdio_data; 85 struct irb irb; /* device status */ 86 struct senseid senseid; /* SenseID info */ 87 struct pgid pgid[8]; /* path group IDs per chpid*/ 88 struct ccw1 iccws[2]; /* ccws for SNID/SID/SPGID commands */ 89 struct work_struct kick_work; 90 wait_queue_head_t wait_q; 91 struct timer_list timer; 92 void *cmb; /* measurement information */ 93 struct list_head cmb_list; /* list of measured devices */ 94 u64 cmb_start_time; /* clock value of cmb reset */ 95 void *cmb_wait; /* deferred cmb enable/disable */ 96 }; 97 98 static inline int ssch(struct subchannel_id schid, volatile struct orb *addr) 99 { 100 register struct subchannel_id reg1 asm("1") = schid; 101 int ccode; 102 103 asm volatile( 104 " ssch 0(%2)\n" 105 " ipm %0\n" 106 " srl %0,28" 107 : "=d" (ccode) : "d" (reg1), "a" (addr), "m" (*addr) : "cc"); 108 return ccode; 109 } 110 111 static inline int rsch(struct subchannel_id schid) 112 { 113 register struct subchannel_id reg1 asm("1") = schid; 114 int ccode; 115 116 asm volatile( 117 " rsch\n" 118 " ipm %0\n" 119 " srl %0,28" 120 : "=d" (ccode) : "d" (reg1) : "cc"); 121 return ccode; 122 } 123 124 static inline int csch(struct subchannel_id schid) 125 { 126 register struct subchannel_id reg1 asm("1") = schid; 127 int ccode; 128 129 asm volatile( 130 " csch\n" 131 " ipm %0\n" 132 " srl %0,28" 133 : "=d" (ccode) : "d" (reg1) : "cc"); 134 return ccode; 135 } 136 137 static inline int hsch(struct subchannel_id schid) 138 { 139 register struct subchannel_id reg1 asm("1") = schid; 140 int ccode; 141 142 asm volatile( 143 " hsch\n" 144 " ipm %0\n" 145 " srl %0,28" 146 : "=d" (ccode) : "d" (reg1) : "cc"); 147 return ccode; 148 } 149 150 static inline int xsch(struct subchannel_id schid) 151 { 152 register struct subchannel_id reg1 asm("1") = schid; 153 int ccode; 154 155 asm volatile( 156 " .insn rre,0xb2760000,%1,0\n" 157 " ipm %0\n" 158 " srl %0,28" 159 : "=d" (ccode) : "d" (reg1) : "cc"); 160 return ccode; 161 } 162 163 #endif 164