* - GeneSys GL620USB-A
* - NetChip 1080 (interoperates with NetChip Win32 drivers)
* - Prolific PL-2301/2302 (replaces "plusb" driver)
+ * - KC Technology KC2190
*
* + Smart USB devices can support such links directly, using Internet
* standard protocols instead of proprietary host-to-device links.
* 22-aug-2003 AX8817X support (Dave Hollis).
* 14-jun-2004 Trivial patch for AX8817X based Buffalo LUA-U2-KTX in Japan
* (Neil Bortnak)
+ * 03-nov-2004 Trivial patch for KC2190 (KC-190) chip. (Jonathan McDowell)
*
*-------------------------------------------------------------------------*/
#include <linux/mm.h>
#include <linux/dma-mapping.h>
-#define DRIVER_VERSION "25-Aug-2003"
+#define DRIVER_VERSION "03-Nov-2004"
/*-------------------------------------------------------------------------*/
devdbg(dev, "ax8817x - Link Status is: %d", link);
}
}
- usb_submit_urb(data->int_urb, GFP_KERNEL);
+ usb_submit_urb(data->int_urb, GFP_ATOMIC);
}
}
static void ax8817x_set_multicast(struct net_device *net)
{
- struct usbnet *dev = (struct usbnet *) net->priv;
+ struct usbnet *dev = netdev_priv(net);
struct ax8817x_data *data = (struct ax8817x_data *)&dev->data;
u8 rx_ctl = 0x8c;
static int ax8817x_mdio_read(struct net_device *netdev, int phy_id, int loc)
{
- struct usbnet *dev = netdev->priv;
+ struct usbnet *dev = netdev_priv(netdev);
u16 res;
u8 buf[1];
static void ax8817x_mdio_write(struct net_device *netdev, int phy_id, int loc, int val)
{
- struct usbnet *dev = netdev->priv;
+ struct usbnet *dev = netdev_priv(netdev);
u16 res = val;
u8 buf[1];
static void ax8817x_get_wol(struct net_device *net, struct ethtool_wolinfo *wolinfo)
{
- struct usbnet *dev = (struct usbnet *)net->priv;
+ struct usbnet *dev = netdev_priv(net);
u8 opt;
if (ax8817x_read_cmd(dev, AX_CMD_READ_MONITOR_MODE, 0, 0, 1, &opt) < 0) {
static int ax8817x_set_wol(struct net_device *net, struct ethtool_wolinfo *wolinfo)
{
- struct usbnet *dev = (struct usbnet *)net->priv;
+ struct usbnet *dev = netdev_priv(net);
u8 opt = 0;
u8 buf[1];
static int ax8817x_get_eeprom(struct net_device *net,
struct ethtool_eeprom *eeprom, u8 *data)
{
- struct usbnet *dev = (struct usbnet *)net->priv;
+ struct usbnet *dev = netdev_priv(net);
u16 *ebuf = (u16 *)data;
int i;
static int ax8817x_get_settings(struct net_device *net, struct ethtool_cmd *cmd)
{
- struct usbnet *dev = (struct usbnet *)net->priv;
+ struct usbnet *dev = netdev_priv(net);
return mii_ethtool_gset(&dev->mii,cmd);
}
static int ax8817x_set_settings(struct net_device *net, struct ethtool_cmd *cmd)
{
- struct usbnet *dev = (struct usbnet *)net->priv;
+ struct usbnet *dev = netdev_priv(net);
return mii_ethtool_sset(&dev->mii,cmd);
}
dev->out = usb_sndbulkpipe(dev->udev, 2);
// allocate irq urb
- if ((data->int_urb = usb_alloc_urb (0, GFP_KERNEL)) == 0) {
+ if ((data->int_urb = usb_alloc_urb (0, GFP_KERNEL)) == NULL) {
dbg ("%s: cannot allocate interrupt URB",
dev->net->name);
return -ENOMEM;
{
struct ax8817x_data *data = (struct ax8817x_data *)dev->data;
- usb_unlink_urb(data->int_urb);
+ usb_kill_urb(data->int_urb);
usb_free_urb(data->int_urb);
kfree(data->int_buf);
}
struct gl_packet packets;
};
-#ifdef GENLINK_ACK
+#ifdef GENELINK_ACK
// FIXME: this code is incomplete, not debugged; it doesn't
// handle interrupts correctly. interrupts should be generic
// handling needs to be generic)
// cancel irq urb first
- usb_unlink_urb (priv->irq_urb);
+ usb_kill_urb (priv->irq_urb);
// free irq urb
usb_free_urb (priv->irq_urb);
#endif /* CONFIG_USB_PL2301 */
+\f
+#ifdef CONFIG_USB_KC2190
+#define HAVE_HARDWARE
+static const struct driver_info kc2190_info = {
+ .description = "KC Technology KC-190",
+};
+#endif /* CONFIG_USB_KC2190 */
\f
#ifdef CONFIG_USB_ARMLINUX
.unbind = cdc_unbind,
.tx_fixup = zaurus_tx_fixup,
};
+#define ZAURUS_STRONGARM_INFO ((unsigned long)&zaurus_sl5x00_info)
+
static const struct driver_info zaurus_pxa_info = {
.description = "Sharp Zaurus, PXA-2xx based",
.flags = FLAG_FRAMING_Z,
.check_connect = always_connected,
+ .bind = generic_cdc_bind,
+ .unbind = cdc_unbind,
.tx_fixup = zaurus_tx_fixup,
+};
+#define ZAURUS_PXA_INFO ((unsigned long)&zaurus_pxa_info)
- .in = 1, .out = 2,
+static const struct driver_info olympus_mxl_info = {
+ .description = "Olympus R1000",
+ .flags = FLAG_FRAMING_Z,
+ .check_connect = always_connected,
+ .bind = generic_cdc_bind,
+ .unbind = cdc_unbind,
+ .tx_fixup = zaurus_tx_fixup,
};
+#define OLYMPUS_MXL_INFO ((unsigned long)&olympus_mxl_info)
+
+#else
+
+/* blacklist all those devices */
+#define ZAURUS_STRONGARM_INFO 0
+#define ZAURUS_PXA_INFO 0
+#define OLYMPUS_MXL_INFO 0
#endif
static int usbnet_change_mtu (struct net_device *net, int new_mtu)
{
- struct usbnet *dev = (struct usbnet *) net->priv;
+ struct usbnet *dev = netdev_priv(net);
if (new_mtu <= MIN_PACKET || new_mtu > MAX_PACKET)
return -EINVAL;
static struct net_device_stats *usbnet_get_stats (struct net_device *net)
{
- return &((struct usbnet *) net->priv)->stats;
+ struct usbnet *dev = netdev_priv(net);
+ return &dev->stats;
}
/*-------------------------------------------------------------------------*/
#endif
size = (sizeof (struct ethhdr) + dev->net->mtu);
- if ((skb = alloc_skb (size, flags)) == 0) {
+ if ((skb = alloc_skb (size, flags)) == NULL) {
devdbg (dev, "no rx skb");
defer_kevent (dev, EVENT_RX_MEMORY);
usb_free_urb (urb);
static int usbnet_stop (struct net_device *net)
{
- struct usbnet *dev = (struct usbnet *) net->priv;
+ struct usbnet *dev = netdev_priv(net);
int temp;
DECLARE_WAIT_QUEUE_HEAD (unlink_wakeup);
DECLARE_WAITQUEUE (wait, current);
static int usbnet_open (struct net_device *net)
{
- struct usbnet *dev = (struct usbnet *) net->priv;
+ struct usbnet *dev = netdev_priv(net);
int retval = 0;
struct driver_info *info = dev->driver_info;
static void usbnet_get_drvinfo (struct net_device *net, struct ethtool_drvinfo *info)
{
- struct usbnet *dev = net->priv;
+ struct usbnet *dev = netdev_priv(net);
strncpy (info->driver, driver_name, sizeof info->driver);
strncpy (info->version, DRIVER_VERSION, sizeof info->version);
static u32 usbnet_get_link (struct net_device *net)
{
- struct usbnet *dev = net->priv;
+ struct usbnet *dev = netdev_priv(net);
/* If a check_connect is defined, return it's results */
if (dev->driver_info->check_connect)
static u32 usbnet_get_msglevel (struct net_device *net)
{
- struct usbnet *dev = net->priv;
+ struct usbnet *dev = netdev_priv(net);
return dev->msg_level;
}
static void usbnet_set_msglevel (struct net_device *net, u32 level)
{
- struct usbnet *dev = net->priv;
+ struct usbnet *dev = netdev_priv(net);
dev->msg_level = level;
}
{
#ifdef NEED_MII
{
- struct usbnet *dev = (struct usbnet *)net->priv;
+ struct usbnet *dev = netdev_priv(net);
if (dev->mii.mdio_read != NULL && dev->mii.mdio_write != NULL)
return generic_mii_ioctl(&dev->mii, if_mii(rq), cmd, NULL);
if (test_bit (EVENT_TX_HALT, &dev->flags)) {
unlink_urbs (dev, &dev->txq);
status = usb_clear_halt (dev->udev, dev->out);
- if (status < 0)
+ if (status < 0 && status != -EPIPE)
deverr (dev, "can't clear tx halt, status %d",
status);
else {
if (test_bit (EVENT_RX_HALT, &dev->flags)) {
unlink_urbs (dev, &dev->rxq);
status = usb_clear_halt (dev->udev, dev->in);
- if (status < 0)
+ if (status < 0 && status != -EPIPE)
deverr (dev, "can't clear rx halt, status %d",
status);
else {
urb = usb_alloc_urb (0, GFP_KERNEL);
else
clear_bit (EVENT_RX_MEMORY, &dev->flags);
- if (urb != 0) {
+ if (urb != NULL) {
clear_bit (EVENT_RX_MEMORY, &dev->flags);
rx_submit (dev, urb, GFP_KERNEL);
tasklet_schedule (&dev->bh);
static void usbnet_tx_timeout (struct net_device *net)
{
- struct usbnet *dev = (struct usbnet *) net->priv;
+ struct usbnet *dev = netdev_priv(net);
unlink_urbs (dev, &dev->txq);
tasklet_schedule (&dev->bh);
static int usbnet_start_xmit (struct sk_buff *skb, struct net_device *net)
{
- struct usbnet *dev = (struct usbnet *) net->priv;
+ struct usbnet *dev = netdev_priv(net);
int length;
int retval = NET_XMIT_SUCCESS;
struct urb *urb = NULL;
// don't refill the queue all at once
for (i = 0; i < 10 && dev->rxq.qlen < qlen; i++) {
- if ((urb = usb_alloc_urb (0, GFP_ATOMIC)) != 0)
+ urb = usb_alloc_urb (0, GFP_ATOMIC);
+ if (urb != NULL)
rx_submit (dev, urb, GFP_ATOMIC);
}
if (temp != dev->rxq.qlen)
{
struct usbnet *dev;
struct usb_device *xdev;
+ struct net_device *net;
dev = usb_get_intfdata(intf);
usb_set_intfdata(intf, NULL);
xdev->bus->bus_name, xdev->devpath,
dev->driver_info->description);
- unregister_netdev (dev->net);
+ net = dev->net;
+ unregister_netdev (net);
/* we don't hold rtnl here ... */
flush_scheduled_work ();
if (dev->driver_info->unbind)
dev->driver_info->unbind (dev, intf);
- free_netdev(dev->net);
- kfree (dev);
+ free_netdev(net);
usb_put_dev (xdev);
}
status = -ENOMEM;
// set up our own records
- if (!(dev = kmalloc (sizeof *dev, GFP_KERNEL))) {
+ net = alloc_etherdev(sizeof(*dev));
+ if (!net) {
dbg ("can't kmalloc dev");
goto out;
}
- memset (dev, 0, sizeof *dev);
+ dev = netdev_priv(net);
dev->udev = xdev;
dev->driver_info = info;
dev->msg_level = msg_level;
dev->delay.data = (unsigned long) dev;
init_timer (&dev->delay);
- // set up network interface records
- net = alloc_etherdev(0);
- if (!net)
- goto out1;
-
SET_MODULE_OWNER (net);
dev->net = net;
- net->priv = dev;
strcpy (net->name, "usb%d");
memcpy (net->dev_addr, node_id, sizeof node_id);
dev->maxpacket = usb_maxpacket (dev->udev, dev->out, 1);
- SET_NETDEV_DEV(dev->net, &udev->dev);
- status = register_netdev (dev->net);
+ SET_NETDEV_DEV(net, &udev->dev);
+ status = register_netdev (net);
if (status)
goto out3;
devinfo (dev, "register usbnet at usb-%s-%s, %s",
usb_set_intfdata (udev, dev);
// start as if the link is up
- netif_device_attach (dev->net);
+ netif_device_attach (net);
return 0;
out3:
if (info->unbind)
info->unbind (dev, udev);
- free_netdev(net);
out1:
- kfree(dev);
+ free_netdev(net);
out:
usb_put_dev(xdev);
return status;
// Sitecom LN-029 "USB 2.0 10/100 Ethernet adapter"
USB_DEVICE (0x6189, 0x182d),
.driver_info = (unsigned long) &ax8817x_info,
+}, {
+ // corega FEther USB2-TX
+ USB_DEVICE (0x07aa, 0x0017),
+ .driver_info = (unsigned long) &ax8817x_info,
+}, {
+ // Surecom EP-1427X-2
+ USB_DEVICE (0x1189, 0x0893),
+ .driver_info = (unsigned long) &ax8817x_info,
+}, {
+ // goodway corp usb gwusb2e
+ USB_DEVICE (0x1631, 0x6200),
+ .driver_info = (unsigned long) &ax8817x_info,
},
#endif
},
#endif
+#ifdef CONFIG_USB_KC2190
+{
+ USB_DEVICE (0x050f, 0x0190), // KC-190
+ .driver_info = (unsigned long) &kc2190_info,
+},
+#endif
+
#ifdef CONFIG_USB_RNDIS
{
/* RNDIS is MSFT's un-official variant of CDC ACM */
*
* PXA25x or PXA210 ... these use a "usb-eth" driver much like
* the sa1100 one, but hardware uses different endpoint numbers.
+ *
+ * Or the Linux "Ethernet" gadget on hardware that can't talk
+ * CDC Ethernet (e.g., no altsettings), in either of two modes:
+ * - acting just like the old "usb-eth" firmware, though
+ * the implementation is different
+ * - supporting RNDIS as the first/default configuration for
+ * MS-Windows interop; Linux needs to use the other config
*/
{
// 1183 = 0x049F, both used as hex values?
// Compaq "Itsy" vendor/product id
- USB_DEVICE (0x049F, 0x505A),
+ USB_DEVICE (0x049F, 0x505A), // usb-eth, or compatible
.driver_info = (unsigned long) &linuxdev_info,
}, {
USB_DEVICE (0x0E7E, 0x1001), // G.Mate "Yopy"
}, {
USB_DEVICE (0x8086, 0x07d3), // "blob" bootloader
.driver_info = (unsigned long) &blob_info,
+}, {
+ // Linux Ethernet/RNDIS gadget on pxa210/25x/26x
+ USB_DEVICE_VER (0x0525, 0xa4a2, 0x0203, 0x0203),
+ .driver_info = (unsigned long) &linuxdev_info,
},
#endif
-#ifdef CONFIG_USB_ZAURUS
+#if defined(CONFIG_USB_ZAURUS) || defined(CONFIG_USB_CDCETHER)
/*
* SA-1100 based Sharp Zaurus ("collie"), or compatible.
* Same idea as above, but different framing.
*
* PXA-2xx based models are also lying-about-cdc.
+ *
+ * NOTE: These entries do double-duty, serving as blacklist entries
+ * whenever Zaurus support isn't enabled, but CDC Ethernet is.
*/
{
.match_flags = USB_DEVICE_ID_MATCH_INT_INFO
.bInterfaceClass = USB_CLASS_COMM,
.bInterfaceSubClass = 6 /* Ethernet model */,
.bInterfaceProtocol = 0,
- .driver_info = (unsigned long) &zaurus_sl5x00_info,
+ .driver_info = ZAURUS_STRONGARM_INFO,
}, {
.match_flags = USB_DEVICE_ID_MATCH_INT_INFO
| USB_DEVICE_ID_MATCH_DEVICE,
.idVendor = 0x04DD,
.idProduct = 0x8005, /* A-300 */
- .bInterfaceClass = 0x02,
- .bInterfaceSubClass = 0x0a,
+ .bInterfaceClass = USB_CLASS_COMM,
+ .bInterfaceSubClass = 6 /* Ethernet model */,
.bInterfaceProtocol = 0x00,
- .driver_info = (unsigned long) &zaurus_pxa_info,
+ .driver_info = ZAURUS_PXA_INFO,
}, {
.match_flags = USB_DEVICE_ID_MATCH_INT_INFO
| USB_DEVICE_ID_MATCH_DEVICE,
.idVendor = 0x04DD,
.idProduct = 0x8006, /* B-500/SL-5600 */
- .bInterfaceClass = 0x02,
- .bInterfaceSubClass = 0x0a,
+ .bInterfaceClass = USB_CLASS_COMM,
+ .bInterfaceSubClass = 6 /* Ethernet model */,
.bInterfaceProtocol = 0x00,
- .driver_info = (unsigned long) &zaurus_pxa_info,
+ .driver_info = ZAURUS_PXA_INFO,
}, {
.match_flags = USB_DEVICE_ID_MATCH_INT_INFO
| USB_DEVICE_ID_MATCH_DEVICE,
.idVendor = 0x04DD,
.idProduct = 0x8007, /* C-700 */
- .bInterfaceClass = 0x02,
- .bInterfaceSubClass = 0x0a,
+ .bInterfaceClass = USB_CLASS_COMM,
+ .bInterfaceSubClass = 6 /* Ethernet model */,
.bInterfaceProtocol = 0x00,
- .driver_info = (unsigned long) &zaurus_pxa_info,
+ .driver_info = ZAURUS_PXA_INFO,
}, {
.match_flags = USB_DEVICE_ID_MATCH_INT_INFO
| USB_DEVICE_ID_MATCH_DEVICE,
.idVendor = 0x04DD,
.idProduct = 0x9031, /* C-750 C-760 */
- .bInterfaceClass = 0x02,
- .bInterfaceSubClass = 0x0a,
+ .bInterfaceClass = USB_CLASS_COMM,
+ .bInterfaceSubClass = 6 /* Ethernet model */,
.bInterfaceProtocol = 0x00,
- .driver_info = (unsigned long) &zaurus_pxa_info,
+ .driver_info = ZAURUS_PXA_INFO,
}, {
.match_flags = USB_DEVICE_ID_MATCH_INT_INFO
| USB_DEVICE_ID_MATCH_DEVICE,
.idVendor = 0x04DD,
.idProduct = 0x9032, /* SL-6000 */
- .bInterfaceClass = 0x02,
- .bInterfaceSubClass = 0x0a,
+ .bInterfaceClass = USB_CLASS_COMM,
+ .bInterfaceSubClass = 6 /* Ethernet model */,
.bInterfaceProtocol = 0x00,
- .driver_info = (unsigned long) &zaurus_pxa_info,
+ .driver_info = ZAURUS_PXA_INFO,
}, {
.match_flags = USB_DEVICE_ID_MATCH_INT_INFO
| USB_DEVICE_ID_MATCH_DEVICE,
.idVendor = 0x04DD,
.idProduct = 0x9050, /* C-860 */
- .bInterfaceClass = 0x02,
- .bInterfaceSubClass = 0x0a,
+ .bInterfaceClass = USB_CLASS_COMM,
+ .bInterfaceSubClass = 6 /* Ethernet model */,
.bInterfaceProtocol = 0x00,
- .driver_info = (unsigned long) &zaurus_pxa_info,
+ .driver_info = ZAURUS_PXA_INFO,
},
-#endif
-
-#ifdef CONFIG_USB_CDCETHER
-#ifndef CONFIG_USB_ZAURUS
- /* if we couldn't whitelist Zaurus, we must blacklist it */
+/* Olympus has some models with a Zaurus-compatible option.
+ * R-1000 uses a FreeScale i.MXL cpu (ARMv4T)
+ */
{
- .match_flags = USB_DEVICE_ID_MATCH_INT_INFO
- | USB_DEVICE_ID_MATCH_DEVICE,
- .idVendor = 0x04DD,
- .idProduct = 0x8004,
- /* match the master interface */
+ .match_flags = USB_DEVICE_ID_MATCH_INT_INFO
+ | USB_DEVICE_ID_MATCH_DEVICE,
+ .idVendor = 0x07B4,
+ .idProduct = 0x0F02, /* R-1000 */
.bInterfaceClass = USB_CLASS_COMM,
.bInterfaceSubClass = 6 /* Ethernet model */,
- .bInterfaceProtocol = 0,
- .driver_info = 0, /* BLACKLIST */
+ .bInterfaceProtocol = 0x00,
+ .driver_info = OLYMPUS_MXL_INFO,
},
- // FIXME blacklist the other Zaurus models too, sigh
#endif
+#ifdef CONFIG_USB_CDCETHER
{
/* CDC Ether uses two interfaces, not necessarily consecutive.
* We match the main interface, ignoring the optional device