📄 boardergo.c
字号:
dst += (offs + ERG_DPRAM_FILL_SIZE); /* offset in the DPRAM */ while (cnt--) { *dst++ = *(buf + 1); /* high byte */ *dst++ = *buf; /* low byte */ dst += 2; /* point to next longword */ buf += 2; /* buffer only filled with words */ } /* if low words (offs = 2) have been written, clear the rest of the DPRAM, */ /* flush the PCI-write-buffer and take the E1 out of reset */ if (offs) { memset(card->dpram, 0, ERG_DPRAM_FILL_SIZE); /* fill the DPRAM still not cleared */ dpram = card->dpram; /* get pointer to dpram structure */ dpram->ToHyNoDpramErrLog = 0xFF; /* write a dpram register */ while (!dpram->ToHyNoDpramErrLog); /* reread volatile register to flush PCI */ byteout(card->iobase + PCI9050_USER_IO, PCI9050_E1_RUN); /* start E1 processor */ /* the interrupts are still masked */ sti(); set_current_state(TASK_INTERRUPTIBLE); schedule_timeout((20 * HZ) / 1000); /* Timeout 20ms */ if (((tDpramBootSpooler *) card->dpram)->Len != DPRAM_SPOOLER_DATA_SIZE) { if (card->debug_flags & LOG_POF_CARD) hysdn_addlog(card, "ERGO: write bootldr no answer"); return (-ERR_BOOTIMG_FAIL); } } /* start_boot_img */ return (0); /* successful */} /* ergo_writebootimg *//********************************************************************************//* ergo_writebootseq writes the buffer containing len bytes to the E1 processor *//* using the boot spool mechanism. If everything works fine 0 is returned. In *//* case of errors a negative error value is returned. *//********************************************************************************/static intergo_writebootseq(struct HYSDN_CARD *card, uchar * buf, int len){ tDpramBootSpooler *sp = (tDpramBootSpooler *) card->dpram; uchar *dst; uchar buflen; int nr_write; uchar tmp_rdptr; uchar wr_mirror; int i; if (card->debug_flags & LOG_POF_CARD) hysdn_addlog(card, "ERGO: write boot seq len=%d ", len); dst = sp->Data; /* point to data in spool structure */ buflen = sp->Len; /* maximum len of spooled data */ wr_mirror = sp->WrPtr; /* only once read */ sti(); /* try until all bytes written or error */ i = 0x1000; /* timeout value */ while (len) { /* first determine the number of bytes that may be buffered */ do { tmp_rdptr = sp->RdPtr; /* first read the pointer */ i--; /* decrement timeout */ } while (i && (tmp_rdptr != sp->RdPtr)); /* wait for stable pointer */ if (!i) { if (card->debug_flags & LOG_POF_CARD) hysdn_addlog(card, "ERGO: write boot seq timeout"); return (-ERR_BOOTSEQ_FAIL); /* value not stable -> timeout */ } if ((nr_write = tmp_rdptr - wr_mirror - 1) < 0) nr_write += buflen; /* now we got number of free bytes - 1 in buffer */ if (!nr_write) continue; /* no free bytes in buffer */ if (nr_write > len) nr_write = len; /* limit if last few bytes */ i = 0x1000; /* reset timeout value */ /* now we know how much bytes we may put in the puffer */ len -= nr_write; /* we savely could adjust len before output */ while (nr_write--) { *(dst + wr_mirror) = *buf++; /* output one byte */ if (++wr_mirror >= buflen) wr_mirror = 0; sp->WrPtr = wr_mirror; /* announce the next byte to E1 */ } /* while (nr_write) */ } /* while (len) */ return (0);} /* ergo_writebootseq *//***********************************************************************************//* ergo_waitpofready waits for a maximum of 10 seconds for the completition of the *//* boot process. If the process has been successful 0 is returned otherwise a *//* negative error code is returned. *//***********************************************************************************/static intergo_waitpofready(struct HYSDN_CARD *card){ tErgDpram *dpr = card->dpram; /* pointer to DPRAM structure */ int timecnt = 10000 / 50; /* timeout is 10 secs max. */ ulong flags; int msg_size; int i; if (card->debug_flags & LOG_POF_CARD) hysdn_addlog(card, "ERGO: waiting for pof ready"); while (timecnt--) { /* wait until timeout */ if (dpr->ToPcFlag) { /* data has arrived */ if ((dpr->ToPcChannel != CHAN_SYSTEM) || (dpr->ToPcSize < MIN_RDY_MSG_SIZE) || (dpr->ToPcSize > MAX_RDY_MSG_SIZE) || ((*(ulong *) dpr->ToPcBuf) != RDY_MAGIC)) break; /* an error occurred */ /* Check for additional data delivered during SysReady */ msg_size = dpr->ToPcSize - RDY_MAGIC_SIZE; if (msg_size > 0) if (EvalSysrTokData(card, dpr->ToPcBuf + RDY_MAGIC_SIZE, msg_size)) break; if (card->debug_flags & LOG_POF_RECORD) hysdn_addlog(card, "ERGO: pof boot success"); save_flags(flags); cli(); card->state = CARD_STATE_RUN; /* now card is running */ /* enable the cards interrupt */ byteout(card->iobase + PCI9050_INTR_REG, bytein(card->iobase + PCI9050_INTR_REG) | (PCI9050_INTR_REG_ENPCI | PCI9050_INTR_REG_EN1)); card->irq_enabled = 1; /* we are ready to receive interrupts */ dpr->ToPcFlag = 0; /* reset data indicator */ dpr->ToHyInt = 1; dpr->ToPcInt = 1; /* interrupt to E1 for all cards */ restore_flags(flags); if ((hynet_enable & (1 << card->myid)) && (i = hysdn_net_create(card))) { ergo_stopcard(card); card->state = CARD_STATE_BOOTERR; return (i); }#ifdef CONFIG_HYSDN_CAPI if((i = hycapi_capi_create(card))) { printk(KERN_WARNING "HYSDN: failed to create capi-interface.\n"); }#endif /* CONFIG_HYSDN_CAPI */ return (0); /* success */ } /* data has arrived */ sti(); set_current_state(TASK_INTERRUPTIBLE); schedule_timeout((50 * HZ) / 1000); /* Timeout 50ms */ } /* wait until timeout */ if (card->debug_flags & LOG_POF_CARD) hysdn_addlog(card, "ERGO: pof boot ready timeout"); return (-ERR_POF_TIMEOUT);} /* ergo_waitpofready *//************************************************************************************//* release the cards hardware. Before releasing do a interrupt disable and hardware *//* reset. Also unmap dpram. *//* Use only during module release. *//************************************************************************************/static voidergo_releasehardware(hysdn_card * card){ ergo_stopcard(card); /* first stop the card if not already done */ free_irq(card->irq, card); /* release interrupt */ release_region(card->iobase + PCI9050_INTR_REG, 1); /* release all io ports */ release_region(card->iobase + PCI9050_USER_IO, 1); vfree(card->dpram); card->dpram = NULL; /* release shared mem */} /* ergo_releasehardware *//*********************************************************************************//* acquire the needed hardware ports and map dpram. If an error occurs a nonzero *//* value is returned. *//* Use only during module init. *//*********************************************************************************/intergo_inithardware(hysdn_card * card){ if (!request_region(card->iobase + PCI9050_INTR_REG, 1, "HYSDN")) return (-1); if (!request_region(card->iobase + PCI9050_USER_IO, 1, "HYSDN")) { release_region(card->iobase + PCI9050_INTR_REG, 1); return (-1); /* ports already in use */ } card->memend = card->membase + ERG_DPRAM_PAGE_SIZE - 1; if (!(card->dpram = ioremap(card->membase, ERG_DPRAM_PAGE_SIZE))) { release_region(card->iobase + PCI9050_INTR_REG, 1); release_region(card->iobase + PCI9050_USER_IO, 1); return (-1); } ergo_stopcard(card); /* disable interrupts */ if (request_irq(card->irq, ergo_interrupt, SA_SHIRQ, "HYSDN", card)) { ergo_releasehardware(card); /* return the acquired hardware */ return (-1); } /* success, now setup the function pointers */ card->stopcard = ergo_stopcard; card->releasehardware = ergo_releasehardware; card->testram = ergo_testram; card->writebootimg = ergo_writebootimg; card->writebootseq = ergo_writebootseq; card->waitpofready = ergo_waitpofready; card->set_errlog_state = ergo_set_errlog_state; INIT_WORK(&card->irq_queue, (void *) (void *) ergo_irq_bh, card); return (0);} /* ergo_inithardware */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -