summaryrefslogtreecommitdiffstats
path: root/drivers/net/irda/irda-usb.c
diff options
context:
space:
mode:
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>2017-08-27 17:03:32 +0200
committerDavid S. Miller <davem@davemloft.net>2017-08-28 16:42:57 -0700
commit6c391ff758eb9f41e11c6143fd5bdb3b3324bf9f (patch)
tree95ee8f47eacb698ecb3de600e73f07bde3f0d404 /drivers/net/irda/irda-usb.c
parent1ca163afb6fd569b6efdc221954177cba5a02cbc (diff)
irda: move drivers/net/irda to drivers/staging/irda/drivers
Move the irda drivers from drivers/net/irda/ to drivers/staging/irda/drivers as they will be deleted in a future kernel release. Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/irda/irda-usb.c')
-rw-r--r--drivers/net/irda/irda-usb.c1914
1 files changed, 0 insertions, 1914 deletions
diff --git a/drivers/net/irda/irda-usb.c b/drivers/net/irda/irda-usb.c
deleted file mode 100644
index 723e49bc4baa..000000000000
--- a/drivers/net/irda/irda-usb.c
+++ /dev/null
@@ -1,1914 +0,0 @@
-/*****************************************************************************
- *
- * Filename: irda-usb.c
- * Version: 0.10
- * Description: IrDA-USB Driver
- * Status: Experimental
- * Author: Dag Brattli <dag@brattli.net>
- *
- * Copyright (C) 2000, Roman Weissgaerber <weissg@vienna.at>
- * Copyright (C) 2001, Dag Brattli <dag@brattli.net>
- * Copyright (C) 2001, Jean Tourrilhes <jt@hpl.hp.com>
- * Copyright (C) 2004, SigmaTel, Inc. <irquality@sigmatel.com>
- * Copyright (C) 2005, Milan Beno <beno@pobox.sk>
- * Copyright (C) 2006, Nick Fedchik <nick@fedchik.org.ua>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * 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., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- *****************************************************************************/
-
-/*
- * IMPORTANT NOTE
- * --------------
- *
- * As of kernel 2.5.20, this is the state of compliance and testing of
- * this driver (irda-usb) with regards to the USB low level drivers...
- *
- * This driver has been tested SUCCESSFULLY with the following drivers :
- * o usb-uhci-hcd (For Intel/Via USB controllers)
- * o uhci-hcd (Alternate/JE driver for Intel/Via USB controllers)
- * o ohci-hcd (For other USB controllers)
- *
- * This driver has NOT been tested with the following drivers :
- * o ehci-hcd (USB 2.0 controllers)
- *
- * Note that all HCD drivers do URB_ZERO_PACKET and timeout properly,
- * so we don't have to worry about that anymore.
- * One common problem is the failure to set the address on the dongle,
- * but this happens before the driver gets loaded...
- *
- * Jean II
- */
-
-/*------------------------------------------------------------------*/
-
-#include <linux/module.h>
-#include <linux/moduleparam.h>
-#include <linux/kernel.h>
-#include <linux/types.h>
-#include <linux/skbuff.h>
-#include <linux/netdevice.h>
-#include <linux/slab.h>
-#include <linux/rtnetlink.h>
-#include <linux/usb.h>
-#include <linux/firmware.h>
-
-#include "irda-usb.h"
-
-/*------------------------------------------------------------------*/
-
-static int qos_mtt_bits = 0;
-
-/* These are the currently known IrDA USB dongles. Add new dongles here */
-static const struct usb_device_id dongles[] = {
- /* ACTiSYS Corp., ACT-IR2000U FIR-USB Adapter */
- { USB_DEVICE(0x9c4, 0x011), .driver_info = IUC_SPEED_BUG | IUC_NO_WINDOW },
- /* Look like ACTiSYS, Report : IBM Corp., IBM UltraPort IrDA */
- { USB_DEVICE(0x4428, 0x012), .driver_info = IUC_SPEED_BUG | IUC_NO_WINDOW },
- /* KC Technology Inc., KC-180 USB IrDA Device */
- { USB_DEVICE(0x50f, 0x180), .driver_info = IUC_SPEED_BUG | IUC_NO_WINDOW },
- /* Extended Systems, Inc., XTNDAccess IrDA USB (ESI-9685) */
- { USB_DEVICE(0x8e9, 0x100), .driver_info = IUC_SPEED_BUG | IUC_NO_WINDOW },
- /* SigmaTel STIR4210/4220/4116 USB IrDA (VFIR) Bridge */
- { USB_DEVICE(0x66f, 0x4210), .driver_info = IUC_STIR421X | IUC_SPEED_BUG },
- { USB_DEVICE(0x66f, 0x4220), .driver_info = IUC_STIR421X | IUC_SPEED_BUG },
- { USB_DEVICE(0x66f, 0x4116), .driver_info = IUC_STIR421X | IUC_SPEED_BUG },
- { .match_flags = USB_DEVICE_ID_MATCH_INT_CLASS |
- USB_DEVICE_ID_MATCH_INT_SUBCLASS,
- .bInterfaceClass = USB_CLASS_APP_SPEC,
- .bInterfaceSubClass = USB_CLASS_IRDA,
- .driver_info = IUC_DEFAULT, },
- { }, /* The end */
-};
-
-/*
- * Important note :
- * Devices based on the SigmaTel chipset (0x66f, 0x4200) are not designed
- * using the "USB-IrDA specification" (yes, there exist such a thing), and
- * therefore not supported by this driver (don't add them above).
- * There is a Linux driver, stir4200, that support those USB devices.
- * Jean II
- */
-
-MODULE_DEVICE_TABLE(usb, dongles);
-
-/*------------------------------------------------------------------*/
-
-static void irda_usb_init_qos(struct irda_usb_cb *self) ;
-static struct irda_class_desc *irda_usb_find_class_desc(struct usb_interface *intf);
-static void irda_usb_disconnect(struct usb_interface *intf);
-static void irda_usb_change_speed_xbofs(struct irda_usb_cb *self);
-static netdev_tx_t irda_usb_hard_xmit(struct sk_buff *skb,
- struct net_device *dev);
-static int irda_usb_open(struct irda_usb_cb *self);
-static void irda_usb_close(struct irda_usb_cb *self);
-static void speed_bulk_callback(struct urb *urb);
-static void write_bulk_callback(struct urb *urb);
-static void irda_usb_receive(struct urb *urb);
-static void irda_usb_rx_defer_expired(unsigned long data);
-static int irda_usb_net_open(struct net_device *dev);
-static int irda_usb_net_close(struct net_device *dev);
-static int irda_usb_net_ioctl(struct net_device *dev, struct ifreq *rq, int cmd);
-static void irda_usb_net_timeout(struct net_device *dev);
-
-/************************ TRANSMIT ROUTINES ************************/
-/*
- * Receive packets from the IrDA stack and send them on the USB pipe.
- * Handle speed change, timeout and lot's of ugliness...
- */
-
-/*------------------------------------------------------------------*/
-/*
- * Function irda_usb_build_header(self, skb, header)
- *
- * Builds USB-IrDA outbound header
- *
- * When we send an IrDA frame over an USB pipe, we add to it a 1 byte
- * header. This function create this header with the proper values.
- *
- * Important note : the USB-IrDA spec 1.0 say very clearly in chapter 5.4.2.2
- * that the setting of the link speed and xbof number in this outbound header
- * should be applied *AFTER* the frame has been sent.
- * Unfortunately, some devices are not compliant with that... It seems that
- * reading the spec is far too difficult...
- * Jean II
- */
-static void irda_usb_build_header(struct irda_usb_cb *self,
- __u8 *header,
- int force)
-{
- /* Here we check if we have an STIR421x chip,
- * and if either speed or xbofs (or both) needs
- * to be changed.
- */
- if (self->capability & IUC_STIR421X &&
- ((self->new_speed != -1) || (self->new_xbofs != -1))) {
-
- /* With STIR421x, speed and xBOFs must be set at the same
- * time, even if only one of them changes.
- */
- if (self->new_speed == -1)
- self->new_speed = self->speed ;
-
- if (self->new_xbofs == -1)
- self->new_xbofs = self->xbofs ;
- }
-
- /* Set the link speed */
- if (self->new_speed != -1) {
- /* Hum... Ugly hack :-(
- * Some device are not compliant with the spec and change
- * parameters *before* sending the frame. - Jean II
- */
- if ((self->capability & IUC_SPEED_BUG) &&
- (!force) && (self->speed != -1)) {
- /* No speed and xbofs change here
- * (we'll do it later in the write callback) */
- pr_debug("%s(), not changing speed yet\n", __func__);
- *header = 0;
- return;
- }
-
- pr_debug("%s(), changing speed to %d\n",
- __func__, self->new_speed);
- self->speed = self->new_speed;
- /* We will do ` self->new_speed = -1; ' in the completion
- * handler just in case the current URB fail - Jean II */
-
- switch (self->speed) {
- case 2400:
- *header = SPEED_2400;
- break;
- default:
- case 9600:
- *header = SPEED_9600;
- break;
- case 19200:
- *header = SPEED_19200;
- break;
- case 38400:
- *header = SPEED_38400;
- break;
- case 57600:
- *header = SPEED_57600;
- break;
- case 115200:
- *header = SPEED_115200;
- break;
- case 576000:
- *header = SPEED_576000;
- break;
- case 1152000:
- *header = SPEED_1152000;
- break;
- case 4000000:
- *header = SPEED_4000000;
- self->new_xbofs = 0;
- break;
- case 16000000:
- *header = SPEED_16000000;
- self->new_xbofs = 0;
- break;
- }
- } else
- /* No change */
- *header = 0;
-
- /* Set the negotiated additional XBOFS */
- if (self->new_xbofs != -1) {
- pr_debug("%s(), changing xbofs to %d\n",
- __func__, self->new_xbofs);
- self->xbofs = self->new_xbofs;
- /* We will do ` self->new_xbofs = -1; ' in the completion
- * handler just in case the current URB fail - Jean II */
-
- switch (self->xbofs) {
- case 48:
- *header |= 0x10;
- break;
- case 28:
- case 24: /* USB spec 1.0 says 24 */
- *header |= 0x20;
- break;
- default:
- case 12:
- *header |= 0x30;
- break;
- case 5: /* Bug in IrLAP spec? (should be 6) */
- case 6:
- *header |= 0x40;
- break;
- case 3:
- *header |= 0x50;
- break;
- case 2:
- *header |= 0x60;
- break;
- case 1:
- *header |= 0x70;
- break;
- case 0:
- *header |= 0x80;
- break;
- }
- }
-}
-
-/*
-* calculate turnaround time for SigmaTel header
-*/
-static __u8 get_turnaround_time(struct sk_buff *skb)
-{
- int turnaround_time = irda_get_mtt(skb);
-
- if ( turnaround_time == 0 )
- return 0;
- else if ( turnaround_time <= 10 )
- return 1;
- else if ( turnaround_time <= 50 )
- return 2;
- else if ( turnaround_time <= 100 )
- return 3;
- else if ( turnaround_time <= 500 )
- return 4;
- else if ( turnaround_time <= 1000 )
- return 5;
- else if ( turnaround_time <= 5000 )
- return 6;
- else
- return 7;
-}
-
-
-/*------------------------------------------------------------------*/
-/*
- * Send a command to change the speed of the dongle
- * Need to be called with spinlock on.
- */
-static void irda_usb_change_speed_xbofs(struct irda_usb_cb *self)
-{
- __u8 *frame;
- struct urb *urb;
- int ret;
-
- pr_debug("%s(), speed=%d, xbofs=%d\n", __func__,
- self->new_speed, self->new_xbofs);
-
- /* Grab the speed URB */
- urb = self->speed_urb;
- if (urb->status != 0) {
- net_warn_ratelimited("%s(), URB still in use!\n", __func__);
- return;
- }
-
- /* Allocate the fake frame */
- frame = self->speed_buff;
-
- /* Set the new speed and xbofs in this fake frame */
- irda_usb_build_header(self, frame, 1);
-
- if (self->capability & IUC_STIR421X) {
- if (frame[0] == 0) return ; // do nothing if no change
- frame[1] = 0; // other parameters don't change here
- frame[2] = 0;
- }
-
- /* Submit the 0 length IrDA frame to trigger new speed settings */
- usb_fill_bulk_urb(urb, self->usbdev,
- usb_sndbulkpipe(self->usbdev, self->bulk_out_ep),
- frame, IRDA_USB_SPEED_MTU,
- speed_bulk_callback, self);
- urb->transfer_buffer_length = self->header_length;
- urb->transfer_flags = 0;
-
- /* Irq disabled -> GFP_ATOMIC */
- if ((ret = usb_submit_urb(urb, GFP_ATOMIC))) {
- net_warn_ratelimited("%s(), failed Speed URB\n", __func__);
- }
-}
-
-/*------------------------------------------------------------------*/
-/*
- * Speed URB callback
- * Now, we can only get called for the speed URB.
- */
-static void speed_bulk_callback(struct urb *urb)
-{
- struct irda_usb_cb *self = urb->context;
-
- /* We should always have a context */
- IRDA_ASSERT(self != NULL, return;);
- /* We should always be called for the speed URB */
- IRDA_ASSERT(urb == self->speed_urb, return;);
-
- /* Check for timeout and other USB nasties */
- if (urb->status != 0) {
- /* I get a lot of -ECONNABORTED = -103 here - Jean II */
- pr_debug("%s(), URB complete status %d, transfer_flags 0x%04X\n",
- __func__, urb->status, urb->transfer_flags);
-
- /* Don't do anything here, that might confuse the USB layer.
- * Instead, we will wait for irda_usb_net_timeout(), the
- * network layer watchdog, to fix the situation.
- * Jean II */
- /* A reset of the dongle might be welcomed here - Jean II */
- return;
- }
-
- /* urb is now available */
- //urb->status = 0; -> tested above
-
- /* New speed and xbof is now committed in hardware */
- self->new_speed = -1;
- self->new_xbofs = -1;
-
- /* Allow the stack to send more packets */
- netif_wake_queue(self->netdev);
-}
-
-/*------------------------------------------------------------------*/
-/*
- * Send an IrDA frame to the USB dongle (for transmission)
- */
-static netdev_tx_t irda_usb_hard_xmit(struct sk_buff *skb,
- struct net_device *netdev)
-{
- struct irda_usb_cb *self = netdev_priv(netdev);
- struct urb *urb = self->tx_urb;
- unsigned long flags;
- s32 speed;
- s16 xbofs;
- int res, mtt;
-
- pr_debug("%s() on %s\n", __func__, netdev->name);
-
- netif_stop_queue(netdev);
-
- /* Protect us from USB callbacks, net watchdog and else. */
- spin_lock_irqsave(&self->lock, flags);
-
- /* Check if the device is still there.
- * We need to check self->present under the spinlock because
- * of irda_usb_disconnect() is synchronous - Jean II */
- if (!self->present) {
- pr_debug("%s(), Device is gone...\n", __func__);
- goto drop;
- }
-
- /* Check if we need to change the number of xbofs */
- xbofs = irda_get_next_xbofs(skb);
- if ((xbofs != self->xbofs) && (xbofs != -1)) {
- self->new_xbofs = xbofs;
- }
-
- /* Check if we need to change the speed */
- speed = irda_get_next_speed(skb);
- if ((speed != self->speed) && (speed != -1)) {
- /* Set the desired speed */
- self->new_speed = speed;
-
- /* Check for empty frame */
- if (!skb->len) {
- /* IrLAP send us an empty frame to make us change the
- * speed. Changing speed with the USB adapter is in
- * fact sending an empty frame to the adapter, so we
- * could just let the present function do its job.
- * However, we would wait for min turn time,
- * do an extra memcpy and increment packet counters...
- * Jean II */
- irda_usb_change_speed_xbofs(self);
- netif_trans_update(netdev);
- /* Will netif_wake_queue() in callback */
- goto drop;
- }
- }
-
- if (urb->status != 0) {
- net_warn_ratelimited("%s(), URB still in use!\n", __func__);
- goto drop;
- }
-
- skb_copy_from_linear_data(skb, self->tx_buff + self->header_length, skb->len);
-
- /* Change setting for next frame */
- if (self->capability & IUC_STIR421X) {
- __u8 turnaround_time;
- __u8* frame = self->tx_buff;
- turnaround_time = get_turnaround_time( skb );
- irda_usb_build_header(self, frame, 0);
- frame[2] = turnaround_time;
- if ((skb->len != 0) &&
- ((skb->len % 128) == 0) &&
- ((skb->len % 512) != 0)) {
- /* add extra byte for special SigmaTel feature */
- frame[1] = 1;
- skb_put(skb, 1);
- } else {
- frame[1] = 0;
- }
- } else {
- irda_usb_build_header(self, self->tx_buff, 0);
- }
-
- /* FIXME: Make macro out of this one */
- ((struct irda_skb_cb *)skb->cb)->context = self;
-
- usb_fill_bulk_urb(urb, self->usbdev,
- usb_sndbulkpipe(self->usbdev, self->bulk_out_ep),
- self->tx_buff, skb->len + self->header_length,
- write_bulk_callback, skb);
-
- /* This flag (URB_ZERO_PACKET) indicates that what we send is not
- * a continuous stream of data but separate packets.
- * In this case, the USB layer will insert an empty USB frame (TD)
- * after each of our packets that is exact multiple of the frame size.
- * This is how the dongle will detect the end of packet - Jean II */
- urb->transfer_flags = URB_ZERO_PACKET;
-
- /* Generate min turn time. FIXME: can we do better than this? */
- /* Trying to a turnaround time at this level is trying to measure
- * processor clock cycle with a wrist-watch, approximate at best...
- *
- * What we know is the last time we received a frame over USB.
- * Due to latency over USB that depend on the USB load, we don't
- * know when this frame was received over IrDA (a few ms before ?)
- * Then, same story for our outgoing frame...
- *
- * In theory, the USB dongle is supposed to handle the turnaround
- * by itself (spec 1.0, chater 4, page 6). Who knows ??? That's
- * why this code is enabled only for dongles that doesn't meet
- * the spec.
- * Jean II */
- if (self->capability & IUC_NO_TURN) {
- mtt = irda_get_mtt(skb);
- if (mtt) {
- int diff;
- diff = ktime_us_delta(ktime_get(), self->stamp);
-#ifdef IU_USB_MIN_RTT
- /* Factor in USB delays -> Get rid of udelay() that
- * would be lost in the noise - Jean II */
- diff += IU_USB_MIN_RTT;
-#endif /* IU_USB_MIN_RTT */
-
- /* Check if the mtt is larger than the time we have
- * already used by all the protocol processing
- */
- if (mtt > diff) {
- mtt -= diff;
- if (mtt > 1000)
- mdelay(mtt/1000);
- else
- udelay(mtt);
- }
- }
- }
-
- /* Ask USB to send the packet - Irq disabled -> GFP_ATOMIC */
- if ((res = usb_submit_urb(urb, GFP_ATOMIC))) {
- net_warn_ratelimited("%s(), failed Tx URB\n", __func__);
- netdev->stats.tx_errors++;
- /* Let USB recover : We will catch that in the watchdog */
- /*netif_start_queue(netdev);*/
- } else {
- /* Increment packet stats */
- netdev->stats.tx_packets++;
- netdev->stats.tx_bytes += skb->len;
-
- netif_trans_update(netdev);
- }
- spin_unlock_irqrestore(&self->lock, flags);
-
- return NETDEV_TX_OK;
-
-drop:
- /* Drop silently the skb and exit */
- dev_kfree_skb(skb);
- spin_unlock_irqrestore(&self->lock, flags);
- return NETDEV_TX_OK;
-}
-
-/*------------------------------------------------------------------*/
-/*
- * Note : this function will be called only for tx_urb...
- */
-static void write_bulk_callback(struct urb *urb)
-{
- unsigned long flags;
- struct sk_buff *skb = urb->context;
- struct irda_usb_cb *self = ((struct irda_skb_cb *) skb->cb)->context;
-
- /* We should always have a context */
- IRDA_ASSERT(self != NULL, return;);
- /* We should always be called for the speed URB */
- IRDA_ASSERT(urb == self->tx_urb, return;);
-
- /* Free up the skb */
- dev_kfree_skb_any(skb);
- urb->context = NULL;
-
- /* Check for timeout and other USB nasties */
- if (urb->status != 0) {
- /* I get a lot of -ECONNABORTED = -103 here - Jean II */
- pr_debug("%s(), URB complete status %d, transfer_flags 0x%04X\n",
- __func__, urb->status, urb->transfer_flags);
-
- /* Don't do anything here, that might confuse the USB layer,
- * and we could go in recursion and blow the kernel stack...
- * Instead, we will wait for irda_usb_net_timeout(), the
- * network layer watchdog, to fix the situation.
- * Jean II */
- /* A reset of the dongle might be welcomed here - Jean II */
- return;
- }
-
- /* urb is now available */
- //urb->status = 0; -> tested above
-
- /* Make sure we read self->present properly */
- spin_lock_irqsave(&self->lock, flags);
-
- /* If the network is closed, stop everything */
- if ((!self->netopen) || (!self->present)) {
- pr_debug("%s(), Network is gone...\n", __func__);
- spin_unlock_irqrestore(&self->lock, flags);
- return;
- }
-
- /* If changes to speed or xbofs is pending... */
- if ((self->new_speed != -1) || (self->new_xbofs != -1)) {
- if ((self->new_speed != self->speed) ||
- (self->new_xbofs != self->xbofs)) {
- /* We haven't changed speed yet (because of
- * IUC_SPEED_BUG), so do it now - Jean II */
- pr_debug("%s(), Changing speed now...\n", __func__);
- irda_usb_change_speed_xbofs(self);
- } else {
- /* New speed and xbof is now committed in hardware */
- self->new_speed = -1;
- self->new_xbofs = -1;
- /* Done, waiting for next packet */
- netif_wake_queue(self->netdev);
- }
- } else {
- /* Otherwise, allow the stack to send more packets */
- netif_wake_queue(self->netdev);
- }
- spin_unlock_irqrestore(&self->lock, flags);
-}
-
-/*------------------------------------------------------------------*/
-/*
- * Watchdog timer from the network layer.
- * After a predetermined timeout, if we don't give confirmation that
- * the packet has been sent (i.e. no call to netif_wake_queue()),
- * the network layer will call this function.
- * Note that URB that we submit have also a timeout. When the URB timeout
- * expire, the normal URB callback is called (write_bulk_callback()).
- */
-static void irda_usb_net_timeout(struct net_device *netdev)
-{
- unsigned long flags;
- struct irda_usb_cb *self = netdev_priv(netdev);
- struct urb *urb;
- int done = 0; /* If we have made any progress */
-
- pr_debug("%s(), Network layer thinks we timed out!\n", __func__);
- IRDA_ASSERT(self != NULL, return;);
-
- /* Protect us from USB callbacks, net Tx and else. */
- spin_lock_irqsave(&self->lock, flags);
-
- /* self->present *MUST* be read under spinlock */
- if (!self->present) {
- net_warn_ratelimited("%s(), device not present!\n", __func__);
- netif_stop_queue(netdev);
- spin_unlock_irqrestore(&self->lock, flags);
- return;
- }
-
- /* Check speed URB */
- urb = self->speed_urb;
- if (urb->status != 0) {
- pr_debug("%s: Speed change timed out, urb->status=%d, urb->transfer_flags=0x%04X\n",
- netdev->name, urb->status, urb->transfer_flags);
-
- switch (urb->status) {
- case -EINPROGRESS:
- usb_unlink_urb(urb);
- /* Note : above will *NOT* call netif_wake_queue()
- * in completion handler, we will come back here.
- * Jean II */
- done = 1;
- break;
- case -ECONNRESET:
- case -ENOENT: /* urb unlinked by us */
- default: /* ??? - Play safe */
- urb->status = 0;
- netif_wake_queue(self->netdev);
- done = 1;
- break;
- }
- }
-
- /* Check Tx URB */
- urb = self->tx_urb;
- if (urb->status != 0) {
- struct sk_buff *skb = urb->context;
-
- pr_debug("%s: Tx timed out, urb->status=%d, urb->transfer_flags=0x%04X\n",
- netdev->name, urb->status, urb->transfer_flags);
-
- /* Increase error count */
- netdev->stats.tx_errors++;
-
-#ifdef IU_BUG_KICK_TIMEOUT
- /* Can't be a bad idea to reset the speed ;-) - Jean II */
- if(self->new_speed == -1)
- self->new_speed = self->speed;
- if(self->new_xbofs == -1)
- self->new_xbofs = self->xbofs;
- irda_usb_change_speed_xbofs(self);
-#endif /* IU_BUG_KICK_TIMEOUT */
-
- switch (urb->status) {
- case -EINPROGRESS:
- usb_unlink_urb(urb);
- /* Note : above will *NOT* call netif_wake_queue()
- * in completion handler, because urb->status will
- * be -ENOENT. We will fix that at the next watchdog,
- * leaving more time to USB to recover...
- * Jean II */
- done = 1;
- break;
- case -ECONNRESET:
- case -ENOENT: /* urb unlinked by us */
- default: /* ??? - Play safe */
- if(skb != NULL) {
- dev_kfree_skb_any(skb);
- urb->context = NULL;
- }
- urb->status = 0;
- netif_wake_queue(self->netdev);
- done = 1;
- break;
- }
- }
- spin_unlock_irqrestore(&self->lock, flags);
-
- /* Maybe we need a reset */
- /* Note : Some drivers seem to use a usb_set_interface() when they
- * need to reset the hardware. Hum...
- */
-
- /* if(done == 0) */
-}
-
-/************************* RECEIVE ROUTINES *************************/
-/*
- * Receive packets from the USB layer stack and pass them to the IrDA stack.
- * Try to work around USB failures...
- */
-
-/*
- * Note :
- * Some of you may have noticed that most dongle have an interrupt in pipe
- * that we don't use. Here is the little secret...
- * When we hang a Rx URB on the bulk in pipe, it generates some USB traffic
- * in every USB frame. This is unnecessary overhead.
- * The interrupt in pipe will generate an event every time a packet is
- * received. Reading an interrupt pipe adds minimal overhead, but has some
- * latency (~1ms).
- * If we are connected (speed != 9600), we want to minimise latency, so
- * we just always hang the Rx URB and ignore the interrupt.
- * If we are not connected (speed == 9600), there is usually no Rx traffic,
- * and we want to minimise the USB overhead. In this case we should wait
- * on the interrupt pipe and hang the Rx URB only when an interrupt is
- * received.
- * Jean II
- *
- * Note : don't read the above as what we are currently doing, but as
- * something we could do with KC dongle. Also don't forget that the
- * interrupt pipe is not part of the original standard, so this would
- * need to be optional...
- * Jean II
- */
-
-/*------------------------------------------------------------------*/
-/*
- * Submit a Rx URB to the USB layer to handle reception of a frame
- * Mostly called by the completion callback of the previous URB.
- *
- * Jean II
- */
-static void irda_usb_submit(struct irda_usb_cb *self, struct sk_buff *skb, struct urb *urb)
-{
- struct irda_skb_cb *cb;
- int ret;
-
- /* This should never happen */
- IRDA_ASSERT(skb != NULL, return;);
- IRDA_ASSERT(urb != NULL, return;);
-
- /* Save ourselves in the skb */
- cb = (struct irda_skb_cb *) skb->cb;
- cb->context = self;
-
- /* Reinitialize URB */
- usb_fill_bulk_urb(urb, self->usbdev,
- usb_rcvbulkpipe(self->usbdev, self->bulk_in_ep),
- skb->data, IRDA_SKB_MAX_MTU,
- irda_usb_receive, skb);
- urb->status = 0;
-
- /* Can be called from irda_usb_receive (irq handler) -> GFP_ATOMIC */
- ret = usb_submit_urb(urb, GFP_ATOMIC);
- if (ret) {
- /* If this ever happen, we are in deep s***.
- * Basically, the Rx path will stop... */
- net_warn_ratelimited("%s(), Failed to submit Rx URB %d\n",
- __func__, ret);
- }
-}
-
-/*------------------------------------------------------------------*/
-/*
- * Function irda_usb_receive(urb)
- *
- * Called by the USB subsystem when a frame has been received
- *
- */
-static void irda_usb_receive(struct urb *urb)
-{
- struct sk_buff *skb = (struct sk_buff *) urb->context;
- struct irda_usb_cb *self;
- struct irda_skb_cb *cb;
- struct sk_buff *newskb;
- struct sk_buff *dataskb;
- struct urb *next_urb;
- unsigned int len, docopy;
-
- pr_debug("%s(), len=%d\n", __func__, urb->actual_length);
-
- /* Find ourselves */
- cb = (struct irda_skb_cb *) skb->cb;
- IRDA_ASSERT(cb != NULL, return;);
- self = (struct irda_usb_cb *) cb->context;
- IRDA_ASSERT(self != NULL, return;);
-
- /* If the network is closed or the device gone, stop everything */
- if ((!self->netopen) || (!self->present)) {
- pr_debug("%s(), Network is gone!\n", __func__);
- /* Don't re-submit the URB : will stall the Rx path */
- return;
- }
-
- /* Check the status */
- if (urb->status != 0) {
- switch (urb->status) {
- case -EILSEQ:
- self->netdev->stats.rx_crc_errors++;
- /* Also precursor to a hot-unplug on UHCI. */
- /* Fallthrough... */
- case -ECONNRESET:
- /* Random error, if I remember correctly */
- /* uhci_cleanup_unlink() is going to kill the Rx
- * URB just after we return. No problem, at this
- * point the URB will be idle ;-) - Jean II */
- case -ESHUTDOWN:
- /* That's usually a hot-unplug. Submit will fail... */
- case -ETIME:
- /* Usually precursor to a hot-unplug on OHCI. */
- default:
- self->netdev->stats.rx_errors++;
- pr_debug("%s(), RX status %d, transfer_flags 0x%04X\n",
- __func__, urb->status, urb->transfer_flags);
- break;
- }
- /* If we received an error, we don't want to resubmit the
- * Rx URB straight away but to give the USB layer a little
- * bit of breathing room.
- * We are in the USB thread context, therefore there is a
- * danger of recursion (new URB we submit fails, we come
- * back here).
- * With recent USB stack (2.6.15+), I'm seeing that on
- * hot unplug of the dongle...
- * Lowest effective timer is 10ms...
- * Jean II */
- self->rx_defer_timer.function = irda_usb_rx_defer_expired;
- self->rx_defer_timer.data = (unsigned long) urb;
- mod_timer(&self->rx_defer_timer,
- jiffies + msecs_to_jiffies(10));
-
- return;
- }
-
- /* Check for empty frames */
- if (urb->actual_length <= self->header_length) {
- net_warn_ratelimited("%s(), empty frame!\n", __func__);
- goto done;
- }
-
- /*
- * Remember the time we received this frame, so we can
- * reduce the min turn time a bit since we will know
- * how much time we have used for protocol processing
- */
- self->stamp = ktime_get();
-
- /* Check if we need to copy the data to a new skb or not.
- * For most frames, we use ZeroCopy and pass the already
- * allocated skb up the stack.
- * If the frame is small, it is more efficient to copy it
- * to save memory (copy will be fast anyway - that's
- * called Rx-copy-break). Jean II */
- docopy = (urb->actual_length < IRDA_RX_COPY_THRESHOLD);
-
- /* Allocate a new skb */
- if (self->capability & IUC_STIR421X)
- newskb = dev_alloc_skb(docopy ? urb->actual_length :
- IRDA_SKB_MAX_MTU +
- USB_IRDA_STIR421X_HEADER);
- else
- newskb = dev_alloc_skb(docopy ? urb->actual_length :
- IRDA_SKB_MAX_MTU);
-
- if (!newskb) {
- self->netdev->stats.rx_dropped++;
- /* We could deliver the current skb, but this would stall
- * the Rx path. Better drop the packet... Jean II */
- goto done;
- }
-
- /* Make sure IP header get aligned (IrDA header is 5 bytes) */
- /* But IrDA-USB header is 1 byte. Jean II */
- //skb_reserve(newskb, USB_IRDA_HEADER - 1);
-
- if(docopy) {
- /* Copy packet, so we can recycle the original */
- skb_copy_from_linear_data(skb, newskb->data, urb->actual_length);
- /* Deliver this new skb */
- dataskb = newskb;
- /* And hook the old skb to the URB
- * Note : we don't need to "clean up" the old skb,
- * as we never touched it. Jean II */
- } else {
- /* We are using ZeroCopy. Deliver old skb */
- dataskb = skb;
- /* And hook the new skb to the URB */
- skb = newskb;
- }
-
- /* Set proper length on skb & remove USB-IrDA header */
- skb_put(dataskb, urb->actual_length);
- skb_pull(dataskb, self->header_length);
-
- /* Ask the networking layer to queue the packet for the IrDA stack */
- dataskb->dev = self->netdev;
- skb_reset_mac_header(dataskb);
- dataskb->protocol = htons(ETH_P_IRDA);
- len = dataskb->len;
- netif_rx(dataskb);
-
- /* Keep stats up to date */
- self->netdev->stats.rx_bytes += len;
- self->netdev->stats.rx_packets++;
-
-done:
- /* Note : at this point, the URB we've just received (urb)
- * is still referenced by the USB layer. For example, if we
- * have received a -ECONNRESET, uhci_cleanup_unlink() will
- * continue to process it (in fact, cleaning it up).
- * If we were to submit this URB, disaster would ensue.
- * Therefore, we submit our idle URB, and put this URB in our
- * idle slot....
- * Jean II */
- /* Note : with this scheme, we could submit the idle URB before
- * processing the Rx URB. I don't think it would buy us anything as
- * we are running in the USB thread context. Jean II */
- next_urb = self->idle_rx_urb;
-
- /* Recycle Rx URB : Now, the idle URB is the present one */
- urb->context = NULL;
- self->idle_rx_urb = urb;
-
- /* Submit the idle URB to replace the URB we've just received.
- * Do it last to avoid race conditions... Jean II */
- irda_usb_submit(self, skb, next_urb);
-}
-
-/*------------------------------------------------------------------*/
-/*
- * In case of errors, we want the USB layer to have time to recover.
- * Now, it is time to resubmit ouur Rx URB...
- */
-static void irda_usb_rx_defer_expired(unsigned long data)
-{
- struct urb *urb = (struct urb *) data;
- struct sk_buff *skb = (struct sk_buff *) urb->context;
- struct irda_usb_cb *self;
- struct irda_skb_cb *cb;
- struct urb *next_urb;
-
- /* Find ourselves */
- cb = (struct irda_skb_cb *) skb->cb;
- IRDA_ASSERT(cb != NULL, return;);
- self = (struct irda_usb_cb *) cb->context;
- IRDA_ASSERT(self != NULL, return;);
-
- /* Same stuff as when Rx is done, see above... */
- next_urb = self->idle_rx_urb;
- urb->context = NULL;
- self->idle_rx_urb = urb;
- irda_usb_submit(self, skb, next_urb);
-}
-
-/*------------------------------------------------------------------*/
-/*
- * Callbak from IrDA layer. IrDA wants to know if we have
- * started receiving anything.
- */
-static int irda_usb_is_receiving(struct irda_usb_cb *self)
-{
- /* Note : because of the way UHCI works, it's almost impossible
- * to get this info. The Controller DMA directly to memory and
- * signal only when the whole frame is finished. To know if the
- * first TD of the URB has been filled or not seems hard work...
- *
- * The other solution would be to use the "receiving" command
- * on the default decriptor with a usb_control_msg(), but that
- * would add USB traffic and would return result only in the
- * next USB frame (~1ms).
- *
- * I've been told that current dongles send status info on their
- * interrupt endpoint, and that's what the Windows driver uses
- * to know this info. Unfortunately, this is not yet in the spec...
- *
- * Jean II
- */
-
- return 0; /* For now */
-}
-
-#define STIR421X_PATCH_PRODUCT_VER "Product Version: "
-#define STIR421X_PATCH_STMP_TAG "STMP"
-#define STIR421X_PATCH_CODE_OFFSET 512 /* patch image starts before here */
-/* marks end of patch file header (PC DOS text file EOF character) */
-#define STIR421X_PATCH_END_OF_HDR_TAG 0x1A
-#define STIR421X_PATCH_BLOCK_SIZE 1023
-
-/*
- * Function stir421x_fwupload (struct irda_usb_cb *self,
- * unsigned char *patch,
- * const unsigned int patch_len)
- *
- * Upload firmware code to SigmaTel 421X IRDA-USB dongle
- */
-static int stir421x_fw_upload(struct irda_usb_cb *self,
- const unsigned char *patch,
- const unsigned int patch_len)
-{
- int ret = -ENOMEM;
- int actual_len = 0;
- unsigned int i;
- unsigned int block_size = 0;
- unsigned char *patch_block;
-
- patch_block = kzalloc(STIR421X_PATCH_BLOCK_SIZE, GFP_KERNEL);
- if (patch_block == NULL)
- return -ENOMEM;
-
- /* break up patch into 1023-byte sections */
- for (i = 0; i < patch_len; i += block_size) {
- block_size = patch_len - i;
-
- if (block_size > STIR421X_PATCH_BLOCK_SIZE)
- block_size = STIR421X_PATCH_BLOCK_SIZE;
-
- /* upload the patch section */
- memcpy(patch_block, patch + i, block_size);
-
- ret = usb_bulk_msg(self->usbdev,
- usb_sndbulkpipe(self->usbdev,
- self->bulk_out_ep),
- patch_block, block_size,
- &actual_len, msecs_to_jiffies(500));
- pr_debug("%s(): Bulk send %u bytes, ret=%d\n",
- __func__, actual_len, ret);
-