3d49919a45171fa715094a9495de8abb9b91c2a4
[linux-2.6.git] / drivers / s390 / cio / chp.c
1 /*
2  *  drivers/s390/cio/chp.c
3  *
4  *    Copyright IBM Corp. 1999,2007
5  *    Author(s): Cornelia Huck (cornelia.huck@de.ibm.com)
6  *               Arnd Bergmann (arndb@de.ibm.com)
7  *               Peter Oberparleiter <peter.oberparleiter@de.ibm.com>
8  */
9
10 #include <linux/bug.h>
11 #include <linux/workqueue.h>
12 #include <linux/spinlock.h>
13 #include <linux/init.h>
14 #include <linux/jiffies.h>
15 #include <linux/wait.h>
16 #include <linux/mutex.h>
17 #include <linux/errno.h>
18 #include <asm/chpid.h>
19 #include <asm/sclp.h>
20
21 #include "cio.h"
22 #include "css.h"
23 #include "ioasm.h"
24 #include "cio_debug.h"
25 #include "chp.h"
26
27 #define to_channelpath(device) container_of(device, struct channel_path, dev)
28 #define CHP_INFO_UPDATE_INTERVAL        1*HZ
29
30 enum cfg_task_t {
31         cfg_none,
32         cfg_configure,
33         cfg_deconfigure
34 };
35
36 /* Map for pending configure tasks. */
37 static enum cfg_task_t chp_cfg_task[__MAX_CSSID + 1][__MAX_CHPID + 1];
38 static DEFINE_MUTEX(cfg_lock);
39 static int cfg_busy;
40
41 /* Map for channel-path status. */
42 static struct sclp_chp_info chp_info;
43 static DEFINE_MUTEX(info_lock);
44
45 /* Time after which channel-path status may be outdated. */
46 static unsigned long chp_info_expires;
47
48 /* Workqueue to perform pending configure tasks. */
49 static struct workqueue_struct *chp_wq;
50 static struct work_struct cfg_work;
51
52 /* Wait queue for configure completion events. */
53 static wait_queue_head_t cfg_wait_queue;
54
55 /* Return channel_path struct for given chpid. */
56 static inline struct channel_path *chpid_to_chp(struct chp_id chpid)
57 {
58         return channel_subsystems[chpid.cssid]->chps[chpid.id];
59 }
60
61 /* Set vary state for given chpid. */
62 static void set_chp_logically_online(struct chp_id chpid, int onoff)
63 {
64         chpid_to_chp(chpid)->state = onoff;
65 }
66
67 /* On succes return 0 if channel-path is varied offline, 1 if it is varied
68  * online. Return -ENODEV if channel-path is not registered. */
69 int chp_get_status(struct chp_id chpid)
70 {
71         return (chpid_to_chp(chpid) ? chpid_to_chp(chpid)->state : -ENODEV);
72 }
73
74 /**
75  * chp_get_sch_opm - return opm for subchannel
76  * @sch: subchannel
77  *
78  * Calculate and return the operational path mask (opm) based on the chpids
79  * used by the subchannel and the status of the associated channel-paths.
80  */
81 u8 chp_get_sch_opm(struct subchannel *sch)
82 {
83         struct chp_id chpid;
84         int opm;
85         int i;
86
87         opm = 0;
88         chp_id_init(&chpid);
89         for (i = 0; i < 8; i++) {
90                 opm <<= 1;
91                 chpid.id = sch->schib.pmcw.chpid[i];
92                 if (chp_get_status(chpid) != 0)
93                         opm |= 1;
94         }
95         return opm;
96 }
97
98 /**
99  * chp_is_registered - check if a channel-path is registered
100  * @chpid: channel-path ID
101  *
102  * Return non-zero if a channel-path with the given chpid is registered,
103  * zero otherwise.
104  */
105 int chp_is_registered(struct chp_id chpid)
106 {
107         return chpid_to_chp(chpid) != NULL;
108 }
109
110 /*
111  * Function: s390_vary_chpid
112  * Varies the specified chpid online or offline
113  */
114 static int s390_vary_chpid(struct chp_id chpid, int on)
115 {
116         char dbf_text[15];
117         int status;
118
119         sprintf(dbf_text, on?"varyon%x.%02x":"varyoff%x.%02x", chpid.cssid,
120                 chpid.id);
121         CIO_TRACE_EVENT(2, dbf_text);
122
123         status = chp_get_status(chpid);
124         if (!on && !status) {
125                 printk(KERN_ERR "cio: chpid %x.%02x is already offline\n",
126                        chpid.cssid, chpid.id);
127                 return -EINVAL;
128         }
129
130         set_chp_logically_online(chpid, on);
131         chsc_chp_vary(chpid, on);
132         return 0;
133 }
134
135 /*
136  * Channel measurement related functions
137  */
138 static ssize_t chp_measurement_chars_read(struct kobject *kobj,
139                                           struct bin_attribute *bin_attr,
140                                           char *buf, loff_t off, size_t count)
141 {
142         struct channel_path *chp;
143         unsigned int size;
144
145         chp = to_channelpath(container_of(kobj, struct device, kobj));
146         if (!chp->cmg_chars)
147                 return 0;
148
149         size = sizeof(struct cmg_chars);
150
151         if (off > size)
152                 return 0;
153         if (off + count > size)
154                 count = size - off;
155         memcpy(buf, chp->cmg_chars + off, count);
156         return count;
157 }
158
159 static struct bin_attribute chp_measurement_chars_attr = {
160         .attr = {
161                 .name = "measurement_chars",
162                 .mode = S_IRUSR,
163         },
164         .size = sizeof(struct cmg_chars),
165         .read = chp_measurement_chars_read,
166 };
167
168 static void chp_measurement_copy_block(struct cmg_entry *buf,
169                                        struct channel_subsystem *css,
170                                        struct chp_id chpid)
171 {
172         void *area;
173         struct cmg_entry *entry, reference_buf;
174         int idx;
175
176         if (chpid.id < 128) {
177                 area = css->cub_addr1;
178                 idx = chpid.id;
179         } else {
180                 area = css->cub_addr2;
181                 idx = chpid.id - 128;
182         }
183         entry = area + (idx * sizeof(struct cmg_entry));
184         do {
185                 memcpy(buf, entry, sizeof(*entry));
186                 memcpy(&reference_buf, entry, sizeof(*entry));
187         } while (reference_buf.values[0] != buf->values[0]);
188 }
189
190 static ssize_t chp_measurement_read(struct kobject *kobj,
191                                     struct bin_attribute *bin_attr,
192                                     char *buf, loff_t off, size_t count)
193 {
194         struct channel_path *chp;
195         struct channel_subsystem *css;
196         unsigned int size;
197
198         chp = to_channelpath(container_of(kobj, struct device, kobj));
199         css = to_css(chp->dev.parent);
200
201         size = sizeof(struct cmg_entry);
202
203         /* Only allow single reads. */
204         if (off || count < size)
205                 return 0;
206         chp_measurement_copy_block((struct cmg_entry *)buf, css, chp->chpid);
207         count = size;
208         return count;
209 }
210
211 static struct bin_attribute chp_measurement_attr = {
212         .attr = {
213                 .name = "measurement",
214                 .mode = S_IRUSR,
215         },
216         .size = sizeof(struct cmg_entry),
217         .read = chp_measurement_read,
218 };
219
220 void chp_remove_cmg_attr(struct channel_path *chp)
221 {
222         device_remove_bin_file(&chp->dev, &chp_measurement_chars_attr);
223         device_remove_bin_file(&chp->dev, &chp_measurement_attr);
224 }
225
226 int chp_add_cmg_attr(struct channel_path *chp)
227 {
228         int ret;
229
230         ret = device_create_bin_file(&chp->dev, &chp_measurement_chars_attr);
231         if (ret)
232                 return ret;
233         ret = device_create_bin_file(&chp->dev, &chp_measurement_attr);
234         if (ret)
235                 device_remove_bin_file(&chp->dev, &chp_measurement_chars_attr);
236         return ret;
237 }
238
239 /*
240  * Files for the channel path entries.
241  */
242 static ssize_t chp_status_show(struct device *dev,
243                                struct device_attribute *attr, char *buf)
244 {
245         struct channel_path *chp = container_of(dev, struct channel_path, dev);
246
247         if (!chp)
248                 return 0;
249         return (chp_get_status(chp->chpid) ? sprintf(buf, "online\n") :
250                 sprintf(buf, "offline\n"));
251 }
252
253 static ssize_t chp_status_write(struct device *dev,
254                                 struct device_attribute *attr,
255                                 const char *buf, size_t count)
256 {
257         struct channel_path *cp = container_of(dev, struct channel_path, dev);
258         char cmd[10];
259         int num_args;
260         int error;
261
262         num_args = sscanf(buf, "%5s", cmd);
263         if (!num_args)
264                 return count;
265
266         if (!strnicmp(cmd, "on", 2) || !strcmp(cmd, "1"))
267                 error = s390_vary_chpid(cp->chpid, 1);
268         else if (!strnicmp(cmd, "off", 3) || !strcmp(cmd, "0"))
269                 error = s390_vary_chpid(cp->chpid, 0);
270         else
271                 error = -EINVAL;
272
273         return error < 0 ? error : count;
274
275 }
276
277 static DEVICE_ATTR(status, 0644, chp_status_show, chp_status_write);
278
279 static ssize_t chp_configure_show(struct device *dev,
280                                   struct device_attribute *attr, char *buf)
281 {
282         struct channel_path *cp;
283         int status;
284
285         cp = container_of(dev, struct channel_path, dev);
286         status = chp_info_get_status(cp->chpid);
287         if (status < 0)
288                 return status;
289
290         return snprintf(buf, PAGE_SIZE, "%d\n", status);
291 }
292
293 static int cfg_wait_idle(void);
294
295 static ssize_t chp_configure_write(struct device *dev,
296                                    struct device_attribute *attr,
297                                    const char *buf, size_t count)
298 {
299         struct channel_path *cp;
300         int val;
301         char delim;
302
303         if (sscanf(buf, "%d %c", &val, &delim) != 1)
304                 return -EINVAL;
305         if (val != 0 && val != 1)
306                 return -EINVAL;
307         cp = container_of(dev, struct channel_path, dev);
308         chp_cfg_schedule(cp->chpid, val);
309         cfg_wait_idle();
310
311         return count;
312 }
313
314 static DEVICE_ATTR(configure, 0644, chp_configure_show, chp_configure_write);
315
316 static ssize_t chp_type_show(struct device *dev, struct device_attribute *attr,
317                              char *buf)
318 {
319         struct channel_path *chp = container_of(dev, struct channel_path, dev);
320
321         if (!chp)
322                 return 0;
323         return sprintf(buf, "%x\n", chp->desc.desc);
324 }
325
326 static DEVICE_ATTR(type, 0444, chp_type_show, NULL);
327
328 static ssize_t chp_cmg_show(struct device *dev, struct device_attribute *attr,
329                             char *buf)
330 {
331         struct channel_path *chp = to_channelpath(dev);
332
333         if (!chp)
334                 return 0;
335         if (chp->cmg == -1) /* channel measurements not available */
336                 return sprintf(buf, "unknown\n");
337         return sprintf(buf, "%x\n", chp->cmg);
338 }
339
340 static DEVICE_ATTR(cmg, 0444, chp_cmg_show, NULL);
341
342 static ssize_t chp_shared_show(struct device *dev,
343                                struct device_attribute *attr, char *buf)
344 {
345         struct channel_path *chp = to_channelpath(dev);
346
347         if (!chp)
348                 return 0;
349         if (chp->shared == -1) /* channel measurements not available */
350                 return sprintf(buf, "unknown\n");
351         return sprintf(buf, "%x\n", chp->shared);
352 }
353
354 static DEVICE_ATTR(shared, 0444, chp_shared_show, NULL);
355
356 static struct attribute *chp_attrs[] = {
357         &dev_attr_status.attr,
358         &dev_attr_configure.attr,
359         &dev_attr_type.attr,
360         &dev_attr_cmg.attr,
361         &dev_attr_shared.attr,
362         NULL,
363 };
364
365 static struct attribute_group chp_attr_group = {
366         .attrs = chp_attrs,
367 };
368
369 static void chp_release(struct device *dev)
370 {
371         struct channel_path *cp;
372
373         cp = container_of(dev, struct channel_path, dev);
374         kfree(cp);
375 }
376
377 /**
378  * chp_new - register a new channel-path
379  * @chpid - channel-path ID
380  *
381  * Create and register data structure representing new channel-path. Return
382  * zero on success, non-zero otherwise.
383  */
384 int chp_new(struct chp_id chpid)
385 {
386         struct channel_path *chp;
387         int ret;
388
389         if (chp_is_registered(chpid))
390                 return 0;
391         chp = kzalloc(sizeof(struct channel_path), GFP_KERNEL);
392         if (!chp)
393                 return -ENOMEM;
394
395         /* fill in status, etc. */
396         chp->chpid = chpid;
397         chp->state = 1;
398         chp->dev.parent = &channel_subsystems[chpid.cssid]->device;
399         chp->dev.release = chp_release;
400         snprintf(chp->dev.bus_id, BUS_ID_SIZE, "chp%x.%02x", chpid.cssid,
401                  chpid.id);
402
403         /* Obtain channel path description and fill it in. */
404         ret = chsc_determine_channel_path_description(chpid, &chp->desc);
405         if (ret)
406                 goto out_free;
407         if ((chp->desc.flags & 0x80) == 0) {
408                 ret = -ENODEV;
409                 goto out_free;
410         }
411         /* Get channel-measurement characteristics. */
412         if (css_characteristics_avail && css_chsc_characteristics.scmc
413             && css_chsc_characteristics.secm) {
414                 ret = chsc_get_channel_measurement_chars(chp);
415                 if (ret)
416                         goto out_free;
417         } else {
418                 chp->cmg = -1;
419         }
420
421         /* make it known to the system */
422         ret = device_register(&chp->dev);
423         if (ret) {
424                 CIO_MSG_EVENT(0, "Could not register chp%x.%02x: %d\n",
425                               chpid.cssid, chpid.id, ret);
426                 goto out_free;
427         }
428         ret = sysfs_create_group(&chp->dev.kobj, &chp_attr_group);
429         if (ret) {
430                 device_unregister(&chp->dev);
431                 goto out_free;
432         }
433         mutex_lock(&channel_subsystems[chpid.cssid]->mutex);
434         if (channel_subsystems[chpid.cssid]->cm_enabled) {
435                 ret = chp_add_cmg_attr(chp);
436                 if (ret) {
437                         sysfs_remove_group(&chp->dev.kobj, &chp_attr_group);
438                         device_unregister(&chp->dev);
439                         mutex_unlock(&channel_subsystems[chpid.cssid]->mutex);
440                         goto out_free;
441                 }
442         }
443         channel_subsystems[chpid.cssid]->chps[chpid.id] = chp;
444         mutex_unlock(&channel_subsystems[chpid.cssid]->mutex);
445         return ret;
446 out_free:
447         kfree(chp);
448         return ret;
449 }
450
451 /**
452  * chp_get_chp_desc - return newly allocated channel-path description
453  * @chpid: channel-path ID
454  *
455  * On success return a newly allocated copy of the channel-path description
456  * data associated with the given channel-path ID. Return %NULL on error.
457  */
458 void *chp_get_chp_desc(struct chp_id chpid)
459 {
460         struct channel_path *chp;
461         struct channel_path_desc *desc;
462
463         chp = chpid_to_chp(chpid);
464         if (!chp)
465                 return NULL;
466         desc = kmalloc(sizeof(struct channel_path_desc), GFP_KERNEL);
467         if (!desc)
468                 return NULL;
469         memcpy(desc, &chp->desc, sizeof(struct channel_path_desc));
470         return desc;
471 }
472
473 /**
474  * chp_process_crw - process channel-path status change
475  * @id: channel-path ID number
476  * @status: non-zero if channel-path has become available, zero otherwise
477  *
478  * Handle channel-report-words indicating that the status of a channel-path
479  * has changed.
480  */
481 void chp_process_crw(int id, int status)
482 {
483         struct chp_id chpid;
484
485         chp_id_init(&chpid);
486         chpid.id = id;
487         if (status) {
488                 if (!chp_is_registered(chpid))
489                         chp_new(chpid);
490                 chsc_chp_online(chpid);
491         } else
492                 chsc_chp_offline(chpid);
493 }
494
495 static inline int info_bit_num(struct chp_id id)
496 {
497         return id.id + id.cssid * (__MAX_CHPID + 1);
498 }
499
500 /* Force chp_info refresh on next call to info_validate(). */
501 static void info_expire(void)
502 {
503         mutex_lock(&info_lock);
504         chp_info_expires = jiffies - 1;
505         mutex_unlock(&info_lock);
506 }
507
508 /* Ensure that chp_info is up-to-date. */
509 static int info_update(void)
510 {
511         int rc;
512
513         mutex_lock(&info_lock);
514         rc = 0;
515         if (time_after(jiffies, chp_info_expires)) {
516                 /* Data is too old, update. */
517                 rc = sclp_chp_read_info(&chp_info);
518                 chp_info_expires = jiffies + CHP_INFO_UPDATE_INTERVAL ;
519         }
520         mutex_unlock(&info_lock);
521
522         return rc;
523 }
524
525 /**
526  * chp_info_get_status - retrieve configure status of a channel-path
527  * @chpid: channel-path ID
528  *
529  * On success, return 0 for standby, 1 for configured, 2 for reserved,
530  * 3 for not recognized. Return negative error code on error.
531  */
532 int chp_info_get_status(struct chp_id chpid)
533 {
534         int rc;
535         int bit;
536
537         rc = info_update();
538         if (rc)
539                 return rc;
540
541         bit = info_bit_num(chpid);
542         mutex_lock(&info_lock);
543         if (!chp_test_bit(chp_info.recognized, bit))
544                 rc = CHP_STATUS_NOT_RECOGNIZED;
545         else if (chp_test_bit(chp_info.configured, bit))
546                 rc = CHP_STATUS_CONFIGURED;
547         else if (chp_test_bit(chp_info.standby, bit))
548                 rc = CHP_STATUS_STANDBY;
549         else
550                 rc = CHP_STATUS_RESERVED;
551         mutex_unlock(&info_lock);
552
553         return rc;
554 }
555
556 /* Return configure task for chpid. */
557 static enum cfg_task_t cfg_get_task(struct chp_id chpid)
558 {
559         return chp_cfg_task[chpid.cssid][chpid.id];
560 }
561
562 /* Set configure task for chpid. */
563 static void cfg_set_task(struct chp_id chpid, enum cfg_task_t cfg)
564 {
565         chp_cfg_task[chpid.cssid][chpid.id] = cfg;
566 }
567
568 /* Perform one configure/deconfigure request. Reschedule work function until
569  * last request. */
570 static void cfg_func(struct work_struct *work)
571 {
572         struct chp_id chpid;
573         enum cfg_task_t t;
574
575         mutex_lock(&cfg_lock);
576         t = cfg_none;
577         chp_id_for_each(&chpid) {
578                 t = cfg_get_task(chpid);
579                 if (t != cfg_none) {
580                         cfg_set_task(chpid, cfg_none);
581                         break;
582                 }
583         }
584         mutex_unlock(&cfg_lock);
585
586         switch (t) {
587         case cfg_configure:
588                 sclp_chp_configure(chpid);
589                 info_expire();
590                 chsc_chp_online(chpid);
591                 break;
592         case cfg_deconfigure:
593                 sclp_chp_deconfigure(chpid);
594                 info_expire();
595                 chsc_chp_offline(chpid);
596                 break;
597         case cfg_none:
598                 /* Get updated information after last change. */
599                 info_update();
600                 mutex_lock(&cfg_lock);
601                 cfg_busy = 0;
602                 mutex_unlock(&cfg_lock);
603                 wake_up_interruptible(&cfg_wait_queue);
604                 return;
605         }
606         queue_work(chp_wq, &cfg_work);
607 }
608
609 /**
610  * chp_cfg_schedule - schedule chpid configuration request
611  * @chpid - channel-path ID
612  * @configure - Non-zero for configure, zero for deconfigure
613  *
614  * Schedule a channel-path configuration/deconfiguration request.
615  */
616 void chp_cfg_schedule(struct chp_id chpid, int configure)
617 {
618         CIO_MSG_EVENT(2, "chp_cfg_sched%x.%02x=%d\n", chpid.cssid, chpid.id,
619                       configure);
620         mutex_lock(&cfg_lock);
621         cfg_set_task(chpid, configure ? cfg_configure : cfg_deconfigure);
622         cfg_busy = 1;
623         mutex_unlock(&cfg_lock);
624         queue_work(chp_wq, &cfg_work);
625 }
626
627 /**
628  * chp_cfg_cancel_deconfigure - cancel chpid deconfiguration request
629  * @chpid - channel-path ID
630  *
631  * Cancel an active channel-path deconfiguration request if it has not yet
632  * been performed.
633  */
634 void chp_cfg_cancel_deconfigure(struct chp_id chpid)
635 {
636         CIO_MSG_EVENT(2, "chp_cfg_cancel:%x.%02x\n", chpid.cssid, chpid.id);
637         mutex_lock(&cfg_lock);
638         if (cfg_get_task(chpid) == cfg_deconfigure)
639                 cfg_set_task(chpid, cfg_none);
640         mutex_unlock(&cfg_lock);
641 }
642
643 static int cfg_wait_idle(void)
644 {
645         if (wait_event_interruptible(cfg_wait_queue, !cfg_busy))
646                 return -ERESTARTSYS;
647         return 0;
648 }
649
650 static int __init chp_init(void)
651 {
652         struct chp_id chpid;
653
654         chp_wq = create_singlethread_workqueue("cio_chp");
655         if (!chp_wq)
656                 return -ENOMEM;
657         INIT_WORK(&cfg_work, cfg_func);
658         init_waitqueue_head(&cfg_wait_queue);
659         if (info_update())
660                 return 0;
661         /* Register available channel-paths. */
662         chp_id_for_each(&chpid) {
663                 if (chp_info_get_status(chpid) != CHP_STATUS_NOT_RECOGNIZED)
664                         chp_new(chpid);
665         }
666
667         return 0;
668 }
669
670 subsys_initcall(chp_init);