diff options
Diffstat (limited to 'drivers/s390')
-rw-r--r-- | drivers/s390/cio/device_fsm.c | 50 |
1 files changed, 50 insertions, 0 deletions
diff --git a/drivers/s390/cio/device_fsm.c b/drivers/s390/cio/device_fsm.c index bfad421cda66..31c0f7885161 100644 --- a/drivers/s390/cio/device_fsm.c +++ b/drivers/s390/cio/device_fsm.c | |||
@@ -25,6 +25,8 @@ | |||
25 | #include "ioasm.h" | 25 | #include "ioasm.h" |
26 | #include "chp.h" | 26 | #include "chp.h" |
27 | 27 | ||
28 | static int timeout_log_enabled; | ||
29 | |||
28 | int | 30 | int |
29 | device_is_online(struct subchannel *sch) | 31 | device_is_online(struct subchannel *sch) |
30 | { | 32 | { |
@@ -82,6 +84,52 @@ int device_trigger_verify(struct subchannel *sch) | |||
82 | return 0; | 84 | return 0; |
83 | } | 85 | } |
84 | 86 | ||
87 | static int __init ccw_timeout_log_setup(char *unused) | ||
88 | { | ||
89 | timeout_log_enabled = 1; | ||
90 | return 1; | ||
91 | } | ||
92 | |||
93 | __setup("ccw_timeout_log", ccw_timeout_log_setup); | ||
94 | |||
95 | static void ccw_timeout_log(struct ccw_device *cdev) | ||
96 | { | ||
97 | struct schib schib; | ||
98 | struct subchannel *sch; | ||
99 | int cc; | ||
100 | |||
101 | sch = to_subchannel(cdev->dev.parent); | ||
102 | cc = stsch(sch->schid, &schib); | ||
103 | |||
104 | printk(KERN_WARNING "cio: ccw device timeout occurred at %llx, " | ||
105 | "device information:\n", get_clock()); | ||
106 | printk(KERN_WARNING "cio: orb:\n"); | ||
107 | print_hex_dump(KERN_WARNING, "cio: ", DUMP_PREFIX_NONE, 16, 1, | ||
108 | &sch->orb, sizeof(sch->orb), 0); | ||
109 | printk(KERN_WARNING "cio: ccw device bus id: %s\n", cdev->dev.bus_id); | ||
110 | printk(KERN_WARNING "cio: subchannel bus id: %s\n", sch->dev.bus_id); | ||
111 | printk(KERN_WARNING "cio: subchannel lpm: %02x, opm: %02x, " | ||
112 | "vpm: %02x\n", sch->lpm, sch->opm, sch->vpm); | ||
113 | |||
114 | if ((void *)(addr_t)sch->orb.cpa == &sch->sense_ccw || | ||
115 | (void *)(addr_t)sch->orb.cpa == cdev->private->iccws) | ||
116 | printk(KERN_WARNING "cio: last channel program (intern):\n"); | ||
117 | else | ||
118 | printk(KERN_WARNING "cio: last channel program:\n"); | ||
119 | |||
120 | print_hex_dump(KERN_WARNING, "cio: ", DUMP_PREFIX_NONE, 16, 1, | ||
121 | (void *)(addr_t)sch->orb.cpa, sizeof(struct ccw1), 0); | ||
122 | printk(KERN_WARNING "cio: ccw device state: %d\n", | ||
123 | cdev->private->state); | ||
124 | printk(KERN_WARNING "cio: store subchannel returned: cc=%d\n", cc); | ||
125 | printk(KERN_WARNING "cio: schib:\n"); | ||
126 | print_hex_dump(KERN_WARNING, "cio: ", DUMP_PREFIX_NONE, 16, 1, | ||
127 | &schib, sizeof(schib), 0); | ||
128 | printk(KERN_WARNING "cio: ccw device flags:\n"); | ||
129 | print_hex_dump(KERN_WARNING, "cio: ", DUMP_PREFIX_NONE, 16, 1, | ||
130 | &cdev->private->flags, sizeof(cdev->private->flags), 0); | ||
131 | } | ||
132 | |||
85 | /* | 133 | /* |
86 | * Timeout function. It just triggers a DEV_EVENT_TIMEOUT. | 134 | * Timeout function. It just triggers a DEV_EVENT_TIMEOUT. |
87 | */ | 135 | */ |
@@ -92,6 +140,8 @@ ccw_device_timeout(unsigned long data) | |||
92 | 140 | ||
93 | cdev = (struct ccw_device *) data; | 141 | cdev = (struct ccw_device *) data; |
94 | spin_lock_irq(cdev->ccwlock); | 142 | spin_lock_irq(cdev->ccwlock); |
143 | if (timeout_log_enabled) | ||
144 | ccw_timeout_log(cdev); | ||
95 | dev_fsm_event(cdev, DEV_EVENT_TIMEOUT); | 145 | dev_fsm_event(cdev, DEV_EVENT_TIMEOUT); |
96 | spin_unlock_irq(cdev->ccwlock); | 146 | spin_unlock_irq(cdev->ccwlock); |
97 | } | 147 | } |