aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/s390/cio/device_fsm.c
diff options
context:
space:
mode:
authorPeter Oberparleiter <peter.oberparleiter@de.ibm.com>2008-07-14 03:58:50 -0400
committerHeiko Carstens <heiko.carstens@de.ibm.com>2008-07-14 04:02:07 -0400
commit23d805b647db6c2063a13089497615efa9deacdd (patch)
tree87fea2384f95192b68535c7ddb1495776677ce85 /drivers/s390/cio/device_fsm.c
parent4f2bd92e3b4f3b6405c5aadae3ad64acd94cdb78 (diff)
[S390] cio: introduce fcx enabled scsw format
Extend the scsw data structure to the format required by fcx. Also provide helper functions for easier access to fields which are present in both the traditional as well as the modified format. Signed-off-by: Peter Oberparleiter <peter.oberparleiter@de.ibm.com> Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com> Signed-off-by: Heiko Carstens <heiko.carstens@de.ibm.com>
Diffstat (limited to 'drivers/s390/cio/device_fsm.c')
-rw-r--r--drivers/s390/cio/device_fsm.c49
1 files changed, 23 insertions, 26 deletions
diff --git a/drivers/s390/cio/device_fsm.c b/drivers/s390/cio/device_fsm.c
index c9b97cbc2203..dc9373031af0 100644
--- a/drivers/s390/cio/device_fsm.c
+++ b/drivers/s390/cio/device_fsm.c
@@ -133,15 +133,15 @@ ccw_device_cancel_halt_clear(struct ccw_device *cdev)
133 /* Not operational -> done. */ 133 /* Not operational -> done. */
134 return 0; 134 return 0;
135 /* Stage 1: cancel io. */ 135 /* Stage 1: cancel io. */
136 if (!(sch->schib.scsw.actl & SCSW_ACTL_HALT_PEND) && 136 if (!(scsw_actl(&sch->schib.scsw) & SCSW_ACTL_HALT_PEND) &&
137 !(sch->schib.scsw.actl & SCSW_ACTL_CLEAR_PEND)) { 137 !(scsw_actl(&sch->schib.scsw) & SCSW_ACTL_CLEAR_PEND)) {
138 ret = cio_cancel(sch); 138 ret = cio_cancel(sch);
139 if (ret != -EINVAL) 139 if (ret != -EINVAL)
140 return ret; 140 return ret;
141 /* cancel io unsuccessful. From now on it is asynchronous. */ 141 /* cancel io unsuccessful. From now on it is asynchronous. */
142 cdev->private->iretry = 3; /* 3 halt retries. */ 142 cdev->private->iretry = 3; /* 3 halt retries. */
143 } 143 }
144 if (!(sch->schib.scsw.actl & SCSW_ACTL_CLEAR_PEND)) { 144 if (!(scsw_actl(&sch->schib.scsw) & SCSW_ACTL_CLEAR_PEND)) {
145 /* Stage 2: halt io. */ 145 /* Stage 2: halt io. */
146 if (cdev->private->iretry) { 146 if (cdev->private->iretry) {
147 cdev->private->iretry--; 147 cdev->private->iretry--;
@@ -551,10 +551,11 @@ ccw_device_verify_done(struct ccw_device *cdev, int err)
551 /* Deliver fake irb to device driver, if needed. */ 551 /* Deliver fake irb to device driver, if needed. */
552 if (cdev->private->flags.fake_irb) { 552 if (cdev->private->flags.fake_irb) {
553 memset(&cdev->private->irb, 0, sizeof(struct irb)); 553 memset(&cdev->private->irb, 0, sizeof(struct irb));
554 cdev->private->irb.scsw.cc = 1; 554 cdev->private->irb.scsw.cmd.cc = 1;
555 cdev->private->irb.scsw.fctl = SCSW_FCTL_START_FUNC; 555 cdev->private->irb.scsw.cmd.fctl = SCSW_FCTL_START_FUNC;
556 cdev->private->irb.scsw.actl = SCSW_ACTL_START_PEND; 556 cdev->private->irb.scsw.cmd.actl = SCSW_ACTL_START_PEND;
557 cdev->private->irb.scsw.stctl = SCSW_STCTL_STATUS_PEND; 557 cdev->private->irb.scsw.cmd.stctl =
558 SCSW_STCTL_STATUS_PEND;
558 cdev->private->flags.fake_irb = 0; 559 cdev->private->flags.fake_irb = 0;
559 if (cdev->handler) 560 if (cdev->handler)
560 cdev->handler(cdev, cdev->private->intparm, 561 cdev->handler(cdev, cdev->private->intparm,
@@ -648,13 +649,10 @@ ccw_device_offline(struct ccw_device *cdev)
648 sch = to_subchannel(cdev->dev.parent); 649 sch = to_subchannel(cdev->dev.parent);
649 if (stsch(sch->schid, &sch->schib) || !sch->schib.pmcw.dnv) 650 if (stsch(sch->schid, &sch->schib) || !sch->schib.pmcw.dnv)
650 return -ENODEV; 651 return -ENODEV;
651 if (cdev->private->state != DEV_STATE_ONLINE) { 652 if (scsw_actl(&sch->schib.scsw) != 0)
652 if (sch->schib.scsw.actl != 0)
653 return -EBUSY;
654 return -EINVAL;
655 }
656 if (sch->schib.scsw.actl != 0)
657 return -EBUSY; 653 return -EBUSY;
654 if (cdev->private->state != DEV_STATE_ONLINE)
655 return -EINVAL;
658 /* Are we doing path grouping? */ 656 /* Are we doing path grouping? */
659 if (!cdev->private->options.pgroup) { 657 if (!cdev->private->options.pgroup) {
660 /* No, set state offline immediately. */ 658 /* No, set state offline immediately. */
@@ -729,9 +727,9 @@ ccw_device_online_verify(struct ccw_device *cdev, enum dev_event dev_event)
729 */ 727 */
730 stsch(sch->schid, &sch->schib); 728 stsch(sch->schid, &sch->schib);
731 729
732 if (sch->schib.scsw.actl != 0 || 730 if (scsw_actl(&sch->schib.scsw) != 0 ||
733 (sch->schib.scsw.stctl & SCSW_STCTL_STATUS_PEND) || 731 (scsw_stctl(&sch->schib.scsw) & SCSW_STCTL_STATUS_PEND) ||
734 (cdev->private->irb.scsw.stctl & SCSW_STCTL_STATUS_PEND)) { 732 (scsw_stctl(&cdev->private->irb.scsw) & SCSW_STCTL_STATUS_PEND)) {
735 /* 733 /*
736 * No final status yet or final status not yet delivered 734 * No final status yet or final status not yet delivered
737 * to the device driver. Can't do path verfication now, 735 * to the device driver. Can't do path verfication now,
@@ -756,10 +754,8 @@ ccw_device_irq(struct ccw_device *cdev, enum dev_event dev_event)
756 754
757 irb = (struct irb *) __LC_IRB; 755 irb = (struct irb *) __LC_IRB;
758 /* Check for unsolicited interrupt. */ 756 /* Check for unsolicited interrupt. */
759 if ((irb->scsw.stctl == 757 if (!scsw_is_solicited(&irb->scsw)) {
760 (SCSW_STCTL_STATUS_PEND | SCSW_STCTL_ALERT_STATUS)) 758 if ((irb->scsw.cmd.dstat & DEV_STAT_UNIT_CHECK) &&
761 && (!irb->scsw.cc)) {
762 if ((irb->scsw.dstat & DEV_STAT_UNIT_CHECK) &&
763 !irb->esw.esw0.erw.cons) { 759 !irb->esw.esw0.erw.cons) {
764 /* Unit check but no sense data. Need basic sense. */ 760 /* Unit check but no sense data. Need basic sense. */
765 if (ccw_device_do_sense(cdev, irb) != 0) 761 if (ccw_device_do_sense(cdev, irb) != 0)
@@ -822,9 +818,9 @@ ccw_device_w4sense(struct ccw_device *cdev, enum dev_event dev_event)
822 818
823 irb = (struct irb *) __LC_IRB; 819 irb = (struct irb *) __LC_IRB;
824 /* Check for unsolicited interrupt. */ 820 /* Check for unsolicited interrupt. */
825 if (irb->scsw.stctl == 821 if (scsw_stctl(&irb->scsw) ==
826 (SCSW_STCTL_STATUS_PEND | SCSW_STCTL_ALERT_STATUS)) { 822 (SCSW_STCTL_STATUS_PEND | SCSW_STCTL_ALERT_STATUS)) {
827 if (irb->scsw.cc == 1) 823 if (scsw_cc(&irb->scsw) == 1)
828 /* Basic sense hasn't started. Try again. */ 824 /* Basic sense hasn't started. Try again. */
829 ccw_device_do_sense(cdev, irb); 825 ccw_device_do_sense(cdev, irb);
830 else { 826 else {
@@ -842,7 +838,8 @@ ccw_device_w4sense(struct ccw_device *cdev, enum dev_event dev_event)
842 * only deliver the halt/clear interrupt to the device driver as if it 838 * only deliver the halt/clear interrupt to the device driver as if it
843 * had killed the original request. 839 * had killed the original request.
844 */ 840 */
845 if (irb->scsw.fctl & (SCSW_FCTL_CLEAR_FUNC | SCSW_FCTL_HALT_FUNC)) { 841 if (scsw_fctl(&irb->scsw) &
842 (SCSW_FCTL_CLEAR_FUNC | SCSW_FCTL_HALT_FUNC)) {
846 /* Retry Basic Sense if requested. */ 843 /* Retry Basic Sense if requested. */
847 if (cdev->private->flags.intretry) { 844 if (cdev->private->flags.intretry) {
848 cdev->private->flags.intretry = 0; 845 cdev->private->flags.intretry = 0;
@@ -949,9 +946,9 @@ ccw_device_stlck_done(struct ccw_device *cdev, enum dev_event dev_event)
949 case DEV_EVENT_INTERRUPT: 946 case DEV_EVENT_INTERRUPT:
950 irb = (struct irb *) __LC_IRB; 947 irb = (struct irb *) __LC_IRB;
951 /* Check for unsolicited interrupt. */ 948 /* Check for unsolicited interrupt. */
952 if ((irb->scsw.stctl == 949 if ((scsw_stctl(&irb->scsw) ==
953 (SCSW_STCTL_STATUS_PEND | SCSW_STCTL_ALERT_STATUS)) && 950 (SCSW_STCTL_STATUS_PEND | SCSW_STCTL_ALERT_STATUS)) &&
954 (!irb->scsw.cc)) 951 (!scsw_cc(&irb->scsw)))
955 /* FIXME: we should restart stlck here, but this 952 /* FIXME: we should restart stlck here, but this
956 * is extremely unlikely ... */ 953 * is extremely unlikely ... */
957 goto out_wakeup; 954 goto out_wakeup;