ieee1394: sbp2: fix bogus dma mapping
[sfrench/cifs-2.6.git] / drivers / s390 / cio / css.c
1 /*
2  *  drivers/s390/cio/css.c
3  *  driver for channel subsystem
4  *
5  *    Copyright (C) 2002 IBM Deutschland Entwicklung GmbH,
6  *                       IBM Corporation
7  *    Author(s): Arnd Bergmann (arndb@de.ibm.com)
8  *               Cornelia Huck (cornelia.huck@de.ibm.com)
9  */
10 #include <linux/module.h>
11 #include <linux/init.h>
12 #include <linux/device.h>
13 #include <linux/slab.h>
14 #include <linux/errno.h>
15 #include <linux/list.h>
16
17 #include "css.h"
18 #include "cio.h"
19 #include "cio_debug.h"
20 #include "ioasm.h"
21 #include "chsc.h"
22 #include "device.h"
23
24 int need_rescan = 0;
25 int css_init_done = 0;
26 static int need_reprobe = 0;
27 static int max_ssid = 0;
28
29 struct channel_subsystem *css[__MAX_CSSID + 1];
30
31 int css_characteristics_avail = 0;
32
33 inline int
34 for_each_subchannel(int(*fn)(struct subchannel_id, void *), void *data)
35 {
36         struct subchannel_id schid;
37         int ret;
38
39         init_subchannel_id(&schid);
40         ret = -ENODEV;
41         do {
42                 do {
43                         ret = fn(schid, data);
44                         if (ret)
45                                 break;
46                 } while (schid.sch_no++ < __MAX_SUBCHANNEL);
47                 schid.sch_no = 0;
48         } while (schid.ssid++ < max_ssid);
49         return ret;
50 }
51
52 static struct subchannel *
53 css_alloc_subchannel(struct subchannel_id schid)
54 {
55         struct subchannel *sch;
56         int ret;
57
58         sch = kmalloc (sizeof (*sch), GFP_KERNEL | GFP_DMA);
59         if (sch == NULL)
60                 return ERR_PTR(-ENOMEM);
61         ret = cio_validate_subchannel (sch, schid);
62         if (ret < 0) {
63                 kfree(sch);
64                 return ERR_PTR(ret);
65         }
66
67         if (sch->st != SUBCHANNEL_TYPE_IO) {
68                 /* For now we ignore all non-io subchannels. */
69                 kfree(sch);
70                 return ERR_PTR(-EINVAL);
71         }
72
73         /* 
74          * Set intparm to subchannel address.
75          * This is fine even on 64bit since the subchannel is always located
76          * under 2G.
77          */
78         sch->schib.pmcw.intparm = (__u32)(unsigned long)sch;
79         ret = cio_modify(sch);
80         if (ret) {
81                 kfree(sch);
82                 return ERR_PTR(ret);
83         }
84         return sch;
85 }
86
87 static void
88 css_free_subchannel(struct subchannel *sch)
89 {
90         if (sch) {
91                 /* Reset intparm to zeroes. */
92                 sch->schib.pmcw.intparm = 0;
93                 cio_modify(sch);
94                 kfree(sch->lock);
95                 kfree(sch);
96         }
97 }
98
99 static void
100 css_subchannel_release(struct device *dev)
101 {
102         struct subchannel *sch;
103
104         sch = to_subchannel(dev);
105         if (!cio_is_console(sch->schid)) {
106                 kfree(sch->lock);
107                 kfree(sch);
108         }
109 }
110
111 extern int css_get_ssd_info(struct subchannel *sch);
112
113
114 int css_sch_device_register(struct subchannel *sch)
115 {
116         int ret;
117
118         mutex_lock(&sch->reg_mutex);
119         ret = device_register(&sch->dev);
120         mutex_unlock(&sch->reg_mutex);
121         return ret;
122 }
123
124 void css_sch_device_unregister(struct subchannel *sch)
125 {
126         mutex_lock(&sch->reg_mutex);
127         device_unregister(&sch->dev);
128         mutex_unlock(&sch->reg_mutex);
129 }
130
131 static int
132 css_register_subchannel(struct subchannel *sch)
133 {
134         int ret;
135
136         /* Initialize the subchannel structure */
137         sch->dev.parent = &css[0]->device;
138         sch->dev.bus = &css_bus_type;
139         sch->dev.release = &css_subchannel_release;
140         sch->dev.groups = subch_attr_groups;
141
142         /* make it known to the system */
143         ret = css_sch_device_register(sch);
144         if (ret) {
145                 printk (KERN_WARNING "%s: could not register %s\n",
146                         __func__, sch->dev.bus_id);
147                 return ret;
148         }
149         css_get_ssd_info(sch);
150         return ret;
151 }
152
153 int
154 css_probe_device(struct subchannel_id schid)
155 {
156         int ret;
157         struct subchannel *sch;
158
159         sch = css_alloc_subchannel(schid);
160         if (IS_ERR(sch))
161                 return PTR_ERR(sch);
162         ret = css_register_subchannel(sch);
163         if (ret)
164                 css_free_subchannel(sch);
165         return ret;
166 }
167
168 static int
169 check_subchannel(struct device * dev, void * data)
170 {
171         struct subchannel *sch;
172         struct subchannel_id *schid = data;
173
174         sch = to_subchannel(dev);
175         return schid_equal(&sch->schid, schid);
176 }
177
178 struct subchannel *
179 get_subchannel_by_schid(struct subchannel_id schid)
180 {
181         struct device *dev;
182
183         dev = bus_find_device(&css_bus_type, NULL,
184                               &schid, check_subchannel);
185
186         return dev ? to_subchannel(dev) : NULL;
187 }
188
189 static inline int css_get_subchannel_status(struct subchannel *sch)
190 {
191         struct schib schib;
192
193         if (stsch(sch->schid, &schib) || !schib.pmcw.dnv)
194                 return CIO_GONE;
195         if (sch->schib.pmcw.dnv && (schib.pmcw.dev != sch->schib.pmcw.dev))
196                 return CIO_REVALIDATE;
197         if (!sch->lpm)
198                 return CIO_NO_PATH;
199         return CIO_OPER;
200 }
201
202 static int css_evaluate_known_subchannel(struct subchannel *sch, int slow)
203 {
204         int event, ret, disc;
205         unsigned long flags;
206         enum { NONE, UNREGISTER, UNREGISTER_PROBE, REPROBE } action;
207
208         spin_lock_irqsave(sch->lock, flags);
209         disc = device_is_disconnected(sch);
210         if (disc && slow) {
211                 /* Disconnected devices are evaluated directly only.*/
212                 spin_unlock_irqrestore(sch->lock, flags);
213                 return 0;
214         }
215         /* No interrupt after machine check - kill pending timers. */
216         device_kill_pending_timer(sch);
217         if (!disc && !slow) {
218                 /* Non-disconnected devices are evaluated on the slow path. */
219                 spin_unlock_irqrestore(sch->lock, flags);
220                 return -EAGAIN;
221         }
222         event = css_get_subchannel_status(sch);
223         CIO_MSG_EVENT(4, "Evaluating schid 0.%x.%04x, event %d, %s, %s path.\n",
224                       sch->schid.ssid, sch->schid.sch_no, event,
225                       disc ? "disconnected" : "normal",
226                       slow ? "slow" : "fast");
227         /* Analyze subchannel status. */
228         action = NONE;
229         switch (event) {
230         case CIO_NO_PATH:
231                 if (disc) {
232                         /* Check if paths have become available. */
233                         action = REPROBE;
234                         break;
235                 }
236                 /* fall through */
237         case CIO_GONE:
238                 /* Prevent unwanted effects when opening lock. */
239                 cio_disable_subchannel(sch);
240                 device_set_disconnected(sch);
241                 /* Ask driver what to do with device. */
242                 action = UNREGISTER;
243                 if (sch->driver && sch->driver->notify) {
244                         spin_unlock_irqrestore(sch->lock, flags);
245                         ret = sch->driver->notify(&sch->dev, event);
246                         spin_lock_irqsave(sch->lock, flags);
247                         if (ret)
248                                 action = NONE;
249                 }
250                 break;
251         case CIO_REVALIDATE:
252                 /* Device will be removed, so no notify necessary. */
253                 if (disc)
254                         /* Reprobe because immediate unregister might block. */
255                         action = REPROBE;
256                 else
257                         action = UNREGISTER_PROBE;
258                 break;
259         case CIO_OPER:
260                 if (disc)
261                         /* Get device operational again. */
262                         action = REPROBE;
263                 break;
264         }
265         /* Perform action. */
266         ret = 0;
267         switch (action) {
268         case UNREGISTER:
269         case UNREGISTER_PROBE:
270                 /* Unregister device (will use subchannel lock). */
271                 spin_unlock_irqrestore(sch->lock, flags);
272                 css_sch_device_unregister(sch);
273                 spin_lock_irqsave(sch->lock, flags);
274
275                 /* Reset intparm to zeroes. */
276                 sch->schib.pmcw.intparm = 0;
277                 cio_modify(sch);
278                 break;
279         case REPROBE:
280                 device_trigger_reprobe(sch);
281                 break;
282         default:
283                 break;
284         }
285         spin_unlock_irqrestore(sch->lock, flags);
286         /* Probe if necessary. */
287         if (action == UNREGISTER_PROBE)
288                 ret = css_probe_device(sch->schid);
289
290         return ret;
291 }
292
293 static int css_evaluate_new_subchannel(struct subchannel_id schid, int slow)
294 {
295         struct schib schib;
296
297         if (!slow) {
298                 /* Will be done on the slow path. */
299                 return -EAGAIN;
300         }
301         if (stsch(schid, &schib) || !schib.pmcw.dnv) {
302                 /* Unusable - ignore. */
303                 return 0;
304         }
305         CIO_MSG_EVENT(4, "Evaluating schid 0.%x.%04x, event %d, unknown, "
306                          "slow path.\n", schid.ssid, schid.sch_no, CIO_OPER);
307
308         return css_probe_device(schid);
309 }
310
311 static int css_evaluate_subchannel(struct subchannel_id schid, int slow)
312 {
313         struct subchannel *sch;
314         int ret;
315
316         sch = get_subchannel_by_schid(schid);
317         if (sch) {
318                 ret = css_evaluate_known_subchannel(sch, slow);
319                 put_device(&sch->dev);
320         } else
321                 ret = css_evaluate_new_subchannel(schid, slow);
322
323         return ret;
324 }
325
326 static int
327 css_rescan_devices(struct subchannel_id schid, void *data)
328 {
329         return css_evaluate_subchannel(schid, 1);
330 }
331
332 struct slow_subchannel {
333         struct list_head slow_list;
334         struct subchannel_id schid;
335 };
336
337 static LIST_HEAD(slow_subchannels_head);
338 static DEFINE_SPINLOCK(slow_subchannel_lock);
339
340 static void
341 css_trigger_slow_path(struct work_struct *unused)
342 {
343         CIO_TRACE_EVENT(4, "slowpath");
344
345         if (need_rescan) {
346                 need_rescan = 0;
347                 for_each_subchannel(css_rescan_devices, NULL);
348                 return;
349         }
350
351         spin_lock_irq(&slow_subchannel_lock);
352         while (!list_empty(&slow_subchannels_head)) {
353                 struct slow_subchannel *slow_sch =
354                         list_entry(slow_subchannels_head.next,
355                                    struct slow_subchannel, slow_list);
356
357                 list_del_init(slow_subchannels_head.next);
358                 spin_unlock_irq(&slow_subchannel_lock);
359                 css_evaluate_subchannel(slow_sch->schid, 1);
360                 spin_lock_irq(&slow_subchannel_lock);
361                 kfree(slow_sch);
362         }
363         spin_unlock_irq(&slow_subchannel_lock);
364 }
365
366 DECLARE_WORK(slow_path_work, css_trigger_slow_path);
367 struct workqueue_struct *slow_path_wq;
368
369 /* Reprobe subchannel if unregistered. */
370 static int reprobe_subchannel(struct subchannel_id schid, void *data)
371 {
372         struct subchannel *sch;
373         int ret;
374
375         CIO_DEBUG(KERN_INFO, 6, "cio: reprobe 0.%x.%04x\n",
376                   schid.ssid, schid.sch_no);
377         if (need_reprobe)
378                 return -EAGAIN;
379
380         sch = get_subchannel_by_schid(schid);
381         if (sch) {
382                 /* Already known. */
383                 put_device(&sch->dev);
384                 return 0;
385         }
386
387         ret = css_probe_device(schid);
388         switch (ret) {
389         case 0:
390                 break;
391         case -ENXIO:
392         case -ENOMEM:
393                 /* These should abort looping */
394                 break;
395         default:
396                 ret = 0;
397         }
398
399         return ret;
400 }
401
402 /* Work function used to reprobe all unregistered subchannels. */
403 static void reprobe_all(struct work_struct *unused)
404 {
405         int ret;
406
407         CIO_MSG_EVENT(2, "reprobe start\n");
408
409         need_reprobe = 0;
410         /* Make sure initial subchannel scan is done. */
411         wait_event(ccw_device_init_wq,
412                    atomic_read(&ccw_device_init_count) == 0);
413         ret = for_each_subchannel(reprobe_subchannel, NULL);
414
415         CIO_MSG_EVENT(2, "reprobe done (rc=%d, need_reprobe=%d)\n", ret,
416                       need_reprobe);
417 }
418
419 DECLARE_WORK(css_reprobe_work, reprobe_all);
420
421 /* Schedule reprobing of all unregistered subchannels. */
422 void css_schedule_reprobe(void)
423 {
424         need_reprobe = 1;
425         queue_work(ccw_device_work, &css_reprobe_work);
426 }
427
428 EXPORT_SYMBOL_GPL(css_schedule_reprobe);
429
430 /*
431  * Rescan for new devices. FIXME: This is slow.
432  * This function is called when we have lost CRWs due to overflows and we have
433  * to do subchannel housekeeping.
434  */
435 void
436 css_reiterate_subchannels(void)
437 {
438         css_clear_subchannel_slow_list();
439         need_rescan = 1;
440 }
441
442 /*
443  * Called from the machine check handler for subchannel report words.
444  */
445 int
446 css_process_crw(int rsid1, int rsid2)
447 {
448         int ret;
449         struct subchannel_id mchk_schid;
450
451         CIO_CRW_EVENT(2, "source is subchannel %04X, subsystem id %x\n",
452                       rsid1, rsid2);
453
454         if (need_rescan)
455                 /* We need to iterate all subchannels anyway. */
456                 return -EAGAIN;
457
458         init_subchannel_id(&mchk_schid);
459         mchk_schid.sch_no = rsid1;
460         if (rsid2 != 0)
461                 mchk_schid.ssid = (rsid2 >> 8) & 3;
462
463         /* 
464          * Since we are always presented with IPI in the CRW, we have to
465          * use stsch() to find out if the subchannel in question has come
466          * or gone.
467          */
468         ret = css_evaluate_subchannel(mchk_schid, 0);
469         if (ret == -EAGAIN) {
470                 if (css_enqueue_subchannel_slow(mchk_schid)) {
471                         css_clear_subchannel_slow_list();
472                         need_rescan = 1;
473                 }
474         }
475         return ret;
476 }
477
478 static int __init
479 __init_channel_subsystem(struct subchannel_id schid, void *data)
480 {
481         struct subchannel *sch;
482         int ret;
483
484         if (cio_is_console(schid))
485                 sch = cio_get_console_subchannel();
486         else {
487                 sch = css_alloc_subchannel(schid);
488                 if (IS_ERR(sch))
489                         ret = PTR_ERR(sch);
490                 else
491                         ret = 0;
492                 switch (ret) {
493                 case 0:
494                         break;
495                 case -ENOMEM:
496                         panic("Out of memory in init_channel_subsystem\n");
497                 /* -ENXIO: no more subchannels. */
498                 case -ENXIO:
499                         return ret;
500                 /* -EIO: this subchannel set not supported. */
501                 case -EIO:
502                         return ret;
503                 default:
504                         return 0;
505                 }
506         }
507         /*
508          * We register ALL valid subchannels in ioinfo, even those
509          * that have been present before init_channel_subsystem.
510          * These subchannels can't have been registered yet (kmalloc
511          * not working) so we do it now. This is true e.g. for the
512          * console subchannel.
513          */
514         css_register_subchannel(sch);
515         return 0;
516 }
517
518 static void __init
519 css_generate_pgid(struct channel_subsystem *css, u32 tod_high)
520 {
521         if (css_characteristics_avail && css_general_characteristics.mcss) {
522                 css->global_pgid.pgid_high.ext_cssid.version = 0x80;
523                 css->global_pgid.pgid_high.ext_cssid.cssid = css->cssid;
524         } else {
525 #ifdef CONFIG_SMP
526                 css->global_pgid.pgid_high.cpu_addr = hard_smp_processor_id();
527 #else
528                 css->global_pgid.pgid_high.cpu_addr = 0;
529 #endif
530         }
531         css->global_pgid.cpu_id = ((cpuid_t *) __LC_CPUID)->ident;
532         css->global_pgid.cpu_model = ((cpuid_t *) __LC_CPUID)->machine;
533         css->global_pgid.tod_high = tod_high;
534
535 }
536
537 static void
538 channel_subsystem_release(struct device *dev)
539 {
540         struct channel_subsystem *css;
541
542         css = to_css(dev);
543         mutex_destroy(&css->mutex);
544         kfree(css);
545 }
546
547 static ssize_t
548 css_cm_enable_show(struct device *dev, struct device_attribute *attr,
549                    char *buf)
550 {
551         struct channel_subsystem *css = to_css(dev);
552
553         if (!css)
554                 return 0;
555         return sprintf(buf, "%x\n", css->cm_enabled);
556 }
557
558 static ssize_t
559 css_cm_enable_store(struct device *dev, struct device_attribute *attr,
560                     const char *buf, size_t count)
561 {
562         struct channel_subsystem *css = to_css(dev);
563         int ret;
564
565         switch (buf[0]) {
566         case '0':
567                 ret = css->cm_enabled ? chsc_secm(css, 0) : 0;
568                 break;
569         case '1':
570                 ret = css->cm_enabled ? 0 : chsc_secm(css, 1);
571                 break;
572         default:
573                 ret = -EINVAL;
574         }
575         return ret < 0 ? ret : count;
576 }
577
578 static DEVICE_ATTR(cm_enable, 0644, css_cm_enable_show, css_cm_enable_store);
579
580 static inline int __init setup_css(int nr)
581 {
582         u32 tod_high;
583         int ret;
584
585         memset(css[nr], 0, sizeof(struct channel_subsystem));
586         css[nr]->pseudo_subchannel =
587                 kzalloc(sizeof(*css[nr]->pseudo_subchannel), GFP_KERNEL);
588         if (!css[nr]->pseudo_subchannel)
589                 return -ENOMEM;
590         css[nr]->pseudo_subchannel->dev.parent = &css[nr]->device;
591         css[nr]->pseudo_subchannel->dev.release = css_subchannel_release;
592         sprintf(css[nr]->pseudo_subchannel->dev.bus_id, "defunct");
593         ret = cio_create_sch_lock(css[nr]->pseudo_subchannel);
594         if (ret) {
595                 kfree(css[nr]->pseudo_subchannel);
596                 return ret;
597         }
598         mutex_init(&css[nr]->mutex);
599         css[nr]->valid = 1;
600         css[nr]->cssid = nr;
601         sprintf(css[nr]->device.bus_id, "css%x", nr);
602         css[nr]->device.release = channel_subsystem_release;
603         tod_high = (u32) (get_clock() >> 32);
604         css_generate_pgid(css[nr], tod_high);
605         return 0;
606 }
607
608 /*
609  * Now that the driver core is running, we can setup our channel subsystem.
610  * The struct subchannel's are created during probing (except for the
611  * static console subchannel).
612  */
613 static int __init
614 init_channel_subsystem (void)
615 {
616         int ret, i;
617
618         if (chsc_determine_css_characteristics() == 0)
619                 css_characteristics_avail = 1;
620
621         if ((ret = bus_register(&css_bus_type)))
622                 goto out;
623
624         /* Try to enable MSS. */
625         ret = chsc_enable_facility(CHSC_SDA_OC_MSS);
626         switch (ret) {
627         case 0: /* Success. */
628                 max_ssid = __MAX_SSID;
629                 break;
630         case -ENOMEM:
631                 goto out_bus;
632         default:
633                 max_ssid = 0;
634         }
635         /* Setup css structure. */
636         for (i = 0; i <= __MAX_CSSID; i++) {
637                 css[i] = kmalloc(sizeof(struct channel_subsystem), GFP_KERNEL);
638                 if (!css[i]) {
639                         ret = -ENOMEM;
640                         goto out_unregister;
641                 }
642                 ret = setup_css(i);
643                 if (ret)
644                         goto out_free;
645                 ret = device_register(&css[i]->device);
646                 if (ret)
647                         goto out_free_all;
648                 if (css_characteristics_avail &&
649                     css_chsc_characteristics.secm) {
650                         ret = device_create_file(&css[i]->device,
651                                                  &dev_attr_cm_enable);
652                         if (ret)
653                                 goto out_device;
654                 }
655                 ret = device_register(&css[i]->pseudo_subchannel->dev);
656                 if (ret)
657                         goto out_file;
658         }
659         css_init_done = 1;
660
661         ctl_set_bit(6, 28);
662
663         for_each_subchannel(__init_channel_subsystem, NULL);
664         return 0;
665 out_file:
666         device_remove_file(&css[i]->device, &dev_attr_cm_enable);
667 out_device:
668         device_unregister(&css[i]->device);
669 out_free_all:
670         kfree(css[i]->pseudo_subchannel->lock);
671         kfree(css[i]->pseudo_subchannel);
672 out_free:
673         kfree(css[i]);
674 out_unregister:
675         while (i > 0) {
676                 i--;
677                 device_unregister(&css[i]->pseudo_subchannel->dev);
678                 if (css_characteristics_avail && css_chsc_characteristics.secm)
679                         device_remove_file(&css[i]->device,
680                                            &dev_attr_cm_enable);
681                 device_unregister(&css[i]->device);
682         }
683 out_bus:
684         bus_unregister(&css_bus_type);
685 out:
686         return ret;
687 }
688
689 int sch_is_pseudo_sch(struct subchannel *sch)
690 {
691         return sch == to_css(sch->dev.parent)->pseudo_subchannel;
692 }
693
694 /*
695  * find a driver for a subchannel. They identify by the subchannel
696  * type with the exception that the console subchannel driver has its own
697  * subchannel type although the device is an i/o subchannel
698  */
699 static int
700 css_bus_match (struct device *dev, struct device_driver *drv)
701 {
702         struct subchannel *sch = container_of (dev, struct subchannel, dev);
703         struct css_driver *driver = container_of (drv, struct css_driver, drv);
704
705         if (sch->st == driver->subchannel_type)
706                 return 1;
707
708         return 0;
709 }
710
711 static int
712 css_probe (struct device *dev)
713 {
714         struct subchannel *sch;
715
716         sch = to_subchannel(dev);
717         sch->driver = container_of (dev->driver, struct css_driver, drv);
718         return (sch->driver->probe ? sch->driver->probe(sch) : 0);
719 }
720
721 static int
722 css_remove (struct device *dev)
723 {
724         struct subchannel *sch;
725
726         sch = to_subchannel(dev);
727         return (sch->driver->remove ? sch->driver->remove(sch) : 0);
728 }
729
730 static void
731 css_shutdown (struct device *dev)
732 {
733         struct subchannel *sch;
734
735         sch = to_subchannel(dev);
736         if (sch->driver->shutdown)
737                 sch->driver->shutdown(sch);
738 }
739
740 struct bus_type css_bus_type = {
741         .name     = "css",
742         .match    = css_bus_match,
743         .probe    = css_probe,
744         .remove   = css_remove,
745         .shutdown = css_shutdown,
746 };
747
748 subsys_initcall(init_channel_subsystem);
749
750 int
751 css_enqueue_subchannel_slow(struct subchannel_id schid)
752 {
753         struct slow_subchannel *new_slow_sch;
754         unsigned long flags;
755
756         new_slow_sch = kzalloc(sizeof(struct slow_subchannel), GFP_ATOMIC);
757         if (!new_slow_sch)
758                 return -ENOMEM;
759         new_slow_sch->schid = schid;
760         spin_lock_irqsave(&slow_subchannel_lock, flags);
761         list_add_tail(&new_slow_sch->slow_list, &slow_subchannels_head);
762         spin_unlock_irqrestore(&slow_subchannel_lock, flags);
763         return 0;
764 }
765
766 void
767 css_clear_subchannel_slow_list(void)
768 {
769         unsigned long flags;
770
771         spin_lock_irqsave(&slow_subchannel_lock, flags);
772         while (!list_empty(&slow_subchannels_head)) {
773                 struct slow_subchannel *slow_sch =
774                         list_entry(slow_subchannels_head.next,
775                                    struct slow_subchannel, slow_list);
776
777                 list_del_init(slow_subchannels_head.next);
778                 kfree(slow_sch);
779         }
780         spin_unlock_irqrestore(&slow_subchannel_lock, flags);
781 }
782
783
784
785 int
786 css_slow_subchannels_exist(void)
787 {
788         return (!list_empty(&slow_subchannels_head));
789 }
790
791 MODULE_LICENSE("GPL");
792 EXPORT_SYMBOL(css_bus_type);
793 EXPORT_SYMBOL_GPL(css_characteristics_avail);