irda-usb.c 49.3 KB
Newer Older
Linus Torvalds's avatar
Linus Torvalds committed
1 2 3
/*****************************************************************************
 *
 * Filename:      irda-usb.c
Linus Torvalds's avatar
Linus Torvalds committed
4
 * Version:       0.9b
Linus Torvalds's avatar
Linus Torvalds committed
5 6 7 8
 * Description:   IrDA-USB Driver
 * Status:        Experimental 
 * Author:        Dag Brattli <dag@brattli.net>
 *
Linus Torvalds's avatar
Linus Torvalds committed
9
 *	Copyright (C) 2000, Roman Weissgaerber <weissg@vienna.at>
Linus Torvalds's avatar
Linus Torvalds committed
10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28
 *      Copyright (C) 2001, Dag Brattli <dag@brattli.net>
 *      Copyright (C) 2001, Jean Tourrilhes <jt@hpl.hp.com>
 *          
 *	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.
 *
 *****************************************************************************/

Linus Torvalds's avatar
Linus Torvalds committed
29 30 31 32
/*
 *			    IMPORTANT NOTE
 *			    --------------
 *
Jean Tourrilhes's avatar
Jean Tourrilhes committed
33
 * As of kernel 2.5.20, this is the state of compliance and testing of
Linus Torvalds's avatar
Linus Torvalds committed
34 35 36
 * this driver (irda-usb) with regards to the USB low level drivers...
 *
 * This driver has been tested SUCCESSFULLY with the following drivers :
Jean Tourrilhes's avatar
Jean Tourrilhes committed
37 38
 *	o usb-uhci-hcd	(For Intel/Via USB controllers)
 *	o uhci-hcd	(Alternate/JE driver for Intel/Via USB controllers)
39
 *	o ohci-hcd	(For other USB controllers)
Linus Torvalds's avatar
Linus Torvalds committed
40 41
 *
 * This driver has NOT been tested with the following drivers :
Jean Tourrilhes's avatar
Jean Tourrilhes committed
42
 *	o ehci-hcd	(USB 2.0 controllers)
Linus Torvalds's avatar
Linus Torvalds committed
43
 *
44
 * Note that all HCD drivers do URB_ZERO_PACKET and timeout properly,
Jean Tourrilhes's avatar
Jean Tourrilhes committed
45 46 47
 * 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...
Linus Torvalds's avatar
Linus Torvalds committed
48 49 50 51 52 53
 *
 * Jean II
 */

/*------------------------------------------------------------------*/

Linus Torvalds's avatar
Linus Torvalds committed
54 55 56 57 58 59 60
#include <linux/module.h>

#include <linux/kernel.h>
#include <linux/types.h>
#include <linux/init.h>
#include <linux/skbuff.h>
#include <linux/netdevice.h>
Linus Torvalds's avatar
Linus Torvalds committed
61
#include <linux/slab.h>
Linus Torvalds's avatar
Linus Torvalds committed
62 63 64 65 66
#include <linux/rtnetlink.h>
#include <linux/usb.h>

#include <net/irda/irda-usb.h>

Linus Torvalds's avatar
Linus Torvalds committed
67 68
/*------------------------------------------------------------------*/

Linus Torvalds's avatar
Linus Torvalds committed
69 70 71 72
static int qos_mtt_bits = 0;

/* These are the currently known IrDA USB dongles. Add new dongles here */
static struct usb_device_id dongles[] = {
Jean Tourrilhes's avatar
Jean Tourrilhes committed
73
	/* ACTiSYS Corp.,  ACT-IR2000U FIR-USB Adapter */
74
	{ USB_DEVICE(0x9c4, 0x011), .driver_info = IUC_SPEED_BUG | IUC_NO_WINDOW },
Jean Tourrilhes's avatar
Jean Tourrilhes committed
75
	/* Look like ACTiSYS, Report : IBM Corp., IBM UltraPort IrDA */
76
	{ USB_DEVICE(0x4428, 0x012), .driver_info = IUC_SPEED_BUG | IUC_NO_WINDOW },
Linus Torvalds's avatar
Linus Torvalds committed
77
	/* KC Technology Inc.,  KC-180 USB IrDA Device */
78
	{ USB_DEVICE(0x50f, 0x180), .driver_info = IUC_SPEED_BUG | IUC_NO_WINDOW },
Linus Torvalds's avatar
Linus Torvalds committed
79
	/* Extended Systems, Inc.,  XTNDAccess IrDA USB (ESI-9685) */
80 81
	{ USB_DEVICE(0x8e9, 0x100), .driver_info = IUC_SPEED_BUG | IUC_NO_WINDOW },
	{ .match_flags = USB_DEVICE_ID_MATCH_INT_CLASS |
Linus Torvalds's avatar
Linus Torvalds committed
82
	               USB_DEVICE_ID_MATCH_INT_SUBCLASS,
83 84 85
	  .bInterfaceClass = USB_CLASS_APP_SPEC,
	  .bInterfaceSubClass = USB_CLASS_IRDA,
	  .driver_info = IUC_DEFAULT, },
Linus Torvalds's avatar
Linus Torvalds committed
86 87 88
	{ }, /* The end */
};

Linus Torvalds's avatar
Linus Torvalds committed
89 90 91 92 93 94 95 96 97
/*
 * Important note :
 * Devices based on the SigmaTel chipset (0x66f, 0x4200) are not compliant
 * with the USB-IrDA specification (and actually very very different), and
 * there is no way this driver can support those devices, apart from
 * a complete rewrite...
 * Jean II
 */

Linus Torvalds's avatar
Linus Torvalds committed
98 99
MODULE_DEVICE_TABLE(usb, dongles);

Linus Torvalds's avatar
Linus Torvalds committed
100 101
/*------------------------------------------------------------------*/

102 103
static struct irda_class_desc *irda_usb_find_class_desc(struct usb_interface *intf);
static void irda_usb_disconnect(struct usb_interface *intf);
Linus Torvalds's avatar
Linus Torvalds committed
104 105 106
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 int irda_usb_open(struct irda_usb_cb *self);
107
static void irda_usb_close(struct irda_usb_cb *self);
David S. Miller's avatar
David S. Miller committed
108 109 110
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);
Linus Torvalds's avatar
Linus Torvalds committed
111 112 113 114 115 116 117
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 ************************/
Linus Torvalds's avatar
Linus Torvalds committed
118
/*
Linus Torvalds's avatar
Linus Torvalds committed
119
 * Receive packets from the IrDA stack and send them on the USB pipe.
120
 * Handle speed change, timeout and lot's of ugliness...
Linus Torvalds's avatar
Linus Torvalds committed
121 122
 */

Linus Torvalds's avatar
Linus Torvalds committed
123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152
/*------------------------------------------------------------------*/
/*
 * 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)
{
	/* Set the negotiated 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) */
153
			IRDA_DEBUG(2, "%s(), not changing speed yet\n", __FUNCTION__);
Linus Torvalds's avatar
Linus Torvalds committed
154 155
			*header = 0;
			return;
Linus Torvalds's avatar
Linus Torvalds committed
156 157
		}

158
		IRDA_DEBUG(2, "%s(), changing speed to %d\n", __FUNCTION__, self->new_speed);
Linus Torvalds's avatar
Linus Torvalds committed
159
		self->speed = self->new_speed;
Jean Tourrilhes's avatar
Jean Tourrilhes committed
160 161
		/* We will do ` self->new_speed = -1; ' in the completion
		 * handler just in case the current URB fail - Jean II */
Linus Torvalds's avatar
Linus Torvalds committed
162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191

		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;
Linus Torvalds's avatar
Linus Torvalds committed
192 193
			break;
		}
Linus Torvalds's avatar
Linus Torvalds committed
194 195 196
	} else
		/* No change */
		*header = 0;
Linus Torvalds's avatar
Linus Torvalds committed
197
	
Linus Torvalds's avatar
Linus Torvalds committed
198 199
	/* Set the negotiated additional XBOFS */
	if (self->new_xbofs != -1) {
200
		IRDA_DEBUG(2, "%s(), changing xbofs to %d\n", __FUNCTION__, self->new_xbofs);
Linus Torvalds's avatar
Linus Torvalds committed
201
		self->xbofs = self->new_xbofs;
Jean Tourrilhes's avatar
Jean Tourrilhes committed
202 203
		/* We will do ` self->new_xbofs = -1; ' in the completion
		 * handler just in case the current URB fail - Jean II */
Linus Torvalds's avatar
Linus Torvalds committed
204 205 206 207

		switch (self->xbofs) {
		case 48:
			*header |= 0x10;
Linus Torvalds's avatar
Linus Torvalds committed
208
			break;
Linus Torvalds's avatar
Linus Torvalds committed
209 210 211
		case 28:
		case 24:	/* USB spec 1.0 says 24 */
			*header |= 0x20;
Linus Torvalds's avatar
Linus Torvalds committed
212 213
			break;
		default:
Linus Torvalds's avatar
Linus Torvalds committed
214 215
		case 12:
			*header |= 0x30;
Linus Torvalds's avatar
Linus Torvalds committed
216
			break;
Linus Torvalds's avatar
Linus Torvalds committed
217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233
		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;
		}
Linus Torvalds's avatar
Linus Torvalds committed
234
	}
Linus Torvalds's avatar
Linus Torvalds committed
235
}
Linus Torvalds's avatar
Linus Torvalds committed
236

Linus Torvalds's avatar
Linus Torvalds committed
237 238 239
/*------------------------------------------------------------------*/
/*
 * Send a command to change the speed of the dongle
240
 * Need to be called with spinlock on.
Linus Torvalds's avatar
Linus Torvalds committed
241 242 243 244
 */
static void irda_usb_change_speed_xbofs(struct irda_usb_cb *self)
{
	__u8 *frame;
Linus Torvalds's avatar
Linus Torvalds committed
245
	struct urb *urb;
Linus Torvalds's avatar
Linus Torvalds committed
246
	int ret;
Linus Torvalds's avatar
Linus Torvalds committed
247

248
	IRDA_DEBUG(2, "%s(), speed=%d, xbofs=%d\n", __FUNCTION__,
Linus Torvalds's avatar
Linus Torvalds committed
249 250 251
		   self->new_speed, self->new_xbofs);

	/* Grab the speed URB */
252
	urb = self->speed_urb;
Linus Torvalds's avatar
Linus Torvalds committed
253
	if (urb->status != 0) {
254
		WARNING("%s(), URB still in use!\n", __FUNCTION__);
Linus Torvalds's avatar
Linus Torvalds committed
255
		return;
Linus Torvalds's avatar
Linus Torvalds committed
256 257
	}

Linus Torvalds's avatar
Linus Torvalds committed
258 259 260 261 262 263 264
	/* 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);

	/* Submit the 0 length IrDA frame to trigger new speed settings */
265
        usb_fill_bulk_urb(urb, self->usbdev,
Linus Torvalds's avatar
Linus Torvalds committed
266 267 268
		      usb_sndbulkpipe(self->usbdev, self->bulk_out_ep),
                      frame, IRDA_USB_SPEED_MTU,
                      speed_bulk_callback, self);
Linus Torvalds's avatar
Linus Torvalds committed
269
	urb->transfer_buffer_length = USB_IRDA_HEADER;
270
	urb->transfer_flags = URB_ASYNC_UNLINK;
Linus Torvalds's avatar
Linus Torvalds committed
271
	urb->timeout = MSECS_TO_JIFFIES(100);
Linus Torvalds's avatar
Linus Torvalds committed
272

273 274
	/* Irq disabled -> GFP_ATOMIC */
	if ((ret = usb_submit_urb(urb, GFP_ATOMIC))) {
275
		WARNING("%s(), failed Speed URB\n", __FUNCTION__);
Linus Torvalds's avatar
Linus Torvalds committed
276
	}
Linus Torvalds's avatar
Linus Torvalds committed
277 278
}

Linus Torvalds's avatar
Linus Torvalds committed
279
/*------------------------------------------------------------------*/
Linus Torvalds's avatar
Linus Torvalds committed
280
/*
Jean Tourrilhes's avatar
Jean Tourrilhes committed
281 282
 * Speed URB callback
 * Now, we can only get called for the speed URB.
Linus Torvalds's avatar
Linus Torvalds committed
283
 */
David S. Miller's avatar
David S. Miller committed
284
static void speed_bulk_callback(struct urb *urb, struct pt_regs *regs)
Linus Torvalds's avatar
Linus Torvalds committed
285
{
Linus Torvalds's avatar
Linus Torvalds committed
286
	struct irda_usb_cb *self = urb->context;
Linus Torvalds's avatar
Linus Torvalds committed
287
	
288
	IRDA_DEBUG(2, "%s()\n", __FUNCTION__);
Linus Torvalds's avatar
Linus Torvalds committed
289

Linus Torvalds's avatar
Linus Torvalds committed
290
	/* We should always have a context */
Jean Tourrilhes's avatar
Jean Tourrilhes committed
291 292 293
	ASSERT(self != NULL, return;);
	/* We should always be called for the speed URB */
	ASSERT(urb == self->speed_urb, return;);
Linus Torvalds's avatar
Linus Torvalds committed
294

Linus Torvalds's avatar
Linus Torvalds committed
295
	/* Check for timeout and other USB nasties */
Linus Torvalds's avatar
Linus Torvalds committed
296
	if (urb->status != 0) {
Linus Torvalds's avatar
Linus Torvalds committed
297
		/* I get a lot of -ECONNABORTED = -103 here - Jean II */
298
		IRDA_DEBUG(0, "%s(), URB complete status %d, transfer_flags 0x%04X\n", __FUNCTION__, urb->status, urb->transfer_flags);
Linus Torvalds's avatar
Linus Torvalds committed
299

Linus Torvalds's avatar
Linus Torvalds committed
300 301 302 303 304 305 306
		/* 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;
	}
Linus Torvalds's avatar
Linus Torvalds committed
307

Linus Torvalds's avatar
Linus Torvalds committed
308
	/* urb is now available */
Jean Tourrilhes's avatar
Jean Tourrilhes committed
309
	//urb->status = 0; -> tested above
Linus Torvalds's avatar
Linus Torvalds committed
310

Jean Tourrilhes's avatar
Jean Tourrilhes committed
311 312 313 314 315 316
	/* New speed and xbof is now commited in hardware */
	self->new_speed = -1;
	self->new_xbofs = -1;

	/* Allow the stack to send more packets */
	netif_wake_queue(self->netdev);
Linus Torvalds's avatar
Linus Torvalds committed
317 318
}

Linus Torvalds's avatar
Linus Torvalds committed
319 320 321 322 323
/*------------------------------------------------------------------*/
/*
 * Send an IrDA frame to the USB dongle (for transmission)
 */
static int irda_usb_hard_xmit(struct sk_buff *skb, struct net_device *netdev)
Linus Torvalds's avatar
Linus Torvalds committed
324
{
Linus Torvalds's avatar
Linus Torvalds committed
325
	struct irda_usb_cb *self = netdev->priv;
326
	struct urb *urb = self->tx_urb;
Linus Torvalds's avatar
Linus Torvalds committed
327 328 329 330
	unsigned long flags;
	s32 speed;
	s16 xbofs;
	int res, mtt;
Jean Tourrilhes's avatar
Jean Tourrilhes committed
331 332
	int	err = 1;	/* Failed */

333
	IRDA_DEBUG(4, "%s() on %s\n", __FUNCTION__, netdev->name);
Linus Torvalds's avatar
Linus Torvalds committed
334

335 336 337 338 339 340 341 342
	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 */
Jean Tourrilhes's avatar
Jean Tourrilhes committed
343
	if (!self->present) {
344
		IRDA_DEBUG(0, "%s(), Device is gone...\n", __FUNCTION__);
Jean Tourrilhes's avatar
Jean Tourrilhes committed
345
		goto drop;
Linus Torvalds's avatar
Linus Torvalds committed
346
	}
Linus Torvalds's avatar
Linus Torvalds committed
347

Linus Torvalds's avatar
Linus Torvalds committed
348 349 350 351 352
	/* 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;
	}
Linus Torvalds's avatar
Linus Torvalds committed
353

Linus Torvalds's avatar
Linus Torvalds committed
354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371
        /* 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);
			netdev->trans_start = jiffies;
			/* Will netif_wake_queue() in callback */
Jean Tourrilhes's avatar
Jean Tourrilhes committed
372
			err = 0;	/* No error */
373
			goto drop;
Linus Torvalds's avatar
Linus Torvalds committed
374
		}
Linus Torvalds's avatar
Linus Torvalds committed
375 376
	}

Linus Torvalds's avatar
Linus Torvalds committed
377
	if (urb->status != 0) {
378
		WARNING("%s(), URB still in use!\n", __FUNCTION__);
379
		goto drop;
Linus Torvalds's avatar
Linus Torvalds committed
380
	}
Linus Torvalds's avatar
Linus Torvalds committed
381

382 383 384 385 386
	/* 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) < USB_IRDA_HEADER) {
387
		IRDA_DEBUG(0, "%s(), Insuficient skb headroom.\n", __FUNCTION__);
388
		if (skb_cow(skb, USB_IRDA_HEADER)) {
389
			WARNING("%s(), failed skb_cow() !!!\n", __FUNCTION__);
390
			goto drop;
391
		}
Linus Torvalds's avatar
Linus Torvalds committed
392 393
	}

Linus Torvalds's avatar
Linus Torvalds committed
394 395
	/* Change setting for next frame */
	irda_usb_build_header(self, skb_push(skb, USB_IRDA_HEADER), 0);
Linus Torvalds's avatar
Linus Torvalds committed
396

Linus Torvalds's avatar
Linus Torvalds committed
397 398
	/* FIXME: Make macro out of this one */
	((struct irda_skb_cb *)skb->cb)->context = self;
Linus Torvalds's avatar
Linus Torvalds committed
399

400
        usb_fill_bulk_urb(urb, self->usbdev, 
Linus Torvalds's avatar
Linus Torvalds committed
401
		      usb_sndbulkpipe(self->usbdev, self->bulk_out_ep),
402
                      skb->data, IRDA_SKB_MAX_MTU,
Linus Torvalds's avatar
Linus Torvalds committed
403
                      write_bulk_callback, skb);
Linus Torvalds's avatar
Linus Torvalds committed
404
	urb->transfer_buffer_length = skb->len;
Linus Torvalds's avatar
Linus Torvalds committed
405 406
	/* Note : unlink *must* be Asynchronous because of the code in 
	 * irda_usb_net_timeout() -> call in irq - Jean II */
407 408
	urb->transfer_flags = URB_ASYNC_UNLINK;
	/* This flag (URB_ZERO_PACKET) indicates that what we send is not
Linus Torvalds's avatar
Linus Torvalds committed
409 410 411 412
	 * 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 */
413
	urb->transfer_flags |= URB_ZERO_PACKET;
Linus Torvalds's avatar
Linus Torvalds committed
414
	/* Timeout need to be shorter than NET watchdog timer */
Linus Torvalds's avatar
Linus Torvalds committed
415
	urb->timeout = MSECS_TO_JIFFIES(200);
Linus Torvalds's avatar
Linus Torvalds committed
416

Linus Torvalds's avatar
Linus Torvalds committed
417 418
	/* Generate min turn time. FIXME: can we do better than this? */
	/* Trying to a turnaround time at this level is trying to measure
Linus Torvalds's avatar
Linus Torvalds committed
419
	 * processor clock cycle with a wrist-watch, approximate at best...
Linus Torvalds's avatar
Linus Torvalds committed
420 421 422 423 424 425 426 427 428 429 430 431 432 433 434
	 *
	 * 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;
Linus Torvalds's avatar
Linus Torvalds committed
435
			do_gettimeofday(&self->now);
Linus Torvalds's avatar
Linus Torvalds committed
436
			diff = self->now.tv_usec - self->stamp.tv_usec;
Linus Torvalds's avatar
Linus Torvalds committed
437 438 439
#ifdef IU_USB_MIN_RTT
			/* Factor in USB delays -> Get rid of udelay() that
			 * would be lost in the noise - Jean II */
