⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 toshoboe.c

📁 内核linux2.4.20,可跟rtlinux3.2打补丁 组成实时linux系统,编译内核
💻 C
📖 第 1 页 / 共 2 页
字号:
/********************************************************************* *                 * Filename:      toshoboe.c * Version:       0.1 * Description:   Driver for the Toshiba OBOE (or type-O or 700 or 701) *                FIR Chipset.  * Status:        Experimental. * Author:        James McKenzie <james@fishsoup.dhs.org> * Created at:    Sat May 8  12:35:27 1999 * Modified:      Paul Bristow <paul.bristow@technologist.com> * Modified:      Mon Nov 11 19:10:05 1999 *  *     Copyright (c) 1999-2000 James McKenzie, All Rights Reserved. *       *     This program is free software; you can redistribute it and/or  *     modify it under the terms of the GNU General Public License as  *     published by the Free Software Foundation; either version 2 of  *     the License, or (at your option) any later version. *   *     Neither James McKenzie nor Cambridge University admit liability nor *     provide warranty for any of this software. This material is  *     provided "AS-IS" and at no charge. * *     Applicable Models : Libretto 100CT. and many more *     Toshiba refers to this chip as the type-O IR port. * ********************************************************************//* This driver is experimental, I have only three ir devices *//* an olivetti notebook which doesn't have FIR, a toshiba libretto, and *//* an hp printer, this works fine at 4MBPS with my HP printer */static char *rcsid = "$Id: toshoboe.c,v 1.91 1999/06/29 14:21:06 root Exp $";/* Define this to have only one frame in the XMIT or RECV queue *//* Toshiba's drivers do this, but it disables back to back tansfers *//* I think that the chip may have some problems certainly, I have *//* seen it jump over tasks in the taskfile->xmit with this turned on */#define ONETASK /* To adjust the number of tasks in use edit toshoboe.h *//* Define this to enable FIR and MIR support */#define ENABLE_FAST/* Size of IO window */#define CHIP_IO_EXTENT	0x1f/* Transmit and receive buffer sizes, adjust at your peril */#define RX_BUF_SZ 	4196#define TX_BUF_SZ	4196/* No user servicable parts below here */#include <linux/module.h>#include <linux/kernel.h>#include <linux/types.h>#include <linux/skbuff.h>#include <linux/netdevice.h>#include <linux/ioport.h>#include <linux/delay.h>#include <linux/slab.h>#include <linux/init.h>#include <linux/pci.h>#include <linux/rtnetlink.h>#include <asm/system.h>#include <asm/io.h>#include <net/irda/wrapper.h>#include <net/irda/irda.h>#include <net/irda/irmod.h>#include <net/irda/irlap_frame.h>#include <net/irda/irda_device.h>#include <linux/pm.h>#include <net/irda/toshoboe.h>#define PCI_DEVICE_ID_FIR701b  0x0d01static struct pci_device_id toshoboe_pci_tbl[] __initdata = {	{ PCI_VENDOR_ID_TOSHIBA, PCI_DEVICE_ID_FIR701, PCI_ANY_ID, PCI_ANY_ID, },	{ PCI_VENDOR_ID_TOSHIBA, PCI_DEVICE_ID_FIR701b, PCI_ANY_ID, PCI_ANY_ID, },	{ }			/* Terminating entry */};MODULE_DEVICE_TABLE(pci, toshoboe_pci_tbl);static const char *driver_name = "toshoboe";static int max_baud = 4000000;/* Shutdown the chip and point the taskfile reg somewhere else */static voidtoshoboe_stopchip (struct toshoboe_cb *self){  IRDA_DEBUG (4, __FUNCTION__ "()\n");  outb_p (0x0e, OBOE_REG_11);  outb_p (0x00, OBOE_RST);  outb_p (0x3f, OBOE_TFP2);     /*Write the taskfile address */  outb_p (0xff, OBOE_TFP1);  outb_p (0xff, OBOE_TFP0);  outb_p (0x0f, OBOE_REG_1B);  outb_p (0xff, OBOE_REG_1A);  outb_p (0x00, OBOE_ISR);      /*FIXME: should i do this to disbale ints */  outb_p (0x80, OBOE_RST);  outb_p (0xe, OBOE_LOCK);}/*Set the baud rate */static voidtoshoboe_setbaud (struct toshoboe_cb *self, int baud){  unsigned long flags;  IRDA_DEBUG (4, __FUNCTION__ "()\n");  printk (KERN_WARNING "ToshOboe: setting baud to %d\n", baud);  save_flags (flags);  cli ();  switch (baud)    {    case 2400:      outb_p (OBOE_PMDL_SIR, OBOE_PMDL);      outb_p (OBOE_SMDL_SIR, OBOE_SMDL);      outb_p (0xbf, OBOE_UDIV);      break;    case 4800:      outb_p (OBOE_PMDL_SIR, OBOE_PMDL);      outb_p (OBOE_SMDL_SIR, OBOE_SMDL);      outb_p (0x5f, OBOE_UDIV);      break;    case 9600:      outb_p (OBOE_PMDL_SIR, OBOE_PMDL);      outb_p (OBOE_SMDL_SIR, OBOE_SMDL);      outb_p (0x2f, OBOE_UDIV);      break;    case 19200:      outb_p (OBOE_PMDL_SIR, OBOE_PMDL);      outb_p (OBOE_SMDL_SIR, OBOE_SMDL);      outb_p (0x17, OBOE_UDIV);      break;    case 38400:      outb_p (OBOE_PMDL_SIR, OBOE_PMDL);      outb_p (OBOE_SMDL_SIR, OBOE_SMDL);      outb_p (0xb, OBOE_UDIV);      break;    case 57600:      outb_p (OBOE_PMDL_SIR, OBOE_PMDL);      outb_p (OBOE_SMDL_SIR, OBOE_SMDL);      outb_p (0x7, OBOE_UDIV);      break;    case 115200:      outb_p (OBOE_PMDL_SIR, OBOE_PMDL);      outb_p (OBOE_SMDL_SIR, OBOE_SMDL);      outb_p (0x3, OBOE_UDIV);      break;    case 1152000:      outb_p (OBOE_PMDL_MIR, OBOE_PMDL);      outb_p (OBOE_SMDL_MIR, OBOE_SMDL);      outb_p (0x1, OBOE_UDIV);      break;    case 4000000:      outb_p (OBOE_PMDL_FIR, OBOE_PMDL);      outb_p (OBOE_SMDL_FIR, OBOE_SMDL);      outb_p (0x0, OBOE_UDIV);      break;    }  restore_flags (flags);  outb_p (0x00, OBOE_RST);  outb_p (0x80, OBOE_RST);  outb_p (0x01, OBOE_REG_9);  self->io.speed = baud;}/* Wake the chip up and get it looking at the taskfile */static voidtoshoboe_startchip (struct toshoboe_cb *self){  __u32 physaddr;  IRDA_DEBUG (4, __FUNCTION__ "()\n");  outb_p (0, OBOE_LOCK);  outb_p (0, OBOE_RST);  outb_p (OBOE_NTR_VAL, OBOE_NTR);  outb_p (0xf0, OBOE_REG_D);  outb_p (0xff, OBOE_ISR);  outb_p (0x0f, OBOE_REG_1B);  outb_p (0xff, OBOE_REG_1A);  physaddr = virt_to_bus (self->taskfile);  outb_p ((physaddr >> 0x0a) & 0xff, OBOE_TFP0);  outb_p ((physaddr >> 0x12) & 0xff, OBOE_TFP1);  outb_p ((physaddr >> 0x1a) & 0x3f, OBOE_TFP2);  outb_p (0x0e, OBOE_REG_11);  outb_p (0x80, OBOE_RST);  toshoboe_setbaud (self, 9600);}/*Let the chip look at memory */static voidtoshoboe_enablebm (struct toshoboe_cb *self){  IRDA_DEBUG (4, __FUNCTION__ "()\n");  pci_set_master (self->pdev);}/*Don't let the chip look at memory */static voidtoshoboe_disablebm (struct toshoboe_cb *self){  __u8 command;  IRDA_DEBUG (4, __FUNCTION__ "()\n");  pci_read_config_byte (self->pdev, PCI_COMMAND, &command);  command &= ~PCI_COMMAND_MASTER;  pci_write_config_byte (self->pdev, PCI_COMMAND, command);}/*setup the taskfile */static voidtoshoboe_initbuffs (struct toshoboe_cb *self){  int i;  unsigned long flags;  IRDA_DEBUG (4, __FUNCTION__ "()\n");  save_flags (flags);  cli ();  for (i = 0; i < TX_SLOTS; ++i)    {      self->taskfile->xmit[i].len = 0;      self->taskfile->xmit[i].control = 0x00;      self->taskfile->xmit[i].buffer = virt_to_bus (self->xmit_bufs[i]);    }  for (i = 0; i < RX_SLOTS; ++i)    {      self->taskfile->recv[i].len = 0;      self->taskfile->recv[i].control = 0x83;      self->taskfile->recv[i].buffer = virt_to_bus (self->recv_bufs[i]);    }  restore_flags (flags);}/*Transmit something */static inttoshoboe_hard_xmit (struct sk_buff *skb, struct net_device *dev){  struct toshoboe_cb *self;  __s32 speed;  int mtt, len;  self = (struct toshoboe_cb *) dev->priv;  ASSERT (self != NULL, return 0;    );  /* Check if we need to change the speed */  speed = irda_get_next_speed(skb);  if ((speed != self->io.speed) && (speed != -1)) {	/* Check for empty frame */	if (!skb->len) {	    toshoboe_setbaud(self, speed); 	    dev_kfree_skb(skb);	    return 0;	} else	    self->new_speed = speed;  }  netif_stop_queue(dev);    if (self->stopped) {	  dev_kfree_skb(skb);    return 0;  }#ifdef ONETASK  if (self->txpending)    return -EBUSY;  self->txs = inb_p (OBOE_XMTT) - OBOE_XMTT_OFFSET;  self->txs &= 0x3f;#endif  if (self->taskfile->xmit[self->txs].control)    return -EBUSY;  if (inb_p (OBOE_RST) & OBOE_RST_WRAP)    {      len = async_wrap_skb (skb, self->xmit_bufs[self->txs], TX_BUF_SZ);    }  else    {      len = skb->len;      memcpy (self->xmit_bufs[self->txs], skb->data, len);    }  self->taskfile->xmit[self->txs].len = len & 0x0fff;  outb_p (0, OBOE_RST);  outb_p (0x1e, OBOE_REG_11);  self->taskfile->xmit[self->txs].control = 0x84;  mtt = irda_get_mtt (skb);  if (mtt)    udelay (mtt);  self->txpending++;  /*FIXME: ask about busy,media_busy stuff, for the moment */  /*busy means can't queue any more */#ifndef ONETASK  if (self->txpending != TX_SLOTS)  {  	netif_wake_queue(dev);  }#endif  outb_p (0x80, OBOE_RST);  outb_p (1, OBOE_REG_9);  self->txs++;  self->txs %= TX_SLOTS;  dev_kfree_skb (skb);  return 0;}/*interrupt handler */static voidtoshoboe_interrupt (int irq, void *dev_id, struct pt_regs *regs){  struct toshoboe_cb *self = (struct toshoboe_cb *) dev_id;  __u8 irqstat;  struct sk_buff *skb;  if (self == NULL)    {      printk (KERN_WARNING "%s: irq %d for unknown device.\n",              driver_name, irq);      return;    }  IRDA_DEBUG (4, __FUNCTION__ "()\n");  irqstat = inb_p (OBOE_ISR);/* woz it us */  if (!(irqstat & 0xf8))    return;  outb_p (irqstat, OBOE_ISR);   /*Acknologede it *//* Txdone */  if (irqstat & OBOE_ISR_TXDONE)    {      self->txpending--;      self->stats.tx_packets++;      if (self->new_speed) {	      toshoboe_setbaud(self, self->new_speed);	      self->new_speed = 0;      }      /* Tell network layer that we want more frames */      netif_wake_queue(self->netdev);    }  if (irqstat & OBOE_ISR_RXDONE)    {#ifdef ONETASK      self->rxs = inb_p (OBOE_RCVT);      self->rxs += (RX_SLOTS - 1);      self->rxs %= RX_SLOTS;#else      while (self->taskfile->recv[self->rxs].control == 0)#endif        {          int len = self->taskfile->recv[self->rxs].len;          if (len > 2)            len -= 2;          skb = dev_alloc_skb (len + 1);          if (skb)            {              skb_reserve (skb, 1);              skb_put (skb, len);              memcpy (skb->data, self->recv_bufs[self->rxs], len);              self->stats.rx_packets++;              skb->dev = self->netdev;              skb->mac.raw = skb->data;              skb->protocol = htons (ETH_P_IRDA);            }          else            {              printk (KERN_INFO __FUNCTION__                      "(), memory squeeze, dropping frame.\n");            }          self->taskfile->recv[self->rxs].control = 0x83;          self->taskfile->recv[self->rxs].len = 0x0;          self->rxs++;          self->rxs %= RX_SLOTS;          if (skb)            netif_rx (skb);        }    }  if (irqstat & OBOE_ISR_20)    {      printk (KERN_WARNING "Oboe_irq: 20\n");    }  if (irqstat & OBOE_ISR_10)    {      printk (KERN_WARNING "Oboe_irq: 10\n");    }  if (irqstat & 0x8)    {      /*FIXME: I think this is a TX or RX error of some sort */      self->stats.tx_errors++;      self->stats.rx_errors++;    }}static inttoshoboe_net_init (struct net_device *dev){  IRDA_DEBUG (4, __FUNCTION__ "()\n");  /* Setup to be a normal IrDA network device driver */  irda_device_setup (dev);  /* Insert overrides below this line! */  return 0;}static void toshoboe_initptrs (struct toshoboe_cb *self){  unsigned long flags;  save_flags (flags);  cli ();

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -