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, volatile 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) : "d" (reg1), "a" (addr), "m" (*addr) : "cc"); 138 return ccode; 139 } 140 141 static inline int rsch(struct subchannel_id schid) 142 { 143 register struct subchannel_id reg1 asm("1") = schid; 144 int ccode; 145 146 asm volatile( 147 " rsch\n" 148 " ipm %0\n" 149 " srl %0,28" 150 : "=d" (ccode) : "d" (reg1) : "cc"); 151 return ccode; 152 } 153 154 static inline int csch(struct subchannel_id schid) 155 { 156 register struct subchannel_id reg1 asm("1") = schid; 157 int ccode; 158 159 asm volatile( 160 " csch\n" 161 " ipm %0\n" 162 " srl %0,28" 163 : "=d" (ccode) : "d" (reg1) : "cc"); 164 return ccode; 165 } 166 167 static inline int hsch(struct subchannel_id schid) 168 { 169 register struct subchannel_id reg1 asm("1") = schid; 170 int ccode; 171 172 asm volatile( 173 " hsch\n" 174 " ipm %0\n" 175 " srl %0,28" 176 : "=d" (ccode) : "d" (reg1) : "cc"); 177 return ccode; 178 } 179 180 static inline int xsch(struct subchannel_id schid) 181 { 182 register struct subchannel_id reg1 asm("1") = schid; 183 int ccode; 184 185 asm volatile( 186 " .insn rre,0xb2760000,%1,0\n" 187 " ipm %0\n" 188 " srl %0,28" 189 : "=d" (ccode) : "d" (reg1) : "cc"); 190 return ccode; 191 } 192 193 #endif 194