diff options
Diffstat (limited to 'drivers/net/irda/irda-usb.c')
| -rw-r--r-- | drivers/net/irda/irda-usb.c | 687 |
1 files changed, 317 insertions, 370 deletions
diff --git a/drivers/net/irda/irda-usb.c b/drivers/net/irda/irda-usb.c index cd87593e4e8..925b78cc979 100644 --- a/drivers/net/irda/irda-usb.c +++ b/drivers/net/irda/irda-usb.c @@ -58,7 +58,6 @@ #include <linux/moduleparam.h> #include <linux/kernel.h> #include <linux/types.h> -#include <linux/init.h> #include <linux/skbuff.h> #include <linux/netdevice.h> #include <linux/slab.h> @@ -83,9 +82,9 @@ static struct usb_device_id dongles[] = { /* 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_STIR_4210 | IUC_SPEED_BUG }, - { USB_DEVICE(0x66f, 0x4220), .driver_info = IUC_STIR_4210 | IUC_SPEED_BUG }, - { USB_DEVICE(0x66f, 0x4116), .driver_info = IUC_STIR_4210 | IUC_SPEED_BUG }, + { 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, @@ -111,18 +110,18 @@ 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 int irda_usb_hard_xmit(struct sk_buff *skb, struct net_device *dev); +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, struct pt_regs *regs); -static void write_bulk_callback(struct urb *urb, struct pt_regs *regs); -static void irda_usb_receive(struct urb *urb, struct pt_regs *regs); +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); -static struct net_device_stats *irda_usb_net_get_stats(struct net_device *dev); /************************ TRANSMIT ROUTINES ************************/ /* @@ -154,7 +153,7 @@ static void irda_usb_build_header(struct irda_usb_cb *self, * and if either speed or xbofs (or both) needs * to be changed. */ - if (self->capability & IUC_STIR_4210 && + if (self->capability & IUC_STIR421X && ((self->new_speed != -1) || (self->new_xbofs != -1))) { /* With STIR421x, speed and xBOFs must be set at the same @@ -177,12 +176,12 @@ static void irda_usb_build_header(struct irda_usb_cb *self, (!force) && (self->speed != -1)) { /* No speed and xbofs change here * (we'll do it later in the write callback) */ - IRDA_DEBUG(2, "%s(), not changing speed yet\n", __FUNCTION__); + IRDA_DEBUG(2, "%s(), not changing speed yet\n", __func__); *header = 0; return; } - IRDA_DEBUG(2, "%s(), changing speed to %d\n", __FUNCTION__, self->new_speed); + IRDA_DEBUG(2, "%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 */ @@ -228,7 +227,7 @@ static void irda_usb_build_header(struct irda_usb_cb *self, /* Set the negotiated additional XBOFS */ if (self->new_xbofs != -1) { - IRDA_DEBUG(2, "%s(), changing xbofs to %d\n", __FUNCTION__, self->new_xbofs); + IRDA_DEBUG(2, "%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 */ @@ -302,13 +301,13 @@ static void irda_usb_change_speed_xbofs(struct irda_usb_cb *self) struct urb *urb; int ret; - IRDA_DEBUG(2, "%s(), speed=%d, xbofs=%d\n", __FUNCTION__, + IRDA_DEBUG(2, "%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) { - IRDA_WARNING("%s(), URB still in use!\n", __FUNCTION__); + IRDA_WARNING("%s(), URB still in use!\n", __func__); return; } @@ -318,7 +317,7 @@ static void irda_usb_change_speed_xbofs(struct irda_usb_cb *self) /* Set the new speed and xbofs in this fake frame */ irda_usb_build_header(self, frame, 1); - if ( self->capability & IUC_STIR_4210 ) { + 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; @@ -334,7 +333,7 @@ static void irda_usb_change_speed_xbofs(struct irda_usb_cb *self) /* Irq disabled -> GFP_ATOMIC */ if ((ret = usb_submit_urb(urb, GFP_ATOMIC))) { - IRDA_WARNING("%s(), failed Speed URB\n", __FUNCTION__); + IRDA_WARNING("%s(), failed Speed URB\n", __func__); } } @@ -343,11 +342,11 @@ static void irda_usb_change_speed_xbofs(struct irda_usb_cb *self) * Speed URB callback * Now, we can only get called for the speed URB. */ -static void speed_bulk_callback(struct urb *urb, struct pt_regs *regs) +static void speed_bulk_callback(struct urb *urb) { struct irda_usb_cb *self = urb->context; - IRDA_DEBUG(2, "%s()\n", __FUNCTION__); + IRDA_DEBUG(2, "%s()\n", __func__); /* We should always have a context */ IRDA_ASSERT(self != NULL, return;); @@ -357,7 +356,7 @@ static void speed_bulk_callback(struct urb *urb, struct pt_regs *regs) /* Check for timeout and other USB nasties */ if (urb->status != 0) { /* I get a lot of -ECONNABORTED = -103 here - Jean II */ - IRDA_DEBUG(0, "%s(), URB complete status %d, transfer_flags 0x%04X\n", __FUNCTION__, urb->status, urb->transfer_flags); + IRDA_DEBUG(0, "%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 @@ -370,7 +369,7 @@ static void speed_bulk_callback(struct urb *urb, struct pt_regs *regs) /* urb is now available */ //urb->status = 0; -> tested above - /* New speed and xbof is now commited in hardware */ + /* New speed and xbof is now committed in hardware */ self->new_speed = -1; self->new_xbofs = -1; @@ -382,17 +381,17 @@ static void speed_bulk_callback(struct urb *urb, struct pt_regs *regs) /* * Send an IrDA frame to the USB dongle (for transmission) */ -static int irda_usb_hard_xmit(struct sk_buff *skb, struct net_device *netdev) +static netdev_tx_t irda_usb_hard_xmit(struct sk_buff *skb, + struct net_device *netdev) { - struct irda_usb_cb *self = netdev->priv; + struct irda_usb_cb *self = netdev_priv(netdev); struct urb *urb = self->tx_urb; unsigned long flags; s32 speed; s16 xbofs; int res, mtt; - int err = 1; /* Failed */ - IRDA_DEBUG(4, "%s() on %s\n", __FUNCTION__, netdev->name); + IRDA_DEBUG(4, "%s() on %s\n", __func__, netdev->name); netif_stop_queue(netdev); @@ -403,7 +402,7 @@ static int irda_usb_hard_xmit(struct sk_buff *skb, struct net_device *netdev) * We need to check self->present under the spinlock because * of irda_usb_disconnect() is synchronous - Jean II */ if (!self->present) { - IRDA_DEBUG(0, "%s(), Device is gone...\n", __FUNCTION__); + IRDA_DEBUG(0, "%s(), Device is gone...\n", __func__); goto drop; } @@ -431,35 +430,22 @@ static int irda_usb_hard_xmit(struct sk_buff *skb, struct net_device *netdev) irda_usb_change_speed_xbofs(self); netdev->trans_start = jiffies; /* Will netif_wake_queue() in callback */ - err = 0; /* No error */ goto drop; } } if (urb->status != 0) { - IRDA_WARNING("%s(), URB still in use!\n", __FUNCTION__); + IRDA_WARNING("%s(), URB still in use!\n", __func__); goto drop; } - /* Make sure there is room for IrDA-USB header. The actual - * allocation will be done lower in skb_push(). - * Also, we don't use directly skb_cow(), because it require - * headroom >= 16, which force unnecessary copies - Jean II */ - if (skb_headroom(skb) < self->header_length) { - IRDA_DEBUG(0, "%s(), Insuficient skb headroom.\n", __FUNCTION__); - if (skb_cow(skb, self->header_length)) { - IRDA_WARNING("%s(), failed skb_cow() !!!\n", __FUNCTION__); - 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_STIR_4210 ) { + if (self->capability & IUC_STIR421X) { __u8 turnaround_time; - __u8* frame; + __u8* frame = self->tx_buff; turnaround_time = get_turnaround_time( skb ); - frame= skb_push(skb, self->header_length); irda_usb_build_header(self, frame, 0); frame[2] = turnaround_time; if ((skb->len != 0) && @@ -472,17 +458,17 @@ static int irda_usb_hard_xmit(struct sk_buff *skb, struct net_device *netdev) frame[1] = 0; } } else { - irda_usb_build_header(self, skb_push(skb, self->header_length), 0); + 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_fill_bulk_urb(urb, self->usbdev, usb_sndbulkpipe(self->usbdev, self->bulk_out_ep), - skb->data, IRDA_SKB_MAX_MTU, + self->tx_buff, skb->len + self->header_length, write_bulk_callback, skb); - urb->transfer_buffer_length = skb->len; + /* 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) @@ -536,39 +522,39 @@ static int irda_usb_hard_xmit(struct sk_buff *skb, struct net_device *netdev) /* Ask USB to send the packet - Irq disabled -> GFP_ATOMIC */ if ((res = usb_submit_urb(urb, GFP_ATOMIC))) { - IRDA_WARNING("%s(), failed Tx URB\n", __FUNCTION__); - self->stats.tx_errors++; + IRDA_WARNING("%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 */ - self->stats.tx_packets++; - self->stats.tx_bytes += skb->len; + netdev->stats.tx_packets++; + netdev->stats.tx_bytes += skb->len; netdev->trans_start = jiffies; } spin_unlock_irqrestore(&self->lock, flags); - return 0; + return NETDEV_TX_OK; drop: /* Drop silently the skb and exit */ dev_kfree_skb(skb); spin_unlock_irqrestore(&self->lock, flags); - return err; /* Usually 1 */ + return NETDEV_TX_OK; } /*------------------------------------------------------------------*/ /* * Note : this function will be called only for tx_urb... */ -static void write_bulk_callback(struct urb *urb, struct pt_regs *regs) +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; - IRDA_DEBUG(2, "%s()\n", __FUNCTION__); + IRDA_DEBUG(2, "%s()\n", __func__); /* We should always have a context */ IRDA_ASSERT(self != NULL, return;); @@ -582,7 +568,7 @@ static void write_bulk_callback(struct urb *urb, struct pt_regs *regs) /* Check for timeout and other USB nasties */ if (urb->status != 0) { /* I get a lot of -ECONNABORTED = -103 here - Jean II */ - IRDA_DEBUG(0, "%s(), URB complete status %d, transfer_flags 0x%04X\n", __FUNCTION__, urb->status, urb->transfer_flags); + IRDA_DEBUG(0, "%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... @@ -601,7 +587,7 @@ static void write_bulk_callback(struct urb *urb, struct pt_regs *regs) /* If the network is closed, stop everything */ if ((!self->netopen) || (!self->present)) { - IRDA_DEBUG(0, "%s(), Network is gone...\n", __FUNCTION__); + IRDA_DEBUG(0, "%s(), Network is gone...\n", __func__); spin_unlock_irqrestore(&self->lock, flags); return; } @@ -612,10 +598,10 @@ static void write_bulk_callback(struct urb *urb, struct pt_regs *regs) (self->new_xbofs != self->xbofs)) { /* We haven't changed speed yet (because of * IUC_SPEED_BUG), so do it now - Jean II */ - IRDA_DEBUG(1, "%s(), Changing speed now...\n", __FUNCTION__); + IRDA_DEBUG(1, "%s(), Changing speed now...\n", __func__); irda_usb_change_speed_xbofs(self); } else { - /* New speed and xbof is now commited in hardware */ + /* New speed and xbof is now committed in hardware */ self->new_speed = -1; self->new_xbofs = -1; /* Done, waiting for next packet */ @@ -640,11 +626,11 @@ static void write_bulk_callback(struct urb *urb, struct pt_regs *regs) static void irda_usb_net_timeout(struct net_device *netdev) { unsigned long flags; - struct irda_usb_cb *self = netdev->priv; + struct irda_usb_cb *self = netdev_priv(netdev); struct urb *urb; int done = 0; /* If we have made any progress */ - IRDA_DEBUG(0, "%s(), Network layer thinks we timed out!\n", __FUNCTION__); + IRDA_DEBUG(0, "%s(), Network layer thinks we timed out!\n", __func__); IRDA_ASSERT(self != NULL, return;); /* Protect us from USB callbacks, net Tx and else. */ @@ -652,7 +638,7 @@ static void irda_usb_net_timeout(struct net_device *netdev) /* self->present *MUST* be read under spinlock */ if (!self->present) { - IRDA_WARNING("%s(), device not present!\n", __FUNCTION__); + IRDA_WARNING("%s(), device not present!\n", __func__); netif_stop_queue(netdev); spin_unlock_irqrestore(&self->lock, flags); return; @@ -671,10 +657,8 @@ static void irda_usb_net_timeout(struct net_device *netdev) * Jean II */ done = 1; break; - case -ECONNABORTED: /* -103 */ - case -ECONNRESET: /* -104 */ - case -ETIMEDOUT: /* -110 */ - case -ENOENT: /* -2 (urb unlinked by us) */ + case -ECONNRESET: + case -ENOENT: /* urb unlinked by us */ default: /* ??? - Play safe */ urb->status = 0; netif_wake_queue(self->netdev); @@ -691,7 +675,7 @@ static void irda_usb_net_timeout(struct net_device *netdev) IRDA_DEBUG(0, "%s: Tx timed out, urb->status=%d, urb->transfer_flags=0x%04X\n", netdev->name, urb->status, urb->transfer_flags); /* Increase error count */ - self->stats.tx_errors++; + netdev->stats.tx_errors++; #ifdef IU_BUG_KICK_TIMEOUT /* Can't be a bad idea to reset the speed ;-) - Jean II */ @@ -712,10 +696,8 @@ static void irda_usb_net_timeout(struct net_device *netdev) * Jean II */ done = 1; break; - case -ECONNABORTED: /* -103 */ - case -ECONNRESET: /* -104 */ - case -ETIMEDOUT: /* -110 */ - case -ENOENT: /* -2 (urb unlinked by us) */ + case -ECONNRESET: + case -ENOENT: /* urb unlinked by us */ default: /* ??? - Play safe */ if(skb != NULL) { dev_kfree_skb_any(skb); @@ -779,7 +761,7 @@ static void irda_usb_submit(struct irda_usb_cb *self, struct sk_buff *skb, struc struct irda_skb_cb *cb; int ret; - IRDA_DEBUG(2, "%s()\n", __FUNCTION__); + IRDA_DEBUG(2, "%s()\n", __func__); /* This should never happen */ IRDA_ASSERT(skb != NULL, return;); @@ -802,7 +784,7 @@ static void irda_usb_submit(struct irda_usb_cb *self, struct sk_buff *skb, struc /* If this ever happen, we are in deep s***. * Basically, the Rx path will stop... */ IRDA_WARNING("%s(), Failed to submit Rx URB %d\n", - __FUNCTION__, ret); + __func__, ret); } } @@ -813,7 +795,7 @@ static void irda_usb_submit(struct irda_usb_cb *self, struct sk_buff *skb, struc * Called by the USB subsystem when a frame has been received * */ -static void irda_usb_receive(struct urb *urb, struct pt_regs *regs) +static void irda_usb_receive(struct urb *urb) { struct sk_buff *skb = (struct sk_buff *) urb->context; struct irda_usb_cb *self; @@ -823,7 +805,7 @@ static void irda_usb_receive(struct urb *urb, struct pt_regs *regs) struct urb *next_urb; unsigned int len, docopy; - IRDA_DEBUG(2, "%s(), len=%d\n", __FUNCTION__, urb->actual_length); + IRDA_DEBUG(2, "%s(), len=%d\n", __func__, urb->actual_length); /* Find ourselves */ cb = (struct irda_skb_cb *) skb->cb; @@ -833,7 +815,7 @@ static void irda_usb_receive(struct urb *urb, struct pt_regs *regs) /* If the network is closed or the device gone, stop everything */ if ((!self->netopen) || (!self->present)) { - IRDA_DEBUG(0, "%s(), Network is gone!\n", __FUNCTION__); + IRDA_DEBUG(0, "%s(), Network is gone!\n", __func__); /* Don't re-submit the URB : will stall the Rx path */ return; } @@ -842,21 +824,21 @@ static void irda_usb_receive(struct urb *urb, struct pt_regs *regs) if (urb->status != 0) { switch (urb->status) { case -EILSEQ: - self->stats.rx_crc_errors++; + self->netdev->stats.rx_crc_errors++; /* Also precursor to a hot-unplug on UHCI. */ /* Fallthrough... */ - case -ECONNRESET: /* -104 */ + 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: /* -108 */ + case -ESHUTDOWN: /* That's usually a hot-unplug. Submit will fail... */ - case -ETIMEDOUT: /* -110 */ + case -ETIME: /* Usually precursor to a hot-unplug on OHCI. */ default: - self->stats.rx_errors++; - IRDA_DEBUG(0, "%s(), RX status %d, transfer_flags 0x%04X \n", __FUNCTION__, urb->status, urb->transfer_flags); + self->netdev->stats.rx_errors++; + IRDA_DEBUG(0, "%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 @@ -869,7 +851,7 @@ static void irda_usb_receive(struct urb *urb, struct pt_regs *regs) * 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.function = irda_usb_rx_defer_expired; self->rx_defer_timer.data = (unsigned long) urb; mod_timer(&self->rx_defer_timer, jiffies + (10 * HZ / 1000)); return; @@ -877,7 +859,7 @@ static void irda_usb_receive(struct urb *urb, struct pt_regs *regs) /* Check for empty frames */ if (urb->actual_length <= self->header_length) { - IRDA_WARNING("%s(), empty frame!\n", __FUNCTION__); + IRDA_WARNING("%s(), empty frame!\n", __func__); goto done; } @@ -897,13 +879,16 @@ static void irda_usb_receive(struct urb *urb, struct pt_regs *regs) docopy = (urb->actual_length < IRDA_RX_COPY_THRESHOLD); /* Allocate a new skb */ - if ( self->capability & IUC_STIR_4210 ) - newskb = dev_alloc_skb(docopy ? urb->actual_length : IRDA_SKB_MAX_MTU + USB_IRDA_SIGMATEL_HEADER); + 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); + newskb = dev_alloc_skb(docopy ? urb->actual_length : + IRDA_SKB_MAX_MTU); if (!newskb) { - self->stats.rx_dropped++; + 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; @@ -915,7 +900,7 @@ static void irda_usb_receive(struct urb *urb, struct pt_regs *regs) if(docopy) { /* Copy packet, so we can recycle the original */ - memcpy(newskb->data, skb->data, urb->actual_length); + 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 @@ -934,15 +919,14 @@ static void irda_usb_receive(struct urb *urb, struct pt_regs *regs) /* Ask the networking layer to queue the packet for the IrDA stack */ dataskb->dev = self->netdev; - dataskb->mac.raw = dataskb->data; + skb_reset_mac_header(dataskb); dataskb->protocol = htons(ETH_P_IRDA); len = dataskb->len; netif_rx(dataskb); /* Keep stats up to date */ - self->stats.rx_bytes += len; - self->stats.rx_packets++; - self->netdev->last_rx = jiffies; + self->netdev->stats.rx_bytes += len; + self->netdev->stats.rx_packets++; done: /* Note : at this point, the URB we've just received (urb) @@ -980,7 +964,7 @@ static void irda_usb_rx_defer_expired(unsigned long data) struct irda_skb_cb *cb; struct urb *next_urb; - IRDA_DEBUG(2, "%s()\n", __FUNCTION__); + IRDA_DEBUG(2, "%s()\n", __func__); /* Find ourselves */ cb = (struct irda_skb_cb *) skb->cb; @@ -1022,188 +1006,142 @@ static int irda_usb_is_receiving(struct irda_usb_cb *self) return 0; /* For now */ } - -#define STIR421X_PATCH_PRODUCT_VERSION_STR "Product Version: " -#define STIR421X_PATCH_COMPONENT_VERSION_STR "Component Version: " -#define STIR421X_PATCH_DATA_TAG_STR "STMP" -#define STIR421X_PATCH_FILE_VERSION_MAX_OFFSET 512 /* version info is before here */ -#define STIR421X_PATCH_FILE_IMAGE_MAX_OFFSET 512 /* patch image starts before here */ -#define STIR421X_PATCH_FILE_END_OF_HEADER_TAG 0x1A /* marks end of patch file header (PC DOS text file EOF character) */ +#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 /* - * Known firmware patches for STIR421x dongles + * 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 char * stir421x_patches[] = { - "42101001.sb", - "42101002.sb", -}; - -static int stir421x_get_patch_version(unsigned char * patch, const unsigned long patch_len) +static int stir421x_fw_upload(struct irda_usb_cb *self, + const unsigned char *patch, + const unsigned int patch_len) { - unsigned int version_offset; - unsigned long version_major, version_minor, version_build; - unsigned char * version_start; - int version_found = 0; - - for (version_offset = 0; - version_offset < STIR421X_PATCH_FILE_END_OF_HEADER_TAG; - version_offset++) { - if (!memcmp(patch + version_offset, - STIR421X_PATCH_PRODUCT_VERSION_STR, - sizeof(STIR421X_PATCH_PRODUCT_VERSION_STR) - 1)) { - version_found = 1; - version_start = patch + - version_offset + - sizeof(STIR421X_PATCH_PRODUCT_VERSION_STR) - 1; - break; - } - } - - /* We couldn't find a product version on this patch */ - if (!version_found) - return -EINVAL; - - /* Let's check if the product version is dotted */ - if (version_start[3] != '.' || - version_start[7] != '.') - return -EINVAL; - - version_major = simple_strtoul(version_start, NULL, 10); - version_minor = simple_strtoul(version_start + 4, NULL, 10); - version_build = simple_strtoul(version_start + 8, NULL, 10); - - IRDA_DEBUG(2, "%s(), Major: %ld Minor: %ld Build: %ld\n", - __FUNCTION__, - version_major, version_minor, version_build); - - return (((version_major) << 12) + - ((version_minor) << 8) + - ((version_build / 10) << 4) + - (version_build % 10)); - -} + 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)); + IRDA_DEBUG(3,"%s(): Bulk send %u bytes, ret=%d\n", + __func__, actual_len, ret); + + if (ret < 0) + break; + mdelay(10); + } -static int stir421x_upload_patch (struct irda_usb_cb *self, - unsigned char * patch, - const unsigned int patch_len) -{ - int retval = 0; - int actual_len; - unsigned int i = 0, download_amount = 0; - unsigned char * patch_chunk; - - IRDA_DEBUG (2, "%s(), Uploading STIR421x Patch\n", __FUNCTION__); - - patch_chunk = kzalloc(STIR421X_MAX_PATCH_DOWNLOAD_SIZE, GFP_KERNEL); - if (patch_chunk == NULL) - return -ENOMEM; - - /* break up patch into 1023-byte sections */ - for (i = 0; retval >= 0 && i < patch_len; i += download_amount) { - download_amount = patch_len - i; - if (download_amount > STIR421X_MAX_PATCH_DOWNLOAD_SIZE) - download_amount = STIR421X_MAX_PATCH_DOWNLOAD_SIZE; - - /* download the patch section */ - memcpy(patch_chunk, patch + i, download_amount); - - retval = usb_bulk_msg (self->usbdev, - usb_sndbulkpipe (self->usbdev, - self->bulk_out_ep), - patch_chunk, download_amount, - &actual_len, msecs_to_jiffies (500)); - IRDA_DEBUG (2, "%s(), Sent %u bytes\n", __FUNCTION__, - actual_len); - if (retval == 0) - mdelay(10); - } - - kfree(patch_chunk); - - if (i != patch_len) { - IRDA_ERROR ("%s(), Pushed %d bytes (!= patch_len (%d))\n", - __FUNCTION__, i, patch_len); - retval = -EIO; - } - - if (retval < 0) - /* todo - mark device as not ready */ - IRDA_ERROR ("%s(), STIR421x patch upload failed (%d)\n", - __FUNCTION__, retval); - - return retval; -} + kfree(patch_block); + return ret; + } +/* + * Function stir421x_patch_device(struct irda_usb_cb *self) + * + * Get a firmware code from userspase using hotplug request_firmware() call + */ static int stir421x_patch_device(struct irda_usb_cb *self) { - unsigned int i, patch_found = 0, data_found = 0, data_offset; - int patch_version, ret = 0; - const struct firmware *fw_entry; - - for (i = 0; i < ARRAY_SIZE(stir421x_patches); i++) { - if(request_firmware(&fw_entry, stir421x_patches[i], &self->usbdev->dev) != 0) { - IRDA_ERROR( "%s(), Patch %s is not available\n", __FUNCTION__, stir421x_patches[i]); - continue; - } - - /* We found a patch from userspace */ - patch_version = stir421x_get_patch_version (fw_entry->data, fw_entry->size); - - if (patch_version < 0) { - /* Couldn't fetch a version, let's move on to the next file */ - IRDA_ERROR("%s(), version parsing failed\n", __FUNCTION__); - ret = patch_version; - release_firmware(fw_entry); - continue; - } - - if (patch_version != self->usbdev->descriptor.bcdDevice) { - /* Patch version and device don't match */ - IRDA_ERROR ("%s(), wrong patch version (%d <-> %d)\n", - __FUNCTION__, - patch_version, self->usbdev->descriptor.bcdDevice); - ret = -EINVAL; - release_firmware(fw_entry); - continue; - } - - /* If we're here, we've found a correct patch */ - patch_found = 1; - break; - - } - - /* We couldn't find a valid firmware, let's leave */ - if (!patch_found) - return ret; - - /* The actual image starts after the "STMP" keyword */ - for (data_offset = 0; data_offset < STIR421X_PATCH_FILE_IMAGE_MAX_OFFSET; data_offset++) { - if (!memcmp(fw_entry->data + data_offset, - STIR421X_PATCH_DATA_TAG_STR, - sizeof(STIR421X_PATCH_FILE_IMAGE_MAX_OFFSET))) { - IRDA_DEBUG(2, "%s(), found patch data for STIR421x at offset %d\n", - __FUNCTION__, data_offset); - data_found = 1; - break; - } - } - - /* We couldn't find "STMP" from the header */ - if (!data_found) - return -EINVAL; - - /* Let's upload the patch to the target */ - ret = stir421x_upload_patch(self, - &fw_entry->data[data_offset + sizeof(STIR421X_PATCH_FILE_IMAGE_MAX_OFFSET)], - fw_entry->size - (data_offset + sizeof(STIR421X_PATCH_FILE_IMAGE_MAX_OFFSET))); - - release_firmware(fw_entry); - - return ret; - + unsigned int i; + int ret; + char stir421x_fw_name[12]; + const struct firmware *fw; + const unsigned char *fw_version_ptr; /* pointer to version string */ + unsigned long fw_version = 0; + + /* + * Known firmware patch file names for STIR421x dongles + * are "42101001.sb" or "42101002.sb" + */ + sprintf(stir421x_fw_name, "4210%4X.sb", + self->usbdev->descriptor.bcdDevice); + ret = request_firmware(&fw, stir421x_fw_name, &self->usbdev->dev); + if (ret < 0) + return ret; + + /* We get a patch from userspace */ + IRDA_MESSAGE("%s(): Received firmware %s (%zu bytes)\n", + __func__, stir421x_fw_name, fw->size); + + ret = -EINVAL; + + /* Get the bcd product version */ + if (!memcmp(fw->data, STIR421X_PATCH_PRODUCT_VER, + sizeof(STIR421X_PATCH_PRODUCT_VER) - 1)) { + fw_version_ptr = fw->data + + sizeof(STIR421X_PATCH_PRODUCT_VER) - 1; + + /* Let's check if the product version is dotted */ + if (fw_version_ptr[3] == '.' && + fw_version_ptr[7] == '.') { + unsigned long major, minor, build; + major = simple_strtoul(fw_version_ptr, NULL, 10); + minor = simple_strtoul(fw_version_ptr + 4, NULL, 10); + build = simple_strtoul(fw_version_ptr + 8, NULL, 10); + + fw_version = (major << 12) + + (minor << 8) + + ((build / 10) << 4) + + (build % 10); + + IRDA_DEBUG(3, "%s(): Firmware Product version %ld\n", + __func__, fw_version); + } + } + + if (self->usbdev->descriptor.bcdDevice == cpu_to_le16(fw_version)) { + /* + * If we're here, we've found a correct patch + * The actual image starts after the "STMP" keyword + * so forward to the firmware header tag + */ + for (i = 0; i < fw->size && fw->data[i] != + STIR421X_PATCH_END_OF_HDR_TAG; i++) ; + /* here we check for the out of buffer case */ + if (i < STIR421X_PATCH_CODE_OFFSET && i < fw->size && + STIR421X_PATCH_END_OF_HDR_TAG == fw->data[i]) { + if (!memcmp(fw->data + i + 1, STIR421X_PATCH_STMP_TAG, + sizeof(STIR421X_PATCH_STMP_TAG) - 1)) { + + /* We can upload the patch to the target */ + i += sizeof(STIR421X_PATCH_STMP_TAG); + ret = stir421x_fw_upload(self, &fw->data[i], + fw->size - i); + } + } + } + + release_firmware(fw); + + return ret; } @@ -1227,23 +1165,27 @@ static int stir421x_patch_device(struct irda_usb_cb *self) static int irda_usb_net_open(struct net_device *netdev) { struct irda_usb_cb *self; + unsigned long flags; char hwname[16]; int i; - IRDA_DEBUG(1, "%s()\n", __FUNCTION__); + IRDA_DEBUG(1, "%s()\n", __func__); IRDA_ASSERT(netdev != NULL, return -1;); - self = (struct irda_usb_cb *) netdev->priv; + self = netdev_priv(netdev); IRDA_ASSERT(self != NULL, return -1;); + spin_lock_irqsave(&self->lock, flags); /* Can only open the device if it's there */ if(!self->present) { - IRDA_WARNING("%s(), device not present!\n", __FUNCTION__); + spin_unlock_irqrestore(&self->lock, flags); + IRDA_WARNING("%s(), device not present!\n", __func__); return -1; } if(self->needspatch) { - IRDA_WARNING("%s(), device needs patch\n", __FUNCTION__) ; + spin_unlock_irqrestore(&self->lock, flags); + IRDA_WARNING("%s(), device needs patch\n", __func__) ; return -EIO ; } @@ -1257,6 +1199,7 @@ static int irda_usb_net_open(struct net_device *netdev) /* To do *before* submitting Rx urbs and starting net Tx queue * Jean II */ self->netopen = 1; + spin_unlock_irqrestore(&self->lock, flags); /* * Now that everything should be initialized properly, @@ -1285,7 +1228,7 @@ static int irda_usb_net_open(struct net_device *netdev) /* If this ever happen, we are in deep s***. * Basically, we can't start the Rx path... */ IRDA_WARNING("%s(), Failed to allocate Rx skb\n", - __FUNCTION__); + __func__); return -1; } //skb_reserve(newskb, USB_IRDA_HEADER - 1); @@ -1308,10 +1251,10 @@ static int irda_usb_net_close(struct net_device *netdev) struct irda_usb_cb *self; int i; - IRDA_DEBUG(1, "%s()\n", __FUNCTION__); + IRDA_DEBUG(1, "%s()\n", __func__); IRDA_ASSERT(netdev != NULL, return -1;); - self = (struct irda_usb_cb *) netdev->priv; + self = netdev_priv(netdev); IRDA_ASSERT(self != NULL, return -1;); /* Clear this flag *before* unlinking the urbs and *before* @@ -1360,10 +1303,10 @@ static int irda_usb_net_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) int ret = 0; IRDA_ASSERT(dev != NULL, return -1;); - self = dev->priv; + self = netdev_priv(dev); IRDA_ASSERT(self != NULL, return -1;); - IRDA_DEBUG(2, "%s(), %s, (cmd=0x%X)\n", __FUNCTION__, dev->name, cmd); + IRDA_DEBUG(2, "%s(), %s, (cmd=0x%X)\n", __func__, dev->name, cmd); switch (cmd) { case SIOCSBANDWIDTH: /* Set bandwidth */ @@ -1397,14 +1340,6 @@ static int irda_usb_net_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) } /*------------------------------------------------------------------*/ -/* - * Get device stats (for /proc/net/dev and ifconfig) - */ -static struct net_device_stats *irda_usb_net_get_stats(struct net_device *dev) -{ - struct irda_usb_cb *self = dev->priv; - return &self->stats; -} /********************* IRDA CONFIG SUBROUTINES *********************/ /* @@ -1421,7 +1356,7 @@ static inline void irda_usb_init_qos(struct irda_usb_cb *self) { struct irda_class_desc *desc; - IRDA_DEBUG(3, "%s()\n", __FUNCTION__); + IRDA_DEBUG(3, "%s()\n", __func__); desc = self->irda_desc; @@ -1438,7 +1373,7 @@ static inline void irda_usb_init_qos(struct irda_usb_cb *self) self->qos.data_size.bits = desc->bmDataSize; IRDA_DEBUG(0, "%s(), dongle says speed=0x%X, size=0x%X, window=0x%X, bofs=0x%X, turn=0x%X\n", - __FUNCTION__, self->qos.baud_rate.bits, self->qos.data_size.bits, self->qos.window_size.bits, self->qos.additional_bofs.bits, self->qos.min_turn_time.bits); + __func__, self->qos.baud_rate.bits, self->qos.data_size.bits, self->qos.window_size.bits, self->qos.additional_bofs.bits, self->qos.min_turn_time.bits); /* Don't always trust what the dongle tell us */ if(self->capability & IUC_SIR_ONLY) @@ -1465,6 +1400,14 @@ static inline void irda_usb_init_qos(struct irda_usb_cb *self) } /*------------------------------------------------------------------*/ +static const struct net_device_ops irda_usb_netdev_ops = { + .ndo_open = irda_usb_net_open, + .ndo_stop = irda_usb_net_close, + .ndo_do_ioctl = irda_usb_net_ioctl, + .ndo_start_xmit = irda_usb_hard_xmit, + .ndo_tx_timeout = irda_usb_net_timeout, +}; + /* * Initialise the network side of the irda-usb instance * Called when a new USB instance is registered in irda_usb_probe() @@ -1473,18 +1416,11 @@ static inline int irda_usb_open(struct irda_usb_cb *self) { struct net_device *netdev = self->netdev; - IRDA_DEBUG(1, "%s()\n", __FUNCTION__); + IRDA_DEBUG(1, "%s()\n", __func__); - irda_usb_init_qos(self); + netdev->netdev_ops = &irda_usb_netdev_ops; - /* Override the network functions we need to use */ - netdev->hard_start_xmit = irda_usb_hard_xmit; - netdev->tx_timeout = irda_usb_net_timeout; - netdev->watchdog_timeo = 250*HZ/1000; /* 250 ms > USB timeout */ - netdev->open = irda_usb_net_open; - netdev->stop = irda_usb_net_close; - netdev->get_stats = irda_usb_net_get_stats; - netdev->do_ioctl = irda_usb_net_ioctl; + irda_usb_init_qos(self); return register_netdev(netdev); } @@ -1496,7 +1432,7 @@ static inline int irda_usb_open(struct irda_usb_cb *self) */ static inline void irda_usb_close(struct irda_usb_cb *self) { - IRDA_DEBUG(1, "%s()\n", __FUNCTION__); + IRDA_DEBUG(1, "%s()\n", __func__); /* Remove netdevice */ unregister_netdev(self->netdev); @@ -1504,6 +1440,9 @@ static inline void irda_usb_close(struct irda_usb_cb *self) /* Remove the speed buffer */ kfree(self->speed_buff); self->speed_buff = NULL; + + kfree(self->tx_buff); + self->tx_buff = NULL; } /********************** USB CONFIG SUBROUTINES **********************/ @@ -1566,17 +1505,15 @@ static inline int irda_usb_parse_endpoints(struct irda_usb_cb *self, struct usb_ /* This is our interrupt endpoint */ self->bulk_int_ep = ep; } else { - IRDA_ERROR("%s(), Unrecognised endpoint %02X.\n", __FUNCTION__, ep); + IRDA_ERROR("%s(), Unrecognised endpoint %02X.\n", __func__, ep); } } } IRDA_DEBUG(0, "%s(), And our endpoints are : in=%02X, out=%02X (%d), int=%02X\n", - __FUNCTION__, self->bulk_in_ep, self->bulk_out_ep, self->bulk_out_mtu, self->bulk_int_ep); - /* Should be 8, 16, 32 or 64 bytes */ - IRDA_ASSERT(self->bulk_out_mtu == 64, ;); + __func__, self->bulk_in_ep, self->bulk_out_ep, self->bulk_out_mtu, self->bulk_int_ep); - return((self->bulk_in_ep != 0) && (self->bulk_out_ep != 0)); + return (self->bulk_in_ep != 0) && (self->bulk_out_ep != 0); } #ifdef IU_DUMP_CLASS_DESC @@ -1619,10 +1556,9 @@ static inline struct irda_class_desc *irda_usb_find_class_desc(struct usb_interf struct irda_class_desc *desc; int ret; - desc = kmalloc(sizeof (*desc), GFP_KERNEL); - if (desc == NULL) + desc = kzalloc(sizeof(*desc), GFP_KERNEL); + if (!desc) return NULL; - memset(desc, 0, sizeof(*desc)); /* USB-IrDA class spec 1.0: * 6.1.3: Standard "Get Descriptor" Device Request is not @@ -1637,7 +1573,7 @@ static inline struct irda_class_desc *irda_usb_find_class_desc(struct usb_interf 0, intf->altsetting->desc.bInterfaceNumber, desc, sizeof(*desc), 500); - IRDA_DEBUG(1, "%s(), ret=%d\n", __FUNCTION__, ret); + IRDA_DEBUG(1, "%s(), ret=%d\n", __func__, ret); if (ret < sizeof(*desc)) { IRDA_WARNING("usb-irda: class_descriptor read %s (%d)\n", (ret<0) ? "failed" : "too short", ret); @@ -1675,7 +1611,7 @@ static int irda_usb_probe(struct usb_interface *intf, { struct net_device *net; struct usb_device *dev = interface_to_usbdev(intf); - struct irda_usb_cb *self = NULL; + struct irda_usb_cb *self; struct usb_host_interface *interface; struct irda_class_desc *irda_desc; int ret = -ENOMEM; @@ -1694,27 +1630,28 @@ static int irda_usb_probe(struct usb_interface *intf, if (!net) goto err_out; - SET_MODULE_OWNER(net); SET_NETDEV_DEV(net, &intf->dev); - self = net->priv; + self = netdev_priv(net); self->netdev = net; spin_lock_init(&self->lock); init_timer(&self->rx_defer_timer); self->capability = id->driver_info; - self->needspatch = ((self->capability & IUC_STIR_4210) != 0) ; + self->needspatch = ((self->capability & IUC_STIR421X) != 0); /* Create all of the needed urbs */ - if (self->capability & IUC_STIR_4210) { + if (self->capability & IUC_STIR421X) { self->max_rx_urb = IU_SIGMATEL_MAX_RX_URBS; - self->header_length = USB_IRDA_SIGMATEL_HEADER; + self->header_length = USB_IRDA_STIR421X_HEADER; } else { self->max_rx_urb = IU_MAX_RX_URBS; self->header_length = USB_IRDA_HEADER; } - self->rx_urb = kzalloc(self->max_rx_urb * sizeof(struct urb *), + self->rx_urb = kcalloc(self->max_rx_urb, sizeof(struct urb *), GFP_KERNEL); + if (!self->rx_urb) + goto err_free_net; for (i = 0; i < self->max_rx_urb; i++) { self->rx_urb[i] = usb_alloc_urb(0, GFP_KERNEL); @@ -1733,7 +1670,7 @@ static int irda_usb_probe(struct usb_interface *intf, /* Is this really necessary? (no, except maybe for broken devices) */ if (usb_reset_configuration (dev) < 0) { - err("reset_configuration failed"); + dev_err(&intf->dev, "reset_configuration failed\n"); ret = -EIO; goto err_out_3; } @@ -1751,10 +1688,10 @@ static int irda_usb_probe(struct usb_interface *intf, /* Martin Diehl says if we get a -EPIPE we should * be fine and we don't need to do a usb_clear_halt(). * - Jean II */ - IRDA_DEBUG(0, "%s(), Received -EPIPE, ignoring...\n", __FUNCTION__); + IRDA_DEBUG(0, "%s(), Received -EPIPE, ignoring...\n", __func__); break; default: - IRDA_DEBUG(0, "%s(), Unknown error %d\n", __FUNCTION__, ret); + IRDA_DEBUG(0, "%s(), Unknown error %d\n", __func__, ret); ret = -EIO; goto err_out_3; } @@ -1763,7 +1700,7 @@ static int irda_usb_probe(struct usb_interface *intf, interface = intf->cur_altsetting; if(!irda_usb_parse_endpoints(self, interface->endpoint, interface->desc.bNumEndpoints)) { - IRDA_ERROR("%s(), Bogus endpoints...\n", __FUNCTION__); + IRDA_ERROR("%s(), Bogus endpoints...\n", __func__); ret = -EIO; goto err_out_3; } @@ -1773,7 +1710,7 @@ static int irda_usb_probe(struct usb_interface *intf, /* Find IrDA class descriptor */ irda_desc = irda_usb_find_class_desc(intf); ret = -ENODEV; - if (irda_desc == NULL) + if (!irda_desc) goto err_out_3; if (self->needspatch) { @@ -1796,15 +1733,18 @@ static int irda_usb_probe(struct usb_interface *intf, /* Don't change this buffer size and allocation without doing * some heavy and complete testing. Don't ask why :-( * Jean II */ - self->speed_buff = (char *) kmalloc(IRDA_USB_SPEED_MTU, GFP_KERNEL); - if (self->speed_buff == NULL) + self->speed_buff = kzalloc(IRDA_USB_SPEED_MTU, GFP_KERNEL); + if (!self->speed_buff) goto err_out_3; - memset(self->speed_buff, 0, IRDA_USB_SPEED_MTU); + self->tx_buff = kzalloc(IRDA_SKB_MAX_MTU + self->header_length, + GFP_KERNEL); + if (!self->tx_buff) + goto err_out_4; ret = irda_usb_open(self); if (ret) - goto err_out_4; + goto err_out_5; IRDA_MESSAGE("IrDA: Registered device %s\n", net->name); usb_set_intfdata(intf, self); @@ -1813,27 +1753,27 @@ static int irda_usb_probe(struct usb_interface *intf, /* Now we fetch and upload the firmware patch */ ret = stir421x_patch_device(self); self->needspatch = (ret < 0); - if (ret < 0) { - printk("patch_device failed\n"); - goto err_out_5; + if (self->needspatch) { + IRDA_ERROR("STIR421X: Couldn't upload patch\n"); + goto err_out_6; } /* replace IrDA class descriptor with what patched device is now reporting */ irda_desc = irda_usb_find_class_desc (self->usbintf); - if (irda_desc == NULL) { + if (!irda_desc) { ret = -ENODEV; - goto err_out_5; + goto err_out_6; } - if (self->irda_desc) - kfree (self->irda_desc); + kfree(self->irda_desc); self->irda_desc = irda_desc; irda_usb_init_qos(self); } return 0; - -err_out_5: +err_out_6: unregister_netdev(self->netdev); +err_out_5: + kfree(self->tx_buff); err_out_4: kfree(self->speed_buff); err_out_3: @@ -1842,10 +1782,10 @@ err_out_3: err_out_2: usb_free_urb(self->tx_urb); err_out_1: - for (i = 0; i < self->max_rx_urb; i++) { - if (self->rx_urb[i]) - usb_free_urb(self->rx_urb[i]); - } + for (i = 0; i < self->max_rx_urb; i++) + usb_free_urb(self->rx_urb[i]); + kfree(self->rx_urb); +err_free_net: free_netdev(net); err_out: return ret; @@ -1869,7 +1809,7 @@ static void irda_usb_disconnect(struct usb_interface *intf) struct irda_usb_cb *self = usb_get_intfdata(intf); int i; - IRDA_DEBUG(1, "%s()\n", __FUNCTION__); + IRDA_DEBUG(1, "%s()\n", __func__); usb_set_intfdata(intf, NULL); if (!self) @@ -1919,55 +1859,62 @@ static void irda_usb_disconnect(struct usb_interface *intf) /* Free self and network device */ free_netdev(self->netdev); - IRDA_DEBUG(0, "%s(), USB IrDA Disconnected\n", __FUNCTION__); + IRDA_DEBUG(0, "%s(), USB IrDA Disconnected\n", __func__); } -/*------------------------------------------------------------------*/ -/* - * USB device callbacks - */ -static struct usb_driver irda_driver = { - .name = "irda-usb", - .probe = irda_usb_probe, - .disconnect = irda_usb_disconnect, - .id_table = dongles, -}; +#ifdef CONFIG_PM +/* USB suspend, so power off the transmitter/receiver */ +static int irda_usb_suspend(struct usb_interface *intf, pm_message_t message) +{ + struct irda_usb_cb *self = usb_get_intfdata(intf); + int i; -/************************* MODULE CALLBACKS *************************/ -/* - * Deal with module insertion/removal - * Mostly tell USB about our existence - */ + netif_device_detach(self->netdev); -/*------------------------------------------------------------------*/ -/* - * Module insertion - */ -static int __init usb_irda_init(void) + if (self->tx_urb != NULL) + usb_kill_urb(self->tx_urb); + if (self->speed_urb != NULL) + usb_kill_urb(self->speed_urb); + for (i = 0; i < self->max_rx_urb; i++) { + if (self->rx_urb[i] != NULL) + usb_kill_urb(self->rx_urb[i]); + } + return 0; +} + +/* Coming out of suspend, so reset hardware */ +static int irda_usb_resume(struct usb_interface *intf) { - int ret; + struct irda_usb_cb *self = usb_get_intfdata(intf); + int i; - ret = usb_register(&irda_driver); - if (ret < 0) - return ret; + for (i = 0; i < self->max_rx_urb; i++) { + if (self->rx_urb[i] != NULL) + usb_submit_urb(self->rx_urb[i], GFP_KERNEL); + } - IRDA_MESSAGE("USB IrDA support registered\n"); + netif_device_attach(self->netdev); return 0; } -module_init(usb_irda_init); +#endif /*------------------------------------------------------------------*/ /* - * Module removal + * USB device callbacks */ -static void __exit usb_irda_cleanup(void) -{ - /* Deregister the driver and remove all pending instances */ - usb_deregister(&irda_driver); -} -module_exit(usb_irda_cleanup); +static struct usb_driver irda_driver = { + .name = "irda-usb", + .probe = irda_usb_probe, + .disconnect = irda_usb_disconnect, + .id_table = dongles, +#ifdef CONFIG_PM + .suspend = irda_usb_suspend, + .resume = irda_usb_resume, +#endif +}; + +module_usb_driver(irda_driver); -/*------------------------------------------------------------------*/ /* * Module parameters */ |
