fedora core 6 1.2949 + vserver 2.2.0
[linux-2.6.git] / drivers / usb / net / catc.c
index 455fe6e..4852012 100644 (file)
@@ -43,7 +43,7 @@
 #include <linux/spinlock.h>
 #include <linux/ethtool.h>
 #include <linux/crc32.h>
-#include <asm/bitops.h>
+#include <linux/bitops.h>
 #include <asm/uaccess.h>
 
 #undef DEBUG
@@ -223,7 +223,7 @@ struct catc {
  * Receive routines.
  */
 
-static void catc_rx_done(struct urb *urb, struct pt_regs *regs)
+static void catc_rx_done(struct urb *urb)
 {
        struct catc *catc = urb->context;
        u8 *pkt_start = urb->transfer_buffer;
@@ -289,7 +289,7 @@ static void catc_rx_done(struct urb *urb, struct pt_regs *regs)
        }
 }
 
-static void catc_irq_done(struct urb *urb, struct pt_regs *regs)
+static void catc_irq_done(struct urb *urb)
 {
        struct catc *catc = urb->context;
        u8 *data = urb->transfer_buffer;
@@ -345,7 +345,7 @@ static void catc_irq_done(struct urb *urb, struct pt_regs *regs)
                } 
        }
 resubmit:
-       status = usb_submit_urb (urb, SLAB_ATOMIC);
+       status = usb_submit_urb (urb, GFP_ATOMIC);
        if (status)
                err ("can't resubmit intr, %s-%s, status %d",
                                catc->usbdev->bus->bus_name,
@@ -376,14 +376,13 @@ static void catc_tx_run(struct catc *catc)
        catc->netdev->trans_start = jiffies;
 }
 
