X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=drivers%2Fusb%2Fnet%2Fcatc.c;h=455fe6e3be0639e6dcdefff3111a324a2490a08c;hb=9e1bf581d67d87a1d7fc0ea500729e3a03643a26;hp=c825ef78c1119a1dceab42a3f8f02e6f41f11797;hpb=8d40237c730b8be87c1b80a5d96b9c603fefa829;p=linux-2.6.git diff --git a/drivers/usb/net/catc.c b/drivers/usb/net/catc.c index c825ef78c..455fe6e3b 100644 --- a/drivers/usb/net/catc.c +++ b/drivers/usb/net/catc.c @@ -43,7 +43,7 @@ #include #include #include -#include +#include #include #undef DEBUG @@ -411,7 +411,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(netdev); + struct catc *catc = netdev->priv; unsigned long flags; char *tx_buf; @@ -442,7 +442,7 @@ 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(netdev); + struct catc *catc = netdev->priv; warn("Transmit timed out."); catc->tx_urb->transfer_flags |= URB_ASYNC_UNLINK; @@ -604,7 +604,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(netdev); + struct catc *catc = netdev->priv; return &catc->stats; } @@ -622,7 +622,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(netdev); + struct catc *catc = netdev->priv; struct dev_mc_list *mc; u8 broadcast[6]; u8 rx = RxEnable | RxPolarity | RxMultiCast; @@ -664,38 +664,74 @@ static void catc_set_multicast_list(struct net_device *netdev) } } -void catc_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *info) +/* + * ioctl's + */ +static int netdev_ethtool_ioctl(struct net_device *dev, void __user *useraddr) { - 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); + 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; } -static int catc_get_settings(struct net_device *dev, struct ethtool_cmd *cmd) +static int catc_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) { - 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; + switch(cmd) { + case SIOCETHTOOL: + return netdev_ethtool_ioctl(dev, rq->ifr_data); + default: + return -EOPNOTSUPP; + } } -static struct ethtool_ops ops = { - .get_drvinfo = catc_get_drvinfo, - .get_settings = catc_get_settings, - .get_link = ethtool_op_get_link -}; /* * Open, close. @@ -703,7 +739,7 @@ static struct ethtool_ops ops = { static int catc_open(struct net_device *netdev) { - struct catc *catc = netdev_priv(netdev); + struct catc *catc = netdev->priv; int status; catc->irq_urb->dev = catc->usbdev; @@ -722,17 +758,17 @@ static int catc_open(struct net_device *netdev) static int catc_stop(struct net_device *netdev) { - struct catc *catc = netdev_priv(netdev); + struct catc *catc = netdev->priv; netif_stop_queue(netdev); if (!catc->is_f5u011) del_timer_sync(&catc->timer); - usb_kill_urb(catc->rx_urb); - usb_kill_urb(catc->tx_urb); - usb_kill_urb(catc->irq_urb); - usb_kill_urb(catc->ctrl_urb); + usb_unlink_urb(catc->rx_urb); + usb_unlink_urb(catc->tx_urb); + usb_unlink_urb(catc->irq_urb); + usb_unlink_urb(catc->ctrl_urb); return 0; } @@ -755,11 +791,17 @@ static int catc_probe(struct usb_interface *intf, const struct usb_device_id *id return -EIO; } - netdev = alloc_etherdev(sizeof(struct catc)); - if (!netdev) + catc = kmalloc(sizeof(struct catc), GFP_KERNEL); + if (!catc) return -ENOMEM; - catc = netdev_priv(netdev); + memset(catc, 0, sizeof(struct catc)); + + netdev = alloc_etherdev(0); + if (!netdev) { + kfree(catc); + return -EIO; + } netdev->open = catc_open; netdev->hard_start_xmit = catc_hard_start_xmit; @@ -768,13 +810,14 @@ 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; - SET_ETHTOOL_OPS(netdev, &ops); + netdev->do_ioctl = catc_ioctl; + netdev->priv = catc; catc->usbdev = usbdev; catc->netdev = netdev; - spin_lock_init(&catc->tx_lock); - spin_lock_init(&catc->ctrl_lock); + catc->tx_lock = SPIN_LOCK_UNLOCKED; + catc->ctrl_lock = SPIN_LOCK_UNLOCKED; init_timer(&catc->timer); catc->timer.data = (long) catc; @@ -796,6 +839,7 @@ static int catc_probe(struct usb_interface *intf, const struct usb_device_id *id if (catc->irq_urb) usb_free_urb(catc->irq_urb); free_netdev(netdev); + kfree(catc); return -ENOMEM; } @@ -900,6 +944,7 @@ 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; @@ -917,6 +962,7 @@ 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); } }