440
			diff += IU_USB_MIN_RTT;
Linus Torvalds's avatar
Linus Torvalds committed
441
#endif /* IU_USB_MIN_RTT */
442 443 444
			/* If the usec counter did wraparound, the diff will
			 * go negative (tv_usec is a long), so we need to
			 * correct it by one second. Jean II */
Linus Torvalds's avatar
Linus Torvalds committed
445 446 447 448 449 450 451 452 453 454 455 456 457 458
			if (diff < 0)
				diff += 1000000;

		        /* 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);
			}
		}
Linus Torvalds's avatar
Linus Torvalds committed
459
	}
Linus Torvalds's avatar
Linus Torvalds committed
460
	
461 462
	/* Ask USB to send the packet - Irq disabled -> GFP_ATOMIC */
	if ((res = usb_submit_urb(urb, GFP_ATOMIC))) {
463
		WARNING("%s(), failed Tx URB\n", __FUNCTION__);
Linus Torvalds's avatar
Linus Torvalds committed
464 465 466 467 468 469 470 471 472 473 474
		self->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->trans_start = jiffies;
	}
	spin_unlock_irqrestore(&self->lock, flags);
Linus Torvalds's avatar
Linus Torvalds committed
475 476
	
	return 0;
477 478 479 480 481

drop:
	/* Drop silently the skb and exit */
	dev_kfree_skb(skb);
	spin_unlock_irqrestore(&self->lock, flags);
Jean Tourrilhes's avatar
Jean Tourrilhes committed
482
	return err;		/* Usually 1 */
Linus Torvalds's avatar
Linus Torvalds committed
483 484
}

Linus Torvalds's avatar
Linus Torvalds committed
485
/*------------------------------------------------------------------*/
Linus Torvalds's avatar
Linus Torvalds committed
486
/*
Linus Torvalds's avatar
Linus Torvalds committed
487
 * Note : this function will be called only for tx_urb...
Linus Torvalds's avatar
Linus Torvalds committed
488
 */
David S. Miller's avatar
David S. Miller committed
489
static void write_bulk_callback(struct urb *urb, struct pt_regs *regs)
Linus Torvalds's avatar
Linus Torvalds committed
490
{
491
	unsigned long flags;
Linus Torvalds's avatar
Linus Torvalds committed
492
	struct sk_buff *skb = urb->context;
Linus Torvalds's avatar
Linus Torvalds committed
493 494
	struct irda_usb_cb *self = ((struct irda_skb_cb *) skb->cb)->context;
	
495
	IRDA_DEBUG(2, "%s()\n", __FUNCTION__);
Linus Torvalds's avatar
Linus Torvalds committed
496

Linus Torvalds's avatar
Linus Torvalds committed
497
	/* We should always have a context */
Jean Tourrilhes's avatar
Jean Tourrilhes committed
498 499 500
	ASSERT(self != NULL, return;);
	/* We should always be called for the speed URB */
	ASSERT(urb == self->tx_urb, return;);
Linus Torvalds's avatar
Linus Torvalds committed
501

Linus Torvalds's avatar
Linus Torvalds committed
502 503
	/* Free up the skb */
	dev_kfree_skb_any(skb);
Linus Torvalds's avatar
Linus Torvalds committed
504
	urb->context = NULL;
Linus Torvalds's avatar
Linus Torvalds committed
505

Linus Torvalds's avatar
Linus Torvalds committed
506
	/* Check for timeout and other USB nasties */
Linus Torvalds's avatar
Linus Torvalds committed
507
	if (urb->status != 0) {
Linus Torvalds's avatar
Linus Torvalds committed
508
		/* I get a lot of -ECONNABORTED = -103 here - Jean II */
509
		IRDA_DEBUG(0, "%s(), URB complete status %d, transfer_flags 0x%04X\n", __FUNCTION__, urb->status, urb->transfer_flags);
Linus Torvalds's avatar
Linus Torvalds committed
510 511 512 513 514 515 516 517

		/* 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;
Linus Torvalds's avatar
Linus Torvalds committed
518 519
	}

Linus Torvalds's avatar
Linus Torvalds committed
520
	/* urb is now available */
521 522 523 524
	//urb->status = 0; -> tested above

	/* Make sure we read self->present properly */
	spin_lock_irqsave(&self->lock, flags);
Linus Torvalds's avatar
Linus Torvalds committed
525

Linus Torvalds's avatar
Linus Torvalds committed
526 527
	/* If the network is closed, stop everything */
	if ((!self->netopen) || (!self->present)) {
528
		IRDA_DEBUG(0, "%s(), Network is gone...\n", __FUNCTION__);
529
		spin_unlock_irqrestore(&self->lock, flags);
Linus Torvalds's avatar
Linus Torvalds committed
530 531 532
		return;
	}

Jean Tourrilhes's avatar
Jean Tourrilhes committed
533
	/* If changes to speed or xbofs is pending... */
Linus Torvalds's avatar
Linus Torvalds committed
534
	if ((self->new_speed != -1) || (self->new_xbofs != -1)) {
Jean Tourrilhes's avatar
Jean Tourrilhes committed
535 536 537 538
		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 */
539
			IRDA_DEBUG(1, "%s(), Changing speed now...\n", __FUNCTION__);
Jean Tourrilhes's avatar
Jean Tourrilhes committed
540 541 542 543 544 545 546 547
			irda_usb_change_speed_xbofs(self);
		} else {
			/* New speed and xbof is now commited in hardware */
			self->new_speed = -1;
			self->new_xbofs = -1;
			/* Done, waiting for next packet */
			netif_wake_queue(self->netdev);
		}
Linus Torvalds's avatar
Linus Torvalds committed
548 549 550
	} else {
		/* Otherwise, allow the stack to send more packets */
		netif_wake_queue(self->netdev);
Linus Torvalds's avatar
Linus Torvalds committed
551
	}
552
	spin_unlock_irqrestore(&self->lock, flags);
Linus Torvalds's avatar
Linus Torvalds committed
553 554
}

Linus Torvalds's avatar
Linus Torvalds committed
555 556 557 558 559 560 561 562 563 564
/*------------------------------------------------------------------*/
/*
 * 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)
Linus Torvalds's avatar
Linus Torvalds committed
565
{
566
	unsigned long flags;
Linus Torvalds's avatar
Linus Torvalds committed
567
	struct irda_usb_cb *self = netdev->priv;
Linus Torvalds's avatar
Linus Torvalds committed
568
	struct urb *urb;
Linus Torvalds's avatar
Linus Torvalds committed
569 570
	int	done = 0;	/* If we have made any progress */

571
	IRDA_DEBUG(0, "%s(), Network layer thinks we timed out!\n", __FUNCTION__);
Jean Tourrilhes's avatar
Jean Tourrilhes committed
572
	ASSERT(self != NULL, return;);
Linus Torvalds's avatar
Linus Torvalds committed
573

574 575 576
	/* Protect us from USB callbacks, net Tx and else. */
	spin_lock_irqsave(&self->lock, flags);

Jean Tourrilhes's avatar
Jean Tourrilhes committed
577 578
	/* self->present *MUST* be read under spinlock */
	if (!self->present) {
579
		WARNING("%s(), device not present!\n", __FUNCTION__);
Linus Torvalds's avatar
Linus Torvalds committed
580
		netif_stop_queue(netdev);
581
		spin_unlock_irqrestore(&self->lock, flags);
Linus Torvalds's avatar
Linus Torvalds committed
582
		return;
Linus Torvalds's avatar
Linus Torvalds committed
583 584
	}

Linus Torvalds's avatar
Linus Torvalds committed
585
	/* Check speed URB */
586
	urb = self->speed_urb;
Linus Torvalds's avatar
Linus Torvalds committed
587 588
	if (urb->status != 0) {
		IRDA_DEBUG(0, "%s: Speed change timed out, urb->status=%d, urb->transfer_flags=0x%04X\n", netdev->name, urb->status, urb->transfer_flags);
Linus Torvalds's avatar
Linus Torvalds committed
589

Linus Torvalds's avatar
Linus Torvalds committed
590
		switch (urb->status) {
Linus Torvalds's avatar
Linus Torvalds committed
591
		case -EINPROGRESS:
Linus Torvalds's avatar
Linus Torvalds committed
592
			usb_unlink_urb(urb);
Linus Torvalds's avatar
Linus Torvalds committed
593 594 595
			/* Note : above will  *NOT* call netif_wake_queue()
			 * in completion handler, we will come back here.
			 * Jean II */
Linus Torvalds's avatar
Linus Torvalds committed
596 597 598 599
			done = 1;
			break;
		case -ECONNABORTED:		/* -103 */
		case -ECONNRESET:		/* -104 */
Linus Torvalds's avatar
Linus Torvalds committed
600 601 602
		case -ETIMEDOUT:		/* -110 */
		case -ENOENT:			/* -2 (urb unlinked by us)  */
		default:			/* ??? - Play safe */
Linus Torvalds's avatar
Linus Torvalds committed
603
			urb->status = 0;
Linus Torvalds's avatar
Linus Torvalds committed
604 605 606
			netif_wake_queue(self->netdev);
			done = 1;
			break;
Linus Torvalds's avatar
Linus Torvalds committed
607 608 609
		}
	}

Linus Torvalds's avatar
Linus Torvalds committed
610
	/* Check Tx URB */
611
	urb = self->tx_urb;
