| .. | .. |
|---|
| 13 | 13 | #include <asm/ebcdic.h> |
|---|
| 14 | 14 | #include <linux/uaccess.h> |
|---|
| 15 | 15 | #include <asm/vtoc.h> |
|---|
| 16 | +#include <linux/module.h> |
|---|
| 17 | +#include <linux/dasd_mod.h> |
|---|
| 16 | 18 | |
|---|
| 17 | 19 | #include "check.h" |
|---|
| 18 | | -#include "ibm.h" |
|---|
| 19 | | - |
|---|
| 20 | 20 | |
|---|
| 21 | 21 | union label_t { |
|---|
| 22 | 22 | struct vtoc_volume_label_cdl vol; |
|---|
| .. | .. |
|---|
| 289 | 289 | */ |
|---|
| 290 | 290 | int ibm_partition(struct parsed_partitions *state) |
|---|
| 291 | 291 | { |
|---|
| 292 | + int (*fn)(struct gendisk *disk, dasd_information2_t *info); |
|---|
| 292 | 293 | struct block_device *bdev = state->bdev; |
|---|
| 294 | + struct gendisk *disk = bdev->bd_disk; |
|---|
| 293 | 295 | int blocksize, res; |
|---|
| 294 | 296 | loff_t i_size, offset, size; |
|---|
| 295 | 297 | dasd_information2_t *info; |
|---|
| .. | .. |
|---|
| 300 | 302 | union label_t *label; |
|---|
| 301 | 303 | |
|---|
| 302 | 304 | res = 0; |
|---|
| 305 | + if (!disk->fops->getgeo) |
|---|
| 306 | + goto out_exit; |
|---|
| 307 | + fn = symbol_get(dasd_biodasdinfo); |
|---|
| 303 | 308 | blocksize = bdev_logical_block_size(bdev); |
|---|
| 304 | 309 | if (blocksize <= 0) |
|---|
| 305 | | - goto out_exit; |
|---|
| 310 | + goto out_symbol; |
|---|
| 306 | 311 | i_size = i_size_read(bdev->bd_inode); |
|---|
| 307 | 312 | if (i_size == 0) |
|---|
| 308 | | - goto out_exit; |
|---|
| 313 | + goto out_symbol; |
|---|
| 309 | 314 | info = kmalloc(sizeof(dasd_information2_t), GFP_KERNEL); |
|---|
| 310 | 315 | if (info == NULL) |
|---|
| 311 | | - goto out_exit; |
|---|
| 316 | + goto out_symbol; |
|---|
| 312 | 317 | geo = kmalloc(sizeof(struct hd_geometry), GFP_KERNEL); |
|---|
| 313 | 318 | if (geo == NULL) |
|---|
| 314 | 319 | goto out_nogeo; |
|---|
| 315 | 320 | label = kmalloc(sizeof(union label_t), GFP_KERNEL); |
|---|
| 316 | 321 | if (label == NULL) |
|---|
| 317 | 322 | goto out_nolab; |
|---|
| 318 | | - if (ioctl_by_bdev(bdev, HDIO_GETGEO, (unsigned long)geo) != 0) |
|---|
| 323 | + /* set start if not filled by getgeo function e.g. virtblk */ |
|---|
| 324 | + geo->start = get_start_sect(bdev); |
|---|
| 325 | + if (disk->fops->getgeo(bdev, geo)) |
|---|
| 319 | 326 | goto out_freeall; |
|---|
| 320 | | - if (ioctl_by_bdev(bdev, BIODASDINFO2, (unsigned long)info) != 0) { |
|---|
| 327 | + if (!fn || fn(disk, info)) { |
|---|
| 321 | 328 | kfree(info); |
|---|
| 322 | 329 | info = NULL; |
|---|
| 323 | 330 | } |
|---|
| .. | .. |
|---|
| 360 | 367 | kfree(geo); |
|---|
| 361 | 368 | out_nogeo: |
|---|
| 362 | 369 | kfree(info); |
|---|
| 370 | +out_symbol: |
|---|
| 371 | + if (fn) |
|---|
| 372 | + symbol_put(dasd_biodasdinfo); |
|---|
| 363 | 373 | out_exit: |
|---|
| 364 | 374 | return res; |
|---|
| 365 | 375 | } |
|---|