toshoboe.c
上传用户:jlfgdled
上传日期:2013-04-10
资源大小:33168k
文件大小:21k
源码类别:

Linux/Unix编程

开发平台:

Unix_Linux

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