From f7733625ec2f7bd628e4fd5014f72a2983830a74 Mon Sep 17 00:00:00 2001 From: Adrian Hunter Date: Tue, 9 Feb 2021 08:24:34 +0200 Subject: [PATCH 001/412] scsi: ufs: Add exception event tracepoint Currently, exception event status can be read from wExceptionEventStatus attribute (sysfs file attributes/exception_event_status under the UFS host controller device directory). Polling that attribute to track UFS exception events is impractical, so add a tracepoint to track exception events for testing and debugging purposes. Note, by the time the exception event status is read, the exception event may have cleared, so the value can be zero - see example below. Note also, only enabled exception events can be reported. A subsequent patch adds the ability for users to enable selected exception events via debugfs. Example with driver instrumented to enable all exception events: # echo 1 > /sys/kernel/debug/tracing/events/ufs/ufshcd_exception_event/enable ... do some I/O ... # cat /sys/kernel/debug/tracing/trace # tracer: nop # # entries-in-buffer/entries-written: 3/3 #P:5 # # _-----=> irqs-off # / _----=> need-resched # | / _---=> hardirq/softirq # || / _--=> preempt-depth # ||| / delay # TASK-PID CPU# |||| TIMESTAMP FUNCTION # | | | |||| | | kworker/2:2-173 [002] .... 731.486419: ufshcd_exception_event: 0000:00:12.5: status 0x0 kworker/2:2-173 [002] .... 732.608918: ufshcd_exception_event: 0000:00:12.5: status 0x4 kworker/2:2-173 [002] .... 732.609312: ufshcd_exception_event: 0000:00:12.5: status 0x4 Link: https://lore.kernel.org/r/20210209062437.6954-2-adrian.hunter@intel.com Reviewed-by: Avri Altman Reviewed-by: Bean Huo Signed-off-by: Adrian Hunter Signed-off-by: Martin K. Petersen --- drivers/scsi/ufs/ufshcd.c | 2 ++ include/trace/events/ufs.h | 21 +++++++++++++++++++++ 2 files changed, 23 insertions(+) diff --git a/drivers/scsi/ufs/ufshcd.c b/drivers/scsi/ufs/ufshcd.c index 77161750c9fb..98b4cc085e1e 100644 --- a/drivers/scsi/ufs/ufshcd.c +++ b/drivers/scsi/ufs/ufshcd.c @@ -5618,6 +5618,8 @@ static void ufshcd_exception_event_handler(struct work_struct *work) goto out; } + trace_ufshcd_exception_event(dev_name(hba->dev), status); + status &= hba->ee_ctrl_mask; if (status & MASK_EE_URGENT_BKOPS) diff --git a/include/trace/events/ufs.h b/include/trace/events/ufs.h index e151477d645c..1cb6f1afba0e 100644 --- a/include/trace/events/ufs.h +++ b/include/trace/events/ufs.h @@ -349,6 +349,27 @@ TRACE_EVENT(ufshcd_upiu, ) ); +TRACE_EVENT(ufshcd_exception_event, + + TP_PROTO(const char *dev_name, u16 status), + + TP_ARGS(dev_name, status), + + TP_STRUCT__entry( + __string(dev_name, dev_name) + __field(u16, status) + ), + + TP_fast_assign( + __assign_str(dev_name, dev_name); + __entry->status = status; + ), + + TP_printk("%s: status 0x%x", + __get_str(dev_name), __entry->status + ) +); + #endif /* if !defined(_TRACE_UFS_H) || defined(TRACE_HEADER_MULTI_READ) */ /* This part must be outside protection */ From 37b97b18704f77f711e7a2c532fcad00268ac025 Mon Sep 17 00:00:00 2001 From: Adrian Hunter Date: Tue, 9 Feb 2021 08:24:35 +0200 Subject: [PATCH 002/412] scsi: ufs: Add exception event definitions For readability and completeness, add exception event definitions. Link: https://lore.kernel.org/r/20210209062437.6954-3-adrian.hunter@intel.com Reviewed-by: Bean Huo Signed-off-by: Adrian Hunter Signed-off-by: Martin K. Petersen --- drivers/scsi/ufs/ufs.h | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/drivers/scsi/ufs/ufs.h b/drivers/scsi/ufs/ufs.h index bf1897a72532..cb80b9670bfe 100644 --- a/drivers/scsi/ufs/ufs.h +++ b/drivers/scsi/ufs/ufs.h @@ -348,8 +348,14 @@ enum power_desc_param_offset { /* Exception event mask values */ enum { - MASK_EE_STATUS = 0xFFFF, - MASK_EE_URGENT_BKOPS = (1 << 2), + MASK_EE_STATUS = 0xFFFF, + MASK_EE_DYNCAP_EVENT = BIT(0), + MASK_EE_SYSPOOL_EVENT = BIT(1), + MASK_EE_URGENT_BKOPS = BIT(2), + MASK_EE_TOO_HIGH_TEMP = BIT(3), + MASK_EE_TOO_LOW_TEMP = BIT(4), + MASK_EE_WRITEBOOSTER_EVENT = BIT(5), + MASK_EE_PERFORMANCE_THROTTLING = BIT(6), }; /* Background operation status */ From cd4694756188dcca0f631e60da26053be1ffdc91 Mon Sep 17 00:00:00 2001 From: Adrian Hunter Date: Tue, 9 Feb 2021 08:24:36 +0200 Subject: [PATCH 003/412] scsi: ufs: ufs-debugfs: Add user-defined exception_event_mask Allow users to enable specific exception events via debugfs. The bits enabled by the driver ee_drv_ctrl are separated from the bits enabled by the user ee_usr_ctrl. The control mask ee_mask_ctrl is the logical-or of those two. A mutex is needed to ensure that the masks match what was written to the device. Link: https://lore.kernel.org/r/20210209062437.6954-4-adrian.hunter@intel.com Acked-by: Bean Huo Signed-off-by: Adrian Hunter Signed-off-by: Martin K. Petersen --- drivers/scsi/ufs/ufs-debugfs.c | 46 ++++++++++++++++++ drivers/scsi/ufs/ufshcd.c | 86 +++++++++++++++++++++------------- drivers/scsi/ufs/ufshcd.h | 22 ++++++++- 3 files changed, 120 insertions(+), 34 deletions(-) diff --git a/drivers/scsi/ufs/ufs-debugfs.c b/drivers/scsi/ufs/ufs-debugfs.c index dee98dc72d29..59729073b569 100644 --- a/drivers/scsi/ufs/ufs-debugfs.c +++ b/drivers/scsi/ufs/ufs-debugfs.c @@ -44,10 +44,56 @@ static int ufs_debugfs_stats_show(struct seq_file *s, void *data) } DEFINE_SHOW_ATTRIBUTE(ufs_debugfs_stats); +static int ee_usr_mask_get(void *data, u64 *val) +{ + struct ufs_hba *hba = data; + + *val = hba->ee_usr_mask; + return 0; +} + +static int ufs_debugfs_get_user_access(struct ufs_hba *hba) +__acquires(&hba->host_sem) +{ + down(&hba->host_sem); + if (!ufshcd_is_user_access_allowed(hba)) { + up(&hba->host_sem); + return -EBUSY; + } + pm_runtime_get_sync(hba->dev); + return 0; +} + +static void ufs_debugfs_put_user_access(struct ufs_hba *hba) +__releases(&hba->host_sem) +{ + pm_runtime_put_sync(hba->dev); + up(&hba->host_sem); +} + +static int ee_usr_mask_set(void *data, u64 val) +{ + struct ufs_hba *hba = data; + int err; + + if (val & ~(u64)MASK_EE_STATUS) + return -EINVAL; + err = ufs_debugfs_get_user_access(hba); + if (err) + return err; + err = ufshcd_update_ee_usr_mask(hba, val, MASK_EE_STATUS); + ufs_debugfs_put_user_access(hba); + return err; +} + +DEFINE_DEBUGFS_ATTRIBUTE(ee_usr_mask_fops, ee_usr_mask_get, ee_usr_mask_set, "%#llx\n"); + void ufs_debugfs_hba_init(struct ufs_hba *hba) { hba->debugfs_root = debugfs_create_dir(dev_name(hba->dev), ufs_debugfs_root); debugfs_create_file("stats", 0400, hba->debugfs_root, hba, &ufs_debugfs_stats_fops); + debugfs_create_file("exception_event_mask", 0600, hba->debugfs_root, + hba, &ee_usr_mask_fops); } void ufs_debugfs_hba_exit(struct ufs_hba *hba) diff --git a/drivers/scsi/ufs/ufshcd.c b/drivers/scsi/ufs/ufshcd.c index 98b4cc085e1e..ac16c9af83b8 100644 --- a/drivers/scsi/ufs/ufshcd.c +++ b/drivers/scsi/ufs/ufshcd.c @@ -5162,6 +5162,46 @@ static irqreturn_t ufshcd_transfer_req_compl(struct ufs_hba *hba) } } +static int __ufshcd_write_ee_control(struct ufs_hba *hba, u32 ee_ctrl_mask) +{ + return ufshcd_query_attr_retry(hba, UPIU_QUERY_OPCODE_WRITE_ATTR, + QUERY_ATTR_IDN_EE_CONTROL, 0, 0, + &ee_ctrl_mask); +} + +static int ufshcd_write_ee_control(struct ufs_hba *hba) +{ + int err; + + mutex_lock(&hba->ee_ctrl_mutex); + err = __ufshcd_write_ee_control(hba, hba->ee_ctrl_mask); + mutex_unlock(&hba->ee_ctrl_mutex); + if (err) + dev_err(hba->dev, "%s: failed to write ee control %d\n", + __func__, err); + return err; +} + +int ufshcd_update_ee_control(struct ufs_hba *hba, u16 *mask, u16 *other_mask, + u16 set, u16 clr) +{ + u16 new_mask, ee_ctrl_mask; + int err = 0; + + mutex_lock(&hba->ee_ctrl_mutex); + new_mask = (*mask & ~clr) | set; + ee_ctrl_mask = new_mask | *other_mask; + if (ee_ctrl_mask != hba->ee_ctrl_mask) + err = __ufshcd_write_ee_control(hba, ee_ctrl_mask); + /* Still need to update 'mask' even if 'ee_ctrl_mask' was unchanged */ + if (!err) { + hba->ee_ctrl_mask = ee_ctrl_mask; + *mask = new_mask; + } + mutex_unlock(&hba->ee_ctrl_mutex); + return err; +} + /** * ufshcd_disable_ee - disable exception event * @hba: per-adapter instance @@ -5172,22 +5212,9 @@ static irqreturn_t ufshcd_transfer_req_compl(struct ufs_hba *hba) * * Returns zero on success, non-zero error value on failure. */ -static int ufshcd_disable_ee(struct ufs_hba *hba, u16 mask) +static inline int ufshcd_disable_ee(struct ufs_hba *hba, u16 mask) { - int err = 0; - u32 val; - - if (!(hba->ee_ctrl_mask & mask)) - goto out; - - val = hba->ee_ctrl_mask & ~mask; - val &= MASK_EE_STATUS; - err = ufshcd_query_attr_retry(hba, UPIU_QUERY_OPCODE_WRITE_ATTR, - QUERY_ATTR_IDN_EE_CONTROL, 0, 0, &val); - if (!err) - hba->ee_ctrl_mask &= ~mask; -out: - return err; + return ufshcd_update_ee_drv_mask(hba, 0, mask); } /** @@ -5200,22 +5227,9 @@ out: * * Returns zero on success, non-zero error value on failure. */ -static int ufshcd_enable_ee(struct ufs_hba *hba, u16 mask) +static inline int ufshcd_enable_ee(struct ufs_hba *hba, u16 mask) { - int err = 0; - u32 val; - - if (hba->ee_ctrl_mask & mask) - goto out; - - val = hba->ee_ctrl_mask | mask; - val &= MASK_EE_STATUS; - err = ufshcd_query_attr_retry(hba, UPIU_QUERY_OPCODE_WRITE_ATTR, - QUERY_ATTR_IDN_EE_CONTROL, 0, 0, &val); - if (!err) - hba->ee_ctrl_mask |= mask; -out: - return err; + return ufshcd_update_ee_drv_mask(hba, mask, 0); } /** @@ -5620,9 +5634,7 @@ static void ufshcd_exception_event_handler(struct work_struct *work) trace_ufshcd_exception_event(dev_name(hba->dev), status); - status &= hba->ee_ctrl_mask; - - if (status & MASK_EE_URGENT_BKOPS) + if (status & hba->ee_drv_mask & MASK_EE_URGENT_BKOPS) ufshcd_bkops_exception_event_handler(hba); out: @@ -7923,6 +7935,8 @@ static int ufshcd_probe_hba(struct ufs_hba *hba, bool async) ufshcd_set_active_icc_lvl(hba); ufshcd_wb_config(hba); + if (hba->ee_usr_mask) + ufshcd_write_ee_control(hba); /* Enable Auto-Hibernate if configured */ ufshcd_auto_hibern8_enable(hba); @@ -8920,6 +8934,9 @@ static int ufshcd_resume(struct ufs_hba *hba, enum ufs_pm_op pm_op) */ ufshcd_urgent_bkops(hba); + if (hba->ee_usr_mask) + ufshcd_write_ee_control(hba); + hba->clk_gating.is_suspended = false; if (ufshcd_is_clkscaling_supported(hba)) @@ -9357,6 +9374,9 @@ int ufshcd_init(struct ufs_hba *hba, void __iomem *mmio_base, unsigned int irq) /* Initialize mutex for device management commands */ mutex_init(&hba->dev_cmd.lock); + /* Initialize mutex for exception event control */ + mutex_init(&hba->ee_ctrl_mutex); + init_rwsem(&hba->clk_scaling_lock); ufshcd_init_clk_gating(hba); diff --git a/drivers/scsi/ufs/ufshcd.h b/drivers/scsi/ufs/ufshcd.h index 18e56c1c1b30..9011a6dee16e 100644 --- a/drivers/scsi/ufs/ufshcd.h +++ b/drivers/scsi/ufs/ufshcd.h @@ -773,7 +773,10 @@ struct ufs_hba { u32 ufshcd_state; u32 eh_flags; u32 intr_mask; - u16 ee_ctrl_mask; + u16 ee_ctrl_mask; /* Exception event mask */ + u16 ee_drv_mask; /* Exception event mask for driver */ + u16 ee_usr_mask; /* Exception event mask for user (via debugfs) */ + struct mutex ee_ctrl_mutex; bool is_powered; bool shutting_down; struct semaphore host_sem; @@ -1285,4 +1288,21 @@ static inline u8 ufshcd_scsi_to_upiu_lun(unsigned int scsi_lun) int ufshcd_dump_regs(struct ufs_hba *hba, size_t offset, size_t len, const char *prefix); +int ufshcd_update_ee_control(struct ufs_hba *hba, u16 *mask, u16 *other_mask, + u16 set, u16 clr); + +static inline int ufshcd_update_ee_drv_mask(struct ufs_hba *hba, + u16 set, u16 clr) +{ + return ufshcd_update_ee_control(hba, &hba->ee_drv_mask, + &hba->ee_usr_mask, set, clr); +} + +static inline int ufshcd_update_ee_usr_mask(struct ufs_hba *hba, + u16 set, u16 clr) +{ + return ufshcd_update_ee_control(hba, &hba->ee_usr_mask, + &hba->ee_drv_mask, set, clr); +} + #endif /* End of Header */ From 7deedfdaeccfec5a9c41dbb83f1725cf11e3ff39 Mon Sep 17 00:00:00 2001 From: Adrian Hunter Date: Tue, 9 Feb 2021 08:24:37 +0200 Subject: [PATCH 004/412] scsi: ufs: ufs-debugfs: Add user-defined exception event rate limiting An enabled user-specified exception event that does not clear quickly will repeatedly cause the handler to run. That could unduly disturb the driver behaviour being tested or debugged. To prevent that add debugfs file exception_event_rate_limit_ms. When a exception event happens, it is disabled, and then after a period of time (default 20ms) the exception event is enabled again. Note that if the driver also has that exception event enabled, it will not be disabled. Link: https://lore.kernel.org/r/20210209062437.6954-5-adrian.hunter@intel.com Acked-by: Bean Huo Signed-off-by: Adrian Hunter Signed-off-by: Martin K. Petersen --- drivers/scsi/ufs/ufs-debugfs.c | 44 ++++++++++++++++++++++++++++++++++ drivers/scsi/ufs/ufs-debugfs.h | 2 ++ drivers/scsi/ufs/ufshcd.c | 5 ++-- drivers/scsi/ufs/ufshcd.h | 4 ++++ 4 files changed, 53 insertions(+), 2 deletions(-) diff --git a/drivers/scsi/ufs/ufs-debugfs.c b/drivers/scsi/ufs/ufs-debugfs.c index 59729073b569..ced9ef4d7c78 100644 --- a/drivers/scsi/ufs/ufs-debugfs.c +++ b/drivers/scsi/ufs/ufs-debugfs.c @@ -88,15 +88,59 @@ static int ee_usr_mask_set(void *data, u64 val) DEFINE_DEBUGFS_ATTRIBUTE(ee_usr_mask_fops, ee_usr_mask_get, ee_usr_mask_set, "%#llx\n"); +void ufs_debugfs_exception_event(struct ufs_hba *hba, u16 status) +{ + bool chgd = false; + u16 ee_ctrl_mask; + int err = 0; + + if (!hba->debugfs_ee_rate_limit_ms || !status) + return; + + mutex_lock(&hba->ee_ctrl_mutex); + ee_ctrl_mask = hba->ee_drv_mask | (hba->ee_usr_mask & ~status); + chgd = ee_ctrl_mask != hba->ee_ctrl_mask; + if (chgd) { + err = __ufshcd_write_ee_control(hba, ee_ctrl_mask); + if (err) + dev_err(hba->dev, "%s: failed to write ee control %d\n", + __func__, err); + } + mutex_unlock(&hba->ee_ctrl_mutex); + + if (chgd && !err) { + unsigned long delay = msecs_to_jiffies(hba->debugfs_ee_rate_limit_ms); + + queue_delayed_work(system_freezable_wq, &hba->debugfs_ee_work, delay); + } +} + +static void ufs_debugfs_restart_ee(struct work_struct *work) +{ + struct ufs_hba *hba = container_of(work, struct ufs_hba, debugfs_ee_work.work); + + if (!hba->ee_usr_mask || pm_runtime_suspended(hba->dev) || + ufs_debugfs_get_user_access(hba)) + return; + ufshcd_write_ee_control(hba); + ufs_debugfs_put_user_access(hba); +} + void ufs_debugfs_hba_init(struct ufs_hba *hba) { + /* Set default exception event rate limit period to 20ms */ + hba->debugfs_ee_rate_limit_ms = 20; + INIT_DELAYED_WORK(&hba->debugfs_ee_work, ufs_debugfs_restart_ee); hba->debugfs_root = debugfs_create_dir(dev_name(hba->dev), ufs_debugfs_root); debugfs_create_file("stats", 0400, hba->debugfs_root, hba, &ufs_debugfs_stats_fops); debugfs_create_file("exception_event_mask", 0600, hba->debugfs_root, hba, &ee_usr_mask_fops); + debugfs_create_u32("exception_event_rate_limit_ms", 0600, hba->debugfs_root, + &hba->debugfs_ee_rate_limit_ms); } void ufs_debugfs_hba_exit(struct ufs_hba *hba) { debugfs_remove_recursive(hba->debugfs_root); + cancel_delayed_work_sync(&hba->debugfs_ee_work); } diff --git a/drivers/scsi/ufs/ufs-debugfs.h b/drivers/scsi/ufs/ufs-debugfs.h index f35b39c4b4f5..3ca29d30460a 100644 --- a/drivers/scsi/ufs/ufs-debugfs.h +++ b/drivers/scsi/ufs/ufs-debugfs.h @@ -12,11 +12,13 @@ void __init ufs_debugfs_init(void); void __exit ufs_debugfs_exit(void); void ufs_debugfs_hba_init(struct ufs_hba *hba); void ufs_debugfs_hba_exit(struct ufs_hba *hba); +void ufs_debugfs_exception_event(struct ufs_hba *hba, u16 status); #else static inline void ufs_debugfs_init(void) {} static inline void ufs_debugfs_exit(void) {} static inline void ufs_debugfs_hba_init(struct ufs_hba *hba) {} static inline void ufs_debugfs_hba_exit(struct ufs_hba *hba) {} +static inline void ufs_debugfs_exception_event(struct ufs_hba *hba, u16 status) {} #endif #endif diff --git a/drivers/scsi/ufs/ufshcd.c b/drivers/scsi/ufs/ufshcd.c index ac16c9af83b8..5c6a364de144 100644 --- a/drivers/scsi/ufs/ufshcd.c +++ b/drivers/scsi/ufs/ufshcd.c @@ -5162,14 +5162,14 @@ static irqreturn_t ufshcd_transfer_req_compl(struct ufs_hba *hba) } } -static int __ufshcd_write_ee_control(struct ufs_hba *hba, u32 ee_ctrl_mask) +int __ufshcd_write_ee_control(struct ufs_hba *hba, u32 ee_ctrl_mask) { return ufshcd_query_attr_retry(hba, UPIU_QUERY_OPCODE_WRITE_ATTR, QUERY_ATTR_IDN_EE_CONTROL, 0, 0, &ee_ctrl_mask); } -static int ufshcd_write_ee_control(struct ufs_hba *hba) +int ufshcd_write_ee_control(struct ufs_hba *hba) { int err; @@ -5637,6 +5637,7 @@ static void ufshcd_exception_event_handler(struct work_struct *work) if (status & hba->ee_drv_mask & MASK_EE_URGENT_BKOPS) ufshcd_bkops_exception_event_handler(hba); + ufs_debugfs_exception_event(hba, status); out: ufshcd_scsi_unblock_requests(hba); /* diff --git a/drivers/scsi/ufs/ufshcd.h b/drivers/scsi/ufs/ufshcd.h index 9011a6dee16e..1af91661dc83 100644 --- a/drivers/scsi/ufs/ufshcd.h +++ b/drivers/scsi/ufs/ufshcd.h @@ -843,6 +843,8 @@ struct ufs_hba { #endif #ifdef CONFIG_DEBUG_FS struct dentry *debugfs_root; + struct delayed_work debugfs_ee_work; + u32 debugfs_ee_rate_limit_ms; #endif }; @@ -1288,6 +1290,8 @@ static inline u8 ufshcd_scsi_to_upiu_lun(unsigned int scsi_lun) int ufshcd_dump_regs(struct ufs_hba *hba, size_t offset, size_t len, const char *prefix); +int __ufshcd_write_ee_control(struct ufs_hba *hba, u32 ee_ctrl_mask); +int ufshcd_write_ee_control(struct ufs_hba *hba); int ufshcd_update_ee_control(struct ufs_hba *hba, u16 *mask, u16 *other_mask, u16 set, u16 clr); From 4ec591790356f0e5a95f8d278b0cfd04aea2ae52 Mon Sep 17 00:00:00 2001 From: Ming Lei Date: Fri, 22 Jan 2021 10:33:05 +0800 Subject: [PATCH 005/412] scsi: sbitmap: Remove sbitmap_clear_bit_unlock No one uses this helper any more, so kill it. Link: https://lore.kernel.org/r/20210122023317.687987-2-ming.lei@redhat.com Cc: Omar Sandoval Cc: Kashyap Desai Cc: Sumanesh Samanta Cc: Ewan D. Milne Cc: Hannes Reinecke Tested-by: Sumanesh Samanta Reviewed-by: Hannes Reinecke Reviewed-by: Johannes Thumshirn Signed-off-by: Ming Lei Signed-off-by: Martin K. Petersen --- include/linux/sbitmap.h | 6 ------ 1 file changed, 6 deletions(-) diff --git a/include/linux/sbitmap.h b/include/linux/sbitmap.h index 74cc6384715e..16353fbee765 100644 --- a/include/linux/sbitmap.h +++ b/include/linux/sbitmap.h @@ -315,12 +315,6 @@ static inline void sbitmap_deferred_clear_bit(struct sbitmap *sb, unsigned int b set_bit(SB_NR_TO_BIT(sb, bitnr), addr); } -static inline void sbitmap_clear_bit_unlock(struct sbitmap *sb, - unsigned int bitnr) -{ - clear_bit_unlock(SB_NR_TO_BIT(sb, bitnr), __sbitmap_word(sb, bitnr)); -} - static inline int sbitmap_test_bit(struct sbitmap *sb, unsigned int bitnr) { return test_bit(SB_NR_TO_BIT(sb, bitnr), __sbitmap_word(sb, bitnr)); From efe1f3a1d5833c0ddd61ee50dbef8908f65a0a5e Mon Sep 17 00:00:00 2001 From: Ming Lei Date: Fri, 22 Jan 2021 10:33:06 +0800 Subject: [PATCH 006/412] scsi: sbitmap: Maintain allocation round_robin in sbitmap Currently the allocation round_robin info is maintained by sbitmap_queue. However, bit allocation really belongs to sbitmap. Move it there. Link: https://lore.kernel.org/r/20210122023317.687987-3-ming.lei@redhat.com Cc: Omar Sandoval Cc: Kashyap Desai Cc: Sumanesh Samanta Cc: Ewan D. Milne Cc: Hannes Reinecke Cc: virtualization@lists.linux-foundation.org Tested-by: Sumanesh Samanta Reviewed-by: Hannes Reinecke Signed-off-by: Ming Lei Signed-off-by: Martin K. Petersen --- block/blk-mq.c | 2 +- block/kyber-iosched.c | 3 ++- drivers/vhost/scsi.c | 4 ++-- include/linux/sbitmap.h | 20 ++++++++++---------- lib/sbitmap.c | 28 ++++++++++++++-------------- 5 files changed, 29 insertions(+), 28 deletions(-) diff --git a/block/blk-mq.c b/block/blk-mq.c index d4d7c1caa439..f133bbfa6cd4 100644 --- a/block/blk-mq.c +++ b/block/blk-mq.c @@ -2702,7 +2702,7 @@ blk_mq_alloc_hctx(struct request_queue *q, struct blk_mq_tag_set *set, goto free_cpumask; if (sbitmap_init_node(&hctx->ctx_map, nr_cpu_ids, ilog2(8), - gfp, node)) + gfp, node, false)) goto free_ctxs; hctx->nr_ctx = 0; diff --git a/block/kyber-iosched.c b/block/kyber-iosched.c index 33d34d69cade..d39ac13f0105 100644 --- a/block/kyber-iosched.c +++ b/block/kyber-iosched.c @@ -478,7 +478,8 @@ static int kyber_init_hctx(struct blk_mq_hw_ctx *hctx, unsigned int hctx_idx) for (i = 0; i < KYBER_NUM_DOMAINS; i++) { if (sbitmap_init_node(&khd->kcq_map[i], hctx->nr_ctx, - ilog2(8), GFP_KERNEL, hctx->numa_node)) { + ilog2(8), GFP_KERNEL, hctx->numa_node, + false)) { while (--i >= 0) sbitmap_free(&khd->kcq_map[i]); goto err_kcqs; diff --git a/drivers/vhost/scsi.c b/drivers/vhost/scsi.c index 5de21ad4bd05..3412a3ad28e6 100644 --- a/drivers/vhost/scsi.c +++ b/drivers/vhost/scsi.c @@ -614,7 +614,7 @@ vhost_scsi_get_cmd(struct vhost_virtqueue *vq, struct vhost_scsi_tpg *tpg, return ERR_PTR(-EIO); } - tag = sbitmap_get(&svq->scsi_tags, 0, false); + tag = sbitmap_get(&svq->scsi_tags, 0); if (tag < 0) { pr_err("Unable to obtain tag for vhost_scsi_cmd\n"); return ERR_PTR(-ENOMEM); @@ -1512,7 +1512,7 @@ static int vhost_scsi_setup_vq_cmds(struct vhost_virtqueue *vq, int max_cmds) return 0; if (sbitmap_init_node(&svq->scsi_tags, max_cmds, -1, GFP_KERNEL, - NUMA_NO_NODE)) + NUMA_NO_NODE, false)) return -ENOMEM; svq->max_cmds = max_cmds; diff --git a/include/linux/sbitmap.h b/include/linux/sbitmap.h index 16353fbee765..734ee6214cd6 100644 --- a/include/linux/sbitmap.h +++ b/include/linux/sbitmap.h @@ -56,6 +56,11 @@ struct sbitmap { */ unsigned int map_nr; + /** + * @round_robin: Allocate bits in strict round-robin order. + */ + bool round_robin; + /** * @map: Allocated bitmap. */ @@ -124,11 +129,6 @@ struct sbitmap_queue { */ atomic_t ws_active; - /** - * @round_robin: Allocate bits in strict round-robin order. - */ - bool round_robin; - /** * @min_shallow_depth: The minimum shallow depth which may be passed to * sbitmap_queue_get_shallow() or __sbitmap_queue_get_shallow(). @@ -144,11 +144,14 @@ struct sbitmap_queue { * given, a good default is chosen. * @flags: Allocation flags. * @node: Memory node to allocate on. + * @round_robin: If true, be stricter about allocation order; always allocate + * starting from the last allocated bit. This is less efficient + * than the default behavior (false). * * Return: Zero on success or negative errno on failure. */ int sbitmap_init_node(struct sbitmap *sb, unsigned int depth, int shift, - gfp_t flags, int node); + gfp_t flags, int node, bool round_robin); /** * sbitmap_free() - Free memory used by a &struct sbitmap. @@ -174,15 +177,12 @@ void sbitmap_resize(struct sbitmap *sb, unsigned int depth); * sbitmap_get() - Try to allocate a free bit from a &struct sbitmap. * @sb: Bitmap to allocate from. * @alloc_hint: Hint for where to start searching for a free bit. - * @round_robin: If true, be stricter about allocation order; always allocate - * starting from the last allocated bit. This is less efficient - * than the default behavior (false). * * This operation provides acquire barrier semantics if it succeeds. * * Return: Non-negative allocated bit number if successful, -1 otherwise. */ -int sbitmap_get(struct sbitmap *sb, unsigned int alloc_hint, bool round_robin); +int sbitmap_get(struct sbitmap *sb, unsigned int alloc_hint); /** * sbitmap_get_shallow() - Try to allocate a free bit from a &struct sbitmap, diff --git a/lib/sbitmap.c b/lib/sbitmap.c index d693d9213ceb..7000636933b3 100644 --- a/lib/sbitmap.c +++ b/lib/sbitmap.c @@ -33,7 +33,7 @@ static inline bool sbitmap_deferred_clear(struct sbitmap_word *map) } int sbitmap_init_node(struct sbitmap *sb, unsigned int depth, int shift, - gfp_t flags, int node) + gfp_t flags, int node, bool round_robin) { unsigned int bits_per_word; unsigned int i; @@ -58,6 +58,7 @@ int sbitmap_init_node(struct sbitmap *sb, unsigned int depth, int shift, sb->shift = shift; sb->depth = depth; sb->map_nr = DIV_ROUND_UP(sb->depth, bits_per_word); + sb->round_robin = round_robin; if (depth == 0) { sb->map = NULL; @@ -129,14 +130,14 @@ static int __sbitmap_get_word(unsigned long *word, unsigned long depth, } static int sbitmap_find_bit_in_index(struct sbitmap *sb, int index, - unsigned int alloc_hint, bool round_robin) + unsigned int alloc_hint) { struct sbitmap_word *map = &sb->map[index]; int nr; do { nr = __sbitmap_get_word(&map->word, map->depth, alloc_hint, - !round_robin); + !sb->round_robin); if (nr != -1) break; if (!sbitmap_deferred_clear(map)) @@ -146,7 +147,7 @@ static int sbitmap_find_bit_in_index(struct sbitmap *sb, int index, return nr; } -int sbitmap_get(struct sbitmap *sb, unsigned int alloc_hint, bool round_robin) +int sbitmap_get(struct sbitmap *sb, unsigned int alloc_hint) { unsigned int i, index; int nr = -1; @@ -158,14 +159,13 @@ int sbitmap_get(struct sbitmap *sb, unsigned int alloc_hint, bool round_robin) * alloc_hint to find the right word index. No point in looping * twice in find_next_zero_bit() for that case. */ - if (round_robin) + if (sb->round_robin) alloc_hint = SB_NR_TO_BIT(sb, alloc_hint); else alloc_hint = 0; for (i = 0; i < sb->map_nr; i++) { - nr = sbitmap_find_bit_in_index(sb, index, alloc_hint, - round_robin); + nr = sbitmap_find_bit_in_index(sb, index, alloc_hint); if (nr != -1) { nr += index << sb->shift; break; @@ -350,7 +350,8 @@ int sbitmap_queue_init_node(struct sbitmap_queue *sbq, unsigned int depth, int ret; int i; - ret = sbitmap_init_node(&sbq->sb, depth, shift, flags, node); + ret = sbitmap_init_node(&sbq->sb, depth, shift, flags, node, + round_robin); if (ret) return ret; @@ -382,7 +383,6 @@ int sbitmap_queue_init_node(struct sbitmap_queue *sbq, unsigned int depth, atomic_set(&sbq->ws[i].wait_cnt, sbq->wake_batch); } - sbq->round_robin = round_robin; return 0; } EXPORT_SYMBOL_GPL(sbitmap_queue_init_node); @@ -424,12 +424,12 @@ int __sbitmap_queue_get(struct sbitmap_queue *sbq) hint = depth ? prandom_u32() % depth : 0; this_cpu_write(*sbq->alloc_hint, hint); } - nr = sbitmap_get(&sbq->sb, hint, sbq->round_robin); + nr = sbitmap_get(&sbq->sb, hint); if (nr == -1) { /* If the map is full, a hint won't do us much good. */ this_cpu_write(*sbq->alloc_hint, 0); - } else if (nr == hint || unlikely(sbq->round_robin)) { + } else if (nr == hint || unlikely(sbq->sb.round_robin)) { /* Only update the hint if we used it. */ hint = nr + 1; if (hint >= depth - 1) @@ -460,7 +460,7 @@ int __sbitmap_queue_get_shallow(struct sbitmap_queue *sbq, if (nr == -1) { /* If the map is full, a hint won't do us much good. */ this_cpu_write(*sbq->alloc_hint, 0); - } else if (nr == hint || unlikely(sbq->round_robin)) { + } else if (nr == hint || unlikely(sbq->sb.round_robin)) { /* Only update the hint if we used it. */ hint = nr + 1; if (hint >= depth - 1) @@ -576,7 +576,7 @@ void sbitmap_queue_clear(struct sbitmap_queue *sbq, unsigned int nr, smp_mb__after_atomic(); sbitmap_queue_wake_up(sbq); - if (likely(!sbq->round_robin && nr < sbq->sb.depth)) + if (likely(!sbq->sb.round_robin && nr < sbq->sb.depth)) *per_cpu_ptr(sbq->alloc_hint, cpu) = nr; } EXPORT_SYMBOL_GPL(sbitmap_queue_clear); @@ -633,7 +633,7 @@ void sbitmap_queue_show(struct sbitmap_queue *sbq, struct seq_file *m) } seq_puts(m, "}\n"); - seq_printf(m, "round_robin=%d\n", sbq->round_robin); + seq_printf(m, "round_robin=%d\n", sbq->sb.round_robin); seq_printf(m, "min_shallow_depth=%u\n", sbq->min_shallow_depth); } EXPORT_SYMBOL_GPL(sbitmap_queue_show); From bf2c4282a10a92810ba83e85677a5273d6ca0df5 Mon Sep 17 00:00:00 2001 From: Ming Lei Date: Fri, 22 Jan 2021 10:33:07 +0800 Subject: [PATCH 007/412] scsi: sbitmap: Add helpers for updating allocation hint Add helpers for updating allocation hint so that we can avoid duplicate code. Prepare for moving allocation hint into sbitmap. Link: https://lore.kernel.org/r/20210122023317.687987-4-ming.lei@redhat.com Cc: Omar Sandoval Cc: Kashyap Desai Cc: Sumanesh Samanta Cc: Ewan D. Milne Cc: Hannes Reinecke Tested-by: Sumanesh Samanta Reviewed-by: Hannes Reinecke Signed-off-by: Ming Lei Signed-off-by: Martin K. Petersen --- lib/sbitmap.c | 93 ++++++++++++++++++++++++++++++--------------------- 1 file changed, 54 insertions(+), 39 deletions(-) diff --git a/lib/sbitmap.c b/lib/sbitmap.c index 7000636933b3..2b43a6aefec3 100644 --- a/lib/sbitmap.c +++ b/lib/sbitmap.c @@ -9,6 +9,55 @@ #include #include +static int init_alloc_hint(struct sbitmap_queue *sbq, gfp_t flags) +{ + unsigned depth = sbq->sb.depth; + + sbq->alloc_hint = alloc_percpu_gfp(unsigned int, flags); + if (!sbq->alloc_hint) + return -ENOMEM; + + if (depth && !sbq->sb.round_robin) { + int i; + + for_each_possible_cpu(i) + *per_cpu_ptr(sbq->alloc_hint, i) = prandom_u32() % depth; + } + + return 0; +} + +static inline unsigned update_alloc_hint_before_get(struct sbitmap_queue *sbq, + unsigned int depth) +{ + unsigned hint; + + hint = this_cpu_read(*sbq->alloc_hint); + if (unlikely(hint >= depth)) { + hint = depth ? prandom_u32() % depth : 0; + this_cpu_write(*sbq->alloc_hint, hint); + } + + return hint; +} + +static inline void update_alloc_hint_after_get(struct sbitmap_queue *sbq, + unsigned int depth, + unsigned int hint, + unsigned int nr) +{ + if (nr == -1) { + /* If the map is full, a hint won't do us much good. */ + this_cpu_write(*sbq->alloc_hint, 0); + } else if (nr == hint || unlikely(sbq->sb.round_robin)) { + /* Only update the hint if we used it. */ + hint = nr + 1; + if (hint >= depth - 1) + hint = 0; + this_cpu_write(*sbq->alloc_hint, hint); + } +} + /* * See if we have deferred clears that we can batch move */ @@ -355,17 +404,11 @@ int sbitmap_queue_init_node(struct sbitmap_queue *sbq, unsigned int depth, if (ret) return ret; - sbq->alloc_hint = alloc_percpu_gfp(unsigned int, flags); - if (!sbq->alloc_hint) { + if (init_alloc_hint(sbq, flags) != 0) { sbitmap_free(&sbq->sb); return -ENOMEM; } - if (depth && !round_robin) { - for_each_possible_cpu(i) - *per_cpu_ptr(sbq->alloc_hint, i) = prandom_u32() % depth; - } - sbq->min_shallow_depth = UINT_MAX; sbq->wake_batch = sbq_calc_wake_batch(sbq, depth); atomic_set(&sbq->wake_index, 0); @@ -418,24 +461,10 @@ int __sbitmap_queue_get(struct sbitmap_queue *sbq) unsigned int hint, depth; int nr; - hint = this_cpu_read(*sbq->alloc_hint); depth = READ_ONCE(sbq->sb.depth); - if (unlikely(hint >= depth)) { - hint = depth ? prandom_u32() % depth : 0; - this_cpu_write(*sbq->alloc_hint, hint); - } + hint = update_alloc_hint_before_get(sbq, depth); nr = sbitmap_get(&sbq->sb, hint); - - if (nr == -1) { - /* If the map is full, a hint won't do us much good. */ - this_cpu_write(*sbq->alloc_hint, 0); - } else if (nr == hint || unlikely(sbq->sb.round_robin)) { - /* Only update the hint if we used it. */ - hint = nr + 1; - if (hint >= depth - 1) - hint = 0; - this_cpu_write(*sbq->alloc_hint, hint); - } + update_alloc_hint_after_get(sbq, depth, hint, nr); return nr; } @@ -449,24 +478,10 @@ int __sbitmap_queue_get_shallow(struct sbitmap_queue *sbq, WARN_ON_ONCE(shallow_depth < sbq->min_shallow_depth); - hint = this_cpu_read(*sbq->alloc_hint); depth = READ_ONCE(sbq->sb.depth); - if (unlikely(hint >= depth)) { - hint = depth ? prandom_u32() % depth : 0; - this_cpu_write(*sbq->alloc_hint, hint); - } + hint = update_alloc_hint_before_get(sbq, depth); nr = sbitmap_get_shallow(&sbq->sb, hint, shallow_depth); - - if (nr == -1) { - /* If the map is full, a hint won't do us much good. */ - this_cpu_write(*sbq->alloc_hint, 0); - } else if (nr == hint || unlikely(sbq->sb.round_robin)) { - /* Only update the hint if we used it. */ - hint = nr + 1; - if (hint >= depth - 1) - hint = 0; - this_cpu_write(*sbq->alloc_hint, hint); - } + update_alloc_hint_after_get(sbq, depth, hint, nr); return nr; } From c548e62bcf6adc7066ff201e9ecc88e536dd8890 Mon Sep 17 00:00:00 2001 From: Ming Lei Date: Fri, 22 Jan 2021 10:33:08 +0800 Subject: [PATCH 008/412] scsi: sbitmap: Move allocation hint into sbitmap Allocation hint should have belonged to sbitmap. Also, when sbitmap's depth is high and there is no need to use mulitple wakeup queues, user can benefit from percpu allocation hint too. Move allocation hint into sbitmap, then SCSI device queue can benefit from allocation hint when converting to plain sbitmap. Convert vhost/scsi.c to use sbitmap allocation with percpu alloc hint. This is more efficient than the previous approach. Link: https://lore.kernel.org/r/20210122023317.687987-5-ming.lei@redhat.com Cc: Omar Sandoval Cc: Kashyap Desai Cc: Sumanesh Samanta Cc: Ewan D. Milne Cc: Mike Christie Cc: virtualization@lists.linux-foundation.org Tested-by: Sumanesh Samanta Reviewed-by: Hannes Reinecke Signed-off-by: Ming Lei Signed-off-by: Martin K. Petersen --- block/blk-mq.c | 2 +- block/kyber-iosched.c | 2 +- drivers/vhost/scsi.c | 4 +- include/linux/sbitmap.h | 41 +++++++++------ lib/sbitmap.c | 112 +++++++++++++++++++++++----------------- 5 files changed, 96 insertions(+), 65 deletions(-) diff --git a/block/blk-mq.c b/block/blk-mq.c index f133bbfa6cd4..2e8c94e00f58 100644 --- a/block/blk-mq.c +++ b/block/blk-mq.c @@ -2702,7 +2702,7 @@ blk_mq_alloc_hctx(struct request_queue *q, struct blk_mq_tag_set *set, goto free_cpumask; if (sbitmap_init_node(&hctx->ctx_map, nr_cpu_ids, ilog2(8), - gfp, node, false)) + gfp, node, false, false)) goto free_ctxs; hctx->nr_ctx = 0; diff --git a/block/kyber-iosched.c b/block/kyber-iosched.c index d39ac13f0105..8969e122f081 100644 --- a/block/kyber-iosched.c +++ b/block/kyber-iosched.c @@ -479,7 +479,7 @@ static int kyber_init_hctx(struct blk_mq_hw_ctx *hctx, unsigned int hctx_idx) for (i = 0; i < KYBER_NUM_DOMAINS; i++) { if (sbitmap_init_node(&khd->kcq_map[i], hctx->nr_ctx, ilog2(8), GFP_KERNEL, hctx->numa_node, - false)) { + false, false)) { while (--i >= 0) sbitmap_free(&khd->kcq_map[i]); goto err_kcqs; diff --git a/drivers/vhost/scsi.c b/drivers/vhost/scsi.c index 3412a3ad28e6..936584250a0b 100644 --- a/drivers/vhost/scsi.c +++ b/drivers/vhost/scsi.c @@ -614,7 +614,7 @@ vhost_scsi_get_cmd(struct vhost_virtqueue *vq, struct vhost_scsi_tpg *tpg, return ERR_PTR(-EIO); } - tag = sbitmap_get(&svq->scsi_tags, 0); + tag = sbitmap_get(&svq->scsi_tags); if (tag < 0) { pr_err("Unable to obtain tag for vhost_scsi_cmd\n"); return ERR_PTR(-ENOMEM); @@ -1512,7 +1512,7 @@ static int vhost_scsi_setup_vq_cmds(struct vhost_virtqueue *vq, int max_cmds) return 0; if (sbitmap_init_node(&svq->scsi_tags, max_cmds, -1, GFP_KERNEL, - NUMA_NO_NODE, false)) + NUMA_NO_NODE, false, true)) return -ENOMEM; svq->max_cmds = max_cmds; diff --git a/include/linux/sbitmap.h b/include/linux/sbitmap.h index 734ee6214cd6..247776fcc02c 100644 --- a/include/linux/sbitmap.h +++ b/include/linux/sbitmap.h @@ -65,6 +65,14 @@ struct sbitmap { * @map: Allocated bitmap. */ struct sbitmap_word *map; + + /* + * @alloc_hint: Cache of last successfully allocated or freed bit. + * + * This is per-cpu, which allows multiple users to stick to different + * cachelines until the map is exhausted. + */ + unsigned int __percpu *alloc_hint; }; #define SBQ_WAIT_QUEUES 8 @@ -100,14 +108,6 @@ struct sbitmap_queue { */ struct sbitmap sb; - /* - * @alloc_hint: Cache of last successfully allocated or freed bit. - * - * This is per-cpu, which allows multiple users to stick to different - * cachelines until the map is exhausted. - */ - unsigned int __percpu *alloc_hint; - /** * @wake_batch: Number of bits which must be freed before we wake up any * waiters. @@ -147,11 +147,13 @@ struct sbitmap_queue { * @round_robin: If true, be stricter about allocation order; always allocate * starting from the last allocated bit. This is less efficient * than the default behavior (false). + * @alloc_hint: If true, apply percpu hint for where to start searching for + * a free bit. * * Return: Zero on success or negative errno on failure. */ int sbitmap_init_node(struct sbitmap *sb, unsigned int depth, int shift, - gfp_t flags, int node, bool round_robin); + gfp_t flags, int node, bool round_robin, bool alloc_hint); /** * sbitmap_free() - Free memory used by a &struct sbitmap. @@ -159,6 +161,7 @@ int sbitmap_init_node(struct sbitmap *sb, unsigned int depth, int shift, */ static inline void sbitmap_free(struct sbitmap *sb) { + free_percpu(sb->alloc_hint); kfree(sb->map); sb->map = NULL; } @@ -176,19 +179,17 @@ void sbitmap_resize(struct sbitmap *sb, unsigned int depth); /** * sbitmap_get() - Try to allocate a free bit from a &struct sbitmap. * @sb: Bitmap to allocate from. - * @alloc_hint: Hint for where to start searching for a free bit. * * This operation provides acquire barrier semantics if it succeeds. * * Return: Non-negative allocated bit number if successful, -1 otherwise. */ -int sbitmap_get(struct sbitmap *sb, unsigned int alloc_hint); +int sbitmap_get(struct sbitmap *sb); /** * sbitmap_get_shallow() - Try to allocate a free bit from a &struct sbitmap, * limiting the depth used from each word. * @sb: Bitmap to allocate from. - * @alloc_hint: Hint for where to start searching for a free bit. * @shallow_depth: The maximum number of bits to allocate from a single word. * * This rather specific operation allows for having multiple users with @@ -200,8 +201,7 @@ int sbitmap_get(struct sbitmap *sb, unsigned int alloc_hint); * * Return: Non-negative allocated bit number if successful, -1 otherwise. */ -int sbitmap_get_shallow(struct sbitmap *sb, unsigned int alloc_hint, - unsigned long shallow_depth); +int sbitmap_get_shallow(struct sbitmap *sb, unsigned long shallow_depth); /** * sbitmap_any_bit_set() - Check for a set bit in a &struct sbitmap. @@ -315,6 +315,18 @@ static inline void sbitmap_deferred_clear_bit(struct sbitmap *sb, unsigned int b set_bit(SB_NR_TO_BIT(sb, bitnr), addr); } +/* + * Pair of sbitmap_get, and this one applies both cleared bit and + * allocation hint. + */ +static inline void sbitmap_put(struct sbitmap *sb, unsigned int bitnr) +{ + sbitmap_deferred_clear_bit(sb, bitnr); + + if (likely(sb->alloc_hint && !sb->round_robin && bitnr < sb->depth)) + *this_cpu_ptr(sb->alloc_hint) = bitnr; +} + static inline int sbitmap_test_bit(struct sbitmap *sb, unsigned int bitnr) { return test_bit(SB_NR_TO_BIT(sb, bitnr), __sbitmap_word(sb, bitnr)); @@ -363,7 +375,6 @@ int sbitmap_queue_init_node(struct sbitmap_queue *sbq, unsigned int depth, static inline void sbitmap_queue_free(struct sbitmap_queue *sbq) { kfree(sbq->ws); - free_percpu(sbq->alloc_hint); sbitmap_free(&sbq->sb); } diff --git a/lib/sbitmap.c b/lib/sbitmap.c index 2b43a6aefec3..e395435654aa 100644 --- a/lib/sbitmap.c +++ b/lib/sbitmap.c @@ -9,52 +9,51 @@ #include #include -static int init_alloc_hint(struct sbitmap_queue *sbq, gfp_t flags) +static int init_alloc_hint(struct sbitmap *sb, gfp_t flags) { - unsigned depth = sbq->sb.depth; + unsigned depth = sb->depth; - sbq->alloc_hint = alloc_percpu_gfp(unsigned int, flags); - if (!sbq->alloc_hint) + sb->alloc_hint = alloc_percpu_gfp(unsigned int, flags); + if (!sb->alloc_hint) return -ENOMEM; - if (depth && !sbq->sb.round_robin) { + if (depth && !sb->round_robin) { int i; for_each_possible_cpu(i) - *per_cpu_ptr(sbq->alloc_hint, i) = prandom_u32() % depth; + *per_cpu_ptr(sb->alloc_hint, i) = prandom_u32() % depth; } - return 0; } -static inline unsigned update_alloc_hint_before_get(struct sbitmap_queue *sbq, +static inline unsigned update_alloc_hint_before_get(struct sbitmap *sb, unsigned int depth) { unsigned hint; - hint = this_cpu_read(*sbq->alloc_hint); + hint = this_cpu_read(*sb->alloc_hint); if (unlikely(hint >= depth)) { hint = depth ? prandom_u32() % depth : 0; - this_cpu_write(*sbq->alloc_hint, hint); + this_cpu_write(*sb->alloc_hint, hint); } return hint; } -static inline void update_alloc_hint_after_get(struct sbitmap_queue *sbq, +static inline void update_alloc_hint_after_get(struct sbitmap *sb, unsigned int depth, unsigned int hint, unsigned int nr) { if (nr == -1) { /* If the map is full, a hint won't do us much good. */ - this_cpu_write(*sbq->alloc_hint, 0); - } else if (nr == hint || unlikely(sbq->sb.round_robin)) { + this_cpu_write(*sb->alloc_hint, 0); + } else if (nr == hint || unlikely(sb->round_robin)) { /* Only update the hint if we used it. */ hint = nr + 1; if (hint >= depth - 1) hint = 0; - this_cpu_write(*sbq->alloc_hint, hint); + this_cpu_write(*sb->alloc_hint, hint); } } @@ -82,7 +81,8 @@ static inline bool sbitmap_deferred_clear(struct sbitmap_word *map) } int sbitmap_init_node(struct sbitmap *sb, unsigned int depth, int shift, - gfp_t flags, int node, bool round_robin) + gfp_t flags, int node, bool round_robin, + bool alloc_hint) { unsigned int bits_per_word; unsigned int i; @@ -114,9 +114,18 @@ int sbitmap_init_node(struct sbitmap *sb, unsigned int depth, int shift, return 0; } + if (alloc_hint) { + if (init_alloc_hint(sb, flags)) + return -ENOMEM; + } else { + sb->alloc_hint = NULL; + } + sb->map = kcalloc_node(sb->map_nr, sizeof(*sb->map), flags, node); - if (!sb->map) + if (!sb->map) { + free_percpu(sb->alloc_hint); return -ENOMEM; + } for (i = 0; i < sb->map_nr; i++) { sb->map[i].depth = min(depth, bits_per_word); @@ -196,7 +205,7 @@ static int sbitmap_find_bit_in_index(struct sbitmap *sb, int index, return nr; } -int sbitmap_get(struct sbitmap *sb, unsigned int alloc_hint) +static int __sbitmap_get(struct sbitmap *sb, unsigned int alloc_hint) { unsigned int i, index; int nr = -1; @@ -228,10 +237,27 @@ int sbitmap_get(struct sbitmap *sb, unsigned int alloc_hint) return nr; } + +int sbitmap_get(struct sbitmap *sb) +{ + int nr; + unsigned int hint, depth; + + if (WARN_ON_ONCE(unlikely(!sb->alloc_hint))) + return -1; + + depth = READ_ONCE(sb->depth); + hint = update_alloc_hint_before_get(sb, depth); + nr = __sbitmap_get(sb, hint); + update_alloc_hint_after_get(sb, depth, hint, nr); + + return nr; +} EXPORT_SYMBOL_GPL(sbitmap_get); -int sbitmap_get_shallow(struct sbitmap *sb, unsigned int alloc_hint, - unsigned long shallow_depth) +static int __sbitmap_get_shallow(struct sbitmap *sb, + unsigned int alloc_hint, + unsigned long shallow_depth) { unsigned int i, index; int nr = -1; @@ -263,6 +289,22 @@ again: return nr; } + +int sbitmap_get_shallow(struct sbitmap *sb, unsigned long shallow_depth) +{ + int nr; + unsigned int hint, depth; + + if (WARN_ON_ONCE(unlikely(!sb->alloc_hint))) + return -1; + + depth = READ_ONCE(sb->depth); + hint = update_alloc_hint_before_get(sb, depth); + nr = __sbitmap_get_shallow(sb, hint, shallow_depth); + update_alloc_hint_after_get(sb, depth, hint, nr); + + return nr; +} EXPORT_SYMBOL_GPL(sbitmap_get_shallow); bool sbitmap_any_bit_set(const struct sbitmap *sb) @@ -400,15 +442,10 @@ int sbitmap_queue_init_node(struct sbitmap_queue *sbq, unsigned int depth, int i; ret = sbitmap_init_node(&sbq->sb, depth, shift, flags, node, - round_robin); + round_robin, true); if (ret) return ret; - if (init_alloc_hint(sbq, flags) != 0) { - sbitmap_free(&sbq->sb); - return -ENOMEM; - } - sbq->min_shallow_depth = UINT_MAX; sbq->wake_batch = sbq_calc_wake_batch(sbq, depth); atomic_set(&sbq->wake_index, 0); @@ -416,7 +453,6 @@ int sbitmap_queue_init_node(struct sbitmap_queue *sbq, unsigned int depth, sbq->ws = kzalloc_node(SBQ_WAIT_QUEUES * sizeof(*sbq->ws), flags, node); if (!sbq->ws) { - free_percpu(sbq->alloc_hint); sbitmap_free(&sbq->sb); return -ENOMEM; } @@ -458,32 +494,16 @@ EXPORT_SYMBOL_GPL(sbitmap_queue_resize); int __sbitmap_queue_get(struct sbitmap_queue *sbq) { - unsigned int hint, depth; - int nr; - - depth = READ_ONCE(sbq->sb.depth); - hint = update_alloc_hint_before_get(sbq, depth); - nr = sbitmap_get(&sbq->sb, hint); - update_alloc_hint_after_get(sbq, depth, hint, nr); - - return nr; + return sbitmap_get(&sbq->sb); } EXPORT_SYMBOL_GPL(__sbitmap_queue_get); int __sbitmap_queue_get_shallow(struct sbitmap_queue *sbq, unsigned int shallow_depth) { - unsigned int hint, depth; - int nr; - WARN_ON_ONCE(shallow_depth < sbq->min_shallow_depth); - depth = READ_ONCE(sbq->sb.depth); - hint = update_alloc_hint_before_get(sbq, depth); - nr = sbitmap_get_shallow(&sbq->sb, hint, shallow_depth); - update_alloc_hint_after_get(sbq, depth, hint, nr); - - return nr; + return sbitmap_get_shallow(&sbq->sb, shallow_depth); } EXPORT_SYMBOL_GPL(__sbitmap_queue_get_shallow); @@ -592,7 +612,7 @@ void sbitmap_queue_clear(struct sbitmap_queue *sbq, unsigned int nr, sbitmap_queue_wake_up(sbq); if (likely(!sbq->sb.round_robin && nr < sbq->sb.depth)) - *per_cpu_ptr(sbq->alloc_hint, cpu) = nr; + *per_cpu_ptr(sbq->sb.alloc_hint, cpu) = nr; } EXPORT_SYMBOL_GPL(sbitmap_queue_clear); @@ -630,7 +650,7 @@ void sbitmap_queue_show(struct sbitmap_queue *sbq, struct seq_file *m) if (!first) seq_puts(m, ", "); first = false; - seq_printf(m, "%u", *per_cpu_ptr(sbq->alloc_hint, i)); + seq_printf(m, "%u", *per_cpu_ptr(sbq->sb.alloc_hint, i)); } seq_puts(m, "}\n"); From cbb9950b41dd9dfb7c2be3429ba09f83b8b1ff98 Mon Sep 17 00:00:00 2001 From: Ming Lei Date: Fri, 22 Jan 2021 10:33:09 +0800 Subject: [PATCH 009/412] scsi: sbitmap: Export sbitmap_weight SCSI's .device_busy will be converted to sbitmap and sbitmap_weight is needed. Export the helper. The only existing user of sbitmap_weight() uses it to find out how many bits are set and not cleared. Align sbitmap_weight() meaning with this usage model. Link: https://lore.kernel.org/r/20210122023317.687987-6-ming.lei@redhat.com Cc: Omar Sandoval Cc: Kashyap Desai Cc: Sumanesh Samanta Cc: Ewan D. Milne Tested-by: Sumanesh Samanta Reviewed-by: Hannes Reinecke Signed-off-by: Ming Lei Signed-off-by: Martin K. Petersen --- include/linux/sbitmap.h | 10 ++++++++++ lib/sbitmap.c | 13 +++++++------ 2 files changed, 17 insertions(+), 6 deletions(-) diff --git a/include/linux/sbitmap.h b/include/linux/sbitmap.h index 247776fcc02c..c65ba887dcc3 100644 --- a/include/linux/sbitmap.h +++ b/include/linux/sbitmap.h @@ -341,6 +341,16 @@ static inline int sbitmap_test_bit(struct sbitmap *sb, unsigned int bitnr) */ void sbitmap_show(struct sbitmap *sb, struct seq_file *m); + +/** + * sbitmap_weight() - Return how many set and not cleared bits in a &struct + * sbitmap. + * @sb: Bitmap to check. + * + * Return: How many set and not cleared bits set + */ +unsigned int sbitmap_weight(const struct sbitmap *sb); + /** * sbitmap_bitmap_show() - Write a hex dump of a &struct sbitmap to a &struct * seq_file. diff --git a/lib/sbitmap.c b/lib/sbitmap.c index e395435654aa..73da26ad021e 100644 --- a/lib/sbitmap.c +++ b/lib/sbitmap.c @@ -334,20 +334,21 @@ static unsigned int __sbitmap_weight(const struct sbitmap *sb, bool set) return weight; } -static unsigned int sbitmap_weight(const struct sbitmap *sb) -{ - return __sbitmap_weight(sb, true); -} - static unsigned int sbitmap_cleared(const struct sbitmap *sb) { return __sbitmap_weight(sb, false); } +unsigned int sbitmap_weight(const struct sbitmap *sb) +{ + return __sbitmap_weight(sb, true) - sbitmap_cleared(sb); +} +EXPORT_SYMBOL_GPL(sbitmap_weight); + void sbitmap_show(struct sbitmap *sb, struct seq_file *m) { seq_printf(m, "depth=%u\n", sb->depth); - seq_printf(m, "busy=%u\n", sbitmap_weight(sb) - sbitmap_cleared(sb)); + seq_printf(m, "busy=%u\n", sbitmap_weight(sb)); seq_printf(m, "cleared=%u\n", sbitmap_cleared(sb)); seq_printf(m, "bits_per_word=%u\n", 1U << sb->shift); seq_printf(m, "map_nr=%u\n", sb->map_nr); From 2d13b1ea9f4affdaa7af0e0e4a1358d28f80c54f Mon Sep 17 00:00:00 2001 From: Ming Lei Date: Fri, 22 Jan 2021 10:33:10 +0800 Subject: [PATCH 010/412] scsi: sbitmap: Add sbitmap_calculate_shift() helper Move code for calculating default shift into a public helper which can be used by SCSI. Link: https://lore.kernel.org/r/20210122023317.687987-7-ming.lei@redhat.com Cc: Omar Sandoval Cc: Kashyap Desai Cc: Sumanesh Samanta Cc: Ewan D. Milne Tested-by: Sumanesh Samanta Reviewed-by: Hannes Reinecke Signed-off-by: Ming Lei Signed-off-by: Martin K. Petersen --- include/linux/sbitmap.h | 18 ++++++++++++++++++ lib/sbitmap.c | 16 +++------------- 2 files changed, 21 insertions(+), 13 deletions(-) diff --git a/include/linux/sbitmap.h b/include/linux/sbitmap.h index c65ba887dcc3..3087e1f15fdd 100644 --- a/include/linux/sbitmap.h +++ b/include/linux/sbitmap.h @@ -332,6 +332,24 @@ static inline int sbitmap_test_bit(struct sbitmap *sb, unsigned int bitnr) return test_bit(SB_NR_TO_BIT(sb, bitnr), __sbitmap_word(sb, bitnr)); } +static inline int sbitmap_calculate_shift(unsigned int depth) +{ + int shift = ilog2(BITS_PER_LONG); + + /* + * If the bitmap is small, shrink the number of bits per word so + * we spread over a few cachelines, at least. If less than 4 + * bits, just forget about it, it's not going to work optimally + * anyway. + */ + if (depth >= 4) { + while ((4U << shift) > depth) + shift--; + } + + return shift; +} + /** * sbitmap_show() - Dump &struct sbitmap information to a &struct seq_file. * @sb: Bitmap to show. diff --git a/lib/sbitmap.c b/lib/sbitmap.c index 73da26ad021e..47b3691058eb 100644 --- a/lib/sbitmap.c +++ b/lib/sbitmap.c @@ -87,19 +87,9 @@ int sbitmap_init_node(struct sbitmap *sb, unsigned int depth, int shift, unsigned int bits_per_word; unsigned int i; - if (shift < 0) { - shift = ilog2(BITS_PER_LONG); - /* - * If the bitmap is small, shrink the number of bits per word so - * we spread over a few cachelines, at least. If less than 4 - * bits, just forget about it, it's not going to work optimally - * anyway. - */ - if (depth >= 4) { - while ((4U << shift) > depth) - shift--; - } - } + if (shift < 0) + shift = sbitmap_calculate_shift(depth); + bits_per_word = 1U << shift; if (bits_per_word > BITS_PER_LONG) return -EINVAL; From d022d18c045fc2ccf92d0f14cf80f98eb0a8e119 Mon Sep 17 00:00:00 2001 From: Ming Lei Date: Fri, 22 Jan 2021 10:33:11 +0800 Subject: [PATCH 011/412] scsi: blk-mq: Add callbacks for storing & retrieving budget token Since SCSI is the only driver which requires dispatch budget move the token from struct request to struct scsi_cmnd. Link: https://lore.kernel.org/r/20210122023317.687987-8-ming.lei@redhat.com Cc: Omar Sandoval Cc: Kashyap Desai Cc: Sumanesh Samanta Cc: Ewan D. Milne Cc: Hannes Reinecke Tested-by: Sumanesh Samanta Reviewed-by: Hannes Reinecke Signed-off-by: Ming Lei Signed-off-by: Martin K. Petersen --- drivers/scsi/scsi_lib.c | 18 ++++++++++++++++++ include/linux/blk-mq.h | 9 +++++++++ include/scsi/scsi_cmnd.h | 2 ++ 3 files changed, 29 insertions(+) diff --git a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c index 7d52a11e1b61..02da34ab335d 100644 --- a/drivers/scsi/scsi_lib.c +++ b/drivers/scsi/scsi_lib.c @@ -1642,6 +1642,20 @@ static bool scsi_mq_get_budget(struct request_queue *q) return false; } +static void scsi_mq_set_rq_budget_token(struct request *req, int token) +{ + struct scsi_cmnd *cmd = blk_mq_rq_to_pdu(req); + + cmd->budget_token = token; +} + +static int scsi_mq_get_rq_budget_token(struct request *req) +{ + struct scsi_cmnd *cmd = blk_mq_rq_to_pdu(req); + + return cmd->budget_token; +} + static blk_status_t scsi_queue_rq(struct blk_mq_hw_ctx *hctx, const struct blk_mq_queue_data *bd) { @@ -1856,6 +1870,8 @@ static const struct blk_mq_ops scsi_mq_ops_no_commit = { .cleanup_rq = scsi_cleanup_rq, .busy = scsi_mq_lld_busy, .map_queues = scsi_map_queues, + .set_rq_budget_token = scsi_mq_set_rq_budget_token, + .get_rq_budget_token = scsi_mq_get_rq_budget_token, }; @@ -1884,6 +1900,8 @@ static const struct blk_mq_ops scsi_mq_ops = { .cleanup_rq = scsi_cleanup_rq, .busy = scsi_mq_lld_busy, .map_queues = scsi_map_queues, + .set_rq_budget_token = scsi_mq_set_rq_budget_token, + .get_rq_budget_token = scsi_mq_get_rq_budget_token, }; struct request_queue *scsi_mq_alloc_queue(struct scsi_device *sdev) diff --git a/include/linux/blk-mq.h b/include/linux/blk-mq.h index 2c473c9b8990..5fae401f083d 100644 --- a/include/linux/blk-mq.h +++ b/include/linux/blk-mq.h @@ -313,6 +313,15 @@ struct blk_mq_ops { */ void (*put_budget)(struct request_queue *); + /* + * @set_rq_budget_toekn: store rq's budget token + */ + void (*set_rq_budget_token)(struct request *, int); + /* + * @get_rq_budget_toekn: retrieve rq's budget token + */ + int (*get_rq_budget_token)(struct request *); + /** * @timeout: Called on request timeout. */ diff --git a/include/scsi/scsi_cmnd.h b/include/scsi/scsi_cmnd.h index ace15b5dc956..0cf2b5ccc1f7 100644 --- a/include/scsi/scsi_cmnd.h +++ b/include/scsi/scsi_cmnd.h @@ -75,6 +75,8 @@ struct scsi_cmnd { int eh_eflags; /* Used by error handlr */ + int budget_token; + /* * This is set to jiffies as it was when the command was first * allocated. It is used to time how long the command has From 2a5a24aa83382a88c43d18a901fab66e6ffe1199 Mon Sep 17 00:00:00 2001 From: Ming Lei Date: Fri, 22 Jan 2021 10:33:12 +0800 Subject: [PATCH 012/412] scsi: blk-mq: Return budget token from .get_budget callback SCSI uses a global atomic variable to track queue depth for each LUN/request queue. This doesn't scale well when there are lots of CPU cores and the disk is very fast. It has been observed that IOPS is affected a lot by tracking queue depth via sdev->device_busy in the I/O path. Return budget token from .get_budget callback. The budget token can be passed to driver so that we can replace the atomic variable with sbitmap_queue and alleviate the scaling problems that way. Link: https://lore.kernel.org/r/20210122023317.687987-9-ming.lei@redhat.com Cc: Omar Sandoval Cc: Kashyap Desai Cc: Sumanesh Samanta Cc: Ewan D. Milne Tested-by: Sumanesh Samanta Reviewed-by: Hannes Reinecke Signed-off-by: Ming Lei Signed-off-by: Martin K. Petersen --- block/blk-mq-sched.c | 17 +++++++++++++---- block/blk-mq.c | 36 +++++++++++++++++++++++++----------- block/blk-mq.h | 25 +++++++++++++++++++++---- drivers/scsi/scsi_lib.c | 16 +++++++++++----- include/linux/blk-mq.h | 4 ++-- 5 files changed, 72 insertions(+), 26 deletions(-) diff --git a/block/blk-mq-sched.c b/block/blk-mq-sched.c index ddb65e9e6fd9..712b7f0afd63 100644 --- a/block/blk-mq-sched.c +++ b/block/blk-mq-sched.c @@ -131,6 +131,7 @@ static int __blk_mq_do_dispatch_sched(struct blk_mq_hw_ctx *hctx) do { struct request *rq; + int budget_token; if (e->type->ops.has_work && !e->type->ops.has_work(hctx)) break; @@ -140,12 +141,13 @@ static int __blk_mq_do_dispatch_sched(struct blk_mq_hw_ctx *hctx) break; } - if (!blk_mq_get_dispatch_budget(q)) + budget_token = blk_mq_get_dispatch_budget(q); + if (budget_token < 0) break; rq = e->type->ops.dispatch_request(hctx); if (!rq) { - blk_mq_put_dispatch_budget(q); + blk_mq_put_dispatch_budget(q, budget_token); /* * We're releasing without dispatching. Holding the * budget could have blocked any "hctx"s with the @@ -157,6 +159,8 @@ static int __blk_mq_do_dispatch_sched(struct blk_mq_hw_ctx *hctx) break; } + blk_mq_set_rq_budget_token(rq, budget_token); + /* * Now this rq owns the budget which has to be released * if this rq won't be queued to driver via .queue_rq() @@ -230,6 +234,8 @@ static int blk_mq_do_dispatch_ctx(struct blk_mq_hw_ctx *hctx) struct request *rq; do { + int budget_token; + if (!list_empty_careful(&hctx->dispatch)) { ret = -EAGAIN; break; @@ -238,12 +244,13 @@ static int blk_mq_do_dispatch_ctx(struct blk_mq_hw_ctx *hctx) if (!sbitmap_any_bit_set(&hctx->ctx_map)) break; - if (!blk_mq_get_dispatch_budget(q)) + budget_token = blk_mq_get_dispatch_budget(q); + if (budget_token < 0) break; rq = blk_mq_dequeue_from_ctx(hctx, ctx); if (!rq) { - blk_mq_put_dispatch_budget(q); + blk_mq_put_dispatch_budget(q, budget_token); /* * We're releasing without dispatching. Holding the * budget could have blocked any "hctx"s with the @@ -255,6 +262,8 @@ static int blk_mq_do_dispatch_ctx(struct blk_mq_hw_ctx *hctx) break; } + blk_mq_set_rq_budget_token(rq, budget_token); + /* * Now this rq owns the budget which has to be released * if this rq won't be queued to driver via .queue_rq() diff --git a/block/blk-mq.c b/block/blk-mq.c index 2e8c94e00f58..2e825a7a3606 100644 --- a/block/blk-mq.c +++ b/block/blk-mq.c @@ -1277,10 +1277,15 @@ static enum prep_dispatch blk_mq_prep_dispatch_rq(struct request *rq, bool need_budget) { struct blk_mq_hw_ctx *hctx = rq->mq_hctx; + int budget_token = -1; - if (need_budget && !blk_mq_get_dispatch_budget(rq->q)) { - blk_mq_put_driver_tag(rq); - return PREP_DISPATCH_NO_BUDGET; + if (need_budget) { + budget_token = blk_mq_get_dispatch_budget(rq->q); + if (budget_token < 0) { + blk_mq_put_driver_tag(rq); + return PREP_DISPATCH_NO_BUDGET; + } + blk_mq_set_rq_budget_token(rq, budget_token); } if (!blk_mq_get_driver_tag(rq)) { @@ -1297,7 +1302,7 @@ static enum prep_dispatch blk_mq_prep_dispatch_rq(struct request *rq, * together during handling partial dispatch */ if (need_budget) - blk_mq_put_dispatch_budget(rq->q); + blk_mq_put_dispatch_budget(rq->q, budget_token); return PREP_DISPATCH_NO_TAG; } } @@ -1307,12 +1312,16 @@ static enum prep_dispatch blk_mq_prep_dispatch_rq(struct request *rq, /* release all allocated budgets before calling to blk_mq_dispatch_rq_list */ static void blk_mq_release_budgets(struct request_queue *q, - unsigned int nr_budgets) + struct list_head *list) { - int i; + struct request *rq; - for (i = 0; i < nr_budgets; i++) - blk_mq_put_dispatch_budget(q); + list_for_each_entry(rq, list, queuelist) { + int budget_token = blk_mq_get_rq_budget_token(rq); + + if (budget_token >= 0) + blk_mq_put_dispatch_budget(q, budget_token); + } } /* @@ -1410,7 +1419,8 @@ out: (hctx->flags & BLK_MQ_F_TAG_QUEUE_SHARED); bool no_budget_avail = prep == PREP_DISPATCH_NO_BUDGET; - blk_mq_release_budgets(q, nr_budgets); + if (nr_budgets) + blk_mq_release_budgets(q, list); spin_lock(&hctx->lock); list_splice_tail_init(list, &hctx->dispatch); @@ -2009,6 +2019,7 @@ static blk_status_t __blk_mq_try_issue_directly(struct blk_mq_hw_ctx *hctx, { struct request_queue *q = rq->q; bool run_queue = true; + int budget_token; /* * RCU or SRCU read lock is needed before checking quiesced flag. @@ -2026,11 +2037,14 @@ static blk_status_t __blk_mq_try_issue_directly(struct blk_mq_hw_ctx *hctx, if (q->elevator && !bypass_insert) goto insert; - if (!blk_mq_get_dispatch_budget(q)) + budget_token = blk_mq_get_dispatch_budget(q); + if (budget_token < 0) goto insert; + blk_mq_set_rq_budget_token(rq, budget_token); + if (!blk_mq_get_driver_tag(rq)) { - blk_mq_put_dispatch_budget(q); + blk_mq_put_dispatch_budget(q, budget_token); goto insert; } diff --git a/block/blk-mq.h b/block/blk-mq.h index 3616453ca28c..9ce64bc4a6c8 100644 --- a/block/blk-mq.h +++ b/block/blk-mq.h @@ -187,17 +187,34 @@ unsigned int blk_mq_in_flight(struct request_queue *q, void blk_mq_in_flight_rw(struct request_queue *q, struct block_device *part, unsigned int inflight[2]); -static inline void blk_mq_put_dispatch_budget(struct request_queue *q) +static inline void blk_mq_put_dispatch_budget(struct request_queue *q, + int budget_token) { if (q->mq_ops->put_budget) - q->mq_ops->put_budget(q); + q->mq_ops->put_budget(q, budget_token); } -static inline bool blk_mq_get_dispatch_budget(struct request_queue *q) +static inline int blk_mq_get_dispatch_budget(struct request_queue *q) { if (q->mq_ops->get_budget) return q->mq_ops->get_budget(q); - return true; + return 0; +} + +static inline void blk_mq_set_rq_budget_token(struct request *rq, int token) +{ + if (token < 0) + return; + + if (rq->q->mq_ops->set_rq_budget_token) + rq->q->mq_ops->set_rq_budget_token(rq, token); +} + +static inline int blk_mq_get_rq_budget_token(struct request *rq) +{ + if (rq->q->mq_ops->get_rq_budget_token) + return rq->q->mq_ops->get_rq_budget_token(rq); + return -1; } static inline void __blk_mq_inc_active_requests(struct blk_mq_hw_ctx *hctx) diff --git a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c index 02da34ab335d..dae9f66caffd 100644 --- a/drivers/scsi/scsi_lib.c +++ b/drivers/scsi/scsi_lib.c @@ -329,6 +329,7 @@ void scsi_device_unbusy(struct scsi_device *sdev, struct scsi_cmnd *cmd) atomic_dec(&starget->target_busy); atomic_dec(&sdev->device_busy); + cmd->budget_token = -1; } static void scsi_kick_queue(struct request_queue *q) @@ -1143,6 +1144,7 @@ void scsi_init_command(struct scsi_device *dev, struct scsi_cmnd *cmd) unsigned long jiffies_at_alloc; int retries, to_clear; bool in_flight; + int budget_token = cmd->budget_token; if (!blk_rq_is_scsi(rq) && !(flags & SCMD_INITIALIZED)) { flags |= SCMD_INITIALIZED; @@ -1171,6 +1173,7 @@ void scsi_init_command(struct scsi_device *dev, struct scsi_cmnd *cmd) cmd->retries = retries; if (in_flight) __set_bit(SCMD_STATE_INFLIGHT, &cmd->state); + cmd->budget_token = budget_token; } @@ -1605,19 +1608,19 @@ static void scsi_mq_done(struct scsi_cmnd *cmd) blk_mq_complete_request(cmd->request); } -static void scsi_mq_put_budget(struct request_queue *q) +static void scsi_mq_put_budget(struct request_queue *q, int budget_token) { struct scsi_device *sdev = q->queuedata; atomic_dec(&sdev->device_busy); } -static bool scsi_mq_get_budget(struct request_queue *q) +static int scsi_mq_get_budget(struct request_queue *q) { struct scsi_device *sdev = q->queuedata; if (scsi_dev_queue_ready(q, sdev)) - return true; + return 0; atomic_inc(&sdev->restarts); @@ -1639,7 +1642,7 @@ static bool scsi_mq_get_budget(struct request_queue *q) if (unlikely(atomic_read(&sdev->device_busy) == 0 && !scsi_device_blocked(sdev))) blk_mq_delay_run_hw_queues(sdev->request_queue, SCSI_QUEUE_DELAY); - return false; + return -1; } static void scsi_mq_set_rq_budget_token(struct request *req, int token) @@ -1667,6 +1670,8 @@ static blk_status_t scsi_queue_rq(struct blk_mq_hw_ctx *hctx, blk_status_t ret; int reason; + WARN_ON_ONCE(cmd->budget_token < 0); + /* * If the device is not in running state we will reject some or all * commands. @@ -1718,7 +1723,8 @@ out_dec_target_busy: if (scsi_target(sdev)->can_queue > 0) atomic_dec(&scsi_target(sdev)->target_busy); out_put_budget: - scsi_mq_put_budget(q); + scsi_mq_put_budget(q, cmd->budget_token); + cmd->budget_token = -1; switch (ret) { case BLK_STS_OK: break; diff --git a/include/linux/blk-mq.h b/include/linux/blk-mq.h index 5fae401f083d..3bd3ee651143 100644 --- a/include/linux/blk-mq.h +++ b/include/linux/blk-mq.h @@ -306,12 +306,12 @@ struct blk_mq_ops { * reserved budget. Also we have to handle failure case * of .get_budget for avoiding I/O deadlock. */ - bool (*get_budget)(struct request_queue *); + int (*get_budget)(struct request_queue *); /** * @put_budget: Release the reserved budget. */ - void (*put_budget)(struct request_queue *); + void (*put_budget)(struct request_queue *, int); /* * @set_rq_budget_toekn: store rq's budget token From 9ebb4d70dc0e0e8989a13d156020db9d55fcfafd Mon Sep 17 00:00:00 2001 From: Ming Lei Date: Fri, 22 Jan 2021 10:33:13 +0800 Subject: [PATCH 013/412] scsi: core: Put hot fields of scsi_host_template in one cacheline The following three fields of scsi_host_template are referenced in the SCSI I/O submission hot path. Put them together in one cacheline: - cmd_size - queuecommand - commit_rqs Link: https://lore.kernel.org/r/20210122023317.687987-10-ming.lei@redhat.com Cc: Omar Sandoval Cc: Kashyap Desai Cc: Sumanesh Samanta Cc: Ewan D. Milne Cc: Hannes Reinecke Tested-by: Sumanesh Samanta Reviewed-by: Hannes Reinecke Reviewed-by: Christoph Hellwig Signed-off-by: Ming Lei Signed-off-by: Martin K. Petersen --- include/scsi/scsi_host.h | 76 ++++++++++++++++++++++------------------ 1 file changed, 41 insertions(+), 35 deletions(-) diff --git a/include/scsi/scsi_host.h b/include/scsi/scsi_host.h index e30fd963b97d..f0e8a9e73002 100644 --- a/include/scsi/scsi_host.h +++ b/include/scsi/scsi_host.h @@ -30,40 +30,15 @@ struct scsi_transport_template; #define MODE_TARGET 0x02 struct scsi_host_template { - struct module *module; - const char *name; + /* + * Put fields referenced in IO submission path together in + * same cacheline + */ /* - * The info function will return whatever useful information the - * developer sees fit. If not provided, then the name field will - * be used instead. - * - * Status: OPTIONAL + * Additional per-command data allocated for the driver. */ - const char *(* info)(struct Scsi_Host *); - - /* - * Ioctl interface - * - * Status: OPTIONAL - */ - int (*ioctl)(struct scsi_device *dev, unsigned int cmd, - void __user *arg); - - -#ifdef CONFIG_COMPAT - /* - * Compat handler. Handle 32bit ABI. - * When unknown ioctl is passed return -ENOIOCTLCMD. - * - * Status: OPTIONAL - */ - int (*compat_ioctl)(struct scsi_device *dev, unsigned int cmd, - void __user *arg); -#endif - - int (*init_cmd_priv)(struct Scsi_Host *shost, struct scsi_cmnd *cmd); - int (*exit_cmd_priv)(struct Scsi_Host *shost, struct scsi_cmnd *cmd); + unsigned int cmd_size; /* * The queuecommand function is used to queue up a scsi @@ -111,6 +86,41 @@ struct scsi_host_template { */ void (*commit_rqs)(struct Scsi_Host *, u16); + struct module *module; + const char *name; + + /* + * The info function will return whatever useful information the + * developer sees fit. If not provided, then the name field will + * be used instead. + * + * Status: OPTIONAL + */ + const char *(*info)(struct Scsi_Host *); + + /* + * Ioctl interface + * + * Status: OPTIONAL + */ + int (*ioctl)(struct scsi_device *dev, unsigned int cmd, + void __user *arg); + + +#ifdef CONFIG_COMPAT + /* + * Compat handler. Handle 32bit ABI. + * When unknown ioctl is passed return -ENOIOCTLCMD. + * + * Status: OPTIONAL + */ + int (*compat_ioctl)(struct scsi_device *dev, unsigned int cmd, + void __user *arg); +#endif + + int (*init_cmd_priv)(struct Scsi_Host *shost, struct scsi_cmnd *cmd); + int (*exit_cmd_priv)(struct Scsi_Host *shost, struct scsi_cmnd *cmd); + /* * This is an error handling strategy routine. You don't need to * define one of these if you don't want to - there is a default @@ -484,10 +494,6 @@ struct scsi_host_template { */ u64 vendor_id; - /* - * Additional per-command data allocated for the driver. - */ - unsigned int cmd_size; struct scsi_host_cmd_pool *cmd_pool; /* Delay for runtime autosuspend */ From 6cb9b15238a389a8892a6ed08f5c68a0ac45d720 Mon Sep 17 00:00:00 2001 From: Kashyap Desai Date: Fri, 22 Jan 2021 10:33:14 +0800 Subject: [PATCH 014/412] scsi: megaraid_sas: Replace sdev_busy with local counter Use local tracking of per-sdev outstanding command since sdev_busy in SCSI mid layer is improved for performance reason using sbitmap (earlier it was atomic variable). Link: https://lore.kernel.org/r/20210122023317.687987-11-ming.lei@redhat.com Cc: Omar Sandoval Cc: Kashyap Desai Cc: Sumanesh Samanta Cc: Ewan D. Milne Reviewed-by: Hannes Reinecke Signed-off-by: Kashyap Desai Signed-off-by: Ming Lei Signed-off-by: Martin K. Petersen --- drivers/scsi/megaraid/megaraid_sas.h | 2 + drivers/scsi/megaraid/megaraid_sas_fusion.c | 47 +++++++++++++++++---- 2 files changed, 41 insertions(+), 8 deletions(-) diff --git a/drivers/scsi/megaraid/megaraid_sas.h b/drivers/scsi/megaraid/megaraid_sas.h index 0f808d63580e..0c6a56b24c6e 100644 --- a/drivers/scsi/megaraid/megaraid_sas.h +++ b/drivers/scsi/megaraid/megaraid_sas.h @@ -2019,10 +2019,12 @@ union megasas_frame { * struct MR_PRIV_DEVICE - sdev private hostdata * @is_tm_capable: firmware managed tm_capable flag * @tm_busy: TM request is in progress + * @sdev_priv_busy: pending command per sdev */ struct MR_PRIV_DEVICE { bool is_tm_capable; bool tm_busy; + atomic_t sdev_priv_busy; atomic_t r1_ldio_hint; u8 interface_type; u8 task_abort_tmo; diff --git a/drivers/scsi/megaraid/megaraid_sas_fusion.c b/drivers/scsi/megaraid/megaraid_sas_fusion.c index 38fc9467c625..f3448567ce28 100644 --- a/drivers/scsi/megaraid/megaraid_sas_fusion.c +++ b/drivers/scsi/megaraid/megaraid_sas_fusion.c @@ -220,6 +220,40 @@ megasas_clear_intr_fusion(struct megasas_instance *instance) return 1; } +static inline void +megasas_sdev_busy_inc(struct megasas_instance *instance, + struct scsi_cmnd *scmd) +{ + if (instance->perf_mode == MR_BALANCED_PERF_MODE) { + struct MR_PRIV_DEVICE *mr_device_priv_data = + scmd->device->hostdata; + atomic_inc(&mr_device_priv_data->sdev_priv_busy); + } +} + +static inline void +megasas_sdev_busy_dec(struct megasas_instance *instance, + struct scsi_cmnd *scmd) +{ + if (instance->perf_mode == MR_BALANCED_PERF_MODE) { + struct MR_PRIV_DEVICE *mr_device_priv_data = + scmd->device->hostdata; + atomic_dec(&mr_device_priv_data->sdev_priv_busy); + } +} + +static inline int +megasas_sdev_busy_read(struct megasas_instance *instance, + struct scsi_cmnd *scmd) +{ + if (instance->perf_mode == MR_BALANCED_PERF_MODE) { + struct MR_PRIV_DEVICE *mr_device_priv_data = + scmd->device->hostdata; + return atomic_read(&mr_device_priv_data->sdev_priv_busy); + } + return 0; +} + /** * megasas_get_cmd_fusion - Get a command from the free pool * @instance: Adapter soft state @@ -357,15 +391,9 @@ megasas_get_msix_index(struct megasas_instance *instance, struct megasas_cmd_fusion *cmd, u8 data_arms) { - int sdev_busy; - - /* TBD - if sml remove device_busy in future, driver - * should track counter in internal structure. - */ - sdev_busy = atomic_read(&scmd->device->device_busy); - if (instance->perf_mode == MR_BALANCED_PERF_MODE && - sdev_busy > (data_arms * MR_DEVICE_HIGH_IOPS_DEPTH)) { + (megasas_sdev_busy_read(instance, scmd) > + (data_arms * MR_DEVICE_HIGH_IOPS_DEPTH))) { cmd->request_desc->SCSIIO.MSIxIndex = mega_mod64((atomic64_add_return(1, &instance->high_iops_outstanding) / MR_HIGH_IOPS_BATCH_COUNT), instance->low_latency_index_start); @@ -3390,6 +3418,7 @@ megasas_build_and_issue_cmd_fusion(struct megasas_instance *instance, * Issue the command to the FW */ + megasas_sdev_busy_inc(instance, scmd); megasas_fire_cmd_fusion(instance, req_desc); if (r1_cmd) @@ -3450,6 +3479,7 @@ megasas_complete_r1_command(struct megasas_instance *instance, scmd_local->SCp.ptr = NULL; megasas_return_cmd_fusion(instance, cmd); scsi_dma_unmap(scmd_local); + megasas_sdev_busy_dec(instance, scmd_local); scmd_local->scsi_done(scmd_local); } } @@ -3550,6 +3580,7 @@ complete_cmd_fusion(struct megasas_instance *instance, u32 MSIxIndex, scmd_local->SCp.ptr = NULL; megasas_return_cmd_fusion(instance, cmd_fusion); scsi_dma_unmap(scmd_local); + megasas_sdev_busy_dec(instance, scmd_local); scmd_local->scsi_done(scmd_local); } else /* Optimal VD - R1 FP command completion. */ megasas_complete_r1_command(instance, cmd_fusion); From 8278807abd338f2246b6ae8057f2ec61a80a5614 Mon Sep 17 00:00:00 2001 From: Ming Lei Date: Fri, 22 Jan 2021 10:33:15 +0800 Subject: [PATCH 015/412] scsi: core: Add scsi_device_busy() wrapper Add scsi_device_busy() helper to prepare drivers for tracking device queue depth via sbitmap_queue. Link: https://lore.kernel.org/r/20210122023317.687987-12-ming.lei@redhat.com Cc: Omar Sandoval Cc: Kashyap Desai Cc: Sumanesh Samanta Cc: Ewan D. Milne Tested-by: Sumanesh Samanta Reviewed-by: Hannes Reinecke Signed-off-by: Ming Lei Signed-off-by: Martin K. Petersen --- drivers/message/fusion/mptsas.c | 2 +- drivers/scsi/mpt3sas/mpt3sas_scsih.c | 2 +- drivers/scsi/scsi_lib.c | 4 ++-- drivers/scsi/scsi_sysfs.c | 2 +- drivers/scsi/sg.c | 2 +- include/scsi/scsi_device.h | 5 +++++ 6 files changed, 11 insertions(+), 6 deletions(-) diff --git a/drivers/message/fusion/mptsas.c b/drivers/message/fusion/mptsas.c index 5eb0b3361e4e..85aa5788826b 100644 --- a/drivers/message/fusion/mptsas.c +++ b/drivers/message/fusion/mptsas.c @@ -3781,7 +3781,7 @@ mptsas_send_link_status_event(struct fw_event_work *fw_event) printk(MYIOC_s_DEBUG_FMT "SDEV OUTSTANDING CMDS" "%d\n", ioc->name, - atomic_read(&sdev->device_busy))); + scsi_device_busy(sdev))); } } diff --git a/drivers/scsi/mpt3sas/mpt3sas_scsih.c b/drivers/scsi/mpt3sas/mpt3sas_scsih.c index ffca03064797..7bd0a57e5b92 100644 --- a/drivers/scsi/mpt3sas/mpt3sas_scsih.c +++ b/drivers/scsi/mpt3sas/mpt3sas_scsih.c @@ -3423,7 +3423,7 @@ scsih_dev_reset(struct scsi_cmnd *scmd) MPI2_SCSITASKMGMT_TASKTYPE_LOGICAL_UNIT_RESET, 0, 0, tr_timeout, tr_method); /* Check for busy commands after reset */ - if (r == SUCCESS && atomic_read(&scmd->device->device_busy)) + if (r == SUCCESS && scsi_device_busy(scmd->device)) r = FAILED; out: sdev_printk(KERN_INFO, scmd->device, "device reset: %s scmd(0x%p)\n", diff --git a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c index dae9f66caffd..2f8578fb89ff 100644 --- a/drivers/scsi/scsi_lib.c +++ b/drivers/scsi/scsi_lib.c @@ -385,7 +385,7 @@ static void scsi_single_lun_run(struct scsi_device *current_sdev) static inline bool scsi_device_is_busy(struct scsi_device *sdev) { - if (atomic_read(&sdev->device_busy) >= sdev->queue_depth) + if (scsi_device_busy(sdev) >= sdev->queue_depth) return true; if (atomic_read(&sdev->device_blocked) > 0) return true; @@ -1639,7 +1639,7 @@ static int scsi_mq_get_budget(struct request_queue *q) * the .restarts flag, and the request queue will be run for handling * this request, see scsi_end_request(). */ - if (unlikely(atomic_read(&sdev->device_busy) == 0 && + if (unlikely(scsi_device_busy(sdev) == 0 && !scsi_device_blocked(sdev))) blk_mq_delay_run_hw_queues(sdev->request_queue, SCSI_QUEUE_DELAY); return -1; diff --git a/drivers/scsi/scsi_sysfs.c b/drivers/scsi/scsi_sysfs.c index b6378c8ca783..0840e44140de 100644 --- a/drivers/scsi/scsi_sysfs.c +++ b/drivers/scsi/scsi_sysfs.c @@ -670,7 +670,7 @@ sdev_show_device_busy(struct device *dev, struct device_attribute *attr, char *buf) { struct scsi_device *sdev = to_scsi_device(dev); - return snprintf(buf, 20, "%d\n", atomic_read(&sdev->device_busy)); + return snprintf(buf, 20, "%d\n", scsi_device_busy(sdev)); } static DEVICE_ATTR(device_busy, S_IRUGO, sdev_show_device_busy, NULL); diff --git a/drivers/scsi/sg.c b/drivers/scsi/sg.c index 4383d93110f8..737cea9d908e 100644 --- a/drivers/scsi/sg.c +++ b/drivers/scsi/sg.c @@ -2503,7 +2503,7 @@ static int sg_proc_seq_show_dev(struct seq_file *s, void *v) scsidp->id, scsidp->lun, (int) scsidp->type, 1, (int) scsidp->queue_depth, - (int) atomic_read(&scsidp->device_busy), + (int) scsi_device_busy(scsidp), (int) scsi_device_online(scsidp)); } read_unlock_irqrestore(&sg_index_lock, iflags); diff --git a/include/scsi/scsi_device.h b/include/scsi/scsi_device.h index 1a5c9a3df6d6..dd0b9f690a26 100644 --- a/include/scsi/scsi_device.h +++ b/include/scsi/scsi_device.h @@ -590,6 +590,11 @@ static inline int scsi_device_supports_vpd(struct scsi_device *sdev) return 0; } +static inline int scsi_device_busy(struct scsi_device *sdev) +{ + return atomic_read(&sdev->device_busy); +} + #define MODULE_ALIAS_SCSI_DEVICE(type) \ MODULE_ALIAS("scsi:t-" __stringify(type) "*") #define SCSI_DEVICE_MODALIAS_FMT "scsi:t-0x%02x" From ca44532139514f5fb0a5a081cd8576e4abe54e65 Mon Sep 17 00:00:00 2001 From: Ming Lei Date: Fri, 22 Jan 2021 10:33:16 +0800 Subject: [PATCH 016/412] scsi: core: Make sure sdev->queue_depth is <= max(shost->can_queue, 1024) Limit SCSI device's queue depth to max(host->can_queue, 1024) in scsi_change_queue_depth(). 1024 is big enough for saturating current fast SCSI LUN(SSD or RAID volume on multiple SSDs). Also single hardware queue depth is usually enough for saturating single LUN because per-core performance is often considered in storage design. This patch is needed for replacing sdev->device_busy with sbitmap which has to be pre-allocated with reasonable max depth. Link: https://lore.kernel.org/r/20210122023317.687987-13-ming.lei@redhat.com Cc: Omar Sandoval Cc: Kashyap Desai Cc: Sumanesh Samanta Cc: Ewan D. Milne Tested-by: Sumanesh Samanta Reviewed-by: Hannes Reinecke Signed-off-by: Ming Lei Signed-off-by: Martin K. Petersen --- drivers/scsi/scsi.c | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/drivers/scsi/scsi.c b/drivers/scsi/scsi.c index 24619c3bebd5..a28d48c850cf 100644 --- a/drivers/scsi/scsi.c +++ b/drivers/scsi/scsi.c @@ -214,6 +214,15 @@ void scsi_finish_command(struct scsi_cmnd *cmd) scsi_io_completion(cmd, good_bytes); } + +/* + * 1024 is big enough for saturating the fast scsi LUN now + */ +static int scsi_device_max_queue_depth(struct scsi_device *sdev) +{ + return max_t(int, sdev->host->can_queue, 1024); +} + /** * scsi_change_queue_depth - change a device's queue depth * @sdev: SCSI Device in question @@ -223,6 +232,8 @@ void scsi_finish_command(struct scsi_cmnd *cmd) */ int scsi_change_queue_depth(struct scsi_device *sdev, int depth) { + depth = min_t(int, depth, scsi_device_max_queue_depth(sdev)); + if (depth > 0) { sdev->queue_depth = depth; wmb(); From 020b0f0a31920e5b7e7e120d4560453b67b70733 Mon Sep 17 00:00:00 2001 From: Ming Lei Date: Fri, 22 Jan 2021 10:33:17 +0800 Subject: [PATCH 017/412] scsi: core: Replace sdev->device_busy with sbitmap SCSI currently uses an atomic variable to track queue depth for each attached device. The queue depth depends on many factors such as transport type and device implementation. In addition, the SCSI device queue depth is not a static entity but changes over time as a result of congestion management. While blk-mq currently tracks queue depth for each hctx, it can't easily be changed to accommodate the SCSI per-device requirement. The current approach of using an atomic variable doesn't scale well when there are lots of CPU cores and the disk is very fast. IOPS can be substantially impacted by the atomic in the hot path. Replace the atomic variable sdev->device_busy with an sbitmap for tracking the SCSI device queue depth. It has been observed that IOPS is improved ~30% by this patchset in the following test: 1) test machine(32 logical CPU cores) Thread(s) per core: 2 Core(s) per socket: 8 Socket(s): 2 NUMA node(s): 2 Model name: Intel(R) Xeon(R) Silver 4110 CPU @ 2.10GHz 2) setup scsi_debug: modprobe scsi_debug virtual_gb=128 max_luns=1 submit_queues=32 delay=0 max_queue=256 3) fio script: fio --rw=randread --size=128G --direct=1 --ioengine=libaio --iodepth=2048 \ --numjobs=32 --bs=4k --group_reporting=1 --group_reporting=1 --runtime=60 \ --loops=10000 --name=job1 --filename=/dev/sdN [mkp: fix device_busy reference in mpt3sas] Link: https://lore.kernel.org/r/20210122023317.687987-14-ming.lei@redhat.com Link: https://lore.kernel.org/linux-block/20200119071432.18558-6-ming.lei@redhat.com/ Cc: Omar Sandoval Cc: Kashyap Desai Cc: Sumanesh Samanta Cc: Ewan D. Milne Cc: Hannes Reinecke Tested-by: Sumanesh Samanta Reviewed-by: Hannes Reinecke Signed-off-by: Ming Lei Signed-off-by: Martin K. Petersen --- drivers/scsi/mpt3sas/mpt3sas_base.c | 3 +-- drivers/scsi/scsi.c | 4 +++- drivers/scsi/scsi_lib.c | 35 +++++++++++++++-------------- drivers/scsi/scsi_priv.h | 3 +++ drivers/scsi/scsi_scan.c | 23 +++++++++++++++++-- drivers/scsi/scsi_sysfs.c | 2 ++ include/scsi/scsi_device.h | 5 +++-- 7 files changed, 51 insertions(+), 24 deletions(-) diff --git a/drivers/scsi/mpt3sas/mpt3sas_base.c b/drivers/scsi/mpt3sas/mpt3sas_base.c index ac066f86bb14..504ed856d479 100644 --- a/drivers/scsi/mpt3sas/mpt3sas_base.c +++ b/drivers/scsi/mpt3sas/mpt3sas_base.c @@ -3678,8 +3678,7 @@ _base_get_high_iops_msix_index(struct MPT3SAS_ADAPTER *ioc, * IOs on the target device is >=8. */ - if (atomic_read(&scmd->device->device_busy) > - MPT3SAS_DEVICE_HIGH_IOPS_DEPTH) + if (scsi_device_busy(scmd->device) > MPT3SAS_DEVICE_HIGH_IOPS_DEPTH) return base_mod64(( atomic64_add_return(1, &ioc->high_iops_outstanding) / MPT3SAS_HIGH_IOPS_BATCH_COUNT), diff --git a/drivers/scsi/scsi.c b/drivers/scsi/scsi.c index a28d48c850cf..e9e2f0e15ac8 100644 --- a/drivers/scsi/scsi.c +++ b/drivers/scsi/scsi.c @@ -218,7 +218,7 @@ void scsi_finish_command(struct scsi_cmnd *cmd) /* * 1024 is big enough for saturating the fast scsi LUN now */ -static int scsi_device_max_queue_depth(struct scsi_device *sdev) +int scsi_device_max_queue_depth(struct scsi_device *sdev) { return max_t(int, sdev->host->can_queue, 1024); } @@ -242,6 +242,8 @@ int scsi_change_queue_depth(struct scsi_device *sdev, int depth) if (sdev->request_queue) blk_set_queue_depth(sdev->request_queue, depth); + sbitmap_resize(&sdev->budget_map, sdev->queue_depth); + return sdev->queue_depth; } EXPORT_SYMBOL(scsi_change_queue_depth); diff --git a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c index 2f8578fb89ff..ffe824782647 100644 --- a/drivers/scsi/scsi_lib.c +++ b/drivers/scsi/scsi_lib.c @@ -328,7 +328,7 @@ void scsi_device_unbusy(struct scsi_device *sdev, struct scsi_cmnd *cmd) if (starget->can_queue > 0) atomic_dec(&starget->target_busy); - atomic_dec(&sdev->device_busy); + sbitmap_put(&sdev->budget_map, cmd->budget_token); cmd->budget_token = -1; } @@ -1257,19 +1257,20 @@ scsi_device_state_check(struct scsi_device *sdev, struct request *req) } /* - * scsi_dev_queue_ready: if we can send requests to sdev, return 1 else - * return 0. - * - * Called with the queue_lock held. + * scsi_dev_queue_ready: if we can send requests to sdev, assign one token + * and return the token else return -1. */ static inline int scsi_dev_queue_ready(struct request_queue *q, struct scsi_device *sdev) { - unsigned int busy; + int token; - busy = atomic_inc_return(&sdev->device_busy) - 1; + token = sbitmap_get(&sdev->budget_map); if (atomic_read(&sdev->device_blocked)) { - if (busy) + if (token < 0) + goto out; + + if (scsi_device_busy(sdev) > 1) goto out_dec; /* @@ -1281,13 +1282,12 @@ static inline int scsi_dev_queue_ready(struct request_queue *q, "unblocking device at zero depth\n")); } - if (busy >= sdev->queue_depth) - goto out_dec; - - return 1; + return token; out_dec: - atomic_dec(&sdev->device_busy); - return 0; + if (token >= 0) + sbitmap_put(&sdev->budget_map, token); +out: + return -1; } /* @@ -1612,15 +1612,16 @@ static void scsi_mq_put_budget(struct request_queue *q, int budget_token) { struct scsi_device *sdev = q->queuedata; - atomic_dec(&sdev->device_busy); + sbitmap_put(&sdev->budget_map, budget_token); } static int scsi_mq_get_budget(struct request_queue *q) { struct scsi_device *sdev = q->queuedata; + int token = scsi_dev_queue_ready(q, sdev); - if (scsi_dev_queue_ready(q, sdev)) - return 0; + if (token >= 0) + return token; atomic_inc(&sdev->restarts); diff --git a/drivers/scsi/scsi_priv.h b/drivers/scsi/scsi_priv.h index 180636d54982..30b35002d2f8 100644 --- a/drivers/scsi/scsi_priv.h +++ b/drivers/scsi/scsi_priv.h @@ -5,6 +5,7 @@ #include #include #include +#include struct request_queue; struct request; @@ -182,6 +183,8 @@ static inline void scsi_dh_add_device(struct scsi_device *sdev) { } static inline void scsi_dh_release_device(struct scsi_device *sdev) { } #endif +extern int scsi_device_max_queue_depth(struct scsi_device *sdev); + /* * internal scsi timeout functions: for use by mid-layer and transport * classes. diff --git a/drivers/scsi/scsi_scan.c b/drivers/scsi/scsi_scan.c index 9af50e6f94c4..9f1b7f3c650a 100644 --- a/drivers/scsi/scsi_scan.c +++ b/drivers/scsi/scsi_scan.c @@ -215,6 +215,7 @@ static void scsi_unlock_floptical(struct scsi_device *sdev, static struct scsi_device *scsi_alloc_sdev(struct scsi_target *starget, u64 lun, void *hostdata) { + unsigned int depth; struct scsi_device *sdev; int display_failure_msg = 1, ret; struct Scsi_Host *shost = dev_to_shost(starget->dev.parent); @@ -276,8 +277,25 @@ static struct scsi_device *scsi_alloc_sdev(struct scsi_target *starget, WARN_ON_ONCE(!blk_get_queue(sdev->request_queue)); sdev->request_queue->queuedata = sdev; - scsi_change_queue_depth(sdev, sdev->host->cmd_per_lun ? - sdev->host->cmd_per_lun : 1); + depth = sdev->host->cmd_per_lun ?: 1; + + /* + * Use .can_queue as budget map's depth because we have to + * support adjusting queue depth from sysfs. Meantime use + * default device queue depth to figure out sbitmap shift + * since we use this queue depth most of times. + */ + if (sbitmap_init_node(&sdev->budget_map, + scsi_device_max_queue_depth(sdev), + sbitmap_calculate_shift(depth), + GFP_KERNEL, sdev->request_queue->node, + false, true)) { + put_device(&starget->dev); + kfree(sdev); + goto out; + } + + scsi_change_queue_depth(sdev, depth); scsi_sysfs_device_initialize(sdev); @@ -979,6 +997,7 @@ static int scsi_add_lun(struct scsi_device *sdev, unsigned char *inq_result, scsi_attach_vpd(sdev); sdev->max_queue_depth = sdev->queue_depth; + WARN_ON_ONCE(sdev->max_queue_depth > sdev->budget_map.depth); sdev->sdev_bflags = *bflags; /* diff --git a/drivers/scsi/scsi_sysfs.c b/drivers/scsi/scsi_sysfs.c index 0840e44140de..7fb2f70e97c8 100644 --- a/drivers/scsi/scsi_sysfs.c +++ b/drivers/scsi/scsi_sysfs.c @@ -477,6 +477,8 @@ static void scsi_device_dev_release_usercontext(struct work_struct *work) /* NULL queue means the device can't be used */ sdev->request_queue = NULL; + sbitmap_free(&sdev->budget_map); + mutex_lock(&sdev->inquiry_mutex); vpd_pg0 = rcu_replace_pointer(sdev->vpd_pg0, vpd_pg0, lockdep_is_held(&sdev->inquiry_mutex)); diff --git a/include/scsi/scsi_device.h b/include/scsi/scsi_device.h index dd0b9f690a26..05c7c320ef32 100644 --- a/include/scsi/scsi_device.h +++ b/include/scsi/scsi_device.h @@ -8,6 +8,7 @@ #include #include #include +#include struct device; struct request_queue; @@ -106,7 +107,7 @@ struct scsi_device { struct list_head siblings; /* list of all devices on this host */ struct list_head same_target_siblings; /* just the devices sharing same target id */ - atomic_t device_busy; /* commands actually active on LLDD */ + struct sbitmap budget_map; atomic_t device_blocked; /* Device returned QUEUE_FULL. */ atomic_t restarts; @@ -592,7 +593,7 @@ static inline int scsi_device_supports_vpd(struct scsi_device *sdev) static inline int scsi_device_busy(struct scsi_device *sdev) { - return atomic_read(&sdev->device_busy); + return sbitmap_weight(&sdev->budget_map); } #define MODULE_ALIAS_SCSI_DEVICE(type) \ From a9294d86743298c87fd9c39d9ddebf4b04d5da10 Mon Sep 17 00:00:00 2001 From: Mike Christie Date: Sat, 27 Feb 2021 10:59:42 -0600 Subject: [PATCH 018/412] scsi: target: core: Move t_task_cdb initialization Prepare to split target_submit_cmd_map_sgls() so the initialization and submission part can be called at different times. If the init part fails we can reference the t_task_cdb early in some of the logging and tracing code. Move it to transport_init_se_cmd() so we don't hit NULL pointer crashes. Link: https://lore.kernel.org/r/20210227170006.5077-2-michael.christie@oracle.com Tested-by: Laurence Oberman Reviewed-by: Christoph Hellwig Reviewed-by: Himanshu Madhani Signed-off-by: Mike Christie Signed-off-by: Martin K. Petersen --- drivers/target/target_core_transport.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/target/target_core_transport.c b/drivers/target/target_core_transport.c index 5ecb9f18a53d..2dfbf9cb9581 100644 --- a/drivers/target/target_core_transport.c +++ b/drivers/target/target_core_transport.c @@ -1391,6 +1391,7 @@ void transport_init_se_cmd( INIT_WORK(&cmd->work, NULL); kref_init(&cmd->cmd_kref); + cmd->t_task_cdb = &cmd->__t_task_cdb[0]; cmd->se_tfo = tfo; cmd->se_sess = se_sess; cmd->data_length = data_length; @@ -1432,7 +1433,6 @@ target_cmd_init_cdb(struct se_cmd *cmd, unsigned char *cdb) { sense_reason_t ret; - cmd->t_task_cdb = &cmd->__t_task_cdb[0]; /* * Ensure that the received CDB is less than the max (252 + 8) bytes * for VARIABLE_LENGTH_CMD From cb222a013dca1872deeb49fe8c7176f8aa656d5f Mon Sep 17 00:00:00 2001 From: Mike Christie Date: Sat, 27 Feb 2021 10:59:43 -0600 Subject: [PATCH 019/412] scsi: target: core: Drop kref_get_unless_zero() in target_get_sess_cmd() The kref_get_unless_zero() use in target_get_sess_cmd() was added in: commit 1b4c59b7a1d0 ("target: fix potential race window in target_sess_cmd_list_waiting()")' but it does not seem to do anything. The original patch might have thought we could have added the cmd to the sess_wait_list and then target_wait_for_sess_cmds could do a put before target_get_sess_cmd did its get. That wouldn't happen because we do the get first then grab the sess lock and put it on the list. It is also not needed now, because the sess_cmd_list does not exist anymore and we instead wait on the session cmd_count. The other problem with the commit is that several target_submit_cmd_map_sgls()/target_submit_cmd() callers do not handle the error case properly if it were to ever happen. These drivers think they have their normal refcount on the cmd and in many cases do a transport_generic_free_cmd() plus target_put_sess_cmd() so they would have fired off the refcount WARN/BUGs. This patch just changes the kref_get_unless_zero() to kref_get(). Link: https://lore.kernel.org/r/20210227170006.5077-3-michael.christie@oracle.com Tested-by: Laurence Oberman Reviewed-by: Christoph Hellwig Reviewed-by: Himanshu Madhani Signed-off-by: Mike Christie Signed-off-by: Martin K. Petersen --- drivers/target/target_core_transport.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/drivers/target/target_core_transport.c b/drivers/target/target_core_transport.c index 2dfbf9cb9581..b8d7edadce46 100644 --- a/drivers/target/target_core_transport.c +++ b/drivers/target/target_core_transport.c @@ -2778,9 +2778,7 @@ int target_get_sess_cmd(struct se_cmd *se_cmd, bool ack_kref) * invocations before se_cmd descriptor release. */ if (ack_kref) { - if (!kref_get_unless_zero(&se_cmd->cmd_kref)) - return -EINVAL; - + kref_get(&se_cmd->cmd_kref); se_cmd->se_cmd_flags |= SCF_ACK_KREF; } From a78b713618c02752310b2be7da465a34fb660ed9 Mon Sep 17 00:00:00 2001 From: Mike Christie Date: Sat, 27 Feb 2021 10:59:44 -0600 Subject: [PATCH 020/412] scsi: target: core: Rename transport_init_se_cmd() Rename transport_init_se_cmd() to __target_init_cmd() to reflect that it is more of an internal function that drivers should normally not use and because we are going to add a new init function in the next patches. Link: https://lore.kernel.org/r/20210227170006.5077-4-michael.christie@oracle.com Reviewed-by: Christoph Hellwig Reviewed-by: Himanshu Madhani Signed-off-by: Mike Christie Signed-off-by: Martin K. Petersen --- drivers/target/iscsi/iscsi_target.c | 16 ++++++++-------- drivers/target/target_core_transport.c | 16 ++++++++-------- drivers/target/target_core_xcopy.c | 8 ++++---- drivers/usb/gadget/function/f_tcm.c | 20 ++++++++++---------- include/target/target_core_fabric.h | 2 +- 5 files changed, 31 insertions(+), 31 deletions(-) diff --git a/drivers/target/iscsi/iscsi_target.c b/drivers/target/iscsi/iscsi_target.c index d0e7ed8f28cc..ef9133a674f6 100644 --- a/drivers/target/iscsi/iscsi_target.c +++ b/drivers/target/iscsi/iscsi_target.c @@ -1154,10 +1154,10 @@ int iscsit_setup_scsi_cmd(struct iscsi_conn *conn, struct iscsi_cmd *cmd, /* * Initialize struct se_cmd descriptor from target_core_mod infrastructure */ - transport_init_se_cmd(&cmd->se_cmd, &iscsi_ops, - conn->sess->se_sess, be32_to_cpu(hdr->data_length), - cmd->data_direction, sam_task_attr, - cmd->sense_buffer + 2, scsilun_to_int(&hdr->lun)); + __target_init_cmd(&cmd->se_cmd, &iscsi_ops, + conn->sess->se_sess, be32_to_cpu(hdr->data_length), + cmd->data_direction, sam_task_attr, + cmd->sense_buffer + 2, scsilun_to_int(&hdr->lun)); pr_debug("Got SCSI Command, ITT: 0x%08x, CmdSN: 0x%08x," " ExpXferLen: %u, Length: %u, CID: %hu\n", hdr->itt, @@ -2013,10 +2013,10 @@ iscsit_handle_task_mgt_cmd(struct iscsi_conn *conn, struct iscsi_cmd *cmd, buf); } - transport_init_se_cmd(&cmd->se_cmd, &iscsi_ops, - conn->sess->se_sess, 0, DMA_NONE, - TCM_SIMPLE_TAG, cmd->sense_buffer + 2, - scsilun_to_int(&hdr->lun)); + __target_init_cmd(&cmd->se_cmd, &iscsi_ops, + conn->sess->se_sess, 0, DMA_NONE, + TCM_SIMPLE_TAG, cmd->sense_buffer + 2, + scsilun_to_int(&hdr->lun)); target_get_sess_cmd(&cmd->se_cmd, true); diff --git a/drivers/target/target_core_transport.c b/drivers/target/target_core_transport.c index b8d7edadce46..44ebabad3b99 100644 --- a/drivers/target/target_core_transport.c +++ b/drivers/target/target_core_transport.c @@ -1304,7 +1304,7 @@ target_check_max_data_sg_nents(struct se_cmd *cmd, struct se_device *dev, * Compare the data buffer size from the CDB with the data buffer limit from the transport * header. Set @cmd->residual_count and SCF_OVERFLOW_BIT or SCF_UNDERFLOW_BIT if necessary. * - * Note: target drivers set @cmd->data_length by calling transport_init_se_cmd(). + * Note: target drivers set @cmd->data_length by calling __target_init_cmd(). * * Return: TCM_NO_SENSE */ @@ -1371,7 +1371,7 @@ target_cmd_size_check(struct se_cmd *cmd, unsigned int size) * * Preserves the value of @cmd->tag. */ -void transport_init_se_cmd( +void __target_init_cmd( struct se_cmd *cmd, const struct target_core_fabric_ops *tfo, struct se_session *se_sess, @@ -1405,7 +1405,7 @@ void transport_init_se_cmd( cmd->state_active = false; } -EXPORT_SYMBOL(transport_init_se_cmd); +EXPORT_SYMBOL(__target_init_cmd); static sense_reason_t transport_check_alloc_task_attr(struct se_cmd *cmd) @@ -1625,9 +1625,9 @@ int target_submit_cmd_map_sgls(struct se_cmd *se_cmd, struct se_session *se_sess * exceptions are handled by sending exception status via * target_core_fabric_ops->queue_status() callback */ - transport_init_se_cmd(se_cmd, se_tpg->se_tpg_tfo, se_sess, - data_length, data_dir, task_attr, sense, - unpacked_lun); + __target_init_cmd(se_cmd, se_tpg->se_tpg_tfo, se_sess, + data_length, data_dir, task_attr, sense, + unpacked_lun); if (flags & TARGET_SCF_UNKNOWN_SIZE) se_cmd->unknown_data_length = 1; @@ -1799,8 +1799,8 @@ int target_submit_tmr(struct se_cmd *se_cmd, struct se_session *se_sess, se_tpg = se_sess->se_tpg; BUG_ON(!se_tpg); - transport_init_se_cmd(se_cmd, se_tpg->se_tpg_tfo, se_sess, - 0, DMA_NONE, TCM_SIMPLE_TAG, sense, unpacked_lun); + __target_init_cmd(se_cmd, se_tpg->se_tpg_tfo, se_sess, + 0, DMA_NONE, TCM_SIMPLE_TAG, sense, unpacked_lun); /* * FIXME: Currently expect caller to handle se_cmd->se_tmr_req * allocation failure. diff --git a/drivers/target/target_core_xcopy.c b/drivers/target/target_core_xcopy.c index 66d6f1d06f21..e86cc6135587 100644 --- a/drivers/target/target_core_xcopy.c +++ b/drivers/target/target_core_xcopy.c @@ -615,8 +615,8 @@ static int target_xcopy_read_source( pr_debug("XCOPY: Built READ_16: LBA: %llu Sectors: %u Length: %u\n", (unsigned long long)src_lba, src_sectors, length); - transport_init_se_cmd(se_cmd, &xcopy_pt_tfo, &xcopy_pt_sess, length, - DMA_FROM_DEVICE, 0, &xpt_cmd.sense_buffer[0], 0); + __target_init_cmd(se_cmd, &xcopy_pt_tfo, &xcopy_pt_sess, length, + DMA_FROM_DEVICE, 0, &xpt_cmd.sense_buffer[0], 0); rc = target_xcopy_setup_pt_cmd(&xpt_cmd, xop, src_dev, &cdb[0], remote_port); @@ -660,8 +660,8 @@ static int target_xcopy_write_destination( pr_debug("XCOPY: Built WRITE_16: LBA: %llu Sectors: %u Length: %u\n", (unsigned long long)dst_lba, dst_sectors, length); - transport_init_se_cmd(se_cmd, &xcopy_pt_tfo, &xcopy_pt_sess, length, - DMA_TO_DEVICE, 0, &xpt_cmd.sense_buffer[0], 0); + __target_init_cmd(se_cmd, &xcopy_pt_tfo, &xcopy_pt_sess, length, + DMA_TO_DEVICE, 0, &xpt_cmd.sense_buffer[0], 0); rc = target_xcopy_setup_pt_cmd(&xpt_cmd, xop, dst_dev, &cdb[0], remote_port); diff --git a/drivers/usb/gadget/function/f_tcm.c b/drivers/usb/gadget/function/f_tcm.c index 410fa89eae8f..dcce6e2605f5 100644 --- a/drivers/usb/gadget/function/f_tcm.c +++ b/drivers/usb/gadget/function/f_tcm.c @@ -1050,11 +1050,11 @@ static void usbg_cmd_work(struct work_struct *work) tv_nexus = tpg->tpg_nexus; dir = get_cmd_dir(cmd->cmd_buf); if (dir < 0) { - transport_init_se_cmd(se_cmd, - tv_nexus->tvn_se_sess->se_tpg->se_tpg_tfo, - tv_nexus->tvn_se_sess, cmd->data_len, DMA_NONE, - cmd->prio_attr, cmd->sense_iu.sense, - cmd->unpacked_lun); + __target_init_cmd(se_cmd, + tv_nexus->tvn_se_sess->se_tpg->se_tpg_tfo, + tv_nexus->tvn_se_sess, cmd->data_len, DMA_NONE, + cmd->prio_attr, cmd->sense_iu.sense, + cmd->unpacked_lun); goto out; } @@ -1181,11 +1181,11 @@ static void bot_cmd_work(struct work_struct *work) tv_nexus = tpg->tpg_nexus; dir = get_cmd_dir(cmd->cmd_buf); if (dir < 0) { - transport_init_se_cmd(se_cmd, - tv_nexus->tvn_se_sess->se_tpg->se_tpg_tfo, - tv_nexus->tvn_se_sess, cmd->data_len, DMA_NONE, - cmd->prio_attr, cmd->sense_iu.sense, - cmd->unpacked_lun); + __target_init_cmd(se_cmd, + tv_nexus->tvn_se_sess->se_tpg->se_tpg_tfo, + tv_nexus->tvn_se_sess, cmd->data_len, DMA_NONE, + cmd->prio_attr, cmd->sense_iu.sense, + cmd->unpacked_lun); goto out; } diff --git a/include/target/target_core_fabric.h b/include/target/target_core_fabric.h index d60a3eb7517a..4975c4d2a933 100644 --- a/include/target/target_core_fabric.h +++ b/include/target/target_core_fabric.h @@ -148,7 +148,7 @@ void transport_deregister_session_configfs(struct se_session *); void transport_deregister_session(struct se_session *); -void transport_init_se_cmd(struct se_cmd *, +void __target_init_cmd(struct se_cmd *, const struct target_core_fabric_ops *, struct se_session *, u32, int, int, unsigned char *, u64); sense_reason_t transport_lookup_cmd_lun(struct se_cmd *); From 750a1d93f90583a270eb62f36e6d32ebbb6af779 Mon Sep 17 00:00:00 2001 From: Mike Christie Date: Sat, 27 Feb 2021 10:59:45 -0600 Subject: [PATCH 021/412] scsi: target: core: Break up target_submit_cmd_map_sgls() This breaks up target_submit_cmd_map_sgls() into 3 helpers: - target_init_cmd(): Do the basic general setup and get a refcount to the session to make sure the caller can execute the cmd. - target_submit_prep(): Do the mapping, cdb processing and get a ref to the LUN. - target_submit(): Pass the cmd to LIO core for execution. The above functions must be used by drivers that either: 1. Rely on LIO for session shutdown synchronization by calling target_stop_session(). 2. Need to map sgls. When the next patches are applied then simple drivers that do not need the extra functionality above can use target_submit_cmd() and not worry about failures being returned and how to handle them, since many drivers were getting this wrong and would have hit refcount bugs. Also, by breaking target_submit_cmd_map_sgls() up into these 3 helper functions, we can allow the later patches to do the init/prep from interrupt context and then do the submission from a workqueue. Link: https://lore.kernel.org/r/20210227170006.5077-5-michael.christie@oracle.com Cc: Bart Van Assche Cc: Juergen Gross Cc: Hannes Reinecke Cc: Nilesh Javali Cc: Michael Cyr Cc: Chris Boot Cc: Felipe Balbi Cc: "Michael S. Tsirkin" Cc: Stefan Hajnoczi Tested-by: Laurence Oberman Reviewed-by: Christoph Hellwig Reviewed-by: Himanshu Madhani Signed-off-by: Mike Christie Signed-off-by: Martin K. Petersen --- drivers/target/target_core_transport.c | 301 ++++++++++++++++--------- include/target/target_core_fabric.h | 8 + 2 files changed, 198 insertions(+), 111 deletions(-) diff --git a/drivers/target/target_core_transport.c b/drivers/target/target_core_transport.c index 44ebabad3b99..000819112bc7 100644 --- a/drivers/target/target_core_transport.c +++ b/drivers/target/target_core_transport.c @@ -1572,9 +1572,190 @@ transport_generic_map_mem_to_cmd(struct se_cmd *cmd, struct scatterlist *sgl, return 0; } +/** + * target_init_cmd - initialize se_cmd + * @se_cmd: command descriptor to init + * @se_sess: associated se_sess for endpoint + * @sense: pointer to SCSI sense buffer + * @unpacked_lun: unpacked LUN to reference for struct se_lun + * @data_length: fabric expected data transfer length + * @task_attr: SAM task attribute + * @data_dir: DMA data direction + * @flags: flags for command submission from target_sc_flags_tables + * + * Task tags are supported if the caller has set @se_cmd->tag. + * + * Returns: + * - less than zero to signal active I/O shutdown failure. + * - zero on success. + * + * If the fabric driver calls target_stop_session, then it must check the + * return code and handle failures. This will never fail for other drivers, + * and the return code can be ignored. + */ +int target_init_cmd(struct se_cmd *se_cmd, struct se_session *se_sess, + unsigned char *sense, u64 unpacked_lun, + u32 data_length, int task_attr, int data_dir, int flags) +{ + struct se_portal_group *se_tpg; + + se_tpg = se_sess->se_tpg; + BUG_ON(!se_tpg); + BUG_ON(se_cmd->se_tfo || se_cmd->se_sess); + + if (flags & TARGET_SCF_USE_CPUID) + se_cmd->se_cmd_flags |= SCF_USE_CPUID; + /* + * Signal bidirectional data payloads to target-core + */ + if (flags & TARGET_SCF_BIDI_OP) + se_cmd->se_cmd_flags |= SCF_BIDI; + + if (flags & TARGET_SCF_UNKNOWN_SIZE) + se_cmd->unknown_data_length = 1; + /* + * Initialize se_cmd for target operation. From this point + * exceptions are handled by sending exception status via + * target_core_fabric_ops->queue_status() callback + */ + __target_init_cmd(se_cmd, se_tpg->se_tpg_tfo, se_sess, data_length, + data_dir, task_attr, sense, unpacked_lun); + + /* + * Obtain struct se_cmd->cmd_kref reference. A second kref_get here is + * necessary for fabrics using TARGET_SCF_ACK_KREF that expect a second + * kref_put() to happen during fabric packet acknowledgement. + */ + return target_get_sess_cmd(se_cmd, flags & TARGET_SCF_ACK_KREF); +} +EXPORT_SYMBOL_GPL(target_init_cmd); + +/** + * target_submit_prep - prepare cmd for submission + * @se_cmd: command descriptor to prep + * @cdb: pointer to SCSI CDB + * @sgl: struct scatterlist memory for unidirectional mapping + * @sgl_count: scatterlist count for unidirectional mapping + * @sgl_bidi: struct scatterlist memory for bidirectional READ mapping + * @sgl_bidi_count: scatterlist count for bidirectional READ mapping + * @sgl_prot: struct scatterlist memory protection information + * @sgl_prot_count: scatterlist count for protection information + * + * Returns: + * - less than zero to signal failure. + * - zero on success. + * If failure is returned, lio will the callers queue_status to complete + * the cmd. + */ +int target_submit_prep(struct se_cmd *se_cmd, unsigned char *cdb, + struct scatterlist *sgl, u32 sgl_count, + struct scatterlist *sgl_bidi, u32 sgl_bidi_count, + struct scatterlist *sgl_prot, u32 sgl_prot_count) +{ + sense_reason_t rc; + + rc = target_cmd_init_cdb(se_cmd, cdb); + if (rc) + goto send_cc_direct; + + /* + * Locate se_lun pointer and attach it to struct se_cmd + */ + rc = transport_lookup_cmd_lun(se_cmd); + if (rc) + goto send_cc_direct; + + rc = target_cmd_parse_cdb(se_cmd); + if (rc != 0) + goto generic_fail; + + /* + * Save pointers for SGLs containing protection information, + * if present. + */ + if (sgl_prot_count) { + se_cmd->t_prot_sg = sgl_prot; + se_cmd->t_prot_nents = sgl_prot_count; + se_cmd->se_cmd_flags |= SCF_PASSTHROUGH_PROT_SG_TO_MEM_NOALLOC; + } + + /* + * When a non zero sgl_count has been passed perform SGL passthrough + * mapping for pre-allocated fabric memory instead of having target + * core perform an internal SGL allocation.. + */ + if (sgl_count != 0) { + BUG_ON(!sgl); + + rc = transport_generic_map_mem_to_cmd(se_cmd, sgl, sgl_count, + sgl_bidi, sgl_bidi_count); + if (rc != 0) + goto generic_fail; + } + + return 0; + +send_cc_direct: + transport_send_check_condition_and_sense(se_cmd, rc, 0); + target_put_sess_cmd(se_cmd); + return -EIO; + +generic_fail: + transport_generic_request_failure(se_cmd, rc); + return -EIO; +} +EXPORT_SYMBOL_GPL(target_submit_prep); + +/** + * target_submit - perform final initialization and submit cmd to LIO core + * @se_cmd: command descriptor to submit + * + * target_submit_prep must have been called on the cmd, and this must be + * called from process context. + */ +void target_submit(struct se_cmd *se_cmd) +{ + struct scatterlist *sgl = se_cmd->t_data_sg; + unsigned char *buf = NULL; + + might_sleep(); + + if (se_cmd->t_data_nents != 0) { + BUG_ON(!sgl); + /* + * A work-around for tcm_loop as some userspace code via + * scsi-generic do not memset their associated read buffers, + * so go ahead and do that here for type non-data CDBs. Also + * note that this is currently guaranteed to be a single SGL + * for this case by target core in target_setup_cmd_from_cdb() + * -> transport_generic_cmd_sequencer(). + */ + if (!(se_cmd->se_cmd_flags & SCF_SCSI_DATA_CDB) && + se_cmd->data_direction == DMA_FROM_DEVICE) { + if (sgl) + buf = kmap(sg_page(sgl)) + sgl->offset; + + if (buf) { + memset(buf, 0, sgl->length); + kunmap(sg_page(sgl)); + } + } + + } + + /* + * Check if we need to delay processing because of ALUA + * Active/NonOptimized primary access state.. + */ + core_alua_check_nonop_delay(se_cmd); + + transport_handle_cdb_direct(se_cmd); +} +EXPORT_SYMBOL_GPL(target_submit); + /** * target_submit_cmd_map_sgls - lookup unpacked lun and submit uninitialized - * se_cmd + use pre-allocated SGL memory. + * se_cmd + use pre-allocated SGL memory. * * @se_cmd: command descriptor to submit * @se_sess: associated se_sess for endpoint @@ -1608,120 +1789,18 @@ int target_submit_cmd_map_sgls(struct se_cmd *se_cmd, struct se_session *se_sess struct scatterlist *sgl_bidi, u32 sgl_bidi_count, struct scatterlist *sgl_prot, u32 sgl_prot_count) { - struct se_portal_group *se_tpg; - sense_reason_t rc; - int ret; + int rc; - might_sleep(); + rc = target_init_cmd(se_cmd, se_sess, sense, unpacked_lun, + data_length, task_attr, data_dir, flags); + if (rc < 0) + return rc; - se_tpg = se_sess->se_tpg; - BUG_ON(!se_tpg); - BUG_ON(se_cmd->se_tfo || se_cmd->se_sess); - - if (flags & TARGET_SCF_USE_CPUID) - se_cmd->se_cmd_flags |= SCF_USE_CPUID; - /* - * Initialize se_cmd for target operation. From this point - * exceptions are handled by sending exception status via - * target_core_fabric_ops->queue_status() callback - */ - __target_init_cmd(se_cmd, se_tpg->se_tpg_tfo, se_sess, - data_length, data_dir, task_attr, sense, - unpacked_lun); - - if (flags & TARGET_SCF_UNKNOWN_SIZE) - se_cmd->unknown_data_length = 1; - /* - * Obtain struct se_cmd->cmd_kref reference. A second kref_get here is - * necessary for fabrics using TARGET_SCF_ACK_KREF that expect a second - * kref_put() to happen during fabric packet acknowledgement. - */ - ret = target_get_sess_cmd(se_cmd, flags & TARGET_SCF_ACK_KREF); - if (ret) - return ret; - /* - * Signal bidirectional data payloads to target-core - */ - if (flags & TARGET_SCF_BIDI_OP) - se_cmd->se_cmd_flags |= SCF_BIDI; - - rc = target_cmd_init_cdb(se_cmd, cdb); - if (rc) { - transport_send_check_condition_and_sense(se_cmd, rc, 0); - target_put_sess_cmd(se_cmd); + if (target_submit_prep(se_cmd, cdb, sgl, sgl_count, sgl_bidi, + sgl_bidi_count, sgl_prot, sgl_prot_count)) return 0; - } - /* - * Locate se_lun pointer and attach it to struct se_cmd - */ - rc = transport_lookup_cmd_lun(se_cmd); - if (rc) { - transport_send_check_condition_and_sense(se_cmd, rc, 0); - target_put_sess_cmd(se_cmd); - return 0; - } - - rc = target_cmd_parse_cdb(se_cmd); - if (rc != 0) { - transport_generic_request_failure(se_cmd, rc); - return 0; - } - - /* - * Save pointers for SGLs containing protection information, - * if present. - */ - if (sgl_prot_count) { - se_cmd->t_prot_sg = sgl_prot; - se_cmd->t_prot_nents = sgl_prot_count; - se_cmd->se_cmd_flags |= SCF_PASSTHROUGH_PROT_SG_TO_MEM_NOALLOC; - } - - /* - * When a non zero sgl_count has been passed perform SGL passthrough - * mapping for pre-allocated fabric memory instead of having target - * core perform an internal SGL allocation.. - */ - if (sgl_count != 0) { - BUG_ON(!sgl); - - /* - * A work-around for tcm_loop as some userspace code via - * scsi-generic do not memset their associated read buffers, - * so go ahead and do that here for type non-data CDBs. Also - * note that this is currently guaranteed to be a single SGL - * for this case by target core in target_setup_cmd_from_cdb() - * -> transport_generic_cmd_sequencer(). - */ - if (!(se_cmd->se_cmd_flags & SCF_SCSI_DATA_CDB) && - se_cmd->data_direction == DMA_FROM_DEVICE) { - unsigned char *buf = NULL; - - if (sgl) - buf = kmap(sg_page(sgl)) + sgl->offset; - - if (buf) { - memset(buf, 0, sgl->length); - kunmap(sg_page(sgl)); - } - } - - rc = transport_generic_map_mem_to_cmd(se_cmd, sgl, sgl_count, - sgl_bidi, sgl_bidi_count); - if (rc != 0) { - transport_generic_request_failure(se_cmd, rc); - return 0; - } - } - - /* - * Check if we need to delay processing because of ALUA - * Active/NonOptimized primary access state.. - */ - core_alua_check_nonop_delay(se_cmd); - - transport_handle_cdb_direct(se_cmd); + target_submit(se_cmd); return 0; } EXPORT_SYMBOL(target_submit_cmd_map_sgls); diff --git a/include/target/target_core_fabric.h b/include/target/target_core_fabric.h index 4975c4d2a933..4b5f6687393a 100644 --- a/include/target/target_core_fabric.h +++ b/include/target/target_core_fabric.h @@ -151,6 +151,14 @@ void transport_deregister_session(struct se_session *); void __target_init_cmd(struct se_cmd *, const struct target_core_fabric_ops *, struct se_session *, u32, int, int, unsigned char *, u64); +int target_init_cmd(struct se_cmd *se_cmd, struct se_session *se_sess, + unsigned char *sense, u64 unpacked_lun, u32 data_length, + int task_attr, int data_dir, int flags); +int target_submit_prep(struct se_cmd *se_cmd, unsigned char *cdb, + struct scatterlist *sgl, u32 sgl_count, + struct scatterlist *sgl_bidi, u32 sgl_bidi_count, + struct scatterlist *sgl_prot, u32 sgl_prot_count); +void target_submit(struct se_cmd *se_cmd); sense_reason_t transport_lookup_cmd_lun(struct se_cmd *); sense_reason_t target_cmd_init_cdb(struct se_cmd *, unsigned char *); sense_reason_t target_cmd_parse_cdb(struct se_cmd *); From 50ab9c47f51dbe3419e414ac6880273f58ac2849 Mon Sep 17 00:00:00 2001 From: Mike Christie Date: Sat, 27 Feb 2021 10:59:46 -0600 Subject: [PATCH 022/412] scsi: target: srpt: Convert to new submission API target_submit_cmd_map_sgls() is being removed, so convert srpt to the new submission API. srpt uses target_stop_session() to sync session shutdown with LIO core, so we use target_init_cmd()/target_submit_prep()/target_submit(), because target_init_cmd() will detect the target_stop_session() call and return an error. Link: https://lore.kernel.org/r/20210227170006.5077-6-michael.christie@oracle.com Cc: Bart Van Assche Reviewed-by: Christoph Hellwig Reviewed-by: Bart Van Assche Signed-off-by: Mike Christie Signed-off-by: Martin K. Petersen --- drivers/infiniband/ulp/srpt/ib_srpt.c | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/drivers/infiniband/ulp/srpt/ib_srpt.c b/drivers/infiniband/ulp/srpt/ib_srpt.c index 6be60aa5ffe2..87741e0b4bca 100644 --- a/drivers/infiniband/ulp/srpt/ib_srpt.c +++ b/drivers/infiniband/ulp/srpt/ib_srpt.c @@ -1528,16 +1528,19 @@ static void srpt_handle_cmd(struct srpt_rdma_ch *ch, goto busy; } - rc = target_submit_cmd_map_sgls(cmd, ch->sess, srp_cmd->cdb, - &send_ioctx->sense_data[0], - scsilun_to_int(&srp_cmd->lun), data_len, - TCM_SIMPLE_TAG, dir, TARGET_SCF_ACK_KREF, - sg, sg_cnt, NULL, 0, NULL, 0); + rc = target_init_cmd(cmd, ch->sess, &send_ioctx->sense_data[0], + scsilun_to_int(&srp_cmd->lun), data_len, + TCM_SIMPLE_TAG, dir, TARGET_SCF_ACK_KREF); if (rc != 0) { pr_debug("target_submit_cmd() returned %d for tag %#llx\n", rc, srp_cmd->tag); goto busy; } + + if (target_submit_prep(cmd, srp_cmd->cdb, sg, sg_cnt, NULL, 0, NULL, 0)) + return; + + target_submit(cmd); return; busy: From 7d676851de8485ccf99288134eee184e9fd5dac0 Mon Sep 17 00:00:00 2001 From: Mike Christie Date: Sat, 27 Feb 2021 10:59:47 -0600 Subject: [PATCH 023/412] scsi: target: ibmvscsi_tgt: Convert to new submission API target_submit_cmd() is now only for simple drivers that do their own sync during shutdown and do not use target_stop_session(). It will never return a failure, so we can remove that code from the driver. Link: https://lore.kernel.org/r/20210227170006.5077-7-michael.christie@oracle.com Cc: Michael Cyr Reviewed-by: Christoph Hellwig Signed-off-by: Mike Christie Signed-off-by: Martin K. Petersen --- drivers/scsi/ibmvscsi_tgt/ibmvscsi_tgt.c | 15 +++------------ 1 file changed, 3 insertions(+), 12 deletions(-) diff --git a/drivers/scsi/ibmvscsi_tgt/ibmvscsi_tgt.c b/drivers/scsi/ibmvscsi_tgt/ibmvscsi_tgt.c index cc3908c2d2f9..cfc54532402c 100644 --- a/drivers/scsi/ibmvscsi_tgt/ibmvscsi_tgt.c +++ b/drivers/scsi/ibmvscsi_tgt/ibmvscsi_tgt.c @@ -2670,7 +2670,6 @@ static void ibmvscsis_parse_cmd(struct scsi_info *vscsi, u64 data_len = 0; enum dma_data_direction dir; int attr = 0; - int rc = 0; nexus = vscsi->tport.ibmv_nexus; /* @@ -2725,17 +2724,9 @@ static void ibmvscsis_parse_cmd(struct scsi_info *vscsi, srp->lun.scsi_lun[0] &= 0x3f; - rc = target_submit_cmd(&cmd->se_cmd, nexus->se_sess, srp->cdb, - cmd->sense_buf, scsilun_to_int(&srp->lun), - data_len, attr, dir, 0); - if (rc) { - dev_err(&vscsi->dev, "target_submit_cmd failed, rc %d\n", rc); - spin_lock_bh(&vscsi->intr_lock); - list_del(&cmd->list); - ibmvscsis_free_cmd_resources(vscsi, cmd); - spin_unlock_bh(&vscsi->intr_lock); - goto fail; - } + target_submit_cmd(&cmd->se_cmd, nexus->se_sess, srp->cdb, + cmd->sense_buf, scsilun_to_int(&srp->lun), + data_len, attr, dir, 0); return; fail: From 919ba0ad7d5a52cb83ae9aebe4500d8bed0a0830 Mon Sep 17 00:00:00 2001 From: Mike Christie Date: Sat, 27 Feb 2021 10:59:48 -0600 Subject: [PATCH 024/412] scsi: target: qla2xxx: Convert to new submission API target_submit_cmd() is now only for simple drivers that do their own sync during shutdown and do not use target_stop_session(). tcm_qla2xxx uses target_stop_session() to sync session shutdown with LIO core, so we use target_init_cmd()/target_submit_prep()/target_submit(), because target_init_cmd() will detect the target_stop_session() call and return an error. Link: https://lore.kernel.org/r/20210227170006.5077-8-michael.christie@oracle.com Cc: Nilesh Javali Tested-by: Laurence Oberman Reviewed-by: Christoph Hellwig Reviewed-by: Himanshu Madhani Signed-off-by: Mike Christie Signed-off-by: Martin K. Petersen --- drivers/scsi/qla2xxx/tcm_qla2xxx.c | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/drivers/scsi/qla2xxx/tcm_qla2xxx.c b/drivers/scsi/qla2xxx/tcm_qla2xxx.c index b55fc768a2a7..56394d901791 100644 --- a/drivers/scsi/qla2xxx/tcm_qla2xxx.c +++ b/drivers/scsi/qla2xxx/tcm_qla2xxx.c @@ -451,7 +451,7 @@ static int tcm_qla2xxx_handle_cmd(scsi_qla_host_t *vha, struct qla_tgt_cmd *cmd, struct se_portal_group *se_tpg; struct tcm_qla2xxx_tpg *tpg; #endif - int target_flags = TARGET_SCF_ACK_KREF; + int rc, target_flags = TARGET_SCF_ACK_KREF; unsigned long flags; if (bidi) @@ -486,9 +486,17 @@ static int tcm_qla2xxx_handle_cmd(scsi_qla_host_t *vha, struct qla_tgt_cmd *cmd, list_add_tail(&cmd->sess_cmd_list, &sess->sess_cmd_list); spin_unlock_irqrestore(&sess->sess_cmd_lock, flags); - return target_submit_cmd(se_cmd, se_sess, cdb, &cmd->sense_buffer[0], - cmd->unpacked_lun, data_length, fcp_task_attr, - data_dir, target_flags); + rc = target_init_cmd(se_cmd, se_sess, &cmd->sense_buffer[0], + cmd->unpacked_lun, data_length, fcp_task_attr, + data_dir, target_flags); + if (rc) + return rc; + + if (target_submit_prep(se_cmd, cdb, NULL, 0, NULL, 0, NULL, 0)) + return 0; + + target_submit(se_cmd); + return 0; } static void tcm_qla2xxx_handle_data_work(struct work_struct *work) From 17ae18a6efed92ce1bb1a61fa9e7360d3d8fd5b9 Mon Sep 17 00:00:00 2001 From: Mike Christie Date: Sat, 27 Feb 2021 10:59:49 -0600 Subject: [PATCH 025/412] scsi: target: tcm_loop: Convert to new submission API target_submit_cmd_map_sgls() is being removed, so convert loop to the new submission API. Even though loop does its own shutdown sync, this has loop use target_init_cmd()/target_submit_prep()/target_submit() since it needed to map sgls and in the next patches it will use the API to use LIO's workqueue. Link: https://lore.kernel.org/r/20210227170006.5077-9-michael.christie@oracle.com Tested-by: Laurence Oberman Reviewed-by: Christoph Hellwig Signed-off-by: Mike Christie Signed-off-by: Martin K. Petersen --- drivers/target/loopback/tcm_loop.c | 22 ++++++++++------------ 1 file changed, 10 insertions(+), 12 deletions(-) diff --git a/drivers/target/loopback/tcm_loop.c b/drivers/target/loopback/tcm_loop.c index badba437e5f9..461f4125fcab 100644 --- a/drivers/target/loopback/tcm_loop.c +++ b/drivers/target/loopback/tcm_loop.c @@ -113,7 +113,6 @@ static void tcm_loop_submission_work(struct work_struct *work) struct tcm_loop_tpg *tl_tpg; struct scatterlist *sgl_bidi = NULL; u32 sgl_bidi_count = 0, transfer_length; - int rc; tl_hba = *(struct tcm_loop_hba **)shost_priv(sc->device->host); tl_tpg = &tl_hba->tl_hba_tpgs[sc->device->id]; @@ -151,17 +150,16 @@ static void tcm_loop_submission_work(struct work_struct *work) } se_cmd->tag = tl_cmd->sc_cmd_tag; - rc = target_submit_cmd_map_sgls(se_cmd, tl_nexus->se_sess, sc->cmnd, - &tl_cmd->tl_sense_buf[0], tl_cmd->sc->device->lun, - transfer_length, TCM_SIMPLE_TAG, - sc->sc_data_direction, 0, - scsi_sglist(sc), scsi_sg_count(sc), - sgl_bidi, sgl_bidi_count, - scsi_prot_sglist(sc), scsi_prot_sg_count(sc)); - if (rc < 0) { - set_host_byte(sc, DID_NO_CONNECT); - goto out_done; - } + target_init_cmd(se_cmd, tl_nexus->se_sess, &tl_cmd->tl_sense_buf[0], + tl_cmd->sc->device->lun, transfer_length, + TCM_SIMPLE_TAG, sc->sc_data_direction, 0); + + if (target_submit_prep(se_cmd, sc->cmnd, scsi_sglist(sc), + scsi_sg_count(sc), sgl_bidi, sgl_bidi_count, + scsi_prot_sglist(sc), scsi_prot_sg_count(sc))) + return; + + target_submit(se_cmd); return; out_done: From c7e086b8d7539f1eafa7748e9c1c19bf33dd269f Mon Sep 17 00:00:00 2001 From: Mike Christie Date: Sat, 27 Feb 2021 10:59:50 -0600 Subject: [PATCH 026/412] scsi: target: sbp_target: Convert to new submission API target_submit_cmd() is now only for simple drivers that do their own sync during shutdown and do not use target_stop_session(). It will never return a failure, so we can remove that code from the driver. Link: https://lore.kernel.org/r/20210227170006.5077-10-michael.christie@oracle.com Cc: Chris Boot Reviewed-by: Christoph Hellwig Signed-off-by: Mike Christie Signed-off-by: Martin K. Petersen --- drivers/target/sbp/sbp_target.c | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/drivers/target/sbp/sbp_target.c b/drivers/target/sbp/sbp_target.c index 2a6165febd3b..ce84f93c183a 100644 --- a/drivers/target/sbp/sbp_target.c +++ b/drivers/target/sbp/sbp_target.c @@ -1218,11 +1218,9 @@ static void sbp_handle_command(struct sbp_target_request *req) /* only used for printk until we do TMRs */ req->se_cmd.tag = req->orb_pointer; - if (target_submit_cmd(&req->se_cmd, sess->se_sess, req->cmd_buf, - req->sense_buf, unpacked_lun, data_length, - TCM_SIMPLE_TAG, data_dir, TARGET_SCF_ACK_KREF)) - goto err; - + target_submit_cmd(&req->se_cmd, sess->se_sess, req->cmd_buf, + req->sense_buf, unpacked_lun, data_length, + TCM_SIMPLE_TAG, data_dir, TARGET_SCF_ACK_KREF); return; err: From 12340930a3e10a3bec110f808be9eeb301969abf Mon Sep 17 00:00:00 2001 From: Mike Christie Date: Sat, 27 Feb 2021 10:59:51 -0600 Subject: [PATCH 027/412] scsi: target: usb: gadget: Convert to new submission API target_submit_cmd() is now only for simple drivers that do their own sync during shutdown and do not use target_stop_session(). It will never return a failure, so we can remove that code from the driver. Note: Before these patches target_submit_cmd() would never return an error for usb since it does not use target_stop_session(). If it did then we would have hit a refcount error here: transport_send_check_condition_and_sense(se_cmd, TCM_UNSUPPORTED_SCSI_OPCODE, 1); transport_generic_free_cmd(&cmd->se_cmd, 0); transport_send_check_condition_and_sense() calls queue_status and the driver can sometimes do transport_generic_free_cmd() from there via uasp_status_data_cmpl(). In that case, the above transport_generic_free_cmd() would then hit a refcount error. So that other use of the above error path in the driver is also probably wrong, but someone with the hardware needs to fix that. Link: https://lore.kernel.org/r/20210227170006.5077-11-michael.christie@oracle.com Cc: Felipe Balbi Reviewed-by: Christoph Hellwig Signed-off-by: Mike Christie Signed-off-by: Martin K. Petersen --- drivers/usb/gadget/function/f_tcm.c | 16 ++++++---------- 1 file changed, 6 insertions(+), 10 deletions(-) diff --git a/drivers/usb/gadget/function/f_tcm.c b/drivers/usb/gadget/function/f_tcm.c index dcce6e2605f5..7acb507946e6 100644 --- a/drivers/usb/gadget/function/f_tcm.c +++ b/drivers/usb/gadget/function/f_tcm.c @@ -1058,11 +1058,9 @@ static void usbg_cmd_work(struct work_struct *work) goto out; } - if (target_submit_cmd(se_cmd, tv_nexus->tvn_se_sess, cmd->cmd_buf, - cmd->sense_iu.sense, cmd->unpacked_lun, 0, - cmd->prio_attr, dir, flags) < 0) - goto out; - + target_submit_cmd(se_cmd, tv_nexus->tvn_se_sess, cmd->cmd_buf, + cmd->sense_iu.sense, cmd->unpacked_lun, 0, + cmd->prio_attr, dir, flags); return; out: @@ -1189,11 +1187,9 @@ static void bot_cmd_work(struct work_struct *work) goto out; } - if (target_submit_cmd(se_cmd, tv_nexus->tvn_se_sess, - cmd->cmd_buf, cmd->sense_iu.sense, cmd->unpacked_lun, - cmd->data_len, cmd->prio_attr, dir, 0) < 0) - goto out; - + target_submit_cmd(se_cmd, tv_nexus->tvn_se_sess, + cmd->cmd_buf, cmd->sense_iu.sense, cmd->unpacked_lun, + cmd->data_len, cmd->prio_attr, dir, 0); return; out: From eb929804db7c3525bc302aa043369193edd36542 Mon Sep 17 00:00:00 2001 From: Mike Christie Date: Sat, 27 Feb 2021 10:59:52 -0600 Subject: [PATCH 028/412] scsi: target: vhost-scsi: Convert to new submission API target_submit_cmd_map_sgls() is being removed, so convert vhost-scsi to the new submission API. This has it use target_init_cmd(), target_submit_prep(), target_submit() because we need to have LIO core map sgls which is now done in target_submit_prep(), and in the next patches we will do the target_submit step from the LIO workqueue. Note: vhost-scsi never calls target_stop_session() so target_submit_cmd_map_sgls() never failed (in the new API target_init_cmd() handles target_stop_session() being called when cmds are being submitted). If it were to have used target_stop_session() and got an error, we would have hit a refcount bug like xen and usb, because it does: if (rc < 0) { transport_send_check_condition_and_sense(se_cmd, TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE, 0); transport_generic_free_cmd(se_cmd, 0); } transport_send_check_condition_and_sense() calls queue_status which does transport_generic_free_cmd(), and then we do an extra transport_generic_free_cmd() call above which would have dropped the refcount to -1 and the refcount code would spit out errors. Link: https://lore.kernel.org/r/20210227170006.5077-12-michael.christie@oracle.com Cc: "Michael S. Tsirkin" Cc: Stefan Hajnoczi Reviewed-by: Christoph Hellwig Reviewed-by: Stefan Hajnoczi Signed-off-by: Mike Christie Signed-off-by: Martin K. Petersen --- drivers/vhost/scsi.c | 20 +++++++++----------- 1 file changed, 9 insertions(+), 11 deletions(-) diff --git a/drivers/vhost/scsi.c b/drivers/vhost/scsi.c index 936584250a0b..ec7ffd51fe5b 100644 --- a/drivers/vhost/scsi.c +++ b/drivers/vhost/scsi.c @@ -789,7 +789,6 @@ static void vhost_scsi_submission_work(struct work_struct *work) struct vhost_scsi_nexus *tv_nexus; struct se_cmd *se_cmd = &cmd->tvc_se_cmd; struct scatterlist *sg_ptr, *sg_prot_ptr = NULL; - int rc; /* FIXME: BIDI operation */ if (cmd->tvc_sgl_count) { @@ -805,18 +804,17 @@ static void vhost_scsi_submission_work(struct work_struct *work) tv_nexus = cmd->tvc_nexus; se_cmd->tag = 0; - rc = target_submit_cmd_map_sgls(se_cmd, tv_nexus->tvn_se_sess, - cmd->tvc_cdb, &cmd->tvc_sense_buf[0], + target_init_cmd(se_cmd, tv_nexus->tvn_se_sess, &cmd->tvc_sense_buf[0], cmd->tvc_lun, cmd->tvc_exp_data_len, vhost_scsi_to_tcm_attr(cmd->tvc_task_attr), - cmd->tvc_data_direction, TARGET_SCF_ACK_KREF, - sg_ptr, cmd->tvc_sgl_count, NULL, 0, sg_prot_ptr, - cmd->tvc_prot_sgl_count); - if (rc < 0) { - transport_send_check_condition_and_sense(se_cmd, - TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE, 0); - transport_generic_free_cmd(se_cmd, 0); - } + cmd->tvc_data_direction, TARGET_SCF_ACK_KREF); + + if (target_submit_prep(se_cmd, cmd->tvc_cdb, sg_ptr, + cmd->tvc_sgl_count, NULL, 0, sg_prot_ptr, + cmd->tvc_prot_sgl_count)) + return; + + target_submit(se_cmd); } static void From 1f48b065dad168eebc4f184e97d4aab7a732bd6a Mon Sep 17 00:00:00 2001 From: Mike Christie Date: Sat, 27 Feb 2021 10:59:53 -0600 Subject: [PATCH 029/412] scsi: target: xen-scsiback: Convert to new submission API target_submit_cmd_map_sgls() is being removed, so convert xen to the new submission API. This has it use target_init_cmd(), target_submit_prep(), or target_submit() because we need to have LIO core map sgls which is now done in target_submit_prep(). target_init_cmd() will never fail for xen because it does its own sync during session shutdown, so we can remove that code. Note: xen never calls target_stop_session() so target_submit_cmd_map_sgls() never failed (in the new API target_init_cmd() handles target_stop_session() being called when cmds are being submitted). If it were to have used target_stop_session() and got an error, we would have hit a refcount bug like xen and usb, because it does: if (rc < 0) { transport_send_check_condition_and_sense(se_cmd, TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE, 0); transport_generic_free_cmd(se_cmd, 0); } transport_send_check_condition_and_sense() calls queue_status which calls scsiback_cmd_done->target_put_sess_cmd. We do an extra transport_generic_free_cmd() call above which would have dropped the refcount to -1 and the refcount code would spit out errors. Link: https://lore.kernel.org/r/20210227170006.5077-13-michael.christie@oracle.com Reviewed-by: Christoph Hellwig Signed-off-by: Mike Christie Signed-off-by: Martin K. Petersen --- drivers/xen/xen-scsiback.c | 21 +++++++++------------ 1 file changed, 9 insertions(+), 12 deletions(-) diff --git a/drivers/xen/xen-scsiback.c b/drivers/xen/xen-scsiback.c index f3024942fbdf..18b9549f6fa3 100644 --- a/drivers/xen/xen-scsiback.c +++ b/drivers/xen/xen-scsiback.c @@ -360,21 +360,18 @@ static void scsiback_cmd_exec(struct vscsibk_pend *pending_req) { struct se_cmd *se_cmd = &pending_req->se_cmd; struct se_session *sess = pending_req->v2p->tpg->tpg_nexus->tvn_se_sess; - int rc; scsiback_get(pending_req->info); se_cmd->tag = pending_req->rqid; - rc = target_submit_cmd_map_sgls(se_cmd, sess, pending_req->cmnd, - pending_req->sense_buffer, pending_req->v2p->lun, - pending_req->data_len, 0, - pending_req->sc_data_direction, TARGET_SCF_ACK_KREF, - pending_req->sgl, pending_req->n_sg, - NULL, 0, NULL, 0); - if (rc < 0) { - transport_send_check_condition_and_sense(se_cmd, - TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE, 0); - transport_generic_free_cmd(se_cmd, 0); - } + target_init_cmd(se_cmd, sess, pending_req->sense_buffer, + pending_req->v2p->lun, pending_req->data_len, 0, + pending_req->sc_data_direction, TARGET_SCF_ACK_KREF); + + if (target_submit_prep(se_cmd, pending_req->cmnd, pending_req->sgl, + pending_req->n_sg, NULL, 0, NULL, 0)) + return; + + target_submit(se_cmd); } static int scsiback_gnttab_data_map_batch(struct gnttab_map_grant_ref *map, From 47edc84f3376980cc2f573d25844c0260e756166 Mon Sep 17 00:00:00 2001 From: Mike Christie Date: Sat, 27 Feb 2021 10:59:54 -0600 Subject: [PATCH 030/412] scsi: target: tcm_fc: Convert to new submission API target_submit_cmd() is now only for simple drivers that do their own sync during shutdown and do not use target_stop_session(). tcm_fc uses target_stop_session() to sync session shutdown with LIO core, so we use target_init_cmd(), target_submit_prep(), target_submit(), because target_init_cmd() will now detect the target_stop_session() call and return an error. Link: https://lore.kernel.org/r/20210227170006.5077-14-michael.christie@oracle.com Reviewed-by: Christoph Hellwig Signed-off-by: Mike Christie Signed-off-by: Martin K. Petersen --- drivers/target/tcm_fc/tfc_cmd.c | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/drivers/target/tcm_fc/tfc_cmd.c b/drivers/target/tcm_fc/tfc_cmd.c index 768f250680d9..1376501ee3d0 100644 --- a/drivers/target/tcm_fc/tfc_cmd.c +++ b/drivers/target/tcm_fc/tfc_cmd.c @@ -543,16 +543,22 @@ static void ft_send_work(struct work_struct *work) fc_seq_set_resp(cmd->seq, ft_recv_seq, cmd); cmd->se_cmd.tag = fc_seq_exch(cmd->seq)->rxid; + /* * Use a single se_cmd->cmd_kref as we expect to release se_cmd * directly from ft_check_stop_free callback in response path. */ - if (target_submit_cmd(&cmd->se_cmd, cmd->sess->se_sess, fcp->fc_cdb, - &cmd->ft_sense_buffer[0], scsilun_to_int(&fcp->fc_lun), - ntohl(fcp->fc_dl), task_attr, data_dir, - TARGET_SCF_ACK_KREF)) + if (target_init_cmd(&cmd->se_cmd, cmd->sess->se_sess, + &cmd->ft_sense_buffer[0], + scsilun_to_int(&fcp->fc_lun), ntohl(fcp->fc_dl), + task_attr, data_dir, TARGET_SCF_ACK_KREF)) goto err; + if (target_submit_prep(&cmd->se_cmd, fcp->fc_cdb, NULL, 0, NULL, 0, + NULL, 0)) + return; + + target_submit(&cmd->se_cmd); pr_debug("r_ctl %x target_submit_cmd %p\n", fh->fh_r_ctl, cmd); return; From 0fa50a8b1244e7fc7363712e2c14a27db740cdcb Mon Sep 17 00:00:00 2001 From: Mike Christie Date: Sat, 27 Feb 2021 10:59:55 -0600 Subject: [PATCH 031/412] scsi: target: core: Remove target_submit_cmd_map_sgls() Convert target_submit_cmd() to do its own calls and then remove target_submit_cmd_map_sgls() since no one uses it. Link: https://lore.kernel.org/r/20210227170006.5077-15-michael.christie@oracle.com Tested-by: Laurence Oberman Reviewed-by: Bodo Stroesser Signed-off-by: Mike Christie Signed-off-by: Martin K. Petersen --- drivers/target/target_core_transport.c | 78 ++++++-------------------- include/target/target_core_fabric.h | 6 +- 2 files changed, 19 insertions(+), 65 deletions(-) diff --git a/drivers/target/target_core_transport.c b/drivers/target/target_core_transport.c index 000819112bc7..560daf9bb039 100644 --- a/drivers/target/target_core_transport.c +++ b/drivers/target/target_core_transport.c @@ -1753,58 +1753,6 @@ void target_submit(struct se_cmd *se_cmd) } EXPORT_SYMBOL_GPL(target_submit); -/** - * target_submit_cmd_map_sgls - lookup unpacked lun and submit uninitialized - * se_cmd + use pre-allocated SGL memory. - * - * @se_cmd: command descriptor to submit - * @se_sess: associated se_sess for endpoint - * @cdb: pointer to SCSI CDB - * @sense: pointer to SCSI sense buffer - * @unpacked_lun: unpacked LUN to reference for struct se_lun - * @data_length: fabric expected data transfer length - * @task_attr: SAM task attribute - * @data_dir: DMA data direction - * @flags: flags for command submission from target_sc_flags_tables - * @sgl: struct scatterlist memory for unidirectional mapping - * @sgl_count: scatterlist count for unidirectional mapping - * @sgl_bidi: struct scatterlist memory for bidirectional READ mapping - * @sgl_bidi_count: scatterlist count for bidirectional READ mapping - * @sgl_prot: struct scatterlist memory protection information - * @sgl_prot_count: scatterlist count for protection information - * - * Task tags are supported if the caller has set @se_cmd->tag. - * - * Returns non zero to signal active I/O shutdown failure. All other - * setup exceptions will be returned as a SCSI CHECK_CONDITION response, - * but still return zero here. - * - * This may only be called from process context, and also currently - * assumes internal allocation of fabric payload buffer by target-core. - */ -int target_submit_cmd_map_sgls(struct se_cmd *se_cmd, struct se_session *se_sess, - unsigned char *cdb, unsigned char *sense, u64 unpacked_lun, - u32 data_length, int task_attr, int data_dir, int flags, - struct scatterlist *sgl, u32 sgl_count, - struct scatterlist *sgl_bidi, u32 sgl_bidi_count, - struct scatterlist *sgl_prot, u32 sgl_prot_count) -{ - int rc; - - rc = target_init_cmd(se_cmd, se_sess, sense, unpacked_lun, - data_length, task_attr, data_dir, flags); - if (rc < 0) - return rc; - - if (target_submit_prep(se_cmd, cdb, sgl, sgl_count, sgl_bidi, - sgl_bidi_count, sgl_prot, sgl_prot_count)) - return 0; - - target_submit(se_cmd); - return 0; -} -EXPORT_SYMBOL(target_submit_cmd_map_sgls); - /** * target_submit_cmd - lookup unpacked lun and submit uninitialized se_cmd * @@ -1820,22 +1768,32 @@ EXPORT_SYMBOL(target_submit_cmd_map_sgls); * * Task tags are supported if the caller has set @se_cmd->tag. * - * Returns non zero to signal active I/O shutdown failure. All other - * setup exceptions will be returned as a SCSI CHECK_CONDITION response, - * but still return zero here. - * * This may only be called from process context, and also currently * assumes internal allocation of fabric payload buffer by target-core. * * It also assumes interal target core SGL memory allocation. + * + * This function must only be used by drivers that do their own + * sync during shutdown and does not use target_stop_session. If there + * is a failure this function will call into the fabric driver's + * queue_status with a CHECK_CONDITION. */ -int target_submit_cmd(struct se_cmd *se_cmd, struct se_session *se_sess, +void target_submit_cmd(struct se_cmd *se_cmd, struct se_session *se_sess, unsigned char *cdb, unsigned char *sense, u64 unpacked_lun, u32 data_length, int task_attr, int data_dir, int flags) { - return target_submit_cmd_map_sgls(se_cmd, se_sess, cdb, sense, - unpacked_lun, data_length, task_attr, data_dir, - flags, NULL, 0, NULL, 0, NULL, 0); + int rc; + + rc = target_init_cmd(se_cmd, se_sess, sense, unpacked_lun, data_length, + task_attr, data_dir, flags); + WARN(rc, "Invalid target_submit_cmd use. Driver must not use target_stop_session or call target_init_cmd directly.\n"); + if (rc) + return; + + if (target_submit_prep(se_cmd, cdb, NULL, 0, NULL, 0, NULL, 0)) + return; + + target_submit(se_cmd); } EXPORT_SYMBOL(target_submit_cmd); diff --git a/include/target/target_core_fabric.h b/include/target/target_core_fabric.h index 4b5f6687393a..86b0d4a7df92 100644 --- a/include/target/target_core_fabric.h +++ b/include/target/target_core_fabric.h @@ -162,11 +162,7 @@ void target_submit(struct se_cmd *se_cmd); sense_reason_t transport_lookup_cmd_lun(struct se_cmd *); sense_reason_t target_cmd_init_cdb(struct se_cmd *, unsigned char *); sense_reason_t target_cmd_parse_cdb(struct se_cmd *); -int target_submit_cmd_map_sgls(struct se_cmd *, struct se_session *, - unsigned char *, unsigned char *, u64, u32, int, int, int, - struct scatterlist *, u32, struct scatterlist *, u32, - struct scatterlist *, u32); -int target_submit_cmd(struct se_cmd *, struct se_session *, unsigned char *, +void target_submit_cmd(struct se_cmd *, struct se_session *, unsigned char *, unsigned char *, u64, u32, int, int, int); int target_submit_tmr(struct se_cmd *se_cmd, struct se_session *se_sess, unsigned char *sense, u64 unpacked_lun, From 08694199477da412baf1852c6d1bf5fedbd40c7e Mon Sep 17 00:00:00 2001 From: Mike Christie Date: Sat, 27 Feb 2021 10:59:56 -0600 Subject: [PATCH 032/412] scsi: target: core: Add gfp_t arg to target_cmd_init_cdb() tcm_loop could be used like a normal block device, so we can't use GFP_KERNEL and should use GFP_NOIO. This adds a gfp_t arg to target_cmd_init_cdb() and converts the users. For every driver but loop GFP_KERNEL is kept. This will also be useful in subsequent patches where loop needs to do target_submit_prep() from interrupt context to get a ref to the se_device, and so it will need to use GFP_ATOMIC. Link: https://lore.kernel.org/r/20210227170006.5077-16-michael.christie@oracle.com Tested-by: Laurence Oberman Reviewed-by: Christoph Hellwig Signed-off-by: Mike Christie Signed-off-by: Martin K. Petersen --- drivers/infiniband/ulp/srpt/ib_srpt.c | 3 ++- drivers/scsi/qla2xxx/tcm_qla2xxx.c | 3 ++- drivers/target/iscsi/iscsi_target.c | 3 ++- drivers/target/loopback/tcm_loop.c | 3 ++- drivers/target/target_core_transport.c | 14 ++++++++------ drivers/target/target_core_xcopy.c | 2 +- drivers/target/tcm_fc/tfc_cmd.c | 2 +- drivers/vhost/scsi.c | 2 +- drivers/xen/xen-scsiback.c | 2 +- include/target/target_core_fabric.h | 5 +++-- 10 files changed, 23 insertions(+), 16 deletions(-) diff --git a/drivers/infiniband/ulp/srpt/ib_srpt.c b/drivers/infiniband/ulp/srpt/ib_srpt.c index 87741e0b4bca..51c386a215f5 100644 --- a/drivers/infiniband/ulp/srpt/ib_srpt.c +++ b/drivers/infiniband/ulp/srpt/ib_srpt.c @@ -1537,7 +1537,8 @@ static void srpt_handle_cmd(struct srpt_rdma_ch *ch, goto busy; } - if (target_submit_prep(cmd, srp_cmd->cdb, sg, sg_cnt, NULL, 0, NULL, 0)) + if (target_submit_prep(cmd, srp_cmd->cdb, sg, sg_cnt, NULL, 0, NULL, 0, + GFP_KERNEL)) return; target_submit(cmd); diff --git a/drivers/scsi/qla2xxx/tcm_qla2xxx.c b/drivers/scsi/qla2xxx/tcm_qla2xxx.c index 56394d901791..12a2265eb2de 100644 --- a/drivers/scsi/qla2xxx/tcm_qla2xxx.c +++ b/drivers/scsi/qla2xxx/tcm_qla2xxx.c @@ -492,7 +492,8 @@ static int tcm_qla2xxx_handle_cmd(scsi_qla_host_t *vha, struct qla_tgt_cmd *cmd, if (rc) return rc; - if (target_submit_prep(se_cmd, cdb, NULL, 0, NULL, 0, NULL, 0)) + if (target_submit_prep(se_cmd, cdb, NULL, 0, NULL, 0, NULL, 0, + GFP_KERNEL)) return 0; target_submit(se_cmd); diff --git a/drivers/target/iscsi/iscsi_target.c b/drivers/target/iscsi/iscsi_target.c index ef9133a674f6..cf7f0465dd63 100644 --- a/drivers/target/iscsi/iscsi_target.c +++ b/drivers/target/iscsi/iscsi_target.c @@ -1166,7 +1166,8 @@ int iscsit_setup_scsi_cmd(struct iscsi_conn *conn, struct iscsi_cmd *cmd, target_get_sess_cmd(&cmd->se_cmd, true); - cmd->sense_reason = target_cmd_init_cdb(&cmd->se_cmd, hdr->cdb); + cmd->sense_reason = target_cmd_init_cdb(&cmd->se_cmd, hdr->cdb, + GFP_KERNEL); if (cmd->sense_reason) { if (cmd->sense_reason == TCM_OUT_OF_RESOURCES) { return iscsit_add_reject_cmd(cmd, diff --git a/drivers/target/loopback/tcm_loop.c b/drivers/target/loopback/tcm_loop.c index 461f4125fcab..677e4b8f0642 100644 --- a/drivers/target/loopback/tcm_loop.c +++ b/drivers/target/loopback/tcm_loop.c @@ -156,7 +156,8 @@ static void tcm_loop_submission_work(struct work_struct *work) if (target_submit_prep(se_cmd, sc->cmnd, scsi_sglist(sc), scsi_sg_count(sc), sgl_bidi, sgl_bidi_count, - scsi_prot_sglist(sc), scsi_prot_sg_count(sc))) + scsi_prot_sglist(sc), scsi_prot_sg_count(sc), + GFP_NOIO)) return; target_submit(se_cmd); diff --git a/drivers/target/target_core_transport.c b/drivers/target/target_core_transport.c index 560daf9bb039..bd3d125a3978 100644 --- a/drivers/target/target_core_transport.c +++ b/drivers/target/target_core_transport.c @@ -1429,7 +1429,7 @@ transport_check_alloc_task_attr(struct se_cmd *cmd) } sense_reason_t -target_cmd_init_cdb(struct se_cmd *cmd, unsigned char *cdb) +target_cmd_init_cdb(struct se_cmd *cmd, unsigned char *cdb, gfp_t gfp) { sense_reason_t ret; @@ -1450,8 +1450,7 @@ target_cmd_init_cdb(struct se_cmd *cmd, unsigned char *cdb) * setup the pointer from __t_task_cdb to t_task_cdb. */ if (scsi_command_size(cdb) > sizeof(cmd->__t_task_cdb)) { - cmd->t_task_cdb = kzalloc(scsi_command_size(cdb), - GFP_KERNEL); + cmd->t_task_cdb = kzalloc(scsi_command_size(cdb), gfp); if (!cmd->t_task_cdb) { pr_err("Unable to allocate cmd->t_task_cdb" " %u > sizeof(cmd->__t_task_cdb): %lu ops\n", @@ -1640,6 +1639,7 @@ EXPORT_SYMBOL_GPL(target_init_cmd); * @sgl_bidi_count: scatterlist count for bidirectional READ mapping * @sgl_prot: struct scatterlist memory protection information * @sgl_prot_count: scatterlist count for protection information + * @gfp: gfp allocation type * * Returns: * - less than zero to signal failure. @@ -1650,11 +1650,12 @@ EXPORT_SYMBOL_GPL(target_init_cmd); int target_submit_prep(struct se_cmd *se_cmd, unsigned char *cdb, struct scatterlist *sgl, u32 sgl_count, struct scatterlist *sgl_bidi, u32 sgl_bidi_count, - struct scatterlist *sgl_prot, u32 sgl_prot_count) + struct scatterlist *sgl_prot, u32 sgl_prot_count, + gfp_t gfp) { sense_reason_t rc; - rc = target_cmd_init_cdb(se_cmd, cdb); + rc = target_cmd_init_cdb(se_cmd, cdb, gfp); if (rc) goto send_cc_direct; @@ -1790,7 +1791,8 @@ void target_submit_cmd(struct se_cmd *se_cmd, struct se_session *se_sess, if (rc) return; - if (target_submit_prep(se_cmd, cdb, NULL, 0, NULL, 0, NULL, 0)) + if (target_submit_prep(se_cmd, cdb, NULL, 0, NULL, 0, NULL, 0, + GFP_KERNEL)) return; target_submit(se_cmd); diff --git a/drivers/target/target_core_xcopy.c b/drivers/target/target_core_xcopy.c index e86cc6135587..d31ed071cb08 100644 --- a/drivers/target/target_core_xcopy.c +++ b/drivers/target/target_core_xcopy.c @@ -554,7 +554,7 @@ static int target_xcopy_setup_pt_cmd( } cmd->se_cmd_flags |= SCF_SE_LUN_CMD; - if (target_cmd_init_cdb(cmd, cdb)) + if (target_cmd_init_cdb(cmd, cdb, GFP_KERNEL)) return -EINVAL; cmd->tag = 0; diff --git a/drivers/target/tcm_fc/tfc_cmd.c b/drivers/target/tcm_fc/tfc_cmd.c index 1376501ee3d0..410b723f9d79 100644 --- a/drivers/target/tcm_fc/tfc_cmd.c +++ b/drivers/target/tcm_fc/tfc_cmd.c @@ -555,7 +555,7 @@ static void ft_send_work(struct work_struct *work) goto err; if (target_submit_prep(&cmd->se_cmd, fcp->fc_cdb, NULL, 0, NULL, 0, - NULL, 0)) + NULL, 0, GFP_KERNEL)) return; target_submit(&cmd->se_cmd); diff --git a/drivers/vhost/scsi.c b/drivers/vhost/scsi.c index ec7ffd51fe5b..9b448a197cb5 100644 --- a/drivers/vhost/scsi.c +++ b/drivers/vhost/scsi.c @@ -811,7 +811,7 @@ static void vhost_scsi_submission_work(struct work_struct *work) if (target_submit_prep(se_cmd, cmd->tvc_cdb, sg_ptr, cmd->tvc_sgl_count, NULL, 0, sg_prot_ptr, - cmd->tvc_prot_sgl_count)) + cmd->tvc_prot_sgl_count, GFP_KERNEL)) return; target_submit(se_cmd); diff --git a/drivers/xen/xen-scsiback.c b/drivers/xen/xen-scsiback.c index 18b9549f6fa3..55a4763da05e 100644 --- a/drivers/xen/xen-scsiback.c +++ b/drivers/xen/xen-scsiback.c @@ -368,7 +368,7 @@ static void scsiback_cmd_exec(struct vscsibk_pend *pending_req) pending_req->sc_data_direction, TARGET_SCF_ACK_KREF); if (target_submit_prep(se_cmd, pending_req->cmnd, pending_req->sgl, - pending_req->n_sg, NULL, 0, NULL, 0)) + pending_req->n_sg, NULL, 0, NULL, 0, GFP_KERNEL)) return; target_submit(se_cmd); diff --git a/include/target/target_core_fabric.h b/include/target/target_core_fabric.h index 86b0d4a7df92..0543ab107723 100644 --- a/include/target/target_core_fabric.h +++ b/include/target/target_core_fabric.h @@ -157,10 +157,11 @@ int target_init_cmd(struct se_cmd *se_cmd, struct se_session *se_sess, int target_submit_prep(struct se_cmd *se_cmd, unsigned char *cdb, struct scatterlist *sgl, u32 sgl_count, struct scatterlist *sgl_bidi, u32 sgl_bidi_count, - struct scatterlist *sgl_prot, u32 sgl_prot_count); + struct scatterlist *sgl_prot, u32 sgl_prot_count, gfp_t gfp); void target_submit(struct se_cmd *se_cmd); sense_reason_t transport_lookup_cmd_lun(struct se_cmd *); -sense_reason_t target_cmd_init_cdb(struct se_cmd *, unsigned char *); +sense_reason_t target_cmd_init_cdb(struct se_cmd *se_cmd, unsigned char *cdb, + gfp_t gfp); sense_reason_t target_cmd_parse_cdb(struct se_cmd *); void target_submit_cmd(struct se_cmd *, struct se_session *, unsigned char *, unsigned char *, u64, u32, int, int, int); From eb44ce8c8c7d3b45f9204c7f34577960c00d5919 Mon Sep 17 00:00:00 2001 From: Mike Christie Date: Sat, 27 Feb 2021 10:59:57 -0600 Subject: [PATCH 033/412] scsi: target: core: Add workqueue based cmd submission loop and vhost/scsi do their target cmd submission from driver workqueues. This allows them to avoid an issue where the backend may block waiting for resources like tags/requests, mem/locks, etc and that ends up blocking their entire submission path and for the case of vhost-scsi both the submission and completion path. This patch adds a helper drivers can use to submit from a LIO workqueue. This code will then be extended in the next patches to fix the plugging of backend devices. We are only converting vhost/loop initially, but the workqueue based submission will work for other drivers and have similar benefits where the main target loops will not end up blocking one some backend resource. Link: https://lore.kernel.org/r/20210227170006.5077-17-michael.christie@oracle.com Tested-by: Laurence Oberman Reviewed-by: Bodo Stroesser Signed-off-by: Mike Christie Signed-off-by: Martin K. Petersen --- drivers/target/target_core_device.c | 10 ++++-- drivers/target/target_core_internal.h | 1 + drivers/target/target_core_transport.c | 42 +++++++++++++++++++++++++- include/target/target_core_base.h | 8 ++++- include/target/target_core_fabric.h | 2 ++ 5 files changed, 59 insertions(+), 4 deletions(-) diff --git a/drivers/target/target_core_device.c b/drivers/target/target_core_device.c index 7787c527aad3..74d3a4896588 100644 --- a/drivers/target/target_core_device.c +++ b/drivers/target/target_core_device.c @@ -735,8 +735,14 @@ struct se_device *target_alloc_device(struct se_hba *hba, const char *name) dev->queue_cnt = nr_cpu_ids; for (i = 0; i < dev->queue_cnt; i++) { - INIT_LIST_HEAD(&dev->queues[i].state_list); - spin_lock_init(&dev->queues[i].lock); + struct se_device_queue *q; + + q = &dev->queues[i]; + INIT_LIST_HEAD(&q->state_list); + spin_lock_init(&q->lock); + + init_llist_head(&q->sq.cmd_list); + INIT_WORK(&q->sq.work, target_queued_submit_work); } dev->se_hba = hba; diff --git a/drivers/target/target_core_internal.h b/drivers/target/target_core_internal.h index e7b3c6e5d574..56f841fd7f04 100644 --- a/drivers/target/target_core_internal.h +++ b/drivers/target/target_core_internal.h @@ -153,6 +153,7 @@ void target_qf_do_work(struct work_struct *work); bool target_check_wce(struct se_device *dev); bool target_check_fua(struct se_device *dev); void __target_execute_cmd(struct se_cmd *, bool); +void target_queued_submit_work(struct work_struct *work); /* target_core_stat.c */ void target_stat_setup_dev_default_groups(struct se_device *); diff --git a/drivers/target/target_core_transport.c b/drivers/target/target_core_transport.c index bd3d125a3978..eea7c27dc4cd 100644 --- a/drivers/target/target_core_transport.c +++ b/drivers/target/target_core_transport.c @@ -41,6 +41,7 @@ #include static struct workqueue_struct *target_completion_wq; +static struct workqueue_struct *target_submission_wq; static struct kmem_cache *se_sess_cache; struct kmem_cache *se_ua_cache; struct kmem_cache *t10_pr_reg_cache; @@ -129,8 +130,15 @@ int init_se_kmem_caches(void) if (!target_completion_wq) goto out_free_lba_map_mem_cache; + target_submission_wq = alloc_workqueue("target_submission", + WQ_MEM_RECLAIM, 0); + if (!target_submission_wq) + goto out_free_completion_wq; + return 0; +out_free_completion_wq: + destroy_workqueue(target_completion_wq); out_free_lba_map_mem_cache: kmem_cache_destroy(t10_alua_lba_map_mem_cache); out_free_lba_map_cache: @@ -153,6 +161,7 @@ out: void release_se_kmem_caches(void) { + destroy_workqueue(target_submission_wq); destroy_workqueue(target_completion_wq); kmem_cache_destroy(se_sess_cache); kmem_cache_destroy(se_ua_cache); @@ -1382,7 +1391,6 @@ void __target_init_cmd( { INIT_LIST_HEAD(&cmd->se_delayed_node); INIT_LIST_HEAD(&cmd->se_qf_node); - INIT_LIST_HEAD(&cmd->se_cmd_list); INIT_LIST_HEAD(&cmd->state_list); init_completion(&cmd->t_transport_stop_comp); cmd->free_compl = NULL; @@ -1799,6 +1807,38 @@ void target_submit_cmd(struct se_cmd *se_cmd, struct se_session *se_sess, } EXPORT_SYMBOL(target_submit_cmd); +void target_queued_submit_work(struct work_struct *work) +{ + struct se_cmd_queue *sq = container_of(work, struct se_cmd_queue, work); + struct se_cmd *se_cmd, *next_cmd; + struct llist_node *cmd_list; + + cmd_list = llist_del_all(&sq->cmd_list); + if (!cmd_list) + /* Previous call took what we were queued to submit */ + return; + + cmd_list = llist_reverse_order(cmd_list); + llist_for_each_entry_safe(se_cmd, next_cmd, cmd_list, se_cmd_list) + target_submit(se_cmd); +} + +/** + * target_queue_submission - queue the cmd to run on the LIO workqueue + * @se_cmd: command descriptor to submit + */ +void target_queue_submission(struct se_cmd *se_cmd) +{ + struct se_device *se_dev = se_cmd->se_dev; + int cpu = se_cmd->cpuid; + struct se_cmd_queue *sq; + + sq = &se_dev->queues[cpu].sq; + llist_add(&se_cmd->se_cmd_list, &sq->cmd_list); + queue_work_on(cpu, target_submission_wq, &sq->work); +} +EXPORT_SYMBOL_GPL(target_queue_submission); + static void target_complete_tmr_failure(struct work_struct *work) { struct se_cmd *se_cmd = container_of(work, struct se_cmd, work); diff --git a/include/target/target_core_base.h b/include/target/target_core_base.h index 54dcc0eb25fa..ec5a10d2d843 100644 --- a/include/target/target_core_base.h +++ b/include/target/target_core_base.h @@ -488,7 +488,7 @@ struct se_cmd { /* Only used for internal passthrough and legacy TCM fabric modules */ struct se_session *se_sess; struct se_tmr_req *se_tmr_req; - struct list_head se_cmd_list; + struct llist_node se_cmd_list; struct completion *free_compl; struct completion *abrt_compl; const struct target_core_fabric_ops *se_tfo; @@ -765,9 +765,15 @@ struct se_dev_stat_grps { struct config_group scsi_lu_group; }; +struct se_cmd_queue { + struct llist_head cmd_list; + struct work_struct work; +}; + struct se_device_queue { struct list_head state_list; spinlock_t lock; + struct se_cmd_queue sq; }; struct se_device { diff --git a/include/target/target_core_fabric.h b/include/target/target_core_fabric.h index 0543ab107723..3c5ade7a04a6 100644 --- a/include/target/target_core_fabric.h +++ b/include/target/target_core_fabric.h @@ -165,6 +165,8 @@ sense_reason_t target_cmd_init_cdb(struct se_cmd *se_cmd, unsigned char *cdb, sense_reason_t target_cmd_parse_cdb(struct se_cmd *); void target_submit_cmd(struct se_cmd *, struct se_session *, unsigned char *, unsigned char *, u64, u32, int, int, int); +void target_queue_submission(struct se_cmd *se_cmd); + int target_submit_tmr(struct se_cmd *se_cmd, struct se_session *se_sess, unsigned char *sense, u64 unpacked_lun, void *fabric_tmr_ptr, unsigned char tm_type, From 6ec29cb8ad333c1b4efd3acaf7451538c30220ae Mon Sep 17 00:00:00 2001 From: Mike Christie Date: Sat, 27 Feb 2021 10:59:58 -0600 Subject: [PATCH 034/412] scsi: target: vhost-scsi: Use LIO wq cmd submission helper Convert vhost-scsi to use the LIO wq cmd submission helper. Link: https://lore.kernel.org/r/20210227170006.5077-18-michael.christie@oracle.com Signed-off-by: Mike Christie Reviewed-by: Stefan Hajnoczi Signed-off-by: Martin K. Petersen --- drivers/vhost/scsi.c | 36 ++++++------------------------------ 1 file changed, 6 insertions(+), 30 deletions(-) diff --git a/drivers/vhost/scsi.c b/drivers/vhost/scsi.c index 9b448a197cb5..d16c04dcc144 100644 --- a/drivers/vhost/scsi.c +++ b/drivers/vhost/scsi.c @@ -85,7 +85,7 @@ struct vhost_scsi_cmd { /* The number of scatterlists associated with this cmd */ u32 tvc_sgl_count; u32 tvc_prot_sgl_count; - /* Saved unpacked SCSI LUN for vhost_scsi_submission_work() */ + /* Saved unpacked SCSI LUN for vhost_scsi_target_queue_cmd() */ u32 tvc_lun; /* Pointer to the SGL formatted memory from virtio-scsi */ struct scatterlist *tvc_sgl; @@ -101,8 +101,6 @@ struct vhost_scsi_cmd { struct vhost_scsi_nexus *tvc_nexus; /* The TCM I/O descriptor that is accessed via container_of() */ struct se_cmd tvc_se_cmd; - /* work item used for cmwq dispatch to vhost_scsi_submission_work() */ - struct work_struct work; /* Copy of the incoming SCSI command descriptor block (CDB) */ unsigned char tvc_cdb[VHOST_SCSI_MAX_CDB_SIZE]; /* Sense buffer that will be mapped into outgoing status */ @@ -240,8 +238,6 @@ struct vhost_scsi_ctx { struct iov_iter out_iter; }; -static struct workqueue_struct *vhost_scsi_workqueue; - /* Global spinlock to protect vhost_scsi TPG list for vhost IOCTL access */ static DEFINE_MUTEX(vhost_scsi_mutex); static LIST_HEAD(vhost_scsi_list); @@ -782,12 +778,10 @@ static int vhost_scsi_to_tcm_attr(int attr) return TCM_SIMPLE_TAG; } -static void vhost_scsi_submission_work(struct work_struct *work) +static void vhost_scsi_target_queue_cmd(struct vhost_scsi_cmd *cmd) { - struct vhost_scsi_cmd *cmd = - container_of(work, struct vhost_scsi_cmd, work); - struct vhost_scsi_nexus *tv_nexus; struct se_cmd *se_cmd = &cmd->tvc_se_cmd; + struct vhost_scsi_nexus *tv_nexus; struct scatterlist *sg_ptr, *sg_prot_ptr = NULL; /* FIXME: BIDI operation */ @@ -814,7 +808,7 @@ static void vhost_scsi_submission_work(struct work_struct *work) cmd->tvc_prot_sgl_count, GFP_KERNEL)) return; - target_submit(se_cmd); + target_queue_submission(se_cmd); } static void @@ -1130,14 +1124,7 @@ vhost_scsi_handle_vq(struct vhost_scsi *vs, struct vhost_virtqueue *vq) * vhost_scsi_queue_data_in() and vhost_scsi_queue_status() */ cmd->tvc_vq_desc = vc.head; - /* - * Dispatch cmd descriptor for cmwq execution in process - * context provided by vhost_scsi_workqueue. This also ensures - * cmd is executed on the same kworker CPU as this vhost - * thread to gain positive L2 cache locality effects. - */ - INIT_WORK(&cmd->work, vhost_scsi_submission_work); - queue_work(vhost_scsi_workqueue, &cmd->work); + vhost_scsi_target_queue_cmd(cmd); ret = 0; err: /* @@ -2484,17 +2471,9 @@ static int __init vhost_scsi_init(void) " on "UTS_RELEASE"\n", VHOST_SCSI_VERSION, utsname()->sysname, utsname()->machine); - /* - * Use our own dedicated workqueue for submitting I/O into - * target core to avoid contention within system_wq. - */ - vhost_scsi_workqueue = alloc_workqueue("vhost_scsi", 0, 0); - if (!vhost_scsi_workqueue) - goto out; - ret = vhost_scsi_register(); if (ret < 0) - goto out_destroy_workqueue; + goto out; ret = target_register_template(&vhost_scsi_ops); if (ret < 0) @@ -2504,8 +2483,6 @@ static int __init vhost_scsi_init(void) out_vhost_scsi_deregister: vhost_scsi_deregister(); -out_destroy_workqueue: - destroy_workqueue(vhost_scsi_workqueue); out: return ret; }; @@ -2514,7 +2491,6 @@ static void vhost_scsi_exit(void) { target_unregister_template(&vhost_scsi_ops); vhost_scsi_deregister(); - destroy_workqueue(vhost_scsi_workqueue); }; MODULE_DESCRIPTION("VHOST_SCSI series fabric driver"); From e0eb5d38b732b011cd9ed5b1bf9f59b83c2500d3 Mon Sep 17 00:00:00 2001 From: Mike Christie Date: Sat, 27 Feb 2021 10:59:59 -0600 Subject: [PATCH 035/412] scsi: target: tcm_loop: Use block cmd allocator for se_cmds Make tcm_loop use the block layer cmd allocator for se_cmds instead of using the tcm_loop_cmd_cache. In the future when we can use the host tags for internal requests like TMFs we can completely kill the tcm_loop_cmd_cache. Link: https://lore.kernel.org/r/20210227170006.5077-19-michael.christie@oracle.com Tested-by: Laurence Oberman Reviewed-by: Christoph Hellwig Signed-off-by: Mike Christie Signed-off-by: Martin K. Petersen --- drivers/target/loopback/tcm_loop.c | 19 ++++++++----------- 1 file changed, 8 insertions(+), 11 deletions(-) diff --git a/drivers/target/loopback/tcm_loop.c b/drivers/target/loopback/tcm_loop.c index 677e4b8f0642..fb877aec6321 100644 --- a/drivers/target/loopback/tcm_loop.c +++ b/drivers/target/loopback/tcm_loop.c @@ -67,8 +67,12 @@ static void tcm_loop_release_cmd(struct se_cmd *se_cmd) { struct tcm_loop_cmd *tl_cmd = container_of(se_cmd, struct tcm_loop_cmd, tl_se_cmd); + struct scsi_cmnd *sc = tl_cmd->sc; - kmem_cache_free(tcm_loop_cmd_cache, tl_cmd); + if (se_cmd->se_cmd_flags & SCF_SCSI_TMR_CDB) + kmem_cache_free(tcm_loop_cmd_cache, tl_cmd); + else + sc->scsi_done(sc); } static int tcm_loop_show_info(struct seq_file *m, struct Scsi_Host *host) @@ -164,7 +168,6 @@ static void tcm_loop_submission_work(struct work_struct *work) return; out_done: - kmem_cache_free(tcm_loop_cmd_cache, tl_cmd); sc->scsi_done(sc); } @@ -174,20 +177,14 @@ out_done: */ static int tcm_loop_queuecommand(struct Scsi_Host *sh, struct scsi_cmnd *sc) { - struct tcm_loop_cmd *tl_cmd; + struct tcm_loop_cmd *tl_cmd = scsi_cmd_priv(sc); pr_debug("%s() %d:%d:%d:%llu got CDB: 0x%02x scsi_buf_len: %u\n", __func__, sc->device->host->host_no, sc->device->id, sc->device->channel, sc->device->lun, sc->cmnd[0], scsi_bufflen(sc)); - tl_cmd = kmem_cache_zalloc(tcm_loop_cmd_cache, GFP_ATOMIC); - if (!tl_cmd) { - set_host_byte(sc, DID_ERROR); - sc->scsi_done(sc); - return 0; - } - + memset(tl_cmd, 0, sizeof(*tl_cmd)); tl_cmd->sc = sc; tl_cmd->sc_cmd_tag = sc->request->tag; INIT_WORK(&tl_cmd->work, tcm_loop_submission_work); @@ -319,6 +316,7 @@ static struct scsi_host_template tcm_loop_driver_template = { .dma_boundary = PAGE_SIZE - 1, .module = THIS_MODULE, .track_queue_depth = 1, + .cmd_size = sizeof(struct tcm_loop_cmd), }; static int tcm_loop_driver_probe(struct device *dev) @@ -579,7 +577,6 @@ static int tcm_loop_queue_data_or_status(const char *func, if ((se_cmd->se_cmd_flags & SCF_OVERFLOW_BIT) || (se_cmd->se_cmd_flags & SCF_UNDERFLOW_BIT)) scsi_set_resid(sc, se_cmd->residual_count); - sc->scsi_done(sc); return 0; } From 1130b499b4a74baa8248002a4fd4275bf137b7f4 Mon Sep 17 00:00:00 2001 From: Mike Christie Date: Sat, 27 Feb 2021 11:00:00 -0600 Subject: [PATCH 036/412] scsi: target: tcm_loop: Use LIO wq cmd submission helper Convert loop to use the LIO wq cmd submission helper. Link: https://lore.kernel.org/r/20210227170006.5077-20-michael.christie@oracle.com Tested-by: Laurence Oberman Reviewed-by: Bodo Stroesser Signed-off-by: Mike Christie Signed-off-by: Martin K. Petersen --- drivers/target/loopback/tcm_loop.c | 22 ++++++---------------- drivers/target/loopback/tcm_loop.h | 1 - 2 files changed, 6 insertions(+), 17 deletions(-) diff --git a/drivers/target/loopback/tcm_loop.c b/drivers/target/loopback/tcm_loop.c index fb877aec6321..2687fd7d45db 100644 --- a/drivers/target/loopback/tcm_loop.c +++ b/drivers/target/loopback/tcm_loop.c @@ -39,7 +39,6 @@ #define to_tcm_loop_hba(hba) container_of(hba, struct tcm_loop_hba, dev) -static struct workqueue_struct *tcm_loop_workqueue; static struct kmem_cache *tcm_loop_cmd_cache; static int tcm_loop_hba_no_cnt; @@ -106,10 +105,8 @@ static struct device_driver tcm_loop_driverfs = { */ static struct device *tcm_loop_primary; -static void tcm_loop_submission_work(struct work_struct *work) +static void tcm_loop_target_queue_cmd(struct tcm_loop_cmd *tl_cmd) { - struct tcm_loop_cmd *tl_cmd = - container_of(work, struct tcm_loop_cmd, work); struct se_cmd *se_cmd = &tl_cmd->tl_se_cmd; struct scsi_cmnd *sc = tl_cmd->sc; struct tcm_loop_nexus *tl_nexus; @@ -161,10 +158,10 @@ static void tcm_loop_submission_work(struct work_struct *work) if (target_submit_prep(se_cmd, sc->cmnd, scsi_sglist(sc), scsi_sg_count(sc), sgl_bidi, sgl_bidi_count, scsi_prot_sglist(sc), scsi_prot_sg_count(sc), - GFP_NOIO)) + GFP_ATOMIC)) return; - target_submit(se_cmd); + target_queue_submission(se_cmd); return; out_done: @@ -187,8 +184,8 @@ static int tcm_loop_queuecommand(struct Scsi_Host *sh, struct scsi_cmnd *sc) memset(tl_cmd, 0, sizeof(*tl_cmd)); tl_cmd->sc = sc; tl_cmd->sc_cmd_tag = sc->request->tag; - INIT_WORK(&tl_cmd->work, tcm_loop_submission_work); - queue_work(tcm_loop_workqueue, &tl_cmd->work); + + tcm_loop_target_queue_cmd(tl_cmd); return 0; } @@ -1160,17 +1157,13 @@ static int __init tcm_loop_fabric_init(void) { int ret = -ENOMEM; - tcm_loop_workqueue = alloc_workqueue("tcm_loop", 0, 0); - if (!tcm_loop_workqueue) - goto out; - tcm_loop_cmd_cache = kmem_cache_create("tcm_loop_cmd_cache", sizeof(struct tcm_loop_cmd), __alignof__(struct tcm_loop_cmd), 0, NULL); if (!tcm_loop_cmd_cache) { pr_debug("kmem_cache_create() for tcm_loop_cmd_cache failed\n"); - goto out_destroy_workqueue; + goto out; } ret = tcm_loop_alloc_core_bus(); @@ -1187,8 +1180,6 @@ out_release_core_bus: tcm_loop_release_core_bus(); out_destroy_cache: kmem_cache_destroy(tcm_loop_cmd_cache); -out_destroy_workqueue: - destroy_workqueue(tcm_loop_workqueue); out: return ret; } @@ -1198,7 +1189,6 @@ static void __exit tcm_loop_fabric_exit(void) target_unregister_template(&loop_ops); tcm_loop_release_core_bus(); kmem_cache_destroy(tcm_loop_cmd_cache); - destroy_workqueue(tcm_loop_workqueue); } MODULE_DESCRIPTION("TCM loopback virtual Linux/SCSI fabric module"); diff --git a/drivers/target/loopback/tcm_loop.h b/drivers/target/loopback/tcm_loop.h index d3110909a213..437663b3905c 100644 --- a/drivers/target/loopback/tcm_loop.h +++ b/drivers/target/loopback/tcm_loop.h @@ -16,7 +16,6 @@ struct tcm_loop_cmd { struct scsi_cmnd *sc; /* The TCM I/O descriptor that is accessed via container_of() */ struct se_cmd tl_se_cmd; - struct work_struct work; struct completion tmr_done; /* Sense buffer that will be mapped into outgoing status */ unsigned char tl_sense_buf[TRANSPORT_SENSE_BUFFER]; From 802ec4f672ed64fc3e6a09aa0e4a92a018383767 Mon Sep 17 00:00:00 2001 From: Mike Christie Date: Sat, 27 Feb 2021 11:00:01 -0600 Subject: [PATCH 037/412] scsi: target: core: Cleanup cmd flag bits We have a couple holes in the cmd flags definitions. This cleans up the definitions to fix that and make it easier to read. Link: https://lore.kernel.org/r/20210227170006.5077-21-michael.christie@oracle.com Reviewed-by: Chaitanya Kulkarni Reviewed-by: Christoph Hellwig Reviewed-by: Himanshu Madhani Signed-off-by: Mike Christie Signed-off-by: Martin K. Petersen --- include/target/target_core_base.h | 38 +++++++++++++++---------------- 1 file changed, 19 insertions(+), 19 deletions(-) diff --git a/include/target/target_core_base.h b/include/target/target_core_base.h index ec5a10d2d843..fbe5b5b93afa 100644 --- a/include/target/target_core_base.h +++ b/include/target/target_core_base.h @@ -127,25 +127,25 @@ enum transport_state_table { /* Used for struct se_cmd->se_cmd_flags */ enum se_cmd_flags_table { - SCF_SUPPORTED_SAM_OPCODE = 0x00000001, - SCF_TRANSPORT_TASK_SENSE = 0x00000002, - SCF_EMULATED_TASK_SENSE = 0x00000004, - SCF_SCSI_DATA_CDB = 0x00000008, - SCF_SCSI_TMR_CDB = 0x00000010, - SCF_FUA = 0x00000080, - SCF_SE_LUN_CMD = 0x00000100, - SCF_BIDI = 0x00000400, - SCF_SENT_CHECK_CONDITION = 0x00000800, - SCF_OVERFLOW_BIT = 0x00001000, - SCF_UNDERFLOW_BIT = 0x00002000, - SCF_ALUA_NON_OPTIMIZED = 0x00008000, - SCF_PASSTHROUGH_SG_TO_MEM_NOALLOC = 0x00020000, - SCF_COMPARE_AND_WRITE = 0x00080000, - SCF_PASSTHROUGH_PROT_SG_TO_MEM_NOALLOC = 0x00200000, - SCF_ACK_KREF = 0x00400000, - SCF_USE_CPUID = 0x00800000, - SCF_TASK_ATTR_SET = 0x01000000, - SCF_TREAT_READ_AS_NORMAL = 0x02000000, + SCF_SUPPORTED_SAM_OPCODE = (1 << 0), + SCF_TRANSPORT_TASK_SENSE = (1 << 1), + SCF_EMULATED_TASK_SENSE = (1 << 2), + SCF_SCSI_DATA_CDB = (1 << 3), + SCF_SCSI_TMR_CDB = (1 << 4), + SCF_FUA = (1 << 5), + SCF_SE_LUN_CMD = (1 << 6), + SCF_BIDI = (1 << 7), + SCF_SENT_CHECK_CONDITION = (1 << 8), + SCF_OVERFLOW_BIT = (1 << 9), + SCF_UNDERFLOW_BIT = (1 << 10), + SCF_ALUA_NON_OPTIMIZED = (1 << 11), + SCF_PASSTHROUGH_SG_TO_MEM_NOALLOC = (1 << 12), + SCF_COMPARE_AND_WRITE = (1 << 13), + SCF_PASSTHROUGH_PROT_SG_TO_MEM_NOALLOC = (1 << 14), + SCF_ACK_KREF = (1 << 15), + SCF_USE_CPUID = (1 << 16), + SCF_TASK_ATTR_SET = (1 << 17), + SCF_TREAT_READ_AS_NORMAL = (1 << 18), }; /* From 302990ac3b1b1a2b7b66f59a5c88038a51fbe18e Mon Sep 17 00:00:00 2001 From: Mike Christie Date: Sat, 27 Feb 2021 11:00:02 -0600 Subject: [PATCH 038/412] scsi: target: core: Fix backend plugging target_core_iblock is plugging and unplugging on every command and this is causing perf issues for drivers that prefer batched cmds. With recent patches we can now take multiple cmds from a fabric driver queue and then pass them down the backend drivers in a batch. This patch adds this support by adding 2 callouts to the backend for plugging and unplugging the device. Subsequent commits will add support for iblock and tcmu device plugging. Link: https://lore.kernel.org/r/20210227170006.5077-22-michael.christie@oracle.com Reviewed-by: Bodo Stroesser Signed-off-by: Mike Christie Signed-off-by: Martin K. Petersen --- drivers/target/target_core_transport.c | 43 +++++++++++++++++++++++++- include/target/target_core_backend.h | 2 ++ include/target/target_core_base.h | 4 +++ 3 files changed, 48 insertions(+), 1 deletion(-) diff --git a/drivers/target/target_core_transport.c b/drivers/target/target_core_transport.c index eea7c27dc4cd..1245c288d3bf 100644 --- a/drivers/target/target_core_transport.c +++ b/drivers/target/target_core_transport.c @@ -1807,10 +1807,42 @@ void target_submit_cmd(struct se_cmd *se_cmd, struct se_session *se_sess, } EXPORT_SYMBOL(target_submit_cmd); + +static struct se_dev_plug *target_plug_device(struct se_device *se_dev) +{ + struct se_dev_plug *se_plug; + + if (!se_dev->transport->plug_device) + return NULL; + + se_plug = se_dev->transport->plug_device(se_dev); + if (!se_plug) + return NULL; + + se_plug->se_dev = se_dev; + /* + * We have a ref to the lun at this point, but the cmds could + * complete before we unplug, so grab a ref to the se_device so we + * can call back into the backend. + */ + config_group_get(&se_dev->dev_group); + return se_plug; +} + +static void target_unplug_device(struct se_dev_plug *se_plug) +{ + struct se_device *se_dev = se_plug->se_dev; + + se_dev->transport->unplug_device(se_plug); + config_group_put(&se_dev->dev_group); +} + void target_queued_submit_work(struct work_struct *work) { struct se_cmd_queue *sq = container_of(work, struct se_cmd_queue, work); struct se_cmd *se_cmd, *next_cmd; + struct se_dev_plug *se_plug = NULL; + struct se_device *se_dev = NULL; struct llist_node *cmd_list; cmd_list = llist_del_all(&sq->cmd_list); @@ -1819,8 +1851,17 @@ void target_queued_submit_work(struct work_struct *work) return; cmd_list = llist_reverse_order(cmd_list); - llist_for_each_entry_safe(se_cmd, next_cmd, cmd_list, se_cmd_list) + llist_for_each_entry_safe(se_cmd, next_cmd, cmd_list, se_cmd_list) { + if (!se_dev) { + se_dev = se_cmd->se_dev; + se_plug = target_plug_device(se_dev); + } + target_submit(se_cmd); + } + + if (se_plug) + target_unplug_device(se_plug); } /** diff --git a/include/target/target_core_backend.h b/include/target/target_core_backend.h index ce2fba49c95d..1f78b09bba55 100644 --- a/include/target/target_core_backend.h +++ b/include/target/target_core_backend.h @@ -34,6 +34,8 @@ struct target_backend_ops { int (*configure_device)(struct se_device *); void (*destroy_device)(struct se_device *); void (*free_device)(struct se_device *device); + struct se_dev_plug *(*plug_device)(struct se_device *se_dev); + void (*unplug_device)(struct se_dev_plug *se_plug); ssize_t (*set_configfs_dev_params)(struct se_device *, const char *, ssize_t); diff --git a/include/target/target_core_base.h b/include/target/target_core_base.h index fbe5b5b93afa..cf445c3a551a 100644 --- a/include/target/target_core_base.h +++ b/include/target/target_core_base.h @@ -770,6 +770,10 @@ struct se_cmd_queue { struct work_struct work; }; +struct se_dev_plug { + struct se_device *se_dev; +}; + struct se_device_queue { struct list_head state_list; spinlock_t lock; From 415ccd9811da38aed04f54051c8ae87699c4e6c2 Mon Sep 17 00:00:00 2001 From: Mike Christie Date: Sat, 27 Feb 2021 11:00:03 -0600 Subject: [PATCH 039/412] scsi: target: iblock: Add backend plug/unplug callouts This patch adds plug/unplug callouts for iblock. For an initiator driver like iSCSI which wants to pass multiple cmds to its xmit thread instead of one cmd at a time, this increases IOPS by around 10% with vhost-scsi (combined with the last patches we can see a total 40-50% increase). For driver combos like tcm_loop and faster drivers like the iSER initiator, we can still see IOPS increase by 20-30% when tcm_loop's nr_hw_queues setting is also increased. Link: https://lore.kernel.org/r/20210227170006.5077-23-michael.christie@oracle.com Signed-off-by: Mike Christie Signed-off-by: Martin K. Petersen --- drivers/target/target_core_iblock.c | 44 ++++++++++++++++++++++++++++- drivers/target/target_core_iblock.h | 10 +++++++ 2 files changed, 53 insertions(+), 1 deletion(-) diff --git a/drivers/target/target_core_iblock.c b/drivers/target/target_core_iblock.c index ee3d52061281..90e1c65ad4b6 100644 --- a/drivers/target/target_core_iblock.c +++ b/drivers/target/target_core_iblock.c @@ -61,9 +61,18 @@ static struct se_device *iblock_alloc_device(struct se_hba *hba, const char *nam return NULL; } + ib_dev->ibd_plug = kcalloc(nr_cpu_ids, sizeof(*ib_dev->ibd_plug), + GFP_KERNEL); + if (!ib_dev->ibd_plug) + goto free_dev; + pr_debug( "IBLOCK: Allocated ib_dev for %s\n", name); return &ib_dev->dev; + +free_dev: + kfree(ib_dev); + return NULL; } static int iblock_configure_device(struct se_device *dev) @@ -171,6 +180,7 @@ static void iblock_dev_call_rcu(struct rcu_head *p) struct se_device *dev = container_of(p, struct se_device, rcu_head); struct iblock_dev *ib_dev = IBLOCK_DEV(dev); + kfree(ib_dev->ibd_plug); kfree(ib_dev); } @@ -188,6 +198,33 @@ static void iblock_destroy_device(struct se_device *dev) bioset_exit(&ib_dev->ibd_bio_set); } +static struct se_dev_plug *iblock_plug_device(struct se_device *se_dev) +{ + struct iblock_dev *ib_dev = IBLOCK_DEV(se_dev); + struct iblock_dev_plug *ib_dev_plug; + + /* + * Each se_device has a per cpu work this can be run from. Wwe + * shouldn't have multiple threads on the same cpu calling this + * at the same time. + */ + ib_dev_plug = &ib_dev->ibd_plug[smp_processor_id()]; + if (test_and_set_bit(IBD_PLUGF_PLUGGED, &ib_dev_plug->flags)) + return NULL; + + blk_start_plug(&ib_dev_plug->blk_plug); + return &ib_dev_plug->se_plug; +} + +static void iblock_unplug_device(struct se_dev_plug *se_plug) +{ + struct iblock_dev_plug *ib_dev_plug = container_of(se_plug, + struct iblock_dev_plug, se_plug); + + blk_finish_plug(&ib_dev_plug->blk_plug); + clear_bit(IBD_PLUGF_PLUGGED, &ib_dev_plug->flags); +} + static unsigned long long iblock_emulate_read_cap_with_block_size( struct se_device *dev, struct block_device *bd, @@ -335,7 +372,10 @@ static void iblock_submit_bios(struct bio_list *list) { struct blk_plug plug; struct bio *bio; - + /* + * The block layer handles nested plugs, so just plug/unplug to handle + * fabric drivers that didn't support batching and multi bio cmds. + */ blk_start_plug(&plug); while ((bio = bio_list_pop(list))) submit_bio(bio); @@ -867,6 +907,8 @@ static const struct target_backend_ops iblock_ops = { .configure_device = iblock_configure_device, .destroy_device = iblock_destroy_device, .free_device = iblock_free_device, + .plug_device = iblock_plug_device, + .unplug_device = iblock_unplug_device, .parse_cdb = iblock_parse_cdb, .set_configfs_dev_params = iblock_set_configfs_dev_params, .show_configfs_dev_params = iblock_show_configfs_dev_params, diff --git a/drivers/target/target_core_iblock.h b/drivers/target/target_core_iblock.h index cefc641145b3..8c55375d2f75 100644 --- a/drivers/target/target_core_iblock.h +++ b/drivers/target/target_core_iblock.h @@ -4,6 +4,7 @@ #include #include +#include #include #define IBLOCK_VERSION "4.0" @@ -17,6 +18,14 @@ struct iblock_req { #define IBDF_HAS_UDEV_PATH 0x01 +#define IBD_PLUGF_PLUGGED 0x01 + +struct iblock_dev_plug { + struct se_dev_plug se_plug; + struct blk_plug blk_plug; + unsigned long flags; +}; + struct iblock_dev { struct se_device dev; unsigned char ibd_udev_path[SE_UDEV_PATH_LEN]; @@ -24,6 +33,7 @@ struct iblock_dev { struct bio_set ibd_bio_set; struct block_device *ibd_bd; bool ibd_readonly; + struct iblock_dev_plug *ibd_plug; } ____cacheline_aligned; #endif /* TARGET_CORE_IBLOCK_H */ From 6888da8179fd4cfff4c6b62d5587ec2cd21e316d Mon Sep 17 00:00:00 2001 From: Mike Christie Date: Sat, 27 Feb 2021 11:00:04 -0600 Subject: [PATCH 040/412] scsi: target: tcmu: Add backend plug/unplug callouts This patch adds plug/unplug callouts for tcmu, so we can avoid the number of times we switch to userspace. Using this driver with tcm_loop is a common config, and dependng on the nr_hw_queues (nr_hw_queues=1 performs much better) and fio jobs (lower num jobs around 4) this patch can increase IOPS by only around 5-10% because we hit other issues like the big per tcmu device mutex. Link: https://lore.kernel.org/r/20210227170006.5077-24-michael.christie@oracle.com Reviewed-by: Bodo Stroesser Signed-off-by: Mike Christie Signed-off-by: Martin K. Petersen --- drivers/target/target_core_user.c | 27 +++++++++++++++++++++++++-- 1 file changed, 25 insertions(+), 2 deletions(-) diff --git a/drivers/target/target_core_user.c b/drivers/target/target_core_user.c index bf73cd5f4b04..48ccdf7e5bf8 100644 --- a/drivers/target/target_core_user.c +++ b/drivers/target/target_core_user.c @@ -111,6 +111,7 @@ struct tcmu_dev { struct kref kref; struct se_device se_dev; + struct se_dev_plug se_plug; char *name; struct se_hba *hba; @@ -119,6 +120,7 @@ struct tcmu_dev { #define TCMU_DEV_BIT_BROKEN 1 #define TCMU_DEV_BIT_BLOCKED 2 #define TCMU_DEV_BIT_TMR_NOTIFY 3 +#define TCM_DEV_BIT_PLUGGED 4 unsigned long flags; struct uio_info uio_info; @@ -959,6 +961,25 @@ static uint32_t ring_insert_padding(struct tcmu_dev *udev, size_t cmd_size) return cmd_head; } +static void tcmu_unplug_device(struct se_dev_plug *se_plug) +{ + struct se_device *se_dev = se_plug->se_dev; + struct tcmu_dev *udev = TCMU_DEV(se_dev); + + clear_bit(TCM_DEV_BIT_PLUGGED, &udev->flags); + uio_event_notify(&udev->uio_info); +} + +static struct se_dev_plug *tcmu_plug_device(struct se_device *se_dev) +{ + struct tcmu_dev *udev = TCMU_DEV(se_dev); + + if (!test_and_set_bit(TCM_DEV_BIT_PLUGGED, &udev->flags)) + return &udev->se_plug; + + return NULL; +} + /** * queue_cmd_ring - queue cmd to ring or internally * @tcmu_cmd: cmd to queue @@ -1086,8 +1107,8 @@ static int queue_cmd_ring(struct tcmu_cmd *tcmu_cmd, sense_reason_t *scsi_err) list_add_tail(&tcmu_cmd->queue_entry, &udev->inflight_queue); - /* TODO: only if FLUSH and FUA? */ - uio_event_notify(&udev->uio_info); + if (!test_bit(TCM_DEV_BIT_PLUGGED, &udev->flags)) + uio_event_notify(&udev->uio_info); return 0; @@ -2863,6 +2884,8 @@ static struct target_backend_ops tcmu_ops = { .configure_device = tcmu_configure_device, .destroy_device = tcmu_destroy_device, .free_device = tcmu_free_device, + .unplug_device = tcmu_unplug_device, + .plug_device = tcmu_plug_device, .parse_cdb = tcmu_parse_cdb, .tmr_notify = tcmu_tmr_notify, .set_configfs_dev_params = tcmu_set_configfs_dev_params, From 3d75948b8320ac167ec2efe5a8ebf44bdcb3cc14 Mon Sep 17 00:00:00 2001 From: Mike Christie Date: Sat, 27 Feb 2021 11:00:05 -0600 Subject: [PATCH 041/412] scsi: target: core: Flush submission work during TMR processing If a cmd is on the submission workqueue then the TMR code will miss it, and end up returning task not found or success for LUN resets. The fabric driver might then tell the initiator that the running cmds have been handled when they are about to run. This adds a flush when we are processing TMRs to make sure queued cmds do not run after returning the TMR response. Link: https://lore.kernel.org/r/20210227170006.5077-25-michael.christie@oracle.com Tested-by: Laurence Oberman Reviewed-by: Bodo Stroesser Signed-off-by: Mike Christie Signed-off-by: Martin K. Petersen --- drivers/target/target_core_tmr.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/drivers/target/target_core_tmr.c b/drivers/target/target_core_tmr.c index 7347285471fa..e7fcbc09f9db 100644 --- a/drivers/target/target_core_tmr.c +++ b/drivers/target/target_core_tmr.c @@ -124,6 +124,8 @@ void core_tmr_abort_task( int i; for (i = 0; i < dev->queue_cnt; i++) { + flush_work(&dev->queues[i].sq.work); + spin_lock_irqsave(&dev->queues[i].lock, flags); list_for_each_entry_safe(se_cmd, next, &dev->queues[i].state_list, state_list) { @@ -302,6 +304,8 @@ static void core_tmr_drain_state_list( * in the Control Mode Page. */ for (i = 0; i < dev->queue_cnt; i++) { + flush_work(&dev->queues[i].sq.work); + spin_lock_irqsave(&dev->queues[i].lock, flags); list_for_each_entry_safe(cmd, next, &dev->queues[i].state_list, state_list) { From 39ae3edda325e9cf9e978c9788affe88231f3b34 Mon Sep 17 00:00:00 2001 From: Mike Christie Date: Sat, 27 Feb 2021 11:00:06 -0600 Subject: [PATCH 042/412] scsi: target: core: Make completion affinity configurable It may not always be best to complete the IO on same CPU as it was submitted on. This commit allows userspace to configure it. This has been useful for vhost-scsi where we have a single thread for submissions and completions. If we force the completion on the submission CPU we may be adding conflicts with what the user has setup in the lower levels with settings like the block layer rq_affinity or the driver's IRQ or softirq (the network's rps_cpus value) settings. We may also want to set it up where the vhost thread runs on CPU N and does its submissions/completions there, and then have LIO do its completion booking on CPU M, but can't configure the lower levels due to issues like using dm-multipath with lots of paths (the path selector can throw commands all over the system because it's only taking into account latency/throughput at its level). The new setting is in: /sys/kernel/config/target/$fabric/$target/param/cmd_completion_affinity Writing: -1 -> Gives the current default behavior of completing on the submission CPU. -2 -> Completes the cmd on the CPU the lower layers sent it to us from. > 0 -> Completes on the CPU userspace has specified. Link: https://lore.kernel.org/r/20210227170006.5077-26-michael.christie@oracle.com Reviewed-by: Himanshu Madhani Signed-off-by: Mike Christie Signed-off-by: Martin K. Petersen --- drivers/target/target_core_fabric_configfs.c | 58 ++++++++++++++++++++ drivers/target/target_core_internal.h | 1 + drivers/target/target_core_transport.c | 11 +++- include/target/target_core_base.h | 9 +++ 4 files changed, 77 insertions(+), 2 deletions(-) diff --git a/drivers/target/target_core_fabric_configfs.c b/drivers/target/target_core_fabric_configfs.c index ee85602213f7..fc7edc04ee09 100644 --- a/drivers/target/target_core_fabric_configfs.c +++ b/drivers/target/target_core_fabric_configfs.c @@ -892,6 +892,7 @@ static void target_fabric_release_wwn(struct config_item *item) struct target_fabric_configfs *tf = wwn->wwn_tf; configfs_remove_default_groups(&wwn->fabric_stat_group); + configfs_remove_default_groups(&wwn->param_group); tf->tf_ops->fabric_drop_wwn(wwn); } @@ -918,6 +919,57 @@ TF_CIT_SETUP(wwn_fabric_stats, NULL, NULL, NULL); /* End of tfc_wwn_fabric_stats_cit */ +static ssize_t +target_fabric_wwn_cmd_completion_affinity_show(struct config_item *item, + char *page) +{ + struct se_wwn *wwn = container_of(to_config_group(item), struct se_wwn, + param_group); + return sprintf(page, "%d\n", + wwn->cmd_compl_affinity == WORK_CPU_UNBOUND ? + SE_COMPL_AFFINITY_CURR_CPU : wwn->cmd_compl_affinity); +} + +static ssize_t +target_fabric_wwn_cmd_completion_affinity_store(struct config_item *item, + const char *page, size_t count) +{ + struct se_wwn *wwn = container_of(to_config_group(item), struct se_wwn, + param_group); + int compl_val; + + if (kstrtoint(page, 0, &compl_val)) + return -EINVAL; + + switch (compl_val) { + case SE_COMPL_AFFINITY_CPUID: + wwn->cmd_compl_affinity = compl_val; + break; + case SE_COMPL_AFFINITY_CURR_CPU: + wwn->cmd_compl_affinity = WORK_CPU_UNBOUND; + break; + default: + if (compl_val < 0 || compl_val >= nr_cpu_ids || + !cpu_online(compl_val)) { + pr_err("Command completion value must be between %d and %d or an online CPU.\n", + SE_COMPL_AFFINITY_CPUID, + SE_COMPL_AFFINITY_CURR_CPU); + return -EINVAL; + } + wwn->cmd_compl_affinity = compl_val; + } + + return count; +} +CONFIGFS_ATTR(target_fabric_wwn_, cmd_completion_affinity); + +static struct configfs_attribute *target_fabric_wwn_param_attrs[] = { + &target_fabric_wwn_attr_cmd_completion_affinity, + NULL, +}; + +TF_CIT_SETUP(wwn_param, NULL, NULL, target_fabric_wwn_param_attrs); + /* Start of tfc_wwn_cit */ static struct config_group *target_fabric_make_wwn( @@ -937,6 +989,7 @@ static struct config_group *target_fabric_make_wwn( if (!wwn || IS_ERR(wwn)) return ERR_PTR(-EINVAL); + wwn->cmd_compl_affinity = SE_COMPL_AFFINITY_CPUID; wwn->wwn_tf = tf; config_group_init_type_name(&wwn->wwn_group, name, &tf->tf_tpg_cit); @@ -945,6 +998,10 @@ static struct config_group *target_fabric_make_wwn( &tf->tf_wwn_fabric_stats_cit); configfs_add_default_group(&wwn->fabric_stat_group, &wwn->wwn_group); + config_group_init_type_name(&wwn->param_group, "param", + &tf->tf_wwn_param_cit); + configfs_add_default_group(&wwn->param_group, &wwn->wwn_group); + if (tf->tf_ops->add_wwn_groups) tf->tf_ops->add_wwn_groups(wwn); return &wwn->wwn_group; @@ -974,6 +1031,7 @@ int target_fabric_setup_cits(struct target_fabric_configfs *tf) target_fabric_setup_discovery_cit(tf); target_fabric_setup_wwn_cit(tf); target_fabric_setup_wwn_fabric_stats_cit(tf); + target_fabric_setup_wwn_param_cit(tf); target_fabric_setup_tpg_cit(tf); target_fabric_setup_tpg_base_cit(tf); target_fabric_setup_tpg_port_cit(tf); diff --git a/drivers/target/target_core_internal.h b/drivers/target/target_core_internal.h index 56f841fd7f04..a343bcfa2180 100644 --- a/drivers/target/target_core_internal.h +++ b/drivers/target/target_core_internal.h @@ -34,6 +34,7 @@ struct target_fabric_configfs { struct config_item_type tf_discovery_cit; struct config_item_type tf_wwn_cit; struct config_item_type tf_wwn_fabric_stats_cit; + struct config_item_type tf_wwn_param_cit; struct config_item_type tf_tpg_cit; struct config_item_type tf_tpg_base_cit; struct config_item_type tf_tpg_lun_cit; diff --git a/drivers/target/target_core_transport.c b/drivers/target/target_core_transport.c index 1245c288d3bf..a75591c929c0 100644 --- a/drivers/target/target_core_transport.c +++ b/drivers/target/target_core_transport.c @@ -857,7 +857,8 @@ static bool target_cmd_interrupted(struct se_cmd *cmd) /* May be called from interrupt context so must not sleep. */ void target_complete_cmd(struct se_cmd *cmd, u8 scsi_status) { - int success; + struct se_wwn *wwn = cmd->se_sess->se_tpg->se_tpg_wwn; + int success, cpu; unsigned long flags; if (target_cmd_interrupted(cmd)) @@ -884,7 +885,13 @@ void target_complete_cmd(struct se_cmd *cmd, u8 scsi_status) INIT_WORK(&cmd->work, success ? target_complete_ok_work : target_complete_failure_work); - queue_work_on(cmd->cpuid, target_completion_wq, &cmd->work); + + if (wwn->cmd_compl_affinity == SE_COMPL_AFFINITY_CPUID) + cpu = cmd->cpuid; + else + cpu = wwn->cmd_compl_affinity; + + queue_work_on(cpu, target_completion_wq, &cmd->work); } EXPORT_SYMBOL(target_complete_cmd); diff --git a/include/target/target_core_base.h b/include/target/target_core_base.h index cf445c3a551a..d1f7d2a45354 100644 --- a/include/target/target_core_base.h +++ b/include/target/target_core_base.h @@ -944,11 +944,20 @@ static inline struct se_portal_group *param_to_tpg(struct config_item *item) tpg_param_group); } +enum { + /* Use se_cmd's cpuid for completion */ + SE_COMPL_AFFINITY_CPUID = -1, + /* Complete on current CPU */ + SE_COMPL_AFFINITY_CURR_CPU = -2, +}; + struct se_wwn { struct target_fabric_configfs *wwn_tf; void *priv; struct config_group wwn_group; struct config_group fabric_stat_group; + struct config_group param_group; + int cmd_compl_affinity; }; static inline void atomic_inc_mb(atomic_t *v) From af1830956dc3dca0c87b2d679f7c91a8fe0331e1 Mon Sep 17 00:00:00 2001 From: Kashyap Desai Date: Mon, 15 Feb 2021 13:10:44 +0530 Subject: [PATCH 043/412] scsi: core: Add mq_poll support to SCSI layer Currently IOPOLL support is only available in block layer. This patch adds mq_poll support to the SCSI layer. Link: https://lore.kernel.org/r/20210215074048.19424-2-kashyap.desai@broadcom.com Cc: sumit.saxena@broadcom.com Cc: chandrakanth.patil@broadcom.com Cc: linux-block@vger.kernel.org Reviewed-by: Hannes Reinecke Reviewed-by: John Garry Signed-off-by: Kashyap Desai Signed-off-by: Martin K. Petersen --- drivers/scsi/scsi_lib.c | 16 ++++++++++++++++ include/scsi/scsi_cmnd.h | 1 + include/scsi/scsi_host.h | 11 +++++++++++ 3 files changed, 28 insertions(+) diff --git a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c index ffe824782647..09d09ef9d193 100644 --- a/drivers/scsi/scsi_lib.c +++ b/drivers/scsi/scsi_lib.c @@ -1810,6 +1810,19 @@ static void scsi_mq_exit_request(struct blk_mq_tag_set *set, struct request *rq, cmd->sense_buffer); } + +static int scsi_mq_poll(struct blk_mq_hw_ctx *hctx) +{ + struct request_queue *q = hctx->queue; + struct scsi_device *sdev = q->queuedata; + struct Scsi_Host *shost = sdev->host; + + if (shost->hostt->mq_poll) + return shost->hostt->mq_poll(shost, hctx->queue_num); + + return 0; +} + static int scsi_map_queues(struct blk_mq_tag_set *set) { struct Scsi_Host *shost = container_of(set, struct Scsi_Host, tag_set); @@ -1877,6 +1890,7 @@ static const struct blk_mq_ops scsi_mq_ops_no_commit = { .cleanup_rq = scsi_cleanup_rq, .busy = scsi_mq_lld_busy, .map_queues = scsi_map_queues, + .poll = scsi_mq_poll, .set_rq_budget_token = scsi_mq_set_rq_budget_token, .get_rq_budget_token = scsi_mq_get_rq_budget_token, }; @@ -1907,6 +1921,7 @@ static const struct blk_mq_ops scsi_mq_ops = { .cleanup_rq = scsi_cleanup_rq, .busy = scsi_mq_lld_busy, .map_queues = scsi_map_queues, + .poll = scsi_mq_poll, .set_rq_budget_token = scsi_mq_set_rq_budget_token, .get_rq_budget_token = scsi_mq_get_rq_budget_token, }; @@ -1941,6 +1956,7 @@ int scsi_mq_setup_tags(struct Scsi_Host *shost) else tag_set->ops = &scsi_mq_ops_no_commit; tag_set->nr_hw_queues = shost->nr_hw_queues ? : 1; + tag_set->nr_maps = shost->nr_maps ? : 1; tag_set->queue_depth = shost->can_queue; tag_set->cmd_size = cmd_size; tag_set->numa_node = NUMA_NO_NODE; diff --git a/include/scsi/scsi_cmnd.h b/include/scsi/scsi_cmnd.h index 0cf2b5ccc1f7..83f7e520be48 100644 --- a/include/scsi/scsi_cmnd.h +++ b/include/scsi/scsi_cmnd.h @@ -10,6 +10,7 @@ #include #include #include +#include #include struct Scsi_Host; diff --git a/include/scsi/scsi_host.h b/include/scsi/scsi_host.h index f0e8a9e73002..d95c1502e17d 100644 --- a/include/scsi/scsi_host.h +++ b/include/scsi/scsi_host.h @@ -280,6 +280,16 @@ struct scsi_host_template { */ int (* map_queues)(struct Scsi_Host *shost); + /* + * SCSI interface of blk_poll - poll for IO completions. + * Only applicable if SCSI LLD exposes multiple h/w queues. + * + * Return value: Number of completed entries found. + * + * Status: OPTIONAL + */ + int (* mq_poll)(struct Scsi_Host *shost, unsigned int queue_num); + /* * Check if scatterlists need to be padded for DMA draining. * @@ -622,6 +632,7 @@ struct Scsi_Host { * the total queue depth is can_queue. */ unsigned nr_hw_queues; + unsigned nr_maps; unsigned active_mode:2; unsigned unchecked_isa_dma:1; From 9e4bec5b2a230066a0dc9f79f24b4c1bcb668c5a Mon Sep 17 00:00:00 2001 From: Kashyap Desai Date: Mon, 15 Feb 2021 13:10:45 +0530 Subject: [PATCH 044/412] scsi: megaraid_sas: mq_poll support Implement mq_poll interface support in megaraid_sas. This feature requires shared host tag support in kernel and driver. The driver can work in non-IRQ mode which means there will not be any MSI-x vector associated for poll_queues. The MegaRAID hardware has a single submission queue and multiple reply queues. However, using the shared host tagset support will enable the driver to simulate multiple hardware queues. Change driver to allocate some extra reply queues which will be marked as poll_queues. These poll_queues will not have associated MSI-x vectors. All I/O completions on these queues will be done through the IOPOLL interface. megaraid_sas with 8 poll_queues and using the io_uring hiprio=1 setting can reach 3.2M IOPS with zero interrupts generated by the hardware. The IOPOLL feature can be enabled using module parameter poll_queues. Link: https://lore.kernel.org/r/20210215074048.19424-3-kashyap.desai@broadcom.com Cc: sumit.saxena@broadcom.com Cc: chandrakanth.patil@broadcom.com Cc: linux-block@vger.kernel.org Reviewed-by: Hannes Reinecke Signed-off-by: Kashyap Desai Signed-off-by: Martin K. Petersen --- drivers/scsi/megaraid/megaraid_sas.h | 3 + drivers/scsi/megaraid/megaraid_sas_base.c | 87 ++++++++++++++++++--- drivers/scsi/megaraid/megaraid_sas_fusion.c | 42 +++++++++- drivers/scsi/megaraid/megaraid_sas_fusion.h | 2 + 4 files changed, 123 insertions(+), 11 deletions(-) diff --git a/drivers/scsi/megaraid/megaraid_sas.h b/drivers/scsi/megaraid/megaraid_sas.h index 0c6a56b24c6e..b5a765b73c76 100644 --- a/drivers/scsi/megaraid/megaraid_sas.h +++ b/drivers/scsi/megaraid/megaraid_sas.h @@ -2214,6 +2214,7 @@ struct megasas_irq_context { struct irq_poll irqpoll; bool irq_poll_scheduled; bool irq_line_enable; + atomic_t in_used; }; struct MR_DRV_SYSTEM_INFO { @@ -2448,6 +2449,7 @@ struct megasas_instance { bool support_pci_lane_margining; u8 low_latency_index_start; int perf_mode; + int iopoll_q_count; }; struct MR_LD_VF_MAP { @@ -2728,5 +2730,6 @@ void megasas_init_debugfs(void); void megasas_exit_debugfs(void); void megasas_setup_debugfs(struct megasas_instance *instance); void megasas_destroy_debugfs(struct megasas_instance *instance); +int megasas_blk_mq_poll(struct Scsi_Host *shost, unsigned int queue_num); #endif /*LSI_MEGARAID_SAS_H */ diff --git a/drivers/scsi/megaraid/megaraid_sas_base.c b/drivers/scsi/megaraid/megaraid_sas_base.c index 63a4f48bdc75..25673d0ee524 100644 --- a/drivers/scsi/megaraid/megaraid_sas_base.c +++ b/drivers/scsi/megaraid/megaraid_sas_base.c @@ -114,6 +114,15 @@ unsigned int enable_sdev_max_qd; module_param(enable_sdev_max_qd, int, 0444); MODULE_PARM_DESC(enable_sdev_max_qd, "Enable sdev max qd as can_queue. Default: 0"); +int poll_queues; +module_param(poll_queues, int, 0444); +MODULE_PARM_DESC(poll_queues, "Number of queues to be use for io_uring poll mode.\n\t\t" + "This parameter is effective only if host_tagset_enable=1 &\n\t\t" + "It is not applicable for MFI_SERIES. &\n\t\t" + "Driver will work in latency mode. &\n\t\t" + "High iops queues are not allocated &\n\t\t" + ); + int host_tagset_enable = 1; module_param(host_tagset_enable, int, 0444); MODULE_PARM_DESC(host_tagset_enable, "Shared host tagset enable/disable Default: enable(1)"); @@ -207,6 +216,7 @@ static bool support_pci_lane_margining; static spinlock_t poll_aen_lock; extern struct dentry *megasas_debugfs_root; +extern int megasas_blk_mq_poll(struct Scsi_Host *shost, unsigned int queue_num); void megasas_complete_cmd(struct megasas_instance *instance, struct megasas_cmd *cmd, @@ -3127,14 +3137,37 @@ megasas_bios_param(struct scsi_device *sdev, struct block_device *bdev, static int megasas_map_queues(struct Scsi_Host *shost) { struct megasas_instance *instance; + int qoff = 0, offset; + struct blk_mq_queue_map *map; instance = (struct megasas_instance *)shost->hostdata; if (shost->nr_hw_queues == 1) return 0; - return blk_mq_pci_map_queues(&shost->tag_set.map[HCTX_TYPE_DEFAULT], - instance->pdev, instance->low_latency_index_start); + offset = instance->low_latency_index_start; + + /* Setup Default hctx */ + map = &shost->tag_set.map[HCTX_TYPE_DEFAULT]; + map->nr_queues = instance->msix_vectors - offset; + map->queue_offset = 0; + blk_mq_pci_map_queues(map, instance->pdev, offset); + qoff += map->nr_queues; + offset += map->nr_queues; + + /* Setup Poll hctx */ + map = &shost->tag_set.map[HCTX_TYPE_POLL]; + map->nr_queues = instance->iopoll_q_count; + if (map->nr_queues) { + /* + * The poll queue(s) doesn't have an IRQ (and hence IRQ + * affinity), so use the regular blk-mq cpu mapping + */ + map->queue_offset = qoff; + blk_mq_map_queues(map); + } + + return 0; } static void megasas_aen_polling(struct work_struct *work); @@ -3446,6 +3479,7 @@ static struct scsi_host_template megasas_template = { .shost_attrs = megaraid_host_attrs, .bios_param = megasas_bios_param, .map_queues = megasas_map_queues, + .mq_poll = megasas_blk_mq_poll, .change_queue_depth = scsi_change_queue_depth, .max_segment_size = 0xffffffff, }; @@ -5834,13 +5868,16 @@ __megasas_alloc_irq_vectors(struct megasas_instance *instance) irq_flags = PCI_IRQ_MSIX; if (instance->smp_affinity_enable) - irq_flags |= PCI_IRQ_AFFINITY; + irq_flags |= PCI_IRQ_AFFINITY | PCI_IRQ_ALL_TYPES; else descp = NULL; + /* Do not allocate msix vectors for poll_queues. + * msix_vectors is always within a range of FW supported reply queue. + */ i = pci_alloc_irq_vectors_affinity(instance->pdev, instance->low_latency_index_start, - instance->msix_vectors, irq_flags, descp); + instance->msix_vectors - instance->iopoll_q_count, irq_flags, descp); return i; } @@ -5856,10 +5893,30 @@ megasas_alloc_irq_vectors(struct megasas_instance *instance) int i; unsigned int num_msix_req; + instance->iopoll_q_count = 0; + if ((instance->adapter_type != MFI_SERIES) && + poll_queues) { + + instance->perf_mode = MR_LATENCY_PERF_MODE; + instance->low_latency_index_start = 1; + + /* reserve for default and non-mananged pre-vector. */ + if (instance->msix_vectors > (poll_queues + 2)) + instance->iopoll_q_count = poll_queues; + else + instance->iopoll_q_count = 0; + + num_msix_req = num_online_cpus() + instance->low_latency_index_start; + instance->msix_vectors = min(num_msix_req, + instance->msix_vectors); + + } + i = __megasas_alloc_irq_vectors(instance); - if ((instance->perf_mode == MR_BALANCED_PERF_MODE) && - (i != instance->msix_vectors)) { + if (((instance->perf_mode == MR_BALANCED_PERF_MODE) + || instance->iopoll_q_count) && + (i != (instance->msix_vectors - instance->iopoll_q_count))) { if (instance->msix_vectors) pci_free_irq_vectors(instance->pdev); /* Disable Balanced IOPS mode and try realloc vectors */ @@ -5870,12 +5927,15 @@ megasas_alloc_irq_vectors(struct megasas_instance *instance) instance->msix_vectors = min(num_msix_req, instance->msix_vectors); + instance->iopoll_q_count = 0; i = __megasas_alloc_irq_vectors(instance); } dev_info(&instance->pdev->dev, - "requested/available msix %d/%d\n", instance->msix_vectors, i); + "requested/available msix %d/%d poll_queue %d\n", + instance->msix_vectors - instance->iopoll_q_count, + i, instance->iopoll_q_count); if (i > 0) instance->msix_vectors = i; @@ -6841,12 +6901,18 @@ static int megasas_io_attach(struct megasas_instance *instance) instance->smp_affinity_enable) { host->host_tagset = 1; host->nr_hw_queues = instance->msix_vectors - - instance->low_latency_index_start; + instance->low_latency_index_start + instance->iopoll_q_count; + if (instance->iopoll_q_count) + host->nr_maps = 3; + } else { + instance->iopoll_q_count = 0; } dev_info(&instance->pdev->dev, - "Max firmware commands: %d shared with nr_hw_queues = %d\n", - instance->max_fw_cmds, host->nr_hw_queues); + "Max firmware commands: %d shared with default " + "hw_queues = %d poll_queues %d\n", instance->max_fw_cmds, + host->nr_hw_queues - instance->iopoll_q_count, + instance->iopoll_q_count); /* * Notify the mid-layer about the new controller */ @@ -8859,6 +8925,7 @@ static int __init megasas_init(void) msix_vectors = 1; rdpq_enable = 0; dual_qdepth_disable = 1; + poll_queues = 0; } /* diff --git a/drivers/scsi/megaraid/megaraid_sas_fusion.c b/drivers/scsi/megaraid/megaraid_sas_fusion.c index f3448567ce28..2221175ae051 100644 --- a/drivers/scsi/megaraid/megaraid_sas_fusion.c +++ b/drivers/scsi/megaraid/megaraid_sas_fusion.c @@ -713,6 +713,8 @@ megasas_alloc_reply_fusion(struct megasas_instance *instance) fusion = instance->ctrl_context; count = instance->msix_vectors > 0 ? instance->msix_vectors : 1; + count += instance->iopoll_q_count; + fusion->reply_frames_desc_pool = dma_pool_create("mr_reply", &instance->pdev->dev, fusion->reply_alloc_sz * count, 16, 0); @@ -807,6 +809,7 @@ megasas_alloc_rdpq_fusion(struct megasas_instance *instance) } msix_count = instance->msix_vectors > 0 ? instance->msix_vectors : 1; + msix_count += instance->iopoll_q_count; fusion->reply_frames_desc_pool = dma_pool_create("mr_rdpq", &instance->pdev->dev, @@ -1157,7 +1160,7 @@ megasas_ioc_init_fusion(struct megasas_instance *instance) MPI2_IOCINIT_MSGFLAG_RDPQ_ARRAY_MODE : 0; IOCInitMessage->SystemRequestFrameBaseAddress = cpu_to_le64(fusion->io_request_frames_phys); IOCInitMessage->SenseBufferAddressHigh = cpu_to_le32(upper_32_bits(fusion->sense_phys_addr)); - IOCInitMessage->HostMSIxVectors = instance->msix_vectors; + IOCInitMessage->HostMSIxVectors = instance->msix_vectors + instance->iopoll_q_count; IOCInitMessage->HostPageSize = MR_DEFAULT_NVME_PAGE_SHIFT; time = ktime_get_real(); @@ -1851,6 +1854,8 @@ megasas_init_adapter_fusion(struct megasas_instance *instance) sizeof(union MPI2_SGE_IO_UNION))/16; count = instance->msix_vectors > 0 ? instance->msix_vectors : 1; + count += instance->iopoll_q_count; + for (i = 0 ; i < count; i++) fusion->last_reply_idx[i] = 0; @@ -1863,6 +1868,9 @@ megasas_init_adapter_fusion(struct megasas_instance *instance) MEGASAS_FUSION_IOCTL_CMDS); sema_init(&instance->ioctl_sem, MEGASAS_FUSION_IOCTL_CMDS); + for (i = 0; i < MAX_MSIX_QUEUES_FUSION; i++) + atomic_set(&fusion->busy_mq_poll[i], 0); + if (megasas_alloc_ioc_init_frame(instance)) return 1; @@ -3530,6 +3538,9 @@ complete_cmd_fusion(struct megasas_instance *instance, u32 MSIxIndex, if (reply_descript_type == MPI2_RPY_DESCRIPT_FLAGS_UNUSED) return IRQ_NONE; + if (irq_context && !atomic_add_unless(&irq_context->in_used, 1, 1)) + return 0; + num_completed = 0; while (d_val.u.low != cpu_to_le32(UINT_MAX) && @@ -3644,6 +3655,7 @@ complete_cmd_fusion(struct megasas_instance *instance, u32 MSIxIndex, irq_context->irq_line_enable = true; irq_poll_sched(&irq_context->irqpoll); } + atomic_dec(&irq_context->in_used); return num_completed; } } @@ -3661,9 +3673,35 @@ complete_cmd_fusion(struct megasas_instance *instance, u32 MSIxIndex, instance->reply_post_host_index_addr[0]); megasas_check_and_restore_queue_depth(instance); } + + if (irq_context) + atomic_dec(&irq_context->in_used); + return num_completed; } +int megasas_blk_mq_poll(struct Scsi_Host *shost, unsigned int queue_num) +{ + + struct megasas_instance *instance; + int num_entries = 0; + struct fusion_context *fusion; + + instance = (struct megasas_instance *)shost->hostdata; + + fusion = instance->ctrl_context; + + queue_num = queue_num + instance->low_latency_index_start; + + if (!atomic_add_unless(&fusion->busy_mq_poll[queue_num], 1, 1)) + return 0; + + num_entries = complete_cmd_fusion(instance, queue_num, NULL); + atomic_dec(&fusion->busy_mq_poll[queue_num]); + + return num_entries; +} + /** * megasas_enable_irq_poll() - enable irqpoll * @instance: Adapter soft state @@ -4194,6 +4232,8 @@ void megasas_reset_reply_desc(struct megasas_instance *instance) fusion = instance->ctrl_context; count = instance->msix_vectors > 0 ? instance->msix_vectors : 1; + count += instance->iopoll_q_count; + for (i = 0 ; i < count ; i++) { fusion->last_reply_idx[i] = 0; reply_desc = fusion->reply_frames_desc[i]; diff --git a/drivers/scsi/megaraid/megaraid_sas_fusion.h b/drivers/scsi/megaraid/megaraid_sas_fusion.h index 30de4b01f703..ce84f811e5e1 100644 --- a/drivers/scsi/megaraid/megaraid_sas_fusion.h +++ b/drivers/scsi/megaraid/megaraid_sas_fusion.h @@ -1303,6 +1303,8 @@ struct fusion_context { u8 *sense; dma_addr_t sense_phys_addr; + atomic_t busy_mq_poll[MAX_MSIX_QUEUES_FUSION]; + dma_addr_t reply_frames_desc_phys[MAX_MSIX_QUEUES_FUSION]; union MPI2_REPLY_DESCRIPTORS_UNION *reply_frames_desc[MAX_MSIX_QUEUES_FUSION]; struct rdpq_alloc_detail rdpq_tracker[RDPQ_MAX_CHUNK_COUNT]; From c4b57d89bad8282c9f461e6b3308df160c50ff8e Mon Sep 17 00:00:00 2001 From: Kashyap Desai Date: Mon, 15 Feb 2021 13:10:46 +0530 Subject: [PATCH 045/412] scsi: scsi_debug: mq_poll support Add support of the mq_poll interface to scsi_debug. This feature requires shared host tag support in kernel and driver. Signed-off-by: Kashyap Desai Acked-by: Douglas Gilbert Tested-by: Douglas Gilbert Reviewed-by: Hannes Reinecke Link: https://lore.kernel.org/r/20210215074048.19424-4-kashyap.desai@broadcom.com Cc: dgilbert@interlog.com Cc: linux-block@vger.kernel.org Signed-off-by: Martin K. Petersen --- drivers/scsi/scsi_debug.c | 130 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 130 insertions(+) diff --git a/drivers/scsi/scsi_debug.c b/drivers/scsi/scsi_debug.c index 3cdeaeb92933..5ea09fe72544 100644 --- a/drivers/scsi/scsi_debug.c +++ b/drivers/scsi/scsi_debug.c @@ -829,6 +829,7 @@ static int sdeb_zbc_max_open = DEF_ZBC_MAX_OPEN_ZONES; static int sdeb_zbc_nr_conv = DEF_ZBC_NR_CONV_ZONES; static int submit_queues = DEF_SUBMIT_QUEUES; /* > 1 for multi-queue (mq) */ +static int poll_queues; /* iouring iopoll interface.*/ static struct sdebug_queue *sdebug_q_arr; /* ptr to array of submit queues */ static DEFINE_RWLOCK(atomic_rw); @@ -5432,6 +5433,14 @@ static int schedule_resp(struct scsi_cmnd *cmnd, struct sdebug_dev_info *devip, cmnd->host_scribble = (unsigned char *)sqcp; sd_dp = sqcp->sd_dp; spin_unlock_irqrestore(&sqp->qc_lock, iflags); + + /* Do not complete IO from default completion path. + * Let it to be on queue. + * Completion should happen from mq_poll interface. + */ + if ((sqp - sdebug_q_arr) >= (submit_queues - poll_queues)) + return 0; + if (!sd_dp) { sd_dp = kzalloc(sizeof(*sd_dp), GFP_ATOMIC); if (!sd_dp) { @@ -5615,6 +5624,7 @@ module_param_named(sector_size, sdebug_sector_size, int, S_IRUGO); module_param_named(statistics, sdebug_statistics, bool, S_IRUGO | S_IWUSR); module_param_named(strict, sdebug_strict, bool, S_IRUGO | S_IWUSR); module_param_named(submit_queues, submit_queues, int, S_IRUGO); +module_param_named(poll_queues, poll_queues, int, S_IRUGO); module_param_named(tur_ms_to_ready, sdeb_tur_ms_to_ready, int, S_IRUGO); module_param_named(unmap_alignment, sdebug_unmap_alignment, int, S_IRUGO); module_param_named(unmap_granularity, sdebug_unmap_granularity, int, S_IRUGO); @@ -5677,6 +5687,7 @@ MODULE_PARM_DESC(opt_xferlen_exp, "optimal transfer length granularity exponent MODULE_PARM_DESC(opts, "1->noise, 2->medium_err, 4->timeout, 8->recovered_err... (def=0)"); MODULE_PARM_DESC(per_host_store, "If set, next positive add_host will get new store (def=0)"); MODULE_PARM_DESC(physblk_exp, "physical block exponent (def=0)"); +MODULE_PARM_DESC(poll_queues, "support for iouring iopoll queues (1 to max(submit_queues - 1)"); MODULE_PARM_DESC(ptype, "SCSI peripheral type(def=0[disk])"); MODULE_PARM_DESC(random, "If set, uniformly randomize command duration between 0 and delay_in_ns"); MODULE_PARM_DESC(removable, "claim to have removable media (def=0)"); @@ -7202,6 +7213,104 @@ static int resp_not_ready(struct scsi_cmnd *scp, struct sdebug_dev_info *devip) return check_condition_result; } +static int sdebug_map_queues(struct Scsi_Host *shost) +{ + int i, qoff; + + if (shost->nr_hw_queues == 1) + return 0; + + for (i = 0, qoff = 0; i < HCTX_MAX_TYPES; i++) { + struct blk_mq_queue_map *map = &shost->tag_set.map[i]; + + map->nr_queues = 0; + + if (i == HCTX_TYPE_DEFAULT) + map->nr_queues = submit_queues - poll_queues; + else if (i == HCTX_TYPE_POLL) + map->nr_queues = poll_queues; + + if (!map->nr_queues) { + BUG_ON(i == HCTX_TYPE_DEFAULT); + continue; + } + + map->queue_offset = qoff; + blk_mq_map_queues(map); + + qoff += map->nr_queues; + } + + return 0; + +} + +static int sdebug_blk_mq_poll(struct Scsi_Host *shost, unsigned int queue_num) +{ + int qc_idx; + int retiring = 0; + unsigned long iflags; + struct sdebug_queue *sqp; + struct sdebug_queued_cmd *sqcp; + struct scsi_cmnd *scp; + struct sdebug_dev_info *devip; + int num_entries = 0; + + sqp = sdebug_q_arr + queue_num; + + do { + spin_lock_irqsave(&sqp->qc_lock, iflags); + qc_idx = find_first_bit(sqp->in_use_bm, sdebug_max_queue); + if (unlikely((qc_idx < 0) || (qc_idx >= sdebug_max_queue))) + goto out; + + sqcp = &sqp->qc_arr[qc_idx]; + scp = sqcp->a_cmnd; + if (unlikely(scp == NULL)) { + pr_err("scp is NULL, queue_num=%d, qc_idx=%d from %s\n", + queue_num, qc_idx, __func__); + goto out; + } + devip = (struct sdebug_dev_info *)scp->device->hostdata; + if (likely(devip)) + atomic_dec(&devip->num_in_q); + else + pr_err("devip=NULL from %s\n", __func__); + if (unlikely(atomic_read(&retired_max_queue) > 0)) + retiring = 1; + + sqcp->a_cmnd = NULL; + if (unlikely(!test_and_clear_bit(qc_idx, sqp->in_use_bm))) { + pr_err("Unexpected completion sqp %p queue_num=%d qc_idx=%d from %s\n", + sqp, queue_num, qc_idx, __func__); + goto out; + } + + if (unlikely(retiring)) { /* user has reduced max_queue */ + int k, retval; + + retval = atomic_read(&retired_max_queue); + if (qc_idx >= retval) { + pr_err("index %d too large\n", retval); + goto out; + } + k = find_last_bit(sqp->in_use_bm, retval); + if ((k < sdebug_max_queue) || (k == retval)) + atomic_set(&retired_max_queue, 0); + else + atomic_set(&retired_max_queue, k + 1); + } + spin_unlock_irqrestore(&sqp->qc_lock, iflags); + scp->scsi_done(scp); /* callback to mid level */ + num_entries++; + } while (1); + +out: + spin_unlock_irqrestore(&sqp->qc_lock, iflags); + return num_entries; +} + + static int scsi_debug_queuecommand(struct Scsi_Host *shost, struct scsi_cmnd *scp) { @@ -7381,6 +7490,8 @@ static struct scsi_host_template sdebug_driver_template = { .ioctl = scsi_debug_ioctl, .queuecommand = scsi_debug_queuecommand, .change_queue_depth = sdebug_change_qdepth, + .map_queues = sdebug_map_queues, + .mq_poll = sdebug_blk_mq_poll, .eh_abort_handler = scsi_debug_abort, .eh_device_reset_handler = scsi_debug_device_reset, .eh_target_reset_handler = scsi_debug_target_reset, @@ -7428,6 +7539,25 @@ static int sdebug_driver_probe(struct device *dev) if (sdebug_host_max_queue) hpnt->host_tagset = 1; + /* poll queues are possible for nr_hw_queues > 1 */ + if (hpnt->nr_hw_queues == 1 || (poll_queues < 1)) { + pr_warn("%s: trim poll_queues to 0. poll_q/nr_hw = (%d/%d)\n", + my_name, poll_queues, hpnt->nr_hw_queues); + poll_queues = 0; + } + + /* + * Poll queues don't need interrupts, but we need at least one I/O queue + * left over for non-polled I/O. + * If condition not met, trim poll_queues to 1 (just for simplicity). + */ + if (poll_queues >= submit_queues) { + pr_warn("%s: trim poll_queues to 1\n", my_name); + poll_queues = 1; + } + if (poll_queues) + hpnt->nr_maps = 3; + sdbg_host->shost = hpnt; *((struct sdebug_host_info **)hpnt->hostdata) = sdbg_host; if ((hpnt->this_id >= 0) && (sdebug_num_tgts > hpnt->this_id)) From 4a0c6f432d153156f8f73078c4e6fa43bd3a1752 Mon Sep 17 00:00:00 2001 From: Douglas Gilbert Date: Mon, 15 Feb 2021 13:10:47 +0530 Subject: [PATCH 046/412] scsi: scsi_debug: Add new defer type for mq_poll Add a new sdeb_defer_type enumeration: SDEB_DEFER_POLL for requests that have REQ_HIPRI set in cmd_flags field. It is expected that these requests will be polled via the mq_poll entry point which is driven by calls to blk_poll() in the block layer. Therefore timer events are not 'wired up' in the normal fashion. There are still cases with short delays (e.g. < 10 microseconds) where by the time the command response processing occurs, the delay is already exceeded in which case the code calls scsi_done() directly. In such cases there is no window for mq_poll() to be called. Add 'mq_polls' counter that increments on each scsi_done() called via the mq_poll entry point. Can be used to show (with 'cat /proc/scsi/scsi_debug/') that blk_poll() is causing completions rather than some other mechanism. Link: https://lore.kernel.org/r/20210215074048.19424-5-kashyap.desai@broadcom.com Tested-by: Kashyap Desai Signed-off-by: Douglas Gilbert Signed-off-by: Kashyap Desai Signed-off-by: Martin K. Petersen --- drivers/scsi/scsi_debug.c | 148 ++++++++++++++++++++++++-------------- 1 file changed, 94 insertions(+), 54 deletions(-) diff --git a/drivers/scsi/scsi_debug.c b/drivers/scsi/scsi_debug.c index 5ea09fe72544..2ef77b980904 100644 --- a/drivers/scsi/scsi_debug.c +++ b/drivers/scsi/scsi_debug.c @@ -322,17 +322,19 @@ struct sdeb_store_info { container_of(d, struct sdebug_host_info, dev) enum sdeb_defer_type {SDEB_DEFER_NONE = 0, SDEB_DEFER_HRT = 1, - SDEB_DEFER_WQ = 2}; + SDEB_DEFER_WQ = 2, SDEB_DEFER_POLL = 3}; struct sdebug_defer { struct hrtimer hrt; struct execute_work ew; + ktime_t cmpl_ts;/* time since boot to complete this cmd */ int sqa_idx; /* index of sdebug_queue array */ int qc_idx; /* index of sdebug_queued_cmd array within sqa_idx */ int hc_idx; /* hostwide tag index */ int issuing_cpu; bool init_hrt; bool init_wq; + bool init_poll; bool aborted; /* true when blk_abort_request() already called */ enum sdeb_defer_type defer_t; }; @@ -357,6 +359,7 @@ static atomic_t sdebug_completions; /* count of deferred completions */ static atomic_t sdebug_miss_cpus; /* submission + completion cpus differ */ static atomic_t sdebug_a_tsf; /* 'almost task set full' counter */ static atomic_t sdeb_inject_pending; +static atomic_t sdeb_mq_poll_count; /* bumped when mq_poll returns > 0 */ struct opcode_info_t { u8 num_attached; /* 0 if this is it (i.e. a leaf); use 0xff */ @@ -4730,7 +4733,6 @@ static void sdebug_q_cmd_complete(struct sdebug_defer *sd_dp) struct scsi_cmnd *scp; struct sdebug_dev_info *devip; - sd_dp->defer_t = SDEB_DEFER_NONE; if (unlikely(aborted)) sd_dp->aborted = false; qc_idx = sd_dp->qc_idx; @@ -4745,6 +4747,7 @@ static void sdebug_q_cmd_complete(struct sdebug_defer *sd_dp) return; } spin_lock_irqsave(&sqp->qc_lock, iflags); + sd_dp->defer_t = SDEB_DEFER_NONE; sqcp = &sqp->qc_arr[qc_idx]; scp = sqcp->a_cmnd; if (unlikely(scp == NULL)) { @@ -5434,13 +5437,6 @@ static int schedule_resp(struct scsi_cmnd *cmnd, struct sdebug_dev_info *devip, sd_dp = sqcp->sd_dp; spin_unlock_irqrestore(&sqp->qc_lock, iflags); - /* Do not complete IO from default completion path. - * Let it to be on queue. - * Completion should happen from mq_poll interface. - */ - if ((sqp - sdebug_q_arr) >= (submit_queues - poll_queues)) - return 0; - if (!sd_dp) { sd_dp = kzalloc(sizeof(*sd_dp), GFP_ATOMIC); if (!sd_dp) { @@ -5517,40 +5513,66 @@ static int schedule_resp(struct scsi_cmnd *cmnd, struct sdebug_dev_info *devip, kt -= d; } } - if (!sd_dp->init_hrt) { - sd_dp->init_hrt = true; - sqcp->sd_dp = sd_dp; - hrtimer_init(&sd_dp->hrt, CLOCK_MONOTONIC, - HRTIMER_MODE_REL_PINNED); - sd_dp->hrt.function = sdebug_q_cmd_hrt_complete; - sd_dp->sqa_idx = sqp - sdebug_q_arr; - sd_dp->qc_idx = k; + sd_dp->cmpl_ts = ktime_add(ns_to_ktime(ns_from_boot), kt); + if (cmnd->request->cmd_flags & REQ_HIPRI) { + spin_lock_irqsave(&sqp->qc_lock, iflags); + if (!sd_dp->init_poll) { + sd_dp->init_poll = true; + sqcp->sd_dp = sd_dp; + sd_dp->sqa_idx = sqp - sdebug_q_arr; + sd_dp->qc_idx = k; + } + sd_dp->defer_t = SDEB_DEFER_POLL; + spin_unlock_irqrestore(&sqp->qc_lock, iflags); + } else { + if (!sd_dp->init_hrt) { + sd_dp->init_hrt = true; + sqcp->sd_dp = sd_dp; + hrtimer_init(&sd_dp->hrt, CLOCK_MONOTONIC, + HRTIMER_MODE_REL_PINNED); + sd_dp->hrt.function = sdebug_q_cmd_hrt_complete; + sd_dp->sqa_idx = sqp - sdebug_q_arr; + sd_dp->qc_idx = k; + } + sd_dp->defer_t = SDEB_DEFER_HRT; + /* schedule the invocation of scsi_done() for a later time */ + hrtimer_start(&sd_dp->hrt, kt, HRTIMER_MODE_REL_PINNED); } if (sdebug_statistics) sd_dp->issuing_cpu = raw_smp_processor_id(); - sd_dp->defer_t = SDEB_DEFER_HRT; - /* schedule the invocation of scsi_done() for a later time */ - hrtimer_start(&sd_dp->hrt, kt, HRTIMER_MODE_REL_PINNED); } else { /* jdelay < 0, use work queue */ - if (!sd_dp->init_wq) { - sd_dp->init_wq = true; - sqcp->sd_dp = sd_dp; - sd_dp->sqa_idx = sqp - sdebug_q_arr; - sd_dp->qc_idx = k; - INIT_WORK(&sd_dp->ew.work, sdebug_q_cmd_wq_complete); - } - if (sdebug_statistics) - sd_dp->issuing_cpu = raw_smp_processor_id(); - sd_dp->defer_t = SDEB_DEFER_WQ; if (unlikely((sdebug_opts & SDEBUG_OPT_CMD_ABORT) && atomic_read(&sdeb_inject_pending))) sd_dp->aborted = true; - schedule_work(&sd_dp->ew.work); - if (unlikely((sdebug_opts & SDEBUG_OPT_CMD_ABORT) && - atomic_read(&sdeb_inject_pending))) { + sd_dp->cmpl_ts = ns_to_ktime(ns_from_boot); + if (cmnd->request->cmd_flags & REQ_HIPRI) { + spin_lock_irqsave(&sqp->qc_lock, iflags); + if (!sd_dp->init_poll) { + sd_dp->init_poll = true; + sqcp->sd_dp = sd_dp; + sd_dp->sqa_idx = sqp - sdebug_q_arr; + sd_dp->qc_idx = k; + } + sd_dp->defer_t = SDEB_DEFER_POLL; + spin_unlock_irqrestore(&sqp->qc_lock, iflags); + } else { + if (!sd_dp->init_wq) { + sd_dp->init_wq = true; + sqcp->sd_dp = sd_dp; + sd_dp->sqa_idx = sqp - sdebug_q_arr; + sd_dp->qc_idx = k; + INIT_WORK(&sd_dp->ew.work, sdebug_q_cmd_wq_complete); + } + sd_dp->defer_t = SDEB_DEFER_WQ; + schedule_work(&sd_dp->ew.work); + } + if (sdebug_statistics) + sd_dp->issuing_cpu = raw_smp_processor_id(); + if (unlikely(sd_dp->aborted)) { sdev_printk(KERN_INFO, sdp, "abort request tag %d\n", cmnd->request->tag); blk_abort_request(cmnd->request); atomic_set(&sdeb_inject_pending, 0); + sd_dp->aborted = false; } } if (unlikely((SDEBUG_OPT_Q_NOISE & sdebug_opts) && scsi_result == device_qfull_result)) @@ -5779,11 +5801,12 @@ static int scsi_debug_show_info(struct seq_file *m, struct Scsi_Host *host) dix_reads, dix_writes, dif_errors); seq_printf(m, "usec_in_jiffy=%lu, statistics=%d\n", TICK_NSEC / 1000, sdebug_statistics); - seq_printf(m, "cmnd_count=%d, completions=%d, %s=%d, a_tsf=%d\n", + seq_printf(m, "cmnd_count=%d, completions=%d, %s=%d, a_tsf=%d, mq_polls=%d\n", atomic_read(&sdebug_cmnd_count), atomic_read(&sdebug_completions), "miss_cpus", atomic_read(&sdebug_miss_cpus), - atomic_read(&sdebug_a_tsf)); + atomic_read(&sdebug_a_tsf), + atomic_read(&sdeb_mq_poll_count)); seq_printf(m, "submit_queues=%d\n", submit_queues); for (j = 0, sqp = sdebug_q_arr; j < submit_queues; ++j, ++sqp) { @@ -7247,52 +7270,68 @@ static int sdebug_map_queues(struct Scsi_Host *shost) static int sdebug_blk_mq_poll(struct Scsi_Host *shost, unsigned int queue_num) { - int qc_idx; - int retiring = 0; + bool first; + bool retiring = false; + int num_entries = 0; + unsigned int qc_idx = 0; unsigned long iflags; + ktime_t kt_from_boot = ktime_get_boottime(); struct sdebug_queue *sqp; struct sdebug_queued_cmd *sqcp; struct scsi_cmnd *scp; struct sdebug_dev_info *devip; - int num_entries = 0; + struct sdebug_defer *sd_dp; sqp = sdebug_q_arr + queue_num; + spin_lock_irqsave(&sqp->qc_lock, iflags); - do { - spin_lock_irqsave(&sqp->qc_lock, iflags); - qc_idx = find_first_bit(sqp->in_use_bm, sdebug_max_queue); - if (unlikely((qc_idx < 0) || (qc_idx >= sdebug_max_queue))) - goto out; + for (first = true; first || qc_idx + 1 < sdebug_max_queue; ) { + if (first) { + qc_idx = find_first_bit(sqp->in_use_bm, sdebug_max_queue); + first = false; + } else { + qc_idx = find_next_bit(sqp->in_use_bm, sdebug_max_queue, qc_idx + 1); + } + if (unlikely(qc_idx >= sdebug_max_queue)) + break; sqcp = &sqp->qc_arr[qc_idx]; + sd_dp = sqcp->sd_dp; + if (unlikely(!sd_dp)) + continue; scp = sqcp->a_cmnd; if (unlikely(scp == NULL)) { - pr_err("scp is NULL, queue_num=%d, qc_idx=%d from %s\n", + pr_err("scp is NULL, queue_num=%d, qc_idx=%u from %s\n", queue_num, qc_idx, __func__); - goto out; + break; } + if (sd_dp->defer_t == SDEB_DEFER_POLL) { + if (kt_from_boot < sd_dp->cmpl_ts) + continue; + + } else /* ignoring non REQ_HIPRI requests */ + continue; devip = (struct sdebug_dev_info *)scp->device->hostdata; if (likely(devip)) atomic_dec(&devip->num_in_q); else pr_err("devip=NULL from %s\n", __func__); if (unlikely(atomic_read(&retired_max_queue) > 0)) - retiring = 1; + retiring = true; sqcp->a_cmnd = NULL; if (unlikely(!test_and_clear_bit(qc_idx, sqp->in_use_bm))) { - pr_err("Unexpected completion sqp %p queue_num=%d qc_idx=%d from %s\n", + pr_err("Unexpected completion sqp %p queue_num=%d qc_idx=%u from %s\n", sqp, queue_num, qc_idx, __func__); - goto out; + break; } - if (unlikely(retiring)) { /* user has reduced max_queue */ int k, retval; retval = atomic_read(&retired_max_queue); if (qc_idx >= retval) { pr_err("index %d too large\n", retval); - goto out; + break; } k = find_last_bit(sqp->in_use_bm, retval); if ((k < sdebug_max_queue) || (k == retval)) @@ -7300,17 +7339,18 @@ static int sdebug_blk_mq_poll(struct Scsi_Host *shost, unsigned int queue_num) else atomic_set(&retired_max_queue, k + 1); } + sd_dp->defer_t = SDEB_DEFER_NONE; spin_unlock_irqrestore(&sqp->qc_lock, iflags); scp->scsi_done(scp); /* callback to mid level */ + spin_lock_irqsave(&sqp->qc_lock, iflags); num_entries++; - } while (1); - -out: + } spin_unlock_irqrestore(&sqp->qc_lock, iflags); + if (num_entries > 0) + atomic_add(num_entries, &sdeb_mq_poll_count); return num_entries; } - static int scsi_debug_queuecommand(struct Scsi_Host *shost, struct scsi_cmnd *scp) { From 4309ea74b0c30f00c6a93b94db018ebb416dc14c Mon Sep 17 00:00:00 2001 From: Kashyap Desai Date: Mon, 15 Feb 2021 13:10:48 +0530 Subject: [PATCH 047/412] scsi: core: Set shost as hctx driver_data hctx->driver_data is not set for SCSI currently. Set hctx->driver_data = shost. Link: https://lore.kernel.org/r/20210215074048.19424-6-kashyap.desai@broadcom.com Suggested-by: John Garry Reviewed-by: John Garry Reviewed-by: Hannes Reinecke Signed-off-by: Kashyap Desai Signed-off-by: Martin K. Petersen --- drivers/scsi/scsi_lib.c | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c index 09d09ef9d193..4bcd744a5c85 100644 --- a/drivers/scsi/scsi_lib.c +++ b/drivers/scsi/scsi_lib.c @@ -1813,9 +1813,7 @@ static void scsi_mq_exit_request(struct blk_mq_tag_set *set, struct request *rq, static int scsi_mq_poll(struct blk_mq_hw_ctx *hctx) { - struct request_queue *q = hctx->queue; - struct scsi_device *sdev = q->queuedata; - struct Scsi_Host *shost = sdev->host; + struct Scsi_Host *shost = hctx->driver_data; if (shost->hostt->mq_poll) return shost->hostt->mq_poll(shost, hctx->queue_num); @@ -1823,6 +1821,15 @@ static int scsi_mq_poll(struct blk_mq_hw_ctx *hctx) return 0; } +static int scsi_init_hctx(struct blk_mq_hw_ctx *hctx, void *data, + unsigned int hctx_idx) +{ + struct Scsi_Host *shost = data; + + hctx->driver_data = shost; + return 0; +} + static int scsi_map_queues(struct blk_mq_tag_set *set) { struct Scsi_Host *shost = container_of(set, struct Scsi_Host, tag_set); @@ -1890,6 +1897,7 @@ static const struct blk_mq_ops scsi_mq_ops_no_commit = { .cleanup_rq = scsi_cleanup_rq, .busy = scsi_mq_lld_busy, .map_queues = scsi_map_queues, + .init_hctx = scsi_init_hctx, .poll = scsi_mq_poll, .set_rq_budget_token = scsi_mq_set_rq_budget_token, .get_rq_budget_token = scsi_mq_get_rq_budget_token, @@ -1898,9 +1906,7 @@ static const struct blk_mq_ops scsi_mq_ops_no_commit = { static void scsi_commit_rqs(struct blk_mq_hw_ctx *hctx) { - struct request_queue *q = hctx->queue; - struct scsi_device *sdev = q->queuedata; - struct Scsi_Host *shost = sdev->host; + struct Scsi_Host *shost = hctx->driver_data; shost->hostt->commit_rqs(shost, hctx->queue_num); } @@ -1921,6 +1927,7 @@ static const struct blk_mq_ops scsi_mq_ops = { .cleanup_rq = scsi_cleanup_rq, .busy = scsi_mq_lld_busy, .map_queues = scsi_map_queues, + .init_hctx = scsi_init_hctx, .poll = scsi_mq_poll, .set_rq_budget_token = scsi_mq_set_rq_budget_token, .get_rq_budget_token = scsi_mq_get_rq_budget_token, From 771f712ba5b0c6a54534421db98f560526a238a4 Mon Sep 17 00:00:00 2001 From: Douglas Gilbert Date: Wed, 3 Mar 2021 20:41:07 -0500 Subject: [PATCH 048/412] scsi: scsi_debug: Fix cmd duration calculation In some cases, sdebug_defer::cmpl_ts (completion timestamp) wasn't being properly set when REQ_HIPRI was given. Fix that and improve code to only call ktime_get_boottime_ns() for commands with REQ_HIPRI set as cmpl_ts is only used in that case. Link: https://lore.kernel.org/r/20210304014107.307625-1-dgilbert@interlog.com Signed-off-by: Douglas Gilbert Signed-off-by: Martin K. Petersen --- drivers/scsi/scsi_debug.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/drivers/scsi/scsi_debug.c b/drivers/scsi/scsi_debug.c index 2ef77b980904..70165be10f00 100644 --- a/drivers/scsi/scsi_debug.c +++ b/drivers/scsi/scsi_debug.c @@ -5367,6 +5367,7 @@ static int schedule_resp(struct scsi_cmnd *cmnd, struct sdebug_dev_info *devip, { bool new_sd_dp; bool inject = false; + bool hipri = (cmnd->request->cmd_flags & REQ_HIPRI); int k, num_in_q, qdepth; unsigned long iflags; u64 ns_from_boot = 0; @@ -5453,7 +5454,7 @@ static int schedule_resp(struct scsi_cmnd *cmnd, struct sdebug_dev_info *devip, if (sdebug_host_max_queue) sd_dp->hc_idx = get_tag(cmnd); - if (ndelay > 0 && ndelay < INCLUSIVE_TIMING_MAX_NS) + if (hipri) ns_from_boot = ktime_get_boottime_ns(); /* one of the resp_*() response functions is called here */ @@ -5513,8 +5514,8 @@ static int schedule_resp(struct scsi_cmnd *cmnd, struct sdebug_dev_info *devip, kt -= d; } } - sd_dp->cmpl_ts = ktime_add(ns_to_ktime(ns_from_boot), kt); - if (cmnd->request->cmd_flags & REQ_HIPRI) { + if (hipri) { + sd_dp->cmpl_ts = ktime_add(ns_to_ktime(ns_from_boot), kt); spin_lock_irqsave(&sqp->qc_lock, iflags); if (!sd_dp->init_poll) { sd_dp->init_poll = true; @@ -5544,8 +5545,8 @@ static int schedule_resp(struct scsi_cmnd *cmnd, struct sdebug_dev_info *devip, if (unlikely((sdebug_opts & SDEBUG_OPT_CMD_ABORT) && atomic_read(&sdeb_inject_pending))) sd_dp->aborted = true; - sd_dp->cmpl_ts = ns_to_ktime(ns_from_boot); - if (cmnd->request->cmd_flags & REQ_HIPRI) { + if (hipri) { + sd_dp->cmpl_ts = ns_to_ktime(ns_from_boot); spin_lock_irqsave(&sqp->qc_lock, iflags); if (!sd_dp->init_poll) { sd_dp->init_poll = true; From 9302154c07bff4e7f7f43c506a1ac84540303d06 Mon Sep 17 00:00:00 2001 From: James Smart Date: Mon, 1 Mar 2021 09:18:00 -0800 Subject: [PATCH 049/412] scsi: lpfc: Fix incorrect dbde assignment when building target abts wqe The wqe_dbde field indicates whether a Data BDE is present in Words 0:2 and should therefore should be clear in the abts request wqe. By setting the bit we can be misleading fw into error cases. Clear the wqe_dbde field. Link: https://lore.kernel.org/r/20210301171821.3427-2-jsmart2021@gmail.com Co-developed-by: Dick Kennedy Signed-off-by: Dick Kennedy Signed-off-by: James Smart Signed-off-by: Martin K. Petersen --- drivers/scsi/lpfc/lpfc_nvmet.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/scsi/lpfc/lpfc_nvmet.c b/drivers/scsi/lpfc/lpfc_nvmet.c index bb2a4a0d1295..a3fd959f7431 100644 --- a/drivers/scsi/lpfc/lpfc_nvmet.c +++ b/drivers/scsi/lpfc/lpfc_nvmet.c @@ -3304,7 +3304,6 @@ lpfc_nvmet_unsol_issue_abort(struct lpfc_hba *phba, bf_set(wqe_rcvoxid, &wqe_abts->xmit_sequence.wqe_com, xri); /* Word 10 */ - bf_set(wqe_dbde, &wqe_abts->xmit_sequence.wqe_com, 1); bf_set(wqe_iod, &wqe_abts->xmit_sequence.wqe_com, LPFC_WQE_IOD_WRITE); bf_set(wqe_lenloc, &wqe_abts->xmit_sequence.wqe_com, LPFC_WQE_LENLOC_WORD12); From 58c36e80ee2d3836080b22ba965aa09454c070d6 Mon Sep 17 00:00:00 2001 From: James Smart Date: Mon, 1 Mar 2021 09:18:01 -0800 Subject: [PATCH 050/412] scsi: lpfc: Fix vport indices in lpfc_find_vport_by_vpid() Calls to lpfc_find_vport_by_vpid() for the highest indexed vport fails with error, "2936 Could not find Vport mapped to vpi XXX". Our vport indices in the loop and if-clauses were off by one. Correct the vpid range used for vpi lookup to include the highest possible vpid. Link: https://lore.kernel.org/r/20210301171821.3427-3-jsmart2021@gmail.com Co-developed-by: Dick Kennedy Signed-off-by: Dick Kennedy Signed-off-by: James Smart Signed-off-by: Martin K. Petersen --- drivers/scsi/lpfc/lpfc_hbadisc.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/scsi/lpfc/lpfc_hbadisc.c b/drivers/scsi/lpfc/lpfc_hbadisc.c index 48ca4a612f80..a60fa3f67076 100644 --- a/drivers/scsi/lpfc/lpfc_hbadisc.c +++ b/drivers/scsi/lpfc/lpfc_hbadisc.c @@ -6081,12 +6081,12 @@ lpfc_find_vport_by_vpid(struct lpfc_hba *phba, uint16_t vpi) * Translate the physical vpi to the logical vpi. The * vport stores the logical vpi. */ - for (i = 0; i < phba->max_vpi; i++) { + for (i = 0; i <= phba->max_vpi; i++) { if (vpi == phba->vpi_ids[i]) break; } - if (i >= phba->max_vpi) { + if (i > phba->max_vpi) { lpfc_printf_log(phba, KERN_ERR, LOG_TRACE_EVENT, "2936 Could not find Vport mapped " "to vpi %d\n", vpi); From 68a6a66c5168f3995baed3fc5bee2d4515eb16d0 Mon Sep 17 00:00:00 2001 From: James Smart Date: Mon, 1 Mar 2021 09:18:02 -0800 Subject: [PATCH 051/412] scsi: lpfc: Fix reftag generation sizing errors An LBA is 8 bytes. The driver generates a reftag from the LBA but the reftag is 4 bytes. Thus scsi_get_lba() could return a value that exceeds our reftag size. Fix by converting all the code to calling the common routine t10_pi_ref_tag() which returns a u32, thus ensuring a consistent 4byte value. Also correct a few code lines that access LBA directly and ensure 64-bit data types are used. Link: https://lore.kernel.org/r/20210301171821.3427-4-jsmart2021@gmail.com Co-developed-by: Dick Kennedy Signed-off-by: Dick Kennedy Signed-off-by: James Smart Signed-off-by: Martin K. Petersen --- drivers/scsi/lpfc/lpfc_scsi.c | 90 ++++++++++++++++++++--------------- 1 file changed, 52 insertions(+), 38 deletions(-) diff --git a/drivers/scsi/lpfc/lpfc_scsi.c b/drivers/scsi/lpfc/lpfc_scsi.c index a4d697373c71..3e1bc55993fd 100644 --- a/drivers/scsi/lpfc/lpfc_scsi.c +++ b/drivers/scsi/lpfc/lpfc_scsi.c @@ -132,6 +132,8 @@ lpfc_sli4_set_rsp_sgl_last(struct lpfc_hba *phba, } } +#define LPFC_INVALID_REFTAG ((u32)-1) + /** * lpfc_update_stats - Update statistical data for the command completion * @vport: The virtual port on which this call is executing. @@ -1000,7 +1002,7 @@ lpfc_bg_err_inject(struct lpfc_hba *phba, struct scsi_cmnd *sc, uint32_t op = scsi_get_prot_op(sc); uint32_t blksize; uint32_t numblks; - sector_t lba; + u32 lba; int rc = 0; int blockoff = 0; @@ -1008,7 +1010,9 @@ lpfc_bg_err_inject(struct lpfc_hba *phba, struct scsi_cmnd *sc, return 0; sgpe = scsi_prot_sglist(sc); - lba = scsi_get_lba(sc); + lba = t10_pi_ref_tag(sc->request); + if (lba == LPFC_INVALID_REFTAG) + return 0; /* First check if we need to match the LBA */ if (phba->lpfc_injerr_lba != LPFC_INJERR_LBA_OFF) { @@ -1016,11 +1020,11 @@ lpfc_bg_err_inject(struct lpfc_hba *phba, struct scsi_cmnd *sc, numblks = (scsi_bufflen(sc) + blksize - 1) / blksize; /* Make sure we have the right LBA if one is specified */ - if ((phba->lpfc_injerr_lba < lba) || - (phba->lpfc_injerr_lba >= (lba + numblks))) + if (phba->lpfc_injerr_lba < (u64)lba || + (phba->lpfc_injerr_lba >= (u64)(lba + numblks))) return 0; if (sgpe) { - blockoff = phba->lpfc_injerr_lba - lba; + blockoff = phba->lpfc_injerr_lba - (u64)lba; numblks = sg_dma_len(sgpe) / sizeof(struct scsi_dif_tuple); if (numblks < blockoff) @@ -1589,7 +1593,9 @@ lpfc_bg_setup_bpl(struct lpfc_hba *phba, struct scsi_cmnd *sc, goto out; /* extract some info from the scsi command for pde*/ - reftag = (uint32_t)scsi_get_lba(sc); /* Truncate LBA */ + reftag = t10_pi_ref_tag(sc->request); + if (reftag == LPFC_INVALID_REFTAG) + goto out; #ifdef CONFIG_SCSI_LPFC_DEBUG_FS rc = lpfc_bg_err_inject(phba, sc, &reftag, NULL, 1); @@ -1750,7 +1756,9 @@ lpfc_bg_setup_bpl_prot(struct lpfc_hba *phba, struct scsi_cmnd *sc, /* extract some info from the scsi command */ blksize = lpfc_cmd_blksize(sc); - reftag = (uint32_t)scsi_get_lba(sc); /* Truncate LBA */ + reftag = t10_pi_ref_tag(sc->request); + if (reftag == LPFC_INVALID_REFTAG) + goto out; #ifdef CONFIG_SCSI_LPFC_DEBUG_FS rc = lpfc_bg_err_inject(phba, sc, &reftag, NULL, 1); @@ -1979,7 +1987,9 @@ lpfc_bg_setup_sgl(struct lpfc_hba *phba, struct scsi_cmnd *sc, goto out; /* extract some info from the scsi command for pde*/ - reftag = (uint32_t)scsi_get_lba(sc); /* Truncate LBA */ + reftag = t10_pi_ref_tag(sc->request); + if (reftag == LPFC_INVALID_REFTAG) + goto out; #ifdef CONFIG_SCSI_LPFC_DEBUG_FS rc = lpfc_bg_err_inject(phba, sc, &reftag, NULL, 1); @@ -2178,7 +2188,9 @@ lpfc_bg_setup_sgl_prot(struct lpfc_hba *phba, struct scsi_cmnd *sc, /* extract some info from the scsi command */ blksize = lpfc_cmd_blksize(sc); - reftag = (uint32_t)scsi_get_lba(sc); /* Truncate LBA */ + reftag = t10_pi_ref_tag(sc->request); + if (reftag == LPFC_INVALID_REFTAG) + goto out; #ifdef CONFIG_SCSI_LPFC_DEBUG_FS rc = lpfc_bg_err_inject(phba, sc, &reftag, NULL, 1); @@ -2770,7 +2782,9 @@ lpfc_calc_bg_err(struct lpfc_hba *phba, struct lpfc_io_buf *lpfc_cmd) chk_guard = 1; src = (struct scsi_dif_tuple *)sg_virt(sgpe); - start_ref_tag = (uint32_t)scsi_get_lba(cmd); /* Truncate LBA */ + start_ref_tag = t10_pi_ref_tag(cmd->request); + if (start_ref_tag == LPFC_INVALID_REFTAG) + goto out; start_app_tag = src->app_tag; len = sgpe->length; while (src && protsegcnt) { @@ -2861,8 +2875,8 @@ out: SAM_STAT_CHECK_CONDITION; phba->bg_guard_err_cnt++; lpfc_printf_log(phba, KERN_WARNING, LOG_FCP | LOG_BG, - "9069 BLKGRD: LBA %lx grd_tag error %x != %x\n", - (unsigned long)scsi_get_lba(cmd), + "9069 BLKGRD: reftag %x grd_tag err %x != %x\n", + t10_pi_ref_tag(cmd->request), sum, guard_tag); } else if (err_type == BGS_REFTAG_ERR_MASK) { @@ -2873,8 +2887,8 @@ out: phba->bg_reftag_err_cnt++; lpfc_printf_log(phba, KERN_WARNING, LOG_FCP | LOG_BG, - "9066 BLKGRD: LBA %lx ref_tag error %x != %x\n", - (unsigned long)scsi_get_lba(cmd), + "9066 BLKGRD: reftag %x ref_tag err %x != %x\n", + t10_pi_ref_tag(cmd->request), ref_tag, start_ref_tag); } else if (err_type == BGS_APPTAG_ERR_MASK) { @@ -2885,8 +2899,8 @@ out: phba->bg_apptag_err_cnt++; lpfc_printf_log(phba, KERN_WARNING, LOG_FCP | LOG_BG, - "9041 BLKGRD: LBA %lx app_tag error %x != %x\n", - (unsigned long)scsi_get_lba(cmd), + "9041 BLKGRD: reftag %x app_tag err %x != %x\n", + t10_pi_ref_tag(cmd->request), app_tag, start_app_tag); } } @@ -3062,10 +3076,10 @@ lpfc_parse_bg_err(struct lpfc_hba *phba, struct lpfc_io_buf *lpfc_cmd, if (lpfc_bgs_get_invalid_prof(bgstat)) { cmd->result = DID_ERROR << 16; lpfc_printf_log(phba, KERN_WARNING, LOG_FCP | LOG_BG, - "9072 BLKGRD: Invalid BG Profile in cmd" - " 0x%x lba 0x%llx blk cnt 0x%x " + "9072 BLKGRD: Invalid BG Profile in cmd " + "0x%x reftag 0x%x blk cnt 0x%x " "bgstat=x%x bghm=x%x\n", cmd->cmnd[0], - (unsigned long long)scsi_get_lba(cmd), + t10_pi_ref_tag(cmd->request), blk_rq_sectors(cmd->request), bgstat, bghm); ret = (-1); goto out; @@ -3074,10 +3088,10 @@ lpfc_parse_bg_err(struct lpfc_hba *phba, struct lpfc_io_buf *lpfc_cmd, if (lpfc_bgs_get_uninit_dif_block(bgstat)) { cmd->result = DID_ERROR << 16; lpfc_printf_log(phba, KERN_WARNING, LOG_FCP | LOG_BG, - "9073 BLKGRD: Invalid BG PDIF Block in cmd" - " 0x%x lba 0x%llx blk cnt 0x%x " + "9073 BLKGRD: Invalid BG PDIF Block in cmd " + "0x%x reftag 0x%x blk cnt 0x%x " "bgstat=x%x bghm=x%x\n", cmd->cmnd[0], - (unsigned long long)scsi_get_lba(cmd), + t10_pi_ref_tag(cmd->request), blk_rq_sectors(cmd->request), bgstat, bghm); ret = (-1); goto out; @@ -3092,10 +3106,10 @@ lpfc_parse_bg_err(struct lpfc_hba *phba, struct lpfc_io_buf *lpfc_cmd, SAM_STAT_CHECK_CONDITION; phba->bg_guard_err_cnt++; lpfc_printf_log(phba, KERN_WARNING, LOG_FCP | LOG_BG, - "9055 BLKGRD: Guard Tag error in cmd" - " 0x%x lba 0x%llx blk cnt 0x%x " + "9055 BLKGRD: Guard Tag error in cmd " + "0x%x reftag 0x%x blk cnt 0x%x " "bgstat=x%x bghm=x%x\n", cmd->cmnd[0], - (unsigned long long)scsi_get_lba(cmd), + t10_pi_ref_tag(cmd->request), blk_rq_sectors(cmd->request), bgstat, bghm); } @@ -3109,10 +3123,10 @@ lpfc_parse_bg_err(struct lpfc_hba *phba, struct lpfc_io_buf *lpfc_cmd, phba->bg_reftag_err_cnt++; lpfc_printf_log(phba, KERN_WARNING, LOG_FCP | LOG_BG, - "9056 BLKGRD: Ref Tag error in cmd" - " 0x%x lba 0x%llx blk cnt 0x%x " + "9056 BLKGRD: Ref Tag error in cmd " + "0x%x reftag 0x%x blk cnt 0x%x " "bgstat=x%x bghm=x%x\n", cmd->cmnd[0], - (unsigned long long)scsi_get_lba(cmd), + t10_pi_ref_tag(cmd->request), blk_rq_sectors(cmd->request), bgstat, bghm); } @@ -3126,10 +3140,10 @@ lpfc_parse_bg_err(struct lpfc_hba *phba, struct lpfc_io_buf *lpfc_cmd, phba->bg_apptag_err_cnt++; lpfc_printf_log(phba, KERN_WARNING, LOG_FCP | LOG_BG, - "9061 BLKGRD: App Tag error in cmd" - " 0x%x lba 0x%llx blk cnt 0x%x " + "9061 BLKGRD: App Tag error in cmd " + "0x%x reftag 0x%x blk cnt 0x%x " "bgstat=x%x bghm=x%x\n", cmd->cmnd[0], - (unsigned long long)scsi_get_lba(cmd), + t10_pi_ref_tag(cmd->request), blk_rq_sectors(cmd->request), bgstat, bghm); } @@ -3170,10 +3184,10 @@ lpfc_parse_bg_err(struct lpfc_hba *phba, struct lpfc_io_buf *lpfc_cmd, if (!ret) { /* No error was reported - problem in FW? */ lpfc_printf_log(phba, KERN_WARNING, LOG_FCP | LOG_BG, - "9057 BLKGRD: Unknown error in cmd" - " 0x%x lba 0x%llx blk cnt 0x%x " + "9057 BLKGRD: Unknown error in cmd " + "0x%x reftag 0x%x blk cnt 0x%x " "bgstat=x%x bghm=x%x\n", cmd->cmnd[0], - (unsigned long long)scsi_get_lba(cmd), + t10_pi_ref_tag(cmd->request), blk_rq_sectors(cmd->request), bgstat, bghm); /* Calcuate what type of error it was */ @@ -5252,10 +5266,10 @@ lpfc_queuecommand(struct Scsi_Host *shost, struct scsi_cmnd *cmnd) lpfc_printf_vlog(vport, KERN_INFO, LOG_SCSI_CMD, "9033 BLKGRD: rcvd %s cmd:x%x " - "sector x%llx cnt %u pt %x\n", + "reftag x%x cnt %u pt %x\n", dif_op_str[scsi_get_prot_op(cmnd)], cmnd->cmnd[0], - (unsigned long long)scsi_get_lba(cmnd), + t10_pi_ref_tag(cmnd->request), blk_rq_sectors(cmnd->request), (cmnd->cmnd[1]>>5)); } @@ -5265,9 +5279,9 @@ lpfc_queuecommand(struct Scsi_Host *shost, struct scsi_cmnd *cmnd) lpfc_printf_vlog(vport, KERN_INFO, LOG_SCSI_CMD, "9038 BLKGRD: rcvd PROT_NORMAL cmd: " - "x%x sector x%llx cnt %u pt %x\n", + "x%x reftag x%x cnt %u pt %x\n", cmnd->cmnd[0], - (unsigned long long)scsi_get_lba(cmnd), + t10_pi_ref_tag(cmnd->request), blk_rq_sectors(cmnd->request), (cmnd->cmnd[1]>>5)); } From 2693f5deed16e302297fa591862dd9cc560ec3b5 Mon Sep 17 00:00:00 2001 From: James Smart Date: Mon, 1 Mar 2021 09:18:03 -0800 Subject: [PATCH 052/412] scsi: lpfc: Fix stale node accesses on stale RRQ request Whenever an RRQ needs to be triggered, the DID from the node structure and node pointer are stored in the RRQ data structure and the RRQ is scheduled for later transmission. However, at the point in time that the timer triggers, there's no validation on the node pointer. Reference counters may have freed the structure. Additionally the DID in the node may no longer be valid. Fix by not tracking the node pointer in the RRQ, only the DID. At the time of the timer expiration, look up the node with the did and if present, send the RRQ. If no node exists, no need to send the RRQ. Link: https://lore.kernel.org/r/20210301171821.3427-5-jsmart2021@gmail.com Co-developed-by: Dick Kennedy Signed-off-by: Dick Kennedy Signed-off-by: James Smart Signed-off-by: Martin K. Petersen --- drivers/scsi/lpfc/lpfc_disc.h | 1 - drivers/scsi/lpfc/lpfc_els.c | 32 ++++++++------------------------ drivers/scsi/lpfc/lpfc_sli.c | 18 ++++++++---------- 3 files changed, 16 insertions(+), 35 deletions(-) diff --git a/drivers/scsi/lpfc/lpfc_disc.h b/drivers/scsi/lpfc/lpfc_disc.h index 8ce13ef3cac3..3bd5bb17035a 100644 --- a/drivers/scsi/lpfc/lpfc_disc.h +++ b/drivers/scsi/lpfc/lpfc_disc.h @@ -159,7 +159,6 @@ struct lpfc_node_rrq { uint16_t rxid; uint32_t nlp_DID; /* FC D_ID of entry */ struct lpfc_vport *vport; - struct lpfc_nodelist *ndlp; unsigned long rrq_stop_time; }; diff --git a/drivers/scsi/lpfc/lpfc_els.c b/drivers/scsi/lpfc/lpfc_els.c index f0a758138ae8..cc0b4f2661ab 100644 --- a/drivers/scsi/lpfc/lpfc_els.c +++ b/drivers/scsi/lpfc/lpfc_els.c @@ -1849,7 +1849,7 @@ lpfc_cmpl_els_rrq(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, { struct lpfc_vport *vport = cmdiocb->vport; IOCB_t *irsp; - struct lpfc_nodelist *ndlp; + struct lpfc_nodelist *ndlp = cmdiocb->context1; struct lpfc_node_rrq *rrq; /* we pass cmdiocb to state machine which needs rspiocb as well */ @@ -1862,22 +1862,12 @@ lpfc_cmpl_els_rrq(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, irsp->ulpStatus, irsp->un.ulpWord[4], irsp->un.elsreq64.remoteID); - ndlp = lpfc_findnode_did(vport, irsp->un.elsreq64.remoteID); - if (!ndlp || ndlp != rrq->ndlp) { - lpfc_printf_vlog(vport, KERN_ERR, LOG_TRACE_EVENT, - "2882 RRQ completes to NPort x%x " - "with no ndlp. Data: x%x x%x x%x\n", - irsp->un.elsreq64.remoteID, - irsp->ulpStatus, irsp->un.ulpWord[4], - irsp->ulpIoTag); - goto out; - } - /* rrq completes to NPort */ lpfc_printf_vlog(vport, KERN_INFO, LOG_ELS, - "2880 RRQ completes to NPort x%x " + "2880 RRQ completes to DID x%x " "Data: x%x x%x x%x x%x x%x\n", - ndlp->nlp_DID, irsp->ulpStatus, irsp->un.ulpWord[4], + irsp->un.elsreq64.remoteID, + irsp->ulpStatus, irsp->un.ulpWord[4], irsp->ulpTimeout, rrq->xritag, rrq->rxid); if (irsp->ulpStatus) { @@ -1893,10 +1883,8 @@ lpfc_cmpl_els_rrq(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, ndlp->nlp_DID, irsp->ulpStatus, irsp->un.ulpWord[4]); } -out: - if (rrq) - lpfc_clr_rrq_active(phba, rrq->xritag, rrq); + lpfc_clr_rrq_active(phba, rrq->xritag, rrq); lpfc_els_free_iocb(phba, cmdiocb); lpfc_nlp_put(ndlp); return; @@ -7619,9 +7607,6 @@ lpfc_issue_els_rrq(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp, uint16_t cmdsize; int ret; - - if (ndlp != rrq->ndlp) - ndlp = rrq->ndlp; if (!ndlp) return 1; @@ -7651,9 +7636,9 @@ lpfc_issue_els_rrq(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp, did, rrq->xritag, rrq->rxid); elsiocb->context_un.rrq = rrq; elsiocb->iocb_cmpl = lpfc_cmpl_els_rrq; - elsiocb->context1 = lpfc_nlp_get(ndlp); - if (!elsiocb->context1) - goto node_err; + + lpfc_nlp_get(ndlp); + elsiocb->context1 = ndlp; ret = lpfc_sli_issue_iocb(phba, LPFC_ELS_RING, elsiocb, 0); if (ret == IOCB_ERROR) @@ -7662,7 +7647,6 @@ lpfc_issue_els_rrq(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp, io_err: lpfc_nlp_put(ndlp); - node_err: lpfc_els_free_iocb(phba, elsiocb); return 1; } diff --git a/drivers/scsi/lpfc/lpfc_sli.c b/drivers/scsi/lpfc/lpfc_sli.c index fa1a714a78f0..99307bb7b62c 100644 --- a/drivers/scsi/lpfc/lpfc_sli.c +++ b/drivers/scsi/lpfc/lpfc_sli.c @@ -987,16 +987,10 @@ lpfc_clr_rrq_active(struct lpfc_hba *phba, { struct lpfc_nodelist *ndlp = NULL; + /* Lookup did to verify if did is still active on this vport */ if (rrq->vport) ndlp = lpfc_findnode_did(rrq->vport, rrq->nlp_DID); - /* The target DID could have been swapped (cable swap) - * we should use the ndlp from the findnode if it is - * available. - */ - if ((!ndlp) && rrq->ndlp) - ndlp = rrq->ndlp; - if (!ndlp) goto out; @@ -1118,9 +1112,14 @@ lpfc_cleanup_vports_rrqs(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp) lpfc_sli4_vport_delete_fcp_xri_aborted(vport); } spin_lock_irqsave(&phba->hbalock, iflags); - list_for_each_entry_safe(rrq, nextrrq, &phba->active_rrq_list, list) - if ((rrq->vport == vport) && (!ndlp || rrq->ndlp == ndlp)) + list_for_each_entry_safe(rrq, nextrrq, &phba->active_rrq_list, list) { + if (rrq->vport != vport) + continue; + + if (!ndlp || ndlp == lpfc_findnode_did(vport, rrq->nlp_DID)) list_move(&rrq->list, &rrq_list); + + } spin_unlock_irqrestore(&phba->hbalock, iflags); list_for_each_entry_safe(rrq, nextrrq, &rrq_list, list) { @@ -1213,7 +1212,6 @@ lpfc_set_rrq_active(struct lpfc_hba *phba, struct lpfc_nodelist *ndlp, rrq->xritag = xritag; rrq->rrq_stop_time = jiffies + msecs_to_jiffies(1000 * (phba->fc_ratov + 1)); - rrq->ndlp = ndlp; rrq->nlp_DID = ndlp->nlp_DID; rrq->vport = ndlp->vport; rrq->rxid = rxid; From 618e2ee146d414481c39af61fb018f50bee4ad33 Mon Sep 17 00:00:00 2001 From: James Smart Date: Mon, 1 Mar 2021 09:18:04 -0800 Subject: [PATCH 053/412] scsi: lpfc: Fix FLOGI failure due to accessing a freed node After an initial successful FLOGI into the switch, if a subsequent FLOGI fails the driver crashed accessing a node struct. On FLOGI error, the flogi completion logic triggers the final dereference on the node structure without checking if it is registered with a backend. The devloss logic is triggered after node is freed leading to the access of freed node. Fix by adjusting the error path to not take the final dereferece if there is an outstanding transport registration. Let the transport devloss call remove the final reference. Link: https://lore.kernel.org/r/20210301171821.3427-6-jsmart2021@gmail.com Co-developed-by: Dick Kennedy Signed-off-by: Dick Kennedy Signed-off-by: James Smart Signed-off-by: Martin K. Petersen --- drivers/scsi/lpfc/lpfc_els.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/scsi/lpfc/lpfc_els.c b/drivers/scsi/lpfc/lpfc_els.c index cc0b4f2661ab..27e2f8136f73 100644 --- a/drivers/scsi/lpfc/lpfc_els.c +++ b/drivers/scsi/lpfc/lpfc_els.c @@ -1182,7 +1182,8 @@ flogifail: phba->fcf.fcf_flag &= ~FCF_DISCOVERY; spin_unlock_irq(&phba->hbalock); - lpfc_nlp_put(ndlp); + if (!(ndlp->fc4_xpt_flags & (SCSI_XPT_REGD | NVME_XPT_REGD))) + lpfc_nlp_put(ndlp); if (!lpfc_error_lost_link(irsp)) { /* FLOGI failed, so just use loop map to make discovery list */ lpfc_disc_list_loopmap(vport); From 6b6eaf8a5330a4ab37a0d562f24228226e6ac630 Mon Sep 17 00:00:00 2001 From: James Smart Date: Mon, 1 Mar 2021 09:18:05 -0800 Subject: [PATCH 054/412] scsi: lpfc: Fix lpfc_els_retry() possible null pointer dereference Driver crashed in lpfc_debugfs_disc_trc() due to null ndlp pointer. In some calling cases, the ndlp is null and the did is looked up. Fix by using the local did variable that is set appropriately based on ndlp value. Link: https://lore.kernel.org/r/20210301171821.3427-7-jsmart2021@gmail.com Co-developed-by: Dick Kennedy Signed-off-by: Dick Kennedy Signed-off-by: James Smart Signed-off-by: Martin K. Petersen --- drivers/scsi/lpfc/lpfc_els.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/scsi/lpfc/lpfc_els.c b/drivers/scsi/lpfc/lpfc_els.c index 27e2f8136f73..e0454c53267b 100644 --- a/drivers/scsi/lpfc/lpfc_els.c +++ b/drivers/scsi/lpfc/lpfc_els.c @@ -3823,7 +3823,7 @@ lpfc_els_retry(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_ELS_CMD, "Retry ELS: wd7:x%x wd4:x%x did:x%x", - *(((uint32_t *) irsp) + 7), irsp->un.ulpWord[4], ndlp->nlp_DID); + *(((uint32_t *)irsp) + 7), irsp->un.ulpWord[4], did); switch (irsp->ulpStatus) { case IOSTAT_FCP_RSP_ERROR: From bd4f5100424d17d4e560d6653902ef8e49b2fc1f Mon Sep 17 00:00:00 2001 From: James Smart Date: Mon, 1 Mar 2021 09:18:06 -0800 Subject: [PATCH 055/412] scsi: lpfc: Fix pt2pt connection does not recover after LOGO On a pt2pt setup, between 2 initiators, if one side issues a a LOGO, there is no relogin attempt. The FC specs are grey in this area on which port (higher wwn or not) is to re-login. As there is no spec guidance, unconditionally re-PLOGI after the logout to ensure a login is re-established. Link: https://lore.kernel.org/r/20210301171821.3427-8-jsmart2021@gmail.com Co-developed-by: Dick Kennedy Signed-off-by: Dick Kennedy Signed-off-by: James Smart Signed-off-by: Martin K. Petersen --- drivers/scsi/lpfc/lpfc_nportdisc.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/drivers/scsi/lpfc/lpfc_nportdisc.c b/drivers/scsi/lpfc/lpfc_nportdisc.c index 135d8e8a42ba..4918423960d6 100644 --- a/drivers/scsi/lpfc/lpfc_nportdisc.c +++ b/drivers/scsi/lpfc/lpfc_nportdisc.c @@ -913,9 +913,14 @@ lpfc_rcv_logo(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp, } } else if ((!(ndlp->nlp_type & NLP_FABRIC) && ((ndlp->nlp_type & NLP_FCP_TARGET) || - !(ndlp->nlp_type & NLP_FCP_INITIATOR))) || + (ndlp->nlp_type & NLP_NVME_TARGET) || + (vport->fc_flag & FC_PT2PT))) || (ndlp->nlp_state == NLP_STE_ADISC_ISSUE)) { - /* Only try to re-login if this is NOT a Fabric Node */ + /* Only try to re-login if this is NOT a Fabric Node + * AND the remote NPORT is a FCP/NVME Target or we + * are in pt2pt mode. NLP_STE_ADISC_ISSUE is a special + * case for LOGO as a response to ADISC behavior. + */ mod_timer(&ndlp->nlp_delayfunc, jiffies + msecs_to_jiffies(1000 * 1)); spin_lock_irq(&ndlp->lock); From ae960d78ec3ab19023d19d134b066eb453aff602 Mon Sep 17 00:00:00 2001 From: James Smart Date: Mon, 1 Mar 2021 09:18:07 -0800 Subject: [PATCH 056/412] scsi: lpfc: Fix unnecessary null check in lpfc_release_scsi_buf lpfc_fcp_io_cmd_wqe_cmpl() is intended to mirror lpfc_nvme_io_cmd_wqe_cmpl() for sli4 fcp completions. When the routine was added, lpfc_fcp_io_cmd_wqe_cmpl() included a null pointer check for phba. However, phba is definitely valid, being dereferenced by the calling routine and used later in the routine itself. Remove the unnecessary null check. Link: https://lore.kernel.org/r/20210301171821.3427-9-jsmart2021@gmail.com Fixes: 96e209be6ecb ("scsi: lpfc: Convert SCSI I/O completions to SLI-3 and SLI-4 handlers") Co-developed-by: Dick Kennedy Signed-off-by: Dick Kennedy Signed-off-by: James Smart Signed-off-by: Martin K. Petersen --- drivers/scsi/lpfc/lpfc_scsi.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/scsi/lpfc/lpfc_scsi.c b/drivers/scsi/lpfc/lpfc_scsi.c index 3e1bc55993fd..97178b30074b 100644 --- a/drivers/scsi/lpfc/lpfc_scsi.c +++ b/drivers/scsi/lpfc/lpfc_scsi.c @@ -4074,7 +4074,7 @@ lpfc_fcp_io_cmd_wqe_cmpl(struct lpfc_hba *phba, struct lpfc_iocbq *pwqeIn, /* Sanity check on return of outstanding command */ cmd = lpfc_cmd->pCmd; - if (!cmd || !phba) { + if (!cmd) { lpfc_printf_vlog(vport, KERN_ERR, LOG_TRACE_EVENT, "9042 I/O completion: Not an active IO\n"); spin_unlock(&lpfc_cmd->buf_lock); From 8dd1c125f7f838abad009b64bff5f0a11afe3cb6 Mon Sep 17 00:00:00 2001 From: James Smart Date: Mon, 1 Mar 2021 09:18:08 -0800 Subject: [PATCH 057/412] scsi: lpfc: Fix null pointer dereference in lpfc_prep_els_iocb() It is possible to call lpfc_issue_els_plogi() passing a did for which no matching ndlp is found. A call is then made to lpfc_prep_els_iocb() with a null pointer to a lpfc_nodelist structure resulting in a null pointer dereference. Fix by returning an error status if no valid ndlp is found. Fix up comments regarding ndlp reference counting. Link: https://lore.kernel.org/r/20210301171821.3427-10-jsmart2021@gmail.com Fixes: 4430f7fd09ec ("scsi: lpfc: Rework locations of ndlp reference taking") Co-developed-by: Dick Kennedy Signed-off-by: Dick Kennedy Signed-off-by: James Smart Signed-off-by: Martin K. Petersen --- drivers/scsi/lpfc/lpfc_els.c | 48 +++++++++++++++++------------------- 1 file changed, 23 insertions(+), 25 deletions(-) diff --git a/drivers/scsi/lpfc/lpfc_els.c b/drivers/scsi/lpfc/lpfc_els.c index e0454c53267b..de67ba76374a 100644 --- a/drivers/scsi/lpfc/lpfc_els.c +++ b/drivers/scsi/lpfc/lpfc_els.c @@ -1,7 +1,7 @@ /******************************************************************* * This file is part of the Emulex Linux Device Driver for * * Fibre Channel Host Bus Adapters. * - * Copyright (C) 2017-2020 Broadcom. All Rights Reserved. The term * + * Copyright (C) 2017-2021 Broadcom. All Rights Reserved. The term * * “Broadcom” refers to Broadcom Inc. and/or its subsidiaries. * * Copyright (C) 2004-2016 Emulex. All rights reserved. * * EMULEX and SLI are trademarks of Emulex. * @@ -2052,13 +2052,12 @@ out_freeiocb: * This routine issues a Port Login (PLOGI) command to a remote N_Port * (with the @did) for a @vport. Before issuing a PLOGI to a remote N_Port, * the ndlp with the remote N_Port DID must exist on the @vport's ndlp list. - * This routine constructs the proper feilds of the PLOGI IOCB and invokes + * This routine constructs the proper fields of the PLOGI IOCB and invokes * the lpfc_sli_issue_iocb() routine to send out PLOGI ELS command. * - * Note that, in lpfc_prep_els_iocb() routine, the reference count of ndlp - * will be incremented by 1 for holding the ndlp and the reference to ndlp - * will be stored into the context1 field of the IOCB for the completion - * callback function to the PLOGI ELS command. + * Note that the ndlp reference count will be incremented by 1 for holding + * the ndlp and the reference to ndlp will be stored into the context1 field + * of the IOCB for the completion callback function to the PLOGI ELS command. * * Return code * 0 - Successfully issued a plogi for @vport @@ -2076,29 +2075,28 @@ lpfc_issue_els_plogi(struct lpfc_vport *vport, uint32_t did, uint8_t retry) int ret; ndlp = lpfc_findnode_did(vport, did); + if (!ndlp) + return 1; - if (ndlp) { - /* Defer the processing of the issue PLOGI until after the - * outstanding UNREG_RPI mbox command completes, unless we - * are going offline. This logic does not apply for Fabric DIDs - */ - if ((ndlp->nlp_flag & NLP_UNREG_INP) && - ((ndlp->nlp_DID & Fabric_DID_MASK) != Fabric_DID_MASK) && - !(vport->fc_flag & FC_OFFLINE_MODE)) { - lpfc_printf_vlog(vport, KERN_INFO, LOG_DISCOVERY, - "4110 Issue PLOGI x%x deferred " - "on NPort x%x rpi x%x Data: x%px\n", - ndlp->nlp_defer_did, ndlp->nlp_DID, - ndlp->nlp_rpi, ndlp); + /* Defer the processing of the issue PLOGI until after the + * outstanding UNREG_RPI mbox command completes, unless we + * are going offline. This logic does not apply for Fabric DIDs + */ + if ((ndlp->nlp_flag & NLP_UNREG_INP) && + ((ndlp->nlp_DID & Fabric_DID_MASK) != Fabric_DID_MASK) && + !(vport->fc_flag & FC_OFFLINE_MODE)) { + lpfc_printf_vlog(vport, KERN_INFO, LOG_DISCOVERY, + "4110 Issue PLOGI x%x deferred " + "on NPort x%x rpi x%x Data: x%px\n", + ndlp->nlp_defer_did, ndlp->nlp_DID, + ndlp->nlp_rpi, ndlp); - /* We can only defer 1st PLOGI */ - if (ndlp->nlp_defer_did == NLP_EVT_NOTHING_PENDING) - ndlp->nlp_defer_did = did; - return 0; - } + /* We can only defer 1st PLOGI */ + if (ndlp->nlp_defer_did == NLP_EVT_NOTHING_PENDING) + ndlp->nlp_defer_did = did; + return 0; } - /* If ndlp is not NULL, we will bump the reference count on it */ cmdsize = (sizeof(uint32_t) + sizeof(struct serv_parm)); elsiocb = lpfc_prep_els_iocb(vport, 1, cmdsize, retry, ndlp, did, ELS_CMD_PLOGI); From 8e9a3250dc61ac1a3b8e4c98ed255fdb4d40cddc Mon Sep 17 00:00:00 2001 From: James Smart Date: Mon, 1 Mar 2021 09:18:09 -0800 Subject: [PATCH 058/412] scsi: lpfc: Fix use after free in lpfc_els_free_iocb There are several code paths where the following sequence occurs: - An ndlp pointer is assigned to an iocb via a nlp_get() - An attempt is made to issue the iocb, but it fails - The failure case does a put on the ndlp then calls lpfc_els_free_iocb() The put may free the ndlp structure, but the els_free_iocb may reference the now-stale ndlp pointer and cause a crash. Fix by ensuring that the lpfc_els_free_iocb() occurs before the lpfc_nlp_put(). While fixing, refactor the code to better ensure this calling sequence. Link: https://lore.kernel.org/r/20210301171821.3427-11-jsmart2021@gmail.com Co-developed-by: Dick Kennedy Signed-off-by: Dick Kennedy Signed-off-by: James Smart Signed-off-by: Martin K. Petersen --- drivers/scsi/lpfc/lpfc_els.c | 348 ++++++++++++++++++----------------- 1 file changed, 177 insertions(+), 171 deletions(-) diff --git a/drivers/scsi/lpfc/lpfc_els.c b/drivers/scsi/lpfc/lpfc_els.c index de67ba76374a..08de3496d065 100644 --- a/drivers/scsi/lpfc/lpfc_els.c +++ b/drivers/scsi/lpfc/lpfc_els.c @@ -1342,12 +1342,17 @@ lpfc_issue_els_flogi(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp, phba->sli3_options, 0, 0); elsiocb->context1 = lpfc_nlp_get(ndlp); - if (!elsiocb->context1) - goto out; + if (!elsiocb->context1) { + lpfc_els_free_iocb(phba, elsiocb); + return 1; + } rc = lpfc_issue_fabric_iocb(phba, elsiocb); - if (rc == IOCB_ERROR) + if (rc == IOCB_ERROR) { + lpfc_els_free_iocb(phba, elsiocb); lpfc_nlp_put(ndlp); + return 1; + } phba->hba_flag |= HBA_FLOGI_ISSUED; @@ -1377,11 +1382,7 @@ lpfc_issue_els_flogi(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp, vport->fc_myDID = did; } - if (!rc) - return 0; - out: - lpfc_els_free_iocb(phba, elsiocb); - return 1; + return 0; } /** @@ -2152,19 +2153,19 @@ lpfc_issue_els_plogi(struct lpfc_vport *vport, uint32_t did, uint8_t retry) "Issue PLOGI: did:x%x refcnt %d", did, kref_read(&ndlp->kref), 0); elsiocb->context1 = lpfc_nlp_get(ndlp); - if (!elsiocb->context1) - goto io_err; + if (!elsiocb->context1) { + lpfc_els_free_iocb(phba, elsiocb); + return 1; + } ret = lpfc_sli_issue_iocb(phba, LPFC_ELS_RING, elsiocb, 0); if (ret) { + lpfc_els_free_iocb(phba, elsiocb); lpfc_nlp_put(ndlp); - goto io_err; + return 1; } - return 0; - io_err: - lpfc_els_free_iocb(phba, elsiocb); - return 1; + return 0; } /** @@ -2458,12 +2459,17 @@ lpfc_issue_els_prli(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp, "Issue PRLI: did:x%x refcnt %d", ndlp->nlp_DID, kref_read(&ndlp->kref), 0); elsiocb->context1 = lpfc_nlp_get(ndlp); - if (!elsiocb->context1) - goto io_err; + if (!elsiocb->context1) { + lpfc_els_free_iocb(phba, elsiocb); + goto err; + } rc = lpfc_sli_issue_iocb(phba, LPFC_ELS_RING, elsiocb, 0); - if (rc == IOCB_ERROR) - goto node_err; + if (rc == IOCB_ERROR) { + lpfc_els_free_iocb(phba, elsiocb); + lpfc_nlp_put(ndlp); + goto err; + } /* The driver supports 2 FC4 types. Make sure @@ -2475,13 +2481,10 @@ lpfc_issue_els_prli(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp, else return 0; - node_err: - lpfc_nlp_put(ndlp); - io_err: +err: spin_lock_irq(&ndlp->lock); ndlp->nlp_flag &= ~NLP_PRLI_SND; spin_unlock_irq(&ndlp->lock); - lpfc_els_free_iocb(phba, elsiocb); return 1; } @@ -2765,24 +2768,27 @@ lpfc_issue_els_adisc(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp, ndlp->nlp_flag |= NLP_ADISC_SND; spin_unlock_irq(&ndlp->lock); elsiocb->context1 = lpfc_nlp_get(ndlp); - if (!elsiocb->context1) - goto node_err; + if (!elsiocb->context1) { + lpfc_els_free_iocb(phba, elsiocb); + goto err; + } lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_ELS_CMD, "Issue ADISC: did:x%x refcnt %d", ndlp->nlp_DID, kref_read(&ndlp->kref), 0); rc = lpfc_sli_issue_iocb(phba, LPFC_ELS_RING, elsiocb, 0); - if (rc == IOCB_ERROR) - goto io_err; + if (rc == IOCB_ERROR) { + lpfc_els_free_iocb(phba, elsiocb); + lpfc_nlp_put(ndlp); + goto err; + } + return 0; - io_err: - lpfc_nlp_put(ndlp); - node_err: +err: spin_lock_irq(&ndlp->lock); ndlp->nlp_flag &= ~NLP_ADISC_SND; spin_unlock_irq(&ndlp->lock); - lpfc_els_free_iocb(phba, elsiocb); return 1; } @@ -2983,15 +2989,20 @@ lpfc_issue_els_logo(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp, ndlp->nlp_flag &= ~NLP_ISSUE_LOGO; spin_unlock_irq(&ndlp->lock); elsiocb->context1 = lpfc_nlp_get(ndlp); - if (!elsiocb->context1) - goto node_err; + if (!elsiocb->context1) { + lpfc_els_free_iocb(phba, elsiocb); + goto err; + } lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_ELS_CMD, "Issue LOGO: did:x%x refcnt %d", ndlp->nlp_DID, kref_read(&ndlp->kref), 0); rc = lpfc_sli_issue_iocb(phba, LPFC_ELS_RING, elsiocb, 0); - if (rc == IOCB_ERROR) - goto io_err; + if (rc == IOCB_ERROR) { + lpfc_els_free_iocb(phba, elsiocb); + lpfc_nlp_put(ndlp); + goto err; + } spin_lock_irq(&ndlp->lock); ndlp->nlp_prev_state = ndlp->nlp_state; @@ -2999,13 +3010,10 @@ lpfc_issue_els_logo(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp, lpfc_nlp_set_state(vport, ndlp, NLP_STE_LOGO_ISSUE); return 0; - io_err: - lpfc_nlp_put(ndlp); - node_err: +err: spin_lock_irq(&ndlp->lock); ndlp->nlp_flag &= ~NLP_LOGO_SND; spin_unlock_irq(&ndlp->lock); - lpfc_els_free_iocb(phba, elsiocb); return 1; } @@ -3221,25 +3229,24 @@ lpfc_issue_els_scr(struct lpfc_vport *vport, uint8_t retry) phba->fc_stat.elsXmitSCR++; elsiocb->iocb_cmpl = lpfc_cmpl_els_disc_cmd; elsiocb->context1 = lpfc_nlp_get(ndlp); - if (!elsiocb->context1) - goto node_err; + if (!elsiocb->context1) { + lpfc_els_free_iocb(phba, elsiocb); + return 1; + } lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_ELS_CMD, "Issue SCR: did:x%x refcnt %d", ndlp->nlp_DID, kref_read(&ndlp->kref), 0); rc = lpfc_sli_issue_iocb(phba, LPFC_ELS_RING, elsiocb, 0); - if (rc == IOCB_ERROR) - goto io_err; + if (rc == IOCB_ERROR) { + lpfc_els_free_iocb(phba, elsiocb); + lpfc_nlp_put(ndlp); + return 1; + } /* Keep the ndlp just in case RDF is being sent */ return 0; - - io_err: - lpfc_nlp_put(ndlp); - node_err: - lpfc_els_free_iocb(phba, elsiocb); - return 1; } /** @@ -3321,16 +3328,21 @@ lpfc_issue_els_rscn(struct lpfc_vport *vport, uint8_t retry) phba->fc_stat.elsXmitRSCN++; elsiocb->iocb_cmpl = lpfc_cmpl_els_cmd; elsiocb->context1 = lpfc_nlp_get(ndlp); - if (!elsiocb->context1) - goto node_err; + if (!elsiocb->context1) { + lpfc_els_free_iocb(phba, elsiocb); + return 1; + } lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_ELS_CMD, "Issue RSCN: did:x%x", ndlp->nlp_DID, 0, 0); rc = lpfc_sli_issue_iocb(phba, LPFC_ELS_RING, elsiocb, 0); - if (rc == IOCB_ERROR) - goto io_err; + if (rc == IOCB_ERROR) { + lpfc_els_free_iocb(phba, elsiocb); + lpfc_nlp_put(ndlp); + return 1; + } /* This will cause the callback-function lpfc_cmpl_els_cmd to * trigger the release of node. @@ -3338,11 +3350,6 @@ lpfc_issue_els_rscn(struct lpfc_vport *vport, uint8_t retry) if (!(vport->fc_flag & FC_PT2PT)) lpfc_nlp_put(ndlp); return 0; -io_err: - lpfc_nlp_put(ndlp); -node_err: - lpfc_els_free_iocb(phba, elsiocb); - return 1; } /** @@ -3437,8 +3444,8 @@ lpfc_issue_els_farpr(struct lpfc_vport *vport, uint32_t nportid, uint8_t retry) * lpfc_els_free_iocb routine to trigger the release of * the node. */ - lpfc_nlp_put(ndlp); lpfc_els_free_iocb(phba, elsiocb); + lpfc_nlp_put(ndlp); return 1; } /* This will cause the callback-function lpfc_cmpl_els_cmd to @@ -3518,23 +3525,22 @@ lpfc_issue_els_rdf(struct lpfc_vport *vport, uint8_t retry) elsiocb->iocb_cmpl = lpfc_cmpl_els_disc_cmd; elsiocb->context1 = lpfc_nlp_get(ndlp); - if (!elsiocb->context1) - goto node_err; + if (!elsiocb->context1) { + lpfc_els_free_iocb(phba, elsiocb); + return -EIO; + } lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_ELS_CMD, "Issue RDF: did:x%x refcnt %d", ndlp->nlp_DID, kref_read(&ndlp->kref), 0); rc = lpfc_sli_issue_iocb(phba, LPFC_ELS_RING, elsiocb, 0); - if (rc == IOCB_ERROR) - goto io_err; + if (rc == IOCB_ERROR) { + lpfc_els_free_iocb(phba, elsiocb); + lpfc_nlp_put(ndlp); + return -EIO; + } return 0; - - io_err: - lpfc_nlp_put(ndlp); - node_err: - lpfc_els_free_iocb(phba, elsiocb); - return -EIO; } /** @@ -4821,12 +4827,17 @@ lpfc_els_rsp_acc(struct lpfc_vport *vport, uint32_t flag, phba->fc_stat.elsXmitACC++; elsiocb->context1 = lpfc_nlp_get(ndlp); - if (!elsiocb->context1) - goto node_err; + if (!elsiocb->context1) { + lpfc_els_free_iocb(phba, elsiocb); + return 1; + } rc = lpfc_sli_issue_iocb(phba, LPFC_ELS_RING, elsiocb, 0); - if (rc == IOCB_ERROR) - goto io_err; + if (rc == IOCB_ERROR) { + lpfc_els_free_iocb(phba, elsiocb); + lpfc_nlp_put(ndlp); + return 1; + } /* Xmit ELS ACC response tag */ lpfc_printf_vlog(vport, KERN_INFO, LOG_ELS, @@ -4837,12 +4848,6 @@ lpfc_els_rsp_acc(struct lpfc_vport *vport, uint32_t flag, ndlp->nlp_DID, ndlp->nlp_flag, ndlp->nlp_state, ndlp->nlp_rpi, vport->fc_flag); return 0; - -io_err: - lpfc_nlp_put(ndlp); -node_err: - lpfc_els_free_iocb(phba, elsiocb); - return 1; } /** @@ -4914,20 +4919,19 @@ lpfc_els_rsp_reject(struct lpfc_vport *vport, uint32_t rejectError, phba->fc_stat.elsXmitLSRJT++; elsiocb->iocb_cmpl = lpfc_cmpl_els_rsp; elsiocb->context1 = lpfc_nlp_get(ndlp); - if (!elsiocb->context1) - goto node_err; + if (!elsiocb->context1) { + lpfc_els_free_iocb(phba, elsiocb); + return 1; + } rc = lpfc_sli_issue_iocb(phba, LPFC_ELS_RING, elsiocb, 0); - if (rc == IOCB_ERROR) - goto io_err; + if (rc == IOCB_ERROR) { + lpfc_els_free_iocb(phba, elsiocb); + lpfc_nlp_put(ndlp); + return 1; + } return 0; - - io_err: - lpfc_nlp_put(ndlp); - node_err: - lpfc_els_free_iocb(phba, elsiocb); - return 1; } /** @@ -4997,12 +5001,17 @@ lpfc_els_rsp_adisc_acc(struct lpfc_vport *vport, struct lpfc_iocbq *oldiocb, phba->fc_stat.elsXmitACC++; elsiocb->iocb_cmpl = lpfc_cmpl_els_rsp; elsiocb->context1 = lpfc_nlp_get(ndlp); - if (!elsiocb->context1) - goto node_err; + if (!elsiocb->context1) { + lpfc_els_free_iocb(phba, elsiocb); + return 1; + } rc = lpfc_sli_issue_iocb(phba, LPFC_ELS_RING, elsiocb, 0); - if (rc == IOCB_ERROR) - goto io_err; + if (rc == IOCB_ERROR) { + lpfc_els_free_iocb(phba, elsiocb); + lpfc_nlp_put(ndlp); + return 1; + } /* Xmit ELS ACC response tag */ lpfc_printf_vlog(vport, KERN_INFO, LOG_ELS, @@ -5013,12 +5022,6 @@ lpfc_els_rsp_adisc_acc(struct lpfc_vport *vport, struct lpfc_iocbq *oldiocb, ndlp->nlp_DID, ndlp->nlp_flag, ndlp->nlp_state, ndlp->nlp_rpi, vport->fc_flag); return 0; - -io_err: - lpfc_nlp_put(ndlp); -node_err: - lpfc_els_free_iocb(phba, elsiocb); - return 1; } /** @@ -5172,19 +5175,19 @@ lpfc_els_rsp_prli_acc(struct lpfc_vport *vport, struct lpfc_iocbq *oldiocb, phba->fc_stat.elsXmitACC++; elsiocb->iocb_cmpl = lpfc_cmpl_els_rsp; elsiocb->context1 = lpfc_nlp_get(ndlp); - if (!elsiocb->context1) - goto node_err; + if (!elsiocb->context1) { + lpfc_els_free_iocb(phba, elsiocb); + return 1; + } rc = lpfc_sli_issue_iocb(phba, LPFC_ELS_RING, elsiocb, 0); - if (rc == IOCB_ERROR) - goto io_err; - return 0; + if (rc == IOCB_ERROR) { + lpfc_els_free_iocb(phba, elsiocb); + lpfc_nlp_put(ndlp); + return 1; + } - io_err: - lpfc_nlp_put(ndlp); - node_err: - lpfc_els_free_iocb(phba, elsiocb); - return 1; + return 0; } /** @@ -5279,20 +5282,19 @@ lpfc_els_rsp_rnid_acc(struct lpfc_vport *vport, uint8_t format, phba->fc_stat.elsXmitACC++; elsiocb->iocb_cmpl = lpfc_cmpl_els_rsp; elsiocb->context1 = lpfc_nlp_get(ndlp); - if (!elsiocb->context1) - goto node_err; + if (!elsiocb->context1) { + lpfc_els_free_iocb(phba, elsiocb); + return 1; + } rc = lpfc_sli_issue_iocb(phba, LPFC_ELS_RING, elsiocb, 0); - if (rc == IOCB_ERROR) - goto io_err; + if (rc == IOCB_ERROR) { + lpfc_els_free_iocb(phba, elsiocb); + lpfc_nlp_put(ndlp); + return 1; + } return 0; - - io_err: - lpfc_nlp_put(ndlp); - node_err: - lpfc_els_free_iocb(phba, elsiocb); - return 1; } /** @@ -5394,19 +5396,19 @@ lpfc_els_rsp_echo_acc(struct lpfc_vport *vport, uint8_t *data, phba->fc_stat.elsXmitACC++; elsiocb->iocb_cmpl = lpfc_cmpl_els_rsp; elsiocb->context1 = lpfc_nlp_get(ndlp); - if (!elsiocb->context1) - goto node_err; + if (!elsiocb->context1) { + lpfc_els_free_iocb(phba, elsiocb); + return 1; + } rc = lpfc_sli_issue_iocb(phba, LPFC_ELS_RING, elsiocb, 0); - if (rc == IOCB_ERROR) - goto io_err; - return 0; + if (rc == IOCB_ERROR) { + lpfc_els_free_iocb(phba, elsiocb); + lpfc_nlp_put(ndlp); + return 1; + } - io_err: - lpfc_nlp_put(ndlp); - node_err: - lpfc_els_free_iocb(phba, elsiocb); - return 1; + return 0; } /** @@ -6050,8 +6052,8 @@ lpfc_els_rdp_cmpl(struct lpfc_hba *phba, struct lpfc_rdp_context *rdp_context, rc = lpfc_sli_issue_iocb(phba, LPFC_ELS_RING, elsiocb, 0); if (rc == IOCB_ERROR) { - lpfc_nlp_put(ndlp); lpfc_els_free_iocb(phba, elsiocb); + lpfc_nlp_put(ndlp); } goto free_rdp_context; @@ -6082,8 +6084,8 @@ error: rc = lpfc_sli_issue_iocb(phba, LPFC_ELS_RING, elsiocb, 0); if (rc == IOCB_ERROR) { - lpfc_nlp_put(ndlp); lpfc_els_free_iocb(phba, elsiocb); + lpfc_nlp_put(ndlp); } free_rdp_context: @@ -6295,16 +6297,16 @@ lpfc_els_lcb_rsp(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb) phba->fc_stat.elsXmitACC++; elsiocb->context1 = lpfc_nlp_get(ndlp); - if (!elsiocb->context1) - goto node_err; + if (!elsiocb->context1) { + lpfc_els_free_iocb(phba, elsiocb); + goto out; + } rc = lpfc_sli_issue_iocb(phba, LPFC_ELS_RING, elsiocb, 0); - if (!rc) - goto out; - - lpfc_nlp_put(ndlp); - node_err: - lpfc_els_free_iocb(phba, elsiocb); + if (rc == IOCB_ERROR) { + lpfc_els_free_iocb(phba, elsiocb); + lpfc_nlp_put(ndlp); + } out: kfree(lcb_context); return; @@ -6340,8 +6342,8 @@ error: rc = lpfc_sli_issue_iocb(phba, LPFC_ELS_RING, elsiocb, 0); if (rc == IOCB_ERROR) { - lpfc_nlp_put(ndlp); lpfc_els_free_iocb(phba, elsiocb); + lpfc_nlp_put(ndlp); } free_lcb_context: kfree(lcb_context); @@ -7407,18 +7409,17 @@ lpfc_els_rsp_rls_acc(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb) elsiocb->iocb_cmpl = lpfc_cmpl_els_rsp; phba->fc_stat.elsXmitACC++; elsiocb->context1 = lpfc_nlp_get(ndlp); - if (!elsiocb->context1) - goto node_err; + if (!elsiocb->context1) { + lpfc_els_free_iocb(phba, elsiocb); + return; + } rc = lpfc_sli_issue_iocb(phba, LPFC_ELS_RING, elsiocb, 0); - if (rc == IOCB_ERROR) - goto io_err; + if (rc == IOCB_ERROR) { + lpfc_els_free_iocb(phba, elsiocb); + lpfc_nlp_put(ndlp); + } return; - - io_err: - lpfc_nlp_put(ndlp); - node_err: - lpfc_els_free_iocb(phba, elsiocb); } /** @@ -7567,8 +7568,8 @@ lpfc_els_rcv_rtv(struct lpfc_vport *vport, struct lpfc_iocbq *cmdiocb, rc = lpfc_sli_issue_iocb(phba, LPFC_ELS_RING, elsiocb, 0); if (rc == IOCB_ERROR) { - lpfc_nlp_put(ndlp); lpfc_els_free_iocb(phba, elsiocb); + lpfc_nlp_put(ndlp); } return 0; @@ -7645,8 +7646,8 @@ lpfc_issue_els_rrq(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp, return 0; io_err: - lpfc_nlp_put(ndlp); lpfc_els_free_iocb(phba, elsiocb); + lpfc_nlp_put(ndlp); return 1; } @@ -7743,19 +7744,19 @@ lpfc_els_rsp_rpl_acc(struct lpfc_vport *vport, uint16_t cmdsize, elsiocb->iocb_cmpl = lpfc_cmpl_els_rsp; phba->fc_stat.elsXmitACC++; elsiocb->context1 = lpfc_nlp_get(ndlp); - if (!elsiocb->context1) - goto node_err; + if (!elsiocb->context1) { + lpfc_els_free_iocb(phba, elsiocb); + return 1; + } rc = lpfc_sli_issue_iocb(phba, LPFC_ELS_RING, elsiocb, 0); - if (rc == IOCB_ERROR) - goto io_err; - return 0; + if (rc == IOCB_ERROR) { + lpfc_els_free_iocb(phba, elsiocb); + lpfc_nlp_put(ndlp); + return 1; + } - io_err: - lpfc_nlp_put(ndlp); - node_err: - lpfc_els_free_iocb(phba, elsiocb); - return 1; + return 0; } /** @@ -9661,11 +9662,14 @@ lpfc_issue_els_fdisc(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp, did, 0, 0); elsiocb->context1 = lpfc_nlp_get(ndlp); - if (!elsiocb->context1) + if (!elsiocb->context1) { + lpfc_els_free_iocb(phba, elsiocb); goto err_out; + } rc = lpfc_issue_fabric_iocb(phba, elsiocb); if (rc == IOCB_ERROR) { + lpfc_els_free_iocb(phba, elsiocb); lpfc_nlp_put(ndlp); goto err_out; } @@ -9674,7 +9678,6 @@ lpfc_issue_els_fdisc(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp, return 0; err_out: - lpfc_els_free_iocb(phba, elsiocb); lpfc_vport_set_state(vport, FC_VPORT_FAILED); lpfc_printf_vlog(vport, KERN_ERR, LOG_TRACE_EVENT, "0256 Issue FDISC: Cannot send IOCB\n"); @@ -9782,20 +9785,23 @@ lpfc_issue_els_npiv_logo(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp) ndlp->nlp_flag |= NLP_LOGO_SND; spin_unlock_irq(&ndlp->lock); elsiocb->context1 = lpfc_nlp_get(ndlp); - if (!elsiocb->context1) - goto node_err; + if (!elsiocb->context1) { + lpfc_els_free_iocb(phba, elsiocb); + goto err; + } + rc = lpfc_sli_issue_iocb(phba, LPFC_ELS_RING, elsiocb, 0); - if (rc == IOCB_ERROR) - goto io_err; + if (rc == IOCB_ERROR) { + lpfc_els_free_iocb(phba, elsiocb); + lpfc_nlp_put(ndlp); + goto err; + } return 0; - io_err: - lpfc_nlp_put(ndlp); - node_err: +err: spin_lock_irq(&ndlp->lock); ndlp->nlp_flag &= ~NLP_LOGO_SND; spin_unlock_irq(&ndlp->lock); - lpfc_els_free_iocb(phba, elsiocb); return 1; } From 148bc64d38fe314475a074c4f757ec9d84537d1c Mon Sep 17 00:00:00 2001 From: James Smart Date: Mon, 1 Mar 2021 09:18:10 -0800 Subject: [PATCH 059/412] scsi: lpfc: Fix status returned in lpfc_els_retry() error exit path An unlikely error exit path from lpfc_els_retry() returns incorrect status to a caller, erroneously indicating that a retry has been successfully issued or scheduled. Change error exit path to indicate no retry. Link: https://lore.kernel.org/r/20210301171821.3427-12-jsmart2021@gmail.com Co-developed-by: Dick Kennedy Signed-off-by: Dick Kennedy Signed-off-by: James Smart Signed-off-by: Martin K. Petersen --- drivers/scsi/lpfc/lpfc_els.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/scsi/lpfc/lpfc_els.c b/drivers/scsi/lpfc/lpfc_els.c index 08de3496d065..3bd1482af72f 100644 --- a/drivers/scsi/lpfc/lpfc_els.c +++ b/drivers/scsi/lpfc/lpfc_els.c @@ -3822,7 +3822,7 @@ lpfc_els_retry(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, did = irsp->un.elsreq64.remoteID; ndlp = lpfc_findnode_did(vport, did); if (!ndlp && (cmd != ELS_CMD_PLOGI)) - return 1; + return 0; } lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_ELS_CMD, From 9dd83f75fc8c2403508d4dbe4b9ebde15ee0bbab Mon Sep 17 00:00:00 2001 From: James Smart Date: Mon, 1 Mar 2021 09:18:11 -0800 Subject: [PATCH 060/412] scsi: lpfc: Fix dropped FLOGI during pt2pt discovery recovery When connected in pt2pt mode, there is a scenario where the remote port significantly delays sending a response to our FLOGI, but acts on the FLOGI it sent us and proceeds to PLOGI/PRLI. The FLOGI ends up timing out and kicks off recovery logic. End result is a lot of unnecessary state changes and lots of discovery messages being logged. Fix by terminating the FLOGI and noop'ing its completion if we have already accepted the remote ports FLOGI and are now processing PLOGI. Link: https://lore.kernel.org/r/20210301171821.3427-13-jsmart2021@gmail.com Co-developed-by: Dick Kennedy Signed-off-by: Dick Kennedy Signed-off-by: James Smart Signed-off-by: Martin K. Petersen --- drivers/scsi/lpfc/lpfc.h | 1 + drivers/scsi/lpfc/lpfc_crtn.h | 2 ++ drivers/scsi/lpfc/lpfc_els.c | 10 ++++++++-- drivers/scsi/lpfc/lpfc_nportdisc.c | 10 ++++++++++ drivers/scsi/lpfc/lpfc_sli.c | 2 +- 5 files changed, 22 insertions(+), 3 deletions(-) diff --git a/drivers/scsi/lpfc/lpfc.h b/drivers/scsi/lpfc/lpfc.h index 6ba5fa08c47a..431c0d5376d9 100644 --- a/drivers/scsi/lpfc/lpfc.h +++ b/drivers/scsi/lpfc/lpfc.h @@ -782,6 +782,7 @@ struct lpfc_hba { #define HBA_NEEDS_CFG_PORT 0x2000000 /* SLI3 - needs a CONFIG_PORT mbox */ #define HBA_HBEAT_INP 0x4000000 /* mbox HBEAT is in progress */ #define HBA_HBEAT_TMO 0x8000000 /* HBEAT initiated after timeout */ +#define HBA_FLOGI_OUTSTANDING 0x10000000 /* FLOGI is outstanding */ uint32_t fcp_ring_in_use; /* When polling test if intr-hndlr active*/ struct lpfc_dmabuf slim2p; diff --git a/drivers/scsi/lpfc/lpfc_crtn.h b/drivers/scsi/lpfc/lpfc_crtn.h index a0aad4896a45..43820ab8a6e8 100644 --- a/drivers/scsi/lpfc/lpfc_crtn.h +++ b/drivers/scsi/lpfc/lpfc_crtn.h @@ -103,6 +103,8 @@ int lpfc_check_sli_ndlp(struct lpfc_hba *, struct lpfc_sli_ring *, struct lpfc_nodelist *lpfc_nlp_init(struct lpfc_vport *vport, uint32_t did); struct lpfc_nodelist *lpfc_nlp_get(struct lpfc_nodelist *); int lpfc_nlp_put(struct lpfc_nodelist *); +void lpfc_ignore_els_cmpl(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, + struct lpfc_iocbq *rspiocb); int lpfc_nlp_not_used(struct lpfc_nodelist *ndlp); struct lpfc_nodelist *lpfc_setup_disc_node(struct lpfc_vport *, uint32_t); void lpfc_disc_list_loopmap(struct lpfc_vport *); diff --git a/drivers/scsi/lpfc/lpfc_els.c b/drivers/scsi/lpfc/lpfc_els.c index 3bd1482af72f..0e92a0b61e77 100644 --- a/drivers/scsi/lpfc/lpfc_els.c +++ b/drivers/scsi/lpfc/lpfc_els.c @@ -1200,6 +1200,7 @@ flogifail: lpfc_issue_clear_la(phba, vport); } out: + phba->hba_flag &= ~HBA_FLOGI_OUTSTANDING; lpfc_els_free_iocb(phba, cmdiocb); lpfc_nlp_put(ndlp); } @@ -1354,7 +1355,7 @@ lpfc_issue_els_flogi(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp, return 1; } - phba->hba_flag |= HBA_FLOGI_ISSUED; + phba->hba_flag |= (HBA_FLOGI_ISSUED | HBA_FLOGI_OUTSTANDING); /* Check for a deferred FLOGI ACC condition */ if (phba->defer_flogi_acc_flag) { @@ -1425,9 +1426,14 @@ lpfc_els_abort_flogi(struct lpfc_hba *phba) icmd = &iocb->iocb; if (icmd->ulpCommand == CMD_ELS_REQUEST64_CR) { ndlp = (struct lpfc_nodelist *)(iocb->context1); - if (ndlp && (ndlp->nlp_DID == Fabric_DID)) + if (ndlp && ndlp->nlp_DID == Fabric_DID) { + if ((phba->pport->fc_flag & FC_PT2PT) && + !(phba->pport->fc_flag & FC_PT2PT_PLOGI)) + iocb->fabric_iocb_cmpl = + lpfc_ignore_els_cmpl; lpfc_sli_issue_abort_iotag(phba, pring, iocb, NULL); + } } } /* Make sure HBA is alive */ diff --git a/drivers/scsi/lpfc/lpfc_nportdisc.c b/drivers/scsi/lpfc/lpfc_nportdisc.c index 4918423960d6..57e4aef8a9a3 100644 --- a/drivers/scsi/lpfc/lpfc_nportdisc.c +++ b/drivers/scsi/lpfc/lpfc_nportdisc.c @@ -523,6 +523,16 @@ lpfc_rcv_plogi(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp, /* rcv'ed PLOGI decides what our NPortId will be */ vport->fc_myDID = icmd->un.rcvels.parmRo; + /* If there is an outstanding FLOGI, abort it now. + * The remote NPort is not going to ACC our FLOGI + * if its already issuing a PLOGI for pt2pt mode. + * This indicates our FLOGI was dropped; however, we + * must have ACCed the remote NPorts FLOGI to us + * to make it here. + */ + if (phba->hba_flag & HBA_FLOGI_OUTSTANDING) + lpfc_els_abort_flogi(phba); + ed_tov = be32_to_cpu(sp->cmn.e_d_tov); if (sp->cmn.edtovResolution) { /* E_D_TOV ticks are in nanoseconds */ diff --git a/drivers/scsi/lpfc/lpfc_sli.c b/drivers/scsi/lpfc/lpfc_sli.c index 99307bb7b62c..56112c9fb6aa 100644 --- a/drivers/scsi/lpfc/lpfc_sli.c +++ b/drivers/scsi/lpfc/lpfc_sli.c @@ -11591,7 +11591,7 @@ release_iocb: * which are aborted. The function frees memory resources used for * the aborted ELS commands. **/ -static void +void lpfc_ignore_els_cmpl(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, struct lpfc_iocbq *rspiocb) { From 143753059b8b957f1cf4355338a3e3a32f3a85bf Mon Sep 17 00:00:00 2001 From: James Smart Date: Mon, 1 Mar 2021 09:18:12 -0800 Subject: [PATCH 061/412] scsi: lpfc: Fix PLOGI ACC to be transmit after REG_LOGIN The driver is seeing a scenario where PLOGI response was issued and traffic is arriving while the adapter is still setting up the login context. This is resulting in errors handling the traffic. Change the driver so that PLOGI response is sent after the login context has been setup to avoid the situation. Link: https://lore.kernel.org/r/20210301171821.3427-14-jsmart2021@gmail.com Co-developed-by: Dick Kennedy Signed-off-by: Dick Kennedy Signed-off-by: James Smart Signed-off-by: Martin K. Petersen --- drivers/scsi/lpfc/lpfc_nportdisc.c | 241 +++++++++-------------------- 1 file changed, 71 insertions(+), 170 deletions(-) diff --git a/drivers/scsi/lpfc/lpfc_nportdisc.c b/drivers/scsi/lpfc/lpfc_nportdisc.c index 57e4aef8a9a3..090a4232bfa8 100644 --- a/drivers/scsi/lpfc/lpfc_nportdisc.c +++ b/drivers/scsi/lpfc/lpfc_nportdisc.c @@ -279,106 +279,43 @@ lpfc_els_abort(struct lpfc_hba *phba, struct lpfc_nodelist *ndlp) lpfc_cancel_retry_delay_tmo(phba->pport, ndlp); } -/* lpfc_defer_pt2pt_acc - Complete SLI3 pt2pt processing on link up +/* lpfc_defer_plogi_acc - Issue PLOGI ACC after reg_login completes * @phba: pointer to lpfc hba data structure. - * @link_mbox: pointer to CONFIG_LINK mailbox object + * @login_mbox: pointer to REG_RPI mailbox object * - * This routine is only called if we are SLI3, direct connect pt2pt - * mode and the remote NPort issues the PLOGI after link up. + * The ACC for a rcv'ed PLOGI is deferred until AFTER the REG_RPI completes */ static void -lpfc_defer_pt2pt_acc(struct lpfc_hba *phba, LPFC_MBOXQ_t *link_mbox) +lpfc_defer_plogi_acc(struct lpfc_hba *phba, LPFC_MBOXQ_t *login_mbox) { - LPFC_MBOXQ_t *login_mbox; - MAILBOX_t *mb = &link_mbox->u.mb; struct lpfc_iocbq *save_iocb; struct lpfc_nodelist *ndlp; + MAILBOX_t *mb = &login_mbox->u.mb; + int rc; - ndlp = link_mbox->ctx_ndlp; - login_mbox = link_mbox->context3; + ndlp = login_mbox->ctx_ndlp; save_iocb = login_mbox->context3; - link_mbox->context3 = NULL; - login_mbox->context3 = NULL; - /* Check for CONFIG_LINK error */ - if (mb->mbxStatus) { - lpfc_printf_log(phba, KERN_ERR, LOG_TRACE_EVENT, - "4575 CONFIG_LINK fails pt2pt discovery: %x\n", - mb->mbxStatus); - mempool_free(login_mbox, phba->mbox_mem_pool); - mempool_free(link_mbox, phba->mbox_mem_pool); - kfree(save_iocb); - return; + if (mb->mbxStatus == MBX_SUCCESS) { + /* Now that REG_RPI completed successfully, + * we can now proceed with sending the PLOGI ACC. + */ + rc = lpfc_els_rsp_acc(login_mbox->vport, ELS_CMD_PLOGI, + save_iocb, ndlp, NULL); + if (rc) { + lpfc_printf_log(phba, KERN_ERR, LOG_TRACE_EVENT, + "4576 PLOGI ACC fails pt2pt discovery: " + "DID %x Data: %x\n", ndlp->nlp_DID, rc); + } } - /* Now that CONFIG_LINK completed, and our SID is configured, - * we can now proceed with sending the PLOGI ACC. - */ - rc = lpfc_els_rsp_acc(link_mbox->vport, ELS_CMD_PLOGI, - save_iocb, ndlp, login_mbox); - if (rc) { - lpfc_printf_log(phba, KERN_ERR, LOG_TRACE_EVENT, - "4576 PLOGI ACC fails pt2pt discovery: %x\n", - rc); - mempool_free(login_mbox, phba->mbox_mem_pool); - } - - mempool_free(link_mbox, phba->mbox_mem_pool); + /* Now process the REG_RPI cmpl */ + lpfc_mbx_cmpl_reg_login(phba, login_mbox); + ndlp->nlp_flag &= ~NLP_ACC_REGLOGIN; kfree(save_iocb); } -/** - * lpfc_defer_tgt_acc - Progress SLI4 target rcv PLOGI handler - * @phba: Pointer to HBA context object. - * @pmb: Pointer to mailbox object. - * - * This function provides the unreg rpi mailbox completion handler for a tgt. - * The routine frees the memory resources associated with the completed - * mailbox command and transmits the ELS ACC. - * - * This routine is only called if we are SLI4, acting in target - * mode and the remote NPort issues the PLOGI after link up. - **/ -static void -lpfc_defer_acc_rsp(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb) -{ - struct lpfc_vport *vport = pmb->vport; - struct lpfc_nodelist *ndlp = pmb->ctx_ndlp; - LPFC_MBOXQ_t *mbox = pmb->context3; - struct lpfc_iocbq *piocb = NULL; - int rc; - - if (mbox) { - pmb->context3 = NULL; - piocb = mbox->context3; - mbox->context3 = NULL; - } - - /* - * Complete the unreg rpi mbx request, and update flags. - * This will also restart any deferred events. - */ - lpfc_sli4_unreg_rpi_cmpl_clr(phba, pmb); - - if (!piocb) { - lpfc_printf_vlog(vport, KERN_ERR, LOG_TRACE_EVENT, - "4578 PLOGI ACC fail\n"); - if (mbox) - mempool_free(mbox, phba->mbox_mem_pool); - return; - } - - rc = lpfc_els_rsp_acc(vport, ELS_CMD_PLOGI, piocb, ndlp, mbox); - if (rc) { - lpfc_printf_vlog(vport, KERN_ERR, LOG_TRACE_EVENT, - "4579 PLOGI ACC fail %x\n", rc); - if (mbox) - mempool_free(mbox, phba->mbox_mem_pool); - } - kfree(piocb); -} - static int lpfc_rcv_plogi(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp, struct lpfc_iocbq *cmdiocb) @@ -395,8 +332,7 @@ lpfc_rcv_plogi(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp, struct lpfc_iocbq *save_iocb; struct ls_rjt stat; uint32_t vid, flag; - u16 rpi; - int rc, defer_acc; + int rc; memset(&stat, 0, sizeof (struct ls_rjt)); pcmd = (struct lpfc_dmabuf *) cmdiocb->context2; @@ -445,7 +381,6 @@ lpfc_rcv_plogi(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp, else ndlp->nlp_fcp_info |= CLASS3; - defer_acc = 0; ndlp->nlp_class_sup = 0; if (sp->cls1.classValid) ndlp->nlp_class_sup |= FC_COS_CLASS1; @@ -549,27 +484,26 @@ lpfc_rcv_plogi(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp, memcpy(&phba->fc_fabparam, sp, sizeof(struct serv_parm)); - /* Issue config_link / reg_vfi to account for updated TOV's */ - + /* Issue CONFIG_LINK for SLI3 or REG_VFI for SLI4, + * to account for updated TOV's / parameters + */ if (phba->sli_rev == LPFC_SLI_REV4) lpfc_issue_reg_vfi(vport); else { - defer_acc = 1; link_mbox = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL); if (!link_mbox) goto out; lpfc_config_link(phba, link_mbox); - link_mbox->mbox_cmpl = lpfc_defer_pt2pt_acc; + link_mbox->mbox_cmpl = lpfc_sli_def_mbox_cmpl; link_mbox->vport = vport; link_mbox->ctx_ndlp = ndlp; - save_iocb = kzalloc(sizeof(*save_iocb), GFP_KERNEL); - if (!save_iocb) + rc = lpfc_sli_issue_mbox(phba, link_mbox, MBX_NOWAIT); + if (rc == MBX_NOT_FINISHED) { + mempool_free(link_mbox, phba->mbox_mem_pool); goto out; - /* Save info from cmd IOCB used in rsp */ - memcpy((uint8_t *)save_iocb, (uint8_t *)cmdiocb, - sizeof(struct lpfc_iocbq)); + } } lpfc_can_disctmo(vport); @@ -588,59 +522,28 @@ lpfc_rcv_plogi(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp, if (!login_mbox) goto out; + save_iocb = kzalloc(sizeof(*save_iocb), GFP_KERNEL); + if (!save_iocb) + goto out; + + /* Save info from cmd IOCB to be used in rsp after all mbox completes */ + memcpy((uint8_t *)save_iocb, (uint8_t *)cmdiocb, + sizeof(struct lpfc_iocbq)); + /* Registering an existing RPI behaves differently for SLI3 vs SLI4 */ - if (phba->nvmet_support && !defer_acc) { - link_mbox = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL); - if (!link_mbox) - goto out; - - /* As unique identifiers such as iotag would be overwritten - * with those from the cmdiocb, allocate separate temporary - * storage for the copy. - */ - save_iocb = kzalloc(sizeof(*save_iocb), GFP_KERNEL); - if (!save_iocb) - goto out; - - /* Unreg RPI is required for SLI4. */ - rpi = phba->sli4_hba.rpi_ids[ndlp->nlp_rpi]; - lpfc_unreg_login(phba, vport->vpi, rpi, link_mbox); - link_mbox->vport = vport; - link_mbox->ctx_ndlp = lpfc_nlp_get(ndlp); - if (!link_mbox->ctx_ndlp) - goto out; - - link_mbox->mbox_cmpl = lpfc_defer_acc_rsp; - - if (((ndlp->nlp_DID & Fabric_DID_MASK) != Fabric_DID_MASK) && - (!(vport->fc_flag & FC_OFFLINE_MODE))) - ndlp->nlp_flag |= NLP_UNREG_INP; - - /* Save info from cmd IOCB used in rsp */ - memcpy(save_iocb, cmdiocb, sizeof(*save_iocb)); - - /* Delay sending ACC till unreg RPI completes. */ - defer_acc = 1; - } else if (phba->sli_rev == LPFC_SLI_REV4) + if (phba->sli_rev == LPFC_SLI_REV4) lpfc_unreg_rpi(vport, ndlp); + /* Issue REG_LOGIN first, before ACCing the PLOGI, thus we will + * always be deferring the ACC. + */ rc = lpfc_reg_rpi(phba, vport->vpi, icmd->un.rcvels.remoteID, (uint8_t *)sp, login_mbox, ndlp->nlp_rpi); if (rc) goto out; - /* ACC PLOGI rsp command needs to execute first, - * queue this login_mbox command to be processed later. - */ login_mbox->mbox_cmpl = lpfc_mbx_cmpl_reg_login; - /* - * login_mbox->ctx_ndlp = lpfc_nlp_get(ndlp) deferred until mailbox - * command issued in lpfc_cmpl_els_acc(). - */ login_mbox->vport = vport; - spin_lock_irq(&ndlp->lock); - ndlp->nlp_flag |= (NLP_ACC_REGLOGIN | NLP_RCV_PLOGI); - spin_unlock_irq(&ndlp->lock); /* * If there is an outstanding PLOGI issued, abort it before @@ -670,7 +573,8 @@ lpfc_rcv_plogi(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp, * to register, then unregister the RPI. */ spin_lock_irq(&ndlp->lock); - ndlp->nlp_flag |= NLP_RM_DFLT_RPI; + ndlp->nlp_flag |= (NLP_RM_DFLT_RPI | NLP_ACC_REGLOGIN | + NLP_RCV_PLOGI); spin_unlock_irq(&ndlp->lock); stat.un.b.lsRjtRsnCode = LSRJT_INVALID_CMD; stat.un.b.lsRjtRsnCodeExp = LSEXP_NOTHING_MORE; @@ -680,42 +584,39 @@ lpfc_rcv_plogi(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp, mempool_free(login_mbox, phba->mbox_mem_pool); return 1; } - if (defer_acc) { - /* So the order here should be: - * SLI3 pt2pt - * Issue CONFIG_LINK mbox - * CONFIG_LINK cmpl - * SLI4 tgt - * Issue UNREG RPI mbx - * UNREG RPI cmpl - * Issue PLOGI ACC - * PLOGI ACC cmpl - * Issue REG_LOGIN mbox - */ - /* Save the REG_LOGIN mbox for and rcv IOCB copy later */ - link_mbox->context3 = login_mbox; - login_mbox->context3 = save_iocb; + /* So the order here should be: + * SLI3 pt2pt + * Issue CONFIG_LINK mbox + * CONFIG_LINK cmpl + * SLI4 pt2pt + * Issue REG_VFI mbox + * REG_VFI cmpl + * SLI4 + * Issue UNREG RPI mbx + * UNREG RPI cmpl + * Issue REG_RPI mbox + * REG RPI cmpl + * Issue PLOGI ACC + * PLOGI ACC cmpl + */ + login_mbox->mbox_cmpl = lpfc_defer_plogi_acc; + login_mbox->ctx_ndlp = lpfc_nlp_get(ndlp); + login_mbox->context3 = save_iocb; /* For PLOGI ACC */ - /* Start the ball rolling by issuing CONFIG_LINK here */ - rc = lpfc_sli_issue_mbox(phba, link_mbox, MBX_NOWAIT); - if (rc == MBX_NOT_FINISHED) - goto out; - return 1; - } + spin_lock_irq(&ndlp->lock); + ndlp->nlp_flag |= (NLP_ACC_REGLOGIN | NLP_RCV_PLOGI); + spin_unlock_irq(&ndlp->lock); + + /* Start the ball rolling by issuing REG_LOGIN here */ + rc = lpfc_sli_issue_mbox(phba, login_mbox, MBX_NOWAIT); + if (rc == MBX_NOT_FINISHED) + goto out; + lpfc_nlp_set_state(vport, ndlp, NLP_STE_REG_LOGIN_ISSUE); - rc = lpfc_els_rsp_acc(vport, ELS_CMD_PLOGI, cmdiocb, ndlp, login_mbox); - if (rc) - mempool_free(login_mbox, phba->mbox_mem_pool); return 1; out: - if (defer_acc) - lpfc_printf_log(phba, KERN_ERR, LOG_TRACE_EVENT, - "4577 discovery failure: %p %p %p\n", - save_iocb, link_mbox, login_mbox); kfree(save_iocb); - if (link_mbox) - mempool_free(link_mbox, phba->mbox_mem_pool); if (login_mbox) mempool_free(login_mbox, phba->mbox_mem_pool); From 309b477462df7542355ac984674a6e89c01c89aa Mon Sep 17 00:00:00 2001 From: James Smart Date: Mon, 1 Mar 2021 09:18:13 -0800 Subject: [PATCH 062/412] scsi: lpfc: Fix ADISC handling that never frees nodes While testing target port swap test with ADISC enabled, several nodes remain in UNUSED state. These nodes are never freed and rmmod hangs for long time before finising with "0233 Nodelist not empty" error. During PLOGI completion lpfc_plogi_confirm_nport() looks for existing nodes with same WWPN. If found, the existing node is used to continue discovery. The node on which plogi was performed is freed. When ADISC is enabled, an ADISC els request is triggered in response to an RSCN. It's possible that the ADISC may be rejected by the remote port causing the ADISC completion handler to clear the port and node name in the node. If this occurs, if a PLOGI is received it causes a node lookup based on wwpn to now fail, causing the port swap logic to kick in which allocates a new node and swaps to it. This effectively orphans the original node structure. Fix the situation by detecting when the lookup fails and forgo the node swap and node allocation by using the node on which the PLOGI was issued. Link: https://lore.kernel.org/r/20210301171821.3427-15-jsmart2021@gmail.com Co-developed-by: Dick Kennedy Signed-off-by: Dick Kennedy Signed-off-by: James Smart Signed-off-by: Martin K. Petersen --- drivers/scsi/lpfc/lpfc_els.c | 33 +++++++-------------------------- 1 file changed, 7 insertions(+), 26 deletions(-) diff --git a/drivers/scsi/lpfc/lpfc_els.c b/drivers/scsi/lpfc/lpfc_els.c index 0e92a0b61e77..9f81113208b8 100644 --- a/drivers/scsi/lpfc/lpfc_els.c +++ b/drivers/scsi/lpfc/lpfc_els.c @@ -1608,7 +1608,7 @@ lpfc_plogi_confirm_nport(struct lpfc_hba *phba, uint32_t *prsp, struct lpfc_nodelist *new_ndlp; struct serv_parm *sp; uint8_t name[sizeof(struct lpfc_name)]; - uint32_t rc, keepDID = 0, keep_nlp_flag = 0; + uint32_t keepDID = 0, keep_nlp_flag = 0; uint32_t keep_new_nlp_flag = 0; uint16_t keep_nlp_state; u32 keep_nlp_fc4_type = 0; @@ -1630,7 +1630,7 @@ lpfc_plogi_confirm_nport(struct lpfc_hba *phba, uint32_t *prsp, new_ndlp = lpfc_findnode_wwpn(vport, &sp->portName); /* return immediately if the WWPN matches ndlp */ - if (new_ndlp == ndlp) + if (!new_ndlp || (new_ndlp == ndlp)) return ndlp; if (phba->sli_rev == LPFC_SLI_REV4) { @@ -1649,30 +1649,11 @@ lpfc_plogi_confirm_nport(struct lpfc_hba *phba, uint32_t *prsp, (new_ndlp ? new_ndlp->nlp_flag : 0), (new_ndlp ? new_ndlp->nlp_fc4_type : 0)); - if (!new_ndlp) { - rc = memcmp(&ndlp->nlp_portname, name, - sizeof(struct lpfc_name)); - if (!rc) { - if (active_rrqs_xri_bitmap) - mempool_free(active_rrqs_xri_bitmap, - phba->active_rrq_pool); - return ndlp; - } - new_ndlp = lpfc_nlp_init(vport, ndlp->nlp_DID); - if (!new_ndlp) { - if (active_rrqs_xri_bitmap) - mempool_free(active_rrqs_xri_bitmap, - phba->active_rrq_pool); - return ndlp; - } - } else { - keepDID = new_ndlp->nlp_DID; - if (phba->sli_rev == LPFC_SLI_REV4 && - active_rrqs_xri_bitmap) - memcpy(active_rrqs_xri_bitmap, - new_ndlp->active_rrqs_xri_bitmap, - phba->cfg_rrq_xri_bitmap_sz); - } + keepDID = new_ndlp->nlp_DID; + + if (phba->sli_rev == LPFC_SLI_REV4 && active_rrqs_xri_bitmap) + memcpy(active_rrqs_xri_bitmap, new_ndlp->active_rrqs_xri_bitmap, + phba->cfg_rrq_xri_bitmap_sz); /* At this point in this routine, we know new_ndlp will be * returned. however, any previous GID_FTs that were done From bb6fd33e3a0cf4325a8114f2f2fece881713973c Mon Sep 17 00:00:00 2001 From: James Smart Date: Mon, 1 Mar 2021 09:18:14 -0800 Subject: [PATCH 063/412] scsi: lpfc: Fix nodeinfo debugfs output The debugfs nodeinfo output gets jumbled when no rpri or a defer entry is displayed. The misalignment makes it difficult to read. Change the format to consistently print out a 4 character rpi, and turn defer into a suffix. Link: https://lore.kernel.org/r/20210301171821.3427-16-jsmart2021@gmail.com Co-developed-by: Dick Kennedy Signed-off-by: Dick Kennedy Signed-off-by: James Smart Signed-off-by: Martin K. Petersen --- drivers/scsi/lpfc/lpfc_debugfs.c | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/drivers/scsi/lpfc/lpfc_debugfs.c b/drivers/scsi/lpfc/lpfc_debugfs.c index bc79a017e1a2..689c183485f7 100644 --- a/drivers/scsi/lpfc/lpfc_debugfs.c +++ b/drivers/scsi/lpfc/lpfc_debugfs.c @@ -869,7 +869,7 @@ lpfc_debugfs_nodelist_data(struct lpfc_vport *vport, char *buf, int size) "WWNN x%llx ", wwn_to_u64(ndlp->nlp_nodename.u.wwn)); if (ndlp->nlp_flag & NLP_RPI_REGISTERED) - len += scnprintf(buf+len, size-len, "RPI:%03d ", + len += scnprintf(buf+len, size-len, "RPI:%04d ", ndlp->nlp_rpi); else len += scnprintf(buf+len, size-len, "RPI:none "); @@ -895,7 +895,7 @@ lpfc_debugfs_nodelist_data(struct lpfc_vport *vport, char *buf, int size) if (ndlp->nlp_type & NLP_NVME_INITIATOR) len += scnprintf(buf + len, size - len, "NVME_INITIATOR "); - len += scnprintf(buf+len, size-len, "refcnt:%x", + len += scnprintf(buf+len, size-len, "refcnt:%d", kref_read(&ndlp->kref)); if (iocnt) { i = atomic_read(&ndlp->cmd_pending); @@ -904,8 +904,11 @@ lpfc_debugfs_nodelist_data(struct lpfc_vport *vport, char *buf, int size) i, ndlp->cmd_qdepth); outio += i; } - len += scnprintf(buf + len, size - len, "defer:%x ", - ndlp->nlp_defer_did); + len += scnprintf(buf+len, size-len, " xpt:x%x", + ndlp->fc4_xpt_flags); + if (ndlp->nlp_defer_did != NLP_EVT_NOTHING_PENDING) + len += scnprintf(buf+len, size-len, " defer:%x", + ndlp->nlp_defer_did); len += scnprintf(buf+len, size-len, "\n"); } spin_unlock_irq(shost->host_lock); From debbc1e2b978bbacd629e30d93d8eaba1592c358 Mon Sep 17 00:00:00 2001 From: James Smart Date: Mon, 1 Mar 2021 09:18:15 -0800 Subject: [PATCH 064/412] scsi: lpfc: Fix pt2pt state transition causing rmmod hang On a setup with a dual port HBA and both ports direct connected, an rmmod hangs momentarily when we log an Illegal State Transition. Once it resumes, a nodelist not empty logic is hit, which forces rmmod to cleanup and exit. We're missing a state transition case in the discovery engine. Fix by adding a case for a DEVICE_RM event while in the unmapped state to avoid illegal state transition log message. Link: https://lore.kernel.org/r/20210301171821.3427-17-jsmart2021@gmail.com Co-developed-by: Dick Kennedy Signed-off-by: Dick Kennedy Signed-off-by: James Smart Signed-off-by: Martin K. Petersen --- drivers/scsi/lpfc/lpfc_nportdisc.c | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/drivers/scsi/lpfc/lpfc_nportdisc.c b/drivers/scsi/lpfc/lpfc_nportdisc.c index 090a4232bfa8..e178ffb4e4eb 100644 --- a/drivers/scsi/lpfc/lpfc_nportdisc.c +++ b/drivers/scsi/lpfc/lpfc_nportdisc.c @@ -2485,6 +2485,16 @@ lpfc_rcv_prlo_unmap_node(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp, return ndlp->nlp_state; } +static uint32_t +lpfc_device_rm_unmap_node(struct lpfc_vport *vport, + struct lpfc_nodelist *ndlp, + void *arg, + uint32_t evt) +{ + lpfc_drop_node(vport, ndlp); + return NLP_STE_FREED_NODE; +} + static uint32_t lpfc_device_recov_unmap_node(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp, @@ -2978,7 +2988,7 @@ static uint32_t (*lpfc_disc_action[NLP_STE_MAX_STATE * NLP_EVT_MAX_EVENT]) lpfc_disc_illegal, /* CMPL_LOGO */ lpfc_disc_illegal, /* CMPL_ADISC */ lpfc_disc_illegal, /* CMPL_REG_LOGIN */ - lpfc_disc_illegal, /* DEVICE_RM */ + lpfc_device_rm_unmap_node, /* DEVICE_RM */ lpfc_device_recov_unmap_node, /* DEVICE_RECOVERY */ lpfc_rcv_plogi_mapped_node, /* RCV_PLOGI MAPPED_NODE */ From 9628aace0d1f74f81baaa353f38e929fb4580248 Mon Sep 17 00:00:00 2001 From: James Smart Date: Mon, 1 Mar 2021 09:18:16 -0800 Subject: [PATCH 065/412] scsi: lpfc: Fix crash caused by switch reboot Driver is causing a crash in __lpfc_sli_release_iocbq_s4() when it dereferences the els_wq which is NULL. Validate the pring for the els_wq before dereferencing. Reorg the code to move the pring assignment closer to where it is actually used. Link: https://lore.kernel.org/r/20210301171821.3427-18-jsmart2021@gmail.com Co-developed-by: Dick Kennedy Signed-off-by: Dick Kennedy Signed-off-by: James Smart Signed-off-by: Martin K. Petersen --- drivers/scsi/lpfc/lpfc_sli.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/drivers/scsi/lpfc/lpfc_sli.c b/drivers/scsi/lpfc/lpfc_sli.c index 56112c9fb6aa..941540fe67ba 100644 --- a/drivers/scsi/lpfc/lpfc_sli.c +++ b/drivers/scsi/lpfc/lpfc_sli.c @@ -1403,7 +1403,6 @@ __lpfc_sli_release_iocbq_s4(struct lpfc_hba *phba, struct lpfc_iocbq *iocbq) goto out; } - pring = phba->sli4_hba.els_wq->pring; if ((iocbq->iocb_flag & LPFC_EXCHANGE_BUSY) && (sglq->state != SGL_XRI_ABORTED)) { spin_lock_irqsave(&phba->sli4_hba.sgl_list_lock, @@ -1426,9 +1425,9 @@ __lpfc_sli_release_iocbq_s4(struct lpfc_hba *phba, struct lpfc_iocbq *iocbq) &phba->sli4_hba.lpfc_els_sgl_list); spin_unlock_irqrestore( &phba->sli4_hba.sgl_list_lock, iflag); - + pring = lpfc_phba_elsring(phba); /* Check if TXQ queue needs to be serviced */ - if (!list_empty(&pring->txq)) + if (pring && (!list_empty(&pring->txq))) lpfc_worker_wake_up(phba); } } From a94a40eb64f15f8374699a114cd24fbbf48048ed Mon Sep 17 00:00:00 2001 From: James Smart Date: Mon, 1 Mar 2021 09:18:17 -0800 Subject: [PATCH 066/412] scsi: lpfc: Change wording of invalid pci reset log message Message 8347 Invalid device found log message is logged when an LPe12000 adapter is installed. The log message is supposed to indicate an unsupported pci reset adapter rather than an invalid device. Change the wording to: Incapable PCI reset device. Link: https://lore.kernel.org/r/20210301171821.3427-19-jsmart2021@gmail.com Co-developed-by: Dick Kennedy Signed-off-by: Dick Kennedy Signed-off-by: James Smart Signed-off-by: Martin K. Petersen --- drivers/scsi/lpfc/lpfc_scsi.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/scsi/lpfc/lpfc_scsi.c b/drivers/scsi/lpfc/lpfc_scsi.c index 97178b30074b..36c8e17553aa 100644 --- a/drivers/scsi/lpfc/lpfc_scsi.c +++ b/drivers/scsi/lpfc/lpfc_scsi.c @@ -5012,7 +5012,7 @@ lpfc_check_pci_resettable(struct lpfc_hba *phba) break; default: lpfc_printf_log(phba, KERN_INFO, LOG_INIT, - "8347 Invalid device found: " + "8347 Incapable PCI reset device: " "0x%04x\n", ptr->device); return -EBADSLT; } From cdf811606bd8cac4b0c6fe140acc6511d37542f9 Mon Sep 17 00:00:00 2001 From: James Smart Date: Mon, 1 Mar 2021 09:18:18 -0800 Subject: [PATCH 067/412] scsi: lpfc: Reduce LOG_TRACE_EVENT logging for vports Lots of discovery messages are flooding the console log when testing NPIV. Informational message for vports should have LOG_VPORT associated with it as opposed to LOG_TRACE_EVENT. Link: https://lore.kernel.org/r/20210301171821.3427-20-jsmart2021@gmail.com Co-developed-by: Dick Kennedy Signed-off-by: Dick Kennedy Signed-off-by: James Smart Signed-off-by: Martin K. Petersen --- drivers/scsi/lpfc/lpfc_vport.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/scsi/lpfc/lpfc_vport.c b/drivers/scsi/lpfc/lpfc_vport.c index ccf7b6cd0bd8..2fb6904f3209 100644 --- a/drivers/scsi/lpfc/lpfc_vport.c +++ b/drivers/scsi/lpfc/lpfc_vport.c @@ -190,7 +190,7 @@ lpfc_valid_wwn_format(struct lpfc_hba *phba, struct lpfc_name *wwn, ((wwn->u.wwn[0] & 0xf) != 0 || (wwn->u.wwn[1] & 0xf) != 0))) return 1; - lpfc_printf_log(phba, KERN_ERR, LOG_TRACE_EVENT, + lpfc_printf_log(phba, KERN_ERR, LOG_VPORT, "1822 Invalid %s: %02x:%02x:%02x:%02x:" "%02x:%02x:%02x:%02x\n", name_type, @@ -531,7 +531,7 @@ disable_vport(struct fc_vport *fc_vport) } lpfc_vport_set_state(vport, FC_VPORT_DISABLED); - lpfc_printf_vlog(vport, KERN_ERR, LOG_TRACE_EVENT, + lpfc_printf_vlog(vport, KERN_ERR, LOG_VPORT, "1826 Vport Disabled.\n"); return VPORT_OK; } @@ -579,7 +579,7 @@ enable_vport(struct fc_vport *fc_vport) } out: - lpfc_printf_vlog(vport, KERN_ERR, LOG_TRACE_EVENT, + lpfc_printf_vlog(vport, KERN_ERR, LOG_VPORT, "1827 Vport Enabled.\n"); return VPORT_OK; } @@ -725,7 +725,7 @@ skip_logo: spin_lock_irq(&phba->port_list_lock); list_del_init(&vport->listentry); spin_unlock_irq(&phba->port_list_lock); - lpfc_printf_vlog(vport, KERN_ERR, LOG_TRACE_EVENT, + lpfc_printf_vlog(vport, KERN_ERR, LOG_VPORT, "1828 Vport Deleted.\n"); scsi_host_put(shost); return VPORT_OK; From 69b8eff25c8beb8073d82ebb4cfb8a241540feba Mon Sep 17 00:00:00 2001 From: James Smart Date: Mon, 1 Mar 2021 09:18:19 -0800 Subject: [PATCH 068/412] scsi: lpfc: Correct function header comments related to ndlp reference counting Code inspection revealed stale comments in function headers for functions that call lpfc_prep_els_iocb(). Changes in ndlp reference counting were not reflected in function headers. Update the stale comments in function headers to more accurately indicate ndlp reference counting. Link: https://lore.kernel.org/r/20210301171821.3427-21-jsmart2021@gmail.com Co-developed-by: Dick Kennedy Signed-off-by: Dick Kennedy Signed-off-by: James Smart Signed-off-by: Martin K. Petersen --- drivers/scsi/lpfc/lpfc_els.c | 157 ++++++++++++++++------------------- 1 file changed, 70 insertions(+), 87 deletions(-) diff --git a/drivers/scsi/lpfc/lpfc_els.c b/drivers/scsi/lpfc/lpfc_els.c index 9f81113208b8..332e8ab7c60c 100644 --- a/drivers/scsi/lpfc/lpfc_els.c +++ b/drivers/scsi/lpfc/lpfc_els.c @@ -1251,10 +1251,9 @@ lpfc_cmpl_els_link_down(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, * function field. The lpfc_issue_fabric_iocb routine is invoked to send * out FLOGI ELS command with one outstanding fabric IOCB at a time. * - * Note that, in lpfc_prep_els_iocb() routine, the reference count of ndlp - * will be incremented by 1 for holding the ndlp and the reference to ndlp - * will be stored into the context1 field of the IOCB for the completion - * callback function to the FLOGI ELS command. + * Note that the ndlp reference count will be incremented by 1 for holding the + * ndlp and the reference to ndlp will be stored into the context1 field of + * the IOCB for the completion callback function to the FLOGI ELS command. * * Return code * 0 - successfully issued flogi iocb for @vport @@ -2281,10 +2280,9 @@ out: * is put to the IOCB completion callback func field before invoking the * routine lpfc_sli_issue_iocb() to send out PRLI command. * - * Note that, in lpfc_prep_els_iocb() routine, the reference count of ndlp - * will be incremented by 1 for holding the ndlp and the reference to ndlp - * will be stored into the context1 field of the IOCB for the completion - * callback function to the PRLI ELS command. + * Note that the ndlp reference count will be incremented by 1 for holding the + * ndlp and the reference to ndlp will be stored into the context1 field of + * the IOCB for the completion callback function to the PRLI ELS command. * * Return code * 0 - successfully issued prli iocb command for @vport @@ -2710,10 +2708,9 @@ out: * and states of the ndlp, and invokes the lpfc_sli_issue_iocb() routine * to issue the ADISC ELS command. * - * Note that, in lpfc_prep_els_iocb() routine, the reference count of ndlp - * will be incremented by 1 for holding the ndlp and the reference to ndlp - * will be stored into the context1 field of the IOCB for the completion - * callback function to the ADISC ELS command. + * Note that the ndlp reference count will be incremented by 1 for holding the + * ndlp and the reference to ndlp will be stored into the context1 field of + * the IOCB for the completion callback function to the ADISC ELS command. * * Return code * 0 - successfully issued adisc @@ -2788,8 +2785,7 @@ err: * This routine is the completion function for issuing the ELS Logout (LOGO) * command. If no error status was reported from the LOGO response, the * state machine of the associated ndlp shall be invoked for transition with - * respect to NLP_EVT_CMPL_LOGO event. Otherwise, if error status was reported, - * the lpfc_els_retry() routine will be invoked to retry the LOGO command. + * respect to NLP_EVT_CMPL_LOGO event. **/ static void lpfc_cmpl_els_logo(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, @@ -2926,10 +2922,9 @@ out: * payload of the IOCB, properly sets up the @ndlp state, and invokes the * lpfc_sli_issue_iocb() routine to send out the LOGO ELS command. * - * Note that, in lpfc_prep_els_iocb() routine, the reference count of ndlp - * will be incremented by 1 for holding the ndlp and the reference to ndlp - * will be stored into the context1 field of the IOCB for the completion - * callback function to the LOGO ELS command. + * Note that the ndlp reference count will be incremented by 1 for holding the + * ndlp and the reference to ndlp will be stored into the context1 field of + * the IOCB for the completion callback function to the LOGO ELS command. * * Callers of this routine are expected to unregister the RPI first * @@ -3165,10 +3160,9 @@ out: * IOCB is allocated, payload prepared, and the lpfc_sli_issue_iocb() * routine is invoked to send the SCR IOCB. * - * Note that, in lpfc_prep_els_iocb() routine, the reference count of ndlp - * will be incremented by 1 for holding the ndlp and the reference to ndlp - * will be stored into the context1 field of the IOCB for the completion - * callback function to the SCR ELS command. + * Note that the ndlp reference count will be incremented by 1 for holding the + * ndlp and the reference to ndlp will be stored into the context1 field of + * the IOCB for the completion callback function to the SCR ELS command. * * Return code * 0 - Successfully issued scr command @@ -3247,10 +3241,9 @@ lpfc_issue_els_scr(struct lpfc_vport *vport, uint8_t retry) * in point-to-point mode. When sent to the Fabric Controller, it will * replay the RSCN to registered recipients. * - * Note that, in lpfc_prep_els_iocb() routine, the reference count of ndlp - * will be incremented by 1 for holding the ndlp and the reference to ndlp - * will be stored into the context1 field of the IOCB for the completion - * callback function to the RSCN ELS command. + * Note that the ndlp reference count will be incremented by 1 for holding the + * ndlp and the reference to ndlp will be stored into the context1 field of + * the IOCB for the completion callback function to the RSCN ELS command. * * Return code * 0 - Successfully issued RSCN command @@ -3352,10 +3345,9 @@ lpfc_issue_els_rscn(struct lpfc_vport *vport, uint8_t retry) * for this (FARPR) purpose. An IOCB is allocated, payload prepared, and the * lpfc_sli_issue_iocb() routine is invoked to send the FARPR ELS command. * - * Note that, in lpfc_prep_els_iocb() routine, the reference count of ndlp - * will be incremented by 1 for holding the ndlp and the reference to ndlp - * will be stored into the context1 field of the IOCB for the completion - * callback function to the PARPR ELS command. + * Note that the ndlp reference count will be incremented by 1 for holding the + * ndlp and the reference to ndlp will be stored into the context1 field of + * the IOCB for the completion callback function to the FARPR ELS command. * * Return code * 0 - Successfully issued farpr command @@ -3450,10 +3442,9 @@ lpfc_issue_els_farpr(struct lpfc_vport *vport, uint32_t nportid, uint8_t retry) * This routine issues an ELS RDF to the Fabric Controller to register * for diagnostic functions. * - * Note that, in lpfc_prep_els_iocb() routine, the reference count of ndlp - * will be incremented by 1 for holding the ndlp and the reference to ndlp - * will be stored into the context1 field of the IOCB for the completion - * callback function to the RDF ELS command. + * Note that the ndlp reference count will be incremented by 1 for holding the + * ndlp and the reference to ndlp will be stored into the context1 field of + * the IOCB for the completion callback function to the RDF ELS command. * * Return code * 0 - Successfully issued rdf command @@ -3764,7 +3755,7 @@ lpfc_link_reset(struct lpfc_vport *vport) * This routine makes a retry decision on an ELS command IOCB, which has * failed. The following ELS IOCBs use this function for retrying the command * when previously issued command responsed with error status: FLOGI, PLOGI, - * PRLI, ADISC, LOGO, and FDISC. Based on the ELS command type and the + * PRLI, ADISC and FDISC. Based on the ELS command type and the * returned error status, it makes the decision whether a retry shall be * issued for the command, and whether a retry shall be made immediately or * delayed. In the former case, the corresponding ELS command issuing-function @@ -4664,10 +4655,10 @@ out: * field of the IOCB for the completion callback function to issue the * mailbox command to the HBA later when callback is invoked. * - * Note that, in lpfc_prep_els_iocb() routine, the reference count of ndlp - * will be incremented by 1 for holding the ndlp and the reference to ndlp - * will be stored into the context1 field of the IOCB for the completion - * callback function to the corresponding response ELS IOCB command. + * Note that the ndlp reference count will be incremented by 1 for holding the + * ndlp and the reference to ndlp will be stored into the context1 field of + * the IOCB for the completion callback function to the corresponding + * response ELS IOCB command. * * Return code * 0 - Successfully issued acc response @@ -4850,10 +4841,10 @@ lpfc_els_rsp_acc(struct lpfc_vport *vport, uint32_t flag, * context_un.mbox field of the IOCB for the completion callback function * to issue to the HBA later. * - * Note that, in lpfc_prep_els_iocb() routine, the reference count of ndlp - * will be incremented by 1 for holding the ndlp and the reference to ndlp - * will be stored into the context1 field of the IOCB for the completion - * callback function to the reject response ELS IOCB command. + * Note that the ndlp reference count will be incremented by 1 for holding the + * ndlp and the reference to ndlp will be stored into the context1 field of + * the IOCB for the completion callback function to the reject response + * ELS IOCB command. * * Return code * 0 - Successfully issued reject response @@ -4931,10 +4922,10 @@ lpfc_els_rsp_reject(struct lpfc_vport *vport, uint32_t rejectError, * Discover (ADISC) ELS command. It simply prepares the payload of the IOCB * and invokes the lpfc_sli_issue_iocb() routine to send out the command. * - * Note that, in lpfc_prep_els_iocb() routine, the reference count of ndlp - * will be incremented by 1 for holding the ndlp and the reference to ndlp - * will be stored into the context1 field of the IOCB for the completion - * callback function to the ADISC Accept response ELS IOCB command. + * Note that the ndlp reference count will be incremented by 1 for holding the + * ndlp and the reference to ndlp will be stored into the context1 field of + * the IOCB for the completion callback function to the ADISC Accept response + * ELS IOCB command. * * Return code * 0 - Successfully issued acc adisc response @@ -5021,10 +5012,10 @@ lpfc_els_rsp_adisc_acc(struct lpfc_vport *vport, struct lpfc_iocbq *oldiocb, * Login (PRLI) ELS command. It simply prepares the payload of the IOCB * and invokes the lpfc_sli_issue_iocb() routine to send out the command. * - * Note that, in lpfc_prep_els_iocb() routine, the reference count of ndlp - * will be incremented by 1 for holding the ndlp and the reference to ndlp - * will be stored into the context1 field of the IOCB for the completion - * callback function to the PRLI Accept response ELS IOCB command. + * Note that the ndlp reference count will be incremented by 1 for holding the + * ndlp and the reference to ndlp will be stored into the context1 field of + * the IOCB for the completion callback function to the PRLI Accept response + * ELS IOCB command. * * Return code * 0 - Successfully issued acc prli response @@ -5187,17 +5178,11 @@ lpfc_els_rsp_prli_acc(struct lpfc_vport *vport, struct lpfc_iocbq *oldiocb, * This routine issues a Request Node Identification Data (RNID) Accept * (ACC) response. It constructs the RNID ACC response command according to * the proper @format and then calls the lpfc_sli_issue_iocb() routine to - * issue the response. Note that this command does not need to hold the ndlp - * reference count for the callback. So, the ndlp reference count taken by - * the lpfc_prep_els_iocb() routine is put back and the context1 field of - * IOCB is set to NULL to indicate to the lpfc_els_free_iocb() routine that - * there is no ndlp reference available. + * issue the response. * - * Note that, in lpfc_prep_els_iocb() routine, the reference count of ndlp - * will be incremented by 1 for holding the ndlp and the reference to ndlp - * will be stored into the context1 field of the IOCB for the completion - * callback function. However, for the RNID Accept Response ELS command, - * this is undone later by this routine after the IOCB is allocated. + * Note that the ndlp reference count will be incremented by 1 for holding the + * ndlp and the reference to ndlp will be stored into the context1 field of + * the IOCB for the completion callback function. * * Return code * 0 - Successfully issued acc rnid response @@ -7318,16 +7303,16 @@ lpfc_els_rcv_rrq(struct lpfc_vport *vport, struct lpfc_iocbq *cmdiocb, * * This routine is the completion callback function for the MBX_READ_LNK_STAT * mailbox command. This callback function is to actually send the Accept - * (ACC) response to a Read Port Status (RPS) unsolicited IOCB event. It + * (ACC) response to a Read Link Status (RLS) unsolicited IOCB event. It * collects the link statistics from the completion of the MBX_READ_LNK_STAT - * mailbox command, constructs the RPS response with the link statistics + * mailbox command, constructs the RLS response with the link statistics * collected, and then invokes the lpfc_sli_issue_iocb() routine to send ACC - * response to the RPS. + * response to the RLS. * - * Note that, in lpfc_prep_els_iocb() routine, the reference count of ndlp - * will be incremented by 1 for holding the ndlp and the reference to ndlp - * will be stored into the context1 field of the IOCB for the completion - * callback function to the RPS Accept Response ELS IOCB command. + * Note that the ndlp reference count will be incremented by 1 for holding the + * ndlp and the reference to ndlp will be stored into the context1 field of + * the IOCB for the completion callback function to the RLS Accept Response + * ELS IOCB command. * **/ static void @@ -7485,10 +7470,10 @@ reject_out: * response. Otherwise, it sends the Accept(ACC) response to a Read Timeout * Value (RTV) unsolicited IOCB event. * - * Note that, in lpfc_prep_els_iocb() routine, the reference count of ndlp - * will be incremented by 1 for holding the ndlp and the reference to ndlp - * will be stored into the context1 field of the IOCB for the completion - * callback function to the RTV Accept Response ELS IOCB command. + * Note that the ndlp reference count will be incremented by 1 for holding the + * ndlp and the reference to ndlp will be stored into the context1 field of + * the IOCB for the completion callback function to the RTV Accept Response + * ELS IOCB command. * * Return codes * 0 - Successfully processed rtv iocb (currently always return 0) @@ -7675,10 +7660,10 @@ lpfc_send_rrq(struct lpfc_hba *phba, struct lpfc_node_rrq *rrq) * This routine issuees an Accept (ACC) Read Port List (RPL) ELS command. * It is to be called by the lpfc_els_rcv_rpl() routine to accept the RPL. * - * Note that, in lpfc_prep_els_iocb() routine, the reference count of ndlp - * will be incremented by 1 for holding the ndlp and the reference to ndlp - * will be stored into the context1 field of the IOCB for the completion - * callback function to the RPL Accept Response ELS command. + * Note that the ndlp reference count will be incremented by 1 for holding the + * ndlp and the reference to ndlp will be stored into the context1 field of + * the IOCB for the completion callback function to the RPL Accept Response + * ELS command. * * Return code * 0 - Successfully issued ACC RPL ELS command @@ -9569,10 +9554,9 @@ out: * routine to issue the IOCB, which makes sure only one outstanding fabric * IOCB will be sent off HBA at any given time. * - * Note that, in lpfc_prep_els_iocb() routine, the reference count of ndlp - * will be incremented by 1 for holding the ndlp and the reference to ndlp - * will be stored into the context1 field of the IOCB for the completion - * callback function to the FDISC ELS command. + * Note that the ndlp reference count will be incremented by 1 for holding the + * ndlp and the reference to ndlp will be stored into the context1 field of + * the IOCB for the completion callback function to the FDISC ELS command. * * Return code * 0 - Successfully issued fdisc iocb command @@ -9730,10 +9714,9 @@ lpfc_cmpl_els_npiv_logo(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, * * This routine issues a LOGO ELS command to an @ndlp off a @vport. * - * Note that, in lpfc_prep_els_iocb() routine, the reference count of ndlp - * will be incremented by 1 for holding the ndlp and the reference to ndlp - * will be stored into the context1 field of the IOCB for the completion - * callback function to the LOGO ELS command. + * Note that the ndlp reference count will be incremented by 1 for holding the + * ndlp and the reference to ndlp will be stored into the context1 field of + * the IOCB for the completion callback function to the LOGO ELS command. * * Return codes * 0 - Successfully issued logo off the @vport @@ -10050,7 +10033,7 @@ lpfc_issue_fabric_iocb(struct lpfc_hba *phba, struct lpfc_iocbq *iocb) * driver internal fabric IOCB list. The list contains fabric IOCBs to be * issued to the ELS IOCB ring. This abort function walks the fabric IOCB * list, removes each IOCB associated with the @vport off the list, set the - * status feild to IOSTAT_LOCAL_REJECT, and invokes the callback function + * status field to IOSTAT_LOCAL_REJECT, and invokes the callback function * associated with the IOCB. **/ static void lpfc_fabric_abort_vport(struct lpfc_vport *vport) @@ -10083,7 +10066,7 @@ static void lpfc_fabric_abort_vport(struct lpfc_vport *vport) * driver internal fabric IOCB list. The list contains fabric IOCBs to be * issued to the ELS IOCB ring. This abort function walks the fabric IOCB * list, removes each IOCB associated with the @ndlp off the list, set the - * status feild to IOSTAT_LOCAL_REJECT, and invokes the callback function + * status field to IOSTAT_LOCAL_REJECT, and invokes the callback function * associated with the IOCB. **/ void lpfc_fabric_abort_nport(struct lpfc_nodelist *ndlp) @@ -10120,7 +10103,7 @@ void lpfc_fabric_abort_nport(struct lpfc_nodelist *ndlp) * This routine aborts all the IOCBs currently on the driver internal * fabric IOCB list. The list contains fabric IOCBs to be issued to the ELS * IOCB ring. This function takes the entire IOCB list off the fabric IOCB - * list, removes IOCBs off the list, set the status feild to + * list, removes IOCBs off the list, set the status field to * IOSTAT_LOCAL_REJECT, and invokes the callback function associated with * the IOCB. **/ From ef53d5e1b8e49c673672db9c3c2e6c64dd7a0fbb Mon Sep 17 00:00:00 2001 From: James Smart Date: Mon, 1 Mar 2021 09:18:20 -0800 Subject: [PATCH 069/412] scsi: lpfc: Update lpfc version to 12.8.0.8 Update lpfc version to 12.8.0.8. Link: https://lore.kernel.org/r/20210301171821.3427-22-jsmart2021@gmail.com Co-developed-by: Dick Kennedy Signed-off-by: Dick Kennedy Signed-off-by: James Smart Signed-off-by: Martin K. Petersen --- drivers/scsi/lpfc/lpfc_version.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/scsi/lpfc/lpfc_version.h b/drivers/scsi/lpfc/lpfc_version.h index fade044c8f15..6360aa95c6b2 100644 --- a/drivers/scsi/lpfc/lpfc_version.h +++ b/drivers/scsi/lpfc/lpfc_version.h @@ -20,7 +20,7 @@ * included with this package. * *******************************************************************/ -#define LPFC_DRIVER_VERSION "12.8.0.7" +#define LPFC_DRIVER_VERSION "12.8.0.8" #define LPFC_DRIVER_NAME "lpfc" /* Used for SLI 2/3 */ @@ -32,6 +32,6 @@ #define LPFC_MODULE_DESC "Emulex LightPulse Fibre Channel SCSI driver " \ LPFC_DRIVER_VERSION -#define LPFC_COPYRIGHT "Copyright (C) 2017-2020 Broadcom. All Rights " \ +#define LPFC_COPYRIGHT "Copyright (C) 2017-2021 Broadcom. All Rights " \ "Reserved. The term \"Broadcom\" refers to Broadcom Inc. " \ "and/or its subsidiaries." From 67073c69c8902d5f23845b3689360853826fcfb8 Mon Sep 17 00:00:00 2001 From: James Smart Date: Mon, 1 Mar 2021 09:18:21 -0800 Subject: [PATCH 070/412] scsi: lpfc: Update copyrights for 12.8.0.7 and 12.8.0.8 changes For the files modified in 2021 via the 12.8.0.7 and 12.8.0.8 patch sets, update the copyright for 2021. Link: https://lore.kernel.org/r/20210301171821.3427-23-jsmart2021@gmail.com Co-developed-by: Dick Kennedy Signed-off-by: Dick Kennedy Signed-off-by: James Smart Signed-off-by: Martin K. Petersen --- drivers/scsi/lpfc/lpfc.h | 2 +- drivers/scsi/lpfc/lpfc_attr.c | 2 +- drivers/scsi/lpfc/lpfc_crtn.h | 2 +- drivers/scsi/lpfc/lpfc_debugfs.c | 2 +- drivers/scsi/lpfc/lpfc_disc.h | 2 +- drivers/scsi/lpfc/lpfc_hbadisc.c | 2 +- drivers/scsi/lpfc/lpfc_init.c | 2 +- drivers/scsi/lpfc/lpfc_nportdisc.c | 2 +- drivers/scsi/lpfc/lpfc_nvme.c | 2 +- drivers/scsi/lpfc/lpfc_nvmet.c | 4 ++-- drivers/scsi/lpfc/lpfc_scsi.c | 4 ++-- drivers/scsi/lpfc/lpfc_sli.c | 4 ++-- drivers/scsi/lpfc/lpfc_version.h | 2 +- drivers/scsi/lpfc/lpfc_vport.c | 2 +- 14 files changed, 17 insertions(+), 17 deletions(-) diff --git a/drivers/scsi/lpfc/lpfc.h b/drivers/scsi/lpfc/lpfc.h index 431c0d5376d9..f8de0d10620b 100644 --- a/drivers/scsi/lpfc/lpfc.h +++ b/drivers/scsi/lpfc/lpfc.h @@ -1,7 +1,7 @@ /******************************************************************* * This file is part of the Emulex Linux Device Driver for * * Fibre Channel Host Bus Adapters. * - * Copyright (C) 2017-2020 Broadcom. All Rights Reserved. The term * + * Copyright (C) 2017-2021 Broadcom. All Rights Reserved. The term * * “Broadcom” refers to Broadcom Inc. and/or its subsidiaries. * * Copyright (C) 2004-2016 Emulex. All rights reserved. * * EMULEX and SLI are trademarks of Emulex. * diff --git a/drivers/scsi/lpfc/lpfc_attr.c b/drivers/scsi/lpfc/lpfc_attr.c index bdd9a29f4201..98594d6bc26b 100644 --- a/drivers/scsi/lpfc/lpfc_attr.c +++ b/drivers/scsi/lpfc/lpfc_attr.c @@ -1,7 +1,7 @@ /******************************************************************* * This file is part of the Emulex Linux Device Driver for * * Fibre Channel Host Bus Adapters. * - * Copyright (C) 2017-2020 Broadcom. All Rights Reserved. The term * + * Copyright (C) 2017-2021 Broadcom. All Rights Reserved. The term * * “Broadcom” refers to Broadcom Inc. and/or its subsidiaries. * * Copyright (C) 2004-2016 Emulex. All rights reserved. * * EMULEX and SLI are trademarks of Emulex. * diff --git a/drivers/scsi/lpfc/lpfc_crtn.h b/drivers/scsi/lpfc/lpfc_crtn.h index 43820ab8a6e8..eb4cf36229d5 100644 --- a/drivers/scsi/lpfc/lpfc_crtn.h +++ b/drivers/scsi/lpfc/lpfc_crtn.h @@ -1,7 +1,7 @@ /******************************************************************* * This file is part of the Emulex Linux Device Driver for * * Fibre Channel Host Bus Adapters. * - * Copyright (C) 2017-2020 Broadcom. All Rights Reserved. The term * + * Copyright (C) 2017-2021 Broadcom. All Rights Reserved. The term * * “Broadcom” refers to Broadcom Inc. and/or its subsidiaries. * * Copyright (C) 2004-2016 Emulex. All rights reserved. * * EMULEX and SLI are trademarks of Emulex. * diff --git a/drivers/scsi/lpfc/lpfc_debugfs.c b/drivers/scsi/lpfc/lpfc_debugfs.c index 689c183485f7..ec5328f7f1d4 100644 --- a/drivers/scsi/lpfc/lpfc_debugfs.c +++ b/drivers/scsi/lpfc/lpfc_debugfs.c @@ -1,7 +1,7 @@ /******************************************************************* * This file is part of the Emulex Linux Device Driver for * * Fibre Channel Host Bus Adapters. * - * Copyright (C) 2017-2020 Broadcom. All Rights Reserved. The term * + * Copyright (C) 2017-2021 Broadcom. All Rights Reserved. The term * * “Broadcom” refers to Broadcom Inc. and/or its subsidiaries. * * Copyright (C) 2007-2015 Emulex. All rights reserved. * * EMULEX and SLI are trademarks of Emulex. * diff --git a/drivers/scsi/lpfc/lpfc_disc.h b/drivers/scsi/lpfc/lpfc_disc.h index 3bd5bb17035a..08999aad6a10 100644 --- a/drivers/scsi/lpfc/lpfc_disc.h +++ b/drivers/scsi/lpfc/lpfc_disc.h @@ -1,7 +1,7 @@ /******************************************************************* * This file is part of the Emulex Linux Device Driver for * * Fibre Channel Host Bus Adapters. * - * Copyright (C) 2017-2020 Broadcom. All Rights Reserved. The term * + * Copyright (C) 2017-2021 Broadcom. All Rights Reserved. The term * * “Broadcom” refers to Broadcom Inc. and/or its subsidiaries. * * Copyright (C) 2004-2013 Emulex. All rights reserved. * * EMULEX and SLI are trademarks of Emulex. * diff --git a/drivers/scsi/lpfc/lpfc_hbadisc.c b/drivers/scsi/lpfc/lpfc_hbadisc.c index a60fa3f67076..2d23892b2f0d 100644 --- a/drivers/scsi/lpfc/lpfc_hbadisc.c +++ b/drivers/scsi/lpfc/lpfc_hbadisc.c @@ -1,7 +1,7 @@ /******************************************************************* * This file is part of the Emulex Linux Device Driver for * * Fibre Channel Host Bus Adapters. * - * Copyright (C) 2017-2020 Broadcom. All Rights Reserved. The term * + * Copyright (C) 2017-2021 Broadcom. All Rights Reserved. The term * * “Broadcom” refers to Broadcom Inc. and/or its subsidiaries. * * Copyright (C) 2004-2016 Emulex. All rights reserved. * * EMULEX and SLI are trademarks of Emulex. * diff --git a/drivers/scsi/lpfc/lpfc_init.c b/drivers/scsi/lpfc/lpfc_init.c index 71f340dd4fbd..5ea43c527e08 100644 --- a/drivers/scsi/lpfc/lpfc_init.c +++ b/drivers/scsi/lpfc/lpfc_init.c @@ -1,7 +1,7 @@ /******************************************************************* * This file is part of the Emulex Linux Device Driver for * * Fibre Channel Host Bus Adapters. * - * Copyright (C) 2017-2020 Broadcom. All Rights Reserved. The term * + * Copyright (C) 2017-2021 Broadcom. All Rights Reserved. The term * * “Broadcom” refers to Broadcom Inc. and/or its subsidiaries. * * Copyright (C) 2004-2016 Emulex. All rights reserved. * * EMULEX and SLI are trademarks of Emulex. * diff --git a/drivers/scsi/lpfc/lpfc_nportdisc.c b/drivers/scsi/lpfc/lpfc_nportdisc.c index e178ffb4e4eb..9aa907ce4c63 100644 --- a/drivers/scsi/lpfc/lpfc_nportdisc.c +++ b/drivers/scsi/lpfc/lpfc_nportdisc.c @@ -1,7 +1,7 @@ /******************************************************************* * This file is part of the Emulex Linux Device Driver for * * Fibre Channel Host Bus Adapters. * - * Copyright (C) 2017-2020 Broadcom. All Rights Reserved. The term * + * Copyright (C) 2017-2021 Broadcom. All Rights Reserved. The term * * “Broadcom” refers to Broadcom Inc. and/or its subsidiaries. * * Copyright (C) 2004-2016 Emulex. All rights reserved. * * EMULEX and SLI are trademarks of Emulex. * diff --git a/drivers/scsi/lpfc/lpfc_nvme.c b/drivers/scsi/lpfc/lpfc_nvme.c index 4d819e52496a..5fe4e93fe984 100644 --- a/drivers/scsi/lpfc/lpfc_nvme.c +++ b/drivers/scsi/lpfc/lpfc_nvme.c @@ -1,7 +1,7 @@ /******************************************************************* * This file is part of the Emulex Linux Device Driver for * * Fibre Channel Host Bus Adapters. * - * Copyright (C) 2017-2020 Broadcom. All Rights Reserved. The term * + * Copyright (C) 2017-2021 Broadcom. All Rights Reserved. The term * * “Broadcom” refers to Broadcom Inc. and/or its subsidiaries. * * Copyright (C) 2004-2016 Emulex. All rights reserved. * * EMULEX and SLI are trademarks of Emulex. * diff --git a/drivers/scsi/lpfc/lpfc_nvmet.c b/drivers/scsi/lpfc/lpfc_nvmet.c index a3fd959f7431..c84da8e6b65d 100644 --- a/drivers/scsi/lpfc/lpfc_nvmet.c +++ b/drivers/scsi/lpfc/lpfc_nvmet.c @@ -1,7 +1,7 @@ /******************************************************************* * This file is part of the Emulex Linux Device Driver for * - * Fibre Channsel Host Bus Adapters. * - * Copyright (C) 2017-2020 Broadcom. All Rights Reserved. The term * + * Fibre Channel Host Bus Adapters. * + * Copyright (C) 2017-2021 Broadcom. All Rights Reserved. The term * * “Broadcom” refers to Broadcom Inc. and/or its subsidiaries. * * Copyright (C) 2004-2016 Emulex. All rights reserved. * * EMULEX and SLI are trademarks of Emulex. * diff --git a/drivers/scsi/lpfc/lpfc_scsi.c b/drivers/scsi/lpfc/lpfc_scsi.c index 36c8e17553aa..f0caf923f38c 100644 --- a/drivers/scsi/lpfc/lpfc_scsi.c +++ b/drivers/scsi/lpfc/lpfc_scsi.c @@ -1,8 +1,8 @@ /******************************************************************* * This file is part of the Emulex Linux Device Driver for * * Fibre Channel Host Bus Adapters. * - * Copyright (C) 2017-2020 Broadcom. All Rights Reserved. The term * - * “Broadcom” refers to Broadcom Inc. and/or its subsidiaries. * + * Copyright (C) 2017-2021 Broadcom. All Rights Reserved. The term * + * “Broadcom” refers to Broadcom Inc. and/or its subsidiaries. * * Copyright (C) 2004-2016 Emulex. All rights reserved. * * EMULEX and SLI are trademarks of Emulex. * * www.broadcom.com * diff --git a/drivers/scsi/lpfc/lpfc_sli.c b/drivers/scsi/lpfc/lpfc_sli.c index 941540fe67ba..977cc09e8542 100644 --- a/drivers/scsi/lpfc/lpfc_sli.c +++ b/drivers/scsi/lpfc/lpfc_sli.c @@ -1,8 +1,8 @@ /******************************************************************* * This file is part of the Emulex Linux Device Driver for * * Fibre Channel Host Bus Adapters. * - * Copyright (C) 2017-2020 Broadcom. All Rights Reserved. The term * - * “Broadcom” refers to Broadcom Inc. and/or its subsidiaries. * + * Copyright (C) 2017-2021 Broadcom. All Rights Reserved. The term * + * “Broadcom” refers to Broadcom Inc. and/or its subsidiaries. * * Copyright (C) 2004-2016 Emulex. All rights reserved. * * EMULEX and SLI are trademarks of Emulex. * * www.broadcom.com * diff --git a/drivers/scsi/lpfc/lpfc_version.h b/drivers/scsi/lpfc/lpfc_version.h index 6360aa95c6b2..bee74bd3c1d7 100644 --- a/drivers/scsi/lpfc/lpfc_version.h +++ b/drivers/scsi/lpfc/lpfc_version.h @@ -1,7 +1,7 @@ /******************************************************************* * This file is part of the Emulex Linux Device Driver for * * Fibre Channel Host Bus Adapters. * - * Copyright (C) 2017-2020 Broadcom. All Rights Reserved. The term * + * Copyright (C) 2017-2021 Broadcom. All Rights Reserved. The term * * “Broadcom” refers to Broadcom Inc. and/or its subsidiaries. * * Copyright (C) 2004-2016 Emulex. All rights reserved. * * EMULEX and SLI are trademarks of Emulex. * diff --git a/drivers/scsi/lpfc/lpfc_vport.c b/drivers/scsi/lpfc/lpfc_vport.c index 2fb6904f3209..da9a1f72d938 100644 --- a/drivers/scsi/lpfc/lpfc_vport.c +++ b/drivers/scsi/lpfc/lpfc_vport.c @@ -1,7 +1,7 @@ /******************************************************************* * This file is part of the Emulex Linux Device Driver for * * Fibre Channel Host Bus Adapters. * - * Copyright (C) 2017-2020 Broadcom. All Rights Reserved. The term * + * Copyright (C) 2017-2021 Broadcom. All Rights Reserved. The term * * “Broadcom” refers to Broadcom Inc. and/or its subsidiaries. * * Copyright (C) 2004-2016 Emulex. All rights reserved. * * EMULEX and SLI are trademarks of Emulex. * From a81a38cc6ddaf128c7ca9e3fffff21c243f33c97 Mon Sep 17 00:00:00 2001 From: "Melanie Plageman (Microsoft)" Date: Wed, 24 Feb 2021 23:29:48 +0000 Subject: [PATCH 071/412] scsi: storvsc: Parameterize number hardware queues Add ability to set the number of hardware queues with new module parameter, storvsc_max_hw_queues. The default value remains the number of CPUs. This functionality is useful in some environments (e.g. Microsoft Azure) where decreasing the number of hardware queues has been shown to improve performance. Link: https://lore.kernel.org/r/20210224232948.4651-1-melanieplageman@gmail.com Reviewed-by: Michael Kelley Signed-off-by: Melanie Plageman (Microsoft) Signed-off-by: Martin K. Petersen --- drivers/scsi/storvsc_drv.c | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/drivers/scsi/storvsc_drv.c b/drivers/scsi/storvsc_drv.c index 6bc5453cea8a..dfe005c03734 100644 --- a/drivers/scsi/storvsc_drv.c +++ b/drivers/scsi/storvsc_drv.c @@ -366,10 +366,14 @@ static u32 max_outstanding_req_per_channel; static int storvsc_change_queue_depth(struct scsi_device *sdev, int queue_depth); static int storvsc_vcpus_per_sub_channel = 4; +static unsigned int storvsc_max_hw_queues; module_param(storvsc_ringbuffer_size, int, S_IRUGO); MODULE_PARM_DESC(storvsc_ringbuffer_size, "Ring buffer size (bytes)"); +module_param(storvsc_max_hw_queues, uint, 0644); +MODULE_PARM_DESC(storvsc_max_hw_queues, "Maximum number of hardware queues"); + module_param(storvsc_vcpus_per_sub_channel, int, S_IRUGO); MODULE_PARM_DESC(storvsc_vcpus_per_sub_channel, "Ratio of VCPUs to subchannels"); @@ -1907,6 +1911,7 @@ static int storvsc_probe(struct hv_device *device, { int ret; int num_cpus = num_online_cpus(); + int num_present_cpus = num_present_cpus(); struct Scsi_Host *host; struct hv_host_device *host_dev; bool dev_is_ide = ((dev_id->driver_data == IDE_GUID) ? true : false); @@ -2015,8 +2020,17 @@ static int storvsc_probe(struct hv_device *device, * For non-IDE disks, the host supports multiple channels. * Set the number of HW queues we are supporting. */ - if (!dev_is_ide) - host->nr_hw_queues = num_present_cpus(); + if (!dev_is_ide) { + if (storvsc_max_hw_queues > num_present_cpus) { + storvsc_max_hw_queues = 0; + storvsc_log(device, STORVSC_LOGGING_WARN, + "Resetting invalid storvsc_max_hw_queues value to default.\n"); + } + if (storvsc_max_hw_queues) + host->nr_hw_queues = storvsc_max_hw_queues; + else + host->nr_hw_queues = num_present_cpus; + } /* * Set the error handler work queue. From 5b1be37f773b24885a6066732661c804bc32bf53 Mon Sep 17 00:00:00 2001 From: Igor Pylypiv Date: Mon, 1 Mar 2021 10:18:47 -0800 Subject: [PATCH 072/412] scsi: pm80xx: Remove list entry from pm8001_ccb_info List entry is not used. Link: https://lore.kernel.org/r/20210301181847.2893199-1-ipylypiv@google.com Acked-by: Jack Wang Signed-off-by: Igor Pylypiv Signed-off-by: Martin K. Petersen --- drivers/scsi/pm8001/pm8001_sas.h | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/scsi/pm8001/pm8001_sas.h b/drivers/scsi/pm8001/pm8001_sas.h index 039ed91e9841..9ae9f1e61b54 100644 --- a/drivers/scsi/pm8001/pm8001_sas.h +++ b/drivers/scsi/pm8001/pm8001_sas.h @@ -281,7 +281,6 @@ struct pm8001_prd { * CCB(Command Control Block) */ struct pm8001_ccb_info { - struct list_head entry; struct sas_task *task; u32 n_elem; u32 ccb_tag; From 9ec3d4c1056533d09092f9f2b055d48f925506fe Mon Sep 17 00:00:00 2001 From: Igor Pylypiv Date: Thu, 4 Mar 2021 22:09:08 -0800 Subject: [PATCH 073/412] scsi: pm80xx: Replace magic numbers with device state defines This improves the code readability. Link: https://lore.kernel.org/r/20210305060908.2476850-1-ipylypiv@google.com Acked-by: Jack Wang Signed-off-by: Igor Pylypiv Signed-off-by: Martin K. Petersen --- drivers/scsi/pm8001/pm8001_sas.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/scsi/pm8001/pm8001_sas.c b/drivers/scsi/pm8001/pm8001_sas.c index a98d4496ff8b..0cbd25a2ee9f 100644 --- a/drivers/scsi/pm8001/pm8001_sas.c +++ b/drivers/scsi/pm8001/pm8001_sas.c @@ -738,7 +738,7 @@ static int pm8001_exec_internal_tmf_task(struct domain_device *dev, if (pm8001_ha->chip_id != chip_8001) { pm8001_dev->setds_completion = &completion_setstate; PM8001_CHIP_DISP->set_dev_state_req(pm8001_ha, - pm8001_dev, 0x01); + pm8001_dev, DS_OPERATIONAL); wait_for_completion(&completion_setstate); } res = -TMF_RESP_FUNC_FAILED; @@ -1110,7 +1110,7 @@ int pm8001_lu_reset(struct domain_device *dev, u8 *lun) sas_put_local_phy(phy); pm8001_dev->setds_completion = &completion_setstate; rc = PM8001_CHIP_DISP->set_dev_state_req(pm8001_ha, - pm8001_dev, 0x01); + pm8001_dev, DS_OPERATIONAL); wait_for_completion(&completion_setstate); } else { tmf_task.tmf = TMF_LU_RESET; @@ -1229,7 +1229,7 @@ int pm8001_abort_task(struct sas_task *task) /* 1. Set Device state as Recovery */ pm8001_dev->setds_completion = &completion; PM8001_CHIP_DISP->set_dev_state_req(pm8001_ha, - pm8001_dev, 0x03); + pm8001_dev, DS_IN_RECOVERY); wait_for_completion(&completion); /* 2. Send Phy Control Hard Reset */ @@ -1300,7 +1300,7 @@ int pm8001_abort_task(struct sas_task *task) reinit_completion(&completion); pm8001_dev->setds_completion = &completion; PM8001_CHIP_DISP->set_dev_state_req(pm8001_ha, - pm8001_dev, 0x01); + pm8001_dev, DS_OPERATIONAL); wait_for_completion(&completion); } else { rc = pm8001_exec_internal_task_abort(pm8001_ha, From 014ace23a5ec3a030bd98dba2f0ad4f1d0c724bf Mon Sep 17 00:00:00 2001 From: Bhaskar Chowdhury Date: Mon, 1 Mar 2021 18:47:36 +0530 Subject: [PATCH 074/412] scsi: qla4xxx: Fix a typo s/circuting/circuiting/ Link: https://lore.kernel.org/r/20210301131736.14236-1-unixbhaskar@gmail.com Acked-by: Randy Dunlap Signed-off-by: Bhaskar Chowdhury Signed-off-by: Martin K. Petersen --- drivers/scsi/qla4xxx/ql4_os.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/scsi/qla4xxx/ql4_os.c b/drivers/scsi/qla4xxx/ql4_os.c index 7bd9a4a04ad5..178506ac4885 100644 --- a/drivers/scsi/qla4xxx/ql4_os.c +++ b/drivers/scsi/qla4xxx/ql4_os.c @@ -6961,7 +6961,7 @@ static int qla4xxx_sess_conn_setup(struct scsi_qla_host *ha, if (is_reset == RESET_ADAPTER) { iscsi_block_session(cls_sess); /* Use the relogin path to discover new devices - * by short-circuting the logic of setting + * by short-circuiting the logic of setting * timer to relogin - instead set the flags * to initiate login right away. */ From b4388e3db56a371c5a8ef8116358028a66278297 Mon Sep 17 00:00:00 2001 From: Zhang Yunkai Date: Sat, 6 Mar 2021 03:47:06 -0800 Subject: [PATCH 075/412] scsi: ufs: Remove duplicate include in ufshcd 'blkdev.h' included in 'ufshcd.c' is included twice. Link: https://lore.kernel.org/r/20210306114706.217873-1-zhang.yunkai@zte.com.cn Reviewed-by: Bean Huo Signed-off-by: Zhang Yunkai Signed-off-by: Martin K. Petersen --- drivers/scsi/ufs/ufshcd.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/scsi/ufs/ufshcd.c b/drivers/scsi/ufs/ufshcd.c index 5c6a364de144..8c0ff024231c 100644 --- a/drivers/scsi/ufs/ufshcd.c +++ b/drivers/scsi/ufs/ufshcd.c @@ -24,7 +24,6 @@ #include "ufs_bsg.h" #include "ufshcd-crypto.h" #include -#include #define CREATE_TRACE_POINTS #include From 18c2a59a419009601d09c13e0ee8e5be826a95d8 Mon Sep 17 00:00:00 2001 From: Jiapeng Chong Date: Thu, 4 Mar 2021 17:28:44 +0800 Subject: [PATCH 076/412] scsi: ibmvfc: Switch to using kobj_to_dev() Fix the following coccicheck warnings: ./drivers/scsi/ibmvscsi/ibmvfc.c:3483:60-61: WARNING opportunity for kobj_to_dev(). Link: https://lore.kernel.org/r/1614850124-54111-1-git-send-email-jiapeng.chong@linux.alibaba.com Reported-by: Abaci Robot Acked-by: Tyrel Datwyler Signed-off-by: Jiapeng Chong Signed-off-by: Martin K. Petersen --- drivers/scsi/ibmvscsi/ibmvfc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/scsi/ibmvscsi/ibmvfc.c b/drivers/scsi/ibmvscsi/ibmvfc.c index 755313b766b9..e5f1ca70faf9 100644 --- a/drivers/scsi/ibmvscsi/ibmvfc.c +++ b/drivers/scsi/ibmvscsi/ibmvfc.c @@ -3480,7 +3480,7 @@ static ssize_t ibmvfc_read_trace(struct file *filp, struct kobject *kobj, struct bin_attribute *bin_attr, char *buf, loff_t off, size_t count) { - struct device *dev = container_of(kobj, struct device, kobj); + struct device *dev = kobj_to_dev(kobj); struct Scsi_Host *shost = class_to_shost(dev); struct ibmvfc_host *vhost = shost_priv(shost); unsigned long flags = 0; From 083d248b2d44ab7513b2410121a4ac5de267d0ee Mon Sep 17 00:00:00 2001 From: zuoqilin Date: Thu, 4 Mar 2021 13:51:20 +0800 Subject: [PATCH 077/412] scsi: FlashPoint: Fix typo Change 'defualt' to 'default'. Link: https://lore.kernel.org/r/20210304055120.2221-1-zuoqilin1@163.com Acked-by: Khalid Aziz Signed-off-by: zuoqilin Signed-off-by: Martin K. Petersen --- drivers/scsi/FlashPoint.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/scsi/FlashPoint.c b/drivers/scsi/FlashPoint.c index 24ace1824048..f479c542e787 100644 --- a/drivers/scsi/FlashPoint.c +++ b/drivers/scsi/FlashPoint.c @@ -4534,7 +4534,7 @@ static void FPT_phaseBusFree(u32 port, unsigned char p_card) * * Function: Auto Load Default Map * - * Description: Load the Automation RAM with the defualt map values. + * Description: Load the Automation RAM with the default map values. * *---------------------------------------------------------------------*/ static void FPT_autoLoadDefaultMap(u32 p_port) From d3cbb743c3624352333fd6139fc32f17433fca2d Mon Sep 17 00:00:00 2001 From: Bodo Stroesser Date: Wed, 24 Feb 2021 19:53:34 +0100 Subject: [PATCH 078/412] scsi: target: tcmu: Replace IDR by XArray An attempt from Matthew Wilcox to replace IDR usage by XArray in tcmu more than 1 year ago unfortunately got lost. I rebased that work on latest tcmu and tested it. Link: https://lore.kernel.org/r/20210224185335.13844-2-bostroesser@gmail.com Reviewed-by: Mike Christie Signed-off-by: Bodo Stroesser Signed-off-by: Martin K. Petersen --- drivers/target/target_core_user.c | 30 +++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/drivers/target/target_core_user.c b/drivers/target/target_core_user.c index 48ccdf7e5bf8..a109592250f5 100644 --- a/drivers/target/target_core_user.c +++ b/drivers/target/target_core_user.c @@ -8,12 +8,12 @@ #include #include -#include #include #include #include #include #include +#include #include #include #include @@ -147,7 +147,7 @@ struct tcmu_dev { unsigned long *data_bitmap; struct radix_tree_root data_blocks; - struct idr commands; + struct xarray commands; struct timer_list cmd_timer; unsigned int cmd_time_out; @@ -998,8 +998,8 @@ static int queue_cmd_ring(struct tcmu_cmd *tcmu_cmd, sense_reason_t *scsi_err) struct tcmu_mailbox *mb = udev->mb_addr; struct tcmu_cmd_entry *entry; struct iovec *iov; - int iov_cnt, iov_bidi_cnt, cmd_id; - uint32_t cmd_head; + int iov_cnt, iov_bidi_cnt; + uint32_t cmd_id, cmd_head; uint64_t cdb_off; /* size of data buffer needed */ size_t data_length = (size_t)tcmu_cmd->dbi_cnt * DATA_BLOCK_SIZE; @@ -1052,8 +1052,8 @@ static int queue_cmd_ring(struct tcmu_cmd *tcmu_cmd, sense_reason_t *scsi_err) */ goto free_and_queue; - cmd_id = idr_alloc(&udev->commands, tcmu_cmd, 1, USHRT_MAX, GFP_NOWAIT); - if (cmd_id < 0) { + if (xa_alloc(&udev->commands, &cmd_id, tcmu_cmd, XA_LIMIT(1, 0xffff), + GFP_NOWAIT) < 0) { pr_err("tcmu: Could not allocate cmd id.\n"); tcmu_cmd_free_data(tcmu_cmd, tcmu_cmd->dbi_cnt); @@ -1436,7 +1436,7 @@ static unsigned int tcmu_handle_completions(struct tcmu_dev *udev) } WARN_ON(tcmu_hdr_get_op(entry->hdr.len_op) != TCMU_OP_CMD); - cmd = idr_remove(&udev->commands, entry->hdr.cmd_id); + cmd = xa_erase(&udev->commands, entry->hdr.cmd_id); if (!cmd) { pr_err("cmd_id %u not found, ring is broken\n", entry->hdr.cmd_id); @@ -1454,7 +1454,7 @@ static unsigned int tcmu_handle_completions(struct tcmu_dev *udev) free_space = tcmu_run_tmr_queue(udev); if (atomic_read(&global_db_count) > tcmu_global_max_blocks && - idr_is_empty(&udev->commands) && list_empty(&udev->qfull_queue)) { + xa_empty(&udev->commands) && list_empty(&udev->qfull_queue)) { /* * Allocated blocks exceeded global block limit, currently no * more pending or waiting commands so try to reclaim blocks. @@ -1577,7 +1577,7 @@ static struct se_device *tcmu_alloc_device(struct se_hba *hba, const char *name) INIT_LIST_HEAD(&udev->qfull_queue); INIT_LIST_HEAD(&udev->tmr_queue); INIT_LIST_HEAD(&udev->inflight_queue); - idr_init(&udev->commands); + xa_init_flags(&udev->commands, XA_FLAGS_ALLOC1); timer_setup(&udev->qfull_timer, tcmu_qfull_timedout, 0); timer_setup(&udev->cmd_timer, tcmu_cmd_timedout, 0); @@ -1637,7 +1637,7 @@ static void tcmu_dev_kref_release(struct kref *kref) struct se_device *dev = &udev->se_dev; struct tcmu_cmd *cmd; bool all_expired = true; - int i; + unsigned long i; vfree(udev->mb_addr); udev->mb_addr = NULL; @@ -1649,7 +1649,7 @@ static void tcmu_dev_kref_release(struct kref *kref) /* Upper layer should drain all requests before calling this */ mutex_lock(&udev->cmdr_lock); - idr_for_each_entry(&udev->commands, cmd, i) { + xa_for_each(&udev->commands, i, cmd) { if (tcmu_check_and_free_pending_cmd(cmd) != 0) all_expired = false; } @@ -1657,7 +1657,7 @@ static void tcmu_dev_kref_release(struct kref *kref) tcmu_remove_all_queued_tmr(udev); if (!list_empty(&udev->qfull_queue)) all_expired = false; - idr_destroy(&udev->commands); + xa_destroy(&udev->commands); WARN_ON(!all_expired); tcmu_blocks_release(&udev->data_blocks, 0, udev->dbi_max + 1); @@ -2247,16 +2247,16 @@ static void tcmu_reset_ring(struct tcmu_dev *udev, u8 err_level) { struct tcmu_mailbox *mb; struct tcmu_cmd *cmd; - int i; + unsigned long i; mutex_lock(&udev->cmdr_lock); - idr_for_each_entry(&udev->commands, cmd, i) { + xa_for_each(&udev->commands, i, cmd) { pr_debug("removing cmd %u on dev %s from ring (is expired %d)\n", cmd->cmd_id, udev->name, test_bit(TCMU_CMD_BIT_EXPIRED, &cmd->flags)); - idr_remove(&udev->commands, i); + xa_erase(&udev->commands, i); if (!test_bit(TCMU_CMD_BIT_EXPIRED, &cmd->flags)) { WARN_ON(!cmd->se_cmd); list_del_init(&cmd->queue_entry); From f7c89771d07dce0e0ac6c4d8d2048d9aa7e1542c Mon Sep 17 00:00:00 2001 From: Bodo Stroesser Date: Wed, 24 Feb 2021 19:53:35 +0100 Subject: [PATCH 079/412] scsi: target: tcmu: Replace radix_tree with XArray An attempt from Matthew Wilcox to replace radix-tree usage by XArray in tcmu more than 1 year ago unfortunately got lost. I rebased that work on latest tcmu and tested it. Link: https://lore.kernel.org/r/20210224185335.13844-3-bostroesser@gmail.com Reviewed-by: Mike Christie Signed-off-by: Bodo Stroesser Signed-off-by: Martin K. Petersen --- drivers/target/target_core_user.c | 34 +++++++++++++++---------------- 1 file changed, 16 insertions(+), 18 deletions(-) diff --git a/drivers/target/target_core_user.c b/drivers/target/target_core_user.c index a109592250f5..ada3ef982969 100644 --- a/drivers/target/target_core_user.c +++ b/drivers/target/target_core_user.c @@ -14,7 +14,6 @@ #include #include #include -#include #include #include #include @@ -145,7 +144,7 @@ struct tcmu_dev { uint32_t dbi_max; uint32_t dbi_thresh; unsigned long *data_bitmap; - struct radix_tree_root data_blocks; + struct xarray data_blocks; struct xarray commands; @@ -502,13 +501,13 @@ static inline int tcmu_get_empty_block(struct tcmu_dev *udev, int prev_dbi, int *iov_cnt) { struct page *page; - int ret, dbi; + int dbi; dbi = find_first_zero_bit(udev->data_bitmap, udev->dbi_thresh); if (dbi == udev->dbi_thresh) return -1; - page = radix_tree_lookup(&udev->data_blocks, dbi); + page = xa_load(&udev->data_blocks, dbi); if (!page) { if (atomic_add_return(1, &global_db_count) > tcmu_global_max_blocks) @@ -519,8 +518,7 @@ static inline int tcmu_get_empty_block(struct tcmu_dev *udev, if (!page) goto err_alloc; - ret = radix_tree_insert(&udev->data_blocks, dbi, page); - if (ret) + if (xa_store(&udev->data_blocks, dbi, page, GFP_KERNEL)) goto err_insert; } @@ -559,7 +557,7 @@ static int tcmu_get_empty_blocks(struct tcmu_dev *udev, static inline struct page * tcmu_get_block_page(struct tcmu_dev *udev, uint32_t dbi) { - return radix_tree_lookup(&udev->data_blocks, dbi); + return xa_load(&udev->data_blocks, dbi); } static inline void tcmu_free_cmd(struct tcmu_cmd *tcmu_cmd) @@ -1582,7 +1580,7 @@ static struct se_device *tcmu_alloc_device(struct se_hba *hba, const char *name) timer_setup(&udev->qfull_timer, tcmu_qfull_timedout, 0); timer_setup(&udev->cmd_timer, tcmu_cmd_timedout, 0); - INIT_RADIX_TREE(&udev->data_blocks, GFP_KERNEL); + xa_init(&udev->data_blocks); return &udev->se_dev; } @@ -1606,19 +1604,19 @@ static int tcmu_check_and_free_pending_cmd(struct tcmu_cmd *cmd) return -EINVAL; } -static void tcmu_blocks_release(struct radix_tree_root *blocks, - int start, int end) +static void tcmu_blocks_release(struct xarray *blocks, unsigned long first, + unsigned long last) { - int i; + XA_STATE(xas, blocks, first); struct page *page; - for (i = start; i < end; i++) { - page = radix_tree_delete(blocks, i); - if (page) { - __free_page(page); - atomic_dec(&global_db_count); - } + xas_lock(&xas); + xas_for_each(&xas, page, last) { + xas_store(&xas, NULL); + __free_page(page); + atomic_dec(&global_db_count); } + xas_unlock(&xas); } static void tcmu_remove_all_queued_tmr(struct tcmu_dev *udev) @@ -2946,7 +2944,7 @@ static void find_free_blocks(void) unmap_mapping_range(udev->inode->i_mapping, off, 0, 1); /* Release the block pages */ - tcmu_blocks_release(&udev->data_blocks, start, end); + tcmu_blocks_release(&udev->data_blocks, start, end - 1); mutex_unlock(&udev->cmdr_lock); total_freed += end - start; From 1080782f13e3604351e690bd2fa84ebc3b4847f6 Mon Sep 17 00:00:00 2001 From: Bodo Stroesser Date: Fri, 5 Mar 2021 20:00:09 +0100 Subject: [PATCH 080/412] scsi: target: tcmu: Use GFP_NOIO while handling cmds or holding cmdr_lock Especially when using tcmu with tcm_loop, memory allocations with GFP_KERNEL for a LUN can cause write back to the same LUN. So we have to use GFP_NOIO when allocation is done while handling commands or while holding cmdr_lock. Link: https://lore.kernel.org/r/20210305190009.32242-1-bostroesser@gmail.com Reviewed-by: Mike Christie Signed-off-by: Bodo Stroesser Signed-off-by: Martin K. Petersen --- drivers/target/target_core_user.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/target/target_core_user.c b/drivers/target/target_core_user.c index ada3ef982969..9e1b115cb032 100644 --- a/drivers/target/target_core_user.c +++ b/drivers/target/target_core_user.c @@ -518,7 +518,7 @@ static inline int tcmu_get_empty_block(struct tcmu_dev *udev, if (!page) goto err_alloc; - if (xa_store(&udev->data_blocks, dbi, page, GFP_KERNEL)) + if (xa_store(&udev->data_blocks, dbi, page, GFP_NOIO)) goto err_insert; } @@ -1272,7 +1272,7 @@ tcmu_tmr_notify(struct se_device *se_dev, enum tcm_tmreq_table tmf, pr_debug("TMR event %d on dev %s, aborted cmds %d, afflicted cmd_ids %d\n", tcmu_tmr_type(tmf), udev->name, i, cmd_cnt); - tmr = kmalloc(sizeof(*tmr) + cmd_cnt * sizeof(*cmd_ids), GFP_KERNEL); + tmr = kmalloc(sizeof(*tmr) + cmd_cnt * sizeof(*cmd_ids), GFP_NOIO); if (!tmr) goto unlock; From bc9e0e366fceda0b7c534a210258357a229aea7a Mon Sep 17 00:00:00 2001 From: Chaitanya Kulkarni Date: Sat, 27 Feb 2021 21:56:23 -0800 Subject: [PATCH 081/412] scsi: target: iblock: Remove an extra argument The two arguments to the functions op and opf which are REQ_OP_XXX and REQ_XXX flags belong to the two different namespaces, i.e. they can be combined safely given that REQ_OP_XXX takes 8 bits of the flags and rest is available to REQ_XXX flags. Replace op and op_flag arguments with opf. Link: https://lore.kernel.org/r/20210228055645.22253-2-chaitanya.kulkarni@wdc.com Reviewed-by: Mike Christie Reviewed-by: Johannes Thumshirn Signed-off-by: Chaitanya Kulkarni Signed-off-by: Martin K. Petersen --- drivers/target/target_core_iblock.c | 34 ++++++++++++++--------------- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/drivers/target/target_core_iblock.c b/drivers/target/target_core_iblock.c index 90e1c65ad4b6..589b6f475e21 100644 --- a/drivers/target/target_core_iblock.c +++ b/drivers/target/target_core_iblock.c @@ -341,9 +341,8 @@ static void iblock_bio_done(struct bio *bio) iblock_complete_cmd(cmd); } -static struct bio * -iblock_get_bio(struct se_cmd *cmd, sector_t lba, u32 sg_num, int op, - int op_flags) +static struct bio *iblock_get_bio(struct se_cmd *cmd, sector_t lba, u32 sg_num, + unsigned int opf) { struct iblock_dev *ib_dev = IBLOCK_DEV(cmd->se_dev); struct bio *bio; @@ -363,7 +362,7 @@ iblock_get_bio(struct se_cmd *cmd, sector_t lba, u32 sg_num, int op, bio->bi_private = cmd; bio->bi_end_io = &iblock_bio_done; bio->bi_iter.bi_sector = lba; - bio_set_op_attrs(bio, op, op_flags); + bio->bi_opf = opf; return bio; } @@ -517,7 +516,7 @@ iblock_execute_write_same(struct se_cmd *cmd) goto fail; cmd->priv = ibr; - bio = iblock_get_bio(cmd, block_lba, 1, REQ_OP_WRITE, 0); + bio = iblock_get_bio(cmd, block_lba, 1, REQ_OP_WRITE); if (!bio) goto fail_free_ibr; @@ -530,8 +529,7 @@ iblock_execute_write_same(struct se_cmd *cmd) while (bio_add_page(bio, sg_page(sg), sg->length, sg->offset) != sg->length) { - bio = iblock_get_bio(cmd, block_lba, 1, REQ_OP_WRITE, - 0); + bio = iblock_get_bio(cmd, block_lba, 1, REQ_OP_WRITE); if (!bio) goto fail_put_bios; @@ -725,9 +723,11 @@ iblock_execute_rw(struct se_cmd *cmd, struct scatterlist *sgl, u32 sgl_nents, struct bio_list list; struct scatterlist *sg; u32 sg_num = sgl_nents; + unsigned int opf; unsigned bio_cnt; - int i, rc, op, op_flags = 0; + int i, rc; struct sg_mapping_iter prot_miter; + unsigned int miter_dir; if (data_direction == DMA_TO_DEVICE) { struct iblock_dev *ib_dev = IBLOCK_DEV(dev); @@ -736,15 +736,17 @@ iblock_execute_rw(struct se_cmd *cmd, struct scatterlist *sgl, u32 sgl_nents, * Force writethrough using REQ_FUA if a volatile write cache * is not enabled, or if initiator set the Force Unit Access bit. */ - op = REQ_OP_WRITE; + opf = REQ_OP_WRITE; + miter_dir = SG_MITER_TO_SG; if (test_bit(QUEUE_FLAG_FUA, &q->queue_flags)) { if (cmd->se_cmd_flags & SCF_FUA) - op_flags = REQ_FUA; + opf |= REQ_FUA; else if (!test_bit(QUEUE_FLAG_WC, &q->queue_flags)) - op_flags = REQ_FUA; + opf |= REQ_FUA; } } else { - op = REQ_OP_READ; + opf = REQ_OP_READ; + miter_dir = SG_MITER_FROM_SG; } ibr = kzalloc(sizeof(struct iblock_req), GFP_KERNEL); @@ -758,7 +760,7 @@ iblock_execute_rw(struct se_cmd *cmd, struct scatterlist *sgl, u32 sgl_nents, return 0; } - bio = iblock_get_bio(cmd, block_lba, sgl_nents, op, op_flags); + bio = iblock_get_bio(cmd, block_lba, sgl_nents, opf); if (!bio) goto fail_free_ibr; @@ -770,8 +772,7 @@ iblock_execute_rw(struct se_cmd *cmd, struct scatterlist *sgl, u32 sgl_nents, if (cmd->prot_type && dev->dev_attrib.pi_prot_type) sg_miter_start(&prot_miter, cmd->t_prot_sg, cmd->t_prot_nents, - op == REQ_OP_READ ? SG_MITER_FROM_SG : - SG_MITER_TO_SG); + miter_dir); for_each_sg(sgl, sg, sgl_nents, i) { /* @@ -792,8 +793,7 @@ iblock_execute_rw(struct se_cmd *cmd, struct scatterlist *sgl, u32 sgl_nents, bio_cnt = 0; } - bio = iblock_get_bio(cmd, block_lba, sg_num, op, - op_flags); + bio = iblock_get_bio(cmd, block_lba, sg_num, opf); if (!bio) goto fail_put_bios; From a2c6c6a3b1ff4c1094f10ee581309d80568649a0 Mon Sep 17 00:00:00 2001 From: Chaitanya Kulkarni Date: Sat, 27 Feb 2021 21:56:24 -0800 Subject: [PATCH 082/412] scsi: target: iblock: Trim line longer than 80 characters Trim the line that is longer than 80 characters, which is inconsistent with the rest of the code. Link: https://lore.kernel.org/r/20210228055645.22253-3-chaitanya.kulkarni@wdc.com Reviewed-by: Mike Christie Reviewed-by: Johannes Thumshirn Signed-off-by: Chaitanya Kulkarni Signed-off-by: Martin K. Petersen --- drivers/target/target_core_iblock.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/target/target_core_iblock.c b/drivers/target/target_core_iblock.c index 589b6f475e21..3851f9ea26c2 100644 --- a/drivers/target/target_core_iblock.c +++ b/drivers/target/target_core_iblock.c @@ -853,7 +853,8 @@ static unsigned int iblock_get_lbppbe(struct se_device *dev) { struct iblock_dev *ib_dev = IBLOCK_DEV(dev); struct block_device *bd = ib_dev->ibd_bd; - int logs_per_phys = bdev_physical_block_size(bd) / bdev_logical_block_size(bd); + int logs_per_phys = + bdev_physical_block_size(bd) / bdev_logical_block_size(bd); return ilog2(logs_per_phys); } From c151eddbef7eb67322e8187d763953e9c70d4bac Mon Sep 17 00:00:00 2001 From: Chaitanya Kulkarni Date: Sat, 27 Feb 2021 21:56:25 -0800 Subject: [PATCH 083/412] scsi: target: iblock: Fix type of logs_per_phys MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit According to ilog2() it expects 32/64 bit unsigned value. "  147  * ilog2 - log base 2 of 32-bit or a 64-bit unsigned value" Replace type of logs_per_phys from int to unsigned int. Link: https://lore.kernel.org/r/20210228055645.22253-4-chaitanya.kulkarni@wdc.com Reviewed-by: Mike Christie Reviewed-by: Johannes Thumshirn Signed-off-by: Chaitanya Kulkarni Signed-off-by: Martin K. Petersen --- drivers/target/target_core_iblock.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/target/target_core_iblock.c b/drivers/target/target_core_iblock.c index 3851f9ea26c2..d6fdd1c61f90 100644 --- a/drivers/target/target_core_iblock.c +++ b/drivers/target/target_core_iblock.c @@ -853,7 +853,7 @@ static unsigned int iblock_get_lbppbe(struct se_device *dev) { struct iblock_dev *ib_dev = IBLOCK_DEV(dev); struct block_device *bd = ib_dev->ibd_bd; - int logs_per_phys = + unsigned int logs_per_phys = bdev_physical_block_size(bd) / bdev_logical_block_size(bd); return ilog2(logs_per_phys); From fd48c056a32ed6e7754c7c475490f3bed54ed378 Mon Sep 17 00:00:00 2001 From: Chaitanya Kulkarni Date: Sat, 27 Feb 2021 21:56:26 -0800 Subject: [PATCH 084/412] scsi: target: pscsi: Fix warning in pscsi_complete_cmd() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This fixes a compilation warning in pscsi_complete_cmd(): drivers/target/target_core_pscsi.c: In function ‘pscsi_complete_cmd’: drivers/target/target_core_pscsi.c:624:5: warning: suggest braces around empty body in an ‘if’ statement [-Wempty-body] ; /* XXX: TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE */ Link: https://lore.kernel.org/r/20210228055645.22253-5-chaitanya.kulkarni@wdc.com Reviewed-by: Mike Christie Reviewed-by: Johannes Thumshirn Signed-off-by: Chaitanya Kulkarni Signed-off-by: Martin K. Petersen --- drivers/target/target_core_pscsi.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/target/target_core_pscsi.c b/drivers/target/target_core_pscsi.c index 3cbc074992bc..689e503e3301 100644 --- a/drivers/target/target_core_pscsi.c +++ b/drivers/target/target_core_pscsi.c @@ -620,8 +620,9 @@ static void pscsi_complete_cmd(struct se_cmd *cmd, u8 scsi_status, unsigned char *buf; buf = transport_kmap_data_sg(cmd); - if (!buf) + if (!buf) { ; /* XXX: TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE */ + } if (cdb[0] == MODE_SENSE_10) { if (!(buf[3] & 0x80)) From 2c958a8c1f15f56a528769f4e1402e33e7a4b90e Mon Sep 17 00:00:00 2001 From: Chaitanya Kulkarni Date: Sat, 27 Feb 2021 21:56:28 -0800 Subject: [PATCH 085/412] scsi: target: pscsi: Remove unused macro ISPRINT Remove unused macro to fix the following compilation warning: drivers/target//target_core_pscsi.c:37: warning: macro "ISPRINT" is not used [-Wunused-macros] #define ISPRINT(a) ((a >= ' ') && (a <= '~')) Link: https://lore.kernel.org/r/20210228055645.22253-7-chaitanya.kulkarni@wdc.com Reviewed-by: Mike Christie Reviewed-by: Johannes Thumshirn Signed-off-by: Chaitanya Kulkarni Signed-off-by: Martin K. Petersen --- drivers/target/target_core_pscsi.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/drivers/target/target_core_pscsi.c b/drivers/target/target_core_pscsi.c index 689e503e3301..7b1035e08419 100644 --- a/drivers/target/target_core_pscsi.c +++ b/drivers/target/target_core_pscsi.c @@ -34,8 +34,6 @@ #include "target_core_internal.h" #include "target_core_pscsi.h" -#define ISPRINT(a) ((a >= ' ') && (a <= '~')) - static inline struct pscsi_dev_virt *PSCSI_DEV(struct se_device *dev) { return container_of(dev, struct pscsi_dev_virt, dev); From 5cfb5b0258a08cc76822343af648604713d7d995 Mon Sep 17 00:00:00 2001 From: Chaitanya Kulkarni Date: Sat, 27 Feb 2021 21:56:27 -0800 Subject: [PATCH 086/412] scsi: target: core: Get rid of warning in compare_and_write_do_cmp() Rename function local variable i to sg_cnt so we can get rid of the shadow variable compilation warning: unsigned int i; ^ int i; ^ Link: https://lore.kernel.org/r/20210228055645.22253-6-chaitanya.kulkarni@wdc.com Reviewed-by: Mike Christie Reviewed-by: Johannes Thumshirn Signed-off-by: Chaitanya Kulkarni Signed-off-by: Martin K. Petersen --- drivers/target/target_core_sbc.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/target/target_core_sbc.c b/drivers/target/target_core_sbc.c index f7c527a826fd..7b07e557dc8d 100644 --- a/drivers/target/target_core_sbc.c +++ b/drivers/target/target_core_sbc.c @@ -448,7 +448,7 @@ compare_and_write_do_cmp(struct scatterlist *read_sgl, unsigned int read_nents, sense_reason_t ret; unsigned int offset; size_t rc; - int i; + int sg_cnt; buf = kzalloc(cmp_len, GFP_KERNEL); if (!buf) { @@ -467,7 +467,7 @@ compare_and_write_do_cmp(struct scatterlist *read_sgl, unsigned int read_nents, */ offset = 0; ret = TCM_NO_SENSE; - for_each_sg(read_sgl, sg, read_nents, i) { + for_each_sg(read_sgl, sg, read_nents, sg_cnt) { unsigned int len = min(sg->length, cmp_len); unsigned char *addr = kmap_atomic(sg_page(sg)); From c3a27351d6db8e4e6729feb83124c09c9958a983 Mon Sep 17 00:00:00 2001 From: Chaitanya Kulkarni Date: Sat, 27 Feb 2021 21:56:29 -0800 Subject: [PATCH 087/412] scsi: target: core: Remove unused macros NONE and ISPRINT Remove the unuseds macro to fix the following compilation warnings: drivers/target//target_core_stat.c:34: warning: macro "NONE" is not used [-Wunused-macros] #define NONE "None" drivers/target//iscsi/iscsi_target_stat.c:36: warning: macro "ISPRINT" is not used [-Wunused-macros] #define ISPRINT(a) ((a >= ' ') && (a <= '~')) Link: https://lore.kernel.org/r/20210228055645.22253-8-chaitanya.kulkarni@wdc.com Link: https://lore.kernel.org/r/20210228055645.22253-9-chaitanya.kulkarni@wdc.com Reviewed-by: Mike Christie Reviewed-by: Johannes Thumshirn Signed-off-by: Chaitanya Kulkarni Signed-off-by: Martin K. Petersen --- drivers/target/target_core_stat.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/drivers/target/target_core_stat.c b/drivers/target/target_core_stat.c index 237309db4b33..62d15bcc3d93 100644 --- a/drivers/target/target_core_stat.c +++ b/drivers/target/target_core_stat.c @@ -31,9 +31,6 @@ #define INITIAL_JIFFIES ((unsigned long)(unsigned int) (-300*HZ)) #endif -#define NONE "None" -#define ISPRINT(a) ((a >= ' ') && (a <= '~')) - #define SCSI_LU_INDEX 1 #define LU_COUNT 1 From fdc1339a421dca3ec2571f20a85214b5e37197f5 Mon Sep 17 00:00:00 2001 From: Chaitanya Kulkarni Date: Sat, 27 Feb 2021 21:56:31 -0800 Subject: [PATCH 088/412] scsi: target: iscsi: Remove unused macro ISCSI_INST_LAST_FAILURE_TYPE Remove unused macro to fix the following compilation warning: drivers/target//iscsi/iscsi_target_stat.c:31: warning: macro "ISCSI_INST_LAST_FAILURE_TYPE" is not used [-Wunused-macros] #define ISCSI_INST_LAST_FAILURE_TYPE 0 Link: https://lore.kernel.org/r/20210228055645.22253-10-chaitanya.kulkarni@wdc.com Reviewed-by: Mike Christie Reviewed-by: Johannes Thumshirn Signed-off-by: Chaitanya Kulkarni Signed-off-by: Martin K. Petersen --- drivers/target/iscsi/iscsi_target_stat.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/target/iscsi/iscsi_target_stat.c b/drivers/target/iscsi/iscsi_target_stat.c index 35e75a3569c9..cce3a827059e 100644 --- a/drivers/target/iscsi/iscsi_target_stat.c +++ b/drivers/target/iscsi/iscsi_target_stat.c @@ -28,7 +28,6 @@ /* Instance Attributes Table */ #define ISCSI_INST_NUM_NODES 1 #define ISCSI_INST_DESCR "Storage Engine Target" -#define ISCSI_INST_LAST_FAILURE_TYPE 0 #define ISCSI_DISCONTINUITY_TIME 0 #define ISCSI_NODE_INDEX 1 From 91ce84a3d789667cb0e967d2bb1272ffd114ea2f Mon Sep 17 00:00:00 2001 From: Chaitanya Kulkarni Date: Sat, 27 Feb 2021 21:56:32 -0800 Subject: [PATCH 089/412] scsi: target: iscsi: Remove unused macro TEXT_LEN Remove unused macro to fix the following compilation warning: drivers/target//iscsi/iscsi_target_nego.c:31: warning: macro "TEXT_LEN" is not used [-Wunused-macros] #define TEXT_LEN 4096 Link: https://lore.kernel.org/r/20210228055645.22253-11-chaitanya.kulkarni@wdc.com Reviewed-by: Mike Christie Reviewed-by: Johannes Thumshirn Signed-off-by: Chaitanya Kulkarni Signed-off-by: Martin K. Petersen --- drivers/target/iscsi/iscsi_target_nego.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/target/iscsi/iscsi_target_nego.c b/drivers/target/iscsi/iscsi_target_nego.c index 8b40f10976ff..151e2949bb75 100644 --- a/drivers/target/iscsi/iscsi_target_nego.c +++ b/drivers/target/iscsi/iscsi_target_nego.c @@ -28,7 +28,6 @@ #include "iscsi_target_auth.h" #define MAX_LOGIN_PDUS 7 -#define TEXT_LEN 4096 void convert_null_to_semi(char *buf, int len) { From c4d81e7c53e7c51b903f20a197399fe30fcc3529 Mon Sep 17 00:00:00 2001 From: Chaitanya Kulkarni Date: Sat, 27 Feb 2021 21:56:33 -0800 Subject: [PATCH 090/412] scsi: target: iscsi: Remove unused macro PRINT_BUF Remove unused macro to fix the following compilation warning: drivers/target//iscsi/iscsi_target_util.c:31: warning: macro "PRINT_BUFF" is not used [-Wunused-macros] #define PRINT_BUFF(buff, len) \ Link: https://lore.kernel.org/r/20210228055645.22253-12-chaitanya.kulkarni@wdc.com Reviewed-by: Mike Christie Reviewed-by: Johannes Thumshirn Signed-off-by: Chaitanya Kulkarni Signed-off-by: Martin K. Petersen --- drivers/target/iscsi/iscsi_target_util.c | 17 ----------------- 1 file changed, 17 deletions(-) diff --git a/drivers/target/iscsi/iscsi_target_util.c b/drivers/target/iscsi/iscsi_target_util.c index 9468b017b4a7..6dd5810e2af1 100644 --- a/drivers/target/iscsi/iscsi_target_util.c +++ b/drivers/target/iscsi/iscsi_target_util.c @@ -28,23 +28,6 @@ #include "iscsi_target_util.h" #include "iscsi_target.h" -#define PRINT_BUFF(buff, len) \ -{ \ - int zzz; \ - \ - pr_debug("%d:\n", __LINE__); \ - for (zzz = 0; zzz < len; zzz++) { \ - if (zzz % 16 == 0) { \ - if (zzz) \ - pr_debug("\n"); \ - pr_debug("%4i: ", zzz); \ - } \ - pr_debug("%02x ", (unsigned char) (buff)[zzz]); \ - } \ - if ((len + 1) % 16) \ - pr_debug("\n"); \ -} - extern struct list_head g_tiqn_list; extern spinlock_t tiqn_lock; From c22659fbb98b24538b1a049fb5504f5a756d09a0 Mon Sep 17 00:00:00 2001 From: Chaitanya Kulkarni Date: Sat, 27 Feb 2021 21:56:34 -0800 Subject: [PATCH 091/412] scsi: target: iscsi: Initialize arrays at declaration time Avoids calling memset(). Link: https://lore.kernel.org/r/20210228055645.22253-13-chaitanya.kulkarni@wdc.com Reviewed-by: Mike Christie Reviewed-by: Johannes Thumshirn Signed-off-by: Chaitanya Kulkarni Signed-off-by: Martin K. Petersen --- drivers/target/iscsi/iscsi_target_configfs.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/target/iscsi/iscsi_target_configfs.c b/drivers/target/iscsi/iscsi_target_configfs.c index 0fa1d57b26fa..f4a24fa5058e 100644 --- a/drivers/target/iscsi/iscsi_target_configfs.c +++ b/drivers/target/iscsi/iscsi_target_configfs.c @@ -161,14 +161,13 @@ static struct se_tpg_np *lio_target_call_addnptotpg( char *str, *str2, *ip_str, *port_str; struct sockaddr_storage sockaddr = { }; int ret; - char buf[MAX_PORTAL_LEN + 1]; + char buf[MAX_PORTAL_LEN + 1] = { }; if (strlen(name) > MAX_PORTAL_LEN) { pr_err("strlen(name): %d exceeds MAX_PORTAL_LEN: %d\n", (int)strlen(name), MAX_PORTAL_LEN); return ERR_PTR(-EOVERFLOW); } - memset(buf, 0, MAX_PORTAL_LEN + 1); snprintf(buf, MAX_PORTAL_LEN + 1, "%s", name); str = strstr(buf, "["); From 2d4e2daf4fed37c267893466753e0a46bcac5fb1 Mon Sep 17 00:00:00 2001 From: Chaitanya Kulkarni Date: Sat, 27 Feb 2021 21:56:35 -0800 Subject: [PATCH 092/412] scsi: target: configfs: Initialize arrays at declaration time Avoids calling memset(). Link: https://lore.kernel.org/r/20210228055645.22253-14-chaitanya.kulkarni@wdc.com Link: https://lore.kernel.org/r/20210228055645.22253-15-chaitanya.kulkarni@wdc.com Link: https://lore.kernel.org/r/20210228055645.22253-16-chaitanya.kulkarni@wdc.com Link: https://lore.kernel.org/r/20210228055645.22253-17-chaitanya.kulkarni@wdc.com Link: https://lore.kernel.org/r/20210228055645.22253-18-chaitanya.kulkarni@wdc.com Link: https://lore.kernel.org/r/20210228055645.22253-19-chaitanya.kulkarni@wdc.com Link: https://lore.kernel.org/r/20210228055645.22253-20-chaitanya.kulkarni@wdc.com Reviewed-by: Mike Christie Reviewed-by: Johannes Thumshirn Signed-off-by: Chaitanya Kulkarni Signed-off-by: Martin K. Petersen --- drivers/target/target_core_configfs.c | 25 +++++++------------------ 1 file changed, 7 insertions(+), 18 deletions(-) diff --git a/drivers/target/target_core_configfs.c b/drivers/target/target_core_configfs.c index f04352285155..9cb1ca8421c8 100644 --- a/drivers/target/target_core_configfs.c +++ b/drivers/target/target_core_configfs.c @@ -1494,7 +1494,7 @@ static ssize_t target_wwn_vpd_unit_serial_store(struct config_item *item, { struct t10_wwn *t10_wwn = to_t10_wwn(item); struct se_device *dev = t10_wwn->t10_dev; - unsigned char buf[INQUIRY_VPD_SERIAL_LEN]; + unsigned char buf[INQUIRY_VPD_SERIAL_LEN] = { }; /* * If Linux/SCSI subsystem_api_t plugin got a VPD Unit Serial @@ -1536,7 +1536,6 @@ static ssize_t target_wwn_vpd_unit_serial_store(struct config_item *item, * Also, strip any newline added from the userspace * echo $UUID > $TARGET/$HBA/$STORAGE_OBJECT/wwn/vpd_unit_serial */ - memset(buf, 0, INQUIRY_VPD_SERIAL_LEN); snprintf(buf, INQUIRY_VPD_SERIAL_LEN, "%s", page); snprintf(dev->t10_wwn.unit_serial, INQUIRY_VPD_SERIAL_LEN, "%s", strstrip(buf)); @@ -1556,11 +1555,9 @@ static ssize_t target_wwn_vpd_protocol_identifier_show(struct config_item *item, { struct t10_wwn *t10_wwn = to_t10_wwn(item); struct t10_vpd *vpd; - unsigned char buf[VPD_TMP_BUF_SIZE]; + unsigned char buf[VPD_TMP_BUF_SIZE] = { }; ssize_t len = 0; - memset(buf, 0, VPD_TMP_BUF_SIZE); - spin_lock(&t10_wwn->t10_vpd_lock); list_for_each_entry(vpd, &t10_wwn->t10_vpd_list, vpd_list) { if (!vpd->protocol_identifier_set) @@ -1663,9 +1660,7 @@ static ssize_t target_core_dev_pr_show_spc3_res(struct se_device *dev, { struct se_node_acl *se_nacl; struct t10_pr_registration *pr_reg; - char i_buf[PR_REG_ISID_ID_LEN]; - - memset(i_buf, 0, PR_REG_ISID_ID_LEN); + char i_buf[PR_REG_ISID_ID_LEN] = { }; pr_reg = dev->dev_pr_res_holder; if (!pr_reg) @@ -2286,7 +2281,7 @@ static ssize_t target_dev_alua_lu_gp_store(struct config_item *item, struct se_hba *hba = dev->se_hba; struct t10_alua_lu_gp *lu_gp = NULL, *lu_gp_new = NULL; struct t10_alua_lu_gp_member *lu_gp_mem; - unsigned char buf[LU_GROUP_NAME_BUF]; + unsigned char buf[LU_GROUP_NAME_BUF] = { }; int move = 0; lu_gp_mem = dev->dev_alua_lu_gp_mem; @@ -2297,7 +2292,6 @@ static ssize_t target_dev_alua_lu_gp_store(struct config_item *item, pr_err("ALUA LU Group Alias too large!\n"); return -EINVAL; } - memset(buf, 0, LU_GROUP_NAME_BUF); memcpy(buf, page, count); /* * Any ALUA logical unit alias besides "NULL" means we will be @@ -2615,9 +2609,7 @@ static ssize_t target_lu_gp_members_show(struct config_item *item, char *page) struct se_hba *hba; struct t10_alua_lu_gp_member *lu_gp_mem; ssize_t len = 0, cur_len; - unsigned char buf[LU_GROUP_NAME_BUF]; - - memset(buf, 0, LU_GROUP_NAME_BUF); + unsigned char buf[LU_GROUP_NAME_BUF] = { }; spin_lock(&lu_gp->lu_gp_lock); list_for_each_entry(lu_gp_mem, &lu_gp->lu_gp_mem_list, lu_gp_mem_list) { @@ -3020,9 +3012,7 @@ static ssize_t target_tg_pt_gp_members_show(struct config_item *item, struct t10_alua_tg_pt_gp *tg_pt_gp = to_tg_pt_gp(item); struct se_lun *lun; ssize_t len = 0, cur_len; - unsigned char buf[TG_PT_GROUP_NAME_BUF]; - - memset(buf, 0, TG_PT_GROUP_NAME_BUF); + unsigned char buf[TG_PT_GROUP_NAME_BUF] = { }; spin_lock(&tg_pt_gp->tg_pt_gp_lock); list_for_each_entry(lun, &tg_pt_gp->tg_pt_gp_lun_list, @@ -3409,11 +3399,10 @@ static struct config_group *target_core_call_addhbatotarget( { char *se_plugin_str, *str, *str2; struct se_hba *hba; - char buf[TARGET_CORE_NAME_MAX_LEN]; + char buf[TARGET_CORE_NAME_MAX_LEN] = { }; unsigned long plugin_dep_id = 0; int ret; - memset(buf, 0, TARGET_CORE_NAME_MAX_LEN); if (strlen(name) >= TARGET_CORE_NAME_MAX_LEN) { pr_err("Passed *name strlen(): %d exceeds" " TARGET_CORE_NAME_MAX_LEN: %d\n", (int)strlen(name), From 4db6dfe62c5f76ce9eef28967c2e2000efde10d5 Mon Sep 17 00:00:00 2001 From: Chaitanya Kulkarni Date: Sat, 27 Feb 2021 21:56:42 -0800 Subject: [PATCH 093/412] scsi: target: core: pr: Initialize arrays at declaration time Avoids calling memset(). Link: https://lore.kernel.org/r/20210228055645.22253-21-chaitanya.kulkarni@wdc.com Link: https://lore.kernel.org/r/20210228055645.22253-22-chaitanya.kulkarni@wdc.com Link: https://lore.kernel.org/r/20210228055645.22253-23-chaitanya.kulkarni@wdc.com Reviewed-by: Mike Christie Reviewed-by: Johannes Thumshirn Signed-off-by: Chaitanya Kulkarni Signed-off-by: Martin K. Petersen --- drivers/target/target_core_pr.c | 36 ++++++++++++--------------------- 1 file changed, 13 insertions(+), 23 deletions(-) diff --git a/drivers/target/target_core_pr.c b/drivers/target/target_core_pr.c index d4cc43afe05b..d61dc166bc5f 100644 --- a/drivers/target/target_core_pr.c +++ b/drivers/target/target_core_pr.c @@ -896,9 +896,8 @@ static void core_scsi3_aptpl_reserve( struct se_node_acl *node_acl, struct t10_pr_registration *pr_reg) { - char i_buf[PR_REG_ISID_ID_LEN]; + char i_buf[PR_REG_ISID_ID_LEN] = { }; - memset(i_buf, 0, PR_REG_ISID_ID_LEN); core_pr_dump_initiator_port(pr_reg, i_buf, PR_REG_ISID_ID_LEN); spin_lock(&dev->dev_reservation_lock); @@ -928,12 +927,10 @@ static int __core_scsi3_check_aptpl_registration( { struct t10_pr_registration *pr_reg, *pr_reg_tmp; struct t10_reservation *pr_tmpl = &dev->t10_pr; - unsigned char i_port[PR_APTPL_MAX_IPORT_LEN]; - unsigned char t_port[PR_APTPL_MAX_TPORT_LEN]; + unsigned char i_port[PR_APTPL_MAX_IPORT_LEN] = { }; + unsigned char t_port[PR_APTPL_MAX_TPORT_LEN] = { }; u16 tpgt; - memset(i_port, 0, PR_APTPL_MAX_IPORT_LEN); - memset(t_port, 0, PR_APTPL_MAX_TPORT_LEN); /* * Copy Initiator Port information from struct se_node_acl */ @@ -1023,9 +1020,8 @@ static void __core_scsi3_dump_registration( enum register_type register_type) { struct se_portal_group *se_tpg = nacl->se_tpg; - char i_buf[PR_REG_ISID_ID_LEN]; + char i_buf[PR_REG_ISID_ID_LEN] = { }; - memset(&i_buf[0], 0, PR_REG_ISID_ID_LEN); core_pr_dump_initiator_port(pr_reg, i_buf, PR_REG_ISID_ID_LEN); pr_debug("SPC-3 PR [%s] Service Action: REGISTER%s Initiator" @@ -1204,10 +1200,10 @@ static struct t10_pr_registration *core_scsi3_locate_pr_reg( struct se_session *sess) { struct se_portal_group *tpg = nacl->se_tpg; - unsigned char buf[PR_REG_ISID_LEN], *isid_ptr = NULL; + unsigned char buf[PR_REG_ISID_LEN] = { }; + unsigned char *isid_ptr = NULL; if (tpg->se_tpg_tfo->sess_get_initiator_sid != NULL) { - memset(&buf[0], 0, PR_REG_ISID_LEN); tpg->se_tpg_tfo->sess_get_initiator_sid(sess, &buf[0], PR_REG_ISID_LEN); isid_ptr = &buf[0]; @@ -1285,11 +1281,10 @@ static void __core_scsi3_free_registration( struct t10_reservation *pr_tmpl = &dev->t10_pr; struct se_node_acl *nacl = pr_reg->pr_reg_nacl; struct se_dev_entry *deve; - char i_buf[PR_REG_ISID_ID_LEN]; + char i_buf[PR_REG_ISID_ID_LEN] = { }; lockdep_assert_held(&pr_tmpl->registration_lock); - memset(i_buf, 0, PR_REG_ISID_ID_LEN); core_pr_dump_initiator_port(pr_reg, i_buf, PR_REG_ISID_ID_LEN); if (!list_empty(&pr_reg->pr_reg_list)) @@ -2059,7 +2054,8 @@ core_scsi3_emulate_pro_register(struct se_cmd *cmd, u64 res_key, u64 sa_res_key, struct se_portal_group *se_tpg; struct t10_pr_registration *pr_reg, *pr_reg_p, *pr_reg_tmp; struct t10_reservation *pr_tmpl = &dev->t10_pr; - unsigned char isid_buf[PR_REG_ISID_LEN], *isid_ptr = NULL; + unsigned char isid_buf[PR_REG_ISID_LEN] = { }; + unsigned char *isid_ptr = NULL; sense_reason_t ret = TCM_NO_SENSE; int pr_holder = 0, type; @@ -2070,7 +2066,6 @@ core_scsi3_emulate_pro_register(struct se_cmd *cmd, u64 res_key, u64 sa_res_key, se_tpg = se_sess->se_tpg; if (se_tpg->se_tpg_tfo->sess_get_initiator_sid) { - memset(&isid_buf[0], 0, PR_REG_ISID_LEN); se_tpg->se_tpg_tfo->sess_get_initiator_sid(se_sess, &isid_buf[0], PR_REG_ISID_LEN); isid_ptr = &isid_buf[0]; @@ -2282,11 +2277,9 @@ core_scsi3_pro_reserve(struct se_cmd *cmd, int type, int scope, u64 res_key) struct se_lun *se_lun = cmd->se_lun; struct t10_pr_registration *pr_reg, *pr_res_holder; struct t10_reservation *pr_tmpl = &dev->t10_pr; - char i_buf[PR_REG_ISID_ID_LEN]; + char i_buf[PR_REG_ISID_ID_LEN] = { }; sense_reason_t ret; - memset(i_buf, 0, PR_REG_ISID_ID_LEN); - if (!se_sess || !se_lun) { pr_err("SPC-3 PR: se_sess || struct se_lun is NULL!\n"); return TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE; @@ -2457,12 +2450,11 @@ static void __core_scsi3_complete_pro_release( int unreg) { const struct target_core_fabric_ops *tfo = se_nacl->se_tpg->se_tpg_tfo; - char i_buf[PR_REG_ISID_ID_LEN]; + char i_buf[PR_REG_ISID_ID_LEN] = { }; int pr_res_type = 0, pr_res_scope = 0; lockdep_assert_held(&dev->dev_reservation_lock); - memset(i_buf, 0, PR_REG_ISID_ID_LEN); core_pr_dump_initiator_port(pr_reg, i_buf, PR_REG_ISID_ID_LEN); /* * Go ahead and release the current PR reservation holder. @@ -2768,11 +2760,10 @@ static void __core_scsi3_complete_pro_preempt( { struct se_node_acl *nacl = pr_reg->pr_reg_nacl; const struct target_core_fabric_ops *tfo = nacl->se_tpg->se_tpg_tfo; - char i_buf[PR_REG_ISID_ID_LEN]; + char i_buf[PR_REG_ISID_ID_LEN] = { }; lockdep_assert_held(&dev->dev_reservation_lock); - memset(i_buf, 0, PR_REG_ISID_ID_LEN); core_pr_dump_initiator_port(pr_reg, i_buf, PR_REG_ISID_ID_LEN); /* * Do an implicit RELEASE of the existing reservation. @@ -3158,7 +3149,7 @@ core_scsi3_emulate_pro_register_and_move(struct se_cmd *cmd, u64 res_key, struct t10_reservation *pr_tmpl = &dev->t10_pr; unsigned char *buf; const unsigned char *initiator_str; - char *iport_ptr = NULL, i_buf[PR_REG_ISID_ID_LEN]; + char *iport_ptr = NULL, i_buf[PR_REG_ISID_ID_LEN] = { }; u32 tid_len, tmp_tid_len; int new_reg = 0, type, scope, matching_iname; sense_reason_t ret; @@ -3170,7 +3161,6 @@ core_scsi3_emulate_pro_register_and_move(struct se_cmd *cmd, u64 res_key, return TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE; } - memset(i_buf, 0, PR_REG_ISID_ID_LEN); se_tpg = se_sess->se_tpg; tf_ops = se_tpg->se_tpg_tfo; /* From 4524a0b159028c2910dfe40469ed6512c455df61 Mon Sep 17 00:00:00 2001 From: Chaitanya Kulkarni Date: Sat, 27 Feb 2021 21:56:45 -0800 Subject: [PATCH 094/412] scsi: target: core: file: Don't duplicate memset(0xff) The function fd_do_prot_fill() is called from two callers fd_do_prot_unmap() and fd_format_prot(). Both callers initialize the passed buffer to 0xff with memset(). Move the memset() call to fd_do_prot_fill() to avoid duplication. Link: https://lore.kernel.org/r/20210228055645.22253-24-chaitanya.kulkarni@wdc.com Reviewed-by: Mike Christie Reviewed-by: Johannes Thumshirn Signed-off-by: Chaitanya Kulkarni Signed-off-by: Martin K. Petersen --- drivers/target/target_core_file.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/target/target_core_file.c b/drivers/target/target_core_file.c index 5a66854def95..ef4a8e189fba 100644 --- a/drivers/target/target_core_file.c +++ b/drivers/target/target_core_file.c @@ -498,6 +498,7 @@ fd_do_prot_fill(struct se_device *se_dev, sector_t lba, sector_t nolb, prot_length = nolb * se_dev->prot_length; + memset(buf, 0xff, bufsize); for (prot = 0; prot < prot_length;) { sector_t len = min_t(sector_t, bufsize, prot_length - prot); ssize_t ret = kernel_write(prot_fd, buf, len, &pos); @@ -523,7 +524,6 @@ fd_do_prot_unmap(struct se_cmd *cmd, sector_t lba, sector_t nolb) pr_err("Unable to allocate FILEIO prot buf\n"); return -ENOMEM; } - memset(buf, 0xff, PAGE_SIZE); rc = fd_do_prot_fill(cmd->se_dev, lba, nolb, buf, PAGE_SIZE); @@ -882,7 +882,6 @@ static int fd_format_prot(struct se_device *dev) (unsigned long long)(dev->transport->get_blocks(dev) + 1) * dev->prot_length); - memset(buf, 0xff, unit_size); ret = fd_do_prot_fill(dev, 0, dev->transport->get_blocks(dev) + 1, buf, unit_size); vfree(buf); From bbb2c0374552d429d55ee5e28cac4f9f112f6a80 Mon Sep 17 00:00:00 2001 From: Lee Jones Date: Wed, 3 Mar 2021 14:46:02 +0000 Subject: [PATCH 095/412] scsi: megaraid_mm: Fix incorrect function name in header Fixes the following W=1 kernel build warning(s): drivers/scsi/megaraid/megaraid_mm.c:505: warning: expecting prototype for mraid_mm_attch_buf(). Prototype was for mraid_mm_attach_buf() instead Link: https://lore.kernel.org/r/20210303144631.3175331-2-lee.jones@linaro.org Cc: Kashyap Desai Cc: Sumit Saxena Cc: Shivasharan S Cc: "James E.J. Bottomley" Cc: "Martin K. Petersen" Cc: megaraidlinux.pdl@broadcom.com Cc: linux-scsi@vger.kernel.org Signed-off-by: Lee Jones Signed-off-by: Martin K. Petersen --- drivers/scsi/megaraid/megaraid_mm.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/scsi/megaraid/megaraid_mm.c b/drivers/scsi/megaraid/megaraid_mm.c index 8df53446641a..abf7b401f5b9 100644 --- a/drivers/scsi/megaraid/megaraid_mm.c +++ b/drivers/scsi/megaraid/megaraid_mm.c @@ -490,7 +490,7 @@ mimd_to_kioc(mimd_t __user *umimd, mraid_mmadp_t *adp, uioc_t *kioc) } /** - * mraid_mm_attch_buf - Attach a free dma buffer for required size + * mraid_mm_attach_buf - Attach a free dma buffer for required size * @adp : Adapter softstate * @kioc : kioc that the buffer needs to be attached to * @xferlen : required length for buffer From 616f6d8d9e16e9e1c54b71b796aceecdc4dc9bc4 Mon Sep 17 00:00:00 2001 From: Lee Jones Date: Wed, 3 Mar 2021 14:46:03 +0000 Subject: [PATCH 096/412] scsi: megaraid_sas: Fix a bunch of misnamed functions in their headers Fixes the following W=1 kernel build warning(s): drivers/scsi/megaraid/megaraid_sas_base.c:483: warning: expecting prototype for megasas_clear_interrupt_xscale(). Prototype was for megasas_clear_intr_xscale() instead drivers/scsi/megaraid/megaraid_sas_base.c:666: warning: expecting prototype for megasas_clear_interrupt_ppc(). Prototype was for megasas_clear_intr_ppc() instead drivers/scsi/megaraid/megaraid_sas_base.c:795: warning: expecting prototype for megasas_clear_interrupt_skinny(). Prototype was for megasas_clear_intr_skinny() instead drivers/scsi/megaraid/megaraid_sas_base.c:943: warning: expecting prototype for megasas_clear_interrupt_gen2(). Prototype was for megasas_clear_intr_gen2() instead drivers/scsi/megaraid/megaraid_sas_base.c:4902: warning: expecting prototype for opcode(). Prototype was for megasas_host_device_list_query() instead drivers/scsi/megaraid/megaraid_sas_base.c:5173: warning: expecting prototype for megasas_get_controller_info(). Prototype was for megasas_get_ctrl_info() instead Link: https://lore.kernel.org/r/20210303144631.3175331-3-lee.jones@linaro.org Cc: Kashyap Desai Cc: Sumit Saxena Cc: Shivasharan S Cc: "James E.J. Bottomley" Cc: "Martin K. Petersen" Cc: megaraidlinux.pdl@broadcom.com Cc: linux-scsi@vger.kernel.org Signed-off-by: Lee Jones Signed-off-by: Martin K. Petersen --- drivers/scsi/megaraid/megaraid_sas_base.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/drivers/scsi/megaraid/megaraid_sas_base.c b/drivers/scsi/megaraid/megaraid_sas_base.c index 25673d0ee524..4d4e9dbe5193 100644 --- a/drivers/scsi/megaraid/megaraid_sas_base.c +++ b/drivers/scsi/megaraid/megaraid_sas_base.c @@ -485,7 +485,7 @@ megasas_read_fw_status_reg_xscale(struct megasas_instance *instance) return readl(&instance->reg_set->outbound_msg_0); } /** - * megasas_clear_interrupt_xscale - Check & clear interrupt + * megasas_clear_intr_xscale - Check & clear interrupt * @instance: Adapter soft state */ static int @@ -668,7 +668,7 @@ megasas_read_fw_status_reg_ppc(struct megasas_instance *instance) } /** - * megasas_clear_interrupt_ppc - Check & clear interrupt + * megasas_clear_intr_ppc - Check & clear interrupt * @instance: Adapter soft state */ static int @@ -797,7 +797,7 @@ megasas_read_fw_status_reg_skinny(struct megasas_instance *instance) } /** - * megasas_clear_interrupt_skinny - Check & clear interrupt + * megasas_clear_intr_skinny - Check & clear interrupt * @instance: Adapter soft state */ static int @@ -945,7 +945,7 @@ megasas_read_fw_status_reg_gen2(struct megasas_instance *instance) } /** - * megasas_clear_interrupt_gen2 - Check & clear interrupt + * megasas_clear_intr_gen2 - Check & clear interrupt * @instance: Adapter soft state */ static int @@ -4918,6 +4918,7 @@ megasas_ld_list_query(struct megasas_instance *instance, u8 query_type) } /** + * megasas_host_device_list_query * dcmd.opcode - MR_DCMD_CTRL_DEVICE_LIST_GET * dcmd.mbox - reserved * dcmd.sge IN - ptr to return MR_HOST_DEVICE_LIST structure @@ -5195,7 +5196,7 @@ void megasas_get_snapdump_properties(struct megasas_instance *instance) } /** - * megasas_get_controller_info - Returns FW's controller structure + * megasas_get_ctrl_info - Returns FW's controller structure * @instance: Adapter soft state * * Issues an internal command (DCMD) to get the FW's controller structure. From 276f9aa2530a32dd7833e277f492098bc7ff7d06 Mon Sep 17 00:00:00 2001 From: Lee Jones Date: Wed, 3 Mar 2021 14:46:04 +0000 Subject: [PATCH 097/412] scsi: fcoe: Fix function name fcoe_set_vport_symbolic_name() in description Fixes the following W=1 kernel build warning(s): drivers/scsi/fcoe/fcoe.c:2782: warning: expecting prototype for fcoe_vport_set_symbolic_name(). Prototype was for fcoe_set_vport_symbolic_name() instead Link: https://lore.kernel.org/r/20210303144631.3175331-4-lee.jones@linaro.org Cc: Hannes Reinecke Cc: "James E.J. Bottomley" Cc: "Martin K. Petersen" Cc: linux-scsi@vger.kernel.org Signed-off-by: Lee Jones Signed-off-by: Martin K. Petersen --- drivers/scsi/fcoe/fcoe.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/scsi/fcoe/fcoe.c b/drivers/scsi/fcoe/fcoe.c index 03bf49adaafe..89ec735929c3 100644 --- a/drivers/scsi/fcoe/fcoe.c +++ b/drivers/scsi/fcoe/fcoe.c @@ -2771,7 +2771,7 @@ static int fcoe_vport_disable(struct fc_vport *vport, bool disable) } /** - * fcoe_vport_set_symbolic_name() - append vport string to symbolic name + * fcoe_set_vport_symbolic_name() - append vport string to symbolic name * @vport: fc_vport with a new symbolic name string * * After generating a new symbolic name string, a new RSPN_ID request is From d4f5ae21597bb2b8dc3919434aa78c4dc2dcfb00 Mon Sep 17 00:00:00 2001 From: Lee Jones Date: Wed, 3 Mar 2021 14:46:05 +0000 Subject: [PATCH 098/412] scsi: megaraid_mbox: Fix function name megaraid_queue_command_lck() in description Fixes the following W=1 kernel build warning(s): drivers/scsi/megaraid/megaraid_mbox.c:1438: warning: expecting prototype for megaraid_queue_command(). Prototype was for megaraid_queue_command_lck() instead Link: https://lore.kernel.org/r/20210303144631.3175331-5-lee.jones@linaro.org Cc: Kashyap Desai Cc: Sumit Saxena Cc: Shivasharan S Cc: "James E.J. Bottomley" Cc: "Martin K. Petersen" Cc: Atul Mukker Cc: Sreenivas Bagalkote Cc: Manoj Jose Cc: megaraidlinux@lsi.com Cc: megaraidlinux.pdl@broadcom.com Cc: linux-scsi@vger.kernel.org Signed-off-by: Lee Jones Signed-off-by: Martin K. Petersen --- drivers/scsi/megaraid/megaraid_mbox.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/scsi/megaraid/megaraid_mbox.c b/drivers/scsi/megaraid/megaraid_mbox.c index d57e93872d7b..b1a2d3536add 100644 --- a/drivers/scsi/megaraid/megaraid_mbox.c +++ b/drivers/scsi/megaraid/megaraid_mbox.c @@ -1427,7 +1427,7 @@ mbox_post_cmd(adapter_t *adapter, scb_t *scb) /** - * megaraid_queue_command - generic queue entry point for all LLDs + * megaraid_queue_command_lck - generic queue entry point for all LLDs * @scp : pointer to the scsi command to be executed * @done : callback routine to be called after the cmd has be completed * From dc173575097f7ce71e818c4e6a403aff7c9497b2 Mon Sep 17 00:00:00 2001 From: Lee Jones Date: Wed, 3 Mar 2021 14:46:06 +0000 Subject: [PATCH 099/412] scsi: fcoe: Fix a couple of incorrectly named functions Fixes the following W=1 kernel build warning(s): drivers/scsi/fcoe/fcoe_ctlr.c:1314: warning: expecting prototype for fcoe_ctlr_recv_els(). Prototype was for fcoe_ctlr_recv_clr_vlink() instead drivers/scsi/fcoe/fcoe_ctlr.c:2963: warning: expecting prototype for fcoe_ctlr_vlan_disk_reply(). Prototype was for fcoe_ctlr_vlan_disc_reply() instead Link: https://lore.kernel.org/r/20210303144631.3175331-6-lee.jones@linaro.org Cc: Hannes Reinecke Cc: "James E.J. Bottomley" Cc: "Martin K. Petersen" Cc: linux-scsi@vger.kernel.org Signed-off-by: Lee Jones Signed-off-by: Martin K. Petersen --- drivers/scsi/fcoe/fcoe_ctlr.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/scsi/fcoe/fcoe_ctlr.c b/drivers/scsi/fcoe/fcoe_ctlr.c index 5ea426effa60..1756a0ac6f08 100644 --- a/drivers/scsi/fcoe/fcoe_ctlr.c +++ b/drivers/scsi/fcoe/fcoe_ctlr.c @@ -1302,7 +1302,7 @@ drop: } /** - * fcoe_ctlr_recv_els() - Handle an incoming link reset frame + * fcoe_ctlr_recv_clr_vlink() - Handle an incoming link reset frame * @fip: The FCoE controller that received the frame * @skb: The received FIP packet * @@ -2952,7 +2952,7 @@ static void fcoe_ctlr_vlan_send(struct fcoe_ctlr *fip, } /** - * fcoe_ctlr_vlan_disk_reply() - send FIP VLAN Discovery Notification. + * fcoe_ctlr_vlan_disc_reply() - send FIP VLAN Discovery Notification. * @fip: The FCoE controller * @frport: The newly-parsed FCoE rport from the Discovery Request * From 577c65b07a5508fb413c8e1fcac79af23be31111 Mon Sep 17 00:00:00 2001 From: Lee Jones Date: Wed, 3 Mar 2021 14:46:07 +0000 Subject: [PATCH 100/412] scsi: aic94xx: Fix a couple of misnamed function names Fixes the following W=1 kernel build warning(s): drivers/scsi/aic94xx/aic94xx_hwi.c:910: warning: expecting prototype for ads_rbi_exsi_isr(). Prototype was for asd_rbi_exsi_isr() instead drivers/scsi/aic94xx/aic94xx_hwi.c:1156: warning: expecting prototype for asd_start_timers(). Prototype was for asd_start_scb_timers() instead Link: https://lore.kernel.org/r/20210303144631.3175331-7-lee.jones@linaro.org Cc: "James E.J. Bottomley" Cc: "Martin K. Petersen" Cc: Lee Jones Cc: Luben Tuikov Cc: linux-scsi@vger.kernel.org Signed-off-by: Lee Jones Signed-off-by: Martin K. Petersen --- drivers/scsi/aic94xx/aic94xx_hwi.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/scsi/aic94xx/aic94xx_hwi.c b/drivers/scsi/aic94xx/aic94xx_hwi.c index 9256ab7b2522..3dd110143471 100644 --- a/drivers/scsi/aic94xx/aic94xx_hwi.c +++ b/drivers/scsi/aic94xx/aic94xx_hwi.c @@ -903,7 +903,7 @@ static void asd_dch_sas_isr(struct asd_ha_struct *asd_ha) } /** - * ads_rbi_exsi_isr -- process external system interface interrupt (INITERR) + * asd_rbi_exsi_isr -- process external system interface interrupt (INITERR) * @asd_ha: pointer to host adapter structure */ static void asd_rbi_exsi_isr(struct asd_ha_struct *asd_ha) @@ -1144,7 +1144,7 @@ static void asd_swap_head_scb(struct asd_ha_struct *asd_ha, } /** - * asd_start_timers -- (add and) start timers of SCBs + * asd_start_scb_timers -- (add and) start timers of SCBs * @list: pointer to struct list_head of the scbs * * If an SCB in the @list has no timer function, assign the default From a80218c7c565360e91844c3b9f11a054a8d0a2c6 Mon Sep 17 00:00:00 2001 From: Lee Jones Date: Wed, 3 Mar 2021 14:46:08 +0000 Subject: [PATCH 101/412] scsi: aacraid: Fix a few incorrectly named functions Fixes the following W=1 kernel build warning(s): drivers/scsi/aacraid/aachba.c:796: warning: expecting prototype for aac_probe_container(). Prototype was for aac_probe_container_callback1() instead drivers/scsi/aacraid/aachba.c:850: warning: expecting prototype for InqStrCopy(). Prototype was for inqstrcpy() instead drivers/scsi/aacraid/aachba.c:1814: warning: expecting prototype for Process topology change(). Prototype was for aac_get_safw_ciss_luns() instead Link: https://lore.kernel.org/r/20210303144631.3175331-8-lee.jones@linaro.org Cc: Adaptec OEM Raid Solutions Cc: "James E.J. Bottomley" Cc: "Martin K. Petersen" Cc: "PMC-Sierra, Inc" Cc: linux-scsi@vger.kernel.org Signed-off-by: Lee Jones Signed-off-by: Martin K. Petersen --- drivers/scsi/aacraid/aachba.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/scsi/aacraid/aachba.c b/drivers/scsi/aacraid/aachba.c index 4ca5e13a26a6..8e06604370c4 100644 --- a/drivers/scsi/aacraid/aachba.c +++ b/drivers/scsi/aacraid/aachba.c @@ -786,8 +786,8 @@ static int _aac_probe_container(struct scsi_cmnd * scsicmd, int (*callback)(stru } /** - * aac_probe_container - query a logical volume - * @scsicmd: the scsi command block + * aac_probe_container_callback1 - query a logical volume + * @scsicmd: the scsi command block * * Queries the controller about the given volume. The volume information * is updated in the struct fsa_dev_info structure rather than returned. @@ -838,7 +838,7 @@ struct scsi_inq { }; /** - * InqStrCopy - string merge + * inqstrcpy - string merge * @a: string to copy from * @b: string to copy to * @@ -1804,7 +1804,7 @@ static inline void aac_free_safw_ciss_luns(struct aac_dev *dev) } /** - * aac_get_safw_ciss_luns() Process topology change + * aac_get_safw_ciss_luns() - Process topology change * @dev: aac_dev structure * * Execute a CISS REPORT PHYS LUNS and process the results into From bd1050e13889d65c7b849d4939bbbf2432083c8a Mon Sep 17 00:00:00 2001 From: Lee Jones Date: Wed, 3 Mar 2021 14:46:09 +0000 Subject: [PATCH 102/412] scsi: pm8001: Provide function name and fix a misspelling Fixes the following W=1 kernel build warning(s): drivers/scsi/pm8001/pm8001_init.c:192: warning: expecting prototype for tasklet for 64 msi(). Prototype was for pm8001_tasklet() instead drivers/scsi/pm8001/pm8001_init.c:872: warning: expecting prototype for pm8001_set_phy_settings_ven_117c_12Gb(). Prototype was for pm8001_set_phy_settings_ven_117c_12G() instead Link: https://lore.kernel.org/r/20210303144631.3175331-9-lee.jones@linaro.org Cc: Jack Wang Cc: "James E.J. Bottomley" Cc: "Martin K. Petersen" Cc: Kumar Santhanam Cc: Sangeetha Gnanasekaran Cc: Nikith Ganigarakoppal Cc: linux-scsi@vger.kernel.org Acked-by: Jack Wang Signed-off-by: Lee Jones Signed-off-by: Martin K. Petersen --- drivers/scsi/pm8001/pm8001_init.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/scsi/pm8001/pm8001_init.c b/drivers/scsi/pm8001/pm8001_init.c index bd626ef876da..bbb6b23aa6b1 100644 --- a/drivers/scsi/pm8001/pm8001_init.c +++ b/drivers/scsi/pm8001/pm8001_init.c @@ -184,7 +184,7 @@ static void pm8001_free(struct pm8001_hba_info *pm8001_ha) #ifdef PM8001_USE_TASKLET /** - * tasklet for 64 msi-x interrupt handler + * pm8001_tasklet() - tasklet for 64 msi-x interrupt handler * @opaque: the passed general host adapter struct * Note: pm8001_tasklet is common for pm8001 & pm80xx */ @@ -864,7 +864,7 @@ void pm8001_get_phy_mask(struct pm8001_hba_info *pm8001_ha, int *phymask) } /** - * pm8001_set_phy_settings_ven_117c_12Gb : Configure ATTO 12Gb PHY settings + * pm8001_set_phy_settings_ven_117c_12G() : Configure ATTO 12Gb PHY settings * @pm8001_ha : our adapter */ static From 4c4b8cf5a1090fcaacdad7363be6ab3b758d87ff Mon Sep 17 00:00:00 2001 From: Lee Jones Date: Wed, 3 Mar 2021 14:46:10 +0000 Subject: [PATCH 103/412] scsi: aacraid: Fix incorrect spelling of aac_send_raw_srb() Fixes the following W=1 kernel build warning(s): drivers/scsi/aacraid/commctrl.c:480: warning: expecting prototype for aac_send_raw_scb(). Prototype was for aac_send_raw_srb() instead Link: https://lore.kernel.org/r/20210303144631.3175331-10-lee.jones@linaro.org Cc: Adaptec OEM Raid Solutions Cc: "James E.J. Bottomley" Cc: "Martin K. Petersen" Cc: "PMC-Sierra, Inc" Cc: linux-scsi@vger.kernel.org Signed-off-by: Lee Jones Signed-off-by: Martin K. Petersen --- drivers/scsi/aacraid/commctrl.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/scsi/aacraid/commctrl.c b/drivers/scsi/aacraid/commctrl.c index 1b1da162f5f6..e7cc927ed952 100644 --- a/drivers/scsi/aacraid/commctrl.c +++ b/drivers/scsi/aacraid/commctrl.c @@ -472,7 +472,7 @@ static int check_revision(struct aac_dev *dev, void __user *arg) /** - * aac_send_raw_scb + * aac_send_raw_srb() * @dev: adapter is being processed * @arg: arguments to the send call */ From 52ffc08d9454c0270ec734f2695b76ee0f1cbaf6 Mon Sep 17 00:00:00 2001 From: Lee Jones Date: Wed, 3 Mar 2021 14:46:11 +0000 Subject: [PATCH 104/412] scsi: bnx2fc: Fix typo in bnx2fc_indicate_kcqe() Fixes the following W=1 kernel build warning(s): drivers/scsi/bnx2fc/bnx2fc_hwi.c:1344: warning: expecting prototype for bnx2fc_indicae_kcqe(). Prototype was for bnx2fc_indicate_kcqe() instead Link: https://lore.kernel.org/r/20210303144631.3175331-11-lee.jones@linaro.org Cc: Saurav Kashyap Cc: Javed Hasan Cc: GR-QLogic-Storage-Upstream@marvell.com Cc: "James E.J. Bottomley" Cc: "Martin K. Petersen" Cc: Prakash Gollapudi Cc: linux-scsi@vger.kernel.org Signed-off-by: Lee Jones Signed-off-by: Martin K. Petersen --- drivers/scsi/bnx2fc/bnx2fc_hwi.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/scsi/bnx2fc/bnx2fc_hwi.c b/drivers/scsi/bnx2fc/bnx2fc_hwi.c index b37b0a9ec12d..0103f811cc25 100644 --- a/drivers/scsi/bnx2fc/bnx2fc_hwi.c +++ b/drivers/scsi/bnx2fc/bnx2fc_hwi.c @@ -1331,7 +1331,7 @@ static void bnx2fc_init_failure(struct bnx2fc_hba *hba, u32 err_code) } /** - * bnx2fc_indicae_kcqe - process KCQE + * bnx2fc_indicate_kcqe() - process KCQE * * @context: adapter structure pointer * @kcq: kcqe pointer From 62690c056ac086b2cead9d29a15f5c1bae811aab Mon Sep 17 00:00:00 2001 From: Lee Jones Date: Wed, 3 Mar 2021 14:46:12 +0000 Subject: [PATCH 105/412] scsi: pm8001: Provide function name 'pm8001_I_T_nexus_reset()' in header Fixes the following W=1 kernel build warning(s): drivers/scsi/pm8001/pm8001_sas.c:989: warning: expecting prototype for and hard reset for(). Prototype was for pm8001_I_T_nexus_reset() instead Link: https://lore.kernel.org/r/20210303144631.3175331-12-lee.jones@linaro.org Cc: Jack Wang Cc: "James E.J. Bottomley" Cc: "Martin K. Petersen" Cc: linux-scsi@vger.kernel.org Acked-by: Jack Wang Signed-off-by: Lee Jones Signed-off-by: Martin K. Petersen --- drivers/scsi/pm8001/pm8001_sas.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/scsi/pm8001/pm8001_sas.c b/drivers/scsi/pm8001/pm8001_sas.c index 0cbd25a2ee9f..6f4753d91418 100644 --- a/drivers/scsi/pm8001/pm8001_sas.c +++ b/drivers/scsi/pm8001/pm8001_sas.c @@ -981,6 +981,7 @@ void pm8001_open_reject_retry( } /** + * pm8001_I_T_nexus_reset() * Standard mandates link reset for ATA (type 0) and hard reset for * SSP (type 1) , only for RECOVERY * @dev: the device structure for the device to reset. From ecef0c9e6407ced2237e867ee68bf12f67105b00 Mon Sep 17 00:00:00 2001 From: Lee Jones Date: Wed, 3 Mar 2021 14:46:13 +0000 Subject: [PATCH 106/412] scsi: qla4xxx: Fix formatting issues - missing '-' and '_' Fixes the following W=1 kernel build warning(s): drivers/scsi/qla4xxx/ql4_os.c:631: warning: expecting prototype for qla4xxx_create chap_list(). Prototype was for qla4xxx_create_chap_list() instead drivers/scsi/qla4xxx/ql4_os.c:9643: warning: expecting prototype for gets called if(). Prototype was for qla4xxx_pci_mmio_enabled() instead Link: https://lore.kernel.org/r/20210303144631.3175331-13-lee.jones@linaro.org Cc: Nilesh Javali Cc: Manish Rangankar Cc: GR-QLogic-Storage-Upstream@marvell.com Cc: "James E.J. Bottomley" Cc: "Martin K. Petersen" Cc: linux-scsi@vger.kernel.org Acked-by: Nilesh Javali Signed-off-by: Lee Jones Signed-off-by: Martin K. Petersen --- drivers/scsi/qla4xxx/ql4_os.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/scsi/qla4xxx/ql4_os.c b/drivers/scsi/qla4xxx/ql4_os.c index 178506ac4885..867730ed21f7 100644 --- a/drivers/scsi/qla4xxx/ql4_os.c +++ b/drivers/scsi/qla4xxx/ql4_os.c @@ -618,7 +618,7 @@ static umode_t qla4_attr_is_visible(int param_type, int param) } /** - * qla4xxx_create chap_list - Create CHAP list from FLASH + * qla4xxx_create_chap_list - Create CHAP list from FLASH * @ha: pointer to adapter structure * * Read flash and make a list of CHAP entries, during login when a CHAP entry @@ -9633,7 +9633,7 @@ qla4xxx_pci_error_detected(struct pci_dev *pdev, pci_channel_state_t state) } /** - * qla4xxx_pci_mmio_enabled() gets called if + * qla4xxx_pci_mmio_enabled() - gets called if * qla4xxx_pci_error_detected() returns PCI_ERS_RESULT_CAN_RECOVER * and read/write to the device still works. * @pdev: PCI device pointer From 3978e59b6d6cf3a0c8f056768fa1a646a1d3d27d Mon Sep 17 00:00:00 2001 From: Lee Jones Date: Wed, 3 Mar 2021 14:46:14 +0000 Subject: [PATCH 107/412] scsi: pm8001: Fix incorrectly named functions in headers Fixes the following W=1 kernel build warning(s): drivers/scsi/pm8001/pm8001_ctl.c:313: warning: expecting prototype for pm8001_ctl_sas_address_show(). Prototype was for pm8001_ctl_host_sas_address_show() instead drivers/scsi/pm8001/pm8001_ctl.c:530: warning: expecting prototype for pm8001_ctl_aap_log_show(). Prototype was for pm8001_ctl_iop_log_show() instead Link: https://lore.kernel.org/r/20210303144631.3175331-14-lee.jones@linaro.org Cc: Jack Wang Cc: "James E.J. Bottomley" Cc: "Martin K. Petersen" Cc: linux-scsi@vger.kernel.org Acked-by: Jack Wang Signed-off-by: Lee Jones Signed-off-by: Martin K. Petersen --- drivers/scsi/pm8001/pm8001_ctl.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/scsi/pm8001/pm8001_ctl.c b/drivers/scsi/pm8001/pm8001_ctl.c index 12035baf0997..1921e69bc232 100644 --- a/drivers/scsi/pm8001/pm8001_ctl.c +++ b/drivers/scsi/pm8001/pm8001_ctl.c @@ -299,7 +299,7 @@ static DEVICE_ATTR(sas_spec_support, S_IRUGO, pm8001_ctl_sas_spec_support_show, NULL); /** - * pm8001_ctl_sas_address_show - sas address + * pm8001_ctl_host_sas_address_show - sas address * @cdev: pointer to embedded class device * @attr: device attribute (unused) * @buf: the buffer returned @@ -518,7 +518,7 @@ static ssize_t event_log_size_show(struct device *cdev, } static DEVICE_ATTR_RO(event_log_size); /** - * pm8001_ctl_aap_log_show - IOP event log + * pm8001_ctl_iop_log_show - IOP event log * @cdev: pointer to embedded class device * @attr: device attribute (unused) * @buf: the buffer returned From 3528b9abbd065d541b30feadd2bc1e6900c97fc8 Mon Sep 17 00:00:00 2001 From: Lee Jones Date: Wed, 3 Mar 2021 14:46:15 +0000 Subject: [PATCH 108/412] scsi: aic94xx: Fix asd_erase_nv_sector()'s header Fixes the following W=1 kernel build warning(s): drivers/scsi/aic94xx/aic94xx_sds.c:1253: warning: expecting prototype for asd_hwi_erase_nv_sector(). Prototype was for asd_erase_nv_sector() instead Link: https://lore.kernel.org/r/20210303144631.3175331-15-lee.jones@linaro.org Cc: "James E.J. Bottomley" Cc: "Martin K. Petersen" Cc: Jason Yan Cc: John Garry Cc: "Gustavo A. R. Silva" Cc: Luben Tuikov Cc: linux-scsi@vger.kernel.org Signed-off-by: Lee Jones Signed-off-by: Martin K. Petersen --- drivers/scsi/aic94xx/aic94xx_sds.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/scsi/aic94xx/aic94xx_sds.c b/drivers/scsi/aic94xx/aic94xx_sds.c index 105adba559a1..297a66770260 100644 --- a/drivers/scsi/aic94xx/aic94xx_sds.c +++ b/drivers/scsi/aic94xx/aic94xx_sds.c @@ -1244,7 +1244,7 @@ int asd_chk_write_status(struct asd_ha_struct *asd_ha, } /** - * asd_hwi_erase_nv_sector - Erase the flash memory sectors. + * asd_erase_nv_sector - Erase the flash memory sectors. * @asd_ha: pointer to the host adapter structure * @flash_addr: pointer to offset from flash memory * @size: total bytes to erase. From 52bb80f18def787e98a9f97a7cabbe71e4879996 Mon Sep 17 00:00:00 2001 From: Lee Jones Date: Wed, 3 Mar 2021 14:46:16 +0000 Subject: [PATCH 109/412] scsi: qla2xxx: Replace __qla2x00_marker()'s missing underscores Fixes the following W=1 kernel build warning(s): drivers/scsi/qla2xxx/qla_iocb.c:508: warning: expecting prototype for qla2x00_marker(). Prototype was for __qla2x00_marker() instead Link: https://lore.kernel.org/r/20210303144631.3175331-16-lee.jones@linaro.org Cc: Nilesh Javali Cc: GR-QLogic-Storage-Upstream@marvell.com Cc: "James E.J. Bottomley" Cc: "Martin K. Petersen" Cc: linux-scsi@vger.kernel.org Acked-by: Nilesh Javali Signed-off-by: Lee Jones Signed-off-by: Martin K. Petersen --- drivers/scsi/qla2xxx/qla_iocb.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/scsi/qla2xxx/qla_iocb.c b/drivers/scsi/qla2xxx/qla_iocb.c index 8b41cbaf8535..e765ee4ce162 100644 --- a/drivers/scsi/qla2xxx/qla_iocb.c +++ b/drivers/scsi/qla2xxx/qla_iocb.c @@ -491,7 +491,7 @@ qla2x00_start_iocbs(struct scsi_qla_host *vha, struct req_que *req) } /** - * qla2x00_marker() - Send a marker IOCB to the firmware. + * __qla2x00_marker() - Send a marker IOCB to the firmware. * @vha: HA context * @qpair: queue pair pointer * @loop_id: loop ID From 53616df28199b2555cccddcfede7098ba51bd789 Mon Sep 17 00:00:00 2001 From: Lee Jones Date: Wed, 3 Mar 2021 14:46:17 +0000 Subject: [PATCH 110/412] scsi: aacraid: Repair formatting issue in aac_handle_sa_aif()'s header MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fixes the following W=1 kernel build warning(s): drivers/scsi/aacraid/commsup.c:334: warning: expecting prototype for fib_deallocate(). Prototype was for fib_dealloc() instead drivers/scsi/aacraid/commsup.c:1961: warning: expecting prototype for aac_handle_sa_aif Handle a message from the firmware(). Prototype was for aac_handle_sa_aif() instead Link: https://lore.kernel.org/r/20210303144631.3175331-17-lee.jones@linaro.org Cc: Adaptec OEM Raid Solutions Cc: "James E.J. Bottomley" Cc: "Martin K. Petersen" Cc: Sumit Semwal Cc: "Christian König" Cc: "PMC-Sierra, Inc" Cc: linux-scsi@vger.kernel.org Cc: linux-media@vger.kernel.org Cc: dri-devel@lists.freedesktop.org Cc: linaro-mm-sig@lists.linaro.org Signed-off-by: Lee Jones Signed-off-by: Martin K. Petersen --- drivers/scsi/aacraid/commsup.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/scsi/aacraid/commsup.c b/drivers/scsi/aacraid/commsup.c index 0ae0d1fa2b50..54eb4d41bc2c 100644 --- a/drivers/scsi/aacraid/commsup.c +++ b/drivers/scsi/aacraid/commsup.c @@ -323,7 +323,7 @@ void aac_fib_init(struct fib *fibptr) } /** - * fib_deallocate - deallocate a fib + * fib_dealloc - deallocate a fib * @fibptr: fib to deallocate * * Will deallocate and return to the free pool the FIB pointed to by the @@ -1950,7 +1950,7 @@ void aac_src_reinit_aif_worker(struct work_struct *work) } /** - * aac_handle_sa_aif Handle a message from the firmware + * aac_handle_sa_aif - Handle a message from the firmware * @dev: Which adapter this fib is from * @fibptr: Pointer to fibptr from adapter * From 8514e2f1e2c6d78537eb66585b69ab59138e0220 Mon Sep 17 00:00:00 2001 From: Lee Jones Date: Wed, 3 Mar 2021 14:46:18 +0000 Subject: [PATCH 111/412] scsi: lpfc: Fix a bunch of kernel-doc issues MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fixes the following W=1 kernel build warning(s): drivers/scsi/lpfc/lpfc_sli.c:9654: warning: expecting prototype for lpfc_sli_iocb2wqe(). Prototype was for lpfc_sli4_iocb2wqe() instead drivers/scsi/lpfc/lpfc_sli.c:10439: warning: Function parameter or member 'phba' not described in 'lpfc_sli_issue_fcp_io' drivers/scsi/lpfc/lpfc_sli.c:10439: warning: Function parameter or member 'ring_number' not described in 'lpfc_sli_issue_fcp_io' drivers/scsi/lpfc/lpfc_sli.c:10439: warning: Function parameter or member 'piocb' not described in 'lpfc_sli_issue_fcp_io' drivers/scsi/lpfc/lpfc_sli.c:10439: warning: Function parameter or member 'flag' not described in 'lpfc_sli_issue_fcp_io' drivers/scsi/lpfc/lpfc_sli.c:14189: warning: expecting prototype for lpfc_sli4_sp_process_cq(). Prototype was for __lpfc_sli4_sp_process_cq() instead drivers/scsi/lpfc/lpfc_sli.c:14754: warning: expecting prototype for lpfc_sli4_hba_process_cq(). Prototype was for lpfc_sli4_dly_hba_process_cq() instead drivers/scsi/lpfc/lpfc_sli.c:17230: warning: expecting prototype for lpfc_sli4_free_xri(). Prototype was for __lpfc_sli4_free_xri() instead drivers/scsi/lpfc/lpfc_sli.c:18950: warning: expecting prototype for lpfc_sli4_free_rpi(). Prototype was for __lpfc_sli4_free_rpi() instead Link: https://lore.kernel.org/r/20210303144631.3175331-18-lee.jones@linaro.org Cc: James Smart Cc: Dick Kennedy Cc: "James E.J. Bottomley" Cc: "Martin K. Petersen" Cc: Sumit Semwal Cc: "Christian König" Cc: linux-scsi@vger.kernel.org Cc: linux-media@vger.kernel.org Cc: dri-devel@lists.freedesktop.org Cc: linaro-mm-sig@lists.linaro.org Signed-off-by: Lee Jones Signed-off-by: Martin K. Petersen --- drivers/scsi/lpfc/lpfc_sli.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/drivers/scsi/lpfc/lpfc_sli.c b/drivers/scsi/lpfc/lpfc_sli.c index 977cc09e8542..f6e1e36eabdc 100644 --- a/drivers/scsi/lpfc/lpfc_sli.c +++ b/drivers/scsi/lpfc/lpfc_sli.c @@ -9632,7 +9632,7 @@ lpfc_sli4_bpl2sgl(struct lpfc_hba *phba, struct lpfc_iocbq *piocbq, } /** - * lpfc_sli_iocb2wqe - Convert the IOCB to a work queue entry. + * lpfc_sli4_iocb2wqe - Convert the IOCB to a work queue entry. * @phba: Pointer to HBA context object. * @iocbq: Pointer to command iocb. * @wqe: Pointer to the work queue entry. @@ -10418,7 +10418,7 @@ __lpfc_sli_issue_iocb_s4(struct lpfc_hba *phba, uint32_t ring_number, return 0; } -/** +/* * lpfc_sli_issue_fcp_io - Wrapper func for issuing fcp i/o * * This routine wraps the actual fcp i/o function for issusing WQE for sli-4 @@ -14167,7 +14167,7 @@ rearm_and_exit: } /** - * lpfc_sli4_sp_process_cq - Process a slow-path event queue entry + * __lpfc_sli4_sp_process_cq - Process a slow-path event queue entry * @cq: pointer to CQ to process * * This routine calls the cq processing routine with a handler specific @@ -14741,7 +14741,7 @@ lpfc_sli4_hba_process_cq(struct work_struct *work) } /** - * lpfc_sli4_hba_process_cq - fast-path work handler when started by timer + * lpfc_sli4_dly_hba_process_cq - fast-path work handler when started by timer * @work: pointer to work element * * translates from the work handler and calls the fast-path handler. @@ -17215,7 +17215,7 @@ lpfc_sli4_alloc_xri(struct lpfc_hba *phba) } /** - * lpfc_sli4_free_xri - Release an xri for reuse. + * __lpfc_sli4_free_xri - Release an xri for reuse. * @phba: pointer to lpfc hba data structure. * @xri: xri to release. * @@ -18935,7 +18935,7 @@ lpfc_sli4_alloc_rpi(struct lpfc_hba *phba) } /** - * lpfc_sli4_free_rpi - Release an rpi for reuse. + * __lpfc_sli4_free_rpi - Release an rpi for reuse. * @phba: pointer to lpfc hba data structure. * @rpi: rpi to free * From 6b87e435e4bccd696f47ea73f9483ae2cfc62aec Mon Sep 17 00:00:00 2001 From: Lee Jones Date: Wed, 3 Mar 2021 14:46:19 +0000 Subject: [PATCH 112/412] scsi: pm8001: Fix some misnamed function descriptions Fixes the following W=1 kernel build warning(s): drivers/scsi/pm8001/pm8001_hwi.c:1183: warning: expecting prototype for pm8001_chip_interrupt_enable(). Prototype was for pm8001_chip_intx_interrupt_enable() instead drivers/scsi/pm8001/pm8001_hwi.c:1257: warning: expecting prototype for pm8001_chip_intx_interrupt_disable(). Prototype was for pm8001_chip_interrupt_disable() instead drivers/scsi/pm8001/pm8001_hwi.c:3235: warning: expecting prototype for asd_get_attached_sas_addr(). Prototype was for pm8001_get_attached_sas_addr() instead drivers/scsi/pm8001/pm8001_hwi.c:3555: warning: expecting prototype for fw_flash_update_resp(). Prototype was for pm8001_mpi_fw_flash_update_resp() instead Link: https://lore.kernel.org/r/20210303144631.3175331-19-lee.jones@linaro.org Cc: Jack Wang Cc: "James E.J. Bottomley" Cc: "Martin K. Petersen" Cc: linux-scsi@vger.kernel.org Acked-by: Jack Wang Signed-off-by: Lee Jones Signed-off-by: Martin K. Petersen --- drivers/scsi/pm8001/pm8001_hwi.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/scsi/pm8001/pm8001_hwi.c b/drivers/scsi/pm8001/pm8001_hwi.c index 49bf2f70a470..6b600e33e9e8 100644 --- a/drivers/scsi/pm8001/pm8001_hwi.c +++ b/drivers/scsi/pm8001/pm8001_hwi.c @@ -1175,7 +1175,7 @@ void pm8001_chip_iounmap(struct pm8001_hba_info *pm8001_ha) #ifndef PM8001_USE_MSIX /** - * pm8001_chip_interrupt_enable - enable PM8001 chip interrupt + * pm8001_chip_intx_interrupt_enable - enable PM8001 chip interrupt * @pm8001_ha: our hba card information */ static void @@ -1248,7 +1248,7 @@ pm8001_chip_interrupt_enable(struct pm8001_hba_info *pm8001_ha, u8 vec) } /** - * pm8001_chip_intx_interrupt_disable- disable PM8001 chip interrupt + * pm8001_chip_interrupt_disable - disable PM8001 chip interrupt * @pm8001_ha: our hba card information * @vec: unused */ @@ -3219,7 +3219,7 @@ void pm8001_get_lrate_mode(struct pm8001_phy *phy, u8 link_rate) } /** - * asd_get_attached_sas_addr -- extract/generate attached SAS address + * pm8001_get_attached_sas_addr - extract/generate attached SAS address * @phy: pointer to asd_phy * @sas_addr: pointer to buffer where the SAS address is to be written * @@ -3546,7 +3546,7 @@ int pm8001_mpi_dereg_resp(struct pm8001_hba_info *pm8001_ha, void *piomb) } /** - * fw_flash_update_resp - Response from FW for flash update command. + * pm8001_mpi_fw_flash_update_resp - Response from FW for flash update command. * @pm8001_ha: our hba card information * @piomb: IO message buffer */ From e39c31a7435af49d03604fb89f035198bf7f5f45 Mon Sep 17 00:00:00 2001 From: Lee Jones Date: Wed, 3 Mar 2021 14:46:20 +0000 Subject: [PATCH 113/412] scsi: qla4xxx: Fix kernel-doc formatting and misnaming issue Fixes the following W=1 kernel build warning(s): drivers/scsi/qla4xxx/ql4_mbx.c:47: warning: wrong kernel-doc identifier on line: drivers/scsi/qla4xxx/ql4_mbx.c:947: warning: expecting prototype for qla4xxx_set_fwddb_entry(). Prototype was for qla4xxx_set_ddb_entry() instead Link: https://lore.kernel.org/r/20210303144631.3175331-20-lee.jones@linaro.org Cc: Nilesh Javali Cc: Manish Rangankar Cc: GR-QLogic-Storage-Upstream@marvell.com Cc: "James E.J. Bottomley" Cc: "Martin K. Petersen" Cc: linux-scsi@vger.kernel.org Acked-by: Nilesh Javali Signed-off-by: Lee Jones Signed-off-by: Martin K. Petersen --- drivers/scsi/qla4xxx/ql4_mbx.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/scsi/qla4xxx/ql4_mbx.c b/drivers/scsi/qla4xxx/ql4_mbx.c index 17b719a8b6fb..187d78aa4f67 100644 --- a/drivers/scsi/qla4xxx/ql4_mbx.c +++ b/drivers/scsi/qla4xxx/ql4_mbx.c @@ -44,7 +44,7 @@ void qla4xxx_process_mbox_intr(struct scsi_qla_host *ha, int out_count) } /** - * qla4xxx_is_intr_poll_mode – Are we allowed to poll for interrupts? + * qla4xxx_is_intr_poll_mode - Are we allowed to poll for interrupts? * @ha: Pointer to host adapter structure. * returns: 1=polling mode, 0=non-polling mode **/ @@ -933,7 +933,7 @@ int qla4xxx_conn_open(struct scsi_qla_host *ha, uint16_t fw_ddb_index) } /** - * qla4xxx_set_fwddb_entry - sets a ddb entry. + * qla4xxx_set_ddb_entry - sets a ddb entry. * @ha: Pointer to host adapter structure. * @fw_ddb_index: Firmware's device database index * @fw_ddb_entry_dma: dma address of ddb entry From a7f4242d120740f549f729b4d18e73b589c889e5 Mon Sep 17 00:00:00 2001 From: Lee Jones Date: Wed, 3 Mar 2021 14:46:21 +0000 Subject: [PATCH 114/412] scsi: bnx2fc: Fix misnaming of bnx2fc_free_session_resc() Fixes the following W=1 kernel build warning(s): drivers/scsi/bnx2fc/bnx2fc_tgt.c:831: warning: expecting prototype for bnx2i_free_session_resc(). Prototype was for bnx2fc_free_session_resc() instead Link: https://lore.kernel.org/r/20210303144631.3175331-21-lee.jones@linaro.org Cc: Saurav Kashyap Cc: Javed Hasan Cc: GR-QLogic-Storage-Upstream@marvell.com Cc: "James E.J. Bottomley" Cc: "Martin K. Petersen" Cc: Prakash Gollapudi Cc: linux-scsi@vger.kernel.org Signed-off-by: Lee Jones Signed-off-by: Martin K. Petersen --- drivers/scsi/bnx2fc/bnx2fc_tgt.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/scsi/bnx2fc/bnx2fc_tgt.c b/drivers/scsi/bnx2fc/bnx2fc_tgt.c index a3e2a38aabf2..9200b718085c 100644 --- a/drivers/scsi/bnx2fc/bnx2fc_tgt.c +++ b/drivers/scsi/bnx2fc/bnx2fc_tgt.c @@ -819,7 +819,7 @@ mem_alloc_failure: } /** - * bnx2i_free_session_resc - free qp resources for the session + * bnx2fc_free_session_resc - free qp resources for the session * * @hba: adapter structure pointer * @tgt: bnx2fc_rport structure pointer From 241b37ac5859434974f8638af9f555a9253c5ed8 Mon Sep 17 00:00:00 2001 From: Lee Jones Date: Wed, 3 Mar 2021 14:46:22 +0000 Subject: [PATCH 115/412] scsi: aic94xx: Remove code that has been unused for at least 13 years Fixes the following W=1 kernel build warning(s): drivers/scsi/aic94xx/aic94xx_dump.c:731: warning: expecting prototype for asd_dump_ddb_site(). Prototype was for asd_dump_target_ddb() instead drivers/scsi/aic94xx/aic94xx_dump.c:875: warning: expecting prototype for ads_dump_seq_state(). Prototype was for asd_dump_seq_state() instead Link: https://lore.kernel.org/r/20210303144631.3175331-22-lee.jones@linaro.org Cc: "James E.J. Bottomley" Cc: "Martin K. Petersen" Cc: David Chaw Cc: Luben Tuikov Cc: linux-scsi@vger.kernel.org Signed-off-by: Lee Jones Signed-off-by: Martin K. Petersen --- drivers/scsi/aic94xx/aic94xx_dump.c | 184 ---------------------------- 1 file changed, 184 deletions(-) diff --git a/drivers/scsi/aic94xx/aic94xx_dump.c b/drivers/scsi/aic94xx/aic94xx_dump.c index 7c4c53a54b78..47a663a39dcc 100644 --- a/drivers/scsi/aic94xx/aic94xx_dump.c +++ b/drivers/scsi/aic94xx/aic94xx_dump.c @@ -720,152 +720,6 @@ static void asd_dump_lseq_state(struct asd_ha_struct *asd_ha, int lseq) PRINT_LMIP_dword(asd_ha, lseq, DEV_PRES_TIMER_TERM_TS); } -#if 0 - -/** - * asd_dump_ddb_site -- dump a CSEQ DDB site - * @asd_ha: pointer to host adapter structure - * @site_no: site number of interest - */ -void asd_dump_target_ddb(struct asd_ha_struct *asd_ha, u16 site_no) -{ - if (site_no >= asd_ha->hw_prof.max_ddbs) - return; - -#define DDB_FIELDB(__name) \ - asd_ddbsite_read_byte(asd_ha, site_no, \ - offsetof(struct asd_ddb_ssp_smp_target_port, __name)) -#define DDB2_FIELDB(__name) \ - asd_ddbsite_read_byte(asd_ha, site_no, \ - offsetof(struct asd_ddb_stp_sata_target_port, __name)) -#define DDB_FIELDW(__name) \ - asd_ddbsite_read_word(asd_ha, site_no, \ - offsetof(struct asd_ddb_ssp_smp_target_port, __name)) - -#define DDB_FIELDD(__name) \ - asd_ddbsite_read_dword(asd_ha, site_no, \ - offsetof(struct asd_ddb_ssp_smp_target_port, __name)) - - asd_printk("DDB: 0x%02x\n", site_no); - asd_printk("conn_type: 0x%02x\n", DDB_FIELDB(conn_type)); - asd_printk("conn_rate: 0x%02x\n", DDB_FIELDB(conn_rate)); - asd_printk("init_conn_tag: 0x%04x\n", be16_to_cpu(DDB_FIELDW(init_conn_tag))); - asd_printk("send_queue_head: 0x%04x\n", be16_to_cpu(DDB_FIELDW(send_queue_head))); - asd_printk("sq_suspended: 0x%02x\n", DDB_FIELDB(sq_suspended)); - asd_printk("DDB Type: 0x%02x\n", DDB_FIELDB(ddb_type)); - asd_printk("AWT Default: 0x%04x\n", DDB_FIELDW(awt_def)); - asd_printk("compat_features: 0x%02x\n", DDB_FIELDB(compat_features)); - asd_printk("Pathway Blocked Count: 0x%02x\n", - DDB_FIELDB(pathway_blocked_count)); - asd_printk("arb_wait_time: 0x%04x\n", DDB_FIELDW(arb_wait_time)); - asd_printk("more_compat_features: 0x%08x\n", - DDB_FIELDD(more_compat_features)); - asd_printk("Conn Mask: 0x%02x\n", DDB_FIELDB(conn_mask)); - asd_printk("flags: 0x%02x\n", DDB_FIELDB(flags)); - asd_printk("flags2: 0x%02x\n", DDB2_FIELDB(flags2)); - asd_printk("ExecQ Tail: 0x%04x\n",DDB_FIELDW(exec_queue_tail)); - asd_printk("SendQ Tail: 0x%04x\n",DDB_FIELDW(send_queue_tail)); - asd_printk("Active Task Count: 0x%04x\n", - DDB_FIELDW(active_task_count)); - asd_printk("ITNL Reason: 0x%02x\n", DDB_FIELDB(itnl_reason)); - asd_printk("ITNL Timeout Const: 0x%04x\n", DDB_FIELDW(itnl_timeout)); - asd_printk("ITNL timestamp: 0x%08x\n", DDB_FIELDD(itnl_timestamp)); -} - -void asd_dump_ddb_0(struct asd_ha_struct *asd_ha) -{ -#define DDB0_FIELDB(__name) \ - asd_ddbsite_read_byte(asd_ha, 0, \ - offsetof(struct asd_ddb_seq_shared, __name)) -#define DDB0_FIELDW(__name) \ - asd_ddbsite_read_word(asd_ha, 0, \ - offsetof(struct asd_ddb_seq_shared, __name)) - -#define DDB0_FIELDD(__name) \ - asd_ddbsite_read_dword(asd_ha,0 , \ - offsetof(struct asd_ddb_seq_shared, __name)) - -#define DDB0_FIELDA(__name, _o) \ - asd_ddbsite_read_byte(asd_ha, 0, \ - offsetof(struct asd_ddb_seq_shared, __name)+_o) - - - asd_printk("DDB: 0\n"); - asd_printk("q_free_ddb_head:%04x\n", DDB0_FIELDW(q_free_ddb_head)); - asd_printk("q_free_ddb_tail:%04x\n", DDB0_FIELDW(q_free_ddb_tail)); - asd_printk("q_free_ddb_cnt:%04x\n", DDB0_FIELDW(q_free_ddb_cnt)); - asd_printk("q_used_ddb_head:%04x\n", DDB0_FIELDW(q_used_ddb_head)); - asd_printk("q_used_ddb_tail:%04x\n", DDB0_FIELDW(q_used_ddb_tail)); - asd_printk("shared_mem_lock:%04x\n", DDB0_FIELDW(shared_mem_lock)); - asd_printk("smp_conn_tag:%04x\n", DDB0_FIELDW(smp_conn_tag)); - asd_printk("est_nexus_buf_cnt:%04x\n", DDB0_FIELDW(est_nexus_buf_cnt)); - asd_printk("est_nexus_buf_thresh:%04x\n", - DDB0_FIELDW(est_nexus_buf_thresh)); - asd_printk("conn_not_active:%02x\n", DDB0_FIELDB(conn_not_active)); - asd_printk("phy_is_up:%02x\n", DDB0_FIELDB(phy_is_up)); - asd_printk("port_map_by_links:%02x %02x %02x %02x " - "%02x %02x %02x %02x\n", - DDB0_FIELDA(port_map_by_links, 0), - DDB0_FIELDA(port_map_by_links, 1), - DDB0_FIELDA(port_map_by_links, 2), - DDB0_FIELDA(port_map_by_links, 3), - DDB0_FIELDA(port_map_by_links, 4), - DDB0_FIELDA(port_map_by_links, 5), - DDB0_FIELDA(port_map_by_links, 6), - DDB0_FIELDA(port_map_by_links, 7)); -} - -static void asd_dump_scb_site(struct asd_ha_struct *asd_ha, u16 site_no) -{ - -#define SCB_FIELDB(__name) \ - asd_scbsite_read_byte(asd_ha, site_no, sizeof(struct scb_header) \ - + offsetof(struct initiate_ssp_task, __name)) -#define SCB_FIELDW(__name) \ - asd_scbsite_read_word(asd_ha, site_no, sizeof(struct scb_header) \ - + offsetof(struct initiate_ssp_task, __name)) -#define SCB_FIELDD(__name) \ - asd_scbsite_read_dword(asd_ha, site_no, sizeof(struct scb_header) \ - + offsetof(struct initiate_ssp_task, __name)) - - asd_printk("Total Xfer Len: 0x%08x.\n", SCB_FIELDD(total_xfer_len)); - asd_printk("Frame Type: 0x%02x.\n", SCB_FIELDB(ssp_frame.frame_type)); - asd_printk("Tag: 0x%04x.\n", SCB_FIELDW(ssp_frame.tag)); - asd_printk("Target Port Xfer Tag: 0x%04x.\n", - SCB_FIELDW(ssp_frame.tptt)); - asd_printk("Data Offset: 0x%08x.\n", SCB_FIELDW(ssp_frame.data_offs)); - asd_printk("Retry Count: 0x%02x.\n", SCB_FIELDB(retry_count)); -} - -/** - * asd_dump_scb_sites -- dump currently used CSEQ SCB sites - * @asd_ha: pointer to host adapter struct - */ -void asd_dump_scb_sites(struct asd_ha_struct *asd_ha) -{ - u16 site_no; - - for (site_no = 0; site_no < asd_ha->hw_prof.max_scbs; site_no++) { - u8 opcode; - - if (!SCB_SITE_VALID(site_no)) - continue; - - /* We are only interested in SCB sites currently used. - */ - opcode = asd_scbsite_read_byte(asd_ha, site_no, - offsetof(struct scb_header, - opcode)); - if (opcode == 0xFF) - continue; - - asd_printk("\nSCB: 0x%x\n", site_no); - asd_dump_scb_site(asd_ha, site_no); - } -} - -#endif /* 0 */ - /** * ads_dump_seq_state -- dump CSEQ and LSEQ states * @asd_ha: pointer to host adapter structure @@ -908,42 +762,4 @@ void asd_dump_frame_rcvd(struct asd_phy *phy, spin_unlock_irqrestore(&phy->sas_phy.frame_rcvd_lock, flags); } -#if 0 - -static void asd_dump_scb(struct asd_ascb *ascb, int ind) -{ - asd_printk("scb%d: vaddr: 0x%p, dma_handle: 0x%llx, next: 0x%llx, " - "index:%d, opcode:0x%02x\n", - ind, ascb->dma_scb.vaddr, - (unsigned long long)ascb->dma_scb.dma_handle, - (unsigned long long) - le64_to_cpu(ascb->scb->header.next_scb), - le16_to_cpu(ascb->scb->header.index), - ascb->scb->header.opcode); -} - -void asd_dump_scb_list(struct asd_ascb *ascb, int num) -{ - int i = 0; - - asd_printk("dumping %d scbs:\n", num); - - asd_dump_scb(ascb, i++); - --num; - - if (num > 0 && !list_empty(&ascb->list)) { - struct list_head *el; - - list_for_each(el, &ascb->list) { - struct asd_ascb *s = list_entry(el, struct asd_ascb, - list); - asd_dump_scb(s, i++); - if (--num <= 0) - break; - } - } -} - -#endif /* 0 */ - #endif /* ASD_DEBUG */ From 7cdaf12ea50afd7512114eb21bc6bf4428c9006c Mon Sep 17 00:00:00 2001 From: Lee Jones Date: Wed, 3 Mar 2021 14:46:23 +0000 Subject: [PATCH 116/412] scsi: pm8001: Fix a bunch of doc-rotted function headers Fixes the following W=1 kernel build warning(s): drivers/scsi/pm8001/pm80xx_hwi.c:1427: warning: expecting prototype for pm8001_chip_init(). Prototype was for pm80xx_chip_init() instead drivers/scsi/pm8001/pm80xx_hwi.c:1584: warning: expecting prototype for pm8001_chip_soft_rst(). Prototype was for pm80xx_chip_soft_rst() instead drivers/scsi/pm8001/pm80xx_hwi.c:1711: warning: expecting prototype for pm8001_chip_interrupt_enable(). Prototype was for pm80xx_chip_intx_interrupt_enable() instead drivers/scsi/pm8001/pm80xx_hwi.c:1722: warning: expecting prototype for pm8001_chip_intx_interrupt_disable(). Prototype was for pm80xx_chip_intx_interrupt_disable() instead drivers/scsi/pm8001/pm80xx_hwi.c:1733: warning: expecting prototype for pm8001_chip_interrupt_enable(). Prototype was for pm80xx_chip_interrupt_enable() instead drivers/scsi/pm8001/pm80xx_hwi.c:1752: warning: expecting prototype for pm8001_chip_interrupt_disable(). Prototype was for pm80xx_chip_interrupt_disable() instead drivers/scsi/pm8001/pm80xx_hwi.c:4192: warning: expecting prototype for pm8001_chip_smp_req(). Prototype was for pm80xx_chip_smp_req() instead drivers/scsi/pm8001/pm80xx_hwi.c:4775: warning: expecting prototype for pm8001_chip_phy_stop_req(). Prototype was for pm80xx_chip_phy_stop_req() instead drivers/scsi/pm8001/pm80xx_hwi.c:4907: warning: expecting prototype for pm8001_chip_isr(). Prototype was for pm80xx_chip_isr() instead Link: https://lore.kernel.org/r/20210303144631.3175331-23-lee.jones@linaro.org Cc: Jack Wang Cc: "James E.J. Bottomley" Cc: "Martin K. Petersen" Cc: linux-scsi@vger.kernel.org Acked-by: Jack Wang Signed-off-by: Lee Jones Signed-off-by: Martin K. Petersen --- drivers/scsi/pm8001/pm80xx_hwi.c | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/drivers/scsi/pm8001/pm80xx_hwi.c b/drivers/scsi/pm8001/pm80xx_hwi.c index 84315560e8e1..74ed072209f4 100644 --- a/drivers/scsi/pm8001/pm80xx_hwi.c +++ b/drivers/scsi/pm8001/pm80xx_hwi.c @@ -1420,7 +1420,7 @@ static int pm80xx_encrypt_update(struct pm8001_hba_info *pm8001_ha) } /** - * pm8001_chip_init - the main init function that initialize whole PM8001 chip. + * pm80xx_chip_init - the main init function that initialize whole PM8001 chip. * @pm8001_ha: our hba card information */ static int pm80xx_chip_init(struct pm8001_hba_info *pm8001_ha) @@ -1574,7 +1574,7 @@ pm80xx_fatal_errors(struct pm8001_hba_info *pm8001_ha) } /** - * pm8001_chip_soft_rst - soft reset the PM8001 chip, so that the clear all + * pm80xx_chip_soft_rst - soft reset the PM8001 chip, so that the clear all * the FW register status to the originated status. * @pm8001_ha: our hba card information */ @@ -1703,7 +1703,7 @@ static void pm80xx_hw_chip_rst(struct pm8001_hba_info *pm8001_ha) } /** - * pm8001_chip_interrupt_enable - enable PM8001 chip interrupt + * pm80xx_chip_intx_interrupt_enable - enable PM8001 chip interrupt * @pm8001_ha: our hba card information */ static void @@ -1714,7 +1714,7 @@ pm80xx_chip_intx_interrupt_enable(struct pm8001_hba_info *pm8001_ha) } /** - * pm8001_chip_intx_interrupt_disable- disable PM8001 chip interrupt + * pm80xx_chip_intx_interrupt_disable - disable PM8001 chip interrupt * @pm8001_ha: our hba card information */ static void @@ -1724,7 +1724,7 @@ pm80xx_chip_intx_interrupt_disable(struct pm8001_hba_info *pm8001_ha) } /** - * pm8001_chip_interrupt_enable - enable PM8001 chip interrupt + * pm80xx_chip_interrupt_enable - enable PM8001 chip interrupt * @pm8001_ha: our hba card information * @vec: interrupt number to enable */ @@ -1743,7 +1743,7 @@ pm80xx_chip_interrupt_enable(struct pm8001_hba_info *pm8001_ha, u8 vec) } /** - * pm8001_chip_interrupt_disable- disable PM8001 chip interrupt + * pm80xx_chip_interrupt_disable - disable PM8001 chip interrupt * @pm8001_ha: our hba card information * @vec: interrupt number to disable */ @@ -4183,7 +4183,7 @@ static void build_smp_cmd(u32 deviceID, __le32 hTag, } /** - * pm8001_chip_smp_req - send a SMP task to FW + * pm80xx_chip_smp_req - send a SMP task to FW * @pm8001_ha: our hba card information. * @ccb: the ccb information this request used. */ @@ -4766,7 +4766,7 @@ pm80xx_chip_phy_start_req(struct pm8001_hba_info *pm8001_ha, u8 phy_id) } /** - * pm8001_chip_phy_stop_req - start phy via PHY_STOP COMMAND + * pm80xx_chip_phy_stop_req - start phy via PHY_STOP COMMAND * @pm8001_ha: our hba card information. * @phy_id: the phy id which we wanted to start up. */ @@ -4898,7 +4898,7 @@ static u32 pm80xx_chip_is_our_interrupt(struct pm8001_hba_info *pm8001_ha) } /** - * pm8001_chip_isr - PM8001 isr handler. + * pm80xx_chip_isr - PM8001 isr handler. * @pm8001_ha: our hba card information. * @vec: irq number. */ From f11c8b42423f3b32c30bd985333e7378226b832d Mon Sep 17 00:00:00 2001 From: Lee Jones Date: Wed, 3 Mar 2021 14:46:24 +0000 Subject: [PATCH 117/412] scsi: qla2xxx: Fix some incorrect formatting/spelling issues Fixes the following W=1 kernel build warning(s): drivers/scsi/qla2xxx/qla_gs.c:1259: warning: expecting prototype for qla2x00_snd_rft_id(). Prototype was for qla2x00_sns_rft_id() instead drivers/scsi/qla2xxx/qla_gs.c:1492: warning: expecting prototype for qla2x00_prep_ct_req(). Prototype was for qla2x00_prep_ct_fdmi_req() instead drivers/scsi/qla2xxx/qla_gs.c:1596: warning: expecting prototype for perform HBA attributes registration(). Prototype was for qla2x00_hba_attributes() instead drivers/scsi/qla2xxx/qla_gs.c:1851: warning: expecting prototype for perform Port attributes registration(). Prototype was for qla2x00_port_attributes() instead drivers/scsi/qla2xxx/qla_gs.c:2284: warning: expecting prototype for perform RPRT registration(). Prototype was for qla2x00_fdmi_rprt() instead Link: https://lore.kernel.org/r/20210303144631.3175331-24-lee.jones@linaro.org Cc: Nilesh Javali Cc: GR-QLogic-Storage-Upstream@marvell.com Cc: "James E.J. Bottomley" Cc: "Martin K. Petersen" Cc: linux-scsi@vger.kernel.org Acked-by: Nilesh Javali Signed-off-by: Lee Jones Signed-off-by: Martin K. Petersen --- drivers/scsi/qla2xxx/qla_gs.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/drivers/scsi/qla2xxx/qla_gs.c b/drivers/scsi/qla2xxx/qla_gs.c index 517d358b0031..8e126afe61b1 100644 --- a/drivers/scsi/qla2xxx/qla_gs.c +++ b/drivers/scsi/qla2xxx/qla_gs.c @@ -1247,7 +1247,7 @@ qla2x00_sns_gnn_id(scsi_qla_host_t *vha, sw_info_t *list) } /** - * qla2x00_snd_rft_id() - SNS Register FC-4 TYPEs (RFT_ID) supported by the HBA. + * qla2x00_sns_rft_id() - SNS Register FC-4 TYPEs (RFT_ID) supported by the HBA. * @vha: HA context * * This command uses the old Exectute SNS Command mailbox routine. @@ -1479,7 +1479,7 @@ qla2x00_update_ms_fdmi_iocb(scsi_qla_host_t *vha, uint32_t req_size) } /** - * qla2x00_prep_ct_req() - Prepare common CT request fields for SNS query. + * qla2x00_prep_ct_fdmi_req() - Prepare common CT request fields for SNS query. * @p: CT request buffer * @cmd: GS command * @rsp_size: response size in bytes @@ -1582,7 +1582,7 @@ qla25xx_fdmi_port_speed_currently(struct qla_hw_data *ha) } /** - * qla2x00_hba_attributes() perform HBA attributes registration + * qla2x00_hba_attributes() - perform HBA attributes registration * @vha: HA context * @entries: number of entries to use * @callopt: Option to issue extended or standard FDMI @@ -1837,7 +1837,7 @@ done: } /** - * qla2x00_port_attributes() perform Port attributes registration + * qla2x00_port_attributes() - perform Port attributes registration * @vha: HA context * @entries: number of entries to use * @callopt: Option to issue extended or standard FDMI @@ -2272,7 +2272,7 @@ qla2x00_fdmi_dhba(scsi_qla_host_t *vha) } /** - * qla2x00_fdmi_rprt() perform RPRT registration + * qla2x00_fdmi_rprt() - perform RPRT registration * @vha: HA context * @callopt: Option to issue extended or standard FDMI * command parameter From 7df1daed3330e78d0bafe09cfd4aa0eb1da199ec Mon Sep 17 00:00:00 2001 From: Lee Jones Date: Wed, 3 Mar 2021 14:46:25 +0000 Subject: [PATCH 118/412] scsi: aacraid: Fix misspelling of _aac_rx_init() Fixes the following W=1 kernel build warning(s): drivers/scsi/aacraid/rx.c:544: warning: expecting prototype for aac_rx_init(). Prototype was for _aac_rx_init() instead Link: https://lore.kernel.org/r/20210303144631.3175331-25-lee.jones@linaro.org Cc: Adaptec OEM Raid Solutions Cc: "James E.J. Bottomley" Cc: "Martin K. Petersen" Cc: "PMC-Sierra, Inc" Cc: linux-scsi@vger.kernel.org Signed-off-by: Lee Jones Signed-off-by: Martin K. Petersen --- drivers/scsi/aacraid/rx.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/scsi/aacraid/rx.c b/drivers/scsi/aacraid/rx.c index cdccf9abcdc4..e06ff83b69ce 100644 --- a/drivers/scsi/aacraid/rx.c +++ b/drivers/scsi/aacraid/rx.c @@ -532,7 +532,7 @@ int aac_rx_select_comm(struct aac_dev *dev, int comm) } /** - * aac_rx_init - initialize an i960 based AAC card + * _aac_rx_init - initialize an i960 based AAC card * @dev: device to configure * * Allocate and set up resources for the i960 based AAC variants. The From 964bc8c4adb343c1142749a7e7276ef293c2d7af Mon Sep 17 00:00:00 2001 From: Lee Jones Date: Wed, 3 Mar 2021 14:46:26 +0000 Subject: [PATCH 119/412] scsi: lpfc: Fix formatting and misspelling issues Fixes the following W=1 kernel build warning(s): drivers/scsi/lpfc/lpfc_ct.c:153: warning: Function parameter or member 'ct_req' not described in 'lpfc_ct_reject_event' drivers/scsi/lpfc/lpfc_ct.c:153: warning: Function parameter or member 'rx_id' not described in 'lpfc_ct_reject_event' drivers/scsi/lpfc/lpfc_ct.c:153: warning: Function parameter or member 'ox_id' not described in 'lpfc_ct_reject_event' drivers/scsi/lpfc/lpfc_ct.c:283: warning: Function parameter or member 'ctiocbq' not described in 'lpfc_ct_handle_mibreq' drivers/scsi/lpfc/lpfc_ct.c:283: warning: Excess function parameter 'ctiocb' description in 'lpfc_ct_handle_mibreq' Link: https://lore.kernel.org/r/20210303144631.3175331-26-lee.jones@linaro.org Cc: James Smart Cc: Dick Kennedy Cc: "James E.J. Bottomley" Cc: "Martin K. Petersen" Cc: linux-scsi@vger.kernel.org Signed-off-by: Lee Jones Signed-off-by: Martin K. Petersen --- drivers/scsi/lpfc/lpfc_ct.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/drivers/scsi/lpfc/lpfc_ct.c b/drivers/scsi/lpfc/lpfc_ct.c index dd0b432f7ac5..37b0c2024998 100644 --- a/drivers/scsi/lpfc/lpfc_ct.c +++ b/drivers/scsi/lpfc/lpfc_ct.c @@ -137,11 +137,11 @@ lpfc_ct_unsol_cmpl(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, } /** - * lpfc_ct_reject_event : Issue reject for unhandled CT MIB commands - * @ndlp : pointer to a node-list data structure. - * ct_req : pointer to the CT request data structure. - * rx_id : rx_id of the received UNSOL CT command - * ox_id : ox_id of the UNSOL CT command + * lpfc_ct_reject_event - Issue reject for unhandled CT MIB commands + * @ndlp: pointer to a node-list data structure. + * @ct_req: pointer to the CT request data structure. + * @rx_id: rx_id of the received UNSOL CT command + * @ox_id: ox_id of the UNSOL CT command * * This routine is invoked by the lpfc_ct_handle_mibreq routine for sending * a reject response. Reject response is sent for the unhandled commands. @@ -272,7 +272,7 @@ ct_exit: /** * lpfc_ct_handle_mibreq - Process an unsolicited CT MIB request data buffer * @phba: pointer to lpfc hba data structure. - * @ctiocb: pointer to lpfc CT command iocb data structure. + * @ctiocbq: pointer to lpfc CT command iocb data structure. * * This routine is used for processing the IOCB associated with a unsolicited * CT MIB request. It first determines whether there is an existing ndlp that From 4a4db603d0b7bab41b49f70d39e88c4c7f95dd89 Mon Sep 17 00:00:00 2001 From: Lee Jones Date: Wed, 3 Mar 2021 14:46:27 +0000 Subject: [PATCH 120/412] scsi: libfc: Fix some possible copy/paste issues Fixes the following W=1 kernel build warning(s): drivers/scsi/libfc/fc_lport.c:710: warning: expecting prototype for fc_rport_enter_ready(). Prototype was for fc_lport_enter_ready() instead drivers/scsi/libfc/fc_lport.c:759: warning: expecting prototype for fc_lport_set_port_id(). Prototype was for fc_lport_set_local_id() instead drivers/scsi/libfc/fc_lport.c:1400: warning: expecting prototype for fc_rport_enter_dns(). Prototype was for fc_lport_enter_dns() instead drivers/scsi/libfc/fc_lport.c:1516: warning: expecting prototype for fc_rport_enter_fdmi(). Prototype was for fc_lport_enter_fdmi() instead drivers/scsi/libfc/fc_lport.c:1647: warning: expecting prototype for fc_rport_enter_logo(). Prototype was for fc_lport_enter_logo() instead drivers/scsi/libfc/fc_lport.c:1789: warning: expecting prototype for fc_rport_enter_flogi(). Prototype was for fc_lport_enter_flogi() instead Link: https://lore.kernel.org/r/20210303144631.3175331-27-lee.jones@linaro.org Cc: Hannes Reinecke Cc: "James E.J. Bottomley" Cc: "Martin K. Petersen" Cc: linux-scsi@vger.kernel.org Signed-off-by: Lee Jones Signed-off-by: Martin K. Petersen --- drivers/scsi/libfc/fc_lport.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/drivers/scsi/libfc/fc_lport.c b/drivers/scsi/libfc/fc_lport.c index 22826544da7e..78bd317f0553 100644 --- a/drivers/scsi/libfc/fc_lport.c +++ b/drivers/scsi/libfc/fc_lport.c @@ -703,7 +703,7 @@ static void fc_lport_disc_callback(struct fc_lport *lport, } /** - * fc_rport_enter_ready() - Enter the ready state and start discovery + * fc_lport_enter_ready() - Enter the ready state and start discovery * @lport: The local port that is ready */ static void fc_lport_enter_ready(struct fc_lport *lport) @@ -747,7 +747,7 @@ static void fc_lport_set_port_id(struct fc_lport *lport, u32 port_id, } /** - * fc_lport_set_port_id() - set the local port Port ID for point-to-multipoint + * fc_lport_set_local_id() - set the local port Port ID for point-to-multipoint * @lport: The local port which will have its Port ID set. * @port_id: The new port ID. * @@ -1393,7 +1393,7 @@ static struct fc_rport_operations fc_lport_rport_ops = { }; /** - * fc_rport_enter_dns() - Create a fc_rport for the name server + * fc_lport_enter_dns() - Create a fc_rport for the name server * @lport: The local port requesting a remote port for the name server */ static void fc_lport_enter_dns(struct fc_lport *lport) @@ -1509,7 +1509,7 @@ static void fc_lport_enter_ms(struct fc_lport *lport, enum fc_lport_state state) } /** - * fc_rport_enter_fdmi() - Create a fc_rport for the management server + * fc_lport_enter_fdmi() - Create a fc_rport for the management server * @lport: The local port requesting a remote port for the management server */ static void fc_lport_enter_fdmi(struct fc_lport *lport) @@ -1640,7 +1640,7 @@ err: EXPORT_SYMBOL(fc_lport_logo_resp); /** - * fc_rport_enter_logo() - Logout of the fabric + * fc_lport_enter_logo() - Logout of the fabric * @lport: The local port to be logged out */ static void fc_lport_enter_logo(struct fc_lport *lport) @@ -1782,7 +1782,7 @@ err: EXPORT_SYMBOL(fc_lport_flogi_resp); /** - * fc_rport_enter_flogi() - Send a FLOGI request to the fabric manager + * fc_lport_enter_flogi() - Send a FLOGI request to the fabric manager * @lport: Fibre Channel local port to be logged in to the fabric */ static void fc_lport_enter_flogi(struct fc_lport *lport) From 3884ce1539b0875a2860fd8d2c2d39c2ddcfa35b Mon Sep 17 00:00:00 2001 From: Lee Jones Date: Wed, 3 Mar 2021 14:46:28 +0000 Subject: [PATCH 121/412] scsi: lpfc: Fix incorrect naming of __lpfc_update_fcf_record() Fixes the following W=1 kernel build warning(s): drivers/scsi/lpfc/lpfc_hbadisc.c:1505: warning: expecting prototype for lpfc_update_fcf_record(). Prototype was for __lpfc_update_fcf_record() instead Link: https://lore.kernel.org/r/20210303144631.3175331-28-lee.jones@linaro.org Cc: James Smart Cc: Dick Kennedy Cc: "James E.J. Bottomley" Cc: "Martin K. Petersen" Cc: linux-scsi@vger.kernel.org Signed-off-by: Lee Jones Signed-off-by: Martin K. Petersen --- drivers/scsi/lpfc/lpfc_hbadisc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/scsi/lpfc/lpfc_hbadisc.c b/drivers/scsi/lpfc/lpfc_hbadisc.c index 2d23892b2f0d..3b5cd23dd172 100644 --- a/drivers/scsi/lpfc/lpfc_hbadisc.c +++ b/drivers/scsi/lpfc/lpfc_hbadisc.c @@ -1486,7 +1486,7 @@ lpfc_copy_fcf_record(struct lpfc_fcf_rec *fcf_rec, } /** - * lpfc_update_fcf_record - Update driver fcf record + * __lpfc_update_fcf_record - Update driver fcf record * @phba: pointer to lpfc hba data structure. * @fcf_rec: pointer to driver fcf record. * @new_fcf_record: pointer to hba fcf record. From e015e0ded1351f281202fc1d138fc862ec01d1d4 Mon Sep 17 00:00:00 2001 From: Lee Jones Date: Wed, 3 Mar 2021 14:46:29 +0000 Subject: [PATCH 122/412] scsi: mpt3sas: Fix misspelling of _base_put_smid_default_atomic() Fixes the following W=1 kernel build warning(s): drivers/scsi/mpt3sas/mpt3sas_base.c:4185: warning: expecting prototype for _base_put_smid_default(). Prototype was for _base_put_smid_default_atomic() instead Link: https://lore.kernel.org/r/20210303144631.3175331-29-lee.jones@linaro.org Cc: Sathya Prakash Cc: Sreekanth Reddy Cc: Suganath Prabu Subramani Cc: "James E.J. Bottomley" Cc: "Martin K. Petersen" Cc: MPT-FusionLinux.pdl@avagotech.com Cc: MPT-FusionLinux.pdl@broadcom.com Cc: linux-scsi@vger.kernel.org Signed-off-by: Lee Jones Signed-off-by: Martin K. Petersen --- drivers/scsi/mpt3sas/mpt3sas_base.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/scsi/mpt3sas/mpt3sas_base.c b/drivers/scsi/mpt3sas/mpt3sas_base.c index 504ed856d479..69586ab16cb6 100644 --- a/drivers/scsi/mpt3sas/mpt3sas_base.c +++ b/drivers/scsi/mpt3sas/mpt3sas_base.c @@ -4172,7 +4172,7 @@ _base_put_smid_hi_priority_atomic(struct MPT3SAS_ADAPTER *ioc, u16 smid, } /** - * _base_put_smid_default - Default, primarily used for config pages + * _base_put_smid_default_atomic - Default, primarily used for config pages * use Atomic Request Descriptor * @ioc: per adapter object * @smid: system request message index From 2111ba8781da6067e869329886fc717cbd7d93e2 Mon Sep 17 00:00:00 2001 From: Lee Jones Date: Wed, 3 Mar 2021 14:46:31 +0000 Subject: [PATCH 123/412] scsi: mpt3sas: Move a little data from the stack onto the heap MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fixes the following W=1 kernel build warning(s): drivers/scsi/mpt3sas/mpt3sas_scsih.c: In function ‘_scsih_scan_for_devices_after_reset’: drivers/scsi/mpt3sas/mpt3sas_scsih.c:10473:1: warning: the frame size of 1064 bytes is larger than 1024 bytes [-Wframe-larger-than=] Link: https://lore.kernel.org/r/20210303144631.3175331-31-lee.jones@linaro.org Cc: Sathya Prakash Cc: Sreekanth Reddy Cc: Suganath Prabu Subramani Cc: "James E.J. Bottomley" Cc: "Martin K. Petersen" Cc: MPT-FusionLinux.pdl@avagotech.com Cc: MPT-FusionLinux.pdl@broadcom.com Cc: linux-scsi@vger.kernel.org Signed-off-by: Lee Jones Signed-off-by: Martin K. Petersen --- drivers/scsi/mpt3sas/mpt3sas_scsih.c | 38 +++++++++++++++++++--------- 1 file changed, 26 insertions(+), 12 deletions(-) diff --git a/drivers/scsi/mpt3sas/mpt3sas_scsih.c b/drivers/scsi/mpt3sas/mpt3sas_scsih.c index 7bd0a57e5b92..945531e94d7e 100644 --- a/drivers/scsi/mpt3sas/mpt3sas_scsih.c +++ b/drivers/scsi/mpt3sas/mpt3sas_scsih.c @@ -10219,8 +10219,8 @@ _scsih_scan_for_devices_after_reset(struct MPT3SAS_ADAPTER *ioc) Mpi2ExpanderPage0_t expander_pg0; Mpi2SasDevicePage0_t sas_device_pg0; Mpi26PCIeDevicePage0_t pcie_device_pg0; - Mpi2RaidVolPage1_t volume_pg1; - Mpi2RaidVolPage0_t volume_pg0; + Mpi2RaidVolPage1_t *volume_pg1; + Mpi2RaidVolPage0_t *volume_pg0; Mpi2RaidPhysDiskPage0_t pd_pg0; Mpi2EventIrConfigElement_t element; Mpi2ConfigReply_t mpi_reply; @@ -10235,6 +10235,16 @@ _scsih_scan_for_devices_after_reset(struct MPT3SAS_ADAPTER *ioc) u8 retry_count; unsigned long flags; + volume_pg0 = kzalloc(sizeof(*volume_pg0), GFP_KERNEL); + if (!volume_pg0) + return; + + volume_pg1 = kzalloc(sizeof(*volume_pg1), GFP_KERNEL); + if (!volume_pg1) { + kfree(volume_pg0); + return; + } + ioc_info(ioc, "scan devices: start\n"); _scsih_sas_host_refresh(ioc); @@ -10344,7 +10354,7 @@ _scsih_scan_for_devices_after_reset(struct MPT3SAS_ADAPTER *ioc) /* volumes */ handle = 0xFFFF; while (!(mpt3sas_config_get_raid_volume_pg1(ioc, &mpi_reply, - &volume_pg1, MPI2_RAID_VOLUME_PGAD_FORM_GET_NEXT_HANDLE, handle))) { + volume_pg1, MPI2_RAID_VOLUME_PGAD_FORM_GET_NEXT_HANDLE, handle))) { ioc_status = le16_to_cpu(mpi_reply.IOCStatus) & MPI2_IOCSTATUS_MASK; if (ioc_status != MPI2_IOCSTATUS_SUCCESS) { @@ -10352,15 +10362,15 @@ _scsih_scan_for_devices_after_reset(struct MPT3SAS_ADAPTER *ioc) ioc_status, le32_to_cpu(mpi_reply.IOCLogInfo)); break; } - handle = le16_to_cpu(volume_pg1.DevHandle); + handle = le16_to_cpu(volume_pg1->DevHandle); spin_lock_irqsave(&ioc->raid_device_lock, flags); raid_device = _scsih_raid_device_find_by_wwid(ioc, - le64_to_cpu(volume_pg1.WWID)); + le64_to_cpu(volume_pg1->WWID)); spin_unlock_irqrestore(&ioc->raid_device_lock, flags); if (raid_device) continue; if (mpt3sas_config_get_raid_volume_pg0(ioc, &mpi_reply, - &volume_pg0, MPI2_RAID_VOLUME_PGAD_FORM_HANDLE, handle, + volume_pg0, MPI2_RAID_VOLUME_PGAD_FORM_HANDLE, handle, sizeof(Mpi2RaidVolPage0_t))) continue; ioc_status = le16_to_cpu(mpi_reply.IOCStatus) & @@ -10370,17 +10380,17 @@ _scsih_scan_for_devices_after_reset(struct MPT3SAS_ADAPTER *ioc) ioc_status, le32_to_cpu(mpi_reply.IOCLogInfo)); break; } - if (volume_pg0.VolumeState == MPI2_RAID_VOL_STATE_OPTIMAL || - volume_pg0.VolumeState == MPI2_RAID_VOL_STATE_ONLINE || - volume_pg0.VolumeState == MPI2_RAID_VOL_STATE_DEGRADED) { + if (volume_pg0->VolumeState == MPI2_RAID_VOL_STATE_OPTIMAL || + volume_pg0->VolumeState == MPI2_RAID_VOL_STATE_ONLINE || + volume_pg0->VolumeState == MPI2_RAID_VOL_STATE_DEGRADED) { memset(&element, 0, sizeof(Mpi2EventIrConfigElement_t)); element.ReasonCode = MPI2_EVENT_IR_CHANGE_RC_ADDED; - element.VolDevHandle = volume_pg1.DevHandle; + element.VolDevHandle = volume_pg1->DevHandle; ioc_info(ioc, "\tBEFORE adding volume: handle (0x%04x)\n", - volume_pg1.DevHandle); + volume_pg1->DevHandle); _scsih_sas_volume_add(ioc, &element); ioc_info(ioc, "\tAFTER adding volume: handle (0x%04x)\n", - volume_pg1.DevHandle); + volume_pg1->DevHandle); } } @@ -10468,6 +10478,10 @@ _scsih_scan_for_devices_after_reset(struct MPT3SAS_ADAPTER *ioc) ioc_info(ioc, "\tAFTER adding pcie end device: handle (0x%04x), wwid(0x%016llx)\n", handle, (u64)le64_to_cpu(pcie_device_pg0.WWID)); } + + kfree(volume_pg0); + kfree(volume_pg1); + ioc_info(ioc, "\tpcie devices: pcie end devices complete\n"); ioc_info(ioc, "scan devices: complete\n"); } From cf9e575e62a4c2dbb665490cf35da043890e5751 Mon Sep 17 00:00:00 2001 From: Lee Jones Date: Fri, 12 Mar 2021 09:47:09 +0000 Subject: [PATCH 124/412] scsi: mpt3sas: Fix a bunch of potential naming doc-rot Fixes the following W=1 kernel build warning(s): drivers/scsi/mpt3sas/mpt3sas_config.c:1795: warning: expecting prototype for mpt3sas_config_set_driver_trigger_pg0(). Prototype was for _config_set_driver_trigger_pg0() instead drivers/scsi/mpt3sas/mpt3sas_config.c:1929: warning: expecting prototype for mpt3sas_config_set_driver_trigger_pg1(). Prototype was for _config_set_driver_trigger_pg1() instead drivers/scsi/mpt3sas/mpt3sas_config.c:2080: warning: expecting prototype for mpt3sas_config_set_driver_trigger_pg2(). Prototype was for _config_set_driver_trigger_pg2() instead drivers/scsi/mpt3sas/mpt3sas_config.c:2240: warning: expecting prototype for mpt3sas_config_set_driver_trigger_pg3(). Prototype was for _config_set_driver_trigger_pg3() instead drivers/scsi/mpt3sas/mpt3sas_config.c:2397: warning: expecting prototype for mpt3sas_config_set_driver_trigger_pg4(). Prototype was for _config_set_driver_trigger_pg4() instead Link: https://lore.kernel.org/r/20210312094738.2207817-2-lee.jones@linaro.org Cc: Sathya Prakash Cc: Sreekanth Reddy Cc: Suganath Prabu Subramani Cc: "James E.J. Bottomley" Cc: "Martin K. Petersen" Cc: MPT-FusionLinux.pdl@avagotech.com Cc: MPT-FusionLinux.pdl@broadcom.com Cc: linux-scsi@vger.kernel.org Signed-off-by: Lee Jones Signed-off-by: Martin K. Petersen --- drivers/scsi/mpt3sas/mpt3sas_config.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/drivers/scsi/mpt3sas/mpt3sas_config.c b/drivers/scsi/mpt3sas/mpt3sas_config.c index 8238843523b5..55cd32908924 100644 --- a/drivers/scsi/mpt3sas/mpt3sas_config.c +++ b/drivers/scsi/mpt3sas/mpt3sas_config.c @@ -1781,7 +1781,7 @@ mpt3sas_config_get_driver_trigger_pg0(struct MPT3SAS_ADAPTER *ioc, } /** - * mpt3sas_config_set_driver_trigger_pg0 - write driver trigger page 0 + * _config_set_driver_trigger_pg0 - write driver trigger page 0 * @ioc: per adapter object * @mpi_reply: reply mf payload returned from firmware * @config_page: contents of the config page @@ -1915,7 +1915,7 @@ mpt3sas_config_get_driver_trigger_pg1(struct MPT3SAS_ADAPTER *ioc, } /** - * mpt3sas_config_set_driver_trigger_pg1 - write driver trigger page 1 + * _config_set_driver_trigger_pg1 - write driver trigger page 1 * @ioc: per adapter object * @mpi_reply: reply mf payload returned from firmware * @config_page: contents of the config page @@ -2066,7 +2066,7 @@ mpt3sas_config_get_driver_trigger_pg2(struct MPT3SAS_ADAPTER *ioc, } /** - * mpt3sas_config_set_driver_trigger_pg2 - write driver trigger page 2 + * _config_set_driver_trigger_pg2 - write driver trigger page 2 * @ioc: per adapter object * @mpi_reply: reply mf payload returned from firmware * @config_page: contents of the config page @@ -2226,7 +2226,7 @@ mpt3sas_config_get_driver_trigger_pg3(struct MPT3SAS_ADAPTER *ioc, } /** - * mpt3sas_config_set_driver_trigger_pg3 - write driver trigger page 3 + * _config_set_driver_trigger_pg3 - write driver trigger page 3 * @ioc: per adapter object * @mpi_reply: reply mf payload returned from firmware * @config_page: contents of the config page @@ -2383,7 +2383,7 @@ mpt3sas_config_get_driver_trigger_pg4(struct MPT3SAS_ADAPTER *ioc, } /** - * mpt3sas_config_set_driver_trigger_pg4 - write driver trigger page 4 + * _config_set_driver_trigger_pg4 - write driver trigger page 4 * @ioc: per adapter object * @mpi_reply: reply mf payload returned from firmware * @config_page: contents of the config page From 11eea9b3fd4d424fcfc1acbb4ae5c25c21fb6edb Mon Sep 17 00:00:00 2001 From: Lee Jones Date: Fri, 12 Mar 2021 09:47:10 +0000 Subject: [PATCH 125/412] scsi: ufs: core: Fix incorrectly named ufshcd_find_max_sup_active_icc_level() Fixes the following W=1 kernel build warning(s): drivers/scsi/ufs/ufshcd.c:7142: warning: expecting prototype for ufshcd_calc_icc_level(). Prototype was for ufshcd_find_max_sup_active_icc_level() instead Link: https://lore.kernel.org/r/20210312094738.2207817-3-lee.jones@linaro.org Cc: Alim Akhtar Cc: Avri Altman Cc: "James E.J. Bottomley" Cc: "Martin K. Petersen" Cc: Santosh Yaraganavi Cc: Vinayak Holikatti Cc: linux-scsi@vger.kernel.org Signed-off-by: Lee Jones Signed-off-by: Martin K. Petersen --- drivers/scsi/ufs/ufshcd.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/scsi/ufs/ufshcd.c b/drivers/scsi/ufs/ufshcd.c index 8c0ff024231c..18b5d888e9de 100644 --- a/drivers/scsi/ufs/ufshcd.c +++ b/drivers/scsi/ufs/ufshcd.c @@ -7143,7 +7143,7 @@ static u32 ufshcd_get_max_icc_level(int sup_curr_uA, u32 start_scan, char *buff) } /** - * ufshcd_calc_icc_level - calculate the max ICC level + * ufshcd_find_max_sup_active_icc_level - calculate the max ICC level * In case regulators are not initialized we'll return 0 * @hba: per-adapter instance * @desc_buf: power descriptor buffer to extract ICC levels from. From 0bb87e01d81575bf6b0007752e637f3253410553 Mon Sep 17 00:00:00 2001 From: Lee Jones Date: Fri, 12 Mar 2021 09:47:11 +0000 Subject: [PATCH 126/412] scsi: lpfc: Fix a bunch of kernel-doc misdemeanours Fixes the following W=1 kernel build warning(s): drivers/scsi/lpfc/lpfc_scsi.c:746: warning: expecting prototype for lpfc_release_scsi_buf(). Prototype was for lpfc_release_scsi_buf_s3() instead drivers/scsi/lpfc/lpfc_scsi.c:979: warning: expecting prototype for App checking is required for(). Prototype was for BG_ERR_CHECK() instead drivers/scsi/lpfc/lpfc_scsi.c:3701: warning: Function parameter or member 'vport' not described in 'lpfc_scsi_prep_cmnd_buf' drivers/scsi/lpfc/lpfc_scsi.c:3701: warning: Excess function parameter 'phba' description in 'lpfc_scsi_prep_cmnd_buf' drivers/scsi/lpfc/lpfc_scsi.c:3717: warning: Function parameter or member 'fcpi_parm' not described in 'lpfc_send_scsi_error_event' drivers/scsi/lpfc/lpfc_scsi.c:3717: warning: Excess function parameter 'rsp_iocb' description in 'lpfc_send_scsi_error_event' drivers/scsi/lpfc/lpfc_scsi.c:3837: warning: Function parameter or member 'fcpi_parm' not described in 'lpfc_handle_fcp_err' drivers/scsi/lpfc/lpfc_scsi.c:3837: warning: expecting prototype for lpfc_handler_fcp_err(). Prototype was for lpfc_handle_fcp_err() instead drivers/scsi/lpfc/lpfc_scsi.c:4021: warning: Function parameter or member 'wcqe' not described in 'lpfc_fcp_io_cmd_wqe_cmpl' drivers/scsi/lpfc/lpfc_scsi.c:4021: warning: Excess function parameter 'pwqeOut' description in 'lpfc_fcp_io_cmd_wqe_cmpl' drivers/scsi/lpfc/lpfc_scsi.c:4621: warning: Function parameter or member 'vport' not described in 'lpfc_scsi_prep_cmnd_buf_s3' drivers/scsi/lpfc/lpfc_scsi.c:4621: warning: Excess function parameter 'phba' description in 'lpfc_scsi_prep_cmnd_buf_s3' drivers/scsi/lpfc/lpfc_scsi.c:4698: warning: Function parameter or member 'vport' not described in 'lpfc_scsi_prep_cmnd_buf_s4' drivers/scsi/lpfc/lpfc_scsi.c:4698: warning: Excess function parameter 'phba' description in 'lpfc_scsi_prep_cmnd_buf_s4' drivers/scsi/lpfc/lpfc_scsi.c:4954: warning: expecting prototype for lpfc_taskmgmt_def_cmpl(). Prototype was for lpfc_tskmgmt_def_cmpl() instead drivers/scsi/lpfc/lpfc_scsi.c:5094: warning: expecting prototype for lpfc_poll_rearm_time(). Prototype was for lpfc_poll_rearm_timer() instead Link: https://lore.kernel.org/r/20210312094738.2207817-4-lee.jones@linaro.org Cc: James Smart Cc: Dick Kennedy Cc: "James E.J. Bottomley" Cc: "Martin K. Petersen" Cc: linux-scsi@vger.kernel.org Signed-off-by: Lee Jones Signed-off-by: Martin K. Petersen --- drivers/scsi/lpfc/lpfc_scsi.c | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/drivers/scsi/lpfc/lpfc_scsi.c b/drivers/scsi/lpfc/lpfc_scsi.c index f0caf923f38c..85f6a066de5a 100644 --- a/drivers/scsi/lpfc/lpfc_scsi.c +++ b/drivers/scsi/lpfc/lpfc_scsi.c @@ -736,7 +736,7 @@ lpfc_get_scsi_buf(struct lpfc_hba *phba, struct lpfc_nodelist *ndlp, } /** - * lpfc_release_scsi_buf - Return a scsi buffer back to hba scsi buf list + * lpfc_release_scsi_buf_s3 - Return a scsi buffer back to hba scsi buf list * @phba: The Hba for which this call is being executed. * @psb: The scsi buffer which is being released. * @@ -974,10 +974,10 @@ lpfc_scsi_prep_dma_buf_s3(struct lpfc_hba *phba, struct lpfc_io_buf *lpfc_cmd) #define BG_ERR_TGT 0x2 /* Return BG_ERR_SWAP if swapping CSUM<-->CRC is required for error injection */ #define BG_ERR_SWAP 0x10 -/** +/* * Return BG_ERR_CHECK if disabling Guard/Ref/App checking is required for * error injection - **/ + */ #define BG_ERR_CHECK 0x20 /** @@ -3699,7 +3699,7 @@ lpfc_bg_scsi_prep_dma_buf(struct lpfc_hba *phba, struct lpfc_io_buf *lpfc_cmd) /** * lpfc_scsi_prep_cmnd_buf - Wrapper function for IOCB/WQE mapping of scsi * buffer - * @phba: The Hba for which this call is being executed. + * @vport: Pointer to vport object. * @lpfc_cmd: The scsi buffer which is going to be mapped. * @tmo: Timeout value for IO * @@ -3721,7 +3721,7 @@ lpfc_scsi_prep_cmnd_buf(struct lpfc_vport *vport, struct lpfc_io_buf *lpfc_cmd, * @phba: Pointer to hba context object. * @vport: Pointer to vport object. * @lpfc_cmd: Pointer to lpfc scsi command which reported the error. - * @rsp_iocb: Pointer to response iocb object which reported error. + * @fcpi_parm: FCP Initiator parameter. * * This function posts an event when there is a SCSI command reporting * error from the scsi device. @@ -3836,10 +3836,10 @@ lpfc_scsi_unprep_dma_buf(struct lpfc_hba *phba, struct lpfc_io_buf *psb) } /** - * lpfc_handler_fcp_err - FCP response handler + * lpfc_handle_fcp_err - FCP response handler * @vport: The virtual port for which this call is being executed. * @lpfc_cmd: Pointer to lpfc_io_buf data structure. - * @rsp_iocb: The response IOCB which contains FCP error. + * @fcpi_parm: FCP Initiator parameter. * * This routine is called to process response IOCB with status field * IOSTAT_FCP_RSP_ERROR. This routine sets result field of scsi command @@ -4023,7 +4023,7 @@ lpfc_handle_fcp_err(struct lpfc_vport *vport, struct lpfc_io_buf *lpfc_cmd, * lpfc_fcp_io_cmd_wqe_cmpl - Complete a FCP IO * @phba: The hba for which this call is being executed. * @pwqeIn: The command WQE for the scsi cmnd. - * @pwqeOut: The response WQE for the scsi cmnd. + * @wcqe: Pointer to driver response CQE object. * * This routine assigns scsi command result by looking into response WQE * status field appropriately. This routine handles QUEUE FULL condition as @@ -4619,7 +4619,7 @@ lpfc_scsi_cmd_iocb_cmpl(struct lpfc_hba *phba, struct lpfc_iocbq *pIocbIn, /** * lpfc_scsi_prep_cmnd_buf_s3 - SLI-3 IOCB init for the IO - * @phba: Pointer to vport object for which I/O is executed + * @vport: Pointer to vport object. * @lpfc_cmd: The scsi buffer which is going to be prep'ed. * @tmo: timeout value for the IO * @@ -4696,7 +4696,7 @@ static int lpfc_scsi_prep_cmnd_buf_s3(struct lpfc_vport *vport, /** * lpfc_scsi_prep_cmnd_buf_s4 - SLI-4 WQE init for the IO - * @phba: Pointer to vport object for which I/O is executed + * @vport: Pointer to vport object. * @lpfc_cmd: The scsi buffer which is going to be prep'ed. * @tmo: timeout value for the IO * @@ -4953,7 +4953,7 @@ lpfc_scsi_api_table_setup(struct lpfc_hba *phba, uint8_t dev_grp) } /** - * lpfc_taskmgmt_def_cmpl - IOCB completion routine for task management command + * lpfc_tskmgmt_def_cmpl - IOCB completion routine for task management command * @phba: The Hba for which this call is being executed. * @cmdiocbq: Pointer to lpfc_iocbq data structure. * @rspiocbq: Pointer to lpfc_iocbq data structure. @@ -5098,7 +5098,7 @@ buffer_done: } /** - * lpfc_poll_rearm_time - Routine to modify fcp_poll timer of hba + * lpfc_poll_rearm_timer - Routine to modify fcp_poll timer of hba * @phba: The Hba for which this call is being executed. * * This routine modifies fcp_poll_timer field of @phba by cfg_poll_tmo. From a3dbf5145d01cdb41b726283afa10a6ff8b0977c Mon Sep 17 00:00:00 2001 From: Lee Jones Date: Fri, 12 Mar 2021 09:47:12 +0000 Subject: [PATCH 127/412] scsi: lpfc: Fix a bunch of misnamed functions Fixes the following W=1 kernel build warning(s): drivers/scsi/lpfc/lpfc_attr.c:880: warning: expecting prototype for lpfc_state_show(). Prototype was for lpfc_link_state_show() instead drivers/scsi/lpfc/lpfc_attr.c:3834: warning: expecting prototype for lpfc_tgt_queue_depth_store(). Prototype was for lpfc_tgt_queue_depth_set() instead drivers/scsi/lpfc/lpfc_attr.c:4027: warning: expecting prototype for lpfc_topology_set(). Prototype was for lpfc_topology_store() instead drivers/scsi/lpfc/lpfc_attr.c:4481: warning: expecting prototype for lpfc_link_speed_set(). Prototype was for lpfc_link_speed_store() instead drivers/scsi/lpfc/lpfc_attr.c:4879: warning: expecting prototype for lpfc_request_firmware_store(). Prototype was for lpfc_request_firmware_upgrade_store() instead drivers/scsi/lpfc/lpfc_attr.c:5235: warning: expecting prototype for lpfc_state_show(). Prototype was for lpfc_fcp_cpu_map_show() instead Link: https://lore.kernel.org/r/20210312094738.2207817-5-lee.jones@linaro.org Cc: James Smart Cc: Dick Kennedy Cc: "James E.J. Bottomley" Cc: "Martin K. Petersen" Cc: linux-scsi@vger.kernel.org Signed-off-by: Lee Jones Signed-off-by: Martin K. Petersen --- drivers/scsi/lpfc/lpfc_attr.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/drivers/scsi/lpfc/lpfc_attr.c b/drivers/scsi/lpfc/lpfc_attr.c index 98594d6bc26b..8b4c42016865 100644 --- a/drivers/scsi/lpfc/lpfc_attr.c +++ b/drivers/scsi/lpfc/lpfc_attr.c @@ -864,7 +864,7 @@ lpfc_option_rom_version_show(struct device *dev, struct device_attribute *attr, } /** - * lpfc_state_show - Return the link state of the port + * lpfc_link_state_show - Return the link state of the port * @dev: class converted to a Scsi_host structure. * @attr: device attribute, not used. * @buf: on return contains text describing the state of the link. @@ -3819,7 +3819,7 @@ lpfc_vport_param_init(tgt_queue_depth, LPFC_MAX_TGT_QDEPTH, LPFC_MIN_TGT_QDEPTH, LPFC_MAX_TGT_QDEPTH); /** - * lpfc_tgt_queue_depth_store: Sets an attribute value. + * lpfc_tgt_queue_depth_set: Sets an attribute value. * @vport: lpfc vport structure pointer. * @val: integer attribute value. * @@ -4004,7 +4004,7 @@ LPFC_ATTR(topology, 0, 0, 6, "Select Fibre Channel topology"); /** - * lpfc_topology_set - Set the adapters topology field + * lpfc_topology_store - Set the adapters topology field * @dev: class device that is converted into a scsi_host. * @attr:device attribute, not used. * @buf: buffer for passing information. @@ -4457,7 +4457,7 @@ static struct bin_attribute sysfs_drvr_stat_data_attr = { # Value range is [0,16]. Default value is 0. */ /** - * lpfc_link_speed_set - Set the adapters link speed + * lpfc_link_speed_store - Set the adapters link speed * @dev: Pointer to class device. * @attr: Unused. * @buf: Data buffer. @@ -4858,7 +4858,7 @@ lpfc_param_show(sriov_nr_virtfn) static DEVICE_ATTR_RW(lpfc_sriov_nr_virtfn); /** - * lpfc_request_firmware_store - Request for Linux generic firmware upgrade + * lpfc_request_firmware_upgrade_store - Request for Linux generic firmware upgrade * * @dev: class device that is converted into a Scsi_host. * @attr: device attribute, not used. @@ -5222,7 +5222,7 @@ lpfc_cq_max_proc_limit_init(struct lpfc_hba *phba, int val) static DEVICE_ATTR_RW(lpfc_cq_max_proc_limit); /** - * lpfc_state_show - Display current driver CPU affinity + * lpfc_fcp_cpu_map_show - Display current driver CPU affinity * @dev: class converted to a Scsi_host structure. * @attr: device attribute, not used. * @buf: on return contains text describing the state of the link. From 0dbea7c188739b6a38d940fb12694c485eb1a8b1 Mon Sep 17 00:00:00 2001 From: Lee Jones Date: Fri, 12 Mar 2021 09:47:13 +0000 Subject: [PATCH 128/412] scsi: libfc: Fix incorrect naming of fc_rport_adisc_resp() Fixes the following W=1 kernel build warning(s): drivers/scsi/libfc/fc_rport.c:1500: warning: expecting prototype for fc_rport_els_adisc_resp(). Prototype was for fc_rport_adisc_resp() instead Link: https://lore.kernel.org/r/20210312094738.2207817-6-lee.jones@linaro.org Cc: Hannes Reinecke Cc: "James E.J. Bottomley" Cc: "Martin K. Petersen" Cc: linux-scsi@vger.kernel.org Signed-off-by: Lee Jones Signed-off-by: Martin K. Petersen --- drivers/scsi/libfc/fc_rport.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/scsi/libfc/fc_rport.c b/drivers/scsi/libfc/fc_rport.c index 56003208d2e7..cd0fb8ca2425 100644 --- a/drivers/scsi/libfc/fc_rport.c +++ b/drivers/scsi/libfc/fc_rport.c @@ -1486,7 +1486,7 @@ static void fc_rport_enter_logo(struct fc_rport_priv *rdata) } /** - * fc_rport_els_adisc_resp() - Handler for Address Discovery (ADISC) responses + * fc_rport_adisc_resp() - Handler for Address Discovery (ADISC) responses * @sp: The sequence the ADISC response was on * @fp: The ADISC response frame * @rdata_arg: The remote port that sent the ADISC response From 54cb88dc3083e5dbdba48600de6a6542c48a3e13 Mon Sep 17 00:00:00 2001 From: Lee Jones Date: Fri, 12 Mar 2021 09:47:14 +0000 Subject: [PATCH 129/412] scsi: mpt3sas: Fix a couple of misdocumented functions/params Fixes the following W=1 kernel build warning(s): drivers/scsi/mpt3sas/mpt3sas_transport.c:71: warning: Function parameter or member 'phy' not described in '_transport_get_port_id_by_sas_phy' drivers/scsi/mpt3sas/mpt3sas_transport.c:354: warning: Function parameter or member 'port_id' not described in '_transport_expander_report_manufacture' drivers/scsi/mpt3sas/mpt3sas_transport.c:354: warning: expecting prototype for transport_expander_report_manufacture(). Prototype was for _transport_expander_report_manufacture() instead drivers/scsi/mpt3sas/mpt3sas_transport.c:684: warning: Function parameter or member 'hba_port' not described in 'mpt3sas_transport_port_add' drivers/scsi/mpt3sas/mpt3sas_transport.c:684: warning: Excess function parameter 'port' description in 'mpt3sas_transport_port_add' Link: https://lore.kernel.org/r/20210312094738.2207817-7-lee.jones@linaro.org Cc: Sathya Prakash Cc: Sreekanth Reddy Cc: Suganath Prabu Subramani Cc: "James E.J. Bottomley" Cc: "Martin K. Petersen" Cc: MPT-FusionLinux.pdl@avagotech.com Cc: MPT-FusionLinux.pdl@broadcom.com Cc: linux-scsi@vger.kernel.org Signed-off-by: Lee Jones Signed-off-by: Martin K. Petersen --- drivers/scsi/mpt3sas/mpt3sas_transport.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/drivers/scsi/mpt3sas/mpt3sas_transport.c b/drivers/scsi/mpt3sas/mpt3sas_transport.c index 6f4708224755..0681daee6c14 100644 --- a/drivers/scsi/mpt3sas/mpt3sas_transport.c +++ b/drivers/scsi/mpt3sas/mpt3sas_transport.c @@ -62,7 +62,7 @@ /** * _transport_get_port_id_by_sas_phy - get zone's port id that Phy belong to - * @phy - sas_phy object + * @phy: sas_phy object * * Return Port number */ @@ -339,10 +339,11 @@ struct rep_manu_reply { }; /** - * transport_expander_report_manufacture - obtain SMP report_manufacture + * _transport_expander_report_manufacture - obtain SMP report_manufacture * @ioc: per adapter object * @sas_address: expander sas address * @edev: the sas_expander_device object + * @port_id: Port ID number * * Fills in the sas_expander_device object when SMP port is created. * @@ -671,7 +672,7 @@ _transport_sanity_check(struct MPT3SAS_ADAPTER *ioc, struct _sas_node *sas_node, * @ioc: per adapter object * @handle: handle of attached device * @sas_address: sas address of parent expander or sas host - * @port: hba port entry + * @hba_port: hba port entry * Context: This function will acquire ioc->sas_node_lock. * * Adding new port object to the sas_node->sas_port_list. From 775b4d65a6fb539d0e1e7a9028279bd0821dbd94 Mon Sep 17 00:00:00 2001 From: Lee Jones Date: Fri, 12 Mar 2021 09:47:15 +0000 Subject: [PATCH 130/412] scsi: libfc: Fix misspelling of fc_fcp_destroy() Fixes the following W=1 kernel build warning(s): drivers/scsi/libfc/fc_fcp.c:2255: warning: expecting prototype for fc_fcp_destory(). Prototype was for fc_fcp_destroy() instead Link: https://lore.kernel.org/r/20210312094738.2207817-8-lee.jones@linaro.org Cc: Hannes Reinecke Cc: "James E.J. Bottomley" Cc: "Martin K. Petersen" Cc: linux-scsi@vger.kernel.org Signed-off-by: Lee Jones Signed-off-by: Martin K. Petersen --- drivers/scsi/libfc/fc_fcp.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/scsi/libfc/fc_fcp.c b/drivers/scsi/libfc/fc_fcp.c index b43b5f62ee3e..509eacd7893d 100644 --- a/drivers/scsi/libfc/fc_fcp.c +++ b/drivers/scsi/libfc/fc_fcp.c @@ -2248,7 +2248,7 @@ int fc_slave_alloc(struct scsi_device *sdev) EXPORT_SYMBOL(fc_slave_alloc); /** - * fc_fcp_destory() - Tear down the FCP layer for a given local port + * fc_fcp_destroy() - Tear down the FCP layer for a given local port * @lport: The local port that no longer needs the FCP layer */ void fc_fcp_destroy(struct fc_lport *lport) From 381095668d51387657e456e2962f0bcc3e1044e3 Mon Sep 17 00:00:00 2001 From: Lee Jones Date: Fri, 12 Mar 2021 09:47:16 +0000 Subject: [PATCH 131/412] scsi: qla2xxx: Fix a couple of misnamed functions Fixes the following W=1 kernel build warning(s): drivers/scsi/qla2xxx/qla_mr.c:525: warning: expecting prototype for qlafx00_warm_reset(). Prototype was for qlafx00_soc_cpu_reset() instead drivers/scsi/qla2xxx/qla_mr.c:2869: warning: expecting prototype for qlafx00x_mbx_completion(). Prototype was for qlafx00_mbx_completion() instead Link: https://lore.kernel.org/r/20210312094738.2207817-9-lee.jones@linaro.org Cc: Nilesh Javali Cc: GR-QLogic-Storage-Upstream@marvell.com Cc: "James E.J. Bottomley" Cc: "Martin K. Petersen" Cc: linux-scsi@vger.kernel.org Signed-off-by: Lee Jones Signed-off-by: Martin K. Petersen --- drivers/scsi/qla2xxx/qla_mr.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/scsi/qla2xxx/qla_mr.c b/drivers/scsi/qla2xxx/qla_mr.c index ca7306685325..d488ae95e149 100644 --- a/drivers/scsi/qla2xxx/qla_mr.c +++ b/drivers/scsi/qla2xxx/qla_mr.c @@ -516,7 +516,7 @@ qlafx00_pci_config(scsi_qla_host_t *vha) } /** - * qlafx00_warm_reset() - Perform warm reset of iSA(CPUs being reset on SOC). + * qlafx00_soc_cpu_reset() - Perform warm reset of iSA(CPUs being reset on SOC). * @vha: HA context * */ @@ -2860,7 +2860,7 @@ qlafx00_async_event(scsi_qla_host_t *vha) } /** - * qlafx00x_mbx_completion() - Process mailbox command completions. + * qlafx00_mbx_completion() - Process mailbox command completions. * @vha: SCSI driver HA context * @mb0: value to be written into mailbox register 0 */ From 782a1ab33f71b898497b2d035a056e5e198df82b Mon Sep 17 00:00:00 2001 From: Lee Jones Date: Fri, 12 Mar 2021 09:47:17 +0000 Subject: [PATCH 132/412] scsi: mpt3sas: Fix some kernel-doc misnaming issues Fixes the following W=1 kernel build warning(s): drivers/scsi/mpt3sas/mpt3sas_ctl.c:463: warning: expecting prototype for mpt3sas_ctl_reset_handler(). Prototype was for mpt3sas_ctl_pre_reset_handler() instead drivers/scsi/mpt3sas/mpt3sas_ctl.c:495: warning: expecting prototype for mpt3sas_ctl_reset_handler(). Prototype was for mpt3sas_ctl_clear_outstanding_ioctls() instead drivers/scsi/mpt3sas/mpt3sas_ctl.c:512: warning: expecting prototype for mpt3sas_ctl_reset_handler(). Prototype was for mpt3sas_ctl_reset_done_handler() instead drivers/scsi/mpt3sas/mpt3sas_ctl.c:2771: warning: expecting prototype for _ ctl_ioctl_compat(). Prototype was for _ctl_ioctl_compat() instead drivers/scsi/mpt3sas/mpt3sas_ctl.c:2789: warning: expecting prototype for _ ctl_mpt2_ioctl_compat(). Prototype was for _ctl_mpt2_ioctl_compat() instead drivers/scsi/mpt3sas/mpt3sas_ctl.c:3061: warning: expecting prototype for sas_address_show(). Prototype was for host_sas_address_show() instead drivers/scsi/mpt3sas/mpt3sas_ctl.c:3682: warning: expecting prototype for diag_trigger_scsi_show(). Prototype was for diag_trigger_mpi_show() instead drivers/scsi/mpt3sas/mpt3sas_ctl.c:3941: warning: expecting prototype for sas_ncq_io_prio_show(). Prototype was for sas_ncq_prio_enable_show() instead Link: https://lore.kernel.org/r/20210312094738.2207817-10-lee.jones@linaro.org Cc: Sathya Prakash Cc: Sreekanth Reddy Cc: Suganath Prabu Subramani Cc: "James E.J. Bottomley" Cc: "Martin K. Petersen" Cc: MPT-FusionLinux.pdl@avagotech.com Cc: MPT-FusionLinux.pdl@broadcom.com Cc: linux-scsi@vger.kernel.org Signed-off-by: Lee Jones Signed-off-by: Martin K. Petersen --- drivers/scsi/mpt3sas/mpt3sas_ctl.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/drivers/scsi/mpt3sas/mpt3sas_ctl.c b/drivers/scsi/mpt3sas/mpt3sas_ctl.c index 44f9a05db94e..8717412b8079 100644 --- a/drivers/scsi/mpt3sas/mpt3sas_ctl.c +++ b/drivers/scsi/mpt3sas/mpt3sas_ctl.c @@ -454,7 +454,7 @@ out: } /** - * mpt3sas_ctl_reset_handler - reset callback handler (for ctl) + * mpt3sas_ctl_pre_reset_handler - reset callback handler (for ctl) * @ioc: per adapter object * * The handler for doing any required cleanup or initialization. @@ -486,7 +486,7 @@ void mpt3sas_ctl_pre_reset_handler(struct MPT3SAS_ADAPTER *ioc) } /** - * mpt3sas_ctl_reset_handler - clears outstanding ioctl cmd. + * mpt3sas_ctl_clear_outstanding_ioctls - clears outstanding ioctl cmd. * @ioc: per adapter object * * The handler for doing any required cleanup or initialization. @@ -503,7 +503,7 @@ void mpt3sas_ctl_clear_outstanding_ioctls(struct MPT3SAS_ADAPTER *ioc) } /** - * mpt3sas_ctl_reset_handler - reset callback handler (for ctl) + * mpt3sas_ctl_reset_done_handler - reset callback handler (for ctl) * @ioc: per adapter object * * The handler for doing any required cleanup or initialization. @@ -2759,7 +2759,7 @@ _ctl_mpt2_ioctl(struct file *file, unsigned int cmd, unsigned long arg) } #ifdef CONFIG_COMPAT /** - *_ ctl_ioctl_compat - main ioctl entry point (compat) + * _ctl_ioctl_compat - main ioctl entry point (compat) * @file: ? * @cmd: ? * @arg: ? @@ -2777,7 +2777,7 @@ _ctl_ioctl_compat(struct file *file, unsigned cmd, unsigned long arg) } /** - *_ ctl_mpt2_ioctl_compat - main ioctl entry point (compat) + * _ctl_mpt2_ioctl_compat - main ioctl entry point (compat) * @file: ? * @cmd: ? * @arg: ? @@ -3045,7 +3045,7 @@ fw_queue_depth_show(struct device *cdev, struct device_attribute *attr, static DEVICE_ATTR_RO(fw_queue_depth); /** - * sas_address_show - sas address + * host_sas_address_show - sas address * @cdev: pointer to embedded class device * @attr: ? * @buf: the buffer returned @@ -3669,7 +3669,7 @@ static DEVICE_ATTR_RW(diag_trigger_scsi); /** - * diag_trigger_scsi_show - show the diag_trigger_mpi attribute + * diag_trigger_mpi_show - show the diag_trigger_mpi attribute * @cdev: pointer to embedded class device * @attr: ? * @buf: the buffer returned @@ -3928,7 +3928,7 @@ sas_device_handle_show(struct device *dev, struct device_attribute *attr, static DEVICE_ATTR_RO(sas_device_handle); /** - * sas_ncq_io_prio_show - send prioritized io commands to device + * sas_ncq_prio_enable_show - send prioritized io commands to device * @dev: pointer to embedded device * @attr: ? * @buf: the buffer returned From a736e44904422ade7af4ac50c64f58617ae4b7ba Mon Sep 17 00:00:00 2001 From: Lee Jones Date: Fri, 12 Mar 2021 09:47:18 +0000 Subject: [PATCH 133/412] scsi: qla2xxx: Fix incorrectly named function qla8044_check_temp() Fixes the following W=1 kernel build warning(s): drivers/scsi/qla2xxx/qla_nx2.c:2038: warning: expecting prototype for qla4_8xxx_check_temp(). Prototype was for qla8044_check_temp() instead Link: https://lore.kernel.org/r/20210312094738.2207817-11-lee.jones@linaro.org Cc: Nilesh Javali Cc: GR-QLogic-Storage-Upstream@marvell.com Cc: "James E.J. Bottomley" Cc: "Martin K. Petersen" Cc: linux-scsi@vger.kernel.org Signed-off-by: Lee Jones Signed-off-by: Martin K. Petersen --- drivers/scsi/qla2xxx/qla_nx2.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/scsi/qla2xxx/qla_nx2.c b/drivers/scsi/qla2xxx/qla_nx2.c index 68a16c95dcb7..7c413f93d53e 100644 --- a/drivers/scsi/qla2xxx/qla_nx2.c +++ b/drivers/scsi/qla2xxx/qla_nx2.c @@ -2028,7 +2028,7 @@ exit_error: } /** - * qla4_8xxx_check_temp - Check the ISP82XX temperature. + * qla8044_check_temp - Check the ISP82XX temperature. * @vha: adapter block pointer. * * Note: The caller should not hold the idc lock. From dc49ab48a77c48b3334ec57c2163f92721b06b5e Mon Sep 17 00:00:00 2001 From: Lee Jones Date: Fri, 12 Mar 2021 09:47:19 +0000 Subject: [PATCH 134/412] scsi: qla2xxx: Fix a couple of misdocumented functions Fixes the following W=1 kernel build warning(s): drivers/scsi/qla2xxx/qla_target.c:6476: warning: expecting prototype for qla_tgt_lport_register(). Prototype was for qlt_lport_register() instead drivers/scsi/qla2xxx/qla_target.c:6546: warning: expecting prototype for qla_tgt_lport_deregister(). Prototype was for qlt_lport_deregister() instead Link: https://lore.kernel.org/r/20210312094738.2207817-12-lee.jones@linaro.org Cc: Nilesh Javali Cc: GR-QLogic-Storage-Upstream@marvell.com Cc: "James E.J. Bottomley" Cc: "Martin K. Petersen" Cc: Vladislav Bolkhovitin Cc: Nathaniel Clark Cc: "Nicholas A. Bellinger" Cc: linux-scsi@vger.kernel.org Signed-off-by: Lee Jones Signed-off-by: Martin K. Petersen --- drivers/scsi/qla2xxx/qla_target.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/scsi/qla2xxx/qla_target.c b/drivers/scsi/qla2xxx/qla_target.c index c48daf52725d..67c6a2710360 100644 --- a/drivers/scsi/qla2xxx/qla_target.c +++ b/drivers/scsi/qla2xxx/qla_target.c @@ -6462,7 +6462,7 @@ static void qlt_lport_dump(struct scsi_qla_host *vha, u64 wwpn, } /** - * qla_tgt_lport_register - register lport with external module + * qlt_lport_register - register lport with external module * * @target_lport_ptr: pointer for tcm_qla2xxx specific lport data * @phys_wwpn: physical port WWPN @@ -6538,7 +6538,7 @@ int qlt_lport_register(void *target_lport_ptr, u64 phys_wwpn, EXPORT_SYMBOL(qlt_lport_register); /** - * qla_tgt_lport_deregister - Degister lport + * qlt_lport_deregister - Degister lport * * @vha: Registered scsi_qla_host pointer */ From 2c6400b7824323326e591d42ab2620d0b7b90b0b Mon Sep 17 00:00:00 2001 From: Lee Jones Date: Fri, 12 Mar 2021 09:47:20 +0000 Subject: [PATCH 135/412] scsi: lpfc: Fix incorrectly documented function lpfc_debugfs_commonxripools_data() Fixes the following W=1 kernel build warning(s): drivers/scsi/lpfc/lpfc_debugfs.c:405: warning: expecting prototype for lpfc_debugfs_common_xri_data(). Prototype was for lpfc_debugfs_commonxripools_data() instead Link: https://lore.kernel.org/r/20210312094738.2207817-13-lee.jones@linaro.org Cc: James Smart Cc: Dick Kennedy Cc: "James E.J. Bottomley" Cc: "Martin K. Petersen" Cc: linux-scsi@vger.kernel.org Signed-off-by: Lee Jones Signed-off-by: Martin K. Petersen --- drivers/scsi/lpfc/lpfc_debugfs.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/scsi/lpfc/lpfc_debugfs.c b/drivers/scsi/lpfc/lpfc_debugfs.c index ec5328f7f1d4..c23a535ac89a 100644 --- a/drivers/scsi/lpfc/lpfc_debugfs.c +++ b/drivers/scsi/lpfc/lpfc_debugfs.c @@ -381,7 +381,7 @@ skipit: static int lpfc_debugfs_last_xripool; /** - * lpfc_debugfs_common_xri_data - Dump Hardware Queue info to a buffer + * lpfc_debugfs_commonxripools_data - Dump Hardware Queue info to a buffer * @phba: The HBA to gather host buffer info from. * @buf: The buffer to dump log into. * @size: The maximum amount of data to process. From 3145d2d69e1600d924aaf23199e63995b1ea108b Mon Sep 17 00:00:00 2001 From: Lee Jones Date: Fri, 12 Mar 2021 09:47:21 +0000 Subject: [PATCH 136/412] scsi: lpfc: Fix a few incorrectly named functions Fixes the following W=1 kernel build warning(s): drivers/scsi/lpfc/lpfc_bsg.c:3591: warning: expecting prototype for lpfc_bsg_mbox_ext_cleanup(). Prototype was for lpfc_bsg_mbox_ext_session_reset() instead drivers/scsi/lpfc/lpfc_bsg.c:3885: warning: expecting prototype for lpfc_bsg_sli_cfg_mse_read_cmd_ext(). Prototype was for lpfc_bsg_sli_cfg_read_cmd_ext() instead drivers/scsi/lpfc/lpfc_bsg.c:4371: warning: expecting prototype for lpfc_bsg_mbox_ext_abort_req(). Prototype was for lpfc_bsg_mbox_ext_abort() instead Link: https://lore.kernel.org/r/20210312094738.2207817-14-lee.jones@linaro.org Cc: James Smart Cc: Dick Kennedy Cc: "James E.J. Bottomley" Cc: "Martin K. Petersen" Cc: linux-scsi@vger.kernel.org Signed-off-by: Lee Jones Signed-off-by: Martin K. Petersen --- drivers/scsi/lpfc/lpfc_bsg.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/scsi/lpfc/lpfc_bsg.c b/drivers/scsi/lpfc/lpfc_bsg.c index b974d39d233b..503540cf2041 100644 --- a/drivers/scsi/lpfc/lpfc_bsg.c +++ b/drivers/scsi/lpfc/lpfc_bsg.c @@ -3580,7 +3580,7 @@ static int lpfc_bsg_check_cmd_access(struct lpfc_hba *phba, } /** - * lpfc_bsg_mbox_ext_cleanup - clean up context of multi-buffer mbox session + * lpfc_bsg_mbox_ext_session_reset - clean up context of multi-buffer mbox session * @phba: Pointer to HBA context object. * * This is routine clean up and reset BSG handling of multi-buffer mbox @@ -3869,7 +3869,7 @@ lpfc_bsg_sli_cfg_dma_desc_setup(struct lpfc_hba *phba, enum nemb_type nemb_tp, } /** - * lpfc_bsg_sli_cfg_mse_read_cmd_ext - sli_config non-embedded mailbox cmd read + * lpfc_bsg_sli_cfg_read_cmd_ext - sli_config non-embedded mailbox cmd read * @phba: Pointer to HBA context object. * @job: Pointer to the job object. * @nemb_tp: Enumerate of non-embedded mailbox command type. @@ -4360,7 +4360,7 @@ lpfc_bsg_handle_sli_cfg_mbox(struct lpfc_hba *phba, struct bsg_job *job, } /** - * lpfc_bsg_mbox_ext_abort_req - request to abort mbox command with ext buffers + * lpfc_bsg_mbox_ext_abort - request to abort mbox command with ext buffers * @phba: Pointer to HBA context object. * * This routine is for requesting to abort a pass-through mailbox command with From a7a11b6cfec2c3dc77b8206966f371dfafabea47 Mon Sep 17 00:00:00 2001 From: Lee Jones Date: Fri, 12 Mar 2021 09:47:22 +0000 Subject: [PATCH 137/412] scsi: bfa: Move a large struct from the stack onto the heap MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fixes the following W=1 kernel build warning(s): drivers/scsi/bfa/bfa_fcs_lport.c: In function ‘bfa_fcs_lport_fdmi_build_rhba_pyld’: drivers/scsi/bfa/bfa_fcs_lport.c:2152:1: warning: the frame size of 1200 bytes is larger than 1024 bytes [-Wframe-larger-than=] Link: https://lore.kernel.org/r/20210312094738.2207817-15-lee.jones@linaro.org Cc: Anil Gurumurthy Cc: Sudarsana Kalluru Cc: "James E.J. Bottomley" Cc: "Martin K. Petersen" Cc: linux-scsi@vger.kernel.org Signed-off-by: Lee Jones Signed-off-by: Martin K. Petersen --- drivers/scsi/bfa/bfa_fcs_lport.c | 20 ++++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) diff --git a/drivers/scsi/bfa/bfa_fcs_lport.c b/drivers/scsi/bfa/bfa_fcs_lport.c index 49a14157f123..b12afcc4b189 100644 --- a/drivers/scsi/bfa/bfa_fcs_lport.c +++ b/drivers/scsi/bfa/bfa_fcs_lport.c @@ -1408,7 +1408,7 @@ static void bfa_fcs_lport_fdmi_rpa_response(void *fcsarg, u32 resid_len, struct fchs_s *rsp_fchs); static void bfa_fcs_lport_fdmi_timeout(void *arg); -static u16 bfa_fcs_lport_fdmi_build_rhba_pyld(struct bfa_fcs_lport_fdmi_s *fdmi, +static int bfa_fcs_lport_fdmi_build_rhba_pyld(struct bfa_fcs_lport_fdmi_s *fdmi, u8 *pyld); static u16 bfa_fcs_lport_fdmi_build_rprt_pyld(struct bfa_fcs_lport_fdmi_s *fdmi, u8 *pyld); @@ -1887,6 +1887,8 @@ bfa_fcs_lport_fdmi_send_rhba(void *fdmi_cbarg, struct bfa_fcxp_s *fcxp_alloced) bfa_fcs_lport_fdmi_build_rhba_pyld(fdmi, (u8 *) ((struct ct_hdr_s *) pyld + 1)); + if (attr_len < 0) + return; bfa_fcxp_send(fcxp, NULL, port->fabric->vf_id, port->lp_tag, BFA_FALSE, FC_CLASS_3, (len + attr_len), &fchs, @@ -1896,17 +1898,20 @@ bfa_fcs_lport_fdmi_send_rhba(void *fdmi_cbarg, struct bfa_fcxp_s *fcxp_alloced) bfa_sm_send_event(fdmi, FDMISM_EVENT_RHBA_SENT); } -static u16 +static int bfa_fcs_lport_fdmi_build_rhba_pyld(struct bfa_fcs_lport_fdmi_s *fdmi, u8 *pyld) { struct bfa_fcs_lport_s *port = fdmi->ms->port; - struct bfa_fcs_fdmi_hba_attr_s hba_attr; - struct bfa_fcs_fdmi_hba_attr_s *fcs_hba_attr = &hba_attr; + struct bfa_fcs_fdmi_hba_attr_s *fcs_hba_attr; struct fdmi_rhba_s *rhba = (struct fdmi_rhba_s *) pyld; struct fdmi_attr_s *attr; + int len; u8 *curr_ptr; - u16 len, count; - u16 templen; + u16 templen, count; + + fcs_hba_attr = kzalloc(sizeof(*fcs_hba_attr), GFP_KERNEL); + if (!fcs_hba_attr) + return -ENOMEM; /* * get hba attributes @@ -2148,6 +2153,9 @@ bfa_fcs_lport_fdmi_build_rhba_pyld(struct bfa_fcs_lport_fdmi_s *fdmi, u8 *pyld) len += ((sizeof(attr->type) + sizeof(attr->len)) * count); rhba->hba_attr_blk.attr_count = cpu_to_be32(count); + + kfree(fcs_hba_attr); + return len; } From f6b35a75042b212c8eb81846ece1da6b471e5b56 Mon Sep 17 00:00:00 2001 From: Lee Jones Date: Fri, 12 Mar 2021 09:47:23 +0000 Subject: [PATCH 138/412] scsi: lpfc: Fix kernel-doc formatting issue Fixes the following W=1 kernel build warning(s): drivers/scsi/lpfc/lpfc_nvme.c:2021: warning: Function parameter or member 'vport' not described in 'lpfc_nvme_create_localport' Link: https://lore.kernel.org/r/20210312094738.2207817-16-lee.jones@linaro.org Cc: James Smart Cc: Dick Kennedy Cc: "James E.J. Bottomley" Cc: "Martin K. Petersen" Cc: linux-scsi@vger.kernel.org Signed-off-by: Lee Jones Signed-off-by: Martin K. Petersen --- drivers/scsi/lpfc/lpfc_nvme.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/scsi/lpfc/lpfc_nvme.c b/drivers/scsi/lpfc/lpfc_nvme.c index 5fe4e93fe984..4d78eadb65c0 100644 --- a/drivers/scsi/lpfc/lpfc_nvme.c +++ b/drivers/scsi/lpfc/lpfc_nvme.c @@ -2002,7 +2002,7 @@ lpfc_release_nvme_buf(struct lpfc_hba *phba, struct lpfc_io_buf *lpfc_ncmd) /** * lpfc_nvme_create_localport - Create/Bind an nvme localport instance. - * @vport - the lpfc_vport instance requesting a localport. + * @vport: the lpfc_vport instance requesting a localport. * * This routine is invoked to create an nvme localport instance to bind * to the nvme_fc_transport. It is called once during driver load From d5db88b0ce89075e7a107ca90ced22508f1d42a9 Mon Sep 17 00:00:00 2001 From: Lee Jones Date: Fri, 12 Mar 2021 09:47:24 +0000 Subject: [PATCH 139/412] scsi: ufs: cdns-pltfrm: Supply function names for headers Fixes the following W=1 kernel build warning(s): drivers/scsi/ufs/cdns-pltfrm.c:109: warning: expecting prototype for Sets HCLKDIV register value based on the core_clk(). Prototype was for cdns_ufs_set_hclkdiv() instead drivers/scsi/ufs/cdns-pltfrm.c:144: warning: wrong kernel-doc identifier on line: drivers/scsi/ufs/cdns-pltfrm.c:160: warning: wrong kernel-doc identifier on line: drivers/scsi/ufs/cdns-pltfrm.c:176: warning: wrong kernel-doc identifier on line: Link: https://lore.kernel.org/r/20210312094738.2207817-17-lee.jones@linaro.org Cc: Alim Akhtar Cc: Avri Altman Cc: "James E.J. Bottomley" Cc: "Martin K. Petersen" Cc: Stanley Chu Cc: Jan Kotas Cc: linux-scsi@vger.kernel.org Signed-off-by: Lee Jones Signed-off-by: Martin K. Petersen --- drivers/scsi/ufs/cdns-pltfrm.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/drivers/scsi/ufs/cdns-pltfrm.c b/drivers/scsi/ufs/cdns-pltfrm.c index 149391faa19c..13d92043e13b 100644 --- a/drivers/scsi/ufs/cdns-pltfrm.c +++ b/drivers/scsi/ufs/cdns-pltfrm.c @@ -100,6 +100,7 @@ static void cdns_ufs_set_l4_attr(struct ufs_hba *hba) } /** + * cdns_ufs_set_hclkdiv() * Sets HCLKDIV register value based on the core_clk * @hba: host controller instance * @@ -141,6 +142,7 @@ static int cdns_ufs_set_hclkdiv(struct ufs_hba *hba) } /** + * cdns_ufs_hce_enable_notify() * Called before and after HCE enable bit is set. * @hba: host controller instance * @status: notify stage (pre, post change) @@ -157,6 +159,7 @@ static int cdns_ufs_hce_enable_notify(struct ufs_hba *hba, } /** + * cdns_ufs_hibern8_notify() * Called around hibern8 enter/exit. * @hba: host controller instance * @cmd: UIC Command @@ -173,6 +176,7 @@ static void cdns_ufs_hibern8_notify(struct ufs_hba *hba, enum uic_cmd_dme cmd, } /** + * cdns_ufs_link_startup_notify() * Called before and after Link startup is carried out. * @hba: host controller instance * @status: notify stage (pre, post change) From 181883786427dab3f89724993c407c5831df09e3 Mon Sep 17 00:00:00 2001 From: Lee Jones Date: Fri, 12 Mar 2021 09:47:25 +0000 Subject: [PATCH 140/412] scsi: cxgbi: cxgb3: Fix misnaming of ddp_setup_conn_digest() Fixes the following W=1 kernel build warning(s): drivers/scsi/cxgbi/cxgb3i/cxgb3i.c:1189: warning: expecting prototype for cxgb3i_setup_conn_digest(). Prototype was for ddp_setup_conn_digest() instead Link: https://lore.kernel.org/r/20210312094738.2207817-18-lee.jones@linaro.org Cc: Karen Xie Cc: "James E.J. Bottomley" Cc: "Martin K. Petersen" Cc: Dimitris Michailidis Cc: linux-scsi@vger.kernel.org Signed-off-by: Lee Jones Signed-off-by: Martin K. Petersen --- drivers/scsi/cxgbi/cxgb3i/cxgb3i.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/scsi/cxgbi/cxgb3i/cxgb3i.c b/drivers/scsi/cxgbi/cxgb3i/cxgb3i.c index 37d99357120f..203f938fca7e 100644 --- a/drivers/scsi/cxgbi/cxgb3i/cxgb3i.c +++ b/drivers/scsi/cxgbi/cxgb3i/cxgb3i.c @@ -1177,7 +1177,7 @@ static int ddp_setup_conn_pgidx(struct cxgbi_sock *csk, } /** - * cxgb3i_setup_conn_digest - setup conn. digest setting + * ddp_setup_conn_digest - setup conn. digest setting * @csk: cxgb tcp socket * @tid: connection id * @hcrc: header digest enabled From 1c666a3e0a54e0d6df6dee5790cc93ed69aff095 Mon Sep 17 00:00:00 2001 From: Lee Jones Date: Fri, 12 Mar 2021 09:47:26 +0000 Subject: [PATCH 141/412] scsi: esas2r: Supply __printf(x, y) formatting for esas2r_log_master() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fixes the following W=1 kernel build warning(s): drivers/scsi/esas2r/esas2r_log.c: In function ‘esas2r_log_master’: drivers/scsi/esas2r/esas2r_log.c:155:3: warning: function ‘esas2r_log_master’ might be a candidate for ‘gnu_printf’ format attribute [-Wsuggest-attribute=format] Link: https://lore.kernel.org/r/20210312094738.2207817-19-lee.jones@linaro.org Cc: Bradley Grove Cc: "James E.J. Bottomley" Cc: "Martin K. Petersen" Cc: linux-scsi@vger.kernel.org Signed-off-by: Lee Jones Signed-off-by: Martin K. Petersen --- drivers/scsi/esas2r/esas2r_log.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/drivers/scsi/esas2r/esas2r_log.c b/drivers/scsi/esas2r/esas2r_log.c index b545798e400c..d6c87a0bae09 100644 --- a/drivers/scsi/esas2r/esas2r_log.c +++ b/drivers/scsi/esas2r/esas2r_log.c @@ -101,6 +101,11 @@ static const char *translate_esas2r_event_level_to_kernel(const long level) } } +#pragma GCC diagnostic push +#ifndef __clang__ +#pragma GCC diagnostic ignored "-Wsuggest-attribute=format" +#endif + /* * the master logging function. this function will format the message as * outlined by the formatting string, the input device information and the @@ -170,6 +175,8 @@ static int esas2r_log_master(const long level, return 0; } +#pragma GCC diagnostic pop + /* * formats and logs a message to the system log. * From 1b8a7ee9308e4e81ff02ed853a38ed23d386190b Mon Sep 17 00:00:00 2001 From: Lee Jones Date: Fri, 12 Mar 2021 09:47:27 +0000 Subject: [PATCH 142/412] scsi: be2iscsi: Fix incorrect naming of beiscsi_iface_config_vlan() Fixes the following W=1 kernel build warning(s): drivers/scsi/be2iscsi/be_iscsi.c:312: warning: expecting prototype for beiscsi_set_vlan_tag(). Prototype was for beiscsi_iface_config_vlan() instead Link: https://lore.kernel.org/r/20210312094738.2207817-20-lee.jones@linaro.org Cc: Subbu Seetharaman Cc: Ketan Mukadam Cc: Jitendra Bhivare Cc: "James E.J. Bottomley" Cc: "Martin K. Petersen" Cc: linux-drivers@broadcom.com Cc: linux-scsi@vger.kernel.org Signed-off-by: Lee Jones Signed-off-by: Martin K. Petersen --- drivers/scsi/be2iscsi/be_iscsi.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/scsi/be2iscsi/be_iscsi.c b/drivers/scsi/be2iscsi/be_iscsi.c index a13c203ef7a9..0e935c49b57b 100644 --- a/drivers/scsi/be2iscsi/be_iscsi.c +++ b/drivers/scsi/be2iscsi/be_iscsi.c @@ -295,7 +295,7 @@ void beiscsi_iface_destroy_default(struct beiscsi_hba *phba) } /** - * beiscsi_set_vlan_tag()- Set the VLAN TAG + * beiscsi_iface_config_vlan()- Set the VLAN TAG * @shost: Scsi Host for the driver instance * @iface_param: Interface paramters * From a905a1dce8bfc1c057ff7eae9e1d99a818af3007 Mon Sep 17 00:00:00 2001 From: Lee Jones Date: Fri, 12 Mar 2021 09:47:28 +0000 Subject: [PATCH 143/412] scsi: be2iscsi: Provide missing function name in header Fixes the following W=1 kernel build warning(s): drivers/scsi/be2iscsi/be_main.c:4934: warning: expecting prototype for Boot flag info for iscsi(). Prototype was for BEISCSI_SYSFS_ISCSI_BOOT_FLAGS() instead Link: https://lore.kernel.org/r/20210312094738.2207817-21-lee.jones@linaro.org Cc: Subbu Seetharaman Cc: Ketan Mukadam Cc: Jitendra Bhivare Cc: "James E.J. Bottomley" Cc: "Martin K. Petersen" Cc: linux-drivers@broadcom.com Cc: linux-scsi@vger.kernel.org Signed-off-by: Lee Jones Signed-off-by: Martin K. Petersen --- drivers/scsi/be2iscsi/be_main.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/scsi/be2iscsi/be_main.c b/drivers/scsi/be2iscsi/be_main.c index 90fcddb76f46..ab32ca535078 100644 --- a/drivers/scsi/be2iscsi/be_main.c +++ b/drivers/scsi/be2iscsi/be_main.c @@ -4927,6 +4927,7 @@ void beiscsi_start_boot_work(struct beiscsi_hba *phba, unsigned int s_handle) } /** + * beiscsi_show_boot_tgt_info() * Boot flag info for iscsi-utilities * Bit 0 Block valid flag * Bit 1 Firmware booting selected From ab4bab7a977da3382232e1a585ed84634c831289 Mon Sep 17 00:00:00 2001 From: Lee Jones Date: Fri, 12 Mar 2021 09:47:29 +0000 Subject: [PATCH 144/412] scsi: be2iscsi: Fix beiscsi_phys_port()'s name in header Fixes the following W=1 kernel build warning(s): drivers/scsi/be2iscsi/be_mgmt.c:1270: warning: expecting prototype for beiscsi_phys_port(). Prototype was for beiscsi_phys_port_disp() instead Link: https://lore.kernel.org/r/20210312094738.2207817-22-lee.jones@linaro.org Cc: Subbu Seetharaman Cc: Ketan Mukadam Cc: Jitendra Bhivare Cc: "James E.J. Bottomley" Cc: "Martin K. Petersen" Cc: linux-drivers@broadcom.com Cc: linux-scsi@vger.kernel.org Signed-off-by: Lee Jones Signed-off-by: Martin K. Petersen --- drivers/scsi/be2iscsi/be_mgmt.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/scsi/be2iscsi/be_mgmt.c b/drivers/scsi/be2iscsi/be_mgmt.c index 0d4928567265..462717bbb5b7 100644 --- a/drivers/scsi/be2iscsi/be_mgmt.c +++ b/drivers/scsi/be2iscsi/be_mgmt.c @@ -1256,7 +1256,7 @@ beiscsi_adap_family_disp(struct device *dev, struct device_attribute *attr, } /** - * beiscsi_phys_port()- Display Physical Port Identifier + * beiscsi_phys_port_disp()- Display Physical Port Identifier * @dev: ptr to device not used. * @attr: device attribute, not used. * @buf: contains formatted text port identifier From 0a386beb7ebdcc475a57327d4ab1eb6fa6a7c678 Mon Sep 17 00:00:00 2001 From: Lee Jones Date: Fri, 12 Mar 2021 09:47:30 +0000 Subject: [PATCH 145/412] scsi: bnx2i: Fix bnx2i_set_ccell_info()'s name in description Fixes the following W=1 kernel build warning(s): drivers/scsi/bnx2i/bnx2i_sysfs.c:118: warning: expecting prototype for bnx2i_get_link_state(). Prototype was for bnx2i_set_ccell_info() instead Link: https://lore.kernel.org/r/20210312094738.2207817-23-lee.jones@linaro.org Cc: Nilesh Javali Cc: Manish Rangankar Cc: GR-QLogic-Storage-Upstream@marvell.com Cc: "James E.J. Bottomley" Cc: "Martin K. Petersen" Cc: Anil Veerabhadrappa Cc: Eddie Wai Cc: QLogic-Storage-Upstream@qlogic.com Cc: linux-scsi@vger.kernel.org Signed-off-by: Lee Jones Signed-off-by: Martin K. Petersen --- drivers/scsi/bnx2i/bnx2i_sysfs.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/scsi/bnx2i/bnx2i_sysfs.c b/drivers/scsi/bnx2i/bnx2i_sysfs.c index 3dc790089f0f..bea00073cb7c 100644 --- a/drivers/scsi/bnx2i/bnx2i_sysfs.c +++ b/drivers/scsi/bnx2i/bnx2i_sysfs.c @@ -104,7 +104,7 @@ static ssize_t bnx2i_show_ccell_info(struct device *dev, /** - * bnx2i_get_link_state - set command cell (HQ) size + * bnx2i_set_ccell_info - set command cell (HQ) size * @dev: device pointer * @attr: device attribute (unused) * @buf: buffer to return current SQ size parameter From 78e40ac8b6960eb8b33b369a55eb46b4563a4b62 Mon Sep 17 00:00:00 2001 From: Lee Jones Date: Fri, 12 Mar 2021 09:47:31 +0000 Subject: [PATCH 146/412] scsi: initio: Remove unused variable 'prev' MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fixes the following W=1 kernel build warning(s): drivers/scsi/initio.c: In function ‘initio_find_busy_scb’: drivers/scsi/initio.c:869:30: warning: variable ‘prev’ set but not used [-Wunused-but-set-variable] Link: https://lore.kernel.org/r/20210312094738.2207817-24-lee.jones@linaro.org Cc: "James E.J. Bottomley" Cc: "Martin K. Petersen" Cc: Bas Vermeulen Cc: Christoph Hellwig Cc: Brian Macy Cc: linux-scsi@vger.kernel.org Reviewed-by: Christoph Hellwig Signed-off-by: Lee Jones Signed-off-by: Martin K. Petersen --- drivers/scsi/initio.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/drivers/scsi/initio.c b/drivers/scsi/initio.c index 814acc57069d..926a7045c2e5 100644 --- a/drivers/scsi/initio.c +++ b/drivers/scsi/initio.c @@ -866,17 +866,16 @@ static void initio_unlink_busy_scb(struct initio_host * host, struct scsi_ctrl_b struct scsi_ctrl_blk *initio_find_busy_scb(struct initio_host * host, u16 tarlun) { - struct scsi_ctrl_blk *tmp, *prev; + struct scsi_ctrl_blk *tmp; u16 scbp_tarlun; - prev = tmp = host->first_busy; + tmp = host->first_busy; while (tmp != NULL) { scbp_tarlun = (tmp->lun << 8) | (tmp->target); if (scbp_tarlun == tarlun) { /* Unlink this SCB */ break; } - prev = tmp; tmp = tmp->next; } #if DEBUG_QUEUE From fb5b29b2ad3f4ef0f0dda2ee267994cf8efb190d Mon Sep 17 00:00:00 2001 From: Lee Jones Date: Fri, 12 Mar 2021 09:47:32 +0000 Subject: [PATCH 147/412] scsi: a100u2w: Remove unused variable 'bios_phys' MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fixes the following W=1 kernel build warning(s): drivers/scsi/a100u2w.c: In function ‘inia100_probe_one’: drivers/scsi/a100u2w.c:1092:8: warning: variable ‘bios_phys’ set but not used [-Wunused-but-set-variable] Link: https://lore.kernel.org/r/20210312094738.2207817-25-lee.jones@linaro.org Cc: "James E.J. Bottomley" Cc: "Martin K. Petersen" Cc: Doug Ledford Cc: Christoph Hellwig Cc: Alan Cox Cc: linux-scsi@vger.kernel.org Reviewed-by: Christoph Hellwig Signed-off-by: Lee Jones Signed-off-by: Martin K. Petersen --- drivers/scsi/a100u2w.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/drivers/scsi/a100u2w.c b/drivers/scsi/a100u2w.c index 66c514310f3c..c99224a128f8 100644 --- a/drivers/scsi/a100u2w.c +++ b/drivers/scsi/a100u2w.c @@ -1089,7 +1089,6 @@ static int inia100_probe_one(struct pci_dev *pdev, int error = -ENODEV; u32 sz; unsigned long biosaddr; - char *bios_phys; if (pci_enable_device(pdev)) goto out; @@ -1141,7 +1140,6 @@ static int inia100_probe_one(struct pci_dev *pdev, biosaddr = host->BIOScfg; biosaddr = (biosaddr << 4); - bios_phys = phys_to_virt(biosaddr); if (init_orchid(host)) { /* Initialize orchid chip */ printk("inia100: initial orchid fail!!\n"); goto out_free_escb_array; From 167b7e6bfbf52c739642659239200874bb388fff Mon Sep 17 00:00:00 2001 From: Lee Jones Date: Fri, 12 Mar 2021 09:47:33 +0000 Subject: [PATCH 148/412] scsi: dc395x: Fix incorrect naming in function headers Fixes the following W=1 kernel build warning(s): drivers/scsi/dc395x.c:980: warning: expecting prototype for dc395x_queue_command(). Prototype was for dc395x_queue_command_lck() instead drivers/scsi/dc395x.c:4263: warning: expecting prototype for adapter_init_host(). Prototype was for adapter_init_scsi_host() instead drivers/scsi/dc395x.c:4353: warning: Function parameter or member 'acb' not described in 'adapter_init' drivers/scsi/dc395x.c:4353: warning: Function parameter or member 'io_port_len' not described in 'adapter_init' drivers/scsi/dc395x.c:4353: warning: expecting prototype for init_adapter(). Prototype was for adapter_init() instead Link: https://lore.kernel.org/r/20210312094738.2207817-26-lee.jones@linaro.org Cc: Oliver Neukum Cc: Ali Akcaagac Cc: Jamie Lenehan Cc: "James E.J. Bottomley" Cc: "Martin K. Petersen" Cc: "C.L. Huang" Cc: Erich Chen Cc: Kurt Garloff Cc: dc395x@twibble.org Cc: linux-scsi@vger.kernel.org Signed-off-by: Lee Jones Signed-off-by: Martin K. Petersen --- drivers/scsi/dc395x.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/scsi/dc395x.c b/drivers/scsi/dc395x.c index 3ea345c12467..e28f8931e23f 100644 --- a/drivers/scsi/dc395x.c +++ b/drivers/scsi/dc395x.c @@ -958,7 +958,7 @@ static void build_srb(struct scsi_cmnd *cmd, struct DeviceCtlBlk *dcb, /** - * dc395x_queue_command - queue scsi command passed from the mid + * dc395x_queue_command_lck - queue scsi command passed from the mid * layer, invoke 'done' on completion * * @cmd: pointer to scsi command object @@ -4248,7 +4248,7 @@ static void adapter_init_params(struct AdapterCtlBlk *acb) /** - * adapter_init_host - Initialize the scsi host instance based on + * adapter_init_scsi_host - Initialize the scsi host instance based on * values that we have already stored in the adapter instance. There's * some mention that a lot of these are deprecated, so we won't use * them (we'll use the ones in the adapter instance) but we'll fill @@ -4336,7 +4336,7 @@ static void adapter_init_chip(struct AdapterCtlBlk *acb) /** - * init_adapter - Grab the resource for the card, setup the adapter + * adapter_init - Grab the resource for the card, setup the adapter * information, set the card into a known state, create the various * tables etc etc. This basically gets all adapter information all up * to date, initialised and gets the chip in sync with it. From 6b71f60ca205a02b80e07f930fe1be378568fc92 Mon Sep 17 00:00:00 2001 From: Lee Jones Date: Fri, 12 Mar 2021 09:47:34 +0000 Subject: [PATCH 149/412] scsi: atp870u: Fix naming and demote incorrect and non-conformant kernel-doc header Fixes the following W=1 kernel build warning(s): drivers/scsi/atp870u.c:623: warning: expecting prototype for atp870u_queuecommand(). Prototype was for atp870u_queuecommand_lck() instead drivers/scsi/atp870u.c:724: warning: Function parameter or member 'dev' not described in 'send_s870' drivers/scsi/atp870u.c:724: warning: Function parameter or member 'c' not described in 'send_s870' drivers/scsi/atp870u.c:724: warning: Excess function parameter 'host' description in 'send_s870' Link: https://lore.kernel.org/r/20210312094738.2207817-27-lee.jones@linaro.org Cc: "James E.J. Bottomley" Cc: "Martin K. Petersen" Cc: Marcelo Tosatti Cc: linux-scsi@vger.kernel.org Signed-off-by: Lee Jones Signed-off-by: Martin K. Petersen --- drivers/scsi/atp870u.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/drivers/scsi/atp870u.c b/drivers/scsi/atp870u.c index da6ca2b153d8..9d179cd15bb8 100644 --- a/drivers/scsi/atp870u.c +++ b/drivers/scsi/atp870u.c @@ -612,7 +612,7 @@ static irqreturn_t atp870u_intr_handle(int irq, void *dev_id) return IRQ_HANDLED; } /** - * atp870u_queuecommand - Queue SCSI command + * atp870u_queuecommand_lck - Queue SCSI command * @req_p: request block * @done: completion function * @@ -711,16 +711,15 @@ static int atp870u_queuecommand_lck(struct scsi_cmnd *req_p, static DEF_SCSI_QCMD(atp870u_queuecommand) -/** +/* * send_s870 - send a command to the controller - * @host: host * * On entry there is work queued to be done. We move some of that work to the * controller itself. * * Caller holds the host lock. */ -static void send_s870(struct atp_unit *dev,unsigned char c) +static void send_s870(struct atp_unit *dev, unsigned char c) { struct scsi_cmnd *workreq = NULL; unsigned int i;//,k; From 3cb0cfb557cd9b07e15d8e4e4540f7a2794da189 Mon Sep 17 00:00:00 2001 From: Lee Jones Date: Fri, 12 Mar 2021 09:47:35 +0000 Subject: [PATCH 150/412] scsi: myrs: Remove a couple of unused 'status' variables MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fixes the following W=1 kernel build warning(s): drivers/scsi/myrs.c: In function ‘consistency_check_show’: drivers/scsi/myrs.c:1193:16: warning: variable ‘status’ set but not used [-Wunused-but-set-variable] drivers/scsi/myrs.c: In function ‘myrs_get_resync’: drivers/scsi/myrs.c:1984:5: warning: variable ‘status’ set but not used [-Wunused-but-set-variable] Link: https://lore.kernel.org/r/20210312094738.2207817-28-lee.jones@linaro.org Cc: Hannes Reinecke Cc: "James E.J. Bottomley" Cc: "Martin K. Petersen" Cc: Linux GmbH Cc: "Leonard N. Zubkoff" Cc: linux-scsi@vger.kernel.org Reviewed-by: Christoph Hellwig Signed-off-by: Lee Jones Signed-off-by: Martin K. Petersen --- drivers/scsi/myrs.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/drivers/scsi/myrs.c b/drivers/scsi/myrs.c index 4adf9ded296a..48e399f057d5 100644 --- a/drivers/scsi/myrs.c +++ b/drivers/scsi/myrs.c @@ -1190,7 +1190,6 @@ static ssize_t consistency_check_show(struct device *dev, struct myrs_hba *cs = shost_priv(sdev->host); struct myrs_ldev_info *ldev_info; unsigned short ldev_num; - unsigned char status; if (sdev->channel < cs->ctlr_info->physchan_present) return snprintf(buf, 32, "physical device - not checking\n"); @@ -1199,7 +1198,7 @@ static ssize_t consistency_check_show(struct device *dev, if (!ldev_info) return -ENXIO; ldev_num = ldev_info->ldev_num; - status = myrs_get_ldev_info(cs, ldev_num, ldev_info); + myrs_get_ldev_info(cs, ldev_num, ldev_info); if (ldev_info->cc_active) return snprintf(buf, 32, "checking block %zu of %zu\n", (size_t)ldev_info->cc_lba, @@ -1981,14 +1980,13 @@ myrs_get_resync(struct device *dev) struct myrs_hba *cs = shost_priv(sdev->host); struct myrs_ldev_info *ldev_info = sdev->hostdata; u64 percent_complete = 0; - u8 status; if (sdev->channel < cs->ctlr_info->physchan_present || !ldev_info) return; if (ldev_info->rbld_active) { unsigned short ldev_num = ldev_info->ldev_num; - status = myrs_get_ldev_info(cs, ldev_num, ldev_info); + myrs_get_ldev_info(cs, ldev_num, ldev_info); percent_complete = ldev_info->rbld_lba * 100; do_div(percent_complete, ldev_info->cfg_devsize); } From 6c31cb74a1ce84ea13cebade1203322b998c98fc Mon Sep 17 00:00:00 2001 From: Lee Jones Date: Fri, 12 Mar 2021 09:47:36 +0000 Subject: [PATCH 151/412] scsi: 3w-xxxx: Remove 2 unused variables 'response_que_value' and 'tw_dev' MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fixes the following W=1 kernel build warning(s): drivers/scsi/3w-xxxx.c: In function ‘tw_empty_response_que’: drivers/scsi/3w-xxxx.c:463:24: warning: variable ‘response_que_value’ set but not used [-Wunused-but-set-variable] drivers/scsi/3w-xxxx.c: In function ‘tw_scsi_biosparam’: drivers/scsi/3w-xxxx.c:1345:23: warning: variable ‘tw_dev’ set but not used [-Wunused-but-set-variable] Link: https://lore.kernel.org/r/20210312094738.2207817-29-lee.jones@linaro.org Cc: Adam Radford Cc: "James E.J. Bottomley" Cc: "Martin K. Petersen" Cc: Joel Jacobson Cc: de Melo Cc: Andre Hedrick Cc: linux-scsi@vger.kernel.org Signed-off-by: Lee Jones Signed-off-by: Martin K. Petersen --- drivers/scsi/3w-xxxx.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/drivers/scsi/3w-xxxx.c b/drivers/scsi/3w-xxxx.c index d90b9fca4aea..a7292883b72b 100644 --- a/drivers/scsi/3w-xxxx.c +++ b/drivers/scsi/3w-xxxx.c @@ -460,12 +460,12 @@ static int tw_check_errors(TW_Device_Extension *tw_dev) /* This function will empty the response que */ static void tw_empty_response_que(TW_Device_Extension *tw_dev) { - u32 status_reg_value, response_que_value; + u32 status_reg_value; status_reg_value = inl(TW_STATUS_REG_ADDR(tw_dev)); while ((status_reg_value & TW_STATUS_RESPONSE_QUEUE_EMPTY) == 0) { - response_que_value = inl(TW_RESPONSE_QUEUE_REG_ADDR(tw_dev)); + inl(TW_RESPONSE_QUEUE_REG_ADDR(tw_dev)); status_reg_value = inl(TW_STATUS_REG_ADDR(tw_dev)); } } /* End tw_empty_response_que() */ @@ -1342,10 +1342,8 @@ static int tw_scsi_biosparam(struct scsi_device *sdev, struct block_device *bdev sector_t capacity, int geom[]) { int heads, sectors, cylinders; - TW_Device_Extension *tw_dev; dprintk(KERN_NOTICE "3w-xxxx: tw_scsi_biosparam()\n"); - tw_dev = (TW_Device_Extension *)sdev->host->hostdata; heads = 64; sectors = 32; From ea7fb5344ad00accb016cad11f88bfd0e8cbcca1 Mon Sep 17 00:00:00 2001 From: Lee Jones Date: Fri, 12 Mar 2021 09:47:37 +0000 Subject: [PATCH 152/412] scsi: 3w-9xxx: Remove a few set but unused variables MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fixes the following W=1 kernel build warning(s): drivers/scsi/3w-9xxx.c: In function ‘twa_empty_response_queue’: drivers/scsi/3w-9xxx.c:942:24: warning: variable ‘response_que_value’ set but not used [-Wunused-but-set-variable] drivers/scsi/3w-9xxx.c: In function ‘twa_scsi_biosparam’: drivers/scsi/3w-9xxx.c:1701:23: warning: variable ‘tw_dev’ set but not used [-Wunused-but-set-variable] drivers/scsi/3w-9xxx.c: In function ‘twa_scsiop_execute_scsi’: drivers/scsi/3w-9xxx.c:1812:22: warning: variable ‘sglist’ set but not used [-Wunused-but-set-variable] Link: https://lore.kernel.org/r/20210312094738.2207817-30-lee.jones@linaro.org Cc: Adam Radford Cc: "James E.J. Bottomley" Cc: "Martin K. Petersen" Cc: linux-scsi@vger.kernel.org Signed-off-by: Lee Jones Signed-off-by: Martin K. Petersen --- drivers/scsi/3w-9xxx.c | 14 ++++---------- 1 file changed, 4 insertions(+), 10 deletions(-) diff --git a/drivers/scsi/3w-9xxx.c b/drivers/scsi/3w-9xxx.c index b96e82de4237..47028f5e57ab 100644 --- a/drivers/scsi/3w-9xxx.c +++ b/drivers/scsi/3w-9xxx.c @@ -939,13 +939,13 @@ out: /* This function will empty the response queue */ static int twa_empty_response_queue(TW_Device_Extension *tw_dev) { - u32 status_reg_value, response_que_value; + u32 status_reg_value; int count = 0, retval = 1; status_reg_value = readl(TW_STATUS_REG_ADDR(tw_dev)); while (((status_reg_value & TW_STATUS_RESPONSE_QUEUE_EMPTY) == 0) && (count < TW_MAX_RESPONSE_DRAIN)) { - response_que_value = readl(TW_RESPONSE_QUEUE_REG_ADDR(tw_dev)); + readl(TW_RESPONSE_QUEUE_REG_ADDR(tw_dev)); status_reg_value = readl(TW_STATUS_REG_ADDR(tw_dev)); count++; } @@ -1698,9 +1698,6 @@ out: static int twa_scsi_biosparam(struct scsi_device *sdev, struct block_device *bdev, sector_t capacity, int geom[]) { int heads, sectors, cylinders; - TW_Device_Extension *tw_dev; - - tw_dev = (TW_Device_Extension *)sdev->host->hostdata; if (capacity >= 0x200000) { heads = 255; @@ -1809,14 +1806,11 @@ static int twa_scsiop_execute_scsi(TW_Device_Extension *tw_dev, int request_id, u32 num_sectors = 0x0; int i, sg_count; struct scsi_cmnd *srb = NULL; - struct scatterlist *sglist = NULL, *sg; + struct scatterlist *sg; int retval = 1; - if (tw_dev->srb[request_id]) { + if (tw_dev->srb[request_id]) srb = tw_dev->srb[request_id]; - if (scsi_sglist(srb)) - sglist = scsi_sglist(srb); - } /* Initialize command packet */ full_command_packet = tw_dev->command_packet_virt[request_id]; From 475bff65c431013057c4b6b150bce259e80d0adf Mon Sep 17 00:00:00 2001 From: Lee Jones Date: Fri, 12 Mar 2021 09:47:38 +0000 Subject: [PATCH 153/412] scsi: 3w-sas: Remove unused variables 'sglist' and 'tw_dev' MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fixes the following W=1 kernel build warning(s): drivers/scsi/3w-sas.c: In function ‘twl_scsiop_execute_scsi’: drivers/scsi/3w-sas.c:298:22: warning: variable ‘sglist’ set but not used [-Wunused-but-set-variable] drivers/scsi/3w-sas.c: In function ‘twl_scsi_biosparam’: drivers/scsi/3w-sas.c:1411:23: warning: variable ‘tw_dev’ set but not used [-Wunused-but-set-variable] Link: https://lore.kernel.org/r/20210312094738.2207817-31-lee.jones@linaro.org Cc: Adam Radford Cc: "James E.J. Bottomley" Cc: "Martin K. Petersen" Cc: linux-scsi@vger.kernel.org Signed-off-by: Lee Jones Signed-off-by: Martin K. Petersen --- drivers/scsi/3w-sas.c | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/drivers/scsi/3w-sas.c b/drivers/scsi/3w-sas.c index 3db0e42e9aa7..383f6f204c24 100644 --- a/drivers/scsi/3w-sas.c +++ b/drivers/scsi/3w-sas.c @@ -295,14 +295,11 @@ static int twl_scsiop_execute_scsi(TW_Device_Extension *tw_dev, int request_id, TW_Command_Apache *command_packet; int i, sg_count; struct scsi_cmnd *srb = NULL; - struct scatterlist *sglist = NULL, *sg; + struct scatterlist *sg; int retval = 1; - if (tw_dev->srb[request_id]) { + if (tw_dev->srb[request_id]) srb = tw_dev->srb[request_id]; - if (scsi_sglist(srb)) - sglist = scsi_sglist(srb); - } /* Initialize command packet */ full_command_packet = tw_dev->command_packet_virt[request_id]; @@ -1408,9 +1405,6 @@ out: static int twl_scsi_biosparam(struct scsi_device *sdev, struct block_device *bdev, sector_t capacity, int geom[]) { int heads, sectors; - TW_Device_Extension *tw_dev; - - tw_dev = (TW_Device_Extension *)sdev->host->hostdata; if (capacity >= 0x200000) { heads = 255; From 720efdd23f963612d0a8c7072293aff119c6f915 Mon Sep 17 00:00:00 2001 From: Wang Qing Date: Sat, 13 Mar 2021 10:41:15 +0800 Subject: [PATCH 154/412] scsi: qla2xxx: Use dma_pool_zalloc() Use dma_pool_zalloc() instead of dma_pool_alloc() and memset(). Link: https://lore.kernel.org/r/1615603275-14303-1-git-send-email-wangqing@vivo.com Reviewed-by: Himanshu Madhani Signed-off-by: Wang Qing Signed-off-by: Martin K. Petersen --- drivers/scsi/qla2xxx/qla_os.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/scsi/qla2xxx/qla_os.c b/drivers/scsi/qla2xxx/qla_os.c index 074392560f3d..ac5e9548b757 100644 --- a/drivers/scsi/qla2xxx/qla_os.c +++ b/drivers/scsi/qla2xxx/qla_os.c @@ -4238,11 +4238,10 @@ qla2x00_mem_alloc(struct qla_hw_data *ha, uint16_t req_len, uint16_t rsp_len, /* Get consistent memory allocated for Special Features-CB. */ if (IS_QLA27XX(ha) || IS_QLA28XX(ha)) { - ha->sf_init_cb = dma_pool_alloc(ha->s_dma_pool, GFP_KERNEL, + ha->sf_init_cb = dma_pool_zalloc(ha->s_dma_pool, GFP_KERNEL, &ha->sf_init_cb_dma); if (!ha->sf_init_cb) goto fail_sf_init_cb; - memset(ha->sf_init_cb, 0, sizeof(struct init_sf_cb)); ql_dbg_pci(ql_dbg_init, ha->pdev, 0x0199, "sf_init_cb=%p.\n", ha->sf_init_cb); } From 471ee95ccca9c417344453f73a39681cfde39af1 Mon Sep 17 00:00:00 2001 From: Bodo Stroesser Date: Wed, 10 Mar 2021 19:44:58 +0100 Subject: [PATCH 155/412] scsi: target: tcmu: Adjust parameter in call to tcmu_blocks_release() In commit f7c89771d07d ("scsi: target: tcmu: Replace radix_tree with XArray") the meaning of last parameter of tcmu_blocks_release() was changed. So in the callers we should subtract 1 from the previous parameter. Unfortunately that change got lost at one of the two places where tcmu_blocks_release() is called. That does not lead to any problems, but we should adjust it anyway. Link: https://lore.kernel.org/r/20210310184458.10741-1-bostroesser@gmail.com Signed-off-by: Bodo Stroesser Signed-off-by: Martin K. Petersen --- drivers/target/target_core_user.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/target/target_core_user.c b/drivers/target/target_core_user.c index 9e1b115cb032..bdfc057f000c 100644 --- a/drivers/target/target_core_user.c +++ b/drivers/target/target_core_user.c @@ -1658,7 +1658,7 @@ static void tcmu_dev_kref_release(struct kref *kref) xa_destroy(&udev->commands); WARN_ON(!all_expired); - tcmu_blocks_release(&udev->data_blocks, 0, udev->dbi_max + 1); + tcmu_blocks_release(&udev->data_blocks, 0, udev->dbi_max); bitmap_free(udev->data_bitmap); mutex_unlock(&udev->cmdr_lock); From 3d9c3dcc58e968403f29767726407bc680e087b5 Mon Sep 17 00:00:00 2001 From: Michael Kelley Date: Tue, 23 Feb 2021 14:44:54 -0800 Subject: [PATCH 156/412] scsi: storvsc: Enable scatterlist entry lengths > 4Kbytes storvsc currently sets .dma_boundary to limit scatterlist entries to 4 Kbytes, which is less efficient with huge pages that offer large chunks of contiguous physical memory. Improve the algorithm for creating the Hyper-V guest physical address PFN array so that scatterlist entries with lengths > 4Kbytes are handled. As a result, remove the .dma_boundary setting. The improved algorithm also adds support for scatterlist entries with offsets >= 4Kbytes, which is supported by many other SCSI low-level drivers. And it retains support for architectures where possibly PAGE_SIZE != HV_HYP_PAGE_SIZE (such as ARM64). Link: https://lore.kernel.org/r/1614120294-1930-1-git-send-email-mikelley@microsoft.com Reviewed-by: Vitaly Kuznetsov Signed-off-by: Michael Kelley Signed-off-by: Martin K. Petersen --- drivers/scsi/storvsc_drv.c | 66 +++++++++++++------------------------- include/linux/hyperv.h | 1 + 2 files changed, 24 insertions(+), 43 deletions(-) diff --git a/drivers/scsi/storvsc_drv.c b/drivers/scsi/storvsc_drv.c index dfe005c03734..e6718a74e5da 100644 --- a/drivers/scsi/storvsc_drv.c +++ b/drivers/scsi/storvsc_drv.c @@ -1692,9 +1692,8 @@ static int storvsc_queuecommand(struct Scsi_Host *host, struct scsi_cmnd *scmnd) struct storvsc_cmd_request *cmd_request = scsi_cmd_priv(scmnd); int i; struct scatterlist *sgl; - unsigned int sg_count = 0; + unsigned int sg_count; struct vmscsi_request *vm_srb; - struct scatterlist *cur_sgl; struct vmbus_packet_mpb_array *payload; u32 payload_sz; u32 length; @@ -1773,8 +1772,8 @@ static int storvsc_queuecommand(struct Scsi_Host *host, struct scsi_cmnd *scmnd) payload_sz = sizeof(cmd_request->mpb); if (sg_count) { - unsigned int hvpgoff = 0; - unsigned long offset_in_hvpg = sgl->offset & ~HV_HYP_PAGE_MASK; + unsigned int hvpgoff, hvpfns_to_add; + unsigned long offset_in_hvpg = offset_in_hvpage(sgl->offset); unsigned int hvpg_count = HVPFN_UP(offset_in_hvpg + length); u64 hvpfn; @@ -1787,51 +1786,34 @@ static int storvsc_queuecommand(struct Scsi_Host *host, struct scsi_cmnd *scmnd) return SCSI_MLQUEUE_DEVICE_BUSY; } - /* - * sgl is a list of PAGEs, and payload->range.pfn_array - * expects the page number in the unit of HV_HYP_PAGE_SIZE (the - * page size that Hyper-V uses, so here we need to divide PAGEs - * into HV_HYP_PAGE in case that PAGE_SIZE > HV_HYP_PAGE_SIZE. - * Besides, payload->range.offset should be the offset in one - * HV_HYP_PAGE. - */ payload->range.len = length; payload->range.offset = offset_in_hvpg; - hvpgoff = sgl->offset >> HV_HYP_PAGE_SHIFT; - cur_sgl = sgl; - for (i = 0; i < hvpg_count; i++) { + + for (i = 0; sgl != NULL; sgl = sg_next(sgl)) { /* - * 'i' is the index of hv pages in the payload and - * 'hvpgoff' is the offset (in hv pages) of the first - * hv page in the the first page. The relationship - * between the sum of 'i' and 'hvpgoff' and the offset - * (in hv pages) in a payload page ('hvpgoff_in_page') - * is as follow: - * - * |------------------ PAGE -------------------| - * | NR_HV_HYP_PAGES_IN_PAGE hvpgs in total | - * |hvpg|hvpg| ... |hvpg|... |hvpg| - * ^ ^ ^ ^ - * +-hvpgoff-+ +-hvpgoff_in_page-+ - * ^ | - * +--------------------- i ---------------------------+ + * Init values for the current sgl entry. hvpgoff + * and hvpfns_to_add are in units of Hyper-V size + * pages. Handling the PAGE_SIZE != HV_HYP_PAGE_SIZE + * case also handles values of sgl->offset that are + * larger than PAGE_SIZE. Such offsets are handled + * even on other than the first sgl entry, provided + * they are a multiple of PAGE_SIZE. */ - unsigned int hvpgoff_in_page = - (i + hvpgoff) % NR_HV_HYP_PAGES_IN_PAGE; + hvpgoff = HVPFN_DOWN(sgl->offset); + hvpfn = page_to_hvpfn(sg_page(sgl)) + hvpgoff; + hvpfns_to_add = HVPFN_UP(sgl->offset + sgl->length) - + hvpgoff; /* - * Two cases that we need to fetch a page: - * 1) i == 0, the first step or - * 2) hvpgoff_in_page == 0, when we reach the boundary - * of a page. + * Fill the next portion of the PFN array with + * sequential Hyper-V PFNs for the continguous physical + * memory described by the sgl entry. The end of the + * last sgl should be reached at the same time that + * the PFN array is filled. */ - if (hvpgoff_in_page == 0 || i == 0) { - hvpfn = page_to_hvpfn(sg_page(cur_sgl)); - cur_sgl = sg_next(cur_sgl); - } - - payload->range.pfn_array[i] = hvpfn + hvpgoff_in_page; + while (hvpfns_to_add--) + payload->range.pfn_array[i++] = hvpfn++; } } @@ -1865,8 +1847,6 @@ static struct scsi_host_template scsi_driver = { .slave_configure = storvsc_device_configure, .cmd_per_lun = 2048, .this_id = -1, - /* Make sure we dont get a sg segment crosses a page boundary */ - .dma_boundary = PAGE_SIZE-1, /* Ensure there are no gaps in presented sgls */ .virt_boundary_mask = PAGE_SIZE-1, .no_write_same = 1, diff --git a/include/linux/hyperv.h b/include/linux/hyperv.h index f1d74dcf0353..7be8c5f7c5b2 100644 --- a/include/linux/hyperv.h +++ b/include/linux/hyperv.h @@ -1726,6 +1726,7 @@ static inline unsigned long virt_to_hvpfn(void *addr) #define NR_HV_HYP_PAGES_IN_PAGE (PAGE_SIZE / HV_HYP_PAGE_SIZE) #define offset_in_hvpage(ptr) ((unsigned long)(ptr) & ~HV_HYP_PAGE_MASK) #define HVPFN_UP(x) (((x) + HV_HYP_PAGE_SIZE-1) >> HV_HYP_PAGE_SHIFT) +#define HVPFN_DOWN(x) ((x) >> HV_HYP_PAGE_SHIFT) #define page_to_hvpfn(page) (page_to_pfn(page) * NR_HV_HYP_PAGES_IN_PAGE) #endif /* _HYPERV_H */ From 4517e77eb83d875c61e11dec01dec4ad49e4c5e7 Mon Sep 17 00:00:00 2001 From: Vinod Koul Date: Thu, 4 Feb 2021 22:22:34 +0530 Subject: [PATCH 157/412] scsi: ufs: dt-bindings: Add sm8250, sm8350 compatible strings Document "qcom,sm8250-ufshc" and "qcom,sm8350-ufshc" compatible string. Use of "qcom,sm8250-ufshc" is already present upstream, so add misiing documentation. "qcom,sm8350-ufshc" is for UFS HC found in SM8350 SoC. Link: https://lore.kernel.org/r/20210204165234.61939-1-vkoul@kernel.org Reviewed-by: Bjorn Andersson Reviewed-by: Rob Herring Signed-off-by: Vinod Koul Signed-off-by: Martin K. Petersen --- Documentation/devicetree/bindings/ufs/ufshcd-pltfrm.txt | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Documentation/devicetree/bindings/ufs/ufshcd-pltfrm.txt b/Documentation/devicetree/bindings/ufs/ufshcd-pltfrm.txt index 415ccdd7442d..d8fd4df81743 100644 --- a/Documentation/devicetree/bindings/ufs/ufshcd-pltfrm.txt +++ b/Documentation/devicetree/bindings/ufs/ufshcd-pltfrm.txt @@ -14,6 +14,8 @@ Required properties: "qcom,msm8998-ufshc", "qcom,ufshc", "jedec,ufs-2.0" "qcom,sdm845-ufshc", "qcom,ufshc", "jedec,ufs-2.0" "qcom,sm8150-ufshc", "qcom,ufshc", "jedec,ufs-2.0" + "qcom,sm8250-ufshc", "qcom,ufshc", "jedec,ufs-2.0" + "qcom,sm8350-ufshc", "qcom,ufshc", "jedec,ufs-2.0" - interrupts : - reg : From 2a8561b78e377f48aa638d7cd203628b6dfc2519 Mon Sep 17 00:00:00 2001 From: Yue Hu Date: Wed, 10 Mar 2021 16:27:41 +0800 Subject: [PATCH 158/412] scsi: ufs: core: Remove unnecessary ret in ufshcd_populate_vreg() The local variable 'ret' is always zero. Remove it and return 0 at the end of the function. Link: https://lore.kernel.org/r/20210310082741.647-1-zbestahu@gmail.com Signed-off-by: Yue Hu Signed-off-by: Martin K. Petersen --- drivers/scsi/ufs/ufshcd-pltfrm.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/drivers/scsi/ufs/ufshcd-pltfrm.c b/drivers/scsi/ufs/ufshcd-pltfrm.c index 1a69949a4ea1..fedb7deb3304 100644 --- a/drivers/scsi/ufs/ufshcd-pltfrm.c +++ b/drivers/scsi/ufs/ufshcd-pltfrm.c @@ -106,7 +106,6 @@ out: static int ufshcd_populate_vreg(struct device *dev, const char *name, struct ufs_vreg **out_vreg) { - int ret = 0; char prop_name[MAX_PROP_SIZE]; struct ufs_vreg *vreg = NULL; struct device_node *np = dev->of_node; @@ -135,9 +134,8 @@ static int ufshcd_populate_vreg(struct device *dev, const char *name, vreg->max_uA = 0; } out: - if (!ret) - *out_vreg = vreg; - return ret; + *out_vreg = vreg; + return 0; } /** From 5142881801786a0658a8df16986b31e76a09760d Mon Sep 17 00:00:00 2001 From: Caleb Connolly Date: Wed, 10 Mar 2021 15:33:42 +0000 Subject: [PATCH 159/412] scsi: ufs: core: Use a function to calculate versions Update the driver to use a function for referencing the UFS version. This replaces the UFSHCI_VERSION_xy macros, and supports comparisons where they did not. Link: https://lore.kernel.org/r/20210310153215.371227-2-caleb@connolly.tech Suggested-by: Christoph Hellwig Reviewed-by: Christoph Hellwig Reviewed-by: Bean Huo Signed-off-by: Caleb Connolly Signed-off-by: Martin K. Petersen --- drivers/scsi/ufs/ufshcd.c | 66 +++++++++++++++++---------------------- drivers/scsi/ufs/ufshci.h | 18 ++++++----- 2 files changed, 39 insertions(+), 45 deletions(-) diff --git a/drivers/scsi/ufs/ufshcd.c b/drivers/scsi/ufs/ufshcd.c index 18b5d888e9de..ec53c0e598c3 100644 --- a/drivers/scsi/ufs/ufshcd.c +++ b/drivers/scsi/ufs/ufshcd.c @@ -668,23 +668,12 @@ int ufshcd_wait_for_register(struct ufs_hba *hba, u32 reg, u32 mask, */ static inline u32 ufshcd_get_intr_mask(struct ufs_hba *hba) { - u32 intr_mask = 0; + if (hba->ufs_version == ufshci_version(1, 0)) + return INTERRUPT_MASK_ALL_VER_10; + if (hba->ufs_version <= ufshci_version(2, 0)) + return INTERRUPT_MASK_ALL_VER_11; - switch (hba->ufs_version) { - case UFSHCI_VERSION_10: - intr_mask = INTERRUPT_MASK_ALL_VER_10; - break; - case UFSHCI_VERSION_11: - case UFSHCI_VERSION_20: - intr_mask = INTERRUPT_MASK_ALL_VER_11; - break; - case UFSHCI_VERSION_21: - default: - intr_mask = INTERRUPT_MASK_ALL_VER_21; - break; - } - - return intr_mask; + return INTERRUPT_MASK_ALL_VER_21; } /** @@ -695,10 +684,22 @@ static inline u32 ufshcd_get_intr_mask(struct ufs_hba *hba) */ static inline u32 ufshcd_get_ufs_version(struct ufs_hba *hba) { - if (hba->quirks & UFSHCD_QUIRK_BROKEN_UFS_HCI_VERSION) - return ufshcd_vops_get_ufs_hci_version(hba); + u32 ufshci_ver; - return ufshcd_readl(hba, REG_UFS_VERSION); + if (hba->quirks & UFSHCD_QUIRK_BROKEN_UFS_HCI_VERSION) + ufshci_ver = ufshcd_vops_get_ufs_hci_version(hba); + else + ufshci_ver = ufshcd_readl(hba, REG_UFS_VERSION); + + /* + * UFSHCI v1.x uses a different version scheme, in order + * to allow the use of comparisons with the ufshci_version + * function, we convert it to the same scheme as ufs 2.0+. + */ + if (ufshci_ver & 0x00010000) + return ufshci_version(1, ufshci_ver & 0x00000100); + + return ufshci_ver; } /** @@ -930,8 +931,7 @@ static inline bool ufshcd_is_hba_active(struct ufs_hba *hba) u32 ufshcd_get_local_unipro_ver(struct ufs_hba *hba) { /* HCI version 1.0 and 1.1 supports UniPro 1.41 */ - if ((hba->ufs_version == UFSHCI_VERSION_10) || - (hba->ufs_version == UFSHCI_VERSION_11)) + if (hba->ufs_version <= ufshci_version(1, 1)) return UFS_UNIPRO_VER_1_41; else return UFS_UNIPRO_VER_1_6; @@ -2334,7 +2334,7 @@ static void ufshcd_enable_intr(struct ufs_hba *hba, u32 intrs) { u32 set = ufshcd_readl(hba, REG_INTERRUPT_ENABLE); - if (hba->ufs_version == UFSHCI_VERSION_10) { + if (hba->ufs_version == ufshci_version(1, 0)) { u32 rw; rw = set & INTERRUPT_MASK_RW_VER_10; set = rw | ((set ^ intrs) & intrs); @@ -2354,7 +2354,7 @@ static void ufshcd_disable_intr(struct ufs_hba *hba, u32 intrs) { u32 set = ufshcd_readl(hba, REG_INTERRUPT_ENABLE); - if (hba->ufs_version == UFSHCI_VERSION_10) { + if (hba->ufs_version == ufshci_version(1, 0)) { u32 rw; rw = (set & INTERRUPT_MASK_RW_VER_10) & ~(intrs & INTERRUPT_MASK_RW_VER_10); @@ -2517,8 +2517,7 @@ static int ufshcd_compose_devman_upiu(struct ufs_hba *hba, u8 upiu_flags; int ret = 0; - if ((hba->ufs_version == UFSHCI_VERSION_10) || - (hba->ufs_version == UFSHCI_VERSION_11)) + if (hba->ufs_version <= ufshci_version(1, 1)) lrbp->command_type = UTP_CMD_TYPE_DEV_MANAGE; else lrbp->command_type = UTP_CMD_TYPE_UFS_STORAGE; @@ -2545,8 +2544,7 @@ static int ufshcd_comp_scsi_upiu(struct ufs_hba *hba, struct ufshcd_lrb *lrbp) u8 upiu_flags; int ret = 0; - if ((hba->ufs_version == UFSHCI_VERSION_10) || - (hba->ufs_version == UFSHCI_VERSION_11)) + if (hba->ufs_version <= ufshci_version(1, 1)) lrbp->command_type = UTP_CMD_TYPE_SCSI; else lrbp->command_type = UTP_CMD_TYPE_UFS_STORAGE; @@ -6575,15 +6573,10 @@ static int ufshcd_issue_devman_upiu_cmd(struct ufs_hba *hba, ufshcd_prepare_lrbp_crypto(NULL, lrbp); hba->dev_cmd.type = cmd_type; - switch (hba->ufs_version) { - case UFSHCI_VERSION_10: - case UFSHCI_VERSION_11: + if (hba->ufs_version <= ufshci_version(1, 1)) lrbp->command_type = UTP_CMD_TYPE_DEV_MANAGE; - break; - default: + else lrbp->command_type = UTP_CMD_TYPE_UFS_STORAGE; - break; - } /* update the task tag in the request upiu */ req_upiu->header.dword_0 |= cpu_to_be32(tag); @@ -9317,10 +9310,7 @@ int ufshcd_init(struct ufs_hba *hba, void __iomem *mmio_base, unsigned int irq) /* Get UFS version supported by the controller */ hba->ufs_version = ufshcd_get_ufs_version(hba); - if ((hba->ufs_version != UFSHCI_VERSION_10) && - (hba->ufs_version != UFSHCI_VERSION_11) && - (hba->ufs_version != UFSHCI_VERSION_20) && - (hba->ufs_version != UFSHCI_VERSION_21)) + if (hba->ufs_version < ufshci_version(1, 0)) dev_err(hba->dev, "invalid UFS version 0x%x\n", hba->ufs_version); diff --git a/drivers/scsi/ufs/ufshci.h b/drivers/scsi/ufs/ufshci.h index 6795e1f0e8f8..335ff7b5a935 100644 --- a/drivers/scsi/ufs/ufshci.h +++ b/drivers/scsi/ufs/ufshci.h @@ -74,13 +74,17 @@ enum { #define MINOR_VERSION_NUM_MASK UFS_MASK(0xFFFF, 0) #define MAJOR_VERSION_NUM_MASK UFS_MASK(0xFFFF, 16) -/* Controller UFSHCI version */ -enum { - UFSHCI_VERSION_10 = 0x00010000, /* 1.0 */ - UFSHCI_VERSION_11 = 0x00010100, /* 1.1 */ - UFSHCI_VERSION_20 = 0x00000200, /* 2.0 */ - UFSHCI_VERSION_21 = 0x00000210, /* 2.1 */ -}; +/* + * Controller UFSHCI version + * - 2.x and newer use the following scheme: + * major << 8 + minor << 4 + * - 1.x has been converted to match this in + * ufshcd_get_ufs_version() + */ +static inline u32 ufshci_version(u32 major, u32 minor) +{ + return (major << 8) + (minor << 4); +} /* * HCDDID - Host Controller Identification Descriptor From f065aca20a2664fd94a3b4cb65eb6cf1e23f4f1b Mon Sep 17 00:00:00 2001 From: Caleb Connolly Date: Wed, 10 Mar 2021 15:33:51 +0000 Subject: [PATCH 160/412] scsi: ufs: qcom: Use ufshci_version() function Replace the UFSHCI_VERSION_xy macros. Link: https://lore.kernel.org/r/20210310153215.371227-3-caleb@connolly.tech Reviewed-by: Bean Huo Signed-off-by: Caleb Connolly Signed-off-by: Martin K. Petersen --- drivers/scsi/ufs/ufs-qcom.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/scsi/ufs/ufs-qcom.c b/drivers/scsi/ufs/ufs-qcom.c index f97d7b0ae3b6..2d54dce0eeda 100644 --- a/drivers/scsi/ufs/ufs-qcom.c +++ b/drivers/scsi/ufs/ufs-qcom.c @@ -809,9 +809,9 @@ static u32 ufs_qcom_get_ufs_hci_version(struct ufs_hba *hba) struct ufs_qcom_host *host = ufshcd_get_variant(hba); if (host->hw_ver.major == 0x1) - return UFSHCI_VERSION_11; + return ufshci_version(1, 1); else - return UFSHCI_VERSION_20; + return ufshci_version(2, 0); } /** From 4f5e51c0ebf04278081caa871b4186789bc98b1c Mon Sep 17 00:00:00 2001 From: Caleb Connolly Date: Wed, 10 Mar 2021 15:34:01 +0000 Subject: [PATCH 161/412] scsi: ufs: core: Remove version check This check is redundant as all UFS versions are currently supported. Link: https://lore.kernel.org/r/20210310153215.371227-4-caleb@connolly.tech Reviewed-by: Bean Huo Co-developed-by: Nitin Rawat Signed-off-by: Nitin Rawat Signed-off-by: Caleb Connolly Signed-off-by: Martin K. Petersen --- drivers/scsi/ufs/ufshcd.c | 4 ---- 1 file changed, 4 deletions(-) diff --git a/drivers/scsi/ufs/ufshcd.c b/drivers/scsi/ufs/ufshcd.c index ec53c0e598c3..ab9a1b15d223 100644 --- a/drivers/scsi/ufs/ufshcd.c +++ b/drivers/scsi/ufs/ufshcd.c @@ -9310,10 +9310,6 @@ int ufshcd_init(struct ufs_hba *hba, void __iomem *mmio_base, unsigned int irq) /* Get UFS version supported by the controller */ hba->ufs_version = ufshcd_get_ufs_version(hba); - if (hba->ufs_version < ufshci_version(1, 0)) - dev_err(hba->dev, "invalid UFS version 0x%x\n", - hba->ufs_version); - /* Get Interrupt bit mask per version */ hba->intr_mask = ufshcd_get_intr_mask(hba); From b2c57925df1ffc9c930629a39c1680035f735ffb Mon Sep 17 00:00:00 2001 From: Adrian Hunter Date: Fri, 12 Mar 2021 10:06:20 +0200 Subject: [PATCH 162/412] scsi: ufs: ufs-pci: Add support for Intel LKF Add PCI ID and callbacks to support Intel LKF. This includes the ability to use an ACPI device-specific method (DSM) to perform a UFS device reset. Link: https://lore.kernel.org/r/20210312080620.13311-1-adrian.hunter@intel.com Signed-off-by: Adrian Hunter Signed-off-by: Martin K. Petersen --- drivers/scsi/ufs/ufshcd-pci.c | 169 ++++++++++++++++++++++++++++++++++ 1 file changed, 169 insertions(+) diff --git a/drivers/scsi/ufs/ufshcd-pci.c b/drivers/scsi/ufs/ufshcd-pci.c index fadd566025b8..23ee828747e2 100644 --- a/drivers/scsi/ufs/ufshcd-pci.c +++ b/drivers/scsi/ufs/ufshcd-pci.c @@ -15,13 +15,89 @@ #include #include #include +#include +#include +#include + +struct ufs_host { + void (*late_init)(struct ufs_hba *hba); +}; + +enum { + INTEL_DSM_FNS = 0, + INTEL_DSM_RESET = 1, +}; struct intel_host { + struct ufs_host ufs_host; + u32 dsm_fns; u32 active_ltr; u32 idle_ltr; struct dentry *debugfs_root; + struct gpio_desc *reset_gpio; }; +static const guid_t intel_dsm_guid = + GUID_INIT(0x1A4832A0, 0x7D03, 0x43CA, + 0xB0, 0x20, 0xF6, 0xDC, 0xD1, 0x2A, 0x19, 0x50); + +static int __intel_dsm(struct intel_host *intel_host, struct device *dev, + unsigned int fn, u32 *result) +{ + union acpi_object *obj; + int err = 0; + size_t len; + + obj = acpi_evaluate_dsm(ACPI_HANDLE(dev), &intel_dsm_guid, 0, fn, NULL); + if (!obj) + return -EOPNOTSUPP; + + if (obj->type != ACPI_TYPE_BUFFER || obj->buffer.length < 1) { + err = -EINVAL; + goto out; + } + + len = min_t(size_t, obj->buffer.length, 4); + + *result = 0; + memcpy(result, obj->buffer.pointer, len); +out: + ACPI_FREE(obj); + + return err; +} + +static int intel_dsm(struct intel_host *intel_host, struct device *dev, + unsigned int fn, u32 *result) +{ + if (fn > 31 || !(intel_host->dsm_fns & (1 << fn))) + return -EOPNOTSUPP; + + return __intel_dsm(intel_host, dev, fn, result); +} + +static void intel_dsm_init(struct intel_host *intel_host, struct device *dev) +{ + int err; + + err = __intel_dsm(intel_host, dev, INTEL_DSM_FNS, &intel_host->dsm_fns); + dev_dbg(dev, "DSM fns %#x, error %d\n", intel_host->dsm_fns, err); +} + +static int ufs_intel_hce_enable_notify(struct ufs_hba *hba, + enum ufs_notify_change_status status) +{ + /* Cannot enable ICE until after HC enable */ + if (status == POST_CHANGE && hba->caps & UFSHCD_CAP_CRYPTO) { + u32 hce = ufshcd_readl(hba, REG_CONTROLLER_ENABLE); + + hce |= CRYPTO_GENERAL_ENABLE; + ufshcd_writel(hba, hce, REG_CONTROLLER_ENABLE); + } + + return 0; +} + static int ufs_intel_disable_lcc(struct ufs_hba *hba) { u32 attr = UIC_ARG_MIB(PA_LOCAL_TX_LCC_ENABLE); @@ -144,6 +220,41 @@ static void intel_remove_debugfs(struct ufs_hba *hba) debugfs_remove_recursive(host->debugfs_root); } +static int ufs_intel_device_reset(struct ufs_hba *hba) +{ + struct intel_host *host = ufshcd_get_variant(hba); + + if (host->dsm_fns & INTEL_DSM_RESET) { + u32 result = 0; + int err; + + err = intel_dsm(host, hba->dev, INTEL_DSM_RESET, &result); + if (!err && !result) + err = -EIO; + if (err) + dev_err(hba->dev, "%s: DSM error %d result %u\n", + __func__, err, result); + return err; + } + + if (!host->reset_gpio) + return -EOPNOTSUPP; + + gpiod_set_value_cansleep(host->reset_gpio, 1); + usleep_range(10, 15); + + gpiod_set_value_cansleep(host->reset_gpio, 0); + usleep_range(10, 15); + + return 0; +} + +static struct gpio_desc *ufs_intel_get_reset_gpio(struct device *dev) +{ + /* GPIO in _DSD has active low setting */ + return devm_gpiod_get_optional(dev, "reset", GPIOD_OUT_LOW); +} + static int ufs_intel_common_init(struct ufs_hba *hba) { struct intel_host *host; @@ -154,6 +265,23 @@ static int ufs_intel_common_init(struct ufs_hba *hba) if (!host) return -ENOMEM; ufshcd_set_variant(hba, host); + intel_dsm_init(host, hba->dev); + if (host->dsm_fns & INTEL_DSM_RESET) { + if (hba->vops->device_reset) + hba->caps |= UFSHCD_CAP_DEEPSLEEP; + } else { + if (hba->vops->device_reset) + host->reset_gpio = ufs_intel_get_reset_gpio(hba->dev); + if (IS_ERR(host->reset_gpio)) { + dev_err(hba->dev, "%s: failed to get reset GPIO, error %ld\n", + __func__, PTR_ERR(host->reset_gpio)); + host->reset_gpio = NULL; + } + if (host->reset_gpio) { + gpiod_set_value_cansleep(host->reset_gpio, 0); + hba->caps |= UFSHCD_CAP_DEEPSLEEP; + } + } intel_ltr_expose(hba->dev); intel_add_debugfs(hba); return 0; @@ -206,6 +334,31 @@ static int ufs_intel_ehl_init(struct ufs_hba *hba) return ufs_intel_common_init(hba); } +static void ufs_intel_lkf_late_init(struct ufs_hba *hba) +{ + /* LKF always needs a full reset, so set PM accordingly */ + if (hba->caps & UFSHCD_CAP_DEEPSLEEP) { + hba->spm_lvl = UFS_PM_LVL_6; + hba->rpm_lvl = UFS_PM_LVL_6; + } else { + hba->spm_lvl = UFS_PM_LVL_5; + hba->rpm_lvl = UFS_PM_LVL_5; + } +} + +static int ufs_intel_lkf_init(struct ufs_hba *hba) +{ + struct ufs_host *ufs_host; + int err; + + hba->quirks |= UFSHCD_QUIRK_BROKEN_AUTO_HIBERN8; + hba->caps |= UFSHCD_CAP_CRYPTO; + err = ufs_intel_common_init(hba); + ufs_host = ufshcd_get_variant(hba); + ufs_host->late_init = ufs_intel_lkf_late_init; + return err; +} + static struct ufs_hba_variant_ops ufs_intel_cnl_hba_vops = { .name = "intel-pci", .init = ufs_intel_common_init, @@ -222,6 +375,16 @@ static struct ufs_hba_variant_ops ufs_intel_ehl_hba_vops = { .resume = ufs_intel_resume, }; +static struct ufs_hba_variant_ops ufs_intel_lkf_hba_vops = { + .name = "intel-pci", + .init = ufs_intel_lkf_init, + .exit = ufs_intel_common_exit, + .hce_enable_notify = ufs_intel_hce_enable_notify, + .link_startup_notify = ufs_intel_link_startup_notify, + .resume = ufs_intel_resume, + .device_reset = ufs_intel_device_reset, +}; + #ifdef CONFIG_PM_SLEEP /** * ufshcd_pci_suspend - suspend power management function @@ -321,6 +484,7 @@ static void ufshcd_pci_remove(struct pci_dev *pdev) static int ufshcd_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id) { + struct ufs_host *ufs_host; struct ufs_hba *hba; void __iomem *mmio_base; int err; @@ -358,6 +522,10 @@ ufshcd_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id) return err; } + ufs_host = ufshcd_get_variant(hba); + if (ufs_host && ufs_host->late_init) + ufs_host->late_init(hba); + pm_runtime_put_noidle(&pdev->dev); pm_runtime_allow(&pdev->dev); @@ -383,6 +551,7 @@ static const struct pci_device_id ufshcd_pci_tbl[] = { { PCI_VDEVICE(INTEL, 0x9DFA), (kernel_ulong_t)&ufs_intel_cnl_hba_vops }, { PCI_VDEVICE(INTEL, 0x4B41), (kernel_ulong_t)&ufs_intel_ehl_hba_vops }, { PCI_VDEVICE(INTEL, 0x4B43), (kernel_ulong_t)&ufs_intel_ehl_hba_vops }, + { PCI_VDEVICE(INTEL, 0x98FA), (kernel_ulong_t)&ufs_intel_lkf_hba_vops }, { } /* terminate list */ }; From a1c4d7741323eff1d9c5baca8337ac3ac4630649 Mon Sep 17 00:00:00 2001 From: "Gustavo A. R. Silva" Date: Wed, 10 Mar 2021 17:59:51 -0600 Subject: [PATCH 163/412] scsi: mpt3sas: Replace unnecessary dynamic allocation with a static one MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Dynamic memory allocation isn't actually needed and it can be replaced by statically allocating memory for struct object io_unit_pg3 with 36 hardcoded entries for its GPIOVal array. Also, this helps the with ongoing efforts to enable -Warray-bounds by fixing the following warning: drivers/scsi/mpt3sas/mpt3sas_ctl.c: In function ‘BRM_status_show’: drivers/scsi/mpt3sas/mpt3sas_ctl.c:3257:63: warning: array subscript 24 is above array bounds of ‘U16[1]’ {aka ‘short unsigned int[1]’} [-Warray-bounds] 3257 | backup_rail_monitor_status = le16_to_cpu(io_unit_pg3->GPIOVal[24]); ./include/uapi/linux/byteorder/little_endian.h:36:51: note: in definition of macro ‘__le16_to_cpu’ 36 | #define __le16_to_cpu(x) ((__force __u16)(__le16)(x)) | ^ drivers/scsi/mpt3sas/mpt3sas_ctl.c:3257:31: note: in expansion of macro ‘le16_to_cpu’ 3257 | backup_rail_monitor_status = le16_to_cpu(io_unit_pg3->GPIOVal[24]); Link: https://github.com/KSPP/linux/issues/109 Link: https://lore.kernel.org/lkml/202103101058.16ED27BE3@keescook/ Link: https://lore.kernel.org/r/20210310235951.GA108661@embeddedor Reviewed-by: Kees Cook Signed-off-by: Gustavo A. R. Silva Signed-off-by: Martin K. Petersen --- drivers/scsi/mpt3sas/mpi/mpi2_cnfg.h | 2 +- drivers/scsi/mpt3sas/mpt3sas_ctl.c | 24 ++++++++---------------- 2 files changed, 9 insertions(+), 17 deletions(-) diff --git a/drivers/scsi/mpt3sas/mpi/mpi2_cnfg.h b/drivers/scsi/mpt3sas/mpi/mpi2_cnfg.h index 43a3bf8ff428..d00431f553e1 100644 --- a/drivers/scsi/mpt3sas/mpi/mpi2_cnfg.h +++ b/drivers/scsi/mpt3sas/mpi/mpi2_cnfg.h @@ -992,7 +992,7 @@ typedef struct _MPI2_CONFIG_PAGE_IO_UNIT_1 { *one and check the value returned for GPIOCount at runtime. */ #ifndef MPI2_IO_UNIT_PAGE_3_GPIO_VAL_MAX -#define MPI2_IO_UNIT_PAGE_3_GPIO_VAL_MAX (1) +#define MPI2_IO_UNIT_PAGE_3_GPIO_VAL_MAX (36) #endif typedef struct _MPI2_CONFIG_PAGE_IO_UNIT_3 { diff --git a/drivers/scsi/mpt3sas/mpt3sas_ctl.c b/drivers/scsi/mpt3sas/mpt3sas_ctl.c index 8717412b8079..e7582fb8a93f 100644 --- a/drivers/scsi/mpt3sas/mpt3sas_ctl.c +++ b/drivers/scsi/mpt3sas/mpt3sas_ctl.c @@ -3203,7 +3203,7 @@ BRM_status_show(struct device *cdev, struct device_attribute *attr, { struct Scsi_Host *shost = class_to_shost(cdev); struct MPT3SAS_ADAPTER *ioc = shost_priv(shost); - Mpi2IOUnitPage3_t *io_unit_pg3 = NULL; + Mpi2IOUnitPage3_t io_unit_pg3; Mpi2ConfigReply_t mpi_reply; u16 backup_rail_monitor_status = 0; u16 ioc_status; @@ -3220,17 +3220,10 @@ BRM_status_show(struct device *cdev, struct device_attribute *attr, if (ioc->pci_error_recovery || ioc->remove_host) goto out; - /* allocate upto GPIOVal 36 entries */ - sz = offsetof(Mpi2IOUnitPage3_t, GPIOVal) + (sizeof(u16) * 36); - io_unit_pg3 = kzalloc(sz, GFP_KERNEL); - if (!io_unit_pg3) { - rc = -ENOMEM; - ioc_err(ioc, "%s: failed allocating memory for iounit_pg3: (%d) bytes\n", - __func__, sz); - goto out; - } + sz = sizeof(io_unit_pg3); + memset(&io_unit_pg3, 0, sz); - if (mpt3sas_config_get_iounit_pg3(ioc, &mpi_reply, io_unit_pg3, sz) != + if (mpt3sas_config_get_iounit_pg3(ioc, &mpi_reply, &io_unit_pg3, sz) != 0) { ioc_err(ioc, "%s: failed reading iounit_pg3\n", __func__); @@ -3246,19 +3239,18 @@ BRM_status_show(struct device *cdev, struct device_attribute *attr, goto out; } - if (io_unit_pg3->GPIOCount < 25) { - ioc_err(ioc, "%s: iounit_pg3->GPIOCount less than 25 entries, detected (%d) entries\n", - __func__, io_unit_pg3->GPIOCount); + if (io_unit_pg3.GPIOCount < 25) { + ioc_err(ioc, "%s: iounit_pg3.GPIOCount less than 25 entries, detected (%d) entries\n", + __func__, io_unit_pg3.GPIOCount); rc = -EINVAL; goto out; } /* BRM status is in bit zero of GPIOVal[24] */ - backup_rail_monitor_status = le16_to_cpu(io_unit_pg3->GPIOVal[24]); + backup_rail_monitor_status = le16_to_cpu(io_unit_pg3.GPIOVal[24]); rc = snprintf(buf, PAGE_SIZE, "%d\n", (backup_rail_monitor_status & 1)); out: - kfree(io_unit_pg3); mutex_unlock(&ioc->pci_access_mutex); return rc; } From d6adc251dd2fede6aaaf6c39f7e4ad799eda3758 Mon Sep 17 00:00:00 2001 From: Suganath Prabu S Date: Fri, 5 Mar 2021 15:58:58 +0530 Subject: [PATCH 164/412] scsi: mpt3sas: Force PCIe scatterlist allocations to be within same 4 GB region According to the MPI specification, PCIe SGL buffers can not cross a 4 GB boundary. While allocating, if any buffer crosses the 4 GB boundary, then: - Release the already allocated memory pools; and - Reallocate them by changing the DMA coherent mask to 32-bit Link: https://lore.kernel.org/r/20210305102904.7560-2-suganath-prabu.subramani@broadcom.com Signed-off-by: Suganath Prabu S Signed-off-by: Martin K. Petersen --- drivers/scsi/mpt3sas/mpt3sas_base.c | 159 ++++++++++++++++++++-------- drivers/scsi/mpt3sas/mpt3sas_base.h | 1 + 2 files changed, 113 insertions(+), 47 deletions(-) diff --git a/drivers/scsi/mpt3sas/mpt3sas_base.c b/drivers/scsi/mpt3sas/mpt3sas_base.c index 69586ab16cb6..5be85ffc8c2c 100644 --- a/drivers/scsi/mpt3sas/mpt3sas_base.c +++ b/drivers/scsi/mpt3sas/mpt3sas_base.c @@ -2905,23 +2905,22 @@ static int _base_config_dma_addressing(struct MPT3SAS_ADAPTER *ioc, struct pci_dev *pdev) { struct sysinfo s; - int dma_mask; if (ioc->is_mcpu_endpoint || sizeof(dma_addr_t) == 4 || ioc->use_32bit_dma || dma_get_required_mask(&pdev->dev) <= 32) - dma_mask = 32; + ioc->dma_mask = 32; /* Set 63 bit DMA mask for all SAS3 and SAS35 controllers */ else if (ioc->hba_mpi_version_belonged > MPI2_VERSION) - dma_mask = 63; + ioc->dma_mask = 63; else - dma_mask = 64; + ioc->dma_mask = 64; - if (dma_set_mask(&pdev->dev, DMA_BIT_MASK(dma_mask)) || - dma_set_coherent_mask(&pdev->dev, DMA_BIT_MASK(dma_mask))) + if (dma_set_mask(&pdev->dev, DMA_BIT_MASK(ioc->dma_mask)) || + dma_set_coherent_mask(&pdev->dev, DMA_BIT_MASK(ioc->dma_mask))) return -ENODEV; - if (dma_mask > 32) { + if (ioc->dma_mask > 32) { ioc->base_add_sg_single = &_base_add_sg_single_64; ioc->sge_size = sizeof(Mpi2SGESimple64_t); } else { @@ -2931,7 +2930,7 @@ _base_config_dma_addressing(struct MPT3SAS_ADAPTER *ioc, struct pci_dev *pdev) si_meminfo(&s); ioc_info(ioc, "%d BIT PCI BUS DMA ADDRESSING SUPPORTED, total mem (%ld kB)\n", - dma_mask, convert_to_kb(s.totalram)); + ioc->dma_mask, convert_to_kb(s.totalram)); return 0; } @@ -5337,10 +5336,10 @@ _base_release_memory_pools(struct MPT3SAS_ADAPTER *ioc) dma_pool_free(ioc->pcie_sgl_dma_pool, ioc->pcie_sg_lookup[i].pcie_sgl, ioc->pcie_sg_lookup[i].pcie_sgl_dma); + ioc->pcie_sg_lookup[i].pcie_sgl = NULL; } dma_pool_destroy(ioc->pcie_sgl_dma_pool); } - if (ioc->config_page) { dexitprintk(ioc, ioc_info(ioc, "config_page(0x%p): free\n", @@ -5398,6 +5397,89 @@ mpt3sas_check_same_4gb_region(long reply_pool_start_address, u32 pool_sz) return 0; } +/** + * _base_reduce_hba_queue_depth- Retry with reduced queue depth + * @ioc: Adapter object + * + * Return: 0 for success, non-zero for failure. + **/ +static inline int +_base_reduce_hba_queue_depth(struct MPT3SAS_ADAPTER *ioc) +{ + int reduce_sz = 64; + + if ((ioc->hba_queue_depth - reduce_sz) > + (ioc->internal_depth + INTERNAL_SCSIIO_CMDS_COUNT)) { + ioc->hba_queue_depth -= reduce_sz; + return 0; + } else + return -ENOMEM; +} + +/** + * _base_allocate_pcie_sgl_pool - Allocating DMA'able memory + * for pcie sgl pools. + * @ioc: Adapter object + * @sz: DMA Pool size + * @ct: Chain tracker + * Return: 0 for success, non-zero for failure. + */ + +static int +_base_allocate_pcie_sgl_pool(struct MPT3SAS_ADAPTER *ioc, u32 sz) +{ + int i = 0, j = 0; + struct chain_tracker *ct; + + ioc->pcie_sgl_dma_pool = + dma_pool_create("PCIe SGL pool", &ioc->pdev->dev, sz, + ioc->page_size, 0); + if (!ioc->pcie_sgl_dma_pool) { + ioc_err(ioc, "PCIe SGL pool: dma_pool_create failed\n"); + return -ENOMEM; + } + + ioc->chains_per_prp_buffer = sz/ioc->chain_segment_sz; + ioc->chains_per_prp_buffer = + min(ioc->chains_per_prp_buffer, ioc->chains_needed_per_io); + for (i = 0; i < ioc->scsiio_depth; i++) { + ioc->pcie_sg_lookup[i].pcie_sgl = + dma_pool_alloc(ioc->pcie_sgl_dma_pool, GFP_KERNEL, + &ioc->pcie_sg_lookup[i].pcie_sgl_dma); + if (!ioc->pcie_sg_lookup[i].pcie_sgl) { + ioc_err(ioc, "PCIe SGL pool: dma_pool_alloc failed\n"); + return -EAGAIN; + } + + if (!mpt3sas_check_same_4gb_region( + (long)ioc->pcie_sg_lookup[i].pcie_sgl, sz)) { + ioc_err(ioc, "PCIE SGLs are not in same 4G !! pcie sgl (0x%p) dma = (0x%llx)\n", + ioc->pcie_sg_lookup[i].pcie_sgl, + (unsigned long long) + ioc->pcie_sg_lookup[i].pcie_sgl_dma); + ioc->use_32bit_dma = true; + return -EAGAIN; + } + + for (j = 0; j < ioc->chains_per_prp_buffer; j++) { + ct = &ioc->chain_lookup[i].chains_per_smid[j]; + ct->chain_buffer = + ioc->pcie_sg_lookup[i].pcie_sgl + + (j * ioc->chain_segment_sz); + ct->chain_buffer_dma = + ioc->pcie_sg_lookup[i].pcie_sgl_dma + + (j * ioc->chain_segment_sz); + } + } + dinitprintk(ioc, ioc_info(ioc, + "PCIe sgl pool depth(%d), element_size(%d), pool_size(%d kB)\n", + ioc->scsiio_depth, sz, (sz * ioc->scsiio_depth)/1024)); + dinitprintk(ioc, ioc_info(ioc, + "Number of chains can fit in a PRP page(%d)\n", + ioc->chains_per_prp_buffer)); + return 0; +} + /** * base_alloc_rdpq_dma_pool - Allocating DMA'able memory * for reply queues. @@ -5496,7 +5578,7 @@ _base_allocate_memory_pools(struct MPT3SAS_ADAPTER *ioc) unsigned short sg_tablesize; u16 sge_size; int i, j; - int ret = 0; + int ret = 0, rc = 0; struct chain_tracker *ct; dinitprintk(ioc, ioc_info(ioc, "%s\n", __func__)); @@ -5801,6 +5883,7 @@ _base_allocate_memory_pools(struct MPT3SAS_ADAPTER *ioc) * be required for NVMe PRP's, only each set of NVMe blocks will be * contiguous, so a new set is allocated for each possible I/O. */ + ioc->chains_per_prp_buffer = 0; if (ioc->facts.ProtocolFlags & MPI2_IOCFACTS_PROTOCOL_NVME_DEVICES) { nvme_blocks_needed = @@ -5815,43 +5898,11 @@ _base_allocate_memory_pools(struct MPT3SAS_ADAPTER *ioc) goto out; } sz = nvme_blocks_needed * ioc->page_size; - ioc->pcie_sgl_dma_pool = - dma_pool_create("PCIe SGL pool", &ioc->pdev->dev, sz, 16, 0); - if (!ioc->pcie_sgl_dma_pool) { - ioc_info(ioc, "PCIe SGL pool: dma_pool_create failed\n"); - goto out; - } - - ioc->chains_per_prp_buffer = sz/ioc->chain_segment_sz; - ioc->chains_per_prp_buffer = min(ioc->chains_per_prp_buffer, - ioc->chains_needed_per_io); - - for (i = 0; i < ioc->scsiio_depth; i++) { - ioc->pcie_sg_lookup[i].pcie_sgl = dma_pool_alloc( - ioc->pcie_sgl_dma_pool, GFP_KERNEL, - &ioc->pcie_sg_lookup[i].pcie_sgl_dma); - if (!ioc->pcie_sg_lookup[i].pcie_sgl) { - ioc_info(ioc, "PCIe SGL pool: dma_pool_alloc failed\n"); - goto out; - } - for (j = 0; j < ioc->chains_per_prp_buffer; j++) { - ct = &ioc->chain_lookup[i].chains_per_smid[j]; - ct->chain_buffer = - ioc->pcie_sg_lookup[i].pcie_sgl + - (j * ioc->chain_segment_sz); - ct->chain_buffer_dma = - ioc->pcie_sg_lookup[i].pcie_sgl_dma + - (j * ioc->chain_segment_sz); - } - } - - dinitprintk(ioc, - ioc_info(ioc, "PCIe sgl pool depth(%d), element_size(%d), pool_size(%d kB)\n", - ioc->scsiio_depth, sz, - (sz * ioc->scsiio_depth) / 1024)); - dinitprintk(ioc, - ioc_info(ioc, "Number of chains can fit in a PRP page(%d)\n", - ioc->chains_per_prp_buffer)); + rc = _base_allocate_pcie_sgl_pool(ioc, sz); + if (rc == -ENOMEM) + return -ENOMEM; + else if (rc == -EAGAIN) + goto try_32bit_dma; total_sz += sz * ioc->scsiio_depth; } @@ -6021,6 +6072,19 @@ _base_allocate_memory_pools(struct MPT3SAS_ADAPTER *ioc) ioc->shost->sg_tablesize); return 0; +try_32bit_dma: + _base_release_memory_pools(ioc); + if (ioc->use_32bit_dma && (ioc->dma_mask > 32)) { + /* Change dma coherent mask to 32 bit and reallocate */ + if (_base_config_dma_addressing(ioc, ioc->pdev) != 0) { + pr_err("Setting 32 bit coherent DMA mask Failed %s\n", + pci_name(ioc->pdev)); + return -ENODEV; + } + } else if (_base_reduce_hba_queue_depth(ioc) != 0) + return -ENOMEM; + goto retry_allocation; + out: return -ENOMEM; } @@ -7681,6 +7745,7 @@ mpt3sas_base_attach(struct MPT3SAS_ADAPTER *ioc) ioc->rdpq_array_enable_assigned = 0; ioc->use_32bit_dma = false; + ioc->dma_mask = 64; if (ioc->is_aero_ioc) ioc->base_readl = &_base_readl_aero; else diff --git a/drivers/scsi/mpt3sas/mpt3sas_base.h b/drivers/scsi/mpt3sas/mpt3sas_base.h index 315aee6ef86f..b86eced75446 100644 --- a/drivers/scsi/mpt3sas/mpt3sas_base.h +++ b/drivers/scsi/mpt3sas/mpt3sas_base.h @@ -1371,6 +1371,7 @@ struct MPT3SAS_ADAPTER { u16 thresh_hold; u8 high_iops_queues; u32 drv_support_bitmap; + u32 dma_mask; bool enable_sdev_max_qd; bool use_32bit_dma; From 7dd847dae1c48f4a58f3ba672ed9141a2a774805 Mon Sep 17 00:00:00 2001 From: Suganath Prabu S Date: Fri, 5 Mar 2021 15:58:59 +0530 Subject: [PATCH 165/412] scsi: mpt3sas: Force chain buffer allocations to be within same 4 GB region According to the MPI specification, chain buffers can not cross a 4 GB boundary. While allocating, if any buffer crosses the 4 GB boundary, then: - Release the already allocated memory pools; and - Reallocate them by changing the DMA coherent mask to 32-bit Link: https://lore.kernel.org/r/20210305102904.7560-3-suganath-prabu.subramani@broadcom.com Signed-off-by: Suganath Prabu S Signed-off-by: Martin K. Petersen --- drivers/scsi/mpt3sas/mpt3sas_base.c | 83 ++++++++++++++++++++--------- 1 file changed, 57 insertions(+), 26 deletions(-) diff --git a/drivers/scsi/mpt3sas/mpt3sas_base.c b/drivers/scsi/mpt3sas/mpt3sas_base.c index 5be85ffc8c2c..fa593d34d12f 100644 --- a/drivers/scsi/mpt3sas/mpt3sas_base.c +++ b/drivers/scsi/mpt3sas/mpt3sas_base.c @@ -5480,6 +5480,52 @@ _base_allocate_pcie_sgl_pool(struct MPT3SAS_ADAPTER *ioc, u32 sz) return 0; } +/** + * _base_allocate_chain_dma_pool - Allocating DMA'able memory + * for chain dma pool. + * @ioc: Adapter object + * @sz: DMA Pool size + * @ctr: Chain tracker + * Return: 0 for success, non-zero for failure. + */ +static int +_base_allocate_chain_dma_pool(struct MPT3SAS_ADAPTER *ioc, u32 sz) +{ + int i = 0, j = 0; + struct chain_tracker *ctr; + + ioc->chain_dma_pool = dma_pool_create("chain pool", &ioc->pdev->dev, + ioc->chain_segment_sz, 16, 0); + if (!ioc->chain_dma_pool) + return -ENOMEM; + + for (i = 0; i < ioc->scsiio_depth; i++) { + for (j = ioc->chains_per_prp_buffer; + j < ioc->chains_needed_per_io; j++) { + ctr = &ioc->chain_lookup[i].chains_per_smid[j]; + ctr->chain_buffer = dma_pool_alloc(ioc->chain_dma_pool, + GFP_KERNEL, &ctr->chain_buffer_dma); + if (!ctr->chain_buffer) + return -EAGAIN; + if (!mpt3sas_check_same_4gb_region((long) + ctr->chain_buffer, ioc->chain_segment_sz)) { + ioc_err(ioc, + "Chain buffers are not in same 4G !!! Chain buff (0x%p) dma = (0x%llx)\n", + ctr->chain_buffer, + (unsigned long long)ctr->chain_buffer_dma); + ioc->use_32bit_dma = true; + return -EAGAIN; + } + } + } + dinitprintk(ioc, ioc_info(ioc, + "chain_lookup depth (%d), frame_size(%d), pool_size(%d kB)\n", + ioc->scsiio_depth, ioc->chain_segment_sz, ((ioc->scsiio_depth * + (ioc->chains_needed_per_io - ioc->chains_per_prp_buffer) * + ioc->chain_segment_sz))/1024)); + return 0; +} + /** * base_alloc_rdpq_dma_pool - Allocating DMA'able memory * for reply queues. @@ -5577,9 +5623,8 @@ _base_allocate_memory_pools(struct MPT3SAS_ADAPTER *ioc) u16 max_request_credit, nvme_blocks_needed; unsigned short sg_tablesize; u16 sge_size; - int i, j; + int i; int ret = 0, rc = 0; - struct chain_tracker *ct; dinitprintk(ioc, ioc_info(ioc, "%s\n", __func__)); @@ -5906,31 +5951,17 @@ _base_allocate_memory_pools(struct MPT3SAS_ADAPTER *ioc) total_sz += sz * ioc->scsiio_depth; } - ioc->chain_dma_pool = dma_pool_create("chain pool", &ioc->pdev->dev, - ioc->chain_segment_sz, 16, 0); - if (!ioc->chain_dma_pool) { - ioc_err(ioc, "chain_dma_pool: dma_pool_create failed\n"); - goto out; - } - for (i = 0; i < ioc->scsiio_depth; i++) { - for (j = ioc->chains_per_prp_buffer; - j < ioc->chains_needed_per_io; j++) { - ct = &ioc->chain_lookup[i].chains_per_smid[j]; - ct->chain_buffer = dma_pool_alloc( - ioc->chain_dma_pool, GFP_KERNEL, - &ct->chain_buffer_dma); - if (!ct->chain_buffer) { - ioc_err(ioc, "chain_lookup: pci_pool_alloc failed\n"); - goto out; - } - } - total_sz += ioc->chain_segment_sz; - } - + rc = _base_allocate_chain_dma_pool(ioc, ioc->chain_segment_sz); + if (rc == -ENOMEM) + return -ENOMEM; + else if (rc == -EAGAIN) + goto try_32bit_dma; + total_sz += ioc->chain_segment_sz * ((ioc->chains_needed_per_io - + ioc->chains_per_prp_buffer) * ioc->scsiio_depth); dinitprintk(ioc, - ioc_info(ioc, "chain pool depth(%d), frame_size(%d), pool_size(%d kB)\n", - ioc->chain_depth, ioc->chain_segment_sz, - (ioc->chain_depth * ioc->chain_segment_sz) / 1024)); + ioc_info(ioc, "chain pool depth(%d), frame_size(%d), pool_size(%d kB)\n", + ioc->chain_depth, ioc->chain_segment_sz, + (ioc->chain_depth * ioc->chain_segment_sz) / 1024)); /* sense buffers, 4 byte align */ sz = ioc->scsiio_depth * SCSI_SENSE_BUFFERSIZE; From 970ac2bb70e79a90eeb75496a523b8f1705d7a8c Mon Sep 17 00:00:00 2001 From: Suganath Prabu S Date: Fri, 5 Mar 2021 15:59:00 +0530 Subject: [PATCH 166/412] scsi: mpt3sas: Force sense buffer allocations to be within same 4 GB region According to the MPI specification, sense buffers can not cross a 4 GB boundary. While allocating, if any buffer crosses the 4 GB boundary, then: - Release the already allocated memory pools; and - Reallocate them by changing the DMA coherent mask to 32-bit Link: https://lore.kernel.org/r/20210305102904.7560-4-suganath-prabu.subramani@broadcom.com Signed-off-by: Suganath Prabu S Signed-off-by: Martin K. Petersen --- drivers/scsi/mpt3sas/mpt3sas_base.c | 86 ++++++++++++++--------------- 1 file changed, 40 insertions(+), 46 deletions(-) diff --git a/drivers/scsi/mpt3sas/mpt3sas_base.c b/drivers/scsi/mpt3sas/mpt3sas_base.c index fa593d34d12f..3416edf9057b 100644 --- a/drivers/scsi/mpt3sas/mpt3sas_base.c +++ b/drivers/scsi/mpt3sas/mpt3sas_base.c @@ -5526,6 +5526,38 @@ _base_allocate_chain_dma_pool(struct MPT3SAS_ADAPTER *ioc, u32 sz) return 0; } +/** + * _base_allocate_sense_dma_pool - Allocating DMA'able memory + * for sense dma pool. + * @ioc: Adapter object + * @sz: DMA Pool size + * Return: 0 for success, non-zero for failure. + */ +static int +_base_allocate_sense_dma_pool(struct MPT3SAS_ADAPTER *ioc, u32 sz) +{ + ioc->sense_dma_pool = + dma_pool_create("sense pool", &ioc->pdev->dev, sz, 4, 0); + if (!ioc->sense_dma_pool) + return -ENOMEM; + ioc->sense = dma_pool_alloc(ioc->sense_dma_pool, + GFP_KERNEL, &ioc->sense_dma); + if (!ioc->sense) + return -EAGAIN; + if (!mpt3sas_check_same_4gb_region((long)ioc->sense, sz)) { + dinitprintk(ioc, pr_err( + "Bad Sense Pool! sense (0x%p) sense_dma = (0x%llx)\n", + ioc->sense, (unsigned long long) ioc->sense_dma)); + ioc->use_32bit_dma = true; + return -EAGAIN; + } + ioc_info(ioc, + "sense pool(0x%p) - dma(0x%llx): depth(%d), element_size(%d), pool_size (%d kB)\n", + ioc->sense, (unsigned long long)ioc->sense_dma, + ioc->scsiio_depth, SCSI_SENSE_BUFFERSIZE, sz/1024); + return 0; +} + /** * base_alloc_rdpq_dma_pool - Allocating DMA'able memory * for reply queues. @@ -5619,7 +5651,7 @@ _base_allocate_memory_pools(struct MPT3SAS_ADAPTER *ioc) u16 chains_needed_per_io; u32 sz, total_sz, reply_post_free_sz, reply_post_free_array_sz; u32 retry_sz; - u32 rdpq_sz = 0; + u32 rdpq_sz = 0, sense_sz = 0; u16 max_request_credit, nvme_blocks_needed; unsigned short sg_tablesize; u16 sge_size; @@ -5962,58 +5994,20 @@ _base_allocate_memory_pools(struct MPT3SAS_ADAPTER *ioc) ioc_info(ioc, "chain pool depth(%d), frame_size(%d), pool_size(%d kB)\n", ioc->chain_depth, ioc->chain_segment_sz, (ioc->chain_depth * ioc->chain_segment_sz) / 1024)); - /* sense buffers, 4 byte align */ - sz = ioc->scsiio_depth * SCSI_SENSE_BUFFERSIZE; - ioc->sense_dma_pool = dma_pool_create("sense pool", &ioc->pdev->dev, sz, - 4, 0); - if (!ioc->sense_dma_pool) { - ioc_err(ioc, "sense pool: dma_pool_create failed\n"); - goto out; - } - ioc->sense = dma_pool_alloc(ioc->sense_dma_pool, GFP_KERNEL, - &ioc->sense_dma); - if (!ioc->sense) { - ioc_err(ioc, "sense pool: dma_pool_alloc failed\n"); - goto out; - } - /* sense buffer requires to be in same 4 gb region. - * Below function will check the same. - * In case of failure, new pci pool will be created with updated - * alignment. Older allocation and pool will be destroyed. - * Alignment will be used such a way that next allocation if - * success, will always meet same 4gb region requirement. - * Actual requirement is not alignment, but we need start and end of - * DMA address must have same upper 32 bit address. - */ - if (!mpt3sas_check_same_4gb_region((long)ioc->sense, sz)) { - //Release Sense pool & Reallocate - dma_pool_free(ioc->sense_dma_pool, ioc->sense, ioc->sense_dma); - dma_pool_destroy(ioc->sense_dma_pool); - ioc->sense = NULL; - - ioc->sense_dma_pool = - dma_pool_create("sense pool", &ioc->pdev->dev, sz, - roundup_pow_of_two(sz), 0); - if (!ioc->sense_dma_pool) { - ioc_err(ioc, "sense pool: pci_pool_create failed\n"); - goto out; - } - ioc->sense = dma_pool_alloc(ioc->sense_dma_pool, GFP_KERNEL, - &ioc->sense_dma); - if (!ioc->sense) { - ioc_err(ioc, "sense pool: pci_pool_alloc failed\n"); - goto out; - } - } + sense_sz = ioc->scsiio_depth * SCSI_SENSE_BUFFERSIZE; + rc = _base_allocate_sense_dma_pool(ioc, sense_sz); + if (rc == -ENOMEM) + return -ENOMEM; + else if (rc == -EAGAIN) + goto try_32bit_dma; + total_sz += sense_sz; ioc_info(ioc, "sense pool(0x%p)- dma(0x%llx): depth(%d)," "element_size(%d), pool_size(%d kB)\n", ioc->sense, (unsigned long long)ioc->sense_dma, ioc->scsiio_depth, SCSI_SENSE_BUFFERSIZE, sz / 1024); - total_sz += sz; - /* reply pool, 4 byte align */ sz = ioc->reply_free_queue_depth * ioc->reply_sz; ioc->reply_dma_pool = dma_pool_create("reply pool", &ioc->pdev->dev, sz, From 58501fd9375f76369c602a0b751a95d3376878e2 Mon Sep 17 00:00:00 2001 From: Suganath Prabu S Date: Fri, 5 Mar 2021 15:59:01 +0530 Subject: [PATCH 167/412] scsi: mpt3sas: Force reply buffer allocations to be within same 4 GB region According to the MPI specification, reply buffers can not cross a 4 GB boundary. While allocating, if any buffer crosses the 4 GB boundary, then: - Release the already allocated memory pools; and - Reallocate them by changing the DMA coherent mask to 32-bit Link: https://lore.kernel.org/r/20210305102904.7560-5-suganath-prabu.subramani@broadcom.com Signed-off-by: Suganath Prabu S Signed-off-by: Martin K. Petersen --- drivers/scsi/mpt3sas/mpt3sas_base.c | 63 ++++++++++++++++++----------- 1 file changed, 40 insertions(+), 23 deletions(-) diff --git a/drivers/scsi/mpt3sas/mpt3sas_base.c b/drivers/scsi/mpt3sas/mpt3sas_base.c index 3416edf9057b..2aedc7e82381 100644 --- a/drivers/scsi/mpt3sas/mpt3sas_base.c +++ b/drivers/scsi/mpt3sas/mpt3sas_base.c @@ -5558,6 +5558,41 @@ _base_allocate_sense_dma_pool(struct MPT3SAS_ADAPTER *ioc, u32 sz) return 0; } +/** + * _base_allocate_reply_pool - Allocating DMA'able memory + * for reply pool. + * @ioc: Adapter object + * @sz: DMA Pool size + * Return: 0 for success, non-zero for failure. + */ +static int +_base_allocate_reply_pool(struct MPT3SAS_ADAPTER *ioc, u32 sz) +{ + /* reply pool, 4 byte align */ + ioc->reply_dma_pool = dma_pool_create("reply pool", + &ioc->pdev->dev, sz, 4, 0); + if (!ioc->reply_dma_pool) + return -ENOMEM; + ioc->reply = dma_pool_alloc(ioc->reply_dma_pool, GFP_KERNEL, + &ioc->reply_dma); + if (!ioc->reply) + return -EAGAIN; + if (!mpt3sas_check_same_4gb_region((long)ioc->reply_free, sz)) { + dinitprintk(ioc, pr_err( + "Bad Reply Pool! Reply (0x%p) Reply dma = (0x%llx)\n", + ioc->reply, (unsigned long long) ioc->reply_dma)); + ioc->use_32bit_dma = true; + return -EAGAIN; + } + ioc->reply_dma_min_address = (u32)(ioc->reply_dma); + ioc->reply_dma_max_address = (u32)(ioc->reply_dma) + sz; + ioc_info(ioc, + "reply pool(0x%p) - dma(0x%llx): depth(%d), frame_size(%d), pool_size(%d kB)\n", + ioc->reply, (unsigned long long)ioc->reply_dma, + ioc->reply_free_queue_depth, ioc->reply_sz, sz/1024); + return 0; +} + /** * base_alloc_rdpq_dma_pool - Allocating DMA'able memory * for reply queues. @@ -6007,32 +6042,14 @@ _base_allocate_memory_pools(struct MPT3SAS_ADAPTER *ioc) "element_size(%d), pool_size(%d kB)\n", ioc->sense, (unsigned long long)ioc->sense_dma, ioc->scsiio_depth, SCSI_SENSE_BUFFERSIZE, sz / 1024); - /* reply pool, 4 byte align */ sz = ioc->reply_free_queue_depth * ioc->reply_sz; - ioc->reply_dma_pool = dma_pool_create("reply pool", &ioc->pdev->dev, sz, - 4, 0); - if (!ioc->reply_dma_pool) { - ioc_err(ioc, "reply pool: dma_pool_create failed\n"); - goto out; - } - ioc->reply = dma_pool_alloc(ioc->reply_dma_pool, GFP_KERNEL, - &ioc->reply_dma); - if (!ioc->reply) { - ioc_err(ioc, "reply pool: dma_pool_alloc failed\n"); - goto out; - } - ioc->reply_dma_min_address = (u32)(ioc->reply_dma); - ioc->reply_dma_max_address = (u32)(ioc->reply_dma) + sz; - dinitprintk(ioc, - ioc_info(ioc, "reply pool(0x%p): depth(%d), frame_size(%d), pool_size(%d kB)\n", - ioc->reply, ioc->reply_free_queue_depth, - ioc->reply_sz, sz / 1024)); - dinitprintk(ioc, - ioc_info(ioc, "reply_dma(0x%llx)\n", - (unsigned long long)ioc->reply_dma)); + rc = _base_allocate_reply_pool(ioc, sz); + if (rc == -ENOMEM) + return -ENOMEM; + else if (rc == -EAGAIN) + goto try_32bit_dma; total_sz += sz; - /* reply free queue, 16 byte align */ sz = ioc->reply_free_queue_depth * 4; ioc->reply_free_dma_pool = dma_pool_create("reply_free pool", From 2e4e8587327b37431e3205d09f541420d9d19266 Mon Sep 17 00:00:00 2001 From: Suganath Prabu S Date: Fri, 5 Mar 2021 15:59:02 +0530 Subject: [PATCH 168/412] scsi: mpt3sas: Force reply post buffer allocations to be within same 4 GB region According to the MPI specification, reply post buffers can not cross a 4 GB boundary. While allocating, if any buffer crosses the 4 GB boundary, then: - Release the already allocated memory pools; and - Reallocate them by changing the DMA coherent mask to 32-bit Link: https://lore.kernel.org/r/20210305102904.7560-6-suganath-prabu.subramani@broadcom.com Signed-off-by: Suganath Prabu S Signed-off-by: Martin K. Petersen --- drivers/scsi/mpt3sas/mpt3sas_base.c | 59 ++++++++++++++++++++--------- 1 file changed, 42 insertions(+), 17 deletions(-) diff --git a/drivers/scsi/mpt3sas/mpt3sas_base.c b/drivers/scsi/mpt3sas/mpt3sas_base.c index 2aedc7e82381..5a1783aba4a6 100644 --- a/drivers/scsi/mpt3sas/mpt3sas_base.c +++ b/drivers/scsi/mpt3sas/mpt3sas_base.c @@ -5593,6 +5593,42 @@ _base_allocate_reply_pool(struct MPT3SAS_ADAPTER *ioc, u32 sz) return 0; } +/** + * _base_allocate_reply_free_dma_pool - Allocating DMA'able memory + * for reply free dma pool. + * @ioc: Adapter object + * @sz: DMA Pool size + * Return: 0 for success, non-zero for failure. + */ +static int +_base_allocate_reply_free_dma_pool(struct MPT3SAS_ADAPTER *ioc, u32 sz) +{ + /* reply free queue, 16 byte align */ + ioc->reply_free_dma_pool = dma_pool_create( + "reply_free pool", &ioc->pdev->dev, sz, 16, 0); + if (!ioc->reply_free_dma_pool) + return -ENOMEM; + ioc->reply_free = dma_pool_alloc(ioc->reply_free_dma_pool, + GFP_KERNEL, &ioc->reply_free_dma); + if (!ioc->reply_free) + return -EAGAIN; + if (!mpt3sas_check_same_4gb_region((long)ioc->reply_free, sz)) { + dinitprintk(ioc, + pr_err("Bad Reply Free Pool! Reply Free (0x%p) Reply Free dma = (0x%llx)\n", + ioc->reply_free, (unsigned long long) ioc->reply_free_dma)); + ioc->use_32bit_dma = true; + return -EAGAIN; + } + memset(ioc->reply_free, 0, sz); + dinitprintk(ioc, ioc_info(ioc, + "reply_free pool(0x%p): depth(%d), element_size(%d), pool_size(%d kB)\n", + ioc->reply_free, ioc->reply_free_queue_depth, 4, sz/1024)); + dinitprintk(ioc, ioc_info(ioc, + "reply_free_dma (0x%llx)\n", + (unsigned long long)ioc->reply_free_dma)); + return 0; +} + /** * base_alloc_rdpq_dma_pool - Allocating DMA'able memory * for reply queues. @@ -6050,29 +6086,18 @@ _base_allocate_memory_pools(struct MPT3SAS_ADAPTER *ioc) else if (rc == -EAGAIN) goto try_32bit_dma; total_sz += sz; + /* reply free queue, 16 byte align */ sz = ioc->reply_free_queue_depth * 4; - ioc->reply_free_dma_pool = dma_pool_create("reply_free pool", - &ioc->pdev->dev, sz, 16, 0); - if (!ioc->reply_free_dma_pool) { - ioc_err(ioc, "reply_free pool: dma_pool_create failed\n"); - goto out; - } - ioc->reply_free = dma_pool_zalloc(ioc->reply_free_dma_pool, GFP_KERNEL, - &ioc->reply_free_dma); - if (!ioc->reply_free) { - ioc_err(ioc, "reply_free pool: dma_pool_alloc failed\n"); - goto out; - } - dinitprintk(ioc, - ioc_info(ioc, "reply_free pool(0x%p): depth(%d), element_size(%d), pool_size(%d kB)\n", - ioc->reply_free, ioc->reply_free_queue_depth, - 4, sz / 1024)); + rc = _base_allocate_reply_free_dma_pool(ioc, sz); + if (rc == -ENOMEM) + return -ENOMEM; + else if (rc == -EAGAIN) + goto try_32bit_dma; dinitprintk(ioc, ioc_info(ioc, "reply_free_dma (0x%llx)\n", (unsigned long long)ioc->reply_free_dma)); total_sz += sz; - if (ioc->rdpq_array_enable) { reply_post_free_array_sz = ioc->reply_queue_count * sizeof(Mpi2IOCInitRDPQArrayEntry); From c569de899bb41b7e8302636a76bf73bbdb80075a Mon Sep 17 00:00:00 2001 From: Suganath Prabu S Date: Fri, 5 Mar 2021 15:59:03 +0530 Subject: [PATCH 169/412] scsi: mpt3sas: Force reply post array allocations to be within same 4 GB region According to the MPI specification, reply post array buffers can not cross a 4 GB boundary. While allocating, if any buffer crosses the 4 GB boundary, then: - Release the already allocated memory pools; and - Reallocate them by changing the DMA coherent mask to 32-bit Link: https://lore.kernel.org/r/20210305102904.7560-7-suganath-prabu.subramani@broadcom.com Signed-off-by: Suganath Prabu S Signed-off-by: Martin K. Petersen --- drivers/scsi/mpt3sas/mpt3sas_base.c | 55 ++++++++++++++++++++--------- 1 file changed, 39 insertions(+), 16 deletions(-) diff --git a/drivers/scsi/mpt3sas/mpt3sas_base.c b/drivers/scsi/mpt3sas/mpt3sas_base.c index 5a1783aba4a6..891722fda7b4 100644 --- a/drivers/scsi/mpt3sas/mpt3sas_base.c +++ b/drivers/scsi/mpt3sas/mpt3sas_base.c @@ -5629,6 +5629,39 @@ _base_allocate_reply_free_dma_pool(struct MPT3SAS_ADAPTER *ioc, u32 sz) return 0; } +/** + * _base_allocate_reply_post_free_array - Allocating DMA'able memory + * for reply post free array. + * @ioc: Adapter object + * @reply_post_free_array_sz: DMA Pool size + * Return: 0 for success, non-zero for failure. + */ + +static int +_base_allocate_reply_post_free_array(struct MPT3SAS_ADAPTER *ioc, + u32 reply_post_free_array_sz) +{ + ioc->reply_post_free_array_dma_pool = + dma_pool_create("reply_post_free_array pool", + &ioc->pdev->dev, reply_post_free_array_sz, 16, 0); + if (!ioc->reply_post_free_array_dma_pool) + return -ENOMEM; + ioc->reply_post_free_array = + dma_pool_alloc(ioc->reply_post_free_array_dma_pool, + GFP_KERNEL, &ioc->reply_post_free_array_dma); + if (!ioc->reply_post_free_array) + return -EAGAIN; + if (!mpt3sas_check_same_4gb_region((long)ioc->reply_post_free_array, + reply_post_free_array_sz)) { + dinitprintk(ioc, pr_err( + "Bad Reply Free Pool! Reply Free (0x%p) Reply Free dma = (0x%llx)\n", + ioc->reply_free, + (unsigned long long) ioc->reply_free_dma)); + ioc->use_32bit_dma = true; + return -EAGAIN; + } + return 0; +} /** * base_alloc_rdpq_dma_pool - Allocating DMA'able memory * for reply queues. @@ -6101,22 +6134,12 @@ _base_allocate_memory_pools(struct MPT3SAS_ADAPTER *ioc) if (ioc->rdpq_array_enable) { reply_post_free_array_sz = ioc->reply_queue_count * sizeof(Mpi2IOCInitRDPQArrayEntry); - ioc->reply_post_free_array_dma_pool = - dma_pool_create("reply_post_free_array pool", - &ioc->pdev->dev, reply_post_free_array_sz, 16, 0); - if (!ioc->reply_post_free_array_dma_pool) { - dinitprintk(ioc, - ioc_info(ioc, "reply_post_free_array pool: dma_pool_create failed\n")); - goto out; - } - ioc->reply_post_free_array = - dma_pool_alloc(ioc->reply_post_free_array_dma_pool, - GFP_KERNEL, &ioc->reply_post_free_array_dma); - if (!ioc->reply_post_free_array) { - dinitprintk(ioc, - ioc_info(ioc, "reply_post_free_array pool: dma_pool_alloc failed\n")); - goto out; - } + rc = _base_allocate_reply_post_free_array(ioc, + reply_post_free_array_sz); + if (rc == -ENOMEM) + return -ENOMEM; + else if (rc == -EAGAIN) + goto try_32bit_dma; } ioc->config_page_sz = 512; ioc->config_page = dma_alloc_coherent(&ioc->pdev->dev, From 37067b97930931c3fe77cf8a3a6d6d43b708808b Mon Sep 17 00:00:00 2001 From: Suganath Prabu S Date: Fri, 5 Mar 2021 15:59:04 +0530 Subject: [PATCH 170/412] scsi: mpt3sas: Update driver version to 37.101.00.00 Update driver version to 37.101.00.00. Link: https://lore.kernel.org/r/20210305102904.7560-8-suganath-prabu.subramani@broadcom.com Signed-off-by: Suganath Prabu S Signed-off-by: Martin K. Petersen --- drivers/scsi/mpt3sas/mpt3sas_base.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/scsi/mpt3sas/mpt3sas_base.h b/drivers/scsi/mpt3sas/mpt3sas_base.h index b86eced75446..98558d9c8c2d 100644 --- a/drivers/scsi/mpt3sas/mpt3sas_base.h +++ b/drivers/scsi/mpt3sas/mpt3sas_base.h @@ -77,9 +77,9 @@ #define MPT3SAS_DRIVER_NAME "mpt3sas" #define MPT3SAS_AUTHOR "Avago Technologies " #define MPT3SAS_DESCRIPTION "LSI MPT Fusion SAS 3.0 Device Driver" -#define MPT3SAS_DRIVER_VERSION "37.100.00.00" +#define MPT3SAS_DRIVER_VERSION "37.101.00.00" #define MPT3SAS_MAJOR_VERSION 37 -#define MPT3SAS_MINOR_VERSION 100 +#define MPT3SAS_MINOR_VERSION 101 #define MPT3SAS_BUILD_VERSION 0 #define MPT3SAS_RELEASE_VERSION 00 From 59f90f5e6c80a46ac5c19d11830b07a0ebd714af Mon Sep 17 00:00:00 2001 From: Jiapeng Chong Date: Thu, 18 Feb 2021 18:16:11 +0800 Subject: [PATCH 171/412] scsi: mvumi: Use true and false for bool variable Fix the following coccicheck warnings: ./drivers/scsi/mvumi.c:69:9-10: WARNING: return of 0/1 in function 'tag_is_empty' with return type bool. Link: https://lore.kernel.org/r/1613643371-122635-1-git-send-email-jiapeng.chong@linux.alibaba.com Reported-by: Abaci Robot Signed-off-by: Jiapeng Chong Signed-off-by: Martin K. Petersen --- drivers/scsi/mvumi.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/scsi/mvumi.c b/drivers/scsi/mvumi.c index 71b6a1f834cd..7cc1143ab9b0 100644 --- a/drivers/scsi/mvumi.c +++ b/drivers/scsi/mvumi.c @@ -66,9 +66,9 @@ static void tag_release_one(struct mvumi_hba *mhba, struct mvumi_tag *st, static bool tag_is_empty(struct mvumi_tag *st) { if (st->top == 0) - return 1; + return true; else - return 0; + return false; } static void mvumi_unmap_pci_addr(struct pci_dev *dev, void **addr_array) From 2af0bf34ae1fa2c340457aa525fdc23c019bbeef Mon Sep 17 00:00:00 2001 From: Yang Li Date: Tue, 9 Mar 2021 14:41:04 +0800 Subject: [PATCH 172/412] scsi: 3w-sas: Remove unneeded variable 'retval' Fix the following coccicheck warning: ./drivers/scsi/3w-sas.c:866:5-11: Unneeded variable: "retval". Return "1" on line 898 Link: https://lore.kernel.org/r/1615272064-42109-1-git-send-email-yang.lee@linux.alibaba.com Reported-by: Abaci Robot Signed-off-by: Yang Li Signed-off-by: Martin K. Petersen --- drivers/scsi/3w-sas.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/scsi/3w-sas.c b/drivers/scsi/3w-sas.c index 383f6f204c24..4fde39da54e4 100644 --- a/drivers/scsi/3w-sas.c +++ b/drivers/scsi/3w-sas.c @@ -860,7 +860,6 @@ static int twl_fill_sense(TW_Device_Extension *tw_dev, int i, int request_id, in TW_Command_Full *full_command_packet; unsigned short error; char *error_str; - int retval = 1; header = tw_dev->sense_buffer_virt[i]; full_command_packet = tw_dev->command_packet_virt[request_id]; @@ -892,7 +891,7 @@ static int twl_fill_sense(TW_Device_Extension *tw_dev, int i, int request_id, in goto out; } out: - return retval; + return 1; } /* End twl_fill_sense() */ /* This function will free up device extension resources */ From 2ed0fc2b9a798177fb41ccc7db5c5f3b59985a65 Mon Sep 17 00:00:00 2001 From: Jiapeng Chong Date: Tue, 9 Mar 2021 17:37:48 +0800 Subject: [PATCH 173/412] scsi: csiostor: Assign boolean values to a bool variable Fix the following coccicheck warnings: ./drivers/scsi/csiostor/csio_scsi.c:150:9-10: WARNING: return of 0/1 in function 'csio_scsi_itnexus_loss_error' with return type bool. Link: https://lore.kernel.org/r/1615282668-36935-1-git-send-email-jiapeng.chong@linux.alibaba.com Reported-by: Abaci Robot Signed-off-by: Jiapeng Chong Signed-off-by: Martin K. Petersen --- drivers/scsi/csiostor/csio_scsi.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/scsi/csiostor/csio_scsi.c b/drivers/scsi/csiostor/csio_scsi.c index 55e74da2f3cb..56b9ad0a1ca0 100644 --- a/drivers/scsi/csiostor/csio_scsi.c +++ b/drivers/scsi/csiostor/csio_scsi.c @@ -147,9 +147,9 @@ csio_scsi_itnexus_loss_error(uint16_t error) case FW_ERR_RDEV_LOST: case FW_ERR_RDEV_LOGO: case FW_ERR_RDEV_IMPL_LOGO: - return 1; + return true; } - return 0; + return false; } /* From 1bf5fa1a2916b779055d97fbb4e0fdd90dadcf63 Mon Sep 17 00:00:00 2001 From: Bhaskar Chowdhury Date: Mon, 15 Mar 2021 07:46:10 +0530 Subject: [PATCH 174/412] scsi: qla1280: Spelling fixes s/quantites/quantities/ s/Unfortunely/Unfortunately/ Link: https://lore.kernel.org/r/20210315021610.2089087-1-unixbhaskar@gmail.com Acked-by: Randy Dunlap Signed-off-by: Bhaskar Chowdhury Signed-off-by: Martin K. Petersen --- drivers/scsi/qla1280.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/scsi/qla1280.c b/drivers/scsi/qla1280.c index 46de2541af25..95008811b2d2 100644 --- a/drivers/scsi/qla1280.c +++ b/drivers/scsi/qla1280.c @@ -633,13 +633,13 @@ static int qla1280_read_nvram(struct scsi_qla_host *ha) * to be read a word (two bytes) at a time. * * The net result of this would be that the word (and - * doubleword) quantites in the firmware would be correct, but + * doubleword) quantities in the firmware would be correct, but * the bytes would be pairwise reversed. Since most of the - * firmware quantites are, in fact, bytes, we do an extra + * firmware quantities are, in fact, bytes, we do an extra * le16_to_cpu() in the firmware read routine. * * The upshot of all this is that the bytes in the firmware - * are in the correct places, but the 16 and 32 bit quantites + * are in the correct places, but the 16 and 32 bit quantities * are still in little endian format. We fix that up below by * doing extra reverses on them */ nv->isp_parameter = cpu_to_le16(nv->isp_parameter); @@ -687,7 +687,7 @@ qla1280_info(struct Scsi_Host *host) * The mid-level driver tries to ensures that queuecommand never gets invoked * concurrently with itself or the interrupt handler (although the * interrupt handler may call this routine as part of request-completion - * handling). Unfortunely, it sometimes calls the scheduler in interrupt + * handling). Unfortunately, it sometimes calls the scheduler in interrupt * context which is a big NO! NO!. **************************************************************************/ static int From ac5669bf79d976f5903e0acb98ccd5c1cb7789c8 Mon Sep 17 00:00:00 2001 From: ganjisheng Date: Tue, 16 Mar 2021 10:51:41 +0800 Subject: [PATCH 175/412] scsi: 53c700: Fix spelling of conditions Link: https://lore.kernel.org/r/20210316025141.824-1-qiumibaozi_1@163.com Signed-off-by: ganjisheng Signed-off-by: Martin K. Petersen --- drivers/scsi/53c700.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/scsi/53c700.c b/drivers/scsi/53c700.c index 3242ff63986f..4fd91f81244d 100644 --- a/drivers/scsi/53c700.c +++ b/drivers/scsi/53c700.c @@ -980,7 +980,7 @@ process_script_interrupt(__u32 dsps, __u32 dsp, struct scsi_cmnd *SCp, NCR_700_set_tag_neg_state(SCp->device, NCR_700_FINISHED_TAG_NEGOTIATION); - /* check for contingent allegiance contitions */ + /* check for contingent allegiance conditions */ if(status_byte(hostdata->status[0]) == CHECK_CONDITION || status_byte(hostdata->status[0]) == COMMAND_TERMINATED) { struct NCR_700_command_slot *slot = From bcf064bc2a3be706d63c3dc23b00d4e9a0771662 Mon Sep 17 00:00:00 2001 From: Bhaskar Chowdhury Date: Wed, 17 Mar 2021 14:52:40 +0530 Subject: [PATCH 176/412] scsi: fnic: Rudimentary spelling fixes Rudimentary typo fixes throughout the fnic_trace.c file. Link: https://lore.kernel.org/r/20210317092240.927822-1-unixbhaskar@gmail.com Acked-by: Randy Dunlap Signed-off-by: Bhaskar Chowdhury Signed-off-by: Martin K. Petersen --- drivers/scsi/fnic/fnic_trace.c | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/drivers/scsi/fnic/fnic_trace.c b/drivers/scsi/fnic/fnic_trace.c index 9d52d83161ed..4a7536bb0ab3 100644 --- a/drivers/scsi/fnic/fnic_trace.c +++ b/drivers/scsi/fnic/fnic_trace.c @@ -153,7 +153,7 @@ int fnic_get_trace_data(fnic_dbgfs_t *fnic_dbgfs_prt) if (rd_idx > (fnic_max_trace_entries-1)) rd_idx = 0; /* - * Continure dumpping trace buffer entries into + * Continue dumping trace buffer entries into * memory file till rd_idx reaches write index */ if (rd_idx == wr_idx) @@ -189,7 +189,7 @@ int fnic_get_trace_data(fnic_dbgfs_t *fnic_dbgfs_prt) tbp->data[3], tbp->data[4]); rd_idx++; /* - * Continue dumpping trace buffer entries into + * Continue dumping trace buffer entries into * memory file till rd_idx reaches write index */ if (rd_idx == wr_idx) @@ -632,7 +632,7 @@ void fnic_fc_trace_free(void) * fnic_fc_ctlr_set_trace_data: * Maintain rd & wr idx accordingly and set data * Passed parameters: - * host_no: host number accociated with fnic + * host_no: host number associated with fnic * frame_type: send_frame, rece_frame or link event * fc_frame: pointer to fc_frame * frame_len: Length of the fc_frame @@ -715,13 +715,13 @@ int fnic_fc_trace_set_data(u32 host_no, u8 frame_type, * fnic_fc_ctlr_get_trace_data: Copy trace buffer to a memory file * Passed parameter: * @fnic_dbgfs_t: pointer to debugfs trace buffer - * rdata_flag: 1 => Unformated file - * 0 => formated file + * rdata_flag: 1 => Unformatted file + * 0 => formatted file * Description: * This routine will copy the trace data to memory file with * proper formatting and also copy to another memory - * file without formatting for further procesing. - * Retrun Value: + * file without formatting for further processing. + * Return Value: * Number of bytes that were dumped into fnic_dbgfs_t */ @@ -785,10 +785,10 @@ int fnic_fc_trace_get_data(fnic_dbgfs_t *fnic_dbgfs_prt, u8 rdata_flag) * @fc_trace_hdr_t: pointer to trace data * @fnic_dbgfs_t: pointer to debugfs trace buffer * @orig_len: pointer to len - * rdata_flag: 0 => Formated file, 1 => Unformated file + * rdata_flag: 0 => Formatted file, 1 => Unformatted file * Description: * This routine will format and copy the passed trace data - * for formated file or unformated file accordingly. + * for formatted file or unformatted file accordingly. */ void copy_and_format_trace_data(struct fc_trace_hdr *tdata, From 69a1709e2ec84b3846327d34d0749a6f2e7803dd Mon Sep 17 00:00:00 2001 From: Bhaskar Chowdhury Date: Wed, 17 Mar 2021 15:42:38 +0530 Subject: [PATCH 177/412] scsi: fusion: Fix a typo in the file mptbase.h s/contets/contents/ Link: https://lore.kernel.org/r/20210317101238.2627574-1-unixbhaskar@gmail.com Acked-by: Randy Dunlap Signed-off-by: Bhaskar Chowdhury Signed-off-by: Martin K. Petersen --- drivers/message/fusion/mptbase.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/message/fusion/mptbase.h b/drivers/message/fusion/mptbase.h index 813d46311f6a..b9e0376be723 100644 --- a/drivers/message/fusion/mptbase.h +++ b/drivers/message/fusion/mptbase.h @@ -274,7 +274,7 @@ typedef union _MPT_FRAME_TRACKER { } linkage; /* * NOTE: When request frames are free, on the linkage structure - * contets are valid. All other values are invalid. + * contents are valid. All other values are invalid. * In particular, do NOT reply on offset [2] * (in words) being the * message context. * The message context must be reset (computed via base address From 3b5f3c0d0548b8d963030b8728e380d6d57aa471 Mon Sep 17 00:00:00 2001 From: Yue Hu Date: Thu, 18 Mar 2021 17:55:36 +0800 Subject: [PATCH 178/412] scsi: ufs: core: Tidy up WB configuration code There are similar code implementations for WB configuration in ufshcd_wb_{ctrl, toggle_flush_during_h8, toggle_flush}. Extract the common parts to create a new helper with a flag parameter to reduce code duplication. Meanwhile, rename ufshcd_wb_ctrl() to ufshcd_wb_toggle() for better readability. And remove unnecessary log messages from ufshcd_wb_config() since relevant toggle function will emit messages. Also change ufshcd_wb_toggle_flush{__during_h8} to void type accordingly. Link: https://lore.kernel.org/r/20210318095536.2048-1-zbestahu@gmail.com Reviewed-by: Avri Altman Signed-off-by: Yue Hu Signed-off-by: Martin K. Petersen --- drivers/scsi/ufs/ufs-sysfs.c | 2 +- drivers/scsi/ufs/ufshcd.c | 103 ++++++++++++++--------------------- drivers/scsi/ufs/ufshcd.h | 2 +- 3 files changed, 44 insertions(+), 63 deletions(-) diff --git a/drivers/scsi/ufs/ufs-sysfs.c b/drivers/scsi/ufs/ufs-sysfs.c index acc54f530f2d..d7c3cff9662f 100644 --- a/drivers/scsi/ufs/ufs-sysfs.c +++ b/drivers/scsi/ufs/ufs-sysfs.c @@ -246,7 +246,7 @@ static ssize_t wb_on_store(struct device *dev, struct device_attribute *attr, } pm_runtime_get_sync(hba->dev); - res = ufshcd_wb_ctrl(hba, wb_enable); + res = ufshcd_wb_toggle(hba, wb_enable); pm_runtime_put_sync(hba->dev); out: up(&hba->host_sem); diff --git a/drivers/scsi/ufs/ufshcd.c b/drivers/scsi/ufs/ufshcd.c index ab9a1b15d223..95fd813068a7 100644 --- a/drivers/scsi/ufs/ufshcd.c +++ b/drivers/scsi/ufs/ufshcd.c @@ -246,8 +246,8 @@ static int ufshcd_setup_vreg(struct ufs_hba *hba, bool on); static inline int ufshcd_config_vreg_hpm(struct ufs_hba *hba, struct ufs_vreg *vreg); static int ufshcd_try_to_abort_task(struct ufs_hba *hba, int tag); -static int ufshcd_wb_toggle_flush_during_h8(struct ufs_hba *hba, bool set); -static inline int ufshcd_wb_toggle_flush(struct ufs_hba *hba, bool enable); +static void ufshcd_wb_toggle_flush_during_h8(struct ufs_hba *hba, bool set); +static inline void ufshcd_wb_toggle_flush(struct ufs_hba *hba, bool enable); static void ufshcd_hba_vreg_set_lpm(struct ufs_hba *hba); static void ufshcd_hba_vreg_set_hpm(struct ufs_hba *hba); @@ -274,20 +274,12 @@ static inline void ufshcd_disable_irq(struct ufs_hba *hba) static inline void ufshcd_wb_config(struct ufs_hba *hba) { - int ret; - if (!ufshcd_is_wb_allowed(hba)) return; - ret = ufshcd_wb_ctrl(hba, true); - if (ret) - dev_err(hba->dev, "%s: Enable WB failed: %d\n", __func__, ret); - else - dev_info(hba->dev, "%s: Write Booster Configured\n", __func__); - ret = ufshcd_wb_toggle_flush_during_h8(hba, true); - if (ret) - dev_err(hba->dev, "%s: En WB flush during H8: failed: %d\n", - __func__, ret); + ufshcd_wb_toggle(hba, true); + + ufshcd_wb_toggle_flush_during_h8(hba, true); if (!(hba->quirks & UFSHCI_QUIRK_SKIP_MANUAL_WB_FLUSH_CTRL)) ufshcd_wb_toggle_flush(hba, true); } @@ -1267,7 +1259,7 @@ static int ufshcd_devfreq_scale(struct ufs_hba *hba, bool scale_up) /* Enable Write Booster if we have scaled up else disable it */ downgrade_write(&hba->clk_scaling_lock); is_writelock = false; - ufshcd_wb_ctrl(hba, scale_up); + ufshcd_wb_toggle(hba, scale_up); out_unprepare: ufshcd_clock_scaling_unprepare(hba, is_writelock); @@ -5443,85 +5435,74 @@ out: __func__, err); } -int ufshcd_wb_ctrl(struct ufs_hba *hba, bool enable) +static int __ufshcd_wb_toggle(struct ufs_hba *hba, bool set, enum flag_idn idn) +{ + u8 index; + enum query_opcode opcode = set ? UPIU_QUERY_OPCODE_SET_FLAG : + UPIU_QUERY_OPCODE_CLEAR_FLAG; + + index = ufshcd_wb_get_query_index(hba); + return ufshcd_query_flag_retry(hba, opcode, idn, index, NULL); +} + +int ufshcd_wb_toggle(struct ufs_hba *hba, bool enable) { int ret; - u8 index; - enum query_opcode opcode; if (!ufshcd_is_wb_allowed(hba)) return 0; if (!(enable ^ hba->dev_info.wb_enabled)) return 0; - if (enable) - opcode = UPIU_QUERY_OPCODE_SET_FLAG; - else - opcode = UPIU_QUERY_OPCODE_CLEAR_FLAG; - index = ufshcd_wb_get_query_index(hba); - ret = ufshcd_query_flag_retry(hba, opcode, - QUERY_FLAG_IDN_WB_EN, index, NULL); + ret = __ufshcd_wb_toggle(hba, enable, QUERY_FLAG_IDN_WB_EN); if (ret) { - dev_err(hba->dev, "%s write booster %s failed %d\n", + dev_err(hba->dev, "%s Write Booster %s failed %d\n", __func__, enable ? "enable" : "disable", ret); return ret; } hba->dev_info.wb_enabled = enable; - dev_dbg(hba->dev, "%s write booster %s %d\n", - __func__, enable ? "enable" : "disable", ret); + dev_info(hba->dev, "%s Write Booster %s\n", + __func__, enable ? "enabled" : "disabled"); return ret; } -static int ufshcd_wb_toggle_flush_during_h8(struct ufs_hba *hba, bool set) -{ - int val; - u8 index; - - if (set) - val = UPIU_QUERY_OPCODE_SET_FLAG; - else - val = UPIU_QUERY_OPCODE_CLEAR_FLAG; - - index = ufshcd_wb_get_query_index(hba); - return ufshcd_query_flag_retry(hba, val, - QUERY_FLAG_IDN_WB_BUFF_FLUSH_DURING_HIBERN8, - index, NULL); -} - -static inline int ufshcd_wb_toggle_flush(struct ufs_hba *hba, bool enable) +static void ufshcd_wb_toggle_flush_during_h8(struct ufs_hba *hba, bool set) +{ + int ret; + + ret = __ufshcd_wb_toggle(hba, set, + QUERY_FLAG_IDN_WB_BUFF_FLUSH_DURING_HIBERN8); + if (ret) { + dev_err(hba->dev, "%s: WB-Buf Flush during H8 %s failed: %d\n", + __func__, set ? "enable" : "disable", ret); + return; + } + dev_dbg(hba->dev, "%s WB-Buf Flush during H8 %s\n", + __func__, set ? "enabled" : "disabled"); +} + +static inline void ufshcd_wb_toggle_flush(struct ufs_hba *hba, bool enable) { int ret; - u8 index; - enum query_opcode opcode; if (!ufshcd_is_wb_allowed(hba) || hba->dev_info.wb_buf_flush_enabled == enable) - return 0; + return; - if (enable) - opcode = UPIU_QUERY_OPCODE_SET_FLAG; - else - opcode = UPIU_QUERY_OPCODE_CLEAR_FLAG; - - index = ufshcd_wb_get_query_index(hba); - ret = ufshcd_query_flag_retry(hba, opcode, - QUERY_FLAG_IDN_WB_BUFF_FLUSH_EN, index, - NULL); + ret = __ufshcd_wb_toggle(hba, enable, QUERY_FLAG_IDN_WB_BUFF_FLUSH_EN); if (ret) { dev_err(hba->dev, "%s WB-Buf Flush %s failed %d\n", __func__, enable ? "enable" : "disable", ret); - goto out; + return; } hba->dev_info.wb_buf_flush_enabled = enable; - dev_dbg(hba->dev, "WB-Buf Flush %s\n", enable ? "enabled" : "disabled"); -out: - return ret; - + dev_dbg(hba->dev, "%s WB-Buf Flush %s\n", + __func__, enable ? "enabled" : "disabled"); } static bool ufshcd_wb_presrv_usrspc_keep_vcc_on(struct ufs_hba *hba, diff --git a/drivers/scsi/ufs/ufshcd.h b/drivers/scsi/ufs/ufshcd.h index 1af91661dc83..cb72695b77ab 100644 --- a/drivers/scsi/ufs/ufshcd.h +++ b/drivers/scsi/ufs/ufshcd.h @@ -1104,7 +1104,7 @@ int ufshcd_exec_raw_upiu_cmd(struct ufs_hba *hba, u8 *desc_buff, int *buff_len, enum query_opcode desc_op); -int ufshcd_wb_ctrl(struct ufs_hba *hba, bool enable); +int ufshcd_wb_toggle(struct ufs_hba *hba, bool enable); /* Wrapper functions for safely calling variant operations */ static inline const char *ufshcd_get_var_name(struct ufs_hba *hba) From b1ebd3b0e4664c4aa8362bd8abb61861dff61849 Mon Sep 17 00:00:00 2001 From: Mike Christie Date: Thu, 18 Mar 2021 17:58:58 -0500 Subject: [PATCH 179/412] scsi: target: Fix htmldocs warning in target_submit_prep() Fix warning: drivers/target/target_core_transport.c:1661: WARNING: Block quote ends without a blank line; unexpected unindent. Link: https://lore.kernel.org/r/20210318225858.11863-1-michael.christie@oracle.com Signed-off-by: Mike Christie Signed-off-by: Martin K. Petersen --- drivers/target/target_core_transport.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/target/target_core_transport.c b/drivers/target/target_core_transport.c index a75591c929c0..8fbfe75c5744 100644 --- a/drivers/target/target_core_transport.c +++ b/drivers/target/target_core_transport.c @@ -1659,6 +1659,7 @@ EXPORT_SYMBOL_GPL(target_init_cmd); * Returns: * - less than zero to signal failure. * - zero on success. + * * If failure is returned, lio will the callers queue_status to complete * the cmd. */ From 035e9f471691a16c32b389c8b2f236043a2a50d7 Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Tue, 16 Mar 2021 20:26:48 -0700 Subject: [PATCH 180/412] scsi: sbitmap: Silence a debug kernel warning triggered by sbitmap_put() All sbitmap code uses implied preemption protection to update sb->alloc_hint except sbitmap_put(). Using implied preemption protection is safe since the value of sb->alloc_hint only affects performance of sbitmap allocations but not their correctness. Change this_cpu_ptr() in sbitmap_put() into raw_cpu_ptr() to suppress the following kernel warning that appears with preemption debugging enabled (CONFIG_DEBUG_PREEMPT): BUG: using smp_processor_id() in preemptible [00000000] code: scsi_eh_0/152 caller is debug_smp_processor_id+0x17/0x20 CPU: 1 PID: 152 Comm: scsi_eh_0 Tainted: G W 5.12.0-rc1-dbg+ #6 Call Trace: show_stack+0x52/0x58 dump_stack+0xaf/0xf3 check_preemption_disabled+0xce/0xd0 debug_smp_processor_id+0x17/0x20 scsi_device_unbusy+0x13a/0x1c0 [scsi_mod] scsi_finish_command+0x4d/0x290 [scsi_mod] scsi_eh_flush_done_q+0x1e7/0x280 [scsi_mod] ata_scsi_port_error_handler+0x592/0x750 [libata] ata_scsi_error+0x1a0/0x1f0 [libata] scsi_error_handler+0x19e/0x330 [scsi_mod] kthread+0x222/0x250 ret_from_fork+0x1f/0x30 Link: https://lore.kernel.org/r/20210317032648.9080-1-bvanassche@acm.org Fixes: c548e62bcf6a ("scsi: sbitmap: Move allocation hint into sbitmap") Cc: Hannes Reinecke Cc: Omar Sandoval Reviewed-by: Ming Lei Reviewed-by: Christoph Hellwig Signed-off-by: Bart Van Assche Signed-off-by: Martin K. Petersen --- include/linux/sbitmap.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/linux/sbitmap.h b/include/linux/sbitmap.h index 3087e1f15fdd..2713e689ad66 100644 --- a/include/linux/sbitmap.h +++ b/include/linux/sbitmap.h @@ -324,7 +324,7 @@ static inline void sbitmap_put(struct sbitmap *sb, unsigned int bitnr) sbitmap_deferred_clear_bit(sb, bitnr); if (likely(sb->alloc_hint && !sb->round_robin && bitnr < sb->depth)) - *this_cpu_ptr(sb->alloc_hint) = bitnr; + *raw_cpu_ptr(sb->alloc_hint) = bitnr; } static inline int sbitmap_test_bit(struct sbitmap *sb, unsigned int bitnr) From 5c9e2596ed1dae031358b647f53cc6ee290e2124 Mon Sep 17 00:00:00 2001 From: Lee Jones Date: Wed, 17 Mar 2021 09:11:18 +0000 Subject: [PATCH 181/412] scsi: BusLogic: Supply __printf(x, y) formatting for blogic_msg() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fixes the following W=1 kernel build warning(s): In file included from drivers/scsi/BusLogic.c:51: drivers/scsi/BusLogic.c: In function ‘blogic_msg’: drivers/scsi/BusLogic.c:3591:2: warning: function ‘blogic_msg’ might be a candidate for ‘gnu_printf’ format attribute [-Wsuggest-attribute=format] Link: https://lore.kernel.org/r/20210317091125.2910058-2-lee.jones@linaro.org Cc: Khalid Aziz Cc: "James E.J. Bottomley" Cc: "Martin K. Petersen" Cc: "Leonard N. Zubkoff" Cc: linux-scsi@vger.kernel.org Acked-by: Khalid Aziz Signed-off-by: Lee Jones Signed-off-by: Martin K. Petersen --- drivers/scsi/BusLogic.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/scsi/BusLogic.c b/drivers/scsi/BusLogic.c index ccb061ab0a0a..0ac3f713fc21 100644 --- a/drivers/scsi/BusLogic.c +++ b/drivers/scsi/BusLogic.c @@ -3578,7 +3578,7 @@ Target Requested Completed Requested Completed Requested Completed\n\ /* blogic_msg prints Driver Messages. */ - +__printf(2, 4) static void blogic_msg(enum blogic_msglevel msglevel, char *fmt, struct blogic_adapter *adapter, ...) { From 66730771543f5fe72363a99035307feedcb1f7d3 Mon Sep 17 00:00:00 2001 From: Lee Jones Date: Wed, 17 Mar 2021 09:11:19 +0000 Subject: [PATCH 182/412] scsi: nsp32: Supply __printf(x, y) formatting for nsp32_message() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fixes the following W=1 kernel build warning(s): drivers/scsi/nsp32.c: In function ‘nsp32_message’: drivers/scsi/nsp32.c:318:2: warning: function ‘nsp32_message’ might be a candidate for ‘gnu_printf’ format attribute [-Wsuggest-attribute=format] Link: https://lore.kernel.org/r/20210317091125.2910058-3-lee.jones@linaro.org Cc: GOTO Masanori Cc: YOKOTA Hiroshi Cc: "James E.J. Bottomley" Cc: "Martin K. Petersen" Cc: gotom@debian.org Cc: linux-scsi@vger.kernel.org Signed-off-by: Lee Jones Signed-off-by: Martin K. Petersen --- drivers/scsi/nsp32.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/scsi/nsp32.c b/drivers/scsi/nsp32.c index e44b1a0f6709..d5aa96f05bce 100644 --- a/drivers/scsi/nsp32.c +++ b/drivers/scsi/nsp32.c @@ -309,6 +309,7 @@ static struct scsi_host_template nsp32_template = { #define NSP32_DEBUG_BUF_LEN 100 +__printf(4, 5) static void nsp32_message(const char *func, int line, char *type, char *fmt, ...) { va_list args; From 94685e7a8cf6441a128a0e0855067648ce379a05 Mon Sep 17 00:00:00 2001 From: Lee Jones Date: Wed, 17 Mar 2021 09:11:20 +0000 Subject: [PATCH 183/412] scsi: nsp32: Remove or exclude unused variables MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fixes the following W=1 kernel build warning(s): drivers/scsi/nsp32.c: In function ‘nsp32_selection_autoscsi’: drivers/scsi/nsp32.c:584:17: warning: variable ‘execph’ set but not used [-Wunused-but-set-variable] drivers/scsi/nsp32.c: In function ‘nsp32_msgout_occur’: drivers/scsi/nsp32.c:1785:7: warning: variable ‘new_sgtp’ set but not used [-Wunused-but-set-variable] drivers/scsi/nsp32.c: In function ‘nsp32_analyze_sdtr’: drivers/scsi/nsp32.c:2227:20: warning: variable ‘syncnum’ set but not used [-Wunused-but-set-variable] drivers/scsi/nsp32.c:2223:20: warning: variable ‘synct’ set but not used [-Wunused-but-set-variable] drivers/scsi/nsp32.c: In function ‘nsp32_do_bus_reset’: drivers/scsi/nsp32.c:2841:17: warning: variable ‘intrdat’ set but not used [-Wunused-but-set-variable] drivers/scsi/nsp32.c: In function ‘nsp32_getprom_param’: drivers/scsi/nsp32.c:2912:11: warning: variable ‘val’ set but not used [-Wunused-but-set-variable] Link: https://lore.kernel.org/r/20210317091125.2910058-4-lee.jones@linaro.org Cc: GOTO Masanori Cc: YOKOTA Hiroshi Cc: "James E.J. Bottomley" Cc: "Martin K. Petersen" Cc: gotom@debian.org Cc: linux-scsi@vger.kernel.org Signed-off-by: Lee Jones Signed-off-by: Martin K. Petersen --- drivers/scsi/nsp32.c | 23 ++++------------------- 1 file changed, 4 insertions(+), 19 deletions(-) diff --git a/drivers/scsi/nsp32.c b/drivers/scsi/nsp32.c index d5aa96f05bce..54abda4d07c6 100644 --- a/drivers/scsi/nsp32.c +++ b/drivers/scsi/nsp32.c @@ -581,7 +581,6 @@ static int nsp32_selection_autoscsi(struct scsi_cmnd *SCpnt) int status; unsigned short command = 0; unsigned int msgout = 0; - unsigned short execph; int i; nsp32_dbg(NSP32_DEBUG_AUTOSCSI, "in"); @@ -605,7 +604,7 @@ static int nsp32_selection_autoscsi(struct scsi_cmnd *SCpnt) /* * clear execph */ - execph = nsp32_read2(base, SCSI_EXECUTE_PHASE); + nsp32_read2(base, SCSI_EXECUTE_PHASE); /* * clear FIFO counter to set CDBs @@ -1781,8 +1780,6 @@ static void nsp32_msgout_occur(struct scsi_cmnd *SCpnt) { nsp32_hw_data *data = (nsp32_hw_data *)SCpnt->device->host->hostdata; unsigned int base = SCpnt->device->host->io_port; - //unsigned short command; - long new_sgtp; int i; nsp32_dbg(NSP32_DEBUG_MSGOUTOCCUR, @@ -1796,14 +1793,6 @@ static void nsp32_msgout_occur(struct scsi_cmnd *SCpnt) nsp32_build_nop(SCpnt); } - /* - * Set SGTP ADDR current entry for restarting AUTOSCSI, - * because SGTP is incremented next point. - * There is few statement in the specification... - */ - new_sgtp = data->cur_lunt->sglun_paddr + - (data->cur_lunt->cur_entry * sizeof(nsp32_sgtable)); - /* * send messages */ @@ -2220,17 +2209,12 @@ static void nsp32_analyze_sdtr(struct scsi_cmnd *SCpnt) { nsp32_hw_data *data = (nsp32_hw_data *)SCpnt->device->host->hostdata; nsp32_target *target = data->cur_target; - nsp32_sync_table *synct; unsigned char get_period = data->msginbuf[3]; unsigned char get_offset = data->msginbuf[4]; int entry; - int syncnum; nsp32_dbg(NSP32_DEBUG_MSGINOCCUR, "enter"); - synct = data->synct; - syncnum = data->syncnum; - /* * If this inititor sent the SDTR message, then target responds SDTR, * initiator SYNCREG, ACKWIDTH from SDTR parameter. @@ -2838,8 +2822,8 @@ static int nsp32_eh_abort(struct scsi_cmnd *SCpnt) static void nsp32_do_bus_reset(nsp32_hw_data *data) { unsigned int base = data->BaseAddress; - unsigned short intrdat; int i; + unsigned short __maybe_unused intrdat; nsp32_dbg(NSP32_DEBUG_BUSRESET, "in"); @@ -2909,7 +2893,8 @@ static int nsp32_getprom_param(nsp32_hw_data *data) { int vendor = data->pci_devid->vendor; int device = data->pci_devid->device; - int ret, val, i; + int ret, i; + int __maybe_unused val; /* * EEPROM checking. From f466690bda03aa2c04c19ff6e63effd1a5a5d7ec Mon Sep 17 00:00:00 2001 From: Lee Jones Date: Wed, 17 Mar 2021 09:11:21 +0000 Subject: [PATCH 184/412] scsi: FlashPoint: Remove unused variable 'TID' from FlashPoint_AbortCCB() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fixes the following W=1 kernel build warning(s): drivers/scsi/FlashPoint.c: In function ‘FlashPoint_AbortCCB’: drivers/scsi/FlashPoint.c:1618:16: warning: variable ‘TID’ set but not used [-Wunused-but-set-variable] Link: https://lore.kernel.org/r/20210317091125.2910058-5-lee.jones@linaro.org Cc: Khalid Aziz Cc: "James E.J. Bottomley" Cc: "Martin K. Petersen" Cc: linux-scsi@vger.kernel.org Acked-by: Khalid Aziz Signed-off-by: Lee Jones Signed-off-by: Martin K. Petersen --- drivers/scsi/FlashPoint.c | 4 ---- 1 file changed, 4 deletions(-) diff --git a/drivers/scsi/FlashPoint.c b/drivers/scsi/FlashPoint.c index f479c542e787..0464e37c806a 100644 --- a/drivers/scsi/FlashPoint.c +++ b/drivers/scsi/FlashPoint.c @@ -1615,7 +1615,6 @@ static int FlashPoint_AbortCCB(void *pCurrCard, struct sccb *p_Sccb) unsigned char thisCard; CALL_BK_FN callback; - unsigned char TID; struct sccb *pSaveSCCB; struct sccb_mgr_tar_info *currTar_Info; @@ -1652,9 +1651,6 @@ static int FlashPoint_AbortCCB(void *pCurrCard, struct sccb *p_Sccb) } else { - - TID = p_Sccb->TargID; - if (p_Sccb->Sccb_tag) { MDISABLE_INT(ioport); if (((struct sccb_card *)pCurrCard)-> From 886eb6d590d1852714e4eff17c3b19096db62b83 Mon Sep 17 00:00:00 2001 From: Lee Jones Date: Wed, 17 Mar 2021 09:11:22 +0000 Subject: [PATCH 185/412] scsi: sim710: Remove unused variable 'err' from sim710_init() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Take the opportunity to rework the comment a little. Fixes the following W=1 kernel build warning(s): drivers/scsi/sim710.c: In function ‘sim710_init’: drivers/scsi/sim710.c:216:6: warning: variable ‘err’ set but not used [-Wunused-but-set-variable] Link: https://lore.kernel.org/r/20210317091125.2910058-6-lee.jones@linaro.org Cc: "James E.J. Bottomley" Cc: "Martin K. Petersen" Cc: Richard Hirst Cc: c by Cc: linux-scsi@vger.kernel.org Signed-off-by: Lee Jones Signed-off-by: Martin K. Petersen --- drivers/scsi/sim710.c | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/drivers/scsi/sim710.c b/drivers/scsi/sim710.c index 22302612e032..e519df68d603 100644 --- a/drivers/scsi/sim710.c +++ b/drivers/scsi/sim710.c @@ -213,21 +213,19 @@ static struct eisa_driver sim710_eisa_driver = { static int __init sim710_init(void) { - int err = -ENODEV; - #ifdef MODULE if (sim710) param_setup(sim710); #endif #ifdef CONFIG_EISA - err = eisa_driver_register(&sim710_eisa_driver); + /* + * FIXME: We'd really like to return -ENODEV if no devices have actually + * been found. However eisa_driver_register() only reports problems + * with kobject_register() so simply return success for now. + */ + eisa_driver_register(&sim710_eisa_driver); #endif - /* FIXME: what we'd really like to return here is -ENODEV if - * no devices have actually been found. Instead, the err - * above actually only reports problems with kobject_register, - * so for the moment return success */ - return 0; } From ab3f2d15fc11ec0e6f05c607159afa5f0528174e Mon Sep 17 00:00:00 2001 From: Lee Jones Date: Wed, 17 Mar 2021 09:11:23 +0000 Subject: [PATCH 186/412] scsi: isci: Make local function isci_remote_device_wait_for_resume_from_abort() static MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fixes the following W=1 kernel build warning(s): drivers/scsi/isci/remote_device.c:1387:6: warning: no previous prototype for ‘isci_remote_device_wait_for_resume_from_abort’ [-Wmissing-prototypes] Link: https://lore.kernel.org/r/20210317091125.2910058-7-lee.jones@linaro.org Cc: Artur Paszkiewicz Cc: "James E.J. Bottomley" Cc: "Martin K. Petersen" Cc: linux-scsi@vger.kernel.org Signed-off-by: Lee Jones Signed-off-by: Martin K. Petersen --- drivers/scsi/isci/remote_device.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/scsi/isci/remote_device.c b/drivers/scsi/isci/remote_device.c index c3f540b55689..b1276f7e49c8 100644 --- a/drivers/scsi/isci/remote_device.c +++ b/drivers/scsi/isci/remote_device.c @@ -1384,7 +1384,7 @@ static bool isci_remote_device_test_resume_done( return done; } -void isci_remote_device_wait_for_resume_from_abort( +static void isci_remote_device_wait_for_resume_from_abort( struct isci_host *ihost, struct isci_remote_device *idev) { From 72444bbd047f4510ad1f01978103299690abf07e Mon Sep 17 00:00:00 2001 From: Lee Jones Date: Wed, 17 Mar 2021 09:11:24 +0000 Subject: [PATCH 187/412] scsi: isci: Make local function port_state_name() static MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fixes the following W=1 kernel build warning(s): drivers/scsi/isci/port.c:65:13: warning: no previous prototype for ‘port_state_name’ [-Wmissing-prototypes] Link: https://lore.kernel.org/r/20210317091125.2910058-8-lee.jones@linaro.org Cc: Artur Paszkiewicz Cc: "James E.J. Bottomley" Cc: "Martin K. Petersen" Cc: linux-scsi@vger.kernel.org Signed-off-by: Lee Jones Signed-off-by: Martin K. Petersen --- drivers/scsi/isci/port.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/scsi/isci/port.c b/drivers/scsi/isci/port.c index 448a8c31ba35..5a362ba76d63 100644 --- a/drivers/scsi/isci/port.c +++ b/drivers/scsi/isci/port.c @@ -62,7 +62,7 @@ #undef C #define C(a) (#a) -const char *port_state_name(enum sci_port_states state) +static const char *port_state_name(enum sci_port_states state) { static const char * const strings[] = PORT_STATES; From 45d59ab3edca82e2cb1b0964e544e4a3c10a972d Mon Sep 17 00:00:00 2001 From: Lee Jones Date: Wed, 17 Mar 2021 09:11:25 +0000 Subject: [PATCH 188/412] scsi: nsp32: Correct expected types in debug print formatting MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fixes the following W=1 kernel build warning(s): drivers/scsi/nsp32.c: In function ‘nsp32_setup_sg_table’: drivers/scsi/nsp32.c:879:6: warning: format ‘%lx’ expects argument of type ‘long unsigned int’, but argument 5 has type ‘unsigned int’ [-Wformat=] drivers/scsi/nsp32.c:280:69: note: in definition of macro ‘nsp32_msg’ drivers/scsi/nsp32.c:879:52: note: format string is defined here drivers/scsi/nsp32.c: In function ‘nsp32_detect’: drivers/scsi/nsp32.c:2719:6: warning: format ‘%lx’ expects argument of type ‘long unsigned int’, but argument 5 has type ‘int’ [-Wformat=] drivers/scsi/nsp32.c:280:69: note: in definition of macro ‘nsp32_msg’ drivers/scsi/nsp32.c:2719:22: note: format string is defined here drivers/scsi/nsp32.c:2719:6: warning: format ‘%lx’ expects argument of type ‘long unsigned int’, but argument 6 has type ‘int’ [-Wformat=] drivers/scsi/nsp32.c:280:69: note: in definition of macro ‘nsp32_msg’ drivers/scsi/nsp32.c:2719:28: note: format string is defined here drivers/scsi/nsp32.c: In function ‘nsp32_suspend’: drivers/scsi/nsp32.c:3267:23: warning: format ‘%ld’ expects argument of type ‘long int’, but argument 6 has type ‘pm_message_t’ {aka ‘struct pm_message’} [-Wformat=] drivers/scsi/nsp32.c:280:69: note: in definition of macro ‘nsp32_msg’ drivers/scsi/nsp32.c:3267:56: note: format string is defined here Link: https://lore.kernel.org/r/20210317091125.2910058-9-lee.jones@linaro.org Cc: GOTO Masanori Cc: YOKOTA Hiroshi Cc: "James E.J. Bottomley" Cc: "Martin K. Petersen" Cc: gotom@debian.org Cc: linux-scsi@vger.kernel.org Signed-off-by: Lee Jones Signed-off-by: Martin K. Petersen --- drivers/scsi/nsp32.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/drivers/scsi/nsp32.c b/drivers/scsi/nsp32.c index 54abda4d07c6..134bbd2d8b66 100644 --- a/drivers/scsi/nsp32.c +++ b/drivers/scsi/nsp32.c @@ -876,7 +876,7 @@ static int nsp32_setup_sg_table(struct scsi_cmnd *SCpnt) if (le32_to_cpu(sgt[i].len) > 0x10000) { nsp32_msg(KERN_ERR, - "can't transfer over 64KB at a time, size=0x%lx", le32_to_cpu(sgt[i].len)); + "can't transfer over 64KB at a time, size=0x%x", le32_to_cpu(sgt[i].len)); return FALSE; } nsp32_dbg(NSP32_DEBUG_SGLIST, @@ -2716,7 +2716,7 @@ static int nsp32_detect(struct pci_dev *pdev) res = request_region(host->io_port, host->n_io_port, "nsp32"); if (res == NULL) { nsp32_msg(KERN_ERR, - "I/O region 0x%lx+0x%lx is already used", + "I/O region 0x%x+0x%x is already used", data->BaseAddress, data->NumAddress); goto free_irq; } @@ -3264,7 +3264,8 @@ static int nsp32_suspend(struct pci_dev *pdev, pm_message_t state) { struct Scsi_Host *host = pci_get_drvdata(pdev); - nsp32_msg(KERN_INFO, "pci-suspend: pdev=0x%p, state=%ld, slot=%s, host=0x%p", pdev, state, pci_name(pdev), host); + nsp32_msg(KERN_INFO, "pci-suspend: pdev=0x%p, state.event=%x, slot=%s, host=0x%p", + pdev, state.event, pci_name(pdev), host); pci_save_state (pdev); pci_disable_device (pdev); From 12a1b740f2251b6218b3f593e812786be9cdf421 Mon Sep 17 00:00:00 2001 From: Lee Jones Date: Wed, 17 Mar 2021 09:11:55 +0000 Subject: [PATCH 189/412] scsi: myrb: Demote non-conformant kernel-doc headers and fix others Fixes the following W=1 kernel build warning(s): drivers/scsi/myrb.c:91: warning: Function parameter or member 'pdev' not described in 'myrb_create_mempools' drivers/scsi/myrb.c:91: warning: Function parameter or member 'cb' not described in 'myrb_create_mempools' drivers/scsi/myrb.c:141: warning: Function parameter or member 'cb' not described in 'myrb_destroy_mempools' drivers/scsi/myrb.c:153: warning: Function parameter or member 'cmd_blk' not described in 'myrb_reset_cmd' drivers/scsi/myrb.c:164: warning: Function parameter or member 'cb' not described in 'myrb_qcmd' drivers/scsi/myrb.c:164: warning: Function parameter or member 'cmd_blk' not described in 'myrb_qcmd' drivers/scsi/myrb.c:187: warning: Function parameter or member 'cb' not described in 'myrb_exec_cmd' drivers/scsi/myrb.c:187: warning: Function parameter or member 'cmd_blk' not described in 'myrb_exec_cmd' drivers/scsi/myrb.c:208: warning: Function parameter or member 'cb' not described in 'myrb_exec_type3' drivers/scsi/myrb.c:208: warning: Function parameter or member 'op' not described in 'myrb_exec_type3' drivers/scsi/myrb.c:208: warning: Function parameter or member 'addr' not described in 'myrb_exec_type3' drivers/scsi/myrb.c:231: warning: Function parameter or member 'cb' not described in 'myrb_exec_type3D' drivers/scsi/myrb.c:231: warning: Function parameter or member 'op' not described in 'myrb_exec_type3D' drivers/scsi/myrb.c:231: warning: Function parameter or member 'sdev' not described in 'myrb_exec_type3D' drivers/scsi/myrb.c:231: warning: Function parameter or member 'pdev_info' not described in 'myrb_exec_type3D' drivers/scsi/myrb.c:341: warning: Function parameter or member 'cb' not described in 'myrb_get_errtable' drivers/scsi/myrb.c:388: warning: Function parameter or member 'cb' not described in 'myrb_get_ldev_info' drivers/scsi/myrb.c:440: warning: Function parameter or member 'cb' not described in 'myrb_get_rbld_progress' drivers/scsi/myrb.c:440: warning: Function parameter or member 'rbld' not described in 'myrb_get_rbld_progress' drivers/scsi/myrb.c:472: warning: Function parameter or member 'cb' not described in 'myrb_update_rbld_progress' drivers/scsi/myrb.c:533: warning: Function parameter or member 'cb' not described in 'myrb_get_cc_progress' drivers/scsi/myrb.c:580: warning: Function parameter or member 'cb' not described in 'myrb_bgi_control' drivers/scsi/myrb.c:671: warning: Function parameter or member 'cb' not described in 'myrb_hba_enquiry' drivers/scsi/myrb.c:782: warning: Function parameter or member 'cb' not described in 'myrb_set_pdev_state' drivers/scsi/myrb.c:782: warning: Function parameter or member 'sdev' not described in 'myrb_set_pdev_state' drivers/scsi/myrb.c:782: warning: Function parameter or member 'state' not described in 'myrb_set_pdev_state' drivers/scsi/myrb.c:808: warning: Function parameter or member 'cb' not described in 'myrb_enable_mmio' drivers/scsi/myrb.c:808: warning: Function parameter or member 'mmio_init_fn' not described in 'myrb_enable_mmio' drivers/scsi/myrb.c:913: warning: Function parameter or member 'cb' not described in 'myrb_get_hba_config' drivers/scsi/myrb.c:1200: warning: Function parameter or member 'cb' not described in 'myrb_unmap' drivers/scsi/myrb.c:1236: warning: Function parameter or member 'cb' not described in 'myrb_cleanup' drivers/scsi/myrb.c:2249: warning: Function parameter or member 'dev' not described in 'myrb_is_raid' drivers/scsi/myrb.c:2260: warning: Function parameter or member 'dev' not described in 'myrb_get_resync' drivers/scsi/myrb.c:2287: warning: Function parameter or member 'dev' not described in 'myrb_get_state' drivers/scsi/myrb.c:2493: warning: Function parameter or member 'cb' not described in 'myrb_err_status' drivers/scsi/myrb.c:2493: warning: Function parameter or member 'error' not described in 'myrb_err_status' drivers/scsi/myrb.c:2493: warning: Function parameter or member 'parm0' not described in 'myrb_err_status' drivers/scsi/myrb.c:2493: warning: Function parameter or member 'parm1' not described in 'myrb_err_status' Link: https://lore.kernel.org/r/20210317091230.2912389-2-lee.jones@linaro.org Cc: Hannes Reinecke Cc: "James E.J. Bottomley" Cc: "Martin K. Petersen" Cc: Linux GmbH Cc: "Leonard N. Zubkoff" Cc: linux-scsi@vger.kernel.org Signed-off-by: Lee Jones Signed-off-by: Martin K. Petersen --- drivers/scsi/myrb.c | 47 ++++++++++++++++++++++----------------------- 1 file changed, 23 insertions(+), 24 deletions(-) diff --git a/drivers/scsi/myrb.c b/drivers/scsi/myrb.c index 3d8e91c07dc7..d469a4889777 100644 --- a/drivers/scsi/myrb.c +++ b/drivers/scsi/myrb.c @@ -82,7 +82,7 @@ static const char *myrb_raidlevel_name(enum myrb_raidlevel level) return NULL; } -/** +/* * myrb_create_mempools - allocates auxiliary data structures * * Return: true on success, false otherwise. @@ -134,7 +134,7 @@ static bool myrb_create_mempools(struct pci_dev *pdev, struct myrb_hba *cb) return true; } -/** +/* * myrb_destroy_mempools - tears down the memory pools for the controller */ static void myrb_destroy_mempools(struct myrb_hba *cb) @@ -146,7 +146,7 @@ static void myrb_destroy_mempools(struct myrb_hba *cb) dma_pool_destroy(cb->dcdb_pool); } -/** +/* * myrb_reset_cmd - reset command block */ static inline void myrb_reset_cmd(struct myrb_cmdblk *cmd_blk) @@ -157,7 +157,7 @@ static inline void myrb_reset_cmd(struct myrb_cmdblk *cmd_blk) cmd_blk->status = 0; } -/** +/* * myrb_qcmd - queues command block for execution */ static void myrb_qcmd(struct myrb_hba *cb, struct myrb_cmdblk *cmd_blk) @@ -177,7 +177,7 @@ static void myrb_qcmd(struct myrb_hba *cb, struct myrb_cmdblk *cmd_blk) cb->next_cmd_mbox = next_mbox; } -/** +/* * myrb_exec_cmd - executes command block and waits for completion. * * Return: command status @@ -198,7 +198,7 @@ static unsigned short myrb_exec_cmd(struct myrb_hba *cb, return cmd_blk->status; } -/** +/* * myrb_exec_type3 - executes a type 3 command and waits for completion. * * Return: command status @@ -220,7 +220,7 @@ static unsigned short myrb_exec_type3(struct myrb_hba *cb, return status; } -/** +/* * myrb_exec_type3D - executes a type 3D command and waits for completion. * * Return: command status @@ -332,7 +332,7 @@ static void myrb_get_event(struct myrb_hba *cb, unsigned int event) ev_buf, ev_addr); } -/** +/* * myrb_get_errtable - retrieves the error table from the controller * * Executes a type 3 command and logs the error table from the controller. @@ -377,7 +377,7 @@ static void myrb_get_errtable(struct myrb_hba *cb) } } -/** +/* * myrb_get_ldev_info - retrieves the logical device table from the controller * * Executes a type 3 command and updates the logical device table. @@ -427,7 +427,7 @@ static unsigned short myrb_get_ldev_info(struct myrb_hba *cb) return status; } -/** +/* * myrb_get_rbld_progress - get rebuild progress information * * Executes a type 3 command and returns the rebuild progress @@ -462,11 +462,10 @@ static unsigned short myrb_get_rbld_progress(struct myrb_hba *cb, return status; } -/** +/* * myrb_update_rbld_progress - updates the rebuild status * * Updates the rebuild status for the attached logical devices. - * */ static void myrb_update_rbld_progress(struct myrb_hba *cb) { @@ -523,7 +522,7 @@ static void myrb_update_rbld_progress(struct myrb_hba *cb) cb->last_rbld_status = status; } -/** +/* * myrb_get_cc_progress - retrieve the rebuild status * * Execute a type 3 Command and fetch the rebuild / consistency check @@ -571,7 +570,7 @@ static void myrb_get_cc_progress(struct myrb_hba *cb) rbld_buf, rbld_addr); } -/** +/* * myrb_bgi_control - updates background initialisation status * * Executes a type 3B command and updates the background initialisation status @@ -660,7 +659,7 @@ static void myrb_bgi_control(struct myrb_hba *cb) bgi, bgi_addr); } -/** +/* * myrb_hba_enquiry - updates the controller status * * Executes a DAC_V1_Enquiry command and updates the controller status. @@ -772,7 +771,7 @@ static unsigned short myrb_hba_enquiry(struct myrb_hba *cb) return MYRB_STATUS_SUCCESS; } -/** +/* * myrb_set_pdev_state - sets the device state for a physical device * * Return: command status @@ -796,7 +795,7 @@ static unsigned short myrb_set_pdev_state(struct myrb_hba *cb, return status; } -/** +/* * myrb_enable_mmio - enables the Memory Mailbox Interface * * PD and P controller types have no memory mailbox, but still need the @@ -901,7 +900,7 @@ static bool myrb_enable_mmio(struct myrb_hba *cb, mbox_mmio_init_t mmio_init_fn) return true; } -/** +/* * myrb_get_hba_config - reads the configuration information * * Reads the configuration information from the controller and @@ -1193,7 +1192,7 @@ out_free: return ret; } -/** +/* * myrb_unmap - unmaps controller structures */ static void myrb_unmap(struct myrb_hba *cb) @@ -1229,7 +1228,7 @@ static void myrb_unmap(struct myrb_hba *cb) } } -/** +/* * myrb_cleanup - cleanup controller structures */ static void myrb_cleanup(struct myrb_hba *cb) @@ -2243,7 +2242,7 @@ static struct scsi_host_template myrb_template = { /** * myrb_is_raid - return boolean indicating device is raid volume - * @dev the device struct object + * @dev: the device struct object */ static int myrb_is_raid(struct device *dev) { @@ -2254,7 +2253,7 @@ static int myrb_is_raid(struct device *dev) /** * myrb_get_resync - get raid volume resync percent complete - * @dev the device struct object + * @dev: the device struct object */ static void myrb_get_resync(struct device *dev) { @@ -2281,7 +2280,7 @@ static void myrb_get_resync(struct device *dev) /** * myrb_get_state - get raid volume status - * @dev the device struct object + * @dev: the device struct object */ static void myrb_get_state(struct device *dev) { @@ -2480,7 +2479,7 @@ static void myrb_monitor(struct work_struct *work) queue_delayed_work(cb->work_q, &cb->monitor_work, interval); } -/** +/* * myrb_err_status - reports controller BIOS messages * * Controller BIOS messages are passed through the Error Status Register From 637b5c3ebc1c2ca4f802fa2def950fed1f5877e6 Mon Sep 17 00:00:00 2001 From: Lee Jones Date: Wed, 17 Mar 2021 09:11:56 +0000 Subject: [PATCH 190/412] scsi: ipr: Fix incorrect function names in their headers Fixes the following W=1 kernel build warning(s): drivers/scsi/ipr.c:5335: warning: expecting prototype for ipr_eh_dev_reset(). Prototype was for __ipr_eh_dev_reset() instead drivers/scsi/ipr.c:5594: warning: expecting prototype for ipr_eh_abort(). Prototype was for ipr_scan_finished() instead drivers/scsi/ipr.c:5616: warning: expecting prototype for ipr_eh_host_reset(). Prototype was for ipr_eh_abort() instead drivers/scsi/ipr.c:6725: warning: expecting prototype for ipr_info(). Prototype was for ipr_ioa_info() instead [mkp: tweaked ipr_scan_finished() comment] Link: https://lore.kernel.org/r/20210317091230.2912389-3-lee.jones@linaro.org Cc: Brian King Cc: "James E.J. Bottomley" Cc: "Martin K. Petersen" Cc: linux-scsi@vger.kernel.org Signed-off-by: Lee Jones Signed-off-by: Martin K. Petersen --- drivers/scsi/ipr.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/scsi/ipr.c b/drivers/scsi/ipr.c index e451102b9a29..30c30a1db5b1 100644 --- a/drivers/scsi/ipr.c +++ b/drivers/scsi/ipr.c @@ -5321,7 +5321,7 @@ static int ipr_sata_reset(struct ata_link *link, unsigned int *classes, } /** - * ipr_eh_dev_reset - Reset the device + * __ipr_eh_dev_reset - Reset the device * @scsi_cmd: scsi command struct * * This function issues a device reset to the affected device. @@ -5583,7 +5583,7 @@ static int ipr_cancel_op(struct scsi_cmnd *scsi_cmd) } /** - * ipr_eh_abort - Abort a single op + * ipr_scan_finished - Report whether scan is done * @shost: scsi host struct * @elapsed_time: elapsed time * @@ -5606,7 +5606,7 @@ static int ipr_scan_finished(struct Scsi_Host *shost, unsigned long elapsed_time } /** - * ipr_eh_host_reset - Reset the host adapter + * ipr_eh_abort - Reset the host adapter * @scsi_cmd: scsi command struct * * Return value: @@ -6715,7 +6715,7 @@ static int ipr_ioctl(struct scsi_device *sdev, unsigned int cmd, } /** - * ipr_info - Get information about the card/driver + * ipr_ioa_info - Get information about the card/driver * @host: scsi host struct * * Return value: From 5ccd626516e186ea2669b654c91af5be8b3773dd Mon Sep 17 00:00:00 2001 From: Lee Jones Date: Wed, 17 Mar 2021 09:11:57 +0000 Subject: [PATCH 191/412] scsi: mvumi: Fix formatting and doc-rot issues Fixes the following W=1 kernel build warning(s): drivers/scsi/mvumi.c:191: warning: Function parameter or member 'sg_count' not described in 'mvumi_make_sgl' drivers/scsi/mvumi.c:1301: warning: Function parameter or member 'ob_frame' not described in 'mvumi_complete_cmd' drivers/scsi/mvumi.c:2084: warning: Function parameter or member 'shost' not described in 'mvumi_queue_command' drivers/scsi/mvumi.c:2084: warning: Excess function parameter 'done' description in 'mvumi_queue_command' Link: https://lore.kernel.org/r/20210317091230.2912389-4-lee.jones@linaro.org Cc: "James E.J. Bottomley" Cc: "Martin K. Petersen" Cc: Marvell Cc: linux-scsi@vger.kernel.org Signed-off-by: Lee Jones Signed-off-by: Martin K. Petersen --- drivers/scsi/mvumi.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/drivers/scsi/mvumi.c b/drivers/scsi/mvumi.c index 7cc1143ab9b0..9d5743627604 100644 --- a/drivers/scsi/mvumi.c +++ b/drivers/scsi/mvumi.c @@ -182,7 +182,7 @@ static void mvumi_release_mem_resource(struct mvumi_hba *mhba) * @mhba: Adapter soft state * @scmd: SCSI command from the mid-layer * @sgl_p: SGL to be filled in - * @sg_count return the number of SG elements + * @sg_count: return the number of SG elements * * If successful, this function returns 0. otherwise, it returns -1. */ @@ -1295,6 +1295,7 @@ static unsigned char mvumi_start(struct mvumi_hba *mhba) * mvumi_complete_cmd - Completes a command * @mhba: Adapter soft state * @cmd: Command to be completed + * @ob_frame: Command response */ static void mvumi_complete_cmd(struct mvumi_hba *mhba, struct mvumi_cmd *cmd, struct mvumi_rsp_frame *ob_frame) @@ -2076,8 +2077,8 @@ error: /** * mvumi_queue_command - Queue entry point + * @shost: Scsi host to queue command on * @scmd: SCSI command to be queued - * @done: Callback entry point */ static int mvumi_queue_command(struct Scsi_Host *shost, struct scsi_cmnd *scmd) From 59863cb53d80adc421092203eeef98708ddca0cb Mon Sep 17 00:00:00 2001 From: Lee Jones Date: Wed, 17 Mar 2021 09:11:58 +0000 Subject: [PATCH 192/412] scsi: sd_zbc: Place function name into header Fixes the following W=1 kernel build warning(s): drivers/scsi/sd_zbc.c:137: warning: wrong kernel-doc identifier on line: Link: https://lore.kernel.org/r/20210317091230.2912389-5-lee.jones@linaro.org Cc: "James E.J. Bottomley" Cc: "Martin K. Petersen" Cc: Hannes Reinecke Cc: Le Moal Cc: Shaun Tancheff Cc: linux-scsi@vger.kernel.org Signed-off-by: Lee Jones Signed-off-by: Martin K. Petersen --- drivers/scsi/sd_zbc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/scsi/sd_zbc.c b/drivers/scsi/sd_zbc.c index ee558675eab4..232f624c3704 100644 --- a/drivers/scsi/sd_zbc.c +++ b/drivers/scsi/sd_zbc.c @@ -134,7 +134,7 @@ static int sd_zbc_do_report_zones(struct scsi_disk *sdkp, unsigned char *buf, } /** - * Allocate a buffer for report zones reply. + * sd_zbc_alloc_report_buffer() - Allocate a buffer for report zones reply. * @sdkp: The target disk * @nr_zones: Maximum number of zones to report * @buflen: Size of the buffer allocated From 3673b7b0007b81ee9f136a19d3b3d65eda461794 Mon Sep 17 00:00:00 2001 From: Lee Jones Date: Wed, 17 Mar 2021 09:11:59 +0000 Subject: [PATCH 193/412] scsi: pmcraid: Fix a whole host of kernel-doc issues Fixes the following W=1 kernel build warning(s): drivers/scsi/pmcraid.c:455: warning: Function parameter or member 'intrs' not described in 'pmcraid_enable_interrupts' drivers/scsi/pmcraid.c:455: warning: Excess function parameter 'intr' description in 'pmcraid_enable_interrupts' drivers/scsi/pmcraid.c:543: warning: Function parameter or member '' not described in 'pmcraid_ioa_reset' drivers/scsi/pmcraid.c:543: warning: expecting prototype for pmcraid_bist_done(). Prototype was for pmcraid_ioa_reset() instead drivers/scsi/pmcraid.c:603: warning: Function parameter or member 't' not described in 'pmcraid_reset_alert_done' drivers/scsi/pmcraid.c:603: warning: Excess function parameter 'cmd' description in 'pmcraid_reset_alert_done' drivers/scsi/pmcraid.c:638: warning: Function parameter or member '' not described in 'pmcraid_notify_ioastate' drivers/scsi/pmcraid.c:638: warning: Function parameter or member 'u32' not described in 'pmcraid_notify_ioastate' drivers/scsi/pmcraid.c:638: warning: expecting prototype for pmcraid_reset_alert(). Prototype was for pmcraid_notify_ioastate() instead drivers/scsi/pmcraid.c:687: warning: Function parameter or member 't' not described in 'pmcraid_timeout_handler' drivers/scsi/pmcraid.c:687: warning: Excess function parameter 'cmd' description in 'pmcraid_timeout_handler' drivers/scsi/pmcraid.c:858: warning: expecting prototype for pmcraid_fire_command(). Prototype was for _pmcraid_fire_command() instead drivers/scsi/pmcraid.c:972: warning: Function parameter or member '' not described in 'pmcraid_querycfg' drivers/scsi/pmcraid.c:972: warning: expecting prototype for pmcraid_get_fwversion_done(). Prototype was for pmcraid_querycfg() instead drivers/scsi/pmcraid.c:1398: warning: Function parameter or member 'aen_msg' not described in 'pmcraid_notify_aen' drivers/scsi/pmcraid.c:1398: warning: Function parameter or member 'data_size' not described in 'pmcraid_notify_aen' drivers/scsi/pmcraid.c:1398: warning: Excess function parameter 'type' description in 'pmcraid_notify_aen' drivers/scsi/pmcraid.c:1781: warning: Function parameter or member '' not described in 'pmcraid_initiate_reset' drivers/scsi/pmcraid.c:1781: warning: expecting prototype for pmcraid_process_ldn(). Prototype was for pmcraid_initiate_reset() instead drivers/scsi/pmcraid.c:1887: warning: Function parameter or member '' not described in 'pmcraid_reinit_buffers' drivers/scsi/pmcraid.c:1887: warning: expecting prototype for pmcraid_reset_enable_ioa(). Prototype was for pmcraid_reinit_buffers() instead drivers/scsi/pmcraid.c:2704: warning: Function parameter or member 'timeout' not described in 'pmcraid_reset_device' drivers/scsi/pmcraid.c:3025: warning: expecting prototype for pmcraid_eh_xxxx_reset_handler(). Prototype was for pmcraid_eh_device_reset_handler() instead drivers/scsi/pmcraid.c:3327: warning: expecting prototype for pmcraid_queuecommand(). Prototype was for pmcraid_queuecommand_lck() instead drivers/scsi/pmcraid.c:3437: warning: Function parameter or member 'inode' not described in 'pmcraid_chr_open' drivers/scsi/pmcraid.c:3437: warning: Function parameter or member 'filep' not described in 'pmcraid_chr_open' drivers/scsi/pmcraid.c:3437: warning: expecting prototype for pmcraid_open(). Prototype was for pmcraid_chr_open() instead drivers/scsi/pmcraid.c:3457: warning: Function parameter or member 'fd' not described in 'pmcraid_chr_fasync' drivers/scsi/pmcraid.c:3457: warning: Function parameter or member 'filep' not described in 'pmcraid_chr_fasync' drivers/scsi/pmcraid.c:3457: warning: Function parameter or member 'mode' not described in 'pmcraid_chr_fasync' drivers/scsi/pmcraid.c:3457: warning: expecting prototype for pmcraid_fasync(). Prototype was for pmcraid_chr_fasync() instead drivers/scsi/pmcraid.c:3574: warning: Function parameter or member 'ioctl_cmd' not described in 'pmcraid_ioctl_passthrough' drivers/scsi/pmcraid.c:3574: warning: Function parameter or member 'buflen' not described in 'pmcraid_ioctl_passthrough' drivers/scsi/pmcraid.c:3574: warning: Excess function parameter 'cmd' description in 'pmcraid_ioctl_passthrough' drivers/scsi/pmcraid.c:3905: warning: Function parameter or member 'filep' not described in 'pmcraid_chr_ioctl' drivers/scsi/pmcraid.c:3905: warning: Function parameter or member 'cmd' not described in 'pmcraid_chr_ioctl' drivers/scsi/pmcraid.c:3905: warning: Function parameter or member 'arg' not described in 'pmcraid_chr_ioctl' drivers/scsi/pmcraid.c:3905: warning: expecting prototype for pmcraid_ioctl(). Prototype was for pmcraid_chr_ioctl() instead drivers/scsi/pmcraid.c:3969: warning: cannot understand function prototype: 'const struct file_operations pmcraid_fops = ' drivers/scsi/pmcraid.c:3993: warning: Function parameter or member 'attr' not described in 'pmcraid_show_log_level' drivers/scsi/pmcraid.c:4015: warning: Function parameter or member 'attr' not described in 'pmcraid_store_log_level' drivers/scsi/pmcraid.c:4055: warning: Function parameter or member 'attr' not described in 'pmcraid_show_drv_version' drivers/scsi/pmcraid.c:4081: warning: Function parameter or member 'attr' not described in 'pmcraid_show_adapter_id' drivers/scsi/pmcraid.c:4081: warning: expecting prototype for pmcraid_show_io_adapter_id(). Prototype was for pmcraid_show_adapter_id() instead drivers/scsi/pmcraid.c:4600: warning: Function parameter or member 'pinstance' not described in 'pmcraid_allocate_cmd_blocks' drivers/scsi/pmcraid.c:5153: warning: Function parameter or member 'minor' not described in 'pmcraid_release_minor' Link: https://lore.kernel.org/r/20210317091230.2912389-6-lee.jones@linaro.org Cc: "James E.J. Bottomley" Cc: "Martin K. Petersen" Cc: Anil Ravindranath Cc: linux-scsi@vger.kernel.org Signed-off-by: Lee Jones Signed-off-by: Martin K. Petersen --- drivers/scsi/pmcraid.c | 68 ++++++++++++++++++++---------------------- 1 file changed, 33 insertions(+), 35 deletions(-) diff --git a/drivers/scsi/pmcraid.c b/drivers/scsi/pmcraid.c index 834556ea21d2..c98e39eb04b2 100644 --- a/drivers/scsi/pmcraid.c +++ b/drivers/scsi/pmcraid.c @@ -443,15 +443,14 @@ static void pmcraid_disable_interrupts( * pmcraid_enable_interrupts - Enables specified interrupts * * @pinstance: pointer to per adapter instance structure - * @intr: interrupts to enable + * @intrs: interrupts to enable * * Return Value * None */ static void pmcraid_enable_interrupts( struct pmcraid_instance *pinstance, - u32 intrs -) + u32 intrs) { u32 gmask = ioread32(pinstance->int_regs.global_interrupt_mask_reg); u32 nmask = gmask & (~GLOBAL_INTERRUPT_MASK); @@ -533,15 +532,13 @@ static void pmcraid_reset_type(struct pmcraid_instance *pinstance) pinstance->ioa_unit_check = 1; } +static void pmcraid_ioa_reset(struct pmcraid_cmd *); /** * pmcraid_bist_done - completion function for PCI BIST - * @cmd: pointer to reset command + * @t: pointer to reset command * Return Value * none */ - -static void pmcraid_ioa_reset(struct pmcraid_cmd *); - static void pmcraid_bist_done(struct timer_list *t) { struct pmcraid_cmd *cmd = from_timer(cmd, t, timer); @@ -595,7 +592,7 @@ static void pmcraid_start_bist(struct pmcraid_cmd *cmd) /** * pmcraid_reset_alert_done - completion routine for reset_alert - * @cmd: pointer to command block used in reset sequence + * @t: pointer to command block used in reset sequence * Return value * None */ @@ -626,16 +623,16 @@ static void pmcraid_reset_alert_done(struct timer_list *t) } } +static void pmcraid_notify_ioastate(struct pmcraid_instance *, u32); /** * pmcraid_reset_alert - alerts IOA for a possible reset - * @cmd : command block to be used for reset sequence. + * @cmd: command block to be used for reset sequence. * * Return Value * returns 0 if pci config-space is accessible and RESET_DOORBELL is * successfully written to IOA. Returns non-zero in case pci_config_space * is not accessible */ -static void pmcraid_notify_ioastate(struct pmcraid_instance *, u32); static void pmcraid_reset_alert(struct pmcraid_cmd *cmd) { struct pmcraid_instance *pinstance = cmd->drv_inst; @@ -676,7 +673,7 @@ static void pmcraid_reset_alert(struct pmcraid_cmd *cmd) /** * pmcraid_timeout_handler - Timeout handler for internally generated ops * - * @cmd : pointer to command structure, that got timedout + * @t: pointer to command structure, that got timedout * * This function blocks host requests and initiates an adapter reset. * @@ -844,7 +841,7 @@ static void pmcraid_erp_done(struct pmcraid_cmd *cmd) } /** - * pmcraid_fire_command - sends an IOA command to adapter + * _pmcraid_fire_command - sends an IOA command to adapter * * This function adds the given block into pending command list * and returns without waiting @@ -961,6 +958,7 @@ static void pmcraid_ioa_shutdown(struct pmcraid_cmd *cmd) pmcraid_timeout_handler); } +static void pmcraid_querycfg(struct pmcraid_cmd *); /** * pmcraid_get_fwversion_done - completion function for get_fwversion * @@ -969,8 +967,6 @@ static void pmcraid_ioa_shutdown(struct pmcraid_cmd *cmd) * Return Value * none */ -static void pmcraid_querycfg(struct pmcraid_cmd *); - static void pmcraid_get_fwversion_done(struct pmcraid_cmd *cmd) { struct pmcraid_instance *pinstance = cmd->drv_inst; @@ -1382,10 +1378,9 @@ static void pmcraid_netlink_release(void) genl_unregister_family(&pmcraid_event_family); } -/** +/* * pmcraid_notify_aen - sends event msg to user space application * @pinstance: pointer to adapter instance structure - * @type: HCAM type * * Return value: * 0 if success, error value in case of any failure. @@ -1393,8 +1388,7 @@ static void pmcraid_netlink_release(void) static int pmcraid_notify_aen( struct pmcraid_instance *pinstance, struct pmcraid_aen_msg *aen_msg, - u32 data_size -) + u32 data_size) { struct sk_buff *skb; void *msg_header; @@ -1771,6 +1765,8 @@ static void pmcraid_process_ccn(struct pmcraid_cmd *cmd) } } +static void pmcraid_initiate_reset(struct pmcraid_instance *); +static void pmcraid_set_timestamp(struct pmcraid_cmd *cmd); /** * pmcraid_process_ldn - op done function for an LDN * @cmd: pointer to command block @@ -1778,9 +1774,6 @@ static void pmcraid_process_ccn(struct pmcraid_cmd *cmd) * Return value * none */ -static void pmcraid_initiate_reset(struct pmcraid_instance *); -static void pmcraid_set_timestamp(struct pmcraid_cmd *cmd); - static void pmcraid_process_ldn(struct pmcraid_cmd *cmd) { struct pmcraid_instance *pinstance = cmd->drv_inst; @@ -1878,14 +1871,14 @@ static void pmcraid_unregister_hcams(struct pmcraid_cmd *cmd) pmcraid_cancel_ldn(cmd); } +static void pmcraid_reinit_buffers(struct pmcraid_instance *); + /** * pmcraid_reset_enable_ioa - re-enable IOA after a hard reset * @pinstance: pointer to adapter instance structure * Return Value * 1 if TRANSITION_TO_OPERATIONAL is active, otherwise 0 */ -static void pmcraid_reinit_buffers(struct pmcraid_instance *); - static int pmcraid_reset_enable_ioa(struct pmcraid_instance *pinstance) { u32 intrs; @@ -2687,6 +2680,7 @@ static int pmcraid_error_handler(struct pmcraid_cmd *cmd) * pmcraid_reset_device - device reset handler functions * * @scsi_cmd: scsi command struct + * @timeout: command timeout * @modifier: reset modifier indicating the reset sequence to be performed * * This function issues a device reset to the affected device. @@ -2699,8 +2693,7 @@ static int pmcraid_error_handler(struct pmcraid_cmd *cmd) static int pmcraid_reset_device( struct scsi_cmnd *scsi_cmd, unsigned long timeout, - u8 modifier -) + u8 modifier) { struct pmcraid_cmd *cmd; struct pmcraid_instance *pinstance; @@ -3008,7 +3001,7 @@ static int pmcraid_eh_abort_handler(struct scsi_cmnd *scsi_cmd) } /** - * pmcraid_eh_xxxx_reset_handler - bus/target/device reset handler callbacks + * pmcraid_eh_device_reset_handler - bus/target/device reset handler callbacks * * @scmd: pointer to scsi_cmd that was sent to the resource to be reset. * @@ -3307,7 +3300,7 @@ static int pmcraid_copy_sglist( } /** - * pmcraid_queuecommand - Queue a mid-layer request + * pmcraid_queuecommand_lck - Queue a mid-layer request * @scsi_cmd: scsi command struct * @done: done function * @@ -3430,7 +3423,7 @@ static int pmcraid_queuecommand_lck( static DEF_SCSI_QCMD(pmcraid_queuecommand) -/** +/* * pmcraid_open -char node "open" entry, allowed only users with admin access */ static int pmcraid_chr_open(struct inode *inode, struct file *filep) @@ -3447,7 +3440,7 @@ static int pmcraid_chr_open(struct inode *inode, struct file *filep) return 0; } -/** +/* * pmcraid_fasync - Async notifier registration from applications * * This function adds the calling process to a driver global queue. When an @@ -3559,7 +3552,8 @@ static void pmcraid_release_passthrough_ioadls( * pmcraid_ioctl_passthrough - handling passthrough IOCTL commands * * @pinstance: pointer to adapter instance structure - * @cmd: ioctl code + * @ioctl_cmd: ioctl code + * @buflen: unused * @arg: pointer to pmcraid_passthrough_buffer user buffer * * Return value @@ -3894,7 +3888,7 @@ static int pmcraid_check_ioctl_buffer( return 0; } -/** +/* * pmcraid_ioctl - char node ioctl entry point */ static long pmcraid_chr_ioctl( @@ -3963,7 +3957,7 @@ static long pmcraid_chr_ioctl( return retval; } -/** +/* * File operations structure for management interface */ static const struct file_operations pmcraid_fops = { @@ -3981,6 +3975,7 @@ static const struct file_operations pmcraid_fops = { /** * pmcraid_show_log_level - Display adapter's error logging level * @dev: class device struct + * @attr: unused * @buf: buffer * * Return value: @@ -4000,6 +3995,7 @@ static ssize_t pmcraid_show_log_level( /** * pmcraid_store_log_level - Change the adapter's error logging level * @dev: class device struct + * @attr: unused * @buf: buffer * @count: not used * @@ -4042,6 +4038,7 @@ static struct device_attribute pmcraid_log_level_attr = { /** * pmcraid_show_drv_version - Display driver version * @dev: class device struct + * @attr: unused * @buf: buffer * * Return value: @@ -4068,6 +4065,7 @@ static struct device_attribute pmcraid_driver_version_attr = { /** * pmcraid_show_io_adapter_id - Display driver assigned adapter id * @dev: class device struct + * @attr: unused * @buf: buffer * * Return value: @@ -4589,7 +4587,7 @@ pmcraid_release_control_blocks( /** * pmcraid_allocate_cmd_blocks - allocate memory for cmd block structures - * @pinstance - pointer to per adapter instance structure + * @pinstance: pointer to per adapter instance structure * * Allocates memory for command blocks using kernel slab allocator. * @@ -5134,7 +5132,7 @@ static void pmcraid_shutdown(struct pci_dev *pdev) } -/** +/* * pmcraid_get_minor - returns unused minor number from minor number bitmap */ static unsigned short pmcraid_get_minor(void) @@ -5146,7 +5144,7 @@ static unsigned short pmcraid_get_minor(void) return minor; } -/** +/* * pmcraid_release_minor - releases given minor back to minor number bitmap */ static void pmcraid_release_minor(unsigned short minor) From ad907c54e36fdc4e9eb8ac54b4d5a774111bc8e3 Mon Sep 17 00:00:00 2001 From: Lee Jones Date: Wed, 17 Mar 2021 09:12:00 +0000 Subject: [PATCH 194/412] scsi: sd: Fix function name in header Fixes the following W=1 kernel build warning(s): drivers/scsi/sd.c:1537: warning: expecting prototype for sd_ioctl(). Prototype was for sd_ioctl_common() instead Link: https://lore.kernel.org/r/20210317091230.2912389-7-lee.jones@linaro.org Cc: "James E.J. Bottomley" Cc: "Martin K. Petersen" Cc: Drew Eckhardt Cc: Eric Youngdale Cc: Jirka Hanika Cc: Richard Gooch Cc: Torben Mathiasen Cc: Alex Davis Cc: Douglas Gilbert Cc: Badari Pulavarty Cc: willy@debian.org Cc: Kurt Garloff Cc: linux-scsi@vger.kernel.org Signed-off-by: Lee Jones Signed-off-by: Martin K. Petersen --- drivers/scsi/sd.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c index ed0b1bb99f08..91c34ee972c7 100644 --- a/drivers/scsi/sd.c +++ b/drivers/scsi/sd.c @@ -1519,7 +1519,7 @@ static int sd_getgeo(struct block_device *bdev, struct hd_geometry *geo) } /** - * sd_ioctl - process an ioctl + * sd_ioctl_common - process an ioctl * @bdev: target block device * @mode: FMODE_* mask * @cmd: ioctl command number From 3e2f4679ea03bab1bc351e7500ce892e485a6879 Mon Sep 17 00:00:00 2001 From: Lee Jones Date: Wed, 17 Mar 2021 09:12:01 +0000 Subject: [PATCH 195/412] scsi: aic94xx: Correct misspelling of function asd_dump_seq_state() Fixes the following W=1 kernel build warning(s): drivers/scsi/aic94xx/aic94xx_dump.c:729: warning: expecting prototype for ads_dump_seq_state(). Prototype was for asd_dump_seq_state() instead Link: https://lore.kernel.org/r/20210317091230.2912389-8-lee.jones@linaro.org Cc: "James E.J. Bottomley" Cc: "Martin K. Petersen" Cc: Lee Jones Cc: David Chaw Cc: Luben Tuikov Cc: linux-scsi@vger.kernel.org Signed-off-by: Lee Jones Signed-off-by: Martin K. Petersen --- drivers/scsi/aic94xx/aic94xx_dump.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/scsi/aic94xx/aic94xx_dump.c b/drivers/scsi/aic94xx/aic94xx_dump.c index 47a663a39dcc..552f1913e95e 100644 --- a/drivers/scsi/aic94xx/aic94xx_dump.c +++ b/drivers/scsi/aic94xx/aic94xx_dump.c @@ -721,7 +721,7 @@ static void asd_dump_lseq_state(struct asd_ha_struct *asd_ha, int lseq) } /** - * ads_dump_seq_state -- dump CSEQ and LSEQ states + * asd_dump_seq_state -- dump CSEQ and LSEQ states * @asd_ha: pointer to host adapter structure * @lseq_mask: mask of LSEQs of interest */ From f1d50e8ee5c9d9a3b1dd481d9c06e54eea65ada6 Mon Sep 17 00:00:00 2001 From: Lee Jones Date: Wed, 17 Mar 2021 09:12:02 +0000 Subject: [PATCH 196/412] scsi: be2iscsi: Ensure function follows directly after its header Fixes the following W=1 kernel build warning(s): drivers/scsi/be2iscsi/be_main.c:4935: warning: expecting prototype for beiscsi_show_boot_tgt_info(). Prototype was for BEISCSI_SYSFS_ISCSI_BOOT_FLAGS() instead Link: https://lore.kernel.org/r/20210317091230.2912389-9-lee.jones@linaro.org Cc: Subbu Seetharaman Cc: Ketan Mukadam Cc: Jitendra Bhivare Cc: "James E.J. Bottomley" Cc: "Martin K. Petersen" Cc: linux-drivers@broadcom.com Cc: linux-scsi@vger.kernel.org Signed-off-by: Lee Jones Signed-off-by: Martin K. Petersen --- drivers/scsi/be2iscsi/be_main.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/scsi/be2iscsi/be_main.c b/drivers/scsi/be2iscsi/be_main.c index ab32ca535078..eac67878b2b1 100644 --- a/drivers/scsi/be2iscsi/be_main.c +++ b/drivers/scsi/be2iscsi/be_main.c @@ -4926,14 +4926,13 @@ void beiscsi_start_boot_work(struct beiscsi_hba *phba, unsigned int s_handle) schedule_work(&phba->boot_work); } +#define BEISCSI_SYSFS_ISCSI_BOOT_FLAGS 3 /** * beiscsi_show_boot_tgt_info() * Boot flag info for iscsi-utilities * Bit 0 Block valid flag * Bit 1 Firmware booting selected */ -#define BEISCSI_SYSFS_ISCSI_BOOT_FLAGS 3 - static ssize_t beiscsi_show_boot_tgt_info(void *data, int type, char *buf) { struct beiscsi_hba *phba = data; From 33c8ef953ece49f7a5cdb08f20cdfefb8c308581 Mon Sep 17 00:00:00 2001 From: Lee Jones Date: Wed, 17 Mar 2021 09:12:03 +0000 Subject: [PATCH 197/412] scsi: dc395x: Fix some function param descriptions Fixes the following W=1 kernel build warning(s): drivers/scsi/dc395x.c:4353: warning: Function parameter or member 'acb' not described in 'adapter_init' drivers/scsi/dc395x.c:4353: warning: Function parameter or member 'io_port_len' not described in 'adapter_init' drivers/scsi/dc395x.c:4353: warning: Excess function parameter 'host' description in 'adapter_init' Link: https://lore.kernel.org/r/20210317091230.2912389-10-lee.jones@linaro.org Cc: Oliver Neukum Cc: Ali Akcaagac Cc: Jamie Lenehan Cc: "James E.J. Bottomley" Cc: "Martin K. Petersen" Cc: "C.L. Huang" Cc: Erich Chen Cc: Kurt Garloff Cc: dc395x@twibble.org Cc: linux-scsi@vger.kernel.org Signed-off-by: Lee Jones Signed-off-by: Martin K. Petersen --- drivers/scsi/dc395x.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/scsi/dc395x.c b/drivers/scsi/dc395x.c index e28f8931e23f..5503230006f8 100644 --- a/drivers/scsi/dc395x.c +++ b/drivers/scsi/dc395x.c @@ -4341,8 +4341,9 @@ static void adapter_init_chip(struct AdapterCtlBlk *acb) * tables etc etc. This basically gets all adapter information all up * to date, initialised and gets the chip in sync with it. * - * @host: This hosts adapter structure + * @acb: The adapter which we are to init. * @io_port: The base I/O port + * @io_port_len: The I/O port size * @irq: IRQ * * Returns 0 if the initialization succeeds, any other value on From 100ec495e01e270fc3fbcea44eaad181e4c8c688 Mon Sep 17 00:00:00 2001 From: Lee Jones Date: Wed, 17 Mar 2021 09:12:04 +0000 Subject: [PATCH 198/412] scsi: initio: Fix a few kernel-doc misdemeanours Fixes the following W=1 kernel build warning(s): drivers/scsi/initio.c:560: warning: Excess function parameter 'num_scbs' description in 'initio_init' drivers/scsi/initio.c:1899: warning: expecting prototype for int_initio_scsi_resel(). Prototype was for int_initio_resel() instead drivers/scsi/initio.c:2615: warning: expecting prototype for i91u_queuecommand(). Prototype was for i91u_queuecommand_lck() instead drivers/scsi/initio.c:2667: warning: Function parameter or member 'dev' not described in 'i91u_biosparam' drivers/scsi/initio.c:2667: warning: expecting prototype for i91u_biospararm(). Prototype was for i91u_biosparam() instead drivers/scsi/initio.c:2740: warning: Function parameter or member 'host_mem' not described in 'i91uSCBPost' drivers/scsi/initio.c:2740: warning: Function parameter or member 'cblk_mem' not described in 'i91uSCBPost' drivers/scsi/initio.c:2740: warning: Excess function parameter 'host' description in 'i91uSCBPost' drivers/scsi/initio.c:2740: warning: Excess function parameter 'cmnd' description in 'i91uSCBPost' Link: https://lore.kernel.org/r/20210317091230.2912389-11-lee.jones@linaro.org Cc: "James E.J. Bottomley" Cc: "Martin K. Petersen" Cc: Bas Vermeulen Cc: Christoph Hellwig Cc: Brian Macy Cc: linux-scsi@vger.kernel.org Signed-off-by: Lee Jones Signed-off-by: Martin K. Petersen --- drivers/scsi/initio.c | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/drivers/scsi/initio.c b/drivers/scsi/initio.c index 926a7045c2e5..9b75e19a9bab 100644 --- a/drivers/scsi/initio.c +++ b/drivers/scsi/initio.c @@ -546,7 +546,6 @@ static int initio_reset_scsi(struct initio_host * host, int seconds) /** * initio_init - set up an InitIO host adapter * @host: InitIO host adapter - * @num_scbs: Number of SCBS * @bios_addr: BIOS address * * Set up the host adapter and devices according to the configuration @@ -1887,7 +1886,7 @@ static int int_initio_scsi_rst(struct initio_host * host) } /** - * int_initio_scsi_resel - Reselection occurred + * int_initio_resel - Reselection occurred * @host: InitIO host adapter * * A SCSI reselection event has been signalled and the interrupt @@ -2601,7 +2600,7 @@ static void initio_build_scb(struct initio_host * host, struct scsi_ctrl_blk * c } /** - * i91u_queuecommand - Queue a new command if possible + * i91u_queuecommand_lck - Queue a new command if possible * @cmd: SCSI command block from the mid layer * @done: Completion handler * @@ -2650,9 +2649,9 @@ static int i91u_bus_reset(struct scsi_cmnd * cmnd) } /** - * i91u_biospararm - return the "logical geometry + * i91u_biosparam - return the "logical geometry * @sdev: SCSI device - * @dev; Matching block device + * @dev: Matching block device * @capacity: Sector size of drive * @info_array: Return space for BIOS geometry * @@ -2727,10 +2726,8 @@ static void i91u_unmap_scb(struct pci_dev *pci_dev, struct scsi_cmnd *cmnd) } } -/** +/* * i91uSCBPost - SCSI callback - * @host: Pointer to host adapter control block. - * @cmnd: Pointer to SCSI control block. * * This is callback routine be called when tulip finish one * SCSI command. From c548a6250627853ca59adf6823b0053ea3b6bfb7 Mon Sep 17 00:00:00 2001 From: Lee Jones Date: Wed, 17 Mar 2021 09:12:05 +0000 Subject: [PATCH 199/412] scsi: a100u2w: Fix some misnaming and formatting issues Fixes the following W=1 kernel build warning(s): drivers/scsi/a100u2w.c:278: warning: expecting prototype for orc_exec_sb(). Prototype was for orc_exec_scb() instead drivers/scsi/a100u2w.c:596: warning: Function parameter or member 'target' not described in 'orc_device_reset' drivers/scsi/a100u2w.c:739: warning: Function parameter or member 'host' not described in 'orchid_abort_scb' drivers/scsi/a100u2w.c:739: warning: Function parameter or member 'scb' not described in 'orchid_abort_scb' drivers/scsi/a100u2w.c:915: warning: expecting prototype for inia100_queue(). Prototype was for inia100_queue_lck() instead Link: https://lore.kernel.org/r/20210317091230.2912389-12-lee.jones@linaro.org Cc: "James E.J. Bottomley" Cc: "Martin K. Petersen" Cc: Doug Ledford Cc: Christoph Hellwig Cc: Alan Cox Cc: linux-scsi@vger.kernel.org Signed-off-by: Lee Jones Signed-off-by: Martin K. Petersen --- drivers/scsi/a100u2w.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/scsi/a100u2w.c b/drivers/scsi/a100u2w.c index c99224a128f8..c9ed210d77b3 100644 --- a/drivers/scsi/a100u2w.c +++ b/drivers/scsi/a100u2w.c @@ -269,7 +269,7 @@ static u8 orc_nv_read(struct orc_host * host, u8 address, u8 *ptr) } /** - * orc_exec_sb - Queue an SCB with the HA + * orc_exec_scb - Queue an SCB with the HA * @host: host adapter the SCB belongs to * @scb: SCB to queue for execution */ @@ -586,7 +586,7 @@ static int orc_reset_scsi_bus(struct orc_host * host) * orc_device_reset - device reset handler * @host: host to reset * @cmd: command causing the reset - * @target; target device + * @target: target device * * Reset registers, reset a hanging bus and kill active and disconnected * commands for target w/o soft reset @@ -727,7 +727,7 @@ static void orc_release_scb(struct orc_host *host, struct orc_scb *scb) spin_unlock_irqrestore(&(host->allocation_lock), flags); } -/** +/* * orchid_abort_scb - abort a command * * Abort a queued command that has been passed to the firmware layer @@ -902,7 +902,7 @@ static int inia100_build_scb(struct orc_host * host, struct orc_scb * scb, struc } /** - * inia100_queue - queue command with host + * inia100_queue_lck - queue command with host * @cmd: Command block * @done: Completion function * From 9eb292eb2ef748ed6b9acae365e8c3a6c51541af Mon Sep 17 00:00:00 2001 From: Lee Jones Date: Wed, 17 Mar 2021 09:12:06 +0000 Subject: [PATCH 200/412] scsi: myrs: Add missing ':' to make the kernel-doc checker happy Fixes the following W=1 kernel build warning(s): drivers/scsi/myrs.c:1965: warning: Function parameter or member 'dev' not described in 'myrs_is_raid' drivers/scsi/myrs.c:1978: warning: Function parameter or member 'dev' not described in 'myrs_get_resync' drivers/scsi/myrs.c:2002: warning: Function parameter or member 'dev' not described in 'myrs_get_state' Link: https://lore.kernel.org/r/20210317091230.2912389-13-lee.jones@linaro.org Cc: Hannes Reinecke Cc: "James E.J. Bottomley" Cc: "Martin K. Petersen" Cc: Linux GmbH Cc: "Leonard N. Zubkoff" Cc: linux-scsi@vger.kernel.org Signed-off-by: Lee Jones Signed-off-by: Martin K. Petersen --- drivers/scsi/myrs.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/scsi/myrs.c b/drivers/scsi/myrs.c index 48e399f057d5..588c0de006b0 100644 --- a/drivers/scsi/myrs.c +++ b/drivers/scsi/myrs.c @@ -1958,7 +1958,7 @@ static struct myrs_hba *myrs_alloc_host(struct pci_dev *pdev, /** * myrs_is_raid - return boolean indicating device is raid volume - * @dev the device struct object + * @dev: the device struct object */ static int myrs_is_raid(struct device *dev) @@ -1971,7 +1971,7 @@ myrs_is_raid(struct device *dev) /** * myrs_get_resync - get raid volume resync percent complete - * @dev the device struct object + * @dev: the device struct object */ static void myrs_get_resync(struct device *dev) @@ -1995,7 +1995,7 @@ myrs_get_resync(struct device *dev) /** * myrs_get_state - get raid volume status - * @dev the device struct object + * @dev: the device struct object */ static void myrs_get_state(struct device *dev) From a364a147b1dcb3c993c4ff1e7b13fa1643288bfb Mon Sep 17 00:00:00 2001 From: Lee Jones Date: Wed, 17 Mar 2021 09:12:07 +0000 Subject: [PATCH 201/412] scsi: pmcraid: Correct function name pmcraid_show_adapter_id() in header Fixes the following W=1 kernel build warning(s): drivers/scsi/pmcraid.c:4079: warning: expecting prototype for pmcraid_show_io_adapter_id(). Prototype was for pmcraid_show_adapter_id() instead Link: https://lore.kernel.org/r/20210317091230.2912389-14-lee.jones@linaro.org Cc: "James E.J. Bottomley" Cc: "Martin K. Petersen" Cc: Anil Ravindranath Cc: linux-scsi@vger.kernel.org Signed-off-by: Lee Jones Signed-off-by: Martin K. Petersen --- drivers/scsi/pmcraid.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/scsi/pmcraid.c b/drivers/scsi/pmcraid.c index c98e39eb04b2..bffd9a9349e7 100644 --- a/drivers/scsi/pmcraid.c +++ b/drivers/scsi/pmcraid.c @@ -4063,7 +4063,7 @@ static struct device_attribute pmcraid_driver_version_attr = { }; /** - * pmcraid_show_io_adapter_id - Display driver assigned adapter id + * pmcraid_show_adapter_id - Display driver assigned adapter id * @dev: class device struct * @attr: unused * @buf: buffer From a8d548b0b3eea1d2bd35aec8900d8f11f2e4c3f1 Mon Sep 17 00:00:00 2001 From: Lee Jones Date: Wed, 17 Mar 2021 09:12:08 +0000 Subject: [PATCH 202/412] scsi: mpt3sas: Fix a few kernel-doc issues Fixes the following W=1 kernel build warning(s): drivers/scsi/mpt3sas/mpt3sas_scsih.c:763: warning: Function parameter or member 'sas_address' not described in '__mpt3sas_get_sdev_by_addr' drivers/scsi/mpt3sas/mpt3sas_scsih.c:763: warning: expecting prototype for mpt3sas_get_sdev_by_addr(). Prototype was for __mpt3sas_get_sdev_by_addr() instead drivers/scsi/mpt3sas/mpt3sas_scsih.c:4535: warning: expecting prototype for _scsih_check_for_pending_internal_cmds(). Prototype was for mpt3sas_check_for_pending_internal_cmds() instead drivers/scsi/mpt3sas/mpt3sas_scsih.c:6188: warning: Function parameter or member 'port_entry' not described in '_scsih_look_and_get_matched_port_entry' drivers/scsi/mpt3sas/mpt3sas_scsih.c:6188: warning: Function parameter or member 'matched_port_entry' not described in '_scsih_look_and_get_matched_port_entry' drivers/scsi/mpt3sas/mpt3sas_scsih.c:6188: warning: Function parameter or member 'count' not described in '_scsih_look_and_get_matched_port_entry' drivers/scsi/mpt3sas/mpt3sas_scsih.c:6959: warning: Function parameter or member 'port' not described in 'mpt3sas_expander_remove' drivers/scsi/mpt3sas/mpt3sas_scsih.c:10494: warning: expecting prototype for mpt3sas_scsih_reset_handler(). Prototype was for mpt3sas_scsih_pre_reset_handler() instead drivers/scsi/mpt3sas/mpt3sas_scsih.c:10536: warning: expecting prototype for mpt3sas_scsih_reset_handler(). Prototype was for mpt3sas_scsih_reset_done_handler() instead drivers/scsi/mpt3sas/mpt3sas_scsih.c:12303: warning: expecting prototype for scsih__ncq_prio_supp(). Prototype was for scsih_ncq_prio_supp() instead Link: https://lore.kernel.org/r/20210317091230.2912389-15-lee.jones@linaro.org Cc: Sathya Prakash Cc: Sreekanth Reddy Cc: Suganath Prabu Subramani Cc: "James E.J. Bottomley" Cc: "Martin K. Petersen" Cc: MPT-FusionLinux.pdl@avagotech.com Cc: MPT-FusionLinux.pdl@broadcom.com Cc: linux-scsi@vger.kernel.org Signed-off-by: Lee Jones Signed-off-by: Martin K. Petersen --- drivers/scsi/mpt3sas/mpt3sas_scsih.c | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/drivers/scsi/mpt3sas/mpt3sas_scsih.c b/drivers/scsi/mpt3sas/mpt3sas_scsih.c index 945531e94d7e..23ecf2750ec7 100644 --- a/drivers/scsi/mpt3sas/mpt3sas_scsih.c +++ b/drivers/scsi/mpt3sas/mpt3sas_scsih.c @@ -749,9 +749,10 @@ __mpt3sas_get_sdev_by_rphy(struct MPT3SAS_ADAPTER *ioc, } /** - * mpt3sas_get_sdev_by_addr - get _sas_device object corresponding to provided + * __mpt3sas_get_sdev_by_addr - get _sas_device object corresponding to provided * sas address from sas_device_list list * @ioc: per adapter object + * @sas_address: device sas address * @port: port number * * Search for _sas_device object corresponding to provided sas address, @@ -4518,7 +4519,7 @@ _scsih_issue_delayed_sas_io_unit_ctrl(struct MPT3SAS_ADAPTER *ioc, } /** - * _scsih_check_for_pending_internal_cmds - check for pending internal messages + * mpt3sas_check_for_pending_internal_cmds - check for pending internal messages * @ioc: per adapter object * @smid: system request message index * @@ -6174,10 +6175,10 @@ enum hba_port_matched_codes { * _scsih_look_and_get_matched_port_entry - Get matched hba port entry * from HBA port table * @ioc: per adapter object - * @port_entry - hba port entry from temporary port table which needs to be + * @port_entry: hba port entry from temporary port table which needs to be * searched for matched entry in the HBA port table - * @matched_port_entry - save matched hba port entry here - * @count - count of matched entries + * @matched_port_entry: save matched hba port entry here + * @count: count of matched entries * * return type of matched entry found. */ @@ -6952,6 +6953,7 @@ _scsih_expander_add(struct MPT3SAS_ADAPTER *ioc, u16 handle) * mpt3sas_expander_remove - removing expander object * @ioc: per adapter object * @sas_address: expander sas_address + * @port: hba port entry */ void mpt3sas_expander_remove(struct MPT3SAS_ADAPTER *ioc, u64 sas_address, @@ -10487,7 +10489,7 @@ _scsih_scan_for_devices_after_reset(struct MPT3SAS_ADAPTER *ioc) } /** - * mpt3sas_scsih_reset_handler - reset callback handler (for scsih) + * mpt3sas_scsih_pre_reset_handler - reset callback handler (for scsih) * @ioc: per adapter object * * The handler for doing any required cleanup or initialization. @@ -10528,7 +10530,7 @@ mpt3sas_scsih_clear_outstanding_scsi_tm_commands(struct MPT3SAS_ADAPTER *ioc) } /** - * mpt3sas_scsih_reset_handler - reset callback handler (for scsih) + * mpt3sas_scsih_reset_done_handler - reset callback handler (for scsih) * @ioc: per adapter object * * The handler for doing any required cleanup or initialization. @@ -12295,7 +12297,7 @@ scsih_pci_mmio_enabled(struct pci_dev *pdev) } /** - * scsih__ncq_prio_supp - Check for NCQ command priority support + * scsih_ncq_prio_supp - Check for NCQ command priority support * @sdev: scsi device struct * * This is called when a user indicates they would like to enable From a90a8c607570c8912479917a6878c05cfb57b724 Mon Sep 17 00:00:00 2001 From: Lee Jones Date: Wed, 17 Mar 2021 09:12:09 +0000 Subject: [PATCH 203/412] scsi: be2iscsi: Demote incomplete/non-conformant kernel-doc header Fixes the following W=1 kernel build warning(s): drivers/scsi/be2iscsi/be_main.c:4937: warning: Function parameter or member 'data' not described in 'beiscsi_show_boot_tgt_info' drivers/scsi/be2iscsi/be_main.c:4937: warning: Function parameter or member 'type' not described in 'beiscsi_show_boot_tgt_info' drivers/scsi/be2iscsi/be_main.c:4937: warning: Function parameter or member 'buf' not described in 'beiscsi_show_boot_tgt_info' Link: https://lore.kernel.org/r/20210317091230.2912389-16-lee.jones@linaro.org Cc: Subbu Seetharaman Cc: Ketan Mukadam Cc: Jitendra Bhivare Cc: "James E.J. Bottomley" Cc: "Martin K. Petersen" Cc: linux-drivers@broadcom.com Cc: linux-scsi@vger.kernel.org Signed-off-by: Lee Jones Signed-off-by: Martin K. Petersen --- drivers/scsi/be2iscsi/be_main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/scsi/be2iscsi/be_main.c b/drivers/scsi/be2iscsi/be_main.c index eac67878b2b1..22cf7f4b8d8c 100644 --- a/drivers/scsi/be2iscsi/be_main.c +++ b/drivers/scsi/be2iscsi/be_main.c @@ -4927,7 +4927,7 @@ void beiscsi_start_boot_work(struct beiscsi_hba *phba, unsigned int s_handle) } #define BEISCSI_SYSFS_ISCSI_BOOT_FLAGS 3 -/** +/* * beiscsi_show_boot_tgt_info() * Boot flag info for iscsi-utilities * Bit 0 Block valid flag From c7eab0704c305606d7db2a698005acee8f129ad1 Mon Sep 17 00:00:00 2001 From: Lee Jones Date: Wed, 17 Mar 2021 09:12:11 +0000 Subject: [PATCH 204/412] scsi: fnic: Demote non-conformant kernel-doc headers Fixes the following W=1 kernel build warning(s): drivers/scsi/fnic/fnic_scsi.c:183: warning: Function parameter or member 'fnic' not described in '__fnic_set_state_flags' drivers/scsi/fnic/fnic_scsi.c:183: warning: Function parameter or member 'st_flags' not described in '__fnic_set_state_flags' drivers/scsi/fnic/fnic_scsi.c:183: warning: Function parameter or member 'clearbits' not described in '__fnic_set_state_flags' drivers/scsi/fnic/fnic_scsi.c:2296: warning: Function parameter or member 'fnic' not described in 'fnic_scsi_host_start_tag' drivers/scsi/fnic/fnic_scsi.c:2296: warning: Function parameter or member 'sc' not described in 'fnic_scsi_host_start_tag' drivers/scsi/fnic/fnic_scsi.c:2316: warning: Function parameter or member 'fnic' not described in 'fnic_scsi_host_end_tag' drivers/scsi/fnic/fnic_scsi.c:2316: warning: Function parameter or member 'sc' not described in 'fnic_scsi_host_end_tag' Link: https://lore.kernel.org/r/20210317091230.2912389-18-lee.jones@linaro.org Cc: Satish Kharat Cc: Sesidhar Baddela Cc: Karan Tilak Kumar Cc: "James E.J. Bottomley" Cc: "Martin K. Petersen" Cc: linux-scsi@vger.kernel.org Signed-off-by: Lee Jones Signed-off-by: Martin K. Petersen --- drivers/scsi/fnic/fnic_scsi.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/scsi/fnic/fnic_scsi.c b/drivers/scsi/fnic/fnic_scsi.c index 36744968378f..e619a82f921b 100644 --- a/drivers/scsi/fnic/fnic_scsi.c +++ b/drivers/scsi/fnic/fnic_scsi.c @@ -173,7 +173,7 @@ static int free_wq_copy_descs(struct fnic *fnic, struct vnic_wq_copy *wq) } -/** +/* * __fnic_set_state_flags * Sets/Clears bits in fnic's state_flags **/ @@ -2287,7 +2287,7 @@ clean_pending_aborts_end: return ret; } -/** +/* * fnic_scsi_host_start_tag * Allocates tagid from host's tag list **/ @@ -2307,7 +2307,7 @@ fnic_scsi_host_start_tag(struct fnic *fnic, struct scsi_cmnd *sc) return dummy->tag; } -/** +/* * fnic_scsi_host_end_tag * frees tag allocated by fnic_scsi_host_start_tag. **/ From 2efd8631d6a5c73cd3a749a9193660750fd936bb Mon Sep 17 00:00:00 2001 From: Lee Jones Date: Wed, 17 Mar 2021 09:12:12 +0000 Subject: [PATCH 205/412] scsi: fnic: Kernel-doc headers must contain the function name Fixes the following W=1 kernel build warning(s): drivers/scsi/fnic/fnic_fcs.c:308: warning: expecting prototype for Check if the Received FIP FLOGI frame is rejected(). Prototype was for is_fnic_fip_flogi_reject() instead Link: https://lore.kernel.org/r/20210317091230.2912389-19-lee.jones@linaro.org Cc: Satish Kharat Cc: Sesidhar Baddela Cc: Karan Tilak Kumar Cc: "James E.J. Bottomley" Cc: "Martin K. Petersen" Cc: linux-scsi@vger.kernel.org Signed-off-by: Lee Jones Signed-off-by: Martin K. Petersen --- drivers/scsi/fnic/fnic_fcs.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/scsi/fnic/fnic_fcs.c b/drivers/scsi/fnic/fnic_fcs.c index e0cee4dcb439..881c4823d7e2 100644 --- a/drivers/scsi/fnic/fnic_fcs.c +++ b/drivers/scsi/fnic/fnic_fcs.c @@ -296,7 +296,7 @@ void fnic_handle_event(struct work_struct *work) } /** - * Check if the Received FIP FLOGI frame is rejected + * is_fnic_fip_flogi_reject() - Check if the Received FIP FLOGI frame is rejected * @fip: The FCoE controller that received the frame * @skb: The received FIP frame * From 6af1d9bd90519e669a37a74333b14fd98f916792 Mon Sep 17 00:00:00 2001 From: Lee Jones Date: Wed, 17 Mar 2021 09:12:10 +0000 Subject: [PATCH 206/412] scsi: isci: phy: Fix a few different kernel-doc related issues Fixes the following W=1 kernel build warning(s): drivers/scsi/isci/phy.c:354: warning: Function parameter or member 'iphy' not described in 'phy_get_non_dummy_port' drivers/scsi/isci/phy.c:354: warning: expecting prototype for If the phy is(). Prototype was for phy_get_non_dummy_port() instead drivers/scsi/isci/phy.c:364: warning: wrong kernel-doc identifier on line: drivers/scsi/isci/phy.c:401: warning: wrong kernel-doc identifier on line: drivers/scsi/isci/phy.c:611: warning: Function parameter or member 'iphy' not described in 'sci_phy_complete_link_training' drivers/scsi/isci/phy.c:611: warning: Excess function parameter 'sci_phy' description in 'sci_phy_complete_link_training' drivers/scsi/isci/phy.c:1170: warning: Cannot understand * drivers/scsi/isci/phy.c:1222: warning: Cannot understand * drivers/scsi/isci/phy.c:1432: warning: Function parameter or member 'sas_phy' not described in 'isci_phy_control' drivers/scsi/isci/phy.c:1432: warning: Excess function parameter 'phy' description in 'isci_phy_control' Link: https://lore.kernel.org/r/20210317091230.2912389-17-lee.jones@linaro.org Cc: Artur Paszkiewicz Cc: "James E.J. Bottomley" Cc: "Martin K. Petersen" Cc: linux-scsi@vger.kernel.org Signed-off-by: Lee Jones Signed-off-by: Martin K. Petersen --- drivers/scsi/isci/phy.c | 21 ++++++++++----------- 1 file changed, 10 insertions(+), 11 deletions(-) diff --git a/drivers/scsi/isci/phy.c b/drivers/scsi/isci/phy.c index 1b87d9080ebe..7ca7621f7747 100644 --- a/drivers/scsi/isci/phy.c +++ b/drivers/scsi/isci/phy.c @@ -361,11 +361,9 @@ struct isci_port *phy_get_non_dummy_port(struct isci_phy *iphy) } /** - * This method will assign a port to the phy object. + * sci_phy_set_port() - This method will assign a port to the phy object. * @out]: iphy This parameter specifies the phy for which to assign a port * object. - * - * */ void sci_phy_set_port( struct isci_phy *iphy, @@ -398,11 +396,11 @@ enum sci_status sci_phy_initialize(struct isci_phy *iphy, } /** - * This method assigns the direct attached device ID for this phy. + * sci_phy_setup_transport() - This method assigns the direct attached device ID for this phy. * - * @iphy The phy for which the direct attached device id is to + * @iphy: The phy for which the direct attached device id is to * be assigned. - * @device_id The direct attached device ID to assign to the phy. + * @device_id: The direct attached device ID to assign to the phy. * This will either be the RNi for the device or an invalid RNi if there * is no current device assigned to the phy. */ @@ -597,7 +595,7 @@ static void sci_phy_start_sata_link_training(struct isci_phy *iphy) /** * sci_phy_complete_link_training - perform processing common to * all protocols upon completion of link training. - * @sci_phy: This parameter specifies the phy object for which link training + * @iphy: This parameter specifies the phy object for which link training * has completed. * @max_link_rate: This parameter specifies the maximum link rate to be * associated with this phy. @@ -1167,8 +1165,8 @@ static void sci_phy_starting_final_substate_enter(struct sci_base_state_machine } /** - * - * @sci_phy: This is the struct isci_phy object to stop. + * scu_link_layer_stop_protocol_engine() + * @iphy: This is the struct isci_phy object to stop. * * This method will stop the struct isci_phy object. This does not reset the * protocol engine it just suspends it and places it in a state where it will @@ -1219,7 +1217,8 @@ static void scu_link_layer_start_oob(struct isci_phy *iphy) } /** - * + * scu_link_layer_tx_hard_reset() + * @iphy: This is the struct isci_phy object to stop. * * This method will transmit a hard reset request on the specified phy. The SCU * hardware requires that we reset the OOB state machine and set the hard reset @@ -1420,7 +1419,7 @@ void isci_phy_init(struct isci_phy *iphy, struct isci_host *ihost, int index) /** * isci_phy_control() - This function is one of the SAS Domain Template * functions. This is a phy management function. - * @phy: This parameter specifies the sphy being controlled. + * @sas_phy: This parameter specifies the sphy being controlled. * @func: This parameter specifies the phy control function being invoked. * @buf: This parameter is specific to the phy function being invoked. * From 6ab7ca5139b76ab92141bfd4fe42a077d7ba0af5 Mon Sep 17 00:00:00 2001 From: Lee Jones Date: Wed, 17 Mar 2021 09:12:13 +0000 Subject: [PATCH 207/412] scsi: isci: phy: Provide function name and demote non-conforming header Fixes the following W=1 kernel build warning(s): drivers/scsi/isci/phy.c:354: warning: Function parameter or member 'iphy' not described in 'phy_get_non_dummy_port' drivers/scsi/isci/phy.c:354: warning: expecting prototype for If the phy is(). Prototype was for phy_get_non_dummy_port() instead drivers/scsi/isci/phy.c:371: warning: Function parameter or member 'iphy' not described in 'sci_phy_set_port' drivers/scsi/isci/phy.c:371: warning: Function parameter or member 'iport' not described in 'sci_phy_set_port' Link: https://lore.kernel.org/r/20210317091230.2912389-20-lee.jones@linaro.org Cc: Artur Paszkiewicz Cc: "James E.J. Bottomley" Cc: "Martin K. Petersen" Cc: linux-scsi@vger.kernel.org Signed-off-by: Lee Jones Signed-off-by: Martin K. Petersen --- drivers/scsi/isci/phy.c | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/drivers/scsi/isci/phy.c b/drivers/scsi/isci/phy.c index 7ca7621f7747..aa8787343e83 100644 --- a/drivers/scsi/isci/phy.c +++ b/drivers/scsi/isci/phy.c @@ -339,10 +339,11 @@ done: } /** - * This method returns the port currently containing this phy. If the phy is - * currently contained by the dummy port, then the phy is considered to not - * be part of a port. - * @sci_phy: This parameter specifies the phy for which to retrieve the + * phy_get_non_dummy_port() - This method returns the port currently containing + * this phy. If the phy is currently contained by the dummy port, then the phy + * is considered to not be part of a port. + * + * @iphy: This parameter specifies the phy for which to retrieve the * containing port. * * This method returns a handle to a port that contains the supplied phy. @@ -360,10 +361,8 @@ struct isci_port *phy_get_non_dummy_port(struct isci_phy *iphy) return iphy->owning_port; } -/** +/* * sci_phy_set_port() - This method will assign a port to the phy object. - * @out]: iphy This parameter specifies the phy for which to assign a port - * object. */ void sci_phy_set_port( struct isci_phy *iphy, From db35a083535719d8b0bb5070f8d4f1de95d33aef Mon Sep 17 00:00:00 2001 From: Lee Jones Date: Wed, 17 Mar 2021 09:12:14 +0000 Subject: [PATCH 208/412] scsi: isci: request: Fix a myriad of kernel-doc issues Fixes the following W=1 kernel build warning(s): drivers/scsi/isci/request.c:211: warning: wrong kernel-doc identifier on line: drivers/scsi/isci/request.c:414: warning: wrong kernel-doc identifier on line: drivers/scsi/isci/request.c:472: warning: Function parameter or member 'ireq' not described in 'scu_ssp_task_request_construct_task_context' drivers/scsi/isci/request.c:472: warning: expecting prototype for The(). Prototype was for scu_ssp_task_request_construct_task_context() instead drivers/scsi/isci/request.c:501: warning: Function parameter or member 'ireq' not described in 'scu_sata_request_construct_task_context' drivers/scsi/isci/request.c:501: warning: expecting prototype for This method is will fill in the SCU Task Context for any type of SATA(). Prototype was for scu_sata_request_construct_task_context() instead drivers/scsi/isci/request.c:597: warning: Cannot understand * drivers/scsi/isci/request.c:785: warning: expecting prototype for sci_req_tx_bytes(). Prototype was for SCU_TASK_CONTEXT_SRAM() instead drivers/scsi/isci/request.c:1399: warning: Cannot understand * drivers/scsi/isci/request.c:1446: warning: Cannot understand * drivers/scsi/isci/request.c:2465: warning: Function parameter or member 'task' not described in 'isci_request_process_response_iu' drivers/scsi/isci/request.c:2465: warning: Excess function parameter 'sas_task' description in 'isci_request_process_response_iu' drivers/scsi/isci/request.c:2501: warning: Function parameter or member 'task' not described in 'isci_request_set_open_reject_status' drivers/scsi/isci/request.c:2524: warning: Function parameter or member 'idev' not described in 'isci_request_handle_controller_specific_errors' drivers/scsi/isci/request.c:2524: warning: Function parameter or member 'task' not described in 'isci_request_handle_controller_specific_errors' drivers/scsi/isci/request.c:3337: warning: Function parameter or member 'idev' not described in 'isci_io_request_build' drivers/scsi/isci/request.c:3337: warning: Excess function parameter 'sci_device' description in 'isci_io_request_build' [mkp: fix typo reported by checkpatch] Link: https://lore.kernel.org/r/20210317091230.2912389-21-lee.jones@linaro.org Cc: Artur Paszkiewicz Cc: "James E.J. Bottomley" Cc: "Martin K. Petersen" Cc: linux-scsi@vger.kernel.org Signed-off-by: Lee Jones Signed-off-by: Martin K. Petersen --- drivers/scsi/isci/request.c | 58 ++++++++++++++++++------------------- 1 file changed, 28 insertions(+), 30 deletions(-) diff --git a/drivers/scsi/isci/request.c b/drivers/scsi/isci/request.c index 58e62162882f..764258f69992 100644 --- a/drivers/scsi/isci/request.c +++ b/drivers/scsi/isci/request.c @@ -207,11 +207,8 @@ static void sci_task_request_build_ssp_task_iu(struct isci_request *ireq) SCI_CONTROLLER_INVALID_IO_TAG; } -/** +/* * This method is will fill in the SCU Task Context for any type of SSP request. - * @sci_req: - * @task_context: - * */ static void scu_ssp_request_construct_task_context( struct isci_request *ireq, @@ -410,10 +407,8 @@ static void scu_ssp_ireq_dif_strip(struct isci_request *ireq, u8 type, u8 op) tc->ref_tag_seed_gen = 0; } -/** +/* * This method is will fill in the SCU Task Context for a SSP IO request. - * @sci_req: - * */ static void scu_ssp_io_request_construct_task_context(struct isci_request *ireq, enum dma_data_direction dir, @@ -456,17 +451,16 @@ static void scu_ssp_io_request_construct_task_context(struct isci_request *ireq, } /** - * This method will fill in the SCU Task Context for a SSP Task request. The - * following important settings are utilized: -# priority == - * SCU_TASK_PRIORITY_HIGH. This ensures that the task request is issued - * ahead of other task destined for the same Remote Node. -# task_type == - * SCU_TASK_TYPE_IOREAD. This simply indicates that a normal request type - * (i.e. non-raw frame) is being utilized to perform task management. -# - * control_frame == 1. This ensures that the proper endianess is set so - * that the bytes are transmitted in the right order for a task frame. - * @sci_req: This parameter specifies the task request object being - * constructed. - * + * scu_ssp_task_request_construct_task_context() - This method will fill in + * the SCU Task Context for a SSP Task request. The following important + * settings are utilized: -# priority == SCU_TASK_PRIORITY_HIGH. This + * ensures that the task request is issued ahead of other task destined + * for the same Remote Node. -# task_type == SCU_TASK_TYPE_IOREAD. This + * simply indicates that a normal request type (i.e. non-raw frame) is + * being utilized to perform task management. -#control_frame == 1. This + * ensures that the proper endianness is set so that the bytes are + * transmitted in the right order for a task frame. + * @ireq: This parameter specifies the task request object being constructed. */ static void scu_ssp_task_request_construct_task_context(struct isci_request *ireq) { @@ -484,6 +478,7 @@ static void scu_ssp_task_request_construct_task_context(struct isci_request *ire } /** + * scu_sata_request_construct_task_context() * This method is will fill in the SCU Task Context for any type of SATA * request. This is called from the various SATA constructors. * @sci_req: The general IO request object which is to be used in @@ -593,9 +588,9 @@ static enum sci_status sci_stp_pio_request_construct(struct isci_request *ireq, return SCI_SUCCESS; } -/** - * - * @sci_req: This parameter specifies the request to be constructed as an +/* + * sci_stp_optimized_request_construct() + * @ireq: This parameter specifies the request to be constructed as an * optimized request. * @optimized_task_type: This parameter specifies whether the request is to be * an UDMA request or a NCQ request. - A value of 0 indicates UDMA. - A @@ -778,11 +773,11 @@ static enum sci_status sci_io_request_construct_basic_sata(struct isci_request * return status; } +#define SCU_TASK_CONTEXT_SRAM 0x200000 /** * sci_req_tx_bytes - bytes transferred when reply underruns request * @ireq: request that was terminated early */ -#define SCU_TASK_CONTEXT_SRAM 0x200000 static u32 sci_req_tx_bytes(struct isci_request *ireq) { struct isci_host *ihost = ireq->owning_controller; @@ -1396,10 +1391,10 @@ static enum sci_status sci_stp_request_pio_data_out_transmit_data(struct isci_re } /** - * - * @stp_request: The request that is used for the SGL processing. - * @data_buffer: The buffer of data to be copied. - * @length: The length of the data transfer. + * sci_stp_request_pio_data_in_copy_data_buffer() + * @stp_req: The request that is used for the SGL processing. + * @data_buf: The buffer of data to be copied. + * @len: The length of the data transfer. * * Copy the data from the buffer for the length specified to the IO request SGL * specified data region. enum sci_status @@ -1443,8 +1438,8 @@ sci_stp_request_pio_data_in_copy_data_buffer(struct isci_stp_request *stp_req, } /** - * - * @sci_req: The PIO DATA IN request that is to receive the data. + * sci_stp_request_pio_data_in_copy_data() + * @stp_req: The PIO DATA IN request that is to receive the data. * @data_buffer: The buffer to copy from. * * Copy the data buffer to the io request data region. enum sci_status @@ -2452,7 +2447,7 @@ sci_io_request_tc_completion(struct isci_request *ireq, * isci_request_process_response_iu() - This function sets the status and * response iu, in the task struct, from the request object for the upper * layer driver. - * @sas_task: This parameter is the task struct from the upper layer driver. + * @task: This parameter is the task struct from the upper layer driver. * @resp_iu: This parameter points to the response iu of the completed request. * @dev: This parameter specifies the linux device struct. * @@ -2485,6 +2480,7 @@ static void isci_request_process_response_iu( * isci_request_set_open_reject_status() - This function prepares the I/O * completion for OPEN_REJECT conditions. * @request: This parameter is the completed isci_request object. + * @task: This parameter is the task struct from the upper layer driver. * @response_ptr: This parameter specifies the service response for the I/O. * @status_ptr: This parameter specifies the exec status for the I/O. * @open_rej_reason: This parameter specifies the encoded reason for the @@ -2509,7 +2505,9 @@ static void isci_request_set_open_reject_status( /** * isci_request_handle_controller_specific_errors() - This function decodes * controller-specific I/O completion error conditions. + * @idev: Remote device * @request: This parameter is the completed isci_request object. + * @task: This parameter is the task struct from the upper layer driver. * @response_ptr: This parameter specifies the service response for the I/O. * @status_ptr: This parameter specifies the exec status for the I/O. * @@ -3326,7 +3324,7 @@ static enum sci_status isci_smp_request_build(struct isci_request *ireq) * @ihost: This parameter specifies the ISCI host object * @request: This parameter points to the isci_request object allocated in the * request construct function. - * @sci_device: This parameter is the handle for the sci core's remote device + * @idev: This parameter is the handle for the sci core's remote device * object that is the destination for this request. * * SCI_SUCCESS on successfull completion, or specific failure code. From 44b7ca9661287d8eb6899e6476c617f2621d2e28 Mon Sep 17 00:00:00 2001 From: Lee Jones Date: Wed, 17 Mar 2021 09:12:15 +0000 Subject: [PATCH 209/412] scsi: isci: host: Fix bunch of kernel-doc related issues Fixes the following W=1 kernel build warning(s): drivers/scsi/isci/host.c:93: warning: Cannot understand * drivers/scsi/isci/host.c:108: warning: Function parameter or member 'x' not described in 'NORMALIZE_PUT_POINTER' drivers/scsi/isci/host.c:121: warning: Function parameter or member 'x' not described in 'NORMALIZE_EVENT_POINTER' drivers/scsi/isci/host.c:130: warning: Function parameter or member 'x' not described in 'NORMALIZE_GET_POINTER' drivers/scsi/isci/host.c:139: warning: Function parameter or member 'x' not described in 'NORMALIZE_GET_POINTER_CYCLE_BIT' drivers/scsi/isci/host.c:146: warning: Function parameter or member 'x' not described in 'COMPLETION_QUEUE_CYCLE_BIT' drivers/scsi/isci/host.c:646: warning: Function parameter or member 'ihost' not described in 'isci_host_start_complete' drivers/scsi/isci/host.c:646: warning: Excess function parameter 'isci_host' description in 'isci_host_start_complete' drivers/scsi/isci/host.c:680: warning: Function parameter or member 'ihost' not described in 'sci_controller_get_suggested_start_timeout' drivers/scsi/isci/host.c:680: warning: Excess function parameter 'controller' description in 'sci_controller_get_suggested_start_timeout' drivers/scsi/isci/host.c:903: warning: Function parameter or member 'ihost' not described in 'sci_controller_start_next_phy' drivers/scsi/isci/host.c:903: warning: Excess function parameter 'scic' description in 'sci_controller_start_next_phy' drivers/scsi/isci/host.c:1159: warning: Function parameter or member 'ihost' not described in 'sci_controller_stop' drivers/scsi/isci/host.c:1159: warning: Excess function parameter 'controller' description in 'sci_controller_stop' drivers/scsi/isci/host.c:1184: warning: Function parameter or member 'ihost' not described in 'sci_controller_reset' drivers/scsi/isci/host.c:1184: warning: Excess function parameter 'controller' description in 'sci_controller_reset' drivers/scsi/isci/host.c:1352: warning: Function parameter or member 'ihost' not described in 'sci_controller_set_interrupt_coalescence' drivers/scsi/isci/host.c:1352: warning: Excess function parameter 'controller' description in 'sci_controller_set_interrupt_coalescence' drivers/scsi/isci/host.c:2498: warning: Function parameter or member 'ihost' not described in 'sci_controller_allocate_remote_node_context' drivers/scsi/isci/host.c:2498: warning: Function parameter or member 'idev' not described in 'sci_controller_allocate_remote_node_context' drivers/scsi/isci/host.c:2498: warning: expecting prototype for This method allocates remote node index and the reserves the remote node(). Prototype was for sci_controller_allocate_remote_node_context() instead drivers/scsi/isci/host.c:2721: warning: Function parameter or member 'ihost' not described in 'sci_controller_start_task' drivers/scsi/isci/host.c:2721: warning: Function parameter or member 'idev' not described in 'sci_controller_start_task' drivers/scsi/isci/host.c:2721: warning: Function parameter or member 'ireq' not described in 'sci_controller_start_task' drivers/scsi/isci/host.c:2721: warning: Excess function parameter 'controller' description in 'sci_controller_start_task' drivers/scsi/isci/host.c:2721: warning: Excess function parameter 'remote_device' description in 'sci_controller_start_task' drivers/scsi/isci/host.c:2721: warning: Excess function parameter 'task_request' description in 'sci_controller_start_task' Link: https://lore.kernel.org/r/20210317091230.2912389-22-lee.jones@linaro.org Cc: Artur Paszkiewicz Cc: "James E.J. Bottomley" Cc: "Martin K. Petersen" Cc: linux-scsi@vger.kernel.org Signed-off-by: Lee Jones Signed-off-by: Martin K. Petersen --- drivers/scsi/isci/host.c | 37 ++++++++++++++++++------------------- 1 file changed, 18 insertions(+), 19 deletions(-) diff --git a/drivers/scsi/isci/host.c b/drivers/scsi/isci/host.c index 7ebfa3c8cdc7..d690d9cf7eb1 100644 --- a/drivers/scsi/isci/host.c +++ b/drivers/scsi/isci/host.c @@ -89,16 +89,14 @@ #define SCIC_SDS_CONTROLLER_PHY_START_TIMEOUT 100 -/** - * - * +/* * The number of milliseconds to wait while a given phy is consuming power * before allowing another set of phys to consume power. Ultimately, this will * be specified by OEM parameter. */ #define SCIC_SDS_CONTROLLER_POWER_CONTROL_INTERVAL 500 -/** +/* * NORMALIZE_PUT_POINTER() - * * This macro will normalize the completion queue put pointer so its value can @@ -108,7 +106,7 @@ ((x) & SMU_COMPLETION_QUEUE_PUT_POINTER_MASK) -/** +/* * NORMALIZE_EVENT_POINTER() - * * This macro will normalize the completion queue event entry so its value can @@ -120,7 +118,7 @@ >> SMU_COMPLETION_QUEUE_GET_EVENT_POINTER_SHIFT \ ) -/** +/* * NORMALIZE_GET_POINTER() - * * This macro will normalize the completion queue get pointer so its value can @@ -129,7 +127,7 @@ #define NORMALIZE_GET_POINTER(x) \ ((x) & SMU_COMPLETION_QUEUE_GET_POINTER_MASK) -/** +/* * NORMALIZE_GET_POINTER_CYCLE_BIT() - * * This macro will normalize the completion queue cycle pointer so it matches @@ -138,7 +136,7 @@ #define NORMALIZE_GET_POINTER_CYCLE_BIT(x) \ ((SMU_CQGR_CYCLE_BIT & (x)) << (31 - SMU_COMPLETION_QUEUE_GET_CYCLE_BIT_SHIFT)) -/** +/* * COMPLETION_QUEUE_CYCLE_BIT() - * * This macro will return the cycle bit of the completion queue entry @@ -637,7 +635,7 @@ irqreturn_t isci_error_isr(int vec, void *data) /** * isci_host_start_complete() - This function is called by the core library, * through the ISCI Module, to indicate controller start status. - * @isci_host: This parameter specifies the ISCI host object + * @ihost: This parameter specifies the ISCI host object * @completion_status: This parameter specifies the completion status from the * core library. * @@ -670,7 +668,7 @@ int isci_host_scan_finished(struct Scsi_Host *shost, unsigned long time) * use any timeout value, but this method provides the suggested minimum * start timeout value. The returned value is based upon empirical * information determined as a result of interoperability testing. - * @controller: the handle to the controller object for which to return the + * @ihost: the handle to the controller object for which to return the * suggested start timeout. * * This method returns the number of milliseconds for the suggested start @@ -893,7 +891,7 @@ bool is_controller_start_complete(struct isci_host *ihost) /** * sci_controller_start_next_phy - start phy - * @scic: controller + * @ihost: controller * * If all the phys have been started, then attempt to transition the * controller to the READY state and inform the user @@ -1145,7 +1143,7 @@ void isci_host_completion_routine(unsigned long data) * controller has been quiesced. This method will ensure that all IO * requests are quiesced, phys are stopped, and all additional operation by * the hardware is halted. - * @controller: the handle to the controller object to stop. + * @ihost: the handle to the controller object to stop. * @timeout: This parameter specifies the number of milliseconds in which the * stop operation should complete. * @@ -1174,7 +1172,7 @@ static enum sci_status sci_controller_stop(struct isci_host *ihost, u32 timeout) * considered destructive. In other words, all current operations are wiped * out. No IO completions for outstanding devices occur. Outstanding IO * requests are not aborted or completed at the actual remote device. - * @controller: the handle to the controller object to reset. + * @ihost: the handle to the controller object to reset. * * Indicate if the controller reset method succeeded or failed in some way. * SCI_SUCCESS if the reset operation successfully started. SCI_FATAL_ERROR if @@ -1331,7 +1329,7 @@ static inline void sci_controller_starting_state_exit(struct sci_base_state_mach /** * sci_controller_set_interrupt_coalescence() - This method allows the user to * configure the interrupt coalescence. - * @controller: This parameter represents the handle to the controller object + * @ihost: This parameter represents the handle to the controller object * for which its interrupt coalesce register is overridden. * @coalesce_number: Used to control the number of entries in the Completion * Queue before an interrupt is generated. If the number of entries exceed @@ -2479,12 +2477,13 @@ struct isci_request *sci_request_by_tag(struct isci_host *ihost, u16 io_tag) } /** + * sci_controller_allocate_remote_node_context() * This method allocates remote node index and the reserves the remote node * context space for use. This method can fail if there are no more remote * node index available. - * @scic: This is the controller object which contains the set of + * @ihost: This is the controller object which contains the set of * free remote node ids - * @sci_dev: This is the device object which is requesting the a remote node + * @idev: This is the device object which is requesting the a remote node * id * @node_id: This is the remote node id that is assinged to the device if one * is available @@ -2709,11 +2708,11 @@ enum sci_status sci_controller_continue_io(struct isci_request *ireq) /** * sci_controller_start_task() - This method is called by the SCIC user to * send/start a framework task management request. - * @controller: the handle to the controller object for which to start the task + * @ihost: the handle to the controller object for which to start the task * management request. - * @remote_device: the handle to the remote device object for which to start + * @idev: the handle to the remote device object for which to start * the task management request. - * @task_request: the handle to the task request object to start. + * @ireq: the handle to the task request object to start. */ enum sci_status sci_controller_start_task(struct isci_host *ihost, struct isci_remote_device *idev, From 0afdee03f2e78941a494b5a7386c39966c4a5c0b Mon Sep 17 00:00:00 2001 From: Lee Jones Date: Wed, 17 Mar 2021 09:12:16 +0000 Subject: [PATCH 210/412] scsi: isci: task: Demote non-conformant header and remove superfluous param Fixes the following W=1 kernel build warning(s): drivers/scsi/isci/task.c:383: warning: Function parameter or member 'isci_host' not described in 'isci_task_send_lu_reset_sas' drivers/scsi/isci/task.c:383: warning: Function parameter or member 'isci_device' not described in 'isci_task_send_lu_reset_sas' drivers/scsi/isci/task.c:677: warning: Excess function parameter 'lun' description in 'isci_task_query_task' Link: https://lore.kernel.org/r/20210317091230.2912389-23-lee.jones@linaro.org Cc: Artur Paszkiewicz Cc: "James E.J. Bottomley" Cc: "Martin K. Petersen" Cc: linux-scsi@vger.kernel.org Signed-off-by: Lee Jones Signed-off-by: Martin K. Petersen --- drivers/scsi/isci/task.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/scsi/isci/task.c b/drivers/scsi/isci/task.c index 26fa1a4d1e6b..62062ed6cd9a 100644 --- a/drivers/scsi/isci/task.c +++ b/drivers/scsi/isci/task.c @@ -369,7 +369,7 @@ static void isci_task_build_abort_task_tmf(struct isci_tmf *tmf, tmf->io_tag = old_request->io_tag; } -/** +/* * isci_task_send_lu_reset_sas() - This function is called by of the SAS Domain * Template functions. * @lun: This parameter specifies the lun to be reset. @@ -668,7 +668,6 @@ int isci_task_clear_task_set( * returned, libsas turns this into a LUN reset; when FUNC_FAILED is * returned, libsas will turn this into a target reset * @task: This parameter specifies the sas task being queried. - * @lun: This parameter specifies the lun associated with this request. * * status, zero indicates success. */ From 103d61927ed34243964918459fb3f346d59be766 Mon Sep 17 00:00:00 2001 From: Lee Jones Date: Wed, 17 Mar 2021 09:12:17 +0000 Subject: [PATCH 211/412] scsi: isci: remote_node_table: Fix a bunch of kernel-doc misdemeanours Fixes the following W=1 kernel build warning(s): drivers/scsi/isci/remote_node_table.c:66: warning: Incorrect use of kernel-doc format: * drivers/scsi/isci/remote_node_table.c:80: warning: Function parameter or member 'remote_node_table' not described in 'sci_remote_node_table_get_group_index' drivers/scsi/isci/remote_node_table.c:80: warning: Function parameter or member 'group_table_index' not described in 'sci_remote_node_table_get_group_index' drivers/scsi/isci/remote_node_table.c:80: warning: expecting prototype for This file contains the implementation of the SCIC_SDS_REMOTE_NODE_TABLE(). Prototype was for sci_remote_node_table_get_group_index() instead drivers/scsi/isci/remote_node_table.c:101: warning: Cannot understand * drivers/scsi/isci/remote_node_table.c:131: warning: Cannot understand * drivers/scsi/isci/remote_node_table.c:161: warning: Cannot understand * drivers/scsi/isci/remote_node_table.c:194: warning: Cannot understand * drivers/scsi/isci/remote_node_table.c:227: warning: Cannot understand * drivers/scsi/isci/remote_node_table.c:256: warning: Cannot understand * drivers/scsi/isci/remote_node_table.c:283: warning: Cannot understand * drivers/scsi/isci/remote_node_table.c:310: warning: Cannot understand * drivers/scsi/isci/remote_node_table.c:368: warning: Cannot understand * drivers/scsi/isci/remote_node_table.c:428: warning: Cannot understand * drivers/scsi/isci/remote_node_table.c:465: warning: Cannot understand * drivers/scsi/isci/remote_node_table.c:508: warning: Cannot understand * drivers/scsi/isci/remote_node_table.c:553: warning: Cannot understand * drivers/scsi/isci/remote_node_table.c:576: warning: Cannot understand * Link: https://lore.kernel.org/r/20210317091230.2912389-24-lee.jones@linaro.org Cc: Artur Paszkiewicz Cc: "James E.J. Bottomley" Cc: "Martin K. Petersen" Cc: linux-scsi@vger.kernel.org Signed-off-by: Lee Jones Signed-off-by: Martin K. Petersen --- drivers/scsi/isci/remote_node_table.c | 51 +++++++++++++-------------- 1 file changed, 25 insertions(+), 26 deletions(-) diff --git a/drivers/scsi/isci/remote_node_table.c b/drivers/scsi/isci/remote_node_table.c index 301b3141945e..1036ab936626 100644 --- a/drivers/scsi/isci/remote_node_table.c +++ b/drivers/scsi/isci/remote_node_table.c @@ -53,17 +53,15 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -/** +/* * This file contains the implementation of the SCIC_SDS_REMOTE_NODE_TABLE * public, protected, and private methods. - * - * */ #include "remote_node_table.h" #include "remote_node_context.h" /** - * + * sci_remote_node_table_get_group_index() * @remote_node_table: This is the remote node index table from which the * selection will be made. * @group_table_index: This is the index to the group table from which to @@ -98,8 +96,8 @@ static u32 sci_remote_node_table_get_group_index( } /** - * - * @out]: remote_node_table This the remote node table in which to clear the + * sci_remote_node_table_clear_group_index() + * @remote_node_table: This the remote node table in which to clear the * selector. * @set_index: This is the remote node selector in which the change will be * made. @@ -128,8 +126,8 @@ static void sci_remote_node_table_clear_group_index( } /** - * - * @out]: remote_node_table This the remote node table in which to set the + * sci_remote_node_table_set_group_index() + * @remote_node_table: This the remote node table in which to set the * selector. * @group_table_index: This is the remote node selector in which the change * will be made. @@ -158,8 +156,8 @@ static void sci_remote_node_table_set_group_index( } /** - * - * @out]: remote_node_table This is the remote node table in which to modify + * sci_remote_node_table_set_node_index() + * @remote_node_table: This is the remote node table in which to modify * the remote node availability. * @remote_node_index: This is the remote node index that is being returned to * the table. @@ -191,8 +189,8 @@ static void sci_remote_node_table_set_node_index( } /** - * - * @out]: remote_node_table This is the remote node table from which to clear + * sci_remote_node_table_clear_node_index() + * @remote_node_table: This is the remote node table from which to clear * the available remote node bit. * @remote_node_index: This is the remote node index which is to be cleared * from the table. @@ -224,8 +222,8 @@ static void sci_remote_node_table_clear_node_index( } /** - * - * @out]: remote_node_table The remote node table from which the slot will be + * sci_remote_node_table_clear_group() + * @remote_node_table: The remote node table from which the slot will be * cleared. * @group_index: The index for the slot that is to be cleared. * @@ -253,7 +251,7 @@ static void sci_remote_node_table_clear_group( } /** - * + * sci_remote_node_table_set_group() * @remote_node_table: * * THis method sets an entire remote node group in the remote node table. @@ -280,7 +278,7 @@ static void sci_remote_node_table_set_group( } /** - * + * sci_remote_node_table_get_group_value() * @remote_node_table: This is the remote node table that for which the group * value is to be returned. * @group_index: This is the group index to use to find the group value. @@ -307,8 +305,8 @@ static u8 sci_remote_node_table_get_group_value( } /** - * - * @out]: remote_node_table The remote that which is to be initialized. + * sci_remote_node_table_initialize() + * @remote_node_table: The remote that which is to be initialized. * @remote_node_entries: The number of entries to put in the table. * * This method will initialize the remote node table for use. none @@ -365,8 +363,8 @@ void sci_remote_node_table_initialize( } /** - * - * @out]: remote_node_table The remote node table from which to allocate a + * sci_remote_node_table_allocate_single_remote_node() + * @remote_node_table: The remote node table from which to allocate a * remote node. * @table_index: The group index that is to be used for the search. * @@ -425,7 +423,7 @@ static u16 sci_remote_node_table_allocate_single_remote_node( } /** - * + * sci_remote_node_table_allocate_triple_remote_node() * @remote_node_table: This is the remote node table from which to allocate the * remote node entries. * @group_table_index: THis is the group table index which must equal two (2) @@ -462,7 +460,7 @@ static u16 sci_remote_node_table_allocate_triple_remote_node( } /** - * + * sci_remote_node_table_allocate_remote_node() * @remote_node_table: This is the remote node table from which the remote node * allocation is to take place. * @remote_node_count: This is ther remote node count which is one of @@ -505,8 +503,9 @@ u16 sci_remote_node_table_allocate_remote_node( } /** - * - * @remote_node_table: + * sci_remote_node_table_release_single_remote_node() + * @remote_node_table: This is the remote node table from which the remote node + * release is to take place. * * This method will free a single remote node index back to the remote node * table. This routine will update the remote node groups @@ -550,7 +549,7 @@ static void sci_remote_node_table_release_single_remote_node( } /** - * + * sci_remote_node_table_release_triple_remote_node() * @remote_node_table: This is the remote node table to which the remote node * index is to be freed. * @@ -573,7 +572,7 @@ static void sci_remote_node_table_release_triple_remote_node( } /** - * + * sci_remote_node_table_release_remote_node_index() * @remote_node_table: The remote node table to which the remote node index is * to be freed. * @remote_node_count: This is the count of consecutive remote nodes that are From ad276048f1bce4d97040cde64eeef61a552c708e Mon Sep 17 00:00:00 2001 From: Lee Jones Date: Wed, 17 Mar 2021 09:12:18 +0000 Subject: [PATCH 212/412] scsi: isci: remote_node_context: Fix one function header and demote a couple more Fixes the following W=1 kernel build warning(s): drivers/scsi/isci/remote_node_context.c:77: warning: Cannot understand * drivers/scsi/isci/remote_node_context.c:167: warning: Cannot understand * drivers/scsi/isci/remote_node_context.c:206: warning: Cannot understand * Link: https://lore.kernel.org/r/20210317091230.2912389-25-lee.jones@linaro.org Cc: Artur Paszkiewicz Cc: "James E.J. Bottomley" Cc: "Martin K. Petersen" Cc: linux-scsi@vger.kernel.org Signed-off-by: Lee Jones Signed-off-by: Martin K. Petersen --- drivers/scsi/isci/remote_node_context.c | 11 ++--------- 1 file changed, 2 insertions(+), 9 deletions(-) diff --git a/drivers/scsi/isci/remote_node_context.c b/drivers/scsi/isci/remote_node_context.c index 68333f523b35..7a576b995afa 100644 --- a/drivers/scsi/isci/remote_node_context.c +++ b/drivers/scsi/isci/remote_node_context.c @@ -74,7 +74,7 @@ const char *rnc_state_name(enum scis_sds_remote_node_context_states state) #undef C /** - * + * sci_remote_node_context_is_ready() * @sci_rnc: The state of the remote node context object to check. * * This method will return true if the remote node context is in a READY state @@ -163,12 +163,7 @@ static void sci_remote_node_context_construct_buffer(struct sci_remote_node_cont rnc->ssp.oaf_source_zone_group = 0; rnc->ssp.oaf_more_compatibility_features = 0; } -/** - * - * @sci_rnc: - * @callback: - * @callback_parameter: - * +/* * This method will setup the remote node context object so it will transition * to its ready state. If the remote node context is already setup to * transition to its final state then this function does nothing. none @@ -203,8 +198,6 @@ static void sci_remote_node_context_setup_to_destroy( } /** - * - * * This method just calls the user callback function and then resets the * callback. */ From 29faa5ce26ae7880821220b08a457ac2a87b3f0c Mon Sep 17 00:00:00 2001 From: Lee Jones Date: Wed, 17 Mar 2021 09:12:19 +0000 Subject: [PATCH 213/412] scsi: isci: port_config: Fix a bunch of doc-rot and demote abuses Fixes the following W=1 kernel build warning(s): drivers/scsi/isci/port_config.c:76: warning: Cannot understand * drivers/scsi/isci/port_config.c:105: warning: Cannot understand * drivers/scsi/isci/port_config.c:148: warning: Cannot understand * drivers/scsi/isci/port_config.c:376: warning: Cannot understand * drivers/scsi/isci/port_config.c:607: warning: Function parameter or member 'ihost' not described in 'sci_apc_agent_link_up' drivers/scsi/isci/port_config.c:607: warning: Function parameter or member 'port_agent' not described in 'sci_apc_agent_link_up' drivers/scsi/isci/port_config.c:607: warning: Function parameter or member 'iport' not described in 'sci_apc_agent_link_up' drivers/scsi/isci/port_config.c:607: warning: Function parameter or member 'iphy' not described in 'sci_apc_agent_link_up' drivers/scsi/isci/port_config.c:607: warning: Excess function parameter 'scic' description in 'sci_apc_agent_link_up' drivers/scsi/isci/port_config.c:607: warning: Excess function parameter 'sci_port' description in 'sci_apc_agent_link_up' drivers/scsi/isci/port_config.c:607: warning: Excess function parameter 'sci_phy' description in 'sci_apc_agent_link_up' drivers/scsi/isci/port_config.c:623: warning: Cannot understand * drivers/scsi/isci/port_config.c:701: warning: Cannot understand * Link: https://lore.kernel.org/r/20210317091230.2912389-26-lee.jones@linaro.org Cc: Artur Paszkiewicz Cc: "James E.J. Bottomley" Cc: "Martin K. Petersen" Cc: linux-scsi@vger.kernel.org Signed-off-by: Lee Jones Signed-off-by: Martin K. Petersen --- drivers/scsi/isci/port_config.c | 37 +++++++++++++++++---------------- 1 file changed, 19 insertions(+), 18 deletions(-) diff --git a/drivers/scsi/isci/port_config.c b/drivers/scsi/isci/port_config.c index b1c197505579..c382a257b51b 100644 --- a/drivers/scsi/isci/port_config.c +++ b/drivers/scsi/isci/port_config.c @@ -73,7 +73,7 @@ enum SCIC_SDS_APC_ACTIVITY { * ****************************************************************************** */ /** - * + * sci_sas_address_compare() * @address_one: A SAS Address to be compared. * @address_two: A SAS Address to be compared. * @@ -102,9 +102,9 @@ static s32 sci_sas_address_compare( } /** - * - * @controller: The controller object used for the port search. - * @phy: The phy object to match. + * sci_port_configuration_agent_find_port() + * @ihost: The controller object used for the port search. + * @iphy: The phy object to match. * * This routine will find a matching port for the phy. This means that the * port and phy both have the same broadcast sas address and same received sas @@ -145,8 +145,8 @@ static struct isci_port *sci_port_configuration_agent_find_port( } /** - * - * @controller: This is the controller object that contains the port agent + * sci_port_configuration_agent_validate_ports() + * @ihost: This is the controller object that contains the port agent * @port_agent: This is the port configuration agent for the controller. * * This routine will validate the port configuration is correct for the SCU @@ -373,15 +373,16 @@ static void sci_mpc_agent_link_up(struct isci_host *ihost, } /** - * - * @controller: This is the controller object that receives the link down + * sci_mpc_agent_link_down() + * @ihost: This is the controller object that receives the link down * notification. - * @port: This is the port object associated with the phy. If the is no + * @port_agent: This is the port configuration agent for the controller. + * @iport: This is the port object associated with the phy. If the is no * associated port this is an NULL. The port is an invalid * handle only if the phy was never port of this port. This happens when * the phy is not broadcasting the same SAS address as the other phys in the * assigned port. - * @phy: This is the phy object which has gone link down. + * @iphy: This is the phy object which has gone link down. * * This function handles the manual port configuration link down notifications. * Since all ports and phys are associated at initialization time we just turn @@ -590,11 +591,12 @@ static void sci_apc_agent_configure_ports(struct isci_host *ihost, /** * sci_apc_agent_link_up - handle apc link up events - * @scic: This is the controller object that receives the link up + * @ihost: This is the controller object that receives the link up * notification. - * @sci_port: This is the port object associated with the phy. If the is no + * @port_agent: This is the port configuration agent for the controller. + * @iport: This is the port object associated with the phy. If the is no * associated port this is an NULL. - * @sci_phy: This is the phy object which has gone link up. + * @iphy: This is the phy object which has gone link up. * * This method handles the automatic port configuration for link up * notifications. Is it possible to get a link down notification from a phy @@ -620,9 +622,10 @@ static void sci_apc_agent_link_up(struct isci_host *ihost, } /** - * - * @controller: This is the controller object that receives the link down + * sci_apc_agent_link_down() + * @ihost: This is the controller object that receives the link down * notification. + * @port_agent: This is the port configuration agent for the controller. * @iport: This is the port object associated with the phy. If the is no * associated port this is an NULL. * @iphy: This is the phy object which has gone link down. @@ -697,9 +700,7 @@ done: * Public port configuration agent routines * ****************************************************************************** */ -/** - * - * +/* * This method will construct the port configuration agent for operation. This * call is universal for both manual port configuration and automatic port * configuration modes. From 242e15d7a4f4087903e7a472e724f92c896d5b6e Mon Sep 17 00:00:00 2001 From: Lee Jones Date: Wed, 17 Mar 2021 09:12:20 +0000 Subject: [PATCH 214/412] scsi: isci: remote_device: Fix a bunch of doc-rot issues Fixes the following W=1 kernel build warning(s): drivers/scsi/isci/remote_device.c:299: warning: Function parameter or member 'ihost' not described in 'isci_remote_device_not_ready' drivers/scsi/isci/remote_device.c:299: warning: Function parameter or member 'idev' not described in 'isci_remote_device_not_ready' drivers/scsi/isci/remote_device.c:299: warning: Function parameter or member 'reason' not described in 'isci_remote_device_not_ready' drivers/scsi/isci/remote_device.c:299: warning: Excess function parameter 'isci_host' description in 'isci_remote_device_not_ready' drivers/scsi/isci/remote_device.c:299: warning: Excess function parameter 'isci_device' description in 'isci_remote_device_not_ready' drivers/scsi/isci/remote_device.c:1015: warning: Function parameter or member 'idev' not described in 'sci_remote_device_destruct' drivers/scsi/isci/remote_device.c:1015: warning: Excess function parameter 'remote_device' description in 'sci_remote_device_destruct' drivers/scsi/isci/remote_device.c:1249: warning: Function parameter or member 'iport' not described in 'sci_remote_device_construct' drivers/scsi/isci/remote_device.c:1249: warning: Function parameter or member 'idev' not described in 'sci_remote_device_construct' drivers/scsi/isci/remote_device.c:1249: warning: Excess function parameter 'sci_port' description in 'sci_remote_device_construct' drivers/scsi/isci/remote_device.c:1249: warning: Excess function parameter 'sci_dev' description in 'sci_remote_device_construct' drivers/scsi/isci/remote_device.c:1275: warning: Function parameter or member 'iport' not described in 'sci_remote_device_da_construct' drivers/scsi/isci/remote_device.c:1275: warning: Function parameter or member 'idev' not described in 'sci_remote_device_da_construct' drivers/scsi/isci/remote_device.c:1311: warning: Function parameter or member 'iport' not described in 'sci_remote_device_ea_construct' drivers/scsi/isci/remote_device.c:1311: warning: Function parameter or member 'idev' not described in 'sci_remote_device_ea_construct' drivers/scsi/isci/remote_device.c:1453: warning: Function parameter or member 'idev' not described in 'sci_remote_device_start' drivers/scsi/isci/remote_device.c:1453: warning: Excess function parameter 'remote_device' description in 'sci_remote_device_start' drivers/scsi/isci/remote_device.c:1513: warning: Function parameter or member 'ihost' not described in 'isci_remote_device_alloc' drivers/scsi/isci/remote_device.c:1513: warning: Function parameter or member 'iport' not described in 'isci_remote_device_alloc' drivers/scsi/isci/remote_device.c:1513: warning: expecting prototype for This function builds the isci_remote_device when a libsas dev_found message(). Prototype was for isci_remote_device_alloc() instead drivers/scsi/isci/remote_device.c:1558: warning: Function parameter or member 'ihost' not described in 'isci_remote_device_stop' drivers/scsi/isci/remote_device.c:1558: warning: Function parameter or member 'idev' not described in 'isci_remote_device_stop' drivers/scsi/isci/remote_device.c:1558: warning: Excess function parameter 'isci_host' description in 'isci_remote_device_stop' drivers/scsi/isci/remote_device.c:1558: warning: Excess function parameter 'isci_device' description in 'isci_remote_device_stop' drivers/scsi/isci/remote_device.c:1592: warning: Function parameter or member 'dev' not described in 'isci_remote_device_gone' drivers/scsi/isci/remote_device.c:1592: warning: Excess function parameter 'domain_device' description in 'isci_remote_device_gone' drivers/scsi/isci/remote_device.c:1614: warning: Function parameter or member 'dev' not described in 'isci_remote_device_found' drivers/scsi/isci/remote_device.c:1614: warning: Excess function parameter 'domain_device' description in 'isci_remote_device_found' Link: https://lore.kernel.org/r/20210317091230.2912389-27-lee.jones@linaro.org Cc: Artur Paszkiewicz Cc: "James E.J. Bottomley" Cc: "Martin K. Petersen" Cc: linux-scsi@vger.kernel.org Signed-off-by: Lee Jones Signed-off-by: Martin K. Petersen --- drivers/scsi/isci/remote_device.c | 31 ++++++++++++++++--------------- 1 file changed, 16 insertions(+), 15 deletions(-) diff --git a/drivers/scsi/isci/remote_device.c b/drivers/scsi/isci/remote_device.c index b1276f7e49c8..866950a02965 100644 --- a/drivers/scsi/isci/remote_device.c +++ b/drivers/scsi/isci/remote_device.c @@ -288,8 +288,9 @@ enum sci_status isci_remote_device_terminate_requests( * isci_remote_device_not_ready() - This function is called by the ihost when * the remote device is not ready. We mark the isci device as ready (not * "ready_for_io") and signal the waiting proccess. -* @isci_host: This parameter specifies the isci host object. -* @isci_device: This parameter specifies the remote device +* @ihost: This parameter specifies the isci host object. +* @idev: This parameter specifies the remote device +* @reason: Reason to switch on * * sci_lock is held on entrance to this function. */ @@ -1000,7 +1001,7 @@ static void sci_remote_device_initial_state_enter(struct sci_base_state_machine /** * sci_remote_device_destruct() - free remote node context and destruct - * @remote_device: This parameter specifies the remote device to be destructed. + * @idev: This parameter specifies the remote device to be destructed. * * Remote device objects are a limited resource. As such, they must be * protected. Thus calls to construct and destruct are mutually exclusive and @@ -1236,8 +1237,8 @@ static const struct sci_base_state sci_remote_device_state_table[] = { /** * sci_remote_device_construct() - common construction - * @sci_port: SAS/SATA port through which this device is accessed. - * @sci_dev: remote device to construct + * @iport: SAS/SATA port through which this device is accessed. + * @idev: remote device to construct * * This routine just performs benign initialization and does not * allocate the remote_node_context which is left to @@ -1256,7 +1257,7 @@ static void sci_remote_device_construct(struct isci_port *iport, SCIC_SDS_REMOTE_NODE_CONTEXT_INVALID_INDEX); } -/** +/* * sci_remote_device_da_construct() - construct direct attached device. * * The information (e.g. IAF, Signature FIS, etc.) necessary to build @@ -1294,7 +1295,7 @@ static enum sci_status sci_remote_device_da_construct(struct isci_port *iport, return SCI_SUCCESS; } -/** +/* * sci_remote_device_ea_construct() - construct expander attached device * * Remote node context(s) is/are a global resource allocated by this @@ -1439,7 +1440,7 @@ enum sci_status isci_remote_device_resume_from_abort( * sci_remote_device_start() - This method will start the supplied remote * device. This method enables normal IO requests to flow through to the * remote device. - * @remote_device: This parameter specifies the device to be started. + * @idev: This parameter specifies the device to be started. * @timeout: This parameter specifies the number of milliseconds in which the * start operation should complete. * @@ -1501,10 +1502,11 @@ static enum sci_status isci_remote_device_construct(struct isci_port *iport, } /** + * isci_remote_device_alloc() * This function builds the isci_remote_device when a libsas dev_found message * is received. - * @isci_host: This parameter specifies the isci host object. - * @port: This parameter specifies the isci_port connected to this device. + * @ihost: This parameter specifies the isci host object. + * @iport: This parameter specifies the isci_port connected to this device. * * pointer to new isci_remote_device. */ @@ -1549,8 +1551,8 @@ void isci_remote_device_release(struct kref *kref) /** * isci_remote_device_stop() - This function is called internally to stop the * remote device. - * @isci_host: This parameter specifies the isci host object. - * @isci_device: This parameter specifies the remote device. + * @ihost: This parameter specifies the isci host object. + * @idev: This parameter specifies the remote device. * * The status of the ihost request to stop. */ @@ -1585,8 +1587,7 @@ enum sci_status isci_remote_device_stop(struct isci_host *ihost, struct isci_rem /** * isci_remote_device_gone() - This function is called by libsas when a domain * device is removed. - * @domain_device: This parameter specifies the libsas domain device. - * + * @dev: This parameter specifies the libsas domain device. */ void isci_remote_device_gone(struct domain_device *dev) { @@ -1606,7 +1607,7 @@ void isci_remote_device_gone(struct domain_device *dev) * device is discovered. A remote device object is created and started. the * function then sleeps until the sci core device started message is * received. - * @domain_device: This parameter specifies the libsas domain device. + * @dev: This parameter specifies the libsas domain device. * * status, zero indicates success. */ From a8604e44514d772785764298ccad3c5974fdee78 Mon Sep 17 00:00:00 2001 From: Lee Jones Date: Wed, 17 Mar 2021 09:12:21 +0000 Subject: [PATCH 215/412] scsi: isci: request: Fix doc-rot issue relating to 'ireq' param Fixes the following W=1 kernel build warning(s): drivers/scsi/isci/request.c:496: warning: Function parameter or member 'ireq' not described in 'scu_sata_request_construct_task_context' drivers/scsi/isci/request.c:496: warning: Excess function parameter 'sci_req' description in 'scu_sata_request_construct_task_context' Link: https://lore.kernel.org/r/20210317091230.2912389-28-lee.jones@linaro.org Cc: Artur Paszkiewicz Cc: "James E.J. Bottomley" Cc: "Martin K. Petersen" Cc: linux-scsi@vger.kernel.org Signed-off-by: Lee Jones Signed-off-by: Martin K. Petersen --- drivers/scsi/isci/request.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/scsi/isci/request.c b/drivers/scsi/isci/request.c index 764258f69992..e7c6cb4c1556 100644 --- a/drivers/scsi/isci/request.c +++ b/drivers/scsi/isci/request.c @@ -481,7 +481,7 @@ static void scu_ssp_task_request_construct_task_context(struct isci_request *ire * scu_sata_request_construct_task_context() * This method is will fill in the SCU Task Context for any type of SATA * request. This is called from the various SATA constructors. - * @sci_req: The general IO request object which is to be used in + * @ireq: The general IO request object which is to be used in * constructing the SCU task context. * @task_context: The buffer pointer for the SCU task context which is being * constructed. From 7292a8b039c579a4e7eda880ea8c0be53ac16f43 Mon Sep 17 00:00:00 2001 From: Lee Jones Date: Wed, 17 Mar 2021 09:12:22 +0000 Subject: [PATCH 216/412] scsi: isci: port: Fix a bunch of kernel-doc issues Fixes the following W=1 kernel build warning(s): drivers/scsi/isci/port.c:130: warning: Function parameter or member 'iport' not described in 'sci_port_get_properties' drivers/scsi/isci/port.c:130: warning: Function parameter or member 'prop' not described in 'sci_port_get_properties' drivers/scsi/isci/port.c:130: warning: Excess function parameter 'port' description in 'sci_port_get_properties' drivers/scsi/isci/port.c:130: warning: Excess function parameter 'properties' description in 'sci_port_get_properties' drivers/scsi/isci/port.c:243: warning: Function parameter or member 'isci_phy' not described in 'isci_port_link_down' drivers/scsi/isci/port.c:243: warning: Function parameter or member 'isci_port' not described in 'isci_port_link_down' drivers/scsi/isci/port.c:243: warning: Excess function parameter 'phy' description in 'isci_port_link_down' drivers/scsi/isci/port.c:243: warning: Excess function parameter 'port' description in 'isci_port_link_down' drivers/scsi/isci/port.c:318: warning: Function parameter or member 'isci_port' not described in 'isci_port_hard_reset_complete' drivers/scsi/isci/port.c:318: warning: Excess function parameter 'port' description in 'isci_port_hard_reset_complete' drivers/scsi/isci/port.c:398: warning: Cannot understand * drivers/scsi/isci/port.c:544: warning: Function parameter or member 'iport' not described in 'sci_port_construct_dummy_rnc' drivers/scsi/isci/port.c:544: warning: Excess function parameter 'sci_port' description in 'sci_port_construct_dummy_rnc' drivers/scsi/isci/port.c:692: warning: Function parameter or member 'iport' not described in 'sci_port_general_link_up_handler' drivers/scsi/isci/port.c:692: warning: Function parameter or member 'iphy' not described in 'sci_port_general_link_up_handler' drivers/scsi/isci/port.c:692: warning: Excess function parameter 'sci_port' description in 'sci_port_general_link_up_handler' drivers/scsi/isci/port.c:692: warning: Excess function parameter 'sci_phy' description in 'sci_port_general_link_up_handler' drivers/scsi/isci/port.c:719: warning: wrong kernel-doc identifier on line: drivers/scsi/isci/port.c:756: warning: Function parameter or member 'iport' not described in 'sci_port_link_detected' drivers/scsi/isci/port.c:756: warning: Function parameter or member 'iphy' not described in 'sci_port_link_detected' drivers/scsi/isci/port.c:756: warning: expecting prototype for if the(). Prototype was for sci_port_link_detected() instead drivers/scsi/isci/port.c:821: warning: wrong kernel-doc identifier on line: drivers/scsi/isci/port.c:885: warning: Function parameter or member 'iport' not described in 'sci_port_post_dummy_request' drivers/scsi/isci/port.c:885: warning: Excess function parameter 'sci_port' description in 'sci_port_post_dummy_request' drivers/scsi/isci/port.c:909: warning: Function parameter or member 'iport' not described in 'sci_port_abort_dummy_request' drivers/scsi/isci/port.c:909: warning: expecting prototype for This will alow the hardware to(). Prototype was for sci_port_abort_dummy_request() instead drivers/scsi/isci/port.c:926: warning: Cannot understand * drivers/scsi/isci/port.c:1017: warning: Cannot understand * drivers/scsi/isci/port.c:1199: warning: Function parameter or member 'iport' not described in 'sci_port_add_phy' drivers/scsi/isci/port.c:1199: warning: Function parameter or member 'iphy' not described in 'sci_port_add_phy' drivers/scsi/isci/port.c:1199: warning: Excess function parameter 'sci_port' description in 'sci_port_add_phy' drivers/scsi/isci/port.c:1199: warning: Excess function parameter 'sci_phy' description in 'sci_port_add_phy' drivers/scsi/isci/port.c:1270: warning: Function parameter or member 'iport' not described in 'sci_port_remove_phy' drivers/scsi/isci/port.c:1270: warning: Function parameter or member 'iphy' not described in 'sci_port_remove_phy' drivers/scsi/isci/port.c:1270: warning: Excess function parameter 'sci_port' description in 'sci_port_remove_phy' drivers/scsi/isci/port.c:1270: warning: Excess function parameter 'sci_phy' description in 'sci_port_remove_phy' [mkp: fixed typo alow->allow] Link: https://lore.kernel.org/r/20210317091230.2912389-29-lee.jones@linaro.org Cc: Artur Paszkiewicz Cc: "James E.J. Bottomley" Cc: "Martin K. Petersen" Cc: linux-scsi@vger.kernel.org Signed-off-by: Lee Jones Signed-off-by: Martin K. Petersen --- drivers/scsi/isci/port.c | 60 +++++++++++++++++++++------------------- 1 file changed, 31 insertions(+), 29 deletions(-) diff --git a/drivers/scsi/isci/port.c b/drivers/scsi/isci/port.c index 5a362ba76d63..1609aba1c9c1 100644 --- a/drivers/scsi/isci/port.c +++ b/drivers/scsi/isci/port.c @@ -115,9 +115,9 @@ static u32 sci_port_get_phys(struct isci_port *iport) /** * sci_port_get_properties() - This method simply returns the properties * regarding the port, such as: physical index, protocols, sas address, etc. - * @port: this parameter specifies the port for which to retrieve the physical + * @iport: this parameter specifies the port for which to retrieve the physical * index. - * @properties: This parameter specifies the properties structure into which to + * @prop: This parameter specifies the properties structure into which to * copy the requested information. * * Indicate if the user specified a valid port. SCI_SUCCESS This value is @@ -233,8 +233,8 @@ static void isci_port_link_up(struct isci_host *isci_host, * isci_port_link_down() - This function is called by the sci core when a link * becomes inactive. * @isci_host: This parameter specifies the isci host object. - * @phy: This parameter specifies the isci phy with the active link. - * @port: This parameter specifies the isci port with the active link. + * @isci_phy: This parameter specifies the isci phy with the active link. + * @isci_port: This parameter specifies the isci port with the active link. * */ static void isci_port_link_down(struct isci_host *isci_host, @@ -308,7 +308,7 @@ static void port_state_machine_change(struct isci_port *iport, /** * isci_port_hard_reset_complete() - This function is called by the sci core * when the hard reset complete notification has been received. - * @port: This parameter specifies the sci port with the active link. + * @isci_port: This parameter specifies the sci port with the active link. * @completion_status: This parameter specifies the core status for the reset * process. * @@ -395,9 +395,10 @@ bool sci_port_is_valid_phy_assignment(struct isci_port *iport, u32 phy_index) } /** - * - * @sci_port: This is the port object for which to determine if the phy mask + * sci_port_is_phy_mask_valid() + * @iport: This is the port object for which to determine if the phy mask * can be supported. + * @phy_mask: Phy mask belonging to this port * * This method will return a true value if the port's phy mask can be supported * by the SCU. The following is a list of valid PHY mask configurations for @@ -533,7 +534,7 @@ void sci_port_get_attached_sas_address(struct isci_port *iport, struct sci_sas_a /** * sci_port_construct_dummy_rnc() - create dummy rnc for si workaround * - * @sci_port: logical port on which we need to create the remote node context + * @iport: logical port on which we need to create the remote node context * @rni: remote node index for this remote node context. * * This routine will construct a dummy remote node context data structure @@ -677,8 +678,8 @@ static void sci_port_invalid_link_up(struct isci_port *iport, struct isci_phy *i /** * sci_port_general_link_up_handler - phy can be assigned to port? - * @sci_port: sci_port object for which has a phy that has gone link up. - * @sci_phy: This is the struct isci_phy object that has gone link up. + * @iport: sci_port object for which has a phy that has gone link up. + * @iphy: This is the struct isci_phy object that has gone link up. * @flags: PF_RESUME, PF_NOTIFY to sci_port_activate_phy * * Determine if this phy can be assigned to this port . If the phy is @@ -716,10 +717,11 @@ static void sci_port_general_link_up_handler(struct isci_port *iport, /** + * sci_port_is_wide() * This method returns false if the port only has a single phy object assigned. * If there are no phys or more than one phy then the method will return * true. - * @sci_port: The port for which the wide port condition is to be checked. + * @iport: The port for which the wide port condition is to be checked. * * bool true Is returned if this is a wide ported port. false Is returned if * this is a narrow port. @@ -739,12 +741,13 @@ static bool sci_port_is_wide(struct isci_port *iport) } /** + * sci_port_link_detected() * This method is called by the PHY object when the link is detected. if the * port wants the PHY to continue on to the link up state then the port * layer must return true. If the port object returns false the phy object * must halt its attempt to go link up. - * @sci_port: The port associated with the phy object. - * @sci_phy: The phy object that is trying to go link up. + * @iport: The port associated with the phy object. + * @iphy: The phy object that is trying to go link up. * * true if the phy object can continue to the link up condition. true Is * returned if this phy can continue to the ready state. false Is returned if @@ -817,10 +820,8 @@ done: /* --------------------------------------------------------------------------- */ -/** +/* * This function updates the hardwares VIIT entry for this port. - * - * */ static void sci_port_update_viit_entry(struct isci_port *iport) { @@ -874,7 +875,7 @@ static void sci_port_suspend_port_task_scheduler(struct isci_port *iport) /** * sci_port_post_dummy_request() - post dummy/workaround request - * @sci_port: port to post task + * @iport: port to post task * * Prevent the hardware scheduler from posting new requests to the front * of the scheduler queue causing a starvation problem for currently @@ -899,10 +900,11 @@ static void sci_port_post_dummy_request(struct isci_port *iport) } /** - * This routine will abort the dummy request. This will alow the hardware to + * sci_port_abort_dummy_request() + * This routine will abort the dummy request. This will allow the hardware to * power down parts of the silicon to save power. * - * @sci_port: The port on which the task must be aborted. + * @iport: The port on which the task must be aborted. * */ static void sci_port_abort_dummy_request(struct isci_port *iport) @@ -923,8 +925,8 @@ static void sci_port_abort_dummy_request(struct isci_port *iport) } /** - * - * @sci_port: This is the struct isci_port object to resume. + * sci_port_resume_port_task_scheduler() + * @iport: This is the struct isci_port object to resume. * * This method will resume the port task scheduler for this port object. none */ @@ -1014,8 +1016,8 @@ static void sci_port_invalidate_dummy_remote_node(struct isci_port *iport) } /** - * - * @object: This is the object which is cast to a struct isci_port object. + * sci_port_ready_substate_operational_exit() + * @sm: This is the object which is cast to a struct isci_port object. * * This method will perform the actions required by the struct isci_port on * exiting the SCI_PORT_SUB_OPERATIONAL. This function reports @@ -1186,9 +1188,9 @@ static enum sci_status sci_port_hard_reset(struct isci_port *iport, u32 timeout) } /** - * sci_port_add_phy() - - * @sci_port: This parameter specifies the port in which the phy will be added. - * @sci_phy: This parameter is the phy which is to be added to the port. + * sci_port_add_phy() + * @iport: This parameter specifies the port in which the phy will be added. + * @iphy: This parameter is the phy which is to be added to the port. * * This method will add a PHY to the selected port. This method returns an * enum sci_status. SCI_SUCCESS the phy has been added to the port. Any other @@ -1257,9 +1259,9 @@ enum sci_status sci_port_add_phy(struct isci_port *iport, } /** - * sci_port_remove_phy() - - * @sci_port: This parameter specifies the port in which the phy will be added. - * @sci_phy: This parameter is the phy which is to be added to the port. + * sci_port_remove_phy() + * @iport: This parameter specifies the port in which the phy will be added. + * @iphy: This parameter is the phy which is to be added to the port. * * This method will remove the PHY from the selected PORT. This method returns * an enum sci_status. SCI_SUCCESS the phy has been removed from the port. Any From d2d480f132e8d1c280f85bb3c324cee7d81fdf78 Mon Sep 17 00:00:00 2001 From: Lee Jones Date: Wed, 17 Mar 2021 09:12:23 +0000 Subject: [PATCH 217/412] scsi: isci: remote_node_context: Demote kernel-doc abuse Fixes the following W=1 kernel build warning(s): drivers/scsi/isci/remote_node_context.c:206: warning: Function parameter or member 'rnc' not described in 'sci_remote_node_context_notify_user' drivers/scsi/isci/remote_node_context.c:206: warning: expecting prototype for This method just calls the user callback function and then resets the(). Prototype was for sci_remote_node_context_notify_user() instead Link: https://lore.kernel.org/r/20210317091230.2912389-30-lee.jones@linaro.org Cc: Artur Paszkiewicz Cc: "James E.J. Bottomley" Cc: "Martin K. Petersen" Cc: linux-scsi@vger.kernel.org Signed-off-by: Lee Jones Signed-off-by: Martin K. Petersen --- drivers/scsi/isci/remote_node_context.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/scsi/isci/remote_node_context.c b/drivers/scsi/isci/remote_node_context.c index 7a576b995afa..77ba0291134e 100644 --- a/drivers/scsi/isci/remote_node_context.c +++ b/drivers/scsi/isci/remote_node_context.c @@ -197,7 +197,7 @@ static void sci_remote_node_context_setup_to_destroy( wake_up(&ihost->eventq); } -/** +/* * This method just calls the user callback function and then resets the * callback. */ From 188f513dd22c6b304a3a89c2919a8569ef0a7c36 Mon Sep 17 00:00:00 2001 From: Lee Jones Date: Wed, 17 Mar 2021 09:12:24 +0000 Subject: [PATCH 218/412] scsi: isci: remote_node_table: Provide some missing params and remove others Fixes the following W=1 kernel build warning(s): drivers/scsi/isci/remote_node_table.c:113: warning: Function parameter or member 'group_table_index' not described in 'sci_remote_node_table_clear_group_index' drivers/scsi/isci/remote_node_table.c:113: warning: Excess function parameter 'set_index' description in 'sci_remote_node_table_clear_group_index' drivers/scsi/isci/remote_node_table.c:262: warning: Function parameter or member 'group_index' not described in 'sci_remote_node_table_set_group' drivers/scsi/isci/remote_node_table.c:383: warning: Function parameter or member 'group_table_index' not described in 'sci_remote_node_table_allocate_single_remote_node' drivers/scsi/isci/remote_node_table.c:383: warning: Excess function parameter 'table_index' description in 'sci_remote_node_table_allocate_single_remote_node' drivers/scsi/isci/remote_node_table.c:516: warning: Function parameter or member 'remote_node_index' not described in 'sci_remote_node_table_release_single_remote_node' drivers/scsi/isci/remote_node_table.c:562: warning: Function parameter or member 'remote_node_index' not described in 'sci_remote_node_table_release_triple_remote_node' drivers/scsi/isci/remote_node_table.c:588: warning: Function parameter or member 'remote_node_index' not described in 'sci_remote_node_table_release_remote_node_index' Link: https://lore.kernel.org/r/20210317091230.2912389-31-lee.jones@linaro.org Cc: Artur Paszkiewicz Cc: "James E.J. Bottomley" Cc: "Martin K. Petersen" Cc: linux-scsi@vger.kernel.org Signed-off-by: Lee Jones Signed-off-by: Martin K. Petersen --- drivers/scsi/isci/remote_node_table.c | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/drivers/scsi/isci/remote_node_table.c b/drivers/scsi/isci/remote_node_table.c index 1036ab936626..1bcaf528c1c9 100644 --- a/drivers/scsi/isci/remote_node_table.c +++ b/drivers/scsi/isci/remote_node_table.c @@ -99,7 +99,7 @@ static u32 sci_remote_node_table_get_group_index( * sci_remote_node_table_clear_group_index() * @remote_node_table: This the remote node table in which to clear the * selector. - * @set_index: This is the remote node selector in which the change will be + * @group_table_index: This is the remote node selector in which the change will be * made. * @group_index: This is the bit index in the table to be modified. * @@ -250,9 +250,8 @@ static void sci_remote_node_table_clear_group( remote_node_table->available_remote_nodes[dword_location] = dword_value; } -/** +/* * sci_remote_node_table_set_group() - * @remote_node_table: * * THis method sets an entire remote node group in the remote node table. */ @@ -366,7 +365,7 @@ void sci_remote_node_table_initialize( * sci_remote_node_table_allocate_single_remote_node() * @remote_node_table: The remote node table from which to allocate a * remote node. - * @table_index: The group index that is to be used for the search. + * @group_table_index: The group index that is to be used for the search. * * This method will allocate a single RNi from the remote node table. The * table index will determine from which remote node group table to search. @@ -426,7 +425,7 @@ static u16 sci_remote_node_table_allocate_single_remote_node( * sci_remote_node_table_allocate_triple_remote_node() * @remote_node_table: This is the remote node table from which to allocate the * remote node entries. - * @group_table_index: THis is the group table index which must equal two (2) + * @group_table_index: This is the group table index which must equal two (2) * for this operation. * * This method will allocate three consecutive remote node context entries. If @@ -506,7 +505,7 @@ u16 sci_remote_node_table_allocate_remote_node( * sci_remote_node_table_release_single_remote_node() * @remote_node_table: This is the remote node table from which the remote node * release is to take place. - * + * @remote_node_index: This is the remote node index that is being released. * This method will free a single remote node index back to the remote node * table. This routine will update the remote node groups */ @@ -552,6 +551,7 @@ static void sci_remote_node_table_release_single_remote_node( * sci_remote_node_table_release_triple_remote_node() * @remote_node_table: This is the remote node table to which the remote node * index is to be freed. + * @remote_node_index: This is the remote node index that is being released. * * This method will release a group of three consecutive remote nodes back to * the free remote nodes. @@ -577,6 +577,7 @@ static void sci_remote_node_table_release_triple_remote_node( * to be freed. * @remote_node_count: This is the count of consecutive remote nodes that are * to be freed. + * @remote_node_index: This is the remote node index that is being released. * * This method will release the remote node index back into the remote node * table free pool. From cf0ad7a15ac5a5f5985493c293824459e486192f Mon Sep 17 00:00:00 2001 From: Lee Jones Date: Wed, 17 Mar 2021 09:12:25 +0000 Subject: [PATCH 219/412] scsi: cxlflash: Fix a little doc-rot Fixes the following W=1 kernel build warning(s): drivers/scsi/cxlflash/main.c:1369: warning: Function parameter or member 'hwq' not described in 'process_hrrq' drivers/scsi/cxlflash/main.c:1369: warning: Excess function parameter 'afu' description in 'process_hrrq' drivers/scsi/cxlflash/main.c:2005: warning: Function parameter or member 'index' not described in 'init_mc' drivers/scsi/cxlflash/main.c:3303: warning: Function parameter or member 'lunprov' not described in 'cxlflash_lun_provision' drivers/scsi/cxlflash/main.c:3303: warning: Excess function parameter 'arg' description in 'cxlflash_lun_provision' drivers/scsi/cxlflash/main.c:3397: warning: Function parameter or member 'afu_dbg' not described in 'cxlflash_afu_debug' drivers/scsi/cxlflash/main.c:3397: warning: Excess function parameter 'arg' description in 'cxlflash_afu_debug' Link: https://lore.kernel.org/r/20210317091230.2912389-32-lee.jones@linaro.org Cc: "Manoj N. Kumar" Cc: "Matthew R. Ochs" Cc: Uma Krishnan Cc: "James E.J. Bottomley" Cc: "Martin K. Petersen" Cc: linux-scsi@vger.kernel.org Signed-off-by: Lee Jones Signed-off-by: Martin K. Petersen --- drivers/scsi/cxlflash/main.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/scsi/cxlflash/main.c b/drivers/scsi/cxlflash/main.c index e72440d919d2..dc36531d589e 100644 --- a/drivers/scsi/cxlflash/main.c +++ b/drivers/scsi/cxlflash/main.c @@ -1357,7 +1357,7 @@ cxlflash_sync_err_irq_exit: /** * process_hrrq() - process the read-response queue - * @afu: AFU associated with the host. + * @hwq: HWQ associated with the host. * @doneq: Queue of commands harvested from the RRQ. * @budget: Threshold of RRQ entries to process. * @@ -1997,7 +1997,7 @@ out: /** * init_mc() - create and register as the master context * @cfg: Internal structure associated with the host. - * index: HWQ Index of the master context. + * @index: HWQ Index of the master context. * * Return: 0 on success, -errno on failure */ @@ -3294,7 +3294,7 @@ static char *decode_hioctl(unsigned int cmd) /** * cxlflash_lun_provision() - host LUN provisioning handler * @cfg: Internal structure associated with the host. - * @arg: Kernel copy of userspace ioctl data structure. + * @lunprov: Kernel copy of userspace ioctl data structure. * * Return: 0 on success, -errno on failure */ @@ -3385,7 +3385,7 @@ out: /** * cxlflash_afu_debug() - host AFU debug handler * @cfg: Internal structure associated with the host. - * @arg: Kernel copy of userspace ioctl data structure. + * @afu_dbg: Kernel copy of userspace ioctl data structure. * * For debug requests requiring a data buffer, always provide an aligned * (cache line) buffer to the AFU to appease any alignment requirements. From 32b3edfd28f843e84e7db8ceb32c7a62a35b5ba6 Mon Sep 17 00:00:00 2001 From: Lee Jones Date: Wed, 17 Mar 2021 09:12:26 +0000 Subject: [PATCH 220/412] scsi: cxlflash: Fix a few misnaming issues Fixes the following W=1 kernel build warning(s): drivers/scsi/cxlflash/superpipe.c:38: warning: Function parameter or member 'release' not described in 'marshal_rele_to_resize' drivers/scsi/cxlflash/superpipe.c:38: warning: Excess function parameter 'rele' description in 'marshal_rele_to_resize' drivers/scsi/cxlflash/superpipe.c:51: warning: Function parameter or member 'release' not described in 'marshal_det_to_rele' drivers/scsi/cxlflash/superpipe.c:51: warning: Excess function parameter 'rele' description in 'marshal_det_to_rele' drivers/scsi/cxlflash/superpipe.c:528: warning: expecting prototype for rhte_format1(). Prototype was for rht_format1() instead Link: https://lore.kernel.org/r/20210317091230.2912389-33-lee.jones@linaro.org Cc: "Manoj N. Kumar" Cc: "Matthew R. Ochs" Cc: Uma Krishnan Cc: "James E.J. Bottomley" Cc: "Martin K. Petersen" Cc: linux-scsi@vger.kernel.org Signed-off-by: Lee Jones Signed-off-by: Martin K. Petersen --- drivers/scsi/cxlflash/superpipe.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/scsi/cxlflash/superpipe.c b/drivers/scsi/cxlflash/superpipe.c index 5dddf67dfa24..ee11ec340654 100644 --- a/drivers/scsi/cxlflash/superpipe.c +++ b/drivers/scsi/cxlflash/superpipe.c @@ -30,7 +30,7 @@ struct cxlflash_global global; /** * marshal_rele_to_resize() - translate release to resize structure - * @rele: Source structure from which to translate/copy. + * @release: Source structure from which to translate/copy. * @resize: Destination structure for the translate/copy. */ static void marshal_rele_to_resize(struct dk_cxlflash_release *release, @@ -44,7 +44,7 @@ static void marshal_rele_to_resize(struct dk_cxlflash_release *release, /** * marshal_det_to_rele() - translate detach to release structure * @detach: Destination structure for the translate/copy. - * @rele: Source structure from which to translate/copy. + * @release: Source structure from which to translate/copy. */ static void marshal_det_to_rele(struct dk_cxlflash_detach *detach, struct dk_cxlflash_release *release) @@ -517,7 +517,7 @@ void rhte_checkin(struct ctx_info *ctxi, } /** - * rhte_format1() - populates a RHTE for format 1 + * rht_format1() - populates a RHTE for format 1 * @rhte: RHTE to populate. * @lun_id: LUN ID of LUN associated with RHTE. * @perm: Desired permissions for RHTE. From a690baa47fd171f01ef9ec9f8c4ab89bfffa80c5 Mon Sep 17 00:00:00 2001 From: Lee Jones Date: Wed, 17 Mar 2021 09:12:30 +0000 Subject: [PATCH 221/412] scsi: cxlflash: Fix some misnaming related doc-rot Fixes the following W=1 kernel build warning(s): drivers/scsi/cxlflash/vlun.c:48: warning: Function parameter or member 'release' not described in 'marshal_clone_to_rele' drivers/scsi/cxlflash/vlun.c:48: warning: Excess function parameter 'rele' description in 'marshal_clone_to_rele' drivers/scsi/cxlflash/vlun.c:238: warning: Function parameter or member 'bali' not described in 'validate_alloc' drivers/scsi/cxlflash/vlun.c:238: warning: Excess function parameter 'ba_lun_info' description in 'validate_alloc' drivers/scsi/cxlflash/vlun.c:308: warning: Function parameter or member 'to_clone' not described in 'ba_clone' drivers/scsi/cxlflash/vlun.c:308: warning: Excess function parameter 'to_free' description in 'ba_clone' drivers/scsi/cxlflash/vlun.c:369: warning: Function parameter or member 'lli' not described in 'init_vlun' drivers/scsi/cxlflash/vlun.c:369: warning: Excess function parameter 'lun_info' description in 'init_vlun' Link: https://lore.kernel.org/r/20210317091230.2912389-37-lee.jones@linaro.org Cc: "Manoj N. Kumar" Cc: "Matthew R. Ochs" Cc: Uma Krishnan Cc: "James E.J. Bottomley" Cc: "Martin K. Petersen" Cc: linux-scsi@vger.kernel.org Signed-off-by: Lee Jones Signed-off-by: Martin K. Petersen --- drivers/scsi/cxlflash/vlun.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/scsi/cxlflash/vlun.c b/drivers/scsi/cxlflash/vlun.c index f1406ac77b0d..01917b28cdb6 100644 --- a/drivers/scsi/cxlflash/vlun.c +++ b/drivers/scsi/cxlflash/vlun.c @@ -41,7 +41,7 @@ static void marshal_virt_to_resize(struct dk_cxlflash_uvirtual *virt, /** * marshal_clone_to_rele() - translate clone to release structure * @clone: Source structure from which to translate/copy. - * @rele: Destination structure for the translate/copy. + * @release: Destination structure for the translate/copy. */ static void marshal_clone_to_rele(struct dk_cxlflash_clone *clone, struct dk_cxlflash_release *release) @@ -229,7 +229,7 @@ static u64 ba_alloc(struct ba_lun *ba_lun) /** * validate_alloc() - validates the specified block has been allocated - * @ba_lun_info: LUN info owning the block allocator. + * @bali: LUN info owning the block allocator. * @aun: Block to validate. * * Return: 0 on success, -1 on failure @@ -300,7 +300,7 @@ static int ba_free(struct ba_lun *ba_lun, u64 to_free) /** * ba_clone() - Clone a chunk of the block allocation table * @ba_lun: Block allocator from which to allocate a block. - * @to_free: Block to free. + * @to_clone: Block to clone. * * Return: 0 on success, -1 on failure */ @@ -361,7 +361,7 @@ void cxlflash_ba_terminate(struct ba_lun *ba_lun) /** * init_vlun() - initializes a LUN for virtual use - * @lun_info: LUN information structure that owns the block allocator. + * @lli: LUN information structure that owns the block allocator. * * Return: 0 on success, -errno on failure */ From 841d7df0d416dc9859f2f957c7bb0830125bd537 Mon Sep 17 00:00:00 2001 From: Lee Jones Date: Wed, 17 Mar 2021 09:12:27 +0000 Subject: [PATCH 222/412] scsi: ibmvscsi: Fix a bunch of kernel-doc related issues Fixes the following W=1 kernel build warning(s): drivers/scsi/ibmvscsi/ibmvscsi.c:143: warning: Function parameter or member 'hostdata' not described in 'ibmvscsi_release_crq_queue' drivers/scsi/ibmvscsi/ibmvscsi.c:143: warning: Function parameter or member 'max_requests' not described in 'ibmvscsi_release_crq_queue' drivers/scsi/ibmvscsi/ibmvscsi.c:143: warning: expecting prototype for release_crq_queue(). Prototype was for ibmvscsi_release_crq_queue() instead drivers/scsi/ibmvscsi/ibmvscsi.c:286: warning: expecting prototype for reset_crq_queue(). Prototype was for ibmvscsi_reset_crq_queue() instead drivers/scsi/ibmvscsi/ibmvscsi.c:328: warning: Function parameter or member 'max_requests' not described in 'ibmvscsi_init_crq_queue' drivers/scsi/ibmvscsi/ibmvscsi.c:328: warning: expecting prototype for initialize_crq_queue(). Prototype was for ibmvscsi_init_crq_queue() instead drivers/scsi/ibmvscsi/ibmvscsi.c:414: warning: expecting prototype for reenable_crq_queue(). Prototype was for ibmvscsi_reenable_crq_queue() instead drivers/scsi/ibmvscsi/ibmvscsi.c:536: warning: expecting prototype for ibmvscsi_free(). Prototype was for free_event_struct() instead drivers/scsi/ibmvscsi/ibmvscsi.c:558: warning: expecting prototype for get_evt_struct(). Prototype was for get_event_struct() instead drivers/scsi/ibmvscsi/ibmvscsi.c:587: warning: Function parameter or member 'evt_struct' not described in 'init_event_struct' drivers/scsi/ibmvscsi/ibmvscsi.c:587: warning: Excess function parameter 'evt' description in 'init_event_struct' drivers/scsi/ibmvscsi/ibmvscsi.c:608: warning: Function parameter or member 'cmd' not described in 'set_srp_direction' drivers/scsi/ibmvscsi/ibmvscsi.c:608: warning: Function parameter or member 'srp_cmd' not described in 'set_srp_direction' drivers/scsi/ibmvscsi/ibmvscsi.c:608: warning: Function parameter or member 'numbuf' not described in 'set_srp_direction' drivers/scsi/ibmvscsi/ibmvscsi.c:641: warning: Function parameter or member 'evt_struct' not described in 'unmap_cmd_data' drivers/scsi/ibmvscsi/ibmvscsi.c:683: warning: Function parameter or member 'evt_struct' not described in 'map_sg_data' drivers/scsi/ibmvscsi/ibmvscsi.c:757: warning: Function parameter or member 'evt_struct' not described in 'map_data_for_srp_cmd' drivers/scsi/ibmvscsi/ibmvscsi.c:783: warning: Function parameter or member 'error_code' not described in 'purge_requests' drivers/scsi/ibmvscsi/ibmvscsi.c:846: warning: Function parameter or member 't' not described in 'ibmvscsi_timeout' drivers/scsi/ibmvscsi/ibmvscsi.c:846: warning: Excess function parameter 'evt_struct' description in 'ibmvscsi_timeout' drivers/scsi/ibmvscsi/ibmvscsi.c:1043: warning: Function parameter or member 'cmnd' not described in 'ibmvscsi_queuecommand_lck' drivers/scsi/ibmvscsi/ibmvscsi.c:1043: warning: expecting prototype for ibmvscsi_queue(). Prototype was for ibmvscsi_queuecommand_lck() instead drivers/scsi/ibmvscsi/ibmvscsi.c:1351: warning: expecting prototype for init_host(). Prototype was for enable_fast_fail() instead drivers/scsi/ibmvscsi/ibmvscsi.c:1464: warning: Function parameter or member 'hostdata' not described in 'init_adapter' drivers/scsi/ibmvscsi/ibmvscsi.c:1475: warning: Function parameter or member 'evt_struct' not described in 'sync_completion' drivers/scsi/ibmvscsi/ibmvscsi.c:1488: warning: Function parameter or member 'cmd' not described in 'ibmvscsi_eh_abort_handler' drivers/scsi/ibmvscsi/ibmvscsi.c:1488: warning: expecting prototype for ibmvscsi_abort(). Prototype was for ibmvscsi_eh_abort_handler() instead drivers/scsi/ibmvscsi/ibmvscsi.c:1627: warning: Function parameter or member 'cmd' not described in 'ibmvscsi_eh_device_reset_handler' drivers/scsi/ibmvscsi/ibmvscsi.c:1893: warning: Excess function parameter 'reason' description in 'ibmvscsi_change_queue_depth' drivers/scsi/ibmvscsi/ibmvscsi.c:2221: warning: Function parameter or member 'vdev' not described in 'ibmvscsi_probe' drivers/scsi/ibmvscsi/ibmvscsi.c:2221: warning: Function parameter or member 'id' not described in 'ibmvscsi_probe' drivers/scsi/ibmvscsi/ibmvscsi.c:2221: warning: expecting prototype for Called by bus code for each adapter(). Prototype was for ibmvscsi_probe() instead drivers/scsi/ibmvscsi/ibmvscsi.c:2381: warning: cannot understand function prototype: 'const struct vio_device_id ibmvscsi_device_table[] = ' [mkp: fix checkpatch whitespace warning] Link: https://lore.kernel.org/r/20210317091230.2912389-34-lee.jones@linaro.org Cc: Tyrel Datwyler Cc: Michael Ellerman Cc: Benjamin Herrenschmidt Cc: Paul Mackerras Cc: "James E.J. Bottomley" Cc: "Martin K. Petersen" Cc: Colin DeVilbiss Cc: Santiago Leon Cc: Dave Boutcher Cc: linux-scsi@vger.kernel.org Cc: linuxppc-dev@lists.ozlabs.org Signed-off-by: Lee Jones Signed-off-by: Martin K. Petersen --- drivers/scsi/ibmvscsi/ibmvscsi.c | 70 ++++++++++++++++---------------- 1 file changed, 35 insertions(+), 35 deletions(-) diff --git a/drivers/scsi/ibmvscsi/ibmvscsi.c b/drivers/scsi/ibmvscsi/ibmvscsi.c index 29fcc44be2d5..bef89829ca9b 100644 --- a/drivers/scsi/ibmvscsi/ibmvscsi.c +++ b/drivers/scsi/ibmvscsi/ibmvscsi.c @@ -130,9 +130,10 @@ static irqreturn_t ibmvscsi_handle_event(int irq, void *dev_instance) } /** - * release_crq_queue: - Deallocates data and unregisters CRQ - * @queue: crq_queue to initialize and register - * @host_data: ibmvscsi_host_data of host + * ibmvscsi_release_crq_queue() - Deallocates data and unregisters CRQ + * @queue: crq_queue to initialize and register + * @hostdata: ibmvscsi_host_data of host + * @max_requests: maximum requests (unused) * * Frees irq, deallocates a page for messages, unmaps dma, and unregisters * the crq with the hypervisor. @@ -276,10 +277,9 @@ static void set_adapter_info(struct ibmvscsi_host_data *hostdata) } /** - * reset_crq_queue: - resets a crq after a failure + * ibmvscsi_reset_crq_queue() - resets a crq after a failure * @queue: crq_queue to initialize and register * @hostdata: ibmvscsi_host_data of host - * */ static int ibmvscsi_reset_crq_queue(struct crq_queue *queue, struct ibmvscsi_host_data *hostdata) @@ -314,9 +314,10 @@ static int ibmvscsi_reset_crq_queue(struct crq_queue *queue, } /** - * initialize_crq_queue: - Initializes and registers CRQ with hypervisor - * @queue: crq_queue to initialize and register - * @hostdata: ibmvscsi_host_data of host + * ibmvscsi_init_crq_queue() - Initializes and registers CRQ with hypervisor + * @queue: crq_queue to initialize and register + * @hostdata: ibmvscsi_host_data of host + * @max_requests: maximum requests (unused) * * Allocates a page for messages, maps it for dma, and registers * the crq with the hypervisor. @@ -404,10 +405,9 @@ static int ibmvscsi_init_crq_queue(struct crq_queue *queue, } /** - * reenable_crq_queue: - reenables a crq after + * ibmvscsi_reenable_crq_queue() - reenables a crq after * @queue: crq_queue to initialize and register * @hostdata: ibmvscsi_host_data of host - * */ static int ibmvscsi_reenable_crq_queue(struct crq_queue *queue, struct ibmvscsi_host_data *hostdata) @@ -439,7 +439,7 @@ static int ibmvscsi_reenable_crq_queue(struct crq_queue *queue, * @hostdata: ibmvscsi_host_data who owns the event pool * * Returns zero on success. -*/ + */ static int initialize_event_pool(struct event_pool *pool, int size, struct ibmvscsi_host_data *hostdata) { @@ -478,12 +478,12 @@ static int initialize_event_pool(struct event_pool *pool, } /** - * release_event_pool: - Frees memory of an event pool of a host + * release_event_pool() - Frees memory of an event pool of a host * @pool: event_pool to be released * @hostdata: ibmvscsi_host_data who owns the even pool * * Returns zero on success. -*/ + */ static void release_event_pool(struct event_pool *pool, struct ibmvscsi_host_data *hostdata) { @@ -526,11 +526,10 @@ static int valid_event_struct(struct event_pool *pool, } /** - * ibmvscsi_free-event_struct: - Changes status of event to "free" + * free_event_struct() - Changes status of event to "free" * @pool: event_pool that contains the event * @evt: srp_event_struct to be modified - * -*/ + */ static void free_event_struct(struct event_pool *pool, struct srp_event_struct *evt) { @@ -547,7 +546,7 @@ static void free_event_struct(struct event_pool *pool, } /** - * get_evt_struct: - Gets the next free event in pool + * get_event_struct() - Gets the next free event in pool * @pool: event_pool that contains the events to be searched * * Returns the next event in "free" state, and NULL if none are free. @@ -575,7 +574,7 @@ static struct srp_event_struct *get_event_struct(struct event_pool *pool) /** * init_event_struct: Initialize fields in an event struct that are always * required. - * @evt: The event + * @evt_struct: The event * @done: Routine to call when the event is responded to * @format: SRP or MAD format * @timeout: timeout value set in the CRQ @@ -597,7 +596,7 @@ static void init_event_struct(struct srp_event_struct *evt_struct, * Routines for receiving SCSI responses from the hosting partition */ -/** +/* * set_srp_direction: Set the fields in the srp related to data * direction and number of buffers based on the direction in * the scsi_cmnd and the number of buffers @@ -632,9 +631,9 @@ static void set_srp_direction(struct scsi_cmnd *cmd, /** * unmap_cmd_data: - Unmap data pointed in srp_cmd based on the format * @cmd: srp_cmd whose additional_data member will be unmapped + * @evt_struct: the event * @dev: device for which the memory is mapped - * -*/ + */ static void unmap_cmd_data(struct srp_cmd *cmd, struct srp_event_struct *evt_struct, struct device *dev) @@ -671,6 +670,7 @@ static int map_sg_list(struct scsi_cmnd *cmd, int nseg, /** * map_sg_data: - Maps dma for a scatterlist and initializes descriptor fields * @cmd: struct scsi_cmnd with the scatterlist + * @evt_struct: struct srp_event_struct to map * @srp_cmd: srp_cmd that contains the memory descriptor * @dev: device for which to map dma memory * @@ -745,6 +745,7 @@ static int map_sg_data(struct scsi_cmnd *cmd, /** * map_data_for_srp_cmd: - Calls functions to map data for srp cmds * @cmd: struct scsi_cmnd with the memory to be mapped + * @evt_struct: struct srp_event_struct to map * @srp_cmd: srp_cmd that contains the memory descriptor * @dev: dma device for which to map dma memory * @@ -778,6 +779,7 @@ static int map_data_for_srp_cmd(struct scsi_cmnd *cmd, /** * purge_requests: Our virtual adapter just shut down. purge any sent requests * @hostdata: the adapter + * @error_code: error code to return as the 'result' */ static void purge_requests(struct ibmvscsi_host_data *hostdata, int error_code) { @@ -838,7 +840,7 @@ static void ibmvscsi_reset_host(struct ibmvscsi_host_data *hostdata) /** * ibmvscsi_timeout - Internal command timeout handler - * @evt_struct: struct srp_event_struct that timed out + * @t: struct srp_event_struct that timed out * * Called when an internally generated command times out */ @@ -1034,8 +1036,8 @@ static inline u16 lun_from_dev(struct scsi_device *dev) } /** - * ibmvscsi_queue: - The queuecommand function of the scsi template - * @cmd: struct scsi_cmnd to be executed + * ibmvscsi_queuecommand_lck() - The queuecommand function of the scsi template + * @cmnd: struct scsi_cmnd to be executed * @done: Callback function to be called when cmd is completed */ static int ibmvscsi_queuecommand_lck(struct scsi_cmnd *cmnd, @@ -1342,7 +1344,7 @@ static void fast_fail_rsp(struct srp_event_struct *evt_struct) } /** - * init_host - Start host initialization + * enable_fast_fail() - Start host initialization * @hostdata: ibmvscsi_host_data of host * * Returns zero if successful. @@ -1456,16 +1458,15 @@ static void send_mad_adapter_info(struct ibmvscsi_host_data *hostdata) spin_unlock_irqrestore(hostdata->host->host_lock, flags); }; -/** - * init_adapter: Start virtual adapter initialization sequence - * +/* + * init_adapter() - Start virtual adapter initialization sequence */ static void init_adapter(struct ibmvscsi_host_data *hostdata) { send_mad_adapter_info(hostdata); } -/** +/* * sync_completion: Signal that a synchronous command has completed * Note that after returning from this call, the evt_struct is freed. * the caller waiting on this completion shouldn't touch the evt_struct @@ -1480,8 +1481,8 @@ static void sync_completion(struct srp_event_struct *evt_struct) complete(&evt_struct->comp); } -/** - * ibmvscsi_abort: Abort a command...from scsi host template +/* + * ibmvscsi_eh_abort_handler: Abort a command...from scsi host template * send this over to the server and wait synchronously for the response */ static int ibmvscsi_eh_abort_handler(struct scsi_cmnd *cmd) @@ -1618,7 +1619,7 @@ static int ibmvscsi_eh_abort_handler(struct scsi_cmnd *cmd) return SUCCESS; } -/** +/* * ibmvscsi_eh_device_reset_handler: Reset a single LUN...from scsi host * template send this over to the server and wait synchronously for the * response @@ -1884,7 +1885,6 @@ static int ibmvscsi_slave_configure(struct scsi_device *sdev) * ibmvscsi_change_queue_depth - Change the device's queue depth * @sdev: scsi device struct * @qdepth: depth to set - * @reason: calling context * * Return value: * actual depth set @@ -2214,7 +2214,7 @@ static int ibmvscsi_work(void *data) return 0; } -/** +/* * Called by bus code for each adapter */ static int ibmvscsi_probe(struct vio_dev *vdev, const struct vio_device_id *id) @@ -2376,7 +2376,7 @@ static int ibmvscsi_resume(struct device *dev) return 0; } -/** +/* * ibmvscsi_device_table: Used by vio.c to match devices in the device tree we * support. */ From dd9c772971485d611d790a8d88546f8126de82ea Mon Sep 17 00:00:00 2001 From: Lee Jones Date: Wed, 17 Mar 2021 09:12:28 +0000 Subject: [PATCH 223/412] scsi: ibmvscsi: Fix a bunch of misdocumentation Fixes the following W=1 kernel build warning(s): drivers/scsi/ibmvscsi/ibmvfc.c:331: warning: Function parameter or member 'vhost' not described in 'ibmvfc_get_err_result' drivers/scsi/ibmvscsi/ibmvfc.c:653: warning: Excess function parameter 'job_step' description in 'ibmvfc_del_tgt' drivers/scsi/ibmvscsi/ibmvfc.c:773: warning: Function parameter or member 'queue' not described in 'ibmvfc_init_event_pool' drivers/scsi/ibmvscsi/ibmvfc.c:773: warning: Function parameter or member 'size' not described in 'ibmvfc_init_event_pool' drivers/scsi/ibmvscsi/ibmvfc.c:823: warning: Function parameter or member 'queue' not described in 'ibmvfc_free_event_pool' drivers/scsi/ibmvscsi/ibmvfc.c:1413: warning: Function parameter or member 'vhost' not described in 'ibmvfc_gather_partition_info' drivers/scsi/ibmvscsi/ibmvfc.c:1483: warning: Function parameter or member 'queue' not described in 'ibmvfc_get_event' drivers/scsi/ibmvscsi/ibmvfc.c:1483: warning: Excess function parameter 'vhost' description in 'ibmvfc_get_event' drivers/scsi/ibmvscsi/ibmvfc.c:1630: warning: Function parameter or member 't' not described in 'ibmvfc_timeout' drivers/scsi/ibmvscsi/ibmvfc.c:1630: warning: Excess function parameter 'evt' description in 'ibmvfc_timeout' drivers/scsi/ibmvscsi/ibmvfc.c:1893: warning: Function parameter or member 'shost' not described in 'ibmvfc_queuecommand' drivers/scsi/ibmvscsi/ibmvfc.c:1893: warning: Excess function parameter 'done' description in 'ibmvfc_queuecommand' drivers/scsi/ibmvscsi/ibmvfc.c:2324: warning: Function parameter or member 'rport' not described in 'ibmvfc_match_rport' drivers/scsi/ibmvscsi/ibmvfc.c:2324: warning: Excess function parameter 'device' description in 'ibmvfc_match_rport' drivers/scsi/ibmvscsi/ibmvfc.c:3133: warning: Function parameter or member 'evt_doneq' not described in 'ibmvfc_handle_crq' drivers/scsi/ibmvscsi/ibmvfc.c:3317: warning: Excess function parameter 'reason' description in 'ibmvfc_change_queue_depth' drivers/scsi/ibmvscsi/ibmvfc.c:3390: warning: Function parameter or member 'attr' not described in 'ibmvfc_show_log_level' drivers/scsi/ibmvscsi/ibmvfc.c:3413: warning: Function parameter or member 'attr' not described in 'ibmvfc_store_log_level' drivers/scsi/ibmvscsi/ibmvfc.c:3413: warning: Function parameter or member 'count' not described in 'ibmvfc_store_log_level' drivers/scsi/ibmvscsi/ibmvfc.c:4121: warning: Function parameter or member 'done' not described in '__ibmvfc_tgt_get_implicit_logout_evt' drivers/scsi/ibmvscsi/ibmvfc.c:4438: warning: Function parameter or member 't' not described in 'ibmvfc_adisc_timeout' drivers/scsi/ibmvscsi/ibmvfc.c:4438: warning: Excess function parameter 'tgt' description in 'ibmvfc_adisc_timeout' drivers/scsi/ibmvscsi/ibmvfc.c:4641: warning: Function parameter or member 'target' not described in 'ibmvfc_alloc_target' drivers/scsi/ibmvscsi/ibmvfc.c:4641: warning: Excess function parameter 'scsi_id' description in 'ibmvfc_alloc_target' drivers/scsi/ibmvscsi/ibmvfc.c:5068: warning: Function parameter or member 'evt' not described in 'ibmvfc_npiv_logout_done' drivers/scsi/ibmvscsi/ibmvfc.c:5068: warning: Excess function parameter 'vhost' description in 'ibmvfc_npiv_logout_done' Link: https://lore.kernel.org/r/20210317091230.2912389-35-lee.jones@linaro.org Cc: Tyrel Datwyler Cc: Michael Ellerman Cc: Benjamin Herrenschmidt Cc: Paul Mackerras Cc: "James E.J. Bottomley" Cc: "Martin K. Petersen" Cc: Brian King Cc: linux-scsi@vger.kernel.org Cc: linuxppc-dev@lists.ozlabs.org Signed-off-by: Lee Jones Signed-off-by: Martin K. Petersen --- drivers/scsi/ibmvscsi/ibmvfc.c | 29 ++++++++++++++++++----------- 1 file changed, 18 insertions(+), 11 deletions(-) diff --git a/drivers/scsi/ibmvscsi/ibmvfc.c b/drivers/scsi/ibmvscsi/ibmvfc.c index e5f1ca70faf9..51e94934eb99 100644 --- a/drivers/scsi/ibmvscsi/ibmvfc.c +++ b/drivers/scsi/ibmvscsi/ibmvfc.c @@ -322,6 +322,7 @@ static const char *ibmvfc_get_cmd_error(u16 status, u16 error) /** * ibmvfc_get_err_result - Find the scsi status to return for the fcp response + * @vhost: ibmvfc host struct * @vfc_cmd: ibmvfc command struct * * Return value: @@ -646,8 +647,6 @@ static void ibmvfc_reinit_host(struct ibmvfc_host *vhost) /** * ibmvfc_del_tgt - Schedule cleanup and removal of the target * @tgt: ibmvfc target struct - * @job_step: job step to perform - * **/ static void ibmvfc_del_tgt(struct ibmvfc_target *tgt) { @@ -764,6 +763,8 @@ static int ibmvfc_send_crq_init_complete(struct ibmvfc_host *vhost) /** * ibmvfc_init_event_pool - Allocates and initializes the event pool for a host * @vhost: ibmvfc host who owns the event pool + * @queue: ibmvfc queue struct + * @size: pool size * * Returns zero on success. **/ @@ -816,6 +817,7 @@ static int ibmvfc_init_event_pool(struct ibmvfc_host *vhost, /** * ibmvfc_free_event_pool - Frees memory of the event pool of a host * @vhost: ibmvfc host who owns the event pool + * @queue: ibmvfc queue struct * **/ static void ibmvfc_free_event_pool(struct ibmvfc_host *vhost, @@ -1405,6 +1407,7 @@ static int ibmvfc_issue_fc_host_lip(struct Scsi_Host *shost) /** * ibmvfc_gather_partition_info - Gather info about the LPAR + * @vhost: ibmvfc host struct * * Return value: * none @@ -1475,7 +1478,7 @@ static void ibmvfc_set_login_info(struct ibmvfc_host *vhost) /** * ibmvfc_get_event - Gets the next free event in pool - * @vhost: ibmvfc host struct + * @queue: ibmvfc queue struct * * Returns a free event from the pool. **/ @@ -1622,7 +1625,7 @@ static int ibmvfc_map_sg_data(struct scsi_cmnd *scmd, /** * ibmvfc_timeout - Internal command timeout handler - * @evt: struct ibmvfc_event that timed out + * @t: struct ibmvfc_event that timed out * * Called when an internally generated command times out **/ @@ -1883,8 +1886,8 @@ static struct ibmvfc_cmd *ibmvfc_init_vfc_cmd(struct ibmvfc_event *evt, struct s /** * ibmvfc_queuecommand - The queuecommand function of the scsi template + * @shost: scsi host struct * @cmnd: struct scsi_cmnd to be executed - * @done: Callback function to be called when cmnd is completed * * Returns: * 0 on success / other on failure @@ -2315,7 +2318,7 @@ static int ibmvfc_reset_device(struct scsi_device *sdev, int type, char *desc) /** * ibmvfc_match_rport - Match function for specified remote port * @evt: ibmvfc event struct - * @device: device to match (rport) + * @rport: device to match * * Returns: * 1 if event matches rport / 0 if event does not match rport @@ -3126,8 +3129,9 @@ static void ibmvfc_handle_async(struct ibmvfc_async_crq *crq, * ibmvfc_handle_crq - Handles and frees received events in the CRQ * @crq: Command/Response queue * @vhost: ibmvfc host struct + * @evt_doneq: Event done queue * - **/ +**/ static void ibmvfc_handle_crq(struct ibmvfc_crq *crq, struct ibmvfc_host *vhost, struct list_head *evt_doneq) { @@ -3308,7 +3312,6 @@ static int ibmvfc_slave_configure(struct scsi_device *sdev) * ibmvfc_change_queue_depth - Change the device's queue depth * @sdev: scsi device struct * @qdepth: depth to set - * @reason: calling context * * Return value: * actual depth set @@ -3380,6 +3383,7 @@ static ssize_t ibmvfc_show_host_capabilities(struct device *dev, /** * ibmvfc_show_log_level - Show the adapter's error logging level * @dev: class device struct + * @attr: unused * @buf: buffer * * Return value: @@ -3402,7 +3406,9 @@ static ssize_t ibmvfc_show_log_level(struct device *dev, /** * ibmvfc_store_log_level - Change the adapter's error logging level * @dev: class device struct + * @attr: unused * @buf: buffer + * @count: buffer size * * Return value: * number of bytes printed to buffer @@ -4112,6 +4118,7 @@ static void ibmvfc_tgt_implicit_logout_done(struct ibmvfc_event *evt) /** * __ibmvfc_tgt_get_implicit_logout_evt - Allocate and init an event for implicit logout * @tgt: ibmvfc target struct + * @done: Routine to call when the event is responded to * * Returns: * Allocated and initialized ibmvfc_event struct @@ -4428,7 +4435,7 @@ static void ibmvfc_tgt_adisc_cancel_done(struct ibmvfc_event *evt) /** * ibmvfc_adisc_timeout - Handle an ADISC timeout - * @tgt: ibmvfc target struct + * @t: ibmvfc target struct * * If an ADISC times out, send a cancel. If the cancel times * out, reset the CRQ. When the ADISC comes back as cancelled, @@ -4631,7 +4638,7 @@ static void ibmvfc_tgt_query_target(struct ibmvfc_target *tgt) /** * ibmvfc_alloc_target - Allocate and initialize an ibmvfc target * @vhost: ibmvfc host struct - * @scsi_id: SCSI ID to allocate target for + * @target: Holds SCSI ID to allocate target forand the WWPN * * Returns: * 0 on success / other on failure @@ -5061,7 +5068,7 @@ static void ibmvfc_npiv_login(struct ibmvfc_host *vhost) /** * ibmvfc_npiv_logout_done - Completion handler for NPIV Logout - * @vhost: ibmvfc host struct + * @evt: ibmvfc event struct * **/ static void ibmvfc_npiv_logout_done(struct ibmvfc_event *evt) From cba3ebfc008e89a58788b2055e82c95331aaefa7 Mon Sep 17 00:00:00 2001 From: Lee Jones Date: Wed, 17 Mar 2021 09:12:29 +0000 Subject: [PATCH 224/412] scsi: ibmvscsi_tgt: Remove duplicate section 'NOTE' Fixes the following W=1 kernel build warning(s): drivers/scsi/ibmvscsi_tgt/ibmvscsi_tgt.c:136: warning: duplicate section name 'NOTE' Link: https://lore.kernel.org/r/20210317091230.2912389-36-lee.jones@linaro.org Cc: Michael Cyr Cc: "James E.J. Bottomley" Cc: "Martin K. Petersen" Cc: Dave Boutcher Cc: Santiago Leon Cc: Linda Xie Cc: FUJITA Tomonori Cc: "Nicholas A. Bellinger" Cc: "Bryant G. Ly" Cc: linux-scsi@vger.kernel.org Cc: target-devel@vger.kernel.org Signed-off-by: Lee Jones Signed-off-by: Martin K. Petersen --- drivers/scsi/ibmvscsi_tgt/ibmvscsi_tgt.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/scsi/ibmvscsi_tgt/ibmvscsi_tgt.c b/drivers/scsi/ibmvscsi_tgt/ibmvscsi_tgt.c index cfc54532402c..f3dc60f71af8 100644 --- a/drivers/scsi/ibmvscsi_tgt/ibmvscsi_tgt.c +++ b/drivers/scsi/ibmvscsi_tgt/ibmvscsi_tgt.c @@ -128,10 +128,10 @@ static bool connection_broken(struct scsi_info *vscsi) * This function calls h_free_q then frees the interrupt bit etc. * It must release the lock before doing so because of the time it can take * for h_free_crq in PHYP - * NOTE: the caller must make sure that state and or flags will prevent - * interrupt handler from scheduling work. - * NOTE: anyone calling this function may need to set the CRQ_CLOSED flag - * we can't do it here, because we don't have the lock + * NOTE: * the caller must make sure that state and or flags will prevent + * interrupt handler from scheduling work. + * * anyone calling this function may need to set the CRQ_CLOSED flag + * we can't do it here, because we don't have the lock * * EXECUTION ENVIRONMENT: * Process level From 634b9774d335020e2cd55950a6c1242e7e3bd1e7 Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Sat, 20 Mar 2021 16:23:54 -0700 Subject: [PATCH 225/412] scsi: qla2xxx: Constify struct qla_tgt_func_tmpl Since the target function pointers are not modified at runtime, declare the data structure with the target function pointers const. Link: https://lore.kernel.org/r/20210320232359.941-3-bvanassche@acm.org Cc: Quinn Tran Cc: Mike Christie Reviewed-by: Daniel Wagner Reviewed-by: Himanshu Madhani Reviewed-by: Lee Duncan Signed-off-by: Bart Van Assche Signed-off-by: Martin K. Petersen --- drivers/scsi/qla2xxx/qla_def.h | 2 +- drivers/scsi/qla2xxx/tcm_qla2xxx.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/scsi/qla2xxx/qla_def.h b/drivers/scsi/qla2xxx/qla_def.h index 49b42b430df4..3bdf55bb0833 100644 --- a/drivers/scsi/qla2xxx/qla_def.h +++ b/drivers/scsi/qla2xxx/qla_def.h @@ -3815,7 +3815,7 @@ struct qlt_hw_data { __le32 __iomem *atio_q_in; __le32 __iomem *atio_q_out; - struct qla_tgt_func_tmpl *tgt_ops; + const struct qla_tgt_func_tmpl *tgt_ops; struct qla_tgt_vp_map *tgt_vp_map; int saved_set; diff --git a/drivers/scsi/qla2xxx/tcm_qla2xxx.c b/drivers/scsi/qla2xxx/tcm_qla2xxx.c index 12a2265eb2de..e7d3acf7a98c 100644 --- a/drivers/scsi/qla2xxx/tcm_qla2xxx.c +++ b/drivers/scsi/qla2xxx/tcm_qla2xxx.c @@ -1582,7 +1582,7 @@ static void tcm_qla2xxx_update_sess(struct fc_port *sess, port_id_t s_id, /* * Calls into tcm_qla2xxx used by qla2xxx LLD I/O path. */ -static struct qla_tgt_func_tmpl tcm_qla2xxx_template = { +static const struct qla_tgt_func_tmpl tcm_qla2xxx_template = { .find_cmd_by_tag = tcm_qla2xxx_find_cmd_by_tag, .handle_cmd = tcm_qla2xxx_handle_cmd, .handle_data = tcm_qla2xxx_handle_data, From 37ce4f3531d4a38f3f598fab45d80be5b46aee3c Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Sat, 20 Mar 2021 16:23:55 -0700 Subject: [PATCH 226/412] scsi: qla2xxx: Fix endianness annotations Fix all recently introduced endianness annotation issues. Link: https://lore.kernel.org/r/20210320232359.941-4-bvanassche@acm.org Cc: Quinn Tran Cc: Mike Christie Reviewed-by: Daniel Wagner Reviewed-by: Himanshu Madhani Reviewed-by: Lee Duncan Signed-off-by: Bart Van Assche Signed-off-by: Martin K. Petersen --- drivers/scsi/qla2xxx/qla_def.h | 2 +- drivers/scsi/qla2xxx/qla_iocb.c | 3 ++- drivers/scsi/qla2xxx/qla_isr.c | 2 +- drivers/scsi/qla2xxx/qla_sup.c | 9 +++++---- 4 files changed, 9 insertions(+), 7 deletions(-) diff --git a/drivers/scsi/qla2xxx/qla_def.h b/drivers/scsi/qla2xxx/qla_def.h index 3bdf55bb0833..52ba75591f9a 100644 --- a/drivers/scsi/qla2xxx/qla_def.h +++ b/drivers/scsi/qla2xxx/qla_def.h @@ -1527,7 +1527,7 @@ struct init_sf_cb { * BIT_12 = Remote Write Optimization (1 - Enabled, 0 - Disabled) * BIT 11-0 = Reserved */ - uint16_t flags; + __le16 flags; uint8_t reserved1[32]; uint16_t discard_OHRB_timeout_value; uint16_t remote_write_opt_queue_num; diff --git a/drivers/scsi/qla2xxx/qla_iocb.c b/drivers/scsi/qla2xxx/qla_iocb.c index e765ee4ce162..c89e6d0f3616 100644 --- a/drivers/scsi/qla2xxx/qla_iocb.c +++ b/drivers/scsi/qla2xxx/qla_iocb.c @@ -2379,7 +2379,8 @@ qla24xx_prli_iocb(srb_t *sp, struct logio_entry_24xx *logio) cpu_to_le32(NVME_PRLI_SP_FIRST_BURST); if (sp->vha->flags.nvme2_enabled) { /* Set service parameter BIT_7 for NVME CONF support */ - logio->io_parameter[0] |= NVME_PRLI_SP_CONF; + logio->io_parameter[0] |= + cpu_to_le32(NVME_PRLI_SP_CONF); /* Set service parameter BIT_8 for SLER support */ logio->io_parameter[0] |= cpu_to_le32(NVME_PRLI_SP_SLER); diff --git a/drivers/scsi/qla2xxx/qla_isr.c b/drivers/scsi/qla2xxx/qla_isr.c index 5e188375c871..0938119e8a5f 100644 --- a/drivers/scsi/qla2xxx/qla_isr.c +++ b/drivers/scsi/qla2xxx/qla_isr.c @@ -3440,7 +3440,7 @@ qla24xx_abort_iocb_entry(scsi_qla_host_t *vha, struct req_que *req, return; abt = &sp->u.iocb_cmd; - abt->u.abt.comp_status = le16_to_cpu(pkt->comp_status); + abt->u.abt.comp_status = pkt->comp_status; orig_sp = sp->cmd_sp; /* Need to pass original sp */ if (orig_sp) diff --git a/drivers/scsi/qla2xxx/qla_sup.c b/drivers/scsi/qla2xxx/qla_sup.c index f771fabcba59..060c89237777 100644 --- a/drivers/scsi/qla2xxx/qla_sup.c +++ b/drivers/scsi/qla2xxx/qla_sup.c @@ -2621,10 +2621,11 @@ qla24xx_read_optrom_data(struct scsi_qla_host *vha, void *buf, } static int -qla28xx_extract_sfub_and_verify(struct scsi_qla_host *vha, uint32_t *buf, +qla28xx_extract_sfub_and_verify(struct scsi_qla_host *vha, __le32 *buf, uint32_t len, uint32_t buf_size_without_sfub, uint8_t *sfub_buf) { - uint32_t *p, check_sum = 0; + uint32_t check_sum = 0; + __le32 *p; int i; p = buf + buf_size_without_sfub; @@ -2790,8 +2791,8 @@ qla28xx_write_flash_data(scsi_qla_host_t *vha, uint32_t *dwptr, uint32_t faddr, goto done; } - rval = qla28xx_extract_sfub_and_verify(vha, dwptr, dwords, - buf_size_without_sfub, (uint8_t *)sfub); + rval = qla28xx_extract_sfub_and_verify(vha, (__le32 *)dwptr, + dwords, buf_size_without_sfub, (uint8_t *)sfub); if (rval != QLA_SUCCESS) goto done; From 17603237f789cfb135fd8e01a7edca27a46a6f6e Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Sat, 20 Mar 2021 16:23:56 -0700 Subject: [PATCH 227/412] scsi: qla2xxx: Suppress Coverity complaints about dseg_r* Change dseq_rq and dseg_rsp from scalar structure members into single-element arrays such that Coverity does not complain about the (*cur_dsd)++ statement in append_dsd64(). Link: https://lore.kernel.org/r/20210320232359.941-5-bvanassche@acm.org Cc: Quinn Tran Cc: Mike Christie Reviewed-by: Daniel Wagner Reviewed-by: Himanshu Madhani Reviewed-by: Lee Duncan Signed-off-by: Bart Van Assche Signed-off-by: Martin K. Petersen --- drivers/scsi/qla2xxx/qla_mr.c | 12 ++++++------ drivers/scsi/qla2xxx/qla_mr.h | 8 ++++++-- 2 files changed, 12 insertions(+), 8 deletions(-) diff --git a/drivers/scsi/qla2xxx/qla_mr.c b/drivers/scsi/qla2xxx/qla_mr.c index d488ae95e149..6e920da64863 100644 --- a/drivers/scsi/qla2xxx/qla_mr.c +++ b/drivers/scsi/qla2xxx/qla_mr.c @@ -3266,8 +3266,8 @@ qlafx00_fxdisc_iocb(srb_t *sp, struct fxdisc_entry_fx00 *pfxiocb) fx_iocb.req_xfrcnt = cpu_to_le16(fxio->u.fxiocb.req_len); put_unaligned_le64(fxio->u.fxiocb.req_dma_handle, - &fx_iocb.dseg_rq.address); - fx_iocb.dseg_rq.length = + &fx_iocb.dseg_rq[0].address); + fx_iocb.dseg_rq[0].length = cpu_to_le32(fxio->u.fxiocb.req_len); } @@ -3276,8 +3276,8 @@ qlafx00_fxdisc_iocb(srb_t *sp, struct fxdisc_entry_fx00 *pfxiocb) fx_iocb.rsp_xfrcnt = cpu_to_le16(fxio->u.fxiocb.rsp_len); put_unaligned_le64(fxio->u.fxiocb.rsp_dma_handle, - &fx_iocb.dseg_rsp.address); - fx_iocb.dseg_rsp.length = + &fx_iocb.dseg_rsp[0].address); + fx_iocb.dseg_rsp[0].length = cpu_to_le32(fxio->u.fxiocb.rsp_len); } @@ -3314,7 +3314,7 @@ qlafx00_fxdisc_iocb(srb_t *sp, struct fxdisc_entry_fx00 *pfxiocb) cpu_to_le16(bsg_job->request_payload.sg_cnt); tot_dsds = bsg_job->request_payload.sg_cnt; - cur_dsd = &fx_iocb.dseg_rq; + cur_dsd = &fx_iocb.dseg_rq[0]; avail_dsds = 1; for_each_sg(bsg_job->request_payload.sg_list, sg, tot_dsds, index) { @@ -3369,7 +3369,7 @@ qlafx00_fxdisc_iocb(srb_t *sp, struct fxdisc_entry_fx00 *pfxiocb) fx_iocb.rsp_dsdcnt = cpu_to_le16(bsg_job->reply_payload.sg_cnt); tot_dsds = bsg_job->reply_payload.sg_cnt; - cur_dsd = &fx_iocb.dseg_rsp; + cur_dsd = &fx_iocb.dseg_rsp[0]; avail_dsds = 1; for_each_sg(bsg_job->reply_payload.sg_list, sg, diff --git a/drivers/scsi/qla2xxx/qla_mr.h b/drivers/scsi/qla2xxx/qla_mr.h index 73be8348402a..4f63aff333db 100644 --- a/drivers/scsi/qla2xxx/qla_mr.h +++ b/drivers/scsi/qla2xxx/qla_mr.h @@ -176,8 +176,12 @@ struct fxdisc_entry_fx00 { uint8_t flags; uint8_t reserved_1; - struct dsd64 dseg_rq; - struct dsd64 dseg_rsp; + /* + * Use array size 1 below to prevent that Coverity complains about + * the append_dsd64() calls for the two arrays below. + */ + struct dsd64 dseg_rq[1]; + struct dsd64 dseg_rsp[1]; __le32 dataword; __le32 adapid; From a20821e3f4719458a888af634c10c286365ecd6f Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Sat, 20 Mar 2021 16:23:57 -0700 Subject: [PATCH 228/412] scsi: qla2xxx: Simplify qla8044_minidump_process_control() This patch fixes the following Coverity complaint: CID 177490 (#1 of 1): Unused value (UNUSED_VALUE) assigned_value: Assigning value from opcode & 0xffffff7fU to opcode here, but that stored value is overwritten before it can be used. Link: https://lore.kernel.org/r/20210320232359.941-6-bvanassche@acm.org Cc: Quinn Tran Cc: Mike Christie Reviewed-by: Daniel Wagner Reviewed-by: Himanshu Madhani Reviewed-by: Lee Duncan Signed-off-by: Bart Van Assche Signed-off-by: Martin K. Petersen --- drivers/scsi/qla2xxx/qla_nx2.c | 8 -------- 1 file changed, 8 deletions(-) diff --git a/drivers/scsi/qla2xxx/qla_nx2.c b/drivers/scsi/qla2xxx/qla_nx2.c index 7c413f93d53e..5ceecc9642fc 100644 --- a/drivers/scsi/qla2xxx/qla_nx2.c +++ b/drivers/scsi/qla2xxx/qla_nx2.c @@ -2226,19 +2226,16 @@ qla8044_minidump_process_control(struct scsi_qla_host *vha, if (opcode & QLA82XX_DBG_OPCODE_WR) { qla8044_wr_reg_indirect(vha, crb_addr, crb_entry->value_1); - opcode &= ~QLA82XX_DBG_OPCODE_WR; } if (opcode & QLA82XX_DBG_OPCODE_RW) { qla8044_rd_reg_indirect(vha, crb_addr, &read_value); qla8044_wr_reg_indirect(vha, crb_addr, read_value); - opcode &= ~QLA82XX_DBG_OPCODE_RW; } if (opcode & QLA82XX_DBG_OPCODE_AND) { qla8044_rd_reg_indirect(vha, crb_addr, &read_value); read_value &= crb_entry->value_2; - opcode &= ~QLA82XX_DBG_OPCODE_AND; if (opcode & QLA82XX_DBG_OPCODE_OR) { read_value |= crb_entry->value_3; opcode &= ~QLA82XX_DBG_OPCODE_OR; @@ -2249,7 +2246,6 @@ qla8044_minidump_process_control(struct scsi_qla_host *vha, qla8044_rd_reg_indirect(vha, crb_addr, &read_value); read_value |= crb_entry->value_3; qla8044_wr_reg_indirect(vha, crb_addr, read_value); - opcode &= ~QLA82XX_DBG_OPCODE_OR; } if (opcode & QLA82XX_DBG_OPCODE_POLL) { poll_time = crb_entry->crb_strd.poll_timeout; @@ -2269,7 +2265,6 @@ qla8044_minidump_process_control(struct scsi_qla_host *vha, crb_addr, &read_value); } } while (1); - opcode &= ~QLA82XX_DBG_OPCODE_POLL; } if (opcode & QLA82XX_DBG_OPCODE_RDSTATE) { @@ -2283,7 +2278,6 @@ qla8044_minidump_process_control(struct scsi_qla_host *vha, qla8044_rd_reg_indirect(vha, addr, &read_value); index = crb_entry->crb_ctrl.state_index_v; tmplt_hdr->saved_state_array[index] = read_value; - opcode &= ~QLA82XX_DBG_OPCODE_RDSTATE; } if (opcode & QLA82XX_DBG_OPCODE_WRSTATE) { @@ -2303,7 +2297,6 @@ qla8044_minidump_process_control(struct scsi_qla_host *vha, } qla8044_wr_reg_indirect(vha, addr, read_value); - opcode &= ~QLA82XX_DBG_OPCODE_WRSTATE; } if (opcode & QLA82XX_DBG_OPCODE_MDSTATE) { @@ -2316,7 +2309,6 @@ qla8044_minidump_process_control(struct scsi_qla_host *vha, read_value |= crb_entry->value_3; read_value += crb_entry->value_1; tmplt_hdr->saved_state_array[index] = read_value; - opcode &= ~QLA82XX_DBG_OPCODE_MDSTATE; } crb_addr += crb_entry->crb_strd.addr_stride; } From a2b2cc660822cae08c351c7f6b452bfd1330a4f7 Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Sat, 20 Mar 2021 16:23:58 -0700 Subject: [PATCH 229/412] scsi: qla2xxx: Always check the return value of qla24xx_get_isp_stats() This patch fixes the following Coverity warning: CID 361199 (#1 of 1): Unchecked return value (CHECKED_RETURN) 3. check_return: Calling qla24xx_get_isp_stats without checking return value (as is done elsewhere 4 out of 5 times). Link: https://lore.kernel.org/r/20210320232359.941-7-bvanassche@acm.org Cc: Quinn Tran Cc: Mike Christie Cc: Himanshu Madhani Cc: Daniel Wagner Cc: Lee Duncan Reviewed-by: Daniel Wagner Reviewed-by: Himanshu Madhani Signed-off-by: Bart Van Assche Signed-off-by: Martin K. Petersen --- drivers/scsi/qla2xxx/qla_attr.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/drivers/scsi/qla2xxx/qla_attr.c b/drivers/scsi/qla2xxx/qla_attr.c index 63391c9be05d..3aa9869f6fae 100644 --- a/drivers/scsi/qla2xxx/qla_attr.c +++ b/drivers/scsi/qla2xxx/qla_attr.c @@ -2864,6 +2864,8 @@ qla2x00_reset_host_stats(struct Scsi_Host *shost) vha->qla_stats.jiffies_at_last_reset = get_jiffies_64(); if (IS_FWI2_CAPABLE(ha)) { + int rval; + stats = dma_alloc_coherent(&ha->pdev->dev, sizeof(*stats), &stats_dma, GFP_KERNEL); if (!stats) { @@ -2873,7 +2875,11 @@ qla2x00_reset_host_stats(struct Scsi_Host *shost) } /* reset firmware statistics */ - qla24xx_get_isp_stats(base_vha, stats, stats_dma, BIT_0); + rval = qla24xx_get_isp_stats(base_vha, stats, stats_dma, BIT_0); + if (rval != QLA_SUCCESS) + ql_log(ql_log_warn, vha, 0x70de, + "Resetting ISP statistics failed: rval = %d\n", + rval); dma_free_coherent(&ha->pdev->dev, sizeof(*stats), stats, stats_dma); From e5406d8ad4a1659f4d4d1b39fe203855c4eaef2d Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Sat, 20 Mar 2021 16:23:59 -0700 Subject: [PATCH 230/412] scsi: qla2xxx: Check kzalloc() return value Instead of crashing if kzalloc() fails, make qla2x00_get_host_stats() return -ENOMEM. Link: https://lore.kernel.org/r/20210320232359.941-8-bvanassche@acm.org Fixes: dbf1f53cfd23 ("scsi: qla2xxx: Implementation to get and manage host, target stats and initiator port") Cc: Himanshu Madhani Cc: Saurav Kashyap Cc: Nilesh Javali Cc: Quinn Tran Cc: Mike Christie Cc: Daniel Wagner Cc: Lee Duncan Reviewed-by: Daniel Wagner Reviewed-by: Himanshu Madhani Acked-by: Saurav Kashyap Signed-off-by: Bart Van Assche Signed-off-by: Martin K. Petersen --- drivers/scsi/qla2xxx/qla_bsg.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/drivers/scsi/qla2xxx/qla_bsg.c b/drivers/scsi/qla2xxx/qla_bsg.c index bee8cf9f8123..bc84b2f389f8 100644 --- a/drivers/scsi/qla2xxx/qla_bsg.c +++ b/drivers/scsi/qla2xxx/qla_bsg.c @@ -2583,6 +2583,10 @@ qla2x00_get_host_stats(struct bsg_job *bsg_job) } data = kzalloc(response_len, GFP_KERNEL); + if (!data) { + kfree(req_data); + return -ENOMEM; + } ret = qla2xxx_get_ini_stats(fc_bsg_to_shost(bsg_job), req_data->stat_type, data, response_len); From 973c920811bc60e1e824be0ec355a9b0a7a3d4d5 Mon Sep 17 00:00:00 2001 From: Jiapeng Chong Date: Tue, 9 Mar 2021 11:39:13 +0800 Subject: [PATCH 231/412] scsi: dc395x: Use bitwise instead of arithmetic operator for flags Fix the following coccicheck warnings: ./drivers/scsi/dc395x.c:2921:28-29: WARNING: sum of probable bitmasks, consider |. Link: https://lore.kernel.org/r/1615261153-32647-1-git-send-email-jiapeng.chong@linux.alibaba.com Reported-by: Abaci Robot Signed-off-by: Jiapeng Chong Signed-off-by: Martin K. Petersen --- drivers/scsi/dc395x.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/scsi/dc395x.c b/drivers/scsi/dc395x.c index 5503230006f8..1e9ec4d8c605 100644 --- a/drivers/scsi/dc395x.c +++ b/drivers/scsi/dc395x.c @@ -2918,7 +2918,7 @@ static void disconnect(struct AdapterCtlBlk *acb) } else { if ((srb->state & (SRB_START_ + SRB_MSGOUT)) || !(srb-> - state & (SRB_DISCONNECT + SRB_COMPLETED))) { + state & (SRB_DISCONNECT | SRB_COMPLETED))) { /* * Selection time out * SRB_START_ || SRB_MSGOUT || (!SRB_DISCONNECT && !SRB_COMPLETED) From be20b96b63197eb2e87ffa8973fadb194a16ee80 Mon Sep 17 00:00:00 2001 From: Jiapeng Chong Date: Wed, 10 Mar 2021 12:16:11 +0800 Subject: [PATCH 232/412] scsi: mac53c94: Fix warning comparing pointer to 0 Fix the following coccicheck warning: ./drivers/scsi/mac53c94.c:470:29-30: WARNING comparing pointer to 0. ./drivers/scsi/mac53c94.c:349:12-13: WARNING comparing pointer to 0. Link: https://lore.kernel.org/r/1615349771-81106-1-git-send-email-jiapeng.chong@linux.alibaba.com Reported-by: Abaci Robot Signed-off-by: Jiapeng Chong Signed-off-by: Martin K. Petersen --- drivers/scsi/mac53c94.c | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/drivers/scsi/mac53c94.c b/drivers/scsi/mac53c94.c index 9e989776609b..ec9840d322e5 100644 --- a/drivers/scsi/mac53c94.c +++ b/drivers/scsi/mac53c94.c @@ -346,7 +346,7 @@ static void cmd_done(struct fsc_state *state, int result) struct scsi_cmnd *cmd; cmd = state->current_req; - if (cmd != 0) { + if (cmd) { cmd->result = result; (*cmd->scsi_done)(cmd); state->current_req = NULL; @@ -467,12 +467,13 @@ static int mac53c94_probe(struct macio_dev *mdev, const struct of_device_id *mat dma_cmd_space = kmalloc_array(host->sg_tablesize + 2, sizeof(struct dbdma_cmd), GFP_KERNEL); - if (dma_cmd_space == 0) { - printk(KERN_ERR "mac53c94: couldn't allocate dma " - "command space for %pOF\n", node); + if (!dma_cmd_space) { + printk(KERN_ERR "mac53c94: couldn't allocate dma " + "command space for %pOF\n", node); rc = -ENOMEM; - goto out_free; - } + goto out_free; + } + state->dma_cmds = (struct dbdma_cmd *)DBDMA_ALIGN(dma_cmd_space); memset(state->dma_cmds, 0, (host->sg_tablesize + 1) * sizeof(struct dbdma_cmd)); From adb253433dc8bc8dd569ee03b233fed21afc1dc7 Mon Sep 17 00:00:00 2001 From: Rasmus Villemoes Date: Wed, 10 Mar 2021 23:16:02 +0100 Subject: [PATCH 233/412] scsi: bnx2i: Make bnx2i_process_iscsi_error() simpler and more robust Instead of strcpy'ing into a stack buffer, just let additional_notice point to a string literal living in .rodata. This is better in a few ways: - Smaller .text - instead of gcc compiling the strcpys as a bunch of immediate stores (effectively encoding the string literal in the instruction stream), we only pay the price of storing the literal in .rodata. - Faster, because there's no string copying. - Smaller stack usage (with my compiler, 72 bytes instead of 176 for the sole caller, bnx2i_indicate_kcqe) Moreover, it's currently possible for additional_notice[] to get used uninitialized, so some random stack garbage would be passed to printk() - in the worst case without any '\0' anywhere in those 64 bytes. That could be fixed by initializing additional_notice[0], but the same is achieved here by initializing the new pointer variable to "". Also give the message pointer a similar treatment - there's no point making temporary copies on the stack of those two strings. Link: https://lore.kernel.org/r/20210310221602.2494422-1-linux@rasmusvillemoes.dk Signed-off-by: Rasmus Villemoes Signed-off-by: Martin K. Petersen --- drivers/scsi/bnx2i/bnx2i_hwi.c | 85 ++++++++++++++++------------------ 1 file changed, 41 insertions(+), 44 deletions(-) diff --git a/drivers/scsi/bnx2i/bnx2i_hwi.c b/drivers/scsi/bnx2i/bnx2i_hwi.c index bad396e5c601..43e8a1dafec0 100644 --- a/drivers/scsi/bnx2i/bnx2i_hwi.c +++ b/drivers/scsi/bnx2i/bnx2i_hwi.c @@ -2206,10 +2206,8 @@ static void bnx2i_process_iscsi_error(struct bnx2i_hba *hba, { struct bnx2i_conn *bnx2i_conn; u32 iscsi_cid; - char warn_notice[] = "iscsi_warning"; - char error_notice[] = "iscsi_error"; - char additional_notice[64]; - char *message; + const char *additional_notice = ""; + const char *message; int need_recovery; u64 err_mask64; @@ -2224,133 +2222,132 @@ static void bnx2i_process_iscsi_error(struct bnx2i_hba *hba, if (err_mask64 & iscsi_error_mask) { need_recovery = 0; - message = warn_notice; + message = "iscsi_warning"; } else { need_recovery = 1; - message = error_notice; + message = "iscsi_error"; } switch (iscsi_err->completion_status) { case ISCSI_KCQE_COMPLETION_STATUS_HDR_DIG_ERR: - strcpy(additional_notice, "hdr digest err"); + additional_notice = "hdr digest err"; break; case ISCSI_KCQE_COMPLETION_STATUS_DATA_DIG_ERR: - strcpy(additional_notice, "data digest err"); + additional_notice = "data digest err"; break; case ISCSI_KCQE_COMPLETION_STATUS_PROTOCOL_ERR_OPCODE: - strcpy(additional_notice, "wrong opcode rcvd"); + additional_notice = "wrong opcode rcvd"; break; case ISCSI_KCQE_COMPLETION_STATUS_PROTOCOL_ERR_AHS_LEN: - strcpy(additional_notice, "AHS len > 0 rcvd"); + additional_notice = "AHS len > 0 rcvd"; break; case ISCSI_KCQE_COMPLETION_STATUS_PROTOCOL_ERR_ITT: - strcpy(additional_notice, "invalid ITT rcvd"); + additional_notice = "invalid ITT rcvd"; break; case ISCSI_KCQE_COMPLETION_STATUS_PROTOCOL_ERR_STATSN: - strcpy(additional_notice, "wrong StatSN rcvd"); + additional_notice = "wrong StatSN rcvd"; break; case ISCSI_KCQE_COMPLETION_STATUS_PROTOCOL_ERR_EXP_DATASN: - strcpy(additional_notice, "wrong DataSN rcvd"); + additional_notice = "wrong DataSN rcvd"; break; case ISCSI_KCQE_COMPLETION_STATUS_PROTOCOL_ERR_PEND_R2T: - strcpy(additional_notice, "pend R2T violation"); + additional_notice = "pend R2T violation"; break; case ISCSI_KCQE_COMPLETION_STATUS_PROTOCOL_ERR_O_U_0: - strcpy(additional_notice, "ERL0, UO"); + additional_notice = "ERL0, UO"; break; case ISCSI_KCQE_COMPLETION_STATUS_PROTOCOL_ERR_O_U_1: - strcpy(additional_notice, "ERL0, U1"); + additional_notice = "ERL0, U1"; break; case ISCSI_KCQE_COMPLETION_STATUS_PROTOCOL_ERR_O_U_2: - strcpy(additional_notice, "ERL0, U2"); + additional_notice = "ERL0, U2"; break; case ISCSI_KCQE_COMPLETION_STATUS_PROTOCOL_ERR_O_U_3: - strcpy(additional_notice, "ERL0, U3"); + additional_notice = "ERL0, U3"; break; case ISCSI_KCQE_COMPLETION_STATUS_PROTOCOL_ERR_O_U_4: - strcpy(additional_notice, "ERL0, U4"); + additional_notice = "ERL0, U4"; break; case ISCSI_KCQE_COMPLETION_STATUS_PROTOCOL_ERR_O_U_5: - strcpy(additional_notice, "ERL0, U5"); + additional_notice = "ERL0, U5"; break; case ISCSI_KCQE_COMPLETION_STATUS_PROTOCOL_ERR_O_U_6: - strcpy(additional_notice, "ERL0, U6"); + additional_notice = "ERL0, U6"; break; case ISCSI_KCQE_COMPLETION_STATUS_PROTOCOL_ERR_REMAIN_RCV_LEN: - strcpy(additional_notice, "invalid resi len"); + additional_notice = "invalid resi len"; break; case ISCSI_KCQE_COMPLETION_STATUS_PROTOCOL_ERR_MAX_RCV_PDU_LEN: - strcpy(additional_notice, "MRDSL violation"); + additional_notice = "MRDSL violation"; break; case ISCSI_KCQE_COMPLETION_STATUS_PROTOCOL_ERR_F_BIT_ZERO: - strcpy(additional_notice, "F-bit not set"); + additional_notice = "F-bit not set"; break; case ISCSI_KCQE_COMPLETION_STATUS_PROTOCOL_ERR_TTT_NOT_RSRV: - strcpy(additional_notice, "invalid TTT"); + additional_notice = "invalid TTT"; break; case ISCSI_KCQE_COMPLETION_STATUS_PROTOCOL_ERR_DATASN: - strcpy(additional_notice, "invalid DataSN"); + additional_notice = "invalid DataSN"; break; case ISCSI_KCQE_COMPLETION_STATUS_PROTOCOL_ERR_REMAIN_BURST_LEN: - strcpy(additional_notice, "burst len violation"); + additional_notice = "burst len violation"; break; case ISCSI_KCQE_COMPLETION_STATUS_PROTOCOL_ERR_BUFFER_OFF: - strcpy(additional_notice, "buf offset violation"); + additional_notice = "buf offset violation"; break; case ISCSI_KCQE_COMPLETION_STATUS_PROTOCOL_ERR_LUN: - strcpy(additional_notice, "invalid LUN field"); + additional_notice = "invalid LUN field"; break; case ISCSI_KCQE_COMPLETION_STATUS_PROTOCOL_ERR_R2TSN: - strcpy(additional_notice, "invalid R2TSN field"); + additional_notice = "invalid R2TSN field"; break; #define BNX2I_ERR_DESIRED_DATA_TRNS_LEN_0 \ ISCSI_KCQE_COMPLETION_STATUS_PROTOCOL_ERR_DESIRED_DATA_TRNS_LEN_0 case BNX2I_ERR_DESIRED_DATA_TRNS_LEN_0: - strcpy(additional_notice, "invalid cmd len1"); + additional_notice = "invalid cmd len1"; break; #define BNX2I_ERR_DESIRED_DATA_TRNS_LEN_1 \ ISCSI_KCQE_COMPLETION_STATUS_PROTOCOL_ERR_DESIRED_DATA_TRNS_LEN_1 case BNX2I_ERR_DESIRED_DATA_TRNS_LEN_1: - strcpy(additional_notice, "invalid cmd len2"); + additional_notice = "invalid cmd len2"; break; case ISCSI_KCQE_COMPLETION_STATUS_PROTOCOL_ERR_PEND_R2T_EXCEED: - strcpy(additional_notice, - "pend r2t exceeds MaxOutstandingR2T value"); + additional_notice = "pend r2t exceeds MaxOutstandingR2T value"; break; case ISCSI_KCQE_COMPLETION_STATUS_PROTOCOL_ERR_TTT_IS_RSRV: - strcpy(additional_notice, "TTT is rsvd"); + additional_notice = "TTT is rsvd"; break; case ISCSI_KCQE_COMPLETION_STATUS_PROTOCOL_ERR_MAX_BURST_LEN: - strcpy(additional_notice, "MBL violation"); + additional_notice = "MBL violation"; break; #define BNX2I_ERR_DATA_SEG_LEN_NOT_ZERO \ ISCSI_KCQE_COMPLETION_STATUS_PROTOCOL_ERR_DATA_SEG_LEN_NOT_ZERO case BNX2I_ERR_DATA_SEG_LEN_NOT_ZERO: - strcpy(additional_notice, "data seg len != 0"); + additional_notice = "data seg len != 0"; break; case ISCSI_KCQE_COMPLETION_STATUS_PROTOCOL_ERR_REJECT_PDU_LEN: - strcpy(additional_notice, "reject pdu len error"); + additional_notice = "reject pdu len error"; break; case ISCSI_KCQE_COMPLETION_STATUS_PROTOCOL_ERR_ASYNC_PDU_LEN: - strcpy(additional_notice, "async pdu len error"); + additional_notice = "async pdu len error"; break; case ISCSI_KCQE_COMPLETION_STATUS_PROTOCOL_ERR_NOPIN_PDU_LEN: - strcpy(additional_notice, "nopin pdu len error"); + additional_notice = "nopin pdu len error"; break; #define BNX2_ERR_PEND_R2T_IN_CLEANUP \ ISCSI_KCQE_COMPLETION_STATUS_PROTOCOL_ERR_PEND_R2T_IN_CLEANUP case BNX2_ERR_PEND_R2T_IN_CLEANUP: - strcpy(additional_notice, "pend r2t in cleanup"); + additional_notice = "pend r2t in cleanup"; break; case ISCI_KCQE_COMPLETION_STATUS_TCP_ERROR_IP_FRAGMENT: - strcpy(additional_notice, "IP fragments rcvd"); + additional_notice = "IP fragments rcvd"; break; case ISCI_KCQE_COMPLETION_STATUS_TCP_ERROR_IP_OPTIONS: - strcpy(additional_notice, "IP options error"); + additional_notice = "IP options error"; break; case ISCI_KCQE_COMPLETION_STATUS_TCP_ERROR_URGENT_FLAG: - strcpy(additional_notice, "urgent flag error"); + additional_notice = "urgent flag error"; break; default: printk(KERN_ALERT "iscsi_err - unknown err %x\n", From 7a0c0e6ce130f506449549c5c5fe7902cf83a200 Mon Sep 17 00:00:00 2001 From: Yue Hu Date: Thu, 11 Mar 2021 12:02:10 +0800 Subject: [PATCH 234/412] scsi: ufs: core: Correct status type in ufshcd_vops_pwr_change_notify() The status parameter's type should be enum ufs_notify_change_status. Link: https://lore.kernel.org/r/20210311040210.1315-1-zbestahu@gmail.com Signed-off-by: Yue Hu Signed-off-by: Martin K. Petersen --- drivers/scsi/ufs/ufshcd.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/scsi/ufs/ufshcd.h b/drivers/scsi/ufs/ufshcd.h index cb72695b77ab..5eb66a8debc7 100644 --- a/drivers/scsi/ufs/ufshcd.h +++ b/drivers/scsi/ufs/ufshcd.h @@ -1186,7 +1186,7 @@ static inline int ufshcd_vops_phy_initialization(struct ufs_hba *hba) } static inline int ufshcd_vops_pwr_change_notify(struct ufs_hba *hba, - bool status, + enum ufs_notify_change_status status, struct ufs_pa_layer_attr *dev_max_params, struct ufs_pa_layer_attr *dev_req_params) { From dfd35e1d5934ca5fb6a8f30cdaa24d919c23d7a3 Mon Sep 17 00:00:00 2001 From: Yue Hu Date: Thu, 11 Mar 2021 12:28:33 +0800 Subject: [PATCH 235/412] scsi: ufs: ufs-exynos: Remove pwr_max from parameter list of exynos_ufs_post_pwr_mode() pwr_max is unused, remove it. Link: https://lore.kernel.org/r/20210311042833.1381-1-zbestahu@gmail.com Signed-off-by: Yue Hu Signed-off-by: Martin K. Petersen --- drivers/scsi/ufs/ufs-exynos.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/scsi/ufs/ufs-exynos.c b/drivers/scsi/ufs/ufs-exynos.c index 267943a13a94..70647eacf195 100644 --- a/drivers/scsi/ufs/ufs-exynos.c +++ b/drivers/scsi/ufs/ufs-exynos.c @@ -652,7 +652,6 @@ out: #define PWR_MODE_STR_LEN 64 static int exynos_ufs_post_pwr_mode(struct ufs_hba *hba, - struct ufs_pa_layer_attr *pwr_max, struct ufs_pa_layer_attr *pwr_req) { struct exynos_ufs *ufs = ufshcd_get_variant(hba); @@ -1155,7 +1154,7 @@ static int exynos_ufs_pwr_change_notify(struct ufs_hba *hba, dev_req_params); break; case POST_CHANGE: - ret = exynos_ufs_post_pwr_mode(hba, NULL, dev_req_params); + ret = exynos_ufs_post_pwr_mode(hba, dev_req_params); break; } From 690209d5ebefc8a2f05b8edb1af7769f1bf15440 Mon Sep 17 00:00:00 2001 From: Wang Qing Date: Fri, 12 Mar 2021 10:18:03 +0800 Subject: [PATCH 236/412] scsi: message: fusion: Remove unnecessary cast Fix the following coccicheck warning: WARNING: casting value returned by memory allocation function is useless. Link: https://lore.kernel.org/r/1615515483-777-1-git-send-email-wangqing@vivo.com Signed-off-by: Wang Qing Signed-off-by: Martin K. Petersen --- drivers/message/fusion/mptbase.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/message/fusion/mptbase.c b/drivers/message/fusion/mptbase.c index 549797d0301d..fa9b1223c9de 100644 --- a/drivers/message/fusion/mptbase.c +++ b/drivers/message/fusion/mptbase.c @@ -4974,7 +4974,7 @@ GetLanConfigPages(MPT_ADAPTER *ioc) if (hdr.PageLength > 0) { data_sz = hdr.PageLength * 4; - ppage0_alloc = (LANPage0_t *) pci_alloc_consistent(ioc->pcidev, data_sz, &page0_dma); + ppage0_alloc = pci_alloc_consistent(ioc->pcidev, data_sz, &page0_dma); rc = -ENOMEM; if (ppage0_alloc) { memset((u8 *)ppage0_alloc, 0, data_sz); @@ -5020,7 +5020,7 @@ GetLanConfigPages(MPT_ADAPTER *ioc) data_sz = hdr.PageLength * 4; rc = -ENOMEM; - ppage1_alloc = (LANPage1_t *) pci_alloc_consistent(ioc->pcidev, data_sz, &page1_dma); + ppage1_alloc = pci_alloc_consistent(ioc->pcidev, data_sz, &page1_dma); if (ppage1_alloc) { memset((u8 *)ppage1_alloc, 0, data_sz); cfg.physAddr = page1_dma; @@ -5321,7 +5321,7 @@ GetIoUnitPage2(MPT_ADAPTER *ioc) /* Read the config page */ data_sz = hdr.PageLength * 4; rc = -ENOMEM; - ppage_alloc = (IOUnitPage2_t *) pci_alloc_consistent(ioc->pcidev, data_sz, &page_dma); + ppage_alloc = pci_alloc_consistent(ioc->pcidev, data_sz, &page_dma); if (ppage_alloc) { memset((u8 *)ppage_alloc, 0, data_sz); cfg.physAddr = page_dma; From 3ba9f38ed43de60ca93afd2aaf3d27572e0352eb Mon Sep 17 00:00:00 2001 From: Wang Qing Date: Fri, 12 Mar 2021 10:18:19 +0800 Subject: [PATCH 237/412] scsi: fnic: Remove unnecessary cast Fix the following coccicheck warning: WARNING: casting value returned by memory allocation function is useless. Link: https://lore.kernel.org/r/1615515500-946-1-git-send-email-wangqing@vivo.com Signed-off-by: Wang Qing Signed-off-by: Martin K. Petersen --- drivers/scsi/fnic/fnic_debugfs.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/scsi/fnic/fnic_debugfs.c b/drivers/scsi/fnic/fnic_debugfs.c index 6c049360f136..e7326505cabb 100644 --- a/drivers/scsi/fnic/fnic_debugfs.c +++ b/drivers/scsi/fnic/fnic_debugfs.c @@ -58,8 +58,7 @@ int fnic_debugfs_init(void) fnic_trace_debugfs_root); /* Allocate memory to structure */ - fc_trc_flag = (struct fc_trace_flag_type *) - vmalloc(sizeof(struct fc_trace_flag_type)); + fc_trc_flag = vmalloc(sizeof(struct fc_trace_flag_type)); if (fc_trc_flag) { fc_trc_flag->fc_row_file = 0; From 0d556a21a9dae9ec4e2373825da653447e4eb79c Mon Sep 17 00:00:00 2001 From: Wang Qing Date: Fri, 12 Mar 2021 10:18:53 +0800 Subject: [PATCH 238/412] scsi: ibmvscsi: Remove unnecessary cast Fix the following coccicheck warning: WARNING: casting value returned by memory allocation function is useless. Link: https://lore.kernel.org/r/1615515534-1250-1-git-send-email-wangqing@vivo.com Signed-off-by: Wang Qing Signed-off-by: Martin K. Petersen --- drivers/scsi/ibmvscsi/ibmvscsi.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/scsi/ibmvscsi/ibmvscsi.c b/drivers/scsi/ibmvscsi/ibmvscsi.c index bef89829ca9b..f33f56680c59 100644 --- a/drivers/scsi/ibmvscsi/ibmvscsi.c +++ b/drivers/scsi/ibmvscsi/ibmvscsi.c @@ -717,8 +717,7 @@ static int map_sg_data(struct scsi_cmnd *cmd, /* get indirect table */ if (!evt_struct->ext_list) { - evt_struct->ext_list = (struct srp_direct_buf *) - dma_alloc_coherent(dev, + evt_struct->ext_list = dma_alloc_coherent(dev, SG_ALL * sizeof(struct srp_direct_buf), &evt_struct->ext_list_token, 0); if (!evt_struct->ext_list) { From 3070c72155c5bba86c02f0a8a7493b0c16a9bfdd Mon Sep 17 00:00:00 2001 From: Jiapeng Chong Date: Mon, 15 Mar 2021 11:49:19 +0800 Subject: [PATCH 239/412] scsi: qla1280: Fix warning comparing pointer to 0 Fix the following coccicheck warning: ./drivers/scsi/qla1280.c:3057:37-38: WARNING comparing pointer to 0. Link: https://lore.kernel.org/r/1615780159-94708-1-git-send-email-jiapeng.chong@linux.alibaba.com Reported-by: Abaci Robot Signed-off-by: Jiapeng Chong Signed-off-by: Martin K. Petersen --- drivers/scsi/qla1280.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/scsi/qla1280.c b/drivers/scsi/qla1280.c index 95008811b2d2..8f35174a1f9a 100644 --- a/drivers/scsi/qla1280.c +++ b/drivers/scsi/qla1280.c @@ -3054,7 +3054,7 @@ qla1280_32bit_start_scsi(struct scsi_qla_host *ha, struct srb * sp) /* Check for empty slot in outstanding command list. */ for (cnt = 0; cnt < MAX_OUTSTANDING_COMMANDS && - (ha->outstanding_cmds[cnt] != 0); cnt++) ; + ha->outstanding_cmds[cnt]; cnt++); if (cnt >= MAX_OUTSTANDING_COMMANDS) { status = SCSI_MLQUEUE_HOST_BUSY; From 1630e752fb8340b188c45eed4fe52a9f2a918e27 Mon Sep 17 00:00:00 2001 From: Jiapeng Chong Date: Tue, 16 Mar 2021 15:48:50 +0800 Subject: [PATCH 240/412] scsi: bfa: Fix warning comparing pointer to 0 Fix the following coccicheck warning: ./drivers/scsi/bfa/bfad_bsg.c:3412:29-30: WARNING comparing pointer to 0. Link: https://lore.kernel.org/r/1615880930-120780-1-git-send-email-jiapeng.chong@linux.alibaba.com Reported-by: Abaci Robot Signed-off-by: Jiapeng Chong Signed-off-by: Martin K. Petersen --- drivers/scsi/bfa/bfad_bsg.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/scsi/bfa/bfad_bsg.c b/drivers/scsi/bfa/bfad_bsg.c index fc515424ca88..be8dfbe13e90 100644 --- a/drivers/scsi/bfa/bfad_bsg.c +++ b/drivers/scsi/bfa/bfad_bsg.c @@ -3409,7 +3409,7 @@ bfad_im_bsg_els_ct_request(struct bsg_job *job) drv_fcxp->port = fcs_port->bfad_port; - if (drv_fcxp->port->bfad == 0) + if (!drv_fcxp->port->bfad) drv_fcxp->port->bfad = bfad; /* Fetch the bfa_rport - if nexus needed */ From 0873045f63c474db5c9f816a01fb1a7f64ea21b2 Mon Sep 17 00:00:00 2001 From: Yue Hu Date: Fri, 19 Mar 2021 15:09:16 +0800 Subject: [PATCH 241/412] scsi: ufs: Remove unnecessary NULL checks in ufshcd_find_max_sup_active_icc_level() vcc/vccq/vccq2 have already been NULL checked at this point in ufshcd_find_max_sup_active_icc_level(). Link: https://lore.kernel.org/r/20210319070916.2254-1-zbestahu@gmail.com Signed-off-by: Yue Hu Signed-off-by: Martin K. Petersen --- drivers/scsi/ufs/ufshcd.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/scsi/ufs/ufshcd.c b/drivers/scsi/ufs/ufshcd.c index 95fd813068a7..8ca8ceb9c145 100644 --- a/drivers/scsi/ufs/ufshcd.c +++ b/drivers/scsi/ufs/ufshcd.c @@ -7138,19 +7138,19 @@ static u32 ufshcd_find_max_sup_active_icc_level(struct ufs_hba *hba, goto out; } - if (hba->vreg_info.vcc && hba->vreg_info.vcc->max_uA) + if (hba->vreg_info.vcc->max_uA) icc_level = ufshcd_get_max_icc_level( hba->vreg_info.vcc->max_uA, POWER_DESC_MAX_ACTV_ICC_LVLS - 1, &desc_buf[PWR_DESC_ACTIVE_LVLS_VCC_0]); - if (hba->vreg_info.vccq && hba->vreg_info.vccq->max_uA) + if (hba->vreg_info.vccq->max_uA) icc_level = ufshcd_get_max_icc_level( hba->vreg_info.vccq->max_uA, icc_level, &desc_buf[PWR_DESC_ACTIVE_LVLS_VCCQ_0]); - if (hba->vreg_info.vccq2 && hba->vreg_info.vccq2->max_uA) + if (hba->vreg_info.vccq2->max_uA) icc_level = ufshcd_get_max_icc_level( hba->vreg_info.vccq2->max_uA, icc_level, From a89562e31f01457c4a9529d6271ce21995784aa8 Mon Sep 17 00:00:00 2001 From: Bhaskar Chowdhury Date: Fri, 19 Mar 2021 14:53:11 +0530 Subject: [PATCH 242/412] scsi: csiostor: Fix a typo s/boudaries/boundaries/ Link: https://lore.kernel.org/r/20210319092311.31776-1-unixbhaskar@gmail.com Acked-by: Randy Dunlap Signed-off-by: Bhaskar Chowdhury Signed-off-by: Martin K. Petersen --- drivers/scsi/csiostor/csio_hw_t5.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/scsi/csiostor/csio_hw_t5.c b/drivers/scsi/csiostor/csio_hw_t5.c index 1df8891d3725..86fded97d799 100644 --- a/drivers/scsi/csiostor/csio_hw_t5.c +++ b/drivers/scsi/csiostor/csio_hw_t5.c @@ -244,7 +244,7 @@ csio_t5_edc_read(struct csio_hw *hw, int idx, uint32_t addr, __be32 *data, * * Reads/writes an [almost] arbitrary memory region in the firmware: the * firmware memory address, length and host buffer must be aligned on - * 32-bit boudaries. The memory is transferred as a raw byte sequence + * 32-bit boundaries. The memory is transferred as a raw byte sequence * from/to the firmware's memory. If this memory contains data * structures which contain multi-byte integers, it's the callers * responsibility to perform appropriate byte order conversions. From 206a3afa9482a85e386b8c9e9961489e12027149 Mon Sep 17 00:00:00 2001 From: Bhaskar Chowdhury Date: Mon, 22 Mar 2021 08:51:45 +0530 Subject: [PATCH 243/412] scsi: mpt3sas: Fix a typo s/encloure/enclosure/ Link: https://lore.kernel.org/r/20210322032145.2242520-1-unixbhaskar@gmail.com Acked-by: Randy Dunlap Signed-off-by: Bhaskar Chowdhury Signed-off-by: Martin K. Petersen --- drivers/scsi/mpt3sas/mpt3sas_base.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/scsi/mpt3sas/mpt3sas_base.c b/drivers/scsi/mpt3sas/mpt3sas_base.c index 891722fda7b4..722718233942 100644 --- a/drivers/scsi/mpt3sas/mpt3sas_base.c +++ b/drivers/scsi/mpt3sas/mpt3sas_base.c @@ -5230,7 +5230,7 @@ _base_static_config_pages(struct MPT3SAS_ADAPTER *ioc) * mpt3sas_free_enclosure_list - release memory * @ioc: per adapter object * - * Free memory allocated during encloure add. + * Free memory allocated during enclosure add. */ void mpt3sas_free_enclosure_list(struct MPT3SAS_ADAPTER *ioc) From 5fae809faec6708a86abcbefc8a820de41e43bea Mon Sep 17 00:00:00 2001 From: Bhaskar Chowdhury Date: Mon, 22 Mar 2021 12:05:30 +0530 Subject: [PATCH 244/412] scsi: bnx2fc: Fix a typo s/struture/structure/ Link: https://lore.kernel.org/r/20210322063530.3588282-1-unixbhaskar@gmail.com Acked-by: Randy Dunlap Signed-off-by: Bhaskar Chowdhury Signed-off-by: Martin K. Petersen --- drivers/scsi/bnx2fc/bnx2fc_fcoe.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/scsi/bnx2fc/bnx2fc_fcoe.c b/drivers/scsi/bnx2fc/bnx2fc_fcoe.c index 16bb6d2f98de..8863a74e6c57 100644 --- a/drivers/scsi/bnx2fc/bnx2fc_fcoe.c +++ b/drivers/scsi/bnx2fc/bnx2fc_fcoe.c @@ -1796,7 +1796,7 @@ static void bnx2fc_unbind_pcidev(struct bnx2fc_hba *hba) /** * bnx2fc_ulp_get_stats - cnic callback to populate FCoE stats * - * @handle: transport handle pointing to adapter struture + * @handle: transport handle pointing to adapter structure */ static int bnx2fc_ulp_get_stats(void *handle) { From ae98ddf05fdb92d5ce6d890911b8ee6f5075678b Mon Sep 17 00:00:00 2001 From: Bhaskar Chowdhury Date: Mon, 22 Mar 2021 12:17:24 +0530 Subject: [PATCH 245/412] scsi: scsi_dh: Fix a typo s/infrastruture/infrastructure/ [mkp: combined .c and .h patches] Link: https://lore.kernel.org/r/20210322064724.4108343-1-unixbhaskar@gmail.com Signed-off-by: Bhaskar Chowdhury Signed-off-by: Martin K. Petersen frog --- drivers/scsi/scsi_dh.c | 2 +- include/scsi/scsi_dh.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/scsi/scsi_dh.c b/drivers/scsi/scsi_dh.c index 6f41e4b5a2b8..7b56e00c7df6 100644 --- a/drivers/scsi/scsi_dh.c +++ b/drivers/scsi/scsi_dh.c @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-2.0-or-later /* - * SCSI device handler infrastruture. + * SCSI device handler infrastructure. * * Copyright IBM Corporation, 2007 * Authors: diff --git a/include/scsi/scsi_dh.h b/include/scsi/scsi_dh.h index 2852e470a8ed..a9f782fe732a 100644 --- a/include/scsi/scsi_dh.h +++ b/include/scsi/scsi_dh.h @@ -1,6 +1,6 @@ /* SPDX-License-Identifier: GPL-2.0-or-later */ /* - * Header file for SCSI device handler infrastruture. + * Header file for SCSI device handler infrastructure. * * Modified version of patches posted by Mike Christie * From 89bbf550eafccd120eb9c6c962f6eeda3b8a254c Mon Sep 17 00:00:00 2001 From: wengjianfeng Date: Mon, 22 Mar 2021 15:56:45 +0800 Subject: [PATCH 246/412] scsi: lpfc: Fix a typo Change 'lenth' to 'length'. Link: https://lore.kernel.org/r/20210322075645.25636-1-samirweng1979@163.com Acked-by: Randy Dunlap Signed-off-by: wengjianfeng Signed-off-by: Martin K. Petersen --- drivers/scsi/lpfc/lpfc_debugfs.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/scsi/lpfc/lpfc_debugfs.c b/drivers/scsi/lpfc/lpfc_debugfs.c index c23a535ac89a..355ace295156 100644 --- a/drivers/scsi/lpfc/lpfc_debugfs.c +++ b/drivers/scsi/lpfc/lpfc_debugfs.c @@ -5154,7 +5154,7 @@ error_out: * This routine is to get the available extent information. * * Returns: - * overall lenth of the data read into the internal buffer. + * overall length of the data read into the internal buffer. **/ static int lpfc_idiag_extacc_avail_get(struct lpfc_hba *phba, char *pbuffer, int len) @@ -5205,7 +5205,7 @@ lpfc_idiag_extacc_avail_get(struct lpfc_hba *phba, char *pbuffer, int len) * This routine is to get the allocated extent information. * * Returns: - * overall lenth of the data read into the internal buffer. + * overall length of the data read into the internal buffer. **/ static int lpfc_idiag_extacc_alloc_get(struct lpfc_hba *phba, char *pbuffer, int len) @@ -5277,7 +5277,7 @@ lpfc_idiag_extacc_alloc_get(struct lpfc_hba *phba, char *pbuffer, int len) * This routine is to get the driver extent information. * * Returns: - * overall lenth of the data read into the internal buffer. + * overall length of the data read into the internal buffer. **/ static int lpfc_idiag_extacc_drivr_get(struct lpfc_hba *phba, char *pbuffer, int len) From 9991ca001b9c12e5beb22d00157c766ebb131b5f Mon Sep 17 00:00:00 2001 From: Bhaskar Chowdhury Date: Tue, 23 Mar 2021 02:28:21 +0530 Subject: [PATCH 247/412] scsi: bfa: Fix a typo in two places s/defintions/definitions/ ....two different places. Link: https://lore.kernel.org/r/20210322205821.1449844-1-unixbhaskar@gmail.com Acked-by: Randy Dunlap Signed-off-by: Bhaskar Chowdhury Signed-off-by: Martin K. Petersen --- drivers/scsi/bfa/bfa_fc.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/scsi/bfa/bfa_fc.h b/drivers/scsi/bfa/bfa_fc.h index d536270bbe9f..0314e4b9e1fb 100644 --- a/drivers/scsi/bfa/bfa_fc.h +++ b/drivers/scsi/bfa/bfa_fc.h @@ -1193,7 +1193,7 @@ enum { }; /* - * defintions for CT reason code + * definitions for CT reason code */ enum { CT_RSN_INV_CMD = 0x01, @@ -1240,7 +1240,7 @@ enum { }; /* - * defintions for the explanation code for all servers + * definitions for the explanation code for all servers */ enum { CT_EXP_AUTH_EXCEPTION = 0xF1, From 835b8c16a0e32403b9e07d2b5ea2fa69cefbab6a Mon Sep 17 00:00:00 2001 From: Bhaskar Chowdhury Date: Wed, 24 Mar 2021 11:43:18 +0530 Subject: [PATCH 248/412] scsi: esp_scsi: Trivial typo fixes s/conditon/condition/ s/pecularity/peculiarity/ Link: https://lore.kernel.org/r/20210324061318.5744-1-unixbhaskar@gmail.com Acked-by: Randy Dunlap Signed-off-by: Bhaskar Chowdhury Signed-off-by: Martin K. Petersen --- drivers/scsi/esp_scsi.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/scsi/esp_scsi.c b/drivers/scsi/esp_scsi.c index 007ccef5d1e2..342535ac0570 100644 --- a/drivers/scsi/esp_scsi.c +++ b/drivers/scsi/esp_scsi.c @@ -647,7 +647,7 @@ static void esp_unmap_sense(struct esp *esp, struct esp_cmd_entry *ent) ent->sense_ptr = NULL; } -/* When a contingent allegiance conditon is created, we force feed a +/* When a contingent allegiance condition is created, we force feed a * REQUEST_SENSE command to the device to fetch the sense data. I * tried many other schemes, relying on the scsi error handling layer * to send out the REQUEST_SENSE automatically, but this was difficult @@ -1341,7 +1341,7 @@ static int esp_data_bytes_sent(struct esp *esp, struct esp_cmd_entry *ent, bytes_sent -= esp->send_cmd_residual; /* - * The am53c974 has a DMA 'pecularity'. The doc states: + * The am53c974 has a DMA 'peculiarity'. The doc states: * In some odd byte conditions, one residual byte will * be left in the SCSI FIFO, and the FIFO Flags will * never count to '0 '. When this happens, the residual From f1891f9bbc46f83099cbd0911b81b7225258ac03 Mon Sep 17 00:00:00 2001 From: Bhaskar Chowdhury Date: Wed, 24 Mar 2021 12:18:29 +0530 Subject: [PATCH 249/412] scsi: lpfc: Fix a typo s/conditons/conditions/ Link: https://lore.kernel.org/r/20210324064829.32092-1-unixbhaskar@gmail.com Signed-off-by: Bhaskar Chowdhury Signed-off-by: Martin K. Petersen --- drivers/scsi/lpfc/lpfc_els.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/scsi/lpfc/lpfc_els.c b/drivers/scsi/lpfc/lpfc_els.c index 332e8ab7c60c..a04546eca18f 100644 --- a/drivers/scsi/lpfc/lpfc_els.c +++ b/drivers/scsi/lpfc/lpfc_els.c @@ -1888,7 +1888,7 @@ lpfc_cmpl_els_rrq(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, * ndlp on the vport node list that matches the remote node ID from the * PLOGI response IOCB. If such ndlp does not exist, the PLOGI is simply * ignored and command IOCB released. The PLOGI response IOCB status is - * checked for error conditons. If there is error status reported, PLOGI + * checked for error conditions. If there is error status reported, PLOGI * retry shall be attempted by invoking the lpfc_els_retry() routine. * Otherwise, the lpfc_plogi_confirm_nport() routine shall be invoked on * the ndlp and the NLP_EVT_CMPL_PLOGI state to the Discover State Machine From c2255ece2be2454dff0b549e2ceb234bfe798181 Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Tue, 23 Mar 2021 13:54:23 +0100 Subject: [PATCH 250/412] scsi: pm8001: Avoid -Wrestrict warning On some configurations, gcc warns about overlapping source and destination arguments to snprintf: drivers/scsi/pm8001/pm8001_init.c: In function 'pm8001_request_msix': drivers/scsi/pm8001/pm8001_init.c:977:3: error: 'snprintf' argument 4 may overlap destination object 'pm8001_ha' [-Werror=restrict] 977 | snprintf(drvname, len, "%s-%d", pm8001_ha->name, i); | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ drivers/scsi/pm8001/pm8001_init.c:962:56: note: destination object referenced by 'restrict'-qualified argument 1 was declared here 962 | static u32 pm8001_request_msix(struct pm8001_hba_info *pm8001_ha) | ~~~~~~~~~~~~~~~~~~~~~~~~^~~~~~~~~ I first assumed this was a gcc bug, as that should not happen, but a reduced test case makes it clear that this happens when the loop counter is not bounded by the array size. Help the compiler out by adding an explicit limit here to make the code slightly more robust and avoid the warning. Link: https://godbolt.org/z/6T1qPM Link: https://lore.kernel.org/r/20210323125458.1825564-1-arnd@kernel.org Acked-by: Jack Wang Signed-off-by: Arnd Bergmann Signed-off-by: Martin K. Petersen --- drivers/scsi/pm8001/pm8001_init.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/drivers/scsi/pm8001/pm8001_init.c b/drivers/scsi/pm8001/pm8001_init.c index bbb6b23aa6b1..0f7b3fffb393 100644 --- a/drivers/scsi/pm8001/pm8001_init.c +++ b/drivers/scsi/pm8001/pm8001_init.c @@ -963,6 +963,7 @@ static u32 pm8001_request_msix(struct pm8001_hba_info *pm8001_ha) { u32 i = 0, j = 0; int flag = 0, rc = 0; + int nr_irqs = pm8001_ha->number_of_intr; if (pm8001_ha->chip_id != chip_8001) flag &= ~IRQF_SHARED; @@ -971,7 +972,10 @@ static u32 pm8001_request_msix(struct pm8001_hba_info *pm8001_ha) "pci_enable_msix request number of intr %d\n", pm8001_ha->number_of_intr); - for (i = 0; i < pm8001_ha->number_of_intr; i++) { + if (nr_irqs > ARRAY_SIZE(pm8001_ha->intr_drvname)) + nr_irqs = ARRAY_SIZE(pm8001_ha->intr_drvname); + + for (i = 0; i < nr_irqs; i++) { snprintf(pm8001_ha->intr_drvname[i], sizeof(pm8001_ha->intr_drvname[0]), "%s-%d", pm8001_ha->name, i); From bcafad6c2d520df42c86f28357d639deac15bad7 Mon Sep 17 00:00:00 2001 From: Arun Easi Date: Mon, 29 Mar 2021 01:52:18 -0700 Subject: [PATCH 251/412] scsi: qla2xxx: Fix IOPS drop seen in some adapters Removing the response queue processing in the send path is showing IOPS drop. Add back the process_response_queue() call in the send path. Link: https://lore.kernel.org/r/20210329085229.4367-2-njavali@marvell.com Reviewed-by: Himanshu Madhani Signed-off-by: Arun Easi Signed-off-by: Nilesh Javali Signed-off-by: Martin K. Petersen --- drivers/scsi/qla2xxx/qla_iocb.c | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/drivers/scsi/qla2xxx/qla_iocb.c b/drivers/scsi/qla2xxx/qla_iocb.c index c89e6d0f3616..fea3a92e7724 100644 --- a/drivers/scsi/qla2xxx/qla_iocb.c +++ b/drivers/scsi/qla2xxx/qla_iocb.c @@ -1600,12 +1600,14 @@ qla24xx_start_scsi(srb_t *sp) uint16_t req_cnt; uint16_t tot_dsds; struct req_que *req = NULL; + struct rsp_que *rsp; struct scsi_cmnd *cmd = GET_CMD_SP(sp); struct scsi_qla_host *vha = sp->vha; struct qla_hw_data *ha = vha->hw; /* Setup device pointers. */ req = vha->req; + rsp = req->rsp; /* So we know we haven't pci_map'ed anything yet */ tot_dsds = 0; @@ -1707,6 +1709,11 @@ qla24xx_start_scsi(srb_t *sp) /* Set chip new ring index. */ wrt_reg_dword(req->req_q_in, req->ring_index); + /* Manage unprocessed RIO/ZIO commands in response queue. */ + if (vha->flags.process_response_queue && + rsp->ring_ptr->signature != RESPONSE_PROCESSED) + qla24xx_process_response_queue(vha, rsp); + spin_unlock_irqrestore(&ha->hardware_lock, flags); return QLA_SUCCESS; @@ -1897,6 +1904,11 @@ qla24xx_dif_start_scsi(srb_t *sp) /* Set chip new ring index. */ wrt_reg_dword(req->req_q_in, req->ring_index); + /* Manage unprocessed RIO/ZIO commands in response queue. */ + if (vha->flags.process_response_queue && + rsp->ring_ptr->signature != RESPONSE_PROCESSED) + qla24xx_process_response_queue(vha, rsp); + spin_unlock_irqrestore(&ha->hardware_lock, flags); return QLA_SUCCESS; @@ -1931,6 +1943,7 @@ qla2xxx_start_scsi_mq(srb_t *sp) uint16_t req_cnt; uint16_t tot_dsds; struct req_que *req = NULL; + struct rsp_que *rsp; struct scsi_cmnd *cmd = GET_CMD_SP(sp); struct scsi_qla_host *vha = sp->fcport->vha; struct qla_hw_data *ha = vha->hw; @@ -1941,6 +1954,7 @@ qla2xxx_start_scsi_mq(srb_t *sp) /* Setup qpair pointers */ req = qpair->req; + rsp = qpair->rsp; /* So we know we haven't pci_map'ed anything yet */ tot_dsds = 0; @@ -2041,6 +2055,11 @@ qla2xxx_start_scsi_mq(srb_t *sp) /* Set chip new ring index. */ wrt_reg_dword(req->req_q_in, req->ring_index); + /* Manage unprocessed RIO/ZIO commands in response queue. */ + if (vha->flags.process_response_queue && + rsp->ring_ptr->signature != RESPONSE_PROCESSED) + qla24xx_process_response_queue(vha, rsp); + spin_unlock_irqrestore(&qpair->qp_lock, flags); return QLA_SUCCESS; From a63f4c45414951ad4fbaeb5b744e37ffd137b689 Mon Sep 17 00:00:00 2001 From: Arun Easi Date: Mon, 29 Mar 2021 01:52:19 -0700 Subject: [PATCH 252/412] scsi: qla2xxx: Add H:C:T info in the log message for fc ports The host:channel:scsi_target_id information is helpful in matching an FC port with a SCSI device, so add it. For initiator FC ports, a -1 would be displayed for "target" part. Link: https://lore.kernel.org/r/20210329085229.4367-3-njavali@marvell.com Reviewed-by: Himanshu Madhani Signed-off-by: Arun Easi Signed-off-by: Nilesh Javali Signed-off-by: Martin K. Petersen --- drivers/scsi/qla2xxx/qla_init.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/drivers/scsi/qla2xxx/qla_init.c b/drivers/scsi/qla2xxx/qla_init.c index f01f07116bd3..af237c485389 100644 --- a/drivers/scsi/qla2xxx/qla_init.c +++ b/drivers/scsi/qla2xxx/qla_init.c @@ -5512,13 +5512,14 @@ qla2x00_reg_remote_port(scsi_qla_host_t *vha, fc_port_t *fcport) if (fcport->port_type & FCT_NVME_DISCOVERY) rport_ids.roles |= FC_PORT_ROLE_NVME_DISCOVERY; + fc_remote_port_rolechg(rport, rport_ids.roles); + ql_dbg(ql_dbg_disc, vha, 0x20ee, - "%s %8phN. rport %p is %s mode\n", - __func__, fcport->port_name, rport, + "%s: %8phN. rport %ld:0:%d (%p) is %s mode\n", + __func__, fcport->port_name, vha->host_no, + rport->scsi_target_id, rport, (fcport->port_type == FCT_TARGET) ? "tgt" : ((fcport->port_type & FCT_NVME) ? "nvme" : "ini")); - - fc_remote_port_rolechg(rport, rport_ids.roles); } /* From c358a3d92b32be89ea1c44fe75721448c0a0fec1 Mon Sep 17 00:00:00 2001 From: Quinn Tran Date: Mon, 29 Mar 2021 01:52:20 -0700 Subject: [PATCH 253/412] scsi: qla2xxx: Fix stuck session Session was stuck due to explicit logout to target timing out. The target was in an unresponsive state. This timeout induced an error to the GNL command from moving forward. Link: https://lore.kernel.org/r/20210329085229.4367-4-njavali@marvell.com Tested-by: Laurence Oberman Signed-off-by: Quinn Tran Signed-off-by: Nilesh Javali Signed-off-by: Martin K. Petersen --- drivers/scsi/qla2xxx/qla_init.c | 1 + drivers/scsi/qla2xxx/qla_target.c | 7 ++++++- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/drivers/scsi/qla2xxx/qla_init.c b/drivers/scsi/qla2xxx/qla_init.c index af237c485389..f6dc8166e7ba 100644 --- a/drivers/scsi/qla2xxx/qla_init.c +++ b/drivers/scsi/qla2xxx/qla_init.c @@ -718,6 +718,7 @@ static void qla24xx_handle_gnl_done_event(scsi_qla_host_t *vha, ql_dbg(ql_dbg_disc, vha, 0x20e0, "%s %8phC login gen changed\n", __func__, fcport->port_name); + set_bit(RELOGIN_NEEDED, &vha->dpc_flags); return; } diff --git a/drivers/scsi/qla2xxx/qla_target.c b/drivers/scsi/qla2xxx/qla_target.c index 67c6a2710360..7a2826149364 100644 --- a/drivers/scsi/qla2xxx/qla_target.c +++ b/drivers/scsi/qla2xxx/qla_target.c @@ -1029,7 +1029,12 @@ void qlt_free_session_done(struct work_struct *work) } msleep(100); cnt++; - if (cnt > 200) + /* + * Driver timeout is set to 22 Sec, update count value to loop + * long enough for log-out to complete before advancing. Otherwise, + * straddling logout can interfere with re-login attempt. + */ + if (cnt > 230) break; } From 5777fef788a59f5ac9ab6661988a95a045fc0574 Mon Sep 17 00:00:00 2001 From: Quinn Tran Date: Mon, 29 Mar 2021 01:52:21 -0700 Subject: [PATCH 254/412] scsi: qla2xxx: Consolidate zio threshold setting for both FCP & NVMe Consolidate zio threshold setting for both FCP & NVMe to prevent one protocol from clobbering the setting of the other protocol. Link: https://lore.kernel.org/r/20210329085229.4367-5-njavali@marvell.com Reviewed-by: Himanshu Madhani Signed-off-by: Quinn Tran Signed-off-by: Nilesh Javali Signed-off-by: Martin K. Petersen --- drivers/scsi/qla2xxx/qla_def.h | 1 - drivers/scsi/qla2xxx/qla_os.c | 36 ++++++++++++++-------------------- 2 files changed, 15 insertions(+), 22 deletions(-) diff --git a/drivers/scsi/qla2xxx/qla_def.h b/drivers/scsi/qla2xxx/qla_def.h index 52ba75591f9a..ca7cebae1d78 100644 --- a/drivers/scsi/qla2xxx/qla_def.h +++ b/drivers/scsi/qla2xxx/qla_def.h @@ -4727,7 +4727,6 @@ typedef struct scsi_qla_host { #define FX00_CRITEMP_RECOVERY 25 #define FX00_HOST_INFO_RESEND 26 #define QPAIR_ONLINE_CHECK_NEEDED 27 -#define SET_NVME_ZIO_THRESHOLD_NEEDED 28 #define DETECT_SFP_CHANGE 29 #define N2N_LOGIN_NEEDED 30 #define IOCB_WORK_ACTIVE 31 diff --git a/drivers/scsi/qla2xxx/qla_os.c b/drivers/scsi/qla2xxx/qla_os.c index ac5e9548b757..eb5fcb3a37ec 100644 --- a/drivers/scsi/qla2xxx/qla_os.c +++ b/drivers/scsi/qla2xxx/qla_os.c @@ -6968,26 +6968,21 @@ intr_on_check: mutex_unlock(&ha->mq_lock); } - if (test_and_clear_bit(SET_NVME_ZIO_THRESHOLD_NEEDED, - &base_vha->dpc_flags)) { - ql_log(ql_log_info, base_vha, 0xffffff, - "nvme: SET ZIO Activity exchange threshold to %d.\n", - ha->nvme_last_rptd_aen); - if (qla27xx_set_zio_threshold(base_vha, - ha->nvme_last_rptd_aen)) { - ql_log(ql_log_info, base_vha, 0xffffff, - "nvme: Unable to SET ZIO Activity exchange threshold to %d.\n", - ha->nvme_last_rptd_aen); - } - } - if (test_and_clear_bit(SET_ZIO_THRESHOLD_NEEDED, - &base_vha->dpc_flags)) { + &base_vha->dpc_flags)) { + u16 threshold = ha->nvme_last_rptd_aen + ha->last_zio_threshold; + + if (threshold > ha->orig_fw_xcb_count) + threshold = ha->orig_fw_xcb_count; + ql_log(ql_log_info, base_vha, 0xffffff, - "SET ZIO Activity exchange threshold to %d.\n", - ha->last_zio_threshold); - qla27xx_set_zio_threshold(base_vha, - ha->last_zio_threshold); + "SET ZIO Activity exchange threshold to %d.\n", + threshold); + if (qla27xx_set_zio_threshold(base_vha, threshold)) { + ql_log(ql_log_info, base_vha, 0xffffff, + "Unable to SET ZIO Activity exchange threshold to %d.\n", + threshold); + } } if (!IS_QLAFX00(ha)) @@ -7217,14 +7212,13 @@ qla2x00_timer(struct timer_list *t) index = atomic_read(&ha->nvme_active_aen_cnt); if (!vha->vp_idx && (index != ha->nvme_last_rptd_aen) && - (index >= DEFAULT_ZIO_THRESHOLD) && ha->zio_mode == QLA_ZIO_MODE_6 && !ha->flags.host_shutting_down) { + ha->nvme_last_rptd_aen = atomic_read(&ha->nvme_active_aen_cnt); ql_log(ql_log_info, vha, 0x3002, "nvme: Sched: Set ZIO exchange threshold to %d.\n", ha->nvme_last_rptd_aen); - ha->nvme_last_rptd_aen = atomic_read(&ha->nvme_active_aen_cnt); - set_bit(SET_NVME_ZIO_THRESHOLD_NEEDED, &vha->dpc_flags); + set_bit(SET_ZIO_THRESHOLD_NEEDED, &vha->dpc_flags); start_dpc++; } From 2ce35c0821afc2acd5ee1c3f60d149f8b2520ce8 Mon Sep 17 00:00:00 2001 From: Quinn Tran Date: Mon, 29 Mar 2021 01:52:22 -0700 Subject: [PATCH 255/412] scsi: qla2xxx: Fix use after free in bsg On bsg command completion, bsg_job_done() was called while qla driver continued to access the bsg_job buffer. bsg_job_done() would free up resources that ended up being reused by other task while the driver continued to access the buffers. As a result, driver was reading garbage data. localhost kernel: BUG: KASAN: use-after-free in sg_next+0x64/0x80 localhost kernel: Read of size 8 at addr ffff8883228a3330 by task swapper/26/0 localhost kernel: localhost kernel: CPU: 26 PID: 0 Comm: swapper/26 Kdump: loaded Tainted: G OE --------- - - 4.18.0-193.el8.x86_64+debug #1 localhost kernel: Hardware name: HP ProLiant DL360 Gen9/ProLiant DL360 Gen9, BIOS P89 08/12/2016 localhost kernel: Call Trace: localhost kernel: localhost kernel: dump_stack+0x9a/0xf0 localhost kernel: print_address_description.cold.3+0x9/0x23b localhost kernel: kasan_report.cold.4+0x65/0x95 localhost kernel: debug_dma_unmap_sg.part.12+0x10d/0x2d0 localhost kernel: qla2x00_bsg_sp_free+0xaf6/0x1010 [qla2xxx] Link: https://lore.kernel.org/r/20210329085229.4367-6-njavali@marvell.com Reviewed-by: Himanshu Madhani Signed-off-by: Quinn Tran Signed-off-by: Saurav Kashyap Signed-off-by: Nilesh Javali Signed-off-by: Martin K. Petersen --- drivers/scsi/qla2xxx/qla_bsg.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/scsi/qla2xxx/qla_bsg.c b/drivers/scsi/qla2xxx/qla_bsg.c index bc84b2f389f8..aef2f7cc89d3 100644 --- a/drivers/scsi/qla2xxx/qla_bsg.c +++ b/drivers/scsi/qla2xxx/qla_bsg.c @@ -25,10 +25,11 @@ void qla2x00_bsg_job_done(srb_t *sp, int res) struct bsg_job *bsg_job = sp->u.bsg_job; struct fc_bsg_reply *bsg_reply = bsg_job->reply; + sp->free(sp); + bsg_reply->result = res; bsg_job_done(bsg_job, bsg_reply->result, bsg_reply->reply_payload_rcv_len); - sp->free(sp); } void qla2x00_bsg_sp_free(srb_t *sp) From 6641df81ab799f28a5d564f860233dd26cca0d93 Mon Sep 17 00:00:00 2001 From: Arun Easi Date: Mon, 29 Mar 2021 01:52:23 -0700 Subject: [PATCH 256/412] scsi: qla2xxx: Fix crash in qla2xxx_mqueuecommand() RIP: 0010:kmem_cache_free+0xfa/0x1b0 Call Trace: qla2xxx_mqueuecommand+0x2b5/0x2c0 [qla2xxx] scsi_queue_rq+0x5e2/0xa40 __blk_mq_try_issue_directly+0x128/0x1d0 blk_mq_request_issue_directly+0x4e/0xb0 Fix incorrect call to free srb in qla2xxx_mqueuecommand(), as srb is now allocated by upper layers. This fixes smatch warning of srb unintended free. Link: https://lore.kernel.org/r/20210329085229.4367-7-njavali@marvell.com Fixes: af2a0c51b120 ("scsi: qla2xxx: Fix SRB leak on switch command timeout") Cc: stable@vger.kernel.org # 5.5 Reported-by: Laurence Oberman Reported-by: Dan Carpenter Reviewed-by: Himanshu Madhani Signed-off-by: Arun Easi Signed-off-by: Nilesh Javali Signed-off-by: Martin K. Petersen --- drivers/scsi/qla2xxx/qla_os.c | 7 ------- 1 file changed, 7 deletions(-) diff --git a/drivers/scsi/qla2xxx/qla_os.c b/drivers/scsi/qla2xxx/qla_os.c index eb5fcb3a37ec..cb4155f8fd44 100644 --- a/drivers/scsi/qla2xxx/qla_os.c +++ b/drivers/scsi/qla2xxx/qla_os.c @@ -1013,8 +1013,6 @@ qla2xxx_mqueuecommand(struct Scsi_Host *host, struct scsi_cmnd *cmd, if (rval != QLA_SUCCESS) { ql_dbg(ql_dbg_io + ql_dbg_verbose, vha, 0x3078, "Start scsi failed rval=%d for cmd=%p.\n", rval, cmd); - if (rval == QLA_INTERFACE_ERROR) - goto qc24_free_sp_fail_command; goto qc24_host_busy_free_sp; } @@ -1026,11 +1024,6 @@ qc24_host_busy_free_sp: qc24_target_busy: return SCSI_MLQUEUE_TARGET_BUSY; -qc24_free_sp_fail_command: - sp->free(sp); - CMD_SP(cmd) = NULL; - qla2xxx_rel_qpair_sp(sp->qpair, sp); - qc24_fail_command: cmd->scsi_done(cmd); From 610d027b1e6372ffe3e85e8e095a562e920fd5cd Mon Sep 17 00:00:00 2001 From: Quinn Tran Date: Mon, 29 Mar 2021 01:52:24 -0700 Subject: [PATCH 257/412] scsi: qla2xxx: Fix RISC RESET completion polling After RISC RESET, the poll time for completion is too short. Fix the completion polling time. Link: https://lore.kernel.org/r/20210329085229.4367-8-njavali@marvell.com Tested-by: Laurence Oberman Reviewed-by: Himanshu Madhani Signed-off-by: Quinn Tran Signed-off-by: Nilesh Javali Signed-off-by: Martin K. Petersen --- drivers/scsi/qla2xxx/qla_init.c | 65 ++++++++++++++++++++++++++++++--- 1 file changed, 59 insertions(+), 6 deletions(-) diff --git a/drivers/scsi/qla2xxx/qla_init.c b/drivers/scsi/qla2xxx/qla_init.c index f6dc8166e7ba..19681d3c5b7a 100644 --- a/drivers/scsi/qla2xxx/qla_init.c +++ b/drivers/scsi/qla2xxx/qla_init.c @@ -2767,6 +2767,49 @@ qla81xx_reset_mpi(scsi_qla_host_t *vha) return qla81xx_write_mpi_register(vha, mb); } +static int +qla_chk_risc_recovery(scsi_qla_host_t *vha) +{ + struct qla_hw_data *ha = vha->hw; + struct device_reg_24xx __iomem *reg = &ha->iobase->isp24; + __le16 __iomem *mbptr = ®->mailbox0; + int i; + u16 mb[32]; + int rc = QLA_SUCCESS; + + if (!IS_QLA27XX(ha) && !IS_QLA28XX(ha)) + return rc; + + /* this check is only valid after RISC reset */ + mb[0] = rd_reg_word(mbptr); + mbptr++; + if (mb[0] == 0xf) { + rc = QLA_FUNCTION_FAILED; + + for (i = 1; i < 32; i++) { + mb[i] = rd_reg_word(mbptr); + mbptr++; + } + + ql_log(ql_log_warn, vha, 0x1015, + "RISC reset failed. mb[0-7] %04xh %04xh %04xh %04xh %04xh %04xh %04xh %04xh\n", + mb[0], mb[1], mb[2], mb[3], mb[4], mb[5], mb[6], mb[7]); + ql_log(ql_log_warn, vha, 0x1015, + "RISC reset failed. mb[8-15] %04xh %04xh %04xh %04xh %04xh %04xh %04xh %04xh\n", + mb[8], mb[9], mb[10], mb[11], mb[12], mb[13], mb[14], + mb[15]); + ql_log(ql_log_warn, vha, 0x1015, + "RISC reset failed. mb[16-23] %04xh %04xh %04xh %04xh %04xh %04xh %04xh %04xh\n", + mb[16], mb[17], mb[18], mb[19], mb[20], mb[21], mb[22], + mb[23]); + ql_log(ql_log_warn, vha, 0x1015, + "RISC reset failed. mb[24-31] %04xh %04xh %04xh %04xh %04xh %04xh %04xh %04xh\n", + mb[24], mb[25], mb[26], mb[27], mb[28], mb[29], mb[30], + mb[31]); + } + return rc; +} + /** * qla24xx_reset_risc() - Perform full reset of ISP24xx RISC. * @vha: HA context @@ -2783,6 +2826,7 @@ qla24xx_reset_risc(scsi_qla_host_t *vha) uint16_t wd; static int abts_cnt; /* ISP abort retry counts */ int rval = QLA_SUCCESS; + int print = 1; spin_lock_irqsave(&ha->hardware_lock, flags); @@ -2871,17 +2915,26 @@ qla24xx_reset_risc(scsi_qla_host_t *vha) rd_reg_dword(®->hccr); wrt_reg_dword(®->hccr, HCCRX_CLR_RISC_RESET); + mdelay(10); rd_reg_dword(®->hccr); - rd_reg_word(®->mailbox0); - for (cnt = 60; rd_reg_word(®->mailbox0) != 0 && - rval == QLA_SUCCESS; cnt--) { + wd = rd_reg_word(®->mailbox0); + for (cnt = 300; wd != 0 && rval == QLA_SUCCESS; cnt--) { barrier(); - if (cnt) - udelay(5); - else + if (cnt) { + mdelay(1); + if (print && qla_chk_risc_recovery(vha)) + print = 0; + + wd = rd_reg_word(®->mailbox0); + } else { rval = QLA_FUNCTION_TIMEOUT; + + ql_log(ql_log_warn, vha, 0x015e, + "RISC reset timeout\n"); + } } + if (rval == QLA_SUCCESS) set_bit(RISC_RDY_AFT_RESET, &ha->fw_dump_cap_flags); From f7a0ed479e66ab177801301a1a72c37775c40450 Mon Sep 17 00:00:00 2001 From: Quinn Tran Date: Mon, 29 Mar 2021 01:52:25 -0700 Subject: [PATCH 258/412] scsi: qla2xxx: Fix crash in PCIe error handling BUG: unable to handle kernel NULL pointer dereference at (null) IP: qla2x00_abort_isp+0x21/0x6b0 [qla2xxx] PGD 0 P4D 0 Oops: 0000 [#1] SMP PTI CPU: 0 PID: 1715 Comm: kworker/0:2 Tainted: GOE 4.12.14-122.37-default #1 SLE12-SP5 Hardware name: HPE Superdome Flex/Superdome Flex, BIOS Bundle:3.30.100 SFW:IP147.007.004.017.000.2009211957 09/21/2020 Workqueue: events aer_recover_work_func task: ffff9e399c14ca80 task.stack: ffffc1c58e4ac000 RIP: 0010:qla2x00_abort_isp+0x21/0x6b0 [qla2xxx] RSP: 0018:ffffc1c58e4afd50 EFLAGS: 00010282 RAX: 0000000000000000 RBX: ffff9e419cdef480 RCX: 0000000000000000 RDX: ffff9e399c14ca80 RSI: 0000000000000246 RDI: ffff9e419bbc27b8 RBP: ffff9e419bbc27b8 R08: 0000000000000004 R09: 00000000a0440000 R10: 0000000000000000 R11: ffff9e399416d1a0 R12: ffff9e419cdef000 R13: ffff9e3a7cfae800 R14: ffff9e3a7cfae800 R15: 00000000000000c0 FS: 0000000000000000(0000) GS:ffff9e39a0000000(0000) knlGS:0000000000000000 CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 CR2: 0000000000000000 CR3: 00000006cd00a005 CR4: 00000000007606f0 DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000 DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400 PKRU: 55555554 Call Trace: qla2xxx_pci_slot_reset+0x141/0x160 [qla2xxx] report_slot_reset+0x41/0x80 ? merge_result.part.4+0x30/0x30 pci_walk_bus+0x70/0x90 pcie_do_recovery+0x1db/0x2e0 aer_recover_work_func+0xc2/0xf0 process_one_work+0x14c/0x390 Disable board_disable logic where driver resources are freed while OS is in the process of recovering the adapter. Link: https://lore.kernel.org/r/20210329085229.4367-9-njavali@marvell.com Tested-by: Laurence Oberman Signed-off-by: Quinn Tran Signed-off-by: Nilesh Javali Signed-off-by: Martin K. Petersen --- drivers/scsi/qla2xxx/qla_dbg.c | 16 ++- drivers/scsi/qla2xxx/qla_def.h | 10 ++ drivers/scsi/qla2xxx/qla_gbl.h | 3 + drivers/scsi/qla2xxx/qla_init.c | 40 ++++--- drivers/scsi/qla2xxx/qla_inline.h | 46 ++++++++ drivers/scsi/qla2xxx/qla_iocb.c | 60 +++++++++-- drivers/scsi/qla2xxx/qla_isr.c | 9 +- drivers/scsi/qla2xxx/qla_mbx.c | 3 +- drivers/scsi/qla2xxx/qla_nvme.c | 10 +- drivers/scsi/qla2xxx/qla_os.c | 173 ++++++++++++++++++------------ 10 files changed, 265 insertions(+), 105 deletions(-) diff --git a/drivers/scsi/qla2xxx/qla_dbg.c b/drivers/scsi/qla2xxx/qla_dbg.c index 144a893e7335..f2d05592c1e2 100644 --- a/drivers/scsi/qla2xxx/qla_dbg.c +++ b/drivers/scsi/qla2xxx/qla_dbg.c @@ -113,8 +113,13 @@ qla27xx_dump_mpi_ram(struct qla_hw_data *ha, uint32_t addr, uint32_t *ram, uint32_t stat; ulong i, j, timer = 6000000; int rval = QLA_FUNCTION_FAILED; + scsi_qla_host_t *vha = pci_get_drvdata(ha->pdev); clear_bit(MBX_INTERRUPT, &ha->mbx_cmd_flags); + + if (qla_pci_disconnected(vha, reg)) + return rval; + for (i = 0; i < ram_dwords; i += dwords, addr += dwords) { if (i + dwords > ram_dwords) dwords = ram_dwords - i; @@ -138,6 +143,9 @@ qla27xx_dump_mpi_ram(struct qla_hw_data *ha, uint32_t addr, uint32_t *ram, while (timer--) { udelay(5); + if (qla_pci_disconnected(vha, reg)) + return rval; + stat = rd_reg_dword(®->host_status); /* Check for pending interrupts. */ if (!(stat & HSRX_RISC_INT)) @@ -192,9 +200,13 @@ qla24xx_dump_ram(struct qla_hw_data *ha, uint32_t addr, __be32 *ram, uint32_t dwords = qla2x00_gid_list_size(ha) / 4; uint32_t stat; ulong i, j, timer = 6000000; + scsi_qla_host_t *vha = pci_get_drvdata(ha->pdev); clear_bit(MBX_INTERRUPT, &ha->mbx_cmd_flags); + if (qla_pci_disconnected(vha, reg)) + return rval; + for (i = 0; i < ram_dwords; i += dwords, addr += dwords) { if (i + dwords > ram_dwords) dwords = ram_dwords - i; @@ -216,8 +228,10 @@ qla24xx_dump_ram(struct qla_hw_data *ha, uint32_t addr, __be32 *ram, ha->flags.mbox_int = 0; while (timer--) { udelay(5); - stat = rd_reg_dword(®->host_status); + if (qla_pci_disconnected(vha, reg)) + return rval; + stat = rd_reg_dword(®->host_status); /* Check for pending interrupts. */ if (!(stat & HSRX_RISC_INT)) continue; diff --git a/drivers/scsi/qla2xxx/qla_def.h b/drivers/scsi/qla2xxx/qla_def.h index ca7cebae1d78..def4d99f80e9 100644 --- a/drivers/scsi/qla2xxx/qla_def.h +++ b/drivers/scsi/qla2xxx/qla_def.h @@ -396,6 +396,7 @@ typedef union { } b; } port_id_t; #define INVALID_PORT_ID 0xFFFFFF +#define ISP_REG16_DISCONNECT 0xFFFF static inline le_id_t be_id_to_le(be_id_t id) { @@ -3857,6 +3858,13 @@ struct qla_hw_data_stat { u32 num_mpi_reset; }; +/* refer to pcie_do_recovery reference */ +typedef enum { + QLA_PCI_RESUME, + QLA_PCI_ERR_DETECTED, + QLA_PCI_MMIO_ENABLED, + QLA_PCI_SLOT_RESET, +} pci_error_state_t; /* * Qlogic host adapter specific data structure. */ @@ -4607,6 +4615,7 @@ struct qla_hw_data { #define DEFAULT_ZIO_THRESHOLD 5 struct qla_hw_data_stat stat; + pci_error_state_t pci_error_state; }; struct active_regions { @@ -4727,6 +4736,7 @@ typedef struct scsi_qla_host { #define FX00_CRITEMP_RECOVERY 25 #define FX00_HOST_INFO_RESEND 26 #define QPAIR_ONLINE_CHECK_NEEDED 27 +#define DO_EEH_RECOVERY 28 #define DETECT_SFP_CHANGE 29 #define N2N_LOGIN_NEEDED 30 #define IOCB_WORK_ACTIVE 31 diff --git a/drivers/scsi/qla2xxx/qla_gbl.h b/drivers/scsi/qla2xxx/qla_gbl.h index 6486f97d649e..fae5cae6f0a8 100644 --- a/drivers/scsi/qla2xxx/qla_gbl.h +++ b/drivers/scsi/qla2xxx/qla_gbl.h @@ -224,6 +224,7 @@ extern int qla2x00_post_uevent_work(struct scsi_qla_host *, u32); extern int qla2x00_post_uevent_work(struct scsi_qla_host *, u32); extern void qla2x00_disable_board_on_pci_error(struct work_struct *); +extern void qla_eeh_work(struct work_struct *); extern void qla2x00_sp_compl(srb_t *sp, int); extern void qla2xxx_qpair_sp_free_dma(srb_t *sp); extern void qla2xxx_qpair_sp_compl(srb_t *sp, int); @@ -235,6 +236,8 @@ int qla24xx_post_relogin_work(struct scsi_qla_host *vha); void qla2x00_wait_for_sess_deletion(scsi_qla_host_t *); void qla24xx_process_purex_rdp(struct scsi_qla_host *vha, struct purex_item *pkt); +void qla_pci_set_eeh_busy(struct scsi_qla_host *); +void qla_schedule_eeh_work(struct scsi_qla_host *); /* * Global Functions in qla_mid.c source file. diff --git a/drivers/scsi/qla2xxx/qla_init.c b/drivers/scsi/qla2xxx/qla_init.c index 19681d3c5b7a..9c5782e946e0 100644 --- a/drivers/scsi/qla2xxx/qla_init.c +++ b/drivers/scsi/qla2xxx/qla_init.c @@ -6932,22 +6932,18 @@ qla2x00_abort_isp_cleanup(scsi_qla_host_t *vha) } spin_unlock_irqrestore(&ha->vport_slock, flags); - if (!ha->flags.eeh_busy) { - /* Make sure for ISP 82XX IO DMA is complete */ - if (IS_P3P_TYPE(ha)) { - qla82xx_chip_reset_cleanup(vha); - ql_log(ql_log_info, vha, 0x00b4, - "Done chip reset cleanup.\n"); + /* Make sure for ISP 82XX IO DMA is complete */ + if (IS_P3P_TYPE(ha)) { + qla82xx_chip_reset_cleanup(vha); + ql_log(ql_log_info, vha, 0x00b4, + "Done chip reset cleanup.\n"); - /* Done waiting for pending commands. - * Reset the online flag. - */ - vha->flags.online = 0; - } - - /* Requeue all commands in outstanding command list. */ - qla2x00_abort_all_cmds(vha, DID_RESET << 16); + /* Done waiting for pending commands. Reset online flag */ + vha->flags.online = 0; } + + /* Requeue all commands in outstanding command list. */ + qla2x00_abort_all_cmds(vha, DID_RESET << 16); /* memory barrier */ wmb(); } @@ -6978,6 +6974,12 @@ qla2x00_abort_isp(scsi_qla_host_t *vha) if (vha->hw->flags.port_isolated) return status; + if (qla2x00_isp_reg_stat(ha)) { + ql_log(ql_log_info, vha, 0x803f, + "ISP Abort - ISP reg disconnect, exiting.\n"); + return status; + } + if (test_and_clear_bit(ISP_ABORT_TO_ROM, &vha->dpc_flags)) { ha->flags.chip_reset_done = 1; vha->flags.online = 1; @@ -7017,8 +7019,18 @@ qla2x00_abort_isp(scsi_qla_host_t *vha) ha->isp_ops->get_flash_version(vha, req->ring); + if (qla2x00_isp_reg_stat(ha)) { + ql_log(ql_log_info, vha, 0x803f, + "ISP Abort - ISP reg disconnect pre nvram config, exiting.\n"); + return status; + } ha->isp_ops->nvram_config(vha); + if (qla2x00_isp_reg_stat(ha)) { + ql_log(ql_log_info, vha, 0x803f, + "ISP Abort - ISP reg disconnect post nvmram config, exiting.\n"); + return status; + } if (!qla2x00_restart_isp(vha)) { clear_bit(RESET_MARKER_NEEDED, &vha->dpc_flags); diff --git a/drivers/scsi/qla2xxx/qla_inline.h b/drivers/scsi/qla2xxx/qla_inline.h index e80e41b6c9e1..82937c6bd9c4 100644 --- a/drivers/scsi/qla2xxx/qla_inline.h +++ b/drivers/scsi/qla2xxx/qla_inline.h @@ -432,3 +432,49 @@ qla_put_iocbs(struct qla_qpair *qp, struct iocb_resource *iores) } iores->res_type = RESOURCE_NONE; } + +#define ISP_REG_DISCONNECT 0xffffffffU +/************************************************************************** + * qla2x00_isp_reg_stat + * + * Description: + * Read the host status register of ISP before aborting the command. + * + * Input: + * ha = pointer to host adapter structure. + * + * + * Returns: + * Either true or false. + * + * Note: Return true if there is register disconnect. + **************************************************************************/ +static inline +uint32_t qla2x00_isp_reg_stat(struct qla_hw_data *ha) +{ + struct device_reg_24xx __iomem *reg = &ha->iobase->isp24; + struct device_reg_82xx __iomem *reg82 = &ha->iobase->isp82; + + if (IS_P3P_TYPE(ha)) + return ((rd_reg_dword(®82->host_int)) == ISP_REG_DISCONNECT); + else + return ((rd_reg_dword(®->host_status)) == + ISP_REG_DISCONNECT); +} + +static inline +bool qla_pci_disconnected(struct scsi_qla_host *vha, + struct device_reg_24xx __iomem *reg) +{ + uint32_t stat; + bool ret = false; + + stat = rd_reg_dword(®->host_status); + if (stat == 0xffffffff) { + ql_log(ql_log_info, vha, 0x8041, + "detected PCI disconnect.\n"); + qla_schedule_eeh_work(vha); + ret = true; + } + return ret; +} diff --git a/drivers/scsi/qla2xxx/qla_iocb.c b/drivers/scsi/qla2xxx/qla_iocb.c index fea3a92e7724..38b5bdde2405 100644 --- a/drivers/scsi/qla2xxx/qla_iocb.c +++ b/drivers/scsi/qla2xxx/qla_iocb.c @@ -1645,8 +1645,14 @@ qla24xx_start_scsi(srb_t *sp) goto queuing_error; if (req->cnt < (req_cnt + 2)) { - cnt = IS_SHADOW_REG_CAPABLE(ha) ? *req->out_ptr : - rd_reg_dword_relaxed(req->req_q_out); + if (IS_SHADOW_REG_CAPABLE(ha)) { + cnt = *req->out_ptr; + } else { + cnt = rd_reg_dword_relaxed(req->req_q_out); + if (qla2x00_check_reg16_for_disconnect(vha, cnt)) + goto queuing_error; + } + if (req->ring_index < cnt) req->cnt = cnt - req->ring_index; else @@ -1842,8 +1848,13 @@ qla24xx_dif_start_scsi(srb_t *sp) goto queuing_error; if (req->cnt < (req_cnt + 2)) { - cnt = IS_SHADOW_REG_CAPABLE(ha) ? *req->out_ptr : - rd_reg_dword_relaxed(req->req_q_out); + if (IS_SHADOW_REG_CAPABLE(ha)) { + cnt = *req->out_ptr; + } else { + cnt = rd_reg_dword_relaxed(req->req_q_out); + if (qla2x00_check_reg16_for_disconnect(vha, cnt)) + goto queuing_error; + } if (req->ring_index < cnt) req->cnt = cnt - req->ring_index; else @@ -1922,6 +1933,7 @@ queuing_error: qla_put_iocbs(sp->qpair, &sp->iores); spin_unlock_irqrestore(&ha->hardware_lock, flags); + return QLA_FUNCTION_FAILED; } @@ -1991,8 +2003,14 @@ qla2xxx_start_scsi_mq(srb_t *sp) goto queuing_error; if (req->cnt < (req_cnt + 2)) { - cnt = IS_SHADOW_REG_CAPABLE(ha) ? *req->out_ptr : - rd_reg_dword_relaxed(req->req_q_out); + if (IS_SHADOW_REG_CAPABLE(ha)) { + cnt = *req->out_ptr; + } else { + cnt = rd_reg_dword_relaxed(req->req_q_out); + if (qla2x00_check_reg16_for_disconnect(vha, cnt)) + goto queuing_error; + } + if (req->ring_index < cnt) req->cnt = cnt - req->ring_index; else @@ -2203,8 +2221,14 @@ qla2xxx_dif_start_scsi_mq(srb_t *sp) goto queuing_error; if (req->cnt < (req_cnt + 2)) { - cnt = IS_SHADOW_REG_CAPABLE(ha) ? *req->out_ptr : - rd_reg_dword_relaxed(req->req_q_out); + if (IS_SHADOW_REG_CAPABLE(ha)) { + cnt = *req->out_ptr; + } else { + cnt = rd_reg_dword_relaxed(req->req_q_out); + if (qla2x00_check_reg16_for_disconnect(vha, cnt)) + goto queuing_error; + } + if (req->ring_index < cnt) req->cnt = cnt - req->ring_index; else @@ -2281,6 +2305,7 @@ queuing_error: qla_put_iocbs(sp->qpair, &sp->iores); spin_unlock_irqrestore(&qpair->qp_lock, flags); + return QLA_FUNCTION_FAILED; } @@ -2325,6 +2350,11 @@ __qla2x00_alloc_iocbs(struct qla_qpair *qpair, srb_t *sp) cnt = qla2x00_debounce_register( ISP_REQ_Q_OUT(ha, ®->isp)); + if (!qpair->use_shadow_reg && cnt == ISP_REG16_DISCONNECT) { + qla_schedule_eeh_work(vha); + return NULL; + } + if (req->ring_index < cnt) req->cnt = cnt - req->ring_index; else @@ -3740,6 +3770,9 @@ qla2x00_start_sp(srb_t *sp) void *pkt; unsigned long flags; + if (vha->hw->flags.eeh_busy) + return -EIO; + spin_lock_irqsave(qp->qp_lock_ptr, flags); pkt = __qla2x00_alloc_iocbs(sp->qpair, sp); if (!pkt) { @@ -3957,8 +3990,14 @@ qla2x00_start_bidir(srb_t *sp, struct scsi_qla_host *vha, uint32_t tot_dsds) /* Check for room on request queue. */ if (req->cnt < req_cnt + 2) { - cnt = IS_SHADOW_REG_CAPABLE(ha) ? *req->out_ptr : - rd_reg_dword_relaxed(req->req_q_out); + if (IS_SHADOW_REG_CAPABLE(ha)) { + cnt = *req->out_ptr; + } else { + cnt = rd_reg_dword_relaxed(req->req_q_out); + if (qla2x00_check_reg16_for_disconnect(vha, cnt)) + goto queuing_error; + } + if (req->ring_index < cnt) req->cnt = cnt - req->ring_index; else @@ -3997,5 +4036,6 @@ qla2x00_start_bidir(srb_t *sp, struct scsi_qla_host *vha, uint32_t tot_dsds) qla2x00_start_iocbs(vha, req); queuing_error: spin_unlock_irqrestore(&ha->hardware_lock, flags); + return rval; } diff --git a/drivers/scsi/qla2xxx/qla_isr.c b/drivers/scsi/qla2xxx/qla_isr.c index 0938119e8a5f..11d6e0db07fe 100644 --- a/drivers/scsi/qla2xxx/qla_isr.c +++ b/drivers/scsi/qla2xxx/qla_isr.c @@ -270,12 +270,7 @@ qla2x00_check_reg32_for_disconnect(scsi_qla_host_t *vha, uint32_t reg) if (!test_and_set_bit(PFLG_DISCONNECTED, &vha->pci_flags) && !test_bit(PFLG_DRIVER_REMOVING, &vha->pci_flags) && !test_bit(PFLG_DRIVER_PROBING, &vha->pci_flags)) { - /* - * Schedule this (only once) on the default system - * workqueue so that all the adapter workqueues and the - * DPC thread can be shutdown cleanly. - */ - schedule_work(&vha->hw->board_disable); + qla_schedule_eeh_work(vha); } return true; } else @@ -1657,8 +1652,6 @@ global_port_update: case MBA_TEMPERATURE_ALERT: ql_dbg(ql_dbg_async, vha, 0x505e, "TEMPERATURE ALERT: %04x %04x %04x\n", mb[1], mb[2], mb[3]); - if (mb[1] == 0x12) - schedule_work(&ha->board_disable); break; case MBA_TRANS_INSERT: diff --git a/drivers/scsi/qla2xxx/qla_mbx.c b/drivers/scsi/qla2xxx/qla_mbx.c index 06c99963b2c9..0149f84cdd8e 100644 --- a/drivers/scsi/qla2xxx/qla_mbx.c +++ b/drivers/scsi/qla2xxx/qla_mbx.c @@ -161,7 +161,8 @@ qla2x00_mailbox_command(scsi_qla_host_t *vha, mbx_cmd_t *mcp) /* check if ISP abort is active and return cmd with timeout */ if ((test_bit(ABORT_ISP_ACTIVE, &base_vha->dpc_flags) || test_bit(ISP_ABORT_RETRY, &base_vha->dpc_flags) || - test_bit(ISP_ABORT_NEEDED, &base_vha->dpc_flags)) && + test_bit(ISP_ABORT_NEEDED, &base_vha->dpc_flags) || + ha->flags.eeh_busy) && !is_rom_cmd(mcp->mb[0])) { ql_log(ql_log_info, vha, 0x1005, "Cmd 0x%x aborted with timeout since ISP Abort is pending\n", diff --git a/drivers/scsi/qla2xxx/qla_nvme.c b/drivers/scsi/qla2xxx/qla_nvme.c index 0237588f48b0..0cacb667a88b 100644 --- a/drivers/scsi/qla2xxx/qla_nvme.c +++ b/drivers/scsi/qla2xxx/qla_nvme.c @@ -398,8 +398,13 @@ static inline int qla2x00_start_nvme_mq(srb_t *sp) } req_cnt = qla24xx_calc_iocbs(vha, tot_dsds); if (req->cnt < (req_cnt + 2)) { - cnt = IS_SHADOW_REG_CAPABLE(ha) ? *req->out_ptr : - rd_reg_dword_relaxed(req->req_q_out); + if (IS_SHADOW_REG_CAPABLE(ha)) { + cnt = *req->out_ptr; + } else { + cnt = rd_reg_dword_relaxed(req->req_q_out); + if (qla2x00_check_reg16_for_disconnect(vha, cnt)) + goto queuing_error; + } if (req->ring_index < cnt) req->cnt = cnt - req->ring_index; @@ -536,6 +541,7 @@ static inline int qla2x00_start_nvme_mq(srb_t *sp) queuing_error: spin_unlock_irqrestore(&qpair->qp_lock, flags); + return rval; } diff --git a/drivers/scsi/qla2xxx/qla_os.c b/drivers/scsi/qla2xxx/qla_os.c index cb4155f8fd44..12959e3874cb 100644 --- a/drivers/scsi/qla2xxx/qla_os.c +++ b/drivers/scsi/qla2xxx/qla_os.c @@ -971,6 +971,13 @@ qla2xxx_mqueuecommand(struct Scsi_Host *host, struct scsi_cmnd *cmd, goto qc24_fail_command; } + if (!qpair->online) { + ql_dbg(ql_dbg_io, vha, 0x3077, + "qpair not online. eeh_busy=%d.\n", ha->flags.eeh_busy); + cmd->result = DID_NO_CONNECT << 16; + goto qc24_fail_command; + } + if (!fcport || fcport->deleted) { cmd->result = DID_IMM_RETRY << 16; goto qc24_fail_command; @@ -1200,35 +1207,6 @@ qla2x00_wait_for_chip_reset(scsi_qla_host_t *vha) return return_status; } -#define ISP_REG_DISCONNECT 0xffffffffU -/************************************************************************** -* qla2x00_isp_reg_stat -* -* Description: -* Read the host status register of ISP before aborting the command. -* -* Input: -* ha = pointer to host adapter structure. -* -* -* Returns: -* Either true or false. -* -* Note: Return true if there is register disconnect. -**************************************************************************/ -static inline -uint32_t qla2x00_isp_reg_stat(struct qla_hw_data *ha) -{ - struct device_reg_24xx __iomem *reg = &ha->iobase->isp24; - struct device_reg_82xx __iomem *reg82 = &ha->iobase->isp82; - - if (IS_P3P_TYPE(ha)) - return ((rd_reg_dword(®82->host_int)) == ISP_REG_DISCONNECT); - else - return ((rd_reg_dword(®->host_status)) == - ISP_REG_DISCONNECT); -} - /************************************************************************** * qla2xxx_eh_abort * @@ -1262,6 +1240,7 @@ qla2xxx_eh_abort(struct scsi_cmnd *cmd) if (qla2x00_isp_reg_stat(ha)) { ql_log(ql_log_info, vha, 0x8042, "PCI/Register disconnect, exiting.\n"); + qla_pci_set_eeh_busy(vha); return FAILED; } @@ -1455,6 +1434,7 @@ qla2xxx_eh_device_reset(struct scsi_cmnd *cmd) if (qla2x00_isp_reg_stat(ha)) { ql_log(ql_log_info, vha, 0x803e, "PCI/Register disconnect, exiting.\n"); + qla_pci_set_eeh_busy(vha); return FAILED; } @@ -1471,6 +1451,7 @@ qla2xxx_eh_target_reset(struct scsi_cmnd *cmd) if (qla2x00_isp_reg_stat(ha)) { ql_log(ql_log_info, vha, 0x803f, "PCI/Register disconnect, exiting.\n"); + qla_pci_set_eeh_busy(vha); return FAILED; } @@ -1506,6 +1487,7 @@ qla2xxx_eh_bus_reset(struct scsi_cmnd *cmd) if (qla2x00_isp_reg_stat(ha)) { ql_log(ql_log_info, vha, 0x8040, "PCI/Register disconnect, exiting.\n"); + qla_pci_set_eeh_busy(vha); return FAILED; } @@ -1583,7 +1565,7 @@ qla2xxx_eh_host_reset(struct scsi_cmnd *cmd) if (qla2x00_isp_reg_stat(ha)) { ql_log(ql_log_info, vha, 0x8041, "PCI/Register disconnect, exiting.\n"); - schedule_work(&ha->board_disable); + qla_pci_set_eeh_busy(vha); return SUCCESS; } @@ -6668,6 +6650,9 @@ qla2x00_do_dpc(void *data) schedule(); + if (test_and_clear_bit(DO_EEH_RECOVERY, &base_vha->dpc_flags)) + qla_pci_set_eeh_busy(base_vha); + if (!base_vha->flags.init_done || ha->flags.mbox_busy) goto end_loop; @@ -7384,6 +7369,8 @@ static void qla_pci_error_cleanup(scsi_qla_host_t *vha) int i; unsigned long flags; + ql_dbg(ql_dbg_aer, vha, 0x9000, + "%s\n", __func__); ha->chip_reset++; ha->base_qpair->chip_reset = ha->chip_reset; @@ -7393,28 +7380,16 @@ static void qla_pci_error_cleanup(scsi_qla_host_t *vha) ha->base_qpair->chip_reset; } - /* purge MBox commands */ - if (atomic_read(&ha->num_pend_mbx_stage3)) { - clear_bit(MBX_INTR_WAIT, &ha->mbx_cmd_flags); - complete(&ha->mbx_intr_comp); - } - - i = 0; - - while (atomic_read(&ha->num_pend_mbx_stage3) || - atomic_read(&ha->num_pend_mbx_stage2) || - atomic_read(&ha->num_pend_mbx_stage1)) { - msleep(20); - i++; - if (i > 50) - break; - } - - ha->flags.purge_mbox = 0; + /* + * purge mailbox might take a while. Slot Reset/chip reset + * will take care of the purge + */ mutex_lock(&ha->mq_lock); + ha->base_qpair->online = 0; list_for_each_entry(qpair, &base_vha->qp_list, qp_list_elem) qpair->online = 0; + wmb(); mutex_unlock(&ha->mq_lock); qla2x00_mark_all_devices_lost(vha); @@ -7451,14 +7426,17 @@ qla2xxx_pci_error_detected(struct pci_dev *pdev, pci_channel_state_t state) { scsi_qla_host_t *vha = pci_get_drvdata(pdev); struct qla_hw_data *ha = vha->hw; + pci_ers_result_t ret = PCI_ERS_RESULT_NEED_RESET; - ql_dbg(ql_dbg_aer, vha, 0x9000, - "PCI error detected, state %x.\n", state); + ql_log(ql_log_warn, vha, 0x9000, + "PCI error detected, state %x.\n", state); + ha->pci_error_state = QLA_PCI_ERR_DETECTED; if (!atomic_read(&pdev->enable_cnt)) { ql_log(ql_log_info, vha, 0xffff, "PCI device is disabled,state %x\n", state); - return PCI_ERS_RESULT_NEED_RESET; + ret = PCI_ERS_RESULT_NEED_RESET; + goto out; } switch (state) { @@ -7468,11 +7446,12 @@ qla2xxx_pci_error_detected(struct pci_dev *pdev, pci_channel_state_t state) set_bit(QPAIR_ONLINE_CHECK_NEEDED, &vha->dpc_flags); qla2xxx_wake_dpc(vha); } - return PCI_ERS_RESULT_CAN_RECOVER; + ret = PCI_ERS_RESULT_CAN_RECOVER; + break; case pci_channel_io_frozen: - ha->flags.eeh_busy = 1; - qla_pci_error_cleanup(vha); - return PCI_ERS_RESULT_NEED_RESET; + qla_pci_set_eeh_busy(vha); + ret = PCI_ERS_RESULT_NEED_RESET; + break; case pci_channel_io_perm_failure: ha->flags.pci_channel_io_perm_failure = 1; qla2x00_abort_all_cmds(vha, DID_NO_CONNECT << 16); @@ -7480,9 +7459,12 @@ qla2xxx_pci_error_detected(struct pci_dev *pdev, pci_channel_state_t state) set_bit(QPAIR_ONLINE_CHECK_NEEDED, &vha->dpc_flags); qla2xxx_wake_dpc(vha); } - return PCI_ERS_RESULT_DISCONNECT; + ret = PCI_ERS_RESULT_DISCONNECT; } - return PCI_ERS_RESULT_NEED_RESET; +out: + ql_dbg(ql_dbg_aer, vha, 0x600d, + "PCI error detected returning [%x].\n", ret); + return ret; } static pci_ers_result_t @@ -7496,6 +7478,10 @@ qla2xxx_pci_mmio_enabled(struct pci_dev *pdev) struct device_reg_2xxx __iomem *reg = &ha->iobase->isp; struct device_reg_24xx __iomem *reg24 = &ha->iobase->isp24; + ql_log(ql_log_warn, base_vha, 0x9000, + "mmio enabled\n"); + + ha->pci_error_state = QLA_PCI_MMIO_ENABLED; if (IS_QLA82XX(ha)) return PCI_ERS_RESULT_RECOVERED; @@ -7519,10 +7505,11 @@ qla2xxx_pci_mmio_enabled(struct pci_dev *pdev) ql_log(ql_log_info, base_vha, 0x9003, "RISC paused -- mmio_enabled, Dumping firmware.\n"); qla2xxx_dump_fw(base_vha); - - return PCI_ERS_RESULT_NEED_RESET; - } else - return PCI_ERS_RESULT_RECOVERED; + } + /* set PCI_ERS_RESULT_NEED_RESET to trigger call to qla2xxx_pci_slot_reset */ + ql_dbg(ql_dbg_aer, base_vha, 0x600d, + "mmio enabled returning.\n"); + return PCI_ERS_RESULT_NEED_RESET; } static pci_ers_result_t @@ -7534,9 +7521,10 @@ qla2xxx_pci_slot_reset(struct pci_dev *pdev) int rc; struct qla_qpair *qpair = NULL; - ql_dbg(ql_dbg_aer, base_vha, 0x9004, - "Slot Reset.\n"); + ql_log(ql_log_warn, base_vha, 0x9004, + "Slot Reset.\n"); + ha->pci_error_state = QLA_PCI_SLOT_RESET; /* Workaround: qla2xxx driver which access hardware earlier * needs error state to be pci_channel_io_online. * Otherwise mailbox command timesout. @@ -7570,16 +7558,24 @@ qla2xxx_pci_slot_reset(struct pci_dev *pdev) qpair->online = 1; mutex_unlock(&ha->mq_lock); + ha->flags.eeh_busy = 0; base_vha->flags.online = 1; set_bit(ABORT_ISP_ACTIVE, &base_vha->dpc_flags); - if (ha->isp_ops->abort_isp(base_vha) == QLA_SUCCESS) - ret = PCI_ERS_RESULT_RECOVERED; + ha->isp_ops->abort_isp(base_vha); clear_bit(ABORT_ISP_ACTIVE, &base_vha->dpc_flags); + if (qla2x00_isp_reg_stat(ha)) { + ha->flags.eeh_busy = 1; + qla_pci_error_cleanup(base_vha); + ql_log(ql_log_warn, base_vha, 0x9005, + "Device unable to recover from PCI error.\n"); + } else { + ret = PCI_ERS_RESULT_RECOVERED; + } exit_slot_reset: ql_dbg(ql_dbg_aer, base_vha, 0x900e, - "slot_reset return %x.\n", ret); + "Slot Reset returning %x.\n", ret); return ret; } @@ -7591,16 +7587,55 @@ qla2xxx_pci_resume(struct pci_dev *pdev) struct qla_hw_data *ha = base_vha->hw; int ret; - ql_dbg(ql_dbg_aer, base_vha, 0x900f, - "pci_resume.\n"); + ql_log(ql_log_warn, base_vha, 0x900f, + "Pci Resume.\n"); - ha->flags.eeh_busy = 0; ret = qla2x00_wait_for_hba_online(base_vha); if (ret != QLA_SUCCESS) { ql_log(ql_log_fatal, base_vha, 0x9002, "The device failed to resume I/O from slot/link_reset.\n"); } + ha->pci_error_state = QLA_PCI_RESUME; + ql_dbg(ql_dbg_aer, base_vha, 0x600d, + "Pci Resume returning.\n"); +} + +void qla_pci_set_eeh_busy(struct scsi_qla_host *vha) +{ + struct qla_hw_data *ha = vha->hw; + struct scsi_qla_host *base_vha = pci_get_drvdata(ha->pdev); + bool do_cleanup = false; + unsigned long flags; + + if (ha->flags.eeh_busy) + return; + + spin_lock_irqsave(&base_vha->work_lock, flags); + if (!ha->flags.eeh_busy) { + ha->flags.eeh_busy = 1; + do_cleanup = true; + } + spin_unlock_irqrestore(&base_vha->work_lock, flags); + + if (do_cleanup) + qla_pci_error_cleanup(base_vha); +} + +/* + * this routine will schedule a task to pause IO from interrupt context + * if caller sees a PCIE error event (register read = 0xf's) + */ +void qla_schedule_eeh_work(struct scsi_qla_host *vha) +{ + struct qla_hw_data *ha = vha->hw; + struct scsi_qla_host *base_vha = pci_get_drvdata(ha->pdev); + + if (ha->flags.eeh_busy) + return; + + set_bit(DO_EEH_RECOVERY, &base_vha->dpc_flags); + qla2xxx_wake_dpc(base_vha); } static void From daafc8d33ff62009e52225106f1a6c20fe1b6ccd Mon Sep 17 00:00:00 2001 From: Quinn Tran Date: Mon, 29 Mar 2021 01:52:26 -0700 Subject: [PATCH 259/412] scsi: qla2xxx: Fix mailbox recovery during PCIe error For the mailbox thread that encounters a PCIe error, pause that thread until PCIe link reset/recovery has completed to prevent the thread from possibly unmapping any type of DMA resource that might be in progress. Link: https://lore.kernel.org/r/20210329085229.4367-10-njavali@marvell.com Tested-by: Laurence Oberman Reviewed-by: Himanshu Madhani Signed-off-by: Quinn Tran Signed-off-by: Nilesh Javali Signed-off-by: Martin K. Petersen --- drivers/scsi/qla2xxx/qla_mbx.c | 39 ++++++++++++++++++++++++++-------- 1 file changed, 30 insertions(+), 9 deletions(-) diff --git a/drivers/scsi/qla2xxx/qla_mbx.c b/drivers/scsi/qla2xxx/qla_mbx.c index 0149f84cdd8e..0bcd8afdc0ff 100644 --- a/drivers/scsi/qla2xxx/qla_mbx.c +++ b/drivers/scsi/qla2xxx/qla_mbx.c @@ -102,7 +102,7 @@ qla2x00_mailbox_command(scsi_qla_host_t *vha, mbx_cmd_t *mcp) int rval, i; unsigned long flags = 0; device_reg_t *reg; - uint8_t abort_active; + uint8_t abort_active, eeh_delay; uint8_t io_lock_on; uint16_t command = 0; uint16_t *iptr; @@ -136,7 +136,7 @@ qla2x00_mailbox_command(scsi_qla_host_t *vha, mbx_cmd_t *mcp) "PCI error, exiting.\n"); return QLA_FUNCTION_TIMEOUT; } - + eeh_delay = 0; reg = ha->iobase; io_lock_on = base_vha->flags.init_done; @@ -159,11 +159,10 @@ qla2x00_mailbox_command(scsi_qla_host_t *vha, mbx_cmd_t *mcp) } /* check if ISP abort is active and return cmd with timeout */ - if ((test_bit(ABORT_ISP_ACTIVE, &base_vha->dpc_flags) || - test_bit(ISP_ABORT_RETRY, &base_vha->dpc_flags) || - test_bit(ISP_ABORT_NEEDED, &base_vha->dpc_flags) || - ha->flags.eeh_busy) && - !is_rom_cmd(mcp->mb[0])) { + if (((test_bit(ABORT_ISP_ACTIVE, &base_vha->dpc_flags) || + test_bit(ISP_ABORT_RETRY, &base_vha->dpc_flags) || + test_bit(ISP_ABORT_NEEDED, &base_vha->dpc_flags)) && + !is_rom_cmd(mcp->mb[0])) || ha->flags.eeh_busy) { ql_log(ql_log_info, vha, 0x1005, "Cmd 0x%x aborted with timeout since ISP Abort is pending\n", mcp->mb[0]); @@ -186,7 +185,11 @@ qla2x00_mailbox_command(scsi_qla_host_t *vha, mbx_cmd_t *mcp) return QLA_FUNCTION_TIMEOUT; } atomic_dec(&ha->num_pend_mbx_stage1); - if (ha->flags.purge_mbox || chip_reset != ha->chip_reset) { + if (ha->flags.purge_mbox || chip_reset != ha->chip_reset || + ha->flags.eeh_busy) { + ql_log(ql_log_warn, vha, 0xd035, + "Error detected: purge[%d] eeh[%d] cmd=0x%x, Exiting.\n", + ha->flags.purge_mbox, ha->flags.eeh_busy, mcp->mb[0]); rval = QLA_ABORTED; goto premature_exit; } @@ -266,6 +269,8 @@ qla2x00_mailbox_command(scsi_qla_host_t *vha, mbx_cmd_t *mcp) if (!wait_for_completion_timeout(&ha->mbx_intr_comp, mcp->tov * HZ)) { if (chip_reset != ha->chip_reset) { + eeh_delay = ha->flags.eeh_busy ? 1 : 0; + spin_lock_irqsave(&ha->hardware_lock, flags); ha->flags.mbox_busy = 0; spin_unlock_irqrestore(&ha->hardware_lock, @@ -283,6 +288,8 @@ qla2x00_mailbox_command(scsi_qla_host_t *vha, mbx_cmd_t *mcp) } else if (ha->flags.purge_mbox || chip_reset != ha->chip_reset) { + eeh_delay = ha->flags.eeh_busy ? 1 : 0; + spin_lock_irqsave(&ha->hardware_lock, flags); ha->flags.mbox_busy = 0; spin_unlock_irqrestore(&ha->hardware_lock, flags); @@ -324,6 +331,8 @@ qla2x00_mailbox_command(scsi_qla_host_t *vha, mbx_cmd_t *mcp) while (!ha->flags.mbox_int) { if (ha->flags.purge_mbox || chip_reset != ha->chip_reset) { + eeh_delay = ha->flags.eeh_busy ? 1 : 0; + spin_lock_irqsave(&ha->hardware_lock, flags); ha->flags.mbox_busy = 0; spin_unlock_irqrestore(&ha->hardware_lock, @@ -532,7 +541,8 @@ qla2x00_mailbox_command(scsi_qla_host_t *vha, mbx_cmd_t *mcp) clear_bit(ISP_ABORT_NEEDED, &vha->dpc_flags); /* Allow next mbx cmd to come in. */ complete(&ha->mbx_cmd_comp); - if (ha->isp_ops->abort_isp(vha)) { + if (ha->isp_ops->abort_isp(vha) && + !ha->flags.eeh_busy) { /* Failed. retry later. */ set_bit(ISP_ABORT_NEEDED, &vha->dpc_flags); @@ -585,6 +595,17 @@ mbx_done: ql_dbg(ql_dbg_mbx, base_vha, 0x1021, "Done %s.\n", __func__); } + i = 500; + while (i && eeh_delay && (ha->pci_error_state < QLA_PCI_SLOT_RESET)) { + /* + * The caller of this mailbox encounter pci error. + * Hold the thread until PCIE link reset complete to make + * sure caller does not unmap dma while recovery is + * in progress. + */ + msleep(1); + i--; + } return rval; } From 1cbcc531d01f813e6a93cefdc7476f858ff2b301 Mon Sep 17 00:00:00 2001 From: Quinn Tran Date: Mon, 29 Mar 2021 01:52:27 -0700 Subject: [PATCH 260/412] scsi: qla2xxx: Update default AER debug mask Use PCIe AER debug mask as default. Link: https://lore.kernel.org/r/20210329085229.4367-11-njavali@marvell.com Tested-by: Laurence Oberman Reviewed-by: Himanshu Madhani Signed-off-by: Quinn Tran Signed-off-by: Nilesh Javali Signed-off-by: Martin K. Petersen --- drivers/scsi/qla2xxx/qla_dbg.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/scsi/qla2xxx/qla_dbg.h b/drivers/scsi/qla2xxx/qla_dbg.h index 2e59e75c62b5..9eb708e5e22e 100644 --- a/drivers/scsi/qla2xxx/qla_dbg.h +++ b/drivers/scsi/qla2xxx/qla_dbg.h @@ -308,7 +308,7 @@ struct qla2xxx_fw_dump { }; #define QL_MSGHDR "qla2xxx" -#define QL_DBG_DEFAULT1_MASK 0x1e400000 +#define QL_DBG_DEFAULT1_MASK 0x1e600000 #define ql_log_fatal 0 /* display fatal errors */ #define ql_log_warn 1 /* display critical errors */ From 022a2d211ce0eb410a2f4d0d0903a5ddf7687b55 Mon Sep 17 00:00:00 2001 From: Quinn Tran Date: Mon, 29 Mar 2021 01:52:28 -0700 Subject: [PATCH 261/412] scsi: qla2xxx: Do logout even if fabric scan retries got exhausted Perform logout of all remote ports so that all I/Os with driver are requeued with midlayer for retry. Link: https://lore.kernel.org/r/20210329085229.4367-12-njavali@marvell.com Reviewed-by: Himanshu Madhani Signed-off-by: Quinn Tran Signed-off-by: Saurav Kashyap Signed-off-by: Nilesh Javali Signed-off-by: Martin K. Petersen --- drivers/scsi/qla2xxx/qla_gs.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/drivers/scsi/qla2xxx/qla_gs.c b/drivers/scsi/qla2xxx/qla_gs.c index 8e126afe61b1..5b6e04a91a18 100644 --- a/drivers/scsi/qla2xxx/qla_gs.c +++ b/drivers/scsi/qla2xxx/qla_gs.c @@ -3443,6 +3443,10 @@ void qla24xx_async_gnnft_done(scsi_qla_host_t *vha, srb_t *sp) list_for_each_entry(fcport, &vha->vp_fcports, list) { if ((fcport->flags & FCF_FABRIC_DEVICE) != 0) { fcport->scan_state = QLA_FCPORT_SCAN; + if (fcport->loop_id == FC_NO_LOOP_ID) + fcport->logout_on_delete = 0; + else + fcport->logout_on_delete = 1; } } goto login_logout; From 10d91a15f26e76aec9e6fed31df7e8065f40770f Mon Sep 17 00:00:00 2001 From: Nilesh Javali Date: Mon, 29 Mar 2021 01:52:29 -0700 Subject: [PATCH 262/412] scsi: qla2xxx: Update version to 10.02.00.106-k Link: https://lore.kernel.org/r/20210329085229.4367-13-njavali@marvell.com Reviewed-by: Himanshu Madhani Signed-off-by: Nilesh Javali Signed-off-by: Martin K. Petersen --- drivers/scsi/qla2xxx/qla_version.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/scsi/qla2xxx/qla_version.h b/drivers/scsi/qla2xxx/qla_version.h index 72c648442e8d..da11829fa12d 100644 --- a/drivers/scsi/qla2xxx/qla_version.h +++ b/drivers/scsi/qla2xxx/qla_version.h @@ -6,9 +6,9 @@ /* * Driver version */ -#define QLA2XXX_VERSION "10.02.00.105-k" +#define QLA2XXX_VERSION "10.02.00.106-k" #define QLA_DRIVER_MAJOR_VER 10 #define QLA_DRIVER_MINOR_VER 2 #define QLA_DRIVER_PATCH_VER 0 -#define QLA_DRIVER_BETA_VER 105 +#define QLA_DRIVER_BETA_VER 106 From d2478dd256915fd0a971a1daba23cb9cadde1132 Mon Sep 17 00:00:00 2001 From: Lee Duncan Date: Tue, 23 Mar 2021 10:27:56 -0700 Subject: [PATCH 263/412] scsi: fnic: Remove bogus ratelimit messages Commit b43abcbbd5b1 ("scsi: fnic: Ratelimit printks to avoid flooding when vlan is not set by the switch.i") added printk_ratelimit() in front of a couple of debug-mode messages to reduce logging overrun when debugging the driver. The code: > if (printk_ratelimit()) > FNIC_FCS_DBG(KERN_DEBUG, fnic->lport->host, > "Start VLAN Discovery\n"); ends up calling printk_ratelimit() quite often, triggering many kernel messages about callbacks being supressed. The fix is to decompose FNIC_FCS_DBG(), then change the order of checks so that printk_ratelimit() is only called if driver debugging is enabled. Link: https://lore.kernel.org/r/20210323172756.5743-1-lduncan@suse.com Reviewed-by: Laurence Oberman Signed-off-by: Lee Duncan Signed-off-by: Martin K. Petersen --- drivers/scsi/fnic/fnic_fcs.c | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/drivers/scsi/fnic/fnic_fcs.c b/drivers/scsi/fnic/fnic_fcs.c index 881c4823d7e2..1885218f9d15 100644 --- a/drivers/scsi/fnic/fnic_fcs.c +++ b/drivers/scsi/fnic/fnic_fcs.c @@ -1343,9 +1343,10 @@ void fnic_handle_fip_timer(struct fnic *fnic) if (list_empty(&fnic->vlans)) { spin_unlock_irqrestore(&fnic->vlans_lock, flags); /* no vlans available, try again */ - if (printk_ratelimit()) - FNIC_FCS_DBG(KERN_DEBUG, fnic->lport->host, - "Start VLAN Discovery\n"); + if (unlikely(fnic_log_level & FNIC_FCS_LOGGING)) + if (printk_ratelimit()) + shost_printk(KERN_DEBUG, fnic->lport->host, + "Start VLAN Discovery\n"); fnic_event_enq(fnic, FNIC_EVT_START_VLAN_DISC); return; } @@ -1363,9 +1364,10 @@ void fnic_handle_fip_timer(struct fnic *fnic) case FIP_VLAN_FAILED: spin_unlock_irqrestore(&fnic->vlans_lock, flags); /* if all vlans are in failed state, restart vlan disc */ - if (printk_ratelimit()) - FNIC_FCS_DBG(KERN_DEBUG, fnic->lport->host, - "Start VLAN Discovery\n"); + if (unlikely(fnic_log_level & FNIC_FCS_LOGGING)) + if (printk_ratelimit()) + shost_printk(KERN_DEBUG, fnic->lport->host, + "Start VLAN Discovery\n"); fnic_event_enq(fnic, FNIC_EVT_START_VLAN_DISC); break; case FIP_VLAN_SENT: From eee8910fe0b502740e5dbb167e130dae791d3d13 Mon Sep 17 00:00:00 2001 From: dudengke Date: Fri, 26 Mar 2021 14:09:02 +0800 Subject: [PATCH 264/412] scsi: core: Fix comment typo s/remoed/removed/ Link: https://lore.kernel.org/r/20210326060902.1851811-1-pinganddu90@gmail.com Signed-off-by: dudengke Signed-off-by: Martin K. Petersen --- drivers/scsi/scsi_sysfs.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/scsi/scsi_sysfs.c b/drivers/scsi/scsi_sysfs.c index 7fb2f70e97c8..6d2a28294092 100644 --- a/drivers/scsi/scsi_sysfs.c +++ b/drivers/scsi/scsi_sysfs.c @@ -1460,7 +1460,7 @@ void __scsi_remove_device(struct scsi_device *sdev) /* * Paired with the kref_get() in scsi_sysfs_initialize(). We have - * remoed sysfs visibility from the device, so make the target + * removed sysfs visibility from the device, so make the target * invisible if this was the last device underneath it. */ scsi_target_reap(scsi_target(sdev)); From fe515ac827689d6f71d967c8e300a59cfeded42b Mon Sep 17 00:00:00 2001 From: Wan Jiabing Date: Sat, 27 Mar 2021 11:08:50 +0800 Subject: [PATCH 265/412] scsi: core: Remove duplicate declarations struct request and struct request_queue are declared twice. Remove the duplicate declarations. Link: https://lore.kernel.org/r/20210327030850.918018-1-wanjiabing@vivo.com Signed-off-by: Wan Jiabing Signed-off-by: Martin K. Petersen --- drivers/scsi/scsi_priv.h | 2 -- 1 file changed, 2 deletions(-) diff --git a/drivers/scsi/scsi_priv.h b/drivers/scsi/scsi_priv.h index 30b35002d2f8..ed240f006c04 100644 --- a/drivers/scsi/scsi_priv.h +++ b/drivers/scsi/scsi_priv.h @@ -97,8 +97,6 @@ extern int scsi_mq_setup_tags(struct Scsi_Host *shost); extern void scsi_mq_destroy_tags(struct Scsi_Host *shost); extern void scsi_exit_queue(void); extern void scsi_evt_thread(struct work_struct *work); -struct request_queue; -struct request; /* scsi_proc.c */ #ifdef CONFIG_SCSI_PROC_FS From 8dc60252968178a132898ea2e1dc7a8e9a05e635 Mon Sep 17 00:00:00 2001 From: Colin Ian King Date: Sat, 27 Mar 2021 23:06:50 +0000 Subject: [PATCH 266/412] scsi: qedi: Remove redundant assignment to variable err Variable err is assigned -ENOMEM followed by an error return path via label err_udev that does not access the variable and returns with the -ENOMEM error return code. The assignment to err is redundant and can be removed. Link: https://lore.kernel.org/r/20210327230650.25803-1-colin.king@canonical.com Addresses-Coverity: ("Unused value") Signed-off-by: Colin Ian King Signed-off-by: Martin K. Petersen --- drivers/scsi/qedi/qedi_main.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/drivers/scsi/qedi/qedi_main.c b/drivers/scsi/qedi/qedi_main.c index 47ad64b06623..faf77808a3a7 100644 --- a/drivers/scsi/qedi/qedi_main.c +++ b/drivers/scsi/qedi/qedi_main.c @@ -276,10 +276,8 @@ static int qedi_alloc_uio_rings(struct qedi_ctx *qedi) } udev = kzalloc(sizeof(*udev), GFP_KERNEL); - if (!udev) { - rc = -ENOMEM; + if (!udev) goto err_udev; - } udev->uio_dev = -1; From 6bfe9855daa3e952faca691dbb2895c523c81b36 Mon Sep 17 00:00:00 2001 From: Wan Jiabing Date: Thu, 25 Mar 2021 14:46:31 +0800 Subject: [PATCH 267/412] scsi: core: scsi_host_cmd_pool is declared twice struct scsi_host_cmd_pool has already been declared. Remove the duplicate. Link: https://lore.kernel.org/r/20210325064632.855002-1-wanjiabing@vivo.com Signed-off-by: Wan Jiabing Signed-off-by: Martin K. Petersen --- include/scsi/scsi_host.h | 1 - 1 file changed, 1 deletion(-) diff --git a/include/scsi/scsi_host.h b/include/scsi/scsi_host.h index d95c1502e17d..3f3ebfdedeb2 100644 --- a/include/scsi/scsi_host.h +++ b/include/scsi/scsi_host.h @@ -19,7 +19,6 @@ struct scsi_device; struct scsi_host_cmd_pool; struct scsi_target; struct Scsi_Host; -struct scsi_host_cmd_pool; struct scsi_transport_template; From 92b4c52c43e1309368bc858a56b4e5d6db159d99 Mon Sep 17 00:00:00 2001 From: Colin Ian King Date: Thu, 25 Mar 2021 17:07:31 +0000 Subject: [PATCH 268/412] scsi: a100u2w: Remove unused variable biosaddr The variable biosaddr is being assigned a value that is never read, the variable is redundant and can be safely removed. Link: https://lore.kernel.org/r/20210325170731.484651-1-colin.king@canonical.com Addresses-Coverity: ("Unused value") Signed-off-by: Colin Ian King Signed-off-by: Martin K. Petersen --- drivers/scsi/a100u2w.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/drivers/scsi/a100u2w.c b/drivers/scsi/a100u2w.c index c9ed210d77b3..028af6b1057c 100644 --- a/drivers/scsi/a100u2w.c +++ b/drivers/scsi/a100u2w.c @@ -1088,7 +1088,6 @@ static int inia100_probe_one(struct pci_dev *pdev, unsigned long port, bios; int error = -ENODEV; u32 sz; - unsigned long biosaddr; if (pci_enable_device(pdev)) goto out; @@ -1138,8 +1137,6 @@ static int inia100_probe_one(struct pci_dev *pdev, goto out_free_scb_array; } - biosaddr = host->BIOScfg; - biosaddr = (biosaddr << 4); if (init_orchid(host)) { /* Initialize orchid chip */ printk("inia100: initial orchid fail!!\n"); goto out_free_escb_array; From ce0b6e38877258a5a8f2f583b53957d4a778da36 Mon Sep 17 00:00:00 2001 From: ganjisheng Date: Fri, 26 Mar 2021 11:04:12 +0800 Subject: [PATCH 269/412] scsi: advansys: Fix spelling of 'is' s/isi/is/ Link: https://lore.kernel.org/r/20210326030412.1656-1-qiumibaozi_1@163.com Signed-off-by: ganjisheng Signed-off-by: Martin K. Petersen --- drivers/scsi/advansys.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/scsi/advansys.c b/drivers/scsi/advansys.c index ec5627890809..e9516de8c18b 100644 --- a/drivers/scsi/advansys.c +++ b/drivers/scsi/advansys.c @@ -1812,7 +1812,7 @@ typedef struct adv_req { * Field naming convention: * * *_able indicates both whether a feature should be enabled or disabled - * and whether a device isi capable of the feature. At initialization + * and whether a device is capable of the feature. At initialization * this field may be set, but later if a device is found to be incapable * of the feature, the field is cleared. */ From 182ad87c95e7fded2134e5aae170b7074bd778c6 Mon Sep 17 00:00:00 2001 From: Shixin Liu Date: Sat, 27 Mar 2021 15:31:56 +0800 Subject: [PATCH 270/412] scsi: myrb: Make symbols DAC960_{LA/PG/PD/P}_privdata static This symbol is not used outside of myrb.c, so we can mark it static. Link: https://lore.kernel.org/r/20210327073156.1786722-1-liushixin2@huawei.com Signed-off-by: Shixin Liu Signed-off-by: Martin K. Petersen --- drivers/scsi/myrb.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/scsi/myrb.c b/drivers/scsi/myrb.c index d469a4889777..56767f8610d4 100644 --- a/drivers/scsi/myrb.c +++ b/drivers/scsi/myrb.c @@ -2809,7 +2809,7 @@ static irqreturn_t DAC960_LA_intr_handler(int irq, void *arg) return IRQ_HANDLED; } -struct myrb_privdata DAC960_LA_privdata = { +static struct myrb_privdata DAC960_LA_privdata = { .hw_init = DAC960_LA_hw_init, .irq_handler = DAC960_LA_intr_handler, .mmio_size = DAC960_LA_mmio_size, @@ -3085,7 +3085,7 @@ static irqreturn_t DAC960_PG_intr_handler(int irq, void *arg) return IRQ_HANDLED; } -struct myrb_privdata DAC960_PG_privdata = { +static struct myrb_privdata DAC960_PG_privdata = { .hw_init = DAC960_PG_hw_init, .irq_handler = DAC960_PG_intr_handler, .mmio_size = DAC960_PG_mmio_size, @@ -3288,7 +3288,7 @@ static irqreturn_t DAC960_PD_intr_handler(int irq, void *arg) return IRQ_HANDLED; } -struct myrb_privdata DAC960_PD_privdata = { +static struct myrb_privdata DAC960_PD_privdata = { .hw_init = DAC960_PD_hw_init, .irq_handler = DAC960_PD_intr_handler, .mmio_size = DAC960_PD_mmio_size, @@ -3486,7 +3486,7 @@ static irqreturn_t DAC960_P_intr_handler(int irq, void *arg) return IRQ_HANDLED; } -struct myrb_privdata DAC960_P_privdata = { +static struct myrb_privdata DAC960_P_privdata = { .hw_init = DAC960_P_hw_init, .irq_handler = DAC960_P_intr_handler, .mmio_size = DAC960_PD_mmio_size, From e27f3c88e2500556b2f1f0ed134a2a4834f88ba3 Mon Sep 17 00:00:00 2001 From: Shixin Liu Date: Sat, 27 Mar 2021 15:31:57 +0800 Subject: [PATCH 271/412] scsi: myrs: Make symbols DAC960_{GEM/BA/LP}_privdata static This symbol is not used outside of myrs.c, so we can mark it static. Link: https://lore.kernel.org/r/20210327073157.1786772-1-liushixin2@huawei.com Signed-off-by: Shixin Liu Signed-off-by: Martin K. Petersen --- drivers/scsi/myrs.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/scsi/myrs.c b/drivers/scsi/myrs.c index 588c0de006b0..3d55208db3ba 100644 --- a/drivers/scsi/myrs.c +++ b/drivers/scsi/myrs.c @@ -2656,7 +2656,7 @@ static irqreturn_t DAC960_GEM_intr_handler(int irq, void *arg) return IRQ_HANDLED; } -struct myrs_privdata DAC960_GEM_privdata = { +static struct myrs_privdata DAC960_GEM_privdata = { .hw_init = DAC960_GEM_hw_init, .irq_handler = DAC960_GEM_intr_handler, .mmio_size = DAC960_GEM_mmio_size, @@ -2906,7 +2906,7 @@ static irqreturn_t DAC960_BA_intr_handler(int irq, void *arg) return IRQ_HANDLED; } -struct myrs_privdata DAC960_BA_privdata = { +static struct myrs_privdata DAC960_BA_privdata = { .hw_init = DAC960_BA_hw_init, .irq_handler = DAC960_BA_intr_handler, .mmio_size = DAC960_BA_mmio_size, @@ -3156,7 +3156,7 @@ static irqreturn_t DAC960_LP_intr_handler(int irq, void *arg) return IRQ_HANDLED; } -struct myrs_privdata DAC960_LP_privdata = { +static struct myrs_privdata DAC960_LP_privdata = { .hw_init = DAC960_LP_hw_init, .irq_handler = DAC960_LP_intr_handler, .mmio_size = DAC960_LP_mmio_size, From 6c26379def094f9f5ae35caf90a58dc1a6bf80e1 Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Mon, 22 Mar 2021 11:25:43 +0100 Subject: [PATCH 272/412] scsi: aic94xx: Avoid -Wempty-body warning Building with 'make W=1' shows a harmless -Wempty-body warning: drivers/scsi/aic94xx/aic94xx_init.c: In function 'asd_free_queues': drivers/scsi/aic94xx/aic94xx_init.c:858:62: error: suggest braces around empty body in an 'if' statement [-Werror=empty-body] 858 | ASD_DPRINTK("Uh-oh! Pending is not empty!\n"); Change the empty ASD_DPRINTK() macro to no_printk(), which avoids this warning and adds format string checking. Link: https://lore.kernel.org/r/20210322102549.278661-1-arnd@kernel.org Signed-off-by: Arnd Bergmann Signed-off-by: Martin K. Petersen --- drivers/scsi/aic94xx/aic94xx.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/scsi/aic94xx/aic94xx.h b/drivers/scsi/aic94xx/aic94xx.h index 98978bc199ff..8f24180646c2 100644 --- a/drivers/scsi/aic94xx/aic94xx.h +++ b/drivers/scsi/aic94xx/aic94xx.h @@ -33,7 +33,7 @@ #ifdef ASD_DEBUG #define ASD_DPRINTK asd_printk #else -#define ASD_DPRINTK(fmt, ...) +#define ASD_DPRINTK(fmt, ...) no_printk(fmt, ##__VA_ARGS__) #endif /* 2*ITNL timeout + 1 second */ From 472c1cfb10f19ff7d2ea477f462fd52d0d2e126b Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Mon, 22 Mar 2021 11:25:44 +0100 Subject: [PATCH 273/412] scsi: message: fusion: Avoid -Wempty-body warnings There are a couple of warnings in this driver when building with W=1: drivers/message/fusion/mptbase.c: In function 'PrimeIocFifos': drivers/message/fusion/mptbase.c:4608:65: error: suggest braces around empty body in an 'if' statement [-Werror=empty-body] 4608 | "restoring 64 bit addressing\n", ioc->name)); | ^ drivers/message/fusion/mptbase.c:4633:65: error: suggest braces around empty body in an 'if' statement [-Werror=empty-body] 4633 | "restoring 64 bit addressing\n", ioc->name)); The macros are slightly suboptimal since are not proper statements. Change both versions to the usual "do { ... } while (0)" style to make them more robust and avoid the warning. Link: https://lore.kernel.org/r/20210322102549.278661-2-arnd@kernel.org Signed-off-by: Arnd Bergmann Signed-off-by: Martin K. Petersen --- drivers/message/fusion/mptdebug.h | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/drivers/message/fusion/mptdebug.h b/drivers/message/fusion/mptdebug.h index 2205dcab0adb..c281b1359419 100644 --- a/drivers/message/fusion/mptdebug.h +++ b/drivers/message/fusion/mptdebug.h @@ -67,12 +67,13 @@ #ifdef CONFIG_FUSION_LOGGING #define MPT_CHECK_LOGGING(IOC, CMD, BITS) \ -{ \ +do { \ if (IOC->debug_level & BITS) \ CMD; \ -} +} while (0) #else -#define MPT_CHECK_LOGGING(IOC, CMD, BITS) +#define MPT_CHECK_LOGGING(IOC, CMD, BITS) \ +do { } while (0) #endif From ae3645d29d4e5f496206ee571d0c8361bd38e242 Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Mon, 22 Mar 2021 11:33:09 +0100 Subject: [PATCH 274/412] scsi: mvsas: Avoid -Wempty-body warning Building with 'make W=1' shows a few harmless -Wempty-body warning for the mvsas driver: drivers/scsi/mvsas/mv_94xx.c: In function 'mvs_94xx_phy_reset': drivers/scsi/mvsas/mv_94xx.c:278:63: error: suggest braces around empty body in an 'if' statement [-Werror=empty-body] 278 | mv_dprintk("phy hard reset failed.\n"); | ^ drivers/scsi/mvsas/mv_sas.c: In function 'mvs_task_prep': drivers/scsi/mvsas/mv_sas.c:723:57: error: suggest braces around empty body in an 'else' statement [-Werror=empty-body] 723 | SAS_ADDR(dev->sas_addr)); | ^ Change the empty dprintk() macros to no_printk(), which avoids this warning and adds format string checking. Link: https://lore.kernel.org/r/20210322103316.620694-1-arnd@kernel.org Signed-off-by: Arnd Bergmann Signed-off-by: Martin K. Petersen --- drivers/scsi/mvsas/mv_sas.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/scsi/mvsas/mv_sas.h b/drivers/scsi/mvsas/mv_sas.h index 327fdd5ee962..8ff976c9967e 100644 --- a/drivers/scsi/mvsas/mv_sas.h +++ b/drivers/scsi/mvsas/mv_sas.h @@ -40,7 +40,7 @@ #define mv_dprintk(format, arg...) \ printk(KERN_DEBUG"%s %d:" format, __FILE__, __LINE__, ## arg) #else -#define mv_dprintk(format, arg...) +#define mv_dprintk(format, arg...) no_printk(format, ## arg) #endif #define MV_MAX_U32 0xffffffff From ada48ba70f6b98b7e93eea56770d6e6932734783 Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Mon, 22 Mar 2021 17:02:47 +0100 Subject: [PATCH 275/412] scsi: lpfc: Fix gcc -Wstringop-overread warning gcc-11 warns about an strnlen with a length larger than the size of the passed buffer: drivers/scsi/lpfc/lpfc_attr.c: In function 'lpfc_nvme_info_show': drivers/scsi/lpfc/lpfc_attr.c:518:25: error: 'strnlen' specified bound 4095 exceeds source size 24 [-Werror=stringop-overread] 518 | strnlen(LPFC_NVME_INFO_MORE_STR, PAGE_SIZE - 1) | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ In this case, the code is entirely valid, as the string is properly terminated, and the size argument is only there out of extra caution in case it exceeds a page. This cannot really happen here, so just simplify it to a sizeof(). Link: https://lore.kernel.org/r/20210322160253.4032422-10-arnd@kernel.org Fixes: afff0d2321ea ("scsi: lpfc: Add Buffer overflow check, when nvme_info larger than PAGE_SIZE") Signed-off-by: Arnd Bergmann Signed-off-by: Martin K. Petersen --- drivers/scsi/lpfc/lpfc_attr.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/drivers/scsi/lpfc/lpfc_attr.c b/drivers/scsi/lpfc/lpfc_attr.c index 8b4c42016865..59ca32d850e3 100644 --- a/drivers/scsi/lpfc/lpfc_attr.c +++ b/drivers/scsi/lpfc/lpfc_attr.c @@ -512,11 +512,9 @@ lpfc_nvme_info_show(struct device *dev, struct device_attribute *attr, "6314 Catching potential buffer " "overflow > PAGE_SIZE = %lu bytes\n", PAGE_SIZE); - strlcpy(buf + PAGE_SIZE - 1 - - strnlen(LPFC_NVME_INFO_MORE_STR, PAGE_SIZE - 1), + strlcpy(buf + PAGE_SIZE - 1 - sizeof(LPFC_NVME_INFO_MORE_STR), LPFC_NVME_INFO_MORE_STR, - strnlen(LPFC_NVME_INFO_MORE_STR, PAGE_SIZE - 1) - + 1); + sizeof(LPFC_NVME_INFO_MORE_STR) + 1); } return len; From 5b11c9d80bde81f6896cc85b23aeaa9502a704ed Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Mon, 22 Mar 2021 17:46:59 +0100 Subject: [PATCH 276/412] scsi: fcoe: Fix mismatched fcoe_wwn_from_mac declaration MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit An old cleanup changed the array size from MAX_ADDR_LEN to unspecified in the declaration, but now gcc-11 warns about this: drivers/scsi/fcoe/fcoe_ctlr.c:1972:37: error: argument 1 of type ‘unsigned char[32]’ with mismatched bound [-Werror=array-parameter=] 1972 | u64 fcoe_wwn_from_mac(unsigned char mac[MAX_ADDR_LEN], | ~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~ In file included from /git/arm-soc/drivers/scsi/fcoe/fcoe_ctlr.c:33: include/scsi/libfcoe.h:252:37: note: previously declared as ‘unsigned char[]’ 252 | u64 fcoe_wwn_from_mac(unsigned char mac[], unsigned int, unsigned int); | ~~~~~~~~~~~~~~^~~~~ Change the type back to what the function definition uses. Link: https://lore.kernel.org/r/20210322164702.957810-1-arnd@kernel.org Fixes: fdd78027fd47 ("[SCSI] fcoe: cleans up libfcoe.h and adds fcoe.h for fcoe module") Signed-off-by: Arnd Bergmann Signed-off-by: Martin K. Petersen --- include/scsi/libfcoe.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/scsi/libfcoe.h b/include/scsi/libfcoe.h index 2568cb0627ec..fac8e89aed81 100644 --- a/include/scsi/libfcoe.h +++ b/include/scsi/libfcoe.h @@ -249,7 +249,7 @@ int fcoe_ctlr_recv_flogi(struct fcoe_ctlr *, struct fc_lport *, struct fc_frame *); /* libfcoe funcs */ -u64 fcoe_wwn_from_mac(unsigned char mac[], unsigned int, unsigned int); +u64 fcoe_wwn_from_mac(unsigned char mac[MAX_ADDR_LEN], unsigned int, unsigned int); int fcoe_libfc_config(struct fc_lport *, struct fcoe_ctlr *, const struct libfc_function_template *, int init_fcp); u32 fcoe_fc_crc(struct fc_frame *fp); From ed46ccc7fe7612eb3763346dc0389d8206f071ef Mon Sep 17 00:00:00 2001 From: "Gustavo A. R. Silva" Date: Wed, 24 Mar 2021 18:00:36 -0500 Subject: [PATCH 277/412] scsi: message: fusion: Replace one-element array with flexible-array member MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit There is a regular need in the kernel to provide a way to declare having a dynamically sized set of trailing elements in a structure. Kernel code should always use "flexible array members"[1] for these cases. The older style of one-element or zero-length arrays should no longer be used[2]. Also, this helps with the ongoing efforts to enable -Warray-bounds by fixing the following warning: drivers/message/fusion/mptbase.c: In function ‘mptbase_reply’: drivers/message/fusion/mptbase.c:7747:62: warning: array subscript 1 is above array bounds of ‘U32[1]’ {aka ‘unsigned int[1]’} [-Warray-bounds] 7747 | ioc->events[idx].data[ii] = le32_to_cpu(pEventReply->Data[ii]); ./include/uapi/linux/byteorder/little_endian.h:34:51: note: in definition of macro ‘__le32_to_cpu’ 34 | #define __le32_to_cpu(x) ((__force __u32)(__le32)(x)) | ^ drivers/message/fusion/mptbase.c:7747:33: note: in expansion of macro ‘le32_to_cpu’ 7747 | ioc->events[idx].data[ii] = le32_to_cpu(pEventReply->Data[ii]); | [1] https://en.wikipedia.org/wiki/Flexible_array_member [2] https://www.kernel.org/doc/html/v5.10/process/deprecated.html#zero-length-and-one-element-arrays Link: https://github.com/KSPP/linux/issues/79 Link: https://github.com/KSPP/linux/issues/109 Link: https://lore.kernel.org/r/20210324230036.GA67851@embeddedor Signed-off-by: Gustavo A. R. Silva Signed-off-by: Martin K. Petersen --- drivers/message/fusion/lsi/mpi_ioc.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/message/fusion/lsi/mpi_ioc.h b/drivers/message/fusion/lsi/mpi_ioc.h index c249f2994fc1..1534460fd5b1 100644 --- a/drivers/message/fusion/lsi/mpi_ioc.h +++ b/drivers/message/fusion/lsi/mpi_ioc.h @@ -448,7 +448,7 @@ typedef struct _MSG_EVENT_NOTIFY_REPLY U32 IOCLogInfo; /* 10h */ U32 Event; /* 14h */ U32 EventContext; /* 18h */ - U32 Data[1]; /* 1Ch */ + U32 Data[]; /* 1Ch */ } MSG_EVENT_NOTIFY_REPLY, MPI_POINTER PTR_MSG_EVENT_NOTIFY_REPLY, EventNotificationReply_t, MPI_POINTER pEventNotificationReply_t; From 4e2e619f3c9e3c49859f085995554a53e9fc0e02 Mon Sep 17 00:00:00 2001 From: "Gustavo A. R. Silva" Date: Wed, 24 Mar 2021 18:33:44 -0500 Subject: [PATCH 278/412] scsi: message: mptlan: Replace one-element array with flexible-array member MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit There is a regular need in the kernel to provide a way to declare having a dynamically sized set of trailing elements in a structure. Kernel code should always use "flexible array members"[1] for these cases. The older style of one-element or zero-length arrays should no longer be used[2]. Refactor the code according to the use of a flexible-array member in struct _SGE_TRANSACTION32 instead of one-element array. Also, this helps with the ongoing efforts to enable -Warray-bounds by fixing the following warning: CC [M] drivers/message/fusion/mptlan.o drivers/message/fusion/mptlan.c: In function ‘mpt_lan_sdu_send’: drivers/message/fusion/mptlan.c:759:28: warning: array subscript 1 is above array bounds of ‘U32[1]’ {aka ‘unsigned int[1]’} [-Warray-bounds] 759 | pTrans->TransactionDetails[1] = cpu_to_le32((mac[2] << 24) | | ~~~~~~~~~~~~~~~~~~~~~~~~~~^~~ [1] https://en.wikipedia.org/wiki/Flexible_array_member [2] https://www.kernel.org/doc/html/v5.10/process/deprecated.html#zero-length-and-one-element-arrays Link: https://github.com/KSPP/linux/issues/79 Link: https://github.com/KSPP/linux/issues/109 Link: https://lore.kernel.org/r/20210324233344.GA99059@embeddedor Signed-off-by: Gustavo A. R. Silva Signed-off-by: Martin K. Petersen --- drivers/message/fusion/lsi/mpi.h | 4 ++-- drivers/message/fusion/mptlan.c | 9 +++------ 2 files changed, 5 insertions(+), 8 deletions(-) diff --git a/drivers/message/fusion/lsi/mpi.h b/drivers/message/fusion/lsi/mpi.h index a575545d681f..eccbe54d43f3 100644 --- a/drivers/message/fusion/lsi/mpi.h +++ b/drivers/message/fusion/lsi/mpi.h @@ -424,8 +424,8 @@ typedef struct _SGE_TRANSACTION32 U8 ContextSize; U8 DetailsLength; U8 Flags; - U32 TransactionContext[1]; - U32 TransactionDetails[1]; + U32 TransactionContext; + U32 TransactionDetails[]; } SGE_TRANSACTION32, MPI_POINTER PTR_SGE_TRANSACTION32, SGETransaction32_t, MPI_POINTER pSGETransaction32_t; diff --git a/drivers/message/fusion/mptlan.c b/drivers/message/fusion/mptlan.c index 7d3784aa20e5..3261cac762de 100644 --- a/drivers/message/fusion/mptlan.c +++ b/drivers/message/fusion/mptlan.c @@ -72,9 +72,6 @@ MODULE_VERSION(my_VERSION); #define MPT_LAN_RECEIVE_POST_REQUEST_SIZE \ (sizeof(LANReceivePostRequest_t) - sizeof(SGE_MPI_UNION)) -#define MPT_LAN_TRANSACTION32_SIZE \ - (sizeof(SGETransaction32_t) - sizeof(u32)) - /* * Fusion MPT LAN private structures */ @@ -745,7 +742,7 @@ mpt_lan_sdu_send (struct sk_buff *skb, struct net_device *dev) pTrans->ContextSize = sizeof(u32); pTrans->DetailsLength = 2 * sizeof(u32); pTrans->Flags = 0; - pTrans->TransactionContext[0] = cpu_to_le32(ctx); + pTrans->TransactionContext = cpu_to_le32(ctx); // dioprintk((KERN_INFO MYNAM ": %s/%s: BC = %08x, skb = %p, buff = %p\n", // IOC_AND_NETDEV_NAMES_s_s(dev), @@ -1159,7 +1156,7 @@ mpt_lan_post_receive_buckets(struct mpt_lan_priv *priv) __func__, buckets, curr)); max = (mpt_dev->req_sz - MPT_LAN_RECEIVE_POST_REQUEST_SIZE) / - (MPT_LAN_TRANSACTION32_SIZE + sizeof(SGESimple64_t)); + (sizeof(SGETransaction32_t) + sizeof(SGESimple64_t)); while (buckets) { mf = mpt_get_msg_frame(LanCtx, mpt_dev); @@ -1234,7 +1231,7 @@ mpt_lan_post_receive_buckets(struct mpt_lan_priv *priv) pTrans->ContextSize = sizeof(u32); pTrans->DetailsLength = 0; pTrans->Flags = 0; - pTrans->TransactionContext[0] = cpu_to_le32(ctx); + pTrans->TransactionContext = cpu_to_le32(ctx); pSimple = (SGESimple64_t *) pTrans->TransactionDetails; From c6d3ee209b9e863c6251f72101511340451ca324 Mon Sep 17 00:00:00 2001 From: Don Brace Date: Thu, 11 Mar 2021 14:14:57 -0600 Subject: [PATCH 279/412] scsi: smartpqi: Use host-wide tag space Correct SCSI midlayer sending more requests than exposed host queue depth causing firmware ASSERT and lockup issues by enabling host-wide tags. Note: This also results in better performance. Link: https://lore.kernel.org/r/161549369787.25025.8975999483518581619.stgit@brunhilda Suggested-by: Ming Lei Suggested-by: John Garry Reviewed-by: Scott Benesh Reviewed-by: Scott Teel Reviewed-by: Mike McGowen Reviewed-by: Kevin Barnett Signed-off-by: Don Brace Signed-off-by: Martin K. Petersen --- drivers/scsi/smartpqi/smartpqi_init.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/scsi/smartpqi/smartpqi_init.c b/drivers/scsi/smartpqi/smartpqi_init.c index c53f456fbd09..61e3a5afaf07 100644 --- a/drivers/scsi/smartpqi/smartpqi_init.c +++ b/drivers/scsi/smartpqi/smartpqi_init.c @@ -6599,6 +6599,7 @@ static int pqi_register_scsi(struct pqi_ctrl_info *ctrl_info) shost->irq = pci_irq_vector(ctrl_info->pci_dev, 0); shost->unique_id = shost->irq; shost->nr_hw_queues = ctrl_info->num_queue_groups; + shost->host_tagset = 1; shost->hostdata[0] = (unsigned long)ctrl_info; rc = scsi_add_host(shost, &ctrl_info->pci_dev->dev); From b622a601a13ae5974c5b0aeecb990c224b8db0d9 Mon Sep 17 00:00:00 2001 From: Murthy Bhat Date: Thu, 11 Mar 2021 14:15:03 -0600 Subject: [PATCH 280/412] scsi: smartpqi: Correct request leakage during reset operations While failing queued I/Os in TMF path, there was a request leak and hence stale entries in request pool with ref count being non-zero. In shutdown path we have a BUG_ON to catch stuck I/O either in firmware or in the driver. The stale requests caused a system crash. The I/O request pool leakage also lead to a significant performance drop. Link: https://lore.kernel.org/r/161549370379.25025.12793264112620796062.stgit@brunhilda Reviewed-by: Scott Teel Reviewed-by: Scott Benesh Reviewed-by: Kevin Barnett Signed-off-by: Murthy Bhat Signed-off-by: Don Brace Signed-off-by: Martin K. Petersen --- drivers/scsi/smartpqi/smartpqi_init.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/drivers/scsi/smartpqi/smartpqi_init.c b/drivers/scsi/smartpqi/smartpqi_init.c index 61e3a5afaf07..4533085c4de6 100644 --- a/drivers/scsi/smartpqi/smartpqi_init.c +++ b/drivers/scsi/smartpqi/smartpqi_init.c @@ -5489,6 +5489,8 @@ static void pqi_fail_io_queued_for_device(struct pqi_ctrl_info *ctrl_info, list_del(&io_request->request_list_entry); set_host_byte(scmd, DID_RESET); + pqi_free_io_request(io_request); + scsi_dma_unmap(scmd); pqi_scsi_done(scmd); } @@ -5525,6 +5527,8 @@ static void pqi_fail_io_queued_for_all_devices(struct pqi_ctrl_info *ctrl_info) list_del(&io_request->request_list_entry); set_host_byte(scmd, DID_RESET); + pqi_free_io_request(io_request); + scsi_dma_unmap(scmd); pqi_scsi_done(scmd); } From 2708a25643abaf24b7edb553afd09a1eb5d4081f Mon Sep 17 00:00:00 2001 From: Kevin Barnett Date: Thu, 11 Mar 2021 14:15:09 -0600 Subject: [PATCH 281/412] scsi: smartpqi: Add support for new product ids Add support for newer hardware by adding in a product identifier. This identifier can then be used to check for the hardware generation. Link: https://lore.kernel.org/r/161549370966.25025.2968242206975557607.stgit@brunhilda Reviewed-by: Scott Benesh Reviewed-by: Mike McGowen Reviewed-by: Scott Teel Reviewed-by: Martin Wilck Signed-off-by: Kevin Barnett Signed-off-by: Don Brace Signed-off-by: Martin K. Petersen --- drivers/scsi/smartpqi/smartpqi.h | 11 ++++++++++- drivers/scsi/smartpqi/smartpqi_init.c | 7 +++++++ drivers/scsi/smartpqi/smartpqi_sis.c | 5 +++++ drivers/scsi/smartpqi/smartpqi_sis.h | 1 + 4 files changed, 23 insertions(+), 1 deletion(-) diff --git a/drivers/scsi/smartpqi/smartpqi.h b/drivers/scsi/smartpqi/smartpqi.h index 3e54590e6e92..7d3f956e949f 100644 --- a/drivers/scsi/smartpqi/smartpqi.h +++ b/drivers/scsi/smartpqi/smartpqi.h @@ -79,7 +79,8 @@ struct pqi_ctrl_registers { __le32 sis_ctrl_to_host_doorbell_clear; /* A0h */ u8 reserved4[0xb0 - (0xa0 + sizeof(__le32))]; __le32 sis_driver_scratch; /* B0h */ - u8 reserved5[0xbc - (0xb0 + sizeof(__le32))]; + __le32 sis_product_identifier; /* B4h */ + u8 reserved5[0xbc - (0xb4 + sizeof(__le32))]; __le32 sis_firmware_status; /* BCh */ u8 reserved6[0x1000 - (0xbc + sizeof(__le32))]; __le32 sis_mailbox[8]; /* 1000h */ @@ -585,6 +586,7 @@ struct pqi_raid_error_info { /* these values are defined by the PQI spec */ #define PQI_MAX_NUM_ELEMENTS_ADMIN_QUEUE 255 #define PQI_MAX_NUM_ELEMENTS_OPERATIONAL_QUEUE 65535 + #define PQI_QUEUE_ELEMENT_ARRAY_ALIGNMENT 64 #define PQI_QUEUE_ELEMENT_LENGTH_ALIGNMENT 16 #define PQI_ADMIN_INDEX_ALIGNMENT 64 @@ -1082,6 +1084,11 @@ struct pqi_event { (PQI_RESERVED_IO_SLOTS_LUN_RESET + PQI_RESERVED_IO_SLOTS_EVENT_ACK + \ PQI_RESERVED_IO_SLOTS_SYNCHRONOUS_REQUESTS) +#define PQI_CTRL_PRODUCT_ID_GEN1 0 +#define PQI_CTRL_PRODUCT_ID_GEN2 7 +#define PQI_CTRL_PRODUCT_REVISION_A 0 +#define PQI_CTRL_PRODUCT_REVISION_B 1 + struct pqi_ctrl_info { unsigned int ctrl_id; struct pci_dev *pci_dev; @@ -1089,6 +1096,8 @@ struct pqi_ctrl_info { char serial_number[17]; char model[17]; char vendor[9]; + u8 product_id; + u8 product_revision; void __iomem *iomem_base; struct pqi_ctrl_registers __iomem *registers; struct pqi_device_registers __iomem *pqi_registers; diff --git a/drivers/scsi/smartpqi/smartpqi_init.c b/drivers/scsi/smartpqi/smartpqi_init.c index 4533085c4de6..f388ef36cb3f 100644 --- a/drivers/scsi/smartpqi/smartpqi_init.c +++ b/drivers/scsi/smartpqi/smartpqi_init.c @@ -7151,6 +7151,7 @@ static int pqi_force_sis_mode(struct pqi_ctrl_info *ctrl_info) static int pqi_ctrl_init(struct pqi_ctrl_info *ctrl_info) { int rc; + u32 product_id; if (reset_devices) { sis_soft_reset(ctrl_info); @@ -7187,6 +7188,10 @@ static int pqi_ctrl_init(struct pqi_ctrl_info *ctrl_info) return rc; } + product_id = sis_get_product_id(ctrl_info); + ctrl_info->product_id = (u8)product_id; + ctrl_info->product_revision = (u8)(product_id >> 8); + if (reset_devices) { if (ctrl_info->max_outstanding_requests > PQI_MAX_OUTSTANDING_REQUESTS_KDUMP) @@ -8607,6 +8612,8 @@ static void __attribute__((unused)) verify_structures(void) sis_ctrl_to_host_doorbell_clear) != 0xa0); BUILD_BUG_ON(offsetof(struct pqi_ctrl_registers, sis_driver_scratch) != 0xb0); + BUILD_BUG_ON(offsetof(struct pqi_ctrl_registers, + sis_product_identifier) != 0xb4); BUILD_BUG_ON(offsetof(struct pqi_ctrl_registers, sis_firmware_status) != 0xbc); BUILD_BUG_ON(offsetof(struct pqi_ctrl_registers, diff --git a/drivers/scsi/smartpqi/smartpqi_sis.c b/drivers/scsi/smartpqi/smartpqi_sis.c index 26ea6b9d4199..f0199bd87dd1 100644 --- a/drivers/scsi/smartpqi/smartpqi_sis.c +++ b/drivers/scsi/smartpqi/smartpqi_sis.c @@ -149,6 +149,11 @@ bool sis_is_kernel_up(struct pqi_ctrl_info *ctrl_info) SIS_CTRL_KERNEL_UP; } +u32 sis_get_product_id(struct pqi_ctrl_info *ctrl_info) +{ + return readl(&ctrl_info->registers->sis_product_identifier); +} + /* used for passing command parameters/results when issuing SIS commands */ struct sis_sync_cmd_params { u32 mailbox[6]; /* mailboxes 0-5 */ diff --git a/drivers/scsi/smartpqi/smartpqi_sis.h b/drivers/scsi/smartpqi/smartpqi_sis.h index 878d34ca6532..12cd2ab1aead 100644 --- a/drivers/scsi/smartpqi/smartpqi_sis.h +++ b/drivers/scsi/smartpqi/smartpqi_sis.h @@ -27,5 +27,6 @@ int sis_reenable_sis_mode(struct pqi_ctrl_info *ctrl_info); void sis_write_driver_scratch(struct pqi_ctrl_info *ctrl_info, u32 value); u32 sis_read_driver_scratch(struct pqi_ctrl_info *ctrl_info); void sis_soft_reset(struct pqi_ctrl_info *ctrl_info); +u32 sis_get_product_id(struct pqi_ctrl_info *ctrl_info); #endif /* _SMARTPQI_SIS_H */ From 281a817f232e2f580665e8a45fce1a43899d3007 Mon Sep 17 00:00:00 2001 From: Don Brace Date: Thu, 11 Mar 2021 14:15:15 -0600 Subject: [PATCH 282/412] scsi: smartpqi: Refactor aio submission code Refactor aio submission code: 1. Break up function pqi_raid_bypass_submit_scsi_cmd() into smaller functions. 2. Add common block (rmd - raid_map_data) to carry around into newly added functions. 3. Prepare for new AIO functionality. No functional changes. Link: https://lore.kernel.org/r/161549371553.25025.8840958689316611074.stgit@brunhilda Reviewed-by: Scott Benesh Reviewed-by: Mike McGowen Reviewed-by: Scott Teel Reviewed-by: Kevin Barnett Reviewed-by: Martin Wilck Signed-off-by: Don Brace Signed-off-by: Martin K. Petersen --- drivers/scsi/smartpqi/smartpqi.h | 52 +++ drivers/scsi/smartpqi/smartpqi_init.c | 572 ++++++++++++++------------ 2 files changed, 369 insertions(+), 255 deletions(-) diff --git a/drivers/scsi/smartpqi/smartpqi.h b/drivers/scsi/smartpqi/smartpqi.h index 7d3f956e949f..01e18da139e3 100644 --- a/drivers/scsi/smartpqi/smartpqi.h +++ b/drivers/scsi/smartpqi/smartpqi.h @@ -908,6 +908,58 @@ struct raid_map { #pragma pack() +struct pqi_scsi_dev_raid_map_data { + bool is_write; + u8 raid_level; + u32 map_index; + u64 first_block; + u64 last_block; + u32 data_length; + u32 block_cnt; + u32 blocks_per_row; + u64 first_row; + u64 last_row; + u32 first_row_offset; + u32 last_row_offset; + u32 first_column; + u32 last_column; + u64 r5or6_first_row; + u64 r5or6_last_row; + u32 r5or6_first_row_offset; + u32 r5or6_last_row_offset; + u32 r5or6_first_column; + u32 r5or6_last_column; + u16 data_disks_per_row; + u32 total_disks_per_row; + u16 layout_map_count; + u32 stripesize; + u16 strip_size; + u32 first_group; + u32 last_group; + u32 current_group; + u32 map_row; + u32 aio_handle; + u64 disk_block; + u32 disk_block_cnt; + u8 cdb[16]; + u8 cdb_length; + int offload_to_mirror; + + /* RAID1 specific */ +#define NUM_RAID1_MAP_ENTRIES 3 + u32 num_it_nexus_entries; + u32 it_nexus[NUM_RAID1_MAP_ENTRIES]; + + /* RAID5 RAID6 specific */ + u32 p_parity_it_nexus; /* aio_handle */ + u32 q_parity_it_nexus; /* aio_handle */ + u8 xor_mult; + u64 row; + u64 stripe_lba; + u32 p_index; + u32 q_index; +}; + #define RAID_CTLR_LUNID "\0\0\0\0\0\0\0\0" struct pqi_scsi_dev { diff --git a/drivers/scsi/smartpqi/smartpqi_init.c b/drivers/scsi/smartpqi/smartpqi_init.c index f388ef36cb3f..c895d32952c1 100644 --- a/drivers/scsi/smartpqi/smartpqi_init.c +++ b/drivers/scsi/smartpqi/smartpqi_init.c @@ -2237,332 +2237,394 @@ static inline void pqi_set_encryption_info( * Attempt to perform RAID bypass mapping for a logical volume I/O. */ +static bool pqi_aio_raid_level_supported(struct pqi_scsi_dev_raid_map_data *rmd) +{ + bool is_supported = true; + + switch (rmd->raid_level) { + case SA_RAID_0: + break; + case SA_RAID_1: + if (rmd->is_write) + is_supported = false; + break; + case SA_RAID_5: + fallthrough; + case SA_RAID_6: + if (rmd->is_write) + is_supported = false; + break; + case SA_RAID_ADM: + if (rmd->is_write) + is_supported = false; + break; + default: + is_supported = false; + } + + return is_supported; +} + #define PQI_RAID_BYPASS_INELIGIBLE 1 -static int pqi_raid_bypass_submit_scsi_cmd(struct pqi_ctrl_info *ctrl_info, - struct pqi_scsi_dev *device, struct scsi_cmnd *scmd, - struct pqi_queue_group *queue_group) +static int pqi_get_aio_lba_and_block_count(struct scsi_cmnd *scmd, + struct pqi_scsi_dev_raid_map_data *rmd) { - struct raid_map *raid_map; - bool is_write = false; - u32 map_index; - u64 first_block; - u64 last_block; - u32 block_cnt; - u32 blocks_per_row; - u64 first_row; - u64 last_row; - u32 first_row_offset; - u32 last_row_offset; - u32 first_column; - u32 last_column; - u64 r0_first_row; - u64 r0_last_row; - u32 r5or6_blocks_per_row; - u64 r5or6_first_row; - u64 r5or6_last_row; - u32 r5or6_first_row_offset; - u32 r5or6_last_row_offset; - u32 r5or6_first_column; - u32 r5or6_last_column; - u16 data_disks_per_row; - u32 total_disks_per_row; - u16 layout_map_count; - u32 stripesize; - u16 strip_size; - u32 first_group; - u32 last_group; - u32 current_group; - u32 map_row; - u32 aio_handle; - u64 disk_block; - u32 disk_block_cnt; - u8 cdb[16]; - u8 cdb_length; - int offload_to_mirror; - struct pqi_encryption_info *encryption_info_ptr; - struct pqi_encryption_info encryption_info; -#if BITS_PER_LONG == 32 - u64 tmpdiv; -#endif - /* Check for valid opcode, get LBA and block count. */ switch (scmd->cmnd[0]) { case WRITE_6: - is_write = true; + rmd->is_write = true; fallthrough; case READ_6: - first_block = (u64)(((scmd->cmnd[1] & 0x1f) << 16) | + rmd->first_block = (u64)(((scmd->cmnd[1] & 0x1f) << 16) | (scmd->cmnd[2] << 8) | scmd->cmnd[3]); - block_cnt = (u32)scmd->cmnd[4]; - if (block_cnt == 0) - block_cnt = 256; + rmd->block_cnt = (u32)scmd->cmnd[4]; + if (rmd->block_cnt == 0) + rmd->block_cnt = 256; break; case WRITE_10: - is_write = true; + rmd->is_write = true; fallthrough; case READ_10: - first_block = (u64)get_unaligned_be32(&scmd->cmnd[2]); - block_cnt = (u32)get_unaligned_be16(&scmd->cmnd[7]); + rmd->first_block = (u64)get_unaligned_be32(&scmd->cmnd[2]); + rmd->block_cnt = (u32)get_unaligned_be16(&scmd->cmnd[7]); break; case WRITE_12: - is_write = true; + rmd->is_write = true; fallthrough; case READ_12: - first_block = (u64)get_unaligned_be32(&scmd->cmnd[2]); - block_cnt = get_unaligned_be32(&scmd->cmnd[6]); + rmd->first_block = (u64)get_unaligned_be32(&scmd->cmnd[2]); + rmd->block_cnt = get_unaligned_be32(&scmd->cmnd[6]); break; case WRITE_16: - is_write = true; + rmd->is_write = true; fallthrough; case READ_16: - first_block = get_unaligned_be64(&scmd->cmnd[2]); - block_cnt = get_unaligned_be32(&scmd->cmnd[10]); + rmd->first_block = get_unaligned_be64(&scmd->cmnd[2]); + rmd->block_cnt = get_unaligned_be32(&scmd->cmnd[10]); break; default: /* Process via normal I/O path. */ return PQI_RAID_BYPASS_INELIGIBLE; } - /* Check for write to non-RAID-0. */ - if (is_write && device->raid_level != SA_RAID_0) - return PQI_RAID_BYPASS_INELIGIBLE; + put_unaligned_le32(scsi_bufflen(scmd), &rmd->data_length); - if (unlikely(block_cnt == 0)) - return PQI_RAID_BYPASS_INELIGIBLE; + return 0; +} - last_block = first_block + block_cnt - 1; - raid_map = device->raid_map; +static int pci_get_aio_common_raid_map_values(struct pqi_ctrl_info *ctrl_info, + struct pqi_scsi_dev_raid_map_data *rmd, + struct raid_map *raid_map) +{ +#if BITS_PER_LONG == 32 + u64 tmpdiv; +#endif + + rmd->last_block = rmd->first_block + rmd->block_cnt - 1; /* Check for invalid block or wraparound. */ - if (last_block >= get_unaligned_le64(&raid_map->volume_blk_cnt) || - last_block < first_block) + if (rmd->last_block >= + get_unaligned_le64(&raid_map->volume_blk_cnt) || + rmd->last_block < rmd->first_block) return PQI_RAID_BYPASS_INELIGIBLE; - data_disks_per_row = get_unaligned_le16(&raid_map->data_disks_per_row); - strip_size = get_unaligned_le16(&raid_map->strip_size); - layout_map_count = get_unaligned_le16(&raid_map->layout_map_count); + rmd->data_disks_per_row = + get_unaligned_le16(&raid_map->data_disks_per_row); + rmd->strip_size = get_unaligned_le16(&raid_map->strip_size); + rmd->layout_map_count = get_unaligned_le16(&raid_map->layout_map_count); /* Calculate stripe information for the request. */ - blocks_per_row = data_disks_per_row * strip_size; + rmd->blocks_per_row = rmd->data_disks_per_row * rmd->strip_size; #if BITS_PER_LONG == 32 - tmpdiv = first_block; - do_div(tmpdiv, blocks_per_row); - first_row = tmpdiv; - tmpdiv = last_block; - do_div(tmpdiv, blocks_per_row); - last_row = tmpdiv; - first_row_offset = (u32)(first_block - (first_row * blocks_per_row)); - last_row_offset = (u32)(last_block - (last_row * blocks_per_row)); - tmpdiv = first_row_offset; - do_div(tmpdiv, strip_size); - first_column = tmpdiv; - tmpdiv = last_row_offset; - do_div(tmpdiv, strip_size); - last_column = tmpdiv; + tmpdiv = rmd->first_block; + do_div(tmpdiv, rmd->blocks_per_row); + rmd->first_row = tmpdiv; + tmpdiv = rmd->last_block; + do_div(tmpdiv, rmd->blocks_per_row); + rmd->last_row = tmpdiv; + rmd->first_row_offset = (u32)(rmd->first_block - (rmd->first_row * rmd->blocks_per_row)); + rmd->last_row_offset = (u32)(rmd->last_block - (rmd->last_row * rmd->blocks_per_row)); + tmpdiv = rmd->first_row_offset; + do_div(tmpdiv, rmd->strip_size); + rmd->first_column = tmpdiv; + tmpdiv = rmd->last_row_offset; + do_div(tmpdiv, rmd->strip_size); + rmd->last_column = tmpdiv; #else - first_row = first_block / blocks_per_row; - last_row = last_block / blocks_per_row; - first_row_offset = (u32)(first_block - (first_row * blocks_per_row)); - last_row_offset = (u32)(last_block - (last_row * blocks_per_row)); - first_column = first_row_offset / strip_size; - last_column = last_row_offset / strip_size; + rmd->first_row = rmd->first_block / rmd->blocks_per_row; + rmd->last_row = rmd->last_block / rmd->blocks_per_row; + rmd->first_row_offset = (u32)(rmd->first_block - + (rmd->first_row * rmd->blocks_per_row)); + rmd->last_row_offset = (u32)(rmd->last_block - (rmd->last_row * + rmd->blocks_per_row)); + rmd->first_column = rmd->first_row_offset / rmd->strip_size; + rmd->last_column = rmd->last_row_offset / rmd->strip_size; #endif /* If this isn't a single row/column then give to the controller. */ - if (first_row != last_row || first_column != last_column) + if (rmd->first_row != rmd->last_row || + rmd->first_column != rmd->last_column) return PQI_RAID_BYPASS_INELIGIBLE; /* Proceeding with driver mapping. */ - total_disks_per_row = data_disks_per_row + + rmd->total_disks_per_row = rmd->data_disks_per_row + get_unaligned_le16(&raid_map->metadata_disks_per_row); - map_row = ((u32)(first_row >> raid_map->parity_rotation_shift)) % + rmd->map_row = ((u32)(rmd->first_row >> + raid_map->parity_rotation_shift)) % get_unaligned_le16(&raid_map->row_cnt); - map_index = (map_row * total_disks_per_row) + first_column; + rmd->map_index = (rmd->map_row * rmd->total_disks_per_row) + + rmd->first_column; + + return 0; +} + +static int pqi_calc_aio_raid_adm(struct pqi_scsi_dev_raid_map_data *rmd, + struct pqi_scsi_dev *device) +{ + /* RAID ADM */ + /* + * Handles N-way mirrors (R1-ADM) and R10 with # of drives + * divisible by 3. + */ + rmd->offload_to_mirror = device->offload_to_mirror; + + if (rmd->offload_to_mirror == 0) { + /* use physical disk in the first mirrored group. */ + rmd->map_index %= rmd->data_disks_per_row; + } else { + do { + /* + * Determine mirror group that map_index + * indicates. + */ + rmd->current_group = + rmd->map_index / rmd->data_disks_per_row; + + if (rmd->offload_to_mirror != + rmd->current_group) { + if (rmd->current_group < + rmd->layout_map_count - 1) { + /* + * Select raid index from + * next group. + */ + rmd->map_index += rmd->data_disks_per_row; + rmd->current_group++; + } else { + /* + * Select raid index from first + * group. + */ + rmd->map_index %= rmd->data_disks_per_row; + rmd->current_group = 0; + } + } + } while (rmd->offload_to_mirror != rmd->current_group); + } + + /* Set mirror group to use next time. */ + rmd->offload_to_mirror = + (rmd->offload_to_mirror >= rmd->layout_map_count - 1) ? + 0 : rmd->offload_to_mirror + 1; + device->offload_to_mirror = rmd->offload_to_mirror; + /* + * Avoid direct use of device->offload_to_mirror within this + * function since multiple threads might simultaneously + * increment it beyond the range of device->layout_map_count -1. + */ + + return 0; +} + +static int pqi_calc_aio_r5_or_r6(struct pqi_scsi_dev_raid_map_data *rmd, + struct raid_map *raid_map) +{ +#if BITS_PER_LONG == 32 + u64 tmpdiv; +#endif + /* RAID 50/60 */ + /* Verify first and last block are in same RAID group */ + rmd->stripesize = rmd->blocks_per_row * rmd->layout_map_count; +#if BITS_PER_LONG == 32 + tmpdiv = rmd->first_block; + rmd->first_group = do_div(tmpdiv, rmd->stripesize); + tmpdiv = rmd->first_group; + do_div(tmpdiv, rmd->blocks_per_row); + rmd->first_group = tmpdiv; + tmpdiv = rmd->last_block; + rmd->last_group = do_div(tmpdiv, rmd->stripesize); + tmpdiv = rmd->last_group; + do_div(tmpdiv, rmd->blocks_per_row); + rmd->last_group = tmpdiv; +#else + rmd->first_group = (rmd->first_block % rmd->stripesize) / rmd->blocks_per_row; + rmd->last_group = (rmd->last_block % rmd->stripesize) / rmd->blocks_per_row; +#endif + if (rmd->first_group != rmd->last_group) + return PQI_RAID_BYPASS_INELIGIBLE; + + /* Verify request is in a single row of RAID 5/6 */ +#if BITS_PER_LONG == 32 + tmpdiv = rmd->first_block; + do_div(tmpdiv, rmd->stripesize); + rmd->first_row = tmpdiv; + rmd->r5or6_first_row = tmpdiv; + tmpdiv = rmd->last_block; + do_div(tmpdiv, rmd->stripesize); + rmd->r5or6_last_row = tmpdiv; +#else + rmd->first_row = rmd->r5or6_first_row = + rmd->first_block / rmd->stripesize; + rmd->r5or6_last_row = rmd->last_block / rmd->stripesize; +#endif + if (rmd->r5or6_first_row != rmd->r5or6_last_row) + return PQI_RAID_BYPASS_INELIGIBLE; + + /* Verify request is in a single column */ +#if BITS_PER_LONG == 32 + tmpdiv = rmd->first_block; + rmd->first_row_offset = do_div(tmpdiv, rmd->stripesize); + tmpdiv = rmd->first_row_offset; + rmd->first_row_offset = (u32)do_div(tmpdiv, rmd->blocks_per_row); + rmd->r5or6_first_row_offset = rmd->first_row_offset; + tmpdiv = rmd->last_block; + rmd->r5or6_last_row_offset = do_div(tmpdiv, rmd->stripesize); + tmpdiv = rmd->r5or6_last_row_offset; + rmd->r5or6_last_row_offset = do_div(tmpdiv, rmd->blocks_per_row); + tmpdiv = rmd->r5or6_first_row_offset; + do_div(tmpdiv, rmd->strip_size); + rmd->first_column = rmd->r5or6_first_column = tmpdiv; + tmpdiv = rmd->r5or6_last_row_offset; + do_div(tmpdiv, rmd->strip_size); + rmd->r5or6_last_column = tmpdiv; +#else + rmd->first_row_offset = rmd->r5or6_first_row_offset = + (u32)((rmd->first_block % + rmd->stripesize) % + rmd->blocks_per_row); + + rmd->r5or6_last_row_offset = + (u32)((rmd->last_block % rmd->stripesize) % + rmd->blocks_per_row); + + rmd->first_column = + rmd->r5or6_first_row_offset / rmd->strip_size; + rmd->r5or6_first_column = rmd->first_column; + rmd->r5or6_last_column = rmd->r5or6_last_row_offset / rmd->strip_size; +#endif + if (rmd->r5or6_first_column != rmd->r5or6_last_column) + return PQI_RAID_BYPASS_INELIGIBLE; + + /* Request is eligible */ + rmd->map_row = + ((u32)(rmd->first_row >> raid_map->parity_rotation_shift)) % + get_unaligned_le16(&raid_map->row_cnt); + + rmd->map_index = (rmd->first_group * + (get_unaligned_le16(&raid_map->row_cnt) * + rmd->total_disks_per_row)) + + (rmd->map_row * rmd->total_disks_per_row) + rmd->first_column; + + return 0; +} + +static void pqi_set_aio_cdb(struct pqi_scsi_dev_raid_map_data *rmd) +{ + /* Build the new CDB for the physical disk I/O. */ + if (rmd->disk_block > 0xffffffff) { + rmd->cdb[0] = rmd->is_write ? WRITE_16 : READ_16; + rmd->cdb[1] = 0; + put_unaligned_be64(rmd->disk_block, &rmd->cdb[2]); + put_unaligned_be32(rmd->disk_block_cnt, &rmd->cdb[10]); + rmd->cdb[14] = 0; + rmd->cdb[15] = 0; + rmd->cdb_length = 16; + } else { + rmd->cdb[0] = rmd->is_write ? WRITE_10 : READ_10; + rmd->cdb[1] = 0; + put_unaligned_be32((u32)rmd->disk_block, &rmd->cdb[2]); + rmd->cdb[6] = 0; + put_unaligned_be16((u16)rmd->disk_block_cnt, &rmd->cdb[7]); + rmd->cdb[9] = 0; + rmd->cdb_length = 10; + } +} + +static int pqi_raid_bypass_submit_scsi_cmd(struct pqi_ctrl_info *ctrl_info, + struct pqi_scsi_dev *device, struct scsi_cmnd *scmd, + struct pqi_queue_group *queue_group) +{ + struct raid_map *raid_map; + int rc; + struct pqi_encryption_info *encryption_info_ptr; + struct pqi_encryption_info encryption_info; + struct pqi_scsi_dev_raid_map_data rmd = {0}; + + rc = pqi_get_aio_lba_and_block_count(scmd, &rmd); + if (rc) + return PQI_RAID_BYPASS_INELIGIBLE; + + rmd.raid_level = device->raid_level; + + if (!pqi_aio_raid_level_supported(&rmd)) + return PQI_RAID_BYPASS_INELIGIBLE; + + if (unlikely(rmd.block_cnt == 0)) + return PQI_RAID_BYPASS_INELIGIBLE; + + raid_map = device->raid_map; + + rc = pci_get_aio_common_raid_map_values(ctrl_info, &rmd, raid_map); + if (rc) + return PQI_RAID_BYPASS_INELIGIBLE; /* RAID 1 */ if (device->raid_level == SA_RAID_1) { if (device->offload_to_mirror) - map_index += data_disks_per_row; + rmd.map_index += rmd.data_disks_per_row; device->offload_to_mirror = !device->offload_to_mirror; } else if (device->raid_level == SA_RAID_ADM) { - /* RAID ADM */ - /* - * Handles N-way mirrors (R1-ADM) and R10 with # of drives - * divisible by 3. - */ - offload_to_mirror = device->offload_to_mirror; - if (offload_to_mirror == 0) { - /* use physical disk in the first mirrored group. */ - map_index %= data_disks_per_row; - } else { - do { - /* - * Determine mirror group that map_index - * indicates. - */ - current_group = map_index / data_disks_per_row; - - if (offload_to_mirror != current_group) { - if (current_group < - layout_map_count - 1) { - /* - * Select raid index from - * next group. - */ - map_index += data_disks_per_row; - current_group++; - } else { - /* - * Select raid index from first - * group. - */ - map_index %= data_disks_per_row; - current_group = 0; - } - } - } while (offload_to_mirror != current_group); - } - - /* Set mirror group to use next time. */ - offload_to_mirror = - (offload_to_mirror >= layout_map_count - 1) ? - 0 : offload_to_mirror + 1; - device->offload_to_mirror = offload_to_mirror; - /* - * Avoid direct use of device->offload_to_mirror within this - * function since multiple threads might simultaneously - * increment it beyond the range of device->layout_map_count -1. - */ + rc = pqi_calc_aio_raid_adm(&rmd, device); } else if ((device->raid_level == SA_RAID_5 || - device->raid_level == SA_RAID_6) && layout_map_count > 1) { - /* RAID 50/60 */ - /* Verify first and last block are in same RAID group */ - r5or6_blocks_per_row = strip_size * data_disks_per_row; - stripesize = r5or6_blocks_per_row * layout_map_count; -#if BITS_PER_LONG == 32 - tmpdiv = first_block; - first_group = do_div(tmpdiv, stripesize); - tmpdiv = first_group; - do_div(tmpdiv, r5or6_blocks_per_row); - first_group = tmpdiv; - tmpdiv = last_block; - last_group = do_div(tmpdiv, stripesize); - tmpdiv = last_group; - do_div(tmpdiv, r5or6_blocks_per_row); - last_group = tmpdiv; -#else - first_group = (first_block % stripesize) / r5or6_blocks_per_row; - last_group = (last_block % stripesize) / r5or6_blocks_per_row; -#endif - if (first_group != last_group) + device->raid_level == SA_RAID_6) && rmd.layout_map_count > 1) { + rc = pqi_calc_aio_r5_or_r6(&rmd, raid_map); + if (rc) return PQI_RAID_BYPASS_INELIGIBLE; - - /* Verify request is in a single row of RAID 5/6 */ -#if BITS_PER_LONG == 32 - tmpdiv = first_block; - do_div(tmpdiv, stripesize); - first_row = r5or6_first_row = r0_first_row = tmpdiv; - tmpdiv = last_block; - do_div(tmpdiv, stripesize); - r5or6_last_row = r0_last_row = tmpdiv; -#else - first_row = r5or6_first_row = r0_first_row = - first_block / stripesize; - r5or6_last_row = r0_last_row = last_block / stripesize; -#endif - if (r5or6_first_row != r5or6_last_row) - return PQI_RAID_BYPASS_INELIGIBLE; - - /* Verify request is in a single column */ -#if BITS_PER_LONG == 32 - tmpdiv = first_block; - first_row_offset = do_div(tmpdiv, stripesize); - tmpdiv = first_row_offset; - first_row_offset = (u32)do_div(tmpdiv, r5or6_blocks_per_row); - r5or6_first_row_offset = first_row_offset; - tmpdiv = last_block; - r5or6_last_row_offset = do_div(tmpdiv, stripesize); - tmpdiv = r5or6_last_row_offset; - r5or6_last_row_offset = do_div(tmpdiv, r5or6_blocks_per_row); - tmpdiv = r5or6_first_row_offset; - do_div(tmpdiv, strip_size); - first_column = r5or6_first_column = tmpdiv; - tmpdiv = r5or6_last_row_offset; - do_div(tmpdiv, strip_size); - r5or6_last_column = tmpdiv; -#else - first_row_offset = r5or6_first_row_offset = - (u32)((first_block % stripesize) % - r5or6_blocks_per_row); - - r5or6_last_row_offset = - (u32)((last_block % stripesize) % - r5or6_blocks_per_row); - - first_column = r5or6_first_row_offset / strip_size; - r5or6_first_column = first_column; - r5or6_last_column = r5or6_last_row_offset / strip_size; -#endif - if (r5or6_first_column != r5or6_last_column) - return PQI_RAID_BYPASS_INELIGIBLE; - - /* Request is eligible */ - map_row = - ((u32)(first_row >> raid_map->parity_rotation_shift)) % - get_unaligned_le16(&raid_map->row_cnt); - - map_index = (first_group * - (get_unaligned_le16(&raid_map->row_cnt) * - total_disks_per_row)) + - (map_row * total_disks_per_row) + first_column; } - aio_handle = raid_map->disk_data[map_index].aio_handle; - disk_block = get_unaligned_le64(&raid_map->disk_starting_blk) + - first_row * strip_size + - (first_row_offset - first_column * strip_size); - disk_block_cnt = block_cnt; + if (unlikely(rmd.map_index >= RAID_MAP_MAX_ENTRIES)) + return PQI_RAID_BYPASS_INELIGIBLE; + + rmd.aio_handle = raid_map->disk_data[rmd.map_index].aio_handle; + rmd.disk_block = get_unaligned_le64(&raid_map->disk_starting_blk) + + rmd.first_row * rmd.strip_size + + (rmd.first_row_offset - rmd.first_column * rmd.strip_size); + rmd.disk_block_cnt = rmd.block_cnt; /* Handle differing logical/physical block sizes. */ if (raid_map->phys_blk_shift) { - disk_block <<= raid_map->phys_blk_shift; - disk_block_cnt <<= raid_map->phys_blk_shift; + rmd.disk_block <<= raid_map->phys_blk_shift; + rmd.disk_block_cnt <<= raid_map->phys_blk_shift; } - if (unlikely(disk_block_cnt > 0xffff)) + if (unlikely(rmd.disk_block_cnt > 0xffff)) return PQI_RAID_BYPASS_INELIGIBLE; - /* Build the new CDB for the physical disk I/O. */ - if (disk_block > 0xffffffff) { - cdb[0] = is_write ? WRITE_16 : READ_16; - cdb[1] = 0; - put_unaligned_be64(disk_block, &cdb[2]); - put_unaligned_be32(disk_block_cnt, &cdb[10]); - cdb[14] = 0; - cdb[15] = 0; - cdb_length = 16; - } else { - cdb[0] = is_write ? WRITE_10 : READ_10; - cdb[1] = 0; - put_unaligned_be32((u32)disk_block, &cdb[2]); - cdb[6] = 0; - put_unaligned_be16((u16)disk_block_cnt, &cdb[7]); - cdb[9] = 0; - cdb_length = 10; - } + pqi_set_aio_cdb(&rmd); if (get_unaligned_le16(&raid_map->flags) & RAID_MAP_ENCRYPTION_ENABLED) { pqi_set_encryption_info(&encryption_info, raid_map, - first_block); + rmd.first_block); encryption_info_ptr = &encryption_info; } else { encryption_info_ptr = NULL; } - return pqi_aio_submit_io(ctrl_info, scmd, aio_handle, - cdb, cdb_length, queue_group, encryption_info_ptr, true); + return pqi_aio_submit_io(ctrl_info, scmd, rmd.aio_handle, + rmd.cdb, rmd.cdb_length, queue_group, + encryption_info_ptr, true); } #define PQI_STATUS_IDLE 0x0 From 1a22bc4bee22b15e933ef4c51a426b6f376d336a Mon Sep 17 00:00:00 2001 From: Don Brace Date: Thu, 11 Mar 2021 14:15:21 -0600 Subject: [PATCH 283/412] scsi: smartpqi: Refactor scatterlist code Factor out code common to all scatter-gather list building to prepare for new AIO functionality. AIO (Accelerated I/O) requests go directly to disk No functional changes. Link: https://lore.kernel.org/r/161549372147.25025.9706613054649682229.stgit@brunhilda Reviewed-by: Scott Benesh Reviewed-by: Mike McGowen Reviewed-by: Scott Teel Reviewed-by: Kevin Barnett Reviewed-by: Martin Wilck Signed-off-by: Don Brace Signed-off-by: Martin K. Petersen --- drivers/scsi/smartpqi/smartpqi_init.c | 101 +++++++++++--------------- 1 file changed, 42 insertions(+), 59 deletions(-) diff --git a/drivers/scsi/smartpqi/smartpqi_init.c b/drivers/scsi/smartpqi/smartpqi_init.c index c895d32952c1..0eb8d4744e3d 100644 --- a/drivers/scsi/smartpqi/smartpqi_init.c +++ b/drivers/scsi/smartpqi/smartpqi_init.c @@ -4857,16 +4857,52 @@ static inline void pqi_set_sg_descriptor( put_unaligned_le32(0, &sg_descriptor->flags); } +static unsigned int pqi_build_sg_list(struct pqi_sg_descriptor *sg_descriptor, + struct scatterlist *sg, int sg_count, struct pqi_io_request *io_request, + int max_sg_per_iu, bool *chained) +{ + int i; + unsigned int num_sg_in_iu; + + *chained = false; + i = 0; + num_sg_in_iu = 0; + max_sg_per_iu--; /* Subtract 1 to leave room for chain marker. */ + + while (1) { + pqi_set_sg_descriptor(sg_descriptor, sg); + if (!*chained) + num_sg_in_iu++; + i++; + if (i == sg_count) + break; + sg_descriptor++; + if (i == max_sg_per_iu) { + put_unaligned_le64((u64)io_request->sg_chain_buffer_dma_handle, + &sg_descriptor->address); + put_unaligned_le32((sg_count - num_sg_in_iu) * sizeof(*sg_descriptor), + &sg_descriptor->length); + put_unaligned_le32(CISS_SG_CHAIN, &sg_descriptor->flags); + *chained = true; + num_sg_in_iu++; + sg_descriptor = io_request->sg_chain_buffer; + } + sg = sg_next(sg); + } + + put_unaligned_le32(CISS_SG_LAST, &sg_descriptor->flags); + + return num_sg_in_iu; +} + static int pqi_build_raid_sg_list(struct pqi_ctrl_info *ctrl_info, struct pqi_raid_path_request *request, struct scsi_cmnd *scmd, struct pqi_io_request *io_request) { - int i; u16 iu_length; int sg_count; bool chained; unsigned int num_sg_in_iu; - unsigned int max_sg_per_iu; struct scatterlist *sg; struct pqi_sg_descriptor *sg_descriptor; @@ -4882,36 +4918,10 @@ static int pqi_build_raid_sg_list(struct pqi_ctrl_info *ctrl_info, sg = scsi_sglist(scmd); sg_descriptor = request->sg_descriptors; - max_sg_per_iu = ctrl_info->max_sg_per_iu - 1; - chained = false; - num_sg_in_iu = 0; - i = 0; - while (1) { - pqi_set_sg_descriptor(sg_descriptor, sg); - if (!chained) - num_sg_in_iu++; - i++; - if (i == sg_count) - break; - sg_descriptor++; - if (i == max_sg_per_iu) { - put_unaligned_le64( - (u64)io_request->sg_chain_buffer_dma_handle, - &sg_descriptor->address); - put_unaligned_le32((sg_count - num_sg_in_iu) - * sizeof(*sg_descriptor), - &sg_descriptor->length); - put_unaligned_le32(CISS_SG_CHAIN, - &sg_descriptor->flags); - chained = true; - num_sg_in_iu++; - sg_descriptor = io_request->sg_chain_buffer; - } - sg = sg_next(sg); - } + num_sg_in_iu = pqi_build_sg_list(sg_descriptor, sg, sg_count, io_request, + ctrl_info->max_sg_per_iu, &chained); - put_unaligned_le32(CISS_SG_LAST, &sg_descriptor->flags); request->partial = chained; iu_length += num_sg_in_iu * sizeof(*sg_descriptor); @@ -4925,12 +4935,10 @@ static int pqi_build_aio_sg_list(struct pqi_ctrl_info *ctrl_info, struct pqi_aio_path_request *request, struct scsi_cmnd *scmd, struct pqi_io_request *io_request) { - int i; u16 iu_length; int sg_count; bool chained; unsigned int num_sg_in_iu; - unsigned int max_sg_per_iu; struct scatterlist *sg; struct pqi_sg_descriptor *sg_descriptor; @@ -4947,35 +4955,10 @@ static int pqi_build_aio_sg_list(struct pqi_ctrl_info *ctrl_info, sg = scsi_sglist(scmd); sg_descriptor = request->sg_descriptors; - max_sg_per_iu = ctrl_info->max_sg_per_iu - 1; - chained = false; - i = 0; - while (1) { - pqi_set_sg_descriptor(sg_descriptor, sg); - if (!chained) - num_sg_in_iu++; - i++; - if (i == sg_count) - break; - sg_descriptor++; - if (i == max_sg_per_iu) { - put_unaligned_le64( - (u64)io_request->sg_chain_buffer_dma_handle, - &sg_descriptor->address); - put_unaligned_le32((sg_count - num_sg_in_iu) - * sizeof(*sg_descriptor), - &sg_descriptor->length); - put_unaligned_le32(CISS_SG_CHAIN, - &sg_descriptor->flags); - chained = true; - num_sg_in_iu++; - sg_descriptor = io_request->sg_chain_buffer; - } - sg = sg_next(sg); - } + num_sg_in_iu = pqi_build_sg_list(sg_descriptor, sg, sg_count, io_request, + ctrl_info->max_sg_per_iu, &chained); - put_unaligned_le32(CISS_SG_LAST, &sg_descriptor->flags); request->partial = chained; iu_length += num_sg_in_iu * sizeof(*sg_descriptor); From 6702d2c40f31b200d90614d1b0a841f14ba22ee0 Mon Sep 17 00:00:00 2001 From: Don Brace Date: Thu, 11 Mar 2021 14:15:27 -0600 Subject: [PATCH 284/412] scsi: smartpqi: Add support for RAID5 and RAID6 writes Add in new IU definition and implement support for RAID5 and RAID6 writes. Link: https://lore.kernel.org/r/161549372734.25025.963261942897080281.stgit@brunhilda Reviewed-by: Scott Benesh Reviewed-by: Mike McGowen Reviewed-by: Scott Teel Reviewed-by: Kevin Barnett Signed-off-by: Don Brace Signed-off-by: Martin K. Petersen --- drivers/scsi/smartpqi/smartpqi.h | 37 ++++ drivers/scsi/smartpqi/smartpqi_init.c | 237 +++++++++++++++++++++++++- 2 files changed, 268 insertions(+), 6 deletions(-) diff --git a/drivers/scsi/smartpqi/smartpqi.h b/drivers/scsi/smartpqi/smartpqi.h index 01e18da139e3..a2fd246c8ae8 100644 --- a/drivers/scsi/smartpqi/smartpqi.h +++ b/drivers/scsi/smartpqi/smartpqi.h @@ -257,6 +257,7 @@ struct pqi_device_capability { }; #define PQI_MAX_EMBEDDED_SG_DESCRIPTORS 4 +#define PQI_MAX_EMBEDDED_R56_SG_DESCRIPTORS 3 struct pqi_raid_path_request { struct pqi_iu_header header; @@ -312,6 +313,37 @@ struct pqi_aio_path_request { sg_descriptors[PQI_MAX_EMBEDDED_SG_DESCRIPTORS]; }; +struct pqi_aio_r56_path_request { + struct pqi_iu_header header; + __le16 request_id; + __le16 volume_id; /* ID of the RAID volume */ + __le32 data_it_nexus; /* IT nexus for the data drive */ + __le32 p_parity_it_nexus; /* IT nexus for the P parity drive */ + __le32 q_parity_it_nexus; /* IT nexus for the Q parity drive */ + __le32 data_length; /* total bytes to read/write */ + u8 data_direction : 2; + u8 partial : 1; + u8 mem_type : 1; /* 0 = PCIe, 1 = DDR */ + u8 fence : 1; + u8 encryption_enable : 1; + u8 reserved : 2; + u8 task_attribute : 3; + u8 command_priority : 4; + u8 reserved1 : 1; + __le16 data_encryption_key_index; + u8 cdb[16]; + __le16 error_index; + u8 num_sg_descriptors; + u8 cdb_length; + u8 xor_multiplier; + u8 reserved2[3]; + __le32 encrypt_tweak_lower; + __le32 encrypt_tweak_upper; + __le64 row; /* row = logical LBA/blocks per row */ + u8 reserved3[8]; + struct pqi_sg_descriptor sg_descriptors[PQI_MAX_EMBEDDED_R56_SG_DESCRIPTORS]; +}; + struct pqi_io_response { struct pqi_iu_header header; __le16 request_id; @@ -484,6 +516,8 @@ struct pqi_raid_error_info { #define PQI_REQUEST_IU_TASK_MANAGEMENT 0x13 #define PQI_REQUEST_IU_RAID_PATH_IO 0x14 #define PQI_REQUEST_IU_AIO_PATH_IO 0x15 +#define PQI_REQUEST_IU_AIO_PATH_RAID5_IO 0x18 +#define PQI_REQUEST_IU_AIO_PATH_RAID6_IO 0x19 #define PQI_REQUEST_IU_GENERAL_ADMIN 0x60 #define PQI_REQUEST_IU_REPORT_VENDOR_EVENT_CONFIG 0x72 #define PQI_REQUEST_IU_SET_VENDOR_EVENT_CONFIG 0x73 @@ -1179,6 +1213,7 @@ struct pqi_ctrl_info { u16 max_inbound_iu_length_per_firmware; u16 max_inbound_iu_length; unsigned int max_sg_per_iu; + unsigned int max_sg_per_r56_iu; void *admin_queue_memory_base; u32 admin_queue_memory_length; dma_addr_t admin_queue_memory_base_dma_handle; @@ -1210,6 +1245,8 @@ struct pqi_ctrl_info { u8 soft_reset_handshake_supported : 1; u8 raid_iu_timeout_supported: 1; u8 tmf_iu_timeout_supported: 1; + u8 enable_r5_writes : 1; + u8 enable_r6_writes : 1; struct list_head scsi_device_list; spinlock_t scsi_device_list_lock; diff --git a/drivers/scsi/smartpqi/smartpqi_init.c b/drivers/scsi/smartpqi/smartpqi_init.c index 0eb8d4744e3d..17b697022473 100644 --- a/drivers/scsi/smartpqi/smartpqi_init.c +++ b/drivers/scsi/smartpqi/smartpqi_init.c @@ -67,6 +67,10 @@ static int pqi_aio_submit_io(struct pqi_ctrl_info *ctrl_info, struct scsi_cmnd *scmd, u32 aio_handle, u8 *cdb, unsigned int cdb_length, struct pqi_queue_group *queue_group, struct pqi_encryption_info *encryption_info, bool raid_bypass); +static int pqi_aio_submit_r56_write_io(struct pqi_ctrl_info *ctrl_info, + struct scsi_cmnd *scmd, struct pqi_queue_group *queue_group, + struct pqi_encryption_info *encryption_info, struct pqi_scsi_dev *device, + struct pqi_scsi_dev_raid_map_data *rmd); static void pqi_ofa_ctrl_quiesce(struct pqi_ctrl_info *ctrl_info); static void pqi_ofa_ctrl_unquiesce(struct pqi_ctrl_info *ctrl_info); static int pqi_ofa_ctrl_restart(struct pqi_ctrl_info *ctrl_info); @@ -2237,7 +2241,8 @@ static inline void pqi_set_encryption_info( * Attempt to perform RAID bypass mapping for a logical volume I/O. */ -static bool pqi_aio_raid_level_supported(struct pqi_scsi_dev_raid_map_data *rmd) +static bool pqi_aio_raid_level_supported(struct pqi_ctrl_info *ctrl_info, + struct pqi_scsi_dev_raid_map_data *rmd) { bool is_supported = true; @@ -2249,9 +2254,11 @@ static bool pqi_aio_raid_level_supported(struct pqi_scsi_dev_raid_map_data *rmd) is_supported = false; break; case SA_RAID_5: - fallthrough; + if (rmd->is_write && !ctrl_info->enable_r5_writes) + is_supported = false; + break; case SA_RAID_6: - if (rmd->is_write) + if (rmd->is_write && !ctrl_info->enable_r6_writes) is_supported = false; break; case SA_RAID_ADM: @@ -2526,6 +2533,38 @@ static int pqi_calc_aio_r5_or_r6(struct pqi_scsi_dev_raid_map_data *rmd, rmd->total_disks_per_row)) + (rmd->map_row * rmd->total_disks_per_row) + rmd->first_column; + if (rmd->is_write) { + u32 index; + + /* + * p_parity_it_nexus and q_parity_it_nexus are pointers to the + * parity entries inside the device's raid_map. + * + * A device's RAID map is bounded by: number of RAID disks squared. + * + * The devices RAID map size is checked during device + * initialization. + */ + index = DIV_ROUND_UP(rmd->map_index + 1, rmd->total_disks_per_row); + index *= rmd->total_disks_per_row; + index -= get_unaligned_le16(&raid_map->metadata_disks_per_row); + + rmd->p_parity_it_nexus = raid_map->disk_data[index].aio_handle; + if (rmd->raid_level == SA_RAID_6) { + rmd->q_parity_it_nexus = raid_map->disk_data[index + 1].aio_handle; + rmd->xor_mult = raid_map->disk_data[rmd->map_index].xor_mult[1]; + } + if (rmd->blocks_per_row == 0) + return PQI_RAID_BYPASS_INELIGIBLE; +#if BITS_PER_LONG == 32 + tmpdiv = rmd->first_block; + do_div(tmpdiv, rmd->blocks_per_row); + rmd->row = tmpdiv; +#else + rmd->row = rmd->first_block / rmd->blocks_per_row; +#endif + } + return 0; } @@ -2567,7 +2606,7 @@ static int pqi_raid_bypass_submit_scsi_cmd(struct pqi_ctrl_info *ctrl_info, rmd.raid_level = device->raid_level; - if (!pqi_aio_raid_level_supported(&rmd)) + if (!pqi_aio_raid_level_supported(ctrl_info, &rmd)) return PQI_RAID_BYPASS_INELIGIBLE; if (unlikely(rmd.block_cnt == 0)) @@ -2587,7 +2626,8 @@ static int pqi_raid_bypass_submit_scsi_cmd(struct pqi_ctrl_info *ctrl_info, } else if (device->raid_level == SA_RAID_ADM) { rc = pqi_calc_aio_raid_adm(&rmd, device); } else if ((device->raid_level == SA_RAID_5 || - device->raid_level == SA_RAID_6) && rmd.layout_map_count > 1) { + device->raid_level == SA_RAID_6) && + (rmd.layout_map_count > 1 || rmd.is_write)) { rc = pqi_calc_aio_r5_or_r6(&rmd, raid_map); if (rc) return PQI_RAID_BYPASS_INELIGIBLE; @@ -2622,9 +2662,27 @@ static int pqi_raid_bypass_submit_scsi_cmd(struct pqi_ctrl_info *ctrl_info, encryption_info_ptr = NULL; } - return pqi_aio_submit_io(ctrl_info, scmd, rmd.aio_handle, + if (rmd.is_write) { + switch (device->raid_level) { + case SA_RAID_0: + return pqi_aio_submit_io(ctrl_info, scmd, rmd.aio_handle, rmd.cdb, rmd.cdb_length, queue_group, encryption_info_ptr, true); + case SA_RAID_5: + case SA_RAID_6: + return pqi_aio_submit_r56_write_io(ctrl_info, scmd, queue_group, + encryption_info_ptr, device, &rmd); + default: + return pqi_aio_submit_io(ctrl_info, scmd, rmd.aio_handle, + rmd.cdb, rmd.cdb_length, queue_group, + encryption_info_ptr, true); + } + } else { + return pqi_aio_submit_io(ctrl_info, scmd, rmd.aio_handle, + rmd.cdb, rmd.cdb_length, queue_group, + encryption_info_ptr, true); + } + } #define PQI_STATUS_IDLE 0x0 @@ -4844,6 +4902,12 @@ static void pqi_calculate_queue_resources(struct pqi_ctrl_info *ctrl_info) PQI_OPERATIONAL_IQ_ELEMENT_LENGTH) / sizeof(struct pqi_sg_descriptor)) + PQI_MAX_EMBEDDED_SG_DESCRIPTORS; + + ctrl_info->max_sg_per_r56_iu = + ((ctrl_info->max_inbound_iu_length - + PQI_OPERATIONAL_IQ_ELEMENT_LENGTH) / + sizeof(struct pqi_sg_descriptor)) + + PQI_MAX_EMBEDDED_R56_SG_DESCRIPTORS; } static inline void pqi_set_sg_descriptor( @@ -4931,6 +4995,42 @@ out: return 0; } +static int pqi_build_aio_r56_sg_list(struct pqi_ctrl_info *ctrl_info, + struct pqi_aio_r56_path_request *request, struct scsi_cmnd *scmd, + struct pqi_io_request *io_request) +{ + u16 iu_length; + int sg_count; + bool chained; + unsigned int num_sg_in_iu; + struct scatterlist *sg; + struct pqi_sg_descriptor *sg_descriptor; + + sg_count = scsi_dma_map(scmd); + if (sg_count < 0) + return sg_count; + + iu_length = offsetof(struct pqi_aio_r56_path_request, sg_descriptors) - + PQI_REQUEST_HEADER_LENGTH; + num_sg_in_iu = 0; + + if (sg_count != 0) { + sg = scsi_sglist(scmd); + sg_descriptor = request->sg_descriptors; + + num_sg_in_iu = pqi_build_sg_list(sg_descriptor, sg, sg_count, io_request, + ctrl_info->max_sg_per_r56_iu, &chained); + + request->partial = chained; + iu_length += num_sg_in_iu * sizeof(*sg_descriptor); + } + + put_unaligned_le16(iu_length, &request->header.iu_length); + request->num_sg_descriptors = num_sg_in_iu; + + return 0; +} + static int pqi_build_aio_sg_list(struct pqi_ctrl_info *ctrl_info, struct pqi_aio_path_request *request, struct scsi_cmnd *scmd, struct pqi_io_request *io_request) @@ -5335,6 +5435,71 @@ static int pqi_aio_submit_io(struct pqi_ctrl_info *ctrl_info, return 0; } +static int pqi_aio_submit_r56_write_io(struct pqi_ctrl_info *ctrl_info, + struct scsi_cmnd *scmd, struct pqi_queue_group *queue_group, + struct pqi_encryption_info *encryption_info, struct pqi_scsi_dev *device, + struct pqi_scsi_dev_raid_map_data *rmd) +{ + int rc; + struct pqi_io_request *io_request; + struct pqi_aio_r56_path_request *r56_request; + + io_request = pqi_alloc_io_request(ctrl_info); + io_request->io_complete_callback = pqi_aio_io_complete; + io_request->scmd = scmd; + io_request->raid_bypass = true; + + r56_request = io_request->iu; + memset(r56_request, 0, offsetof(struct pqi_aio_r56_path_request, sg_descriptors)); + + if (device->raid_level == SA_RAID_5 || device->raid_level == SA_RAID_51) + r56_request->header.iu_type = PQI_REQUEST_IU_AIO_PATH_RAID5_IO; + else + r56_request->header.iu_type = PQI_REQUEST_IU_AIO_PATH_RAID6_IO; + + put_unaligned_le16(*(u16 *)device->scsi3addr & 0x3fff, &r56_request->volume_id); + put_unaligned_le32(rmd->aio_handle, &r56_request->data_it_nexus); + put_unaligned_le32(rmd->p_parity_it_nexus, &r56_request->p_parity_it_nexus); + if (rmd->raid_level == SA_RAID_6) { + put_unaligned_le32(rmd->q_parity_it_nexus, &r56_request->q_parity_it_nexus); + r56_request->xor_multiplier = rmd->xor_mult; + } + put_unaligned_le32(scsi_bufflen(scmd), &r56_request->data_length); + r56_request->task_attribute = SOP_TASK_ATTRIBUTE_SIMPLE; + put_unaligned_le64(rmd->row, &r56_request->row); + + put_unaligned_le16(io_request->index, &r56_request->request_id); + r56_request->error_index = r56_request->request_id; + + if (rmd->cdb_length > sizeof(r56_request->cdb)) + rmd->cdb_length = sizeof(r56_request->cdb); + r56_request->cdb_length = rmd->cdb_length; + memcpy(r56_request->cdb, rmd->cdb, rmd->cdb_length); + + /* The direction is always write. */ + r56_request->data_direction = SOP_READ_FLAG; + + if (encryption_info) { + r56_request->encryption_enable = true; + put_unaligned_le16(encryption_info->data_encryption_key_index, + &r56_request->data_encryption_key_index); + put_unaligned_le32(encryption_info->encrypt_tweak_lower, + &r56_request->encrypt_tweak_lower); + put_unaligned_le32(encryption_info->encrypt_tweak_upper, + &r56_request->encrypt_tweak_upper); + } + + rc = pqi_build_aio_r56_sg_list(ctrl_info, r56_request, scmd, io_request); + if (rc) { + pqi_free_io_request(io_request); + return SCSI_MLQUEUE_HOST_BUSY; + } + + pqi_start_io(ctrl_info, queue_group, AIO_PATH, io_request); + + return 0; +} + static inline u16 pqi_get_hw_queue(struct pqi_ctrl_info *ctrl_info, struct scsi_cmnd *scmd) { @@ -6302,6 +6467,60 @@ static ssize_t pqi_lockup_action_store(struct device *dev, return -EINVAL; } +static ssize_t pqi_host_enable_r5_writes_show(struct device *dev, + struct device_attribute *attr, char *buffer) +{ + struct Scsi_Host *shost = class_to_shost(dev); + struct pqi_ctrl_info *ctrl_info = shost_to_hba(shost); + + return scnprintf(buffer, 10, "%x\n", ctrl_info->enable_r5_writes); +} + +static ssize_t pqi_host_enable_r5_writes_store(struct device *dev, + struct device_attribute *attr, const char *buffer, size_t count) +{ + struct Scsi_Host *shost = class_to_shost(dev); + struct pqi_ctrl_info *ctrl_info = shost_to_hba(shost); + u8 set_r5_writes = 0; + + if (kstrtou8(buffer, 0, &set_r5_writes)) + return -EINVAL; + + if (set_r5_writes > 0) + set_r5_writes = 1; + + ctrl_info->enable_r5_writes = set_r5_writes; + + return count; +} + +static ssize_t pqi_host_enable_r6_writes_show(struct device *dev, + struct device_attribute *attr, char *buffer) +{ + struct Scsi_Host *shost = class_to_shost(dev); + struct pqi_ctrl_info *ctrl_info = shost_to_hba(shost); + + return scnprintf(buffer, 10, "%x\n", ctrl_info->enable_r6_writes); +} + +static ssize_t pqi_host_enable_r6_writes_store(struct device *dev, + struct device_attribute *attr, const char *buffer, size_t count) +{ + struct Scsi_Host *shost = class_to_shost(dev); + struct pqi_ctrl_info *ctrl_info = shost_to_hba(shost); + u8 set_r6_writes = 0; + + if (kstrtou8(buffer, 0, &set_r6_writes)) + return -EINVAL; + + if (set_r6_writes > 0) + set_r6_writes = 1; + + ctrl_info->enable_r6_writes = set_r6_writes; + + return count; +} + static DEVICE_ATTR(driver_version, 0444, pqi_driver_version_show, NULL); static DEVICE_ATTR(firmware_version, 0444, pqi_firmware_version_show, NULL); static DEVICE_ATTR(model, 0444, pqi_model_show, NULL); @@ -6310,6 +6529,10 @@ static DEVICE_ATTR(vendor, 0444, pqi_vendor_show, NULL); static DEVICE_ATTR(rescan, 0200, NULL, pqi_host_rescan_store); static DEVICE_ATTR(lockup_action, 0644, pqi_lockup_action_show, pqi_lockup_action_store); +static DEVICE_ATTR(enable_r5_writes, 0644, + pqi_host_enable_r5_writes_show, pqi_host_enable_r5_writes_store); +static DEVICE_ATTR(enable_r6_writes, 0644, + pqi_host_enable_r6_writes_show, pqi_host_enable_r6_writes_store); static struct device_attribute *pqi_shost_attrs[] = { &dev_attr_driver_version, @@ -6319,6 +6542,8 @@ static struct device_attribute *pqi_shost_attrs[] = { &dev_attr_vendor, &dev_attr_rescan, &dev_attr_lockup_action, + &dev_attr_enable_r5_writes, + &dev_attr_enable_r6_writes, NULL }; From 7a012c23c7a7d9cdc7b6db0e8837f8a413dbe436 Mon Sep 17 00:00:00 2001 From: Don Brace Date: Thu, 11 Mar 2021 14:15:33 -0600 Subject: [PATCH 285/412] scsi: smartpqi: Add support for RAID1 writes Add RAID1 write IU and implement RAID1 write support. Change brand names ADM/ADG to TRIPLE/RAID-6. Link: https://lore.kernel.org/r/161549373324.25025.2441592111049564780.stgit@brunhilda Reviewed-by: Scott Benesh Reviewed-by: Scott Teel Reviewed-by: Kevin Barnett Signed-off-by: Don Brace Signed-off-by: Martin K. Petersen --- drivers/scsi/smartpqi/smartpqi.h | 37 ++++- drivers/scsi/smartpqi/smartpqi_init.c | 228 +++++++++++++++++--------- 2 files changed, 183 insertions(+), 82 deletions(-) diff --git a/drivers/scsi/smartpqi/smartpqi.h b/drivers/scsi/smartpqi/smartpqi.h index a2fd246c8ae8..bed80c4c4598 100644 --- a/drivers/scsi/smartpqi/smartpqi.h +++ b/drivers/scsi/smartpqi/smartpqi.h @@ -313,6 +313,36 @@ struct pqi_aio_path_request { sg_descriptors[PQI_MAX_EMBEDDED_SG_DESCRIPTORS]; }; +#define PQI_RAID1_NVME_XFER_LIMIT (32 * 1024) /* 32 KiB */ +struct pqi_aio_r1_path_request { + struct pqi_iu_header header; + __le16 request_id; + __le16 volume_id; /* ID of the RAID volume */ + __le32 it_nexus_1; /* IT nexus of the 1st drive in the RAID volume */ + __le32 it_nexus_2; /* IT nexus of the 2nd drive in the RAID volume */ + __le32 it_nexus_3; /* IT nexus of the 3rd drive in the RAID volume */ + __le32 data_length; /* total bytes to read/write */ + u8 data_direction : 2; + u8 partial : 1; + u8 memory_type : 1; + u8 fence : 1; + u8 encryption_enable : 1; + u8 reserved : 2; + u8 task_attribute : 3; + u8 command_priority : 4; + u8 reserved2 : 1; + __le16 data_encryption_key_index; + u8 cdb[16]; + __le16 error_index; + u8 num_sg_descriptors; + u8 cdb_length; + u8 num_drives; /* number of drives in the RAID volume (2 or 3) */ + u8 reserved3[3]; + __le32 encrypt_tweak_lower; + __le32 encrypt_tweak_upper; + struct pqi_sg_descriptor sg_descriptors[PQI_MAX_EMBEDDED_SG_DESCRIPTORS]; +}; + struct pqi_aio_r56_path_request { struct pqi_iu_header header; __le16 request_id; @@ -518,6 +548,7 @@ struct pqi_raid_error_info { #define PQI_REQUEST_IU_AIO_PATH_IO 0x15 #define PQI_REQUEST_IU_AIO_PATH_RAID5_IO 0x18 #define PQI_REQUEST_IU_AIO_PATH_RAID6_IO 0x19 +#define PQI_REQUEST_IU_AIO_PATH_RAID1_IO 0x1A #define PQI_REQUEST_IU_GENERAL_ADMIN 0x60 #define PQI_REQUEST_IU_REPORT_VENDOR_EVENT_CONFIG 0x72 #define PQI_REQUEST_IU_SET_VENDOR_EVENT_CONFIG 0x73 @@ -970,14 +1001,12 @@ struct pqi_scsi_dev_raid_map_data { u16 strip_size; u32 first_group; u32 last_group; - u32 current_group; u32 map_row; u32 aio_handle; u64 disk_block; u32 disk_block_cnt; u8 cdb[16]; u8 cdb_length; - int offload_to_mirror; /* RAID1 specific */ #define NUM_RAID1_MAP_ENTRIES 3 @@ -1038,8 +1067,7 @@ struct pqi_scsi_dev { u16 phys_connector[8]; bool raid_bypass_configured; /* RAID bypass configured */ bool raid_bypass_enabled; /* RAID bypass enabled */ - int offload_to_mirror; /* Send next RAID bypass request */ - /* to mirror drive. */ + u32 next_bypass_group; struct raid_map *raid_map; /* RAID bypass map */ struct pqi_sas_port *sas_port; @@ -1245,6 +1273,7 @@ struct pqi_ctrl_info { u8 soft_reset_handshake_supported : 1; u8 raid_iu_timeout_supported: 1; u8 tmf_iu_timeout_supported: 1; + u8 enable_r1_writes : 1; u8 enable_r5_writes : 1; u8 enable_r6_writes : 1; diff --git a/drivers/scsi/smartpqi/smartpqi_init.c b/drivers/scsi/smartpqi/smartpqi_init.c index 17b697022473..a36861184fc0 100644 --- a/drivers/scsi/smartpqi/smartpqi_init.c +++ b/drivers/scsi/smartpqi/smartpqi_init.c @@ -67,6 +67,10 @@ static int pqi_aio_submit_io(struct pqi_ctrl_info *ctrl_info, struct scsi_cmnd *scmd, u32 aio_handle, u8 *cdb, unsigned int cdb_length, struct pqi_queue_group *queue_group, struct pqi_encryption_info *encryption_info, bool raid_bypass); +static int pqi_aio_submit_r1_write_io(struct pqi_ctrl_info *ctrl_info, + struct scsi_cmnd *scmd, struct pqi_queue_group *queue_group, + struct pqi_encryption_info *encryption_info, struct pqi_scsi_dev *device, + struct pqi_scsi_dev_raid_map_data *rmd); static int pqi_aio_submit_r56_write_io(struct pqi_ctrl_info *ctrl_info, struct scsi_cmnd *scmd, struct pqi_queue_group *queue_group, struct pqi_encryption_info *encryption_info, struct pqi_scsi_dev *device, @@ -167,8 +171,8 @@ static char *raid_levels[] = { "RAID-1(1+0)", "RAID-5", "RAID-5+1", - "RAID-ADG", - "RAID-1(ADM)", + "RAID-6", + "RAID-1(Triple)", }; static char *pqi_raid_level_to_string(u8 raid_level) @@ -185,8 +189,8 @@ static char *pqi_raid_level_to_string(u8 raid_level) #define SA_RAID_5 3 /* also used for RAID 50 */ #define SA_RAID_51 4 #define SA_RAID_6 5 /* also used for RAID 60 */ -#define SA_RAID_ADM 6 /* also used for RAID 1+0 ADM */ -#define SA_RAID_MAX SA_RAID_ADM +#define SA_RAID_TRIPLE 6 /* also used for RAID 1+0 Triple */ +#define SA_RAID_MAX SA_RAID_TRIPLE #define SA_RAID_UNKNOWN 0xff static inline void pqi_scsi_done(struct scsi_cmnd *scmd) @@ -1141,9 +1145,9 @@ static int pqi_validate_raid_map(struct pqi_ctrl_info *ctrl_info, err_msg = "invalid RAID-1 map"; goto bad_raid_map; } - } else if (device->raid_level == SA_RAID_ADM) { + } else if (device->raid_level == SA_RAID_TRIPLE) { if (get_unaligned_le16(&raid_map->layout_map_count) != 3) { - err_msg = "invalid RAID-1(ADM) map"; + err_msg = "invalid RAID-1(Triple) map"; goto bad_raid_map; } } else if ((device->raid_level == SA_RAID_5 || @@ -1717,7 +1721,7 @@ static void pqi_scsi_update_device(struct pqi_scsi_dev *existing_device, sizeof(existing_device->box)); memcpy(existing_device->phys_connector, new_device->phys_connector, sizeof(existing_device->phys_connector)); - existing_device->offload_to_mirror = 0; + existing_device->next_bypass_group = 0; kfree(existing_device->raid_map); existing_device->raid_map = new_device->raid_map; existing_device->raid_bypass_configured = @@ -2250,7 +2254,8 @@ static bool pqi_aio_raid_level_supported(struct pqi_ctrl_info *ctrl_info, case SA_RAID_0: break; case SA_RAID_1: - if (rmd->is_write) + case SA_RAID_TRIPLE: + if (rmd->is_write && !ctrl_info->enable_r1_writes) is_supported = false; break; case SA_RAID_5: @@ -2261,10 +2266,6 @@ static bool pqi_aio_raid_level_supported(struct pqi_ctrl_info *ctrl_info, if (rmd->is_write && !ctrl_info->enable_r6_writes) is_supported = false; break; - case SA_RAID_ADM: - if (rmd->is_write) - is_supported = false; - break; default: is_supported = false; } @@ -2386,64 +2387,6 @@ static int pci_get_aio_common_raid_map_values(struct pqi_ctrl_info *ctrl_info, return 0; } -static int pqi_calc_aio_raid_adm(struct pqi_scsi_dev_raid_map_data *rmd, - struct pqi_scsi_dev *device) -{ - /* RAID ADM */ - /* - * Handles N-way mirrors (R1-ADM) and R10 with # of drives - * divisible by 3. - */ - rmd->offload_to_mirror = device->offload_to_mirror; - - if (rmd->offload_to_mirror == 0) { - /* use physical disk in the first mirrored group. */ - rmd->map_index %= rmd->data_disks_per_row; - } else { - do { - /* - * Determine mirror group that map_index - * indicates. - */ - rmd->current_group = - rmd->map_index / rmd->data_disks_per_row; - - if (rmd->offload_to_mirror != - rmd->current_group) { - if (rmd->current_group < - rmd->layout_map_count - 1) { - /* - * Select raid index from - * next group. - */ - rmd->map_index += rmd->data_disks_per_row; - rmd->current_group++; - } else { - /* - * Select raid index from first - * group. - */ - rmd->map_index %= rmd->data_disks_per_row; - rmd->current_group = 0; - } - } - } while (rmd->offload_to_mirror != rmd->current_group); - } - - /* Set mirror group to use next time. */ - rmd->offload_to_mirror = - (rmd->offload_to_mirror >= rmd->layout_map_count - 1) ? - 0 : rmd->offload_to_mirror + 1; - device->offload_to_mirror = rmd->offload_to_mirror; - /* - * Avoid direct use of device->offload_to_mirror within this - * function since multiple threads might simultaneously - * increment it beyond the range of device->layout_map_count -1. - */ - - return 0; -} - static int pqi_calc_aio_r5_or_r6(struct pqi_scsi_dev_raid_map_data *rmd, struct raid_map *raid_map) { @@ -2590,12 +2533,34 @@ static void pqi_set_aio_cdb(struct pqi_scsi_dev_raid_map_data *rmd) } } +static void pqi_calc_aio_r1_nexus(struct raid_map *raid_map, + struct pqi_scsi_dev_raid_map_data *rmd) +{ + u32 index; + u32 group; + + group = rmd->map_index / rmd->data_disks_per_row; + + index = rmd->map_index - (group * rmd->data_disks_per_row); + rmd->it_nexus[0] = raid_map->disk_data[index].aio_handle; + index += rmd->data_disks_per_row; + rmd->it_nexus[1] = raid_map->disk_data[index].aio_handle; + if (rmd->layout_map_count > 2) { + index += rmd->data_disks_per_row; + rmd->it_nexus[2] = raid_map->disk_data[index].aio_handle; + } + + rmd->num_it_nexus_entries = rmd->layout_map_count; +} + static int pqi_raid_bypass_submit_scsi_cmd(struct pqi_ctrl_info *ctrl_info, struct pqi_scsi_dev *device, struct scsi_cmnd *scmd, struct pqi_queue_group *queue_group) { - struct raid_map *raid_map; int rc; + struct raid_map *raid_map; + u32 group; + u32 next_bypass_group; struct pqi_encryption_info *encryption_info_ptr; struct pqi_encryption_info encryption_info; struct pqi_scsi_dev_raid_map_data rmd = {0}; @@ -2618,13 +2583,18 @@ static int pqi_raid_bypass_submit_scsi_cmd(struct pqi_ctrl_info *ctrl_info, if (rc) return PQI_RAID_BYPASS_INELIGIBLE; - /* RAID 1 */ - if (device->raid_level == SA_RAID_1) { - if (device->offload_to_mirror) - rmd.map_index += rmd.data_disks_per_row; - device->offload_to_mirror = !device->offload_to_mirror; - } else if (device->raid_level == SA_RAID_ADM) { - rc = pqi_calc_aio_raid_adm(&rmd, device); + if (device->raid_level == SA_RAID_1 || + device->raid_level == SA_RAID_TRIPLE) { + if (rmd.is_write) { + pqi_calc_aio_r1_nexus(raid_map, &rmd); + } else { + group = device->next_bypass_group; + next_bypass_group = group + 1; + if (next_bypass_group >= rmd.layout_map_count) + next_bypass_group = 0; + device->next_bypass_group = next_bypass_group; + rmd.map_index += group * rmd.data_disks_per_row; + } } else if ((device->raid_level == SA_RAID_5 || device->raid_level == SA_RAID_6) && (rmd.layout_map_count > 1 || rmd.is_write)) { @@ -2668,6 +2638,10 @@ static int pqi_raid_bypass_submit_scsi_cmd(struct pqi_ctrl_info *ctrl_info, return pqi_aio_submit_io(ctrl_info, scmd, rmd.aio_handle, rmd.cdb, rmd.cdb_length, queue_group, encryption_info_ptr, true); + case SA_RAID_1: + case SA_RAID_TRIPLE: + return pqi_aio_submit_r1_write_io(ctrl_info, scmd, queue_group, + encryption_info_ptr, device, &rmd); case SA_RAID_5: case SA_RAID_6: return pqi_aio_submit_r56_write_io(ctrl_info, scmd, queue_group, @@ -4995,6 +4969,44 @@ out: return 0; } +static int pqi_build_aio_r1_sg_list(struct pqi_ctrl_info *ctrl_info, + struct pqi_aio_r1_path_request *request, struct scsi_cmnd *scmd, + struct pqi_io_request *io_request) +{ + u16 iu_length; + int sg_count; + bool chained; + unsigned int num_sg_in_iu; + struct scatterlist *sg; + struct pqi_sg_descriptor *sg_descriptor; + + sg_count = scsi_dma_map(scmd); + if (sg_count < 0) + return sg_count; + + iu_length = offsetof(struct pqi_aio_r1_path_request, sg_descriptors) - + PQI_REQUEST_HEADER_LENGTH; + num_sg_in_iu = 0; + + if (sg_count == 0) + goto out; + + sg = scsi_sglist(scmd); + sg_descriptor = request->sg_descriptors; + + num_sg_in_iu = pqi_build_sg_list(sg_descriptor, sg, sg_count, io_request, + ctrl_info->max_sg_per_iu, &chained); + + request->partial = chained; + iu_length += num_sg_in_iu * sizeof(*sg_descriptor); + +out: + put_unaligned_le16(iu_length, &request->header.iu_length); + request->num_sg_descriptors = num_sg_in_iu; + + return 0; +} + static int pqi_build_aio_r56_sg_list(struct pqi_ctrl_info *ctrl_info, struct pqi_aio_r56_path_request *request, struct scsi_cmnd *scmd, struct pqi_io_request *io_request) @@ -5435,6 +5447,66 @@ static int pqi_aio_submit_io(struct pqi_ctrl_info *ctrl_info, return 0; } +static int pqi_aio_submit_r1_write_io(struct pqi_ctrl_info *ctrl_info, + struct scsi_cmnd *scmd, struct pqi_queue_group *queue_group, + struct pqi_encryption_info *encryption_info, struct pqi_scsi_dev *device, + struct pqi_scsi_dev_raid_map_data *rmd) + +{ + int rc; + struct pqi_io_request *io_request; + struct pqi_aio_r1_path_request *r1_request; + + io_request = pqi_alloc_io_request(ctrl_info); + io_request->io_complete_callback = pqi_aio_io_complete; + io_request->scmd = scmd; + io_request->raid_bypass = true; + + r1_request = io_request->iu; + memset(r1_request, 0, offsetof(struct pqi_aio_r1_path_request, sg_descriptors)); + + r1_request->header.iu_type = PQI_REQUEST_IU_AIO_PATH_RAID1_IO; + + put_unaligned_le16(*(u16 *)device->scsi3addr & 0x3fff, &r1_request->volume_id); + r1_request->num_drives = rmd->num_it_nexus_entries; + put_unaligned_le32(rmd->it_nexus[0], &r1_request->it_nexus_1); + put_unaligned_le32(rmd->it_nexus[1], &r1_request->it_nexus_2); + if (rmd->num_it_nexus_entries == 3) + put_unaligned_le32(rmd->it_nexus[2], &r1_request->it_nexus_3); + + put_unaligned_le32(scsi_bufflen(scmd), &r1_request->data_length); + r1_request->task_attribute = SOP_TASK_ATTRIBUTE_SIMPLE; + put_unaligned_le16(io_request->index, &r1_request->request_id); + r1_request->error_index = r1_request->request_id; + if (rmd->cdb_length > sizeof(r1_request->cdb)) + rmd->cdb_length = sizeof(r1_request->cdb); + r1_request->cdb_length = rmd->cdb_length; + memcpy(r1_request->cdb, rmd->cdb, rmd->cdb_length); + + /* The direction is always write. */ + r1_request->data_direction = SOP_READ_FLAG; + + if (encryption_info) { + r1_request->encryption_enable = true; + put_unaligned_le16(encryption_info->data_encryption_key_index, + &r1_request->data_encryption_key_index); + put_unaligned_le32(encryption_info->encrypt_tweak_lower, + &r1_request->encrypt_tweak_lower); + put_unaligned_le32(encryption_info->encrypt_tweak_upper, + &r1_request->encrypt_tweak_upper); + } + + rc = pqi_build_aio_r1_sg_list(ctrl_info, r1_request, scmd, io_request); + if (rc) { + pqi_free_io_request(io_request); + return SCSI_MLQUEUE_HOST_BUSY; + } + + pqi_start_io(ctrl_info, queue_group, AIO_PATH, io_request); + + return 0; +} + static int pqi_aio_submit_r56_write_io(struct pqi_ctrl_info *ctrl_info, struct scsi_cmnd *scmd, struct pqi_queue_group *queue_group, struct pqi_encryption_info *encryption_info, struct pqi_scsi_dev *device, From f6cc2a774aa7f5469f381b52804bb244d4f8f4d7 Mon Sep 17 00:00:00 2001 From: Kevin Barnett Date: Thu, 11 Mar 2021 14:15:39 -0600 Subject: [PATCH 286/412] scsi: smartpqi: Add support for BMIC sense feature cmd and feature bits Determine support for supported features from BMIC sense feature command instead of config table. Enable features such as: RAID 1/5/6 write support, SATA wwid, and encryption. Link: https://lore.kernel.org/r/161549373914.25025.7999816178098103135.stgit@brunhilda Reviewed-by: Scott Teel Reviewed-by: Mike McGowen Reviewed-by: Scott Benesh Signed-off-by: Kevin Barnett Signed-off-by: Don Brace Signed-off-by: Martin K. Petersen --- drivers/scsi/smartpqi/smartpqi.h | 70 ++++++ drivers/scsi/smartpqi/smartpqi_init.c | 337 ++++++++++++++++++++++++-- 2 files changed, 388 insertions(+), 19 deletions(-) diff --git a/drivers/scsi/smartpqi/smartpqi.h b/drivers/scsi/smartpqi/smartpqi.h index bed80c4c4598..35e892579773 100644 --- a/drivers/scsi/smartpqi/smartpqi.h +++ b/drivers/scsi/smartpqi/smartpqi.h @@ -343,6 +343,10 @@ struct pqi_aio_r1_path_request { struct pqi_sg_descriptor sg_descriptors[PQI_MAX_EMBEDDED_SG_DESCRIPTORS]; }; +#define PQI_DEFAULT_MAX_WRITE_RAID_5_6 (8 * 1024U) +#define PQI_DEFAULT_MAX_TRANSFER_ENCRYPTED_SAS_SATA (~0U) +#define PQI_DEFAULT_MAX_TRANSFER_ENCRYPTED_NVME (32 * 1024U) + struct pqi_aio_r56_path_request { struct pqi_iu_header header; __le16 request_id; @@ -826,13 +830,28 @@ struct pqi_config_table_firmware_features { u8 features_supported[]; /* u8 features_requested_by_host[]; */ /* u8 features_enabled[]; */ +/* The 2 fields below are only valid if the MAX_KNOWN_FEATURE bit is set. */ +/* __le16 firmware_max_known_feature; */ +/* __le16 host_max_known_feature; */ }; #define PQI_FIRMWARE_FEATURE_OFA 0 #define PQI_FIRMWARE_FEATURE_SMP 1 +#define PQI_FIRMWARE_FEATURE_MAX_KNOWN_FEATURE 2 +#define PQI_FIRMWARE_FEATURE_RAID_0_READ_BYPASS 3 +#define PQI_FIRMWARE_FEATURE_RAID_1_READ_BYPASS 4 +#define PQI_FIRMWARE_FEATURE_RAID_5_READ_BYPASS 5 +#define PQI_FIRMWARE_FEATURE_RAID_6_READ_BYPASS 6 +#define PQI_FIRMWARE_FEATURE_RAID_0_WRITE_BYPASS 7 +#define PQI_FIRMWARE_FEATURE_RAID_1_WRITE_BYPASS 8 +#define PQI_FIRMWARE_FEATURE_RAID_5_WRITE_BYPASS 9 +#define PQI_FIRMWARE_FEATURE_RAID_6_WRITE_BYPASS 10 #define PQI_FIRMWARE_FEATURE_SOFT_RESET_HANDSHAKE 11 +#define PQI_FIRMWARE_FEATURE_UNIQUE_SATA_WWN 12 #define PQI_FIRMWARE_FEATURE_RAID_IU_TIMEOUT 13 #define PQI_FIRMWARE_FEATURE_TMF_IU_TIMEOUT 14 +#define PQI_FIRMWARE_FEATURE_RAID_BYPASS_ON_ENCRYPTED_NVME 15 +#define PQI_FIRMWARE_FEATURE_MAXIMUM 15 struct pqi_config_table_debug { struct pqi_config_table_section_header header; @@ -1069,6 +1088,7 @@ struct pqi_scsi_dev { bool raid_bypass_enabled; /* RAID bypass enabled */ u32 next_bypass_group; struct raid_map *raid_map; /* RAID bypass map */ + u32 max_transfer_encrypted; struct pqi_sas_port *sas_port; struct scsi_device *sdev; @@ -1276,6 +1296,14 @@ struct pqi_ctrl_info { u8 enable_r1_writes : 1; u8 enable_r5_writes : 1; u8 enable_r6_writes : 1; + u8 lv_drive_type_mix_valid : 1; + + u8 ciss_report_log_flags; + u32 max_transfer_encrypted_sas_sata; + u32 max_transfer_encrypted_nvme; + u32 max_write_raid_5_6; + u32 max_write_raid_1_10_2drive; + u32 max_write_raid_1_10_3drive; struct list_head scsi_device_list; spinlock_t scsi_device_list_lock; @@ -1336,6 +1364,7 @@ enum pqi_ctrl_mode { #define BMIC_IDENTIFY_PHYSICAL_DEVICE 0x15 #define BMIC_READ 0x26 #define BMIC_WRITE 0x27 +#define BMIC_SENSE_FEATURE 0x61 #define BMIC_SENSE_CONTROLLER_PARAMETERS 0x64 #define BMIC_SENSE_SUBSYSTEM_INFORMATION 0x66 #define BMIC_CSMI_PASSTHRU 0x68 @@ -1355,6 +1384,19 @@ enum pqi_ctrl_mode { (((CISS_GET_LEVEL_2_BUS((lunid)) - 1) << 8) + \ CISS_GET_LEVEL_2_TARGET((lunid))) +#define LV_GET_DRIVE_TYPE_MIX(lunid) ((lunid)[6]) + +#define LV_DRIVE_TYPE_MIX_UNKNOWN 0 +#define LV_DRIVE_TYPE_MIX_NO_RESTRICTION 1 +#define LV_DRIVE_TYPE_MIX_SAS_HDD_ONLY 2 +#define LV_DRIVE_TYPE_MIX_SATA_HDD_ONLY 3 +#define LV_DRIVE_TYPE_MIX_SAS_OR_SATA_SSD_ONLY 4 +#define LV_DRIVE_TYPE_MIX_SAS_SSD_ONLY 5 +#define LV_DRIVE_TYPE_MIX_SATA_SSD_ONLY 6 +#define LV_DRIVE_TYPE_MIX_SAS_ONLY 7 +#define LV_DRIVE_TYPE_MIX_SATA_ONLY 8 +#define LV_DRIVE_TYPE_MIX_NVME_ONLY 9 + #define NO_TIMEOUT ((unsigned long) -1) #pragma pack(1) @@ -1468,6 +1510,34 @@ struct bmic_identify_physical_device { u8 padding_to_multiple_of_512[9]; }; +#define BMIC_SENSE_FEATURE_IO_PAGE 0x8 +#define BMIC_SENSE_FEATURE_IO_PAGE_AIO_SUBPAGE 0x2 + +struct bmic_sense_feature_buffer_header { + u8 page_code; + u8 subpage_code; + __le16 buffer_length; +}; + +struct bmic_sense_feature_page_header { + u8 page_code; + u8 subpage_code; + __le16 page_length; +}; + +struct bmic_sense_feature_io_page_aio_subpage { + struct bmic_sense_feature_page_header header; + u8 firmware_read_support; + u8 driver_read_support; + u8 firmware_write_support; + u8 driver_write_support; + __le16 max_transfer_encrypted_sas_sata; + __le16 max_transfer_encrypted_nvme; + __le16 max_write_raid_5_6; + __le16 max_write_raid_1_10_2drive; + __le16 max_write_raid_1_10_3drive; +}; + struct bmic_smp_request { u8 frame_type; u8 function; diff --git a/drivers/scsi/smartpqi/smartpqi_init.c b/drivers/scsi/smartpqi/smartpqi_init.c index a36861184fc0..82f75a6be71c 100644 --- a/drivers/scsi/smartpqi/smartpqi_init.c +++ b/drivers/scsi/smartpqi/smartpqi_init.c @@ -506,7 +506,7 @@ static int pqi_build_raid_path_request(struct pqi_ctrl_info *ctrl_info, if (cmd == CISS_REPORT_PHYS) cdb[1] = CISS_REPORT_PHYS_FLAG_OTHER; else - cdb[1] = CISS_REPORT_LOG_FLAG_UNIQUE_LUN_ID; + cdb[1] = ctrl_info->ciss_report_log_flags; put_unaligned_be32(cdb_length, &cdb[6]); break; case CISS_GET_RAID_MAP: @@ -527,6 +527,7 @@ static int pqi_build_raid_path_request(struct pqi_ctrl_info *ctrl_info, case BMIC_IDENTIFY_CONTROLLER: case BMIC_IDENTIFY_PHYSICAL_DEVICE: case BMIC_SENSE_SUBSYSTEM_INFORMATION: + case BMIC_SENSE_FEATURE: request->data_direction = SOP_READ_FLAG; cdb[0] = BMIC_READ; cdb[6] = cmd; @@ -695,6 +696,105 @@ static int pqi_identify_physical_device(struct pqi_ctrl_info *ctrl_info, return rc; } +static inline u32 pqi_aio_limit_to_bytes(__le16 *limit) +{ + u32 bytes; + + bytes = get_unaligned_le16(limit); + if (bytes == 0) + bytes = ~0; + else + bytes *= 1024; + + return bytes; +} + +#pragma pack(1) + +struct bmic_sense_feature_buffer { + struct bmic_sense_feature_buffer_header header; + struct bmic_sense_feature_io_page_aio_subpage aio_subpage; +}; + +#pragma pack() + +#define MINIMUM_AIO_SUBPAGE_BUFFER_LENGTH \ + offsetofend(struct bmic_sense_feature_buffer, \ + aio_subpage.max_write_raid_1_10_3drive) + +#define MINIMUM_AIO_SUBPAGE_LENGTH \ + (offsetofend(struct bmic_sense_feature_io_page_aio_subpage, \ + max_write_raid_1_10_3drive) - \ + sizeof_field(struct bmic_sense_feature_io_page_aio_subpage, header)) + +static int pqi_get_advanced_raid_bypass_config(struct pqi_ctrl_info *ctrl_info) +{ + int rc; + enum dma_data_direction dir; + struct pqi_raid_path_request request; + struct bmic_sense_feature_buffer *buffer; + + buffer = kmalloc(sizeof(*buffer), GFP_KERNEL); + if (!buffer) + return -ENOMEM; + + rc = pqi_build_raid_path_request(ctrl_info, &request, + BMIC_SENSE_FEATURE, RAID_CTLR_LUNID, buffer, + sizeof(*buffer), 0, &dir); + if (rc) + goto error; + + request.cdb[2] = BMIC_SENSE_FEATURE_IO_PAGE; + request.cdb[3] = BMIC_SENSE_FEATURE_IO_PAGE_AIO_SUBPAGE; + + rc = pqi_submit_raid_request_synchronous(ctrl_info, &request.header, + 0, NULL, NO_TIMEOUT); + + pqi_pci_unmap(ctrl_info->pci_dev, request.sg_descriptors, 1, dir); + + if (rc) + goto error; + + if (buffer->header.page_code != BMIC_SENSE_FEATURE_IO_PAGE || + buffer->header.subpage_code != + BMIC_SENSE_FEATURE_IO_PAGE_AIO_SUBPAGE || + get_unaligned_le16(&buffer->header.buffer_length) < + MINIMUM_AIO_SUBPAGE_BUFFER_LENGTH || + buffer->aio_subpage.header.page_code != + BMIC_SENSE_FEATURE_IO_PAGE || + buffer->aio_subpage.header.subpage_code != + BMIC_SENSE_FEATURE_IO_PAGE_AIO_SUBPAGE || + get_unaligned_le16(&buffer->aio_subpage.header.page_length) < + MINIMUM_AIO_SUBPAGE_LENGTH) { + goto error; + } + + ctrl_info->max_transfer_encrypted_sas_sata = + pqi_aio_limit_to_bytes( + &buffer->aio_subpage.max_transfer_encrypted_sas_sata); + + ctrl_info->max_transfer_encrypted_nvme = + pqi_aio_limit_to_bytes( + &buffer->aio_subpage.max_transfer_encrypted_nvme); + + ctrl_info->max_write_raid_5_6 = + pqi_aio_limit_to_bytes( + &buffer->aio_subpage.max_write_raid_5_6); + + ctrl_info->max_write_raid_1_10_2drive = + pqi_aio_limit_to_bytes( + &buffer->aio_subpage.max_write_raid_1_10_2drive); + + ctrl_info->max_write_raid_1_10_3drive = + pqi_aio_limit_to_bytes( + &buffer->aio_subpage.max_write_raid_1_10_3drive); + +error: + kfree(buffer); + + return rc; +} + static int pqi_flush_cache(struct pqi_ctrl_info *ctrl_info, enum bmic_flush_cache_shutdown_event shutdown_event) { @@ -1232,6 +1332,39 @@ error: return rc; } +static void pqi_set_max_transfer_encrypted(struct pqi_ctrl_info *ctrl_info, + struct pqi_scsi_dev *device) +{ + if (!ctrl_info->lv_drive_type_mix_valid) { + device->max_transfer_encrypted = ~0; + return; + } + + switch (LV_GET_DRIVE_TYPE_MIX(device->scsi3addr)) { + case LV_DRIVE_TYPE_MIX_SAS_HDD_ONLY: + case LV_DRIVE_TYPE_MIX_SATA_HDD_ONLY: + case LV_DRIVE_TYPE_MIX_SAS_OR_SATA_SSD_ONLY: + case LV_DRIVE_TYPE_MIX_SAS_SSD_ONLY: + case LV_DRIVE_TYPE_MIX_SATA_SSD_ONLY: + case LV_DRIVE_TYPE_MIX_SAS_ONLY: + case LV_DRIVE_TYPE_MIX_SATA_ONLY: + device->max_transfer_encrypted = + ctrl_info->max_transfer_encrypted_sas_sata; + break; + case LV_DRIVE_TYPE_MIX_NVME_ONLY: + device->max_transfer_encrypted = + ctrl_info->max_transfer_encrypted_nvme; + break; + case LV_DRIVE_TYPE_MIX_UNKNOWN: + case LV_DRIVE_TYPE_MIX_NO_RESTRICTION: + default: + device->max_transfer_encrypted = + min(ctrl_info->max_transfer_encrypted_sas_sata, + ctrl_info->max_transfer_encrypted_nvme); + break; + } +} + static void pqi_get_raid_bypass_status(struct pqi_ctrl_info *ctrl_info, struct pqi_scsi_dev *device) { @@ -1257,8 +1390,12 @@ static void pqi_get_raid_bypass_status(struct pqi_ctrl_info *ctrl_info, (bypass_status & RAID_BYPASS_CONFIGURED) != 0; if (device->raid_bypass_configured && (bypass_status & RAID_BYPASS_ENABLED) && - pqi_get_raid_map(ctrl_info, device) == 0) + pqi_get_raid_map(ctrl_info, device) == 0) { device->raid_bypass_enabled = true; + if (get_unaligned_le16(&device->raid_map->flags) & + RAID_MAP_ENCRYPTION_ENABLED) + pqi_set_max_transfer_encrypted(ctrl_info, device); + } out: kfree(buffer); @@ -2028,6 +2165,10 @@ static int pqi_update_scsi_devices(struct pqi_ctrl_info *ctrl_info) } } + if (num_logicals && + (logdev_list->header.flags & CISS_REPORT_LOG_FLAG_DRIVE_TYPE_MIX)) + ctrl_info->lv_drive_type_mix_valid = true; + num_new_devices = num_physicals + num_logicals; new_device_list = kmalloc_array(num_new_devices, @@ -2254,20 +2395,28 @@ static bool pqi_aio_raid_level_supported(struct pqi_ctrl_info *ctrl_info, case SA_RAID_0: break; case SA_RAID_1: + if (rmd->is_write && (!ctrl_info->enable_r1_writes || + rmd->data_length > ctrl_info->max_write_raid_1_10_2drive)) + is_supported = false; + break; case SA_RAID_TRIPLE: - if (rmd->is_write && !ctrl_info->enable_r1_writes) + if (rmd->is_write && (!ctrl_info->enable_r1_writes || + rmd->data_length > ctrl_info->max_write_raid_1_10_3drive)) is_supported = false; break; case SA_RAID_5: - if (rmd->is_write && !ctrl_info->enable_r5_writes) + if (rmd->is_write && (!ctrl_info->enable_r5_writes || + rmd->data_length > ctrl_info->max_write_raid_5_6)) is_supported = false; break; case SA_RAID_6: - if (rmd->is_write && !ctrl_info->enable_r6_writes) + if (rmd->is_write && (!ctrl_info->enable_r6_writes || + rmd->data_length > ctrl_info->max_write_raid_5_6)) is_supported = false; break; default: is_supported = false; + break; } return is_supported; @@ -2624,7 +2773,9 @@ static int pqi_raid_bypass_submit_scsi_cmd(struct pqi_ctrl_info *ctrl_info, pqi_set_aio_cdb(&rmd); if (get_unaligned_le16(&raid_map->flags) & - RAID_MAP_ENCRYPTION_ENABLED) { + RAID_MAP_ENCRYPTION_ENABLED) { + if (rmd.data_length > device->max_transfer_encrypted) + return PQI_RAID_BYPASS_INELIGIBLE; pqi_set_encryption_info(&encryption_info, raid_map, rmd.first_block); encryption_info_ptr = &encryption_info; @@ -2634,10 +2785,6 @@ static int pqi_raid_bypass_submit_scsi_cmd(struct pqi_ctrl_info *ctrl_info, if (rmd.is_write) { switch (device->raid_level) { - case SA_RAID_0: - return pqi_aio_submit_io(ctrl_info, scmd, rmd.aio_handle, - rmd.cdb, rmd.cdb_length, queue_group, - encryption_info_ptr, true); case SA_RAID_1: case SA_RAID_TRIPLE: return pqi_aio_submit_r1_write_io(ctrl_info, scmd, queue_group, @@ -2646,17 +2793,12 @@ static int pqi_raid_bypass_submit_scsi_cmd(struct pqi_ctrl_info *ctrl_info, case SA_RAID_6: return pqi_aio_submit_r56_write_io(ctrl_info, scmd, queue_group, encryption_info_ptr, device, &rmd); - default: - return pqi_aio_submit_io(ctrl_info, scmd, rmd.aio_handle, - rmd.cdb, rmd.cdb_length, queue_group, - encryption_info_ptr, true); } - } else { - return pqi_aio_submit_io(ctrl_info, scmd, rmd.aio_handle, - rmd.cdb, rmd.cdb_length, queue_group, - encryption_info_ptr, true); } + return pqi_aio_submit_io(ctrl_info, scmd, rmd.aio_handle, + rmd.cdb, rmd.cdb_length, queue_group, + encryption_info_ptr, true); } #define PQI_STATUS_IDLE 0x0 @@ -7189,6 +7331,7 @@ static int pqi_enable_firmware_features(struct pqi_ctrl_info *ctrl_info, { void *features_requested; void __iomem *features_requested_iomem_addr; + void __iomem *host_max_known_feature_iomem_addr; features_requested = firmware_features->features_supported + le16_to_cpu(firmware_features->num_elements); @@ -7199,6 +7342,16 @@ static int pqi_enable_firmware_features(struct pqi_ctrl_info *ctrl_info, memcpy_toio(features_requested_iomem_addr, features_requested, le16_to_cpu(firmware_features->num_elements)); + if (pqi_is_firmware_feature_supported(firmware_features, + PQI_FIRMWARE_FEATURE_MAX_KNOWN_FEATURE)) { + host_max_known_feature_iomem_addr = + features_requested_iomem_addr + + (le16_to_cpu(firmware_features->num_elements) * 2) + + sizeof(__le16); + writew(PQI_FIRMWARE_FEATURE_MAXIMUM, + host_max_known_feature_iomem_addr); + } + return pqi_config_table_update(ctrl_info, PQI_CONFIG_TABLE_SECTION_FIRMWARE_FEATURES, PQI_CONFIG_TABLE_SECTION_FIRMWARE_FEATURES); @@ -7236,6 +7389,15 @@ static void pqi_ctrl_update_feature_flags(struct pqi_ctrl_info *ctrl_info, struct pqi_firmware_feature *firmware_feature) { switch (firmware_feature->feature_bit) { + case PQI_FIRMWARE_FEATURE_RAID_1_WRITE_BYPASS: + ctrl_info->enable_r1_writes = firmware_feature->enabled; + break; + case PQI_FIRMWARE_FEATURE_RAID_5_WRITE_BYPASS: + ctrl_info->enable_r5_writes = firmware_feature->enabled; + break; + case PQI_FIRMWARE_FEATURE_RAID_6_WRITE_BYPASS: + ctrl_info->enable_r6_writes = firmware_feature->enabled; + break; case PQI_FIRMWARE_FEATURE_SOFT_RESET_HANDSHAKE: ctrl_info->soft_reset_handshake_supported = firmware_feature->enabled; @@ -7273,6 +7435,51 @@ static struct pqi_firmware_feature pqi_firmware_features[] = { .feature_bit = PQI_FIRMWARE_FEATURE_SMP, .feature_status = pqi_firmware_feature_status, }, + { + .feature_name = "Maximum Known Feature", + .feature_bit = PQI_FIRMWARE_FEATURE_MAX_KNOWN_FEATURE, + .feature_status = pqi_firmware_feature_status, + }, + { + .feature_name = "RAID 0 Read Bypass", + .feature_bit = PQI_FIRMWARE_FEATURE_RAID_0_READ_BYPASS, + .feature_status = pqi_firmware_feature_status, + }, + { + .feature_name = "RAID 1 Read Bypass", + .feature_bit = PQI_FIRMWARE_FEATURE_RAID_1_READ_BYPASS, + .feature_status = pqi_firmware_feature_status, + }, + { + .feature_name = "RAID 5 Read Bypass", + .feature_bit = PQI_FIRMWARE_FEATURE_RAID_5_READ_BYPASS, + .feature_status = pqi_firmware_feature_status, + }, + { + .feature_name = "RAID 6 Read Bypass", + .feature_bit = PQI_FIRMWARE_FEATURE_RAID_6_READ_BYPASS, + .feature_status = pqi_firmware_feature_status, + }, + { + .feature_name = "RAID 0 Write Bypass", + .feature_bit = PQI_FIRMWARE_FEATURE_RAID_0_WRITE_BYPASS, + .feature_status = pqi_firmware_feature_status, + }, + { + .feature_name = "RAID 1 Write Bypass", + .feature_bit = PQI_FIRMWARE_FEATURE_RAID_1_WRITE_BYPASS, + .feature_status = pqi_ctrl_update_feature_flags, + }, + { + .feature_name = "RAID 5 Write Bypass", + .feature_bit = PQI_FIRMWARE_FEATURE_RAID_5_WRITE_BYPASS, + .feature_status = pqi_ctrl_update_feature_flags, + }, + { + .feature_name = "RAID 6 Write Bypass", + .feature_bit = PQI_FIRMWARE_FEATURE_RAID_6_WRITE_BYPASS, + .feature_status = pqi_ctrl_update_feature_flags, + }, { .feature_name = "New Soft Reset Handshake", .feature_bit = PQI_FIRMWARE_FEATURE_SOFT_RESET_HANDSHAKE, @@ -7288,6 +7495,11 @@ static struct pqi_firmware_feature pqi_firmware_features[] = { .feature_bit = PQI_FIRMWARE_FEATURE_TMF_IU_TIMEOUT, .feature_status = pqi_ctrl_update_feature_flags, }, + { + .feature_name = "RAID Bypass on encrypted logical volumes on NVMe", + .feature_bit = PQI_FIRMWARE_FEATURE_RAID_BYPASS_ON_ENCRYPTED_NVME, + .feature_status = pqi_firmware_feature_status, + }, }; static void pqi_process_firmware_features( @@ -7372,14 +7584,21 @@ static void pqi_process_firmware_features_section( mutex_unlock(&pqi_firmware_features_mutex); } +/* + * Reset all controller settings that can be initialized during the processing + * of the PQI Configuration Table. + */ + static int pqi_process_config_table(struct pqi_ctrl_info *ctrl_info) { u32 table_length; u32 section_offset; + bool firmware_feature_section_present; void __iomem *table_iomem_addr; struct pqi_config_table *config_table; struct pqi_config_table_section_header *section; struct pqi_config_table_section_info section_info; + struct pqi_config_table_section_info feature_section_info; table_length = ctrl_info->config_table_length; if (table_length == 0) @@ -7400,6 +7619,7 @@ static int pqi_process_config_table(struct pqi_ctrl_info *ctrl_info) ctrl_info->config_table_offset; memcpy_fromio(config_table, table_iomem_addr, table_length); + firmware_feature_section_present = false; section_info.ctrl_info = ctrl_info; section_offset = get_unaligned_le32(&config_table->first_section_offset); @@ -7414,7 +7634,8 @@ static int pqi_process_config_table(struct pqi_ctrl_info *ctrl_info) switch (get_unaligned_le16(§ion->section_id)) { case PQI_CONFIG_TABLE_SECTION_FIRMWARE_FEATURES: - pqi_process_firmware_features_section(§ion_info); + firmware_feature_section_present = true; + feature_section_info = section_info; break; case PQI_CONFIG_TABLE_SECTION_HEARTBEAT: if (pqi_disable_heartbeat) @@ -7441,6 +7662,14 @@ static int pqi_process_config_table(struct pqi_ctrl_info *ctrl_info) get_unaligned_le16(§ion->next_section_offset); } + /* + * We process the firmware feature section after all other sections + * have been processed so that the feature bit callbacks can take + * into account the settings configured by other sections. + */ + if (firmware_feature_section_present) + pqi_process_firmware_features_section(&feature_section_info); + kfree(config_table); return 0; @@ -7647,6 +7876,17 @@ static int pqi_ctrl_init(struct pqi_ctrl_info *ctrl_info) pqi_start_heartbeat_timer(ctrl_info); + if (ctrl_info->enable_r5_writes || ctrl_info->enable_r6_writes) { + rc = pqi_get_advanced_raid_bypass_config(ctrl_info); + if (rc) { /* Supported features not returned correctly. */ + dev_err(&ctrl_info->pci_dev->dev, + "error obtaining advanced RAID bypass configuration\n"); + return rc; + } + ctrl_info->ciss_report_log_flags |= + CISS_REPORT_LOG_FLAG_DRIVE_TYPE_MIX; + } + rc = pqi_enable_events(ctrl_info); if (rc) { dev_err(&ctrl_info->pci_dev->dev, @@ -7802,6 +8042,17 @@ static int pqi_ctrl_init_resume(struct pqi_ctrl_info *ctrl_info) pqi_start_heartbeat_timer(ctrl_info); + if (ctrl_info->enable_r5_writes || ctrl_info->enable_r6_writes) { + rc = pqi_get_advanced_raid_bypass_config(ctrl_info); + if (rc) { + dev_err(&ctrl_info->pci_dev->dev, + "error obtaining advanced RAID bypass configuration\n"); + return rc; + } + ctrl_info->ciss_report_log_flags |= + CISS_REPORT_LOG_FLAG_DRIVE_TYPE_MIX; + } + rc = pqi_enable_events(ctrl_info); if (rc) { dev_err(&ctrl_info->pci_dev->dev, @@ -7965,6 +8216,15 @@ static struct pqi_ctrl_info *pqi_alloc_ctrl_info(int numa_node) ctrl_info->irq_mode = IRQ_MODE_NONE; ctrl_info->max_msix_vectors = PQI_MAX_MSIX_VECTORS; + ctrl_info->ciss_report_log_flags = CISS_REPORT_LOG_FLAG_UNIQUE_LUN_ID; + ctrl_info->max_transfer_encrypted_sas_sata = + PQI_DEFAULT_MAX_TRANSFER_ENCRYPTED_SAS_SATA; + ctrl_info->max_transfer_encrypted_nvme = + PQI_DEFAULT_MAX_TRANSFER_ENCRYPTED_NVME; + ctrl_info->max_write_raid_5_6 = PQI_DEFAULT_MAX_WRITE_RAID_5_6; + ctrl_info->max_write_raid_1_10_2drive = ~0; + ctrl_info->max_write_raid_1_10_3drive = ~0; + return ctrl_info; } @@ -9376,6 +9636,45 @@ static void __attribute__((unused)) verify_structures(void) current_queue_depth_limit) != 1796); BUILD_BUG_ON(sizeof(struct bmic_identify_physical_device) != 2560); + BUILD_BUG_ON(sizeof(struct bmic_sense_feature_buffer_header) != 4); + BUILD_BUG_ON(offsetof(struct bmic_sense_feature_buffer_header, + page_code) != 0); + BUILD_BUG_ON(offsetof(struct bmic_sense_feature_buffer_header, + subpage_code) != 1); + BUILD_BUG_ON(offsetof(struct bmic_sense_feature_buffer_header, + buffer_length) != 2); + + BUILD_BUG_ON(sizeof(struct bmic_sense_feature_page_header) != 4); + BUILD_BUG_ON(offsetof(struct bmic_sense_feature_page_header, + page_code) != 0); + BUILD_BUG_ON(offsetof(struct bmic_sense_feature_page_header, + subpage_code) != 1); + BUILD_BUG_ON(offsetof(struct bmic_sense_feature_page_header, + page_length) != 2); + + BUILD_BUG_ON(sizeof(struct bmic_sense_feature_io_page_aio_subpage) + != 18); + BUILD_BUG_ON(offsetof(struct bmic_sense_feature_io_page_aio_subpage, + header) != 0); + BUILD_BUG_ON(offsetof(struct bmic_sense_feature_io_page_aio_subpage, + firmware_read_support) != 4); + BUILD_BUG_ON(offsetof(struct bmic_sense_feature_io_page_aio_subpage, + driver_read_support) != 5); + BUILD_BUG_ON(offsetof(struct bmic_sense_feature_io_page_aio_subpage, + firmware_write_support) != 6); + BUILD_BUG_ON(offsetof(struct bmic_sense_feature_io_page_aio_subpage, + driver_write_support) != 7); + BUILD_BUG_ON(offsetof(struct bmic_sense_feature_io_page_aio_subpage, + max_transfer_encrypted_sas_sata) != 8); + BUILD_BUG_ON(offsetof(struct bmic_sense_feature_io_page_aio_subpage, + max_transfer_encrypted_nvme) != 10); + BUILD_BUG_ON(offsetof(struct bmic_sense_feature_io_page_aio_subpage, + max_write_raid_5_6) != 12); + BUILD_BUG_ON(offsetof(struct bmic_sense_feature_io_page_aio_subpage, + max_write_raid_1_10_2drive) != 14); + BUILD_BUG_ON(offsetof(struct bmic_sense_feature_io_page_aio_subpage, + max_write_raid_1_10_3drive) != 16); + BUILD_BUG_ON(PQI_ADMIN_IQ_NUM_ELEMENTS > 255); BUILD_BUG_ON(PQI_ADMIN_OQ_NUM_ELEMENTS > 255); BUILD_BUG_ON(PQI_ADMIN_IQ_ELEMENT_LENGTH % From 598bef8d79421117b49642ef2b7cb65a73e186c1 Mon Sep 17 00:00:00 2001 From: Kevin Barnett Date: Thu, 11 Mar 2021 14:15:45 -0600 Subject: [PATCH 287/412] scsi: smartpqi: Add support for long firmware version Add support for new "long" firmware version which requires minor driver changes to expose. Link: https://lore.kernel.org/r/161549374508.25025.15467221395888158022.stgit@brunhilda Reviewed-by: Scott Benesh Reviewed-by: Mike McGowen Reviewed-by: Scott Teel Signed-off-by: Kevin Barnett Signed-off-by: Don Brace Signed-off-by: Martin K. Petersen --- drivers/scsi/smartpqi/smartpqi.h | 14 +++++++--- drivers/scsi/smartpqi/smartpqi_init.c | 37 +++++++++++++++++++++------ 2 files changed, 39 insertions(+), 12 deletions(-) diff --git a/drivers/scsi/smartpqi/smartpqi.h b/drivers/scsi/smartpqi/smartpqi.h index 35e892579773..aaafaced596b 100644 --- a/drivers/scsi/smartpqi/smartpqi.h +++ b/drivers/scsi/smartpqi/smartpqi.h @@ -1226,7 +1226,7 @@ struct pqi_event { struct pqi_ctrl_info { unsigned int ctrl_id; struct pci_dev *pci_dev; - char firmware_version[11]; + char firmware_version[32]; char serial_number[17]; char model[17]; char vendor[9]; @@ -1404,7 +1404,7 @@ enum pqi_ctrl_mode { struct bmic_identify_controller { u8 configured_logical_drive_count; __le32 configuration_signature; - u8 firmware_version[4]; + u8 firmware_version_short[4]; u8 reserved[145]; __le16 extended_logical_unit_count; u8 reserved1[34]; @@ -1412,11 +1412,17 @@ struct bmic_identify_controller { u8 reserved2[8]; u8 vendor_id[8]; u8 product_id[16]; - u8 reserved3[68]; + u8 reserved3[62]; + __le32 extra_controller_flags; + u8 reserved4[2]; u8 controller_mode; - u8 reserved4[32]; + u8 spare_part_number[32]; + u8 firmware_version_long[32]; }; +/* constants for extra_controller_flags field of bmic_identify_controller */ +#define BMIC_IDENTIFY_EXTRA_FLAGS_LONG_FW_VERSION_SUPPORTED 0x20000000 + struct bmic_sense_subsystem_info { u8 reserved[44]; u8 ctrl_serial_number[16]; diff --git a/drivers/scsi/smartpqi/smartpqi_init.c b/drivers/scsi/smartpqi/smartpqi_init.c index 82f75a6be71c..6cc953dd9961 100644 --- a/drivers/scsi/smartpqi/smartpqi_init.c +++ b/drivers/scsi/smartpqi/smartpqi_init.c @@ -7228,13 +7228,24 @@ static int pqi_get_ctrl_product_details(struct pqi_ctrl_info *ctrl_info) if (rc) goto out; - memcpy(ctrl_info->firmware_version, identify->firmware_version, - sizeof(identify->firmware_version)); - ctrl_info->firmware_version[sizeof(identify->firmware_version)] = '\0'; - snprintf(ctrl_info->firmware_version + - strlen(ctrl_info->firmware_version), - sizeof(ctrl_info->firmware_version), - "-%u", get_unaligned_le16(&identify->firmware_build_number)); + if (get_unaligned_le32(&identify->extra_controller_flags) & + BMIC_IDENTIFY_EXTRA_FLAGS_LONG_FW_VERSION_SUPPORTED) { + memcpy(ctrl_info->firmware_version, + identify->firmware_version_long, + sizeof(identify->firmware_version_long)); + } else { + memcpy(ctrl_info->firmware_version, + identify->firmware_version_short, + sizeof(identify->firmware_version_short)); + ctrl_info->firmware_version + [sizeof(identify->firmware_version_short)] = '\0'; + snprintf(ctrl_info->firmware_version + + strlen(ctrl_info->firmware_version), + sizeof(ctrl_info->firmware_version) - + sizeof(identify->firmware_version_short), + "-%u", + get_unaligned_le16(&identify->firmware_build_number)); + } memcpy(ctrl_info->model, identify->product_id, sizeof(identify->product_id)); @@ -9612,13 +9623,23 @@ static void __attribute__((unused)) verify_structures(void) BUILD_BUG_ON(offsetof(struct bmic_identify_controller, configuration_signature) != 1); BUILD_BUG_ON(offsetof(struct bmic_identify_controller, - firmware_version) != 5); + firmware_version_short) != 5); BUILD_BUG_ON(offsetof(struct bmic_identify_controller, extended_logical_unit_count) != 154); BUILD_BUG_ON(offsetof(struct bmic_identify_controller, firmware_build_number) != 190); + BUILD_BUG_ON(offsetof(struct bmic_identify_controller, + vendor_id) != 200); + BUILD_BUG_ON(offsetof(struct bmic_identify_controller, + product_id) != 208); + BUILD_BUG_ON(offsetof(struct bmic_identify_controller, + extra_controller_flags) != 286); BUILD_BUG_ON(offsetof(struct bmic_identify_controller, controller_mode) != 292); + BUILD_BUG_ON(offsetof(struct bmic_identify_controller, + spare_part_number) != 293); + BUILD_BUG_ON(offsetof(struct bmic_identify_controller, + firmware_version_long) != 325); BUILD_BUG_ON(offsetof(struct bmic_identify_physical_device, phys_bay_in_box) != 115); From 583891c9e509256a2b2902607c2e7a7c36beb0d3 Mon Sep 17 00:00:00 2001 From: Kevin Barnett Date: Thu, 11 Mar 2021 14:15:50 -0600 Subject: [PATCH 288/412] scsi: smartpqi: Align code with oob driver Reduce differences between out-of-box driver and kernel.org driver. No functional changes. Link: https://lore.kernel.org/r/161549375094.25025.9268879575316758510.stgit@brunhilda Reviewed-by: Scott Benesh Reviewed-by: Mike McGowen Reviewed-by: Scott Teel Signed-off-by: Kevin Barnett Signed-off-by: Don Brace Signed-off-by: Martin K. Petersen --- drivers/scsi/smartpqi/smartpqi.h | 57 ++-- drivers/scsi/smartpqi/smartpqi_init.c | 316 +++++++----------- .../scsi/smartpqi/smartpqi_sas_transport.c | 10 +- drivers/scsi/smartpqi/smartpqi_sis.c | 4 +- 4 files changed, 156 insertions(+), 231 deletions(-) diff --git a/drivers/scsi/smartpqi/smartpqi.h b/drivers/scsi/smartpqi/smartpqi.h index aaafaced596b..6639432f3dab 100644 --- a/drivers/scsi/smartpqi/smartpqi.h +++ b/drivers/scsi/smartpqi/smartpqi.h @@ -129,7 +129,7 @@ struct pqi_iu_header { __le16 iu_length; /* in bytes - does not include the length */ /* of this header */ __le16 response_queue_id; /* specifies the OQ where the */ - /* response IU is to be delivered */ + /* response IU is to be delivered */ u8 work_area[2]; /* reserved for driver use */ }; @@ -281,8 +281,7 @@ struct pqi_raid_path_request { u8 cdb[16]; u8 reserved6[12]; __le32 timeout; - struct pqi_sg_descriptor - sg_descriptors[PQI_MAX_EMBEDDED_SG_DESCRIPTORS]; + struct pqi_sg_descriptor sg_descriptors[PQI_MAX_EMBEDDED_SG_DESCRIPTORS]; }; struct pqi_aio_path_request { @@ -309,11 +308,11 @@ struct pqi_aio_path_request { u8 cdb_length; u8 lun_number[8]; u8 reserved4[4]; - struct pqi_sg_descriptor - sg_descriptors[PQI_MAX_EMBEDDED_SG_DESCRIPTORS]; + struct pqi_sg_descriptor sg_descriptors[PQI_MAX_EMBEDDED_SG_DESCRIPTORS]; }; #define PQI_RAID1_NVME_XFER_LIMIT (32 * 1024) /* 32 KiB */ + struct pqi_aio_r1_path_request { struct pqi_iu_header header; __le16 request_id; @@ -420,7 +419,7 @@ struct pqi_event_config { #define PQI_EVENT_OFA_MEMORY_ALLOCATION 0x0 #define PQI_EVENT_OFA_QUIESCE 0x1 -#define PQI_EVENT_OFA_CANCELLED 0x2 +#define PQI_EVENT_OFA_CANCELED 0x2 struct pqi_event_response { struct pqi_iu_header header; @@ -725,7 +724,7 @@ struct pqi_admin_queues_aligned { struct pqi_admin_queues { void *iq_element_array; void *oq_element_array; - pqi_index_t *iq_ci; + pqi_index_t __iomem *iq_ci; pqi_index_t __iomem *oq_pi; dma_addr_t iq_element_array_bus_addr; dma_addr_t oq_element_array_bus_addr; @@ -750,8 +749,8 @@ struct pqi_queue_group { dma_addr_t oq_element_array_bus_addr; __le32 __iomem *iq_pi[2]; pqi_index_t iq_pi_copy[2]; - pqi_index_t __iomem *iq_ci[2]; - pqi_index_t __iomem *oq_pi; + pqi_index_t __iomem *iq_ci[2]; + pqi_index_t __iomem *oq_pi; dma_addr_t iq_ci_bus_addr[2]; dma_addr_t oq_pi_bus_addr; __le32 __iomem *oq_ci; @@ -764,7 +763,7 @@ struct pqi_event_queue { u16 oq_id; u16 int_msg_num; void *oq_element_array; - pqi_index_t __iomem *oq_pi; + pqi_index_t __iomem *oq_pi; dma_addr_t oq_element_array_bus_addr; dma_addr_t oq_pi_bus_addr; __le32 __iomem *oq_ci; @@ -835,21 +834,21 @@ struct pqi_config_table_firmware_features { /* __le16 host_max_known_feature; */ }; -#define PQI_FIRMWARE_FEATURE_OFA 0 -#define PQI_FIRMWARE_FEATURE_SMP 1 -#define PQI_FIRMWARE_FEATURE_MAX_KNOWN_FEATURE 2 -#define PQI_FIRMWARE_FEATURE_RAID_0_READ_BYPASS 3 -#define PQI_FIRMWARE_FEATURE_RAID_1_READ_BYPASS 4 -#define PQI_FIRMWARE_FEATURE_RAID_5_READ_BYPASS 5 -#define PQI_FIRMWARE_FEATURE_RAID_6_READ_BYPASS 6 -#define PQI_FIRMWARE_FEATURE_RAID_0_WRITE_BYPASS 7 -#define PQI_FIRMWARE_FEATURE_RAID_1_WRITE_BYPASS 8 -#define PQI_FIRMWARE_FEATURE_RAID_5_WRITE_BYPASS 9 -#define PQI_FIRMWARE_FEATURE_RAID_6_WRITE_BYPASS 10 -#define PQI_FIRMWARE_FEATURE_SOFT_RESET_HANDSHAKE 11 -#define PQI_FIRMWARE_FEATURE_UNIQUE_SATA_WWN 12 -#define PQI_FIRMWARE_FEATURE_RAID_IU_TIMEOUT 13 -#define PQI_FIRMWARE_FEATURE_TMF_IU_TIMEOUT 14 +#define PQI_FIRMWARE_FEATURE_OFA 0 +#define PQI_FIRMWARE_FEATURE_SMP 1 +#define PQI_FIRMWARE_FEATURE_MAX_KNOWN_FEATURE 2 +#define PQI_FIRMWARE_FEATURE_RAID_0_READ_BYPASS 3 +#define PQI_FIRMWARE_FEATURE_RAID_1_READ_BYPASS 4 +#define PQI_FIRMWARE_FEATURE_RAID_5_READ_BYPASS 5 +#define PQI_FIRMWARE_FEATURE_RAID_6_READ_BYPASS 6 +#define PQI_FIRMWARE_FEATURE_RAID_0_WRITE_BYPASS 7 +#define PQI_FIRMWARE_FEATURE_RAID_1_WRITE_BYPASS 8 +#define PQI_FIRMWARE_FEATURE_RAID_5_WRITE_BYPASS 9 +#define PQI_FIRMWARE_FEATURE_RAID_6_WRITE_BYPASS 10 +#define PQI_FIRMWARE_FEATURE_SOFT_RESET_HANDSHAKE 11 +#define PQI_FIRMWARE_FEATURE_UNIQUE_SATA_WWN 12 +#define PQI_FIRMWARE_FEATURE_RAID_IU_TIMEOUT 13 +#define PQI_FIRMWARE_FEATURE_TMF_IU_TIMEOUT 14 #define PQI_FIRMWARE_FEATURE_RAID_BYPASS_ON_ENCRYPTED_NVME 15 #define PQI_FIRMWARE_FEATURE_MAXIMUM 15 @@ -1027,12 +1026,12 @@ struct pqi_scsi_dev_raid_map_data { u8 cdb[16]; u8 cdb_length; - /* RAID1 specific */ + /* RAID 1 specific */ #define NUM_RAID1_MAP_ENTRIES 3 u32 num_it_nexus_entries; u32 it_nexus[NUM_RAID1_MAP_ENTRIES]; - /* RAID5 RAID6 specific */ + /* RAID 5 / RAID 6 specific */ u32 p_parity_it_nexus; /* aio_handle */ u32 q_parity_it_nexus; /* aio_handle */ u8 xor_mult; @@ -1291,8 +1290,8 @@ struct pqi_ctrl_info { u8 pqi_mode_enabled : 1; u8 pqi_reset_quiesce_supported : 1; u8 soft_reset_handshake_supported : 1; - u8 raid_iu_timeout_supported: 1; - u8 tmf_iu_timeout_supported: 1; + u8 raid_iu_timeout_supported : 1; + u8 tmf_iu_timeout_supported : 1; u8 enable_r1_writes : 1; u8 enable_r5_writes : 1; u8 enable_r6_writes : 1; diff --git a/drivers/scsi/smartpqi/smartpqi_init.c b/drivers/scsi/smartpqi/smartpqi_init.c index 6cc953dd9961..143bb7b64095 100644 --- a/drivers/scsi/smartpqi/smartpqi_init.c +++ b/drivers/scsi/smartpqi/smartpqi_init.c @@ -156,14 +156,12 @@ MODULE_PARM_DESC(lockup_action, "Action to take when controller locked up.\n" static int pqi_expose_ld_first; module_param_named(expose_ld_first, pqi_expose_ld_first, int, 0644); -MODULE_PARM_DESC(expose_ld_first, - "Expose logical drives before physical drives."); +MODULE_PARM_DESC(expose_ld_first, "Expose logical drives before physical drives."); static int pqi_hide_vsep; module_param_named(hide_vsep, pqi_hide_vsep, int, 0644); -MODULE_PARM_DESC(hide_vsep, - "Hide the virtual SEP for direct attached drives."); +MODULE_PARM_DESC(hide_vsep, "Hide the virtual SEP for direct attached drives."); static char *raid_levels[] = { "RAID-0", @@ -236,8 +234,7 @@ static inline bool pqi_is_hba_lunid(u8 *scsi3addr) return pqi_scsi3addr_equal(scsi3addr, RAID_CTLR_LUNID); } -static inline enum pqi_ctrl_mode pqi_get_ctrl_mode( - struct pqi_ctrl_info *ctrl_info) +static inline enum pqi_ctrl_mode pqi_get_ctrl_mode(struct pqi_ctrl_info *ctrl_info) { return sis_read_driver_scratch(ctrl_info); } @@ -368,8 +365,8 @@ static inline bool pqi_ctrl_in_shutdown(struct pqi_ctrl_info *ctrl_info) return ctrl_info->in_shutdown; } -static inline void pqi_schedule_rescan_worker_with_delay( - struct pqi_ctrl_info *ctrl_info, unsigned long delay) +static inline void pqi_schedule_rescan_worker_with_delay(struct pqi_ctrl_info *ctrl_info, + unsigned long delay) { if (pqi_ctrl_offline(ctrl_info)) return; @@ -386,8 +383,7 @@ static inline void pqi_schedule_rescan_worker(struct pqi_ctrl_info *ctrl_info) #define PQI_RESCAN_WORK_DELAY (10 * PQI_HZ) -static inline void pqi_schedule_rescan_worker_delayed( - struct pqi_ctrl_info *ctrl_info) +static inline void pqi_schedule_rescan_worker_delayed(struct pqi_ctrl_info *ctrl_info) { pqi_schedule_rescan_worker_with_delay(ctrl_info, PQI_RESCAN_WORK_DELAY); } @@ -418,8 +414,7 @@ static inline u8 pqi_read_soft_reset_status(struct pqi_ctrl_info *ctrl_info) return readb(ctrl_info->soft_reset_status); } -static inline void pqi_clear_soft_reset_status(struct pqi_ctrl_info *ctrl_info, - u8 clear) +static inline void pqi_clear_soft_reset_status(struct pqi_ctrl_info *ctrl_info, u8 clear) { u8 status; @@ -616,9 +611,8 @@ static int pqi_send_scsi_raid_request(struct pqi_ctrl_info *ctrl_info, u8 cmd, struct pqi_raid_path_request request; enum dma_data_direction dir; - rc = pqi_build_raid_path_request(ctrl_info, &request, - cmd, scsi3addr, buffer, - buffer_length, vpd_page, &dir); + rc = pqi_build_raid_path_request(ctrl_info, &request, cmd, scsi3addr, + buffer, buffer_length, vpd_page, &dir); if (rc) return rc; @@ -738,17 +732,15 @@ static int pqi_get_advanced_raid_bypass_config(struct pqi_ctrl_info *ctrl_info) if (!buffer) return -ENOMEM; - rc = pqi_build_raid_path_request(ctrl_info, &request, - BMIC_SENSE_FEATURE, RAID_CTLR_LUNID, buffer, - sizeof(*buffer), 0, &dir); + rc = pqi_build_raid_path_request(ctrl_info, &request, BMIC_SENSE_FEATURE, RAID_CTLR_LUNID, + buffer, sizeof(*buffer), 0, &dir); if (rc) goto error; request.cdb[2] = BMIC_SENSE_FEATURE_IO_PAGE; request.cdb[3] = BMIC_SENSE_FEATURE_IO_PAGE_AIO_SUBPAGE; - rc = pqi_submit_raid_request_synchronous(ctrl_info, &request.header, - 0, NULL, NO_TIMEOUT); + rc = pqi_submit_raid_request_synchronous(ctrl_info, &request.header, 0, NULL, NO_TIMEOUT); pqi_pci_unmap(ctrl_info->pci_dev, request.sg_descriptors, 1, dir); @@ -998,27 +990,23 @@ static void pqi_update_time_worker(struct work_struct *work) PQI_UPDATE_TIME_WORK_INTERVAL); } -static inline void pqi_schedule_update_time_worker( - struct pqi_ctrl_info *ctrl_info) +static inline void pqi_schedule_update_time_worker(struct pqi_ctrl_info *ctrl_info) { schedule_delayed_work(&ctrl_info->update_time_work, 0); } -static inline void pqi_cancel_update_time_worker( - struct pqi_ctrl_info *ctrl_info) +static inline void pqi_cancel_update_time_worker(struct pqi_ctrl_info *ctrl_info) { cancel_delayed_work_sync(&ctrl_info->update_time_work); } -static inline int pqi_report_luns(struct pqi_ctrl_info *ctrl_info, u8 cmd, - void *buffer, size_t buffer_length) +static inline int pqi_report_luns(struct pqi_ctrl_info *ctrl_info, u8 cmd, void *buffer, + size_t buffer_length) { - return pqi_send_ctrl_raid_request(ctrl_info, cmd, buffer, - buffer_length); + return pqi_send_ctrl_raid_request(ctrl_info, cmd, buffer, buffer_length); } -static int pqi_report_phys_logical_luns(struct pqi_ctrl_info *ctrl_info, u8 cmd, - void **buffer) +static int pqi_report_phys_logical_luns(struct pqi_ctrl_info *ctrl_info, u8 cmd, void **buffer) { int rc; size_t lun_list_length; @@ -1033,8 +1021,7 @@ static int pqi_report_phys_logical_luns(struct pqi_ctrl_info *ctrl_info, u8 cmd, goto out; } - rc = pqi_report_luns(ctrl_info, cmd, report_lun_header, - sizeof(*report_lun_header)); + rc = pqi_report_luns(ctrl_info, cmd, report_lun_header, sizeof(*report_lun_header)); if (rc) goto out; @@ -1058,8 +1045,8 @@ again: if (rc) goto out; - new_lun_list_length = get_unaligned_be32( - &((struct report_lun_header *)lun_data)->list_length); + new_lun_list_length = + get_unaligned_be32(&((struct report_lun_header *)lun_data)->list_length); if (new_lun_list_length > lun_list_length) { lun_list_length = new_lun_list_length; @@ -1080,15 +1067,12 @@ out: return rc; } -static inline int pqi_report_phys_luns(struct pqi_ctrl_info *ctrl_info, - void **buffer) +static inline int pqi_report_phys_luns(struct pqi_ctrl_info *ctrl_info, void **buffer) { - return pqi_report_phys_logical_luns(ctrl_info, CISS_REPORT_PHYS, - buffer); + return pqi_report_phys_logical_luns(ctrl_info, CISS_REPORT_PHYS, buffer); } -static inline int pqi_report_logical_luns(struct pqi_ctrl_info *ctrl_info, - void **buffer) +static inline int pqi_report_logical_luns(struct pqi_ctrl_info *ctrl_info, void **buffer) { return pqi_report_phys_logical_luns(ctrl_info, CISS_REPORT_LOG, buffer); } @@ -1311,7 +1295,7 @@ static int pqi_get_raid_map(struct pqi_ctrl_info *ctrl_info, if (get_unaligned_le32(&raid_map->structure_size) != raid_map_size) { dev_warn(&ctrl_info->pci_dev->dev, - "Requested %d bytes, received %d bytes", + "requested %u bytes, received %u bytes\n", raid_map_size, get_unaligned_le32(&raid_map->structure_size)); goto error; @@ -1668,8 +1652,7 @@ static int pqi_add_device(struct pqi_ctrl_info *ctrl_info, #define PQI_PENDING_IO_TIMEOUT_SECS 20 -static inline void pqi_remove_device(struct pqi_ctrl_info *ctrl_info, - struct pqi_scsi_dev *device) +static inline void pqi_remove_device(struct pqi_ctrl_info *ctrl_info, struct pqi_scsi_dev *device) { int rc; @@ -1703,8 +1686,7 @@ static struct pqi_scsi_dev *pqi_find_scsi_dev(struct pqi_ctrl_info *ctrl_info, return NULL; } -static inline bool pqi_device_equal(struct pqi_scsi_dev *dev1, - struct pqi_scsi_dev *dev2) +static inline bool pqi_device_equal(struct pqi_scsi_dev *dev1, struct pqi_scsi_dev *dev2) { if (dev1->is_physical_device != dev2->is_physical_device) return false; @@ -1712,8 +1694,7 @@ static inline bool pqi_device_equal(struct pqi_scsi_dev *dev1, if (dev1->is_physical_device) return dev1->wwid == dev2->wwid; - return memcmp(dev1->volume_id, dev2->volume_id, - sizeof(dev1->volume_id)) == 0; + return memcmp(dev1->volume_id, dev2->volume_id, sizeof(dev1->volume_id)) == 0; } enum pqi_find_result { @@ -1852,8 +1833,7 @@ static void pqi_scsi_update_device(struct pqi_scsi_dev *existing_device, existing_device->bay = new_device->bay; existing_device->box_index = new_device->box_index; existing_device->phys_box_on_bus = new_device->phys_box_on_bus; - existing_device->phy_connected_dev_type = - new_device->phy_connected_dev_type; + existing_device->phy_connected_dev_type = new_device->phy_connected_dev_type; memcpy(existing_device->box, new_device->box, sizeof(existing_device->box)); memcpy(existing_device->phys_connector, new_device->phys_connector, @@ -2012,15 +1992,10 @@ static void pqi_update_device_list(struct pqi_ctrl_info *ctrl_info, * Notify the SCSI ML if the queue depth of any existing device has * changed. */ - list_for_each_entry(device, &ctrl_info->scsi_device_list, - scsi_device_list_entry) { - if (device->sdev) { - if (device->queue_depth != - device->advertised_queue_depth) { - device->advertised_queue_depth = device->queue_depth; - scsi_change_queue_depth(device->sdev, - device->advertised_queue_depth); - } + list_for_each_entry(device, &ctrl_info->scsi_device_list, scsi_device_list_entry) { + if (device->sdev && device->queue_depth != device->advertised_queue_depth) { + device->advertised_queue_depth = device->queue_depth; + scsi_change_queue_depth(device->sdev, device->advertised_queue_depth); if (device->rescan) { scsi_rescan_device(&device->sdev->sdev_gendev); device->rescan = false; @@ -2056,7 +2031,7 @@ static inline bool pqi_is_supported_device(struct pqi_scsi_dev *device) */ if (device->device_type == SA_DEVICE_TYPE_CONTROLLER && !pqi_is_hba_lunid(device->scsi3addr)) - return false; + return false; return true; } @@ -2089,8 +2064,7 @@ static inline bool pqi_is_device_with_sas_address(struct pqi_scsi_dev *device) static inline bool pqi_expose_device(struct pqi_scsi_dev *device) { - return !device->is_physical_device || - !pqi_skip_device(device->scsi3addr); + return !device->is_physical_device || !pqi_skip_device(device->scsi3addr); } static int pqi_update_scsi_devices(struct pqi_ctrl_info *ctrl_info) @@ -2154,11 +2128,8 @@ static int pqi_update_scsi_devices(struct pqi_ctrl_info *ctrl_info) for (i = num_physicals - 1; i >= 0; i--) { phys_lun_ext_entry = &physdev_list->lun_entries[i]; - if (CISS_GET_DRIVE_NUMBER( - phys_lun_ext_entry->lunid) == - PQI_VSEP_CISS_BTL) { - pqi_mask_device( - phys_lun_ext_entry->lunid); + if (CISS_GET_DRIVE_NUMBER(phys_lun_ext_entry->lunid) == PQI_VSEP_CISS_BTL) { + pqi_mask_device(phys_lun_ext_entry->lunid); break; } } @@ -2248,8 +2219,7 @@ static int pqi_update_scsi_devices(struct pqi_ctrl_info *ctrl_info) if (device->is_physical_device) dev_warn(&ctrl_info->pci_dev->dev, "obtaining device info failed, skipping physical device %016llx\n", - get_unaligned_be64( - &phys_lun_ext_entry->wwid)); + get_unaligned_be64(&phys_lun_ext_entry->wwid)); else dev_warn(&ctrl_info->pci_dev->dev, "obtaining device info failed, skipping logical device %08x%08x\n", @@ -2266,9 +2236,9 @@ static int pqi_update_scsi_devices(struct pqi_ctrl_info *ctrl_info) if ((phys_lun_ext_entry->device_flags & CISS_REPORT_PHYS_DEV_FLAG_AIO_ENABLED) && phys_lun_ext_entry->aio_handle) { - device->aio_enabled = true; - device->aio_handle = - phys_lun_ext_entry->aio_handle; + device->aio_enabled = true; + device->aio_handle = + phys_lun_ext_entry->aio_handle; } } else { memcpy(device->volume_id, log_lun_ext_entry->volume_id, @@ -2361,9 +2331,8 @@ static void pqi_wait_until_ofa_finished(struct pqi_ctrl_info *ctrl_info) mutex_unlock(&ctrl_info->ofa_mutex); } -static inline void pqi_set_encryption_info( - struct pqi_encryption_info *encryption_info, struct raid_map *raid_map, - u64 first_block) +static inline void pqi_set_encryption_info(struct pqi_encryption_info *encryption_info, + struct raid_map *raid_map, u64 first_block) { u32 volume_blk_size; @@ -2425,7 +2394,7 @@ static bool pqi_aio_raid_level_supported(struct pqi_ctrl_info *ctrl_info, #define PQI_RAID_BYPASS_INELIGIBLE 1 static int pqi_get_aio_lba_and_block_count(struct scsi_cmnd *scmd, - struct pqi_scsi_dev_raid_map_data *rmd) + struct pqi_scsi_dev_raid_map_data *rmd) { /* Check for valid opcode, get LBA and block count. */ switch (scmd->cmnd[0]) { @@ -2471,8 +2440,7 @@ static int pqi_get_aio_lba_and_block_count(struct scsi_cmnd *scmd, } static int pci_get_aio_common_raid_map_values(struct pqi_ctrl_info *ctrl_info, - struct pqi_scsi_dev_raid_map_data *rmd, - struct raid_map *raid_map) + struct pqi_scsi_dev_raid_map_data *rmd, struct raid_map *raid_map) { #if BITS_PER_LONG == 32 u64 tmpdiv; @@ -2487,7 +2455,7 @@ static int pci_get_aio_common_raid_map_values(struct pqi_ctrl_info *ctrl_info, return PQI_RAID_BYPASS_INELIGIBLE; rmd->data_disks_per_row = - get_unaligned_le16(&raid_map->data_disks_per_row); + get_unaligned_le16(&raid_map->data_disks_per_row); rmd->strip_size = get_unaligned_le16(&raid_map->strip_size); rmd->layout_map_count = get_unaligned_le16(&raid_map->layout_map_count); @@ -2512,16 +2480,16 @@ static int pci_get_aio_common_raid_map_values(struct pqi_ctrl_info *ctrl_info, rmd->first_row = rmd->first_block / rmd->blocks_per_row; rmd->last_row = rmd->last_block / rmd->blocks_per_row; rmd->first_row_offset = (u32)(rmd->first_block - - (rmd->first_row * rmd->blocks_per_row)); + (rmd->first_row * rmd->blocks_per_row)); rmd->last_row_offset = (u32)(rmd->last_block - (rmd->last_row * - rmd->blocks_per_row)); + rmd->blocks_per_row)); rmd->first_column = rmd->first_row_offset / rmd->strip_size; rmd->last_column = rmd->last_row_offset / rmd->strip_size; #endif /* If this isn't a single row/column then give to the controller. */ if (rmd->first_row != rmd->last_row || - rmd->first_column != rmd->last_column) + rmd->first_column != rmd->last_column) return PQI_RAID_BYPASS_INELIGIBLE; /* Proceeding with driver mapping. */ @@ -2531,19 +2499,19 @@ static int pci_get_aio_common_raid_map_values(struct pqi_ctrl_info *ctrl_info, raid_map->parity_rotation_shift)) % get_unaligned_le16(&raid_map->row_cnt); rmd->map_index = (rmd->map_row * rmd->total_disks_per_row) + - rmd->first_column; + rmd->first_column; return 0; } static int pqi_calc_aio_r5_or_r6(struct pqi_scsi_dev_raid_map_data *rmd, - struct raid_map *raid_map) + struct raid_map *raid_map) { #if BITS_PER_LONG == 32 u64 tmpdiv; #endif /* RAID 50/60 */ - /* Verify first and last block are in same RAID group */ + /* Verify first and last block are in same RAID group. */ rmd->stripesize = rmd->blocks_per_row * rmd->layout_map_count; #if BITS_PER_LONG == 32 tmpdiv = rmd->first_block; @@ -2563,7 +2531,7 @@ static int pqi_calc_aio_r5_or_r6(struct pqi_scsi_dev_raid_map_data *rmd, if (rmd->first_group != rmd->last_group) return PQI_RAID_BYPASS_INELIGIBLE; - /* Verify request is in a single row of RAID 5/6 */ + /* Verify request is in a single row of RAID 5/6. */ #if BITS_PER_LONG == 32 tmpdiv = rmd->first_block; do_div(tmpdiv, rmd->stripesize); @@ -2580,7 +2548,7 @@ static int pqi_calc_aio_r5_or_r6(struct pqi_scsi_dev_raid_map_data *rmd, if (rmd->r5or6_first_row != rmd->r5or6_last_row) return PQI_RAID_BYPASS_INELIGIBLE; - /* Verify request is in a single column */ + /* Verify request is in a single column. */ #if BITS_PER_LONG == 32 tmpdiv = rmd->first_block; rmd->first_row_offset = do_div(tmpdiv, rmd->stripesize); @@ -2599,23 +2567,22 @@ static int pqi_calc_aio_r5_or_r6(struct pqi_scsi_dev_raid_map_data *rmd, rmd->r5or6_last_column = tmpdiv; #else rmd->first_row_offset = rmd->r5or6_first_row_offset = - (u32)((rmd->first_block % - rmd->stripesize) % - rmd->blocks_per_row); + (u32)((rmd->first_block % rmd->stripesize) % + rmd->blocks_per_row); rmd->r5or6_last_row_offset = (u32)((rmd->last_block % rmd->stripesize) % rmd->blocks_per_row); rmd->first_column = - rmd->r5or6_first_row_offset / rmd->strip_size; + rmd->r5or6_first_row_offset / rmd->strip_size; rmd->r5or6_first_column = rmd->first_column; rmd->r5or6_last_column = rmd->r5or6_last_row_offset / rmd->strip_size; #endif if (rmd->r5or6_first_column != rmd->r5or6_last_column) return PQI_RAID_BYPASS_INELIGIBLE; - /* Request is eligible */ + /* Request is eligible. */ rmd->map_row = ((u32)(rmd->first_row >> raid_map->parity_rotation_shift)) % get_unaligned_le16(&raid_map->row_cnt); @@ -2683,7 +2650,7 @@ static void pqi_set_aio_cdb(struct pqi_scsi_dev_raid_map_data *rmd) } static void pqi_calc_aio_r1_nexus(struct raid_map *raid_map, - struct pqi_scsi_dev_raid_map_data *rmd) + struct pqi_scsi_dev_raid_map_data *rmd) { u32 index; u32 group; @@ -2712,7 +2679,7 @@ static int pqi_raid_bypass_submit_scsi_cmd(struct pqi_ctrl_info *ctrl_info, u32 next_bypass_group; struct pqi_encryption_info *encryption_info_ptr; struct pqi_encryption_info encryption_info; - struct pqi_scsi_dev_raid_map_data rmd = {0}; + struct pqi_scsi_dev_raid_map_data rmd = { 0 }; rc = pqi_get_aio_lba_and_block_count(scmd, &rmd); if (rc) @@ -2772,12 +2739,10 @@ static int pqi_raid_bypass_submit_scsi_cmd(struct pqi_ctrl_info *ctrl_info, pqi_set_aio_cdb(&rmd); - if (get_unaligned_le16(&raid_map->flags) & - RAID_MAP_ENCRYPTION_ENABLED) { + if (get_unaligned_le16(&raid_map->flags) & RAID_MAP_ENCRYPTION_ENABLED) { if (rmd.data_length > device->max_transfer_encrypted) return PQI_RAID_BYPASS_INELIGIBLE; - pqi_set_encryption_info(&encryption_info, raid_map, - rmd.first_block); + pqi_set_encryption_info(&encryption_info, raid_map, rmd.first_block); encryption_info_ptr = &encryption_info; } else { encryption_info_ptr = NULL; @@ -2792,7 +2757,7 @@ static int pqi_raid_bypass_submit_scsi_cmd(struct pqi_ctrl_info *ctrl_info, case SA_RAID_5: case SA_RAID_6: return pqi_aio_submit_r56_write_io(ctrl_info, scmd, queue_group, - encryption_info_ptr, device, &rmd); + encryption_info_ptr, device, &rmd); } } @@ -3178,8 +3143,7 @@ static int pqi_process_io_intr(struct pqi_ctrl_info *ctrl_info, struct pqi_queue case PQI_RESPONSE_IU_VENDOR_GENERAL: io_request->status = get_unaligned_le16( - &((struct pqi_vendor_general_response *) - response)->status); + &((struct pqi_vendor_general_response *)response)->status); break; case PQI_RESPONSE_IU_TASK_MANAGEMENT: io_request->status = @@ -3304,8 +3268,8 @@ static void pqi_acknowledge_event(struct pqi_ctrl_info *ctrl_info, static enum pqi_soft_reset_status pqi_poll_for_soft_reset_status( struct pqi_ctrl_info *ctrl_info) { - unsigned long timeout; u8 status; + unsigned long timeout; timeout = (PQI_SOFT_RESET_STATUS_TIMEOUT_SECS * PQI_HZ) + jiffies; @@ -3391,7 +3355,7 @@ static void pqi_ofa_process_event(struct pqi_ctrl_info *ctrl_info, pqi_ofa_setup_host_buffer(ctrl_info, le32_to_cpu(event->ofa_bytes_requested)); pqi_ofa_host_memory_update(ctrl_info); - } else if (event_id == PQI_EVENT_OFA_CANCELLED) { + } else if (event_id == PQI_EVENT_OFA_CANCELED) { pqi_ofa_free_host_buffer(ctrl_info); pqi_acknowledge_event(ctrl_info, event); dev_info(&ctrl_info->pci_dev->dev, @@ -3441,8 +3405,7 @@ static void pqi_heartbeat_timer_handler(struct timer_list *t) { int num_interrupts; u32 heartbeat_count; - struct pqi_ctrl_info *ctrl_info = from_timer(ctrl_info, t, - heartbeat_timer); + struct pqi_ctrl_info *ctrl_info = from_timer(ctrl_info, t, heartbeat_timer); pqi_check_ctrl_health(ctrl_info); if (pqi_ctrl_offline(ctrl_info)) @@ -3515,7 +3478,7 @@ static void pqi_ofa_capture_event_payload(struct pqi_event *event, if (event_id == PQI_EVENT_OFA_MEMORY_ALLOCATION) { event->ofa_bytes_requested = response->data.ofa_memory_allocation.bytes_requested; - } else if (event_id == PQI_EVENT_OFA_CANCELLED) { + } else if (event_id == PQI_EVENT_OFA_CANCELED) { event->ofa_cancel_reason = response->data.ofa_cancelled.reason; } @@ -3552,8 +3515,7 @@ static int pqi_process_event_intr(struct pqi_ctrl_info *ctrl_info) num_events++; response = event_queue->oq_element_array + (oq_ci * PQI_EVENT_OQ_ELEMENT_LENGTH); - event_index = - pqi_event_type_to_event_index(response->event_type); + event_index = pqi_event_type_to_event_index(response->event_type); if (event_index >= 0 && response->request_acknowledge) { event = &ctrl_info->events[event_index]; @@ -3579,8 +3541,7 @@ static int pqi_process_event_intr(struct pqi_ctrl_info *ctrl_info) #define PQI_LEGACY_INTX_MASK 0x1 -static inline void pqi_configure_legacy_intx(struct pqi_ctrl_info *ctrl_info, - bool enable_intx) +static inline void pqi_configure_legacy_intx(struct pqi_ctrl_info *ctrl_info, bool enable_intx) { u32 intx_mask; struct pqi_device_registers __iomem *pqi_registers; @@ -3657,8 +3618,7 @@ static inline bool pqi_is_valid_irq(struct pqi_ctrl_info *ctrl_info) valid_irq = true; break; case IRQ_MODE_INTX: - intx_status = - readl(&ctrl_info->pqi_registers->legacy_intx_status); + intx_status = readl(&ctrl_info->pqi_registers->legacy_intx_status); if (intx_status & PQI_LEGACY_INTX_PENDING) valid_irq = true; else @@ -3979,7 +3939,8 @@ static int pqi_alloc_admin_queues(struct pqi_ctrl_info *ctrl_info) &admin_queues_aligned->iq_element_array; admin_queues->oq_element_array = &admin_queues_aligned->oq_element_array; - admin_queues->iq_ci = &admin_queues_aligned->iq_ci; + admin_queues->iq_ci = + (pqi_index_t __iomem *)&admin_queues_aligned->iq_ci; admin_queues->oq_pi = (pqi_index_t __iomem *)&admin_queues_aligned->oq_pi; @@ -3993,8 +3954,8 @@ static int pqi_alloc_admin_queues(struct pqi_ctrl_info *ctrl_info) ctrl_info->admin_queue_memory_base); admin_queues->iq_ci_bus_addr = ctrl_info->admin_queue_memory_base_dma_handle + - ((void *)admin_queues->iq_ci - - ctrl_info->admin_queue_memory_base); + ((void __iomem *)admin_queues->iq_ci - + (void __iomem *)ctrl_info->admin_queue_memory_base); admin_queues->oq_pi_bus_addr = ctrl_info->admin_queue_memory_base_dma_handle + ((void __iomem *)admin_queues->oq_pi - @@ -4030,6 +3991,7 @@ static int pqi_create_admin_queues(struct pqi_ctrl_info *ctrl_info) (PQI_ADMIN_OQ_NUM_ELEMENTS << 8) | (admin_queues->int_msg_num << 16); writel(reg, &pqi_registers->admin_iq_num_elements); + writel(PQI_CREATE_ADMIN_QUEUE_PAIR, &pqi_registers->function_and_status_code); @@ -4326,8 +4288,7 @@ static int pqi_submit_raid_request_synchronous(struct pqi_ctrl_info *ctrl_info, io_request->io_complete_callback = pqi_raid_synchronous_complete; io_request->context = &wait; - pqi_start_io(ctrl_info, - &ctrl_info->queue_groups[PQI_DEFAULT_QUEUE_GROUP], RAID_PATH, + pqi_start_io(ctrl_info, &ctrl_info->queue_groups[PQI_DEFAULT_QUEUE_GROUP], RAID_PATH, io_request); pqi_ctrl_unbusy(ctrl_info); @@ -4345,13 +4306,11 @@ static int pqi_submit_raid_request_synchronous(struct pqi_ctrl_info *ctrl_info, if (error_info) { if (io_request->error_info) - memcpy(error_info, io_request->error_info, - sizeof(*error_info)); + memcpy(error_info, io_request->error_info, sizeof(*error_info)); else memset(error_info, 0, sizeof(*error_info)); } else if (rc == 0 && io_request->error_info) { - rc = pqi_process_raid_io_error_synchronous( - io_request->error_info); + rc = pqi_process_raid_io_error_synchronous(io_request->error_info); } pqi_free_io_request(io_request); @@ -4429,8 +4388,7 @@ static int pqi_report_device_capability(struct pqi_ctrl_info *ctrl_info) if (rc) goto out; - rc = pqi_submit_admin_request_synchronous(ctrl_info, &request, - &response); + rc = pqi_submit_admin_request_synchronous(ctrl_info, &request, &response); pqi_pci_unmap(ctrl_info->pci_dev, &request.data.report_device_capability.sg_descriptor, 1, @@ -4779,7 +4737,7 @@ static int pqi_configure_events(struct pqi_ctrl_info *ctrl_info, event_descriptor = &event_config->descriptors[i]; if (enable_events && pqi_is_supported_event(event_descriptor->event_type)) - put_unaligned_le16(ctrl_info->event_queue.oq_id, + put_unaligned_le16(ctrl_info->event_queue.oq_id, &event_descriptor->oq_id); else put_unaligned_le16(0, &event_descriptor->oq_id); @@ -4854,7 +4812,6 @@ static void pqi_free_all_io_requests(struct pqi_ctrl_info *ctrl_info) static inline int pqi_alloc_error_buffer(struct pqi_ctrl_info *ctrl_info) { - ctrl_info->error_buffer = dma_alloc_coherent(&ctrl_info->pci_dev->dev, ctrl_info->error_buffer_length, &ctrl_info->error_buffer_dma_handle, @@ -4874,9 +4831,8 @@ static int pqi_alloc_io_resources(struct pqi_ctrl_info *ctrl_info) struct device *dev; struct pqi_io_request *io_request; - ctrl_info->io_request_pool = - kcalloc(ctrl_info->max_io_slots, - sizeof(ctrl_info->io_request_pool[0]), GFP_KERNEL); + ctrl_info->io_request_pool = kcalloc(ctrl_info->max_io_slots, + sizeof(ctrl_info->io_request_pool[0]), GFP_KERNEL); if (!ctrl_info->io_request_pool) { dev_err(&ctrl_info->pci_dev->dev, @@ -4889,8 +4845,7 @@ static int pqi_alloc_io_resources(struct pqi_ctrl_info *ctrl_info) io_request = ctrl_info->io_request_pool; for (i = 0; i < ctrl_info->max_io_slots; i++) { - io_request->iu = - kmalloc(ctrl_info->max_inbound_iu_length, GFP_KERNEL); + io_request->iu = kmalloc(ctrl_info->max_inbound_iu_length, GFP_KERNEL); if (!io_request->iu) { dev_err(&ctrl_info->pci_dev->dev, @@ -4910,8 +4865,7 @@ static int pqi_alloc_io_resources(struct pqi_ctrl_info *ctrl_info) io_request->index = i; io_request->sg_chain_buffer = sg_chain_buffer; - io_request->sg_chain_buffer_dma_handle = - sg_chain_buffer_dma_handle; + io_request->sg_chain_buffer_dma_handle = sg_chain_buffer_dma_handle; io_request++; } @@ -5026,8 +4980,8 @@ static void pqi_calculate_queue_resources(struct pqi_ctrl_info *ctrl_info) PQI_MAX_EMBEDDED_R56_SG_DESCRIPTORS; } -static inline void pqi_set_sg_descriptor( - struct pqi_sg_descriptor *sg_descriptor, struct scatterlist *sg) +static inline void pqi_set_sg_descriptor(struct pqi_sg_descriptor *sg_descriptor, + struct scatterlist *sg) { u64 address = (u64)sg_dma_address(sg); unsigned int length = sg_dma_len(sg); @@ -5247,16 +5201,14 @@ static int pqi_raid_submit_scsi_cmd_with_io_request( io_request->scmd = scmd; request = io_request->iu; - memset(request, 0, - offsetof(struct pqi_raid_path_request, sg_descriptors)); + memset(request, 0, offsetof(struct pqi_raid_path_request, sg_descriptors)); request->header.iu_type = PQI_REQUEST_IU_RAID_PATH_IO; put_unaligned_le32(scsi_bufflen(scmd), &request->buffer_length); request->task_attribute = SOP_TASK_ATTRIBUTE_SIMPLE; put_unaligned_le16(io_request->index, &request->request_id); request->error_index = request->request_id; - memcpy(request->lun_number, device->scsi3addr, - sizeof(request->lun_number)); + memcpy(request->lun_number, device->scsi3addr, sizeof(request->lun_number)); cdb_length = min_t(size_t, scmd->cmd_len, sizeof(request->cdb)); memcpy(request->cdb, scmd->cmnd, cdb_length); @@ -5266,30 +5218,20 @@ static int pqi_raid_submit_scsi_cmd_with_io_request( case 10: case 12: case 16: - /* No bytes in the Additional CDB bytes field */ - request->additional_cdb_bytes_usage = - SOP_ADDITIONAL_CDB_BYTES_0; + request->additional_cdb_bytes_usage = SOP_ADDITIONAL_CDB_BYTES_0; break; case 20: - /* 4 bytes in the Additional cdb field */ - request->additional_cdb_bytes_usage = - SOP_ADDITIONAL_CDB_BYTES_4; + request->additional_cdb_bytes_usage = SOP_ADDITIONAL_CDB_BYTES_4; break; case 24: - /* 8 bytes in the Additional cdb field */ - request->additional_cdb_bytes_usage = - SOP_ADDITIONAL_CDB_BYTES_8; + request->additional_cdb_bytes_usage = SOP_ADDITIONAL_CDB_BYTES_8; break; case 28: - /* 12 bytes in the Additional cdb field */ - request->additional_cdb_bytes_usage = - SOP_ADDITIONAL_CDB_BYTES_12; + request->additional_cdb_bytes_usage = SOP_ADDITIONAL_CDB_BYTES_12; break; case 32: default: - /* 16 bytes in the Additional cdb field */ - request->additional_cdb_bytes_usage = - SOP_ADDITIONAL_CDB_BYTES_16; + request->additional_cdb_bytes_usage = SOP_ADDITIONAL_CDB_BYTES_16; break; } @@ -5534,8 +5476,7 @@ static int pqi_aio_submit_io(struct pqi_ctrl_info *ctrl_info, io_request->raid_bypass = raid_bypass; request = io_request->iu; - memset(request, 0, - offsetof(struct pqi_raid_path_request, sg_descriptors)); + memset(request, 0, offsetof(struct pqi_raid_path_request, sg_descriptors)); request->header.iu_type = PQI_REQUEST_IU_AIO_PATH_IO; put_unaligned_le32(aio_handle, &request->nexus_id); @@ -5593,7 +5534,6 @@ static int pqi_aio_submit_r1_write_io(struct pqi_ctrl_info *ctrl_info, struct scsi_cmnd *scmd, struct pqi_queue_group *queue_group, struct pqi_encryption_info *encryption_info, struct pqi_scsi_dev *device, struct pqi_scsi_dev_raid_map_data *rmd) - { int rc; struct pqi_io_request *io_request; @@ -5608,7 +5548,6 @@ static int pqi_aio_submit_r1_write_io(struct pqi_ctrl_info *ctrl_info, memset(r1_request, 0, offsetof(struct pqi_aio_r1_path_request, sg_descriptors)); r1_request->header.iu_type = PQI_REQUEST_IU_AIO_PATH_RAID1_IO; - put_unaligned_le16(*(u16 *)device->scsi3addr & 0x3fff, &r1_request->volume_id); r1_request->num_drives = rmd->num_it_nexus_entries; put_unaligned_le32(rmd->it_nexus[0], &r1_request->it_nexus_1); @@ -5760,7 +5699,6 @@ static int pqi_scsi_queue_command(struct Scsi_Host *shost, bool raid_bypassed; device = scmd->device->hostdata; - ctrl_info = shost_to_hba(shost); if (!device) { set_host_byte(scmd, DID_NO_CONNECT); @@ -5770,6 +5708,8 @@ static int pqi_scsi_queue_command(struct Scsi_Host *shost, atomic_inc(&device->scsi_cmds_outstanding); + ctrl_info = shost_to_hba(shost); + if (pqi_ctrl_offline(ctrl_info) || pqi_device_in_remove(device)) { set_host_byte(scmd, DID_NO_CONNECT); pqi_scsi_done(scmd); @@ -5903,6 +5843,7 @@ static void pqi_fail_io_queued_for_device(struct pqi_ctrl_info *ctrl_info, list_for_each_entry_safe(io_request, next, &queue_group->request_list[path], request_list_entry) { + scmd = io_request->scmd; if (!scmd) continue; @@ -6100,8 +6041,7 @@ static int pqi_lun_reset(struct pqi_ctrl_info *ctrl_info, put_unaligned_le16(PQI_LUN_RESET_TIMEOUT_SECS, &request->timeout); - pqi_start_io(ctrl_info, - &ctrl_info->queue_groups[PQI_DEFAULT_QUEUE_GROUP], RAID_PATH, + pqi_start_io(ctrl_info, &ctrl_info->queue_groups[PQI_DEFAULT_QUEUE_GROUP], RAID_PATH, io_request); rc = pqi_wait_for_lun_reset_completion(ctrl_info, device, &wait); @@ -6741,8 +6681,8 @@ static DEVICE_ATTR(model, 0444, pqi_model_show, NULL); static DEVICE_ATTR(serial_number, 0444, pqi_serial_number_show, NULL); static DEVICE_ATTR(vendor, 0444, pqi_vendor_show, NULL); static DEVICE_ATTR(rescan, 0200, NULL, pqi_host_rescan_store); -static DEVICE_ATTR(lockup_action, 0644, - pqi_lockup_action_show, pqi_lockup_action_store); +static DEVICE_ATTR(lockup_action, 0644, pqi_lockup_action_show, + pqi_lockup_action_store); static DEVICE_ATTR(enable_r5_writes, 0644, pqi_host_enable_r5_writes_show, pqi_host_enable_r5_writes_store); static DEVICE_ATTR(enable_r6_writes, 0644, @@ -6791,7 +6731,8 @@ static ssize_t pqi_unique_id_show(struct device *dev, spin_unlock_irqrestore(&ctrl_info->scsi_device_list_lock, flags); return snprintf(buffer, PAGE_SIZE, - "%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X\n", + "%02X%02X%02X%02X%02X%02X%02X%02X" + "%02X%02X%02X%02X%02X%02X%02X%02X\n", unique_id[0], unique_id[1], unique_id[2], unique_id[3], unique_id[4], unique_id[5], unique_id[6], unique_id[7], unique_id[8], unique_id[9], unique_id[10], unique_id[11], @@ -7066,9 +7007,7 @@ static int pqi_register_scsi(struct pqi_ctrl_info *ctrl_info) shost = scsi_host_alloc(&pqi_driver_template, sizeof(ctrl_info)); if (!shost) { - dev_err(&ctrl_info->pci_dev->dev, - "scsi_host_alloc failed for controller %u\n", - ctrl_info->ctrl_id); + dev_err(&ctrl_info->pci_dev->dev, "scsi_host_alloc failed\n"); return -ENOMEM; } @@ -7092,17 +7031,13 @@ static int pqi_register_scsi(struct pqi_ctrl_info *ctrl_info) rc = scsi_add_host(shost, &ctrl_info->pci_dev->dev); if (rc) { - dev_err(&ctrl_info->pci_dev->dev, - "scsi_add_host failed for controller %u\n", - ctrl_info->ctrl_id); + dev_err(&ctrl_info->pci_dev->dev, "scsi_add_host failed\n"); goto free_host; } rc = pqi_add_sas_host(shost, ctrl_info); if (rc) { - dev_err(&ctrl_info->pci_dev->dev, - "add SAS host failed for controller %u\n", - ctrl_info->ctrl_id); + dev_err(&ctrl_info->pci_dev->dev, "add SAS host failed\n"); goto remove_host; } @@ -7172,8 +7107,7 @@ static int pqi_reset(struct pqi_ctrl_info *ctrl_info) rc = sis_pqi_reset_quiesce(ctrl_info); if (rc) { dev_err(&ctrl_info->pci_dev->dev, - "PQI reset failed during quiesce with error %d\n", - rc); + "PQI reset failed during quiesce with error %d\n", rc); return rc; } } @@ -7414,12 +7348,10 @@ static void pqi_ctrl_update_feature_flags(struct pqi_ctrl_info *ctrl_info, firmware_feature->enabled; break; case PQI_FIRMWARE_FEATURE_RAID_IU_TIMEOUT: - ctrl_info->raid_iu_timeout_supported = - firmware_feature->enabled; + ctrl_info->raid_iu_timeout_supported = firmware_feature->enabled; break; case PQI_FIRMWARE_FEATURE_TMF_IU_TIMEOUT: - ctrl_info->tmf_iu_timeout_supported = - firmware_feature->enabled; + ctrl_info->tmf_iu_timeout_supported = firmware_feature->enabled; break; } @@ -7569,7 +7501,7 @@ static void pqi_process_firmware_features( if (pqi_is_firmware_feature_enabled(firmware_features, firmware_features_iomem_addr, pqi_firmware_features[i].feature_bit)) { - pqi_firmware_features[i].enabled = true; + pqi_firmware_features[i].enabled = true; } pqi_firmware_feature_update(ctrl_info, &pqi_firmware_features[i]); @@ -7626,22 +7558,19 @@ static int pqi_process_config_table(struct pqi_ctrl_info *ctrl_info) * Copy the config table contents from I/O memory space into the * temporary buffer. */ - table_iomem_addr = ctrl_info->iomem_base + - ctrl_info->config_table_offset; + table_iomem_addr = ctrl_info->iomem_base + ctrl_info->config_table_offset; memcpy_fromio(config_table, table_iomem_addr, table_length); firmware_feature_section_present = false; section_info.ctrl_info = ctrl_info; - section_offset = - get_unaligned_le32(&config_table->first_section_offset); + section_offset = get_unaligned_le32(&config_table->first_section_offset); while (section_offset) { section = (void *)config_table + section_offset; section_info.section = section; section_info.section_offset = section_offset; - section_info.section_iomem_addr = - table_iomem_addr + section_offset; + section_info.section_iomem_addr = table_iomem_addr + section_offset; switch (get_unaligned_le16(§ion->section_id)) { case PQI_CONFIG_TABLE_SECTION_FIRMWARE_FEATURES: @@ -7656,8 +7585,7 @@ static int pqi_process_config_table(struct pqi_ctrl_info *ctrl_info) ctrl_info->heartbeat_counter = table_iomem_addr + section_offset + - offsetof( - struct pqi_config_table_heartbeat, + offsetof(struct pqi_config_table_heartbeat, heartbeat_counter); break; case PQI_CONFIG_TABLE_SECTION_SOFT_RESET: @@ -7665,12 +7593,11 @@ static int pqi_process_config_table(struct pqi_ctrl_info *ctrl_info) table_iomem_addr + section_offset + offsetof(struct pqi_config_table_soft_reset, - soft_reset_status); + soft_reset_status); break; } - section_offset = - get_unaligned_le16(§ion->next_section_offset); + section_offset = get_unaligned_le16(§ion->next_section_offset); } /* @@ -7777,12 +7704,12 @@ static int pqi_ctrl_init(struct pqi_ctrl_info *ctrl_info) if (reset_devices) { if (ctrl_info->max_outstanding_requests > PQI_MAX_OUTSTANDING_REQUESTS_KDUMP) - ctrl_info->max_outstanding_requests = + ctrl_info->max_outstanding_requests = PQI_MAX_OUTSTANDING_REQUESTS_KDUMP; } else { if (ctrl_info->max_outstanding_requests > PQI_MAX_OUTSTANDING_REQUESTS) - ctrl_info->max_outstanding_requests = + ctrl_info->max_outstanding_requests = PQI_MAX_OUTSTANDING_REQUESTS; } @@ -8099,8 +8026,7 @@ static int pqi_ctrl_init_resume(struct pqi_ctrl_info *ctrl_info) return 0; } -static inline int pqi_set_pcie_completion_timeout(struct pci_dev *pci_dev, - u16 timeout) +static inline int pqi_set_pcie_completion_timeout(struct pci_dev *pci_dev, u16 timeout) { int rc; @@ -8352,8 +8278,8 @@ static int pqi_ofa_alloc_mem(struct pqi_ctrl_info *ctrl_info, break; mem_descriptor = &ofap->sg_descriptor[i]; - put_unaligned_le64 ((u64) dma_handle, &mem_descriptor->address); - put_unaligned_le32 (chunk_size, &mem_descriptor->length); + put_unaligned_le64((u64)dma_handle, &mem_descriptor->address); + put_unaligned_le32(chunk_size, &mem_descriptor->length); } if (!size || size < total_size) diff --git a/drivers/scsi/smartpqi/smartpqi_sas_transport.c b/drivers/scsi/smartpqi/smartpqi_sas_transport.c index c9b00b3368d7..77923c6ec2c6 100644 --- a/drivers/scsi/smartpqi/smartpqi_sas_transport.c +++ b/drivers/scsi/smartpqi/smartpqi_sas_transport.c @@ -107,8 +107,7 @@ static int pqi_sas_port_add_rphy(struct pqi_sas_port *pqi_sas_port, static struct sas_rphy *pqi_sas_rphy_alloc(struct pqi_sas_port *pqi_sas_port) { - if (pqi_sas_port->device && - pqi_sas_port->device->is_expander_smp_device) + if (pqi_sas_port->device && pqi_sas_port->device->is_expander_smp_device) return sas_expander_alloc(pqi_sas_port->port, SAS_FANOUT_EXPANDER_DEVICE); @@ -161,7 +160,7 @@ static void pqi_free_sas_port(struct pqi_sas_port *pqi_sas_port) list_for_each_entry_safe(pqi_sas_phy, next, &pqi_sas_port->phy_list_head, phy_list_entry) - pqi_free_sas_phy(pqi_sas_phy); + pqi_free_sas_phy(pqi_sas_phy); sas_port_delete(pqi_sas_port->port); list_del(&pqi_sas_port->port_list_entry); @@ -191,7 +190,7 @@ static void pqi_free_sas_node(struct pqi_sas_node *pqi_sas_node) list_for_each_entry_safe(pqi_sas_port, next, &pqi_sas_node->port_list_head, port_list_entry) - pqi_free_sas_port(pqi_sas_port); + pqi_free_sas_port(pqi_sas_port); kfree(pqi_sas_node); } @@ -498,7 +497,7 @@ static unsigned int pqi_build_sas_smp_handler_reply( job->reply_len = le16_to_cpu(error_info->sense_data_length); memcpy(job->reply, error_info->data, - le16_to_cpu(error_info->sense_data_length)); + le16_to_cpu(error_info->sense_data_length)); return job->reply_payload.payload_len - get_unaligned_le32(&error_info->data_in_transferred); @@ -547,6 +546,7 @@ void pqi_sas_smp_handler(struct bsg_job *job, struct Scsi_Host *shost, goto out; reslen = pqi_build_sas_smp_handler_reply(smp_buf, job, &error_info); + out: bsg_job_done(job, rc, reslen); } diff --git a/drivers/scsi/smartpqi/smartpqi_sis.c b/drivers/scsi/smartpqi/smartpqi_sis.c index f0199bd87dd1..c954620628e0 100644 --- a/drivers/scsi/smartpqi/smartpqi_sis.c +++ b/drivers/scsi/smartpqi/smartpqi_sis.c @@ -71,7 +71,7 @@ struct sis_base_struct { /* error response data */ __le32 error_buffer_element_length; /* length of each PQI error */ /* response buffer element */ - /* in bytes */ + /* in bytes */ __le32 error_buffer_num_elements; /* total number of PQI error */ /* response buffers available */ }; @@ -146,7 +146,7 @@ bool sis_is_firmware_running(struct pqi_ctrl_info *ctrl_info) bool sis_is_kernel_up(struct pqi_ctrl_info *ctrl_info) { return readl(&ctrl_info->registers->sis_firmware_status) & - SIS_CTRL_KERNEL_UP; + SIS_CTRL_KERNEL_UP; } u32 sis_get_product_id(struct pqi_ctrl_info *ctrl_info) From c7ffedb3a774a835450a518566639254534e72c4 Mon Sep 17 00:00:00 2001 From: Don Brace Date: Thu, 11 Mar 2021 14:15:56 -0600 Subject: [PATCH 289/412] scsi: smartpqi: Add stream detection Enhance performance by adding sequential stream detection for RAID5/RAID6 sequential write requests. Reduce stripe lock contention with full-stripe write operations. There is one common stripe lock for each RAID volume that can be set by either the RAID engine or the AIO engine. The AIO path has I/O request sizes well below the stripe size resulting in many Read-Modify-Write operations. Sending the request to the RAID engine allows for coalescing requests into full stripe operations resulting in reduced Read-Modify-Write operations. Link: https://lore.kernel.org/r/161549375693.25025.2962141451773219796.stgit@brunhilda Reviewed-by: Scott Benesh Reviewed-by: Mike McGowen Reviewed-by: Scott Teel Reviewed-by: Kevin Barnett Signed-off-by: Don Brace Signed-off-by: Martin K. Petersen --- drivers/scsi/smartpqi/smartpqi.h | 9 +++ drivers/scsi/smartpqi/smartpqi_init.c | 87 +++++++++++++++++++++++++-- 2 files changed, 90 insertions(+), 6 deletions(-) diff --git a/drivers/scsi/smartpqi/smartpqi.h b/drivers/scsi/smartpqi/smartpqi.h index 6639432f3dab..976bfd8c5192 100644 --- a/drivers/scsi/smartpqi/smartpqi.h +++ b/drivers/scsi/smartpqi/smartpqi.h @@ -1043,6 +1043,13 @@ struct pqi_scsi_dev_raid_map_data { #define RAID_CTLR_LUNID "\0\0\0\0\0\0\0\0" +#define NUM_STREAMS_PER_LUN 8 + +struct pqi_stream_data { + u64 next_lba; + u32 last_accessed; +}; + struct pqi_scsi_dev { int devtype; /* as reported by INQUIRY commmand */ u8 device_type; /* as reported by */ @@ -1097,6 +1104,7 @@ struct pqi_scsi_dev { struct list_head add_list_entry; struct list_head delete_list_entry; + struct pqi_stream_data stream_data[NUM_STREAMS_PER_LUN]; atomic_t scsi_cmds_outstanding; atomic_t raid_bypass_cnt; }; @@ -1296,6 +1304,7 @@ struct pqi_ctrl_info { u8 enable_r5_writes : 1; u8 enable_r6_writes : 1; u8 lv_drive_type_mix_valid : 1; + u8 enable_stream_detection : 1; u8 ciss_report_log_flags; u32 max_transfer_encrypted_sas_sata; diff --git a/drivers/scsi/smartpqi/smartpqi_init.c b/drivers/scsi/smartpqi/smartpqi_init.c index 143bb7b64095..27bd3d9a3810 100644 --- a/drivers/scsi/smartpqi/smartpqi_init.c +++ b/drivers/scsi/smartpqi/smartpqi_init.c @@ -5688,8 +5688,82 @@ void pqi_prep_for_scsi_done(struct scsi_cmnd *scmd) atomic_dec(&device->scsi_cmds_outstanding); } -static int pqi_scsi_queue_command(struct Scsi_Host *shost, +static bool pqi_is_parity_write_stream(struct pqi_ctrl_info *ctrl_info, struct scsi_cmnd *scmd) +{ + u32 oldest_jiffies; + u8 lru_index; + int i; + int rc; + struct pqi_scsi_dev *device; + struct pqi_stream_data *pqi_stream_data; + struct pqi_scsi_dev_raid_map_data rmd; + + if (!ctrl_info->enable_stream_detection) + return false; + + rc = pqi_get_aio_lba_and_block_count(scmd, &rmd); + if (rc) + return false; + + /* Check writes only. */ + if (!rmd.is_write) + return false; + + device = scmd->device->hostdata; + + /* Check for RAID 5/6 streams. */ + if (device->raid_level != SA_RAID_5 && device->raid_level != SA_RAID_6) + return false; + + /* + * If controller does not support AIO RAID{5,6} writes, need to send + * requests down non-AIO path. + */ + if ((device->raid_level == SA_RAID_5 && !ctrl_info->enable_r5_writes) || + (device->raid_level == SA_RAID_6 && !ctrl_info->enable_r6_writes)) + return true; + + lru_index = 0; + oldest_jiffies = INT_MAX; + for (i = 0; i < NUM_STREAMS_PER_LUN; i++) { + pqi_stream_data = &device->stream_data[i]; + /* + * Check for adjacent request or request is within + * the previous request. + */ + if ((pqi_stream_data->next_lba && + rmd.first_block >= pqi_stream_data->next_lba) && + rmd.first_block <= pqi_stream_data->next_lba + + rmd.block_cnt) { + pqi_stream_data->next_lba = rmd.first_block + + rmd.block_cnt; + pqi_stream_data->last_accessed = jiffies; + return true; + } + + /* unused entry */ + if (pqi_stream_data->last_accessed == 0) { + lru_index = i; + break; + } + + /* Find entry with oldest last accessed time. */ + if (pqi_stream_data->last_accessed <= oldest_jiffies) { + oldest_jiffies = pqi_stream_data->last_accessed; + lru_index = i; + } + } + + /* Set LRU entry. */ + pqi_stream_data = &device->stream_data[lru_index]; + pqi_stream_data->last_accessed = jiffies; + pqi_stream_data->next_lba = rmd.first_block + rmd.block_cnt; + + return false; +} + +static int pqi_scsi_queue_command(struct Scsi_Host *shost, struct scsi_cmnd *scmd) { int rc; struct pqi_ctrl_info *ctrl_info; @@ -5736,11 +5810,12 @@ static int pqi_scsi_queue_command(struct Scsi_Host *shost, raid_bypassed = false; if (device->raid_bypass_enabled && !blk_rq_is_passthrough(scmd->request)) { - rc = pqi_raid_bypass_submit_scsi_cmd(ctrl_info, device, - scmd, queue_group); - if (rc == 0 || rc == SCSI_MLQUEUE_HOST_BUSY) { - raid_bypassed = true; - atomic_inc(&device->raid_bypass_cnt); + if (!pqi_is_parity_write_stream(ctrl_info, scmd)) { + rc = pqi_raid_bypass_submit_scsi_cmd(ctrl_info, device, scmd, queue_group); + if (rc == 0 || rc == SCSI_MLQUEUE_HOST_BUSY) { + raid_bypassed = true; + atomic_inc(&device->raid_bypass_cnt); + } } } if (!raid_bypassed) From 5be746d7d74b0f40128ac6f1d1ba30bc05770beb Mon Sep 17 00:00:00 2001 From: Don Brace Date: Thu, 11 Mar 2021 14:16:02 -0600 Subject: [PATCH 290/412] scsi: smartpqi: Add host level stream detection enable Allow R5/R6 stream detection to be disabled/enabled using sysfs entry enable_stream_detection. Example usage: lsscsi [2:2:0:0] storage Adaptec 3258P-32i /e 0010 ^ | +---- NOTE: here host is host2 find /sys -name \*enable_stream\* /sys/devices/pci0000:36/0000:36:00.0/0000:37:00.0/0000:38:00.0/0000:39:00.0/host2/scsi_host/host2/enable_stream_detection /sys/devices/pci0000:5b/0000:5b:00.0/0000:5c:00.0/host3/scsi_host/host3/enable_stream_detection Current stream detection: cat /sys/devices/pci0000:36/0000:36:00.0/0000:37:00.0/0000:38:00.0/0000:39:00.0/host2/scsi_host/host2/enable_stream_detection 1 Turn off stream detection: echo 0 > /sys/devices/pci0000:36/0000:36:00.0/0000:37:00.0/0000:38:00.0/0000:39:00.0/host2/scsi_host/host2/enable_stream_detection Turn on stream detection: echo 1 > /sys/devices/pci0000:36/0000:36:00.0/0000:37:00.0/0000:38:00.0/0000:39:00.0/host2/scsi_host/host2/enable_stream_detection Link: https://lore.kernel.org/r/161549376281.25025.1132304698441513738.stgit@brunhilda Reviewed-by: Scott Benesh Reviewed-by: Mike McGowen Reviewed-by: Scott Teel Reviewed-by: Kevin Barnett Reviewed-by: Martin Wilck Signed-off-by: Don Brace Signed-off-by: Martin K. Petersen --- drivers/scsi/smartpqi/smartpqi_init.c | 32 +++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/drivers/scsi/smartpqi/smartpqi_init.c b/drivers/scsi/smartpqi/smartpqi_init.c index 27bd3d9a3810..dce832f2614a 100644 --- a/drivers/scsi/smartpqi/smartpqi_init.c +++ b/drivers/scsi/smartpqi/smartpqi_init.c @@ -6696,6 +6696,34 @@ static ssize_t pqi_lockup_action_store(struct device *dev, return -EINVAL; } +static ssize_t pqi_host_enable_stream_detection_show(struct device *dev, + struct device_attribute *attr, char *buffer) +{ + struct Scsi_Host *shost = class_to_shost(dev); + struct pqi_ctrl_info *ctrl_info = shost_to_hba(shost); + + return scnprintf(buffer, 10, "%x\n", + ctrl_info->enable_stream_detection); +} + +static ssize_t pqi_host_enable_stream_detection_store(struct device *dev, + struct device_attribute *attr, const char *buffer, size_t count) +{ + struct Scsi_Host *shost = class_to_shost(dev); + struct pqi_ctrl_info *ctrl_info = shost_to_hba(shost); + u8 set_stream_detection = 0; + + if (kstrtou8(buffer, 0, &set_stream_detection)) + return -EINVAL; + + if (set_stream_detection > 0) + set_stream_detection = 1; + + ctrl_info->enable_stream_detection = set_stream_detection; + + return count; +} + static ssize_t pqi_host_enable_r5_writes_show(struct device *dev, struct device_attribute *attr, char *buffer) { @@ -6758,6 +6786,9 @@ static DEVICE_ATTR(vendor, 0444, pqi_vendor_show, NULL); static DEVICE_ATTR(rescan, 0200, NULL, pqi_host_rescan_store); static DEVICE_ATTR(lockup_action, 0644, pqi_lockup_action_show, pqi_lockup_action_store); +static DEVICE_ATTR(enable_stream_detection, 0644, + pqi_host_enable_stream_detection_show, + pqi_host_enable_stream_detection_store); static DEVICE_ATTR(enable_r5_writes, 0644, pqi_host_enable_r5_writes_show, pqi_host_enable_r5_writes_store); static DEVICE_ATTR(enable_r6_writes, 0644, @@ -6771,6 +6802,7 @@ static struct device_attribute *pqi_shost_attrs[] = { &dev_attr_vendor, &dev_attr_rescan, &dev_attr_lockup_action, + &dev_attr_enable_stream_detection, &dev_attr_enable_r5_writes, &dev_attr_enable_r6_writes, NULL From 99a12b487f19618f7a857281a7a80930f7c503e3 Mon Sep 17 00:00:00 2001 From: Kevin Barnett Date: Thu, 11 Mar 2021 14:16:08 -0600 Subject: [PATCH 291/412] scsi: smartpqi: Disable WRITE SAME for HBA NVMe disks Controller does not support SCSI WRITE SAME for NVMe drives in HBA mode Link: https://lore.kernel.org/r/161549376866.25025.5961694654342018260.stgit@brunhilda Reviewed-by: Scott Benesh Reviewed-by: Mike McGowen Reviewed-by: Scott Teel Reviewed-by: Martin Wilck Signed-off-by: Kevin Barnett Signed-off-by: Don Brace Signed-off-by: Martin K. Petersen --- drivers/scsi/smartpqi/smartpqi_init.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/drivers/scsi/smartpqi/smartpqi_init.c b/drivers/scsi/smartpqi/smartpqi_init.c index dce832f2614a..e8d27b133fc8 100644 --- a/drivers/scsi/smartpqi/smartpqi_init.c +++ b/drivers/scsi/smartpqi/smartpqi_init.c @@ -6252,10 +6252,13 @@ static int pqi_slave_alloc(struct scsi_device *sdev) scsi_change_queue_depth(sdev, device->advertised_queue_depth); } - if (pqi_is_logical_device(device)) + if (pqi_is_logical_device(device)) { pqi_disable_write_same(sdev); - else + } else { sdev->allow_restart = 1; + if (device->device_type == SA_DEVICE_TYPE_NVME) + pqi_disable_write_same(sdev); + } } spin_unlock_irqrestore(&ctrl_info->scsi_device_list_lock, flags); From ae0c189db4f1f763b3b1e9190bed06f81ad668fd Mon Sep 17 00:00:00 2001 From: Kevin Barnett Date: Thu, 11 Mar 2021 14:16:14 -0600 Subject: [PATCH 292/412] scsi: smartpqi: Remove timeouts from internal cmds Remove timeouts for driver-initiated commands. Responses to internal requests can take longer than hard coded timeout values and the driver will still have an outstanding request that may complete in the future with no context. Link: https://lore.kernel.org/r/161549377451.25025.12306492868851801623.stgit@brunhilda Reviewed-by: Scott Benesh Reviewed-by: Mike McGowen Reviewed-by: Scott Teel Signed-off-by: Kevin Barnett Signed-off-by: Don Brace Signed-off-by: Martin K. Petersen --- drivers/scsi/smartpqi/smartpqi.h | 5 +- drivers/scsi/smartpqi/smartpqi_init.c | 141 ++++++++------------------ 2 files changed, 46 insertions(+), 100 deletions(-) diff --git a/drivers/scsi/smartpqi/smartpqi.h b/drivers/scsi/smartpqi/smartpqi.h index 976bfd8c5192..8e5e2543c7cf 100644 --- a/drivers/scsi/smartpqi/smartpqi.h +++ b/drivers/scsi/smartpqi/smartpqi.h @@ -130,9 +130,12 @@ struct pqi_iu_header { /* of this header */ __le16 response_queue_id; /* specifies the OQ where the */ /* response IU is to be delivered */ - u8 work_area[2]; /* reserved for driver use */ + u16 driver_flags; /* reserved for driver use */ }; +/* manifest constants for pqi_iu_header.driver_flags */ +#define PQI_DRIVER_NONBLOCKABLE_REQUEST 0x1 + /* * According to the PQI spec, the IU header is only the first 4 bytes of our * pqi_iu_header structure. diff --git a/drivers/scsi/smartpqi/smartpqi_init.c b/drivers/scsi/smartpqi/smartpqi_init.c index e8d27b133fc8..d442aabf8fe8 100644 --- a/drivers/scsi/smartpqi/smartpqi_init.c +++ b/drivers/scsi/smartpqi/smartpqi_init.c @@ -62,7 +62,7 @@ static void pqi_start_io(struct pqi_ctrl_info *ctrl_info, struct pqi_io_request *io_request); static int pqi_submit_raid_request_synchronous(struct pqi_ctrl_info *ctrl_info, struct pqi_iu_header *request, unsigned int flags, - struct pqi_raid_error_info *error_info, unsigned long timeout_msecs); + struct pqi_raid_error_info *error_info); static int pqi_aio_submit_io(struct pqi_ctrl_info *ctrl_info, struct scsi_cmnd *scmd, u32 aio_handle, u8 *cdb, unsigned int cdb_length, struct pqi_queue_group *queue_group, @@ -274,33 +274,15 @@ static inline void pqi_ctrl_unblock_requests(struct pqi_ctrl_info *ctrl_info) scsi_unblock_requests(ctrl_info->scsi_host); } -static unsigned long pqi_wait_if_ctrl_blocked(struct pqi_ctrl_info *ctrl_info, - unsigned long timeout_msecs) +static void pqi_wait_if_ctrl_blocked(struct pqi_ctrl_info *ctrl_info) { - unsigned long remaining_msecs; - if (!pqi_ctrl_blocked(ctrl_info)) - return timeout_msecs; + return; atomic_inc(&ctrl_info->num_blocked_threads); - - if (timeout_msecs == NO_TIMEOUT) { - wait_event(ctrl_info->block_requests_wait, - !pqi_ctrl_blocked(ctrl_info)); - remaining_msecs = timeout_msecs; - } else { - unsigned long remaining_jiffies; - - remaining_jiffies = - wait_event_timeout(ctrl_info->block_requests_wait, - !pqi_ctrl_blocked(ctrl_info), - msecs_to_jiffies(timeout_msecs)); - remaining_msecs = jiffies_to_msecs(remaining_jiffies); - } - + wait_event(ctrl_info->block_requests_wait, + !pqi_ctrl_blocked(ctrl_info)); atomic_dec(&ctrl_info->num_blocked_threads); - - return remaining_msecs; } static inline void pqi_ctrl_wait_until_quiesced(struct pqi_ctrl_info *ctrl_info) @@ -511,6 +493,7 @@ static int pqi_build_raid_path_request(struct pqi_ctrl_info *ctrl_info, put_unaligned_be32(cdb_length, &cdb[6]); break; case SA_FLUSH_CACHE: + request->header.driver_flags = PQI_DRIVER_NONBLOCKABLE_REQUEST; request->data_direction = SOP_WRITE_FLAG; cdb[0] = BMIC_WRITE; cdb[6] = BMIC_FLUSH_CACHE; @@ -605,7 +588,7 @@ static void pqi_free_io_request(struct pqi_io_request *io_request) static int pqi_send_scsi_raid_request(struct pqi_ctrl_info *ctrl_info, u8 cmd, u8 *scsi3addr, void *buffer, size_t buffer_length, u16 vpd_page, - struct pqi_raid_error_info *error_info, unsigned long timeout_msecs) + struct pqi_raid_error_info *error_info) { int rc; struct pqi_raid_path_request request; @@ -616,8 +599,7 @@ static int pqi_send_scsi_raid_request(struct pqi_ctrl_info *ctrl_info, u8 cmd, if (rc) return rc; - rc = pqi_submit_raid_request_synchronous(ctrl_info, &request.header, 0, - error_info, timeout_msecs); + rc = pqi_submit_raid_request_synchronous(ctrl_info, &request.header, 0, error_info); pqi_pci_unmap(ctrl_info->pci_dev, request.sg_descriptors, 1, dir); @@ -630,7 +612,7 @@ static inline int pqi_send_ctrl_raid_request(struct pqi_ctrl_info *ctrl_info, u8 cmd, void *buffer, size_t buffer_length) { return pqi_send_scsi_raid_request(ctrl_info, cmd, RAID_CTLR_LUNID, - buffer, buffer_length, 0, NULL, NO_TIMEOUT); + buffer, buffer_length, 0, NULL); } static inline int pqi_send_ctrl_raid_with_error(struct pqi_ctrl_info *ctrl_info, @@ -638,7 +620,7 @@ static inline int pqi_send_ctrl_raid_with_error(struct pqi_ctrl_info *ctrl_info, struct pqi_raid_error_info *error_info) { return pqi_send_scsi_raid_request(ctrl_info, cmd, RAID_CTLR_LUNID, - buffer, buffer_length, 0, error_info, NO_TIMEOUT); + buffer, buffer_length, 0, error_info); } static inline int pqi_identify_controller(struct pqi_ctrl_info *ctrl_info, @@ -660,7 +642,7 @@ static inline int pqi_scsi_inquiry(struct pqi_ctrl_info *ctrl_info, u8 *scsi3addr, u16 vpd_page, void *buffer, size_t buffer_length) { return pqi_send_scsi_raid_request(ctrl_info, INQUIRY, scsi3addr, - buffer, buffer_length, vpd_page, NULL, NO_TIMEOUT); + buffer, buffer_length, vpd_page, NULL); } static int pqi_identify_physical_device(struct pqi_ctrl_info *ctrl_info, @@ -682,8 +664,7 @@ static int pqi_identify_physical_device(struct pqi_ctrl_info *ctrl_info, request.cdb[2] = (u8)bmic_device_index; request.cdb[9] = (u8)(bmic_device_index >> 8); - rc = pqi_submit_raid_request_synchronous(ctrl_info, &request.header, - 0, NULL, NO_TIMEOUT); + rc = pqi_submit_raid_request_synchronous(ctrl_info, &request.header, 0, NULL); pqi_pci_unmap(ctrl_info->pci_dev, request.sg_descriptors, 1, dir); @@ -740,7 +721,7 @@ static int pqi_get_advanced_raid_bypass_config(struct pqi_ctrl_info *ctrl_info) request.cdb[2] = BMIC_SENSE_FEATURE_IO_PAGE; request.cdb[3] = BMIC_SENSE_FEATURE_IO_PAGE_AIO_SUBPAGE; - rc = pqi_submit_raid_request_synchronous(ctrl_info, &request.header, 0, NULL, NO_TIMEOUT); + rc = pqi_submit_raid_request_synchronous(ctrl_info, &request.header, 0, NULL); pqi_pci_unmap(ctrl_info->pci_dev, request.sg_descriptors, 1, dir); @@ -1270,9 +1251,7 @@ static int pqi_get_raid_map(struct pqi_ctrl_info *ctrl_info, return -ENOMEM; rc = pqi_send_scsi_raid_request(ctrl_info, CISS_GET_RAID_MAP, - device->scsi3addr, raid_map, sizeof(*raid_map), - 0, NULL, NO_TIMEOUT); - + device->scsi3addr, raid_map, sizeof(*raid_map), 0, NULL); if (rc) goto error; @@ -1287,8 +1266,7 @@ static int pqi_get_raid_map(struct pqi_ctrl_info *ctrl_info, return -ENOMEM; rc = pqi_send_scsi_raid_request(ctrl_info, CISS_GET_RAID_MAP, - device->scsi3addr, raid_map, raid_map_size, - 0, NULL, NO_TIMEOUT); + device->scsi3addr, raid_map, raid_map_size, 0, NULL); if (rc) goto error; @@ -3375,7 +3353,7 @@ static void pqi_event_worker(struct work_struct *work) ctrl_info = container_of(work, struct pqi_ctrl_info, event_work); pqi_ctrl_busy(ctrl_info); - pqi_wait_if_ctrl_blocked(ctrl_info, NO_TIMEOUT); + pqi_wait_if_ctrl_blocked(ctrl_info); if (pqi_ctrl_offline(ctrl_info)) goto out; @@ -4219,59 +4197,40 @@ static int pqi_process_raid_io_error_synchronous( return rc; } +static inline bool pqi_is_blockable_request(struct pqi_iu_header *request) +{ + return (request->driver_flags & PQI_DRIVER_NONBLOCKABLE_REQUEST) == 0; +} + static int pqi_submit_raid_request_synchronous(struct pqi_ctrl_info *ctrl_info, struct pqi_iu_header *request, unsigned int flags, - struct pqi_raid_error_info *error_info, unsigned long timeout_msecs) + struct pqi_raid_error_info *error_info) { int rc = 0; struct pqi_io_request *io_request; - unsigned long start_jiffies; - unsigned long msecs_blocked; size_t iu_length; DECLARE_COMPLETION_ONSTACK(wait); - /* - * Note that specifying PQI_SYNC_FLAGS_INTERRUPTABLE and a timeout value - * are mutually exclusive. - */ - if (flags & PQI_SYNC_FLAGS_INTERRUPTABLE) { if (down_interruptible(&ctrl_info->sync_request_sem)) return -ERESTARTSYS; } else { - if (timeout_msecs == NO_TIMEOUT) { - down(&ctrl_info->sync_request_sem); - } else { - start_jiffies = jiffies; - if (down_timeout(&ctrl_info->sync_request_sem, - msecs_to_jiffies(timeout_msecs))) - return -ETIMEDOUT; - msecs_blocked = - jiffies_to_msecs(jiffies - start_jiffies); - if (msecs_blocked >= timeout_msecs) { - rc = -ETIMEDOUT; - goto out; - } - timeout_msecs -= msecs_blocked; - } + down(&ctrl_info->sync_request_sem); } pqi_ctrl_busy(ctrl_info); - timeout_msecs = pqi_wait_if_ctrl_blocked(ctrl_info, timeout_msecs); - if (timeout_msecs == 0) { - pqi_ctrl_unbusy(ctrl_info); - rc = -ETIMEDOUT; - goto out; - } + /* + * Wait for other admin queue updates such as; + * config table changes, OFA memory updates, ... + */ + if (pqi_is_blockable_request(request)) + pqi_wait_if_ctrl_blocked(ctrl_info); if (pqi_ctrl_offline(ctrl_info)) { - pqi_ctrl_unbusy(ctrl_info); rc = -ENXIO; goto out; } - atomic_inc(&ctrl_info->sync_cmds_outstanding); - io_request = pqi_alloc_io_request(ctrl_info); put_unaligned_le16(io_request->index, @@ -4291,18 +4250,7 @@ static int pqi_submit_raid_request_synchronous(struct pqi_ctrl_info *ctrl_info, pqi_start_io(ctrl_info, &ctrl_info->queue_groups[PQI_DEFAULT_QUEUE_GROUP], RAID_PATH, io_request); - pqi_ctrl_unbusy(ctrl_info); - - if (timeout_msecs == NO_TIMEOUT) { - pqi_wait_for_completion_io(ctrl_info, &wait); - } else { - if (!wait_for_completion_io_timeout(&wait, - msecs_to_jiffies(timeout_msecs))) { - dev_warn(&ctrl_info->pci_dev->dev, - "command timed out\n"); - rc = -ETIMEDOUT; - } - } + pqi_wait_for_completion_io(ctrl_info, &wait); if (error_info) { if (io_request->error_info) @@ -4315,8 +4263,8 @@ static int pqi_submit_raid_request_synchronous(struct pqi_ctrl_info *ctrl_info, pqi_free_io_request(io_request); - atomic_dec(&ctrl_info->sync_cmds_outstanding); out: + pqi_ctrl_unbusy(ctrl_info); up(&ctrl_info->sync_request_sem); return rc; @@ -4353,8 +4301,7 @@ static int pqi_submit_admin_request_synchronous( rc = pqi_poll_for_admin_response(ctrl_info, response); if (rc == 0) - rc = pqi_validate_admin_response(response, - request->function_code); + rc = pqi_validate_admin_response(response, request->function_code); return rc; } @@ -4723,8 +4670,7 @@ static int pqi_configure_events(struct pqi_ctrl_info *ctrl_info, if (rc) goto out; - rc = pqi_submit_raid_request_synchronous(ctrl_info, &request.header, - 0, NULL, NO_TIMEOUT); + rc = pqi_submit_raid_request_synchronous(ctrl_info, &request.header, 0, NULL); pqi_pci_unmap(ctrl_info->pci_dev, request.data.report_event_configuration.sg_descriptors, 1, @@ -4759,8 +4705,7 @@ static int pqi_configure_events(struct pqi_ctrl_info *ctrl_info, if (rc) goto out; - rc = pqi_submit_raid_request_synchronous(ctrl_info, &request.header, 0, - NULL, NO_TIMEOUT); + rc = pqi_submit_raid_request_synchronous(ctrl_info, &request.header, 0, NULL); pqi_pci_unmap(ctrl_info->pci_dev, request.data.report_event_configuration.sg_descriptors, 1, @@ -6516,7 +6461,7 @@ static int pqi_passthru_ioctl(struct pqi_ctrl_info *ctrl_info, void __user *arg) put_unaligned_le32(iocommand.Request.Timeout, &request.timeout); rc = pqi_submit_raid_request_synchronous(ctrl_info, &request.header, - PQI_SYNC_FLAGS_INTERRUPTABLE, &pqi_error_info, NO_TIMEOUT); + PQI_SYNC_FLAGS_INTERRUPTABLE, &pqi_error_info); if (iocommand.buf_size > 0) pqi_pci_unmap(ctrl_info->pci_dev, request.sg_descriptors, 1, @@ -7376,8 +7321,7 @@ static int pqi_config_table_update(struct pqi_ctrl_info *ctrl_info, put_unaligned_le16(last_section, &request.data.config_table_update.last_section); - return pqi_submit_raid_request_synchronous(ctrl_info, &request.header, - 0, NULL, NO_TIMEOUT); + return pqi_submit_raid_request_synchronous(ctrl_info, &request.header, 0, NULL); } static int pqi_enable_firmware_features(struct pqi_ctrl_info *ctrl_info, @@ -8522,8 +8466,7 @@ static int pqi_ofa_host_memory_update(struct pqi_ctrl_info *ctrl_info) } - return pqi_submit_raid_request_synchronous(ctrl_info, &request.header, - 0, NULL, NO_TIMEOUT); + return pqi_submit_raid_request_synchronous(ctrl_info, &request.header, 0, NULL); } static int pqi_ofa_ctrl_restart(struct pqi_ctrl_info *ctrl_info) @@ -9277,7 +9220,7 @@ static void __attribute__((unused)) verify_structures(void) BUILD_BUG_ON(offsetof(struct pqi_iu_header, response_queue_id) != 0x4); BUILD_BUG_ON(offsetof(struct pqi_iu_header, - work_area) != 0x6); + driver_flags) != 0x6); BUILD_BUG_ON(sizeof(struct pqi_iu_header) != 0x8); BUILD_BUG_ON(offsetof(struct pqi_aio_error_info, @@ -9375,7 +9318,7 @@ static void __attribute__((unused)) verify_structures(void) BUILD_BUG_ON(offsetof(struct pqi_general_admin_request, header.iu_length) != 2); BUILD_BUG_ON(offsetof(struct pqi_general_admin_request, - header.work_area) != 6); + header.driver_flags) != 6); BUILD_BUG_ON(offsetof(struct pqi_general_admin_request, request_id) != 8); BUILD_BUG_ON(offsetof(struct pqi_general_admin_request, @@ -9431,7 +9374,7 @@ static void __attribute__((unused)) verify_structures(void) BUILD_BUG_ON(offsetof(struct pqi_general_admin_response, header.iu_length) != 2); BUILD_BUG_ON(offsetof(struct pqi_general_admin_response, - header.work_area) != 6); + header.driver_flags) != 6); BUILD_BUG_ON(offsetof(struct pqi_general_admin_response, request_id) != 8); BUILD_BUG_ON(offsetof(struct pqi_general_admin_response, @@ -9455,7 +9398,7 @@ static void __attribute__((unused)) verify_structures(void) BUILD_BUG_ON(offsetof(struct pqi_raid_path_request, header.response_queue_id) != 4); BUILD_BUG_ON(offsetof(struct pqi_raid_path_request, - header.work_area) != 6); + header.driver_flags) != 6); BUILD_BUG_ON(offsetof(struct pqi_raid_path_request, request_id) != 8); BUILD_BUG_ON(offsetof(struct pqi_raid_path_request, @@ -9484,7 +9427,7 @@ static void __attribute__((unused)) verify_structures(void) BUILD_BUG_ON(offsetof(struct pqi_aio_path_request, header.response_queue_id) != 4); BUILD_BUG_ON(offsetof(struct pqi_aio_path_request, - header.work_area) != 6); + header.driver_flags) != 6); BUILD_BUG_ON(offsetof(struct pqi_aio_path_request, request_id) != 8); BUILD_BUG_ON(offsetof(struct pqi_aio_path_request, From 7a84a821f194bb1e509219c80efcbff2b4d47e45 Mon Sep 17 00:00:00 2001 From: Kevin Barnett Date: Thu, 11 Mar 2021 14:16:20 -0600 Subject: [PATCH 293/412] scsi: smartpqi: Add support for wwid WWID has been added to Report Physical LUNs in newer controller firmware. The presence of this field is detected by a feature bit. Add detection of this new feature and store the WWID when set. Link: https://lore.kernel.org/r/161549378041.25025.3869709982357729841.stgit@brunhilda Reviewed-by: Scott Benesh Reviewed-by: Mike McGowen Reviewed-by: Scott Teel Signed-off-by: Kevin Barnett Signed-off-by: Don Brace Signed-off-by: Martin K. Petersen --- drivers/scsi/smartpqi/smartpqi.h | 5 ++++- drivers/scsi/smartpqi/smartpqi_init.c | 24 +++++++++++++++++++++++- 2 files changed, 27 insertions(+), 2 deletions(-) diff --git a/drivers/scsi/smartpqi/smartpqi.h b/drivers/scsi/smartpqi/smartpqi.h index 8e5e2543c7cf..a579d772dce0 100644 --- a/drivers/scsi/smartpqi/smartpqi.h +++ b/drivers/scsi/smartpqi/smartpqi.h @@ -853,7 +853,8 @@ struct pqi_config_table_firmware_features { #define PQI_FIRMWARE_FEATURE_RAID_IU_TIMEOUT 13 #define PQI_FIRMWARE_FEATURE_TMF_IU_TIMEOUT 14 #define PQI_FIRMWARE_FEATURE_RAID_BYPASS_ON_ENCRYPTED_NVME 15 -#define PQI_FIRMWARE_FEATURE_MAXIMUM 15 +#define PQI_FIRMWARE_FEATURE_UNIQUE_WWID_IN_REPORT_PHYS_LUN 16 +#define PQI_FIRMWARE_FEATURE_MAXIMUM 16 struct pqi_config_table_debug { struct pqi_config_table_section_header header; @@ -1110,6 +1111,7 @@ struct pqi_scsi_dev { struct pqi_stream_data stream_data[NUM_STREAMS_PER_LUN]; atomic_t scsi_cmds_outstanding; atomic_t raid_bypass_cnt; + u8 page_83_identifier[16]; }; /* VPD inquiry pages */ @@ -1303,6 +1305,7 @@ struct pqi_ctrl_info { u8 soft_reset_handshake_supported : 1; u8 raid_iu_timeout_supported : 1; u8 tmf_iu_timeout_supported : 1; + u8 unique_wwid_in_report_phys_lun_supported : 1; u8 enable_r1_writes : 1; u8 enable_r5_writes : 1; u8 enable_r6_writes : 1; diff --git a/drivers/scsi/smartpqi/smartpqi_init.c b/drivers/scsi/smartpqi/smartpqi_init.c index d442aabf8fe8..a226b7e32e3d 100644 --- a/drivers/scsi/smartpqi/smartpqi_init.c +++ b/drivers/scsi/smartpqi/smartpqi_init.c @@ -1441,6 +1441,9 @@ static int pqi_get_physical_device_info(struct pqi_ctrl_info *ctrl_info, sizeof(device->phys_connector)); device->bay = id_phys->phys_bay_in_box; + memcpy(&device->page_83_identifier, &id_phys->page_83_identifier, + sizeof(device->page_83_identifier)); + return 0; } @@ -2045,6 +2048,16 @@ static inline bool pqi_expose_device(struct pqi_scsi_dev *device) return !device->is_physical_device || !pqi_skip_device(device->scsi3addr); } +static inline void pqi_set_physical_device_wwid(struct pqi_ctrl_info *ctrl_info, + struct pqi_scsi_dev *device, struct report_phys_lun_extended_entry *phys_lun_ext_entry) +{ + if (ctrl_info->unique_wwid_in_report_phys_lun_supported || + pqi_is_device_with_sas_address(device)) + device->wwid = phys_lun_ext_entry->wwid; + else + device->wwid = cpu_to_be64(get_unaligned_be64(&device->page_83_identifier)); +} + static int pqi_update_scsi_devices(struct pqi_ctrl_info *ctrl_info) { int i; @@ -2210,7 +2223,7 @@ static int pqi_update_scsi_devices(struct pqi_ctrl_info *ctrl_info) pqi_assign_bus_target_lun(device); if (device->is_physical_device) { - device->wwid = phys_lun_ext_entry->wwid; + pqi_set_physical_device_wwid(ctrl_info, device, phys_lun_ext_entry); if ((phys_lun_ext_entry->device_flags & CISS_REPORT_PHYS_DEV_FLAG_AIO_ENABLED) && phys_lun_ext_entry->aio_handle) { @@ -7407,6 +7420,10 @@ static void pqi_ctrl_update_feature_flags(struct pqi_ctrl_info *ctrl_info, case PQI_FIRMWARE_FEATURE_TMF_IU_TIMEOUT: ctrl_info->tmf_iu_timeout_supported = firmware_feature->enabled; break; + case PQI_FIRMWARE_FEATURE_UNIQUE_WWID_IN_REPORT_PHYS_LUN: + ctrl_info->unique_wwid_in_report_phys_lun_supported = + firmware_feature->enabled; + break; } pqi_firmware_feature_status(ctrl_info, firmware_feature); @@ -7497,6 +7514,11 @@ static struct pqi_firmware_feature pqi_firmware_features[] = { .feature_bit = PQI_FIRMWARE_FEATURE_RAID_BYPASS_ON_ENCRYPTED_NVME, .feature_status = pqi_firmware_feature_status, }, + { + .feature_name = "Unique WWID in Report Physical LUN", + .feature_bit = PQI_FIRMWARE_FEATURE_UNIQUE_WWID_IN_REPORT_PHYS_LUN, + .feature_status = pqi_ctrl_update_feature_flags, + }, }; static void pqi_process_firmware_features( From 06b41e0d1800a33a54e23c6e7b98e7ecc6a9fd78 Mon Sep 17 00:00:00 2001 From: Kevin Barnett Date: Thu, 11 Mar 2021 14:16:26 -0600 Subject: [PATCH 294/412] scsi: smartpqi: Update event handler Change the data types for event_id and additional_event_id. Link: https://lore.kernel.org/r/161549378628.25025.14338046567871170916.stgit@brunhilda Reviewed-by: Scott Benesh Reviewed-by: Mike McGowen Reviewed-by: Scott Teel Signed-off-by: Kevin Barnett Signed-off-by: Don Brace Signed-off-by: Martin K. Petersen --- drivers/scsi/smartpqi/smartpqi.h | 4 ++-- drivers/scsi/smartpqi/smartpqi_init.c | 9 +++++---- 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/drivers/scsi/smartpqi/smartpqi.h b/drivers/scsi/smartpqi/smartpqi.h index a579d772dce0..a18c1f9afb37 100644 --- a/drivers/scsi/smartpqi/smartpqi.h +++ b/drivers/scsi/smartpqi/smartpqi.h @@ -1217,8 +1217,8 @@ struct pqi_io_request { struct pqi_event { bool pending; u8 event_type; - __le16 event_id; - __le32 additional_event_id; + u16 event_id; + u32 additional_event_id; __le32 ofa_bytes_requested; __le16 ofa_cancel_reason; }; diff --git a/drivers/scsi/smartpqi/smartpqi_init.c b/drivers/scsi/smartpqi/smartpqi_init.c index a226b7e32e3d..4c0962879029 100644 --- a/drivers/scsi/smartpqi/smartpqi_init.c +++ b/drivers/scsi/smartpqi/smartpqi_init.c @@ -3247,8 +3247,8 @@ static void pqi_acknowledge_event(struct pqi_ctrl_info *ctrl_info, put_unaligned_le16(sizeof(request) - PQI_REQUEST_HEADER_LENGTH, &request.header.iu_length); request.event_type = event->event_type; - request.event_id = event->event_id; - request.additional_event_id = event->additional_event_id; + put_unaligned_le16(event->event_id, &request.event_id); + put_unaligned_le32(event->additional_event_id, &request.additional_event_id); pqi_send_event_ack(ctrl_info, &request, sizeof(request)); } @@ -3512,8 +3512,9 @@ static int pqi_process_event_intr(struct pqi_ctrl_info *ctrl_info) event = &ctrl_info->events[event_index]; event->pending = true; event->event_type = response->event_type; - event->event_id = response->event_id; - event->additional_event_id = response->additional_event_id; + event->event_id = get_unaligned_le16(&response->event_id); + event->additional_event_id = + get_unaligned_le32(&response->additional_event_id); if (event->event_type == PQI_EVENT_TYPE_OFA) pqi_ofa_capture_event_payload(event, response); } From 4ccc354bac14b03e13c1d20131fe6d5a8e2c2c45 Mon Sep 17 00:00:00 2001 From: Kevin Barnett Date: Thu, 11 Mar 2021 14:16:32 -0600 Subject: [PATCH 295/412] scsi: smartpqi: Update soft reset management for OFA Cleanup soft reset code for Online Firmware Activation (OFA). OFA allows controller firmware updates without a reboot. OFA updates require an on-line controller reset to activate the updated firmware. There were some missing actions for some of the reset cases. The controller is first set back to sis mode before returning to pqi mode. Check to ensure the controller is in sis mode. Release QRM memory (OFA buffer) on OFA error conditions. Clean up controller state which can cause a kernel panic upon reboot after an unsuccessful OFA. Link: https://lore.kernel.org/r/161549379215.25025.10654441314249183621.stgit@brunhilda Reviewed-by: Scott Benesh Reviewed-by: Mike McGowen Reviewed-by: Scott Teel Signed-off-by: Kevin Barnett Signed-off-by: Don Brace Signed-off-by: Martin K. Petersen --- drivers/scsi/smartpqi/smartpqi_init.c | 86 +++++++++++++++++---------- 1 file changed, 53 insertions(+), 33 deletions(-) diff --git a/drivers/scsi/smartpqi/smartpqi_init.c b/drivers/scsi/smartpqi/smartpqi_init.c index 4c0962879029..41aa401e58eb 100644 --- a/drivers/scsi/smartpqi/smartpqi_init.c +++ b/drivers/scsi/smartpqi/smartpqi_init.c @@ -390,21 +390,15 @@ static inline u32 pqi_read_heartbeat_counter(struct pqi_ctrl_info *ctrl_info) static inline u8 pqi_read_soft_reset_status(struct pqi_ctrl_info *ctrl_info) { - if (!ctrl_info->soft_reset_status) - return 0; - return readb(ctrl_info->soft_reset_status); } -static inline void pqi_clear_soft_reset_status(struct pqi_ctrl_info *ctrl_info, u8 clear) +static inline void pqi_clear_soft_reset_status(struct pqi_ctrl_info *ctrl_info) { u8 status; - if (!ctrl_info->soft_reset_status) - return; - status = pqi_read_soft_reset_status(ctrl_info); - status &= ~clear; + status &= ~PQI_SOFT_RESET_ABORT; writeb(status, ctrl_info->soft_reset_status); } @@ -3272,46 +3266,65 @@ static enum pqi_soft_reset_status pqi_poll_for_soft_reset_status( if (status & PQI_SOFT_RESET_ABORT) return RESET_ABORT; + if (!sis_is_firmware_running(ctrl_info)) + return RESET_NORESPONSE; + if (time_after(jiffies, timeout)) { - dev_err(&ctrl_info->pci_dev->dev, + dev_warn(&ctrl_info->pci_dev->dev, "timed out waiting for soft reset status\n"); return RESET_TIMEDOUT; } - if (!sis_is_firmware_running(ctrl_info)) - return RESET_NORESPONSE; - ssleep(PQI_SOFT_RESET_STATUS_POLL_INTERVAL_SECS); } } -static void pqi_process_soft_reset(struct pqi_ctrl_info *ctrl_info, - enum pqi_soft_reset_status reset_status) +static void pqi_process_soft_reset(struct pqi_ctrl_info *ctrl_info) { int rc; + enum pqi_soft_reset_status reset_status; + + if (ctrl_info->soft_reset_handshake_supported) + reset_status = pqi_poll_for_soft_reset_status(ctrl_info); + else + reset_status = RESET_INITIATE_FIRMWARE; switch (reset_status) { - case RESET_INITIATE_DRIVER: case RESET_TIMEDOUT: + fallthrough; + case RESET_INITIATE_DRIVER: dev_info(&ctrl_info->pci_dev->dev, - "resetting controller %u\n", ctrl_info->ctrl_id); + "Online Firmware Activation: resetting controller\n"); sis_soft_reset(ctrl_info); fallthrough; case RESET_INITIATE_FIRMWARE: + ctrl_info->pqi_mode_enabled = false; + pqi_save_ctrl_mode(ctrl_info, SIS_MODE); rc = pqi_ofa_ctrl_restart(ctrl_info); pqi_ofa_free_host_buffer(ctrl_info); + pqi_ctrl_ofa_done(ctrl_info); dev_info(&ctrl_info->pci_dev->dev, - "Online Firmware Activation for controller %u: %s\n", - ctrl_info->ctrl_id, rc == 0 ? "SUCCESS" : "FAILED"); + "Online Firmware Activation: %s\n", + rc == 0 ? "SUCCESS" : "FAILED"); break; case RESET_ABORT: - pqi_ofa_ctrl_unquiesce(ctrl_info); dev_info(&ctrl_info->pci_dev->dev, - "Online Firmware Activation for controller %u: %s\n", - ctrl_info->ctrl_id, "ABORTED"); + "Online Firmware Activation ABORTED\n"); + if (ctrl_info->soft_reset_handshake_supported) + pqi_clear_soft_reset_status(ctrl_info); + pqi_ofa_free_host_buffer(ctrl_info); + pqi_ctrl_ofa_done(ctrl_info); + pqi_ofa_ctrl_unquiesce(ctrl_info); break; case RESET_NORESPONSE: + fallthrough; + default: + dev_err(&ctrl_info->pci_dev->dev, + "unexpected Online Firmware Activation reset status: 0x%x\n", + reset_status); pqi_ofa_free_host_buffer(ctrl_info); + pqi_ctrl_ofa_done(ctrl_info); + pqi_ofa_ctrl_unquiesce(ctrl_info); pqi_take_ctrl_offline(ctrl_info); break; } @@ -3321,7 +3334,6 @@ static void pqi_ofa_process_event(struct pqi_ctrl_info *ctrl_info, struct pqi_event *event) { u16 event_id; - enum pqi_soft_reset_status status; event_id = get_unaligned_le16(&event->event_id); @@ -3333,14 +3345,7 @@ static void pqi_ofa_process_event(struct pqi_ctrl_info *ctrl_info, ctrl_info->ctrl_id); pqi_ofa_ctrl_quiesce(ctrl_info); pqi_acknowledge_event(ctrl_info, event); - if (ctrl_info->soft_reset_handshake_supported) { - status = pqi_poll_for_soft_reset_status(ctrl_info); - pqi_process_soft_reset(ctrl_info, status); - } else { - pqi_process_soft_reset(ctrl_info, - RESET_INITIATE_FIRMWARE); - } - + pqi_process_soft_reset(ctrl_info); } else if (event_id == PQI_EVENT_OFA_MEMORY_ALLOCATION) { pqi_acknowledge_event(ctrl_info, event); pqi_ofa_setup_host_buffer(ctrl_info, @@ -7413,7 +7418,8 @@ static void pqi_ctrl_update_feature_flags(struct pqi_ctrl_info *ctrl_info, break; case PQI_FIRMWARE_FEATURE_SOFT_RESET_HANDSHAKE: ctrl_info->soft_reset_handshake_supported = - firmware_feature->enabled; + firmware_feature->enabled && + pqi_read_soft_reset_status(ctrl_info); break; case PQI_FIRMWARE_FEATURE_RAID_IU_TIMEOUT: ctrl_info->raid_iu_timeout_supported = firmware_feature->enabled; @@ -7609,6 +7615,19 @@ static void pqi_process_firmware_features_section( * of the PQI Configuration Table. */ +static void pqi_ctrl_reset_config(struct pqi_ctrl_info *ctrl_info) +{ + ctrl_info->heartbeat_counter = NULL; + ctrl_info->soft_reset_status = NULL; + ctrl_info->soft_reset_handshake_supported = false; + ctrl_info->enable_r1_writes = false; + ctrl_info->enable_r5_writes = false; + ctrl_info->enable_r6_writes = false; + ctrl_info->raid_iu_timeout_supported = false; + ctrl_info->tmf_iu_timeout_supported = false; + ctrl_info->unique_wwid_in_report_phys_lun_supported = false; +} + static int pqi_process_config_table(struct pqi_ctrl_info *ctrl_info) { u32 table_length; @@ -8051,6 +8070,8 @@ static int pqi_ctrl_init_resume(struct pqi_ctrl_info *ctrl_info) ctrl_info->controller_online = true; pqi_ctrl_unblock_requests(ctrl_info); + pqi_ctrl_reset_config(ctrl_info); + rc = pqi_process_config_table(ctrl_info); if (rc) return rc; @@ -8314,8 +8335,7 @@ static void pqi_ofa_ctrl_unquiesce(struct pqi_ctrl_info *ctrl_info) pqi_ctrl_unblock_requests(ctrl_info); pqi_start_heartbeat_timer(ctrl_info); pqi_schedule_update_time_worker(ctrl_info); - pqi_clear_soft_reset_status(ctrl_info, - PQI_SOFT_RESET_ABORT); + pqi_clear_soft_reset_status(ctrl_info); pqi_scan_scsi_devices(ctrl_info); } From 37f3318199ce31122c389bafb092ee72a6123d9d Mon Sep 17 00:00:00 2001 From: Kevin Barnett Date: Thu, 11 Mar 2021 14:16:38 -0600 Subject: [PATCH 296/412] scsi: smartpqi: Synchronize device resets with mutex Remove some flags used to check for device resets already in progress. Allow only 1 reset operation at a time for the host. Link: https://lore.kernel.org/r/161549379810.25025.10194117431886743795.stgit@brunhilda Reviewed-by: Scott Benesh Reviewed-by: Mike McGowen Reviewed-by: Scott Teel Signed-off-by: Kevin Barnett Signed-off-by: Don Brace Signed-off-by: Martin K. Petersen --- drivers/scsi/smartpqi/smartpqi.h | 1 - drivers/scsi/smartpqi/smartpqi_init.c | 48 ++++++++------------------- 2 files changed, 13 insertions(+), 36 deletions(-) diff --git a/drivers/scsi/smartpqi/smartpqi.h b/drivers/scsi/smartpqi/smartpqi.h index a18c1f9afb37..ba7d26364b84 100644 --- a/drivers/scsi/smartpqi/smartpqi.h +++ b/drivers/scsi/smartpqi/smartpqi.h @@ -1295,7 +1295,6 @@ struct pqi_ctrl_info { struct mutex ofa_mutex; /* serialize ofa */ bool controller_online; bool block_requests; - bool block_device_reset; bool in_ofa; bool in_shutdown; u8 inbound_spanning_supported : 1; diff --git a/drivers/scsi/smartpqi/smartpqi_init.c b/drivers/scsi/smartpqi/smartpqi_init.c index 41aa401e58eb..cc2b29a67ba0 100644 --- a/drivers/scsi/smartpqi/smartpqi_init.c +++ b/drivers/scsi/smartpqi/smartpqi_init.c @@ -247,12 +247,12 @@ static inline void pqi_save_ctrl_mode(struct pqi_ctrl_info *ctrl_info, static inline void pqi_ctrl_block_device_reset(struct pqi_ctrl_info *ctrl_info) { - ctrl_info->block_device_reset = true; + mutex_lock(&ctrl_info->lun_reset_mutex); } -static inline bool pqi_device_reset_blocked(struct pqi_ctrl_info *ctrl_info) +static inline void pqi_ctrl_unblock_device_reset(struct pqi_ctrl_info *ctrl_info) { - return ctrl_info->block_device_reset; + mutex_unlock(&ctrl_info->lun_reset_mutex); } static inline bool pqi_ctrl_blocked(struct pqi_ctrl_info *ctrl_info) @@ -297,16 +297,6 @@ static inline bool pqi_device_offline(struct pqi_scsi_dev *device) return device->device_offline; } -static inline void pqi_device_reset_start(struct pqi_scsi_dev *device) -{ - device->in_reset = true; -} - -static inline void pqi_device_reset_done(struct pqi_scsi_dev *device) -{ - device->in_reset = false; -} - static inline bool pqi_device_in_reset(struct pqi_scsi_dev *device) { return device->in_reset; @@ -6098,7 +6088,7 @@ static int pqi_lun_reset(struct pqi_ctrl_info *ctrl_info, #define PQI_LUN_RESET_RETRY_INTERVAL_MSECS 10000 #define PQI_LUN_RESET_PENDING_IO_TIMEOUT_SECS 120 -static int _pqi_device_reset(struct pqi_ctrl_info *ctrl_info, +static int pqi_lun_reset_with_retries(struct pqi_ctrl_info *ctrl_info, struct pqi_scsi_dev *device) { int rc; @@ -6124,23 +6114,15 @@ static int pqi_device_reset(struct pqi_ctrl_info *ctrl_info, { int rc; - mutex_lock(&ctrl_info->lun_reset_mutex); - pqi_ctrl_block_requests(ctrl_info); pqi_ctrl_wait_until_quiesced(ctrl_info); pqi_fail_io_queued_for_device(ctrl_info, device); rc = pqi_wait_until_inbound_queues_empty(ctrl_info); - pqi_device_reset_start(device); - pqi_ctrl_unblock_requests(ctrl_info); - if (rc) rc = FAILED; else - rc = _pqi_device_reset(ctrl_info, device); - - pqi_device_reset_done(device); - - mutex_unlock(&ctrl_info->lun_reset_mutex); + rc = pqi_lun_reset_with_retries(ctrl_info, device); + pqi_ctrl_unblock_requests(ctrl_info); return rc; } @@ -6156,29 +6138,25 @@ static int pqi_eh_device_reset_handler(struct scsi_cmnd *scmd) ctrl_info = shost_to_hba(shost); device = scmd->device->hostdata; + mutex_lock(&ctrl_info->lun_reset_mutex); + dev_err(&ctrl_info->pci_dev->dev, "resetting scsi %d:%d:%d:%d\n", shost->host_no, device->bus, device->target, device->lun); pqi_check_ctrl_health(ctrl_info); - if (pqi_ctrl_offline(ctrl_info) || - pqi_device_reset_blocked(ctrl_info)) { + if (pqi_ctrl_offline(ctrl_info)) rc = FAILED; - goto out; - } + else + rc = pqi_device_reset(ctrl_info, device); - pqi_wait_until_ofa_finished(ctrl_info); - - atomic_inc(&ctrl_info->sync_cmds_outstanding); - rc = pqi_device_reset(ctrl_info, device); - atomic_dec(&ctrl_info->sync_cmds_outstanding); - -out: dev_err(&ctrl_info->pci_dev->dev, "reset of scsi %d:%d:%d:%d: %s\n", shost->host_no, device->bus, device->target, device->lun, rc == SUCCESS ? "SUCCESS" : "FAILED"); + mutex_unlock(&ctrl_info->lun_reset_mutex); + return rc; } From 9fa8202336096d124a8433d67c6d1deb59b1a0d5 Mon Sep 17 00:00:00 2001 From: Kevin Barnett Date: Thu, 11 Mar 2021 14:16:44 -0600 Subject: [PATCH 297/412] scsi: smartpqi: Update suspend/resume and shutdown For suspend/resume and shutdown prevent: Controller events, any new I/O requests, controller requests, REGNEWD, and reset operations. Wait for any pending completions from the controller to complete to avoid controller NMI events. Link: https://lore.kernel.org/r/161549380398.25025.12266769502766103580.stgit@brunhilda Reviewed-by: Scott Teel Reviewed-by: Scott Benesh Signed-off-by: Kevin Barnett Signed-off-by: Don Brace Signed-off-by: Martin K. Petersen --- drivers/scsi/smartpqi/smartpqi.h | 11 +-- drivers/scsi/smartpqi/smartpqi_init.c | 113 ++++++++++++++------------ 2 files changed, 64 insertions(+), 60 deletions(-) diff --git a/drivers/scsi/smartpqi/smartpqi.h b/drivers/scsi/smartpqi/smartpqi.h index ba7d26364b84..fa1ebeea777d 100644 --- a/drivers/scsi/smartpqi/smartpqi.h +++ b/drivers/scsi/smartpqi/smartpqi.h @@ -1295,6 +1295,7 @@ struct pqi_ctrl_info { struct mutex ofa_mutex; /* serialize ofa */ bool controller_online; bool block_requests; + bool scan_blocked; bool in_ofa; bool in_shutdown; u8 inbound_spanning_supported : 1; @@ -1624,16 +1625,6 @@ struct bmic_diag_options { #pragma pack() -static inline void pqi_ctrl_busy(struct pqi_ctrl_info *ctrl_info) -{ - atomic_inc(&ctrl_info->num_busy_threads); -} - -static inline void pqi_ctrl_unbusy(struct pqi_ctrl_info *ctrl_info) -{ - atomic_dec(&ctrl_info->num_busy_threads); -} - static inline struct pqi_ctrl_info *shost_to_hba(struct Scsi_Host *shost) { void *hostdata = shost_priv(shost); diff --git a/drivers/scsi/smartpqi/smartpqi_init.c b/drivers/scsi/smartpqi/smartpqi_init.c index cc2b29a67ba0..4f7a38b96356 100644 --- a/drivers/scsi/smartpqi/smartpqi_init.c +++ b/drivers/scsi/smartpqi/smartpqi_init.c @@ -54,7 +54,6 @@ MODULE_LICENSE("GPL"); static void pqi_take_ctrl_offline(struct pqi_ctrl_info *ctrl_info); static void pqi_ctrl_offline_worker(struct work_struct *work); -static void pqi_retry_raid_bypass_requests(struct pqi_ctrl_info *ctrl_info); static int pqi_scan_scsi_devices(struct pqi_ctrl_info *ctrl_info); static void pqi_scan_start(struct Scsi_Host *shost); static void pqi_start_io(struct pqi_ctrl_info *ctrl_info, @@ -245,6 +244,23 @@ static inline void pqi_save_ctrl_mode(struct pqi_ctrl_info *ctrl_info, sis_write_driver_scratch(ctrl_info, mode); } +static inline void pqi_ctrl_block_scan(struct pqi_ctrl_info *ctrl_info) +{ + ctrl_info->scan_blocked = true; + mutex_lock(&ctrl_info->scan_mutex); +} + +static inline void pqi_ctrl_unblock_scan(struct pqi_ctrl_info *ctrl_info) +{ + ctrl_info->scan_blocked = false; + mutex_unlock(&ctrl_info->scan_mutex); +} + +static inline bool pqi_ctrl_scan_blocked(struct pqi_ctrl_info *ctrl_info) +{ + return ctrl_info->scan_blocked; +} + static inline void pqi_ctrl_block_device_reset(struct pqi_ctrl_info *ctrl_info) { mutex_lock(&ctrl_info->lun_reset_mutex); @@ -255,6 +271,41 @@ static inline void pqi_ctrl_unblock_device_reset(struct pqi_ctrl_info *ctrl_info mutex_unlock(&ctrl_info->lun_reset_mutex); } +static inline void pqi_scsi_block_requests(struct pqi_ctrl_info *ctrl_info) +{ + struct Scsi_Host *shost; + unsigned int num_loops; + int msecs_sleep; + + shost = ctrl_info->scsi_host; + + scsi_block_requests(shost); + + num_loops = 0; + msecs_sleep = 20; + while (scsi_host_busy(shost)) { + num_loops++; + if (num_loops == 10) + msecs_sleep = 500; + msleep(msecs_sleep); + } +} + +static inline void pqi_scsi_unblock_requests(struct pqi_ctrl_info *ctrl_info) +{ + scsi_unblock_requests(ctrl_info->scsi_host); +} + +static inline void pqi_ctrl_busy(struct pqi_ctrl_info *ctrl_info) +{ + atomic_inc(&ctrl_info->num_busy_threads); +} + +static inline void pqi_ctrl_unbusy(struct pqi_ctrl_info *ctrl_info) +{ + atomic_dec(&ctrl_info->num_busy_threads); +} + static inline bool pqi_ctrl_blocked(struct pqi_ctrl_info *ctrl_info) { return ctrl_info->block_requests; @@ -263,15 +314,12 @@ static inline bool pqi_ctrl_blocked(struct pqi_ctrl_info *ctrl_info) static inline void pqi_ctrl_block_requests(struct pqi_ctrl_info *ctrl_info) { ctrl_info->block_requests = true; - scsi_block_requests(ctrl_info->scsi_host); } static inline void pqi_ctrl_unblock_requests(struct pqi_ctrl_info *ctrl_info) { ctrl_info->block_requests = false; wake_up_all(&ctrl_info->block_requests_wait); - pqi_retry_raid_bypass_requests(ctrl_info); - scsi_unblock_requests(ctrl_info->scsi_host); } static void pqi_wait_if_ctrl_blocked(struct pqi_ctrl_info *ctrl_info) @@ -5999,18 +6047,6 @@ static int pqi_ctrl_wait_for_pending_io(struct pqi_ctrl_info *ctrl_info, return 0; } -static int pqi_ctrl_wait_for_pending_sync_cmds(struct pqi_ctrl_info *ctrl_info) -{ - while (atomic_read(&ctrl_info->sync_cmds_outstanding)) { - pqi_check_ctrl_health(ctrl_info); - if (pqi_ctrl_offline(ctrl_info)) - return -ENXIO; - usleep_range(1000, 2000); - } - - return 0; -} - static void pqi_lun_reset_complete(struct pqi_io_request *io_request, void *context) { @@ -8208,7 +8244,6 @@ static struct pqi_ctrl_info *pqi_alloc_ctrl_info(int numa_node) INIT_WORK(&ctrl_info->event_work, pqi_event_worker); atomic_set(&ctrl_info->num_interrupts, 0); - atomic_set(&ctrl_info->sync_cmds_outstanding, 0); INIT_DELAYED_WORK(&ctrl_info->rescan_work, pqi_rescan_worker); INIT_DELAYED_WORK(&ctrl_info->update_time_work, pqi_update_time_worker); @@ -8683,24 +8718,12 @@ static void pqi_shutdown(struct pci_dev *pci_dev) return; } - pqi_disable_events(ctrl_info); pqi_wait_until_ofa_finished(ctrl_info); - pqi_cancel_update_time_worker(ctrl_info); - pqi_cancel_rescan_worker(ctrl_info); - pqi_cancel_event_worker(ctrl_info); - - pqi_ctrl_shutdown_start(ctrl_info); - pqi_ctrl_wait_until_quiesced(ctrl_info); - - rc = pqi_ctrl_wait_for_pending_io(ctrl_info, NO_TIMEOUT); - if (rc) { - dev_err(&pci_dev->dev, - "wait for pending I/O failed\n"); - return; - } + pqi_scsi_block_requests(ctrl_info); pqi_ctrl_block_device_reset(ctrl_info); - pqi_wait_until_lun_reset_finished(ctrl_info); + pqi_ctrl_block_requests(ctrl_info); + pqi_ctrl_wait_until_quiesced(ctrl_info); /* * Write all data in the controller's battery-backed cache to @@ -8711,15 +8734,6 @@ static void pqi_shutdown(struct pci_dev *pci_dev) dev_err(&pci_dev->dev, "unable to flush controller cache\n"); - pqi_ctrl_block_requests(ctrl_info); - - rc = pqi_ctrl_wait_for_pending_sync_cmds(ctrl_info); - if (rc) { - dev_err(&pci_dev->dev, - "wait for pending sync cmds failed\n"); - return; - } - pqi_crash_if_pending_command(ctrl_info); pqi_reset(ctrl_info); } @@ -8754,19 +8768,18 @@ static __maybe_unused int pqi_suspend(struct pci_dev *pci_dev, pm_message_t stat ctrl_info = pci_get_drvdata(pci_dev); - pqi_disable_events(ctrl_info); - pqi_cancel_update_time_worker(ctrl_info); - pqi_cancel_rescan_worker(ctrl_info); - pqi_wait_until_scan_finished(ctrl_info); - pqi_wait_until_lun_reset_finished(ctrl_info); pqi_wait_until_ofa_finished(ctrl_info); - pqi_flush_cache(ctrl_info, SUSPEND); + + pqi_ctrl_block_scan(ctrl_info); + pqi_scsi_block_requests(ctrl_info); + pqi_ctrl_block_device_reset(ctrl_info); pqi_ctrl_block_requests(ctrl_info); pqi_ctrl_wait_until_quiesced(ctrl_info); - pqi_wait_until_inbound_queues_empty(ctrl_info); - pqi_ctrl_wait_for_pending_io(ctrl_info, NO_TIMEOUT); + pqi_flush_cache(ctrl_info, SUSPEND); pqi_stop_heartbeat_timer(ctrl_info); + pqi_crash_if_pending_command(ctrl_info); + if (state.event == PM_EVENT_FREEZE) return 0; @@ -8799,8 +8812,8 @@ static __maybe_unused int pqi_resume(struct pci_dev *pci_dev) pci_dev->irq, rc); return rc; } - pqi_start_heartbeat_timer(ctrl_info); pqi_ctrl_unblock_requests(ctrl_info); + pqi_scsi_unblock_requests(ctrl_info); return 0; } From 5be9db069d3faac584bec6db6ca98e699abf199e Mon Sep 17 00:00:00 2001 From: Kevin Barnett Date: Thu, 11 Mar 2021 14:16:49 -0600 Subject: [PATCH 298/412] scsi: smartpqi: Update RAID bypass handling Simplify AIO retry management by removing retry list and list management. Need to retry is already set in the response status. Also remove the bypass worker thread. Accelerated I/O requests bypass the RAID engine and go directly to either an HBA disk or to a physical component of a RAID volume. Link: https://lore.kernel.org/r/161549380976.25025.11776487034357231156.stgit@brunhilda Reviewed-by: Scott Benesh Reviewed-by: Scott Teel Signed-off-by: Kevin Barnett Signed-off-by: Don Brace Signed-off-by: Martin K. Petersen --- drivers/scsi/smartpqi/smartpqi.h | 4 - drivers/scsi/smartpqi/smartpqi_init.c | 172 +++----------------------- 2 files changed, 19 insertions(+), 157 deletions(-) diff --git a/drivers/scsi/smartpqi/smartpqi.h b/drivers/scsi/smartpqi/smartpqi.h index fa1ebeea777d..1b9aa6e9e04c 100644 --- a/drivers/scsi/smartpqi/smartpqi.h +++ b/drivers/scsi/smartpqi/smartpqi.h @@ -1347,10 +1347,6 @@ struct pqi_ctrl_info { atomic_t num_blocked_threads; wait_queue_head_t block_requests_wait; - struct list_head raid_bypass_retry_list; - spinlock_t raid_bypass_retry_list_lock; - struct work_struct raid_bypass_retry_work; - struct pqi_ofa_memory *pqi_ofa_mem_virt_addr; dma_addr_t pqi_ofa_mem_dma_handle; void **pqi_ofa_chunk_virt_addr; diff --git a/drivers/scsi/smartpqi/smartpqi_init.c b/drivers/scsi/smartpqi/smartpqi_init.c index 4f7a38b96356..b44de3e25541 100644 --- a/drivers/scsi/smartpqi/smartpqi_init.c +++ b/drivers/scsi/smartpqi/smartpqi_init.c @@ -5280,12 +5280,6 @@ static inline int pqi_raid_submit_scsi_cmd(struct pqi_ctrl_info *ctrl_info, device, scmd, queue_group); } -static inline void pqi_schedule_bypass_retry(struct pqi_ctrl_info *ctrl_info) -{ - if (!pqi_ctrl_blocked(ctrl_info)) - schedule_work(&ctrl_info->raid_bypass_retry_work); -} - static bool pqi_raid_bypass_retry_needed(struct pqi_io_request *io_request) { struct scsi_cmnd *scmd; @@ -5302,7 +5296,7 @@ static bool pqi_raid_bypass_retry_needed(struct pqi_io_request *io_request) return false; device = scmd->device->hostdata; - if (pqi_device_offline(device)) + if (pqi_device_offline(device) || pqi_device_in_remove(device)) return false; ctrl_info = shost_to_hba(scmd->device->host); @@ -5312,132 +5306,6 @@ static bool pqi_raid_bypass_retry_needed(struct pqi_io_request *io_request) return true; } -static inline void pqi_add_to_raid_bypass_retry_list( - struct pqi_ctrl_info *ctrl_info, - struct pqi_io_request *io_request, bool at_head) -{ - unsigned long flags; - - spin_lock_irqsave(&ctrl_info->raid_bypass_retry_list_lock, flags); - if (at_head) - list_add(&io_request->request_list_entry, - &ctrl_info->raid_bypass_retry_list); - else - list_add_tail(&io_request->request_list_entry, - &ctrl_info->raid_bypass_retry_list); - spin_unlock_irqrestore(&ctrl_info->raid_bypass_retry_list_lock, flags); -} - -static void pqi_queued_raid_bypass_complete(struct pqi_io_request *io_request, - void *context) -{ - struct scsi_cmnd *scmd; - - scmd = io_request->scmd; - pqi_free_io_request(io_request); - pqi_scsi_done(scmd); -} - -static void pqi_queue_raid_bypass_retry(struct pqi_io_request *io_request) -{ - struct scsi_cmnd *scmd; - struct pqi_ctrl_info *ctrl_info; - - io_request->io_complete_callback = pqi_queued_raid_bypass_complete; - scmd = io_request->scmd; - scmd->result = 0; - ctrl_info = shost_to_hba(scmd->device->host); - - pqi_add_to_raid_bypass_retry_list(ctrl_info, io_request, false); - pqi_schedule_bypass_retry(ctrl_info); -} - -static int pqi_retry_raid_bypass(struct pqi_io_request *io_request) -{ - struct scsi_cmnd *scmd; - struct pqi_scsi_dev *device; - struct pqi_ctrl_info *ctrl_info; - struct pqi_queue_group *queue_group; - - scmd = io_request->scmd; - device = scmd->device->hostdata; - if (pqi_device_in_reset(device)) { - pqi_free_io_request(io_request); - set_host_byte(scmd, DID_RESET); - pqi_scsi_done(scmd); - return 0; - } - - ctrl_info = shost_to_hba(scmd->device->host); - queue_group = io_request->queue_group; - - pqi_reinit_io_request(io_request); - - return pqi_raid_submit_scsi_cmd_with_io_request(ctrl_info, io_request, - device, scmd, queue_group); -} - -static inline struct pqi_io_request *pqi_next_queued_raid_bypass_request( - struct pqi_ctrl_info *ctrl_info) -{ - unsigned long flags; - struct pqi_io_request *io_request; - - spin_lock_irqsave(&ctrl_info->raid_bypass_retry_list_lock, flags); - io_request = list_first_entry_or_null( - &ctrl_info->raid_bypass_retry_list, - struct pqi_io_request, request_list_entry); - if (io_request) - list_del(&io_request->request_list_entry); - spin_unlock_irqrestore(&ctrl_info->raid_bypass_retry_list_lock, flags); - - return io_request; -} - -static void pqi_retry_raid_bypass_requests(struct pqi_ctrl_info *ctrl_info) -{ - int rc; - struct pqi_io_request *io_request; - - pqi_ctrl_busy(ctrl_info); - - while (1) { - if (pqi_ctrl_blocked(ctrl_info)) - break; - io_request = pqi_next_queued_raid_bypass_request(ctrl_info); - if (!io_request) - break; - rc = pqi_retry_raid_bypass(io_request); - if (rc) { - pqi_add_to_raid_bypass_retry_list(ctrl_info, io_request, - true); - pqi_schedule_bypass_retry(ctrl_info); - break; - } - } - - pqi_ctrl_unbusy(ctrl_info); -} - -static void pqi_raid_bypass_retry_worker(struct work_struct *work) -{ - struct pqi_ctrl_info *ctrl_info; - - ctrl_info = container_of(work, struct pqi_ctrl_info, - raid_bypass_retry_work); - pqi_retry_raid_bypass_requests(ctrl_info); -} - -static void pqi_clear_all_queued_raid_bypass_retries( - struct pqi_ctrl_info *ctrl_info) -{ - unsigned long flags; - - spin_lock_irqsave(&ctrl_info->raid_bypass_retry_list_lock, flags); - INIT_LIST_HEAD(&ctrl_info->raid_bypass_retry_list); - spin_unlock_irqrestore(&ctrl_info->raid_bypass_retry_list_lock, flags); -} - static void pqi_aio_io_complete(struct pqi_io_request *io_request, void *context) { @@ -5445,12 +5313,11 @@ static void pqi_aio_io_complete(struct pqi_io_request *io_request, scmd = io_request->scmd; scsi_dma_unmap(scmd); - if (io_request->status == -EAGAIN) + if (io_request->status == -EAGAIN || pqi_raid_bypass_retry_needed(io_request)) { set_host_byte(scmd, DID_IMM_RETRY); - else if (pqi_raid_bypass_retry_needed(io_request)) { - pqi_queue_raid_bypass_retry(io_request); - return; + scmd->SCp.this_residual++; } + pqi_free_io_request(io_request); pqi_scsi_done(scmd); } @@ -5667,6 +5534,14 @@ static inline u16 pqi_get_hw_queue(struct pqi_ctrl_info *ctrl_info, return hw_queue; } +static inline bool pqi_is_bypass_eligible_request(struct scsi_cmnd *scmd) +{ + if (blk_rq_is_passthrough(scmd->request)) + return false; + + return scmd->SCp.this_residual == 0; +} + /* * This function gets called just before we hand the completed SCSI request * back to the SML. @@ -5792,9 +5667,7 @@ static int pqi_scsi_queue_command(struct Scsi_Host *shost, struct scsi_cmnd *scm return 0; } - pqi_ctrl_busy(ctrl_info); - if (pqi_ctrl_blocked(ctrl_info) || pqi_device_in_reset(device) || - pqi_ctrl_in_ofa(ctrl_info) || pqi_ctrl_in_shutdown(ctrl_info)) { + if (pqi_ctrl_blocked(ctrl_info)) { rc = SCSI_MLQUEUE_HOST_BUSY; goto out; } @@ -5811,13 +5684,12 @@ static int pqi_scsi_queue_command(struct Scsi_Host *shost, struct scsi_cmnd *scm if (pqi_is_logical_device(device)) { raid_bypassed = false; if (device->raid_bypass_enabled && - !blk_rq_is_passthrough(scmd->request)) { - if (!pqi_is_parity_write_stream(ctrl_info, scmd)) { - rc = pqi_raid_bypass_submit_scsi_cmd(ctrl_info, device, scmd, queue_group); - if (rc == 0 || rc == SCSI_MLQUEUE_HOST_BUSY) { - raid_bypassed = true; - atomic_inc(&device->raid_bypass_cnt); - } + pqi_is_bypass_eligible_request(scmd) && + !pqi_is_parity_write_stream(ctrl_info, scmd)) { + rc = pqi_raid_bypass_submit_scsi_cmd(ctrl_info, device, scmd, queue_group); + if (rc == 0 || rc == SCSI_MLQUEUE_HOST_BUSY) { + raid_bypassed = true; + atomic_inc(&device->raid_bypass_cnt); } } if (!raid_bypassed) @@ -8255,11 +8127,6 @@ static struct pqi_ctrl_info *pqi_alloc_ctrl_info(int numa_node) PQI_RESERVED_IO_SLOTS_SYNCHRONOUS_REQUESTS); init_waitqueue_head(&ctrl_info->block_requests_wait); - INIT_LIST_HEAD(&ctrl_info->raid_bypass_retry_list); - spin_lock_init(&ctrl_info->raid_bypass_retry_list_lock); - INIT_WORK(&ctrl_info->raid_bypass_retry_work, - pqi_raid_bypass_retry_worker); - ctrl_info->ctrl_id = atomic_inc_return(&pqi_controller_count) - 1; ctrl_info->irq_mode = IRQ_MODE_NONE; ctrl_info->max_msix_vectors = PQI_MAX_MSIX_VECTORS; @@ -8585,7 +8452,6 @@ static void pqi_take_ctrl_offline_deferred(struct pqi_ctrl_info *ctrl_info) pqi_cancel_update_time_worker(ctrl_info); pqi_ctrl_wait_until_quiesced(ctrl_info); pqi_fail_all_outstanding_requests(ctrl_info); - pqi_clear_all_queued_raid_bypass_retries(ctrl_info); pqi_ctrl_unblock_requests(ctrl_info); } From 2790cd4d3f6ac5a761b0e3851fce2e75490b5051 Mon Sep 17 00:00:00 2001 From: Kevin Barnett Date: Thu, 11 Mar 2021 14:16:55 -0600 Subject: [PATCH 299/412] scsi: smartpqi: Update OFA management OFA, Online Firmware Activation, allows users to update firmware without a reboot. - Change OFA setup to a worker thread - Delay soft resets - Add OFA event handler to allow FW to initiate OFA - Add in-memory allocation to OFA events - Update OFA buffer size calculations - Add ability to cancel OFA events - Update OFA quiesce/un-quiesce - Prevent Kernel crashes while issuing ioctl during OFA - Returned EBUSY for pass-through IOCTLs throughout all stages of OFA - Add mutex to prevent parallel OFA updates. Link: https://lore.kernel.org/r/161549381563.25025.2647205502550052197.stgit@brunhilda Reviewed-by: Scott Benesh Reviewed-by: Scott Teel Signed-off-by: Kevin Barnett Signed-off-by: Don Brace Signed-off-by: Martin K. Petersen --- drivers/scsi/smartpqi/smartpqi.h | 18 +- drivers/scsi/smartpqi/smartpqi_init.c | 376 +++++++++++++------------- 2 files changed, 197 insertions(+), 197 deletions(-) diff --git a/drivers/scsi/smartpqi/smartpqi.h b/drivers/scsi/smartpqi/smartpqi.h index 1b9aa6e9e04c..0b94c755a74c 100644 --- a/drivers/scsi/smartpqi/smartpqi.h +++ b/drivers/scsi/smartpqi/smartpqi.h @@ -511,10 +511,6 @@ struct pqi_vendor_general_response { #define PQI_OFA_SIGNATURE "OFA_QRM" #define PQI_OFA_MAX_SG_DESCRIPTORS 64 -#define PQI_OFA_MEMORY_DESCRIPTOR_LENGTH \ - (offsetof(struct pqi_ofa_memory, sg_descriptor) + \ - (PQI_OFA_MAX_SG_DESCRIPTORS * sizeof(struct pqi_sg_descriptor))) - struct pqi_ofa_memory { __le64 signature; /* "OFA_QRM" */ __le16 version; /* version of this struct (1 = 1st version) */ @@ -522,7 +518,7 @@ struct pqi_ofa_memory { __le32 bytes_allocated; /* total allocated memory in bytes */ __le16 num_memory_descriptors; u8 reserved1[2]; - struct pqi_sg_descriptor sg_descriptor[1]; + struct pqi_sg_descriptor sg_descriptor[PQI_OFA_MAX_SG_DESCRIPTORS]; }; struct pqi_aio_error_info { @@ -1075,7 +1071,6 @@ struct pqi_scsi_dev { u8 volume_offline : 1; u8 rescan : 1; bool aio_enabled; /* only valid for physical disks */ - bool in_reset; bool in_remove; bool device_offline; u8 vendor[8]; /* bytes 8-15 of inquiry data */ @@ -1219,8 +1214,6 @@ struct pqi_event { u8 event_type; u16 event_id; u32 additional_event_id; - __le32 ofa_bytes_requested; - __le16 ofa_cancel_reason; }; #define PQI_RESERVED_IO_SLOTS_LUN_RESET 1 @@ -1292,12 +1285,9 @@ struct pqi_ctrl_info { struct mutex scan_mutex; struct mutex lun_reset_mutex; - struct mutex ofa_mutex; /* serialize ofa */ bool controller_online; bool block_requests; bool scan_blocked; - bool in_ofa; - bool in_shutdown; u8 inbound_spanning_supported : 1; u8 outbound_spanning_supported : 1; u8 pqi_mode_enabled : 1; @@ -1347,10 +1337,14 @@ struct pqi_ctrl_info { atomic_t num_blocked_threads; wait_queue_head_t block_requests_wait; + struct mutex ofa_mutex; struct pqi_ofa_memory *pqi_ofa_mem_virt_addr; dma_addr_t pqi_ofa_mem_dma_handle; void **pqi_ofa_chunk_virt_addr; - atomic_t sync_cmds_outstanding; + struct work_struct ofa_memory_alloc_work; + struct work_struct ofa_quiesce_work; + u32 ofa_bytes_requested; + u16 ofa_cancel_reason; }; enum pqi_ctrl_mode { diff --git a/drivers/scsi/smartpqi/smartpqi_init.c b/drivers/scsi/smartpqi/smartpqi_init.c index b44de3e25541..89b6972a21f6 100644 --- a/drivers/scsi/smartpqi/smartpqi_init.c +++ b/drivers/scsi/smartpqi/smartpqi_init.c @@ -45,6 +45,9 @@ #define PQI_EXTRA_SGL_MEMORY (12 * sizeof(struct pqi_sg_descriptor)) +#define PQI_POST_RESET_DELAY_SECS 5 +#define PQI_POST_OFA_RESET_DELAY_UPON_TIMEOUT_SECS 10 + MODULE_AUTHOR("Microsemi"); MODULE_DESCRIPTION("Driver for Microsemi Smart Family Controller version " DRIVER_VERSION); @@ -76,9 +79,8 @@ static int pqi_aio_submit_r56_write_io(struct pqi_ctrl_info *ctrl_info, struct pqi_scsi_dev_raid_map_data *rmd); static void pqi_ofa_ctrl_quiesce(struct pqi_ctrl_info *ctrl_info); static void pqi_ofa_ctrl_unquiesce(struct pqi_ctrl_info *ctrl_info); -static int pqi_ofa_ctrl_restart(struct pqi_ctrl_info *ctrl_info); -static void pqi_ofa_setup_host_buffer(struct pqi_ctrl_info *ctrl_info, - u32 bytes_requested); +static int pqi_ofa_ctrl_restart(struct pqi_ctrl_info *ctrl_info, unsigned int delay_secs); +static void pqi_ofa_setup_host_buffer(struct pqi_ctrl_info *ctrl_info); static void pqi_ofa_free_host_buffer(struct pqi_ctrl_info *ctrl_info); static int pqi_ofa_host_memory_update(struct pqi_ctrl_info *ctrl_info); static int pqi_device_wait_for_pending_io(struct pqi_ctrl_info *ctrl_info, @@ -345,24 +347,25 @@ static inline bool pqi_device_offline(struct pqi_scsi_dev *device) return device->device_offline; } -static inline bool pqi_device_in_reset(struct pqi_scsi_dev *device) -{ - return device->in_reset; -} - static inline void pqi_ctrl_ofa_start(struct pqi_ctrl_info *ctrl_info) { - ctrl_info->in_ofa = true; + mutex_lock(&ctrl_info->ofa_mutex); } static inline void pqi_ctrl_ofa_done(struct pqi_ctrl_info *ctrl_info) { - ctrl_info->in_ofa = false; + mutex_unlock(&ctrl_info->ofa_mutex); } -static inline bool pqi_ctrl_in_ofa(struct pqi_ctrl_info *ctrl_info) +static inline void pqi_wait_until_ofa_finished(struct pqi_ctrl_info *ctrl_info) { - return ctrl_info->in_ofa; + mutex_lock(&ctrl_info->ofa_mutex); + mutex_unlock(&ctrl_info->ofa_mutex); +} + +static inline bool pqi_ofa_in_progress(struct pqi_ctrl_info *ctrl_info) +{ + return mutex_is_locked(&ctrl_info->ofa_mutex); } static inline void pqi_device_remove_start(struct pqi_scsi_dev *device) @@ -375,14 +378,20 @@ static inline bool pqi_device_in_remove(struct pqi_scsi_dev *device) return device->in_remove; } -static inline void pqi_ctrl_shutdown_start(struct pqi_ctrl_info *ctrl_info) +static inline int pqi_event_type_to_event_index(unsigned int event_type) { - ctrl_info->in_shutdown = true; + int index; + + for (index = 0; index < ARRAY_SIZE(pqi_supported_event_types); index++) + if (event_type == pqi_supported_event_types[index]) + return index; + + return -1; } -static inline bool pqi_ctrl_in_shutdown(struct pqi_ctrl_info *ctrl_info) +static inline bool pqi_is_supported_event(unsigned int event_type) { - return ctrl_info->in_shutdown; + return pqi_event_type_to_event_index(event_type) != -1; } static inline void pqi_schedule_rescan_worker_with_delay(struct pqi_ctrl_info *ctrl_info, @@ -390,8 +399,6 @@ static inline void pqi_schedule_rescan_worker_with_delay(struct pqi_ctrl_info *c { if (pqi_ctrl_offline(ctrl_info)) return; - if (pqi_ctrl_in_ofa(ctrl_info)) - return; schedule_delayed_work(&ctrl_info->rescan_work, delay); } @@ -1982,8 +1989,18 @@ static void pqi_update_device_list(struct pqi_ctrl_info *ctrl_info, spin_unlock_irqrestore(&ctrl_info->scsi_device_list_lock, flags); - if (pqi_ctrl_in_ofa(ctrl_info)) - pqi_ctrl_ofa_done(ctrl_info); + /* + * If OFA is in progress and there are devices that need to be deleted, + * allow any pending reset operations to continue and unblock any SCSI + * requests before removal. + */ + if (pqi_ofa_in_progress(ctrl_info)) { + list_for_each_entry_safe(device, next, &delete_list, delete_list_entry) + if (pqi_is_device_added(device)) + pqi_device_remove_start(device); + pqi_ctrl_unblock_device_reset(ctrl_info); + pqi_scsi_unblock_requests(ctrl_info); + } /* Remove all devices that have gone away. */ list_for_each_entry_safe(device, next, &delete_list, delete_list_entry) { @@ -2318,8 +2335,6 @@ static void pqi_scan_start(struct Scsi_Host *shost) struct pqi_ctrl_info *ctrl_info; ctrl_info = shost_to_hba(shost); - if (pqi_ctrl_in_ofa(ctrl_info)) - return; pqi_scan_scsi_devices(ctrl_info); } @@ -2336,24 +2351,6 @@ static int pqi_scan_finished(struct Scsi_Host *shost, return !mutex_is_locked(&ctrl_info->scan_mutex); } -static void pqi_wait_until_scan_finished(struct pqi_ctrl_info *ctrl_info) -{ - mutex_lock(&ctrl_info->scan_mutex); - mutex_unlock(&ctrl_info->scan_mutex); -} - -static void pqi_wait_until_lun_reset_finished(struct pqi_ctrl_info *ctrl_info) -{ - mutex_lock(&ctrl_info->lun_reset_mutex); - mutex_unlock(&ctrl_info->lun_reset_mutex); -} - -static void pqi_wait_until_ofa_finished(struct pqi_ctrl_info *ctrl_info) -{ - mutex_lock(&ctrl_info->ofa_mutex); - mutex_unlock(&ctrl_info->ofa_mutex); -} - static inline void pqi_set_encryption_info(struct pqi_encryption_info *encryption_info, struct raid_map *raid_map, u64 first_block) { @@ -3320,6 +3317,7 @@ static enum pqi_soft_reset_status pqi_poll_for_soft_reset_status( static void pqi_process_soft_reset(struct pqi_ctrl_info *ctrl_info) { int rc; + unsigned int delay_secs; enum pqi_soft_reset_status reset_status; if (ctrl_info->soft_reset_handshake_supported) @@ -3327,8 +3325,11 @@ static void pqi_process_soft_reset(struct pqi_ctrl_info *ctrl_info) else reset_status = RESET_INITIATE_FIRMWARE; + delay_secs = PQI_POST_RESET_DELAY_SECS; + switch (reset_status) { case RESET_TIMEDOUT: + delay_secs = PQI_POST_OFA_RESET_DELAY_UPON_TIMEOUT_SECS; fallthrough; case RESET_INITIATE_DRIVER: dev_info(&ctrl_info->pci_dev->dev, @@ -3338,7 +3339,7 @@ static void pqi_process_soft_reset(struct pqi_ctrl_info *ctrl_info) case RESET_INITIATE_FIRMWARE: ctrl_info->pqi_mode_enabled = false; pqi_save_ctrl_mode(ctrl_info, SIS_MODE); - rc = pqi_ofa_ctrl_restart(ctrl_info); + rc = pqi_ofa_ctrl_restart(ctrl_info, delay_secs); pqi_ofa_free_host_buffer(ctrl_info); pqi_ctrl_ofa_done(ctrl_info); dev_info(&ctrl_info->pci_dev->dev, @@ -3368,43 +3369,74 @@ static void pqi_process_soft_reset(struct pqi_ctrl_info *ctrl_info) } } -static void pqi_ofa_process_event(struct pqi_ctrl_info *ctrl_info, +static void pqi_ofa_memory_alloc_worker(struct work_struct *work) +{ + struct pqi_ctrl_info *ctrl_info; + + ctrl_info = container_of(work, struct pqi_ctrl_info, ofa_memory_alloc_work); + + pqi_ctrl_ofa_start(ctrl_info); + pqi_ofa_setup_host_buffer(ctrl_info); + pqi_ofa_host_memory_update(ctrl_info); +} + +static void pqi_ofa_quiesce_worker(struct work_struct *work) +{ + struct pqi_ctrl_info *ctrl_info; + struct pqi_event *event; + + ctrl_info = container_of(work, struct pqi_ctrl_info, ofa_quiesce_work); + + event = &ctrl_info->events[pqi_event_type_to_event_index(PQI_EVENT_TYPE_OFA)]; + + pqi_ofa_ctrl_quiesce(ctrl_info); + pqi_acknowledge_event(ctrl_info, event); + pqi_process_soft_reset(ctrl_info); +} + +static bool pqi_ofa_process_event(struct pqi_ctrl_info *ctrl_info, struct pqi_event *event) { - u16 event_id; + bool ack_event; - event_id = get_unaligned_le16(&event->event_id); + ack_event = true; - mutex_lock(&ctrl_info->ofa_mutex); - - if (event_id == PQI_EVENT_OFA_QUIESCE) { + switch (event->event_id) { + case PQI_EVENT_OFA_MEMORY_ALLOCATION: dev_info(&ctrl_info->pci_dev->dev, - "Received Online Firmware Activation quiesce event for controller %u\n", - ctrl_info->ctrl_id); - pqi_ofa_ctrl_quiesce(ctrl_info); - pqi_acknowledge_event(ctrl_info, event); - pqi_process_soft_reset(ctrl_info); - } else if (event_id == PQI_EVENT_OFA_MEMORY_ALLOCATION) { - pqi_acknowledge_event(ctrl_info, event); - pqi_ofa_setup_host_buffer(ctrl_info, - le32_to_cpu(event->ofa_bytes_requested)); - pqi_ofa_host_memory_update(ctrl_info); - } else if (event_id == PQI_EVENT_OFA_CANCELED) { + "received Online Firmware Activation memory allocation request\n"); + schedule_work(&ctrl_info->ofa_memory_alloc_work); + break; + case PQI_EVENT_OFA_QUIESCE: + dev_info(&ctrl_info->pci_dev->dev, + "received Online Firmware Activation quiesce request\n"); + schedule_work(&ctrl_info->ofa_quiesce_work); + ack_event = false; + break; + case PQI_EVENT_OFA_CANCELED: + dev_info(&ctrl_info->pci_dev->dev, + "received Online Firmware Activation cancel request: reason: %u\n", + ctrl_info->ofa_cancel_reason); pqi_ofa_free_host_buffer(ctrl_info); - pqi_acknowledge_event(ctrl_info, event); - dev_info(&ctrl_info->pci_dev->dev, - "Online Firmware Activation(%u) cancel reason : %u\n", - ctrl_info->ctrl_id, event->ofa_cancel_reason); + pqi_ctrl_ofa_done(ctrl_info); + break; + default: + dev_err(&ctrl_info->pci_dev->dev, + "received unknown Online Firmware Activation request: event ID: %u\n", + event->event_id); + break; } - mutex_unlock(&ctrl_info->ofa_mutex); + return ack_event; } static void pqi_event_worker(struct work_struct *work) { unsigned int i; + bool rescan_needed; struct pqi_ctrl_info *ctrl_info; struct pqi_event *event; + bool ack_event; ctrl_info = container_of(work, struct pqi_ctrl_info, event_work); @@ -3413,22 +3445,26 @@ static void pqi_event_worker(struct work_struct *work) if (pqi_ctrl_offline(ctrl_info)) goto out; - pqi_schedule_rescan_worker_delayed(ctrl_info); - + rescan_needed = false; event = ctrl_info->events; for (i = 0; i < PQI_NUM_SUPPORTED_EVENTS; i++) { if (event->pending) { event->pending = false; if (event->event_type == PQI_EVENT_TYPE_OFA) { - pqi_ctrl_unbusy(ctrl_info); - pqi_ofa_process_event(ctrl_info, event); - return; + ack_event = pqi_ofa_process_event(ctrl_info, event); + } else { + ack_event = true; + rescan_needed = true; } - pqi_acknowledge_event(ctrl_info, event); + if (ack_event) + pqi_acknowledge_event(ctrl_info, event); } event++; } + if (rescan_needed) + pqi_schedule_rescan_worker_delayed(ctrl_info); + out: pqi_ctrl_unbusy(ctrl_info); } @@ -3485,37 +3521,18 @@ static inline void pqi_stop_heartbeat_timer(struct pqi_ctrl_info *ctrl_info) del_timer_sync(&ctrl_info->heartbeat_timer); } -static inline int pqi_event_type_to_event_index(unsigned int event_type) +static void pqi_ofa_capture_event_payload(struct pqi_ctrl_info *ctrl_info, + struct pqi_event *event, struct pqi_event_response *response) { - int index; - - for (index = 0; index < ARRAY_SIZE(pqi_supported_event_types); index++) - if (event_type == pqi_supported_event_types[index]) - return index; - - return -1; -} - -static inline bool pqi_is_supported_event(unsigned int event_type) -{ - return pqi_event_type_to_event_index(event_type) != -1; -} - -static void pqi_ofa_capture_event_payload(struct pqi_event *event, - struct pqi_event_response *response) -{ - u16 event_id; - - event_id = get_unaligned_le16(&event->event_id); - - if (event->event_type == PQI_EVENT_TYPE_OFA) { - if (event_id == PQI_EVENT_OFA_MEMORY_ALLOCATION) { - event->ofa_bytes_requested = - response->data.ofa_memory_allocation.bytes_requested; - } else if (event_id == PQI_EVENT_OFA_CANCELED) { - event->ofa_cancel_reason = - response->data.ofa_cancelled.reason; - } + switch (event->event_id) { + case PQI_EVENT_OFA_MEMORY_ALLOCATION: + ctrl_info->ofa_bytes_requested = + get_unaligned_le32(&response->data.ofa_memory_allocation.bytes_requested); + break; + case PQI_EVENT_OFA_CANCELED: + ctrl_info->ofa_cancel_reason = + get_unaligned_le16(&response->data.ofa_cancelled.reason); + break; } } @@ -3559,7 +3576,7 @@ static int pqi_process_event_intr(struct pqi_ctrl_info *ctrl_info) event->additional_event_id = get_unaligned_le32(&response->additional_event_id); if (event->event_type == PQI_EVENT_TYPE_OFA) - pqi_ofa_capture_event_payload(event, response); + pqi_ofa_capture_event_payload(ctrl_info, event, response); } oq_ci = (oq_ci + 1) % PQI_NUM_EVENT_QUEUE_ELEMENTS; @@ -6282,6 +6299,8 @@ static int pqi_passthru_ioctl(struct pqi_ctrl_info *ctrl_info, void __user *arg) if (pqi_ctrl_offline(ctrl_info)) return -ENXIO; + if (pqi_ofa_in_progress(ctrl_info) && pqi_ctrl_blocked(ctrl_info)) + return -EBUSY; if (!arg) return -EINVAL; if (!capable(CAP_SYS_RAWIO)) @@ -6418,9 +6437,6 @@ static int pqi_ioctl(struct scsi_device *sdev, unsigned int cmd, ctrl_info = shost_to_hba(sdev->host); - if (pqi_ctrl_in_ofa(ctrl_info) || pqi_ctrl_in_shutdown(ctrl_info)) - return -EBUSY; - switch (cmd) { case CCISS_DEREGDISK: case CCISS_REGNEWDISK: @@ -8003,7 +8019,8 @@ static int pqi_ctrl_init_resume(struct pqi_ctrl_info *ctrl_info) return rc; } - pqi_schedule_update_time_worker(ctrl_info); + if (pqi_ofa_in_progress(ctrl_info)) + pqi_ctrl_unblock_scan(ctrl_info); pqi_scan_scsi_devices(ctrl_info); @@ -8123,6 +8140,9 @@ static struct pqi_ctrl_info *pqi_alloc_ctrl_info(int numa_node) timer_setup(&ctrl_info->heartbeat_timer, pqi_heartbeat_timer_handler, 0); INIT_WORK(&ctrl_info->ctrl_offline_work, pqi_ctrl_offline_worker); + INIT_WORK(&ctrl_info->ofa_memory_alloc_work, pqi_ofa_memory_alloc_worker); + INIT_WORK(&ctrl_info->ofa_quiesce_work, pqi_ofa_quiesce_worker); + sema_init(&ctrl_info->sync_request_sem, PQI_RESERVED_IO_SLOTS_SYNCHRONOUS_REQUESTS); init_waitqueue_head(&ctrl_info->block_requests_wait); @@ -8191,11 +8211,9 @@ static void pqi_remove_ctrl(struct pqi_ctrl_info *ctrl_info) static void pqi_ofa_ctrl_quiesce(struct pqi_ctrl_info *ctrl_info) { - pqi_cancel_update_time_worker(ctrl_info); - pqi_cancel_rescan_worker(ctrl_info); - pqi_wait_until_lun_reset_finished(ctrl_info); - pqi_wait_until_scan_finished(ctrl_info); - pqi_ctrl_ofa_start(ctrl_info); + pqi_ctrl_block_scan(ctrl_info); + pqi_scsi_block_requests(ctrl_info); + pqi_ctrl_block_device_reset(ctrl_info); pqi_ctrl_block_requests(ctrl_info); pqi_ctrl_wait_until_quiesced(ctrl_info); pqi_ctrl_wait_for_pending_io(ctrl_info, PQI_PENDING_IO_TIMEOUT_SECS); @@ -8208,63 +8226,47 @@ static void pqi_ofa_ctrl_quiesce(struct pqi_ctrl_info *ctrl_info) static void pqi_ofa_ctrl_unquiesce(struct pqi_ctrl_info *ctrl_info) { - pqi_ofa_free_host_buffer(ctrl_info); - ctrl_info->pqi_mode_enabled = true; - pqi_save_ctrl_mode(ctrl_info, PQI_MODE); - ctrl_info->controller_online = true; - pqi_ctrl_unblock_requests(ctrl_info); pqi_start_heartbeat_timer(ctrl_info); - pqi_schedule_update_time_worker(ctrl_info); - pqi_clear_soft_reset_status(ctrl_info); - pqi_scan_scsi_devices(ctrl_info); + pqi_ctrl_unblock_requests(ctrl_info); + pqi_ctrl_unblock_device_reset(ctrl_info); + pqi_scsi_unblock_requests(ctrl_info); + pqi_ctrl_unblock_scan(ctrl_info); } -static int pqi_ofa_alloc_mem(struct pqi_ctrl_info *ctrl_info, - u32 total_size, u32 chunk_size) +static int pqi_ofa_alloc_mem(struct pqi_ctrl_info *ctrl_info, u32 total_size, u32 chunk_size) { - u32 sg_count; - u32 size; int i; - struct pqi_sg_descriptor *mem_descriptor = NULL; + u32 sg_count; struct device *dev; struct pqi_ofa_memory *ofap; - - dev = &ctrl_info->pci_dev->dev; - - sg_count = (total_size + chunk_size - 1); - sg_count /= chunk_size; + struct pqi_sg_descriptor *mem_descriptor; + dma_addr_t dma_handle; ofap = ctrl_info->pqi_ofa_mem_virt_addr; - if (sg_count*chunk_size < total_size) + sg_count = DIV_ROUND_UP(total_size, chunk_size); + if (sg_count == 0 || sg_count > PQI_OFA_MAX_SG_DESCRIPTORS) goto out; - ctrl_info->pqi_ofa_chunk_virt_addr = - kcalloc(sg_count, sizeof(void *), GFP_KERNEL); + ctrl_info->pqi_ofa_chunk_virt_addr = kmalloc_array(sg_count, sizeof(void *), GFP_KERNEL); if (!ctrl_info->pqi_ofa_chunk_virt_addr) goto out; - for (size = 0, i = 0; size < total_size; size += chunk_size, i++) { - dma_addr_t dma_handle; + dev = &ctrl_info->pci_dev->dev; + for (i = 0; i < sg_count; i++) { ctrl_info->pqi_ofa_chunk_virt_addr[i] = - dma_alloc_coherent(dev, chunk_size, &dma_handle, - GFP_KERNEL); - + dma_alloc_coherent(dev, chunk_size, &dma_handle, GFP_KERNEL); if (!ctrl_info->pqi_ofa_chunk_virt_addr[i]) - break; - + goto out_free_chunks; mem_descriptor = &ofap->sg_descriptor[i]; put_unaligned_le64((u64)dma_handle, &mem_descriptor->address); put_unaligned_le32(chunk_size, &mem_descriptor->length); } - if (!size || size < total_size) - goto out_free_chunks; - put_unaligned_le32(CISS_SG_LAST, &mem_descriptor->flags); put_unaligned_le16(sg_count, &ofap->num_memory_descriptors); - put_unaligned_le32(size, &ofap->bytes_allocated); + put_unaligned_le32(sg_count * chunk_size, &ofap->bytes_allocated); return 0; @@ -8272,82 +8274,87 @@ out_free_chunks: while (--i >= 0) { mem_descriptor = &ofap->sg_descriptor[i]; dma_free_coherent(dev, chunk_size, - ctrl_info->pqi_ofa_chunk_virt_addr[i], - get_unaligned_le64(&mem_descriptor->address)); + ctrl_info->pqi_ofa_chunk_virt_addr[i], + get_unaligned_le64(&mem_descriptor->address)); } kfree(ctrl_info->pqi_ofa_chunk_virt_addr); out: - put_unaligned_le32 (0, &ofap->bytes_allocated); return -ENOMEM; } static int pqi_ofa_alloc_host_buffer(struct pqi_ctrl_info *ctrl_info) { u32 total_size; + u32 chunk_size; u32 min_chunk_size; - u32 chunk_sz; - total_size = le32_to_cpu( - ctrl_info->pqi_ofa_mem_virt_addr->bytes_allocated); - min_chunk_size = total_size / PQI_OFA_MAX_SG_DESCRIPTORS; + if (ctrl_info->ofa_bytes_requested == 0) + return 0; - for (chunk_sz = total_size; chunk_sz >= min_chunk_size; chunk_sz /= 2) - if (!pqi_ofa_alloc_mem(ctrl_info, total_size, chunk_sz)) + total_size = PAGE_ALIGN(ctrl_info->ofa_bytes_requested); + min_chunk_size = DIV_ROUND_UP(total_size, PQI_OFA_MAX_SG_DESCRIPTORS); + min_chunk_size = PAGE_ALIGN(min_chunk_size); + + for (chunk_size = total_size; chunk_size >= min_chunk_size;) { + if (pqi_ofa_alloc_mem(ctrl_info, total_size, chunk_size) == 0) return 0; + chunk_size /= 2; + chunk_size = PAGE_ALIGN(chunk_size); + } return -ENOMEM; } -static void pqi_ofa_setup_host_buffer(struct pqi_ctrl_info *ctrl_info, - u32 bytes_requested) +static void pqi_ofa_setup_host_buffer(struct pqi_ctrl_info *ctrl_info) { - struct pqi_ofa_memory *pqi_ofa_memory; struct device *dev; + struct pqi_ofa_memory *ofap; dev = &ctrl_info->pci_dev->dev; - pqi_ofa_memory = dma_alloc_coherent(dev, - PQI_OFA_MEMORY_DESCRIPTOR_LENGTH, - &ctrl_info->pqi_ofa_mem_dma_handle, - GFP_KERNEL); - if (!pqi_ofa_memory) + ofap = dma_alloc_coherent(dev, sizeof(*ofap), + &ctrl_info->pqi_ofa_mem_dma_handle, GFP_KERNEL); + if (!ofap) return; - put_unaligned_le16(PQI_OFA_VERSION, &pqi_ofa_memory->version); - memcpy(&pqi_ofa_memory->signature, PQI_OFA_SIGNATURE, - sizeof(pqi_ofa_memory->signature)); - pqi_ofa_memory->bytes_allocated = cpu_to_le32(bytes_requested); - - ctrl_info->pqi_ofa_mem_virt_addr = pqi_ofa_memory; + ctrl_info->pqi_ofa_mem_virt_addr = ofap; if (pqi_ofa_alloc_host_buffer(ctrl_info) < 0) { - dev_err(dev, "Failed to allocate host buffer of size = %u", - bytes_requested); + dev_err(dev, + "failed to allocate host buffer for Online Firmware Activation\n"); + dma_free_coherent(dev, sizeof(*ofap), ofap, ctrl_info->pqi_ofa_mem_dma_handle); + ctrl_info->pqi_ofa_mem_virt_addr = NULL; + return; } - return; + put_unaligned_le16(PQI_OFA_VERSION, &ofap->version); + memcpy(&ofap->signature, PQI_OFA_SIGNATURE, sizeof(ofap->signature)); } static void pqi_ofa_free_host_buffer(struct pqi_ctrl_info *ctrl_info) { - int i; - struct pqi_sg_descriptor *mem_descriptor; + unsigned int i; + struct device *dev; struct pqi_ofa_memory *ofap; + struct pqi_sg_descriptor *mem_descriptor; + unsigned int num_memory_descriptors; ofap = ctrl_info->pqi_ofa_mem_virt_addr; - if (!ofap) return; - if (!ofap->bytes_allocated) + dev = &ctrl_info->pci_dev->dev; + + if (get_unaligned_le32(&ofap->bytes_allocated) == 0) goto out; mem_descriptor = ofap->sg_descriptor; + num_memory_descriptors = + get_unaligned_le16(&ofap->num_memory_descriptors); - for (i = 0; i < get_unaligned_le16(&ofap->num_memory_descriptors); - i++) { - dma_free_coherent(&ctrl_info->pci_dev->dev, + for (i = 0; i < num_memory_descriptors; i++) { + dma_free_coherent(dev, get_unaligned_le32(&mem_descriptor[i].length), ctrl_info->pqi_ofa_chunk_virt_addr[i], get_unaligned_le64(&mem_descriptor[i].address)); @@ -8355,46 +8362,45 @@ static void pqi_ofa_free_host_buffer(struct pqi_ctrl_info *ctrl_info) kfree(ctrl_info->pqi_ofa_chunk_virt_addr); out: - dma_free_coherent(&ctrl_info->pci_dev->dev, - PQI_OFA_MEMORY_DESCRIPTOR_LENGTH, ofap, - ctrl_info->pqi_ofa_mem_dma_handle); + dma_free_coherent(dev, sizeof(*ofap), ofap, + ctrl_info->pqi_ofa_mem_dma_handle); ctrl_info->pqi_ofa_mem_virt_addr = NULL; } static int pqi_ofa_host_memory_update(struct pqi_ctrl_info *ctrl_info) { + u32 buffer_length; struct pqi_vendor_general_request request; - size_t size; struct pqi_ofa_memory *ofap; memset(&request, 0, sizeof(request)); - ofap = ctrl_info->pqi_ofa_mem_virt_addr; - request.header.iu_type = PQI_REQUEST_IU_VENDOR_GENERAL; put_unaligned_le16(sizeof(request) - PQI_REQUEST_HEADER_LENGTH, &request.header.iu_length); put_unaligned_le16(PQI_VENDOR_GENERAL_HOST_MEMORY_UPDATE, &request.function_code); + ofap = ctrl_info->pqi_ofa_mem_virt_addr; + if (ofap) { - size = offsetof(struct pqi_ofa_memory, sg_descriptor) + + buffer_length = offsetof(struct pqi_ofa_memory, sg_descriptor) + get_unaligned_le16(&ofap->num_memory_descriptors) * sizeof(struct pqi_sg_descriptor); put_unaligned_le64((u64)ctrl_info->pqi_ofa_mem_dma_handle, &request.data.ofa_memory_allocation.buffer_address); - put_unaligned_le32(size, + put_unaligned_le32(buffer_length, &request.data.ofa_memory_allocation.buffer_length); - } return pqi_submit_raid_request_synchronous(ctrl_info, &request.header, 0, NULL); } -static int pqi_ofa_ctrl_restart(struct pqi_ctrl_info *ctrl_info) +static int pqi_ofa_ctrl_restart(struct pqi_ctrl_info *ctrl_info, unsigned int delay_secs) { - msleep(PQI_POST_RESET_DELAY_B4_MSGU_READY); + ssleep(delay_secs); + return pqi_ctrl_init_resume(ctrl_info); } From 66f1c2b40270b759eb070990ebd5c8f94244360f Mon Sep 17 00:00:00 2001 From: Kevin Barnett Date: Thu, 11 Mar 2021 14:17:01 -0600 Subject: [PATCH 300/412] scsi: smartpqi: Update device scan operations Change return type from EINPROGRESS to EBUSY to signal applications to retry a REGNEWD if the driver cannot process the REGNEWD. Events such as OFA, suspend, and shutdown return EINPROGRESS if a scan is currently running. This prevents applications from immediately retrying REGNEWD. Schedule a new REGNEWD if system low on memory. Link: https://lore.kernel.org/r/161549382157.25025.16054784597622125373.stgit@brunhilda Reviewed-by: Scott Benesh Reviewed-by: Mike McGowen Reviewed-by: Scott Teel Signed-off-by: Kevin Barnett Signed-off-by: Don Brace Signed-off-by: Martin K. Petersen --- drivers/scsi/smartpqi/smartpqi_init.c | 22 ++++++++++++++-------- 1 file changed, 14 insertions(+), 8 deletions(-) diff --git a/drivers/scsi/smartpqi/smartpqi_init.c b/drivers/scsi/smartpqi/smartpqi_init.c index 89b6972a21f6..9f6ab2f4144f 100644 --- a/drivers/scsi/smartpqi/smartpqi_init.c +++ b/drivers/scsi/smartpqi/smartpqi_init.c @@ -2312,21 +2312,27 @@ out: static int pqi_scan_scsi_devices(struct pqi_ctrl_info *ctrl_info) { - int rc = 0; + int rc; + int mutex_acquired; if (pqi_ctrl_offline(ctrl_info)) return -ENXIO; - if (!mutex_trylock(&ctrl_info->scan_mutex)) { + mutex_acquired = mutex_trylock(&ctrl_info->scan_mutex); + + if (!mutex_acquired) { + if (pqi_ctrl_scan_blocked(ctrl_info)) + return -EBUSY; pqi_schedule_rescan_worker_delayed(ctrl_info); - rc = -EINPROGRESS; - } else { - rc = pqi_update_scsi_devices(ctrl_info); - if (rc) - pqi_schedule_rescan_worker_delayed(ctrl_info); - mutex_unlock(&ctrl_info->scan_mutex); + return -EINPROGRESS; } + rc = pqi_update_scsi_devices(ctrl_info); + if (rc && !pqi_ctrl_scan_blocked(ctrl_info)) + pqi_schedule_rescan_worker_delayed(ctrl_info); + + mutex_unlock(&ctrl_info->scan_mutex); + return rc; } From 3268b8a8cf77dbc1f84e9a328069144506636c87 Mon Sep 17 00:00:00 2001 From: Kevin Barnett Date: Thu, 11 Mar 2021 14:17:07 -0600 Subject: [PATCH 301/412] scsi: smartpqi: Fix driver synchronization issues - Synchronize OFA and controller offline events. Prevent I/O during the above conditions. - Cleanup pqi_device_wait_for_pending_io() by checking the device->scsi_cmds_outstanding instead of walking the device's list of commands. - Stop failing all I/O for all devices. This was causing OS to retry them, delaying OFA. - Clean up cache flush. The controller is checked for offline status in lower level functions. Link: https://lore.kernel.org/r/161549382770.25025.789855864026860170.stgit@brunhilda Reviewed-by: Scott Benesh Reviewed-by: Mike McGowen Reviewed-by: Scott Teel Signed-off-by: Kevin Barnett Signed-off-by: Don Brace Signed-off-by: Martin K. Petersen --- drivers/scsi/smartpqi/smartpqi_init.c | 106 +------------------------- 1 file changed, 3 insertions(+), 103 deletions(-) diff --git a/drivers/scsi/smartpqi/smartpqi_init.c b/drivers/scsi/smartpqi/smartpqi_init.c index 9f6ab2f4144f..8b512f39f9d9 100644 --- a/drivers/scsi/smartpqi/smartpqi_init.c +++ b/drivers/scsi/smartpqi/smartpqi_init.c @@ -813,13 +813,6 @@ static int pqi_flush_cache(struct pqi_ctrl_info *ctrl_info, int rc; struct bmic_flush_cache *flush_cache; - /* - * Don't bother trying to flush the cache if the controller is - * locked up. - */ - if (pqi_ctrl_offline(ctrl_info)) - return -ENXIO; - flush_cache = kzalloc(sizeof(*flush_cache), GFP_KERNEL); if (!flush_cache) return -ENOMEM; @@ -998,9 +991,6 @@ static void pqi_update_time_worker(struct work_struct *work) ctrl_info = container_of(to_delayed_work(work), struct pqi_ctrl_info, update_time_work); - if (pqi_ctrl_offline(ctrl_info)) - return; - rc = pqi_write_current_time_to_host_wellness(ctrl_info); if (rc) dev_warn(&ctrl_info->pci_dev->dev, @@ -5725,7 +5715,6 @@ static int pqi_scsi_queue_command(struct Scsi_Host *shost, struct scsi_cmnd *scm } out: - pqi_ctrl_unbusy(ctrl_info); if (rc) atomic_dec(&device->scsi_cmds_outstanding); @@ -5837,49 +5826,12 @@ static void pqi_fail_io_queued_for_device(struct pqi_ctrl_info *ctrl_info, } } -static void pqi_fail_io_queued_for_all_devices(struct pqi_ctrl_info *ctrl_info) -{ - unsigned int i; - unsigned int path; - struct pqi_queue_group *queue_group; - unsigned long flags; - struct pqi_io_request *io_request; - struct pqi_io_request *next; - struct scsi_cmnd *scmd; - - for (i = 0; i < ctrl_info->num_queue_groups; i++) { - queue_group = &ctrl_info->queue_groups[i]; - - for (path = 0; path < 2; path++) { - spin_lock_irqsave(&queue_group->submit_lock[path], - flags); - - list_for_each_entry_safe(io_request, next, - &queue_group->request_list[path], - request_list_entry) { - - scmd = io_request->scmd; - if (!scmd) - continue; - - list_del(&io_request->request_list_entry); - set_host_byte(scmd, DID_RESET); - pqi_free_io_request(io_request); - scsi_dma_unmap(scmd); - pqi_scsi_done(scmd); - } - - spin_unlock_irqrestore( - &queue_group->submit_lock[path], flags); - } - } -} - static int pqi_device_wait_for_pending_io(struct pqi_ctrl_info *ctrl_info, struct pqi_scsi_dev *device, unsigned long timeout_secs) { unsigned long timeout; + timeout = (timeout_secs * PQI_HZ) + jiffies; while (atomic_read(&device->scsi_cmds_outstanding)) { @@ -5889,50 +5841,7 @@ static int pqi_device_wait_for_pending_io(struct pqi_ctrl_info *ctrl_info, if (timeout_secs != NO_TIMEOUT) { if (time_after(jiffies, timeout)) { dev_err(&ctrl_info->pci_dev->dev, - "timed out waiting for pending IO\n"); - return -ETIMEDOUT; - } - } - usleep_range(1000, 2000); - } - - return 0; -} - -static int pqi_ctrl_wait_for_pending_io(struct pqi_ctrl_info *ctrl_info, - unsigned long timeout_secs) -{ - bool io_pending; - unsigned long flags; - unsigned long timeout; - struct pqi_scsi_dev *device; - - timeout = (timeout_secs * PQI_HZ) + jiffies; - while (1) { - io_pending = false; - - spin_lock_irqsave(&ctrl_info->scsi_device_list_lock, flags); - list_for_each_entry(device, &ctrl_info->scsi_device_list, - scsi_device_list_entry) { - if (atomic_read(&device->scsi_cmds_outstanding)) { - io_pending = true; - break; - } - } - spin_unlock_irqrestore(&ctrl_info->scsi_device_list_lock, - flags); - - if (!io_pending) - break; - - pqi_check_ctrl_health(ctrl_info); - if (pqi_ctrl_offline(ctrl_info)) - return -ENXIO; - - if (timeout_secs != NO_TIMEOUT) { - if (time_after(jiffies, timeout)) { - dev_err(&ctrl_info->pci_dev->dev, - "timed out waiting for pending IO\n"); + "timed out waiting for pending I/O\n"); return -ETIMEDOUT; } } @@ -6013,8 +5922,6 @@ static int pqi_lun_reset(struct pqi_ctrl_info *ctrl_info, return rc; } -/* Performs a reset at the LUN level. */ - #define PQI_LUN_RESET_RETRIES 3 #define PQI_LUN_RESET_RETRY_INTERVAL_MSECS 10000 #define PQI_LUN_RESET_PENDING_IO_TIMEOUT_SECS 120 @@ -7659,8 +7566,6 @@ static int pqi_force_sis_mode(struct pqi_ctrl_info *ctrl_info) return pqi_revert_to_sis_mode(ctrl_info); } -#define PQI_POST_RESET_DELAY_B4_MSGU_READY 5000 - static int pqi_ctrl_init(struct pqi_ctrl_info *ctrl_info) { int rc; @@ -7668,7 +7573,7 @@ static int pqi_ctrl_init(struct pqi_ctrl_info *ctrl_info) if (reset_devices) { sis_soft_reset(ctrl_info); - msleep(PQI_POST_RESET_DELAY_B4_MSGU_READY); + msleep(PQI_POST_RESET_DELAY_SECS * PQI_HZ); } else { rc = pqi_force_sis_mode(ctrl_info); if (rc) @@ -8222,12 +8127,7 @@ static void pqi_ofa_ctrl_quiesce(struct pqi_ctrl_info *ctrl_info) pqi_ctrl_block_device_reset(ctrl_info); pqi_ctrl_block_requests(ctrl_info); pqi_ctrl_wait_until_quiesced(ctrl_info); - pqi_ctrl_wait_for_pending_io(ctrl_info, PQI_PENDING_IO_TIMEOUT_SECS); - pqi_fail_io_queued_for_all_devices(ctrl_info); - pqi_wait_until_inbound_queues_empty(ctrl_info); pqi_stop_heartbeat_timer(ctrl_info); - ctrl_info->pqi_mode_enabled = false; - pqi_save_ctrl_mode(ctrl_info, SIS_MODE); } static void pqi_ofa_ctrl_unquiesce(struct pqi_ctrl_info *ctrl_info) From a425625277a10dcb039ac05b90202d4f54f824ad Mon Sep 17 00:00:00 2001 From: Kevin Barnett Date: Thu, 11 Mar 2021 14:17:13 -0600 Subject: [PATCH 302/412] scsi: smartpqi: Convert snprintf() to scnprintf() The entire Linux kernel has been slowly migrating from snprintf() to scnprintf(), so we are doing our part. This article explains the rationale for this change: https: //lwn.net/Articles/69419/ Link: https://lore.kernel.org/r/161549383357.25025.12363435617789964291.stgit@brunhilda Reviewed-by: Scott Benesh Reviewed-by: Mike McGowen Reviewed-by: Scott Teel Reviewed-by: Martin Wilck Signed-off-by: Kevin Barnett Signed-off-by: Don Brace Signed-off-by: Martin K. Petersen --- drivers/scsi/smartpqi/smartpqi_init.c | 23 +++++++++++------------ 1 file changed, 11 insertions(+), 12 deletions(-) diff --git a/drivers/scsi/smartpqi/smartpqi_init.c b/drivers/scsi/smartpqi/smartpqi_init.c index 8b512f39f9d9..761d7ec6d2b2 100644 --- a/drivers/scsi/smartpqi/smartpqi_init.c +++ b/drivers/scsi/smartpqi/smartpqi_init.c @@ -1749,7 +1749,7 @@ static void pqi_dev_info(struct pqi_ctrl_info *ctrl_info, ssize_t count; char buffer[PQI_DEV_INFO_BUFFER_LENGTH]; - count = snprintf(buffer, PQI_DEV_INFO_BUFFER_LENGTH, + count = scnprintf(buffer, PQI_DEV_INFO_BUFFER_LENGTH, "%d:%d:", ctrl_info->scsi_host->host_no, device->bus); if (device->target_lun_valid) @@ -6382,14 +6382,13 @@ static ssize_t pqi_firmware_version_show(struct device *dev, shost = class_to_shost(dev); ctrl_info = shost_to_hba(shost); - return snprintf(buffer, PAGE_SIZE, "%s\n", ctrl_info->firmware_version); + return scnprintf(buffer, PAGE_SIZE, "%s\n", ctrl_info->firmware_version); } static ssize_t pqi_driver_version_show(struct device *dev, struct device_attribute *attr, char *buffer) { - return snprintf(buffer, PAGE_SIZE, "%s\n", - DRIVER_VERSION BUILD_TIMESTAMP); + return scnprintf(buffer, PAGE_SIZE, "%s\n", DRIVER_VERSION BUILD_TIMESTAMP); } static ssize_t pqi_serial_number_show(struct device *dev, @@ -6401,7 +6400,7 @@ static ssize_t pqi_serial_number_show(struct device *dev, shost = class_to_shost(dev); ctrl_info = shost_to_hba(shost); - return snprintf(buffer, PAGE_SIZE, "%s\n", ctrl_info->serial_number); + return scnprintf(buffer, PAGE_SIZE, "%s\n", ctrl_info->serial_number); } static ssize_t pqi_model_show(struct device *dev, @@ -6413,7 +6412,7 @@ static ssize_t pqi_model_show(struct device *dev, shost = class_to_shost(dev); ctrl_info = shost_to_hba(shost); - return snprintf(buffer, PAGE_SIZE, "%s\n", ctrl_info->model); + return scnprintf(buffer, PAGE_SIZE, "%s\n", ctrl_info->model); } static ssize_t pqi_vendor_show(struct device *dev, @@ -6425,7 +6424,7 @@ static ssize_t pqi_vendor_show(struct device *dev, shost = class_to_shost(dev); ctrl_info = shost_to_hba(shost); - return snprintf(buffer, PAGE_SIZE, "%s\n", ctrl_info->vendor); + return scnprintf(buffer, PAGE_SIZE, "%s\n", ctrl_info->vendor); } static ssize_t pqi_host_rescan_store(struct device *dev, @@ -6619,7 +6618,7 @@ static ssize_t pqi_unique_id_show(struct device *dev, spin_unlock_irqrestore(&ctrl_info->scsi_device_list_lock, flags); - return snprintf(buffer, PAGE_SIZE, + return scnprintf(buffer, PAGE_SIZE, "%02X%02X%02X%02X%02X%02X%02X%02X" "%02X%02X%02X%02X%02X%02X%02X%02X\n", unique_id[0], unique_id[1], unique_id[2], unique_id[3], @@ -6652,7 +6651,7 @@ static ssize_t pqi_lunid_show(struct device *dev, spin_unlock_irqrestore(&ctrl_info->scsi_device_list_lock, flags); - return snprintf(buffer, PAGE_SIZE, "0x%8phN\n", lunid); + return scnprintf(buffer, PAGE_SIZE, "0x%8phN\n", lunid); } #define MAX_PATHS 8 @@ -6764,7 +6763,7 @@ static ssize_t pqi_sas_address_show(struct device *dev, spin_unlock_irqrestore(&ctrl_info->scsi_device_list_lock, flags); - return snprintf(buffer, PAGE_SIZE, "0x%016llx\n", sas_address); + return scnprintf(buffer, PAGE_SIZE, "0x%016llx\n", sas_address); } static ssize_t pqi_ssd_smart_path_enabled_show(struct device *dev, @@ -6822,7 +6821,7 @@ static ssize_t pqi_raid_level_show(struct device *dev, spin_unlock_irqrestore(&ctrl_info->scsi_device_list_lock, flags); - return snprintf(buffer, PAGE_SIZE, "%s\n", raid_level); + return scnprintf(buffer, PAGE_SIZE, "%s\n", raid_level); } static ssize_t pqi_raid_bypass_cnt_show(struct device *dev, @@ -6849,7 +6848,7 @@ static ssize_t pqi_raid_bypass_cnt_show(struct device *dev, spin_unlock_irqrestore(&ctrl_info->scsi_device_list_lock, flags); - return snprintf(buffer, PAGE_SIZE, "0x%x\n", raid_bypass_cnt); + return scnprintf(buffer, PAGE_SIZE, "0x%x\n", raid_bypass_cnt); } static DEVICE_ATTR(lunid, 0444, pqi_lunid_show, NULL); From ec504b23df9d33260602affc50389cf070707c9b Mon Sep 17 00:00:00 2001 From: Murthy Bhat Date: Thu, 11 Mar 2021 14:17:19 -0600 Subject: [PATCH 303/412] scsi: smartpqi: Add phy ID support for the physical drives Display topology using PHY numbers. PHY (both local and remote) numbers corresponding to physical drives are read from BMIC_IDENTIFY_PHYSICAL_DEVICE. Link: https://lore.kernel.org/r/161549383947.25025.16977895345376485056.stgit@brunhilda Reviewed-by: Scott Benesh Reviewed-by: Mike McGowen Reviewed-by: Scott Teel Reviewed-by: Kevin Barnett Reviewed-by: Martin Wilck Signed-off-by: Murthy Bhat Signed-off-by: Don Brace Signed-off-by: Martin K. Petersen --- drivers/scsi/smartpqi/smartpqi.h | 1 + drivers/scsi/smartpqi/smartpqi_init.c | 10 ++++++++++ drivers/scsi/smartpqi/smartpqi_sas_transport.c | 1 + 3 files changed, 12 insertions(+) diff --git a/drivers/scsi/smartpqi/smartpqi.h b/drivers/scsi/smartpqi/smartpqi.h index 0b94c755a74c..d7dac5572274 100644 --- a/drivers/scsi/smartpqi/smartpqi.h +++ b/drivers/scsi/smartpqi/smartpqi.h @@ -1089,6 +1089,7 @@ struct pqi_scsi_dev { u8 phy_connected_dev_type; u8 box[8]; u16 phys_connector[8]; + u8 phy_id; bool raid_bypass_configured; /* RAID bypass configured */ bool raid_bypass_enabled; /* RAID bypass enabled */ u32 next_bypass_group; diff --git a/drivers/scsi/smartpqi/smartpqi_init.c b/drivers/scsi/smartpqi/smartpqi_init.c index 761d7ec6d2b2..0e433223aea4 100644 --- a/drivers/scsi/smartpqi/smartpqi_init.c +++ b/drivers/scsi/smartpqi/smartpqi_init.c @@ -1434,6 +1434,8 @@ no_buffer: device->volume_offline = volume_offline; } +#define PQI_DEVICE_PHY_MAP_SUPPORTED 0x10 + static int pqi_get_physical_device_info(struct pqi_ctrl_info *ctrl_info, struct pqi_scsi_dev *device, struct bmic_identify_physical_device *id_phys) @@ -1473,6 +1475,13 @@ static int pqi_get_physical_device_info(struct pqi_ctrl_info *ctrl_info, memcpy(&device->page_83_identifier, &id_phys->page_83_identifier, sizeof(device->page_83_identifier)); + if ((id_phys->even_more_flags & PQI_DEVICE_PHY_MAP_SUPPORTED) && + id_phys->phy_count) + device->phy_id = + id_phys->phy_to_phy_map[device->active_path_index]; + else + device->phy_id = 0xFF; + return 0; } @@ -1839,6 +1848,7 @@ static void pqi_scsi_update_device(struct pqi_scsi_dev *existing_device, existing_device->aio_handle = new_device->aio_handle; existing_device->volume_status = new_device->volume_status; existing_device->active_path_index = new_device->active_path_index; + existing_device->phy_id = new_device->phy_id; existing_device->path_map = new_device->path_map; existing_device->bay = new_device->bay; existing_device->box_index = new_device->box_index; diff --git a/drivers/scsi/smartpqi/smartpqi_sas_transport.c b/drivers/scsi/smartpqi/smartpqi_sas_transport.c index 77923c6ec2c6..71e83d5fdd02 100644 --- a/drivers/scsi/smartpqi/smartpqi_sas_transport.c +++ b/drivers/scsi/smartpqi/smartpqi_sas_transport.c @@ -92,6 +92,7 @@ static int pqi_sas_port_add_rphy(struct pqi_sas_port *pqi_sas_port, identify = &rphy->identify; identify->sas_address = pqi_sas_port->sas_address; + identify->phy_identifier = pqi_sas_port->device->phy_id; if (pqi_sas_port->device && pqi_sas_port->device->is_expander_smp_device) { From 55732a46d6c5289fb555bbdbff9c7222efd983c1 Mon Sep 17 00:00:00 2001 From: Murthy Bhat Date: Thu, 11 Mar 2021 14:17:25 -0600 Subject: [PATCH 304/412] scsi: smartpqi: Update SAS initiator_port_protocols and target_port_protocols Export valid sas initiator_port_protocols and target_port_protocols to sysfs. Needed for lsscsi to show correct values. Link: https://lore.kernel.org/r/161549384532.25025.1469409935400845385.stgit@brunhilda Reviewed-by: Scott Benesh Reviewed-by: Mike McGowen Reviewed-by: Scott Teel Reviewed-by: Kevin Barnett Reviewed-by: Martin Wilck Signed-off-by: Murthy Bhat Signed-off-by: Don Brace Signed-off-by: Martin K. Petersen --- .../scsi/smartpqi/smartpqi_sas_transport.c | 28 +++++++++++++------ 1 file changed, 19 insertions(+), 9 deletions(-) diff --git a/drivers/scsi/smartpqi/smartpqi_sas_transport.c b/drivers/scsi/smartpqi/smartpqi_sas_transport.c index 71e83d5fdd02..dd9b784792ef 100644 --- a/drivers/scsi/smartpqi/smartpqi_sas_transport.c +++ b/drivers/scsi/smartpqi/smartpqi_sas_transport.c @@ -65,8 +65,8 @@ static int pqi_sas_port_add_phy(struct pqi_sas_phy *pqi_sas_phy) memset(identify, 0, sizeof(*identify)); identify->sas_address = pqi_sas_port->sas_address; identify->device_type = SAS_END_DEVICE; - identify->initiator_port_protocols = SAS_PROTOCOL_STP; - identify->target_port_protocols = SAS_PROTOCOL_STP; + identify->initiator_port_protocols = SAS_PROTOCOL_ALL; + identify->target_port_protocols = SAS_PROTOCOL_ALL; phy->minimum_linkrate_hw = SAS_LINK_RATE_UNKNOWN; phy->maximum_linkrate_hw = SAS_LINK_RATE_UNKNOWN; phy->minimum_linkrate = SAS_LINK_RATE_UNKNOWN; @@ -94,13 +94,23 @@ static int pqi_sas_port_add_rphy(struct pqi_sas_port *pqi_sas_port, identify->sas_address = pqi_sas_port->sas_address; identify->phy_identifier = pqi_sas_port->device->phy_id; - if (pqi_sas_port->device && - pqi_sas_port->device->is_expander_smp_device) { - identify->initiator_port_protocols = SAS_PROTOCOL_SMP; - identify->target_port_protocols = SAS_PROTOCOL_SMP; - } else { - identify->initiator_port_protocols = SAS_PROTOCOL_STP; - identify->target_port_protocols = SAS_PROTOCOL_STP; + identify->initiator_port_protocols = SAS_PROTOCOL_ALL; + identify->target_port_protocols = SAS_PROTOCOL_STP; + + if (pqi_sas_port->device) { + switch (pqi_sas_port->device->device_type) { + case SA_DEVICE_TYPE_SAS: + case SA_DEVICE_TYPE_SES: + case SA_DEVICE_TYPE_NVME: + identify->target_port_protocols = SAS_PROTOCOL_SSP; + break; + case SA_DEVICE_TYPE_EXPANDER_SMP: + identify->target_port_protocols = SAS_PROTOCOL_SMP; + break; + case SA_DEVICE_TYPE_SATA: + default: + break; + } } return sas_rphy_add(rphy); From 18ff5f0877be9bf45079691939d2ff7af6e437ae Mon Sep 17 00:00:00 2001 From: Kevin Barnett Date: Thu, 11 Mar 2021 14:17:31 -0600 Subject: [PATCH 305/412] scsi: smartpqi: Add additional logging for LUN resets LUN resets can take longer to complete. Adding in more driver logging helps show where the driver is in the reset process. Add a timeout in pqi_device_wait_for_pending_io() to cap how long the driver will wait for outstanding commands. Link: https://lore.kernel.org/r/161549385119.25025.10366493975709358647.stgit@brunhilda Reviewed-by: Mahesh Rajashekhara Reviewed-by: Scott Benesh Reviewed-by: Mike McGowen Reviewed-by: Scott Teel Signed-off-by: Kevin Barnett Signed-off-by: Don Brace Signed-off-by: Martin K. Petersen --- drivers/scsi/smartpqi/smartpqi_init.c | 125 ++++++++++++++++++-------- 1 file changed, 89 insertions(+), 36 deletions(-) diff --git a/drivers/scsi/smartpqi/smartpqi_init.c b/drivers/scsi/smartpqi/smartpqi_init.c index 0e433223aea4..91616ddafd17 100644 --- a/drivers/scsi/smartpqi/smartpqi_init.c +++ b/drivers/scsi/smartpqi/smartpqi_init.c @@ -84,7 +84,7 @@ static void pqi_ofa_setup_host_buffer(struct pqi_ctrl_info *ctrl_info); static void pqi_ofa_free_host_buffer(struct pqi_ctrl_info *ctrl_info); static int pqi_ofa_host_memory_update(struct pqi_ctrl_info *ctrl_info); static int pqi_device_wait_for_pending_io(struct pqi_ctrl_info *ctrl_info, - struct pqi_scsi_dev *device, unsigned long timeout_secs); + struct pqi_scsi_dev *device, unsigned long timeout_msecs); /* for flags argument to pqi_submit_raid_request_synchronous() */ #define PQI_SYNC_FLAGS_INTERRUPTABLE 0x1 @@ -335,11 +335,34 @@ static void pqi_wait_if_ctrl_blocked(struct pqi_ctrl_info *ctrl_info) atomic_dec(&ctrl_info->num_blocked_threads); } +#define PQI_QUIESCE_WARNING_TIMEOUT_SECS 10 + static inline void pqi_ctrl_wait_until_quiesced(struct pqi_ctrl_info *ctrl_info) { + unsigned long start_jiffies; + unsigned long warning_timeout; + bool displayed_warning; + + displayed_warning = false; + start_jiffies = jiffies; + warning_timeout = (PQI_QUIESCE_WARNING_TIMEOUT_SECS * PQI_HZ) + start_jiffies; + while (atomic_read(&ctrl_info->num_busy_threads) > - atomic_read(&ctrl_info->num_blocked_threads)) + atomic_read(&ctrl_info->num_blocked_threads)) { + if (time_after(jiffies, warning_timeout)) { + dev_warn(&ctrl_info->pci_dev->dev, + "waiting %u seconds for driver activity to quiesce\n", + jiffies_to_msecs(jiffies - start_jiffies) / 1000); + displayed_warning = true; + warning_timeout = (PQI_QUIESCE_WARNING_TIMEOUT_SECS * PQI_HZ) + jiffies; + } usleep_range(1000, 2000); + } + + if (displayed_warning) + dev_warn(&ctrl_info->pci_dev->dev, + "driver activity quiesced after waiting for %u seconds\n", + jiffies_to_msecs(jiffies - start_jiffies) / 1000); } static inline bool pqi_device_offline(struct pqi_scsi_dev *device) @@ -1669,7 +1692,7 @@ static int pqi_add_device(struct pqi_ctrl_info *ctrl_info, return rc; } -#define PQI_PENDING_IO_TIMEOUT_SECS 20 +#define PQI_REMOVE_DEVICE_PENDING_IO_TIMEOUT_MSECS (20 * 1000) static inline void pqi_remove_device(struct pqi_ctrl_info *ctrl_info, struct pqi_scsi_dev *device) { @@ -1677,7 +1700,8 @@ static inline void pqi_remove_device(struct pqi_ctrl_info *ctrl_info, struct pqi pqi_device_remove_start(device); - rc = pqi_device_wait_for_pending_io(ctrl_info, device, PQI_PENDING_IO_TIMEOUT_SECS); + rc = pqi_device_wait_for_pending_io(ctrl_info, device, + PQI_REMOVE_DEVICE_PENDING_IO_TIMEOUT_MSECS); if (rc) dev_err(&ctrl_info->pci_dev->dev, "scsi %d:%d:%d:%d removing device with %d outstanding command(s)\n", @@ -3086,7 +3110,7 @@ static void pqi_process_io_error(unsigned int iu_type, } } -static int pqi_interpret_task_management_response( +static int pqi_interpret_task_management_response(struct pqi_ctrl_info *ctrl_info, struct pqi_task_management_response *response) { int rc; @@ -3104,6 +3128,10 @@ static int pqi_interpret_task_management_response( break; } + if (rc) + dev_err(&ctrl_info->pci_dev->dev, + "Task Management Function error: %d (response code: %u)\n", rc, response->response_code); + return rc; } @@ -3172,9 +3200,8 @@ static int pqi_process_io_intr(struct pqi_ctrl_info *ctrl_info, struct pqi_queue &((struct pqi_vendor_general_response *)response)->status); break; case PQI_RESPONSE_IU_TASK_MANAGEMENT: - io_request->status = - pqi_interpret_task_management_response( - (void *)response); + io_request->status = pqi_interpret_task_management_response(ctrl_info, + (void *)response); break; case PQI_RESPONSE_IU_AIO_PATH_DISABLED: pqi_aio_path_disabled(io_request); @@ -5836,24 +5863,37 @@ static void pqi_fail_io_queued_for_device(struct pqi_ctrl_info *ctrl_info, } } +#define PQI_PENDING_IO_WARNING_TIMEOUT_SECS 10 + static int pqi_device_wait_for_pending_io(struct pqi_ctrl_info *ctrl_info, - struct pqi_scsi_dev *device, unsigned long timeout_secs) + struct pqi_scsi_dev *device, unsigned long timeout_msecs) { - unsigned long timeout; + int cmds_outstanding; + unsigned long start_jiffies; + unsigned long warning_timeout; + unsigned long msecs_waiting; + start_jiffies = jiffies; + warning_timeout = (PQI_PENDING_IO_WARNING_TIMEOUT_SECS * PQI_HZ) + start_jiffies; - timeout = (timeout_secs * PQI_HZ) + jiffies; - - while (atomic_read(&device->scsi_cmds_outstanding)) { + while ((cmds_outstanding = atomic_read(&device->scsi_cmds_outstanding)) > 0) { pqi_check_ctrl_health(ctrl_info); if (pqi_ctrl_offline(ctrl_info)) return -ENXIO; - if (timeout_secs != NO_TIMEOUT) { - if (time_after(jiffies, timeout)) { - dev_err(&ctrl_info->pci_dev->dev, - "timed out waiting for pending I/O\n"); - return -ETIMEDOUT; - } + msecs_waiting = jiffies_to_msecs(jiffies - start_jiffies); + if (msecs_waiting > timeout_msecs) { + dev_err(&ctrl_info->pci_dev->dev, + "scsi %d:%d:%d:%d: timed out after %lu seconds waiting for %d outstanding command(s)\n", + ctrl_info->scsi_host->host_no, device->bus, device->target, + device->lun, msecs_waiting / 1000, cmds_outstanding); + return -ETIMEDOUT; + } + if (time_after(jiffies, warning_timeout)) { + dev_warn(&ctrl_info->pci_dev->dev, + "scsi %d:%d:%d:%d: waiting %lu seconds for %d outstanding command(s)\n", + ctrl_info->scsi_host->host_no, device->bus, device->target, + device->lun, msecs_waiting / 1000, cmds_outstanding); + warning_timeout = (PQI_PENDING_IO_WARNING_TIMEOUT_SECS * PQI_HZ) + jiffies; } usleep_range(1000, 2000); } @@ -5869,13 +5909,15 @@ static void pqi_lun_reset_complete(struct pqi_io_request *io_request, complete(waiting); } -#define PQI_LUN_RESET_TIMEOUT_SECS 30 #define PQI_LUN_RESET_POLL_COMPLETION_SECS 10 static int pqi_wait_for_lun_reset_completion(struct pqi_ctrl_info *ctrl_info, struct pqi_scsi_dev *device, struct completion *wait) { int rc; + unsigned int wait_secs; + + wait_secs = 0; while (1) { if (wait_for_completion_io_timeout(wait, @@ -5889,13 +5931,21 @@ static int pqi_wait_for_lun_reset_completion(struct pqi_ctrl_info *ctrl_info, rc = -ENXIO; break; } + + wait_secs += PQI_LUN_RESET_POLL_COMPLETION_SECS; + + dev_warn(&ctrl_info->pci_dev->dev, + "scsi %d:%d:%d:%d: waiting %u seconds for LUN reset to complete\n", + ctrl_info->scsi_host->host_no, device->bus, device->target, device->lun, + wait_secs); } return rc; } -static int pqi_lun_reset(struct pqi_ctrl_info *ctrl_info, - struct pqi_scsi_dev *device) +#define PQI_LUN_RESET_FIRMWARE_TIMEOUT_SECS 30 + +static int pqi_lun_reset(struct pqi_ctrl_info *ctrl_info, struct pqi_scsi_dev *device) { int rc; struct pqi_io_request *io_request; @@ -5917,8 +5967,7 @@ static int pqi_lun_reset(struct pqi_ctrl_info *ctrl_info, sizeof(request->lun_number)); request->task_management_function = SOP_TASK_MANAGEMENT_LUN_RESET; if (ctrl_info->tmf_iu_timeout_supported) - put_unaligned_le16(PQI_LUN_RESET_TIMEOUT_SECS, - &request->timeout); + put_unaligned_le16(PQI_LUN_RESET_FIRMWARE_TIMEOUT_SECS, &request->timeout); pqi_start_io(ctrl_info, &ctrl_info->queue_groups[PQI_DEFAULT_QUEUE_GROUP], RAID_PATH, io_request); @@ -5932,29 +5981,33 @@ static int pqi_lun_reset(struct pqi_ctrl_info *ctrl_info, return rc; } -#define PQI_LUN_RESET_RETRIES 3 -#define PQI_LUN_RESET_RETRY_INTERVAL_MSECS 10000 -#define PQI_LUN_RESET_PENDING_IO_TIMEOUT_SECS 120 +#define PQI_LUN_RESET_RETRIES 3 +#define PQI_LUN_RESET_RETRY_INTERVAL_MSECS (10 * 1000) +#define PQI_LUN_RESET_PENDING_IO_TIMEOUT_MSECS (10 * 60 * 1000) +#define PQI_LUN_RESET_FAILED_PENDING_IO_TIMEOUT_MSECS (2 * 60 * 1000) -static int pqi_lun_reset_with_retries(struct pqi_ctrl_info *ctrl_info, - struct pqi_scsi_dev *device) +static int pqi_lun_reset_with_retries(struct pqi_ctrl_info *ctrl_info, struct pqi_scsi_dev *device) { - int rc; + int reset_rc; + int wait_rc; unsigned int retries; - unsigned long timeout_secs; + unsigned long timeout_msecs; for (retries = 0;;) { - rc = pqi_lun_reset(ctrl_info, device); - if (rc == 0 || ++retries > PQI_LUN_RESET_RETRIES) + reset_rc = pqi_lun_reset(ctrl_info, device); + if (reset_rc == 0 || ++retries > PQI_LUN_RESET_RETRIES) break; msleep(PQI_LUN_RESET_RETRY_INTERVAL_MSECS); } - timeout_secs = rc ? PQI_LUN_RESET_PENDING_IO_TIMEOUT_SECS : NO_TIMEOUT; + timeout_msecs = reset_rc ? PQI_LUN_RESET_FAILED_PENDING_IO_TIMEOUT_MSECS : + PQI_LUN_RESET_PENDING_IO_TIMEOUT_MSECS; - rc |= pqi_device_wait_for_pending_io(ctrl_info, device, timeout_secs); + wait_rc = pqi_device_wait_for_pending_io(ctrl_info, device, timeout_msecs); + if (wait_rc && reset_rc == 0) + reset_rc = wait_rc; - return rc == 0 ? SUCCESS : FAILED; + return reset_rc == 0 ? SUCCESS : FAILED; } static int pqi_device_reset(struct pqi_ctrl_info *ctrl_info, From d0cba99fd7a3781a78f751cfd4f4e3ff4d0b1ea3 Mon Sep 17 00:00:00 2001 From: Murthy Bhat Date: Thu, 11 Mar 2021 14:17:37 -0600 Subject: [PATCH 306/412] scsi: smartpqi: Update enclosure identifier in sysfs Update enclosure identifier field corresponding to physical devices in lsscsi/sysfs. During device add the SCSI devtype is filled in during slave_configure(). However, when pqi_scsi_update_device() runs (REGNEWD) the firmware returns zero for the SCSI devtype field, and valid devtype is overwritten by zero. Due to this, lsscsi output shows wrong values. Link: https://lore.kernel.org/r/161549385708.25025.17234953506918043750.stgit@brunhilda Reviewed-by: Scott Benesh Reviewed-by: Mike McGowen Reviewed-by: Scott Teel Reviewed-by: Kevin Barnett Signed-off-by: Murthy Bhat Signed-off-by: Don Brace Signed-off-by: Martin K. Petersen --- drivers/scsi/smartpqi/smartpqi_init.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/scsi/smartpqi/smartpqi_init.c b/drivers/scsi/smartpqi/smartpqi_init.c index 91616ddafd17..dbc0d3732d85 100644 --- a/drivers/scsi/smartpqi/smartpqi_init.c +++ b/drivers/scsi/smartpqi/smartpqi_init.c @@ -1840,7 +1840,6 @@ static void pqi_dev_info(struct pqi_ctrl_info *ctrl_info, static void pqi_scsi_update_device(struct pqi_scsi_dev *existing_device, struct pqi_scsi_dev *new_device) { - existing_device->devtype = new_device->devtype; existing_device->device_type = new_device->device_type; existing_device->bus = new_device->bus; if (new_device->target_lun_valid) { From 43e97ef482eea96698af5cde99c9d55bbefe225d Mon Sep 17 00:00:00 2001 From: Kevin Barnett Date: Thu, 11 Mar 2021 14:17:42 -0600 Subject: [PATCH 307/412] scsi: smartpqi: Correct system hangs when resuming from hibernation Correct system hangs when resuming from hibernation after first successful hibernation/resume cycle. Rare condition involving OFA. Note: Suspend/resume is not supported on many platforms. It was originally intended for workstations. Link: https://lore.kernel.org/r/161549386295.25025.14555840632114761610.stgit@brunhilda Reviewed-by: Scott Benesh Reviewed-by: Scott Teel Signed-off-by: Kevin Barnett Signed-off-by: Don Brace Signed-off-by: Martin K. Petersen --- drivers/scsi/smartpqi/smartpqi_init.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/drivers/scsi/smartpqi/smartpqi_init.c b/drivers/scsi/smartpqi/smartpqi_init.c index dbc0d3732d85..939da70058a0 100644 --- a/drivers/scsi/smartpqi/smartpqi_init.c +++ b/drivers/scsi/smartpqi/smartpqi_init.c @@ -8651,14 +8651,21 @@ static __maybe_unused int pqi_resume(struct pci_dev *pci_dev) pci_dev->irq, rc); return rc; } + pqi_ctrl_unblock_device_reset(ctrl_info); pqi_ctrl_unblock_requests(ctrl_info); pqi_scsi_unblock_requests(ctrl_info); + pqi_ctrl_unblock_scan(ctrl_info); return 0; } pci_set_power_state(pci_dev, PCI_D0); pci_restore_state(pci_dev); + pqi_ctrl_unblock_device_reset(ctrl_info); + pqi_ctrl_unblock_requests(ctrl_info); + pqi_scsi_unblock_requests(ctrl_info); + pqi_ctrl_unblock_scan(ctrl_info); + return pqi_ctrl_init_resume(ctrl_info); } From 75fbeacca3ad30835e903002dba98dd909b4dfff Mon Sep 17 00:00:00 2001 From: Kevin Barnett Date: Thu, 11 Mar 2021 14:17:48 -0600 Subject: [PATCH 308/412] scsi: smartpqi: Add new PCI IDs Add support for newer hardware. Link: https://lore.kernel.org/r/161549386882.25025.2594251735886014958.stgit@brunhilda Reviewed-by: Scott Benesh Reviewed-by: Scott Teel Acked-by: Martin Wilck Signed-off-by: Kevin Barnett Signed-off-by: Don Brace Signed-off-by: Martin K. Petersen --- drivers/scsi/smartpqi/smartpqi_init.c | 156 ++++++++++++++++++++++++++ 1 file changed, 156 insertions(+) diff --git a/drivers/scsi/smartpqi/smartpqi_init.c b/drivers/scsi/smartpqi/smartpqi_init.c index 939da70058a0..99c24599b2c8 100644 --- a/drivers/scsi/smartpqi/smartpqi_init.c +++ b/drivers/scsi/smartpqi/smartpqi_init.c @@ -8699,6 +8699,10 @@ static const struct pci_device_id pqi_pci_id_table[] = { PCI_DEVICE_SUB(PCI_VENDOR_ID_ADAPTEC2, 0x028f, 0x152d, 0x8a37) }, + { + PCI_DEVICE_SUB(PCI_VENDOR_ID_ADAPTEC2, 0x028f, + 0x193d, 0x8460) + }, { PCI_DEVICE_SUB(PCI_VENDOR_ID_ADAPTEC2, 0x028f, 0x193d, 0x1104) @@ -8771,6 +8775,22 @@ static const struct pci_device_id pqi_pci_id_table[] = { PCI_DEVICE_SUB(PCI_VENDOR_ID_ADAPTEC2, 0x028f, 0x1bd4, 0x004f) }, + { + PCI_DEVICE_SUB(PCI_VENDOR_ID_ADAPTEC2, 0x028f, + 0x1bd4, 0x0051) + }, + { + PCI_DEVICE_SUB(PCI_VENDOR_ID_ADAPTEC2, 0x028f, + 0x1bd4, 0x0052) + }, + { + PCI_DEVICE_SUB(PCI_VENDOR_ID_ADAPTEC2, 0x028f, + 0x1bd4, 0x0053) + }, + { + PCI_DEVICE_SUB(PCI_VENDOR_ID_ADAPTEC2, 0x028f, + 0x1bd4, 0x0054) + }, { PCI_DEVICE_SUB(PCI_VENDOR_ID_ADAPTEC2, 0x028f, 0x19e5, 0xd227) @@ -8931,6 +8951,122 @@ static const struct pci_device_id pqi_pci_id_table[] = { PCI_DEVICE_SUB(PCI_VENDOR_ID_ADAPTEC2, 0x028f, PCI_VENDOR_ID_ADAPTEC2, 0x1380) }, + { + PCI_DEVICE_SUB(PCI_VENDOR_ID_ADAPTEC2, 0x028f, + PCI_VENDOR_ID_ADAPTEC2, 0x1400) + }, + { + PCI_DEVICE_SUB(PCI_VENDOR_ID_ADAPTEC2, 0x028f, + PCI_VENDOR_ID_ADAPTEC2, 0x1402) + }, + { + PCI_DEVICE_SUB(PCI_VENDOR_ID_ADAPTEC2, 0x028f, + PCI_VENDOR_ID_ADAPTEC2, 0x1410) + }, + { + PCI_DEVICE_SUB(PCI_VENDOR_ID_ADAPTEC2, 0x028f, + PCI_VENDOR_ID_ADAPTEC2, 0x1411) + }, + { + PCI_DEVICE_SUB(PCI_VENDOR_ID_ADAPTEC2, 0x028f, + PCI_VENDOR_ID_ADAPTEC2, 0x1412) + }, + { + PCI_DEVICE_SUB(PCI_VENDOR_ID_ADAPTEC2, 0x028f, + PCI_VENDOR_ID_ADAPTEC2, 0x1420) + }, + { + PCI_DEVICE_SUB(PCI_VENDOR_ID_ADAPTEC2, 0x028f, + PCI_VENDOR_ID_ADAPTEC2, 0x1430) + }, + { + PCI_DEVICE_SUB(PCI_VENDOR_ID_ADAPTEC2, 0x028f, + PCI_VENDOR_ID_ADAPTEC2, 0x1440) + }, + { + PCI_DEVICE_SUB(PCI_VENDOR_ID_ADAPTEC2, 0x028f, + PCI_VENDOR_ID_ADAPTEC2, 0x1441) + }, + { + PCI_DEVICE_SUB(PCI_VENDOR_ID_ADAPTEC2, 0x028f, + PCI_VENDOR_ID_ADAPTEC2, 0x1450) + }, + { + PCI_DEVICE_SUB(PCI_VENDOR_ID_ADAPTEC2, 0x028f, + PCI_VENDOR_ID_ADAPTEC2, 0x1452) + }, + { + PCI_DEVICE_SUB(PCI_VENDOR_ID_ADAPTEC2, 0x028f, + PCI_VENDOR_ID_ADAPTEC2, 0x1460) + }, + { + PCI_DEVICE_SUB(PCI_VENDOR_ID_ADAPTEC2, 0x028f, + PCI_VENDOR_ID_ADAPTEC2, 0x1461) + }, + { + PCI_DEVICE_SUB(PCI_VENDOR_ID_ADAPTEC2, 0x028f, + PCI_VENDOR_ID_ADAPTEC2, 0x1462) + }, + { + PCI_DEVICE_SUB(PCI_VENDOR_ID_ADAPTEC2, 0x028f, + PCI_VENDOR_ID_ADAPTEC2, 0x1470) + }, + { + PCI_DEVICE_SUB(PCI_VENDOR_ID_ADAPTEC2, 0x028f, + PCI_VENDOR_ID_ADAPTEC2, 0x1471) + }, + { + PCI_DEVICE_SUB(PCI_VENDOR_ID_ADAPTEC2, 0x028f, + PCI_VENDOR_ID_ADAPTEC2, 0x1472) + }, + { + PCI_DEVICE_SUB(PCI_VENDOR_ID_ADAPTEC2, 0x028f, + PCI_VENDOR_ID_ADAPTEC2, 0x1480) + }, + { + PCI_DEVICE_SUB(PCI_VENDOR_ID_ADAPTEC2, 0x028f, + PCI_VENDOR_ID_ADAPTEC2, 0x1490) + }, + { + PCI_DEVICE_SUB(PCI_VENDOR_ID_ADAPTEC2, 0x028f, + PCI_VENDOR_ID_ADAPTEC2, 0x1491) + }, + { + PCI_DEVICE_SUB(PCI_VENDOR_ID_ADAPTEC2, 0x028f, + PCI_VENDOR_ID_ADAPTEC2, 0x14a0) + }, + { + PCI_DEVICE_SUB(PCI_VENDOR_ID_ADAPTEC2, 0x028f, + PCI_VENDOR_ID_ADAPTEC2, 0x14a1) + }, + { + PCI_DEVICE_SUB(PCI_VENDOR_ID_ADAPTEC2, 0x028f, + PCI_VENDOR_ID_ADAPTEC2, 0x14b0) + }, + { + PCI_DEVICE_SUB(PCI_VENDOR_ID_ADAPTEC2, 0x028f, + PCI_VENDOR_ID_ADAPTEC2, 0x14b1) + }, + { + PCI_DEVICE_SUB(PCI_VENDOR_ID_ADAPTEC2, 0x028f, + PCI_VENDOR_ID_ADAPTEC2, 0x14c0) + }, + { + PCI_DEVICE_SUB(PCI_VENDOR_ID_ADAPTEC2, 0x028f, + PCI_VENDOR_ID_ADAPTEC2, 0x14c1) + }, + { + PCI_DEVICE_SUB(PCI_VENDOR_ID_ADAPTEC2, 0x028f, + PCI_VENDOR_ID_ADAPTEC2, 0x14d0) + }, + { + PCI_DEVICE_SUB(PCI_VENDOR_ID_ADAPTEC2, 0x028f, + PCI_VENDOR_ID_ADAPTEC2, 0x14e0) + }, + { + PCI_DEVICE_SUB(PCI_VENDOR_ID_ADAPTEC2, 0x028f, + PCI_VENDOR_ID_ADAPTEC2, 0x14f0) + }, { PCI_DEVICE_SUB(PCI_VENDOR_ID_ADAPTEC2, 0x028f, PCI_VENDOR_ID_ADVANTECH, 0x8312) @@ -8995,6 +9131,10 @@ static const struct pci_device_id pqi_pci_id_table[] = { PCI_DEVICE_SUB(PCI_VENDOR_ID_ADAPTEC2, 0x028f, PCI_VENDOR_ID_HP, 0x1001) }, + { + PCI_DEVICE_SUB(PCI_VENDOR_ID_ADAPTEC2, 0x028f, + PCI_VENDOR_ID_HP, 0x1002) + }, { PCI_DEVICE_SUB(PCI_VENDOR_ID_ADAPTEC2, 0x028f, PCI_VENDOR_ID_HP, 0x1100) @@ -9003,6 +9143,22 @@ static const struct pci_device_id pqi_pci_id_table[] = { PCI_DEVICE_SUB(PCI_VENDOR_ID_ADAPTEC2, 0x028f, PCI_VENDOR_ID_HP, 0x1101) }, + { + PCI_DEVICE_SUB(PCI_VENDOR_ID_ADAPTEC2, 0x028f, + 0x1590, 0x0294) + }, + { + PCI_DEVICE_SUB(PCI_VENDOR_ID_ADAPTEC2, 0x028f, + 0x1590, 0x02db) + }, + { + PCI_DEVICE_SUB(PCI_VENDOR_ID_ADAPTEC2, 0x028f, + 0x1590, 0x02dc) + }, + { + PCI_DEVICE_SUB(PCI_VENDOR_ID_ADAPTEC2, 0x028f, + 0x1590, 0x032e) + }, { PCI_DEVICE_SUB(PCI_VENDOR_ID_ADAPTEC2, 0x028f, 0x1d8d, 0x0800) From d56030f882a71e41732b544f98e1735b66a25d35 Mon Sep 17 00:00:00 2001 From: Don Brace Date: Thu, 11 Mar 2021 14:17:54 -0600 Subject: [PATCH 309/412] scsi: smartpqi: Update version to 2.1.8-045 Update version. Link: https://lore.kernel.org/r/161549387469.25025.12859568843576080076.stgit@brunhilda Reviewed-by: Scott Benesh Reviewed-by: Gerry Morong Reviewed-by: Mike McGowen Reviewed-by: Scott Teel Reviewed-by: Kevin Barnett Reviewed-by: Martin Wilck Signed-off-by: Don Brace Signed-off-by: Martin K. Petersen --- drivers/scsi/smartpqi/smartpqi_init.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/drivers/scsi/smartpqi/smartpqi_init.c b/drivers/scsi/smartpqi/smartpqi_init.c index 99c24599b2c8..3b0f281daa2b 100644 --- a/drivers/scsi/smartpqi/smartpqi_init.c +++ b/drivers/scsi/smartpqi/smartpqi_init.c @@ -33,11 +33,11 @@ #define BUILD_TIMESTAMP #endif -#define DRIVER_VERSION "1.2.16-012" -#define DRIVER_MAJOR 1 -#define DRIVER_MINOR 2 -#define DRIVER_RELEASE 16 -#define DRIVER_REVISION 12 +#define DRIVER_VERSION "2.1.8-045" +#define DRIVER_MAJOR 2 +#define DRIVER_MINOR 1 +#define DRIVER_RELEASE 8 +#define DRIVER_REVISION 45 #define DRIVER_NAME "Microsemi PQI Driver (v" \ DRIVER_VERSION BUILD_TIMESTAMP ")" From 22ec513e705735e32d4b8263c23d20c779639c7e Mon Sep 17 00:00:00 2001 From: John Pittman Date: Wed, 31 Mar 2021 14:16:56 -0400 Subject: [PATCH 310/412] scsi: scsi_dh_alua: Prevent duplicate pg info print in alua_rtpg() Due to the frequency that alua_rtpg() is called, the path group info print within can print the same info multiple times in the logs, subsequent prints adding no new information or value. To reproduce: # modprobe scsi_debug vpd_use_hostno=0 # systemctl start multipathd.service To fix, check stored values, only printing at alua attach/activate and if any of the values change. Link: https://lore.kernel.org/r/20210331181656.5046-1-jpittman@redhat.com Reviewed-by: David Jeffery Reviewed-by: Laurence Oberman Signed-off-by: John Pittman Signed-off-by: Martin K. Petersen --- drivers/scsi/device_handler/scsi_dh_alua.c | 30 ++++++++++++++-------- 1 file changed, 19 insertions(+), 11 deletions(-) diff --git a/drivers/scsi/device_handler/scsi_dh_alua.c b/drivers/scsi/device_handler/scsi_dh_alua.c index ea436a14087f..7438ed491681 100644 --- a/drivers/scsi/device_handler/scsi_dh_alua.c +++ b/drivers/scsi/device_handler/scsi_dh_alua.c @@ -515,6 +515,7 @@ static int alua_rtpg(struct scsi_device *sdev, struct alua_port_group *pg) struct scsi_sense_hdr sense_hdr; struct alua_port_group *tmp_pg; int len, k, off, bufflen = ALUA_RTPG_SIZE; + int group_id_old, state_old, pref_old, valid_states_old; unsigned char *desc, *buff; unsigned err, retval; unsigned int tpg_desc_tbl_off; @@ -522,6 +523,11 @@ static int alua_rtpg(struct scsi_device *sdev, struct alua_port_group *pg) unsigned long flags; bool transitioning_sense = false; + group_id_old = pg->group_id; + state_old = pg->state; + pref_old = pg->pref; + valid_states_old = pg->valid_states; + if (!pg->expiry) { unsigned long transition_tmo = ALUA_FAILOVER_TIMEOUT * HZ; @@ -686,17 +692,19 @@ static int alua_rtpg(struct scsi_device *sdev, struct alua_port_group *pg) if (transitioning_sense) pg->state = SCSI_ACCESS_STATE_TRANSITIONING; - sdev_printk(KERN_INFO, sdev, - "%s: port group %02x state %c %s supports %c%c%c%c%c%c%c\n", - ALUA_DH_NAME, pg->group_id, print_alua_state(pg->state), - pg->pref ? "preferred" : "non-preferred", - pg->valid_states&TPGS_SUPPORT_TRANSITION?'T':'t', - pg->valid_states&TPGS_SUPPORT_OFFLINE?'O':'o', - pg->valid_states&TPGS_SUPPORT_LBA_DEPENDENT?'L':'l', - pg->valid_states&TPGS_SUPPORT_UNAVAILABLE?'U':'u', - pg->valid_states&TPGS_SUPPORT_STANDBY?'S':'s', - pg->valid_states&TPGS_SUPPORT_NONOPTIMIZED?'N':'n', - pg->valid_states&TPGS_SUPPORT_OPTIMIZED?'A':'a'); + if (group_id_old != pg->group_id || state_old != pg->state || + pref_old != pg->pref || valid_states_old != pg->valid_states) + sdev_printk(KERN_INFO, sdev, + "%s: port group %02x state %c %s supports %c%c%c%c%c%c%c\n", + ALUA_DH_NAME, pg->group_id, print_alua_state(pg->state), + pg->pref ? "preferred" : "non-preferred", + pg->valid_states&TPGS_SUPPORT_TRANSITION?'T':'t', + pg->valid_states&TPGS_SUPPORT_OFFLINE?'O':'o', + pg->valid_states&TPGS_SUPPORT_LBA_DEPENDENT?'L':'l', + pg->valid_states&TPGS_SUPPORT_UNAVAILABLE?'U':'u', + pg->valid_states&TPGS_SUPPORT_STANDBY?'S':'s', + pg->valid_states&TPGS_SUPPORT_NONOPTIMIZED?'N':'n', + pg->valid_states&TPGS_SUPPORT_OPTIMIZED?'A':'a'); switch (pg->state) { case SCSI_ACCESS_STATE_TRANSITIONING: From bc3f2b42b70eb1b8576e753e7d0e117bbb674496 Mon Sep 17 00:00:00 2001 From: "Ewan D. Milne" Date: Wed, 31 Mar 2021 16:11:54 -0400 Subject: [PATCH 311/412] scsi: scsi_dh_alua: Remove check for ASC 24h in alua_rtpg() Some arrays return ILLEGAL_REQUEST with ASC 00h if they don't support the RTPG extended header so remove the check for INVALID FIELD IN CDB. Link: https://lore.kernel.org/r/20210331201154.20348-1-emilne@redhat.com Reviewed-by: Hannes Reinecke Signed-off-by: Ewan D. Milne Signed-off-by: Martin K. Petersen --- drivers/scsi/device_handler/scsi_dh_alua.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/drivers/scsi/device_handler/scsi_dh_alua.c b/drivers/scsi/device_handler/scsi_dh_alua.c index 7438ed491681..e6fde27d4565 100644 --- a/drivers/scsi/device_handler/scsi_dh_alua.c +++ b/drivers/scsi/device_handler/scsi_dh_alua.c @@ -579,10 +579,11 @@ static int alua_rtpg(struct scsi_device *sdev, struct alua_port_group *pg) * even though it shouldn't according to T10. * The retry without rtpg_ext_hdr_req set * handles this. + * Note: some arrays return a sense key of ILLEGAL_REQUEST + * with ASC 00h if they don't support the extended header. */ if (!(pg->flags & ALUA_RTPG_EXT_HDR_UNSUPP) && - sense_hdr.sense_key == ILLEGAL_REQUEST && - sense_hdr.asc == 0x24 && sense_hdr.ascq == 0) { + sense_hdr.sense_key == ILLEGAL_REQUEST) { pg->flags |= ALUA_RTPG_EXT_HDR_UNSUPP; goto retry; } From 0aecfa662e4312046ece56bb5666796412abe8cb Mon Sep 17 00:00:00 2001 From: Konstantin Shelekhin Date: Mon, 22 Mar 2021 23:09:37 +0300 Subject: [PATCH 312/412] scsi: target: Add the DUMMY flag to rd_mcp This commit adds the DUMMY flag to the rd_mcp backend that forces a logical unit to report itself as not connected device of an unknown type. Essentially this allows users to create devices identical to the device for the virtual LUN 0, making it possible to explicitly create a LUN 0 device and configure its WWNs (e.g. vendor or product name). Link: https://lore.kernel.org/r/20210322200938.53300-2-k.shelekhin@yadro.com Reviewed-by: Roman Bolshakov Reviewed-by: Mike Christie Signed-off-by: Konstantin Shelekhin Signed-off-by: Martin K. Petersen --- drivers/target/target_core_rd.c | 27 +++++++++++++++++++++++---- drivers/target/target_core_rd.h | 1 + 2 files changed, 24 insertions(+), 4 deletions(-) diff --git a/drivers/target/target_core_rd.c b/drivers/target/target_core_rd.c index bf936bbeccfe..6648c1c90e19 100644 --- a/drivers/target/target_core_rd.c +++ b/drivers/target/target_core_rd.c @@ -530,12 +530,13 @@ rd_execute_rw(struct se_cmd *cmd, struct scatterlist *sgl, u32 sgl_nents, } enum { - Opt_rd_pages, Opt_rd_nullio, Opt_err + Opt_rd_pages, Opt_rd_nullio, Opt_rd_dummy, Opt_err }; static match_table_t tokens = { {Opt_rd_pages, "rd_pages=%d"}, {Opt_rd_nullio, "rd_nullio=%d"}, + {Opt_rd_dummy, "rd_dummy=%d"}, {Opt_err, NULL} }; @@ -574,6 +575,14 @@ static ssize_t rd_set_configfs_dev_params(struct se_device *dev, pr_debug("RAMDISK: Setting NULLIO flag: %d\n", arg); rd_dev->rd_flags |= RDF_NULLIO; break; + case Opt_rd_dummy: + match_int(args, &arg); + if (arg != 1) + break; + + pr_debug("RAMDISK: Setting DUMMY flag: %d\n", arg); + rd_dev->rd_flags |= RDF_DUMMY; + break; default: break; } @@ -590,12 +599,22 @@ static ssize_t rd_show_configfs_dev_params(struct se_device *dev, char *b) ssize_t bl = sprintf(b, "TCM RamDisk ID: %u RamDisk Makeup: rd_mcp\n", rd_dev->rd_dev_id); bl += sprintf(b + bl, " PAGES/PAGE_SIZE: %u*%lu" - " SG_table_count: %u nullio: %d\n", rd_dev->rd_page_count, + " SG_table_count: %u nullio: %d dummy: %d\n", + rd_dev->rd_page_count, PAGE_SIZE, rd_dev->sg_table_count, - !!(rd_dev->rd_flags & RDF_NULLIO)); + !!(rd_dev->rd_flags & RDF_NULLIO), + !!(rd_dev->rd_flags & RDF_DUMMY)); return bl; } +static u32 rd_get_device_type(struct se_device *dev) +{ + if (RD_DEV(dev)->rd_flags & RDF_DUMMY) + return 0x3f; /* Unknown device type, not connected */ + else + return sbc_get_device_type(dev); +} + static sector_t rd_get_blocks(struct se_device *dev) { struct rd_dev *rd_dev = RD_DEV(dev); @@ -647,7 +666,7 @@ static const struct target_backend_ops rd_mcp_ops = { .parse_cdb = rd_parse_cdb, .set_configfs_dev_params = rd_set_configfs_dev_params, .show_configfs_dev_params = rd_show_configfs_dev_params, - .get_device_type = sbc_get_device_type, + .get_device_type = rd_get_device_type, .get_blocks = rd_get_blocks, .init_prot = rd_init_prot, .free_prot = rd_free_prot, diff --git a/drivers/target/target_core_rd.h b/drivers/target/target_core_rd.h index 8b88f9b14c3f..9ffda5c4b584 100644 --- a/drivers/target/target_core_rd.h +++ b/drivers/target/target_core_rd.h @@ -28,6 +28,7 @@ struct rd_dev_sg_table { #define RDF_HAS_PAGE_COUNT 0x01 #define RDF_NULLIO 0x02 +#define RDF_DUMMY 0x04 struct rd_dev { struct se_device dev; From 1b5ad814af5ed38fe66274c37800c093c8347994 Mon Sep 17 00:00:00 2001 From: Konstantin Shelekhin Date: Mon, 22 Mar 2021 23:09:38 +0300 Subject: [PATCH 313/412] scsi: target: Make the virtual LUN 0 device Create the device for the virtual LUN 0 using the DUMMY flag. This change makes it possible to remove some special-casing in the INQUIRY code. Link: https://lore.kernel.org/r/20210322200938.53300-3-k.shelekhin@yadro.com Reviewed-by: Roman Bolshakov Reviewed-by: Mike Christie Signed-off-by: Konstantin Shelekhin Signed-off-by: Martin K. Petersen --- drivers/target/target_core_device.c | 2 +- drivers/target/target_core_spc.c | 6 +----- 2 files changed, 2 insertions(+), 6 deletions(-) diff --git a/drivers/target/target_core_device.c b/drivers/target/target_core_device.c index 74d3a4896588..a8df9f0a82fa 100644 --- a/drivers/target/target_core_device.c +++ b/drivers/target/target_core_device.c @@ -1035,7 +1035,7 @@ int core_dev_setup_virtual_lun0(void) { struct se_hba *hba; struct se_device *dev; - char buf[] = "rd_pages=8,rd_nullio=1"; + char buf[] = "rd_pages=8,rd_nullio=1,rd_dummy=1"; int ret; hba = core_alloc_hba("rd_mcp", 0, HBA_FLAGS_INTERNAL_USE); diff --git a/drivers/target/target_core_spc.c b/drivers/target/target_core_spc.c index ca5579ebc81d..70a661801cb9 100644 --- a/drivers/target/target_core_spc.c +++ b/drivers/target/target_core_spc.c @@ -701,7 +701,6 @@ static sense_reason_t spc_emulate_inquiry(struct se_cmd *cmd) { struct se_device *dev = cmd->se_dev; - struct se_portal_group *tpg = cmd->se_lun->lun_tpg; unsigned char *rbuf; unsigned char *cdb = cmd->t_task_cdb; unsigned char *buf; @@ -715,10 +714,7 @@ spc_emulate_inquiry(struct se_cmd *cmd) return TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE; } - if (dev == rcu_access_pointer(tpg->tpg_virt_lun0->lun_se_dev)) - buf[0] = 0x3f; /* Not connected */ - else - buf[0] = dev->transport->get_device_type(dev); + buf[0] = dev->transport->get_device_type(dev); if (!(cdb[1] & 0x1)) { if (cdb[2]) { From 4c51f956965120b3441cdd39c358b87daba13e19 Mon Sep 17 00:00:00 2001 From: Sreekanth Reddy Date: Tue, 30 Mar 2021 16:20:04 +0530 Subject: [PATCH 314/412] scsi: mpt3sas: Only one vSES is present even when IOC has multi vSES Whenever the driver is adding a vSES to virtual-phys list it is reinitializing the list head. Hence those vSES devices which were added previously are lost. Stop reinitializing the list every time a new vSES device is added. Link: https://lore.kernel.org/r/20210330105004.20413-1-sreekanth.reddy@broadcom.com Cc: stable@vger.kernel.org #v5.11.10+ Signed-off-by: Sreekanth Reddy Signed-off-by: Martin K. Petersen --- drivers/scsi/mpt3sas/mpt3sas_scsih.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/scsi/mpt3sas/mpt3sas_scsih.c b/drivers/scsi/mpt3sas/mpt3sas_scsih.c index ffa7522cbb40..3c5160f0137b 100644 --- a/drivers/scsi/mpt3sas/mpt3sas_scsih.c +++ b/drivers/scsi/mpt3sas/mpt3sas_scsih.c @@ -6484,6 +6484,9 @@ _scsih_alloc_vphy(struct MPT3SAS_ADAPTER *ioc, u8 port_id, u8 phy_num) if (!vphy) return NULL; + if (!port->vphys_mask) + INIT_LIST_HEAD(&port->vphys_list); + /* * Enable bit corresponding to HBA phy number on its * parent hba_port object's vphys_mask field. @@ -6491,7 +6494,6 @@ _scsih_alloc_vphy(struct MPT3SAS_ADAPTER *ioc, u8 port_id, u8 phy_num) port->vphys_mask |= (1 << phy_num); vphy->phy_mask |= (1 << phy_num); - INIT_LIST_HEAD(&port->vphys_list); list_add_tail(&vphy->list, &port->vphys_list); ioc_info(ioc, From c0629d70ca5570ab75e791e03e6fd11b9c754a6a Mon Sep 17 00:00:00 2001 From: Sreekanth Reddy Date: Tue, 30 Mar 2021 16:21:06 +0530 Subject: [PATCH 315/412] scsi: mpt3sas: Fix endianness for ActiveCablePowerRequirement Covert ActiveCablePowerRequirement's value to target CPU endian before displaying it. Link: https://lore.kernel.org/r/20210330105106.20569-1-sreekanth.reddy@broadcom.com Signed-off-by: Sreekanth Reddy Signed-off-by: Martin K. Petersen --- drivers/scsi/mpt3sas/mpt3sas_scsih.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/scsi/mpt3sas/mpt3sas_scsih.c b/drivers/scsi/mpt3sas/mpt3sas_scsih.c index 3c5160f0137b..d00aca3c77ce 100644 --- a/drivers/scsi/mpt3sas/mpt3sas_scsih.c +++ b/drivers/scsi/mpt3sas/mpt3sas_scsih.c @@ -10820,7 +10820,8 @@ mpt3sas_scsih_event_callback(struct MPT3SAS_ADAPTER *ioc, u8 msix_index, pr_notice("cannot be powered and devices connected\n"); pr_notice("to this active cable will not be seen\n"); pr_notice("This active cable requires %d mW of power\n", - ActiveCableEventData->ActiveCablePowerRequirement); + le32_to_cpu( + ActiveCableEventData->ActiveCablePowerRequirement)); break; case MPI26_EVENT_ACTIVE_CABLE_DEGRADED: From 3c8604691d2acc7b7d4795d9695070de9eaa5828 Mon Sep 17 00:00:00 2001 From: Sreekanth Reddy Date: Tue, 30 Mar 2021 16:21:37 +0530 Subject: [PATCH 316/412] scsi: mpt3sas: Block PCI config access from userspace during reset While diag reset is in progress there is short duration where all access to controller's PCI config space from the host needs to be blocked. This is due to a hardware limitation of the IOC controllers. Block all access to controller's config space from userland applications by calling pci_cfg_access_lock() while diag reset is in progress and unlocking it again after the controller comes back to ready state. Link: https://lore.kernel.org/r/20210330105137.20728-1-sreekanth.reddy@broadcom.com Cc: stable@vger.kernel.org #v5.4.108+ Signed-off-by: Sreekanth Reddy Signed-off-by: Martin K. Petersen --- drivers/scsi/mpt3sas/mpt3sas_base.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/drivers/scsi/mpt3sas/mpt3sas_base.c b/drivers/scsi/mpt3sas/mpt3sas_base.c index 016b01bcc1a3..84c507587166 100644 --- a/drivers/scsi/mpt3sas/mpt3sas_base.c +++ b/drivers/scsi/mpt3sas/mpt3sas_base.c @@ -7405,6 +7405,8 @@ _base_diag_reset(struct MPT3SAS_ADAPTER *ioc) ioc_info(ioc, "sending diag reset !!\n"); + pci_cfg_access_lock(ioc->pdev); + drsprintk(ioc, ioc_info(ioc, "clear interrupts\n")); count = 0; @@ -7495,10 +7497,12 @@ _base_diag_reset(struct MPT3SAS_ADAPTER *ioc) goto out; } + pci_cfg_access_unlock(ioc->pdev); ioc_info(ioc, "diag reset: SUCCESS\n"); return 0; out: + pci_cfg_access_unlock(ioc->pdev); ioc_err(ioc, "diag reset: FAILED\n"); return -EFAULT; } From 4dec8004de296952b4afc66b47f50cbf4f8421a9 Mon Sep 17 00:00:00 2001 From: zhouchuangao Date: Tue, 30 Mar 2021 05:46:01 -0700 Subject: [PATCH 317/412] scsi: message: fusion: Use BUG_ON instead of if condition followed by BUG BUG_ON() uses unlikely in if() which can be optimized at compile time. Link: https://lore.kernel.org/r/1617108361-6870-1-git-send-email-zhouchuangao@vivo.com Signed-off-by: zhouchuangao Signed-off-by: Martin K. Petersen --- drivers/message/fusion/mptsas.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/drivers/message/fusion/mptsas.c b/drivers/message/fusion/mptsas.c index 85aa5788826b..1857869e7e8d 100644 --- a/drivers/message/fusion/mptsas.c +++ b/drivers/message/fusion/mptsas.c @@ -3442,14 +3442,12 @@ mptsas_expander_event_add(MPT_ADAPTER *ioc, __le64 sas_address; port_info = kzalloc(sizeof(struct mptsas_portinfo), GFP_KERNEL); - if (!port_info) - BUG(); + BUG_ON(!port_info); port_info->num_phys = (expander_data->NumPhys) ? expander_data->NumPhys : 1; port_info->phy_info = kcalloc(port_info->num_phys, sizeof(struct mptsas_phyinfo), GFP_KERNEL); - if (!port_info->phy_info) - BUG(); + BUG_ON(!port_info->phy_info); memcpy(&sas_address, &expander_data->SASAddress, sizeof(__le64)); for (i = 0; i < port_info->num_phys; i++) { port_info->phy_info[i].portinfo = port_info; From aa6f2fccd7119c5579f9705c4f52f2eefa5e37d5 Mon Sep 17 00:00:00 2001 From: Yang Yingliang Date: Tue, 30 Mar 2021 20:59:11 +0800 Subject: [PATCH 318/412] scsi: fnic: Remove unnecessary spin_lock_init() and INIT_LIST_HEAD() The spinlock and list head of fnic_list are initialized statically. It is unnecessary to initialize them. Link: https://lore.kernel.org/r/20210330125911.1050879-1-yangyingliang@huawei.com Reported-by: Hulk Robot Signed-off-by: Yang Yingliang Signed-off-by: Martin K. Petersen --- drivers/scsi/fnic/fnic_main.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/drivers/scsi/fnic/fnic_main.c b/drivers/scsi/fnic/fnic_main.c index 186c3ab4456b..786f9d2704b6 100644 --- a/drivers/scsi/fnic/fnic_main.c +++ b/drivers/scsi/fnic/fnic_main.c @@ -1100,9 +1100,6 @@ static int __init fnic_init_module(void) goto err_create_fnic_workq; } - spin_lock_init(&fnic_list_lock); - INIT_LIST_HEAD(&fnic_list); - fnic_fip_queue = create_singlethread_workqueue("fnic_fip_q"); if (!fnic_fip_queue) { printk(KERN_ERR PFX "fnic FIP work queue create failed\n"); From 1352eec8c0da71ee14b6b3bd46d49f8523f8e106 Mon Sep 17 00:00:00 2001 From: "Gustavo A. R. Silva" Date: Wed, 31 Mar 2021 17:43:38 -0500 Subject: [PATCH 319/412] scsi: ufs: core: Fix out-of-bounds warnings in ufshcd_exec_raw_upiu_cmd() Fix the following out-of-bounds warnings by enclosing some structure members into new structure objects upiu_req and upiu_rsp: include/linux/fortify-string.h:20:29: warning: '__builtin_memcpy' offset [29, 48] from the object at 'treq' is out of the bounds of referenced subobject 'req_header' with type 'struct utp_upiu_header' at offset 16 [-Warray-bounds] include/linux/fortify-string.h:20:29: warning: '__builtin_memcpy' offset [61, 80] from the object at 'treq' is out of the bounds of referenced subobject 'rsp_header' with type 'struct utp_upiu_header' at offset 48 [-Warray-bounds] arch/m68k/include/asm/string.h:72:25: warning: '__builtin_memcpy' offset [29, 48] from the object at 'treq' is out of the bounds of referenced subobject 'req_header' with type 'struct utp_upiu_header' at offset 16 [-Warray-bounds] arch/m68k/include/asm/string.h:72:25: warning: '__builtin_memcpy' offset [61, 80] from the object at 'treq' is out of the bounds of referenced subobject 'rsp_header' with type 'struct utp_upiu_header' at offset 48 [-Warray-bounds] Refactor the code by making it more structured. The problem is that the original code is trying to copy data into a bunch of struct members adjacent to each other in a single call to memcpy(). Now that a new struct _upiu_req_ enclosing all those adjacent members is introduced, memcpy() doesn't overrun the length of &treq.req_header, because the address of the new struct object _upiu_req_ is used as the destination, instead. The same problem is present when memcpy() overruns the length of the source &treq.rsp_header; in this case the address of the new struct object _upiu_rsp_ is used, instead. Also, this helps with the ongoing efforts to enable -Warray-bounds and avoid confusing the compiler. Link: https://github.com/KSPP/linux/issues/109 Link: https://lore.kernel.org/lkml/60640558.lsAxiK6otPwTo9rv%25lkp@intel.com/ Link: https://lore.kernel.org/r/20210331224338.GA347171@embeddedor Reported-by: kernel test robot Reviewed-by: Avri Altman Signed-off-by: Gustavo A. R. Silva Signed-off-by: Martin K. Petersen Build-tested-by: kernel test robot --- drivers/scsi/ufs/ufshcd.c | 28 ++++++++++++++++------------ drivers/scsi/ufs/ufshci.h | 22 +++++++++++++--------- 2 files changed, 29 insertions(+), 21 deletions(-) diff --git a/drivers/scsi/ufs/ufshcd.c b/drivers/scsi/ufs/ufshcd.c index acc6356d9d43..58d7f264c664 100644 --- a/drivers/scsi/ufs/ufshcd.c +++ b/drivers/scsi/ufs/ufshcd.c @@ -327,11 +327,15 @@ static void ufshcd_add_tm_upiu_trace(struct ufs_hba *hba, unsigned int tag, return; if (str_t == UFS_TM_SEND) - trace_ufshcd_upiu(dev_name(hba->dev), str_t, &descp->req_header, - &descp->input_param1, UFS_TSF_TM_INPUT); + trace_ufshcd_upiu(dev_name(hba->dev), str_t, + &descp->upiu_req.req_header, + &descp->upiu_req.input_param1, + UFS_TSF_TM_INPUT); else - trace_ufshcd_upiu(dev_name(hba->dev), str_t, &descp->rsp_header, - &descp->output_param1, UFS_TSF_TM_OUTPUT); + trace_ufshcd_upiu(dev_name(hba->dev), str_t, + &descp->upiu_rsp.rsp_header, + &descp->upiu_rsp.output_param1, + UFS_TSF_TM_OUTPUT); } static void ufshcd_add_uic_command_trace(struct ufs_hba *hba, @@ -6398,7 +6402,7 @@ static int __ufshcd_issue_tm_cmd(struct ufs_hba *hba, spin_lock_irqsave(host->host_lock, flags); task_tag = hba->nutrs + free_slot; - treq->req_header.dword_0 |= cpu_to_be32(task_tag); + treq->upiu_req.req_header.dword_0 |= cpu_to_be32(task_tag); memcpy(hba->utmrdl_base_addr + free_slot, treq, sizeof(*treq)); ufshcd_vops_setup_task_mgmt(hba, free_slot, tm_function); @@ -6471,16 +6475,16 @@ static int ufshcd_issue_tm_cmd(struct ufs_hba *hba, int lun_id, int task_id, treq.header.dword_2 = cpu_to_le32(OCS_INVALID_COMMAND_STATUS); /* Configure task request UPIU */ - treq.req_header.dword_0 = cpu_to_be32(lun_id << 8) | + treq.upiu_req.req_header.dword_0 = cpu_to_be32(lun_id << 8) | cpu_to_be32(UPIU_TRANSACTION_TASK_REQ << 24); - treq.req_header.dword_1 = cpu_to_be32(tm_function << 16); + treq.upiu_req.req_header.dword_1 = cpu_to_be32(tm_function << 16); /* * The host shall provide the same value for LUN field in the basic * header and for Input Parameter. */ - treq.input_param1 = cpu_to_be32(lun_id); - treq.input_param2 = cpu_to_be32(task_id); + treq.upiu_req.input_param1 = cpu_to_be32(lun_id); + treq.upiu_req.input_param2 = cpu_to_be32(task_id); err = __ufshcd_issue_tm_cmd(hba, &treq, tm_function); if (err == -ETIMEDOUT) @@ -6491,7 +6495,7 @@ static int ufshcd_issue_tm_cmd(struct ufs_hba *hba, int lun_id, int task_id, dev_err(hba->dev, "%s: failed, ocs = 0x%x\n", __func__, ocs_value); else if (tm_response) - *tm_response = be32_to_cpu(treq.output_param1) & + *tm_response = be32_to_cpu(treq.upiu_rsp.output_param1) & MASK_TM_SERVICE_RESP; return err; } @@ -6666,7 +6670,7 @@ int ufshcd_exec_raw_upiu_cmd(struct ufs_hba *hba, treq.header.dword_0 = cpu_to_le32(UTP_REQ_DESC_INT_CMD); treq.header.dword_2 = cpu_to_le32(OCS_INVALID_COMMAND_STATUS); - memcpy(&treq.req_header, req_upiu, sizeof(*req_upiu)); + memcpy(&treq.upiu_req, req_upiu, sizeof(*req_upiu)); err = __ufshcd_issue_tm_cmd(hba, &treq, tm_f); if (err == -ETIMEDOUT) @@ -6679,7 +6683,7 @@ int ufshcd_exec_raw_upiu_cmd(struct ufs_hba *hba, break; } - memcpy(rsp_upiu, &treq.rsp_header, sizeof(*rsp_upiu)); + memcpy(rsp_upiu, &treq.upiu_rsp, sizeof(*rsp_upiu)); break; default: diff --git a/drivers/scsi/ufs/ufshci.h b/drivers/scsi/ufs/ufshci.h index 335ff7b5a935..de95be5d11d4 100644 --- a/drivers/scsi/ufs/ufshci.h +++ b/drivers/scsi/ufs/ufshci.h @@ -486,17 +486,21 @@ struct utp_task_req_desc { struct request_desc_header header; /* DW 4-11 - Task request UPIU structure */ - struct utp_upiu_header req_header; - __be32 input_param1; - __be32 input_param2; - __be32 input_param3; - __be32 __reserved1[2]; + struct { + struct utp_upiu_header req_header; + __be32 input_param1; + __be32 input_param2; + __be32 input_param3; + __be32 __reserved1[2]; + } upiu_req; /* DW 12-19 - Task Management Response UPIU structure */ - struct utp_upiu_header rsp_header; - __be32 output_param1; - __be32 output_param2; - __be32 __reserved2[3]; + struct { + struct utp_upiu_header rsp_header; + __be32 output_param1; + __be32 output_param2; + __be32 __reserved2[3]; + } upiu_rsp; }; #endif /* End of Header */ From c3b0d087763f983343f153f348ec535784c556b2 Mon Sep 17 00:00:00 2001 From: Wan Jiabing Date: Thu, 1 Apr 2021 14:35:34 +0800 Subject: [PATCH 320/412] scsi: bfa: Remove unnecessary struct declarations struct bfa_fcs_s is declared twice. First is declared at line 50, remove the duplicate. struct bfa_fcs_fabric_s is defined at line 175, remove unnecessary declaration. Link: https://lore.kernel.org/r/20210401063535.992487-1-wanjiabing@vivo.com Signed-off-by: Wan Jiabing Signed-off-by: Martin K. Petersen --- drivers/scsi/bfa/bfa_fcs.h | 3 --- 1 file changed, 3 deletions(-) diff --git a/drivers/scsi/bfa/bfa_fcs.h b/drivers/scsi/bfa/bfa_fcs.h index 3e117fed95c9..c1baf5cd0d3e 100644 --- a/drivers/scsi/bfa/bfa_fcs.h +++ b/drivers/scsi/bfa/bfa_fcs.h @@ -217,9 +217,6 @@ struct bfa_vf_event_s { u32 undefined; }; -struct bfa_fcs_s; -struct bfa_fcs_fabric_s; - /* * @todo : need to move to a global config file. * Maximum Rports supported per port (physical/logical). From a1e9981ba528d002cdf323dc8d535bc919a981a0 Mon Sep 17 00:00:00 2001 From: Tian Tao Date: Thu, 1 Apr 2021 21:26:58 +0800 Subject: [PATCH 321/412] scsi: qedf: Remove unused include of linux/version.h Remove unnecessary include of linux/version.h. Link: https://lore.kernel.org/r/1617283618-19346-1-git-send-email-tiantao6@hisilicon.com Signed-off-by: Tian Tao Signed-off-by: Zhiqi Song Signed-off-by: Martin K. Petersen --- drivers/scsi/qedf/qedf.h | 2 -- drivers/scsi/qedf/qedf_dbg.h | 1 - 2 files changed, 3 deletions(-) diff --git a/drivers/scsi/qedf/qedf.h b/drivers/scsi/qedf/qedf.h index 88a592d09433..0583b0707354 100644 --- a/drivers/scsi/qedf/qedf.h +++ b/drivers/scsi/qedf/qedf.h @@ -11,8 +11,6 @@ #include #include #include -#include - /* qedf_hsi.h needs to before included any qed includes */ #include "qedf_hsi.h" diff --git a/drivers/scsi/qedf/qedf_dbg.h b/drivers/scsi/qedf/qedf_dbg.h index 2386bfb73c46..f4d81127239e 100644 --- a/drivers/scsi/qedf/qedf_dbg.h +++ b/drivers/scsi/qedf/qedf_dbg.h @@ -10,7 +10,6 @@ #include #include #include -#include #include #include #include From c03f2422b9f5918ba76c86ae69a02217ea791825 Mon Sep 17 00:00:00 2001 From: Luo Jiaxing Date: Thu, 25 Mar 2021 20:29:55 +0800 Subject: [PATCH 322/412] scsi: libsas: Correctly indent statements in sas_to_ata_err() checkpatch reported an error in sas_to_ata_err(). switch and case statements are incorrectly indented. Link: https://lore.kernel.org/r/1616675396-6108-2-git-send-email-luojiaxing@huawei.com Signed-off-by: Luo Jiaxing Signed-off-by: Martin K. Petersen --- drivers/scsi/libsas/sas_ata.c | 74 ++++++++++++++++------------------- 1 file changed, 34 insertions(+), 40 deletions(-) diff --git a/drivers/scsi/libsas/sas_ata.c b/drivers/scsi/libsas/sas_ata.c index 024e5a550759..c6f527d62a00 100644 --- a/drivers/scsi/libsas/sas_ata.c +++ b/drivers/scsi/libsas/sas_ata.c @@ -35,46 +35,40 @@ static enum ata_completion_errors sas_to_ata_err(struct task_status_struct *ts) /* ts->resp == SAS_TASK_COMPLETE */ /* task delivered, what happened afterwards? */ switch (ts->stat) { - case SAS_DEV_NO_RESPONSE: - return AC_ERR_TIMEOUT; - - case SAS_INTERRUPTED: - case SAS_PHY_DOWN: - case SAS_NAK_R_ERR: - return AC_ERR_ATA_BUS; - - - case SAS_DATA_UNDERRUN: - /* - * Some programs that use the taskfile interface - * (smartctl in particular) can cause underrun - * problems. Ignore these errors, perhaps at our - * peril. - */ - return 0; - - case SAS_DATA_OVERRUN: - case SAS_QUEUE_FULL: - case SAS_DEVICE_UNKNOWN: - case SAS_SG_ERR: - return AC_ERR_INVALID; - - case SAS_OPEN_TO: - case SAS_OPEN_REJECT: - pr_warn("%s: Saw error %d. What to do?\n", - __func__, ts->stat); - return AC_ERR_OTHER; - - case SAM_STAT_CHECK_CONDITION: - case SAS_ABORTED_TASK: - return AC_ERR_DEV; - - case SAS_PROTO_RESPONSE: - /* This means the ending_fis has the error - * value; return 0 here to collect it */ - return 0; - default: - return 0; + case SAS_DEV_NO_RESPONSE: + return AC_ERR_TIMEOUT; + case SAS_INTERRUPTED: + case SAS_PHY_DOWN: + case SAS_NAK_R_ERR: + return AC_ERR_ATA_BUS; + case SAS_DATA_UNDERRUN: + /* + * Some programs that use the taskfile interface + * (smartctl in particular) can cause underrun + * problems. Ignore these errors, perhaps at our + * peril. + */ + return 0; + case SAS_DATA_OVERRUN: + case SAS_QUEUE_FULL: + case SAS_DEVICE_UNKNOWN: + case SAS_SG_ERR: + return AC_ERR_INVALID; + case SAS_OPEN_TO: + case SAS_OPEN_REJECT: + pr_warn("%s: Saw error %d. What to do?\n", + __func__, ts->stat); + return AC_ERR_OTHER; + case SAM_STAT_CHECK_CONDITION: + case SAS_ABORTED_TASK: + return AC_ERR_DEV; + case SAS_PROTO_RESPONSE: + /* This means the ending_fis has the error + * value; return 0 here to collect it + */ + return 0; + default: + return 0; } } From 857a80bbd7321161f986588160d97815d1b1206a Mon Sep 17 00:00:00 2001 From: Luo Jiaxing Date: Thu, 25 Mar 2021 20:29:56 +0800 Subject: [PATCH 323/412] scsi: libsas: Clean up whitespace checkpatch reported several whitespace errors. Fix them all. Link: https://lore.kernel.org/r/1616675396-6108-3-git-send-email-luojiaxing@huawei.com Signed-off-by: Luo Jiaxing Signed-off-by: Martin K. Petersen --- drivers/scsi/libsas/sas_discover.c | 2 +- drivers/scsi/libsas/sas_expander.c | 13 +++++++------ 2 files changed, 8 insertions(+), 7 deletions(-) diff --git a/drivers/scsi/libsas/sas_discover.c b/drivers/scsi/libsas/sas_discover.c index 161c9b387da7..9f5068f3bcfb 100644 --- a/drivers/scsi/libsas/sas_discover.c +++ b/drivers/scsi/libsas/sas_discover.c @@ -75,7 +75,7 @@ static int sas_get_port_device(struct asd_sas_port *port) struct dev_to_host_fis *fis = (struct dev_to_host_fis *) dev->frame_rcvd; if (fis->interrupt_reason == 1 && fis->lbal == 1 && - fis->byte_count_low==0x69 && fis->byte_count_high == 0x96 + fis->byte_count_low == 0x69 && fis->byte_count_high == 0x96 && (fis->device & ~0x10) == 0) dev->dev_type = SAS_SATA_PM; else diff --git a/drivers/scsi/libsas/sas_expander.c b/drivers/scsi/libsas/sas_expander.c index 8d6bcc19359f..6d583e8c403a 100644 --- a/drivers/scsi/libsas/sas_expander.c +++ b/drivers/scsi/libsas/sas_expander.c @@ -553,7 +553,7 @@ static int sas_ex_manuf_info(struct domain_device *dev) mi_req[1] = SMP_REPORT_MANUF_INFO; - res = smp_execute_task(dev, mi_req, MI_REQ_SIZE, mi_resp,MI_RESP_SIZE); + res = smp_execute_task(dev, mi_req, MI_REQ_SIZE, mi_resp, MI_RESP_SIZE); if (res) { pr_notice("MI: ex %016llx failed:0x%x\n", SAS_ADDR(dev->sas_addr), res); @@ -594,13 +594,13 @@ int sas_smp_phy_control(struct domain_device *dev, int phy_id, pc_req[1] = SMP_PHY_CONTROL; pc_req[9] = phy_id; - pc_req[10]= phy_func; + pc_req[10] = phy_func; if (rates) { pc_req[32] = rates->minimum_linkrate << 4; pc_req[33] = rates->maximum_linkrate << 4; } - res = smp_execute_task(dev, pc_req, PC_REQ_SIZE, pc_resp,PC_RESP_SIZE); + res = smp_execute_task(dev, pc_req, PC_REQ_SIZE, pc_resp, PC_RESP_SIZE); if (res) { pr_err("ex %016llx phy%02d PHY control failed: %d\n", SAS_ADDR(dev->sas_addr), phy_id, res); @@ -678,7 +678,7 @@ int sas_smp_get_phy_events(struct sas_phy *phy) req[9] = phy->number; res = smp_execute_task(dev, req, RPEL_REQ_SIZE, - resp, RPEL_RESP_SIZE); + resp, RPEL_RESP_SIZE); if (res) goto out; @@ -714,7 +714,7 @@ int sas_get_report_phy_sata(struct domain_device *dev, int phy_id, rps_req[9] = phy_id; res = smp_execute_task(dev, rps_req, RPS_REQ_SIZE, - rps_resp, RPS_RESP_SIZE); + rps_resp, RPS_RESP_SIZE); /* 0x34 is the FIS type for the D2H fis. There's a potential * standards cockup here. sas-2 explicitly specifies the FIS @@ -1506,7 +1506,8 @@ static int sas_configure_phy(struct domain_device *dev, int phy_id, if (res) return res; if (include ^ present) - return sas_configure_set(dev, phy_id, sas_addr, index,include); + return sas_configure_set(dev, phy_id, sas_addr, index, + include); return res; } From ecddbb7e945daabdf28a29b95c4a2d88d166a891 Mon Sep 17 00:00:00 2001 From: Bodo Stroesser Date: Wed, 24 Mar 2021 20:57:53 +0100 Subject: [PATCH 324/412] scsi: target: tcmu: Adjust names of variables and definitions Some definitions and members of struct tcmu_dev had misleading names. Examples: - ring_size was used for the size of mailbox + cmd ring + data area - CMDR_SIZE was used for size of mailbox + cmd ring I added the new definition MB_CMDR_SIZE (mailbox + command ring), changed CMDR_SIZE to hold the size of the command ring only and replaced in struct tcmu_dev the member ring_size with mmap_pages, because the member is now used in tcmu_mmap() only, where we need page count, not size. I also added the new struct tcmu_dev member 'cmdr' which is used to replace some occurences of '(void *)mb + CMDR_OFF' with 'udev->cmdr' for better readability. Link: https://lore.kernel.org/r/20210324195758.2021-2-bostroesser@gmail.com Signed-off-by: Bodo Stroesser Signed-off-by: Martin K. Petersen --- drivers/target/target_core_user.c | 39 +++++++++++++++++-------------- 1 file changed, 22 insertions(+), 17 deletions(-) diff --git a/drivers/target/target_core_user.c b/drivers/target/target_core_user.c index bdfc057f000c..35975dd75dde 100644 --- a/drivers/target/target_core_user.c +++ b/drivers/target/target_core_user.c @@ -60,8 +60,11 @@ #define TCMU_TIME_OUT (30 * MSEC_PER_SEC) -/* For cmd area, the size is fixed 8MB */ -#define CMDR_SIZE (8 * 1024 * 1024) +/* For mailbox plus cmd ring, the size is fixed 8MB */ +#define MB_CMDR_SIZE (8 * 1024 * 1024) +/* Offset of cmd ring is size of mailbox */ +#define CMDR_OFF sizeof(struct tcmu_mailbox) +#define CMDR_SIZE (MB_CMDR_SIZE - CMDR_OFF) /* * For data area, the block size is PAGE_SIZE and @@ -126,8 +129,10 @@ struct tcmu_dev { struct inode *inode; - struct tcmu_mailbox *mb_addr; uint64_t dev_size; + + struct tcmu_mailbox *mb_addr; + void *cmdr; u32 cmdr_size; u32 cmdr_last_cleaned; /* Offset of data area from start of mb */ @@ -135,7 +140,7 @@ struct tcmu_dev { size_t data_off; size_t data_size; uint32_t max_blocks; - size_t ring_size; + size_t mmap_pages; struct mutex cmdr_lock; struct list_head qfull_queue; @@ -166,8 +171,6 @@ struct tcmu_dev { #define TCMU_DEV(_se_dev) container_of(_se_dev, struct tcmu_dev, se_dev) -#define CMDR_OFF sizeof(struct tcmu_mailbox) - struct tcmu_cmd { struct se_cmd *se_cmd; struct tcmu_dev *tcmu_dev; @@ -941,7 +944,7 @@ static uint32_t ring_insert_padding(struct tcmu_dev *udev, size_t cmd_size) if (head_to_end(cmd_head, udev->cmdr_size) < cmd_size) { size_t pad_size = head_to_end(cmd_head, udev->cmdr_size); - hdr = (void *) mb + CMDR_OFF + cmd_head; + hdr = udev->cmdr + cmd_head; tcmu_hdr_set_op(&hdr->len_op, TCMU_OP_PAD); tcmu_hdr_set_len(&hdr->len_op, pad_size); hdr->cmd_id = 0; /* not used for PAD */ @@ -1065,7 +1068,7 @@ static int queue_cmd_ring(struct tcmu_cmd *tcmu_cmd, sense_reason_t *scsi_err) cmd_head = ring_insert_padding(udev, command_size); - entry = (void *) mb + CMDR_OFF + cmd_head; + entry = udev->cmdr + cmd_head; memset(entry, 0, command_size); tcmu_hdr_set_op(&entry->hdr.len_op, TCMU_OP_CMD); @@ -1157,7 +1160,7 @@ queue_tmr_ring(struct tcmu_dev *udev, struct tcmu_tmr *tmr) cmd_head = ring_insert_padding(udev, cmd_size); - entry = (void *)mb + CMDR_OFF + cmd_head; + entry = udev->cmdr + cmd_head; memset(entry, 0, cmd_size); tcmu_hdr_set_op(&entry->hdr.len_op, TCMU_OP_TMR); tcmu_hdr_set_len(&entry->hdr.len_op, cmd_size); @@ -1412,7 +1415,7 @@ static unsigned int tcmu_handle_completions(struct tcmu_dev *udev) while (udev->cmdr_last_cleaned != READ_ONCE(mb->cmd_tail)) { - struct tcmu_cmd_entry *entry = (void *) mb + CMDR_OFF + udev->cmdr_last_cleaned; + struct tcmu_cmd_entry *entry = udev->cmdr + udev->cmdr_last_cleaned; /* * Flush max. up to end of cmd ring since current entry might @@ -1851,7 +1854,7 @@ static int tcmu_mmap(struct uio_info *info, struct vm_area_struct *vma) vma->vm_private_data = udev; /* Ensure the mmap is exactly the right size */ - if (vma_pages(vma) != (udev->ring_size >> PAGE_SHIFT)) + if (vma_pages(vma) != udev->mmap_pages) return -EINVAL; tcmu_vma_open(vma); @@ -2100,20 +2103,22 @@ static int tcmu_configure_device(struct se_device *dev) goto err_bitmap_alloc; } - udev->mb_addr = vzalloc(CMDR_SIZE); - if (!udev->mb_addr) { + mb = vzalloc(MB_CMDR_SIZE); + if (!mb) { ret = -ENOMEM; goto err_vzalloc; } /* mailbox fits in first part of CMDR space */ - udev->cmdr_size = CMDR_SIZE - CMDR_OFF; - udev->data_off = CMDR_SIZE; + udev->mb_addr = mb; + udev->cmdr = (void *)mb + CMDR_OFF; + udev->cmdr_size = CMDR_SIZE; + udev->data_off = MB_CMDR_SIZE; udev->data_size = udev->max_blocks * DATA_BLOCK_SIZE; + udev->mmap_pages = (udev->data_size + MB_CMDR_SIZE) >> PAGE_SHIFT; udev->dbi_thresh = 0; /* Default in Idle state */ /* Initialise the mailbox of the ring buffer */ - mb = udev->mb_addr; mb->version = TCMU_MAILBOX_VERSION; mb->flags = TCMU_MAILBOX_FLAG_CAP_OOOC | TCMU_MAILBOX_FLAG_CAP_READ_LEN | @@ -2129,7 +2134,7 @@ static int tcmu_configure_device(struct se_device *dev) info->mem[0].name = "tcm-user command & data buffer"; info->mem[0].addr = (phys_addr_t)(uintptr_t)udev->mb_addr; - info->mem[0].size = udev->ring_size = udev->data_size + CMDR_SIZE; + info->mem[0].size = udev->data_size + MB_CMDR_SIZE; info->mem[0].memtype = UIO_MEM_NONE; info->irqcontrol = tcmu_irqcontrol; From 8b084d9dfb0158362c3be6ee7fdc8c8320a0ba30 Mon Sep 17 00:00:00 2001 From: Bodo Stroesser Date: Wed, 24 Mar 2021 20:57:54 +0100 Subject: [PATCH 325/412] scsi: target: tcmu: Prepare for PAGE_SIZE != DATA_BLOCK_SIZE Rename some variables and definitions as a first preparation for DATA_BLOCK_SIZE != PAGE_SIZE and add the new DATA_PAGES_PER_BLK definition containing the number of pages per data block. Rename tcmu_try_get_block_page() to tcmu_try_get_data_page(). Keep name tcmu_get_block_page() since it will go away in a following commit when there is only one caller left. Subsequent commits will then add full support for DATA_PAGES_PER_BLK != 1, which also means DATA_BLOCK_SIZE = DATA_PAGES_PER_BLK * PAGE_SIZE Link: https://lore.kernel.org/r/20210324195758.2021-3-bostroesser@gmail.com Signed-off-by: Bodo Stroesser Signed-off-by: Martin K. Petersen --- drivers/target/target_core_user.c | 82 +++++++++++++++---------------- 1 file changed, 41 insertions(+), 41 deletions(-) diff --git a/drivers/target/target_core_user.c b/drivers/target/target_core_user.c index 35975dd75dde..f42d38873aaf 100644 --- a/drivers/target/target_core_user.c +++ b/drivers/target/target_core_user.c @@ -71,17 +71,17 @@ * the total size is 256K * PAGE_SIZE. */ #define DATA_BLOCK_SIZE PAGE_SIZE -#define DATA_BLOCK_SHIFT PAGE_SHIFT +#define DATA_PAGES_PER_BLK 1 #define DATA_BLOCK_BITS_DEF (256 * 1024) -#define TCMU_MBS_TO_BLOCKS(_mbs) (_mbs << (20 - DATA_BLOCK_SHIFT)) -#define TCMU_BLOCKS_TO_MBS(_blocks) (_blocks >> (20 - DATA_BLOCK_SHIFT)) +#define TCMU_MBS_TO_PAGES(_mbs) (_mbs << (20 - PAGE_SHIFT)) +#define TCMU_PAGES_TO_MBS(_pages) (_pages >> (20 - PAGE_SHIFT)) /* * Default number of global data blocks(512K * PAGE_SIZE) * when the unmap thread will be started. */ -#define TCMU_GLOBAL_MAX_BLOCKS_DEF (512 * 1024) +#define TCMU_GLOBAL_MAX_PAGES_DEF (512 * 1024) static u8 tcmu_kern_cmd_reply_supported; static u8 tcmu_netlink_blocked; @@ -149,7 +149,7 @@ struct tcmu_dev { uint32_t dbi_max; uint32_t dbi_thresh; unsigned long *data_bitmap; - struct xarray data_blocks; + struct xarray data_pages; struct xarray commands; @@ -219,9 +219,9 @@ static LIST_HEAD(timed_out_udevs); static struct kmem_cache *tcmu_cmd_cache; -static atomic_t global_db_count = ATOMIC_INIT(0); +static atomic_t global_page_count = ATOMIC_INIT(0); static struct delayed_work tcmu_unmap_work; -static int tcmu_global_max_blocks = TCMU_GLOBAL_MAX_BLOCKS_DEF; +static int tcmu_global_max_pages = TCMU_GLOBAL_MAX_PAGES_DEF; static int tcmu_set_global_max_data_area(const char *str, const struct kernel_param *kp) @@ -237,8 +237,8 @@ static int tcmu_set_global_max_data_area(const char *str, return -EINVAL; } - tcmu_global_max_blocks = TCMU_MBS_TO_BLOCKS(max_area_mb); - if (atomic_read(&global_db_count) > tcmu_global_max_blocks) + tcmu_global_max_pages = TCMU_MBS_TO_PAGES(max_area_mb); + if (atomic_read(&global_page_count) > tcmu_global_max_pages) schedule_delayed_work(&tcmu_unmap_work, 0); else cancel_delayed_work_sync(&tcmu_unmap_work); @@ -249,7 +249,7 @@ static int tcmu_set_global_max_data_area(const char *str, static int tcmu_get_global_max_data_area(char *buffer, const struct kernel_param *kp) { - return sprintf(buffer, "%d\n", TCMU_BLOCKS_TO_MBS(tcmu_global_max_blocks)); + return sprintf(buffer, "%d\n", TCMU_PAGES_TO_MBS(tcmu_global_max_pages)); } static const struct kernel_param_ops tcmu_global_max_data_area_op = { @@ -510,10 +510,10 @@ static inline int tcmu_get_empty_block(struct tcmu_dev *udev, if (dbi == udev->dbi_thresh) return -1; - page = xa_load(&udev->data_blocks, dbi); + page = xa_load(&udev->data_pages, dbi); if (!page) { - if (atomic_add_return(1, &global_db_count) > - tcmu_global_max_blocks) + if (atomic_add_return(1, &global_page_count) > + tcmu_global_max_pages) schedule_delayed_work(&tcmu_unmap_work, 0); /* try to get new page from the mm */ @@ -521,7 +521,7 @@ static inline int tcmu_get_empty_block(struct tcmu_dev *udev, if (!page) goto err_alloc; - if (xa_store(&udev->data_blocks, dbi, page, GFP_NOIO)) + if (xa_store(&udev->data_pages, dbi, page, GFP_NOIO)) goto err_insert; } @@ -538,7 +538,7 @@ static inline int tcmu_get_empty_block(struct tcmu_dev *udev, err_insert: __free_page(page); err_alloc: - atomic_dec(&global_db_count); + atomic_dec(&global_page_count); return -1; } @@ -558,9 +558,9 @@ static int tcmu_get_empty_blocks(struct tcmu_dev *udev, } static inline struct page * -tcmu_get_block_page(struct tcmu_dev *udev, uint32_t dbi) +tcmu_get_block_page(struct tcmu_dev *udev, uint32_t dpi) { - return xa_load(&udev->data_blocks, dbi); + return xa_load(&udev->data_pages, dpi); } static inline void tcmu_free_cmd(struct tcmu_cmd *tcmu_cmd) @@ -1454,7 +1454,7 @@ static unsigned int tcmu_handle_completions(struct tcmu_dev *udev) if (free_space) free_space = tcmu_run_tmr_queue(udev); - if (atomic_read(&global_db_count) > tcmu_global_max_blocks && + if (atomic_read(&global_page_count) > tcmu_global_max_pages && xa_empty(&udev->commands) && list_empty(&udev->qfull_queue)) { /* * Allocated blocks exceeded global block limit, currently no @@ -1583,7 +1583,7 @@ static struct se_device *tcmu_alloc_device(struct se_hba *hba, const char *name) timer_setup(&udev->qfull_timer, tcmu_qfull_timedout, 0); timer_setup(&udev->cmd_timer, tcmu_cmd_timedout, 0); - xa_init(&udev->data_blocks); + xa_init(&udev->data_pages); return &udev->se_dev; } @@ -1617,7 +1617,7 @@ static void tcmu_blocks_release(struct xarray *blocks, unsigned long first, xas_for_each(&xas, page, last) { xas_store(&xas, NULL); __free_page(page); - atomic_dec(&global_db_count); + atomic_dec(&global_page_count); } xas_unlock(&xas); } @@ -1661,7 +1661,7 @@ static void tcmu_dev_kref_release(struct kref *kref) xa_destroy(&udev->commands); WARN_ON(!all_expired); - tcmu_blocks_release(&udev->data_blocks, 0, udev->dbi_max); + tcmu_blocks_release(&udev->data_pages, 0, udev->dbi_max); bitmap_free(udev->data_bitmap); mutex_unlock(&udev->cmdr_lock); @@ -1759,12 +1759,12 @@ static int tcmu_find_mem_index(struct vm_area_struct *vma) return -1; } -static struct page *tcmu_try_get_block_page(struct tcmu_dev *udev, uint32_t dbi) +static struct page *tcmu_try_get_data_page(struct tcmu_dev *udev, uint32_t dpi) { struct page *page; mutex_lock(&udev->cmdr_lock); - page = tcmu_get_block_page(udev, dbi); + page = tcmu_get_block_page(udev, dpi); if (likely(page)) { mutex_unlock(&udev->cmdr_lock); return page; @@ -1774,12 +1774,11 @@ static struct page *tcmu_try_get_block_page(struct tcmu_dev *udev, uint32_t dbi) * Userspace messed up and passed in a address not in the * data iov passed to it. */ - pr_err("Invalid addr to data block mapping (dbi %u) on device %s\n", - dbi, udev->name); - page = NULL; + pr_err("Invalid addr to data page mapping (dpi %u) on device %s\n", + dpi, udev->name); mutex_unlock(&udev->cmdr_lock); - return page; + return NULL; } static void tcmu_vma_open(struct vm_area_struct *vma) @@ -1824,11 +1823,11 @@ static vm_fault_t tcmu_vma_fault(struct vm_fault *vmf) addr = (void *)(unsigned long)info->mem[mi].addr + offset; page = vmalloc_to_page(addr); } else { - uint32_t dbi; + uint32_t dpi; /* For the dynamically growing data area pages */ - dbi = (offset - udev->data_off) / DATA_BLOCK_SIZE; - page = tcmu_try_get_block_page(udev, dbi); + dpi = (offset - udev->data_off) / PAGE_SIZE; + page = tcmu_try_get_data_page(udev, dpi); if (!page) return VM_FAULT_SIGBUS; } @@ -2344,7 +2343,7 @@ static int tcmu_set_dev_attrib(substring_t *arg, u32 *dev_attrib) static int tcmu_set_max_blocks_param(struct tcmu_dev *udev, substring_t *arg) { - int val, ret; + int val, ret, blks; ret = match_int(arg, &val); if (ret < 0) { @@ -2353,7 +2352,8 @@ static int tcmu_set_max_blocks_param(struct tcmu_dev *udev, substring_t *arg) return ret; } - if (val <= 0) { + blks = TCMU_MBS_TO_PAGES(val) / DATA_PAGES_PER_BLK; + if (blks <= 0) { pr_err("Invalid max_data_area %d.\n", val); return -EINVAL; } @@ -2365,11 +2365,11 @@ static int tcmu_set_max_blocks_param(struct tcmu_dev *udev, substring_t *arg) goto unlock; } - udev->max_blocks = TCMU_MBS_TO_BLOCKS(val); - if (udev->max_blocks > tcmu_global_max_blocks) { + udev->max_blocks = blks; + if (udev->max_blocks * DATA_PAGES_PER_BLK > tcmu_global_max_pages) { pr_err("%d is too large. Adjusting max_data_area_mb to global limit of %u\n", - val, TCMU_BLOCKS_TO_MBS(tcmu_global_max_blocks)); - udev->max_blocks = tcmu_global_max_blocks; + val, TCMU_PAGES_TO_MBS(tcmu_global_max_pages)); + udev->max_blocks = tcmu_global_max_pages / DATA_PAGES_PER_BLK; } unlock: @@ -2449,7 +2449,7 @@ static ssize_t tcmu_show_configfs_dev_params(struct se_device *dev, char *b) udev->dev_config[0] ? udev->dev_config : "NULL"); bl += sprintf(b + bl, "Size: %llu ", udev->dev_size); bl += sprintf(b + bl, "MaxDataAreaMB: %u\n", - TCMU_BLOCKS_TO_MBS(udev->max_blocks)); + TCMU_PAGES_TO_MBS(udev->max_blocks * DATA_PAGES_PER_BLK)); return bl; } @@ -2544,7 +2544,7 @@ static ssize_t tcmu_max_data_area_mb_show(struct config_item *item, char *page) struct tcmu_dev *udev = TCMU_DEV(da->da_dev); return snprintf(page, PAGE_SIZE, "%u\n", - TCMU_BLOCKS_TO_MBS(udev->max_blocks)); + TCMU_PAGES_TO_MBS(udev->max_blocks * DATA_PAGES_PER_BLK)); } CONFIGFS_ATTR_RO(tcmu_, max_data_area_mb); @@ -2904,7 +2904,7 @@ static void find_free_blocks(void) loff_t off; u32 start, end, block, total_freed = 0; - if (atomic_read(&global_db_count) <= tcmu_global_max_blocks) + if (atomic_read(&global_page_count) <= tcmu_global_max_pages) return; mutex_lock(&root_udev_mutex); @@ -2949,7 +2949,7 @@ static void find_free_blocks(void) unmap_mapping_range(udev->inode->i_mapping, off, 0, 1); /* Release the block pages */ - tcmu_blocks_release(&udev->data_blocks, start, end - 1); + tcmu_blocks_release(&udev->data_pages, start, end - 1); mutex_unlock(&udev->cmdr_lock); total_freed += end - start; @@ -2958,7 +2958,7 @@ static void find_free_blocks(void) } mutex_unlock(&root_udev_mutex); - if (atomic_read(&global_db_count) > tcmu_global_max_blocks) + if (atomic_read(&global_page_count) > tcmu_global_max_pages) schedule_delayed_work(&tcmu_unmap_work, msecs_to_jiffies(5000)); } From f5ce815f34bc97b92f5605eced806f1d32e1d602 Mon Sep 17 00:00:00 2001 From: Bodo Stroesser Date: Wed, 24 Mar 2021 20:57:55 +0100 Subject: [PATCH 326/412] scsi: target: tcmu: Support DATA_BLOCK_SIZE = N * PAGE_SIZE Change tcmu to support DATA_BLOCK_SIZE being a multiple of PAGE_SIZE. There are two reasons why one would like to have a bigger DATA_BLOCK_SIZE: 1) If userspace - e.g. due to data compression, encryption or deduplication - needs to have receive or transmit data in a consecutive buffer, we can define DATA_BLOCK_SIZE to the maximum size of a SCSI READ/WRITE to enforce that userspace sees just one consecutive buffer. That way we can avoid the need for doing data copy in userspace. 2) Using a bigger data block size can speed up command processing in tcmu. The number of free data blocks to look up in bitmap is reduced substantially. The lookup for data pages in radix_tree can be done more efficiently if there are multiple pages in a data block. The maximum number of IOVs to set up is lower so cmd entries in the ring become smaller. Link: https://lore.kernel.org/r/20210324195758.2021-4-bostroesser@gmail.com Signed-off-by: Bodo Stroesser Signed-off-by: Martin K. Petersen --- drivers/target/target_core_user.c | 203 +++++++++++++++++------------- 1 file changed, 115 insertions(+), 88 deletions(-) diff --git a/drivers/target/target_core_user.c b/drivers/target/target_core_user.c index f42d38873aaf..3596346f362e 100644 --- a/drivers/target/target_core_user.c +++ b/drivers/target/target_core_user.c @@ -67,14 +67,14 @@ #define CMDR_SIZE (MB_CMDR_SIZE - CMDR_OFF) /* - * For data area, the block size is PAGE_SIZE and - * the total size is 256K * PAGE_SIZE. + * For data area, the default block size is PAGE_SIZE and + * the default total size is 256K * PAGE_SIZE. */ -#define DATA_BLOCK_SIZE PAGE_SIZE #define DATA_PAGES_PER_BLK 1 -#define DATA_BLOCK_BITS_DEF (256 * 1024) +#define DATA_BLOCK_SIZE (DATA_PAGES_PER_BLK * PAGE_SIZE) +#define DATA_AREA_PAGES_DEF (256 * 1024) -#define TCMU_MBS_TO_PAGES(_mbs) (_mbs << (20 - PAGE_SHIFT)) +#define TCMU_MBS_TO_PAGES(_mbs) ((size_t)_mbs << (20 - PAGE_SHIFT)) #define TCMU_PAGES_TO_MBS(_pages) (_pages >> (20 - PAGE_SHIFT)) /* @@ -138,7 +138,7 @@ struct tcmu_dev { /* Offset of data area from start of mb */ /* Must add data_off and mb_addr to get the address */ size_t data_off; - size_t data_size; + int data_area_mb; uint32_t max_blocks; size_t mmap_pages; @@ -501,31 +501,39 @@ static void tcmu_cmd_free_data(struct tcmu_cmd *tcmu_cmd, uint32_t len) static inline int tcmu_get_empty_block(struct tcmu_dev *udev, struct tcmu_cmd *tcmu_cmd, - int prev_dbi, int *iov_cnt) + int prev_dbi, int length, int *iov_cnt) { + XA_STATE(xas, &udev->data_pages, 0); struct page *page; - int dbi; + int i, cnt, dbi; + int page_cnt = DIV_ROUND_UP(length, PAGE_SIZE); dbi = find_first_zero_bit(udev->data_bitmap, udev->dbi_thresh); if (dbi == udev->dbi_thresh) return -1; - page = xa_load(&udev->data_pages, dbi); - if (!page) { - if (atomic_add_return(1, &global_page_count) > - tcmu_global_max_pages) - schedule_delayed_work(&tcmu_unmap_work, 0); + /* Count the number of already allocated pages */ + xas_set(&xas, dbi * DATA_PAGES_PER_BLK); + for (cnt = 0; xas_next(&xas) && cnt < page_cnt;) + cnt++; + for (i = cnt; i < page_cnt; i++) { /* try to get new page from the mm */ page = alloc_page(GFP_NOIO); if (!page) - goto err_alloc; + break; - if (xa_store(&udev->data_pages, dbi, page, GFP_NOIO)) - goto err_insert; + if (xa_store(&udev->data_pages, dbi * DATA_PAGES_PER_BLK + i, + page, GFP_NOIO)) { + __free_page(page); + break; + } } + if (atomic_add_return(i - cnt, &global_page_count) > + tcmu_global_max_pages) + schedule_delayed_work(&tcmu_unmap_work, 0); - if (dbi > udev->dbi_max) + if (i && dbi > udev->dbi_max) udev->dbi_max = dbi; set_bit(dbi, udev->data_bitmap); @@ -534,23 +542,19 @@ static inline int tcmu_get_empty_block(struct tcmu_dev *udev, if (dbi != prev_dbi + 1) *iov_cnt += 1; - return dbi; -err_insert: - __free_page(page); -err_alloc: - atomic_dec(&global_page_count); - return -1; + return i == page_cnt ? dbi : -1; } static int tcmu_get_empty_blocks(struct tcmu_dev *udev, - struct tcmu_cmd *tcmu_cmd, int dbi_cnt) + struct tcmu_cmd *tcmu_cmd, int length) { /* start value of dbi + 1 must not be a valid dbi */ int dbi = -2; - int i, iov_cnt = 0; + int blk_len, iov_cnt = 0; - for (i = 0; i < dbi_cnt; i++) { - dbi = tcmu_get_empty_block(udev, tcmu_cmd, dbi, &iov_cnt); + for (; length > 0; length -= DATA_BLOCK_SIZE) { + blk_len = min_t(int, length, DATA_BLOCK_SIZE); + dbi = tcmu_get_empty_block(udev, tcmu_cmd, dbi, blk_len, &iov_cnt); if (dbi < 0) return -1; } @@ -698,9 +702,11 @@ static inline void tcmu_copy_data(struct tcmu_dev *udev, struct scatterlist *sg, unsigned int sg_nents, struct iovec **iov, size_t data_len) { + XA_STATE(xas, &udev->data_pages, 0); /* start value of dbi + 1 must not be a valid dbi */ int dbi = -2; - size_t block_remaining, cp_len; + size_t page_remaining, cp_len; + int page_cnt, page_inx; struct sg_mapping_iter sg_iter; unsigned int sg_flags; struct page *page; @@ -718,37 +724,48 @@ static inline void tcmu_copy_data(struct tcmu_dev *udev, data_len); else dbi = tcmu_cmd_get_dbi(tcmu_cmd); - page = tcmu_get_block_page(udev, dbi); - if (direction == TCMU_DATA_AREA_TO_SG) - flush_dcache_page(page); - data_page_start = kmap_atomic(page); - block_remaining = DATA_BLOCK_SIZE; - while (block_remaining && data_len) { - if (!sg_miter_next(&sg_iter)) { - /* set length to 0 to abort outer loop */ - data_len = 0; - pr_debug("tcmu_move_data: aborting data copy due to exhausted sg_list\n"); - break; + page_cnt = DIV_ROUND_UP(data_len, PAGE_SIZE); + if (page_cnt > DATA_PAGES_PER_BLK) + page_cnt = DATA_PAGES_PER_BLK; + + xas_set(&xas, dbi * DATA_PAGES_PER_BLK); + for (page_inx = 0; page_inx < page_cnt && data_len; page_inx++) { + page = xas_next(&xas); + + if (direction == TCMU_DATA_AREA_TO_SG) + flush_dcache_page(page); + data_page_start = kmap_atomic(page); + page_remaining = PAGE_SIZE; + + while (page_remaining && data_len) { + if (!sg_miter_next(&sg_iter)) { + /* set length to 0 to abort outer loop */ + data_len = 0; + pr_debug("%s: aborting data copy due to exhausted sg_list\n", + __func__); + break; + } + cp_len = min3(sg_iter.length, page_remaining, + data_len); + + data_addr = data_page_start + + PAGE_SIZE - page_remaining; + if (direction == TCMU_SG_TO_DATA_AREA) + memcpy(data_addr, sg_iter.addr, cp_len); + else + memcpy(sg_iter.addr, data_addr, cp_len); + + data_len -= cp_len; + page_remaining -= cp_len; + sg_iter.consumed = cp_len; } - cp_len = min3(sg_iter.length, block_remaining, data_len); + sg_miter_stop(&sg_iter); - data_addr = data_page_start + - DATA_BLOCK_SIZE - block_remaining; + kunmap_atomic(data_page_start); if (direction == TCMU_SG_TO_DATA_AREA) - memcpy(data_addr, sg_iter.addr, cp_len); - else - memcpy(sg_iter.addr, data_addr, cp_len); - - data_len -= cp_len; - block_remaining -= cp_len; - sg_iter.consumed = cp_len; + flush_dcache_page(page); } - sg_miter_stop(&sg_iter); - - kunmap_atomic(data_page_start); - if (direction == TCMU_SG_TO_DATA_AREA) - flush_dcache_page(page); } } @@ -858,13 +875,12 @@ static int tcmu_alloc_data_space(struct tcmu_dev *udev, struct tcmu_cmd *cmd, udev->dbi_thresh = udev->max_blocks; } - iov_cnt = tcmu_get_empty_blocks(udev, cmd, - cmd->dbi_cnt - cmd->dbi_bidi_cnt); + iov_cnt = tcmu_get_empty_blocks(udev, cmd, cmd->se_cmd->data_length); if (iov_cnt < 0) return -1; if (cmd->dbi_bidi_cnt) { - ret = tcmu_get_empty_blocks(udev, cmd, cmd->dbi_bidi_cnt); + ret = tcmu_get_empty_blocks(udev, cmd, cmd->data_len_bidi); if (ret < 0) return -1; } @@ -1020,9 +1036,9 @@ static int queue_cmd_ring(struct tcmu_cmd *tcmu_cmd, sense_reason_t *scsi_err) if (!list_empty(&udev->qfull_queue)) goto queue; - if (data_length > udev->data_size) { + if (data_length > udev->max_blocks * DATA_BLOCK_SIZE) { pr_warn("TCMU: Request of size %zu is too big for %zu data area\n", - data_length, udev->data_size); + data_length, udev->max_blocks * DATA_BLOCK_SIZE); *scsi_err = TCM_INVALID_CDB_FIELD; return -1; } @@ -1570,7 +1586,8 @@ static struct se_device *tcmu_alloc_device(struct se_hba *hba, const char *name) udev->cmd_time_out = TCMU_TIME_OUT; udev->qfull_time_out = -1; - udev->max_blocks = DATA_BLOCK_BITS_DEF; + udev->max_blocks = DATA_AREA_PAGES_DEF / DATA_PAGES_PER_BLK; + udev->data_area_mb = TCMU_PAGES_TO_MBS(DATA_AREA_PAGES_DEF); mutex_init(&udev->cmdr_lock); INIT_LIST_HEAD(&udev->node); @@ -1607,19 +1624,24 @@ static int tcmu_check_and_free_pending_cmd(struct tcmu_cmd *cmd) return -EINVAL; } -static void tcmu_blocks_release(struct xarray *blocks, unsigned long first, +static u32 tcmu_blocks_release(struct xarray *blocks, unsigned long first, unsigned long last) { - XA_STATE(xas, blocks, first); + XA_STATE(xas, blocks, first * DATA_PAGES_PER_BLK); struct page *page; + u32 pages_freed = 0; xas_lock(&xas); - xas_for_each(&xas, page, last) { + xas_for_each(&xas, page, (last + 1) * DATA_PAGES_PER_BLK - 1) { xas_store(&xas, NULL); __free_page(page); - atomic_dec(&global_page_count); + pages_freed++; } xas_unlock(&xas); + + atomic_sub(pages_freed, &global_page_count); + + return pages_freed; } static void tcmu_remove_all_queued_tmr(struct tcmu_dev *udev) @@ -2086,6 +2108,7 @@ static int tcmu_configure_device(struct se_device *dev) struct tcmu_dev *udev = TCMU_DEV(dev); struct uio_info *info; struct tcmu_mailbox *mb; + size_t data_size; int ret = 0; ret = tcmu_update_uio_info(udev); @@ -2113,8 +2136,8 @@ static int tcmu_configure_device(struct se_device *dev) udev->cmdr = (void *)mb + CMDR_OFF; udev->cmdr_size = CMDR_SIZE; udev->data_off = MB_CMDR_SIZE; - udev->data_size = udev->max_blocks * DATA_BLOCK_SIZE; - udev->mmap_pages = (udev->data_size + MB_CMDR_SIZE) >> PAGE_SHIFT; + data_size = TCMU_MBS_TO_PAGES(udev->data_area_mb) << PAGE_SHIFT; + udev->mmap_pages = (data_size + MB_CMDR_SIZE) >> PAGE_SHIFT; udev->dbi_thresh = 0; /* Default in Idle state */ /* Initialise the mailbox of the ring buffer */ @@ -2126,14 +2149,13 @@ static int tcmu_configure_device(struct se_device *dev) mb->cmdr_size = udev->cmdr_size; WARN_ON(!PAGE_ALIGNED(udev->data_off)); - WARN_ON(udev->data_size % PAGE_SIZE); - WARN_ON(udev->data_size % DATA_BLOCK_SIZE); + WARN_ON(data_size % PAGE_SIZE); info->version = __stringify(TCMU_MAILBOX_VERSION); info->mem[0].name = "tcm-user command & data buffer"; info->mem[0].addr = (phys_addr_t)(uintptr_t)udev->mb_addr; - info->mem[0].size = udev->data_size + MB_CMDR_SIZE; + info->mem[0].size = data_size + MB_CMDR_SIZE; info->mem[0].memtype = UIO_MEM_NONE; info->irqcontrol = tcmu_irqcontrol; @@ -2343,7 +2365,7 @@ static int tcmu_set_dev_attrib(substring_t *arg, u32 *dev_attrib) static int tcmu_set_max_blocks_param(struct tcmu_dev *udev, substring_t *arg) { - int val, ret, blks; + int val, ret; ret = match_int(arg, &val); if (ret < 0) { @@ -2351,12 +2373,20 @@ static int tcmu_set_max_blocks_param(struct tcmu_dev *udev, substring_t *arg) ret); return ret; } - - blks = TCMU_MBS_TO_PAGES(val) / DATA_PAGES_PER_BLK; - if (blks <= 0) { + if (val <= 0) { pr_err("Invalid max_data_area %d.\n", val); return -EINVAL; } + if (val > TCMU_PAGES_TO_MBS(tcmu_global_max_pages)) { + pr_err("%d is too large. Adjusting max_data_area_mb to global limit of %u\n", + val, TCMU_PAGES_TO_MBS(tcmu_global_max_pages)); + val = TCMU_PAGES_TO_MBS(tcmu_global_max_pages); + } + if (TCMU_MBS_TO_PAGES(val) < DATA_PAGES_PER_BLK) { + pr_err("Invalid max_data_area %d (%zu pages): smaller than data_pages_per_blk (%d pages).\n", + val, TCMU_MBS_TO_PAGES(val), DATA_PAGES_PER_BLK); + return -EINVAL; + } mutex_lock(&udev->cmdr_lock); if (udev->data_bitmap) { @@ -2365,12 +2395,8 @@ static int tcmu_set_max_blocks_param(struct tcmu_dev *udev, substring_t *arg) goto unlock; } - udev->max_blocks = blks; - if (udev->max_blocks * DATA_PAGES_PER_BLK > tcmu_global_max_pages) { - pr_err("%d is too large. Adjusting max_data_area_mb to global limit of %u\n", - val, TCMU_PAGES_TO_MBS(tcmu_global_max_pages)); - udev->max_blocks = tcmu_global_max_pages / DATA_PAGES_PER_BLK; - } + udev->data_area_mb = val; + udev->max_blocks = TCMU_MBS_TO_PAGES(val) / DATA_PAGES_PER_BLK; unlock: mutex_unlock(&udev->cmdr_lock); @@ -2448,8 +2474,7 @@ static ssize_t tcmu_show_configfs_dev_params(struct se_device *dev, char *b) bl = sprintf(b + bl, "Config: %s ", udev->dev_config[0] ? udev->dev_config : "NULL"); bl += sprintf(b + bl, "Size: %llu ", udev->dev_size); - bl += sprintf(b + bl, "MaxDataAreaMB: %u\n", - TCMU_PAGES_TO_MBS(udev->max_blocks * DATA_PAGES_PER_BLK)); + bl += sprintf(b + bl, "MaxDataAreaMB: %u\n", udev->data_area_mb); return bl; } @@ -2543,8 +2568,7 @@ static ssize_t tcmu_max_data_area_mb_show(struct config_item *item, char *page) struct se_dev_attrib, da_group); struct tcmu_dev *udev = TCMU_DEV(da->da_dev); - return snprintf(page, PAGE_SIZE, "%u\n", - TCMU_PAGES_TO_MBS(udev->max_blocks * DATA_PAGES_PER_BLK)); + return snprintf(page, PAGE_SIZE, "%u\n", udev->data_area_mb); } CONFIGFS_ATTR_RO(tcmu_, max_data_area_mb); @@ -2902,7 +2926,8 @@ static void find_free_blocks(void) { struct tcmu_dev *udev; loff_t off; - u32 start, end, block, total_freed = 0; + u32 pages_freed, total_pages_freed = 0; + u32 start, end, block, total_blocks_freed = 0; if (atomic_read(&global_page_count) <= tcmu_global_max_pages) return; @@ -2949,12 +2974,14 @@ static void find_free_blocks(void) unmap_mapping_range(udev->inode->i_mapping, off, 0, 1); /* Release the block pages */ - tcmu_blocks_release(&udev->data_pages, start, end - 1); + pages_freed = tcmu_blocks_release(&udev->data_pages, start, end - 1); mutex_unlock(&udev->cmdr_lock); - total_freed += end - start; - pr_debug("Freed %u blocks (total %u) from %s.\n", end - start, - total_freed, udev->name); + total_pages_freed += pages_freed; + total_blocks_freed += end - start; + pr_debug("Freed %u pages (total %u) from %u blocks (total %u) from %s.\n", + pages_freed, total_pages_freed, end - start, + total_blocks_freed, udev->name); } mutex_unlock(&root_udev_mutex); From 3722e36c4ea4b9e39fe468dd1776b43c61a0c459 Mon Sep 17 00:00:00 2001 From: Bodo Stroesser Date: Wed, 24 Mar 2021 20:57:56 +0100 Subject: [PATCH 327/412] scsi: target: tcmu: Remove function tcmu_get_block_page() There is only one caller of tcmu_get_block_page left. Since it is a one-liner, we can remove the function. Link: https://lore.kernel.org/r/20210324195758.2021-5-bostroesser@gmail.com Signed-off-by: Bodo Stroesser Signed-off-by: Martin K. Petersen --- drivers/target/target_core_user.c | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/drivers/target/target_core_user.c b/drivers/target/target_core_user.c index 3596346f362e..9b2bff450510 100644 --- a/drivers/target/target_core_user.c +++ b/drivers/target/target_core_user.c @@ -561,12 +561,6 @@ static int tcmu_get_empty_blocks(struct tcmu_dev *udev, return iov_cnt; } -static inline struct page * -tcmu_get_block_page(struct tcmu_dev *udev, uint32_t dpi) -{ - return xa_load(&udev->data_pages, dpi); -} - static inline void tcmu_free_cmd(struct tcmu_cmd *tcmu_cmd) { kfree(tcmu_cmd->dbi); @@ -1786,7 +1780,7 @@ static struct page *tcmu_try_get_data_page(struct tcmu_dev *udev, uint32_t dpi) struct page *page; mutex_lock(&udev->cmdr_lock); - page = tcmu_get_block_page(udev, dpi); + page = xa_load(&udev->data_pages, dpi); if (likely(page)) { mutex_unlock(&udev->cmdr_lock); return page; From e719afdcf6911425c404ec50403a9aa116b2b616 Mon Sep 17 00:00:00 2001 From: Bodo Stroesser Date: Wed, 24 Mar 2021 20:57:57 +0100 Subject: [PATCH 328/412] scsi: target: tcmu: Replace block size definitions with new udev members Replace DATA_PAGES_PER_BLK and DATA_BLOCK_SIZE with new struct elements tcmu_dev->data_pages_per_blk and tcmu_dev->data_blk_size. These new variables are still loaded with constant definition DATA_PAGES_PER_BLK_DEF (= 1) and DATA_PAGES_PER_BLK_DEF * PAGE_SIZE. There is no way yet to set the values via configfs. Link: https://lore.kernel.org/r/20210324195758.2021-6-bostroesser@gmail.com Signed-off-by: Bodo Stroesser Signed-off-by: Martin K. Petersen --- drivers/target/target_core_user.c | 82 +++++++++++++++++-------------- 1 file changed, 45 insertions(+), 37 deletions(-) diff --git a/drivers/target/target_core_user.c b/drivers/target/target_core_user.c index 9b2bff450510..3de66db06438 100644 --- a/drivers/target/target_core_user.c +++ b/drivers/target/target_core_user.c @@ -70,8 +70,7 @@ * For data area, the default block size is PAGE_SIZE and * the default total size is 256K * PAGE_SIZE. */ -#define DATA_PAGES_PER_BLK 1 -#define DATA_BLOCK_SIZE (DATA_PAGES_PER_BLK * PAGE_SIZE) +#define DATA_PAGES_PER_BLK_DEF 1 #define DATA_AREA_PAGES_DEF (256 * 1024) #define TCMU_MBS_TO_PAGES(_mbs) ((size_t)_mbs << (20 - PAGE_SHIFT)) @@ -150,6 +149,8 @@ struct tcmu_dev { uint32_t dbi_thresh; unsigned long *data_bitmap; struct xarray data_pages; + uint32_t data_pages_per_blk; + uint32_t data_blk_size; struct xarray commands; @@ -505,15 +506,16 @@ static inline int tcmu_get_empty_block(struct tcmu_dev *udev, { XA_STATE(xas, &udev->data_pages, 0); struct page *page; - int i, cnt, dbi; + int i, cnt, dbi, dpi; int page_cnt = DIV_ROUND_UP(length, PAGE_SIZE); dbi = find_first_zero_bit(udev->data_bitmap, udev->dbi_thresh); if (dbi == udev->dbi_thresh) return -1; + dpi = dbi * udev->data_pages_per_blk; /* Count the number of already allocated pages */ - xas_set(&xas, dbi * DATA_PAGES_PER_BLK); + xas_set(&xas, dpi); for (cnt = 0; xas_next(&xas) && cnt < page_cnt;) cnt++; @@ -523,8 +525,7 @@ static inline int tcmu_get_empty_block(struct tcmu_dev *udev, if (!page) break; - if (xa_store(&udev->data_pages, dbi * DATA_PAGES_PER_BLK + i, - page, GFP_NOIO)) { + if (xa_store(&udev->data_pages, dpi + i, page, GFP_NOIO)) { __free_page(page); break; } @@ -550,11 +551,13 @@ static int tcmu_get_empty_blocks(struct tcmu_dev *udev, { /* start value of dbi + 1 must not be a valid dbi */ int dbi = -2; - int blk_len, iov_cnt = 0; + int blk_data_len, iov_cnt = 0; + uint32_t blk_size = udev->data_blk_size; - for (; length > 0; length -= DATA_BLOCK_SIZE) { - blk_len = min_t(int, length, DATA_BLOCK_SIZE); - dbi = tcmu_get_empty_block(udev, tcmu_cmd, dbi, blk_len, &iov_cnt); + for (; length > 0; length -= blk_size) { + blk_data_len = min_t(uint32_t, length, blk_size); + dbi = tcmu_get_empty_block(udev, tcmu_cmd, dbi, blk_data_len, + &iov_cnt); if (dbi < 0) return -1; } @@ -571,14 +574,15 @@ static inline void tcmu_cmd_set_block_cnts(struct tcmu_cmd *cmd) { int i, len; struct se_cmd *se_cmd = cmd->se_cmd; + uint32_t blk_size = cmd->tcmu_dev->data_blk_size; - cmd->dbi_cnt = DIV_ROUND_UP(se_cmd->data_length, DATA_BLOCK_SIZE); + cmd->dbi_cnt = DIV_ROUND_UP(se_cmd->data_length, blk_size); if (se_cmd->se_cmd_flags & SCF_BIDI) { BUG_ON(!(se_cmd->t_bidi_data_sg && se_cmd->t_bidi_data_nents)); for (i = 0, len = 0; i < se_cmd->t_bidi_data_nents; i++) len += se_cmd->t_bidi_data_sg[i].length; - cmd->dbi_bidi_cnt = DIV_ROUND_UP(len, DATA_BLOCK_SIZE); + cmd->dbi_bidi_cnt = DIV_ROUND_UP(len, blk_size); cmd->dbi_cnt += cmd->dbi_bidi_cnt; cmd->data_len_bidi = len; } @@ -590,9 +594,8 @@ static int new_block_to_iov(struct tcmu_dev *udev, struct tcmu_cmd *cmd, /* Get the next dbi */ int dbi = tcmu_cmd_get_dbi(cmd); - /* Do not add more than DATA_BLOCK_SIZE to iov */ - if (len > DATA_BLOCK_SIZE) - len = DATA_BLOCK_SIZE; + /* Do not add more than udev->data_blk_size to iov */ + len = min_t(int, len, udev->data_blk_size); /* * The following code will gather and map the blocks to the same iovec @@ -604,7 +607,7 @@ static int new_block_to_iov(struct tcmu_dev *udev, struct tcmu_cmd *cmd, (*iov)++; /* write offset relative to mb_addr */ (*iov)->iov_base = (void __user *) - (udev->data_off + dbi * DATA_BLOCK_SIZE); + (udev->data_off + dbi * udev->data_blk_size); } (*iov)->iov_len += len; @@ -618,7 +621,7 @@ static void tcmu_setup_iovs(struct tcmu_dev *udev, struct tcmu_cmd *cmd, int dbi = -2; /* We prepare the IOVs for DMA_FROM_DEVICE transfer direction */ - for (; data_length > 0; data_length -= DATA_BLOCK_SIZE) + for (; data_length > 0; data_length -= udev->data_blk_size) dbi = new_block_to_iov(udev, cmd, iov, dbi, data_length); } @@ -720,10 +723,10 @@ static inline void tcmu_copy_data(struct tcmu_dev *udev, dbi = tcmu_cmd_get_dbi(tcmu_cmd); page_cnt = DIV_ROUND_UP(data_len, PAGE_SIZE); - if (page_cnt > DATA_PAGES_PER_BLK) - page_cnt = DATA_PAGES_PER_BLK; + if (page_cnt > udev->data_pages_per_blk) + page_cnt = udev->data_pages_per_blk; - xas_set(&xas, dbi * DATA_PAGES_PER_BLK); + xas_set(&xas, dbi * udev->data_pages_per_blk); for (page_inx = 0; page_inx < page_cnt && data_len; page_inx++) { page = xas_next(&xas); @@ -858,9 +861,9 @@ static int tcmu_alloc_data_space(struct tcmu_dev *udev, struct tcmu_cmd *cmd, (udev->max_blocks - udev->dbi_thresh) + space; if (blocks_left < cmd->dbi_cnt) { - pr_debug("no data space: only %lu available, but ask for %lu\n", - blocks_left * DATA_BLOCK_SIZE, - cmd->dbi_cnt * DATA_BLOCK_SIZE); + pr_debug("no data space: only %lu available, but ask for %u\n", + blocks_left * udev->data_blk_size, + cmd->dbi_cnt * udev->data_blk_size); return -1; } @@ -1012,8 +1015,9 @@ static int queue_cmd_ring(struct tcmu_cmd *tcmu_cmd, sense_reason_t *scsi_err) int iov_cnt, iov_bidi_cnt; uint32_t cmd_id, cmd_head; uint64_t cdb_off; + uint32_t blk_size = udev->data_blk_size; /* size of data buffer needed */ - size_t data_length = (size_t)tcmu_cmd->dbi_cnt * DATA_BLOCK_SIZE; + size_t data_length = (size_t)tcmu_cmd->dbi_cnt * blk_size; *scsi_err = TCM_NO_SENSE; @@ -1030,9 +1034,9 @@ static int queue_cmd_ring(struct tcmu_cmd *tcmu_cmd, sense_reason_t *scsi_err) if (!list_empty(&udev->qfull_queue)) goto queue; - if (data_length > udev->max_blocks * DATA_BLOCK_SIZE) { + if (data_length > (size_t)udev->max_blocks * blk_size) { pr_warn("TCMU: Request of size %zu is too big for %zu data area\n", - data_length, udev->max_blocks * DATA_BLOCK_SIZE); + data_length, (size_t)udev->max_blocks * blk_size); *scsi_err = TCM_INVALID_CDB_FIELD; return -1; } @@ -1580,8 +1584,10 @@ static struct se_device *tcmu_alloc_device(struct se_hba *hba, const char *name) udev->cmd_time_out = TCMU_TIME_OUT; udev->qfull_time_out = -1; - udev->max_blocks = DATA_AREA_PAGES_DEF / DATA_PAGES_PER_BLK; + udev->data_pages_per_blk = DATA_PAGES_PER_BLK_DEF; + udev->max_blocks = DATA_AREA_PAGES_DEF / udev->data_pages_per_blk; udev->data_area_mb = TCMU_PAGES_TO_MBS(DATA_AREA_PAGES_DEF); + mutex_init(&udev->cmdr_lock); INIT_LIST_HEAD(&udev->node); @@ -1618,15 +1624,15 @@ static int tcmu_check_and_free_pending_cmd(struct tcmu_cmd *cmd) return -EINVAL; } -static u32 tcmu_blocks_release(struct xarray *blocks, unsigned long first, +static u32 tcmu_blocks_release(struct tcmu_dev *udev, unsigned long first, unsigned long last) { - XA_STATE(xas, blocks, first * DATA_PAGES_PER_BLK); + XA_STATE(xas, &udev->data_pages, first * udev->data_pages_per_blk); struct page *page; u32 pages_freed = 0; xas_lock(&xas); - xas_for_each(&xas, page, (last + 1) * DATA_PAGES_PER_BLK - 1) { + xas_for_each(&xas, page, (last + 1) * udev->data_pages_per_blk - 1) { xas_store(&xas, NULL); __free_page(page); pages_freed++; @@ -1677,7 +1683,7 @@ static void tcmu_dev_kref_release(struct kref *kref) xa_destroy(&udev->commands); WARN_ON(!all_expired); - tcmu_blocks_release(&udev->data_pages, 0, udev->dbi_max); + tcmu_blocks_release(udev, 0, udev->dbi_max); bitmap_free(udev->data_bitmap); mutex_unlock(&udev->cmdr_lock); @@ -2132,6 +2138,7 @@ static int tcmu_configure_device(struct se_device *dev) udev->data_off = MB_CMDR_SIZE; data_size = TCMU_MBS_TO_PAGES(udev->data_area_mb) << PAGE_SHIFT; udev->mmap_pages = (data_size + MB_CMDR_SIZE) >> PAGE_SHIFT; + udev->data_blk_size = udev->data_pages_per_blk * PAGE_SIZE; udev->dbi_thresh = 0; /* Default in Idle state */ /* Initialise the mailbox of the ring buffer */ @@ -2360,6 +2367,7 @@ static int tcmu_set_dev_attrib(substring_t *arg, u32 *dev_attrib) static int tcmu_set_max_blocks_param(struct tcmu_dev *udev, substring_t *arg) { int val, ret; + uint32_t pages_per_blk = udev->data_pages_per_blk; ret = match_int(arg, &val); if (ret < 0) { @@ -2376,9 +2384,9 @@ static int tcmu_set_max_blocks_param(struct tcmu_dev *udev, substring_t *arg) val, TCMU_PAGES_TO_MBS(tcmu_global_max_pages)); val = TCMU_PAGES_TO_MBS(tcmu_global_max_pages); } - if (TCMU_MBS_TO_PAGES(val) < DATA_PAGES_PER_BLK) { - pr_err("Invalid max_data_area %d (%zu pages): smaller than data_pages_per_blk (%d pages).\n", - val, TCMU_MBS_TO_PAGES(val), DATA_PAGES_PER_BLK); + if (TCMU_MBS_TO_PAGES(val) < pages_per_blk) { + pr_err("Invalid max_data_area %d (%zu pages): smaller than data_pages_per_blk (%u pages).\n", + val, TCMU_MBS_TO_PAGES(val), pages_per_blk); return -EINVAL; } @@ -2390,7 +2398,7 @@ static int tcmu_set_max_blocks_param(struct tcmu_dev *udev, substring_t *arg) } udev->data_area_mb = val; - udev->max_blocks = TCMU_MBS_TO_PAGES(val) / DATA_PAGES_PER_BLK; + udev->max_blocks = TCMU_MBS_TO_PAGES(val) / pages_per_blk; unlock: mutex_unlock(&udev->cmdr_lock); @@ -2964,11 +2972,11 @@ static void find_free_blocks(void) } /* Here will truncate the data area from off */ - off = udev->data_off + start * DATA_BLOCK_SIZE; + off = udev->data_off + (loff_t)start * udev->data_blk_size; unmap_mapping_range(udev->inode->i_mapping, off, 0, 1); /* Release the block pages */ - pages_freed = tcmu_blocks_release(&udev->data_pages, start, end - 1); + pages_freed = tcmu_blocks_release(udev, start, end - 1); mutex_unlock(&udev->cmdr_lock); total_pages_freed += pages_freed; From 08976cb548d67d8a492d75c9202fde28e21915e2 Mon Sep 17 00:00:00 2001 From: Bodo Stroesser Date: Wed, 24 Mar 2021 20:57:58 +0100 Subject: [PATCH 329/412] scsi: target: tcmu: Make data_pages_per_blk changeable via configfs Make data_pages_per_blk changeable similar to the way it is done for max_data_area_mb. One can change the value by typing: echo "data_pages_per_blk=N" >control The value is printed when doing: cat info In addition, a new readonly attribute 'data_pages_per_blk' returns the value on read. Link: https://lore.kernel.org/r/20210324195758.2021-7-bostroesser@gmail.com Signed-off-by: Bodo Stroesser Signed-off-by: Martin K. Petersen --- drivers/target/target_core_user.c | 55 +++++++++++++++++++++++++++++-- 1 file changed, 53 insertions(+), 2 deletions(-) diff --git a/drivers/target/target_core_user.c b/drivers/target/target_core_user.c index 3de66db06438..eec2fd573e2b 100644 --- a/drivers/target/target_core_user.c +++ b/drivers/target/target_core_user.c @@ -2331,7 +2331,8 @@ static void tcmu_reset_ring(struct tcmu_dev *udev, u8 err_level) enum { Opt_dev_config, Opt_dev_size, Opt_hw_block_size, Opt_hw_max_sectors, - Opt_nl_reply_supported, Opt_max_data_area_mb, Opt_err, + Opt_nl_reply_supported, Opt_max_data_area_mb, Opt_data_pages_per_blk, + Opt_err, }; static match_table_t tokens = { @@ -2341,6 +2342,7 @@ static match_table_t tokens = { {Opt_hw_max_sectors, "hw_max_sectors=%d"}, {Opt_nl_reply_supported, "nl_reply_supported=%d"}, {Opt_max_data_area_mb, "max_data_area_mb=%d"}, + {Opt_data_pages_per_blk, "data_pages_per_blk=%d"}, {Opt_err, NULL} }; @@ -2405,6 +2407,39 @@ unlock: return ret; } +static int tcmu_set_data_pages_per_blk(struct tcmu_dev *udev, substring_t *arg) +{ + int val, ret; + + ret = match_int(arg, &val); + if (ret < 0) { + pr_err("match_int() failed for data_pages_per_blk=. Error %d.\n", + ret); + return ret; + } + + if (val > TCMU_MBS_TO_PAGES(udev->data_area_mb)) { + pr_err("Invalid data_pages_per_blk %d: greater than max_data_area_mb %d -> %zd pages).\n", + val, udev->data_area_mb, + TCMU_MBS_TO_PAGES(udev->data_area_mb)); + return -EINVAL; + } + + mutex_lock(&udev->cmdr_lock); + if (udev->data_bitmap) { + pr_err("Cannot set data_pages_per_blk after it has been enabled.\n"); + ret = -EINVAL; + goto unlock; + } + + udev->data_pages_per_blk = val; + udev->max_blocks = TCMU_MBS_TO_PAGES(udev->data_area_mb) / val; + +unlock: + mutex_unlock(&udev->cmdr_lock); + return ret; +} + static ssize_t tcmu_set_configfs_dev_params(struct se_device *dev, const char *page, ssize_t count) { @@ -2456,6 +2491,9 @@ static ssize_t tcmu_set_configfs_dev_params(struct se_device *dev, case Opt_max_data_area_mb: ret = tcmu_set_max_blocks_param(udev, &args[0]); break; + case Opt_data_pages_per_blk: + ret = tcmu_set_data_pages_per_blk(udev, &args[0]); + break; default: break; } @@ -2476,7 +2514,8 @@ static ssize_t tcmu_show_configfs_dev_params(struct se_device *dev, char *b) bl = sprintf(b + bl, "Config: %s ", udev->dev_config[0] ? udev->dev_config : "NULL"); bl += sprintf(b + bl, "Size: %llu ", udev->dev_size); - bl += sprintf(b + bl, "MaxDataAreaMB: %u\n", udev->data_area_mb); + bl += sprintf(b + bl, "MaxDataAreaMB: %u ", udev->data_area_mb); + bl += sprintf(b + bl, "DataPagesPerBlk: %u\n", udev->data_pages_per_blk); return bl; } @@ -2574,6 +2613,17 @@ static ssize_t tcmu_max_data_area_mb_show(struct config_item *item, char *page) } CONFIGFS_ATTR_RO(tcmu_, max_data_area_mb); +static ssize_t tcmu_data_pages_per_blk_show(struct config_item *item, + char *page) +{ + struct se_dev_attrib *da = container_of(to_config_group(item), + struct se_dev_attrib, da_group); + struct tcmu_dev *udev = TCMU_DEV(da->da_dev); + + return snprintf(page, PAGE_SIZE, "%u\n", udev->data_pages_per_blk); +} +CONFIGFS_ATTR_RO(tcmu_, data_pages_per_blk); + static ssize_t tcmu_dev_config_show(struct config_item *item, char *page) { struct se_dev_attrib *da = container_of(to_config_group(item), @@ -2885,6 +2935,7 @@ static struct configfs_attribute *tcmu_attrib_attrs[] = { &tcmu_attr_cmd_time_out, &tcmu_attr_qfull_time_out, &tcmu_attr_max_data_area_mb, + &tcmu_attr_data_pages_per_blk, &tcmu_attr_dev_config, &tcmu_attr_dev_size, &tcmu_attr_emulate_write_cache, From 3f744a14f331f56703a9d74e86520db045f11831 Mon Sep 17 00:00:00 2001 From: Igor Pylypiv Date: Tue, 6 Apr 2021 11:05:33 -0700 Subject: [PATCH 330/412] scsi: pm80xx: Increase timeout for pm80xx mpi_uninit_check() The mpi_uninit_check() takes longer for inbound doorbell register to be cleared. Increase the timeout substantially so that the driver does not fail to load. Previously, the inbound doorbell wait time was mistakenly increased in the mpi_init_check() instead of mpi_uninit_check(). It is okay to leave the mpi_init_check() wait time as-is as these are timeout values and if there is a failure, waiting longer is not an issue. Link: https://lore.kernel.org/r/20210406180534.1924345-2-ipylypiv@google.com Fixes: e90e236250e9 ("scsi: pm80xx: Increase timeout for pm80xx mpi_uninit_check") Reviewed-by: Vishakha Channapattan Acked-by: Jack Wang Signed-off-by: Igor Pylypiv Signed-off-by: Martin K. Petersen --- drivers/scsi/pm8001/pm80xx_hwi.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/scsi/pm8001/pm80xx_hwi.c b/drivers/scsi/pm8001/pm80xx_hwi.c index 74ed072209f4..92cb57de5f8d 100644 --- a/drivers/scsi/pm8001/pm80xx_hwi.c +++ b/drivers/scsi/pm8001/pm80xx_hwi.c @@ -1502,9 +1502,9 @@ static int mpi_uninit_check(struct pm8001_hba_info *pm8001_ha) /* wait until Inbound DoorBell Clear Register toggled */ if (IS_SPCV_12G(pm8001_ha->pdev)) { - max_wait_count = 4 * 1000 * 1000;/* 4 sec */ + max_wait_count = 30 * 1000 * 1000; /* 30 sec */ } else { - max_wait_count = 2 * 1000 * 1000;/* 2 sec */ + max_wait_count = 15 * 1000 * 1000; /* 15 sec */ } do { udelay(1); From 6f305bf699fe233ef27d80cc29fd1650423c8e74 Mon Sep 17 00:00:00 2001 From: Igor Pylypiv Date: Tue, 6 Apr 2021 11:05:34 -0700 Subject: [PATCH 331/412] scsi: pm80xx: Remove busy wait from mpi_uninit_check() mpi_uninit_check() is not being called in an atomic context. The only caller of mpi_uninit_check() is pm80xx_chip_soft_rst(). Callers of pm80xx_chip_soft_rst(): - pm8001_ioctl_soft_reset() - pm8001_pci_probe() - pm8001_pci_remove() - pm8001_pci_suspend() - pm8001_pci_resume() There was a similar fix for mpi_init_check() in commit d71023af4bec ("scsi: pm80xx: Do not busy wait in MPI init check") Link: https://lore.kernel.org/r/20210406180534.1924345-3-ipylypiv@google.com Reviewed-by: Vishakha Channapattan Acked-by: Jack Wang Signed-off-by: Igor Pylypiv Signed-off-by: Martin K. Petersen --- drivers/scsi/pm8001/pm80xx_hwi.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/drivers/scsi/pm8001/pm80xx_hwi.c b/drivers/scsi/pm8001/pm80xx_hwi.c index 92cb57de5f8d..42602d8d5ccf 100644 --- a/drivers/scsi/pm8001/pm80xx_hwi.c +++ b/drivers/scsi/pm8001/pm80xx_hwi.c @@ -1502,12 +1502,12 @@ static int mpi_uninit_check(struct pm8001_hba_info *pm8001_ha) /* wait until Inbound DoorBell Clear Register toggled */ if (IS_SPCV_12G(pm8001_ha->pdev)) { - max_wait_count = 30 * 1000 * 1000; /* 30 sec */ + max_wait_count = SPCV_DOORBELL_CLEAR_TIMEOUT; } else { - max_wait_count = 15 * 1000 * 1000; /* 15 sec */ + max_wait_count = SPC_DOORBELL_CLEAR_TIMEOUT; } do { - udelay(1); + msleep(FW_READY_INTERVAL); value = pm8001_cr32(pm8001_ha, 0, MSGU_IBDB_SET); value &= SPCv_MSGU_CFG_TABLE_RESET; } while ((value != 0) && (--max_wait_count)); @@ -1519,9 +1519,9 @@ static int mpi_uninit_check(struct pm8001_hba_info *pm8001_ha) /* check the MPI-State for termination in progress */ /* wait until Inbound DoorBell Clear Register toggled */ - max_wait_count = 2 * 1000 * 1000; /* 2 sec for spcv/ve */ + max_wait_count = 100; /* 2 sec for spcv/ve */ do { - udelay(1); + msleep(FW_READY_INTERVAL); gst_len_mpistate = pm8001_mr32(pm8001_ha->general_stat_tbl_addr, GST_GSTLEN_MPIS_OFFSET); From 40fa7394a1ad5706e795823276f2e394cca145d0 Mon Sep 17 00:00:00 2001 From: Colin Ian King Date: Wed, 7 Apr 2021 14:58:40 +0100 Subject: [PATCH 332/412] scsi: pm80xx: Fix potential infinite loop The for-loop iterates with a u8 loop counter i and compares this with the loop upper limit of pm8001_ha->max_q_num which is a u32 type. There is a potential infinite loop if pm8001_ha->max_q_num is larger than the u8 loop counter. Fix this by making the loop counter the same type as pm8001_ha->max_q_num. [mkp: this is purely theoretical, max_q_num is currently limited to 64] Link: https://lore.kernel.org/r/20210407135840.494747-1-colin.king@canonical.com Fixes: 65df7d1986a1 ("scsi: pm80xx: Fix chip initialization failure") Addresses-Coverity: ("Infinite loop") Reviewed-by: Johannes Thumshirn Signed-off-by: Colin Ian King Signed-off-by: Martin K. Petersen --- drivers/scsi/pm8001/pm8001_hwi.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/scsi/pm8001/pm8001_hwi.c b/drivers/scsi/pm8001/pm8001_hwi.c index d048455f4941..16edd84e7130 100644 --- a/drivers/scsi/pm8001/pm8001_hwi.c +++ b/drivers/scsi/pm8001/pm8001_hwi.c @@ -643,7 +643,7 @@ static void init_pci_device_addresses(struct pm8001_hba_info *pm8001_ha) */ static int pm8001_chip_init(struct pm8001_hba_info *pm8001_ha) { - u8 i = 0; + u32 i = 0; u16 deviceid; pci_read_config_word(pm8001_ha->pdev, PCI_DEVICE_ID, &deviceid); /* 8081 controllers need BAR shift to access MPI space From 8a23dbc600895694b7deb4302b735f2b8d274a5d Mon Sep 17 00:00:00 2001 From: Luo Jiaxing Date: Thu, 8 Apr 2021 20:56:32 +0800 Subject: [PATCH 333/412] scsi: pm8001: Clean up white space checkpatch reports the following: ERROR: space prohibited before that ',' (ctx:WxW) +int pm8001_mpi_general_event(struct pm8001_hba_info *pm8001_ha , void *piomb); Remove unnecessary whitespace. Link: https://lore.kernel.org/r/1617886593-36421-2-git-send-email-luojiaxing@huawei.com Acked-by: Jack Wang Signed-off-by: Luo Jiaxing Signed-off-by: Jianqin Xie Signed-off-by: Martin K. Petersen --- drivers/scsi/pm8001/pm8001_ctl.c | 20 +++++++++----------- drivers/scsi/pm8001/pm8001_ctl.h | 5 +++++ drivers/scsi/pm8001/pm8001_hwi.c | 14 +++++++------- drivers/scsi/pm8001/pm8001_sas.c | 20 ++++++++++---------- drivers/scsi/pm8001/pm8001_sas.h | 2 +- drivers/scsi/pm8001/pm80xx_hwi.c | 14 +++++++------- 6 files changed, 39 insertions(+), 36 deletions(-) diff --git a/drivers/scsi/pm8001/pm8001_ctl.c b/drivers/scsi/pm8001/pm8001_ctl.c index 1921e69bc232..8c1711e2d5bb 100644 --- a/drivers/scsi/pm8001/pm8001_ctl.c +++ b/drivers/scsi/pm8001/pm8001_ctl.c @@ -369,24 +369,22 @@ static ssize_t pm8001_ctl_aap_log_show(struct device *cdev, struct Scsi_Host *shost = class_to_shost(cdev); struct sas_ha_struct *sha = SHOST_TO_SAS_HA(shost); struct pm8001_hba_info *pm8001_ha = sha->lldd_ha; + u8 *ptr = (u8 *)pm8001_ha->memoryMap.region[AAP1].virt_ptr; int i; -#define AAP1_MEMMAP(r, c) \ - (*(u32 *)((u8*)pm8001_ha->memoryMap.region[AAP1].virt_ptr + (r) * 32 \ - + (c))) char *str = buf; int max = 2; for (i = 0; i < max; i++) { str += sprintf(str, "0x%08x 0x%08x 0x%08x 0x%08x 0x%08x 0x%08x" "0x%08x 0x%08x\n", - AAP1_MEMMAP(i, 0), - AAP1_MEMMAP(i, 4), - AAP1_MEMMAP(i, 8), - AAP1_MEMMAP(i, 12), - AAP1_MEMMAP(i, 16), - AAP1_MEMMAP(i, 20), - AAP1_MEMMAP(i, 24), - AAP1_MEMMAP(i, 28)); + pm8001_ctl_aap1_memmap(ptr, i, 0), + pm8001_ctl_aap1_memmap(ptr, i, 4), + pm8001_ctl_aap1_memmap(ptr, i, 8), + pm8001_ctl_aap1_memmap(ptr, i, 12), + pm8001_ctl_aap1_memmap(ptr, i, 16), + pm8001_ctl_aap1_memmap(ptr, i, 20), + pm8001_ctl_aap1_memmap(ptr, i, 24), + pm8001_ctl_aap1_memmap(ptr, i, 28)); } return str - buf; diff --git a/drivers/scsi/pm8001/pm8001_ctl.h b/drivers/scsi/pm8001/pm8001_ctl.h index d0d43a250b9e..4743f0de223e 100644 --- a/drivers/scsi/pm8001/pm8001_ctl.h +++ b/drivers/scsi/pm8001/pm8001_ctl.h @@ -59,5 +59,10 @@ #define SYSFS_OFFSET 1024 #define PM80XX_IB_OB_QUEUE_SIZE (32 * 1024) #define PM8001_IB_OB_QUEUE_SIZE (16 * 1024) + +static inline u32 pm8001_ctl_aap1_memmap(u8 *ptr, int idx, int off) +{ + return *(u32 *)(ptr + idx * 32 + off); +} #endif /* PM8001_CTL_H_INCLUDED */ diff --git a/drivers/scsi/pm8001/pm8001_hwi.c b/drivers/scsi/pm8001/pm8001_hwi.c index 16edd84e7130..c1f9e7d0466b 100644 --- a/drivers/scsi/pm8001/pm8001_hwi.c +++ b/drivers/scsi/pm8001/pm8001_hwi.c @@ -1826,7 +1826,7 @@ static void pm8001_send_read_log(struct pm8001_hba_info *pm8001_ha, * that the task has been finished. */ static void -mpi_ssp_completion(struct pm8001_hba_info *pm8001_ha , void *piomb) +mpi_ssp_completion(struct pm8001_hba_info *pm8001_ha, void *piomb) { struct sas_task *t; struct pm8001_ccb_info *ccb; @@ -2058,7 +2058,7 @@ mpi_ssp_completion(struct pm8001_hba_info *pm8001_ha , void *piomb) } /*See the comments for mpi_ssp_completion */ -static void mpi_ssp_event(struct pm8001_hba_info *pm8001_ha , void *piomb) +static void mpi_ssp_event(struct pm8001_hba_info *pm8001_ha, void *piomb) { struct sas_task *t; unsigned long flags; @@ -2294,9 +2294,9 @@ mpi_sata_completion(struct pm8001_hba_info *pm8001_ha, void *piomb) (status != IO_UNDERFLOW)) { if (!((t->dev->parent) && (dev_is_expander(t->dev->parent->dev_type)))) { - for (i = 0 , j = 4; j <= 7 && i <= 3; i++ , j++) + for (i = 0, j = 4; j <= 7 && i <= 3; i++, j++) sata_addr_low[i] = pm8001_ha->sas_addr[j]; - for (i = 0 , j = 0; j <= 3 && i <= 3; i++ , j++) + for (i = 0, j = 0; j <= 3 && i <= 3; i++, j++) sata_addr_hi[i] = pm8001_ha->sas_addr[j]; memcpy(&temp_sata_addr_low, sata_addr_low, sizeof(sata_addr_low)); @@ -2625,7 +2625,7 @@ mpi_sata_completion(struct pm8001_hba_info *pm8001_ha, void *piomb) } /*See the comments for mpi_ssp_completion */ -static void mpi_sata_event(struct pm8001_hba_info *pm8001_ha , void *piomb) +static void mpi_sata_event(struct pm8001_hba_info *pm8001_ha, void *piomb) { struct sas_task *t; struct task_status_struct *ts; @@ -3602,7 +3602,7 @@ int pm8001_mpi_fw_flash_update_resp(struct pm8001_hba_info *pm8001_ha, return 0; } -int pm8001_mpi_general_event(struct pm8001_hba_info *pm8001_ha , void *piomb) +int pm8001_mpi_general_event(struct pm8001_hba_info *pm8001_ha, void *piomb) { u32 status; int i; @@ -3685,7 +3685,7 @@ int pm8001_mpi_task_abort_resp(struct pm8001_hba_info *pm8001_ha, void *piomb) * @pm8001_ha: our hba card information * @piomb: IO message buffer */ -static int mpi_hw_event(struct pm8001_hba_info *pm8001_ha, void* piomb) +static int mpi_hw_event(struct pm8001_hba_info *pm8001_ha, void *piomb) { unsigned long flags; struct hw_event_resp *pPayload = diff --git a/drivers/scsi/pm8001/pm8001_sas.c b/drivers/scsi/pm8001/pm8001_sas.c index 6f4753d91418..a773ee6e810b 100644 --- a/drivers/scsi/pm8001/pm8001_sas.c +++ b/drivers/scsi/pm8001/pm8001_sas.c @@ -877,8 +877,8 @@ static void pm8001_dev_gone_notify(struct domain_device *dev) pm8001_dev->device_id, pm8001_dev->dev_type); if (atomic_read(&pm8001_dev->running_req)) { spin_unlock_irqrestore(&pm8001_ha->lock, flags); - pm8001_exec_internal_task_abort(pm8001_ha, pm8001_dev , - dev, 1, 0); + pm8001_exec_internal_task_abort(pm8001_ha, pm8001_dev, + dev, 1, 0); while (atomic_read(&pm8001_dev->running_req)) msleep(20); spin_lock_irqsave(&pm8001_ha->lock, flags); @@ -1014,8 +1014,8 @@ int pm8001_I_T_nexus_reset(struct domain_device *dev) goto out; } msleep(2000); - rc = pm8001_exec_internal_task_abort(pm8001_ha, pm8001_dev , - dev, 1, 0); + rc = pm8001_exec_internal_task_abort(pm8001_ha, pm8001_dev, + dev, 1, 0); if (rc) { pm8001_dbg(pm8001_ha, EH, "task abort failed %x\n" "with rc %d\n", pm8001_dev->device_id, rc); @@ -1060,8 +1060,8 @@ int pm8001_I_T_nexus_event_handler(struct domain_device *dev) goto out; } /* send internal ssp/sata/smp abort command to FW */ - rc = pm8001_exec_internal_task_abort(pm8001_ha, pm8001_dev , - dev, 1, 0); + rc = pm8001_exec_internal_task_abort(pm8001_ha, pm8001_dev, + dev, 1, 0); msleep(100); /* deregister the target device */ @@ -1076,8 +1076,8 @@ int pm8001_I_T_nexus_event_handler(struct domain_device *dev) wait_for_completion(&completion_setstate); } else { /* send internal ssp/sata/smp abort command to FW */ - rc = pm8001_exec_internal_task_abort(pm8001_ha, pm8001_dev , - dev, 1, 0); + rc = pm8001_exec_internal_task_abort(pm8001_ha, pm8001_dev, + dev, 1, 0); msleep(100); /* deregister the target device */ @@ -1105,8 +1105,8 @@ int pm8001_lu_reset(struct domain_device *dev, u8 *lun) DECLARE_COMPLETION_ONSTACK(completion_setstate); if (dev_is_sata(dev)) { struct sas_phy *phy = sas_get_local_phy(dev); - rc = pm8001_exec_internal_task_abort(pm8001_ha, pm8001_dev , - dev, 1, 0); + rc = pm8001_exec_internal_task_abort(pm8001_ha, pm8001_dev, + dev, 1, 0); rc = sas_phy_reset(phy, 1); sas_put_local_phy(phy); pm8001_dev->setds_completion = &completion_setstate; diff --git a/drivers/scsi/pm8001/pm8001_sas.h b/drivers/scsi/pm8001/pm8001_sas.h index 9ae9f1e61b54..07d1ac287d43 100644 --- a/drivers/scsi/pm8001/pm8001_sas.h +++ b/drivers/scsi/pm8001/pm8001_sas.h @@ -704,7 +704,7 @@ int pm8001_mpi_reg_resp(struct pm8001_hba_info *pm8001_ha, void *piomb); int pm8001_mpi_dereg_resp(struct pm8001_hba_info *pm8001_ha, void *piomb); int pm8001_mpi_fw_flash_update_resp(struct pm8001_hba_info *pm8001_ha, void *piomb); -int pm8001_mpi_general_event(struct pm8001_hba_info *pm8001_ha , void *piomb); +int pm8001_mpi_general_event(struct pm8001_hba_info *pm8001_ha, void *piomb); int pm8001_mpi_task_abort_resp(struct pm8001_hba_info *pm8001_ha, void *piomb); struct sas_task *pm8001_alloc_task(void); void pm8001_task_done(struct sas_task *task); diff --git a/drivers/scsi/pm8001/pm80xx_hwi.c b/drivers/scsi/pm8001/pm80xx_hwi.c index 42602d8d5ccf..f4f3956e658f 100644 --- a/drivers/scsi/pm8001/pm80xx_hwi.c +++ b/drivers/scsi/pm8001/pm80xx_hwi.c @@ -90,7 +90,7 @@ ssize_t pm80xx_get_fatal_dump(struct device *cdev, struct sas_ha_struct *sha = SHOST_TO_SAS_HA(shost); struct pm8001_hba_info *pm8001_ha = sha->lldd_ha; void __iomem *fatal_table_address = pm8001_ha->fatal_tbl_addr; - u32 accum_len , reg_val, index, *temp; + u32 accum_len, reg_val, index, *temp; u32 status = 1; unsigned long start; u8 *direct_data; @@ -1904,7 +1904,7 @@ static void pm80xx_send_read_log(struct pm8001_hba_info *pm8001_ha, * that the task has been finished. */ static void -mpi_ssp_completion(struct pm8001_hba_info *pm8001_ha , void *piomb) +mpi_ssp_completion(struct pm8001_hba_info *pm8001_ha, void *piomb) { struct sas_task *t; struct pm8001_ccb_info *ccb; @@ -2194,7 +2194,7 @@ mpi_ssp_completion(struct pm8001_hba_info *pm8001_ha , void *piomb) } /*See the comments for mpi_ssp_completion */ -static void mpi_ssp_event(struct pm8001_hba_info *pm8001_ha , void *piomb) +static void mpi_ssp_event(struct pm8001_hba_info *pm8001_ha, void *piomb) { struct sas_task *t; unsigned long flags; @@ -2444,9 +2444,9 @@ mpi_sata_completion(struct pm8001_hba_info *pm8001_ha, void *piomb) (status != IO_UNDERFLOW)) { if (!((t->dev->parent) && (dev_is_expander(t->dev->parent->dev_type)))) { - for (i = 0 , j = 4; i <= 3 && j <= 7; i++ , j++) + for (i = 0, j = 4; i <= 3 && j <= 7; i++, j++) sata_addr_low[i] = pm8001_ha->sas_addr[j]; - for (i = 0 , j = 0; i <= 3 && j <= 3; i++ , j++) + for (i = 0, j = 0; i <= 3 && j <= 3; i++, j++) sata_addr_hi[i] = pm8001_ha->sas_addr[j]; memcpy(&temp_sata_addr_low, sata_addr_low, sizeof(sata_addr_low)); @@ -2788,7 +2788,7 @@ mpi_sata_completion(struct pm8001_hba_info *pm8001_ha, void *piomb) } /*See the comments for mpi_ssp_completion */ -static void mpi_sata_event(struct pm8001_hba_info *pm8001_ha , void *piomb) +static void mpi_sata_event(struct pm8001_hba_info *pm8001_ha, void *piomb) { struct sas_task *t; struct task_status_struct *ts; @@ -4918,7 +4918,7 @@ static void mpi_set_phy_profile_req(struct pm8001_hba_info *pm8001_ha, u32 operation, u32 phyid, u32 length, u32 *buf) { - u32 tag , i, j = 0; + u32 tag, i, j = 0; int rc; struct set_phy_profile_req payload; struct inbound_queue_table *circularQ; From fa5ac2beabadc2ef5eaae0f99407e708bd5dbd66 Mon Sep 17 00:00:00 2001 From: Luo Jiaxing Date: Thu, 8 Apr 2021 20:56:33 +0800 Subject: [PATCH 334/412] scsi: pm8001: Clean up open braces checkpatch reports the following: ERROR: that open brace { should be on the previous line +static struct error_fw flash_error_table[] = +{ Fix a couple of instances of misplaced open bracket. Link: https://lore.kernel.org/r/1617886593-36421-3-git-send-email-luojiaxing@huawei.com Acked-by: Jack Wang Signed-off-by: Luo Jiaxing Signed-off-by: Jianqin Xie Signed-off-by: Martin K. Petersen --- drivers/scsi/pm8001/pm8001_ctl.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/drivers/scsi/pm8001/pm8001_ctl.c b/drivers/scsi/pm8001/pm8001_ctl.c index 8c1711e2d5bb..26e340edb0b3 100644 --- a/drivers/scsi/pm8001/pm8001_ctl.c +++ b/drivers/scsi/pm8001/pm8001_ctl.c @@ -645,8 +645,7 @@ struct flash_command { int code; }; -static struct flash_command flash_command_table[] = -{ +static const struct flash_command flash_command_table[] = { {"set_nvmd", FLASH_CMD_SET_NVMD}, {"update", FLASH_CMD_UPDATE}, {"", FLASH_CMD_NONE} /* Last entry should be NULL. */ @@ -657,8 +656,7 @@ struct error_fw { int err_code; }; -static struct error_fw flash_error_table[] = -{ +static const struct error_fw flash_error_table[] = { {"Failed to open fw image file", FAIL_OPEN_BIOS_FILE}, {"image header mismatch", FLASH_UPDATE_HDR_ERR}, {"image offset mismatch", FLASH_UPDATE_OFFSET_ERR}, From 2843d2fb42254ac443c83e5e0b97e1cae6b7a4de Mon Sep 17 00:00:00 2001 From: Luo Jiaxing Date: Tue, 6 Apr 2021 19:48:26 +0800 Subject: [PATCH 335/412] scsi: hisi_sas: Delete some unused callbacks The debugfs code has been relocated to v3 hw driver, so delete unused struct hisi_sas_hw function pointers snapshot_{prepare, restore}. Link: https://lore.kernel.org/r/1617709711-195853-2-git-send-email-john.garry@huawei.com Signed-off-by: Luo Jiaxing Signed-off-by: John Garry Signed-off-by: Martin K. Petersen --- drivers/scsi/hisi_sas/hisi_sas.h | 2 -- 1 file changed, 2 deletions(-) diff --git a/drivers/scsi/hisi_sas/hisi_sas.h b/drivers/scsi/hisi_sas/hisi_sas.h index 2401a9575215..4dd53bc2d946 100644 --- a/drivers/scsi/hisi_sas/hisi_sas.h +++ b/drivers/scsi/hisi_sas/hisi_sas.h @@ -346,8 +346,6 @@ struct hisi_sas_hw { u8 reg_index, u8 reg_count, u8 *write_data); void (*wait_cmds_complete_timeout)(struct hisi_hba *hisi_hba, int delay_ms, int timeout_ms); - void (*snapshot_prepare)(struct hisi_hba *hisi_hba); - void (*snapshot_restore)(struct hisi_hba *hisi_hba); int complete_hdr_size; struct scsi_host_template *sht; }; From 4da0b7f6fac331f2d2336df3ca88a335f545b4dc Mon Sep 17 00:00:00 2001 From: Luo Jiaxing Date: Tue, 6 Apr 2021 19:48:27 +0800 Subject: [PATCH 336/412] scsi: hisi_sas: Print SAS address for v3 hw erroneous completion print To help debugging efforts, print the device SAS address for v3 hw erroneous completion log. Here is an example print: hisi_sas_v3_hw 0000:b4:02.0: erroneous completion iptt=2193 task=000000002b0c13f8 dev id=17 addr=570fd45f9d17b001 Link: https://lore.kernel.org/r/1617709711-195853-3-git-send-email-john.garry@huawei.com Signed-off-by: Luo Jiaxing Signed-off-by: John Garry Signed-off-by: Martin K. Petersen --- drivers/scsi/hisi_sas/hisi_sas_v3_hw.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c b/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c index 4580e081e489..51187dd53c86 100644 --- a/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c +++ b/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c @@ -2252,8 +2252,9 @@ static void slot_complete_v3_hw(struct hisi_hba *hisi_hba, slot_err_v3_hw(hisi_hba, task, slot); if (ts->stat != SAS_DATA_UNDERRUN) - dev_info(dev, "erroneous completion iptt=%d task=%pK dev id=%d CQ hdr: 0x%x 0x%x 0x%x 0x%x Error info: 0x%x 0x%x 0x%x 0x%x\n", + dev_info(dev, "erroneous completion iptt=%d task=%pK dev id=%d addr=%016llx CQ hdr: 0x%x 0x%x 0x%x 0x%x Error info: 0x%x 0x%x 0x%x 0x%x\n", slot->idx, task, sas_dev->device_id, + SAS_ADDR(device->sas_addr), dw0, dw1, complete_hdr->act, dw3, error_info[0], error_info[1], error_info[2], error_info[3]); From f467666504bf0c7eae95b929d0c86f77ff9b4356 Mon Sep 17 00:00:00 2001 From: Xiang Chen Date: Tue, 6 Apr 2021 19:48:28 +0800 Subject: [PATCH 337/412] scsi: hisi_sas: Call sas_unregister_ha() to roll back if .hw_init() fails Function sas_unregister_ha() needs to be called to roll back if hisi_hba->hw->hw_init() fails in function hisi_sas_probe() or hisi_sas_v3_probe(). Make that change. Link: https://lore.kernel.org/r/1617709711-195853-4-git-send-email-john.garry@huawei.com Signed-off-by: Xiang Chen Signed-off-by: John Garry Signed-off-by: Martin K. Petersen --- drivers/scsi/hisi_sas/hisi_sas_main.c | 4 +++- drivers/scsi/hisi_sas/hisi_sas_v3_hw.c | 4 +++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/drivers/scsi/hisi_sas/hisi_sas_main.c b/drivers/scsi/hisi_sas/hisi_sas_main.c index a979edfd9a78..971c45a1401c 100644 --- a/drivers/scsi/hisi_sas/hisi_sas_main.c +++ b/drivers/scsi/hisi_sas/hisi_sas_main.c @@ -2689,12 +2689,14 @@ int hisi_sas_probe(struct platform_device *pdev, rc = hisi_hba->hw->hw_init(hisi_hba); if (rc) - goto err_out_register_ha; + goto err_out_hw_init; scsi_scan_host(shost); return 0; +err_out_hw_init: + sas_unregister_ha(sha); err_out_register_ha: scsi_remove_host(shost); err_out_ha: diff --git a/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c b/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c index 51187dd53c86..d7f8ba0c1680 100644 --- a/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c +++ b/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c @@ -4761,7 +4761,7 @@ hisi_sas_v3_probe(struct pci_dev *pdev, const struct pci_device_id *id) rc = hisi_sas_v3_init(hisi_hba); if (rc) - goto err_out_register_ha; + goto err_out_hw_init; scsi_scan_host(shost); @@ -4778,6 +4778,8 @@ hisi_sas_v3_probe(struct pci_dev *pdev, const struct pci_device_id *id) return 0; +err_out_hw_init: + sas_unregister_ha(sha); err_out_register_ha: scsi_remove_host(shost); err_out_free_irq_vectors: From 2c74cb1f9222ebfcc204c02018275ad167d25212 Mon Sep 17 00:00:00 2001 From: Jianqin Xie Date: Tue, 6 Apr 2021 19:48:29 +0800 Subject: [PATCH 338/412] scsi: hisi_sas: Directly snapshot registers when executing a reset The debugfs snapshot should be executed before the reset occurs to ensure that the register contents are saved properly. As such, it is incorrect to queue the debugfs dump when running a reset as the reset will occur prior to the snapshot work item is handler. Therefore, directly snapshot registers in the reset work handler. Link: https://lore.kernel.org/r/1617709711-195853-5-git-send-email-john.garry@huawei.com Signed-off-by: Jianqin Xie Signed-off-by: Luo Jiaxing Signed-off-by: John Garry Signed-off-by: Martin K. Petersen --- drivers/scsi/hisi_sas/hisi_sas.h | 1 + drivers/scsi/hisi_sas/hisi_sas_main.c | 28 ++++++++++++++++++-------- drivers/scsi/hisi_sas/hisi_sas_v3_hw.c | 27 ++++++++++++++----------- 3 files changed, 36 insertions(+), 20 deletions(-) diff --git a/drivers/scsi/hisi_sas/hisi_sas.h b/drivers/scsi/hisi_sas/hisi_sas.h index 4dd53bc2d946..cf879cc59e4c 100644 --- a/drivers/scsi/hisi_sas/hisi_sas.h +++ b/drivers/scsi/hisi_sas/hisi_sas.h @@ -346,6 +346,7 @@ struct hisi_sas_hw { u8 reg_index, u8 reg_count, u8 *write_data); void (*wait_cmds_complete_timeout)(struct hisi_hba *hisi_hba, int delay_ms, int timeout_ms); + void (*debugfs_snapshot_regs)(struct hisi_hba *hisi_hba); int complete_hdr_size; struct scsi_host_template *sht; }; diff --git a/drivers/scsi/hisi_sas/hisi_sas_main.c b/drivers/scsi/hisi_sas/hisi_sas_main.c index 971c45a1401c..4c90d91d47f4 100644 --- a/drivers/scsi/hisi_sas/hisi_sas_main.c +++ b/drivers/scsi/hisi_sas/hisi_sas_main.c @@ -1568,21 +1568,26 @@ void hisi_sas_controller_reset_done(struct hisi_hba *hisi_hba) } EXPORT_SYMBOL_GPL(hisi_sas_controller_reset_done); -static int hisi_sas_controller_reset(struct hisi_hba *hisi_hba) +static int hisi_sas_controller_prereset(struct hisi_hba *hisi_hba) { - struct device *dev = hisi_hba->dev; - struct Scsi_Host *shost = hisi_hba->shost; - int rc; - - if (hisi_sas_debugfs_enable && hisi_hba->debugfs_itct[0].itct) - queue_work(hisi_hba->wq, &hisi_hba->debugfs_work); - if (!hisi_hba->hw->soft_reset) return -1; if (test_and_set_bit(HISI_SAS_RESET_BIT, &hisi_hba->flags)) return -1; + if (hisi_sas_debugfs_enable && hisi_hba->debugfs_itct[0].itct) + hisi_hba->hw->debugfs_snapshot_regs(hisi_hba); + + return 0; +} + +static int hisi_sas_controller_reset(struct hisi_hba *hisi_hba) +{ + struct device *dev = hisi_hba->dev; + struct Scsi_Host *shost = hisi_hba->shost; + int rc; + dev_info(dev, "controller resetting...\n"); hisi_sas_controller_reset_prepare(hisi_hba); @@ -2471,6 +2476,9 @@ void hisi_sas_rst_work_handler(struct work_struct *work) struct hisi_hba *hisi_hba = container_of(work, struct hisi_hba, rst_work); + if (hisi_sas_controller_prereset(hisi_hba)) + return; + hisi_sas_controller_reset(hisi_hba); } EXPORT_SYMBOL_GPL(hisi_sas_rst_work_handler); @@ -2480,8 +2488,12 @@ void hisi_sas_sync_rst_work_handler(struct work_struct *work) struct hisi_sas_rst *rst = container_of(work, struct hisi_sas_rst, work); + if (hisi_sas_controller_prereset(rst->hisi_hba)) + goto rst_complete; + if (!hisi_sas_controller_reset(rst->hisi_hba)) rst->done = true; +rst_complete: complete(rst->completion); } EXPORT_SYMBOL_GPL(hisi_sas_sync_rst_work_handler); diff --git a/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c b/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c index d7f8ba0c1680..0927b0b30b29 100644 --- a/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c +++ b/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c @@ -531,6 +531,7 @@ module_param(prot_mask, int, 0); MODULE_PARM_DESC(prot_mask, " host protection capabilities mask, def=0x0 "); static void debugfs_work_handler_v3_hw(struct work_struct *work); +static void debugfs_snapshot_regs_v3_hw(struct hisi_hba *hisi_hba); static u32 hisi_sas_read32(struct hisi_hba *hisi_hba, u32 off) { @@ -3182,6 +3183,7 @@ static const struct hisi_sas_hw hisi_sas_v3_hw = { .get_events = phy_get_events_v3_hw, .write_gpio = write_gpio_v3_hw, .wait_cmds_complete_timeout = wait_cmds_complete_timeout_v3_hw, + .debugfs_snapshot_regs = debugfs_snapshot_regs_v3_hw, }; static struct Scsi_Host * @@ -3666,6 +3668,19 @@ static void debugfs_create_files_v3_hw(struct hisi_hba *hisi_hba) static void debugfs_snapshot_regs_v3_hw(struct hisi_hba *hisi_hba) { + int debugfs_dump_index = hisi_hba->debugfs_dump_index; + struct device *dev = hisi_hba->dev; + u64 timestamp = local_clock(); + + if (debugfs_dump_index >= hisi_sas_debugfs_dump_count) { + dev_warn(dev, "dump count exceeded!\n"); + return; + } + + do_div(timestamp, NSEC_PER_MSEC); + hisi_hba->debugfs_timestamp[debugfs_dump_index] = timestamp; + hisi_hba->debugfs_dump_index++; + debugfs_snapshot_prepare_v3_hw(hisi_hba); debugfs_snapshot_global_reg_v3_hw(hisi_hba); @@ -4408,20 +4423,8 @@ static void debugfs_work_handler_v3_hw(struct work_struct *work) { struct hisi_hba *hisi_hba = container_of(work, struct hisi_hba, debugfs_work); - int debugfs_dump_index = hisi_hba->debugfs_dump_index; - struct device *dev = hisi_hba->dev; - u64 timestamp = local_clock(); - - if (debugfs_dump_index >= hisi_sas_debugfs_dump_count) { - dev_warn(dev, "dump count exceeded!\n"); - return; - } - - do_div(timestamp, NSEC_PER_MSEC); - hisi_hba->debugfs_timestamp[debugfs_dump_index] = timestamp; debugfs_snapshot_regs_v3_hw(hisi_hba); - hisi_hba->debugfs_dump_index++; } static void debugfs_release_v3_hw(struct hisi_hba *hisi_hba, int dump_index) From 2d31cb20a3cd611a9a544f9586eb3908ee2085cf Mon Sep 17 00:00:00 2001 From: Luo Jiaxing Date: Tue, 6 Apr 2021 19:48:30 +0800 Subject: [PATCH 339/412] scsi: hisi_sas: Warn in v3 hw channel interrupt handler when status reg cleared If a channel interrupt occurs without any status bit set, the handler will return directly. However, if such redundant interrupts are received, it's better to check what happen, so add logs for this. Link: https://lore.kernel.org/r/1617709711-195853-6-git-send-email-john.garry@huawei.com Signed-off-by: Luo Jiaxing Signed-off-by: Yihang Li Signed-off-by: John Garry Signed-off-by: Martin K. Petersen --- drivers/scsi/hisi_sas/hisi_sas_v3_hw.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c b/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c index 0927b0b30b29..499c770d405c 100644 --- a/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c +++ b/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c @@ -1718,8 +1718,11 @@ static void handle_chl_int1_v3_hw(struct hisi_hba *hisi_hba, int phy_no) int i; irq_value &= ~irq_msk; - if (!irq_value) + if (!irq_value) { + dev_warn(dev, "phy%d channel int 1 received with status bits cleared\n", + phy_no); return; + } for (i = 0; i < ARRAY_SIZE(port_axi_error); i++) { const struct hisi_sas_hw_error *error = &port_axi_error[i]; @@ -1780,8 +1783,11 @@ static void handle_chl_int2_v3_hw(struct hisi_hba *hisi_hba, int phy_no) BIT(CHL_INT2_RX_INVLD_DW_OFF); irq_value &= ~irq_msk; - if (!irq_value) + if (!irq_value) { + dev_warn(dev, "phy%d channel int 2 received with status bits cleared\n", + phy_no); return; + } if (irq_value & BIT(CHL_INT2_SL_IDAF_TOUT_CONF_OFF)) { dev_warn(dev, "phy%d identify timeout\n", phy_no); From f4df167ad5a2274c12680ba3e7d816d32d1fc375 Mon Sep 17 00:00:00 2001 From: Luo Jiaxing Date: Tue, 6 Apr 2021 19:48:31 +0800 Subject: [PATCH 340/412] scsi: hisi_sas: Print SATA device SAS address for soft reset failure Add (pseudo) SAS address for ATA software reset failure log to assist in debugging. Link: https://lore.kernel.org/r/1617709711-195853-7-git-send-email-john.garry@huawei.com Signed-off-by: Luo Jiaxing Signed-off-by: John Garry Signed-off-by: Martin K. Petersen --- drivers/scsi/hisi_sas/hisi_sas_main.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/drivers/scsi/hisi_sas/hisi_sas_main.c b/drivers/scsi/hisi_sas/hisi_sas_main.c index 4c90d91d47f4..5a204074099c 100644 --- a/drivers/scsi/hisi_sas/hisi_sas_main.c +++ b/drivers/scsi/hisi_sas/hisi_sas_main.c @@ -1341,10 +1341,12 @@ static int hisi_sas_softreset_ata_disk(struct domain_device *device) rc = hisi_sas_exec_internal_tmf_task(device, fis, s, NULL); if (rc != TMF_RESP_FUNC_COMPLETE) - dev_err(dev, "ata disk de-reset failed\n"); + dev_err(dev, "ata disk %016llx de-reset failed\n", + SAS_ADDR(device->sas_addr)); } } else { - dev_err(dev, "ata disk reset failed\n"); + dev_err(dev, "ata disk %016llx reset failed\n", + SAS_ADDR(device->sas_addr)); } if (rc == TMF_RESP_FUNC_COMPLETE) From 790f9a48abd0e4cd1b202b6093055c295d4b8e3d Mon Sep 17 00:00:00 2001 From: Ye Bin Date: Fri, 9 Apr 2021 15:55:22 +0800 Subject: [PATCH 341/412] scsi: ufs: ufs-qcom: Remove redundant dev_err() call in ufs_qcom_init() There is a error message within devm_ioremap_resource() already, so remove the dev_err() call to avoid redundant error message. Link: https://lore.kernel.org/r/20210409075522.2111083-1-yebin10@huawei.com Reported-by: Hulk Robot Reviewed-by: Manivannan Sadhasivam Signed-off-by: Ye Bin Signed-off-by: Martin K. Petersen --- drivers/scsi/ufs/ufs-qcom.c | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/drivers/scsi/ufs/ufs-qcom.c b/drivers/scsi/ufs/ufs-qcom.c index 9b711d6aac54..2a3dd21da6a6 100644 --- a/drivers/scsi/ufs/ufs-qcom.c +++ b/drivers/scsi/ufs/ufs-qcom.c @@ -1071,13 +1071,8 @@ static int ufs_qcom_init(struct ufs_hba *hba) if (res) { host->dev_ref_clk_ctrl_mmio = devm_ioremap_resource(dev, res); - if (IS_ERR(host->dev_ref_clk_ctrl_mmio)) { - dev_warn(dev, - "%s: could not map dev_ref_clk_ctrl_mmio, err %ld\n", - __func__, - PTR_ERR(host->dev_ref_clk_ctrl_mmio)); + if (IS_ERR(host->dev_ref_clk_ctrl_mmio)) host->dev_ref_clk_ctrl_mmio = NULL; - } host->dev_ref_clk_en_mask = BIT(5); } } From 54300bfd738b649004793ce138a29c30e900ec21 Mon Sep 17 00:00:00 2001 From: dingsenjie Date: Wed, 31 Mar 2021 14:53:25 +0800 Subject: [PATCH 342/412] scsi: snic: Convert to DEFINE_SHOW_ATTRIBUTE() Use DEFINE_SHOW_ATTRIBUTE() macro to simplify the code. Link: https://lore.kernel.org/r/20210331065326.18804-1-dingsenjie@163.com Signed-off-by: dingsenjie Signed-off-by: Martin K. Petersen --- drivers/scsi/snic/snic_debugfs.c | 20 +------------------- 1 file changed, 1 insertion(+), 19 deletions(-) diff --git a/drivers/scsi/snic/snic_debugfs.c b/drivers/scsi/snic/snic_debugfs.c index 4471c4c8aafa..3aeee856d5c7 100644 --- a/drivers/scsi/snic/snic_debugfs.c +++ b/drivers/scsi/snic/snic_debugfs.c @@ -334,25 +334,7 @@ snic_stats_show(struct seq_file *sfp, void *data) return 0; } -/* - * snic_stats_open - Open the stats file for specific host - * - * Description: - * This routine opens a debugfs file stats of specific host - */ -static int -snic_stats_open(struct inode *inode, struct file *filp) -{ - return single_open(filp, snic_stats_show, inode->i_private); -} - -static const struct file_operations snic_stats_fops = { - .owner = THIS_MODULE, - .open = snic_stats_open, - .read = seq_read, - .llseek = seq_lseek, - .release = single_release, -}; +DEFINE_SHOW_ATTRIBUTE(snic_stats); static const struct file_operations snic_reset_stats_fops = { .owner = THIS_MODULE, From 339c9b63cc7ce779ce45c675bf709cb58b807fc3 Mon Sep 17 00:00:00 2001 From: Sergey Shtylyov Date: Mon, 29 Mar 2021 23:50:58 +0300 Subject: [PATCH 343/412] scsi: ufs: ufshcd-pltfrm: Fix deferred probing The driver overrides the error codes returned by platform_get_irq() to -ENODEV, so if it returns -EPROBE_DEFER, the driver would fail the probe permanently instead of the deferred probing. Propagate the error code upstream as it should have been done from the start... Link: https://lore.kernel.org/r/420364ca-614a-45e3-4e35-0e0653c7bc53@omprussia.ru Fixes: 2953f850c3b8 ("[SCSI] ufs: use devres functions for ufshcd") Signed-off-by: Sergey Shtylyov Signed-off-by: Martin K. Petersen --- drivers/scsi/ufs/ufshcd-pltfrm.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/scsi/ufs/ufshcd-pltfrm.c b/drivers/scsi/ufs/ufshcd-pltfrm.c index fedb7deb3304..298e22ef907e 100644 --- a/drivers/scsi/ufs/ufshcd-pltfrm.c +++ b/drivers/scsi/ufs/ufshcd-pltfrm.c @@ -375,7 +375,7 @@ int ufshcd_pltfrm_init(struct platform_device *pdev, irq = platform_get_irq(pdev, 0); if (irq < 0) { - err = -ENODEV; + err = irq; goto out; } From 6c11dc060427e07ca144eacaccd696106b361b06 Mon Sep 17 00:00:00 2001 From: Sergey Shtylyov Date: Sat, 3 Apr 2021 23:43:55 +0300 Subject: [PATCH 344/412] scsi: hisi_sas: Fix IRQ checks Commit df2d8213d9e3 ("hisi_sas: use platform_get_irq()") failed to take into account that irq_of_parse_and_map() and platform_get_irq() have a different way of indicating an error: the former returns 0 and the latter returns a negative error code. Fix up the IRQ checks! Link: https://lore.kernel.org/r/810f26d3-908b-1d6b-dc5c-40019726baca@omprussia.ru Fixes: df2d8213d9e3 ("hisi_sas: use platform_get_irq()") Acked-by: John Garry Signed-off-by: Sergey Shtylyov Signed-off-by: Martin K. Petersen --- drivers/scsi/hisi_sas/hisi_sas_v1_hw.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/scsi/hisi_sas/hisi_sas_v1_hw.c b/drivers/scsi/hisi_sas/hisi_sas_v1_hw.c index 7451377c4cb6..3e359ac752fd 100644 --- a/drivers/scsi/hisi_sas/hisi_sas_v1_hw.c +++ b/drivers/scsi/hisi_sas/hisi_sas_v1_hw.c @@ -1646,7 +1646,7 @@ static int interrupt_init_v1_hw(struct hisi_hba *hisi_hba) idx = i * HISI_SAS_PHY_INT_NR; for (j = 0; j < HISI_SAS_PHY_INT_NR; j++, idx++) { irq = platform_get_irq(pdev, idx); - if (!irq) { + if (irq < 0) { dev_err(dev, "irq init: fail map phy interrupt %d\n", idx); return -ENOENT; @@ -1665,7 +1665,7 @@ static int interrupt_init_v1_hw(struct hisi_hba *hisi_hba) idx = hisi_hba->n_phy * HISI_SAS_PHY_INT_NR; for (i = 0; i < hisi_hba->queue_count; i++, idx++) { irq = platform_get_irq(pdev, idx); - if (!irq) { + if (irq < 0) { dev_err(dev, "irq init: could not map cq interrupt %d\n", idx); return -ENOENT; @@ -1683,7 +1683,7 @@ static int interrupt_init_v1_hw(struct hisi_hba *hisi_hba) idx = (hisi_hba->n_phy * HISI_SAS_PHY_INT_NR) + hisi_hba->queue_count; for (i = 0; i < HISI_SAS_FATAL_INT_NR; i++, idx++) { irq = platform_get_irq(pdev, idx); - if (!irq) { + if (irq < 0) { dev_err(dev, "irq init: could not map fatal interrupt %d\n", idx); return -ENOENT; From 38fca15c29db6ed06e894ac194502633e2a7d1fb Mon Sep 17 00:00:00 2001 From: Sergey Shtylyov Date: Tue, 30 Mar 2021 20:43:23 +0300 Subject: [PATCH 345/412] scsi: jazz_esp: Add IRQ check The driver neglects to check the result of platform_get_irq()'s call and blithely passes the negative error codes to request_irq() (which takes *unsigned* IRQ #), causing it to fail with -EINVAL, overriding the real error code. Stop calling request_irq() with the invalid IRQ #s. Link: https://lore.kernel.org/r/594aa9ae-2215-49f6-f73c-33bd38989912@omprussia.ru Fixes: 352e921f0dd4 ("[SCSI] jazz_esp: converted to use esp_core") Signed-off-by: Sergey Shtylyov Signed-off-by: Martin K. Petersen --- drivers/scsi/jazz_esp.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/scsi/jazz_esp.c b/drivers/scsi/jazz_esp.c index f0ed6863cc70..60a88a95a8e2 100644 --- a/drivers/scsi/jazz_esp.c +++ b/drivers/scsi/jazz_esp.c @@ -143,7 +143,9 @@ static int esp_jazz_probe(struct platform_device *dev) if (!esp->command_block) goto fail_unmap_regs; - host->irq = platform_get_irq(dev, 0); + host->irq = err = platform_get_irq(dev, 0); + if (err < 0) + goto fail_unmap_command_block; err = request_irq(host->irq, scsi_esp_intr, IRQF_SHARED, "ESP", esp); if (err < 0) goto fail_unmap_command_block; From 14b321380eb333c82853d7d612d0995f05f88fdc Mon Sep 17 00:00:00 2001 From: Sergey Shtylyov Date: Tue, 30 Mar 2021 20:44:08 +0300 Subject: [PATCH 346/412] scsi: sun3x_esp: Add IRQ check The driver neglects to check the result of platform_get_irq()'s call and blithely passes the negative error codes to request_irq() (which takes *unsigned* IRQ #), causing it to fail with -EINVAL, overriding the real error code. Stop calling request_irq() with the invalid IRQ #s. Link: https://lore.kernel.org/r/363eb4c8-a3bf-4dc9-2a9e-90f349030a15@omprussia.ru Fixes: 0bb67f181834 ("[SCSI] sun3x_esp: convert to esp_scsi") Signed-off-by: Sergey Shtylyov Signed-off-by: Martin K. Petersen --- drivers/scsi/sun3x_esp.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/scsi/sun3x_esp.c b/drivers/scsi/sun3x_esp.c index 7de82f2c9757..d3489ac7ab28 100644 --- a/drivers/scsi/sun3x_esp.c +++ b/drivers/scsi/sun3x_esp.c @@ -206,7 +206,9 @@ static int esp_sun3x_probe(struct platform_device *dev) if (!esp->command_block) goto fail_unmap_regs_dma; - host->irq = platform_get_irq(dev, 0); + host->irq = err = platform_get_irq(dev, 0); + if (err < 0) + goto fail_unmap_command_block; err = request_irq(host->irq, scsi_esp_intr, IRQF_SHARED, "SUN3X ESP", esp); if (err < 0) From 1160d61bc51e87e509cfaf9da50a0060f67b6de4 Mon Sep 17 00:00:00 2001 From: Sergey Shtylyov Date: Tue, 30 Mar 2021 20:45:12 +0300 Subject: [PATCH 347/412] scsi: sni_53c710: Add IRQ check The driver neglects to check the result of platform_get_irq()'s call and blithely passes the negative error codes to request_irq() (which takes *unsigned* IRQ #s), causing it to fail with -EINVAL (overridden by -ENODEV further below). Stop calling request_irq() with the invalid IRQ #s. Link: https://lore.kernel.org/r/8f4b8fa5-8251-b977-70a1-9099bcb4bb17@omprussia.ru Fixes: c27d85f3f3c5 ("[SCSI] SNI RM 53c710 driver") Signed-off-by: Sergey Shtylyov Signed-off-by: Martin K. Petersen --- drivers/scsi/sni_53c710.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/drivers/scsi/sni_53c710.c b/drivers/scsi/sni_53c710.c index 9e2e196bc202..97c6f81b1d2a 100644 --- a/drivers/scsi/sni_53c710.c +++ b/drivers/scsi/sni_53c710.c @@ -58,6 +58,7 @@ static int snirm710_probe(struct platform_device *dev) struct NCR_700_Host_Parameters *hostdata; struct Scsi_Host *host; struct resource *res; + int rc; res = platform_get_resource(dev, IORESOURCE_MEM, 0); if (!res) @@ -83,7 +84,9 @@ static int snirm710_probe(struct platform_device *dev) goto out_kfree; host->this_id = 7; host->base = base; - host->irq = platform_get_irq(dev, 0); + host->irq = rc = platform_get_irq(dev, 0); + if (rc < 0) + goto out_put_host; if(request_irq(host->irq, NCR_700_intr, IRQF_SHARED, "snirm710", host)) { printk(KERN_ERR "snirm710: request_irq failed!\n"); goto out_put_host; From 4aab946f789ed7c2e44481f395ab2eab0b63824a Mon Sep 17 00:00:00 2001 From: Javed Hasan Date: Wed, 31 Mar 2021 09:49:16 -0700 Subject: [PATCH 348/412] scsi: qedf: Enable devlink support Devlink instance lifetime was linked to qed_dev object. That caused devlink to be recreated on each recovery. Change it by making higher level driver (qede) responsible for lifetime management. This way devlink survives recoveries. qede now stores devlink structure pointer as a part of its device object, devlink private data contains a linkage structure, qed_devlink. Link: https://lore.kernel.org/r/20210331164917.24662-2-jhasan@marvell.com Signed-off-by: Javed Hasan Signed-off-by: Martin K. Petersen --- drivers/scsi/qedf/qedf.h | 1 + drivers/scsi/qedf/qedf_main.c | 13 +++++++++++++ 2 files changed, 14 insertions(+) diff --git a/drivers/scsi/qedf/qedf.h b/drivers/scsi/qedf/qedf.h index 0583b0707354..ba94413fe2ea 100644 --- a/drivers/scsi/qedf/qedf.h +++ b/drivers/scsi/qedf/qedf.h @@ -333,6 +333,7 @@ struct qedf_ctx { unsigned int curr_conn_id; struct workqueue_struct *ll2_recv_wq; struct workqueue_struct *link_update_wq; + struct devlink *devlink; struct delayed_work link_update; struct delayed_work link_recovery; struct completion flogi_compl; diff --git a/drivers/scsi/qedf/qedf_main.c b/drivers/scsi/qedf/qedf_main.c index cec27f2ef70d..b8d016914eee 100644 --- a/drivers/scsi/qedf/qedf_main.c +++ b/drivers/scsi/qedf/qedf_main.c @@ -3408,6 +3408,14 @@ retry_probe: goto err2; } + if (mode != QEDF_MODE_RECOVERY) { + qedf->devlink = qed_ops->common->devlink_register(qedf->cdev); + if (IS_ERR(qedf->devlink)) { + QEDF_ERR(&qedf->dbg_ctx, "Cannot register devlink\n"); + qedf->devlink = NULL; + } + } + /* Record BDQ producer doorbell addresses */ qedf->bdq_primary_prod = qedf->dev_info.primary_dbq_rq_addr; qedf->bdq_secondary_prod = qedf->dev_info.secondary_bdq_rq_addr; @@ -3789,6 +3797,11 @@ static void __qedf_remove(struct pci_dev *pdev, int mode) QEDF_ERR(&(qedf->dbg_ctx), "Failed to send drv state to MFW.\n"); + if (mode != QEDF_MODE_RECOVERY && qedf->devlink) { + qed_ops->common->devlink_unregister(qedf->devlink); + qedf->devlink = NULL; + } + qed_ops->common->slowpath_stop(qedf->cdev); qed_ops->common->remove(qedf->cdev); From 9d6f87c25ad57b52a4dc8c2d904ead37fe829512 Mon Sep 17 00:00:00 2001 From: Javed Hasan Date: Wed, 31 Mar 2021 09:49:17 -0700 Subject: [PATCH 349/412] scsi: qedf: Use devlink to report errors and recovery Use devlink_health_report() to push error indications. Implement this in qede via a callback function to make it possible to reuse it for other drivers sitting on top of qed in future. Also remove forcible recovery trigger and put it as a normal devlink callback in qed module. This allows user to enable/disable it via: devlink health set pci/xxxx:xx:xx.x reporter fw_fatal auto_recover false Link: https://lore.kernel.org/r/20210331164917.24662-3-jhasan@marvell.com Signed-off-by: Javed Hasan Signed-off-by: Martin K. Petersen --- drivers/scsi/qedf/qedf_main.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/drivers/scsi/qedf/qedf_main.c b/drivers/scsi/qedf/qedf_main.c index b8d016914eee..69f7784233f9 100644 --- a/drivers/scsi/qedf/qedf_main.c +++ b/drivers/scsi/qedf/qedf_main.c @@ -3859,8 +3859,9 @@ void qedf_schedule_hw_err_handler(void *dev, enum qed_hw_err_type err_type) /* Prevent HW attentions from being reasserted */ qed_ops->common->attn_clr_enable(qedf->cdev, true); - if (qedf_enable_recovery) - qed_ops->common->recovery_process(qedf->cdev); + if (qedf_enable_recovery && qedf->devlink) + qed_ops->common->report_fatal_error(qedf->devlink, + err_type); break; default: From 16660db3fc2af8664af5e0a3cac69c4a54bfb794 Mon Sep 17 00:00:00 2001 From: "Gustavo A. R. Silva" Date: Thu, 1 Apr 2021 11:20:54 -0500 Subject: [PATCH 350/412] scsi: mpt3sas: Fix out-of-bounds warnings in _ctl_addnl_diag_query Fix the following out-of-bounds warnings by embedding existing struct htb_rel_query into struct mpt3_addnl_diag_query, instead of duplicating its members: include/linux/fortify-string.h:20:29: warning: '__builtin_memcpy' offset [19, 32] from the object at 'karg' is out of the bounds of referenced subobject 'buffer_rel_condition' with type 'short unsigned int' at offset 16 [-Warray-bounds] include/linux/fortify-string.h:22:29: warning: '__builtin_memset' offset [19, 32] from the object at 'karg' is out of the bounds of referenced subobject 'buffer_rel_condition' with type 'short unsigned int' at offset 16 [-Warray-bounds] The problem is that the original code is trying to copy data into a bunch of struct members adjacent to each other in a single call to memcpy(). All those members are exactly the same contained in struct htb_rel_query, so instead of duplicating them into struct mpt3_addnl_diag_query, replace them with new member rel_query of type struct htb_rel_query. So, now that this new object is introduced, memcpy() doesn't overrun the length of &karg.buffer_rel_condition, because the address of the new struct object _rel_query_ is used as destination, instead. The same issue is present when calling memset(), and it is fixed with this same approach. Below is a comparison of struct mpt3_addnl_diag_query, before and after this change (the size and cachelines remain the same): $ pahole -C mpt3_addnl_diag_query drivers/scsi/mpt3sas/mpt3sas_ctl.o struct mpt3_addnl_diag_query { struct mpt3_ioctl_header hdr; /* 0 12 */ uint32_t unique_id; /* 12 4 */ uint16_t buffer_rel_condition; /* 16 2 */ uint16_t reserved1; /* 18 2 */ uint32_t trigger_type; /* 20 4 */ uint32_t trigger_info_dwords[2]; /* 24 8 */ uint32_t reserved2[2]; /* 32 8 */ /* size: 40, cachelines: 1, members: 7 */ /* last cacheline: 40 bytes */ }; $ pahole -C mpt3_addnl_diag_query drivers/scsi/mpt3sas/mpt3sas_ctl.o struct mpt3_addnl_diag_query { struct mpt3_ioctl_header hdr; /* 0 12 */ uint32_t unique_id; /* 12 4 */ struct htb_rel_query rel_query; /* 16 16 */ uint32_t reserved2[2]; /* 32 8 */ /* size: 40, cachelines: 1, members: 4 */ /* last cacheline: 40 bytes */ }; Also, this helps with the ongoing efforts to globally enable -Warray-bounds and get us closer to being able to tighten the FORTIFY_SOURCE routines on memcpy(). Link: https://github.com/KSPP/linux/issues/109 Link: https://lore.kernel.org/lkml/60659889.bJJILx2THu3hlpxW%25lkp@intel.com/ Link: https://lore.kernel.org/r/20210401162054.GA397186@embeddedor Build-tested-by: kernel test robot Reported-by: kernel test robot Signed-off-by: Gustavo A. R. Silva Signed-off-by: Martin K. Petersen --- drivers/scsi/mpt3sas/mpt3sas_ctl.c | 5 ++--- drivers/scsi/mpt3sas/mpt3sas_ctl.h | 12 ++++-------- 2 files changed, 6 insertions(+), 11 deletions(-) diff --git a/drivers/scsi/mpt3sas/mpt3sas_ctl.c b/drivers/scsi/mpt3sas/mpt3sas_ctl.c index e7582fb8a93f..b66140e4c370 100644 --- a/drivers/scsi/mpt3sas/mpt3sas_ctl.c +++ b/drivers/scsi/mpt3sas/mpt3sas_ctl.c @@ -2507,7 +2507,7 @@ _ctl_addnl_diag_query(struct MPT3SAS_ADAPTER *ioc, void __user *arg) __func__, karg.unique_id); return -EPERM; } - memset(&karg.buffer_rel_condition, 0, sizeof(struct htb_rel_query)); + memset(&karg.rel_query, 0, sizeof(karg.rel_query)); if ((ioc->diag_buffer_status[buffer_type] & MPT3_DIAG_BUFFER_IS_REGISTERED) == 0) { ioc_info(ioc, "%s: buffer_type(0x%02x) is not registered\n", @@ -2520,8 +2520,7 @@ _ctl_addnl_diag_query(struct MPT3SAS_ADAPTER *ioc, void __user *arg) __func__, buffer_type); return -EPERM; } - memcpy(&karg.buffer_rel_condition, &ioc->htb_rel, - sizeof(struct htb_rel_query)); + memcpy(&karg.rel_query, &ioc->htb_rel, sizeof(karg.rel_query)); out: if (copy_to_user(arg, &karg, sizeof(struct mpt3_addnl_diag_query))) { ioc_err(ioc, "%s: unable to write mpt3_addnl_diag_query data @ %p\n", diff --git a/drivers/scsi/mpt3sas/mpt3sas_ctl.h b/drivers/scsi/mpt3sas/mpt3sas_ctl.h index d2ccdafb8df2..8f6ffb40261c 100644 --- a/drivers/scsi/mpt3sas/mpt3sas_ctl.h +++ b/drivers/scsi/mpt3sas/mpt3sas_ctl.h @@ -50,6 +50,8 @@ #include #endif +#include "mpt3sas_base.h" + #ifndef MPT2SAS_MINOR #define MPT2SAS_MINOR (MPT_MINOR + 1) #endif @@ -436,19 +438,13 @@ struct mpt3_diag_read_buffer { * struct mpt3_addnl_diag_query - diagnostic buffer release reason * @hdr - generic header * @unique_id - unique id associated with this buffer. - * @buffer_rel_condition - Release condition ioctl/sysfs/reset - * @reserved1 - * @trigger_type - Master/Event/scsi/MPI - * @trigger_info_dwords - Data Correspondig to trigger type + * @rel_query - release query. * @reserved2 */ struct mpt3_addnl_diag_query { struct mpt3_ioctl_header hdr; uint32_t unique_id; - uint16_t buffer_rel_condition; - uint16_t reserved1; - uint32_t trigger_type; - uint32_t trigger_info_dwords[2]; + struct htb_rel_query rel_query; uint32_t reserved2[2]; }; From efd2617100d9c6a49c8cd27160a2353b04844d78 Mon Sep 17 00:00:00 2001 From: Qiheng Lin Date: Fri, 9 Apr 2021 20:09:25 +0800 Subject: [PATCH 351/412] scsi: qla2xxx: Remove unneeded if-null-free check Eliminate the following coccicheck warning: drivers/scsi/qla2xxx/qla_os.c:4622:2-7: WARNING: NULL check before some freeing functions is not needed. drivers/scsi/qla2xxx/qla_os.c:4637:3-8: WARNING: NULL check before some freeing functions is not needed. Link: https://lore.kernel.org/r/20210409120925.7122-1-linqiheng@huawei.com Reviewed-by: Himanshu Madhani Signed-off-by: Qiheng Lin Signed-off-by: Martin K. Petersen --- drivers/scsi/qla2xxx/qla_os.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/drivers/scsi/qla2xxx/qla_os.c b/drivers/scsi/qla2xxx/qla_os.c index 12959e3874cb..d74c32f84ef5 100644 --- a/drivers/scsi/qla2xxx/qla_os.c +++ b/drivers/scsi/qla2xxx/qla_os.c @@ -4618,8 +4618,7 @@ qla2x00_free_fw_dump(struct qla_hw_data *ha) dma_free_coherent(&ha->pdev->dev, EFT_SIZE, ha->eft, ha->eft_dma); - if (ha->fw_dump) - vfree(ha->fw_dump); + vfree(ha->fw_dump); ha->fce = NULL; ha->fce_dma = 0; @@ -4633,8 +4632,7 @@ qla2x00_free_fw_dump(struct qla_hw_data *ha) ha->fw_dump_len = 0; for (j = 0; j < 2; j++, fwdt++) { - if (fwdt->template) - vfree(fwdt->template); + vfree(fwdt->template); fwdt->template = NULL; fwdt->length = 0; } From 5dc3468888f8ba54c3a2fdd38b13288f6b8daed2 Mon Sep 17 00:00:00 2001 From: Christophe JAILLET Date: Sun, 11 Apr 2021 11:21:40 +0200 Subject: [PATCH 352/412] scsi: qla2xxx: Reuse existing error handling path There is no need to duplicate code, use the existing error handling path to free resources. This is more future-proof. Link: https://lore.kernel.org/r/6973844a1532ec2dc8e86f3533362e79d78ed774.1618132821.git.christophe.jaillet@wanadoo.fr Reviewed-by: Bart Van Assche Signed-off-by: Christophe JAILLET Signed-off-by: Martin K. Petersen --- drivers/scsi/qla2xxx/qla_bsg.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/scsi/qla2xxx/qla_bsg.c b/drivers/scsi/qla2xxx/qla_bsg.c index aef2f7cc89d3..d42b2ad84049 100644 --- a/drivers/scsi/qla2xxx/qla_bsg.c +++ b/drivers/scsi/qla2xxx/qla_bsg.c @@ -2585,8 +2585,8 @@ qla2x00_get_host_stats(struct bsg_job *bsg_job) data = kzalloc(response_len, GFP_KERNEL); if (!data) { - kfree(req_data); - return -ENOMEM; + ret = -ENOMEM; + goto host_stat_out; } ret = qla2xxx_get_ini_stats(fc_bsg_to_shost(bsg_job), req_data->stat_type, From eb5a3e3b75fe31a5ce53ad632bbc96c76c63d3e9 Mon Sep 17 00:00:00 2001 From: Qiheng Lin Date: Fri, 9 Apr 2021 20:03:45 +0800 Subject: [PATCH 353/412] scsi: qla4xxx: Remove unneeded if-null-free check Eliminate the following coccicheck warning: drivers/scsi/qla4xxx/ql4_os.c:4175:2-7: WARNING: NULL check before some freeing functions is not needed. drivers/scsi/qla4xxx/ql4_os.c:4196:2-7: WARNING: NULL check before some freeing functions is not needed. drivers/scsi/qla4xxx/ql4_os.c:4215:2-7: WARNING: NULL check before some freeing functions is not needed. drivers/scsi/qla4xxx/ql4_os.c:6400:2-7: WARNING: NULL check before some freeing functions is not needed. drivers/scsi/qla4xxx/ql4_os.c:6402:2-7: WARNING: NULL check before some freeing functions is not needed. drivers/scsi/qla4xxx/ql4_os.c:6555:2-7: WARNING: NULL check before some freeing functions is not needed. drivers/scsi/qla4xxx/ql4_os.c:6557:2-7: WARNING: NULL check before some freeing functions is not needed. drivers/scsi/qla4xxx/ql4_os.c:7838:2-7: WARNING: NULL check before some freeing functions is not needed. drivers/scsi/qla4xxx/ql4_os.c:7840:2-7: WARNING: NULL check before some freeing functions is not needed. Link: https://lore.kernel.org/r/20210409120345.6447-1-linqiheng@huawei.com Signed-off-by: Qiheng Lin Signed-off-by: Martin K. Petersen --- drivers/scsi/qla4xxx/ql4_os.c | 27 +++++++++------------------ 1 file changed, 9 insertions(+), 18 deletions(-) diff --git a/drivers/scsi/qla4xxx/ql4_os.c b/drivers/scsi/qla4xxx/ql4_os.c index 867730ed21f7..ad3afe30f617 100644 --- a/drivers/scsi/qla4xxx/ql4_os.c +++ b/drivers/scsi/qla4xxx/ql4_os.c @@ -4171,8 +4171,7 @@ static void qla4xxx_mem_free(struct scsi_qla_host *ha) dma_free_coherent(&ha->pdev->dev, ha->queues_len, ha->queues, ha->queues_dma); - if (ha->fw_dump) - vfree(ha->fw_dump); + vfree(ha->fw_dump); ha->queues_len = 0; ha->queues = NULL; @@ -4192,8 +4191,7 @@ static void qla4xxx_mem_free(struct scsi_qla_host *ha) dma_pool_destroy(ha->chap_dma_pool); - if (ha->chap_list) - vfree(ha->chap_list); + vfree(ha->chap_list); ha->chap_list = NULL; dma_pool_destroy(ha->fw_ddb_dma_pool); @@ -4211,8 +4209,7 @@ static void qla4xxx_mem_free(struct scsi_qla_host *ha) iounmap(ha->reg); } - if (ha->reset_tmplt.buff) - vfree(ha->reset_tmplt.buff); + vfree(ha->reset_tmplt.buff); pci_release_regions(ha->pdev); } @@ -6396,10 +6393,8 @@ static int qla4xxx_is_session_exists(struct scsi_qla_host *ha, } exit_check: - if (fw_tddb) - vfree(fw_tddb); - if (tmp_tddb) - vfree(tmp_tddb); + vfree(fw_tddb); + vfree(tmp_tddb); return ret; } @@ -6551,10 +6546,8 @@ static int qla4xxx_is_flash_ddb_exists(struct scsi_qla_host *ha, } exit_check: - if (fw_tddb) - vfree(fw_tddb); - if (tmp_tddb) - vfree(tmp_tddb); + vfree(fw_tddb); + vfree(tmp_tddb); return ret; } @@ -7834,10 +7827,8 @@ static int qla4xxx_sysfs_ddb_logout(struct iscsi_bus_flash_session *fnode_sess, ret = -ESRCH; exit_ddb_logout: - if (flash_tddb) - vfree(flash_tddb); - if (tmp_tddb) - vfree(tmp_tddb); + vfree(flash_tddb); + vfree(tmp_tddb); if (fw_ddb_entry) dma_pool_free(ha->fw_ddb_dma_pool, fw_ddb_entry, fw_ddb_dma); From 039cf38166486ac42ce54df3c4cb951561e91617 Mon Sep 17 00:00:00 2001 From: Zhen Lei Date: Thu, 8 Apr 2021 14:18:49 +0800 Subject: [PATCH 354/412] scsi: message: fusion: Remove unused local variable 'time_count' MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fixes the following W=1 kernel build warning: drivers/message/fusion/mptctl.c: In function ‘mptctl_do_taskmgmt: drivers/message/fusion/mptctl.c:324:17: warning: variable ‘time_count’ set but not used [-Wunused-but-set-variable] Link: https://lore.kernel.org/r/20210408061851.3089-2-thunder.leizhen@huawei.com Fixes: 7d757f185540 ("[SCSI] mptfusion: Updated SCSI IO IOCTL error handling.") Reported-by: Hulk Robot Signed-off-by: Zhen Lei Signed-off-by: Martin K. Petersen --- drivers/message/fusion/mptctl.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/drivers/message/fusion/mptctl.c b/drivers/message/fusion/mptctl.c index 24aebad60366..0a9321239e76 100644 --- a/drivers/message/fusion/mptctl.c +++ b/drivers/message/fusion/mptctl.c @@ -321,7 +321,6 @@ mptctl_do_taskmgmt(MPT_ADAPTER *ioc, u8 tm_type, u8 bus_id, u8 target_id) int ii; int retval; unsigned long timeout; - unsigned long time_count; u16 iocstatus; @@ -383,7 +382,6 @@ mptctl_do_taskmgmt(MPT_ADAPTER *ioc, u8 tm_type, u8 bus_id, u8 target_id) ioc->name, tm_type, timeout)); INITIALIZE_MGMT_STATUS(ioc->taskmgmt_cmds.status) - time_count = jiffies; if ((ioc->facts.IOCCapabilities & MPI_IOCFACTS_CAPABILITY_HIGH_PRI_Q) && (ioc->facts.MsgVersion >= MPI_VERSION_01_05)) mpt_put_msg_frame_hi_pri(mptctl_taskmgmt_id, ioc, mf); From 30264737bd954a2af6361316b862afeed579d103 Mon Sep 17 00:00:00 2001 From: Zhen Lei Date: Thu, 8 Apr 2021 14:18:50 +0800 Subject: [PATCH 355/412] scsi: message: fusion: Remove unused local variable 'port' MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fixes the following W=1 kernel build warning: drivers/message/fusion/mptctl.c: In function ‘mptctl_gettargetinfo drivers/message/fusion/mptctl.c:1372:7: warning: variable ‘port’ set but not used [-Wunused-but-set-variable] Link: https://lore.kernel.org/r/20210408061851.3089-3-thunder.leizhen@huawei.com Reported-by: Hulk Robot Signed-off-by: Zhen Lei Signed-off-by: Martin K. Petersen --- drivers/message/fusion/mptctl.c | 6 ------ 1 file changed, 6 deletions(-) diff --git a/drivers/message/fusion/mptctl.c b/drivers/message/fusion/mptctl.c index 0a9321239e76..72025996cd70 100644 --- a/drivers/message/fusion/mptctl.c +++ b/drivers/message/fusion/mptctl.c @@ -1367,7 +1367,6 @@ mptctl_gettargetinfo (MPT_ADAPTER *ioc, unsigned long arg) int lun; int maxWordsLeft; int numBytes; - u8 port; struct scsi_device *sdev; if (copy_from_user(&karg, uarg, sizeof(struct mpt_ioctl_targetinfo))) { @@ -1379,13 +1378,8 @@ mptctl_gettargetinfo (MPT_ADAPTER *ioc, unsigned long arg) dctlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "mptctl_gettargetinfo called.\n", ioc->name)); - /* Get the port number and set the maximum number of bytes - * in the returned structure. - * Ignore the port setting. - */ numBytes = karg.hdr.maxDataSize - sizeof(mpt_ioctl_header); maxWordsLeft = numBytes/sizeof(int); - port = karg.hdr.port; if (maxWordsLeft <= 0) { printk(MYIOC_s_ERR_FMT "%s@%d::mptctl_gettargetinfo() - no memory available!\n", From c436b41a99b74936eb0a0ff34c42696ae36da156 Mon Sep 17 00:00:00 2001 From: Jiapeng Chong Date: Thu, 8 Apr 2021 17:06:20 +0800 Subject: [PATCH 356/412] scsi: message: fusion: Remove unused local variable 'status' MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fix the following gcc warning: drivers/message/fusion/mptbase.c:3087:9: warning: variable ‘status’ set but not used [-Wunused-but-set-variable]. Link: https://lore.kernel.org/r/1617872780-126448-1-git-send-email-jiapeng.chong@linux.alibaba.com Reported-by: Abaci Robot Signed-off-by: Jiapeng Chong Signed-off-by: Martin K. Petersen --- drivers/message/fusion/mptbase.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/message/fusion/mptbase.c b/drivers/message/fusion/mptbase.c index fa9b1223c9de..f4f89cf23631 100644 --- a/drivers/message/fusion/mptbase.c +++ b/drivers/message/fusion/mptbase.c @@ -3084,7 +3084,7 @@ GetIocFacts(MPT_ADAPTER *ioc, int sleepFlag, int reason) int req_sz; int reply_sz; int sz; - u32 status, vv; + u32 vv; u8 shiftFactor=1; /* IOC *must* NOT be in RESET state! */ @@ -3142,7 +3142,6 @@ GetIocFacts(MPT_ADAPTER *ioc, int sleepFlag, int reason) facts->IOCExceptions = le16_to_cpu(facts->IOCExceptions); facts->IOCStatus = le16_to_cpu(facts->IOCStatus); facts->IOCLogInfo = le32_to_cpu(facts->IOCLogInfo); - status = le16_to_cpu(facts->IOCStatus) & MPI_IOCSTATUS_MASK; /* CHECKME! IOCStatus, IOCLogInfo */ facts->ReplyQueueDepth = le16_to_cpu(facts->ReplyQueueDepth); From cf17ff2678806780ddfe33cf3e9457f369170661 Mon Sep 17 00:00:00 2001 From: Jiapeng Chong Date: Mon, 12 Apr 2021 13:59:06 +0800 Subject: [PATCH 357/412] scsi: message: fusion: Remove unused local variable 'vtarget' MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fix the following gcc warning: drivers/message/fusion/mptsas.c:783:14: warning: variable ‘vtarget’ set but not used [-Wunused-but-set-variable]. Link: https://lore.kernel.org/r/1618207146-96542-1-git-send-email-jiapeng.chong@linux.alibaba.com Reported-by: Abaci Robot Signed-off-by: Jiapeng Chong Signed-off-by: Martin K. Petersen --- drivers/message/fusion/mptsas.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/drivers/message/fusion/mptsas.c b/drivers/message/fusion/mptsas.c index 1857869e7e8d..e0a65a348502 100644 --- a/drivers/message/fusion/mptsas.c +++ b/drivers/message/fusion/mptsas.c @@ -780,13 +780,11 @@ static void mptsas_add_device_component_starget(MPT_ADAPTER *ioc, struct scsi_target *starget) { - VirtTarget *vtarget; struct sas_rphy *rphy; struct mptsas_phyinfo *phy_info = NULL; struct mptsas_enclosure enclosure_info; rphy = dev_to_rphy(starget->dev.parent); - vtarget = starget->hostdata; phy_info = mptsas_find_phyinfo_by_sas_address(ioc, rphy->identify.sas_address); if (!phy_info) From 8350e19658c1632874888971052a5ace92dae7c5 Mon Sep 17 00:00:00 2001 From: Wan Jiabing Date: Tue, 6 Apr 2021 18:59:13 +0800 Subject: [PATCH 358/412] scsi: isci: Remove unnecessary struct declaration struct sci_phy_proto was already defined on line 142. The declaration here is unnecessary. Remove it. Link: https://lore.kernel.org/r/20210406105913.676746-1-wanjiabing@vivo.com Signed-off-by: Wan Jiabing Signed-off-by: Martin K. Petersen --- drivers/scsi/isci/phy.h | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/scsi/isci/phy.h b/drivers/scsi/isci/phy.h index 45fecfa36a98..5aaf95b14b2e 100644 --- a/drivers/scsi/isci/phy.h +++ b/drivers/scsi/isci/phy.h @@ -447,7 +447,6 @@ void sci_phy_get_attached_sas_address( struct isci_phy *iphy, struct sci_sas_address *sas_address); -struct sci_phy_proto; void sci_phy_get_protocols( struct isci_phy *iphy, struct sci_phy_proto *protocols); From 078c68b87a717b9fcd8e0f2109f73456fbc55490 Mon Sep 17 00:00:00 2001 From: James Smart Date: Sun, 11 Apr 2021 18:31:12 -0700 Subject: [PATCH 359/412] scsi: lpfc: Fix rmmod crash due to bad ring pointers to abort_iotag Rmmod on SLI-4 adapters is sometimes hitting a bad ptr dereference in lpfc_els_free_iocb(). A prior patch refactored the lpfc_sli_abort_iocb() routine. One of the changes was to convert from building/sending an abort within the routine to using a common routine. The reworked routine passes, without modification, the pring ptr to the new common routine. The older routine had logic to check SLI-3 vs SLI-4 and adapt the pring ptr if necessary as callers were passing SLI-3 pointers even when not on an SLI-4 adapter. The new routine is missing this check and adapt, so the SLI-3 ring pointers are being used in SLI-4 paths. Fix by cleaning up the calling routines. In review, there is no need to pass the ring ptr argument to abort_iocb at all. The routine can look at the adapter type itself and reference the proper ring. Link: https://lore.kernel.org/r/20210412013127.2387-2-jsmart2021@gmail.com Fixes: db7531d2b377 ("scsi: lpfc: Convert abort handling to SLI-3 and SLI-4 handlers") Cc: # v5.11+ Co-developed-by: Justin Tee Signed-off-by: Justin Tee Signed-off-by: James Smart Signed-off-by: Martin K. Petersen --- drivers/scsi/lpfc/lpfc_crtn.h | 4 ++-- drivers/scsi/lpfc/lpfc_hbadisc.c | 10 +++------- drivers/scsi/lpfc/lpfc_nportdisc.c | 4 +--- drivers/scsi/lpfc/lpfc_sli.c | 20 +++++++++++++++----- 4 files changed, 21 insertions(+), 17 deletions(-) diff --git a/drivers/scsi/lpfc/lpfc_crtn.h b/drivers/scsi/lpfc/lpfc_crtn.h index eb4cf36229d5..e7db4496e8a9 100644 --- a/drivers/scsi/lpfc/lpfc_crtn.h +++ b/drivers/scsi/lpfc/lpfc_crtn.h @@ -353,8 +353,8 @@ int lpfc_sli_hbq_size(void); int lpfc_sli_issue_abort_iotag(struct lpfc_hba *, struct lpfc_sli_ring *, struct lpfc_iocbq *, void *); int lpfc_sli_sum_iocb(struct lpfc_vport *, uint16_t, uint64_t, lpfc_ctx_cmd); -int lpfc_sli_abort_iocb(struct lpfc_vport *, struct lpfc_sli_ring *, uint16_t, - uint64_t, lpfc_ctx_cmd); +int lpfc_sli_abort_iocb(struct lpfc_vport *vport, u16 tgt_id, u64 lun_id, + lpfc_ctx_cmd abort_cmd); int lpfc_sli_abort_taskmgmt(struct lpfc_vport *, struct lpfc_sli_ring *, uint16_t, uint64_t, lpfc_ctx_cmd); diff --git a/drivers/scsi/lpfc/lpfc_hbadisc.c b/drivers/scsi/lpfc/lpfc_hbadisc.c index 3b5cd23dd172..85633eb7524f 100644 --- a/drivers/scsi/lpfc/lpfc_hbadisc.c +++ b/drivers/scsi/lpfc/lpfc_hbadisc.c @@ -140,11 +140,8 @@ lpfc_terminate_rport_io(struct fc_rport *rport) "rport terminate: sid:x%x did:x%x flg:x%x", ndlp->nlp_sid, ndlp->nlp_DID, ndlp->nlp_flag); - if (ndlp->nlp_sid != NLP_NO_SID) { - lpfc_sli_abort_iocb(vport, - &vport->phba->sli.sli3_ring[LPFC_FCP_RING], - ndlp->nlp_sid, 0, LPFC_CTX_TGT); - } + if (ndlp->nlp_sid != NLP_NO_SID) + lpfc_sli_abort_iocb(vport, ndlp->nlp_sid, 0, LPFC_CTX_TGT); } /* @@ -299,8 +296,7 @@ lpfc_dev_loss_tmo_handler(struct lpfc_nodelist *ndlp) if (ndlp->nlp_sid != NLP_NO_SID) { warn_on = 1; - lpfc_sli_abort_iocb(vport, &phba->sli.sli3_ring[LPFC_FCP_RING], - ndlp->nlp_sid, 0, LPFC_CTX_TGT); + lpfc_sli_abort_iocb(vport, ndlp->nlp_sid, 0, LPFC_CTX_TGT); } if (warn_on) { diff --git a/drivers/scsi/lpfc/lpfc_nportdisc.c b/drivers/scsi/lpfc/lpfc_nportdisc.c index 9aa907ce4c63..8472c5e716db 100644 --- a/drivers/scsi/lpfc/lpfc_nportdisc.c +++ b/drivers/scsi/lpfc/lpfc_nportdisc.c @@ -2559,12 +2559,10 @@ static uint32_t lpfc_rcv_prlo_mapped_node(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp, void *arg, uint32_t evt) { - struct lpfc_hba *phba = vport->phba; struct lpfc_iocbq *cmdiocb = (struct lpfc_iocbq *) arg; /* flush the target */ - lpfc_sli_abort_iocb(vport, &phba->sli.sli3_ring[LPFC_FCP_RING], - ndlp->nlp_sid, 0, LPFC_CTX_TGT); + lpfc_sli_abort_iocb(vport, ndlp->nlp_sid, 0, LPFC_CTX_TGT); /* Treat like rcv logo */ lpfc_rcv_logo(vport, ndlp, cmdiocb, ELS_CMD_PRLO); diff --git a/drivers/scsi/lpfc/lpfc_sli.c b/drivers/scsi/lpfc/lpfc_sli.c index f6e1e36eabdc..7832f8470667 100644 --- a/drivers/scsi/lpfc/lpfc_sli.c +++ b/drivers/scsi/lpfc/lpfc_sli.c @@ -11644,7 +11644,7 @@ lpfc_sli_issue_abort_iotag(struct lpfc_hba *phba, struct lpfc_sli_ring *pring, icmd = &cmdiocb->iocb; if (icmd->ulpCommand == CMD_ABORT_XRI_CN || icmd->ulpCommand == CMD_CLOSE_XRI_CN || - (cmdiocb->iocb_flag & LPFC_DRIVER_ABORTED) != 0) + cmdiocb->iocb_flag & LPFC_DRIVER_ABORTED) return IOCB_ABORTING; if (!pring) { @@ -11942,7 +11942,6 @@ lpfc_sli_abort_fcp_cmpl(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, /** * lpfc_sli_abort_iocb - issue abort for all commands on a host/target/LUN * @vport: Pointer to virtual port. - * @pring: Pointer to driver SLI ring object. * @tgt_id: SCSI ID of the target. * @lun_id: LUN ID of the scsi device. * @abort_cmd: LPFC_CTX_LUN/LPFC_CTX_TGT/LPFC_CTX_HOST. @@ -11957,18 +11956,22 @@ lpfc_sli_abort_fcp_cmpl(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, * FCP iocbs associated with SCSI target specified by tgt_id parameter. * When abort_cmd == LPFC_CTX_HOST, the function sends abort to all * FCP iocbs associated with virtual port. + * The pring used for SLI3 is sli3_ring[LPFC_FCP_RING], for SLI4 + * lpfc_sli4_calc_ring is used. * This function returns number of iocbs it failed to abort. * This function is called with no locks held. **/ int -lpfc_sli_abort_iocb(struct lpfc_vport *vport, struct lpfc_sli_ring *pring, - uint16_t tgt_id, uint64_t lun_id, lpfc_ctx_cmd abort_cmd) +lpfc_sli_abort_iocb(struct lpfc_vport *vport, u16 tgt_id, u64 lun_id, + lpfc_ctx_cmd abort_cmd) { struct lpfc_hba *phba = vport->phba; + struct lpfc_sli_ring *pring = NULL; struct lpfc_iocbq *iocbq; int errcnt = 0, ret_val = 0; unsigned long iflags; int i; + void *fcp_cmpl = NULL; /* all I/Os are in process of being flushed */ if (phba->hba_flag & HBA_IOQ_FLUSH) @@ -11982,8 +11985,15 @@ lpfc_sli_abort_iocb(struct lpfc_vport *vport, struct lpfc_sli_ring *pring, continue; spin_lock_irqsave(&phba->hbalock, iflags); + if (phba->sli_rev == LPFC_SLI_REV3) { + pring = &phba->sli.sli3_ring[LPFC_FCP_RING]; + fcp_cmpl = lpfc_sli_abort_fcp_cmpl; + } else if (phba->sli_rev == LPFC_SLI_REV4) { + pring = lpfc_sli4_calc_ring(phba, iocbq); + fcp_cmpl = lpfc_sli4_abort_fcp_cmpl; + } ret_val = lpfc_sli_issue_abort_iotag(phba, pring, iocbq, - lpfc_sli_abort_fcp_cmpl); + fcp_cmpl); spin_unlock_irqrestore(&phba->hbalock, iflags); if (ret_val != IOCB_SUCCESS) errcnt++; From fffd18ec6579c2d9c72b212169259062fe747888 Mon Sep 17 00:00:00 2001 From: James Smart Date: Sun, 11 Apr 2021 18:31:13 -0700 Subject: [PATCH 360/412] scsi: lpfc: Fix crash when a REG_RPI mailbox fails triggering a LOGO response Fix a crash caused by a double put on the node when the driver completed an ACC for an unsolicted abort on the same node. The second put was executed by lpfc_nlp_not_used() and is wrong because the completion routine executes the nlp_put when the iocbq was released. Additionally, the driver is issuing a LOGO then immediately calls lpfc_nlp_set_state to put the node into NPR. This call does nothing. Remove the lpfc_nlp_not_used call and additional set_state in the completion routine. Remove the lpfc_nlp_set_state post issue_logo. Isn't necessary. Link: https://lore.kernel.org/r/20210412013127.2387-3-jsmart2021@gmail.com Co-developed-by: Justin Tee Signed-off-by: Justin Tee Signed-off-by: James Smart Signed-off-by: Martin K. Petersen --- drivers/scsi/lpfc/lpfc_nportdisc.c | 2 -- drivers/scsi/lpfc/lpfc_sli.c | 1 - 2 files changed, 3 deletions(-) diff --git a/drivers/scsi/lpfc/lpfc_nportdisc.c b/drivers/scsi/lpfc/lpfc_nportdisc.c index 8472c5e716db..fd3d0197d155 100644 --- a/drivers/scsi/lpfc/lpfc_nportdisc.c +++ b/drivers/scsi/lpfc/lpfc_nportdisc.c @@ -1901,8 +1901,6 @@ lpfc_cmpl_reglogin_reglogin_issue(struct lpfc_vport *vport, ndlp->nlp_last_elscmd = ELS_CMD_PLOGI; lpfc_issue_els_logo(vport, ndlp, 0); - ndlp->nlp_prev_state = NLP_STE_REG_LOGIN_ISSUE; - lpfc_nlp_set_state(vport, ndlp, NLP_STE_NPR_NODE); return ndlp->nlp_state; } diff --git a/drivers/scsi/lpfc/lpfc_sli.c b/drivers/scsi/lpfc/lpfc_sli.c index 7832f8470667..cd9943f91eff 100644 --- a/drivers/scsi/lpfc/lpfc_sli.c +++ b/drivers/scsi/lpfc/lpfc_sli.c @@ -18071,7 +18071,6 @@ lpfc_sli4_seq_abort_rsp_cmpl(struct lpfc_hba *phba, if (cmd_iocbq) { ndlp = (struct lpfc_nodelist *)cmd_iocbq->context1; lpfc_nlp_put(ndlp); - lpfc_nlp_not_used(ndlp); lpfc_sli_release_iocbq(phba, cmd_iocbq); } From f866eb06c087125619457b53e9211a9e758f64f7 Mon Sep 17 00:00:00 2001 From: James Smart Date: Sun, 11 Apr 2021 18:31:14 -0700 Subject: [PATCH 361/412] scsi: lpfc: Fix reference counting errors in lpfc_cmpl_els_rsp() Call traces are being seen that result from a nodelist structure ref counting error. They are typically seen after transmission of an LS_RJT ELS response. Aged code in lpfc_cmpl_els_rsp() calls lpfc_nlp_not_used() which, if the ndlp reference count is exactly 1, will decrement the reference count. Previously lpfc_nlp_put() was within lpfc_els_free_iocb(), and the 'put' within the free would only be invoked if cmdiocb->context1 was not NULL. Since the nodelist structure reference count is decremented when exiting lpfc_cmpl_els_rsp() the lpfc_nlp_not_used() calls are no longer required. Calling them is causing the reference count issue. Fix by removing the lpfc_nlp_not_used() calls. Link: https://lore.kernel.org/r/20210412013127.2387-4-jsmart2021@gmail.com Co-developed-by: Justin Tee Signed-off-by: Justin Tee Signed-off-by: James Smart Signed-off-by: Martin K. Petersen --- drivers/scsi/lpfc/lpfc_els.c | 64 +----------------------------------- 1 file changed, 1 insertion(+), 63 deletions(-) diff --git a/drivers/scsi/lpfc/lpfc_els.c b/drivers/scsi/lpfc/lpfc_els.c index a04546eca18f..c62c141342a6 100644 --- a/drivers/scsi/lpfc/lpfc_els.c +++ b/drivers/scsi/lpfc/lpfc_els.c @@ -4444,10 +4444,7 @@ lpfc_mbx_cmpl_dflt_rpi(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb) * nlp_flag bitmap in the ndlp data structure, if the mbox command reference * field in the command IOCB is not NULL, the referred mailbox command will * be send out, and then invokes the lpfc_els_free_iocb() routine to release - * the IOCB. Under error conditions, such as when a LS_RJT is returned or a - * link down event occurred during the discovery, the lpfc_nlp_not_used() - * routine shall be invoked trying to release the ndlp if no other threads - * are currently referring it. + * the IOCB. **/ static void lpfc_cmpl_els_rsp(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, @@ -4457,10 +4454,8 @@ lpfc_cmpl_els_rsp(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, struct lpfc_vport *vport = ndlp ? ndlp->vport : NULL; struct Scsi_Host *shost = vport ? lpfc_shost_from_vport(vport) : NULL; IOCB_t *irsp; - uint8_t *pcmd; LPFC_MBOXQ_t *mbox = NULL; struct lpfc_dmabuf *mp = NULL; - uint32_t ls_rjt = 0; irsp = &rspiocb->iocb; @@ -4472,18 +4467,6 @@ lpfc_cmpl_els_rsp(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, if (cmdiocb->context_un.mbox) mbox = cmdiocb->context_un.mbox; - /* First determine if this is a LS_RJT cmpl. Note, this callback - * function can have cmdiocb->contest1 (ndlp) field set to NULL. - */ - pcmd = (uint8_t *) (((struct lpfc_dmabuf *) cmdiocb->context2)->virt); - if (ndlp && (*((uint32_t *) (pcmd)) == ELS_CMD_LS_RJT)) { - /* A LS_RJT associated with Default RPI cleanup has its own - * separate code path. - */ - if (!(ndlp->nlp_flag & NLP_RM_DFLT_RPI)) - ls_rjt = 1; - } - /* Check to see if link went down during discovery */ if (!ndlp || lpfc_els_chk_latt(vport)) { if (mbox) { @@ -4494,15 +4477,6 @@ lpfc_cmpl_els_rsp(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, } mempool_free(mbox, phba->mbox_mem_pool); } - if (ndlp && (ndlp->nlp_flag & NLP_RM_DFLT_RPI)) - if (lpfc_nlp_not_used(ndlp)) { - ndlp = NULL; - /* Indicate the node has already released, - * should not reference to it from within - * the routine lpfc_els_free_iocb. - */ - cmdiocb->context1 = NULL; - } goto out; } @@ -4580,29 +4554,6 @@ lpfc_cmpl_els_rsp(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, "Data: x%x x%x x%x\n", ndlp->nlp_DID, ndlp->nlp_flag, ndlp->nlp_state, ndlp->nlp_rpi); - - if (lpfc_nlp_not_used(ndlp)) { - ndlp = NULL; - /* Indicate node has already been released, - * should not reference to it from within - * the routine lpfc_els_free_iocb. - */ - cmdiocb->context1 = NULL; - } - } else { - /* Do not drop node for lpfc_els_abort'ed ELS cmds */ - if (!lpfc_error_lost_link(irsp) && - ndlp->nlp_flag & NLP_ACC_REGLOGIN) { - if (lpfc_nlp_not_used(ndlp)) { - ndlp = NULL; - /* Indicate node has already been - * released, should not reference - * to it from within the routine - * lpfc_els_free_iocb. - */ - cmdiocb->context1 = NULL; - } - } } mp = (struct lpfc_dmabuf *)mbox->ctx_buf; if (mp) { @@ -4618,19 +4569,6 @@ out: ndlp->nlp_flag &= ~NLP_ACC_REGLOGIN; ndlp->nlp_flag &= ~NLP_RM_DFLT_RPI; spin_unlock_irq(&ndlp->lock); - - /* If the node is not being used by another discovery thread, - * and we are sending a reject, we are done with it. - * Release driver reference count here and free associated - * resources. - */ - if (ls_rjt) - if (lpfc_nlp_not_used(ndlp)) - /* Indicate node has already been released, - * should not reference to it from within - * the routine lpfc_els_free_iocb. - */ - cmdiocb->context1 = NULL; } /* Release the originating I/O reference. */ From a789241e49b6adce84cdba7a24c92ecc845aface Mon Sep 17 00:00:00 2001 From: James Smart Date: Sun, 11 Apr 2021 18:31:15 -0700 Subject: [PATCH 362/412] scsi: lpfc: Fix NMI crash during rmmod due to circular hbalock dependency Remove hbalock dependency for lpfc_abts_els_sgl_list and lpfc_abts_nvmet_ctx_list. The lists are adaquately synchronized with the sgl_list_lock and abts_nvmet_buf_list_lock. Link: https://lore.kernel.org/r/20210412013127.2387-5-jsmart2021@gmail.com Co-developed-by: Justin Tee Signed-off-by: Justin Tee Signed-off-by: James Smart Signed-off-by: Martin K. Petersen --- drivers/scsi/lpfc/lpfc_els.c | 24 +++++++++--------------- drivers/scsi/lpfc/lpfc_init.c | 26 ++++++++++---------------- drivers/scsi/lpfc/lpfc_nvmet.c | 26 +++++++++++--------------- 3 files changed, 30 insertions(+), 46 deletions(-) diff --git a/drivers/scsi/lpfc/lpfc_els.c b/drivers/scsi/lpfc/lpfc_els.c index c62c141342a6..1bb1e3cf7113 100644 --- a/drivers/scsi/lpfc/lpfc_els.c +++ b/drivers/scsi/lpfc/lpfc_els.c @@ -10072,8 +10072,7 @@ lpfc_sli4_vport_delete_els_xri_aborted(struct lpfc_vport *vport) struct lpfc_sglq *sglq_entry = NULL, *sglq_next = NULL; unsigned long iflag = 0; - spin_lock_irqsave(&phba->hbalock, iflag); - spin_lock(&phba->sli4_hba.sgl_list_lock); + spin_lock_irqsave(&phba->sli4_hba.sgl_list_lock, iflag); list_for_each_entry_safe(sglq_entry, sglq_next, &phba->sli4_hba.lpfc_abts_els_sgl_list, list) { if (sglq_entry->ndlp && sglq_entry->ndlp->vport == vport) { @@ -10081,8 +10080,7 @@ lpfc_sli4_vport_delete_els_xri_aborted(struct lpfc_vport *vport) sglq_entry->ndlp = NULL; } } - spin_unlock(&phba->sli4_hba.sgl_list_lock); - spin_unlock_irqrestore(&phba->hbalock, iflag); + spin_unlock_irqrestore(&phba->sli4_hba.sgl_list_lock, iflag); return; } @@ -10109,8 +10107,7 @@ lpfc_sli4_els_xri_aborted(struct lpfc_hba *phba, pring = lpfc_phba_elsring(phba); - spin_lock_irqsave(&phba->hbalock, iflag); - spin_lock(&phba->sli4_hba.sgl_list_lock); + spin_lock_irqsave(&phba->sli4_hba.sgl_list_lock, iflag); list_for_each_entry_safe(sglq_entry, sglq_next, &phba->sli4_hba.lpfc_abts_els_sgl_list, list) { if (sglq_entry->sli4_xritag == xri) { @@ -10120,8 +10117,8 @@ lpfc_sli4_els_xri_aborted(struct lpfc_hba *phba, list_add_tail(&sglq_entry->list, &phba->sli4_hba.lpfc_els_sgl_list); sglq_entry->state = SGL_FREED; - spin_unlock(&phba->sli4_hba.sgl_list_lock); - spin_unlock_irqrestore(&phba->hbalock, iflag); + spin_unlock_irqrestore(&phba->sli4_hba.sgl_list_lock, + iflag); if (ndlp) { lpfc_set_rrq_active(phba, ndlp, @@ -10136,21 +10133,18 @@ lpfc_sli4_els_xri_aborted(struct lpfc_hba *phba, return; } } - spin_unlock(&phba->sli4_hba.sgl_list_lock); + spin_unlock_irqrestore(&phba->sli4_hba.sgl_list_lock, iflag); lxri = lpfc_sli4_xri_inrange(phba, xri); - if (lxri == NO_XRI) { - spin_unlock_irqrestore(&phba->hbalock, iflag); + if (lxri == NO_XRI) return; - } - spin_lock(&phba->sli4_hba.sgl_list_lock); + + spin_lock_irqsave(&phba->hbalock, iflag); sglq_entry = __lpfc_get_active_sglq(phba, lxri); if (!sglq_entry || (sglq_entry->sli4_xritag != xri)) { - spin_unlock(&phba->sli4_hba.sgl_list_lock); spin_unlock_irqrestore(&phba->hbalock, iflag); return; } sglq_entry->state = SGL_XRI_ABORTED; - spin_unlock(&phba->sli4_hba.sgl_list_lock); spin_unlock_irqrestore(&phba->hbalock, iflag); return; } diff --git a/drivers/scsi/lpfc/lpfc_init.c b/drivers/scsi/lpfc/lpfc_init.c index 5ea43c527e08..631f22baf45f 100644 --- a/drivers/scsi/lpfc/lpfc_init.c +++ b/drivers/scsi/lpfc/lpfc_init.c @@ -1043,12 +1043,11 @@ lpfc_hba_down_post_s4(struct lpfc_hba *phba) * driver is unloading or reposted if the driver is restarting * the port. */ - spin_lock_irq(&phba->hbalock); /* required for lpfc_els_sgl_list and */ - /* scsl_buf_list */ + /* sgl_list_lock required because worker thread uses this * list. */ - spin_lock(&phba->sli4_hba.sgl_list_lock); + spin_lock_irq(&phba->sli4_hba.sgl_list_lock); list_for_each_entry(sglq_entry, &phba->sli4_hba.lpfc_abts_els_sgl_list, list) sglq_entry->state = SGL_FREED; @@ -1057,11 +1056,12 @@ lpfc_hba_down_post_s4(struct lpfc_hba *phba) &phba->sli4_hba.lpfc_els_sgl_list); - spin_unlock(&phba->sli4_hba.sgl_list_lock); + spin_unlock_irq(&phba->sli4_hba.sgl_list_lock); /* abts_xxxx_buf_list_lock required because worker thread uses this * list. */ + spin_lock_irq(&phba->hbalock); cnt = 0; for (idx = 0; idx < phba->cfg_hdw_queue; idx++) { qp = &phba->sli4_hba.hdwq[idx]; @@ -3804,12 +3804,10 @@ lpfc_sli4_els_sgl_update(struct lpfc_hba *phba) sglq_entry->state = SGL_FREED; list_add_tail(&sglq_entry->list, &els_sgl_list); } - spin_lock_irq(&phba->hbalock); - spin_lock(&phba->sli4_hba.sgl_list_lock); + spin_lock_irq(&phba->sli4_hba.sgl_list_lock); list_splice_init(&els_sgl_list, &phba->sli4_hba.lpfc_els_sgl_list); - spin_unlock(&phba->sli4_hba.sgl_list_lock); - spin_unlock_irq(&phba->hbalock); + spin_unlock_irq(&phba->sli4_hba.sgl_list_lock); } else if (els_xri_cnt < phba->sli4_hba.els_xri_cnt) { /* els xri-sgl shrinked */ xri_cnt = phba->sli4_hba.els_xri_cnt - els_xri_cnt; @@ -3817,8 +3815,7 @@ lpfc_sli4_els_sgl_update(struct lpfc_hba *phba) "3158 ELS xri-sgl count decreased from " "%d to %d\n", phba->sli4_hba.els_xri_cnt, els_xri_cnt); - spin_lock_irq(&phba->hbalock); - spin_lock(&phba->sli4_hba.sgl_list_lock); + spin_lock_irq(&phba->sli4_hba.sgl_list_lock); list_splice_init(&phba->sli4_hba.lpfc_els_sgl_list, &els_sgl_list); /* release extra els sgls from list */ @@ -3833,8 +3830,7 @@ lpfc_sli4_els_sgl_update(struct lpfc_hba *phba) } list_splice_init(&els_sgl_list, &phba->sli4_hba.lpfc_els_sgl_list); - spin_unlock(&phba->sli4_hba.sgl_list_lock); - spin_unlock_irq(&phba->hbalock); + spin_unlock_irq(&phba->sli4_hba.sgl_list_lock); } else lpfc_printf_log(phba, KERN_INFO, LOG_SLI, "3163 ELS xri-sgl count unchanged: %d\n", @@ -7388,11 +7384,9 @@ lpfc_free_els_sgl_list(struct lpfc_hba *phba) LIST_HEAD(sglq_list); /* Retrieve all els sgls from driver list */ - spin_lock_irq(&phba->hbalock); - spin_lock(&phba->sli4_hba.sgl_list_lock); + spin_lock_irq(&phba->sli4_hba.sgl_list_lock); list_splice_init(&phba->sli4_hba.lpfc_els_sgl_list, &sglq_list); - spin_unlock(&phba->sli4_hba.sgl_list_lock); - spin_unlock_irq(&phba->hbalock); + spin_unlock_irq(&phba->sli4_hba.sgl_list_lock); /* Now free the sgl list */ lpfc_free_sgl_list(phba, &sglq_list); diff --git a/drivers/scsi/lpfc/lpfc_nvmet.c b/drivers/scsi/lpfc/lpfc_nvmet.c index c84da8e6b65d..f2d9a3580887 100644 --- a/drivers/scsi/lpfc/lpfc_nvmet.c +++ b/drivers/scsi/lpfc/lpfc_nvmet.c @@ -1440,7 +1440,10 @@ __lpfc_nvmet_clean_io_for_cpu(struct lpfc_hba *phba, list_del_init(&ctx_buf->list); spin_unlock(&phba->sli4_hba.abts_nvmet_buf_list_lock); + spin_lock(&phba->hbalock); __lpfc_clear_active_sglq(phba, ctx_buf->sglq->sli4_lxritag); + spin_unlock(&phba->hbalock); + ctx_buf->sglq->state = SGL_FREED; ctx_buf->sglq->ndlp = NULL; @@ -1787,8 +1790,7 @@ lpfc_sli4_nvmet_xri_aborted(struct lpfc_hba *phba, atomic_inc(&tgtp->xmt_fcp_xri_abort_cqe); } - spin_lock_irqsave(&phba->hbalock, iflag); - spin_lock(&phba->sli4_hba.abts_nvmet_buf_list_lock); + spin_lock_irqsave(&phba->sli4_hba.abts_nvmet_buf_list_lock, iflag); list_for_each_entry_safe(ctxp, next_ctxp, &phba->sli4_hba.lpfc_abts_nvmet_ctx_list, list) { @@ -1806,10 +1808,10 @@ lpfc_sli4_nvmet_xri_aborted(struct lpfc_hba *phba, } ctxp->flag &= ~LPFC_NVME_XBUSY; spin_unlock(&ctxp->ctxlock); - spin_unlock(&phba->sli4_hba.abts_nvmet_buf_list_lock); + spin_unlock_irqrestore(&phba->sli4_hba.abts_nvmet_buf_list_lock, + iflag); rrq_empty = list_empty(&phba->active_rrq_list); - spin_unlock_irqrestore(&phba->hbalock, iflag); ndlp = lpfc_findnode_did(phba->pport, ctxp->sid); if (ndlp && (ndlp->nlp_state == NLP_STE_UNMAPPED_NODE || @@ -1830,9 +1832,7 @@ lpfc_sli4_nvmet_xri_aborted(struct lpfc_hba *phba, lpfc_worker_wake_up(phba); return; } - spin_unlock(&phba->sli4_hba.abts_nvmet_buf_list_lock); - spin_unlock_irqrestore(&phba->hbalock, iflag); - + spin_unlock_irqrestore(&phba->sli4_hba.abts_nvmet_buf_list_lock, iflag); ctxp = lpfc_nvmet_get_ctx_for_xri(phba, xri); if (ctxp) { /* @@ -1876,8 +1876,7 @@ lpfc_nvmet_rcv_unsol_abort(struct lpfc_vport *vport, sid = sli4_sid_from_fc_hdr(fc_hdr); oxid = be16_to_cpu(fc_hdr->fh_ox_id); - spin_lock_irqsave(&phba->hbalock, iflag); - spin_lock(&phba->sli4_hba.abts_nvmet_buf_list_lock); + spin_lock_irqsave(&phba->sli4_hba.abts_nvmet_buf_list_lock, iflag); list_for_each_entry_safe(ctxp, next_ctxp, &phba->sli4_hba.lpfc_abts_nvmet_ctx_list, list) { @@ -1886,9 +1885,8 @@ lpfc_nvmet_rcv_unsol_abort(struct lpfc_vport *vport, xri = ctxp->ctxbuf->sglq->sli4_xritag; - spin_unlock(&phba->sli4_hba.abts_nvmet_buf_list_lock); - spin_unlock_irqrestore(&phba->hbalock, iflag); - + spin_unlock_irqrestore(&phba->sli4_hba.abts_nvmet_buf_list_lock, + iflag); spin_lock_irqsave(&ctxp->ctxlock, iflag); ctxp->flag |= LPFC_NVME_ABTS_RCV; spin_unlock_irqrestore(&ctxp->ctxlock, iflag); @@ -1907,9 +1905,7 @@ lpfc_nvmet_rcv_unsol_abort(struct lpfc_vport *vport, lpfc_sli4_seq_abort_rsp(vport, fc_hdr, 1); return 0; } - spin_unlock(&phba->sli4_hba.abts_nvmet_buf_list_lock); - spin_unlock_irqrestore(&phba->hbalock, iflag); - + spin_unlock_irqrestore(&phba->sli4_hba.abts_nvmet_buf_list_lock, iflag); /* check the wait list */ if (phba->sli4_hba.nvmet_io_wait_cnt) { struct rqb_dmabuf *nvmebuf; From 4e76d4a9a226e3c7d453675f22359aba34e73ec4 Mon Sep 17 00:00:00 2001 From: James Smart Date: Sun, 11 Apr 2021 18:31:16 -0700 Subject: [PATCH 363/412] scsi: lpfc: Fix lack of device removal on port swaps with PRLIs During target port-swap testing with link flips, the initiator could encounter PRLI errors. If the target node disappears permanently, the ndlp is found stuck in UNUSED state with ref count of 1. The rmmod of the driver will hang waiting for this node to be freed. While handling a link error in PRLI completion path, the code intends to skip triggering the discovery state machine. However this is causing the final reference release path to be skipped. This causes the node to be stuck with ref count of 1 Fix by ensuring the code path triggers the device removal event on the node state machine. Link: https://lore.kernel.org/r/20210412013127.2387-6-jsmart2021@gmail.com Co-developed-by: Justin Tee Signed-off-by: Justin Tee Signed-off-by: James Smart Signed-off-by: Martin K. Petersen --- drivers/scsi/lpfc/lpfc_els.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/drivers/scsi/lpfc/lpfc_els.c b/drivers/scsi/lpfc/lpfc_els.c index 1bb1e3cf7113..ed57d92e96e1 100644 --- a/drivers/scsi/lpfc/lpfc_els.c +++ b/drivers/scsi/lpfc/lpfc_els.c @@ -2233,9 +2233,7 @@ lpfc_cmpl_els_prli(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, irsp->un.ulpWord[4], ndlp->fc4_prli_sent); /* Do not call DSM for lpfc_els_abort'ed ELS cmds */ - if (lpfc_error_lost_link(irsp)) - goto out; - else + if (!lpfc_error_lost_link(irsp)) lpfc_disc_state_machine(vport, ndlp, cmdiocb, NLP_EVT_CMPL_PRLI); From 304ee43238fed517faa123e034b593905b8679f8 Mon Sep 17 00:00:00 2001 From: James Smart Date: Sun, 11 Apr 2021 18:31:17 -0700 Subject: [PATCH 364/412] scsi: lpfc: Fix error handling for mailboxes completed in MBX_POLL mode In SLI-4, when performing a mailbox command with MBX_POLL, the driver uses the BMBX register to send the command rather than the MQ. A flag is set indicating the BMBX register is active and saves the mailbox job struct (mboxq) in the mbox_active element of the adapter. The routine then waits for completion or timeout. The mailbox job struct is not freed by the routine. In cases of timeout, the adapter will be reset. The lpfc_sli_mbox_sys_flush() routine will clean up the mbox in preparation for the reset. It clears the BMBX active flag and marks the job structure as MBX_NOT_FINISHED. But, it never frees the mboxq job structure. Expectation in both normal completion and timeout cases is that the issuer of the mbx command will free the structure. Unfortunately, not all calling paths are freeing the memory in cases of error. All calling paths were looked at and updated, if missing, to free the mboxq memory regardless of completion status. Link: https://lore.kernel.org/r/20210412013127.2387-7-jsmart2021@gmail.com Co-developed-by: Justin Tee Signed-off-by: Justin Tee Signed-off-by: James Smart Signed-off-by: Martin K. Petersen --- drivers/scsi/lpfc/lpfc_attr.c | 75 +++++++++++++++++++++-------------- drivers/scsi/lpfc/lpfc_init.c | 9 ++--- drivers/scsi/lpfc/lpfc_sli.c | 42 ++++++++++---------- 3 files changed, 70 insertions(+), 56 deletions(-) diff --git a/drivers/scsi/lpfc/lpfc_attr.c b/drivers/scsi/lpfc/lpfc_attr.c index 59ca32d850e3..e723b716608a 100644 --- a/drivers/scsi/lpfc/lpfc_attr.c +++ b/drivers/scsi/lpfc/lpfc_attr.c @@ -1685,8 +1685,7 @@ lpfc_set_trunking(struct lpfc_hba *phba, char *buff_out) lpfc_printf_log(phba, KERN_ERR, LOG_MBOX, "0071 Set trunk mode failed with status: %d", rc); - if (rc != MBX_TIMEOUT) - mempool_free(mbox, phba->mbox_mem_pool); + mempool_free(mbox, phba->mbox_mem_pool); return 0; } @@ -6791,15 +6790,19 @@ lpfc_get_stats(struct Scsi_Host *shost) pmboxq->ctx_buf = NULL; pmboxq->vport = vport; - if (vport->fc_flag & FC_OFFLINE_MODE) + if (vport->fc_flag & FC_OFFLINE_MODE) { rc = lpfc_sli_issue_mbox(phba, pmboxq, MBX_POLL); - else - rc = lpfc_sli_issue_mbox_wait(phba, pmboxq, phba->fc_ratov * 2); - - if (rc != MBX_SUCCESS) { - if (rc != MBX_TIMEOUT) + if (rc != MBX_SUCCESS) { mempool_free(pmboxq, phba->mbox_mem_pool); - return NULL; + return NULL; + } + } else { + rc = lpfc_sli_issue_mbox_wait(phba, pmboxq, phba->fc_ratov * 2); + if (rc != MBX_SUCCESS) { + if (rc != MBX_TIMEOUT) + mempool_free(pmboxq, phba->mbox_mem_pool); + return NULL; + } } memset(hs, 0, sizeof (struct fc_host_statistics)); @@ -6823,15 +6826,19 @@ lpfc_get_stats(struct Scsi_Host *shost) pmboxq->ctx_buf = NULL; pmboxq->vport = vport; - if (vport->fc_flag & FC_OFFLINE_MODE) + if (vport->fc_flag & FC_OFFLINE_MODE) { rc = lpfc_sli_issue_mbox(phba, pmboxq, MBX_POLL); - else - rc = lpfc_sli_issue_mbox_wait(phba, pmboxq, phba->fc_ratov * 2); - - if (rc != MBX_SUCCESS) { - if (rc != MBX_TIMEOUT) + if (rc != MBX_SUCCESS) { mempool_free(pmboxq, phba->mbox_mem_pool); - return NULL; + return NULL; + } + } else { + rc = lpfc_sli_issue_mbox_wait(phba, pmboxq, phba->fc_ratov * 2); + if (rc != MBX_SUCCESS) { + if (rc != MBX_TIMEOUT) + mempool_free(pmboxq, phba->mbox_mem_pool); + return NULL; + } } hs->link_failure_count = pmb->un.varRdLnk.linkFailureCnt; @@ -6904,15 +6911,19 @@ lpfc_reset_stats(struct Scsi_Host *shost) pmboxq->vport = vport; if ((vport->fc_flag & FC_OFFLINE_MODE) || - (!(psli->sli_flag & LPFC_SLI_ACTIVE))) + (!(psli->sli_flag & LPFC_SLI_ACTIVE))) { rc = lpfc_sli_issue_mbox(phba, pmboxq, MBX_POLL); - else - rc = lpfc_sli_issue_mbox_wait(phba, pmboxq, phba->fc_ratov * 2); - - if (rc != MBX_SUCCESS) { - if (rc != MBX_TIMEOUT) + if (rc != MBX_SUCCESS) { mempool_free(pmboxq, phba->mbox_mem_pool); - return; + return; + } + } else { + rc = lpfc_sli_issue_mbox_wait(phba, pmboxq, phba->fc_ratov * 2); + if (rc != MBX_SUCCESS) { + if (rc != MBX_TIMEOUT) + mempool_free(pmboxq, phba->mbox_mem_pool); + return; + } } memset(pmboxq, 0, sizeof(LPFC_MBOXQ_t)); @@ -6922,15 +6933,19 @@ lpfc_reset_stats(struct Scsi_Host *shost) pmboxq->vport = vport; if ((vport->fc_flag & FC_OFFLINE_MODE) || - (!(psli->sli_flag & LPFC_SLI_ACTIVE))) + (!(psli->sli_flag & LPFC_SLI_ACTIVE))) { rc = lpfc_sli_issue_mbox(phba, pmboxq, MBX_POLL); - else + if (rc != MBX_SUCCESS) { + mempool_free(pmboxq, phba->mbox_mem_pool); + return; + } + } else { rc = lpfc_sli_issue_mbox_wait(phba, pmboxq, phba->fc_ratov * 2); - - if (rc != MBX_SUCCESS) { - if (rc != MBX_TIMEOUT) - mempool_free( pmboxq, phba->mbox_mem_pool); - return; + if (rc != MBX_SUCCESS) { + if (rc != MBX_TIMEOUT) + mempool_free(pmboxq, phba->mbox_mem_pool); + return; + } } lso->link_failure_count = pmb->un.varRdLnk.linkFailureCnt; diff --git a/drivers/scsi/lpfc/lpfc_init.c b/drivers/scsi/lpfc/lpfc_init.c index 631f22baf45f..be13a5e20efa 100644 --- a/drivers/scsi/lpfc/lpfc_init.c +++ b/drivers/scsi/lpfc/lpfc_init.c @@ -9654,8 +9654,7 @@ lpfc_sli4_queue_setup(struct lpfc_hba *phba) "3250 QUERY_FW_CFG mailbox failed with status " "x%x add_status x%x, mbx status x%x\n", shdr_status, shdr_add_status, rc); - if (rc != MBX_TIMEOUT) - mempool_free(mboxq, phba->mbox_mem_pool); + mempool_free(mboxq, phba->mbox_mem_pool); rc = -ENXIO; goto out_error; } @@ -9671,8 +9670,7 @@ lpfc_sli4_queue_setup(struct lpfc_hba *phba) "ulp1_mode:x%x\n", phba->sli4_hba.fw_func_mode, phba->sli4_hba.ulp0_mode, phba->sli4_hba.ulp1_mode); - if (rc != MBX_TIMEOUT) - mempool_free(mboxq, phba->mbox_mem_pool); + mempool_free(mboxq, phba->mbox_mem_pool); /* * Set up HBA Event Queues (EQs) @@ -10270,8 +10268,7 @@ lpfc_pci_function_reset(struct lpfc_hba *phba) shdr_status = bf_get(lpfc_mbox_hdr_status, &shdr->response); shdr_add_status = bf_get(lpfc_mbox_hdr_add_status, &shdr->response); - if (rc != MBX_TIMEOUT) - mempool_free(mboxq, phba->mbox_mem_pool); + mempool_free(mboxq, phba->mbox_mem_pool); if (shdr_status || shdr_add_status || rc) { lpfc_printf_log(phba, KERN_ERR, LOG_TRACE_EVENT, "0495 SLI_FUNCTION_RESET mailbox " diff --git a/drivers/scsi/lpfc/lpfc_sli.c b/drivers/scsi/lpfc/lpfc_sli.c index cd9943f91eff..3b48e3e88e67 100644 --- a/drivers/scsi/lpfc/lpfc_sli.c +++ b/drivers/scsi/lpfc/lpfc_sli.c @@ -5680,12 +5680,10 @@ lpfc_sli4_get_ctl_attr(struct lpfc_hba *phba) phba->sli4_hba.lnk_info.lnk_no, phba->BIOSVersion); out_free_mboxq: - if (rc != MBX_TIMEOUT) { - if (bf_get(lpfc_mqe_command, &mboxq->u.mqe) == MBX_SLI4_CONFIG) - lpfc_sli4_mbox_cmd_free(phba, mboxq); - else - mempool_free(mboxq, phba->mbox_mem_pool); - } + if (bf_get(lpfc_mqe_command, &mboxq->u.mqe) == MBX_SLI4_CONFIG) + lpfc_sli4_mbox_cmd_free(phba, mboxq); + else + mempool_free(mboxq, phba->mbox_mem_pool); return rc; } @@ -5786,12 +5784,10 @@ retrieve_ppname: } out_free_mboxq: - if (rc != MBX_TIMEOUT) { - if (bf_get(lpfc_mqe_command, &mboxq->u.mqe) == MBX_SLI4_CONFIG) - lpfc_sli4_mbox_cmd_free(phba, mboxq); - else - mempool_free(mboxq, phba->mbox_mem_pool); - } + if (bf_get(lpfc_mqe_command, &mboxq->u.mqe) == MBX_SLI4_CONFIG) + lpfc_sli4_mbox_cmd_free(phba, mboxq); + else + mempool_free(mboxq, phba->mbox_mem_pool); return rc; } @@ -17079,8 +17075,7 @@ lpfc_rq_destroy(struct lpfc_hba *phba, struct lpfc_queue *hrq, "2509 RQ_DESTROY mailbox failed with " "status x%x add_status x%x, mbx status x%x\n", shdr_status, shdr_add_status, rc); - if (rc != MBX_TIMEOUT) - mempool_free(mbox, hrq->phba->mbox_mem_pool); + mempool_free(mbox, hrq->phba->mbox_mem_pool); return -ENXIO; } bf_set(lpfc_mbx_rq_destroy_q_id, &mbox->u.mqe.un.rq_destroy.u.request, @@ -17177,7 +17172,9 @@ lpfc_sli4_post_sgl(struct lpfc_hba *phba, shdr = (union lpfc_sli4_cfg_shdr *) &post_sgl_pages->header.cfg_shdr; shdr_status = bf_get(lpfc_mbox_hdr_status, &shdr->response); shdr_add_status = bf_get(lpfc_mbox_hdr_add_status, &shdr->response); - if (rc != MBX_TIMEOUT) + if (!phba->sli4_hba.intr_enable) + mempool_free(mbox, phba->mbox_mem_pool); + else if (rc != MBX_TIMEOUT) mempool_free(mbox, phba->mbox_mem_pool); if (shdr_status || shdr_add_status || rc) { lpfc_printf_log(phba, KERN_ERR, LOG_TRACE_EVENT, @@ -17374,7 +17371,9 @@ lpfc_sli4_post_sgl_list(struct lpfc_hba *phba, shdr = (union lpfc_sli4_cfg_shdr *) &sgl->cfg_shdr; shdr_status = bf_get(lpfc_mbox_hdr_status, &shdr->response); shdr_add_status = bf_get(lpfc_mbox_hdr_add_status, &shdr->response); - if (rc != MBX_TIMEOUT) + if (!phba->sli4_hba.intr_enable) + lpfc_sli4_mbox_cmd_free(phba, mbox); + else if (rc != MBX_TIMEOUT) lpfc_sli4_mbox_cmd_free(phba, mbox); if (shdr_status || shdr_add_status || rc) { lpfc_printf_log(phba, KERN_ERR, LOG_TRACE_EVENT, @@ -17487,7 +17486,9 @@ lpfc_sli4_post_io_sgl_block(struct lpfc_hba *phba, struct list_head *nblist, shdr = (union lpfc_sli4_cfg_shdr *)&sgl->cfg_shdr; shdr_status = bf_get(lpfc_mbox_hdr_status, &shdr->response); shdr_add_status = bf_get(lpfc_mbox_hdr_add_status, &shdr->response); - if (rc != MBX_TIMEOUT) + if (!phba->sli4_hba.intr_enable) + lpfc_sli4_mbox_cmd_free(phba, mbox); + else if (rc != MBX_TIMEOUT) lpfc_sli4_mbox_cmd_free(phba, mbox); if (shdr_status || shdr_add_status || rc) { lpfc_printf_log(phba, KERN_ERR, LOG_TRACE_EVENT, @@ -18837,8 +18838,7 @@ lpfc_sli4_post_rpi_hdr(struct lpfc_hba *phba, struct lpfc_rpi_hdr *rpi_page) shdr = (union lpfc_sli4_cfg_shdr *) &hdr_tmpl->header.cfg_shdr; shdr_status = bf_get(lpfc_mbox_hdr_status, &shdr->response); shdr_add_status = bf_get(lpfc_mbox_hdr_add_status, &shdr->response); - if (rc != MBX_TIMEOUT) - mempool_free(mboxq, phba->mbox_mem_pool); + mempool_free(mboxq, phba->mbox_mem_pool); if (shdr_status || shdr_add_status || rc) { lpfc_printf_log(phba, KERN_ERR, LOG_TRACE_EVENT, "2514 POST_RPI_HDR mailbox failed with " @@ -20082,7 +20082,9 @@ lpfc_wr_object(struct lpfc_hba *phba, struct list_head *dmabuf_list, break; } } - if (rc != MBX_TIMEOUT) + if (!phba->sli4_hba.intr_enable) + mempool_free(mbox, phba->mbox_mem_pool); + else if (rc != MBX_TIMEOUT) mempool_free(mbox, phba->mbox_mem_pool); if (shdr_status || shdr_add_status || rc) { lpfc_printf_log(phba, KERN_ERR, LOG_TRACE_EVENT, From 724f6b43a3492b02e2ebc88f9fb749d1405098e2 Mon Sep 17 00:00:00 2001 From: James Smart Date: Sun, 11 Apr 2021 18:31:18 -0700 Subject: [PATCH 365/412] scsi: lpfc: Fix use-after-free on unused nodes after port swap During target port swap, the swap logic ignores the DROPPED flag in the nodes. As a node then moves into the UNUSED state, the reference count will be dropped. If a node is later reused and moved out of the UNUSED state, an access can result in a use-after-free assert. Fix by having the port swap logic propagate the DROPPED flag when switching nodes. This will avoid reference from being dropped. Link: https://lore.kernel.org/r/20210412013127.2387-8-jsmart2021@gmail.com Co-developed-by: Justin Tee Signed-off-by: Justin Tee Signed-off-by: James Smart Signed-off-by: Martin K. Petersen --- drivers/scsi/lpfc/lpfc_els.c | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/drivers/scsi/lpfc/lpfc_els.c b/drivers/scsi/lpfc/lpfc_els.c index ed57d92e96e1..c919bedd931c 100644 --- a/drivers/scsi/lpfc/lpfc_els.c +++ b/drivers/scsi/lpfc/lpfc_els.c @@ -1691,6 +1691,15 @@ lpfc_plogi_confirm_nport(struct lpfc_hba *phba, uint32_t *prsp, else new_ndlp->nlp_flag &= ~NLP_RPI_REGISTERED; + /* + * Retain the DROPPED flag. This will take care of the init + * refcount when affecting the state change + */ + if (keep_new_nlp_flag & NLP_DROPPED) + new_ndlp->nlp_flag |= NLP_DROPPED; + else + new_ndlp->nlp_flag &= ~NLP_DROPPED; + ndlp->nlp_flag = keep_new_nlp_flag; /* if ndlp had NLP_UNREG_INP set, keep it */ @@ -1705,6 +1714,15 @@ lpfc_plogi_confirm_nport(struct lpfc_hba *phba, uint32_t *prsp, else ndlp->nlp_flag &= ~NLP_RPI_REGISTERED; + /* + * Retain the DROPPED flag. This will take care of the init + * refcount when affecting the state change + */ + if (keep_nlp_flag & NLP_DROPPED) + ndlp->nlp_flag |= NLP_DROPPED; + else + ndlp->nlp_flag &= ~NLP_DROPPED; + spin_unlock_irq(&new_ndlp->lock); spin_unlock_irq(&ndlp->lock); From a1a553e31a994be6f68d3123c0546a84c04a7f6c Mon Sep 17 00:00:00 2001 From: James Smart Date: Sun, 11 Apr 2021 18:31:19 -0700 Subject: [PATCH 366/412] scsi: lpfc: Fix silent memory allocation failure in lpfc_sli4_bsg_link_diag_test() In the unlikely case of a failure to allocate an LPFC_MBOXQ_t structure, no return status is set, thus the routine never logs an error and returns success to the callee. Fix by setting a return code on failure. Link: https://lore.kernel.org/r/20210412013127.2387-9-jsmart2021@gmail.com Co-developed-by: Justin Tee Signed-off-by: Justin Tee Signed-off-by: James Smart Signed-off-by: Martin K. Petersen --- drivers/scsi/lpfc/lpfc_bsg.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/scsi/lpfc/lpfc_bsg.c b/drivers/scsi/lpfc/lpfc_bsg.c index 503540cf2041..48a6b0cc58ef 100644 --- a/drivers/scsi/lpfc/lpfc_bsg.c +++ b/drivers/scsi/lpfc/lpfc_bsg.c @@ -2435,8 +2435,10 @@ lpfc_sli4_bsg_link_diag_test(struct bsg_job *job) goto job_error; pmboxq = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL); - if (!pmboxq) + if (!pmboxq) { + rc = -ENOMEM; goto link_diag_test_exit; + } req_len = (sizeof(struct lpfc_mbx_set_link_diag_state) - sizeof(struct lpfc_sli4_cfg_mhdr)); From a314dec37c0e3879e964b574564b205b3529daa5 Mon Sep 17 00:00:00 2001 From: James Smart Date: Sun, 11 Apr 2021 18:31:20 -0700 Subject: [PATCH 367/412] scsi: lpfc: Fix missing FDMI registrations after Mgmt Svc login FDMI registration needs to be performed after every login with the FC Mgmt service. The flag the driver is using to track registration is cleared on link up, but never on Mgmt service logout/re-login. Fix by clearing the flag whenever a new login is completed with the FC Mgmt service. While perusing the flag use, logging was performed as if FDMI registration occurred on vports. However, it is limited to the physical port only. Revise the logging to reflect physical port based. Link: https://lore.kernel.org/r/20210412013127.2387-10-jsmart2021@gmail.com Co-developed-by: Justin Tee Signed-off-by: Justin Tee Signed-off-by: James Smart Signed-off-by: Martin K. Petersen --- drivers/scsi/lpfc/lpfc_ct.c | 28 ++++++++++++++++------------ drivers/scsi/lpfc/lpfc_hbadisc.c | 6 ++++-- 2 files changed, 20 insertions(+), 14 deletions(-) diff --git a/drivers/scsi/lpfc/lpfc_ct.c b/drivers/scsi/lpfc/lpfc_ct.c index 37b0c2024998..8da9e18a1fde 100644 --- a/drivers/scsi/lpfc/lpfc_ct.c +++ b/drivers/scsi/lpfc/lpfc_ct.c @@ -2253,12 +2253,12 @@ lpfc_cmpl_ct_disc_fdmi(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, return; case SLI_MGMT_RPA: - /* No retry on Vendor RPA */ + /* No retry on Vendor, RPA only done on physical port */ if (phba->link_flag & LS_CT_VEN_RPA) { - lpfc_printf_vlog(vport, KERN_ERR, - LOG_DISCOVERY | LOG_ELS, - "6460 VEN FDMI RPA failure\n"); phba->link_flag &= ~LS_CT_VEN_RPA; + lpfc_printf_log(phba, KERN_ERR, + LOG_DISCOVERY | LOG_ELS, + "6460 VEN FDMI RPA failure\n"); return; } if (vport->fdmi_port_mask == LPFC_FDMI2_PORT_ATTR) { @@ -2306,23 +2306,24 @@ lpfc_cmpl_ct_disc_fdmi(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, if (phba->link_flag & LS_CT_VEN_RPA) { lpfc_printf_vlog(vport, KERN_INFO, LOG_DISCOVERY | LOG_ELS, - "6449 VEN RPA Success\n"); + "6449 VEN RPA FDMI Success\n"); + phba->link_flag &= ~LS_CT_VEN_RPA; break; } if (lpfc_fdmi_cmd(vport, ndlp, cmd, LPFC_FDMI_VENDOR_ATTR_mi) == 0) phba->link_flag |= LS_CT_VEN_RPA; - lpfc_printf_vlog(vport, KERN_INFO, + lpfc_printf_log(phba, KERN_INFO, LOG_DISCOVERY | LOG_ELS, "6458 Send MI FDMI:%x Flag x%x\n", phba->sli4_hba.pc_sli4_params.mi_value, phba->link_flag); } else { - lpfc_printf_vlog(vport, KERN_INFO, - LOG_DISCOVERY | LOG_ELS, - "6459 No FDMI VEN MI support - " - "RPA Success\n"); + lpfc_printf_log(phba, KERN_INFO, + LOG_DISCOVERY | LOG_ELS, + "6459 No FDMI VEN MI support - " + "RPA Success\n"); } break; } @@ -2369,10 +2370,13 @@ lpfc_fdmi_change_check(struct lpfc_vport *vport) * DHBA -> DPRT -> RHBA -> RPA (physical port) * DPRT -> RPRT (vports) */ - if (vport->port_type == LPFC_PHYSICAL_PORT) + if (vport->port_type == LPFC_PHYSICAL_PORT) { + /* For extra Vendor RPA */ + phba->link_flag &= ~LS_CT_VEN_RPA; lpfc_fdmi_cmd(vport, ndlp, SLI_MGMT_DHBA, 0); - else + } else { lpfc_fdmi_cmd(vport, ndlp, SLI_MGMT_DPRT, 0); + } /* Since this code path registers all the port attributes * we can just return without further checking. diff --git a/drivers/scsi/lpfc/lpfc_hbadisc.c b/drivers/scsi/lpfc/lpfc_hbadisc.c index 85633eb7524f..03977a2268fe 100644 --- a/drivers/scsi/lpfc/lpfc_hbadisc.c +++ b/drivers/scsi/lpfc/lpfc_hbadisc.c @@ -5952,10 +5952,12 @@ lpfc_mbx_cmpl_fdmi_reg_login(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb) * DHBA -> DPRT -> RHBA -> RPA (physical port) * DPRT -> RPRT (vports) */ - if (vport->port_type == LPFC_PHYSICAL_PORT) + if (vport->port_type == LPFC_PHYSICAL_PORT) { + phba->link_flag &= ~LS_CT_VEN_RPA; /* For extra Vendor RPA */ lpfc_fdmi_cmd(vport, ndlp, SLI_MGMT_DHBA, 0); - else + } else { lpfc_fdmi_cmd(vport, ndlp, SLI_MGMT_DPRT, 0); + } /* decrement the node reference count held for this callback From d3de0d11a219f32b185d525cca2568817e22d3a1 Mon Sep 17 00:00:00 2001 From: James Smart Date: Sun, 11 Apr 2021 18:31:21 -0700 Subject: [PATCH 368/412] scsi: lpfc: Fix lpfc_hdw_queue attribute being ignored The lpfc_hdw_queue attribute is to set the number of hardware queues to be created on the adapter. Normally, the value is set to a default, which allows the hw queue count to be sized dynamically based on adapter capabilities, CPU/platform architecture, or CPU type. Currently, when lpfc_hdw_queue is set to a specific value, is has no effect and the dynamic sizing occurs. The routine checking whether parameters are default or not ignores the lpfc_hdw_queue setting and invokes the dynamic logic. Fix the routine to additionally check the lpfc_hdw_queue attribute value before using dynamic scaling. Additionally, SLI-3 supports only a small number of queues with dedicated functions, thus it needs to be exempted from the variable scaling and set to the expected values. Link: https://lore.kernel.org/r/20210412013127.2387-11-jsmart2021@gmail.com Co-developed-by: Justin Tee Signed-off-by: Justin Tee Signed-off-by: James Smart Signed-off-by: Martin K. Petersen --- drivers/scsi/lpfc/lpfc_attr.c | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/drivers/scsi/lpfc/lpfc_attr.c b/drivers/scsi/lpfc/lpfc_attr.c index e723b716608a..8d50a391058f 100644 --- a/drivers/scsi/lpfc/lpfc_attr.c +++ b/drivers/scsi/lpfc/lpfc_attr.c @@ -5813,7 +5813,9 @@ lpfc_irq_chann_init(struct lpfc_hba *phba, uint32_t val) } /* Check if default setting was passed */ - if (val == LPFC_IRQ_CHANN_DEF) + if (val == LPFC_IRQ_CHANN_DEF && + phba->cfg_hdw_queue == LPFC_HBA_HDWQ_DEF && + phba->sli_rev == LPFC_SLI_REV4) lpfc_assign_default_irq_chann(phba); if (phba->irq_chann_mode != NORMAL_MODE) { @@ -5852,7 +5854,12 @@ lpfc_irq_chann_init(struct lpfc_hba *phba, uint32_t val) phba->cfg_irq_chann = LPFC_IRQ_CHANN_DEF; return -EINVAL; } - phba->cfg_irq_chann = val; + if (phba->sli_rev == LPFC_SLI_REV4) { + phba->cfg_irq_chann = val; + } else { + phba->cfg_irq_chann = 2; + phba->cfg_hdw_queue = 1; + } } return 0; @@ -7409,7 +7416,8 @@ lpfc_get_cfgparam(struct lpfc_hba *phba) phba->cfg_hdw_queue = phba->sli4_hba.num_present_cpu; if (phba->cfg_irq_chann == 0) phba->cfg_irq_chann = phba->sli4_hba.num_present_cpu; - if (phba->cfg_irq_chann > phba->cfg_hdw_queue) + if (phba->cfg_irq_chann > phba->cfg_hdw_queue && + phba->sli_rev == LPFC_SLI_REV4) phba->cfg_irq_chann = phba->cfg_hdw_queue; phba->cfg_soft_wwnn = 0L; From b62232ba8caccaf1954e197058104a6478fac1af Mon Sep 17 00:00:00 2001 From: James Smart Date: Sun, 11 Apr 2021 18:31:22 -0700 Subject: [PATCH 369/412] scsi: lpfc: Remove unsupported mbox PORT_CAPABILITIES logic SLI-4 does not contain a PORT_CAPABILITIES mailbox command (only SLI-3 does, and SLI-3 doesn't use it), yet there are SLI-4 code paths that have code to issue the command. The command will always fail. Remove the code for the mailbox command and leave only the resulting "failure path" logic. Link: https://lore.kernel.org/r/20210412013127.2387-12-jsmart2021@gmail.com Co-developed-by: Justin Tee Signed-off-by: Justin Tee Signed-off-by: James Smart Signed-off-by: Martin K. Petersen --- drivers/scsi/lpfc/lpfc_crtn.h | 3 - drivers/scsi/lpfc/lpfc_hw4.h | 174 +--------------------------------- drivers/scsi/lpfc/lpfc_init.c | 103 +------------------- drivers/scsi/lpfc/lpfc_mbox.c | 36 ------- 4 files changed, 3 insertions(+), 313 deletions(-) diff --git a/drivers/scsi/lpfc/lpfc_crtn.h b/drivers/scsi/lpfc/lpfc_crtn.h index e7db4496e8a9..383abf46fd29 100644 --- a/drivers/scsi/lpfc/lpfc_crtn.h +++ b/drivers/scsi/lpfc/lpfc_crtn.h @@ -55,9 +55,6 @@ void lpfc_register_new_vport(struct lpfc_hba *, struct lpfc_vport *, void lpfc_unreg_vpi(struct lpfc_hba *, uint16_t, LPFC_MBOXQ_t *); void lpfc_init_link(struct lpfc_hba *, LPFC_MBOXQ_t *, uint32_t, uint32_t); void lpfc_request_features(struct lpfc_hba *, struct lpfcMboxq *); -void lpfc_supported_pages(struct lpfcMboxq *); -void lpfc_pc_sli4_params(struct lpfcMboxq *); -int lpfc_pc_sli4_params_get(struct lpfc_hba *, LPFC_MBOXQ_t *); int lpfc_sli4_mbox_rsrc_extent(struct lpfc_hba *, struct lpfcMboxq *, uint16_t, uint16_t, bool); int lpfc_get_sli4_parameters(struct lpfc_hba *, LPFC_MBOXQ_t *); diff --git a/drivers/scsi/lpfc/lpfc_hw4.h b/drivers/scsi/lpfc/lpfc_hw4.h index 541b9aef6bfe..f5bc2c32a817 100644 --- a/drivers/scsi/lpfc/lpfc_hw4.h +++ b/drivers/scsi/lpfc/lpfc_hw4.h @@ -124,6 +124,7 @@ struct lpfc_sli_intf { /* Define SLI4 Alignment requirements. */ #define LPFC_ALIGN_16_BYTE 16 #define LPFC_ALIGN_64_BYTE 64 +#define SLI4_PAGE_SIZE 4096 /* Define SLI4 specific definitions. */ #define LPFC_MQ_CQE_BYTE_OFFSET 256 @@ -2976,62 +2977,6 @@ struct lpfc_mbx_request_features { #define lpfc_mbx_rq_ftr_rsp_mrqp_WORD word3 }; -struct lpfc_mbx_supp_pages { - uint32_t word1; -#define qs_SHIFT 0 -#define qs_MASK 0x00000001 -#define qs_WORD word1 -#define wr_SHIFT 1 -#define wr_MASK 0x00000001 -#define wr_WORD word1 -#define pf_SHIFT 8 -#define pf_MASK 0x000000ff -#define pf_WORD word1 -#define cpn_SHIFT 16 -#define cpn_MASK 0x000000ff -#define cpn_WORD word1 - uint32_t word2; -#define list_offset_SHIFT 0 -#define list_offset_MASK 0x000000ff -#define list_offset_WORD word2 -#define next_offset_SHIFT 8 -#define next_offset_MASK 0x000000ff -#define next_offset_WORD word2 -#define elem_cnt_SHIFT 16 -#define elem_cnt_MASK 0x000000ff -#define elem_cnt_WORD word2 - uint32_t word3; -#define pn_0_SHIFT 24 -#define pn_0_MASK 0x000000ff -#define pn_0_WORD word3 -#define pn_1_SHIFT 16 -#define pn_1_MASK 0x000000ff -#define pn_1_WORD word3 -#define pn_2_SHIFT 8 -#define pn_2_MASK 0x000000ff -#define pn_2_WORD word3 -#define pn_3_SHIFT 0 -#define pn_3_MASK 0x000000ff -#define pn_3_WORD word3 - uint32_t word4; -#define pn_4_SHIFT 24 -#define pn_4_MASK 0x000000ff -#define pn_4_WORD word4 -#define pn_5_SHIFT 16 -#define pn_5_MASK 0x000000ff -#define pn_5_WORD word4 -#define pn_6_SHIFT 8 -#define pn_6_MASK 0x000000ff -#define pn_6_WORD word4 -#define pn_7_SHIFT 0 -#define pn_7_MASK 0x000000ff -#define pn_7_WORD word4 - uint32_t rsvd[27]; -#define LPFC_SUPP_PAGES 0 -#define LPFC_BLOCK_GUARD_PROFILES 1 -#define LPFC_SLI4_PARAMETERS 2 -}; - struct lpfc_mbx_memory_dump_type3 { uint32_t word1; #define lpfc_mbx_memory_dump_type3_type_SHIFT 0 @@ -3248,121 +3193,6 @@ struct user_eeprom { uint8_t reserved191[57]; }; -struct lpfc_mbx_pc_sli4_params { - uint32_t word1; -#define qs_SHIFT 0 -#define qs_MASK 0x00000001 -#define qs_WORD word1 -#define wr_SHIFT 1 -#define wr_MASK 0x00000001 -#define wr_WORD word1 -#define pf_SHIFT 8 -#define pf_MASK 0x000000ff -#define pf_WORD word1 -#define cpn_SHIFT 16 -#define cpn_MASK 0x000000ff -#define cpn_WORD word1 - uint32_t word2; -#define if_type_SHIFT 0 -#define if_type_MASK 0x00000007 -#define if_type_WORD word2 -#define sli_rev_SHIFT 4 -#define sli_rev_MASK 0x0000000f -#define sli_rev_WORD word2 -#define sli_family_SHIFT 8 -#define sli_family_MASK 0x000000ff -#define sli_family_WORD word2 -#define featurelevel_1_SHIFT 16 -#define featurelevel_1_MASK 0x000000ff -#define featurelevel_1_WORD word2 -#define featurelevel_2_SHIFT 24 -#define featurelevel_2_MASK 0x0000001f -#define featurelevel_2_WORD word2 - uint32_t word3; -#define fcoe_SHIFT 0 -#define fcoe_MASK 0x00000001 -#define fcoe_WORD word3 -#define fc_SHIFT 1 -#define fc_MASK 0x00000001 -#define fc_WORD word3 -#define nic_SHIFT 2 -#define nic_MASK 0x00000001 -#define nic_WORD word3 -#define iscsi_SHIFT 3 -#define iscsi_MASK 0x00000001 -#define iscsi_WORD word3 -#define rdma_SHIFT 4 -#define rdma_MASK 0x00000001 -#define rdma_WORD word3 - uint32_t sge_supp_len; -#define SLI4_PAGE_SIZE 4096 - uint32_t word5; -#define if_page_sz_SHIFT 0 -#define if_page_sz_MASK 0x0000ffff -#define if_page_sz_WORD word5 -#define loopbk_scope_SHIFT 24 -#define loopbk_scope_MASK 0x0000000f -#define loopbk_scope_WORD word5 -#define rq_db_window_SHIFT 28 -#define rq_db_window_MASK 0x0000000f -#define rq_db_window_WORD word5 - uint32_t word6; -#define eq_pages_SHIFT 0 -#define eq_pages_MASK 0x0000000f -#define eq_pages_WORD word6 -#define eqe_size_SHIFT 8 -#define eqe_size_MASK 0x000000ff -#define eqe_size_WORD word6 - uint32_t word7; -#define cq_pages_SHIFT 0 -#define cq_pages_MASK 0x0000000f -#define cq_pages_WORD word7 -#define cqe_size_SHIFT 8 -#define cqe_size_MASK 0x000000ff -#define cqe_size_WORD word7 - uint32_t word8; -#define mq_pages_SHIFT 0 -#define mq_pages_MASK 0x0000000f -#define mq_pages_WORD word8 -#define mqe_size_SHIFT 8 -#define mqe_size_MASK 0x000000ff -#define mqe_size_WORD word8 -#define mq_elem_cnt_SHIFT 16 -#define mq_elem_cnt_MASK 0x000000ff -#define mq_elem_cnt_WORD word8 - uint32_t word9; -#define wq_pages_SHIFT 0 -#define wq_pages_MASK 0x0000ffff -#define wq_pages_WORD word9 -#define wqe_size_SHIFT 8 -#define wqe_size_MASK 0x000000ff -#define wqe_size_WORD word9 - uint32_t word10; -#define rq_pages_SHIFT 0 -#define rq_pages_MASK 0x0000ffff -#define rq_pages_WORD word10 -#define rqe_size_SHIFT 8 -#define rqe_size_MASK 0x000000ff -#define rqe_size_WORD word10 - uint32_t word11; -#define hdr_pages_SHIFT 0 -#define hdr_pages_MASK 0x0000000f -#define hdr_pages_WORD word11 -#define hdr_size_SHIFT 8 -#define hdr_size_MASK 0x0000000f -#define hdr_size_WORD word11 -#define hdr_pp_align_SHIFT 16 -#define hdr_pp_align_MASK 0x0000ffff -#define hdr_pp_align_WORD word11 - uint32_t word12; -#define sgl_pages_SHIFT 0 -#define sgl_pages_MASK 0x0000000f -#define sgl_pages_WORD word12 -#define sgl_pp_align_SHIFT 16 -#define sgl_pp_align_MASK 0x0000ffff -#define sgl_pp_align_WORD word12 - uint32_t rsvd_13_63[51]; -}; #define SLI4_PAGE_ALIGN(addr) (((addr)+((SLI4_PAGE_SIZE)-1)) \ &(~((SLI4_PAGE_SIZE)-1))) @@ -3994,8 +3824,6 @@ struct lpfc_mqe { struct lpfc_mbx_post_hdr_tmpl hdr_tmpl; struct lpfc_mbx_query_fw_config query_fw_cfg; struct lpfc_mbx_set_beacon_config beacon_config; - struct lpfc_mbx_supp_pages supp_pages; - struct lpfc_mbx_pc_sli4_params sli4_params; struct lpfc_mbx_get_sli4_parameters get_sli4_parameters; struct lpfc_mbx_set_link_diag_state link_diag_state; struct lpfc_mbx_set_link_diag_loopback link_diag_loopback; diff --git a/drivers/scsi/lpfc/lpfc_init.c b/drivers/scsi/lpfc/lpfc_init.c index be13a5e20efa..c80fd7d49f6e 100644 --- a/drivers/scsi/lpfc/lpfc_init.c +++ b/drivers/scsi/lpfc/lpfc_init.c @@ -6569,8 +6569,6 @@ lpfc_sli4_driver_resource_setup(struct lpfc_hba *phba) LPFC_MBOXQ_t *mboxq; MAILBOX_t *mb; int rc, i, max_buf_size; - uint8_t pn_page[LPFC_MAX_SUPPORTED_PAGES] = {0}; - struct lpfc_mqe *mqe; int longs; int extra; uint64_t wwn; @@ -6804,32 +6802,6 @@ lpfc_sli4_driver_resource_setup(struct lpfc_hba *phba) lpfc_nvme_mod_param_dep(phba); - /* Get the Supported Pages if PORT_CAPABILITIES is supported by port. */ - lpfc_supported_pages(mboxq); - rc = lpfc_sli_issue_mbox(phba, mboxq, MBX_POLL); - if (!rc) { - mqe = &mboxq->u.mqe; - memcpy(&pn_page[0], ((uint8_t *)&mqe->un.supp_pages.word3), - LPFC_MAX_SUPPORTED_PAGES); - for (i = 0; i < LPFC_MAX_SUPPORTED_PAGES; i++) { - switch (pn_page[i]) { - case LPFC_SLI4_PARAMETERS: - phba->sli4_hba.pc_sli4_params.supported = 1; - break; - default: - break; - } - } - /* Read the port's SLI4 Parameters capabilities if supported. */ - if (phba->sli4_hba.pc_sli4_params.supported) - rc = lpfc_pc_sli4_params_get(phba, mboxq); - if (rc) { - mempool_free(mboxq, phba->mbox_mem_pool); - rc = -EIO; - goto out_free_bsmbx; - } - } - /* * Get sli4 parameters that override parameters from Port capabilities. * If this call fails, it isn't critical unless the SLI4 parameters come @@ -12066,78 +12038,6 @@ lpfc_sli4_hba_unset(struct lpfc_hba *phba) phba->pport->work_port_events = 0; } - /** - * lpfc_pc_sli4_params_get - Get the SLI4_PARAMS port capabilities. - * @phba: Pointer to HBA context object. - * @mboxq: Pointer to the mailboxq memory for the mailbox command response. - * - * This function is called in the SLI4 code path to read the port's - * sli4 capabilities. - * - * This function may be be called from any context that can block-wait - * for the completion. The expectation is that this routine is called - * typically from probe_one or from the online routine. - **/ -int -lpfc_pc_sli4_params_get(struct lpfc_hba *phba, LPFC_MBOXQ_t *mboxq) -{ - int rc; - struct lpfc_mqe *mqe; - struct lpfc_pc_sli4_params *sli4_params; - uint32_t mbox_tmo; - - rc = 0; - mqe = &mboxq->u.mqe; - - /* Read the port's SLI4 Parameters port capabilities */ - lpfc_pc_sli4_params(mboxq); - if (!phba->sli4_hba.intr_enable) - rc = lpfc_sli_issue_mbox(phba, mboxq, MBX_POLL); - else { - mbox_tmo = lpfc_mbox_tmo_val(phba, mboxq); - rc = lpfc_sli_issue_mbox_wait(phba, mboxq, mbox_tmo); - } - - if (unlikely(rc)) - return 1; - - sli4_params = &phba->sli4_hba.pc_sli4_params; - sli4_params->if_type = bf_get(if_type, &mqe->un.sli4_params); - sli4_params->sli_rev = bf_get(sli_rev, &mqe->un.sli4_params); - sli4_params->sli_family = bf_get(sli_family, &mqe->un.sli4_params); - sli4_params->featurelevel_1 = bf_get(featurelevel_1, - &mqe->un.sli4_params); - sli4_params->featurelevel_2 = bf_get(featurelevel_2, - &mqe->un.sli4_params); - sli4_params->proto_types = mqe->un.sli4_params.word3; - sli4_params->sge_supp_len = mqe->un.sli4_params.sge_supp_len; - sli4_params->if_page_sz = bf_get(if_page_sz, &mqe->un.sli4_params); - sli4_params->rq_db_window = bf_get(rq_db_window, &mqe->un.sli4_params); - sli4_params->loopbk_scope = bf_get(loopbk_scope, &mqe->un.sli4_params); - sli4_params->eq_pages_max = bf_get(eq_pages, &mqe->un.sli4_params); - sli4_params->eqe_size = bf_get(eqe_size, &mqe->un.sli4_params); - sli4_params->cq_pages_max = bf_get(cq_pages, &mqe->un.sli4_params); - sli4_params->cqe_size = bf_get(cqe_size, &mqe->un.sli4_params); - sli4_params->mq_pages_max = bf_get(mq_pages, &mqe->un.sli4_params); - sli4_params->mqe_size = bf_get(mqe_size, &mqe->un.sli4_params); - sli4_params->mq_elem_cnt = bf_get(mq_elem_cnt, &mqe->un.sli4_params); - sli4_params->wq_pages_max = bf_get(wq_pages, &mqe->un.sli4_params); - sli4_params->wqe_size = bf_get(wqe_size, &mqe->un.sli4_params); - sli4_params->rq_pages_max = bf_get(rq_pages, &mqe->un.sli4_params); - sli4_params->rqe_size = bf_get(rqe_size, &mqe->un.sli4_params); - sli4_params->hdr_pages_max = bf_get(hdr_pages, &mqe->un.sli4_params); - sli4_params->hdr_size = bf_get(hdr_size, &mqe->un.sli4_params); - sli4_params->hdr_pp_align = bf_get(hdr_pp_align, &mqe->un.sli4_params); - sli4_params->sgl_pages_max = bf_get(sgl_pages, &mqe->un.sli4_params); - sli4_params->sgl_pp_align = bf_get(sgl_pp_align, &mqe->un.sli4_params); - - /* Make sure that sge_supp_len can be handled by the driver */ - if (sli4_params->sge_supp_len > LPFC_MAX_SGE_SIZE) - sli4_params->sge_supp_len = LPFC_MAX_SGE_SIZE; - - return rc; -} - /** * lpfc_get_sli4_parameters - Get the SLI4 Config PARAMETERS. * @phba: Pointer to HBA context object. @@ -12196,7 +12096,8 @@ lpfc_get_sli4_parameters(struct lpfc_hba *phba, LPFC_MBOXQ_t *mboxq) else phba->sli3_options &= ~LPFC_SLI4_PHWQ_ENABLED; sli4_params->sge_supp_len = mbx_sli4_parameters->sge_supp_len; - sli4_params->loopbk_scope = bf_get(loopbk_scope, mbx_sli4_parameters); + sli4_params->loopbk_scope = bf_get(cfg_loopbk_scope, + mbx_sli4_parameters); sli4_params->oas_supported = bf_get(cfg_oas, mbx_sli4_parameters); sli4_params->cqv = bf_get(cfg_cqv, mbx_sli4_parameters); sli4_params->mqv = bf_get(cfg_mqv, mbx_sli4_parameters); diff --git a/drivers/scsi/lpfc/lpfc_mbox.c b/drivers/scsi/lpfc/lpfc_mbox.c index c03a7f12dd65..72dd22ad5dcc 100644 --- a/drivers/scsi/lpfc/lpfc_mbox.c +++ b/drivers/scsi/lpfc/lpfc_mbox.c @@ -2624,39 +2624,3 @@ lpfc_resume_rpi(struct lpfcMboxq *mbox, struct lpfc_nodelist *ndlp) resume_rpi->event_tag = ndlp->phba->fc_eventTag; } -/** - * lpfc_supported_pages - Initialize the PORT_CAPABILITIES supported pages - * mailbox command. - * @mbox: pointer to lpfc mbox command to initialize. - * - * The PORT_CAPABILITIES supported pages mailbox command is issued to - * retrieve the particular feature pages supported by the port. - **/ -void -lpfc_supported_pages(struct lpfcMboxq *mbox) -{ - struct lpfc_mbx_supp_pages *supp_pages; - - memset(mbox, 0, sizeof(*mbox)); - supp_pages = &mbox->u.mqe.un.supp_pages; - bf_set(lpfc_mqe_command, &mbox->u.mqe, MBX_PORT_CAPABILITIES); - bf_set(cpn, supp_pages, LPFC_SUPP_PAGES); -} - -/** - * lpfc_pc_sli4_params - Initialize the PORT_CAPABILITIES SLI4 Params mbox cmd. - * @mbox: pointer to lpfc mbox command to initialize. - * - * The PORT_CAPABILITIES SLI4 parameters mailbox command is issued to - * retrieve the particular SLI4 features supported by the port. - **/ -void -lpfc_pc_sli4_params(struct lpfcMboxq *mbox) -{ - struct lpfc_mbx_pc_sli4_params *sli4_params; - - memset(mbox, 0, sizeof(*mbox)); - sli4_params = &mbox->u.mqe.un.sli4_params; - bf_set(lpfc_mqe_command, &mbox->u.mqe, MBX_PORT_CAPABILITIES); - bf_set(cpn, sli4_params, LPFC_SLI4_PARAMETERS); -} From 3bfab8a026b393d5836e6e5abdc201d510dda857 Mon Sep 17 00:00:00 2001 From: James Smart Date: Sun, 11 Apr 2021 18:31:23 -0700 Subject: [PATCH 370/412] scsi: lpfc: Fix various trivial errors in comments and log messages Clean up minor issues spotted by tools and code review: - Spelling Errors - Spurious characters and errors in function headers - nvme_info wqerr and err fields source data reversed - Extraneous new line in log message 0466 - Spacing error in log message 0109 - Messages 0140 and 0141 have portname and nodename reversed - Incorrect function labelling in comment Link: https://lore.kernel.org/r/20210412013127.2387-13-jsmart2021@gmail.com Co-developed-by: Justin Tee Signed-off-by: Justin Tee Signed-off-by: James Smart Signed-off-by: Martin K. Petersen --- drivers/scsi/lpfc/lpfc_attr.c | 11 +++++------ drivers/scsi/lpfc/lpfc_bsg.c | 16 ++++++++-------- drivers/scsi/lpfc/lpfc_els.c | 4 ++-- drivers/scsi/lpfc/lpfc_nportdisc.c | 4 ++-- drivers/scsi/lpfc/lpfc_sli.c | 8 ++++---- 5 files changed, 21 insertions(+), 22 deletions(-) diff --git a/drivers/scsi/lpfc/lpfc_attr.c b/drivers/scsi/lpfc/lpfc_attr.c index 8d50a391058f..5bb8a7c1b6ec 100644 --- a/drivers/scsi/lpfc/lpfc_attr.c +++ b/drivers/scsi/lpfc/lpfc_attr.c @@ -487,8 +487,8 @@ lpfc_nvme_info_show(struct device *dev, struct device_attribute *attr, atomic_read(&lport->xmt_fcp_noxri), atomic_read(&lport->xmt_fcp_bad_ndlp), atomic_read(&lport->xmt_fcp_qdepth), - atomic_read(&lport->xmt_fcp_err), - atomic_read(&lport->xmt_fcp_wqerr)); + atomic_read(&lport->xmt_fcp_wqerr), + atomic_read(&lport->xmt_fcp_err)); if (strlcat(buf, tmp, PAGE_SIZE) >= PAGE_SIZE) goto buffer_done; @@ -1174,8 +1174,7 @@ lpfc_emptyq_wait(struct lpfc_hba *phba, struct list_head *q, spinlock_t *lock) msleep(20); if (cnt++ > 250) { /* 5 secs */ lpfc_printf_log(phba, KERN_WARNING, LOG_INIT, - "0466 %s %s\n", - "Outstanding IO when ", + "0466 Outstanding IO when " "bringing Adapter offline\n"); return 0; } @@ -5927,7 +5926,7 @@ LPFC_ATTR_RW(XLanePriority, 0, 0x0, 0x7f, "CS_CTL for Express Lane Feature."); LPFC_ATTR_R(enable_bg, 0, 0, 1, "Enable BlockGuard Support"); /* -# lpfc_prot_mask: i +# lpfc_prot_mask: # - Bit mask of host protection capabilities used to register with the # SCSI mid-layer # - Only meaningful if BG is turned on (lpfc_enable_bg=1). @@ -5952,7 +5951,7 @@ LPFC_ATTR(prot_mask, "T10-DIF host protection capabilities mask"); /* -# lpfc_prot_guard: i +# lpfc_prot_guard: # - Bit mask of protection guard types to register with the SCSI mid-layer # - Guard types are currently either 1) T10-DIF CRC 2) IP checksum # - Allows you to ultimately specify which profiles to use diff --git a/drivers/scsi/lpfc/lpfc_bsg.c b/drivers/scsi/lpfc/lpfc_bsg.c index 48a6b0cc58ef..32e562f27e8f 100644 --- a/drivers/scsi/lpfc/lpfc_bsg.c +++ b/drivers/scsi/lpfc/lpfc_bsg.c @@ -3878,7 +3878,7 @@ lpfc_bsg_sli_cfg_dma_desc_setup(struct lpfc_hba *phba, enum nemb_type nemb_tp, * @dmabuf: Pointer to a DMA buffer descriptor. * * This routine performs SLI_CONFIG (0x9B) read mailbox command operation with - * non-embedded external bufffers. + * non-embedded external buffers. **/ static int lpfc_bsg_sli_cfg_read_cmd_ext(struct lpfc_hba *phba, struct bsg_job *job, @@ -4067,7 +4067,7 @@ job_error: * @dmabuf: Pointer to a DMA buffer descriptor. * * This routine performs SLI_CONFIG (0x9B) write mailbox command operation with - * non-embedded external bufffers. + * non-embedded external buffers. **/ static int lpfc_bsg_sli_cfg_write_cmd_ext(struct lpfc_hba *phba, struct bsg_job *job, @@ -4211,7 +4211,7 @@ lpfc_bsg_sli_cfg_write_cmd_ext(struct lpfc_hba *phba, struct bsg_job *job, goto job_error; } - /* wait for additoinal external buffers */ + /* wait for additional external buffers */ bsg_reply->result = 0; bsg_job_done(job, bsg_reply->result, @@ -4233,8 +4233,8 @@ job_error: * @dmabuf: Pointer to a DMA buffer descriptor. * * This routine handles SLI_CONFIG (0x9B) mailbox command with non-embedded - * external bufffers, including both 0x9B with non-embedded MSEs and 0x9B - * with embedded sussystem 0x1 and opcodes with external HBDs. + * external buffers, including both 0x9B with non-embedded MSEs and 0x9B + * with embedded subsystem 0x1 and opcodes with external HBDs. **/ static int lpfc_bsg_handle_sli_cfg_mbox(struct lpfc_hba *phba, struct bsg_job *job, @@ -4559,7 +4559,7 @@ lpfc_bsg_write_ebuf_set(struct lpfc_hba *phba, struct bsg_job *job, goto job_error; } - /* wait for additoinal external buffers */ + /* wait for additional external buffers */ bsg_reply->result = 0; bsg_job_done(job, bsg_reply->result, bsg_reply->reply_payload_rcv_len); @@ -4625,7 +4625,7 @@ lpfc_bsg_handle_sli_cfg_ebuf(struct lpfc_hba *phba, struct bsg_job *job, * @job: Pointer to the job object. * @dmabuf: Pointer to a DMA buffer descriptor. * - * This routine checkes and handles non-embedded multi-buffer SLI_CONFIG + * This routine checks and handles non-embedded multi-buffer SLI_CONFIG * (0x9B) mailbox commands and external buffers. **/ static int @@ -4703,7 +4703,7 @@ sli_cfg_ext_error: * from the mailbox pool, copy the caller mailbox command. * * If offline and the sli is active we need to poll for the command (port is - * being reset) and com-plete the job, otherwise issue the mailbox command and + * being reset) and complete the job, otherwise issue the mailbox command and * let our completion handler finish the command. **/ static int diff --git a/drivers/scsi/lpfc/lpfc_els.c b/drivers/scsi/lpfc/lpfc_els.c index c919bedd931c..21108f322c99 100644 --- a/drivers/scsi/lpfc/lpfc_els.c +++ b/drivers/scsi/lpfc/lpfc_els.c @@ -4378,7 +4378,7 @@ lpfc_cmpl_els_logo_acc(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, irsp->ulpStatus, irsp->un.ulpWord[4], ndlp->nlp_DID); /* ACC to LOGO completes to NPort */ lpfc_printf_vlog(vport, KERN_INFO, LOG_ELS, - "0109 ACC to LOGO completes to NPort x%x refcnt %d" + "0109 ACC to LOGO completes to NPort x%x refcnt %d " "Data: x%x x%x x%x\n", ndlp->nlp_DID, kref_read(&ndlp->kref), ndlp->nlp_flag, ndlp->nlp_state, ndlp->nlp_rpi); @@ -4783,7 +4783,7 @@ lpfc_els_rsp_acc(struct lpfc_vport *vport, uint32_t flag, } /** - * lpfc_els_rsp_reject - Propare and issue a rjt response iocb command + * lpfc_els_rsp_reject - Prepare and issue a rjt response iocb command * @vport: pointer to a virtual N_Port data structure. * @rejectError: reject response to issue * @oldiocb: pointer to the original lpfc command iocb data structure. diff --git a/drivers/scsi/lpfc/lpfc_nportdisc.c b/drivers/scsi/lpfc/lpfc_nportdisc.c index fd3d0197d155..bb4e65a32ecc 100644 --- a/drivers/scsi/lpfc/lpfc_nportdisc.c +++ b/drivers/scsi/lpfc/lpfc_nportdisc.c @@ -340,7 +340,7 @@ lpfc_rcv_plogi(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp, sp = (struct serv_parm *) ((uint8_t *) lp + sizeof (uint32_t)); if (wwn_to_u64(sp->portName.u.wwn) == 0) { lpfc_printf_vlog(vport, KERN_ERR, LOG_TRACE_EVENT, - "0140 PLOGI Reject: invalid nname\n"); + "0140 PLOGI Reject: invalid pname\n"); stat.un.b.lsRjtRsnCode = LSRJT_UNABLE_TPC; stat.un.b.lsRjtRsnCodeExp = LSEXP_INVALID_PNAME; lpfc_els_rsp_reject(vport, stat.un.lsRjtError, cmdiocb, ndlp, @@ -349,7 +349,7 @@ lpfc_rcv_plogi(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp, } if (wwn_to_u64(sp->nodeName.u.wwn) == 0) { lpfc_printf_vlog(vport, KERN_ERR, LOG_TRACE_EVENT, - "0141 PLOGI Reject: invalid pname\n"); + "0141 PLOGI Reject: invalid nname\n"); stat.un.b.lsRjtRsnCode = LSRJT_UNABLE_TPC; stat.un.b.lsRjtRsnCodeExp = LSEXP_INVALID_NNAME; lpfc_els_rsp_reject(vport, stat.un.lsRjtError, cmdiocb, ndlp, diff --git a/drivers/scsi/lpfc/lpfc_sli.c b/drivers/scsi/lpfc/lpfc_sli.c index 3b48e3e88e67..11145a78dbe9 100644 --- a/drivers/scsi/lpfc/lpfc_sli.c +++ b/drivers/scsi/lpfc/lpfc_sli.c @@ -935,7 +935,7 @@ __lpfc_sli_get_iocbq(struct lpfc_hba *phba) * @phba: Pointer to HBA context object. * @xritag: XRI value. * - * This function clears the sglq pointer from the array of acive + * This function clears the sglq pointer from the array of active * sglq's. The xritag that is passed in is used to index into the * array. Before the xritag can be used it needs to be adjusted * by subtracting the xribase. @@ -957,7 +957,7 @@ __lpfc_clear_active_sglq(struct lpfc_hba *phba, uint16_t xritag) * @phba: Pointer to HBA context object. * @xritag: XRI value. * - * This function returns the sglq pointer from the array of acive + * This function returns the sglq pointer from the array of active * sglq's. The xritag that is passed in is used to index into the * array. Before the xritag can be used it needs to be adjusted * by subtracting the xribase. @@ -14851,7 +14851,7 @@ lpfc_sli4_hba_intr_handler(int irq, void *dev_id) } return IRQ_HANDLED; -} /* lpfc_sli4_fp_intr_handler */ +} /* lpfc_sli4_hba_intr_handler */ /** * lpfc_sli4_intr_handler - Device-level interrupt handler for SLI-4 device @@ -18106,7 +18106,7 @@ lpfc_sli4_xri_inrange(struct lpfc_hba *phba, /** * lpfc_sli4_seq_abort_rsp - bls rsp to sequence abort - * @vport: pointer to a vitural port. + * @vport: pointer to a virtual port. * @fc_hdr: pointer to a FC frame header. * @aborted: was the partially assembled receive sequence successfully aborted * From f115612528b8e25ff01b6749e0ac61ff6a0f51a0 Mon Sep 17 00:00:00 2001 From: James Smart Date: Sun, 11 Apr 2021 18:31:24 -0700 Subject: [PATCH 371/412] scsi: lpfc: Standardize discovery object logging format Code inspection showed lpfc was using three different pointer formats when logging discovery object pointers. Standardize the pointer format to x%px. Note: %px use is limited to discovery objects in order to aid core analysis. Link: https://lore.kernel.org/r/20210412013127.2387-14-jsmart2021@gmail.com Co-developed-by: Justin Tee Signed-off-by: Justin Tee Signed-off-by: James Smart Signed-off-by: Martin K. Petersen --- drivers/scsi/lpfc/lpfc_ct.c | 2 +- drivers/scsi/lpfc/lpfc_hbadisc.c | 10 +++++----- drivers/scsi/lpfc/lpfc_init.c | 2 +- drivers/scsi/lpfc/lpfc_nvme.c | 16 ++++++++-------- drivers/scsi/lpfc/lpfc_scsi.c | 2 +- drivers/scsi/lpfc/lpfc_sli.c | 6 +++--- 6 files changed, 19 insertions(+), 19 deletions(-) diff --git a/drivers/scsi/lpfc/lpfc_ct.c b/drivers/scsi/lpfc/lpfc_ct.c index 8da9e18a1fde..b9bccd8fc355 100644 --- a/drivers/scsi/lpfc/lpfc_ct.c +++ b/drivers/scsi/lpfc/lpfc_ct.c @@ -777,7 +777,7 @@ lpfc_prep_node_fc4type(struct lpfc_vport *vport, uint32_t Did, uint8_t fc4_type) lpfc_printf_vlog(vport, KERN_INFO, LOG_DISCOVERY, "0239 Skip x%06x NameServer Rsp " - "Data: x%x x%x %p\n", + "Data: x%x x%x x%px\n", Did, vport->fc_flag, vport->fc_rscn_id_cnt, ndlp); } diff --git a/drivers/scsi/lpfc/lpfc_hbadisc.c b/drivers/scsi/lpfc/lpfc_hbadisc.c index 03977a2268fe..f5a898c2c904 100644 --- a/drivers/scsi/lpfc/lpfc_hbadisc.c +++ b/drivers/scsi/lpfc/lpfc_hbadisc.c @@ -102,20 +102,20 @@ lpfc_rport_invalid(struct fc_rport *rport) rdata = rport->dd_data; if (!rdata) { - pr_err("**** %s: NULL dd_data on rport %p SID x%x\n", + pr_err("**** %s: NULL dd_data on rport x%px SID x%x\n", __func__, rport, rport->scsi_target_id); return -EINVAL; } ndlp = rdata->pnode; if (!rdata->pnode) { - pr_err("**** %s: NULL ndlp on rport %p SID x%x\n", + pr_err("**** %s: NULL ndlp on rport x%px SID x%x\n", __func__, rport, rport->scsi_target_id); return -EINVAL; } if (!ndlp->vport) { - pr_err("**** %s: Null vport on ndlp %p, DID x%x rport %p " + pr_err("**** %s: Null vport on ndlp x%px, DID x%x rport x%px " "SID x%x\n", __func__, ndlp, ndlp->nlp_DID, rport, rport->scsi_target_id); return -EINVAL; @@ -168,7 +168,7 @@ lpfc_dev_loss_tmo_callbk(struct fc_rport *rport) ndlp->nlp_sid, ndlp->nlp_DID, ndlp->nlp_flag); lpfc_printf_vlog(ndlp->vport, KERN_INFO, LOG_NODE, - "3181 dev_loss_callbk x%06x, rport %p flg x%x " + "3181 dev_loss_callbk x%06x, rport x%px flg x%x " "load_flag x%x refcnt %d\n", ndlp->nlp_DID, ndlp->rport, ndlp->nlp_flag, vport->load_flag, kref_read(&ndlp->kref)); @@ -6168,7 +6168,7 @@ lpfc_nlp_release(struct kref *kref) ndlp->nlp_DID, ndlp->nlp_flag, ndlp->nlp_type); lpfc_printf_vlog(vport, KERN_INFO, LOG_NODE, - "0279 %s: ndlp:%p did %x refcnt:%d rpi:%x\n", + "0279 %s: ndlp: x%px did %x refcnt:%d rpi:%x\n", __func__, ndlp, ndlp->nlp_DID, kref_read(&ndlp->kref), ndlp->nlp_rpi); diff --git a/drivers/scsi/lpfc/lpfc_init.c b/drivers/scsi/lpfc/lpfc_init.c index c80fd7d49f6e..1e4c792bb660 100644 --- a/drivers/scsi/lpfc/lpfc_init.c +++ b/drivers/scsi/lpfc/lpfc_init.c @@ -3552,7 +3552,7 @@ lpfc_offline_prep(struct lpfc_hba *phba, int mbx_action) lpfc_printf_vlog(vports[i], KERN_INFO, LOG_NODE | LOG_DISCOVERY, "0011 Free RPI x%x on " - "ndlp: %p did x%x\n", + "ndlp: x%px did x%x\n", ndlp->nlp_rpi, ndlp, ndlp->nlp_DID); lpfc_sli4_free_rpi(phba, ndlp->nlp_rpi); diff --git a/drivers/scsi/lpfc/lpfc_nvme.c b/drivers/scsi/lpfc/lpfc_nvme.c index 4d78eadb65c0..41e49f61fac2 100644 --- a/drivers/scsi/lpfc/lpfc_nvme.c +++ b/drivers/scsi/lpfc/lpfc_nvme.c @@ -190,14 +190,14 @@ lpfc_nvme_remoteport_delete(struct nvme_fc_remote_port *remoteport) ndlp = rport->ndlp; if (!ndlp) { - pr_err("**** %s: NULL ndlp on rport %p remoteport %p\n", + pr_err("**** %s: NULL ndlp on rport x%px remoteport x%px\n", __func__, rport, remoteport); goto rport_err; } vport = ndlp->vport; if (!vport) { - pr_err("**** %s: Null vport on ndlp %p, ste x%x rport %p\n", + pr_err("**** %s: Null vport on ndlp x%px, ste x%x rport x%px\n", __func__, ndlp, ndlp->nlp_state, rport); goto rport_err; } @@ -209,7 +209,7 @@ lpfc_nvme_remoteport_delete(struct nvme_fc_remote_port *remoteport) * calling state machine to remove the node. */ lpfc_printf_vlog(vport, KERN_INFO, LOG_NVME_DISC, - "6146 remoteport delete of remoteport %p\n", + "6146 remoteport delete of remoteport x%px\n", remoteport); spin_lock_irq(&ndlp->lock); @@ -317,7 +317,7 @@ __lpfc_nvme_ls_req_cmp(struct lpfc_hba *phba, struct lpfc_vport *vport, status = bf_get(lpfc_wcqe_c_status, wcqe) & LPFC_IOCB_STATUS_MASK; lpfc_printf_vlog(vport, KERN_INFO, LOG_NVME_DISC, - "6047 NVMEx LS REQ %px cmpl DID %x Xri: %x " + "6047 NVMEx LS REQ x%px cmpl DID %x Xri: %x " "status %x reason x%x cmd:x%px lsreg:x%px bmp:x%px " "ndlp:x%px\n", pnvme_lsreq, ndlp ? ndlp->nlp_DID : 0, @@ -339,7 +339,7 @@ __lpfc_nvme_ls_req_cmp(struct lpfc_hba *phba, struct lpfc_vport *vport, else lpfc_printf_vlog(vport, KERN_ERR, LOG_TRACE_EVENT, "6046 NVMEx cmpl without done call back? " - "Data %px DID %x Xri: %x status %x\n", + "Data x%px DID %x Xri: %x status %x\n", pnvme_lsreq, ndlp ? ndlp->nlp_DID : 0, cmdwqe->sli4_xritag, status); if (ndlp) { @@ -707,7 +707,7 @@ __lpfc_nvme_ls_abort(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp, lpfc_printf_vlog(vport, KERN_INFO, LOG_NVME_DISC | LOG_NVME_ABTS, "6040 NVMEx LS REQ Abort: Issue LS_ABORT for lsreq " - "x%p rqstlen:%d rsplen:%d %pad %pad\n", + "x%px rqstlen:%d rsplen:%d %pad %pad\n", pnvme_lsreq, pnvme_lsreq->rqstlen, pnvme_lsreq->rsplen, &pnvme_lsreq->rqstdma, &pnvme_lsreq->rspdma); @@ -736,7 +736,7 @@ __lpfc_nvme_ls_abort(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp, return 0; lpfc_printf_vlog(vport, KERN_INFO, LOG_NVME_DISC | LOG_NVME_ABTS, - "6213 NVMEx LS REQ Abort: Unable to locate req x%p\n", + "6213 NVMEx LS REQ Abort: Unable to locate req x%px\n", pnvme_lsreq); return -EINVAL; } @@ -1839,7 +1839,7 @@ lpfc_nvme_fcp_abort(struct nvme_fc_local_port *pnvme_lport, lpfc_printf_vlog(vport, KERN_ERR, LOG_TRACE_EVENT, "6144 Outstanding NVME I/O Abort Request " "still pending on nvme_fcreq x%px, " - "lpfc_ncmd %px xri x%x\n", + "lpfc_ncmd x%px xri x%x\n", pnvme_fcreq, lpfc_nbuf, nvmereq_wqe->sli4_xritag); goto out_unlock; diff --git a/drivers/scsi/lpfc/lpfc_scsi.c b/drivers/scsi/lpfc/lpfc_scsi.c index 85f6a066de5a..eefbb9b22798 100644 --- a/drivers/scsi/lpfc/lpfc_scsi.c +++ b/drivers/scsi/lpfc/lpfc_scsi.c @@ -4292,7 +4292,7 @@ lpfc_fcp_io_cmd_wqe_cmpl(struct lpfc_hba *phba, struct lpfc_iocbq *pwqeIn, u32 *lp = (u32 *)cmd->sense_buffer; lpfc_printf_vlog(vport, KERN_INFO, LOG_FCP, - "9039 Iodone <%d/%llu> cmd x%p, error " + "9039 Iodone <%d/%llu> cmd x%px, error " "x%x SNS x%x x%x Data: x%x x%x\n", cmd->device->id, cmd->device->lun, cmd, cmd->result, *lp, *(lp + 3), cmd->retries, diff --git a/drivers/scsi/lpfc/lpfc_sli.c b/drivers/scsi/lpfc/lpfc_sli.c index 11145a78dbe9..06ccc0157bd8 100644 --- a/drivers/scsi/lpfc/lpfc_sli.c +++ b/drivers/scsi/lpfc/lpfc_sli.c @@ -2656,7 +2656,7 @@ lpfc_sli_def_mbox_cmpl(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb) vport, KERN_INFO, LOG_MBOX | LOG_DISCOVERY, "1438 UNREG cmpl deferred mbox x%x " - "on NPort x%x Data: x%x x%x %px x%x x%x\n", + "on NPort x%x Data: x%x x%x x%px x%x x%x\n", ndlp->nlp_rpi, ndlp->nlp_DID, ndlp->nlp_flag, ndlp->nlp_defer_did, ndlp, vport->load_flag, kref_read(&ndlp->kref)); @@ -2721,7 +2721,7 @@ lpfc_sli4_unreg_rpi_cmpl_clr(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb) vport, KERN_INFO, LOG_MBOX | LOG_SLI, "0010 UNREG_LOGIN vpi:%x " "rpi:%x DID:%x defer x%x flg x%x " - "%px\n", + "x%px\n", vport->vpi, ndlp->nlp_rpi, ndlp->nlp_DID, ndlp->nlp_defer_did, ndlp->nlp_flag, @@ -3023,7 +3023,7 @@ lpfc_nvme_unsol_ls_handler(struct lpfc_hba *phba, struct lpfc_iocbq *piocb) goto out_fail; lpfc_printf_log(phba, KERN_ERR, LOG_NODE, - "6206 NVMET unsol ls_req ndlp %p " + "6206 NVMET unsol ls_req ndlp x%px " "DID x%x xflags x%x refcnt %d\n", ndlp, ndlp->nlp_DID, ndlp->fc4_xpt_flags, From 5b1f5089b6e65a8a146ae9d0c69708d369c349e4 Mon Sep 17 00:00:00 2001 From: James Smart Date: Sun, 11 Apr 2021 18:31:25 -0700 Subject: [PATCH 372/412] scsi: lpfc: Eliminate use of LPFC_DRIVER_NAME in lpfc_attr.c During code inspection, several cases of creating a dynamic attribute names in logs messages using a define was found. This is unnecessary. Place the native symbol name in the log messages. Link: https://lore.kernel.org/r/20210412013127.2387-15-jsmart2021@gmail.com Co-developed-by: Justin Tee Signed-off-by: Justin Tee Signed-off-by: James Smart Signed-off-by: Martin K. Petersen --- drivers/scsi/lpfc/lpfc_attr.c | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/drivers/scsi/lpfc/lpfc_attr.c b/drivers/scsi/lpfc/lpfc_attr.c index 5bb8a7c1b6ec..0975a8b252a0 100644 --- a/drivers/scsi/lpfc/lpfc_attr.c +++ b/drivers/scsi/lpfc/lpfc_attr.c @@ -2272,14 +2272,14 @@ lpfc_enable_bbcr_set(struct lpfc_hba *phba, uint val) { if (lpfc_rangecheck(val, 0, 1) && phba->sli_rev == LPFC_SLI_REV4) { lpfc_printf_log(phba, KERN_ERR, LOG_INIT, - "3068 %s_enable_bbcr changed from %d to %d\n", - LPFC_DRIVER_NAME, phba->cfg_enable_bbcr, val); + "3068 lpfc_enable_bbcr changed from %d to " + "%d\n", phba->cfg_enable_bbcr, val); phba->cfg_enable_bbcr = val; return 0; } lpfc_printf_log(phba, KERN_ERR, LOG_INIT, - "0451 %s_enable_bbcr cannot set to %d, range is 0, 1\n", - LPFC_DRIVER_NAME, val); + "0451 lpfc_enable_bbcr cannot set to %d, range is 0, " + "1\n", val); return -EINVAL; } @@ -2722,8 +2722,8 @@ lpfc_soft_wwn_enable_store(struct device *dev, struct device_attribute *attr, */ if (vvvl == 1 && cpu_to_be32(*fawwpn_key) == FAPWWN_KEY_VENDOR) { lpfc_printf_log(phba, KERN_ERR, LOG_INIT, - "0051 "LPFC_DRIVER_NAME" soft wwpn can not" - " be enabled: fawwpn is enabled\n"); + "0051 lpfc soft wwpn can not be enabled: " + "fawwpn is enabled\n"); return -EINVAL; } @@ -5208,8 +5208,8 @@ lpfc_cq_max_proc_limit_init(struct lpfc_hba *phba, int val) } lpfc_printf_log(phba, KERN_ERR, LOG_INIT, - "0371 "LPFC_DRIVER_NAME"_cq_max_proc_limit: " - "%d out of range, using default\n", + "0371 lpfc_cq_max_proc_limit: %d out of range, using " + "default\n", phba->cfg_cq_max_proc_limit); return 0; @@ -6043,8 +6043,8 @@ lpfc_sg_seg_cnt_init(struct lpfc_hba *phba, int val) return 0; } lpfc_printf_log(phba, KERN_ERR, LOG_INIT, - "0409 "LPFC_DRIVER_NAME"_sg_seg_cnt attribute cannot " - "be set to %d, allowed range is [%d, %d]\n", + "0409 lpfc_sg_seg_cnt attribute cannot be set to %d, " + "allowed range is [%d, %d]\n", val, LPFC_MIN_SG_SEG_CNT, LPFC_MAX_SG_SEG_CNT); phba->cfg_sg_seg_cnt = LPFC_DEFAULT_SG_SEG_CNT; return -EINVAL; From 3ebd25b0a44359befbbfb17c545d96a10d84e77a Mon Sep 17 00:00:00 2001 From: James Smart Date: Sun, 11 Apr 2021 18:31:26 -0700 Subject: [PATCH 373/412] scsi: lpfc: Update lpfc version to 12.8.0.9 Update lpfc version to 12.8.0.9 Link: https://lore.kernel.org/r/20210412013127.2387-16-jsmart2021@gmail.com Co-developed-by: Justin Tee Signed-off-by: Justin Tee Signed-off-by: James Smart Signed-off-by: Martin K. Petersen --- drivers/scsi/lpfc/lpfc_version.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/scsi/lpfc/lpfc_version.h b/drivers/scsi/lpfc/lpfc_version.h index bee74bd3c1d7..4b8e89375644 100644 --- a/drivers/scsi/lpfc/lpfc_version.h +++ b/drivers/scsi/lpfc/lpfc_version.h @@ -20,7 +20,7 @@ * included with this package. * *******************************************************************/ -#define LPFC_DRIVER_VERSION "12.8.0.8" +#define LPFC_DRIVER_VERSION "12.8.0.9" #define LPFC_DRIVER_NAME "lpfc" /* Used for SLI 2/3 */ From cf270817cafb394547b1d301edfda8222030a26e Mon Sep 17 00:00:00 2001 From: James Smart Date: Sun, 11 Apr 2021 18:31:27 -0700 Subject: [PATCH 374/412] scsi: lpfc: Copyright updates for 12.8.0.9 patches Update copyrights to 2021 for files modified in the 12.8.0.9 patch set. Link: https://lore.kernel.org/r/20210412013127.2387-17-jsmart2021@gmail.com Co-developed-by: Justin Tee Signed-off-by: Justin Tee Signed-off-by: James Smart Signed-off-by: Martin K. Petersen --- drivers/scsi/lpfc/lpfc_bsg.c | 2 +- drivers/scsi/lpfc/lpfc_ct.c | 2 +- drivers/scsi/lpfc/lpfc_hw4.h | 2 +- drivers/scsi/lpfc/lpfc_mbox.c | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/scsi/lpfc/lpfc_bsg.c b/drivers/scsi/lpfc/lpfc_bsg.c index 32e562f27e8f..c2776b88d493 100644 --- a/drivers/scsi/lpfc/lpfc_bsg.c +++ b/drivers/scsi/lpfc/lpfc_bsg.c @@ -1,7 +1,7 @@ /******************************************************************* * This file is part of the Emulex Linux Device Driver for * * Fibre Channel Host Bus Adapters. * - * Copyright (C) 2017-2020 Broadcom. All Rights Reserved. The term * + * Copyright (C) 2017-2021 Broadcom. All Rights Reserved. The term * * “Broadcom” refers to Broadcom Inc. and/or its subsidiaries. * * Copyright (C) 2009-2015 Emulex. All rights reserved. * * EMULEX and SLI are trademarks of Emulex. * diff --git a/drivers/scsi/lpfc/lpfc_ct.c b/drivers/scsi/lpfc/lpfc_ct.c index b9bccd8fc355..3bbefa225484 100644 --- a/drivers/scsi/lpfc/lpfc_ct.c +++ b/drivers/scsi/lpfc/lpfc_ct.c @@ -1,7 +1,7 @@ /******************************************************************* * This file is part of the Emulex Linux Device Driver for * * Fibre Channel Host Bus Adapters. * - * Copyright (C) 2017-2020 Broadcom. All Rights Reserved. The term * + * Copyright (C) 2017-2021 Broadcom. All Rights Reserved. The term * * “Broadcom” refers to Broadcom Inc. and/or its subsidiaries. * * Copyright (C) 2004-2016 Emulex. All rights reserved. * * EMULEX and SLI are trademarks of Emulex. * diff --git a/drivers/scsi/lpfc/lpfc_hw4.h b/drivers/scsi/lpfc/lpfc_hw4.h index f5bc2c32a817..f77e71e6dbbd 100644 --- a/drivers/scsi/lpfc/lpfc_hw4.h +++ b/drivers/scsi/lpfc/lpfc_hw4.h @@ -1,7 +1,7 @@ /******************************************************************* * This file is part of the Emulex Linux Device Driver for * * Fibre Channel Host Bus Adapters. * - * Copyright (C) 2017-2020 Broadcom. All Rights Reserved. The term * + * Copyright (C) 2017-2021 Broadcom. All Rights Reserved. The term * * “Broadcom” refers to Broadcom Inc. and/or its subsidiaries. * * Copyright (C) 2009-2016 Emulex. All rights reserved. * * EMULEX and SLI are trademarks of Emulex. * diff --git a/drivers/scsi/lpfc/lpfc_mbox.c b/drivers/scsi/lpfc/lpfc_mbox.c index 72dd22ad5dcc..1b40a3bbd1cd 100644 --- a/drivers/scsi/lpfc/lpfc_mbox.c +++ b/drivers/scsi/lpfc/lpfc_mbox.c @@ -1,7 +1,7 @@ /******************************************************************* * This file is part of the Emulex Linux Device Driver for * * Fibre Channel Host Bus Adapters. * - * Copyright (C) 2017-2018 Broadcom. All Rights Reserved. The term * + * Copyright (C) 2017-2021 Broadcom. All Rights Reserved. The term * * “Broadcom” refers to Broadcom Inc. and/or its subsidiaries. * * Copyright (C) 2004-2016 Emulex. All rights reserved. * * EMULEX and SLI are trademarks of Emulex. * From 15cfef8623a449d40d16541687afd58e78033be3 Mon Sep 17 00:00:00 2001 From: Brian King Date: Mon, 12 Apr 2021 18:10:09 -0600 Subject: [PATCH 375/412] scsi: ibmvfc: Fix invalid state machine BUG_ON() This fixes an issue hitting the BUG_ON() in ibmvfc_do_work(). When going through a host action of IBMVFC_HOST_ACTION_RESET, we change the action to IBMVFC_HOST_ACTION_TGT_DEL, then drop the host lock, and reset the CRQ, which changes the host state to IBMVFC_NO_CRQ. If, prior to setting the host state to IBMVFC_NO_CRQ, ibmvfc_init_host() is called, it can then end up changing the host action to IBMVFC_HOST_ACTION_INIT. If we then change the host state to IBMVFC_NO_CRQ, we will then hit the BUG_ON(). Make a couple of changes to avoid this. Leave the host action to be IBMVFC_HOST_ACTION_RESET or IBMVFC_HOST_ACTION_REENABLE until after we drop the host lock and reset or reenable the CRQ. Also harden the host state machine to ensure we cannot leave the reset / reenable state until we've finished processing the reset or reenable. Link: https://lore.kernel.org/r/20210413001009.902400-1-tyreld@linux.ibm.com Fixes: 73ee5d867287 ("[SCSI] ibmvfc: Fix soft lockup on resume") Signed-off-by: Brian King [tyreld: added fixes tag] Signed-off-by: Tyrel Datwyler [mkp: fix comment checkpatch warnings] Signed-off-by: Martin K. Petersen --- drivers/scsi/ibmvscsi/ibmvfc.c | 57 ++++++++++++++++++++++------------ 1 file changed, 38 insertions(+), 19 deletions(-) diff --git a/drivers/scsi/ibmvscsi/ibmvfc.c b/drivers/scsi/ibmvscsi/ibmvfc.c index 067c7c45a654..8f3b783ae08a 100644 --- a/drivers/scsi/ibmvscsi/ibmvfc.c +++ b/drivers/scsi/ibmvscsi/ibmvfc.c @@ -604,8 +604,17 @@ static void ibmvfc_set_host_action(struct ibmvfc_host *vhost, if (vhost->action == IBMVFC_HOST_ACTION_ALLOC_TGTS) vhost->action = action; break; + case IBMVFC_HOST_ACTION_REENABLE: + case IBMVFC_HOST_ACTION_RESET: + vhost->action = action; + break; case IBMVFC_HOST_ACTION_INIT: case IBMVFC_HOST_ACTION_TGT_DEL: + case IBMVFC_HOST_ACTION_LOGO: + case IBMVFC_HOST_ACTION_QUERY_TGTS: + case IBMVFC_HOST_ACTION_TGT_DEL_FAILED: + case IBMVFC_HOST_ACTION_NONE: + default: switch (vhost->action) { case IBMVFC_HOST_ACTION_RESET: case IBMVFC_HOST_ACTION_REENABLE: @@ -615,15 +624,6 @@ static void ibmvfc_set_host_action(struct ibmvfc_host *vhost, break; } break; - case IBMVFC_HOST_ACTION_LOGO: - case IBMVFC_HOST_ACTION_QUERY_TGTS: - case IBMVFC_HOST_ACTION_TGT_DEL_FAILED: - case IBMVFC_HOST_ACTION_NONE: - case IBMVFC_HOST_ACTION_RESET: - case IBMVFC_HOST_ACTION_REENABLE: - default: - vhost->action = action; - break; } } @@ -5380,30 +5380,49 @@ static void ibmvfc_do_work(struct ibmvfc_host *vhost) case IBMVFC_HOST_ACTION_INIT_WAIT: break; case IBMVFC_HOST_ACTION_RESET: - vhost->action = IBMVFC_HOST_ACTION_TGT_DEL; list_splice_init(&vhost->purge, &purge); spin_unlock_irqrestore(vhost->host->host_lock, flags); ibmvfc_complete_purge(&purge); rc = ibmvfc_reset_crq(vhost); + spin_lock_irqsave(vhost->host->host_lock, flags); - if (rc == H_CLOSED) + if (!rc || rc == H_CLOSED) vio_enable_interrupts(to_vio_dev(vhost->dev)); - if (rc || (rc = ibmvfc_send_crq_init(vhost)) || - (rc = vio_enable_interrupts(to_vio_dev(vhost->dev)))) { - ibmvfc_link_down(vhost, IBMVFC_LINK_DEAD); - dev_err(vhost->dev, "Error after reset (rc=%d)\n", rc); + if (vhost->action == IBMVFC_HOST_ACTION_RESET) { + /* + * The only action we could have changed to would have + * been reenable, in which case, we skip the rest of + * this path and wait until we've done the re-enable + * before sending the crq init. + */ + vhost->action = IBMVFC_HOST_ACTION_TGT_DEL; + + if (rc || (rc = ibmvfc_send_crq_init(vhost)) || + (rc = vio_enable_interrupts(to_vio_dev(vhost->dev)))) { + ibmvfc_link_down(vhost, IBMVFC_LINK_DEAD); + dev_err(vhost->dev, "Error after reset (rc=%d)\n", rc); + } } break; case IBMVFC_HOST_ACTION_REENABLE: - vhost->action = IBMVFC_HOST_ACTION_TGT_DEL; list_splice_init(&vhost->purge, &purge); spin_unlock_irqrestore(vhost->host->host_lock, flags); ibmvfc_complete_purge(&purge); rc = ibmvfc_reenable_crq_queue(vhost); + spin_lock_irqsave(vhost->host->host_lock, flags); - if (rc || (rc = ibmvfc_send_crq_init(vhost))) { - ibmvfc_link_down(vhost, IBMVFC_LINK_DEAD); - dev_err(vhost->dev, "Error after enable (rc=%d)\n", rc); + if (vhost->action == IBMVFC_HOST_ACTION_REENABLE) { + /* + * The only action we could have changed to would have + * been reset, in which case, we skip the rest of this + * path and wait until we've done the reset before + * sending the crq init. + */ + vhost->action = IBMVFC_HOST_ACTION_TGT_DEL; + if (rc || (rc = ibmvfc_send_crq_init(vhost))) { + ibmvfc_link_down(vhost, IBMVFC_LINK_DEAD); + dev_err(vhost->dev, "Error after enable (rc=%d)\n", rc); + } } break; case IBMVFC_HOST_ACTION_LOGO: From 667298ceaf042e28b856478e02cfa2cbe8ed83c6 Mon Sep 17 00:00:00 2001 From: Don Brace Date: Thu, 15 Apr 2021 11:42:04 -0500 Subject: [PATCH 376/412] scsi: smartpqi: Fix blocks_per_row static checker issue Dan Carpenter found a possible divide by 0 issue in the smartpqi driver in functions pci_get_aio_common_raid_map_values() and pqi_calc_aio_r5_or_r6(). The variable rmd->blocks_per_row is used as a divisor and could be 0. Using rmd->blocks_per_row as a divisor without checking it for 0 first. Correct these possible divide by 0 conditions by insuring that rmd->blocks_per_row is not zero before usage. The check for non-0 was too late to prevent a divide by 0 condition. Add in a comment to explain why the check for non-zero is necessary. If the member is 0, return PQI_RAID_BYPASS_INELIGIBLE before any division is performed. Link: https://lore.kernel.org/linux-scsi/YG%2F5kWHHAr7w5dU5@mwanda/ Link: https://lore.kernel.org/r/161850492435.7302.392780350442938047.stgit@brunhilda Fixes: 6702d2c40f31 ("scsi: smartpqi: Add support for RAID5 and RAID6 writes") Reported-by: Dan Carpenter Reported-by: kernel test robot Reviewed-by: Scott Benesh Reviewed-by: Scott Teel Reviewed-by: Mike McGowen Reviewed-by: Kevin Barnett Signed-off-by: Don Brace Signed-off-by: Martin K. Petersen --- drivers/scsi/smartpqi/smartpqi_init.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/drivers/scsi/smartpqi/smartpqi_init.c b/drivers/scsi/smartpqi/smartpqi_init.c index 3b0f281daa2b..797ac699b7ff 100644 --- a/drivers/scsi/smartpqi/smartpqi_init.c +++ b/drivers/scsi/smartpqi/smartpqi_init.c @@ -2510,6 +2510,8 @@ static int pci_get_aio_common_raid_map_values(struct pqi_ctrl_info *ctrl_info, /* Calculate stripe information for the request. */ rmd->blocks_per_row = rmd->data_disks_per_row * rmd->strip_size; + if (rmd->blocks_per_row == 0) /* Used as a divisor in many calculations */ + return PQI_RAID_BYPASS_INELIGIBLE; #if BITS_PER_LONG == 32 tmpdiv = rmd->first_block; do_div(tmpdiv, rmd->blocks_per_row); @@ -2559,6 +2561,10 @@ static int pqi_calc_aio_r5_or_r6(struct pqi_scsi_dev_raid_map_data *rmd, #if BITS_PER_LONG == 32 u64 tmpdiv; #endif + + if (rmd->blocks_per_row == 0) /* Used as a divisor in many calculations */ + return PQI_RAID_BYPASS_INELIGIBLE; + /* RAID 50/60 */ /* Verify first and last block are in same RAID group. */ rmd->stripesize = rmd->blocks_per_row * rmd->layout_map_count; @@ -2662,8 +2668,6 @@ static int pqi_calc_aio_r5_or_r6(struct pqi_scsi_dev_raid_map_data *rmd, rmd->q_parity_it_nexus = raid_map->disk_data[index + 1].aio_handle; rmd->xor_mult = raid_map->disk_data[rmd->map_index].xor_mult[1]; } - if (rmd->blocks_per_row == 0) - return PQI_RAID_BYPASS_INELIGIBLE; #if BITS_PER_LONG == 32 tmpdiv = rmd->first_block; do_div(tmpdiv, rmd->blocks_per_row); From 5cad5a507241b4b72b7cad27cf769ac645e53d45 Mon Sep 17 00:00:00 2001 From: Don Brace Date: Thu, 15 Apr 2021 11:42:10 -0500 Subject: [PATCH 377/412] scsi: smartpqi: Fix device pointer variable reference static checker issue Dan Carpenter found a possible NULL pointer dereference issue in function pqi_sas_port_add_rphy(): drivers/scsi/smartpqi/smartpqi_sas_transport.c:97 pqi_sas_port_add_rphy() warn: variable dereferenced before check 'pqi_sas_port->device' (see line 95) Correct issue by moving reference of pqi_sas_port->device after the check for the device pointer being non-NULL. Link: https://www.mail-archive.com/kbuild@lists.01.org/msg06329.html Link: https://lore.kernel.org/r/161850493026.7302.10032784239320437353.stgit@brunhilda Fixes: ec504b23df9d ("scsi: smartpqi: Add phy ID support for the physical drives") Reported-by: Dan Carpenter Reported-by: kernel test robot Reviewed-by: Scott Benesh Reviewed-by: Scott Teel Reviewed-by: Mike McGowen Reviewed-by: Kevin Barnett Signed-off-by: Don Brace Signed-off-by: Martin K. Petersen --- drivers/scsi/smartpqi/smartpqi_sas_transport.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/scsi/smartpqi/smartpqi_sas_transport.c b/drivers/scsi/smartpqi/smartpqi_sas_transport.c index dd9b784792ef..dd628cc87f78 100644 --- a/drivers/scsi/smartpqi/smartpqi_sas_transport.c +++ b/drivers/scsi/smartpqi/smartpqi_sas_transport.c @@ -92,12 +92,12 @@ static int pqi_sas_port_add_rphy(struct pqi_sas_port *pqi_sas_port, identify = &rphy->identify; identify->sas_address = pqi_sas_port->sas_address; - identify->phy_identifier = pqi_sas_port->device->phy_id; identify->initiator_port_protocols = SAS_PROTOCOL_ALL; identify->target_port_protocols = SAS_PROTOCOL_STP; if (pqi_sas_port->device) { + identify->phy_identifier = pqi_sas_port->device->phy_id; switch (pqi_sas_port->device->device_type) { case SA_DEVICE_TYPE_SAS: case SA_DEVICE_TYPE_SES: From f02d4086a8f36a0e1aaebf559b54cf24a177a486 Mon Sep 17 00:00:00 2001 From: Roman Bolshakov Date: Mon, 12 Apr 2021 19:57:40 +0300 Subject: [PATCH 378/412] scsi: qla2xxx: Reserve extra IRQ vectors Commit a6dcfe08487e ("scsi: qla2xxx: Limit interrupt vectors to number of CPUs") lowers the number of allocated MSI-X vectors to the number of CPUs. That breaks vector allocation assumptions in qla83xx_iospace_config(), qla24xx_enable_msix() and qla2x00_iospace_config(). Either of the functions computes maximum number of qpairs as: ha->max_qpairs = ha->msix_count - 1 (MB interrupt) - 1 (default response queue) - 1 (ATIO, in dual or pure target mode) max_qpairs is set to zero in case of two CPUs and initiator mode. The number is then used to allocate ha->queue_pair_map inside qla2x00_alloc_queues(). No allocation happens and ha->queue_pair_map is left NULL but the driver thinks there are queue pairs available. qla2xxx_queuecommand() tries to find a qpair in the map and crashes: if (ha->mqenable) { uint32_t tag; uint16_t hwq; struct qla_qpair *qpair = NULL; tag = blk_mq_unique_tag(cmd->request); hwq = blk_mq_unique_tag_to_hwq(tag); qpair = ha->queue_pair_map[hwq]; # <- HERE if (qpair) return qla2xxx_mqueuecommand(host, cmd, qpair); } BUG: kernel NULL pointer dereference, address: 0000000000000000 #PF: supervisor read access in kernel mode #PF: error_code(0x0000) - not-present page PGD 0 P4D 0 Oops: 0000 [#1] SMP PTI CPU: 0 PID: 72 Comm: kworker/u4:3 Tainted: G W 5.10.0-rc1+ #25 Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS 1.0.0-prebuilt.qemu-project.org 04/01/2014 Workqueue: scsi_wq_7 fc_scsi_scan_rport [scsi_transport_fc] RIP: 0010:qla2xxx_queuecommand+0x16b/0x3f0 [qla2xxx] Call Trace: scsi_queue_rq+0x58c/0xa60 blk_mq_dispatch_rq_list+0x2b7/0x6f0 ? __sbitmap_get_word+0x2a/0x80 __blk_mq_sched_dispatch_requests+0xb8/0x170 blk_mq_sched_dispatch_requests+0x2b/0x50 __blk_mq_run_hw_queue+0x49/0xb0 __blk_mq_delay_run_hw_queue+0xfb/0x150 blk_mq_sched_insert_request+0xbe/0x110 blk_execute_rq+0x45/0x70 __scsi_execute+0x10e/0x250 scsi_probe_and_add_lun+0x228/0xda0 __scsi_scan_target+0xf4/0x620 ? __pm_runtime_resume+0x4f/0x70 scsi_scan_target+0x100/0x110 fc_scsi_scan_rport+0xa1/0xb0 [scsi_transport_fc] process_one_work+0x1ea/0x3b0 worker_thread+0x28/0x3b0 ? process_one_work+0x3b0/0x3b0 kthread+0x112/0x130 ? kthread_park+0x80/0x80 ret_from_fork+0x22/0x30 The driver should allocate enough vectors to provide every CPU it's own HW queue and still handle reserved (MB, RSP, ATIO) interrupts. The change fixes the crash on dual core VM and prevents unbalanced QP allocation where nr_hw_queues is two less than the number of CPUs. Link: https://lore.kernel.org/r/20210412165740.39318-1-r.bolshakov@yadro.com Fixes: a6dcfe08487e ("scsi: qla2xxx: Limit interrupt vectors to number of CPUs") Cc: Daniel Wagner Cc: Himanshu Madhani Cc: Quinn Tran Cc: Nilesh Javali Cc: Martin K. Petersen Cc: stable@vger.kernel.org # 5.11+ Reported-by: Aleksandr Volkov Reported-by: Aleksandr Miloserdov Reviewed-by: Daniel Wagner Reviewed-by: Himanshu Madhani Signed-off-by: Roman Bolshakov Signed-off-by: Martin K. Petersen --- drivers/scsi/qla2xxx/qla_isr.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/scsi/qla2xxx/qla_isr.c b/drivers/scsi/qla2xxx/qla_isr.c index 11d6e0db07fe..6e8f737a4af3 100644 --- a/drivers/scsi/qla2xxx/qla_isr.c +++ b/drivers/scsi/qla2xxx/qla_isr.c @@ -3998,11 +3998,11 @@ qla24xx_enable_msix(struct qla_hw_data *ha, struct rsp_que *rsp) if (USER_CTRL_IRQ(ha) || !ha->mqiobase) { /* user wants to control IRQ setting for target mode */ ret = pci_alloc_irq_vectors(ha->pdev, min_vecs, - min((u16)ha->msix_count, (u16)num_online_cpus()), + min((u16)ha->msix_count, (u16)(num_online_cpus() + min_vecs)), PCI_IRQ_MSIX); } else ret = pci_alloc_irq_vectors_affinity(ha->pdev, min_vecs, - min((u16)ha->msix_count, (u16)num_online_cpus()), + min((u16)ha->msix_count, (u16)(num_online_cpus() + min_vecs)), PCI_IRQ_MSIX | PCI_IRQ_AFFINITY, &desc); From 91cf21ec6d04db21ab51d47014fd9970b5bd9861 Mon Sep 17 00:00:00 2001 From: Julian Wiedmann Date: Wed, 14 Apr 2021 19:07:59 +0200 Subject: [PATCH 379/412] scsi: zfcp: Remove unneeded INIT_LIST_HEAD() for FSF requests INIT_LIST_HEAD() is only needed for actual list heads, while req->list is used as a list entry. Note that when the error path in zfcp_fsf_req_send() removes the request from the adapter's list of pending requests, it actually looks up the request from the zfcp_reqlist - rather than just calling list_del(). So there's no risk of us calling list_del() on a request that hasn't been added to any list yet. Link: https://lore.kernel.org/r/254dc0ae28dccc43ab0b1079ef2c8dcb5fe1d2e4.1618417667.git.bblock@linux.ibm.com Reviewed-by: Benjamin Block Reviewed-by: Steffen Maier Signed-off-by: Julian Wiedmann Signed-off-by: Benjamin Block Signed-off-by: Martin K. Petersen --- drivers/s390/scsi/zfcp_fsf.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/s390/scsi/zfcp_fsf.c b/drivers/s390/scsi/zfcp_fsf.c index 485028324eae..2e4804ef2fb9 100644 --- a/drivers/s390/scsi/zfcp_fsf.c +++ b/drivers/s390/scsi/zfcp_fsf.c @@ -846,7 +846,6 @@ static struct zfcp_fsf_req *zfcp_fsf_req_create(struct zfcp_qdio *qdio, if (adapter->req_no == 0) adapter->req_no++; - INIT_LIST_HEAD(&req->list); timer_setup(&req->timer, NULL, 0); init_completion(&req->completion); From 8824db894dd1da48bad363612577ef410a5d1828 Mon Sep 17 00:00:00 2001 From: Yevhen Viktorov Date: Wed, 14 Apr 2021 19:08:00 +0200 Subject: [PATCH 380/412] scsi: zfcp: Fix indentation coding style issue Code indentation should use tabs where possible. Link: https://lore.kernel.org/r/e8a15a2f3d64e2e76a214647cfd4fe23d370b165.1618417667.git.bblock@linux.ibm.com Signed-off-by: Yevhen Viktorov Signed-off-by: Steffen Maier Signed-off-by: Benjamin Block Signed-off-by: Martin K. Petersen --- drivers/s390/scsi/zfcp_def.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/s390/scsi/zfcp_def.h b/drivers/s390/scsi/zfcp_def.h index 26c89c232ef2..94de55304a02 100644 --- a/drivers/s390/scsi/zfcp_def.h +++ b/drivers/s390/scsi/zfcp_def.h @@ -156,7 +156,7 @@ struct zfcp_adapter { u32 fsf_lic_version; u32 adapter_features; /* FCP channel features */ u32 connection_features; /* host connection features */ - u32 hardware_version; /* of FCP channel */ + u32 hardware_version; /* of FCP channel */ u32 fc_security_algorithms; /* of FCP channel */ u32 fc_security_algorithms_old; /* of FCP channel */ u16 timer_ticks; /* time int for a tick */ @@ -180,7 +180,7 @@ struct zfcp_adapter { rwlock_t erp_lock; wait_queue_head_t erp_done_wqh; struct zfcp_erp_action erp_action; /* pending error recovery */ - atomic_t erp_counter; + atomic_t erp_counter; u32 erp_total_count; /* total nr of enqueued erp actions */ u32 erp_low_mem_count; /* nr of erp actions waiting @@ -217,7 +217,7 @@ struct zfcp_port { u32 d_id; /* D_ID */ u32 handle; /* handle assigned by FSF */ struct zfcp_erp_action erp_action; /* pending error recovery */ - atomic_t erp_counter; + atomic_t erp_counter; u32 maxframe_size; u32 supported_classes; u32 connection_info; From ab1fa88062f8d1d9e8947719b8ed3ab48a60476c Mon Sep 17 00:00:00 2001 From: Julian Wiedmann Date: Wed, 14 Apr 2021 19:08:01 +0200 Subject: [PATCH 381/412] scsi: zfcp: Fix sysfs roll-back on error in zfcp_adapter_enqueue() When zfcp_adapter_enqueue() fails to create the zfcp_sysfs_adapter_attrs group, it calls zfcp_adapter_unregister() to tear down the adapter state again. This then unconditionally attempts to remove the zfcp_sysfs_adapter_attrs group, resulting in a "group not found" WARN from sysfs code. Avoid this by copying most of zfcp_adapter_unregister() into the error path, allowing for more fine-granular roll-back. Then skip the sysfs tear-down steps if we haven't progressed this far in the initialization. Link: https://lore.kernel.org/r/790922cc3af075795fff9a4b787e6bda19bdb3be.1618417667.git.bblock@linux.ibm.com Reviewed-by: Benjamin Block Reviewed-by: Steffen Maier Signed-off-by: Julian Wiedmann Signed-off-by: Benjamin Block Signed-off-by: Martin K. Petersen --- drivers/s390/scsi/zfcp_aux.c | 20 ++++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) diff --git a/drivers/s390/scsi/zfcp_aux.c b/drivers/s390/scsi/zfcp_aux.c index 768873dd55b8..abad77694e72 100644 --- a/drivers/s390/scsi/zfcp_aux.c +++ b/drivers/s390/scsi/zfcp_aux.c @@ -418,7 +418,7 @@ struct zfcp_adapter *zfcp_adapter_enqueue(struct ccw_device *ccw_device) goto failed; if (zfcp_diag_sysfs_setup(adapter)) - goto failed; + goto err_diag_sysfs; /* report size limit per scatter-gather segment */ adapter->ccw_device->dev.dma_parms = &adapter->dma_parms; @@ -427,8 +427,24 @@ struct zfcp_adapter *zfcp_adapter_enqueue(struct ccw_device *ccw_device) return adapter; +err_diag_sysfs: + sysfs_remove_group(&ccw_device->dev.kobj, &zfcp_sysfs_adapter_attrs); failed: - zfcp_adapter_unregister(adapter); + /* TODO: make this more fine-granular */ + cancel_delayed_work_sync(&adapter->scan_work); + cancel_work_sync(&adapter->stat_work); + cancel_work_sync(&adapter->ns_up_work); + cancel_work_sync(&adapter->version_change_lost_work); + zfcp_destroy_adapter_work_queue(adapter); + + zfcp_fc_wka_ports_force_offline(adapter->gs); + zfcp_scsi_adapter_unregister(adapter); + + zfcp_erp_thread_kill(adapter); + zfcp_dbf_adapter_unregister(adapter); + zfcp_qdio_destroy(adapter->qdio); + + zfcp_ccw_adapter_put(adapter); /* final put to release */ return ERR_PTR(-ENOMEM); } From 20540a5645f00015ca8eb968b98d62a1b275ceb8 Mon Sep 17 00:00:00 2001 From: Julian Wiedmann Date: Wed, 14 Apr 2021 19:08:02 +0200 Subject: [PATCH 382/412] scsi: zfcp: Clean up sysfs code for SFP diagnostics The error path from zfcp_adapter_enqueue() no longer attempts to remove the diagnostics attributes if they haven't been created yet. So remove the manual 'sysfs_established' guard for this case, and use device_add_groups() to add all adapter-related sysfs attributes in one go. Link: https://lore.kernel.org/r/37a97537f675d643006271f37723c346189b6eec.1618417667.git.bblock@linux.ibm.com Reviewed-by: Benjamin Block Reviewed-by: Steffen Maier Signed-off-by: Julian Wiedmann Signed-off-by: Benjamin Block Signed-off-by: Martin K. Petersen --- drivers/s390/scsi/zfcp_aux.c | 14 ++++-------- drivers/s390/scsi/zfcp_diag.c | 42 ---------------------------------- drivers/s390/scsi/zfcp_diag.h | 7 ------ drivers/s390/scsi/zfcp_ext.h | 4 ++-- drivers/s390/scsi/zfcp_sysfs.c | 10 ++++++-- 5 files changed, 14 insertions(+), 63 deletions(-) diff --git a/drivers/s390/scsi/zfcp_aux.c b/drivers/s390/scsi/zfcp_aux.c index abad77694e72..fd2f1c31bd21 100644 --- a/drivers/s390/scsi/zfcp_aux.c +++ b/drivers/s390/scsi/zfcp_aux.c @@ -413,12 +413,8 @@ struct zfcp_adapter *zfcp_adapter_enqueue(struct ccw_device *ccw_device) dev_set_drvdata(&ccw_device->dev, adapter); - if (sysfs_create_group(&ccw_device->dev.kobj, - &zfcp_sysfs_adapter_attrs)) - goto failed; - - if (zfcp_diag_sysfs_setup(adapter)) - goto err_diag_sysfs; + if (device_add_groups(&ccw_device->dev, zfcp_sysfs_adapter_attr_groups)) + goto err_sysfs; /* report size limit per scatter-gather segment */ adapter->ccw_device->dev.dma_parms = &adapter->dma_parms; @@ -427,8 +423,7 @@ struct zfcp_adapter *zfcp_adapter_enqueue(struct ccw_device *ccw_device) return adapter; -err_diag_sysfs: - sysfs_remove_group(&ccw_device->dev.kobj, &zfcp_sysfs_adapter_attrs); +err_sysfs: failed: /* TODO: make this more fine-granular */ cancel_delayed_work_sync(&adapter->scan_work); @@ -460,8 +455,7 @@ void zfcp_adapter_unregister(struct zfcp_adapter *adapter) zfcp_fc_wka_ports_force_offline(adapter->gs); zfcp_scsi_adapter_unregister(adapter); - zfcp_diag_sysfs_destroy(adapter); - sysfs_remove_group(&cdev->dev.kobj, &zfcp_sysfs_adapter_attrs); + device_remove_groups(&cdev->dev, zfcp_sysfs_adapter_attr_groups); zfcp_erp_thread_kill(adapter); zfcp_dbf_adapter_unregister(adapter); diff --git a/drivers/s390/scsi/zfcp_diag.c b/drivers/s390/scsi/zfcp_diag.c index 67a8f4e57db1..4d2d89d9c15a 100644 --- a/drivers/s390/scsi/zfcp_diag.c +++ b/drivers/s390/scsi/zfcp_diag.c @@ -10,8 +10,6 @@ #include #include #include -#include -#include #include #include @@ -79,46 +77,6 @@ void zfcp_diag_adapter_free(struct zfcp_adapter *const adapter) adapter->diagnostics = NULL; } -/** - * zfcp_diag_sysfs_setup() - Setup the sysfs-group for adapter-diagnostics. - * @adapter: target adapter to which the group should be added. - * - * Return: 0 on success; Something else otherwise (see sysfs_create_group()). - */ -int zfcp_diag_sysfs_setup(struct zfcp_adapter *const adapter) -{ - int rc = sysfs_create_group(&adapter->ccw_device->dev.kobj, - &zfcp_sysfs_diag_attr_group); - if (rc == 0) - adapter->diagnostics->sysfs_established = 1; - - return rc; -} - -/** - * zfcp_diag_sysfs_destroy() - Remove the sysfs-group for adapter-diagnostics. - * @adapter: target adapter from which the group should be removed. - */ -void zfcp_diag_sysfs_destroy(struct zfcp_adapter *const adapter) -{ - if (adapter->diagnostics == NULL || - !adapter->diagnostics->sysfs_established) - return; - - /* - * We need this state-handling so we can prevent warnings being printed - * on the kernel-console in case we have to abort a halfway done - * zfcp_adapter_enqueue(), in which the sysfs-group was not yet - * established. sysfs_remove_group() does this checking as well, but - * still prints a warning in case we try to remove a group that has not - * been established before - */ - adapter->diagnostics->sysfs_established = 0; - sysfs_remove_group(&adapter->ccw_device->dev.kobj, - &zfcp_sysfs_diag_attr_group); -} - - /** * zfcp_diag_update_xdata() - Update a diagnostics buffer. * @hdr: the meta data to update. diff --git a/drivers/s390/scsi/zfcp_diag.h b/drivers/s390/scsi/zfcp_diag.h index 3852367f15f6..da55133da8fe 100644 --- a/drivers/s390/scsi/zfcp_diag.h +++ b/drivers/s390/scsi/zfcp_diag.h @@ -40,8 +40,6 @@ struct zfcp_diag_header { /** * struct zfcp_diag_adapter - central storage for all diagnostics concerning an * adapter. - * @sysfs_established: flag showing that the associated sysfs-group was created - * during run of zfcp_adapter_enqueue(). * @max_age: maximum age of data in diagnostic buffers before they need to be * refreshed (in ms). * @port_data: data retrieved using exchange port data. @@ -52,8 +50,6 @@ struct zfcp_diag_header { * @config_data.data: cached QTCB Bottom of command exchange config data. */ struct zfcp_diag_adapter { - u64 sysfs_established :1; - unsigned long max_age; struct zfcp_diag_adapter_port_data { @@ -69,9 +65,6 @@ struct zfcp_diag_adapter { int zfcp_diag_adapter_setup(struct zfcp_adapter *const adapter); void zfcp_diag_adapter_free(struct zfcp_adapter *const adapter); -int zfcp_diag_sysfs_setup(struct zfcp_adapter *const adapter); -void zfcp_diag_sysfs_destroy(struct zfcp_adapter *const adapter); - void zfcp_diag_update_xdata(struct zfcp_diag_header *const hdr, const void *const data, const bool incomplete); diff --git a/drivers/s390/scsi/zfcp_ext.h b/drivers/s390/scsi/zfcp_ext.h index 58879213f225..6bc96d70254d 100644 --- a/drivers/s390/scsi/zfcp_ext.h +++ b/drivers/s390/scsi/zfcp_ext.h @@ -11,6 +11,7 @@ #define ZFCP_EXT_H #include +#include #include #include "zfcp_def.h" #include "zfcp_fc.h" @@ -179,13 +180,12 @@ extern void zfcp_scsi_shost_update_port_data( const struct fsf_qtcb_bottom_port *const bottom); /* zfcp_sysfs.c */ +extern const struct attribute_group *zfcp_sysfs_adapter_attr_groups[]; extern const struct attribute_group *zfcp_unit_attr_groups[]; -extern struct attribute_group zfcp_sysfs_adapter_attrs; extern const struct attribute_group *zfcp_port_attr_groups[]; extern struct mutex zfcp_sysfs_port_units_mutex; extern struct device_attribute *zfcp_sysfs_sdev_attrs[]; extern struct device_attribute *zfcp_sysfs_shost_attrs[]; -extern const struct attribute_group zfcp_sysfs_diag_attr_group; bool zfcp_sysfs_port_is_removing(const struct zfcp_port *const port); /* zfcp_unit.c */ diff --git a/drivers/s390/scsi/zfcp_sysfs.c b/drivers/s390/scsi/zfcp_sysfs.c index 8d9662e8b717..f76946dcbd59 100644 --- a/drivers/s390/scsi/zfcp_sysfs.c +++ b/drivers/s390/scsi/zfcp_sysfs.c @@ -435,7 +435,7 @@ static struct attribute *zfcp_adapter_attrs[] = { NULL }; -struct attribute_group zfcp_sysfs_adapter_attrs = { +static const struct attribute_group zfcp_sysfs_adapter_attr_group = { .attrs = zfcp_adapter_attrs, }; @@ -906,7 +906,13 @@ static struct attribute *zfcp_sysfs_diag_attrs[] = { NULL, }; -const struct attribute_group zfcp_sysfs_diag_attr_group = { +static const struct attribute_group zfcp_sysfs_diag_attr_group = { .name = "diagnostics", .attrs = zfcp_sysfs_diag_attrs, }; + +const struct attribute_group *zfcp_sysfs_adapter_attr_groups[] = { + &zfcp_sysfs_adapter_attr_group, + &zfcp_sysfs_diag_attr_group, + NULL, +}; From be46e39ae3be8cde8dd0d09d7c0f8eed443747ab Mon Sep 17 00:00:00 2001 From: Qinglang Miao Date: Wed, 14 Apr 2021 19:08:03 +0200 Subject: [PATCH 383/412] scsi: zfcp: Move the position of put_device() Place the put_device() call after device_unregister() in both zfcp_unit_remove() and zfcp_sysfs_port_remove_store() to make it more natural. put_device() ought to be the last time we touch the object in both functions. Add comments after put_device() to make code clearer. Link: https://lore.kernel.org/r/0a568c7733ba0f1dde28b0c663b90270d44dd540.1618417667.git.bblock@linux.ibm.com Suggested-by: Steffen Maier Suggested-by: Benjamin Block Signed-off-by: Qinglang Miao Signed-off-by: Benjamin Block Signed-off-by: Martin K. Petersen --- drivers/s390/scsi/zfcp_sysfs.c | 4 ++-- drivers/s390/scsi/zfcp_unit.c | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/s390/scsi/zfcp_sysfs.c b/drivers/s390/scsi/zfcp_sysfs.c index f76946dcbd59..544efd4c42f0 100644 --- a/drivers/s390/scsi/zfcp_sysfs.c +++ b/drivers/s390/scsi/zfcp_sysfs.c @@ -327,10 +327,10 @@ static ssize_t zfcp_sysfs_port_remove_store(struct device *dev, list_del(&port->list); write_unlock_irq(&adapter->port_list_lock); - put_device(&port->dev); - zfcp_erp_port_shutdown(port, 0, "syprs_1"); device_unregister(&port->dev); + + put_device(&port->dev); /* undo zfcp_get_port_by_wwpn() */ out: zfcp_ccw_adapter_put(adapter); return retval ? retval : (ssize_t) count; diff --git a/drivers/s390/scsi/zfcp_unit.c b/drivers/s390/scsi/zfcp_unit.c index e67bf7388cae..59333f0257a8 100644 --- a/drivers/s390/scsi/zfcp_unit.c +++ b/drivers/s390/scsi/zfcp_unit.c @@ -255,9 +255,9 @@ int zfcp_unit_remove(struct zfcp_port *port, u64 fcp_lun) scsi_device_put(sdev); } - put_device(&unit->dev); - device_unregister(&unit->dev); + put_device(&unit->dev); /* undo _zfcp_unit_find() */ + return 0; } From b3f0a1ee9e3986106869eec49b61b40abdccdcf7 Mon Sep 17 00:00:00 2001 From: Julian Wiedmann Date: Wed, 14 Apr 2021 19:08:04 +0200 Subject: [PATCH 384/412] scsi: zfcp: Lift Request Queue tasklet & timer from qdio The qdio layer currently provides its own infrastructure to scan for Request Queue completions & to report them to the device driver. This comes with several drawbacks - having an async tasklet & timer construct in qdio introduces additional lifetime complexity, and makes it harder to integrate them with the rest of the device driver. The timeouts are also currently hard-coded, and can't be tweaked without affecting other qdio drivers (ie. qeth). But due to recent enhancements to the qdio layer, zfcp can actually take full control of the Request Queue completion processing. It merely needs to opt-out from the qdio layer mechanisms by setting the scan_threshold to 0, and then use qdio_inspect_queue() to scan for completions. So re-implement the tasklet & timer mechanism in zfcp, while initially copying the scan conditions from qdio's handle_outbound() and qdio_outbound_tasklet(). One minor behavioural change is that zfcp_qdio_send() will unconditionally reduce the timeout to 1 HZ, rather than leaving it at 10 Hz if it was last armed by the tasklet. This just makes things more consistent. Also note that we can drop a lot of the accumulated cruft in qdio_outbound_tasklet(), as zfcp doesn't even use PCI interrupt requests any longer. This also slightly touches the Response Queue processing, as qdio_get_next_buffers() will no longer implicitly scan for Request Queue completions. So complete the migration to qdio_inspect_queue() here as well and make the tasklet_schedule() visible. Link: https://lore.kernel.org/r/018d3ddd029f8d6ac00cf4184880288c637c4fd1.1618417667.git.bblock@linux.ibm.com Reviewed-by: Benjamin Block Signed-off-by: Julian Wiedmann Signed-off-by: Benjamin Block Signed-off-by: Martin K. Petersen --- drivers/s390/scsi/zfcp_qdio.c | 68 ++++++++++++++++++++++++++++------- drivers/s390/scsi/zfcp_qdio.h | 5 +++ 2 files changed, 61 insertions(+), 12 deletions(-) diff --git a/drivers/s390/scsi/zfcp_qdio.c b/drivers/s390/scsi/zfcp_qdio.c index 23ab16d65f2a..16a332d501e7 100644 --- a/drivers/s390/scsi/zfcp_qdio.c +++ b/drivers/s390/scsi/zfcp_qdio.c @@ -20,6 +20,9 @@ static bool enable_multibuffer = true; module_param_named(datarouter, enable_multibuffer, bool, 0400); MODULE_PARM_DESC(datarouter, "Enable hardware data router support (default on)"); +#define ZFCP_QDIO_REQUEST_RESCAN_MSECS (MSEC_PER_SEC * 10) +#define ZFCP_QDIO_REQUEST_SCAN_MSECS MSEC_PER_SEC + static void zfcp_qdio_handler_error(struct zfcp_qdio *qdio, char *dbftag, unsigned int qdio_err) { @@ -70,15 +73,41 @@ static void zfcp_qdio_int_req(struct ccw_device *cdev, unsigned int qdio_err, zfcp_qdio_handler_error(qdio, "qdireq1", qdio_err); return; } +} - /* cleanup all SBALs being program-owned now */ - zfcp_qdio_zero_sbals(qdio->req_q, idx, count); +static void zfcp_qdio_request_tasklet(struct tasklet_struct *tasklet) +{ + struct zfcp_qdio *qdio = from_tasklet(qdio, tasklet, request_tasklet); + struct ccw_device *cdev = qdio->adapter->ccw_device; + unsigned int start, error; + int completed; - spin_lock_irq(&qdio->stat_lock); - zfcp_qdio_account(qdio); - spin_unlock_irq(&qdio->stat_lock); - atomic_add(count, &qdio->req_q_free); - wake_up(&qdio->req_q_wq); + completed = qdio_inspect_queue(cdev, 0, false, &start, &error); + if (completed > 0) { + if (error) { + zfcp_qdio_handler_error(qdio, "qdreqt1", error); + } else { + /* cleanup all SBALs being program-owned now */ + zfcp_qdio_zero_sbals(qdio->req_q, start, completed); + + spin_lock_irq(&qdio->stat_lock); + zfcp_qdio_account(qdio); + spin_unlock_irq(&qdio->stat_lock); + atomic_add(completed, &qdio->req_q_free); + wake_up(&qdio->req_q_wq); + } + } + + if (atomic_read(&qdio->req_q_free) < QDIO_MAX_BUFFERS_PER_Q) + timer_reduce(&qdio->request_timer, + jiffies + msecs_to_jiffies(ZFCP_QDIO_REQUEST_RESCAN_MSECS)); +} + +static void zfcp_qdio_request_timer(struct timer_list *timer) +{ + struct zfcp_qdio *qdio = from_timer(qdio, timer, request_timer); + + tasklet_schedule(&qdio->request_tasklet); } static void zfcp_qdio_int_resp(struct ccw_device *cdev, unsigned int qdio_err, @@ -139,8 +168,11 @@ static void zfcp_qdio_irq_tasklet(struct tasklet_struct *tasklet) unsigned int start, error; int completed; - /* Check the Response Queue, and kick off the Request Queue tasklet: */ - completed = qdio_get_next_buffers(cdev, 0, &start, &error); + if (atomic_read(&qdio->req_q_free) < QDIO_MAX_BUFFERS_PER_Q) + tasklet_schedule(&qdio->request_tasklet); + + /* Check the Response Queue: */ + completed = qdio_inspect_queue(cdev, 0, true, &start, &error); if (completed < 0) return; if (completed > 0) @@ -286,7 +318,7 @@ int zfcp_qdio_send(struct zfcp_qdio *qdio, struct zfcp_qdio_req *q_req) /* * This should actually be a spin_lock_bh(stat_lock), to protect against - * zfcp_qdio_int_req() in tasklet context. + * Request Queue completion processing in tasklet context. * But we can't do so (and are safe), as we always get called with IRQs * disabled by spin_lock_irq[save](req_q_lock). */ @@ -308,6 +340,12 @@ int zfcp_qdio_send(struct zfcp_qdio *qdio, struct zfcp_qdio_req *q_req) return retval; } + if (atomic_read(&qdio->req_q_free) <= 2 * ZFCP_QDIO_MAX_SBALS_PER_REQ) + tasklet_schedule(&qdio->request_tasklet); + else + timer_reduce(&qdio->request_timer, + jiffies + msecs_to_jiffies(ZFCP_QDIO_REQUEST_SCAN_MSECS)); + /* account for transferred buffers */ qdio->req_q_idx += sbal_number; qdio->req_q_idx %= QDIO_MAX_BUFFERS_PER_Q; @@ -368,6 +406,8 @@ void zfcp_qdio_close(struct zfcp_qdio *qdio) wake_up(&qdio->req_q_wq); tasklet_disable(&qdio->irq_tasklet); + tasklet_disable(&qdio->request_tasklet); + del_timer_sync(&qdio->request_timer); qdio_stop_irq(adapter->ccw_device); qdio_shutdown(adapter->ccw_device, QDIO_FLAG_CLEANUP_USING_CLEAR); @@ -428,8 +468,6 @@ int zfcp_qdio_open(struct zfcp_qdio *qdio) init_data.int_parm = (unsigned long) qdio; init_data.input_sbal_addr_array = input_sbals; init_data.output_sbal_addr_array = output_sbals; - init_data.scan_threshold = - QDIO_MAX_BUFFERS_PER_Q - ZFCP_QDIO_MAX_SBALS_PER_REQ * 2; if (qdio_establish(cdev, &init_data)) goto failed_establish; @@ -471,6 +509,8 @@ int zfcp_qdio_open(struct zfcp_qdio *qdio) atomic_set(&qdio->req_q_free, QDIO_MAX_BUFFERS_PER_Q); atomic_or(ZFCP_STATUS_ADAPTER_QDIOUP, &qdio->adapter->status); + /* Enable processing for Request Queue completions: */ + tasklet_enable(&qdio->request_tasklet); /* Enable processing for QDIO interrupts: */ tasklet_enable(&qdio->irq_tasklet); /* This results in a qdio_start_irq(): */ @@ -494,6 +534,7 @@ void zfcp_qdio_destroy(struct zfcp_qdio *qdio) return; tasklet_kill(&qdio->irq_tasklet); + tasklet_kill(&qdio->request_tasklet); if (qdio->adapter->ccw_device) qdio_free(qdio->adapter->ccw_device); @@ -520,8 +561,11 @@ int zfcp_qdio_setup(struct zfcp_adapter *adapter) spin_lock_init(&qdio->req_q_lock); spin_lock_init(&qdio->stat_lock); + timer_setup(&qdio->request_timer, zfcp_qdio_request_timer, 0); tasklet_setup(&qdio->irq_tasklet, zfcp_qdio_irq_tasklet); + tasklet_setup(&qdio->request_tasklet, zfcp_qdio_request_tasklet); tasklet_disable(&qdio->irq_tasklet); + tasklet_disable(&qdio->request_tasklet); adapter->qdio = qdio; return 0; diff --git a/drivers/s390/scsi/zfcp_qdio.h b/drivers/s390/scsi/zfcp_qdio.h index 9c1f310db155..390706867df3 100644 --- a/drivers/s390/scsi/zfcp_qdio.h +++ b/drivers/s390/scsi/zfcp_qdio.h @@ -30,6 +30,9 @@ * @req_q_util: used for accounting * @req_q_full: queue full incidents * @req_q_wq: used to wait for SBAL availability + * @irq_tasklet: used for QDIO interrupt processing + * @request_tasklet: used for Request Queue completion processing + * @request_timer: used to trigger the Request Queue completion processing * @adapter: adapter used in conjunction with this qdio structure * @max_sbale_per_sbal: qdio limit per sbal * @max_sbale_per_req: qdio limit per request @@ -46,6 +49,8 @@ struct zfcp_qdio { atomic_t req_q_full; wait_queue_head_t req_q_wq; struct tasklet_struct irq_tasklet; + struct tasklet_struct request_tasklet; + struct timer_list request_timer; struct zfcp_adapter *adapter; u16 max_sbale_per_sbal; u16 max_sbale_per_req; From 4ddbea1b6f51a2ac07c4b80b3c3f50ea37367828 Mon Sep 17 00:00:00 2001 From: Vishakha Channapattan Date: Thu, 15 Apr 2021 16:03:45 +0530 Subject: [PATCH 385/412] scsi: pm80xx: Add sysfs attribute to check MPI state A new sysfs variable 'ctl_mpi_state' is being introduced to check the state of MPI. Using the 'ctl_mpi_state' sysfs variable we can check the MPI state: linux-2dq0:~# cat /sys/class/scsi_host/host*/ctl_mpi_state MPI is successfully initialized Link: https://lore.kernel.org/r/20210415103352.3580-2-Viswas.G@microchip.com Reported-by: kernel test robot Reported-by: Dan Carpenter Signed-off-by: Vishakha Channapattan Signed-off-by: Viswas G Signed-off-by: Ruksar Devadi Signed-off-by: Ashokkumar N Signed-off-by: Radha Ramachandran Signed-off-by: kernel test robot Signed-off-by: Martin K. Petersen --- drivers/scsi/pm8001/pm8001_ctl.c | 32 +++++++++++++++++++++++++++++++- 1 file changed, 31 insertions(+), 1 deletion(-) diff --git a/drivers/scsi/pm8001/pm8001_ctl.c b/drivers/scsi/pm8001/pm8001_ctl.c index 26e340edb0b3..f3863076a81e 100644 --- a/drivers/scsi/pm8001/pm8001_ctl.c +++ b/drivers/scsi/pm8001/pm8001_ctl.c @@ -41,6 +41,7 @@ #include #include "pm8001_sas.h" #include "pm8001_ctl.h" +#include "pm8001_chips.h" /* scsi host attributes */ @@ -879,9 +880,37 @@ static ssize_t pm8001_show_update_fw(struct device *cdev, flash_error_table[i].err_code, flash_error_table[i].reason); } - static DEVICE_ATTR(update_fw, S_IRUGO|S_IWUSR|S_IWGRP, pm8001_show_update_fw, pm8001_store_update_fw); + +/** + * ctl_mpi_state_show - controller MPI state check + * @cdev: pointer to embedded class device + * @buf: the buffer returned + * + * A sysfs 'read-only' shost attribute. + */ + +static const char *const mpiStateText[] = { + "MPI is not initialized", + "MPI is successfully initialized", + "MPI termination is in progress", + "MPI initialization failed with error in [31:16]" +}; + +static ssize_t ctl_mpi_state_show(struct device *cdev, + struct device_attribute *attr, char *buf) +{ + struct Scsi_Host *shost = class_to_shost(cdev); + struct sas_ha_struct *sha = SHOST_TO_SAS_HA(shost); + struct pm8001_hba_info *pm8001_ha = sha->lldd_ha; + unsigned int mpidw0; + + mpidw0 = pm8001_mr32(pm8001_ha->general_stat_tbl_addr, 0); + return sysfs_emit(buf, "%s\n", mpiStateText[mpidw0 & 0x0003]); +} +static DEVICE_ATTR_RO(ctl_mpi_state); + struct device_attribute *pm8001_host_attrs[] = { &dev_attr_interface_rev, &dev_attr_controller_fatal_error, @@ -905,6 +934,7 @@ struct device_attribute *pm8001_host_attrs[] = { &dev_attr_ob_log, &dev_attr_ila_version, &dev_attr_inc_fw_ver, + &dev_attr_ctl_mpi_state, NULL, }; From a4c55e16c50022825966864cf1f08b9efa3ebb86 Mon Sep 17 00:00:00 2001 From: Vishakha Channapattan Date: Thu, 15 Apr 2021 16:03:46 +0530 Subject: [PATCH 386/412] scsi: pm80xx: Add sysfs attribute to check controller hmi error A new sysfs variable 'ctl_hmi_error' is being introduced to give the error details if the MPI initialization fails Using the 'ctl_hmi_error' sysfs variable we can check the error details: linux-2dq0:~# cat /sys/class/scsi_host/host*/ctl_hmi_error 0x00000000 0x00000000 0x00000000 Link: https://lore.kernel.org/r/20210415103352.3580-3-Viswas.G@microchip.com Signed-off-by: Vishakha Channapattan Signed-off-by: Viswas G Signed-off-by: Ruksar Devadi Signed-off-by: Martin K. Petersen --- drivers/scsi/pm8001/pm8001_ctl.c | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/drivers/scsi/pm8001/pm8001_ctl.c b/drivers/scsi/pm8001/pm8001_ctl.c index f3863076a81e..786bd2d252b6 100644 --- a/drivers/scsi/pm8001/pm8001_ctl.c +++ b/drivers/scsi/pm8001/pm8001_ctl.c @@ -911,6 +911,27 @@ static ssize_t ctl_mpi_state_show(struct device *cdev, } static DEVICE_ATTR_RO(ctl_mpi_state); +/** + * ctl_hmi_error_show - controller MPI initialization fails + * @cdev: pointer to embedded class device + * @buf: the buffer returned + * + * A sysfs 'read-only' shost attribute. + */ + +static ssize_t ctl_hmi_error_show(struct device *cdev, + struct device_attribute *attr, char *buf) +{ + struct Scsi_Host *shost = class_to_shost(cdev); + struct sas_ha_struct *sha = SHOST_TO_SAS_HA(shost); + struct pm8001_hba_info *pm8001_ha = sha->lldd_ha; + unsigned int mpidw0; + + mpidw0 = pm8001_mr32(pm8001_ha->general_stat_tbl_addr, 0); + return sysfs_emit(buf, "0x%08x\n", (mpidw0 >> 16)); +} +static DEVICE_ATTR_RO(ctl_hmi_error); + struct device_attribute *pm8001_host_attrs[] = { &dev_attr_interface_rev, &dev_attr_controller_fatal_error, @@ -935,6 +956,7 @@ struct device_attribute *pm8001_host_attrs[] = { &dev_attr_ila_version, &dev_attr_inc_fw_ver, &dev_attr_ctl_mpi_state, + &dev_attr_ctl_hmi_error, NULL, }; From dd49ded8aa432e2877e8b8bafcc00898c20ca381 Mon Sep 17 00:00:00 2001 From: Vishakha Channapattan Date: Thu, 15 Apr 2021 16:03:47 +0530 Subject: [PATCH 387/412] scsi: pm80xx: Add sysfs attribute to track RAAE count A new sysfs variable 'ctl_raae_count' is being introduced that tells if the controller is alive by indicating controller ticks. If on subsequent run we see the ticks changing in RAAE count that indicates that controller is not dead. Using the 'ctl_raae_count' sysfs variable we can see ticks incrementing: linux-9saw:~# cat /sys/class/scsi_host/host*/ctl_raae_count 0x00002245 0x00002253 0x0000225e Link: https://lore.kernel.org/r/20210415103352.3580-4-Viswas.G@microchip.com Acked-by: Jack Wang Signed-off-by: Vishakha Channapattan Signed-off-by: Viswas G Signed-off-by: Ruksar Devadi Signed-off-by: Ashokkumar N Signed-off-by: Radha Ramachandran Signed-off-by: Martin K. Petersen --- drivers/scsi/pm8001/pm8001_ctl.c | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/drivers/scsi/pm8001/pm8001_ctl.c b/drivers/scsi/pm8001/pm8001_ctl.c index 786bd2d252b6..4552e695be14 100644 --- a/drivers/scsi/pm8001/pm8001_ctl.c +++ b/drivers/scsi/pm8001/pm8001_ctl.c @@ -932,6 +932,27 @@ static ssize_t ctl_hmi_error_show(struct device *cdev, } static DEVICE_ATTR_RO(ctl_hmi_error); +/** + * ctl_raae_count_show - controller raae count check + * @cdev: pointer to embedded class device + * @buf: the buffer returned + * + * A sysfs 'read-only' shost attribute. + */ + +static ssize_t ctl_raae_count_show(struct device *cdev, + struct device_attribute *attr, char *buf) +{ + struct Scsi_Host *shost = class_to_shost(cdev); + struct sas_ha_struct *sha = SHOST_TO_SAS_HA(shost); + struct pm8001_hba_info *pm8001_ha = sha->lldd_ha; + unsigned int raaecnt; + + raaecnt = pm8001_mr32(pm8001_ha->general_stat_tbl_addr, 12); + return sysfs_emit(buf, "0x%08x\n", raaecnt); +} +static DEVICE_ATTR_RO(ctl_raae_count); + struct device_attribute *pm8001_host_attrs[] = { &dev_attr_interface_rev, &dev_attr_controller_fatal_error, @@ -957,6 +978,7 @@ struct device_attribute *pm8001_host_attrs[] = { &dev_attr_inc_fw_ver, &dev_attr_ctl_mpi_state, &dev_attr_ctl_hmi_error, + &dev_attr_ctl_raae_count, NULL, }; From 0602624ace23afddb92ec842fc602df04fad97c0 Mon Sep 17 00:00:00 2001 From: Vishakha Channapattan Date: Thu, 15 Apr 2021 16:03:48 +0530 Subject: [PATCH 388/412] scsi: pm80xx: Add sysfs attribute to track iop0 count A new sysfs variable 'ctl_iop0_count' is being introduced that tells if the controller is alive by indicating controller ticks. If on subsequent run we see the ticks changing that indicates that controller is not dead. Using the 'ctl_iop0_count' sysfs variable we can see ticks incrementing: linux-9saw:~# cat /sys/class/scsi_host/host*/ctl_iop0_count 0x000000a3 0x000001db 0x000001e4 0x000001e7 Link: https://lore.kernel.org/r/20210415103352.3580-5-Viswas.G@microchip.com Acked-by: Jack Wang Signed-off-by: Vishakha Channapattan Signed-off-by: Viswas G Signed-off-by: Ruksar Devadi Signed-off-by: Ashokkumar N Signed-off-by: Radha Ramachandran Signed-off-by: Martin K. Petersen --- drivers/scsi/pm8001/pm8001_ctl.c | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/drivers/scsi/pm8001/pm8001_ctl.c b/drivers/scsi/pm8001/pm8001_ctl.c index 4552e695be14..aa35c4d77d15 100644 --- a/drivers/scsi/pm8001/pm8001_ctl.c +++ b/drivers/scsi/pm8001/pm8001_ctl.c @@ -953,6 +953,27 @@ static ssize_t ctl_raae_count_show(struct device *cdev, } static DEVICE_ATTR_RO(ctl_raae_count); +/** + * ctl_iop0_count_show - controller iop0 count check + * @cdev: pointer to embedded class device + * @buf: the buffer returned + * + * A sysfs 'read-only' shost attribute. + */ + +static ssize_t ctl_iop0_count_show(struct device *cdev, + struct device_attribute *attr, char *buf) +{ + struct Scsi_Host *shost = class_to_shost(cdev); + struct sas_ha_struct *sha = SHOST_TO_SAS_HA(shost); + struct pm8001_hba_info *pm8001_ha = sha->lldd_ha; + unsigned int iop0cnt; + + iop0cnt = pm8001_mr32(pm8001_ha->general_stat_tbl_addr, 16); + return sysfs_emit(buf, "0x%08x\n", iop0cnt); +} +static DEVICE_ATTR_RO(ctl_iop0_count); + struct device_attribute *pm8001_host_attrs[] = { &dev_attr_interface_rev, &dev_attr_controller_fatal_error, @@ -979,6 +1000,7 @@ struct device_attribute *pm8001_host_attrs[] = { &dev_attr_ctl_mpi_state, &dev_attr_ctl_hmi_error, &dev_attr_ctl_raae_count, + &dev_attr_ctl_iop0_count, NULL, }; From b0c306e6216749378ce43f2c5ac4f17bb5ba35ff Mon Sep 17 00:00:00 2001 From: Vishakha Channapattan Date: Thu, 15 Apr 2021 16:03:49 +0530 Subject: [PATCH 389/412] scsi: pm80xx: Add sysfs attribute to track iop1 count A new sysfs variable 'ctl_iop1_count' is being introduced that tells if the controller is alive by indicating controller ticks. If on subsequent run we see the ticks changing that indicates that controller is not dead. Using the 'ctl_iop1_count' sysfs variable we can see ticks incrementing: linux-9saw:~# cat /sys/class/scsi_host/host*/ctl_iop1_count 0x00000069 0x0000006b 0x0000006d 0x00000072 Link: https://lore.kernel.org/r/20210415103352.3580-6-Viswas.G@microchip.com Acked-by: Jack Wang Signed-off-by: Vishakha Channapattan Signed-off-by: Viswas G Signed-off-by: Ruksar Devadi Signed-off-by: Ashokkumar N Signed-off-by: Radha Ramachandran Signed-off-by: Martin K. Petersen --- drivers/scsi/pm8001/pm8001_ctl.c | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/drivers/scsi/pm8001/pm8001_ctl.c b/drivers/scsi/pm8001/pm8001_ctl.c index aa35c4d77d15..0b8802beb7ce 100644 --- a/drivers/scsi/pm8001/pm8001_ctl.c +++ b/drivers/scsi/pm8001/pm8001_ctl.c @@ -974,6 +974,28 @@ static ssize_t ctl_iop0_count_show(struct device *cdev, } static DEVICE_ATTR_RO(ctl_iop0_count); +/** + * ctl_iop1_count_show - controller iop1 count check + * @cdev: pointer to embedded class device + * @buf: the buffer returned + * + * A sysfs 'read-only' shost attribute. + */ + +static ssize_t ctl_iop1_count_show(struct device *cdev, + struct device_attribute *attr, char *buf) +{ + struct Scsi_Host *shost = class_to_shost(cdev); + struct sas_ha_struct *sha = SHOST_TO_SAS_HA(shost); + struct pm8001_hba_info *pm8001_ha = sha->lldd_ha; + unsigned int iop1cnt; + + iop1cnt = pm8001_mr32(pm8001_ha->general_stat_tbl_addr, 20); + return sysfs_emit(buf, "0x%08x\n", iop1cnt); + +} +static DEVICE_ATTR_RO(ctl_iop1_count); + struct device_attribute *pm8001_host_attrs[] = { &dev_attr_interface_rev, &dev_attr_controller_fatal_error, @@ -1001,6 +1023,7 @@ struct device_attribute *pm8001_host_attrs[] = { &dev_attr_ctl_hmi_error, &dev_attr_ctl_raae_count, &dev_attr_ctl_iop0_count, + &dev_attr_ctl_iop1_count, NULL, }; From 4f5deeb40f9cf721030a1bdfecb19584fca9091e Mon Sep 17 00:00:00 2001 From: Ruksar Devadi Date: Thu, 15 Apr 2021 16:03:50 +0530 Subject: [PATCH 390/412] scsi: pm80xx: Completing pending I/O after fatal error When controller runs into fatal error, I/Os get stuck with no response, handler event is defined to complete the pending I/Os (SAS task and internal task) and also perform the cleanup for the drives. Link: https://lore.kernel.org/r/20210415103352.3580-7-Viswas.G@microchip.com Acked-by: Jack Wang Signed-off-by: Ruksar Devadi Signed-off-by: Viswas G Signed-off-by: Ashokkumar N Signed-off-by: Martin K. Petersen --- drivers/scsi/pm8001/pm8001_hwi.c | 66 +++++++++++++++++++++++++++++--- drivers/scsi/pm8001/pm8001_hwi.h | 1 + drivers/scsi/pm8001/pm8001_sas.c | 2 +- drivers/scsi/pm8001/pm8001_sas.h | 1 + drivers/scsi/pm8001/pm80xx_hwi.c | 1 + drivers/scsi/pm8001/pm80xx_hwi.h | 1 + 6 files changed, 65 insertions(+), 7 deletions(-) diff --git a/drivers/scsi/pm8001/pm8001_hwi.c b/drivers/scsi/pm8001/pm8001_hwi.c index c1f9e7d0466b..8ed505051657 100644 --- a/drivers/scsi/pm8001/pm8001_hwi.c +++ b/drivers/scsi/pm8001/pm8001_hwi.c @@ -1499,12 +1499,14 @@ void pm8001_work_fn(struct work_struct *work) * was cancelled. This nullification happens when the device * goes away. */ - pm8001_dev = pw->data; /* Most stash device structure */ - if ((pm8001_dev == NULL) - || ((pw->handler != IO_XFER_ERROR_BREAK) - && (pm8001_dev->dev_type == SAS_PHY_UNUSED))) { - kfree(pw); - return; + if (pw->handler != IO_FATAL_ERROR) { + pm8001_dev = pw->data; /* Most stash device structure */ + if ((pm8001_dev == NULL) + || ((pw->handler != IO_XFER_ERROR_BREAK) + && (pm8001_dev->dev_type == SAS_PHY_UNUSED))) { + kfree(pw); + return; + } } switch (pw->handler) { @@ -1668,6 +1670,58 @@ void pm8001_work_fn(struct work_struct *work) dev = pm8001_dev->sas_device; pm8001_I_T_nexus_reset(dev); break; + case IO_FATAL_ERROR: + { + struct pm8001_hba_info *pm8001_ha = pw->pm8001_ha; + struct pm8001_ccb_info *ccb; + struct task_status_struct *ts; + struct sas_task *task; + int i; + u32 tag, device_id; + + for (i = 0; ccb = NULL, i < PM8001_MAX_CCB; i++) { + ccb = &pm8001_ha->ccb_info[i]; + task = ccb->task; + ts = &task->task_status; + tag = ccb->ccb_tag; + /* check if tag is NULL */ + if (!tag) { + pm8001_dbg(pm8001_ha, FAIL, + "tag Null\n"); + continue; + } + if (task != NULL) { + dev = task->dev; + if (!dev) { + pm8001_dbg(pm8001_ha, FAIL, + "dev is NULL\n"); + continue; + } + /*complete sas task and update to top layer */ + pm8001_ccb_task_free(pm8001_ha, task, ccb, tag); + ts->resp = SAS_TASK_COMPLETE; + task->task_done(task); + } else if (tag != 0xFFFFFFFF) { + /* complete the internal commands/non-sas task */ + pm8001_dev = ccb->device; + if (pm8001_dev->dcompletion) { + complete(pm8001_dev->dcompletion); + pm8001_dev->dcompletion = NULL; + } + complete(pm8001_ha->nvmd_completion); + pm8001_tag_free(pm8001_ha, tag); + } + } + /* Deregister all the device ids */ + for (i = 0; i < PM8001_MAX_DEVICES; i++) { + pm8001_dev = &pm8001_ha->devices[i]; + device_id = pm8001_dev->device_id; + if (device_id) { + PM8001_CHIP_DISP->dereg_dev_req(pm8001_ha, device_id); + pm8001_free_dev(pm8001_dev); + } + } + } break; } kfree(pw); } diff --git a/drivers/scsi/pm8001/pm8001_hwi.h b/drivers/scsi/pm8001/pm8001_hwi.h index 6d91e2446542..d1f3aa93325b 100644 --- a/drivers/scsi/pm8001/pm8001_hwi.h +++ b/drivers/scsi/pm8001/pm8001_hwi.h @@ -805,6 +805,7 @@ struct set_dev_state_resp { #define IO_ABORT_IN_PROGRESS 0x40 #define IO_ABORT_DELAYED 0x41 #define IO_INVALID_LENGTH 0x42 +#define IO_FATAL_ERROR 0x51 /* WARNING: This error code must always be the last number. * If you add error code, modify this code also diff --git a/drivers/scsi/pm8001/pm8001_sas.c b/drivers/scsi/pm8001/pm8001_sas.c index a773ee6e810b..d28af413b93a 100644 --- a/drivers/scsi/pm8001/pm8001_sas.c +++ b/drivers/scsi/pm8001/pm8001_sas.c @@ -590,7 +590,7 @@ struct pm8001_device *pm8001_find_dev(struct pm8001_hba_info *pm8001_ha, return NULL; } -static void pm8001_free_dev(struct pm8001_device *pm8001_dev) +void pm8001_free_dev(struct pm8001_device *pm8001_dev) { u32 id = pm8001_dev->id; memset(pm8001_dev, 0, sizeof(*pm8001_dev)); diff --git a/drivers/scsi/pm8001/pm8001_sas.h b/drivers/scsi/pm8001/pm8001_sas.h index 07d1ac287d43..b5562f7fc7e5 100644 --- a/drivers/scsi/pm8001/pm8001_sas.h +++ b/drivers/scsi/pm8001/pm8001_sas.h @@ -726,6 +726,7 @@ ssize_t pm80xx_get_non_fatal_dump(struct device *cdev, struct device_attribute *attr, char *buf); ssize_t pm8001_get_gsm_dump(struct device *cdev, u32, char *buf); int pm80xx_fatal_errors(struct pm8001_hba_info *pm8001_ha); +void pm8001_free_dev(struct pm8001_device *pm8001_dev); /* ctl shared API */ extern struct device_attribute *pm8001_host_attrs[]; diff --git a/drivers/scsi/pm8001/pm80xx_hwi.c b/drivers/scsi/pm8001/pm80xx_hwi.c index f4f3956e658f..1c8dcdd5642c 100644 --- a/drivers/scsi/pm8001/pm80xx_hwi.c +++ b/drivers/scsi/pm8001/pm80xx_hwi.c @@ -4126,6 +4126,7 @@ static int process_oq(struct pm8001_hba_info *pm8001_ha, u8 vec) pm8001_dbg(pm8001_ha, FAIL, "Firmware Fatal error! Regval:0x%x\n", regval); + pm8001_handle_event(pm8001_ha, NULL, IO_FATAL_ERROR); print_scratchpad_registers(pm8001_ha); return ret; } diff --git a/drivers/scsi/pm8001/pm80xx_hwi.h b/drivers/scsi/pm8001/pm80xx_hwi.h index 2c8e85cfdbc4..c7e5d93bea92 100644 --- a/drivers/scsi/pm8001/pm80xx_hwi.h +++ b/drivers/scsi/pm8001/pm80xx_hwi.h @@ -1272,6 +1272,7 @@ typedef struct SASProtocolTimerConfig SASProtocolTimerConfig_t; #define IO_OPEN_CNX_ERROR_IT_NEXUS_LOSS_OPEN_COLLIDE 0x47 #define IO_OPEN_CNX_ERROR_IT_NEXUS_LOSS_PATHWAY_BLOCKED 0x48 #define IO_DS_INVALID 0x49 +#define IO_FATAL_ERROR 0x51 /* WARNING: the value is not contiguous from here */ #define IO_XFER_ERR_LAST_PIO_DATAIN_CRC_ERR 0x52 #define IO_XFER_DMA_ACTIVATE_TIMEOUT 0x53 From b431472bc88b4a230c88049ed077fcccf4448980 Mon Sep 17 00:00:00 2001 From: Viswas G Date: Thu, 15 Apr 2021 16:03:51 +0530 Subject: [PATCH 391/412] scsi: pm80xx: Reset PI and CI memory during re-initialization Producer index(PI) outbound queue and consumer index(CI) for Outbound queue are in DMA memory. During resume(), the stale PI and CI Values will lead to unexpected behavior. These values should be reset to 0 during driver reinitialization. Link: https://lore.kernel.org/r/20210415103352.3580-8-Viswas.G@microchip.com Acked-by: Jack Wang Signed-off-by: Viswas G Signed-off-by: Ruksar Devadi Signed-off-by: Ashokkumar N Signed-off-by: Martin K. Petersen --- drivers/scsi/pm8001/pm8001_hwi.c | 2 ++ drivers/scsi/pm8001/pm80xx_hwi.c | 2 ++ 2 files changed, 4 insertions(+) diff --git a/drivers/scsi/pm8001/pm8001_hwi.c b/drivers/scsi/pm8001/pm8001_hwi.c index 8ed505051657..ecd06d2d7e81 100644 --- a/drivers/scsi/pm8001/pm8001_hwi.c +++ b/drivers/scsi/pm8001/pm8001_hwi.c @@ -240,6 +240,7 @@ static void init_default_table_values(struct pm8001_hba_info *pm8001_ha) pm8001_ha->memoryMap.region[ci_offset + i].phys_addr_lo; pm8001_ha->inbnd_q_tbl[i].ci_virt = pm8001_ha->memoryMap.region[ci_offset + i].virt_ptr; + pm8001_write_32(pm8001_ha->inbnd_q_tbl[i].ci_virt, 0, 0); offsetib = i * 0x20; pm8001_ha->inbnd_q_tbl[i].pi_pci_bar = get_pci_bar_index(pm8001_mr32(addressib, @@ -268,6 +269,7 @@ static void init_default_table_values(struct pm8001_hba_info *pm8001_ha) 0 | (10 << 16) | (i << 24); pm8001_ha->outbnd_q_tbl[i].pi_virt = pm8001_ha->memoryMap.region[pi_offset + i].virt_ptr; + pm8001_write_32(pm8001_ha->outbnd_q_tbl[i].pi_virt, 0, 0); offsetob = i * 0x24; pm8001_ha->outbnd_q_tbl[i].ci_pci_bar = get_pci_bar_index(pm8001_mr32(addressob, diff --git a/drivers/scsi/pm8001/pm80xx_hwi.c b/drivers/scsi/pm8001/pm80xx_hwi.c index 1c8dcdd5642c..771490223f87 100644 --- a/drivers/scsi/pm8001/pm80xx_hwi.c +++ b/drivers/scsi/pm8001/pm80xx_hwi.c @@ -787,6 +787,7 @@ static void init_default_table_values(struct pm8001_hba_info *pm8001_ha) pm8001_ha->memoryMap.region[ci_offset + i].phys_addr_lo; pm8001_ha->inbnd_q_tbl[i].ci_virt = pm8001_ha->memoryMap.region[ci_offset + i].virt_ptr; + pm8001_write_32(pm8001_ha->inbnd_q_tbl[i].ci_virt, 0, 0); offsetib = i * 0x20; pm8001_ha->inbnd_q_tbl[i].pi_pci_bar = get_pci_bar_index(pm8001_mr32(addressib, @@ -820,6 +821,7 @@ static void init_default_table_values(struct pm8001_hba_info *pm8001_ha) pm8001_ha->outbnd_q_tbl[i].interrup_vec_cnt_delay = (i << 24); pm8001_ha->outbnd_q_tbl[i].pi_virt = pm8001_ha->memoryMap.region[pi_offset + i].virt_ptr; + pm8001_write_32(pm8001_ha->outbnd_q_tbl[i].pi_virt, 0, 0); offsetob = i * 0x24; pm8001_ha->outbnd_q_tbl[i].ci_pci_bar = get_pci_bar_index(pm8001_mr32(addressob, From 1f02beff224e6176c1a0aacced7fb5127b240996 Mon Sep 17 00:00:00 2001 From: Viswas G Date: Thu, 15 Apr 2021 16:03:52 +0530 Subject: [PATCH 392/412] scsi: pm80xx: Remove global lock from outbound queue processing Introduce spin lock for outbound queue. With this, driver need not acquire HBA global lock for outbound queue processing. Link: https://lore.kernel.org/r/20210415103352.3580-9-Viswas.G@microchip.com Acked-by: Jack Wang Signed-off-by: Viswas G Signed-off-by: Ruksar Devadi Signed-off-by: Ashokkumar N Signed-off-by: Martin K. Petersen --- drivers/scsi/pm8001/pm8001_init.c | 9 ++++++--- drivers/scsi/pm8001/pm8001_sas.h | 1 + drivers/scsi/pm8001/pm80xx_hwi.c | 4 ++-- 3 files changed, 9 insertions(+), 5 deletions(-) diff --git a/drivers/scsi/pm8001/pm8001_init.c b/drivers/scsi/pm8001/pm8001_init.c index 0f7b3fffb393..390c33df0357 100644 --- a/drivers/scsi/pm8001/pm8001_init.c +++ b/drivers/scsi/pm8001/pm8001_init.c @@ -267,7 +267,8 @@ static int pm8001_alloc(struct pm8001_hba_info *pm8001_ha, { int i, count = 0, rc = 0; u32 ci_offset, ib_offset, ob_offset, pi_offset; - struct inbound_queue_table *circularQ; + struct inbound_queue_table *ibq; + struct outbound_queue_table *obq; spin_lock_init(&pm8001_ha->lock); spin_lock_init(&pm8001_ha->bitmap_lock); @@ -315,8 +316,8 @@ static int pm8001_alloc(struct pm8001_hba_info *pm8001_ha, pm8001_ha->memoryMap.region[IOP].alignment = 32; for (i = 0; i < count; i++) { - circularQ = &pm8001_ha->inbnd_q_tbl[i]; - spin_lock_init(&circularQ->iq_lock); + ibq = &pm8001_ha->inbnd_q_tbl[i]; + spin_lock_init(&ibq->iq_lock); /* MPI Memory region 3 for consumer Index of inbound queues */ pm8001_ha->memoryMap.region[ci_offset+i].num_elements = 1; pm8001_ha->memoryMap.region[ci_offset+i].element_size = 4; @@ -345,6 +346,8 @@ static int pm8001_alloc(struct pm8001_hba_info *pm8001_ha, } for (i = 0; i < count; i++) { + obq = &pm8001_ha->outbnd_q_tbl[i]; + spin_lock_init(&obq->oq_lock); /* MPI Memory region 4 for producer Index of outbound queues */ pm8001_ha->memoryMap.region[pi_offset+i].num_elements = 1; pm8001_ha->memoryMap.region[pi_offset+i].element_size = 4; diff --git a/drivers/scsi/pm8001/pm8001_sas.h b/drivers/scsi/pm8001/pm8001_sas.h index b5562f7fc7e5..62d08b535a4b 100644 --- a/drivers/scsi/pm8001/pm8001_sas.h +++ b/drivers/scsi/pm8001/pm8001_sas.h @@ -456,6 +456,7 @@ struct outbound_queue_table { u32 dinterrup_to_pci_offset; __le32 producer_index; u32 consumer_idx; + spinlock_t oq_lock; }; struct pm8001_hba_memspace { void __iomem *memvirtaddr; diff --git a/drivers/scsi/pm8001/pm80xx_hwi.c b/drivers/scsi/pm8001/pm80xx_hwi.c index 771490223f87..4e980830f9f5 100644 --- a/drivers/scsi/pm8001/pm80xx_hwi.c +++ b/drivers/scsi/pm8001/pm80xx_hwi.c @@ -4133,8 +4133,8 @@ static int process_oq(struct pm8001_hba_info *pm8001_ha, u8 vec) return ret; } } - spin_lock_irqsave(&pm8001_ha->lock, flags); circularQ = &pm8001_ha->outbnd_q_tbl[vec]; + spin_lock_irqsave(&circularQ->oq_lock, flags); do { /* spurious interrupt during setup if kexec-ing and * driver doing a doorbell access w/ the pre-kexec oq @@ -4160,7 +4160,7 @@ static int process_oq(struct pm8001_hba_info *pm8001_ha, u8 vec) break; } } while (1); - spin_unlock_irqrestore(&pm8001_ha->lock, flags); + spin_unlock_irqrestore(&circularQ->oq_lock, flags); return ret; } From 76fc0df9a0e717f7213424a28cbe1263355d8228 Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Thu, 15 Apr 2021 15:08:07 -0700 Subject: [PATCH 393/412] scsi: core: Make the scsi_alloc_sgtables() documentation more accurate The current scsi_alloc_sgtables() documentation does not accurately explain what this function does. Hence improve the documentation of this function. Link: https://lore.kernel.org/r/20210415220826.29438-2-bvanassche@acm.org Cc: Christoph Hellwig Cc: Johannes Thumshirn Cc: Hannes Reinecke Cc: Daniel Wagner Signed-off-by: Bart Van Assche Signed-off-by: Martin K. Petersen --- drivers/scsi/scsi_lib.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c index 4bcd744a5c85..c092b1be38d7 100644 --- a/drivers/scsi/scsi_lib.c +++ b/drivers/scsi/scsi_lib.c @@ -999,8 +999,11 @@ static inline bool scsi_cmd_needs_dma_drain(struct scsi_device *sdev, } /** - * scsi_alloc_sgtables - allocate S/G tables for a command - * @cmd: command descriptor we wish to initialize + * scsi_alloc_sgtables - Allocate and initialize data and integrity scatterlists + * @cmd: SCSI command data structure to initialize. + * + * Initializes @cmd->sdb and also @cmd->prot_sdb if data integrity is enabled + * for @cmd. * * Returns: * * BLK_STS_OK - on success From 886874af943953bc4ee575d828c3e3cc7d1aebe9 Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Thu, 15 Apr 2021 15:08:08 -0700 Subject: [PATCH 394/412] scsi: core: Remove an incorrect comment scsi_device.sdev_target is used in more code than the single_lun code, hence remove the comment next to the definition of the sdev_target member. Link: https://lore.kernel.org/r/20210415220826.29438-3-bvanassche@acm.org Cc: Christoph Hellwig Cc: Johannes Thumshirn Cc: Hannes Reinecke Cc: Daniel Wagner Signed-off-by: Bart Van Assche Signed-off-by: Martin K. Petersen --- include/scsi/scsi_device.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/scsi/scsi_device.h b/include/scsi/scsi_device.h index 05c7c320ef32..ac6ab16abee7 100644 --- a/include/scsi/scsi_device.h +++ b/include/scsi/scsi_device.h @@ -146,7 +146,7 @@ struct scsi_device { struct scsi_vpd __rcu *vpd_pg80; struct scsi_vpd __rcu *vpd_pg89; unsigned char current_tag; /* current tag */ - struct scsi_target *sdev_target; /* used only for single_lun */ + struct scsi_target *sdev_target; blist_flags_t sdev_bflags; /* black/white flags as also found in * scsi_devinfo.[hc]. For now used only to From 0d2810cd62d91bd44f42c87f386c126f6620a43d Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Thu, 15 Apr 2021 15:08:09 -0700 Subject: [PATCH 395/412] scsi: core: Rename scsi_softirq_done() into scsi_complete() Commit 320ae51feed5 ("blk-mq: new multi-queue block IO queueing mechanism"; v3.13) introduced a code path that calls the blk-mq completion function from interrupt context. scsi-mq was introduced by commit d285203cf647 ("scsi: add support for a blk-mq based I/O path."; v3.17). Since the introduction of scsi-mq, scsi_softirq_done() can be called from interrupt context. That made the name of the function misleading, rename it to scsi_complete(). Link: https://lore.kernel.org/r/20210415220826.29438-4-bvanassche@acm.org Cc: Christoph Hellwig Cc: Johannes Thumshirn Cc: Hannes Reinecke Cc: Daniel Wagner Signed-off-by: Bart Van Assche Signed-off-by: Martin K. Petersen --- drivers/scsi/scsi_lib.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c index c092b1be38d7..8ffb789de6f7 100644 --- a/drivers/scsi/scsi_lib.c +++ b/drivers/scsi/scsi_lib.c @@ -1434,7 +1434,11 @@ static bool scsi_mq_lld_busy(struct request_queue *q) return false; } -static void scsi_softirq_done(struct request *rq) +/* + * Block layer request completion callback. May be called from interrupt + * context. + */ +static void scsi_complete(struct request *rq) { struct scsi_cmnd *cmd = blk_mq_rq_to_pdu(rq); int disposition; @@ -1889,7 +1893,7 @@ static const struct blk_mq_ops scsi_mq_ops_no_commit = { .get_budget = scsi_mq_get_budget, .put_budget = scsi_mq_put_budget, .queue_rq = scsi_queue_rq, - .complete = scsi_softirq_done, + .complete = scsi_complete, .timeout = scsi_timeout, #ifdef CONFIG_BLK_DEBUG_FS .show_rq = scsi_show_rq, @@ -1919,7 +1923,7 @@ static const struct blk_mq_ops scsi_mq_ops = { .put_budget = scsi_mq_put_budget, .queue_rq = scsi_queue_rq, .commit_rqs = scsi_commit_rqs, - .complete = scsi_softirq_done, + .complete = scsi_complete, .timeout = scsi_timeout, #ifdef CONFIG_BLK_DEBUG_FS .show_rq = scsi_show_rq, From 280e91b026653af77296b5feb54f16d85973b104 Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Thu, 15 Apr 2021 15:08:10 -0700 Subject: [PATCH 396/412] scsi: core: Modify the scsi_send_eh_cmnd() return value for the SDEV_BLOCK case The comment above scsi_send_eh_cmnd() says: "Returns SUCCESS or FAILED or NEEDS_RETRY". This patch makes all values returned by scsi_send_eh_cmnd() match the documentation of this function. This change does not affect the behavior of scsi_eh_tur() nor of scsi_eh_try_stu() nor of the scsi_request_sense() callers. See also commit bbe9fb0d04b9 ("scsi: Avoid that .queuecommand() gets called for a blocked SCSI device"; v5.3). Link: https://lore.kernel.org/r/20210415220826.29438-5-bvanassche@acm.org Cc: Christoph Hellwig Cc: Johannes Thumshirn Cc: Hannes Reinecke Cc: Daniel Wagner Signed-off-by: Bart Van Assche Signed-off-by: Martin K. Petersen --- drivers/scsi/scsi_error.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/scsi/scsi_error.c b/drivers/scsi/scsi_error.c index 08c06c56331c..271718e888d1 100644 --- a/drivers/scsi/scsi_error.c +++ b/drivers/scsi/scsi_error.c @@ -1109,7 +1109,7 @@ retry: if (sdev->sdev_state != SDEV_BLOCK) rtn = shost->hostt->queuecommand(shost, scmd); else - rtn = SCSI_MLQUEUE_DEVICE_BUSY; + rtn = FAILED; mutex_unlock(&sdev->state_mutex); if (rtn) { From b8e162f9e7e2da6e823a4984d6aa0523e278babf Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Thu, 15 Apr 2021 15:08:11 -0700 Subject: [PATCH 397/412] scsi: core: Introduce enum scsi_disposition Improve readability of the code in the SCSI core by introducing an enumeration type for the values used internally that decide how to continue processing a SCSI command. The eh_*_handler return values have not been changed because that would involve modifying all SCSI drivers. The output of the following command has been inspected to verify that no out-of-range values are assigned to a variable of type enum scsi_disposition: KCFLAGS=-Wassign-enum make CC=clang W=1 drivers/scsi/ Link: https://lore.kernel.org/r/20210415220826.29438-6-bvanassche@acm.org Cc: Christoph Hellwig Cc: Johannes Thumshirn Cc: Hannes Reinecke Cc: Daniel Wagner Signed-off-by: Bart Van Assche Signed-off-by: Martin K. Petersen --- drivers/ata/libata-eh.c | 2 +- drivers/scsi/device_handler/scsi_dh_alua.c | 4 +- drivers/scsi/device_handler/scsi_dh_emc.c | 4 +- drivers/scsi/device_handler/scsi_dh_rdac.c | 4 +- drivers/scsi/scsi_error.c | 64 ++++++++++++---------- drivers/scsi/scsi_lib.c | 2 +- drivers/scsi/scsi_priv.h | 2 +- include/scsi/scsi.h | 21 +++---- include/scsi/scsi_dh.h | 3 +- include/scsi/scsi_eh.h | 2 +- 10 files changed, 57 insertions(+), 51 deletions(-) diff --git a/drivers/ata/libata-eh.c b/drivers/ata/libata-eh.c index b6f92050e60c..5352be2b447d 100644 --- a/drivers/ata/libata-eh.c +++ b/drivers/ata/libata-eh.c @@ -1599,7 +1599,7 @@ static unsigned int ata_eh_analyze_tf(struct ata_queued_cmd *qc, } if (qc->flags & ATA_QCFLAG_SENSE_VALID) { - int ret = scsi_check_sense(qc->scsicmd); + enum scsi_disposition ret = scsi_check_sense(qc->scsicmd); /* * SUCCESS here means that the sense code could be * evaluated and should be passed to the upper layers diff --git a/drivers/scsi/device_handler/scsi_dh_alua.c b/drivers/scsi/device_handler/scsi_dh_alua.c index e6fde27d4565..efa8c0381476 100644 --- a/drivers/scsi/device_handler/scsi_dh_alua.c +++ b/drivers/scsi/device_handler/scsi_dh_alua.c @@ -405,8 +405,8 @@ static char print_alua_state(unsigned char state) } } -static int alua_check_sense(struct scsi_device *sdev, - struct scsi_sense_hdr *sense_hdr) +static enum scsi_disposition alua_check_sense(struct scsi_device *sdev, + struct scsi_sense_hdr *sense_hdr) { struct alua_dh_data *h = sdev->handler_data; struct alua_port_group *pg; diff --git a/drivers/scsi/device_handler/scsi_dh_emc.c b/drivers/scsi/device_handler/scsi_dh_emc.c index caa685cfe3d4..bd28ec6cfb72 100644 --- a/drivers/scsi/device_handler/scsi_dh_emc.c +++ b/drivers/scsi/device_handler/scsi_dh_emc.c @@ -280,8 +280,8 @@ static int send_trespass_cmd(struct scsi_device *sdev, return res; } -static int clariion_check_sense(struct scsi_device *sdev, - struct scsi_sense_hdr *sense_hdr) +static enum scsi_disposition clariion_check_sense(struct scsi_device *sdev, + struct scsi_sense_hdr *sense_hdr) { switch (sense_hdr->sense_key) { case NOT_READY: diff --git a/drivers/scsi/device_handler/scsi_dh_rdac.c b/drivers/scsi/device_handler/scsi_dh_rdac.c index 5efc959493ec..25f6e1ac9e7b 100644 --- a/drivers/scsi/device_handler/scsi_dh_rdac.c +++ b/drivers/scsi/device_handler/scsi_dh_rdac.c @@ -656,8 +656,8 @@ static blk_status_t rdac_prep_fn(struct scsi_device *sdev, struct request *req) return BLK_STS_OK; } -static int rdac_check_sense(struct scsi_device *sdev, - struct scsi_sense_hdr *sense_hdr) +static enum scsi_disposition rdac_check_sense(struct scsi_device *sdev, + struct scsi_sense_hdr *sense_hdr) { struct rdac_dh_data *h = sdev->handler_data; diff --git a/drivers/scsi/scsi_error.c b/drivers/scsi/scsi_error.c index 271718e888d1..d8fafe77dbbe 100644 --- a/drivers/scsi/scsi_error.c +++ b/drivers/scsi/scsi_error.c @@ -60,8 +60,8 @@ static void scsi_eh_done(struct scsi_cmnd *scmd); #define HOST_RESET_SETTLE_TIME (10) static int scsi_eh_try_stu(struct scsi_cmnd *scmd); -static int scsi_try_to_abort_cmd(struct scsi_host_template *, - struct scsi_cmnd *); +static enum scsi_disposition scsi_try_to_abort_cmd(struct scsi_host_template *, + struct scsi_cmnd *); void scsi_eh_wakeup(struct Scsi_Host *shost) { @@ -151,7 +151,7 @@ scmd_eh_abort_handler(struct work_struct *work) struct scsi_cmnd *scmd = container_of(work, struct scsi_cmnd, abort_work.work); struct scsi_device *sdev = scmd->device; - int rtn; + enum scsi_disposition rtn; if (scsi_host_eh_past_deadline(sdev->host)) { SCSI_LOG_ERROR_RECOVERY(3, @@ -498,7 +498,7 @@ static void scsi_report_sense(struct scsi_device *sdev, * When a deferred error is detected the current command has * not been executed and needs retrying. */ -int scsi_check_sense(struct scsi_cmnd *scmd) +enum scsi_disposition scsi_check_sense(struct scsi_cmnd *scmd) { struct scsi_device *sdev = scmd->device; struct scsi_sense_hdr sshdr; @@ -512,7 +512,7 @@ int scsi_check_sense(struct scsi_cmnd *scmd) return NEEDS_RETRY; if (sdev->handler && sdev->handler->check_sense) { - int rc; + enum scsi_disposition rc; rc = sdev->handler->check_sense(sdev, &sshdr); if (rc != SCSI_RETURN_NOT_HANDLED) @@ -723,7 +723,7 @@ static void scsi_handle_queue_full(struct scsi_device *sdev) * don't allow for the possibility of retries here, and we are a lot * more restrictive about what we consider acceptable. */ -static int scsi_eh_completed_normally(struct scsi_cmnd *scmd) +static enum scsi_disposition scsi_eh_completed_normally(struct scsi_cmnd *scmd) { /* * first check the host byte, to see if there is anything in there @@ -804,10 +804,10 @@ static void scsi_eh_done(struct scsi_cmnd *scmd) * scsi_try_host_reset - ask host adapter to reset itself * @scmd: SCSI cmd to send host reset. */ -static int scsi_try_host_reset(struct scsi_cmnd *scmd) +static enum scsi_disposition scsi_try_host_reset(struct scsi_cmnd *scmd) { unsigned long flags; - int rtn; + enum scsi_disposition rtn; struct Scsi_Host *host = scmd->device->host; struct scsi_host_template *hostt = host->hostt; @@ -834,10 +834,10 @@ static int scsi_try_host_reset(struct scsi_cmnd *scmd) * scsi_try_bus_reset - ask host to perform a bus reset * @scmd: SCSI cmd to send bus reset. */ -static int scsi_try_bus_reset(struct scsi_cmnd *scmd) +static enum scsi_disposition scsi_try_bus_reset(struct scsi_cmnd *scmd) { unsigned long flags; - int rtn; + enum scsi_disposition rtn; struct Scsi_Host *host = scmd->device->host; struct scsi_host_template *hostt = host->hostt; @@ -876,10 +876,10 @@ static void __scsi_report_device_reset(struct scsi_device *sdev, void *data) * timer on it, and set the host back to a consistent state prior to * returning. */ -static int scsi_try_target_reset(struct scsi_cmnd *scmd) +static enum scsi_disposition scsi_try_target_reset(struct scsi_cmnd *scmd) { unsigned long flags; - int rtn; + enum scsi_disposition rtn; struct Scsi_Host *host = scmd->device->host; struct scsi_host_template *hostt = host->hostt; @@ -907,9 +907,9 @@ static int scsi_try_target_reset(struct scsi_cmnd *scmd) * timer on it, and set the host back to a consistent state prior to * returning. */ -static int scsi_try_bus_device_reset(struct scsi_cmnd *scmd) +static enum scsi_disposition scsi_try_bus_device_reset(struct scsi_cmnd *scmd) { - int rtn; + enum scsi_disposition rtn; struct scsi_host_template *hostt = scmd->device->host->hostt; if (!hostt->eh_device_reset_handler) @@ -938,8 +938,8 @@ static int scsi_try_bus_device_reset(struct scsi_cmnd *scmd) * if the device is temporarily unavailable (eg due to a * link down on FibreChannel) */ -static int scsi_try_to_abort_cmd(struct scsi_host_template *hostt, - struct scsi_cmnd *scmd) +static enum scsi_disposition +scsi_try_to_abort_cmd(struct scsi_host_template *hostt, struct scsi_cmnd *scmd) { if (!hostt->eh_abort_handler) return FAILED; @@ -1072,8 +1072,8 @@ EXPORT_SYMBOL(scsi_eh_restore_cmnd); * Return value: * SUCCESS or FAILED or NEEDS_RETRY */ -static int scsi_send_eh_cmnd(struct scsi_cmnd *scmd, unsigned char *cmnd, - int cmnd_size, int timeout, unsigned sense_bytes) +static enum scsi_disposition scsi_send_eh_cmnd(struct scsi_cmnd *scmd, + unsigned char *cmnd, int cmnd_size, int timeout, unsigned sense_bytes) { struct scsi_device *sdev = scmd->device; struct Scsi_Host *shost = sdev->host; @@ -1180,12 +1180,13 @@ retry: * that we obtain it on our own. This function will *not* return until * the command either times out, or it completes. */ -static int scsi_request_sense(struct scsi_cmnd *scmd) +static enum scsi_disposition scsi_request_sense(struct scsi_cmnd *scmd) { return scsi_send_eh_cmnd(scmd, NULL, 0, scmd->device->eh_timeout, ~0); } -static int scsi_eh_action(struct scsi_cmnd *scmd, int rtn) +static enum scsi_disposition +scsi_eh_action(struct scsi_cmnd *scmd, enum scsi_disposition rtn) { if (!blk_rq_is_passthrough(scmd->request)) { struct scsi_driver *sdrv = scsi_cmd_to_driver(scmd); @@ -1238,7 +1239,7 @@ int scsi_eh_get_sense(struct list_head *work_q, { struct scsi_cmnd *scmd, *next; struct Scsi_Host *shost; - int rtn; + enum scsi_disposition rtn; /* * If SCSI_EH_ABORT_SCHEDULED has been set, it is timeout IO, @@ -1316,7 +1317,8 @@ EXPORT_SYMBOL_GPL(scsi_eh_get_sense); static int scsi_eh_tur(struct scsi_cmnd *scmd) { static unsigned char tur_command[6] = {TEST_UNIT_READY, 0, 0, 0, 0, 0}; - int retry_cnt = 1, rtn; + int retry_cnt = 1; + enum scsi_disposition rtn; retry_tur: rtn = scsi_send_eh_cmnd(scmd, tur_command, 6, @@ -1404,7 +1406,8 @@ static int scsi_eh_try_stu(struct scsi_cmnd *scmd) static unsigned char stu_command[6] = {START_STOP, 0, 0, 0, 1, 0}; if (scmd->device->allow_restart) { - int i, rtn = NEEDS_RETRY; + int i; + enum scsi_disposition rtn = NEEDS_RETRY; for (i = 0; rtn == NEEDS_RETRY && i < 2; i++) rtn = scsi_send_eh_cmnd(scmd, stu_command, 6, scmd->device->request_queue->rq_timeout, 0); @@ -1498,7 +1501,7 @@ static int scsi_eh_bus_device_reset(struct Scsi_Host *shost, { struct scsi_cmnd *scmd, *bdr_scmd, *next; struct scsi_device *sdev; - int rtn; + enum scsi_disposition rtn; shost_for_each_device(sdev, shost) { if (scsi_host_eh_past_deadline(shost)) { @@ -1565,7 +1568,7 @@ static int scsi_eh_target_reset(struct Scsi_Host *shost, while (!list_empty(&tmp_list)) { struct scsi_cmnd *next, *scmd; - int rtn; + enum scsi_disposition rtn; unsigned int id; if (scsi_host_eh_past_deadline(shost)) { @@ -1623,7 +1626,7 @@ static int scsi_eh_bus_reset(struct Scsi_Host *shost, struct scsi_cmnd *scmd, *chan_scmd, *next; LIST_HEAD(check_list); unsigned int channel; - int rtn; + enum scsi_disposition rtn; /* * we really want to loop over the various channels, and do this on @@ -1694,7 +1697,7 @@ static int scsi_eh_host_reset(struct Scsi_Host *shost, { struct scsi_cmnd *scmd, *next; LIST_HEAD(check_list); - int rtn; + enum scsi_disposition rtn; if (!list_empty(work_q)) { scmd = list_entry(work_q->next, @@ -1800,9 +1803,9 @@ check_type: * doesn't require the error handler read (i.e. we don't need to * abort/reset), this function should return SUCCESS. */ -int scsi_decide_disposition(struct scsi_cmnd *scmd) +enum scsi_disposition scsi_decide_disposition(struct scsi_cmnd *scmd) { - int rtn; + enum scsi_disposition rtn; /* * if the device is offline, then we clearly just pass the result back @@ -2365,7 +2368,8 @@ scsi_ioctl_reset(struct scsi_device *dev, int __user *arg) struct Scsi_Host *shost = dev->host; struct request *rq; unsigned long flags; - int error = 0, rtn, val; + int error = 0, val; + enum scsi_disposition rtn; if (!capable(CAP_SYS_ADMIN) || !capable(CAP_SYS_RAWIO)) return -EACCES; diff --git a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c index 8ffb789de6f7..d7c0d5a5f263 100644 --- a/drivers/scsi/scsi_lib.c +++ b/drivers/scsi/scsi_lib.c @@ -1441,7 +1441,7 @@ static bool scsi_mq_lld_busy(struct request_queue *q) static void scsi_complete(struct request *rq) { struct scsi_cmnd *cmd = blk_mq_rq_to_pdu(rq); - int disposition; + enum scsi_disposition disposition; INIT_LIST_HEAD(&cmd->eh_entry); diff --git a/drivers/scsi/scsi_priv.h b/drivers/scsi/scsi_priv.h index ed240f006c04..75d6f23e4fff 100644 --- a/drivers/scsi/scsi_priv.h +++ b/drivers/scsi/scsi_priv.h @@ -74,7 +74,7 @@ extern void scsi_exit_devinfo(void); extern void scmd_eh_abort_handler(struct work_struct *work); extern enum blk_eh_timer_return scsi_times_out(struct request *req); extern int scsi_error_handler(void *host); -extern int scsi_decide_disposition(struct scsi_cmnd *cmd); +extern enum scsi_disposition scsi_decide_disposition(struct scsi_cmnd *cmd); extern void scsi_eh_wakeup(struct Scsi_Host *shost); extern void scsi_eh_scmd_add(struct scsi_cmnd *); void scsi_eh_ready_devs(struct Scsi_Host *shost, diff --git a/include/scsi/scsi.h b/include/scsi/scsi.h index e75cca25338a..246ced401683 100644 --- a/include/scsi/scsi.h +++ b/include/scsi/scsi.h @@ -180,16 +180,17 @@ static inline int scsi_is_wlun(u64 lun) /* * Internal return values. */ - -#define NEEDS_RETRY 0x2001 -#define SUCCESS 0x2002 -#define FAILED 0x2003 -#define QUEUED 0x2004 -#define SOFT_ERROR 0x2005 -#define ADD_TO_MLQUEUE 0x2006 -#define TIMEOUT_ERROR 0x2007 -#define SCSI_RETURN_NOT_HANDLED 0x2008 -#define FAST_IO_FAIL 0x2009 +enum scsi_disposition { + NEEDS_RETRY = 0x2001, + SUCCESS = 0x2002, + FAILED = 0x2003, + QUEUED = 0x2004, + SOFT_ERROR = 0x2005, + ADD_TO_MLQUEUE = 0x2006, + TIMEOUT_ERROR = 0x2007, + SCSI_RETURN_NOT_HANDLED = 0x2008, + FAST_IO_FAIL = 0x2009, +}; /* * Midlevel queue return values. diff --git a/include/scsi/scsi_dh.h b/include/scsi/scsi_dh.h index a9f782fe732a..4df943c1b90b 100644 --- a/include/scsi/scsi_dh.h +++ b/include/scsi/scsi_dh.h @@ -52,7 +52,8 @@ struct scsi_device_handler { /* Filled by the hardware handler */ struct module *module; const char *name; - int (*check_sense)(struct scsi_device *, struct scsi_sense_hdr *); + enum scsi_disposition (*check_sense)(struct scsi_device *, + struct scsi_sense_hdr *); int (*attach)(struct scsi_device *); void (*detach)(struct scsi_device *); int (*activate)(struct scsi_device *, activate_complete, void *); diff --git a/include/scsi/scsi_eh.h b/include/scsi/scsi_eh.h index 6bd5ed695a5e..468094254b3c 100644 --- a/include/scsi/scsi_eh.h +++ b/include/scsi/scsi_eh.h @@ -17,7 +17,7 @@ extern void scsi_report_device_reset(struct Scsi_Host *, int, int); extern int scsi_block_when_processing_errors(struct scsi_device *); extern bool scsi_command_normalize_sense(const struct scsi_cmnd *cmd, struct scsi_sense_hdr *sshdr); -extern int scsi_check_sense(struct scsi_cmnd *); +extern enum scsi_disposition scsi_check_sense(struct scsi_cmnd *); static inline bool scsi_sense_is_deferred(const struct scsi_sense_hdr *sshdr) { From 56853f0e615bd347daa29b1d7ab165f2bc5ac5f4 Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Thu, 15 Apr 2021 15:08:12 -0700 Subject: [PATCH 398/412] scsi: aacraid: Remove an unused function This was detected by building the kernel with clang and W=1. Link: https://lore.kernel.org/r/20210415220826.29438-7-bvanassche@acm.org Cc: aacraid@microsemi.com Signed-off-by: Bart Van Assche Signed-off-by: Martin K. Petersen --- drivers/scsi/aacraid/aachba.c | 5 ----- 1 file changed, 5 deletions(-) diff --git a/drivers/scsi/aacraid/aachba.c b/drivers/scsi/aacraid/aachba.c index 8e06604370c4..f1f62b5da8b7 100644 --- a/drivers/scsi/aacraid/aachba.c +++ b/drivers/scsi/aacraid/aachba.c @@ -1881,11 +1881,6 @@ static inline u32 aac_get_safw_phys_nexus(struct aac_dev *dev, int lun) return *((u32 *)&dev->safw_phys_luns->lun[lun].node_ident[12]); } -static inline u32 aac_get_safw_phys_device_type(struct aac_dev *dev, int lun) -{ - return dev->safw_phys_luns->lun[lun].node_ident[8]; -} - static inline void aac_free_safw_identify_resp(struct aac_dev *dev, int bus, int target) { From 90d6697810f06aceea9de71ad836a8c7669789cd Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Thu, 15 Apr 2021 15:08:13 -0700 Subject: [PATCH 399/412] scsi: libfc: Fix a format specifier Since the 'mfs' member has been declared as 'u32' in include/scsi/libfc.h, use the %u format specifier instead of %hu. This patch fixes the following clang compiler warning: warning: format specifies type 'unsigned short' but the argument has type 'u32' (aka 'unsigned int') [-Wformat] "lport->mfs:%hu\n", mfs, lport->mfs); ~~~ ^~~~~~~~~~ %u Link: https://lore.kernel.org/r/20210415220826.29438-8-bvanassche@acm.org Cc: Hannes Reinecke Signed-off-by: Bart Van Assche Signed-off-by: Martin K. Petersen --- drivers/scsi/libfc/fc_lport.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/scsi/libfc/fc_lport.c b/drivers/scsi/libfc/fc_lport.c index 78bd317f0553..cf36c8cb5493 100644 --- a/drivers/scsi/libfc/fc_lport.c +++ b/drivers/scsi/libfc/fc_lport.c @@ -1731,7 +1731,7 @@ void fc_lport_flogi_resp(struct fc_seq *sp, struct fc_frame *fp, if (mfs < FC_SP_MIN_MAX_PAYLOAD || mfs > FC_SP_MAX_MAX_PAYLOAD) { FC_LPORT_DBG(lport, "FLOGI bad mfs:%hu response, " - "lport->mfs:%hu\n", mfs, lport->mfs); + "lport->mfs:%u\n", mfs, lport->mfs); fc_lport_error(lport, fp); goto out; } From be5aeee30e45678668a6314a9a2dc1d3b2562818 Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Thu, 15 Apr 2021 15:08:14 -0700 Subject: [PATCH 400/412] scsi: fcoe: Suppress a compiler warning Suppress the following compiler warning: warning: cast to smaller integer type 'enum fip_mode' from 'void *' [-Wvoid-pointer-to-enum-cast] enum fip_mode fip_mode = (enum fip_mode)kp->arg; ^~~~~~~~~~~~~~~~~~~~~~ Link: https://lore.kernel.org/r/20210415220826.29438-9-bvanassche@acm.org Cc: Hannes Reinecke Signed-off-by: Bart Van Assche Signed-off-by: Martin K. Petersen --- drivers/scsi/fcoe/fcoe_transport.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/scsi/fcoe/fcoe_transport.c b/drivers/scsi/fcoe/fcoe_transport.c index b927b3d84523..4d0e19e7c84b 100644 --- a/drivers/scsi/fcoe/fcoe_transport.c +++ b/drivers/scsi/fcoe/fcoe_transport.c @@ -863,7 +863,7 @@ static int fcoe_transport_create(const char *buffer, int rc = -ENODEV; struct net_device *netdev = NULL; struct fcoe_transport *ft = NULL; - enum fip_mode fip_mode = (enum fip_mode)kp->arg; + enum fip_mode fip_mode = (enum fip_mode)(uintptr_t)kp->arg; mutex_lock(&ft_mutex); From 3ad0b1da0da2e073b1c9d2e317a5ebf7704f98e6 Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Thu, 15 Apr 2021 15:08:15 -0700 Subject: [PATCH 401/412] scsi: mpt3sas: Fix two kernel-doc headers Fix the following warnings: drivers/scsi/mpt3sas/mpt3sas_base.c:5430: warning: Excess function parameter 'ct' description in '_base_allocate_pcie_sgl_pool' drivers/scsi/mpt3sas/mpt3sas_base.c:5493: warning: Excess function parameter 'ctr' description in '_base_allocate_chain_dma_pool' Link: https://lore.kernel.org/r/20210415220826.29438-10-bvanassche@acm.org Fixes: d6adc251dd2f ("scsi: mpt3sas: Force PCIe scatterlist allocations to be within same 4 GB region") Fixes: 7dd847dae1c4 ("scsi: mpt3sas: Force chain buffer allocations to be within same 4 GB region") Cc: Sathya Prakash Cc: Sreekanth Reddy Cc: Suganath Prabu Subramani Signed-off-by: Bart Van Assche Signed-off-by: Martin K. Petersen --- drivers/scsi/mpt3sas/mpt3sas_base.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/scsi/mpt3sas/mpt3sas_base.c b/drivers/scsi/mpt3sas/mpt3sas_base.c index 84c507587166..5779f313f6f8 100644 --- a/drivers/scsi/mpt3sas/mpt3sas_base.c +++ b/drivers/scsi/mpt3sas/mpt3sas_base.c @@ -5421,7 +5421,7 @@ _base_reduce_hba_queue_depth(struct MPT3SAS_ADAPTER *ioc) * for pcie sgl pools. * @ioc: Adapter object * @sz: DMA Pool size - * @ct: Chain tracker + * * Return: 0 for success, non-zero for failure. */ @@ -5485,7 +5485,7 @@ _base_allocate_pcie_sgl_pool(struct MPT3SAS_ADAPTER *ioc, u32 sz) * for chain dma pool. * @ioc: Adapter object * @sz: DMA Pool size - * @ctr: Chain tracker + * * Return: 0 for success, non-zero for failure. */ static int From 3690ad6708c5bfbbf4c5dbb0cd7a0877580d62a6 Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Thu, 15 Apr 2021 15:08:16 -0700 Subject: [PATCH 402/412] scsi: myrb: Remove unused functions This was detected by building the kernel with clang and W=1. Link: https://lore.kernel.org/r/20210415220826.29438-11-bvanassche@acm.org Cc: Hannes Reinecke Signed-off-by: Bart Van Assche Signed-off-by: Martin K. Petersen --- drivers/scsi/myrb.c | 71 --------------------------------------------- 1 file changed, 71 deletions(-) diff --git a/drivers/scsi/myrb.c b/drivers/scsi/myrb.c index 56767f8610d4..d9c82e211ae7 100644 --- a/drivers/scsi/myrb.c +++ b/drivers/scsi/myrb.c @@ -2552,11 +2552,6 @@ static inline void DAC960_LA_ack_hw_mbox_status(void __iomem *base) writeb(DAC960_LA_IDB_HWMBOX_ACK_STS, base + DAC960_LA_IDB_OFFSET); } -static inline void DAC960_LA_gen_intr(void __iomem *base) -{ - writeb(DAC960_LA_IDB_GEN_IRQ, base + DAC960_LA_IDB_OFFSET); -} - static inline void DAC960_LA_reset_ctrl(void __iomem *base) { writeb(DAC960_LA_IDB_CTRL_RESET, base + DAC960_LA_IDB_OFFSET); @@ -2586,11 +2581,6 @@ static inline void DAC960_LA_ack_hw_mbox_intr(void __iomem *base) writeb(DAC960_LA_ODB_HWMBOX_ACK_IRQ, base + DAC960_LA_ODB_OFFSET); } -static inline void DAC960_LA_ack_mem_mbox_intr(void __iomem *base) -{ - writeb(DAC960_LA_ODB_MMBOX_ACK_IRQ, base + DAC960_LA_ODB_OFFSET); -} - static inline void DAC960_LA_ack_intr(void __iomem *base) { writeb(DAC960_LA_ODB_HWMBOX_ACK_IRQ | DAC960_LA_ODB_MMBOX_ACK_IRQ, @@ -2604,13 +2594,6 @@ static inline bool DAC960_LA_hw_mbox_status_available(void __iomem *base) return odb & DAC960_LA_ODB_HWMBOX_STS_AVAIL; } -static inline bool DAC960_LA_mem_mbox_status_available(void __iomem *base) -{ - unsigned char odb = readb(base + DAC960_LA_ODB_OFFSET); - - return odb & DAC960_LA_ODB_MMBOX_STS_AVAIL; -} - static inline void DAC960_LA_enable_intr(void __iomem *base) { unsigned char odb = 0xFF; @@ -2627,13 +2610,6 @@ static inline void DAC960_LA_disable_intr(void __iomem *base) writeb(odb, base + DAC960_LA_IRQMASK_OFFSET); } -static inline bool DAC960_LA_intr_enabled(void __iomem *base) -{ - unsigned char imask = readb(base + DAC960_LA_IRQMASK_OFFSET); - - return !(imask & DAC960_LA_IRQMASK_DISABLE_IRQ); -} - static inline void DAC960_LA_write_cmd_mbox(union myrb_cmd_mbox *mem_mbox, union myrb_cmd_mbox *mbox) { @@ -2656,11 +2632,6 @@ static inline void DAC960_LA_write_hw_mbox(void __iomem *base, writeb(mbox->bytes[12], base + DAC960_LA_MBOX12_OFFSET); } -static inline unsigned char DAC960_LA_read_status_cmd_ident(void __iomem *base) -{ - return readb(base + DAC960_LA_STSID_OFFSET); -} - static inline unsigned short DAC960_LA_read_status(void __iomem *base) { return readw(base + DAC960_LA_STS_OFFSET); @@ -2828,11 +2799,6 @@ static inline void DAC960_PG_ack_hw_mbox_status(void __iomem *base) writel(DAC960_PG_IDB_HWMBOX_ACK_STS, base + DAC960_PG_IDB_OFFSET); } -static inline void DAC960_PG_gen_intr(void __iomem *base) -{ - writel(DAC960_PG_IDB_GEN_IRQ, base + DAC960_PG_IDB_OFFSET); -} - static inline void DAC960_PG_reset_ctrl(void __iomem *base) { writel(DAC960_PG_IDB_CTRL_RESET, base + DAC960_PG_IDB_OFFSET); @@ -2862,11 +2828,6 @@ static inline void DAC960_PG_ack_hw_mbox_intr(void __iomem *base) writel(DAC960_PG_ODB_HWMBOX_ACK_IRQ, base + DAC960_PG_ODB_OFFSET); } -static inline void DAC960_PG_ack_mem_mbox_intr(void __iomem *base) -{ - writel(DAC960_PG_ODB_MMBOX_ACK_IRQ, base + DAC960_PG_ODB_OFFSET); -} - static inline void DAC960_PG_ack_intr(void __iomem *base) { writel(DAC960_PG_ODB_HWMBOX_ACK_IRQ | DAC960_PG_ODB_MMBOX_ACK_IRQ, @@ -2880,13 +2841,6 @@ static inline bool DAC960_PG_hw_mbox_status_available(void __iomem *base) return odb & DAC960_PG_ODB_HWMBOX_STS_AVAIL; } -static inline bool DAC960_PG_mem_mbox_status_available(void __iomem *base) -{ - unsigned char odb = readl(base + DAC960_PG_ODB_OFFSET); - - return odb & DAC960_PG_ODB_MMBOX_STS_AVAIL; -} - static inline void DAC960_PG_enable_intr(void __iomem *base) { unsigned int imask = (unsigned int)-1; @@ -2902,13 +2856,6 @@ static inline void DAC960_PG_disable_intr(void __iomem *base) writel(imask, base + DAC960_PG_IRQMASK_OFFSET); } -static inline bool DAC960_PG_intr_enabled(void __iomem *base) -{ - unsigned int imask = readl(base + DAC960_PG_IRQMASK_OFFSET); - - return !(imask & DAC960_PG_IRQMASK_DISABLE_IRQ); -} - static inline void DAC960_PG_write_cmd_mbox(union myrb_cmd_mbox *mem_mbox, union myrb_cmd_mbox *mbox) { @@ -2931,12 +2878,6 @@ static inline void DAC960_PG_write_hw_mbox(void __iomem *base, writeb(mbox->bytes[12], base + DAC960_PG_MBOX12_OFFSET); } -static inline unsigned char -DAC960_PG_read_status_cmd_ident(void __iomem *base) -{ - return readb(base + DAC960_PG_STSID_OFFSET); -} - static inline unsigned short DAC960_PG_read_status(void __iomem *base) { @@ -3106,11 +3047,6 @@ static inline void DAC960_PD_ack_hw_mbox_status(void __iomem *base) writeb(DAC960_PD_IDB_HWMBOX_ACK_STS, base + DAC960_PD_IDB_OFFSET); } -static inline void DAC960_PD_gen_intr(void __iomem *base) -{ - writeb(DAC960_PD_IDB_GEN_IRQ, base + DAC960_PD_IDB_OFFSET); -} - static inline void DAC960_PD_reset_ctrl(void __iomem *base) { writeb(DAC960_PD_IDB_CTRL_RESET, base + DAC960_PD_IDB_OFFSET); @@ -3152,13 +3088,6 @@ static inline void DAC960_PD_disable_intr(void __iomem *base) writeb(0, base + DAC960_PD_IRQEN_OFFSET); } -static inline bool DAC960_PD_intr_enabled(void __iomem *base) -{ - unsigned char imask = readb(base + DAC960_PD_IRQEN_OFFSET); - - return imask & DAC960_PD_IRQMASK_ENABLE_IRQ; -} - static inline void DAC960_PD_write_cmd_mbox(void __iomem *base, union myrb_cmd_mbox *mbox) { From 40d1373b604794e1c3b496f5415ef2e3a9074ca8 Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Thu, 15 Apr 2021 15:08:17 -0700 Subject: [PATCH 403/412] scsi: myrs: Remove unused functions This was detected by building the kernel with clang and W=1. Link: https://lore.kernel.org/r/20210415220826.29438-12-bvanassche@acm.org Cc: Hannes Reinecke Signed-off-by: Bart Van Assche Signed-off-by: Martin K. Petersen --- drivers/scsi/myrs.c | 99 --------------------------------------------- 1 file changed, 99 deletions(-) diff --git a/drivers/scsi/myrs.c b/drivers/scsi/myrs.c index d5ec1cdea0e1..3b68c68d1716 100644 --- a/drivers/scsi/myrs.c +++ b/drivers/scsi/myrs.c @@ -2410,13 +2410,6 @@ static inline void DAC960_GEM_ack_hw_mbox_status(void __iomem *base) writel(val, base + DAC960_GEM_IDB_CLEAR_OFFSET); } -static inline void DAC960_GEM_gen_intr(void __iomem *base) -{ - __le32 val = cpu_to_le32(DAC960_GEM_IDB_GEN_IRQ << 24); - - writel(val, base + DAC960_GEM_IDB_READ_OFFSET); -} - static inline void DAC960_GEM_reset_ctrl(void __iomem *base) { __le32 val = cpu_to_le32(DAC960_GEM_IDB_CTRL_RESET << 24); @@ -2454,13 +2447,6 @@ static inline void DAC960_GEM_ack_hw_mbox_intr(void __iomem *base) writel(val, base + DAC960_GEM_ODB_CLEAR_OFFSET); } -static inline void DAC960_GEM_ack_mem_mbox_intr(void __iomem *base) -{ - __le32 val = cpu_to_le32(DAC960_GEM_ODB_MMBOX_ACK_IRQ << 24); - - writel(val, base + DAC960_GEM_ODB_CLEAR_OFFSET); -} - static inline void DAC960_GEM_ack_intr(void __iomem *base) { __le32 val = cpu_to_le32((DAC960_GEM_ODB_HWMBOX_ACK_IRQ | @@ -2477,14 +2463,6 @@ static inline bool DAC960_GEM_hw_mbox_status_available(void __iomem *base) return (le32_to_cpu(val) >> 24) & DAC960_GEM_ODB_HWMBOX_STS_AVAIL; } -static inline bool DAC960_GEM_mem_mbox_status_available(void __iomem *base) -{ - __le32 val; - - val = readl(base + DAC960_GEM_ODB_READ_OFFSET); - return (le32_to_cpu(val) >> 24) & DAC960_GEM_ODB_MMBOX_STS_AVAIL; -} - static inline void DAC960_GEM_enable_intr(void __iomem *base) { __le32 val = cpu_to_le32((DAC960_GEM_IRQMASK_HWMBOX_IRQ | @@ -2499,16 +2477,6 @@ static inline void DAC960_GEM_disable_intr(void __iomem *base) writel(val, base + DAC960_GEM_IRQMASK_READ_OFFSET); } -static inline bool DAC960_GEM_intr_enabled(void __iomem *base) -{ - __le32 val; - - val = readl(base + DAC960_GEM_IRQMASK_READ_OFFSET); - return !((le32_to_cpu(val) >> 24) & - (DAC960_GEM_IRQMASK_HWMBOX_IRQ | - DAC960_GEM_IRQMASK_MMBOX_IRQ)); -} - static inline void DAC960_GEM_write_cmd_mbox(union myrs_cmd_mbox *mem_mbox, union myrs_cmd_mbox *mbox) { @@ -2527,11 +2495,6 @@ static inline void DAC960_GEM_write_hw_mbox(void __iomem *base, dma_addr_writeql(cmd_mbox_addr, base + DAC960_GEM_CMDMBX_OFFSET); } -static inline unsigned short DAC960_GEM_read_cmd_ident(void __iomem *base) -{ - return readw(base + DAC960_GEM_CMDSTS_OFFSET); -} - static inline unsigned char DAC960_GEM_read_cmd_status(void __iomem *base) { return readw(base + DAC960_GEM_CMDSTS_OFFSET + 2); @@ -2676,11 +2639,6 @@ static inline void DAC960_BA_ack_hw_mbox_status(void __iomem *base) writeb(DAC960_BA_IDB_HWMBOX_ACK_STS, base + DAC960_BA_IDB_OFFSET); } -static inline void DAC960_BA_gen_intr(void __iomem *base) -{ - writeb(DAC960_BA_IDB_GEN_IRQ, base + DAC960_BA_IDB_OFFSET); -} - static inline void DAC960_BA_reset_ctrl(void __iomem *base) { writeb(DAC960_BA_IDB_CTRL_RESET, base + DAC960_BA_IDB_OFFSET); @@ -2712,11 +2670,6 @@ static inline void DAC960_BA_ack_hw_mbox_intr(void __iomem *base) writeb(DAC960_BA_ODB_HWMBOX_ACK_IRQ, base + DAC960_BA_ODB_OFFSET); } -static inline void DAC960_BA_ack_mem_mbox_intr(void __iomem *base) -{ - writeb(DAC960_BA_ODB_MMBOX_ACK_IRQ, base + DAC960_BA_ODB_OFFSET); -} - static inline void DAC960_BA_ack_intr(void __iomem *base) { writeb(DAC960_BA_ODB_HWMBOX_ACK_IRQ | DAC960_BA_ODB_MMBOX_ACK_IRQ, @@ -2731,14 +2684,6 @@ static inline bool DAC960_BA_hw_mbox_status_available(void __iomem *base) return val & DAC960_BA_ODB_HWMBOX_STS_AVAIL; } -static inline bool DAC960_BA_mem_mbox_status_available(void __iomem *base) -{ - u8 val; - - val = readb(base + DAC960_BA_ODB_OFFSET); - return val & DAC960_BA_ODB_MMBOX_STS_AVAIL; -} - static inline void DAC960_BA_enable_intr(void __iomem *base) { writeb(~DAC960_BA_IRQMASK_DISABLE_IRQ, base + DAC960_BA_IRQMASK_OFFSET); @@ -2749,14 +2694,6 @@ static inline void DAC960_BA_disable_intr(void __iomem *base) writeb(0xFF, base + DAC960_BA_IRQMASK_OFFSET); } -static inline bool DAC960_BA_intr_enabled(void __iomem *base) -{ - u8 val; - - val = readb(base + DAC960_BA_IRQMASK_OFFSET); - return !(val & DAC960_BA_IRQMASK_DISABLE_IRQ); -} - static inline void DAC960_BA_write_cmd_mbox(union myrs_cmd_mbox *mem_mbox, union myrs_cmd_mbox *mbox) { @@ -2776,11 +2713,6 @@ static inline void DAC960_BA_write_hw_mbox(void __iomem *base, dma_addr_writeql(cmd_mbox_addr, base + DAC960_BA_CMDMBX_OFFSET); } -static inline unsigned short DAC960_BA_read_cmd_ident(void __iomem *base) -{ - return readw(base + DAC960_BA_CMDSTS_OFFSET); -} - static inline unsigned char DAC960_BA_read_cmd_status(void __iomem *base) { return readw(base + DAC960_BA_CMDSTS_OFFSET + 2); @@ -2926,11 +2858,6 @@ static inline void DAC960_LP_ack_hw_mbox_status(void __iomem *base) writeb(DAC960_LP_IDB_HWMBOX_ACK_STS, base + DAC960_LP_IDB_OFFSET); } -static inline void DAC960_LP_gen_intr(void __iomem *base) -{ - writeb(DAC960_LP_IDB_GEN_IRQ, base + DAC960_LP_IDB_OFFSET); -} - static inline void DAC960_LP_reset_ctrl(void __iomem *base) { writeb(DAC960_LP_IDB_CTRL_RESET, base + DAC960_LP_IDB_OFFSET); @@ -2962,11 +2889,6 @@ static inline void DAC960_LP_ack_hw_mbox_intr(void __iomem *base) writeb(DAC960_LP_ODB_HWMBOX_ACK_IRQ, base + DAC960_LP_ODB_OFFSET); } -static inline void DAC960_LP_ack_mem_mbox_intr(void __iomem *base) -{ - writeb(DAC960_LP_ODB_MMBOX_ACK_IRQ, base + DAC960_LP_ODB_OFFSET); -} - static inline void DAC960_LP_ack_intr(void __iomem *base) { writeb(DAC960_LP_ODB_HWMBOX_ACK_IRQ | DAC960_LP_ODB_MMBOX_ACK_IRQ, @@ -2981,14 +2903,6 @@ static inline bool DAC960_LP_hw_mbox_status_available(void __iomem *base) return val & DAC960_LP_ODB_HWMBOX_STS_AVAIL; } -static inline bool DAC960_LP_mem_mbox_status_available(void __iomem *base) -{ - u8 val; - - val = readb(base + DAC960_LP_ODB_OFFSET); - return val & DAC960_LP_ODB_MMBOX_STS_AVAIL; -} - static inline void DAC960_LP_enable_intr(void __iomem *base) { writeb(~DAC960_LP_IRQMASK_DISABLE_IRQ, base + DAC960_LP_IRQMASK_OFFSET); @@ -2999,14 +2913,6 @@ static inline void DAC960_LP_disable_intr(void __iomem *base) writeb(0xFF, base + DAC960_LP_IRQMASK_OFFSET); } -static inline bool DAC960_LP_intr_enabled(void __iomem *base) -{ - u8 val; - - val = readb(base + DAC960_LP_IRQMASK_OFFSET); - return !(val & DAC960_LP_IRQMASK_DISABLE_IRQ); -} - static inline void DAC960_LP_write_cmd_mbox(union myrs_cmd_mbox *mem_mbox, union myrs_cmd_mbox *mbox) { @@ -3025,11 +2931,6 @@ static inline void DAC960_LP_write_hw_mbox(void __iomem *base, dma_addr_writeql(cmd_mbox_addr, base + DAC960_LP_CMDMBX_OFFSET); } -static inline unsigned short DAC960_LP_read_cmd_ident(void __iomem *base) -{ - return readw(base + DAC960_LP_CMDSTS_OFFSET); -} - static inline unsigned char DAC960_LP_read_cmd_status(void __iomem *base) { return readw(base + DAC960_LP_CMDSTS_OFFSET + 2); From 11417cd5e2ec4a07a573586c15134a08ff56909a Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Thu, 15 Apr 2021 15:08:18 -0700 Subject: [PATCH 404/412] scsi: qla4xxx: Remove an unused function This was detected by building the kernel with clang and W=1. Link: https://lore.kernel.org/r/20210415220826.29438-13-bvanassche@acm.org Cc: Nilesh Javali Acked-by: Manish Rangankar Signed-off-by: Bart Van Assche Signed-off-by: Martin K. Petersen --- drivers/scsi/qla4xxx/ql4_nx.c | 6 ------ 1 file changed, 6 deletions(-) diff --git a/drivers/scsi/qla4xxx/ql4_nx.c b/drivers/scsi/qla4xxx/ql4_nx.c index e6e35e6958f6..66a487795c53 100644 --- a/drivers/scsi/qla4xxx/ql4_nx.c +++ b/drivers/scsi/qla4xxx/ql4_nx.c @@ -3634,12 +3634,6 @@ flash_conf_addr(struct ql82xx_hw_data *hw, uint32_t faddr) return hw->flash_conf_off | faddr; } -static inline uint32_t -flash_data_addr(struct ql82xx_hw_data *hw, uint32_t faddr) -{ - return hw->flash_data_off | faddr; -} - static uint32_t * qla4_82xx_read_flash_data(struct scsi_qla_host *ha, uint32_t *dwptr, uint32_t faddr, uint32_t length) From c64aab41c5e15063de41b15c0f1e301aef59ae2f Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Thu, 15 Apr 2021 15:08:19 -0700 Subject: [PATCH 405/412] scsi: smartpqi: Remove unused functions This was detected by building the kernel with clang and W=1. Link: https://lore.kernel.org/r/20210415220826.29438-14-bvanassche@acm.org Cc: Don Brace Signed-off-by: Bart Van Assche Signed-off-by: Martin K. Petersen --- drivers/scsi/smartpqi/smartpqi_init.c | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/drivers/scsi/smartpqi/smartpqi_init.c b/drivers/scsi/smartpqi/smartpqi_init.c index 797ac699b7ff..25c0409e98df 100644 --- a/drivers/scsi/smartpqi/smartpqi_init.c +++ b/drivers/scsi/smartpqi/smartpqi_init.c @@ -443,11 +443,6 @@ static inline void pqi_cancel_rescan_worker(struct pqi_ctrl_info *ctrl_info) cancel_delayed_work_sync(&ctrl_info->rescan_work); } -static inline void pqi_cancel_event_worker(struct pqi_ctrl_info *ctrl_info) -{ - cancel_work_sync(&ctrl_info->event_work); -} - static inline u32 pqi_read_heartbeat_counter(struct pqi_ctrl_info *ctrl_info) { if (!ctrl_info->heartbeat_counter) @@ -4832,11 +4827,6 @@ static inline int pqi_enable_events(struct pqi_ctrl_info *ctrl_info) return pqi_configure_events(ctrl_info, true); } -static inline int pqi_disable_events(struct pqi_ctrl_info *ctrl_info) -{ - return pqi_configure_events(ctrl_info, false); -} - static void pqi_free_all_io_requests(struct pqi_ctrl_info *ctrl_info) { unsigned int i; From 3940ebf7ba52a82db2aae16a3aa00835d7a98109 Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Thu, 15 Apr 2021 15:08:20 -0700 Subject: [PATCH 406/412] scsi: 53c700: Open-code status_byte(u8) calls The 53c700 driver is one of the two drivers that passes an u8 argument to status_byte() instead of an s32 argument. Open-code status_byte in preparation of changing SCSI status values into a structure. Link: https://lore.kernel.org/r/20210415220826.29438-15-bvanassche@acm.org Cc: "James E.J. Bottomley" Signed-off-by: Bart Van Assche Signed-off-by: Martin K. Petersen --- drivers/scsi/53c700.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/scsi/53c700.c b/drivers/scsi/53c700.c index 4fd91f81244d..ab42feab233f 100644 --- a/drivers/scsi/53c700.c +++ b/drivers/scsi/53c700.c @@ -981,8 +981,8 @@ process_script_interrupt(__u32 dsps, __u32 dsp, struct scsi_cmnd *SCp, NCR_700_FINISHED_TAG_NEGOTIATION); /* check for contingent allegiance conditions */ - if(status_byte(hostdata->status[0]) == CHECK_CONDITION || - status_byte(hostdata->status[0]) == COMMAND_TERMINATED) { + if (hostdata->status[0] >> 1 == CHECK_CONDITION || + hostdata->status[0] >> 1 == COMMAND_TERMINATED) { struct NCR_700_command_slot *slot = (struct NCR_700_command_slot *)SCp->host_scribble; if(slot->flags == NCR_700_FLAG_AUTOSENSE) { From 22dc227e8f0e913d86552f5714fccb0e622ec650 Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Thu, 15 Apr 2021 15:08:21 -0700 Subject: [PATCH 407/412] scsi: dc395x: Open-code status_byte(u8) calls The dc395x driver is one of the two drivers that passes an u8 argument to status_byte() instead of an s32 argument. Open-code status_byte() in preparation of changing SCSI status values into a structure. Link: https://lore.kernel.org/r/20210415220826.29438-16-bvanassche@acm.org Cc: Hannes Reinecke Signed-off-by: Bart Van Assche Signed-off-by: Martin K. Petersen --- drivers/scsi/dc395x.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/scsi/dc395x.c b/drivers/scsi/dc395x.c index 1e9ec4d8c605..be87d5a7583d 100644 --- a/drivers/scsi/dc395x.c +++ b/drivers/scsi/dc395x.c @@ -3258,10 +3258,10 @@ static void srb_done(struct AdapterCtlBlk *acb, struct DeviceCtlBlk *dcb, /* * target status.......................... */ - if (status_byte(status) == CHECK_CONDITION) { + if (status >> 1 == CHECK_CONDITION) { request_sense(acb, dcb, srb); return; - } else if (status_byte(status) == QUEUE_FULL) { + } else if (status >> 1 == QUEUE_FULL) { tempcnt = (u8)list_size(&dcb->srb_going_list); dprintkl(KERN_INFO, "QUEUE_FULL for dev <%02i-%i> with %i cmnds\n", dcb->target_id, dcb->target_lun, tempcnt); From 41e70e3006f63b89ae3b0d49557ac9f620bac524 Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Thu, 15 Apr 2021 15:08:22 -0700 Subject: [PATCH 408/412] scsi: sd: Introduce a new local variable in sd_check_events() Instead of using 'retval' to represent first a SCSI status and later whether or not a disk change event occurred, introduce a new variable for the latter purpose. Link: https://lore.kernel.org/r/20210415220826.29438-17-bvanassche@acm.org Cc: Christoph Hellwig Cc: Johannes Thumshirn Cc: Hannes Reinecke Cc: Daniel Wagner Signed-off-by: Bart Van Assche Signed-off-by: Martin K. Petersen --- drivers/scsi/sd.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c index 91c34ee972c7..cb3c37d1e009 100644 --- a/drivers/scsi/sd.c +++ b/drivers/scsi/sd.c @@ -1623,6 +1623,7 @@ static unsigned int sd_check_events(struct gendisk *disk, unsigned int clearing) struct scsi_disk *sdkp = scsi_disk_get(disk); struct scsi_device *sdp; int retval; + bool disk_changed; if (!sdkp) return 0; @@ -1680,10 +1681,10 @@ out: * Medium present state has changed in either direction. * Device has indicated UNIT_ATTENTION. */ - retval = sdp->changed ? DISK_EVENT_MEDIA_CHANGE : 0; + disk_changed = sdp->changed; sdp->changed = 0; scsi_disk_put(sdkp); - return retval; + return disk_changed ? DISK_EVENT_MEDIA_CHANGE : 0; } static int sd_sync_cache(struct scsi_disk *sdkp, struct scsi_sense_hdr *sshdr) From 15df85e0d63d870e67fbd39c416f1d9815a107d0 Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Thu, 15 Apr 2021 15:08:23 -0700 Subject: [PATCH 409/412] scsi: target: Compare explicitly with SAM_STAT_GOOD Instead of leaving it implicit that SAM_STAT_GOOD == 0, compare explicitly with SAM_STAT_GOOD. Link: https://lore.kernel.org/r/20210415220826.29438-18-bvanassche@acm.org Reviewed-by: Mike Christie Signed-off-by: Bart Van Assche Signed-off-by: Martin K. Petersen --- drivers/target/target_core_pscsi.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/target/target_core_pscsi.c b/drivers/target/target_core_pscsi.c index 1c9aeab93477..dac44caf77a3 100644 --- a/drivers/target/target_core_pscsi.c +++ b/drivers/target/target_core_pscsi.c @@ -1046,7 +1046,7 @@ static void pscsi_req_done(struct request *req, blk_status_t status) int result = scsi_req(req)->result; u8 scsi_status = status_byte(result) << 1; - if (scsi_status) { + if (scsi_status != SAM_STAT_GOOD) { pr_debug("PSCSI Status Byte exception at cmd: %p CDB:" " 0x%02x Result: 0x%08x\n", cmd, pt->pscsi_cdb[0], result); From e15c745295a22470b663b101f5130d29e16fbde3 Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Thu, 15 Apr 2021 15:08:24 -0700 Subject: [PATCH 410/412] scsi: target: Fix two format specifiers Use format specifier '%u' to format the u32 data type instead of '%hu'. Link: https://lore.kernel.org/r/20210415220826.29438-19-bvanassche@acm.org Cc: Mike Christie Reviewed-by: Mike Christie Signed-off-by: Bart Van Assche Signed-off-by: Martin K. Petersen --- drivers/target/target_core_pr.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/drivers/target/target_core_pr.c b/drivers/target/target_core_pr.c index d61dc166bc5f..6fd5fec95539 100644 --- a/drivers/target/target_core_pr.c +++ b/drivers/target/target_core_pr.c @@ -1637,8 +1637,7 @@ core_scsi3_decode_spec_i_port( } dest_tpg = tmp_tpg; - pr_debug("SPC-3 PR SPEC_I_PT: Located %s Node:" - " %s Port RTPI: %hu\n", + pr_debug("SPC-3 PR SPEC_I_PT: Located %s Node: %s Port RTPI: %u\n", dest_tpg->se_tpg_tfo->fabric_name, dest_node_acl->initiatorname, dest_rtpi); @@ -1675,8 +1674,7 @@ core_scsi3_decode_spec_i_port( dest_se_deve = core_get_se_deve_from_rtpi(dest_node_acl, dest_rtpi); if (!dest_se_deve) { - pr_err("Unable to locate %s dest_se_deve" - " from destination RTPI: %hu\n", + pr_err("Unable to locate %s dest_se_deve from destination RTPI: %u\n", dest_tpg->se_tpg_tfo->fabric_name, dest_rtpi); From baa75afde8cb53f15d166acae2a675a1f33c0a61 Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Thu, 15 Apr 2021 15:08:25 -0700 Subject: [PATCH 411/412] scsi: target: Shorten ALUA error messages Do not print tg_pt_gp->tg_pt_gp_valid_id if we already know that it is zero. Link: https://lore.kernel.org/r/20210415220826.29438-20-bvanassche@acm.org Cc: Mike Christie Reviewed-by: Mike Christie Signed-off-by: Bart Van Assche Signed-off-by: Martin K. Petersen --- drivers/target/target_core_configfs.c | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) diff --git a/drivers/target/target_core_configfs.c b/drivers/target/target_core_configfs.c index 9cb1ca8421c8..4b2e49341ad6 100644 --- a/drivers/target/target_core_configfs.c +++ b/drivers/target/target_core_configfs.c @@ -2745,8 +2745,7 @@ static ssize_t target_tg_pt_gp_alua_access_state_store(struct config_item *item, int new_state, ret; if (!tg_pt_gp->tg_pt_gp_valid_id) { - pr_err("Unable to do implicit ALUA on non valid" - " tg_pt_gp ID: %hu\n", tg_pt_gp->tg_pt_gp_valid_id); + pr_err("Unable to do implicit ALUA on invalid tg_pt_gp ID\n"); return -EINVAL; } if (!target_dev_configured(dev)) { @@ -2797,9 +2796,7 @@ static ssize_t target_tg_pt_gp_alua_access_status_store( int new_status, ret; if (!tg_pt_gp->tg_pt_gp_valid_id) { - pr_err("Unable to do set ALUA access status on non" - " valid tg_pt_gp ID: %hu\n", - tg_pt_gp->tg_pt_gp_valid_id); + pr_err("Unable to set ALUA access status on invalid tg_pt_gp ID\n"); return -EINVAL; } @@ -2852,9 +2849,7 @@ static ssize_t target_tg_pt_gp_alua_support_##_name##_store( \ int ret; \ \ if (!t->tg_pt_gp_valid_id) { \ - pr_err("Unable to do set " #_name " ALUA state on non" \ - " valid tg_pt_gp ID: %hu\n", \ - t->tg_pt_gp_valid_id); \ + pr_err("Unable to set " #_name " ALUA state on invalid tg_pt_gp ID\n"); \ return -EINVAL; \ } \ \ From 7a3beeae289385f7be9f61a33a6e4f6c7e2400d3 Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Thu, 15 Apr 2021 15:08:26 -0700 Subject: [PATCH 412/412] scsi: target: tcm_fc: Fix a kernel-doc header Fix the function name in the kernel-doc header above ft_prli(). Link: https://lore.kernel.org/r/20210415220826.29438-21-bvanassche@acm.org Cc: Hannes Reinecke Signed-off-by: Bart Van Assche Signed-off-by: Martin K. Petersen --- drivers/target/tcm_fc/tfc_sess.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/target/tcm_fc/tfc_sess.c b/drivers/target/tcm_fc/tfc_sess.c index 23ce506d5402..593540da9346 100644 --- a/drivers/target/tcm_fc/tfc_sess.c +++ b/drivers/target/tcm_fc/tfc_sess.c @@ -410,7 +410,7 @@ not_target: } /** - * tcm_fcp_prli() - Handle incoming or outgoing PRLI for the FCP target + * ft_prli() - Handle incoming or outgoing PRLI for the FCP target * @rdata: remote port private * @spp_len: service parameter page length * @rspp: received service parameter page (NULL for outgoing PRLI)