aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/s390/block/dasd.c38
-rw-r--r--drivers/s390/block/dasd_genhd.c2
-rw-r--r--drivers/s390/block/dasd_int.h7
-rw-r--r--drivers/s390/block/dasd_proc.c3
-rw-r--r--fs/partitions/ibm.c16
5 files changed, 46 insertions, 20 deletions
diff --git a/drivers/s390/block/dasd.c b/drivers/s390/block/dasd.c
index af1d5b404cee..33157c84d1d3 100644
--- a/drivers/s390/block/dasd.c
+++ b/drivers/s390/block/dasd.c
@@ -215,9 +215,10 @@ dasd_state_basic_to_known(struct dasd_device * device)
215 * interrupt for this detection ccw uses the kernel event daemon to 215 * interrupt for this detection ccw uses the kernel event daemon to
216 * trigger the call to dasd_change_state. All this is done in the 216 * trigger the call to dasd_change_state. All this is done in the
217 * discipline code, see dasd_eckd.c. 217 * discipline code, see dasd_eckd.c.
218 * After the analysis ccw is done (do_analysis returned 0 or error) 218 * After the analysis ccw is done (do_analysis returned 0) the block
219 * the block device is setup. Either a fake disk is added to allow 219 * device is setup.
220 * formatting or a proper device request queue is created. 220 * In case the analysis returns an error, the device setup is stopped
221 * (a fake disk was already added to allow formatting).
221 */ 222 */
222static inline int 223static inline int
223dasd_state_basic_to_ready(struct dasd_device * device) 224dasd_state_basic_to_ready(struct dasd_device * device)
@@ -227,13 +228,19 @@ dasd_state_basic_to_ready(struct dasd_device * device)
227 rc = 0; 228 rc = 0;
228 if (device->discipline->do_analysis != NULL) 229 if (device->discipline->do_analysis != NULL)
229 rc = device->discipline->do_analysis(device); 230 rc = device->discipline->do_analysis(device);
230 if (rc) 231 if (rc) {
232 if (rc != -EAGAIN)
233 device->state = DASD_STATE_UNFMT;
231 return rc; 234 return rc;
235 }
236 /* make disk known with correct capacity */
232 dasd_setup_queue(device); 237 dasd_setup_queue(device);
238 set_capacity(device->gdp, device->blocks << device->s2b_shift);
233 device->state = DASD_STATE_READY; 239 device->state = DASD_STATE_READY;
234 if (dasd_scan_partitions(device) != 0) 240 rc = dasd_scan_partitions(device);
241 if (rc)
235 device->state = DASD_STATE_BASIC; 242 device->state = DASD_STATE_BASIC;
236 return 0; 243 return rc;
237} 244}
238 245
239/* 246/*
@@ -254,6 +261,15 @@ dasd_state_ready_to_basic(struct dasd_device * device)
254} 261}
255 262
256/* 263/*
264 * Back to basic.
265 */
266static inline void
267dasd_state_unfmt_to_basic(struct dasd_device * device)
268{
269 device->state = DASD_STATE_BASIC;
270}
271
272/*
257 * Make the device online and schedule the bottom half to start 273 * Make the device online and schedule the bottom half to start
258 * the requeueing of requests from the linux request queue to the 274 * the requeueing of requests from the linux request queue to the
259 * ccw queue. 275 * ccw queue.
@@ -319,8 +335,12 @@ dasd_decrease_state(struct dasd_device *device)
319 if (device->state == DASD_STATE_READY && 335 if (device->state == DASD_STATE_READY &&
320 device->target <= DASD_STATE_BASIC) 336 device->target <= DASD_STATE_BASIC)
321 dasd_state_ready_to_basic(device); 337 dasd_state_ready_to_basic(device);
322 338
323 if (device->state == DASD_STATE_BASIC && 339 if (device->state == DASD_STATE_UNFMT &&
340 device->target <= DASD_STATE_BASIC)
341 dasd_state_unfmt_to_basic(device);
342
343 if (device->state == DASD_STATE_BASIC &&
324 device->target <= DASD_STATE_KNOWN) 344 device->target <= DASD_STATE_KNOWN)
325 dasd_state_basic_to_known(device); 345 dasd_state_basic_to_known(device);
326 346
@@ -1722,7 +1742,7 @@ dasd_open(struct inode *inp, struct file *filp)
1722 goto out; 1742 goto out;
1723 } 1743 }
1724 1744
1725 if (device->state < DASD_STATE_BASIC) { 1745 if (device->state <= DASD_STATE_BASIC) {
1726 DBF_DEV_EVENT(DBF_ERR, device, " %s", 1746 DBF_DEV_EVENT(DBF_ERR, device, " %s",
1727 " Cannot open unrecognized device"); 1747 " Cannot open unrecognized device");
1728 rc = -ENODEV; 1748 rc = -ENODEV;
diff --git a/drivers/s390/block/dasd_genhd.c b/drivers/s390/block/dasd_genhd.c
index 65dc844b975c..fce2835e7d19 100644
--- a/drivers/s390/block/dasd_genhd.c
+++ b/drivers/s390/block/dasd_genhd.c
@@ -100,8 +100,6 @@ dasd_scan_partitions(struct dasd_device * device)
100{ 100{
101 struct block_device *bdev; 101 struct block_device *bdev;
102 102
103 /* Make the disk known. */
104 set_capacity(device->gdp, device->blocks << device->s2b_shift);
105 bdev = bdget_disk(device->gdp, 0); 103 bdev = bdget_disk(device->gdp, 0);
106 if (!bdev || blkdev_get(bdev, FMODE_READ, 1) < 0) 104 if (!bdev || blkdev_get(bdev, FMODE_READ, 1) < 0)
107 return -ENODEV; 105 return -ENODEV;
diff --git a/drivers/s390/block/dasd_int.h b/drivers/s390/block/dasd_int.h
index 0592354cc604..7cb0b9e78a6a 100644
--- a/drivers/s390/block/dasd_int.h
+++ b/drivers/s390/block/dasd_int.h
@@ -26,7 +26,7 @@
26 * new: the dasd_device structure is allocated. 26 * new: the dasd_device structure is allocated.
27 * known: the discipline for the device is identified. 27 * known: the discipline for the device is identified.
28 * basic: the device can do basic i/o. 28 * basic: the device can do basic i/o.
29 * accept: the device is analysed (format is known). 29 * unfmt: the device could not be analyzed (format is unknown).
30 * ready: partition detection is done and the device is can do block io. 30 * ready: partition detection is done and the device is can do block io.
31 * online: the device accepts requests from the block device queue. 31 * online: the device accepts requests from the block device queue.
32 * 32 *
@@ -47,8 +47,9 @@
47#define DASD_STATE_NEW 0 47#define DASD_STATE_NEW 0
48#define DASD_STATE_KNOWN 1 48#define DASD_STATE_KNOWN 1
49#define DASD_STATE_BASIC 2 49#define DASD_STATE_BASIC 2
50#define DASD_STATE_READY 3 50#define DASD_STATE_UNFMT 3
51#define DASD_STATE_ONLINE 4 51#define DASD_STATE_READY 4
52#define DASD_STATE_ONLINE 5
52 53
53#include <linux/module.h> 54#include <linux/module.h>
54#include <linux/wait.h> 55#include <linux/wait.h>
diff --git a/drivers/s390/block/dasd_proc.c b/drivers/s390/block/dasd_proc.c
index 2d5da3c75ca7..4c1acc8daa82 100644
--- a/drivers/s390/block/dasd_proc.c
+++ b/drivers/s390/block/dasd_proc.c
@@ -93,6 +93,9 @@ dasd_devices_show(struct seq_file *m, void *v)
93 case DASD_STATE_BASIC: 93 case DASD_STATE_BASIC:
94 seq_printf(m, "basic"); 94 seq_printf(m, "basic");
95 break; 95 break;
96 case DASD_STATE_UNFMT:
97 seq_printf(m, "unnformatted");
98 break;
96 case DASD_STATE_READY: 99 case DASD_STATE_READY:
97 case DASD_STATE_ONLINE: 100 case DASD_STATE_ONLINE:
98 seq_printf(m, "active "); 101 seq_printf(m, "active ");
diff --git a/fs/partitions/ibm.c b/fs/partitions/ibm.c
index 78010ad60e47..1e4a93835fed 100644
--- a/fs/partitions/ibm.c
+++ b/fs/partitions/ibm.c
@@ -52,6 +52,7 @@ int
52ibm_partition(struct parsed_partitions *state, struct block_device *bdev) 52ibm_partition(struct parsed_partitions *state, struct block_device *bdev)
53{ 53{
54 int blocksize, offset, size; 54 int blocksize, offset, size;
55 loff_t i_size;
55 dasd_information_t *info; 56 dasd_information_t *info;
56 struct hd_geometry *geo; 57 struct hd_geometry *geo;
57 char type[5] = {0,}; 58 char type[5] = {0,};
@@ -63,6 +64,13 @@ ibm_partition(struct parsed_partitions *state, struct block_device *bdev)
63 unsigned char *data; 64 unsigned char *data;
64 Sector sect; 65 Sector sect;
65 66
67 blocksize = bdev_hardsect_size(bdev);
68 if (blocksize <= 0)
69 return 0;
70 i_size = i_size_read(bdev->bd_inode);
71 if (i_size == 0)
72 return 0;
73
66 if ((info = kmalloc(sizeof(dasd_information_t), GFP_KERNEL)) == NULL) 74 if ((info = kmalloc(sizeof(dasd_information_t), GFP_KERNEL)) == NULL)
67 goto out_noinfo; 75 goto out_noinfo;
68 if ((geo = kmalloc(sizeof(struct hd_geometry), GFP_KERNEL)) == NULL) 76 if ((geo = kmalloc(sizeof(struct hd_geometry), GFP_KERNEL)) == NULL)
@@ -73,9 +81,6 @@ ibm_partition(struct parsed_partitions *state, struct block_device *bdev)
73 if (ioctl_by_bdev(bdev, BIODASDINFO, (unsigned long)info) != 0 || 81 if (ioctl_by_bdev(bdev, BIODASDINFO, (unsigned long)info) != 0 ||
74 ioctl_by_bdev(bdev, HDIO_GETGEO, (unsigned long)geo) != 0) 82 ioctl_by_bdev(bdev, HDIO_GETGEO, (unsigned long)geo) != 0)
75 goto out_noioctl; 83 goto out_noioctl;
76
77 if ((blocksize = bdev_hardsect_size(bdev)) <= 0)
78 goto out_badsect;
79 84
80 /* 85 /*
81 * Get volume label, extract name and type. 86 * Get volume label, extract name and type.
@@ -111,7 +116,7 @@ ibm_partition(struct parsed_partitions *state, struct block_device *bdev)
111 } else { 116 } else {
112 printk("CMS1/%8s:", name); 117 printk("CMS1/%8s:", name);
113 offset = (info->label_block + 1); 118 offset = (info->label_block + 1);
114 size = bdev->bd_inode->i_size >> 9; 119 size = i_size >> 9;
115 } 120 }
116 put_partition(state, 1, offset*(blocksize >> 9), 121 put_partition(state, 1, offset*(blocksize >> 9),
117 size-offset*(blocksize >> 9)); 122 size-offset*(blocksize >> 9));
@@ -168,7 +173,7 @@ ibm_partition(struct parsed_partitions *state, struct block_device *bdev)
168 else 173 else
169 printk("(nonl)/%8s:", name); 174 printk("(nonl)/%8s:", name);
170 offset = (info->label_block + 1); 175 offset = (info->label_block + 1);
171 size = (bdev->bd_inode->i_size >> 9); 176 size = i_size >> 9;
172 put_partition(state, 1, offset*(blocksize >> 9), 177 put_partition(state, 1, offset*(blocksize >> 9),
173 size-offset*(blocksize >> 9)); 178 size-offset*(blocksize >> 9));
174 } 179 }
@@ -180,7 +185,6 @@ ibm_partition(struct parsed_partitions *state, struct block_device *bdev)
180 return 1; 185 return 1;
181 186
182out_readerr: 187out_readerr:
183out_badsect:
184out_noioctl: 188out_noioctl:
185 kfree(label); 189 kfree(label);
186out_nolab: 190out_nolab: