Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

can: bittiming: change can_calc_tdco()'s prototype to not directly modify priv

The function can_calc_tdco() directly retrieves can_priv from the
net_device and directly modifies it.

This is annoying for the upcoming patch. In
drivers/net/can/dev/netlink.c:can_changelink(), the data bittiming are
written to a temporary structure and memcpyed to can_priv only after
everything succeeded. In the next patch, where we will introduce the
netlink interface for TDC parameters, we will add a new TDC block
which can potentially fail. For this reason, the data bittiming
temporary structure has to be copied after that to-be-introduced TDC
block. However, TDC also needs to access data bittiming information.

We change the prototype so that the data bittiming structure is passed
to can_calc_tdco() as an argument instead of retrieving it from
priv. This way can_calc_tdco() can access the data bittiming before it
gets memcpyed to priv.

Link: https://lore.kernel.org/all/20210918095637.20108-4-mailhol.vincent@wanadoo.fr
Signed-off-by: Vincent Mailhol <mailhol.vincent@wanadoo.fr>
Signed-off-by: Marc Kleine-Budde <mkl@pengutronix.de>

authored by

Vincent Mailhol and committed by
Marc Kleine-Budde
da45a1e4 39f66c9e

+16 -13
+7 -10
drivers/net/can/dev/bittiming.c
··· 175 175 return 0; 176 176 } 177 177 178 - void can_calc_tdco(struct net_device *dev) 179 - { 180 - struct can_priv *priv = netdev_priv(dev); 181 - const struct can_bittiming *dbt = &priv->data_bittiming; 182 - struct can_tdc *tdc = &priv->tdc; 183 - const struct can_tdc_const *tdc_const = priv->tdc_const; 178 + void can_calc_tdco(struct can_tdc *tdc, const struct can_tdc_const *tdc_const, 179 + const struct can_bittiming *dbt, 180 + u32 *ctrlmode, u32 ctrlmode_supported) 184 181 185 - if (!tdc_const || 186 - !(priv->ctrlmode_supported & CAN_CTRLMODE_TDC_AUTO)) 182 + { 183 + if (!tdc_const || !(ctrlmode_supported & CAN_CTRLMODE_TDC_AUTO)) 187 184 return; 188 185 189 - priv->ctrlmode &= ~CAN_CTRLMODE_TDC_MASK; 186 + *ctrlmode &= ~CAN_CTRLMODE_TDC_MASK; 190 187 191 188 /* As specified in ISO 11898-1 section 11.3.3 "Transmitter 192 189 * delay compensation" (TDC) is only applicable if data BRP is ··· 197 200 if (sample_point_in_tc < tdc_const->tdco_min) 198 201 return; 199 202 tdc->tdco = min(sample_point_in_tc, tdc_const->tdco_max); 200 - priv->ctrlmode |= CAN_CTRLMODE_TDC_AUTO; 203 + *ctrlmode |= CAN_CTRLMODE_TDC_AUTO; 201 204 } 202 205 } 203 206 #endif /* CONFIG_CAN_CALC_BITTIMING */
+2 -1
drivers/net/can/dev/netlink.c
··· 189 189 190 190 memcpy(&priv->data_bittiming, &dbt, sizeof(dbt)); 191 191 192 - can_calc_tdco(dev); 192 + can_calc_tdco(&priv->tdc, priv->tdc_const, &priv->data_bittiming, 193 + &priv->ctrlmode, priv->ctrlmode_supported); 193 194 194 195 if (priv->do_set_data_bittiming) { 195 196 /* Finally, set the bit-timing registers */
+7 -2
include/linux/can/bittiming.h
··· 123 123 int can_calc_bittiming(struct net_device *dev, struct can_bittiming *bt, 124 124 const struct can_bittiming_const *btc); 125 125 126 - void can_calc_tdco(struct net_device *dev); 126 + void can_calc_tdco(struct can_tdc *tdc, const struct can_tdc_const *tdc_const, 127 + const struct can_bittiming *dbt, 128 + u32 *ctrlmode, u32 ctrlmode_supported); 127 129 #else /* !CONFIG_CAN_CALC_BITTIMING */ 128 130 static inline int 129 131 can_calc_bittiming(struct net_device *dev, struct can_bittiming *bt, ··· 135 133 return -EINVAL; 136 134 } 137 135 138 - static inline void can_calc_tdco(struct net_device *dev) 136 + static inline void 137 + can_calc_tdco(struct can_tdc *tdc, const struct can_tdc_const *tdc_const, 138 + const struct can_bittiming *dbt, 139 + u32 *ctrlmode, u32 ctrlmode_supported) 139 140 { 140 141 } 141 142 #endif /* CONFIG_CAN_CALC_BITTIMING */