1 /*********************************************************************
2  *
3  * Filename:      toshoboe.c
4  * Version:       0.1
5  * Description:   Driver for the Toshiba OBOE (or type-O or 700 or 701)
6  *                FIR Chipset.
7  * Status:        Experimental.
8  * Author:        James McKenzie <james@fishsoup.dhs.org>
9  * Created at:    Sat May 8  12:35:27 1999
10  * Modified:      Paul Bristow <paul.bristow@technologist.com>
11  * Modified:      Mon Nov 11 19:10:05 1999
12  *
13  *     Copyright (c) 1999-2000 James McKenzie, All Rights Reserved.
14  *
15  *     This program is free software; you can redistribute it and/or
16  *     modify it under the terms of the GNU General Public License as
17  *     published by the Free Software Foundation; either version 2 of
18  *     the License, or (at your option) any later version.
19  *
20  *     Neither James McKenzie nor Cambridge University admit liability nor
21  *     provide warranty for any of this software. This material is
22  *     provided "AS-IS" and at no charge.
23  *
24  *     Applicable Models : Libretto 100CT. and many more
25  *     Toshiba refers to this chip as the type-O IR port.
26  *
27  ********************************************************************/
28 
29 /* This driver is experimental, I have only three ir devices */
30 /* an olivetti notebook which doesn't have FIR, a toshiba libretto, and */
31 /* an hp printer, this works fine at 4MBPS with my HP printer */
32 
33 static char *rcsid = "$Id: toshoboe.c,v 1.91 1999/06/29 14:21:06 root Exp $";
34 
35 /* Define this to have only one frame in the XMIT or RECV queue */
36 /* Toshiba's drivers do this, but it disables back to back tansfers */
37 /* I think that the chip may have some problems certainly, I have */
38 /* seen it jump over tasks in the taskfile->xmit with this turned on */
39 #define ONETASK
40 
41 /* To adjust the number of tasks in use edit toshoboe.h */
42 
43 /* Define this to enable FIR and MIR support */
44 #define ENABLE_FAST
45 
46 /* Size of IO window */
47 #define CHIP_IO_EXTENT	0x1f
48 
49 /* Transmit and receive buffer sizes, adjust at your peril */
50 #define RX_BUF_SZ 	4196
51 #define TX_BUF_SZ	4196
52 
53 /* No user servicable parts below here */
54 
55 #include <linux/module.h>
56 #include <linux/kernel.h>
57 #include <linux/types.h>
58 #include <linux/skbuff.h>
59 #include <linux/netdevice.h>
60 #include <linux/ioport.h>
61 #include <linux/delay.h>
62 #include <linux/slab.h>
63 #include <linux/init.h>
64 #include <linux/pci.h>
65 #include <linux/rtnetlink.h>
66 
67 #include <asm/system.h>
68 #include <asm/io.h>
69 
70 #include <net/irda/wrapper.h>
71 #include <net/irda/irda.h>
72 #include <net/irda/irmod.h>
73 #include <net/irda/irlap_frame.h>
74 #include <net/irda/irda_device.h>
75 
76 #include <linux/pm.h>
77 
78 #include <net/irda/toshoboe.h>
79 
80 #define PCI_DEVICE_ID_FIR701b  0x0d01
81 
82 static struct pci_device_id toshoboe_pci_tbl[] __initdata = {
83 	{ PCI_VENDOR_ID_TOSHIBA, PCI_DEVICE_ID_FIR701, PCI_ANY_ID, PCI_ANY_ID, },
84 	{ PCI_VENDOR_ID_TOSHIBA, PCI_DEVICE_ID_FIR701b, PCI_ANY_ID, PCI_ANY_ID, },
85 	{ }			/* Terminating entry */
86 };
87 MODULE_DEVICE_TABLE(pci, toshoboe_pci_tbl);
88 
89 static const char *driver_name = "toshoboe";
90 
91 static int max_baud = 4000000;
92 
93 /* Shutdown the chip and point the taskfile reg somewhere else */
94 static void
toshoboe_stopchip(struct toshoboe_cb * self)95 toshoboe_stopchip (struct toshoboe_cb *self)
96 {
97   IRDA_DEBUG (4, "%s()\n", __FUNCTION__);
98 
99   outb_p (0x0e, OBOE_REG_11);
100 
101   outb_p (0x00, OBOE_RST);
102   outb_p (0x3f, OBOE_TFP2);     /*Write the taskfile address */
103   outb_p (0xff, OBOE_TFP1);
104   outb_p (0xff, OBOE_TFP0);
105   outb_p (0x0f, OBOE_REG_1B);
106   outb_p (0xff, OBOE_REG_1A);
107   outb_p (0x00, OBOE_ISR);      /*FIXME: should i do this to disbale ints */
108   outb_p (0x80, OBOE_RST);
109   outb_p (0xe, OBOE_LOCK);
110 
111 }
112 
113 /*Set the baud rate */
114 static void
toshoboe_setbaud(struct toshoboe_cb * self,int baud)115 toshoboe_setbaud (struct toshoboe_cb *self, int baud)
116 {
117   unsigned long flags;
118   IRDA_DEBUG (4, "%s()\n", __FUNCTION__);
119 
120   printk (KERN_WARNING "ToshOboe: setting baud to %d\n", baud);
121 
122   save_flags (flags);
123   cli ();
124   switch (baud)
125     {
126     case 2400:
127       outb_p (OBOE_PMDL_SIR, OBOE_PMDL);
128       outb_p (OBOE_SMDL_SIR, OBOE_SMDL);
129       outb_p (0xbf, OBOE_UDIV);
130       break;
131     case 4800:
132       outb_p (OBOE_PMDL_SIR, OBOE_PMDL);
133       outb_p (OBOE_SMDL_SIR, OBOE_SMDL);
134       outb_p (0x5f, OBOE_UDIV);
135       break;
136     case 9600:
137       outb_p (OBOE_PMDL_SIR, OBOE_PMDL);
138       outb_p (OBOE_SMDL_SIR, OBOE_SMDL);
139       outb_p (0x2f, OBOE_UDIV);
140       break;
141     case 19200:
142       outb_p (OBOE_PMDL_SIR, OBOE_PMDL);
143       outb_p (OBOE_SMDL_SIR, OBOE_SMDL);
144       outb_p (0x17, OBOE_UDIV);
145       break;
146     case 38400:
147       outb_p (OBOE_PMDL_SIR, OBOE_PMDL);
148       outb_p (OBOE_SMDL_SIR, OBOE_SMDL);
149       outb_p (0xb, OBOE_UDIV);
150       break;
151     case 57600:
152       outb_p (OBOE_PMDL_SIR, OBOE_PMDL);
153       outb_p (OBOE_SMDL_SIR, OBOE_SMDL);
154       outb_p (0x7, OBOE_UDIV);
155       break;
156     case 115200:
157       outb_p (OBOE_PMDL_SIR, OBOE_PMDL);
158       outb_p (OBOE_SMDL_SIR, OBOE_SMDL);
159       outb_p (0x3, OBOE_UDIV);
160       break;
161     case 1152000:
162       outb_p (OBOE_PMDL_MIR, OBOE_PMDL);
163       outb_p (OBOE_SMDL_MIR, OBOE_SMDL);
164       outb_p (0x1, OBOE_UDIV);
165       break;
166     case 4000000:
167       outb_p (OBOE_PMDL_FIR, OBOE_PMDL);
168       outb_p (OBOE_SMDL_FIR, OBOE_SMDL);
169       outb_p (0x0, OBOE_UDIV);
170       break;
171     }
172 
173   restore_flags (flags);
174 
175   outb_p (0x00, OBOE_RST);
176   outb_p (0x80, OBOE_RST);
177   outb_p (0x01, OBOE_REG_9);
178 
179   self->io.speed = baud;
180 }
181 
182 /* Wake the chip up and get it looking at the taskfile */
183 static void
toshoboe_startchip(struct toshoboe_cb * self)184 toshoboe_startchip (struct toshoboe_cb *self)
185 {
186   __u32 physaddr;
187 
188   IRDA_DEBUG (4, "%s()\n", __FUNCTION__);
189 
190 
191   outb_p (0, OBOE_LOCK);
192   outb_p (0, OBOE_RST);
193   outb_p (OBOE_NTR_VAL, OBOE_NTR);
194   outb_p (0xf0, OBOE_REG_D);
195   outb_p (0xff, OBOE_ISR);
196   outb_p (0x0f, OBOE_REG_1B);
197   outb_p (0xff, OBOE_REG_1A);
198 
199 
200   physaddr = virt_to_bus (self->taskfile);
201 
202   outb_p ((physaddr >> 0x0a) & 0xff, OBOE_TFP0);
203   outb_p ((physaddr >> 0x12) & 0xff, OBOE_TFP1);
204   outb_p ((physaddr >> 0x1a) & 0x3f, OBOE_TFP2);
205 
206   outb_p (0x0e, OBOE_REG_11);
207   outb_p (0x80, OBOE_RST);
208 
209   toshoboe_setbaud (self, 9600);
210 
211 }
212 
213 /*Let the chip look at memory */
214 static void
toshoboe_enablebm(struct toshoboe_cb * self)215 toshoboe_enablebm (struct toshoboe_cb *self)
216 {
217   IRDA_DEBUG (4, "%s()\n", __FUNCTION__);
218   pci_set_master (self->pdev);
219 }
220 
221 /*Don't let the chip look at memory */
222 static void
toshoboe_disablebm(struct toshoboe_cb * self)223 toshoboe_disablebm (struct toshoboe_cb *self)
224 {
225   __u8 command;
226   IRDA_DEBUG (4, "%s()\n", __FUNCTION__);
227 
228   pci_read_config_byte (self->pdev, PCI_COMMAND, &command);
229   command &= ~PCI_COMMAND_MASTER;
230   pci_write_config_byte (self->pdev, PCI_COMMAND, command);
231 
232 }
233 
234 /*setup the taskfile */
235 static void
toshoboe_initbuffs(struct toshoboe_cb * self)236 toshoboe_initbuffs (struct toshoboe_cb *self)
237 {
238   int i;
239   unsigned long flags;
240 
241   IRDA_DEBUG (4, "%s()\n", __FUNCTION__);
242 
243   save_flags (flags);
244   cli ();
245 
246   for (i = 0; i < TX_SLOTS; ++i)
247     {
248       self->taskfile->xmit[i].len = 0;
249       self->taskfile->xmit[i].control = 0x00;
250       self->taskfile->xmit[i].buffer = virt_to_bus (self->xmit_bufs[i]);
251     }
252 
253   for (i = 0; i < RX_SLOTS; ++i)
254     {
255       self->taskfile->recv[i].len = 0;
256       self->taskfile->recv[i].control = 0x83;
257       self->taskfile->recv[i].buffer = virt_to_bus (self->recv_bufs[i]);
258     }
259 
260   restore_flags (flags);
261 }
262 
263 /*Transmit something */
264 static int
toshoboe_hard_xmit(struct sk_buff * skb,struct net_device * dev)265 toshoboe_hard_xmit (struct sk_buff *skb, struct net_device *dev)
266 {
267   struct toshoboe_cb *self;
268   __s32 speed;
269   int mtt, len;
270 
271   self = (struct toshoboe_cb *) dev->priv;
272 
273   ASSERT (self != NULL, return 0;
274     );
275 
276   /* Check if we need to change the speed */
277   speed = irda_get_next_speed(skb);
278   if ((speed != self->io.speed) && (speed != -1)) {
279 	/* Check for empty frame */
280 	if (!skb->len) {
281 	    toshoboe_setbaud(self, speed);
282 	    dev_kfree_skb(skb);
283 	    return 0;
284 	} else
285 	    self->new_speed = speed;
286   }
287 
288   netif_stop_queue(dev);
289 
290   if (self->stopped) {
291 	  dev_kfree_skb(skb);
292     return 0;
293   }
294 
295 #ifdef ONETASK
296   if (self->txpending)
297     return -EBUSY;
298 
299   self->txs = inb_p (OBOE_XMTT) - OBOE_XMTT_OFFSET;
300 
301   self->txs &= 0x3f;
302 
303 #endif
304 
305   if (self->taskfile->xmit[self->txs].control)
306     return -EBUSY;
307 
308 
309   if (inb_p (OBOE_RST) & OBOE_RST_WRAP)
310     {
311       len = async_wrap_skb (skb, self->xmit_bufs[self->txs], TX_BUF_SZ);
312     }
313   else
314     {
315       len = skb->len;
316       memcpy (self->xmit_bufs[self->txs], skb->data, len);
317     }
318   self->taskfile->xmit[self->txs].len = len & 0x0fff;
319 
320 
321 
322   outb_p (0, OBOE_RST);
323   outb_p (0x1e, OBOE_REG_11);
324 
325   self->taskfile->xmit[self->txs].control = 0x84;
326 
327   mtt = irda_get_mtt (skb);
328   if (mtt)
329     udelay (mtt);
330 
331   self->txpending++;
332 
333   /*FIXME: ask about busy,media_busy stuff, for the moment */
334   /*busy means can't queue any more */
335 #ifndef ONETASK
336   if (self->txpending != TX_SLOTS)
337   {
338   	netif_wake_queue(dev);
339   }
340 #endif
341 
342   outb_p (0x80, OBOE_RST);
343   outb_p (1, OBOE_REG_9);
344 
345   self->txs++;
346   self->txs %= TX_SLOTS;
347 
348   dev_kfree_skb (skb);
349 
350   return 0;
351 }
352 
353 /*interrupt handler */
354 static void
toshoboe_interrupt(int irq,void * dev_id,struct pt_regs * regs)355 toshoboe_interrupt (int irq, void *dev_id, struct pt_regs *regs)
356 {
357   struct toshoboe_cb *self = (struct toshoboe_cb *) dev_id;
358   __u8 irqstat;
359   struct sk_buff *skb;
360 
361   if (self == NULL)
362     {
363       printk (KERN_WARNING "%s: irq %d for unknown device.\n",
364               driver_name, irq);
365       return;
366     }
367 
368   IRDA_DEBUG (4, "%s()\n", __FUNCTION__);
369 
370   irqstat = inb_p (OBOE_ISR);
371 
372 /* woz it us */
373   if (!(irqstat & 0xf8))
374     return;
375 
376   outb_p (irqstat, OBOE_ISR);   /*Acknologede it */
377 
378 
379 /* Txdone */
380   if (irqstat & OBOE_ISR_TXDONE)
381     {
382       self->txpending--;
383 
384       self->stats.tx_packets++;
385 
386       if (self->new_speed) {
387 	      toshoboe_setbaud(self, self->new_speed);
388 
389 	      self->new_speed = 0;
390       }
391       /* Tell network layer that we want more frames */
392       netif_wake_queue(self->netdev);
393     }
394 
395   if (irqstat & OBOE_ISR_RXDONE)
396     {
397 
398 #ifdef ONETASK
399       self->rxs = inb_p (OBOE_RCVT);
400       self->rxs += (RX_SLOTS - 1);
401       self->rxs %= RX_SLOTS;
402 #else
403       while (self->taskfile->recv[self->rxs].control == 0)
404 #endif
405         {
406           int len = self->taskfile->recv[self->rxs].len;
407 
408           if (len > 2)
409             len -= 2;
410 
411           skb = dev_alloc_skb (len + 1);
412           if (skb)
413             {
414               skb_reserve (skb, 1);
415 
416               skb_put (skb, len);
417               memcpy (skb->data, self->recv_bufs[self->rxs], len);
418 
419               self->stats.rx_packets++;
420               skb->dev = self->netdev;
421               skb->mac.raw = skb->data;
422               skb->protocol = htons (ETH_P_IRDA);
423             }
424           else
425             {
426               printk (KERN_INFO "%s(), memory squeeze, dropping frame.\n", __FUNCTION__);
427             }
428 
429           self->taskfile->recv[self->rxs].control = 0x83;
430           self->taskfile->recv[self->rxs].len = 0x0;
431 
432           self->rxs++;
433           self->rxs %= RX_SLOTS;
434 
435           if (skb)
436             netif_rx (skb);
437 
438         }
439 
440     }
441 
442   if (irqstat & OBOE_ISR_20)
443     {
444       printk (KERN_WARNING "Oboe_irq: 20\n");
445     }
446   if (irqstat & OBOE_ISR_10)
447     {
448       printk (KERN_WARNING "Oboe_irq: 10\n");
449     }
450   if (irqstat & 0x8)
451     {
452       /*FIXME: I think this is a TX or RX error of some sort */
453 
454       self->stats.tx_errors++;
455       self->stats.rx_errors++;
456 
457     }
458 
459 
460 }
461 
462 static int
toshoboe_net_init(struct net_device * dev)463 toshoboe_net_init (struct net_device *dev)
464 {
465   IRDA_DEBUG (4, "%s()\n", __FUNCTION__);
466 
467   /* Setup to be a normal IrDA network device driver */
468   irda_device_setup (dev);
469 
470   /* Insert overrides below this line! */
471   return 0;
472 }
473 
474 
475 static void
toshoboe_initptrs(struct toshoboe_cb * self)476 toshoboe_initptrs (struct toshoboe_cb *self)
477 {
478 
479   unsigned long flags;
480   save_flags (flags);
481   cli ();
482 
483   /*FIXME: need to test this carefully to check which one */
484   /*of the two possible startup logics the chip uses */
485   /*although it won't make any difference if no-one xmits durining init */
486   /*and none what soever if using ONETASK */
487 
488   self->rxs = inb_p (OBOE_RCVT);
489   self->txs = inb_p (OBOE_XMTT) - OBOE_XMTT_OFFSET;
490 
491 #if 0
492   self->rxs = 0;
493   self->txs = 0;
494 #endif
495 #if 0
496   self->rxs = RX_SLOTS - 1;
497   self->txs = 0;
498 #endif
499 
500 
501   self->txpending = 0;
502 
503   restore_flags (flags);
504 
505 }
506 
507 
508 static int
toshoboe_net_open(struct net_device * dev)509 toshoboe_net_open (struct net_device *dev)
510 {
511   struct toshoboe_cb *self;
512   char hwname[32];
513 
514   IRDA_DEBUG (4, "%s()\n", __FUNCTION__);
515 
516   ASSERT (dev != NULL, return -1;
517     );
518   self = (struct toshoboe_cb *) dev->priv;
519 
520   ASSERT (self != NULL, return 0;
521     );
522 
523   if (self->stopped)
524     return 0;
525 
526   if (request_irq (self->io.irq, toshoboe_interrupt,
527                    SA_SHIRQ | SA_INTERRUPT, dev->name, (void *) self))
528     {
529 
530       return -EAGAIN;
531     }
532 
533   toshoboe_initbuffs (self);
534   toshoboe_enablebm (self);
535   toshoboe_startchip (self);
536   toshoboe_initptrs (self);
537 
538   /* Ready to play! */
539   netif_start_queue(dev);
540   /* Give self a hardware name */
541   sprintf(hwname, "Toshiba-FIR @ 0x%03x", self->base);
542   /*
543    * Open new IrLAP layer instance, now that everything should be
544    * initialized properly
545    */
546   self->irlap = irlap_open(dev, &self->qos, hwname);
547 
548   self->open = 1;
549 
550   MOD_INC_USE_COUNT;
551 
552   return 0;
553 
554 }
555 
556 static int
toshoboe_net_close(struct net_device * dev)557 toshoboe_net_close (struct net_device *dev)
558 {
559   struct toshoboe_cb *self;
560 
561   IRDA_DEBUG (4, "%s()\n", __FUNCTION__);
562 
563   ASSERT (dev != NULL, return -1;
564     );
565   self = (struct toshoboe_cb *) dev->priv;
566 
567   /* Stop device */
568   netif_stop_queue(dev);
569 
570   /* Stop and remove instance of IrLAP */
571   if (self->irlap)
572 	  irlap_close(self->irlap);
573   self->irlap = NULL;
574 
575   self->open = 0;
576 
577   free_irq (self->io.irq, (void *) self);
578 
579   if (!self->stopped)
580     {
581       toshoboe_stopchip (self);
582       toshoboe_disablebm (self);
583     }
584 
585   MOD_DEC_USE_COUNT;
586 
587   return 0;
588 
589 }
590 
591 /*
592  * Function toshoboe_net_ioctl (dev, rq, cmd)
593  *
594  *    Process IOCTL commands for this device
595  *
596  */
toshoboe_net_ioctl(struct net_device * dev,struct ifreq * rq,int cmd)597 static int toshoboe_net_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
598 {
599 	struct if_irda_req *irq = (struct if_irda_req *) rq;
600 	struct toshoboe_cb *self;
601 	unsigned long flags;
602 	int ret = 0;
603 
604 	ASSERT(dev != NULL, return -1;);
605 
606 	self = dev->priv;
607 
608 	ASSERT(self != NULL, return -1;);
609 
610 	IRDA_DEBUG(2, "%s(), %s, (cmd=0x%X)\n", __FUNCTION__, dev->name, cmd);
611 
612 	/* Disable interrupts & save flags */
613 	save_flags(flags);
614 	cli();
615 	switch (cmd) {
616 	case SIOCSBANDWIDTH: /* Set bandwidth */
617 		if (!capable(CAP_NET_ADMIN)) {
618 			ret = -EPERM;
619 			goto out;
620 		}
621 		/* toshoboe_setbaud(self, irq->ifr_baudrate); */
622                 /* Just change speed once - inserted by Paul Bristow */
623 	        self->new_speed = irq->ifr_baudrate;
624 		break;
625 	case SIOCSMEDIABUSY: /* Set media busy */
626 		if (!capable(CAP_NET_ADMIN)) {
627 			ret = -EPERM;
628 			goto out;
629 		}
630 		irda_device_set_media_busy(self->netdev, TRUE);
631 		break;
632 	case SIOCGRECEIVING: /* Check if we are receiving right now */
633 		irq->ifr_receiving = 0; /* Can't tell */
634 		break;
635 	default:
636 		ret = -EOPNOTSUPP;
637 	}
638 out:
639 	restore_flags(flags);
640 	return ret;
641 }
642 
643 MODULE_DESCRIPTION("Toshiba OBOE IrDA Device Driver");
644 MODULE_AUTHOR("James McKenzie <james@fishsoup.dhs.org>");
645 MODULE_LICENSE("GPL");
646 
647 MODULE_PARM (max_baud, "i");
648 MODULE_PARM_DESC(max_baus, "Maximum baud rate");
649 
650 static void
toshoboe_remove(struct pci_dev * pci_dev)651 toshoboe_remove (struct pci_dev *pci_dev)
652 {
653   int i;
654   struct toshoboe_cb *self = (struct toshoboe_cb*)pci_get_drvdata(pci_dev);
655 
656   IRDA_DEBUG (4, "%s()\n", __FUNCTION__);
657 
658   ASSERT (self != NULL, return;
659     );
660 
661   if (!self->stopped)
662     {
663       toshoboe_stopchip (self);
664       toshoboe_disablebm (self);
665     }
666 
667   release_region (self->io.sir_base, self->io.sir_ext);
668 
669 
670   for (i = 0; i < TX_SLOTS; ++i)
671     {
672       kfree (self->xmit_bufs[i]);
673       self->xmit_bufs[i] = NULL;
674     }
675 
676   for (i = 0; i < RX_SLOTS; ++i)
677     {
678       kfree (self->recv_bufs[i]);
679       self->recv_bufs[i] = NULL;
680     }
681 
682   if (self->netdev) {
683 	  /* Remove netdevice */
684 	  rtnl_lock();
685 	  unregister_netdevice(self->netdev);
686 	  rtnl_unlock();
687   }
688 
689   kfree (self->taskfilebuf);
690   self->taskfilebuf = NULL;
691   self->taskfile = NULL;
692 
693   return;
694 
695 }
696 
697 static int
toshoboe_probe(struct pci_dev * pci_dev,const struct pci_device_id * pdid)698 toshoboe_probe (struct pci_dev *pci_dev, const struct pci_device_id *pdid)
699 {
700   struct toshoboe_cb *self;
701   struct net_device *dev;
702   int i = 0;
703   int ok = 0;
704   int err;
705 
706   IRDA_DEBUG (4, "%s()\n", __FUNCTION__);
707 
708   if ((err=pci_enable_device(pci_dev)))
709 	  return err;
710 
711   self = kmalloc (sizeof (struct toshoboe_cb), GFP_KERNEL);
712 
713   if (self == NULL)
714     {
715       printk (KERN_ERR "IrDA: Can't allocate memory for "
716               "IrDA control block!\n");
717       return -ENOMEM;
718     }
719 
720   memset (self, 0, sizeof (struct toshoboe_cb));
721 
722   self->open = 0;
723   self->stopped = 0;
724   self->pdev = pci_dev;
725   self->base = pci_resource_start(pci_dev,0);
726 
727   self->io.sir_base = self->base;
728   self->io.irq = pci_dev->irq;
729   self->io.sir_ext = CHIP_IO_EXTENT;
730   self->io.speed = 9600;
731 
732   /* Lock the port that we need */
733   if (NULL==request_region (self->io.sir_base, self->io.sir_ext, driver_name))
734     {
735       IRDA_DEBUG (0, "%s(), can't get iobase of 0x%03x\n",
736       	__FUNCTION__, self->io.sir_base);
737 
738       err = -EBUSY;
739       goto freeself;
740     }
741 
742   irda_init_max_qos_capabilies (&self->qos);
743   self->qos.baud_rate.bits = 0;
744 
745   if (max_baud >= 2400)
746     self->qos.baud_rate.bits |= IR_2400;
747   /*if (max_baud>=4800) idev->qos.baud_rate.bits|=IR_4800; */
748   if (max_baud >= 9600)
749     self->qos.baud_rate.bits |= IR_9600;
750   if (max_baud >= 19200)
751     self->qos.baud_rate.bits |= IR_19200;
752   if (max_baud >= 115200)
753     self->qos.baud_rate.bits |= IR_115200;
754 #ifdef ENABLE_FAST
755   if (max_baud >= 576000)
756     self->qos.baud_rate.bits |= IR_576000;
757   if (max_baud >= 1152000)
758     self->qos.baud_rate.bits |= IR_1152000;
759   if (max_baud >= 4000000)
760     self->qos.baud_rate.bits |= (IR_4000000 << 8);
761 #endif
762 
763 
764   self->qos.min_turn_time.bits = 0xff;  /*FIXME: what does this do? */
765 
766   irda_qos_bits_to_value (&self->qos);
767 
768   self->flags = IFF_SIR | IFF_DMA | IFF_PIO;
769 
770 #ifdef ENABLE_FAST
771   if (max_baud >= 576000)
772     self->flags |= IFF_FIR;
773 #endif
774 
775   /* Now setup the endless buffers we need */
776 
777   self->txs = 0;
778   self->rxs = 0;
779 
780   self->taskfilebuf = kmalloc (OBOE_TASK_BUF_LEN, GFP_KERNEL);
781   if (!self->taskfilebuf)
782     {
783       printk (KERN_ERR "toshoboe: kmalloc for DMA failed()\n");
784       err = -ENOMEM;
785       goto freeregion;
786     }
787 
788 
789   memset (self->taskfilebuf, 0, OBOE_TASK_BUF_LEN);
790 
791   /*We need to align the taskfile on a taskfile size boundary */
792   {
793     __u32 addr;
794 
795     addr = (__u32) self->taskfilebuf;
796     addr &= ~(sizeof (struct OboeTaskFile) - 1);
797     addr += sizeof (struct OboeTaskFile);
798 
799     self->taskfile = (struct OboeTaskFile *) addr;
800   }
801 
802   for (i = 0; i < TX_SLOTS; ++i)
803     {
804       self->xmit_bufs[i] = kmalloc (TX_BUF_SZ, GFP_KERNEL | GFP_DMA);
805       if (self->xmit_bufs[i])
806         ok++;
807     }
808 
809   for (i = 0; i < RX_SLOTS; ++i)
810     {
811       self->recv_bufs[i] = kmalloc (TX_BUF_SZ, GFP_KERNEL | GFP_DMA);
812       if (self->recv_bufs[i])
813         ok++;
814     }
815 
816   if (ok != RX_SLOTS + TX_SLOTS)
817     {
818       printk (KERN_ERR "toshoboe: kmalloc for buffers failed()\n");
819       err = -ENOMEM;
820       goto freebufs;
821 
822   }
823 
824 
825   if (!(dev = dev_alloc("irda%d", &err))) {
826       ERROR("%s(), dev_alloc() failed!\n", __FUNCTION__);
827       err = -ENOMEM;
828       goto freebufs;
829   }
830   dev->priv = (void *) self;
831   self->netdev = dev;
832 
833   MESSAGE("IrDA: Registered device %s\n", dev->name);
834 
835   dev->init = toshoboe_net_init;
836   dev->hard_start_xmit = toshoboe_hard_xmit;
837   dev->open = toshoboe_net_open;
838   dev->stop = toshoboe_net_close;
839   dev->do_ioctl = toshoboe_net_ioctl;
840 
841   rtnl_lock();
842   err = register_netdevice(dev);
843   rtnl_unlock();
844   if (err) {
845 	  ERROR("%s(), register_netdev() failed!\n", __FUNCTION__);
846 	  /* XXX there is not freeing for dev? */
847           goto freebufs;
848   }
849   pci_set_drvdata(pci_dev,self);
850 
851   printk (KERN_WARNING "ToshOboe: Using ");
852 #ifdef ONETASK
853   printk ("single");
854 #else
855   printk ("multiple");
856 #endif
857   printk (" tasks, version %s\n", rcsid);
858 
859   return (0);
860 freebufs:
861       for (i = 0; i < TX_SLOTS; ++i)
862         if (self->xmit_bufs[i])
863           kfree (self->xmit_bufs[i]);
864       for (i = 0; i < RX_SLOTS; ++i)
865         if (self->recv_bufs[i])
866           kfree (self->recv_bufs[i]);
867       kfree(self->taskfilebuf);
868 freeregion:
869       release_region (self->io.sir_base, self->io.sir_ext);
870 freeself:
871       kfree (self);
872       return err;
873 }
874 
875 static int
toshoboe_suspend(struct pci_dev * pci_dev,u32 crap)876 toshoboe_suspend (struct pci_dev *pci_dev, u32 crap)
877 {
878   int i = 10;
879   struct toshoboe_cb *self = (struct toshoboe_cb*)pci_get_drvdata(pci_dev);
880 
881   printk (KERN_WARNING "ToshOboe: suspending\n");
882 
883   if (!self || self->stopped)
884     return 0;
885 
886   self->stopped = 1;
887 
888   if (!self->open)
889     return 0;
890 
891 /*FIXME: can't sleep here wait one second */
892 
893   while ((i--) && (self->txpending))
894     udelay (100);
895 
896   toshoboe_stopchip (self);
897   toshoboe_disablebm (self);
898 
899   self->txpending = 0;
900   return 0;
901 }
902 
903 
904 static int
toshoboe_resume(struct pci_dev * pci_dev)905 toshoboe_resume (struct pci_dev *pci_dev)
906 {
907   struct toshoboe_cb *self = (struct toshoboe_cb*)pci_get_drvdata(pci_dev);
908   unsigned long flags;
909 
910   if (!self)
911     return 0;
912 
913   if (!self->stopped)
914     return 0;
915 
916   if (!self->open)
917     {
918       self->stopped = 0;
919       return 0;
920     }
921 
922   save_flags (flags);
923   cli ();
924 
925   toshoboe_initbuffs (self);
926   toshoboe_enablebm (self);
927   toshoboe_startchip (self);
928 
929   toshoboe_setbaud (self, self->io.speed);
930 
931   toshoboe_initptrs (self);
932 
933   netif_wake_queue(self->netdev);
934   restore_flags (flags);
935   printk (KERN_WARNING "ToshOboe: waking up\n");
936   return 0;
937 }
938 
939 static struct pci_driver toshoboe_pci_driver = {
940   name		: "toshoboe",
941   id_table	: toshoboe_pci_tbl,
942   probe		: toshoboe_probe,
943   remove	: toshoboe_remove,
944   suspend	: toshoboe_suspend,
945   resume	: toshoboe_resume
946 };
947 
948 int __init
toshoboe_init(void)949 toshoboe_init (void)
950 {
951   return pci_module_init(&toshoboe_pci_driver);
952 }
953 
954 void
toshoboe_cleanup(void)955 toshoboe_cleanup (void)
956 {
957   pci_unregister_driver(&toshoboe_pci_driver);
958 }
959 
960 module_init(toshoboe_init);
961 module_exit(toshoboe_cleanup);
962