diff options
-rw-r--r-- | drivers/s390/cio/blacklist.c | 23 | ||||
-rw-r--r-- | drivers/s390/cio/chsc.c | 63 | ||||
-rw-r--r-- | drivers/s390/cio/cio.c | 84 | ||||
-rw-r--r-- | drivers/s390/cio/cio.h | 11 | ||||
-rw-r--r-- | drivers/s390/cio/cmf.c | 8 | ||||
-rw-r--r-- | drivers/s390/cio/css.c | 69 | ||||
-rw-r--r-- | drivers/s390/cio/css.h | 13 | ||||
-rw-r--r-- | drivers/s390/cio/device.c | 17 | ||||
-rw-r--r-- | drivers/s390/cio/device.h | 1 | ||||
-rw-r--r-- | drivers/s390/cio/device_fsm.c | 18 | ||||
-rw-r--r-- | drivers/s390/cio/device_id.c | 6 | ||||
-rw-r--r-- | drivers/s390/cio/device_ops.c | 4 | ||||
-rw-r--r-- | drivers/s390/cio/device_pgid.c | 13 | ||||
-rw-r--r-- | drivers/s390/cio/device_status.c | 8 | ||||
-rw-r--r-- | drivers/s390/cio/ioasm.h | 55 | ||||
-rw-r--r-- | drivers/s390/cio/qdio.c | 107 | ||||
-rw-r--r-- | drivers/s390/cio/qdio.h | 26 | ||||
-rw-r--r-- | drivers/s390/cio/schid.h | 25 |
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))) |
40 | static unsigned long bl_dev[__BL_DEV_WORDS]; | 40 | static unsigned long bl_dev[__BL_DEV_WORDS]; |
41 | typedef enum {add, free} range_action; | 41 | typedef 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) | |||
226 | static inline void | 226 | static inline void |
227 | s390_redo_validation (void) | 227 | s390_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: | |||
284 | out_unreg: | 285 | out_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 | |||
348 | s390_process_res_acc (u8 chpid, __u16 fla, u32 fla_mask) | 349 | s390_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 | |||
608 | chp_add(int chpid) | 611 | chp_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 | |||
789 | s390_vary_chpid( __u8 chpid, int on) | 794 | s390_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); |
841 | out: | 848 | out: |
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 | */ |
510 | int | 510 | int |
511 | cio_validate_subchannel (struct subchannel *sch, unsigned int irq) | 511 | cio_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) | |||
693 | static int | 693 | static int |
694 | cio_console_irq(void) | 694 | cio_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 * | |||
729 | cio_probe_console(void) | 731 | cio_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. */ |
772 | int | 777 | int |
773 | cio_is_console(int irq) | 778 | cio_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 | ||
780 | struct subchannel * | 785 | struct subchannel * |
@@ -787,7 +792,7 @@ cio_get_console_subchannel(void) | |||
787 | 792 | ||
788 | #endif | 793 | #endif |
789 | static inline int | 794 | static 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 | ||
807 | static inline int | 812 | static 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); | |||
830 | void | 835 | void |
831 | clear_all_subchannels(void) | 836 | clear_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 */ |
85 | struct subchannel { | 87 | struct 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 | ||
117 | extern int cio_validate_subchannel (struct subchannel *, unsigned int); | 119 | extern int cio_validate_subchannel (struct subchannel *, struct subchannel_id); |
118 | extern int cio_enable_subchannel (struct subchannel *, unsigned int); | 120 | extern int cio_enable_subchannel (struct subchannel *, unsigned int); |
119 | extern int cio_disable_subchannel (struct subchannel *); | 121 | extern int cio_disable_subchannel (struct subchannel *); |
120 | extern int cio_cancel (struct subchannel *); | 122 | extern int cio_cancel (struct subchannel *); |
@@ -127,14 +129,15 @@ extern int cio_cancel (struct subchannel *); | |||
127 | extern int cio_set_options (struct subchannel *, int); | 129 | extern int cio_set_options (struct subchannel *, int); |
128 | extern int cio_get_options (struct subchannel *); | 130 | extern int cio_get_options (struct subchannel *); |
129 | extern int cio_modify (struct subchannel *); | 131 | extern int cio_modify (struct subchannel *); |
132 | |||
130 | /* Use with care. */ | 133 | /* Use with care. */ |
131 | #ifdef CONFIG_CCW_CONSOLE | 134 | #ifdef CONFIG_CCW_CONSOLE |
132 | extern struct subchannel *cio_probe_console(void); | 135 | extern struct subchannel *cio_probe_console(void); |
133 | extern void cio_release_console(void); | 136 | extern void cio_release_console(void); |
134 | extern int cio_is_console(int irq); | 137 | extern int cio_is_console(struct subchannel_id); |
135 | extern struct subchannel *cio_get_console_subchannel(void); | 138 | extern 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 | ||
35 | static struct subchannel * | 35 | static struct subchannel * |
36 | css_alloc_subchannel(int irq) | 36 | css_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 | ||
116 | int | 114 | int |
117 | css_probe_device(int irq) | 115 | css_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 | |||
132 | check_subchannel(struct device * dev, void * data) | 130 | check_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 | ||
141 | struct subchannel * | 139 | struct subchannel * |
142 | get_subchannel_by_schid(int irq) | 140 | get_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 | ||
153 | static inline int | 151 | static inline int |
154 | css_get_subchannel_status(struct subchannel *sch, int schid) | 152 | css_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 | ||
172 | static int | 170 | static int |
173 | css_evaluate_subchannel(int irq, int slow) | 171 | css_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) | |||
284 | static void | 283 | static void |
285 | css_rescan_devices(void) | 284 | css_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 | ||
303 | struct slow_subchannel { | 304 | struct 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 | ||
308 | static LIST_HEAD(slow_subchannels_head); | 309 | static LIST_HEAD(slow_subchannels_head); |
@@ -357,20 +358,24 @@ int | |||
357 | css_process_crw(int irq) | 358 | css_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) | |||
404 | static int __init | 409 | static int __init |
405 | init_channel_subsystem (void) | 410 | init_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 | ||
454 | out_bus: | 461 | out_bus: |
@@ -482,7 +489,7 @@ struct bus_type css_bus_type = { | |||
482 | subsys_initcall(init_channel_subsystem); | 489 | subsys_initcall(init_channel_subsystem); |
483 | 490 | ||
484 | int | 491 | int |
485 | css_enqueue_subchannel_slow(unsigned long schid) | 492 | css_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 { | |||
121 | extern struct bus_type css_bus_type; | 123 | extern struct bus_type css_bus_type; |
122 | extern struct css_driver io_subchannel_driver; | 124 | extern struct css_driver io_subchannel_driver; |
123 | 125 | ||
124 | int css_probe_device(int irq); | 126 | extern int css_probe_device(struct subchannel_id); |
125 | extern struct subchannel * get_subchannel_by_schid(int irq); | 127 | extern struct subchannel * get_subchannel_by_schid(struct subchannel_id); |
126 | extern unsigned int highest_subchannel; | ||
127 | extern int css_init_done; | 128 | extern int css_init_done; |
128 | 129 | ||
129 | #define __MAX_SUBCHANNELS 65536 | 130 | #define __MAX_SUBCHANNEL 65535 |
130 | 131 | ||
131 | extern struct bus_type css_bus_type; | 132 | extern struct bus_type css_bus_type; |
132 | extern struct device css_bus_device; | 133 | extern struct device css_bus_device; |
@@ -144,7 +145,7 @@ void device_set_waiting(struct subchannel *); | |||
144 | void device_kill_pending_timer(struct subchannel *); | 145 | void 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. */ |
147 | int css_enqueue_subchannel_slow(unsigned long schid); | 148 | extern int css_enqueue_subchannel_slow(struct subchannel_id schid); |
148 | void css_walk_subchannel_slow_list(void (*fn)(unsigned long)); | 149 | void css_walk_subchannel_slow_list(void (*fn)(unsigned long)); |
149 | void css_clear_subchannel_slow_list(void); | 150 | void css_clear_subchannel_slow_list(void); |
150 | int css_slow_subchannels_exist(void); | 151 | int 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. */ | ||
1150 | struct subchannel_id | ||
1151 | ccw_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 | |||
1149 | MODULE_LICENSE("GPL"); | 1159 | MODULE_LICENSE("GPL"); |
1150 | EXPORT_SYMBOL(ccw_device_set_online); | 1160 | EXPORT_SYMBOL(ccw_device_set_online); |
1151 | EXPORT_SYMBOL(ccw_device_set_offline); | 1161 | EXPORT_SYMBOL(ccw_device_set_offline); |
@@ -1155,3 +1165,4 @@ EXPORT_SYMBOL(get_ccwdev_by_busid); | |||
1155 | EXPORT_SYMBOL(ccw_bus_type); | 1165 | EXPORT_SYMBOL(ccw_bus_type); |
1156 | EXPORT_SYMBOL(ccw_device_work); | 1166 | EXPORT_SYMBOL(ccw_device_work); |
1157 | EXPORT_SYMBOL(ccw_device_notify_work); | 1167 | EXPORT_SYMBOL(ccw_device_notify_work); |
1168 | EXPORT_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. */ |
112 | void ccw_device_set_timeout(struct ccw_device *, int); | 112 | void ccw_device_set_timeout(struct ccw_device *, int); |
113 | extern struct subchannel_id ccw_device_get_subchannel_id(struct ccw_device *); | ||
113 | 114 | ||
114 | void retry_set_schib(struct ccw_device *cdev); | 115 | void 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) | |||
570 | int | 570 | int |
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 | ||
576 | int | 576 | int |
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 | */ |
7 | struct tpi_info { | 9 | struct 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 | ||
24 | static inline int stsch(int irq, volatile struct schib *addr) | 25 | static 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 | ||
39 | static inline int msch(int irq, volatile struct schib *addr) | 41 | static 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 | ||
54 | static inline int msch_err(int irq, volatile struct schib *addr) | 57 | static 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 | ||
82 | static inline int tsch(int irq, volatile struct irb *addr) | 86 | static 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 | ||
111 | static inline int ssch(int irq, volatile struct orb *addr) | 116 | static 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 | ||
126 | static inline int rsch(int irq) | 132 | static 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 | ||
141 | static inline int csch(int irq) | 147 | static 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 | ||
156 | static inline int hsch(int irq) | 162 | static 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 | ||
171 | static inline int xsch(int irq) | 177 | static 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 | ||
186 | static inline int chsc(void *chsc_area) | 192 | static 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 | ||
1948 | static inline void | 1952 | static inline void |
1949 | qdio_irq_check_sense(int irq, struct irb *irb) | 1953 | qdio_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 | ||
319 | static inline int | 321 | static inline int |
320 | do_siga_sync(unsigned int irq, unsigned int mask1, unsigned int mask2) | 322 | do_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 | ||
354 | static inline int | 356 | static inline int |
355 | do_siga_input(unsigned int irq, unsigned int mask) | 357 | do_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 | ||
388 | static inline int | 390 | static inline int |
389 | do_siga_output(unsigned long irq, unsigned long mask, __u32 *bb, | 391 | do_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 | |||
4 | struct 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. */ | ||
12 | static inline void | ||
13 | init_subchannel_id(struct subchannel_id *schid) | ||
14 | { | ||
15 | memset(schid, 0, sizeof(struct subchannel_id)); | ||
16 | schid->one = 1; | ||
17 | } | ||
18 | |||
19 | static inline int | ||
20 | schid_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 */ | ||