diff options
| -rw-r--r-- | drivers/s390/block/dasd.c | 38 | ||||
| -rw-r--r-- | drivers/s390/block/dasd_genhd.c | 2 | ||||
| -rw-r--r-- | drivers/s390/block/dasd_int.h | 7 | ||||
| -rw-r--r-- | drivers/s390/block/dasd_proc.c | 3 | ||||
| -rw-r--r-- | fs/partitions/ibm.c | 16 |
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 | */ |
| 222 | static inline int | 223 | static inline int |
| 223 | dasd_state_basic_to_ready(struct dasd_device * device) | 224 | dasd_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 | */ | ||
| 266 | static inline void | ||
| 267 | dasd_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 | |||
| 52 | ibm_partition(struct parsed_partitions *state, struct block_device *bdev) | 52 | ibm_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 | ||
| 182 | out_readerr: | 187 | out_readerr: |
| 183 | out_badsect: | ||
| 184 | out_noioctl: | 188 | out_noioctl: |
| 185 | kfree(label); | 189 | kfree(label); |
| 186 | out_nolab: | 190 | out_nolab: |