Linus Torvalds's avatar
Linus Torvalds committed
612 613
	if (urb->status != 0) {
		struct sk_buff *skb = urb->context;
Linus Torvalds's avatar
Linus Torvalds committed
614

Linus Torvalds's avatar
Linus Torvalds committed
615
		IRDA_DEBUG(0, "%s: Tx timed out, urb->status=%d, urb->transfer_flags=0x%04X\n", netdev->name, urb->status, urb->transfer_flags);
Linus Torvalds's avatar
Linus Torvalds committed
616

Linus Torvalds's avatar
Linus Torvalds committed
617 618
		/* Increase error count */
		self->stats.tx_errors++;
Linus Torvalds's avatar
Linus Torvalds committed
619

Linus Torvalds's avatar
Linus Torvalds committed
620 621 622 623 624 625 626
#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);
Linus Torvalds's avatar
Linus Torvalds committed
627
#endif /* IU_BUG_KICK_TIMEOUT */
Linus Torvalds's avatar
Linus Torvalds committed
628

Linus Torvalds's avatar
Linus Torvalds committed
629
		switch (urb->status) {
Linus Torvalds's avatar
Linus Torvalds committed
630
		case -EINPROGRESS:
Linus Torvalds's avatar
Linus Torvalds committed
631
			usb_unlink_urb(urb);
Linus Torvalds's avatar
Linus Torvalds committed
632
			/* Note : above will  *NOT* call netif_wake_queue()
Linus Torvalds's avatar
Linus Torvalds committed
633
			 * in completion handler, because urb->status will
Linus Torvalds's avatar
Linus Torvalds committed
634 635 636
			 * be -ENOENT. We will fix that at the next watchdog,
			 * leaving more time to USB to recover...
			 * Also, we are in interrupt, so we need to have
637
			 * URB_ASYNC_UNLINK to work properly...
Linus Torvalds's avatar
Linus Torvalds committed
638 639 640
			 * Jean II */
			done = 1;
			break;
Linus Torvalds's avatar
Linus Torvalds committed
641 642
		case -ECONNABORTED:		/* -103 */
		case -ECONNRESET:		/* -104 */
Linus Torvalds's avatar
Linus Torvalds committed
643 644 645
		case -ETIMEDOUT:		/* -110 */
		case -ENOENT:			/* -2 (urb unlinked by us)  */
		default:			/* ??? - Play safe */
Linus Torvalds's avatar
Linus Torvalds committed
646 647
			if(skb != NULL) {
				dev_kfree_skb_any(skb);
Linus Torvalds's avatar
Linus Torvalds committed
648
				urb->context = NULL;
Linus Torvalds's avatar
Linus Torvalds committed
649
			}
Linus Torvalds's avatar
Linus Torvalds committed
650
			urb->status = 0;
Linus Torvalds's avatar
Linus Torvalds committed
651 652 653
			netif_wake_queue(self->netdev);
			done = 1;
			break;
Linus Torvalds's avatar
Linus Torvalds committed
654
		}
Linus Torvalds's avatar
Linus Torvalds committed
655
	}
656
	spin_unlock_irqrestore(&self->lock, flags);
Linus Torvalds's avatar
Linus Torvalds committed
657

Linus Torvalds's avatar
Linus Torvalds committed
658 659 660 661
	/* Maybe we need a reset */
	/* Note : Some drivers seem to use a usb_set_interface() when they
	 * need to reset the hardware. Hum...
	 */
Linus Torvalds's avatar
Linus Torvalds committed
662

Linus Torvalds's avatar
Linus Torvalds committed
663
	/* if(done == 0) */
Linus Torvalds's avatar
Linus Torvalds committed
664 665
}

Linus Torvalds's avatar
Linus Torvalds committed
666
/************************* RECEIVE ROUTINES *************************/
Linus Torvalds's avatar
Linus Torvalds committed
667
/*
Linus Torvalds's avatar
Linus Torvalds committed
668 669
 * Receive packets from the USB layer stack and pass them to the IrDA stack.
 * Try to work around USB failures...
Linus Torvalds's avatar
Linus Torvalds committed
670
 */
Linus Torvalds's avatar
Linus Torvalds committed
671

Linus Torvalds's avatar
Linus Torvalds committed
672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689
/*
 * 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
 */

Linus Torvalds's avatar
Linus Torvalds committed
690 691 692
/*------------------------------------------------------------------*/
/*
 * Submit a Rx URB to the USB layer to handle reception of a frame
Jean Tourrilhes's avatar
Jean Tourrilhes committed
693
 * Mostly called by the completion callback of the previous URB.
Linus Torvalds's avatar
Linus Torvalds committed
694 695 696
 *
 * Jean II
 */
Linus Torvalds's avatar
Linus Torvalds committed
697
static void irda_usb_submit(struct irda_usb_cb *self, struct sk_buff *skb, struct urb *urb)
Linus Torvalds's avatar
Linus Torvalds committed
698
{
Linus Torvalds's avatar
Linus Torvalds committed
699 700 701
	struct irda_skb_cb *cb;
	int ret;

702
	IRDA_DEBUG(2, "%s()\n", __FUNCTION__);
Linus Torvalds's avatar
Linus Torvalds committed
703

704 705 706
	/* This should never happen */
	ASSERT(skb != NULL, return;);
	ASSERT(urb != NULL, return;);
Linus Torvalds's avatar
Linus Torvalds committed
707

708
	/* Save ourselves in the skb */
Linus Torvalds's avatar
Linus Torvalds committed
709 710 711 712
	cb = (struct irda_skb_cb *) skb->cb;
	cb->context = self;

	/* Reinitialize URB */
713
	usb_fill_bulk_urb(urb, self->usbdev, 
Linus Torvalds's avatar
Linus Torvalds committed
714 715 716
		      usb_rcvbulkpipe(self->usbdev, self->bulk_in_ep), 
		      skb->data, skb->truesize,
                      irda_usb_receive, skb);
Linus Torvalds's avatar
Linus Torvalds committed
717 718
	/* Note : unlink *must* be synchronous because of the code in 
	 * irda_usb_net_close() -> free the skb - Jean II */
Linus Torvalds's avatar
Linus Torvalds committed
719
	urb->status = 0;
720 721 722

	/* Can be called from irda_usb_receive (irq handler) -> GFP_ATOMIC */
	ret = usb_submit_urb(urb, GFP_ATOMIC);
Linus Torvalds's avatar
Linus Torvalds committed
723 724 725
	if (ret) {
		/* If this ever happen, we are in deep s***.
		 * Basically, the Rx path will stop... */
726
		WARNING("%s(), Failed to submit Rx URB %d\n", __FUNCTION__, ret);
Linus Torvalds's avatar
Linus Torvalds committed
727 728 729
	}
}

Linus Torvalds's avatar
Linus Torvalds committed
730
/*------------------------------------------------------------------*/
Linus Torvalds's avatar
Linus Torvalds committed
731
/*
Linus Torvalds's avatar
Linus Torvalds committed
732
 * Function irda_usb_receive(urb)
Linus Torvalds's avatar
Linus Torvalds committed
733 734 735 736
 *
 *     Called by the USB subsystem when a frame has been received
 *
 */
David S. Miller's avatar
David S. Miller committed
737
static void irda_usb_receive(struct urb *urb, struct pt_regs *regs)
Linus Torvalds's avatar
Linus Torvalds committed
738
{
Linus Torvalds's avatar
Linus Torvalds committed
739
	struct sk_buff *skb = (struct sk_buff *) urb->context;
Linus Torvalds's avatar
Linus Torvalds committed
740 741
	struct irda_usb_cb *self; 
	struct irda_skb_cb *cb;
742 743 744 745
	struct sk_buff *newskb;
	struct sk_buff *dataskb;
	int		docopy;

746
	IRDA_DEBUG(2, "%s(), len=%d\n", __FUNCTION__, urb->actual_length);
Linus Torvalds's avatar
Linus Torvalds committed
747
	
Linus Torvalds's avatar
Linus Torvalds committed
748 749 750 751 752 753 754 755
	/* Find ourselves */
	cb = (struct irda_skb_cb *) skb->cb;
	ASSERT(cb != NULL, return;);
	self = (struct irda_usb_cb *) cb->context;
	ASSERT(self != NULL, return;);

	/* If the network is closed or the device gone, stop everything */
	if ((!self->netopen) || (!self->present)) {
756
		IRDA_DEBUG(0, "%s(), Network is gone!\n", __FUNCTION__);
Linus Torvalds's avatar
Linus Torvalds committed
757 758 759 760 761
		/* Don't re-submit the URB : will stall the Rx path */
		return;
	}
	
	/* Check the status */
Linus Torvalds's avatar
Linus Torvalds committed
762 763
	if (urb->status != 0) {
		switch (urb->status) {
Linus Torvalds's avatar
Linus Torvalds committed
764
		case -EILSEQ:
Linus Torvalds's avatar
Linus Torvalds committed
765 766 767
			self->stats.rx_errors++;
			self->stats.rx_crc_errors++;	
			break;
Linus Torvalds's avatar
Linus Torvalds committed
768
		case -ECONNRESET:		/* -104 */
769
			IRDA_DEBUG(0, "%s(), Connection Reset (-104), transfer_flags 0x%04X \n", __FUNCTION__, urb->transfer_flags);
Linus Torvalds's avatar
Linus Torvalds committed
770 771 772 773 774
			/* 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 */
			break;
		default:
775
			IRDA_DEBUG(0, "%s(), RX status %d,transfer_flags 0x%04X \n", __FUNCTION__, urb->status, urb->transfer_flags);
Linus Torvalds's avatar
Linus Torvalds committed
776 777 778 779
			break;
		}
		goto done;
	}
Linus Torvalds's avatar
Linus Torvalds committed
780
	
Linus Torvalds's avatar
Linus Torvalds committed
781
	/* Check for empty frames */
Linus Torvalds's avatar
Linus Torvalds committed
782
	if (urb->actual_length <= USB_IRDA_HEADER) {
783
		WARNING("%s(), empty frame!\n", __FUNCTION__);
Linus Torvalds's avatar
Linus Torvalds committed
784 785 786 787 788 789 790 791
		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
	 */
Linus Torvalds's avatar
Linus Torvalds committed
792
        do_gettimeofday(&self->stamp);
Linus Torvalds's avatar
Linus Torvalds committed
793

794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809
	/* 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 */
	newskb = dev_alloc_skb(docopy ? urb->actual_length : IRDA_SKB_MAX_MTU);
	if (!newskb)  {
		self->stats.rx_dropped++;
		/* We could deliver the current skb, but this would stall
		 * the Rx path. Better drop the packet... Jean II */
		goto done;  
	}
Linus Torvalds's avatar
Linus Torvalds committed
810

811 812 813
	/* 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);
Linus Torvalds's avatar
Linus Torvalds committed
814

815
	if(docopy) {
Linus Torvalds's avatar
Linus Torvalds committed
816
		/* Copy packet, so we can recycle the original */
817 818 819 820 821 822
		memcpy(newskb->data, skb->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 */
Linus Torvalds's avatar
Linus Torvalds committed
823
	} else {
824 825 826 827
		/* We are using ZeroCopy. Deliver old skb */
		dataskb = skb;
		/* And hook the new skb to the URB */
		skb = newskb;
Linus Torvalds's avatar
Linus Torvalds committed
828
	}
829 830 831 832

	/* Set proper length on skb & remove USB-IrDA header */
	skb_put(dataskb, urb->actual_length);
	skb_pull(dataskb, USB_IRDA_HEADER);
Linus Torvalds's avatar
Linus Torvalds committed
833 834

	/* Ask the networking layer to queue the packet for the IrDA stack */
835 836 837 838 839 840 841 842 843
	dataskb->dev = self->netdev;
	dataskb->mac.raw  = dataskb->data;
	dataskb->protocol = htons(ETH_P_IRDA);
	netif_rx(dataskb);

	/* Keep stats up to date */
	self->stats.rx_bytes += dataskb->len;
	self->stats.rx_packets++;
	self->netdev->last_rx = jiffies;
Linus Torvalds's avatar
Linus Torvalds committed
844

Linus Torvalds's avatar
Linus Torvalds committed
845
done:
Linus Torvalds's avatar
Linus Torvalds committed
846
	/* Note : at this point, the URB we've just received (urb)
Linus Torvalds's avatar
Linus Torvalds committed
847 848 849 850 851 852 853 854 855
	 * 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. Another time... Jean II */
Linus Torvalds's avatar
Linus Torvalds committed
856

Linus Torvalds's avatar
Linus Torvalds committed
857 858 859
	/* Submit the idle URB to replace the URB we've just received */
	irda_usb_submit(self, skb, self->idle_rx_urb);
	/* Recycle Rx URB : Now, the idle URB is the present one */
Linus Torvalds's avatar
Linus Torvalds committed
860
	urb->context = NULL;
861
	self->idle_rx_urb = urb;
Linus Torvalds's avatar
Linus Torvalds committed
862 863
}

Linus Torvalds's avatar
Linus Torvalds committed
864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898
/*------------------------------------------------------------------*/
/*
 * 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 */
}

