Messages in this thread Patch in this message |  | | From | Jean Tourrilhes <> | Subject | hp100 - device naming patch | Date | Wed, 12 Feb 1997 20:05:17 +0000 (GMT) |
| |
Hi,
This is the second version of my "device naming" patch for the 100vg network driver. I already send it to the 100vg maintainer, but I send it also to the list because : o It has been updated o 100vg maintainers are a bit slow (first version was in october) o It migh interest other network driver maintainers
What's device naming ? Nothing really complicated. I've got a laptop with a pcmcia socket and a docking station, in the docking station a 100vg card and in the pcmcia slot a Wavelan card. If I start docked, 100vg is eth0 and Wavelan is eth1. If I start undocked, Wavelan is eth0. Then, if I dock, 100vg is eth1. The pcmcia package adapt quite well, but normal configuration scripts require that the card is at a fixed name. With device naming, I set [options hp100 hp100_name=eth2] in /etc/conf.modules and 100vg is *always* eth2. eth0 and eth1 are free for the pcmcia socket. It might also be used if you don't like "eth#" and want to use other name.
This stuff is already implemented in a sligthly different way in the Wavelan driver (but, who care about the Wavelan ?). Of course, to use that patch, you need the new version of insmod which hasn't been yet released. That's the bleeding edge of the kernel development !
Have fun with that, and sorry to be so talkative...
Jean
P.S. : I'm new to the list, so I don't know if it should really be there. I'm just trying to understand the instructions in the MAINTAINERS file. This patch is quite small, but I've got a *big* one for the Wavelan in 2.0.29 to send...
-----------------------------------------
diff -u --recursive --new-file /usr/src/kernel-source-2.1.26b/drivers/net/hp100.c /usr/src/linux/drivers/net/hp100.c --- /usr/src/kernel-source-2.1.26b/drivers/net/hp100.c Sun Feb 2 19:50:59 1997 +++ /usr/src/linux/drivers/net/hp100.c Mon Feb 10 20:13:31 1997 @@ -1098,36 +1098,77 @@ #ifdef MODULE -static int hp100_port = -1; -MODULE_PARM(hp100_port, "i"); +/* Parameters set by insmod */ +static int hp100_port[5] = { 0, -1, -1, -1, -1 }; +MODULE_PARM(hp100_port, "1-5i"); -static char devicename[9] = { 0, }; -static struct device dev_hp100 = { - devicename, /* device name is inserted by linux/drivers/net/net_init.c */ - 0, 0, 0, 0, - 0, 0, - 0, 0, 0, NULL, hp100_probe -}; +static char hp100_name[5][IFNAMSIZ] = { "", "", "", "", "" }; +MODULE_PARM(hp100_name, "1-5c" __MODULE_STRING(IFNAMSIZ)); + +/* List of devices */ +static struct device *hp100_devlist[5] = { NULL, NULL, NULL, NULL, NULL }; + +/* Note : if you have more that 5 100vg card in your pc, feel free to + * increase this value :-) + */ + +/* Note : to register three eisa or pci device, do : + * option hp100 hp100_port=0,0,0 + * to register 1 card at io 0x280 as eth239, do : + * option hp100 hp100_port=0x280 hp100_name=eth239 + */ int init_module( void ) { + int i; + int ret = 0; + if (hp100_port == 0 && !EISA_bus) printk("HP100: You should not use auto-probing with insmod!\n"); - if ( hp100_port > 0 ) - dev_hp100.base_addr = hp100_port; - if ( register_netdev( &dev_hp100 ) != 0 ) - return -EIO; - return 0; + + /* Loop on all possible base addresses */ + i = -1; + while((hp100_port[++i] != -1) && (i < 5)) + { + /* Create device and set basics args */ + hp100_devlist[i] = kmalloc(sizeof(struct device), GFP_KERNEL); + memset(hp100_devlist[i], 0x00, sizeof(struct device)); + hp100_devlist[i]->name = hp100_name[i]; + hp100_devlist[i]->base_addr = hp100_port[i]; + hp100_devlist[i]->init = &hp100_probe; + + /* Try to create the device */ + if(register_netdev(hp100_devlist[i]) != 0) + { + /* DeAllocate everything */ + /* Note : if dev->priv is mallocated, there is no way to fail */ + kfree_s(hp100_devlist[i], sizeof(struct device)); + hp100_devlist[i] = (struct device *) NULL; + ret = -EIO; + } + } /* Loop on all devices */ + + return ret; } void cleanup_module( void ) { - unregister_netdev( &dev_hp100 ); - release_region( dev_hp100.base_addr, HP100_REGION_SIZE ); - if ( ((struct hp100_private *)dev_hp100.priv) -> mem_ptr_virt ) - iounmap( ((struct hp100_private *)dev_hp100.priv) -> mem_ptr_virt ); - kfree_s( dev_hp100.priv, sizeof( struct hp100_private ) ); - dev_hp100.priv = NULL; + int i; + + for(i = 0; i < 5; i++) + if(hp100_devlist[i] != (struct 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) -> mem_ptr_virt ) + iounmap( ((struct hp100_private *) + hp100_devlist[i]->priv) -> mem_ptr_virt ); + kfree_s( hp100_devlist[i]->priv, sizeof( struct hp100_private ) ); + hp100_devlist[i]->priv = NULL; + kfree_s(hp100_devlist[i], sizeof(struct device)); + hp100_devlist[i] = (struct device *) NULL; + } } #endif
|  |