📄 comx-hw-comx.c
字号:
savep = ch->HW_access_board(dev); COMX_WRITE(dev, OFF_A_L2_LINKUP, 0); if (ch->HW_set_clock) { ch->HW_set_clock(dev); } COMX_CMD(dev, COMX_CMD_INIT); jiffs = jiffies; while (COMX_readw(dev, OFF_A_L2_LINKUP) != 1 && jiffies < jiffs + HZ) { schedule_timeout(1); } if (jiffies >= jiffs + HZ) { printk(KERN_ERR "%s: board timeout on INIT command\n", dev->name); ch->HW_release_board(dev, savep); retval=-EIO; goto error; } udelay(1000); COMX_CMD(dev, COMX_CMD_OPEN); jiffs = jiffies; while (COMX_readw(dev, OFF_A_L2_LINKUP) != 3 && jiffies < jiffs + HZ) { schedule_timeout(1); } if (jiffies >= jiffs + HZ) { printk(KERN_ERR "%s: board timeout on OPEN command\n", dev->name); ch->HW_release_board(dev, savep); retval=-EIO; goto error; } ch->init_status |= HW_OPEN; /* Ez eleg ciki, de ilyen a rendszer */ if (COMX_readw(dev, OFF_A_L1_PBUFOVR) >> 8) { ch->line_status &= ~LINE_UP; } else { ch->line_status |= LINE_UP; } if (ch->LINE_status) { ch->LINE_status(dev, ch->line_status); } ch->HW_release_board(dev, savep); for ( ; procfile ; procfile = procfile->next) { if (strcmp(procfile->name, FILENAME_IRQ) == 0 || strcmp(procfile->name, FILENAME_IO) == 0 || strcmp(procfile->name, FILENAME_MEMADDR) == 0 || strcmp(procfile->name, FILENAME_CHANNEL) == 0 || strcmp(procfile->name, FILENAME_FIRMWARE) == 0 || strcmp(procfile->name, FILENAME_CLOCK) == 0) { procfile->mode = S_IFREG | 0444; } } return 0; error: if(!twin_open) { release_region(dev->base_addr, hw->io_extent); free_irq(dev->irq, (void *)dev); } return retval;}static int COMX_close(struct net_device *dev){ struct comx_channel *ch = dev->priv; struct proc_dir_entry *procfile = ch->procdir->subdir; struct comx_privdata *hw = ch->HW_privdata; struct comx_channel *twin_ch; struct net_device *savep; savep = ch->HW_access_board(dev); COMX_CMD(dev, COMX_CMD_CLOSE); udelay(1000); COMX_CMD(dev, COMX_CMD_EXIT); ch->HW_release_board(dev, savep); if (ch->init_status & IRQ_ALLOCATED) { free_irq(dev->irq, (void *)dev); ch->init_status &= ~IRQ_ALLOCATED; } release_region(dev->base_addr, hw->io_extent); if (ch->twin && (twin_ch = ch->twin->priv) && (twin_ch->init_status & HW_OPEN)) { /* Pass the irq to the twin */ if (request_irq(dev->irq, COMX_interrupt, 0, ch->twin->name, (void *)ch->twin) == 0) { twin_ch->init_status |= IRQ_ALLOCATED; } } for ( ; procfile ; procfile = procfile->next) { if (strcmp(procfile->name, FILENAME_IRQ) == 0 || strcmp(procfile->name, FILENAME_IO) == 0 || strcmp(procfile->name, FILENAME_MEMADDR) == 0 || strcmp(procfile->name, FILENAME_CHANNEL) == 0 || strcmp(procfile->name, FILENAME_FIRMWARE) == 0 || strcmp(procfile->name, FILENAME_CLOCK) == 0) { procfile->mode = S_IFREG | 0644; } } ch->init_status &= ~HW_OPEN; return 0;}static int COMX_statistics(struct net_device *dev, char *page){ struct comx_channel *ch = dev->priv; struct comx_privdata *hw = ch->HW_privdata; struct net_device *savep; int len = 0; savep = ch->HW_access_board(dev); len += sprintf(page + len, "Board data: %s %s %s %s\nPBUFOVR: %02x, " "MODSTAT: %02x, LINKUP: %02x, DAV: %02x\nRxBUFP: %02x, " "TxEMPTY: %02x, TxBUFP: %02x\n", (ch->init_status & HW_OPEN) ? "HW_OPEN" : "", (ch->init_status & LINE_OPEN) ? "LINE_OPEN" : "", (ch->init_status & FW_LOADED) ? "FW_LOADED" : "", (ch->init_status & IRQ_ALLOCATED) ? "IRQ_ALLOCATED" : "", COMX_readw(dev, OFF_A_L1_PBUFOVR) & 0xff, (COMX_readw(dev, OFF_A_L1_PBUFOVR) >> 8) & 0xff, COMX_readw(dev, OFF_A_L2_LINKUP) & 0xff, COMX_readw(dev, OFF_A_L2_DAV) & 0xff, COMX_readw(dev, OFF_A_L2_RxBUFP) & 0xff, COMX_readw(dev, OFF_A_L2_TxEMPTY) & 0xff, COMX_readw(dev, OFF_A_L2_TxBUFP) & 0xff); len += sprintf(page + len, "hist[0]: %8lu hist[1]: %8lu hist[2]: %8lu\n" "hist[3]: %8lu hist[4]: %8lu\n",hw->histogram[0],hw->histogram[1], hw->histogram[2],hw->histogram[3],hw->histogram[4]); ch->HW_release_board(dev, savep); return len;}static int COMX_load_board(struct net_device *dev){ struct comx_channel *ch = dev->priv; struct comx_privdata *hw = ch->HW_privdata; struct comx_firmware *fw = hw->firmware; word board_segment = dev->mem_start >> 16; int mempos = (dev->mem_start - COMX_MEM_MIN) >> 16; unsigned long flags; unsigned char id1, id2; struct net_device *saved; int retval; int loopcount; int len; byte *COMX_address; if (!fw || !fw->len) { struct comx_channel *twin_ch = ch->twin ? ch->twin->priv : NULL; struct comx_privdata *twin_hw; if (!twin_ch || !(twin_hw = twin_ch->HW_privdata)) { return -EAGAIN; } if (!(fw = twin_hw->firmware) || !fw->len) { return -EAGAIN; } } id1 = fw->data[OFF_FW_L1_ID]; id2 = fw->data[OFF_FW_L1_ID + 1]; if (id1 != FW_L1_ID_1 || id2 != FW_L1_ID_2_COMX) { printk(KERN_ERR "%s: incorrect firmware, load aborted\n", dev->name); return -EAGAIN; } printk(KERN_INFO "%s: Loading COMX Layer 1 firmware %s\n", dev->name, (char *)(fw->data + OFF_FW_L1_ID + 2)); id1 = fw->data[OFF_FW_L2_ID]; id2 = fw->data[OFF_FW_L2_ID + 1]; if (id1 == FW_L2_ID_1 && (id2 == 0xc0 || id2 == 0xc1 || id2 == 0xc2)) { printk(KERN_INFO "with Layer 2 code %s\n", (char *)(fw->data + OFF_FW_L2_ID + 2)); } outb_p(board_segment | COMX_BOARD_RESET, dev->base_addr); /* 10 usec should be enough here */ udelay(100); save_flags(flags); cli(); saved=memory_used[mempos]; if(saved) { ((struct comx_channel *)saved->priv)->HW_board_off(saved); } memory_used[mempos]=dev; outb_p(board_segment | COMX_ENABLE_BOARD_MEM, dev->base_addr); writeb(0, dev->mem_start + COMX_JAIL_OFFSET); loopcount=0; while(loopcount++ < 10000 && readb(dev->mem_start + COMX_JAIL_OFFSET) != COMX_JAIL_VALUE) { udelay(100); } if (readb(dev->mem_start + COMX_JAIL_OFFSET) != COMX_JAIL_VALUE) { printk(KERN_ERR "%s: Can't reset board, JAIL value is %02x\n", dev->name, readb(dev->mem_start + COMX_JAIL_OFFSET)); retval=-ENODEV; goto out; } writeb(0x55, dev->mem_start + 0x18ff); loopcount=0; while(loopcount++ < 10000 && readb(dev->mem_start + 0x18ff) != 0) { udelay(100); } if(readb(dev->mem_start + 0x18ff) != 0) { printk(KERN_ERR "%s: Can't reset board, reset timeout\n", dev->name); retval=-ENODEV; goto out; } len = 0; COMX_address = (byte *)dev->mem_start; while (fw->len > len) { writeb(fw->data[len++], COMX_address++); } len = 0; COMX_address = (byte *)dev->mem_start; while (len != fw->len && readb(COMX_address++) == fw->data[len]) { len++; } if (len != fw->len) { printk(KERN_ERR "%s: error loading firmware: [%d] is 0x%02x " "instead of 0x%02x\n", dev->name, len, readb(COMX_address - 1), fw->data[len]); retval=-EAGAIN; goto out; } writeb(0, dev->mem_start + COMX_JAIL_OFFSET); loopcount = 0; while ( loopcount++ < 10000 && COMX_readw(dev, OFF_A_L2_LINKUP) != 1 ) { udelay(100); } if (COMX_readw(dev, OFF_A_L2_LINKUP) != 1) { printk(KERN_ERR "%s: error starting firmware, linkup word is %04x\n", dev->name, COMX_readw(dev, OFF_A_L2_LINKUP)); retval=-EAGAIN; goto out; } ch->init_status |= FW_LOADED; retval=0;out: outb_p(board_segment | COMX_DISABLE_ALL, dev->base_addr); if(saved) { ((struct comx_channel *)saved->priv)->HW_board_on(saved); } memory_used[mempos]=saved; restore_flags(flags); return retval;}static int CMX_load_board(struct net_device *dev){ struct comx_channel *ch = dev->priv; struct comx_privdata *hw = ch->HW_privdata; struct comx_firmware *fw = hw->firmware; word board_segment = dev->mem_start >> 16; int mempos = (dev->mem_start - COMX_MEM_MIN) >> 16; #if 0 unsigned char id1, id2; #endif struct net_device *saved; unsigned long flags; int retval; int loopcount; int len; byte *COMX_address; if (!fw || !fw->len) { struct comx_channel *twin_ch = ch->twin ? ch->twin->priv : NULL; struct comx_privdata *twin_hw; if (!twin_ch || !(twin_hw = twin_ch->HW_privdata)) { return -EAGAIN; } if (!(fw = twin_hw->firmware) || !fw->len) { return -EAGAIN; } } /* Ide kell olyat tenni, hogy ellenorizze az ID-t */ if (inb_p(dev->base_addr) != CMX_ID_BYTE) { printk(KERN_ERR "%s: CMX id byte is invalid(%02x)\n", dev->name, inb_p(dev->base_addr)); return -ENODEV; } printk(KERN_INFO "%s: Loading CMX Layer 1 firmware %s\n", dev->name, (char *)(fw->data + OFF_FW_L1_ID + 2)); save_flags(flags); cli(); saved=memory_used[mempos]; if(saved) { ((struct comx_channel *)saved->priv)->HW_board_off(saved); } memory_used[mempos]=dev; outb_p(board_segment | COMX_ENABLE_BOARD_MEM | COMX_BOARD_RESET, dev->base_addr); len = 0; COMX_address = (byte *)dev->mem_start; while (fw->len > len) { writeb(fw->data[len++], COMX_address++); } len = 0; COMX_address = (byte *)dev->mem_start; while (len != fw->len && readb(COMX_address++) == fw->data[len]) { len++; } outb_p(board_segment | COMX_ENABLE_BOARD_MEM, dev->base_addr); if (len != fw->len) { printk(KERN_ERR "%s: error loading firmware: [%d] is 0x%02x " "instead of 0x%02x\n", dev->name, len, readb(COMX_address - 1), fw->data[len]); retval=-EAGAIN; goto out; } loopcount=0; while( loopcount++ < 10000 && COMX_readw(dev, OFF_A_L2_LINKUP) != 1 ) { udelay(100); } if (COMX_readw(dev, OFF_A_L2_LINKUP) != 1) { printk(KERN_ERR "%s: error starting firmware, linkup word is %04x\n", dev->name, COMX_readw(dev, OFF_A_L2_LINKUP)); retval=-EAGAIN; goto out; } ch->init_status |= FW_LOADED; retval=0;out: outb_p(board_segment | COMX_DISABLE_ALL, dev->base_addr); if(saved) { ((struct comx_channel *)saved->priv)->HW_board_on(saved); } memory_used[mempos]=saved; restore_flags(flags); return retval;}static int HICOMX_load_board(struct net_device *dev){ struct comx_channel *ch = dev->priv; struct comx_privdata *hw = ch->HW_privdata; struct comx_firmware *fw = hw->firmware; word board_segment = dev->mem_start >> 12; int mempos = (dev->mem_start - COMX_MEM_MIN) >> 16; struct net_device *saved; unsigned char id1, id2; unsigned long flags; int retval; int loopcount; int len; word *HICOMX_address; char id = 1; if (!fw || !fw->len) { struct comx_channel *twin_ch = ch->twin ? ch->twin->priv : NULL; struct comx_privdata *twin_hw; if (!twin_ch || !(twin_hw = twin_ch->HW_privdata)) { return -EAGAIN; } if (!(fw = twin_hw->firmware) || !fw->len) { return -EAGAIN; } } while (id != 4) { if (inb_p(dev->base_addr + id++) != HICOMX_ID_BYTE) { break; } } if (id != 4) { printk(KERN_ERR "%s: can't find HICOMX at 0x%04x, id[%d] = %02x\n", dev->name, (unsigned int)dev->base_addr, id - 1, inb_p(dev->base_addr + id - 1)); return -1; } id1 = fw->data[OFF_FW_L1_ID]; id2 = fw->data[OFF_FW_L1_ID + 1]; if (id1 != FW_L1_ID_1 || id2 != FW_L1_ID_2_HICOMX) { printk(KERN_ERR "%s: incorrect firmware, load aborted\n", dev->name); return -EAGAIN; } printk(KERN_INFO "%s: Loading HICOMX Layer 1 firmware %s\n", dev->name, (char *)(fw->data + OFF_FW_L1_ID + 2)); id1 = fw->data[OFF_FW_L2_ID]; id2 = fw->data[OFF_FW_L2_ID + 1]; if (id1 == FW_L2_ID_1 && (id2 == 0xc0 || id2 == 0xc1 || id2 == 0xc2)) { printk(KERN_INFO "with Layer 2 code %s\n", (char *)(fw->data + OFF_FW_L2_ID + 2)); } outb_p(board_segment | HICOMX_BOARD_RESET, dev->base_addr); udelay(10); save_flags(flags); cli(); saved=memory_used[mempos]; if(saved) { ((struct comx_channel *)saved->priv)->HW_board_off(saved); } memory_used[mempos]=dev; outb_p(board_segment | HICOMX_ENABLE_BOARD_MEM, dev->base_addr); outb_p(HICOMX_PRG_MEM, dev->base_addr + 1); len = 0; HICOMX_address = (word *)dev->mem_start; while (fw->len > len) { writeb(fw->data[len++], HICOMX_address++); } len = 0; HICOMX_address = (word *)dev->mem_start; while (len != fw->len && (readw(HICOMX_address++) & 0xff) == fw->data[len]) { len++; } if (len != fw->len) { printk(KERN_ERR "%s: error loading firmware: [%d] is 0x%02x " "instead of 0x%02x\n", dev->name, len, readw(HICOMX_address - 1) & 0xff, fw->data[len]); retval=-EAGAIN; goto out; } outb_p(board_segment | HICOMX_BOARD_RESET, dev->base_addr); outb_p(HICOMX_DATA_MEM, dev->base_addr + 1); outb_p(board_segment | HICOMX_ENABLE_BOARD_MEM, dev->base_addr);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -