root/drivers/s390/cio/chsc.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. chsc_error_from_response
  2. chsc_get_ssd_info
  3. chsc_ssqd
  4. chsc_sadc
  5. s390_subchannel_remove_chpid
  6. chsc_chp_offline
  7. __s390_process_res_acc
  8. s390_process_res_acc
  9. store_ebcdic
  10. format_node_data
  11. chsc_process_sei_link_incident
  12. chsc_process_sei_res_acc
  13. chsc_process_sei_chp_avail
  14. chsc_process_sei_chp_config
  15. chsc_process_sei_scm_change
  16. chsc_process_sei_scm_avail
  17. chsc_process_sei_ap_cfg_chg
  18. chsc_process_sei_nt2
  19. chsc_process_sei_nt0
  20. chsc_process_event_information
  21. chsc_process_crw
  22. chsc_chp_online
  23. __s390_subchannel_vary_chpid
  24. s390_subchannel_vary_chpid_off
  25. s390_subchannel_vary_chpid_on
  26. chsc_chp_vary
  27. chsc_remove_cmg_attr
  28. chsc_add_cmg_attr
  29. __chsc_do_secm
  30. chsc_secm
  31. chsc_determine_channel_path_desc
  32. chsc_det_chp_desc
  33. chsc_get_channel_measurement_chars
  34. chsc_init
  35. chsc_init_cleanup
  36. __chsc_enable_facility
  37. chsc_enable_facility
  38. chsc_get_cssid
  39. chsc_determine_css_characteristics
  40. chsc_sstpc
  41. chsc_sstpi
  42. chsc_siosl
  43. chsc_scm_info
  44. chsc_pnso_brinfo
  45. chsc_sgib

   1 // SPDX-License-Identifier: GPL-2.0
   2 /*
   3  *   S/390 common I/O routines -- channel subsystem call
   4  *
   5  *    Copyright IBM Corp. 1999,2012
   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 #include <linux/mutex.h>
  19 #include <linux/pci.h>
  20 
  21 #include <asm/cio.h>
  22 #include <asm/chpid.h>
  23 #include <asm/chsc.h>
  24 #include <asm/crw.h>
  25 #include <asm/isc.h>
  26 #include <asm/ebcdic.h>
  27 #include <asm/ap.h>
  28 
  29 #include "css.h"
  30 #include "cio.h"
  31 #include "cio_debug.h"
  32 #include "ioasm.h"
  33 #include "chp.h"
  34 #include "chsc.h"
  35 
  36 static void *sei_page;
  37 static void *chsc_page;
  38 static DEFINE_SPINLOCK(chsc_page_lock);
  39 
  40 /**
  41  * chsc_error_from_response() - convert a chsc response to an error
  42  * @response: chsc response code
  43  *
  44  * Returns an appropriate Linux error code for @response.
  45  */
  46 int chsc_error_from_response(int response)
  47 {
  48         switch (response) {
  49         case 0x0001:
  50                 return 0;
  51         case 0x0002:
  52         case 0x0003:
  53         case 0x0006:
  54         case 0x0007:
  55         case 0x0008:
  56         case 0x000a:
  57         case 0x0104:
  58                 return -EINVAL;
  59         case 0x0004:
  60                 return -EOPNOTSUPP;
  61         case 0x000b:
  62         case 0x0107:            /* "Channel busy" for the op 0x003d */
  63                 return -EBUSY;
  64         case 0x0100:
  65         case 0x0102:
  66                 return -ENOMEM;
  67         default:
  68                 return -EIO;
  69         }
  70 }
  71 EXPORT_SYMBOL_GPL(chsc_error_from_response);
  72 
  73 struct chsc_ssd_area {
  74         struct chsc_header request;
  75         u16 :10;
  76         u16 ssid:2;
  77         u16 :4;
  78         u16 f_sch;        /* first subchannel */
  79         u16 :16;
  80         u16 l_sch;        /* last subchannel */
  81         u32 :32;
  82         struct chsc_header response;
  83         u32 :32;
  84         u8 sch_valid : 1;
  85         u8 dev_valid : 1;
  86         u8 st        : 3; /* subchannel type */
  87         u8 zeroes    : 3;
  88         u8  unit_addr;    /* unit address */
  89         u16 devno;        /* device number */
  90         u8 path_mask;
  91         u8 fla_valid_mask;
  92         u16 sch;          /* subchannel */
  93         u8 chpid[8];      /* chpids 0-7 */
  94         u16 fla[8];       /* full link addresses 0-7 */
  95 } __packed __aligned(PAGE_SIZE);
  96 
  97 int chsc_get_ssd_info(struct subchannel_id schid, struct chsc_ssd_info *ssd)
  98 {
  99         struct chsc_ssd_area *ssd_area;
 100         unsigned long flags;
 101         int ccode;
 102         int ret;
 103         int i;
 104         int mask;
 105 
 106         spin_lock_irqsave(&chsc_page_lock, flags);
 107         memset(chsc_page, 0, PAGE_SIZE);
 108         ssd_area = chsc_page;
 109         ssd_area->request.length = 0x0010;
 110         ssd_area->request.code = 0x0004;
 111         ssd_area->ssid = schid.ssid;
 112         ssd_area->f_sch = schid.sch_no;
 113         ssd_area->l_sch = schid.sch_no;
 114 
 115         ccode = chsc(ssd_area);
 116         /* Check response. */
 117         if (ccode > 0) {
 118                 ret = (ccode == 3) ? -ENODEV : -EBUSY;
 119                 goto out;
 120         }
 121         ret = chsc_error_from_response(ssd_area->response.code);
 122         if (ret != 0) {
 123                 CIO_MSG_EVENT(2, "chsc: ssd failed for 0.%x.%04x (rc=%04x)\n",
 124                               schid.ssid, schid.sch_no,
 125                               ssd_area->response.code);
 126                 goto out;
 127         }
 128         if (!ssd_area->sch_valid) {
 129                 ret = -ENODEV;
 130                 goto out;
 131         }
 132         /* Copy data */
 133         ret = 0;
 134         memset(ssd, 0, sizeof(struct chsc_ssd_info));
 135         if ((ssd_area->st != SUBCHANNEL_TYPE_IO) &&
 136             (ssd_area->st != SUBCHANNEL_TYPE_MSG))
 137                 goto out;
 138         ssd->path_mask = ssd_area->path_mask;
 139         ssd->fla_valid_mask = ssd_area->fla_valid_mask;
 140         for (i = 0; i < 8; i++) {
 141                 mask = 0x80 >> i;
 142                 if (ssd_area->path_mask & mask) {
 143                         chp_id_init(&ssd->chpid[i]);
 144                         ssd->chpid[i].id = ssd_area->chpid[i];
 145                 }
 146                 if (ssd_area->fla_valid_mask & mask)
 147                         ssd->fla[i] = ssd_area->fla[i];
 148         }
 149 out:
 150         spin_unlock_irqrestore(&chsc_page_lock, flags);
 151         return ret;
 152 }
 153 
 154 /**
 155  * chsc_ssqd() - store subchannel QDIO data (SSQD)
 156  * @schid: id of the subchannel on which SSQD is performed
 157  * @ssqd: request and response block for SSQD
 158  *
 159  * Returns 0 on success.
 160  */
 161 int chsc_ssqd(struct subchannel_id schid, struct chsc_ssqd_area *ssqd)
 162 {
 163         memset(ssqd, 0, sizeof(*ssqd));
 164         ssqd->request.length = 0x0010;
 165         ssqd->request.code = 0x0024;
 166         ssqd->first_sch = schid.sch_no;
 167         ssqd->last_sch = schid.sch_no;
 168         ssqd->ssid = schid.ssid;
 169 
 170         if (chsc(ssqd))
 171                 return -EIO;
 172 
 173         return chsc_error_from_response(ssqd->response.code);
 174 }
 175 EXPORT_SYMBOL_GPL(chsc_ssqd);
 176 
 177 /**
 178  * chsc_sadc() - set adapter device controls (SADC)
 179  * @schid: id of the subchannel on which SADC is performed
 180  * @scssc: request and response block for SADC
 181  * @summary_indicator_addr: summary indicator address
 182  * @subchannel_indicator_addr: subchannel indicator address
 183  *
 184  * Returns 0 on success.
 185  */
 186 int chsc_sadc(struct subchannel_id schid, struct chsc_scssc_area *scssc,
 187               u64 summary_indicator_addr, u64 subchannel_indicator_addr)
 188 {
 189         memset(scssc, 0, sizeof(*scssc));
 190         scssc->request.length = 0x0fe0;
 191         scssc->request.code = 0x0021;
 192         scssc->operation_code = 0;
 193 
 194         scssc->summary_indicator_addr = summary_indicator_addr;
 195         scssc->subchannel_indicator_addr = subchannel_indicator_addr;
 196 
 197         scssc->ks = PAGE_DEFAULT_KEY >> 4;
 198         scssc->kc = PAGE_DEFAULT_KEY >> 4;
 199         scssc->isc = QDIO_AIRQ_ISC;
 200         scssc->schid = schid;
 201 
 202         /* enable the time delay disablement facility */
 203         if (css_general_characteristics.aif_tdd)
 204                 scssc->word_with_d_bit = 0x10000000;
 205 
 206         if (chsc(scssc))
 207                 return -EIO;
 208 
 209         return chsc_error_from_response(scssc->response.code);
 210 }
 211 EXPORT_SYMBOL_GPL(chsc_sadc);
 212 
 213 static int s390_subchannel_remove_chpid(struct subchannel *sch, void *data)
 214 {
 215         spin_lock_irq(sch->lock);
 216         if (sch->driver && sch->driver->chp_event)
 217                 if (sch->driver->chp_event(sch, data, CHP_OFFLINE) != 0)
 218                         goto out_unreg;
 219         spin_unlock_irq(sch->lock);
 220         return 0;
 221 
 222 out_unreg:
 223         sch->lpm = 0;
 224         spin_unlock_irq(sch->lock);
 225         css_schedule_eval(sch->schid);
 226         return 0;
 227 }
 228 
 229 void chsc_chp_offline(struct chp_id chpid)
 230 {
 231         struct channel_path *chp = chpid_to_chp(chpid);
 232         struct chp_link link;
 233         char dbf_txt[15];
 234 
 235         sprintf(dbf_txt, "chpr%x.%02x", chpid.cssid, chpid.id);
 236         CIO_TRACE_EVENT(2, dbf_txt);
 237 
 238         if (chp_get_status(chpid) <= 0)
 239                 return;
 240         memset(&link, 0, sizeof(struct chp_link));
 241         link.chpid = chpid;
 242         /* Wait until previous actions have settled. */
 243         css_wait_for_slow_path();
 244 
 245         mutex_lock(&chp->lock);
 246         chp_update_desc(chp);
 247         mutex_unlock(&chp->lock);
 248 
 249         for_each_subchannel_staged(s390_subchannel_remove_chpid, NULL, &link);
 250 }
 251 
 252 static int __s390_process_res_acc(struct subchannel *sch, void *data)
 253 {
 254         spin_lock_irq(sch->lock);
 255         if (sch->driver && sch->driver->chp_event)
 256                 sch->driver->chp_event(sch, data, CHP_ONLINE);
 257         spin_unlock_irq(sch->lock);
 258 
 259         return 0;
 260 }
 261 
 262 static void s390_process_res_acc(struct chp_link *link)
 263 {
 264         char dbf_txt[15];
 265 
 266         sprintf(dbf_txt, "accpr%x.%02x", link->chpid.cssid,
 267                 link->chpid.id);
 268         CIO_TRACE_EVENT( 2, dbf_txt);
 269         if (link->fla != 0) {
 270                 sprintf(dbf_txt, "fla%x", link->fla);
 271                 CIO_TRACE_EVENT( 2, dbf_txt);
 272         }
 273         /* Wait until previous actions have settled. */
 274         css_wait_for_slow_path();
 275         /*
 276          * I/O resources may have become accessible.
 277          * Scan through all subchannels that may be concerned and
 278          * do a validation on those.
 279          * The more information we have (info), the less scanning
 280          * will we have to do.
 281          */
 282         for_each_subchannel_staged(__s390_process_res_acc, NULL, link);
 283         css_schedule_reprobe();
 284 }
 285 
 286 struct chsc_sei_nt0_area {
 287         u8  flags;
 288         u8  vf;                         /* validity flags */
 289         u8  rs;                         /* reporting source */
 290         u8  cc;                         /* content code */
 291         u16 fla;                        /* full link address */
 292         u16 rsid;                       /* reporting source id */
 293         u32 reserved1;
 294         u32 reserved2;
 295         /* ccdf has to be big enough for a link-incident record */
 296         u8  ccdf[PAGE_SIZE - 24 - 16];  /* content-code dependent field */
 297 } __packed;
 298 
 299 struct chsc_sei_nt2_area {
 300         u8  flags;                      /* p and v bit */
 301         u8  reserved1;
 302         u8  reserved2;
 303         u8  cc;                         /* content code */
 304         u32 reserved3[13];
 305         u8  ccdf[PAGE_SIZE - 24 - 56];  /* content-code dependent field */
 306 } __packed;
 307 
 308 #define CHSC_SEI_NT0    (1ULL << 63)
 309 #define CHSC_SEI_NT2    (1ULL << 61)
 310 
 311 struct chsc_sei {
 312         struct chsc_header request;
 313         u32 reserved1;
 314         u64 ntsm;                       /* notification type mask */
 315         struct chsc_header response;
 316         u32 :24;
 317         u8 nt;
 318         union {
 319                 struct chsc_sei_nt0_area nt0_area;
 320                 struct chsc_sei_nt2_area nt2_area;
 321                 u8 nt_area[PAGE_SIZE - 24];
 322         } u;
 323 } __packed __aligned(PAGE_SIZE);
 324 
 325 /*
 326  * Link Incident Record as defined in SA22-7202, "ESCON I/O Interface"
 327  */
 328 
 329 #define LIR_IQ_CLASS_INFO               0
 330 #define LIR_IQ_CLASS_DEGRADED           1
 331 #define LIR_IQ_CLASS_NOT_OPERATIONAL    2
 332 
 333 struct lir {
 334         struct {
 335                 u32 null:1;
 336                 u32 reserved:3;
 337                 u32 class:2;
 338                 u32 reserved2:2;
 339         } __packed iq;
 340         u32 ic:8;
 341         u32 reserved:16;
 342         struct node_descriptor incident_node;
 343         struct node_descriptor attached_node;
 344         u8 reserved2[32];
 345 } __packed;
 346 
 347 #define PARAMS_LEN      10      /* PARAMS=xx,xxxxxx */
 348 #define NODEID_LEN      35      /* NODEID=tttttt/mdl,mmm.ppssssssssssss,xxxx */
 349 
 350 /* Copy EBCIDC text, convert to ASCII and optionally add delimiter. */
 351 static char *store_ebcdic(char *dest, const char *src, unsigned long len,
 352                           char delim)
 353 {
 354         memcpy(dest, src, len);
 355         EBCASC(dest, len);
 356 
 357         if (delim)
 358                 dest[len++] = delim;
 359 
 360         return dest + len;
 361 }
 362 
 363 /* Format node ID and parameters for output in LIR log message. */
 364 static void format_node_data(char *params, char *id, struct node_descriptor *nd)
 365 {
 366         memset(params, 0, PARAMS_LEN);
 367         memset(id, 0, NODEID_LEN);
 368 
 369         if (nd->validity != ND_VALIDITY_VALID) {
 370                 strncpy(params, "n/a", PARAMS_LEN - 1);
 371                 strncpy(id, "n/a", NODEID_LEN - 1);
 372                 return;
 373         }
 374 
 375         /* PARAMS=xx,xxxxxx */
 376         snprintf(params, PARAMS_LEN, "%02x,%06x", nd->byte0, nd->params);
 377         /* NODEID=tttttt/mdl,mmm.ppssssssssssss,xxxx */
 378         id = store_ebcdic(id, nd->type, sizeof(nd->type), '/');
 379         id = store_ebcdic(id, nd->model, sizeof(nd->model), ',');
 380         id = store_ebcdic(id, nd->manufacturer, sizeof(nd->manufacturer), '.');
 381         id = store_ebcdic(id, nd->plant, sizeof(nd->plant), 0);
 382         id = store_ebcdic(id, nd->seq, sizeof(nd->seq), ',');
 383         sprintf(id, "%04X", nd->tag);
 384 }
 385 
 386 static void chsc_process_sei_link_incident(struct chsc_sei_nt0_area *sei_area)
 387 {
 388         struct lir *lir = (struct lir *) &sei_area->ccdf;
 389         char iuparams[PARAMS_LEN], iunodeid[NODEID_LEN], auparams[PARAMS_LEN],
 390              aunodeid[NODEID_LEN];
 391 
 392         CIO_CRW_EVENT(4, "chsc: link incident (rs=%02x, rs_id=%04x, iq=%02x)\n",
 393                       sei_area->rs, sei_area->rsid, sei_area->ccdf[0]);
 394 
 395         /* Ignore NULL Link Incident Records. */
 396         if (lir->iq.null)
 397                 return;
 398 
 399         /* Inform user that a link requires maintenance actions because it has
 400          * become degraded or not operational. Note that this log message is
 401          * the primary intention behind a Link Incident Record. */
 402 
 403         format_node_data(iuparams, iunodeid, &lir->incident_node);
 404         format_node_data(auparams, aunodeid, &lir->attached_node);
 405 
 406         switch (lir->iq.class) {
 407         case LIR_IQ_CLASS_DEGRADED:
 408                 pr_warn("Link degraded: RS=%02x RSID=%04x IC=%02x "
 409                         "IUPARAMS=%s IUNODEID=%s AUPARAMS=%s AUNODEID=%s\n",
 410                         sei_area->rs, sei_area->rsid, lir->ic, iuparams,
 411                         iunodeid, auparams, aunodeid);
 412                 break;
 413         case LIR_IQ_CLASS_NOT_OPERATIONAL:
 414                 pr_err("Link stopped: RS=%02x RSID=%04x IC=%02x "
 415                        "IUPARAMS=%s IUNODEID=%s AUPARAMS=%s AUNODEID=%s\n",
 416                        sei_area->rs, sei_area->rsid, lir->ic, iuparams,
 417                        iunodeid, auparams, aunodeid);
 418                 break;
 419         default:
 420                 break;
 421         }
 422 }
 423 
 424 static void chsc_process_sei_res_acc(struct chsc_sei_nt0_area *sei_area)
 425 {
 426         struct channel_path *chp;
 427         struct chp_link link;
 428         struct chp_id chpid;
 429         int status;
 430 
 431         CIO_CRW_EVENT(4, "chsc: resource accessibility event (rs=%02x, "
 432                       "rs_id=%04x)\n", sei_area->rs, sei_area->rsid);
 433         if (sei_area->rs != 4)
 434                 return;
 435         chp_id_init(&chpid);
 436         chpid.id = sei_area->rsid;
 437         /* allocate a new channel path structure, if needed */
 438         status = chp_get_status(chpid);
 439         if (!status)
 440                 return;
 441 
 442         if (status < 0) {
 443                 chp_new(chpid);
 444         } else {
 445                 chp = chpid_to_chp(chpid);
 446                 mutex_lock(&chp->lock);
 447                 chp_update_desc(chp);
 448                 mutex_unlock(&chp->lock);
 449         }
 450         memset(&link, 0, sizeof(struct chp_link));
 451         link.chpid = chpid;
 452         if ((sei_area->vf & 0xc0) != 0) {
 453                 link.fla = sei_area->fla;
 454                 if ((sei_area->vf & 0xc0) == 0xc0)
 455                         /* full link address */
 456                         link.fla_mask = 0xffff;
 457                 else
 458                         /* link address */
 459                         link.fla_mask = 0xff00;
 460         }
 461         s390_process_res_acc(&link);
 462 }
 463 
 464 static void chsc_process_sei_chp_avail(struct chsc_sei_nt0_area *sei_area)
 465 {
 466         struct channel_path *chp;
 467         struct chp_id chpid;
 468         u8 *data;
 469         int num;
 470 
 471         CIO_CRW_EVENT(4, "chsc: channel path availability information\n");
 472         if (sei_area->rs != 0)
 473                 return;
 474         data = sei_area->ccdf;
 475         chp_id_init(&chpid);
 476         for (num = 0; num <= __MAX_CHPID; num++) {
 477                 if (!chp_test_bit(data, num))
 478                         continue;
 479                 chpid.id = num;
 480 
 481                 CIO_CRW_EVENT(4, "Update information for channel path "
 482                               "%x.%02x\n", chpid.cssid, chpid.id);
 483                 chp = chpid_to_chp(chpid);
 484                 if (!chp) {
 485                         chp_new(chpid);
 486                         continue;
 487                 }
 488                 mutex_lock(&chp->lock);
 489                 chp_update_desc(chp);
 490                 mutex_unlock(&chp->lock);
 491         }
 492 }
 493 
 494 struct chp_config_data {
 495         u8 map[32];
 496         u8 op;
 497         u8 pc;
 498 };
 499 
 500 static void chsc_process_sei_chp_config(struct chsc_sei_nt0_area *sei_area)
 501 {
 502         struct chp_config_data *data;
 503         struct chp_id chpid;
 504         int num;
 505         char *events[3] = {"configure", "deconfigure", "cancel deconfigure"};
 506 
 507         CIO_CRW_EVENT(4, "chsc: channel-path-configuration notification\n");
 508         if (sei_area->rs != 0)
 509                 return;
 510         data = (struct chp_config_data *) &(sei_area->ccdf);
 511         chp_id_init(&chpid);
 512         for (num = 0; num <= __MAX_CHPID; num++) {
 513                 if (!chp_test_bit(data->map, num))
 514                         continue;
 515                 chpid.id = num;
 516                 pr_notice("Processing %s for channel path %x.%02x\n",
 517                           events[data->op], chpid.cssid, chpid.id);
 518                 switch (data->op) {
 519                 case 0:
 520                         chp_cfg_schedule(chpid, 1);
 521                         break;
 522                 case 1:
 523                         chp_cfg_schedule(chpid, 0);
 524                         break;
 525                 case 2:
 526                         chp_cfg_cancel_deconfigure(chpid);
 527                         break;
 528                 }
 529         }
 530 }
 531 
 532 static void chsc_process_sei_scm_change(struct chsc_sei_nt0_area *sei_area)
 533 {
 534         int ret;
 535 
 536         CIO_CRW_EVENT(4, "chsc: scm change notification\n");
 537         if (sei_area->rs != 7)
 538                 return;
 539 
 540         ret = scm_update_information();
 541         if (ret)
 542                 CIO_CRW_EVENT(0, "chsc: updating change notification"
 543                               " failed (rc=%d).\n", ret);
 544 }
 545 
 546 static void chsc_process_sei_scm_avail(struct chsc_sei_nt0_area *sei_area)
 547 {
 548         int ret;
 549 
 550         CIO_CRW_EVENT(4, "chsc: scm available information\n");
 551         if (sei_area->rs != 7)
 552                 return;
 553 
 554         ret = scm_process_availability_information();
 555         if (ret)
 556                 CIO_CRW_EVENT(0, "chsc: process availability information"
 557                               " failed (rc=%d).\n", ret);
 558 }
 559 
 560 static void chsc_process_sei_ap_cfg_chg(struct chsc_sei_nt0_area *sei_area)
 561 {
 562         CIO_CRW_EVENT(3, "chsc: ap config changed\n");
 563         if (sei_area->rs != 5)
 564                 return;
 565 
 566         ap_bus_cfg_chg();
 567 }
 568 
 569 static void chsc_process_sei_nt2(struct chsc_sei_nt2_area *sei_area)
 570 {
 571         switch (sei_area->cc) {
 572         case 1:
 573                 zpci_event_error(sei_area->ccdf);
 574                 break;
 575         case 2:
 576                 zpci_event_availability(sei_area->ccdf);
 577                 break;
 578         default:
 579                 CIO_CRW_EVENT(2, "chsc: sei nt2 unhandled cc=%d\n",
 580                               sei_area->cc);
 581                 break;
 582         }
 583 }
 584 
 585 static void chsc_process_sei_nt0(struct chsc_sei_nt0_area *sei_area)
 586 {
 587         /* which kind of information was stored? */
 588         switch (sei_area->cc) {
 589         case 1: /* link incident*/
 590                 chsc_process_sei_link_incident(sei_area);
 591                 break;
 592         case 2: /* i/o resource accessibility */
 593                 chsc_process_sei_res_acc(sei_area);
 594                 break;
 595         case 3: /* ap config changed */
 596                 chsc_process_sei_ap_cfg_chg(sei_area);
 597                 break;
 598         case 7: /* channel-path-availability information */
 599                 chsc_process_sei_chp_avail(sei_area);
 600                 break;
 601         case 8: /* channel-path-configuration notification */
 602                 chsc_process_sei_chp_config(sei_area);
 603                 break;
 604         case 12: /* scm change notification */
 605                 chsc_process_sei_scm_change(sei_area);
 606                 break;
 607         case 14: /* scm available notification */
 608                 chsc_process_sei_scm_avail(sei_area);
 609                 break;
 610         default: /* other stuff */
 611                 CIO_CRW_EVENT(2, "chsc: sei nt0 unhandled cc=%d\n",
 612                               sei_area->cc);
 613                 break;
 614         }
 615 
 616         /* Check if we might have lost some information. */
 617         if (sei_area->flags & 0x40) {
 618                 CIO_CRW_EVENT(2, "chsc: event overflow\n");
 619                 css_schedule_eval_all();
 620         }
 621 }
 622 
 623 static void chsc_process_event_information(struct chsc_sei *sei, u64 ntsm)
 624 {
 625         static int ntsm_unsupported;
 626 
 627         while (true) {
 628                 memset(sei, 0, sizeof(*sei));
 629                 sei->request.length = 0x0010;
 630                 sei->request.code = 0x000e;
 631                 if (!ntsm_unsupported)
 632                         sei->ntsm = ntsm;
 633 
 634                 if (chsc(sei))
 635                         break;
 636 
 637                 if (sei->response.code != 0x0001) {
 638                         CIO_CRW_EVENT(2, "chsc: sei failed (rc=%04x, ntsm=%llx)\n",
 639                                       sei->response.code, sei->ntsm);
 640 
 641                         if (sei->response.code == 3 && sei->ntsm) {
 642                                 /* Fallback for old firmware. */
 643                                 ntsm_unsupported = 1;
 644                                 continue;
 645                         }
 646                         break;
 647                 }
 648 
 649                 CIO_CRW_EVENT(2, "chsc: sei successful (nt=%d)\n", sei->nt);
 650                 switch (sei->nt) {
 651                 case 0:
 652                         chsc_process_sei_nt0(&sei->u.nt0_area);
 653                         break;
 654                 case 2:
 655                         chsc_process_sei_nt2(&sei->u.nt2_area);
 656                         break;
 657                 default:
 658                         CIO_CRW_EVENT(2, "chsc: unhandled nt: %d\n", sei->nt);
 659                         break;
 660                 }
 661 
 662                 if (!(sei->u.nt0_area.flags & 0x80))
 663                         break;
 664         }
 665 }
 666 
 667 /*
 668  * Handle channel subsystem related CRWs.
 669  * Use store event information to find out what's going on.
 670  *
 671  * Note: Access to sei_page is serialized through machine check handler
 672  * thread, so no need for locking.
 673  */
 674 static void chsc_process_crw(struct crw *crw0, struct crw *crw1, int overflow)
 675 {
 676         struct chsc_sei *sei = sei_page;
 677 
 678         if (overflow) {
 679                 css_schedule_eval_all();
 680                 return;
 681         }
 682         CIO_CRW_EVENT(2, "CRW reports slct=%d, oflw=%d, "
 683                       "chn=%d, rsc=%X, anc=%d, erc=%X, rsid=%X\n",
 684                       crw0->slct, crw0->oflw, crw0->chn, crw0->rsc, crw0->anc,
 685                       crw0->erc, crw0->rsid);
 686 
 687         CIO_TRACE_EVENT(2, "prcss");
 688         chsc_process_event_information(sei, CHSC_SEI_NT0 | CHSC_SEI_NT2);
 689 }
 690 
 691 void chsc_chp_online(struct chp_id chpid)
 692 {
 693         struct channel_path *chp = chpid_to_chp(chpid);
 694         struct chp_link link;
 695         char dbf_txt[15];
 696 
 697         sprintf(dbf_txt, "cadd%x.%02x", chpid.cssid, chpid.id);
 698         CIO_TRACE_EVENT(2, dbf_txt);
 699 
 700         if (chp_get_status(chpid) != 0) {
 701                 memset(&link, 0, sizeof(struct chp_link));
 702                 link.chpid = chpid;
 703                 /* Wait until previous actions have settled. */
 704                 css_wait_for_slow_path();
 705 
 706                 mutex_lock(&chp->lock);
 707                 chp_update_desc(chp);
 708                 mutex_unlock(&chp->lock);
 709 
 710                 for_each_subchannel_staged(__s390_process_res_acc, NULL,
 711                                            &link);
 712                 css_schedule_reprobe();
 713         }
 714 }
 715 
 716 static void __s390_subchannel_vary_chpid(struct subchannel *sch,
 717                                          struct chp_id chpid, int on)
 718 {
 719         unsigned long flags;
 720         struct chp_link link;
 721 
 722         memset(&link, 0, sizeof(struct chp_link));
 723         link.chpid = chpid;
 724         spin_lock_irqsave(sch->lock, flags);
 725         if (sch->driver && sch->driver->chp_event)
 726                 sch->driver->chp_event(sch, &link,
 727                                        on ? CHP_VARY_ON : CHP_VARY_OFF);
 728         spin_unlock_irqrestore(sch->lock, flags);
 729 }
 730 
 731 static int s390_subchannel_vary_chpid_off(struct subchannel *sch, void *data)
 732 {
 733         struct chp_id *chpid = data;
 734 
 735         __s390_subchannel_vary_chpid(sch, *chpid, 0);
 736         return 0;
 737 }
 738 
 739 static int s390_subchannel_vary_chpid_on(struct subchannel *sch, void *data)
 740 {
 741         struct chp_id *chpid = data;
 742 
 743         __s390_subchannel_vary_chpid(sch, *chpid, 1);
 744         return 0;
 745 }
 746 
 747 /**
 748  * chsc_chp_vary - propagate channel-path vary operation to subchannels
 749  * @chpid: channl-path ID
 750  * @on: non-zero for vary online, zero for vary offline
 751  */
 752 int chsc_chp_vary(struct chp_id chpid, int on)
 753 {
 754         struct channel_path *chp = chpid_to_chp(chpid);
 755 
 756         /* Wait until previous actions have settled. */
 757         css_wait_for_slow_path();
 758         /*
 759          * Redo PathVerification on the devices the chpid connects to
 760          */
 761         if (on) {
 762                 /* Try to update the channel path description. */
 763                 chp_update_desc(chp);
 764                 for_each_subchannel_staged(s390_subchannel_vary_chpid_on,
 765                                            NULL, &chpid);
 766                 css_schedule_reprobe();
 767         } else
 768                 for_each_subchannel_staged(s390_subchannel_vary_chpid_off,
 769                                            NULL, &chpid);
 770 
 771         return 0;
 772 }
 773 
 774 static void
 775 chsc_remove_cmg_attr(struct channel_subsystem *css)
 776 {
 777         int i;
 778 
 779         for (i = 0; i <= __MAX_CHPID; i++) {
 780                 if (!css->chps[i])
 781                         continue;
 782                 chp_remove_cmg_attr(css->chps[i]);
 783         }
 784 }
 785 
 786 static int
 787 chsc_add_cmg_attr(struct channel_subsystem *css)
 788 {
 789         int i, ret;
 790 
 791         ret = 0;
 792         for (i = 0; i <= __MAX_CHPID; i++) {
 793                 if (!css->chps[i])
 794                         continue;
 795                 ret = chp_add_cmg_attr(css->chps[i]);
 796                 if (ret)
 797                         goto cleanup;
 798         }
 799         return ret;
 800 cleanup:
 801         for (--i; i >= 0; i--) {
 802                 if (!css->chps[i])
 803                         continue;
 804                 chp_remove_cmg_attr(css->chps[i]);
 805         }
 806         return ret;
 807 }
 808 
 809 int __chsc_do_secm(struct channel_subsystem *css, int enable)
 810 {
 811         struct {
 812                 struct chsc_header request;
 813                 u32 operation_code : 2;
 814                 u32 : 30;
 815                 u32 key : 4;
 816                 u32 : 28;
 817                 u32 zeroes1;
 818                 u32 cub_addr1;
 819                 u32 zeroes2;
 820                 u32 cub_addr2;
 821                 u32 reserved[13];
 822                 struct chsc_header response;
 823                 u32 status : 8;
 824                 u32 : 4;
 825                 u32 fmt : 4;
 826                 u32 : 16;
 827         } *secm_area;
 828         unsigned long flags;
 829         int ret, ccode;
 830 
 831         spin_lock_irqsave(&chsc_page_lock, flags);
 832         memset(chsc_page, 0, PAGE_SIZE);
 833         secm_area = chsc_page;
 834         secm_area->request.length = 0x0050;
 835         secm_area->request.code = 0x0016;
 836 
 837         secm_area->key = PAGE_DEFAULT_KEY >> 4;
 838         secm_area->cub_addr1 = (u64)(unsigned long)css->cub_addr1;
 839         secm_area->cub_addr2 = (u64)(unsigned long)css->cub_addr2;
 840 
 841         secm_area->operation_code = enable ? 0 : 1;
 842 
 843         ccode = chsc(secm_area);
 844         if (ccode > 0) {
 845                 ret = (ccode == 3) ? -ENODEV : -EBUSY;
 846                 goto out;
 847         }
 848 
 849         switch (secm_area->response.code) {
 850         case 0x0102:
 851         case 0x0103:
 852                 ret = -EINVAL;
 853                 break;
 854         default:
 855                 ret = chsc_error_from_response(secm_area->response.code);
 856         }
 857         if (ret != 0)
 858                 CIO_CRW_EVENT(2, "chsc: secm failed (rc=%04x)\n",
 859                               secm_area->response.code);
 860 out:
 861         spin_unlock_irqrestore(&chsc_page_lock, flags);
 862         return ret;
 863 }
 864 
 865 int
 866 chsc_secm(struct channel_subsystem *css, int enable)
 867 {
 868         int ret;
 869 
 870         if (enable && !css->cm_enabled) {
 871                 css->cub_addr1 = (void *)get_zeroed_page(GFP_KERNEL | GFP_DMA);
 872                 css->cub_addr2 = (void *)get_zeroed_page(GFP_KERNEL | GFP_DMA);
 873                 if (!css->cub_addr1 || !css->cub_addr2) {
 874                         free_page((unsigned long)css->cub_addr1);
 875                         free_page((unsigned long)css->cub_addr2);
 876                         return -ENOMEM;
 877                 }
 878         }
 879         ret = __chsc_do_secm(css, enable);
 880         if (!ret) {
 881                 css->cm_enabled = enable;
 882                 if (css->cm_enabled) {
 883                         ret = chsc_add_cmg_attr(css);
 884                         if (ret) {
 885                                 __chsc_do_secm(css, 0);
 886                                 css->cm_enabled = 0;
 887                         }
 888                 } else
 889                         chsc_remove_cmg_attr(css);
 890         }
 891         if (!css->cm_enabled) {
 892                 free_page((unsigned long)css->cub_addr1);
 893                 free_page((unsigned long)css->cub_addr2);
 894         }
 895         return ret;
 896 }
 897 
 898 int chsc_determine_channel_path_desc(struct chp_id chpid, int fmt, int rfmt,
 899                                      int c, int m, void *page)
 900 {
 901         struct chsc_scpd *scpd_area;
 902         int ccode, ret;
 903 
 904         if ((rfmt == 1 || rfmt == 0) && c == 1 &&
 905             !css_general_characteristics.fcs)
 906                 return -EINVAL;
 907         if ((rfmt == 2) && !css_general_characteristics.cib)
 908                 return -EINVAL;
 909         if ((rfmt == 3) && !css_general_characteristics.util_str)
 910                 return -EINVAL;
 911 
 912         memset(page, 0, PAGE_SIZE);
 913         scpd_area = page;
 914         scpd_area->request.length = 0x0010;
 915         scpd_area->request.code = 0x0002;
 916         scpd_area->cssid = chpid.cssid;
 917         scpd_area->first_chpid = chpid.id;
 918         scpd_area->last_chpid = chpid.id;
 919         scpd_area->m = m;
 920         scpd_area->c = c;
 921         scpd_area->fmt = fmt;
 922         scpd_area->rfmt = rfmt;
 923 
 924         ccode = chsc(scpd_area);
 925         if (ccode > 0)
 926                 return (ccode == 3) ? -ENODEV : -EBUSY;
 927 
 928         ret = chsc_error_from_response(scpd_area->response.code);
 929         if (ret)
 930                 CIO_CRW_EVENT(2, "chsc: scpd failed (rc=%04x)\n",
 931                               scpd_area->response.code);
 932         return ret;
 933 }
 934 EXPORT_SYMBOL_GPL(chsc_determine_channel_path_desc);
 935 
 936 #define chsc_det_chp_desc(FMT, c)                                       \
 937 int chsc_determine_fmt##FMT##_channel_path_desc(                        \
 938         struct chp_id chpid, struct channel_path_desc_fmt##FMT *desc)   \
 939 {                                                                       \
 940         struct chsc_scpd *scpd_area;                                    \
 941         unsigned long flags;                                            \
 942         int ret;                                                        \
 943                                                                         \
 944         spin_lock_irqsave(&chsc_page_lock, flags);                      \
 945         scpd_area = chsc_page;                                          \
 946         ret = chsc_determine_channel_path_desc(chpid, 0, FMT, c, 0,     \
 947                                                scpd_area);              \
 948         if (ret)                                                        \
 949                 goto out;                                               \
 950                                                                         \
 951         memcpy(desc, scpd_area->data, sizeof(*desc));                   \
 952 out:                                                                    \
 953         spin_unlock_irqrestore(&chsc_page_lock, flags);                 \
 954         return ret;                                                     \
 955 }
 956 
 957 chsc_det_chp_desc(0, 0)
 958 chsc_det_chp_desc(1, 1)
 959 chsc_det_chp_desc(3, 0)
 960 
 961 static void
 962 chsc_initialize_cmg_chars(struct channel_path *chp, u8 cmcv,
 963                           struct cmg_chars *chars)
 964 {
 965         int i, mask;
 966 
 967         for (i = 0; i < NR_MEASUREMENT_CHARS; i++) {
 968                 mask = 0x80 >> (i + 3);
 969                 if (cmcv & mask)
 970                         chp->cmg_chars.values[i] = chars->values[i];
 971                 else
 972                         chp->cmg_chars.values[i] = 0;
 973         }
 974 }
 975 
 976 int chsc_get_channel_measurement_chars(struct channel_path *chp)
 977 {
 978         unsigned long flags;
 979         int ccode, ret;
 980 
 981         struct {
 982                 struct chsc_header request;
 983                 u32 : 24;
 984                 u32 first_chpid : 8;
 985                 u32 : 24;
 986                 u32 last_chpid : 8;
 987                 u32 zeroes1;
 988                 struct chsc_header response;
 989                 u32 zeroes2;
 990                 u32 not_valid : 1;
 991                 u32 shared : 1;
 992                 u32 : 22;
 993                 u32 chpid : 8;
 994                 u32 cmcv : 5;
 995                 u32 : 11;
 996                 u32 cmgq : 8;
 997                 u32 cmg : 8;
 998                 u32 zeroes3;
 999                 u32 data[NR_MEASUREMENT_CHARS];
1000         } *scmc_area;
1001 
1002         chp->shared = -1;
1003         chp->cmg = -1;
1004 
1005         if (!css_chsc_characteristics.scmc || !css_chsc_characteristics.secm)
1006                 return -EINVAL;
1007 
1008         spin_lock_irqsave(&chsc_page_lock, flags);
1009         memset(chsc_page, 0, PAGE_SIZE);
1010         scmc_area = chsc_page;
1011         scmc_area->request.length = 0x0010;
1012         scmc_area->request.code = 0x0022;
1013         scmc_area->first_chpid = chp->chpid.id;
1014         scmc_area->last_chpid = chp->chpid.id;
1015 
1016         ccode = chsc(scmc_area);
1017         if (ccode > 0) {
1018                 ret = (ccode == 3) ? -ENODEV : -EBUSY;
1019                 goto out;
1020         }
1021 
1022         ret = chsc_error_from_response(scmc_area->response.code);
1023         if (ret) {
1024                 CIO_CRW_EVENT(2, "chsc: scmc failed (rc=%04x)\n",
1025                               scmc_area->response.code);
1026                 goto out;
1027         }
1028         if (scmc_area->not_valid)
1029                 goto out;
1030 
1031         chp->cmg = scmc_area->cmg;
1032         chp->shared = scmc_area->shared;
1033         if (chp->cmg != 2 && chp->cmg != 3) {
1034                 /* No cmg-dependent data. */
1035                 goto out;
1036         }
1037         chsc_initialize_cmg_chars(chp, scmc_area->cmcv,
1038                                   (struct cmg_chars *) &scmc_area->data);
1039 out:
1040         spin_unlock_irqrestore(&chsc_page_lock, flags);
1041         return ret;
1042 }
1043 
1044 int __init chsc_init(void)
1045 {
1046         int ret;
1047 
1048         sei_page = (void *)get_zeroed_page(GFP_KERNEL | GFP_DMA);
1049         chsc_page = (void *)get_zeroed_page(GFP_KERNEL | GFP_DMA);
1050         if (!sei_page || !chsc_page) {
1051                 ret = -ENOMEM;
1052                 goto out_err;
1053         }
1054         ret = crw_register_handler(CRW_RSC_CSS, chsc_process_crw);
1055         if (ret)
1056                 goto out_err;
1057         return ret;
1058 out_err:
1059         free_page((unsigned long)chsc_page);
1060         free_page((unsigned long)sei_page);
1061         return ret;
1062 }
1063 
1064 void __init chsc_init_cleanup(void)
1065 {
1066         crw_unregister_handler(CRW_RSC_CSS);
1067         free_page((unsigned long)chsc_page);
1068         free_page((unsigned long)sei_page);
1069 }
1070 
1071 int __chsc_enable_facility(struct chsc_sda_area *sda_area, int operation_code)
1072 {
1073         int ret;
1074 
1075         sda_area->request.length = 0x0400;
1076         sda_area->request.code = 0x0031;
1077         sda_area->operation_code = operation_code;
1078 
1079         ret = chsc(sda_area);
1080         if (ret > 0) {
1081                 ret = (ret == 3) ? -ENODEV : -EBUSY;
1082                 goto out;
1083         }
1084 
1085         switch (sda_area->response.code) {
1086         case 0x0101:
1087                 ret = -EOPNOTSUPP;
1088                 break;
1089         default:
1090                 ret = chsc_error_from_response(sda_area->response.code);
1091         }
1092 out:
1093         return ret;
1094 }
1095 
1096 int chsc_enable_facility(int operation_code)
1097 {
1098         struct chsc_sda_area *sda_area;
1099         unsigned long flags;
1100         int ret;
1101 
1102         spin_lock_irqsave(&chsc_page_lock, flags);
1103         memset(chsc_page, 0, PAGE_SIZE);
1104         sda_area = chsc_page;
1105 
1106         ret = __chsc_enable_facility(sda_area, operation_code);
1107         if (ret != 0)
1108                 CIO_CRW_EVENT(2, "chsc: sda (oc=%x) failed (rc=%04x)\n",
1109                               operation_code, sda_area->response.code);
1110 
1111         spin_unlock_irqrestore(&chsc_page_lock, flags);
1112         return ret;
1113 }
1114 
1115 int __init chsc_get_cssid(int idx)
1116 {
1117         struct {
1118                 struct chsc_header request;
1119                 u8 atype;
1120                 u32 : 24;
1121                 u32 reserved1[6];
1122                 struct chsc_header response;
1123                 u32 reserved2[3];
1124                 struct {
1125                         u8 cssid;
1126                         u32 : 24;
1127                 } list[0];
1128         } *sdcal_area;
1129         int ret;
1130 
1131         spin_lock_irq(&chsc_page_lock);
1132         memset(chsc_page, 0, PAGE_SIZE);
1133         sdcal_area = chsc_page;
1134         sdcal_area->request.length = 0x0020;
1135         sdcal_area->request.code = 0x0034;
1136         sdcal_area->atype = 4;
1137 
1138         ret = chsc(sdcal_area);
1139         if (ret) {
1140                 ret = (ret == 3) ? -ENODEV : -EBUSY;
1141                 goto exit;
1142         }
1143 
1144         ret = chsc_error_from_response(sdcal_area->response.code);
1145         if (ret) {
1146                 CIO_CRW_EVENT(2, "chsc: sdcal failed (rc=%04x)\n",
1147                               sdcal_area->response.code);
1148                 goto exit;
1149         }
1150 
1151         if ((addr_t) &sdcal_area->list[idx] <
1152             (addr_t) &sdcal_area->response + sdcal_area->response.length)
1153                 ret = sdcal_area->list[idx].cssid;
1154         else
1155                 ret = -ENODEV;
1156 exit:
1157         spin_unlock_irq(&chsc_page_lock);
1158         return ret;
1159 }
1160 
1161 struct css_general_char css_general_characteristics;
1162 struct css_chsc_char css_chsc_characteristics;
1163 
1164 int __init
1165 chsc_determine_css_characteristics(void)
1166 {
1167         unsigned long flags;
1168         int result;
1169         struct {
1170                 struct chsc_header request;
1171                 u32 reserved1;
1172                 u32 reserved2;
1173                 u32 reserved3;
1174                 struct chsc_header response;
1175                 u32 reserved4;
1176                 u32 general_char[510];
1177                 u32 chsc_char[508];
1178         } *scsc_area;
1179 
1180         spin_lock_irqsave(&chsc_page_lock, flags);
1181         memset(chsc_page, 0, PAGE_SIZE);
1182         scsc_area = chsc_page;
1183         scsc_area->request.length = 0x0010;
1184         scsc_area->request.code = 0x0010;
1185 
1186         result = chsc(scsc_area);
1187         if (result) {
1188                 result = (result == 3) ? -ENODEV : -EBUSY;
1189                 goto exit;
1190         }
1191 
1192         result = chsc_error_from_response(scsc_area->response.code);
1193         if (result == 0) {
1194                 memcpy(&css_general_characteristics, scsc_area->general_char,
1195                        sizeof(css_general_characteristics));
1196                 memcpy(&css_chsc_characteristics, scsc_area->chsc_char,
1197                        sizeof(css_chsc_characteristics));
1198         } else
1199                 CIO_CRW_EVENT(2, "chsc: scsc failed (rc=%04x)\n",
1200                               scsc_area->response.code);
1201 exit:
1202         spin_unlock_irqrestore(&chsc_page_lock, flags);
1203         return result;
1204 }
1205 
1206 EXPORT_SYMBOL_GPL(css_general_characteristics);
1207 EXPORT_SYMBOL_GPL(css_chsc_characteristics);
1208 
1209 int chsc_sstpc(void *page, unsigned int op, u16 ctrl, u64 *clock_delta)
1210 {
1211         struct {
1212                 struct chsc_header request;
1213                 unsigned int rsvd0;
1214                 unsigned int op : 8;
1215                 unsigned int rsvd1 : 8;
1216                 unsigned int ctrl : 16;
1217                 unsigned int rsvd2[5];
1218                 struct chsc_header response;
1219                 unsigned int rsvd3[3];
1220                 u64 clock_delta;
1221                 unsigned int rsvd4[2];
1222         } *rr;
1223         int rc;
1224 
1225         memset(page, 0, PAGE_SIZE);
1226         rr = page;
1227         rr->request.length = 0x0020;
1228         rr->request.code = 0x0033;
1229         rr->op = op;
1230         rr->ctrl = ctrl;
1231         rc = chsc(rr);
1232         if (rc)
1233                 return -EIO;
1234         rc = (rr->response.code == 0x0001) ? 0 : -EIO;
1235         if (clock_delta)
1236                 *clock_delta = rr->clock_delta;
1237         return rc;
1238 }
1239 
1240 int chsc_sstpi(void *page, void *result, size_t size)
1241 {
1242         struct {
1243                 struct chsc_header request;
1244                 unsigned int rsvd0[3];
1245                 struct chsc_header response;
1246                 char data[];
1247         } *rr;
1248         int rc;
1249 
1250         memset(page, 0, PAGE_SIZE);
1251         rr = page;
1252         rr->request.length = 0x0010;
1253         rr->request.code = 0x0038;
1254         rc = chsc(rr);
1255         if (rc)
1256                 return -EIO;
1257         memcpy(result, &rr->data, size);
1258         return (rr->response.code == 0x0001) ? 0 : -EIO;
1259 }
1260 
1261 int chsc_siosl(struct subchannel_id schid)
1262 {
1263         struct {
1264                 struct chsc_header request;
1265                 u32 word1;
1266                 struct subchannel_id sid;
1267                 u32 word3;
1268                 struct chsc_header response;
1269                 u32 word[11];
1270         } *siosl_area;
1271         unsigned long flags;
1272         int ccode;
1273         int rc;
1274 
1275         spin_lock_irqsave(&chsc_page_lock, flags);
1276         memset(chsc_page, 0, PAGE_SIZE);
1277         siosl_area = chsc_page;
1278         siosl_area->request.length = 0x0010;
1279         siosl_area->request.code = 0x0046;
1280         siosl_area->word1 = 0x80000000;
1281         siosl_area->sid = schid;
1282 
1283         ccode = chsc(siosl_area);
1284         if (ccode > 0) {
1285                 if (ccode == 3)
1286                         rc = -ENODEV;
1287                 else
1288                         rc = -EBUSY;
1289                 CIO_MSG_EVENT(2, "chsc: chsc failed for 0.%x.%04x (ccode=%d)\n",
1290                               schid.ssid, schid.sch_no, ccode);
1291                 goto out;
1292         }
1293         rc = chsc_error_from_response(siosl_area->response.code);
1294         if (rc)
1295                 CIO_MSG_EVENT(2, "chsc: siosl failed for 0.%x.%04x (rc=%04x)\n",
1296                               schid.ssid, schid.sch_no,
1297                               siosl_area->response.code);
1298         else
1299                 CIO_MSG_EVENT(4, "chsc: siosl succeeded for 0.%x.%04x\n",
1300                               schid.ssid, schid.sch_no);
1301 out:
1302         spin_unlock_irqrestore(&chsc_page_lock, flags);
1303         return rc;
1304 }
1305 EXPORT_SYMBOL_GPL(chsc_siosl);
1306 
1307 /**
1308  * chsc_scm_info() - store SCM information (SSI)
1309  * @scm_area: request and response block for SSI
1310  * @token: continuation token
1311  *
1312  * Returns 0 on success.
1313  */
1314 int chsc_scm_info(struct chsc_scm_info *scm_area, u64 token)
1315 {
1316         int ccode, ret;
1317 
1318         memset(scm_area, 0, sizeof(*scm_area));
1319         scm_area->request.length = 0x0020;
1320         scm_area->request.code = 0x004C;
1321         scm_area->reqtok = token;
1322 
1323         ccode = chsc(scm_area);
1324         if (ccode > 0) {
1325                 ret = (ccode == 3) ? -ENODEV : -EBUSY;
1326                 goto out;
1327         }
1328         ret = chsc_error_from_response(scm_area->response.code);
1329         if (ret != 0)
1330                 CIO_MSG_EVENT(2, "chsc: scm info failed (rc=%04x)\n",
1331                               scm_area->response.code);
1332 out:
1333         return ret;
1334 }
1335 EXPORT_SYMBOL_GPL(chsc_scm_info);
1336 
1337 /**
1338  * chsc_pnso_brinfo() - Perform Network-Subchannel Operation, Bridge Info.
1339  * @schid:              id of the subchannel on which PNSO is performed
1340  * @brinfo_area:        request and response block for the operation
1341  * @resume_token:       resume token for multiblock response
1342  * @cnc:                Boolean change-notification control
1343  *
1344  * brinfo_area must be allocated by the caller with get_zeroed_page(GFP_KERNEL)
1345  *
1346  * Returns 0 on success.
1347  */
1348 int chsc_pnso_brinfo(struct subchannel_id schid,
1349                 struct chsc_pnso_area *brinfo_area,
1350                 struct chsc_brinfo_resume_token resume_token,
1351                 int cnc)
1352 {
1353         memset(brinfo_area, 0, sizeof(*brinfo_area));
1354         brinfo_area->request.length = 0x0030;
1355         brinfo_area->request.code = 0x003d; /* network-subchannel operation */
1356         brinfo_area->m     = schid.m;
1357         brinfo_area->ssid  = schid.ssid;
1358         brinfo_area->sch   = schid.sch_no;
1359         brinfo_area->cssid = schid.cssid;
1360         brinfo_area->oc    = 0; /* Store-network-bridging-information list */
1361         brinfo_area->resume_token = resume_token;
1362         brinfo_area->n     = (cnc != 0);
1363         if (chsc(brinfo_area))
1364                 return -EIO;
1365         return chsc_error_from_response(brinfo_area->response.code);
1366 }
1367 EXPORT_SYMBOL_GPL(chsc_pnso_brinfo);
1368 
1369 int chsc_sgib(u32 origin)
1370 {
1371         struct {
1372                 struct chsc_header request;
1373                 u16 op;
1374                 u8  reserved01[2];
1375                 u8  reserved02:4;
1376                 u8  fmt:4;
1377                 u8  reserved03[7];
1378                 /* operation data area begin */
1379                 u8  reserved04[4];
1380                 u32 gib_origin;
1381                 u8  reserved05[10];
1382                 u8  aix;
1383                 u8  reserved06[4029];
1384                 struct chsc_header response;
1385                 u8  reserved07[4];
1386         } *sgib_area;
1387         int ret;
1388 
1389         spin_lock_irq(&chsc_page_lock);
1390         memset(chsc_page, 0, PAGE_SIZE);
1391         sgib_area = chsc_page;
1392         sgib_area->request.length = 0x0fe0;
1393         sgib_area->request.code = 0x0021;
1394         sgib_area->op = 0x1;
1395         sgib_area->gib_origin = origin;
1396 
1397         ret = chsc(sgib_area);
1398         if (ret == 0)
1399                 ret = chsc_error_from_response(sgib_area->response.code);
1400         spin_unlock_irq(&chsc_page_lock);
1401 
1402         return ret;
1403 }
1404 EXPORT_SYMBOL_GPL(chsc_sgib);

/* [<][>][^][v][top][bottom][index][help] */