aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/s390/block
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/s390/block')
-rw-r--r--drivers/s390/block/dasd_eckd.c73
1 files changed, 60 insertions, 13 deletions
diff --git a/drivers/s390/block/dasd_eckd.c b/drivers/s390/block/dasd_eckd.c
index ab84da5592e8..0483b2e76b11 100644
--- a/drivers/s390/block/dasd_eckd.c
+++ b/drivers/s390/block/dasd_eckd.c
@@ -82,6 +82,14 @@ static struct ccw_driver dasd_eckd_driver; /* see below */
82#define INIT_CQR_UNFORMATTED 1 82#define INIT_CQR_UNFORMATTED 1
83#define INIT_CQR_ERROR 2 83#define INIT_CQR_ERROR 2
84 84
85/* emergency request for reserve/release */
86static struct {
87 struct dasd_ccw_req cqr;
88 struct ccw1 ccw;
89 char data[32];
90} *dasd_reserve_req;
91static DEFINE_MUTEX(dasd_reserve_mutex);
92
85 93
86/* initial attempt at a probe function. this can be simplified once 94/* initial attempt at a probe function. this can be simplified once
87 * the other detection code is gone */ 95 * the other detection code is gone */
@@ -2645,15 +2653,23 @@ dasd_eckd_release(struct dasd_device *device)
2645 struct dasd_ccw_req *cqr; 2653 struct dasd_ccw_req *cqr;
2646 int rc; 2654 int rc;
2647 struct ccw1 *ccw; 2655 struct ccw1 *ccw;
2656 int useglobal;
2648 2657
2649 if (!capable(CAP_SYS_ADMIN)) 2658 if (!capable(CAP_SYS_ADMIN))
2650 return -EACCES; 2659 return -EACCES;
2651 2660
2661 useglobal = 0;
2652 cqr = dasd_smalloc_request(DASD_ECKD_MAGIC, 1, 32, device); 2662 cqr = dasd_smalloc_request(DASD_ECKD_MAGIC, 1, 32, device);
2653 if (IS_ERR(cqr)) { 2663 if (IS_ERR(cqr)) {
2654 DBF_DEV_EVENT(DBF_WARNING, device, "%s", 2664 mutex_lock(&dasd_reserve_mutex);
2655 "Could not allocate initialization request"); 2665 useglobal = 1;
2656 return PTR_ERR(cqr); 2666 cqr = &dasd_reserve_req->cqr;
2667 memset(cqr, 0, sizeof(*cqr));
2668 memset(&dasd_reserve_req->ccw, 0,
2669 sizeof(dasd_reserve_req->ccw));
2670 cqr->cpaddr = &dasd_reserve_req->ccw;
2671 cqr->data = &dasd_reserve_req->data;
2672 cqr->magic = DASD_ECKD_MAGIC;
2657 } 2673 }
2658 ccw = cqr->cpaddr; 2674 ccw = cqr->cpaddr;
2659 ccw->cmd_code = DASD_ECKD_CCW_RELEASE; 2675 ccw->cmd_code = DASD_ECKD_CCW_RELEASE;
@@ -2671,7 +2687,10 @@ dasd_eckd_release(struct dasd_device *device)
2671 2687
2672 rc = dasd_sleep_on_immediatly(cqr); 2688 rc = dasd_sleep_on_immediatly(cqr);
2673 2689
2674 dasd_sfree_request(cqr, cqr->memdev); 2690 if (useglobal)
2691 mutex_unlock(&dasd_reserve_mutex);
2692 else
2693 dasd_sfree_request(cqr, cqr->memdev);
2675 return rc; 2694 return rc;
2676} 2695}
2677 2696
@@ -2687,15 +2706,23 @@ dasd_eckd_reserve(struct dasd_device *device)
2687 struct dasd_ccw_req *cqr; 2706 struct dasd_ccw_req *cqr;
2688 int rc; 2707 int rc;
2689 struct ccw1 *ccw; 2708 struct ccw1 *ccw;
2709 int useglobal;
2690 2710
2691 if (!capable(CAP_SYS_ADMIN)) 2711 if (!capable(CAP_SYS_ADMIN))
2692 return -EACCES; 2712 return -EACCES;
2693 2713
2714 useglobal = 0;
2694 cqr = dasd_smalloc_request(DASD_ECKD_MAGIC, 1, 32, device); 2715 cqr = dasd_smalloc_request(DASD_ECKD_MAGIC, 1, 32, device);
2695 if (IS_ERR(cqr)) { 2716 if (IS_ERR(cqr)) {
2696 DBF_DEV_EVENT(DBF_WARNING, device, "%s", 2717 mutex_lock(&dasd_reserve_mutex);
2697 "Could not allocate initialization request"); 2718 useglobal = 1;
2698 return PTR_ERR(cqr); 2719 cqr = &dasd_reserve_req->cqr;
2720 memset(cqr, 0, sizeof(*cqr));
2721 memset(&dasd_reserve_req->ccw, 0,
2722 sizeof(dasd_reserve_req->ccw));
2723 cqr->cpaddr = &dasd_reserve_req->ccw;
2724 cqr->data = &dasd_reserve_req->data;
2725 cqr->magic = DASD_ECKD_MAGIC;
2699 } 2726 }
2700 ccw = cqr->cpaddr; 2727 ccw = cqr->cpaddr;
2701 ccw->cmd_code = DASD_ECKD_CCW_RESERVE; 2728 ccw->cmd_code = DASD_ECKD_CCW_RESERVE;
@@ -2713,7 +2740,10 @@ dasd_eckd_reserve(struct dasd_device *device)
2713 2740
2714 rc = dasd_sleep_on_immediatly(cqr); 2741 rc = dasd_sleep_on_immediatly(cqr);
2715 2742
2716 dasd_sfree_request(cqr, cqr->memdev); 2743 if (useglobal)
2744 mutex_unlock(&dasd_reserve_mutex);
2745 else
2746 dasd_sfree_request(cqr, cqr->memdev);
2717 return rc; 2747 return rc;
2718} 2748}
2719 2749
@@ -2728,15 +2758,23 @@ dasd_eckd_steal_lock(struct dasd_device *device)
2728 struct dasd_ccw_req *cqr; 2758 struct dasd_ccw_req *cqr;
2729 int rc; 2759 int rc;
2730 struct ccw1 *ccw; 2760 struct ccw1 *ccw;
2761 int useglobal;
2731 2762
2732 if (!capable(CAP_SYS_ADMIN)) 2763 if (!capable(CAP_SYS_ADMIN))
2733 return -EACCES; 2764 return -EACCES;
2734 2765
2766 useglobal = 0;
2735 cqr = dasd_smalloc_request(DASD_ECKD_MAGIC, 1, 32, device); 2767 cqr = dasd_smalloc_request(DASD_ECKD_MAGIC, 1, 32, device);
2736 if (IS_ERR(cqr)) { 2768 if (IS_ERR(cqr)) {
2737 DBF_DEV_EVENT(DBF_WARNING, device, "%s", 2769 mutex_lock(&dasd_reserve_mutex);
2738 "Could not allocate initialization request"); 2770 useglobal = 1;
2739 return PTR_ERR(cqr); 2771 cqr = &dasd_reserve_req->cqr;
2772 memset(cqr, 0, sizeof(*cqr));
2773 memset(&dasd_reserve_req->ccw, 0,
2774 sizeof(dasd_reserve_req->ccw));
2775 cqr->cpaddr = &dasd_reserve_req->ccw;
2776 cqr->data = &dasd_reserve_req->data;
2777 cqr->magic = DASD_ECKD_MAGIC;
2740 } 2778 }
2741 ccw = cqr->cpaddr; 2779 ccw = cqr->cpaddr;
2742 ccw->cmd_code = DASD_ECKD_CCW_SLCK; 2780 ccw->cmd_code = DASD_ECKD_CCW_SLCK;
@@ -2754,7 +2792,10 @@ dasd_eckd_steal_lock(struct dasd_device *device)
2754 2792
2755 rc = dasd_sleep_on_immediatly(cqr); 2793 rc = dasd_sleep_on_immediatly(cqr);
2756 2794
2757 dasd_sfree_request(cqr, cqr->memdev); 2795 if (useglobal)
2796 mutex_unlock(&dasd_reserve_mutex);
2797 else
2798 dasd_sfree_request(cqr, cqr->memdev);
2758 return rc; 2799 return rc;
2759} 2800}
2760 2801
@@ -3488,10 +3529,15 @@ dasd_eckd_init(void)
3488 int ret; 3529 int ret;
3489 3530
3490 ASCEBC(dasd_eckd_discipline.ebcname, 4); 3531 ASCEBC(dasd_eckd_discipline.ebcname, 4);
3532 dasd_reserve_req = kmalloc(sizeof(*dasd_reserve_req),
3533 GFP_KERNEL | GFP_DMA);
3534 if (!dasd_reserve_req)
3535 return -ENOMEM;
3491 ret = ccw_driver_register(&dasd_eckd_driver); 3536 ret = ccw_driver_register(&dasd_eckd_driver);
3492 if (!ret) 3537 if (!ret)
3493 wait_for_device_probe(); 3538 wait_for_device_probe();
3494 3539 else
3540 kfree(dasd_reserve_req);
3495 return ret; 3541 return ret;
3496} 3542}
3497 3543
@@ -3499,6 +3545,7 @@ static void __exit
3499dasd_eckd_cleanup(void) 3545dasd_eckd_cleanup(void)
3500{ 3546{
3501 ccw_driver_unregister(&dasd_eckd_driver); 3547 ccw_driver_unregister(&dasd_eckd_driver);
3548 kfree(dasd_reserve_req);
3502} 3549}
3503 3550
3504module_init(dasd_eckd_init); 3551module_init(dasd_eckd_init);