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 git://git.kernel.org/pub/scm/linux/kernel/git/nab/target-pending

Pull SCSI target fixes from Nicholas Bellinger:
"The bulk of the changes are in qla2xxx target driver code to address
various issues found during Cavium/QLogic's internal testing (stable
CC's included), along with a few other stability and smaller
miscellaneous improvements.

There are also a couple of different patch sets from Mike Christie,
which have been a result of his work to use target-core ALUA logic
together with tcm-user backend driver.

Finally, a patch to address some long standing issues with
pass-through SCSI export of TYPE_TAPE + TYPE_MEDIUM_CHANGER devices,
which will make folks using physical (or virtual) magnetic tape happy"

* git://git.kernel.org/pub/scm/linux/kernel/git/nab/target-pending: (28 commits)
qla2xxx: Update driver version to 9.00.00.00-k
qla2xxx: Fix delayed response to command for loop mode/direct connect.
qla2xxx: Change scsi host lookup method.
qla2xxx: Add DebugFS node to display Port Database
qla2xxx: Use IOCB interface to submit non-critical MBX.
qla2xxx: Add async new target notification
qla2xxx: Export DIF stats via debugfs
qla2xxx: Improve T10-DIF/PI handling in driver.
qla2xxx: Allow relogin to proceed if remote login did not finish
qla2xxx: Fix sess_lock & hardware_lock lock order problem.
qla2xxx: Fix inadequate lock protection for ABTS.
qla2xxx: Fix request queue corruption.
qla2xxx: Fix memory leak for abts processing
qla2xxx: Allow vref count to timeout on vport delete.
tcmu: Convert cmd_time_out into backend device attribute
tcmu: make cmd timeout configurable
tcmu: add helper to check if dev was configured
target: fix race during implicit transition work flushes
target: allow userspace to set state to transitioning
target: fix ALUA transition timeout handling
...

