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

📄 donauboe.c

📁 《linux驱动程序设计从入门到精通》一书中所有的程序代码含驱动和相应的应用程序
💻 C
📖 第 1 页 / 共 4 页
字号:
      break;#ifdef USE_MIR      /* MIR mode */      /* Set for 16 bit CRC and enable MIR */      /* Preamble now handled by the chip */    case 1152000:      pconfig |= 0 << OBOE_PCONFIG_BAUDSHIFT;      pconfig |= 8 << OBOE_PCONFIG_WIDTHSHIFT;      pconfig |= 1 << OBOE_PCONFIG_PREAMBLESHIFT;      config0l = OBOE_CONFIG0L_CRC16 | OBOE_CONFIG0L_ENMIR;      break;#endif      /* FIR mode */      /* Set for 32 bit CRC and enable FIR */      /* Preamble handled by the chip */    case 4000000:      pconfig |= 0 << OBOE_PCONFIG_BAUDSHIFT;      /* Documentation says 14, but toshiba use 15 in their drivers */      pconfig |= 15 << OBOE_PCONFIG_PREAMBLESHIFT;      config0l = OBOE_CONFIG0L_ENFIR;      break;    }  /* Copy into new PHY config buffer */  OUTBP (pconfig >> 8, OBOE_NEW_PCONFIGH);  OUTB (pconfig & 0xff, OBOE_NEW_PCONFIGL);  OUTB (config0l, OBOE_CONFIG0L);  /* Now make OBOE copy from new PHY to current PHY */  OUTB (0x0, OBOE_ENABLEH);  OUTB (OBOE_ENABLEH_PHYANDCLOCK, OBOE_ENABLEH);  PROMPT;  /* speed change executed */  self->new_speed = 0;  self->io.speed = self->speed;}/*Let the chip look at memory */static voidtoshoboe_enablebm (struct toshoboe_cb *self){  IRDA_DEBUG (4, "%s()\n", __FUNCTION__);  pci_set_master (self->pdev);}/*setup the ring */static voidtoshoboe_initring (struct toshoboe_cb *self){  int i;  IRDA_DEBUG (4, "%s()\n", __FUNCTION__);  for (i = 0; i < TX_SLOTS; ++i)    {      self->ring->tx[i].len = 0;      self->ring->tx[i].control = 0x00;      self->ring->tx[i].address = virt_to_bus (self->tx_bufs[i]);    }  for (i = 0; i < RX_SLOTS; ++i)    {      self->ring->rx[i].len = RX_LEN;      self->ring->rx[i].len = 0;      self->ring->rx[i].address = virt_to_bus (self->rx_bufs[i]);      self->ring->rx[i].control = OBOE_CTL_RX_HW_OWNS;    }}static voidtoshoboe_resetptrs (struct toshoboe_cb *self){  /* Can reset pointers by twidling DMA */  OUTB (0x0, OBOE_ENABLEH);  OUTBP (CONFIG0H_DMA_OFF, OBOE_CONFIG0H);  OUTB (OBOE_ENABLEH_PHYANDCLOCK, OBOE_ENABLEH);  self->rxs = inb_p (OBOE_RXSLOT) & OBOE_SLOT_MASK;  self->txs = inb_p (OBOE_TXSLOT) & OBOE_SLOT_MASK;}/* Called in locked state */static voidtoshoboe_initptrs (struct toshoboe_cb *self){  /* spin_lock_irqsave(self->spinlock, flags); */  /* save_flags (flags); */  /* Can reset pointers by twidling DMA */  toshoboe_resetptrs (self);  OUTB (0x0, OBOE_ENABLEH);  OUTB (CONFIG0H_DMA_ON, OBOE_CONFIG0H);  OUTB (OBOE_ENABLEH_PHYANDCLOCK, OBOE_ENABLEH);  self->txpending = 0;  /* spin_unlock_irqrestore(self->spinlock, flags); */  /* restore_flags (flags); */}/* Wake the chip up and get it looking at the rings *//* Called in locked state */static voidtoshoboe_startchip (struct toshoboe_cb *self){  __u32 physaddr;  IRDA_DEBUG (4, "%s()\n", __FUNCTION__);  toshoboe_initring (self);  toshoboe_enablebm (self);  OUTBP (OBOE_CONFIG1_RESET, OBOE_CONFIG1);  OUTBP (OBOE_CONFIG1_ON, OBOE_CONFIG1);  /* Stop the clocks */  OUTB (0, OBOE_ENABLEH);  /*Set size of rings */  OUTB (RING_SIZE, OBOE_RING_SIZE);  /*Acknoledge any pending interrupts */  OUTB (0xff, OBOE_ISR);  /*Enable ints */  OUTB (OBOE_INT_TXDONE  | OBOE_INT_RXDONE |        OBOE_INT_TXUNDER | OBOE_INT_RXOVER | OBOE_INT_SIP , OBOE_IER);  /*Acknoledge any pending interrupts */  OUTB (0xff, OBOE_ISR);  /*Set the maximum packet length to 0xfff (4095) */  OUTB (RX_LEN >> 8, OBOE_MAXLENH);  OUTB (RX_LEN & 0xff, OBOE_MAXLENL);  /*Shutdown DMA */  OUTB (CONFIG0H_DMA_OFF, OBOE_CONFIG0H);  /*Find out where the rings live */  physaddr = virt_to_bus (self->ring);  IRDA_ASSERT ((physaddr & 0x3ff) == 0,	       printk (KERN_ERR DRIVER_NAME "ring not correctly aligned\n");	       return;);  OUTB ((physaddr >> 10) & 0xff, OBOE_RING_BASE0);  OUTB ((physaddr >> 18) & 0xff, OBOE_RING_BASE1);  OUTB ((physaddr >> 26) & 0x3f, OBOE_RING_BASE2);  /*Enable DMA controler in byte mode and RX */  OUTB (CONFIG0H_DMA_ON, OBOE_CONFIG0H);  /* Start up the clocks */  OUTB (OBOE_ENABLEH_PHYANDCLOCK, OBOE_ENABLEH);  /*set to sensible speed */  self->speed = 9600;  toshoboe_setbaud (self);  toshoboe_initptrs (self);}static voidtoshoboe_isntstuck (struct toshoboe_cb *self){}static voidtoshoboe_checkstuck (struct toshoboe_cb *self){  unsigned long flags;  if (0)    {      spin_lock_irqsave(&self->spinlock, flags);      /* This will reset the chip completely */      printk (KERN_ERR DRIVER_NAME ": Resetting chip\n");      toshoboe_stopchip (self);      toshoboe_startchip (self);      spin_unlock_irqrestore(&self->spinlock, flags);    }}/*Generate packet of about mtt us long */static inttoshoboe_makemttpacket (struct toshoboe_cb *self, void *buf, int mtt){  int xbofs;  xbofs = ((int) (mtt/100)) * (int) (self->speed);  xbofs=xbofs/80000; /*Eight bits per byte, and mtt is in us*/  xbofs++;  IRDA_DEBUG (2, DRIVER_NAME      ": generated mtt of %d bytes for %d us at %d baud\n"	  , xbofs,mtt,self->speed);  if (xbofs > TX_LEN)    {      printk (KERN_ERR DRIVER_NAME ": wanted %d bytes MTT but TX_LEN is %d\n",              xbofs, TX_LEN);      xbofs = TX_LEN;    }  /*xbofs will do for SIR, MIR and FIR,SIR mode doesn't generate a checksum anyway */  memset (buf, XBOF, xbofs);  return xbofs;}#ifdef USE_PROBE/***********************************************************************//* Probe code */static voidtoshoboe_dumptx (struct toshoboe_cb *self){  int i;  PROBE_DEBUG(KERN_WARNING "TX:");  for (i = 0; i < RX_SLOTS; ++i)    PROBE_DEBUG(" (%d,%02x)",self->ring->tx[i].len,self->ring->tx[i].control);  PROBE_DEBUG(" [%d]\n",self->speed);}static voidtoshoboe_dumprx (struct toshoboe_cb *self, int score){  int i;  PROBE_DEBUG(" %d\nRX:",score);  for (i = 0; i < RX_SLOTS; ++i)    PROBE_DEBUG(" (%d,%02x)",self->ring->rx[i].len,self->ring->rx[i].control);  PROBE_DEBUG("\n");}static inline intstuff_byte (__u8 byte, __u8 * buf){  switch (byte)    {    case BOF:                  /* FALLTHROUGH */    case EOF:                  /* FALLTHROUGH */    case CE:      /* Insert transparently coded */      buf[0] = CE;              /* Send link escape */      buf[1] = byte ^ IRDA_TRANS; /* Complement bit 5 */      return 2;      /* break; */    default:      /* Non-special value, no transparency required */      buf[0] = byte;      return 1;      /* break; */    }}static irqreturn_ttoshoboe_probeinterrupt (int irq, void *dev_id){  struct toshoboe_cb *self = dev_id;  __u8 irqstat;  irqstat = INB (OBOE_ISR);/* was it us */  if (!(irqstat & OBOE_INT_MASK))    return IRQ_NONE;/* Ack all the interrupts */  OUTB (irqstat, OBOE_ISR);  if (irqstat & OBOE_INT_TXDONE)    {      int txp;      self->int_tx++;      PROBE_DEBUG("T");      txp = INB (OBOE_TXSLOT) & OBOE_SLOT_MASK;      if (self->ring->tx[txp].control & OBOE_CTL_TX_HW_OWNS)        {          self->int_tx+=100;          PROBE_DEBUG("S");          toshoboe_start_DMA(self, OBOE_CONFIG0H_ENTX | OBOE_CONFIG0H_LOOP);        }    }  if (irqstat & OBOE_INT_RXDONE) {    self->int_rx++;    PROBE_DEBUG("R"); }  if (irqstat & OBOE_INT_TXUNDER) {    self->int_txunder++;    PROBE_DEBUG("U"); }  if (irqstat & OBOE_INT_RXOVER) {    self->int_rxover++;    PROBE_DEBUG("O"); }  if (irqstat & OBOE_INT_SIP) {    self->int_sip++;    PROBE_DEBUG("I"); }  return IRQ_HANDLED;}static inttoshoboe_maketestpacket (unsigned char *buf, int badcrc, int fir){  int i;  int len = 0;  union  {    __u16 value;    __u8 bytes[2];  }  fcs;  if (fir)    {      memset (buf, 0, TT_LEN);      return (TT_LEN);    }  fcs.value = INIT_FCS;  memset (buf, XBOF, 10);  len += 10;  buf[len++] = BOF;  for (i = 0; i < TT_LEN; ++i)    {      len += stuff_byte (i, buf + len);      fcs.value = irda_fcs (fcs.value, i);    }  len += stuff_byte (fcs.bytes[0] ^ badcrc, buf + len);  len += stuff_byte (fcs.bytes[1] ^ badcrc, buf + len);  buf[len++] = EOF;  len++;  return len;}static inttoshoboe_probefail (struct toshoboe_cb *self, char *msg){  printk (KERN_ERR DRIVER_NAME "probe(%d) failed %s\n",self-> speed, msg);  toshoboe_dumpregs (self);  toshoboe_stopchip (self);  free_irq (self->io.irq, (void *) self);  return 0;}static inttoshoboe_numvalidrcvs (struct toshoboe_cb *self){  int i, ret = 0;  for (i = 0; i < RX_SLOTS; ++i)    if ((self->ring->rx[i].control & 0xe0) == 0)      ret++;  return ret;}static inttoshoboe_numrcvs (struct toshoboe_cb *self){  int i, ret = 0;  for (i = 0; i < RX_SLOTS; ++i)    if (!(self->ring->rx[i].control & OBOE_CTL_RX_HW_OWNS))      ret++;  return ret;}static inttoshoboe_probe (struct toshoboe_cb *self){  int i, j, n;#ifdef USE_MIR  int bauds[] = { 9600, 115200, 4000000, 1152000 };#else  int bauds[] = { 9600, 115200, 4000000 };#endif  unsigned long flags;  IRDA_DEBUG (4, "%s()\n", __FUNCTION__);  if (request_irq (self->io.irq, toshoboe_probeinterrupt,                   self->io.irqflags, "toshoboe", (void *) self))    {      printk (KERN_ERR DRIVER_NAME ": probe failed to allocate irq %d\n",              self->io.irq);      return 0;    }  /* test 1: SIR filter and back to back */  for (j = 0; j < (sizeof (bauds) / sizeof (int)); ++j)    {      int fir = (j > 1);      toshoboe_stopchip (self);      spin_lock_irqsave(&self->spinlock, flags);      /*Address is already setup */      toshoboe_startchip (self);      self->int_rx = self->int_tx = 0;      self->speed = bauds[j];      toshoboe_setbaud (self);      toshoboe_initptrs (self);      spin_unlock_irqrestore(&self->spinlock, flags);      self->ring->tx[self->txs].control =/*   (FIR only) OBOE_CTL_TX_SIP needed for switching to next slot *//*    MIR: all received data is stored in one slot */        (fir) ? OBOE_CTL_TX_HW_OWNS | OBOE_CTL_TX_RTCENTX              : OBOE_CTL_TX_HW_OWNS ;      self->ring->tx[self->txs].len =        toshoboe_maketestpacket (self->tx_bufs[self->txs], 0, fir);      self->txs++;      self->txs %= TX_SLOTS;      self->ring->tx[self->txs].control =        (fir) ? OBOE_CTL_TX_HW_OWNS | OBOE_CTL_TX_SIP              : OBOE_CTL_TX_HW_OWNS | OBOE_CTL_TX_RTCENTX ;      self->ring->tx[self->txs].len =        toshoboe_maketestpacket (self->tx_bufs[self->txs], 0, fir);      self->txs++;      self->txs %= TX_SLOTS;      self->ring->tx[self->txs].control =        (fir) ? OBOE_CTL_TX_HW_OWNS | OBOE_CTL_TX_RTCENTX              : OBOE_CTL_TX_HW_OWNS ;      self->ring->tx[self->txs].len =        toshoboe_maketestpacket (self->tx_bufs[self->txs], 0, fir);      self->txs++;      self->txs %= TX_SLOTS;      self->ring->tx[self->txs].control =        (fir) ? OBOE_CTL_TX_HW_OWNS | OBOE_CTL_TX_RTCENTX              | OBOE_CTL_TX_SIP     | OBOE_CTL_TX_BAD_CRC              : OBOE_CTL_TX_HW_OWNS | OBOE_CTL_TX_RTCENTX ;      self->ring->tx[self->txs].len =        toshoboe_maketestpacket (self->tx_bufs[self->txs], 0, fir);      self->txs++;

⌨️ 快捷键说明

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