aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@woody.linux-foundation.org>2007-03-06 22:52:50 -0500
committerLinus Torvalds <torvalds@woody.linux-foundation.org>2007-03-06 22:52:50 -0500
commitfe1b4ba400193176213f95be3ea711a53518a609 (patch)
treee60943d4703fca5a291fffc2e0b77a786b6db3f4 /drivers
parentae5dd8e346efc25a5f9cc9d01bc0915c40eb38d9 (diff)
parent2470b648e17e0216922bb78c7f05b4668402459a (diff)
Merge branch 'for-linus' of git://git390.osdl.marist.edu/pub/scm/linux-2.6
* 'for-linus' of git://git390.osdl.marist.edu/pub/scm/linux-2.6: [S390] cio: Call cancel_halt_clear even when actl == 0. [S390] cio: Use path verification to check for path state. [S390] cio: Fix locking when calling notify function. [S390] Fixed handling of access register mode faults. [S390] dasd: Use default recovery for SNSS requests [S390] check_bugs() should be inline. [S390] tape: Compression overwrites crypto setting [S390] nss: disable kexec. [S390] reipl: move dump_prefix_page out of text section. [S390] smp: disable preemption in smp_call_function/smp_call_function_on [S390] kprobes breaks BUG_ON
Diffstat (limited to 'drivers')
-rw-r--r--drivers/s390/block/dasd_eer.c1
-rw-r--r--drivers/s390/char/tape_std.c5
-rw-r--r--drivers/s390/cio/device_fsm.c117
3 files changed, 60 insertions, 63 deletions
diff --git a/drivers/s390/block/dasd_eer.c b/drivers/s390/block/dasd_eer.c
index 4b8a95fba1e5..a1dc8c466ec9 100644
--- a/drivers/s390/block/dasd_eer.c
+++ b/drivers/s390/block/dasd_eer.c
@@ -461,6 +461,7 @@ int dasd_eer_enable(struct dasd_device *device)
461 cqr->device = device; 461 cqr->device = device;
462 cqr->retries = 255; 462 cqr->retries = 255;
463 cqr->expires = 10 * HZ; 463 cqr->expires = 10 * HZ;
464 clear_bit(DASD_CQR_FLAGS_USE_ERP, &cqr->flags);
464 465
465 cqr->cpaddr->cmd_code = DASD_ECKD_CCW_SNSS; 466 cqr->cpaddr->cmd_code = DASD_ECKD_CCW_SNSS;
466 cqr->cpaddr->count = SNSS_DATA_SIZE; 467 cqr->cpaddr->count = SNSS_DATA_SIZE;
diff --git a/drivers/s390/char/tape_std.c b/drivers/s390/char/tape_std.c
index 7a76ec413a3a..2a1af4e60be0 100644
--- a/drivers/s390/char/tape_std.c
+++ b/drivers/s390/char/tape_std.c
@@ -647,7 +647,10 @@ tape_std_mtcompression(struct tape_device *device, int mt_count)
647 return PTR_ERR(request); 647 return PTR_ERR(request);
648 request->op = TO_NOP; 648 request->op = TO_NOP;
649 /* setup ccws */ 649 /* setup ccws */
650 *device->modeset_byte = (mt_count == 0) ? 0x00 : 0x08; 650 if (mt_count == 0)
651 *device->modeset_byte &= ~0x08;
652 else
653 *device->modeset_byte |= 0x08;
651 tape_ccw_cc(request->cpaddr, MODE_SET_DB, 1, device->modeset_byte); 654 tape_ccw_cc(request->cpaddr, MODE_SET_DB, 1, device->modeset_byte);
652 tape_ccw_end(request->cpaddr + 1, NOP, 0, NULL); 655 tape_ccw_end(request->cpaddr + 1, NOP, 0, NULL);
653 /* execute it */ 656 /* execute it */
diff --git a/drivers/s390/cio/device_fsm.c b/drivers/s390/cio/device_fsm.c
index 51238e7555bb..089a3ddd6265 100644
--- a/drivers/s390/cio/device_fsm.c
+++ b/drivers/s390/cio/device_fsm.c
@@ -144,8 +144,8 @@ ccw_device_cancel_halt_clear(struct ccw_device *cdev)
144 ret = stsch(sch->schid, &sch->schib); 144 ret = stsch(sch->schid, &sch->schib);
145 if (ret || !sch->schib.pmcw.dnv) 145 if (ret || !sch->schib.pmcw.dnv)
146 return -ENODEV; 146 return -ENODEV;
147 if (!sch->schib.pmcw.ena || sch->schib.scsw.actl == 0) 147 if (!sch->schib.pmcw.ena)
148 /* Not operational or no activity -> done. */ 148 /* Not operational -> done. */
149 return 0; 149 return 0;
150 /* Stage 1: cancel io. */ 150 /* Stage 1: cancel io. */
151 if (!(sch->schib.scsw.actl & SCSW_ACTL_HALT_PEND) && 151 if (!(sch->schib.scsw.actl & SCSW_ACTL_HALT_PEND) &&
@@ -334,20 +334,29 @@ ccw_device_oper_notify(struct work_struct *work)
334 struct ccw_device *cdev; 334 struct ccw_device *cdev;
335 struct subchannel *sch; 335 struct subchannel *sch;
336 int ret; 336 int ret;
337 unsigned long flags;
337 338
338 priv = container_of(work, struct ccw_device_private, kick_work); 339 priv = container_of(work, struct ccw_device_private, kick_work);
339 cdev = priv->cdev; 340 cdev = priv->cdev;
341 spin_lock_irqsave(cdev->ccwlock, flags);
340 sch = to_subchannel(cdev->dev.parent); 342 sch = to_subchannel(cdev->dev.parent);
341 ret = (sch->driver && sch->driver->notify) ? 343 if (sch->driver && sch->driver->notify) {
342 sch->driver->notify(&sch->dev, CIO_OPER) : 0; 344 spin_unlock_irqrestore(cdev->ccwlock, flags);
343 if (!ret) 345 ret = sch->driver->notify(&sch->dev, CIO_OPER);
344 /* Driver doesn't want device back. */ 346 spin_lock_irqsave(cdev->ccwlock, flags);
345 ccw_device_do_unreg_rereg(work); 347 } else
346 else { 348 ret = 0;
349 if (ret) {
347 /* Reenable channel measurements, if needed. */ 350 /* Reenable channel measurements, if needed. */
351 spin_unlock_irqrestore(cdev->ccwlock, flags);
348 cmf_reenable(cdev); 352 cmf_reenable(cdev);
353 spin_lock_irqsave(cdev->ccwlock, flags);
349 wake_up(&cdev->private->wait_q); 354 wake_up(&cdev->private->wait_q);
350 } 355 }
356 spin_unlock_irqrestore(cdev->ccwlock, flags);
357 if (!ret)
358 /* Driver doesn't want device back. */
359 ccw_device_do_unreg_rereg(work);
351} 360}
352 361
353/* 362/*
@@ -534,15 +543,21 @@ ccw_device_nopath_notify(struct work_struct *work)
534 struct ccw_device *cdev; 543 struct ccw_device *cdev;
535 struct subchannel *sch; 544 struct subchannel *sch;
536 int ret; 545 int ret;
546 unsigned long flags;
537 547
538 priv = container_of(work, struct ccw_device_private, kick_work); 548 priv = container_of(work, struct ccw_device_private, kick_work);
539 cdev = priv->cdev; 549 cdev = priv->cdev;
550 spin_lock_irqsave(cdev->ccwlock, flags);
540 sch = to_subchannel(cdev->dev.parent); 551 sch = to_subchannel(cdev->dev.parent);
541 /* Extra sanity. */ 552 /* Extra sanity. */
542 if (sch->lpm) 553 if (sch->lpm)
543 return; 554 goto out_unlock;
544 ret = (sch->driver && sch->driver->notify) ? 555 if (sch->driver && sch->driver->notify) {
545 sch->driver->notify(&sch->dev, CIO_NO_PATH) : 0; 556 spin_unlock_irqrestore(cdev->ccwlock, flags);
557 ret = sch->driver->notify(&sch->dev, CIO_NO_PATH);
558 spin_lock_irqsave(cdev->ccwlock, flags);
559 } else
560 ret = 0;
546 if (!ret) { 561 if (!ret) {
547 if (get_device(&sch->dev)) { 562 if (get_device(&sch->dev)) {
548 /* Driver doesn't want to keep device. */ 563 /* Driver doesn't want to keep device. */
@@ -562,6 +577,8 @@ ccw_device_nopath_notify(struct work_struct *work)
562 cdev->private->state = DEV_STATE_DISCONNECTED; 577 cdev->private->state = DEV_STATE_DISCONNECTED;
563 wake_up(&cdev->private->wait_q); 578 wake_up(&cdev->private->wait_q);
564 } 579 }
580out_unlock:
581 spin_unlock_irqrestore(cdev->ccwlock, flags);
565} 582}
566 583
567void 584void
@@ -607,10 +624,13 @@ ccw_device_verify_done(struct ccw_device *cdev, int err)
607 default: 624 default:
608 /* Reset oper notify indication after verify error. */ 625 /* Reset oper notify indication after verify error. */
609 cdev->private->flags.donotify = 0; 626 cdev->private->flags.donotify = 0;
610 PREPARE_WORK(&cdev->private->kick_work, 627 if (cdev->online) {
611 ccw_device_nopath_notify); 628 PREPARE_WORK(&cdev->private->kick_work,
612 queue_work(ccw_device_notify_work, &cdev->private->kick_work); 629 ccw_device_nopath_notify);
613 ccw_device_done(cdev, DEV_STATE_NOT_OPER); 630 queue_work(ccw_device_notify_work,
631 &cdev->private->kick_work);
632 } else
633 ccw_device_done(cdev, DEV_STATE_NOT_OPER);
614 break; 634 break;
615 } 635 }
616} 636}
@@ -756,15 +776,22 @@ static void
756ccw_device_online_notoper(struct ccw_device *cdev, enum dev_event dev_event) 776ccw_device_online_notoper(struct ccw_device *cdev, enum dev_event dev_event)
757{ 777{
758 struct subchannel *sch; 778 struct subchannel *sch;
779 int ret;
759 780
760 sch = to_subchannel(cdev->dev.parent); 781 sch = to_subchannel(cdev->dev.parent);
761 if (sch->driver->notify && 782 if (sch->driver->notify) {
762 sch->driver->notify(&sch->dev, sch->lpm ? CIO_GONE : CIO_NO_PATH)) { 783 spin_unlock_irq(cdev->ccwlock);
763 ccw_device_set_timeout(cdev, 0); 784 ret = sch->driver->notify(&sch->dev,
764 cdev->private->flags.fake_irb = 0; 785 sch->lpm ? CIO_GONE : CIO_NO_PATH);
765 cdev->private->state = DEV_STATE_DISCONNECTED; 786 spin_lock_irq(cdev->ccwlock);
766 wake_up(&cdev->private->wait_q); 787 } else
767 return; 788 ret = 0;
789 if (ret) {
790 ccw_device_set_timeout(cdev, 0);
791 cdev->private->flags.fake_irb = 0;
792 cdev->private->state = DEV_STATE_DISCONNECTED;
793 wake_up(&cdev->private->wait_q);
794 return;
768 } 795 }
769 cdev->private->state = DEV_STATE_NOT_OPER; 796 cdev->private->state = DEV_STATE_NOT_OPER;
770 cio_disable_subchannel(sch); 797 cio_disable_subchannel(sch);
@@ -969,18 +996,12 @@ ccw_device_killing_irq(struct ccw_device *cdev, enum dev_event dev_event)
969 996
970 sch = to_subchannel(cdev->dev.parent); 997 sch = to_subchannel(cdev->dev.parent);
971 ccw_device_set_timeout(cdev, 0); 998 ccw_device_set_timeout(cdev, 0);
999 /* Start delayed path verification. */
1000 ccw_device_online_verify(cdev, 0);
972 /* OK, i/o is dead now. Call interrupt handler. */ 1001 /* OK, i/o is dead now. Call interrupt handler. */
973 cdev->private->state = DEV_STATE_ONLINE;
974 if (cdev->handler) 1002 if (cdev->handler)
975 cdev->handler(cdev, cdev->private->intparm, 1003 cdev->handler(cdev, cdev->private->intparm,
976 ERR_PTR(-EIO)); 1004 ERR_PTR(-EIO));
977 if (!sch->lpm) {
978 PREPARE_WORK(&cdev->private->kick_work,
979 ccw_device_nopath_notify);
980 queue_work(ccw_device_notify_work, &cdev->private->kick_work);
981 } else if (cdev->private->flags.doverify)
982 /* Start delayed path verification. */
983 ccw_device_online_verify(cdev, 0);
984} 1005}
985 1006
986static void 1007static void
@@ -993,21 +1014,8 @@ ccw_device_killing_timeout(struct ccw_device *cdev, enum dev_event dev_event)
993 ccw_device_set_timeout(cdev, 3*HZ); 1014 ccw_device_set_timeout(cdev, 3*HZ);
994 return; 1015 return;
995 } 1016 }
996 if (ret == -ENODEV) { 1017 /* Start delayed path verification. */
997 struct subchannel *sch; 1018 ccw_device_online_verify(cdev, 0);
998
999 sch = to_subchannel(cdev->dev.parent);
1000 if (!sch->lpm) {
1001 PREPARE_WORK(&cdev->private->kick_work,
1002 ccw_device_nopath_notify);
1003 queue_work(ccw_device_notify_work,
1004 &cdev->private->kick_work);
1005 } else
1006 dev_fsm_event(cdev, DEV_EVENT_NOTOPER);
1007 return;
1008 }
1009 //FIXME: Can we get here?
1010 cdev->private->state = DEV_STATE_ONLINE;
1011 if (cdev->handler) 1019 if (cdev->handler)
1012 cdev->handler(cdev, cdev->private->intparm, 1020 cdev->handler(cdev, cdev->private->intparm,
1013 ERR_PTR(-EIO)); 1021 ERR_PTR(-EIO));
@@ -1025,26 +1033,11 @@ void device_kill_io(struct subchannel *sch)
1025 cdev->private->state = DEV_STATE_TIMEOUT_KILL; 1033 cdev->private->state = DEV_STATE_TIMEOUT_KILL;
1026 return; 1034 return;
1027 } 1035 }
1028 if (ret == -ENODEV) { 1036 /* Start delayed path verification. */
1029 if (!sch->lpm) { 1037 ccw_device_online_verify(cdev, 0);
1030 PREPARE_WORK(&cdev->private->kick_work,
1031 ccw_device_nopath_notify);
1032 queue_work(ccw_device_notify_work,
1033 &cdev->private->kick_work);
1034 } else
1035 dev_fsm_event(cdev, DEV_EVENT_NOTOPER);
1036 return;
1037 }
1038 if (cdev->handler) 1038 if (cdev->handler)
1039 cdev->handler(cdev, cdev->private->intparm, 1039 cdev->handler(cdev, cdev->private->intparm,
1040 ERR_PTR(-EIO)); 1040 ERR_PTR(-EIO));
1041 if (!sch->lpm) {
1042 PREPARE_WORK(&cdev->private->kick_work,
1043 ccw_device_nopath_notify);
1044 queue_work(ccw_device_notify_work, &cdev->private->kick_work);
1045 } else
1046 /* Start delayed path verification. */
1047 ccw_device_online_verify(cdev, 0);
1048} 1041}
1049 1042
1050static void 1043static void