+1276 -550
+1
drivers/scsi/qla2xxx/Kconfig
··· 3 3 depends on PCI && SCSI 4 4 depends on SCSI_FC_ATTRS 5 5 select FW_LOADER 6 + select BTREE 6 7 ---help--- 7 8 This qla2xxx driver supports all QLogic Fibre Channel 8 9 PCI and PCIe host adapters.
+1 -3
drivers/scsi/qla2xxx/qla_attr.c
··· 2154 2154 "Timer for the VP[%d] has stopped\n", vha->vp_idx); 2155 2155 } 2156 2156 2157 - BUG_ON(atomic_read(&vha->vref_count)); 2158 - 2159 2157 qla2x00_free_fcports(vha); 2160 2158 2161 2159 mutex_lock(&ha->vport_lock); ··· 2164 2166 dma_free_coherent(&ha->pdev->dev, vha->gnl.size, vha->gnl.l, 2165 2167 vha->gnl.ldma); 2166 2168 2167 - if (vha->qpair->vp_idx == vha->vp_idx) { 2169 + if (vha->qpair && vha->qpair->vp_idx == vha->vp_idx) { 2168 2170 if (qla2xxx_delete_qpair(vha, vha->qpair) != QLA_SUCCESS) 2169 2171 ql_log(ql_log_warn, vha, 0x7087, 2170 2172 "Queue Pair delete failed.\n");
+1
drivers/scsi/qla2xxx/qla_dbg.h
··· 348 348 #define ql_dbg_tgt 0x00004000 /* Target mode */ 349 349 #define ql_dbg_tgt_mgt 0x00002000 /* Target mode management */ 350 350 #define ql_dbg_tgt_tmr 0x00001000 /* Target mode task management */ 351 + #define ql_dbg_tgt_dif 0x00000800 /* Target mode dif */ 351 352 352 353 extern int qla27xx_dump_mpi_ram(struct qla_hw_data *, uint32_t, uint32_t *, 353 354 uint32_t, void **);
+50 -6
drivers/scsi/qla2xxx/qla_def.h
··· 25 25 #include <linux/firmware.h> 26 26 #include <linux/aer.h> 27 27 #include <linux/mutex.h> 28 + #include <linux/btree.h> 28 29 29 30 #include <scsi/scsi.h> 30 31 #include <scsi/scsi_host.h> ··· 396 395 struct completion comp; 397 396 } abt; 398 397 struct ct_arg ctarg; 398 + #define MAX_IOCB_MB_REG 28 399 + #define SIZEOF_IOCB_MB_REG (MAX_IOCB_MB_REG * sizeof(uint16_t)) 399 400 struct { 400 - __le16 in_mb[28]; /* fr fw */ 401 - __le16 out_mb[28]; /* to fw */ 401 + __le16 in_mb[MAX_IOCB_MB_REG]; /* from FW */ 402 + __le16 out_mb[MAX_IOCB_MB_REG]; /* to FW */ 402 403 void *out, *in; 403 404 dma_addr_t out_dma, in_dma; 405 + struct completion comp; 406 + int rc; 404 407 } mbx; 405 408 struct { 406 409 struct imm_ntfy_from_isp *ntfy; ··· 442 437 uint32_t handle; 443 438 uint16_t flags; 444 439 uint16_t type; 445 - char *name; 440 + const char *name; 446 441 int iocbs; 447 442 struct qla_qpair *qpair; 448 443 u32 gen1; /* scratch */ ··· 2305 2300 struct ct_sns_desc ct_desc; 2306 2301 enum discovery_state disc_state; 2307 2302 enum login_state fw_login_state; 2303 + unsigned long plogi_nack_done_deadline; 2304 + 2308 2305 u32 login_gen, last_login_gen; 2309 2306 u32 rscn_gen, last_rscn_gen; 2310 2307 u32 chip_reset; ··· 3113 3106 uint32_t gold_fw_version; 3114 3107 }; 3115 3108 3109 + struct qla_dif_statistics { 3110 + uint64_t dif_input_bytes; 3111 + uint64_t dif_output_bytes; 3112 + uint64_t dif_input_requests; 3113 + uint64_t dif_output_requests; 3114 + uint32_t dif_guard_err; 3115 + uint32_t dif_ref_tag_err; 3116 + uint32_t dif_app_tag_err; 3117 + }; 3118 + 3116 3119 struct qla_statistics { 3117 3120 uint32_t total_isp_aborts; 3118 3121 uint64_t input_bytes; ··· 3135 3118 uint32_t stat_max_pend_cmds; 3136 3119 uint32_t stat_max_qfull_cmds_alloc; 3137 3120 uint32_t stat_max_qfull_cmds_dropped; 3121 + 3122 + struct qla_dif_statistics qla_dif_stats; 3138 3123 }; 3139 3124 3140 3125 struct bidi_statistics { 3141 3126 unsigned long long io_count; 3142 3127 unsigned long long transfer_bytes; 3128 + }; 3129 + 3130 + struct qla_tc_param { 3131 + struct scsi_qla_host *vha; 3132 + uint32_t blk_sz; 3133 + uint32_t bufflen; 3134 + struct scatterlist *sg; 3135 + struct scatterlist *prot_sg; 3136 + struct crc_context *ctx; 3137 + uint8_t *ctx_dsd_alloced; 3143 3138 }; 3144 3139 3145 3140 /* Multi queue support */ ··· 3301 3272 uint8_t tgt_node_name[WWN_SIZE]; 3302 3273 3303 3274 struct dentry *dfs_tgt_sess; 3275 + struct dentry *dfs_tgt_port_database; 3276 + 3304 3277 struct list_head q_full_list; 3305 3278 uint32_t num_pend_cmds; 3306 3279 uint32_t num_qfull_cmds_alloc; ··· 3312 3281 spinlock_t sess_lock; 3313 3282 int rspq_vector_cpuid; 3314 3283 spinlock_t atio_lock ____cacheline_aligned; 3284 + struct btree_head32 host_map; 3315 3285 }; 3316 3286 3317 3287 #define MAX_QFULL_CMDS_ALLOC 8192 ··· 3321 3289 ((ha->cur_fw_xcb_count/100) * Q_FULL_THRESH_HOLD_PERCENT) 3322 3290 3323 3291 #define LEAK_EXCHG_THRESH_HOLD_PERCENT 75 /* 75 percent */ 3292 + 3293 + #define QLA_EARLY_LINKUP(_ha) \ 3294 + ((_ha->flags.n2n_ae || _ha->flags.lip_ae) && \ 3295 + _ha->flags.fw_started && !_ha->flags.fw_init_done) 3324 3296 3325 3297 /* 3326 3298 * Qlogic host adapter specific data structure. ··· 3375 3339 uint32_t fawwpn_enabled:1; 3376 3340 uint32_t exlogins_enabled:1; 3377 3341 uint32_t exchoffld_enabled:1; 3378 - /* 35 bits */ 3342 + 3343 + uint32_t lip_ae:1; 3344 + uint32_t n2n_ae:1; 3345 + uint32_t fw_started:1; 3346 + uint32_t fw_init_done:1; 3379 3347 } flags; 3380 3348 3381 3349 /* This spinlock is used to protect "io transactions", you must ··· 3472 3432 #define P2P_LOOP 3 3473 3433 uint8_t interrupts_on; 3474 3434 uint32_t isp_abort_cnt; 3475 - 3476 3435 #define PCI_DEVICE_ID_QLOGIC_ISP2532 0x2532 3477 3436 #define PCI_DEVICE_ID_QLOGIC_ISP8432 0x8432 3478 3437 #define PCI_DEVICE_ID_QLOGIC_ISP8001 0x8001 ··· 3952 3913 struct list_head vp_fcports; /* list of fcports */ 3953 3914 struct list_head work_list; 3954 3915 spinlock_t work_lock; 3916 + struct work_struct iocb_work; 3955 3917 3956 3918 /* Commonly used flags and state information. */ 3957 3919 struct Scsi_Host *host; ··· 4116 4076 /* Count of active session/fcport */ 4117 4077 int fcport_count; 4118 4078 wait_queue_head_t fcport_waitQ; 4079 + wait_queue_head_t vref_waitq; 4119 4080 } scsi_qla_host_t; 4120 4081 4121 4082 struct qla27xx_image_status { ··· 4172 4131 mb(); \ 4173 4132 if (__vha->flags.delete_progress) { \ 4174 4133 atomic_dec(&__vha->vref_count); \ 4134 + wake_up(&__vha->vref_waitq); \ 4175 4135 __bail = 1; \ 4176 4136 } else { \ 4177 4137 __bail = 0; \ 4178 4138 } \ 4179 4139 } while (0) 4180 4140 4181 - #define QLA_VHA_MARK_NOT_BUSY(__vha) \ 4141 + #define QLA_VHA_MARK_NOT_BUSY(__vha) do { \ 4182 4142 atomic_dec(&__vha->vref_count); \ 4143 + wake_up(&__vha->vref_waitq); \ 4144 + } while (0) \ 4183 4145 4184 4146 #define QLA_QPAIR_MARK_BUSY(__qpair, __bail) do { \ 4185 4147 atomic_inc(&__qpair->ref_count); \
+103 -4
drivers/scsi/qla2xxx/qla_dfs.c
··· 19 19 struct qla_hw_data *ha = vha->hw; 20 20 unsigned long flags; 21 21 struct fc_port *sess = NULL; 22 - struct qla_tgt *tgt= vha->vha_tgt.qla_tgt; 22 + struct qla_tgt *tgt = vha->vha_tgt.qla_tgt; 23 23 24 - seq_printf(s, "%s\n",vha->host_str); 24 + seq_printf(s, "%s\n", vha->host_str); 25 25 if (tgt) { 26 - seq_printf(s, "Port ID Port Name Handle\n"); 26 + seq_puts(s, "Port ID Port Name Handle\n"); 27 27 28 28 spin_lock_irqsave(&ha->tgt.sess_lock, flags); 29 29 list_for_each_entry(sess, &vha->vp_fcports, list) ··· 44 44 return single_open(file, qla2x00_dfs_tgt_sess_show, vha); 45 45 } 46 46 47 - 48 47 static const struct file_operations dfs_tgt_sess_ops = { 49 48 .open = qla2x00_dfs_tgt_sess_open, 49 + .read = seq_read, 50 + .llseek = seq_lseek, 51 + .release = single_release, 52 + }; 53 + 54 + static int 55 + qla2x00_dfs_tgt_port_database_show(struct seq_file *s, void *unused) 56 + { 57 + scsi_qla_host_t *vha = s->private; 58 + struct qla_hw_data *ha = vha->hw; 59 + struct gid_list_info *gid_list; 60 + dma_addr_t gid_list_dma; 61 + fc_port_t fc_port; 62 + char *id_iter; 63 + int rc, i; 64 + uint16_t entries, loop_id; 65 + struct qla_tgt *tgt = vha->vha_tgt.qla_tgt; 66 + 67 + seq_printf(s, "%s\n", vha->host_str); 68 + if (tgt) { 69 + gid_list = dma_alloc_coherent(&ha->pdev->dev, 70 + qla2x00_gid_list_size(ha), 71 + &gid_list_dma, GFP_KERNEL); 72 + if (!gid_list) { 73 + ql_dbg(ql_dbg_user, vha, 0x705c, 74 + "DMA allocation failed for %u\n", 75 + qla2x00_gid_list_size(ha)); 76 + return 0; 77 + } 78 + 79 + rc = qla24xx_gidlist_wait(vha, gid_list, gid_list_dma, 80 + &entries); 81 + if (rc != QLA_SUCCESS) 82 + goto out_free_id_list; 83 + 84 + id_iter = (char *)gid_list; 85 + 86 + seq_puts(s, "Port Name Port ID Loop ID\n"); 87 + 88 + for (i = 0; i < entries; i++) { 89 + struct gid_list_info *gid = 90 + (struct gid_list_info *)id_iter; 91 + loop_id = le16_to_cpu(gid->loop_id); 92 + memset(&fc_port, 0, sizeof(fc_port_t)); 93 + 94 + fc_port.loop_id = loop_id; 95 + 96 + rc = qla24xx_gpdb_wait(vha, &fc_port, 0); 97 + seq_printf(s, "%8phC %02x%02x%02x %d\n", 98 + fc_port.port_name, fc_port.d_id.b.domain, 99 + fc_port.d_id.b.area, fc_port.d_id.b.al_pa, 100 + fc_port.loop_id); 101 + id_iter += ha->gid_list_info_size; 102 + } 103 + out_free_id_list: 104 + dma_free_coherent(&ha->pdev->dev, qla2x00_gid_list_size(ha), 105 + gid_list, gid_list_dma); 106 + } 107 + 108 + return 0; 109 + } 110 + 111 + static int 112 + qla2x00_dfs_tgt_port_database_open(struct inode *inode, struct file *file) 113 + { 114 + scsi_qla_host_t *vha = inode->i_private; 115 + 116 + return single_open(file, qla2x00_dfs_tgt_port_database_show, vha); 117 + } 118 + 119 + static const struct file_operations dfs_tgt_port_database_ops = { 120 + .open = qla2x00_dfs_tgt_port_database_open, 50 121 .read = seq_read, 51 122 .llseek = seq_lseek, 52 123 .release = single_release, ··· 185 114 seq_printf(s, "num Q full sent = %lld\n", 186 115 vha->tgt_counters.num_q_full_sent); 187 116 117 + /* DIF stats */ 118 + seq_printf(s, "DIF Inp Bytes = %lld\n", 119 + vha->qla_stats.qla_dif_stats.dif_input_bytes); 120 + seq_printf(s, "DIF Outp Bytes = %lld\n", 121 + vha->qla_stats.qla_dif_stats.dif_output_bytes); 122 + seq_printf(s, "DIF Inp Req = %lld\n", 123 + vha->qla_stats.qla_dif_stats.dif_input_requests); 124 + seq_printf(s, "DIF Outp Req = %lld\n", 125 + vha->qla_stats.qla_dif_stats.dif_output_requests); 126 + seq_printf(s, "DIF Guard err = %d\n", 127 + vha->qla_stats.qla_dif_stats.dif_guard_err); 128 + seq_printf(s, "DIF Ref tag err = %d\n", 129 + vha->qla_stats.qla_dif_stats.dif_ref_tag_err); 130 + seq_printf(s, "DIF App tag err = %d\n", 131 + vha->qla_stats.qla_dif_stats.dif_app_tag_err); 188 132 return 0; 189 133 } 190 134 ··· 367 281 goto out; 368 282 } 369 283 284 + ha->tgt.dfs_tgt_port_database = debugfs_create_file("tgt_port_database", 285 + S_IRUSR, ha->dfs_dir, vha, &dfs_tgt_port_database_ops); 286 + if (!ha->tgt.dfs_tgt_port_database) { 287 + ql_log(ql_log_warn, vha, 0xffff, 288 + "Unable to create debugFS tgt_port_database node.\n"); 289 + goto out; 290 + } 291 + 370 292 ha->dfs_fce = debugfs_create_file("fce", S_IRUSR, ha->dfs_dir, vha, 371 293 &dfs_fce_ops); 372 294 if (!ha->dfs_fce) { ··· 403 309 if (ha->tgt.dfs_tgt_sess) { 404 310 debugfs_remove(ha->tgt.dfs_tgt_sess); 405 311 ha->tgt.dfs_tgt_sess = NULL; 312 + } 313 + 314 + if (ha->tgt.dfs_tgt_port_database) { 315 + debugfs_remove(ha->tgt.dfs_tgt_port_database); 316 + ha->tgt.dfs_tgt_port_database = NULL; 406 317 } 407 318 408 319 if (ha->dfs_fw_resource_cnt) {
+14 -4
drivers/scsi/qla2xxx/qla_gbl.h
··· 193 193 void qla2x00_handle_login_done_event(struct scsi_qla_host *, fc_port_t *, 194 194 uint16_t *); 195 195 int qla24xx_post_gnl_work(struct scsi_qla_host *, fc_port_t *); 196 + int qla24xx_async_abort_cmd(srb_t *); 196 197 197 198 /* 198 199 * Global Functions in qla_mid.c source file. ··· 257 256 extern void *qla2x00_alloc_iocbs(scsi_qla_host_t *, srb_t *); 258 257 extern int qla2x00_issue_marker(scsi_qla_host_t *, int); 259 258 extern int qla24xx_walk_and_build_sglist_no_difb(struct qla_hw_data *, srb_t *, 260 - uint32_t *, uint16_t, struct qla_tgt_cmd *); 259 + uint32_t *, uint16_t, struct qla_tc_param *); 261 260 extern int qla24xx_walk_and_build_sglist(struct qla_hw_data *, srb_t *, 262 - uint32_t *, uint16_t, struct qla_tgt_cmd *); 261 + uint32_t *, uint16_t, struct qla_tc_param *); 263 262 extern int qla24xx_walk_and_build_prot_sglist(struct qla_hw_data *, srb_t *, 264 - uint32_t *, uint16_t, struct qla_tgt_cmd *); 263 + uint32_t *, uint16_t, struct qla_tc_param *); 265 264 extern int qla24xx_get_one_block_sg(uint32_t, struct qla2_sgx *, uint32_t *); 266 265 extern int qla24xx_configure_prot_mode(srb_t *, uint16_t *); 267 266 extern int qla24xx_build_scsi_crc_2_iocbs(srb_t *, ··· 369 368 370 369 extern int 371 370 qla24xx_get_isp_stats(scsi_qla_host_t *, struct link_statistics *, 372 - dma_addr_t, uint); 371 + dma_addr_t, uint16_t); 373 372 374 373 extern int qla24xx_abort_command(srb_t *); 375 374 extern int qla24xx_async_abort_command(srb_t *); ··· 472 471 473 472 extern int 474 473 qla26xx_dport_diagnostics(scsi_qla_host_t *, void *, uint, uint); 474 + 475 + int qla24xx_send_mb_cmd(struct scsi_qla_host *, mbx_cmd_t *); 476 + int qla24xx_gpdb_wait(struct scsi_qla_host *, fc_port_t *, u8); 477 + int qla24xx_gidlist_wait(struct scsi_qla_host *, void *, dma_addr_t, 478 + uint16_t *); 479 + int __qla24xx_parse_gpdb(struct scsi_qla_host *, fc_port_t *, 480 + struct port_database_24xx *); 475 481 476 482 /* 477 483 * Global Function Prototypes in qla_isr.c source file. ··· 854 846 uint64_t wwn, port_id_t port_id, uint16_t loop_id, struct fc_port **); 855 847 void qla24xx_delete_sess_fn(struct work_struct *); 856 848 void qlt_unknown_atio_work_fn(struct work_struct *); 849 + void qlt_update_host_map(struct scsi_qla_host *, port_id_t); 850 + void qlt_remove_target_resources(struct qla_hw_data *); 857 851 858 852 #endif /* _QLA_GBL_H */
+31 -54
drivers/scsi/qla2xxx/qla_init.c
··· 629 629 struct srb *sp = s; 630 630 struct scsi_qla_host *vha = sp->vha; 631 631 struct qla_hw_data *ha = vha->hw; 632 - uint64_t zero = 0; 633 632 struct port_database_24xx *pd; 634 633 fc_port_t *fcport = sp->fcport; 635 634 u16 *mb = sp->u.iocb_cmd.u.mbx.in_mb; ··· 648 649 649 650 pd = (struct port_database_24xx *)sp->u.iocb_cmd.u.mbx.in; 650 651 651 - /* Check for logged in state. */ 652 - if (pd->current_login_state != PDS_PRLI_COMPLETE && 653 - pd->last_login_state != PDS_PRLI_COMPLETE) { 654 - ql_dbg(ql_dbg_mbx, vha, 0xffff, 655 - "Unable to verify login-state (%x/%x) for " 656 - "loop_id %x.\n", pd->current_login_state, 657 - pd->last_login_state, fcport->loop_id); 658 - rval = QLA_FUNCTION_FAILED; 659 - goto gpd_error_out; 660 - } 661 - 662 - if (fcport->loop_id == FC_NO_LOOP_ID || 663 - (memcmp(fcport->port_name, (uint8_t *)&zero, 8) && 664 - memcmp(fcport->port_name, pd->port_name, 8))) { 665 - /* We lost the device mid way. */ 666 - rval = QLA_NOT_LOGGED_IN; 667 - goto gpd_error_out; 668 - } 669 - 670 - /* Names are little-endian. */ 671 - memcpy(fcport->node_name, pd->node_name, WWN_SIZE); 672 - 673 - /* Get port_id of device. */ 674 - fcport->d_id.b.domain = pd->port_id[0]; 675 - fcport->d_id.b.area = pd->port_id[1]; 676 - fcport->d_id.b.al_pa = pd->port_id[2]; 677 - fcport->d_id.b.rsvd_1 = 0; 678 - 679 - /* If not target must be initiator or unknown type. */ 680 - if ((pd->prli_svc_param_word_3[0] & BIT_4) == 0) 681 - fcport->port_type = FCT_INITIATOR; 682 - else 683 - fcport->port_type = FCT_TARGET; 684 - 685 - /* Passback COS information. */ 686 - fcport->supported_classes = (pd->flags & PDF_CLASS_2) ? 687 - FC_COS_CLASS2 : FC_COS_CLASS3; 688 - 689 - if (pd->prli_svc_param_word_3[0] & BIT_7) { 690 - fcport->flags |= FCF_CONF_COMP_SUPPORTED; 691 - fcport->conf_compl_supported = 1; 692 - } 652 + rval = __qla24xx_parse_gpdb(vha, fcport, pd); 693 653 694 654 gpd_error_out: 695 655 memset(&ea, 0, sizeof(ea)); ··· 834 876 fcport->login_retry--; 835 877 836 878 if ((fcport->fw_login_state == DSC_LS_PLOGI_PEND) || 837 - (fcport->fw_login_state == DSC_LS_PLOGI_COMP) || 838 879 (fcport->fw_login_state == DSC_LS_PRLI_PEND)) 839 880 return 0; 881 + 882 + if (fcport->fw_login_state == DSC_LS_PLOGI_COMP) { 883 + if (time_before_eq(jiffies, fcport->plogi_nack_done_deadline)) 884 + return 0; 885 + } 840 886 841 887 /* for pure Target Mode. Login will not be initiated */ 842 888 if (vha->host->active_mode == MODE_TARGET) ··· 1003 1041 fcport->flags); 1004 1042 1005 1043 if ((fcport->fw_login_state == DSC_LS_PLOGI_PEND) || 1006 - (fcport->fw_login_state == DSC_LS_PLOGI_COMP) || 1007 1044 (fcport->fw_login_state == DSC_LS_PRLI_PEND)) 1008 1045 return; 1046 + 1047 + if (fcport->fw_login_state == DSC_LS_PLOGI_COMP) { 1048 + if (time_before_eq(jiffies, fcport->plogi_nack_done_deadline)) 1049 + return; 1050 + } 1009 1051 1010 1052 if (fcport->flags & FCF_ASYNC_SENT) { 1011 1053 fcport->login_retry++; ··· 1224 1258 complete(&abt->u.abt.comp); 1225 1259 } 1226 1260 1227 - static int 1261 + int 1228 1262 qla24xx_async_abort_cmd(srb_t *cmd_sp) 1229 1263 { 1230 1264 scsi_qla_host_t *vha = cmd_sp->vha; ··· 3178 3212 } else { 3179 3213 ql_dbg(ql_dbg_init, vha, 0x00d3, 3180 3214 "Init Firmware -- success.\n"); 3215 + ha->flags.fw_started = 1; 3181 3216 } 3182 3217 3183 3218 return (rval); ··· 3341 3374 uint8_t domain; 3342 3375 char connect_type[22]; 3343 3376 struct qla_hw_data *ha = vha->hw; 3344 - unsigned long flags; 3345 3377 scsi_qla_host_t *base_vha = pci_get_drvdata(ha->pdev); 3378 + port_id_t id; 3346 3379 3347 3380 /* Get host addresses. */ 3348 3381 rval = qla2x00_get_adapter_id(vha, ··· 3420 3453 3421 3454 /* Save Host port and loop ID. */ 3422 3455 /* byte order - Big Endian */ 3423 - vha->d_id.b.domain = domain; 3424 - vha->d_id.b.area = area; 3425 - vha->d_id.b.al_pa = al_pa; 3426 - 3427 - spin_lock_irqsave(&ha->vport_slock, flags); 3428 - qlt_update_vp_map(vha, SET_AL_PA); 3429 - spin_unlock_irqrestore(&ha->vport_slock, flags); 3456 + id.b.domain = domain; 3457 + id.b.area = area; 3458 + id.b.al_pa = al_pa; 3459 + id.b.rsvd_1 = 0; 3460 + qlt_update_host_map(vha, id); 3430 3461 3431 3462 if (!vha->flags.init_done) 3432 3463 ql_log(ql_log_info, vha, 0x2010, ··· 4001 4036 atomic_set(&vha->loop_state, LOOP_READY); 4002 4037 ql_dbg(ql_dbg_disc, vha, 0x2069, 4003 4038 "LOOP READY.\n"); 4039 + ha->flags.fw_init_done = 1; 4004 4040 4005 4041 /* 4006 4042 * Process any ATIO queue entries that came in ··· 5114 5148 } 5115 5149 } 5116 5150 atomic_dec(&vha->vref_count); 5151 + wake_up(&vha->vref_waitq); 5117 5152 } 5118 5153 spin_unlock_irqrestore(&ha->vport_slock, flags); 5119 5154 } ··· 5493 5526 if (!(IS_P3P_TYPE(ha))) 5494 5527 ha->isp_ops->reset_chip(vha); 5495 5528 5529 + ha->flags.n2n_ae = 0; 5530 + ha->flags.lip_ae = 0; 5531 + ha->current_topology = 0; 5532 + ha->flags.fw_started = 0; 5533 + ha->flags.fw_init_done = 0; 5496 5534 ha->chip_reset++; 5497 5535 5498 5536 atomic_set(&vha->loop_down_timer, LOOP_DOWN_TIME); ··· 6774 6802 return; 6775 6803 if (!ha->fw_major_version) 6776 6804 return; 6805 + if (!ha->flags.fw_started) 6806 + return; 6777 6807 6778 6808 ret = qla2x00_stop_firmware(vha); 6779 6809 for (retries = 5; ret != QLA_SUCCESS && ret != QLA_FUNCTION_TIMEOUT && ··· 6789 6815 "Attempting retry of stop-firmware command.\n"); 6790 6816 ret = qla2x00_stop_firmware(vha); 6791 6817 } 6818 + 6819 + ha->flags.fw_started = 0; 6820 + ha->flags.fw_init_done = 0; 6792 6821 } 6793 6822 6794 6823 int
+6 -7
drivers/scsi/qla2xxx/qla_iocb.c
··· 889 889 890 890 int 891 891 qla24xx_walk_and_build_sglist_no_difb(struct qla_hw_data *ha, srb_t *sp, 892 - uint32_t *dsd, uint16_t tot_dsds, struct qla_tgt_cmd *tc) 892 + uint32_t *dsd, uint16_t tot_dsds, struct qla_tc_param *tc) 893 893 { 894 894 void *next_dsd; 895 895 uint8_t avail_dsds = 0; ··· 898 898 struct scatterlist *sg_prot; 899 899 uint32_t *cur_dsd = dsd; 900 900 uint16_t used_dsds = tot_dsds; 901 - 902 901 uint32_t prot_int; /* protection interval */ 903 902 uint32_t partial; 904 903 struct qla2_sgx sgx; ··· 965 966 } else { 966 967 list_add_tail(&dsd_ptr->list, 967 968 &(tc->ctx->dsd_list)); 968 - tc->ctx_dsd_alloced = 1; 969 + *tc->ctx_dsd_alloced = 1; 969 970 } 970 971 971 972 ··· 1004 1005 1005 1006 int 1006 1007 qla24xx_walk_and_build_sglist(struct qla_hw_data *ha, srb_t *sp, uint32_t *dsd, 1007 - uint16_t tot_dsds, struct qla_tgt_cmd *tc) 1008 + uint16_t tot_dsds, struct qla_tc_param *tc) 1008 1009 { 1009 1010 void *next_dsd; 1010 1011 uint8_t avail_dsds = 0; ··· 1065 1066 } else { 1066 1067 list_add_tail(&dsd_ptr->list, 1067 1068 &(tc->ctx->dsd_list)); 1068 - tc->ctx_dsd_alloced = 1; 1069 + *tc->ctx_dsd_alloced = 1; 1069 1070 } 1070 1071 1071 1072 /* add new list to cmd iocb or last list */ ··· 1091 1092 1092 1093 int 1093 1094 qla24xx_walk_and_build_prot_sglist(struct qla_hw_data *ha, srb_t *sp, 1094 - uint32_t *dsd, uint16_t tot_dsds, struct qla_tgt_cmd *tc) 1095 + uint32_t *dsd, uint16_t tot_dsds, struct qla_tc_param *tc) 1095 1096 { 1096 1097 void *next_dsd; 1097 1098 uint8_t avail_dsds = 0; ··· 1157 1158 } else { 1158 1159 list_add_tail(&dsd_ptr->list, 1159 1160 &(tc->ctx->dsd_list)); 1160 - tc->ctx_dsd_alloced = 1; 1161 + *tc->ctx_dsd_alloced = 1; 1161 1162 } 1162 1163 1163 1164 /* add new list to cmd iocb or last list */
+33 -8
drivers/scsi/qla2xxx/qla_isr.c
··· 708 708 "mbx7=%xh.\n", mb[1], mb[2], mb[3], mbx); 709 709 710 710 ha->isp_ops->fw_dump(vha, 1); 711 + ha->flags.fw_init_done = 0; 712 + ha->flags.fw_started = 0; 711 713 712 714 if (IS_FWI2_CAPABLE(ha)) { 713 715 if (mb[1] == 0 && mb[2] == 0) { ··· 763 761 break; 764 762 765 763 case MBA_LIP_OCCURRED: /* Loop Initialization Procedure */ 764 + ha->flags.lip_ae = 1; 765 + ha->flags.n2n_ae = 0; 766 + 766 767 ql_dbg(ql_dbg_async, vha, 0x5009, 767 768 "LIP occurred (%x).\n", mb[1]); 768 769 ··· 802 797 break; 803 798 804 799 case MBA_LOOP_DOWN: /* Loop Down Event */ 800 + ha->flags.n2n_ae = 0; 801 + ha->flags.lip_ae = 0; 802 + ha->current_topology = 0; 803 + 805 804 mbx = (IS_QLA81XX(ha) || IS_QLA8031(ha)) 806 805 ? RD_REG_WORD(&reg24->mailbox4) : 0; 807 806 mbx = (IS_P3P_TYPE(ha)) ? RD_REG_WORD(&reg82->mailbox_out[4]) ··· 875 866 876 867 /* case MBA_DCBX_COMPLETE: */ 877 868 case MBA_POINT_TO_POINT: /* Point-to-Point */ 869 + ha->flags.lip_ae = 0; 870 + ha->flags.n2n_ae = 1; 871 + 878 872 if (IS_QLA2100(ha)) 879 873 break; 880 874 ··· 1632 1620 QLA_LOGIO_LOGIN_RETRIED : 0; 1633 1621 if (logio->entry_status) { 1634 1622 ql_log(ql_log_warn, fcport->vha, 0x5034, 1635 - "Async-%s error entry - hdl=%x" 1623 + "Async-%s error entry - %8phC hdl=%x" 1636 1624 "portid=%02x%02x%02x entry-status=%x.\n", 1637 - type, sp->handle, fcport->d_id.b.domain, 1625 + type, fcport->port_name, sp->handle, fcport->d_id.b.domain, 1638 1626 fcport->d_id.b.area, fcport->d_id.b.al_pa, 1639 1627 logio->entry_status); 1640 1628 ql_dump_buffer(ql_dbg_async + ql_dbg_buffer, vha, 0x504d, ··· 1645 1633 1646 1634 if (le16_to_cpu(logio->comp_status) == CS_COMPLETE) { 1647 1635 ql_dbg(ql_dbg_async, fcport->vha, 0x5036, 1648 - "Async-%s complete - hdl=%x portid=%02x%02x%02x " 1649 - "iop0=%x.\n", type, sp->handle, fcport->d_id.b.domain, 1636 + "Async-%s complete - %8phC hdl=%x portid=%02x%02x%02x " 1637 + "iop0=%x.\n", type, fcport->port_name, sp->handle, 1638 + fcport->d_id.b.domain, 1650 1639 fcport->d_id.b.area, fcport->d_id.b.al_pa, 1651 1640 le32_to_cpu(logio->io_parameter[0])); 1652 1641 ··· 1687 1674 case LSC_SCODE_NPORT_USED: 1688 1675 data[0] = MBS_LOOP_ID_USED; 1689 1676 break; 1677 + case LSC_SCODE_CMD_FAILED: 1678 + if (iop[1] == 0x0606) { 1679 + /* 1680 + * PLOGI/PRLI Completed. We must have Recv PLOGI/PRLI, 1681 + * Target side acked. 1682 + */ 1683 + data[0] = MBS_COMMAND_COMPLETE; 1684 + goto logio_done; 1685 + } 1686 + data[0] = MBS_COMMAND_ERROR; 1687 + break; 1690 1688 case LSC_SCODE_NOXCB: 1691 1689 vha->hw->exch_starvation++; 1692 1690 if (vha->hw->exch_starvation > 5) { ··· 1719 1695 } 1720 1696 1721 1697 ql_dbg(ql_dbg_async, fcport->vha, 0x5037, 1722 - "Async-%s failed - hdl=%x portid=%02x%02x%02x comp=%x " 1723 - "iop0=%x iop1=%x.\n", type, sp->handle, fcport->d_id.b.domain, 1698 + "Async-%s failed - %8phC hdl=%x portid=%02x%02x%02x comp=%x " 1699 + "iop0=%x iop1=%x.\n", type, fcport->port_name, 1700 + sp->handle, fcport->d_id.b.domain, 1724 1701 fcport->d_id.b.area, fcport->d_id.b.al_pa, 1725 1702 le16_to_cpu(logio->comp_status), 1726 1703 le32_to_cpu(logio->io_parameter[0]), ··· 2704 2679 return; 2705 2680 2706 2681 abt = &sp->u.iocb_cmd; 2707 - abt->u.abt.comp_status = le32_to_cpu(pkt->nport_handle); 2682 + abt->u.abt.comp_status = le16_to_cpu(pkt->nport_handle); 2708 2683 sp->done(sp, 0); 2709 2684 } 2710 2685 ··· 2718 2693 struct sts_entry_24xx *pkt; 2719 2694 struct qla_hw_data *ha = vha->hw; 2720 2695 2721 - if (!vha->flags.online) 2696 + if (!ha->flags.fw_started) 2722 2697 return; 2723 2698 2724 2699 while (rsp->ring_ptr->signature != RESPONSE_PROCESSED) {
+268 -36
drivers/scsi/qla2xxx/qla_mbx.c
··· 10 10 #include <linux/delay.h> 11 11 #include <linux/gfp.h> 12 12 13 + static struct mb_cmd_name { 14 + uint16_t cmd; 15 + const char *str; 16 + } mb_str[] = { 17 + {MBC_GET_PORT_DATABASE, "GPDB"}, 18 + {MBC_GET_ID_LIST, "GIDList"}, 19 + {MBC_GET_LINK_PRIV_STATS, "Stats"}, 20 + }; 21 + 22 + static const char *mb_to_str(uint16_t cmd) 23 + { 24 + int i; 25 + struct mb_cmd_name *e; 26 + 27 + for (i = 0; i < ARRAY_SIZE(mb_str); i++) { 28 + e = mb_str + i; 29 + if (cmd == e->cmd) 30 + return e->str; 31 + } 32 + return "unknown"; 33 + } 34 + 13 35 static struct rom_cmd { 14 36 uint16_t cmd; 15 37 } rom_cmds[] = { ··· 2840 2818 2841 2819 int 2842 2820 qla24xx_get_isp_stats(scsi_qla_host_t *vha, struct link_statistics *stats, 2843 - dma_addr_t stats_dma, uint options) 2821 + dma_addr_t stats_dma, uint16_t options) 2844 2822 { 2845 2823 int rval; 2846 2824 mbx_cmd_t mc; ··· 2850 2828 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1088, 2851 2829 "Entered %s.\n", __func__); 2852 2830 2853 - mcp->mb[0] = MBC_GET_LINK_PRIV_STATS; 2854 - mcp->mb[2] = MSW(stats_dma); 2855 - mcp->mb[3] = LSW(stats_dma); 2856 - mcp->mb[6] = MSW(MSD(stats_dma)); 2857 - mcp->mb[7] = LSW(MSD(stats_dma)); 2858 - mcp->mb[8] = sizeof(struct link_statistics) / 4; 2859 - mcp->mb[9] = vha->vp_idx; 2860 - mcp->mb[10] = options; 2861 - mcp->out_mb = MBX_10|MBX_9|MBX_8|MBX_7|MBX_6|MBX_3|MBX_2|MBX_0; 2862 - mcp->in_mb = MBX_2|MBX_1|MBX_0; 2863 - mcp->tov = MBX_TOV_SECONDS; 2864 - mcp->flags = IOCTL_CMD; 2865 - rval = qla2x00_mailbox_command(vha, mcp); 2831 + memset(&mc, 0, sizeof(mc)); 2832 + mc.mb[0] = MBC_GET_LINK_PRIV_STATS; 2833 + mc.mb[2] = MSW(stats_dma); 2834 + mc.mb[3] = LSW(stats_dma); 2835 + mc.mb[6] = MSW(MSD(stats_dma)); 2836 + mc.mb[7] = LSW(MSD(stats_dma)); 2837 + mc.mb[8] = sizeof(struct link_statistics) / 4; 2838 + mc.mb[9] = cpu_to_le16(vha->vp_idx); 2839 + mc.mb[10] = cpu_to_le16(options); 2840 + 2841 + rval = qla24xx_send_mb_cmd(vha, &mc); 2866 2842 2867 2843 if (rval == QLA_SUCCESS) { 2868 2844 if (mcp->mb[0] != MBS_COMMAND_COMPLETE) { ··· 3623 3603 scsi_qla_host_t *vp = NULL; 3624 3604 unsigned long flags; 3625 3605 int found; 3606 + port_id_t id; 3626 3607 3627 3608 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10b6, 3628 3609 "Entered %s.\n", __func__); ··· 3631 3610 if (rptid_entry->entry_status != 0) 3632 3611 return; 3633 3612 3613 + id.b.domain = rptid_entry->port_id[2]; 3614 + id.b.area = rptid_entry->port_id[1]; 3615 + id.b.al_pa = rptid_entry->port_id[0]; 3616 + id.b.rsvd_1 = 0; 3617 + 3634 3618 if (rptid_entry->format == 0) { 3635 3619 /* loop */ 3636 - ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10b7, 3620 + ql_dbg(ql_dbg_async, vha, 0x10b7, 3637 3621 "Format 0 : Number of VPs setup %d, number of " 3638 3622 "VPs acquired %d.\n", rptid_entry->vp_setup, 3639 3623 rptid_entry->vp_acquired); 3640 - ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10b8, 3624 + ql_dbg(ql_dbg_async, vha, 0x10b8, 3641 3625 "Primary port id %02x%02x%02x.\n", 3642 3626 rptid_entry->port_id[2], rptid_entry->port_id[1], 3643 3627 rptid_entry->port_id[0]); 3644 3628 3645 - vha->d_id.b.domain = rptid_entry->port_id[2]; 3646 - vha->d_id.b.area = rptid_entry->port_id[1]; 3647 - vha->d_id.b.al_pa = rptid_entry->port_id[0]; 3648 - 3649 - spin_lock_irqsave(&ha->vport_slock, flags); 3650 - qlt_update_vp_map(vha, SET_AL_PA); 3651 - spin_unlock_irqrestore(&ha->vport_slock, flags); 3629 + qlt_update_host_map(vha, id); 3652 3630 3653 3631 } else if (rptid_entry->format == 1) { 3654 3632 /* fabric */ 3655 - ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10b9, 3633 + ql_dbg(ql_dbg_async, vha, 0x10b9, 3656 3634 "Format 1: VP[%d] enabled - status %d - with " 3657 3635 "port id %02x%02x%02x.\n", rptid_entry->vp_idx, 3658 3636 rptid_entry->vp_status, ··· 3673 3653 WWN_SIZE); 3674 3654 } 3675 3655 3676 - vha->d_id.b.domain = rptid_entry->port_id[2]; 3677 - vha->d_id.b.area = rptid_entry->port_id[1]; 3678 - vha->d_id.b.al_pa = rptid_entry->port_id[0]; 3679 - spin_lock_irqsave(&ha->vport_slock, flags); 3680 - qlt_update_vp_map(vha, SET_AL_PA); 3681 - spin_unlock_irqrestore(&ha->vport_slock, flags); 3656 + qlt_update_host_map(vha, id); 3682 3657 } 3683 3658 3684 3659 fc_host_port_name(vha->host) = ··· 3709 3694 if (!found) 3710 3695 return; 3711 3696 3712 - vp->d_id.b.domain = rptid_entry->port_id[2]; 3713 - vp->d_id.b.area = rptid_entry->port_id[1]; 3714 - vp->d_id.b.al_pa = rptid_entry->port_id[0]; 3715 - spin_lock_irqsave(&ha->vport_slock, flags); 3716 - qlt_update_vp_map(vp, SET_AL_PA); 3717 - spin_unlock_irqrestore(&ha->vport_slock, flags); 3697 + qlt_update_host_map(vp, id); 3718 3698 3719 3699 /* 3720 3700 * Cannot configure here as we are still sitting on the ··· 5835 5825 dma_unmap_single(&vha->hw->pdev->dev, dd_dma, 5836 5826 size, DMA_FROM_DEVICE); 5837 5827 5828 + return rval; 5829 + } 5830 + 5831 + static void qla2x00_async_mb_sp_done(void *s, int res) 5832 + { 5833 + struct srb *sp = s; 5834 + 5835 + sp->u.iocb_cmd.u.mbx.rc = res; 5836 + 5837 + complete(&sp->u.iocb_cmd.u.mbx.comp); 5838 + /* don't free sp here. Let the caller do the free */ 5839 + } 5840 + 5841 + /* 5842 + * This mailbox uses the iocb interface to send MB command. 5843 + * This allows non-critial (non chip setup) command to go 5844 + * out in parrallel. 5845 + */ 5846 + int qla24xx_send_mb_cmd(struct scsi_qla_host *vha, mbx_cmd_t *mcp) 5847 + { 5848 + int rval = QLA_FUNCTION_FAILED; 5849 + srb_t *sp; 5850 + struct srb_iocb *c; 5851 + 5852 + if (!vha->hw->flags.fw_started) 5853 + goto done; 5854 + 5855 + sp = qla2x00_get_sp(vha, NULL, GFP_KERNEL); 5856 + if (!sp) 5857 + goto done; 5858 + 5859 + sp->type = SRB_MB_IOCB; 5860 + sp->name = mb_to_str(mcp->mb[0]); 5861 + 5862 + qla2x00_init_timer(sp, qla2x00_get_async_timeout(vha) + 2); 5863 + 5864 + memcpy(sp->u.iocb_cmd.u.mbx.out_mb, mcp->mb, SIZEOF_IOCB_MB_REG); 5865 + 5866 + c = &sp->u.iocb_cmd; 5867 + c->timeout = qla2x00_async_iocb_timeout; 5868 + init_completion(&c->u.mbx.comp); 5869 + 5870 + sp->done = qla2x00_async_mb_sp_done; 5871 + 5872 + rval = qla2x00_start_sp(sp); 5873 + if (rval != QLA_SUCCESS) { 5874 + ql_dbg(ql_dbg_mbx, vha, 0xffff, 5875 + "%s: %s Failed submission. %x.\n", 5876 + __func__, sp->name, rval); 5877 + goto done_free_sp; 5878 + } 5879 + 5880 + ql_dbg(ql_dbg_mbx, vha, 0xffff, "MB:%s hndl %x submitted\n", 5881 + sp->name, sp->handle); 5882 + 5883 + wait_for_completion(&c->u.mbx.comp); 5884 + memcpy(mcp->mb, sp->u.iocb_cmd.u.mbx.in_mb, SIZEOF_IOCB_MB_REG); 5885 + 5886 + rval = c->u.mbx.rc; 5887 + switch (rval) { 5888 + case QLA_FUNCTION_TIMEOUT: 5889 + ql_dbg(ql_dbg_mbx, vha, 0xffff, "%s: %s Timeout. %x.\n", 5890 + __func__, sp->name, rval); 5891 + break; 5892 + case QLA_SUCCESS: 5893 + ql_dbg(ql_dbg_mbx, vha, 0xffff, "%s: %s done.\n", 5894 + __func__, sp->name); 5895 + sp->free(sp); 5896 + break; 5897 + default: 5898 + ql_dbg(ql_dbg_mbx, vha, 0xffff, "%s: %s Failed. %x.\n", 5899 + __func__, sp->name, rval); 5900 + sp->free(sp); 5901 + break; 5902 + } 5903 + 5904 + return rval; 5905 + 5906 + done_free_sp: 5907 + sp->free(sp); 5908 + done: 5909 + return rval; 5910 + } 5911 + 5912 + /* 5913 + * qla24xx_gpdb_wait 5914 + * NOTE: Do not call this routine from DPC thread 5915 + */ 5916 + int qla24xx_gpdb_wait(struct scsi_qla_host *vha, fc_port_t *fcport, u8 opt) 5917 + { 5918 + int rval = QLA_FUNCTION_FAILED; 5919 + dma_addr_t pd_dma; 5920 + struct port_database_24xx *pd; 5921 + struct qla_hw_data *ha = vha->hw; 5922 + mbx_cmd_t mc; 5923 + 5924 + if (!vha->hw->flags.fw_started) 5925 + goto done; 5926 + 5927 + pd = dma_pool_alloc(ha->s_dma_pool, GFP_KERNEL, &pd_dma); 5928 + if (pd == NULL) { 5929 + ql_log(ql_log_warn, vha, 0xffff, 5930 + "Failed to allocate port database structure.\n"); 5931 + goto done_free_sp; 5932 + } 5933 + memset(pd, 0, max(PORT_DATABASE_SIZE, PORT_DATABASE_24XX_SIZE)); 5934 + 5935 + memset(&mc, 0, sizeof(mc)); 5936 + mc.mb[0] = MBC_GET_PORT_DATABASE; 5937 + mc.mb[1] = cpu_to_le16(fcport->loop_id); 5938 + mc.mb[2] = MSW(pd_dma); 5939 + mc.mb[3] = LSW(pd_dma); 5940 + mc.mb[6] = MSW(MSD(pd_dma)); 5941 + mc.mb[7] = LSW(MSD(pd_dma)); 5942 + mc.mb[9] = cpu_to_le16(vha->vp_idx); 5943 + mc.mb[10] = cpu_to_le16((uint16_t)opt); 5944 + 5945 + rval = qla24xx_send_mb_cmd(vha, &mc); 5946 + if (rval != QLA_SUCCESS) { 5947 + ql_dbg(ql_dbg_mbx, vha, 0xffff, 5948 + "%s: %8phC fail\n", __func__, fcport->port_name); 5949 + goto done_free_sp; 5950 + } 5951 + 5952 + rval = __qla24xx_parse_gpdb(vha, fcport, pd); 5953 + 5954 + ql_dbg(ql_dbg_mbx, vha, 0xffff, "%s: %8phC done\n", 5955 + __func__, fcport->port_name); 5956 + 5957 + done_free_sp: 5958 + if (pd) 5959 + dma_pool_free(ha->s_dma_pool, pd, pd_dma); 5960 + done: 5961 + return rval; 5962 + } 5963 + 5964 + int __qla24xx_parse_gpdb(struct scsi_qla_host *vha, fc_port_t *fcport, 5965 + struct port_database_24xx *pd) 5966 + { 5967 + int rval = QLA_SUCCESS; 5968 + uint64_t zero = 0; 5969 + 5970 + /* Check for logged in state. */ 5971 + if (pd->current_login_state != PDS_PRLI_COMPLETE && 5972 + pd->last_login_state != PDS_PRLI_COMPLETE) { 5973 + ql_dbg(ql_dbg_mbx, vha, 0xffff, 5974 + "Unable to verify login-state (%x/%x) for " 5975 + "loop_id %x.\n", pd->current_login_state, 5976 + pd->last_login_state, fcport->loop_id); 5977 + rval = QLA_FUNCTION_FAILED; 5978 + goto gpd_error_out; 5979 + } 5980 + 5981 + if (fcport->loop_id == FC_NO_LOOP_ID || 5982 + (memcmp(fcport->port_name, (uint8_t *)&zero, 8) && 5983 + memcmp(fcport->port_name, pd->port_name, 8))) { 5984 + /* We lost the device mid way. */ 5985 + rval = QLA_NOT_LOGGED_IN; 5986 + goto gpd_error_out; 5987 + } 5988 + 5989 + /* Names are little-endian. */ 5990 + memcpy(fcport->node_name, pd->node_name, WWN_SIZE); 5991 + memcpy(fcport->port_name, pd->port_name, WWN_SIZE); 5992 + 5993 + /* Get port_id of device. */ 5994 + fcport->d_id.b.domain = pd->port_id[0]; 5995 + fcport->d_id.b.area = pd->port_id[1]; 5996 + fcport->d_id.b.al_pa = pd->port_id[2]; 5997 + fcport->d_id.b.rsvd_1 = 0; 5998 + 5999 + /* If not target must be initiator or unknown type. */ 6000 + if ((pd->prli_svc_param_word_3[0] & BIT_4) == 0) 6001 + fcport->port_type = FCT_INITIATOR; 6002 + else 6003 + fcport->port_type = FCT_TARGET; 6004 + 6005 + /* Passback COS information. */ 6006 + fcport->supported_classes = (pd->flags & PDF_CLASS_2) ? 6007 + FC_COS_CLASS2 : FC_COS_CLASS3; 6008 + 6009 + if (pd->prli_svc_param_word_3[0] & BIT_7) { 6010 + fcport->flags |= FCF_CONF_COMP_SUPPORTED; 6011 + fcport->conf_compl_supported = 1; 6012 + } 6013 + 6014 + gpd_error_out: 6015 + return rval; 6016 + } 6017 + 6018 + /* 6019 + * qla24xx_gidlist__wait 6020 + * NOTE: don't call this routine from DPC thread. 6021 + */ 6022 + int qla24xx_gidlist_wait(struct scsi_qla_host *vha, 6023 + void *id_list, dma_addr_t id_list_dma, uint16_t *entries) 6024 + { 6025 + int rval = QLA_FUNCTION_FAILED; 6026 + mbx_cmd_t mc; 6027 + 6028 + if (!vha->hw->flags.fw_started) 6029 + goto done; 6030 + 6031 + memset(&mc, 0, sizeof(mc)); 6032 + mc.mb[0] = MBC_GET_ID_LIST; 6033 + mc.mb[2] = MSW(id_list_dma); 6034 + mc.mb[3] = LSW(id_list_dma); 6035 + mc.mb[6] = MSW(MSD(id_list_dma)); 6036 + mc.mb[7] = LSW(MSD(id_list_dma)); 6037 + mc.mb[8] = 0; 6038 + mc.mb[9] = cpu_to_le16(vha->vp_idx); 6039 + 6040 + rval = qla24xx_send_mb_cmd(vha, &mc); 6041 + if (rval != QLA_SUCCESS) { 6042 + ql_dbg(ql_dbg_mbx, vha, 0xffff, 6043 + "%s: fail\n", __func__); 6044 + } else { 6045 + *entries = mc.mb[1]; 6046 + ql_dbg(ql_dbg_mbx, vha, 0xffff, 6047 + "%s: done\n", __func__); 6048 + } 6049 + done: 5838 6050 return rval; 5839 6051 }
+8 -6
drivers/scsi/qla2xxx/qla_mid.c
··· 74 74 * ensures no active vp_list traversal while the vport is removed 75 75 * from the queue) 76 76 */ 77 + wait_event_timeout(vha->vref_waitq, atomic_read(&vha->vref_count), 78 + 10*HZ); 79 + 77 80 spin_lock_irqsave(&ha->vport_slock, flags); 78 - while (atomic_read(&vha->vref_count)) { 79 - spin_unlock_irqrestore(&ha->vport_slock, flags); 80 - 81 - msleep(500); 82 - 83 - spin_lock_irqsave(&ha->vport_slock, flags); 81 + if (atomic_read(&vha->vref_count)) { 82 + ql_dbg(ql_dbg_vport, vha, 0xfffa, 83 + "vha->vref_count=%u timeout\n", vha->vref_count.counter); 84 + vha->vref_count = (atomic_t)ATOMIC_INIT(0); 84 85 } 85 86 list_del(&vha->list); 86 87 qlt_update_vp_map(vha, RESET_VP_IDX); ··· 270 269 271 270 spin_lock_irqsave(&ha->vport_slock, flags); 272 271 atomic_dec(&vha->vref_count); 272 + wake_up(&vha->vref_waitq); 273 273 } 274 274 i++; 275 275 }
+22 -1
drivers/scsi/qla2xxx/qla_os.c
··· 2560 2560 return atomic_read(&vha->loop_state) == LOOP_READY; 2561 2561 } 2562 2562 2563 + static void qla2x00_iocb_work_fn(struct work_struct *work) 2564 + { 2565 + struct scsi_qla_host *vha = container_of(work, 2566 + struct scsi_qla_host, iocb_work); 2567 + int cnt = 0; 2568 + 2569 + while (!list_empty(&vha->work_list)) { 2570 + qla2x00_do_work(vha); 2571 + cnt++; 2572 + if (cnt > 10) 2573 + break; 2574 + } 2575 + } 2576 + 2563 2577 /* 2564 2578 * PCI driver interface 2565 2579 */ ··· 3092 3078 */ 3093 3079 qla2xxx_wake_dpc(base_vha); 3094 3080 3081 + INIT_WORK(&base_vha->iocb_work, qla2x00_iocb_work_fn); 3095 3082 INIT_WORK(&ha->board_disable, qla2x00_disable_board_on_pci_error); 3096 3083 3097 3084 if (IS_QLA8031(ha) || IS_MCTP_CAPABLE(ha)) { ··· 3484 3469 qla2x00_free_sysfs_attr(base_vha, true); 3485 3470 3486 3471 fc_remove_host(base_vha->host); 3472 + qlt_remove_target_resources(ha); 3487 3473 3488 3474 scsi_remove_host(base_vha->host); 3489 3475 ··· 4284 4268 spin_lock_init(&vha->work_lock); 4285 4269 spin_lock_init(&vha->cmd_list_lock); 4286 4270 init_waitqueue_head(&vha->fcport_waitQ); 4271 + init_waitqueue_head(&vha->vref_waitq); 4287 4272 4288 4273 vha->gnl.size = sizeof(struct get_name_list_extended) * 4289 4274 (ha->max_loop_id + 1); ··· 4336 4319 spin_lock_irqsave(&vha->work_lock, flags); 4337 4320 list_add_tail(&e->list, &vha->work_list); 4338 4321 spin_unlock_irqrestore(&vha->work_lock, flags); 4339 - qla2xxx_wake_dpc(vha); 4322 + 4323 + if (QLA_EARLY_LINKUP(vha->hw)) 4324 + schedule_work(&vha->iocb_work); 4325 + else 4326 + qla2xxx_wake_dpc(vha); 4340 4327 4341 4328 return QLA_SUCCESS; 4342 4329 }
+472 -280
drivers/scsi/qla2xxx/qla_target.c
··· 130 130 static struct fc_port *qlt_create_sess(struct scsi_qla_host *vha, 131 131 fc_port_t *fcport, bool local); 132 132 void qlt_unreg_sess(struct fc_port *sess); 133 + static void qlt_24xx_handle_abts(struct scsi_qla_host *, 134 + struct abts_recv_from_24xx *); 135 + 133 136 /* 134 137 * Global Variables 135 138 */ ··· 142 139 static struct workqueue_struct *qla_tgt_wq; 143 140 static DEFINE_MUTEX(qla_tgt_mutex); 144 141 static LIST_HEAD(qla_tgt_glist); 142 + 143 + static const char *prot_op_str(u32 prot_op) 144 + { 145 + switch (prot_op) { 146 + case TARGET_PROT_NORMAL: return "NORMAL"; 147 + case TARGET_PROT_DIN_INSERT: return "DIN_INSERT"; 148 + case TARGET_PROT_DOUT_INSERT: return "DOUT_INSERT"; 149 + case TARGET_PROT_DIN_STRIP: return "DIN_STRIP"; 150 + case TARGET_PROT_DOUT_STRIP: return "DOUT_STRIP"; 151 + case TARGET_PROT_DIN_PASS: return "DIN_PASS"; 152 + case TARGET_PROT_DOUT_PASS: return "DOUT_PASS"; 153 + default: return "UNKNOWN"; 154 + } 155 + } 145 156 146 157 /* This API intentionally takes dest as a parameter, rather than returning 147 158 * int value to avoid caller forgetting to issue wmb() after the store */ ··· 187 170 struct scsi_qla_host *qlt_find_host_by_d_id(struct scsi_qla_host *vha, 188 171 uint8_t *d_id) 189 172 { 190 - struct qla_hw_data *ha = vha->hw; 191 - uint8_t vp_idx; 173 + struct scsi_qla_host *host; 174 + uint32_t key = 0; 192 175 193 - if ((vha->d_id.b.area != d_id[1]) || (vha->d_id.b.domain != d_id[0])) 194 - return NULL; 195 - 196 - if (vha->d_id.b.al_pa == d_id[2]) 176 + if ((vha->d_id.b.area == d_id[1]) && (vha->d_id.b.domain == d_id[0]) && 177 + (vha->d_id.b.al_pa == d_id[2])) 197 178 return vha; 198 179 199 - BUG_ON(ha->tgt.tgt_vp_map == NULL); 200 - vp_idx = ha->tgt.tgt_vp_map[d_id[2]].idx; 201 - if (likely(test_bit(vp_idx, ha->vp_idx_map))) 202 - return ha->tgt.tgt_vp_map[vp_idx].vha; 180 + key = (uint32_t)d_id[0] << 16; 181 + key |= (uint32_t)d_id[1] << 8; 182 + key |= (uint32_t)d_id[2]; 203 183 204 - return NULL; 184 + host = btree_lookup32(&vha->hw->tgt.host_map, key); 185 + if (!host) 186 + ql_dbg(ql_dbg_tgt_mgt, vha, 0xffff, 187 + "Unable to find host %06x\n", key); 188 + 189 + return host; 205 190 } 206 191 207 192 static inline ··· 408 389 (struct abts_recv_from_24xx *)atio; 409 390 struct scsi_qla_host *host = qlt_find_host_by_vp_idx(vha, 410 391 entry->vp_index); 392 + unsigned long flags; 393 + 411 394 if (unlikely(!host)) { 412 395 ql_dbg(ql_dbg_tgt, vha, 0xffff, 413 396 "qla_target(%d): Response pkt (ABTS_RECV_24XX) " ··· 417 396 vha->vp_idx, entry->vp_index); 418 397 break; 419 398 } 420 - qlt_response_pkt(host, (response_t *)atio); 399 + if (!ha_locked) 400 + spin_lock_irqsave(&host->hw->hardware_lock, flags); 401 + qlt_24xx_handle_abts(host, (struct abts_recv_from_24xx *)atio); 402 + if (!ha_locked) 403 + spin_unlock_irqrestore(&host->hw->hardware_lock, flags); 421 404 break; 422 - 423 405 } 424 406 425 407 /* case PUREX_IOCB_TYPE: ql2xmvasynctoatio */ ··· 578 554 sp->fcport->login_gen++; 579 555 sp->fcport->fw_login_state = DSC_LS_PLOGI_COMP; 580 556 sp->fcport->logout_on_delete = 1; 557 + sp->fcport->plogi_nack_done_deadline = jiffies + HZ; 581 558 break; 582 559 583 560 case SRB_NACK_PRLI: ··· 638 613 break; 639 614 case SRB_NACK_PRLI: 640 615 fcport->fw_login_state = DSC_LS_PRLI_PEND; 616 + fcport->deleted = 0; 641 617 c = "PRLI"; 642 618 break; 643 619 case SRB_NACK_LOGO: ··· 1241 1215 } 1242 1216 1243 1217 /* Get list of logged in devices */ 1244 - rc = qla2x00_get_id_list(vha, gid_list, gid_list_dma, &entries); 1218 + rc = qla24xx_gidlist_wait(vha, gid_list, gid_list_dma, &entries); 1245 1219 if (rc != QLA_SUCCESS) { 1246 1220 ql_dbg(ql_dbg_tgt_mgt, vha, 0xf045, 1247 1221 "qla_target(%d): get_id_list() failed: %x\n", ··· 1576 1550 struct qla_hw_data *ha = vha->hw; 1577 1551 request_t *pkt; 1578 1552 struct nack_to_isp *nack; 1553 + 1554 + if (!ha->flags.fw_started) 1555 + return; 1579 1556 1580 1557 ql_dbg(ql_dbg_tgt, vha, 0xe004, "Sending NOTIFY_ACK (ha=%p)\n", ha); 1581 1558 ··· 2042 2013 } 2043 2014 EXPORT_SYMBOL(qlt_free_mcmd); 2044 2015 2016 + /* 2017 + * ha->hardware_lock supposed to be held on entry. Might drop it, then 2018 + * reacquire 2019 + */ 2020 + void qlt_send_resp_ctio(scsi_qla_host_t *vha, struct qla_tgt_cmd *cmd, 2021 + uint8_t scsi_status, uint8_t sense_key, uint8_t asc, uint8_t ascq) 2022 + { 2023 + struct atio_from_isp *atio = &cmd->atio; 2024 + struct ctio7_to_24xx *ctio; 2025 + uint16_t temp; 2026 + 2027 + ql_dbg(ql_dbg_tgt_dif, vha, 0x3066, 2028 + "Sending response CTIO7 (vha=%p, atio=%p, scsi_status=%02x, " 2029 + "sense_key=%02x, asc=%02x, ascq=%02x", 2030 + vha, atio, scsi_status, sense_key, asc, ascq); 2031 + 2032 + ctio = (struct ctio7_to_24xx *)qla2x00_alloc_iocbs(vha, NULL); 2033 + if (!ctio) { 2034 + ql_dbg(ql_dbg_async, vha, 0x3067, 2035 + "qla2x00t(%ld): %s failed: unable to allocate request packet", 2036 + vha->host_no, __func__); 2037 + goto out; 2038 + } 2039 + 2040 + ctio->entry_type = CTIO_TYPE7; 2041 + ctio->entry_count = 1; 2042 + ctio->handle = QLA_TGT_SKIP_HANDLE; 2043 + ctio->nport_handle = cmd->sess->loop_id; 2044 + ctio->timeout = cpu_to_le16(QLA_TGT_TIMEOUT); 2045 + ctio->vp_index = vha->vp_idx; 2046 + ctio->initiator_id[0] = atio->u.isp24.fcp_hdr.s_id[2]; 2047 + ctio->initiator_id[1] = atio->u.isp24.fcp_hdr.s_id[1]; 2048 + ctio->initiator_id[2] = atio->u.isp24.fcp_hdr.s_id[0]; 2049 + ctio->exchange_addr = atio->u.isp24.exchange_addr; 2050 + ctio->u.status1.flags = (atio->u.isp24.attr << 9) | 2051 + cpu_to_le16(CTIO7_FLAGS_STATUS_MODE_1 | CTIO7_FLAGS_SEND_STATUS); 2052 + temp = be16_to_cpu(atio->u.isp24.fcp_hdr.ox_id); 2053 + ctio->u.status1.ox_id = cpu_to_le16(temp); 2054 + ctio->u.status1.scsi_status = 2055 + cpu_to_le16(SS_RESPONSE_INFO_LEN_VALID | scsi_status); 2056 + ctio->u.status1.response_len = cpu_to_le16(18); 2057 + ctio->u.status1.residual = cpu_to_le32(get_datalen_for_atio(atio)); 2058 + 2059 + if (ctio->u.status1.residual != 0) 2060 + ctio->u.status1.scsi_status |= 2061 + cpu_to_le16(SS_RESIDUAL_UNDER); 2062 + 2063 + /* Response code and sense key */ 2064 + put_unaligned_le32(((0x70 << 24) | (sense_key << 8)), 2065 + (&ctio->u.status1.sense_data)[0]); 2066 + /* Additional sense length */ 2067 + put_unaligned_le32(0x0a, (&ctio->u.status1.sense_data)[1]); 2068 + /* ASC and ASCQ */ 2069 + put_unaligned_le32(((asc << 24) | (ascq << 16)), 2070 + (&ctio->u.status1.sense_data)[3]); 2071 + 2072 + /* Memory Barrier */ 2073 + wmb(); 2074 + 2075 + qla2x00_start_iocbs(vha, vha->req); 2076 + out: 2077 + return; 2078 + } 2079 + 2045 2080 /* callback from target fabric module code */ 2046 2081 void qlt_xmit_tm_rsp(struct qla_tgt_mgmt_cmd *mcmd) 2047 2082 { ··· 2354 2261 */ 2355 2262 return -EAGAIN; 2356 2263 } else 2357 - ha->tgt.cmds[h-1] = prm->cmd; 2264 + ha->tgt.cmds[h - 1] = prm->cmd; 2358 2265 2359 2266 pkt->handle = h | CTIO_COMPLETION_HANDLE_MARK; 2360 2267 pkt->nport_handle = prm->cmd->loop_id; ··· 2484 2391 return cmd->bufflen > 0; 2485 2392 } 2486 2393 2394 + static void qlt_print_dif_err(struct qla_tgt_prm *prm) 2395 + { 2396 + struct qla_tgt_cmd *cmd; 2397 + struct scsi_qla_host *vha; 2398 + 2399 + /* asc 0x10=dif error */ 2400 + if (prm->sense_buffer && (prm->sense_buffer[12] == 0x10)) { 2401 + cmd = prm->cmd; 2402 + vha = cmd->vha; 2403 + /* ASCQ */ 2404 + switch (prm->sense_buffer[13]) { 2405 + case 1: 2406 + ql_dbg(ql_dbg_tgt_dif, vha, 0xffff, 2407 + "BE detected Guard TAG ERR: lba[0x%llx|%lld] len[0x%x] " 2408 + "se_cmd=%p tag[%x]", 2409 + cmd->lba, cmd->lba, cmd->num_blks, &cmd->se_cmd, 2410 + cmd->atio.u.isp24.exchange_addr); 2411 + break; 2412 + case 2: 2413 + ql_dbg(ql_dbg_tgt_dif, vha, 0xffff, 2414 + "BE detected APP TAG ERR: lba[0x%llx|%lld] len[0x%x] " 2415 + "se_cmd=%p tag[%x]", 2416 + cmd->lba, cmd->lba, cmd->num_blks, &cmd->se_cmd, 2417 + cmd->atio.u.isp24.exchange_addr); 2418 + break; 2419 + case 3: 2420 + ql_dbg(ql_dbg_tgt_dif, vha, 0xffff, 2421 + "BE detected REF TAG ERR: lba[0x%llx|%lld] len[0x%x] " 2422 + "se_cmd=%p tag[%x]", 2423 + cmd->lba, cmd->lba, cmd->num_blks, &cmd->se_cmd, 2424 + cmd->atio.u.isp24.exchange_addr); 2425 + break; 2426 + default: 2427 + ql_dbg(ql_dbg_tgt_dif, vha, 0xffff, 2428 + "BE detected Dif ERR: lba[%llx|%lld] len[%x] " 2429 + "se_cmd=%p tag[%x]", 2430 + cmd->lba, cmd->lba, cmd->num_blks, &cmd->se_cmd, 2431 + cmd->atio.u.isp24.exchange_addr); 2432 + break; 2433 + } 2434 + ql_dump_buffer(ql_dbg_tgt_dif, vha, 0xffff, cmd->cdb, 16); 2435 + } 2436 + } 2437 + 2487 2438 /* 2488 2439 * Called without ha->hardware_lock held 2489 2440 */ ··· 2649 2512 for (i = 0; i < prm->sense_buffer_len/4; i++) 2650 2513 ((uint32_t *)ctio->u.status1.sense_data)[i] = 2651 2514 cpu_to_be32(((uint32_t *)prm->sense_buffer)[i]); 2652 - #if 0 2653 - if (unlikely((prm->sense_buffer_len % 4) != 0)) { 2654 - static int q; 2655 - if (q < 10) { 2656 - ql_dbg(ql_dbg_tgt, vha, 0xe04f, 2657 - "qla_target(%d): %d bytes of sense " 2658 - "lost", prm->tgt->ha->vp_idx, 2659 - prm->sense_buffer_len % 4); 2660 - q++; 2661 - } 2662 - } 2663 - #endif 2515 + 2516 + qlt_print_dif_err(prm); 2517 + 2664 2518 } else { 2665 2519 ctio->u.status1.flags &= 2666 2520 ~cpu_to_le16(CTIO7_FLAGS_STATUS_MODE_0); ··· 2665 2537 /* Sense with len > 24, is it possible ??? */ 2666 2538 } 2667 2539 2668 - 2669 - 2670 - /* diff */ 2671 2540 static inline int 2672 2541 qlt_hba_err_chk_enabled(struct se_cmd *se_cmd) 2673 2542 { 2674 - /* 2675 - * Uncomment when corresponding SCSI changes are done. 2676 - * 2677 - if (!sp->cmd->prot_chk) 2678 - return 0; 2679 - * 2680 - */ 2681 2543 switch (se_cmd->prot_op) { 2682 2544 case TARGET_PROT_DOUT_INSERT: 2683 2545 case TARGET_PROT_DIN_STRIP: ··· 2688 2570 return 0; 2689 2571 } 2690 2572 2691 - /* 2692 - * qla24xx_set_t10dif_tags_from_cmd - Extract Ref and App tags from SCSI command 2693 - * 2694 - */ 2695 - static inline void 2696 - qlt_set_t10dif_tags(struct se_cmd *se_cmd, struct crc_context *ctx) 2573 + static inline int 2574 + qla_tgt_ref_mask_check(struct se_cmd *se_cmd) 2697 2575 { 2698 - uint32_t lba = 0xffffffff & se_cmd->t_task_lba; 2576 + switch (se_cmd->prot_op) { 2577 + case TARGET_PROT_DIN_INSERT: 2578 + case TARGET_PROT_DOUT_INSERT: 2579 + case TARGET_PROT_DIN_STRIP: 2580 + case TARGET_PROT_DOUT_STRIP: 2581 + case TARGET_PROT_DIN_PASS: 2582 + case TARGET_PROT_DOUT_PASS: 2583 + return 1; 2584 + default: 2585 + return 0; 2586 + } 2587 + return 0; 2588 + } 2699 2589 2700 - /* wait til Mode Sense/Select cmd, modepage Ah, subpage 2 2590 + /* 2591 + * qla_tgt_set_dif_tags - Extract Ref and App tags from SCSI command 2592 + */ 2593 + static void 2594 + qla_tgt_set_dif_tags(struct qla_tgt_cmd *cmd, struct crc_context *ctx, 2595 + uint16_t *pfw_prot_opts) 2596 + { 2597 + struct se_cmd *se_cmd = &cmd->se_cmd; 2598 + uint32_t lba = 0xffffffff & se_cmd->t_task_lba; 2599 + scsi_qla_host_t *vha = cmd->tgt->vha; 2600 + struct qla_hw_data *ha = vha->hw; 2601 + uint32_t t32 = 0; 2602 + 2603 + /* 2604 + * wait till Mode Sense/Select cmd, modepage Ah, subpage 2 2701 2605 * have been immplemented by TCM, before AppTag is avail. 2702 2606 * Look for modesense_handlers[] 2703 2607 */ ··· 2727 2587 ctx->app_tag_mask[0] = 0x0; 2728 2588 ctx->app_tag_mask[1] = 0x0; 2729 2589 2590 + if (IS_PI_UNINIT_CAPABLE(ha)) { 2591 + if ((se_cmd->prot_type == TARGET_DIF_TYPE1_PROT) || 2592 + (se_cmd->prot_type == TARGET_DIF_TYPE2_PROT)) 2593 + *pfw_prot_opts |= PO_DIS_VALD_APP_ESC; 2594 + else if (se_cmd->prot_type == TARGET_DIF_TYPE3_PROT) 2595 + *pfw_prot_opts |= PO_DIS_VALD_APP_REF_ESC; 2596 + } 2597 + 2598 + t32 = ha->tgt.tgt_ops->get_dif_tags(cmd, pfw_prot_opts); 2599 + 2730 2600 switch (se_cmd->prot_type) { 2731 2601 case TARGET_DIF_TYPE0_PROT: 2732 2602 /* 2733 - * No check for ql2xenablehba_err_chk, as it would be an 2734 - * I/O error if hba tag generation is not done. 2603 + * No check for ql2xenablehba_err_chk, as it 2604 + * would be an I/O error if hba tag generation 2605 + * is not done. 2735 2606 */ 2736 2607 ctx->ref_tag = cpu_to_le32(lba); 2737 - 2738 - if (!qlt_hba_err_chk_enabled(se_cmd)) 2739 - break; 2740 - 2741 2608 /* enable ALL bytes of the ref tag */ 2742 2609 ctx->ref_tag_mask[0] = 0xff; 2743 2610 ctx->ref_tag_mask[1] = 0xff; 2744 2611 ctx->ref_tag_mask[2] = 0xff; 2745 2612 ctx->ref_tag_mask[3] = 0xff; 2746 2613 break; 2747 - /* 2748 - * For TYpe 1 protection: 16 bit GUARD tag, 32 bit REF tag, and 2749 - * 16 bit app tag. 2750 - */ 2751 2614 case TARGET_DIF_TYPE1_PROT: 2752 - ctx->ref_tag = cpu_to_le32(lba); 2753 - 2754 - if (!qlt_hba_err_chk_enabled(se_cmd)) 2755 - break; 2756 - 2757 - /* enable ALL bytes of the ref tag */ 2758 - ctx->ref_tag_mask[0] = 0xff; 2759 - ctx->ref_tag_mask[1] = 0xff; 2760 - ctx->ref_tag_mask[2] = 0xff; 2761 - ctx->ref_tag_mask[3] = 0xff; 2762 - break; 2763 - /* 2764 - * For TYPE 2 protection: 16 bit GUARD + 32 bit REF tag has to 2765 - * match LBA in CDB + N 2766 - */ 2615 + /* 2616 + * For TYPE 1 protection: 16 bit GUARD tag, 32 bit 2617 + * REF tag, and 16 bit app tag. 2618 + */ 2619 + ctx->ref_tag = cpu_to_le32(lba); 2620 + if (!qla_tgt_ref_mask_check(se_cmd) || 2621 + !(ha->tgt.tgt_ops->chk_dif_tags(t32))) { 2622 + *pfw_prot_opts |= PO_DIS_REF_TAG_VALD; 2623 + break; 2624 + } 2625 + /* enable ALL bytes of the ref tag */ 2626 + ctx->ref_tag_mask[0] = 0xff; 2627 + ctx->ref_tag_mask[1] = 0xff; 2628 + ctx->ref_tag_mask[2] = 0xff; 2629 + ctx->ref_tag_mask[3] = 0xff; 2630 + break; 2767 2631 case TARGET_DIF_TYPE2_PROT: 2768 - ctx->ref_tag = cpu_to_le32(lba); 2769 - 2770 - if (!qlt_hba_err_chk_enabled(se_cmd)) 2771 - break; 2772 - 2773 - /* enable ALL bytes of the ref tag */ 2774 - ctx->ref_tag_mask[0] = 0xff; 2775 - ctx->ref_tag_mask[1] = 0xff; 2776 - ctx->ref_tag_mask[2] = 0xff; 2777 - ctx->ref_tag_mask[3] = 0xff; 2778 - break; 2779 - 2780 - /* For Type 3 protection: 16 bit GUARD only */ 2632 + /* 2633 + * For TYPE 2 protection: 16 bit GUARD + 32 bit REF 2634 + * tag has to match LBA in CDB + N 2635 + */ 2636 + ctx->ref_tag = cpu_to_le32(lba); 2637 + if (!qla_tgt_ref_mask_check(se_cmd) || 2638 + !(ha->tgt.tgt_ops->chk_dif_tags(t32))) { 2639 + *pfw_prot_opts |= PO_DIS_REF_TAG_VALD; 2640 + break; 2641 + } 2642 + /* enable ALL bytes of the ref tag */ 2643 + ctx->ref_tag_mask[0] = 0xff; 2644 + ctx->ref_tag_mask[1] = 0xff; 2645 + ctx->ref_tag_mask[2] = 0xff; 2646 + ctx->ref_tag_mask[3] = 0xff; 2647 + break; 2781 2648 case TARGET_DIF_TYPE3_PROT: 2782 - ctx->ref_tag_mask[0] = ctx->ref_tag_mask[1] = 2783 - ctx->ref_tag_mask[2] = ctx->ref_tag_mask[3] = 0x00; 2784 - break; 2649 + /* For TYPE 3 protection: 16 bit GUARD only */ 2650 + *pfw_prot_opts |= PO_DIS_REF_TAG_VALD; 2651 + ctx->ref_tag_mask[0] = ctx->ref_tag_mask[1] = 2652 + ctx->ref_tag_mask[2] = ctx->ref_tag_mask[3] = 0x00; 2653 + break; 2785 2654 } 2786 2655 } 2787 - 2788 2656 2789 2657 static inline int 2790 2658 qlt_build_ctio_crc2_pkt(struct qla_tgt_prm *prm, scsi_qla_host_t *vha) ··· 2812 2664 struct se_cmd *se_cmd = &cmd->se_cmd; 2813 2665 uint32_t h; 2814 2666 struct atio_from_isp *atio = &prm->cmd->atio; 2667 + struct qla_tc_param tc; 2815 2668 uint16_t t16; 2816 2669 2817 2670 ha = vha->hw; ··· 2838 2689 case TARGET_PROT_DIN_INSERT: 2839 2690 case TARGET_PROT_DOUT_STRIP: 2840 2691 transfer_length = data_bytes; 2841 - data_bytes += dif_bytes; 2692 + if (cmd->prot_sg_cnt) 2693 + data_bytes += dif_bytes; 2842 2694 break; 2843 - 2844 2695 case TARGET_PROT_DIN_STRIP: 2845 2696 case TARGET_PROT_DOUT_INSERT: 2846 2697 case TARGET_PROT_DIN_PASS: 2847 2698 case TARGET_PROT_DOUT_PASS: 2848 2699 transfer_length = data_bytes + dif_bytes; 2849 2700 break; 2850 - 2851 2701 default: 2852 2702 BUG(); 2853 2703 break; ··· 2882 2734 break; 2883 2735 } 2884 2736 2885 - 2886 2737 /* ---- PKT ---- */ 2887 2738 /* Update entry type to indicate Command Type CRC_2 IOCB */ 2888 2739 pkt->entry_type = CTIO_CRC2; ··· 2899 2752 } else 2900 2753 ha->tgt.cmds[h-1] = prm->cmd; 2901 2754 2902 - 2903 2755 pkt->handle = h | CTIO_COMPLETION_HANDLE_MARK; 2904 - pkt->nport_handle = prm->cmd->loop_id; 2756 + pkt->nport_handle = cpu_to_le16(prm->cmd->loop_id); 2905 2757 pkt->timeout = cpu_to_le16(QLA_TGT_TIMEOUT); 2906 2758 pkt->initiator_id[0] = atio->u.isp24.fcp_hdr.s_id[2]; 2907 2759 pkt->initiator_id[1] = atio->u.isp24.fcp_hdr.s_id[1]; ··· 2921 2775 else if (cmd->dma_data_direction == DMA_FROM_DEVICE) 2922 2776 pkt->flags = cpu_to_le16(CTIO7_FLAGS_DATA_OUT); 2923 2777 2924 - 2925 2778 pkt->dseg_count = prm->tot_dsds; 2926 2779 /* Fibre channel byte count */ 2927 2780 pkt->transfer_length = cpu_to_le32(transfer_length); 2928 - 2929 2781 2930 2782 /* ----- CRC context -------- */ 2931 2783 ··· 2944 2800 /* Set handle */ 2945 2801 crc_ctx_pkt->handle = pkt->handle; 2946 2802 2947 - qlt_set_t10dif_tags(se_cmd, crc_ctx_pkt); 2803 + qla_tgt_set_dif_tags(cmd, crc_ctx_pkt, &fw_prot_opts); 2948 2804 2949 2805 pkt->crc_context_address[0] = cpu_to_le32(LSD(crc_ctx_dma)); 2950 2806 pkt->crc_context_address[1] = cpu_to_le32(MSD(crc_ctx_dma)); 2951 2807 pkt->crc_context_len = CRC_CONTEXT_LEN_FW; 2952 - 2953 2808 2954 2809 if (!bundling) { 2955 2810 cur_dsd = (uint32_t *) &crc_ctx_pkt->u.nobundling.data_address; ··· 2970 2827 crc_ctx_pkt->byte_count = cpu_to_le32(data_bytes); 2971 2828 crc_ctx_pkt->guard_seed = cpu_to_le16(0); 2972 2829 2830 + memset((uint8_t *)&tc, 0 , sizeof(tc)); 2831 + tc.vha = vha; 2832 + tc.blk_sz = cmd->blk_sz; 2833 + tc.bufflen = cmd->bufflen; 2834 + tc.sg = cmd->sg; 2835 + tc.prot_sg = cmd->prot_sg; 2836 + tc.ctx = crc_ctx_pkt; 2837 + tc.ctx_dsd_alloced = &cmd->ctx_dsd_alloced; 2973 2838 2974 2839 /* Walks data segments */ 2975 2840 pkt->flags |= cpu_to_le16(CTIO7_FLAGS_DSD_PTR); 2976 2841 2977 2842 if (!bundling && prm->prot_seg_cnt) { 2978 2843 if (qla24xx_walk_and_build_sglist_no_difb(ha, NULL, cur_dsd, 2979 - prm->tot_dsds, cmd)) 2844 + prm->tot_dsds, &tc)) 2980 2845 goto crc_queuing_error; 2981 2846 } else if (qla24xx_walk_and_build_sglist(ha, NULL, cur_dsd, 2982 - (prm->tot_dsds - prm->prot_seg_cnt), cmd)) 2847 + (prm->tot_dsds - prm->prot_seg_cnt), &tc)) 2983 2848 goto crc_queuing_error; 2984 2849 2985 2850 if (bundling && prm->prot_seg_cnt) { ··· 2996 2845 2997 2846 cur_dsd = (uint32_t *) &crc_ctx_pkt->u.bundling.dif_address; 2998 2847 if (qla24xx_walk_and_build_prot_sglist(ha, NULL, cur_dsd, 2999 - prm->prot_seg_cnt, cmd)) 2848 + prm->prot_seg_cnt, &tc)) 3000 2849 goto crc_queuing_error; 3001 2850 } 3002 2851 return QLA_SUCCESS; 3003 2852 3004 2853 crc_queuing_error: 3005 2854 /* Cleanup will be performed by the caller */ 2855 + vha->hw->tgt.cmds[h - 1] = NULL; 3006 2856 3007 2857 return QLA_FUNCTION_FAILED; 3008 2858 } 3009 - 3010 2859 3011 2860 /* 3012 2861 * Callback to setup response of xmit_type of QLA_TGT_XMIT_DATA and * ··· 3057 2906 else 3058 2907 vha->tgt_counters.core_qla_que_buf++; 3059 2908 3060 - if (!vha->flags.online || cmd->reset_count != ha->chip_reset) { 2909 + if (!ha->flags.fw_started || cmd->reset_count != ha->chip_reset) { 3061 2910 /* 3062 2911 * Either the port is not online or this request was from 3063 2912 * previous life, just abort the processing. ··· 3198 3047 3199 3048 spin_lock_irqsave(&ha->hardware_lock, flags); 3200 3049 3201 - if (!vha->flags.online || (cmd->reset_count != ha->chip_reset) || 3050 + if (!ha->flags.fw_started || (cmd->reset_count != ha->chip_reset) || 3202 3051 (cmd->sess && cmd->sess->deleted)) { 3203 3052 /* 3204 3053 * Either the port is not online or this request was from ··· 3255 3104 3256 3105 3257 3106 /* 3258 - * Checks the guard or meta-data for the type of error 3259 - * detected by the HBA. 3107 + * it is assumed either hardware_lock or qpair lock is held. 3260 3108 */ 3261 - static inline int 3109 + static void 3262 3110 qlt_handle_dif_error(struct scsi_qla_host *vha, struct qla_tgt_cmd *cmd, 3263 - struct ctio_crc_from_fw *sts) 3111 + struct ctio_crc_from_fw *sts) 3264 3112 { 3265 3113 uint8_t *ap = &sts->actual_dif[0]; 3266 3114 uint8_t *ep = &sts->expected_dif[0]; 3267 - uint32_t e_ref_tag, a_ref_tag; 3268 - uint16_t e_app_tag, a_app_tag; 3269 - uint16_t e_guard, a_guard; 3270 3115 uint64_t lba = cmd->se_cmd.t_task_lba; 3116 + uint8_t scsi_status, sense_key, asc, ascq; 3117 + unsigned long flags; 3271 3118 3272 - a_guard = be16_to_cpu(*(uint16_t *)(ap + 0)); 3273 - a_app_tag = be16_to_cpu(*(uint16_t *)(ap + 2)); 3274 - a_ref_tag = be32_to_cpu(*(uint32_t *)(ap + 4)); 3119 + cmd->trc_flags |= TRC_DIF_ERR; 3275 3120 3276 - e_guard = be16_to_cpu(*(uint16_t *)(ep + 0)); 3277 - e_app_tag = be16_to_cpu(*(uint16_t *)(ep + 2)); 3278 - e_ref_tag = be32_to_cpu(*(uint32_t *)(ep + 4)); 3121 + cmd->a_guard = be16_to_cpu(*(uint16_t *)(ap + 0)); 3122 + cmd->a_app_tag = be16_to_cpu(*(uint16_t *)(ap + 2)); 3123 + cmd->a_ref_tag = be32_to_cpu(*(uint32_t *)(ap + 4)); 3279 3124 3280 - ql_dbg(ql_dbg_tgt, vha, 0xe075, 3281 - "iocb(s) %p Returned STATUS.\n", sts); 3125 + cmd->e_guard = be16_to_cpu(*(uint16_t *)(ep + 0)); 3126 + cmd->e_app_tag = be16_to_cpu(*(uint16_t *)(ep + 2)); 3127 + cmd->e_ref_tag = be32_to_cpu(*(uint32_t *)(ep + 4)); 3282 3128 3283 - ql_dbg(ql_dbg_tgt, vha, 0xf075, 3284 - "dif check TGT cdb 0x%x lba 0x%llx: [Actual|Expected] Ref Tag[0x%x|0x%x], App Tag [0x%x|0x%x], Guard [0x%x|0x%x]\n", 3285 - cmd->atio.u.isp24.fcp_cmnd.cdb[0], lba, 3286 - a_ref_tag, e_ref_tag, a_app_tag, e_app_tag, a_guard, e_guard); 3129 + ql_dbg(ql_dbg_tgt_dif, vha, 0xf075, 3130 + "%s: aborted %d state %d\n", __func__, cmd->aborted, cmd->state); 3287 3131 3288 - /* 3289 - * Ignore sector if: 3290 - * For type 3: ref & app tag is all 'f's 3291 - * For type 0,1,2: app tag is all 'f's 3292 - */ 3293 - if ((a_app_tag == 0xffff) && 3294 - ((cmd->se_cmd.prot_type != TARGET_DIF_TYPE3_PROT) || 3295 - (a_ref_tag == 0xffffffff))) { 3296 - uint32_t blocks_done; 3132 + scsi_status = sense_key = asc = ascq = 0; 3297 3133 3298 - /* 2TB boundary case covered automatically with this */ 3299 - blocks_done = e_ref_tag - (uint32_t)lba + 1; 3300 - cmd->se_cmd.bad_sector = e_ref_tag; 3301 - cmd->se_cmd.pi_err = 0; 3302 - ql_dbg(ql_dbg_tgt, vha, 0xf074, 3303 - "need to return scsi good\n"); 3134 + /* check appl tag */ 3135 + if (cmd->e_app_tag != cmd->a_app_tag) { 3136 + ql_dbg(ql_dbg_tgt_dif, vha, 0xffff, 3137 + "App Tag ERR: cdb[%x] lba[%llx %llx] blks[%x] [Actual|Expected] " 3138 + "Ref[%x|%x], App[%x|%x], " 3139 + "Guard [%x|%x] cmd=%p ox_id[%04x]", 3140 + cmd->cdb[0], lba, (lba+cmd->num_blks), cmd->num_blks, 3141 + cmd->a_ref_tag, cmd->e_ref_tag, 3142 + cmd->a_app_tag, cmd->e_app_tag, 3143 + cmd->a_guard, cmd->e_guard, 3144 + cmd, cmd->atio.u.isp24.fcp_hdr.ox_id); 3304 3145 3305 - /* Update protection tag */ 3306 - if (cmd->prot_sg_cnt) { 3307 - uint32_t i, k = 0, num_ent; 3308 - struct scatterlist *sg, *sgl; 3309 - 3310 - 3311 - sgl = cmd->prot_sg; 3312 - 3313 - /* Patch the corresponding protection tags */ 3314 - for_each_sg(sgl, sg, cmd->prot_sg_cnt, i) { 3315 - num_ent = sg_dma_len(sg) / 8; 3316 - if (k + num_ent < blocks_done) { 3317 - k += num_ent; 3318 - continue; 3319 - } 3320 - k = blocks_done; 3321 - break; 3322 - } 3323 - 3324 - if (k != blocks_done) { 3325 - ql_log(ql_log_warn, vha, 0xf076, 3326 - "unexpected tag values tag:lba=%u:%llu)\n", 3327 - e_ref_tag, (unsigned long long)lba); 3328 - goto out; 3329 - } 3330 - 3331 - #if 0 3332 - struct sd_dif_tuple *spt; 3333 - /* TODO: 3334 - * This section came from initiator. Is it valid here? 3335 - * should ulp be override with actual val??? 3336 - */ 3337 - spt = page_address(sg_page(sg)) + sg->offset; 3338 - spt += j; 3339 - 3340 - spt->app_tag = 0xffff; 3341 - if (cmd->se_cmd.prot_type == SCSI_PROT_DIF_TYPE3) 3342 - spt->ref_tag = 0xffffffff; 3343 - #endif 3344 - } 3345 - 3346 - return 0; 3347 - } 3348 - 3349 - /* check guard */ 3350 - if (e_guard != a_guard) { 3351 - cmd->se_cmd.pi_err = TCM_LOGICAL_BLOCK_GUARD_CHECK_FAILED; 3352 - cmd->se_cmd.bad_sector = cmd->se_cmd.t_task_lba; 3353 - 3354 - ql_log(ql_log_warn, vha, 0xe076, 3355 - "Guard ERR: cdb 0x%x lba 0x%llx: [Actual|Expected] Ref Tag[0x%x|0x%x], App Tag [0x%x|0x%x], Guard [0x%x|0x%x] cmd=%p\n", 3356 - cmd->atio.u.isp24.fcp_cmnd.cdb[0], lba, 3357 - a_ref_tag, e_ref_tag, a_app_tag, e_app_tag, 3358 - a_guard, e_guard, cmd); 3359 - goto out; 3146 + cmd->dif_err_code = DIF_ERR_APP; 3147 + scsi_status = SAM_STAT_CHECK_CONDITION; 3148 + sense_key = ABORTED_COMMAND; 3149 + asc = 0x10; 3150 + ascq = 0x2; 3360 3151 } 3361 3152 3362 3153 /* check ref tag */ 3363 - if (e_ref_tag != a_ref_tag) { 3364 - cmd->se_cmd.pi_err = TCM_LOGICAL_BLOCK_REF_TAG_CHECK_FAILED; 3365 - cmd->se_cmd.bad_sector = e_ref_tag; 3154 + if (cmd->e_ref_tag != cmd->a_ref_tag) { 3155 + ql_dbg(ql_dbg_tgt_dif, vha, 0xffff, 3156 + "Ref Tag ERR: cdb[%x] lba[%llx %llx] blks[%x] [Actual|Expected] " 3157 + "Ref[%x|%x], App[%x|%x], " 3158 + "Guard[%x|%x] cmd=%p ox_id[%04x] ", 3159 + cmd->cdb[0], lba, (lba+cmd->num_blks), cmd->num_blks, 3160 + cmd->a_ref_tag, cmd->e_ref_tag, 3161 + cmd->a_app_tag, cmd->e_app_tag, 3162 + cmd->a_guard, cmd->e_guard, 3163 + cmd, cmd->atio.u.isp24.fcp_hdr.ox_id); 3366 3164 3367 - ql_log(ql_log_warn, vha, 0xe077, 3368 - "Ref Tag ERR: cdb 0x%x lba 0x%llx: [Actual|Expected] Ref Tag[0x%x|0x%x], App Tag [0x%x|0x%x], Guard [0x%x|0x%x] cmd=%p\n", 3369 - cmd->atio.u.isp24.fcp_cmnd.cdb[0], lba, 3370 - a_ref_tag, e_ref_tag, a_app_tag, e_app_tag, 3371 - a_guard, e_guard, cmd); 3165 + cmd->dif_err_code = DIF_ERR_REF; 3166 + scsi_status = SAM_STAT_CHECK_CONDITION; 3167 + sense_key = ABORTED_COMMAND; 3168 + asc = 0x10; 3169 + ascq = 0x3; 3372 3170 goto out; 3373 3171 } 3374 3172 3375 - /* check appl tag */ 3376 - if (e_app_tag != a_app_tag) { 3377 - cmd->se_cmd.pi_err = TCM_LOGICAL_BLOCK_APP_TAG_CHECK_FAILED; 3378 - cmd->se_cmd.bad_sector = cmd->se_cmd.t_task_lba; 3379 - 3380 - ql_log(ql_log_warn, vha, 0xe078, 3381 - "App Tag ERR: cdb 0x%x lba 0x%llx: [Actual|Expected] Ref Tag[0x%x|0x%x], App Tag [0x%x|0x%x], Guard [0x%x|0x%x] cmd=%p\n", 3382 - cmd->atio.u.isp24.fcp_cmnd.cdb[0], lba, 3383 - a_ref_tag, e_ref_tag, a_app_tag, e_app_tag, 3384 - a_guard, e_guard, cmd); 3385 - goto out; 3173 + /* check guard */ 3174 + if (cmd->e_guard != cmd->a_guard) { 3175 + ql_dbg(ql_dbg_tgt_dif, vha, 0xffff, 3176 + "Guard ERR: cdb[%x] lba[%llx %llx] blks[%x] [Actual|Expected] " 3177 + "Ref[%x|%x], App[%x|%x], " 3178 + "Guard [%x|%x] cmd=%p ox_id[%04x]", 3179 + cmd->cdb[0], lba, (lba+cmd->num_blks), cmd->num_blks, 3180 + cmd->a_ref_tag, cmd->e_ref_tag, 3181 + cmd->a_app_tag, cmd->e_app_tag, 3182 + cmd->a_guard, cmd->e_guard, 3183 + cmd, cmd->atio.u.isp24.fcp_hdr.ox_id); 3184 + cmd->dif_err_code = DIF_ERR_GRD; 3185 + scsi_status = SAM_STAT_CHECK_CONDITION; 3186 + sense_key = ABORTED_COMMAND; 3187 + asc = 0x10; 3188 + ascq = 0x1; 3386 3189 } 3387 3190 out: 3388 - return 1; 3389 - } 3191 + switch (cmd->state) { 3192 + case QLA_TGT_STATE_NEED_DATA: 3193 + /* handle_data will load DIF error code */ 3194 + cmd->state = QLA_TGT_STATE_DATA_IN; 3195 + vha->hw->tgt.tgt_ops->handle_data(cmd); 3196 + break; 3197 + default: 3198 + spin_lock_irqsave(&cmd->cmd_lock, flags); 3199 + if (cmd->aborted) { 3200 + spin_unlock_irqrestore(&cmd->cmd_lock, flags); 3201 + vha->hw->tgt.tgt_ops->free_cmd(cmd); 3202 + break; 3203 + } 3204 + spin_unlock_irqrestore(&cmd->cmd_lock, flags); 3390 3205 3206 + qlt_send_resp_ctio(vha, cmd, scsi_status, sense_key, asc, ascq); 3207 + /* assume scsi status gets out on the wire. 3208 + * Will not wait for completion. 3209 + */ 3210 + vha->hw->tgt.tgt_ops->free_cmd(cmd); 3211 + break; 3212 + } 3213 + } 3391 3214 3392 3215 /* If hardware_lock held on entry, might drop it, then reaquire */ 3393 3216 /* This function sends the appropriate CTIO to ISP 2xxx or 24xx */ ··· 3376 3251 ql_dbg(ql_dbg_tgt_tmr, vha, 0xe01c, 3377 3252 "Sending TERM ELS CTIO (ha=%p)\n", ha); 3378 3253 3379 - pkt = (request_t *)qla2x00_alloc_iocbs_ready(vha, NULL); 3254 + pkt = (request_t *)qla2x00_alloc_iocbs(vha, NULL); 3380 3255 if (pkt == NULL) { 3381 3256 ql_dbg(ql_dbg_tgt, vha, 0xe080, 3382 3257 "qla_target(%d): %s failed: unable to allocate " ··· 3668 3543 { 3669 3544 int term = 0; 3670 3545 3546 + if (cmd->se_cmd.prot_op) 3547 + ql_dbg(ql_dbg_tgt_dif, vha, 0xffff, 3548 + "Term DIF cmd: lba[0x%llx|%lld] len[0x%x] " 3549 + "se_cmd=%p tag[%x] op %#x/%s", 3550 + cmd->lba, cmd->lba, 3551 + cmd->num_blks, &cmd->se_cmd, 3552 + cmd->atio.u.isp24.exchange_addr, 3553 + cmd->se_cmd.prot_op, 3554 + prot_op_str(cmd->se_cmd.prot_op)); 3555 + 3671 3556 if (ctio != NULL) { 3672 3557 struct ctio7_from_24xx *c = (struct ctio7_from_24xx *)ctio; 3673 3558 term = !(c->flags & ··· 3895 3760 struct ctio_crc_from_fw *crc = 3896 3761 (struct ctio_crc_from_fw *)ctio; 3897 3762 ql_dbg(ql_dbg_tgt_mgt, vha, 0xf073, 3898 - "qla_target(%d): CTIO with DIF_ERROR status %x received (state %x, se_cmd %p) actual_dif[0x%llx] expect_dif[0x%llx]\n", 3763 + "qla_target(%d): CTIO with DIF_ERROR status %x " 3764 + "received (state %x, ulp_cmd %p) actual_dif[0x%llx] " 3765 + "expect_dif[0x%llx]\n", 3899 3766 vha->vp_idx, status, cmd->state, se_cmd, 3900 3767 *((u64 *)&crc->actual_dif[0]), 3901 3768 *((u64 *)&crc->expected_dif[0])); 3902 3769 3903 - if (qlt_handle_dif_error(vha, cmd, ctio)) { 3904 - if (cmd->state == QLA_TGT_STATE_NEED_DATA) { 3905 - /* scsi Write/xfer rdy complete */ 3906 - goto skip_term; 3907 - } else { 3908 - /* scsi read/xmit respond complete 3909 - * call handle dif to send scsi status 3910 - * rather than terminate exchange. 3911 - */ 3912 - cmd->state = QLA_TGT_STATE_PROCESSED; 3913 - ha->tgt.tgt_ops->handle_dif_err(cmd); 3914 - return; 3915 - } 3916 - } else { 3917 - /* Need to generate a SCSI good completion. 3918 - * because FW did not send scsi status. 3919 - */ 3920 - status = 0; 3921 - goto skip_term; 3922 - } 3923 - break; 3770 + qlt_handle_dif_error(vha, cmd, ctio); 3771 + return; 3924 3772 } 3925 3773 default: 3926 3774 ql_dbg(ql_dbg_tgt_mgt, vha, 0xf05b, ··· 3926 3808 return; 3927 3809 } 3928 3810 } 3929 - skip_term: 3930 3811 3931 3812 if (cmd->state == QLA_TGT_STATE_PROCESSED) { 3932 3813 cmd->trc_flags |= TRC_CTIO_DONE; ··· 4701 4584 } 4702 4585 4703 4586 if (sess != NULL) { 4704 - if (sess->fw_login_state == DSC_LS_PLOGI_PEND) { 4587 + if (sess->fw_login_state != DSC_LS_PLOGI_PEND && 4588 + sess->fw_login_state != DSC_LS_PLOGI_COMP) { 4705 4589 /* 4706 4590 * Impatient initiator sent PRLI before last 4707 4591 * PLOGI could finish. Will force him to re-try, ··· 4741 4623 4742 4624 /* Make session global (not used in fabric mode) */ 4743 4625 if (ha->current_topology != ISP_CFG_F) { 4744 - set_bit(LOOP_RESYNC_NEEDED, &vha->dpc_flags); 4745 - set_bit(LOCAL_LOOP_UPDATE, &vha->dpc_flags); 4746 - qla2xxx_wake_dpc(vha); 4626 + if (sess) { 4627 + ql_dbg(ql_dbg_disc, vha, 0xffff, 4628 + "%s %d %8phC post nack\n", 4629 + __func__, __LINE__, sess->port_name); 4630 + qla24xx_post_nack_work(vha, sess, iocb, 4631 + SRB_NACK_PRLI); 4632 + res = 0; 4633 + } else { 4634 + set_bit(LOOP_RESYNC_NEEDED, &vha->dpc_flags); 4635 + set_bit(LOCAL_LOOP_UPDATE, &vha->dpc_flags); 4636 + qla2xxx_wake_dpc(vha); 4637 + } 4747 4638 } else { 4748 4639 if (sess) { 4749 4640 ql_dbg(ql_dbg_disc, vha, 0xffff, 4750 - "%s %d %8phC post nack\n", 4751 - __func__, __LINE__, sess->port_name); 4752 - 4641 + "%s %d %8phC post nack\n", 4642 + __func__, __LINE__, sess->port_name); 4753 4643 qla24xx_post_nack_work(vha, sess, iocb, 4754 4644 SRB_NACK_PRLI); 4755 4645 res = 0; 4756 4646 } 4757 4647 } 4758 4648 break; 4759 - 4760 4649 4761 4650 case ELS_TPRLO: 4762 4651 if (le16_to_cpu(iocb->u.isp24.flags) & ··· 5204 5079 5205 5080 static int 5206 5081 qlt_chk_qfull_thresh_hold(struct scsi_qla_host *vha, 5207 - struct atio_from_isp *atio) 5082 + struct atio_from_isp *atio, bool ha_locked) 5208 5083 { 5209 5084 struct qla_hw_data *ha = vha->hw; 5210 5085 uint16_t status; 5086 + unsigned long flags; 5211 5087 5212 5088 if (ha->tgt.num_pend_cmds < Q_FULL_THRESH_HOLD(ha)) 5213 5089 return 0; 5214 5090 5091 + if (!ha_locked) 5092 + spin_lock_irqsave(&ha->hardware_lock, flags); 5215 5093 status = temp_sam_status; 5216 5094 qlt_send_busy(vha, atio, status); 5095 + if (!ha_locked) 5096 + spin_unlock_irqrestore(&ha->hardware_lock, flags); 5097 + 5217 5098 return 1; 5218 5099 } 5219 5100 ··· 5234 5103 unsigned long flags; 5235 5104 5236 5105 if (unlikely(tgt == NULL)) { 5237 - ql_dbg(ql_dbg_io, vha, 0x3064, 5106 + ql_dbg(ql_dbg_tgt, vha, 0x3064, 5238 5107 "ATIO pkt, but no tgt (ha %p)", ha); 5239 5108 return; 5240 5109 } ··· 5264 5133 5265 5134 5266 5135 if (likely(atio->u.isp24.fcp_cmnd.task_mgmt_flags == 0)) { 5267 - rc = qlt_chk_qfull_thresh_hold(vha, atio); 5136 + rc = qlt_chk_qfull_thresh_hold(vha, atio, ha_locked); 5268 5137 if (rc != 0) { 5269 5138 tgt->atio_irq_cmd_count--; 5270 5139 return; ··· 5387 5256 break; 5388 5257 } 5389 5258 5390 - rc = qlt_chk_qfull_thresh_hold(vha, atio); 5259 + rc = qlt_chk_qfull_thresh_hold(vha, atio, true); 5391 5260 if (rc != 0) { 5392 5261 tgt->irq_cmd_count--; 5393 5262 return; ··· 5662 5531 5663 5532 fcport->loop_id = loop_id; 5664 5533 5665 - rc = qla2x00_get_port_database(vha, fcport, 0); 5534 + rc = qla24xx_gpdb_wait(vha, fcport, 0); 5666 5535 if (rc != QLA_SUCCESS) { 5667 5536 ql_dbg(ql_dbg_tgt_mgt, vha, 0xf070, 5668 5537 "qla_target(%d): Failed to retrieve fcport " ··· 5844 5713 } 5845 5714 } 5846 5715 5847 - spin_lock_irqsave(&ha->hardware_lock, flags); 5848 - 5849 - if (tgt->tgt_stop) 5850 - goto out_term; 5851 - 5852 5716 rc = __qlt_24xx_handle_abts(vha, &prm->abts, sess); 5717 + ha->tgt.tgt_ops->put_sess(sess); 5718 + spin_unlock_irqrestore(&ha->tgt.sess_lock, flags2); 5719 + 5853 5720 if (rc != 0) 5854 5721 goto out_term; 5855 - spin_unlock_irqrestore(&ha->hardware_lock, flags); 5856 - if (sess) 5857 - ha->tgt.tgt_ops->put_sess(sess); 5858 - spin_unlock_irqrestore(&ha->tgt.sess_lock, flags2); 5859 5722 return; 5860 5723 5861 5724 out_term2: 5862 - spin_lock_irqsave(&ha->hardware_lock, flags); 5863 - 5864 - out_term: 5865 - qlt_24xx_send_abts_resp(vha, &prm->abts, FCP_TMF_REJECTED, false); 5866 - spin_unlock_irqrestore(&ha->hardware_lock, flags); 5867 - 5868 5725 if (sess) 5869 5726 ha->tgt.tgt_ops->put_sess(sess); 5870 5727 spin_unlock_irqrestore(&ha->tgt.sess_lock, flags2); 5728 + 5729 + out_term: 5730 + spin_lock_irqsave(&ha->hardware_lock, flags); 5731 + qlt_24xx_send_abts_resp(vha, &prm->abts, FCP_TMF_REJECTED, false); 5732 + spin_unlock_irqrestore(&ha->hardware_lock, flags); 5871 5733 } 5872 5734 5873 5735 static void qlt_tmr_work(struct qla_tgt *tgt, ··· 5880 5756 spin_lock_irqsave(&ha->tgt.sess_lock, flags); 5881 5757 5882 5758 if (tgt->tgt_stop) 5883 - goto out_term; 5759 + goto out_term2; 5884 5760 5885 5761 s_id = prm->tm_iocb2.u.isp24.fcp_hdr.s_id; 5886 5762 sess = ha->tgt.tgt_ops->find_sess_by_s_id(vha, s_id); ··· 5892 5768 5893 5769 spin_lock_irqsave(&ha->tgt.sess_lock, flags); 5894 5770 if (!sess) 5895 - goto out_term; 5771 + goto out_term2; 5896 5772 } else { 5897 5773 if (sess->deleted) { 5898 5774 sess = NULL; 5899 - goto out_term; 5775 + goto out_term2; 5900 5776 } 5901 5777 5902 5778 if (!kref_get_unless_zero(&sess->sess_kref)) { ··· 5904 5780 "%s: kref_get fail %8phC\n", 5905 5781 __func__, sess->port_name); 5906 5782 sess = NULL; 5907 - goto out_term; 5783 + goto out_term2; 5908 5784 } 5909 5785 } 5910 5786 ··· 5914 5790 unpacked_lun = scsilun_to_int((struct scsi_lun *)&lun); 5915 5791 5916 5792 rc = qlt_issue_task_mgmt(sess, unpacked_lun, fn, iocb, 0); 5793 + ha->tgt.tgt_ops->put_sess(sess); 5794 + spin_unlock_irqrestore(&ha->tgt.sess_lock, flags); 5795 + 5917 5796 if (rc != 0) 5918 5797 goto out_term; 5919 - 5920 - ha->tgt.tgt_ops->put_sess(sess); 5921 - spin_unlock_irqrestore(&ha->tgt.sess_lock, flags); 5922 5798 return; 5923 5799 5800 + out_term2: 5801 + if (sess) 5802 + ha->tgt.tgt_ops->put_sess(sess); 5803 + spin_unlock_irqrestore(&ha->tgt.sess_lock, flags); 5924 5804 out_term: 5925 5805 qlt_send_term_exchange(vha, NULL, &prm->tm_iocb2, 1, 0); 5926 - ha->tgt.tgt_ops->put_sess(sess); 5927 - spin_unlock_irqrestore(&ha->tgt.sess_lock, flags); 5928 5806 } 5929 5807 5930 5808 static void qlt_sess_work_fn(struct work_struct *work) ··· 6019 5893 tgt->datasegs_per_cmd = QLA_TGT_DATASEGS_PER_CMD_24XX; 6020 5894 tgt->datasegs_per_cont = QLA_TGT_DATASEGS_PER_CONT_24XX; 6021 5895 6022 - if (base_vha->fc_vport) 6023 - return 0; 6024 - 6025 5896 mutex_lock(&qla_tgt_mutex); 6026 5897 list_add_tail(&tgt->tgt_list_entry, &qla_tgt_glist); 6027 5898 mutex_unlock(&qla_tgt_mutex); 5899 + 5900 + if (ha->tgt.tgt_ops && ha->tgt.tgt_ops->add_target) 5901 + ha->tgt.tgt_ops->add_target(base_vha); 6028 5902 6029 5903 return 0; 6030 5904 } ··· 6052 5926 qlt_release(vha->vha_tgt.qla_tgt); 6053 5927 6054 5928 return 0; 5929 + } 5930 + 5931 + void qlt_remove_target_resources(struct qla_hw_data *ha) 5932 + { 5933 + struct scsi_qla_host *node; 5934 + u32 key = 0; 5935 + 5936 + btree_for_each_safe32(&ha->tgt.host_map, key, node) 5937 + btree_remove32(&ha->tgt.host_map, key); 5938 + 5939 + btree_destroy32(&ha->tgt.host_map); 6055 5940 } 6056 5941 6057 5942 static void qlt_lport_dump(struct scsi_qla_host *vha, u64 wwpn, ··· 6371 6234 struct atio_from_isp *pkt; 6372 6235 int cnt, i; 6373 6236 6374 - if (!vha->flags.online) 6237 + if (!ha->flags.fw_started) 6375 6238 return; 6376 6239 6377 6240 while ((ha->tgt.atio_ring_ptr->signature != ATIO_PROCESSED) || ··· 6718 6581 void 6719 6582 qlt_probe_one_stage1(struct scsi_qla_host *base_vha, struct qla_hw_data *ha) 6720 6583 { 6584 + int rc; 6585 + 6721 6586 if (!QLA_TGT_MODE_ENABLED()) 6722 6587 return; 6723 6588 ··· 6739 6600 qlt_unknown_atio_work_fn); 6740 6601 6741 6602 qlt_clear_mode(base_vha); 6603 + 6604 + rc = btree_init32(&ha->tgt.host_map); 6605 + if (rc) 6606 + ql_log(ql_log_info, base_vha, 0xffff, 6607 + "Unable to initialize ha->host_map btree\n"); 6608 + 6609 + qlt_update_vp_map(base_vha, SET_VP_IDX); 6742 6610 } 6743 6611 6744 6612 irqreturn_t ··· 6788 6642 spin_lock_irqsave(&ha->hardware_lock, flags); 6789 6643 qlt_response_pkt_all_vps(vha, (response_t *)&op->atio); 6790 6644 spin_unlock_irqrestore(&ha->hardware_lock, flags); 6645 + 6646 + kfree(op); 6791 6647 } 6792 6648 6793 6649 void ··· 6854 6706 void 6855 6707 qlt_update_vp_map(struct scsi_qla_host *vha, int cmd) 6856 6708 { 6709 + void *slot; 6710 + u32 key; 6711 + int rc; 6712 + 6857 6713 if (!QLA_TGT_MODE_ENABLED()) 6858 6714 return; 6715 + 6716 + key = vha->d_id.b24; 6859 6717 6860 6718 switch (cmd) { 6861 6719 case SET_VP_IDX: 6862 6720 vha->hw->tgt.tgt_vp_map[vha->vp_idx].vha = vha; 6863 6721 break; 6864 6722 case SET_AL_PA: 6865 - vha->hw->tgt.tgt_vp_map[vha->d_id.b.al_pa].idx = vha->vp_idx; 6723 + slot = btree_lookup32(&vha->hw->tgt.host_map, key); 6724 + if (!slot) { 6725 + ql_dbg(ql_dbg_tgt_mgt, vha, 0xffff, 6726 + "Save vha in host_map %p %06x\n", vha, key); 6727 + rc = btree_insert32(&vha->hw->tgt.host_map, 6728 + key, vha, GFP_ATOMIC); 6729 + if (rc) 6730 + ql_log(ql_log_info, vha, 0xffff, 6731 + "Unable to insert s_id into host_map: %06x\n", 6732 + key); 6733 + return; 6734 + } 6735 + ql_dbg(ql_dbg_tgt_mgt, vha, 0xffff, 6736 + "replace existing vha in host_map %p %06x\n", vha, key); 6737 + btree_update32(&vha->hw->tgt.host_map, key, vha); 6866 6738 break; 6867 6739 case RESET_VP_IDX: 6868 6740 vha->hw->tgt.tgt_vp_map[vha->vp_idx].vha = NULL; 6869 6741 break; 6870 6742 case RESET_AL_PA: 6871 - vha->hw->tgt.tgt_vp_map[vha->d_id.b.al_pa].idx = 0; 6743 + ql_dbg(ql_dbg_tgt_mgt, vha, 0xffff, 6744 + "clear vha in host_map %p %06x\n", vha, key); 6745 + slot = btree_lookup32(&vha->hw->tgt.host_map, key); 6746 + if (slot) 6747 + btree_remove32(&vha->hw->tgt.host_map, key); 6748 + vha->d_id.b24 = 0; 6872 6749 break; 6750 + } 6751 + } 6752 + 6753 + void qlt_update_host_map(struct scsi_qla_host *vha, port_id_t id) 6754 + { 6755 + unsigned long flags; 6756 + struct qla_hw_data *ha = vha->hw; 6757 + 6758 + if (!vha->d_id.b24) { 6759 + spin_lock_irqsave(&ha->vport_slock, flags); 6760 + vha->d_id = id; 6761 + qlt_update_vp_map(vha, SET_AL_PA); 6762 + spin_unlock_irqrestore(&ha->vport_slock, flags); 6763 + } else if (vha->d_id.b24 != id.b24) { 6764 + spin_lock_irqsave(&ha->vport_slock, flags); 6765 + qlt_update_vp_map(vha, RESET_AL_PA); 6766 + vha->d_id = id; 6767 + qlt_update_vp_map(vha, SET_AL_PA); 6768 + spin_unlock_irqrestore(&ha->vport_slock, flags); 6873 6769 } 6874 6770 } 6875 6771
+33 -6
drivers/scsi/qla2xxx/qla_target.h
··· 378 378 atio->u.isp24.fcp_cmnd.add_cdb_len = 0; 379 379 } 380 380 381 + static inline int get_datalen_for_atio(struct atio_from_isp *atio) 382 + { 383 + int len = atio->u.isp24.fcp_cmnd.add_cdb_len; 384 + 385 + return (be32_to_cpu(get_unaligned((uint32_t *) 386 + &atio->u.isp24.fcp_cmnd.add_cdb[len * 4]))); 387 + } 388 + 381 389 #define CTIO_TYPE7 0x12 /* Continue target I/O entry (for 24xx) */ 382 390 383 391 /* ··· 675 667 int (*handle_cmd)(struct scsi_qla_host *, struct qla_tgt_cmd *, 676 668 unsigned char *, uint32_t, int, int, int); 677 669 void (*handle_data)(struct qla_tgt_cmd *); 678 - void (*handle_dif_err)(struct qla_tgt_cmd *); 679 670 int (*handle_tmr)(struct qla_tgt_mgmt_cmd *, uint32_t, uint16_t, 680 671 uint32_t); 681 672 void (*free_cmd)(struct qla_tgt_cmd *); ··· 691 684 void (*clear_nacl_from_fcport_map)(struct fc_port *); 692 685 void (*put_sess)(struct fc_port *); 693 686 void (*shutdown_sess)(struct fc_port *); 687 + int (*get_dif_tags)(struct qla_tgt_cmd *cmd, uint16_t *pfw_prot_opts); 688 + int (*chk_dif_tags)(uint32_t tag); 689 + void (*add_target)(struct scsi_qla_host *); 694 690 }; 695 691 696 692 int qla2x00_wait_for_hba_online(struct scsi_qla_host *); ··· 730 720 #define QLA_TGT_ABORT_ALL 0xFFFE 731 721 #define QLA_TGT_NEXUS_LOSS_SESS 0xFFFD 732 722 #define QLA_TGT_NEXUS_LOSS 0xFFFC 733 - #define QLA_TGT_ABTS 0xFFFB 734 - #define QLA_TGT_2G_ABORT_TASK 0xFFFA 723 + #define QLA_TGT_ABTS 0xFFFB 724 + #define QLA_TGT_2G_ABORT_TASK 0xFFFA 735 725 736 726 /* Notify Acknowledge flags */ 737 727 #define NOTIFY_ACK_RES_COUNT BIT_8 ··· 855 845 TRC_CMD_FREE = BIT_17, 856 846 TRC_DATA_IN = BIT_18, 857 847 TRC_ABORT = BIT_19, 848 + TRC_DIF_ERR = BIT_20, 858 849 }; 859 850 860 851 struct qla_tgt_cmd { ··· 873 862 unsigned int sg_mapped:1; 874 863 unsigned int free_sg:1; 875 864 unsigned int write_data_transferred:1; 876 - unsigned int ctx_dsd_alloced:1; 877 865 unsigned int q_full:1; 878 866 unsigned int term_exchg:1; 879 867 unsigned int cmd_sent_to_fw:1; ··· 895 885 struct list_head cmd_list; 896 886 897 887 struct atio_from_isp atio; 898 - /* t10dif */ 888 + 889 + uint8_t ctx_dsd_alloced; 890 + 891 + /* T10-DIF */ 892 + #define DIF_ERR_NONE 0 893 + #define DIF_ERR_GRD 1 894 + #define DIF_ERR_REF 2 895 + #define DIF_ERR_APP 3 896 + int8_t dif_err_code; 899 897 struct scatterlist *prot_sg; 900 898 uint32_t prot_sg_cnt; 901 - uint32_t blk_sz; 899 + uint32_t blk_sz, num_blks; 900 + uint8_t scsi_status, sense_key, asc, ascq; 901 + 902 902 struct crc_context *ctx; 903 + uint8_t *cdb; 904 + uint64_t lba; 905 + uint16_t a_guard, e_guard, a_app_tag, e_app_tag; 906 + uint32_t a_ref_tag, e_ref_tag; 903 907 904 908 uint64_t jiffies_at_alloc; 905 909 uint64_t jiffies_at_free; ··· 1076 1052 extern int qlt_free_qfull_cmds(struct scsi_qla_host *); 1077 1053 extern void qlt_logo_completion_handler(fc_port_t *, int); 1078 1054 extern void qlt_do_generation_tick(struct scsi_qla_host *, int *); 1055 + 1056 + void qlt_send_resp_ctio(scsi_qla_host_t *, struct qla_tgt_cmd *, uint8_t, 1057 + uint8_t, uint8_t, uint8_t); 1079 1058 1080 1059 #endif /* __QLA_TARGET_H */
+3 -3
drivers/scsi/qla2xxx/qla_version.h
··· 7 7 /* 8 8 * Driver version 9 9 */ 10 - #define QLA2XXX_VERSION "8.07.00.38-k" 10 + #define QLA2XXX_VERSION "9.00.00.00-k" 11 11 12 - #define QLA_DRIVER_MAJOR_VER 8 13 - #define QLA_DRIVER_MINOR_VER 7 12 + #define QLA_DRIVER_MAJOR_VER 9 13 + #define QLA_DRIVER_MINOR_VER 0 14 14 #define QLA_DRIVER_PATCH_VER 0 15 15 #define QLA_DRIVER_BETA_VER 0
+33 -16
drivers/scsi/qla2xxx/tcm_qla2xxx.c
··· 531 531 return; 532 532 } 533 533 534 + switch (cmd->dif_err_code) { 535 + case DIF_ERR_GRD: 536 + cmd->se_cmd.pi_err = 537 + TCM_LOGICAL_BLOCK_GUARD_CHECK_FAILED; 538 + break; 539 + case DIF_ERR_REF: 540 + cmd->se_cmd.pi_err = 541 + TCM_LOGICAL_BLOCK_REF_TAG_CHECK_FAILED; 542 + break; 543 + case DIF_ERR_APP: 544 + cmd->se_cmd.pi_err = 545 + TCM_LOGICAL_BLOCK_APP_TAG_CHECK_FAILED; 546 + break; 547 + case DIF_ERR_NONE: 548 + default: 549 + break; 550 + } 551 + 534 552 if (cmd->se_cmd.pi_err) 535 553 transport_generic_request_failure(&cmd->se_cmd, 536 554 cmd->se_cmd.pi_err); ··· 573 555 queue_work_on(smp_processor_id(), tcm_qla2xxx_free_wq, &cmd->work); 574 556 } 575 557 576 - static void tcm_qla2xxx_handle_dif_work(struct work_struct *work) 558 + static int tcm_qla2xxx_chk_dif_tags(uint32_t tag) 577 559 { 578 - struct qla_tgt_cmd *cmd = container_of(work, struct qla_tgt_cmd, work); 579 - 580 - /* take an extra kref to prevent cmd free too early. 581 - * need to wait for SCSI status/check condition to 582 - * finish responding generate by transport_generic_request_failure. 583 - */ 584 - kref_get(&cmd->se_cmd.cmd_kref); 585 - transport_generic_request_failure(&cmd->se_cmd, cmd->se_cmd.pi_err); 560 + return 0; 586 561 } 587 562 588 - /* 589 - * Called from qla_target.c:qlt_do_ctio_completion() 590 - */ 591 - static void tcm_qla2xxx_handle_dif_err(struct qla_tgt_cmd *cmd) 563 + static int tcm_qla2xxx_dif_tags(struct qla_tgt_cmd *cmd, 564 + uint16_t *pfw_prot_opts) 592 565 { 593 - INIT_WORK(&cmd->work, tcm_qla2xxx_handle_dif_work); 594 - queue_work(tcm_qla2xxx_free_wq, &cmd->work); 566 + struct se_cmd *se_cmd = &cmd->se_cmd; 567 + 568 + if (!(se_cmd->prot_checks & TARGET_DIF_CHECK_GUARD)) 569 + *pfw_prot_opts |= PO_DISABLE_GUARD_CHECK; 570 + 571 + if (!(se_cmd->prot_checks & TARGET_DIF_CHECK_APPTAG)) 572 + *pfw_prot_opts |= PO_DIS_APP_TAG_VALD; 573 + 574 + return 0; 595 575 } 596 576 597 577 /* ··· 1626 1610 static struct qla_tgt_func_tmpl tcm_qla2xxx_template = { 1627 1611 .handle_cmd = tcm_qla2xxx_handle_cmd, 1628 1612 .handle_data = tcm_qla2xxx_handle_data, 1629 - .handle_dif_err = tcm_qla2xxx_handle_dif_err, 1630 1613 .handle_tmr = tcm_qla2xxx_handle_tmr, 1631 1614 .free_cmd = tcm_qla2xxx_free_cmd, 1632 1615 .free_mcmd = tcm_qla2xxx_free_mcmd, ··· 1637 1622 .clear_nacl_from_fcport_map = tcm_qla2xxx_clear_nacl_from_fcport_map, 1638 1623 .put_sess = tcm_qla2xxx_put_sess, 1639 1624 .shutdown_sess = tcm_qla2xxx_shutdown_sess, 1625 + .get_dif_tags = tcm_qla2xxx_dif_tags, 1626 + .chk_dif_tags = tcm_qla2xxx_chk_dif_tags, 1640 1627 }; 1641 1628 1642 1629 static int tcm_qla2xxx_init_lport(struct tcm_qla2xxx_lport *lport)
+38 -44
drivers/target/target_core_alua.c
··· 43 43 #include "target_core_ua.h" 44 44 45 45 static sense_reason_t core_alua_check_transition(int state, int valid, 46 - int *primary); 46 + int *primary, int explicit); 47 47 static int core_alua_set_tg_pt_secondary_state( 48 48 struct se_lun *lun, int explicit, int offline); 49 49 ··· 335 335 * the state is a primary or secondary target port asymmetric 336 336 * access state. 337 337 */ 338 - rc = core_alua_check_transition(alua_access_state, 339 - valid_states, &primary); 338 + rc = core_alua_check_transition(alua_access_state, valid_states, 339 + &primary, 1); 340 340 if (rc) { 341 341 /* 342 342 * If the SET TARGET PORT GROUPS attempts to establish ··· 691 691 692 692 if (dev->se_hba->hba_flags & HBA_FLAGS_INTERNAL_USE) 693 693 return 0; 694 - if (dev->transport->transport_flags & TRANSPORT_FLAG_PASSTHROUGH) 694 + if (dev->transport->transport_flags & TRANSPORT_FLAG_PASSTHROUGH_ALUA) 695 695 return 0; 696 696 697 697 /* ··· 762 762 * Check implicit and explicit ALUA state change request. 763 763 */ 764 764 static sense_reason_t 765 - core_alua_check_transition(int state, int valid, int *primary) 765 + core_alua_check_transition(int state, int valid, int *primary, int explicit) 766 766 { 767 767 /* 768 768 * OPTIMIZED, NON-OPTIMIZED, STANDBY and UNAVAILABLE are ··· 804 804 *primary = 0; 805 805 break; 806 806 case ALUA_ACCESS_STATE_TRANSITION: 807 - /* 808 - * Transitioning is set internally, and 809 - * cannot be selected manually. 810 - */ 811 - goto not_supported; 807 + if (!(valid & ALUA_T_SUP) || explicit) 808 + /* 809 + * Transitioning is set internally and by tcmu daemon, 810 + * and cannot be selected through a STPG. 811 + */ 812 + goto not_supported; 813 + *primary = 0; 814 + break; 812 815 default: 813 816 pr_err("Unknown ALUA access state: 0x%02x\n", state); 814 817 return TCM_INVALID_PARAMETER_LIST; ··· 1016 1013 static void core_alua_do_transition_tg_pt_work(struct work_struct *work) 1017 1014 { 1018 1015 struct t10_alua_tg_pt_gp *tg_pt_gp = container_of(work, 1019 - struct t10_alua_tg_pt_gp, tg_pt_gp_transition_work.work); 1016 + struct t10_alua_tg_pt_gp, tg_pt_gp_transition_work); 1020 1017 struct se_device *dev = tg_pt_gp->tg_pt_gp_dev; 1021 1018 bool explicit = (tg_pt_gp->tg_pt_gp_alua_access_status == 1022 1019 ALUA_STATUS_ALTERED_BY_EXPLICIT_STPG); ··· 1073 1070 if (atomic_read(&tg_pt_gp->tg_pt_gp_alua_access_state) == new_state) 1074 1071 return 0; 1075 1072 1076 - if (new_state == ALUA_ACCESS_STATE_TRANSITION) 1073 + if (explicit && new_state == ALUA_ACCESS_STATE_TRANSITION) 1077 1074 return -EAGAIN; 1078 1075 1079 1076 /* 1080 1077 * Flush any pending transitions 1081 1078 */ 1082 - if (!explicit && tg_pt_gp->tg_pt_gp_implicit_trans_secs && 1083 - atomic_read(&tg_pt_gp->tg_pt_gp_alua_access_state) == 1084 - ALUA_ACCESS_STATE_TRANSITION) { 1085 - /* Just in case */ 1086 - tg_pt_gp->tg_pt_gp_alua_pending_state = new_state; 1087 - tg_pt_gp->tg_pt_gp_transition_complete = &wait; 1088 - flush_delayed_work(&tg_pt_gp->tg_pt_gp_transition_work); 1089 - wait_for_completion(&wait); 1090 - tg_pt_gp->tg_pt_gp_transition_complete = NULL; 1091 - return 0; 1092 - } 1079 + if (!explicit) 1080 + flush_work(&tg_pt_gp->tg_pt_gp_transition_work); 1093 1081 1094 1082 /* 1095 1083 * Save the old primary ALUA access state, and set the current state 1096 1084 * to ALUA_ACCESS_STATE_TRANSITION. 1097 1085 */ 1098 - tg_pt_gp->tg_pt_gp_alua_previous_state = 1099 - atomic_read(&tg_pt_gp->tg_pt_gp_alua_access_state); 1100 - tg_pt_gp->tg_pt_gp_alua_pending_state = new_state; 1101 - 1102 1086 atomic_set(&tg_pt_gp->tg_pt_gp_alua_access_state, 1103 1087 ALUA_ACCESS_STATE_TRANSITION); 1104 1088 tg_pt_gp->tg_pt_gp_alua_access_status = (explicit) ? ··· 1093 1103 ALUA_STATUS_ALTERED_BY_IMPLICIT_ALUA; 1094 1104 1095 1105 core_alua_queue_state_change_ua(tg_pt_gp); 1106 + 1107 + if (new_state == ALUA_ACCESS_STATE_TRANSITION) 1108 + return 0; 1109 + 1110 + tg_pt_gp->tg_pt_gp_alua_previous_state = 1111 + atomic_read(&tg_pt_gp->tg_pt_gp_alua_access_state); 1112 + tg_pt_gp->tg_pt_gp_alua_pending_state = new_state; 1096 1113 1097 1114 /* 1098 1115 * Check for the optional ALUA primary state transition delay ··· 1114 1117 atomic_inc(&tg_pt_gp->tg_pt_gp_ref_cnt); 1115 1118 spin_unlock(&dev->t10_alua.tg_pt_gps_lock); 1116 1119 1117 - if (!explicit && tg_pt_gp->tg_pt_gp_implicit_trans_secs) { 1118 - unsigned long transition_tmo; 1119 - 1120 - transition_tmo = tg_pt_gp->tg_pt_gp_implicit_trans_secs * HZ; 1121 - queue_delayed_work(tg_pt_gp->tg_pt_gp_dev->tmr_wq, 1122 - &tg_pt_gp->tg_pt_gp_transition_work, 1123 - transition_tmo); 1124 - } else { 1120 + schedule_work(&tg_pt_gp->tg_pt_gp_transition_work); 1121 + if (explicit) { 1125 1122 tg_pt_gp->tg_pt_gp_transition_complete = &wait; 1126 - queue_delayed_work(tg_pt_gp->tg_pt_gp_dev->tmr_wq, 1127 - &tg_pt_gp->tg_pt_gp_transition_work, 0); 1128 1123 wait_for_completion(&wait); 1129 1124 tg_pt_gp->tg_pt_gp_transition_complete = NULL; 1130 1125 } ··· 1138 1149 struct t10_alua_tg_pt_gp *tg_pt_gp; 1139 1150 int primary, valid_states, rc = 0; 1140 1151 1152 + if (l_dev->transport->transport_flags & TRANSPORT_FLAG_PASSTHROUGH_ALUA) 1153 + return -ENODEV; 1154 + 1141 1155 valid_states = l_tg_pt_gp->tg_pt_gp_alua_supported_states; 1142 - if (core_alua_check_transition(new_state, valid_states, &primary) != 0) 1156 + if (core_alua_check_transition(new_state, valid_states, &primary, 1157 + explicit) != 0) 1143 1158 return -EINVAL; 1144 1159 1145 1160 local_lu_gp_mem = l_dev->dev_alua_lu_gp_mem; ··· 1688 1695 mutex_init(&tg_pt_gp->tg_pt_gp_md_mutex); 1689 1696 spin_lock_init(&tg_pt_gp->tg_pt_gp_lock); 1690 1697 atomic_set(&tg_pt_gp->tg_pt_gp_ref_cnt, 0); 1691 - INIT_DELAYED_WORK(&tg_pt_gp->tg_pt_gp_transition_work, 1692 - core_alua_do_transition_tg_pt_work); 1698 + INIT_WORK(&tg_pt_gp->tg_pt_gp_transition_work, 1699 + core_alua_do_transition_tg_pt_work); 1693 1700 tg_pt_gp->tg_pt_gp_dev = dev; 1694 1701 atomic_set(&tg_pt_gp->tg_pt_gp_alua_access_state, 1695 1702 ALUA_ACCESS_STATE_ACTIVE_OPTIMIZED); ··· 1797 1804 dev->t10_alua.alua_tg_pt_gps_counter--; 1798 1805 spin_unlock(&dev->t10_alua.tg_pt_gps_lock); 1799 1806 1800 - flush_delayed_work(&tg_pt_gp->tg_pt_gp_transition_work); 1807 + flush_work(&tg_pt_gp->tg_pt_gp_transition_work); 1801 1808 1802 1809 /* 1803 1810 * Allow a struct t10_alua_tg_pt_gp_member * referenced by ··· 1966 1973 unsigned char buf[TG_PT_GROUP_NAME_BUF]; 1967 1974 int move = 0; 1968 1975 1969 - if (dev->transport->transport_flags & TRANSPORT_FLAG_PASSTHROUGH || 1976 + if (dev->transport->transport_flags & TRANSPORT_FLAG_PASSTHROUGH_ALUA || 1970 1977 (dev->se_hba->hba_flags & HBA_FLAGS_INTERNAL_USE)) 1971 1978 return -ENODEV; 1972 1979 ··· 2223 2230 unsigned long tmp; 2224 2231 int ret; 2225 2232 2226 - if (dev->transport->transport_flags & TRANSPORT_FLAG_PASSTHROUGH || 2233 + if (dev->transport->transport_flags & TRANSPORT_FLAG_PASSTHROUGH_ALUA || 2227 2234 (dev->se_hba->hba_flags & HBA_FLAGS_INTERNAL_USE)) 2228 2235 return -ENODEV; 2229 2236 ··· 2309 2316 2310 2317 int core_setup_alua(struct se_device *dev) 2311 2318 { 2312 - if (!(dev->transport->transport_flags & TRANSPORT_FLAG_PASSTHROUGH) && 2319 + if (!(dev->transport->transport_flags & 2320 + TRANSPORT_FLAG_PASSTHROUGH_ALUA) && 2313 2321 !(dev->se_hba->hba_flags & HBA_FLAGS_INTERNAL_USE)) { 2314 2322 struct t10_alua_lu_gp_member *lu_gp_mem; 2315 2323
+4
drivers/target/target_core_configfs.c
··· 421 421 pr_err("Missing tfo->aborted_task()\n"); 422 422 return -EINVAL; 423 423 } 424 + if (!tfo->check_stop_free) { 425 + pr_err("Missing tfo->check_stop_free()\n"); 426 + return -EINVAL; 427 + } 424 428 /* 425 429 * We at least require tfo->fabric_make_wwn(), tfo->fabric_drop_wwn() 426 430 * tfo->fabric_make_tpg() and tfo->fabric_drop_tpg() in
+14 -36
drivers/target/target_core_pscsi.c
··· 154 154 155 155 buf = kzalloc(12, GFP_KERNEL); 156 156 if (!buf) 157 - return; 157 + goto out_free; 158 158 159 159 memset(cdb, 0, MAX_COMMAND_SIZE); 160 160 cdb[0] = MODE_SENSE; ··· 169 169 * If MODE_SENSE still returns zero, set the default value to 1024. 170 170 */ 171 171 sdev->sector_size = (buf[9] << 16) | (buf[10] << 8) | (buf[11]); 172 + out_free: 172 173 if (!sdev->sector_size) 173 174 sdev->sector_size = 1024; 174 - out_free: 175 + 175 176 kfree(buf); 176 177 } 177 178 ··· 315 314 sd->lun, sd->queue_depth); 316 315 } 317 316 318 - dev->dev_attrib.hw_block_size = sd->sector_size; 317 + dev->dev_attrib.hw_block_size = 318 + min_not_zero((int)sd->sector_size, 512); 319 319 dev->dev_attrib.hw_max_sectors = 320 - min_t(int, sd->host->max_sectors, queue_max_hw_sectors(q)); 320 + min_not_zero(sd->host->max_sectors, queue_max_hw_sectors(q)); 321 321 dev->dev_attrib.hw_queue_depth = sd->queue_depth; 322 322 323 323 /* ··· 341 339 /* 342 340 * For TYPE_TAPE, attempt to determine blocksize with MODE_SENSE. 343 341 */ 344 - if (sd->type == TYPE_TAPE) 342 + if (sd->type == TYPE_TAPE) { 345 343 pscsi_tape_read_blocksize(dev, sd); 344 + dev->dev_attrib.hw_block_size = sd->sector_size; 345 + } 346 346 return 0; 347 347 } 348 348 ··· 410 406 /* 411 407 * Called with struct Scsi_Host->host_lock called. 412 408 */ 413 - static int pscsi_create_type_rom(struct se_device *dev, struct scsi_device *sd) 409 + static int pscsi_create_type_nondisk(struct se_device *dev, struct scsi_device *sd) 414 410 __releases(sh->host_lock) 415 411 { 416 412 struct pscsi_hba_virt *phv = dev->se_hba->hba_ptr; ··· 434 430 phv->phv_host_id, scsi_device_type(sd->type), sh->host_no, 435 431 sd->channel, sd->id, sd->lun); 436 432 437 - return 0; 438 - } 439 - 440 - /* 441 - * Called with struct Scsi_Host->host_lock called. 442 - */ 443 - static int pscsi_create_type_other(struct se_device *dev, 444 - struct scsi_device *sd) 445 - __releases(sh->host_lock) 446 - { 447 - struct pscsi_hba_virt *phv = dev->se_hba->hba_ptr; 448 - struct Scsi_Host *sh = sd->host; 449 - int ret; 450 - 451 - spin_unlock_irq(sh->host_lock); 452 - ret = pscsi_add_device_to_list(dev, sd); 453 - if (ret) 454 - return ret; 455 - 456 - pr_debug("CORE_PSCSI[%d] - Added Type: %s for %d:%d:%d:%llu\n", 457 - phv->phv_host_id, scsi_device_type(sd->type), sh->host_no, 458 - sd->channel, sd->id, sd->lun); 459 433 return 0; 460 434 } 461 435 ··· 524 542 case TYPE_DISK: 525 543 ret = pscsi_create_type_disk(dev, sd); 526 544 break; 527 - case TYPE_ROM: 528 - ret = pscsi_create_type_rom(dev, sd); 529 - break; 530 545 default: 531 - ret = pscsi_create_type_other(dev, sd); 546 + ret = pscsi_create_type_nondisk(dev, sd); 532 547 break; 533 548 } 534 549 ··· 590 611 else if (pdv->pdv_lld_host) 591 612 scsi_host_put(pdv->pdv_lld_host); 592 613 593 - if ((sd->type == TYPE_DISK) || (sd->type == TYPE_ROM)) 594 - scsi_device_put(sd); 614 + scsi_device_put(sd); 595 615 596 616 pdv->pdv_sd = NULL; 597 617 } ··· 1042 1064 if (pdv->pdv_bd && pdv->pdv_bd->bd_part) 1043 1065 return pdv->pdv_bd->bd_part->nr_sects; 1044 1066 1045 - dump_stack(); 1046 1067 return 0; 1047 1068 } 1048 1069 ··· 1080 1103 static const struct target_backend_ops pscsi_ops = { 1081 1104 .name = "pscsi", 1082 1105 .owner = THIS_MODULE, 1083 - .transport_flags = TRANSPORT_FLAG_PASSTHROUGH, 1106 + .transport_flags = TRANSPORT_FLAG_PASSTHROUGH | 1107 + TRANSPORT_FLAG_PASSTHROUGH_ALUA, 1084 1108 .attach_hba = pscsi_attach_hba, 1085 1109 .detach_hba = pscsi_detach_hba, 1086 1110 .pmode_enable_hba = pscsi_pmode_enable_hba,
+8 -2
drivers/target/target_core_sbc.c
··· 1105 1105 return ret; 1106 1106 break; 1107 1107 case VERIFY: 1108 + case VERIFY_16: 1108 1109 size = 0; 1109 - sectors = transport_get_sectors_10(cdb); 1110 - cmd->t_task_lba = transport_lba_32(cdb); 1110 + if (cdb[0] == VERIFY) { 1111 + sectors = transport_get_sectors_10(cdb); 1112 + cmd->t_task_lba = transport_lba_32(cdb); 1113 + } else { 1114 + sectors = transport_get_sectors_16(cdb); 1115 + cmd->t_task_lba = transport_lba_64(cdb); 1116 + } 1111 1117 cmd->execute_cmd = sbc_emulate_noop; 1112 1118 goto check_lba; 1113 1119 case REZERO_UNIT:
+2 -1
drivers/target/target_core_tpg.c
··· 602 602 if (ret) 603 603 goto out_kill_ref; 604 604 605 - if (!(dev->transport->transport_flags & TRANSPORT_FLAG_PASSTHROUGH) && 605 + if (!(dev->transport->transport_flags & 606 + TRANSPORT_FLAG_PASSTHROUGH_ALUA) && 606 607 !(dev->se_hba->hba_flags & HBA_FLAGS_INTERNAL_USE)) 607 608 target_attach_tg_pt_gp(lun, dev->t10_alua.default_tg_pt_gp); 608 609
+1 -2
drivers/target/target_core_transport.c
··· 636 636 * Fabric modules are expected to return '1' here if the se_cmd being 637 637 * passed is released at this point, or zero if not being released. 638 638 */ 639 - return cmd->se_tfo->check_stop_free ? cmd->se_tfo->check_stop_free(cmd) 640 - : 0; 639 + return cmd->se_tfo->check_stop_free(cmd); 641 640 } 642 641 643 642 static void transport_lun_remove_cmd(struct se_cmd *cmd)
+123 -29
drivers/target/target_core_user.c
··· 28 28 #include <linux/stringify.h> 29 29 #include <linux/bitops.h> 30 30 #include <linux/highmem.h> 31 + #include <linux/configfs.h> 31 32 #include <net/genetlink.h> 32 33 #include <scsi/scsi_common.h> 33 34 #include <scsi/scsi_proto.h> ··· 113 112 spinlock_t commands_lock; 114 113 115 114 struct timer_list timeout; 115 + unsigned int cmd_time_out; 116 116 117 117 char dev_config[TCMU_CONFIG_LEN]; 118 118 }; ··· 174 172 175 173 tcmu_cmd->se_cmd = se_cmd; 176 174 tcmu_cmd->tcmu_dev = udev; 177 - tcmu_cmd->deadline = jiffies + msecs_to_jiffies(TCMU_TIME_OUT); 175 + if (udev->cmd_time_out) 176 + tcmu_cmd->deadline = jiffies + 177 + msecs_to_jiffies(udev->cmd_time_out); 178 178 179 179 idr_preload(GFP_KERNEL); 180 180 spin_lock_irq(&udev->commands_lock); ··· 455 451 456 452 pr_debug("sleeping for ring space\n"); 457 453 spin_unlock_irq(&udev->cmdr_lock); 458 - ret = schedule_timeout(msecs_to_jiffies(TCMU_TIME_OUT)); 454 + if (udev->cmd_time_out) 455 + ret = schedule_timeout( 456 + msecs_to_jiffies(udev->cmd_time_out)); 457 + else 458 + ret = schedule_timeout(msecs_to_jiffies(TCMU_TIME_OUT)); 459 459 finish_wait(&udev->wait_cmdr, &__wait); 460 460 if (!ret) { 461 461 pr_warn("tcmu: command timed out\n"); ··· 534 526 /* TODO: only if FLUSH and FUA? */ 535 527 uio_event_notify(&udev->uio_info); 536 528 537 - mod_timer(&udev->timeout, 538 - round_jiffies_up(jiffies + msecs_to_jiffies(TCMU_TIME_OUT))); 529 + if (udev->cmd_time_out) 530 + mod_timer(&udev->timeout, round_jiffies_up(jiffies + 531 + msecs_to_jiffies(udev->cmd_time_out))); 539 532 540 533 return TCM_NO_SENSE; 541 534 } ··· 751 742 } 752 743 753 744 udev->hba = hba; 745 + udev->cmd_time_out = TCMU_TIME_OUT; 754 746 755 747 init_waitqueue_head(&udev->wait_cmdr); 756 748 spin_lock_init(&udev->cmdr_lock); ··· 970 960 if (dev->dev_attrib.hw_block_size == 0) 971 961 dev->dev_attrib.hw_block_size = 512; 972 962 /* Other attributes can be configured in userspace */ 973 - dev->dev_attrib.hw_max_sectors = 128; 963 + if (!dev->dev_attrib.hw_max_sectors) 964 + dev->dev_attrib.hw_max_sectors = 128; 974 965 dev->dev_attrib.hw_queue_depth = 128; 975 966 976 967 ret = tcmu_netlink_event(TCMU_CMD_ADDED_DEVICE, udev->uio_info.name, ··· 1008 997 kfree(udev); 1009 998 } 1010 999 1000 + static bool tcmu_dev_configured(struct tcmu_dev *udev) 1001 + { 1002 + return udev->uio_info.uio_dev ? true : false; 1003 + } 1004 + 1011 1005 static void tcmu_free_device(struct se_device *dev) 1012 1006 { 1013 1007 struct tcmu_dev *udev = TCMU_DEV(dev); ··· 1034 1018 spin_unlock_irq(&udev->commands_lock); 1035 1019 WARN_ON(!all_expired); 1036 1020 1037 - /* Device was configured */ 1038 - if (udev->uio_info.uio_dev) { 1021 + if (tcmu_dev_configured(udev)) { 1039 1022 tcmu_netlink_event(TCMU_CMD_REMOVED_DEVICE, udev->uio_info.name, 1040 1023 udev->uio_info.uio_dev->minor); 1041 1024 ··· 1046 1031 } 1047 1032 1048 1033 enum { 1049 - Opt_dev_config, Opt_dev_size, Opt_hw_block_size, Opt_err, 1034 + Opt_dev_config, Opt_dev_size, Opt_hw_block_size, Opt_hw_max_sectors, 1035 + Opt_err, 1050 1036 }; 1051 1037 1052 1038 static match_table_t tokens = { 1053 1039 {Opt_dev_config, "dev_config=%s"}, 1054 1040 {Opt_dev_size, "dev_size=%u"}, 1055 1041 {Opt_hw_block_size, "hw_block_size=%u"}, 1042 + {Opt_hw_max_sectors, "hw_max_sectors=%u"}, 1056 1043 {Opt_err, NULL} 1057 1044 }; 1045 + 1046 + static int tcmu_set_dev_attrib(substring_t *arg, u32 *dev_attrib) 1047 + { 1048 + unsigned long tmp_ul; 1049 + char *arg_p; 1050 + int ret; 1051 + 1052 + arg_p = match_strdup(arg); 1053 + if (!arg_p) 1054 + return -ENOMEM; 1055 + 1056 + ret = kstrtoul(arg_p, 0, &tmp_ul); 1057 + kfree(arg_p); 1058 + if (ret < 0) { 1059 + pr_err("kstrtoul() failed for dev attrib\n"); 1060 + return ret; 1061 + } 1062 + if (!tmp_ul) { 1063 + pr_err("dev attrib must be nonzero\n"); 1064 + return -EINVAL; 1065 + } 1066 + *dev_attrib = tmp_ul; 1067 + return 0; 1068 + } 1058 1069 1059 1070 static ssize_t tcmu_set_configfs_dev_params(struct se_device *dev, 1060 1071 const char *page, ssize_t count) ··· 1089 1048 char *orig, *ptr, *opts, *arg_p; 1090 1049 substring_t args[MAX_OPT_ARGS]; 1091 1050 int ret = 0, token; 1092 - unsigned long tmp_ul; 1093 1051 1094 1052 opts = kstrdup(page, GFP_KERNEL); 1095 1053 if (!opts) ··· 1122 1082 pr_err("kstrtoul() failed for dev_size=\n"); 1123 1083 break; 1124 1084 case Opt_hw_block_size: 1125 - arg_p = match_strdup(&args[0]); 1126 - if (!arg_p) { 1127 - ret = -ENOMEM; 1128 - break; 1129 - } 1130 - ret = kstrtoul(arg_p, 0, &tmp_ul); 1131 - kfree(arg_p); 1132 - if (ret < 0) { 1133 - pr_err("kstrtoul() failed for hw_block_size=\n"); 1134 - break; 1135 - } 1136 - if (!tmp_ul) { 1137 - pr_err("hw_block_size must be nonzero\n"); 1138 - break; 1139 - } 1140 - dev->dev_attrib.hw_block_size = tmp_ul; 1085 + ret = tcmu_set_dev_attrib(&args[0], 1086 + &(dev->dev_attrib.hw_block_size)); 1087 + break; 1088 + case Opt_hw_max_sectors: 1089 + ret = tcmu_set_dev_attrib(&args[0], 1090 + &(dev->dev_attrib.hw_max_sectors)); 1141 1091 break; 1142 1092 default: 1143 1093 break; 1144 1094 } 1095 + 1096 + if (ret) 1097 + break; 1145 1098 } 1146 1099 1147 1100 kfree(orig); ··· 1167 1134 return passthrough_parse_cdb(cmd, tcmu_queue_cmd); 1168 1135 } 1169 1136 1170 - static const struct target_backend_ops tcmu_ops = { 1137 + static ssize_t tcmu_cmd_time_out_show(struct config_item *item, char *page) 1138 + { 1139 + struct se_dev_attrib *da = container_of(to_config_group(item), 1140 + struct se_dev_attrib, da_group); 1141 + struct tcmu_dev *udev = container_of(da->da_dev, 1142 + struct tcmu_dev, se_dev); 1143 + 1144 + return snprintf(page, PAGE_SIZE, "%lu\n", udev->cmd_time_out / MSEC_PER_SEC); 1145 + } 1146 + 1147 + static ssize_t tcmu_cmd_time_out_store(struct config_item *item, const char *page, 1148 + size_t count) 1149 + { 1150 + struct se_dev_attrib *da = container_of(to_config_group(item), 1151 + struct se_dev_attrib, da_group); 1152 + struct tcmu_dev *udev = container_of(da->da_dev, 1153 + struct tcmu_dev, se_dev); 1154 + u32 val; 1155 + int ret; 1156 + 1157 + if (da->da_dev->export_count) { 1158 + pr_err("Unable to set tcmu cmd_time_out while exports exist\n"); 1159 + return -EINVAL; 1160 + } 1161 + 1162 + ret = kstrtou32(page, 0, &val); 1163 + if (ret < 0) 1164 + return ret; 1165 + 1166 + if (!val) { 1167 + pr_err("Illegal value for cmd_time_out\n"); 1168 + return -EINVAL; 1169 + } 1170 + 1171 + udev->cmd_time_out = val * MSEC_PER_SEC; 1172 + return count; 1173 + } 1174 + CONFIGFS_ATTR(tcmu_, cmd_time_out); 1175 + 1176 + static struct configfs_attribute **tcmu_attrs; 1177 + 1178 + static struct target_backend_ops tcmu_ops = { 1171 1179 .name = "user", 1172 1180 .owner = THIS_MODULE, 1173 1181 .transport_flags = TRANSPORT_FLAG_PASSTHROUGH, ··· 1222 1148 .show_configfs_dev_params = tcmu_show_configfs_dev_params, 1223 1149 .get_device_type = sbc_get_device_type, 1224 1150 .get_blocks = tcmu_get_blocks, 1225 - .tb_dev_attrib_attrs = passthrough_attrib_attrs, 1151 + .tb_dev_attrib_attrs = NULL, 1226 1152 }; 1227 1153 1228 1154 static int __init tcmu_module_init(void) 1229 1155 { 1230 - int ret; 1156 + int ret, i, len = 0; 1231 1157 1232 1158 BUILD_BUG_ON((sizeof(struct tcmu_cmd_entry) % TCMU_OP_ALIGN_SIZE) != 0); 1233 1159 ··· 1249 1175 goto out_unreg_device; 1250 1176 } 1251 1177 1178 + for (i = 0; passthrough_attrib_attrs[i] != NULL; i++) { 1179 + len += sizeof(struct configfs_attribute *); 1180 + } 1181 + len += sizeof(struct configfs_attribute *) * 2; 1182 + 1183 + tcmu_attrs = kzalloc(len, GFP_KERNEL); 1184 + if (!tcmu_attrs) { 1185 + ret = -ENOMEM; 1186 + goto out_unreg_genl; 1187 + } 1188 + 1189 + for (i = 0; passthrough_attrib_attrs[i] != NULL; i++) { 1190 + tcmu_attrs[i] = passthrough_attrib_attrs[i]; 1191 + } 1192 + tcmu_attrs[i] = &tcmu_attr_cmd_time_out; 1193 + tcmu_ops.tb_dev_attrib_attrs = tcmu_attrs; 1194 + 1252 1195 ret = transport_backend_register(&tcmu_ops); 1253 1196 if (ret) 1254 - goto out_unreg_genl; 1197 + goto out_attrs; 1255 1198 1256 1199 return 0; 1257 1200 1201 + out_attrs: 1202 + kfree(tcmu_attrs); 1258 1203 out_unreg_genl: 1259 1204 genl_unregister_family(&tcmu_genl_family); 1260 1205 out_unreg_device: ··· 1287 1194 static void __exit tcmu_module_exit(void) 1288 1195 { 1289 1196 target_backend_unregister(&tcmu_ops); 1197 + kfree(tcmu_attrs); 1290 1198 genl_unregister_family(&tcmu_genl_family); 1291 1199 root_device_unregister(tcmu_root_device); 1292 1200 kmem_cache_destroy(tcmu_cmd_cache);
+6 -1
include/target/target_core_backend.h
··· 4 4 #include <linux/types.h> 5 5 #include <target/target_core_base.h> 6 6 7 - #define TRANSPORT_FLAG_PASSTHROUGH 1 7 + #define TRANSPORT_FLAG_PASSTHROUGH 0x1 8 + /* 9 + * ALUA commands, state checks and setup operations are handled by the 10 + * backend module. 11 + */ 12 + #define TRANSPORT_FLAG_PASSTHROUGH_ALUA 0x2 8 13 9 14 struct request_queue; 10 15 struct scatterlist;
+1 -1
include/target/target_core_base.h
··· 299 299 struct list_head tg_pt_gp_lun_list; 300 300 struct se_lun *tg_pt_gp_alua_lun; 301 301 struct se_node_acl *tg_pt_gp_alua_nacl; 302 - struct delayed_work tg_pt_gp_transition_work; 302 + struct work_struct tg_pt_gp_transition_work; 303 303 struct completion *tg_pt_gp_transition_complete; 304 304 }; 305 305