When getting the CAN interface's name via the SIOCGIFNAME ioctl,
elm->dev->name may no longer exist because the interface is being shut
down.
Also, print the name of the interface to dmesg.
struct tty_struct *tty;
struct net_device *dev;
struct tty_struct *tty;
struct net_device *dev;
/* Per-channel lock */
spinlock_t lock;
/* Per-channel lock */
spinlock_t lock;
* (takes elm->lock) *
************************************************************************/
* (takes elm->lock) *
************************************************************************/
+static int elmcan_netdev_init(struct net_device *dev)
+{
+ struct elmcan *elm = netdev_priv(dev);
+
+ /* Copy the interface name here, so the SIOCGIFNAME case in
+ * elmcan_ldisc_ioctl() doesn't race against unregister_candev().
+ */
+ memcpy(elm->ifname, dev->name, IFNAMSIZ);
+
+ return 0;
+}
+
/* Netdevice DOWN -> UP routine */
static int elmcan_netdev_open(struct net_device *dev)
{
/* Netdevice DOWN -> UP routine */
static int elmcan_netdev_open(struct net_device *dev)
{
}
static const struct net_device_ops elmcan_netdev_ops = {
}
static const struct net_device_ops elmcan_netdev_ops = {
+ .ndo_init = elmcan_netdev_init,
.ndo_open = elmcan_netdev_open,
.ndo_stop = elmcan_netdev_close,
.ndo_start_xmit = elmcan_netdev_start_xmit,
.ndo_open = elmcan_netdev_open,
.ndo_stop = elmcan_netdev_close,
.ndo_start_xmit = elmcan_netdev_start_xmit,
+ netdev_info(elm->dev, "elmcan on %s.\n", tty->name);
+
switch (cmd) {
case SIOCGIFNAME:
switch (cmd) {
case SIOCGIFNAME:
- tmp = strlen(elm->dev->name) + 1;
- if (copy_to_user((void __user *)arg, elm->dev->name, tmp))
+ tmp = strlen(elm->ifname) + 1;
+ if (copy_to_user((void __user *)arg, elm->ifname, tmp))
return -EFAULT;
return 0;
return -EFAULT;
return 0;
- ``if (!elm)``: Race with ``ldisc_close()``
- ``if (!elm)``: Race with ``ldisc_close()``
-- ``elm->dev``: Race in ``ldisc_ioctl()``
-
- DMA capable rx/tx buffers
- fixup constants, constant for '``>``'
- DMA capable rx/tx buffers
- fixup constants, constant for '``>``'