1 #ifndef S390_IO_SCH_H 2 #define S390_IO_SCH_H 3 4 #include <asm/schid.h> 5 6 /* 7 * command-mode operation request block 8 */ 9 struct cmd_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 /* 32 * transport-mode operation request block 33 */ 34 struct tm_orb { 35 u32 intparm; 36 u32 key:4; 37 u32 :9; 38 u32 b:1; 39 u32 :2; 40 u32 lpm:8; 41 u32 :7; 42 u32 x:1; 43 u32 tcw; 44 u32 prio:8; 45 u32 :8; 46 u32 rsvpgm:8; 47 u32 :8; 48 u32 :32; 49 u32 :32; 50 u32 :32; 51 u32 :32; 52 } __attribute__ ((packed, aligned(4))); 53 54 union orb { 55 struct cmd_orb cmd; 56 struct tm_orb tm; 57 } __attribute__ ((packed, aligned(4))); 58 59 struct io_subchannel_private { 60 union orb orb; /* operation request block */ 61 struct ccw1 sense_ccw; /* static ccw for sense command */ 62 } __attribute__ ((aligned(8))); 63 64 #define to_io_private(n) ((struct io_subchannel_private *)n->private) 65 #define sch_get_cdev(n) (dev_get_drvdata(&n->dev)) 66 #define sch_set_cdev(n, c) (dev_set_drvdata(&n->dev, c)) 67 68 #define MAX_CIWS 8 69 70 /* 71 * sense-id response buffer layout 72 */ 73 struct senseid { 74 /* common part */ 75 u8 reserved; /* always 0x'FF' */ 76 u16 cu_type; /* control unit type */ 77 u8 cu_model; /* control unit model */ 78 u16 dev_type; /* device type */ 79 u8 dev_model; /* device model */ 80 u8 unused; /* padding byte */ 81 /* extended part */ 82 struct ciw ciw[MAX_CIWS]; /* variable # of CIWs */ 83 } __attribute__ ((packed, aligned(4))); 84 85 struct ccw_device_private { 86 struct ccw_device *cdev; 87 struct subchannel *sch; 88 int state; /* device state */ 89 atomic_t onoff; 90 unsigned long registered; 91 struct ccw_dev_id dev_id; /* device id */ 92 struct subchannel_id schid; /* subchannel number */ 93 u8 imask; /* lpm mask for SNID/SID/SPGID */ 94 int iretry; /* retry counter SNID/SID/SPGID */ 95 struct { 96 unsigned int fast:1; /* post with "channel end" */ 97 unsigned int repall:1; /* report every interrupt status */ 98 unsigned int pgroup:1; /* do path grouping */ 99 unsigned int force:1; /* allow forced online */ 100 } __attribute__ ((packed)) options; 101 struct { 102 unsigned int pgid_single:1; /* use single path for Set PGID */ 103 unsigned int esid:1; /* Ext. SenseID supported by HW */ 104 unsigned int dosense:1; /* delayed SENSE required */ 105 unsigned int doverify:1; /* delayed path verification */ 106 unsigned int donotify:1; /* call notify function */ 107 unsigned int recog_done:1; /* dev. recog. complete */ 108 unsigned int fake_irb:1; /* deliver faked irb */ 109 unsigned int intretry:1; /* retry internal operation */ 110 } __attribute__((packed)) flags; 111 unsigned long intparm; /* user interruption parameter */ 112 struct qdio_irq *qdio_data; 113 struct irb irb; /* device status */ 114 struct senseid senseid; /* SenseID info */ 115 struct pgid pgid[8]; /* path group IDs per chpid*/ 116 struct ccw1 iccws[2]; /* ccws for SNID/SID/SPGID commands */ 117 struct work_struct kick_work; 118 wait_queue_head_t wait_q; 119 struct timer_list timer; 120 void *cmb; /* measurement information */ 121 struct list_head cmb_list; /* list of measured devices */ 122 u64 cmb_start_time; /* clock value of cmb reset */ 123 void *cmb_wait; /* deferred cmb enable/disable */ 124 }; 125 126 static inline int ssch(struct subchannel_id schid, union orb *addr) 127 { 128 register struct subchannel_id reg1 asm("1") = schid; 129 int ccode = -EIO; 130 131 asm volatile( 132 " ssch 0(%2)\n" 133 "0: ipm %0\n" 134 " srl %0,28\n" 135 "1:\n" 136 EX_TABLE(0b, 1b) 137 : "+d" (ccode) 138 : "d" (reg1), "a" (addr), "m" (*addr) 139 : "cc", "memory"); 140 return ccode; 141 } 142 143 static inline int rsch(struct subchannel_id schid) 144 { 145 register struct subchannel_id reg1 asm("1") = schid; 146 int ccode; 147 148 asm volatile( 149 " rsch\n" 150 " ipm %0\n" 151 " srl %0,28" 152 : "=d" (ccode) 153 : "d" (reg1) 154 : "cc", "memory"); 155 return ccode; 156 } 157 158 static inline int csch(struct subchannel_id schid) 159 { 160 register struct subchannel_id reg1 asm("1") = schid; 161 int ccode; 162 163 asm volatile( 164 " csch\n" 165 " ipm %0\n" 166 " srl %0,28" 167 : "=d" (ccode) 168 : "d" (reg1) 169 : "cc"); 170 return ccode; 171 } 172 173 static inline int hsch(struct subchannel_id schid) 174 { 175 register struct subchannel_id reg1 asm("1") = schid; 176 int ccode; 177 178 asm volatile( 179 " hsch\n" 180 " ipm %0\n" 181 " srl %0,28" 182 : "=d" (ccode) 183 : "d" (reg1) 184 : "cc"); 185 return ccode; 186 } 187 188 static inline int xsch(struct subchannel_id schid) 189 { 190 register struct subchannel_id reg1 asm("1") = schid; 191 int ccode; 192 193 asm volatile( 194 " .insn rre,0xb2760000,%1,0\n" 195 " ipm %0\n" 196 " srl %0,28" 197 : "=d" (ccode) 198 : "d" (reg1) 199 : "cc"); 200 return ccode; 201 } 202 203 #endif 204