Lines Matching refs:sdkp
73 static int sd_zbc_parse_report(struct scsi_disk *sdkp, const u8 buf[64], in sd_zbc_parse_report() argument
76 struct scsi_device *sdp = sdkp->device; in sd_zbc_parse_report()
95 if (sdkp->zone_starting_lba_gran) { in sd_zbc_parse_report()
96 gran = logical_to_sectors(sdp, sdkp->zone_starting_lba_gran); in sd_zbc_parse_report()
98 sd_printk(KERN_ERR, sdkp, in sd_zbc_parse_report()
121 if (sdkp->rev_wp_offset) in sd_zbc_parse_report()
122 sdkp->rev_wp_offset[idx] = sd_zbc_get_zone_wp_offset(&zone); in sd_zbc_parse_report()
141 static int sd_zbc_do_report_zones(struct scsi_disk *sdkp, unsigned char *buf, in sd_zbc_do_report_zones() argument
145 struct scsi_device *sdp = sdkp->device; in sd_zbc_do_report_zones()
164 sd_printk(KERN_ERR, sdkp, in sd_zbc_do_report_zones()
166 sd_print_result(sdkp, "REPORT ZONES", result); in sd_zbc_do_report_zones()
168 sd_print_sense_hdr(sdkp, &sshdr); in sd_zbc_do_report_zones()
174 sd_printk(KERN_ERR, sdkp, in sd_zbc_do_report_zones()
196 static void *sd_zbc_alloc_report_buffer(struct scsi_disk *sdkp, in sd_zbc_alloc_report_buffer() argument
199 struct request_queue *q = sdkp->disk->queue; in sd_zbc_alloc_report_buffer()
212 nr_zones = min(nr_zones, sdkp->zone_info.nr_zones); in sd_zbc_alloc_report_buffer()
235 static inline sector_t sd_zbc_zone_sectors(struct scsi_disk *sdkp) in sd_zbc_zone_sectors() argument
237 return logical_to_sectors(sdkp->device, sdkp->zone_info.zone_blocks); in sd_zbc_zone_sectors()
254 struct scsi_disk *sdkp = scsi_disk(disk); in sd_zbc_report_zones() local
255 sector_t lba = sectors_to_logical(sdkp->device, sector); in sd_zbc_report_zones()
263 if (!sd_is_zoned(sdkp)) in sd_zbc_report_zones()
267 if (!sdkp->capacity) in sd_zbc_report_zones()
271 buf = sd_zbc_alloc_report_buffer(sdkp, nr_zones, &buflen); in sd_zbc_report_zones()
275 while (zone_idx < nr_zones && lba < sdkp->capacity) { in sd_zbc_report_zones()
276 ret = sd_zbc_do_report_zones(sdkp, buf, buflen, lba, true); in sd_zbc_report_zones()
294 sd_printk(KERN_ERR, sdkp, in sd_zbc_report_zones()
302 if (sdkp->zone_starting_lba_gran) in sd_zbc_report_zones()
304 sd_printk(KERN_ERR, sdkp, in sd_zbc_report_zones()
310 ret = sd_zbc_parse_report(sdkp, buf + offset, zone_idx, in sd_zbc_report_zones()
328 struct scsi_disk *sdkp = scsi_disk(rq->q->disk); in sd_zbc_cmnd_checks() local
331 if (!sd_is_zoned(sdkp)) in sd_zbc_cmnd_checks()
335 if (sdkp->device->changed) in sd_zbc_cmnd_checks()
338 if (sector & (sd_zbc_zone_sectors(sdkp) - 1)) in sd_zbc_cmnd_checks()
351 struct scsi_disk *sdkp = data; in sd_zbc_update_wp_offset_cb() local
353 lockdep_assert_held(&sdkp->zones_wp_offset_lock); in sd_zbc_update_wp_offset_cb()
355 sdkp->zones_wp_offset[idx] = sd_zbc_get_zone_wp_offset(zone); in sd_zbc_update_wp_offset_cb()
366 struct scsi_disk *sdkp; in sd_zbc_update_wp_offset_workfn() local
371 sdkp = container_of(work, struct scsi_disk, zone_wp_offset_work); in sd_zbc_update_wp_offset_workfn()
373 spin_lock_irqsave(&sdkp->zones_wp_offset_lock, flags); in sd_zbc_update_wp_offset_workfn()
374 for (zno = 0; zno < sdkp->zone_info.nr_zones; zno++) { in sd_zbc_update_wp_offset_workfn()
375 if (sdkp->zones_wp_offset[zno] != SD_ZBC_UPDATING_WP_OFST) in sd_zbc_update_wp_offset_workfn()
378 spin_unlock_irqrestore(&sdkp->zones_wp_offset_lock, flags); in sd_zbc_update_wp_offset_workfn()
379 ret = sd_zbc_do_report_zones(sdkp, sdkp->zone_wp_update_buf, in sd_zbc_update_wp_offset_workfn()
381 zno * sdkp->zone_info.zone_blocks, true); in sd_zbc_update_wp_offset_workfn()
382 spin_lock_irqsave(&sdkp->zones_wp_offset_lock, flags); in sd_zbc_update_wp_offset_workfn()
384 sd_zbc_parse_report(sdkp, sdkp->zone_wp_update_buf + 64, in sd_zbc_update_wp_offset_workfn()
386 sdkp); in sd_zbc_update_wp_offset_workfn()
388 spin_unlock_irqrestore(&sdkp->zones_wp_offset_lock, flags); in sd_zbc_update_wp_offset_workfn()
390 scsi_device_put(sdkp->device); in sd_zbc_update_wp_offset_workfn()
410 struct scsi_disk *sdkp = scsi_disk(rq->q->disk); in sd_zbc_prepare_zone_append() local
426 spin_lock_irqsave(&sdkp->zones_wp_offset_lock, flags); in sd_zbc_prepare_zone_append()
427 wp_offset = sdkp->zones_wp_offset[zno]; in sd_zbc_prepare_zone_append()
436 if (scsi_device_get(sdkp->device)) { in sd_zbc_prepare_zone_append()
440 sdkp->zones_wp_offset[zno] = SD_ZBC_UPDATING_WP_OFST; in sd_zbc_prepare_zone_append()
441 schedule_work(&sdkp->zone_wp_offset_work); in sd_zbc_prepare_zone_append()
447 wp_offset = sectors_to_logical(sdkp->device, wp_offset); in sd_zbc_prepare_zone_append()
448 if (wp_offset + nr_blocks > sdkp->zone_info.zone_blocks) { in sd_zbc_prepare_zone_append()
455 spin_unlock_irqrestore(&sdkp->zones_wp_offset_lock, flags); in sd_zbc_prepare_zone_append()
476 struct scsi_disk *sdkp = scsi_disk(rq->q->disk); in sd_zbc_setup_zone_mgmt_cmnd() local
477 sector_t block = sectors_to_logical(sdkp->device, sector); in sd_zbc_setup_zone_mgmt_cmnd()
530 struct scsi_disk *sdkp = scsi_disk(rq->q->disk); in sd_zbc_zone_wp_update() local
541 spin_lock_irqsave(&sdkp->zones_wp_offset_lock, flags); in sd_zbc_zone_wp_update()
554 if (sdkp->zones_wp_offset[zno] != SD_ZBC_UPDATING_WP_OFST) in sd_zbc_zone_wp_update()
555 sdkp->zones_wp_offset[zno] = SD_ZBC_INVALID_WP_OFST; in sd_zbc_zone_wp_update()
561 rq->__sector += sdkp->zones_wp_offset[zno]; in sd_zbc_zone_wp_update()
565 if (sdkp->zones_wp_offset[zno] < sd_zbc_zone_sectors(sdkp)) in sd_zbc_zone_wp_update()
566 sdkp->zones_wp_offset[zno] += in sd_zbc_zone_wp_update()
570 sdkp->zones_wp_offset[zno] = 0; in sd_zbc_zone_wp_update()
573 sdkp->zones_wp_offset[zno] = sd_zbc_zone_sectors(sdkp); in sd_zbc_zone_wp_update()
576 memset(sdkp->zones_wp_offset, 0, in sd_zbc_zone_wp_update()
577 sdkp->zone_info.nr_zones * sizeof(unsigned int)); in sd_zbc_zone_wp_update()
584 spin_unlock_irqrestore(&sdkp->zones_wp_offset_lock, flags); in sd_zbc_zone_wp_update()
630 static int sd_zbc_check_zoned_characteristics(struct scsi_disk *sdkp, in sd_zbc_check_zoned_characteristics() argument
635 if (scsi_get_vpd_page(sdkp->device, 0xb6, buf, 64)) { in sd_zbc_check_zoned_characteristics()
636 sd_printk(KERN_NOTICE, sdkp, in sd_zbc_check_zoned_characteristics()
641 if (sdkp->device->type != TYPE_ZBC) { in sd_zbc_check_zoned_characteristics()
643 sdkp->urswrz = 1; in sd_zbc_check_zoned_characteristics()
644 sdkp->zones_optimal_open = get_unaligned_be32(&buf[8]); in sd_zbc_check_zoned_characteristics()
645 sdkp->zones_optimal_nonseq = get_unaligned_be32(&buf[12]); in sd_zbc_check_zoned_characteristics()
646 sdkp->zones_max_open = 0; in sd_zbc_check_zoned_characteristics()
651 sdkp->urswrz = buf[4] & 1; in sd_zbc_check_zoned_characteristics()
652 sdkp->zones_optimal_open = 0; in sd_zbc_check_zoned_characteristics()
653 sdkp->zones_optimal_nonseq = 0; in sd_zbc_check_zoned_characteristics()
654 sdkp->zones_max_open = get_unaligned_be32(&buf[16]); in sd_zbc_check_zoned_characteristics()
665 logical_to_sectors(sdkp->device, zone_starting_lba_gran) > in sd_zbc_check_zoned_characteristics()
667 sd_printk(KERN_ERR, sdkp, in sd_zbc_check_zoned_characteristics()
672 sdkp->zone_starting_lba_gran = zone_starting_lba_gran; in sd_zbc_check_zoned_characteristics()
675 sd_printk(KERN_ERR, sdkp, "Invalid zone alignment method\n"); in sd_zbc_check_zoned_characteristics()
684 if (!sdkp->urswrz) { in sd_zbc_check_zoned_characteristics()
685 if (sdkp->first_scan) in sd_zbc_check_zoned_characteristics()
686 sd_printk(KERN_NOTICE, sdkp, in sd_zbc_check_zoned_characteristics()
706 static int sd_zbc_check_capacity(struct scsi_disk *sdkp, unsigned char *buf, in sd_zbc_check_capacity() argument
715 ret = sd_zbc_do_report_zones(sdkp, buf, SD_BUF_SIZE, 0, false); in sd_zbc_check_capacity()
719 if (sdkp->rc_basis == 0) { in sd_zbc_check_capacity()
722 if (sdkp->capacity != max_lba + 1) { in sd_zbc_check_capacity()
723 if (sdkp->first_scan) in sd_zbc_check_capacity()
724 sd_printk(KERN_WARNING, sdkp, in sd_zbc_check_capacity()
726 (unsigned long long)sdkp->capacity, in sd_zbc_check_capacity()
728 sdkp->capacity = max_lba + 1; in sd_zbc_check_capacity()
732 if (sdkp->zone_starting_lba_gran == 0) { in sd_zbc_check_capacity()
736 if (logical_to_sectors(sdkp->device, zone_blocks) > UINT_MAX) { in sd_zbc_check_capacity()
737 if (sdkp->first_scan) in sd_zbc_check_capacity()
738 sd_printk(KERN_NOTICE, sdkp, in sd_zbc_check_capacity()
743 zone_blocks = sdkp->zone_starting_lba_gran; in sd_zbc_check_capacity()
747 sd_printk(KERN_ERR, sdkp, in sd_zbc_check_capacity()
758 static void sd_zbc_print_zones(struct scsi_disk *sdkp) in sd_zbc_print_zones() argument
760 if (!sd_is_zoned(sdkp) || !sdkp->capacity) in sd_zbc_print_zones()
763 if (sdkp->capacity & (sdkp->zone_info.zone_blocks - 1)) in sd_zbc_print_zones()
764 sd_printk(KERN_NOTICE, sdkp, in sd_zbc_print_zones()
766 sdkp->zone_info.nr_zones - 1, in sd_zbc_print_zones()
767 sdkp->zone_info.zone_blocks); in sd_zbc_print_zones()
769 sd_printk(KERN_NOTICE, sdkp, in sd_zbc_print_zones()
771 sdkp->zone_info.nr_zones, in sd_zbc_print_zones()
772 sdkp->zone_info.zone_blocks); in sd_zbc_print_zones()
775 static int sd_zbc_init_disk(struct scsi_disk *sdkp) in sd_zbc_init_disk() argument
777 sdkp->zones_wp_offset = NULL; in sd_zbc_init_disk()
778 spin_lock_init(&sdkp->zones_wp_offset_lock); in sd_zbc_init_disk()
779 sdkp->rev_wp_offset = NULL; in sd_zbc_init_disk()
780 mutex_init(&sdkp->rev_mutex); in sd_zbc_init_disk()
781 INIT_WORK(&sdkp->zone_wp_offset_work, sd_zbc_update_wp_offset_workfn); in sd_zbc_init_disk()
782 sdkp->zone_wp_update_buf = kzalloc(SD_BUF_SIZE, GFP_KERNEL); in sd_zbc_init_disk()
783 if (!sdkp->zone_wp_update_buf) in sd_zbc_init_disk()
789 void sd_zbc_free_zone_info(struct scsi_disk *sdkp) in sd_zbc_free_zone_info() argument
791 if (!sdkp->zone_wp_update_buf) in sd_zbc_free_zone_info()
795 mutex_lock(&sdkp->rev_mutex); in sd_zbc_free_zone_info()
797 kvfree(sdkp->zones_wp_offset); in sd_zbc_free_zone_info()
798 sdkp->zones_wp_offset = NULL; in sd_zbc_free_zone_info()
799 kfree(sdkp->zone_wp_update_buf); in sd_zbc_free_zone_info()
800 sdkp->zone_wp_update_buf = NULL; in sd_zbc_free_zone_info()
802 sdkp->early_zone_info = (struct zoned_disk_info){ }; in sd_zbc_free_zone_info()
803 sdkp->zone_info = (struct zoned_disk_info){ }; in sd_zbc_free_zone_info()
805 mutex_unlock(&sdkp->rev_mutex); in sd_zbc_free_zone_info()
810 struct scsi_disk *sdkp = scsi_disk(disk); in sd_zbc_revalidate_zones_cb() local
812 swap(sdkp->zones_wp_offset, sdkp->rev_wp_offset); in sd_zbc_revalidate_zones_cb()
820 int sd_zbc_revalidate_zones(struct scsi_disk *sdkp) in sd_zbc_revalidate_zones() argument
822 struct gendisk *disk = sdkp->disk; in sd_zbc_revalidate_zones()
824 u32 zone_blocks = sdkp->early_zone_info.zone_blocks; in sd_zbc_revalidate_zones()
825 unsigned int nr_zones = sdkp->early_zone_info.nr_zones; in sd_zbc_revalidate_zones()
837 if (sd_is_zoned(sdkp) && !sdkp->zone_wp_update_buf) { in sd_zbc_revalidate_zones()
838 ret = sd_zbc_init_disk(sdkp); in sd_zbc_revalidate_zones()
854 mutex_lock(&sdkp->rev_mutex); in sd_zbc_revalidate_zones()
856 if (sdkp->zone_info.zone_blocks == zone_blocks && in sd_zbc_revalidate_zones()
857 sdkp->zone_info.nr_zones == nr_zones && in sd_zbc_revalidate_zones()
862 sdkp->zone_info.zone_blocks = zone_blocks; in sd_zbc_revalidate_zones()
863 sdkp->zone_info.nr_zones = nr_zones; in sd_zbc_revalidate_zones()
864 sdkp->rev_wp_offset = kvcalloc(nr_zones, sizeof(u32), GFP_KERNEL); in sd_zbc_revalidate_zones()
865 if (!sdkp->rev_wp_offset) { in sd_zbc_revalidate_zones()
874 kvfree(sdkp->rev_wp_offset); in sd_zbc_revalidate_zones()
875 sdkp->rev_wp_offset = NULL; in sd_zbc_revalidate_zones()
878 sdkp->zone_info = (struct zoned_disk_info){ }; in sd_zbc_revalidate_zones()
879 sdkp->capacity = 0; in sd_zbc_revalidate_zones()
883 max_append = min_t(u32, logical_to_sectors(sdkp->device, zone_blocks), in sd_zbc_revalidate_zones()
889 sd_zbc_print_zones(sdkp); in sd_zbc_revalidate_zones()
892 mutex_unlock(&sdkp->rev_mutex); in sd_zbc_revalidate_zones()
906 int sd_zbc_read_zones(struct scsi_disk *sdkp, u8 buf[SD_BUF_SIZE]) in sd_zbc_read_zones() argument
908 struct gendisk *disk = sdkp->disk; in sd_zbc_read_zones()
914 if (!sd_is_zoned(sdkp)) { in sd_zbc_read_zones()
920 sd_zbc_free_zone_info(sdkp); in sd_zbc_read_zones()
925 sdkp->device->use_16_for_rw = 1; in sd_zbc_read_zones()
926 sdkp->device->use_10_for_rw = 0; in sd_zbc_read_zones()
935 sd_zbc_free_zone_info(sdkp); in sd_zbc_read_zones()
940 ret = sd_zbc_check_zoned_characteristics(sdkp, buf); in sd_zbc_read_zones()
945 ret = sd_zbc_check_capacity(sdkp, buf, &zone_blocks); in sd_zbc_read_zones()
952 if (sdkp->zones_max_open == U32_MAX) in sd_zbc_read_zones()
955 disk_set_max_open_zones(disk, sdkp->zones_max_open); in sd_zbc_read_zones()
957 nr_zones = round_up(sdkp->capacity, zone_blocks) >> ilog2(zone_blocks); in sd_zbc_read_zones()
965 blk_queue_zone_write_granularity(q, sdkp->physical_block_size); in sd_zbc_read_zones()
967 sdkp->early_zone_info.nr_zones = nr_zones; in sd_zbc_read_zones()
968 sdkp->early_zone_info.zone_blocks = zone_blocks; in sd_zbc_read_zones()
973 sdkp->capacity = 0; in sd_zbc_read_zones()