📄 ohci1394.c
字号:
} ohci->ir_context = alloc_dma_rcv_ctx(ohci, 2, IR_NUM_DESC, IR_BUF_SIZE, IR_SPLIT_BUF_SIZE, OHCI1394_IsoRcvContextControlSet, OHCI1394_IsoRcvContextControlClear, OHCI1394_IsoRcvCommandPtr); if (ohci->ir_context == NULL) { FAIL("failed to allocate IR context"); } ohci->ISO_channel_usage= 0; spin_lock_init(&ohci->IR_channel_lock); if (!request_irq(dev->irq, ohci_irq_handler, SA_SHIRQ, OHCI1394_DRIVER_NAME, ohci)) { PRINT(KERN_INFO, ohci->id, "allocated interrupt %d", dev->irq); } else { FAIL("failed to allocate shared interrupt %d", dev->irq); } ohci_init_config_rom(ohci); DBGMSG(ohci->id, "The 1st byte at offset 0x404 is: 0x%02x", *((char *)ohci->csr_config_rom_cpu+4)); return 0;#undef FAIL}#ifdef CONFIG_PROC_FS#define SR(fmt, reg0, reg1, reg2)\p += sprintf(p,fmt,reg_read(ohci, reg0),\ reg_read(ohci, reg1),reg_read(ohci, reg2));static int ohci_get_status(char *buf){ struct ti_ohci *ohci=&cards[0]; struct hpsb_host *host=ohci->host; char *p=buf; //unsigned char phyreg; //int i, nports; int i; struct dma_rcv_ctx *d=NULL; struct dma_trm_ctx *dt=NULL; p += sprintf(p,"IEEE-1394 OHCI Driver status report:\n"); p += sprintf(p," bus number: 0x%x Node ID: 0x%x\n", (reg_read(ohci, OHCI1394_NodeID) & 0xFFC0) >> 6, reg_read(ohci, OHCI1394_NodeID)&0x3f);#if 0 p += sprintf(p," hardware version %d.%d GUID_ROM is %s\n\n", (reg_read(ohci, OHCI1394_Version) & 0xFF0000) >>16, reg_read(ohci, OHCI1394_Version) & 0xFF, (reg_read(ohci, OHCI1394_Version) & 0x01000000) ? "set" : "clear");#endif p += sprintf(p,"\n### Host data ###\n"); p += sprintf(p,"node_count: %8d ",host->node_count); p += sprintf(p,"node_id : %08X\n",host->node_id); p += sprintf(p,"irm_id : %08X ",host->irm_id); p += sprintf(p,"busmgr_id : %08X\n",host->busmgr_id); p += sprintf(p,"%s %s %s\n", host->initialized ? "initialized" : "", host->in_bus_reset ? "in_bus_reset" : "", host->attempt_root ? "attempt_root" : ""); p += sprintf(p,"%s %s %s %s\n", host->is_root ? "root" : "", host->is_cycmst ? "cycle_master" : "", host->is_irm ? "iso_res_mgr" : "", host->is_busmgr ? "bus_mgr" : ""); p += sprintf(p,"\n---Iso Receive DMA---\n"); d = ohci->ir_context;#if 0 for (i=0; i<d->num_desc; i++) { p += sprintf(p, "IR buf[%d] : %p prg[%d]: %p\n", i, d->buf[i], i, d->prg[i]); }#endif p += sprintf(p, "Current buf: %d offset: %d\n", d->buf_ind,d->buf_offset); p += sprintf(p,"\n---Async Receive DMA---\n"); d = ohci->ar_req_context;#if 0 for (i=0; i<d->num_desc; i++) { p += sprintf(p, "AR req buf[%d] : %p prg[%d]: %p\n", i, d->buf[i], i, d->prg[i]); }#endif p += sprintf(p, "Ar req current buf: %d offset: %d\n", d->buf_ind,d->buf_offset); d = ohci->ar_resp_context;#if 0 for (i=0; i<d->num_desc; i++) { p += sprintf(p, "AR resp buf[%d] : %p prg[%d]: %p\n", i, d->buf[i], i, d->prg[i]); }#endif p += sprintf(p, "AR resp current buf: %d offset: %d\n", d->buf_ind,d->buf_offset); p += sprintf(p,"\n---Async Transmit DMA---\n"); dt = ohci->at_req_context; p += sprintf(p, "AT req prg: %d sent: %d free: %d branchAddrPtr: %p\n", dt->prg_ind, dt->sent_ind, dt->free_prgs, dt->branchAddrPtr); p += sprintf(p, "AT req queue: first: %p last: %p\n", dt->fifo_first, dt->fifo_last); dt = ohci->at_resp_context;#if 0 for (i=0; i<dt->num_desc; i++) { p += sprintf(p, "------- AT resp prg[%02d] ------\n",i); p += sprintf(p, "%p: control : %08x\n", &(dt->prg[i].begin.control), dt->prg[i].begin.control); p += sprintf(p, "%p: address : %08x\n", &(dt->prg[i].begin.address), dt->prg[i].begin.address); p += sprintf(p, "%p: brancAddr: %08x\n", &(dt->prg[i].begin.branchAddress), dt->prg[i].begin.branchAddress); p += sprintf(p, "%p: status : %08x\n", &(dt->prg[i].begin.status), dt->prg[i].begin.status); p += sprintf(p, "%p: header[0]: %08x\n", &(dt->prg[i].data[0]), dt->prg[i].data[0]); p += sprintf(p, "%p: header[1]: %08x\n", &(dt->prg[i].data[1]), dt->prg[i].data[1]); p += sprintf(p, "%p: header[2]: %08x\n", &(dt->prg[i].data[2]), dt->prg[i].data[2]); p += sprintf(p, "%p: header[3]: %08x\n", &(dt->prg[i].data[3]), dt->prg[i].data[3]); p += sprintf(p, "%p: control : %08x\n", &(dt->prg[i].end.control), dt->prg[i].end.control); p += sprintf(p, "%p: address : %08x\n", &(dt->prg[i].end.address), dt->prg[i].end.address); p += sprintf(p, "%p: brancAddr: %08x\n", &(dt->prg[i].end.branchAddress), dt->prg[i].end.branchAddress); p += sprintf(p, "%p: status : %08x\n", &(dt->prg[i].end.status), dt->prg[i].end.status); }#endif p += sprintf(p, "AR resp prg: %d sent: %d free: %d" " branchAddrPtr: %p\n", dt->prg_ind, dt->sent_ind, dt->free_prgs, dt->branchAddrPtr); p += sprintf(p, "AT resp queue: first: %p last: %p\n", dt->fifo_first, dt->fifo_last); /* ----- Register Dump ----- */ p += sprintf(p,"\n### HC Register dump ###\n"); SR("Version : %08x GUID_ROM : %08x ATRetries : %08x\n", OHCI1394_Version, OHCI1394_GUID_ROM, OHCI1394_ATRetries); SR("CSRData : %08x CSRCompData : %08x CSRControl : %08x\n", OHCI1394_CSRData, OHCI1394_CSRCompareData, OHCI1394_CSRControl); SR("ConfigROMhdr: %08x BusID : %08x BusOptions : %08x\n", OHCI1394_ConfigROMhdr, OHCI1394_BusID, OHCI1394_BusOptions); SR("GUIDHi : %08x GUIDLo : %08x ConfigROMmap: %08x\n", OHCI1394_GUIDHi, OHCI1394_GUIDLo, OHCI1394_ConfigROMmap); SR("PtdWrAddrLo : %08x PtdWrAddrHi : %08x VendorID : %08x\n", OHCI1394_PostedWriteAddressLo, OHCI1394_PostedWriteAddressHi, OHCI1394_VendorID); SR("HCControl : %08x SelfIDBuffer: %08x SelfIDCount : %08x\n", OHCI1394_HCControlSet, OHCI1394_SelfIDBuffer, OHCI1394_SelfIDCount); SR("IRMuChMaskHi: %08x IRMuChMaskLo: %08x IntEvent : %08x\n", OHCI1394_IRMultiChanMaskHiSet, OHCI1394_IRMultiChanMaskLoSet, OHCI1394_IntEventSet); SR("IntMask : %08x IsoXmIntEvnt: %08x IsoXmIntMask: %08x\n", OHCI1394_IntMaskSet, OHCI1394_IsoXmitIntEventSet, OHCI1394_IsoXmitIntMaskSet); SR("IsoRcvIntEvt: %08x IsoRcvIntMsk: %08x FairnessCtrl: %08x\n", OHCI1394_IsoRecvIntEventSet, OHCI1394_IsoRecvIntMaskSet, OHCI1394_FairnessControl); SR("LinkControl : %08x NodeID : %08x PhyControl : %08x\n", OHCI1394_LinkControlSet, OHCI1394_NodeID, OHCI1394_PhyControl); SR("IsoCyclTimer: %08x AsRqFilterHi: %08x AsRqFilterLo: %08x\n", OHCI1394_IsochronousCycleTimer, OHCI1394_AsReqFilterHiSet, OHCI1394_AsReqFilterLoSet); SR("PhyReqFiltHi: %08x PhyReqFiltLo: %08x PhyUpperBnd : %08x\n", OHCI1394_PhyReqFilterHiSet, OHCI1394_PhyReqFilterLoSet, OHCI1394_PhyUpperBound); SR("AsRqTrCxtCtl: %08x AsRqTrCmdPtr: %08x AsRsTrCtxCtl: %08x\n", OHCI1394_AsReqTrContextControlSet, OHCI1394_AsReqTrCommandPtr, OHCI1394_AsRspTrContextControlSet); SR("AsRsTrCmdPtr: %08x AsRqRvCtxCtl: %08x AsRqRvCmdPtr: %08x\n", OHCI1394_AsRspTrCommandPtr, OHCI1394_AsReqRcvContextControlSet, OHCI1394_AsReqRcvCommandPtr); SR("AsRsRvCtxCtl: %08x AsRsRvCmdPtr: %08x IntEvent : %08x\n", OHCI1394_AsRspRcvContextControlSet, OHCI1394_AsRspRcvCommandPtr, OHCI1394_IntEventSet); for (i=0;i<ohci->nb_iso_rcv_ctx;i++) { p += sprintf(p,"IsoRCtxCtl%02d: %08x IsoRCmdPtr%02d: %08x" " IsoRCxtMch%02d: %08x\n", i, reg_read(ohci, OHCI1394_IsoRcvContextControlSet+32*i), i,reg_read(ohci, OHCI1394_IsoRcvCommandPtr+32*i), i,reg_read(ohci, OHCI1394_IsoRcvContextMatch+32*i)); } for (i=0;i<ohci->nb_iso_xmit_ctx;i++) { p += sprintf(p,"IsoTCtxCtl%02d: %08x IsoTCmdPtr%02d: %08x\n", i, reg_read(ohci, OHCI1394_IsoXmitContextControlSet+32*i), i,reg_read(ohci,OHCI1394_IsoXmitCommandPtr+32*i)); }#if 0 p += sprintf(p,"\n### Phy Register dump ###\n"); phyreg=get_phy_reg(ohci,1); p += sprintf(p,"offset: %d val: 0x%02x -> RHB: %d" "IBR: %d Gap_count: %d\n", 1,phyreg,(phyreg&0x80) != 0, (phyreg&0x40) !=0, phyreg&0x3f); phyreg=get_phy_reg(ohci,2); nports=phyreg&0x1f; p += sprintf(p,"offset: %d val: 0x%02x -> SPD: %d" " E : %d Ports : %2d\n", 2,phyreg, (phyreg&0xC0)>>6, (phyreg&0x20) !=0, nports); for (i=0;i<nports;i++) { phyreg=get_phy_reg(ohci,3+i); p += sprintf(p,"offset: %d val: 0x%02x -> [port %d]" " TPA: %d TPB: %d | %s %s\n", 3+i,phyreg, i, (phyreg&0xC0)>>6, (phyreg&0x30)>>4, (phyreg&0x08) ? "child" : "parent", (phyreg&0x04) ? "connected" : "disconnected"); } phyreg=get_phy_reg(ohci,3+i); p += sprintf(p,"offset: %d val: 0x%02x -> ENV: %s Reg_count: %d\n", 3+i,phyreg, (((phyreg&0xC0)>>6)==0) ? "backplane" : (((phyreg&0xC0)>>6)==1) ? "cable" : "reserved", phyreg&0x3f);#endif return p - buf;}static int ohci1394_read_proc(char *page, char **start, off_t off, int count, int *eof, void *data){ int len = ohci_get_status(page); if (len <= off+count) *eof = 1; *start = page + off; len -= off; if (len>count) len = count; if (len<0) len = 0; return len;}#if LINUX_VERSION_CODE < KERNEL_VERSION(2,3,0)struct proc_dir_entry *ohci_proc_entry;#endif /* LINUX_VERSION_CODE */#endif /* CONFIG_PROC_FS */static void remove_card(struct ti_ohci *ohci){ /* * Reset the board properly before leaving * Daniel Kobras <daniel.kobras@student.uni-tuebingen.de> */ ohci_soft_reset(ohci); /* Free AR dma */ free_dma_rcv_ctx(&ohci->ar_req_context); free_dma_rcv_ctx(&ohci->ar_resp_context); /* Free AT dma */ free_dma_trm_ctx(&ohci->at_req_context); free_dma_trm_ctx(&ohci->at_resp_context); /* Free IR dma */ free_dma_rcv_ctx(&ohci->ir_context); /* Free self-id buffer */ if (ohci->selfid_buf_cpu) pci_free_consistent(ohci->dev, 2048, ohci->selfid_buf_cpu, ohci->selfid_buf_bus); /* Free config rom */ if (ohci->csr_config_rom_cpu) pci_free_consistent(ohci->dev, sizeof(ohci_csr_rom), ohci->csr_config_rom_cpu, ohci->csr_config_rom_bus); /* Free the IRQ */ free_irq(ohci->dev->irq, ohci); if (ohci->registers) iounmap(ohci->registers); ohci->state = 0;}static int init_driver(){ struct pci_dev *dev = NULL; int success = 0;#if USE_DEVICE int i;#endif if (num_of_cards) { PRINT_G(KERN_DEBUG, __PRETTY_FUNCTION__ " called again"); return 0; } PRINT_G(KERN_INFO, "looking for Ohci1394 cards");#if USE_DEVICE for (i = 0; supported_chips[i][0] != -1; i++) { while ((dev = pci_find_device(supported_chips[i][0], supported_chips[i][1], dev)) != NULL) { if (add_card(dev) == 0) { success = 1; } } }#else while ((dev = pci_find_class(PCI_CLASS_FIREWIRE_OHCI, dev)) != NULL ) { if (add_card(dev) == 0) success = 1; }#endif /* USE_DEVICE */ if (success == 0) { PRINT_G(KERN_WARNING, "no operable Ohci1394 cards found"); return -ENXIO; }#ifdef CONFIG_PROC_FS#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,0) create_proc_read_entry ("ohci1394", 0, NULL, ohci1394_read_proc, NULL);#else if ((ohci_proc_entry = create_proc_entry("ohci1394", 0, NULL))) ohci_proc_entry->read_proc = ohci1394_read_proc;#endif#endif return 0;}static size_t get_ohci_rom(struct hpsb_host *host, const quadlet_t **ptr){ struct ti_ohci *ohci=host->hostdata; DBGMSG(ohci->id, "request csr_rom address: %08X", (u32)ohci->csr_config_rom_cpu); *ptr = ohci->csr_config_rom_cpu; return sizeof(ohci_csr_rom);}static quadlet_t ohci_hw_csr_reg(struct hpsb_host *host, int reg, quadlet_t data, quadlet_t compare){ struct ti_ohci *ohci=host->hostdata; int timeout = 255; reg_write(ohci, OHCI1394_CSRData, data); reg_write(ohci, OHCI1394_CSRCompareData, compare); reg_write(ohci, OHCI1394_CSRControl, reg&0x3); while (timeout-- && !(reg_read(ohci, OHCI1394_CSRControl)&0x80000000)); if (!timeout) PRINT(KERN_ERR, ohci->id, __FUNCTION__ "timeout!"); return reg_read(ohci, OHCI1394_CSRData);} struct hpsb_host_template *get_ohci_template(void){ static struct hpsb_host_template tmpl; static int initialized = 0; if (!initialized) { /* Initialize by field names so that a template structure * reorganization does not influence this code. */ tmpl.name = "ohci1394"; tmpl.detect_hosts = ohci_detect; tmpl.initialize_host = ohci_initialize; tmpl.release_host = ohci_remove; tmpl.get_rom = get_ohci_rom; tmpl.transmit_packet = ohci_transmit; tmpl.devctl = ohci_devctl; tmpl.hw_csr_reg = ohci_hw_csr_reg; initialized = 1; } return &tmpl;}void ohci1394_stop_context(struct ti_ohci *ohci, int reg, char *msg){ int i=0; /* stop the channel program if it's still running */ reg_write(ohci, reg, 0x8000); /* Wait until it effectively stops */ while (reg_read(ohci, reg) & 0x400) { i++; if (i>5000) { PRINT(KERN_ERR, ohci->id, "runaway loop while stopping context..."); break; } } if (msg) PRINT(KERN_ERR, ohci->id, "%s\n dma prg stopped\n", msg);}struct ti_ohci *ohci1394_get_struct(int card_num){ if (card_num>=0 && card_num<num_of_cards) return &cards[card_num]; return NULL;}int ohci1394_register_video(struct ti_ohci *ohci, struct video_template *tmpl){ if (ohci->video_tmpl) return -ENFILE; ohci->video_tmpl = tmpl; MOD_INC_USE_COUNT; return 0;} void ohci1394_unregister_video(struct ti_ohci *ohci, struct video_template *tmpl){ if (ohci->video_tmpl != tmpl) { PRINT(KERN_ERR, ohci->id, "Trying to unregister wrong video device"); } else { ohci->video_tmpl = NULL; MOD_DEC_USE_COUNT; }}#if 0int ohci_compare_swap(struct ti_ohci *ohci, quadlet_t *data, quadlet_t compare, int sel){ int timeout = 255; reg_write(ohci, OHCI1394_CSRData, *data); reg_write(o
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -