aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/s390/cio/device_fsm.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/s390/cio/device_fsm.c')
-rw-r--r--drivers/s390/cio/device_fsm.c49
1 files changed, 33 insertions, 16 deletions
diff --git a/drivers/s390/cio/device_fsm.c b/drivers/s390/cio/device_fsm.c
index dc9373031af0..cd31bb5177e6 100644
--- a/drivers/s390/cio/device_fsm.c
+++ b/drivers/s390/cio/device_fsm.c
@@ -39,31 +39,43 @@ static void ccw_timeout_log(struct ccw_device *cdev)
39 struct schib schib; 39 struct schib schib;
40 struct subchannel *sch; 40 struct subchannel *sch;
41 struct io_subchannel_private *private; 41 struct io_subchannel_private *private;
42 union orb *orb;
42 int cc; 43 int cc;
43 44
44 sch = to_subchannel(cdev->dev.parent); 45 sch = to_subchannel(cdev->dev.parent);
45 private = to_io_private(sch); 46 private = to_io_private(sch);
47 orb = &private->orb;
46 cc = stsch(sch->schid, &schib); 48 cc = stsch(sch->schid, &schib);
47 49
48 printk(KERN_WARNING "cio: ccw device timeout occurred at %llx, " 50 printk(KERN_WARNING "cio: ccw device timeout occurred at %llx, "
49 "device information:\n", get_clock()); 51 "device information:\n", get_clock());
50 printk(KERN_WARNING "cio: orb:\n"); 52 printk(KERN_WARNING "cio: orb:\n");
51 print_hex_dump(KERN_WARNING, "cio: ", DUMP_PREFIX_NONE, 16, 1, 53 print_hex_dump(KERN_WARNING, "cio: ", DUMP_PREFIX_NONE, 16, 1,
52 &private->orb, sizeof(private->orb), 0); 54 orb, sizeof(*orb), 0);
53 printk(KERN_WARNING "cio: ccw device bus id: %s\n", cdev->dev.bus_id); 55 printk(KERN_WARNING "cio: ccw device bus id: %s\n", cdev->dev.bus_id);
54 printk(KERN_WARNING "cio: subchannel bus id: %s\n", sch->dev.bus_id); 56 printk(KERN_WARNING "cio: subchannel bus id: %s\n", sch->dev.bus_id);
55 printk(KERN_WARNING "cio: subchannel lpm: %02x, opm: %02x, " 57 printk(KERN_WARNING "cio: subchannel lpm: %02x, opm: %02x, "
56 "vpm: %02x\n", sch->lpm, sch->opm, sch->vpm); 58 "vpm: %02x\n", sch->lpm, sch->opm, sch->vpm);
57 59
58 if ((void *)(addr_t)private->orb.cpa == &private->sense_ccw || 60 if (orb->tm.b) {
59 (void *)(addr_t)private->orb.cpa == cdev->private->iccws) 61 printk(KERN_WARNING "cio: orb indicates transport mode\n");
60 printk(KERN_WARNING "cio: last channel program (intern):\n"); 62 printk(KERN_WARNING "cio: last tcw:\n");
61 else 63 print_hex_dump(KERN_WARNING, "cio: ", DUMP_PREFIX_NONE, 16, 1,
62 printk(KERN_WARNING "cio: last channel program:\n"); 64 (void *)(addr_t)orb->tm.tcw,
63 65 sizeof(struct tcw), 0);
64 print_hex_dump(KERN_WARNING, "cio: ", DUMP_PREFIX_NONE, 16, 1, 66 } else {
65 (void *)(addr_t)private->orb.cpa, 67 printk(KERN_WARNING "cio: orb indicates command mode\n");
66 sizeof(struct ccw1), 0); 68 if ((void *)(addr_t)orb->cmd.cpa == &private->sense_ccw ||
69 (void *)(addr_t)orb->cmd.cpa == cdev->private->iccws)
70 printk(KERN_WARNING "cio: last channel program "
71 "(intern):\n");
72 else
73 printk(KERN_WARNING "cio: last channel program:\n");
74
75 print_hex_dump(KERN_WARNING, "cio: ", DUMP_PREFIX_NONE, 16, 1,
76 (void *)(addr_t)orb->cmd.cpa,
77 sizeof(struct ccw1), 0);
78 }
67 printk(KERN_WARNING "cio: ccw device state: %d\n", 79 printk(KERN_WARNING "cio: ccw device state: %d\n",
68 cdev->private->state); 80 cdev->private->state);
69 printk(KERN_WARNING "cio: store subchannel returned: cc=%d\n", cc); 81 printk(KERN_WARNING "cio: store subchannel returned: cc=%d\n", cc);
@@ -135,10 +147,13 @@ ccw_device_cancel_halt_clear(struct ccw_device *cdev)
135 /* Stage 1: cancel io. */ 147 /* Stage 1: cancel io. */
136 if (!(scsw_actl(&sch->schib.scsw) & SCSW_ACTL_HALT_PEND) && 148 if (!(scsw_actl(&sch->schib.scsw) & SCSW_ACTL_HALT_PEND) &&
137 !(scsw_actl(&sch->schib.scsw) & SCSW_ACTL_CLEAR_PEND)) { 149 !(scsw_actl(&sch->schib.scsw) & SCSW_ACTL_CLEAR_PEND)) {
138 ret = cio_cancel(sch); 150 if (!scsw_is_tm(&sch->schib.scsw)) {
139 if (ret != -EINVAL) 151 ret = cio_cancel(sch);
140 return ret; 152 if (ret != -EINVAL)
141 /* cancel io unsuccessful. From now on it is asynchronous. */ 153 return ret;
154 }
155 /* cancel io unsuccessful or not applicable (transport mode).
156 * Continue with asynchronous instructions. */
142 cdev->private->iretry = 3; /* 3 halt retries. */ 157 cdev->private->iretry = 3; /* 3 halt retries. */
143 } 158 }
144 if (!(scsw_actl(&sch->schib.scsw) & SCSW_ACTL_CLEAR_PEND)) { 159 if (!(scsw_actl(&sch->schib.scsw) & SCSW_ACTL_CLEAR_PEND)) {
@@ -751,11 +766,13 @@ static void
751ccw_device_irq(struct ccw_device *cdev, enum dev_event dev_event) 766ccw_device_irq(struct ccw_device *cdev, enum dev_event dev_event)
752{ 767{
753 struct irb *irb; 768 struct irb *irb;
769 int is_cmd;
754 770
755 irb = (struct irb *) __LC_IRB; 771 irb = (struct irb *) __LC_IRB;
772 is_cmd = !scsw_is_tm(&irb->scsw);
756 /* Check for unsolicited interrupt. */ 773 /* Check for unsolicited interrupt. */
757 if (!scsw_is_solicited(&irb->scsw)) { 774 if (!scsw_is_solicited(&irb->scsw)) {
758 if ((irb->scsw.cmd.dstat & DEV_STAT_UNIT_CHECK) && 775 if (is_cmd && (irb->scsw.cmd.dstat & DEV_STAT_UNIT_CHECK) &&
759 !irb->esw.esw0.erw.cons) { 776 !irb->esw.esw0.erw.cons) {
760 /* Unit check but no sense data. Need basic sense. */ 777 /* Unit check but no sense data. Need basic sense. */
761 if (ccw_device_do_sense(cdev, irb) != 0) 778 if (ccw_device_do_sense(cdev, irb) != 0)
@@ -774,7 +791,7 @@ call_handler_unsol:
774 } 791 }
775 /* Accumulate status and find out if a basic sense is needed. */ 792 /* Accumulate status and find out if a basic sense is needed. */
776 ccw_device_accumulate_irb(cdev, irb); 793 ccw_device_accumulate_irb(cdev, irb);
777 if (cdev->private->flags.dosense) { 794 if (is_cmd && cdev->private->flags.dosense) {
778 if (ccw_device_do_sense(cdev, irb) == 0) { 795 if (ccw_device_do_sense(cdev, irb) == 0) {
779 cdev->private->state = DEV_STATE_W4SENSE; 796 cdev->private->state = DEV_STATE_W4SENSE;
780 } 797 }