1 /* 2 * drivers/s390/cio/chsc.c 3 * S/390 common I/O routines -- channel subsystem call 4 * 5 * Copyright IBM Corp. 1999,2008 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 DEFINE_SPINLOCK(sda_lock); 33 34 /** 35 * chsc_error_from_response() - convert a chsc response to an error 36 * @response: chsc response code 37 * 38 * Returns an appropriate Linux error code for @response. 39 */ 40 int chsc_error_from_response(int response) 41 { 42 switch (response) { 43 case 0x0001: 44 return 0; 45 case 0x0002: 46 case 0x0003: 47 case 0x0006: 48 case 0x0007: 49 case 0x0008: 50 case 0x000a: 51 return -EINVAL; 52 case 0x0004: 53 return -EOPNOTSUPP; 54 default: 55 return -EIO; 56 } 57 } 58 EXPORT_SYMBOL_GPL(chsc_error_from_response); 59 60 struct chsc_ssd_area { 61 struct chsc_header request; 62 u16 :10; 63 u16 ssid:2; 64 u16 :4; 65 u16 f_sch; /* first subchannel */ 66 u16 :16; 67 u16 l_sch; /* last subchannel */ 68 u32 :32; 69 struct chsc_header response; 70 u32 :32; 71 u8 sch_valid : 1; 72 u8 dev_valid : 1; 73 u8 st : 3; /* subchannel type */ 74 u8 zeroes : 3; 75 u8 unit_addr; /* unit address */ 76 u16 devno; /* device number */ 77 u8 path_mask; 78 u8 fla_valid_mask; 79 u16 sch; /* subchannel */ 80 u8 chpid[8]; /* chpids 0-7 */ 81 u16 fla[8]; /* full link addresses 0-7 */ 82 } __attribute__ ((packed)); 83 84 int chsc_get_ssd_info(struct subchannel_id schid, struct chsc_ssd_info *ssd) 85 { 86 unsigned long page; 87 struct chsc_ssd_area *ssd_area; 88 int ccode; 89 int ret; 90 int i; 91 int mask; 92 93 page = get_zeroed_page(GFP_KERNEL | GFP_DMA); 94 if (!page) 95 return -ENOMEM; 96 ssd_area = (struct chsc_ssd_area *) 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_free; 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_free; 115 } 116 if (!ssd_area->sch_valid) { 117 ret = -ENODEV; 118 goto out_free; 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_free; 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_free: 138 free_page(page); 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 struct chp_config_data { 330 u8 map[32]; 331 u8 op; 332 u8 pc; 333 }; 334 335 static void chsc_process_sei_chp_config(struct chsc_sei_area *sei_area) 336 { 337 struct chp_config_data *data; 338 struct chp_id chpid; 339 int num; 340 char *events[3] = {"configure", "deconfigure", "cancel deconfigure"}; 341 342 CIO_CRW_EVENT(4, "chsc: channel-path-configuration notification\n"); 343 if (sei_area->rs != 0) 344 return; 345 data = (struct chp_config_data *) &(sei_area->ccdf); 346 chp_id_init(&chpid); 347 for (num = 0; num <= __MAX_CHPID; num++) { 348 if (!chp_test_bit(data->map, num)) 349 continue; 350 chpid.id = num; 351 pr_notice("Processing %s for channel path %x.%02x\n", 352 events[data->op], chpid.cssid, chpid.id); 353 switch (data->op) { 354 case 0: 355 chp_cfg_schedule(chpid, 1); 356 break; 357 case 1: 358 chp_cfg_schedule(chpid, 0); 359 break; 360 case 2: 361 chp_cfg_cancel_deconfigure(chpid); 362 break; 363 } 364 } 365 } 366 367 static void chsc_process_sei(struct chsc_sei_area *sei_area) 368 { 369 /* Check if we might have lost some information. */ 370 if (sei_area->flags & 0x40) { 371 CIO_CRW_EVENT(2, "chsc: event overflow\n"); 372 css_schedule_eval_all(); 373 } 374 /* which kind of information was stored? */ 375 switch (sei_area->cc) { 376 case 1: /* link incident*/ 377 chsc_process_sei_link_incident(sei_area); 378 break; 379 case 2: /* i/o resource accessibiliy */ 380 chsc_process_sei_res_acc(sei_area); 381 break; 382 case 8: /* channel-path-configuration notification */ 383 chsc_process_sei_chp_config(sei_area); 384 break; 385 default: /* other stuff */ 386 CIO_CRW_EVENT(4, "chsc: unhandled sei content code %d\n", 387 sei_area->cc); 388 break; 389 } 390 } 391 392 static void chsc_process_crw(struct crw *crw0, struct crw *crw1, int overflow) 393 { 394 struct chsc_sei_area *sei_area; 395 396 if (overflow) { 397 css_schedule_eval_all(); 398 return; 399 } 400 CIO_CRW_EVENT(2, "CRW reports slct=%d, oflw=%d, " 401 "chn=%d, rsc=%X, anc=%d, erc=%X, rsid=%X\n", 402 crw0->slct, crw0->oflw, crw0->chn, crw0->rsc, crw0->anc, 403 crw0->erc, crw0->rsid); 404 if (!sei_page) 405 return; 406 /* Access to sei_page is serialized through machine check handler 407 * thread, so no need for locking. */ 408 sei_area = sei_page; 409 410 CIO_TRACE_EVENT(2, "prcss"); 411 do { 412 memset(sei_area, 0, sizeof(*sei_area)); 413 sei_area->request.length = 0x0010; 414 sei_area->request.code = 0x000e; 415 if (chsc(sei_area)) 416 break; 417 418 if (sei_area->response.code == 0x0001) { 419 CIO_CRW_EVENT(4, "chsc: sei successful\n"); 420 chsc_process_sei(sei_area); 421 } else { 422 CIO_CRW_EVENT(2, "chsc: sei failed (rc=%04x)\n", 423 sei_area->response.code); 424 break; 425 } 426 } while (sei_area->flags & 0x80); 427 } 428 429 void chsc_chp_online(struct chp_id chpid) 430 { 431 char dbf_txt[15]; 432 struct chp_link link; 433 434 sprintf(dbf_txt, "cadd%x.%02x", chpid.cssid, chpid.id); 435 CIO_TRACE_EVENT(2, dbf_txt); 436 437 if (chp_get_status(chpid) != 0) { 438 memset(&link, 0, sizeof(struct chp_link)); 439 link.chpid = chpid; 440 /* Wait until previous actions have settled. */ 441 css_wait_for_slow_path(); 442 for_each_subchannel_staged(__s390_process_res_acc, NULL, 443 &link); 444 } 445 } 446 447 static void __s390_subchannel_vary_chpid(struct subchannel *sch, 448 struct chp_id chpid, int on) 449 { 450 unsigned long flags; 451 struct chp_link link; 452 453 memset(&link, 0, sizeof(struct chp_link)); 454 link.chpid = chpid; 455 spin_lock_irqsave(sch->lock, flags); 456 if (sch->driver && sch->driver->chp_event) 457 sch->driver->chp_event(sch, &link, 458 on ? CHP_VARY_ON : CHP_VARY_OFF); 459 spin_unlock_irqrestore(sch->lock, flags); 460 } 461 462 static int s390_subchannel_vary_chpid_off(struct subchannel *sch, void *data) 463 { 464 struct chp_id *chpid = data; 465 466 __s390_subchannel_vary_chpid(sch, *chpid, 0); 467 return 0; 468 } 469 470 static int s390_subchannel_vary_chpid_on(struct subchannel *sch, void *data) 471 { 472 struct chp_id *chpid = data; 473 474 __s390_subchannel_vary_chpid(sch, *chpid, 1); 475 return 0; 476 } 477 478 static int 479 __s390_vary_chpid_on(struct subchannel_id schid, void *data) 480 { 481 struct schib schib; 482 483 if (stsch_err(schid, &schib)) 484 /* We're through */ 485 return -ENXIO; 486 /* Put it on the slow path. */ 487 css_schedule_eval(schid); 488 return 0; 489 } 490 491 /** 492 * chsc_chp_vary - propagate channel-path vary operation to subchannels 493 * @chpid: channl-path ID 494 * @on: non-zero for vary online, zero for vary offline 495 */ 496 int chsc_chp_vary(struct chp_id chpid, int on) 497 { 498 struct chp_link link; 499 500 memset(&link, 0, sizeof(struct chp_link)); 501 link.chpid = chpid; 502 /* Wait until previous actions have settled. */ 503 css_wait_for_slow_path(); 504 /* 505 * Redo PathVerification on the devices the chpid connects to 506 */ 507 508 if (on) 509 for_each_subchannel_staged(s390_subchannel_vary_chpid_on, 510 __s390_vary_chpid_on, &link); 511 else 512 for_each_subchannel_staged(s390_subchannel_vary_chpid_off, 513 NULL, &link); 514 515 return 0; 516 } 517 518 static void 519 chsc_remove_cmg_attr(struct channel_subsystem *css) 520 { 521 int i; 522 523 for (i = 0; i <= __MAX_CHPID; i++) { 524 if (!css->chps[i]) 525 continue; 526 chp_remove_cmg_attr(css->chps[i]); 527 } 528 } 529 530 static int 531 chsc_add_cmg_attr(struct channel_subsystem *css) 532 { 533 int i, ret; 534 535 ret = 0; 536 for (i = 0; i <= __MAX_CHPID; i++) { 537 if (!css->chps[i]) 538 continue; 539 ret = chp_add_cmg_attr(css->chps[i]); 540 if (ret) 541 goto cleanup; 542 } 543 return ret; 544 cleanup: 545 for (--i; i >= 0; i--) { 546 if (!css->chps[i]) 547 continue; 548 chp_remove_cmg_attr(css->chps[i]); 549 } 550 return ret; 551 } 552 553 int __chsc_do_secm(struct channel_subsystem *css, int enable, void *page) 554 { 555 struct { 556 struct chsc_header request; 557 u32 operation_code : 2; 558 u32 : 30; 559 u32 key : 4; 560 u32 : 28; 561 u32 zeroes1; 562 u32 cub_addr1; 563 u32 zeroes2; 564 u32 cub_addr2; 565 u32 reserved[13]; 566 struct chsc_header response; 567 u32 status : 8; 568 u32 : 4; 569 u32 fmt : 4; 570 u32 : 16; 571 } __attribute__ ((packed)) *secm_area; 572 int ret, ccode; 573 574 secm_area = page; 575 secm_area->request.length = 0x0050; 576 secm_area->request.code = 0x0016; 577 578 secm_area->key = PAGE_DEFAULT_KEY >> 4; 579 secm_area->cub_addr1 = (u64)(unsigned long)css->cub_addr1; 580 secm_area->cub_addr2 = (u64)(unsigned long)css->cub_addr2; 581 582 secm_area->operation_code = enable ? 0 : 1; 583 584 ccode = chsc(secm_area); 585 if (ccode > 0) 586 return (ccode == 3) ? -ENODEV : -EBUSY; 587 588 switch (secm_area->response.code) { 589 case 0x0102: 590 case 0x0103: 591 ret = -EINVAL; 592 break; 593 default: 594 ret = chsc_error_from_response(secm_area->response.code); 595 } 596 if (ret != 0) 597 CIO_CRW_EVENT(2, "chsc: secm failed (rc=%04x)\n", 598 secm_area->response.code); 599 return ret; 600 } 601 602 int 603 chsc_secm(struct channel_subsystem *css, int enable) 604 { 605 void *secm_area; 606 int ret; 607 608 secm_area = (void *)get_zeroed_page(GFP_KERNEL | GFP_DMA); 609 if (!secm_area) 610 return -ENOMEM; 611 612 if (enable && !css->cm_enabled) { 613 css->cub_addr1 = (void *)get_zeroed_page(GFP_KERNEL | GFP_DMA); 614 css->cub_addr2 = (void *)get_zeroed_page(GFP_KERNEL | GFP_DMA); 615 if (!css->cub_addr1 || !css->cub_addr2) { 616 free_page((unsigned long)css->cub_addr1); 617 free_page((unsigned long)css->cub_addr2); 618 free_page((unsigned long)secm_area); 619 return -ENOMEM; 620 } 621 } 622 ret = __chsc_do_secm(css, enable, secm_area); 623 if (!ret) { 624 css->cm_enabled = enable; 625 if (css->cm_enabled) { 626 ret = chsc_add_cmg_attr(css); 627 if (ret) { 628 memset(secm_area, 0, PAGE_SIZE); 629 __chsc_do_secm(css, 0, secm_area); 630 css->cm_enabled = 0; 631 } 632 } else 633 chsc_remove_cmg_attr(css); 634 } 635 if (!css->cm_enabled) { 636 free_page((unsigned long)css->cub_addr1); 637 free_page((unsigned long)css->cub_addr2); 638 } 639 free_page((unsigned long)secm_area); 640 return ret; 641 } 642 643 int chsc_determine_channel_path_desc(struct chp_id chpid, int fmt, int rfmt, 644 int c, int m, 645 struct chsc_response_struct *resp) 646 { 647 int ccode, ret; 648 649 struct { 650 struct chsc_header request; 651 u32 : 2; 652 u32 m : 1; 653 u32 c : 1; 654 u32 fmt : 4; 655 u32 cssid : 8; 656 u32 : 4; 657 u32 rfmt : 4; 658 u32 first_chpid : 8; 659 u32 : 24; 660 u32 last_chpid : 8; 661 u32 zeroes1; 662 struct chsc_header response; 663 u8 data[PAGE_SIZE - 20]; 664 } __attribute__ ((packed)) *scpd_area; 665 666 if ((rfmt == 1) && !css_general_characteristics.fcs) 667 return -EINVAL; 668 if ((rfmt == 2) && !css_general_characteristics.cib) 669 return -EINVAL; 670 scpd_area = (void *)get_zeroed_page(GFP_KERNEL | GFP_DMA); 671 if (!scpd_area) 672 return -ENOMEM; 673 674 scpd_area->request.length = 0x0010; 675 scpd_area->request.code = 0x0002; 676 677 scpd_area->cssid = chpid.cssid; 678 scpd_area->first_chpid = chpid.id; 679 scpd_area->last_chpid = chpid.id; 680 scpd_area->m = m; 681 scpd_area->c = c; 682 scpd_area->fmt = fmt; 683 scpd_area->rfmt = rfmt; 684 685 ccode = chsc(scpd_area); 686 if (ccode > 0) { 687 ret = (ccode == 3) ? -ENODEV : -EBUSY; 688 goto out; 689 } 690 691 ret = chsc_error_from_response(scpd_area->response.code); 692 if (ret == 0) 693 /* Success. */ 694 memcpy(resp, &scpd_area->response, scpd_area->response.length); 695 else 696 CIO_CRW_EVENT(2, "chsc: scpd failed (rc=%04x)\n", 697 scpd_area->response.code); 698 out: 699 free_page((unsigned long)scpd_area); 700 return ret; 701 } 702 EXPORT_SYMBOL_GPL(chsc_determine_channel_path_desc); 703 704 int chsc_determine_base_channel_path_desc(struct chp_id chpid, 705 struct channel_path_desc *desc) 706 { 707 struct chsc_response_struct *chsc_resp; 708 int ret; 709 710 chsc_resp = kzalloc(sizeof(*chsc_resp), GFP_KERNEL); 711 if (!chsc_resp) 712 return -ENOMEM; 713 ret = chsc_determine_channel_path_desc(chpid, 0, 0, 0, 0, chsc_resp); 714 if (ret) 715 goto out_free; 716 memcpy(desc, &chsc_resp->data, chsc_resp->length); 717 out_free: 718 kfree(chsc_resp); 719 return ret; 720 } 721 722 static void 723 chsc_initialize_cmg_chars(struct channel_path *chp, u8 cmcv, 724 struct cmg_chars *chars) 725 { 726 switch (chp->cmg) { 727 case 2: 728 case 3: 729 chp->cmg_chars = kmalloc(sizeof(struct cmg_chars), 730 GFP_KERNEL); 731 if (chp->cmg_chars) { 732 int i, mask; 733 struct cmg_chars *cmg_chars; 734 735 cmg_chars = chp->cmg_chars; 736 for (i = 0; i < NR_MEASUREMENT_CHARS; i++) { 737 mask = 0x80 >> (i + 3); 738 if (cmcv & mask) 739 cmg_chars->values[i] = chars->values[i]; 740 else 741 cmg_chars->values[i] = 0; 742 } 743 } 744 break; 745 default: 746 /* No cmg-dependent data. */ 747 break; 748 } 749 } 750 751 int chsc_get_channel_measurement_chars(struct channel_path *chp) 752 { 753 int ccode, ret; 754 755 struct { 756 struct chsc_header request; 757 u32 : 24; 758 u32 first_chpid : 8; 759 u32 : 24; 760 u32 last_chpid : 8; 761 u32 zeroes1; 762 struct chsc_header response; 763 u32 zeroes2; 764 u32 not_valid : 1; 765 u32 shared : 1; 766 u32 : 22; 767 u32 chpid : 8; 768 u32 cmcv : 5; 769 u32 : 11; 770 u32 cmgq : 8; 771 u32 cmg : 8; 772 u32 zeroes3; 773 u32 data[NR_MEASUREMENT_CHARS]; 774 } __attribute__ ((packed)) *scmc_area; 775 776 scmc_area = (void *)get_zeroed_page(GFP_KERNEL | GFP_DMA); 777 if (!scmc_area) 778 return -ENOMEM; 779 780 scmc_area->request.length = 0x0010; 781 scmc_area->request.code = 0x0022; 782 783 scmc_area->first_chpid = chp->chpid.id; 784 scmc_area->last_chpid = chp->chpid.id; 785 786 ccode = chsc(scmc_area); 787 if (ccode > 0) { 788 ret = (ccode == 3) ? -ENODEV : -EBUSY; 789 goto out; 790 } 791 792 ret = chsc_error_from_response(scmc_area->response.code); 793 if (ret == 0) { 794 /* Success. */ 795 if (!scmc_area->not_valid) { 796 chp->cmg = scmc_area->cmg; 797 chp->shared = scmc_area->shared; 798 chsc_initialize_cmg_chars(chp, scmc_area->cmcv, 799 (struct cmg_chars *) 800 &scmc_area->data); 801 } else { 802 chp->cmg = -1; 803 chp->shared = -1; 804 } 805 } else { 806 CIO_CRW_EVENT(2, "chsc: scmc failed (rc=%04x)\n", 807 scmc_area->response.code); 808 } 809 out: 810 free_page((unsigned long)scmc_area); 811 return ret; 812 } 813 814 int __init chsc_alloc_sei_area(void) 815 { 816 int ret; 817 818 sei_page = (void *)get_zeroed_page(GFP_KERNEL | GFP_DMA); 819 if (!sei_page) { 820 CIO_MSG_EVENT(0, "Can't allocate page for processing of " 821 "chsc machine checks!\n"); 822 return -ENOMEM; 823 } 824 ret = crw_register_handler(CRW_RSC_CSS, chsc_process_crw); 825 if (ret) 826 kfree(sei_page); 827 return ret; 828 } 829 830 void __init chsc_free_sei_area(void) 831 { 832 crw_unregister_handler(CRW_RSC_CSS); 833 kfree(sei_page); 834 } 835 836 int chsc_enable_facility(int operation_code) 837 { 838 int ret; 839 static struct { 840 struct chsc_header request; 841 u8 reserved1:4; 842 u8 format:4; 843 u8 reserved2; 844 u16 operation_code; 845 u32 reserved3; 846 u32 reserved4; 847 u32 operation_data_area[252]; 848 struct chsc_header response; 849 u32 reserved5:4; 850 u32 format2:4; 851 u32 reserved6:24; 852 } __attribute__ ((packed, aligned(4096))) sda_area; 853 854 spin_lock(&sda_lock); 855 memset(&sda_area, 0, sizeof(sda_area)); 856 sda_area.request.length = 0x0400; 857 sda_area.request.code = 0x0031; 858 sda_area.operation_code = operation_code; 859 860 ret = chsc(&sda_area); 861 if (ret > 0) { 862 ret = (ret == 3) ? -ENODEV : -EBUSY; 863 goto out; 864 } 865 866 switch (sda_area.response.code) { 867 case 0x0101: 868 ret = -EOPNOTSUPP; 869 break; 870 default: 871 ret = chsc_error_from_response(sda_area.response.code); 872 } 873 if (ret != 0) 874 CIO_CRW_EVENT(2, "chsc: sda (oc=%x) failed (rc=%04x)\n", 875 operation_code, sda_area.response.code); 876 out: 877 spin_unlock(&sda_lock); 878 return ret; 879 } 880 881 struct css_general_char css_general_characteristics; 882 struct css_chsc_char css_chsc_characteristics; 883 884 int __init 885 chsc_determine_css_characteristics(void) 886 { 887 int result; 888 struct { 889 struct chsc_header request; 890 u32 reserved1; 891 u32 reserved2; 892 u32 reserved3; 893 struct chsc_header response; 894 u32 reserved4; 895 u32 general_char[510]; 896 u32 chsc_char[518]; 897 } __attribute__ ((packed)) *scsc_area; 898 899 scsc_area = (void *)get_zeroed_page(GFP_KERNEL | GFP_DMA); 900 if (!scsc_area) 901 return -ENOMEM; 902 903 scsc_area->request.length = 0x0010; 904 scsc_area->request.code = 0x0010; 905 906 result = chsc(scsc_area); 907 if (result) { 908 result = (result == 3) ? -ENODEV : -EBUSY; 909 goto exit; 910 } 911 912 result = chsc_error_from_response(scsc_area->response.code); 913 if (result == 0) { 914 memcpy(&css_general_characteristics, scsc_area->general_char, 915 sizeof(css_general_characteristics)); 916 memcpy(&css_chsc_characteristics, scsc_area->chsc_char, 917 sizeof(css_chsc_characteristics)); 918 } else 919 CIO_CRW_EVENT(2, "chsc: scsc failed (rc=%04x)\n", 920 scsc_area->response.code); 921 exit: 922 free_page ((unsigned long) scsc_area); 923 return result; 924 } 925 926 EXPORT_SYMBOL_GPL(css_general_characteristics); 927 EXPORT_SYMBOL_GPL(css_chsc_characteristics); 928 929 int chsc_sstpc(void *page, unsigned int op, u16 ctrl) 930 { 931 struct { 932 struct chsc_header request; 933 unsigned int rsvd0; 934 unsigned int op : 8; 935 unsigned int rsvd1 : 8; 936 unsigned int ctrl : 16; 937 unsigned int rsvd2[5]; 938 struct chsc_header response; 939 unsigned int rsvd3[7]; 940 } __attribute__ ((packed)) *rr; 941 int rc; 942 943 memset(page, 0, PAGE_SIZE); 944 rr = page; 945 rr->request.length = 0x0020; 946 rr->request.code = 0x0033; 947 rr->op = op; 948 rr->ctrl = ctrl; 949 rc = chsc(rr); 950 if (rc) 951 return -EIO; 952 rc = (rr->response.code == 0x0001) ? 0 : -EIO; 953 return rc; 954 } 955 956 int chsc_sstpi(void *page, void *result, size_t size) 957 { 958 struct { 959 struct chsc_header request; 960 unsigned int rsvd0[3]; 961 struct chsc_header response; 962 char data[size]; 963 } __attribute__ ((packed)) *rr; 964 int rc; 965 966 memset(page, 0, PAGE_SIZE); 967 rr = page; 968 rr->request.length = 0x0010; 969 rr->request.code = 0x0038; 970 rc = chsc(rr); 971 if (rc) 972 return -EIO; 973 memcpy(result, &rr->data, size); 974 return (rr->response.code == 0x0001) ? 0 : -EIO; 975 } 976 977