Lines Matching refs:sdkp
76 static int sd_zbc_parse_report(struct scsi_disk *sdkp, const u8 buf[64], in sd_zbc_parse_report() argument
79 struct scsi_device *sdp = sdkp->device; in sd_zbc_parse_report()
98 if (sdkp->zone_starting_lba_gran) { in sd_zbc_parse_report()
99 gran = logical_to_sectors(sdp, sdkp->zone_starting_lba_gran); in sd_zbc_parse_report()
101 sd_printk(KERN_ERR, sdkp, in sd_zbc_parse_report()
124 if (sdkp->rev_wp_offset) in sd_zbc_parse_report()
125 sdkp->rev_wp_offset[idx] = sd_zbc_get_zone_wp_offset(&zone); in sd_zbc_parse_report()
144 static int sd_zbc_do_report_zones(struct scsi_disk *sdkp, unsigned char *buf, in sd_zbc_do_report_zones() argument
148 struct scsi_device *sdp = sdkp->device; in sd_zbc_do_report_zones()
169 sd_printk(KERN_ERR, sdkp, in sd_zbc_do_report_zones()
171 sd_print_result(sdkp, "REPORT ZONES", result); in sd_zbc_do_report_zones()
173 sd_print_sense_hdr(sdkp, &sshdr); in sd_zbc_do_report_zones()
179 sd_printk(KERN_ERR, sdkp, in sd_zbc_do_report_zones()
201 static void *sd_zbc_alloc_report_buffer(struct scsi_disk *sdkp, in sd_zbc_alloc_report_buffer() argument
204 struct request_queue *q = sdkp->disk->queue; in sd_zbc_alloc_report_buffer()
217 nr_zones = min(nr_zones, sdkp->zone_info.nr_zones); in sd_zbc_alloc_report_buffer()
240 static inline sector_t sd_zbc_zone_sectors(struct scsi_disk *sdkp) in sd_zbc_zone_sectors() argument
242 return logical_to_sectors(sdkp->device, sdkp->zone_info.zone_blocks); in sd_zbc_zone_sectors()
259 struct scsi_disk *sdkp = scsi_disk(disk); in sd_zbc_report_zones() local
260 sector_t lba = sectors_to_logical(sdkp->device, sector); in sd_zbc_report_zones()
268 if (!sd_is_zoned(sdkp)) in sd_zbc_report_zones()
272 if (!sdkp->capacity) in sd_zbc_report_zones()
276 buf = sd_zbc_alloc_report_buffer(sdkp, nr_zones, &buflen); in sd_zbc_report_zones()
280 while (zone_idx < nr_zones && lba < sdkp->capacity) { in sd_zbc_report_zones()
281 ret = sd_zbc_do_report_zones(sdkp, buf, buflen, lba, true); in sd_zbc_report_zones()
299 sd_printk(KERN_ERR, sdkp, in sd_zbc_report_zones()
307 if (sdkp->zone_starting_lba_gran) in sd_zbc_report_zones()
309 sd_printk(KERN_ERR, sdkp, in sd_zbc_report_zones()
315 ret = sd_zbc_parse_report(sdkp, buf + offset, zone_idx, in sd_zbc_report_zones()
333 struct scsi_disk *sdkp = scsi_disk(rq->q->disk); in sd_zbc_cmnd_checks() local
336 if (!sd_is_zoned(sdkp)) in sd_zbc_cmnd_checks()
340 if (sdkp->device->changed) in sd_zbc_cmnd_checks()
343 if (sector & (sd_zbc_zone_sectors(sdkp) - 1)) in sd_zbc_cmnd_checks()
356 struct scsi_disk *sdkp = data; in sd_zbc_update_wp_offset_cb() local
358 lockdep_assert_held(&sdkp->zones_wp_offset_lock); in sd_zbc_update_wp_offset_cb()
360 sdkp->zones_wp_offset[idx] = sd_zbc_get_zone_wp_offset(zone); in sd_zbc_update_wp_offset_cb()
371 struct scsi_disk *sdkp; in sd_zbc_update_wp_offset_workfn() local
376 sdkp = container_of(work, struct scsi_disk, zone_wp_offset_work); in sd_zbc_update_wp_offset_workfn()
378 spin_lock_irqsave(&sdkp->zones_wp_offset_lock, flags); in sd_zbc_update_wp_offset_workfn()
379 for (zno = 0; zno < sdkp->zone_info.nr_zones; zno++) { in sd_zbc_update_wp_offset_workfn()
380 if (sdkp->zones_wp_offset[zno] != SD_ZBC_UPDATING_WP_OFST) in sd_zbc_update_wp_offset_workfn()
383 spin_unlock_irqrestore(&sdkp->zones_wp_offset_lock, flags); in sd_zbc_update_wp_offset_workfn()
384 ret = sd_zbc_do_report_zones(sdkp, sdkp->zone_wp_update_buf, in sd_zbc_update_wp_offset_workfn()
386 zno * sdkp->zone_info.zone_blocks, true); in sd_zbc_update_wp_offset_workfn()
387 spin_lock_irqsave(&sdkp->zones_wp_offset_lock, flags); in sd_zbc_update_wp_offset_workfn()
389 sd_zbc_parse_report(sdkp, sdkp->zone_wp_update_buf + 64, in sd_zbc_update_wp_offset_workfn()
391 sdkp); in sd_zbc_update_wp_offset_workfn()
393 spin_unlock_irqrestore(&sdkp->zones_wp_offset_lock, flags); in sd_zbc_update_wp_offset_workfn()
395 scsi_device_put(sdkp->device); in sd_zbc_update_wp_offset_workfn()
415 struct scsi_disk *sdkp = scsi_disk(rq->q->disk); in sd_zbc_prepare_zone_append() local
431 spin_lock_irqsave(&sdkp->zones_wp_offset_lock, flags); in sd_zbc_prepare_zone_append()
432 wp_offset = sdkp->zones_wp_offset[zno]; in sd_zbc_prepare_zone_append()
441 if (scsi_device_get(sdkp->device)) { in sd_zbc_prepare_zone_append()
445 sdkp->zones_wp_offset[zno] = SD_ZBC_UPDATING_WP_OFST; in sd_zbc_prepare_zone_append()
446 schedule_work(&sdkp->zone_wp_offset_work); in sd_zbc_prepare_zone_append()
452 wp_offset = sectors_to_logical(sdkp->device, wp_offset); in sd_zbc_prepare_zone_append()
453 if (wp_offset + nr_blocks > sdkp->zone_info.zone_blocks) { in sd_zbc_prepare_zone_append()
461 spin_unlock_irqrestore(&sdkp->zones_wp_offset_lock, flags); in sd_zbc_prepare_zone_append()
482 struct scsi_disk *sdkp = scsi_disk(rq->q->disk); in sd_zbc_setup_zone_mgmt_cmnd() local
483 sector_t block = sectors_to_logical(sdkp->device, sector); in sd_zbc_setup_zone_mgmt_cmnd()
536 struct scsi_disk *sdkp = scsi_disk(rq->q->disk); in sd_zbc_zone_wp_update() local
547 spin_lock_irqsave(&sdkp->zones_wp_offset_lock, flags); in sd_zbc_zone_wp_update()
560 if (sdkp->zones_wp_offset[zno] != SD_ZBC_UPDATING_WP_OFST) in sd_zbc_zone_wp_update()
561 sdkp->zones_wp_offset[zno] = SD_ZBC_INVALID_WP_OFST; in sd_zbc_zone_wp_update()
568 sdkp->zones_wp_offset[zno], good_bytes); in sd_zbc_zone_wp_update()
569 rq->__sector += sdkp->zones_wp_offset[zno]; in sd_zbc_zone_wp_update()
573 if (sdkp->zones_wp_offset[zno] < sd_zbc_zone_sectors(sdkp)) in sd_zbc_zone_wp_update()
574 sdkp->zones_wp_offset[zno] += in sd_zbc_zone_wp_update()
578 sdkp->zones_wp_offset[zno] = 0; in sd_zbc_zone_wp_update()
581 sdkp->zones_wp_offset[zno] = sd_zbc_zone_sectors(sdkp); in sd_zbc_zone_wp_update()
584 memset(sdkp->zones_wp_offset, 0, in sd_zbc_zone_wp_update()
585 sdkp->zone_info.nr_zones * sizeof(unsigned int)); in sd_zbc_zone_wp_update()
592 spin_unlock_irqrestore(&sdkp->zones_wp_offset_lock, flags); in sd_zbc_zone_wp_update()
638 static int sd_zbc_check_zoned_characteristics(struct scsi_disk *sdkp, in sd_zbc_check_zoned_characteristics() argument
643 if (scsi_get_vpd_page(sdkp->device, 0xb6, buf, 64)) { in sd_zbc_check_zoned_characteristics()
644 sd_printk(KERN_NOTICE, sdkp, in sd_zbc_check_zoned_characteristics()
649 if (sdkp->device->type != TYPE_ZBC) { in sd_zbc_check_zoned_characteristics()
651 sdkp->urswrz = 1; in sd_zbc_check_zoned_characteristics()
652 sdkp->zones_optimal_open = get_unaligned_be32(&buf[8]); in sd_zbc_check_zoned_characteristics()
653 sdkp->zones_optimal_nonseq = get_unaligned_be32(&buf[12]); in sd_zbc_check_zoned_characteristics()
654 sdkp->zones_max_open = 0; in sd_zbc_check_zoned_characteristics()
659 sdkp->urswrz = buf[4] & 1; in sd_zbc_check_zoned_characteristics()
660 sdkp->zones_optimal_open = 0; in sd_zbc_check_zoned_characteristics()
661 sdkp->zones_optimal_nonseq = 0; in sd_zbc_check_zoned_characteristics()
662 sdkp->zones_max_open = get_unaligned_be32(&buf[16]); in sd_zbc_check_zoned_characteristics()
673 logical_to_sectors(sdkp->device, zone_starting_lba_gran) > in sd_zbc_check_zoned_characteristics()
675 sd_printk(KERN_ERR, sdkp, in sd_zbc_check_zoned_characteristics()
680 sdkp->zone_starting_lba_gran = zone_starting_lba_gran; in sd_zbc_check_zoned_characteristics()
683 sd_printk(KERN_ERR, sdkp, "Invalid zone alignment method\n"); in sd_zbc_check_zoned_characteristics()
692 if (!sdkp->urswrz) { in sd_zbc_check_zoned_characteristics()
693 if (sdkp->first_scan) in sd_zbc_check_zoned_characteristics()
694 sd_printk(KERN_NOTICE, sdkp, in sd_zbc_check_zoned_characteristics()
714 static int sd_zbc_check_capacity(struct scsi_disk *sdkp, unsigned char *buf, in sd_zbc_check_capacity() argument
723 ret = sd_zbc_do_report_zones(sdkp, buf, SD_BUF_SIZE, 0, false); in sd_zbc_check_capacity()
727 if (sdkp->rc_basis == 0) { in sd_zbc_check_capacity()
730 if (sdkp->capacity != max_lba + 1) { in sd_zbc_check_capacity()
731 if (sdkp->first_scan) in sd_zbc_check_capacity()
732 sd_printk(KERN_WARNING, sdkp, in sd_zbc_check_capacity()
734 (unsigned long long)sdkp->capacity, in sd_zbc_check_capacity()
736 sdkp->capacity = max_lba + 1; in sd_zbc_check_capacity()
740 if (sdkp->zone_starting_lba_gran == 0) { in sd_zbc_check_capacity()
744 if (logical_to_sectors(sdkp->device, zone_blocks) > UINT_MAX) { in sd_zbc_check_capacity()
745 if (sdkp->first_scan) in sd_zbc_check_capacity()
746 sd_printk(KERN_NOTICE, sdkp, in sd_zbc_check_capacity()
751 zone_blocks = sdkp->zone_starting_lba_gran; in sd_zbc_check_capacity()
755 sd_printk(KERN_ERR, sdkp, in sd_zbc_check_capacity()
766 static void sd_zbc_print_zones(struct scsi_disk *sdkp) in sd_zbc_print_zones() argument
768 if (!sd_is_zoned(sdkp) || !sdkp->capacity) in sd_zbc_print_zones()
771 if (sdkp->capacity & (sdkp->zone_info.zone_blocks - 1)) in sd_zbc_print_zones()
772 sd_printk(KERN_NOTICE, sdkp, in sd_zbc_print_zones()
774 sdkp->zone_info.nr_zones - 1, in sd_zbc_print_zones()
775 sdkp->zone_info.zone_blocks); in sd_zbc_print_zones()
777 sd_printk(KERN_NOTICE, sdkp, in sd_zbc_print_zones()
779 sdkp->zone_info.nr_zones, in sd_zbc_print_zones()
780 sdkp->zone_info.zone_blocks); in sd_zbc_print_zones()
783 static int sd_zbc_init_disk(struct scsi_disk *sdkp) in sd_zbc_init_disk() argument
785 sdkp->zones_wp_offset = NULL; in sd_zbc_init_disk()
786 spin_lock_init(&sdkp->zones_wp_offset_lock); in sd_zbc_init_disk()
787 sdkp->rev_wp_offset = NULL; in sd_zbc_init_disk()
788 mutex_init(&sdkp->rev_mutex); in sd_zbc_init_disk()
789 INIT_WORK(&sdkp->zone_wp_offset_work, sd_zbc_update_wp_offset_workfn); in sd_zbc_init_disk()
790 sdkp->zone_wp_update_buf = kzalloc(SD_BUF_SIZE, GFP_KERNEL); in sd_zbc_init_disk()
791 if (!sdkp->zone_wp_update_buf) in sd_zbc_init_disk()
797 void sd_zbc_free_zone_info(struct scsi_disk *sdkp) in sd_zbc_free_zone_info() argument
799 if (!sdkp->zone_wp_update_buf) in sd_zbc_free_zone_info()
803 mutex_lock(&sdkp->rev_mutex); in sd_zbc_free_zone_info()
805 kvfree(sdkp->zones_wp_offset); in sd_zbc_free_zone_info()
806 sdkp->zones_wp_offset = NULL; in sd_zbc_free_zone_info()
807 kfree(sdkp->zone_wp_update_buf); in sd_zbc_free_zone_info()
808 sdkp->zone_wp_update_buf = NULL; in sd_zbc_free_zone_info()
810 sdkp->early_zone_info = (struct zoned_disk_info){ }; in sd_zbc_free_zone_info()
811 sdkp->zone_info = (struct zoned_disk_info){ }; in sd_zbc_free_zone_info()
813 mutex_unlock(&sdkp->rev_mutex); in sd_zbc_free_zone_info()
818 struct scsi_disk *sdkp = scsi_disk(disk); in sd_zbc_revalidate_zones_cb() local
820 swap(sdkp->zones_wp_offset, sdkp->rev_wp_offset); in sd_zbc_revalidate_zones_cb()
828 int sd_zbc_revalidate_zones(struct scsi_disk *sdkp) in sd_zbc_revalidate_zones() argument
830 struct gendisk *disk = sdkp->disk; in sd_zbc_revalidate_zones()
832 u32 zone_blocks = sdkp->early_zone_info.zone_blocks; in sd_zbc_revalidate_zones()
833 unsigned int nr_zones = sdkp->early_zone_info.nr_zones; in sd_zbc_revalidate_zones()
844 if (sd_is_zoned(sdkp) && !sdkp->zone_wp_update_buf) { in sd_zbc_revalidate_zones()
845 ret = sd_zbc_init_disk(sdkp); in sd_zbc_revalidate_zones()
861 mutex_lock(&sdkp->rev_mutex); in sd_zbc_revalidate_zones()
863 if (sdkp->zone_info.zone_blocks == zone_blocks && in sd_zbc_revalidate_zones()
864 sdkp->zone_info.nr_zones == nr_zones && in sd_zbc_revalidate_zones()
869 sdkp->zone_info.zone_blocks = zone_blocks; in sd_zbc_revalidate_zones()
870 sdkp->zone_info.nr_zones = nr_zones; in sd_zbc_revalidate_zones()
871 sdkp->rev_wp_offset = kvcalloc(nr_zones, sizeof(u32), GFP_KERNEL); in sd_zbc_revalidate_zones()
872 if (!sdkp->rev_wp_offset) { in sd_zbc_revalidate_zones()
879 logical_to_sectors(sdkp->device, zone_blocks)); in sd_zbc_revalidate_zones()
886 kvfree(sdkp->rev_wp_offset); in sd_zbc_revalidate_zones()
887 sdkp->rev_wp_offset = NULL; in sd_zbc_revalidate_zones()
890 sdkp->zone_info = (struct zoned_disk_info){ }; in sd_zbc_revalidate_zones()
891 sdkp->capacity = 0; in sd_zbc_revalidate_zones()
895 sd_zbc_print_zones(sdkp); in sd_zbc_revalidate_zones()
898 mutex_unlock(&sdkp->rev_mutex); in sd_zbc_revalidate_zones()
912 int sd_zbc_read_zones(struct scsi_disk *sdkp, u8 buf[SD_BUF_SIZE]) in sd_zbc_read_zones() argument
914 struct gendisk *disk = sdkp->disk; in sd_zbc_read_zones()
920 if (!sd_is_zoned(sdkp)) { in sd_zbc_read_zones()
926 sd_zbc_free_zone_info(sdkp); in sd_zbc_read_zones()
931 sdkp->device->use_16_for_rw = 1; in sd_zbc_read_zones()
932 sdkp->device->use_10_for_rw = 0; in sd_zbc_read_zones()
933 sdkp->device->use_16_for_sync = 1; in sd_zbc_read_zones()
942 sd_zbc_free_zone_info(sdkp); in sd_zbc_read_zones()
947 ret = sd_zbc_check_zoned_characteristics(sdkp, buf); in sd_zbc_read_zones()
952 ret = sd_zbc_check_capacity(sdkp, buf, &zone_blocks); in sd_zbc_read_zones()
959 if (sdkp->zones_max_open == U32_MAX) in sd_zbc_read_zones()
962 disk_set_max_open_zones(disk, sdkp->zones_max_open); in sd_zbc_read_zones()
964 nr_zones = round_up(sdkp->capacity, zone_blocks) >> ilog2(zone_blocks); in sd_zbc_read_zones()
966 sdkp->early_zone_info.nr_zones = nr_zones; in sd_zbc_read_zones()
967 sdkp->early_zone_info.zone_blocks = zone_blocks; in sd_zbc_read_zones()
972 sdkp->capacity = 0; in sd_zbc_read_zones()