]> www.infradead.org Git - users/willy/xarray.git/commitdiff
scsi: bfa: Fix function pointer type mismatch for hcb_qe->cbfn
authorArnd Bergmann <arnd@arndb.de>
Thu, 22 Feb 2024 12:44:06 +0000 (13:44 +0100)
committerMartin K. Petersen <martin.petersen@oracle.com>
Tue, 27 Feb 2024 02:16:48 +0000 (21:16 -0500)
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: 37ea0558b87a ("[SCSI] bfa: Added support to collect and reset fcport stats")
Fixes: 3ec4f2c8bff2 ("[SCSI] bfa: Added support to configure QOS and collect stats.")
Reviewed-by: Kees Cook <keescook@chromium.org>
Signed-off-by: Arnd Bergmann <arnd@arndb.de>
Link: https://lore.kernel.org/r/20240222124433.2046570-1-arnd@kernel.org
Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
drivers/scsi/bfa/bfa.h
drivers/scsi/bfa/bfa_core.c
drivers/scsi/bfa/bfa_ioc.h
drivers/scsi/bfa/bfad_bsg.c

index 7bd2ba1ad4d1184feac315d6e2909e861a58f46b..f30fe324e6ecc1428a691b1d61dda3c80b22ed8c 100644 (file)
@@ -20,7 +20,6 @@
 struct bfa_s;
 
 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
@@ -437,4 +436,12 @@ struct bfa_cb_pending_q_s {
        (__qe)->data = (__data);                                \
 } 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__ */
index 6846ca8f7313c379b03983f4c532f631bc0b2a40..3438d0b8ba0624020a4c33e29656c0a55ef06070 100644 (file)
@@ -1907,15 +1907,13 @@ bfa_comp_process(struct bfa_s *bfa, struct list_head *comp_q)
        struct list_head                *qe;
        struct list_head                *qen;
        struct bfa_cb_qe_s      *hcb_qe;
-       bfa_cb_cbfn_status_t    cbfn;
 
        list_for_each_safe(qe, qen, comp_q) {
                hcb_qe = (struct bfa_cb_qe_s *) qe;
                if (hcb_qe->pre_rmv) {
                        /* qe is invalid after return, dequeue before cbfn() */
                        list_del(qe);
-                       cbfn = (bfa_cb_cbfn_status_t)(hcb_qe->cbfn);
-                       cbfn(hcb_qe->cbarg, hcb_qe->fw_status);
+                       hcb_qe->cbfn_status(hcb_qe->cbarg, hcb_qe->fw_status);
                } else
                        hcb_qe->cbfn(hcb_qe->cbarg, BFA_TRUE);
        }
index 933a1c3890ff50bd5ee9da57d5e4137116b401d2..5e568d6d7b261032ec0ad028e541daa9c5ffc97b 100644 (file)
@@ -361,14 +361,18 @@ struct bfa_reqq_wait_s {
        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.
  */
 struct bfa_cb_qe_s {
        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   pre_rmv;        /* set for stack based qe(s) */
        bfa_status_t    fw_status;      /* to access fw status in comp proc */
index d4ceca2d435ee1a3af6c6424cf2eb6648d8a6887..54bd11e6d593350f632b55af7deb3599c59adc9f 100644 (file)
@@ -2135,8 +2135,7 @@ bfad_iocmd_fcport_get_stats(struct bfad_s *bfad, void *cmd)
        struct bfa_cb_pending_q_s cb_qe;
 
        init_completion(&fcomp.comp);
-       bfa_pending_q_init(&cb_qe, (bfa_cb_cbfn_t)bfad_hcb_comp,
-                          &fcomp, &iocmd->stats);
+       bfa_pending_q_init_status(&cb_qe, bfad_hcb_comp, &fcomp, &iocmd->stats);
        spin_lock_irqsave(&bfad->bfad_lock, flags);
        iocmd->status = bfa_fcport_get_stats(&bfad->bfa, &cb_qe);
        spin_unlock_irqrestore(&bfad->bfad_lock, flags);
@@ -2159,7 +2158,7 @@ bfad_iocmd_fcport_reset_stats(struct bfad_s *bfad, void *cmd)
        struct bfa_cb_pending_q_s cb_qe;
 
        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);
        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)
        struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(&bfad->bfa);
 
        init_completion(&fcomp.comp);
-       bfa_pending_q_init(&cb_qe, (bfa_cb_cbfn_t)bfad_hcb_comp,
-                          &fcomp, &iocmd->stats);
+       bfa_pending_q_init_status(&cb_qe, bfad_hcb_comp, &fcomp, &iocmd->stats);
 
        spin_lock_irqsave(&bfad->bfad_lock, flags);
        WARN_ON(!bfa_ioc_get_fcmode(&bfad->bfa.ioc));
@@ -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);
 
        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);
        WARN_ON(!bfa_ioc_get_fcmode(&bfad->bfa.ioc));