]> bbs.cooldavid.org Git - net-next-2.6.git/blobdiff - drivers/usb/net/usbnet.c
WorkStruct: make allyesconfig
[net-next-2.6.git] / drivers / usb / net / usbnet.c
index 98a522f1e264412bc7b15971aee924125930eedd..79b5474fe2343593b41f1ef61d218fe42d159f65 100644 (file)
@@ -158,7 +158,7 @@ int usbnet_get_endpoints(struct usbnet *dev, struct usb_interface *intf)
 }
 EXPORT_SYMBOL_GPL(usbnet_get_endpoints);
 
-static void intr_complete (struct urb *urb, struct pt_regs *regs);
+static void intr_complete (struct urb *urb);
 
 static int init_status (struct usbnet *dev, struct usb_interface *intf)
 {
@@ -295,7 +295,7 @@ EXPORT_SYMBOL_GPL(usbnet_defer_kevent);
 
 /*-------------------------------------------------------------------------*/
 
-static void rx_complete (struct urb *urb, struct pt_regs *regs);
+static void rx_complete (struct urb *urb);
 
 static void rx_submit (struct usbnet *dev, struct urb *urb, gfp_t flags)
 {
@@ -383,7 +383,7 @@ error:
 
 /*-------------------------------------------------------------------------*/
 
-static void rx_complete (struct urb *urb, struct pt_regs *regs)
+static void rx_complete (struct urb *urb)
 {
        struct sk_buff          *skb = (struct sk_buff *) urb->context;
        struct skb_data         *entry = (struct skb_data *) skb->cb;
@@ -467,7 +467,7 @@ block:
                devdbg (dev, "no read resubmitted");
 }
 
-static void intr_complete (struct urb *urb, struct pt_regs *regs)
+static void intr_complete (struct urb *urb)
 {
        struct usbnet   *dev = urb->context;
        int             status = urb->status;
@@ -554,7 +554,7 @@ static int usbnet_stop (struct net_device *net)
 {
        struct usbnet           *dev = netdev_priv(net);
        int                     temp;
-       DECLARE_WAIT_QUEUE_HEAD (unlink_wakeup); 
+       DECLARE_WAIT_QUEUE_HEAD_ONSTACK (unlink_wakeup);
        DECLARE_WAITQUEUE (wait, current);
 
        netif_stop_queue (net);
@@ -669,20 +669,40 @@ done:
  * they'll probably want to use this base set.
  */
 
-void usbnet_get_drvinfo (struct net_device *net, struct ethtool_drvinfo *info)
+#if defined(CONFIG_MII) || defined(CONFIG_MII_MODULE)
+#define HAVE_MII
+
+int usbnet_get_settings (struct net_device *net, struct ethtool_cmd *cmd)
 {
        struct usbnet *dev = netdev_priv(net);
 
-       /* REVISIT don't always return "usbnet" */
-       strncpy (info->driver, driver_name, sizeof info->driver);
-       strncpy (info->version, DRIVER_VERSION, sizeof info->version);
-       strncpy (info->fw_version, dev->driver_info->description,
-               sizeof info->fw_version);
-       usb_make_path (dev->udev, info->bus_info, sizeof info->bus_info);
+       if (!dev->mii.mdio_read)
+               return -EOPNOTSUPP;
+
+       return mii_ethtool_gset(&dev->mii, cmd);
 }
-EXPORT_SYMBOL_GPL(usbnet_get_drvinfo);
+EXPORT_SYMBOL_GPL(usbnet_get_settings);
+
+int usbnet_set_settings (struct net_device *net, struct ethtool_cmd *cmd)
+{
+       struct usbnet *dev = netdev_priv(net);
+       int retval;
+
+       if (!dev->mii.mdio_write)
+               return -EOPNOTSUPP;
 
-static u32 usbnet_get_link (struct net_device *net)
+       retval = mii_ethtool_sset(&dev->mii, cmd);
+
+       /* link speed/duplex might have changed */
+       if (dev->driver_info->link_reset)
+               dev->driver_info->link_reset(dev);
+
+       return retval;
+
+}
+EXPORT_SYMBOL_GPL(usbnet_set_settings);
+
+u32 usbnet_get_link (struct net_device *net)
 {
        struct usbnet *dev = netdev_priv(net);
 
@@ -690,9 +710,40 @@ static u32 usbnet_get_link (struct net_device *net)
        if (dev->driver_info->check_connect)
                return dev->driver_info->check_connect (dev) == 0;
 
+       /* if the device has mii operations, use those */
+       if (dev->mii.mdio_read)
+               return mii_link_ok(&dev->mii);
+
        /* Otherwise, say we're up (to avoid breaking scripts) */
        return 1;
 }
+EXPORT_SYMBOL_GPL(usbnet_get_link);
+
+int usbnet_nway_reset(struct net_device *net)
+{
+       struct usbnet *dev = netdev_priv(net);
+
+       if (!dev->mii.mdio_write)
+               return -EOPNOTSUPP;
+
+       return mii_nway_restart(&dev->mii);
+}
+EXPORT_SYMBOL_GPL(usbnet_nway_reset);
+
+#endif /* HAVE_MII */
+
+void usbnet_get_drvinfo (struct net_device *net, struct ethtool_drvinfo *info)
+{
+       struct usbnet *dev = netdev_priv(net);
+
+       /* REVISIT don't always return "usbnet" */
+       strncpy (info->driver, driver_name, sizeof info->driver);
+       strncpy (info->version, DRIVER_VERSION, sizeof info->version);
+       strncpy (info->fw_version, dev->driver_info->description,
+               sizeof info->fw_version);
+       usb_make_path (dev->udev, info->bus_info, sizeof info->bus_info);
+}
+EXPORT_SYMBOL_GPL(usbnet_get_drvinfo);
 
 u32 usbnet_get_msglevel (struct net_device *net)
 {
@@ -712,8 +763,13 @@ EXPORT_SYMBOL_GPL(usbnet_set_msglevel);
 
 /* drivers may override default ethtool_ops in their bind() routine */
 static struct ethtool_ops usbnet_ethtool_ops = {
-       .get_drvinfo            = usbnet_get_drvinfo,
+#ifdef HAVE_MII
+       .get_settings           = usbnet_get_settings,
+       .set_settings           = usbnet_set_settings,
        .get_link               = usbnet_get_link,
+       .nway_reset             = usbnet_nway_reset,
+#endif
+       .get_drvinfo            = usbnet_get_drvinfo,
        .get_msglevel           = usbnet_get_msglevel,
        .set_msglevel           = usbnet_set_msglevel,
 };
@@ -726,9 +782,10 @@ static struct ethtool_ops usbnet_ethtool_ops = {
  * especially now that control transfers can be queued.
  */
 static void
-kevent (void *data)
+kevent (struct work_struct *work)
 {
-       struct usbnet           *dev = data;
+       struct usbnet           *dev =
+               container_of(work, struct usbnet, kevent);
        int                     status;
 
        /* usb_clear_halt() needs a thread context */
@@ -797,7 +854,7 @@ kevent (void *data)
 
 /*-------------------------------------------------------------------------*/
 
-static void tx_complete (struct urb *urb, struct pt_regs *regs)
+static void tx_complete (struct urb *urb)
 {
        struct sk_buff          *skb = (struct sk_buff *) urb->context;
        struct skb_data         *entry = (struct skb_data *) skb->cb;
@@ -1090,10 +1147,11 @@ usbnet_probe (struct usb_interface *udev, const struct usb_device_id *prod)
        skb_queue_head_init (&dev->done);
        dev->bh.func = usbnet_bh;
        dev->bh.data = (unsigned long) dev;
-       INIT_WORK (&dev->kevent, kevent, dev);
+       INIT_WORK (&dev->kevent, kevent);
        dev->delay.function = usbnet_bh;
        dev->delay.data = (unsigned long) dev;
        init_timer (&dev->delay);
+       mutex_init (&dev->phy_mutex);
 
        SET_MODULE_OWNER (net);
        dev->net = net;
@@ -1225,7 +1283,7 @@ EXPORT_SYMBOL_GPL(usbnet_resume);
 static int __init usbnet_init(void)
 {
        /* compiler should optimize this out */
-       BUG_ON (sizeof (((struct sk_buff *)0)->cb)
+       BUILD_BUG_ON (sizeof (((struct sk_buff *)0)->cb)
                        < sizeof (struct skb_data));
 
        random_ether_addr(node_id);