diff options
author | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2017-08-27 17:03:32 +0200 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2017-08-28 16:42:57 -0700 |
commit | 6c391ff758eb9f41e11c6143fd5bdb3b3324bf9f (patch) | |
tree | 95ee8f47eacb698ecb3de600e73f07bde3f0d404 /drivers/net/irda/irda-usb.c | |
parent | 1ca163afb6fd569b6efdc221954177cba5a02cbc (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.c | 1914 |
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); - |