Commit b6960023 authored by Arnd Bergmann's avatar Arnd Bergmann Committed by Martin K. Petersen

scsi: bfa: Fix function pointer type mismatch for hcb_qe->cbfn

Some callback functions used here take a boolean argument, others take a
status argument. This breaks KCFI type checking, so clang now warns about
the function pointer cast:

drivers/scsi/bfa/bfad_bsg.c:2138:29: error: cast from 'void (*)(void *, enum bfa_status)' to 'bfa_cb_cbfn_t' (aka 'void (*)(void *, enum bfa_boolean)') converts to incompatible function type [-Werror,-Wcast-function-type-strict]

Assuming the code is actually correct here and the callers always match the
argument types of the callee, rework this to replace the explicit cast with
a union of the two pointer types. This does not change the behavior of the
code, so if something is actually broken here, a larger rework may be
necessary.

Fixes: 37ea0558 ("[SCSI] bfa: Added support to collect and reset fcport stats")
Fixes: 3ec4f2c8 ("[SCSI] bfa: Added support to configure QOS and collect stats.")
Reviewed-by: default avatarKees Cook <keescook@chromium.org>
Signed-off-by: default avatarArnd Bergmann <arnd@arndb.de>
Link: https://lore.kernel.org/r/20240222124433.2046570-1-arnd@kernel.orgSigned-off-by: default avatarMartin K. Petersen <martin.petersen@oracle.com>
parent c121b588
...@@ -20,7 +20,6 @@ ...@@ -20,7 +20,6 @@
struct bfa_s; struct bfa_s;
typedef void (*bfa_isr_func_t) (struct bfa_s *bfa, struct bfi_msg_s *m); typedef void (*bfa_isr_func_t) (struct bfa_s *bfa, struct bfi_msg_s *m);
typedef void (*bfa_cb_cbfn_status_t) (void *cbarg, bfa_status_t status);
/* /*
* Interrupt message handlers * Interrupt message handlers
...@@ -437,4 +436,12 @@ struct bfa_cb_pending_q_s { ...@@ -437,4 +436,12 @@ struct bfa_cb_pending_q_s {
(__qe)->data = (__data); \ (__qe)->data = (__data); \
} while (0) } while (0)
#define bfa_pending_q_init_status(__qe, __cbfn, __cbarg, __data) do { \
bfa_q_qe_init(&((__qe)->hcb_qe.qe)); \
(__qe)->hcb_qe.cbfn_status = (__cbfn); \
(__qe)->hcb_qe.cbarg = (__cbarg); \
(__qe)->hcb_qe.pre_rmv = BFA_TRUE; \
(__qe)->data = (__data); \
} while (0)
#endif /* __BFA_H__ */ #endif /* __BFA_H__ */
...@@ -1907,15 +1907,13 @@ bfa_comp_process(struct bfa_s *bfa, struct list_head *comp_q) ...@@ -1907,15 +1907,13 @@ bfa_comp_process(struct bfa_s *bfa, struct list_head *comp_q)
struct list_head *qe; struct list_head *qe;
struct list_head *qen; struct list_head *qen;
struct bfa_cb_qe_s *hcb_qe; struct bfa_cb_qe_s *hcb_qe;
bfa_cb_cbfn_status_t cbfn;
list_for_each_safe(qe, qen, comp_q) { list_for_each_safe(qe, qen, comp_q) {
hcb_qe = (struct bfa_cb_qe_s *) qe; hcb_qe = (struct bfa_cb_qe_s *) qe;
if (hcb_qe->pre_rmv) { if (hcb_qe->pre_rmv) {
/* qe is invalid after return, dequeue before cbfn() */ /* qe is invalid after return, dequeue before cbfn() */
list_del(qe); list_del(qe);
cbfn = (bfa_cb_cbfn_status_t)(hcb_qe->cbfn); hcb_qe->cbfn_status(hcb_qe->cbarg, hcb_qe->fw_status);
cbfn(hcb_qe->cbarg, hcb_qe->fw_status);
} else } else
hcb_qe->cbfn(hcb_qe->cbarg, BFA_TRUE); hcb_qe->cbfn(hcb_qe->cbarg, BFA_TRUE);
} }
......
...@@ -361,14 +361,18 @@ struct bfa_reqq_wait_s { ...@@ -361,14 +361,18 @@ struct bfa_reqq_wait_s {
void *cbarg; void *cbarg;
}; };
typedef void (*bfa_cb_cbfn_t) (void *cbarg, bfa_boolean_t complete); typedef void (*bfa_cb_cbfn_t) (void *cbarg, bfa_boolean_t complete);
typedef void (*bfa_cb_cbfn_status_t) (void *cbarg, bfa_status_t status);
/* /*
* Generic BFA callback element. * Generic BFA callback element.
*/ */
struct bfa_cb_qe_s { struct bfa_cb_qe_s {
struct list_head qe; struct list_head qe;
bfa_cb_cbfn_t cbfn; union {
bfa_cb_cbfn_status_t cbfn_status;
bfa_cb_cbfn_t cbfn;
};
bfa_boolean_t once; bfa_boolean_t once;
bfa_boolean_t pre_rmv; /* set for stack based qe(s) */ bfa_boolean_t pre_rmv; /* set for stack based qe(s) */
bfa_status_t fw_status; /* to access fw status in comp proc */ bfa_status_t fw_status; /* to access fw status in comp proc */
......
...@@ -2135,8 +2135,7 @@ bfad_iocmd_fcport_get_stats(struct bfad_s *bfad, void *cmd) ...@@ -2135,8 +2135,7 @@ bfad_iocmd_fcport_get_stats(struct bfad_s *bfad, void *cmd)
struct bfa_cb_pending_q_s cb_qe; struct bfa_cb_pending_q_s cb_qe;
init_completion(&fcomp.comp); init_completion(&fcomp.comp);
bfa_pending_q_init(&cb_qe, (bfa_cb_cbfn_t)bfad_hcb_comp, bfa_pending_q_init_status(&cb_qe, bfad_hcb_comp, &fcomp, &iocmd->stats);
&fcomp, &iocmd->stats);
spin_lock_irqsave(&bfad->bfad_lock, flags); spin_lock_irqsave(&bfad->bfad_lock, flags);
iocmd->status = bfa_fcport_get_stats(&bfad->bfa, &cb_qe); iocmd->status = bfa_fcport_get_stats(&bfad->bfa, &cb_qe);
spin_unlock_irqrestore(&bfad->bfad_lock, flags); spin_unlock_irqrestore(&bfad->bfad_lock, flags);
...@@ -2159,7 +2158,7 @@ bfad_iocmd_fcport_reset_stats(struct bfad_s *bfad, void *cmd) ...@@ -2159,7 +2158,7 @@ bfad_iocmd_fcport_reset_stats(struct bfad_s *bfad, void *cmd)
struct bfa_cb_pending_q_s cb_qe; struct bfa_cb_pending_q_s cb_qe;
init_completion(&fcomp.comp); init_completion(&fcomp.comp);
bfa_pending_q_init(&cb_qe, (bfa_cb_cbfn_t)bfad_hcb_comp, &fcomp, NULL); bfa_pending_q_init_status(&cb_qe, bfad_hcb_comp, &fcomp, NULL);
spin_lock_irqsave(&bfad->bfad_lock, flags); spin_lock_irqsave(&bfad->bfad_lock, flags);
iocmd->status = bfa_fcport_clear_stats(&bfad->bfa, &cb_qe); iocmd->status = bfa_fcport_clear_stats(&bfad->bfa, &cb_qe);
...@@ -2443,8 +2442,7 @@ bfad_iocmd_qos_get_stats(struct bfad_s *bfad, void *cmd) ...@@ -2443,8 +2442,7 @@ bfad_iocmd_qos_get_stats(struct bfad_s *bfad, void *cmd)
struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(&bfad->bfa); struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(&bfad->bfa);
init_completion(&fcomp.comp); init_completion(&fcomp.comp);
bfa_pending_q_init(&cb_qe, (bfa_cb_cbfn_t)bfad_hcb_comp, bfa_pending_q_init_status(&cb_qe, bfad_hcb_comp, &fcomp, &iocmd->stats);
&fcomp, &iocmd->stats);
spin_lock_irqsave(&bfad->bfad_lock, flags); spin_lock_irqsave(&bfad->bfad_lock, flags);
WARN_ON(!bfa_ioc_get_fcmode(&bfad->bfa.ioc)); WARN_ON(!bfa_ioc_get_fcmode(&bfad->bfa.ioc));
...@@ -2474,8 +2472,7 @@ bfad_iocmd_qos_reset_stats(struct bfad_s *bfad, void *cmd) ...@@ -2474,8 +2472,7 @@ bfad_iocmd_qos_reset_stats(struct bfad_s *bfad, void *cmd)
struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(&bfad->bfa); struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(&bfad->bfa);
init_completion(&fcomp.comp); init_completion(&fcomp.comp);
bfa_pending_q_init(&cb_qe, (bfa_cb_cbfn_t)bfad_hcb_comp, bfa_pending_q_init_status(&cb_qe, bfad_hcb_comp, &fcomp, NULL);
&fcomp, NULL);
spin_lock_irqsave(&bfad->bfad_lock, flags); spin_lock_irqsave(&bfad->bfad_lock, flags);
WARN_ON(!bfa_ioc_get_fcmode(&bfad->bfa.ioc)); WARN_ON(!bfa_ioc_get_fcmode(&bfad->bfa.ioc));
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment