patch-2.4.3 linux/drivers/net/hp100.c
Next file: linux/drivers/net/ibmlana.h
Previous file: linux/drivers/net/hamradio/soundmodem/gentbl.c
Back to the patch index
Back to the overall index
- Lines: 137
- Date:
Sat Mar 3 10:55:47 2001
- Orig file:
v2.4.2/linux/drivers/net/hp100.c
- Orig date:
Wed Feb 21 18:20:27 2001
diff -u --recursive --new-file v2.4.2/linux/drivers/net/hp100.c linux/drivers/net/hp100.c
@@ -45,6 +45,8 @@
** along with this program; if not, write to the Free Software
** Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
**
+** 1.57b -> 1.57c - Arnaldo Carvalho de Melo <acme@conectiva.com.br>
+** - release resources on failure in init_module
**
** 1.57 -> 1.57b - Jean II
** - fix spinlocks, SMP is now working !
@@ -265,12 +267,14 @@
#define HP100_EISA_IDS_SIZE (sizeof(hp100_eisa_ids)/sizeof(struct hp100_eisa_id))
+#ifdef CONFIG_PCI
static struct hp100_pci_id hp100_pci_ids[] = {
{ PCI_VENDOR_ID_HP, PCI_DEVICE_ID_HP_J2585A },
{ PCI_VENDOR_ID_HP, PCI_DEVICE_ID_HP_J2585B },
{ PCI_VENDOR_ID_COMPEX, PCI_DEVICE_ID_COMPEX_ENET100VG4 },
{ PCI_VENDOR_ID_COMPEX2, PCI_DEVICE_ID_COMPEX2_100VG }
};
+#endif
#define HP100_PCI_IDS_SIZE (sizeof(hp100_pci_ids)/sizeof(struct hp100_pci_id))
@@ -1896,7 +1900,7 @@
/* First get indication of received lan packet */
/* RX_PKT_CND indicates the number of packets which have been fully */
- /* received onto the card but have not been fully transfered of the card */
+ /* received onto the card but have not been fully transferred of the card */
packets = hp100_inb( RX_PKT_CNT );
#ifdef HP100_DEBUG_RX
if ( packets > 1 )
@@ -1967,11 +1971,6 @@
insl( ioaddr + HP100_REG_DATA32, ptr, pkt_len >> 2 );
skb->protocol = eth_type_trans( skb, dev );
-
- netif_rx( skb );
- dev->last_rx = jiffies;
- lp->stats.rx_packets++;
- lp->stats.rx_bytes += pkt_len;
#ifdef HP100_DEBUG_RX
printk( "hp100: %s: rx: %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x\n",
@@ -1979,6 +1978,10 @@
ptr[ 0 ], ptr[ 1 ], ptr[ 2 ], ptr[ 3 ], ptr[ 4 ], ptr[ 5 ],
ptr[ 6 ], ptr[ 7 ], ptr[ 8 ], ptr[ 9 ], ptr[ 10 ], ptr[ 11 ] );
#endif
+ netif_rx( skb );
+ dev->last_rx = jiffies;
+ lp->stats.rx_packets++;
+ lp->stats.rx_bytes += pkt_len;
}
/* Indicate the card that we have got the packet */
@@ -3017,16 +3020,34 @@
#ifdef MODULE
/* Parameters set by insmod */
-int hp100_port[5] = { 0, -1, -1, -1, -1 };
+static int hp100_port[5] = { 0, -1, -1, -1, -1 };
MODULE_PARM(hp100_port, "1-5i");
/* Allocate 5 string of length IFNAMSIZ, one string for each device */
-char hp100_name[5][IFNAMSIZ] = { "", "", "", "", "" };
+static char hp100_name[5][IFNAMSIZ] = { "", "", "", "", "" };
/* Allow insmod to write those 5 strings individually */
MODULE_PARM(hp100_name, "1-5c" __MODULE_STRING(IFNAMSIZ));
/* List of devices */
-static struct net_device *hp100_devlist[5] = { NULL, NULL, NULL, NULL, NULL };
+static struct net_device *hp100_devlist[5];
+
+static void release_dev(int i)
+{
+ struct net_device *d = hp100_devlist[i];
+ struct hp100_private *p = (struct hp100_private *)d->priv;
+
+ unregister_netdev(d);
+ release_region(d->base_addr, HP100_REGION_SIZE);
+
+ if (p->mode == 1) /* busmaster */
+ kfree(p->page_vaddr);
+ if (p->mem_ptr_virt)
+ iounmap(p->mem_ptr_virt);
+ kfree(d->priv);
+ d->priv = NULL;
+ kfree(d);
+ hp100_devlist[i] = NULL;
+}
/*
* Note: if you have more than five 100vg cards in your pc, feel free to
@@ -3053,6 +3074,8 @@
{
/* Create device and set basics args */
hp100_devlist[i] = kmalloc(sizeof(struct net_device), GFP_KERNEL);
+ if (!hp100_devlist[i])
+ goto fail;
memset(hp100_devlist[i], 0x00, sizeof(struct net_device));
#if LINUX_VERSION_CODE >= 0x020362 /* 2.3.99-pre7 */
memcpy(hp100_devlist[i]->name, hp100_name[i], IFNAMSIZ); /* Copy name */
@@ -3075,6 +3098,13 @@
} /* Loop over all devices */
return cards > 0 ? 0 : -ENODEV;
+ fail:
+ while (cards && --i)
+ if (hp100_devlist[i]) {
+ release_dev(i);
+ --cards;
+ }
+ return -ENOMEM;
}
void cleanup_module( void )
@@ -3084,18 +3114,7 @@
/* TODO: Check if all skb's are released/freed. */
for(i = 0; i < 5; i++)
if(hp100_devlist[i] != (struct net_device *) NULL)
- {
- unregister_netdev( hp100_devlist[i] );
- release_region( hp100_devlist[i]->base_addr, HP100_REGION_SIZE );
- if( ((struct hp100_private *)hp100_devlist[i]->priv)->mode==1 ) /* busmaster */
- kfree( ((struct hp100_private *)hp100_devlist[i]->priv)->page_vaddr );
- if ( ((struct hp100_private *)hp100_devlist[i]->priv) -> mem_ptr_virt )
- iounmap( ((struct hp100_private *)hp100_devlist[i]->priv) -> mem_ptr_virt );
- kfree( hp100_devlist[i]->priv );
- hp100_devlist[i]->priv = NULL;
- kfree(hp100_devlist[i]);
- hp100_devlist[i] = (struct net_device *) NULL;
- }
+ release_dev(i);
}
#endif /* MODULE */
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)