diff options
author | Jiri Kosina <jkosina@suse.cz> | 2010-08-11 03:36:51 -0400 |
---|---|---|
committer | Jiri Kosina <jkosina@suse.cz> | 2010-08-11 03:36:51 -0400 |
commit | 6396fc3b3ff3f6b942992b653a62df11dcef9bea (patch) | |
tree | db3c7cbe833b43c653adc99f70941431c5ff7c4e /drivers/s390/block | |
parent | 4785879e4d340e24e54f6de2ccfc42728b912808 (diff) | |
parent | 3d30701b58970425e1d45994d6cb82f828924fdd (diff) |
Merge branch 'master' into for-next
Conflicts:
fs/exofs/inode.c
Diffstat (limited to 'drivers/s390/block')
-rw-r--r-- | drivers/s390/block/dasd.c | 8 | ||||
-rw-r--r-- | drivers/s390/block/dasd_devmap.c | 44 | ||||
-rw-r--r-- | drivers/s390/block/dasd_diag.c | 6 | ||||
-rw-r--r-- | drivers/s390/block/dasd_eckd.c | 94 | ||||
-rw-r--r-- | drivers/s390/block/dasd_eckd.h | 7 | ||||
-rw-r--r-- | drivers/s390/block/dasd_fba.c | 4 | ||||
-rw-r--r-- | drivers/s390/block/dasd_int.h | 8 | ||||
-rw-r--r-- | drivers/s390/block/dcssblk.c | 5 |
8 files changed, 153 insertions, 23 deletions
diff --git a/drivers/s390/block/dasd.c b/drivers/s390/block/dasd.c index 33975e922d65..1a84fae155e1 100644 --- a/drivers/s390/block/dasd.c +++ b/drivers/s390/block/dasd.c | |||
@@ -21,6 +21,7 @@ | |||
21 | #include <linux/hdreg.h> | 21 | #include <linux/hdreg.h> |
22 | #include <linux/async.h> | 22 | #include <linux/async.h> |
23 | #include <linux/mutex.h> | 23 | #include <linux/mutex.h> |
24 | #include <linux/smp_lock.h> | ||
24 | 25 | ||
25 | #include <asm/ccwdev.h> | 26 | #include <asm/ccwdev.h> |
26 | #include <asm/ebcdic.h> | 27 | #include <asm/ebcdic.h> |
@@ -2196,7 +2197,7 @@ static void dasd_setup_queue(struct dasd_block *block) | |||
2196 | */ | 2197 | */ |
2197 | blk_queue_max_segment_size(block->request_queue, PAGE_SIZE); | 2198 | blk_queue_max_segment_size(block->request_queue, PAGE_SIZE); |
2198 | blk_queue_segment_boundary(block->request_queue, PAGE_SIZE - 1); | 2199 | blk_queue_segment_boundary(block->request_queue, PAGE_SIZE - 1); |
2199 | blk_queue_ordered(block->request_queue, QUEUE_ORDERED_DRAIN, NULL); | 2200 | blk_queue_ordered(block->request_queue, QUEUE_ORDERED_DRAIN); |
2200 | } | 2201 | } |
2201 | 2202 | ||
2202 | /* | 2203 | /* |
@@ -2235,6 +2236,7 @@ static int dasd_open(struct block_device *bdev, fmode_t mode) | |||
2235 | if (!block) | 2236 | if (!block) |
2236 | return -ENODEV; | 2237 | return -ENODEV; |
2237 | 2238 | ||
2239 | lock_kernel(); | ||
2238 | base = block->base; | 2240 | base = block->base; |
2239 | atomic_inc(&block->open_count); | 2241 | atomic_inc(&block->open_count); |
2240 | if (test_bit(DASD_FLAG_OFFLINE, &base->flags)) { | 2242 | if (test_bit(DASD_FLAG_OFFLINE, &base->flags)) { |
@@ -2269,12 +2271,14 @@ static int dasd_open(struct block_device *bdev, fmode_t mode) | |||
2269 | goto out; | 2271 | goto out; |
2270 | } | 2272 | } |
2271 | 2273 | ||
2274 | unlock_kernel(); | ||
2272 | return 0; | 2275 | return 0; |
2273 | 2276 | ||
2274 | out: | 2277 | out: |
2275 | module_put(base->discipline->owner); | 2278 | module_put(base->discipline->owner); |
2276 | unlock: | 2279 | unlock: |
2277 | atomic_dec(&block->open_count); | 2280 | atomic_dec(&block->open_count); |
2281 | unlock_kernel(); | ||
2278 | return rc; | 2282 | return rc; |
2279 | } | 2283 | } |
2280 | 2284 | ||
@@ -2282,8 +2286,10 @@ static int dasd_release(struct gendisk *disk, fmode_t mode) | |||
2282 | { | 2286 | { |
2283 | struct dasd_block *block = disk->private_data; | 2287 | struct dasd_block *block = disk->private_data; |
2284 | 2288 | ||
2289 | lock_kernel(); | ||
2285 | atomic_dec(&block->open_count); | 2290 | atomic_dec(&block->open_count); |
2286 | module_put(block->base->discipline->owner); | 2291 | module_put(block->base->discipline->owner); |
2292 | unlock_kernel(); | ||
2287 | return 0; | 2293 | return 0; |
2288 | } | 2294 | } |
2289 | 2295 | ||
diff --git a/drivers/s390/block/dasd_devmap.c b/drivers/s390/block/dasd_devmap.c index bed7b4634ccd..8d41f3ed38d7 100644 --- a/drivers/s390/block/dasd_devmap.c +++ b/drivers/s390/block/dasd_devmap.c | |||
@@ -1083,6 +1083,49 @@ dasd_eer_store(struct device *dev, struct device_attribute *attr, | |||
1083 | 1083 | ||
1084 | static DEVICE_ATTR(eer_enabled, 0644, dasd_eer_show, dasd_eer_store); | 1084 | static DEVICE_ATTR(eer_enabled, 0644, dasd_eer_show, dasd_eer_store); |
1085 | 1085 | ||
1086 | /* | ||
1087 | * expiration time for default requests | ||
1088 | */ | ||
1089 | static ssize_t | ||
1090 | dasd_expires_show(struct device *dev, struct device_attribute *attr, char *buf) | ||
1091 | { | ||
1092 | struct dasd_device *device; | ||
1093 | int len; | ||
1094 | |||
1095 | device = dasd_device_from_cdev(to_ccwdev(dev)); | ||
1096 | if (IS_ERR(device)) | ||
1097 | return -ENODEV; | ||
1098 | len = snprintf(buf, PAGE_SIZE, "%lu\n", device->default_expires); | ||
1099 | dasd_put_device(device); | ||
1100 | return len; | ||
1101 | } | ||
1102 | |||
1103 | static ssize_t | ||
1104 | dasd_expires_store(struct device *dev, struct device_attribute *attr, | ||
1105 | const char *buf, size_t count) | ||
1106 | { | ||
1107 | struct dasd_device *device; | ||
1108 | unsigned long val; | ||
1109 | |||
1110 | device = dasd_device_from_cdev(to_ccwdev(dev)); | ||
1111 | if (IS_ERR(device)) | ||
1112 | return -ENODEV; | ||
1113 | |||
1114 | if ((strict_strtoul(buf, 10, &val) != 0) || | ||
1115 | (val > DASD_EXPIRES_MAX) || val == 0) { | ||
1116 | dasd_put_device(device); | ||
1117 | return -EINVAL; | ||
1118 | } | ||
1119 | |||
1120 | if (val) | ||
1121 | device->default_expires = val; | ||
1122 | |||
1123 | dasd_put_device(device); | ||
1124 | return count; | ||
1125 | } | ||
1126 | |||
1127 | static DEVICE_ATTR(expires, 0644, dasd_expires_show, dasd_expires_store); | ||
1128 | |||
1086 | static struct attribute * dasd_attrs[] = { | 1129 | static struct attribute * dasd_attrs[] = { |
1087 | &dev_attr_readonly.attr, | 1130 | &dev_attr_readonly.attr, |
1088 | &dev_attr_discipline.attr, | 1131 | &dev_attr_discipline.attr, |
@@ -1094,6 +1137,7 @@ static struct attribute * dasd_attrs[] = { | |||
1094 | &dev_attr_eer_enabled.attr, | 1137 | &dev_attr_eer_enabled.attr, |
1095 | &dev_attr_erplog.attr, | 1138 | &dev_attr_erplog.attr, |
1096 | &dev_attr_failfast.attr, | 1139 | &dev_attr_failfast.attr, |
1140 | &dev_attr_expires.attr, | ||
1097 | NULL, | 1141 | NULL, |
1098 | }; | 1142 | }; |
1099 | 1143 | ||
diff --git a/drivers/s390/block/dasd_diag.c b/drivers/s390/block/dasd_diag.c index 687f323cdc38..2b3bc3ec0541 100644 --- a/drivers/s390/block/dasd_diag.c +++ b/drivers/s390/block/dasd_diag.c | |||
@@ -43,7 +43,7 @@ MODULE_LICENSE("GPL"); | |||
43 | sizeof(struct dasd_diag_req)) / \ | 43 | sizeof(struct dasd_diag_req)) / \ |
44 | sizeof(struct dasd_diag_bio)) / 2) | 44 | sizeof(struct dasd_diag_bio)) / 2) |
45 | #define DIAG_MAX_RETRIES 32 | 45 | #define DIAG_MAX_RETRIES 32 |
46 | #define DIAG_TIMEOUT 50 * HZ | 46 | #define DIAG_TIMEOUT 50 |
47 | 47 | ||
48 | static struct dasd_discipline dasd_diag_discipline; | 48 | static struct dasd_discipline dasd_diag_discipline; |
49 | 49 | ||
@@ -360,6 +360,8 @@ dasd_diag_check_device(struct dasd_device *device) | |||
360 | goto out; | 360 | goto out; |
361 | } | 361 | } |
362 | 362 | ||
363 | device->default_expires = DIAG_TIMEOUT; | ||
364 | |||
363 | /* Figure out position of label block */ | 365 | /* Figure out position of label block */ |
364 | switch (private->rdc_data.vdev_class) { | 366 | switch (private->rdc_data.vdev_class) { |
365 | case DEV_CLASS_FBA: | 367 | case DEV_CLASS_FBA: |
@@ -563,7 +565,7 @@ static struct dasd_ccw_req *dasd_diag_build_cp(struct dasd_device *memdev, | |||
563 | cqr->startdev = memdev; | 565 | cqr->startdev = memdev; |
564 | cqr->memdev = memdev; | 566 | cqr->memdev = memdev; |
565 | cqr->block = block; | 567 | cqr->block = block; |
566 | cqr->expires = DIAG_TIMEOUT; | 568 | cqr->expires = memdev->default_expires * HZ; |
567 | cqr->status = DASD_CQR_FILLED; | 569 | cqr->status = DASD_CQR_FILLED; |
568 | return cqr; | 570 | return cqr; |
569 | } | 571 | } |
diff --git a/drivers/s390/block/dasd_eckd.c b/drivers/s390/block/dasd_eckd.c index ab84da5592e8..66360c24bd48 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 */ | ||
86 | static struct { | ||
87 | struct dasd_ccw_req cqr; | ||
88 | struct ccw1 ccw; | ||
89 | char data[32]; | ||
90 | } *dasd_reserve_req; | ||
91 | static 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 */ |
@@ -1107,8 +1115,9 @@ dasd_eckd_check_characteristics(struct dasd_device *device) | |||
1107 | struct dasd_eckd_private *private; | 1115 | struct dasd_eckd_private *private; |
1108 | struct dasd_block *block; | 1116 | struct dasd_block *block; |
1109 | struct dasd_uid temp_uid; | 1117 | struct dasd_uid temp_uid; |
1110 | int is_known, rc; | 1118 | int is_known, rc, i; |
1111 | int readonly; | 1119 | int readonly; |
1120 | unsigned long value; | ||
1112 | 1121 | ||
1113 | if (!ccw_device_is_pathgroup(device->cdev)) { | 1122 | if (!ccw_device_is_pathgroup(device->cdev)) { |
1114 | dev_warn(&device->cdev->dev, | 1123 | dev_warn(&device->cdev->dev, |
@@ -1143,6 +1152,18 @@ dasd_eckd_check_characteristics(struct dasd_device *device) | |||
1143 | if (rc) | 1152 | if (rc) |
1144 | goto out_err1; | 1153 | goto out_err1; |
1145 | 1154 | ||
1155 | /* set default timeout */ | ||
1156 | device->default_expires = DASD_EXPIRES; | ||
1157 | if (private->gneq) { | ||
1158 | value = 1; | ||
1159 | for (i = 0; i < private->gneq->timeout.value; i++) | ||
1160 | value = 10 * value; | ||
1161 | value = value * private->gneq->timeout.number; | ||
1162 | /* do not accept useless values */ | ||
1163 | if (value != 0 && value <= DASD_EXPIRES_MAX) | ||
1164 | device->default_expires = value; | ||
1165 | } | ||
1166 | |||
1146 | /* Generate device unique id */ | 1167 | /* Generate device unique id */ |
1147 | rc = dasd_eckd_generate_uid(device); | 1168 | rc = dasd_eckd_generate_uid(device); |
1148 | if (rc) | 1169 | if (rc) |
@@ -1973,7 +1994,7 @@ static struct dasd_ccw_req *dasd_eckd_build_cp_cmd_single( | |||
1973 | cqr->startdev = startdev; | 1994 | cqr->startdev = startdev; |
1974 | cqr->memdev = startdev; | 1995 | cqr->memdev = startdev; |
1975 | cqr->block = block; | 1996 | cqr->block = block; |
1976 | cqr->expires = 5 * 60 * HZ; /* 5 minutes */ | 1997 | cqr->expires = startdev->default_expires * HZ; /* default 5 minutes */ |
1977 | cqr->lpm = private->path_data.ppm; | 1998 | cqr->lpm = private->path_data.ppm; |
1978 | cqr->retries = 256; | 1999 | cqr->retries = 256; |
1979 | cqr->buildclk = get_clock(); | 2000 | cqr->buildclk = get_clock(); |
@@ -2150,7 +2171,7 @@ static struct dasd_ccw_req *dasd_eckd_build_cp_cmd_track( | |||
2150 | cqr->startdev = startdev; | 2171 | cqr->startdev = startdev; |
2151 | cqr->memdev = startdev; | 2172 | cqr->memdev = startdev; |
2152 | cqr->block = block; | 2173 | cqr->block = block; |
2153 | cqr->expires = 5 * 60 * HZ; /* 5 minutes */ | 2174 | cqr->expires = startdev->default_expires * HZ; /* default 5 minutes */ |
2154 | cqr->lpm = private->path_data.ppm; | 2175 | cqr->lpm = private->path_data.ppm; |
2155 | cqr->retries = 256; | 2176 | cqr->retries = 256; |
2156 | cqr->buildclk = get_clock(); | 2177 | cqr->buildclk = get_clock(); |
@@ -2398,7 +2419,7 @@ static struct dasd_ccw_req *dasd_eckd_build_cp_tpm_track( | |||
2398 | cqr->startdev = startdev; | 2419 | cqr->startdev = startdev; |
2399 | cqr->memdev = startdev; | 2420 | cqr->memdev = startdev; |
2400 | cqr->block = block; | 2421 | cqr->block = block; |
2401 | cqr->expires = 5 * 60 * HZ; /* 5 minutes */ | 2422 | cqr->expires = startdev->default_expires * HZ; /* default 5 minutes */ |
2402 | cqr->lpm = private->path_data.ppm; | 2423 | cqr->lpm = private->path_data.ppm; |
2403 | cqr->retries = 256; | 2424 | cqr->retries = 256; |
2404 | cqr->buildclk = get_clock(); | 2425 | cqr->buildclk = get_clock(); |
@@ -2645,15 +2666,23 @@ dasd_eckd_release(struct dasd_device *device) | |||
2645 | struct dasd_ccw_req *cqr; | 2666 | struct dasd_ccw_req *cqr; |
2646 | int rc; | 2667 | int rc; |
2647 | struct ccw1 *ccw; | 2668 | struct ccw1 *ccw; |
2669 | int useglobal; | ||
2648 | 2670 | ||
2649 | if (!capable(CAP_SYS_ADMIN)) | 2671 | if (!capable(CAP_SYS_ADMIN)) |
2650 | return -EACCES; | 2672 | return -EACCES; |
2651 | 2673 | ||
2674 | useglobal = 0; | ||
2652 | cqr = dasd_smalloc_request(DASD_ECKD_MAGIC, 1, 32, device); | 2675 | cqr = dasd_smalloc_request(DASD_ECKD_MAGIC, 1, 32, device); |
2653 | if (IS_ERR(cqr)) { | 2676 | if (IS_ERR(cqr)) { |
2654 | DBF_DEV_EVENT(DBF_WARNING, device, "%s", | 2677 | mutex_lock(&dasd_reserve_mutex); |
2655 | "Could not allocate initialization request"); | 2678 | useglobal = 1; |
2656 | return PTR_ERR(cqr); | 2679 | cqr = &dasd_reserve_req->cqr; |
2680 | memset(cqr, 0, sizeof(*cqr)); | ||
2681 | memset(&dasd_reserve_req->ccw, 0, | ||
2682 | sizeof(dasd_reserve_req->ccw)); | ||
2683 | cqr->cpaddr = &dasd_reserve_req->ccw; | ||
2684 | cqr->data = &dasd_reserve_req->data; | ||
2685 | cqr->magic = DASD_ECKD_MAGIC; | ||
2657 | } | 2686 | } |
2658 | ccw = cqr->cpaddr; | 2687 | ccw = cqr->cpaddr; |
2659 | ccw->cmd_code = DASD_ECKD_CCW_RELEASE; | 2688 | ccw->cmd_code = DASD_ECKD_CCW_RELEASE; |
@@ -2671,7 +2700,10 @@ dasd_eckd_release(struct dasd_device *device) | |||
2671 | 2700 | ||
2672 | rc = dasd_sleep_on_immediatly(cqr); | 2701 | rc = dasd_sleep_on_immediatly(cqr); |
2673 | 2702 | ||
2674 | dasd_sfree_request(cqr, cqr->memdev); | 2703 | if (useglobal) |
2704 | mutex_unlock(&dasd_reserve_mutex); | ||
2705 | else | ||
2706 | dasd_sfree_request(cqr, cqr->memdev); | ||
2675 | return rc; | 2707 | return rc; |
2676 | } | 2708 | } |
2677 | 2709 | ||
@@ -2687,15 +2719,23 @@ dasd_eckd_reserve(struct dasd_device *device) | |||
2687 | struct dasd_ccw_req *cqr; | 2719 | struct dasd_ccw_req *cqr; |
2688 | int rc; | 2720 | int rc; |
2689 | struct ccw1 *ccw; | 2721 | struct ccw1 *ccw; |
2722 | int useglobal; | ||
2690 | 2723 | ||
2691 | if (!capable(CAP_SYS_ADMIN)) | 2724 | if (!capable(CAP_SYS_ADMIN)) |
2692 | return -EACCES; | 2725 | return -EACCES; |
2693 | 2726 | ||
2727 | useglobal = 0; | ||
2694 | cqr = dasd_smalloc_request(DASD_ECKD_MAGIC, 1, 32, device); | 2728 | cqr = dasd_smalloc_request(DASD_ECKD_MAGIC, 1, 32, device); |
2695 | if (IS_ERR(cqr)) { | 2729 | if (IS_ERR(cqr)) { |
2696 | DBF_DEV_EVENT(DBF_WARNING, device, "%s", | 2730 | mutex_lock(&dasd_reserve_mutex); |
2697 | "Could not allocate initialization request"); | 2731 | useglobal = 1; |
2698 | return PTR_ERR(cqr); | 2732 | cqr = &dasd_reserve_req->cqr; |
2733 | memset(cqr, 0, sizeof(*cqr)); | ||
2734 | memset(&dasd_reserve_req->ccw, 0, | ||
2735 | sizeof(dasd_reserve_req->ccw)); | ||
2736 | cqr->cpaddr = &dasd_reserve_req->ccw; | ||
2737 | cqr->data = &dasd_reserve_req->data; | ||
2738 | cqr->magic = DASD_ECKD_MAGIC; | ||
2699 | } | 2739 | } |
2700 | ccw = cqr->cpaddr; | 2740 | ccw = cqr->cpaddr; |
2701 | ccw->cmd_code = DASD_ECKD_CCW_RESERVE; | 2741 | ccw->cmd_code = DASD_ECKD_CCW_RESERVE; |
@@ -2713,7 +2753,10 @@ dasd_eckd_reserve(struct dasd_device *device) | |||
2713 | 2753 | ||
2714 | rc = dasd_sleep_on_immediatly(cqr); | 2754 | rc = dasd_sleep_on_immediatly(cqr); |
2715 | 2755 | ||
2716 | dasd_sfree_request(cqr, cqr->memdev); | 2756 | if (useglobal) |
2757 | mutex_unlock(&dasd_reserve_mutex); | ||
2758 | else | ||
2759 | dasd_sfree_request(cqr, cqr->memdev); | ||
2717 | return rc; | 2760 | return rc; |
2718 | } | 2761 | } |
2719 | 2762 | ||
@@ -2728,15 +2771,23 @@ dasd_eckd_steal_lock(struct dasd_device *device) | |||
2728 | struct dasd_ccw_req *cqr; | 2771 | struct dasd_ccw_req *cqr; |
2729 | int rc; | 2772 | int rc; |
2730 | struct ccw1 *ccw; | 2773 | struct ccw1 *ccw; |
2774 | int useglobal; | ||
2731 | 2775 | ||
2732 | if (!capable(CAP_SYS_ADMIN)) | 2776 | if (!capable(CAP_SYS_ADMIN)) |
2733 | return -EACCES; | 2777 | return -EACCES; |
2734 | 2778 | ||
2779 | useglobal = 0; | ||
2735 | cqr = dasd_smalloc_request(DASD_ECKD_MAGIC, 1, 32, device); | 2780 | cqr = dasd_smalloc_request(DASD_ECKD_MAGIC, 1, 32, device); |
2736 | if (IS_ERR(cqr)) { | 2781 | if (IS_ERR(cqr)) { |
2737 | DBF_DEV_EVENT(DBF_WARNING, device, "%s", | 2782 | mutex_lock(&dasd_reserve_mutex); |
2738 | "Could not allocate initialization request"); | 2783 | useglobal = 1; |
2739 | return PTR_ERR(cqr); | 2784 | cqr = &dasd_reserve_req->cqr; |
2785 | memset(cqr, 0, sizeof(*cqr)); | ||
2786 | memset(&dasd_reserve_req->ccw, 0, | ||
2787 | sizeof(dasd_reserve_req->ccw)); | ||
2788 | cqr->cpaddr = &dasd_reserve_req->ccw; | ||
2789 | cqr->data = &dasd_reserve_req->data; | ||
2790 | cqr->magic = DASD_ECKD_MAGIC; | ||
2740 | } | 2791 | } |
2741 | ccw = cqr->cpaddr; | 2792 | ccw = cqr->cpaddr; |
2742 | ccw->cmd_code = DASD_ECKD_CCW_SLCK; | 2793 | ccw->cmd_code = DASD_ECKD_CCW_SLCK; |
@@ -2754,7 +2805,10 @@ dasd_eckd_steal_lock(struct dasd_device *device) | |||
2754 | 2805 | ||
2755 | rc = dasd_sleep_on_immediatly(cqr); | 2806 | rc = dasd_sleep_on_immediatly(cqr); |
2756 | 2807 | ||
2757 | dasd_sfree_request(cqr, cqr->memdev); | 2808 | if (useglobal) |
2809 | mutex_unlock(&dasd_reserve_mutex); | ||
2810 | else | ||
2811 | dasd_sfree_request(cqr, cqr->memdev); | ||
2758 | return rc; | 2812 | return rc; |
2759 | } | 2813 | } |
2760 | 2814 | ||
@@ -3488,10 +3542,15 @@ dasd_eckd_init(void) | |||
3488 | int ret; | 3542 | int ret; |
3489 | 3543 | ||
3490 | ASCEBC(dasd_eckd_discipline.ebcname, 4); | 3544 | ASCEBC(dasd_eckd_discipline.ebcname, 4); |
3545 | dasd_reserve_req = kmalloc(sizeof(*dasd_reserve_req), | ||
3546 | GFP_KERNEL | GFP_DMA); | ||
3547 | if (!dasd_reserve_req) | ||
3548 | return -ENOMEM; | ||
3491 | ret = ccw_driver_register(&dasd_eckd_driver); | 3549 | ret = ccw_driver_register(&dasd_eckd_driver); |
3492 | if (!ret) | 3550 | if (!ret) |
3493 | wait_for_device_probe(); | 3551 | wait_for_device_probe(); |
3494 | 3552 | else | |
3553 | kfree(dasd_reserve_req); | ||
3495 | return ret; | 3554 | return ret; |
3496 | } | 3555 | } |
3497 | 3556 | ||
@@ -3499,6 +3558,7 @@ static void __exit | |||
3499 | dasd_eckd_cleanup(void) | 3558 | dasd_eckd_cleanup(void) |
3500 | { | 3559 | { |
3501 | ccw_driver_unregister(&dasd_eckd_driver); | 3560 | ccw_driver_unregister(&dasd_eckd_driver); |
3561 | kfree(dasd_reserve_req); | ||
3502 | } | 3562 | } |
3503 | 3563 | ||
3504 | module_init(dasd_eckd_init); | 3564 | module_init(dasd_eckd_init); |
diff --git a/drivers/s390/block/dasd_eckd.h b/drivers/s390/block/dasd_eckd.h index dd6385a5af14..0eb49655a6cd 100644 --- a/drivers/s390/block/dasd_eckd.h +++ b/drivers/s390/block/dasd_eckd.h | |||
@@ -320,7 +320,12 @@ struct dasd_gneq { | |||
320 | __u8 identifier:2; | 320 | __u8 identifier:2; |
321 | __u8 reserved:6; | 321 | __u8 reserved:6; |
322 | } __attribute__ ((packed)) flags; | 322 | } __attribute__ ((packed)) flags; |
323 | __u8 reserved[7]; | 323 | __u8 reserved[5]; |
324 | struct { | ||
325 | __u8 value:2; | ||
326 | __u8 number:6; | ||
327 | } __attribute__ ((packed)) timeout; | ||
328 | __u8 reserved3; | ||
324 | __u16 subsystemID; | 329 | __u16 subsystemID; |
325 | __u8 reserved2[22]; | 330 | __u8 reserved2[22]; |
326 | } __attribute__ ((packed)); | 331 | } __attribute__ ((packed)); |
diff --git a/drivers/s390/block/dasd_fba.c b/drivers/s390/block/dasd_fba.c index 37282b90eecc..bec5486e0e6d 100644 --- a/drivers/s390/block/dasd_fba.c +++ b/drivers/s390/block/dasd_fba.c | |||
@@ -163,6 +163,8 @@ dasd_fba_check_characteristics(struct dasd_device *device) | |||
163 | return rc; | 163 | return rc; |
164 | } | 164 | } |
165 | 165 | ||
166 | device->default_expires = DASD_EXPIRES; | ||
167 | |||
166 | readonly = dasd_device_is_ro(device); | 168 | readonly = dasd_device_is_ro(device); |
167 | if (readonly) | 169 | if (readonly) |
168 | set_bit(DASD_FLAG_DEVICE_RO, &device->flags); | 170 | set_bit(DASD_FLAG_DEVICE_RO, &device->flags); |
@@ -370,7 +372,7 @@ static struct dasd_ccw_req *dasd_fba_build_cp(struct dasd_device * memdev, | |||
370 | cqr->startdev = memdev; | 372 | cqr->startdev = memdev; |
371 | cqr->memdev = memdev; | 373 | cqr->memdev = memdev; |
372 | cqr->block = block; | 374 | cqr->block = block; |
373 | cqr->expires = 5 * 60 * HZ; /* 5 minutes */ | 375 | cqr->expires = memdev->default_expires * HZ; /* default 5 minutes */ |
374 | cqr->retries = 32; | 376 | cqr->retries = 32; |
375 | cqr->buildclk = get_clock(); | 377 | cqr->buildclk = get_clock(); |
376 | cqr->status = DASD_CQR_FILLED; | 378 | cqr->status = DASD_CQR_FILLED; |
diff --git a/drivers/s390/block/dasd_int.h b/drivers/s390/block/dasd_int.h index 49b431d135e0..500678d7116c 100644 --- a/drivers/s390/block/dasd_int.h +++ b/drivers/s390/block/dasd_int.h | |||
@@ -186,7 +186,7 @@ struct dasd_ccw_req { | |||
186 | 186 | ||
187 | /* ... and how */ | 187 | /* ... and how */ |
188 | unsigned long starttime; /* jiffies time of request start */ | 188 | unsigned long starttime; /* jiffies time of request start */ |
189 | int expires; /* expiration period in jiffies */ | 189 | unsigned long expires; /* expiration period in jiffies */ |
190 | char lpm; /* logical path mask */ | 190 | char lpm; /* logical path mask */ |
191 | void *data; /* pointer to data area */ | 191 | void *data; /* pointer to data area */ |
192 | 192 | ||
@@ -224,6 +224,9 @@ struct dasd_ccw_req { | |||
224 | #define DASD_CQR_CLEARED 0x84 /* request was cleared */ | 224 | #define DASD_CQR_CLEARED 0x84 /* request was cleared */ |
225 | #define DASD_CQR_SUCCESS 0x85 /* request was successful */ | 225 | #define DASD_CQR_SUCCESS 0x85 /* request was successful */ |
226 | 226 | ||
227 | /* default expiration time*/ | ||
228 | #define DASD_EXPIRES 300 | ||
229 | #define DASD_EXPIRES_MAX 40000000 | ||
227 | 230 | ||
228 | /* per dasd_ccw_req flags */ | 231 | /* per dasd_ccw_req flags */ |
229 | #define DASD_CQR_FLAGS_USE_ERP 0 /* use ERP for this request */ | 232 | #define DASD_CQR_FLAGS_USE_ERP 0 /* use ERP for this request */ |
@@ -404,6 +407,9 @@ struct dasd_device { | |||
404 | 407 | ||
405 | /* hook for alias management */ | 408 | /* hook for alias management */ |
406 | struct list_head alias_list; | 409 | struct list_head alias_list; |
410 | |||
411 | /* default expiration time in s */ | ||
412 | unsigned long default_expires; | ||
407 | }; | 413 | }; |
408 | 414 | ||
409 | struct dasd_block { | 415 | struct dasd_block { |
diff --git a/drivers/s390/block/dcssblk.c b/drivers/s390/block/dcssblk.c index 9b43ae94beba..2bd72aa34c59 100644 --- a/drivers/s390/block/dcssblk.c +++ b/drivers/s390/block/dcssblk.c | |||
@@ -14,6 +14,7 @@ | |||
14 | #include <linux/init.h> | 14 | #include <linux/init.h> |
15 | #include <linux/slab.h> | 15 | #include <linux/slab.h> |
16 | #include <linux/blkdev.h> | 16 | #include <linux/blkdev.h> |
17 | #include <linux/smp_lock.h> | ||
17 | #include <linux/completion.h> | 18 | #include <linux/completion.h> |
18 | #include <linux/interrupt.h> | 19 | #include <linux/interrupt.h> |
19 | #include <linux/platform_device.h> | 20 | #include <linux/platform_device.h> |
@@ -775,6 +776,7 @@ dcssblk_open(struct block_device *bdev, fmode_t mode) | |||
775 | struct dcssblk_dev_info *dev_info; | 776 | struct dcssblk_dev_info *dev_info; |
776 | int rc; | 777 | int rc; |
777 | 778 | ||
779 | lock_kernel(); | ||
778 | dev_info = bdev->bd_disk->private_data; | 780 | dev_info = bdev->bd_disk->private_data; |
779 | if (NULL == dev_info) { | 781 | if (NULL == dev_info) { |
780 | rc = -ENODEV; | 782 | rc = -ENODEV; |
@@ -784,6 +786,7 @@ dcssblk_open(struct block_device *bdev, fmode_t mode) | |||
784 | bdev->bd_block_size = 4096; | 786 | bdev->bd_block_size = 4096; |
785 | rc = 0; | 787 | rc = 0; |
786 | out: | 788 | out: |
789 | unlock_kernel(); | ||
787 | return rc; | 790 | return rc; |
788 | } | 791 | } |
789 | 792 | ||
@@ -794,6 +797,7 @@ dcssblk_release(struct gendisk *disk, fmode_t mode) | |||
794 | struct segment_info *entry; | 797 | struct segment_info *entry; |
795 | int rc; | 798 | int rc; |
796 | 799 | ||
800 | lock_kernel(); | ||
797 | if (!dev_info) { | 801 | if (!dev_info) { |
798 | rc = -ENODEV; | 802 | rc = -ENODEV; |
799 | goto out; | 803 | goto out; |
@@ -811,6 +815,7 @@ dcssblk_release(struct gendisk *disk, fmode_t mode) | |||
811 | up_write(&dcssblk_devices_sem); | 815 | up_write(&dcssblk_devices_sem); |
812 | rc = 0; | 816 | rc = 0; |
813 | out: | 817 | out: |
818 | unlock_kernel(); | ||
814 | return rc; | 819 | return rc; |
815 | } | 820 | } |
816 | 821 | ||