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

Reply via email to