📄 donauboe.c
字号:
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 + -