aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/s390/cio
diff options
context:
space:
mode:
authorCornelia Huck <cohuck@de.ibm.com>2006-01-06 03:19:21 -0500
committerLinus Torvalds <torvalds@g5.osdl.org>2006-01-06 11:33:51 -0500
commita8237fc4108060402d904bea5e1062e22e731969 (patch)
treefc19e33ea8bbe664c33fba6c78b34e497f2cc478 /drivers/s390/cio
parent8129ee164267dc030b8e1d541ee3643c0b9f2fa1 (diff)
[PATCH] s390: introduce struct subchannel_id
This patch introduces a struct subchannel_id containing the subchannel number (formerly referred to as "irq") and switches code formerly relying on the subchannel number over to it. While we're touching inline assemblies anyway, make sure they have correct memory constraints. Signed-off-by: Cornelia Huck <cohuck@de.ibm.com> Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com> Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'drivers/s390/cio')
-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 */