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()
121 sd_print_sense_hdr(sdkp, &sshdr); in sd_zbc_do_report_zones()
127 sd_printk(KERN_ERR, sdkp, in sd_zbc_do_report_zones()
149 static void *sd_zbc_alloc_report_buffer(struct scsi_disk *sdkp, in sd_zbc_alloc_report_buffer() argument
152 struct request_queue *q = sdkp->disk->queue; in sd_zbc_alloc_report_buffer()
165 nr_zones = min(nr_zones, sdkp->nr_zones); in sd_zbc_alloc_report_buffer()
188 static inline sector_t sd_zbc_zone_sectors(struct scsi_disk *sdkp) in sd_zbc_zone_sectors() argument
190 return logical_to_sectors(sdkp->device, sdkp->zone_blocks); in sd_zbc_zone_sectors()
196 struct scsi_disk *sdkp = scsi_disk(disk); in sd_zbc_report_zones() local
197 sector_t capacity = logical_to_sectors(sdkp->device, sdkp->capacity); in sd_zbc_report_zones()
204 if (!sd_is_zoned(sdkp)) in sd_zbc_report_zones()
212 buf = sd_zbc_alloc_report_buffer(sdkp, nr_zones, &buflen); in sd_zbc_report_zones()
217 ret = sd_zbc_do_report_zones(sdkp, buf, buflen, in sd_zbc_report_zones()
218 sectors_to_logical(sdkp->device, sector), true); in sd_zbc_report_zones()
229 ret = sd_zbc_parse_report(sdkp, buf + offset, zone_idx, in sd_zbc_report_zones()
236 sector += sd_zbc_zone_sectors(sdkp) * i; in sd_zbc_report_zones()
248 struct scsi_disk *sdkp = scsi_disk(rq->rq_disk); in sd_zbc_cmnd_checks() local
251 if (!sd_is_zoned(sdkp)) in sd_zbc_cmnd_checks()
255 if (sdkp->device->changed) in sd_zbc_cmnd_checks()
258 if (sector & (sd_zbc_zone_sectors(sdkp) - 1)) in sd_zbc_cmnd_checks()
271 struct scsi_disk *sdkp = data; in sd_zbc_update_wp_offset_cb() local
273 lockdep_assert_held(&sdkp->zones_wp_offset_lock); in sd_zbc_update_wp_offset_cb()
275 sdkp->zones_wp_offset[idx] = sd_zbc_get_zone_wp_offset(zone); in sd_zbc_update_wp_offset_cb()
282 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_bh(&sdkp->zones_wp_offset_lock); 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_bh(&sdkp->zones_wp_offset_lock); 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_bh(&sdkp->zones_wp_offset_lock); 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_bh(&sdkp->zones_wp_offset_lock); 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
340 spin_lock_bh(&sdkp->zones_wp_offset_lock); in sd_zbc_prepare_zone_append()
341 wp_offset = sdkp->zones_wp_offset[zno]; in sd_zbc_prepare_zone_append()
350 if (scsi_device_get(sdkp->device)) { in sd_zbc_prepare_zone_append()
354 sdkp->zones_wp_offset[zno] = SD_ZBC_UPDATING_WP_OFST; in sd_zbc_prepare_zone_append()
355 schedule_work(&sdkp->zone_wp_offset_work); in sd_zbc_prepare_zone_append()
361 wp_offset = sectors_to_logical(sdkp->device, wp_offset); in sd_zbc_prepare_zone_append()
362 if (wp_offset + nr_blocks > sdkp->zone_blocks) { in sd_zbc_prepare_zone_append()
369 spin_unlock_bh(&sdkp->zones_wp_offset_lock); in sd_zbc_prepare_zone_append()
390 struct scsi_disk *sdkp = scsi_disk(rq->rq_disk); in sd_zbc_setup_zone_mgmt_cmnd() local
391 sector_t block = sectors_to_logical(sdkp->device, sector); in sd_zbc_setup_zone_mgmt_cmnd()
445 struct scsi_disk *sdkp = scsi_disk(rq->rq_disk); in sd_zbc_zone_wp_update() local
455 spin_lock_bh(&sdkp->zones_wp_offset_lock); in sd_zbc_zone_wp_update()
468 if (sdkp->zones_wp_offset[zno] != SD_ZBC_UPDATING_WP_OFST) in sd_zbc_zone_wp_update()
469 sdkp->zones_wp_offset[zno] = SD_ZBC_INVALID_WP_OFST; in sd_zbc_zone_wp_update()
475 rq->__sector += sdkp->zones_wp_offset[zno]; in sd_zbc_zone_wp_update()
480 if (sdkp->zones_wp_offset[zno] < sd_zbc_zone_sectors(sdkp)) in sd_zbc_zone_wp_update()
481 sdkp->zones_wp_offset[zno] += in sd_zbc_zone_wp_update()
485 sdkp->zones_wp_offset[zno] = 0; in sd_zbc_zone_wp_update()
488 sdkp->zones_wp_offset[zno] = sd_zbc_zone_sectors(sdkp); in sd_zbc_zone_wp_update()
491 memset(sdkp->zones_wp_offset, 0, in sd_zbc_zone_wp_update()
492 sdkp->nr_zones * sizeof(unsigned int)); in sd_zbc_zone_wp_update()
499 spin_unlock_bh(&sdkp->zones_wp_offset_lock); in sd_zbc_zone_wp_update()
545 static int sd_zbc_check_zoned_characteristics(struct scsi_disk *sdkp, in sd_zbc_check_zoned_characteristics() argument
549 if (scsi_get_vpd_page(sdkp->device, 0xb6, buf, 64)) { in sd_zbc_check_zoned_characteristics()
550 sd_printk(KERN_NOTICE, sdkp, in sd_zbc_check_zoned_characteristics()
555 if (sdkp->device->type != TYPE_ZBC) { in sd_zbc_check_zoned_characteristics()
557 sdkp->urswrz = 1; in sd_zbc_check_zoned_characteristics()
558 sdkp->zones_optimal_open = get_unaligned_be32(&buf[8]); in sd_zbc_check_zoned_characteristics()
559 sdkp->zones_optimal_nonseq = get_unaligned_be32(&buf[12]); in sd_zbc_check_zoned_characteristics()
560 sdkp->zones_max_open = 0; in sd_zbc_check_zoned_characteristics()
563 sdkp->urswrz = buf[4] & 1; in sd_zbc_check_zoned_characteristics()
564 sdkp->zones_optimal_open = 0; in sd_zbc_check_zoned_characteristics()
565 sdkp->zones_optimal_nonseq = 0; in sd_zbc_check_zoned_characteristics()
566 sdkp->zones_max_open = get_unaligned_be32(&buf[16]); in sd_zbc_check_zoned_characteristics()
574 if (!sdkp->urswrz) { in sd_zbc_check_zoned_characteristics()
575 if (sdkp->first_scan) in sd_zbc_check_zoned_characteristics()
576 sd_printk(KERN_NOTICE, sdkp, in sd_zbc_check_zoned_characteristics()
596 static int sd_zbc_check_capacity(struct scsi_disk *sdkp, unsigned char *buf, in sd_zbc_check_capacity() argument
605 ret = sd_zbc_do_report_zones(sdkp, buf, SD_BUF_SIZE, 0, false); in sd_zbc_check_capacity()
609 if (sdkp->rc_basis == 0) { in sd_zbc_check_capacity()
612 if (sdkp->capacity != max_lba + 1) { in sd_zbc_check_capacity()
613 if (sdkp->first_scan) in sd_zbc_check_capacity()
614 sd_printk(KERN_WARNING, sdkp, in sd_zbc_check_capacity()
616 (unsigned long long)sdkp->capacity, in sd_zbc_check_capacity()
618 sdkp->capacity = max_lba + 1; in sd_zbc_check_capacity()
625 if (logical_to_sectors(sdkp->device, zone_blocks) > UINT_MAX) { in sd_zbc_check_capacity()
626 if (sdkp->first_scan) in sd_zbc_check_capacity()
627 sd_printk(KERN_NOTICE, sdkp, in sd_zbc_check_capacity()
637 static void sd_zbc_print_zones(struct scsi_disk *sdkp) in sd_zbc_print_zones() argument
639 if (!sd_is_zoned(sdkp) || !sdkp->capacity) in sd_zbc_print_zones()
642 if (sdkp->capacity & (sdkp->zone_blocks - 1)) in sd_zbc_print_zones()
643 sd_printk(KERN_NOTICE, sdkp, in sd_zbc_print_zones()
645 sdkp->nr_zones - 1, in sd_zbc_print_zones()
646 sdkp->zone_blocks); in sd_zbc_print_zones()
648 sd_printk(KERN_NOTICE, sdkp, in sd_zbc_print_zones()
650 sdkp->nr_zones, in sd_zbc_print_zones()
651 sdkp->zone_blocks); in sd_zbc_print_zones()
654 static int sd_zbc_init_disk(struct scsi_disk *sdkp) in sd_zbc_init_disk() argument
656 sdkp->zones_wp_offset = NULL; in sd_zbc_init_disk()
657 spin_lock_init(&sdkp->zones_wp_offset_lock); in sd_zbc_init_disk()
658 sdkp->rev_wp_offset = NULL; in sd_zbc_init_disk()
659 mutex_init(&sdkp->rev_mutex); in sd_zbc_init_disk()
660 INIT_WORK(&sdkp->zone_wp_offset_work, sd_zbc_update_wp_offset_workfn); in sd_zbc_init_disk()
661 sdkp->zone_wp_update_buf = kzalloc(SD_BUF_SIZE, GFP_KERNEL); in sd_zbc_init_disk()
662 if (!sdkp->zone_wp_update_buf) in sd_zbc_init_disk()
668 void sd_zbc_release_disk(struct scsi_disk *sdkp) in sd_zbc_release_disk() argument
670 kvfree(sdkp->zones_wp_offset); in sd_zbc_release_disk()
671 sdkp->zones_wp_offset = NULL; in sd_zbc_release_disk()
672 kfree(sdkp->zone_wp_update_buf); in sd_zbc_release_disk()
673 sdkp->zone_wp_update_buf = NULL; in sd_zbc_release_disk()
678 struct scsi_disk *sdkp = scsi_disk(disk); in sd_zbc_revalidate_zones_cb() local
680 swap(sdkp->zones_wp_offset, sdkp->rev_wp_offset); in sd_zbc_revalidate_zones_cb()
683 int sd_zbc_revalidate_zones(struct scsi_disk *sdkp) in sd_zbc_revalidate_zones() argument
685 struct gendisk *disk = sdkp->disk; in sd_zbc_revalidate_zones()
687 u32 zone_blocks = sdkp->rev_zone_blocks; in sd_zbc_revalidate_zones()
688 unsigned int nr_zones = sdkp->rev_nr_zones; in sd_zbc_revalidate_zones()
699 if (sd_is_zoned(sdkp) && !sdkp->zone_wp_update_buf) { in sd_zbc_revalidate_zones()
700 ret = sd_zbc_init_disk(sdkp); in sd_zbc_revalidate_zones()
716 mutex_lock(&sdkp->rev_mutex); in sd_zbc_revalidate_zones()
718 if (sdkp->zone_blocks == zone_blocks && in sd_zbc_revalidate_zones()
719 sdkp->nr_zones == nr_zones && in sd_zbc_revalidate_zones()
723 sdkp->zone_blocks = zone_blocks; in sd_zbc_revalidate_zones()
724 sdkp->nr_zones = nr_zones; in sd_zbc_revalidate_zones()
725 sdkp->rev_wp_offset = kvcalloc(nr_zones, sizeof(u32), GFP_NOIO); in sd_zbc_revalidate_zones()
726 if (!sdkp->rev_wp_offset) { in sd_zbc_revalidate_zones()
733 kvfree(sdkp->rev_wp_offset); in sd_zbc_revalidate_zones()
734 sdkp->rev_wp_offset = NULL; in sd_zbc_revalidate_zones()
737 sdkp->zone_blocks = 0; in sd_zbc_revalidate_zones()
738 sdkp->nr_zones = 0; in sd_zbc_revalidate_zones()
739 sdkp->capacity = 0; in sd_zbc_revalidate_zones()
743 max_append = min_t(u32, logical_to_sectors(sdkp->device, zone_blocks), in sd_zbc_revalidate_zones()
749 sd_zbc_print_zones(sdkp); in sd_zbc_revalidate_zones()
752 mutex_unlock(&sdkp->rev_mutex); in sd_zbc_revalidate_zones()
757 int sd_zbc_read_zones(struct scsi_disk *sdkp, unsigned char *buf) in sd_zbc_read_zones() argument
759 struct gendisk *disk = sdkp->disk; in sd_zbc_read_zones()
765 if (!sd_is_zoned(sdkp)) in sd_zbc_read_zones()
773 ret = sd_zbc_check_zoned_characteristics(sdkp, buf); in sd_zbc_read_zones()
778 ret = sd_zbc_check_capacity(sdkp, buf, &zone_blocks); in sd_zbc_read_zones()
785 if (sdkp->zones_max_open == U32_MAX) in sd_zbc_read_zones()
788 blk_queue_max_open_zones(q, sdkp->zones_max_open); in sd_zbc_read_zones()
790 nr_zones = round_up(sdkp->capacity, zone_blocks) >> ilog2(zone_blocks); in sd_zbc_read_zones()
793 sdkp->device->use_16_for_rw = 1; in sd_zbc_read_zones()
794 sdkp->device->use_10_for_rw = 0; in sd_zbc_read_zones()
796 sdkp->rev_nr_zones = nr_zones; in sd_zbc_read_zones()
797 sdkp->rev_zone_blocks = zone_blocks; in sd_zbc_read_zones()
802 sdkp->capacity = 0; in sd_zbc_read_zones()