~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~ [ freetext search ] ~ [ file search ] ~

Linux Cross Reference
Linux/drivers/net/irda/toshoboe.c

Version: ~ [ 2.2.5 ] ~ [ 2.4.1 ] ~ [ 2.4.9 ] ~ [ 2.6.17.10 ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

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

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~ [ freetext search ] ~ [ file search ] ~

This page was automatically generated by the LXR engine.
Visit the LXR main site for more information.