diff options
Diffstat (limited to 'drivers/scsi/sd_zbc.c')
-rw-r--r-- | drivers/scsi/sd_zbc.c | 35 |
1 files changed, 15 insertions, 20 deletions
diff --git a/drivers/scsi/sd_zbc.c b/drivers/scsi/sd_zbc.c index 6c348a211ebb..89cf4498f535 100644 --- a/drivers/scsi/sd_zbc.c +++ b/drivers/scsi/sd_zbc.c | |||
@@ -403,7 +403,7 @@ static int sd_zbc_check_capacity(struct scsi_disk *sdkp, unsigned char *buf) | |||
403 | */ | 403 | */ |
404 | static int sd_zbc_check_zone_size(struct scsi_disk *sdkp) | 404 | static int sd_zbc_check_zone_size(struct scsi_disk *sdkp) |
405 | { | 405 | { |
406 | u64 zone_blocks; | 406 | u64 zone_blocks = 0; |
407 | sector_t block = 0; | 407 | sector_t block = 0; |
408 | unsigned char *buf; | 408 | unsigned char *buf; |
409 | unsigned char *rec; | 409 | unsigned char *rec; |
@@ -421,10 +421,8 @@ static int sd_zbc_check_zone_size(struct scsi_disk *sdkp) | |||
421 | 421 | ||
422 | /* Do a report zone to get the same field */ | 422 | /* Do a report zone to get the same field */ |
423 | ret = sd_zbc_report_zones(sdkp, buf, SD_ZBC_BUF_SIZE, 0); | 423 | ret = sd_zbc_report_zones(sdkp, buf, SD_ZBC_BUF_SIZE, 0); |
424 | if (ret) { | 424 | if (ret) |
425 | zone_blocks = 0; | 425 | goto out_free; |
426 | goto out; | ||
427 | } | ||
428 | 426 | ||
429 | same = buf[4] & 0x0f; | 427 | same = buf[4] & 0x0f; |
430 | if (same > 0) { | 428 | if (same > 0) { |
@@ -464,7 +462,7 @@ static int sd_zbc_check_zone_size(struct scsi_disk *sdkp) | |||
464 | ret = sd_zbc_report_zones(sdkp, buf, | 462 | ret = sd_zbc_report_zones(sdkp, buf, |
465 | SD_ZBC_BUF_SIZE, block); | 463 | SD_ZBC_BUF_SIZE, block); |
466 | if (ret) | 464 | if (ret) |
467 | return ret; | 465 | goto out_free; |
468 | } | 466 | } |
469 | 467 | ||
470 | } while (block < sdkp->capacity); | 468 | } while (block < sdkp->capacity); |
@@ -472,35 +470,32 @@ static int sd_zbc_check_zone_size(struct scsi_disk *sdkp) | |||
472 | zone_blocks = sdkp->zone_blocks; | 470 | zone_blocks = sdkp->zone_blocks; |
473 | 471 | ||
474 | out: | 472 | out: |
475 | kfree(buf); | ||
476 | |||
477 | if (!zone_blocks) { | 473 | if (!zone_blocks) { |
478 | if (sdkp->first_scan) | 474 | if (sdkp->first_scan) |
479 | sd_printk(KERN_NOTICE, sdkp, | 475 | sd_printk(KERN_NOTICE, sdkp, |
480 | "Devices with non constant zone " | 476 | "Devices with non constant zone " |
481 | "size are not supported\n"); | 477 | "size are not supported\n"); |
482 | return -ENODEV; | 478 | ret = -ENODEV; |
483 | } | 479 | } else if (!is_power_of_2(zone_blocks)) { |
484 | |||
485 | if (!is_power_of_2(zone_blocks)) { | ||
486 | if (sdkp->first_scan) | 480 | if (sdkp->first_scan) |
487 | sd_printk(KERN_NOTICE, sdkp, | 481 | sd_printk(KERN_NOTICE, sdkp, |
488 | "Devices with non power of 2 zone " | 482 | "Devices with non power of 2 zone " |
489 | "size are not supported\n"); | 483 | "size are not supported\n"); |
490 | return -ENODEV; | 484 | ret = -ENODEV; |
491 | } | 485 | } else if (logical_to_sectors(sdkp->device, zone_blocks) > UINT_MAX) { |
492 | |||
493 | if (logical_to_sectors(sdkp->device, zone_blocks) > UINT_MAX) { | ||
494 | if (sdkp->first_scan) | 486 | if (sdkp->first_scan) |
495 | sd_printk(KERN_NOTICE, sdkp, | 487 | sd_printk(KERN_NOTICE, sdkp, |
496 | "Zone size too large\n"); | 488 | "Zone size too large\n"); |
497 | return -ENODEV; | 489 | ret = -ENODEV; |
490 | } else { | ||
491 | sdkp->zone_blocks = zone_blocks; | ||
492 | sdkp->zone_shift = ilog2(zone_blocks); | ||
498 | } | 493 | } |
499 | 494 | ||
500 | sdkp->zone_blocks = zone_blocks; | 495 | out_free: |
501 | sdkp->zone_shift = ilog2(zone_blocks); | 496 | kfree(buf); |
502 | 497 | ||
503 | return 0; | 498 | return ret; |
504 | } | 499 | } |
505 | 500 | ||
506 | /** | 501 | /** |