/********************** IRDA DEVICE CALLBACKS **********************/
/*
 * Main calls from the IrDA/Network subsystem.
 * Mostly registering a new irda-usb device and removing it....
 * We only deal with the IrDA side of the business, the USB side will
 * be dealt with below...
 */

Linus Torvalds's avatar
Linus Torvalds committed
899

Linus Torvalds's avatar
Linus Torvalds committed
900
/*------------------------------------------------------------------*/
Linus Torvalds's avatar
Linus Torvalds committed
901 902 903 904 905 906 907 908 909 910
/*
 * Function irda_usb_net_open (dev)
 *
 *    Network device is taken up. Usually this is done by "ifconfig irda0 up" 
 *   
 * Note : don't mess with self->netopen - Jean II
 */
static int irda_usb_net_open(struct net_device *netdev)
{
	struct irda_usb_cb *self;
Linus Torvalds's avatar
Linus Torvalds committed
911
	char	hwname[16];
Linus Torvalds's avatar
Linus Torvalds committed
912 913
	int i;
	
914
	IRDA_DEBUG(1, "%s()\n", __FUNCTION__);
Linus Torvalds's avatar
Linus Torvalds committed
915 916 917 918 919 920 921

	ASSERT(netdev != NULL, return -1;);
	self = (struct irda_usb_cb *) netdev->priv;
	ASSERT(self != NULL, return -1;);

	/* Can only open the device if it's there */
	if(!self->present) {
922
		WARNING("%s(), device not present!\n", __FUNCTION__);
Linus Torvalds's avatar
Linus Torvalds committed
923 924 925 926 927 928 929 930 931 932 933 934 935 936 937 938 939 940 941
		return -1;
	}

	/* Initialise default speed and xbofs value
	 * (IrLAP will change that soon) */
	self->speed = -1;
	self->xbofs = -1;
	self->new_speed = -1;
	self->new_xbofs = -1;

	/* To do *before* submitting Rx urbs and starting net Tx queue
	 * Jean II */
	self->netopen = 1;

	/* 
	 * Now that everything should be initialized properly,
	 * Open new IrLAP layer instance to take care of us...
	 * Note : will send immediately a speed change...
	 */
Linus Torvalds's avatar
Linus Torvalds committed
942 943
	sprintf(hwname, "usb#%d", self->usbdev->devnum);
	self->irlap = irlap_open(netdev, &self->qos, hwname);
Linus Torvalds's avatar
Linus Torvalds committed
944 945 946 947 948
	ASSERT(self->irlap != NULL, return -1;);

	/* Allow IrLAP to send data to us */
	netif_start_queue(netdev);

949 950 951 952 953 954 955
	/* We submit all the Rx URB except for one that we keep idle.
	 * Need to be initialised before submitting other USBs, because
	 * in some cases as soon as we submit the URBs the USB layer
	 * will trigger a dummy receive - Jean II */
	self->idle_rx_urb = self->rx_urb[IU_MAX_ACTIVE_RX_URBS];
	self->idle_rx_urb->context = NULL;

Linus Torvalds's avatar
Linus Torvalds committed
956 957
	/* Now that we can pass data to IrLAP, allow the USB layer
	 * to send us some data... */
958 959 960 961 962 963 964 965 966 967 968
	for (i = 0; i < IU_MAX_ACTIVE_RX_URBS; i++) {
		struct sk_buff *skb = dev_alloc_skb(IRDA_SKB_MAX_MTU);
		if (!skb) {
			/* If this ever happen, we are in deep s***.
			 * Basically, we can't start the Rx path... */
			WARNING("%s(), Failed to allocate Rx skb\n", __FUNCTION__);
			return -1;
		}
		//skb_reserve(newskb, USB_IRDA_HEADER - 1);
		irda_usb_submit(self, skb, self->rx_urb[i]);
	}
Linus Torvalds's avatar
Linus Torvalds committed
969 970 971 972 973 974 975 976 977 978 979 980 981 982 983 984 985

	/* Ready to play !!! */
	return 0;
}

/*------------------------------------------------------------------*/
/*
 * Function irda_usb_net_close (self)
 *
 *    Network device is taken down. Usually this is done by 
 *    "ifconfig irda0 down" 
 */
static int irda_usb_net_close(struct net_device *netdev)
{
	struct irda_usb_cb *self;
	int	i;

986
	IRDA_DEBUG(1, "%s()\n", __FUNCTION__);
Linus Torvalds's avatar
Linus Torvalds committed
987 988 989 990 991 992 993 994 995 996 997 998 999 1000

	ASSERT(netdev != NULL, return -1;);
	self = (struct irda_usb_cb *) netdev->priv;
	ASSERT(self != NULL, return -1;);

	/* Clear this flag *before* unlinking the urbs and *before*
	 * stopping the network Tx queue - Jean II */
	self->netopen = 0;

	/* Stop network Tx queue */
	netif_stop_queue(netdev);

	/* Deallocate all the Rx path buffers (URBs and skb) */
	for (i = 0; i < IU_MAX_RX_URBS; i++) {
1001
		struct urb *urb = self->rx_urb[i];
Linus Torvalds's avatar
Linus Torvalds committed
1002
		struct sk_buff *skb = (struct sk_buff *) urb->context;
Linus Torvalds's avatar
Linus Torvalds committed
1003
		/* Cancel the receive command */
Linus Torvalds's avatar
Linus Torvalds committed
1004
		usb_unlink_urb(urb);
Linus Torvalds's avatar
Linus Torvalds committed
1005 1006 1007
		/* The skb is ours, free it */
		if(skb) {
			dev_kfree_skb(skb);
Linus Torvalds's avatar
Linus Torvalds committed
1008
			urb->context = NULL;
Linus Torvalds's avatar
Linus Torvalds committed
1009 1010
		}
	}
1011
	/* Cancel Tx and speed URB - need to be synchronous to avoid races */
1012
	self->tx_urb->transfer_flags &= ~URB_ASYNC_UNLINK;
1013
	usb_unlink_urb(self->tx_urb);
1014
	self->speed_urb->transfer_flags &= ~URB_ASYNC_UNLINK;
1015
	usb_unlink_urb(self->speed_urb);
Linus Torvalds's avatar
Linus Torvalds committed
1016 1017 1018 1019 1020 1021 1022 1023 1024 1025 1026 1027 1028 1029 1030

	/* Stop and remove instance of IrLAP */
	if (self->irlap)
		irlap_close(self->irlap);
	self->irlap = NULL;

	return 0;
}

/*------------------------------------------------------------------*/
/*
 * IOCTLs : Extra out-of-band network commands...
 */
static int irda_usb_net_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
{
1031
	unsigned long flags;
Linus Torvalds's avatar
Linus Torvalds committed
1032 1033 1034 1035 1036 1037 1038 1039
	struct if_irda_req *irq = (struct if_irda_req *) rq;
	struct irda_usb_cb *self;
	int ret = 0;

	ASSERT(dev != NULL, return -1;);
	self = dev->priv;
	ASSERT(self != NULL, return -1;);

1040
	IRDA_DEBUG(2, "%s(), %s, (cmd=0x%X)\n", __FUNCTION__, dev->name, cmd);
Linus Torvalds's avatar
Linus Torvalds committed
1041 1042 1043 1044 1045

	switch (cmd) {
	case SIOCSBANDWIDTH: /* Set bandwidth */
		if (!capable(CAP_NET_ADMIN))
			return -EPERM;
1046 1047 1048 1049 1050 1051 1052 1053 1054
		/* Protect us from USB callbacks, net watchdog and else. */
		spin_lock_irqsave(&self->lock, flags);
		/* Check if the device is still there */
		if(self->present) {
			/* Set the desired speed */
			self->new_speed = irq->ifr_baudrate;
			irda_usb_change_speed_xbofs(self);
		}
		spin_unlock_irqrestore(&self->lock, flags);
Linus Torvalds's avatar
Linus Torvalds committed
1055 1056 1057 1058
		break;
	case SIOCSMEDIABUSY: /* Set media busy */
		if (!capable(CAP_NET_ADMIN))
			return -EPERM;
1059 1060 1061
		/* Check if the IrDA stack is still there */
		if(self->netopen)
			irda_device_set_media_busy(self->netdev, TRUE);
Linus Torvalds's avatar
Linus Torvalds committed
1062 1063 1064 1065 1066 1067 1068 1069 1070 1071 1072 1073 1074 1075 1076 1077 1078 1079 1080 1081 1082 1083 1084 1085 1086 1087 1088 1089 1090 1091 1092 1093 1094 1095 1096 1097
		break;
	case SIOCGRECEIVING: /* Check if we are receiving right now */
		irq->ifr_receiving = irda_usb_is_receiving(self);
		break;
	default:
		ret = -EOPNOTSUPP;
	}
	
	return ret;
}

