aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/s390/cio/blacklist.c23
-rw-r--r--drivers/s390/cio/chsc.c63
-rw-r--r--drivers/s390/cio/cio.c84
-rw-r--r--drivers/s390/cio/cio.h11
-rw-r--r--drivers/s390/cio/cmf.c8
-rw-r--r--drivers/s390/cio/css.c69
-rw-r--r--drivers/s390/cio/css.h13
-rw-r--r--drivers/s390/cio/device.c17
-rw-r--r--drivers/s390/cio/device.h1
-rw-r--r--drivers/s390/cio/device_fsm.c18
-rw-r--r--drivers/s390/cio/device_id.c6
-rw-r--r--drivers/s390/cio/device_ops.c4
-rw-r--r--drivers/s390/cio/device_pgid.c13
-rw-r--r--drivers/s390/cio/device_status.c8
-rw-r--r--drivers/s390/cio/ioasm.h55
-rw-r--r--drivers/s390/cio/qdio.c107
-rw-r--r--drivers/s390/cio/qdio.h26
-rw-r--r--drivers/s390/cio/schid.h25
18 files changed, 313 insertions, 238 deletions
diff --git a/drivers/s390/cio/blacklist.c b/drivers/s390/cio/blacklist.c
index a1c52a682191..a4b03031ff50 100644
--- a/drivers/s390/cio/blacklist.c
+++ b/drivers/s390/cio/blacklist.c
@@ -35,7 +35,7 @@
35 */ 35 */
36 36
37/* 65536 bits to indicate if a devno is blacklisted or not */ 37/* 65536 bits to indicate if a devno is blacklisted or not */
38#define __BL_DEV_WORDS ((__MAX_SUBCHANNELS + (8*sizeof(long) - 1)) / \ 38#define __BL_DEV_WORDS ((__MAX_SUBCHANNEL + (8*sizeof(long) - 1)) / \
39 (8*sizeof(long))) 39 (8*sizeof(long)))
40static unsigned long bl_dev[__BL_DEV_WORDS]; 40static unsigned long bl_dev[__BL_DEV_WORDS];
41typedef enum {add, free} range_action; 41typedef enum {add, free} range_action;
@@ -50,7 +50,7 @@ blacklist_range (range_action action, unsigned int from, unsigned int to)
50 if (!to) 50 if (!to)
51 to = from; 51 to = from;
52 52
53 if (from > to || to > __MAX_SUBCHANNELS) { 53 if (from > to || to > __MAX_SUBCHANNEL) {
54 printk (KERN_WARNING "Invalid blacklist range " 54 printk (KERN_WARNING "Invalid blacklist range "
55 "0x%04x to 0x%04x, skipping\n", from, to); 55 "0x%04x to 0x%04x, skipping\n", from, to);
56 return; 56 return;
@@ -143,7 +143,7 @@ blacklist_parse_parameters (char *str, range_action action)
143 if (strncmp(str,"all,",4) == 0 || strcmp(str,"all") == 0 || 143 if (strncmp(str,"all,",4) == 0 || strcmp(str,"all") == 0 ||
144 strncmp(str,"all\n",4) == 0 || strncmp(str,"all ",4) == 0) { 144 strncmp(str,"all\n",4) == 0 || strncmp(str,"all ",4) == 0) {
145 from = 0; 145 from = 0;
146 to = __MAX_SUBCHANNELS; 146 to = __MAX_SUBCHANNEL;
147 str += 3; 147 str += 3;
148 } else { 148 } else {
149 int rc; 149 int rc;
@@ -226,20 +226,21 @@ is_blacklisted (int devno)
226static inline void 226static inline void
227s390_redo_validation (void) 227s390_redo_validation (void)
228{ 228{
229 unsigned int irq; 229 struct subchannel_id schid;
230 230
231 CIO_TRACE_EVENT (0, "redoval"); 231 CIO_TRACE_EVENT (0, "redoval");
232 for (irq = 0; irq < __MAX_SUBCHANNELS; irq++) { 232 init_subchannel_id(&schid);
233 do {
233 int ret; 234 int ret;
234 struct subchannel *sch; 235 struct subchannel *sch;
235 236
236 sch = get_subchannel_by_schid(irq); 237 sch = get_subchannel_by_schid(schid);
237 if (sch) { 238 if (sch) {
238 /* Already known. */ 239 /* Already known. */
239 put_device(&sch->dev); 240 put_device(&sch->dev);
240 continue; 241 continue;
241 } 242 }
242 ret = css_probe_device(irq); 243 ret = css_probe_device(schid);
243 if (ret == -ENXIO) 244 if (ret == -ENXIO)
244 break; /* We're through. */ 245 break; /* We're through. */
245 if (ret == -ENOMEM) 246 if (ret == -ENOMEM)
@@ -248,7 +249,7 @@ s390_redo_validation (void)
248 * panic. 249 * panic.
249 */ 250 */
250 break; 251 break;
251 } 252 } while (schid.sch_no++ < __MAX_SUBCHANNEL);
252} 253}
253 254
254/* 255/*
@@ -289,12 +290,12 @@ static int cio_ignore_read (char *page, char **start, off_t off,
289 len = 0; 290 len = 0;
290 for (devno = off; /* abuse the page variable 291 for (devno = off; /* abuse the page variable
291 * as counter, see fs/proc/generic.c */ 292 * as counter, see fs/proc/generic.c */
292 devno < __MAX_SUBCHANNELS && len + entry_size < count; devno++) { 293 devno < __MAX_SUBCHANNEL && len + entry_size < count; devno++) {
293 if (!test_bit(devno, bl_dev)) 294 if (!test_bit(devno, bl_dev))
294 continue; 295 continue;
295 len += sprintf(page + len, "0.0.%04lx", devno); 296 len += sprintf(page + len, "0.0.%04lx", devno);
296 if (test_bit(devno + 1, bl_dev)) { /* print range */ 297 if (test_bit(devno + 1, bl_dev)) { /* print range */
297 while (++devno < __MAX_SUBCHANNELS) 298 while (++devno < __MAX_SUBCHANNEL)
298 if (!test_bit(devno, bl_dev)) 299 if (!test_bit(devno, bl_dev))
299 break; 300 break;
300 len += sprintf(page + len, "-0.0.%04lx", --devno); 301 len += sprintf(page + len, "-0.0.%04lx", --devno);
@@ -302,7 +303,7 @@ static int cio_ignore_read (char *page, char **start, off_t off,
302 len += sprintf(page + len, "\n"); 303 len += sprintf(page + len, "\n");
303 } 304 }
304 305
305 if (devno < __MAX_SUBCHANNELS) 306 if (devno < __MAX_SUBCHANNEL)
306 *eof = 1; 307 *eof = 1;
307 *start = (char *) (devno - off); /* number of checked entries */ 308 *start = (char *) (devno - off); /* number of checked entries */
308 return len; 309 return len;
diff --git a/drivers/s390/cio/chsc.c b/drivers/s390/cio/chsc.c
index fa3c23b80e3a..aff5d149b729 100644
--- a/drivers/s390/cio/chsc.c
+++ b/drivers/s390/cio/chsc.c
@@ -104,8 +104,8 @@ chsc_get_sch_desc_irq(struct subchannel *sch, void *page)
104 .code = 0x0004, 104 .code = 0x0004,
105 }; 105 };
106 106
107 ssd_area->f_sch = sch->irq; 107 ssd_area->f_sch = sch->schid.sch_no;
108 ssd_area->l_sch = sch->irq; 108 ssd_area->l_sch = sch->schid.sch_no;
109 109
110 ccode = chsc(ssd_area); 110 ccode = chsc(ssd_area);
111 if (ccode > 0) { 111 if (ccode > 0) {
@@ -147,7 +147,8 @@ chsc_get_sch_desc_irq(struct subchannel *sch, void *page)
147 */ 147 */
148 if (ssd_area->st > 3) { /* uhm, that looks strange... */ 148 if (ssd_area->st > 3) { /* uhm, that looks strange... */
149 CIO_CRW_EVENT(0, "Strange subchannel type %d" 149 CIO_CRW_EVENT(0, "Strange subchannel type %d"
150 " for sch %04x\n", ssd_area->st, sch->irq); 150 " for sch %04x\n", ssd_area->st,
151 sch->schid.sch_no);
151 /* 152 /*
152 * There may have been a new subchannel type defined in the 153 * There may have been a new subchannel type defined in the
153 * time since this code was written; since we don't know which 154 * time since this code was written; since we don't know which
@@ -157,7 +158,7 @@ chsc_get_sch_desc_irq(struct subchannel *sch, void *page)
157 } else { 158 } else {
158 const char *type[4] = {"I/O", "chsc", "message", "ADM"}; 159 const char *type[4] = {"I/O", "chsc", "message", "ADM"};
159 CIO_CRW_EVENT(6, "ssd: sch %04x is %s subchannel\n", 160 CIO_CRW_EVENT(6, "ssd: sch %04x is %s subchannel\n",
160 sch->irq, type[ssd_area->st]); 161 sch->schid.sch_no, type[ssd_area->st]);
161 162
162 sch->ssd_info.valid = 1; 163 sch->ssd_info.valid = 1;
163 sch->ssd_info.type = ssd_area->st; 164 sch->ssd_info.type = ssd_area->st;
@@ -232,7 +233,7 @@ s390_subchannel_remove_chpid(struct device *dev, void *data)
232 mask = 0x80 >> j; 233 mask = 0x80 >> j;
233 spin_lock(&sch->lock); 234 spin_lock(&sch->lock);
234 235
235 stsch(sch->irq, &schib); 236 stsch(sch->schid, &schib);
236 if (!schib.pmcw.dnv) 237 if (!schib.pmcw.dnv)
237 goto out_unreg; 238 goto out_unreg;
238 memcpy(&sch->schib, &schib, sizeof(struct schib)); 239 memcpy(&sch->schib, &schib, sizeof(struct schib));
@@ -284,7 +285,7 @@ out_unlock:
284out_unreg: 285out_unreg:
285 spin_unlock(&sch->lock); 286 spin_unlock(&sch->lock);
286 sch->lpm = 0; 287 sch->lpm = 0;
287 if (css_enqueue_subchannel_slow(sch->irq)) { 288 if (css_enqueue_subchannel_slow(sch->schid)) {
288 css_clear_subchannel_slow_list(); 289 css_clear_subchannel_slow_list();
289 need_rescan = 1; 290 need_rescan = 1;
290 } 291 }
@@ -337,7 +338,7 @@ s390_process_res_acc_sch(u8 chpid, __u16 fla, u32 fla_mask,
337 * new path information and eventually check for logically 338 * new path information and eventually check for logically
338 * offline chpids. 339 * offline chpids.
339 */ 340 */
340 ccode = stsch(sch->irq, &sch->schib); 341 ccode = stsch(sch->schid, &sch->schib);
341 if (ccode > 0) 342 if (ccode > 0)
342 return 0; 343 return 0;
343 344
@@ -348,7 +349,8 @@ static int
348s390_process_res_acc (u8 chpid, __u16 fla, u32 fla_mask) 349s390_process_res_acc (u8 chpid, __u16 fla, u32 fla_mask)
349{ 350{
350 struct subchannel *sch; 351 struct subchannel *sch;
351 int irq, rc; 352 int rc;
353 struct subchannel_id schid;
352 char dbf_txt[15]; 354 char dbf_txt[15];
353 355
354 sprintf(dbf_txt, "accpr%x", chpid); 356 sprintf(dbf_txt, "accpr%x", chpid);
@@ -370,10 +372,11 @@ s390_process_res_acc (u8 chpid, __u16 fla, u32 fla_mask)
370 return 0; /* no need to do the rest */ 372 return 0; /* no need to do the rest */
371 373
372 rc = 0; 374 rc = 0;
373 for (irq = 0; irq < __MAX_SUBCHANNELS; irq++) { 375 init_subchannel_id(&schid);
376 do {
374 int chp_mask, old_lpm; 377 int chp_mask, old_lpm;
375 378
376 sch = get_subchannel_by_schid(irq); 379 sch = get_subchannel_by_schid(schid);
377 if (!sch) { 380 if (!sch) {
378 struct schib schib; 381 struct schib schib;
379 int ret; 382 int ret;
@@ -385,7 +388,7 @@ s390_process_res_acc (u8 chpid, __u16 fla, u32 fla_mask)
385 * that beast may be on we'll have to do a stsch 388 * that beast may be on we'll have to do a stsch
386 * on all devices, grr... 389 * on all devices, grr...
387 */ 390 */
388 if (stsch(irq, &schib)) { 391 if (stsch(schid, &schib)) {
389 /* We're through */ 392 /* We're through */
390 if (need_rescan) 393 if (need_rescan)
391 rc = -EAGAIN; 394 rc = -EAGAIN;
@@ -396,7 +399,7 @@ s390_process_res_acc (u8 chpid, __u16 fla, u32 fla_mask)
396 continue; 399 continue;
397 } 400 }
398 /* Put it on the slow path. */ 401 /* Put it on the slow path. */
399 ret = css_enqueue_subchannel_slow(irq); 402 ret = css_enqueue_subchannel_slow(schid);
400 if (ret) { 403 if (ret) {
401 css_clear_subchannel_slow_list(); 404 css_clear_subchannel_slow_list();
402 need_rescan = 1; 405 need_rescan = 1;
@@ -428,7 +431,7 @@ s390_process_res_acc (u8 chpid, __u16 fla, u32 fla_mask)
428 put_device(&sch->dev); 431 put_device(&sch->dev);
429 if (fla_mask == 0xffff) 432 if (fla_mask == 0xffff)
430 break; 433 break;
431 } 434 } while (schid.sch_no++ < __MAX_SUBCHANNEL);
432 return rc; 435 return rc;
433} 436}
434 437
@@ -608,7 +611,8 @@ static int
608chp_add(int chpid) 611chp_add(int chpid)
609{ 612{
610 struct subchannel *sch; 613 struct subchannel *sch;
611 int irq, ret, rc; 614 int ret, rc;
615 struct subchannel_id schid;
612 char dbf_txt[15]; 616 char dbf_txt[15];
613 617
614 if (!get_chp_status(chpid)) 618 if (!get_chp_status(chpid))
@@ -618,14 +622,15 @@ chp_add(int chpid)
618 CIO_TRACE_EVENT(2, dbf_txt); 622 CIO_TRACE_EVENT(2, dbf_txt);
619 623
620 rc = 0; 624 rc = 0;
621 for (irq = 0; irq < __MAX_SUBCHANNELS; irq++) { 625 init_subchannel_id(&schid);
626 do {
622 int i; 627 int i;
623 628
624 sch = get_subchannel_by_schid(irq); 629 sch = get_subchannel_by_schid(schid);
625 if (!sch) { 630 if (!sch) {
626 struct schib schib; 631 struct schib schib;
627 632
628 if (stsch(irq, &schib)) { 633 if (stsch(schid, &schib)) {
629 /* We're through */ 634 /* We're through */
630 if (need_rescan) 635 if (need_rescan)
631 rc = -EAGAIN; 636 rc = -EAGAIN;
@@ -636,7 +641,7 @@ chp_add(int chpid)
636 continue; 641 continue;
637 } 642 }
638 /* Put it on the slow path. */ 643 /* Put it on the slow path. */
639 ret = css_enqueue_subchannel_slow(irq); 644 ret = css_enqueue_subchannel_slow(schid);
640 if (ret) { 645 if (ret) {
641 css_clear_subchannel_slow_list(); 646 css_clear_subchannel_slow_list();
642 need_rescan = 1; 647 need_rescan = 1;
@@ -648,7 +653,7 @@ chp_add(int chpid)
648 spin_lock(&sch->lock); 653 spin_lock(&sch->lock);
649 for (i=0; i<8; i++) 654 for (i=0; i<8; i++)
650 if (sch->schib.pmcw.chpid[i] == chpid) { 655 if (sch->schib.pmcw.chpid[i] == chpid) {
651 if (stsch(sch->irq, &sch->schib) != 0) { 656 if (stsch(sch->schid, &sch->schib) != 0) {
652 /* Endgame. */ 657 /* Endgame. */
653 spin_unlock(&sch->lock); 658 spin_unlock(&sch->lock);
654 return rc; 659 return rc;
@@ -669,7 +674,7 @@ chp_add(int chpid)
669 674
670 spin_unlock(&sch->lock); 675 spin_unlock(&sch->lock);
671 put_device(&sch->dev); 676 put_device(&sch->dev);
672 } 677 } while (schid.sch_no++ < __MAX_SUBCHANNEL);
673 return rc; 678 return rc;
674} 679}
675 680
@@ -702,7 +707,7 @@ __check_for_io_and_kill(struct subchannel *sch, int index)
702 if (!device_is_online(sch)) 707 if (!device_is_online(sch))
703 /* cio could be doing I/O. */ 708 /* cio could be doing I/O. */
704 return 0; 709 return 0;
705 cc = stsch(sch->irq, &sch->schib); 710 cc = stsch(sch->schid, &sch->schib);
706 if (cc) 711 if (cc)
707 return 0; 712 return 0;
708 if (sch->schib.scsw.actl && sch->schib.pmcw.lpum == (0x80 >> index)) { 713 if (sch->schib.scsw.actl && sch->schib.pmcw.lpum == (0x80 >> index)) {
@@ -743,7 +748,7 @@ __s390_subchannel_vary_chpid(struct subchannel *sch, __u8 chpid, int on)
743 * just varied off path. Then kill it. 748 * just varied off path. Then kill it.
744 */ 749 */
745 if (!__check_for_io_and_kill(sch, chp) && !sch->lpm) { 750 if (!__check_for_io_and_kill(sch, chp) && !sch->lpm) {
746 if (css_enqueue_subchannel_slow(sch->irq)) { 751 if (css_enqueue_subchannel_slow(sch->schid)) {
747 css_clear_subchannel_slow_list(); 752 css_clear_subchannel_slow_list();
748 need_rescan = 1; 753 need_rescan = 1;
749 } 754 }
@@ -789,7 +794,8 @@ static int
789s390_vary_chpid( __u8 chpid, int on) 794s390_vary_chpid( __u8 chpid, int on)
790{ 795{
791 char dbf_text[15]; 796 char dbf_text[15];
792 int status, irq, ret; 797 int status, ret;
798 struct subchannel_id schid;
793 struct subchannel *sch; 799 struct subchannel *sch;
794 800
795 sprintf(dbf_text, on?"varyon%x":"varyoff%x", chpid); 801 sprintf(dbf_text, on?"varyon%x":"varyoff%x", chpid);
@@ -818,26 +824,27 @@ s390_vary_chpid( __u8 chpid, int on)
818 if (!on) 824 if (!on)
819 goto out; 825 goto out;
820 /* Scan for new devices on varied on path. */ 826 /* Scan for new devices on varied on path. */
821 for (irq = 0; irq < __MAX_SUBCHANNELS; irq++) { 827 init_subchannel_id(&schid);
828 do {
822 struct schib schib; 829 struct schib schib;
823 830
824 if (need_rescan) 831 if (need_rescan)
825 break; 832 break;
826 sch = get_subchannel_by_schid(irq); 833 sch = get_subchannel_by_schid(schid);
827 if (sch) { 834 if (sch) {
828 put_device(&sch->dev); 835 put_device(&sch->dev);
829 continue; 836 continue;
830 } 837 }
831 if (stsch(irq, &schib)) 838 if (stsch(schid, &schib))
832 /* We're through */ 839 /* We're through */
833 break; 840 break;
834 /* Put it on the slow path. */ 841 /* Put it on the slow path. */
835 ret = css_enqueue_subchannel_slow(irq); 842 ret = css_enqueue_subchannel_slow(schid);
836 if (ret) { 843 if (ret) {
837 css_clear_subchannel_slow_list(); 844 css_clear_subchannel_slow_list();
838 need_rescan = 1; 845 need_rescan = 1;
839 } 846 }
840 } 847 } while (schid.sch_no++ < __MAX_SUBCHANNEL);
841out: 848out:
842 if (need_rescan || css_slow_subchannels_exist()) 849 if (need_rescan || css_slow_subchannels_exist())
843 queue_work(slow_path_wq, &slow_path_work); 850 queue_work(slow_path_wq, &slow_path_work);
diff --git a/drivers/s390/cio/cio.c b/drivers/s390/cio/cio.c
index 185bc73c3ecd..396bada65f86 100644
--- a/drivers/s390/cio/cio.c
+++ b/drivers/s390/cio/cio.c
@@ -135,7 +135,7 @@ cio_tpi(void)
135 return 0; 135 return 0;
136 irb = (struct irb *) __LC_IRB; 136 irb = (struct irb *) __LC_IRB;
137 /* Store interrupt response block to lowcore. */ 137 /* Store interrupt response block to lowcore. */
138 if (tsch (tpi_info->irq, irb) != 0) 138 if (tsch (tpi_info->schid, irb) != 0)
139 /* Not status pending or not operational. */ 139 /* Not status pending or not operational. */
140 return 1; 140 return 1;
141 sch = (struct subchannel *)(unsigned long)tpi_info->intparm; 141 sch = (struct subchannel *)(unsigned long)tpi_info->intparm;
@@ -163,10 +163,10 @@ cio_start_handle_notoper(struct subchannel *sch, __u8 lpm)
163 else 163 else
164 sch->lpm = 0; 164 sch->lpm = 0;
165 165
166 stsch (sch->irq, &sch->schib); 166 stsch (sch->schid, &sch->schib);
167 167
168 CIO_MSG_EVENT(0, "cio_start: 'not oper' status for " 168 CIO_MSG_EVENT(0, "cio_start: 'not oper' status for "
169 "subchannel %04x!\n", sch->irq); 169 "subchannel %04x!\n", sch->schid.sch_no);
170 sprintf(dbf_text, "no%s", sch->dev.bus_id); 170 sprintf(dbf_text, "no%s", sch->dev.bus_id);
171 CIO_TRACE_EVENT(0, dbf_text); 171 CIO_TRACE_EVENT(0, dbf_text);
172 CIO_HEX_EVENT(0, &sch->schib, sizeof (struct schib)); 172 CIO_HEX_EVENT(0, &sch->schib, sizeof (struct schib));
@@ -204,7 +204,7 @@ cio_start_key (struct subchannel *sch, /* subchannel structure */
204 sch->orb.key = key >> 4; 204 sch->orb.key = key >> 4;
205 /* issue "Start Subchannel" */ 205 /* issue "Start Subchannel" */
206 sch->orb.cpa = (__u32) __pa (cpa); 206 sch->orb.cpa = (__u32) __pa (cpa);
207 ccode = ssch (sch->irq, &sch->orb); 207 ccode = ssch (sch->schid, &sch->orb);
208 208
209 /* process condition code */ 209 /* process condition code */
210 sprintf (dbf_txt, "ccode:%d", ccode); 210 sprintf (dbf_txt, "ccode:%d", ccode);
@@ -243,7 +243,7 @@ cio_resume (struct subchannel *sch)
243 CIO_TRACE_EVENT (4, "resIO"); 243 CIO_TRACE_EVENT (4, "resIO");
244 CIO_TRACE_EVENT (4, sch->dev.bus_id); 244 CIO_TRACE_EVENT (4, sch->dev.bus_id);
245 245
246 ccode = rsch (sch->irq); 246 ccode = rsch (sch->schid);
247 247
248 sprintf (dbf_txt, "ccode:%d", ccode); 248 sprintf (dbf_txt, "ccode:%d", ccode);
249 CIO_TRACE_EVENT (4, dbf_txt); 249 CIO_TRACE_EVENT (4, dbf_txt);
@@ -283,7 +283,7 @@ cio_halt(struct subchannel *sch)
283 /* 283 /*
284 * Issue "Halt subchannel" and process condition code 284 * Issue "Halt subchannel" and process condition code
285 */ 285 */
286 ccode = hsch (sch->irq); 286 ccode = hsch (sch->schid);
287 287
288 sprintf (dbf_txt, "ccode:%d", ccode); 288 sprintf (dbf_txt, "ccode:%d", ccode);
289 CIO_TRACE_EVENT (2, dbf_txt); 289 CIO_TRACE_EVENT (2, dbf_txt);
@@ -318,7 +318,7 @@ cio_clear(struct subchannel *sch)
318 /* 318 /*
319 * Issue "Clear subchannel" and process condition code 319 * Issue "Clear subchannel" and process condition code
320 */ 320 */
321 ccode = csch (sch->irq); 321 ccode = csch (sch->schid);
322 322
323 sprintf (dbf_txt, "ccode:%d", ccode); 323 sprintf (dbf_txt, "ccode:%d", ccode);
324 CIO_TRACE_EVENT (2, dbf_txt); 324 CIO_TRACE_EVENT (2, dbf_txt);
@@ -351,7 +351,7 @@ cio_cancel (struct subchannel *sch)
351 CIO_TRACE_EVENT (2, "cancelIO"); 351 CIO_TRACE_EVENT (2, "cancelIO");
352 CIO_TRACE_EVENT (2, sch->dev.bus_id); 352 CIO_TRACE_EVENT (2, sch->dev.bus_id);
353 353
354 ccode = xsch (sch->irq); 354 ccode = xsch (sch->schid);
355 355
356 sprintf (dbf_txt, "ccode:%d", ccode); 356 sprintf (dbf_txt, "ccode:%d", ccode);
357 CIO_TRACE_EVENT (2, dbf_txt); 357 CIO_TRACE_EVENT (2, dbf_txt);
@@ -359,7 +359,7 @@ cio_cancel (struct subchannel *sch)
359 switch (ccode) { 359 switch (ccode) {
360 case 0: /* success */ 360 case 0: /* success */
361 /* Update information in scsw. */ 361 /* Update information in scsw. */
362 stsch (sch->irq, &sch->schib); 362 stsch (sch->schid, &sch->schib);
363 return 0; 363 return 0;
364 case 1: /* status pending */ 364 case 1: /* status pending */
365 return -EBUSY; 365 return -EBUSY;
@@ -381,7 +381,7 @@ cio_modify (struct subchannel *sch)
381 381
382 ret = 0; 382 ret = 0;
383 for (retry = 0; retry < 5; retry++) { 383 for (retry = 0; retry < 5; retry++) {
384 ccode = msch_err (sch->irq, &sch->schib); 384 ccode = msch_err (sch->schid, &sch->schib);
385 if (ccode < 0) /* -EIO if msch gets a program check. */ 385 if (ccode < 0) /* -EIO if msch gets a program check. */
386 return ccode; 386 return ccode;
387 switch (ccode) { 387 switch (ccode) {
@@ -414,7 +414,7 @@ cio_enable_subchannel (struct subchannel *sch, unsigned int isc)
414 CIO_TRACE_EVENT (2, "ensch"); 414 CIO_TRACE_EVENT (2, "ensch");
415 CIO_TRACE_EVENT (2, sch->dev.bus_id); 415 CIO_TRACE_EVENT (2, sch->dev.bus_id);
416 416
417 ccode = stsch (sch->irq, &sch->schib); 417 ccode = stsch (sch->schid, &sch->schib);
418 if (ccode) 418 if (ccode)
419 return -ENODEV; 419 return -ENODEV;
420 420
@@ -432,13 +432,13 @@ cio_enable_subchannel (struct subchannel *sch, unsigned int isc)
432 */ 432 */
433 sch->schib.pmcw.csense = 0; 433 sch->schib.pmcw.csense = 0;
434 if (ret == 0) { 434 if (ret == 0) {
435 stsch (sch->irq, &sch->schib); 435 stsch (sch->schid, &sch->schib);
436 if (sch->schib.pmcw.ena) 436 if (sch->schib.pmcw.ena)
437 break; 437 break;
438 } 438 }
439 if (ret == -EBUSY) { 439 if (ret == -EBUSY) {
440 struct irb irb; 440 struct irb irb;
441 if (tsch(sch->irq, &irb) != 0) 441 if (tsch(sch->schid, &irb) != 0)
442 break; 442 break;
443 } 443 }
444 } 444 }
@@ -461,7 +461,7 @@ cio_disable_subchannel (struct subchannel *sch)
461 CIO_TRACE_EVENT (2, "dissch"); 461 CIO_TRACE_EVENT (2, "dissch");
462 CIO_TRACE_EVENT (2, sch->dev.bus_id); 462 CIO_TRACE_EVENT (2, sch->dev.bus_id);
463 463
464 ccode = stsch (sch->irq, &sch->schib); 464 ccode = stsch (sch->schid, &sch->schib);
465 if (ccode == 3) /* Not operational. */ 465 if (ccode == 3) /* Not operational. */
466 return -ENODEV; 466 return -ENODEV;
467 467
@@ -485,7 +485,7 @@ cio_disable_subchannel (struct subchannel *sch)
485 */ 485 */
486 break; 486 break;
487 if (ret == 0) { 487 if (ret == 0) {
488 stsch (sch->irq, &sch->schib); 488 stsch (sch->schid, &sch->schib);
489 if (!sch->schib.pmcw.ena) 489 if (!sch->schib.pmcw.ena)
490 break; 490 break;
491 } 491 }
@@ -508,12 +508,12 @@ cio_disable_subchannel (struct subchannel *sch)
508 * -ENODEV for subchannels with invalid device number or blacklisted devices 508 * -ENODEV for subchannels with invalid device number or blacklisted devices
509 */ 509 */
510int 510int
511cio_validate_subchannel (struct subchannel *sch, unsigned int irq) 511cio_validate_subchannel (struct subchannel *sch, struct subchannel_id schid)
512{ 512{
513 char dbf_txt[15]; 513 char dbf_txt[15];
514 int ccode; 514 int ccode;
515 515
516 sprintf (dbf_txt, "valsch%x", irq); 516 sprintf (dbf_txt, "valsch%x", schid.sch_no);
517 CIO_TRACE_EVENT (4, dbf_txt); 517 CIO_TRACE_EVENT (4, dbf_txt);
518 518
519 /* Nuke all fields. */ 519 /* Nuke all fields. */
@@ -522,17 +522,17 @@ cio_validate_subchannel (struct subchannel *sch, unsigned int irq)
522 spin_lock_init(&sch->lock); 522 spin_lock_init(&sch->lock);
523 523
524 /* Set a name for the subchannel */ 524 /* Set a name for the subchannel */
525 snprintf (sch->dev.bus_id, BUS_ID_SIZE, "0.0.%04x", irq); 525 snprintf (sch->dev.bus_id, BUS_ID_SIZE, "0.0.%04x", schid.sch_no);
526 526
527 /* 527 /*
528 * The first subchannel that is not-operational (ccode==3) 528 * The first subchannel that is not-operational (ccode==3)
529 * indicates that there aren't any more devices available. 529 * indicates that there aren't any more devices available.
530 */ 530 */
531 sch->irq = irq; 531 ccode = stsch (schid, &sch->schib);
532 ccode = stsch (irq, &sch->schib);
533 if (ccode) 532 if (ccode)
534 return -ENXIO; 533 return -ENXIO;
535 534
535 sch->schid = schid;
536 /* Copy subchannel type from path management control word. */ 536 /* Copy subchannel type from path management control word. */
537 sch->st = sch->schib.pmcw.st; 537 sch->st = sch->schib.pmcw.st;
538 538
@@ -543,7 +543,7 @@ cio_validate_subchannel (struct subchannel *sch, unsigned int irq)
543 CIO_DEBUG(KERN_INFO, 0, 543 CIO_DEBUG(KERN_INFO, 0,
544 "Subchannel %04X reports " 544 "Subchannel %04X reports "
545 "non-I/O subchannel type %04X\n", 545 "non-I/O subchannel type %04X\n",
546 sch->irq, sch->st); 546 sch->schid.sch_no, sch->st);
547 /* We stop here for non-io subchannels. */ 547 /* We stop here for non-io subchannels. */
548 return sch->st; 548 return sch->st;
549 } 549 }
@@ -573,7 +573,7 @@ cio_validate_subchannel (struct subchannel *sch, unsigned int irq)
573 CIO_DEBUG(KERN_INFO, 0, 573 CIO_DEBUG(KERN_INFO, 0,
574 "Detected device %04X on subchannel %04X" 574 "Detected device %04X on subchannel %04X"
575 " - PIM = %02X, PAM = %02X, POM = %02X\n", 575 " - PIM = %02X, PAM = %02X, POM = %02X\n",
576 sch->schib.pmcw.dev, sch->irq, sch->schib.pmcw.pim, 576 sch->schib.pmcw.dev, sch->schid.sch_no, sch->schib.pmcw.pim,
577 sch->schib.pmcw.pam, sch->schib.pmcw.pom); 577 sch->schib.pmcw.pam, sch->schib.pmcw.pom);
578 578
579 /* 579 /*
@@ -632,7 +632,7 @@ do_IRQ (struct pt_regs *regs)
632 if (sch) 632 if (sch)
633 spin_lock(&sch->lock); 633 spin_lock(&sch->lock);
634 /* Store interrupt response block to lowcore. */ 634 /* Store interrupt response block to lowcore. */
635 if (tsch (tpi_info->irq, irb) == 0 && sch) { 635 if (tsch (tpi_info->schid, irb) == 0 && sch) {
636 /* Keep subchannel information word up to date. */ 636 /* Keep subchannel information word up to date. */
637 memcpy (&sch->schib.scsw, &irb->scsw, 637 memcpy (&sch->schib.scsw, &irb->scsw,
638 sizeof (irb->scsw)); 638 sizeof (irb->scsw));
@@ -693,26 +693,28 @@ wait_cons_dev (void)
693static int 693static int
694cio_console_irq(void) 694cio_console_irq(void)
695{ 695{
696 int irq; 696 struct subchannel_id schid;
697 697
698 init_subchannel_id(&schid);
698 if (console_irq != -1) { 699 if (console_irq != -1) {
699 /* VM provided us with the irq number of the console. */ 700 /* VM provided us with the irq number of the console. */
700 if (stsch(console_irq, &console_subchannel.schib) != 0 || 701 schid.sch_no = console_irq;
702 if (stsch(schid, &console_subchannel.schib) != 0 ||
701 !console_subchannel.schib.pmcw.dnv) 703 !console_subchannel.schib.pmcw.dnv)
702 return -1; 704 return -1;
703 console_devno = console_subchannel.schib.pmcw.dev; 705 console_devno = console_subchannel.schib.pmcw.dev;
704 } else if (console_devno != -1) { 706 } else if (console_devno != -1) {
705 /* At least the console device number is known. */ 707 /* At least the console device number is known. */
706 for (irq = 0; irq < __MAX_SUBCHANNELS; irq++) { 708 do {
707 if (stsch(irq, &console_subchannel.schib) != 0) 709 if (stsch(schid, &console_subchannel.schib) != 0)
708 break; 710 break;
709 if (console_subchannel.schib.pmcw.dnv && 711 if (console_subchannel.schib.pmcw.dnv &&
710 console_subchannel.schib.pmcw.dev == 712 console_subchannel.schib.pmcw.dev ==
711 console_devno) { 713 console_devno) {
712 console_irq = irq; 714 console_irq = schid.sch_no;
713 break; 715 break;
714 } 716 }
715 } 717 } while (schid.sch_no++ < __MAX_SUBCHANNEL);
716 if (console_irq == -1) 718 if (console_irq == -1)
717 return -1; 719 return -1;
718 } else { 720 } else {
@@ -729,6 +731,7 @@ struct subchannel *
729cio_probe_console(void) 731cio_probe_console(void)
730{ 732{
731 int irq, ret; 733 int irq, ret;
734 struct subchannel_id schid;
732 735
733 if (xchg(&console_subchannel_in_use, 1) != 0) 736 if (xchg(&console_subchannel_in_use, 1) != 0)
734 return ERR_PTR(-EBUSY); 737 return ERR_PTR(-EBUSY);
@@ -738,7 +741,9 @@ cio_probe_console(void)
738 return ERR_PTR(-ENODEV); 741 return ERR_PTR(-ENODEV);
739 } 742 }
740 memset(&console_subchannel, 0, sizeof(struct subchannel)); 743 memset(&console_subchannel, 0, sizeof(struct subchannel));
741 ret = cio_validate_subchannel(&console_subchannel, irq); 744 init_subchannel_id(&schid);
745 schid.sch_no = irq;
746 ret = cio_validate_subchannel(&console_subchannel, schid);
742 if (ret) { 747 if (ret) {
743 console_subchannel_in_use = 0; 748 console_subchannel_in_use = 0;
744 return ERR_PTR(-ENODEV); 749 return ERR_PTR(-ENODEV);
@@ -770,11 +775,11 @@ cio_release_console(void)
770 775
771/* Bah... hack to catch console special sausages. */ 776/* Bah... hack to catch console special sausages. */
772int 777int
773cio_is_console(int irq) 778cio_is_console(struct subchannel_id schid)
774{ 779{
775 if (!console_subchannel_in_use) 780 if (!console_subchannel_in_use)
776 return 0; 781 return 0;
777 return (irq == console_subchannel.irq); 782 return schid_equal(&schid, &console_subchannel.schid);
778} 783}
779 784
780struct subchannel * 785struct subchannel *
@@ -787,7 +792,7 @@ cio_get_console_subchannel(void)
787 792
788#endif 793#endif
789static inline int 794static inline int
790__disable_subchannel_easy(unsigned int schid, struct schib *schib) 795__disable_subchannel_easy(struct subchannel_id schid, struct schib *schib)
791{ 796{
792 int retry, cc; 797 int retry, cc;
793 798
@@ -805,7 +810,7 @@ __disable_subchannel_easy(unsigned int schid, struct schib *schib)
805} 810}
806 811
807static inline int 812static inline int
808__clear_subchannel_easy(unsigned int schid) 813__clear_subchannel_easy(struct subchannel_id schid)
809{ 814{
810 int retry; 815 int retry;
811 816
@@ -815,8 +820,8 @@ __clear_subchannel_easy(unsigned int schid)
815 struct tpi_info ti; 820 struct tpi_info ti;
816 821
817 if (tpi(&ti)) { 822 if (tpi(&ti)) {
818 tsch(ti.irq, (struct irb *)__LC_IRB); 823 tsch(ti.schid, (struct irb *)__LC_IRB);
819 if (ti.irq == schid) 824 if (schid_equal(&ti.schid, &schid))
820 return 0; 825 return 0;
821 } 826 }
822 udelay(100); 827 udelay(100);
@@ -830,10 +835,11 @@ extern void do_reipl(unsigned long devno);
830void 835void
831clear_all_subchannels(void) 836clear_all_subchannels(void)
832{ 837{
833 unsigned int schid; 838 struct subchannel_id schid;
834 839
835 local_irq_disable(); 840 local_irq_disable();
836 for (schid=0;schid<=highest_subchannel;schid++) { 841 init_subchannel_id(&schid);
842 do {
837 struct schib schib; 843 struct schib schib;
838 if (stsch(schid, &schib)) 844 if (stsch(schid, &schib))
839 break; /* break out of the loop */ 845 break; /* break out of the loop */
@@ -849,7 +855,7 @@ clear_all_subchannels(void)
849 stsch(schid, &schib); 855 stsch(schid, &schib);
850 __disable_subchannel_easy(schid, &schib); 856 __disable_subchannel_easy(schid, &schib);
851 } 857 }
852 } 858 } while (schid.sch_no++ < __MAX_SUBCHANNEL);
853} 859}
854 860
855/* Make sure all subchannels are quiet before we re-ipl an lpar. */ 861/* Make sure all subchannels are quiet before we re-ipl an lpar. */
diff --git a/drivers/s390/cio/cio.h b/drivers/s390/cio/cio.h
index c50a9da420a9..0ca987344e07 100644
--- a/drivers/s390/cio/cio.h
+++ b/drivers/s390/cio/cio.h
@@ -1,6 +1,8 @@
1#ifndef S390_CIO_H 1#ifndef S390_CIO_H
2#define S390_CIO_H 2#define S390_CIO_H
3 3
4#include "schid.h"
5
4/* 6/*
5 * where we put the ssd info 7 * where we put the ssd info
6 */ 8 */
@@ -83,7 +85,7 @@ struct orb {
83 85
84/* subchannel data structure used by I/O subroutines */ 86/* subchannel data structure used by I/O subroutines */
85struct subchannel { 87struct subchannel {
86 unsigned int irq; /* aka. subchannel number */ 88 struct subchannel_id schid;
87 spinlock_t lock; /* subchannel lock */ 89 spinlock_t lock; /* subchannel lock */
88 90
89 enum { 91 enum {
@@ -114,7 +116,7 @@ struct subchannel {
114 116
115#define to_subchannel(n) container_of(n, struct subchannel, dev) 117#define to_subchannel(n) container_of(n, struct subchannel, dev)
116 118
117extern int cio_validate_subchannel (struct subchannel *, unsigned int); 119extern int cio_validate_subchannel (struct subchannel *, struct subchannel_id);
118extern int cio_enable_subchannel (struct subchannel *, unsigned int); 120extern int cio_enable_subchannel (struct subchannel *, unsigned int);
119extern int cio_disable_subchannel (struct subchannel *); 121extern int cio_disable_subchannel (struct subchannel *);
120extern int cio_cancel (struct subchannel *); 122extern int cio_cancel (struct subchannel *);
@@ -127,14 +129,15 @@ extern int cio_cancel (struct subchannel *);
127extern int cio_set_options (struct subchannel *, int); 129extern int cio_set_options (struct subchannel *, int);
128extern int cio_get_options (struct subchannel *); 130extern int cio_get_options (struct subchannel *);
129extern int cio_modify (struct subchannel *); 131extern int cio_modify (struct subchannel *);
132
130/* Use with care. */ 133/* Use with care. */
131#ifdef CONFIG_CCW_CONSOLE 134#ifdef CONFIG_CCW_CONSOLE
132extern struct subchannel *cio_probe_console(void); 135extern struct subchannel *cio_probe_console(void);
133extern void cio_release_console(void); 136extern void cio_release_console(void);
134extern int cio_is_console(int irq); 137extern int cio_is_console(struct subchannel_id);
135extern struct subchannel *cio_get_console_subchannel(void); 138extern struct subchannel *cio_get_console_subchannel(void);
136#else 139#else
137#define cio_is_console(irq) 0 140#define cio_is_console(schid) 0
138#define cio_get_console_subchannel() NULL 141#define cio_get_console_subchannel() NULL
139#endif 142#endif
140 143
diff --git a/drivers/s390/cio/cmf.c b/drivers/s390/cio/cmf.c
index b978f7fe8327..0b03714e696a 100644
--- a/drivers/s390/cio/cmf.c
+++ b/drivers/s390/cio/cmf.c
@@ -1,5 +1,5 @@
1/* 1/*
2 * linux/drivers/s390/cio/cmf.c ($Revision: 1.16 $) 2 * linux/drivers/s390/cio/cmf.c ($Revision: 1.19 $)
3 * 3 *
4 * Linux on zSeries Channel Measurement Facility support 4 * Linux on zSeries Channel Measurement Facility support
5 * 5 *
@@ -178,7 +178,7 @@ set_schib(struct ccw_device *cdev, u32 mme, int mbfc, unsigned long address)
178 /* msch can silently fail, so do it again if necessary */ 178 /* msch can silently fail, so do it again if necessary */
179 for (retry = 0; retry < 3; retry++) { 179 for (retry = 0; retry < 3; retry++) {
180 /* prepare schib */ 180 /* prepare schib */
181 stsch(sch->irq, schib); 181 stsch(sch->schid, schib);
182 schib->pmcw.mme = mme; 182 schib->pmcw.mme = mme;
183 schib->pmcw.mbfc = mbfc; 183 schib->pmcw.mbfc = mbfc;
184 /* address can be either a block address or a block index */ 184 /* address can be either a block address or a block index */
@@ -188,7 +188,7 @@ set_schib(struct ccw_device *cdev, u32 mme, int mbfc, unsigned long address)
188 schib->pmcw.mbi = address; 188 schib->pmcw.mbi = address;
189 189
190 /* try to submit it */ 190 /* try to submit it */
191 switch(ret = msch_err(sch->irq, schib)) { 191 switch(ret = msch_err(sch->schid, schib)) {
192 case 0: 192 case 0:
193 break; 193 break;
194 case 1: 194 case 1:
@@ -202,7 +202,7 @@ set_schib(struct ccw_device *cdev, u32 mme, int mbfc, unsigned long address)
202 ret = -EINVAL; 202 ret = -EINVAL;
203 break; 203 break;
204 } 204 }
205 stsch(sch->irq, schib); /* restore the schib */ 205 stsch(sch->schid, schib); /* restore the schib */
206 206
207 if (ret) 207 if (ret)
208 break; 208 break;
diff --git a/drivers/s390/cio/css.c b/drivers/s390/cio/css.c
index 7e4d57b4266f..5137dafd1e8d 100644
--- a/drivers/s390/cio/css.c
+++ b/drivers/s390/cio/css.c
@@ -33,7 +33,7 @@ struct device css_bus_device = {
33}; 33};
34 34
35static struct subchannel * 35static struct subchannel *
36css_alloc_subchannel(int irq) 36css_alloc_subchannel(struct subchannel_id schid)
37{ 37{
38 struct subchannel *sch; 38 struct subchannel *sch;
39 int ret; 39 int ret;
@@ -41,13 +41,11 @@ css_alloc_subchannel(int irq)
41 sch = kmalloc (sizeof (*sch), GFP_KERNEL | GFP_DMA); 41 sch = kmalloc (sizeof (*sch), GFP_KERNEL | GFP_DMA);
42 if (sch == NULL) 42 if (sch == NULL)
43 return ERR_PTR(-ENOMEM); 43 return ERR_PTR(-ENOMEM);
44 ret = cio_validate_subchannel (sch, irq); 44 ret = cio_validate_subchannel (sch, schid);
45 if (ret < 0) { 45 if (ret < 0) {
46 kfree(sch); 46 kfree(sch);
47 return ERR_PTR(ret); 47 return ERR_PTR(ret);
48 } 48 }
49 if (irq > highest_subchannel)
50 highest_subchannel = irq;
51 49
52 if (sch->st != SUBCHANNEL_TYPE_IO) { 50 if (sch->st != SUBCHANNEL_TYPE_IO) {
53 /* For now we ignore all non-io subchannels. */ 51 /* For now we ignore all non-io subchannels. */
@@ -87,7 +85,7 @@ css_subchannel_release(struct device *dev)
87 struct subchannel *sch; 85 struct subchannel *sch;
88 86
89 sch = to_subchannel(dev); 87 sch = to_subchannel(dev);
90 if (!cio_is_console(sch->irq)) 88 if (!cio_is_console(sch->schid))
91 kfree(sch); 89 kfree(sch);
92} 90}
93 91
@@ -114,12 +112,12 @@ css_register_subchannel(struct subchannel *sch)
114} 112}
115 113
116int 114int
117css_probe_device(int irq) 115css_probe_device(struct subchannel_id schid)
118{ 116{
119 int ret; 117 int ret;
120 struct subchannel *sch; 118 struct subchannel *sch;
121 119
122 sch = css_alloc_subchannel(irq); 120 sch = css_alloc_subchannel(schid);
123 if (IS_ERR(sch)) 121 if (IS_ERR(sch))
124 return PTR_ERR(sch); 122 return PTR_ERR(sch);
125 ret = css_register_subchannel(sch); 123 ret = css_register_subchannel(sch);
@@ -132,26 +130,26 @@ static int
132check_subchannel(struct device * dev, void * data) 130check_subchannel(struct device * dev, void * data)
133{ 131{
134 struct subchannel *sch; 132 struct subchannel *sch;
135 int irq = (unsigned long)data; 133 struct subchannel_id *schid = data;
136 134
137 sch = to_subchannel(dev); 135 sch = to_subchannel(dev);
138 return (sch->irq == irq); 136 return schid_equal(&sch->schid, schid);
139} 137}
140 138
141struct subchannel * 139struct subchannel *
142get_subchannel_by_schid(int irq) 140get_subchannel_by_schid(struct subchannel_id schid)
143{ 141{
144 struct device *dev; 142 struct device *dev;
145 143
146 dev = bus_find_device(&css_bus_type, NULL, 144 dev = bus_find_device(&css_bus_type, NULL,
147 (void *)(unsigned long)irq, check_subchannel); 145 (void *)&schid, check_subchannel);
148 146
149 return dev ? to_subchannel(dev) : NULL; 147 return dev ? to_subchannel(dev) : NULL;
150} 148}
151 149
152 150
153static inline int 151static inline int
154css_get_subchannel_status(struct subchannel *sch, int schid) 152css_get_subchannel_status(struct subchannel *sch, struct subchannel_id schid)
155{ 153{
156 struct schib schib; 154 struct schib schib;
157 int cc; 155 int cc;
@@ -170,13 +168,13 @@ css_get_subchannel_status(struct subchannel *sch, int schid)
170} 168}
171 169
172static int 170static int
173css_evaluate_subchannel(int irq, int slow) 171css_evaluate_subchannel(struct subchannel_id schid, int slow)
174{ 172{
175 int event, ret, disc; 173 int event, ret, disc;
176 struct subchannel *sch; 174 struct subchannel *sch;
177 unsigned long flags; 175 unsigned long flags;
178 176
179 sch = get_subchannel_by_schid(irq); 177 sch = get_subchannel_by_schid(schid);
180 disc = sch ? device_is_disconnected(sch) : 0; 178 disc = sch ? device_is_disconnected(sch) : 0;
181 if (disc && slow) { 179 if (disc && slow) {
182 if (sch) 180 if (sch)
@@ -194,9 +192,10 @@ css_evaluate_subchannel(int irq, int slow)
194 put_device(&sch->dev); 192 put_device(&sch->dev);
195 return -EAGAIN; /* Will be done on the slow path. */ 193 return -EAGAIN; /* Will be done on the slow path. */
196 } 194 }
197 event = css_get_subchannel_status(sch, irq); 195 event = css_get_subchannel_status(sch, schid);
198 CIO_MSG_EVENT(4, "Evaluating schid %04x, event %d, %s, %s path.\n", 196 CIO_MSG_EVENT(4, "Evaluating schid %04x, event %d, %s, %s path.\n",
199 irq, event, sch?(disc?"disconnected":"normal"):"unknown", 197 schid.sch_no, event,
198 sch?(disc?"disconnected":"normal"):"unknown",
200 slow?"slow":"fast"); 199 slow?"slow":"fast");
201 switch (event) { 200 switch (event) {
202 case CIO_NO_PATH: 201 case CIO_NO_PATH:
@@ -253,7 +252,7 @@ css_evaluate_subchannel(int irq, int slow)
253 sch->schib.pmcw.intparm = 0; 252 sch->schib.pmcw.intparm = 0;
254 cio_modify(sch); 253 cio_modify(sch);
255 put_device(&sch->dev); 254 put_device(&sch->dev);
256 ret = css_probe_device(irq); 255 ret = css_probe_device(schid);
257 } else { 256 } else {
258 /* 257 /*
259 * We can't immediately deregister the disconnected 258 * We can't immediately deregister the disconnected
@@ -272,7 +271,7 @@ css_evaluate_subchannel(int irq, int slow)
272 device_trigger_reprobe(sch); 271 device_trigger_reprobe(sch);
273 spin_unlock_irqrestore(&sch->lock, flags); 272 spin_unlock_irqrestore(&sch->lock, flags);
274 } 273 }
275 ret = sch ? 0 : css_probe_device(irq); 274 ret = sch ? 0 : css_probe_device(schid);
276 break; 275 break;
277 default: 276 default:
278 BUG(); 277 BUG();
@@ -284,10 +283,12 @@ css_evaluate_subchannel(int irq, int slow)
284static void 283static void
285css_rescan_devices(void) 284css_rescan_devices(void)
286{ 285{
287 int irq, ret; 286 int ret;
287 struct subchannel_id schid;
288 288
289 for (irq = 0; irq < __MAX_SUBCHANNELS; irq++) { 289 init_subchannel_id(&schid);
290 ret = css_evaluate_subchannel(irq, 1); 290 do {
291 ret = css_evaluate_subchannel(schid, 1);
291 /* No more memory. It doesn't make sense to continue. No 292 /* No more memory. It doesn't make sense to continue. No
292 * panic because this can happen in midflight and just 293 * panic because this can happen in midflight and just
293 * because we can't use a new device is no reason to crash 294 * because we can't use a new device is no reason to crash
@@ -297,12 +298,12 @@ css_rescan_devices(void)
297 /* -ENXIO indicates that there are no more subchannels. */ 298 /* -ENXIO indicates that there are no more subchannels. */
298 if (ret == -ENXIO) 299 if (ret == -ENXIO)
299 break; 300 break;
300 } 301 } while (schid.sch_no++ < __MAX_SUBCHANNEL);
301} 302}
302 303
303struct slow_subchannel { 304struct slow_subchannel {
304 struct list_head slow_list; 305 struct list_head slow_list;
305 unsigned long schid; 306 struct subchannel_id schid;
306}; 307};
307 308
308static LIST_HEAD(slow_subchannels_head); 309static LIST_HEAD(slow_subchannels_head);
@@ -357,20 +358,24 @@ int
357css_process_crw(int irq) 358css_process_crw(int irq)
358{ 359{
359 int ret; 360 int ret;
361 struct subchannel_id mchk_schid;
360 362
361 CIO_CRW_EVENT(2, "source is subchannel %04X\n", irq); 363 CIO_CRW_EVENT(2, "source is subchannel %04X\n", irq);
362 364
363 if (need_rescan) 365 if (need_rescan)
364 /* We need to iterate all subchannels anyway. */ 366 /* We need to iterate all subchannels anyway. */
365 return -EAGAIN; 367 return -EAGAIN;
368
369 init_subchannel_id(&mchk_schid);
370 mchk_schid.sch_no = irq;
366 /* 371 /*
367 * Since we are always presented with IPI in the CRW, we have to 372 * Since we are always presented with IPI in the CRW, we have to
368 * use stsch() to find out if the subchannel in question has come 373 * use stsch() to find out if the subchannel in question has come
369 * or gone. 374 * or gone.
370 */ 375 */
371 ret = css_evaluate_subchannel(irq, 0); 376 ret = css_evaluate_subchannel(mchk_schid, 0);
372 if (ret == -EAGAIN) { 377 if (ret == -EAGAIN) {
373 if (css_enqueue_subchannel_slow(irq)) { 378 if (css_enqueue_subchannel_slow(mchk_schid)) {
374 css_clear_subchannel_slow_list(); 379 css_clear_subchannel_slow_list();
375 need_rescan = 1; 380 need_rescan = 1;
376 } 381 }
@@ -404,7 +409,8 @@ css_generate_pgid(void)
404static int __init 409static int __init
405init_channel_subsystem (void) 410init_channel_subsystem (void)
406{ 411{
407 int ret, irq; 412 int ret;
413 struct subchannel_id schid;
408 414
409 if (chsc_determine_css_characteristics() == 0) 415 if (chsc_determine_css_characteristics() == 0)
410 css_characteristics_avail = 1; 416 css_characteristics_avail = 1;
@@ -420,13 +426,14 @@ init_channel_subsystem (void)
420 426
421 ctl_set_bit(6, 28); 427 ctl_set_bit(6, 28);
422 428
423 for (irq = 0; irq < __MAX_SUBCHANNELS; irq++) { 429 init_subchannel_id(&schid);
430 do {
424 struct subchannel *sch; 431 struct subchannel *sch;
425 432
426 if (cio_is_console(irq)) 433 if (cio_is_console(schid))
427 sch = cio_get_console_subchannel(); 434 sch = cio_get_console_subchannel();
428 else { 435 else {
429 sch = css_alloc_subchannel(irq); 436 sch = css_alloc_subchannel(schid);
430 if (IS_ERR(sch)) 437 if (IS_ERR(sch))
431 ret = PTR_ERR(sch); 438 ret = PTR_ERR(sch);
432 else 439 else
@@ -448,7 +455,7 @@ init_channel_subsystem (void)
448 * console subchannel. 455 * console subchannel.
449 */ 456 */
450 css_register_subchannel(sch); 457 css_register_subchannel(sch);
451 } 458 } while (schid.sch_no++ < __MAX_SUBCHANNEL);
452 return 0; 459 return 0;
453 460
454out_bus: 461out_bus:
@@ -482,7 +489,7 @@ struct bus_type css_bus_type = {
482subsys_initcall(init_channel_subsystem); 489subsys_initcall(init_channel_subsystem);
483 490
484int 491int
485css_enqueue_subchannel_slow(unsigned long schid) 492css_enqueue_subchannel_slow(struct subchannel_id schid)
486{ 493{
487 struct slow_subchannel *new_slow_sch; 494 struct slow_subchannel *new_slow_sch;
488 unsigned long flags; 495 unsigned long flags;
diff --git a/drivers/s390/cio/css.h b/drivers/s390/cio/css.h
index 2004a6c49388..f26e16daecb5 100644
--- a/drivers/s390/cio/css.h
+++ b/drivers/s390/cio/css.h
@@ -6,6 +6,8 @@
6 6
7#include <asm/cio.h> 7#include <asm/cio.h>
8 8
9#include "schid.h"
10
9/* 11/*
10 * path grouping stuff 12 * path grouping stuff
11 */ 13 */
@@ -68,7 +70,7 @@ struct ccw_device_private {
68 atomic_t onoff; 70 atomic_t onoff;
69 unsigned long registered; 71 unsigned long registered;
70 __u16 devno; /* device number */ 72 __u16 devno; /* device number */
71 __u16 irq; /* subchannel number */ 73 __u16 sch_no; /* subchannel number */
72 __u8 imask; /* lpm mask for SNID/SID/SPGID */ 74 __u8 imask; /* lpm mask for SNID/SID/SPGID */
73 int iretry; /* retry counter SNID/SID/SPGID */ 75 int iretry; /* retry counter SNID/SID/SPGID */
74 struct { 76 struct {
@@ -121,12 +123,11 @@ struct css_driver {
121extern struct bus_type css_bus_type; 123extern struct bus_type css_bus_type;
122extern struct css_driver io_subchannel_driver; 124extern struct css_driver io_subchannel_driver;
123 125
124int css_probe_device(int irq); 126extern int css_probe_device(struct subchannel_id);
125extern struct subchannel * get_subchannel_by_schid(int irq); 127extern struct subchannel * get_subchannel_by_schid(struct subchannel_id);
126extern unsigned int highest_subchannel;
127extern int css_init_done; 128extern int css_init_done;
128 129
129#define __MAX_SUBCHANNELS 65536 130#define __MAX_SUBCHANNEL 65535
130 131
131extern struct bus_type css_bus_type; 132extern struct bus_type css_bus_type;
132extern struct device css_bus_device; 133extern struct device css_bus_device;
@@ -144,7 +145,7 @@ void device_set_waiting(struct subchannel *);
144void device_kill_pending_timer(struct subchannel *); 145void device_kill_pending_timer(struct subchannel *);
145 146
146/* Helper functions to build lists for the slow path. */ 147/* Helper functions to build lists for the slow path. */
147int css_enqueue_subchannel_slow(unsigned long schid); 148extern int css_enqueue_subchannel_slow(struct subchannel_id schid);
148void css_walk_subchannel_slow_list(void (*fn)(unsigned long)); 149void css_walk_subchannel_slow_list(void (*fn)(unsigned long));
149void css_clear_subchannel_slow_list(void); 150void css_clear_subchannel_slow_list(void);
150int css_slow_subchannels_exist(void); 151int css_slow_subchannels_exist(void);
diff --git a/drivers/s390/cio/device.c b/drivers/s390/cio/device.c
index 0590cffe62aa..9ac07aeffbe6 100644
--- a/drivers/s390/cio/device.c
+++ b/drivers/s390/cio/device.c
@@ -622,7 +622,7 @@ ccw_device_do_unreg_rereg(void *data)
622 622
623 other_sch = to_subchannel(other_cdev->dev.parent); 623 other_sch = to_subchannel(other_cdev->dev.parent);
624 if (get_device(&other_sch->dev)) { 624 if (get_device(&other_sch->dev)) {
625 stsch(other_sch->irq, &other_sch->schib); 625 stsch(other_sch->schid, &other_sch->schib);
626 if (other_sch->schib.pmcw.dnv) { 626 if (other_sch->schib.pmcw.dnv) {
627 other_sch->schib.pmcw.intparm = 0; 627 other_sch->schib.pmcw.intparm = 0;
628 cio_modify(other_sch); 628 cio_modify(other_sch);
@@ -772,7 +772,7 @@ io_subchannel_recog(struct ccw_device *cdev, struct subchannel *sch)
772 /* Init private data. */ 772 /* Init private data. */
773 priv = cdev->private; 773 priv = cdev->private;
774 priv->devno = sch->schib.pmcw.dev; 774 priv->devno = sch->schib.pmcw.dev;
775 priv->irq = sch->irq; 775 priv->sch_no = sch->schid.sch_no;
776 priv->state = DEV_STATE_NOT_OPER; 776 priv->state = DEV_STATE_NOT_OPER;
777 INIT_LIST_HEAD(&priv->cmb_list); 777 INIT_LIST_HEAD(&priv->cmb_list);
778 init_waitqueue_head(&priv->wait_q); 778 init_waitqueue_head(&priv->wait_q);
@@ -951,7 +951,7 @@ io_subchannel_shutdown(struct device *dev)
951 sch = to_subchannel(dev); 951 sch = to_subchannel(dev);
952 cdev = dev->driver_data; 952 cdev = dev->driver_data;
953 953
954 if (cio_is_console(sch->irq)) 954 if (cio_is_console(sch->schid))
955 return; 955 return;
956 if (!sch->schib.pmcw.ena) 956 if (!sch->schib.pmcw.ena)
957 /* Nothing to do. */ 957 /* Nothing to do. */
@@ -1146,6 +1146,16 @@ ccw_driver_unregister (struct ccw_driver *cdriver)
1146 driver_unregister(&cdriver->driver); 1146 driver_unregister(&cdriver->driver);
1147} 1147}
1148 1148
1149/* Helper func for qdio. */
1150struct subchannel_id
1151ccw_device_get_subchannel_id(struct ccw_device *cdev)
1152{
1153 struct subchannel *sch;
1154
1155 sch = to_subchannel(cdev->dev.parent);
1156 return sch->schid;
1157}
1158
1149MODULE_LICENSE("GPL"); 1159MODULE_LICENSE("GPL");
1150EXPORT_SYMBOL(ccw_device_set_online); 1160EXPORT_SYMBOL(ccw_device_set_online);
1151EXPORT_SYMBOL(ccw_device_set_offline); 1161EXPORT_SYMBOL(ccw_device_set_offline);
@@ -1155,3 +1165,4 @@ EXPORT_SYMBOL(get_ccwdev_by_busid);
1155EXPORT_SYMBOL(ccw_bus_type); 1165EXPORT_SYMBOL(ccw_bus_type);
1156EXPORT_SYMBOL(ccw_device_work); 1166EXPORT_SYMBOL(ccw_device_work);
1157EXPORT_SYMBOL(ccw_device_notify_work); 1167EXPORT_SYMBOL(ccw_device_notify_work);
1168EXPORT_SYMBOL_GPL(ccw_device_get_subchannel_id);
diff --git a/drivers/s390/cio/device.h b/drivers/s390/cio/device.h
index a3aa056d7245..11587ebb7289 100644
--- a/drivers/s390/cio/device.h
+++ b/drivers/s390/cio/device.h
@@ -110,6 +110,7 @@ int ccw_device_stlck(struct ccw_device *);
110 110
111/* qdio needs this. */ 111/* qdio needs this. */
112void ccw_device_set_timeout(struct ccw_device *, int); 112void ccw_device_set_timeout(struct ccw_device *, int);
113extern struct subchannel_id ccw_device_get_subchannel_id(struct ccw_device *);
113 114
114void retry_set_schib(struct ccw_device *cdev); 115void retry_set_schib(struct ccw_device *cdev);
115#endif 116#endif
diff --git a/drivers/s390/cio/device_fsm.c b/drivers/s390/cio/device_fsm.c
index c1c89f4fd4e3..9efeae75ad28 100644
--- a/drivers/s390/cio/device_fsm.c
+++ b/drivers/s390/cio/device_fsm.c
@@ -133,7 +133,7 @@ ccw_device_cancel_halt_clear(struct ccw_device *cdev)
133 int ret; 133 int ret;
134 134
135 sch = to_subchannel(cdev->dev.parent); 135 sch = to_subchannel(cdev->dev.parent);
136 ret = stsch(sch->irq, &sch->schib); 136 ret = stsch(sch->schid, &sch->schib);
137 if (ret || !sch->schib.pmcw.dnv) 137 if (ret || !sch->schib.pmcw.dnv)
138 return -ENODEV; 138 return -ENODEV;
139 if (!sch->schib.pmcw.ena || sch->schib.scsw.actl == 0) 139 if (!sch->schib.pmcw.ena || sch->schib.scsw.actl == 0)
@@ -231,7 +231,7 @@ ccw_device_recog_done(struct ccw_device *cdev, int state)
231 * through ssch() and the path information is up to date. 231 * through ssch() and the path information is up to date.
232 */ 232 */
233 old_lpm = sch->lpm; 233 old_lpm = sch->lpm;
234 stsch(sch->irq, &sch->schib); 234 stsch(sch->schid, &sch->schib);
235 sch->lpm = sch->schib.pmcw.pim & 235 sch->lpm = sch->schib.pmcw.pim &
236 sch->schib.pmcw.pam & 236 sch->schib.pmcw.pam &
237 sch->schib.pmcw.pom & 237 sch->schib.pmcw.pom &
@@ -258,7 +258,7 @@ ccw_device_recog_done(struct ccw_device *cdev, int state)
258 case DEV_STATE_NOT_OPER: 258 case DEV_STATE_NOT_OPER:
259 CIO_DEBUG(KERN_WARNING, 2, 259 CIO_DEBUG(KERN_WARNING, 2,
260 "SenseID : unknown device %04x on subchannel %04x\n", 260 "SenseID : unknown device %04x on subchannel %04x\n",
261 cdev->private->devno, sch->irq); 261 cdev->private->devno, sch->schid.sch_no);
262 break; 262 break;
263 case DEV_STATE_OFFLINE: 263 case DEV_STATE_OFFLINE:
264 if (cdev->private->state == DEV_STATE_DISCONNECTED_SENSE_ID) { 264 if (cdev->private->state == DEV_STATE_DISCONNECTED_SENSE_ID) {
@@ -291,7 +291,7 @@ ccw_device_recog_done(struct ccw_device *cdev, int state)
291 case DEV_STATE_BOXED: 291 case DEV_STATE_BOXED:
292 CIO_DEBUG(KERN_WARNING, 2, 292 CIO_DEBUG(KERN_WARNING, 2,
293 "SenseID : boxed device %04x on subchannel %04x\n", 293 "SenseID : boxed device %04x on subchannel %04x\n",
294 cdev->private->devno, sch->irq); 294 cdev->private->devno, sch->schid.sch_no);
295 break; 295 break;
296 } 296 }
297 cdev->private->state = state; 297 cdev->private->state = state;
@@ -359,7 +359,7 @@ ccw_device_done(struct ccw_device *cdev, int state)
359 if (state == DEV_STATE_BOXED) 359 if (state == DEV_STATE_BOXED)
360 CIO_DEBUG(KERN_WARNING, 2, 360 CIO_DEBUG(KERN_WARNING, 2,
361 "Boxed device %04x on subchannel %04x\n", 361 "Boxed device %04x on subchannel %04x\n",
362 cdev->private->devno, sch->irq); 362 cdev->private->devno, sch->schid.sch_no);
363 363
364 if (cdev->private->flags.donotify) { 364 if (cdev->private->flags.donotify) {
365 cdev->private->flags.donotify = 0; 365 cdev->private->flags.donotify = 0;
@@ -592,7 +592,7 @@ ccw_device_offline(struct ccw_device *cdev)
592 struct subchannel *sch; 592 struct subchannel *sch;
593 593
594 sch = to_subchannel(cdev->dev.parent); 594 sch = to_subchannel(cdev->dev.parent);
595 if (stsch(sch->irq, &sch->schib) || !sch->schib.pmcw.dnv) 595 if (stsch(sch->schid, &sch->schib) || !sch->schib.pmcw.dnv)
596 return -ENODEV; 596 return -ENODEV;
597 if (cdev->private->state != DEV_STATE_ONLINE) { 597 if (cdev->private->state != DEV_STATE_ONLINE) {
598 if (sch->schib.scsw.actl != 0) 598 if (sch->schib.scsw.actl != 0)
@@ -711,7 +711,7 @@ ccw_device_online_verify(struct ccw_device *cdev, enum dev_event dev_event)
711 * Since we might not just be coming from an interrupt from the 711 * Since we might not just be coming from an interrupt from the
712 * subchannel we have to update the schib. 712 * subchannel we have to update the schib.
713 */ 713 */
714 stsch(sch->irq, &sch->schib); 714 stsch(sch->schid, &sch->schib);
715 715
716 if (sch->schib.scsw.actl != 0 || 716 if (sch->schib.scsw.actl != 0 ||
717 (cdev->private->irb.scsw.stctl & SCSW_STCTL_STATUS_PEND)) { 717 (cdev->private->irb.scsw.stctl & SCSW_STCTL_STATUS_PEND)) {
@@ -923,7 +923,7 @@ ccw_device_wait4io_irq(struct ccw_device *cdev, enum dev_event dev_event)
923 923
924 /* Iff device is idle, reset timeout. */ 924 /* Iff device is idle, reset timeout. */
925 sch = to_subchannel(cdev->dev.parent); 925 sch = to_subchannel(cdev->dev.parent);
926 if (!stsch(sch->irq, &sch->schib)) 926 if (!stsch(sch->schid, &sch->schib))
927 if (sch->schib.scsw.actl == 0) 927 if (sch->schib.scsw.actl == 0)
928 ccw_device_set_timeout(cdev, 0); 928 ccw_device_set_timeout(cdev, 0);
929 /* Call the handler. */ 929 /* Call the handler. */
@@ -1035,7 +1035,7 @@ device_trigger_reprobe(struct subchannel *sch)
1035 return; 1035 return;
1036 1036
1037 /* Update some values. */ 1037 /* Update some values. */
1038 if (stsch(sch->irq, &sch->schib)) 1038 if (stsch(sch->schid, &sch->schib))
1039 return; 1039 return;
1040 1040
1041 /* 1041 /*
diff --git a/drivers/s390/cio/device_id.c b/drivers/s390/cio/device_id.c
index 0e68fb511dc9..207881ec7aaf 100644
--- a/drivers/s390/cio/device_id.c
+++ b/drivers/s390/cio/device_id.c
@@ -258,7 +258,7 @@ ccw_device_check_sense_id(struct ccw_device *cdev)
258 */ 258 */
259 CIO_MSG_EVENT(2, "SenseID : device %04x on Subchannel %04x " 259 CIO_MSG_EVENT(2, "SenseID : device %04x on Subchannel %04x "
260 "reports cmd reject\n", 260 "reports cmd reject\n",
261 cdev->private->devno, sch->irq); 261 cdev->private->devno, sch->schid.sch_no);
262 return -EOPNOTSUPP; 262 return -EOPNOTSUPP;
263 } 263 }
264 if (irb->esw.esw0.erw.cons) { 264 if (irb->esw.esw0.erw.cons) {
@@ -280,13 +280,13 @@ ccw_device_check_sense_id(struct ccw_device *cdev)
280 CIO_MSG_EVENT(2, "SenseID : path %02X for device %04x on" 280 CIO_MSG_EVENT(2, "SenseID : path %02X for device %04x on"
281 " subchannel %04x is 'not operational'\n", 281 " subchannel %04x is 'not operational'\n",
282 sch->orb.lpm, cdev->private->devno, 282 sch->orb.lpm, cdev->private->devno,
283 sch->irq); 283 sch->schid.sch_no);
284 return -EACCES; 284 return -EACCES;
285 } 285 }
286 /* Hmm, whatever happened, try again. */ 286 /* Hmm, whatever happened, try again. */
287 CIO_MSG_EVENT(2, "SenseID : start_IO() for device %04x on " 287 CIO_MSG_EVENT(2, "SenseID : start_IO() for device %04x on "
288 "subchannel %04x returns status %02X%02X\n", 288 "subchannel %04x returns status %02X%02X\n",
289 cdev->private->devno, sch->irq, 289 cdev->private->devno, sch->schid.sch_no,
290 irb->scsw.dstat, irb->scsw.cstat); 290 irb->scsw.dstat, irb->scsw.cstat);
291 return -EAGAIN; 291 return -EAGAIN;
292} 292}
diff --git a/drivers/s390/cio/device_ops.c b/drivers/s390/cio/device_ops.c
index 85a3026e6900..143b6c25a4e6 100644
--- a/drivers/s390/cio/device_ops.c
+++ b/drivers/s390/cio/device_ops.c
@@ -1,7 +1,7 @@
1/* 1/*
2 * drivers/s390/cio/device_ops.c 2 * drivers/s390/cio/device_ops.c
3 * 3 *
4 * $Revision: 1.57 $ 4 * $Revision: 1.58 $
5 * 5 *
6 * Copyright (C) 2002 IBM Deutschland Entwicklung GmbH, 6 * Copyright (C) 2002 IBM Deutschland Entwicklung GmbH,
7 * IBM Corporation 7 * IBM Corporation
@@ -570,7 +570,7 @@ ccw_device_get_chp_desc(struct ccw_device *cdev, int chp_no)
570int 570int
571_ccw_device_get_subchannel_number(struct ccw_device *cdev) 571_ccw_device_get_subchannel_number(struct ccw_device *cdev)
572{ 572{
573 return cdev->private->irq; 573 return cdev->private->sch_no;
574} 574}
575 575
576int 576int
diff --git a/drivers/s390/cio/device_pgid.c b/drivers/s390/cio/device_pgid.c
index 757b2706d5a9..f08e84cc3563 100644
--- a/drivers/s390/cio/device_pgid.c
+++ b/drivers/s390/cio/device_pgid.c
@@ -59,7 +59,7 @@ __ccw_device_sense_pgid_start(struct ccw_device *cdev)
59 CIO_MSG_EVENT(2, "SNID - Device %04x on Subchannel " 59 CIO_MSG_EVENT(2, "SNID - Device %04x on Subchannel "
60 "%04x, lpm %02X, became 'not " 60 "%04x, lpm %02X, became 'not "
61 "operational'\n", 61 "operational'\n",
62 cdev->private->devno, sch->irq, 62 cdev->private->devno, sch->schid.sch_no,
63 cdev->private->imask); 63 cdev->private->imask);
64 64
65 } 65 }
@@ -121,13 +121,14 @@ __ccw_device_check_sense_pgid(struct ccw_device *cdev)
121 if (irb->scsw.cc == 3) { 121 if (irb->scsw.cc == 3) {
122 CIO_MSG_EVENT(2, "SNID - Device %04x on Subchannel " 122 CIO_MSG_EVENT(2, "SNID - Device %04x on Subchannel "
123 "%04x, lpm %02X, became 'not operational'\n", 123 "%04x, lpm %02X, became 'not operational'\n",
124 cdev->private->devno, sch->irq, sch->orb.lpm); 124 cdev->private->devno, sch->schid.sch_no,
125 sch->orb.lpm);
125 return -EACCES; 126 return -EACCES;
126 } 127 }
127 if (cdev->private->pgid.inf.ps.state2 == SNID_STATE2_RESVD_ELSE) { 128 if (cdev->private->pgid.inf.ps.state2 == SNID_STATE2_RESVD_ELSE) {
128 CIO_MSG_EVENT(2, "SNID - Device %04x on Subchannel %04x " 129 CIO_MSG_EVENT(2, "SNID - Device %04x on Subchannel %04x "
129 "is reserved by someone else\n", 130 "is reserved by someone else\n",
130 cdev->private->devno, sch->irq); 131 cdev->private->devno, sch->schid.sch_no);
131 return -EUSERS; 132 return -EUSERS;
132 } 133 }
133 return 0; 134 return 0;
@@ -237,7 +238,7 @@ __ccw_device_do_pgid(struct ccw_device *cdev, __u8 func)
237 sch->vpm &= ~cdev->private->imask; 238 sch->vpm &= ~cdev->private->imask;
238 CIO_MSG_EVENT(2, "SPID - Device %04x on Subchannel " 239 CIO_MSG_EVENT(2, "SPID - Device %04x on Subchannel "
239 "%04x, lpm %02X, became 'not operational'\n", 240 "%04x, lpm %02X, became 'not operational'\n",
240 cdev->private->devno, sch->irq, cdev->private->imask); 241 cdev->private->devno, sch->schid.sch_no, cdev->private->imask);
241 return ret; 242 return ret;
242} 243}
243 244
@@ -271,7 +272,7 @@ __ccw_device_check_pgid(struct ccw_device *cdev)
271 if (irb->scsw.cc == 3) { 272 if (irb->scsw.cc == 3) {
272 CIO_MSG_EVENT(2, "SPID - Device %04x on Subchannel " 273 CIO_MSG_EVENT(2, "SPID - Device %04x on Subchannel "
273 "%04x, lpm %02X, became 'not operational'\n", 274 "%04x, lpm %02X, became 'not operational'\n",
274 cdev->private->devno, sch->irq, 275 cdev->private->devno, sch->schid.sch_no,
275 cdev->private->imask); 276 cdev->private->imask);
276 return -EACCES; 277 return -EACCES;
277 } 278 }
@@ -373,7 +374,7 @@ ccw_device_verify_start(struct ccw_device *cdev)
373 * Update sch->lpm with current values to catch paths becoming 374 * Update sch->lpm with current values to catch paths becoming
374 * available again. 375 * available again.
375 */ 376 */
376 if (stsch(sch->irq, &sch->schib)) { 377 if (stsch(sch->schid, &sch->schib)) {
377 ccw_device_verify_done(cdev, -ENODEV); 378 ccw_device_verify_done(cdev, -ENODEV);
378 return; 379 return;
379 } 380 }
diff --git a/drivers/s390/cio/device_status.c b/drivers/s390/cio/device_status.c
index 12a24d4331a2..929f8fb505f2 100644
--- a/drivers/s390/cio/device_status.c
+++ b/drivers/s390/cio/device_status.c
@@ -38,13 +38,13 @@ ccw_device_msg_control_check(struct ccw_device *cdev, struct irb *irb)
38 "received" 38 "received"
39 " ... device %04X on subchannel %04X, dev_stat " 39 " ... device %04X on subchannel %04X, dev_stat "
40 ": %02X sch_stat : %02X\n", 40 ": %02X sch_stat : %02X\n",
41 cdev->private->devno, cdev->private->irq, 41 cdev->private->devno, cdev->private->sch_no,
42 irb->scsw.dstat, irb->scsw.cstat); 42 irb->scsw.dstat, irb->scsw.cstat);
43 43
44 if (irb->scsw.cc != 3) { 44 if (irb->scsw.cc != 3) {
45 char dbf_text[15]; 45 char dbf_text[15];
46 46
47 sprintf(dbf_text, "chk%x", cdev->private->irq); 47 sprintf(dbf_text, "chk%x", cdev->private->sch_no);
48 CIO_TRACE_EVENT(0, dbf_text); 48 CIO_TRACE_EVENT(0, dbf_text);
49 CIO_HEX_EVENT(0, irb, sizeof (struct irb)); 49 CIO_HEX_EVENT(0, irb, sizeof (struct irb));
50 } 50 }
@@ -59,10 +59,10 @@ ccw_device_path_notoper(struct ccw_device *cdev)
59 struct subchannel *sch; 59 struct subchannel *sch;
60 60
61 sch = to_subchannel(cdev->dev.parent); 61 sch = to_subchannel(cdev->dev.parent);
62 stsch (sch->irq, &sch->schib); 62 stsch (sch->schid, &sch->schib);
63 63
64 CIO_MSG_EVENT(0, "%s(%04x) - path(s) %02x are " 64 CIO_MSG_EVENT(0, "%s(%04x) - path(s) %02x are "
65 "not operational \n", __FUNCTION__, sch->irq, 65 "not operational \n", __FUNCTION__, sch->schid.sch_no,
66 sch->schib.pmcw.pnom); 66 sch->schib.pmcw.pnom);
67 67
68 sch->lpm &= ~sch->schib.pmcw.pnom; 68 sch->lpm &= ~sch->schib.pmcw.pnom;
diff --git a/drivers/s390/cio/ioasm.h b/drivers/s390/cio/ioasm.h
index 45480a2bc4c0..66c882e52f32 100644
--- a/drivers/s390/cio/ioasm.h
+++ b/drivers/s390/cio/ioasm.h
@@ -1,12 +1,13 @@
1#ifndef S390_CIO_IOASM_H 1#ifndef S390_CIO_IOASM_H
2#define S390_CIO_IOASM_H 2#define S390_CIO_IOASM_H
3 3
4#include "schid.h"
5
4/* 6/*
5 * TPI info structure 7 * TPI info structure
6 */ 8 */
7struct tpi_info { 9struct tpi_info {
8 __u32 reserved1 : 16; /* reserved 0x00000001 */ 10 struct subchannel_id schid;
9 __u32 irq : 16; /* aka. subchannel number */
10 __u32 intparm; /* interruption parameter */ 11 __u32 intparm; /* interruption parameter */
11 __u32 adapter_IO : 1; 12 __u32 adapter_IO : 1;
12 __u32 reserved2 : 1; 13 __u32 reserved2 : 1;
@@ -21,7 +22,8 @@ struct tpi_info {
21 * Some S390 specific IO instructions as inline 22 * Some S390 specific IO instructions as inline
22 */ 23 */
23 24
24static inline int stsch(int irq, volatile struct schib *addr) 25static inline int stsch(struct subchannel_id schid,
26 volatile struct schib *addr)
25{ 27{
26 int ccode; 28 int ccode;
27 29
@@ -31,12 +33,13 @@ static inline int stsch(int irq, volatile struct schib *addr)
31 " ipm %0\n" 33 " ipm %0\n"
32 " srl %0,28" 34 " srl %0,28"
33 : "=d" (ccode) 35 : "=d" (ccode)
34 : "d" (irq | 0x10000), "a" (addr) 36 : "d" (schid), "a" (addr), "m" (*addr)
35 : "cc", "1" ); 37 : "cc", "1" );
36 return ccode; 38 return ccode;
37} 39}
38 40
39static inline int msch(int irq, volatile struct schib *addr) 41static inline int msch(struct subchannel_id schid,
42 volatile struct schib *addr)
40{ 43{
41 int ccode; 44 int ccode;
42 45
@@ -46,12 +49,13 @@ static inline int msch(int irq, volatile struct schib *addr)
46 " ipm %0\n" 49 " ipm %0\n"
47 " srl %0,28" 50 " srl %0,28"
48 : "=d" (ccode) 51 : "=d" (ccode)
49 : "d" (irq | 0x10000L), "a" (addr) 52 : "d" (schid), "a" (addr), "m" (*addr)
50 : "cc", "1" ); 53 : "cc", "1" );
51 return ccode; 54 return ccode;
52} 55}
53 56
54static inline int msch_err(int irq, volatile struct schib *addr) 57static inline int msch_err(struct subchannel_id schid,
58 volatile struct schib *addr)
55{ 59{
56 int ccode; 60 int ccode;
57 61
@@ -74,12 +78,13 @@ static inline int msch_err(int irq, volatile struct schib *addr)
74 ".previous" 78 ".previous"
75#endif 79#endif
76 : "=&d" (ccode) 80 : "=&d" (ccode)
77 : "d" (irq | 0x10000L), "a" (addr), "K" (-EIO) 81 : "d" (schid), "a" (addr), "K" (-EIO), "m" (*addr)
78 : "cc", "1" ); 82 : "cc", "1" );
79 return ccode; 83 return ccode;
80} 84}
81 85
82static inline int tsch(int irq, volatile struct irb *addr) 86static inline int tsch(struct subchannel_id schid,
87 volatile struct irb *addr)
83{ 88{
84 int ccode; 89 int ccode;
85 90
@@ -89,7 +94,7 @@ static inline int tsch(int irq, volatile struct irb *addr)
89 " ipm %0\n" 94 " ipm %0\n"
90 " srl %0,28" 95 " srl %0,28"
91 : "=d" (ccode) 96 : "=d" (ccode)
92 : "d" (irq | 0x10000L), "a" (addr) 97 : "d" (schid), "a" (addr), "m" (*addr)
93 : "cc", "1" ); 98 : "cc", "1" );
94 return ccode; 99 return ccode;
95} 100}
@@ -103,12 +108,13 @@ static inline int tpi( volatile struct tpi_info *addr)
103 " ipm %0\n" 108 " ipm %0\n"
104 " srl %0,28" 109 " srl %0,28"
105 : "=d" (ccode) 110 : "=d" (ccode)
106 : "a" (addr) 111 : "a" (addr), "m" (*addr)
107 : "cc", "1" ); 112 : "cc", "1" );
108 return ccode; 113 return ccode;
109} 114}
110 115
111static inline int ssch(int irq, volatile struct orb *addr) 116static inline int ssch(struct subchannel_id schid,
117 volatile struct orb *addr)
112{ 118{
113 int ccode; 119 int ccode;
114 120
@@ -118,12 +124,12 @@ static inline int ssch(int irq, volatile struct orb *addr)
118 " ipm %0\n" 124 " ipm %0\n"
119 " srl %0,28" 125 " srl %0,28"
120 : "=d" (ccode) 126 : "=d" (ccode)
121 : "d" (irq | 0x10000L), "a" (addr) 127 : "d" (schid), "a" (addr), "m" (*addr)
122 : "cc", "1" ); 128 : "cc", "1" );
123 return ccode; 129 return ccode;
124} 130}
125 131
126static inline int rsch(int irq) 132static inline int rsch(struct subchannel_id schid)
127{ 133{
128 int ccode; 134 int ccode;
129 135
@@ -133,12 +139,12 @@ static inline int rsch(int irq)
133 " ipm %0\n" 139 " ipm %0\n"
134 " srl %0,28" 140 " srl %0,28"
135 : "=d" (ccode) 141 : "=d" (ccode)
136 : "d" (irq | 0x10000L) 142 : "d" (schid)
137 : "cc", "1" ); 143 : "cc", "1" );
138 return ccode; 144 return ccode;
139} 145}
140 146
141static inline int csch(int irq) 147static inline int csch(struct subchannel_id schid)
142{ 148{
143 int ccode; 149 int ccode;
144 150
@@ -148,12 +154,12 @@ static inline int csch(int irq)
148 " ipm %0\n" 154 " ipm %0\n"
149 " srl %0,28" 155 " srl %0,28"
150 : "=d" (ccode) 156 : "=d" (ccode)
151 : "d" (irq | 0x10000L) 157 : "d" (schid)
152 : "cc", "1" ); 158 : "cc", "1" );
153 return ccode; 159 return ccode;
154} 160}
155 161
156static inline int hsch(int irq) 162static inline int hsch(struct subchannel_id schid)
157{ 163{
158 int ccode; 164 int ccode;
159 165
@@ -163,12 +169,12 @@ static inline int hsch(int irq)
163 " ipm %0\n" 169 " ipm %0\n"
164 " srl %0,28" 170 " srl %0,28"
165 : "=d" (ccode) 171 : "=d" (ccode)
166 : "d" (irq | 0x10000L) 172 : "d" (schid)
167 : "cc", "1" ); 173 : "cc", "1" );
168 return ccode; 174 return ccode;
169} 175}
170 176
171static inline int xsch(int irq) 177static inline int xsch(struct subchannel_id schid)
172{ 178{
173 int ccode; 179 int ccode;
174 180
@@ -178,21 +184,22 @@ static inline int xsch(int irq)
178 " ipm %0\n" 184 " ipm %0\n"
179 " srl %0,28" 185 " srl %0,28"
180 : "=d" (ccode) 186 : "=d" (ccode)
181 : "d" (irq | 0x10000L) 187 : "d" (schid)
182 : "cc", "1" ); 188 : "cc", "1" );
183 return ccode; 189 return ccode;
184} 190}
185 191
186static inline int chsc(void *chsc_area) 192static inline int chsc(void *chsc_area)
187{ 193{
194 typedef struct { char _[4096]; } addr_type;
188 int cc; 195 int cc;
189 196
190 __asm__ __volatile__ ( 197 __asm__ __volatile__ (
191 ".insn rre,0xb25f0000,%1,0 \n\t" 198 ".insn rre,0xb25f0000,%2,0 \n\t"
192 "ipm %0 \n\t" 199 "ipm %0 \n\t"
193 "srl %0,28 \n\t" 200 "srl %0,28 \n\t"
194 : "=d" (cc) 201 : "=d" (cc), "=m" (*(addr_type *) chsc_area)
195 : "d" (chsc_area) 202 : "d" (chsc_area), "m" (*(addr_type *) chsc_area)
196 : "cc" ); 203 : "cc" );
197 204
198 return cc; 205 return cc;
diff --git a/drivers/s390/cio/qdio.c b/drivers/s390/cio/qdio.c
index e8bdfcd1d02a..5c7001b5c7a1 100644
--- a/drivers/s390/cio/qdio.c
+++ b/drivers/s390/cio/qdio.c
@@ -270,7 +270,7 @@ qdio_siga_sync(struct qdio_q *q, unsigned int gpr2,
270 perf_stats.siga_syncs++; 270 perf_stats.siga_syncs++;
271#endif /* QDIO_PERFORMANCE_STATS */ 271#endif /* QDIO_PERFORMANCE_STATS */
272 272
273 cc = do_siga_sync(0x10000|q->irq, gpr2, gpr3); 273 cc = do_siga_sync(q->schid, gpr2, gpr3);
274 if (cc) 274 if (cc)
275 QDIO_DBF_HEX3(0,trace,&cc,sizeof(int*)); 275 QDIO_DBF_HEX3(0,trace,&cc,sizeof(int*));
276 276
@@ -290,12 +290,16 @@ __do_siga_output(struct qdio_q *q, unsigned int *busy_bit)
290{ 290{
291 struct qdio_irq *irq; 291 struct qdio_irq *irq;
292 unsigned int fc = 0; 292 unsigned int fc = 0;
293 unsigned long schid;
293 294
294 irq = (struct qdio_irq *) q->irq_ptr; 295 irq = (struct qdio_irq *) q->irq_ptr;
295 if (!irq->is_qebsm) 296 if (!irq->is_qebsm)
296 return do_siga_output(0x10000|q->irq, q->mask, busy_bit, fc); 297 schid = *((u32 *)&q->schid);
297 fc |= 0x80; 298 else {
298 return do_siga_output(irq->sch_token, q->mask, busy_bit, fc); 299 schid = irq->sch_token;
300 fc |= 0x80;
301 }
302 return do_siga_output(schid, q->mask, busy_bit, fc);
299} 303}
300 304
301/* 305/*
@@ -349,7 +353,7 @@ qdio_siga_input(struct qdio_q *q)
349 perf_stats.siga_ins++; 353 perf_stats.siga_ins++;
350#endif /* QDIO_PERFORMANCE_STATS */ 354#endif /* QDIO_PERFORMANCE_STATS */
351 355
352 cc = do_siga_input(0x10000|q->irq, q->mask); 356 cc = do_siga_input(q->schid, q->mask);
353 357
354 if (cc) 358 if (cc)
355 QDIO_DBF_HEX3(0,trace,&cc,sizeof(int*)); 359 QDIO_DBF_HEX3(0,trace,&cc,sizeof(int*));
@@ -855,7 +859,7 @@ qdio_kick_outbound_q(struct qdio_q *q)
855 /* went smooth this time, reset timestamp */ 859 /* went smooth this time, reset timestamp */
856#ifdef CONFIG_QDIO_DEBUG 860#ifdef CONFIG_QDIO_DEBUG
857 QDIO_DBF_TEXT3(0,trace,"cc2reslv"); 861 QDIO_DBF_TEXT3(0,trace,"cc2reslv");
858 sprintf(dbf_text,"%4x%2x%2x",q->irq,q->q_no, 862 sprintf(dbf_text,"%4x%2x%2x",q->schid.sch_no,q->q_no,
859 atomic_read(&q->busy_siga_counter)); 863 atomic_read(&q->busy_siga_counter));
860 QDIO_DBF_TEXT3(0,trace,dbf_text); 864 QDIO_DBF_TEXT3(0,trace,dbf_text);
861#endif /* CONFIG_QDIO_DEBUG */ 865#endif /* CONFIG_QDIO_DEBUG */
@@ -878,7 +882,7 @@ qdio_kick_outbound_q(struct qdio_q *q)
878 } 882 }
879 QDIO_DBF_TEXT2(0,trace,"cc2REPRT"); 883 QDIO_DBF_TEXT2(0,trace,"cc2REPRT");
880#ifdef CONFIG_QDIO_DEBUG 884#ifdef CONFIG_QDIO_DEBUG
881 sprintf(dbf_text,"%4x%2x%2x",q->irq,q->q_no, 885 sprintf(dbf_text,"%4x%2x%2x",q->schid.sch_no,q->q_no,
882 atomic_read(&q->busy_siga_counter)); 886 atomic_read(&q->busy_siga_counter));
883 QDIO_DBF_TEXT3(0,trace,dbf_text); 887 QDIO_DBF_TEXT3(0,trace,dbf_text);
884#endif /* CONFIG_QDIO_DEBUG */ 888#endif /* CONFIG_QDIO_DEBUG */
@@ -1733,7 +1737,7 @@ qdio_fill_qs(struct qdio_irq *irq_ptr, struct ccw_device *cdev,
1733 void *ptr; 1737 void *ptr;
1734 int available; 1738 int available;
1735 1739
1736 sprintf(dbf_text,"qfqs%4x",cdev->private->irq); 1740 sprintf(dbf_text,"qfqs%4x",cdev->private->sch_no);
1737 QDIO_DBF_TEXT0(0,setup,dbf_text); 1741 QDIO_DBF_TEXT0(0,setup,dbf_text);
1738 for (i=0;i<no_input_qs;i++) { 1742 for (i=0;i<no_input_qs;i++) {
1739 q=irq_ptr->input_qs[i]; 1743 q=irq_ptr->input_qs[i];
@@ -1753,7 +1757,7 @@ qdio_fill_qs(struct qdio_irq *irq_ptr, struct ccw_device *cdev,
1753 1757
1754 q->queue_type=q_format; 1758 q->queue_type=q_format;
1755 q->int_parm=int_parm; 1759 q->int_parm=int_parm;
1756 q->irq=irq_ptr->irq; 1760 q->schid = irq_ptr->schid;
1757 q->irq_ptr = irq_ptr; 1761 q->irq_ptr = irq_ptr;
1758 q->cdev = cdev; 1762 q->cdev = cdev;
1759 q->mask=1<<(31-i); 1763 q->mask=1<<(31-i);
@@ -1826,7 +1830,7 @@ qdio_fill_qs(struct qdio_irq *irq_ptr, struct ccw_device *cdev,
1826 q->queue_type=q_format; 1830 q->queue_type=q_format;
1827 q->int_parm=int_parm; 1831 q->int_parm=int_parm;
1828 q->is_input_q=0; 1832 q->is_input_q=0;
1829 q->irq=irq_ptr->irq; 1833 q->schid = irq_ptr->schid;
1830 q->cdev = cdev; 1834 q->cdev = cdev;
1831 q->irq_ptr = irq_ptr; 1835 q->irq_ptr = irq_ptr;
1832 q->mask=1<<(31-i); 1836 q->mask=1<<(31-i);
@@ -1933,7 +1937,7 @@ qdio_set_state(struct qdio_irq *irq_ptr, enum qdio_irq_states state)
1933 char dbf_text[15]; 1937 char dbf_text[15];
1934 1938
1935 QDIO_DBF_TEXT5(0,trace,"newstate"); 1939 QDIO_DBF_TEXT5(0,trace,"newstate");
1936 sprintf(dbf_text,"%4x%4x",irq_ptr->irq,state); 1940 sprintf(dbf_text,"%4x%4x",irq_ptr->schid.sch_no,state);
1937 QDIO_DBF_TEXT5(0,trace,dbf_text); 1941 QDIO_DBF_TEXT5(0,trace,dbf_text);
1938#endif /* CONFIG_QDIO_DEBUG */ 1942#endif /* CONFIG_QDIO_DEBUG */
1939 1943
@@ -1946,12 +1950,12 @@ qdio_set_state(struct qdio_irq *irq_ptr, enum qdio_irq_states state)
1946} 1950}
1947 1951
1948static inline void 1952static inline void
1949qdio_irq_check_sense(int irq, struct irb *irb) 1953qdio_irq_check_sense(struct subchannel_id schid, struct irb *irb)
1950{ 1954{
1951 char dbf_text[15]; 1955 char dbf_text[15];
1952 1956
1953 if (irb->esw.esw0.erw.cons) { 1957 if (irb->esw.esw0.erw.cons) {
1954 sprintf(dbf_text,"sens%4x",irq); 1958 sprintf(dbf_text,"sens%4x",schid.sch_no);
1955 QDIO_DBF_TEXT2(1,trace,dbf_text); 1959 QDIO_DBF_TEXT2(1,trace,dbf_text);
1956 QDIO_DBF_HEX0(0,sense,irb,QDIO_DBF_SENSE_LEN); 1960 QDIO_DBF_HEX0(0,sense,irb,QDIO_DBF_SENSE_LEN);
1957 1961
@@ -2063,20 +2067,20 @@ qdio_timeout_handler(struct ccw_device *cdev)
2063 switch (irq_ptr->state) { 2067 switch (irq_ptr->state) {
2064 case QDIO_IRQ_STATE_INACTIVE: 2068 case QDIO_IRQ_STATE_INACTIVE:
2065 QDIO_PRINT_ERR("establish queues on irq %04x: timed out\n", 2069 QDIO_PRINT_ERR("establish queues on irq %04x: timed out\n",
2066 irq_ptr->irq); 2070 irq_ptr->schid.sch_no);
2067 QDIO_DBF_TEXT2(1,setup,"eq:timeo"); 2071 QDIO_DBF_TEXT2(1,setup,"eq:timeo");
2068 qdio_set_state(irq_ptr, QDIO_IRQ_STATE_ERR); 2072 qdio_set_state(irq_ptr, QDIO_IRQ_STATE_ERR);
2069 break; 2073 break;
2070 case QDIO_IRQ_STATE_CLEANUP: 2074 case QDIO_IRQ_STATE_CLEANUP:
2071 QDIO_PRINT_INFO("Did not get interrupt on cleanup, irq=0x%x.\n", 2075 QDIO_PRINT_INFO("Did not get interrupt on cleanup, irq=0x%x.\n",
2072 irq_ptr->irq); 2076 irq_ptr->schid.sch_no);
2073 qdio_set_state(irq_ptr, QDIO_IRQ_STATE_ERR); 2077 qdio_set_state(irq_ptr, QDIO_IRQ_STATE_ERR);
2074 break; 2078 break;
2075 case QDIO_IRQ_STATE_ESTABLISHED: 2079 case QDIO_IRQ_STATE_ESTABLISHED:
2076 case QDIO_IRQ_STATE_ACTIVE: 2080 case QDIO_IRQ_STATE_ACTIVE:
2077 /* I/O has been terminated by common I/O layer. */ 2081 /* I/O has been terminated by common I/O layer. */
2078 QDIO_PRINT_INFO("Queues on irq %04x killed by cio.\n", 2082 QDIO_PRINT_INFO("Queues on irq %04x killed by cio.\n",
2079 irq_ptr->irq); 2083 irq_ptr->schid.sch_no);
2080 QDIO_DBF_TEXT2(1, trace, "cio:term"); 2084 QDIO_DBF_TEXT2(1, trace, "cio:term");
2081 qdio_set_state(irq_ptr, QDIO_IRQ_STATE_STOPPED); 2085 qdio_set_state(irq_ptr, QDIO_IRQ_STATE_STOPPED);
2082 if (get_device(&cdev->dev)) { 2086 if (get_device(&cdev->dev)) {
@@ -2139,7 +2143,7 @@ qdio_handler(struct ccw_device *cdev, unsigned long intparm, struct irb *irb)
2139 } 2143 }
2140 } 2144 }
2141 2145
2142 qdio_irq_check_sense(irq_ptr->irq, irb); 2146 qdio_irq_check_sense(irq_ptr->schid, irb);
2143 2147
2144#ifdef CONFIG_QDIO_DEBUG 2148#ifdef CONFIG_QDIO_DEBUG
2145 sprintf(dbf_text, "state:%d", irq_ptr->state); 2149 sprintf(dbf_text, "state:%d", irq_ptr->state);
@@ -2195,7 +2199,7 @@ qdio_synchronize(struct ccw_device *cdev, unsigned int flags,
2195 return -ENODEV; 2199 return -ENODEV;
2196 2200
2197#ifdef CONFIG_QDIO_DEBUG 2201#ifdef CONFIG_QDIO_DEBUG
2198 *((int*)(&dbf_text[4])) = irq_ptr->irq; 2202 *((int*)(&dbf_text[4])) = irq_ptr->schid.sch_no;
2199 QDIO_DBF_HEX4(0,trace,dbf_text,QDIO_DBF_TRACE_LEN); 2203 QDIO_DBF_HEX4(0,trace,dbf_text,QDIO_DBF_TRACE_LEN);
2200 *((int*)(&dbf_text[0]))=flags; 2204 *((int*)(&dbf_text[0]))=flags;
2201 *((int*)(&dbf_text[4]))=queue_number; 2205 *((int*)(&dbf_text[4]))=queue_number;
@@ -2207,13 +2211,13 @@ qdio_synchronize(struct ccw_device *cdev, unsigned int flags,
2207 if (!q) 2211 if (!q)
2208 return -EINVAL; 2212 return -EINVAL;
2209 if (!(irq_ptr->is_qebsm)) 2213 if (!(irq_ptr->is_qebsm))
2210 cc = do_siga_sync(0x10000|q->irq, 0, q->mask); 2214 cc = do_siga_sync(q->schid, 0, q->mask);
2211 } else if (flags&QDIO_FLAG_SYNC_OUTPUT) { 2215 } else if (flags&QDIO_FLAG_SYNC_OUTPUT) {
2212 q=irq_ptr->output_qs[queue_number]; 2216 q=irq_ptr->output_qs[queue_number];
2213 if (!q) 2217 if (!q)
2214 return -EINVAL; 2218 return -EINVAL;
2215 if (!(irq_ptr->is_qebsm)) 2219 if (!(irq_ptr->is_qebsm))
2216 cc = do_siga_sync(0x10000|q->irq, q->mask, 0); 2220 cc = do_siga_sync(q->schid, q->mask, 0);
2217 } else 2221 } else
2218 return -EINVAL; 2222 return -EINVAL;
2219 2223
@@ -2298,7 +2302,7 @@ qdio_get_ssqd_information(struct qdio_irq *irq_ptr)
2298 ssqd_area = (void *)get_zeroed_page(GFP_KERNEL | GFP_DMA); 2302 ssqd_area = (void *)get_zeroed_page(GFP_KERNEL | GFP_DMA);
2299 if (!ssqd_area) { 2303 if (!ssqd_area) {
2300 QDIO_PRINT_WARN("Could not get memory for chsc. Using all " \ 2304 QDIO_PRINT_WARN("Could not get memory for chsc. Using all " \
2301 "SIGAs for sch x%x.\n", irq_ptr->irq); 2305 "SIGAs for sch x%x.\n", irq_ptr->schid.sch_no);
2302 irq_ptr->qdioac = CHSC_FLAG_SIGA_INPUT_NECESSARY || 2306 irq_ptr->qdioac = CHSC_FLAG_SIGA_INPUT_NECESSARY ||
2303 CHSC_FLAG_SIGA_OUTPUT_NECESSARY || 2307 CHSC_FLAG_SIGA_OUTPUT_NECESSARY ||
2304 CHSC_FLAG_SIGA_SYNC_NECESSARY; /* all flags set */ 2308 CHSC_FLAG_SIGA_SYNC_NECESSARY; /* all flags set */
@@ -2312,14 +2316,14 @@ qdio_get_ssqd_information(struct qdio_irq *irq_ptr)
2312 .length = 0x0010, 2316 .length = 0x0010,
2313 .code = 0x0024, 2317 .code = 0x0024,
2314 }; 2318 };
2315 ssqd_area->first_sch = irq_ptr->irq; 2319 ssqd_area->first_sch = irq_ptr->schid.sch_no;
2316 ssqd_area->last_sch = irq_ptr->irq; 2320 ssqd_area->last_sch = irq_ptr->schid.sch_no;
2317 result = chsc(ssqd_area); 2321 result = chsc(ssqd_area);
2318 2322
2319 if (result) { 2323 if (result) {
2320 QDIO_PRINT_WARN("CHSC returned cc %i. Using all " \ 2324 QDIO_PRINT_WARN("CHSC returned cc %i. Using all " \
2321 "SIGAs for sch x%x.\n", 2325 "SIGAs for sch x%x.\n",
2322 result, irq_ptr->irq); 2326 result, irq_ptr->schid.sch_no);
2323 qdioac = CHSC_FLAG_SIGA_INPUT_NECESSARY || 2327 qdioac = CHSC_FLAG_SIGA_INPUT_NECESSARY ||
2324 CHSC_FLAG_SIGA_OUTPUT_NECESSARY || 2328 CHSC_FLAG_SIGA_OUTPUT_NECESSARY ||
2325 CHSC_FLAG_SIGA_SYNC_NECESSARY; /* all flags set */ 2329 CHSC_FLAG_SIGA_SYNC_NECESSARY; /* all flags set */
@@ -2330,7 +2334,7 @@ qdio_get_ssqd_information(struct qdio_irq *irq_ptr)
2330 if (ssqd_area->response.code != QDIO_CHSC_RESPONSE_CODE_OK) { 2334 if (ssqd_area->response.code != QDIO_CHSC_RESPONSE_CODE_OK) {
2331 QDIO_PRINT_WARN("response upon checking SIGA needs " \ 2335 QDIO_PRINT_WARN("response upon checking SIGA needs " \
2332 "is 0x%x. Using all SIGAs for sch x%x.\n", 2336 "is 0x%x. Using all SIGAs for sch x%x.\n",
2333 ssqd_area->response.code, irq_ptr->irq); 2337 ssqd_area->response.code, irq_ptr->schid.sch_no);
2334 qdioac = CHSC_FLAG_SIGA_INPUT_NECESSARY || 2338 qdioac = CHSC_FLAG_SIGA_INPUT_NECESSARY ||
2335 CHSC_FLAG_SIGA_OUTPUT_NECESSARY || 2339 CHSC_FLAG_SIGA_OUTPUT_NECESSARY ||
2336 CHSC_FLAG_SIGA_SYNC_NECESSARY; /* all flags set */ 2340 CHSC_FLAG_SIGA_SYNC_NECESSARY; /* all flags set */
@@ -2339,9 +2343,9 @@ qdio_get_ssqd_information(struct qdio_irq *irq_ptr)
2339 } 2343 }
2340 if (!(ssqd_area->flags & CHSC_FLAG_QDIO_CAPABILITY) || 2344 if (!(ssqd_area->flags & CHSC_FLAG_QDIO_CAPABILITY) ||
2341 !(ssqd_area->flags & CHSC_FLAG_VALIDITY) || 2345 !(ssqd_area->flags & CHSC_FLAG_VALIDITY) ||
2342 (ssqd_area->sch != irq_ptr->irq)) { 2346 (ssqd_area->sch != irq_ptr->schid.sch_no)) {
2343 QDIO_PRINT_WARN("huh? problems checking out sch x%x... " \ 2347 QDIO_PRINT_WARN("huh? problems checking out sch x%x... " \
2344 "using all SIGAs.\n",irq_ptr->irq); 2348 "using all SIGAs.\n",irq_ptr->schid.sch_no);
2345 qdioac = CHSC_FLAG_SIGA_INPUT_NECESSARY | 2349 qdioac = CHSC_FLAG_SIGA_INPUT_NECESSARY |
2346 CHSC_FLAG_SIGA_OUTPUT_NECESSARY | 2350 CHSC_FLAG_SIGA_OUTPUT_NECESSARY |
2347 CHSC_FLAG_SIGA_SYNC_NECESSARY; /* worst case */ 2351 CHSC_FLAG_SIGA_SYNC_NECESSARY; /* worst case */
@@ -2427,7 +2431,7 @@ tiqdio_set_subchannel_ind(struct qdio_irq *irq_ptr, int reset_to_zero)
2427 /* set to 0x10000000 to enable 2431 /* set to 0x10000000 to enable
2428 * time delay disablement facility */ 2432 * time delay disablement facility */
2429 u32 reserved5; 2433 u32 reserved5;
2430 u32 subsystem_id; 2434 struct subchannel_id schid;
2431 u32 reserved6[1004]; 2435 u32 reserved6[1004];
2432 struct chsc_header response; 2436 struct chsc_header response;
2433 u32 reserved7; 2437 u32 reserved7;
@@ -2449,7 +2453,7 @@ tiqdio_set_subchannel_ind(struct qdio_irq *irq_ptr, int reset_to_zero)
2449 scssc_area = (void *)get_zeroed_page(GFP_KERNEL | GFP_DMA); 2453 scssc_area = (void *)get_zeroed_page(GFP_KERNEL | GFP_DMA);
2450 if (!scssc_area) { 2454 if (!scssc_area) {
2451 QDIO_PRINT_WARN("No memory for setting indicators on " \ 2455 QDIO_PRINT_WARN("No memory for setting indicators on " \
2452 "subchannel x%x.\n", irq_ptr->irq); 2456 "subchannel x%x.\n", irq_ptr->schid.sch_no);
2453 return -ENOMEM; 2457 return -ENOMEM;
2454 } 2458 }
2455 scssc_area->request = (struct chsc_header) { 2459 scssc_area->request = (struct chsc_header) {
@@ -2463,7 +2467,7 @@ tiqdio_set_subchannel_ind(struct qdio_irq *irq_ptr, int reset_to_zero)
2463 scssc_area->ks = QDIO_STORAGE_KEY; 2467 scssc_area->ks = QDIO_STORAGE_KEY;
2464 scssc_area->kc = QDIO_STORAGE_KEY; 2468 scssc_area->kc = QDIO_STORAGE_KEY;
2465 scssc_area->isc = TIQDIO_THININT_ISC; 2469 scssc_area->isc = TIQDIO_THININT_ISC;
2466 scssc_area->subsystem_id = (1<<16) + irq_ptr->irq; 2470 scssc_area->schid = irq_ptr->schid;
2467 /* enables the time delay disablement facility. Don't care 2471 /* enables the time delay disablement facility. Don't care
2468 * whether it is really there (i.e. we haven't checked for 2472 * whether it is really there (i.e. we haven't checked for
2469 * it) */ 2473 * it) */
@@ -2473,12 +2477,10 @@ tiqdio_set_subchannel_ind(struct qdio_irq *irq_ptr, int reset_to_zero)
2473 QDIO_PRINT_WARN("Time delay disablement facility " \ 2477 QDIO_PRINT_WARN("Time delay disablement facility " \
2474 "not available\n"); 2478 "not available\n");
2475 2479
2476
2477
2478 result = chsc(scssc_area); 2480 result = chsc(scssc_area);
2479 if (result) { 2481 if (result) {
2480 QDIO_PRINT_WARN("could not set indicators on irq x%x, " \ 2482 QDIO_PRINT_WARN("could not set indicators on irq x%x, " \
2481 "cc=%i.\n",irq_ptr->irq,result); 2483 "cc=%i.\n",irq_ptr->schid.sch_no,result);
2482 result = -EIO; 2484 result = -EIO;
2483 goto out; 2485 goto out;
2484 } 2486 }
@@ -2534,7 +2536,7 @@ tiqdio_set_delay_target(struct qdio_irq *irq_ptr, unsigned long delay_target)
2534 scsscf_area = (void *)get_zeroed_page(GFP_KERNEL | GFP_DMA); 2536 scsscf_area = (void *)get_zeroed_page(GFP_KERNEL | GFP_DMA);
2535 if (!scsscf_area) { 2537 if (!scsscf_area) {
2536 QDIO_PRINT_WARN("No memory for setting delay target on " \ 2538 QDIO_PRINT_WARN("No memory for setting delay target on " \
2537 "subchannel x%x.\n", irq_ptr->irq); 2539 "subchannel x%x.\n", irq_ptr->schid.sch_no);
2538 return -ENOMEM; 2540 return -ENOMEM;
2539 } 2541 }
2540 scsscf_area->request = (struct chsc_header) { 2542 scsscf_area->request = (struct chsc_header) {
@@ -2547,7 +2549,8 @@ tiqdio_set_delay_target(struct qdio_irq *irq_ptr, unsigned long delay_target)
2547 result=chsc(scsscf_area); 2549 result=chsc(scsscf_area);
2548 if (result) { 2550 if (result) {
2549 QDIO_PRINT_WARN("could not set delay target on irq x%x, " \ 2551 QDIO_PRINT_WARN("could not set delay target on irq x%x, " \
2550 "cc=%i. Continuing.\n",irq_ptr->irq,result); 2552 "cc=%i. Continuing.\n",irq_ptr->schid.sch_no,
2553 result);
2551 result = -EIO; 2554 result = -EIO;
2552 goto out; 2555 goto out;
2553 } 2556 }
@@ -2581,7 +2584,7 @@ qdio_cleanup(struct ccw_device *cdev, int how)
2581 if (!irq_ptr) 2584 if (!irq_ptr)
2582 return -ENODEV; 2585 return -ENODEV;
2583 2586
2584 sprintf(dbf_text,"qcln%4x",irq_ptr->irq); 2587 sprintf(dbf_text,"qcln%4x",irq_ptr->schid.sch_no);
2585 QDIO_DBF_TEXT1(0,trace,dbf_text); 2588 QDIO_DBF_TEXT1(0,trace,dbf_text);
2586 QDIO_DBF_TEXT0(0,setup,dbf_text); 2589 QDIO_DBF_TEXT0(0,setup,dbf_text);
2587 2590
@@ -2608,7 +2611,7 @@ qdio_shutdown(struct ccw_device *cdev, int how)
2608 2611
2609 down(&irq_ptr->setting_up_sema); 2612 down(&irq_ptr->setting_up_sema);
2610 2613
2611 sprintf(dbf_text,"qsqs%4x",irq_ptr->irq); 2614 sprintf(dbf_text,"qsqs%4x",irq_ptr->schid.sch_no);
2612 QDIO_DBF_TEXT1(0,trace,dbf_text); 2615 QDIO_DBF_TEXT1(0,trace,dbf_text);
2613 QDIO_DBF_TEXT0(0,setup,dbf_text); 2616 QDIO_DBF_TEXT0(0,setup,dbf_text);
2614 2617
@@ -2714,7 +2717,7 @@ qdio_free(struct ccw_device *cdev)
2714 2717
2715 down(&irq_ptr->setting_up_sema); 2718 down(&irq_ptr->setting_up_sema);
2716 2719
2717 sprintf(dbf_text,"qfqs%4x",irq_ptr->irq); 2720 sprintf(dbf_text,"qfqs%4x",irq_ptr->schid.sch_no);
2718 QDIO_DBF_TEXT1(0,trace,dbf_text); 2721 QDIO_DBF_TEXT1(0,trace,dbf_text);
2719 QDIO_DBF_TEXT0(0,setup,dbf_text); 2722 QDIO_DBF_TEXT0(0,setup,dbf_text);
2720 2723
@@ -2862,13 +2865,13 @@ qdio_establish_irq_check_for_errors(struct ccw_device *cdev, int cstat,
2862 irq_ptr = cdev->private->qdio_data; 2865 irq_ptr = cdev->private->qdio_data;
2863 2866
2864 if (cstat || (dstat & ~(DEV_STAT_CHN_END|DEV_STAT_DEV_END))) { 2867 if (cstat || (dstat & ~(DEV_STAT_CHN_END|DEV_STAT_DEV_END))) {
2865 sprintf(dbf_text,"ick1%4x",irq_ptr->irq); 2868 sprintf(dbf_text,"ick1%4x",irq_ptr->schid.sch_no);
2866 QDIO_DBF_TEXT2(1,trace,dbf_text); 2869 QDIO_DBF_TEXT2(1,trace,dbf_text);
2867 QDIO_DBF_HEX2(0,trace,&dstat,sizeof(int)); 2870 QDIO_DBF_HEX2(0,trace,&dstat,sizeof(int));
2868 QDIO_DBF_HEX2(0,trace,&cstat,sizeof(int)); 2871 QDIO_DBF_HEX2(0,trace,&cstat,sizeof(int));
2869 QDIO_PRINT_ERR("received check condition on establish " \ 2872 QDIO_PRINT_ERR("received check condition on establish " \
2870 "queues on irq 0x%x (cs=x%x, ds=x%x).\n", 2873 "queues on irq 0x%x (cs=x%x, ds=x%x).\n",
2871 irq_ptr->irq,cstat,dstat); 2874 irq_ptr->schid.sch_no,cstat,dstat);
2872 qdio_set_state(irq_ptr,QDIO_IRQ_STATE_ERR); 2875 qdio_set_state(irq_ptr,QDIO_IRQ_STATE_ERR);
2873 } 2876 }
2874 2877
@@ -2878,7 +2881,7 @@ qdio_establish_irq_check_for_errors(struct ccw_device *cdev, int cstat,
2878 QDIO_DBF_HEX2(0,setup,&cstat, sizeof(cstat)); 2881 QDIO_DBF_HEX2(0,setup,&cstat, sizeof(cstat));
2879 QDIO_PRINT_ERR("establish queues on irq %04x: didn't get " 2882 QDIO_PRINT_ERR("establish queues on irq %04x: didn't get "
2880 "device end: dstat=%02x, cstat=%02x\n", 2883 "device end: dstat=%02x, cstat=%02x\n",
2881 irq_ptr->irq, dstat, cstat); 2884 irq_ptr->schid.sch_no, dstat, cstat);
2882 qdio_set_state(irq_ptr, QDIO_IRQ_STATE_ERR); 2885 qdio_set_state(irq_ptr, QDIO_IRQ_STATE_ERR);
2883 return 1; 2886 return 1;
2884 } 2887 }
@@ -2890,7 +2893,7 @@ qdio_establish_irq_check_for_errors(struct ccw_device *cdev, int cstat,
2890 QDIO_PRINT_ERR("establish queues on irq %04x: got " 2893 QDIO_PRINT_ERR("establish queues on irq %04x: got "
2891 "the following devstat: dstat=%02x, " 2894 "the following devstat: dstat=%02x, "
2892 "cstat=%02x\n", 2895 "cstat=%02x\n",
2893 irq_ptr->irq, dstat, cstat); 2896 irq_ptr->schid.sch_no, dstat, cstat);
2894 qdio_set_state(irq_ptr, QDIO_IRQ_STATE_ERR); 2897 qdio_set_state(irq_ptr, QDIO_IRQ_STATE_ERR);
2895 return 1; 2898 return 1;
2896 } 2899 }
@@ -2905,7 +2908,7 @@ qdio_establish_handle_irq(struct ccw_device *cdev, int cstat, int dstat)
2905 2908
2906 irq_ptr = cdev->private->qdio_data; 2909 irq_ptr = cdev->private->qdio_data;
2907 2910
2908 sprintf(dbf_text,"qehi%4x",cdev->private->irq); 2911 sprintf(dbf_text,"qehi%4x",cdev->private->sch_no);
2909 QDIO_DBF_TEXT0(0,setup,dbf_text); 2912 QDIO_DBF_TEXT0(0,setup,dbf_text);
2910 QDIO_DBF_TEXT0(0,trace,dbf_text); 2913 QDIO_DBF_TEXT0(0,trace,dbf_text);
2911 2914
@@ -2924,7 +2927,7 @@ qdio_initialize(struct qdio_initialize *init_data)
2924 int rc; 2927 int rc;
2925 char dbf_text[15]; 2928 char dbf_text[15];
2926 2929
2927 sprintf(dbf_text,"qini%4x",init_data->cdev->private->irq); 2930 sprintf(dbf_text,"qini%4x",init_data->cdev->private->sch_no);
2928 QDIO_DBF_TEXT0(0,setup,dbf_text); 2931 QDIO_DBF_TEXT0(0,setup,dbf_text);
2929 QDIO_DBF_TEXT0(0,trace,dbf_text); 2932 QDIO_DBF_TEXT0(0,trace,dbf_text);
2930 2933
@@ -2945,7 +2948,7 @@ qdio_allocate(struct qdio_initialize *init_data)
2945 struct qdio_irq *irq_ptr; 2948 struct qdio_irq *irq_ptr;
2946 char dbf_text[15]; 2949 char dbf_text[15];
2947 2950
2948 sprintf(dbf_text,"qalc%4x",init_data->cdev->private->irq); 2951 sprintf(dbf_text,"qalc%4x",init_data->cdev->private->sch_no);
2949 QDIO_DBF_TEXT0(0,setup,dbf_text); 2952 QDIO_DBF_TEXT0(0,setup,dbf_text);
2950 QDIO_DBF_TEXT0(0,trace,dbf_text); 2953 QDIO_DBF_TEXT0(0,trace,dbf_text);
2951 if ( (init_data->no_input_qs>QDIO_MAX_QUEUES_PER_IRQ) || 2954 if ( (init_data->no_input_qs>QDIO_MAX_QUEUES_PER_IRQ) ||
@@ -3018,7 +3021,7 @@ int qdio_fill_irq(struct qdio_initialize *init_data)
3018 3021
3019 irq_ptr->int_parm=init_data->int_parm; 3022 irq_ptr->int_parm=init_data->int_parm;
3020 3023
3021 irq_ptr->irq = init_data->cdev->private->irq; 3024 irq_ptr->schid = ccw_device_get_subchannel_id(init_data->cdev);
3022 irq_ptr->no_input_qs=init_data->no_input_qs; 3025 irq_ptr->no_input_qs=init_data->no_input_qs;
3023 irq_ptr->no_output_qs=init_data->no_output_qs; 3026 irq_ptr->no_output_qs=init_data->no_output_qs;
3024 3027
@@ -3038,7 +3041,7 @@ int qdio_fill_irq(struct qdio_initialize *init_data)
3038 QDIO_DBF_HEX1(0,setup,&irq_ptr->dev_st_chg_ind,sizeof(void*)); 3041 QDIO_DBF_HEX1(0,setup,&irq_ptr->dev_st_chg_ind,sizeof(void*));
3039 if (!irq_ptr->dev_st_chg_ind) { 3042 if (!irq_ptr->dev_st_chg_ind) {
3040 QDIO_PRINT_WARN("no indicator location available " \ 3043 QDIO_PRINT_WARN("no indicator location available " \
3041 "for irq 0x%x\n",irq_ptr->irq); 3044 "for irq 0x%x\n",irq_ptr->schid.sch_no);
3042 qdio_release_irq_memory(irq_ptr); 3045 qdio_release_irq_memory(irq_ptr);
3043 return -ENOBUFS; 3046 return -ENOBUFS;
3044 } 3047 }
@@ -3169,7 +3172,7 @@ qdio_establish(struct qdio_initialize *init_data)
3169 tiqdio_set_delay_target(irq_ptr,TIQDIO_DELAY_TARGET); 3172 tiqdio_set_delay_target(irq_ptr,TIQDIO_DELAY_TARGET);
3170 } 3173 }
3171 3174
3172 sprintf(dbf_text,"qest%4x",cdev->private->irq); 3175 sprintf(dbf_text,"qest%4x",cdev->private->sch_no);
3173 QDIO_DBF_TEXT0(0,setup,dbf_text); 3176 QDIO_DBF_TEXT0(0,setup,dbf_text);
3174 QDIO_DBF_TEXT0(0,trace,dbf_text); 3177 QDIO_DBF_TEXT0(0,trace,dbf_text);
3175 3178
@@ -3197,7 +3200,7 @@ qdio_establish(struct qdio_initialize *init_data)
3197 } 3200 }
3198 QDIO_PRINT_WARN("establish queues on irq %04x: do_IO " \ 3201 QDIO_PRINT_WARN("establish queues on irq %04x: do_IO " \
3199 "returned %i, next try returned %i\n", 3202 "returned %i, next try returned %i\n",
3200 irq_ptr->irq,result,result2); 3203 irq_ptr->schid.sch_no,result,result2);
3201 result=result2; 3204 result=result2;
3202 if (result) 3205 if (result)
3203 ccw_device_set_timeout(cdev, 0); 3206 ccw_device_set_timeout(cdev, 0);
@@ -3270,7 +3273,7 @@ qdio_activate(struct ccw_device *cdev, int flags)
3270 goto out; 3273 goto out;
3271 } 3274 }
3272 3275
3273 sprintf(dbf_text,"qact%4x", irq_ptr->irq); 3276 sprintf(dbf_text,"qact%4x", irq_ptr->schid.sch_no);
3274 QDIO_DBF_TEXT2(0,setup,dbf_text); 3277 QDIO_DBF_TEXT2(0,setup,dbf_text);
3275 QDIO_DBF_TEXT2(0,trace,dbf_text); 3278 QDIO_DBF_TEXT2(0,trace,dbf_text);
3276 3279
@@ -3297,7 +3300,7 @@ qdio_activate(struct ccw_device *cdev, int flags)
3297 } 3300 }
3298 QDIO_PRINT_WARN("activate queues on irq %04x: do_IO " \ 3301 QDIO_PRINT_WARN("activate queues on irq %04x: do_IO " \
3299 "returned %i, next try returned %i\n", 3302 "returned %i, next try returned %i\n",
3300 irq_ptr->irq,result,result2); 3303 irq_ptr->schid.sch_no,result,result2);
3301 result=result2; 3304 result=result2;
3302 } 3305 }
3303 3306
@@ -3509,7 +3512,7 @@ do_QDIO(struct ccw_device *cdev,unsigned int callflags,
3509#ifdef CONFIG_QDIO_DEBUG 3512#ifdef CONFIG_QDIO_DEBUG
3510 char dbf_text[20]; 3513 char dbf_text[20];
3511 3514
3512 sprintf(dbf_text,"doQD%04x",cdev->private->irq); 3515 sprintf(dbf_text,"doQD%04x",cdev->private->sch_no);
3513 QDIO_DBF_TEXT3(0,trace,dbf_text); 3516 QDIO_DBF_TEXT3(0,trace,dbf_text);
3514#endif /* CONFIG_QDIO_DEBUG */ 3517#endif /* CONFIG_QDIO_DEBUG */
3515 3518
diff --git a/drivers/s390/cio/qdio.h b/drivers/s390/cio/qdio.h
index b5d303e79a24..43b840af5300 100644
--- a/drivers/s390/cio/qdio.h
+++ b/drivers/s390/cio/qdio.h
@@ -3,7 +3,9 @@
3 3
4#include <asm/page.h> 4#include <asm/page.h>
5 5
6#define VERSION_CIO_QDIO_H "$Revision: 1.37 $" 6#include "schid.h"
7
8#define VERSION_CIO_QDIO_H "$Revision: 1.40 $"
7 9
8#ifdef CONFIG_QDIO_DEBUG 10#ifdef CONFIG_QDIO_DEBUG
9#define QDIO_VERBOSE_LEVEL 9 11#define QDIO_VERBOSE_LEVEL 9
@@ -317,7 +319,7 @@ do_eqbs(unsigned long sch, unsigned char *state, int queue,
317 319
318 320
319static inline int 321static inline int
320do_siga_sync(unsigned int irq, unsigned int mask1, unsigned int mask2) 322do_siga_sync(struct subchannel_id schid, unsigned int mask1, unsigned int mask2)
321{ 323{
322 int cc; 324 int cc;
323 325
@@ -331,7 +333,7 @@ do_siga_sync(unsigned int irq, unsigned int mask1, unsigned int mask2)
331 "ipm %0 \n\t" 333 "ipm %0 \n\t"
332 "srl %0,28 \n\t" 334 "srl %0,28 \n\t"
333 : "=d" (cc) 335 : "=d" (cc)
334 : "d" (irq), "d" (mask1), "d" (mask2) 336 : "d" (schid), "d" (mask1), "d" (mask2)
335 : "cc", "0", "1", "2", "3" 337 : "cc", "0", "1", "2", "3"
336 ); 338 );
337#else /* CONFIG_ARCH_S390X */ 339#else /* CONFIG_ARCH_S390X */
@@ -344,7 +346,7 @@ do_siga_sync(unsigned int irq, unsigned int mask1, unsigned int mask2)
344 "ipm %0 \n\t" 346 "ipm %0 \n\t"
345 "srl %0,28 \n\t" 347 "srl %0,28 \n\t"
346 : "=d" (cc) 348 : "=d" (cc)
347 : "d" (irq), "d" (mask1), "d" (mask2) 349 : "d" (schid), "d" (mask1), "d" (mask2)
348 : "cc", "0", "1", "2", "3" 350 : "cc", "0", "1", "2", "3"
349 ); 351 );
350#endif /* CONFIG_ARCH_S390X */ 352#endif /* CONFIG_ARCH_S390X */
@@ -352,7 +354,7 @@ do_siga_sync(unsigned int irq, unsigned int mask1, unsigned int mask2)
352} 354}
353 355
354static inline int 356static inline int
355do_siga_input(unsigned int irq, unsigned int mask) 357do_siga_input(struct subchannel_id schid, unsigned int mask)
356{ 358{
357 int cc; 359 int cc;
358 360
@@ -365,7 +367,7 @@ do_siga_input(unsigned int irq, unsigned int mask)
365 "ipm %0 \n\t" 367 "ipm %0 \n\t"
366 "srl %0,28 \n\t" 368 "srl %0,28 \n\t"
367 : "=d" (cc) 369 : "=d" (cc)
368 : "d" (irq), "d" (mask) 370 : "d" (schid), "d" (mask)
369 : "cc", "0", "1", "2", "memory" 371 : "cc", "0", "1", "2", "memory"
370 ); 372 );
371#else /* CONFIG_ARCH_S390X */ 373#else /* CONFIG_ARCH_S390X */
@@ -377,7 +379,7 @@ do_siga_input(unsigned int irq, unsigned int mask)
377 "ipm %0 \n\t" 379 "ipm %0 \n\t"
378 "srl %0,28 \n\t" 380 "srl %0,28 \n\t"
379 : "=d" (cc) 381 : "=d" (cc)
380 : "d" (irq), "d" (mask) 382 : "d" (schid), "d" (mask)
381 : "cc", "0", "1", "2", "memory" 383 : "cc", "0", "1", "2", "memory"
382 ); 384 );
383#endif /* CONFIG_ARCH_S390X */ 385#endif /* CONFIG_ARCH_S390X */
@@ -386,7 +388,7 @@ do_siga_input(unsigned int irq, unsigned int mask)
386} 388}
387 389
388static inline int 390static inline int
389do_siga_output(unsigned long irq, unsigned long mask, __u32 *bb, 391do_siga_output(unsigned long schid, unsigned long mask, __u32 *bb,
390 unsigned int fc) 392 unsigned int fc)
391{ 393{
392 int cc; 394 int cc;
@@ -418,7 +420,7 @@ do_siga_output(unsigned long irq, unsigned long mask, __u32 *bb,
418 ".long 0b,2b \n\t" 420 ".long 0b,2b \n\t"
419 ".previous \n\t" 421 ".previous \n\t"
420 : "=d" (cc), "=d" (busy_bit) 422 : "=d" (cc), "=d" (busy_bit)
421 : "d" (irq), "d" (mask), 423 : "d" (schid), "d" (mask),
422 "i" (QDIO_SIGA_ERROR_ACCESS_EXCEPTION) 424 "i" (QDIO_SIGA_ERROR_ACCESS_EXCEPTION)
423 : "cc", "0", "1", "2", "memory" 425 : "cc", "0", "1", "2", "memory"
424 ); 426 );
@@ -443,7 +445,7 @@ do_siga_output(unsigned long irq, unsigned long mask, __u32 *bb,
443 ".quad 0b,1b \n\t" 445 ".quad 0b,1b \n\t"
444 ".previous \n\t" 446 ".previous \n\t"
445 : "=d" (cc), "=d" (busy_bit) 447 : "=d" (cc), "=d" (busy_bit)
446 : "d" (irq), "d" (mask), 448 : "d" (schid), "d" (mask),
447 "i" (QDIO_SIGA_ERROR_ACCESS_EXCEPTION), "d" (fc) 449 "i" (QDIO_SIGA_ERROR_ACCESS_EXCEPTION), "d" (fc)
448 : "cc", "0", "1", "2", "memory" 450 : "cc", "0", "1", "2", "memory"
449 ); 451 );
@@ -554,7 +556,7 @@ struct qdio_q {
554 __u32 * dev_st_chg_ind; 556 __u32 * dev_st_chg_ind;
555 557
556 int is_input_q; 558 int is_input_q;
557 int irq; 559 struct subchannel_id schid;
558 struct ccw_device *cdev; 560 struct ccw_device *cdev;
559 561
560 unsigned int is_iqdio_q; 562 unsigned int is_iqdio_q;
@@ -649,7 +651,7 @@ struct qdio_irq {
649 __u32 * volatile dev_st_chg_ind; 651 __u32 * volatile dev_st_chg_ind;
650 652
651 unsigned long int_parm; 653 unsigned long int_parm;
652 int irq; 654 struct subchannel_id schid;
653 655
654 unsigned int is_iqdio_irq; 656 unsigned int is_iqdio_irq;
655 unsigned int is_thinint_irq; 657 unsigned int is_thinint_irq;
diff --git a/drivers/s390/cio/schid.h b/drivers/s390/cio/schid.h
new file mode 100644
index 000000000000..220d97882341
--- /dev/null
+++ b/drivers/s390/cio/schid.h
@@ -0,0 +1,25 @@
1#ifndef S390_SCHID_H
2#define S390_SCHID_H
3
4struct subchannel_id {
5 __u32 reserved:15;
6 __u32 one:1;
7 __u32 sch_no:16;
8} __attribute__ ((packed,aligned(4)));
9
10
11/* Helper function for sane state of pre-allocated subchannel_id. */
12static inline void
13init_subchannel_id(struct subchannel_id *schid)
14{
15 memset(schid, 0, sizeof(struct subchannel_id));
16 schid->one = 1;
17}
18
19static inline int
20schid_equal(struct subchannel_id *schid1, struct subchannel_id *schid2)
21{
22 return !memcmp(schid1, schid2, sizeof(struct subchannel_id));
23}
24
25#endif /* S390_SCHID_H */