1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61#define USE_PROBE 1
62#undef USE_PROBE
63
64
65#define PROBE_VERBOSE 1
66
67
68
69#undef DUMP_PACKETS
70
71
72
73#define USE_MIR
74
75
76
77
78#define OPTIMIZE_TX
79
80
81
82
83
84#define RING_SIZE (OBOE_RING_SIZE_RX8 | OBOE_RING_SIZE_TX8)
85#define TX_SLOTS 8
86#define RX_SLOTS 8
87
88
89
90
91
92
93
94
95
96
97
98
99#define TT_LEN 0x80
100#define TX_LEN 0xc00
101#define RX_LEN 0xc04
102
103
104
105
106#define BUF_SAFETY 0x7a
107#define RX_BUF_SZ (RX_LEN)
108#define TX_BUF_SZ (TX_LEN+BUF_SAFETY)
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145#include <linux/module.h>
146
147#include <linux/kernel.h>
148#include <linux/types.h>
149#include <linux/skbuff.h>
150#include <linux/netdevice.h>
151#include <linux/ioport.h>
152#include <linux/delay.h>
153#include <linux/slab.h>
154#include <linux/init.h>
155#include <linux/interrupt.h>
156#include <linux/pci.h>
157#include <linux/rtnetlink.h>
158
159#include <asm/io.h>
160
161#include <net/irda/wrapper.h>
162#include <net/irda/irda.h>
163
164
165#include <net/irda/irda_device.h>
166#include <net/irda/crc.h>
167
168#include "donauboe.h"
169
170#define INB(port) inb_p(port)
171#define OUTB(val,port) outb_p(val,port)
172#define OUTBP(val,port) outb_p(val,port)
173
174#define PROMPT OUTB(OBOE_PROMPT_BIT,OBOE_PROMPT);
175
176#if PROBE_VERBOSE
177#define PROBE_DEBUG(args...) (printk (args))
178#else
179#define PROBE_DEBUG(args...) ;
180#endif
181
182
183#define CONFIG0H_DMA_OFF OBOE_CONFIG0H_RCVANY
184#define CONFIG0H_DMA_ON_NORX CONFIG0H_DMA_OFF| OBOE_CONFIG0H_ENDMAC
185#define CONFIG0H_DMA_ON CONFIG0H_DMA_ON_NORX | OBOE_CONFIG0H_ENRX
186
187static const struct pci_device_id toshoboe_pci_tbl[] = {
188 { PCI_VENDOR_ID_TOSHIBA, PCI_DEVICE_ID_FIR701, PCI_ANY_ID, PCI_ANY_ID, },
189 { PCI_VENDOR_ID_TOSHIBA, PCI_DEVICE_ID_FIRD01, PCI_ANY_ID, PCI_ANY_ID, },
190 { }
191};
192MODULE_DEVICE_TABLE(pci, toshoboe_pci_tbl);
193
194#define DRIVER_NAME "toshoboe"
195static char *driver_name = DRIVER_NAME;
196
197static int max_baud = 4000000;
198#ifdef USE_PROBE
199static bool do_probe = false;
200#endif
201
202
203
204static int
205toshoboe_checkfcs (unsigned char *buf, int len)
206{
207 int i;
208 union
209 {
210 __u16 value;
211 __u8 bytes[2];
212 }
213 fcs;
214
215 fcs.value = INIT_FCS;
216
217 for (i = 0; i < len; ++i)
218 fcs.value = irda_fcs (fcs.value, *(buf++));
219
220 return fcs.value == GOOD_FCS;
221}
222
223
224
225#ifdef DUMP_PACKETS
226static unsigned char dump[50];
227static void
228_dumpbufs (unsigned char *data, int len, char tete)
229{
230int i,j;
231char head=tete;
232for (i=0;i<len;i+=16) {
233 for (j=0;j<16 && i+j<len;j++) { sprintf(&dump[3*j],"%02x.",data[i+j]); }
234 dump [3*j]=0;
235 pr_debug("%c%s\n", head, dump);
236 head='+';
237 }
238}
239#endif
240
241#ifdef USE_PROBE
242
243static void
244toshoboe_dumpregs (struct toshoboe_cb *self)
245{
246 __u32 ringbase;
247
248 ringbase = INB (OBOE_RING_BASE0) << 10;
249 ringbase |= INB (OBOE_RING_BASE1) << 18;
250 ringbase |= INB (OBOE_RING_BASE2) << 26;
251
252 printk (KERN_ERR DRIVER_NAME ": Register dump:\n");
253 printk (KERN_ERR "Interrupts: Tx:%d Rx:%d TxUnder:%d RxOver:%d Sip:%d\n",
254 self->int_tx, self->int_rx, self->int_txunder, self->int_rxover,
255 self->int_sip);
256 printk (KERN_ERR "RX %02x TX %02x RingBase %08x\n",
257 INB (OBOE_RXSLOT), INB (OBOE_TXSLOT), ringbase);
258 printk (KERN_ERR "RING_SIZE %02x IER %02x ISR %02x\n",
259 INB (OBOE_RING_SIZE), INB (OBOE_IER), INB (OBOE_ISR));
260 printk (KERN_ERR "CONFIG1 %02x STATUS %02x\n",
261 INB (OBOE_CONFIG1), INB (OBOE_STATUS));
262 printk (KERN_ERR "CONFIG0 %02x%02x ENABLE %02x%02x\n",
263 INB (OBOE_CONFIG0H), INB (OBOE_CONFIG0L),
264 INB (OBOE_ENABLEH), INB (OBOE_ENABLEL));
265 printk (KERN_ERR "NEW_PCONFIG %02x%02x CURR_PCONFIG %02x%02x\n",
266 INB (OBOE_NEW_PCONFIGH), INB (OBOE_NEW_PCONFIGL),
267 INB (OBOE_CURR_PCONFIGH), INB (OBOE_CURR_PCONFIGL));
268 printk (KERN_ERR "MAXLEN %02x%02x RXCOUNT %02x%02x\n",
269 INB (OBOE_MAXLENH), INB (OBOE_MAXLENL),
270 INB (OBOE_RXCOUNTL), INB (OBOE_RXCOUNTH));
271
272 if (self->ring)
273 {
274 int i;
275 ringbase = virt_to_bus (self->ring);
276 printk (KERN_ERR "Ring at %08x:\n", ringbase);
277 printk (KERN_ERR "RX:");
278 for (i = 0; i < RX_SLOTS; ++i)
279 printk (" (%d,%02x)",self->ring->rx[i].len,self->ring->rx[i].control);
280 printk ("\n");
281 printk (KERN_ERR "TX:");
282 for (i = 0; i < RX_SLOTS; ++i)
283 printk (" (%d,%02x)",self->ring->tx[i].len,self->ring->tx[i].control);
284 printk ("\n");
285 }
286}
287#endif
288
289
290static void
291toshoboe_disablebm (struct toshoboe_cb *self)
292{
293 __u8 command;
294 pci_read_config_byte (self->pdev, PCI_COMMAND, &command);
295 command &= ~PCI_COMMAND_MASTER;
296 pci_write_config_byte (self->pdev, PCI_COMMAND, command);
297
298}
299
300
301static void
302toshoboe_stopchip (struct toshoboe_cb *self)
303{
304
305 OUTB (0x0, OBOE_IER);
306
307 OUTB (CONFIG0H_DMA_OFF, OBOE_CONFIG0H);
308
309 OUTB (0x00, OBOE_ENABLEH);
310
311 OUTB (0x3f, OBOE_RING_BASE2);
312 OUTB (0xff, OBOE_RING_BASE1);
313 OUTB (0xff, OBOE_RING_BASE0);
314
315 OUTB (RX_LEN >> 8, OBOE_MAXLENH);
316 OUTB (RX_LEN & 0xff, OBOE_MAXLENL);
317
318
319 OUTB (0xff, OBOE_ISR);
320
321
322 OUTB (OBOE_ENABLEH_PHYANDCLOCK, OBOE_ENABLEH);
323
324
325 OUTB (OBOE_CONFIG1_OFF, OBOE_CONFIG1);
326
327 toshoboe_disablebm (self);
328}
329
330
331static void
332toshoboe_start_DMA (struct toshoboe_cb *self, int opts)
333{
334 OUTB (0x0, OBOE_ENABLEH);
335 OUTB (CONFIG0H_DMA_ON | opts, OBOE_CONFIG0H);
336 OUTB (OBOE_ENABLEH_PHYANDCLOCK, OBOE_ENABLEH);
337 PROMPT;
338}
339
340
341static void
342toshoboe_setbaud (struct toshoboe_cb *self)
343{
344 __u16 pconfig = 0;
345 __u8 config0l = 0;
346
347 pr_debug("%s(%d/%d)\n", __func__, self->speed, self->io.speed);
348
349 switch (self->speed)
350 {
351 case 2400:
352 case 4800:
353 case 9600:
354 case 19200:
355 case 38400:
356 case 57600:
357 case 115200:
358#ifdef USE_MIR
359 case 1152000:
360#endif
361 case 4000000:
362 break;
363 default:
364
365 printk (KERN_ERR DRIVER_NAME ": switch to unsupported baudrate %d\n",
366 self->speed);
367 return;
368 }
369
370 switch (self->speed)
371 {
372
373
374
375 case 2400:
376 pconfig |= 47 << OBOE_PCONFIG_BAUDSHIFT;
377 pconfig |= 25 << OBOE_PCONFIG_WIDTHSHIFT;
378 break;
379 case 4800:
380 pconfig |= 23 << OBOE_PCONFIG_BAUDSHIFT;
381 pconfig |= 25 << OBOE_PCONFIG_WIDTHSHIFT;
382 break;
383 case 9600:
384 pconfig |= 11 << OBOE_PCONFIG_BAUDSHIFT;
385 pconfig |= 25 << OBOE_PCONFIG_WIDTHSHIFT;
386 break;
387 case 19200:
388 pconfig |= 5 << OBOE_PCONFIG_BAUDSHIFT;
389 pconfig |= 25 << OBOE_PCONFIG_WIDTHSHIFT;
390 break;
391 case 38400:
392 pconfig |= 2 << OBOE_PCONFIG_BAUDSHIFT;
393 pconfig |= 25 << OBOE_PCONFIG_WIDTHSHIFT;
394 break;
395 case 57600:
396 pconfig |= 1 << OBOE_PCONFIG_BAUDSHIFT;
397 pconfig |= 25 << OBOE_PCONFIG_WIDTHSHIFT;
398 break;
399 case 115200:
400 pconfig |= 0 << OBOE_PCONFIG_BAUDSHIFT;
401 pconfig |= 25 << OBOE_PCONFIG_WIDTHSHIFT;
402 break;
403 default:
404
405 OUTB (RX_LEN >> 8, OBOE_MAXLENH);
406 OUTB (RX_LEN & 0xff, OBOE_MAXLENL);
407 break;
408 }
409
410 switch (self->speed)
411 {
412 case 2400:
413 case 4800:
414 case 9600:
415 case 19200:
416 case 38400:
417 case 57600:
418 case 115200:
419 config0l = OBOE_CONFIG0L_ENSIR;
420 if (self->async)
421 {
422
423
424
425 OUTB (0x01, OBOE_MAXLENH);
426 OUTB (0x01, OBOE_MAXLENL);
427 OUTB (0x00, OBOE_MAXLENH);
428 }
429 else
430 {
431
432 config0l |= OBOE_CONFIG0L_ENSIRF;
433 OUTB (RX_LEN >> 8, OBOE_MAXLENH);
434 OUTB (RX_LEN & 0xff, OBOE_MAXLENL);
435 }
436 break;
437
438#ifdef USE_MIR
439
440
441
442 case 1152000:
443 pconfig |= 0 << OBOE_PCONFIG_BAUDSHIFT;
444 pconfig |= 8 << OBOE_PCONFIG_WIDTHSHIFT;
445 pconfig |= 1 << OBOE_PCONFIG_PREAMBLESHIFT;
446 config0l = OBOE_CONFIG0L_CRC16 | OBOE_CONFIG0L_ENMIR;
447 break;
448#endif
449
450
451
452 case 4000000:
453 pconfig |= 0 << OBOE_PCONFIG_BAUDSHIFT;
454
455 pconfig |= 15 << OBOE_PCONFIG_PREAMBLESHIFT;
456 config0l = OBOE_CONFIG0L_ENFIR;
457 break;
458 }
459
460
461 OUTBP (pconfig >> 8, OBOE_NEW_PCONFIGH);
462 OUTB (pconfig & 0xff, OBOE_NEW_PCONFIGL);
463 OUTB (config0l, OBOE_CONFIG0L);
464
465
466 OUTB (0x0, OBOE_ENABLEH);
467 OUTB (OBOE_ENABLEH_PHYANDCLOCK, OBOE_ENABLEH);
468 PROMPT;
469
470
471 self->new_speed = 0;
472 self->io.speed = self->speed;
473}
474
475
476static void
477toshoboe_enablebm (struct toshoboe_cb *self)
478{
479 pci_set_master (self->pdev);
480}
481
482
483static void
484toshoboe_initring (struct toshoboe_cb *self)
485{
486 int i;
487
488 for (i = 0; i < TX_SLOTS; ++i)
489 {
490 self->ring->tx[i].len = 0;
491 self->ring->tx[i].control = 0x00;
492 self->ring->tx[i].address = virt_to_bus (self->tx_bufs[i]);
493 }
494
495 for (i = 0; i < RX_SLOTS; ++i)
496 {
497 self->ring->rx[i].len = RX_LEN;
498 self->ring->rx[i].len = 0;
499 self->ring->rx[i].address = virt_to_bus (self->rx_bufs[i]);
500 self->ring->rx[i].control = OBOE_CTL_RX_HW_OWNS;
501 }
502}
503
504static void
505toshoboe_resetptrs (struct toshoboe_cb *self)
506{
507
508 OUTB (0x0, OBOE_ENABLEH);
509 OUTBP (CONFIG0H_DMA_OFF, OBOE_CONFIG0H);
510 OUTB (OBOE_ENABLEH_PHYANDCLOCK, OBOE_ENABLEH);
511
512 self->rxs = inb_p (OBOE_RXSLOT) & OBOE_SLOT_MASK;
513 self->txs = inb_p (OBOE_TXSLOT) & OBOE_SLOT_MASK;
514}
515
516
517static void
518toshoboe_initptrs (struct toshoboe_cb *self)
519{
520
521
522
523
524
525 toshoboe_resetptrs (self);
526
527 OUTB (0x0, OBOE_ENABLEH);
528 OUTB (CONFIG0H_DMA_ON, OBOE_CONFIG0H);
529 OUTB (OBOE_ENABLEH_PHYANDCLOCK, OBOE_ENABLEH);
530
531 self->txpending = 0;
532
533
534
535}
536
537
538
539static void
540toshoboe_startchip (struct toshoboe_cb *self)
541{
542 __u32 physaddr;
543
544 toshoboe_initring (self);
545 toshoboe_enablebm (self);
546 OUTBP (OBOE_CONFIG1_RESET, OBOE_CONFIG1);
547 OUTBP (OBOE_CONFIG1_ON, OBOE_CONFIG1);
548
549
550 OUTB (0, OBOE_ENABLEH);
551
552
553 OUTB (RING_SIZE, OBOE_RING_SIZE);
554
555
556 OUTB (0xff, OBOE_ISR);
557
558
559 OUTB (OBOE_INT_TXDONE | OBOE_INT_RXDONE |
560 OBOE_INT_TXUNDER | OBOE_INT_RXOVER | OBOE_INT_SIP , OBOE_IER);
561
562
563 OUTB (0xff, OBOE_ISR);
564
565
566 OUTB (RX_LEN >> 8, OBOE_MAXLENH);
567 OUTB (RX_LEN & 0xff, OBOE_MAXLENL);
568
569
570 OUTB (CONFIG0H_DMA_OFF, OBOE_CONFIG0H);
571
572
573 physaddr = virt_to_bus (self->ring);
574
575 IRDA_ASSERT ((physaddr & 0x3ff) == 0,
576 printk (KERN_ERR DRIVER_NAME "ring not correctly aligned\n");
577 return;);
578
579 OUTB ((physaddr >> 10) & 0xff, OBOE_RING_BASE0);
580 OUTB ((physaddr >> 18) & 0xff, OBOE_RING_BASE1);
581 OUTB ((physaddr >> 26) & 0x3f, OBOE_RING_BASE2);
582
583
584 OUTB (CONFIG0H_DMA_ON, OBOE_CONFIG0H);
585
586
587 OUTB (OBOE_ENABLEH_PHYANDCLOCK, OBOE_ENABLEH);
588
589
590 self->speed = 9600;
591 toshoboe_setbaud (self);
592 toshoboe_initptrs (self);
593}
594
595static void
596toshoboe_isntstuck (struct toshoboe_cb *self)
597{
598}
599
600static void
601toshoboe_checkstuck (struct toshoboe_cb *self)
602{
603 unsigned long flags;
604
605 if (0)
606 {
607 spin_lock_irqsave(&self->spinlock, flags);
608
609
610 printk (KERN_ERR DRIVER_NAME ": Resetting chip\n");
611
612 toshoboe_stopchip (self);
613 toshoboe_startchip (self);
614 spin_unlock_irqrestore(&self->spinlock, flags);
615 }
616}
617
618
619static int
620toshoboe_makemttpacket (struct toshoboe_cb *self, void *buf, int mtt)
621{
622 int xbofs;
623
624 xbofs = ((int) (mtt/100)) * (int) (self->speed);
625 xbofs=xbofs/80000;
626 xbofs++;
627
628 pr_debug(DRIVER_NAME ": generated mtt of %d bytes for %d us at %d baud\n",
629 xbofs, mtt, self->speed);
630
631 if (xbofs > TX_LEN)
632 {
633 printk (KERN_ERR DRIVER_NAME ": wanted %d bytes MTT but TX_LEN is %d\n",
634 xbofs, TX_LEN);
635 xbofs = TX_LEN;
636 }
637
638
639 memset (buf, XBOF, xbofs);
640
641 return xbofs;
642}
643
644#ifdef USE_PROBE
645
646
647
648static void
649toshoboe_dumptx (struct toshoboe_cb *self)
650{
651 int i;
652 PROBE_DEBUG(KERN_WARNING "TX:");
653 for (i = 0; i < RX_SLOTS; ++i)
654 PROBE_DEBUG(" (%d,%02x)",self->ring->tx[i].len,self->ring->tx[i].control);
655 PROBE_DEBUG(" [%d]\n",self->speed);
656}
657
658static void
659toshoboe_dumprx (struct toshoboe_cb *self, int score)
660{
661 int i;
662 PROBE_DEBUG(" %d\nRX:",score);
663 for (i = 0; i < RX_SLOTS; ++i)
664 PROBE_DEBUG(" (%d,%02x)",self->ring->rx[i].len,self->ring->rx[i].control);
665 PROBE_DEBUG("\n");
666}
667
668static inline int
669stuff_byte (__u8 byte, __u8 * buf)
670{
671 switch (byte)
672 {
673 case BOF:
674 case EOF:
675 case CE:
676
677 buf[0] = CE;
678 buf[1] = byte ^ IRDA_TRANS;
679 return 2;
680
681 default:
682
683 buf[0] = byte;
684 return 1;
685
686 }
687}
688
689static irqreturn_t
690toshoboe_probeinterrupt (int irq, void *dev_id)
691{
692 struct toshoboe_cb *self = dev_id;
693 __u8 irqstat;
694
695 irqstat = INB (OBOE_ISR);
696
697
698 if (!(irqstat & OBOE_INT_MASK))
699 return IRQ_NONE;
700
701
702 OUTB (irqstat, OBOE_ISR);
703
704 if (irqstat & OBOE_INT_TXDONE)
705 {
706 int txp;
707
708 self->int_tx++;
709 PROBE_DEBUG("T");
710
711 txp = INB (OBOE_TXSLOT) & OBOE_SLOT_MASK;
712 if (self->ring->tx[txp].control & OBOE_CTL_TX_HW_OWNS)
713 {
714 self->int_tx+=100;
715 PROBE_DEBUG("S");
716 toshoboe_start_DMA(self, OBOE_CONFIG0H_ENTX | OBOE_CONFIG0H_LOOP);
717 }
718 }
719
720 if (irqstat & OBOE_INT_RXDONE) {
721 self->int_rx++;
722 PROBE_DEBUG("R"); }
723 if (irqstat & OBOE_INT_TXUNDER) {
724 self->int_txunder++;
725 PROBE_DEBUG("U"); }
726 if (irqstat & OBOE_INT_RXOVER) {
727 self->int_rxover++;
728 PROBE_DEBUG("O"); }
729 if (irqstat & OBOE_INT_SIP) {
730 self->int_sip++;
731 PROBE_DEBUG("I"); }
732 return IRQ_HANDLED;
733}
734
735static int
736toshoboe_maketestpacket (unsigned char *buf, int badcrc, int fir)
737{
738 int i;
739 int len = 0;
740 union
741 {
742 __u16 value;
743 __u8 bytes[2];
744 }
745 fcs;
746
747 if (fir)
748 {
749 memset (buf, 0, TT_LEN);
750 return TT_LEN;
751 }
752
753 fcs.value = INIT_FCS;
754
755 memset (buf, XBOF, 10);
756 len += 10;
757 buf[len++] = BOF;
758
759 for (i = 0; i < TT_LEN; ++i)
760 {
761 len += stuff_byte (i, buf + len);
762 fcs.value = irda_fcs (fcs.value, i);
763 }
764
765 len += stuff_byte (fcs.bytes[0] ^ badcrc, buf + len);
766 len += stuff_byte (fcs.bytes[1] ^ badcrc, buf + len);
767 buf[len++] = EOF;
768 len++;
769 return len;
770}
771
772static int
773toshoboe_probefail (struct toshoboe_cb *self, char *msg)
774{
775 printk (KERN_ERR DRIVER_NAME "probe(%d) failed %s\n",self-> speed, msg);
776 toshoboe_dumpregs (self);
777 toshoboe_stopchip (self);
778 free_irq (self->io.irq, (void *) self);
779 return 0;
780}
781
782static int
783toshoboe_numvalidrcvs (struct toshoboe_cb *self)
784{
785 int i, ret = 0;
786 for (i = 0; i < RX_SLOTS; ++i)
787 if ((self->ring->rx[i].control & 0xe0) == 0)
788 ret++;
789
790 return ret;
791}
792
793static int
794toshoboe_numrcvs (struct toshoboe_cb *self)
795{
796 int i, ret = 0;
797 for (i = 0; i < RX_SLOTS; ++i)
798 if (!(self->ring->rx[i].control & OBOE_CTL_RX_HW_OWNS))
799 ret++;
800
801 return ret;
802}
803
804static int
805toshoboe_probe (struct toshoboe_cb *self)
806{
807 int i, j, n;
808#ifdef USE_MIR
809 static const int bauds[] = { 9600, 115200, 4000000, 1152000 };
810#else
811 static const int bauds[] = { 9600, 115200, 4000000 };
812#endif
813 unsigned long flags;
814
815 if (request_irq (self->io.irq, toshoboe_probeinterrupt,
816 self->io.irqflags, "toshoboe", (void *) self))
817 {
818 printk (KERN_ERR DRIVER_NAME ": probe failed to allocate irq %d\n",
819 self->io.irq);
820 return 0;
821 }
822
823
824
825 for (j = 0; j < ARRAY_SIZE(bauds); ++j)
826 {
827 int fir = (j > 1);
828 toshoboe_stopchip (self);
829
830
831 spin_lock_irqsave(&self->spinlock, flags);
832
833 toshoboe_startchip (self);
834 self->int_rx = self->int_tx = 0;
835 self->speed = bauds[j];
836 toshoboe_setbaud (self);
837 toshoboe_initptrs (self);
838 spin_unlock_irqrestore(&self->spinlock, flags);
839
840 self->ring->tx[self->txs].control =
841
842
843 (fir) ? OBOE_CTL_TX_HW_OWNS | OBOE_CTL_TX_RTCENTX
844 : OBOE_CTL_TX_HW_OWNS ;
845 self->ring->tx[self->txs].len =
846 toshoboe_maketestpacket (self->tx_bufs[self->txs], 0, fir);
847 self->txs++;
848 self->txs %= TX_SLOTS;
849
850 self->ring->tx[self->txs].control =
851 (fir) ? OBOE_CTL_TX_HW_OWNS | OBOE_CTL_TX_SIP
852 : OBOE_CTL_TX_HW_OWNS | OBOE_CTL_TX_RTCENTX ;
853 self->ring->tx[self->txs].len =
854 toshoboe_maketestpacket (self->tx_bufs[self->txs], 0, fir);
855 self->txs++;
856 self->txs %= TX_SLOTS;
857
858 self->ring->tx[self->txs].control =
859 (fir) ? OBOE_CTL_TX_HW_OWNS | OBOE_CTL_TX_RTCENTX
860 : OBOE_CTL_TX_HW_OWNS ;
861 self->ring->tx[self->txs].len =
862 toshoboe_maketestpacket (self->tx_bufs[self->txs], 0, fir);
863 self->txs++;
864 self->txs %= TX_SLOTS;
865
866 self->ring->tx[self->txs].control =
867 (fir) ? OBOE_CTL_TX_HW_OWNS | OBOE_CTL_TX_RTCENTX
868 | OBOE_CTL_TX_SIP | OBOE_CTL_TX_BAD_CRC
869 : OBOE_CTL_TX_HW_OWNS | OBOE_CTL_TX_RTCENTX ;
870 self->ring->tx[self->txs].len =
871 toshoboe_maketestpacket (self->tx_bufs[self->txs], 0, fir);
872 self->txs++;
873 self->txs %= TX_SLOTS;
874
875 toshoboe_dumptx (self);
876
877 toshoboe_start_DMA(self, OBOE_CONFIG0H_ENTX | OBOE_CONFIG0H_LOOP);
878
879 i = 0;
880 n = fir ? 1 : 4;
881 while (toshoboe_numvalidrcvs (self) != n)
882 {
883 if (i > 4800)
884 return toshoboe_probefail (self, "filter test");
885 udelay ((9600*(TT_LEN+16))/self->speed);
886 i++;
887 }
888
889 n = fir ? 203 : 102;
890 while ((toshoboe_numrcvs(self) != self->int_rx) || (self->int_tx != n))
891 {
892 if (i > 4800)
893 return toshoboe_probefail (self, "interrupt test");
894 udelay ((9600*(TT_LEN+16))/self->speed);
895 i++;
896 }
897 toshoboe_dumprx (self,i);
898
899 }
900
901
902
903 toshoboe_stopchip (self);
904 self->int_rx = self->int_tx = 0;
905
906 spin_lock_irqsave(&self->spinlock, flags);
907 toshoboe_startchip (self);
908 spin_unlock_irqrestore(&self->spinlock, flags);
909
910 self->async = 1;
911 self->speed = 115200;
912 toshoboe_setbaud (self);
913 self->ring->tx[self->txs].control =
914 OBOE_CTL_TX_RTCENTX | OBOE_CTL_TX_HW_OWNS;
915 self->ring->tx[self->txs].len = 4;
916
917 ((unsigned char *) self->tx_bufs[self->txs])[0] = 'f';
918 ((unsigned char *) self->tx_bufs[self->txs])[1] = 'i';
919 ((unsigned char *) self->tx_bufs[self->txs])[2] = 's';
920 ((unsigned char *) self->tx_bufs[self->txs])[3] = 'h';
921 toshoboe_dumptx (self);
922 toshoboe_start_DMA(self, OBOE_CONFIG0H_ENTX | OBOE_CONFIG0H_LOOP);
923
924 i = 0;
925 while (toshoboe_numvalidrcvs (self) != 4)
926 {
927 if (i > 100)
928 return toshoboe_probefail (self, "Async test");
929 udelay (100);
930 i++;
931 }
932
933 while ((toshoboe_numrcvs (self) != self->int_rx) || (self->int_tx != 1))
934 {
935 if (i > 100)
936 return toshoboe_probefail (self, "Async interrupt test");
937 udelay (100);
938 i++;
939 }
940 toshoboe_dumprx (self,i);
941
942 self->async = 0;
943 self->speed = 9600;
944 toshoboe_setbaud (self);
945 toshoboe_stopchip (self);
946
947 free_irq (self->io.irq, (void *) self);
948
949 printk (KERN_WARNING DRIVER_NAME ": Self test passed ok\n");
950
951 return 1;
952}
953#endif
954
955
956
957
958
959static netdev_tx_t
960toshoboe_hard_xmit (struct sk_buff *skb, struct net_device *dev)
961{
962 struct toshoboe_cb *self;
963 __s32 speed;
964 int mtt, len, ctl;
965 unsigned long flags;
966 struct irda_skb_cb *cb = (struct irda_skb_cb *) skb->cb;
967
968 self = netdev_priv(dev);
969
970 IRDA_ASSERT (self != NULL, return NETDEV_TX_OK; );
971
972 pr_debug("%s.tx:%x(%x)%x\n",
973 __func__, skb->len, self->txpending, INB(OBOE_ENABLEH));
974 if (!cb->magic) {
975 pr_debug("%s.Not IrLAP:%x\n", __func__, cb->magic);
976#ifdef DUMP_PACKETS
977 _dumpbufs(skb->data,skb->len,'>');
978#endif
979 }
980
981
982 if (self->new_speed)
983 return NETDEV_TX_BUSY;
984
985
986 if (self->stopped)
987 return NETDEV_TX_BUSY;
988
989 toshoboe_checkstuck (self);
990
991
992
993 speed=irda_get_next_speed(skb);
994 if ((speed != self->io.speed) && (speed != -1))
995 {
996 spin_lock_irqsave(&self->spinlock, flags);
997
998 if (self->txpending || skb->len)
999 {
1000 self->new_speed = speed;
1001 pr_debug("%s: Queued TxDone scheduled speed change %d\n" ,
1002 __func__, speed);
1003
1004 if (!skb->len)
1005 {
1006 spin_unlock_irqrestore(&self->spinlock, flags);
1007 dev_kfree_skb (skb);
1008 return NETDEV_TX_OK;
1009 }
1010
1011
1012 netif_stop_queue(dev);
1013
1014 spin_unlock_irqrestore(&self->spinlock, flags);
1015 }
1016 else
1017 {
1018
1019 self->speed = speed;
1020 toshoboe_setbaud (self);
1021 spin_unlock_irqrestore(&self->spinlock, flags);
1022 dev_kfree_skb (skb);
1023 return NETDEV_TX_OK;
1024 }
1025
1026 }
1027
1028 if ((mtt = irda_get_mtt(skb)))
1029 {
1030
1031 spin_lock_irqsave(&self->spinlock, flags);
1032
1033 if (self->txpending)
1034 {
1035 spin_unlock_irqrestore(&self->spinlock, flags);
1036 return NETDEV_TX_BUSY;
1037 }
1038
1039
1040
1041
1042
1043 mtt = toshoboe_makemttpacket (self, self->tx_bufs[self->txs], mtt);
1044 pr_debug("%s.mtt:%x(%x)%d\n", __func__, skb->len, mtt, self->txpending);
1045 if (mtt)
1046 {
1047 self->ring->tx[self->txs].len = mtt & 0xfff;
1048
1049 ctl = OBOE_CTL_TX_HW_OWNS | OBOE_CTL_TX_RTCENTX;
1050 if (INB (OBOE_ENABLEH) & OBOE_ENABLEH_FIRON)
1051 {
1052 ctl |= OBOE_CTL_TX_BAD_CRC | OBOE_CTL_TX_SIP ;
1053 }
1054#ifdef USE_MIR
1055 else if (INB (OBOE_ENABLEH) & OBOE_ENABLEH_MIRON)
1056 {
1057 ctl |= OBOE_CTL_TX_BAD_CRC;
1058 }
1059#endif
1060 self->ring->tx[self->txs].control = ctl;
1061
1062 OUTB (0x0, OBOE_ENABLEH);
1063
1064 toshoboe_start_DMA(self, OBOE_CONFIG0H_ENTX | OBOE_CONFIG0H_LOOP);
1065
1066 self->txpending++;
1067
1068 self->txs++;
1069 self->txs %= TX_SLOTS;
1070
1071 }
1072 else
1073 {
1074 printk(KERN_ERR DRIVER_NAME ": problem with mtt packet - ignored\n");
1075 }
1076 spin_unlock_irqrestore(&self->spinlock, flags);
1077 }
1078
1079#ifdef DUMP_PACKETS
1080dumpbufs(skb->data,skb->len,'>');
1081#endif
1082
1083 spin_lock_irqsave(&self->spinlock, flags);
1084
1085 if (self->ring->tx[self->txs].control & OBOE_CTL_TX_HW_OWNS)
1086 {
1087 pr_debug("%s.ful:%x(%x)%x\n",
1088 __func__, skb->len, self->ring->tx[self->txs].control,
1089 self->txpending);
1090 toshoboe_start_DMA(self, OBOE_CONFIG0H_ENTX);
1091 spin_unlock_irqrestore(&self->spinlock, flags);
1092 return NETDEV_TX_BUSY;
1093 }
1094
1095 if (INB (OBOE_ENABLEH) & OBOE_ENABLEH_SIRON)
1096 {
1097 len = async_wrap_skb (skb, self->tx_bufs[self->txs], TX_BUF_SZ);
1098 }
1099 else
1100 {
1101 len = skb->len;
1102 skb_copy_from_linear_data(skb, self->tx_bufs[self->txs], len);
1103 }
1104 self->ring->tx[self->txs].len = len & 0x0fff;
1105
1106
1107
1108
1109
1110 ctl = OBOE_CTL_TX_HW_OWNS | OBOE_CTL_TX_RTCENTX;
1111 if (INB (OBOE_ENABLEH) & OBOE_ENABLEH_FIRON)
1112 {
1113 ctl |= OBOE_CTL_TX_SIP ;
1114 }
1115 self->ring->tx[self->txs].control = ctl;
1116
1117
1118
1119 if (!self->txpending)
1120 toshoboe_start_DMA(self, OBOE_CONFIG0H_ENTX);
1121
1122 self->txpending++;
1123
1124 self->txs++;
1125 self->txs %= TX_SLOTS;
1126
1127 spin_unlock_irqrestore(&self->spinlock, flags);
1128 dev_kfree_skb (skb);
1129
1130 return NETDEV_TX_OK;
1131}
1132
1133
1134static irqreturn_t
1135toshoboe_interrupt (int irq, void *dev_id)
1136{
1137 struct toshoboe_cb *self = dev_id;
1138 __u8 irqstat;
1139 struct sk_buff *skb = NULL;
1140
1141 irqstat = INB (OBOE_ISR);
1142
1143
1144 if (!(irqstat & OBOE_INT_MASK))
1145 return IRQ_NONE;
1146
1147
1148 OUTB (irqstat, OBOE_ISR);
1149
1150 toshoboe_isntstuck (self);
1151
1152
1153 if (irqstat & OBOE_INT_TXDONE)
1154 {
1155 int txp, txpc;
1156 int i;
1157
1158 txp = self->txpending;
1159 self->txpending = 0;
1160
1161 for (i = 0; i < TX_SLOTS; ++i)
1162 {
1163 if (self->ring->tx[i].control & OBOE_CTL_TX_HW_OWNS)
1164 self->txpending++;
1165 }
1166 pr_debug("%s.txd(%x)%x/%x\n", __func__, irqstat, txp, self->txpending);
1167
1168 txp = INB (OBOE_TXSLOT) & OBOE_SLOT_MASK;
1169
1170
1171 if (self->ring->tx[txp].control & OBOE_CTL_TX_HW_OWNS)
1172 {
1173 txpc = txp;
1174#ifdef OPTIMIZE_TX
1175 while (self->ring->tx[txpc].control & OBOE_CTL_TX_HW_OWNS)
1176 {
1177 txp = txpc;
1178 txpc++;
1179 txpc %= TX_SLOTS;
1180 self->netdev->stats.tx_packets++;
1181 if (self->ring->tx[txpc].control & OBOE_CTL_TX_HW_OWNS)
1182 self->ring->tx[txp].control &= ~OBOE_CTL_TX_RTCENTX;
1183 }
1184 self->netdev->stats.tx_packets--;
1185#else
1186 self->netdev->stats.tx_packets++;
1187#endif
1188 toshoboe_start_DMA(self, OBOE_CONFIG0H_ENTX);
1189 }
1190
1191 if ((!self->txpending) && (self->new_speed))
1192 {
1193 self->speed = self->new_speed;
1194 pr_debug("%s: Executed TxDone scheduled speed change %d\n",
1195 __func__, self->speed);
1196 toshoboe_setbaud (self);
1197 }
1198
1199
1200 if (!self->new_speed)
1201 netif_wake_queue(self->netdev);
1202 }
1203
1204 if (irqstat & OBOE_INT_RXDONE)
1205 {
1206 while (!(self->ring->rx[self->rxs].control & OBOE_CTL_RX_HW_OWNS))
1207 {
1208 int len = self->ring->rx[self->rxs].len;
1209 skb = NULL;
1210 pr_debug("%s.rcv:%x(%x)\n", __func__
1211 , len, self->ring->rx[self->rxs].control);
1212
1213#ifdef DUMP_PACKETS
1214dumpbufs(self->rx_bufs[self->rxs],len,'<');
1215#endif
1216
1217 if (self->ring->rx[self->rxs].control == 0)
1218 {
1219 __u8 enable = INB (OBOE_ENABLEH);
1220
1221
1222
1223 if (enable & OBOE_ENABLEH_SIRON)
1224 {
1225 if (!toshoboe_checkfcs (self->rx_bufs[self->rxs], len))
1226 len = 0;
1227
1228 if (len > 1)
1229 len -= 2;
1230 else
1231 len = 0;
1232 pr_debug("%s.SIR:%x(%x)\n", __func__, len, enable);
1233 }
1234
1235#ifdef USE_MIR
1236 else if (enable & OBOE_ENABLEH_MIRON)
1237 {
1238 if (len > 1)
1239 len -= 2;
1240 else
1241 len = 0;
1242 pr_debug("%s.MIR:%x(%x)\n", __func__, len, enable);
1243 }
1244#endif
1245 else if (enable & OBOE_ENABLEH_FIRON)
1246 {
1247 if (len > 3)
1248 len -= 4;
1249 else
1250 len = 0;
1251 pr_debug("%s.FIR:%x(%x)\n", __func__, len, enable);
1252 }
1253 else
1254 pr_debug("%s.?IR:%x(%x)\n", __func__, len, enable);
1255
1256 if (len)
1257 {
1258 skb = dev_alloc_skb (len + 1);
1259 if (skb)
1260 {
1261 skb_reserve (skb, 1);
1262
1263 skb_put (skb, len);
1264 skb_copy_to_linear_data(skb, self->rx_bufs[self->rxs],
1265 len);
1266 self->netdev->stats.rx_packets++;
1267 skb->dev = self->netdev;
1268 skb_reset_mac_header(skb);
1269 skb->protocol = htons (ETH_P_IRDA);
1270 }
1271 else
1272 {
1273 printk (KERN_INFO
1274 "%s(), memory squeeze, dropping frame.\n",
1275 __func__);
1276 }
1277 }
1278 }
1279 else
1280 {
1281
1282
1283
1284
1285
1286
1287 pr_debug("%s.err:%x(%x)\n", __func__
1288 , len, self->ring->rx[self->rxs].control);
1289 }
1290
1291 self->ring->rx[self->rxs].len = 0x0;
1292 self->ring->rx[self->rxs].control = OBOE_CTL_RX_HW_OWNS;
1293
1294 self->rxs++;
1295 self->rxs %= RX_SLOTS;
1296
1297 if (skb)
1298 netif_rx (skb);
1299
1300 }
1301 }
1302
1303 if (irqstat & OBOE_INT_TXUNDER)
1304 {
1305 printk (KERN_WARNING DRIVER_NAME ": tx fifo underflow\n");
1306 }
1307 if (irqstat & OBOE_INT_RXOVER)
1308 {
1309 printk (KERN_WARNING DRIVER_NAME ": rx fifo overflow\n");
1310 }
1311
1312 if (irqstat & OBOE_INT_SIP)
1313 {
1314 self->int_sip++;
1315 pr_debug("%s.sip:%x(%x)%x\n",
1316 __func__, self->int_sip, irqstat, self->txpending);
1317 }
1318 return IRQ_HANDLED;
1319}
1320
1321
1322static int
1323toshoboe_net_open (struct net_device *dev)
1324{
1325 struct toshoboe_cb *self;
1326 unsigned long flags;
1327 int rc;
1328
1329 self = netdev_priv(dev);
1330
1331 if (self->async)
1332 return -EBUSY;
1333
1334 if (self->stopped)
1335 return 0;
1336
1337 rc = request_irq (self->io.irq, toshoboe_interrupt,
1338 IRQF_SHARED, dev->name, self);
1339 if (rc)
1340 return rc;
1341
1342 spin_lock_irqsave(&self->spinlock, flags);
1343 toshoboe_startchip (self);
1344 spin_unlock_irqrestore(&self->spinlock, flags);
1345
1346
1347 netif_start_queue(dev);
1348
1349
1350
1351
1352
1353 self->irlap = irlap_open (dev, &self->qos, driver_name);
1354
1355 self->irdad = 1;
1356
1357 return 0;
1358}
1359
1360static int
1361toshoboe_net_close (struct net_device *dev)
1362{
1363 struct toshoboe_cb *self;
1364
1365 IRDA_ASSERT (dev != NULL, return -1; );
1366 self = netdev_priv(dev);
1367
1368
1369 netif_stop_queue(dev);
1370
1371
1372 if (self->irlap)
1373 irlap_close (self->irlap);
1374 self->irlap = NULL;
1375
1376 self->irdad = 0;
1377
1378 free_irq (self->io.irq, (void *) self);
1379
1380 if (!self->stopped)
1381 {
1382 toshoboe_stopchip (self);
1383 }
1384
1385 return 0;
1386}
1387
1388
1389
1390
1391
1392
1393
1394static int
1395toshoboe_net_ioctl (struct net_device *dev, struct ifreq *rq, int cmd)
1396{
1397 struct if_irda_req *irq = (struct if_irda_req *) rq;
1398 struct toshoboe_cb *self;
1399 unsigned long flags;
1400 int ret = 0;
1401
1402 IRDA_ASSERT (dev != NULL, return -1; );
1403
1404 self = netdev_priv(dev);
1405
1406 IRDA_ASSERT (self != NULL, return -1; );
1407
1408 pr_debug("%s(), %s, (cmd=0x%X)\n", __func__, dev->name, cmd);
1409
1410
1411 spin_lock_irqsave(&self->spinlock, flags);
1412
1413 switch (cmd)
1414 {
1415 case SIOCSBANDWIDTH:
1416
1417
1418
1419
1420 pr_debug("%s(BANDWIDTH), %s, (%X/%ld\n",
1421 __func__, dev->name, INB(OBOE_STATUS), irq->ifr_baudrate);
1422 if (!in_interrupt () && !capable (CAP_NET_ADMIN)) {
1423 ret = -EPERM;
1424 goto out;
1425 }
1426
1427
1428
1429
1430 self->new_speed = irq->ifr_baudrate;
1431 break;
1432 case SIOCSMEDIABUSY:
1433 pr_debug("%s(MEDIABUSY), %s, (%X/%x)\n",
1434 __func__, dev->name,
1435 INB(OBOE_STATUS), capable(CAP_NET_ADMIN));
1436 if (!capable (CAP_NET_ADMIN)) {
1437 ret = -EPERM;
1438 goto out;
1439 }
1440 irda_device_set_media_busy (self->netdev, TRUE);
1441 break;
1442 case SIOCGRECEIVING:
1443 irq->ifr_receiving = (INB (OBOE_STATUS) & OBOE_STATUS_RXBUSY) ? 1 : 0;
1444 pr_debug("%s(RECEIVING), %s, (%X/%x)\n",
1445 __func__, dev->name, INB(OBOE_STATUS), irq->ifr_receiving);
1446 break;
1447 default:
1448 pr_debug("%s(?), %s, (cmd=0x%X)\n", __func__, dev->name, cmd);
1449 ret = -EOPNOTSUPP;
1450 }
1451out:
1452 spin_unlock_irqrestore(&self->spinlock, flags);
1453 return ret;
1454
1455}
1456
1457MODULE_DESCRIPTION("Toshiba OBOE IrDA Device Driver");
1458MODULE_AUTHOR("James McKenzie <james@fishsoup.dhs.org>");
1459MODULE_LICENSE("GPL");
1460
1461module_param (max_baud, int, 0);
1462MODULE_PARM_DESC(max_baud, "Maximum baud rate");
1463
1464#ifdef USE_PROBE
1465module_param (do_probe, bool, 0);
1466MODULE_PARM_DESC(do_probe, "Enable/disable chip probing and self-test");
1467#endif
1468
1469static void
1470toshoboe_close (struct pci_dev *pci_dev)
1471{
1472 int i;
1473 struct toshoboe_cb *self = pci_get_drvdata(pci_dev);
1474
1475 IRDA_ASSERT (self != NULL, return; );
1476
1477 if (!self->stopped)
1478 {
1479 toshoboe_stopchip (self);
1480 }
1481
1482 release_region (self->io.fir_base, self->io.fir_ext);
1483
1484 for (i = 0; i < TX_SLOTS; ++i)
1485 {
1486 kfree (self->tx_bufs[i]);
1487 self->tx_bufs[i] = NULL;
1488 }
1489
1490 for (i = 0; i < RX_SLOTS; ++i)
1491 {
1492 kfree (self->rx_bufs[i]);
1493 self->rx_bufs[i] = NULL;
1494 }
1495
1496 unregister_netdev(self->netdev);
1497
1498 kfree (self->ringbuf);
1499 self->ringbuf = NULL;
1500 self->ring = NULL;
1501
1502 free_netdev(self->netdev);
1503}
1504
1505static const struct net_device_ops toshoboe_netdev_ops = {
1506 .ndo_open = toshoboe_net_open,
1507 .ndo_stop = toshoboe_net_close,
1508 .ndo_start_xmit = toshoboe_hard_xmit,
1509 .ndo_do_ioctl = toshoboe_net_ioctl,
1510};
1511
1512static int
1513toshoboe_open (struct pci_dev *pci_dev, const struct pci_device_id *pdid)
1514{
1515 struct toshoboe_cb *self;
1516 struct net_device *dev;
1517 int i = 0;
1518 int ok = 0;
1519 int err;
1520
1521 if ((err=pci_enable_device(pci_dev)))
1522 return err;
1523
1524 dev = alloc_irdadev(sizeof (struct toshoboe_cb));
1525 if (dev == NULL)
1526 {
1527 printk (KERN_ERR DRIVER_NAME ": can't allocate memory for "
1528 "IrDA control block\n");
1529 return -ENOMEM;
1530 }
1531
1532 self = netdev_priv(dev);
1533 self->netdev = dev;
1534 self->pdev = pci_dev;
1535 self->base = pci_resource_start(pci_dev,0);
1536
1537 self->io.fir_base = self->base;
1538 self->io.fir_ext = OBOE_IO_EXTENT;
1539 self->io.irq = pci_dev->irq;
1540 self->io.irqflags = IRQF_SHARED;
1541
1542 self->speed = self->io.speed = 9600;
1543 self->async = 0;
1544
1545
1546 if (NULL==request_region (self->io.fir_base, self->io.fir_ext, driver_name))
1547 {
1548 printk (KERN_ERR DRIVER_NAME ": can't get iobase of 0x%03x\n"
1549 ,self->io.fir_base);
1550 err = -EBUSY;
1551 goto freeself;
1552 }
1553
1554 spin_lock_init(&self->spinlock);
1555
1556 irda_init_max_qos_capabilies (&self->qos);
1557 self->qos.baud_rate.bits = 0;
1558
1559 if (max_baud >= 2400)
1560 self->qos.baud_rate.bits |= IR_2400;
1561
1562 if (max_baud >= 9600)
1563 self->qos.baud_rate.bits |= IR_9600;
1564 if (max_baud >= 19200)
1565 self->qos.baud_rate.bits |= IR_19200;
1566 if (max_baud >= 115200)
1567 self->qos.baud_rate.bits |= IR_115200;
1568#ifdef USE_MIR
1569 if (max_baud >= 1152000)
1570 {
1571 self->qos.baud_rate.bits |= IR_1152000;
1572 }
1573#endif
1574 if (max_baud >= 4000000)
1575 {
1576 self->qos.baud_rate.bits |= (IR_4000000 << 8);
1577 }
1578
1579
1580 self->qos.min_turn_time.bits = 0xff;
1581
1582 irda_qos_bits_to_value (&self->qos);
1583
1584
1585 self->ringbuf = kmalloc(OBOE_RING_LEN << 1, GFP_KERNEL);
1586 if (!self->ringbuf)
1587 {
1588 err = -ENOMEM;
1589 goto freeregion;
1590 }
1591
1592#if (BITS_PER_LONG == 64)
1593#error broken on 64-bit: casts pointer to 32-bit, and then back to pointer.
1594#endif
1595
1596
1597 {
1598 unsigned long addr;
1599
1600 addr = (__u32) self->ringbuf;
1601 addr &= ~(OBOE_RING_LEN - 1);
1602 addr += OBOE_RING_LEN;
1603 self->ring = (struct OboeRing *) addr;
1604 }
1605
1606 memset (self->ring, 0, OBOE_RING_LEN);
1607 self->io.mem_base = (__u32) self->ring;
1608
1609 ok = 1;
1610 for (i = 0; i < TX_SLOTS; ++i)
1611 {
1612 self->tx_bufs[i] = kmalloc (TX_BUF_SZ, GFP_KERNEL);
1613 if (!self->tx_bufs[i])
1614 ok = 0;
1615 }
1616
1617 for (i = 0; i < RX_SLOTS; ++i)
1618 {
1619 self->rx_bufs[i] = kmalloc (RX_BUF_SZ, GFP_KERNEL);
1620 if (!self->rx_bufs[i])
1621 ok = 0;
1622 }
1623
1624 if (!ok)
1625 {
1626 err = -ENOMEM;
1627 goto freebufs;
1628 }
1629
1630
1631#ifdef USE_PROBE
1632 if (do_probe)
1633 if (!toshoboe_probe (self))
1634 {
1635 err = -ENODEV;
1636 goto freebufs;
1637 }
1638#endif
1639
1640 SET_NETDEV_DEV(dev, &pci_dev->dev);
1641 dev->netdev_ops = &toshoboe_netdev_ops;
1642
1643 err = register_netdev(dev);
1644 if (err)
1645 {
1646 printk (KERN_ERR DRIVER_NAME ": register_netdev() failed\n");
1647 err = -ENOMEM;
1648 goto freebufs;
1649 }
1650 printk (KERN_INFO "IrDA: Registered device %s\n", dev->name);
1651
1652 pci_set_drvdata(pci_dev,self);
1653
1654 printk (KERN_INFO DRIVER_NAME ": Using multiple tasks\n");
1655
1656 return 0;
1657
1658freebufs:
1659 for (i = 0; i < TX_SLOTS; ++i)
1660 kfree (self->tx_bufs[i]);
1661 for (i = 0; i < RX_SLOTS; ++i)
1662 kfree (self->rx_bufs[i]);
1663 kfree(self->ringbuf);
1664
1665freeregion:
1666 release_region (self->io.fir_base, self->io.fir_ext);
1667
1668freeself:
1669 free_netdev(dev);
1670
1671 return err;
1672}
1673
1674static int
1675toshoboe_gotosleep (struct pci_dev *pci_dev, pm_message_t crap)
1676{
1677 struct toshoboe_cb *self = pci_get_drvdata(pci_dev);
1678 unsigned long flags;
1679 int i = 10;
1680
1681 if (!self || self->stopped)
1682 return 0;
1683
1684 if ((!self->irdad) && (!self->async))
1685 return 0;
1686
1687
1688 while ((i--) && (self->txpending))
1689 msleep(10);
1690
1691 spin_lock_irqsave(&self->spinlock, flags);
1692
1693 toshoboe_stopchip (self);
1694 self->stopped = 1;
1695 self->txpending = 0;
1696
1697 spin_unlock_irqrestore(&self->spinlock, flags);
1698 return 0;
1699}
1700
1701static int
1702toshoboe_wakeup (struct pci_dev *pci_dev)
1703{
1704 struct toshoboe_cb *self = pci_get_drvdata(pci_dev);
1705 unsigned long flags;
1706
1707 if (!self || !self->stopped)
1708 return 0;
1709
1710 if ((!self->irdad) && (!self->async))
1711 return 0;
1712
1713 spin_lock_irqsave(&self->spinlock, flags);
1714
1715 toshoboe_startchip (self);
1716 self->stopped = 0;
1717
1718 netif_wake_queue(self->netdev);
1719 spin_unlock_irqrestore(&self->spinlock, flags);
1720 return 0;
1721}
1722
1723static struct pci_driver donauboe_pci_driver = {
1724 .name = "donauboe",
1725 .id_table = toshoboe_pci_tbl,
1726 .probe = toshoboe_open,
1727 .remove = toshoboe_close,
1728 .suspend = toshoboe_gotosleep,
1729 .resume = toshoboe_wakeup
1730};
1731
1732module_pci_driver(donauboe_pci_driver);
1733