diff options
Diffstat (limited to 'drivers/net/usb/net1080.c')
| -rw-r--r-- | drivers/net/usb/net1080.c | 294 |
1 files changed, 112 insertions, 182 deletions
diff --git a/drivers/net/usb/net1080.c b/drivers/net/usb/net1080.c index aeb1ab03a9e..4cbdb1307f3 100644 --- a/drivers/net/usb/net1080.c +++ b/drivers/net/usb/net1080.c @@ -13,15 +13,13 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * along with this program; if not, see <http://www.gnu.org/licenses/>. */ // #define DEBUG // error path messages, extra info // #define VERBOSE // more; success messages #include <linux/module.h> -#include <linux/init.h> #include <linux/netdevice.h> #include <linux/etherdevice.h> #include <linux/ethtool.h> @@ -29,6 +27,7 @@ #include <linux/mii.h> #include <linux/usb.h> #include <linux/usb/usbnet.h> +#include <linux/slab.h> #include <asm/unaligned.h> @@ -63,13 +62,13 @@ struct nc_header { // packed: // all else is optional, and must start with: // __le16 vendorId; // from usb-if // __le16 productId; -} __attribute__((__packed__)); +} __packed; #define PAD_BYTE ((unsigned char)0xAC) struct nc_trailer { __le16 packet_id; -} __attribute__((__packed__)); +} __packed; // packets may use FLAG_FRAMING_NC and optional pad #define FRAMED_SIZE(mtu) (sizeof (struct nc_header) \ @@ -108,13 +107,11 @@ struct nc_trailer { static int nc_vendor_read(struct usbnet *dev, u8 req, u8 regnum, u16 *retval_ptr) { - int status = usb_control_msg(dev->udev, - usb_rcvctrlpipe(dev->udev, 0), - req, - USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE, - 0, regnum, - retval_ptr, sizeof *retval_ptr, - USB_CTRL_GET_TIMEOUT); + int status = usbnet_read_cmd(dev, req, + USB_DIR_IN | USB_TYPE_VENDOR | + USB_RECIP_DEVICE, + 0, regnum, retval_ptr, + sizeof *retval_ptr); if (status > 0) status = 0; if (!status) @@ -132,13 +129,9 @@ nc_register_read(struct usbnet *dev, u8 regnum, u16 *retval_ptr) static void nc_vendor_write(struct usbnet *dev, u8 req, u8 regnum, u16 value) { - usb_control_msg(dev->udev, - usb_sndctrlpipe(dev->udev, 0), - req, - USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, - value, regnum, - NULL, 0, // data is in setup packet - USB_CTRL_SET_TIMEOUT); + usbnet_write_cmd(dev, req, + USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, + value, regnum, NULL, 0); } static inline void @@ -154,12 +147,10 @@ static void nc_dump_registers(struct usbnet *dev) u8 reg; u16 *vp = kmalloc(sizeof (u16)); - if (!vp) { - dbg("no memory?"); + if (!vp) return; - } - dbg("%s registers:", dev->net->name); + netdev_dbg(dev->net, "registers:\n"); for (reg = 0; reg < 0x20; reg++) { int retval; @@ -171,11 +162,10 @@ static void nc_dump_registers(struct usbnet *dev) retval = nc_register_read(dev, reg, vp); if (retval < 0) - dbg("%s reg [0x%x] ==> error %d", - dev->net->name, reg, retval); + netdev_dbg(dev->net, "reg [0x%x] ==> error %d\n", + reg, retval); else - dbg("%s reg [0x%x] = 0x%x", - dev->net->name, reg, *vp); + netdev_dbg(dev->net, "reg [0x%x] = 0x%x\n", reg, *vp); } kfree(vp); } @@ -203,25 +193,23 @@ static void nc_dump_registers(struct usbnet *dev) static inline void nc_dump_usbctl(struct usbnet *dev, u16 usbctl) { - if (!netif_msg_link(dev)) - return; - devdbg(dev, "net1080 %s-%s usbctl 0x%x:%s%s%s%s%s;" - " this%s%s;" - " other%s%s; r/o 0x%x", - dev->udev->bus->bus_name, dev->udev->devpath, - usbctl, - (usbctl & USBCTL_ENABLE_LANG) ? " lang" : "", - (usbctl & USBCTL_ENABLE_MFGR) ? " mfgr" : "", - (usbctl & USBCTL_ENABLE_PROD) ? " prod" : "", - (usbctl & USBCTL_ENABLE_SERIAL) ? " serial" : "", - (usbctl & USBCTL_ENABLE_DEFAULTS) ? " defaults" : "", - - (usbctl & USBCTL_FLUSH_OTHER) ? " FLUSH" : "", - (usbctl & USBCTL_DISCONN_OTHER) ? " DIS" : "", - (usbctl & USBCTL_FLUSH_THIS) ? " FLUSH" : "", - (usbctl & USBCTL_DISCONN_THIS) ? " DIS" : "", - usbctl & ~USBCTL_WRITABLE_MASK - ); + netif_dbg(dev, link, dev->net, + "net1080 %s-%s usbctl 0x%x:%s%s%s%s%s; this%s%s; other%s%s; r/o 0x%x\n", + dev->udev->bus->bus_name, dev->udev->devpath, + usbctl, + (usbctl & USBCTL_ENABLE_LANG) ? " lang" : "", + (usbctl & USBCTL_ENABLE_MFGR) ? " mfgr" : "", + (usbctl & USBCTL_ENABLE_PROD) ? " prod" : "", + (usbctl & USBCTL_ENABLE_SERIAL) ? " serial" : "", + (usbctl & USBCTL_ENABLE_DEFAULTS) ? " defaults" : "", + + (usbctl & USBCTL_FLUSH_THIS) ? " FLUSH" : "", + (usbctl & USBCTL_DISCONN_THIS) ? " DIS" : "", + + (usbctl & USBCTL_FLUSH_OTHER) ? " FLUSH" : "", + (usbctl & USBCTL_DISCONN_OTHER) ? " DIS" : "", + + usbctl & ~USBCTL_WRITABLE_MASK); } /*-------------------------------------------------------------------------*/ @@ -248,30 +236,26 @@ static inline void nc_dump_usbctl(struct usbnet *dev, u16 usbctl) static inline void nc_dump_status(struct usbnet *dev, u16 status) { - if (!netif_msg_link(dev)) - return; - devdbg(dev, "net1080 %s-%s status 0x%x:" - " this (%c) PKT=%d%s%s%s;" - " other PKT=%d%s%s%s; unspec 0x%x", - dev->udev->bus->bus_name, dev->udev->devpath, - status, - - // XXX the packet counts don't seem right - // (1 at reset, not 0); maybe UNSPEC too - - (status & STATUS_PORT_A) ? 'A' : 'B', - STATUS_PACKETS_THIS(status), - (status & STATUS_CONN_THIS) ? " CON" : "", - (status & STATUS_SUSPEND_THIS) ? " SUS" : "", - (status & STATUS_MAILBOX_THIS) ? " MBOX" : "", - - STATUS_PACKETS_OTHER(status), - (status & STATUS_CONN_OTHER) ? " CON" : "", - (status & STATUS_SUSPEND_OTHER) ? " SUS" : "", - (status & STATUS_MAILBOX_OTHER) ? " MBOX" : "", - - status & STATUS_UNSPEC_MASK - ); + netif_dbg(dev, link, dev->net, + "net1080 %s-%s status 0x%x: this (%c) PKT=%d%s%s%s; other PKT=%d%s%s%s; unspec 0x%x\n", + dev->udev->bus->bus_name, dev->udev->devpath, + status, + + // XXX the packet counts don't seem right + // (1 at reset, not 0); maybe UNSPEC too + + (status & STATUS_PORT_A) ? 'A' : 'B', + STATUS_PACKETS_THIS(status), + (status & STATUS_CONN_THIS) ? " CON" : "", + (status & STATUS_SUSPEND_THIS) ? " SUS" : "", + (status & STATUS_MAILBOX_THIS) ? " MBOX" : "", + + STATUS_PACKETS_OTHER(status), + (status & STATUS_CONN_OTHER) ? " CON" : "", + (status & STATUS_SUSPEND_OTHER) ? " SUS" : "", + (status & STATUS_MAILBOX_OTHER) ? " MBOX" : "", + + status & STATUS_UNSPEC_MASK); } /*-------------------------------------------------------------------------*/ @@ -286,10 +270,9 @@ static inline void nc_dump_status(struct usbnet *dev, u16 status) static inline void nc_dump_ttl(struct usbnet *dev, u16 ttl) { - if (netif_msg_link(dev)) - devdbg(dev, "net1080 %s-%s ttl 0x%x this = %d, other = %d", - dev->udev->bus->bus_name, dev->udev->devpath, - ttl, TTL_THIS(ttl), TTL_OTHER(ttl)); + netif_dbg(dev, link, dev->net, "net1080 %s-%s ttl 0x%x this = %d, other = %d\n", + dev->udev->bus->bus_name, dev->udev->devpath, + ttl, TTL_THIS(ttl), TTL_OTHER(ttl)); } /*-------------------------------------------------------------------------*/ @@ -297,52 +280,46 @@ static inline void nc_dump_ttl(struct usbnet *dev, u16 ttl) static int net1080_reset(struct usbnet *dev) { u16 usbctl, status, ttl; - u16 *vp = kmalloc(sizeof (u16), GFP_KERNEL); + u16 vp; int retval; - if (!vp) - return -ENOMEM; - // nc_dump_registers(dev); - if ((retval = nc_register_read(dev, REG_STATUS, vp)) < 0) { - dbg("can't read %s-%s status: %d", - dev->udev->bus->bus_name, dev->udev->devpath, retval); + if ((retval = nc_register_read(dev, REG_STATUS, &vp)) < 0) { + netdev_dbg(dev->net, "can't read %s-%s status: %d\n", + dev->udev->bus->bus_name, dev->udev->devpath, retval); goto done; } - status = *vp; + status = vp; nc_dump_status(dev, status); - if ((retval = nc_register_read(dev, REG_USBCTL, vp)) < 0) { - dbg("can't read USBCTL, %d", retval); + if ((retval = nc_register_read(dev, REG_USBCTL, &vp)) < 0) { + netdev_dbg(dev->net, "can't read USBCTL, %d\n", retval); goto done; } - usbctl = *vp; + usbctl = vp; nc_dump_usbctl(dev, usbctl); nc_register_write(dev, REG_USBCTL, USBCTL_FLUSH_THIS | USBCTL_FLUSH_OTHER); - if ((retval = nc_register_read(dev, REG_TTL, vp)) < 0) { - dbg("can't read TTL, %d", retval); + if ((retval = nc_register_read(dev, REG_TTL, &vp)) < 0) { + netdev_dbg(dev->net, "can't read TTL, %d\n", retval); goto done; } - ttl = *vp; + ttl = vp; // nc_dump_ttl(dev, ttl); nc_register_write(dev, REG_TTL, MK_TTL(NC_READ_TTL_MS, TTL_OTHER(ttl)) ); - dbg("%s: assigned TTL, %d ms", dev->net->name, NC_READ_TTL_MS); + netdev_dbg(dev->net, "assigned TTL, %d ms\n", NC_READ_TTL_MS); - if (netif_msg_link(dev)) - devinfo(dev, "port %c, peer %sconnected", - (status & STATUS_PORT_A) ? 'A' : 'B', - (status & STATUS_CONN_OTHER) ? "" : "dis" - ); + netif_info(dev, link, dev->net, "port %c, peer %sconnected\n", + (status & STATUS_PORT_A) ? 'A' : 'B', + (status & STATUS_CONN_OTHER) ? "" : "dis"); retval = 0; done: - kfree(vp); return retval; } @@ -350,15 +327,12 @@ static int net1080_check_connect(struct usbnet *dev) { int retval; u16 status; - u16 *vp = kmalloc(sizeof (u16), GFP_KERNEL); + u16 vp; - if (!vp) - return -ENOMEM; - retval = nc_register_read(dev, REG_STATUS, vp); - status = *vp; - kfree(vp); + retval = nc_register_read(dev, REG_STATUS, &vp); + status = vp; if (retval != 0) { - dbg("%s net1080_check_conn read - %d", dev->net->name, retval); + netdev_dbg(dev->net, "net1080_check_conn read - %d\n", retval); return retval; } if ((status & STATUS_CONN_OTHER) != STATUS_CONN_OTHER) @@ -366,59 +340,22 @@ static int net1080_check_connect(struct usbnet *dev) return 0; } -static void nc_flush_complete(struct urb *urb) -{ - kfree(urb->context); - usb_free_urb(urb); -} - static void nc_ensure_sync(struct usbnet *dev) { - dev->frame_errors++; - if (dev->frame_errors > 5) { - struct urb *urb; - struct usb_ctrlrequest *req; - int status; - - /* Send a flush */ - urb = usb_alloc_urb(0, GFP_ATOMIC); - if (!urb) - return; - - req = kmalloc(sizeof *req, GFP_ATOMIC); - if (!req) { - usb_free_urb(urb); - return; - } + if (++dev->frame_errors <= 5) + return; - req->bRequestType = USB_DIR_OUT - | USB_TYPE_VENDOR - | USB_RECIP_DEVICE; - req->bRequest = REQUEST_REGISTER; - req->wValue = cpu_to_le16(USBCTL_FLUSH_THIS - | USBCTL_FLUSH_OTHER); - req->wIndex = cpu_to_le16(REG_USBCTL); - req->wLength = cpu_to_le16(0); - - /* queue an async control request, we don't need - * to do anything when it finishes except clean up. - */ - usb_fill_control_urb(urb, dev->udev, - usb_sndctrlpipe(dev->udev, 0), - (unsigned char *) req, - NULL, 0, - nc_flush_complete, req); - status = usb_submit_urb(urb, GFP_ATOMIC); - if (status) { - kfree(req); - usb_free_urb(urb); - return; - } + if (usbnet_write_cmd_async(dev, REQUEST_REGISTER, + USB_DIR_OUT | USB_TYPE_VENDOR | + USB_RECIP_DEVICE, + USBCTL_FLUSH_THIS | + USBCTL_FLUSH_OTHER, + REG_USBCTL, NULL, 0)) + return; - if (netif_msg_rx_err(dev)) - devdbg(dev, "flush net1080; too many framing errors"); - dev->frame_errors = 0; - } + netif_dbg(dev, rx_err, dev->net, + "flush net1080; too many framing errors\n"); + dev->frame_errors = 0; } static int net1080_rx_fixup(struct usbnet *dev, struct sk_buff *skb) @@ -427,12 +364,14 @@ static int net1080_rx_fixup(struct usbnet *dev, struct sk_buff *skb) struct nc_trailer *trailer; u16 hdr_len, packet_len; + /* This check is no longer done by usbnet */ + if (skb->len < dev->net->hard_header_len) + return 0; + if (!(skb->len & 0x01)) { -#ifdef DEBUG - struct net_device *net = dev->net; - dbg("rx framesize %d range %d..%d mtu %d", skb->len, - net->hard_header_len, dev->hard_mtu, net->mtu); -#endif + netdev_dbg(dev->net, "rx framesize %d range %d..%d mtu %d\n", + skb->len, dev->net->hard_header_len, dev->hard_mtu, + dev->net->mtu); dev->net->stats.rx_frame_errors++; nc_ensure_sync(dev); return 0; @@ -443,17 +382,17 @@ static int net1080_rx_fixup(struct usbnet *dev, struct sk_buff *skb) packet_len = le16_to_cpup(&header->packet_len); if (FRAMED_SIZE(packet_len) > NC_MAX_PACKET) { dev->net->stats.rx_frame_errors++; - dbg("packet too big, %d", packet_len); + netdev_dbg(dev->net, "packet too big, %d\n", packet_len); nc_ensure_sync(dev); return 0; } else if (hdr_len < MIN_HEADER) { dev->net->stats.rx_frame_errors++; - dbg("header too short, %d", hdr_len); + netdev_dbg(dev->net, "header too short, %d\n", hdr_len); nc_ensure_sync(dev); return 0; } else if (hdr_len > MIN_HEADER) { // out of band data for us? - dbg("header OOB, %d bytes", hdr_len - MIN_HEADER); + netdev_dbg(dev->net, "header OOB, %d bytes\n", hdr_len - MIN_HEADER); nc_ensure_sync(dev); // switch (vendor/product ids) { ... } } @@ -466,28 +405,28 @@ static int net1080_rx_fixup(struct usbnet *dev, struct sk_buff *skb) if ((packet_len & 0x01) == 0) { if (skb->data [packet_len] != PAD_BYTE) { dev->net->stats.rx_frame_errors++; - dbg("bad pad"); + netdev_dbg(dev->net, "bad pad\n"); return 0; } skb_trim(skb, skb->len - 1); } if (skb->len != packet_len) { dev->net->stats.rx_frame_errors++; - dbg("bad packet len %d (expected %d)", - skb->len, packet_len); + netdev_dbg(dev->net, "bad packet len %d (expected %d)\n", + skb->len, packet_len); nc_ensure_sync(dev); return 0; } if (header->packet_id != get_unaligned(&trailer->packet_id)) { dev->net->stats.rx_fifo_errors++; - dbg("(2+ dropped) rx packet_id mismatch 0x%x 0x%x", - le16_to_cpu(header->packet_id), - le16_to_cpu(trailer->packet_id)); + netdev_dbg(dev->net, "(2+ dropped) rx packet_id mismatch 0x%x 0x%x\n", + le16_to_cpu(header->packet_id), + le16_to_cpu(trailer->packet_id)); return 0; } #if 0 - devdbg(dev, "frame <rx h %d p %d id %d", header->hdr_len, - header->packet_len, header->packet_id); + netdev_dbg(dev->net, "frame <rx h %d p %d id %d\n", header->hdr_len, + header->packet_len, header->packet_id); #endif dev->frame_errors = 0; return 1; @@ -547,9 +486,9 @@ encapsulate: trailer = (struct nc_trailer *) skb_put(skb, sizeof *trailer); put_unaligned(header->packet_id, &trailer->packet_id); #if 0 - devdbg(dev, "frame >tx h %d p %d id %d", - header->hdr_len, header->packet_len, - header->packet_id); + netdev_dbg(dev->net, "frame >tx h %d p %d id %d\n", + header->hdr_len, header->packet_len, + header->packet_id); #endif return skb; } @@ -568,7 +507,7 @@ static int net1080_bind(struct usbnet *dev, struct usb_interface *intf) static const struct driver_info net1080_info = { .description = "NetChip TurboCONNECT", - .flags = FLAG_FRAMING_NC, + .flags = FLAG_POINTTOPOINT | FLAG_FRAMING_NC, .bind = net1080_bind, .reset = net1080_reset, .check_connect = net1080_check_connect, @@ -595,19 +534,10 @@ static struct usb_driver net1080_driver = { .disconnect = usbnet_disconnect, .suspend = usbnet_suspend, .resume = usbnet_resume, + .disable_hub_initiated_lpm = 1, }; -static int __init net1080_init(void) -{ - return usb_register(&net1080_driver); -} -module_init(net1080_init); - -static void __exit net1080_exit(void) -{ - usb_deregister(&net1080_driver); -} -module_exit(net1080_exit); +module_usb_driver(net1080_driver); MODULE_AUTHOR("David Brownell"); MODULE_DESCRIPTION("NetChip 1080 based USB Host-to-Host Links"); |