-static void catc_tx_done(struct urb *urb, struct pt_regs *regs)
+static void catc_tx_done(struct urb *urb)
 {
        struct catc *catc = urb->context;
        unsigned long flags;
 
        if (urb->status == -ECONNRESET) {
                dbg("Tx Reset.");
-               urb->transfer_flags &= ~URB_ASYNC_UNLINK;
                urb->status = 0;
                catc->netdev->trans_start = jiffies;
                catc->stats.tx_errors++;
@@ -411,7 +410,7 @@ static void catc_tx_done(struct urb *urb, struct pt_regs *regs)
 
 static int catc_hard_start_xmit(struct sk_buff *skb, struct net_device *netdev)
 {
-       struct catc *catc = netdev->priv;
+       struct catc *catc = netdev_priv(netdev);
        unsigned long flags;
        char *tx_buf;
 
@@ -442,10 +441,9 @@ static int catc_hard_start_xmit(struct sk_buff *skb, struct net_device *netdev)
 
 static void catc_tx_timeout(struct net_device *netdev)
 {
-       struct catc *catc = netdev->priv;
+       struct catc *catc = netdev_priv(netdev);
 
        warn("Transmit timed out.");
-       catc->tx_urb->transfer_flags |= URB_ASYNC_UNLINK;
        usb_unlink_urb(catc->tx_urb);
 }
 
@@ -457,7 +455,7 @@ static int catc_ctrl_msg(struct catc *catc, u8 dir, u8 request, u16 value, u16 i
 {
         int retval = usb_control_msg(catc->usbdev,
                dir ? usb_rcvctrlpipe(catc->usbdev, 0) : usb_sndctrlpipe(catc->usbdev, 0),
-                request, 0x40 | dir, value, index, buf, len, HZ);
+                request, 0x40 | dir, value, index, buf, len, 1000);
         return retval < 0 ? retval : 0;
 }
 
@@ -488,7 +486,7 @@ static void catc_ctrl_run(struct catc *catc)
                err("submit(ctrl_urb) status %d", status);
 }
 
-static void catc_ctrl_done(struct urb *urb, struct pt_regs *regs)
+static void catc_ctrl_done(struct urb *urb)
 {
        struct catc *catc = urb->context;
        struct ctrl_queue *q;
@@ -604,7 +602,7 @@ static void catc_stats_timer(unsigned long data)
 
 static struct net_device_stats *catc_get_stats(struct net_device *netdev)
 {
-       struct catc *catc = netdev->priv;
+       struct catc *catc = netdev_priv(netdev);
        return &catc->stats;
 }
 
@@ -622,7 +620,7 @@ static void catc_multicast(unsigned char *addr, u8 *multicast)
 
 static void catc_set_multicast_list(struct net_device *netdev)
 {
-       struct catc *catc = netdev->priv;
+       struct catc *catc = netdev_priv(netdev);
        struct dev_mc_list *mc;
        u8 broadcast[6];
        u8 rx = RxEnable | RxPolarity | RxMultiCast;
@@ -664,74 +662,39 @@ static void catc_set_multicast_list(struct net_device *netdev)
        }
 }
 
-/*
- * ioctl's
- */
-static int netdev_ethtool_ioctl(struct net_device *dev, void __user *useraddr)
+static void catc_get_drvinfo(struct net_device *dev,
+                            struct ethtool_drvinfo *info)
 {
-        struct catc *catc = dev->priv;
-        u32 cmd;
-        
-        if (get_user(cmd, (u32 __user *)useraddr))
-                return -EFAULT;
-
-        switch (cmd) {
-        /* get driver info */
-        case ETHTOOL_GDRVINFO: {
-                struct ethtool_drvinfo info = {ETHTOOL_GDRVINFO};
-                strncpy(info.driver, driver_name, ETHTOOL_BUSINFO_LEN);
-                strncpy(info.version, DRIVER_VERSION, ETHTOOL_BUSINFO_LEN);
-               usb_make_path (catc->usbdev, info.bus_info, sizeof info.bus_info);
-                if (copy_to_user(useraddr, &info, sizeof(info)))
-                        return -EFAULT;
-                return 0;
-        }
-
-       /* get settings */
-       case ETHTOOL_GSET:
-               if (catc->is_f5u011) {
-                       struct ethtool_cmd ecmd = { ETHTOOL_GSET, 
-                                                   SUPPORTED_10baseT_Half | SUPPORTED_TP, 
-                                                   ADVERTISED_10baseT_Half | ADVERTISED_TP, 
-                                                   SPEED_10, 
-                                                   DUPLEX_HALF, 
-                                                   PORT_TP, 
-                                                   0, 
-                                                   XCVR_INTERNAL, 
-                                                   AUTONEG_DISABLE, 
-                                                   1, 
-                                                   1 
-                       };
-                       if (copy_to_user(useraddr, &ecmd, sizeof(ecmd)))
-                               return -EFAULT;
-                       return 0;
-               } else {
-                       return -EOPNOTSUPP;
-               }
-
-        /* get link status */
-        case ETHTOOL_GLINK: {
-                struct ethtool_value edata = {ETHTOOL_GLINK};
-                edata.data = netif_carrier_ok(dev);
-                if (copy_to_user(useraddr, &edata, sizeof(edata)))
-                        return -EFAULT;
-                return 0;
-        }
-       }
-        
-        return -EOPNOTSUPP;
+       struct catc *catc = netdev_priv(dev);
+       strncpy(info->driver, driver_name, ETHTOOL_BUSINFO_LEN);
+       strncpy(info->version, DRIVER_VERSION, ETHTOOL_BUSINFO_LEN);
+       usb_make_path (catc->usbdev, info->bus_info, sizeof info->bus_info);
 }
 
-static int catc_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
+static int catc_get_settings(struct net_device *dev, struct ethtool_cmd *cmd)
 {
-        switch(cmd) {
-        case SIOCETHTOOL:
-                return netdev_ethtool_ioctl(dev, rq->ifr_data);
-        default:
-                return -EOPNOTSUPP;
-        }
+       struct catc *catc = netdev_priv(dev);
+       if (!catc->is_f5u011)
+               return -EOPNOTSUPP;
+
+       cmd->supported = SUPPORTED_10baseT_Half | SUPPORTED_TP;
+       cmd->advertising = ADVERTISED_10baseT_Half | ADVERTISED_TP;
+       cmd->speed = SPEED_10;
+       cmd->duplex = DUPLEX_HALF;
+       cmd->port = PORT_TP; 
+       cmd->phy_address = 0;
+       cmd->transceiver = XCVR_INTERNAL;
+       cmd->autoneg = AUTONEG_DISABLE;
+       cmd->maxtxpkt = 1;
+       cmd->maxrxpkt = 1;
+       return 0;
 }
 
+static struct ethtool_ops ops = {
+       .get_drvinfo = catc_get_drvinfo,
+       .get_settings = catc_get_settings,
+       .get_link = ethtool_op_get_link
+};
 
 /*
  * Open, close.
@@ -739,7 +702,7 @@ static int catc_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
 
 static int catc_open(struct net_device *netdev)
 {
-       struct catc *catc = netdev->priv;
+       struct catc *catc = netdev_priv(netdev);
        int status;
 
        catc->irq_urb->dev = catc->usbdev;
@@ -758,17 +721,17 @@ static int catc_open(struct net_device *netdev)
 
 static int catc_stop(struct net_device *netdev)
 {
-       struct catc *catc = netdev->priv;
+       struct catc *catc = netdev_priv(netdev);
 
        netif_stop_queue(netdev);
 
        if (!catc->is_f5u011)
                del_timer_sync(&catc->timer);
 
-       usb_unlink_urb(catc->rx_urb);
-       usb_unlink_urb(catc->tx_urb);
-       usb_unlink_urb(catc->irq_urb);
-       usb_unlink_urb(catc->ctrl_urb);
+       usb_kill_urb(catc->rx_urb);
+       usb_kill_urb(catc->tx_urb);
+       usb_kill_urb(catc->irq_urb);
+       usb_kill_urb(catc->ctrl_urb);
 
        return 0;
 }
@@ -791,17 +754,11 @@ static int catc_probe(struct usb_interface *intf, const struct usb_device_id *id
                return -EIO;
        }
 
-       catc = kmalloc(sizeof(struct catc), GFP_KERNEL);
-       if (!catc)
+       netdev = alloc_etherdev(sizeof(struct catc));
+       if (!netdev)
                return -ENOMEM;
 
-       memset(catc, 0, sizeof(struct catc));
-
-       netdev = alloc_etherdev(0);
-       if (!netdev) {
-               kfree(catc);
-               return -EIO;
-       }
+       catc = netdev_priv(netdev);
 
        netdev->open = catc_open;
        netdev->hard_start_xmit = catc_hard_start_xmit;
@@ -810,14 +767,13 @@ static int catc_probe(struct usb_interface *intf, const struct usb_device_id *id
        netdev->tx_timeout = catc_tx_timeout;
        netdev->watchdog_timeo = TX_TIMEOUT;
        netdev->set_multicast_list = catc_set_multicast_list;
-       netdev->do_ioctl = catc_ioctl;
-       netdev->priv = catc;
+       SET_ETHTOOL_OPS(netdev, &ops);
 
        catc->usbdev = usbdev;
        catc->netdev = netdev;
 
-       catc->tx_lock = SPIN_LOCK_UNLOCKED;
-       catc->ctrl_lock = SPIN_LOCK_UNLOCKED;
+       spin_lock_init(&catc->tx_lock);
+       spin_lock_init(&catc->ctrl_lock);
 
        init_timer(&catc->timer);
        catc->timer.data = (long) catc;
@@ -830,22 +786,18 @@ static int catc_probe(struct usb_interface *intf, const struct usb_device_id *id
        if ((!catc->ctrl_urb) || (!catc->tx_urb) || 
            (!catc->rx_urb) || (!catc->irq_urb)) {
                err("No free urbs available.");
-               if (catc->ctrl_urb)
-                       usb_free_urb(catc->ctrl_urb);
-               if (catc->tx_urb)
-                       usb_free_urb(catc->tx_urb);
-               if (catc->rx_urb)
-                       usb_free_urb(catc->rx_urb);
-               if (catc->irq_urb)
-                       usb_free_urb(catc->irq_urb);
+               usb_free_urb(catc->ctrl_urb);
+               usb_free_urb(catc->tx_urb);
+               usb_free_urb(catc->rx_urb);
+               usb_free_urb(catc->irq_urb);
                free_netdev(netdev);
-               kfree(catc);
                return -ENOMEM;
        }
 
        /* The F5U011 has the same vendor/product as the netmate but a device version of 0x130 */
-       if (usbdev->descriptor.idVendor == 0x0423 && usbdev->descriptor.idProduct == 0xa &&
-          catc->usbdev->descriptor.bcdDevice == 0x0130 ) {
+       if (le16_to_cpu(usbdev->descriptor.idVendor) == 0x0423 && 
+           le16_to_cpu(usbdev->descriptor.idProduct) == 0xa &&
+           le16_to_cpu(catc->usbdev->descriptor.bcdDevice) == 0x0130) {
                dbg("Testing for f5u011");
                catc->is_f5u011 = 1;            
                atomic_set(&catc->recq_sz, 0);
@@ -944,7 +896,6 @@ static int catc_probe(struct usb_interface *intf, const struct usb_device_id *id
                usb_free_urb(catc->rx_urb);
                usb_free_urb(catc->irq_urb);
                free_netdev(netdev);
-               kfree(catc);
                return -EIO;
        }
        return 0;
@@ -962,7 +913,6 @@ static void catc_disconnect(struct usb_interface *intf)
                usb_free_urb(catc->rx_urb);
                usb_free_urb(catc->irq_urb);
                free_netdev(catc->netdev);
-               kfree(catc);
        }
 }
 
@@ -980,7 +930,6 @@ static struct usb_device_id catc_id_table [] = {
 MODULE_DEVICE_TABLE(usb, catc_id_table);
 
 static struct usb_driver catc_driver = {
-       .owner =        THIS_MODULE,
        .name =         driver_name,
        .probe =        catc_probe,
        .disconnect =   catc_disconnect,