^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) // Copyright (c) 2010-2011 EIA Electronics,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) // Kurt Van Dijck <kurt.van.dijck@eia.be>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) // Copyright (c) 2017-2019 Pengutronix,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) // Marc Kleine-Budde <kernel@pengutronix.de>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) // Copyright (c) 2017-2019 Pengutronix,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) // Oleksij Rempel <kernel@pengutronix.de>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) /* bus for j1939 remote devices
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) * Since rtnetlink, no real bus is used.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) #include <net/sock.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) #include "j1939-priv.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) static void __j1939_ecu_release(struct kref *kref)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) struct j1939_ecu *ecu = container_of(kref, struct j1939_ecu, kref);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) struct j1939_priv *priv = ecu->priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) list_del(&ecu->list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) kfree(ecu);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) j1939_priv_put(priv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) void j1939_ecu_put(struct j1939_ecu *ecu)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) kref_put(&ecu->kref, __j1939_ecu_release);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) static void j1939_ecu_get(struct j1939_ecu *ecu)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) kref_get(&ecu->kref);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) static bool j1939_ecu_is_mapped_locked(struct j1939_ecu *ecu)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) struct j1939_priv *priv = ecu->priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) lockdep_assert_held(&priv->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) return j1939_ecu_find_by_addr_locked(priv, ecu->addr) == ecu;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) /* ECU device interface */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) /* map ECU to a bus address space */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) static void j1939_ecu_map_locked(struct j1939_ecu *ecu)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) struct j1939_priv *priv = ecu->priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) struct j1939_addr_ent *ent;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) lockdep_assert_held(&priv->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) if (!j1939_address_is_unicast(ecu->addr))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) ent = &priv->ents[ecu->addr];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) if (ent->ecu) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) netdev_warn(priv->ndev, "Trying to map already mapped ECU, addr: 0x%02x, name: 0x%016llx. Skip it.\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) ecu->addr, ecu->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) j1939_ecu_get(ecu);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) ent->ecu = ecu;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) ent->nusers += ecu->nusers;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) /* unmap ECU from a bus address space */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) void j1939_ecu_unmap_locked(struct j1939_ecu *ecu)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) struct j1939_priv *priv = ecu->priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) struct j1939_addr_ent *ent;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) lockdep_assert_held(&priv->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) if (!j1939_address_is_unicast(ecu->addr))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) if (!j1939_ecu_is_mapped_locked(ecu))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) ent = &priv->ents[ecu->addr];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) ent->ecu = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) ent->nusers -= ecu->nusers;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) j1939_ecu_put(ecu);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) void j1939_ecu_unmap(struct j1939_ecu *ecu)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) write_lock_bh(&ecu->priv->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) j1939_ecu_unmap_locked(ecu);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) write_unlock_bh(&ecu->priv->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) void j1939_ecu_unmap_all(struct j1939_priv *priv)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) write_lock_bh(&priv->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) for (i = 0; i < ARRAY_SIZE(priv->ents); i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) if (priv->ents[i].ecu)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) j1939_ecu_unmap_locked(priv->ents[i].ecu);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) write_unlock_bh(&priv->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) void j1939_ecu_timer_start(struct j1939_ecu *ecu)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) /* The ECU is held here and released in the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) * j1939_ecu_timer_handler() or j1939_ecu_timer_cancel().
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) j1939_ecu_get(ecu);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) /* Schedule timer in 250 msec to commit address change. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) hrtimer_start(&ecu->ac_timer, ms_to_ktime(250),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) HRTIMER_MODE_REL_SOFT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) void j1939_ecu_timer_cancel(struct j1939_ecu *ecu)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) if (hrtimer_cancel(&ecu->ac_timer))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) j1939_ecu_put(ecu);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) static enum hrtimer_restart j1939_ecu_timer_handler(struct hrtimer *hrtimer)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) struct j1939_ecu *ecu =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) container_of(hrtimer, struct j1939_ecu, ac_timer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) struct j1939_priv *priv = ecu->priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) write_lock_bh(&priv->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) /* TODO: can we test if ecu->addr is unicast before starting
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) * the timer?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) j1939_ecu_map_locked(ecu);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) /* The corresponding j1939_ecu_get() is in
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) * j1939_ecu_timer_start().
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) j1939_ecu_put(ecu);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) write_unlock_bh(&priv->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) return HRTIMER_NORESTART;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) struct j1939_ecu *j1939_ecu_create_locked(struct j1939_priv *priv, name_t name)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) struct j1939_ecu *ecu;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) lockdep_assert_held(&priv->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) ecu = kzalloc(sizeof(*ecu), gfp_any());
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) if (!ecu)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) return ERR_PTR(-ENOMEM);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) kref_init(&ecu->kref);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) ecu->addr = J1939_IDLE_ADDR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) ecu->name = name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) hrtimer_init(&ecu->ac_timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL_SOFT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) ecu->ac_timer.function = j1939_ecu_timer_handler;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) INIT_LIST_HEAD(&ecu->list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) j1939_priv_get(priv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) ecu->priv = priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) list_add_tail(&ecu->list, &priv->ecus);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) return ecu;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) struct j1939_ecu *j1939_ecu_find_by_addr_locked(struct j1939_priv *priv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) u8 addr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) lockdep_assert_held(&priv->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) return priv->ents[addr].ecu;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) struct j1939_ecu *j1939_ecu_get_by_addr_locked(struct j1939_priv *priv, u8 addr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) struct j1939_ecu *ecu;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) lockdep_assert_held(&priv->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) if (!j1939_address_is_unicast(addr))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) ecu = j1939_ecu_find_by_addr_locked(priv, addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) if (ecu)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) j1939_ecu_get(ecu);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) return ecu;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) struct j1939_ecu *j1939_ecu_get_by_addr(struct j1939_priv *priv, u8 addr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) struct j1939_ecu *ecu;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) read_lock_bh(&priv->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) ecu = j1939_ecu_get_by_addr_locked(priv, addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) read_unlock_bh(&priv->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) return ecu;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) /* get pointer to ecu without increasing ref counter */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) static struct j1939_ecu *j1939_ecu_find_by_name_locked(struct j1939_priv *priv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) name_t name)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) struct j1939_ecu *ecu;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) lockdep_assert_held(&priv->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) list_for_each_entry(ecu, &priv->ecus, list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) if (ecu->name == name)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) return ecu;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) struct j1939_ecu *j1939_ecu_get_by_name_locked(struct j1939_priv *priv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) name_t name)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) struct j1939_ecu *ecu;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) lockdep_assert_held(&priv->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) if (!name)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) ecu = j1939_ecu_find_by_name_locked(priv, name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) if (ecu)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) j1939_ecu_get(ecu);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) return ecu;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) struct j1939_ecu *j1939_ecu_get_by_name(struct j1939_priv *priv, name_t name)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) struct j1939_ecu *ecu;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) read_lock_bh(&priv->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) ecu = j1939_ecu_get_by_name_locked(priv, name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) read_unlock_bh(&priv->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) return ecu;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) u8 j1939_name_to_addr(struct j1939_priv *priv, name_t name)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) struct j1939_ecu *ecu;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) int addr = J1939_IDLE_ADDR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) if (!name)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) return J1939_NO_ADDR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) read_lock_bh(&priv->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) ecu = j1939_ecu_find_by_name_locked(priv, name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) if (ecu && j1939_ecu_is_mapped_locked(ecu))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) /* ecu's SA is registered */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) addr = ecu->addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) read_unlock_bh(&priv->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) return addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) /* TX addr/name accounting
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) * Transport protocol needs to know if a SA is local or not
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) * These functions originate from userspace manipulating sockets,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) * so locking is straigforward
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) int j1939_local_ecu_get(struct j1939_priv *priv, name_t name, u8 sa)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) struct j1939_ecu *ecu;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) int err = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) write_lock_bh(&priv->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) if (j1939_address_is_unicast(sa))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) priv->ents[sa].nusers++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) if (!name)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) goto done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) ecu = j1939_ecu_get_by_name_locked(priv, name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) if (!ecu)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) ecu = j1939_ecu_create_locked(priv, name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) err = PTR_ERR_OR_ZERO(ecu);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) goto done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) ecu->nusers++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) /* TODO: do we care if ecu->addr != sa? */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) if (j1939_ecu_is_mapped_locked(ecu))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) /* ecu's sa is active already */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) priv->ents[ecu->addr].nusers++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) done:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) write_unlock_bh(&priv->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) void j1939_local_ecu_put(struct j1939_priv *priv, name_t name, u8 sa)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) struct j1939_ecu *ecu;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) write_lock_bh(&priv->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) if (j1939_address_is_unicast(sa))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) priv->ents[sa].nusers--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) if (!name)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) goto done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) ecu = j1939_ecu_find_by_name_locked(priv, name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) if (WARN_ON_ONCE(!ecu))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) goto done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) ecu->nusers--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) /* TODO: do we care if ecu->addr != sa? */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) if (j1939_ecu_is_mapped_locked(ecu))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) /* ecu's sa is active already */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) priv->ents[ecu->addr].nusers--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) j1939_ecu_put(ecu);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) done:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) write_unlock_bh(&priv->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) }