11 #include <linux/device.h>
12 #include <linux/module.h>
14 #include <linux/slab.h>
15 #include <linux/list.h>
18 #include <asm/debug.h>
33 #define EADM_TIMEOUT (5 * HZ)
39 #define EADM_LOG(imp, txt) do { \
40 debug_text_event(eadm_debug, imp, txt); \
45 if (level > eadm_debug->
level)
48 debug_event(eadm_debug, level, data, length);
54 static void orb_init(
union orb *
orb)
56 memset(orb, 0,
sizeof(
union orb));
57 orb->
eadm.compat1 = 1;
58 orb->
eadm.compat2 = 1;
74 EADM_LOG_HEX(6, &sch->
schid,
sizeof(sch->
schid));
76 cc = ssch(sch->
schid, orb);
90 static int eadm_subchannel_clear(
struct subchannel *sch)
94 cc = csch(sch->
schid);
102 static void eadm_subchannel_timeout(
unsigned long data)
106 spin_lock_irq(sch->
lock);
108 EADM_LOG_HEX(1, &sch->
schid,
sizeof(sch->
schid));
109 if (eadm_subchannel_clear(sch))
111 spin_unlock_irq(sch->
lock);
114 static void eadm_subchannel_set_timeout(
struct subchannel *sch,
int expires)
122 if (timer_pending(&private->timer)) {
123 if (
mod_timer(&private->timer, jiffies + expires))
126 private->timer.function = eadm_subchannel_timeout;
127 private->timer.data = (
unsigned long) sch;
128 private->timer.expires =
jiffies + expires;
132 static void eadm_subchannel_irq(
struct subchannel *sch)
140 EADM_LOG_HEX(6, irb,
sizeof(*irb));
151 eadm_subchannel_set_timeout(sch, 0);
155 EADM_LOG_HEX(1, irb,
sizeof(*irb));
164 static struct subchannel *eadm_get_idle_sch(
void)
173 spin_lock(sch->
lock);
176 list_move_tail(&private->head, &eadm_list);
177 spin_unlock(sch->
lock);
178 spin_unlock_irqrestore(&
list_lock, flags);
182 spin_unlock(sch->
lock);
184 spin_unlock_irqrestore(&
list_lock, flags);
189 static int eadm_start_aob(
struct aob *aob)
196 sch = eadm_get_idle_sch();
202 ret = eadm_subchannel_start(sch, aob);
207 eadm_subchannel_set_timeout(sch, 0);
213 spin_unlock_irqrestore(sch->
lock, flags);
218 static int eadm_subchannel_probe(
struct subchannel *sch)
227 INIT_LIST_HEAD(&private->head);
230 spin_lock_irq(sch->
lock);
238 spin_unlock_irq(sch->
lock);
242 spin_unlock_irq(sch->
lock);
245 list_add(&private->head, &eadm_list);
248 if (dev_get_uevent_suppress(&sch->
dev)) {
249 dev_set_uevent_suppress(&sch->
dev, 0);
256 static void eadm_quiesce(
struct subchannel *sch)
261 spin_lock_irq(sch->
lock);
263 spin_unlock_irq(sch->
lock);
264 }
while (ret == -
EBUSY);
267 static int eadm_subchannel_remove(
struct subchannel *sch)
277 spin_lock_irq(sch->
lock);
279 spin_unlock_irq(sch->
lock);
286 static void eadm_subchannel_shutdown(
struct subchannel *sch)
291 static int eadm_subchannel_freeze(
struct subchannel *sch)
296 static int eadm_subchannel_restore(
struct subchannel *sch)
311 static int eadm_subchannel_sch_event(
struct subchannel *sch,
int process)
318 if (!device_is_registered(&sch->
dev))
333 spin_unlock_irqrestore(sch->
lock, flags);
344 static struct css_driver eadm_subchannel_driver = {
346 .name =
"eadm_subchannel",
349 .subchannel_type = eadm_subchannel_ids,
350 .irq = eadm_subchannel_irq,
351 .probe = eadm_subchannel_probe,
352 .remove = eadm_subchannel_remove,
353 .shutdown = eadm_subchannel_shutdown,
354 .sch_event = eadm_subchannel_sch_event,
355 .freeze = eadm_subchannel_freeze,
356 .thaw = eadm_subchannel_restore,
357 .restore = eadm_subchannel_restore,
365 static int __init eadm_sch_init(
void)
393 static void __exit eadm_sch_exit(
void)