📄 skystar2.c
字号:
if ( op == 0 ) { WriteRegOp(adapter, 0x208, 2, ~0x00000800, 0); } else { WriteRegOp(adapter, 0x208, 1, 0, 0x00000800); }}//-------------------------------------------------------------------u32 DmaEnableDisableIrq(struct adapter *adapter, u32 flag1, u32 flag2, u32 flag3){ adapter->dma_ctrl = adapter->dma_ctrl & 0x000F0000; if ( flag1 == 0 ) { if ( flag2 == 0 ) adapter->dma_ctrl = adapter->dma_ctrl & ~0x00010000; else adapter->dma_ctrl = adapter->dma_ctrl | 0x00010000; if ( flag3 == 0 ) adapter->dma_ctrl = adapter->dma_ctrl & ~0x00020000; else adapter->dma_ctrl = adapter->dma_ctrl | 0x00020000; } else { if ( flag2 == 0 ) adapter->dma_ctrl = adapter->dma_ctrl & ~0x00040000; else adapter->dma_ctrl = adapter->dma_ctrl | 0x00040000; if ( flag3 == 0 ) adapter->dma_ctrl = adapter->dma_ctrl & ~0x00080000; else adapter->dma_ctrl = adapter->dma_ctrl | 0x00080000; } return adapter->dma_ctrl;}//-------------------------------------------------------------------u32 IrqDmaEnableDisableIrq(struct adapter *adapter, u32 op){ u32 value; value = ReadRegDW(adapter, 0x208) & 0xFFF0FFFF; if ( op != 0 ) value = value | ( adapter->dma_ctrl & 0x000F0000); WriteRegDW(adapter, 0x208, value); return value;}/////////////////////////////////////////////////////////////////////////// FlexCopII has 2 dma channels. DMA1 is used to transfer TS data to// system memory.//// The DMA1 buffer is divided in 2 subbuffers of equal size.// FlexCopII will transfer TS data to one subbuffer, signal an interrupt// when the subbuffer is full and continue fillig the second subbuffer.//// For DMA1:// subbuffer size in 32-bit words is stored in the first 24 bits of// register 0x004. The last 8 bits of register 0x004 contain the number// of subbuffers.// // the first 30 bits of register 0x000 contain the address of the first// subbuffer. The last 2 bits contain 0, when dma1 is disabled and 1,// when dma1 is enabled.//// the first 30 bits of register 0x00C contain the address of the second// subbuffer. the last 2 bits contain 1.//// register 0x008 will contain the address of the subbuffer that was filled// with TS data, when FlexCopII will generate an interrupt.//// For DMA2:// subbuffer size in 32-bit words is stored in the first 24 bits of// register 0x014. The last 8 bits of register 0x014 contain the number// of subbuffers.// // the first 30 bits of register 0x010 contain the address of the first// subbuffer. The last 2 bits contain 0, when dma1 is disabled and 1,// when dma1 is enabled.//// the first 30 bits of register 0x01C contain the address of the second// subbuffer. the last 2 bits contain 1.//// register 0x018 contains the address of the subbuffer that was filled// with TS data, when FlexCopII generates an interrupt.///////////////////////////////////////////////////////////////////////////-------------------------------------------------------------------int DmaInitDMA(struct adapter * adapter, u32 dma_channel){ u32 subbuffers, subbufsize, subbuf0, subbuf1; if ( dma_channel == 0 ) { dprintk("%s: Initializing DMA1 channel\n", __FUNCTION__); subbuffers = 2; subbufsize = ( ( (adapter->DmaQ1.buffer_size / 2) / 4) << 8 ) | subbuffers; subbuf0 = adapter->DmaQ1.bus_addr & 0xFFFFFFFC; subbuf1 = ( (adapter->DmaQ1.bus_addr + adapter->DmaQ1.buffer_size / 2) & 0xFFFFFFFC ) | 1; dprintk("%s: first subbuffer address = 0x%x\n", __FUNCTION__, subbuf0); udelay(1000); WriteRegDW(adapter, 0x000, subbuf0); dprintk("%s: subbuffer size = 0x%x\n", __FUNCTION__, (subbufsize >> 8)*4); udelay(1000); WriteRegDW(adapter, 0x004, subbufsize); dprintk("%s: second subbuffer address = 0x%x\n", __FUNCTION__, subbuf1); udelay(1000); WriteRegDW(adapter, 0x00C, subbuf1); dprintk("%s: counter = 0x%x\n", __FUNCTION__, adapter->DmaQ1.bus_addr & 0xFFFFFFFC ); WriteRegDW(adapter, 0x008, adapter->DmaQ1.bus_addr & 0xFFFFFFFC); udelay(1000); if ( subbuffers == 0 ) DmaEnableDisableIrq(adapter, 0, 1, 0); else DmaEnableDisableIrq(adapter, 0, 1, 1); IrqDmaEnableDisableIrq(adapter, 1); SRAMSetMediaDest(adapter, 1); SRAMSetNetDest(adapter, 1); SRAMSetCaiDest(adapter, 2); SRAMSetCaoDest(adapter, 2); } if ( dma_channel == 1 ) { dprintk("%s: Initializing DMA2 channel\n", __FUNCTION__); subbuffers = 2; subbufsize = ( (( adapter->DmaQ2.buffer_size / 2 ) / 4 ) << 8 ) | subbuffers; subbuf0 = adapter->DmaQ2.bus_addr & 0xFFFFFFFC; subbuf1 = ( ( adapter->DmaQ2.bus_addr + adapter->DmaQ2.buffer_size / 2 ) & 0xFFFFFFFC ) | 1; dprintk("%s: first subbuffer address = 0x%x\n", __FUNCTION__, subbuf0); udelay(1000); WriteRegDW(adapter, 0x010, subbuf0); dprintk("%s: subbuffer size = 0x%x\n", __FUNCTION__, (subbufsize >> 8)*4); udelay(1000); WriteRegDW(adapter, 0x014, subbufsize); dprintk("%s: second buffer address = 0x%x\n", __FUNCTION__, subbuf1); udelay(1000); WriteRegDW(adapter, 0x01C, subbuf1); SRAMSetCaiDest(adapter, 2); } return 0;}//-------------------------------------------------------------------void CtrlEnableReceiveData(struct adapter *adapter, u32 op){ if ( op == 0 ) { WriteRegOp(adapter, 0x208, 2, ~0x00008000, 0); adapter->dma_status = adapter->dma_status & ~0x00000004; } else { WriteRegOp(adapter, 0x208, 1, 0, 0x00008000); adapter->dma_status = adapter->dma_status | 0x00000004; }}///////////////////////////////////////////////////////////////////////////////// bit 0 of dma_mask is set to 1 if dma1 channel has to be enabled/disabled// bit 1 of dma_mask is set to 1 if dma2 channel has to be enabled/disabled//-------------------------------------------------------------------void DmaStartStop0x2102(struct adapter *adapter, u32 dma_mask, u32 start_stop){ u32 dma_enable, dma1_enable, dma2_enable; dprintk("%s: dma_mask=%x\n", __FUNCTION__, dma_mask); if ( start_stop == 1 ) { dprintk("%s: starting dma\n", __FUNCTION__); dma1_enable = 0; dma2_enable = 0; if ( ( ( dma_mask & 1 ) != 0 ) && ( ( adapter->dma_status & 1 ) == 0 ) && ( adapter->DmaQ1.bus_addr != 0 ) ) { adapter->dma_status = adapter->dma_status | 1; dma1_enable = 1; } if ( ( ( dma_mask & 2 ) != 0 ) && ( ( adapter->dma_status & 2 ) == 0 ) && ( adapter->DmaQ2.bus_addr != 0 ) ) { adapter->dma_status = adapter->dma_status | 2; dma2_enable = 1; } // enable dma1 and dma2 if ( ( dma1_enable == 1 ) && ( dma2_enable == 1 ) ) { WriteRegDW(adapter, 0x000, adapter->DmaQ1.bus_addr | 1 ); WriteRegDW(adapter, 0x00C, ( adapter->DmaQ1.bus_addr + adapter->DmaQ1.buffer_size/2 ) | 1); WriteRegDW(adapter, 0x010, adapter->DmaQ2.bus_addr | 1); CtrlEnableReceiveData(adapter, 1); return; } // enable dma1 if ( ( dma1_enable == 1 ) && ( dma2_enable == 0 ) ) { WriteRegDW(adapter, 0x000, adapter->DmaQ1.bus_addr | 1); WriteRegDW(adapter, 0x00C, ( adapter->DmaQ1.bus_addr + adapter->DmaQ1.buffer_size/2 ) | 1 ); CtrlEnableReceiveData(adapter, 1); return; } // enable dma2 if ( ( dma1_enable == 0 ) && ( dma2_enable == 1 ) ) { WriteRegDW(adapter, 0x010, adapter->DmaQ2.bus_addr | 1); CtrlEnableReceiveData(adapter, 1); return; } // start dma if ( ( dma1_enable == 0 ) && ( dma2_enable == 0 ) ) { CtrlEnableReceiveData(adapter, 1); return; } } else { dprintk("%s: stoping dma\n", __FUNCTION__); dma_enable = adapter->dma_status & 0x00000003; if ( ( ( dma_mask & 1 ) != 0 ) && ( ( adapter->dma_status & 1 ) != 0 ) ) { dma_enable = dma_enable & 0xFFFFFFFE; } if ( ( ( dma_mask & 2 ) != 0 ) && ( ( adapter->dma_status & 2 ) != 0 ) ) { dma_enable = dma_enable & 0xFFFFFFFD; } //stop dma if ( ( dma_enable == 0 ) && ( ( adapter->dma_status & 4 ) != 0 ) ) { CtrlEnableReceiveData(adapter, 0); udelay(3000); } //disable dma1 if ( ( ( dma_mask & 1 ) != 0 ) && ( ( adapter->dma_status & 1 ) != 0 ) && ( adapter->DmaQ1.bus_addr != 0 ) ) { WriteRegDW(adapter, 0x000, adapter->DmaQ1.bus_addr); WriteRegDW(adapter, 0x00C, ( adapter->DmaQ1.bus_addr + adapter->DmaQ1.buffer_size/2 ) | 1 ); adapter->dma_status = adapter->dma_status & ~0x00000001; } //disable dma2 if ( ( ( dma_mask & 2 ) != 0 ) && ( ( adapter->dma_status & 2 ) != 0 ) && ( adapter->DmaQ2.bus_addr != 0 ) ) { WriteRegDW(adapter, 0x010, adapter->DmaQ2.bus_addr); adapter->dma_status = adapter->dma_status & ~0x00000002; } }}//-------------------------------------------------------------------void OpenStream(struct adapter * adapter, u32 pid){ u32 dma_mask; if ( adapter->capturing == 0 ) adapter->capturing = 1; FilterEnableMaskFilter(adapter, 1); AddPID(adapter, pid); dprintk("%s: adapter->dma_status=%x\n", __FUNCTION__, adapter->dma_status); if ( ( adapter->dma_status & 7 ) != 7 ) { dma_mask = 0; if ( ( ( adapter->dma_status & 0x10000000 ) != 0 ) && ( ( adapter->dma_status & 1 ) == 0 ) ) { dma_mask = dma_mask | 1; adapter->DmaQ1.head = 0; adapter->DmaQ1.tail = 0; memset(adapter->DmaQ1.buffer, 0, adapter->DmaQ1.buffer_size); } if ( ( ( adapter->dma_status & 0x20000000 ) != 0 ) && ( ( adapter->dma_status & 2 ) == 0 ) ) { dma_mask = dma_mask | 2; adapter->DmaQ2.head = 0; adapter->DmaQ2.tail = 0; } if ( dma_mask != 0 ) { IrqDmaEnableDisableIrq(adapter, 1); DmaStartStop0x2102(adapter, dma_mask, 1); } }}//-------------------------------------------------------------------void CloseStream(struct adapter * adapter, u32 pid){ u32 dma_mask; if ( adapter->capturing != 0 ) adapter->capturing = 0; dprintk("%s: dma_status=%x\n", __FUNCTION__, adapter->dma_status); dma_mask = 0; if ( ( adapter->dma_status & 1 ) != 0 ) dma_mask = dma_mask | 0x00000001; if ( ( adapter->dma_status & 2 ) != 0 ) dma_mask = dma_mask | 0x00000002; if ( dma_mask != 0 ) { DmaStartStop0x2102(adapter, dma_mask, 0); } RemovePID(adapter, pid); }//-------------------------------------------------------------------u32 InterruptServiceDMA1(struct adapter *adapter){ struct dvb_demux * dvbdmx = &adapter->demux; struct packet_header_t packet_header; int nCurDmaCounter; u32 nNumBytesParsed; u32 nNumNewBytesTransferred; u32 dwDefaultPacketSize = 188; u8 gbTmpBuffer[188]; u8 *pbDMABufCurPos; nCurDmaCounter = readl(adapter->io_mem + 0x008) - adapter->DmaQ1.bus_addr; nCurDmaCounter = ( nCurDmaCounter / dwDefaultPacketSize ) * dwDefaultPacketSize; if ( ( nCurDmaCounter < 0 ) || ( nCurDmaCounter > adapter->DmaQ1.buffer_size) ) { dprintk("%s: dma counter outside dma buffer\n", __FUNCTION__); return 1; } adapter->DmaQ1.head = nCurDmaCounter; if ( adapter->DmaQ1.tail <= nCurDmaCounter ) { nNumNewBytesTransferred = nCurDmaCounter - adapter->DmaQ1.tail; } else { nNumNewBytesTransferred = (adapter->DmaQ1.buffer_size - adapter->DmaQ1.tail) + nCurDmaCounter; } // dprintk("%s: nCurDmaCounter = %d\n" , __FUNCTION__, nCurDmaCounter); // dprintk("%s: DmaQ1.tail = %d\n" , __FUNCTION__, adapter->DmaQ1.tail); // dprintk("%s: BytesTransferred = %d\n" , __FUNCTION__, nNumNewBytesTransferred); if ( nNumNewBytesTransferred < dwDefaultPacketSize ) return 0; nNumBytesParsed = 0; while ( nNumBytesParsed < nNumNewBytesTransferred ) { pbDMABufCurPos = adapter->DmaQ1.buffer + adapter->DmaQ1.tail; if ( adapter->DmaQ1.buffer + adapter->DmaQ1.buffer_size < adapter->DmaQ1.buffer + adapter->DmaQ1.tail + 188) { memcpy(gbTmpBuffer, adapter->DmaQ1.buffer + adapter->DmaQ1.tail, adapter->DmaQ1.buffer_size - adapter->DmaQ1.tail); memcpy(gbTmpBuffer + (adapter->DmaQ1.buffer_size - adapter->DmaQ1.tail), adapter->DmaQ1.buffer, ( 188 - ( adapter->DmaQ1.buffer_size - adapter->DmaQ1.tail ) ) ); pbDMABufCurPos = gbTmpBuffer; } if ( adapter->capturing != 0 ) { u32 * dq = (u32 *)pbDMABufCurPos; packet_header.sync_byte = *dq & 0x000000FF; packet_header.transport_error_indicator = *dq & 0x00008000; packet_header.payload_unit_start_indicator = *dq & 0x00004000; packet_header.transport_priority = *dq & 0x00002000; packet_header.pid = ( ( *dq & 0x00FF0000 ) >> 0x10 ) | ( *dq & 0x00001F00 ); packet_header.transport_scrambling_control = *dq >> 0x1E; packet_header.adaptation_field_control = ( *dq & 0x30000000 ) >> 0x1C; packet_header.continuity_counter = ( *dq & 0x0F000000 ) >> 0x18; if ( ( packet_header.sync_byte == 0x47 ) && ( packet_header.transport_error_indicator == 0 ) && ( packet_header.pid != 0x1FFF ) ) { if ( CheckPID(adapter, packet_header.pid & 0x0000FFFF) != 0 ) { dvb_dmx_swfilter_packets(dvbdmx, pbDMABufCurPos, dwDefaultPacketSize/188); } else { dprintk("%s: pid=%x\n", __FUNCTION__, packet_header.pid); } } } nNumBytesParsed = nNumBytesParsed + dwDefaultPacketSize; adapter->DmaQ1.tail = adapter->DmaQ1.tail + dwDefaultPacketSize; if ( adapter->DmaQ1.tail >= adapter->DmaQ1.buffer_size ) adapter->DmaQ1.tail = adapter->DmaQ1.tail - adapter->DmaQ1.buffer_size; }; return 1;}//-------------------------------------------------------------------void InterruptServiceDMA2(struct adapter *adapter){ printk("%s:\n", __FUNCTION__);}//-------------------------------------------------------------------void isr(int irq, void *dev_id, struct pt_regs *regs){ struct adapter *tmp = dev_id; u32 value; spin_lock_irq(&tmp->lock); while ( ( ( value = ReadRegDW(tmp, 0x20C) ) & 0x0F ) != 0 ) { if ( ( value & 0x03 ) != 0 ) InterruptServiceDMA1(tmp); if ( ( value & 0x0C ) != 0 ) InterruptServiceDMA2(tmp); } spin_unlock_irq(&tmp->lock);}//-------------------------------------------------------------------void InitDmaQueue(struct adapter *adapter){ dma_addr_t dma_addr; if ( adapter->DmaQ1.buffer != 0 ) return; adapter->DmaQ1.head = 0; adapter->DmaQ1.tail = 0; adapter->DmaQ1.buffer = 0; adapter->DmaQ1.buffer = pci_alloc_consistent(adapter->pdev, SizeOfBufDMA1 + 0x80, &dma_addr); if ( adapter->DmaQ1.buffer != 0 ) { memset(adapter->DmaQ1.buffer, 0, SizeOfBufDMA1); adapter->DmaQ1.bus_addr = dma_addr; adapter->DmaQ1.buffer_size = SizeOfBufDMA1; DmaInitDMA(adapter, 0); adapter->dma_status = adapter->dma_status | 0x10000000; dprintk("%s: allocated dma buffer at 0x%x, length=%d\n", __FUNCTION__, (int)adapter->DmaQ1.buffer, SizeOfBufDMA1); } else { adapter->dma_status = adapter->dma_status & ~0x10000000; } if ( adapter->DmaQ2.buffer != 0 ) return; adapter->DmaQ2.head = 0; adapter->DmaQ2.tail = 0; adapter->DmaQ2.buffer = 0; adapter->DmaQ2.buffer = pci_alloc_consistent(adapter->pdev, SizeOfBufDMA2 + 0x80, &dma_addr); if ( adapter->DmaQ2.buffer != 0 ) { memset(adapter->DmaQ2.buffer, 0, SizeOfBufDMA2); adapter->DmaQ2.bus_addr = dma_addr; adapter->DmaQ2.buffer_size = SizeOfBufDMA2; DmaInitDMA(adapter, 1);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -