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 */ | ||
