Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

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

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
Loading
Loading
Loading
Loading
+1 −3
Original line number Original line Diff line number Diff line
@@ -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.


+7 −7
Original line number Original line Diff line number Diff line
@@ -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)


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)


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)


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)


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)


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,
	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);
+1 −1
Original line number Original line Diff line number Diff line
@@ -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;


+6 −6
Original line number Original line Diff line number Diff line
@@ -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)


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)


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)
 
 
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)
		/* 
		/* 
		 *	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)
		
		
		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))
		{
		{
+1 −0
Original line number Original line Diff line number Diff line
@@ -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);
Loading