Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Merge tag 'scsi-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi

Pull SCSI fixes from James Bottomley:
"Three fixes: one in drivers (lpfc) and two for zoned block devices.

The latter also impinges on the block layer but only to introduce a
new block API for setting the zone model rather than fiddling with the
queue directly in the zoned block driver"

* tag 'scsi-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi:
scsi: sd: sd_zbc: Fix ZBC disk initialization
scsi: sd: sd_zbc: Fix handling of host-aware ZBC disks
scsi: lpfc: Fix initial FLOGI failure due to BBSCN not supported

+159 -73
+46
block/blk-settings.c
··· 801 801 } 802 802 EXPORT_SYMBOL_GPL(blk_queue_can_use_dma_map_merging); 803 803 804 + /** 805 + * blk_queue_set_zoned - configure a disk queue zoned model. 806 + * @disk: the gendisk of the queue to configure 807 + * @model: the zoned model to set 808 + * 809 + * Set the zoned model of the request queue of @disk according to @model. 810 + * When @model is BLK_ZONED_HM (host managed), this should be called only 811 + * if zoned block device support is enabled (CONFIG_BLK_DEV_ZONED option). 812 + * If @model specifies BLK_ZONED_HA (host aware), the effective model used 813 + * depends on CONFIG_BLK_DEV_ZONED settings and on the existence of partitions 814 + * on the disk. 815 + */ 816 + void blk_queue_set_zoned(struct gendisk *disk, enum blk_zoned_model model) 817 + { 818 + switch (model) { 819 + case BLK_ZONED_HM: 820 + /* 821 + * Host managed devices are supported only if 822 + * CONFIG_BLK_DEV_ZONED is enabled. 823 + */ 824 + WARN_ON_ONCE(!IS_ENABLED(CONFIG_BLK_DEV_ZONED)); 825 + break; 826 + case BLK_ZONED_HA: 827 + /* 828 + * Host aware devices can be treated either as regular block 829 + * devices (similar to drive managed devices) or as zoned block 830 + * devices to take advantage of the zone command set, similarly 831 + * to host managed devices. We try the latter if there are no 832 + * partitions and zoned block device support is enabled, else 833 + * we do nothing special as far as the block layer is concerned. 834 + */ 835 + if (!IS_ENABLED(CONFIG_BLK_DEV_ZONED) || 836 + disk_has_partitions(disk)) 837 + model = BLK_ZONED_NONE; 838 + break; 839 + case BLK_ZONED_NONE: 840 + default: 841 + if (WARN_ON_ONCE(model != BLK_ZONED_NONE)) 842 + model = BLK_ZONED_NONE; 843 + break; 844 + } 845 + 846 + disk->queue->limits.zoned = model; 847 + } 848 + EXPORT_SYMBOL_GPL(blk_queue_set_zoned); 849 + 804 850 static int __init blk_settings_init(void) 805 851 { 806 852 blk_max_low_pfn = max_low_pfn - 1;
+52 -24
drivers/scsi/lpfc/lpfc_hbadisc.c
··· 71 71 static void lpfc_disc_flush_list(struct lpfc_vport *vport); 72 72 static void lpfc_unregister_fcfi_cmpl(struct lpfc_hba *, LPFC_MBOXQ_t *); 73 73 static int lpfc_fcf_inuse(struct lpfc_hba *); 74 + static void lpfc_mbx_cmpl_read_sparam(struct lpfc_hba *, LPFC_MBOXQ_t *); 74 75 75 76 void 76 77 lpfc_terminate_rport_io(struct fc_rport *rport) ··· 1139 1138 return; 1140 1139 } 1141 1140 1142 - 1143 1141 void 1144 1142 lpfc_mbx_cmpl_local_config_link(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb) 1145 1143 { 1146 1144 struct lpfc_vport *vport = pmb->vport; 1145 + LPFC_MBOXQ_t *sparam_mb; 1146 + struct lpfc_dmabuf *sparam_mp; 1147 + int rc; 1147 1148 1148 1149 if (pmb->u.mb.mbxStatus) 1149 1150 goto out; ··· 1170 1167 } 1171 1168 1172 1169 /* Start discovery by sending a FLOGI. port_state is identically 1173 - * LPFC_FLOGI while waiting for FLOGI cmpl. Check if sending 1174 - * the FLOGI is being deferred till after MBX_READ_SPARAM completes. 1170 + * LPFC_FLOGI while waiting for FLOGI cmpl. 1175 1171 */ 1176 1172 if (vport->port_state != LPFC_FLOGI) { 1177 - if (!(phba->hba_flag & HBA_DEFER_FLOGI)) 1173 + /* Issue MBX_READ_SPARAM to update CSPs before FLOGI if 1174 + * bb-credit recovery is in place. 1175 + */ 1176 + if (phba->bbcredit_support && phba->cfg_enable_bbcr && 1177 + !(phba->link_flag & LS_LOOPBACK_MODE)) { 1178 + sparam_mb = mempool_alloc(phba->mbox_mem_pool, 1179 + GFP_KERNEL); 1180 + if (!sparam_mb) 1181 + goto sparam_out; 1182 + 1183 + rc = lpfc_read_sparam(phba, sparam_mb, 0); 1184 + if (rc) { 1185 + mempool_free(sparam_mb, phba->mbox_mem_pool); 1186 + goto sparam_out; 1187 + } 1188 + sparam_mb->vport = vport; 1189 + sparam_mb->mbox_cmpl = lpfc_mbx_cmpl_read_sparam; 1190 + rc = lpfc_sli_issue_mbox(phba, sparam_mb, MBX_NOWAIT); 1191 + if (rc == MBX_NOT_FINISHED) { 1192 + sparam_mp = (struct lpfc_dmabuf *) 1193 + sparam_mb->ctx_buf; 1194 + lpfc_mbuf_free(phba, sparam_mp->virt, 1195 + sparam_mp->phys); 1196 + kfree(sparam_mp); 1197 + sparam_mb->ctx_buf = NULL; 1198 + mempool_free(sparam_mb, phba->mbox_mem_pool); 1199 + goto sparam_out; 1200 + } 1201 + 1202 + phba->hba_flag |= HBA_DEFER_FLOGI; 1203 + } else { 1178 1204 lpfc_initial_flogi(vport); 1205 + } 1179 1206 } else { 1180 1207 if (vport->fc_flag & FC_PT2PT) 1181 1208 lpfc_disc_start(vport); ··· 1217 1184 "0306 CONFIG_LINK mbxStatus error x%x " 1218 1185 "HBA state x%x\n", 1219 1186 pmb->u.mb.mbxStatus, vport->port_state); 1187 + sparam_out: 1220 1188 mempool_free(pmb, phba->mbox_mem_pool); 1221 1189 1222 1190 lpfc_linkdown(phba); ··· 3273 3239 lpfc_linkup(phba); 3274 3240 sparam_mbox = NULL; 3275 3241 3276 - if (!(phba->hba_flag & HBA_FCOE_MODE)) { 3277 - cfglink_mbox = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL); 3278 - if (!cfglink_mbox) 3279 - goto out; 3280 - vport->port_state = LPFC_LOCAL_CFG_LINK; 3281 - lpfc_config_link(phba, cfglink_mbox); 3282 - cfglink_mbox->vport = vport; 3283 - cfglink_mbox->mbox_cmpl = lpfc_mbx_cmpl_local_config_link; 3284 - rc = lpfc_sli_issue_mbox(phba, cfglink_mbox, MBX_NOWAIT); 3285 - if (rc == MBX_NOT_FINISHED) { 3286 - mempool_free(cfglink_mbox, phba->mbox_mem_pool); 3287 - goto out; 3288 - } 3289 - } 3290 - 3291 3242 sparam_mbox = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL); 3292 3243 if (!sparam_mbox) 3293 3244 goto out; ··· 3293 3274 goto out; 3294 3275 } 3295 3276 3296 - if (phba->hba_flag & HBA_FCOE_MODE) { 3277 + if (!(phba->hba_flag & HBA_FCOE_MODE)) { 3278 + cfglink_mbox = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL); 3279 + if (!cfglink_mbox) 3280 + goto out; 3281 + vport->port_state = LPFC_LOCAL_CFG_LINK; 3282 + lpfc_config_link(phba, cfglink_mbox); 3283 + cfglink_mbox->vport = vport; 3284 + cfglink_mbox->mbox_cmpl = lpfc_mbx_cmpl_local_config_link; 3285 + rc = lpfc_sli_issue_mbox(phba, cfglink_mbox, MBX_NOWAIT); 3286 + if (rc == MBX_NOT_FINISHED) { 3287 + mempool_free(cfglink_mbox, phba->mbox_mem_pool); 3288 + goto out; 3289 + } 3290 + } else { 3297 3291 vport->port_state = LPFC_VPORT_UNKNOWN; 3298 3292 /* 3299 3293 * Add the driver's default FCF record at FCF index 0 now. This ··· 3363 3331 } 3364 3332 /* Reset FCF roundrobin bmask for new discovery */ 3365 3333 lpfc_sli4_clear_fcf_rr_bmask(phba); 3366 - } else { 3367 - if (phba->bbcredit_support && phba->cfg_enable_bbcr && 3368 - !(phba->link_flag & LS_LOOPBACK_MODE)) 3369 - phba->hba_flag |= HBA_DEFER_FLOGI; 3370 3334 } 3371 3335 3372 3336 /* Prepare for LINK up registrations */
+18 -16
drivers/scsi/sd.c
··· 2964 2964 2965 2965 if (sdkp->device->type == TYPE_ZBC) { 2966 2966 /* Host-managed */ 2967 - q->limits.zoned = BLK_ZONED_HM; 2967 + blk_queue_set_zoned(sdkp->disk, BLK_ZONED_HM); 2968 2968 } else { 2969 2969 sdkp->zoned = (buffer[8] >> 4) & 3; 2970 - if (sdkp->zoned == 1 && !disk_has_partitions(sdkp->disk)) { 2970 + if (sdkp->zoned == 1) { 2971 2971 /* Host-aware */ 2972 - q->limits.zoned = BLK_ZONED_HA; 2972 + blk_queue_set_zoned(sdkp->disk, BLK_ZONED_HA); 2973 2973 } else { 2974 - /* 2975 - * Treat drive-managed devices and host-aware devices 2976 - * with partitions as regular block devices. 2977 - */ 2978 - q->limits.zoned = BLK_ZONED_NONE; 2979 - if (sdkp->zoned == 2 && sdkp->first_scan) 2980 - sd_printk(KERN_NOTICE, sdkp, 2981 - "Drive-managed SMR disk\n"); 2974 + /* Regular disk or drive managed disk */ 2975 + blk_queue_set_zoned(sdkp->disk, BLK_ZONED_NONE); 2982 2976 } 2983 2977 } 2984 - if (blk_queue_is_zoned(q) && sdkp->first_scan) 2978 + 2979 + if (!sdkp->first_scan) 2980 + goto out; 2981 + 2982 + if (blk_queue_is_zoned(q)) { 2985 2983 sd_printk(KERN_NOTICE, sdkp, "Host-%s zoned block device\n", 2986 2984 q->limits.zoned == BLK_ZONED_HM ? "managed" : "aware"); 2985 + } else { 2986 + if (sdkp->zoned == 1) 2987 + sd_printk(KERN_NOTICE, sdkp, 2988 + "Host-aware SMR disk used as regular disk\n"); 2989 + else if (sdkp->zoned == 2) 2990 + sd_printk(KERN_NOTICE, sdkp, 2991 + "Drive-managed SMR disk\n"); 2992 + } 2987 2993 2988 2994 out: 2989 2995 kfree(buffer); ··· 3409 3403 sdkp->ATO = 0; 3410 3404 sdkp->first_scan = 1; 3411 3405 sdkp->max_medium_access_timeouts = SD_MAX_MEDIUM_TIMEOUTS; 3412 - 3413 - error = sd_zbc_init_disk(sdkp); 3414 - if (error) 3415 - goto out_free_index; 3416 3406 3417 3407 sd_revalidate_disk(gd); 3418 3408
+1 -7
drivers/scsi/sd.h
··· 215 215 216 216 #ifdef CONFIG_BLK_DEV_ZONED 217 217 218 - int sd_zbc_init_disk(struct scsi_disk *sdkp); 219 218 void sd_zbc_release_disk(struct scsi_disk *sdkp); 220 219 int sd_zbc_read_zones(struct scsi_disk *sdkp, unsigned char *buffer); 221 220 int sd_zbc_revalidate_zones(struct scsi_disk *sdkp); ··· 229 230 unsigned int nr_blocks); 230 231 231 232 #else /* CONFIG_BLK_DEV_ZONED */ 232 - 233 - static inline int sd_zbc_init_disk(struct scsi_disk *sdkp) 234 - { 235 - return 0; 236 - } 237 233 238 234 static inline void sd_zbc_release_disk(struct scsi_disk *sdkp) {} 239 235 ··· 253 259 static inline unsigned int sd_zbc_complete(struct scsi_cmnd *cmd, 254 260 unsigned int good_bytes, struct scsi_sense_hdr *sshdr) 255 261 { 256 - return 0; 262 + return good_bytes; 257 263 } 258 264 259 265 static inline blk_status_t sd_zbc_prepare_zone_append(struct scsi_cmnd *cmd,
+40 -26
drivers/scsi/sd_zbc.c
··· 651 651 sdkp->zone_blocks); 652 652 } 653 653 654 + static int sd_zbc_init_disk(struct scsi_disk *sdkp) 655 + { 656 + sdkp->zones_wp_offset = NULL; 657 + spin_lock_init(&sdkp->zones_wp_offset_lock); 658 + sdkp->rev_wp_offset = NULL; 659 + mutex_init(&sdkp->rev_mutex); 660 + INIT_WORK(&sdkp->zone_wp_offset_work, sd_zbc_update_wp_offset_workfn); 661 + sdkp->zone_wp_update_buf = kzalloc(SD_BUF_SIZE, GFP_KERNEL); 662 + if (!sdkp->zone_wp_update_buf) 663 + return -ENOMEM; 664 + 665 + return 0; 666 + } 667 + 668 + void sd_zbc_release_disk(struct scsi_disk *sdkp) 669 + { 670 + kvfree(sdkp->zones_wp_offset); 671 + sdkp->zones_wp_offset = NULL; 672 + kfree(sdkp->zone_wp_update_buf); 673 + sdkp->zone_wp_update_buf = NULL; 674 + } 675 + 654 676 static void sd_zbc_revalidate_zones_cb(struct gendisk *disk) 655 677 { 656 678 struct scsi_disk *sdkp = scsi_disk(disk); ··· 689 667 u32 max_append; 690 668 int ret = 0; 691 669 692 - if (!sd_is_zoned(sdkp)) 670 + /* 671 + * For all zoned disks, initialize zone append emulation data if not 672 + * already done. This is necessary also for host-aware disks used as 673 + * regular disks due to the presence of partitions as these partitions 674 + * may be deleted and the disk zoned model changed back from 675 + * BLK_ZONED_NONE to BLK_ZONED_HA. 676 + */ 677 + if (sd_is_zoned(sdkp) && !sdkp->zone_wp_update_buf) { 678 + ret = sd_zbc_init_disk(sdkp); 679 + if (ret) 680 + return ret; 681 + } 682 + 683 + /* 684 + * There is nothing to do for regular disks, including host-aware disks 685 + * that have partitions. 686 + */ 687 + if (!blk_queue_is_zoned(q)) 693 688 return 0; 694 689 695 690 /* ··· 802 763 sdkp->capacity = 0; 803 764 804 765 return ret; 805 - } 806 - 807 - int sd_zbc_init_disk(struct scsi_disk *sdkp) 808 - { 809 - if (!sd_is_zoned(sdkp)) 810 - return 0; 811 - 812 - sdkp->zones_wp_offset = NULL; 813 - spin_lock_init(&sdkp->zones_wp_offset_lock); 814 - sdkp->rev_wp_offset = NULL; 815 - mutex_init(&sdkp->rev_mutex); 816 - INIT_WORK(&sdkp->zone_wp_offset_work, sd_zbc_update_wp_offset_workfn); 817 - sdkp->zone_wp_update_buf = kzalloc(SD_BUF_SIZE, GFP_KERNEL); 818 - if (!sdkp->zone_wp_update_buf) 819 - return -ENOMEM; 820 - 821 - return 0; 822 - } 823 - 824 - void sd_zbc_release_disk(struct scsi_disk *sdkp) 825 - { 826 - kvfree(sdkp->zones_wp_offset); 827 - sdkp->zones_wp_offset = NULL; 828 - kfree(sdkp->zone_wp_update_buf); 829 - sdkp->zone_wp_update_buf = NULL; 830 766 }
+2
include/linux/blkdev.h
··· 352 352 typedef int (*report_zones_cb)(struct blk_zone *zone, unsigned int idx, 353 353 void *data); 354 354 355 + void blk_queue_set_zoned(struct gendisk *disk, enum blk_zoned_model model); 356 + 355 357 #ifdef CONFIG_BLK_DEV_ZONED 356 358 357 359 #define BLK_ALL_ZONES ((unsigned int)-1)