[S390] cio: Remove grace period for vary off chpid.

The grace period handling introduced needless complexity. It didn't
help the dasd driver (which can handle terminated I/O just well),
and it doesn't help for long running channel programs (which won't
complete during the grace period anyway). Terminating I/O using a
path that just disappeared immediately is much more consistent with
what the user expects.

Signed-off-by: Cornelia Huck <cornelia.huck@de.ibm.com>
Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>

authored by Cornelia Huck and committed by Martin Schwidefsky e7769b48 78964268

+14 -76
+6 -11
drivers/s390/cio/chsc.c
··· 707 707 return chp_add(chpid); 708 708 } 709 709 710 - static inline int 711 - __check_for_io_and_kill(struct subchannel *sch, int index) 710 + static inline int check_for_io_on_path(struct subchannel *sch, int index) 712 711 { 713 712 int cc; 714 713 ··· 717 718 cc = stsch(sch->schid, &sch->schib); 718 719 if (cc) 719 720 return 0; 720 - if (sch->schib.scsw.actl && sch->schib.pmcw.lpum == (0x80 >> index)) { 721 - device_set_waiting(sch); 721 + if (sch->schib.scsw.actl && sch->schib.pmcw.lpum == (0x80 >> index)) 722 722 return 1; 723 - } 724 723 return 0; 725 724 } 726 725 ··· 747 750 } else { 748 751 sch->opm &= ~(0x80 >> chp); 749 752 sch->lpm &= ~(0x80 >> chp); 750 - /* 751 - * Give running I/O a grace period in which it 752 - * can successfully terminate, even using the 753 - * just varied off path. Then kill it. 754 - */ 755 - if (!__check_for_io_and_kill(sch, chp) && !sch->lpm) { 753 + if (check_for_io_on_path(sch, chp)) 754 + /* Path verification is done after killing. */ 755 + device_kill_io(sch); 756 + else if (!sch->lpm) { 756 757 if (css_enqueue_subchannel_slow(sch->schid)) { 757 758 css_clear_subchannel_slow_list(); 758 759 need_rescan = 1;
+1 -1
drivers/s390/cio/css.h
··· 170 170 171 171 /* Helper functions for vary on/off. */ 172 172 int device_is_online(struct subchannel *); 173 - void device_set_waiting(struct subchannel *); 173 + void device_kill_io(struct subchannel *); 174 174 175 175 /* Machine check helper function. */ 176 176 void device_kill_pending_timer(struct subchannel *);
-1
drivers/s390/cio/device.h
··· 21 21 /* states to wait for i/o completion before doing something */ 22 22 DEV_STATE_CLEAR_VERIFY, 23 23 DEV_STATE_TIMEOUT_KILL, 24 - DEV_STATE_WAIT4IO, 25 24 DEV_STATE_QUIESCE, 26 25 /* special states for devices gone not operational */ 27 26 DEV_STATE_DISCONNECTED,
+7 -61
drivers/s390/cio/device_fsm.c
··· 59 59 cdev->private->state = DEV_STATE_DISCONNECTED; 60 60 } 61 61 62 - void 63 - device_set_waiting(struct subchannel *sch) 64 - { 65 - struct ccw_device *cdev; 66 - 67 - if (!sch->dev.driver_data) 68 - return; 69 - cdev = sch->dev.driver_data; 70 - ccw_device_set_timeout(cdev, 10*HZ); 71 - cdev->private->state = DEV_STATE_WAIT4IO; 72 - } 73 - 74 62 /* 75 63 * Timeout function. It just triggers a DEV_EVENT_TIMEOUT. 76 64 */ ··· 935 947 cdev->private->state = DEV_STATE_ONLINE; 936 948 if (cdev->handler) 937 949 cdev->handler(cdev, cdev->private->intparm, 938 - ERR_PTR(-ETIMEDOUT)); 950 + ERR_PTR(-EIO)); 939 951 if (!sch->lpm) { 940 952 PREPARE_WORK(&cdev->private->kick_work, 941 953 ccw_device_nopath_notify, (void *)cdev); ··· 972 984 cdev->private->state = DEV_STATE_ONLINE; 973 985 if (cdev->handler) 974 986 cdev->handler(cdev, cdev->private->intparm, 975 - ERR_PTR(-ETIMEDOUT)); 987 + ERR_PTR(-EIO)); 976 988 } 977 989 978 - static void 979 - ccw_device_wait4io_irq(struct ccw_device *cdev, enum dev_event dev_event) 980 - { 981 - struct irb *irb; 982 - struct subchannel *sch; 983 - 984 - irb = (struct irb *) __LC_IRB; 985 - /* 986 - * Accumulate status and find out if a basic sense is needed. 987 - * This is fine since we have already adapted the lpm. 988 - */ 989 - ccw_device_accumulate_irb(cdev, irb); 990 - if (cdev->private->flags.dosense) { 991 - if (ccw_device_do_sense(cdev, irb) == 0) { 992 - cdev->private->state = DEV_STATE_W4SENSE; 993 - } 994 - return; 995 - } 996 - 997 - /* Iff device is idle, reset timeout. */ 998 - sch = to_subchannel(cdev->dev.parent); 999 - if (!stsch(sch->schid, &sch->schib)) 1000 - if (sch->schib.scsw.actl == 0) 1001 - ccw_device_set_timeout(cdev, 0); 1002 - /* Call the handler. */ 1003 - ccw_device_call_handler(cdev); 1004 - if (!sch->lpm) { 1005 - PREPARE_WORK(&cdev->private->kick_work, 1006 - ccw_device_nopath_notify, (void *)cdev); 1007 - queue_work(ccw_device_notify_work, &cdev->private->kick_work); 1008 - } else if (cdev->private->flags.doverify) 1009 - ccw_device_online_verify(cdev, 0); 1010 - } 1011 - 1012 - static void 1013 - ccw_device_wait4io_timeout(struct ccw_device *cdev, enum dev_event dev_event) 990 + void device_kill_io(struct subchannel *sch) 1014 991 { 1015 992 int ret; 1016 - struct subchannel *sch; 993 + struct ccw_device *cdev; 1017 994 1018 - sch = to_subchannel(cdev->dev.parent); 1019 - ccw_device_set_timeout(cdev, 0); 995 + cdev = sch->dev.driver_data; 1020 996 ret = ccw_device_cancel_halt_clear(cdev); 1021 997 if (ret == -EBUSY) { 1022 998 ccw_device_set_timeout(cdev, 3*HZ); ··· 999 1047 } 1000 1048 if (cdev->handler) 1001 1049 cdev->handler(cdev, cdev->private->intparm, 1002 - ERR_PTR(-ETIMEDOUT)); 1050 + ERR_PTR(-EIO)); 1003 1051 if (!sch->lpm) { 1004 1052 PREPARE_WORK(&cdev->private->kick_work, 1005 1053 ccw_device_nopath_notify, (void *)cdev); 1006 1054 queue_work(ccw_device_notify_work, &cdev->private->kick_work); 1007 - } else if (cdev->private->flags.doverify) 1055 + } else 1008 1056 /* Start delayed path verification. */ 1009 1057 ccw_device_online_verify(cdev, 0); 1010 1058 } ··· 1240 1288 [DEV_EVENT_INTERRUPT] = ccw_device_killing_irq, 1241 1289 [DEV_EVENT_TIMEOUT] = ccw_device_killing_timeout, 1242 1290 [DEV_EVENT_VERIFY] = ccw_device_nop, //FIXME 1243 - }, 1244 - [DEV_STATE_WAIT4IO] = { 1245 - [DEV_EVENT_NOTOPER] = ccw_device_online_notoper, 1246 - [DEV_EVENT_INTERRUPT] = ccw_device_wait4io_irq, 1247 - [DEV_EVENT_TIMEOUT] = ccw_device_wait4io_timeout, 1248 - [DEV_EVENT_VERIFY] = ccw_device_delay_verify, 1249 1291 }, 1250 1292 [DEV_STATE_QUIESCE] = { 1251 1293 [DEV_EVENT_NOTOPER] = ccw_device_quiesce_done,
-2
drivers/s390/cio/device_ops.c
··· 50 50 if (cdev->private->state == DEV_STATE_NOT_OPER) 51 51 return -ENODEV; 52 52 if (cdev->private->state != DEV_STATE_ONLINE && 53 - cdev->private->state != DEV_STATE_WAIT4IO && 54 53 cdev->private->state != DEV_STATE_W4SENSE) 55 54 return -EINVAL; 56 55 sch = to_subchannel(cdev->dev.parent); ··· 154 155 if (cdev->private->state == DEV_STATE_NOT_OPER) 155 156 return -ENODEV; 156 157 if (cdev->private->state != DEV_STATE_ONLINE && 157 - cdev->private->state != DEV_STATE_WAIT4IO && 158 158 cdev->private->state != DEV_STATE_W4SENSE) 159 159 return -EINVAL; 160 160 sch = to_subchannel(cdev->dev.parent);