1 /* 2 * drivers/s390/cio/chsc.c 3 * S/390 common I/O routines -- channel subsystem call 4 * 5 * Copyright IBM Corp. 1999,2010 6 * Author(s): Ingo Adlung (adlung@de.ibm.com) 7 * Cornelia Huck (cornelia.huck@de.ibm.com) 8 * Arnd Bergmann (arndb@de.ibm.com) 9 */ 10 11 #define KMSG_COMPONENT "cio" 12 #define pr_fmt(fmt) KMSG_COMPONENT ": " fmt 13 14 #include <linux/module.h> 15 #include <linux/slab.h> 16 #include <linux/init.h> 17 #include <linux/device.h> 18 19 #include <asm/cio.h> 20 #include <asm/chpid.h> 21 #include <asm/chsc.h> 22 #include <asm/crw.h> 23 24 #include "css.h" 25 #include "cio.h" 26 #include "cio_debug.h" 27 #include "ioasm.h" 28 #include "chp.h" 29 #include "chsc.h" 30 31 static void *sei_page; 32 static void *chsc_page; 33 static DEFINE_SPINLOCK(chsc_page_lock); 34 35 /** 36 * chsc_error_from_response() - convert a chsc response to an error 37 * @response: chsc response code 38 * 39 * Returns an appropriate Linux error code for @response. 40 */ 41 int chsc_error_from_response(int response) 42 { 43 switch (response) { 44 case 0x0001: 45 return 0; 46 case 0x0002: 47 case 0x0003: 48 case 0x0006: 49 case 0x0007: 50 case 0x0008: 51 case 0x000a: 52 case 0x0104: 53 return -EINVAL; 54 case 0x0004: 55 return -EOPNOTSUPP; 56 default: 57 return -EIO; 58 } 59 } 60 EXPORT_SYMBOL_GPL(chsc_error_from_response); 61 62 struct chsc_ssd_area { 63 struct chsc_header request; 64 u16 :10; 65 u16 ssid:2; 66 u16 :4; 67 u16 f_sch; /* first subchannel */ 68 u16 :16; 69 u16 l_sch; /* last subchannel */ 70 u32 :32; 71 struct chsc_header response; 72 u32 :32; 73 u8 sch_valid : 1; 74 u8 dev_valid : 1; 75 u8 st : 3; /* subchannel type */ 76 u8 zeroes : 3; 77 u8 unit_addr; /* unit address */ 78 u16 devno; /* device number */ 79 u8 path_mask; 80 u8 fla_valid_mask; 81 u16 sch; /* subchannel */ 82 u8 chpid[8]; /* chpids 0-7 */ 83 u16 fla[8]; /* full link addresses 0-7 */ 84 } __attribute__ ((packed)); 85 86 int chsc_get_ssd_info(struct subchannel_id schid, struct chsc_ssd_info *ssd) 87 { 88 struct chsc_ssd_area *ssd_area; 89 int ccode; 90 int ret; 91 int i; 92 int mask; 93 94 spin_lock_irq(&chsc_page_lock); 95 memset(chsc_page, 0, PAGE_SIZE); 96 ssd_area = chsc_page; 97 ssd_area->request.length = 0x0010; 98 ssd_area->request.code = 0x0004; 99 ssd_area->ssid = schid.ssid; 100 ssd_area->f_sch = schid.sch_no; 101 ssd_area->l_sch = schid.sch_no; 102 103 ccode = chsc(ssd_area); 104 /* Check response. */ 105 if (ccode > 0) { 106 ret = (ccode == 3) ? -ENODEV : -EBUSY; 107 goto out; 108 } 109 ret = chsc_error_from_response(ssd_area->response.code); 110 if (ret != 0) { 111 CIO_MSG_EVENT(2, "chsc: ssd failed for 0.%x.%04x (rc=%04x)\n", 112 schid.ssid, schid.sch_no, 113 ssd_area->response.code); 114 goto out; 115 } 116 if (!ssd_area->sch_valid) { 117 ret = -ENODEV; 118 goto out; 119 } 120 /* Copy data */ 121 ret = 0; 122 memset(ssd, 0, sizeof(struct chsc_ssd_info)); 123 if ((ssd_area->st != SUBCHANNEL_TYPE_IO) && 124 (ssd_area->st != SUBCHANNEL_TYPE_MSG)) 125 goto out; 126 ssd->path_mask = ssd_area->path_mask; 127 ssd->fla_valid_mask = ssd_area->fla_valid_mask; 128 for (i = 0; i < 8; i++) { 129 mask = 0x80 >> i; 130 if (ssd_area->path_mask & mask) { 131 chp_id_init(&ssd->chpid[i]); 132 ssd->chpid[i].id = ssd_area->chpid[i]; 133 } 134 if (ssd_area->fla_valid_mask & mask) 135 ssd->fla[i] = ssd_area->fla[i]; 136 } 137 out: 138 spin_unlock_irq(&chsc_page_lock); 139 return ret; 140 } 141 142 static int s390_subchannel_remove_chpid(struct subchannel *sch, void *data) 143 { 144 spin_lock_irq(sch->lock); 145 if (sch->driver && sch->driver->chp_event) 146 if (sch->driver->chp_event(sch, data, CHP_OFFLINE) != 0) 147 goto out_unreg; 148 spin_unlock_irq(sch->lock); 149 return 0; 150 151 out_unreg: 152 sch->lpm = 0; 153 spin_unlock_irq(sch->lock); 154 css_schedule_eval(sch->schid); 155 return 0; 156 } 157 158 void chsc_chp_offline(struct chp_id chpid) 159 { 160 char dbf_txt[15]; 161 struct chp_link link; 162 163 sprintf(dbf_txt, "chpr%x.%02x", chpid.cssid, chpid.id); 164 CIO_TRACE_EVENT(2, dbf_txt); 165 166 if (chp_get_status(chpid) <= 0) 167 return; 168 memset(&link, 0, sizeof(struct chp_link)); 169 link.chpid = chpid; 170 /* Wait until previous actions have settled. */ 171 css_wait_for_slow_path(); 172 for_each_subchannel_staged(s390_subchannel_remove_chpid, NULL, &link); 173 } 174 175 static int s390_process_res_acc_new_sch(struct subchannel_id schid, void *data) 176 { 177 struct schib schib; 178 /* 179 * We don't know the device yet, but since a path 180 * may be available now to the device we'll have 181 * to do recognition again. 182 * Since we don't have any idea about which chpid 183 * that beast may be on we'll have to do a stsch 184 * on all devices, grr... 185 */ 186 if (stsch_err(schid, &schib)) 187 /* We're through */ 188 return -ENXIO; 189 190 /* Put it on the slow path. */ 191 css_schedule_eval(schid); 192 return 0; 193 } 194 195 static int __s390_process_res_acc(struct subchannel *sch, void *data) 196 { 197 spin_lock_irq(sch->lock); 198 if (sch->driver && sch->driver->chp_event) 199 sch->driver->chp_event(sch, data, CHP_ONLINE); 200 spin_unlock_irq(sch->lock); 201 202 return 0; 203 } 204 205 static void s390_process_res_acc(struct chp_link *link) 206 { 207 char dbf_txt[15]; 208 209 sprintf(dbf_txt, "accpr%x.%02x", link->chpid.cssid, 210 link->chpid.id); 211 CIO_TRACE_EVENT( 2, dbf_txt); 212 if (link->fla != 0) { 213 sprintf(dbf_txt, "fla%x", link->fla); 214 CIO_TRACE_EVENT( 2, dbf_txt); 215 } 216 /* Wait until previous actions have settled. */ 217 css_wait_for_slow_path(); 218 /* 219 * I/O resources may have become accessible. 220 * Scan through all subchannels that may be concerned and 221 * do a validation on those. 222 * The more information we have (info), the less scanning 223 * will we have to do. 224 */ 225 for_each_subchannel_staged(__s390_process_res_acc, 226 s390_process_res_acc_new_sch, link); 227 } 228 229 static int 230 __get_chpid_from_lir(void *data) 231 { 232 struct lir { 233 u8 iq; 234 u8 ic; 235 u16 sci; 236 /* incident-node descriptor */ 237 u32 indesc[28]; 238 /* attached-node descriptor */ 239 u32 andesc[28]; 240 /* incident-specific information */ 241 u32 isinfo[28]; 242 } __attribute__ ((packed)) *lir; 243 244 lir = data; 245 if (!(lir->iq&0x80)) 246 /* NULL link incident record */ 247 return -EINVAL; 248 if (!(lir->indesc[0]&0xc0000000)) 249 /* node descriptor not valid */ 250 return -EINVAL; 251 if (!(lir->indesc[0]&0x10000000)) 252 /* don't handle device-type nodes - FIXME */ 253 return -EINVAL; 254 /* Byte 3 contains the chpid. Could also be CTCA, but we don't care */ 255 256 return (u16) (lir->indesc[0]&0x000000ff); 257 } 258 259 struct chsc_sei_area { 260 struct chsc_header request; 261 u32 reserved1; 262 u32 reserved2; 263 u32 reserved3; 264 struct chsc_header response; 265 u32 reserved4; 266 u8 flags; 267 u8 vf; /* validity flags */ 268 u8 rs; /* reporting source */ 269 u8 cc; /* content code */ 270 u16 fla; /* full link address */ 271 u16 rsid; /* reporting source id */ 272 u32 reserved5; 273 u32 reserved6; 274 u8 ccdf[4096 - 16 - 24]; /* content-code dependent field */ 275 /* ccdf has to be big enough for a link-incident record */ 276 } __attribute__ ((packed)); 277 278 static void chsc_process_sei_link_incident(struct chsc_sei_area *sei_area) 279 { 280 struct chp_id chpid; 281 int id; 282 283 CIO_CRW_EVENT(4, "chsc: link incident (rs=%02x, rs_id=%04x)\n", 284 sei_area->rs, sei_area->rsid); 285 if (sei_area->rs != 4) 286 return; 287 id = __get_chpid_from_lir(sei_area->ccdf); 288 if (id < 0) 289 CIO_CRW_EVENT(4, "chsc: link incident - invalid LIR\n"); 290 else { 291 chp_id_init(&chpid); 292 chpid.id = id; 293 chsc_chp_offline(chpid); 294 } 295 } 296 297 static void chsc_process_sei_res_acc(struct chsc_sei_area *sei_area) 298 { 299 struct chp_link link; 300 struct chp_id chpid; 301 int status; 302 303 CIO_CRW_EVENT(4, "chsc: resource accessibility event (rs=%02x, " 304 "rs_id=%04x)\n", sei_area->rs, sei_area->rsid); 305 if (sei_area->rs != 4) 306 return; 307 chp_id_init(&chpid); 308 chpid.id = sei_area->rsid; 309 /* allocate a new channel path structure, if needed */ 310 status = chp_get_status(chpid); 311 if (status < 0) 312 chp_new(chpid); 313 else if (!status) 314 return; 315 memset(&link, 0, sizeof(struct chp_link)); 316 link.chpid = chpid; 317 if ((sei_area->vf & 0xc0) != 0) { 318 link.fla = sei_area->fla; 319 if ((sei_area->vf & 0xc0) == 0xc0) 320 /* full link address */ 321 link.fla_mask = 0xffff; 322 else 323 /* link address */ 324 link.fla_mask = 0xff00; 325 } 326 s390_process_res_acc(&link); 327 } 328 329 static void chsc_process_sei_chp_avail(struct chsc_sei_area *sei_area) 330 { 331 struct channel_path *chp; 332 struct chp_id chpid; 333 u8 *data; 334 int num; 335 336 CIO_CRW_EVENT(4, "chsc: channel path availability information\n"); 337 if (sei_area->rs != 0) 338 return; 339 data = sei_area->ccdf; 340 chp_id_init(&chpid); 341 for (num = 0; num <= __MAX_CHPID; num++) { 342 if (!chp_test_bit(data, num)) 343 continue; 344 chpid.id = num; 345 346 CIO_CRW_EVENT(4, "Update information for channel path " 347 "%x.%02x\n", chpid.cssid, chpid.id); 348 chp = chpid_to_chp(chpid); 349 if (!chp) { 350 chp_new(chpid); 351 continue; 352 } 353 mutex_lock(&chp->lock); 354 chsc_determine_base_channel_path_desc(chpid, &chp->desc); 355 mutex_unlock(&chp->lock); 356 } 357 } 358 359 struct chp_config_data { 360 u8 map[32]; 361 u8 op; 362 u8 pc; 363 }; 364 365 static void chsc_process_sei_chp_config(struct chsc_sei_area *sei_area) 366 { 367 struct chp_config_data *data; 368 struct chp_id chpid; 369 int num; 370 char *events[3] = {"configure", "deconfigure", "cancel deconfigure"}; 371 372 CIO_CRW_EVENT(4, "chsc: channel-path-configuration notification\n"); 373 if (sei_area->rs != 0) 374 return; 375 data = (struct chp_config_data *) &(sei_area->ccdf); 376 chp_id_init(&chpid); 377 for (num = 0; num <= __MAX_CHPID; num++) { 378 if (!chp_test_bit(data->map, num)) 379 continue; 380 chpid.id = num; 381 pr_notice("Processing %s for channel path %x.%02x\n", 382 events[data->op], chpid.cssid, chpid.id); 383 switch (data->op) { 384 case 0: 385 chp_cfg_schedule(chpid, 1); 386 break; 387 case 1: 388 chp_cfg_schedule(chpid, 0); 389 break; 390 case 2: 391 chp_cfg_cancel_deconfigure(chpid); 392 break; 393 } 394 } 395 } 396 397 static void chsc_process_sei(struct chsc_sei_area *sei_area) 398 { 399 /* Check if we might have lost some information. */ 400 if (sei_area->flags & 0x40) { 401 CIO_CRW_EVENT(2, "chsc: event overflow\n"); 402 css_schedule_eval_all(); 403 } 404 /* which kind of information was stored? */ 405 switch (sei_area->cc) { 406 case 1: /* link incident*/ 407 chsc_process_sei_link_incident(sei_area); 408 break; 409 case 2: /* i/o resource accessibility */ 410 chsc_process_sei_res_acc(sei_area); 411 break; 412 case 7: /* channel-path-availability information */ 413 chsc_process_sei_chp_avail(sei_area); 414 break; 415 case 8: /* channel-path-configuration notification */ 416 chsc_process_sei_chp_config(sei_area); 417 break; 418 default: /* other stuff */ 419 CIO_CRW_EVENT(4, "chsc: unhandled sei content code %d\n", 420 sei_area->cc); 421 break; 422 } 423 } 424 425 static void chsc_process_crw(struct crw *crw0, struct crw *crw1, int overflow) 426 { 427 struct chsc_sei_area *sei_area; 428 429 if (overflow) { 430 css_schedule_eval_all(); 431 return; 432 } 433 CIO_CRW_EVENT(2, "CRW reports slct=%d, oflw=%d, " 434 "chn=%d, rsc=%X, anc=%d, erc=%X, rsid=%X\n", 435 crw0->slct, crw0->oflw, crw0->chn, crw0->rsc, crw0->anc, 436 crw0->erc, crw0->rsid); 437 if (!sei_page) 438 return; 439 /* Access to sei_page is serialized through machine check handler 440 * thread, so no need for locking. */ 441 sei_area = sei_page; 442 443 CIO_TRACE_EVENT(2, "prcss"); 444 do { 445 memset(sei_area, 0, sizeof(*sei_area)); 446 sei_area->request.length = 0x0010; 447 sei_area->request.code = 0x000e; 448 if (chsc(sei_area)) 449 break; 450 451 if (sei_area->response.code == 0x0001) { 452 CIO_CRW_EVENT(4, "chsc: sei successful\n"); 453 chsc_process_sei(sei_area); 454 } else { 455 CIO_CRW_EVENT(2, "chsc: sei failed (rc=%04x)\n", 456 sei_area->response.code); 457 break; 458 } 459 } while (sei_area->flags & 0x80); 460 } 461 462 void chsc_chp_online(struct chp_id chpid) 463 { 464 char dbf_txt[15]; 465 struct chp_link link; 466 467 sprintf(dbf_txt, "cadd%x.%02x", chpid.cssid, chpid.id); 468 CIO_TRACE_EVENT(2, dbf_txt); 469 470 if (chp_get_status(chpid) != 0) { 471 memset(&link, 0, sizeof(struct chp_link)); 472 link.chpid = chpid; 473 /* Wait until previous actions have settled. */ 474 css_wait_for_slow_path(); 475 for_each_subchannel_staged(__s390_process_res_acc, NULL, 476 &link); 477 } 478 } 479 480 static void __s390_subchannel_vary_chpid(struct subchannel *sch, 481 struct chp_id chpid, int on) 482 { 483 unsigned long flags; 484 struct chp_link link; 485 486 memset(&link, 0, sizeof(struct chp_link)); 487 link.chpid = chpid; 488 spin_lock_irqsave(sch->lock, flags); 489 if (sch->driver && sch->driver->chp_event) 490 sch->driver->chp_event(sch, &link, 491 on ? CHP_VARY_ON : CHP_VARY_OFF); 492 spin_unlock_irqrestore(sch->lock, flags); 493 } 494 495 static int s390_subchannel_vary_chpid_off(struct subchannel *sch, void *data) 496 { 497 struct chp_id *chpid = data; 498 499 __s390_subchannel_vary_chpid(sch, *chpid, 0); 500 return 0; 501 } 502 503 static int s390_subchannel_vary_chpid_on(struct subchannel *sch, void *data) 504 { 505 struct chp_id *chpid = data; 506 507 __s390_subchannel_vary_chpid(sch, *chpid, 1); 508 return 0; 509 } 510 511 static int 512 __s390_vary_chpid_on(struct subchannel_id schid, void *data) 513 { 514 struct schib schib; 515 516 if (stsch_err(schid, &schib)) 517 /* We're through */ 518 return -ENXIO; 519 /* Put it on the slow path. */ 520 css_schedule_eval(schid); 521 return 0; 522 } 523 524 /** 525 * chsc_chp_vary - propagate channel-path vary operation to subchannels 526 * @chpid: channl-path ID 527 * @on: non-zero for vary online, zero for vary offline 528 */ 529 int chsc_chp_vary(struct chp_id chpid, int on) 530 { 531 struct channel_path *chp = chpid_to_chp(chpid); 532 struct chp_link link; 533 534 memset(&link, 0, sizeof(struct chp_link)); 535 link.chpid = chpid; 536 /* Wait until previous actions have settled. */ 537 css_wait_for_slow_path(); 538 /* 539 * Redo PathVerification on the devices the chpid connects to 540 */ 541 if (on) { 542 /* Try to update the channel path descritor. */ 543 chsc_determine_base_channel_path_desc(chpid, &chp->desc); 544 for_each_subchannel_staged(s390_subchannel_vary_chpid_on, 545 __s390_vary_chpid_on, &link); 546 } else 547 for_each_subchannel_staged(s390_subchannel_vary_chpid_off, 548 NULL, &link); 549 550 return 0; 551 } 552 553 static void 554 chsc_remove_cmg_attr(struct channel_subsystem *css) 555 { 556 int i; 557 558 for (i = 0; i <= __MAX_CHPID; i++) { 559 if (!css->chps[i]) 560 continue; 561 chp_remove_cmg_attr(css->chps[i]); 562 } 563 } 564 565 static int 566 chsc_add_cmg_attr(struct channel_subsystem *css) 567 { 568 int i, ret; 569 570 ret = 0; 571 for (i = 0; i <= __MAX_CHPID; i++) { 572 if (!css->chps[i]) 573 continue; 574 ret = chp_add_cmg_attr(css->chps[i]); 575 if (ret) 576 goto cleanup; 577 } 578 return ret; 579 cleanup: 580 for (--i; i >= 0; i--) { 581 if (!css->chps[i]) 582 continue; 583 chp_remove_cmg_attr(css->chps[i]); 584 } 585 return ret; 586 } 587 588 int __chsc_do_secm(struct channel_subsystem *css, int enable) 589 { 590 struct { 591 struct chsc_header request; 592 u32 operation_code : 2; 593 u32 : 30; 594 u32 key : 4; 595 u32 : 28; 596 u32 zeroes1; 597 u32 cub_addr1; 598 u32 zeroes2; 599 u32 cub_addr2; 600 u32 reserved[13]; 601 struct chsc_header response; 602 u32 status : 8; 603 u32 : 4; 604 u32 fmt : 4; 605 u32 : 16; 606 } __attribute__ ((packed)) *secm_area; 607 int ret, ccode; 608 609 spin_lock_irq(&chsc_page_lock); 610 memset(chsc_page, 0, PAGE_SIZE); 611 secm_area = chsc_page; 612 secm_area->request.length = 0x0050; 613 secm_area->request.code = 0x0016; 614 615 secm_area->key = PAGE_DEFAULT_KEY >> 4; 616 secm_area->cub_addr1 = (u64)(unsigned long)css->cub_addr1; 617 secm_area->cub_addr2 = (u64)(unsigned long)css->cub_addr2; 618 619 secm_area->operation_code = enable ? 0 : 1; 620 621 ccode = chsc(secm_area); 622 if (ccode > 0) { 623 ret = (ccode == 3) ? -ENODEV : -EBUSY; 624 goto out; 625 } 626 627 switch (secm_area->response.code) { 628 case 0x0102: 629 case 0x0103: 630 ret = -EINVAL; 631 break; 632 default: 633 ret = chsc_error_from_response(secm_area->response.code); 634 } 635 if (ret != 0) 636 CIO_CRW_EVENT(2, "chsc: secm failed (rc=%04x)\n", 637 secm_area->response.code); 638 out: 639 spin_unlock_irq(&chsc_page_lock); 640 return ret; 641 } 642 643 int 644 chsc_secm(struct channel_subsystem *css, int enable) 645 { 646 int ret; 647 648 if (enable && !css->cm_enabled) { 649 css->cub_addr1 = (void *)get_zeroed_page(GFP_KERNEL | GFP_DMA); 650 css->cub_addr2 = (void *)get_zeroed_page(GFP_KERNEL | GFP_DMA); 651 if (!css->cub_addr1 || !css->cub_addr2) { 652 free_page((unsigned long)css->cub_addr1); 653 free_page((unsigned long)css->cub_addr2); 654 return -ENOMEM; 655 } 656 } 657 ret = __chsc_do_secm(css, enable); 658 if (!ret) { 659 css->cm_enabled = enable; 660 if (css->cm_enabled) { 661 ret = chsc_add_cmg_attr(css); 662 if (ret) { 663 __chsc_do_secm(css, 0); 664 css->cm_enabled = 0; 665 } 666 } else 667 chsc_remove_cmg_attr(css); 668 } 669 if (!css->cm_enabled) { 670 free_page((unsigned long)css->cub_addr1); 671 free_page((unsigned long)css->cub_addr2); 672 } 673 return ret; 674 } 675 676 int chsc_determine_channel_path_desc(struct chp_id chpid, int fmt, int rfmt, 677 int c, int m, void *page) 678 { 679 struct chsc_scpd *scpd_area; 680 int ccode, ret; 681 682 if ((rfmt == 1) && !css_general_characteristics.fcs) 683 return -EINVAL; 684 if ((rfmt == 2) && !css_general_characteristics.cib) 685 return -EINVAL; 686 687 memset(page, 0, PAGE_SIZE); 688 scpd_area = page; 689 scpd_area->request.length = 0x0010; 690 scpd_area->request.code = 0x0002; 691 scpd_area->cssid = chpid.cssid; 692 scpd_area->first_chpid = chpid.id; 693 scpd_area->last_chpid = chpid.id; 694 scpd_area->m = m; 695 scpd_area->c = c; 696 scpd_area->fmt = fmt; 697 scpd_area->rfmt = rfmt; 698 699 ccode = chsc(scpd_area); 700 if (ccode > 0) 701 return (ccode == 3) ? -ENODEV : -EBUSY; 702 703 ret = chsc_error_from_response(scpd_area->response.code); 704 if (ret) 705 CIO_CRW_EVENT(2, "chsc: scpd failed (rc=%04x)\n", 706 scpd_area->response.code); 707 return ret; 708 } 709 EXPORT_SYMBOL_GPL(chsc_determine_channel_path_desc); 710 711 int chsc_determine_base_channel_path_desc(struct chp_id chpid, 712 struct channel_path_desc *desc) 713 { 714 struct chsc_response_struct *chsc_resp; 715 struct chsc_scpd *scpd_area; 716 unsigned long flags; 717 int ret; 718 719 spin_lock_irqsave(&chsc_page_lock, flags); 720 scpd_area = chsc_page; 721 ret = chsc_determine_channel_path_desc(chpid, 0, 0, 0, 0, scpd_area); 722 if (ret) 723 goto out; 724 chsc_resp = (void *)&scpd_area->response; 725 memcpy(desc, &chsc_resp->data, sizeof(*desc)); 726 out: 727 spin_unlock_irqrestore(&chsc_page_lock, flags); 728 return ret; 729 } 730 731 int chsc_determine_fmt1_channel_path_desc(struct chp_id chpid, 732 struct channel_path_desc_fmt1 *desc) 733 { 734 struct chsc_response_struct *chsc_resp; 735 struct chsc_scpd *scpd_area; 736 int ret; 737 738 spin_lock_irq(&chsc_page_lock); 739 scpd_area = chsc_page; 740 ret = chsc_determine_channel_path_desc(chpid, 0, 0, 1, 0, scpd_area); 741 if (ret) 742 goto out; 743 chsc_resp = (void *)&scpd_area->response; 744 memcpy(desc, &chsc_resp->data, sizeof(*desc)); 745 out: 746 spin_unlock_irq(&chsc_page_lock); 747 return ret; 748 } 749 750 static void 751 chsc_initialize_cmg_chars(struct channel_path *chp, u8 cmcv, 752 struct cmg_chars *chars) 753 { 754 struct cmg_chars *cmg_chars; 755 int i, mask; 756 757 cmg_chars = chp->cmg_chars; 758 for (i = 0; i < NR_MEASUREMENT_CHARS; i++) { 759 mask = 0x80 >> (i + 3); 760 if (cmcv & mask) 761 cmg_chars->values[i] = chars->values[i]; 762 else 763 cmg_chars->values[i] = 0; 764 } 765 } 766 767 int chsc_get_channel_measurement_chars(struct channel_path *chp) 768 { 769 struct cmg_chars *cmg_chars; 770 int ccode, ret; 771 772 struct { 773 struct chsc_header request; 774 u32 : 24; 775 u32 first_chpid : 8; 776 u32 : 24; 777 u32 last_chpid : 8; 778 u32 zeroes1; 779 struct chsc_header response; 780 u32 zeroes2; 781 u32 not_valid : 1; 782 u32 shared : 1; 783 u32 : 22; 784 u32 chpid : 8; 785 u32 cmcv : 5; 786 u32 : 11; 787 u32 cmgq : 8; 788 u32 cmg : 8; 789 u32 zeroes3; 790 u32 data[NR_MEASUREMENT_CHARS]; 791 } __attribute__ ((packed)) *scmc_area; 792 793 chp->cmg_chars = NULL; 794 cmg_chars = kmalloc(sizeof(*cmg_chars), GFP_KERNEL); 795 if (!cmg_chars) 796 return -ENOMEM; 797 798 spin_lock_irq(&chsc_page_lock); 799 memset(chsc_page, 0, PAGE_SIZE); 800 scmc_area = chsc_page; 801 scmc_area->request.length = 0x0010; 802 scmc_area->request.code = 0x0022; 803 scmc_area->first_chpid = chp->chpid.id; 804 scmc_area->last_chpid = chp->chpid.id; 805 806 ccode = chsc(scmc_area); 807 if (ccode > 0) { 808 ret = (ccode == 3) ? -ENODEV : -EBUSY; 809 goto out; 810 } 811 812 ret = chsc_error_from_response(scmc_area->response.code); 813 if (ret) { 814 CIO_CRW_EVENT(2, "chsc: scmc failed (rc=%04x)\n", 815 scmc_area->response.code); 816 goto out; 817 } 818 if (scmc_area->not_valid) { 819 chp->cmg = -1; 820 chp->shared = -1; 821 goto out; 822 } 823 chp->cmg = scmc_area->cmg; 824 chp->shared = scmc_area->shared; 825 if (chp->cmg != 2 && chp->cmg != 3) { 826 /* No cmg-dependent data. */ 827 goto out; 828 } 829 chp->cmg_chars = cmg_chars; 830 chsc_initialize_cmg_chars(chp, scmc_area->cmcv, 831 (struct cmg_chars *) &scmc_area->data); 832 out: 833 spin_unlock_irq(&chsc_page_lock); 834 if (!chp->cmg_chars) 835 kfree(cmg_chars); 836 837 return ret; 838 } 839 840 int __init chsc_init(void) 841 { 842 int ret; 843 844 sei_page = (void *)get_zeroed_page(GFP_KERNEL | GFP_DMA); 845 chsc_page = (void *)get_zeroed_page(GFP_KERNEL | GFP_DMA); 846 if (!sei_page || !chsc_page) { 847 ret = -ENOMEM; 848 goto out_err; 849 } 850 ret = crw_register_handler(CRW_RSC_CSS, chsc_process_crw); 851 if (ret) 852 goto out_err; 853 return ret; 854 out_err: 855 free_page((unsigned long)chsc_page); 856 free_page((unsigned long)sei_page); 857 return ret; 858 } 859 860 void __init chsc_init_cleanup(void) 861 { 862 crw_unregister_handler(CRW_RSC_CSS); 863 free_page((unsigned long)chsc_page); 864 free_page((unsigned long)sei_page); 865 } 866 867 int chsc_enable_facility(int operation_code) 868 { 869 unsigned long flags; 870 int ret; 871 struct { 872 struct chsc_header request; 873 u8 reserved1:4; 874 u8 format:4; 875 u8 reserved2; 876 u16 operation_code; 877 u32 reserved3; 878 u32 reserved4; 879 u32 operation_data_area[252]; 880 struct chsc_header response; 881 u32 reserved5:4; 882 u32 format2:4; 883 u32 reserved6:24; 884 } __attribute__ ((packed)) *sda_area; 885 886 spin_lock_irqsave(&chsc_page_lock, flags); 887 memset(chsc_page, 0, PAGE_SIZE); 888 sda_area = chsc_page; 889 sda_area->request.length = 0x0400; 890 sda_area->request.code = 0x0031; 891 sda_area->operation_code = operation_code; 892 893 ret = chsc(sda_area); 894 if (ret > 0) { 895 ret = (ret == 3) ? -ENODEV : -EBUSY; 896 goto out; 897 } 898 899 switch (sda_area->response.code) { 900 case 0x0101: 901 ret = -EOPNOTSUPP; 902 break; 903 default: 904 ret = chsc_error_from_response(sda_area->response.code); 905 } 906 if (ret != 0) 907 CIO_CRW_EVENT(2, "chsc: sda (oc=%x) failed (rc=%04x)\n", 908 operation_code, sda_area->response.code); 909 out: 910 spin_unlock_irqrestore(&chsc_page_lock, flags); 911 return ret; 912 } 913 914 struct css_general_char css_general_characteristics; 915 struct css_chsc_char css_chsc_characteristics; 916 917 int __init 918 chsc_determine_css_characteristics(void) 919 { 920 int result; 921 struct { 922 struct chsc_header request; 923 u32 reserved1; 924 u32 reserved2; 925 u32 reserved3; 926 struct chsc_header response; 927 u32 reserved4; 928 u32 general_char[510]; 929 u32 chsc_char[508]; 930 } __attribute__ ((packed)) *scsc_area; 931 932 spin_lock_irq(&chsc_page_lock); 933 memset(chsc_page, 0, PAGE_SIZE); 934 scsc_area = chsc_page; 935 scsc_area->request.length = 0x0010; 936 scsc_area->request.code = 0x0010; 937 938 result = chsc(scsc_area); 939 if (result) { 940 result = (result == 3) ? -ENODEV : -EBUSY; 941 goto exit; 942 } 943 944 result = chsc_error_from_response(scsc_area->response.code); 945 if (result == 0) { 946 memcpy(&css_general_characteristics, scsc_area->general_char, 947 sizeof(css_general_characteristics)); 948 memcpy(&css_chsc_characteristics, scsc_area->chsc_char, 949 sizeof(css_chsc_characteristics)); 950 } else 951 CIO_CRW_EVENT(2, "chsc: scsc failed (rc=%04x)\n", 952 scsc_area->response.code); 953 exit: 954 spin_unlock_irq(&chsc_page_lock); 955 return result; 956 } 957 958 EXPORT_SYMBOL_GPL(css_general_characteristics); 959 EXPORT_SYMBOL_GPL(css_chsc_characteristics); 960 961 int chsc_sstpc(void *page, unsigned int op, u16 ctrl) 962 { 963 struct { 964 struct chsc_header request; 965 unsigned int rsvd0; 966 unsigned int op : 8; 967 unsigned int rsvd1 : 8; 968 unsigned int ctrl : 16; 969 unsigned int rsvd2[5]; 970 struct chsc_header response; 971 unsigned int rsvd3[7]; 972 } __attribute__ ((packed)) *rr; 973 int rc; 974 975 memset(page, 0, PAGE_SIZE); 976 rr = page; 977 rr->request.length = 0x0020; 978 rr->request.code = 0x0033; 979 rr->op = op; 980 rr->ctrl = ctrl; 981 rc = chsc(rr); 982 if (rc) 983 return -EIO; 984 rc = (rr->response.code == 0x0001) ? 0 : -EIO; 985 return rc; 986 } 987 988 int chsc_sstpi(void *page, void *result, size_t size) 989 { 990 struct { 991 struct chsc_header request; 992 unsigned int rsvd0[3]; 993 struct chsc_header response; 994 char data[size]; 995 } __attribute__ ((packed)) *rr; 996 int rc; 997 998 memset(page, 0, PAGE_SIZE); 999 rr = page; 1000 rr->request.length = 0x0010; 1001 rr->request.code = 0x0038; 1002 rc = chsc(rr); 1003 if (rc) 1004 return -EIO; 1005 memcpy(result, &rr->data, size); 1006 return (rr->response.code == 0x0001) ? 0 : -EIO; 1007 } 1008 1009 int chsc_siosl(struct subchannel_id schid) 1010 { 1011 struct { 1012 struct chsc_header request; 1013 u32 word1; 1014 struct subchannel_id sid; 1015 u32 word3; 1016 struct chsc_header response; 1017 u32 word[11]; 1018 } __attribute__ ((packed)) *siosl_area; 1019 unsigned long flags; 1020 int ccode; 1021 int rc; 1022 1023 spin_lock_irqsave(&chsc_page_lock, flags); 1024 memset(chsc_page, 0, PAGE_SIZE); 1025 siosl_area = chsc_page; 1026 siosl_area->request.length = 0x0010; 1027 siosl_area->request.code = 0x0046; 1028 siosl_area->word1 = 0x80000000; 1029 siosl_area->sid = schid; 1030 1031 ccode = chsc(siosl_area); 1032 if (ccode > 0) { 1033 if (ccode == 3) 1034 rc = -ENODEV; 1035 else 1036 rc = -EBUSY; 1037 CIO_MSG_EVENT(2, "chsc: chsc failed for 0.%x.%04x (ccode=%d)\n", 1038 schid.ssid, schid.sch_no, ccode); 1039 goto out; 1040 } 1041 rc = chsc_error_from_response(siosl_area->response.code); 1042 if (rc) 1043 CIO_MSG_EVENT(2, "chsc: siosl failed for 0.%x.%04x (rc=%04x)\n", 1044 schid.ssid, schid.sch_no, 1045 siosl_area->response.code); 1046 else 1047 CIO_MSG_EVENT(4, "chsc: siosl succeeded for 0.%x.%04x\n", 1048 schid.ssid, schid.sch_no); 1049 out: 1050 spin_unlock_irqrestore(&chsc_page_lock, flags); 1051 return rc; 1052 } 1053 EXPORT_SYMBOL_GPL(chsc_siosl); 1054