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