Lines Matching refs:sdkp
47 static int sd_zbc_parse_report(struct scsi_disk *sdkp, u8 *buf, in sd_zbc_parse_report() argument
50 struct scsi_device *sdp = sdkp->device; in sd_zbc_parse_report()
73 if (sdkp->rev_wp_offset) in sd_zbc_parse_report()
74 sdkp->rev_wp_offset[idx] = sd_zbc_get_zone_wp_offset(&zone); in sd_zbc_parse_report()
93 static int sd_zbc_do_report_zones(struct scsi_disk *sdkp, unsigned char *buf, in sd_zbc_do_report_zones() argument
97 struct scsi_device *sdp = sdkp->device; in sd_zbc_do_report_zones()
116 sd_printk(KERN_ERR, sdkp, in sd_zbc_do_report_zones()
118 sd_print_result(sdkp, "REPORT ZONES", result); in sd_zbc_do_report_zones()
120 sd_print_sense_hdr(sdkp, &sshdr); in sd_zbc_do_report_zones()
126 sd_printk(KERN_ERR, sdkp, in sd_zbc_do_report_zones()
148 static void *sd_zbc_alloc_report_buffer(struct scsi_disk *sdkp, in sd_zbc_alloc_report_buffer() argument
151 struct request_queue *q = sdkp->disk->queue; in sd_zbc_alloc_report_buffer()
164 nr_zones = min(nr_zones, sdkp->nr_zones); in sd_zbc_alloc_report_buffer()
187 static inline sector_t sd_zbc_zone_sectors(struct scsi_disk *sdkp) in sd_zbc_zone_sectors() argument
189 return logical_to_sectors(sdkp->device, sdkp->zone_blocks); in sd_zbc_zone_sectors()
195 struct scsi_disk *sdkp = scsi_disk(disk); in sd_zbc_report_zones() local
196 sector_t capacity = logical_to_sectors(sdkp->device, sdkp->capacity); in sd_zbc_report_zones()
203 if (!sd_is_zoned(sdkp)) in sd_zbc_report_zones()
211 buf = sd_zbc_alloc_report_buffer(sdkp, nr_zones, &buflen); in sd_zbc_report_zones()
216 ret = sd_zbc_do_report_zones(sdkp, buf, buflen, in sd_zbc_report_zones()
217 sectors_to_logical(sdkp->device, sector), true); in sd_zbc_report_zones()
228 ret = sd_zbc_parse_report(sdkp, buf + offset, zone_idx, in sd_zbc_report_zones()
235 sector += sd_zbc_zone_sectors(sdkp) * i; in sd_zbc_report_zones()
247 struct scsi_disk *sdkp = scsi_disk(rq->rq_disk); in sd_zbc_cmnd_checks() local
250 if (!sd_is_zoned(sdkp)) in sd_zbc_cmnd_checks()
254 if (sdkp->device->changed) in sd_zbc_cmnd_checks()
257 if (sector & (sd_zbc_zone_sectors(sdkp) - 1)) in sd_zbc_cmnd_checks()
270 struct scsi_disk *sdkp = data; in sd_zbc_update_wp_offset_cb() local
272 lockdep_assert_held(&sdkp->zones_wp_offset_lock); in sd_zbc_update_wp_offset_cb()
274 sdkp->zones_wp_offset[idx] = sd_zbc_get_zone_wp_offset(zone); in sd_zbc_update_wp_offset_cb()
281 struct scsi_disk *sdkp; in sd_zbc_update_wp_offset_workfn() local
286 sdkp = container_of(work, struct scsi_disk, zone_wp_offset_work); in sd_zbc_update_wp_offset_workfn()
288 spin_lock_irqsave(&sdkp->zones_wp_offset_lock, flags); in sd_zbc_update_wp_offset_workfn()
289 for (zno = 0; zno < sdkp->nr_zones; zno++) { in sd_zbc_update_wp_offset_workfn()
290 if (sdkp->zones_wp_offset[zno] != SD_ZBC_UPDATING_WP_OFST) in sd_zbc_update_wp_offset_workfn()
293 spin_unlock_irqrestore(&sdkp->zones_wp_offset_lock, flags); in sd_zbc_update_wp_offset_workfn()
294 ret = sd_zbc_do_report_zones(sdkp, sdkp->zone_wp_update_buf, in sd_zbc_update_wp_offset_workfn()
296 zno * sdkp->zone_blocks, true); in sd_zbc_update_wp_offset_workfn()
297 spin_lock_irqsave(&sdkp->zones_wp_offset_lock, flags); in sd_zbc_update_wp_offset_workfn()
299 sd_zbc_parse_report(sdkp, sdkp->zone_wp_update_buf + 64, in sd_zbc_update_wp_offset_workfn()
301 sdkp); in sd_zbc_update_wp_offset_workfn()
303 spin_unlock_irqrestore(&sdkp->zones_wp_offset_lock, flags); in sd_zbc_update_wp_offset_workfn()
305 scsi_device_put(sdkp->device); in sd_zbc_update_wp_offset_workfn()
325 struct scsi_disk *sdkp = scsi_disk(rq->rq_disk); in sd_zbc_prepare_zone_append() local
341 spin_lock_irqsave(&sdkp->zones_wp_offset_lock, flags); in sd_zbc_prepare_zone_append()
342 wp_offset = sdkp->zones_wp_offset[zno]; in sd_zbc_prepare_zone_append()
351 if (scsi_device_get(sdkp->device)) { in sd_zbc_prepare_zone_append()
355 sdkp->zones_wp_offset[zno] = SD_ZBC_UPDATING_WP_OFST; in sd_zbc_prepare_zone_append()
356 schedule_work(&sdkp->zone_wp_offset_work); in sd_zbc_prepare_zone_append()
362 wp_offset = sectors_to_logical(sdkp->device, wp_offset); in sd_zbc_prepare_zone_append()
363 if (wp_offset + nr_blocks > sdkp->zone_blocks) { in sd_zbc_prepare_zone_append()
370 spin_unlock_irqrestore(&sdkp->zones_wp_offset_lock, flags); in sd_zbc_prepare_zone_append()
391 struct scsi_disk *sdkp = scsi_disk(rq->rq_disk); in sd_zbc_setup_zone_mgmt_cmnd() local
392 sector_t block = sectors_to_logical(sdkp->device, sector); in sd_zbc_setup_zone_mgmt_cmnd()
446 struct scsi_disk *sdkp = scsi_disk(rq->rq_disk); in sd_zbc_zone_wp_update() local
457 spin_lock_irqsave(&sdkp->zones_wp_offset_lock, flags); in sd_zbc_zone_wp_update()
470 if (sdkp->zones_wp_offset[zno] != SD_ZBC_UPDATING_WP_OFST) in sd_zbc_zone_wp_update()
471 sdkp->zones_wp_offset[zno] = SD_ZBC_INVALID_WP_OFST; in sd_zbc_zone_wp_update()
477 rq->__sector += sdkp->zones_wp_offset[zno]; in sd_zbc_zone_wp_update()
482 if (sdkp->zones_wp_offset[zno] < sd_zbc_zone_sectors(sdkp)) in sd_zbc_zone_wp_update()
483 sdkp->zones_wp_offset[zno] += in sd_zbc_zone_wp_update()
487 sdkp->zones_wp_offset[zno] = 0; in sd_zbc_zone_wp_update()
490 sdkp->zones_wp_offset[zno] = sd_zbc_zone_sectors(sdkp); in sd_zbc_zone_wp_update()
493 memset(sdkp->zones_wp_offset, 0, in sd_zbc_zone_wp_update()
494 sdkp->nr_zones * sizeof(unsigned int)); in sd_zbc_zone_wp_update()
501 spin_unlock_irqrestore(&sdkp->zones_wp_offset_lock, flags); in sd_zbc_zone_wp_update()
547 static int sd_zbc_check_zoned_characteristics(struct scsi_disk *sdkp, in sd_zbc_check_zoned_characteristics() argument
551 if (scsi_get_vpd_page(sdkp->device, 0xb6, buf, 64)) { in sd_zbc_check_zoned_characteristics()
552 sd_printk(KERN_NOTICE, sdkp, in sd_zbc_check_zoned_characteristics()
557 if (sdkp->device->type != TYPE_ZBC) { in sd_zbc_check_zoned_characteristics()
559 sdkp->urswrz = 1; in sd_zbc_check_zoned_characteristics()
560 sdkp->zones_optimal_open = get_unaligned_be32(&buf[8]); in sd_zbc_check_zoned_characteristics()
561 sdkp->zones_optimal_nonseq = get_unaligned_be32(&buf[12]); in sd_zbc_check_zoned_characteristics()
562 sdkp->zones_max_open = 0; in sd_zbc_check_zoned_characteristics()
565 sdkp->urswrz = buf[4] & 1; in sd_zbc_check_zoned_characteristics()
566 sdkp->zones_optimal_open = 0; in sd_zbc_check_zoned_characteristics()
567 sdkp->zones_optimal_nonseq = 0; in sd_zbc_check_zoned_characteristics()
568 sdkp->zones_max_open = get_unaligned_be32(&buf[16]); in sd_zbc_check_zoned_characteristics()
576 if (!sdkp->urswrz) { in sd_zbc_check_zoned_characteristics()
577 if (sdkp->first_scan) in sd_zbc_check_zoned_characteristics()
578 sd_printk(KERN_NOTICE, sdkp, in sd_zbc_check_zoned_characteristics()
598 static int sd_zbc_check_capacity(struct scsi_disk *sdkp, unsigned char *buf, in sd_zbc_check_capacity() argument
607 ret = sd_zbc_do_report_zones(sdkp, buf, SD_BUF_SIZE, 0, false); in sd_zbc_check_capacity()
611 if (sdkp->rc_basis == 0) { in sd_zbc_check_capacity()
614 if (sdkp->capacity != max_lba + 1) { in sd_zbc_check_capacity()
615 if (sdkp->first_scan) in sd_zbc_check_capacity()
616 sd_printk(KERN_WARNING, sdkp, in sd_zbc_check_capacity()
618 (unsigned long long)sdkp->capacity, in sd_zbc_check_capacity()
620 sdkp->capacity = max_lba + 1; in sd_zbc_check_capacity()
627 if (logical_to_sectors(sdkp->device, zone_blocks) > UINT_MAX) { in sd_zbc_check_capacity()
628 if (sdkp->first_scan) in sd_zbc_check_capacity()
629 sd_printk(KERN_NOTICE, sdkp, in sd_zbc_check_capacity()
639 static void sd_zbc_print_zones(struct scsi_disk *sdkp) in sd_zbc_print_zones() argument
641 if (!sd_is_zoned(sdkp) || !sdkp->capacity) in sd_zbc_print_zones()
644 if (sdkp->capacity & (sdkp->zone_blocks - 1)) in sd_zbc_print_zones()
645 sd_printk(KERN_NOTICE, sdkp, in sd_zbc_print_zones()
647 sdkp->nr_zones - 1, in sd_zbc_print_zones()
648 sdkp->zone_blocks); in sd_zbc_print_zones()
650 sd_printk(KERN_NOTICE, sdkp, in sd_zbc_print_zones()
652 sdkp->nr_zones, in sd_zbc_print_zones()
653 sdkp->zone_blocks); in sd_zbc_print_zones()
656 static int sd_zbc_init_disk(struct scsi_disk *sdkp) in sd_zbc_init_disk() argument
658 sdkp->zones_wp_offset = NULL; in sd_zbc_init_disk()
659 spin_lock_init(&sdkp->zones_wp_offset_lock); in sd_zbc_init_disk()
660 sdkp->rev_wp_offset = NULL; in sd_zbc_init_disk()
661 mutex_init(&sdkp->rev_mutex); in sd_zbc_init_disk()
662 INIT_WORK(&sdkp->zone_wp_offset_work, sd_zbc_update_wp_offset_workfn); in sd_zbc_init_disk()
663 sdkp->zone_wp_update_buf = kzalloc(SD_BUF_SIZE, GFP_KERNEL); in sd_zbc_init_disk()
664 if (!sdkp->zone_wp_update_buf) in sd_zbc_init_disk()
670 static void sd_zbc_clear_zone_info(struct scsi_disk *sdkp) in sd_zbc_clear_zone_info() argument
673 mutex_lock(&sdkp->rev_mutex); in sd_zbc_clear_zone_info()
675 kvfree(sdkp->zones_wp_offset); in sd_zbc_clear_zone_info()
676 sdkp->zones_wp_offset = NULL; in sd_zbc_clear_zone_info()
677 kfree(sdkp->zone_wp_update_buf); in sd_zbc_clear_zone_info()
678 sdkp->zone_wp_update_buf = NULL; in sd_zbc_clear_zone_info()
680 sdkp->nr_zones = 0; in sd_zbc_clear_zone_info()
681 sdkp->rev_nr_zones = 0; in sd_zbc_clear_zone_info()
682 sdkp->zone_blocks = 0; in sd_zbc_clear_zone_info()
683 sdkp->rev_zone_blocks = 0; in sd_zbc_clear_zone_info()
685 mutex_unlock(&sdkp->rev_mutex); in sd_zbc_clear_zone_info()
688 void sd_zbc_release_disk(struct scsi_disk *sdkp) in sd_zbc_release_disk() argument
690 if (sd_is_zoned(sdkp)) in sd_zbc_release_disk()
691 sd_zbc_clear_zone_info(sdkp); in sd_zbc_release_disk()
696 struct scsi_disk *sdkp = scsi_disk(disk); in sd_zbc_revalidate_zones_cb() local
698 swap(sdkp->zones_wp_offset, sdkp->rev_wp_offset); in sd_zbc_revalidate_zones_cb()
701 int sd_zbc_revalidate_zones(struct scsi_disk *sdkp) in sd_zbc_revalidate_zones() argument
703 struct gendisk *disk = sdkp->disk; in sd_zbc_revalidate_zones()
705 u32 zone_blocks = sdkp->rev_zone_blocks; in sd_zbc_revalidate_zones()
706 unsigned int nr_zones = sdkp->rev_nr_zones; in sd_zbc_revalidate_zones()
718 if (sd_is_zoned(sdkp) && !sdkp->zone_wp_update_buf) { in sd_zbc_revalidate_zones()
719 ret = sd_zbc_init_disk(sdkp); in sd_zbc_revalidate_zones()
735 mutex_lock(&sdkp->rev_mutex); in sd_zbc_revalidate_zones()
737 if (sdkp->zone_blocks == zone_blocks && in sd_zbc_revalidate_zones()
738 sdkp->nr_zones == nr_zones && in sd_zbc_revalidate_zones()
743 sdkp->zone_blocks = zone_blocks; in sd_zbc_revalidate_zones()
744 sdkp->nr_zones = nr_zones; in sd_zbc_revalidate_zones()
745 sdkp->rev_wp_offset = kvcalloc(nr_zones, sizeof(u32), GFP_KERNEL); in sd_zbc_revalidate_zones()
746 if (!sdkp->rev_wp_offset) { in sd_zbc_revalidate_zones()
755 kvfree(sdkp->rev_wp_offset); in sd_zbc_revalidate_zones()
756 sdkp->rev_wp_offset = NULL; in sd_zbc_revalidate_zones()
759 sdkp->zone_blocks = 0; in sd_zbc_revalidate_zones()
760 sdkp->nr_zones = 0; in sd_zbc_revalidate_zones()
761 sdkp->capacity = 0; in sd_zbc_revalidate_zones()
765 max_append = min_t(u32, logical_to_sectors(sdkp->device, zone_blocks), in sd_zbc_revalidate_zones()
771 sd_zbc_print_zones(sdkp); in sd_zbc_revalidate_zones()
774 mutex_unlock(&sdkp->rev_mutex); in sd_zbc_revalidate_zones()
779 int sd_zbc_read_zones(struct scsi_disk *sdkp, unsigned char *buf) in sd_zbc_read_zones() argument
781 struct gendisk *disk = sdkp->disk; in sd_zbc_read_zones()
787 if (!sd_is_zoned(sdkp)) in sd_zbc_read_zones()
795 sdkp->device->use_16_for_rw = 1; in sd_zbc_read_zones()
796 sdkp->device->use_10_for_rw = 0; in sd_zbc_read_zones()
805 sd_zbc_clear_zone_info(sdkp); in sd_zbc_read_zones()
810 ret = sd_zbc_check_zoned_characteristics(sdkp, buf); in sd_zbc_read_zones()
815 ret = sd_zbc_check_capacity(sdkp, buf, &zone_blocks); in sd_zbc_read_zones()
822 if (sdkp->zones_max_open == U32_MAX) in sd_zbc_read_zones()
825 blk_queue_max_open_zones(q, sdkp->zones_max_open); in sd_zbc_read_zones()
827 nr_zones = round_up(sdkp->capacity, zone_blocks) >> ilog2(zone_blocks); in sd_zbc_read_zones()
835 blk_queue_zone_write_granularity(q, sdkp->physical_block_size); in sd_zbc_read_zones()
837 sdkp->rev_nr_zones = nr_zones; in sd_zbc_read_zones()
838 sdkp->rev_zone_blocks = zone_blocks; in sd_zbc_read_zones()
843 sdkp->capacity = 0; in sd_zbc_read_zones()