/*------------------------------------------------------------------*/
/*
 * 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 *********************/
/*
 * Various subroutines dealing with IrDA and network stuff we use to
 * configure and initialise each irda-usb instance.
 * These functions are used below in the main calls of the driver...
 */

/*------------------------------------------------------------------*/
/*
 * Set proper values in the IrDA QOS structure
 */
static inline void irda_usb_init_qos(struct irda_usb_cb *self)
{
	struct irda_class_desc *desc;

1098
	IRDA_DEBUG(3, "%s()\n", __FUNCTION__);
Linus Torvalds's avatar
Linus Torvalds committed
1099 1100 1101 1102 1103 1104
	
	desc = self->irda_desc;
	
	/* Initialize QoS for this device */
	irda_init_max_qos_capabilies(&self->qos);

Jean Tourrilhes's avatar
Jean Tourrilhes committed
1105 1106 1107 1108
	/* See spec section 7.2 for meaning.
	 * Values are little endian (as most USB stuff), the IrDA stack
	 * use it in native order (see parameters.c). - Jean II */
	self->qos.baud_rate.bits       = le16_to_cpu(desc->wBaudRate);
Linus Torvalds's avatar
Linus Torvalds committed
1109 1110 1111 1112 1113
	self->qos.min_turn_time.bits   = desc->bmMinTurnaroundTime;
	self->qos.additional_bofs.bits = desc->bmAdditionalBOFs;
	self->qos.window_size.bits     = desc->bmWindowSize;
	self->qos.data_size.bits       = desc->bmDataSize;

1114 1115
	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);
Linus Torvalds's avatar
Linus Torvalds committed
1116 1117 1118

	/* Don't always trust what the dongle tell us */
	if(self->capability & IUC_SIR_ONLY)
Jean Tourrilhes's avatar
Jean Tourrilhes committed
1119
		self->qos.baud_rate.bits	&= 0x00ff;
Linus Torvalds's avatar
Linus Torvalds committed
1120 1121 1122 1123 1124 1125 1126 1127 1128 1129 1130 1131 1132 1133 1134 1135 1136 1137 1138 1139 1140 1141 1142 1143 1144 1145 1146 1147 1148 1149 1150 1151 1152 1153 1154 1155
	if(self->capability & IUC_SMALL_PKT)
		self->qos.data_size.bits	 = 0x07;
	if(self->capability & IUC_NO_WINDOW)
		self->qos.window_size.bits	 = 0x01;
	if(self->capability & IUC_MAX_WINDOW)
		self->qos.window_size.bits	 = 0x7f;
	if(self->capability & IUC_MAX_XBOFS)
		self->qos.additional_bofs.bits	 = 0x01;

#if 1
	/* Module parameter can override the rx window size */
	if (qos_mtt_bits)
		self->qos.min_turn_time.bits = qos_mtt_bits;
#endif	    
	/* 
	 * Note : most of those values apply only for the receive path,
	 * the transmit path will be set differently - Jean II 
	 */
	irda_qos_bits_to_value(&self->qos);

	self->flags |= IFF_SIR;
	if (self->qos.baud_rate.value > 115200)
		self->flags |= IFF_MIR;
	if (self->qos.baud_rate.value > 1152000)
		self->flags |= IFF_FIR;
	if (self->qos.baud_rate.value > 4000000)
		self->flags |= IFF_VFIR;
}

/*------------------------------------------------------------------*/
/*
 * Initialise the network side of the irda-usb instance
 * Called when a new USB instance is registered in irda_usb_probe()
 */
static inline int irda_usb_open(struct irda_usb_cb *self)
{
1156
	struct net_device *netdev = self->netdev;
Linus Torvalds's avatar
Linus Torvalds committed
1157

1158
	IRDA_DEBUG(1, "%s()\n", __FUNCTION__);
Linus Torvalds's avatar
Linus Torvalds committed
1159 1160 1161 1162 1163 1164

	irda_usb_init_qos(self);

	/* Override the network functions we need to use */
	netdev->hard_start_xmit = irda_usb_hard_xmit;
	netdev->tx_timeout	= irda_usb_net_timeout;
Linus Torvalds's avatar
Linus Torvalds committed
1165
	netdev->watchdog_timeo  = 250*HZ/1000;	/* 250 ms > USB timeout */
Linus Torvalds's avatar
Linus Torvalds committed
1166 1167 1168 1169 1170
	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;

1171
	return register_netdev(netdev);
Linus Torvalds's avatar
Linus Torvalds committed
1172 1173 1174 1175 1176 1177 1178
}

/*------------------------------------------------------------------*/
/*
 * Cleanup the network side of the irda-usb instance
 * Called when a USB instance is removed in irda_usb_disconnect()
 */
1179
static inline void irda_usb_close(struct irda_usb_cb *self)
Linus Torvalds's avatar
Linus Torvalds committed
1180
{
1181
	IRDA_DEBUG(1, "%s()\n", __FUNCTION__);
Linus Torvalds's avatar
Linus Torvalds committed
1182 1183

	/* Remove netdevice */
1184
	unregister_netdev(self->netdev);
1185

Linus Torvalds's avatar
Linus Torvalds committed
1186 1187 1188 1189 1190 1191 1192 1193 1194 1195 1196 1197 1198 1199 1200 1201 1202 1203 1204 1205 1206 1207 1208 1209 1210 1211
	/* Remove the speed buffer */
	if (self->speed_buff != NULL) {
		kfree(self->speed_buff);
		self->speed_buff = NULL;
	}
}

/********************** USB CONFIG SUBROUTINES **********************/
/*
 * Various subroutines dealing with USB stuff we use to configure and
 * initialise each irda-usb instance.
 * These functions are used below in the main calls of the driver...
 */

/*------------------------------------------------------------------*/
/*
 * Function irda_usb_parse_endpoints(dev, ifnum)
 *
 *    Parse the various endpoints and find the one we need.
 *
 * The endpoint are the pipes used to communicate with the USB device.
 * The spec defines 2 endpoints of type bulk transfer, one in, and one out.
 * These are used to pass frames back and forth with the dongle.
 * Most dongle have also an interrupt endpoint, that will be probably
 * documented in the next spec...
 */
1212
static inline int irda_usb_parse_endpoints(struct irda_usb_cb *self, struct usb_host_endpoint *endpoint, int ennum)
Linus Torvalds's avatar
Linus Torvalds committed
1213 1214 1215 1216 1217 1218 1219 1220 1221 1222 1223 1224 1225 1226 1227 1228 1229 1230
{
	int i;		/* Endpoint index in table */
		
	/* Init : no endpoints */
	self->bulk_in_ep = 0;
	self->bulk_out_ep = 0;
	self->bulk_int_ep = 0;

	/* Let's look at all those endpoints */
	for(i = 0; i < ennum; i++) {
		/* All those variables will get optimised by the compiler,
		 * so let's aim for clarity... - Jean II */
		__u8 ep;	/* Endpoint address */
		__u8 dir;	/* Endpoint direction */
		__u8 attr;	/* Endpoint attribute */
		__u16 psize;	/* Endpoint max packet size in bytes */

		/* Get endpoint address, direction and attribute */
1231 1232 1233 1234
		ep = endpoint[i].desc.bEndpointAddress & USB_ENDPOINT_NUMBER_MASK;
		dir = endpoint[i].desc.bEndpointAddress & USB_ENDPOINT_DIR_MASK;
		attr = endpoint[i].desc.bmAttributes;
		psize = endpoint[i].desc.wMaxPacketSize;
Linus Torvalds's avatar
Linus Torvalds committed
1235 1236 1237 1238 1239 1240 1241 1242 1243 1244 1245 1246 1247 1248 1249 1250 1251 1252

		/* Is it a bulk endpoint ??? */
		if(attr == USB_ENDPOINT_XFER_BULK) {
			/* We need to find an IN and an OUT */
			if(dir == USB_DIR_IN) {
				/* This is our Rx endpoint */
				self->bulk_in_ep = ep;
			} else {
				/* This is our Tx endpoint */
				self->bulk_out_ep = ep;
				self->bulk_out_mtu = psize;
			}
		} else {
			if((attr == USB_ENDPOINT_XFER_INT) &&
			   (dir == USB_DIR_IN)) {
				/* This is our interrupt endpoint */
				self->bulk_int_ep = ep;
			} else {
1253
				ERROR("%s(), Unrecognised endpoint %02X.\n", __FUNCTION__, ep);
Linus Torvalds's avatar
Linus Torvalds committed
1254 1255 1256 1257
			}
		}
	}

1258 1259
	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);
Linus Torvalds's avatar
Linus Torvalds committed
1260 1261 1262 1263 1264 1265 1266 1267 1268 1269 1270 1271 1272 1273 1274 1275
	/* Should be 8, 16, 32 or 64 bytes */
	ASSERT(self->bulk_out_mtu == 64, ;);

	return((self->bulk_in_ep != 0) && (self->bulk_out_ep != 0));
}

#ifdef IU_DUMP_CLASS_DESC
/*------------------------------------------------------------------*/
/*
 * Function usb_irda_dump_class_desc(desc)
 *
 *    Prints out the contents of the IrDA class descriptor
 *
 */
static inline void irda_usb_dump_class_desc(struct irda_class_desc *desc)
{
Jean Tourrilhes's avatar
Jean Tourrilhes committed
1276
	/* Values are little endian */
Linus Torvalds's avatar
Linus Torvalds committed
1277 1278
	printk("bLength=%x\n", desc->bLength);
	printk("bDescriptorType=%x\n", desc->bDescriptorType);
Jean Tourrilhes's avatar
Jean Tourrilhes committed
1279
	printk("bcdSpecRevision=%x\n", le16_to_cpu(desc->bcdSpecRevision)); 
Linus Torvalds's avatar
Linus Torvalds committed
1280 1281 1282
	printk("bmDataSize=%x\n", desc->bmDataSize);
	printk("bmWindowSize=%x\n", desc->bmWindowSize);
	printk("bmMinTurnaroundTime=%d\n", desc->bmMinTurnaroundTime);
Jean Tourrilhes's avatar
Jean Tourrilhes committed
1283
	printk("wBaudRate=%x\n", le16_to_cpu(desc->wBaudRate));
Linus Torvalds's avatar
Linus Torvalds committed
1284 1285 1286 1287
	printk("bmAdditionalBOFs=%x\n", desc->bmAdditionalBOFs);
	printk("bIrdaRateSniff=%x\n", desc->bIrdaRateSniff);
	printk("bMaxUnicastList=%x\n", desc->bMaxUnicastList);
}
Linus Torvalds's avatar
Linus Torvalds committed
1288
#endif /* IU_DUMP_CLASS_DESC */
Linus Torvalds's avatar
Linus Torvalds committed
1289 1290 1291

/*------------------------------------------------------------------*/
/*
1292
 * Function irda_usb_find_class_desc(intf)
Linus Torvalds's avatar
Linus Torvalds committed
1293 1294 1295 1296 1297 1298 1299
 *
 *    Returns instance of IrDA class descriptor, or NULL if not found
 *
 * The class descriptor is some extra info that IrDA USB devices will
 * offer to us, describing their IrDA characteristics. We will use that in
 * irda_usb_init_qos()
 */
1300
static inline struct irda_class_desc *irda_usb_find_class_desc(struct usb_interface *intf)
Linus Torvalds's avatar
Linus Torvalds committed
1301
{
1302
	struct usb_device *dev = interface_to_usbdev (intf);
Linus Torvalds's avatar
Linus Torvalds committed
1303
	struct irda_class_desc *desc;
Linus Torvalds's avatar
Linus Torvalds committed
1304
	int ret;
Linus Torvalds's avatar
Linus Torvalds committed
1305 1306

	desc = kmalloc(sizeof (*desc), GFP_KERNEL);
Linus Torvalds's avatar
Linus Torvalds committed
1307 1308
	if (desc == NULL) 
		return NULL;
Linus Torvalds's avatar
Linus Torvalds committed
1309
	memset(desc, 0, sizeof(*desc));
Linus Torvalds's avatar
Linus Torvalds committed
1310

Linus Torvalds's avatar
Linus Torvalds committed
1311 1312 1313 1314 1315 1316
	/* USB-IrDA class spec 1.0:
	 *	6.1.3: Standard "Get Descriptor" Device Request is not
	 *	       appropriate to retrieve class-specific descriptor
	 *	6.2.5: Class Specific "Get Class Descriptor" Interface Request
	 *	       is mandatory and returns the USB-IrDA class descriptor
	 */
Linus Torvalds's avatar
Linus Torvalds committed
1317

Linus Torvalds's avatar
Linus Torvalds committed
1318 1319 1320
	ret = usb_control_msg(dev, usb_rcvctrlpipe(dev,0),
		IU_REQ_GET_CLASS_DESC,
		USB_DIR_IN | USB_TYPE_CLASS | USB_RECIP_INTERFACE,
1321
		0, intf->altsetting->desc.bInterfaceNumber, desc,
1322
		sizeof(*desc), MSECS_TO_JIFFIES(500));
Linus Torvalds's avatar
Linus Torvalds committed
1323
	
1324
	IRDA_DEBUG(1, "%s(), ret=%d\n", __FUNCTION__, ret);
Linus Torvalds's avatar
Linus Torvalds committed
1325 1326 1327 1328 1329 1330
	if (ret < sizeof(*desc)) {
		WARNING("usb-irda: class_descriptor read %s (%d)\n",
			(ret<0) ? "failed" : "too short", ret);
	}
	else if (desc->bDescriptorType != USB_DT_IRDA) {
		WARNING("usb-irda: bad class_descriptor type\n");
Linus Torvalds's avatar
Linus Torvalds committed
1331
	}
Linus Torvalds's avatar
Linus Torvalds committed
1332
	else {
Linus Torvalds's avatar
Linus Torvalds committed
1333
#ifdef IU_DUMP_CLASS_DESC
Linus Torvalds's avatar
Linus Torvalds committed
1334
		irda_usb_dump_class_desc(desc);
Linus Torvalds's avatar
Linus Torvalds committed
1335
#endif	/* IU_DUMP_CLASS_DESC */
Linus Torvalds's avatar
Linus Torvalds committed
1336 1337 1338 1339 1340

		return desc;
	}
	kfree(desc);
	return NULL;
Linus Torvalds's avatar
Linus Torvalds committed
1341 1342
}

Linus Torvalds's avatar
Linus Torvalds committed
1343
/*********************** USB DEVICE CALLBACKS ***********************/
Linus Torvalds's avatar
Linus Torvalds committed
1344
/*
Linus Torvalds's avatar
Linus Torvalds committed
1345 1346
 * Main calls from the USB subsystem.
 * Mostly registering a new irda-usb device and removing it....
Linus Torvalds's avatar
Linus Torvalds committed
1347
 */
Linus Torvalds's avatar
Linus Torvalds committed
1348 1349 1350 1351 1352 1353

/*------------------------------------------------------------------*/
/*
 * This routine is called by the USB subsystem for each new device
 * in the system. We need to check if the device is ours, and in
 * this case start handling it.
Jean Tourrilhes's avatar
Jean Tourrilhes committed
1354 1355
 * The USB layer protect us from reentrancy (via BKL), so we don't need
 * to spinlock in there... Jean II
Linus Torvalds's avatar
Linus Torvalds committed
1356
 */
1357 1358
static int irda_usb_probe(struct usb_interface *intf,
			  const struct usb_device_id *id)
Linus Torvalds's avatar
Linus Torvalds committed
1359
{
1360
	struct net_device *net;
1361
	struct usb_device *dev = interface_to_usbdev(intf);
Linus Torvalds's avatar
Linus Torvalds committed
1362
	struct irda_usb_cb *self = NULL;
1363
	struct usb_host_interface *interface;
Linus Torvalds's avatar
Linus Torvalds committed
1364
	struct irda_class_desc *irda_desc;
1365
	int ret = -ENOMEM;
Jean Tourrilhes's avatar
Jean Tourrilhes committed
1366
	int i;		/* Driver instance index / Rx URB index */
Linus Torvalds's avatar
Linus Torvalds committed
1367

Linus Torvalds's avatar
Linus Torvalds committed
1368 1369 1370 1371
	/* Note : the probe make sure to call us only for devices that
	 * matches the list of dongle (top of the file). So, we
	 * don't need to check if the dongle is really ours.
	 * Jean II */
Linus Torvalds's avatar
Linus Torvalds committed
1372

Linus Torvalds's avatar
Linus Torvalds committed
1373 1374 1375
	MESSAGE("IRDA-USB found at address %d, Vendor: %x, Product: %x\n",
		dev->devnum, dev->descriptor.idVendor,
		dev->descriptor.idProduct);
Linus Torvalds's avatar
Linus Torvalds committed
1376

1377 1378 1379
	net = alloc_irdadev(sizeof(*self));
	if (!net) 
		goto err_out;
Linus Torvalds's avatar
Linus Torvalds committed
1380

1381 1382 1383
	self = net->priv;
	self->netdev = net;
	spin_lock_init(&self->lock);
Linus Torvalds's avatar
Linus Torvalds committed
1384

1385
	SET_MODULE_OWNER(net);
Linus Torvalds's avatar
Linus Torvalds committed
1386

1387 1388 1389 1390
	/* Create all of the needed urbs */
	for (i = 0; i < IU_MAX_RX_URBS; i++) {
		self->rx_urb[i] = usb_alloc_urb(0, GFP_KERNEL);
		if (!self->rx_urb[i]) {
Jean Tourrilhes's avatar
Jean Tourrilhes committed
1391
			goto err_out_1;
1392 1393 1394 1395
		}
	}
	self->tx_urb = usb_alloc_urb(0, GFP_KERNEL);
	if (!self->tx_urb) {
Jean Tourrilhes's avatar
Jean Tourrilhes committed
1396
		goto err_out_1;
1397 1398 1399
	}
	self->speed_urb = usb_alloc_urb(0, GFP_KERNEL);
	if (!self->speed_urb) {
Jean Tourrilhes's avatar
Jean Tourrilhes committed
1400
		goto err_out_2;
1401 1402
	}

1403 1404 1405
	/* Is this really necessary? (no, except maybe for broken devices) */
	if (usb_reset_configuration (dev) < 0) {
		err("reset_configuration failed");
Jean Tourrilhes's avatar
Jean Tourrilhes committed
1406 1407
		ret = -EIO;
		goto err_out_3;
Linus Torvalds's avatar
Linus Torvalds committed
1408 1409
	}

Linus Torvalds's avatar
Linus Torvalds committed
1410 1411 1412 1413
	/* Is this really necessary? */
	/* Note : some driver do hardcode the interface number, some others
	 * specify an alternate, but very few driver do like this.
	 * Jean II */
1414
	ret = usb_set_interface(dev, intf->altsetting->desc.bInterfaceNumber, 0);
1415
	IRDA_DEBUG(1, "usb-irda: set interface %d result %d\n", intf->altsetting->desc.bInterfaceNumber, ret);
Linus Torvalds's avatar
Linus Torvalds committed
1416
	switch (ret) {
Linus Torvalds's avatar
Linus Torvalds committed
1417
		case 0:
Linus Torvalds's avatar
Linus Torvalds committed
1418
			break;
Linus Torvalds's avatar
Linus Torvalds committed
1419
		case -EPIPE:		/* -EPIPE = -32 */
1420 1421 1422 1423
			/* 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__);
Linus Torvalds's avatar
Linus Torvalds committed
1424 1425
			break;
		default:
1426
			IRDA_DEBUG(0, "%s(), Unknown error %d\n", __FUNCTION__, ret);
Jean Tourrilhes's avatar
Jean Tourrilhes committed
1427 1428
			ret = -EIO;
			goto err_out_3;
Linus Torvalds's avatar
Linus Torvalds committed
1429
	}
Linus Torvalds's avatar
Linus Torvalds committed
1430 1431

	/* Find our endpoints */
1432
	interface = &intf->altsetting[0];
Linus Torvalds's avatar
Linus Torvalds committed
1433
	if(!irda_usb_parse_endpoints(self, interface->endpoint,
1434
				     interface->desc.bNumEndpoints)) {
1435
		ERROR("%s(), Bogus endpoints...\n", __FUNCTION__);
Jean Tourrilhes's avatar
Jean Tourrilhes committed
1436 1437
		ret = -EIO;
		goto err_out_3;
Linus Torvalds's avatar
Linus Torvalds committed
1438 1439
	}

Linus Torvalds's avatar
Linus Torvalds committed
1440
	/* Find IrDA class descriptor */
1441
	irda_desc = irda_usb_find_class_desc(intf);
Jean Tourrilhes's avatar
Jean Tourrilhes committed
1442
	ret = -ENODEV;
Linus Torvalds's avatar
Linus Torvalds committed
1443
	if (irda_desc == NULL)
Jean Tourrilhes's avatar
Jean Tourrilhes committed
1444 1445 1446
		goto err_out_3;

	self->irda_desc =  irda_desc;
Linus Torvalds's avatar
Linus Torvalds committed
1447 1448 1449 1450
	self->present = 1;
	self->netopen = 0;
	self->capability = id->driver_info;
	self->usbdev = dev;
1451
	self->usbintf = intf;
1452 1453 1454 1455 1456 1457 1458

	/* Allocate the buffer for speed changes */
	/* 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) 
Jean Tourrilhes's avatar
Jean Tourrilhes committed
1459
		goto err_out_3;
Linus Torvalds's avatar
Linus Torvalds committed
1460

1461 1462 1463 1464 1465 1466 1467
	memset(self->speed_buff, 0, IRDA_USB_SPEED_MTU);

	ret = irda_usb_open(self);
	if (ret) 
		goto err_out_4;

	MESSAGE("IrDA: Registered device %s\n", net->name);
1468
	usb_set_intfdata(intf, self);
1469
	return 0;
Jean Tourrilhes's avatar
Jean Tourrilhes committed
1470

1471 1472
err_out_4:
	kfree(self->speed_buff);
Jean Tourrilhes's avatar
Jean Tourrilhes committed
1473 1474 1475 1476 1477 1478 1479 1480 1481 1482
err_out_3:
	/* Free all urbs that we may have created */
	usb_free_urb(self->speed_urb);
err_out_2:
	usb_free_urb(self->tx_urb);
err_out_1:
	for (i = 0; i < IU_MAX_RX_URBS; i++) {
		if (self->rx_urb[i])
			usb_free_urb(self->rx_urb[i]);
	}
1483 1484
	free_netdev(net);
err_out:
Jean Tourrilhes's avatar
Jean Tourrilhes committed
1485
	return ret;
Linus Torvalds's avatar
Linus Torvalds committed
1486 1487
}

Linus Torvalds's avatar
Linus Torvalds committed
1488 1489 1490 1491
/*------------------------------------------------------------------*/
/*
 * The current irda-usb device is removed, the USB layer tell us
 * to shut it down...
1492 1493 1494 1495 1496 1497 1498
 * One of the constraints is that when we exit this function,
 * we cannot use the usb_device no more. Gone. Destroyed. kfree().
 * Most other subsystem allow you to destroy the instance at a time
 * when it's convenient to you, to postpone it to a later date, but
 * not the USB subsystem.
 * So, we must make bloody sure that everything gets deactivated.
 * Jean II
Linus Torvalds's avatar
Linus Torvalds committed
1499
 */
1500
static void irda_usb_disconnect(struct usb_interface *intf)
Linus Torvalds's avatar
Linus Torvalds committed
1501
{
1502
	unsigned long flags;
1503
	struct irda_usb_cb *self = usb_get_intfdata(intf);
Linus Torvalds's avatar
Linus Torvalds committed
1504
	int i;
Linus Torvalds's avatar
Linus Torvalds committed
1505

1506
	IRDA_DEBUG(1, "%s()\n", __FUNCTION__);
Linus Torvalds's avatar
Linus Torvalds committed
1507

1508
	usb_set_intfdata(intf, NULL);
1509 1510 1511
	if (!self)
		return;

1512 1513 1514 1515 1516
	/* Make sure that the Tx path is not executing. - Jean II */
	spin_lock_irqsave(&self->lock, flags);

	/* Oups ! We are not there any more.
	 * This will stop/desactivate the Tx path. - Jean II */
Linus Torvalds's avatar
Linus Torvalds committed
1517
	self->present = 0;
Linus Torvalds's avatar
Linus Torvalds committed
1518

1519 1520 1521 1522 1523 1524
	/* We need to have irq enabled to unlink the URBs. That's OK,
	 * at this point the Tx path is gone - Jean II */
	spin_unlock_irqrestore(&self->lock, flags);

	/* Hum... Check if networking is still active (avoid races) */
	if((self->netopen) || (self->irlap)) {
Linus Torvalds's avatar
Linus Torvalds committed
1525 1526 1527 1528 1529
		/* Accept no more transmissions */
		/*netif_device_detach(self->netdev);*/
		netif_stop_queue(self->netdev);
		/* Stop all the receive URBs */
		for (i = 0; i < IU_MAX_RX_URBS; i++)
1530
			usb_unlink_urb(self->rx_urb[i]);
1531 1532
		/* Cancel Tx and speed URB.
		 * Toggle flags to make sure it's synchronous. */
1533
		self->tx_urb->transfer_flags &= ~URB_ASYNC_UNLINK;
1534
		usb_unlink_urb(self->tx_urb);
1535
		self->speed_urb->transfer_flags &= ~URB_ASYNC_UNLINK;
1536
		usb_unlink_urb(self->speed_urb);
Linus Torvalds's avatar
Linus Torvalds committed
1537 1538
	}

Linus Torvalds's avatar
Linus Torvalds committed
1539 1540 1541 1542
	/* Cleanup the device stuff */
	irda_usb_close(self);
	/* No longer attached to USB bus */
	self->usbdev = NULL;
1543
	self->usbintf = NULL;
1544 1545 1546 1547

	/* Clean up our urbs */
	for (i = 0; i < IU_MAX_RX_URBS; i++)
		usb_free_urb(self->rx_urb[i]);
1548
	/* Clean up Tx and speed URB */
1549 1550 1551
	usb_free_urb(self->tx_urb);
	usb_free_urb(self->speed_urb);

1552 1553
	/* Free self and network device */
	free_netdev(self->netdev);
1554
	IRDA_DEBUG(0, "%s(), USB IrDA Disconnected\n", __FUNCTION__);
Linus Torvalds's avatar
Linus Torvalds committed
1555 1556
}

Linus Torvalds's avatar
Linus Torvalds committed
1557 1558 1559 1560 1561
/*------------------------------------------------------------------*/
/*
 * USB device callbacks
 */
static struct usb_driver irda_driver = {
1562
	.owner		= THIS_MODULE,
1563 1564 1565 1566
	.name		= "irda-usb",
	.probe		= irda_usb_probe,
	.disconnect	= irda_usb_disconnect,
	.id_table	= dongles,
Linus Torvalds's avatar
Linus Torvalds committed
1567 1568 1569 1570 1571 1572 1573 1574 1575 1576 1577 1578
};

/************************* MODULE CALLBACKS *************************/
/*
 * Deal with module insertion/removal
 * Mostly tell USB about our existence
 */

/*------------------------------------------------------------------*/
/*
 * Module insertion
 */
Jean Tourrilhes's avatar
Jean Tourrilhes committed
1579
static int __init usb_irda_init(void)
Linus Torvalds's avatar
Linus Torvalds committed
1580
{
Jean Tourrilhes's avatar
Jean Tourrilhes committed
1581 1582 1583 1584 1585
	int	ret;

	ret = usb_register(&irda_driver);
	if (ret < 0)
		return ret;
Linus Torvalds's avatar
Linus Torvalds committed
1586 1587 1588 1589 1590 1591

	MESSAGE("USB IrDA support registered\n");
	return 0;
}
module_init(usb_irda_init);

Linus Torvalds's avatar
Linus Torvalds committed
1592 1593 1594 1595
/*------------------------------------------------------------------*/
/*
 * Module removal
 */
Jean Tourrilhes's avatar
Jean Tourrilhes committed
1596
static void __exit usb_irda_cleanup(void)
Linus Torvalds's avatar
Linus Torvalds committed
1597 1598 1599 1600 1601 1602
{
	/* Deregister the driver and remove all pending instances */
	usb_deregister(&irda_driver);
}
module_exit(usb_irda_cleanup);

Linus Torvalds's avatar
Linus Torvalds committed
1603 1604 1605 1606
/*------------------------------------------------------------------*/
/*
 * Module parameters
 */
Linus Torvalds's avatar
Linus Torvalds committed
1607 1608 1609 1610
MODULE_PARM(qos_mtt_bits, "i");
MODULE_PARM_DESC(qos_mtt_bits, "Minimum Turn Time");
MODULE_AUTHOR("Roman Weissgaerber <weissg@vienna.at>, Dag Brattli <dag@brattli.net> and Jean Tourrilhes <jt@hpl.hp.com>");
MODULE_DESCRIPTION("IrDA-USB Dongle Driver"); 
1611
MODULE_LICENSE("GPL");