📄 io.c
字号:
e->XOffset = 0 ;/* * queue this entity in the adapter request queue */ IoAdapter->e_tbl[i].next = 0 ; if ( IoAdapter->head ) { IoAdapter->e_tbl[IoAdapter->tail].next = i ; IoAdapter->tail = i ; } else { IoAdapter->head = i ; IoAdapter->tail = i ; }/* * queue the DPC to process the request */ diva_os_schedule_soft_isr (&IoAdapter->req_soft_isr); diva_os_leave_spin_lock (&IoAdapter->data_spin_lock, &irql, "data_req");}/* --------------------------------------------------------------------- Main DPC routine --------------------------------------------------------------------- */void DIDpcRoutine (struct _diva_os_soft_isr* psoft_isr, void* Context) { PISDN_ADAPTER IoAdapter = (PISDN_ADAPTER)Context ; ADAPTER* a = &IoAdapter->a ; diva_os_atomic_t* pin_dpc = &IoAdapter->in_dpc; if (diva_os_atomic_increment (pin_dpc) == 1) { do { if ( IoAdapter->tst_irq (a) ) { if ( !IoAdapter->Unavailable ) IoAdapter->dpc (a) ; IoAdapter->clr_irq (a) ; } IoAdapter->out (a) ; } while (diva_os_atomic_decrement (pin_dpc) > 0); /* ---------------------------------------------------------------- Look for XLOG request (cards with indirect addressing) ---------------------------------------------------------------- */ if (IoAdapter->pcm_pending) { struct pc_maint *pcm; diva_os_spin_lock_magic_t OldIrql ; diva_os_enter_spin_lock (&IoAdapter->data_spin_lock, &OldIrql, "data_dpc"); pcm = (struct pc_maint *)IoAdapter->pcm_data; switch (IoAdapter->pcm_pending) { case 1: /* ask card for XLOG */ a->ram_out (a, &IoAdapter->pcm->rc, 0) ; a->ram_out (a, &IoAdapter->pcm->req, pcm->req) ; IoAdapter->pcm_pending = 2; break; case 2: /* Try to get XLOG from the card */ if ((int)(a->ram_in (a, &IoAdapter->pcm->rc))) { a->ram_in_buffer (a, IoAdapter->pcm, pcm, sizeof(*pcm)) ; IoAdapter->pcm_pending = 3; } break; case 3: /* let XDI recovery XLOG */ break; } diva_os_leave_spin_lock (&IoAdapter->data_spin_lock, &OldIrql, "data_dpc"); } /* ---------------------------------------------------------------- */ }}/* -------------------------------------------------------------------------- XLOG interface -------------------------------------------------------------------------- */static voidpcm_req (PISDN_ADAPTER IoAdapter, ENTITY *e){ diva_os_spin_lock_magic_t OldIrql ; int i, rc ; ADAPTER *a = &IoAdapter->a ; struct pc_maint *pcm = (struct pc_maint *)&e->Ind ;/* * special handling of I/O based card interface * the memory access isn't an atomic operation ! */ if ( IoAdapter->Properties.Card == CARD_MAE ) { diva_os_enter_spin_lock (&IoAdapter->data_spin_lock, &OldIrql, "data_pcm_1"); IoAdapter->pcm_data = (void *)pcm; IoAdapter->pcm_pending = 1; diva_os_schedule_soft_isr (&IoAdapter->req_soft_isr); diva_os_leave_spin_lock (&IoAdapter->data_spin_lock, &OldIrql, "data_pcm_1"); for ( rc = 0, i = (IoAdapter->trapped ? 3000 : 250) ; !rc && (i > 0) ; --i ) { diva_os_sleep (1) ; if (IoAdapter->pcm_pending == 3) { diva_os_enter_spin_lock (&IoAdapter->data_spin_lock, &OldIrql, "data_pcm_3"); IoAdapter->pcm_pending = 0; IoAdapter->pcm_data = NULL ; diva_os_leave_spin_lock (&IoAdapter->data_spin_lock, &OldIrql, "data_pcm_3"); return ; } diva_os_enter_spin_lock (&IoAdapter->data_spin_lock, &OldIrql, "data_pcm_2"); diva_os_schedule_soft_isr (&IoAdapter->req_soft_isr); diva_os_leave_spin_lock (&IoAdapter->data_spin_lock, &OldIrql, "data_pcm_2"); } diva_os_enter_spin_lock (&IoAdapter->data_spin_lock, &OldIrql, "data_pcm_4"); IoAdapter->pcm_pending = 0; IoAdapter->pcm_data = NULL ; diva_os_leave_spin_lock (&IoAdapter->data_spin_lock, &OldIrql, "data_pcm_4"); goto Trapped ; }/* * memory based shared ram is accessible from different * processors without disturbing concurrent processes. */ a->ram_out (a, &IoAdapter->pcm->rc, 0) ; a->ram_out (a, &IoAdapter->pcm->req, pcm->req) ; for ( i = (IoAdapter->trapped ? 3000 : 250) ; --i > 0 ; ) { diva_os_sleep (1) ; rc = (int)(a->ram_in (a, &IoAdapter->pcm->rc)) ; if ( rc ) { a->ram_in_buffer (a, IoAdapter->pcm, pcm, sizeof(*pcm)) ; return ; } }Trapped: if ( IoAdapter->trapFnc ) { int trapped = IoAdapter->trapped; IoAdapter->trapFnc (IoAdapter) ; /* Firs trap, also notify user if supported */ if (!trapped && IoAdapter->trapped && IoAdapter->os_trap_nfy_Fnc) { (*(IoAdapter->os_trap_nfy_Fnc))(IoAdapter, IoAdapter->ANum); } }}/*------------------------------------------------------------------*//* ram access functions for memory mapped cards *//*------------------------------------------------------------------*/byte mem_in (ADAPTER *a, void *addr){ byte val; volatile byte __iomem *Base = DIVA_OS_MEM_ATTACH_RAM((PISDN_ADAPTER)a->io); val = READ_BYTE(Base + (unsigned long)addr); DIVA_OS_MEM_DETACH_RAM((PISDN_ADAPTER)a->io, Base); return (val);}word mem_inw (ADAPTER *a, void *addr){ word val; volatile byte __iomem *Base = DIVA_OS_MEM_ATTACH_RAM((PISDN_ADAPTER)a->io); val = READ_WORD((Base + (unsigned long)addr)); DIVA_OS_MEM_DETACH_RAM((PISDN_ADAPTER)a->io, Base); return (val);}void mem_in_dw (ADAPTER *a, void *addr, dword* data, int dwords){ volatile byte __iomem * Base = DIVA_OS_MEM_ATTACH_RAM((PISDN_ADAPTER)a->io); while (dwords--) { *data++ = READ_DWORD((Base + (unsigned long)addr)); addr+=4; } DIVA_OS_MEM_DETACH_RAM((PISDN_ADAPTER)a->io, Base);}void mem_in_buffer (ADAPTER *a, void *addr, void *buffer, word length){ volatile byte __iomem *Base = DIVA_OS_MEM_ATTACH_RAM((PISDN_ADAPTER)a->io); memcpy_fromio(buffer, (Base + (unsigned long)addr), length); DIVA_OS_MEM_DETACH_RAM((PISDN_ADAPTER)a->io, Base);}void mem_look_ahead (ADAPTER *a, PBUFFER *RBuffer, ENTITY *e){ PISDN_ADAPTER IoAdapter = (PISDN_ADAPTER)a->io ; IoAdapter->RBuffer.length = mem_inw (a, &RBuffer->length) ; mem_in_buffer (a, RBuffer->P, IoAdapter->RBuffer.P, IoAdapter->RBuffer.length) ; e->RBuffer = (DBUFFER *)&IoAdapter->RBuffer ;}void mem_out (ADAPTER *a, void *addr, byte data){ volatile byte __iomem *Base = DIVA_OS_MEM_ATTACH_RAM((PISDN_ADAPTER)a->io); WRITE_BYTE(Base + (unsigned long)addr, data); DIVA_OS_MEM_DETACH_RAM((PISDN_ADAPTER)a->io, Base);}void mem_outw (ADAPTER *a, void *addr, word data){ volatile byte __iomem * Base = DIVA_OS_MEM_ATTACH_RAM((PISDN_ADAPTER)a->io); WRITE_WORD((Base + (unsigned long)addr), data); DIVA_OS_MEM_DETACH_RAM((PISDN_ADAPTER)a->io, Base);}void mem_out_dw (ADAPTER *a, void *addr, const dword* data, int dwords){ volatile byte __iomem * Base = DIVA_OS_MEM_ATTACH_RAM((PISDN_ADAPTER)a->io); while (dwords--) { WRITE_DWORD((Base + (unsigned long)addr), *data); addr+=4; data++; } DIVA_OS_MEM_DETACH_RAM((PISDN_ADAPTER)a->io, Base);}void mem_out_buffer (ADAPTER *a, void *addr, void *buffer, word length){ volatile byte __iomem * Base = DIVA_OS_MEM_ATTACH_RAM((PISDN_ADAPTER)a->io); memcpy_toio((Base + (unsigned long)addr), buffer, length) ; DIVA_OS_MEM_DETACH_RAM((PISDN_ADAPTER)a->io, Base);}void mem_inc (ADAPTER *a, void *addr){ volatile byte __iomem *Base = DIVA_OS_MEM_ATTACH_RAM((PISDN_ADAPTER)a->io); byte x = READ_BYTE(Base + (unsigned long)addr); WRITE_BYTE(Base + (unsigned long)addr, x + 1); DIVA_OS_MEM_DETACH_RAM((PISDN_ADAPTER)a->io, Base);}/*------------------------------------------------------------------*//* ram access functions for io-mapped cards *//*------------------------------------------------------------------*/byte io_in(ADAPTER * a, void * adr){ byte val; byte __iomem *Port = DIVA_OS_MEM_ATTACH_PORT((PISDN_ADAPTER)a->io); outppw(Port + 4, (word)(unsigned long)adr); val = inpp(Port); DIVA_OS_MEM_DETACH_PORT((PISDN_ADAPTER)a->io, Port); return(val);}word io_inw(ADAPTER * a, void * adr){ word val; byte __iomem *Port = DIVA_OS_MEM_ATTACH_PORT((PISDN_ADAPTER)a->io); outppw(Port + 4, (word)(unsigned long)adr); val = inppw(Port); DIVA_OS_MEM_DETACH_PORT((PISDN_ADAPTER)a->io, Port); return(val);}void io_in_buffer(ADAPTER * a, void * adr, void * buffer, word len){ byte __iomem *Port = DIVA_OS_MEM_ATTACH_PORT((PISDN_ADAPTER)a->io); byte* P = (byte*)buffer; if ((long)adr & 1) { outppw(Port+4, (word)(unsigned long)adr); *P = inpp(Port); P++; adr = ((byte *) adr) + 1; len--; if (!len) { DIVA_OS_MEM_DETACH_PORT((PISDN_ADAPTER)a->io, Port); return; } } outppw(Port+4, (word)(unsigned long)adr); inppw_buffer (Port, P, len+1); DIVA_OS_MEM_DETACH_PORT((PISDN_ADAPTER)a->io, Port);}void io_look_ahead(ADAPTER * a, PBUFFER * RBuffer, ENTITY * e){ byte __iomem *Port = DIVA_OS_MEM_ATTACH_PORT((PISDN_ADAPTER)a->io); outppw(Port+4, (word)(unsigned long)RBuffer); ((PISDN_ADAPTER)a->io)->RBuffer.length = inppw(Port); inppw_buffer (Port, ((PISDN_ADAPTER)a->io)->RBuffer.P, ((PISDN_ADAPTER)a->io)->RBuffer.length + 1); e->RBuffer = (DBUFFER *) &(((PISDN_ADAPTER)a->io)->RBuffer); DIVA_OS_MEM_DETACH_PORT((PISDN_ADAPTER)a->io, Port);}void io_out(ADAPTER * a, void * adr, byte data){ byte __iomem *Port = DIVA_OS_MEM_ATTACH_PORT((PISDN_ADAPTER)a->io); outppw(Port+4, (word)(unsigned long)adr); outpp(Port, data); DIVA_OS_MEM_DETACH_PORT((PISDN_ADAPTER)a->io, Port);}void io_outw(ADAPTER * a, void * adr, word data){ byte __iomem *Port = DIVA_OS_MEM_ATTACH_PORT((PISDN_ADAPTER)a->io); outppw(Port+4, (word)(unsigned long)adr); outppw(Port, data); DIVA_OS_MEM_DETACH_PORT((PISDN_ADAPTER)a->io, Port);}void io_out_buffer(ADAPTER * a, void * adr, void * buffer, word len){ byte __iomem *Port = DIVA_OS_MEM_ATTACH_PORT((PISDN_ADAPTER)a->io); byte* P = (byte*)buffer; if ((long)adr & 1) { outppw(Port+4, (word)(unsigned long)adr); outpp(Port, *P); P++; adr = ((byte *) adr) + 1; len--; if (!len) { DIVA_OS_MEM_DETACH_PORT((PISDN_ADAPTER)a->io, Port); return; } } outppw(Port+4, (word)(unsigned long)adr); outppw_buffer (Port, P, len+1); DIVA_OS_MEM_DETACH_PORT((PISDN_ADAPTER)a->io, Port);}void io_inc(ADAPTER * a, void * adr){ byte x; byte __iomem *Port = DIVA_OS_MEM_ATTACH_PORT((PISDN_ADAPTER)a->io); outppw(Port+4, (word)(unsigned long)adr); x = inpp(Port); outppw(Port+4, (word)(unsigned long)adr); outpp(Port, x+1); DIVA_OS_MEM_DETACH_PORT((PISDN_ADAPTER)a->io, Port);}/*------------------------------------------------------------------*//* OS specific functions related to queuing of entities *//*------------------------------------------------------------------*/void free_entity(ADAPTER * a, byte e_no){ PISDN_ADAPTER IoAdapter; diva_os_spin_lock_magic_t irql; IoAdapter = (PISDN_ADAPTER) a->io; diva_os_enter_spin_lock (&IoAdapter->data_spin_lock, &irql, "data_free"); IoAdapter->e_tbl[e_no].e = NULL; IoAdapter->e_count--; diva_os_leave_spin_lock (&IoAdapter->data_spin_lock, &irql, "data_free");}void assign_queue(ADAPTER * a, byte e_no, word ref){ PISDN_ADAPTER IoAdapter; diva_os_spin_lock_magic_t irql; IoAdapter = (PISDN_ADAPTER) a->io; diva_os_enter_spin_lock (&IoAdapter->data_spin_lock, &irql, "data_assign"); IoAdapter->e_tbl[e_no].assign_ref = ref; IoAdapter->e_tbl[e_no].next = (byte)IoAdapter->assign; IoAdapter->assign = e_no; diva_os_leave_spin_lock (&IoAdapter->data_spin_lock, &irql, "data_assign");}byte get_assign(ADAPTER * a, word ref){ PISDN_ADAPTER IoAdapter; diva_os_spin_lock_magic_t irql; byte e_no; IoAdapter = (PISDN_ADAPTER) a->io; diva_os_enter_spin_lock (&IoAdapter->data_spin_lock, &irql, "data_assign_get"); for(e_no = (byte)IoAdapter->assign; e_no && IoAdapter->e_tbl[e_no].assign_ref!=ref; e_no = IoAdapter->e_tbl[e_no].next); diva_os_leave_spin_lock (&IoAdapter->data_spin_lock, &irql, "data_assign_get"); return e_no;}void req_queue(ADAPTER * a, byte e_no){ PISDN_ADAPTER IoAdapter; diva_os_spin_lock_magic_t irql; IoAdapter = (PISDN_ADAPTER) a->io; diva_os_enter_spin_lock (&IoAdapter->data_spin_lock, &irql, "data_req_q"); IoAdapter->e_tbl[e_no].next = 0; if(IoAdapter->head) { IoAdapter->e_tbl[IoAdapter->tail].next = e_no; IoAdapter->tail = e_no; } else { IoAdapter->head = e_no; IoAdapter->tail = e_no; } diva_os_leave_spin_lock (&IoAdapter->data_spin_lock, &irql, "data_req_q");}byte look_req(ADAPTER * a){ PISDN_ADAPTER IoAdapter; IoAdapter = (PISDN_ADAPTER) a->io; return ((byte)IoAdapter->head) ;}void next_req(ADAPTER * a){ PISDN_ADAPTER IoAdapter; diva_os_spin_lock_magic_t irql; IoAdapter = (PISDN_ADAPTER) a->io; diva_os_enter_spin_lock (&IoAdapter->data_spin_lock, &irql, "data_req_next"); IoAdapter->head = IoAdapter->e_tbl[IoAdapter->head].next; if(!IoAdapter->head) IoAdapter->tail = 0; diva_os_leave_spin_lock (&IoAdapter->data_spin_lock, &irql, "data_req_next");}/*------------------------------------------------------------------*//* memory map functions *//*------------------------------------------------------------------*/ENTITY * entity_ptr(ADAPTER * a, byte e_no){ PISDN_ADAPTER IoAdapter; IoAdapter = (PISDN_ADAPTER) a->io; return (IoAdapter->e_tbl[e_no].e);}void * PTR_X(ADAPTER * a, ENTITY * e){ return ((void *) e->X);}void * PTR_R(ADAPTER * a, ENTITY * e){ return ((void *) e->R);}void * PTR_P(ADAPTER * a, ENTITY * e, void * P){ return P;}void CALLBACK(ADAPTER * a, ENTITY * e){ if ( e && e->callback ) e->callback (e) ;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -