diff options
| -rw-r--r-- | drivers/scsi/hosts.c | 3 | ||||
| -rw-r--r-- | drivers/scsi/megaraid/megaraid_sas_fusion.c | 42 | ||||
| -rw-r--r-- | drivers/scsi/mpt3sas/mpt3sas_base.c | 8 | ||||
| -rw-r--r-- | drivers/scsi/mpt3sas/mpt3sas_base.h | 3 | ||||
| -rw-r--r-- | drivers/scsi/mpt3sas/mpt3sas_scsih.c | 21 | ||||
| -rw-r--r-- | drivers/scsi/qedi/qedi_fw.c | 5 | ||||
| -rw-r--r-- | drivers/scsi/qla2xxx/qla_def.h | 5 | ||||
| -rw-r--r-- | drivers/scsi/qla2xxx/qla_gs.c | 5 | ||||
| -rw-r--r-- | drivers/scsi/qla2xxx/qla_init.c | 51 | ||||
| -rw-r--r-- | drivers/scsi/qla2xxx/qla_os.c | 14 | ||||
| -rw-r--r-- | drivers/scsi/qla2xxx/qla_target.c | 17 | ||||
| -rw-r--r-- | drivers/scsi/scsi_error.c | 5 | ||||
| -rw-r--r-- | drivers/scsi/scsi_lib.c | 4 | ||||
| -rw-r--r-- | drivers/scsi/storvsc_drv.c | 3 | ||||
| -rw-r--r-- | include/scsi/scsi_cmnd.h | 3 | ||||
| -rw-r--r-- | include/scsi/scsi_host.h | 2 |
16 files changed, 115 insertions, 76 deletions
diff --git a/drivers/scsi/hosts.c b/drivers/scsi/hosts.c index 57bf43e34863..dd9464920456 100644 --- a/drivers/scsi/hosts.c +++ b/drivers/scsi/hosts.c | |||
| @@ -328,8 +328,6 @@ static void scsi_host_dev_release(struct device *dev) | |||
| 328 | if (shost->work_q) | 328 | if (shost->work_q) |
| 329 | destroy_workqueue(shost->work_q); | 329 | destroy_workqueue(shost->work_q); |
| 330 | 330 | ||
| 331 | destroy_rcu_head(&shost->rcu); | ||
| 332 | |||
| 333 | if (shost->shost_state == SHOST_CREATED) { | 331 | if (shost->shost_state == SHOST_CREATED) { |
| 334 | /* | 332 | /* |
| 335 | * Free the shost_dev device name here if scsi_host_alloc() | 333 | * Free the shost_dev device name here if scsi_host_alloc() |
| @@ -404,7 +402,6 @@ struct Scsi_Host *scsi_host_alloc(struct scsi_host_template *sht, int privsize) | |||
| 404 | INIT_LIST_HEAD(&shost->starved_list); | 402 | INIT_LIST_HEAD(&shost->starved_list); |
| 405 | init_waitqueue_head(&shost->host_wait); | 403 | init_waitqueue_head(&shost->host_wait); |
| 406 | mutex_init(&shost->scan_mutex); | 404 | mutex_init(&shost->scan_mutex); |
| 407 | init_rcu_head(&shost->rcu); | ||
| 408 | 405 | ||
| 409 | index = ida_simple_get(&host_index_ida, 0, 0, GFP_KERNEL); | 406 | index = ida_simple_get(&host_index_ida, 0, 0, GFP_KERNEL); |
| 410 | if (index < 0) | 407 | if (index < 0) |
diff --git a/drivers/scsi/megaraid/megaraid_sas_fusion.c b/drivers/scsi/megaraid/megaraid_sas_fusion.c index 073ced07e662..dc8e850fbfd2 100644 --- a/drivers/scsi/megaraid/megaraid_sas_fusion.c +++ b/drivers/scsi/megaraid/megaraid_sas_fusion.c | |||
| @@ -216,36 +216,30 @@ inline void megasas_return_cmd_fusion(struct megasas_instance *instance, | |||
| 216 | /** | 216 | /** |
| 217 | * megasas_fire_cmd_fusion - Sends command to the FW | 217 | * megasas_fire_cmd_fusion - Sends command to the FW |
| 218 | * @instance: Adapter soft state | 218 | * @instance: Adapter soft state |
| 219 | * @req_desc: 32bit or 64bit Request descriptor | 219 | * @req_desc: 64bit Request descriptor |
| 220 | * | 220 | * |
| 221 | * Perform PCI Write. Ventura supports 32 bit Descriptor. | 221 | * Perform PCI Write. |
| 222 | * Prior to Ventura (12G) MR controller supports 64 bit Descriptor. | ||
| 223 | */ | 222 | */ |
| 224 | 223 | ||
| 225 | static void | 224 | static void |
| 226 | megasas_fire_cmd_fusion(struct megasas_instance *instance, | 225 | megasas_fire_cmd_fusion(struct megasas_instance *instance, |
| 227 | union MEGASAS_REQUEST_DESCRIPTOR_UNION *req_desc) | 226 | union MEGASAS_REQUEST_DESCRIPTOR_UNION *req_desc) |
| 228 | { | 227 | { |
| 229 | if (instance->adapter_type == VENTURA_SERIES) | ||
| 230 | writel(le32_to_cpu(req_desc->u.low), | ||
| 231 | &instance->reg_set->inbound_single_queue_port); | ||
| 232 | else { | ||
| 233 | #if defined(writeq) && defined(CONFIG_64BIT) | 228 | #if defined(writeq) && defined(CONFIG_64BIT) |
| 234 | u64 req_data = (((u64)le32_to_cpu(req_desc->u.high) << 32) | | 229 | u64 req_data = (((u64)le32_to_cpu(req_desc->u.high) << 32) | |
| 235 | le32_to_cpu(req_desc->u.low)); | 230 | le32_to_cpu(req_desc->u.low)); |
| 236 | 231 | ||
| 237 | writeq(req_data, &instance->reg_set->inbound_low_queue_port); | 232 | writeq(req_data, &instance->reg_set->inbound_low_queue_port); |
| 238 | #else | 233 | #else |
| 239 | unsigned long flags; | 234 | unsigned long flags; |
| 240 | spin_lock_irqsave(&instance->hba_lock, flags); | 235 | spin_lock_irqsave(&instance->hba_lock, flags); |
| 241 | writel(le32_to_cpu(req_desc->u.low), | 236 | writel(le32_to_cpu(req_desc->u.low), |
| 242 | &instance->reg_set->inbound_low_queue_port); | 237 | &instance->reg_set->inbound_low_queue_port); |
| 243 | writel(le32_to_cpu(req_desc->u.high), | 238 | writel(le32_to_cpu(req_desc->u.high), |
| 244 | &instance->reg_set->inbound_high_queue_port); | 239 | &instance->reg_set->inbound_high_queue_port); |
| 245 | mmiowb(); | 240 | mmiowb(); |
| 246 | spin_unlock_irqrestore(&instance->hba_lock, flags); | 241 | spin_unlock_irqrestore(&instance->hba_lock, flags); |
| 247 | #endif | 242 | #endif |
| 248 | } | ||
| 249 | } | 243 | } |
| 250 | 244 | ||
| 251 | /** | 245 | /** |
| @@ -982,7 +976,6 @@ megasas_ioc_init_fusion(struct megasas_instance *instance) | |||
| 982 | const char *sys_info; | 976 | const char *sys_info; |
| 983 | MFI_CAPABILITIES *drv_ops; | 977 | MFI_CAPABILITIES *drv_ops; |
| 984 | u32 scratch_pad_2; | 978 | u32 scratch_pad_2; |
| 985 | unsigned long flags; | ||
| 986 | ktime_t time; | 979 | ktime_t time; |
| 987 | bool cur_fw_64bit_dma_capable; | 980 | bool cur_fw_64bit_dma_capable; |
| 988 | 981 | ||
| @@ -1121,14 +1114,7 @@ megasas_ioc_init_fusion(struct megasas_instance *instance) | |||
| 1121 | break; | 1114 | break; |
| 1122 | } | 1115 | } |
| 1123 | 1116 | ||
| 1124 | /* For Ventura also IOC INIT required 64 bit Descriptor write. */ | 1117 | megasas_fire_cmd_fusion(instance, &req_desc); |
| 1125 | spin_lock_irqsave(&instance->hba_lock, flags); | ||
| 1126 | writel(le32_to_cpu(req_desc.u.low), | ||
| 1127 | &instance->reg_set->inbound_low_queue_port); | ||
| 1128 | writel(le32_to_cpu(req_desc.u.high), | ||
| 1129 | &instance->reg_set->inbound_high_queue_port); | ||
| 1130 | mmiowb(); | ||
| 1131 | spin_unlock_irqrestore(&instance->hba_lock, flags); | ||
| 1132 | 1118 | ||
| 1133 | wait_and_poll(instance, cmd, MFI_POLL_TIMEOUT_SECS); | 1119 | wait_and_poll(instance, cmd, MFI_POLL_TIMEOUT_SECS); |
| 1134 | 1120 | ||
diff --git a/drivers/scsi/mpt3sas/mpt3sas_base.c b/drivers/scsi/mpt3sas/mpt3sas_base.c index 59a87ca328d3..0aafbfd1b746 100644 --- a/drivers/scsi/mpt3sas/mpt3sas_base.c +++ b/drivers/scsi/mpt3sas/mpt3sas_base.c | |||
| @@ -6297,14 +6297,14 @@ _base_reset_handler(struct MPT3SAS_ADAPTER *ioc, int reset_phase) | |||
| 6297 | } | 6297 | } |
| 6298 | 6298 | ||
| 6299 | /** | 6299 | /** |
| 6300 | * _wait_for_commands_to_complete - reset controller | 6300 | * mpt3sas_wait_for_commands_to_complete - reset controller |
| 6301 | * @ioc: Pointer to MPT_ADAPTER structure | 6301 | * @ioc: Pointer to MPT_ADAPTER structure |
| 6302 | * | 6302 | * |
| 6303 | * This function is waiting 10s for all pending commands to complete | 6303 | * This function is waiting 10s for all pending commands to complete |
| 6304 | * prior to putting controller in reset. | 6304 | * prior to putting controller in reset. |
| 6305 | */ | 6305 | */ |
| 6306 | static void | 6306 | void |
| 6307 | _wait_for_commands_to_complete(struct MPT3SAS_ADAPTER *ioc) | 6307 | mpt3sas_wait_for_commands_to_complete(struct MPT3SAS_ADAPTER *ioc) |
| 6308 | { | 6308 | { |
| 6309 | u32 ioc_state; | 6309 | u32 ioc_state; |
| 6310 | 6310 | ||
| @@ -6377,7 +6377,7 @@ mpt3sas_base_hard_reset_handler(struct MPT3SAS_ADAPTER *ioc, | |||
| 6377 | is_fault = 1; | 6377 | is_fault = 1; |
| 6378 | } | 6378 | } |
| 6379 | _base_reset_handler(ioc, MPT3_IOC_PRE_RESET); | 6379 | _base_reset_handler(ioc, MPT3_IOC_PRE_RESET); |
| 6380 | _wait_for_commands_to_complete(ioc); | 6380 | mpt3sas_wait_for_commands_to_complete(ioc); |
| 6381 | _base_mask_interrupts(ioc); | 6381 | _base_mask_interrupts(ioc); |
| 6382 | r = _base_make_ioc_ready(ioc, type); | 6382 | r = _base_make_ioc_ready(ioc, type); |
| 6383 | if (r) | 6383 | if (r) |
diff --git a/drivers/scsi/mpt3sas/mpt3sas_base.h b/drivers/scsi/mpt3sas/mpt3sas_base.h index 789bc421424b..99ccf83b8c51 100644 --- a/drivers/scsi/mpt3sas/mpt3sas_base.h +++ b/drivers/scsi/mpt3sas/mpt3sas_base.h | |||
| @@ -1433,6 +1433,9 @@ void mpt3sas_base_update_missing_delay(struct MPT3SAS_ADAPTER *ioc, | |||
| 1433 | 1433 | ||
| 1434 | int mpt3sas_port_enable(struct MPT3SAS_ADAPTER *ioc); | 1434 | int mpt3sas_port_enable(struct MPT3SAS_ADAPTER *ioc); |
| 1435 | 1435 | ||
| 1436 | void | ||
| 1437 | mpt3sas_wait_for_commands_to_complete(struct MPT3SAS_ADAPTER *ioc); | ||
| 1438 | |||
| 1436 | 1439 | ||
| 1437 | /* scsih shared API */ | 1440 | /* scsih shared API */ |
| 1438 | struct scsi_cmnd *mpt3sas_scsih_scsi_lookup_get(struct MPT3SAS_ADAPTER *ioc, | 1441 | struct scsi_cmnd *mpt3sas_scsih_scsi_lookup_get(struct MPT3SAS_ADAPTER *ioc, |
diff --git a/drivers/scsi/mpt3sas/mpt3sas_scsih.c b/drivers/scsi/mpt3sas/mpt3sas_scsih.c index 74fca184dba9..c2ea13c7e37e 100644 --- a/drivers/scsi/mpt3sas/mpt3sas_scsih.c +++ b/drivers/scsi/mpt3sas/mpt3sas_scsih.c | |||
| @@ -2835,7 +2835,8 @@ scsih_abort(struct scsi_cmnd *scmd) | |||
| 2835 | _scsih_tm_display_info(ioc, scmd); | 2835 | _scsih_tm_display_info(ioc, scmd); |
| 2836 | 2836 | ||
| 2837 | sas_device_priv_data = scmd->device->hostdata; | 2837 | sas_device_priv_data = scmd->device->hostdata; |
| 2838 | if (!sas_device_priv_data || !sas_device_priv_data->sas_target) { | 2838 | if (!sas_device_priv_data || !sas_device_priv_data->sas_target || |
| 2839 | ioc->remove_host) { | ||
| 2839 | sdev_printk(KERN_INFO, scmd->device, | 2840 | sdev_printk(KERN_INFO, scmd->device, |
| 2840 | "device been deleted! scmd(%p)\n", scmd); | 2841 | "device been deleted! scmd(%p)\n", scmd); |
| 2841 | scmd->result = DID_NO_CONNECT << 16; | 2842 | scmd->result = DID_NO_CONNECT << 16; |
| @@ -2898,7 +2899,8 @@ scsih_dev_reset(struct scsi_cmnd *scmd) | |||
| 2898 | _scsih_tm_display_info(ioc, scmd); | 2899 | _scsih_tm_display_info(ioc, scmd); |
| 2899 | 2900 | ||
| 2900 | sas_device_priv_data = scmd->device->hostdata; | 2901 | sas_device_priv_data = scmd->device->hostdata; |
| 2901 | if (!sas_device_priv_data || !sas_device_priv_data->sas_target) { | 2902 | if (!sas_device_priv_data || !sas_device_priv_data->sas_target || |
| 2903 | ioc->remove_host) { | ||
| 2902 | sdev_printk(KERN_INFO, scmd->device, | 2904 | sdev_printk(KERN_INFO, scmd->device, |
| 2903 | "device been deleted! scmd(%p)\n", scmd); | 2905 | "device been deleted! scmd(%p)\n", scmd); |
| 2904 | scmd->result = DID_NO_CONNECT << 16; | 2906 | scmd->result = DID_NO_CONNECT << 16; |
| @@ -2961,7 +2963,8 @@ scsih_target_reset(struct scsi_cmnd *scmd) | |||
| 2961 | _scsih_tm_display_info(ioc, scmd); | 2963 | _scsih_tm_display_info(ioc, scmd); |
| 2962 | 2964 | ||
| 2963 | sas_device_priv_data = scmd->device->hostdata; | 2965 | sas_device_priv_data = scmd->device->hostdata; |
| 2964 | if (!sas_device_priv_data || !sas_device_priv_data->sas_target) { | 2966 | if (!sas_device_priv_data || !sas_device_priv_data->sas_target || |
| 2967 | ioc->remove_host) { | ||
| 2965 | starget_printk(KERN_INFO, starget, "target been deleted! scmd(%p)\n", | 2968 | starget_printk(KERN_INFO, starget, "target been deleted! scmd(%p)\n", |
| 2966 | scmd); | 2969 | scmd); |
| 2967 | scmd->result = DID_NO_CONNECT << 16; | 2970 | scmd->result = DID_NO_CONNECT << 16; |
| @@ -3019,7 +3022,7 @@ scsih_host_reset(struct scsi_cmnd *scmd) | |||
| 3019 | ioc->name, scmd); | 3022 | ioc->name, scmd); |
| 3020 | scsi_print_command(scmd); | 3023 | scsi_print_command(scmd); |
| 3021 | 3024 | ||
| 3022 | if (ioc->is_driver_loading) { | 3025 | if (ioc->is_driver_loading || ioc->remove_host) { |
| 3023 | pr_info(MPT3SAS_FMT "Blocking the host reset\n", | 3026 | pr_info(MPT3SAS_FMT "Blocking the host reset\n", |
| 3024 | ioc->name); | 3027 | ioc->name); |
| 3025 | r = FAILED; | 3028 | r = FAILED; |
| @@ -4453,7 +4456,7 @@ _scsih_flush_running_cmds(struct MPT3SAS_ADAPTER *ioc) | |||
| 4453 | st = scsi_cmd_priv(scmd); | 4456 | st = scsi_cmd_priv(scmd); |
| 4454 | mpt3sas_base_clear_st(ioc, st); | 4457 | mpt3sas_base_clear_st(ioc, st); |
| 4455 | scsi_dma_unmap(scmd); | 4458 | scsi_dma_unmap(scmd); |
| 4456 | if (ioc->pci_error_recovery) | 4459 | if (ioc->pci_error_recovery || ioc->remove_host) |
| 4457 | scmd->result = DID_NO_CONNECT << 16; | 4460 | scmd->result = DID_NO_CONNECT << 16; |
| 4458 | else | 4461 | else |
| 4459 | scmd->result = DID_RESET << 16; | 4462 | scmd->result = DID_RESET << 16; |
| @@ -9739,6 +9742,10 @@ static void scsih_remove(struct pci_dev *pdev) | |||
| 9739 | unsigned long flags; | 9742 | unsigned long flags; |
| 9740 | 9743 | ||
| 9741 | ioc->remove_host = 1; | 9744 | ioc->remove_host = 1; |
| 9745 | |||
| 9746 | mpt3sas_wait_for_commands_to_complete(ioc); | ||
| 9747 | _scsih_flush_running_cmds(ioc); | ||
| 9748 | |||
| 9742 | _scsih_fw_event_cleanup_queue(ioc); | 9749 | _scsih_fw_event_cleanup_queue(ioc); |
| 9743 | 9750 | ||
| 9744 | spin_lock_irqsave(&ioc->fw_event_lock, flags); | 9751 | spin_lock_irqsave(&ioc->fw_event_lock, flags); |
| @@ -9815,6 +9822,10 @@ scsih_shutdown(struct pci_dev *pdev) | |||
| 9815 | unsigned long flags; | 9822 | unsigned long flags; |
| 9816 | 9823 | ||
| 9817 | ioc->remove_host = 1; | 9824 | ioc->remove_host = 1; |
| 9825 | |||
| 9826 | mpt3sas_wait_for_commands_to_complete(ioc); | ||
| 9827 | _scsih_flush_running_cmds(ioc); | ||
| 9828 | |||
| 9818 | _scsih_fw_event_cleanup_queue(ioc); | 9829 | _scsih_fw_event_cleanup_queue(ioc); |
| 9819 | 9830 | ||
| 9820 | spin_lock_irqsave(&ioc->fw_event_lock, flags); | 9831 | spin_lock_irqsave(&ioc->fw_event_lock, flags); |
diff --git a/drivers/scsi/qedi/qedi_fw.c b/drivers/scsi/qedi/qedi_fw.c index 667d7697ba01..d09afe1b567d 100644 --- a/drivers/scsi/qedi/qedi_fw.c +++ b/drivers/scsi/qedi/qedi_fw.c | |||
| @@ -762,6 +762,11 @@ static void qedi_process_cmd_cleanup_resp(struct qedi_ctx *qedi, | |||
| 762 | 762 | ||
| 763 | iscsi_cid = cqe->conn_id; | 763 | iscsi_cid = cqe->conn_id; |
| 764 | qedi_conn = qedi->cid_que.conn_cid_tbl[iscsi_cid]; | 764 | qedi_conn = qedi->cid_que.conn_cid_tbl[iscsi_cid]; |
| 765 | if (!qedi_conn) { | ||
| 766 | QEDI_INFO(&qedi->dbg_ctx, QEDI_LOG_INFO, | ||
| 767 | "icid not found 0x%x\n", cqe->conn_id); | ||
| 768 | return; | ||
| 769 | } | ||
| 765 | 770 | ||
| 766 | /* Based on this itt get the corresponding qedi_cmd */ | 771 | /* Based on this itt get the corresponding qedi_cmd */ |
| 767 | spin_lock_bh(&qedi_conn->tmf_work_lock); | 772 | spin_lock_bh(&qedi_conn->tmf_work_lock); |
diff --git a/drivers/scsi/qla2xxx/qla_def.h b/drivers/scsi/qla2xxx/qla_def.h index be7d6824581a..c9689f97c307 100644 --- a/drivers/scsi/qla2xxx/qla_def.h +++ b/drivers/scsi/qla2xxx/qla_def.h | |||
| @@ -261,9 +261,9 @@ | |||
| 261 | struct name_list_extended { | 261 | struct name_list_extended { |
| 262 | struct get_name_list_extended *l; | 262 | struct get_name_list_extended *l; |
| 263 | dma_addr_t ldma; | 263 | dma_addr_t ldma; |
| 264 | struct list_head fcports; /* protect by sess_list */ | 264 | struct list_head fcports; |
| 265 | spinlock_t fcports_lock; | ||
| 265 | u32 size; | 266 | u32 size; |
| 266 | u8 sent; | ||
| 267 | }; | 267 | }; |
| 268 | /* | 268 | /* |
| 269 | * Timeout timer counts in seconds | 269 | * Timeout timer counts in seconds |
| @@ -2217,6 +2217,7 @@ typedef struct { | |||
| 2217 | 2217 | ||
| 2218 | /* FCP-4 types */ | 2218 | /* FCP-4 types */ |
| 2219 | #define FC4_TYPE_FCP_SCSI 0x08 | 2219 | #define FC4_TYPE_FCP_SCSI 0x08 |
| 2220 | #define FC4_TYPE_NVME 0x28 | ||
| 2220 | #define FC4_TYPE_OTHER 0x0 | 2221 | #define FC4_TYPE_OTHER 0x0 |
| 2221 | #define FC4_TYPE_UNKNOWN 0xff | 2222 | #define FC4_TYPE_UNKNOWN 0xff |
| 2222 | 2223 | ||
diff --git a/drivers/scsi/qla2xxx/qla_gs.c b/drivers/scsi/qla2xxx/qla_gs.c index 5bf9a59432f6..403fa096f8c8 100644 --- a/drivers/scsi/qla2xxx/qla_gs.c +++ b/drivers/scsi/qla2xxx/qla_gs.c | |||
| @@ -3179,6 +3179,7 @@ done_free_sp: | |||
| 3179 | sp->free(sp); | 3179 | sp->free(sp); |
| 3180 | fcport->flags &= ~FCF_ASYNC_SENT; | 3180 | fcport->flags &= ~FCF_ASYNC_SENT; |
| 3181 | done: | 3181 | done: |
| 3182 | fcport->flags &= ~FCF_ASYNC_ACTIVE; | ||
| 3182 | return rval; | 3183 | return rval; |
| 3183 | } | 3184 | } |
| 3184 | 3185 | ||
| @@ -3370,6 +3371,7 @@ done_free_sp: | |||
| 3370 | sp->free(sp); | 3371 | sp->free(sp); |
| 3371 | fcport->flags &= ~FCF_ASYNC_SENT; | 3372 | fcport->flags &= ~FCF_ASYNC_SENT; |
| 3372 | done: | 3373 | done: |
| 3374 | fcport->flags &= ~FCF_ASYNC_ACTIVE; | ||
| 3373 | return rval; | 3375 | return rval; |
| 3374 | } | 3376 | } |
| 3375 | 3377 | ||
| @@ -3971,6 +3973,9 @@ out: | |||
| 3971 | spin_lock_irqsave(&vha->work_lock, flags); | 3973 | spin_lock_irqsave(&vha->work_lock, flags); |
| 3972 | vha->scan.scan_flags &= ~SF_SCANNING; | 3974 | vha->scan.scan_flags &= ~SF_SCANNING; |
| 3973 | spin_unlock_irqrestore(&vha->work_lock, flags); | 3975 | spin_unlock_irqrestore(&vha->work_lock, flags); |
| 3976 | |||
| 3977 | if ((fc4type == FC4_TYPE_FCP_SCSI) && vha->flags.nvme_enabled) | ||
| 3978 | qla24xx_async_gpnft(vha, FC4_TYPE_NVME); | ||
| 3974 | } | 3979 | } |
| 3975 | 3980 | ||
| 3976 | static void qla2x00_async_gpnft_gnnft_sp_done(void *s, int res) | 3981 | static void qla2x00_async_gpnft_gnnft_sp_done(void *s, int res) |
diff --git a/drivers/scsi/qla2xxx/qla_init.c b/drivers/scsi/qla2xxx/qla_init.c index 2dea1129d396..00329dda6179 100644 --- a/drivers/scsi/qla2xxx/qla_init.c +++ b/drivers/scsi/qla2xxx/qla_init.c | |||
| @@ -213,6 +213,7 @@ done_free_sp: | |||
| 213 | sp->free(sp); | 213 | sp->free(sp); |
| 214 | fcport->flags &= ~FCF_ASYNC_SENT; | 214 | fcport->flags &= ~FCF_ASYNC_SENT; |
| 215 | done: | 215 | done: |
| 216 | fcport->flags &= ~FCF_ASYNC_ACTIVE; | ||
| 216 | return rval; | 217 | return rval; |
| 217 | } | 218 | } |
| 218 | 219 | ||
| @@ -263,7 +264,7 @@ qla2x00_async_logout(struct scsi_qla_host *vha, fc_port_t *fcport) | |||
| 263 | done_free_sp: | 264 | done_free_sp: |
| 264 | sp->free(sp); | 265 | sp->free(sp); |
| 265 | done: | 266 | done: |
| 266 | fcport->flags &= ~FCF_ASYNC_SENT; | 267 | fcport->flags &= ~(FCF_ASYNC_SENT | FCF_ASYNC_ACTIVE); |
| 267 | return rval; | 268 | return rval; |
| 268 | } | 269 | } |
| 269 | 270 | ||
| @@ -271,6 +272,7 @@ void | |||
| 271 | qla2x00_async_prlo_done(struct scsi_qla_host *vha, fc_port_t *fcport, | 272 | qla2x00_async_prlo_done(struct scsi_qla_host *vha, fc_port_t *fcport, |
| 272 | uint16_t *data) | 273 | uint16_t *data) |
| 273 | { | 274 | { |
| 275 | fcport->flags &= ~FCF_ASYNC_ACTIVE; | ||
| 274 | /* Don't re-login in target mode */ | 276 | /* Don't re-login in target mode */ |
| 275 | if (!fcport->tgt_session) | 277 | if (!fcport->tgt_session) |
| 276 | qla2x00_mark_device_lost(vha, fcport, 1, 0); | 278 | qla2x00_mark_device_lost(vha, fcport, 1, 0); |
| @@ -284,6 +286,7 @@ qla2x00_async_prlo_sp_done(void *s, int res) | |||
| 284 | struct srb_iocb *lio = &sp->u.iocb_cmd; | 286 | struct srb_iocb *lio = &sp->u.iocb_cmd; |
| 285 | struct scsi_qla_host *vha = sp->vha; | 287 | struct scsi_qla_host *vha = sp->vha; |
| 286 | 288 | ||
| 289 | sp->fcport->flags &= ~FCF_ASYNC_ACTIVE; | ||
| 287 | if (!test_bit(UNLOADING, &vha->dpc_flags)) | 290 | if (!test_bit(UNLOADING, &vha->dpc_flags)) |
| 288 | qla2x00_post_async_prlo_done_work(sp->fcport->vha, sp->fcport, | 291 | qla2x00_post_async_prlo_done_work(sp->fcport->vha, sp->fcport, |
| 289 | lio->u.logio.data); | 292 | lio->u.logio.data); |
| @@ -322,6 +325,7 @@ qla2x00_async_prlo(struct scsi_qla_host *vha, fc_port_t *fcport) | |||
| 322 | done_free_sp: | 325 | done_free_sp: |
| 323 | sp->free(sp); | 326 | sp->free(sp); |
| 324 | done: | 327 | done: |
| 328 | fcport->flags &= ~FCF_ASYNC_ACTIVE; | ||
| 325 | return rval; | 329 | return rval; |
| 326 | } | 330 | } |
| 327 | 331 | ||
| @@ -375,6 +379,8 @@ qla2x00_async_adisc_sp_done(void *ptr, int res) | |||
| 375 | "Async done-%s res %x %8phC\n", | 379 | "Async done-%s res %x %8phC\n", |
| 376 | sp->name, res, sp->fcport->port_name); | 380 | sp->name, res, sp->fcport->port_name); |
| 377 | 381 | ||
| 382 | sp->fcport->flags &= ~FCF_ASYNC_SENT; | ||
| 383 | |||
| 378 | memset(&ea, 0, sizeof(ea)); | 384 | memset(&ea, 0, sizeof(ea)); |
| 379 | ea.event = FCME_ADISC_DONE; | 385 | ea.event = FCME_ADISC_DONE; |
| 380 | ea.rc = res; | 386 | ea.rc = res; |
| @@ -425,7 +431,7 @@ qla2x00_async_adisc(struct scsi_qla_host *vha, fc_port_t *fcport, | |||
| 425 | done_free_sp: | 431 | done_free_sp: |
| 426 | sp->free(sp); | 432 | sp->free(sp); |
| 427 | done: | 433 | done: |
| 428 | fcport->flags &= ~FCF_ASYNC_SENT; | 434 | fcport->flags &= ~(FCF_ASYNC_SENT | FCF_ASYNC_ACTIVE); |
| 429 | qla2x00_post_async_adisc_work(vha, fcport, data); | 435 | qla2x00_post_async_adisc_work(vha, fcport, data); |
| 430 | return rval; | 436 | return rval; |
| 431 | } | 437 | } |
| @@ -643,8 +649,7 @@ qla24xx_async_gnl_sp_done(void *s, int res) | |||
| 643 | (loop_id & 0x7fff)); | 649 | (loop_id & 0x7fff)); |
| 644 | } | 650 | } |
| 645 | 651 | ||
| 646 | spin_lock_irqsave(&vha->hw->tgt.sess_lock, flags); | 652 | spin_lock_irqsave(&vha->gnl.fcports_lock, flags); |
| 647 | vha->gnl.sent = 0; | ||
| 648 | 653 | ||
| 649 | INIT_LIST_HEAD(&h); | 654 | INIT_LIST_HEAD(&h); |
| 650 | fcport = tf = NULL; | 655 | fcport = tf = NULL; |
| @@ -653,12 +658,16 @@ qla24xx_async_gnl_sp_done(void *s, int res) | |||
| 653 | 658 | ||
| 654 | list_for_each_entry_safe(fcport, tf, &h, gnl_entry) { | 659 | list_for_each_entry_safe(fcport, tf, &h, gnl_entry) { |
| 655 | list_del_init(&fcport->gnl_entry); | 660 | list_del_init(&fcport->gnl_entry); |
| 661 | spin_lock(&vha->hw->tgt.sess_lock); | ||
| 656 | fcport->flags &= ~(FCF_ASYNC_SENT | FCF_ASYNC_ACTIVE); | 662 | fcport->flags &= ~(FCF_ASYNC_SENT | FCF_ASYNC_ACTIVE); |
| 663 | spin_unlock(&vha->hw->tgt.sess_lock); | ||
| 657 | ea.fcport = fcport; | 664 | ea.fcport = fcport; |
| 658 | 665 | ||
| 659 | qla2x00_fcport_event_handler(vha, &ea); | 666 | qla2x00_fcport_event_handler(vha, &ea); |
| 660 | } | 667 | } |
| 668 | spin_unlock_irqrestore(&vha->gnl.fcports_lock, flags); | ||
| 661 | 669 | ||
| 670 | spin_lock_irqsave(&vha->hw->tgt.sess_lock, flags); | ||
| 662 | /* create new fcport if fw has knowledge of new sessions */ | 671 | /* create new fcport if fw has knowledge of new sessions */ |
| 663 | for (i = 0; i < n; i++) { | 672 | for (i = 0; i < n; i++) { |
| 664 | port_id_t id; | 673 | port_id_t id; |
| @@ -710,18 +719,21 @@ int qla24xx_async_gnl(struct scsi_qla_host *vha, fc_port_t *fcport) | |||
| 710 | ql_dbg(ql_dbg_disc, vha, 0x20d9, | 719 | ql_dbg(ql_dbg_disc, vha, 0x20d9, |
| 711 | "Async-gnlist WWPN %8phC \n", fcport->port_name); | 720 | "Async-gnlist WWPN %8phC \n", fcport->port_name); |
| 712 | 721 | ||
| 713 | spin_lock_irqsave(&vha->hw->tgt.sess_lock, flags); | 722 | spin_lock_irqsave(&vha->gnl.fcports_lock, flags); |
| 723 | if (!list_empty(&fcport->gnl_entry)) { | ||
| 724 | spin_unlock_irqrestore(&vha->gnl.fcports_lock, flags); | ||
| 725 | rval = QLA_SUCCESS; | ||
| 726 | goto done; | ||
| 727 | } | ||
| 728 | |||
| 729 | spin_lock(&vha->hw->tgt.sess_lock); | ||
| 714 | fcport->disc_state = DSC_GNL; | 730 | fcport->disc_state = DSC_GNL; |
| 715 | fcport->last_rscn_gen = fcport->rscn_gen; | 731 | fcport->last_rscn_gen = fcport->rscn_gen; |
| 716 | fcport->last_login_gen = fcport->login_gen; | 732 | fcport->last_login_gen = fcport->login_gen; |
| 733 | spin_unlock(&vha->hw->tgt.sess_lock); | ||
| 717 | 734 | ||
| 718 | list_add_tail(&fcport->gnl_entry, &vha->gnl.fcports); | 735 | list_add_tail(&fcport->gnl_entry, &vha->gnl.fcports); |
| 719 | if (vha->gnl.sent) { | 736 | spin_unlock_irqrestore(&vha->gnl.fcports_lock, flags); |
| 720 | spin_unlock_irqrestore(&vha->hw->tgt.sess_lock, flags); | ||
| 721 | return QLA_SUCCESS; | ||
| 722 | } | ||
| 723 | vha->gnl.sent = 1; | ||
| 724 | spin_unlock_irqrestore(&vha->hw->tgt.sess_lock, flags); | ||
| 725 | 737 | ||
| 726 | sp = qla2x00_get_sp(vha, fcport, GFP_KERNEL); | 738 | sp = qla2x00_get_sp(vha, fcport, GFP_KERNEL); |
| 727 | if (!sp) | 739 | if (!sp) |
| @@ -1049,6 +1061,7 @@ void qla24xx_handle_gpdb_event(scsi_qla_host_t *vha, struct event_arg *ea) | |||
| 1049 | fc_port_t *fcport = ea->fcport; | 1061 | fc_port_t *fcport = ea->fcport; |
| 1050 | struct port_database_24xx *pd; | 1062 | struct port_database_24xx *pd; |
| 1051 | struct srb *sp = ea->sp; | 1063 | struct srb *sp = ea->sp; |
| 1064 | uint8_t ls; | ||
| 1052 | 1065 | ||
| 1053 | pd = (struct port_database_24xx *)sp->u.iocb_cmd.u.mbx.in; | 1066 | pd = (struct port_database_24xx *)sp->u.iocb_cmd.u.mbx.in; |
| 1054 | 1067 | ||
| @@ -1061,7 +1074,12 @@ void qla24xx_handle_gpdb_event(scsi_qla_host_t *vha, struct event_arg *ea) | |||
| 1061 | if (fcport->disc_state == DSC_DELETE_PEND) | 1074 | if (fcport->disc_state == DSC_DELETE_PEND) |
| 1062 | return; | 1075 | return; |
| 1063 | 1076 | ||
| 1064 | switch (pd->current_login_state) { | 1077 | if (fcport->fc4f_nvme) |
| 1078 | ls = pd->current_login_state >> 4; | ||
| 1079 | else | ||
| 1080 | ls = pd->current_login_state & 0xf; | ||
| 1081 | |||
| 1082 | switch (ls) { | ||
| 1065 | case PDS_PRLI_COMPLETE: | 1083 | case PDS_PRLI_COMPLETE: |
| 1066 | __qla24xx_parse_gpdb(vha, fcport, pd); | 1084 | __qla24xx_parse_gpdb(vha, fcport, pd); |
| 1067 | break; | 1085 | break; |
| @@ -1151,8 +1169,9 @@ int qla24xx_fcport_handle_login(struct scsi_qla_host *vha, fc_port_t *fcport) | |||
| 1151 | if (fcport->scan_state != QLA_FCPORT_FOUND) | 1169 | if (fcport->scan_state != QLA_FCPORT_FOUND) |
| 1152 | return 0; | 1170 | return 0; |
| 1153 | 1171 | ||
| 1154 | if ((fcport->fw_login_state == DSC_LS_PLOGI_PEND) || | 1172 | if ((fcport->loop_id != FC_NO_LOOP_ID) && |
| 1155 | (fcport->fw_login_state == DSC_LS_PRLI_PEND)) | 1173 | ((fcport->fw_login_state == DSC_LS_PLOGI_PEND) || |
| 1174 | (fcport->fw_login_state == DSC_LS_PRLI_PEND))) | ||
| 1156 | return 0; | 1175 | return 0; |
| 1157 | 1176 | ||
| 1158 | if (fcport->fw_login_state == DSC_LS_PLOGI_COMP) { | 1177 | if (fcport->fw_login_state == DSC_LS_PLOGI_COMP) { |
| @@ -1527,6 +1546,7 @@ qla24xx_abort_sp_done(void *ptr, int res) | |||
| 1527 | srb_t *sp = ptr; | 1546 | srb_t *sp = ptr; |
| 1528 | struct srb_iocb *abt = &sp->u.iocb_cmd; | 1547 | struct srb_iocb *abt = &sp->u.iocb_cmd; |
| 1529 | 1548 | ||
| 1549 | del_timer(&sp->u.iocb_cmd.timer); | ||
| 1530 | complete(&abt->u.abt.comp); | 1550 | complete(&abt->u.abt.comp); |
| 1531 | } | 1551 | } |
| 1532 | 1552 | ||
| @@ -1791,6 +1811,7 @@ qla2x00_async_logout_done(struct scsi_qla_host *vha, fc_port_t *fcport, | |||
| 1791 | qla2x00_mark_device_lost(vha, fcport, 1, 0); | 1811 | qla2x00_mark_device_lost(vha, fcport, 1, 0); |
| 1792 | qlt_logo_completion_handler(fcport, data[0]); | 1812 | qlt_logo_completion_handler(fcport, data[0]); |
| 1793 | fcport->login_gen++; | 1813 | fcport->login_gen++; |
| 1814 | fcport->flags &= ~FCF_ASYNC_ACTIVE; | ||
| 1794 | return; | 1815 | return; |
| 1795 | } | 1816 | } |
| 1796 | 1817 | ||
| @@ -1798,6 +1819,7 @@ void | |||
| 1798 | qla2x00_async_adisc_done(struct scsi_qla_host *vha, fc_port_t *fcport, | 1819 | qla2x00_async_adisc_done(struct scsi_qla_host *vha, fc_port_t *fcport, |
| 1799 | uint16_t *data) | 1820 | uint16_t *data) |
| 1800 | { | 1821 | { |
| 1822 | fcport->flags &= ~(FCF_ASYNC_SENT | FCF_ASYNC_ACTIVE); | ||
| 1801 | if (data[0] == MBS_COMMAND_COMPLETE) { | 1823 | if (data[0] == MBS_COMMAND_COMPLETE) { |
| 1802 | qla2x00_update_fcport(vha, fcport); | 1824 | qla2x00_update_fcport(vha, fcport); |
| 1803 | 1825 | ||
| @@ -1805,7 +1827,6 @@ qla2x00_async_adisc_done(struct scsi_qla_host *vha, fc_port_t *fcport, | |||
| 1805 | } | 1827 | } |
| 1806 | 1828 | ||
| 1807 | /* Retry login. */ | 1829 | /* Retry login. */ |
| 1808 | fcport->flags &= ~FCF_ASYNC_SENT; | ||
| 1809 | if (data[1] & QLA_LOGIO_LOGIN_RETRIED) | 1830 | if (data[1] & QLA_LOGIO_LOGIN_RETRIED) |
| 1810 | set_bit(RELOGIN_NEEDED, &vha->dpc_flags); | 1831 | set_bit(RELOGIN_NEEDED, &vha->dpc_flags); |
| 1811 | else | 1832 | else |
diff --git a/drivers/scsi/qla2xxx/qla_os.c b/drivers/scsi/qla2xxx/qla_os.c index afcb5567998a..285911e81728 100644 --- a/drivers/scsi/qla2xxx/qla_os.c +++ b/drivers/scsi/qla2xxx/qla_os.c | |||
| @@ -4577,6 +4577,7 @@ struct scsi_qla_host *qla2x00_create_host(struct scsi_host_template *sht, | |||
| 4577 | 4577 | ||
| 4578 | spin_lock_init(&vha->work_lock); | 4578 | spin_lock_init(&vha->work_lock); |
| 4579 | spin_lock_init(&vha->cmd_list_lock); | 4579 | spin_lock_init(&vha->cmd_list_lock); |
| 4580 | spin_lock_init(&vha->gnl.fcports_lock); | ||
| 4580 | init_waitqueue_head(&vha->fcport_waitQ); | 4581 | init_waitqueue_head(&vha->fcport_waitQ); |
| 4581 | init_waitqueue_head(&vha->vref_waitq); | 4582 | init_waitqueue_head(&vha->vref_waitq); |
| 4582 | 4583 | ||
| @@ -4806,9 +4807,12 @@ void qla24xx_create_new_sess(struct scsi_qla_host *vha, struct qla_work_evt *e) | |||
| 4806 | fcport->d_id = e->u.new_sess.id; | 4807 | fcport->d_id = e->u.new_sess.id; |
| 4807 | fcport->flags |= FCF_FABRIC_DEVICE; | 4808 | fcport->flags |= FCF_FABRIC_DEVICE; |
| 4808 | fcport->fw_login_state = DSC_LS_PLOGI_PEND; | 4809 | fcport->fw_login_state = DSC_LS_PLOGI_PEND; |
| 4809 | if (e->u.new_sess.fc4_type == FC4_TYPE_FCP_SCSI) | 4810 | if (e->u.new_sess.fc4_type == FC4_TYPE_FCP_SCSI) { |
| 4810 | fcport->fc4_type = FC4_TYPE_FCP_SCSI; | 4811 | fcport->fc4_type = FC4_TYPE_FCP_SCSI; |
| 4811 | 4812 | } else if (e->u.new_sess.fc4_type == FC4_TYPE_NVME) { | |
| 4813 | fcport->fc4_type = FC4_TYPE_OTHER; | ||
| 4814 | fcport->fc4f_nvme = FC4_TYPE_NVME; | ||
| 4815 | } | ||
| 4812 | memcpy(fcport->port_name, e->u.new_sess.port_name, | 4816 | memcpy(fcport->port_name, e->u.new_sess.port_name, |
| 4813 | WWN_SIZE); | 4817 | WWN_SIZE); |
| 4814 | } else { | 4818 | } else { |
| @@ -4877,6 +4881,8 @@ void qla24xx_create_new_sess(struct scsi_qla_host *vha, struct qla_work_evt *e) | |||
| 4877 | } | 4881 | } |
| 4878 | qlt_plogi_ack_unref(vha, pla); | 4882 | qlt_plogi_ack_unref(vha, pla); |
| 4879 | } else { | 4883 | } else { |
| 4884 | fc_port_t *dfcp = NULL; | ||
| 4885 | |||
| 4880 | spin_lock_irqsave(&vha->hw->tgt.sess_lock, flags); | 4886 | spin_lock_irqsave(&vha->hw->tgt.sess_lock, flags); |
| 4881 | tfcp = qla2x00_find_fcport_by_nportid(vha, | 4887 | tfcp = qla2x00_find_fcport_by_nportid(vha, |
| 4882 | &e->u.new_sess.id, 1); | 4888 | &e->u.new_sess.id, 1); |
| @@ -4899,11 +4905,13 @@ void qla24xx_create_new_sess(struct scsi_qla_host *vha, struct qla_work_evt *e) | |||
| 4899 | default: | 4905 | default: |
| 4900 | fcport->login_pause = 1; | 4906 | fcport->login_pause = 1; |
| 4901 | tfcp->conflict = fcport; | 4907 | tfcp->conflict = fcport; |
| 4902 | qlt_schedule_sess_for_deletion(tfcp); | 4908 | dfcp = tfcp; |
| 4903 | break; | 4909 | break; |
| 4904 | } | 4910 | } |
| 4905 | } | 4911 | } |
| 4906 | spin_unlock_irqrestore(&vha->hw->tgt.sess_lock, flags); | 4912 | spin_unlock_irqrestore(&vha->hw->tgt.sess_lock, flags); |
| 4913 | if (dfcp) | ||
| 4914 | qlt_schedule_sess_for_deletion(tfcp); | ||
| 4907 | 4915 | ||
| 4908 | wwn = wwn_to_u64(fcport->node_name); | 4916 | wwn = wwn_to_u64(fcport->node_name); |
| 4909 | 4917 | ||
diff --git a/drivers/scsi/qla2xxx/qla_target.c b/drivers/scsi/qla2xxx/qla_target.c index 896b2d8bd803..b49ac85f3de2 100644 --- a/drivers/scsi/qla2xxx/qla_target.c +++ b/drivers/scsi/qla2xxx/qla_target.c | |||
| @@ -1224,10 +1224,10 @@ static void qla24xx_chk_fcp_state(struct fc_port *sess) | |||
| 1224 | } | 1224 | } |
| 1225 | } | 1225 | } |
| 1226 | 1226 | ||
| 1227 | /* ha->tgt.sess_lock supposed to be held on entry */ | ||
| 1228 | void qlt_schedule_sess_for_deletion(struct fc_port *sess) | 1227 | void qlt_schedule_sess_for_deletion(struct fc_port *sess) |
| 1229 | { | 1228 | { |
| 1230 | struct qla_tgt *tgt = sess->tgt; | 1229 | struct qla_tgt *tgt = sess->tgt; |
| 1230 | struct qla_hw_data *ha = sess->vha->hw; | ||
| 1231 | unsigned long flags; | 1231 | unsigned long flags; |
| 1232 | 1232 | ||
| 1233 | if (sess->disc_state == DSC_DELETE_PEND) | 1233 | if (sess->disc_state == DSC_DELETE_PEND) |
| @@ -1244,16 +1244,16 @@ void qlt_schedule_sess_for_deletion(struct fc_port *sess) | |||
| 1244 | return; | 1244 | return; |
| 1245 | } | 1245 | } |
| 1246 | 1246 | ||
| 1247 | spin_lock_irqsave(&ha->tgt.sess_lock, flags); | ||
| 1247 | if (sess->deleted == QLA_SESS_DELETED) | 1248 | if (sess->deleted == QLA_SESS_DELETED) |
| 1248 | sess->logout_on_delete = 0; | 1249 | sess->logout_on_delete = 0; |
| 1249 | 1250 | ||
| 1250 | spin_lock_irqsave(&sess->vha->work_lock, flags); | ||
| 1251 | if (sess->deleted == QLA_SESS_DELETION_IN_PROGRESS) { | 1251 | if (sess->deleted == QLA_SESS_DELETION_IN_PROGRESS) { |
| 1252 | spin_unlock_irqrestore(&sess->vha->work_lock, flags); | 1252 | spin_unlock_irqrestore(&ha->tgt.sess_lock, flags); |
| 1253 | return; | 1253 | return; |
| 1254 | } | 1254 | } |
| 1255 | sess->deleted = QLA_SESS_DELETION_IN_PROGRESS; | 1255 | sess->deleted = QLA_SESS_DELETION_IN_PROGRESS; |
| 1256 | spin_unlock_irqrestore(&sess->vha->work_lock, flags); | 1256 | spin_unlock_irqrestore(&ha->tgt.sess_lock, flags); |
| 1257 | 1257 | ||
| 1258 | sess->disc_state = DSC_DELETE_PEND; | 1258 | sess->disc_state = DSC_DELETE_PEND; |
| 1259 | 1259 | ||
| @@ -1262,13 +1262,10 @@ void qlt_schedule_sess_for_deletion(struct fc_port *sess) | |||
| 1262 | ql_dbg(ql_dbg_tgt, sess->vha, 0xe001, | 1262 | ql_dbg(ql_dbg_tgt, sess->vha, 0xe001, |
| 1263 | "Scheduling sess %p for deletion\n", sess); | 1263 | "Scheduling sess %p for deletion\n", sess); |
| 1264 | 1264 | ||
| 1265 | /* use cancel to push work element through before re-queue */ | ||
| 1266 | cancel_work_sync(&sess->del_work); | ||
| 1267 | INIT_WORK(&sess->del_work, qla24xx_delete_sess_fn); | 1265 | INIT_WORK(&sess->del_work, qla24xx_delete_sess_fn); |
| 1268 | queue_work(sess->vha->hw->wq, &sess->del_work); | 1266 | WARN_ON(!queue_work(sess->vha->hw->wq, &sess->del_work)); |
| 1269 | } | 1267 | } |
| 1270 | 1268 | ||
| 1271 | /* ha->tgt.sess_lock supposed to be held on entry */ | ||
| 1272 | static void qlt_clear_tgt_db(struct qla_tgt *tgt) | 1269 | static void qlt_clear_tgt_db(struct qla_tgt *tgt) |
| 1273 | { | 1270 | { |
| 1274 | struct fc_port *sess; | 1271 | struct fc_port *sess; |
| @@ -1451,8 +1448,8 @@ qlt_fc_port_deleted(struct scsi_qla_host *vha, fc_port_t *fcport, int max_gen) | |||
| 1451 | ql_dbg(ql_dbg_tgt_mgt, vha, 0xf008, "qla_tgt_fc_port_deleted %p", sess); | 1448 | ql_dbg(ql_dbg_tgt_mgt, vha, 0xf008, "qla_tgt_fc_port_deleted %p", sess); |
| 1452 | 1449 | ||
| 1453 | sess->local = 1; | 1450 | sess->local = 1; |
| 1454 | qlt_schedule_sess_for_deletion(sess); | ||
| 1455 | spin_unlock_irqrestore(&vha->hw->tgt.sess_lock, flags); | 1451 | spin_unlock_irqrestore(&vha->hw->tgt.sess_lock, flags); |
| 1452 | qlt_schedule_sess_for_deletion(sess); | ||
| 1456 | } | 1453 | } |
| 1457 | 1454 | ||
| 1458 | static inline int test_tgt_sess_count(struct qla_tgt *tgt) | 1455 | static inline int test_tgt_sess_count(struct qla_tgt *tgt) |
| @@ -1512,10 +1509,8 @@ int qlt_stop_phase1(struct qla_tgt *tgt) | |||
| 1512 | * Lock is needed, because we still can get an incoming packet. | 1509 | * Lock is needed, because we still can get an incoming packet. |
| 1513 | */ | 1510 | */ |
| 1514 | mutex_lock(&vha->vha_tgt.tgt_mutex); | 1511 | mutex_lock(&vha->vha_tgt.tgt_mutex); |
| 1515 | spin_lock_irqsave(&ha->tgt.sess_lock, flags); | ||
| 1516 | tgt->tgt_stop = 1; | 1512 | tgt->tgt_stop = 1; |
| 1517 | qlt_clear_tgt_db(tgt); | 1513 | qlt_clear_tgt_db(tgt); |
| 1518 | spin_unlock_irqrestore(&ha->tgt.sess_lock, flags); | ||
| 1519 | mutex_unlock(&vha->vha_tgt.tgt_mutex); | 1514 | mutex_unlock(&vha->vha_tgt.tgt_mutex); |
| 1520 | mutex_unlock(&qla_tgt_mutex); | 1515 | mutex_unlock(&qla_tgt_mutex); |
| 1521 | 1516 | ||
diff --git a/drivers/scsi/scsi_error.c b/drivers/scsi/scsi_error.c index d042915ce895..ca53a5f785ee 100644 --- a/drivers/scsi/scsi_error.c +++ b/drivers/scsi/scsi_error.c | |||
| @@ -223,7 +223,8 @@ static void scsi_eh_reset(struct scsi_cmnd *scmd) | |||
| 223 | 223 | ||
| 224 | static void scsi_eh_inc_host_failed(struct rcu_head *head) | 224 | static void scsi_eh_inc_host_failed(struct rcu_head *head) |
| 225 | { | 225 | { |
| 226 | struct Scsi_Host *shost = container_of(head, typeof(*shost), rcu); | 226 | struct scsi_cmnd *scmd = container_of(head, typeof(*scmd), rcu); |
| 227 | struct Scsi_Host *shost = scmd->device->host; | ||
| 227 | unsigned long flags; | 228 | unsigned long flags; |
| 228 | 229 | ||
| 229 | spin_lock_irqsave(shost->host_lock, flags); | 230 | spin_lock_irqsave(shost->host_lock, flags); |
| @@ -259,7 +260,7 @@ void scsi_eh_scmd_add(struct scsi_cmnd *scmd) | |||
| 259 | * Ensure that all tasks observe the host state change before the | 260 | * Ensure that all tasks observe the host state change before the |
| 260 | * host_failed change. | 261 | * host_failed change. |
| 261 | */ | 262 | */ |
| 262 | call_rcu(&shost->rcu, scsi_eh_inc_host_failed); | 263 | call_rcu(&scmd->rcu, scsi_eh_inc_host_failed); |
| 263 | } | 264 | } |
| 264 | 265 | ||
| 265 | /** | 266 | /** |
diff --git a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c index a86df9ca7d1c..c84f931388f2 100644 --- a/drivers/scsi/scsi_lib.c +++ b/drivers/scsi/scsi_lib.c | |||
| @@ -671,6 +671,7 @@ static bool scsi_end_request(struct request *req, blk_status_t error, | |||
| 671 | if (!blk_rq_is_scsi(req)) { | 671 | if (!blk_rq_is_scsi(req)) { |
| 672 | WARN_ON_ONCE(!(cmd->flags & SCMD_INITIALIZED)); | 672 | WARN_ON_ONCE(!(cmd->flags & SCMD_INITIALIZED)); |
| 673 | cmd->flags &= ~SCMD_INITIALIZED; | 673 | cmd->flags &= ~SCMD_INITIALIZED; |
| 674 | destroy_rcu_head(&cmd->rcu); | ||
| 674 | } | 675 | } |
| 675 | 676 | ||
| 676 | if (req->mq_ctx) { | 677 | if (req->mq_ctx) { |
| @@ -720,6 +721,8 @@ static blk_status_t __scsi_error_from_host_byte(struct scsi_cmnd *cmd, | |||
| 720 | int result) | 721 | int result) |
| 721 | { | 722 | { |
| 722 | switch (host_byte(result)) { | 723 | switch (host_byte(result)) { |
| 724 | case DID_OK: | ||
| 725 | return BLK_STS_OK; | ||
| 723 | case DID_TRANSPORT_FAILFAST: | 726 | case DID_TRANSPORT_FAILFAST: |
| 724 | return BLK_STS_TRANSPORT; | 727 | return BLK_STS_TRANSPORT; |
| 725 | case DID_TARGET_FAILURE: | 728 | case DID_TARGET_FAILURE: |
| @@ -1151,6 +1154,7 @@ static void scsi_initialize_rq(struct request *rq) | |||
| 1151 | struct scsi_cmnd *cmd = blk_mq_rq_to_pdu(rq); | 1154 | struct scsi_cmnd *cmd = blk_mq_rq_to_pdu(rq); |
| 1152 | 1155 | ||
| 1153 | scsi_req_init(&cmd->req); | 1156 | scsi_req_init(&cmd->req); |
| 1157 | init_rcu_head(&cmd->rcu); | ||
| 1154 | cmd->jiffies_at_alloc = jiffies; | 1158 | cmd->jiffies_at_alloc = jiffies; |
| 1155 | cmd->retries = 0; | 1159 | cmd->retries = 0; |
| 1156 | } | 1160 | } |
diff --git a/drivers/scsi/storvsc_drv.c b/drivers/scsi/storvsc_drv.c index 6be5ab32c94f..8c51d628b52e 100644 --- a/drivers/scsi/storvsc_drv.c +++ b/drivers/scsi/storvsc_drv.c | |||
| @@ -1311,7 +1311,8 @@ static int storvsc_do_io(struct hv_device *device, | |||
| 1311 | */ | 1311 | */ |
| 1312 | cpumask_and(&alloced_mask, &stor_device->alloced_cpus, | 1312 | cpumask_and(&alloced_mask, &stor_device->alloced_cpus, |
| 1313 | cpumask_of_node(cpu_to_node(q_num))); | 1313 | cpumask_of_node(cpu_to_node(q_num))); |
| 1314 | for_each_cpu(tgt_cpu, &alloced_mask) { | 1314 | for_each_cpu_wrap(tgt_cpu, &alloced_mask, |
| 1315 | outgoing_channel->target_cpu + 1) { | ||
| 1315 | if (tgt_cpu != outgoing_channel->target_cpu) { | 1316 | if (tgt_cpu != outgoing_channel->target_cpu) { |
| 1316 | outgoing_channel = | 1317 | outgoing_channel = |
| 1317 | stor_device->stor_chns[tgt_cpu]; | 1318 | stor_device->stor_chns[tgt_cpu]; |
diff --git a/include/scsi/scsi_cmnd.h b/include/scsi/scsi_cmnd.h index d8d4a902a88d..2280b2351739 100644 --- a/include/scsi/scsi_cmnd.h +++ b/include/scsi/scsi_cmnd.h | |||
| @@ -68,6 +68,9 @@ struct scsi_cmnd { | |||
| 68 | struct list_head list; /* scsi_cmnd participates in queue lists */ | 68 | struct list_head list; /* scsi_cmnd participates in queue lists */ |
| 69 | struct list_head eh_entry; /* entry for the host eh_cmd_q */ | 69 | struct list_head eh_entry; /* entry for the host eh_cmd_q */ |
| 70 | struct delayed_work abort_work; | 70 | struct delayed_work abort_work; |
| 71 | |||
| 72 | struct rcu_head rcu; | ||
| 73 | |||
| 71 | int eh_eflags; /* Used by error handlr */ | 74 | int eh_eflags; /* Used by error handlr */ |
| 72 | 75 | ||
| 73 | /* | 76 | /* |
diff --git a/include/scsi/scsi_host.h b/include/scsi/scsi_host.h index 1a1df0d21ee3..a8b7bf879ced 100644 --- a/include/scsi/scsi_host.h +++ b/include/scsi/scsi_host.h | |||
| @@ -571,8 +571,6 @@ struct Scsi_Host { | |||
| 571 | struct blk_mq_tag_set tag_set; | 571 | struct blk_mq_tag_set tag_set; |
| 572 | }; | 572 | }; |
| 573 | 573 | ||
| 574 | struct rcu_head rcu; | ||
| 575 | |||
| 576 | atomic_t host_busy; /* commands actually active on low-level */ | 574 | atomic_t host_busy; /* commands actually active on low-level */ |
| 577 | atomic_t host_blocked; | 575 | atomic_t host_blocked; |
| 578 | 576 | ||
