📄 capifunc.c
字号:
memset(this, 0, sizeof(APPL)); this->Id = appl; for (i = 0; i < max_adapter; i++) { adapter[i].CIP_Mask[appl - 1] = 0; } this->queue_size = 1000; this->MaxNCCI = (byte) nconn; this->MaxNCCIData = (byte) rp->datablkcnt; this->MaxBuffer = bnum; this->MaxDataLength = rp->datablklen; this->DataNCCI = DataNCCI; this->DataFlags = DataFlags; this->ReceiveBuffer = ReceiveBuffer; this->xbuffer_used = xbuffer_used; this->xbuffer_ptr = xbuffer_ptr; this->xbuffer_internal = xbuffer_internal; for (i = 0; i < xnum; i++) { this->xbuffer_ptr[i] = xbuffer_ptr[i]; } CapiRegister(this->Id); diva_os_leave_spin_lock(&api_lock, &old_irql, "register_appl");}/* * release appl */static void diva_release_appl(struct capi_ctr *ctrl, __u16 appl){ diva_os_spin_lock_magic_t old_irql; APPL *this = &application[appl - 1]; void *mem_to_free = NULL; DBG_TRC(("application %d(%d) cleanup", this->Id, appl)) if (diva_os_in_irq()) { DBG_ERR(("CAPI_RELEASE - in irq context !")) return; } diva_os_enter_spin_lock(&api_lock, &old_irql, "release_appl"); if (this->Id) { CapiRelease(this->Id); mem_to_free = this->DataNCCI; this->DataNCCI = NULL; this->Id = 0; } diva_os_leave_spin_lock(&api_lock, &old_irql, "release_appl"); if (mem_to_free) diva_os_free(0, mem_to_free);}/* * send message */static u16 diva_send_message(struct capi_ctr *ctrl, diva_os_message_buffer_s * dmb){ int i = 0; word ret = 0; diva_os_spin_lock_magic_t old_irql; CAPI_MSG *msg = (CAPI_MSG *) DIVA_MESSAGE_BUFFER_DATA(dmb); APPL *this = &application[GET_WORD(&msg->header.appl_id) - 1]; diva_card *card = ctrl->driverdata; __u32 length = DIVA_MESSAGE_BUFFER_LEN(dmb); word clength = GET_WORD(&msg->header.length); word command = GET_WORD(&msg->header.command); u16 retval = CAPI_NOERROR; if (diva_os_in_irq()) { DBG_ERR(("CAPI_SEND_MSG - in irq context !")) return CAPI_REGOSRESOURCEERR; } DBG_PRV1(("Write - appl = %d, cmd = 0x%x", this->Id, command)) if (card->remove_in_progress) { DBG_ERR(("CAPI_SEND_MSG - remove in progress!")) return CAPI_REGOSRESOURCEERR; } diva_os_enter_spin_lock(&api_lock, &old_irql, "send message"); if (!this->Id) { diva_os_leave_spin_lock(&api_lock, &old_irql, "send message"); return CAPI_ILLAPPNR; } /* patch controller number */ msg->header.controller = ControllerMap[card->Id] | (msg->header.controller & 0x80); /* preserve external controller bit */ switch (command) { default: xlog("\x00\x02", msg, 0x80, clength); break; case _DATA_B3_I | RESPONSE:#ifndef DIVA_NO_DEBUGLIB if (myDriverDebugHandle.dbgMask & DL_BLK) xlog("\x00\x02", msg, 0x80, clength);#endif break; case _DATA_B3_R:#ifndef DIVA_NO_DEBUGLIB if (myDriverDebugHandle.dbgMask & DL_BLK) xlog("\x00\x02", msg, 0x80, clength);#endif if (clength == 24) clength = 22; /* workaround for PPcom bug */ /* header is always 22 */ if (GET_WORD(&msg->info.data_b3_req.Data_Length) > this->MaxDataLength || GET_WORD(&msg->info.data_b3_req.Data_Length) > (length - clength)) { DBG_ERR(("Write - invalid message size")) retval = CAPI_ILLCMDORSUBCMDORMSGTOSMALL; goto write_end; } for (i = 0; i < (MAX_DATA_B3 * this->MaxNCCI) && this->xbuffer_used[i]; i++); if (i == (MAX_DATA_B3 * this->MaxNCCI)) { DBG_ERR(("Write - too many data pending")) retval = CAPI_SENDQUEUEFULL; goto write_end; } msg->info.data_b3_req.Data = i; this->xbuffer_internal[i] = NULL; memcpy(this->xbuffer_ptr[i], &((__u8 *) msg)[clength], GET_WORD(&msg->info.data_b3_req.Data_Length));#ifndef DIVA_NO_DEBUGLIB if ((myDriverDebugHandle.dbgMask & DL_BLK) && (myDriverDebugHandle.dbgMask & DL_XLOG)) { int j; for (j = 0; j < GET_WORD(&msg->info.data_b3_req.Data_Length); j += 256) { DBG_BLK((((char *) this->xbuffer_ptr[i]) + j, ((GET_WORD(&msg->info.data_b3_req.Data_Length) - j) < 256) ? (GET_WORD(&msg->info.data_b3_req.Data_Length) - j) : 256)) if (!(myDriverDebugHandle.dbgMask & DL_PRV0)) break; /* not more if not explicitely requested */ } }#endif break; } memcpy(mapped_msg, msg, (__u32) clength); mapped_msg->header.controller = MapController(mapped_msg->header.controller); mapped_msg->header.length = clength; mapped_msg->header.command = command; mapped_msg->header.number = GET_WORD(&msg->header.number); ret = api_put(this, mapped_msg); switch (ret) { case 0: break; case _BAD_MSG: DBG_ERR(("Write - bad message")) retval = CAPI_ILLCMDORSUBCMDORMSGTOSMALL; break; case _QUEUE_FULL: DBG_ERR(("Write - queue full")) retval = CAPI_SENDQUEUEFULL; break; default: DBG_ERR(("Write - api_put returned unknown error")) retval = CAPI_UNKNOWNNOTPAR; break; } write_end: diva_os_leave_spin_lock(&api_lock, &old_irql, "send message"); if (retval == CAPI_NOERROR) diva_os_free_message_buffer(dmb); return retval;}/* * cards request function */static void DIRequest(ENTITY * e){ DIVA_CAPI_ADAPTER *a = &(adapter[(byte) e->user[0]]); diva_card *os_card = (diva_card *) a->os_card; if (e->Req && (a->FlowControlIdTable[e->ReqCh] == e->Id)) { a->FlowControlSkipTable[e->ReqCh] = 1; } (*(os_card->d.request)) (e);}/* * callback function from didd */static void didd_callback(void *context, DESCRIPTOR * adapter, int removal){ if (adapter->type == IDI_DADAPTER) { DBG_ERR(("Notification about IDI_DADAPTER change ! Oops.")); return; } else if (adapter->type == IDI_DIMAINT) { if (removal) { stop_dbg(); } else { memcpy(&MAdapter, adapter, sizeof(MAdapter)); dprintf = (DIVA_DI_PRINTF) MAdapter.request; DbgRegister("CAPI20", DRIVERRELEASE_CAPI, DBG_DEFAULT); } } else if ((adapter->type > 0) && (adapter->type < 16)) { /* IDI Adapter */ if (removal) { divacapi_remove_card(adapter); } else { diva_add_card(adapter); } } return;}/* * connect to didd */static int divacapi_connect_didd(void){ int x = 0; int dadapter = 0; IDI_SYNC_REQ req; DESCRIPTOR DIDD_Table[MAX_DESCRIPTORS]; DIVA_DIDD_Read(DIDD_Table, sizeof(DIDD_Table)); for (x = 0; x < MAX_DESCRIPTORS; x++) { if (DIDD_Table[x].type == IDI_DIMAINT) { /* MAINT found */ memcpy(&MAdapter, &DIDD_Table[x], sizeof(DAdapter)); dprintf = (DIVA_DI_PRINTF) MAdapter.request; DbgRegister("CAPI20", DRIVERRELEASE_CAPI, DBG_DEFAULT); break; } } for (x = 0; x < MAX_DESCRIPTORS; x++) { if (DIDD_Table[x].type == IDI_DADAPTER) { /* DADAPTER found */ dadapter = 1; memcpy(&DAdapter, &DIDD_Table[x], sizeof(DAdapter)); req.didd_notify.e.Req = 0; req.didd_notify.e.Rc = IDI_SYNC_REQ_DIDD_REGISTER_ADAPTER_NOTIFY; req.didd_notify.info.callback = (void *)didd_callback; req.didd_notify.info.context = NULL; DAdapter.request((ENTITY *) & req); if (req.didd_notify.e.Rc != 0xff) { stop_dbg(); return (0); } notify_handle = req.didd_notify.info.handle; } else if ((DIDD_Table[x].type > 0) && (DIDD_Table[x].type < 16)) { /* IDI Adapter found */ diva_add_card(&DIDD_Table[x]); } } if (!dadapter) { stop_dbg(); } return (dadapter);}/* * diconnect from didd */static void divacapi_disconnect_didd(void){ IDI_SYNC_REQ req; stop_dbg(); req.didd_notify.e.Req = 0; req.didd_notify.e.Rc = IDI_SYNC_REQ_DIDD_REMOVE_ADAPTER_NOTIFY; req.didd_notify.info.handle = notify_handle; DAdapter.request((ENTITY *) & req);}/* * we do not provide date/time here, * the application should do this. */int fax_head_line_time(char *buffer){ return (0);}/* * init (alloc) main structures */static int DIVA_INIT_FUNCTION init_main_structs(void){ if (!(mapped_msg = (CAPI_MSG *) diva_os_malloc(0, MAX_MSG_SIZE))) { DBG_ERR(("init: failed alloc mapped_msg.")) return 0; } if (!(adapter = diva_os_malloc(0, sizeof(DIVA_CAPI_ADAPTER) * MAX_DESCRIPTORS))) { DBG_ERR(("init: failed alloc adapter struct.")) diva_os_free(0, mapped_msg); return 0; } memset(adapter, 0, sizeof(DIVA_CAPI_ADAPTER) * MAX_DESCRIPTORS); if (!(application = diva_os_malloc(0, sizeof(APPL) * MAX_APPL))) { DBG_ERR(("init: failed alloc application struct.")) diva_os_free(0, mapped_msg); diva_os_free(0, adapter); return 0; } memset(application, 0, sizeof(APPL) * MAX_APPL); return (1);}/* * remove (free) main structures */static void remove_main_structs(void){ if (application) diva_os_free(0, application); if (adapter) diva_os_free(0, adapter); if (mapped_msg) diva_os_free(0, mapped_msg);}/* * api_remove_start */static void do_api_remove_start(void){ diva_os_spin_lock_magic_t old_irql; int ret = 1, count = 100; do { diva_os_enter_spin_lock(&api_lock, &old_irql, "api remove start"); ret = api_remove_start(); diva_os_leave_spin_lock(&api_lock, &old_irql, "api remove start"); diva_os_sleep(10); } while (ret && count--); if (ret) DBG_ERR(("could not remove signaling ID's"))}/* * init */int DIVA_INIT_FUNCTION init_capifunc(void){ diva_os_initialize_spin_lock(&api_lock, "capifunc"); memset(ControllerMap, 0, MAX_DESCRIPTORS + 1); max_adapter = 0; if (!init_main_structs()) { DBG_ERR(("init: failed to init main structs.")) diva_os_destroy_spin_lock(&api_lock, "capifunc"); return (0); } if (!divacapi_connect_didd()) { DBG_ERR(("init: failed to connect to DIDD.")) do_api_remove_start(); divacapi_remove_cards(); remove_main_structs(); diva_os_destroy_spin_lock(&api_lock, "capifunc"); return (0); } return (1);}/* * finit */void DIVA_EXIT_FUNCTION finit_capifunc(void){ do_api_remove_start(); divacapi_disconnect_didd(); divacapi_remove_cards(); remove_main_structs(); diva_os_destroy_spin_lock(&api_lock, "capifunc");}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -