681709a617c4c9df8a5c46080e2c26bd505fed19
[linux-flexiantxendom0-3.2.10.git] / drivers / usb / plusb.c
1 /*****************************************************************************/
2
3 /*
4  *      plusb.c  --  prolific pl-2301/pl-2302 driver.
5  *
6  *      Copyright (C) 2000  Deti Fliegl (deti@fliegl.de)
7  *      Copyright (C) 2000  Pavel Machek (pavel@suse.cz)
8  *      Copyright (C) 2000  Eric Z. Ayers (eric@compgen.com)
9  *
10  *      This program is free software; you can redistribute it and/or modify
11  *      it under the terms of the GNU General Public License as published by
12  *      the Free Software Foundation; either version 2 of the License, or
13  *      (at your option) any later version.
14  *
15  *      This program is distributed in the hope that it will be useful,
16  *      but WITHOUT ANY WARRANTY; without even the implied warranty of
17  *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  *      GNU General Public License for more details.
19  *
20  *      You should have received a copy of the GNU General Public License
21  *      along with this program; if not, write to the Free Software
22  *      Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
23  *
24  *
25  *  This driver creates a network interface (plusb0, plusb1, ...) that will
26  *  send messages over a USB host-host cable based on the Prolific ASIC.
27  *  It works a lot like plip or PP over an RS-232C null modem cable.
28  *
29  *  Expect speeds of around 330Kbytes/second over a UHCI host controller.
30  *  OHCI should be faster.  Increase the MTU for faster transfers of large
31  *  files (up-to 800Kbytes/second).  (16384 is a good size)
32  *
33  *  $Id: plusb.c,v 1.18 2000/02/14 10:38:58 fliegl Exp $
34  *
35  *  Changelog:
36  *
37  *    v0.1                deti
38  *        Original Version of driver.
39  *    v0.2     15 Sep 2000  pavel
40  *        Patches to decrease latency by rescheduling the bottom half of
41  *          interrupt code.
42  *    v0.3     10 Oct 2000  eric
43  *        Patches to work in v2.2 backport (v2.4 changes the way net_dev.name
44  *          is allocated)
45  *    v0.4     19 Oct 2000  eric
46  *        Some more performance fixes.  Lock re-submitting urbs.
47  *          Lower the number of sk_buff's to queue.
48  *    v0.5     25 Oct 2000 eric
49  *        Removed use of usb_bulk_msg() all together.  This caused
50  *          the driver to block in an interrupt context.
51  *        Consolidate read urb submission into read_urb_submit().
52  *        Performance is the same as v0.4.
53  *    v0.5.1   27 Oct 2000 eric
54  *        Extra debugging messages to help diagnose problem with uchi.o stack.
55  *    v0.5.2   27 Oct 2000 eric
56  *        Set the 'start' flag for the network device in plusb_net_start()
57  *         and plusb_net_stop() (doesn't help)
58  *    v0.5.3   27 Oct 2000 pavel
59  *        Commented out handlers when -EPIPE is received,
60  *         (remove calls to usb_clear_halt()) Since the callback is in
61  *         an interrupt context, it doesn't help, it just panics
62  *         the kernel. (what do we do?)
63  *        Under high load, dev_alloc_skb() fails, the read URB must
64  *         be re-submitted.
65  *        Added plusb_change_mtu() and increased the size of _BULK_DATA_LEN
66  *    v0.5.4   31 Oct 2000 eric
67  *        Fix race between plusb_net_xmit() and plusb_bulk_write_complete()
68  *    v0.5.5    1 Nov 2000 eric
69  *        Remove dev->start field, otherwise, it won't compile in 2.4
70  *        Use dev_kfree_skb_any(). (important in 2.4 kernel)
71  *    v0.5.6   2 Nov 2000 pavel,eric
72  *        Add calls to netif_stop_queue() and netif_start_queue()
73  *        Drop packets that come in while the free list is empty.
74  *        (This version is being submitted after the release of 2.4-test10)
75  *    v0.5.7   6 Nov 2000
76  *        Fix to not re-submit the urb on error to help when cables
77  *          are yanked (not tested)
78  *
79  *
80  * KNOWN PROBLEMS: (Any suggestions greatfully accepted!)
81  *
82  *     2 Nov 2000
83  *      - The shutdown for this may not be entirely clean.  Sometimes, the
84  *         kernel will Oops when the cable is unplugged, or
85  *         if the plusb module is removed.
86  *      - If you ifdown a device and then ifup it again, the link will not
87  *         always work.  You have to 'rmmod plusb ; modprobe plusb' on
88  *         both machines to get it to work again.  Something must be wrong with
89  *         plusb_net_open() and plusb_net_start() ?  Maybe
90  *         the 'suspend' and 'resume' entry points need to be
91  *         implemented?
92  *      - Needs to handle -EPIPE correctly in bulk complete handlers.
93  *         (replace usb_clear_halt() function with async urbs?)
94  *      - I think this code relies too much on one spinlock and does
95  *         too much in the interrupt handler.  The net1080 code is
96  *         much more elegant, and should work for this chip.  Its
97  *         only drawback is that it is going to be tough to backport
98  *         it to v2.2.
99  *      - Occasionally the device will hang under the 'uhci.o'
100  *         driver.   The workaround is to ifdown the device and
101  *         remove the modules, then re-insert them.  You may have
102  *         better luck with the 'usb-uhci.o' driver.
103  *      - After using ifconfig down ; ifconfig up, sometimes packets
104  *         continue to be received, but there is a framing problem.
105  *
106  * FUTURE DIRECTIONS:
107  *
108  *     - Fix the known problems.
109  *     - There isn't much functional difference between the net1080
110  *        driver and this one.  It would be neat if the same driver
111  *        could handle both types of chips.  Or if both drivers
112  *        could handle both types of chips - this one is easier to
113  *        backport to the 2.2 kernel.
114  *     - Get rid of plusb_add_buf_tail and the single spinlock.
115  *        Use a separate spinlock for the 2 lists, and use atomic
116  *        operators for writeurb_submitted and readurb_submitted members.
117  *
118  *
119  */
120
121 /*****************************************************************************/
122
123 #include <linux/module.h>
124 #include <linux/socket.h>
125 #include <linux/miscdevice.h>
126 #include <linux/list.h>
127 #include <linux/vmalloc.h>
128 #include <linux/slab.h>
129 #include <linux/init.h>
130 #include <asm/uaccess.h>
131 #include <asm/atomic.h>
132 #include <linux/delay.h>
133 #include <linux/netdevice.h>
134 #include <linux/etherdevice.h>
135 #include <linux/skbuff.h>
136 //#define DEBUG 1
137 #include <linux/usb.h>
138
139 #if (LINUX_VERSION_CODE < 0x020300)
140 #define dev_kfree_skb_any dev_kfree_skb
141 #endif
142
143 /* Definitions formerly in plusb.h relocated. No need to export them -EZA */
144
145 #define _PLUSB_INTPIPE          0x1
146 #define _PLUSB_BULKOUTPIPE      0x2
147 #define _PLUSB_BULKINPIPE       0x3
148
149 #define _SKB_NUM                32
150
151 /* increase size of BULK_DATA_LEN so we can use bigger MTU's*/
152 #define _BULK_DATA_LEN          32768
153
154
155 typedef struct
156 {
157         int connected;   /* indicates if this structure is active */
158         struct usb_device *usbdev;
159                                          /* keep track of USB structure */
160         int status;      /* Prolific status byte returned from interrupt */
161         int in_bh;       /* flag to indicate that we are in the bulk handler */
162         int opened;      /* flag to indicate that network dev is open    */
163
164         spinlock_t lock; /* Lock for the buffer list. re-used for
165                                                 locking around submitting the readurb member.
166                                          */
167         urb_t *inturb;   /* Read buffer for the interrupt callback */
168         unsigned char *         interrupt_in_buffer;
169                          /* holds data for the inturb*/
170         urb_t *readurb;  /* Read buffer for the bulk data callback */
171         unsigned char *         bulk_in_buffer;
172                                          /* kmalloc'ed data for the readurb */
173         int readurb_submitted;
174                                          /* Flag to indicate that readurb already sent */
175         urb_t *writeurb; /* Write buffer for the bulk data callback */
176         int writeurb_submitted;
177                                          /* Flag to indicate that writeurb already sent */
178         
179         struct list_head tx_skb_list;
180                                          /* sk_buff's read from net device */
181         struct list_head free_skb_list;
182                                         /* free sk_buff list */
183         struct net_device net_dev;
184                                         /* handle to linux network device */
185         struct net_device_stats net_stats;
186                                         /* stats to return for ifconfig output */
187 } plusb_t,*pplusb_t;
188
189 /*
190  * skb_list - queue of packets from the network driver to be delivered to USB
191  */
192 typedef struct
193 {
194         struct list_head skb_list;
195         struct sk_buff *skb;
196         int state;
197         plusb_t *s;
198 } skb_list_t,*pskb_list_t;
199
200
201 /* --------------------------------------------------------------------- */
202
203 #define NRPLUSB 4
204
205 /*
206  * Interrupt endpoint status byte, from Prolific PL-2301 docs
207  * Check the 'download' link at www.prolifictech.com
208  */
209 #define _PL_INT_RES1    0x80 /* reserved              */
210 #define _PL_INT_RES2    0x40 /* reserved              */
211 #define _PL_INT_RXD     _PL_INT_RES2  /* Read data ready - Not documented by Prolific, but seems to work! */
212 #define _PL_INT_TX_RDY  0x20 /* OK to transmit data   */
213 #define _PL_INT_RESET_O 0x10 /* reset output pipe     */
214 #define _PL_INT_RESET_I 0x08 /* reset input pipe      */
215 #define _PL_INT_TX_C    0x04 /* transmission complete */
216 #define _PL_INT_TX_REQ  0x02 /* transmission received */
217 #define _PL_INT_PEER_E  0x01 /* peer exists           */
218
219 /*-------------------------------------------------------------------*/
220
221 static plusb_t plusb[NRPLUSB];
222
223 static void plusb_write_bulk_complete(urb_t *purb);
224 static void plusb_read_bulk_complete(urb_t *purb);
225 static void plusb_int_complete(urb_t *purb);
226
227 /* --------------------------------------------------------------------- */
228
229 /*
230  * plusb_add_buf_tail - Take the head of the src list and append it to
231  *                      the tail of the dest list
232  */
233 static int plusb_add_buf_tail (plusb_t *s, struct list_head *dst, struct list_head *src)
234 {
235         unsigned long flags = 0;
236         struct list_head *tmp;
237         int ret = 0;
238
239         spin_lock_irqsave (&s->lock, flags);
240
241         if (list_empty (src)) {
242                 // no elements in source buffer
243                 ret = -1;
244                 goto err;
245         }
246         tmp = src->next;
247         list_del (tmp);
248         list_add_tail (tmp, dst);
249
250   err:  spin_unlock_irqrestore (&s->lock, flags);
251         return ret;
252 }
253 /*-------------------------------------------------------------------*/
254
255 /*
256  * dequeue_next_skb - submit the first thing on the tx_skb_list to the
257  * USB stack.  This function should be called each time we get a new
258  * message to send to the other host, or each time a message is sucessfully
259  * sent.
260  */
261 static void dequeue_next_skb(char * func, plusb_t * s)
262 {
263         skb_list_t * skb_list;
264         unsigned long flags = 0;
265
266         if (!s->connected)
267                 return;
268         
269         spin_lock_irqsave (&s->lock, flags);
270         
271         if (!list_empty (&s->tx_skb_list) && !s->writeurb_submitted) {
272                 int submit_ret;
273                 skb_list = list_entry (s->tx_skb_list.next, skb_list_t, skb_list);
274
275                 if (skb_list->skb) {
276                         s->writeurb_submitted = 1;
277                 
278                         /* Use the buffer inside the sk_buff directly. why copy? */
279                         FILL_BULK_URB_TO(s->writeurb, s->usbdev,
280                                                          usb_sndbulkpipe(s->usbdev, _PLUSB_BULKOUTPIPE),
281                                                          skb_list->skb->data, skb_list->skb->len,
282                                                          plusb_write_bulk_complete, skb_list, 500);
283                         
284                         dbg ("%s: %s: submitting urb. skb_list %p", s->net_dev.name, func, skb_list);
285                 
286                         submit_ret = usb_submit_urb(s->writeurb);
287                         if (submit_ret) {
288                                 s->writeurb_submitted = 0;
289                                 printk (KERN_CRIT "%s: %s: can't submit writeurb: %d\n",
290                                                 s->net_dev.name, func, submit_ret);
291                         }
292                 } /* end if the skb value has been filled in */
293         }
294         
295         spin_unlock_irqrestore (&s->lock, flags);       
296 }
297
298 /*
299  * submit_read_urb - re-submit the read URB to the stack
300  */
301 void submit_read_urb(char * func, plusb_t * s)
302 {
303         unsigned long flags=0;
304
305         if (!s->connected)
306                 return;
307         
308         spin_lock_irqsave (&s->lock, flags);
309         
310         if (!s->readurb_submitted) {
311                 int ret;
312                 s->readurb_submitted=1;
313                 s->readurb->dev=s->usbdev;
314                 ret = usb_submit_urb(s->readurb);
315                 if (ret) {
316                         printk (KERN_CRIT "%s: %s: error %d submitting read URB\n",
317                                    s->net_dev.name, func, ret);
318                         s->readurb_submitted=0;
319                 }
320         }
321
322         spin_unlock_irqrestore (&s->lock, flags);
323         
324 }
325 /* --------------------------------------------------------------------- */
326
327 /*
328  * plusb_net_xmit - callback from the network device driver for outgoing data
329  *
330  * Data has arrived to the network device from the local machine and needs
331  * to be sent over the USB cable.  This is in an interrupt, so we don't
332  * want to spend too much time in this function.
333  *
334  */
335 static int plusb_net_xmit(struct sk_buff *skb, struct net_device *dev)
336 {
337         plusb_t *s=dev->priv;
338         skb_list_t *skb_list;
339         unsigned int flags;
340
341         dbg("plusb_net_xmit: len:%d i:%d",skb->len,in_interrupt());
342
343         if(!s->connected || !s->opened) {
344                 /*
345                   NOTE: If we get to this point, you'll return the error
346                   kernel: virtual device plusb0 asks to queue packet
347
348                   Other things we could do:
349                   1) just drop this packet
350                   2) drop other packets in the queue
351                 */
352                 return 1;
353         }
354
355         spin_lock_irqsave (&s->lock, flags);
356
357         if  (list_empty(&s->free_skb_list)
358         || plusb_add_buf_tail (s, &s->tx_skb_list, &s->free_skb_list)) {
359                 /* The buffers on this side are full. DROP the packet
360                    I think that this shouldn't happen with the correct
361                    use of the netif_XXX functions -EZA
362                  */
363                 dbg ("plusb: Free list is empty.");
364                 kfree_skb(skb);
365                 s->net_stats.tx_dropped++;
366                 spin_unlock_irqrestore (&s->lock, flags);
367                 return 0;
368         }
369         
370         skb_list = list_entry (s->tx_skb_list.prev, skb_list_t, skb_list);
371         skb_list->skb=skb;
372         skb_list->state=1;
373         skb_list->s=s;
374
375         if (list_empty(&s->free_skb_list)) {
376                 /* apply "backpressure". Tell the net layer to stop sending
377                    the driver packets.
378                 */
379                 netif_stop_queue(dev);
380         }
381         
382         spin_unlock_irqrestore (&s->lock, flags);
383         
384         /* If there is no write urb outstanding, pull the first thing
385            off of the list and submit it to the USB stack
386         */
387         dequeue_next_skb("plusb_net_xmit", s);
388         
389         return 0;
390 }
391
392 /* --------------------------------------------------------------------- */
393
394 /*
395  * plusb_write_bulk_complete () - callback after the data has been
396  *   sent to the USB device, or a timeout occured.
397  */
398 static void plusb_write_bulk_complete(urb_t *purb)
399 {
400         skb_list_t * skb_list=purb->context;
401         plusb_t *s=skb_list->s;
402
403         dbg ("%s: plusb_write_bulk_complete: status:%d skb_list:%p\n",
404                  s->net_dev.name, purb->status, skb_list);
405
406         skb_list->state=0;
407
408         if( purb->status == -EPIPE )
409                 printk(KERN_CRIT "%s: plusb_write_bulk_complete: got -EPIPE and don't know what to do!\n",
410                      s->net_dev.name);
411                 
412         if(!purb->status) {
413                 s->net_stats.tx_packets++;
414                 s->net_stats.tx_bytes+=skb_list->skb->len;
415         }
416         else {
417                 err ("%s: plusb_write_bulk_complete: returned ERROR status:%d\n",
418                          s->net_dev.name, purb->status);
419
420                 s->net_stats.tx_errors++;
421                 s->net_stats.tx_aborted_errors++;
422         }
423         
424         dbg("plusb_bh: dev_kfree_skb");
425
426         /* NOTE: In 2.4 it's a problem to call dev_kfree_skb() in a hard IRQ:
427            Oct 28 23:42:14 bug kernel: Warning: kfree_skb on hard IRQ c023329a
428         */
429         dev_kfree_skb_any(skb_list->skb);
430         
431         skb_list->skb = NULL;
432         if (plusb_add_buf_tail (s, &s->free_skb_list, &s->tx_skb_list)) {
433                 err ("plusb: tx list empty. This shouldn't happen.");
434         }
435
436         purb->status = 0;
437         s->writeurb_submitted = 0;
438         
439     netif_wake_queue((&s->net_dev));
440         
441         dequeue_next_skb("plusb_write_bulk_complete", s);
442
443         
444 }
445
446 /*
447  * plusb_read_bulk_complete - Callback for data arriving from the USB device
448  *
449  * This gets called back when a full 'urb' is received from the remote system.
450  * This urb was allocated by this driver and is kept in the member: s->readurb
451  *
452  */
453 static void plusb_read_bulk_complete(urb_t *purb)
454 {
455         
456         plusb_t *s=purb->context;
457
458         dbg("plusb_read_bulk_complete: status:%d length:%d", purb->status,purb->actual_length);
459         
460         if(!s->connected)
461                 return;
462
463         if( purb->status == -EPIPE )
464                 printk(KERN_CRIT "%s: plusb_read_bulk_complete: got -EPIPE and I don't know what to do!\n",
465                      s->net_dev.name);
466         else if (!purb->status) {
467                 struct sk_buff *skb;
468                 unsigned char *dst;
469                 int len=purb->transfer_buffer_length;
470                 struct net_device_stats *stats=&s->net_stats;
471
472                 skb=dev_alloc_skb(len);
473
474                 if(!skb) {
475                         printk (KERN_CRIT "%s: plusb_read_bulk_complete: dev_alloc_skb(%d)=NULL, dropping frame\n", s->net_dev.name, len);
476                         stats->rx_dropped++;
477                 } else {
478                         dst=(char *)skb_put(skb, len);
479                         memcpy( dst, purb->transfer_buffer, len);
480                         
481                         skb->dev=&s->net_dev;
482                         skb->protocol=eth_type_trans(skb, skb->dev);
483                         stats->rx_packets++;
484                         stats->rx_bytes+=len;
485                         netif_rx(skb);
486                 }
487                 
488         }
489         
490         s->readurb_submitted = 0;
491         
492         if (purb->status) {
493                 /* Give the system a chance to "catch its breath". Shortcut
494                    re-submitting the read URB>  It will be re-submitted if
495                    another interrupt comes back.  The problem scenario is that
496                    the plub is pulled and the read returns an error.
497                    You don't want to resumbit in this case.
498                 */
499                 err ("%s: plusb_read_bulk_complete: returned status %d\n",
500                          s->net_dev.name, purb->status);
501                 return;
502         }
503
504
505         purb->status=0;
506
507         /* Keep it coming! resubmit the URB for reading.. Make sure
508            we aren't in contention with the interrupt callback.
509         */
510         submit_read_urb("plusb_read_bulk_complete", s);
511 }
512
513 /* --------------------------------------------------------------------- */
514 /*
515  * plusb_int_complete - USB driver callback for interrupt msg from the device
516  *
517  * Interrupts are scheduled to go off on a periodic basis (see FILL_INT_URB)
518  * For the prolific device, this is basically just returning a register
519  * filled with bits.  See the macro definitions for _PL_INT_XXX above.
520  * Most of these bits are for implementing a machine-machine protocol
521  * and can be set with a special message (described as the "Quicklink"
522  * feature in the prolific documentation.)
523  *
524  * I don't think we need any of that to work as a network device. If a
525  * message is lost, big deal - that's what UNIX networking expects from
526  * the physical layer.
527  *
528  */
529 static void plusb_int_complete(urb_t *purb)
530 {
531         plusb_t *s=purb->context;
532         s->status=((unsigned char*)purb->transfer_buffer)[0]&255;
533         
534 #if 0
535         /* This isn't right because 0x20 is TX_RDY and
536            sometimes will not be set
537         */
538         if((s->status&0x3f)!=0x20) {
539                 warn("invalid device status %02X", s->status);
540                 return;
541         }
542 #endif  
543         if(!s->connected)
544                 return;
545
546         /* Don't turn this on unless you want to see the log flooded. */
547 #if 0
548         printk("plusb_int_complete: PEER_E:%d TX_REQ:%d TX_C:%d RESET_IN:%d RESET_O: %d TX_RDY:%d RES1:%d RES2:%d\n",
549             s->status & _PL_INT_PEER_E  ? 1 : 0,
550             s->status & _PL_INT_TX_REQ  ? 1 : 0,
551             s->status & _PL_INT_TX_C    ? 1 : 0,
552             s->status & _PL_INT_RESET_I ? 1 : 0,
553             s->status & _PL_INT_RESET_O ? 1 : 0,
554             s->status & _PL_INT_TX_RDY  ? 1 : 0,
555             s->status & _PL_INT_RES1    ? 1 : 0,
556             s->status & _PL_INT_RES2    ? 1 : 0);
557 #endif
558
559 #if 1
560         /* At first glance, this logic appears to not really be needed, but
561            it can help recover from intermittent problems where the
562            usb_submit_urb() fails in the read callback. -EZA
563         */
564         
565         /* Try to submit the read URB again. Make sure
566            we aren't in contention with the bulk read callback
567         */
568         submit_read_urb ("plusb_int_complete", s);
569         
570         /* While we are at it, why not check to see if the
571            write urb should be re-submitted?
572         */
573         dequeue_next_skb("plusb_int_complete", s);      
574         
575 #endif
576
577 }
578
579 /* --------------------------------------------------------------------- */
580 /*
581  * plusb_free_all - deallocate all memory kept for an instance of the device.
582  */
583 static void plusb_free_all(plusb_t *s)
584 {
585         struct list_head *skb;
586         skb_list_t *skb_list;
587         
588         dbg("plusb_free_all");
589         
590         /* set a flag to tell all callbacks to cease and desist */
591         s->connected = 0;
592
593         /* If the interrupt handler is about to fire, let it finish up */
594         run_task_queue(&tq_immediate);  
595
596         if(s->inturb) {
597                 dbg("unlink inturb");
598                 usb_unlink_urb(s->inturb);
599                 dbg("free_urb inturb");
600                 usb_free_urb(s->inturb);
601                 s->inturb=NULL;
602         }
603         
604         if(s->interrupt_in_buffer) {
605                 dbg("kfree s->interrupt_in_buffer");
606                 kfree(s->interrupt_in_buffer);
607                 s->interrupt_in_buffer=NULL;
608         }
609
610         if(s->readurb) {
611                 dbg("unlink readurb");
612                 usb_unlink_urb(s->readurb);
613                 dbg("free_urb readurb:");
614                 usb_free_urb(s->readurb);
615                 s->readurb=NULL;
616         }
617
618         if(s->bulk_in_buffer) {
619                 dbg("kfree s->bulk_in_buffer");
620                 kfree(s->bulk_in_buffer);
621                 s->bulk_in_buffer=NULL;
622         }
623         
624         s->readurb_submitted = 0;
625         
626         if(s->writeurb) {
627                 dbg("unlink writeurb");
628                 usb_unlink_urb(s->writeurb);
629                 dbg("free_urb writeurb:");
630                 usb_free_urb(s->writeurb);
631                 s->writeurb=NULL;
632         }
633
634         s->writeurb_submitted = 0;
635         
636         while(!list_empty(&s->free_skb_list)) {
637                 skb=s->free_skb_list.next;
638                 list_del(skb);
639                 skb_list = list_entry (skb, skb_list_t, skb_list);
640                 kfree(skb_list);
641         }
642
643         while(!list_empty(&s->tx_skb_list)) {
644                 skb=s->tx_skb_list.next;
645                 list_del(skb);
646                 skb_list = list_entry (skb, skb_list_t, skb_list);
647                 if (skb_list->skb) {
648                         dbg ("Freeing SKB in queue");
649                         dev_kfree_skb_any(skb_list->skb);
650                         skb_list->skb = NULL;
651                 }
652                 kfree(skb_list);
653         }
654         
655         s->in_bh=0;
656         
657         dbg("plusb_free_all: finished");        
658 }
659
660 /*-------------------------------------------------------------------*/
661 /*
662  * plusb_alloc - allocate memory associated with one instance of the device
663  */
664 static int plusb_alloc(plusb_t *s)
665 {
666         int i;
667         skb_list_t *skb;
668
669         dbg("plusb_alloc");
670
671         for(i=0 ; i < _SKB_NUM ; i++) {
672                 skb=kmalloc(sizeof(skb_list_t), GFP_KERNEL);
673                 if(!skb) {
674                         err("kmalloc for skb_list failed");
675                         goto reject;
676                 }
677                 memset(skb, 0, sizeof(skb_list_t));
678                 list_add(&skb->skb_list, &s->free_skb_list);
679         }
680
681         dbg("inturb allocation:");
682         s->inturb=usb_alloc_urb(0);
683         if(!s->inturb) {
684                 err("alloc_urb failed");
685                 goto reject;
686         }
687
688         dbg("bulk read urb allocation:");
689         s->readurb=usb_alloc_urb(0);
690         if(!s->readurb) {
691                 err("alloc_urb failed");
692                 goto reject;
693         }
694         
695         dbg("bulk write urb allocation:");
696         s->writeurb=usb_alloc_urb(0);
697         if(!s->writeurb) {
698                 err("alloc_urb for writeurb failed");
699                 goto reject;
700         }
701         
702         dbg("readurb/inturb init:");
703         s->interrupt_in_buffer=kmalloc(64, GFP_KERNEL);
704         if(!s->interrupt_in_buffer) {
705                 err("kmalloc failed");
706                 goto reject;
707         }
708
709         /* The original value of '10' makes this interrupt fire off a LOT.
710            It was set so low because the callback determined when to
711            sumbit the buld read URB. I've lowered it to 100 - the driver
712            doesn't depend on that logic anymore. -EZA
713         */
714         FILL_INT_URB(s->inturb, s->usbdev,
715                      usb_rcvintpipe (s->usbdev, _PLUSB_INTPIPE),
716                      s->interrupt_in_buffer, 1,
717                      plusb_int_complete, s, HZ);
718
719         dbg("inturb submission:");
720         if(usb_submit_urb(s->inturb)<0) {
721                 err("usb_submit_urb failed");
722                 goto reject;
723         }
724         
725         dbg("readurb init:");
726         s->bulk_in_buffer = kmalloc(_BULK_DATA_LEN, GFP_KERNEL);
727         if (!s->bulk_in_buffer) {
728                 err("kmalloc %d bytes for bulk in buffer failed", _BULK_DATA_LEN);
729         }
730
731         FILL_BULK_URB(s->readurb, s->usbdev,
732                       usb_rcvbulkpipe(s->usbdev, _PLUSB_BULKINPIPE),
733                       s->bulk_in_buffer, _BULK_DATA_LEN,
734                       plusb_read_bulk_complete, s);
735
736         /* The write urb will be initialized inside the network
737            interrupt.
738         */
739
740         /* get the bulk read going */
741         submit_read_urb("plusb_alloc", s);
742
743         dbg ("plusb_alloc: finished. readurb=%p writeurb=%p inturb=%p",
744                 s->readurb, s->writeurb, s->inturb);
745         
746         return 0;
747
748   reject:
749         dbg("plusb_alloc: failed");
750         
751         plusb_free_all(s);
752         return -ENOMEM;
753 }
754
755 /*-------------------------------------------------------------------*/
756
757 static int plusb_net_open(struct net_device *dev)
758 {
759         plusb_t *s=dev->priv;
760         
761         dbg("plusb_net_open");
762         
763         if(plusb_alloc(s))
764                 return -ENOMEM;
765
766         s->opened=1;
767         
768         MOD_INC_USE_COUNT;
769
770         netif_start_queue(dev);
771
772         dbg("plusb_net_open: success");
773         
774         return 0;
775         
776 }
777
778 /* --------------------------------------------------------------------- */
779
780 static int plusb_net_stop(struct net_device *dev)
781 {
782         plusb_t *s=dev->priv;
783
784         netif_stop_queue(dev);
785         
786         dbg("plusb_net_stop");  
787         
788         s->opened=0;
789         plusb_free_all(s);
790
791         MOD_DEC_USE_COUNT;
792         dbg("plusb_net_stop:finished");
793         return 0;
794 }
795
796 /* --------------------------------------------------------------------- */
797
798 static struct net_device_stats *plusb_net_get_stats(struct net_device *dev)
799 {
800         plusb_t *s=dev->priv;
801         
802         dbg("net_device_stats");
803         
804         return &s->net_stats;
805 }
806
807 /* --------------------------------------------------------------------- */
808
809 static plusb_t *plusb_find_struct (void)
810 {
811         int u;
812
813         for (u = 0; u < NRPLUSB; u++) {
814                 plusb_t *s = &plusb[u];
815                 if (!s->connected)
816                         return s;
817         }
818         return NULL;
819 }
820
821 /* --------------------------------------------------------------------- */
822
823 static void plusb_disconnect (struct usb_device *usbdev, void *ptr)
824 {
825         plusb_t *s = ptr;
826
827         dbg("plusb_disconnect");
828         
829         plusb_free_all(s);
830
831         if(!s->opened && s->net_dev.name) {
832                 dbg("unregistering netdev: %s",s->net_dev.name);
833                 unregister_netdev(&s->net_dev);
834                 s->net_dev.name[0] = '\0';
835 #if (LINUX_VERSION_CODE < 0x020300)
836                 dbg("plusb_disconnect: About to free name");
837                 kfree (s->net_dev.name);
838                 s->net_dev.name = NULL;
839 #endif  
840         }
841         
842         dbg("plusb_disconnect: finished");
843         MOD_DEC_USE_COUNT;
844 }
845
846 /* --------------------------------------------------------------------- */
847
848 static int plusb_change_mtu(struct net_device *dev, int new_mtu)
849 {
850         if ((new_mtu < 68) || (new_mtu > _BULK_DATA_LEN))
851                 return -EINVAL;
852
853         printk("plusb: changing mtu to %d\n", new_mtu);
854         dev->mtu = new_mtu;
855         
856         /* NOTE: Could we change the size of the READ URB here dynamically
857            to save kernel memory?
858         */
859         return 0;
860 }
861
862 /* --------------------------------------------------------------------- */
863
864 int plusb_net_init(struct net_device *dev)
865 {
866         dbg("plusb_net_init");
867         
868         dev->open=plusb_net_open;
869         dev->stop=plusb_net_stop;
870         dev->hard_start_xmit=plusb_net_xmit;
871         dev->get_stats  = plusb_net_get_stats;
872         ether_setup(dev);
873         dev->change_mtu = plusb_change_mtu;
874         /* Setting the default MTU to 16K gives good performance for
875            me, and keeps the ping latency low too.  Setting it up
876            to 32K made performance go down. -EZA
877            Pavel says it would be best not to do this...
878         */
879         /*dev->mtu=16384; */
880         dev->tx_queue_len = 0;  
881         dev->flags = IFF_POINTOPOINT|IFF_NOARP;
882
883         
884         dbg("plusb_net_init: finished");
885         return 0;
886 }
887
888 /* --------------------------------------------------------------------- */
889
890 static void *plusb_probe (struct usb_device *usbdev, unsigned int ifnum)
891 {
892         plusb_t *s;
893
894         dbg("plusb: probe: vendor id 0x%x, device id 0x%x ifnum:%d",
895           usbdev->descriptor.idVendor, usbdev->descriptor.idProduct, ifnum);
896
897         if (usbdev->descriptor.idVendor != 0x067b || usbdev->descriptor.idProduct > 0x1)
898                 return NULL;
899
900         /* We don't handle multiple configurations */
901         if (usbdev->descriptor.bNumConfigurations != 1)
902                 return NULL;
903
904         s = plusb_find_struct ();
905         if (!s)
906                 return NULL;
907
908         s->usbdev = usbdev;
909
910         if (usb_set_configuration (s->usbdev, usbdev->config[0].bConfigurationValue) < 0) {
911                 err("set_configuration failed");
912                 return NULL;
913         }
914
915         if (usb_set_interface (s->usbdev, 0, 0) < 0) {
916                 err("set_interface failed");
917                 return NULL;
918         }
919
920 #if (LINUX_VERSION_CODE < 0x020300)
921         {
922                 int i;
923                 
924                 /* For Kernel version 2.2, the driver is responsible for
925                    allocating this memory. For version 2.4, the rules
926                    have apparently changed, but there is a nifty function
927                    'init_netdev' that might make this easier...  It's in 
928                    ../net/net_init.c - but can we get there from here?  (no)
929                    -EZA
930                 */
931                 
932                 /* Find the device number... we seem to have lost it... -EZA */
933                 for (i=0; i<NRPLUSB; i++) {
934                         if (&plusb[i] == s)
935                                 break;
936                 }
937         
938                 if(!s->net_dev.name) {
939                         s->net_dev.name = kmalloc(strlen("plusbXXXX"), GFP_KERNEL);
940                         sprintf (s->net_dev.name, "plusb%d", i);
941                         s->net_dev.init=plusb_net_init;
942                         s->net_dev.priv=s;
943                         
944                         printk ("plusb_probe: Registering Device\n");   
945                         if(!register_netdev(&s->net_dev))
946                                 info("registered: %s", s->net_dev.name);
947                         else {
948                                 err("register_netdev failed");
949                                 s->net_dev.name[0] = '\0';
950                         }
951                         dbg ("plusb_probe: Connected!");
952                 }
953         }
954 #else
955         /* Kernel version 2.3+ works a little bit differently than 2.2 */
956         if(!s->net_dev.name[0]) {
957                 strcpy(s->net_dev.name, "plusb%d");
958                 s->net_dev.init=plusb_net_init;
959                 s->net_dev.priv=s;
960                 if(!register_netdev(&s->net_dev))
961                         info("registered: %s", s->net_dev.name);
962                 else {
963                         err("register_netdev failed");
964                         s->net_dev.name[0] = '\0';
965                 }
966         }
967 #endif
968         
969         s->connected = 1;
970
971         if(s->opened) {
972                 dbg("net device already allocated, restarting USB transfers");
973                 plusb_alloc(s);
974         }
975
976         info("bound to interface: %d dev: %p", ifnum, usbdev);
977         MOD_INC_USE_COUNT;
978         return s;
979 }
980 /* --------------------------------------------------------------------- */
981
982 static struct usb_driver plusb_driver =
983 {
984         name: "plusb",
985         probe: plusb_probe,
986         disconnect: plusb_disconnect,
987 };
988
989 /* --------------------------------------------------------------------- */
990
991 static int __init plusb_init (void)
992 {
993         unsigned u;
994         dbg("plusb_init");
995         
996         /* initialize struct */
997         for (u = 0; u < NRPLUSB; u++) {
998                 plusb_t *s = &plusb[u];
999                 memset (s, 0, sizeof (plusb_t));
1000                 INIT_LIST_HEAD (&s->tx_skb_list);
1001                 INIT_LIST_HEAD (&s->free_skb_list);
1002                 spin_lock_init (&s->lock);
1003         }
1004
1005         /* register misc device */
1006         usb_register (&plusb_driver);
1007
1008         dbg("plusb_init: driver registered");
1009
1010         return 0;
1011 }
1012
1013 /* --------------------------------------------------------------------- */
1014
1015 static void __exit plusb_cleanup (void)
1016 {
1017         unsigned u;
1018
1019         dbg("plusb_cleanup");
1020         for (u = 0; u < NRPLUSB; u++) {
1021                 plusb_t *s = &plusb[u];
1022 #if (LINUX_VERSION_CODE < 0x020300)
1023                 if(s->net_dev.name) {
1024                         dbg("unregistering netdev: %s",s->net_dev.name);
1025                         unregister_netdev(&s->net_dev);
1026                         s->net_dev.name[0] = '\0';
1027                         kfree (s->net_dev.name);
1028                         s->net_dev.name = NULL;         
1029                 }               
1030 #else
1031                 if(s->net_dev.name[0]) {
1032                         dbg("unregistering netdev: %s",s->net_dev.name);
1033                         unregister_netdev(&s->net_dev);
1034                         s->net_dev.name[0] = '\0';
1035                 }
1036 #endif
1037         }
1038         usb_deregister (&plusb_driver);
1039         dbg("plusb_cleanup: finished");
1040 }
1041
1042 /* --------------------------------------------------------------------- */
1043
1044 MODULE_AUTHOR ("Deti Fliegl, deti@fliegl.de");
1045 MODULE_DESCRIPTION ("PL-2302 USB Interface Driver for Linux (c)2000");
1046
1047
1048 module_init (plusb_init);
1049 module_exit (plusb_cleanup);
1050
1051 /* --------------------------------------------------------------------- */