Commit 4951704b authored by David S. Miller's avatar David S. Miller

syncppp: Fix crashes.

The syncppp layer wants a mid-level netdev private pointer.

It was using netdev->priv but that only worked by accident,
and thus this scheme was broken when the device private
allocation strategy changed.

Add a proper mid-layer private pointer for uses like this,
update syncppp and all users, and remove the HDLC_PPP broken
tag from drivers/net/wan/Kconfig
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent c4492586
...@@ -150,11 +150,9 @@ config HDLC_FR ...@@ -150,11 +150,9 @@ config HDLC_FR
config HDLC_PPP config HDLC_PPP
tristate "Synchronous Point-to-Point Protocol (PPP) support" tristate "Synchronous Point-to-Point Protocol (PPP) support"
depends on HDLC && BROKEN depends on HDLC
help help
Generic HDLC driver supporting PPP over WAN connections. Generic HDLC driver supporting PPP over WAN connections.
This module is currently broken and will cause a kernel panic
when a device configured in PPP mode is activated.
It will be replaced by new PPP implementation in Linux 2.6.26. It will be replaced by new PPP implementation in Linux 2.6.26.
......
...@@ -629,7 +629,7 @@ static void sppp_channel_init(struct channel_data *chan) ...@@ -629,7 +629,7 @@ static void sppp_channel_init(struct channel_data *chan)
d->base_addr = chan->cosa->datareg; d->base_addr = chan->cosa->datareg;
d->irq = chan->cosa->irq; d->irq = chan->cosa->irq;
d->dma = chan->cosa->dma; d->dma = chan->cosa->dma;
d->priv = chan; d->ml_priv = chan;
sppp_attach(&chan->pppdev); sppp_attach(&chan->pppdev);
if (register_netdev(d)) { if (register_netdev(d)) {
printk(KERN_WARNING "%s: register_netdev failed.\n", d->name); printk(KERN_WARNING "%s: register_netdev failed.\n", d->name);
...@@ -650,7 +650,7 @@ static void sppp_channel_delete(struct channel_data *chan) ...@@ -650,7 +650,7 @@ static void sppp_channel_delete(struct channel_data *chan)
static int cosa_sppp_open(struct net_device *d) static int cosa_sppp_open(struct net_device *d)
{ {
struct channel_data *chan = d->priv; struct channel_data *chan = d->ml_priv;
int err; int err;
unsigned long flags; unsigned long flags;
...@@ -690,7 +690,7 @@ static int cosa_sppp_open(struct net_device *d) ...@@ -690,7 +690,7 @@ static int cosa_sppp_open(struct net_device *d)
static int cosa_sppp_tx(struct sk_buff *skb, struct net_device *dev) static int cosa_sppp_tx(struct sk_buff *skb, struct net_device *dev)
{ {
struct channel_data *chan = dev->priv; struct channel_data *chan = dev->ml_priv;
netif_stop_queue(dev); netif_stop_queue(dev);
...@@ -701,7 +701,7 @@ static int cosa_sppp_tx(struct sk_buff *skb, struct net_device *dev) ...@@ -701,7 +701,7 @@ static int cosa_sppp_tx(struct sk_buff *skb, struct net_device *dev)
static void cosa_sppp_timeout(struct net_device *dev) static void cosa_sppp_timeout(struct net_device *dev)
{ {
struct channel_data *chan = dev->priv; struct channel_data *chan = dev->ml_priv;
if (test_bit(RXBIT, &chan->cosa->rxtx)) { if (test_bit(RXBIT, &chan->cosa->rxtx)) {
chan->stats.rx_errors++; chan->stats.rx_errors++;
...@@ -720,7 +720,7 @@ static void cosa_sppp_timeout(struct net_device *dev) ...@@ -720,7 +720,7 @@ static void cosa_sppp_timeout(struct net_device *dev)
static int cosa_sppp_close(struct net_device *d) static int cosa_sppp_close(struct net_device *d)
{ {
struct channel_data *chan = d->priv; struct channel_data *chan = d->ml_priv;
unsigned long flags; unsigned long flags;
netif_stop_queue(d); netif_stop_queue(d);
...@@ -800,7 +800,7 @@ static int sppp_tx_done(struct channel_data *chan, int size) ...@@ -800,7 +800,7 @@ static int sppp_tx_done(struct channel_data *chan, int size)
static struct net_device_stats *cosa_net_stats(struct net_device *dev) static struct net_device_stats *cosa_net_stats(struct net_device *dev)
{ {
struct channel_data *chan = dev->priv; struct channel_data *chan = dev->ml_priv;
return &chan->stats; return &chan->stats;
} }
...@@ -1217,7 +1217,7 @@ static int cosa_sppp_ioctl(struct net_device *dev, struct ifreq *ifr, ...@@ -1217,7 +1217,7 @@ static int cosa_sppp_ioctl(struct net_device *dev, struct ifreq *ifr,
int cmd) int cmd)
{ {
int rv; int rv;
struct channel_data *chan = dev->priv; struct channel_data *chan = dev->ml_priv;
rv = cosa_ioctl_common(chan->cosa, chan, cmd, (unsigned long)ifr->ifr_data); rv = cosa_ioctl_common(chan->cosa, chan, cmd, (unsigned long)ifr->ifr_data);
if (rv == -ENOIOCTLCMD) { if (rv == -ENOIOCTLCMD) {
return sppp_do_ioctl(dev, ifr, cmd); return sppp_do_ioctl(dev, ifr, cmd);
......
...@@ -45,7 +45,7 @@ static int ppp_open(struct net_device *dev) ...@@ -45,7 +45,7 @@ static int ppp_open(struct net_device *dev)
int (*old_ioctl)(struct net_device *, struct ifreq *, int); int (*old_ioctl)(struct net_device *, struct ifreq *, int);
int result; int result;
dev->priv = &state(hdlc)->syncppp_ptr; dev->ml_priv = &state(hdlc)->syncppp_ptr;
state(hdlc)->syncppp_ptr = &state(hdlc)->pppdev; state(hdlc)->syncppp_ptr = &state(hdlc)->pppdev;
state(hdlc)->pppdev.dev = dev; state(hdlc)->pppdev.dev = dev;
......
...@@ -75,7 +75,7 @@ static void hostess_input(struct z8530_channel *c, struct sk_buff *skb) ...@@ -75,7 +75,7 @@ static void hostess_input(struct z8530_channel *c, struct sk_buff *skb)
static int hostess_open(struct net_device *d) static int hostess_open(struct net_device *d)
{ {
struct sv11_device *sv11=d->priv; struct sv11_device *sv11=d->ml_priv;
int err = -1; int err = -1;
/* /*
...@@ -128,7 +128,7 @@ static int hostess_open(struct net_device *d) ...@@ -128,7 +128,7 @@ static int hostess_open(struct net_device *d)
static int hostess_close(struct net_device *d) static int hostess_close(struct net_device *d)
{ {
struct sv11_device *sv11=d->priv; struct sv11_device *sv11=d->ml_priv;
/* /*
* Discard new frames * Discard new frames
*/ */
...@@ -159,14 +159,14 @@ static int hostess_close(struct net_device *d) ...@@ -159,14 +159,14 @@ static int hostess_close(struct net_device *d)
static int hostess_ioctl(struct net_device *d, struct ifreq *ifr, int cmd) static int hostess_ioctl(struct net_device *d, struct ifreq *ifr, int cmd)
{ {
/* struct sv11_device *sv11=d->priv; /* struct sv11_device *sv11=d->ml_priv;
z8530_ioctl(d,&sv11->sync.chanA,ifr,cmd) */ z8530_ioctl(d,&sv11->sync.chanA,ifr,cmd) */
return sppp_do_ioctl(d, ifr,cmd); return sppp_do_ioctl(d, ifr,cmd);
} }
static struct net_device_stats *hostess_get_stats(struct net_device *d) static struct net_device_stats *hostess_get_stats(struct net_device *d)
{ {
struct sv11_device *sv11=d->priv; struct sv11_device *sv11=d->ml_priv;
if(sv11) if(sv11)
return z8530_get_stats(&sv11->sync.chanA); return z8530_get_stats(&sv11->sync.chanA);
else else
...@@ -179,7 +179,7 @@ static struct net_device_stats *hostess_get_stats(struct net_device *d) ...@@ -179,7 +179,7 @@ static struct net_device_stats *hostess_get_stats(struct net_device *d)
static int hostess_queue_xmit(struct sk_buff *skb, struct net_device *d) static int hostess_queue_xmit(struct sk_buff *skb, struct net_device *d)
{ {
struct sv11_device *sv11=d->priv; struct sv11_device *sv11=d->ml_priv;
return z8530_queue_xmit(&sv11->sync.chanA, skb); return z8530_queue_xmit(&sv11->sync.chanA, skb);
} }
...@@ -325,6 +325,7 @@ static struct sv11_device *sv11_init(int iobase, int irq) ...@@ -325,6 +325,7 @@ static struct sv11_device *sv11_init(int iobase, int irq)
/* /*
* Initialise the PPP components * Initialise the PPP components
*/ */
d->ml_priv = sv;
sppp_attach(&sv->netdev); sppp_attach(&sv->netdev);
/* /*
...@@ -333,7 +334,6 @@ static struct sv11_device *sv11_init(int iobase, int irq) ...@@ -333,7 +334,6 @@ static struct sv11_device *sv11_init(int iobase, int irq)
d->base_addr = iobase; d->base_addr = iobase;
d->irq = irq; d->irq = irq;
d->priv = sv;
if(register_netdev(d)) if(register_netdev(d))
{ {
......
...@@ -891,6 +891,7 @@ static int __devinit lmc_init_one(struct pci_dev *pdev, ...@@ -891,6 +891,7 @@ static int __devinit lmc_init_one(struct pci_dev *pdev,
/* Initialize the sppp layer */ /* Initialize the sppp layer */
/* An ioctl can cause a subsequent detach for raw frame interface */ /* An ioctl can cause a subsequent detach for raw frame interface */
dev->ml_priv = sc;
sc->if_type = LMC_PPP; sc->if_type = LMC_PPP;
sc->check = 0xBEAFCAFE; sc->check = 0xBEAFCAFE;
dev->base_addr = pci_resource_start(pdev, 0); dev->base_addr = pci_resource_start(pdev, 0);
......
...@@ -241,6 +241,7 @@ static inline struct slvl_device *slvl_alloc(int iobase, int irq) ...@@ -241,6 +241,7 @@ static inline struct slvl_device *slvl_alloc(int iobase, int irq)
return NULL; return NULL;
sv = d->priv; sv = d->priv;
d->ml_priv = sv;
sv->if_ptr = &sv->pppdev; sv->if_ptr = &sv->pppdev;
sv->pppdev.dev = d; sv->pppdev.dev = d;
d->base_addr = iobase; d->base_addr = iobase;
......
...@@ -715,6 +715,9 @@ struct net_device ...@@ -715,6 +715,9 @@ struct net_device
struct net *nd_net; struct net *nd_net;
#endif #endif
/* mid-layer private */
void *ml_priv;
/* bridge stuff */ /* bridge stuff */
struct net_bridge_port *br_port; struct net_bridge_port *br_port;
/* macvlan */ /* macvlan */
......
...@@ -59,7 +59,7 @@ struct ppp_device ...@@ -59,7 +59,7 @@ struct ppp_device
static inline struct sppp *sppp_of(struct net_device *dev) static inline struct sppp *sppp_of(struct net_device *dev)
{ {
struct ppp_device **ppp = dev->priv; struct ppp_device **ppp = dev->ml_priv;
BUG_ON((*ppp)->dev != dev); BUG_ON((*ppp)->dev != dev);
return &(*ppp)->sppp; return &(*ppp)->sppp;
} }
......
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