📄 diva.c
字号:
/* $Id: diva.c,v 1.21.4.1 2004/05/08 14:33:43 armin Exp $ */#define CARDTYPE_H_WANT_DATA 1#define CARDTYPE_H_WANT_IDI_DATA 0#define CARDTYPE_H_WANT_RESOURCE_DATA 0#define CARDTYPE_H_WANT_FILE_DATA 0#include "platform.h"#include "debuglib.h"#include "cardtype.h"#include "pc.h"#include "di_defs.h"#include "di.h"#include "io.h"#include "pc_maint.h"#include "xdi_msg.h"#include "xdi_adapter.h"#include "diva_pci.h"#include "diva.h"#ifdef CONFIG_ISDN_DIVAS_PRIPCI#include "os_pri.h"#endif#ifdef CONFIG_ISDN_DIVAS_BRIPCI#include "os_bri.h"#include "os_4bri.h"#endifPISDN_ADAPTER IoAdapters[MAX_ADAPTER];extern IDI_CALL Requests[MAX_ADAPTER];extern int create_adapter_proc(diva_os_xdi_adapter_t * a);extern void remove_adapter_proc(diva_os_xdi_adapter_t * a);#define DivaIdiReqFunc(N) \static void DivaIdiRequest##N(ENTITY *e) \{ if ( IoAdapters[N] ) (* IoAdapters[N]->DIRequest)(IoAdapters[N], e) ; }/*** Create own 32 Adapters*/DivaIdiReqFunc(0)DivaIdiReqFunc(1)DivaIdiReqFunc(2)DivaIdiReqFunc(3)DivaIdiReqFunc(4)DivaIdiReqFunc(5)DivaIdiReqFunc(6)DivaIdiReqFunc(7)DivaIdiReqFunc(8)DivaIdiReqFunc(9)DivaIdiReqFunc(10)DivaIdiReqFunc(11)DivaIdiReqFunc(12)DivaIdiReqFunc(13)DivaIdiReqFunc(14)DivaIdiReqFunc(15)DivaIdiReqFunc(16)DivaIdiReqFunc(17)DivaIdiReqFunc(18)DivaIdiReqFunc(19)DivaIdiReqFunc(20)DivaIdiReqFunc(21)DivaIdiReqFunc(22)DivaIdiReqFunc(23)DivaIdiReqFunc(24)DivaIdiReqFunc(25)DivaIdiReqFunc(26)DivaIdiReqFunc(27)DivaIdiReqFunc(28)DivaIdiReqFunc(29)DivaIdiReqFunc(30)DivaIdiReqFunc(31)struct pt_regs;/*** LOCALS*/static LIST_HEAD(adapter_queue);typedef struct _diva_get_xlog { word command; byte req; byte rc; byte data[sizeof(struct mi_pc_maint)];} diva_get_xlog_t;typedef struct _diva_supported_cards_info { int CardOrdinal; diva_init_card_proc_t init_card;} diva_supported_cards_info_t;static diva_supported_cards_info_t divas_supported_cards[] = {#ifdef CONFIG_ISDN_DIVAS_PRIPCI /* PRI Cards */ {CARDTYPE_DIVASRV_P_30M_PCI, diva_pri_init_card}, /* PRI Rev.2 Cards */ {CARDTYPE_DIVASRV_P_30M_V2_PCI, diva_pri_init_card}, /* PRI Rev.2 VoIP Cards */ {CARDTYPE_DIVASRV_VOICE_P_30M_V2_PCI, diva_pri_init_card},#endif#ifdef CONFIG_ISDN_DIVAS_BRIPCI /* 4BRI Rev 1 Cards */ {CARDTYPE_DIVASRV_Q_8M_PCI, diva_4bri_init_card}, {CARDTYPE_DIVASRV_VOICE_Q_8M_PCI, diva_4bri_init_card}, /* 4BRI Rev 2 Cards */ {CARDTYPE_DIVASRV_Q_8M_V2_PCI, diva_4bri_init_card}, {CARDTYPE_DIVASRV_VOICE_Q_8M_V2_PCI, diva_4bri_init_card}, /* 4BRI Based BRI Rev 2 Cards */ {CARDTYPE_DIVASRV_B_2M_V2_PCI, diva_4bri_init_card}, {CARDTYPE_DIVASRV_B_2F_PCI, diva_4bri_init_card}, {CARDTYPE_DIVASRV_VOICE_B_2M_V2_PCI, diva_4bri_init_card}, /* BRI */ {CARDTYPE_MAESTRA_PCI, diva_bri_init_card},#endif /* EOL */ {-1}};static void diva_init_request_array(void);static void *divas_create_pci_card(int handle, void *pci_dev_handle);static diva_os_spin_lock_t adapter_lock;static int diva_find_free_adapters(int base, int nr){ int i; for (i = 0; i < nr; i++) { if (IoAdapters[base + i]) { return (-1); } } return (0);}static diva_os_xdi_adapter_t *diva_q_get_next(struct list_head * what){ diva_os_xdi_adapter_t *a = NULL; if (what && (what->next != &adapter_queue)) a = list_entry(what->next, diva_os_xdi_adapter_t, link); return(a);}/* -------------------------------------------------------------------------- Add card to the card list -------------------------------------------------------------------------- */void *diva_driver_add_card(void *pdev, unsigned long CardOrdinal){ diva_os_spin_lock_magic_t old_irql; diva_os_xdi_adapter_t *pdiva, *pa; int i, j, max, nr; for (i = 0; divas_supported_cards[i].CardOrdinal != -1; i++) { if (divas_supported_cards[i].CardOrdinal == CardOrdinal) { if (!(pdiva = divas_create_pci_card(i, pdev))) { return NULL; } switch (CardOrdinal) { case CARDTYPE_DIVASRV_Q_8M_PCI: case CARDTYPE_DIVASRV_VOICE_Q_8M_PCI: case CARDTYPE_DIVASRV_Q_8M_V2_PCI: case CARDTYPE_DIVASRV_VOICE_Q_8M_V2_PCI: max = MAX_ADAPTER - 4; nr = 4; break; default: max = MAX_ADAPTER; nr = 1; } diva_os_enter_spin_lock(&adapter_lock, &old_irql, "add card"); for (i = 0; i < max; i++) { if (!diva_find_free_adapters(i, nr)) { pdiva->controller = i + 1; pdiva->xdi_adapter.ANum = pdiva->controller; IoAdapters[i] = &pdiva->xdi_adapter; diva_os_leave_spin_lock(&adapter_lock, &old_irql, "add card"); create_adapter_proc(pdiva); /* add adapter to proc file system */ DBG_LOG(("add %s:%d", CardProperties [CardOrdinal].Name, pdiva->controller)) diva_os_enter_spin_lock(&adapter_lock, &old_irql, "add card"); pa = pdiva; for (j = 1; j < nr; j++) { /* slave adapters, if any */ pa = diva_q_get_next(&pa->link); if (pa && !pa->interface.cleanup_adapter_proc) { pa->controller = i + 1 + j; pa->xdi_adapter.ANum = pa->controller; IoAdapters[i + j] = &pa->xdi_adapter; diva_os_leave_spin_lock(&adapter_lock, &old_irql, "add card"); DBG_LOG(("add slave adapter (%d)", pa->controller)) create_adapter_proc(pa); /* add adapter to proc file system */ diva_os_enter_spin_lock(&adapter_lock, &old_irql, "add card"); } else { DBG_ERR(("slave adapter problem")) break; } } diva_os_leave_spin_lock(&adapter_lock, &old_irql, "add card"); return (pdiva); } } diva_os_leave_spin_lock(&adapter_lock, &old_irql, "add card"); /* Not able to add adapter - remove it and return error */ DBG_ERR(("can not alloc request array")) diva_driver_remove_card(pdiva); return NULL; } } return NULL;}/* -------------------------------------------------------------------------- Called on driver load, MAIN, main, DriverEntry -------------------------------------------------------------------------- */int divasa_xdi_driver_entry(void){ diva_os_initialize_spin_lock(&adapter_lock, "adapter"); memset(&IoAdapters[0], 0x00, sizeof(IoAdapters)); diva_init_request_array(); return (0);}/* -------------------------------------------------------------------------- Remove adapter from list -------------------------------------------------------------------------- */static diva_os_xdi_adapter_t *get_and_remove_from_queue(void){ diva_os_spin_lock_magic_t old_irql; diva_os_xdi_adapter_t *a = NULL; diva_os_enter_spin_lock(&adapter_lock, &old_irql, "driver_unload"); if (!list_empty(&adapter_queue)) { a = list_entry(adapter_queue.next, diva_os_xdi_adapter_t, link); list_del(adapter_queue.next); } diva_os_leave_spin_lock(&adapter_lock, &old_irql, "driver_unload"); return (a);}/* -------------------------------------------------------------------------- Remove card from the card list -------------------------------------------------------------------------- */void diva_driver_remove_card(void *pdiva){ diva_os_spin_lock_magic_t old_irql; diva_os_xdi_adapter_t *a[4]; diva_os_xdi_adapter_t *pa; int i; pa = a[0] = (diva_os_xdi_adapter_t *) pdiva; a[1] = a[2] = a[3] = NULL; diva_os_enter_spin_lock(&adapter_lock, &old_irql, "remode adapter"); for (i = 1; i < 4; i++) { if ((pa = diva_q_get_next(&pa->link)) && !pa->interface.cleanup_adapter_proc) { a[i] = pa; } else { break; } } for (i = 0; ((i < 4) && a[i]); i++) { list_del(&a[i]->link); } diva_os_leave_spin_lock(&adapter_lock, &old_irql, "driver_unload"); (*(a[0]->interface.cleanup_adapter_proc)) (a[0]); for (i = 0; i < 4; i++) { if (a[i]) { if (a[i]->controller) { DBG_LOG(("remove adapter (%d)", a[i]->controller)) IoAdapters[a[i]->controller - 1] = NULL; remove_adapter_proc(a[i]); } diva_os_free(0, a[i]); } }}/* -------------------------------------------------------------------------- Create diva PCI adapter and init internal adapter structures -------------------------------------------------------------------------- */static void *divas_create_pci_card(int handle, void *pci_dev_handle){ diva_supported_cards_info_t *pI = &divas_supported_cards[handle]; diva_os_spin_lock_magic_t old_irql; diva_os_xdi_adapter_t *a; DBG_LOG(("found %d-%s", pI->CardOrdinal, CardProperties[pI->CardOrdinal].Name))
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -