On Saturday 01 April 2006 15:50, Linsys Contractor Amit S. Kale wrote:
Not a full review, just what I noticed from a quick read.
> +static int
> +netxen_loopback_test(struct net_device *netdev, int fint, void *ptr)
[... lots of self test code snipped ...]
Isn't that a bit too much self test infrastructure for a production
driver? Would be better if you put that into a separate module
and perhaps not include it.
BTW you might end up with a name space collision with the xen people
with that prefix. Better double check everything is static or use something
more unique.
Your white space probably needs some improvement. Maybe a Lindent run.
> +static int
> +netxen_nic_ioctl(struct net_device *netdev, struct ifreq *ifr, int cmd)
> +{
I believe custom ioctls like this are strongly discouraged. Any statistics
should go through ethtool and the rest probably doesn't belong in there.
> + netif_device_detach(netdev);
> +
> + if(netif_running(netdev)) {
> + netif_carrier_off(netdev);
> + netif_stop_queue(netdev);
> + port->state = PORT_SUSPEND;
> + netxen_nic_down(port);
> + }
I don't think resume functions are supposed to mess with
the upper layer queueing like this. They should keep
that the same or perhaps only do a netif_detach_device()
> +
> +/* pci_save_state(pdev, port->pci_state); */
> +/* pci_disable_device(pdev); */
> +
> + return 0;
> +}
> +
> +static int
> +netxen_nic_resume(struct pci_dev *pdev)
> +{
> + uint32_t ret;
> + struct net_device *netdev = pci_get_drvdata(pdev);
> + struct netxen_port *port = netdev->priv;
> + ret = pci_enable_device(pdev);
> + port->state = PORT_UP;
> + netif_device_attach(netdev);
> + return ret;
So what reinitializes the device registers? Looks broken.
> + unsigned long flags;
> + void* addr;
> + if(adapter->ahw.board_type == NetXen_NIC_XGBE) {
> + write_lock_irqsave(&adapter->adapter_lock, flags);
> + netxen_nic_pci_change_crbwindow(adapter, 0);
> + NetXen_NIC_LOCKED_READ_REG(NetXen_NIU_XGE_TX_BYTE_CNT,
> &(netxen_stats->tx_bytes));
Your identifiers are far too long and redundant.
> + switch (data.cmd) {
> + case netxen_nic_cmd_pci_read:
Again looks like a lot of debugging support that shouldn't be there.
> + case netxen_nic_cmd_pci_config_read:
Especially that since Linux already has other ways to read/write
config space.
> +static int
> +netxen_nic_port_read_proc(char *buf, char **start, off_t offset, int count,
> + int *eof, void *data)
> +{
This should be probably in ethtool
> + printk(KERN_INFO "%s \n", netxen_nic_driver_string);
In general drivers shouldn't print anything when no hardware is found.
> + netxen_proc_dir_entry = proc_mkdir(netxen_nic_driver_name, proc_net);
> + if (!netxen_proc_dir_entry) {
> + printk(KERN_WARNING "%s: Unable to create /proc/net/%s",
> + netxen_nic_driver_name,
> netxen_nic_driver_name);
> + return -ENOMEM;
> + }
> + netxen_proc_dir_entry->owner = THIS_MODULE;
> +
> + cmd_desc_cache = kmem_cache_create("cmd_desc_cache",
> + sizeof(cmdDescType0_t) * ((MAX_BUFFERS_PER_CMD/4)+3),
> + ARCH_KMALLOC_MINALIGN, ARCH_KMALLOC_FLAGS, NULL, NULL);
> + cmd_buff_cache = kmem_cache_create("cmd_buff_cache",
> + sizeof(struct netxen_cmd_buffer), ARCH_KMALLOC_MINALIGN,
> + ARCH_KMALLOC_FLAGS, NULL, NULL);
> + for (i=0; i<NR_CPUS; i++) {
> + cmd_desc_array[i] =
> + (cmdDescType0_t *) kmem_cache_alloc (cmd_desc_cache,
> + SLAB_ATOMIC);
> + cmd_buff_array[i] =
> + (struct netxen_cmd_buffer *) kmem_cache_alloc
> (cmd_buff_cache,
> + SLAB_ATOMIC);
Lots of NULL pointer checks missing.
And you shouldn't use GFP_ATOMIC here since it's unreliable and not needed since
you don't hold any locks.
>
> + if (tx_user_packet_data != NULL) {
> + kfree(tx_user_packet_data);
> + tx_user_packet_data = NULL;
> + tx_user_packet_length = 0;
> + }
> + for(i=0; i<MAX_NUM_CARDS; i++)
> + {
> + adapter = adapterlist[i];
> + if (adapter == NULL)
> + continue;
> + if (adapter->netlist != NULL && adapter->netlist->netdev !=
> NULL) {
> +/* struct net_device *netdev = netxen_netlist->netdev;
> + struct netxen_port *port = netdev->priv;
> + struct netxen_adapter_s *adapter = port->adapter;
> +*/
> + read_lock(&adapter->adapter_lock);
In general rw locks should be only used when absolutely needed because
they're much slower than normal spinlocks.
> + netxen_nic_disable_int(adapter);
> + read_unlock(&adapter->adapter_lock);
> + /*
> + * Wait for some time to allow the dma to drain, if any.
> + */
> + mdelay(5);
This is not enough to make sure the interrupt handler can't execute
on any CPU anymore I think.
> + pci_unregister_driver(&netxen_driver);
> + remove_proc_entry(netxen_proc_dir_entry->name, proc_net);
> + for (i=0; i<NR_CPUS; i++) {
Using NR_CPUS like this is bad because it can be very large and waste lots of
memory.
Use for_each_possible_cpu. And consider using per cpu data.
-Andi
-
To unsubscribe from this list: send the line "unsubscribe netdev" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at http://vger.kernel.org/majordomo-info.html